/* /Layout/MainLayout.razor.rz.scp.css */
/* Deux colonnes (sidebar + contenu) depuis l'ajout de la barre latérale (session ultérieure) : le
   gouttière de page (space-4/space-5, "chat window side margins" selon tokens.md) vit désormais sur
   .app-shell__content, plus sur .app-shell elle-même — Sidebar gère son propre espacement interne. Plus
   de max-width/margin:auto sur le contenu (décidé plus tôt) : la fenêtre de chat occupe toute la largeur
   restante, pas une colonne centrale étroite. */
.app-shell[b-umpunalz9o] {
    height: 100vh;
    width: 100%;
    display: flex;
    flex-direction: row;
}

.app-shell__content[b-umpunalz9o] {
    flex: 1 1 auto;
    min-width: 0;
    min-height: 0;
    display: flex;
    flex-direction: column;
    padding: var(--space-4);
}

@media (min-width: 768px) {
    .app-shell__content[b-umpunalz9o] {
        padding: var(--space-5);
    }
}
/* /Layout/Sidebar.razor.rz.scp.css */
.sidebar[b-26eb40kdu9] {
    flex: 0 0 auto;
    width: 240px;
    height: 100%;
    background: var(--surface-raised);
    border-right: 1px solid var(--divider);
    display: flex;
    flex-direction: column;
    overflow-y: auto;
}

.sidebar__brand[b-26eb40kdu9] {
    padding: var(--space-5) var(--space-4);
}

/* Largeur d'affichage mini 120px et clear space >= hauteur du "D" capital (api/assets/Logos.md) : le
   padding de .sidebar__brand ci-dessus sert cet espace de respiration, la largeur choisie (140px) reste
   nettement au-dessus du minimum documenté. Ne jamais étirer hors de son propre ratio (asset non
   vectoriel, 300x67 documenté) — width fixe + height:auto plutôt que object-fit. */
.sidebar__logo[b-26eb40kdu9] {
    display: block;
    width: 140px;
    height: auto;
}

/* Taille de texte normal (text-body, 14px — l'UI courante de l'app), en ink-secondary plutôt qu'ink :
   le nom produit reste un sous-titre au logo, pas au même niveau d'emphase que le wordmark lui-même. */
.sidebar__product-name[b-26eb40kdu9] {
    margin: var(--space-1) 0 0 0;
    font: var(--text-body);
    color: var(--ink-secondary);
}

.sidebar__nav[b-26eb40kdu9] {
    list-style: none;
    margin: 0;
    padding: 0 var(--space-3);
    display: flex;
    flex-direction: column;
    gap: 10px;
}

/* .sidebar__link lui-même (fond, padding, radius, ombre, états survol/actif) est stylé globalement
   dans wwwroot/css/layout.css, PAS ici — corrigé en session : cette classe est posée sur le tag
   composant <NavLink>, pas sur un élément HTML écrit directement dans ce fichier, donc l'attribut de
   portée CSS isolée de Blazor (b-xxx) ne l'atteint jamais (NavLink rend son <a> depuis son propre
   assembly, sans connaissance de la portée de Sidebar.razor.css) — la règle scoped restait donc
   silencieusement sans effet, symptôme observé : un <a> par défaut du navigateur. .sidebar__icon/
   .sidebar__label ci-dessous n'ont pas ce problème : ce sont des éléments HTML écrits directement dans
   Sidebar.razor (passés à NavLink comme contenu enfant), donc bien dans la portée de ce fichier. */
.sidebar__icon[b-26eb40kdu9] {
    width: 20px;
    height: 20px;
    flex: 0 0 auto;
    color: var(--border);
}

.sidebar__label[b-26eb40kdu9] {
    font: var(--text-body-strong);
}
/* /Shared/Chat/ChartView.razor.rz.scp.css */
.chart__empty[b-lz5apmb0nr] {
    color: var(--ink-secondary);
}

/* Chart.js (responsive:true, maintainAspectRatio:false, cf. chart-view.js) a besoin d'un parent de
   taille explicite pour se redimensionner correctement — sans ça, un canvas dans un conteneur flex
   (.chat-bubble__blocks, align-items:flex-start) peut grandir indéfiniment à chaque cycle de resize.
   Largeur/hauteur posées en style inline par instance (ChartView.razor, _plan.Width/Height) plutôt qu'ici
   en dur : la taille dépend du nombre de catégories/séries/tranches de CE graphique précis (demandé
   explicitement) — seul position:relative (nécessaire au redimensionnement) reste générique. */
.chart[b-lz5apmb0nr] {
    position: relative;
}
/* /Shared/Chat/ChatBubble.razor.rz.scp.css */
.chat-bubble-row[b-vkbag8kiwe] {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.chat-bubble-row--user[b-vkbag8kiwe] {
    align-self: flex-end;
    align-items: flex-end;
    max-width: 75%;
}

/* Pas de plafond de largeur pour l'assistant (corrigé en session, était 80% comme l'utilisateur) : un
   texte court continue de s'ajuster à son contenu (align-items: flex-start ne l'étire pas), mais un bloc
   de réponse qui en a besoin (un tableau large, notamment) peut désormais grandir jusqu'à la pleine
   largeur de la fenêtre de chat plutôt que de forcer un retour à la ligne excessif dans un espace trop
   étroit. */
.chat-bubble-row--assistant[b-vkbag8kiwe] {
    align-self: flex-start;
    align-items: flex-start;
    max-width: 100%;
    width: 100%;
}

.chat-bubble[b-vkbag8kiwe] {
    padding: var(--space-2) var(--space-4);
    border-radius: var(--radius-lg);
    color: var(--on-fill);
}

.chat-bubble-row--user .chat-bubble[b-vkbag8kiwe] {
    background: var(--accent-strong);
    border-bottom-right-radius: var(--radius-sm);
}

.chat-bubble-row--assistant .chat-bubble[b-vkbag8kiwe] {
    background: var(--accent-subtle);
    border-bottom-left-radius: var(--radius-sm);
    color: var(--ink);
}

/* Les actions menées par l'assistant avant la réponse finale (tours "progress" de la boucle agentique,
   cf. CLAUDE.md Api §11) sont volontairement moins voyantes que la réponse elle-même : même bulle, mais
   accent-subtle/ink-secondary plutôt que accent-muted/on-fill. Même spécificité que la règle générale
   ci-dessus (deux classes) : gagne par ordre de déclaration (posée après), pas besoin de !important. */
.chat-bubble-row--assistant .chat-bubble--progress[b-vkbag8kiwe] {
    background: var(--accent-subtle);
    color: var(--ink-secondary);
}

/* Demandé explicitement : contrairement à la bulle de réponse finale (pas de plafond, cf.
   .chat-bubble-row--assistant plus haut — un tableau large peut en avoir besoin), la bulle de réflexion
   reste une simple ligne de texte et doit rester compacte plutôt que de s'étirer sur toute la largeur du
   parent (100% via la ligne assistant) : max-width propre ici, repli au retour à la ligne normal du span
   (déjà white-space:normal par défaut, rien à changer côté texte). */
.chat-bubble--progress[b-vkbag8kiwe] {
    max-width: 480px;
}

.chat-bubble__text[b-vkbag8kiwe] {
    white-space: pre-wrap;
}

.chat-bubble__timestamp[b-vkbag8kiwe] {
    color: var(--ink-secondary);
    padding: 0 var(--space-2);
}

/* Icône animée (ThinkingLoader, un par famille d'outils — design-guidelines/loaders.html) à gauche du
   texte, space-3 entre les deux (12px, espace icône → texte du guide). flex-start : le texte passe par
   SimpleMarkdown et peut faire plusieurs lignes, l'icône reste en haut à gauche (son alignement sur la
   première ou les deux premières lignes est porté par ses propres marges, cf. ThinkingLoader.razor.css). */
.chat-bubble__progress[b-vkbag8kiwe] {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
}

/* Enveloppe de l'icône, porteuse de son fondu propre (changement d'icône sous la même tâche principale,
   cf. ChatBubble.razor) : ThinkingLoader est un composant enfant, une classe de fondu posée sur lui
   n'atteindrait pas son élément racine de façon fiable. Élément flex : les marges verticales de l'icône
   ne fusionnent pas à travers elle. */
.chat-bubble__icon[b-vkbag8kiwe] {
    display: block;
    flex: none;
}

/* Tâche principale au-dessus, sous-tâche en cours en dessous (cf. ChatBubble.razor, ProgressView).
   min-width: 0 : sans lui, un élément flex ne descend pas sous la largeur de son contenu et un long mot
   (URL, référence) déborderait de la bulle plafonnée à 480px au lieu de revenir à la ligne.
   align-self: center : une seule ligne de texte se centre sur l'icône (plus haute qu'elle) ; dès deux
   lignes, le texte est au moins aussi haut que l'icône et ce centrage ne déplace plus rien. */
.chat-bubble__progress-body[b-vkbag8kiwe] {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    min-width: 0;
    align-self: center;
}

/* Poids de text-body-strong/text-data-strong (tokens.css, pas de variante "strong" pour caption). */
.chat-bubble__progress-text--main[b-vkbag8kiwe] {
    font-weight: 600;
}

/* Frère de .chat-bubble (plus imbriqué dedans, corrigé en session) : align-self: stretch pour occuper
   toute la largeur disponible de la ligne (jusqu'à 100%, cf. .chat-bubble-row--assistant ci-dessus) —
   align-items: flex-start en interne pour que kpi/graphique restent compacts par défaut ; seul .chat-
   block--table s'étire explicitement (ci-dessous), un tableau étant le cas qui a besoin de toute la place. */
.chat-bubble__blocks[b-vkbag8kiwe] {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    align-self: stretch;
    gap: var(--space-3);
    width: 100%;
}

/* Plusieurs graphiques consécutifs côte à côte (demandé explicitement) plutôt qu'empilés — flex-wrap
   plutôt qu'une vraie grille CSS (colonnes de largeur égale) : chaque ChartView calcule sa propre largeur
   selon ses données (cf. ChartView.razor, _plan.Width) et une grille à pistes uniformes forcerait toutes
   les cartes à la même largeur, contredisant cette taille dynamique — le flex-wrap laisse chaque carte
   garder sa largeur calculée et revient à la ligne dès que la rangée ne tient plus. */
.chat-bubble__chart-grid[b-vkbag8kiwe] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-4);
}
/* /Shared/Chat/ChatComposer.razor.rz.scp.css */
.chat-composer[b-bab6ohhy57] {
    display: flex;
    align-items: flex-end;
    gap: var(--space-3);
    padding: var(--space-4) var(--space-5);
    border-top: 1px solid var(--divider);
    flex: 0 0 auto;
    background: var(--surface-raised);
    box-shadow: var(--shadow-md);
}

.chat-composer__input[b-bab6ohhy57] {
    flex: 1 1 auto;
    resize: none;
    min-height: 40px;
    max-height: 160px;
    background: var(--surface-sunken);
    border: none;
    border-radius: var(--radius-sm);
    padding: var(--space-2) var(--space-3);
    color: var(--ink);
    font-family: var(--font-sans);
}

.chat-composer__input[b-bab6ohhy57]::placeholder {
    color: var(--ink-secondary);
}

.chat-composer__input:focus[b-bab6ohhy57] {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.chat-composer__input:disabled[b-bab6ohhy57] {
    color: var(--ink-secondary);
}

.chat-composer__send[b-bab6ohhy57] {
    flex: 0 0 auto;
    width: 40px;
    height: 40px;
    border-radius: var(--radius-full);
    border: none;
    background: var(--accent-strong);
    color: var(--on-fill);
    box-shadow: var(--shadow-sm);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: background-color 120ms ease-out;
}

.chat-composer__send:hover:not(:disabled)[b-bab6ohhy57] {
    background: color-mix(in srgb, var(--accent-strong) 92%, black);
}

.chat-composer__send:focus-visible[b-bab6ohhy57] {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.chat-composer__send:disabled[b-bab6ohhy57] {
    background: var(--surface-sunken);
    color: var(--border);
    cursor: default;
    box-shadow: none;
}

/* Action secondaire (pas d'envoi direct) : fond neutre au repos, contrairement au bouton d'envoi qui est
   l'action principale de la barre — bascule en accent-strong seulement pendant l'enregistrement, pour que
   l'état "actif" soit sans ambiguïté avec l'envoi normal. */
.chat-composer__mic[b-bab6ohhy57] {
    flex: 0 0 auto;
    width: 40px;
    height: 40px;
    border-radius: var(--radius-full);
    border: none;
    background: var(--surface-sunken);
    color: var(--ink-secondary);
    box-shadow: var(--shadow-sm);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: background-color 120ms ease-out, color 120ms ease-out;
}

.chat-composer__mic:hover:not(:disabled)[b-bab6ohhy57] {
    background: color-mix(in srgb, var(--surface-sunken) 85%, black);
}

.chat-composer__mic:focus-visible[b-bab6ohhy57] {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.chat-composer__mic:disabled[b-bab6ohhy57] {
    color: var(--border);
    cursor: default;
    box-shadow: none;
}

.chat-composer__mic--recording[b-bab6ohhy57] {
    background: var(--accent-strong);
    color: var(--on-fill);
}

@media (prefers-reduced-motion: no-preference) {
    .chat-composer__mic--recording[b-bab6ohhy57] {
        animation: chat-composer-mic-pulse-b-bab6ohhy57 1.1s ease-in-out infinite;
    }
}

@keyframes chat-composer-mic-pulse-b-bab6ohhy57 {
    0%, 100% {
        box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent-strong) 45%, transparent);
    }

    50% {
        box-shadow: 0 0 0 6px color-mix(in srgb, var(--accent-strong) 0%, transparent);
    }
}

.chat-composer__error[b-bab6ohhy57] {
    padding: var(--space-2) var(--space-5) var(--space-3);
    color: var(--danger);
    background: var(--surface-raised);
    flex: 0 0 auto;
}
/* /Shared/Chat/ChatWindow.razor.rz.scp.css */
.chat-window[b-fofvml5pju] {
    background: var(--surface-raised);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
    width: 100%;
    overflow: hidden;
}

.chat-window__header[b-fofvml5pju] {
    padding: var(--space-4) var(--space-5);
    border-bottom: 1px solid var(--divider);
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
}

/* Bouton "Ghost" (Button.md) : action secondaire de l'en-tête, jamais l'action principale de la vue
   (l'envoi d'un message) — même traitement que .column-picker__toggle (InvoiceSearch). */
.chat-window__new[b-fofvml5pju] {
    display: flex;
    align-items: center;
    background: transparent;
    border: none;
    color: var(--accent-strong);
    padding: calc(var(--space-2) - 2px) var(--space-4);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
    cursor: pointer;
}

.chat-window__new .txt[b-fofvml5pju] {
    line-height: 1;
    position: relative;
    top: -1.3px;
}

.chat-window__new:hover:not(:disabled)[b-fofvml5pju] {
    background: color-mix(in srgb, var(--accent-strong) 8%, transparent);
}

.chat-window__new:focus-visible[b-fofvml5pju] {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* Disabled (Button.md) : surface-sunken/border, jamais une opacité réduite. */
.chat-window__new:disabled[b-fofvml5pju] {
    background: var(--surface-sunken);
    color: var(--border);
    box-shadow: none;
    cursor: default;
}

.chat-window__messages[b-fofvml5pju] {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: var(--space-5);
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.chat-window__empty[b-fofvml5pju] {
    color: var(--ink-secondary);
    text-align: center;
    margin: auto;
    max-width: 40ch;
}
/* /Shared/Chat/ResponseBlockView.razor.rz.scp.css */
/* Corrigé en session : var(--on-fill) (blanc) était illisible sur ce bloc, qui n'a pas de fond opaque
   (contrairement aux blocs tableau/kpi/graphique, tous posés sur .card/surface-raised) — ink-secondary
   plutôt qu'ink, ce texte restant un contenu secondaire par rapport à la bulle de réponse elle-même. */
.chat-block--text[b-l49lhu4ecs] {
    color: var(--ink-secondary);
    white-space: pre-wrap;
}

.card.chat-block[b-l49lhu4ecs] {
    color: var(--ink);
}

.chat-block__title[b-l49lhu4ecs] {
    display: block;
    color: var(--ink);
    margin-bottom: var(--space-2);
}

.chat-block__note[b-l49lhu4ecs] {
    color: var(--ink-secondary);
    margin: var(--space-3) 0 0;
    padding-top: var(--space-2);
    border-top: 1px solid var(--divider);
}

/* Carte de graphique : sa largeur doit être celle du graphique et de sa légende (canvas de largeur fixe,
   calculée par ChartView), jamais celle du texte qui l'accompagne — retour utilisateur, un titre démesuré
   élargissait la carte bien au-delà du graphique. contain: inline-size retire le titre et le commentaire
   du calcul de largeur de la carte : ils prennent ensuite la largeur ainsi fixée et passent à la ligne.
   overflow-wrap: anywhere pour un mot sans espace plus long que cette largeur (référence, URL). */
.chat-block--chart .chat-block__title[b-l49lhu4ecs],
.chat-block--chart .chat-block__note[b-l49lhu4ecs] {
    contain: inline-size;
    overflow-wrap: anywhere;
}

/* .chat-block--table s'étire pour occuper toute la largeur offerte par .chat-bubble__blocks (corrigé en
   session — les autres types de bloc restent compacts, cf. leur parent align-items:flex-start) : c'est le
   cas qui a le plus besoin de place pour éviter le retour à la ligne excessif signalé par l'utilisateur.
   padding: 0 + overflow: hidden (corrigé en session) : "The table is a Card internally" (DataTable.md) —
   lu comme le tableau affleurant les bords de la carte plutôt qu'un tableau posé avec la marge générique
   de .card (space-4) tout autour ; overflow: hidden découpe les coins carrés du tableau/de l'en-tête sur
   le radius-md hérité de .card, sans avoir à dupliquer le rayon sur chaque cellule d'angle. Titre et
   commentaire (ci-dessous) reprennent leur propre marge intérieure puisque celle de .card ne s'applique
   plus ici. */
.chat-block--table[b-l49lhu4ecs] {
    align-self: stretch;
    max-width: 100%;
    padding: 0;
    overflow: hidden;
}

.chat-block--table .chat-block__title[b-l49lhu4ecs] {
    padding: var(--space-3) var(--space-4) 0;
    margin-bottom: 11px;
}

.chat-block--table .chat-block__note[b-l49lhu4ecs] {
    margin: 0;
    padding: var(--space-2) var(--space-4) var(--space-3);
}

/* .chat-block__table-scroll/.data-table (défilement horizontal de secours, typographie tête/corps,
   zébrure, survol, alignement numérique en police tabulaire) — extraites vers wwwroot/css/data-table.css
   (implémenté en session) : consommées aussi par Shared/InvoiceSearch/InvoiceResultsTable.razor, une
   feuille globale partagée évite une divergence silencieuse entre les deux tableaux plutôt que dupliquer
   ces règles dans un second fichier *.razor.css. */

.chat-block--kpi[b-l49lhu4ecs] {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    min-width: 140px;
}

.chat-block__kpi-label[b-l49lhu4ecs] {
    color: var(--ink-secondary);
}

.chat-block__kpi-value[b-l49lhu4ecs] {
    color: var(--ink);
    font-family: var(--font-mono);
    font-size: 20px;
    font-weight: 600;
}

.chat-block__kpi-unit[b-l49lhu4ecs] {
    color: var(--ink-secondary);
    font-family: var(--font-sans);
    font-weight: 400;
    font-size: 13px;
    margin-left: var(--space-1);
}

/* Bloc "fiche_technique" (fiche technique d'un produit, cf. CLAUDE.md Client §5, SearchDatasheet) : même
   carte pleine largeur que le tableau (.chat-block--table, dont il reprend padding 0/overflow hidden), avec
   un en-tête titre + badges (type du document source, identifiant exact du produit) et un pied listant les
   sources. Badges : langage visuel de Badge.md (surface-badge, radius-full, caption sur un .txt interne avec
   le même nudge optique), sans point de statut — ce sont des étiquettes d'information, pas des statuts. */
.chat-block__datasheet-head[b-l49lhu4ecs] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-4) 11px;
}

.chat-block--datasheet .chat-block__datasheet-head .chat-block__title[b-l49lhu4ecs] {
    padding: 0;
    margin: 0;
}

.chat-block__badges[b-l49lhu4ecs] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1);
}

.chat-badge[b-l49lhu4ecs] {
    display: inline-flex;
    align-items: center;
    background: var(--surface-badge);
    border-radius: var(--radius-full);
    padding: var(--space-1) var(--space-3);
    color: var(--ink);
}

.chat-badge__txt[b-l49lhu4ecs] {
    position: relative;
    top: -0.75px;
    line-height: 1;
    white-space: nowrap;
}

/* Les cellules de .data-table sont en nowrap (défilement horizontal de secours) : une valeur ou une
   condition longue d'une fiche technique passe plutôt à la ligne, pour garder la carte lisible. */
.chat-block--datasheet .data-table td[b-l49lhu4ecs] {
    white-space: normal;
}

.chat-block__sources[b-l49lhu4ecs] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1) var(--space-3);
}

.chat-block__sources a[b-l49lhu4ecs] {
    color: inherit;
    text-decoration: underline;
    text-decoration-color: currentColor;
    overflow-wrap: anywhere;
}
/* /Shared/Chat/ThinkingLoader.razor.rz.scp.css */
/* Portage de design-guidelines/loaders.html — cycles, délais et keyframes repris tels quels (voir la
   section "Règles d'intégration" de ce fichier pour leur description). Couleurs : tokens du design system
   quand la valeur du guide leur est identique, sinon valeur du guide telle quelle (orange, violet prune et
   rose de la vague n'ont pas de token). Toujours la forme raccourcie `animation:` (jamais `animation-name`
   seul) : c'est celle dont le CSS scopé réécrit le nom avec le suffixe b-xxx de ses @keyframes. */
.thinking-loader[b-p9tw2el1rm] {
    --icon-size: 28;
    --tl-idle: var(--ink-secondary);   /* #716A64 */
    --tl-warm: #e8907e;
    --tl-peak: var(--accent);          /* #FD0000 */
    --tl-deep: var(--accent-strong);   /* #890807 */
    --tl-orange: #ff8a2b;
    --tl-prune: #8e2c8a;
    --tl-paper: var(--accent-subtle);  /* fond de la bulle de réflexion (#F9CFC5) */
    --sine-inout: cubic-bezier(.37, 0, .63, 1);
    display: block;
    flex: none;
    width: calc(var(--icon-size) * 1px);
    height: calc(var(--icon-size) * 1px);
    /* Alignement (règles 1 ligne / 2 lignes du guide), sur la ligne caption de la bulle (16px) : l'icône est
       centrée à 16px du haut, soit au milieu des deux premières lignes. Même marge en bas : sa boîte fait
       32px, le texte d'une seule ligne (centré, cf. .chat-bubble__progress-body) tombe alors pile en face. */
    margin-block: calc(16px - var(--icon-size) * .5px);
}

.thinking-loader--sm[b-p9tw2el1rm] {
    margin-inline: 1px;
}

.thinking-loader--lg[b-p9tw2el1rm] {
    --icon-size: 30;
}

.s[b-p9tw2el1rm] {
    display: block;
    position: relative;
    width: 90px;
    height: 90px;
    transform-origin: 0 0;
    transform: scale(calc(var(--icon-size) / 90));
}

.s svg[b-p9tw2el1rm] {
    position: absolute;
    inset: 0;
    overflow: visible;
}

.ac[b-p9tw2el1rm] { stroke: var(--tl-orange); }
.af[b-p9tw2el1rm] { fill: var(--tl-orange); }
.an .ac[b-p9tw2el1rm] { stroke: var(--tl-prune); }
.an .af[b-p9tw2el1rm] { fill: var(--tl-prune); }
.an .bar2[b-p9tw2el1rm] { fill: var(--tl-orange); }
.axes[b-p9tw2el1rm], .outline[b-p9tw2el1rm] { stroke: var(--tl-idle); }

/* ---------- Grille de pixels commune ---------- */
.g[b-p9tw2el1rm] {
    position: absolute;
    left: 21px;
    top: 21px;
    display: grid;
    grid-template-columns: repeat(3, 12px);
    gap: 6px;
}

.g i[b-p9tw2el1rm] {
    display: block;
    width: 12px;
    height: 12px;
    border-radius: 3px;
    background: var(--tl-idle);
    animation: tl-w-b-p9tw2el1rm 1.8s ease-in-out infinite;
}

@keyframes tl-w-b-p9tw2el1rm {
    0%, 100% { transform: scale(.38); background: var(--tl-idle); }
    38%      { transform: scale(1); background: var(--tl-warm); }
    52%      { transform: scale(1.1) translateY(-3px); background: var(--tl-peak); }
    66%      { transform: scale(.8); background: var(--tl-deep); }
}

/* ---------- Réflexion : vague diagonale continue ---------- */
.base .g[b-p9tw2el1rm] { transform: scale(1.55); }
.base .g i[b-p9tw2el1rm] {
    animation: tl-wr-b-p9tw2el1rm calc(1.8s / 1.3) ease-in-out calc(((var(--x) + var(--y)) * .09s - 2s) / 1.3) infinite;
}

@keyframes tl-wr-b-p9tw2el1rm {
    0%, 100% { transform: scale(1); background: var(--tl-warm); }
    33%      { transform: scale(1.1) translateY(-3px); background: var(--tl-peak); }
    66%      { transform: scale(.8); background: var(--tl-deep); }
}

/* ---------- Analyse : vague en barres, puis courbe / barres / camembert (5,7 s) ---------- */
.an .g[b-p9tw2el1rm] { left: 27px; top: 19px; }
.an .g i[b-p9tw2el1rm] {
    transform-origin: 50% 100%;
    animation: tl-wa-b-p9tw2el1rm 5.7s ease-in-out calc(var(--x) * .11s + (2 - var(--y)) * .06s - 5.95s) infinite;
}

@keyframes tl-wa-b-p9tw2el1rm {
    0%, 19.30%, 33.33%, 52.63%, 66.67%, 85.97%, 100% { transform: scaleY(.38); background: var(--tl-idle); opacity: 0; }
    7.33%  { transform: scaleY(1);    background: var(--tl-warm); opacity: 1; }
    10.04% { transform: scaleY(1.15); background: var(--tl-peak); opacity: 1; }
    12.74% { transform: scaleY(.8);   background: var(--tl-deep); opacity: 1; }
    40.66% { transform: scaleY(1);    background: var(--tl-warm); opacity: 1; }
    43.37% { transform: scaleY(1.15); background: var(--tl-peak); opacity: 1; }
    46.07% { transform: scaleY(.8);   background: var(--tl-deep); opacity: 1; }
    74.00% { transform: scaleY(1);    background: var(--tl-warm); opacity: 1; }
    76.71% { transform: scaleY(1.15); background: var(--tl-peak); opacity: 1; }
    79.41% { transform: scaleY(.8);   background: var(--tl-deep); opacity: 1; }
}

.an .trend[b-p9tw2el1rm] { stroke-dasharray: 100; animation: tl-dr-b-p9tw2el1rm 5.7s ease-in-out infinite; }
.an .dot[b-p9tw2el1rm] { animation: tl-dt-b-p9tw2el1rm 5.7s ease-in-out infinite; }

@keyframes tl-dr-b-p9tw2el1rm {
    0%, 13.9%      { stroke-dashoffset: 100; opacity: 0; }
    14.04%         { stroke-dashoffset: 100; opacity: 1; }
    24.56%, 33.33% { stroke-dashoffset: 0; opacity: 1; }
    37.72%         { stroke-dashoffset: 0; opacity: 0; }
    99.9%          { stroke-dashoffset: 0; opacity: 0; }
    100%           { stroke-dashoffset: 100; opacity: 0; }
}

@keyframes tl-dt-b-p9tw2el1rm {
    0%, 20%        { opacity: 0; }
    24.56%, 33.33% { opacity: 1; }
    37.72%, 100%   { opacity: 0; }
}

.an .bar[b-p9tw2el1rm] { transform-box: fill-box; transform-origin: 50% 100%; transform: scaleY(0); opacity: 0; }
.an .bar1[b-p9tw2el1rm] { animation: tl-b1-b-p9tw2el1rm 5.7s ease-in-out infinite; }
.an .bar2[b-p9tw2el1rm] { animation: tl-b2-b-p9tw2el1rm 5.7s ease-in-out infinite; }

@keyframes tl-b1-b-p9tw2el1rm {
    0%, 47.2%      { transform: scaleY(0); opacity: 0; }
    47.37%         { transform: scaleY(0); opacity: 1; animation-timing-function: cubic-bezier(.2, .8, .2, 1); }
    56.14%, 66.67% { transform: scaleY(1); opacity: 1; }
    71.06%         { transform: scaleY(1); opacity: 0; }
    100%           { transform: scaleY(0); opacity: 0; }
}

@keyframes tl-b2-b-p9tw2el1rm {
    0%, 47.2%    { transform: scaleY(0); opacity: 0; }
    48.8%        { transform: scaleY(0); opacity: 1; animation-timing-function: cubic-bezier(.2, .8, .2, 1); }
    58.5%, 66.67% { transform: scaleY(1); opacity: 1; }
    71.06%       { transform: scaleY(1); opacity: 0; }
    100%         { transform: scaleY(0); opacity: 0; }
}

.an .slice1[b-p9tw2el1rm] { stroke: var(--tl-orange); }
.an .slice2[b-p9tw2el1rm] { stroke: var(--tl-prune); }
.an .slice3[b-p9tw2el1rm] { stroke: var(--tl-warm); }
.an .pie[b-p9tw2el1rm] { opacity: 0; animation: tl-pieo-b-p9tw2el1rm 5.7s ease-in-out infinite; }
.an .pierev[b-p9tw2el1rm] { stroke-dasharray: 82.7 82.7; stroke-dashoffset: 82.7; animation: tl-pier-b-p9tw2el1rm 5.7s ease-in-out infinite; }

@keyframes tl-pieo-b-p9tw2el1rm {
    0%             { opacity: 1; }
    4.39%, 80.5%   { opacity: 0; }
    80.70%, 100%   { opacity: 1; }
}

@keyframes tl-pier-b-p9tw2el1rm {
    0%, 4.39%      { stroke-dashoffset: 0; }
    4.5%, 80.6%    { stroke-dashoffset: 82.7; }
    92.98%, 100%   { stroke-dashoffset: 0; }
}

/* ---------- Recherche : loupe qui parcourt la grille ---------- */
.re .g[b-p9tw2el1rm] { transform: scale(1.4); }
.re .zoom[b-p9tw2el1rm] { transform: translate(45px, 45px) scale(1.4) translate(-45px, -45px); }
.re .g i[b-p9tw2el1rm] { animation-delay: calc((var(--x) + var(--y)) * .09s - 2s); }
.re .loupe[b-p9tw2el1rm] { animation: tl-lp-b-p9tw2el1rm 3.2s ease-in-out infinite; }
.re .loupe .ac[b-p9tw2el1rm] { animation: tl-lc-b-p9tw2el1rm 1.8s ease-in-out infinite; animation-delay: calc(.18s - 2s); }

@keyframes tl-lc-b-p9tw2el1rm {
    0%, 100% { stroke: var(--tl-orange); fill: var(--tl-orange); }
    52%      { stroke: var(--tl-prune); fill: var(--tl-prune); }
}

@keyframes tl-lp-b-p9tw2el1rm {
    0%, 100% { transform: translate(35px, 35px); }
    25%      { transform: translate(55px, 35px); }
    50%      { transform: translate(55px, 55px); }
    75%      { transform: translate(35px, 55px); }
}

/* ---------- Analyse de document : lot de 3 pages scannées (3 s) ---------- */
.doc .g[b-p9tw2el1rm] { top: 32px; }
.doc .stk[b-p9tw2el1rm] {
    display: block;
    position: absolute;
    inset: 0;
    transform-origin: 0 0;
    transform: translate(45px, 45px) scale(.8) translate(-56px, -38px);
}
.doc .pg[b-p9tw2el1rm] { display: block; position: absolute; inset: 0; }
.doc .dfill[b-p9tw2el1rm] { fill: var(--tl-paper); }
.doc .dA[b-p9tw2el1rm] { animation: tl-pA-b-p9tw2el1rm 3s infinite; }
.doc .dB[b-p9tw2el1rm] { animation: tl-pB-b-p9tw2el1rm 3s infinite; }
.doc .dC[b-p9tw2el1rm] { animation: tl-pC-b-p9tw2el1rm 3s infinite; }

@keyframes tl-pA-b-p9tw2el1rm {
    0%           { transform: translate(30px, 0); opacity: 0; animation-timing-function: cubic-bezier(.2, .8, .2, 1); }
    13.33%, 31%  { transform: translate(0, 0); opacity: 1; animation-timing-function: cubic-bezier(.6, 0, .9, .4); }
    41.67%, 100% { transform: translate(-26px, 0); opacity: 0; }
}

@keyframes tl-pB-b-p9tw2el1rm {
    0%             { transform: translate(41px, -9px); opacity: 0; animation-timing-function: cubic-bezier(.2, .8, .2, 1); }
    13.33%, 31%    { transform: translate(11px, -9px); opacity: 1; animation-timing-function: ease-in-out; }
    41.67%, 57.67% { transform: translate(0, 0); opacity: 1; animation-timing-function: cubic-bezier(.6, 0, .9, .4); }
    68.33%, 100%   { transform: translate(-26px, 0); opacity: 0; }
}

@keyframes tl-pC-b-p9tw2el1rm {
    0%             { transform: translate(52px, -18px); opacity: 0; animation-timing-function: cubic-bezier(.2, .8, .2, 1); }
    13.33%, 31%    { transform: translate(22px, -18px); opacity: 1; animation-timing-function: ease-in-out; }
    41.67%, 57.67% { transform: translate(11px, -9px); opacity: 1; animation-timing-function: ease-in-out; }
    68.33%, 84.33% { transform: translate(0, 0); opacity: 1; animation-timing-function: cubic-bezier(.6, 0, .9, .4); }
    95%, 100%      { transform: translate(-26px, 0); opacity: 0; }
}

/* Seule la feuille de devant est cornée : chaque feuille se corne en arrivant au premier plan. */
.doc .fd[b-p9tw2el1rm] { opacity: 0; }
.doc .dA .fd[b-p9tw2el1rm] { opacity: 1; }
.doc .dA .plain[b-p9tw2el1rm] { opacity: 0; }
.doc .dB .plain[b-p9tw2el1rm] { animation: tl-xB-b-p9tw2el1rm 3s linear infinite; }
.doc .dB .fd[b-p9tw2el1rm] { animation: tl-fB-b-p9tw2el1rm 3s linear infinite; }
.doc .dC .plain[b-p9tw2el1rm] { animation: tl-xC-b-p9tw2el1rm 3s linear infinite; }
.doc .dC .fd[b-p9tw2el1rm] { animation: tl-fC-b-p9tw2el1rm 3s linear infinite; }

@keyframes tl-xB-b-p9tw2el1rm { 0%, 31% { opacity: 1; } 41.67%, 100% { opacity: 0; } }
@keyframes tl-fB-b-p9tw2el1rm { 0%, 31% { opacity: 0; } 41.67%, 100% { opacity: 1; } }
@keyframes tl-xC-b-p9tw2el1rm { 0%, 57.67% { opacity: 1; } 68.33%, 100% { opacity: 0; } }
@keyframes tl-fC-b-p9tw2el1rm { 0%, 57.67% { opacity: 0; } 68.33%, 100% { opacity: 1; } }

.doc .g i[b-p9tw2el1rm] {
    animation: tl-wd-b-p9tw2el1rm 3s ease-in-out calc(var(--t0) * 1s + var(--y) * .18s + var(--x) * .0133s - .168s - 3s) infinite;
}

@keyframes tl-wd-b-p9tw2el1rm {
    0%, 20%, 100% { transform: scale(.38); background: var(--tl-idle); }
    7.6%          { transform: scale(1); background: var(--tl-warm); }
    10.4%         { transform: scale(1.1) translateY(-3px); background: var(--tl-peak); }
    13.2%         { transform: scale(.8); background: var(--tl-deep); }
}

.doc .scan[b-p9tw2el1rm] { animation: tl-sc-b-p9tw2el1rm 3s linear infinite; animation-delay: calc(var(--t0) * 1s - 3s); }
.doc .scan .ac[b-p9tw2el1rm] { animation: tl-scs-b-p9tw2el1rm 3s linear infinite; animation-delay: calc(var(--t0) * 1s - 3s); }
.doc .scan .af[b-p9tw2el1rm] { animation: tl-scf-b-p9tw2el1rm 3s linear infinite; animation-delay: calc(var(--t0) * 1s - 3s); }

@keyframes tl-scs-b-p9tw2el1rm { 0% { stroke: var(--tl-orange); } 16%, 100% { stroke: var(--tl-prune); } }
@keyframes tl-scf-b-p9tw2el1rm { 0% { fill: var(--tl-orange); } 16%, 100% { fill: var(--tl-prune); } }

@keyframes tl-sc-b-p9tw2el1rm {
    0%        { transform: translateY(0); opacity: 0; }
    1.6%      { opacity: 1; }
    15%       { opacity: 1; }
    16%, 100% { transform: translateY(48px); opacity: 0; }
}

/* ---------- Recherche web : planète et vague centrifuge (1,95 s) ---------- */
.pl .g i[b-p9tw2el1rm] {
    animation: tl-wp-b-p9tw2el1rm 1.95s ease-in-out calc(var(--d) * .15s + .05s - 1.95s) infinite;
}

@keyframes tl-wp-b-p9tw2el1rm {
    0%, 46.15%   { transform: scale(0); background: var(--tl-idle); }
    53.85%       { transform: scale(.38); background: var(--tl-idle); }
    67.5%        { transform: scale(1); background: var(--tl-warm); }
    72.5%        { transform: scale(1.1) translateY(-3px); background: var(--tl-peak); }
    77.54%       { transform: scale(.8); background: var(--tl-deep); }
    89.74%       { transform: scale(.38); background: var(--tl-idle); }
    97.44%, 100% { transform: scale(0); background: var(--tl-idle); }
}

.pl .globe[b-p9tw2el1rm] { animation: tl-gl-b-p9tw2el1rm 1.95s var(--sine-inout) infinite, tl-gc-b-p9tw2el1rm 1.95s linear infinite; animation-delay: -.2s, -1.464s; }
.pl .globe .fillc[b-p9tw2el1rm] { fill-opacity: .15; animation: tl-gcf-b-p9tw2el1rm 1.95s linear infinite; animation-delay: -1.464s; }

@keyframes tl-gl-b-p9tw2el1rm {
    0%, 100% { opacity: 0; }
    50%      { opacity: 1; }
}

/* Trajet violet prune → bordeaux → orange vif échantillonné en 12 intervalles (valeurs du guide). */
@keyframes tl-gc-b-p9tw2el1rm {
    0.00%     { stroke: var(--tl-prune); }
    2.47%     { stroke: #8e2b85; }
    4.95%     { stroke: #8d2778; }
    7.42%     { stroke: #8c2162; }
    9.89%     { stroke: #8b1945; }
    12.36%    { stroke: #8a1023; }
    14.84%    { stroke: #900e07; }
    17.31%    { stroke: #ad2605; }
    19.78%    { stroke: #c83c03; }
    22.25%    { stroke: #df4f02; }
    24.73%    { stroke: #f05e01; }
    27.20%    { stroke: #fb6700; }
    29.67%    { stroke: #ff6a00; animation-timing-function: var(--sine-inout); }
    60%, 100% { stroke: var(--tl-prune); }
}

@keyframes tl-gcf-b-p9tw2el1rm {
    0.00%     { fill: var(--tl-prune); }
    2.47%     { fill: #8e2b85; }
    4.95%     { fill: #8d2778; }
    7.42%     { fill: #8c2162; }
    9.89%     { fill: #8b1945; }
    12.36%    { fill: #8a1023; }
    14.84%    { fill: #900e07; }
    17.31%    { fill: #ad2605; }
    19.78%    { fill: #c83c03; }
    22.25%    { fill: #df4f02; }
    24.73%    { fill: #f05e01; }
    27.20%    { fill: #fb6700; }
    29.67%    { fill: #ff6a00; animation-timing-function: var(--sine-inout); }
    60%, 100% { fill: var(--tl-prune); }
}

/* Règle du guide (pas la garde no-preference du reste de l'app) : cycles ralentis à 6 s plutôt que figés. */
@media (prefers-reduced-motion: reduce) {
    .s[b-p9tw2el1rm], .s *[b-p9tw2el1rm] {
        animation-duration: 6s !important;
    }
}
/* /Shared/InvoiceSearch/ColumnPicker.razor.rz.scp.css */
.column-picker[b-6rbivjxcaj] {
    position: relative;
    flex: 0 0 auto;
}

/* Bouton "Ghost" (Button.md) : transparent, texte accent-strong — action inline répétée, la plus
   discrète des quatre traitements documentés, cohérent avec une action secondaire de la barre d'outils
   du tableau (pas l'action principale de la page). */
.column-picker__toggle[b-6rbivjxcaj] {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    background: transparent;
    border: none;
    color: var(--accent-strong);
    padding: calc(var(--space-2) - 2px) var(--space-4);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
    cursor: pointer;
}

.column-picker__toggle:hover[b-6rbivjxcaj] {
    background: color-mix(in srgb, var(--accent-strong) 8%, transparent);
}

.column-picker__toggle:focus-visible[b-6rbivjxcaj] {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.column-picker__panel[b-6rbivjxcaj] {
    position: absolute;
    top: calc(100% + var(--space-1));
    right: 0;
    z-index: 10;
    background: var(--surface-raised);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    padding: var(--space-2);
    min-width: 220px;
    max-height: 320px;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.column-picker__option[b-6rbivjxcaj] {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-1) var(--space-2);
    border-radius: var(--radius-sm);
    color: var(--ink);
    cursor: pointer;
    white-space: nowrap;
}

.column-picker__option:hover[b-6rbivjxcaj] {
    background: var(--surface-sunken);
}
/* /Shared/InvoiceSearch/FilterChip.razor.rz.scp.css */
/* Reprend le langage visuel de Badge (surface-badge, radius-full — cf. design-guidelines/components/
   Badge/README.md) mais ajoute une affordance de suppression (×) non documentée sur Badge — écart
   assumé et documenté (cf. plan docs/plans/recherche-manuelle-invoice-lines.md côté Client), même
   posture que les autres écarts déjà loggés dans CLAUDE.md Client §5. */
.filter-chip[b-x9nn4mh1s7] {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    background: var(--surface-badge);
    border-radius: var(--radius-full);
    padding: var(--space-1) var(--space-1) var(--space-1) var(--space-3);
    color: var(--ink);
}

/* Même nudge optique que Badge.md (.txt) : DM Sans rend visiblement bas dans une ligne serrée à 12px. */
.filter-chip__txt[b-x9nn4mh1s7] {
    position: relative;
    top: -0.75px;
    line-height: 1;
    white-space: nowrap;
}

.filter-chip__remove[b-x9nn4mh1s7] {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    flex: 0 0 auto;
    border: none;
    border-radius: var(--radius-full);
    background: transparent;
    color: var(--ink-secondary);
    cursor: pointer;
}

.filter-chip__remove:hover[b-x9nn4mh1s7] {
    background: color-mix(in srgb, var(--ink) 12%, transparent);
    color: var(--ink);
}

.filter-chip__remove:focus-visible[b-x9nn4mh1s7] {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}
/* /Shared/InvoiceSearch/FilterPanel.razor.rz.scp.css */
.filter-panel[b-hgsyxviwcb] {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.filter-panel__title[b-hgsyxviwcb] {
    margin: 0;
}

/* Grille plutôt qu'une pile verticale (retour utilisateur : "bloc qui s'étend en colonne, peu pratique")
   — chaque catégorie de filtre (nom/période/fournisseurs/matériaux/options/dimension) devient une section
   à part, posées côte à côte tant que la largeur le permet plutôt qu'empilées les unes sous les autres. */
.filter-panel__sections[b-hgsyxviwcb] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: var(--space-4);
}

/* Regroupement visuel par section — pas de composant dédié dans le design system (gap comblé, même
   posture que Sidebar/FilterChip déjà documentés comme écarts en CLAUDE.md Client §4/§5bis). Un bordure
   `divider` (pas `border`, réservée aux contours de contrôle) plutôt qu'un remplissage `surface-sunken` :
   les champs à l'intérieur (.filter-panel__input) sont déjà surface-sunken, un fond de section identique
   aurait rendu les deux indiscernables. Pas en contradiction avec la règle Card ("jamais de bordure en plus
   de l'ombre") : ce ne sont pas des Card, seulement des groupes internes à celle-ci. */
.filter-panel__section[b-hgsyxviwcb] {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    box-shadow: var(--shadow-md);
    border-radius: var(--radius-md);
    padding: var(--space-3);
}

.filter-panel__section--dimension[b-hgsyxviwcb] {
    grid-column: span 2;
}

/* Micro-label de groupe (écart documenté, même esprit que ".meta"/eyebrow déjà utilisé pour la sidebar,
   cf. CLAUDE.md Client §4) : distinct à la fois du titre de panneau (.h3 sur filter-panel__title) et des
   labels de champ (.label, ex. "Date début") pour ne pas confondre les trois niveaux. */
.filter-panel__section-title[b-hgsyxviwcb] {
    margin: 0;
    font: var(--text-body-strong); 
}

.filter-panel__row[b-hgsyxviwcb] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
}

.filter-panel__field[b-hgsyxviwcb] {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    flex: 1 1 120px;
}

/* Variante "champ texte standard" du design system (SearchInput/README.md) : radius-sm, rectangulaire,
   contour border neutre au repos — la variante pilule/accent-strong est réservée au champ de recherche
   principal du chat (ChatComposer), pas à un panneau de filtres secondaire. */
.filter-panel__input[b-hgsyxviwcb] {
    background: var(--surface);
    border: 1px solid var(--divider);
    border-radius: var(--radius-sm);
    padding: var(--space-1) var(--space-2);
    color: var(--ink);
    font: var(--text-body);
    width: 100%;
}

.filter-panel__input[b-hgsyxviwcb]::placeholder {
    color: var(--ink-secondary);
}

.filter-panel__input:focus[b-hgsyxviwcb] {
    background: var(--surface-raised);
    border-color: var(--accent);
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}

.filter-panel__input:disabled[b-hgsyxviwcb] {
    color: var(--ink-secondary);
    cursor: default;
}

.filter-panel__dropdown[b-hgsyxviwcb] {
    position: relative;
}

.filter-panel__dropdown-toggle[b-hgsyxviwcb] {
    width: 100%;
    text-align: left;
    cursor: pointer;
}

/* Plein écran (position: fixed) plutôt que limité à .filter-panel__dropdown : capte un clic n'importe où
   "ailleurs" pour fermer le menu (cf. FilterPanel.CloseDropdowns), y compris au-dessus d'une autre section
   du panneau de filtres. Sans arrière-plan visible (transparent) : un vrai overlay assombrissant serait
   hors charte pour un simple menu déroulant. Élément frère du panneau, pas un ancêtre : un clic à
   l'intérieur du panneau (z-index supérieur) ne traverse jamais jusqu'au backdrop, pas besoin de
   @onclick:stopPropagation sur le contenu du menu. */
.filter-panel__dropdown-backdrop[b-hgsyxviwcb] {
    position: fixed;
    inset: 0;
    z-index: 15;
    background: transparent;
}

.filter-panel__dropdown-panel[b-hgsyxviwcb] {
    position: absolute;
    top: calc(100% + var(--space-1));
    left: 0;
    right: 0;
    /* Au-dessus du backdrop ci-dessus ET de tout élément statique du panneau (autres .filter-panel__section,
       tableau de résultats sous ce panneau) — valeur relevée de 10 à 20, l'ancienne valeur pouvait se faire
       recouvrir par une section voisine plus bas dans la grille (retour utilisateur). */
    z-index: 20;
    background: var(--surface-raised);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    padding: var(--space-2);
    max-height: 260px;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

/* Barre de recherche interne au menu (retour utilisateur : ces listes fournisseurs/matériaux peuvent être
   nombreuses) — fixée en tête du menu déroulant, filtre la liste déjà chargée en mémoire sans nouvel appel
   Api (cf. FilteredSuppliers/FilteredMaterials). */
.filter-panel__dropdown-search[b-hgsyxviwcb] {
    margin-bottom: var(--space-1);
    position: sticky;
    top: 0;
}

.filter-panel__dropdown-empty[b-hgsyxviwcb] {
    margin: var(--space-1) 0 0;
    color: var(--ink-secondary);
    text-align: center;
}

.filter-panel__option[b-hgsyxviwcb] {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-1) var(--space-2);
    border-radius: var(--radius-sm);
    color: var(--ink);
    cursor: pointer;
}

.filter-panel__option:hover[b-hgsyxviwcb] {
    background: var(--surface-sunken);
}

.filter-panel__checkbox[b-hgsyxviwcb] {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    color: var(--ink);
}

.filter-panel__dimension-inputs[b-hgsyxviwcb] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
}

.filter-panel__dimension-inputs .filter-panel__input[b-hgsyxviwcb] {
    width: auto;
    flex: 1 1 120px;
}

.filter-panel__number[b-hgsyxviwcb] {
    width: 90px;
    flex: 0 0 90px;
}

/* Bouton "Secondaire" (Button.md) : surface-raised, ink, shadow-sm — pas d'accent-strong, cette action
   est une étape de composition (ajouter UN filtre parmi d'autres), pas l'action principale de la page. */
.filter-panel__add[b-hgsyxviwcb] {
    background: var(--surface-raised);
    color: var(--ink);
    border: none;
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
    padding: calc(var(--space-2) - 2px) var(--space-4);
    font: var(--text-body-strong);
    cursor: pointer;
    flex: 0 0 auto;
}

.filter-panel__add:hover:not(:disabled)[b-hgsyxviwcb] {
    background: color-mix(in srgb, var(--surface-raised) 92%, black);
}

.filter-panel__add:focus-visible[b-hgsyxviwcb] {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* Disabled = surface-sunken/border (Button.md) — jamais un simple estompage d'opacité, qui laverait le
   fond chaud de la marque. */
.filter-panel__add:disabled[b-hgsyxviwcb] {
    background: var(--surface-sunken);
    color: var(--border);
    box-shadow: none;
    cursor: default;
}

/* Bloc "Filtres actifs" — sa propre section délimitée (retour utilisateur), même traitement que
   .filter-panel__section plutôt qu'un simple filet .filter-panel__chips au fil de l'eau. */
.filter-panel__active[b-hgsyxviwcb] {
    display: flex;
    flex-direction: column;
    gap: var(--space-2); 
    border-radius: var(--radius-md);
    padding: var(--space-3);
}

.filter-panel__chips[b-hgsyxviwcb] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
}

@media (max-width: 640px) {
    .filter-panel__section--dimension[b-hgsyxviwcb] {
        grid-column: span 1;
    }
}
/* /Shared/InvoiceSearch/InvoiceResultsTable.razor.rz.scp.css */
/* Même lecture de DataTable.md ("The table is a Card internally") que .chat-block--table côté chat :
   le tableau affleure les bords de sa propre carte plutôt que d'hériter du padding générique de .card
   (space-4) tout autour — overflow:hidden découpe les coins carrés du tableau/de l'en-tête sur le
   radius-md hérité de .card. Statut/pagination reprennent leur propre padding puisque celui de .card ne
   s'applique plus ici. */
.invoice-results[b-z4h09efpob] {
    padding: 0;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

.invoice-results__status[b-z4h09efpob] {
    padding: var(--space-4);
    color: var(--ink-secondary);
}

.invoice-results__pagination[b-z4h09efpob] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    border-top: 1px solid var(--divider);
}

.invoice-results__count[b-z4h09efpob] {
    color: var(--ink-secondary);
}

.invoice-results__pagination-buttons[b-z4h09efpob] {
    display: flex;
    gap: var(--space-2);
}

/* Bouton "Secondaire" (Button.md), même enveloppe que FilterPanel__add. */
.invoice-results__page-button[b-z4h09efpob] {
    background: var(--surface-raised);
    color: var(--ink);
    border: none;
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
    padding: calc(var(--space-2) - 2px) var(--space-4);
    font: var(--text-body-strong);
    cursor: pointer;
}

.invoice-results__page-button:hover:not(:disabled)[b-z4h09efpob] {
    background: color-mix(in srgb, var(--surface-raised) 92%, black);
}

.invoice-results__page-button:focus-visible[b-z4h09efpob] {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.invoice-results__page-button:disabled[b-z4h09efpob] {
    background: var(--surface-sunken);
    color: var(--border);
    box-shadow: none;
    cursor: default;
}
/* /Shared/InvoiceSearch/InvoiceSearchView.razor.rz.scp.css */
.invoice-search-view[b-ajrx3ln6ya] {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    overflow-y: auto;
}

.invoice-search-view__header[b-ajrx3ln6ya] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    flex: 0 0 auto;
}

.invoice-search-view__body[b-ajrx3ln6ya] {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.invoice-search-view__error[b-ajrx3ln6ya] {
    color: var(--danger);
}

/* Occupe toute la place que header+body prendraient normalement (flex:1 1 auto sur .invoice-search-view,
   même mécanisme que ChatWindow, cf. CLAUDE.md Client §5) — tant que les filtres (matériaux, types de
   dimension...) ne sont pas chargés, aucune interaction utile n'est possible sur cette page. Pas de
   composant Spinner documenté dans le design system (gap explicite, même posture que Sidebar/FilterChip) :
   anneau en tokens génériques (border/accent) plutôt qu'une valeur improvisée. */
.invoice-search-view__loading[b-ajrx3ln6ya] {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-3);
}

.invoice-search-view__loading-text[b-ajrx3ln6ya] {
    color: var(--ink-secondary);
}

.invoice-search-view__spinner[b-ajrx3ln6ya] {
    width: 32px;
    height: 32px;
    border-radius: var(--radius-full);
    border: 3px solid var(--border);
    border-top-color: var(--accent);
}

@media (prefers-reduced-motion: no-preference) {
    .invoice-search-view__spinner[b-ajrx3ln6ya] {
        animation: invoice-search-view-spin-b-ajrx3ln6ya 800ms linear infinite;
    }
}

@keyframes invoice-search-view-spin-b-ajrx3ln6ya {
    to {
        transform: rotate(360deg);
    }
}
