/* The 2026 visual language.
 *
 * Near-white paper, one contrast colour, and that colour is the navy the logo
 * already wears. The palette itself is remapped at source across every
 * application stylesheet; this file is for the shapes a palette cannot reach.
 *
 * Written after a first attempt that broke three layouts, so two rules of its
 * own: nothing here changes a `display` mode or a grid template that another
 * stylesheet already owns, and nothing here gives a table column a fixed width
 * - those were the two mistakes, and both were invisible to a console and
 * obvious on a screen. `scripts/layout-probe.js` is the check.
 */

:root {
  --t-bg: #F7F6F2;
  --t-surface: #FFFFFF;
  --t-surface-soft: #FBFAF7;
  --t-line: #DEDCD6;
  --t-line-soft: #EEEDE8;
  --t-ink: #0B1433;
  --t-ink-soft: #3B4860;
  --t-muted: #596378;
  --t-faint: #959FB2;
  --t-navy: #0B1F4D;
  --t-navy-hover: #1A377E;
  --t-tint: #F3F7FF;
  --t-tint-line: #C7DBFF;
  --t-radius: 12px;
  --t-radius-sm: 8px;
}
@keyframes thesr-ai-pulse {
  0% { box-shadow: 0 0 0 0 rgba(22, 159, 101, 0.55); }
  70% { box-shadow: 0 0 0 7px rgba(22, 159, 101, 0); }
  100% { box-shadow: 0 0 0 0 rgba(22, 159, 101, 0); }
}
@keyframes thesr-ai-shimmer {
  from { background-position: 0% 50%; }
  to { background-position: -220% 50%; }
}
body.app-body .quick-action {
  background: var(--t-surface) !important;
  background-image: none !important;
  border: 1px solid var(--t-line) !important;
  box-shadow: none !important;
  color: var(--t-ink) !important;
  border-radius: var(--t-radius) !important;
}

body.app-body .quick-action:hover {
  border-color: var(--t-tint-line) !important;
  background: var(--t-tint) !important;
}

body.app-body .quick-action--primary,
body.app-body .quick-action--primary i,
body.app-body .quick-action--primary span {
  background: var(--t-navy) !important;
  border-color: var(--t-navy) !important;
  color: #FFFFFF !important;
}

body.app-body .quick-action--primary i,
body.app-body .quick-action--primary span {
  background: transparent !important;
}

body.app-body .quick-action--primary:hover {
  background: var(--t-navy-hover) !important;
  border-color: var(--t-navy-hover) !important;
  color: #FFFFFF !important;
}

/* The first paint of the application: a warm radial wash behind the splash
   card, which is the one colour the interface no longer has. */
body.app-body #app-loader {
  background: var(--t-bg) !important;
  background-image: none !important;
}

body.app-body .app-loader__logo {
  width: 44px;
  height: 44px;
  border-radius: 0;
  background: transparent !important;
  object-fit: contain;
}

/* Every primary button carried a warm glow under it - a second accent colour
   in a palette that has one. Two stylesheets set it with !important behind a
   four-class selector, so this one has to be at least as specific to win. */
body.app-body[data-app-page="app"] .btn.btn-primary,
body.app-body[data-app-page="app"] .btn.btn-primary:hover,
body.app-body[data-app-page="app"] .btn.btn-primary:focus,
body.app-body .btn-primary,
body.app-body .btn-primary:hover,
body.app-body .btn-primary:focus {
  box-shadow: none !important;
}

body.app-body .toggle-icon {
  background: var(--t-line-soft) !important;
  color: var(--t-muted) !important;
  border-color: var(--t-line) !important;
}

body.app-body .workspace-landing__badge {
  background: var(--t-tint) !important;
  border-color: var(--t-tint-line) !important;
  color: var(--t-navy) !important;
}

/* The search field is described once, further down, with the rest of the top
   bar. Two more copies of it lived here and lost every declaration to it. */

body.app-body .topbar-utility {
  border: 0 !important;
  background: transparent !important;
  color: var(--t-muted) !important;
  border-radius: 10px !important;
}

body.app-body .topbar-utility:hover {
  background: var(--t-line-soft) !important;
  color: var(--t-navy) !important;
}

/* ── A select looks like a select ────────────────────────────────────────
 * app_theme.css, admin.css and settings.css each set `background-image: none`
 * on .form-select - settings.css for every standalone page - which removes
 * Bootstrap's chevron. Every dropdown on the profile, the CRM and the cabinet
 * administration therefore looked like a text field that happened to hold a
 * word, and nothing said it could be opened. One chevron, restored here.
 * ------------------------------------------------------------------------ */
body.app-body .form-select,
body.app-body .crm-field select,
body.app-body .crm-form > p select {
  appearance: none !important;
  -webkit-appearance: none !important;
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%2364748b' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.8' d='m3.5 6 4.5 4.5L12.5 6'/%3e%3c/svg%3e") !important;
  background-repeat: no-repeat !important;
  background-position: right 0.6rem center !important;
  background-size: 14px 14px !important;
  padding-right: 2rem !important;
}

/* A card's title does not need a rule under it; the space does that. */
body.app-body .dashboard-card__header,
body.app-body.empty-dashboard-mode[data-app-page="app"] .dashboard-card__header {
  border-bottom: 0 !important;
  padding-bottom: 0.25rem !important;
}

/* Unselected tabs are words; the selected one is the only filled pill. */
body.app-body .dashboard-activity__tab:not(.active),
body.app-body.empty-dashboard-mode[data-app-page="app"] .dashboard-activity__tab:not(.active) {
  border-color: transparent !important;
}

/* The list/calendar switch is a track, not an outlined box. */
body.app-body .task-views {
  border: 0 !important;
  background: var(--t-line-soft) !important;
}

body.app-body .task-add { border-top: 0 !important; }
body.app-body[data-app-page="app"] #sidebar #category-tree,
body.app-body[data-app-page="app"] #sidebar #category-tree .ux-tree {
  border: 0 !important;
  box-shadow: none !important;
  background: transparent !important;
  border-radius: 0 !important;
}
body.app-body[data-app-page="app"] #sidebar #category-tree .ux-tree { padding-left: 0 !important; padding-right: 0 !important; }
body.app-body[data-app-page="app"] #sidebar .label-text.selected {
  border-color: transparent !important;
  box-shadow: none !important;
}
body.app-body[data-app-page="app"] #sidebar .filter-card {
  border: 0 !important;
  box-shadow: none !important;
  background: transparent !important;
  padding-left: 0 !important;
  padding-right: 0 !important;
}
/* Results. The heading "Résultats pour …" was a floating outlined card of its
   own, and each result had an outline, a shadow and a cream fill left over
   from the palette before this one. The heading is a heading; a result is a
   white card on the tint, lifted, with no outline. */
body.app-body[data-app-page="app"] .search-results-head {
  border: 0 !important;
  box-shadow: none !important;
  background: transparent !important;
}
body.app-body[data-app-page="app"] .result-item {
  border-color: transparent !important;
  background: var(--t-surface) !important;
  box-shadow: 0 1px 2px rgba(11, 20, 51, 0.05), 0 6px 20px -12px rgba(11, 20, 51, 0.12) !important;
}
body.app-body[data-app-page="app"] .result-item:hover {
  box-shadow: 0 1px 2px rgba(11, 20, 51, 0.06), 0 10px 28px -12px rgba(11, 20, 51, 0.2) !important;
}
body.app-body[data-app-page="app"] .result-item__icon { border: 0 !important; }

body.app-body[data-app-page="app"] #sidebar .filter-card__icon {
  border: 0 !important;
  background: var(--t-tint) !important;
  color: var(--t-navy) !important;
}

/* ── Buttons ───────────────────────────────────────────────────────────── */
/* Flat, not a gradient. Several primary buttons still carried the old accent
   as a `linear-gradient`, which survives a `background-color` override because
   it is a different property - so the colour looked changed everywhere except
   on the buttons that matter most. */
body.app-body .btn-primary,
body.app-body .btn-dark,
body.app-body #home-new-folder,
body.app-body .dashboard-cta--primary {
  background: var(--t-navy) !important;
  background-image: none !important;
  border: 1px solid var(--t-navy) !important;
  color: #FFFFFF !important;
  border-radius: var(--t-radius-sm) !important;
  font-weight: 600;
  box-shadow: none !important;
}

body.app-body .btn-primary:hover,
body.app-body .btn-dark:hover {
  background: var(--t-navy-hover) !important;
  border-color: var(--t-navy-hover) !important;
}

body.app-body[data-app-page="app"] .btn-outline-secondary,
body.app-body[data-app-page="app"] .btn-light {
  background: var(--t-surface) !important;
  border: 1px solid var(--t-line) !important;
  color: var(--t-ink-soft) !important;
  border-radius: var(--t-radius-sm) !important;
  box-shadow: none !important;
}

/* ── Focus ─────────────────────────────────────────────────────────────── */
body.app-body :focus-visible { outline-color: var(--t-navy-hover) !important; }

/* ── The dashboard hero ────────────────────────────────────────────────────
 * Paper, with dark text on it - which is what the reference shows, and which
 * is also the only way this card is readable at all: the palette work turned
 * its background white and left the text white on it. Every colour it needs is
 * stated here rather than inherited from a dark-card vocabulary that no longer
 * describes it. */
body.app-body .dashboard-card--hero {
  background: linear-gradient(115deg, #FFFFFF 0%, #FBFAF7 46%, #E3EDFF 100%) !important;
  color: var(--t-ink) !important;
  border: 1px solid var(--t-line) !important;
}

body.app-body .dashboard-hero__title { color: var(--t-ink) !important; }

body.app-body .dashboard-hero__welcome {
  display: block;
  color: var(--t-faint) !important;
  font-size: 0.72rem !important;
  font-weight: 700 !important;
  letter-spacing: 0.13em;
  text-transform: uppercase;
}

/* The firm's name in the same face as the rest of the application. It was set
   in Source Serif, which reads as a different product from the sans-serif
   under it and beside it. */
body.app-body .dashboard-hero__title {
  font-family: inherit !important;
  font-size: clamp(2rem, 3.2vw, 2.9rem) !important;
  font-weight: 700 !important;
  letter-spacing: -0.015em;
  line-height: 1.1;
  margin: 0.35rem 0 0.6rem;
}

/* ── The three numbers ─────────────────────────────────────────────────────
 * Icon, then value over label: three readings rather than one row of digits.
 * Small, under the firm's name - they describe the space, the two actions
 * below are what the card is for. */
body.app-body .dashboard-stats {
  display: flex !important;
  align-items: center;
  gap: 0;
  margin-top: 1rem;
}

/* The order used to come from flex-direction: column-reverse, set four classes
   deep in dashboard_premium.css, because the label came first in the markup.
   The markup now says value then label, so the direction has to be unwound at
   the same specificity or the icon lands under the number. */
body.app-body.empty-dashboard-mode[data-app-page="app"] .dashboard-stat,
body.app-body .dashboard-stat {
  display: flex !important;
  flex-direction: row !important;
  align-items: center !important;
  gap: 0.55rem;
  padding: 0 1.4rem 0 0;
  margin: 0;
  border: 0 !important;
  background: transparent !important;
}

body.app-body.empty-dashboard-mode[data-app-page="app"] .dashboard-stat + .dashboard-stat,
body.app-body .dashboard-stat + .dashboard-stat {
  padding-left: 1.4rem;
  border-left: 0 !important;
}

body.app-body .dashboard-stat__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  border-radius: 8px;
  background: var(--t-tint);
  border: 0;
  color: var(--t-navy);
  font-size: 0.8rem;
}

body.app-body .dashboard-stat__body {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

body.app-body .dashboard-stat__value {
  color: var(--t-ink) !important;
  font-family: inherit !important;
  font-size: 1.05rem !important;
  font-weight: 700 !important;
  line-height: 1.2;
  white-space: nowrap;
}

body.app-body .dashboard-stat__label {
  color: var(--t-muted) !important;
  font-size: 0.76rem !important;
  font-weight: 500 !important;
  letter-spacing: 0 !important;
  text-transform: none !important;
  white-space: nowrap;
}

/* ══ ONE FRAME, NOT FOUR ══════════════════════════════════════════════════
 * Counting the boxes drawn between the screen edge and a filename: the tab
 * content had a border, a 16px radius and a shadow; inside it .doc-main had a
 * border, a 14px radius and a shadow; inside that the dropzone had a 2px
 * border and a white fill of its own; and the category panel had a twelfth
 * radius and a tint. Four rounded frames inside one another, each one eating a
 * little more of the room, which is why it read as cramped. The reference has
 * one: a white card on the page tint, and a hairline where the tree ends.
 */

/* The frame belongs to the pane that wants one, not to the box that holds
   every pane: the library is a single white card, and the dashboard is cards
   floating on the page tint with nothing drawn around them. Leaving the frame
   on .tab-content gave the dashboard an outer border, then a second white card
   inside it, then the tint again, and only then the hero. */
body.app-body[data-app-page="app"] .tab-content,
body.app-body[data-app-page="app"] #pane-global-search,
body.app-body[data-app-page="app"] #global-results-container,
body.app-body[data-app-page="app"] .empty-dashboard {
  background: transparent !important;
  background-image: none !important;
  border: 0 !important;
  border-radius: 0 !important;
  box-shadow: none !important;
}

body.app-body[data-app-page="app"] #global-results-container,
body.app-body[data-app-page="app"] #pane-global-search {
  padding: 0 !important;
}

body.app-body[data-app-page="app"] .empty-dashboard {
  padding: 0.35rem 0.5rem 1.5rem !important;
}

body.app-body .topbar-row .global-search {
  flex: 1 1 auto;
  min-width: 0;
  max-width: 46rem;
}

body.app-body .topbar-row .topbar-utilities {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 0.35rem;
  flex: 0 0 auto;
}

/* Le rappel d'essai d'un bac à sable, entre la recherche et les utilitaires
   (components/_topbar.html). Neutre : l'accent de l'écran reste à l'écran. */
body.app-body .topbar-row .topbar-sandbox {
  margin-left: auto;
  flex: 0 1 auto;
  min-width: 0;
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  height: 34px;
  padding: 0 0.35rem 0 0.8rem;
  border: 1px solid #DEDCD6;
  border-radius: 999px;
  background: #FFFFFF;
  color: #3B4860;
  font-size: 0.8rem;
  white-space: nowrap;
}
body.app-body .topbar-row .topbar-sandbox__dot {
  flex: 0 0 auto;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #00814F;
  box-shadow: 0 0 0 3px rgba(0, 129, 79, 0.14);
}
body.app-body .topbar-row .topbar-sandbox__text { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
body.app-body .topbar-row .topbar-sandbox__short { display: none; }
body.app-body .topbar-row .topbar-sandbox__tour {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  height: 26px;
  padding: 0 0.7rem;
  border-radius: 999px;
  background: #F7F6F2;
  color: var(--c-brand, #0B1F4D);
  font-weight: 600;
  text-decoration: none;
}
body.app-body .topbar-row .topbar-sandbox__tour:hover,
body.app-body .topbar-row .topbar-sandbox__tour:focus-visible { background: #E3EDFF; }
/* Le retour au compte d'où l'on est entré (sandbox_session.py) : la même
   pastille, pleine - c'est la sortie. */
body.app-body .topbar-row .topbar-sandbox__back { display: contents; }
body.app-body .topbar-row .topbar-sandbox__back button {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  height: 26px;
  padding: 0 0.7rem;
  border: 0;
  border-radius: 999px;
  background: var(--c-brand, #0B1F4D);
  color: #FFFFFF;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
body.app-body .topbar-row .topbar-sandbox__back button:hover,
body.app-body .topbar-row .topbar-sandbox__back button:focus-visible { background: #0B1433; }
/* Le rappel prend l'auto-marge : les utilitaires le suivent, collés. */
body.app-body[data-app-page="app"] .topbar-row .topbar-sandbox + .topbar-utilities,
body.app-body .topbar-row .topbar-sandbox + .topbar-utilities { margin-left: 0.5rem; }
@media (max-width: 1199.98px) {
  body.app-body .topbar-row .topbar-sandbox__tour span { display: none; }
  body.app-body .topbar-row .topbar-sandbox__tour { width: 26px; padding: 0; justify-content: center; }
}
@media (max-width: 991.98px) {
  body.app-body .topbar-row .topbar-sandbox__back span { display: none; }
  body.app-body .topbar-row .topbar-sandbox__back button { width: 26px; padding: 0; justify-content: center; }
}
@media (max-width: 767.98px) {
  body.app-body .topbar-row .topbar-sandbox { padding-left: 0.6rem; gap: 0.4rem; flex-shrink: 0; }
  body.app-body .topbar-row .topbar-sandbox__long { display: none; }
  body.app-body .topbar-row .topbar-sandbox__short { display: inline; }
}
/* Sur un téléphone, la barre n'a de place que pour la recherche : le rappel
   écrasait le champ à 123 px. La présentation se rejoue depuis l'accueil
   (dashboard-try__replay). */
@media (max-width: 575.98px) {
  body.app-body .topbar-row .topbar-sandbox { display: none; }
}

/* The field itself. Everything that makes it a pill - the room for the icon,
   the shortcut chip, the submit button - was written against the application,
   so on the other pages the magnifier sat on top of the placeholder. */
body.app-body .topbar-row .search-field {
  display: flex !important;
  position: relative;
  align-items: center;
  height: 44px;
}

/* This is the only place the field is described.
 *
 * It was described in three: twice above in this file and once in
 * workspace_premium.css, where its padding, its border, its background and its
 * hover were all inert - beaten by this block, which is later and
 * `!important`. Changing the one that was read was the only way to change the
 * field, and there was no way to tell which that was by reading the source.
 * The other two are gone.
 *
 * The magnifier is a 32px button at 0.45rem, so its box ends at 2.45rem. The
 * text starts after it with a gap that is chosen rather than left over: it was
 * one pixel, which is what the button's hover tint touched. */
body.app-body .topbar-row .search-field .form-control {
  height: 44px;
  padding: 0.35rem 3.4rem 0.35rem 2.9rem !important;
  background: var(--t-surface-soft) !important;
  border: 1px solid var(--t-line) !important;
  border-radius: 999px !important;
  color: var(--t-ink) !important;
  font-size: 0.94rem;
  box-shadow: none !important;
  transition: border-color 140ms ease-out, background-color 140ms ease-out,
    box-shadow 140ms ease-out;
}

body.app-body .topbar-row .search-field .form-control::placeholder {
  color: var(--t-faint);
}

body.app-body .topbar-row .search-field .form-control:hover {
  border-color: var(--t-tint-line) !important;
}

/* On the field, not on the input: the magnifier is the submit button and sits
   inside it, so reaching it by keyboard lights the same ring. */
body.app-body .topbar-row .search-field:focus-within .form-control {
  background: var(--t-surface) !important;
  border-color: var(--t-navy) !important;
  box-shadow: 0 0 0 3px rgba(11, 31, 77, 0.16) !important;
}

@media (prefers-reduced-motion: reduce) {
  body.app-body .topbar-row .search-field .form-control { transition: none; }
}

body.app-body .topbar-row .search-field .search-shortcut {
  position: absolute;
  right: 0.55rem;
  background: var(--t-surface) !important;
  border: 1px solid var(--t-line) !important;
  border-radius: 7px;
  padding: 0.14rem 0.4rem;
  color: var(--t-faint) !important;
  font-size: 0.7rem;
}

body.app-body .topbar-utility {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 9px;
  color: var(--t-ink-soft) !important;
  text-decoration: none;
}

body.app-body .topbar-utility:hover {
  background: var(--t-tint) !important;
  color: var(--t-navy) !important;
}

/* The page being read, when it is one of these - the trash (28 September). */
body.app-body .topbar-utility[aria-current="page"] {
  background: var(--t-tint) !important;
  color: var(--t-navy) !important;
}

/* The column lines up with the title above it. */
body.app-body[data-app-page="standalone"] .page-content > .container,
body.app-body[data-app-page="standalone"] .container {
  max-width: 68rem !important;
  margin-left: 0 !important;
  margin-right: 0 !important;
  padding-left: 0 !important;
  padding-right: 0 !important;
}

/* The panels were centred in a 860px column with auto margins while the title
   and the identity card above them started at the left edge, so nothing on the
   page lined up with anything else. */
body.app-body[data-app-page="standalone"] .account-content,
body.app-body[data-app-page="standalone"] .account-body {
  margin-left: 0 !important;
  margin-right: 0 !important;
  max-width: 68rem !important;
}

/* Cards, as everywhere else: white on the page tint, one hairline, no shadow
   and no second card inside the first. */
body.app-body[data-app-page="standalone"] .account-panel,
body.app-body[data-app-page="standalone"] .account-hero__card,
body.app-body[data-app-page="standalone"] .connector-card,
body.app-body[data-app-page="standalone"] .help-card,
body.app-body[data-app-page="standalone"] .card {
  background: var(--t-surface) !important;
  border: 1px solid var(--t-line) !important;
  border-radius: var(--t-radius) !important;
  box-shadow: none !important;
}

/* The two warm tiles left on the account page. */
body.app-body .account-hero__avatar,
body.app-body .account-panel__icon {
  background: var(--t-tint) !important;
  background-image: none !important;
  color: var(--t-navy) !important;
  border: 1px solid var(--t-tint-line) !important;
}

body.app-body[data-app-page="standalone"] .account-hero__title,
body.app-body[data-app-page="standalone"] .page-header h1,
body.app-body[data-app-page="standalone"] .page-title {
  font-family: inherit !important;
  color: var(--t-ink) !important;
}

body.app-body[data-app-page="standalone"] .account-hero__badge,
body.app-body[data-app-page="standalone"] .page-header__eyebrow {
  color: var(--t-faint) !important;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
}

body.app-body[data-app-page="standalone"] .account-hero__meta-item {
  background: var(--t-surface-soft) !important;
  border: 1px solid var(--t-line) !important;
  border-radius: 999px !important;
  color: var(--t-ink-soft) !important;
}

/* Bootstrap's own primary is #0d6efd, and it surfaces wherever a template
   reached for .text-primary or .bg-primary - three bright blue icons on the
   Assistance page, among others. There is one accent here and it is the navy
   from the mark. */
body.app-body .text-primary { color: var(--t-navy) !important; }
body.app-body .bg-primary { background-color: var(--t-navy) !important; }
body.app-body .border-primary { border-color: var(--t-navy) !important; }
body.app-body a.text-primary:hover { color: var(--t-navy-hover) !important; }

/* ══ DIALOGS ══════════════════════════════════════════════════════════════
 * The close button sat immediately after the title because the header's
 * justify-content had been left at normal, so a dialog read "Importer des
 * documents ✕" as if the cross were part of the sentence. It goes to the far
 * end, where a person reaches for it.
 */
body.app-body .modal-header {
  display: flex !important;
  align-items: center !important;
  justify-content: space-between !important;
  gap: 1rem;
  border-bottom: 1px solid var(--t-line) !important;
  background: var(--t-surface) !important;
}

body.app-body .modal-header .close,
body.app-body .modal-header .btn-close,
body.app-body .modal-header .inline-upload-close,
body.app-body .modal-header [data-dismiss="modal"],
body.app-body .modal-header [data-bs-dismiss="modal"] {
  margin-left: auto !important;
  flex: 0 0 auto;
}

body.app-body .modal-title {
  font-family: inherit !important;
  font-size: 1.12rem !important;
  font-weight: 650 !important;
  color: var(--t-ink) !important;
}

body.app-body .modal-content {
  background: var(--t-surface) !important;
  border: 1px solid var(--t-line) !important;
  border-radius: var(--t-radius) !important;
  box-shadow: 0 24px 60px -30px rgba(11, 20, 51, 0.45) !important;
}

body.app-body .modal-body,
body.app-body .modal-footer {
  background: var(--t-surface) !important;
}

body.app-body .modal-footer {
  border-top: 1px solid var(--t-line) !important;
}

/* The drop target answered a drag with #fbf5ec - the cream this palette
   dropped - and the anonymisation card was a yellow gradient. */
body.app-body .upload-dropzone {
  border: 1px dashed var(--t-line) !important;
  border-radius: var(--t-radius) !important;
  background: var(--t-surface-soft) !important;
  background-image: none !important;
}

body.app-body .upload-dropzone:hover,
body.app-body .upload-dropzone.bg-light {
  border-color: var(--t-tint-line) !important;
  background: var(--t-tint) !important;
  background-image: none !important;
}

body.app-body .anonymize-card {
  background: var(--t-surface-soft) !important;
  background-image: none !important;
  border: 1px solid var(--t-line) !important;
  border-radius: var(--t-radius) !important;
}

/* ══ ON A PHONE ═══════════════════════════════════════════════════════════
 * Six boxes nest between the screen edge and the dashboard - the content main,
 * the tab content, the pane, the results container, the page card and the card
 * itself - and each was written with a desktop's room to spare. On a 375px
 * screen they took 66px of it between them, an eighth of the screen on each
 * side, and drew three rounded borders inside one another on the way. A phone
 * gets one margin and no nested frames.
 */
@media (max-width: 767.98px) {

  body.app-body .empty-dashboard {
    padding: 1rem 0.85rem !important;
  }

  body.app-body .dashboard-card {
    padding: 1.1rem 1rem !important;
    border-radius: var(--t-radius) !important;
  }

  body.app-body .dashboard-grid {
    gap: 0.9rem !important;
  }
}

/* Three measurements side by side need about 700px. Under that they wrap, and
   a wrapped row cannot carry vertical dividers between its parts - the second
   line would start with one hanging off its left edge. On a phone the row ran
   730px wide inside a 375px card and the last two were simply clipped away. */
@media (max-width: 767.98px) {
  body.app-body .dashboard-stats {
    flex-wrap: wrap !important;
    gap: 0.9rem 1.4rem;
  }

  body.app-body.empty-dashboard-mode[data-app-page="app"] .dashboard-stat,
  body.app-body .dashboard-stat {
    padding: 0 !important;
  }

  body.app-body.empty-dashboard-mode[data-app-page="app"] .dashboard-stat + .dashboard-stat,
  body.app-body .dashboard-stat + .dashboard-stat {
    padding-left: 0;
    border-left: 0 !important;
  }

  body.app-body .dashboard-stat__value { white-space: normal; }
  body.app-body .dashboard-stat__label { white-space: normal; }
}

body.app-body .dashboard-logo--placeholder,
body.app-body .dashboard-logo--image {
  background: var(--t-navy) !important;
  color: #FFFFFF !important;
  border: 0 !important;
}

/* Buttons on paper are ordinary buttons: one filled, one outlined. On the dark
   card they were white rectangles, which on paper is nothing at all. */
body.app-body .dashboard-card--hero .btn {
  background: var(--t-surface) !important;
  border: 1px solid var(--t-line) !important;
  color: var(--t-ink) !important;
}

body.app-body .dashboard-card--hero .btn-primary,
body.app-body .dashboard-card--hero .dashboard-cta--primary {
  background: var(--t-navy) !important;
  border-color: var(--t-navy) !important;
  color: #FFFFFF !important;
}

/* The first-run block sat on the dark card and took its colours with it. */
body.app-body .dashboard-getting-started,
body.app-body .dashboard-getting-started * {
  color: var(--t-ink-soft) !important;
}

body.app-body .dashboard-getting-started__title,
body.app-body .dashboard-getting-started h3,
body.app-body .dashboard-getting-started strong { color: var(--t-ink) !important; }

/* Each step's icon in the same square: tinted while it waits, green once
   done. The waiting ones kept the dark card's translucent white, invisible
   on this one, and showed as bare glyphs beside the done step's green chip
   (25 September). */
body.app-body .dashboard-getting-started .dashboard-getting-started__check {
  background: var(--t-tint) !important;
  border: 1px solid var(--t-line) !important;
}
body.app-body .dashboard-getting-started .dashboard-getting-started__check i { color: var(--t-navy) !important; }
body.app-body .dashboard-getting-started .is-complete .dashboard-getting-started__check {
  background: #169F65 !important;
  border-color: transparent !important;
}
body.app-body .dashboard-getting-started .is-complete .dashboard-getting-started__check i { color: #FFFFFF !important; }

/* ── The second row ────────────────────────────────────────────────────────
 * Two cards: what you owe, and where you have been. Documents récents and
 * Accès rapides were both saying again what the rail and the list already say,
 * so the row is the to-do at three fifths and the history at two. */
@media (min-width: 992px) {
  body.app-body.empty-dashboard-mode[data-app-page="app"] .dashboard-card--tasks { grid-column: span 7 !important; }
  body.app-body.empty-dashboard-mode[data-app-page="app"] .dashboard-card--activity { grid-column: span 5 !important; }
}

/* ── One row shape for the history ─────────────────────────────────────────
 * The four tabs each had their own furniture, so switching tab changed the
 * shape of the card rather than its contents. One row: an icon for what the
 * thing is, its name, and a line saying what kind and when. */
body.app-body .activity-list {
  list-style: none;
  margin: 0.4rem 0 0;
  padding: 0;
}

body.app-body .activity-row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
  padding: 0.6rem 0.55rem !important;
  border: 0 !important;
  border-radius: var(--t-radius-sm) !important;
  background: transparent !important;
  text-align: left;
  /* A button centres or spreads its content: the title of a row with a short
     name sat at the right of the card, far from its icon. */
  justify-content: flex-start;
  cursor: pointer;
}

body.app-body .activity-row:hover {
  background: var(--t-tint) !important;
}

body.app-body .activity-row__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: var(--t-line-soft);
  color: var(--t-navy);
  font-size: 0.9rem;
}

body.app-body .activity-row__body {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-width: 0;
  text-align: left;
}

body.app-body .activity-row__title {
  color: var(--t-ink);
  font-weight: 600;
  font-size: 0.93rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

body.app-body .activity-row__meta {
  color: var(--t-muted);
  font-size: 0.81rem;
  line-height: 1.35;
}

/* ── The hero's banner ─────────────────────────────────────────────────────
 * The artwork from the brief: pale sheets over a colonnade, kept far enough
 * right and faint enough that it never competes with the words on top of it. */
body.app-body .dashboard-card--hero {
  position: relative;
  overflow: hidden;
  background-image:
    linear-gradient(100deg, #FFFFFF 0%, #FFFFFF 46%, rgba(255, 255, 255, 0.84) 62%, rgba(255, 255, 255, 0.58) 100%),
    url("../../img/hero-banner.png") !important;
  /* All three carry the flag. Without it dashboard_premium.css, which is four
     classes deep, kept its own position and size: the artwork was drawn at its
     natural size in the top-left corner, entirely under the white end of the
     gradient, which is why the card looked like a plain wash.
     The artwork is pinned to the top right and sized by height, so it stays a
     band in the corner. Sized to the card instead, it filled the right half of
     a tall card with a dark colonnade and swallowed the words over it. */
  background-position: 0 0, top right !important;
  background-size: 100% 100%, auto 62% !important;
  background-repeat: no-repeat !important;
}

/* Below this the artwork would sit under the text rather than beside it. */
@media (max-width: 900px) {
  body.app-body .dashboard-card--hero {
    background-image: linear-gradient(115deg, #FFFFFF 0%, #FBFAF7 100%) !important;
  }
}

/* ══ THE READER ═══════════════════════════════════════════════════════════
 * A legal research reader: a page in the middle, and a column beside it that
 * is the second half of the screen rather than a strip.
 */

body.app-body[data-app-page="app"] #pane-doc-read { background: var(--t-bg) !important; }

/* Every page stylesheet keeps its own name for the page colour - --v3-bg,
   --rev-bg, --nb-bg - and whichever loads last wins. The reader looked darker
   than the rest of the application because it was: #f1f2f3 rather than the
   token. They are pointed at one value here so the question cannot come up. */
body.app-body[data-app-page="app"] {
  --v3-bg: var(--t-bg);
  --rev-bg: var(--t-bg);
  --nb-bg: var(--t-bg);
  background: var(--t-bg) !important;
  background-image: none !important;
}

/* ============================================================
   Cabinet administration
   ------------------------------------------------------------
   This section hides the application's own rail and draws its
   own, which was still a slab of the navy the product left
   behind - so the one screen a firm's administrator lives in
   looked like a different product. Same rail, same hairline,
   same tinted active row as everywhere else.
   ============================================================ */
body.admin-page .admin-sidebar {
  background: var(--t-surface) !important;
  border: 1px solid var(--t-line) !important;
  border-radius: var(--t-radius) !important;
  box-shadow: none !important;
}

body.admin-page .admin-sidebar__eyebrow {
  color: var(--t-faint) !important;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
body.admin-page .admin-sidebar__hint { color: var(--t-muted) !important; }

/* The rail's group headings were white at a third opacity, for the navy slab
   this rail used to be. On white they were white on white: the CRM's four
   sections were there, taking their space, saying nothing. */
body.admin-page .admin-nav__group {
  color: var(--t-faint) !important;
}

body.admin-page .admin-nav .nav-link {
  display: flex;
  align-items: center;
  padding: 0.5rem 0.65rem !important;
  border-radius: var(--t-radius-sm) !important;
  color: var(--t-ink-soft) !important;
  font-size: 0.93rem;
  font-weight: 600;
  background: transparent !important;
}
body.admin-page .admin-nav .nav-link i { color: var(--t-faint) !important; width: 1.1rem; }
body.admin-page .admin-nav .nav-link:hover {
  background: rgba(11, 31, 77, 0.06) !important;
  color: var(--t-navy) !important;
}
body.admin-page .admin-nav .nav-link.active {
  background: var(--t-tint) !important;
  color: var(--t-navy) !important;
}
body.admin-page .admin-nav .nav-link.active i { color: var(--t-navy) !important; }

/* The page already carries its name in the header above it, and the
   screen then said "Cabinet - Administration" and "Administration du
   cabinet" underneath: the same words three times before any content. */
body.admin-page .admin-header { display: none !important; }

/* ── The administration overview ──────────────────────────────
   Eight identical bordered boxes down the middle of the page,
   each holding one number, told an administrator nothing about
   which of them mattered. They are three questions - what is in
   the base, what the plan allows, what people actually do - so
   they are grouped and labelled as three.
   ============================================================ */
body.admin-page .admin-overview { display: grid; gap: 2rem; max-width: 62rem; }

body.admin-page .admin-group__title {
  margin: 0 0 0.9rem;
  font-family: var(--t-sans, inherit);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--t-faint);
}

body.admin-page .admin-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 0;
  border: 1px solid var(--t-line);
  border-radius: var(--t-radius);
  background: var(--t-surface);
  overflow: hidden;
}

body.admin-page .admin-stat {
  padding: 1.05rem 1.25rem;
  border-left: 1px solid var(--t-line-soft);
}
body.admin-page .admin-stat:first-child { border-left: 0; }

body.admin-page .admin-stat__value {
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1.1;
  color: var(--t-ink);
  letter-spacing: -0.02em;
}
body.admin-page .admin-stat__unit {
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--t-muted);
}
body.admin-page .admin-stat__label {
  margin: 0.3rem 0 0;
  font-size: 0.82rem;
  color: var(--t-muted);
}

body.admin-page .admin-upgrade {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1rem;
  padding: 1.1rem 1.25rem;
  border: 1px solid var(--t-tint-line);
  border-radius: var(--t-radius);
  background: var(--t-tint);
}
body.admin-page .admin-upgrade p { margin: 0; font-size: 0.9rem; color: var(--t-ink-soft); }
body.admin-page .admin-upgrade strong { display: block; color: var(--t-ink); font-size: 0.98rem; }

@media (max-width: 720px) {
  body.admin-page .admin-stat { border-left: 0; border-top: 1px solid var(--t-line-soft); }
  body.admin-page .admin-stat:first-child { border-top: 0; }
}

/* ============================================================
   CRM
   ------------------------------------------------------------
   The staff side was left on plain Bootstrap while the product
   around it was rebuilt, so the one tool the team uses every
   day is the one that still looks like a scaffold. The tables
   and toolbars are the whole of it: rows with a hairline
   between them, a toolbar that is a row rather than a form,
   and the same navy for the one action that matters.
   ============================================================ */
body.admin-page .table {
  --bs-table-bg: transparent;
  margin-bottom: 0;
  color: var(--t-ink);
}

body.admin-page .table > thead th {
  padding: 0.55rem 0.75rem;
  border-bottom: 1px solid var(--t-line) !important;
  background: transparent;
  color: var(--t-faint);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
}

body.admin-page .table > tbody td {
  padding: 0.7rem 0.75rem;
  border-top: 1px solid var(--t-line-soft) !important;
  border-bottom: 0 !important;
  vertical-align: middle;
  font-size: 0.9rem;
}
body.admin-page .table > tbody tr:first-child td { border-top: 0 !important; }

body.admin-page .table-hover > tbody > tr:hover > * {
  background-color: var(--t-surface-soft) !important;
  --bs-table-accent-bg: transparent;
}

/* The table itself is the card. A bordered box around a bordered
   table is the doubling this product spent a week removing. */
body.admin-page .crm-table-wrap {
  border: 1px solid var(--t-line);
  border-radius: var(--t-radius);
  background: var(--t-surface);
  /* Clips to the rounded corners like hidden did, and scrolls a table wider
     than a phone instead of cutting its last columns off. */
  overflow-x: auto;
}

body.admin-page .btn-primary {
  background: var(--t-navy) !important;
  border-color: var(--t-navy) !important;
  color: #FFFFFF !important;
  box-shadow: none !important;
}
body.admin-page .btn-primary:hover {
  background: var(--t-navy-hover) !important;
  border-color: var(--t-navy-hover) !important;
}

body.admin-page .btn-secondary,
body.admin-page .btn-outline-info,
body.admin-page .btn-outline-secondary {
  background: var(--t-surface) !important;
  border-color: var(--t-line) !important;
  color: var(--t-ink-soft) !important;
  box-shadow: none !important;
}
body.admin-page .btn-secondary:hover,
body.admin-page .btn-outline-info:hover,
body.admin-page .btn-outline-secondary:hover {
  background: var(--t-tint) !important;
  border-color: var(--t-tint-line) !important;
  color: var(--t-navy) !important;
}

/* A row of numbers with their names under them. */
body.admin-page .crm-metrics {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.75rem;
  margin: 0;
}
body.admin-page .crm-metrics > div { min-width: 0; }
body.admin-page .crm-metrics dt {
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--t-ink);
  line-height: 1.2;
}
body.admin-page .crm-metrics dd {
  margin: 0.1rem 0 0;
  font-size: 0.78rem;
  color: var(--t-muted);
  white-space: nowrap;
}
/* The same row, as the panel Facturation opens on. */
body.admin-page .crm-metrics.crm-metrics--panel {
  margin: 0 0 1rem;
  padding: 1rem 1.1rem;
  border: 1px solid var(--t-line);
  border-radius: var(--t-radius);
  background: var(--t-surface);
}

/* A chart's box, with a height that does not come from the chart.
   See the comment in crm/dashboard.html: without this the canvas
   and its parent grew each other on every resize, and the page
   passed twenty thousand pixels. position:relative is what
   Chart.js measures against. */
body.admin-page .crm-chart {
  position: relative;
  height: 15rem;
  margin: 0 0 1.5rem;
}

/* ── One frame for every CRM page ─────────────────────────────
   Cabinets put its action top right, Offres put the same kind
   of action underneath the title, and each screen picked its
   own heading size. Two pages of the same kind read as two
   tools. crm-head is that frame, and it is the only place a
   CRM page is allowed to name itself.
   ============================================================ */
body.admin-page .crm-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin: 0 0 1.25rem;
  padding-bottom: 0.9rem;
  border-bottom: 1px solid var(--t-line);
}

body.admin-page .crm-head__text { min-width: 0; }

/* The heading was set in Source Serif, which this product already
   decided reads as a different application from the sans under it
   and beside it - see .dashboard-hero__title. The CRM was the last
   place still doing it. Redefining the variable admin.css reaches
   for kills every serif in here at once rather than chasing each
   selector. */
body.admin-page { --crm-display: inherit; }

body.admin-page .crm-head__title {
  margin: 0;
  font-family: inherit;
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--t-ink);
  line-height: 1.2;
}

body.admin-page .crm-head__subtitle {
  margin: 0.3rem 0 0;
  font-size: 0.9rem;
  color: var(--t-ink-soft);
  max-width: 62ch;
}

body.admin-page .crm-head__actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-shrink: 0;
  /* A prospect has four; on a phone they went 140px past the screen's edge. */
  flex-wrap: wrap;
  max-width: 100%;
}
body.admin-page .crm-head__actions:empty { display: none; }

/* A filter is a toolbar, not a form that wants the page. The search
   field on Cabinets ran the full thousand pixels to filter a column
   of firm names. */
body.admin-page .crm-toolbar {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin: 0 0 1rem;
}
body.admin-page .crm-toolbar .form-control { max-width: 22rem; }
/* A select is as wide as the longest thing in it. The country filter held
   two-letter codes and ran to 350px. */
body.admin-page .crm-toolbar .form-select { width: auto; min-width: 8rem; }

/* Row actions. Bordered boxes on every row are the doubling the
   documents list removed in September; here the words stay - this
   is a tool used rarely, where an unlabelled icon is a guess - but
   they are quiet until the row is under the pointer. */
body.admin-page .table .crm-row-actions {
  display: flex;
  gap: 0.25rem;
  justify-content: flex-end;
  white-space: nowrap;
}
body.admin-page .table .crm-row-actions .btn {
  background: transparent !important;
  border-color: transparent !important;
  color: var(--t-muted) !important;
  padding: 0.2rem 0.55rem;
  font-size: 0.82rem;
  box-shadow: none !important;
}
body.admin-page .table tr:hover .crm-row-actions .btn,
body.admin-page .table .crm-row-actions .btn:focus-visible {
  color: var(--t-ink-soft) !important;
}
body.admin-page .table .crm-row-actions .btn:hover,
body.admin-page .table .crm-row-actions .btn:focus-visible {
  background: var(--t-tint) !important;
  border-color: var(--t-tint-line) !important;
  color: var(--t-navy) !important;
}
body.admin-page .table .crm-row-actions form { display: inline-flex; margin: 0; }

/* Le reste des actions, ouvert à la demande.
 *
 * Une ligne de bac à sable portait neuf contrôles et le tableau débordait en
 * largeur : « Supprimer » était hors de l'écran et le choix de scénario
 * écrasé à quarante pixels. Deux contrôles restent sur la ligne, le reste
 * s'ouvre en panneau - ce qui met aussi le destructif derrière un geste
 * (23 septembre). */
body.admin-page .table .crm-row-more { position: relative; display: inline-block; }
body.admin-page .table .crm-row-more > summary {
  list-style: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
}
body.admin-page .table .crm-row-more > summary::-webkit-details-marker { display: none; }
body.admin-page .table .crm-row-more[open] > summary {
  background: var(--t-tint) !important;
  border-color: var(--t-tint-line) !important;
  color: var(--t-navy) !important;
}
body.admin-page .table .crm-row-more__panel {
  position: absolute;
  right: 0;
  z-index: 20;
  min-width: 24rem;
  margin-top: 0.3rem;
  padding: 0.5rem;
  border: 1px solid var(--t-line-soft);
  border-radius: 0.6rem;
  background: #FFFFFF;
  box-shadow: 0 10px 28px rgba(11, 20, 51, 0.14);
  text-align: left;
  white-space: normal;
}
/* Une action par ligne : `.crm-row-actions form` les met en inline-flex pour
 * la ligne du tableau, ce qui collait ici « Renvoyer » et « Supprimer » côte
 * à côte, et le trait qui met le destructif à part ne se voyait plus. */
body.admin-page .table .crm-row-actions .crm-row-more__line {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.25rem 0.1rem;
}
body.admin-page .table .crm-row-more__line label {
  flex: 0 0 auto;
  font-size: 0.78rem;
  color: var(--t-faint);
}
body.admin-page .table .crm-row-more__line .form-select {
  flex: 1 1 auto;
  min-width: 7rem;
  width: auto;
}
body.admin-page .table .crm-row-more__line--danger {
  margin-top: 0.3rem;
  padding-top: 0.45rem;
  border-top: 1px solid var(--t-line-soft);
}

/* Several buttons that are one choice with a number in it. Without this they
   read as three unrelated actions; the label says once what all three do. */
body.admin-page .table .crm-row-actions__group {
  display: inline-flex;
  align-items: center;
  gap: 0.1rem;
  padding: 0 0.15rem;
  border-left: 1px solid var(--t-line-soft);
  border-right: 1px solid var(--t-line-soft);
}
body.admin-page .table .crm-row-actions__label {
  font-size: 0.72rem;
  color: var(--t-faint);
  padding: 0 0.3rem 0 0.45rem;
  white-space: nowrap;
}

/* Destruction still reads as destruction. Quiet at rest like its neighbours,
   red the moment it is aimed at. */
body.admin-page .table .crm-row-actions .btn-outline-danger:hover,
body.admin-page .table .crm-row-actions .btn-outline-danger:focus-visible {
  background: #F7F6F2 !important;
  border-color: #FFC4BB !important;
  color: #C32324 !important;
}

body.admin-page .crm-toolbar__label {
  font-size: 0.82rem;
  color: var(--t-ink-soft);
  margin: 0;
}

/* A count under a list is a footnote, not a card footer. */
body.admin-page .crm-count {
  margin: 0.6rem 0 0;
  font-size: 0.8rem;
  color: var(--t-faint);
}

/* A feed URL is long and identifying at its start. Letting it push the row
   wide moved the actions off the right of a narrow window. */
body.admin-page .crm-cell-url {
  max-width: 18rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The line under a failing feed. table-warning painted the whole row amber,
   which said "warning" about the feed rather than "here is what went wrong". */
body.admin-page .table > tbody tr.crm-row-error td {
  border-top: 0 !important;
  padding-top: 0;
  color: #C32324;
}

/* Status pills. Bootstrap's own are fully saturated - #dc3545 beside #198754 -
   and on a page of hairlines and slate they were the loudest thing on screen,
   shouting about a feed's HTTP status. A tinted pill with dark text says the
   same thing at the volume the rest of the page speaks at. */
body.admin-page .table .badge.text-bg-success {
  background: #D3F5E0 !important;
  color: #00814F !important;
}
body.admin-page .table .badge.text-bg-danger {
  background: #F7F6F2 !important;
  color: #C32324 !important;
}
body.admin-page .table .badge.text-bg-warning {
  background: #FFF8E6 !important;
  color: #B08505 !important;
}
body.admin-page .table .badge.text-bg-secondary,
body.admin-page .table .badge.text-bg-light {
  background: var(--t-surface-soft) !important;
  color: var(--t-ink-soft) !important;
  border: 1px solid var(--t-line);
}
body.admin-page .table .badge {
  font-weight: 600;
  font-size: 0.72rem;
  padding: 0.28em 0.6em;
}

/* ── CRM forms ────────────────────────────────────────────────
   Every one of these rendered as {{ form.as_p }}: labels ending
   in a colon, inputs each as wide as their widget felt like,
   help text running into the next field, and no grouping at
   all. The plan editor came out as thirty-six undifferentiated
   rows across the full width of a 1440px screen.
   ============================================================ */
body.admin-page .crm-form { max-width: 46rem; }

body.admin-page .crm-fieldset { margin: 0 0 1.75rem; }

body.admin-page .crm-fieldset__title {
  margin: 0 0 0.75rem;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--t-faint);
  padding-bottom: 0.45rem;
  border-bottom: 1px solid var(--t-line-soft);
}

body.admin-page .crm-fieldset__fields { display: grid; gap: 1rem; }
/* A long form two fields to a row: « Code postal » does not need the width of
   an address, and one field per row made the firm's page 2,500px tall. The
   form names the fields that keep the whole row (CrmFieldsetsMixin.WIDE). */
body.admin-page .crm-form--columns .crm-fieldset__fields { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem 1.25rem; }
body.admin-page .crm-form--columns .crm-field--wide { grid-column: 1 / -1; }
/* Paired fields fill their column, so a field alone on its row does too:
   otherwise it stops at 24rem under two that reach the edge. */
body.admin-page .crm-form--columns .crm-field input:not([type="checkbox"]):not([type="file"]),
body.admin-page .crm-form--columns .crm-field select { max-width: none; }
@media (max-width: 560px) {
  body.admin-page .crm-form--columns .crm-fieldset__fields { grid-template-columns: minmax(0, 1fr); }
}

body.admin-page .crm-field > label {
  display: block;
  margin: 0 0 0.3rem;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--t-ink);
}

body.admin-page .crm-field input[type="text"],
body.admin-page .crm-field input[type="number"],
body.admin-page .crm-field input[type="email"],
body.admin-page .crm-field input[type="url"],
body.admin-page .crm-field input[type="tel"],
body.admin-page .crm-field input[type="date"],
body.admin-page .crm-field input[type="datetime-local"],
body.admin-page .crm-field select,
body.admin-page .crm-field textarea {
  width: 100%;
  max-width: 24rem;
  padding: 0.4rem 0.6rem;
  border: 1px solid var(--t-line);
  border-radius: var(--t-radius-sm);
  background: var(--t-surface);
  color: var(--t-ink);
  font-size: 0.9rem;
  font-family: inherit;
}
body.admin-page .crm-field textarea { max-width: 100%; min-height: 6rem; }
body.admin-page .crm-field input:focus,
body.admin-page .crm-field select:focus,
body.admin-page .crm-field textarea:focus {
  outline: none;
  border-color: var(--t-navy);
  box-shadow: 0 0 0 3px var(--t-tint);
}

/* A checkbox belongs beside its label, not under it with a colon
   between them. */
body.admin-page .crm-field--switch {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: start;
  gap: 0 0.55rem;
}
body.admin-page .crm-field--switch > label { order: 2; margin: 0; font-weight: 500; }
body.admin-page .crm-field--switch > input[type="checkbox"] {
  order: 1;
  margin-top: 0.2rem;
  width: 1rem;
  height: 1rem;
  accent-color: var(--t-navy);
}
body.admin-page .crm-field--switch .crm-field__help { grid-column: 2; order: 3; }

body.admin-page .crm-field__help {
  margin: 0.25rem 0 0;
  font-size: 0.8rem;
  color: var(--t-muted);
}
body.admin-page .crm-field__error {
  margin: 0.25rem 0 0;
  font-size: 0.8rem;
  color: #C32324;
}

/* The forms that still render as {{ form.as_p }}. Only the plan editor has
   enough fields to be worth grouping by hand; the rest are five or six, and a
   paragraph per field is a perfectly good shape once it is given the same
   label, input and help-text treatment as a crm-field. */
body.admin-page .crm-form > p {
  margin: 0 0 1rem;
}
body.admin-page .crm-form > p > label {
  display: block;
  margin: 0 0 0.3rem;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--t-ink);
}
body.admin-page .crm-form > p input[type="text"],
body.admin-page .crm-form > p input[type="number"],
body.admin-page .crm-form > p input[type="email"],
body.admin-page .crm-form > p input[type="url"],
body.admin-page .crm-form > p input[type="datetime-local"],
body.admin-page .crm-form > p input[type="date"],
body.admin-page .crm-form > p select,
body.admin-page .crm-form > p textarea {
  width: 100%;
  max-width: 24rem;
  padding: 0.4rem 0.6rem;
  border: 1px solid var(--t-line);
  border-radius: var(--t-radius-sm);
  background: var(--t-surface);
  color: var(--t-ink);
  font-size: 0.9rem;
  font-family: inherit;
}
body.admin-page .crm-form > p textarea { max-width: 100%; min-height: 8rem; }
body.admin-page .crm-form > p input[type="checkbox"] {
  width: 1rem;
  height: 1rem;
  accent-color: var(--t-navy);
  vertical-align: -0.15em;
}
body.admin-page .crm-form > p input:focus,
body.admin-page .crm-form > p select:focus,
body.admin-page .crm-form > p textarea:focus {
  outline: none;
  border-color: var(--t-navy);
  box-shadow: 0 0 0 3px var(--t-tint);
}
/* A checkbox belongs beside what it is called, not under it. as_p emits the
   label first and the box after, so the order is swapped here rather than in
   seven templates. */
body.admin-page .crm-form > p:has(> input[type="checkbox"]) {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}
body.admin-page .crm-form > p:has(> input[type="checkbox"]) > label {
  order: 2;
  margin: 0;
  font-weight: 500;
}
body.admin-page .crm-form > p:has(> input[type="checkbox"]) > input[type="checkbox"] {
  order: 1;
  margin: 0;
}
body.admin-page .crm-form > p:has(> input[type="checkbox"]) > .helptext {
  order: 3;
  flex-basis: 100%;
  margin: 0.15rem 0 0 1.5rem;
}

body.admin-page .crm-form > p .helptext {
  display: block;
  margin-top: 0.25rem;
  font-size: 0.8rem;
  color: var(--t-muted);
}
body.admin-page .crm-form ul.errorlist {
  list-style: none;
  padding: 0;
  margin: 0 0 0.3rem;
  font-size: 0.8rem;
  color: #C32324;
}

body.admin-page .crm-field input[type="file"] { font-size: 0.88rem; }

body.admin-page .crm-import-report {
  margin: 1.25rem 0 0;
  padding: 0.8rem 1rem 0.8rem 2rem;
  border: 1px solid var(--t-line);
  border-radius: var(--t-radius);
  background: var(--t-surface-soft);
  font-size: 0.88rem;
  color: var(--t-ink-soft);
}

body.admin-page .crm-reserved {
  border: 1px solid var(--t-line);
  border-radius: var(--t-radius);
  background: var(--t-surface-soft);
  padding: 0.7rem 0.9rem;
  margin: 0 0 1.5rem;
}
body.admin-page .crm-reserved > summary {
  cursor: pointer;
  font-size: 0.85rem;
  color: var(--t-muted);
}
body.admin-page .crm-reserved__fields {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
  gap: 0.4rem;
  margin-top: 0.8rem;
}
body.admin-page .crm-reserved__item {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.82rem;
  color: var(--t-muted);
  margin: 0;
}

body.admin-page .crm-form__actions {
  display: flex;
  gap: 0.5rem;
  padding-top: 1rem;
  border-top: 1px solid var(--t-line);
}

/* An empty list is a thing to say, not a table row saying "Aucun". */
body.admin-page .crm-empty {
  border: 1px dashed var(--t-line);
  border-radius: var(--t-radius);
  background: var(--t-surface-soft);
  padding: 2.25rem 1.5rem;
  text-align: center;
  color: var(--t-muted);
  font-size: 0.92rem;
}
body.admin-page .crm-empty strong {
  display: block;
  color: var(--t-ink);
  font-size: 1rem;
  font-weight: 600;
  margin-bottom: 0.2rem;
}

body.admin-page .form-control,
body.admin-page .form-select {
  border-color: var(--t-line);
  border-radius: var(--t-radius-sm);
  font-size: 0.9rem;
}
body.admin-page .form-control:focus,
body.admin-page .form-select:focus {
  border-color: var(--t-tint-line);
  box-shadow: 0 0 0 3px rgba(11, 31, 77, 0.08);
}

body.admin-page .card {
  border: 1px solid var(--t-line) !important;
  border-radius: var(--t-radius) !important;
  box-shadow: none !important;
  background: var(--t-surface) !important;
}

/* Bootstrap's badges are a saturated palette from another product.
   Here they label a state, quietly. */
body.admin-page .badge {
  padding: 0.28rem 0.55rem;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 650;
  letter-spacing: 0.01em;
}
body.admin-page .badge.text-bg-info,
body.admin-page .badge.text-bg-primary {
  background: var(--t-tint) !important;
  color: var(--t-navy) !important;
}
body.admin-page .badge.text-bg-secondary {
  background: var(--t-surface-soft) !important;
  color: var(--t-muted) !important;
  border: 1px solid var(--t-line);
}

body.app-body[data-app-page="app"] .page-item.active .page-link {
  background: var(--t-navy) !important;
  border-color: var(--t-navy) !important;
  color: #FFFFFF !important;
}
body.app-body[data-app-page="app"] .page-item .page-link {
  border-color: var(--t-line) !important;
  color: var(--t-ink-soft) !important;
}
body.app-body[data-app-page="app"] .page-item .page-link:hover,
body.app-body[data-app-page="app"] .page-item .page-link:focus {
  background: var(--t-tint) !important;
  border-color: var(--t-tint-line) !important;
  color: var(--t-navy) !important;
}
