/* Auto-generated by fulgore:css:bundle — do not edit manually */

/* fulgore: auth/mfa_challenge_form.css */
.auth-mfa-challenge-form {
  max-width: 28rem;
  margin: var(--space-16) auto;
  display: grid;
  gap: var(--space-6);
}

.auth-mfa-challenge-form h2 {
  margin: 0;
}

.auth-mfa-challenge-form form {
  display: grid;
  gap: var(--space-5);
}


/* fulgore: auth/mfa_disable_modal.css */
.mfa-disable-modal__icon {
  text-align: center;
  font-size: 2rem;
  margin-bottom: var(--space-2);
}

.mfa-disable-modal__warning {
  color: var(--color-text-subtle);
  text-align: center;
  line-height: var(--line-height-loose);
}


/* fulgore: auth/mfa_setup_form.css */
/* LE QR A BESOIN D'UN FOND CLAIR, SINON IL NE SE SCANNE PAS.
   RQRCode le peint en `#000` et ne pose aucun fond (Mfa::Enroll, `color: "000"`).
   Un consumer dont le gabarit d'accès est sombre obtient donc du noir sur noir :
   mesuré au rendu WebKit sur Fatima le 2026-08-31, 1,03:1 de contraste. Le QR
   était bien là, bien centré, bien dimensionné — et parfaitement inscannable,
   donc personne ne s'enrôlait et personne n'entrait dans l'admin.

   Aucun spec ne pouvait le voir : la couleur des modules vit dans les octets du
   SVG, pas dans un style calculé. C'est la capture qui l'a sorti.

   La marge n'est pas décorative : les lecteurs de QR attendent une zone de
   silence autour du motif pour l'accrocher. */
.auth-mfa-setup-form {
  .mfa-qr-code {
    display: flex;
    justify-content: center;
    margin-block: var(--space-4);
    margin-inline: auto;
    width: fit-content;
    background: #fff;
    padding: var(--space-4);
    border-radius: var(--radius-md);
  }
}


/* fulgore: shared/errors/base.css */
.shared-errors-not-found,
.shared-errors-internal-server {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 60vh;
  text-align: center;
  gap: var(--space-6);
  padding: var(--space-10);
}

.shared-errors-not-found__code,
.shared-errors-internal-server__code {
  display: block;
  font-size: 8rem;
  font-weight: var(--font-weight-bold);
  color: var(--color-text-subtle);
  line-height: 1;
}

.shared-errors-not-found__title,
.shared-errors-internal-server__title {
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
  margin: 0;
}

.shared-errors-not-found__description,
.shared-errors-internal-server__description {
  color: var(--color-text-subtle);
  margin: 0;
}

/* Raccourcis facultatifs sous le bouton de retour. Ils s'enroulent plutôt que
   de déborder : sur un écran étroit, quatre libellés ne tiennent pas sur une
   ligne. */
.shared-errors-not-found__links,
.shared-errors-internal-server__links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--space-2) var(--space-4);
  max-width: 100%;
}


/* fulgore: shared/flash.css */
@keyframes flash-enter {
  from {
    opacity: 0;
    transform: translateY(-8px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes flash-exit {
  from {
    opacity: 1;
    transform: translateY(0);
  }

  to {
    opacity: 0;
    transform: translateY(-4px);
  }
}

.flash-container {
  
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  position: fixed;
  top: calc(var(--navbar-height) + var(--space-4));
  right: var(--space-6);
  z-index: 1000;

  
  min-width: 280px;
  max-width: 400px;
}

.flash-item {
  
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  gap: var(--space-3);

  .svg {
    width: var(--icon-size-sm);
    height: var(--icon-size-sm);
  }

  
  min-width: 280px;
  max-width: 400px;
  padding: var(--space-4);
  margin-bottom: var(--space-2);
  border-left: 3px solid;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md, 0 4px 12px rgba(0, 0, 0, 0.12));

  
  animation: flash-enter var(--duration-normal) var(--easing-default) both;

  &:last-child {
    margin-bottom: 0;
  }

  &.flash-item--exiting {
    animation: flash-exit var(--duration-fast) var(--easing-default) forwards;
  }
}

.flash-notice {
  background: var(--color-success-surface);
  color: var(--color-success);
  border-color: var(--color-success);
}

.flash-alert {
  background: var(--color-danger-surface);
  color: var(--color-danger);
  border-color: var(--color-danger);
}

.flash-warning {
  background: var(--color-warning-surface);
  color: var(--color-warning);
  border-color: var(--color-warning);
}

.flash-info {
  background: var(--color-info-surface);
  color: var(--color-info);
  border-color: var(--color-info);
}

.flash-icon {
  
  flex-shrink: 0;

  
  width: var(--icon-size-sm);
  height: var(--icon-size-sm);
  margin-top: 1px;
}

.flash-body {
  
  display: flex;
  flex-direction: column;
  flex: 1;
  gap: var(--space-1);
}

.flash-message {
  
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  line-height: 1.4;

  flex: 1;
}

.flash-dismiss {
  
  flex-shrink: 0;

  
  padding: 0;
  border: none;

  
  line-height: 1;

  
  color: inherit;
  background: none;

  
  cursor: pointer;
  opacity: 0.6;
  transition: opacity var(--duration-fast) var(--easing-default);

  &:hover {
    opacity: 1;
  }

  .svg {
    width: var(--icon-size-sm);
    height: var(--icon-size-sm);
  }

  svg {
    display: block;
    width: var(--icon-size-sm);
    height: var(--icon-size-sm);
  }
}


/* fulgore: surveys/base_completion_screen.css */
.surveys-base-completion-screen {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-4);
  margin-block-start: var(--space-8);
}

.surveys-base-completion-screen__heading {
  font-size: var(--font-size-4xl);
  font-weight: var(--font-weight-bold);
  color: var(--color-text);
  margin: 0;
}

.surveys-base-completion-screen__description {
  font-size: var(--font-size-xl);
  color: var(--color-text-subtle);
  margin: 0;
  white-space: pre-line;
}

.surveys-base-completion-screen__actions {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  margin-block-start: var(--space-4);
  margin-block-end: var(--space-8);
}

.surveys-base-completion-screen__footer {
  align-self: flex-start;
}


/* fulgore: surveys/context_block.css */
.surveys-context-block {
  display: flex;
  flex-direction: column;
}

.surveys-context-block > * {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

/* ── Heading ── */

.surveys-context-block h2 {
  margin: 0;
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-brand);
}

/* ── Description ── */

.surveys-context-block p {
  margin: 0;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-normal);
  line-height: var(--line-height-loose);
  color: var(--color-text-subtle);
}

/* ── Label / Value pairs ── */

.surveys-context-block div > span:first-child {
  display: block;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  color: var(--color-brand-light);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: var(--space-1);
}

.surveys-context-block div > span:last-child {
  display: block;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-normal);
  color: var(--color-text-subtle);
}

/* ── Lists (steps, units) ── */

.surveys-context-block ol,
.surveys-context-block ul {
  margin: 0;
  padding-left: var(--space-5);
}

.surveys-context-block li {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-normal);
  line-height: var(--line-height-loose);
  color: var(--color-text-subtle);
  margin-bottom: var(--space-1);
}

.surveys-context-block ol li::marker {
  color: var(--color-brand-light);
  font-weight: var(--font-weight-semibold);
}


/* fulgore: surveys/inputs/base.css */
.surveys-inputs-base {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}


/* fulgore: surveys/inputs/boolean_card.css */
.ui-form:has(.surveys-inputs-boolean-card) {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-3);
}

.ui-form:has(.surveys-inputs-boolean-card) .form-actions,
.ui-form:has(.surveys-inputs-boolean-card) .ui-input {
  grid-column: 1 / -1;
}

.surveys-inputs-boolean-card__card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-5) var(--space-3);
  border: 1.5px solid var(--color-brand-a10);
  border-radius: var(--radius-lg);
  background: var(--color-brand-surface);
  cursor: pointer;
  transition: border-color 200ms ease-out, box-shadow 200ms ease-out, transform 150ms ease-out;
  text-align: center;
}

.surveys-inputs-boolean-card__card:hover {
  border-color: var(--color-brand-light);
  box-shadow: 0 0 0 3px var(--color-brand-a10);
  transform: translateY(-2px);
}

.surveys-inputs-boolean-card__card:active {
  transform: translateY(0);
  box-shadow: none;
}

.surveys-inputs-boolean-card__checkbox:checked + .surveys-inputs-boolean-card__card {
  border-color: var(--color-brand);
  box-shadow: 0 0 0 3px var(--color-brand-a20);
}

.surveys-inputs-boolean-card__checkbox {
  position: absolute;
  width: 0;
  height: 0;
  opacity: 0;
  overflow: hidden;
}

.surveys-inputs-boolean-card__icon {
  font-size: var(--font-size-2xl);
  line-height: 1;
}

.surveys-inputs-boolean-card__label {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
}

@media (max-width: 767px) {
  .ui-form:has(.surveys-inputs-boolean-card) {
    grid-template-columns: repeat(2, 1fr);
  }
}


/* fulgore: surveys/inputs/choice_card.css */
.surveys-inputs-choice-card__form {
  display: contents;
}

.surveys-inputs-choice-card__button {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);

  padding: var(--space-5) var(--space-4);
  border: 1.5px solid var(--color-brand-a10);
  border-radius: var(--radius-lg);
  background: var(--color-brand-surface);

  cursor: pointer;
  transition: border-color 200ms ease-out, box-shadow 200ms ease-out, transform 150ms ease-out;
}

.surveys-inputs-choice-card__button:hover {
  border-color: var(--color-brand-light);
  box-shadow: 0 0 0 3px var(--color-brand-a10);
  transform: translateY(-2px);
}

.surveys-inputs-choice-card__button:active {
  transform: translateY(0);
  box-shadow: none;
}

.surveys-inputs-choice-card__icon {
  font-size: var(--font-size-2xl);
  line-height: 1;
}

.surveys-inputs-choice-card__label {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-text);
  text-align: center;
}


/* fulgore: surveys/inputs/descriptive_choice.css */
.surveys-inputs-descriptive-choice {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-3);
}

.surveys-inputs-descriptive-choice__form {
  display: contents;
}

.surveys-inputs-descriptive-choice__card {
  flex: 0 1 240px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-5) var(--space-3);
  border: 1.5px solid var(--color-brand-a10);
  border-radius: var(--radius-lg);
  background: var(--color-brand-surface);
  cursor: pointer;
  transition: border-color 200ms ease-out, box-shadow 200ms ease-out, transform 150ms ease-out;
  text-align: center;
}

.surveys-inputs-descriptive-choice__card:hover {
  border-color: var(--color-brand-light);
  box-shadow: 0 0 0 3px var(--color-brand-a10);
  transform: translateY(-2px);
}

.surveys-inputs-descriptive-choice__card:active {
  transform: translateY(0);
  box-shadow: none;
}

.surveys-inputs-descriptive-choice__card--selected {
  border-color: var(--color-brand);
  box-shadow: 0 0 0 3px var(--color-brand-a20);
}

.surveys-inputs-descriptive-choice__icon {
  font-size: var(--font-size-2xl);
  line-height: 1;
}

.surveys-inputs-descriptive-choice__label {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
}

.surveys-inputs-descriptive-choice__description {
  font-size: var(--font-size-xs);
  color: var(--color-text-subtle);
  line-height: var(--line-height-loose);
}



/* fulgore: surveys/map.css */
.surveys-map {
  --stop-height: 40px;
  --badge-size: 24px;

  position: relative;
  padding: var(--space-6);
  border-radius: var(--radius-lg);
  background: var(--color-surface-subtle);
}

.surveys-map__list {
  list-style: none;
  padding: 0;
  margin: 0;
}

/* ── SVG paths overlay ── */

.surveys-map__stops-wrapper {
  position: relative;
}

.surveys-map__paths {
  position: absolute;
  top: 0;
  left: 0;
  width: var(--badge-size);
  height: 100%;
  overflow: visible;
  pointer-events: none;
  z-index: 1;
}

.surveys-map__list {
  position: relative;
  z-index: 2;
}

/* ── Collapsible body ── */

.surveys-map__details {
  position: relative;
  z-index: 20;
  margin-top: var(--space-3);
}

.surveys-map__toggle {
  display: none;
}

.surveys-map__body {
  display: grid;
  grid-template-rows: 1fr;
  transition: grid-template-rows 400ms ease-out, opacity 400ms ease-out;
  opacity: 1;
}

.surveys-map__details:not([open]) .surveys-map__body {
  grid-template-rows: 0fr;
  opacity: 0;
}

.surveys-map__body > * {
  overflow: visible;
}

/* ── SVG path draw animation ── */

.surveys-map__segment {
  stroke-dasharray: var(--segment-length);
  stroke-dashoffset: var(--segment-length);
  animation: map-draw 500ms ease-out forwards;
}

.surveys-map__arc-segment {
  stroke-dasharray: var(--segment-length);
  stroke-dashoffset: var(--segment-length);
  animation: map-draw 800ms ease-in-out forwards;
  animation-delay: 200ms;
}

@keyframes map-draw {
  to { stroke-dashoffset: 0; }
}

/* Mobile — collapsed by default, toggle visible */
@media (max-width: 767px) {
  .surveys-map__toggle {
    display: block;
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--color-brand);
    cursor: pointer;
    list-style: none;
    margin-bottom: var(--space-3);
  }

  .surveys-map__toggle::-webkit-details-marker {
    display: none;
  }

  .surveys-map__toggle::before {
    content: "▸ ";
  }

  .surveys-map__details[open] > .surveys-map__toggle::before {
    content: "▾ ";
  }
}


/* fulgore: surveys/map/arc.css */
/* Arc — loop-back indicator connecting a later stop back to an earlier one.
   Rendered as a left bracket with an arrow pointing up at the target. */

.surveys-map-arc {
  position: absolute;

  /* Vertical span: from target badge center to source badge center */
  top: calc(var(--space-6) + var(--space-3) + (var(--arc-to) + 0.5) * var(--stop-height));
  height: calc((var(--arc-from) - var(--arc-to)) * var(--stop-height));

  /* Horizontal: dedicated rail left of forks.
     Arc sits in the --arc-rail zone, forks sit in the --arc-indent zone. */
  left: 6px;
  right: calc(100% - var(--arc-rail) - var(--arc-indent) - var(--space-6) - var(--badge-size) / 2);

  /* Thinner than forks (2px vs 3px) to reduce visual noise */
  border: 2px solid var(--color-border);
  border-right: none;
  border-radius: var(--radius-md) 0 0 var(--radius-md);

  z-index: var(--arc-z);
  pointer-events: none;
}

/* Arrow pointing UP at the target stop */
.surveys-map-arc::before {
  content: "";
  position: absolute;
  top: -5px;
  right: -6px;

  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-bottom: 6px solid var(--color-border);
}

/* Brand fill overlay — animates top-to-bottom (visual: "going back up") when loop is active */
.surveys-map-arc--active {
  border-color: var(--color-brand);
}

.surveys-map-arc--active::before {
  border-bottom-color: var(--color-brand);
}

.surveys-map-arc--active::after {
  content: "";
  position: absolute;
  top: -2px;
  left: -2px;
  bottom: -2px;
  right: 0;

  border: 2px solid var(--color-brand);
  border-right: none;
  border-radius: var(--radius-md) 0 0 var(--radius-md);

  clip-path: inset(100% 0 0 0);
  animation: arc-fill 800ms ease-out forwards;
  animation-delay: 400ms;
}

@keyframes arc-fill {
  0% { clip-path: inset(100% 0 0 0); }
  100% { clip-path: inset(0 0 0 0); }
}

/* Hide when map is collapsed on mobile */
@media (max-width: 767px) {
  .surveys-map__details:not([open]) ~ .surveys-map-arc {
    display: none;
  }
}


/* fulgore: surveys/map/fork.css */
/* Fork — left bracket connecting two badges (skip path) */

.surveys-map-fork {
  position: absolute;

  /* Top edge at fork-from badge center, bottom edge at fork-to badge center */
  top: calc(var(--space-6) + var(--space-3) + (var(--fork-from) + 0.5) * var(--stop-height));
  height: calc((var(--fork-to) - var(--fork-from)) * var(--stop-height));

  /* Left bracket in the arc-indent gutter (after the arc rail), right edge at badge center */
  left: calc(var(--arc-rail) + var(--space-6));
  right: calc(100% - var(--arc-rail) - var(--arc-indent) - var(--space-6) - var(--badge-size) / 2);

  border: 3px solid var(--color-border);
  border-right: none;
  border-radius: var(--radius-lg) 0 0 var(--radius-lg);
  z-index: 10;
}

/* Brand fill overlay — progressive top-to-bottom reveal when taken */
.surveys-map-fork--taken::after {
  content: "";
  position: absolute;
  top: -3px;
  left: -3px;
  bottom: -3px;
  right: 0;

  border: 3px solid var(--color-brand);
  border-right: none;
  border-radius: var(--radius-lg) 0 0 var(--radius-lg);

  clip-path: inset(0 0 100% 0);
  animation: fork-fill 1200ms ease-in-out forwards;
  animation-delay: 300ms;
}

@keyframes fork-fill {
  0% { clip-path: inset(0 0 100% 0); }
  100% { clip-path: inset(0 0 0 0); }
}

/* Hide when map is collapsed on mobile */
@media (max-width: 767px) {
  .surveys-map__details:not([open]) ~ .surveys-map-fork {
    display: none;
  }
}


/* fulgore: surveys/map/progress.css */
.surveys-map-progress {
  position: absolute;
  top: var(--space-4);
  right: var(--space-4);

  padding: var(--space-2) var(--space-3);
  border: 1.5px solid var(--color-brand-a10);
  border-radius: var(--radius-lg);
  background: var(--color-brand-surface);

  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  font-variant-numeric: tabular-nums;
  color: var(--color-brand);
}


/* fulgore: surveys/map/stop.css */
.surveys-map-stop {
  --badge-size: 24px;

  display: flex;
  align-items: center;
  gap: var(--space-3);
  height: var(--stop-height);
  position: relative;
}

/* ── Badge ── */

.surveys-map-stop__badge {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;

  width: var(--badge-size);
  height: var(--badge-size);
  border-radius: var(--radius-full);

  position: relative;
  z-index: 20;

  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  line-height: 1;
}

/* ── Label ── */

.surveys-map-stop__label {
  font-size: var(--font-size-sm);
  line-height: var(--line-height-tight);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ── States ── */

/* Completed */
.surveys-map-stop--completed .surveys-map-stop__badge {
  background: var(--color-brand);
  color: var(--color-text-inverted);
}

.surveys-map-stop--completed .surveys-map-stop__label {
  color: var(--color-text-subtle);
}

.surveys-map-stop--completed .surveys-map-stop__badge .ui-icon {
  width: 14px;
  height: 14px;
}

/* Animated — pulse + check reveal (only on just-completed stop) */
.surveys-map-stop--animate .surveys-map-stop__badge {
  animation: badge-complete-pulse 250ms ease-out;
  animation-delay: calc(var(--stop-index, 0) * 150ms);
}

.surveys-map-stop--animate .surveys-map-stop__badge .ui-icon {
  opacity: 0;
  clip-path: inset(0 100% 0 0);
  animation: check-reveal 800ms ease-out forwards;
  animation-delay: calc(var(--stop-index, 0) * 150ms + 400ms);
}

@keyframes badge-complete-pulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.3); }
}

@keyframes check-reveal {
  0% {
    opacity: 0;
    clip-path: inset(0 100% 0 0);
  }
  20% {
    opacity: 1;
  }
  100% {
    opacity: 1;
    clip-path: inset(0 0 0 0);
  }
}

/* Current */
.surveys-map-stop--current .surveys-map-stop__badge {
  background: var(--color-brand);
  color: var(--color-text-inverted);

  animation-name: badge-activate, survey-map-pulse;
  animation-duration: 300ms, 2s;
  animation-timing-function: ease-out, ease-in-out;
  animation-delay:
    calc(var(--stop-index, 0) * 150ms + 600ms),
    calc(var(--stop-index, 0) * 150ms + 900ms);
  animation-iteration-count: 1, infinite;
  animation-fill-mode: backwards, none;
}

@keyframes badge-activate {
  from {
    background: var(--color-surface-subtle);
    outline: 2px solid var(--color-border);
    outline-offset: -2px;
    color: transparent;
    box-shadow: none;
  }
  to {
    background: var(--color-brand);
    outline: 2px solid transparent;
    outline-offset: -2px;
    color: var(--color-text-inverted);
    box-shadow: none;
  }
}

.surveys-map-stop--current .surveys-map-stop__label {
  color: var(--color-text);
  font-weight: var(--font-weight-semibold);
}

@keyframes survey-map-pulse {
  0%, 100% {
    box-shadow: 0 0 0 0 var(--color-brand-a20);
  }
  50% {
    box-shadow: 0 0 0 6px var(--color-brand-a20);
  }
}

/* Upcoming */
.surveys-map-stop--upcoming .surveys-map-stop__badge {
  background: var(--color-surface-subtle);
  outline: 2px solid var(--color-border);
  outline-offset: -2px;
}

.surveys-map-stop--upcoming .surveys-map-stop__label {
  color: var(--color-text-disabled);
}

/* Skipped */
.surveys-map-stop--skipped .surveys-map-stop__badge {
  background: var(--color-surface-subtle);
  outline: 2px dashed var(--color-border);
  outline-offset: -2px;
}

.surveys-map-stop--skipped .surveys-map-stop__label {
  color: var(--color-text-disabled);
  text-decoration: line-through;
}

/* ── End stop ── */

.surveys-map-stop--end .surveys-map-stop__badge {
  width: calc(var(--badge-size) * 0.6);
  height: calc(var(--badge-size) * 0.6);
  margin-left: calc(var(--badge-size) * 0.2);
}

.surveys-map-stop--end.surveys-map-stop--completed .surveys-map-stop__badge {
  width: var(--badge-size);
  height: var(--badge-size);
  margin-left: 0;
  background: var(--color-success-surface);
  outline: none;
  font-size: var(--font-size-base);
  animation: tada-pop 600ms ease-out;
}

@keyframes tada-pop {
  0% { transform: scale(0); opacity: 0; }
  50% { transform: scale(1.4); opacity: 1; }
  70% { transform: scale(0.9); }
  100% { transform: scale(1); opacity: 1; }
}

.surveys-map-stop--end .surveys-map-stop__label {
  font-style: italic;
}

/* ── Clickable wrapper (jump_path active) ── */

.surveys-map-stop__form {
  display: contents;
}

.surveys-map-stop__button {
  all: unset;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  cursor: pointer;
}

.surveys-map-stop__button:hover .surveys-map-stop__label {
  color: var(--color-text);
}


/* fulgore: surveys/question_forms/footer.css */
.surveys-question-forms-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: var(--space-6);
}

.surveys-question-forms-footer__submit {
  margin-left: auto;
}


/* fulgore: surveys/question_label.css */
.surveys-question-label {
  font-family: var(--font-family-display);
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-tight);

  color: var(--color-text);

  margin-bottom: var(--space-8);
}


/* fulgore: surveys/question_layout.css */
.surveys-question-layout {
  display: grid;
  /* start : la map et le bloc contexte gardent la hauteur de leur contenu
     au lieu de s'étirer à la hauteur de la colonne principale */
  align-items: start;
  gap: var(--space-6);
}

/* Le frame survey n'est pas un formulaire simple : lever le plafond 48rem
   posé par record-view sur son enfant unique, sinon la grille multi-colonnes
   ci-dessous s'applique dans 768px et écrase la colonne principale. */
.ui-bases-record-view__body > turbo-frame:only-child:has(.surveys-question-layout) {
  max-width: none;
}

.surveys-question-layout__context-block {
  min-height: var(--space-16);
  padding: var(--space-5) var(--space-6);
  border: 1.5px solid var(--color-brand-a10);
  border-radius: var(--radius-lg);
  background: var(--color-brand-surface);
}

.surveys-question-layout__main {
  position: relative;
  z-index: 1;
}

/* ── Transitions ── */

.surveys-question-layout__main {
  opacity: 1;
}

@keyframes surveys-question-enter {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}

.surveys-question-layout__main {
  animation: surveys-question-enter 320ms cubic-bezier(0.4, 0, 0.2, 1) both;
}

@media (prefers-reduced-motion: reduce) {
  .surveys-question-layout__main {
    animation: none;
  }
}

@media (min-width: 768px) {
  .surveys-question-layout {
    grid-template-columns: 3fr 2fr;
    /* 3e rangée 1fr : absorbe l'excédent de hauteur de la colonne
       principale (section dépliée), sinon il se répartit sur la rangée 1
       et le bloc contexte tombe en bas de page. */
    grid-template-rows: auto auto 1fr;
    gap: var(--space-8);
  }

  .surveys-question-layout__main {
    grid-column: 1;
    grid-row: 1 / 4;
  }

  .surveys-map {
    grid-column: 2;
  }

  .surveys-question-layout__context-block {
    grid-column: 2;
  }
}

@media (min-width: 1440px) {
  .surveys-question-layout {
    grid-template-columns: 1fr 280px 280px;
    grid-template-rows: none;
  }

  .surveys-question-layout__main {
    grid-row: auto;
  }

  .surveys-map {
    grid-column: auto;
  }

  .surveys-question-layout__context-block {
    grid-column: auto;
  }
}


/* fulgore: ui/bases/button.css */
.ui-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-5);
  border-radius: var(--radius-md);
  font-family: var(--font-family-base);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  line-height: 1;
  cursor: pointer;
  border: 1.5px solid transparent;
  text-decoration: none;
  white-space: nowrap;
  user-select: none;
  transition:
    background var(--duration-fast) var(--easing-default),
    color var(--duration-fast) var(--easing-default),
    border-color var(--duration-fast) var(--easing-default),
    box-shadow var(--duration-fast) var(--easing-default),
    opacity var(--duration-fast) var(--easing-default);

  .svg {
    height: var(--space-4);
    fill: currentColor;
  }

  &:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring);
  }

  

  &.ui-button--primary {
    background: var(--color-brand);
    color: var(--color-text-inverted);
    border-color: var(--color-brand);

    &:hover:not(:disabled):not(.ui-button--disabled) {
      background: var(--color-brand-dark);
      border-color: var(--color-brand-dark);
    }

    &:active:not(:disabled):not(.ui-button--disabled) {
      background: var(--color-brand-dark);
      box-shadow: none;
    }
  }

  &.ui-button--secondary {
    background: transparent;
    color: var(--color-brand);
    border-color: var(--color-brand);

    &:hover:not(:disabled):not(.ui-button--disabled) {
      background: var(--color-brand-surface);
    }
  }

  &.ui-button--danger {
    background: var(--color-danger);
    color: var(--color-text-inverted);
    border-color: var(--color-danger);

    &:hover:not(:disabled):not(.ui-button--disabled) {
      background: var(--color-danger-dark);
      border-color: var(--color-danger-dark);
    }

    &:active:not(:disabled):not(.ui-button--disabled) {
      background: var(--color-danger-dark);
      box-shadow: none;
    }

    &:focus-visible {
      box-shadow: var(--focus-ring-danger);
    }
  }

  &.ui-button--ghost {
    background: transparent;
    color: var(--color-text-subtle);
    border-color: transparent;

    &:hover:not(:disabled):not(.ui-button--disabled) {
      background: var(--color-surface-raised);
      color: var(--color-text);
    }

    &:focus-visible {
      box-shadow: var(--focus-ring-neutral);
    }
  }

  

  &.ui-button--sm {
    font-size: var(--font-size-xs);
    padding: var(--space-1) var(--space-3);
  }

  &.ui-button--lg {
    font-size: var(--font-size-base);
    padding: var(--space-3) var(--space-6);
  }

  &.ui-button--icon-only {
    padding: var(--space-2);

    /* Shield the icon from consumer resets like `svg { max-width: 100% }`:
       100% of a shrink-to-fit content box computes to 0 width and hides
       the icon entirely — same trap as the sortable grip (cf. row.css). */
    .svg {
      width: var(--space-4);
      min-width: var(--space-4);
      max-width: none;
    }

    &.ui-button--sm {
      padding: var(--space-1);
    }

    &.ui-button--lg {
      padding: var(--space-3);
    }
  }



  /* L'ÉTAT DÉSACTIVÉ SE LIT « INACTIF », PAS « CASSÉ ». `opacity: 0.45` délave
     la couleur de marque du consumer sans rien garantir : sur le terracotta de
     FBordes, le libellé blanc tombait à ~2,6:1 (contre 6,44:1 à l'état actif) —
     sous les deux planchers WCAG. Et c'est le PREMIER état que voit un visiteur
     d'un écran de connexion, dont `form-validation` désactive le bouton tant que
     les champs sont vides.
     Des couleurs franches le disent sans ambiguïté et ne dépendent plus de la
     teinte de marque : mesuré 5,69:1 au navigateur le 2026-08-03, dans les deux
     moteurs et aux deux tailles d'écran.
     ⚠️ CE SIDECAR EST LA COPIE SERVIE — voir la note jumelle dans
     `ui/inputs/password.css`. `app/assets/stylesheets/fulgore/button.css` porte
     une seconde définition qui n'atteint aucun consumer. */
  &:disabled,
  &.ui-button--disabled {
    background: var(--color-surface-raised);
    border-color: var(--color-border);
    color: var(--color-text-subtle);
    cursor: not-allowed;
    pointer-events: none;
  }
}


/* fulgore: ui/bases/card.css */
.ui-bases-card {
  box-sizing: border-box;
  margin-inline: auto;
  padding: var(--space-8);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  background: var(--color-surface);
}

.ui-bases-card__heading {
  display: grid;
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-semibold);
  grid-template-columns: min-content auto;
  align-items: end;
}

.ui-bases-card__title {
  font: inherit;
}

.ui-bases-card__details {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: start;
  gap: var(--space-2) var(--space-6);
}

@media (max-width: 480px) {
  .ui-bases-card {
    padding: var(--space-4);
  }

  .ui-bases-card__details {
    grid-template-columns: 1fr;
  }
}


/* fulgore: ui/bases/card_row.css */
.ui-bases-card-row__dt {
  grid-column: 1;
  font-size: var(--font-size-sm);
  color: var(--color-text-subtle);
  font-weight: var(--font-weight-medium);
}

.ui-bases-card-row__dd {
  grid-column: 2;
  margin: 0;
  font-size: var(--font-size-sm);
}

@media (max-width: 480px) {
  .ui-bases-card-row__dt {
    grid-column: auto;
  }

  .ui-bases-card-row__dd {
    grid-column: auto;
  }
}


/* fulgore: ui/bases/context_block.css */
.ui-bases-context-block {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-5) var(--space-6);
  border: 1.5px solid var(--color-brand-a10);
  border-radius: var(--radius-lg);
  background: var(--color-brand-surface);

  .ui-bases-context-block__heading {
    font-size: var(--font-size-base);
    font-weight: var(--font-weight-semibold);
    color: var(--color-brand);
  }

  .ui-bases-context-block__description {
    font-size: var(--font-size-sm);
    color: var(--color-text-subtle);
  }

  .ui-bases-context-block__list {
    margin: 0;
    padding-left: var(--space-5);

    & li {
      font-size: var(--font-size-sm);
      color: var(--color-text-subtle);
      margin-bottom: var(--space-1);
    }
  }
}

.ui-bases-context-block--warning {
  background: var(--color-warning-surface);
  border-color: var(--color-warning-a10);
  margin-bottom: var(--space-6);

  .ui-bases-context-block__heading {
    color: var(--color-warning);
  }
}


/* fulgore: ui/bases/edit.css */
.ui-bases-edit__header {
  margin-block-end: var(--space-6);
}

.ui-bases-edit__body {
}


/* fulgore: ui/bases/filter_bar.css */
/* `flex-start` et non `center` : dès qu'une barre porte des champs de hauteurs
   différentes (un multi-select à huit options est bien plus haut qu'une
   recherche), le centrage aligne chaque champ sur le milieu de sa ligne et
   dessine un escalier. Sur une barre à champs de même hauteur — le cas de tous
   les consumers jusqu'ici — les deux valeurs rendent à l'identique. */
.ui-filter-bar__fields {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
  flex-wrap: wrap;
}

.filter-field__label {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-subtle);
  margin-right: var(--space-2);
}

/* ⚠️ `flex` ET NON `inline-flex`, et c'est le contraire d'un détail. Un
   `inline-flex` se dimensionne sur son CONTENU : sa largeur est « indéfinie »
   au sens de CSS, et tout `width: %` d'un enfant s'y résout alors contre rien
   — l'input retombe sur sa taille intrinsèque quelle que soit la place qu'on
   lui offre. Mesuré le 2026-08-03 : 302 px pris dans un conteneur de 328,
   et 302 px dans une piste de grille de 416 chez RatsAndFrogs, où la barre
   paraissait décentrée alors que la GRILLE était juste.
   Le passage en `flex` (donc de niveau bloc) ne change RIEN aux barres à
   plusieurs champs : `.filter-field--search` y est un élément flex de
   `.ui-filter-bar__fields`, dimensionné sur son `max-content` — vérifié au
   rendu avant/après, à 1280 et 390 px, sur `UI::Bases::ExampleFilterBar`. */
.filter-search-wrapper {
  position: relative;
  display: flex;
  align-items: center;
}

.filter-search {
  padding: var(--space-2) var(--space-8) var(--space-2) var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  font-size: var(--font-size-sm);
  background: var(--color-surface);
  color: var(--color-text);
  min-width: 16rem;

  /* ⚠️ `flex: 1` EST LA SECONDE MOITIÉ DU CORRECTIF, et sans elle la première
     ne sert à rien : passer le conteneur en `flex` lui donne une largeur
     définie, mais l'input reste `flex: 0 1 auto`, donc dimensionné sur son
     contenu. Mesuré le 2026-08-03 par injection : conteneur porté à 600 px,
     input toujours à 302. Les deux règles se tiennent — ne pas en retirer une
     en croyant l'autre suffisante.
     ⚠️⚠️ `flex: 1` ET NON `width: 100%`, essayé d'abord et REVERTÉ : un `100%`
     oblige à déclarer `box-sizing: border-box` (la gem n'a aucune remise à
     zéro globale — chaque composant le déclare chez lui), et ce border-box
     fait alors compter les 46 px de padding et de bordure DANS le `min-width:
     16rem` ci-dessus, qui a toujours été écrit en largeur de contenu. Mesuré :
     les champs des barres passaient de 302 à 256 px, soit 46 px perdus dans
     les dix-sept barres de la flotte. Le flex, lui, dimensionne sur la boîte
     de bordure quel que soit le `box-sizing` — rien à compenser. */
  flex: 1;

  &:focus {
    outline: none;
    border-color: var(--color-brand);
  }
}

.filter-search-clear {
  position: absolute;
  right: var(--space-2);
  display: none;
  align-items: center;
  justify-content: center;
  width: 1.25rem;
  height: 1.25rem;
  background: var(--color-neutral-300);
  color: var(--color-neutral-700);
  border: none;
  border-radius: 999px;
  font-size: var(--font-size-xs);
  line-height: 1;
  cursor: pointer;
  padding: 0;

  &:hover {
    background: var(--color-neutral-400);
  }
}

.filter-search:not(:placeholder-shown) ~ .filter-search-clear {
  display: flex;
}

/* `min-width: 0` est le remède au piège WebKit : un item flex garde par défaut
   `min-width: auto` et refuse de se rétrécir sous son `min-content` — un
   multi-select à beaucoup d'options débordait alors sa case et se dessinait
   PAR-DESSUS le champ voisin. Mesuré en WebKit : recouvrement du champ de
   recherche par les options de type, ramené à zéro par cette règle. */
.filter-field--multi-select {
  display: flex;
  align-items: flex-start;
  flex-wrap: wrap;
  min-width: 0;
  max-width: 100%;
}

.filter-multi-select {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.filter-multi-select__option {
  display: inline-flex;
  align-items: center;
  padding: var(--space-1) var(--space-3);
  border-radius: 999px;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text-subtle);
  cursor: pointer;
  transition: background var(--duration-fast), color var(--duration-fast), border-color var(--duration-fast);

  input[type="checkbox"] {
    display: none;
  }

  &:hover {
    border-color: var(--color-brand);
    color: var(--color-brand);
  }

  &.is-active {
    background: var(--color-brand-surface);
    border-color: var(--color-brand);
    color: var(--color-brand);
    font-weight: var(--font-weight-semibold);
  }

  /* Le badge se teinte par `currentColor` plutôt qu'en dur : l'option prend
     l'une des 12 teintes de `UI::Pill` quand elle est active, et le compteur
     suit sans qu'on redéclare douze règles. */
  .filter-multi-select__count {
    margin-left: var(--space-2);
    min-width: 1.25em;
    padding: 0 var(--space-1);
    border-radius: 999px;
    background: color-mix(in srgb, currentColor 15%, transparent);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    line-height: 1.5;
    text-align: center;
    font-variant-numeric: tabular-nums;
  }
}

.filter-multi-select__option.is-active.ui-pill--violet {
  background: var(--color-violet-100);
  color: var(--color-violet-700);
  border-color: var(--color-violet-100);
}

.filter-multi-select__option.is-active.ui-pill--blue {
  background: var(--color-blue-100);
  color: var(--color-blue-700);
  border-color: var(--color-blue-100);
}

.filter-multi-select__option.is-active.ui-pill--green {
  background: var(--color-green-100);
  color: var(--color-green-700);
  border-color: var(--color-green-100);
}

.filter-multi-select__option.is-active.ui-pill--red {
  background: var(--color-red-100);
  color: var(--color-red-700);
  border-color: var(--color-red-100);
}

.filter-field--switch {
  display: flex;
  align-items: center;
}

.filter-switch {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-size-sm);
  color: var(--color-text-subtle);
  cursor: pointer;

  input[type="checkbox"] {
    width: 1rem;
    height: 1rem;
    accent-color: var(--color-brand);
    cursor: pointer;
  }
}


/* fulgore: ui/bases/form.css */
.ui-bases-form {
  form {
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
  }
}

.ui-form {
  display: grid;

  .ui-input + .ui-input {
    margin-top: var(--space-6);
  }
}

.ui-form__footer {
  margin: var(--space-4) 0 0;
  text-align: center;
  font-size: var(--font-size-sm);

  a {
    color: var(--color-text-subtle);
    transition: color var(--duration-fast) var(--easing-default);

    &:hover {
      color: var(--color-brand);
    }
  }
}

.form-error-summary {
  padding: var(--space-3) var(--space-4);
  background: var(--color-danger-a10);
  border: 1.5px solid var(--color-danger);
  border-radius: var(--radius-md);
  margin-bottom: var(--space-4);

  .form-error-summary__title {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--color-danger);
    margin-bottom: var(--space-2);
  }

  ul {
    margin: 0;
    padding-left: var(--space-4);

    li {
      font-size: var(--font-size-sm);
      color: var(--color-danger);
    }
  }
}

.form-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-6);
  justify-content: flex-end;
}


/* fulgore: ui/bases/input.css */
.ui-input {
  display: grid;
  gap: var(--space-2);

  label {
    display: flex;
    align-items: center;
    justify-content: space-between;
    /* gap : espace minimal entre le texte et le tooltip quand le label est
       à largeur de contenu (checkbox) — space-between n'y suffit pas */
    gap: var(--space-2);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--color-text);
  }

  input,
  textarea {
    width: 100%;
    padding: var(--space-3) var(--space-4);
    font-family: var(--font-family-base);
    font-size: var(--font-size-base);
    color: var(--color-text);
    background: var(--color-surface);
    border: 1.5px solid var(--color-border);
    border-radius: var(--radius-md);
    outline: none;
    box-sizing: border-box;
    transition:
      border-color var(--duration-fast) var(--easing-default),
      box-shadow var(--duration-fast) var(--easing-default);

    &::placeholder {
      color: var(--color-text-disabled);
    }

    &:focus {
      border-color: var(--color-brand);
      box-shadow: var(--focus-ring);
    }
  }

  textarea {
    resize: vertical;
    min-height: 6rem;
    line-height: var(--line-height-normal);
  }

  .ui-input__required {
    color: var(--color-danger);
    margin-left: var(--space-1);
  }

  .ui-input__hint {
    font-size: var(--font-size-xs);
    color: var(--color-text-subtle);
  }

  .ui-input__error {
    font-size: var(--font-size-xs);
    color: var(--color-danger);
  }

  

  &.ui-input--error {
    label {
      color: var(--color-danger);
    }

    input,
    textarea {
      border-color: var(--color-danger);

      &:focus {
        box-shadow: 0 0 0 3px var(--color-danger-a10);
      }
    }
  }

  

  &.ui-input--disabled {
    opacity: 0.5;
    cursor: not-allowed;

    input,
    textarea {
      cursor: not-allowed;
    }
  }
}


/* fulgore: ui/bases/list.css */
.ui-bases-list {
  padding: var(--space-8);
  display: grid;
  gap: var(--space-6);

  h1 {
    margin: 0;
  }
}

.ui-list-sort-disabled-notice {
  margin: var(--space-2) 0 0;
  color: var(--color-text-subtle);
  font-size: var(--font-size-sm);
}

.ui-list-table-wrapper {
  overflow-x: auto;
}

.ui-list-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;

  th,
  td {
    padding: var(--space-3) var(--space-4);
    text-align: left;
    vertical-align: middle;
    border-bottom: 1px solid var(--color-border);
    font-size: var(--font-size-sm);
  }

  th {
    font-weight: var(--font-weight-semibold);
    color: var(--color-text-subtle);
    font-size: var(--font-size-sm);
  }

  /* ⚠️ MONTÉES ICI LE 2026-09-02, ET ELLES CHANGENT L'ASPECT DE TOUTES LES
     LISTES DU PARC. C'étaient les deux seules choses qu'une table de la gem ne
     donnait pas, et deux sidecars de Fatima les recopiaient donc à l'identique.
     Les laisser dehors condamnait chaque consumer à les réécrire pour obtenir
     un tableau d'apparence ordinaire.
     Sous 768 px, `thead` est masqué par la bascule en cartes : la première
     règle y est inerte, la seconde teinte la carte survolée. */
  thead {
    background-color: var(--color-surface-subtle);
  }

  tbody tr:hover {
    background-color: var(--color-surface-subtle);
  }

  .ui-list-table__th--sortable {
    padding: 0;
  }

  .ui-col--spacer {
    width: 100%;
  }

  .ui-col--thumb {
    width: 3rem;
  }

  /* ⚠️ `white-space: nowrap` A CESSÉ D'ÊTRE LE DÉFAUT DE TOUTE CELLULE — NE PAS
     LE REMETTRE SUR `th, td`. Il l'a été jusqu'au 2026-08-02, et il fabriquait
     un débordement là où il n'y avait aucune raison d'en avoir un : la largeur
     du tableau devenait la somme de ses contenus les plus longs tenus sur UNE
     ligne. Mesuré en production sur un tableau de cinq colonnes dans 880 px de
     large — 1010 px de contenu, donc 130 px cachés, à cause d'une seule cellule
     de texte libre (« Me contacter (différents packs proposés) »).

     Et ce débordement n'était pas qu'un défilement de plus : il décalait la
     colonne d'actions collée à droite, qui RECOUVRAIT alors la dernière colonne
     de données. Chez le consumer c'était « Publiée », le champ qui dit si une
     fiche est en ligne — 7 en-têtes dans le DOM, 6 visibles à l'écran, dans les
     deux moteurs. Rien ne rougissait : le `<th>` est bien rendu, il n'est ni
     clippé ni hors cadre, il est simplement PEINT DESSOUS.

     La colonne collée n'était donc pas le défaut, elle en était le symptôme.
     Le `nowrap` général était la cause, et il aurait rejoué sur le prochain
     tableau du prochain site.

     Il reste juste là où couper serait pire que replier : un libellé d'en-tête,
     une vignette, la poignée, le rang, et la cellule d'actions — tous courts ou
     atomiques. Pour une cellule de données qui ne doit jamais se couper (une
     date, un montant, une référence), l'opt-in est `ui-col--nowrap`, dans la
     même famille que `ui-col--optional` / `--important` / `--thumb`.

     Borné à partir de 769 px : en dessous, le tableau devient une pile de
     cartes et TOUT doit se replier (cf. le bloc `max-width: 768px`). */
  @media (min-width: 769px) {
    th,
    .ui-col--nowrap,
    .ui-col--thumb,
    .ui-bases-row__grip,
    .ui-bases-row__position,
    .ui-list-table__td--actions,
    .ui-bases-row__actions {
      white-space: nowrap;
    }
  }

  .ui-list-table__th--right {
    text-align: right;
  }

  .sort-link {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    padding: var(--space-3) var(--space-4);
    color: var(--color-text-subtle);
    text-decoration: none;
    white-space: nowrap;

    &:hover {
      color: var(--color-brand);
    }

    &.sort-link--active {
      color: var(--color-brand);
    }
  }

  .sort-arrow {
    font-size: var(--font-size-xs);
    opacity: 0.5;
  }

  .sort-link--active .sort-arrow {
    opacity: 1;
  }

  .ui-list-table__th--actions,
  .ui-list-table__td--actions,
  .ui-bases-row__actions {
    position: sticky;
    right: 0;
    background: var(--color-surface);
    box-shadow: -4px 0 8px -2px rgb(0 0 0 / 0.04);
  }

  /* `position: sticky` ALWAYS creates a stacking context, so every Actions
     cell is its own layer painted in DOM order — and a RowActionsMenu's
     `z-index: var(--z-dropdown)` only ever ranks INSIDE its own cell. Result:
     an open kebab menu is painted over by the next row's Actions cell (33% of
     the panel covered, measured WebKit + Chromium). Raising just the cell that
     holds an open menu lifts its whole layer above its siblings, which are all
     at `z-index: auto`. Floating mode (`position: fixed`, dropdown_controller)
     escapes CLIPPING, not stacking — it does not help here.
     Keep this rule INSIDE the `.ui-list-table` block: flattened out it drops
     from (0,2,0) to (0,1,0) and is silently outranked. */
  .ui-list-table__td--actions:has(.ui-row-actions-menu.is-open),
  .ui-bases-row__actions:has(.ui-row-actions-menu.is-open) {
    z-index: 1;
  }

}

/* ⚠️ ICI VIVAIT UNE RÈGLE QUI ÉTEIGNAIT L'OMBRE DE LA COLONNE COLLÉE AU-DESSUS
   DE 1025 px — NE PAS LA REMETTRE. L'ombre est le SEUL indice qui dise que
   cette colonne flotte au-dessus du reste et qu'il reste du contenu à sa
   gauche. La couper aux largeurs de bureau, c'est la couper exactement là où
   on regarde : le 2026-08-02, en production à 1280, une colonne de données
   entière était recouverte sans qu'aucun signe ne l'indique — et la barre de
   défilement du cadre mesure 0 px de haut (barre superposée macOS, invisible
   tant qu'on ne fait pas le geste). Aucun indice, donc, d'aucune sorte.

   Le pari de cette règle était « à cette largeur le tableau tient, l'ombre
   serait du bruit ». Il ne tient pas : un tableau déborde en fonction de son
   CONTENU, pas de la largeur de l'écran. Et le bruit est faible — l'ombre vaut
   4 % d'opacité, invisible quand la colonne est à sa place naturelle. */

@media (max-width: 1024px) {
  .ui-list-table .ui-col--optional {
    display: none;
  }
}

@media (max-width: 768px) {
  .ui-list-table {
    display: block;
    width: 100%;

    thead {
      display: none;
    }

    tbody {
      display: block;
      width: 100%;
    }

    .ui-col--optional,
    .ui-col--important {
      display: flex;
    }

    tbody tr {
      display: block;
      width: 100%;
      box-sizing: border-box;
      border: 1px solid var(--color-border);
      border-radius: var(--radius-md);
      margin-bottom: var(--space-3);
      padding: var(--space-2);
      box-shadow: var(--shadow-md);
    }

    td {
      display: flex;
      width: 100%;
      box-sizing: border-box;
      justify-content: space-between;
      align-items: center;
      border-bottom: 1px solid var(--color-border);
      white-space: normal;
    }


    td:last-child {
      border-bottom: none;
    }

    .ui-col--spacer {
      display: none;
    }

    .ui-col--card-hidden {
      display: none;
    }

    td::before {
      content: attr(data-label);
      font-weight: var(--font-weight-semibold);
      color: var(--color-text-subtle);
      font-size: var(--font-size-sm);
      flex-shrink: 0;
      margin-right: var(--space-3);
    }

    .ui-list-table__td--actions {
      position: static;
      box-shadow: none;
    }
  }
}

@media (max-width: 480px) {
  .ui-bases-list {
    padding: var(--space-3);
  }
}


/* fulgore: ui/bases/modal.css */
.ui-modal {
  display: none;
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  align-items: center;
  justify-content: center;

  &.is-open {
    display: flex;

    .ui-modal__backdrop {
      animation: fade-in var(--duration-normal) var(--easing-out) both;
    }

    .ui-modal__dialog {
      animation: scale-in var(--duration-normal) var(--easing-spring) both;
    }
  }
}

.ui-modal__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}

.ui-modal__dialog {
  position: relative;
  white-space: normal;
  background: var(--color-surface);
  border-radius: var(--radius-xl);
  padding: var(--space-8);
  width: 100%;
  max-width: 32rem;
  max-height: calc(100vh - var(--space-8) * 2);
  margin: var(--space-4);
  box-shadow: var(--shadow-xl);
  overflow-x: hidden;
  overflow-y: auto;
}

@media (max-width: 1023px) {
  .ui-modal {
    padding-top: var(--navbar-height);
  }

  .ui-modal__dialog {
    max-height: calc(100vh - var(--navbar-height) - var(--space-8));
  }
}

.ui-modal__dialog > .ui-button {
  position: absolute;
  top: var(--space-4);
  right: var(--space-4);
}

.ui-modal__body {
  max-width: 100%;
  overflow-wrap: break-word;
  text-align: center;
}

.ui-modal__header {
  margin-bottom: var(--space-4);
  text-align: center;
}

.ui-modal__footer {
  margin-top: var(--space-6);
}

.ui-modal__footer .form-actions {
  justify-content: center;
}

.ui-modal__footer .form-actions:has(> :nth-child(2)) {
  justify-content: space-between;
}

@media (max-width: 480px) {
  .ui-modal__dialog {
    padding: var(--space-5);
    margin: var(--space-2);
  }
}


/* fulgore: ui/bases/navbar.css */
.ui-bases-navbar {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: var(--space-4);
  height: var(--navbar-height);
  padding: var(--space-1) var(--space-4);
  box-sizing: border-box;
  align-items: center;
  background: var(--color-brand);
  color: var(--color-text-inverted);
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
}

.ui-bases-navbar a {
  display: block;
  color: inherit;
  text-decoration: none;
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  transition: background var(--duration-fast) var(--easing-default);
}

.ui-bases-navbar a:hover {
  background: rgba(255, 255, 255, 0.15);
}

/* ── Left section ── */

.navbar-left {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.navbar-brand {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  color: inherit;
  text-decoration: none;
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  transition: background var(--duration-fast) var(--easing-default);
  width: fit-content;
}

.navbar-brand:hover {
  background: rgba(255, 255, 255, 0.15);
}

.navbar-brand svg {
  width: 2rem;
  height: 2rem;
  flex-shrink: 0;
}

/* ── Hamburger ── */

.navbar-hamburger {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border: none;
  background: transparent;
  border-radius: var(--radius-md);
  color: var(--color-text-inverted);
  cursor: pointer;
  transition: background var(--duration-fast) var(--easing-default);
}

.navbar-hamburger:hover {
  background: rgba(255, 255, 255, 0.15);
}

.navbar-hamburger:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}

/* ── Center section ── */

.navbar-nav {
  display: flex;
  justify-content: center;
  gap: var(--space-4);
  flex-wrap: wrap;
}

.navbar-link {
  display: block;
  color: inherit;
  text-decoration: none;
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  transition: background var(--duration-fast) var(--easing-default);
}

.navbar-link:hover {
  background: rgba(255, 255, 255, 0.15);
}

.navbar-link--active {
  background: rgba(255, 255, 255, 0.25);
  font-weight: var(--font-weight-semibold);
}

/* ── Right section ── */

.navbar-actions {
  display: flex;
  gap: var(--space-3);
  align-items: center;
}

/* ── Responsive ── */

@media (max-width: 1023px) {
  .ui-bases-navbar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
  }
}


/* fulgore: ui/bases/new.css */
.ui-bases-new__header {
  margin-block-end: var(--space-6);
}

.ui-bases-new__body {
}


/* fulgore: ui/bases/page_header.css */
.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-bottom: var(--space-6);
}

.page-title {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.page-header--size-md .page-title {
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-tight);
  margin: 0;
}

.page-header--size-sm .page-title {
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-tight);
  margin: 0;
}

@media (max-width: 480px) {
  .page-header {
    flex-direction: column;
    gap: var(--space-3);
  }
}


/* fulgore: ui/bases/progress_bar.css */
.ui-bases-progress-bar {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.ui-bases-progress-bar__label {
  margin: 0;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-subtle);
}

.ui-bases-progress-bar__track {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.ui-bases-progress-bar__bar {
  flex: 1;
  height: var(--space-2);
  border-radius: var(--radius-full);
  background-color: var(--color-surface-subtle);
  overflow: hidden;
}

.ui-bases-progress-bar__fill {
  height: 100%;
  border-radius: var(--radius-full);
  background-color: var(--color-text-subtle);
  transition: width var(--duration-normal) var(--easing-default);
}

.ui-bases-progress-bar--brand .ui-bases-progress-bar__fill {
  background-color: var(--color-brand);
}

.ui-bases-progress-bar--accent .ui-bases-progress-bar__fill {
  background-color: var(--color-accent);
}

.ui-bases-progress-bar--sm .ui-bases-progress-bar__bar {
  height: var(--space-1);
}

.ui-bases-progress-bar--sm .ui-bases-progress-bar__percentage {
  font-size: var(--font-size-xs);
}

.ui-bases-progress-bar__percentage {
  font-size: var(--font-size-sm);
  color: var(--color-text-subtle);
  font-variant-numeric: tabular-nums;
  min-width: 3ch;
  text-align: right;
}


/* fulgore: ui/bases/record_view.css */
.ui-bases-record-view__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* wrap + min-width 0 : sans eux, une zone d'actions plus large que
     l'espace restant déborde du viewport mobile (flex min-width:auto). */
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-bottom: var(--space-6);
}

.ui-bases-record-view__header > * {
  min-width: 0;
}

.ui-bases-record-view__title-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin: var(--space-6) 0 var(--space-8) 0;
}

.ui-bases-record-view__body {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-6);
  align-items: start;
}

.ui-bases-record-view__body > :only-child {
  grid-column: 1 / -1;
  max-width: 48rem;
  margin-inline: auto;
  width: 100%;
}

.ui-bases-record-view__body > .ui-bases-record-view__layout {
  max-width: none;
  margin-inline: 0;
}

/* ── Layout (used by Show/Edit body_content) ── */

.ui-bases-record-view__layout {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

/* ── Row (2-column grid) ── */

.ui-bases-record-view__row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-6);
  align-items: start;
}

@media (max-width: 768px) {
  .ui-bases-record-view__body {
    grid-template-columns: 1fr;
  }

  .ui-bases-record-view__row {
    grid-template-columns: 1fr;
  }
}


/* fulgore: ui/bases/record_view_title.css */
.ui-bases-record-view-title {
  font-family: var(--font-family-display);
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-tight);
  color: var(--color-text);
  margin: 0;
}


/* fulgore: ui/bases/row.css */
.ui-bases-row__actions-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

@media (max-width: 480px) {
  .ui-bases-row__actions-inner {
    justify-content: flex-end;
    flex-wrap: wrap;
  }
}


@keyframes position-flip {
  0%   { transform: perspective(120px) rotateX(0deg);   opacity: 1; }
  45%  { transform: perspective(120px) rotateX(-90deg); opacity: 0; }
  55%  { transform: perspective(120px) rotateX(-90deg); opacity: 0; }
  100% { transform: perspective(120px) rotateX(0deg);   opacity: 1; }
}

.ui-bases-row__position {
  color: var(--color-text-subtle);
  font-size: var(--font-size-sm);
  user-select: none;
}

.ui-bases-row__position.is-flipping {
  animation: position-flip 300ms ease-in-out;
  will-change: transform;
}

/* td-qualified: must outrank `.ui-list-table td` (list.css) or its padding
   collapses the cell content box to 0 and hides the handle. */
td.ui-bases-row__grip {
  width: 1.25rem;
  padding-right: 0;
  color: var(--color-text-subtle);
  user-select: none;
  cursor: grab;

  &:active {
    cursor: grabbing;
  }

  /* Shield the handle from consumer resets like `svg { max-width: 100% }`
     (100% of a zero-width content box renders the handle invisible). */
  & svg {
    width: 10px;
    min-width: 10px;
    max-width: none;
  }
}

/* The handle is a real button so it can be reached by Tab and driven by the
   arrow keys — mouse dragging is not the only way to reorder. It must not look
   like one: no native chrome, it inherits the cell's colour and grab cursor.
   The focus ring is the one thing it keeps, and it must stay visible — it is
   the only cue telling a keyboard user which row the arrows will move. */
button.ui-bases-row__grip-button {
  display: inline-flex;
  align-items: center;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  cursor: inherit;
  font: inherit;
  line-height: 0;

  /* Même anneau que partout ailleurs dans la gem (bouton, menu d'actions,
     lien de barre latérale) : `--focus-ring`, jamais un outline maison. */
  &:focus-visible {
    outline: none;
    border-radius: var(--radius-sm);
    box-shadow: var(--focus-ring);
  }
}

tr[draggable="true"] {
  cursor: grab;

  
  & td:not(:has(a, button)) {
    cursor: grab;
  }

  &:active,
  &:active td:not(:has(a, button)) {
    cursor: ns-resize;
  }
}

tr.sortable--dragging,
tr.sortable--dragging td {
  cursor: ns-resize;
}

tr.sortable--dragging {
  opacity: 0.7;
  background: var(--color-surface-raised);
  outline: 1.5px dashed var(--color-border-strong);
  outline-offset: -1px;
  box-shadow: var(--shadow-md);
}


/* fulgore: ui/bases/show.css */
.ui-bases-show__header {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  margin-block-end: var(--space-6);

  .ui-links-back {
    margin-block: 0;
  }
}

.ui-bases-show__body {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: start;
  gap: var(--space-8);
}

.ui-bases-show__list {
  width: 100%;
  margin-block-start: var(--space-8);
}

.ui-bases-show__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-block-start: var(--space-8);
}

@media (max-width: 767px) {
  .ui-bases-show__body {
    grid-template-columns: 1fr;
  }

  .ui-bases-show__header {
    grid-template-columns: 1fr;
  }
}


/* fulgore: ui/bases/sidebar.css */
/* Le panneau reçoit le focus à l'ouverture en mobile (cf. nav_sidebar_controller
   #enableFocusTrap) : ce n'est pas un contrôle, aucun anneau ne doit s'y
   dessiner. Sélecteur d'attribut et non de classe — la règle doit valoir pour
   toute sidebar branchée sur le contrôleur, y compris les panneaux propres aux
   consumers qui n'utilisent pas .sidebar. */
[data-nav-sidebar-target="sidebar"]:focus {
  outline: none;
}

.sidebar {
  position: fixed;
  top: var(--navbar-height);
  left: 0;
  bottom: 0;
  width: var(--sidebar-width);
  background: var(--color-surface);
  border-right: 1px solid var(--color-border);
  padding: var(--space-4) 0;
  overflow-y: auto;
  z-index: var(--z-raised);
  box-sizing: border-box;
}

.sidebar nav {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.sidebar-link {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-5);
  color: var(--color-text-subtle);
  text-decoration: none;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  transition: background var(--duration-fast), color var(--duration-fast);
  border-left: 3px solid transparent;
}

.sidebar-link:hover {
  background: var(--color-surface-subtle);
  color: var(--color-text);
}

.sidebar-link:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}

.sidebar-link svg {
  width: 1.25rem;
  height: 1.25rem;
  flex-shrink: 0;
}

.sidebar-link--active {
  color: var(--color-brand);
  background: var(--color-brand-surface);
  border-left-color: var(--color-brand);
  font-weight: var(--font-weight-semibold);
}

/* ── Responsive ── */

@media (max-width: 1023px) {
  .sidebar {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .sidebar-link {
    transition: none;
  }
}


/* fulgore: ui/bases/stat_card.css */
.ui-stat-card {
  padding: var(--space-8);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  background: var(--color-surface);
}

.ui-stat-card__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}

.ui-stat-card__title {
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-bold);
  line-height: 1.2;
  margin: 0;
}


/* fulgore: ui/bases/view_actions.css */
.ui-bases-view-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
}


/* fulgore: ui/buttons/switch.css */
.ui-buttons-switch {
  display: inline-flex;
  cursor: pointer;
  align-items: center;

  form,
  button {
    display: contents;
    background: none;
    border: none;
    padding: 0;
    margin: 0;
    cursor: pointer;
  }
}

.ui-buttons-switch__track {
  position: relative;
  display: inline-flex;
  align-items: center;
  width: 2.75rem;
  height: 1.5rem;
  border-radius: var(--radius-full);
  background-color: var(--color-border);
  transition: background-color var(--duration-slow) var(--easing-default);
  padding: 0 var(--space-1);
  box-sizing: border-box;
  box-shadow:
    inset 0 2px 4px rgba(0, 0, 0, 0.18),
    inset 0 1px 2px rgba(0, 0, 0, 0.10);
}

.ui-buttons-switch--checked .ui-buttons-switch__track {
  background-color: var(--color-brand);
}

.ui-buttons-switch__thumb {
  position: absolute;
  left: var(--space-1);
  width: 1.25rem;
  height: 1.25rem;
  border-radius: var(--radius-full);
  background: radial-gradient(circle at 35% 30%, #ffffff, #c8c8c8);
  box-shadow:
    0 2px 4px rgba(0, 0, 0, 0.22),
    0 1px 2px rgba(0, 0, 0, 0.14),
    0 0 0 1px rgba(0, 0, 0, 0.06);
  transition:
    transform var(--duration-slow) var(--easing-spring),
    width var(--duration-fast) var(--easing-out);
}

.ui-buttons-switch--checked .ui-buttons-switch__thumb {
  transform: translateX(1rem);
}

.ui-buttons-switch:active .ui-buttons-switch__thumb {
  width: 1.5rem;
}


/* fulgore: ui/chat/bubble.css */
.ui-chat-bubble {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  max-width: 75%;
}

.ui-chat-bubble--sent {
  align-self: flex-end;
  align-items: flex-end;
}

.ui-chat-bubble--received {
  align-self: flex-start;
  align-items: flex-start;
}

.ui-chat-bubble__author {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.ui-chat-bubble__meta {
  display: flex;
  justify-content: flex-end;
}

.ui-chat-bubble__time {
  font-size: var(--font-size-xs);
  color: var(--color-text-subtle);
}

.ui-chat-bubble__body {
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-lg);
  font-size: var(--font-size-sm);
  line-height: var(--line-height-loose);
  word-break: break-word;
}

.ui-chat-bubble--sent .ui-chat-bubble__body {
  background: var(--color-brand-surface);
  color: var(--color-text);
  border-bottom-right-radius: var(--radius-sm);
}

.ui-chat-bubble--received .ui-chat-bubble__body {
  background: var(--color-surface-subtle);
  color: var(--color-text);
  border-bottom-left-radius: var(--radius-sm);
}


/* fulgore: ui/chat/conversation_item.css */
.ui-chat-conversation-item {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: var(--space-3);
  align-items: center;
  padding: var(--space-3) var(--space-4);
  text-decoration: none;
  color: var(--color-text);
  border-radius: var(--radius-md);
  transition: background var(--duration-fast) var(--easing-default);

  &:hover {
    background: var(--color-surface-raised);
  }

  &--unread {
    background: var(--color-brand-surface);

    &:hover {
      background: var(--color-brand-a10);
    }

    .ui-chat-conversation-item__names {
      font-weight: var(--font-weight-semibold);
    }

    .ui-chat-conversation-item__preview {
      color: var(--color-text);
    }
  }
}

/* --- Avatars --- */

.ui-chat-conversation-item__avatars {
  display: flex;
  flex-direction: row;
  align-items: center;
  align-self: center;
}

.ui-chat-conversation-item__avatar {
  margin-left: -6px;

  &:first-child {
    margin-left: 0;
  }

  .ui-user-badge {
    gap: 0;
  }

  .ui-user-badge__text {
    display: none;
  }

  .ui-user-badge__circle {
    width: 1.75rem !important;
    height: 1.75rem !important;
    font-size: 0.6875rem !important;
    border: 2px solid var(--color-surface);
  }
}

/* --- Content --- */

.ui-chat-conversation-item__content {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.ui-chat-conversation-item__header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
}

.ui-chat-conversation-item__names {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ui-chat-conversation-item__time {
  font-size: 0.625rem;
  color: var(--color-text-subtle);
  white-space: nowrap;
  flex-shrink: 0;
}

.ui-chat-conversation-item__subject {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  color: var(--color-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ui-chat-conversation-item__preview {
  margin: 0;
  font-size: var(--font-size-xs);
  color: var(--color-text-subtle);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* --- Unread badge --- */

.ui-chat-conversation-item__unread-badge {
  display: inline-block;
  min-width: 1.25rem;
  height: 1.25rem;
  line-height: 1.25rem;
  padding-inline: 5px;
  border-radius: var(--radius-full);
  background: var(--color-danger);
  color: var(--color-text-inverted);
  font-family: system-ui, -apple-system, sans-serif;
  font-size: 0.6875rem;
  font-weight: 600;
  text-align: center;
  font-variant-numeric: tabular-nums;
  align-self: center;
}


/* fulgore: ui/chat/empty_state.css */
.ui-chat-empty-state {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  padding: var(--space-8);
  color: var(--color-text-subtle);

  .svg {
    width: var(--icon-size-lg);
    height: var(--icon-size-lg);
    opacity: 0.4;
  }
}

.ui-chat-empty-state__text {
  margin: 0;
  font-size: var(--font-size-sm);
  text-align: center;
}


/* fulgore: ui/chat/input.css */
.ui-chat-input {
  flex-shrink: 0;
  border-top: 1px solid var(--color-border);
  padding: var(--space-3) var(--space-4);
}

.ui-chat-input__form {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.ui-chat-input__textarea {
  flex: 1;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  font-size: 16px;
  font-family: inherit;
  resize: none;
  outline: none;
  transition: border-color var(--duration-fast) var(--easing-default);

  &:focus {
    border-color: var(--color-brand);
    box-shadow: var(--focus-ring);
  }
}

.ui-chat-input__submit {
  padding: var(--space-2) var(--space-4);
  border: none;
  border-radius: var(--radius-lg);
  background: var(--color-brand);
  color: var(--color-text-inverted);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--duration-fast) var(--easing-default);

  &:hover {
    background: var(--color-brand-dark);
  }

  &:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring);
  }

  &:disabled {
    opacity: 0.6;
    cursor: not-allowed;
  }
}


/* fulgore: ui/chat/list.css */
.ui-chat-list {
  flex: 1;
  min-height: 20rem;
  max-height: 60vh;
  overflow-y: auto;
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.ui-chat-list[data-full-height="true"] {
  min-height: 0;
  max-height: none;
}


/* fulgore: ui/directions_dropdown.css */
/* "Directions" dropdown — anchors the absolute menu under the trigger.
   Stimulus `dropdown` toggles .is-open on this root element, not the menu. */

.ui-directions-dropdown {
  position: relative;
  display: inline-block;
}

.ui-directions-dropdown__toggle::after {
  content: "▾";
  margin-left: var(--space-1);
  font-size: 0.75em;
}

.ui-directions-dropdown__menu {
  display: none;
  position: absolute;
  top: calc(100% + var(--space-1));
  left: 0;
  z-index: var(--z-dropdown);
  min-width: 12rem;
  padding: var(--space-1) 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--color-surface);
  box-shadow: var(--shadow-md);
}

.ui-directions-dropdown.is-open .ui-directions-dropdown__menu {
  display: block;
}

.ui-directions-dropdown__item {
  display: block;
  padding: var(--space-2) var(--space-4);
  font-size: var(--font-size-sm);
  color: var(--color-text);
  text-decoration: none;
  white-space: nowrap;
}

.ui-directions-dropdown__item:hover,
.ui-directions-dropdown__item:focus {
  background: var(--color-surface-alt);
}


/* fulgore: ui/display/code.css */
.code-container {
  display: grid;
  user-select: text;
}

/* ── Toggle button ── */

.code-container .collapse-toggle {
  background-color: var(--color-neutral-900);
  border: 1px solid var(--color-neutral-900);
  border-radius: var(--radius-lg);
  color: var(--color-text-inverted);
  cursor: pointer;
  font-size: var(--font-size-2xl);
  margin: 0 var(--space-4) 0 auto;
  padding: var(--space-2);
  position: relative;
  top: var(--space-6);
  transition: background-color var(--duration-normal) var(--easing-default),
              border-color var(--duration-normal) var(--easing-default);
  width: fit-content;
  z-index: var(--z-raised);
}

.code-container .collapse-toggle:hover {
  background-color: var(--color-surface);
  border-color: var(--color-neutral-900);
  color: var(--color-text);
}

/* ── Code block ── */

.code-container .code {
  background-color: var(--color-neutral-900);
  color: var(--color-neutral-0);
  overflow: scroll;
  padding: var(--space-2);
  transition: height var(--duration-normal) var(--easing-default);
  z-index: 1;
}

.code-container pre.collapsed {
  height: 5rem;
  overflow: hidden;
  cursor: pointer;
  padding: 0;
}

.code-container pre.expanded {
  height: 100%;
  overflow: scroll;
}


/* fulgore: ui/display/counter.css */
.ui-display-counter {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 2px var(--space-3);
  border-radius: 999px;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
  background: var(--color-surface-raised);
  color: var(--color-text-subtle);
}

.ui-display-counter .ui-icon {
  width: 0.875rem;
  height: 0.875rem;
}


/* fulgore: ui/display/datetime.css */
.ui-display-datetime {
  font-size: var(--font-size-sm);
  color: var(--color-text-subtle);
  white-space: nowrap;
}


/* fulgore: ui/display/distribution_bar.css */
.ui-display-distribution-bar {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.ui-display-distribution-bar {
  min-width: 0;
}

.ui-display-distribution-bar__row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto minmax(40px, 80px);
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
}

.ui-display-distribution-bar__emoji {
  font-size: var(--font-size-base);
  line-height: 1;
}

.ui-display-distribution-bar__label {
  font-size: var(--font-size-sm);
  color: var(--color-text);
  margin: 0;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ui-display-distribution-bar__count {
  font-size: var(--font-size-sm);
  font-variant-numeric: tabular-nums;
  color: var(--color-text-subtle);
  text-align: right;
}

.ui-display-distribution-bar__track {
  height: 8px;
  background-color: var(--color-surface-subtle);
  border-radius: 999px;
  overflow: hidden;
}

.ui-display-distribution-bar__fill {
  height: 100%;
  background-color: var(--color-brand);
  transition: width 200ms ease;
}


/* fulgore: ui/display/iban.css */
.ui-display-iban {
  font-variant-numeric: tabular-nums;
}


/* fulgore: ui/display/image_skeleton.css */
/* .ui-image-skeleton — classe utility skeleton image partagée.
 * Pose un shimmer en background + un spinner via ::before sur l'élément porteur.
 * Réutilise @keyframes skeleton-shimmer et @keyframes spin (fulgore/animations.css).
 * Le wrapper doit définir ses propres dimensions (aspect-ratio, width, height,
 * border-radius, overflow).
 *
 * Deux usages possibles (selon la présence d'un wrapper) :
 *
 *   1. Sur un wrapper <div> qui contient un <picture> rendu par UI::Display::Picture
 *      → le shimmer + spinner sont sur le wrapper, l'image enfant le masque
 *        une fois chargée (z-index:1 sur le picture/img).
 *
 *   2. Directement sur le <picture> lui-même (via css_class de Picture, pour les
 *      cas sans wrapper parent — ex. miniatures en ligne dans un Row)
 *      → le ::before n'aurait pas d'effet sur un <img> seul (replaced element),
 *        mais le <picture> n'est PAS replaced, donc ::before fonctionne ;
 *        le <img> enfant masque le skeleton via z-index.
 *
 * Caveat asset transparent : le contract suppose un asset opaque (JPEG/WebP en
 * object-fit:cover). Pour un SVG/PNG transparent avec object-fit:contain,
 * les zones transparentes laissent voir le shimmer en permanence — préférer
 * dans ce cas un wrapper neutre sans skeleton (cf. show.css logo).
 */

.ui-image-skeleton {
  position: relative;
  overflow: hidden;
  background: linear-gradient(
    90deg,
    var(--color-surface-raised) 25%,
    var(--color-surface-subtle) 50%,
    var(--color-surface-raised) 75%
  );
  background-size: 200% 100%;
  animation: skeleton-shimmer 1.5s ease-in-out infinite;
}

.ui-image-skeleton::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 24px;
  height: 24px;
  margin: -12px 0 0 -12px;
  border: 3px solid var(--color-border);
  border-top-color: var(--color-brand);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
  z-index: 0;
}

.ui-image-skeleton > picture,
.ui-image-skeleton > picture > img,
picture.ui-image-skeleton,
picture.ui-image-skeleton > img {
  position: relative;
  z-index: 1;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}


/* fulgore: ui/display/money.css */
.ui-display-money {
  display: block;
  font-size: var(--font-size-sm);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  text-align: right;
}

.ui-display-money--default {
  color: var(--color-brand);
}

.ui-display-money--positive {
  color: var(--color-success);
}

.ui-display-money--negative {
  color: var(--color-danger);
}


/* fulgore: ui/display/range_bar.css */
.ui-display-range-bar {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-width: 0;
}

.ui-display-range-bar__labels {
  display: flex;
  justify-content: space-between;
  gap: var(--space-2);
  font-size: var(--font-size-xs);
  font-weight: 500;
  color: var(--color-text-subtle);
}

.ui-display-range-bar__min,
.ui-display-range-bar__max {
  margin: 0;
  min-width: 0;
  font-variant-numeric: tabular-nums;
}

.ui-display-range-bar__max {
  text-align: right;
}

.ui-display-range-bar__track {
  position: relative;
  height: 6px;
  border-radius: 999px;
  background: linear-gradient(
    to right,
    var(--color-surface-subtle) 0%,
    var(--color-brand-surface) 50%,
    var(--color-surface-subtle) 100%
  );
  overflow: hidden;
}

.ui-display-range-bar__marker {
  position: absolute;
  top: 50%;
  width: 12px;
  height: 12px;
  background-color: var(--color-brand);
  border-radius: 50%;
  transform: translateY(-50%) translateX(-50%);
}

.ui-display-range-bar__marker-label {
  position: absolute;
  top: 100%;
  white-space: nowrap;
  margin-top: var(--space-1);
  font-size: var(--font-size-xs);
  color: var(--color-text-subtle);
  transform: translateX(-50%);
}


/* fulgore: ui/display/rna.css */
.ui-display-rna {
  font-variant-numeric: tabular-nums;
}


/* fulgore: ui/display/simple_format.css */
.simple-format {
  white-space: pre-line;
}

.simple-format p {
  margin: 0 0 1em;
}

.simple-format br {
  display: inline;
}


/* fulgore: ui/display/siret.css */
.ui-display-siret {
  font-variant-numeric: tabular-nums;
}


/* fulgore: ui/display/stat_block.css */
.ui-display-stat-block {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--space-3);
  min-width: 0;
  text-align: center;
}

/* Large variant — default */
.ui-display-stat-block--large {
  .ui-display-stat-block__value {
    font-size: var(--font-size-3xl);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    line-height: 1.2;
    margin: 0;
  }

  .ui-display-stat-block__label {
    font-size: var(--font-size-xs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-text-subtle);
    margin: 0;
  }
}

/* Compact variant */
.ui-display-stat-block--compact {
  min-width: 0;

  .ui-display-stat-block__value {
    font-size: var(--font-size-lg);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    line-height: 1.3;
    margin: 0;
    min-width: 0;
    overflow-wrap: anywhere;
  }

  .ui-display-stat-block__label {
    font-size: var(--font-size-xs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-text-subtle);
    margin: 0;
  }
}


/* fulgore: ui/display/thumbnail.css */
.ui-display-thumbnail {
  width: 40px;
  height: 40px;
  overflow: hidden;
  border-radius: var(--radius-sm);
  flex-shrink: 0;
}

.ui-display-thumbnail picture,
.ui-display-thumbnail .ui-display-thumbnail__img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  aspect-ratio: 1;
}


/* fulgore: ui/empty_state.css */
.ui-empty-state {
  text-align: center;
  padding: var(--space-12) var(--space-8);
  color: var(--color-text-subtle);

  .empty-state-icon {
    margin-bottom: var(--space-3);

    .svg {
      width: var(--space-10);
      height: var(--space-10);
      fill: currentColor;
      opacity: 0.4;
      /* Consumer resets may force `svg { display: block }`, which escapes
         the text-align: center of the root — margin-inline keeps a block
         svg centered and is a no-op on an inline one. */
      margin-inline: auto;
    }
  }

  .empty-state-title {
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-medium);
    margin: 0 0 var(--space-2) 0;
  }

  .empty-state-description {
    font-size: var(--font-size-base);
    margin: 0;
  }

  .empty-state-cta {
    margin-top: var(--space-5);
  }
}


/* fulgore: ui/gauge.css */
.ui-gauge {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-4) var(--space-3);
  background-color: var(--color-brand-surface);
  border: 1px solid var(--color-brand-a10);
  border-radius: var(--radius-lg);
  text-align: center;
}

.ui-gauge__icon {
  font-size: var(--font-size-2xl);
  line-height: 1;
}

.ui-gauge__label {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  color: var(--color-brand);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.ui-gauge .ui-bases-progress-bar {
  width: 100%;
}

.ui-gauge .ui-bases-progress-bar__track {
  flex-direction: column;
  gap: var(--space-2);
}

.ui-gauge .ui-bases-progress-bar__bar {
  flex: none;
  width: 100%;
  height: var(--space-1);
}

.ui-gauge .ui-bases-progress-bar__percentage {
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
  color: var(--color-brand);
  text-align: center;
  min-width: unset;
}


/* fulgore: ui/ghost_row.css */
.ui-ghost-row {
  
  & .ui-ghost-row__cell {
    
    border: 3px dashed var(--color-brand);
    background-color: var(--color-brand-a20);
    padding-block: var(--space-1);
  }
}


/* fulgore: ui/help_tooltip.css */
.ui-help-tooltip {
  position: relative;
  display: inline-flex;
  align-items: center;
}

.ui-help-tooltip__trigger {
  position: relative;
  width: 1.1rem;
  height: 1.1rem;
  background: var(--color-surface-raised);
  color: var(--color-text-subtle);
  font-size: var(--font-size-xs);
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border);
  cursor: pointer;
  line-height: 1;
  padding: 0;
}

/* Le rond visible fait 17,6 px (1.1rem, bordure comprise) ; le minimum
   WCAG 2.5.8 (AA) est 24 px. On étend la zone touchable AUTOUR du rond au lieu
   de grossir le rond : l'aspect ne bouge dans aucun consumer, et la cible passe
   la norme.
   ⚠️ Le débord se choisit à la mesure, pas au calcul : 3 px donnent 23,6 px,
   sous la barre. Mesuré au navigateur (WebKit ET Chromium, 390×844, sonde
   elementFromPoint), 0.25rem rend 24,4 px — ça passe, mais 0,4 px de marge se
   perd au premier arrondi d'appareil. 0.3rem rend 26 px. */
.ui-help-tooltip__trigger::before {
  content: "";
  position: absolute;
  inset: -0.3rem;
  border-radius: var(--radius-full);
}

.ui-help-tooltip__trigger:hover {
  background: var(--color-surface);
  color: var(--color-text);
}

.ui-help-tooltip__trigger:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}

.ui-help-tooltip__panel {
  --ui-tooltip-shift: 0;

  position: absolute;
  top: 50%;
  right: calc(100% + var(--space-2));
  transform: translateY(-50%);
  /* Rattrapage horizontal posé par tooltip_controller quand la bulle dépasse
     encore un bord après bascule. `translate` est une propriété distincte de
     `transform` : elle se compose avec le centrage ci-dessus ET avec les
     `transform: none` que certains consumers posent en repositionnant. */
  translate: var(--ui-tooltip-shift);
  background: var(--color-surface);
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  font-size: var(--font-size-sm);
  color: var(--color-text);
  box-shadow: var(--shadow-lg);
  min-width: 220px;
  max-width: 320px;
  z-index: var(--z-dropdown);
  white-space: normal;
}

/* Bascule posée par tooltip_controller quand la bulle sortirait du bord
   gauche du viewport : elle s'ouvre alors à droite du déclencheur. */
.ui-help-tooltip__panel[data-flipped] {
  right: auto;
  left: calc(100% + var(--space-2));
}


/* fulgore: ui/icon.css */
.svg {
  width: var(--icon-size-md);
  height: var(--icon-size-md);
  flex-shrink: 0;
  fill: currentColor;
}


/* fulgore: ui/icon_label.css */
.ui-icon-label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}

.ui-icon-label__icon {
  flex-shrink: 0;
  font-size: var(--font-size-base);
  line-height: 1;
}

.ui-icon-label__label {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-text);
}


/* fulgore: ui/inputs/checkbox.css */
.ui-input--checkbox {
  display: flex;
  flex-direction: row-reverse;
  align-items: center;
  justify-content: flex-start;
  gap: var(--space-3);

  label {
    cursor: pointer;
  }

  input[type="checkbox"] {
    width: 1.125rem;
    height: 1.125rem;
    accent-color: var(--color-brand);
    cursor: pointer;
  }

  input[type="hidden"] {
    display: none;
  }
}


/* fulgore: ui/inputs/checkbox_card.css */
.ui-inputs-checkbox-card {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-6);
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius-lg);
  cursor: pointer;
  transition:
    border-color var(--duration-fast) var(--easing-default),
    background var(--duration-fast) var(--easing-default);

  &:hover {
    border-color: var(--color-brand);
    background: var(--color-brand-a10);
  }

  &.is-checked {
    border-color: var(--color-brand);
    background: var(--color-brand-a10);
  }
}

.ui-inputs-checkbox-card__checkbox {
  width: 1.25rem;
  height: 1.25rem;
  accent-color: var(--color-brand);
  cursor: pointer;
  transition: transform var(--duration-fast) var(--easing-bounce, cubic-bezier(0.34, 1.56, 0.64, 1));

  .no-transition & {
    transition: none;
  }
}

.ui-inputs-checkbox-card.is-checked .ui-inputs-checkbox-card__checkbox {
  animation: checkbox-pop var(--duration-normal, 250ms) var(--easing-bounce, cubic-bezier(0.34, 1.56, 0.64, 1));
}

.ui-inputs-checkbox-card.no-transition .ui-inputs-checkbox-card__checkbox {
  animation: none;
}

@keyframes checkbox-pop {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.35); }
  100% { transform: scale(1); }
}

.ui-inputs-checkbox-card__text {
  position: relative;
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-medium);
  color: var(--color-text);
}

.ui-inputs-checkbox-card__label {
  display: block;
  transition: opacity var(--duration-fast) var(--easing-default);
}

.ui-inputs-checkbox-card__label--unchecked {
  opacity: 1;
}

.ui-inputs-checkbox-card__label--checked {
  position: absolute;
  inset: 0;
  opacity: 0;
}

.ui-inputs-checkbox-card.is-checked .ui-inputs-checkbox-card__label--unchecked {
  opacity: 0;
}

.ui-inputs-checkbox-card.is-checked .ui-inputs-checkbox-card__label--checked {
  opacity: 1;
}


/* fulgore: ui/inputs/checkbox_select.css */
.ui-input {
  .ui-checkbox-select {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
  }

  .ui-checkbox-select__option {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    gap: var(--space-2);
    cursor: pointer;
    font-size: var(--font-size-sm);
    color: var(--color-text);

    input[type="checkbox"] {
      width: auto;
      flex: none;
      accent-color: var(--color-brand);
      cursor: pointer;
    }
  }
}


/* fulgore: ui/inputs/color.css */
.ui-input {
  [data-controller="color-picker"] {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: var(--space-2);
    width: 100%;
  }

  [data-color-picker-target="swatch"] {
    flex: 0 0 auto;
    width: 2.25rem;
    height: 2.25rem;
    padding: var(--space-1);
    border: 1.5px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    cursor: pointer;
    transition:
      border-color var(--duration-fast) var(--easing-default),
      box-shadow var(--duration-fast) var(--easing-default);

    &::-webkit-color-swatch-wrapper {
      padding: 0;
    }

    &::-webkit-color-swatch {
      border: none;
      border-radius: var(--radius-sm);
    }

    &::-moz-color-swatch {
      border: none;
      border-radius: var(--radius-sm);
    }

    &:focus {
      border-color: var(--color-brand);
      box-shadow: var(--focus-ring);
    }
  }

  [data-color-picker-target="hex"] {
    flex: 1;
    width: auto;
    font-family: var(--font-family-mono);
  }

  &.ui-input--error {
    [data-color-picker-target="swatch"] {
      border-color: var(--color-danger);

      &:focus {
        box-shadow: 0 0 0 3px var(--color-danger-a10);
      }
    }
  }
}


/* fulgore: ui/inputs/date_range.css */
.filter-field--date-range {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.filter-date-range__field {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}

.filter-date-range__label {
  font-size: var(--font-size-sm);
  color: var(--color-text-subtle);
}

.filter-field--date-range input[type="date"] {
  padding: var(--space-1) var(--space-2);
  font-size: var(--font-size-sm);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text);
}


/* fulgore: ui/inputs/file_dropzone.css */
.ui-inputs-file-dropzone__zone {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-5) var(--space-4);
  border: 2px dashed var(--color-border);
  border-radius: var(--radius-lg);
  background-color: var(--color-surface);
  cursor: pointer;
  transition: border-color 150ms ease, background-color 150ms ease;
}

.ui-inputs-file-dropzone__zone:hover {
  border-color: var(--color-brand);
  background-color: var(--color-brand-surface);
}

.ui-inputs-file-dropzone__zone.is-dragover {
  border-color: var(--color-brand);
  background-color: var(--color-brand-surface);
}

.ui-inputs-file-dropzone__icon {
  font-size: var(--font-size-2xl);
}

.ui-inputs-file-dropzone__label {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-text);
}

.ui-inputs-file-dropzone__hint {
  font-size: var(--font-size-xs);
  color: var(--color-text-subtle);
}

.ui-inputs-file-dropzone__zone.is-uploading {
  border-color: var(--color-brand);
  background-color: var(--color-brand-surface);
  pointer-events: none;
  cursor: default;
}

.ui-inputs-file-dropzone__zone.is-uploading .ui-inputs-file-dropzone__icon,
.ui-inputs-file-dropzone__zone.is-uploading .ui-inputs-file-dropzone__label,
.ui-inputs-file-dropzone__zone.is-uploading .ui-inputs-file-dropzone__hint {
  display: none;
}

.ui-inputs-file-dropzone__zone.is-uploading::after {
  content: "Envoi en cours…";
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-brand);
}

.ui-inputs-file-dropzone__zone.is-uploading::before {
  content: "";
  width: 1rem;
  height: 1rem;
  border: 2px solid var(--color-brand);
  border-right-color: transparent;
  border-radius: var(--radius-full);
  animation: dropzone-spin 600ms linear infinite;
}

@keyframes dropzone-spin {
  to { transform: rotate(360deg); }
}

.ui-inputs-file-dropzone__input {
  display: none;
}


/* fulgore: ui/inputs/file_zone.css */
.ui-inputs-file-zone__zone {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-5) var(--space-4);
  border: 2px dashed var(--color-border);
  border-radius: var(--radius-lg);
  background-color: var(--color-surface);
  cursor: pointer;
  transition: border-color var(--duration-normal) var(--easing-default),
    background-color var(--duration-normal) var(--easing-default);
}

.ui-inputs-file-zone__zone:hover {
  border-color: var(--color-brand);
  background-color: var(--color-brand-surface);
}

.ui-inputs-file-zone__zone.is-dragover {
  border-color: var(--color-brand);
  background-color: var(--color-brand-surface);
}

.ui-inputs-file-zone__current {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
  margin-bottom: var(--space-2);
}

.ui-inputs-file-zone__current-thumb {
  max-height: 7.5rem;
  border-radius: var(--radius-md);
  object-fit: contain;
}

.ui-inputs-file-zone__current-name {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
}

.ui-inputs-file-zone__replace {
  font-size: var(--font-size-xs);
  color: var(--color-text-subtle);
}

.ui-inputs-file-zone__zone.has-file .ui-inputs-file-zone__current {
  display: none !important;
}

.ui-inputs-file-zone__preview {
  max-height: 7.5rem;
  margin-bottom: var(--space-2);
  border-radius: var(--radius-md);
  object-fit: contain;
}

.ui-inputs-file-zone__preview[hidden] {
  display: none !important;
}

.ui-inputs-file-zone__icon {
  font-size: var(--font-size-2xl);
}

.ui-inputs-file-zone__invite {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-text);
}

.ui-inputs-file-zone__filename {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
}

.ui-inputs-file-zone__filename[hidden] {
  display: none !important;
}

.ui-inputs-file-zone__formats {
  font-size: var(--font-size-xs);
  color: var(--color-text-subtle);
}

.ui-inputs-file-zone__zone.has-file .ui-inputs-file-zone__invite {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-normal);
  color: var(--color-text-subtle);
}


/* fulgore: ui/inputs/money.css */
.ui-inputs-money {
  display: flex;
  flex-direction: row;
  align-items: stretch;
  width: 100%;
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
  transition:
    border-color var(--duration-fast) var(--easing-default),
    box-shadow var(--duration-fast) var(--easing-default);
}

.ui-inputs-money:focus-within {
  border-color: var(--color-brand);
  box-shadow: var(--focus-ring);
}

.ui-inputs-money input[type="text"] {
  flex: 1;
  border: none;
  border-radius: 0;
  box-shadow: none;
}

.ui-inputs-money input[type="text"]:focus {
  border-color: transparent;
  box-shadow: none;
}

.ui-inputs-money__currency {
  display: flex;
  align-items: center;
  padding: 0 var(--space-3);
  border-left: 1px solid var(--color-border);
  background: var(--color-surface-subtle);
  color: var(--color-text-subtle);
  font-size: var(--font-size-sm);
  white-space: nowrap;
}

.ui-input--error .ui-inputs-money {
  border-color: var(--color-danger);
}

.ui-input--error .ui-inputs-money:focus-within {
  border-color: var(--color-danger);
  box-shadow: 0 0 0 3px var(--color-danger-a10);
}


/* fulgore: ui/inputs/password.css */
.ui-input {
  .password-wrapper {
    position: relative;
  }

  .password-wrapper input {
    padding-right: var(--space-10);
  }

  /* LA ZONE TACTILE, PAS L'ICÔNE. La pastille mesurait 16×16 — la taille de son
     icône, avec `padding: 0` autour. Le minimum WCAG 2.5.8 est 24×24 et Apple
     recommande 44 : sur un téléphone, 16px se rate. On agrandit la ZONE et on
     centre l'icône dedans, qui reste à 1rem : l'apparence ne change pas, la
     cible oui. `right` passe à `--space-1` pour que le carré de 44px reste dans
     le champ, qui fait 45px de haut.
     Mesuré au navigateur sur les écrans d'accès de FBordes, le 2026-08-03.
     ⚠️ CE SIDECAR EST LA COPIE SERVIE. `app/assets/stylesheets/fulgore/
     input.css` porte une seconde définition de `.password-toggle` qui n'est
     chargée nulle part chez les consumers — corriger celle-là seule ne change
     rien à l'écran, contre-épreuve faite le 2026-08-03. Les deux sont tenues
     alignées en attendant qu'on tranche laquelle disparaît. */
  .password-toggle {
    position: absolute;
    right: var(--space-1);
    top: 50%;
    transform: translateY(-50%);
    background: none;
    border: none;
    width: 44px;
    height: 44px;
    padding: 0;
    cursor: pointer;
    color: var(--color-text-subtle);
    display: flex;
    align-items: center;
    justify-content: center;
    transition: color var(--duration-fast) var(--easing-default);

    &:hover { color: var(--color-text); }

    .svg {
      display: block;
      width: 1rem;
      height: 1rem;
    }
  }
}


/* fulgore: ui/inputs/percentage.css */
.ui-inputs-percentage {
  display: flex;
  flex-direction: row;
  align-items: stretch;
  width: 100%;
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
  transition:
    border-color var(--duration-fast) var(--easing-default),
    box-shadow var(--duration-fast) var(--easing-default);
}

.ui-inputs-percentage:focus-within {
  border-color: var(--color-brand);
  box-shadow: var(--focus-ring);
}

.ui-inputs-percentage input[type="number"] {
  flex: 1;
  border: none;
  border-radius: 0;
  box-shadow: none;
}

.ui-inputs-percentage input[type="number"]:focus {
  border-color: transparent;
  box-shadow: none;
}

.ui-inputs-percentage__suffix {
  display: flex;
  align-items: center;
  padding: 0 var(--space-3);
  border-left: 1px solid var(--color-border);
  background: var(--color-surface-subtle);
  color: var(--color-text-subtle);
  font-size: var(--font-size-sm);
  white-space: nowrap;
}

.ui-input--error .ui-inputs-percentage {
  border-color: var(--color-danger);
}

.ui-input--error .ui-inputs-percentage:focus-within {
  border-color: var(--color-danger);
  box-shadow: 0 0 0 3px var(--color-danger-a10);
}


/* fulgore: ui/inputs/pill_select.css */
.pill-select {
  position: relative;
  display: inline-block;
  width: 100%;
}

.pill-select__trigger {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  padding: var(--space-1) var(--space-2);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  cursor: pointer;
  text-align: left;
}

.pill-select__caret {
  margin-left: auto;
  color: var(--color-text-subtle);
  font-size: var(--font-size-xs);
}

.pill-select__dropdown {
  position: absolute;
  top: calc(100% + var(--space-1));
  left: 0;
  z-index: var(--z-dropdown);
  min-width: 100%;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  padding: var(--space-1);
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.pill-select__dropdown[hidden] {
  display: none;
}

.pill-select__option {
  display: flex;
  align-items: center;
  padding: var(--space-1) var(--space-2);
  background: transparent;
  border: none;
  border-radius: var(--radius-sm);
  cursor: pointer;
  width: 100%;
  text-align: left;
}

.pill-select__option:hover {
  background: var(--color-surface-subtle);
}


/* fulgore: ui/inputs/range_slider.css */
.filter-field--range-slider {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  flex: 1;
  min-width: 180px;
}

.filter-range-slider__labels {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  font-size: var(--font-size-sm);
  font-variant-numeric: tabular-nums;
  color: var(--color-text-subtle);
  min-height: 1.2em;
  word-break: break-word;
}

.filter-range-slider__label {
  font-weight: var(--font-weight-semibold);
  color: var(--color-brand-dark);
}

.filter-range-slider__separator {
  color: var(--color-text-subtle);
  flex-shrink: 0;
}

.filter-range-slider__track {
  position: relative;
  height: 28px;
  display: flex;
  align-items: center;
}

.filter-range-slider__track::before {
  content: "";
  position: absolute;
  inset: 50% 0 auto 0;
  height: 4px;
  margin-top: -2px;
  background: var(--color-border);
  border-radius: var(--radius-full);
  pointer-events: none;
}

/* Les deux `input[type=range]` sont superposés en plein cadre et transparents :
   seules leurs poignées reçoivent le pointeur, ce qui laisse les deux
   attrapables sur toute la longueur de la piste. */
.filter-range-slider__thumb {
  position: absolute;
  inset: 0 0 0 0;
  width: 100%;
  margin: 0;
  padding: 0;
  background: transparent;
  pointer-events: none;
  -webkit-appearance: none;
  appearance: none;
}

.filter-range-slider__thumb:focus-visible {
  outline: none;
}

.filter-range-slider__thumb::-webkit-slider-runnable-track {
  background: transparent;
  height: 28px;
  border: none;
}

.filter-range-slider__thumb::-moz-range-track {
  background: transparent;
  height: 28px;
  border: none;
}

.filter-range-slider__thumb::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  pointer-events: all;
  width: 18px;
  height: 18px;
  border-radius: var(--radius-full);
  background: var(--color-brand);
  border: 2px solid var(--color-surface);
  box-shadow: 0 0 0 1px var(--color-brand-dark);
  cursor: grab;
  transition: transform 100ms ease;
}

.filter-range-slider__thumb::-webkit-slider-thumb:active {
  cursor: grabbing;
  transform: scale(1.1);
}

.filter-range-slider__thumb::-moz-range-thumb {
  pointer-events: all;
  width: 18px;
  height: 18px;
  border-radius: var(--radius-full);
  background: var(--color-brand);
  border: 2px solid var(--color-surface);
  box-shadow: 0 0 0 1px var(--color-brand-dark);
  cursor: grab;
  transition: transform 100ms ease;
}

.filter-range-slider__thumb::-moz-range-thumb:active {
  cursor: grabbing;
  transform: scale(1.1);
}

.filter-range-slider__thumb:focus-visible::-webkit-slider-thumb {
  box-shadow: 0 0 0 3px var(--color-brand-surface);
}

.filter-range-slider__thumb:focus-visible::-moz-range-thumb {
  box-shadow: 0 0 0 3px var(--color-brand-surface);
}

.filter-range-slider__thumb--min {
  z-index: 1;
}

.filter-range-slider__thumb--max {
  z-index: 2;
}


/* fulgore: ui/inputs/rich_text.css */
.ui-input__rich-text {
  min-height: 200px;
  padding: var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  font-family: inherit;
  font-size: var(--font-size-base);
  line-height: 1.5;
  background-color: var(--color-surface);
}

.ui-input__rich-text:focus {
  outline: none;
  border-color: var(--color-brand);
  box-shadow: var(--focus-ring);
}

.ui-input__rich-text:disabled {
  background-color: var(--color-surface-subtle);
  color: var(--color-text-disabled);
  cursor: not-allowed;
}


/* fulgore: ui/inputs/select.css */
.ui-select {
  width: 100%;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background-color: var(--color-surface);
  color: var(--color-text);
  font-size: var(--font-size-sm);
  cursor: pointer;
}

/* ============================================================
   Mode recherche (UI::Inputs::Select searchable: true)
   Le <select> natif garde .ui-select ci-dessus et reste la valeur
   soumise ; ce bloc n'habille que le déclencheur et le panneau que
   search-select_controller révèle par-dessus lui. `.is-open` est
   posé par dropdown_controller sur la racine .ui-search-select,
   jamais sur le panneau — même convention que row_actions_menu.css
   / directions_dropdown.css (racine.is-open racine__menu).
   ============================================================ */

.ui-search-select {
  position: relative;
  display: block;
  width: 100%;
}

/* Doit rendre comme .ui-select ci-dessus (même bordure, rayon,
   fond, taille de texte) pour qu'un formulaire mixant les deux
   modes reste homogène visuellement. */
.ui-search-select__trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  width: 100%;

  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);

  font-size: var(--font-size-sm);
  text-align: left;
  color: var(--color-text);

  background-color: var(--color-surface);

  cursor: pointer;

  /* Le libellé peut déborder (valeur longue) : il se coupe
     proprement, jamais le chevron qui reste visible à droite. */
  span {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    min-width: 0;
  }

  &::after {
    content: "▾";
    flex-shrink: 0;
    font-size: 0.75em; /* pas de token pour une taille relative au glyphe — même valeur que directions_dropdown.css */
    color: var(--color-text-subtle);
  }

  &:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring);
  }
}

.ui-search-select__panel {
  display: none;
  flex-direction: column;
  position: absolute;
  top: calc(100% + var(--space-1));
  left: 0;
  right: 0;
  z-index: var(--z-dropdown);

  /* Pas de token de hauteur dédié : borne dérivée de l'espacement
     (~15rem) pour garder ~6-7 options visibles avant de défiler. */
  max-height: calc(var(--space-10) * 6);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;

  /* L'écart intérieur est porté PAR LE PANNEAU, et aucun de ses deux enfants
     ne porte de marge horizontale. C'est délibéré : un enfant de conteneur
     flex étiré prend la largeur du contenu du parent SANS en déduire sa
     propre marge — mesuré ici à 9px à gauche et −7px à droite, un débordement
     que le `overflow: hidden` ci-dessus rogne, donc invisible à l'œil et
     visible seulement à la mesure. Reprendre l'écart en marge sur le champ
     réintroduirait exactement ce défaut. */
  padding: var(--space-2);

  background: var(--color-surface);
  box-shadow: var(--shadow-md);
}

.ui-search-select.is-open .ui-search-select__panel {
  display: flex;
}

.ui-search-select__filter {
  flex-shrink: 0;
  box-sizing: border-box;
  /* Aucune marge horizontale : l'écart vient du padding du panneau (cf. son
     commentaire). Seul l'écart SOUS le champ lui appartient. */
  margin: 0 0 var(--space-2);
  padding: var(--space-2) var(--space-3);

  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);

  font-size: var(--font-size-sm);
  color: var(--color-text);

  background: var(--color-surface);

  &:focus {
    outline: none;
    border-color: var(--color-brand);
    box-shadow: var(--focus-ring);
  }
}

/* Liste bornée + défilante : c'est tout l'intérêt du panneau
   recherche. Le champ de filtre ci-dessus reste fixe (flex-shrink: 0)
   pendant que la liste défile dans l'espace restant. */
.ui-search-select__list {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;

  margin: 0;
  padding: var(--space-1) 0;
  list-style: none;
}

.ui-search-select__option {
  padding: var(--space-2) var(--space-3);

  font-size: var(--font-size-sm);
  color: var(--color-text);

  cursor: pointer;

  /* Survol souris et .is-active (option courante au clavier)
     doivent rester visuellement distincts : les deux peuvent être
     vrais en même temps sur deux lignes différentes. */
  &:hover {
    background: var(--color-surface-alt);
  }

  &.is-active {
    background: var(--color-brand-a10);
    color: var(--color-brand-dark);
  }
}

.ui-search-select__empty {
  margin: 0;
  padding: var(--space-4);

  font-size: var(--font-size-sm);
  text-align: center;
  color: var(--color-text-subtle);
}


/* fulgore: ui/inputs/vat_breakdown.css */
.ui-inputs-vat-breakdown {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}


/* fulgore: ui/inputs/verification_code.css */
.ui-verification-code__boxes {
  display: flex;
  flex-direction: row;
  gap: var(--space-2);
}

.ui-verification-code__box {
  width: 3rem;
  height: 3.5rem;
  text-align: center;
  font-family: var(--font-family-mono);
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-semibold);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background-color: var(--color-surface);
  color: var(--color-text);
  transition: border-color var(--duration-fast) var(--easing-default),
              box-shadow var(--duration-fast) var(--easing-default);
  appearance: none;
  -moz-appearance: textfield;
}

.ui-verification-code__box::-webkit-outer-spin-button,
.ui-verification-code__box::-webkit-inner-spin-button {
  appearance: none;
}

.ui-verification-code__box:focus {
  outline: none;
  border-color: var(--color-brand);
  box-shadow: var(--focus-ring);
}

.ui-input--error .ui-verification-code__box {
  border-color: var(--color-danger);
}

.ui-input--error .ui-verification-code__box:focus {
  box-shadow: 0 0 0 3px var(--color-danger-a10);
}

.ui-verification-code__box:disabled {
  background-color: var(--color-surface-raised);
  color: var(--color-text-disabled);
  cursor: not-allowed;
}


/* fulgore: ui/label_with_tooltip.css */
.ui-label-with-tooltip {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  flex: 1;
  min-width: 0;
}

.ui-label-with-tooltip__text {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-text);
}


/* fulgore: ui/links/back.css */
.ui-links-back {
  display: flex;
  align-items: center;
  font-size: var(--font-size-sm);
  color: var(--color-text-subtle);
  margin-block: var(--space-6);
}

.ui-links-back a {
  color: inherit;
  text-decoration: none;
  transition: color var(--duration-fast) var(--easing-default);

  &:hover {
    color: var(--color-brand);
  }
}


/* fulgore: ui/links/edit.css */
.ui-button--sm .svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}


/* fulgore: ui/links/plain.css */
.ui-link {
  color: inherit;
  text-decoration: none;
  cursor: pointer;
  transition: opacity var(--duration-fast) var(--easing-default);

  &:hover {
    opacity: 0.7;
  }

  &:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring);
    border-radius: var(--radius-sm);
  }
}


/* fulgore: ui/locale_flag_switch.css */
/* Drapeau SVG du switch de langue. PAS de règle `fill` : les couleurs
   viennent du fichier SVG (contrairement à .svg de UI::Icon qui force
   currentColor). Ratio 4:3 (viewBox 640x480), hauteur fixe pour aligner. */
.ui-locale-flag {
  display: block;
  height: 1.25rem;
  width: auto;
  border-radius: var(--radius-sm);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1);
}


/* fulgore: ui/locale_switch.css */
.ui-locale-switch {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

.ui-locale-switch__link {
  text-transform: uppercase;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
}

/* Sous `include_current`, la langue courante est affichée à côté des autres.
   Sans marque visuelle, deux drapeaux côte à côte ne disent pas lequel est
   actif — le sélecteur redevient muet, ce que l'option cherchait à corriger.
   Ce sont donc les AUTRES qui s'effacent, et le `:has()` limite la règle aux
   switchers qui affichent réellement la langue courante : un switcher sans
   `--current` (le régime par défaut) garde ses liens à pleine opacité. */
.ui-locale-switch:has(.ui-locale-switch__link--current)
  .ui-locale-switch__link:not(.ui-locale-switch__link--current) {
  opacity: 0.55;
}

/* Le survol doit ANNULER l'estompage, pas le retour au survol de `.ui-link`
   (`opacity: 0.7`, plain.css). Un simple `.ui-locale-switch__link:hover` a la
   même spécificité que lui et passe après dans le bundle : il l'aurait écrasé
   partout, y compris sur les switchers qui n'utilisent pas `include_current`.
   Le sélecteur reste donc calqué sur celui de l'estompage.
   La valeur est `1` et non `0.7` : depuis un repos à 0.55, un survol à 0.7 ne
   laisserait que 0.15 d'écart, un signal qu'on ne voit plus. Annuler pour de
   bon est aussi ce que le premier mot de ce commentaire promet. */
.ui-locale-switch:has(.ui-locale-switch__link--current)
  .ui-locale-switch__link:not(.ui-locale-switch__link--current):hover {
  opacity: 1;
}


/* fulgore: ui/map.css */
.ui-map {
  width: 100%;
  height: 20rem;
  border-radius: var(--radius-md);
  overflow: hidden;
  z-index: 0;
}


/* fulgore: ui/menu_toggle.css */
.ui-menu-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  background: none;
  color: var(--color-text);
  cursor: pointer;
  transition: border-color var(--duration-fast) var(--easing-default),
              background-color var(--duration-fast) var(--easing-default);
}

.ui-menu-toggle:hover {
  border-color: var(--color-text-soft);
  background-color: var(--color-surface-alt);
}

.ui-menu-toggle:focus-visible {
  outline: none;
  border-color: var(--color-text-soft);
  box-shadow: var(--focus-ring);
}


/* fulgore: ui/metric_card.css */
.ui-metric-card {
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}

.ui-metric-card__label {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-size-xs);
  color: var(--color-text-subtle);
  font-weight: var(--font-weight-medium);
  margin-bottom: var(--space-1);
  position: relative;
}

.ui-metric-card__value {
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  color: var(--color-text);
  margin: 0;
  font-variant-numeric: tabular-nums;
}

/* ── Tooltip repositioning inside card ── */

.ui-metric-card .ui-help-tooltip__panel {
  top: calc(100% + var(--space-1));
  right: auto;
  left: 0;
  transform: none;
  min-width: 12rem;
}

/* ── Comparison delta (M/M-1, etc.) ── */

.ui-metric-card__comparison {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  margin-top: var(--space-1);
  font-size: var(--font-size-xs);
}

.ui-metric-card__delta-value {
  font-weight: var(--font-weight-semibold);
  font-variant-numeric: tabular-nums;
}

.ui-metric-card__delta-label {
  color: var(--color-text-subtle);
}

.ui-metric-card__comparison--positive .ui-metric-card__delta-value {
  color: var(--color-success);
}

.ui-metric-card__comparison--negative .ui-metric-card__delta-value {
  color: var(--color-danger);
}

.ui-metric-card__comparison--neutral .ui-metric-card__delta-value {
  color: var(--color-text-subtle);
}


/* fulgore: ui/notification/badge.css */
.ui-notification-badge {
  display: inline-block;
  min-width: 1.25rem;
  height: 1.25rem;
  line-height: 1.25rem;
  padding-inline: 5px;
  border-radius: var(--radius-full);
  background: var(--color-danger);
  color: var(--color-text-inverted);
  font-family: system-ui, -apple-system, sans-serif;
  font-size: 0.6875rem;
  font-weight: 600;
  text-align: center;
  font-variant-numeric: tabular-nums;
  box-sizing: border-box;
}


/* fulgore: ui/notification/bell.css */
.ui-notification-bell {
  position: relative;
}

.ui-notification-bell__button {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  padding: 0;
  border: none;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--color-text-inverted);
  cursor: pointer;
  position: relative;
  transition: background var(--duration-fast) var(--easing-default);

  .svg {
    width: var(--icon-size-sm);
    height: var(--icon-size-sm);
  }

  &:hover {
    background: rgba(255, 255, 255, 0.15);
  }

  &:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring);
  }
}

.ui-notification-bell__badge {
  position: absolute;
  top: 2px;
  right: 2px;
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 1rem;
  height: 1rem;
  padding: 0 3px;
  border-radius: var(--radius-full);
  background: var(--color-danger);
  color: var(--color-text-inverted);
  font-size: 0.625rem;
  font-weight: var(--font-weight-semibold);
  line-height: 1;
}

.ui-notification-bell__badge--hidden {
  display: none;
}

.ui-notification-bell__dropdown {
  display: none;
  position: absolute;
  top: 100%;
  right: 0;
  margin-top: var(--space-2);
  width: 22rem;
  max-width: calc(100vw - 2rem);
  max-height: 28rem;
  overflow-y: auto;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xl);
  z-index: var(--z-dropdown);

  &.is-open {
    display: block;
  }
}

.ui-notification-bell__dropdown-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-border);
}

.ui-notification-bell__dropdown-title {
  margin: 0;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
}

.ui-notification-bell__mark-all {
  border: none;
  background: none;
  padding: 0;
  font-size: var(--font-size-xs);
  color: var(--color-brand);
  cursor: pointer;

  &:hover {
    text-decoration: underline;
  }
}

.ui-notification-bell__list {
  display: flex;
  flex-direction: column;
}

.ui-notification-bell__empty {
  padding: var(--space-6);
  text-align: center;
  font-size: var(--font-size-sm);
  color: var(--color-text-subtle);
  margin: 0;
}


/* fulgore: ui/notification/item.css */
.ui-notification-item {
  display: grid;
  grid-template-columns: 1.75rem 1fr;
  gap: var(--space-2);
  align-items: start;
  padding: var(--space-2) var(--space-4);
  text-decoration: none;
  color: var(--color-text);

  &:not(:last-child) {
    border-bottom: 1px solid var(--color-border);
  }

  &:hover {
    background: var(--color-surface-raised);
  }

  &--unread {
    background: var(--color-brand-surface);

    &:hover {
      background: var(--color-brand-a10);
    }
  }
}

.ui-notification-item__avatar {
  flex-shrink: 0;

  .ui-user-badge {
    gap: 0;
  }

  .ui-user-badge__text {
    display: none;
  }

  .ui-user-badge__circle {
    width: 1.75rem !important;
    height: 1.75rem !important;
    font-size: 0.625rem !important;
  }
}

.ui-notification-item__content {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.ui-notification-item__title-line {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-1);
}

.ui-notification-item__actor-name {
  font-size: var(--font-size-xs);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ui-notification-item .ui-pill {
  font-size: 0.5625rem;
  padding: 0 4px;
  line-height: 1.125rem;
  flex-shrink: 0;
}

.ui-notification-item__body {
  margin: 0;
  font-size: var(--font-size-xs);
  color: var(--color-text-subtle);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ui-notification-item__meta {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  margin-top: 1px;
}

.ui-notification-item__time,
.ui-notification-item__context {
  font-size: 0.625rem;
  color: var(--color-text-disabled);
}


/* fulgore: ui/pagination.css */
.ui-pagination {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
}

.ui-pagination__arrow,
.ui-pagination__page,
.ui-pagination__gap {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--space-8);
  height: var(--space-8);
  padding: 0 var(--space-2);
  border-radius: var(--radius-md);
  font-size: var(--font-size-sm);
  text-decoration: none;
}

.ui-pagination__arrow {
  color: var(--color-text-subtle);

  &:hover {
    background: var(--color-surface-subtle);
    color: var(--color-text);
  }
}

.ui-pagination__arrow--disabled {
  color: var(--color-text-disabled);
  pointer-events: none;
}

.ui-pagination__page {
  color: var(--color-text-subtle);

  &:hover {
    background: var(--color-surface-subtle);
    color: var(--color-text);
  }
}

.ui-pagination__page--current {
  background: var(--color-brand);
  color: var(--color-text-inverted);
  border: 1px solid var(--color-brand);
  font-weight: var(--font-weight-medium);
  pointer-events: none;
}

.ui-pagination__gap {
  color: var(--color-text-disabled);
  pointer-events: none;
}


/* fulgore: ui/pill.css */
.ui-pill {
  display: inline-flex;
  align-items: center;
  padding: 2px var(--space-3);
  border-radius: 999px;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
}

.ui-pill--brand {
  background: var(--color-violet-100);
  color: var(--color-violet-700);
}

.ui-pill--info {
  background: var(--color-blue-100);
  color: var(--color-blue-700);
}

.ui-pill--success {
  background: var(--color-green-100);
  color: var(--color-green-700);
}

.ui-pill--danger {
  background: var(--color-red-100);
  color: var(--color-red-700);
}

.ui-pill--warning {
  background: var(--color-amber-100);
  color: var(--color-amber-700);
}

.ui-pill--neutral {
  background: var(--color-neutral-100);
  color: var(--color-neutral-700);
}

/* Teintes nommées — la couleur est choisie par l'utilisateur d'un consumer,
   le nom ne porte donc aucun sens métier. Les cinq premières doublent
   volontairement une variante sémantique (brand/info/success/danger/warning) :
   « ce que ça veut dire » et « de quelle couleur c'est » sont deux vocabulaires
   distincts, et seul le second est configurable. */
.ui-pill--violet { background: var(--color-violet-100); color: var(--color-violet-700); }
.ui-pill--blue   { background: var(--color-blue-100);   color: var(--color-blue-700); }
.ui-pill--green  { background: var(--color-green-100);  color: var(--color-green-700); }
.ui-pill--red    { background: var(--color-red-100);    color: var(--color-red-700); }
.ui-pill--amber  { background: var(--color-amber-100);  color: var(--color-amber-700); }
.ui-pill--indigo { background: var(--color-indigo-100); color: var(--color-indigo-700); }
.ui-pill--teal   { background: var(--color-teal-100);   color: var(--color-teal-700); }
.ui-pill--lime   { background: var(--color-lime-100);   color: var(--color-lime-700); }
.ui-pill--orange { background: var(--color-orange-100); color: var(--color-orange-700); }
.ui-pill--pink   { background: var(--color-pink-100);   color: var(--color-pink-700); }
.ui-pill--brown  { background: var(--color-brown-100);  color: var(--color-brown-700); }

.ui-pill--draft {
  background: var(--color-surface-raised);
  color: var(--color-text-subtle);
}

.ui-pill--in_progress {
  background: var(--color-success-surface);
  color: var(--color-success);
}

.ui-pill--review {
  background: var(--color-warning-surface);
  color: var(--color-warning);
}

.ui-pill--completed {
  background: var(--color-info-surface);
  color: var(--color-info);
}

.ui-pill--archived {
  background: var(--color-surface-raised);
  color: var(--color-text-subtle);
}

.ui-pill--admin {
  background: var(--color-violet-100);
  color: var(--color-violet-700);
}

.ui-pill--accountant {
  background: var(--color-blue-100);
  color: var(--color-blue-700);
}

.ui-pill--active {
  background: var(--color-success-surface);
  color: var(--color-success);
}

.ui-pill--suspended {
  background: var(--color-red-100);
  color: var(--color-red-700);
}

.ui-pill--pending {
  background: var(--color-warning-surface);
  color: var(--color-warning);
}

.ui-pill--read {
  background: var(--color-blue-100);
  color: var(--color-blue-700);
}

.ui-pill--lmnp {
  background: var(--color-brand-surface);
  color: var(--color-brand);
}

.ui-pill--lmnp_vat {
  background: var(--color-info-surface);
  color: var(--color-info);
}

.ui-pill--lg {
  padding: var(--space-2) var(--space-4);
  font-size: var(--font-size-sm);
}

.ui-pill--strong {
  padding: var(--space-1) var(--space-3);
  font-weight: var(--font-weight-bold);
  box-shadow: var(--shadow-pill-strong);
}

.ui-pill--strong.ui-pill--brand   { background: var(--color-violet-600); color: var(--color-neutral-0); }
.ui-pill--strong.ui-pill--info    { background: var(--color-blue-700);   color: var(--color-neutral-0); }
.ui-pill--strong.ui-pill--success { background: var(--color-green-500);  color: var(--color-neutral-0); }
.ui-pill--strong.ui-pill--warning { background: var(--color-amber-500);  color: var(--color-neutral-0); }
.ui-pill--strong.ui-pill--danger  { background: var(--color-red-500);    color: var(--color-neutral-0); }
.ui-pill--strong.ui-pill--neutral { background: var(--color-neutral-700); color: var(--color-neutral-0); }

.ui-pill--strong.ui-pill--violet { background: var(--color-violet-600); color: var(--color-neutral-0); }
.ui-pill--strong.ui-pill--blue   { background: var(--color-blue-700);   color: var(--color-neutral-0); }
.ui-pill--strong.ui-pill--green  { background: var(--color-green-500);  color: var(--color-neutral-0); }
.ui-pill--strong.ui-pill--red    { background: var(--color-red-500);    color: var(--color-neutral-0); }
.ui-pill--strong.ui-pill--amber  { background: var(--color-amber-500);  color: var(--color-neutral-0); }
.ui-pill--strong.ui-pill--indigo { background: var(--color-indigo-700); color: var(--color-neutral-0); }
.ui-pill--strong.ui-pill--teal   { background: var(--color-teal-700);   color: var(--color-neutral-0); }
.ui-pill--strong.ui-pill--lime   { background: var(--color-lime-700);   color: var(--color-neutral-0); }
.ui-pill--strong.ui-pill--orange { background: var(--color-orange-700); color: var(--color-neutral-0); }
.ui-pill--strong.ui-pill--pink   { background: var(--color-pink-700);   color: var(--color-neutral-0); }
.ui-pill--strong.ui-pill--brown  { background: var(--color-brown-700);  color: var(--color-neutral-0); }


/* fulgore: ui/progress_ring.css */
.ui-progress-ring {
  display: flex;
  align-items: center;
  gap: var(--space-6);
  padding: var(--space-6) var(--space-8);
  background-color: var(--color-brand-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
}

.ui-progress-ring__ring {
  flex-shrink: 0;
  width: 5rem;
  height: 5rem;
}

.ui-progress-ring__svg {
  width: 100%;
  height: 100%;
  transform: rotate(-90deg);
}

.ui-progress-ring__track {
  fill: none;
  stroke: var(--color-border);
  stroke-width: 8;
}

.ui-progress-ring__fill {
  fill: none;
  stroke: var(--color-brand);
  stroke-width: 8;
  stroke-linecap: round;
  transition: stroke-dashoffset 1.2s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.ui-progress-ring__ratio {
  transform: rotate(90deg);
  transform-origin: 60px 60px;
  text-anchor: middle;
  dominant-baseline: central;
  font-family: var(--font-family-display);
  font-size: 1.25rem;
  font-weight: var(--font-weight-bold);
  fill: var(--color-text);
}

.ui-progress-ring__text {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.ui-progress-ring__title {
  font-family: var(--font-family-display);
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
  margin: 0;
}

.ui-progress-ring__subtitle {
  font-size: var(--font-size-sm);
  color: var(--color-text-subtle);
  margin: 0;
}


/* fulgore: ui/row_actions_menu.css */
/* RowActionsMenu — kebab (⋮) dropdown wrapping already-rendered action
   components (UI::Links::* / UI::Buttons::*) as flat, full-width menu rows.
   Stimulus `dropdown` toggles .is-open on this root element, not the menu
   (cf. directions_dropdown.css / dropdown_controller). */

.ui-row-actions-menu {
  position: relative;
  display: inline-block;
}

.ui-row-actions-menu__toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;

  width: 2rem;
  height: 2rem;
  padding: 0;
  border: none;
  border-radius: var(--radius-md);

  color: var(--color-text-subtle);
  background: transparent;

  cursor: pointer;
  transition: background var(--duration-fast) var(--easing-default),
    color var(--duration-fast) var(--easing-default);

  .svg {
    width: 1.25rem;
    height: 1.25rem;
  }

  &:hover:not(:disabled):not(.ui-row-actions-menu__toggle--disabled) {
    background: var(--color-surface-subtle);
    color: var(--color-text);
  }

  &:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring);
  }
}

.ui-row-actions-menu__menu {
  display: none;
  position: absolute;
  top: calc(100% + var(--space-1));
  right: 0;
  z-index: var(--z-dropdown);
  min-width: 12rem;

  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;

  background: var(--color-surface);
  box-shadow: var(--shadow-md);
}

.ui-row-actions-menu.is-open .ui-row-actions-menu__menu {
  display: block;
}

.ui-row-actions-menu__item {
  display: block;
}

/* Neutralize the wrapped action components (ui-link, ui-button — primary/
   secondary/danger, all sizes) back into flat, full-width text menu rows.
   Targets the real classes emitted by UI::Links::Show/Edit/New (<a
   class="ui-button ui-button--{primary,secondary} ui-button--sm">) and
   UI::Buttons::Destroy (<form> root wrapping <button class="ui-button
   ui-button--danger ui-button--sm">). */
.ui-row-actions-menu__item a,
.ui-row-actions-menu__item button,
.ui-row-actions-menu__item form {
  display: block;
  width: 100%;
  box-sizing: border-box;

  margin: 0;
  padding: var(--space-2) var(--space-4);
  border: none;
  border-radius: 0;

  font-size: var(--font-size-sm);
  text-align: left;
  color: var(--color-text);
  text-decoration: none;
  white-space: nowrap;

  background: transparent;
  box-shadow: none;

  cursor: pointer;
}

.ui-row-actions-menu__item a:hover,
.ui-row-actions-menu__item button:hover,
.ui-row-actions-menu__item form:hover {
  background: var(--color-surface-alt);
}

.ui-row-actions-menu__item a:focus-visible,
.ui-row-actions-menu__item button:focus-visible {
  outline: none;
  box-shadow: none;
  background: var(--color-surface-alt);
}

/* The base variant rules (.ui-button.ui-button--primary/secondary/danger,
   specificity 0,2,0) outrank the plain-element resets above (0,1,1) and
   win regardless of concat order — so background/color/hover-background
   from the wrapped button chrome survive unless matched at equal-or-higher
   specificity here. Re-neutralize per variant explicitly. */
.ui-row-actions-menu__item .ui-button--primary,
.ui-row-actions-menu__item .ui-button--secondary,
.ui-row-actions-menu__item .ui-button--danger {
  color: var(--color-text);
  background: transparent;
  border-color: transparent;
}

.ui-row-actions-menu__item .ui-button--primary:hover,
.ui-row-actions-menu__item .ui-button--secondary:hover,
.ui-row-actions-menu__item .ui-button--danger:hover {
  background: var(--color-surface-alt);
  border-color: transparent;
}

/* The wrapped icon (pen-to-square, plus…) rides along the text baseline
   instead of the button's centered flex layout. `display: inline-block`
   defends against a consumer global reset (`svg { display: block }`) that
   would otherwise stack the icon above its label. */
.ui-row-actions-menu__item .svg {
  display: inline-block;
  width: var(--font-size-sm);
  height: var(--font-size-sm);
  margin-right: var(--space-2);
  vertical-align: -0.15em;
}

/* Destroy's <form> is the item's direct child and must not add its own
   padding on top of the <button> it wraps, or add block spacing. */
.ui-row-actions-menu__item form {
  padding: 0;
}

.ui-row-actions-menu__item form button {
  width: 100%;
}

/* Danger row (UI::Buttons::Destroy → .ui-button--danger) keeps a red
   label, overriding the neutral text-color reset above. Source order
   (after the variant reset block) settles the equal-specificity (0,2,0)
   tie in its favor — hover background already comes from the reset
   block above, so only color needs restating here. */
.ui-row-actions-menu__item .ui-button--danger {
  color: var(--color-danger);
}

@media (prefers-reduced-motion: reduce) {
  .ui-row-actions-menu__toggle {
    transition: none;
  }
}


/* fulgore: ui/section.css */
.ui-section {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-5);
}

/* ── Header ── */

.ui-section__header {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--color-border);
  margin-bottom: var(--space-4);
}

.ui-section__header[data-action] {
  cursor: pointer;
  user-select: none;
}

.ui-section__icon {
  flex-shrink: 0;
  font-size: var(--font-size-lg);
  line-height: 1;
}

.ui-section__title {
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
  margin: 0;
}

.ui-section__counter {
  font-weight: var(--font-weight-normal);
  color: var(--color-text-subtle);
}

.ui-section__action {
  margin-left: auto;
  flex-shrink: 0;
}

.ui-section__toggle {
  margin-left: auto;
  background: none;
  border: none;
  padding: var(--space-1);
  cursor: pointer;
  color: var(--color-text-subtle);
  font-size: var(--font-size-sm);
  transition: transform var(--duration-fast);
}

.ui-section__action + .ui-section__toggle {
  margin-left: 0;
}

/* ── Body ── */

.ui-section__body {
  min-height: 0;
}

/* ── Footer ── */

.ui-section__footer {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border);
  margin-top: var(--space-4);
}


/* fulgore: ui/section_header.css */
.ui-section-header {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--color-border);
  margin-bottom: var(--space-4);
}

.ui-section-header__icon {
  flex-shrink: 0;
  font-size: var(--font-size-lg);
  line-height: 1;
}

.ui-section-header__title {
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
  margin: 0;
}

.ui-section-header__action {
  margin-left: auto;
  flex-shrink: 0;
}


/* fulgore: ui/shell/navbar.css */
.ui-shell-navbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  height: var(--navbar-height);
  padding: var(--space-1) var(--space-4);
  box-sizing: border-box;
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  background: var(--shell-navbar-bg);
  color: var(--shell-navbar-fg);

  .navbar-hamburger { display: none; }
}
@media (max-width: 1023px) {
  .ui-shell-navbar .navbar-hamburger { display: flex; }
}
.navbar-sidebar-toggle {
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border: none;
  border-radius: var(--radius-md);
  color: inherit;
  background: transparent;
  cursor: pointer;
  transition: background var(--duration-fast) var(--easing-default);
  .svg {
    width: var(--icon-size-sm);
    height: var(--icon-size-sm);
    transition: transform var(--duration-fast) var(--easing-default);
  }
  &[aria-expanded="false"] .svg { transform: rotate(180deg); }
  &:hover { background: rgba(255, 255, 255, 0.15); }
  &:focus-visible { outline: none; box-shadow: var(--focus-ring); }
}
.ui-shell-navbar .navbar-sidebar-toggle { display: flex; }
@media (max-width: 1023px) {
  .ui-shell-navbar .navbar-sidebar-toggle { display: none; }
}
.ui-shell-navbar__brand {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  text-decoration: none;
  color: inherit;
}
.ui-shell-navbar__brand-logo { height: 28px; width: auto; }
.ui-shell-navbar__brand-name {
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
}
.navbar-session-email {
  font-size: var(--font-size-sm);
  color: color-mix(in srgb, var(--shell-navbar-fg) 85%, transparent);
  white-space: nowrap;
}
@media (max-width: 1023px) {
  .navbar-session-email { display: none; }
}
.navbar-logout { margin: 0; }
.ui-shell-navbar .navbar-logout .ui-button {
  display: flex;
  align-items: center;
  padding: var(--space-2) var(--space-3);
  border: 1px solid color-mix(in srgb, var(--shell-navbar-fg) 30%, transparent);
  border-radius: var(--radius-sm);
  font-family: inherit;
  font-size: var(--font-size-sm);
  font-weight: inherit;
  color: var(--shell-navbar-fg);
  background: transparent;
  box-shadow: none;
  &:hover:not(:disabled) {
    background: color-mix(in srgb, var(--shell-navbar-fg) 15%, transparent);
    color: var(--shell-navbar-fg);
  }
  &:focus-visible { outline: none; box-shadow: var(--focus-ring); }
}


/* fulgore: ui/shell/sidebar.css */
.ui-shell-sidebar {
  position: fixed;
  top: var(--navbar-height);
  left: 0;
  bottom: 0;
  z-index: var(--z-raised);
  width: var(--sidebar-width);
  max-width: 80vw;
  box-sizing: border-box;
  overflow-x: hidden;
  overflow-y: auto;
  padding: var(--space-6) var(--space-4);
  border-right: 1px solid var(--color-border);
  box-shadow: var(--shadow-lg);
  background: var(--color-surface-subtle);
  transform: translateX(-100%);
  transition: transform var(--duration-slow) var(--easing-out);
  nav { display: flex; flex-direction: column; gap: var(--space-2); }
  &.is-compact, &.is-expanded { transform: translateX(0); }
}
@media (min-width: 1024px) {
  .ui-shell-sidebar {
    position: sticky;
    top: var(--navbar-height);
    left: auto;
    bottom: auto;
    height: calc(100dvh - var(--navbar-height));
    max-width: none;
    width: var(--sidebar-width);
    flex-shrink: 0;
    align-self: flex-start;
    box-shadow: none;
    transform: none;
    transition: width var(--duration-slow) var(--easing-out);
  }
  .ui-shell-sidebar.is-compact {
    width: var(--sidebar-compact-width);
    padding: var(--space-6) var(--space-3);
  }
  .ui-shell-sidebar.is-expanded { width: var(--sidebar-width); }
  .ui-shell-sidebar.is-compact .ui-shell-sidebar__link {
    justify-content: center;
    padding: var(--space-3);
  }
  .ui-shell-sidebar.is-compact .sidebar-link__label { display: none; }
  .ui-shell-sidebar.is-compact .sidebar-section__heading { display: none; }
  .ui-shell-sidebar.is-compact .sidebar-section.is-collapsed .sidebar-section__items { display: flex; }
}
@media (prefers-reduced-motion: reduce) {
  .ui-shell-sidebar,
  .ui-shell-sidebar .sidebar-section__toggle .svg { transition: none; }
}
.sidebar-section {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding-top: var(--space-4);
}
.sidebar-section:first-of-type { padding-top: var(--space-2); }
.sidebar-section__heading { margin: 0; }
.sidebar-section__toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  width: 100%;
  padding: var(--space-1) var(--space-3);
  border: none;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-text-subtle);
  background: transparent;
  cursor: pointer;
  transition: color var(--duration-fast) var(--easing-default);
  .svg {
    width: var(--icon-size-sm);
    height: var(--icon-size-sm);
    flex-shrink: 0;
    transition: transform var(--duration-fast) var(--easing-default);
  }
  &:hover { color: var(--color-text); }
  &:focus-visible { outline: none; box-shadow: var(--focus-ring); border-radius: var(--radius-sm); }
}
.sidebar-section.is-collapsed .sidebar-section__toggle .svg { transform: rotate(-90deg); }
.sidebar-section__items { display: flex; flex-direction: column; gap: var(--space-2); }
.sidebar-section.is-collapsed .sidebar-section__items { display: none; }
.ui-shell-sidebar__link {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  text-decoration: none;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-subtle);
  transition:
    background var(--duration-fast) var(--easing-default),
    color var(--duration-fast) var(--easing-default);
  .svg { width: var(--icon-size-sm); height: var(--icon-size-sm); flex-shrink: 0; }
  &:hover:not(.ui-shell-sidebar__link--active) {
    background: var(--color-surface-raised);
    color: var(--color-text);
  }
  &:focus-visible { outline: none; box-shadow: var(--focus-ring); }
}
.ui-shell-sidebar__link--active {
  background: var(--color-brand-surface);
  color: var(--color-brand);
  font-weight: var(--font-weight-semibold);
}
.sidebar-link__label { display: inline; }


/* fulgore: ui/skeleton_block.css */
@keyframes skeleton-shimmer {
  0%   { background-position: 200% center; }
  100% { background-position: -200% center; }
}

.ui-skeleton-block {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.ui-skeleton-block--card {
  padding: var(--space-4);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  gap: var(--space-3);
}

.ui-skeleton-block__title {
  height: 0.875rem;
  width: 45%;
  border-radius: var(--radius-sm);
  background: linear-gradient(
    90deg,
    var(--color-surface-raised) 25%,
    var(--color-surface-subtle) 50%,
    var(--color-surface-raised) 75%
  );
  background-size: 200%;
  animation: skeleton-shimmer 1.5s infinite;
  margin-bottom: var(--space-1);
}

.ui-skeleton-block__row {
  display: flex;
  flex-direction: row;
  gap: var(--space-3);
  height: 2rem;
  border-radius: var(--radius-sm);
  background: linear-gradient(
    90deg,
    var(--color-surface-raised) 25%,
    var(--color-surface-subtle) 50%,
    var(--color-surface-raised) 75%
  );
  background-size: 200%;
  animation: skeleton-shimmer 1.5s infinite;
}

.ui-skeleton-block--card .ui-skeleton-block__row {
  height: 1.25rem;
}

.ui-skeleton-block__cell--wide {
  flex: 3;
}

.ui-skeleton-block__cell--narrow {
  flex: 1;
}


/* fulgore: ui/spinner.css */
.ui-spinner {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

.ui-spinner::before {
  content: "";
  display: block;
  width: 1em;
  height: 1em;
  border: 2px solid var(--color-border);
  border-top-color: var(--color-brand);
  border-radius: var(--radius-full);
  animation: spinner-spin var(--duration-slow) linear infinite;
}

@keyframes spinner-spin {
  to { transform: rotate(360deg); }
}

.spinner-label {
  font-size: var(--font-size-sm);
  color: var(--color-text-subtle);
}


/* fulgore: ui/stat_grid.css */
/* ── Stat grid: reusable dt/dd key-value layout ──
 *
 * PAS un sidecar orphelin : aucun stat_grid.rb n'existe et c'est voulu.
 * `.ui-stat-grid` est une layout utilitaire cross-composant, émise par
 * UI::Bases::StatCard (qui a par ailleurs son propre sidecar
 * bases/stat_card.css) et écrite en dur chez des consumers (Fatima
 * admin/orders/*_section, FBordes manage/dashboard). La purger ou la
 * renommer casse leur rendu sans erreur Ruby. */

.ui-stat-grid {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: var(--space-2) var(--space-4);
  margin: 0;
}

.ui-stat-grid__label {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-size-sm);
  color: var(--color-text-subtle);
  font-weight: var(--font-weight-medium);
  position: relative;
}

.ui-stat-grid__icon {
  font-size: var(--font-size-base);
}

.ui-stat-grid__value {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
  margin: 0;
  text-align: right;
}

/* ── Tooltip repositioning ── */

.ui-stat-grid .ui-help-tooltip__panel {
  top: calc(100% + var(--space-1));
  right: auto;
  left: 0;
  transform: none;
}


/* fulgore: ui/status_icon.css */
.ui-status-icon {
  font-size: var(--font-size-base);
  flex-shrink: 0;
  line-height: 1;
}


/* fulgore: ui/summary_row.css */
.ui-summary-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  text-decoration: none;
  color: inherit;
}

.ui-summary-row--clickable {
  border-radius: var(--radius-md);
  transition: background var(--duration-fast) var(--easing-default);
}

.ui-summary-row--clickable:hover {
  background: var(--color-surface-subtle);
}

.ui-summary-row__icon {
  font-size: var(--font-size-base);
  flex-shrink: 0;
  line-height: 1;
}

.ui-summary-row__label {
  flex: 1;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-text);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ui-summary-row__dots {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  flex-shrink: 0;
}

.ui-summary-row__dot {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: var(--radius-full);
}

.ui-summary-row__dot--validated {
  background: var(--color-success);
}

.ui-summary-row__dot--pending {
  background: var(--color-warning);
}

.ui-summary-row__dot--rejected {
  background: var(--color-danger);
}

.ui-summary-row__dot--missing {
  background: var(--color-neutral-300);
}

.ui-summary-row__count {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-subtle);
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
}


/* fulgore: ui/tabs.css */
.ui-tabs__list {
  display: flex;
  gap: var(--space-1);
  overflow-x: auto;
  border-bottom: 1px solid var(--color-border);
  margin-bottom: var(--space-4);
  scrollbar-width: none;
}

.ui-tabs__list::-webkit-scrollbar {
  display: none;
}

.ui-tabs__tab {
  flex-shrink: 0;
  padding: var(--space-2) var(--space-4);
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  color: var(--color-text-subtle);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  white-space: nowrap;
  cursor: pointer;
  transition: color var(--duration-fast) var(--easing-default),
              border-color var(--duration-fast) var(--easing-default);
}

.ui-tabs__tab:hover {
  color: var(--color-text);
}

.ui-tabs__tab--active {
  color: var(--color-brand);
  border-bottom-color: var(--color-brand);
}

.ui-tabs__panel[hidden] {
  display: none;
}


/* fulgore: ui/timeline.css */
.ui-timeline {
  padding: var(--space-4) 0;
}

/* ── Track ── */

.ui-timeline__track {
  position: relative;
  height: 2rem;
  margin: 0 var(--space-6);
}

.ui-timeline__line {
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  height: 2px;
  background: var(--color-border-strong);
  transform: translateY(-50%);
}

.ui-timeline__dot {
  position: absolute;
  top: 50%;
  width: 0.75rem;
  height: 0.75rem;
  border-radius: var(--radius-full);
  background: var(--color-neutral-400);
  border: 2px solid var(--color-surface);
  transform: translate(-50%, -50%);
  z-index: 1;
}

.ui-timeline__dot--past {
  background: var(--color-brand);
}

.ui-timeline__today {
  position: absolute;
  top: 50%;
  width: 0.5rem;
  height: 1.25rem;
  background: var(--color-danger);
  border-radius: var(--radius-sm);
  transform: translate(-50%, -50%);
  z-index: 2;
}

/* ── Labels ── */

.ui-timeline__labels {
  position: relative;
  margin: var(--space-2) var(--space-6) 0;
  height: 3.5rem;
}

.ui-timeline__label {
  position: absolute;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  white-space: nowrap;
}

.ui-timeline__label-text {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
}

.ui-timeline__label-date {
  font-size: var(--font-size-xs);
  color: var(--color-text-subtle);
}

.ui-timeline__delay {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-subtle);
  margin-top: var(--space-1);
}

.ui-timeline__delay--urgent {
  color: var(--color-danger);
  font-weight: var(--font-weight-semibold);
}


/* fulgore: ui/user_badge.css */
.ui-user-badge {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.ui-user-badge__circle {
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-full);
  overflow: hidden;
  color: var(--color-neutral-0);
  font-weight: var(--font-weight-semibold);
  flex-shrink: 0;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.ui-user-badge__text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.ui-user-badge__name {
  font-weight: var(--font-weight-medium);
  color: var(--color-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ui-user-badge__email {
  color: var(--color-text-subtle);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ui-user-badge__avatar {
  width: 100%;
  height: 100%;
  border-radius: var(--radius-full);
  object-fit: cover;
}

.ui-user-badge__you {
  color: var(--color-text-subtle);
  font-style: italic;
  font-size: var(--font-size-xs);
}

/* --- Tailles --- */

.ui-user-badge--sm .ui-user-badge__circle {
  width: 1.5rem;
  height: 1.5rem;
  font-size: var(--font-size-xs);
}

.ui-user-badge--sm .ui-user-badge__name {
  font-size: 0.8125rem;
}

.ui-user-badge--sm .ui-user-badge__email {
  font-size: var(--font-size-xs);
}

.ui-user-badge--md .ui-user-badge__circle {
  width: 2rem;
  height: 2rem;
  font-size: 0.8125rem;
}

.ui-user-badge--md .ui-user-badge__name {
  font-size: var(--font-size-sm);
}

.ui-user-badge--md .ui-user-badge__email {
  font-size: var(--font-size-xs);
}

.ui-user-badge--lg .ui-user-badge__circle {
  width: 2.5rem;
  height: 2.5rem;
  font-size: var(--font-size-base);
}

.ui-user-badge--lg .ui-user-badge__name {
  font-size: var(--font-size-base);
}

.ui-user-badge--lg .ui-user-badge__email {
  font-size: var(--font-size-sm);
}


/* fulgore: ui/widgets/grid.css */
.ui-widgets-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
  gap: var(--space-6);
  align-items: start;
}
