/*
colorbackbody=247,248,250
colorbackvmenu1=255,255,255
colorbackhmenu1=255,255,255
colorbacktitle1=241,244,248
colorbacklineimpair1=255,255,255
colorbacklineimpair2=255,255,255
colorbacklinepair1=255,255,255
colorbacklinepair2=255,255,255
colorbacklinepairhover=241,244,248
colorbacklinepairchecked=238,240,254
$colortexttitlenotab=11,18,32
$colortexttitle=91,107,130
$colortext=0,0,0
$colortextlink=67,56,202
$colortextbackhmenu=000000
$colortextbackvmenu=222222
dol_hide_topmenu=
dol_hide_leftmenu=
dol_optimize_smallscreen=
dol_no_mouse_hover=
dol_screenwidth=
dol_screenheight=
fontsize=0.9375rem
nbtopmenuentries=4
fontsizesmaller=0.75em
topMenuFontSize=0.6875rem
toolTipBgColor=rgba(255, 255, 255, 0.96)
toolTipFontColor=#333
getDolGlobalString("THEME_SATURATE_RATIO")= (must be between 0 and 1)
*/

/* ==========================================================================
   COMMAND -- tokens
   ========================================================================== */

:root {
	color-scheme: light;

	/* Neutrals: a cool slate ramp. */
	--c-ink: #0B1220;
	--c-ink-2: #263244;
	/* The quiet weight a data-table header is written against. It was named by
	   that rule and never defined, so the declaration was dropped and headers
	   fell back to full ink -- the loudest thing in the table. */
	--c-ink-subtle: #5B6B82;
	--c-muted: #5B6B82;
	--c-faint: #8C9AAE;
	--c-hairline: #EEF0F3;
	--c-border: #E7E9EE;
	--c-border-strong: #C9D2DE;
	--c-surface: #FFFFFF;
	--c-canvas: #F7F8FA;
	--c-sunken: #F1F4F8;

	/* One accent. Indigo reads as "tool", not "brochure". */
	--c-accent: #4F46E5;
	--c-accent-hover: #4338CA;
	--c-accent-ink: #4338CA;
	--c-accent-soft: #EEF0FE;

	/* Display > Skin and colors lets an administrator set the action button
	   colour. Dolibarr resolves that setting into $butactionbg before this file
	   is included, but the theme was painting its buttons from the accent above,
	   so changing the setting did nothing at all. Take the resolved values, which
	   already fall back to the theme's own defaults when nothing is configured. */
	--c-btn-action: rgb(79,70,229);
	--c-btn-action-text: rgb(255,255,255);
	/* Filled actions follow Dolibarr's Skin and colors settings.  Keep their
	   focus/shadow tint derived from that same configured color too, so a
	   custom action color never leaves an unrelated indigo halo behind. */
	--c-btn-action-ring: color-mix(in srgb, var(--c-btn-action) 24%, transparent);
	--c-accent-ring: rgba(79, 70, 229, 0.22);

	--c-success: #0F7B4F;
	--c-warning: #96610A;
	--c-danger: #B3261E;
	--c-info: #2B5C8A;

	/* Eldy's compact, neutral sans-serif character, expressed through one
	   deterministic stack. Liberation Sans is metrically compatible with Arial
	   on the Linux-hosted browser and the remaining faces provide the same
	   crisp fallback elsewhere. Respect THEME_FONT_FAMILY when configured. */
	--c-font: "Liberation Sans", Arial, Tahoma, Verdana, Helvetica, sans-serif;
	--c-mono: "SF Mono", "JetBrains Mono", "Cascadia Mono", Menlo, Consolas, monospace;

	--sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px;
	--sp-5: 24px; --sp-6: 32px; --sp-7: 48px; --sp-8: 64px;

	--r-sm: 6px; --r: 8px; --r-lg: 12px; --r-xl: 16px; --r-pill: 999px;

	--sh-sm: 0 1px 2px rgba(11, 18, 32, 0.035);
	--sh: 0 1px 2px rgba(11, 18, 32, 0.035), 0 5px 14px -5px rgba(11, 18, 32, 0.07);
	--sh-md: 0 2px 4px rgba(11, 18, 32, 0.04), 0 12px 24px -6px rgba(11, 18, 32, 0.09);
	--sh-lg: 0 24px 64px -12px rgba(11, 18, 32, 0.28), 0 4px 12px rgba(11, 18, 32, 0.08);

	--bar-h: 60px;
	--control-h: 40px;
	--table-row-h: 50px;
	--t: 120ms cubic-bezier(0.4, 0, 0.2, 1);

	/* Dolibarr's documented variable contract -- core and third-party module
	   CSS reference these names, so all of them stay defined. */
	--colorbackbody: var(--c-canvas);
	--colorbackhmenu1: var(--c-surface);
	--colorbackvmenu1: var(--c-surface);
	--colorbacktitle1: var(--c-sunken);
	--colorbacktabcard1: var(--c-surface);
	--colorbacktabactive: var(--c-accent-soft);
	--colorbacklineimpair1: var(--c-surface);
	--colorbacklineimpair2: var(--c-surface);
	--colorbacklinepair1: var(--c-surface);
	--colorbacklinepair2: var(--c-surface);
	--colorbacklinepairhover: var(--c-sunken);
	--colorbacklinepairchecked: var(--c-accent-soft);
	--colorbacklinebreak: var(--c-sunken);
	--colorbackgrey: var(--c-sunken);
	--colorbackmobilemenu: var(--c-surface);
	--colortopbordertitle1: var(--c-accent);
	--colortext: var(--c-ink);
	--colortextlink: var(--c-accent-ink);
	--colortexttitle: var(--c-ink);
	--colortexttitlelink: var(--c-accent-ink);
	--colortexttitlenotab: var(--c-ink);
	--colortexttitlenotab2: var(--c-accent-ink);
	--colortextbackhmenu: var(--c-ink);
	--colortextbackvmenu: var(--c-ink);
	--colortextbacktab: var(--c-ink);
	--colorwhite: #ffffff;
	--colorblack: var(--c-ink);
	--inputbackgroundcolor: var(--c-surface);
	--inputbackgroundcolordisabled: var(--c-sunken);
	--inputbordercolor: var(--c-border);
	--inputcolordisabled: var(--c-faint);
	--fieldrequiredcolor: var(--c-ink);
	--tableforfieldcolor: var(--c-muted);
	--tablevalidbgcolor: var(--c-accent-soft);
	--oddevencolor: var(--c-ink);
	--listetotal: var(--c-accent-ink);
	--tooltipbgcolor: rgba(255, 255, 255, 0.96);
	--tooltipfontcolor: #333;
	--refidnocolor: var(--c-muted);
	--colorboxiconbg: var(--c-sunken);
	--colorboxstatsborder: var(--c-border);
	--infoboxmoduleenabledbgcolor: var(--c-accent-soft);
	--dolgraphbg: var(--c-surface);
	--heightrow: 155%;
	--amountremaintopaycolor: var(--c-danger);
	--amountremaintopaybackcolor: transparent;
	--amountpaymentcomplete: var(--c-success);
	--productlinestockod: var(--c-success);
	--productlinestocktoolow: var(--c-danger);
	--colortextlink-h: 244; --colortextlink-s: 75%; --colortextlink-l: 51%; --colortextlink-a: 1;
}



/* ==========================================================================
   Base
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

body {
	margin: 0;
	background: var(--c-canvas);
	color: var(--c-ink);
	font-family: var(--c-font);
	font-size: 0.9375rem;
	line-height: 1.5;
	font-kerning: normal;
	text-rendering: optimizeLegibility;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}

/* Dolibarr and installed modules still assign their own font stacks to labels,
   controls and tables, sometimes with !important and after the theme sheet.
   The mainbody id gives COMMAND's global typography contract enough
   specificity to remain authoritative without adding module-specific rules.
   Icon and code faces remain explicit exceptions at the same specificity. */
body#mainbody :where(*) { font-family: var(--c-font) !important; }
body#mainbody :where(.fa, .fas, .far, .fab, [class*="fa-"], .icon, [class^="icon-"]) {
	font-family: "Font Awesome 5 Free", "Font Awesome 6 Free", FontAwesome !important;
}
body#mainbody :where(.fab, .fa-brands) { font-family: "Font Awesome 5 Brands" !important; }
body#mainbody :where(code, pre, kbd) { font-family: var(--c-mono) !important; }

/* Figures align in columns -- the highest-value typographic choice in an ERP. */
td, th, input, .amount, .refid, .badge, .cmd-kbd { font-variant-numeric: tabular-nums; }

a { color: var(--colortextlink); text-decoration: none; transition: color var(--t); }
a:hover { color: var(--c-accent-hover); }
a.nounderline, a.nounderline:hover { text-decoration: none !important; }

:focus-visible { outline: 2px solid var(--c-accent); outline-offset: 1px; border-radius: var(--r-sm); }

h1, h2, h3, h4 {
	margin: 0 0 var(--sp-3) 0;
	font-weight: 620;
	line-height: 1.18;
	letter-spacing: -0.022em;
	color: var(--c-ink);
}
h1 { font-size: 1.75rem; } h2 { font-size: 1.375rem; }
h3 { font-size: 1.125rem; } h4 { font-size: 1rem; }
p { margin: 0 0 var(--sp-3) 0; }
/* Spacing between paragraphs, not after the last one. A trailing margin inside
   a box that is sized to its content pushes that content off centre -- the
   login message sat 12px high in its own plate for exactly this reason -- and
   it is never what the last paragraph in a container wants. */
p:last-child { margin-bottom: 0; }
hr { border: 0; border-top: 1px solid var(--c-hairline); margin: var(--sp-4) 0; }
img { border: 0; vertical-align: middle; }
code, pre, kbd { font-family: var(--c-mono); font-size: 0.9em; }
::placeholder { color: var(--c-faint); opacity: 1; }
::selection { background: var(--c-accent-soft); color: var(--c-accent-ink); }

* { scrollbar-width: thin; scrollbar-color: var(--c-border-strong) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { background: var(--c-border-strong); border-radius: var(--r-pill); border: 2px solid var(--c-canvas); }





/* ==========================================================================
   Utilities
   Dolibarr's PHP emits these class names and depends on them for layout, not
   decoration, so they are behavioural and reimplemented in meaning.
   ========================================================================== */

/* Deliberately NOT !important. Dolibarr ships every popup's host element as
   <div id="idfordialog..." class="hidden"> (functions.lib.php) and jQuery UI reveals
   it by writing an inline display:block. An !important declaration outranks that
   inline style, so the host stayed collapsed and the dialog opened as a bare title
   bar with no content -- the virtual business card URL and every other dialog built
   on the same pattern. Plain `display: none` still hides it until JS says otherwise. */
.hidden, .hideobject { display: none; }
.clearboth { clear: both; }
.nowrap, .nowraponall { white-space: nowrap !important; }
.wrapimp { white-space: normal !important; }
.wordbreak { word-break: break-all; }
.center { text-align: center !important; }
.left { text-align: left !important; }
.right { text-align: right !important; }
.floatleft, .float { float: left; }
.floatright { float: right; }
.floatnone { float: none; }
.inline-block { display: inline-block; }
.inline-blockimp { display: inline-block !important; }
.block { display: block; }
.valignmiddle { vertical-align: middle; }
.valigntop { vertical-align: top; }
.valignbottom { vertical-align: bottom; }
.bold, .strong { font-weight: 600 !important; }
.nobold { font-weight: 400 !important; }
.italic { font-style: italic; }
.uppercase { text-transform: uppercase; }
.small, .smallfont { font-size: 0.75em; }
.opacitymedium { opacity: 0.62; }
.opacitymediumbycolor { color: var(--c-muted); }
.opacityhigh { opacity: 0.4; }
.opacitylow { opacity: 0.8; }
.cursorpointer { cursor: pointer; }
.cursormove { cursor: move; }
.cursornotallowed { cursor: not-allowed; }
.marginleftonly { margin-left: var(--sp-2); }
.marginrightonly { margin-right: var(--sp-2); }
.margintoponly { margin-top: var(--sp-2); }
.marginbottomonly { margin-bottom: var(--sp-2); }
.marginleftonlyshort { margin-left: var(--sp-1); }
.marginrightonlyshort { margin-right: var(--sp-1); }
.nomargin { margin: 0 !important; }
.paddingleft { padding-left: var(--sp-2); }
.paddingright { padding-right: var(--sp-2); }
.paddingtop { padding-top: var(--sp-2); }
.paddingbottom { padding-bottom: var(--sp-2); }
.padding { padding: var(--sp-3); }
.nopadding { padding: 0 !important; }
.nopaddingleft { padding-left: 0 !important; }
.nopaddingright { padding-right: 0 !important; }
.centpercent { width: 100%; }
.quatrevingtpercent { width: 80%; }
.moitie { width: 50%; }
/* Dolibarr puts its tooltip classes on links, spans and whole blocks -- 45-67
   elements on a typical page -- so a blanket `cursor: help` turned the pointer
   into a question-mark arrow over most of the UI. Links must stay a pointer and
   blocks a normal arrow; the help cursor belongs only to a standalone info
   glyph, where it actually means "hover for an explanation". */
.classfortooltip, .classforajaxtooltip, .classfortooltiponclick { cursor: inherit; }
a.classfortooltip, a.classforajaxtooltip { cursor: pointer; }

/* The help cursor is not used anywhere in this theme -- it reads as a stray
   question mark rather than an affordance. Tooltip targets keep the cursor
   their element type implies. */
/* Dolibarr writes `cursor: help` as an INLINE style from PHP on info pictos,
   so a stylesheet rule cannot win without !important. This is the one place
   the theme needs it. */
.classfortooltip, .classforajaxtooltip, .classfortooltiponclick,
[title], [class*="fa-info"], [class*="fa-question"] { cursor: inherit !important; }
a[title], a.classfortooltip, a.classforajaxtooltip { cursor: pointer !important; }
input[title], select[title], textarea[title] { cursor: auto !important; }
button[title], label[title] { cursor: pointer !important; }
.pictofixedwidth { width: 1.35em; text-align: center; display: inline-block; }
.fieldrequired { font-weight: 600; color: var(--fieldrequiredcolor); }
.fieldrequired::after {
	content: "\00a0*";
	display: inline;
	white-space: nowrap;
	color: var(--c-danger);
}
/* Table-based forms often put fieldrequired on a cell containing a block label.
   Paint the marker beside that label, not after the block at the cell bottom. */
.fieldrequired:has(> label)::after { display: none; }
.fieldrequired > label::after {
	content: "\00a0*";
	display: inline;
	white-space: nowrap;
	color: var(--c-danger);
}
.error { color: var(--c-danger) !important; }
.warning { color: var(--c-warning) !important; }
.ok, .green { color: var(--c-success) !important; }
.red { color: var(--c-danger) !important; }
.orange { color: var(--c-warning) !important; }
.hideonsmartphone { }
.nocellnopadd { padding: 0 !important; }
.noborderspacing { border-spacing: 0; }

[class*="tdoverflowmax"] { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tdoverflowmax20 { max-width: 20px; }
.tdoverflowmax25 { max-width: 25px; }
.tdoverflowmax30 { max-width: 30px; }
.tdoverflowmax35 { max-width: 35px; }
.tdoverflowmax40 { max-width: 40px; }
.tdoverflowmax50 { max-width: 50px; }
.tdoverflowmax60 { max-width: 60px; }
.tdoverflowmax65 { max-width: 65px; }
.tdoverflowmax70 { max-width: 70px; }
.tdoverflowmax75 { max-width: 75px; }
.tdoverflowmax80 { max-width: 80px; }
.tdoverflowmax90 { max-width: 90px; }
.tdoverflowmax100 { max-width: 100px; }
.tdoverflowmax125 { max-width: 125px; }
.tdoverflowmax150 { max-width: 150px; }
.tdoverflowmax175 { max-width: 175px; }
.tdoverflowmax200 { max-width: 200px; }
.tdoverflowmax250 { max-width: 250px; }
.tdoverflowmax300 { max-width: 300px; }
.tdoverflowmax350 { max-width: 350px; }
.tdoverflowmax400 { max-width: 400px; }
.tdoverflowmax500 { max-width: 500px; }
.tdoverflowmax750 { max-width: 750px; }
.maxwidth50 { max-width: 50px; }
.minwidth50 { min-width: 50px; }
.width50 { width: 50px; }
.maxwidth75 { max-width: 75px; }
.minwidth75 { min-width: 75px; }
.width75 { width: 75px; }
.maxwidth100 { max-width: 100px; }
.minwidth100 { min-width: 100px; }
.width100 { width: 100px; }
.maxwidth125 { max-width: 125px; }
.minwidth125 { min-width: 125px; }
.width125 { width: 125px; }
.maxwidth150 { max-width: 150px; }
.minwidth150 { min-width: 150px; }
.width150 { width: 150px; }
.maxwidth200 { max-width: 200px; }
.minwidth200 { min-width: 200px; }
.width200 { width: 200px; }
.maxwidth250 { max-width: 250px; }
.minwidth250 { min-width: 250px; }
.width250 { width: 250px; }
.maxwidth300 { max-width: 300px; }
.minwidth300 { min-width: 300px; }
.width300 { width: 300px; }
.maxwidth400 { max-width: 400px; }
.minwidth400 { min-width: 400px; }
.width400 { width: 400px; }
.maxwidth500 { max-width: 500px; }
.minwidth500 { min-width: 500px; }
.width500 { width: 500px; }
.maxwidth750 { max-width: 750px; }
.minwidth750 { min-width: 750px; }
.width750 { width: 750px; }

/* ==========================================================================
   The COMMAND bar
   ========================================================================== */

header.cmd-bar {
	/* Not sticky: Dolibarr nests this inside <header id="id-top"><div.tmenu>,
	   and a sticky element cannot outlive its containing block -- the bar
	   scrolled away with that short wrapper. Fixed escapes it. */
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	z-index: 1300;
	display: flex;
	align-items: center;
	gap: var(--sp-4);
	height: var(--bar-h);
	padding: 0 var(--sp-5);
	/* Near-opaque: at 82% the page scrolled visibly through the bar and the
	   text behind it competed with the controls. */
	background: color-mix(in srgb, var(--c-surface) 97%, transparent);
	-webkit-backdrop-filter: saturate(180%) blur(16px);
	backdrop-filter: saturate(180%) blur(16px);
	border-bottom: 1px solid var(--c-hairline);
}

/* Qualified by the element, because the body carries a class of the same name
   while the drawer is open -- the state and the control that sets it were
   named alike. Unqualified, this button's own box became the body's: a page
   40px wide, the size of the button, every time the nav was opened. */
button.cmd-nav-open { display: none; }
.cmd-brand {
	display: inline-flex;
	align-items: center;
	gap: var(--sp-2);
	color: var(--c-ink);
	font-weight: 620;
	letter-spacing: -0.018em;
	white-space: nowrap;
}
.cmd-brand:hover { color: var(--c-ink); }
.cmd-brand-mark {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 26px;
	height: 26px;
	border-radius: var(--r-sm);
	background: var(--c-accent);
	color: #fff;
	font-size: 0.8125rem;
	font-weight: 700;
}
/* Showing the company logo, the tile is the logo's frame and nothing else: the
   accent fill behind an initial would tint a logo that brought its own colours,
   and a logo with a transparent background would pick up the accent as if it
   were part of the mark. */
.cmd-brand-mark-logo {
	background: transparent;
	overflow: hidden;
}
.cmd-brand-mark-logo > img {
	width: 100%;
	height: 100%;
	object-fit: contain;
	border-radius: inherit;
}
.cmd-brand-text { max-width: 200px; overflow: hidden; text-overflow: ellipsis; }

.cmd-crumbs { display: none; }
.cmd-crumb {
	color: var(--c-muted);
	font-size: 0.75em;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}
.cmd-crumb-current {
	color: var(--c-ink);
	font-weight: 550;
	font-size: 0.9375rem;
	padding-left: var(--sp-3);
	margin-left: var(--sp-1);
	border-left: 1px solid var(--c-border);
}
.cmd-crumb-sep {
	width: 5px; height: 5px;
	border-right: 1.5px solid var(--c-faint);
	border-top: 1.5px solid var(--c-faint);
	transform: rotate(45deg);
	opacity: 0.7;
}

/* The palette trigger is the primary navigation control, so it looks like an
   input rather than a button. */
.cmd-trigger {
	display: inline-flex;
	align-items: center;
	gap: var(--sp-2);
	min-width: 240px;
	height: var(--control-h);
	padding: 0 var(--sp-2) 0 var(--sp-3);
	margin-right: var(--sp-2);
	background: var(--c-sunken);
	border: 1px solid var(--c-border);
	border-radius: var(--r);
	color: var(--c-faint);
	font-family: inherit;
	font-size: 0.75em;
	cursor: pointer;
	transition: border-color var(--t), background var(--t);
}
.cmd-trigger:hover { border-color: var(--c-border-strong); background: var(--c-surface); }
.cmd-trigger-label { flex: 1; text-align: left; }
.cmd-trigger-icon { font-size: 0.8125rem; }

@media only screen and (min-width: 993px) {
	header.cmd-bar .cmd-trigger {
		position: absolute;
		left: 50%;
		transform: translateX(-50%);
		width: clamp(380px, 30vw, 470px);
		margin: 0;
		background: var(--c-surface);
		box-shadow: var(--sh-sm);
	}
}

.cmd-kbd {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 20px;
	height: 20px;
	padding: 0 5px;
	background: var(--c-surface);
	border: 1px solid var(--c-border);
	border-radius: var(--r-sm);
	color: var(--c-muted);
	font-family: var(--c-font);
	font-size: 0.6875rem;
	font-weight: 550;
	line-height: 1;
}

.cmd-bar-spacer { flex: 1 1 auto; }
.cmd-bar-tools { display: flex; align-items: center; }

/* Dolibarr's own tools/account block, relocated into the bar by command.js */
.cmd-bar-tools div.login_block {
	position: static;
	display: flex;
	align-items: center;
	gap: var(--sp-2);
	color: var(--c-muted);
	font-size: 0.75em;
}
.cmd-bar-tools .login_block_other,
.cmd-bar-tools .login_block_tools,
.cmd-bar-tools .login_block_user { display: flex; align-items: center; gap: var(--sp-2); }
.cmd-bar-tools .login_block_elem {
	display: inline-flex; align-items: center; justify-content: center;
	min-width: 32px; height: 32px; padding: 0 var(--sp-1);
	border-radius: var(--r); transition: background var(--t);
}
.cmd-bar-tools .login_block_elem:hover { background: var(--c-sunken); color: var(--c-ink); }
.cmd-bar-tools a, .cmd-bar-tools a:hover { color: var(--c-muted); }
.cmd-bar-tools .atoplogin {
	display: inline-flex; align-items: center; gap: var(--sp-2);
	height: 34px; padding: 0 var(--sp-2);
	border-radius: var(--r-pill);
	color: var(--c-muted); font-weight: 500;
}
.cmd-bar-tools .atoplogin:hover { background: var(--c-sunken); color: var(--c-ink); }
/* Only the account chip is outlined. Applying the outline to every .atoplogin
   draws empty pills around the bare icon links beside it. */
.cmd-bar-tools #topmenu-login-dropdown > .atoplogin {
	padding-left: var(--sp-1);
	border: 1px solid var(--c-border);
	color: var(--c-ink-2);
}
/* Dolibarr emits placeholder anchors for disabled top-bar tools; with no icon
   inside they would render as empty boxes. */
.cmd-bar-tools .login_block_elem:empty,
.cmd-bar-tools .atoplogin:empty { display: none; }
img.userphoto { border-radius: 50%; object-fit: cover; }

/* Dolibarr's own left column stays suppressed -- navigation is the .cmd-nav
   rail emitted by command.lib.php instead. */
div.side-nav, #id-left, .menuhider { display: none !important; }
#id-container, .id-container { display: block; width: 100%; }
/* The offset lives on <body>, not on #id-right: several Dolibarr pages print
   markup outside the #id-right container (compta/sociales/list.php among
   them), and anything outside it slid underneath the fixed rail. Padding the
   body clears the chrome for every element on the page, stray or not. */
body {
	padding-left: var(--nav-w);
	padding-top: var(--bar-h);
	transition: padding var(--t);
}
body.bodylogin { padding: 0; }		/* the login page has no chrome */

/* Held back until the theme has composed the page -- see the script in
   command.lib.php, which is also what takes this off again. Only the content
   area waits; the bar and the nav are server-rendered and paint immediately, so
   what is on screen is the application, not a blank page. Kept out of the
   printed page and off the login screen, neither of which is composed. */
html.ts-shell-pending #id-right,
html.ts-shell-pending .fiche {
	visibility: hidden;
}
/* Dolibarr prints its account/tool block in #id-top before modern.js moves the
   existing nodes into COMMAND's app bar.  That source block used to remain
   visible while the content gate was up, producing a full-width raw strip of
   icons and user text on every uncached navigation.  Keep the source wrapper
   out of the first paint as part of the same fail-safe gate.  Once the nodes
   are composed, modern.js removes ts-shell-pending; if composition fails, the
   existing timed fallback restores the native block with the rest of the
   page, so account controls never become permanently inaccessible. */
html.ts-shell-pending #id-top {
	visibility: hidden;
	height: 0 !important;
	min-height: 0 !important;
	margin: 0 !important;
	padding: 0 !important;
	border: 0 !important;
	overflow: hidden;
}
html.ts-shell-pending body.bodylogin #id-right,
html.ts-shell-pending body.bodylogin .fiche {
	visibility: visible;
}
@media print {
	html.ts-shell-pending #id-right,
	html.ts-shell-pending .fiche { visibility: visible; }
}

/* ==========================================================================
   Authentication surface

   Keep Dolibarr's original form, field ids and password-toggle script intact,
   but detach its old table-like icon/input geometry. This is intentionally
   scoped to bodylogin so setup pages and normal forms are unaffected.
   ========================================================================== */
html body.bodylogin {
	min-height: 100svh;
	margin: 0;
	/* Longhand: Dolibarr writes a configured login background onto this same
	   element as an inline style, and the shorthand would drop the image. */
	background-color: var(--c-canvas);
	font-family: var(--c-font);
}

/* The message under the card is given a max-width by Dolibarr but no side
   margins, so it sat against the left edge of the column rather than under the
   middle of the card. */
body.bodylogin .login_main_home {
	margin-left: auto;
	margin-right: auto;
}
/* Dolibarr marks the message for a plate whenever there is an image behind it,
   which the theme never drew -- so the message was reading straight off the
   photo. */
body.bodylogin .login_main_home.backgroundsemitransparent {
	width: fit-content;
	padding: 7px 14px;
	border-radius: var(--r);
	background: color-mix(in srgb, var(--c-surface) 86%, transparent);
	color: var(--c-ink-2);
}
body.bodylogin .login_center .login_vertical_align {
	box-sizing: border-box;
	width: min(440px, calc(100vw - 32px)) !important;
	min-width: 0;
}
html body.bodylogin form#login {
	box-sizing: border-box;
	width: 100% !important;
	margin: 0 auto;
	padding: 32px;
	border: 1px solid var(--c-border);
	border-radius: var(--r-xl);
	background: var(--c-surface);
	box-shadow: var(--sh-md);
}
body.bodylogin .login_table_title {
	margin: 0;
	padding: 0 0 12px;
	color: var(--c-muted);
	font-size: .6875rem;
	line-height: 1.35;
}
body.bodylogin .login_table_title a { color: inherit; }
body.bodylogin .login_table,
body.bodylogin #login_line1,
body.bodylogin #login_left,
body.bodylogin #login_right,
body.bodylogin #login_right .tagtable,
body.bodylogin .trinputlogin,
body.bodylogin .tdinputlogin {
	display: block !important;
	box-sizing: border-box;
	width: 100% !important;
	min-width: 0;
	float: none !important;
}
body.bodylogin #login_left { text-align: center; }
body.bodylogin #login_left br { display: none; }
body.bodylogin #img_logo {
	display: block;
	width: min(100%, 300px);
	height: auto;
	max-height: 92px;
	margin: 0 auto 20px;
	object-fit: contain;
}
body.bodylogin .tdinputlogin {
	position: relative;
	min-height: 44px;
	padding: 0 !important;
}
body.bodylogin .tdinputlogin > .fa:first-child {
	position: absolute;
	left: 14px;
	top: 50%;
	z-index: 1;
	width: 16px;
	margin: 0;
	transform: translateY(-50%);
	color: var(--c-muted);
	line-height: 1;
	pointer-events: none;
}
body.bodylogin .tdinputlogin input[type="text"],
body.bodylogin .tdinputlogin input[type="password"] {
	box-sizing: border-box;
	width: 100% !important;
	height: 44px;
	min-width: 0;
	margin: 0 !important;
	padding: 0 44px !important;
	border: 1px solid var(--c-border) !important;
	border-radius: var(--r) !important;
	background: var(--c-surface) !important;
	color: var(--c-ink);
	font: 500 .875rem/1 var(--c-font);
	outline: none;
	box-shadow: none !important;
}
body.bodylogin .tdinputlogin input:focus {
	border-color: var(--c-btn-action) !important;
	box-shadow: 0 0 0 3px var(--c-btn-action-ring) !important;
}
body.bodylogin .tdinputlogin input:-webkit-autofill,
body.bodylogin .tdinputlogin input:-webkit-autofill:hover,
body.bodylogin .tdinputlogin input:-webkit-autofill:focus {
	-webkit-text-fill-color: var(--c-ink);
	-webkit-box-shadow: 0 0 0 1000px var(--c-surface) inset !important;
	caret-color: var(--c-ink);
}
body.bodylogin #togglepassword {
	position: absolute;
	right: 10px;
	top: 50%;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 24px;
	height: 24px;
	margin: 0;
	transform: translateY(-50%);
	border-radius: var(--r-sm);
	color: var(--c-muted);
	line-height: 1;
	cursor: pointer;
}
body.bodylogin #togglepassword:hover { background: var(--c-sunken); color: var(--c-ink); }
body.bodylogin #login_line2 { clear: both; margin-top: 20px; }
body.bodylogin #login-submit-wrapper { display: flex; justify-content: center; margin: 0; }
body.bodylogin #login-submit-wrapper input.button {
	min-height: 40px;
	margin: 0;
	padding: 0 22px;
	border: 1px solid var(--c-btn-action) !important;
	border-radius: var(--r) !important;
	background: var(--c-btn-action) !important;
	color: var(--c-btn-action-text) !important;
	font: 650 .875rem/1 var(--c-font);
	box-shadow: 0 1px 2px var(--c-btn-action-ring);
	cursor: pointer;
}
body.bodylogin #login_line2 > .center { margin-top: 18px !important; }
body.bodylogin a.alogin { color: var(--c-accent-ink); font-size: .8125rem; }

/* Password recovery uses the same login form but adds a CAPTCHA image and
   refresh link after its security-code input. Keep those existing controls in
   one bounded row instead of letting Dolibarr's inline fragments escape the
   authentication card. */
body.bodylogin .tdinputlogin:has(#securitycode) {
	display: grid !important;
	grid-template-columns: minmax(0, 1fr) 80px 32px;
	align-items: center;
	gap: 8px;
	min-height: 44px;
}
body.bodylogin .tdinputlogin:has(#securitycode) > .span-icon-security {
	display: block !important;
	min-width: 0;
}
body.bodylogin .tdinputlogin:has(#securitycode) > .fa-unlock {
	grid-column: 1;
	left: 14px;
}
body.bodylogin #securitycode {
	width: 100% !important;
	min-width: 0;
	height: 44px;
	margin: 0 !important;
	padding: 0 14px 0 44px !important;
	border: 1px solid var(--c-border) !important;
	border-radius: var(--r) !important;
	background: var(--c-surface) !important;
	box-sizing: border-box;
}
body.bodylogin #securitycode:focus {
	border-color: var(--c-btn-action) !important;
	box-shadow: 0 0 0 3px var(--c-btn-action-ring) !important;
	outline: none;
}
body.bodylogin .tdinputlogin:has(#securitycode) > .nowrap {
	display: contents !important;
}
body.bodylogin #img_securitycode {
	grid-column: 2;
	display: block;
	width: 80px !important;
	height: 32px !important;
	margin: 0 !important;
	border: 1px solid var(--c-border);
	border-radius: var(--r-sm);
	background: var(--c-sunken);
	object-fit: contain;
}
body.bodylogin a[data-role="button"]:has(#captcha_refresh_img) {
	grid-column: 3;
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	margin: 0 !important;
	border-radius: var(--r-sm);
	color: var(--c-accent-ink);
	line-height: 1;
}
body.bodylogin a[data-role="button"]:has(#captcha_refresh_img):hover {
	background: var(--c-sunken);
}
body.bodylogin #login_line2 > br { display: none; }
body.bodylogin #login_line2 input[name="button_password"] {
	min-height: 40px;
	margin: 0;
	padding: 0 18px;
	border: 1px solid var(--c-btn-action) !important;
	border-radius: var(--r) !important;
	background: var(--c-btn-action) !important;
	color: var(--c-btn-action-text) !important;
	font: 650 .875rem/1 var(--c-font);
	box-shadow: 0 1px 2px var(--c-btn-action-ring);
	cursor: pointer;
}
body.bodylogin .login_main_home.divpasswordmessagedesc {
	box-sizing: border-box;
	width: min(400px, calc(100vw - 32px)) !important;
	max-width: none !important;
	margin: 16px auto 0;
	padding: 0 8px;
	color: var(--c-muted);
	font-size: .75rem;
	line-height: 1.5;
}
@media only screen and (max-width: 480px) {
	body.bodylogin .login_center .login_vertical_align { width: calc(100vw - 24px) !important; }
	body.bodylogin form#login { padding: 24px 20px; }
	body.bodylogin #img_logo { max-height: 76px; margin-bottom: 18px; }
	body.bodylogin .tdinputlogin:has(#securitycode) { grid-template-columns: minmax(0, 1fr) 70px 32px; gap: 6px; }
	body.bodylogin #img_securitycode { width: 70px !important; }
}

#id-right {
	margin-left: 0 !important;
	min-width: 0;
	overflow-x: hidden;
}


/* ==========================================================================
   Persistent navigation
   The palette is fast but invisible; this is what makes the app browsable.
   ========================================================================== */

:root { --nav-w: 260px; --nav-w-collapsed: 68px; --nav-w-expanded: 260px; }

aside.cmd-nav {
	position: fixed;
	top: var(--bar-h);
	/* Fixed elements position against the viewport, so body padding does not
	   shift them -- they stay flush to the edges. */
	left: 0;
	bottom: 0;
	width: var(--nav-w);
	display: flex;
	flex-direction: column;
	background: var(--c-surface);
	border-right: 1px solid var(--c-hairline);
	z-index: 1100;
	transition: width var(--t);
}
.cmd-nav-scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden; padding: var(--sp-3) var(--sp-2); }
/* Breathing room after an expanded module, so its children stay visually
   attached to it and separate from the next module. */
.cmd-nav-group.is-active { margin-bottom: var(--sp-3); }
.cmd-nav-list, .cmd-nav-sub { list-style: none; margin: 0; padding: 0; }

/* Inter renders heavy at small sizes on the sidebar's light ground; smoothing
   keeps the labels crisp rather than smudged. */
.cmd-nav-link,
.cmd-nav-sublink,
.cmd-nav-section {
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	text-rendering: optimizeLegibility;
}
.cmd-nav-link {
	display: flex;
	align-items: center;
	gap: var(--sp-3);
	padding: var(--sp-2) var(--sp-3);
	margin-bottom: 1px;
	border-radius: var(--r);
	color: var(--c-ink-2);
	font-weight: 500;
	white-space: nowrap;
	transition: background var(--t), color var(--t);
	min-height: 42px;
	font-size: 0.875rem;
	letter-spacing: -0.006em;
}
.cmd-nav-link:hover { background: var(--c-sunken); color: var(--c-ink); }
.cmd-nav-group.is-active > .cmd-nav-link {
	background: var(--c-accent-soft);
	color: var(--c-accent-ink);
	font-weight: 620;
}
.cmd-nav-icon {
	flex: 0 0 auto;
	width: 1.15em;
	text-align: center;
	color: var(--c-faint);
	font-size: 1.125rem;
}
.cmd-nav-group.is-active .cmd-nav-icon { color: var(--c-accent); }
.cmd-nav-link:hover .cmd-nav-icon { color: var(--c-muted); }
.cmd-nav-label { overflow: hidden; text-overflow: ellipsis; }

/* Sub-entries of the open module, with a guide rule so depth is readable */
.cmd-nav-sub {
	margin: var(--sp-1) 0 var(--sp-3) 0;
	padding-left: var(--sp-5);
	border-left: 1px solid var(--c-hairline);
	margin-left: var(--sp-4);
}
.cmd-nav-sublink {
	display: block;
	/* --lvl carries the entry's real depth, so repeated labels ("List",
	   "Customers") read as children of their parent rather than duplicates. */
	padding: 5px var(--sp-2) 5px calc(var(--sp-2) + (var(--lvl, 0) * 12px));
	border-radius: var(--r-sm);
	color: var(--c-ink-2);
	/* Dolibarr's $fontsizesmaller resolves to 10.5px here, which is a caption
	   size doing navigation work: the sub-entries are how most of the app is
	   reached, and they were the smallest text on the page. */
	font-size: 0.8125rem;
	font-weight: 450;
	line-height: 1.45;
	letter-spacing: -0.005em;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	transition: background var(--t), color var(--t);
}
.cmd-nav-sublink:hover { background: var(--c-sunken); color: var(--c-ink); }
/* The page you are actually on */
.cmd-nav-sublink.is-current {
	background: var(--c-sunken);
	color: var(--c-ink);
	font-weight: 600;
	box-shadow: inset 2px 0 0 var(--c-accent);
}

.cmd-nav-toggle {
	flex: 0 0 auto;
	display: flex;
	align-items: center;
	gap: var(--sp-3);
	width: 100%;
	/* Clear of the home indicator and the browser's own bottom bar. */
	padding: var(--sp-3) var(--sp-4) calc(var(--sp-3) + env(safe-area-inset-bottom, 0px));
	background: transparent;
	border: 0;
	border-top: 1px solid var(--c-hairline);
	color: var(--c-faint);
	font-family: inherit;
	font-size: 0.75em;
	cursor: pointer;
	transition: color var(--t), background var(--t);
}
.cmd-nav-toggle:hover { color: var(--c-ink); background: var(--c-sunken); }
.cmd-nav-toggle-icon {
	width: 7px; height: 7px;
	border-left: 1.5px solid currentColor;
	border-bottom: 1.5px solid currentColor;
	transform: rotate(45deg);
	margin-left: 4px;
	transition: transform var(--t);
}

/* Collapsed: an icon rail. Labels are dropped, not hidden, so the row stays
   centred; the module name still reaches screen readers via the link title. */
body.cmd-nav-collapsed { --nav-w: var(--nav-w-collapsed); }
body.cmd-nav-collapsed .cmd-nav-label,
body.cmd-nav-collapsed .cmd-nav-sub,
body.cmd-nav-collapsed .cmd-nav-toggle-label { display: none; }
body.cmd-nav-collapsed .cmd-nav-link { justify-content: center; padding-left: 0; padding-right: 0; }
body.cmd-nav-collapsed .cmd-nav-toggle { justify-content: center; }
body.cmd-nav-collapsed .cmd-nav-toggle-icon { transform: rotate(-135deg); margin: 0; }


/* ==========================================================================
   Command palette
   ========================================================================== */

.cmd-palette { position: fixed; inset: 0; z-index: 4000; }
.cmd-palette[hidden] { display: none; }
body.cmd-palette-open { overflow: hidden; }

.cmd-palette-backdrop {
	position: absolute; inset: 0;
	background: rgba(11, 18, 32, 0.42);
	-webkit-backdrop-filter: blur(2px);
	backdrop-filter: blur(2px);
}
.cmd-palette-panel {
	position: relative;
	width: min(640px, calc(100vw - var(--sp-6)));
	max-height: min(60vh, 520px);
	margin: 12vh auto 0 auto;
	display: flex;
	flex-direction: column;
	background: var(--c-surface);
	border: 1px solid var(--c-border);
	border-radius: var(--r-xl);
	box-shadow: var(--sh-lg);
	overflow: hidden;
	animation: cmd-pop 130ms cubic-bezier(0.2, 0, 0.2, 1);
}
@keyframes cmd-pop {
	from { opacity: 0; transform: translateY(-6px) scale(0.985); }
	to { opacity: 1; transform: none; }
}

.cmd-palette-input-row {
	display: flex;
	align-items: center;
	gap: var(--sp-3);
	padding: var(--sp-4);
	border-bottom: 1px solid var(--c-hairline);
}
.cmd-palette-input-icon { color: var(--c-faint); }
.cmd-palette-input {
	flex: 1;
	min-width: 0;
	border: 0 !important;
	outline: none;
	background: transparent;
	color: var(--c-ink);
	font-family: inherit;
	font-size: 1rem;
	padding: 0;
	border-radius: 0;
}
/* The row is the field; the input must not draw its own box on top of it. */
.cmd-palette-input:focus, .cmd-palette-input:hover {
	box-shadow: none !important;
	border: 0 !important;
	outline: none;
}

.cmd-palette-results { flex: 1; overflow-y: auto; padding: var(--sp-2); }
.cmd-res-group {
	padding: var(--sp-3) var(--sp-3) var(--sp-1) var(--sp-3);
	font-size: 0.6875rem;
	font-weight: 620;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--c-faint);
}
.cmd-res {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--sp-3);
	padding: var(--sp-2) var(--sp-3);
	border-radius: var(--r);
	color: var(--c-ink-2);
}
.cmd-res.is-active { background: var(--c-accent-soft); color: var(--c-accent-ink); }
.cmd-res-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cmd-res-group-tag { flex: 0 0 auto; color: var(--c-faint); font-size: 0.75rem; }
.cmd-res.is-active .cmd-res-group-tag { color: var(--c-accent-ink); opacity: 0.7; }
.cmd-palette-empty { padding: var(--sp-6); text-align: center; color: var(--c-faint); }

.cmd-palette-foot {
	display: flex;
	gap: var(--sp-4);
	padding: var(--sp-2) var(--sp-4);
	border-top: 1px solid var(--c-hairline);
	background: var(--c-sunken);
	color: var(--c-faint);
	font-size: 0.75rem;
}
.cmd-palette-foot span { display: inline-flex; align-items: center; gap: var(--sp-1); }




/* ---- Palette trigger, shared by every shell ---- */
/* The palette trigger is the primary navigation control, so it looks like an
   input rather than a button. */
.cmd-trigger {
	display: inline-flex;
	align-items: center;
	gap: var(--sp-2);
	min-width: 260px;
	height: 34px;
	padding: 0 var(--sp-2) 0 var(--sp-3);
	margin-left: var(--sp-2);
	background: var(--c-sunken);
	border: 1px solid var(--c-border);
	border-radius: var(--r);
	color: var(--c-faint);
	font-family: inherit;
	font-size: 0.75em;
	cursor: pointer;
	transition: border-color var(--t), background var(--t);
}
.cmd-trigger:hover { border-color: var(--c-border-strong); background: var(--c-surface); }
.cmd-trigger-label { flex: 1; text-align: left; }
.cmd-trigger-icon { font-size: 0.8125rem; }

.cmd-kbd {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 20px;
	height: 20px;
	padding: 0 5px;
	background: var(--c-surface);
	border: 1px solid var(--c-border);
	border-radius: var(--r-sm);
	color: var(--c-muted);
	font-family: var(--c-font);
	font-size: 0.6875rem;
	font-weight: 550;
	line-height: 1;
}



/* ---- Relocated account block ----
   command.js moves Dolibarr's own tools/account block into whichever slot the
   active shell exposes (#cmd-bar-tools). Without these rules it lands
   unstyled, because Dolibarr positions it absolutely for its own top bar. */
#cmd-bar-tools div.login_block,
.wb-rail-foot div.login_block,
.ed-side-foot div.login_block {
	position: static;
	display: flex;
	align-items: center;
	gap: var(--sp-1);
	height: auto;
	color: var(--c-muted);
	font-size: 0.75em;
	white-space: nowrap;
}
/* The rail and the editorial sidebar are narrow columns, so the block stacks. */
.wb-rail-foot div.login_block,
.ed-side-foot div.login_block { flex-direction: column; gap: var(--sp-2); }

#cmd-bar-tools .login_block_other,
#cmd-bar-tools .login_block_tools,
#cmd-bar-tools .login_block_user,
.wb-rail-foot .login_block_other,
.wb-rail-foot .login_block_tools,
.wb-rail-foot .login_block_user,
.ed-side-foot .login_block_other,
.ed-side-foot .login_block_tools,
.ed-side-foot .login_block_user {
	display: flex;
	align-items: center;
	gap: var(--sp-1);
}
.wb-rail-foot .login_block_other,
.wb-rail-foot .login_block_tools,
.wb-rail-foot .login_block_user { flex-direction: column; }

#cmd-bar-tools .login_block_elem,
.wb-rail-foot .login_block_elem,
.ed-side-foot .login_block_elem {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 30px;
	height: 30px;
	padding: 0 var(--sp-1);
	border-radius: var(--r);
	transition: background var(--t), color var(--t);
}
#cmd-bar-tools .login_block_elem:hover,
.ed-side-foot .login_block_elem:hover { background: var(--c-sunken); color: var(--c-ink); }
.wb-rail-foot .login_block_elem:hover { background: rgba(255, 255, 255, 0.12); color: #fff; }

#cmd-bar-tools a, #cmd-bar-tools a:hover,
.ed-side-foot a, .ed-side-foot a:hover { color: var(--c-muted); }
.wb-rail-foot a, .wb-rail-foot a:hover { color: rgba(255, 255, 255, 0.62); }
.wb-rail-foot a:hover { color: #fff; }

#cmd-bar-tools .atoplogin,
.wb-rail-foot .atoplogin,
.ed-side-foot .atoplogin {
	display: inline-flex;
	align-items: center;
	gap: var(--sp-2);
	height: 30px;
	padding: 0 var(--sp-2);
	border-radius: var(--r-pill);
	font-weight: 500;
}
/* Dolibarr emits placeholder anchors for disabled tools; with no icon inside
   they would render as empty boxes.
   :not([class*="fa"]) is essential -- an icon-font element draws its glyph
   from ::before and has no child nodes, so it matches :empty too. Without the
   guard this rule hid the bug, print and help icons in the bar. */
#cmd-bar-tools .login_block_elem:empty:not([class*="fa"]),
#cmd-bar-tools .atoplogin:empty:not([class*="fa"]),
.wb-rail-foot .login_block_elem:empty:not([class*="fa"]),
.ed-side-foot .login_block_elem:empty:not([class*="fa"]) { display: none; }
/* The version string has no room in a rail or a compact bar. */
.wb-rail-foot .login_block_other span:not([class*="fa"]) { display: none; }
img.userphoto { border-radius: 50%; object-fit: cover; }


/* ---- Account dropdown ----
   Dolibarr builds this as <b>Label:</b><span>value</span><br> pairs with no
   row elements, so it reads as one dense block. These rules give it column
   alignment, grouping and a scroll ceiling without needing new markup. */

#topmenu-login-dropdown .dropdown-menu {
	width: 340px;
	max-height: min(78vh, 720px);
	flex-direction: column;
	padding: 0;
	overflow: hidden;
}
/* display belongs to the open state only. Declaring `display: flex` on the
   panel itself outranks the base `.dropdown-menu { display: none }` and left
   the account panel visible on every page load. */
#topmenu-login-dropdown.open > .dropdown-menu,
.open > #topmenu-login-dropdown .dropdown-menu { display: flex; }

/* Header: identity first, timestamps demoted. */
#topmenu-login-dropdown .user-header {
	padding: var(--sp-5) var(--sp-4) var(--sp-4) var(--sp-4);
	text-align: center;
	background: var(--c-sunken);
	border-bottom: 1px solid var(--c-border);
}
#topmenu-login-dropdown .user-header img.dropdown-user-image {
	width: 64px; height: 64px;
	border-radius: 50%;
	border: 2px solid var(--c-surface);
	box-shadow: var(--sh);
	object-fit: cover;
}
#topmenu-login-dropdown .user-header p {
	margin: var(--sp-3) 0 0 0;
	font-size: 0.9375rem;
	font-weight: 620;
	color: var(--c-ink);
	line-height: 1.5;
}
#topmenu-login-dropdown .user-header small {
	display: inline-block;
	font-size: 0.75rem;
	font-weight: 400;
	color: var(--c-muted);
}

/* Body: label column + value, with a scroll ceiling. */
#topmenu-login-dropdown .user-body {
	flex: 1 1 auto;
	min-height: 0;
	overflow-y: auto;
	padding: var(--sp-3) var(--sp-4);
	font-size: 0.8125rem;
	line-height: 1.9;
	color: var(--c-ink-2);
}
#topmenu-login-dropdown .user-body b {
	display: inline-block;
	min-width: 126px;
	padding-right: var(--sp-1);
	color: var(--c-muted);
	font-weight: 500;
}
/* Each pair is separated by a bare <br>; the leading one just opened a gap
   under the disclosure row. */
#topmenulogincompanyinfo > br:first-child,
#topmenuloginmoreinfo > br:first-child { display: none; }
/* Technical values read better as monospace and should not wrap mid-token. */
#topmenu-login-dropdown #topmenuloginmoreinfo span:not([class]),
#topmenu-login-dropdown #topmenulogincompanyinfo span:not([class]) {
	font-variant-numeric: tabular-nums;
	word-break: break-word;
}
/* "Session" acts as a group heading. */
#topmenu-login-dropdown .user-body u {
	display: block;
	margin: var(--sp-3) 0 var(--sp-1) 0;
	padding-top: var(--sp-3);
	border-top: 1px solid var(--c-hairline);
	text-decoration: none;
	font-size: 0.6875rem;
	font-weight: 620;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--c-faint);
}
/* Disclosure triggers become real rows rather than bare carets. */
#topmenulogincompanyinfo-btn, #topmenuloginmoreinfo-btn {
	display: flex;
	align-items: center;
	gap: var(--sp-2);
	margin: var(--sp-1) calc(var(--sp-2) * -1);
	padding: var(--sp-2);
	border-radius: var(--r-sm);
	color: var(--c-ink);
	font-weight: 550;
	cursor: pointer;
	transition: background var(--t);
}
#topmenulogincompanyinfo-btn:hover, #topmenuloginmoreinfo-btn:hover { background: var(--c-sunken); }
#topmenulogincompanyinfo-btn .fa, #topmenuloginmoreinfo-btn .fa {
	color: var(--c-faint);
	transition: transform var(--t);
}

/* Footer: evenly weighted actions on one row. */
#topmenu-login-dropdown .user-footer {
	flex: 0 0 auto;
	display: flex;
	align-items: center;
	gap: var(--sp-2);
	padding: var(--sp-3) var(--sp-4);
	background: var(--c-sunken);
	border-top: 1px solid var(--c-border);
}
#topmenu-login-dropdown .user-footer .pull-left,
#topmenu-login-dropdown .user-footer .pull-right { float: none; }
#topmenu-login-dropdown .user-footer .pull-right { margin-left: auto; }
#topmenu-login-dropdown .user-footer .clearboth { display: none; }
#topmenu-login-dropdown .user-footer a {
	display: inline-flex;
	align-items: center;
	gap: var(--sp-2);
	height: 30px;
	padding: 0 var(--sp-3);
	border-radius: var(--r);
	color: var(--c-ink-2);
	font-size: 0.8125rem;
	font-weight: 500;
	transition: background var(--t), color var(--t);
}
#topmenu-login-dropdown .user-footer a:hover { background: var(--c-surface); color: var(--c-ink); }
/* Logout is the destructive action here. */
#topmenu-login-dropdown .user-footer .pull-right a:hover { color: var(--c-danger); }

/* ==========================================================================
   Page
   ========================================================================== */

.fiche {
	width: 100%;
	max-width: 1560px;
	margin: 0 auto;
	padding: var(--sp-6) var(--sp-7) var(--sp-8) var(--sp-7);
	min-width: 0;
}
.fichecenter { clear: both; width: 100%; }
.fichecenter::after { content: ""; display: table; clear: both; }
.fichehalfleft, .fichethirdleft { float: left; width: calc(50% - var(--sp-3)); }
.fichehalfright, .fichetwothirdright { float: right; width: calc(50% - var(--sp-3)); }

.titre, div.titre {
	font-size: 1.75rem;
	font-weight: 640;
	letter-spacing: -0.028em;
	line-height: 1.12;
	color: var(--c-ink);
}
.titre .opacitymedium {
	font-size: 0.6em; font-weight: 450; opacity: 1;
	color: var(--c-muted); margin-left: var(--sp-2);
}
.table-fiche-title { width: 100%; margin-bottom: var(--sp-5); border: 0; border-spacing: 0; }
.table-fiche-title td { padding: 0; border: 0; vertical-align: middle; }
.table-fiche-title td.col-picto { width: 34px; }
.table-fiche-title.ts-empty-title { display: none !important; }
.widthpictotitle { width: 26px; }
.pictotitle { margin-right: var(--sp-2); color: var(--c-accent) !important; opacity: 0.9; }
/* .print-barre-liste is a span inside the list title (it marks what survives
   printing), not a toolbar -- it must not become a flex container. */
.print-barre-liste { display: inline-block; }


/* ==========================================================================
   Tabs and object banner
   ========================================================================== */

div.tabs { display: flex; flex-wrap: wrap; gap: 2px; border-bottom: 1px solid var(--c-border); }
div.tabsElem { display: inline-block; }
a.tab, a.tabactive, a.tabunactive {
	display: inline-block; position: relative;
	padding: var(--sp-2) var(--sp-4);
	border: 0; border-radius: var(--r) var(--r) 0 0;
	color: var(--c-muted); font-weight: 500; white-space: nowrap;
	transition: background var(--t), color var(--t);
}
a.tab:hover, a.tabunactive:hover { background: var(--c-sunken); color: var(--c-ink); }
/* Dolibarr emits <div class="tab tabactive"><a class="tab">, so the active
   state lives on the wrapper. Styling only a.tabactive matched nothing and
   the current tab had no indicator at all. */
a.tabactive,
div.tab.tabactive > a.tab,
.tabsElemActive a.tab { color: var(--c-accent-ink); font-weight: 620; }

div.tabs div.tab { position: relative; display: inline-block; }
a.tabactive::after,
div.tab.tabactive::after,
.tabsElemActive::after {
	content: ""; position: absolute; left: var(--sp-3); right: var(--sp-3);
	bottom: -1px; height: 2px; background: var(--c-accent); border-radius: 2px 2px 0 0;
}
.tabsElem { position: relative; }
div.tab.tabunactive > a.tab { color: var(--c-muted); }
div.tab:hover > a.tab { color: var(--c-ink); }
.tabs .badge { margin-left: var(--sp-1); background: var(--c-sunken); color: var(--c-muted); }
a.tabactive .badge { background: var(--c-accent-soft); color: var(--c-accent-ink); }

div.tabBar {
	background: var(--c-surface);
	border: 1px solid var(--c-hairline); border-top: 0;
	border-radius: 0 0 var(--r-lg) var(--r-lg);
	padding: var(--sp-6);
	box-shadow: var(--sh);
}
div.tabBarNoTop, div.tabBarWithBottom { border-top: 1px solid var(--c-hairline); border-radius: var(--r-lg); }

div.arearef { padding-bottom: var(--sp-5); margin-bottom: var(--sp-5); border-bottom: 1px solid var(--c-hairline); }
.refid { font-size: 1.5rem; font-weight: 640; letter-spacing: -0.026em; color: var(--c-ink); }
/* rem, not em: .refidno sits inside the 24px ref block, so an em value
   compounded to ~22px and the address, phone and email lines rendered almost
   as large as the record title. */
.refidno { font-size: 0.9375rem; font-weight: 400; color: var(--refidnocolor); }
/* Everything else in the banner is body text, not heading text. */
div.arearef .address,
div.arearef .refidno,
div.arearef .paddingright,
div.arearef .paddingrightonly,
div.arearef .nospan,
div.arearef a:not(.refid) { font-size: 0.9375rem; line-height: 1.55; }
div.statusref { float: right; text-align: right; padding-left: var(--sp-4); }
div.divphotoref, .photoref { margin-right: var(--sp-4); }
div.divphotoref img, .photoref img { border-radius: var(--r); border: 1px solid var(--c-border); }


/* ==========================================================================
   Tables and lists
   ========================================================================== */

table { border-collapse: collapse; border-spacing: 0; }

div.div-table-responsive, div.div-table-responsive-no-min {
	max-width: 100%;
	overflow-x: auto;
	background: var(--c-surface);
	border: 1px solid var(--c-hairline);
	border-radius: var(--r-lg);
	box-shadow: var(--sh);
}
table.liste, table.noborder, table.border, table.centpercent { width: 100%; background: transparent; }

tr.liste_titre, .liste_titre { background: var(--colorbacktitle1); }
tr.liste_titre th, tr.liste_titre td, th.liste_titre, td.liste_titre {
	padding: var(--sp-3) var(--sp-4);
	text-align: left;
	font-size: 0.75em;
	font-weight: 550;
	color: var(--c-muted);
	white-space: nowrap;
	border-bottom: 1px solid var(--c-border);
	vertical-align: middle;
}
tr.liste_titre th a, .liste_titre a { color: var(--c-muted); }
tr.liste_titre th a:hover, .liste_titre a:hover { color: var(--c-accent-ink); }

tr.liste_titre_filter, tr.liste_titre_filter td, tr.liste_titre_filter th {
	background: var(--c-surface);
	border-bottom: 1px solid var(--c-border);
	padding: var(--sp-2);
}

tr.oddeven, tr.impair, tr.pair {
	background: var(--c-surface);
	border-bottom: 1px solid var(--c-hairline);
	transition: background var(--t);
}
tr.oddeven td, tr.impair td, tr.pair td, table.liste td, table.noborder td {
	padding: var(--sp-3) var(--sp-4);
	height: 44px;
	color: var(--oddevencolor);
	vertical-align: middle;
	border: 0;
}
tr.oddeven:last-child, tr.impair:last-child, tr.pair:last-child { border-bottom: 0; }
tr.oddeven:hover, tr.impair:hover, tr.pair:hover { background: var(--colorbacklinepairhover); }
tr.nohover:hover, .nohover:hover { background: var(--c-surface) !important; }
tr.highlight, tr.selected { background: var(--colorbacklinepairchecked) !important; }

tr.liste_total td, .liste_total {
	background: var(--c-sunken); font-weight: 620;
	color: var(--listetotal); border-top: 2px solid var(--c-border);
}
tr.trforbreak td { background: var(--colorbacklinebreak); font-weight: 600; }

td.right, th.right, td.amount, th.amount { text-align: right; }
td.amount, .amount { font-weight: 500; }

/* Sticky list header on tall lists */
div.div-table-responsive table.liste tr.liste_titre th {
	position: sticky; top: 0; z-index: 3; background: var(--colorbacktitle1);
}

/* Key/value field tables on cards */
table.border td, table.tableforfield td, table.border th {
	padding: var(--sp-2) var(--sp-3);
	vertical-align: top;
}
/* The separator belongs to the row, not the cell: Dolibarr emits a varying
   number of <td> per row (2 on single-field rows, 4 on paired ones), so a
   border on the cell stopped mid-table and the rules looked ragged. */
table.border > tbody > tr,
table.tableforfield > tbody > tr {
	border-bottom: 1px solid var(--c-hairline);
}
table.border > tbody > tr:last-child,
table.tableforfield > tbody > tr:last-child { border-bottom: 0; }
table.border > tbody > tr > td,
table.tableforfield > tbody > tr > td { border-bottom: 0; }
/* A percentage label column looks fine in a half-width card (234px) but opens
   a 475px dead gap on a full-width one. A fixed width keeps the label/value
   relationship identical on every tab and every card. */
td.titlefield, td.titlefieldcreate, .tableforfield td:first-child, table.border td.fieldtitle {
	width: 320px;
	/* Was --tableforfieldcolor (muted). Beside a tall control such as the
	   rich-text editor a muted label all but disappeared, so labels now carry
	   body-text weight and colour. */
	color: var(--c-ink-2);
	font-weight: 550;
	padding-right: var(--sp-4);
	padding-top: var(--sp-3);
}
.titlefieldcreate { width: 320px; }

/* A settings/edit table stretched to the full card width leaves a toggle
   floating a thousand pixels from its label. Capping the measure keeps the
   pair readable as one line of text; list tables are untouched and still use
   the whole width. */
/* No width cap: capping the table made long setting labels wrap inside a
   narrow column while the right half of the card sat empty. Full width with a
   proportional label column keeps labels on one line instead. */
div.tabBar table.border:not(.liste),
div.tabBar table.tableforfield:not(.liste),
table.editmode:not(.liste) {
	max-width: none;
}
/* Full-width settings tables cap the label column instead of scaling it. A
   proportional width looked reasonable on a narrow card and absurd on a wide
   one: at 42% of a 1194px table, "Zip" and "Town" were given a 501px column
   and the form read as two distant halves with a river of empty space down
   the middle. Labels here are short by nature, so a ceiling serves them
   better than a share of whatever width the container happens to have. */
div.tabBar > table.border:not(.liste) > tbody > tr > td.titlefield,
div.tabBar > table.tableforfield:not(.liste) > tbody > tr > td:first-child,
table.editmode:not(.liste) > tbody > tr > td:first-child {
	width: 320px;
	max-width: 34%;
}
/* Two-column cards are already narrow -- no cap needed there. */
.fichehalfleft table, .fichehalfright table { max-width: none; }
/* Narrow containers fall back to proportional so the label never crowds out
   the field beside it. */
@media only screen and (max-width: 1100px) {
	td.titlefield, td.titlefieldcreate, .tableforfield td:first-child { width: 34%; }
}
table.nobordernopadding td, td.nobordernopadding { border: 0; padding: 0; }

div.divsearchfield { display: inline-flex; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-3); }
.selectedfields, .selectedfieldsleft { color: var(--c-muted); }

/* Pager: Dolibarr emits div.pagination > ul > li, so the list chrome must be
   reset or the controls render as a bulleted column. */
div.pagination, .paginationref { font-size: 0.75em; color: var(--c-muted); }
div.pagination ul, .paginationref ul {
	display: flex; align-items: center; justify-content: flex-end;
	gap: var(--sp-1); margin: 0; padding: 0; list-style: none;
}
div.pagination li, .paginationref li { display: inline-flex; align-items: center; white-space: nowrap; }
div.pagination li a {
	display: inline-flex; align-items: center; justify-content: center;
	min-width: 28px; height: 28px; padding: 0 var(--sp-2);
	border-radius: var(--r); color: var(--c-muted); transition: background var(--t);
}
div.pagination li a:hover { background: var(--c-sunken); color: var(--c-accent-ink); }
div.pagination li.pagination-active a {
	background: var(--c-btn-action);
	border-color: var(--c-btn-action);
	color: var(--c-btn-action-text);
	font-weight: 620;
}
div.pagination select.selectlimit { height: 28px; padding-top: 0; padding-bottom: 0; }
/* The current-page field is a text input and will otherwise take the row's
   free width. */
div.pagination input, div.pagination input[type="text"], .paginationref input {
	width: 44px; height: 28px; padding: 0 var(--sp-1); text-align: center;
}


/* ==========================================================================
   Forms and buttons
   ========================================================================== */

/* Dolibarr emits most of its fields as bare <input name="..."> with no type
   attribute, and input[type="text"] cannot match an absent attribute -- those
   fields kept the browser's 2px inset default while the focus ring (from a
   bare input:focus rule) still applied, so they only looked styled on click.
   Matching by exclusion covers typed and untyped fields alike. */
input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]):not([type="reset"]):not([type="file"]):not([type="image"]):not([type="range"]):not([type="color"]):not([type="hidden"]),
textarea, select, .flat {
	font-family: inherit;
	font-size: 0.9375rem;
	line-height: 1.4;
	color: var(--c-ink);
	background: var(--inputbackgroundcolor);
	border: 1px solid var(--inputbordercolor);
	border-radius: var(--r);
	padding: 6px var(--sp-2);
	max-width: 100%;
	transition: border-color var(--t), box-shadow var(--t);
}
textarea { padding: var(--sp-2); }
/* Hover and focus must repeat the base rule's full :not() list. The base
   carries ten of them -- specificity (0,10,1) -- so a five-clause :focus
   selector scores (0,6,1) and LOSES to it. The ring still drew, because
   nothing else set box-shadow, but the border never changed colour: a focused
   field looked identical to a resting one except for a faint halo. Matching
   the clause count puts focus back in charge of its own border. */
input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]):not([type="reset"]):not([type="file"]):not([type="image"]):not([type="range"]):not([type="color"]):not([type="hidden"]):hover:not([disabled]),
select:hover:not([disabled]), textarea:hover:not([disabled]) { border-color: var(--c-border-strong); }
input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]):not([type="reset"]):not([type="file"]):not([type="image"]):not([type="range"]):not([type="color"]):not([type="hidden"]):focus,
select:focus, textarea:focus, .flat:focus {
	outline: none; border-color: var(--c-accent); box-shadow: 0 0 0 3px var(--c-accent-ring);
}
input[disabled]:not([type="checkbox"]):not([type="radio"]), select[disabled], textarea[disabled],
input[readonly]:not([type="checkbox"]):not([type="radio"]) {
	background: var(--inputbackgroundcolordisabled); color: var(--inputcolordisabled); cursor: not-allowed;
}

/* File pickers keep a native control inside, so they get the frame only. */
input[type="file"] {
	font-family: inherit;
	font-size: 0.75em;
	color: var(--c-ink-2);
	background: var(--inputbackgroundcolor);
	border: 1px solid var(--inputbordercolor);
	border-radius: var(--r);
	padding: var(--sp-2);
	max-width: 100%;
}
input[type="file"]::file-selector-button {
	margin-right: var(--sp-3);
	padding: 5px var(--sp-3);
	background: var(--c-sunken);
	border: 1px solid var(--c-border);
	border-radius: var(--r-sm);
	color: var(--c-ink-2);
	font-family: inherit;
	font-size: 0.75em;
	cursor: pointer;
}
input[type="file"]::file-selector-button:hover { background: var(--c-surface); border-color: var(--c-border-strong); }
select, select.flat {
	padding-right: var(--sp-5);
	background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%235B6B82' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 6.5 8 10.5 12 6.5'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right var(--sp-2) center;
	background-size: 14px;
	appearance: none; -webkit-appearance: none;
}
input[type="checkbox"], input[type="radio"] { accent-color: var(--c-accent); width: 15px; height: 15px; cursor: pointer; }
fieldset { border: 1px solid var(--c-border); border-radius: var(--r); padding: var(--sp-4); margin-bottom: var(--sp-4); }
legend { padding: 0 var(--sp-2); font-weight: 600; color: var(--c-muted); font-size: 0.75em; }
.button_search, .button_removefilter { background: transparent; border: 0; color: var(--c-muted); cursor: pointer; padding: var(--sp-1); }
.button_search:hover { color: var(--c-accent); }
.button_removefilter:hover { color: var(--c-danger); }

.butAction, .butActionDelete, .butActionRefused, a.butAction, a.butActionDelete,
a.butActionRefused, input.butAction, input.button, button.button, a.button,
button.buttongen, .buttongen {
	display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
	height: 34px; padding: 0 var(--sp-4); margin: 0 0 0 var(--sp-2);
	border: 1px solid transparent; border-radius: var(--r);
	font-family: inherit; font-size: 0.9375rem; font-weight: 550;
	line-height: 1; white-space: nowrap; cursor: pointer;
	transition: background var(--t), border-color var(--t), box-shadow var(--t);
}
.butAction, a.butAction, input.butAction, button.butAction {
	background: var(--c-btn-action, var(--c-accent));
	color: var(--c-btn-action-text, #fff);
	box-shadow: var(--sh-sm);
}
.butAction:hover, a.butAction:hover, input.butAction:hover, button.butAction:hover {
	background: var(--c-btn-action, var(--c-accent-hover));
	color: var(--c-btn-action-text, #fff);
	filter: brightness(0.94);
}
input.button, .buttongen, button.button, a.button { background: var(--c-surface); color: var(--c-ink); border-color: var(--c-border); }
input.button:hover, .buttongen:hover, a.button:hover { background: var(--c-sunken); border-color: var(--c-border-strong); }
.butActionDelete, a.butActionDelete { background: var(--c-surface); color: var(--c-danger); border-color: var(--c-border); }
.butActionDelete:hover, a.butActionDelete:hover { background: var(--c-danger); border-color: var(--c-danger); color: #fff; }
.butActionRefused, a.butActionRefused {
	background: var(--c-sunken); color: var(--c-faint); border-color: var(--c-border);
	cursor: not-allowed; box-shadow: none;
}
div.tabsAction {
	display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--sp-2);
	margin: var(--sp-4) 0 var(--sp-3) 0; border: 0;
}
div.tabsAction .butAction, div.tabsAction .butActionDelete, div.tabsAction .butActionRefused { margin: 0; }


/* ==========================================================================
   Cards, boxes, info-boxes
   ========================================================================== */

.box, div.box, div.divboxtable { margin-bottom: var(--sp-4); }
table.boxtable, div.boxtable {
	width: 100%; background: var(--c-surface);
	border: 1px solid var(--c-hairline); border-radius: var(--r-lg);
	box-shadow: var(--sh); overflow: hidden;
}
tr.box_titre td, .box_titre td {
	padding: var(--sp-4) var(--sp-5);
	font-size: 0.9375rem; font-weight: 620; color: var(--c-ink); letter-spacing: -0.012em;
	border-bottom: 1px solid var(--c-hairline);
}
/* Dolibarr's "no records" rows are the most-seen state on a fresh install and
   should read as calm, not as missing content. */
table.boxtable td.center, table.boxtable tr.oddeven td[colspan] {
	color: var(--c-muted);
}
tr.box_impair td, tr.box_pair td { padding: var(--sp-3) var(--sp-5); border-bottom: 1px solid var(--c-hairline); }
table.boxtable tr:last-child td { border-bottom: 0; }
/* Summary cards often reserve several empty result columns even when their
   empty state contains one message row. Fixed distribution keeps the semantic
   title column readable instead of collapsing it to the first few letters. */
.fichecenter table.noborder:not(.boxtable):has(th[colspan]) {
	table-layout: fixed;
}
.fichecenter table.noborder:not(.boxtable):has(th[colspan]) tr:first-child > th:first-child {
	width: 42%;
	min-width: 12rem;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}
.boxclose, .boxhandle, .boxfilter { color: var(--c-faint); cursor: pointer; opacity: 0; transition: color var(--t), opacity var(--t); }
table.boxtable:hover .boxclose, table.boxtable:hover .boxhandle, table.boxtable:hover .boxfilter { opacity: 1; }
.boxclose:hover { color: var(--c-danger); }
.boxhandle:hover, .boxfilter:hover { color: var(--c-accent); }
.boxhalfleft { float: left; width: calc(50% - var(--sp-3)); }
.boxhalfright { float: right; width: calc(50% - var(--sp-3)); }

.box-flex-container { display: flex; flex-wrap: wrap; gap: var(--sp-4); margin-bottom: var(--sp-5); }
.box-flex-item { flex: 1 1 300px; min-width: 280px; }

div.info-box {
	display: flex; align-items: center;
	background: var(--c-surface);
	border: 1px solid var(--c-hairline);
	border-radius: var(--r-lg);
	box-shadow: var(--sh);
	overflow: hidden;
	transition: box-shadow var(--t), border-color var(--t), transform var(--t);
}
div.info-box:hover { border-color: var(--c-border); box-shadow: var(--sh-md); transform: translateY(-1px); }
span.info-box-icon {
	display: flex; align-items: center; justify-content: center;
	width: 40px; height: 40px; flex: 0 0 40px;
	margin: var(--sp-4) 0 var(--sp-4) var(--sp-4);
	background: var(--c-sunken); border-radius: var(--r);
	color: var(--c-accent); font-size: 1.0625rem;
}
div.info-box-content { flex: 1; min-width: 0; padding: var(--sp-4); display: flex; flex-direction: column; justify-content: center; gap: 2px; }
/* Label above, figure below: the metric is what the tile is for. */
span.info-box-title, div.info-box-title {
	font-size: 0.6875rem;
	font-weight: 620;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	color: var(--c-muted);
	order: -1;
}
span.info-box-text, .info-box-text { font-size: 0.9375rem; color: var(--c-ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.info-box-text-a { color: var(--colortextlink); }
span.info-box-weight, span.info-box-number {
	font-size: 1.5rem; font-weight: 640; color: var(--c-ink); letter-spacing: -0.03em; line-height: 1.15;
}
.info-box-more, .info-box-line { font-size: 0.75em; color: var(--c-muted); }
.info-box-module-enabled { background: var(--infoboxmoduleenabledbgcolor); }

/* Dolibarr's own glyph aliases: object type -> Font Awesome codepoint. An icon
   map, not styling, so the codepoints match upstream. */
.fa-dol-action:before { content: "\f073"; }
.fa-dol-propal:before, .fa-dol-supplier_proposal:before { content: "\f573"; }
.fa-dol-facture:before, .fa-dol-invoice_supplier:before { content: "\f571"; }
.fa-dol-project:before { content: "\f542"; }
.fa-dol-commande:before, .fa-dol-order_supplier:before { content: "\f570"; }
.fa-dol-contrat:before { content: "\f0f2"; }
.fa-dol-ticket:before { content: "\f3ff"; }
.fa-dol-bank_account:before { content: "\f19c"; }
.fa-dol-member:before { content: "\f007"; }
.fa-dol-expensereport:before { content: "\f555"; }
.fa-dol-holiday:before { content: "\f5ca"; }
.fa-dol-cubes:before { content: "\f1b3"; }
.fa-weather-level0:before { content: "\f185"; color: var(--c-success); }
.fa-weather-level1:before { content: "\f6c4"; color: var(--c-warning); }
.fa-weather-level2:before { content: "\f743"; color: var(--c-warning); }
.fa-weather-level3:before { content: "\f740"; color: var(--c-danger); }
.fa-weather-level4:before { content: "\f0e7"; color: var(--c-danger); }
/* Those levels colour the glyph by severity, which reads on a list or in a
   tooltip. On the dashboard the same glyph sits on a summary card's tile
   alongside every other module's icon, all of them white -- and the tile does
   not change with the level, so the lone coloured glyph read as a mistake
   rather than as a signal. There it takes the tile's own colour. */
.ts-dashboard-summary-card .info-box-icon [class*="fa-weather-level"]:before,
.ts-dashboard-summary-card .info-box-icon[class*="fa-weather-level"]:before {
	color: inherit;
}
.info-box-weather .info-box-icon { background: var(--c-sunken) !important; }
.infobox-action { color: #6366F1; }
.infobox-propal, .infobox-facture, .infobox-commande { color: #4F46E5; }
.infobox-supplier_proposal, .infobox-invoice_supplier, .infobox-order_supplier { color: var(--c-info); }
.infobox-contrat, .infobox-ticket { color: #0E9F8E; }
.infobox-bank_account { color: #7A6A1F; }
.infobox-adherent, .infobox-member { color: #7C5AA0; }
.infobox-project { color: #3B5BDB; }
.infobox-expensereport { color: #96610A; }
.infobox-holiday { color: #755114; }
.info-box-icon i { color: inherit; }

/* Stat tiles inside a widget. The anchor is the tile, so it must be
   inline-block: block stacks them one per row, and a border on an inline
   element paints across the label instead of around it. */
a.boxstatsindicator, a.thumbstat {
	display: inline-block; width: calc(33.333% - var(--sp-2));
	margin: 0 var(--sp-1) var(--sp-2) 0; vertical-align: top;
	padding: 0; border: 0; color: inherit;
}
div.boxstats {
	display: flex; flex-direction: column; align-items: center; justify-content: center;
	gap: var(--sp-1); min-height: 68px; padding: var(--sp-3);
	border: 1px solid var(--colorboxstatsborder); border-radius: var(--r);
	background: var(--c-surface); text-align: center;
	transition: border-color var(--t), box-shadow var(--t);
}
a.boxstatsindicator:hover div.boxstats { border-color: var(--c-accent); box-shadow: var(--sh-sm); }
span.boxstatstext { font-size: 0.75em; color: var(--c-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
div.boxstats span.boxstatsindicator {
	display: inline-flex; align-items: center; gap: var(--sp-2);
	font-size: 1.125rem; font-weight: 620; color: var(--c-ink); border: 0; padding: 0; width: auto;
}
div.boxstats br { display: none; }
.tdwidgetstate { padding: var(--sp-2) !important; }
@media only screen and (max-width: 1400px) { a.boxstatsindicator, a.thumbstat { width: calc(50% - var(--sp-2)); } }


/* ==========================================================================
   Badges and notices
   ========================================================================== */

.badge {
	display: inline-flex; align-items: center; gap: var(--sp-1);
	padding: 2px var(--sp-2); border-radius: var(--r-pill);
	font-size: 0.6875rem; font-weight: 620; line-height: 1.5;
	white-space: nowrap; vertical-align: middle;
}
.badge-status { border: 1px solid transparent; background: var(--c-sunken); color: var(--c-muted); }
.badge-dot { padding: 0; width: 9px; height: 9px; min-width: 9px; border-radius: 50%; display: inline-block; }
.badge-status0 { background: color-mix(in srgb, #6B7A73 15%, transparent); color: color-mix(in srgb, #6B7A73 52%, var(--c-ink)); border-color: color-mix(in srgb, #6B7A73 30%, transparent); }
.badge-status0.badge-dot { background: #6B7A73; border-color: #6B7A73; }
.badge-status1 { background: color-mix(in srgb, #bc9526 15%, transparent); color: color-mix(in srgb, #bc9526 52%, var(--c-ink)); border-color: color-mix(in srgb, #bc9526 30%, transparent); }
.badge-status1.badge-dot { background: #bc9526; border-color: #bc9526; }
.badge-status1b { background: color-mix(in srgb, #bc9526 15%, transparent); color: color-mix(in srgb, #bc9526 52%, var(--c-ink)); border-color: color-mix(in srgb, #bc9526 30%, transparent); }
.badge-status1b.badge-dot { background: #bc9526; border-color: #bc9526; }
.badge-status2 { background: color-mix(in srgb, #9c9c26 15%, transparent); color: color-mix(in srgb, #9c9c26 52%, var(--c-ink)); border-color: color-mix(in srgb, #9c9c26 30%, transparent); }
.badge-status2.badge-dot { background: #9c9c26; border-color: #9c9c26; }
.badge-status3 { background: color-mix(in srgb, #bca52b 15%, transparent); color: color-mix(in srgb, #bca52b 52%, var(--c-ink)); border-color: color-mix(in srgb, #bca52b 30%, transparent); }
.badge-status3.badge-dot { background: #bca52b; border-color: #bca52b; }
.badge-status4 { background: color-mix(in srgb, #25a580 15%, transparent); color: color-mix(in srgb, #25a580 52%, var(--c-ink)); border-color: color-mix(in srgb, #25a580 30%, transparent); }
.badge-status4.badge-dot { background: #25a580; border-color: #25a580; }
.badge-status4b { background: color-mix(in srgb, #25a580 15%, transparent); color: color-mix(in srgb, #25a580 52%, var(--c-ink)); border-color: color-mix(in srgb, #25a580 30%, transparent); }
.badge-status4b.badge-dot { background: #25a580; border-color: #25a580; }
.badge-status5 { background: color-mix(in srgb, #5F6B65 15%, transparent); color: color-mix(in srgb, #5F6B65 52%, var(--c-ink)); border-color: color-mix(in srgb, #5F6B65 30%, transparent); }
.badge-status5.badge-dot { background: #5F6B65; border-color: #5F6B65; }
.badge-status6 { background: color-mix(in srgb, #5F6B65 15%, transparent); color: color-mix(in srgb, #5F6B65 52%, var(--c-ink)); border-color: color-mix(in srgb, #5F6B65 30%, transparent); }
.badge-status6.badge-dot { background: #5F6B65; border-color: #5F6B65; }
.badge-status7 { background: color-mix(in srgb, #25a580 15%, transparent); color: color-mix(in srgb, #25a580 52%, var(--c-ink)); border-color: color-mix(in srgb, #25a580 30%, transparent); }
.badge-status7.badge-dot { background: #25a580; border-color: #25a580; }
.badge-status8 { background: color-mix(in srgb, #994013 15%, transparent); color: color-mix(in srgb, #994013 52%, var(--c-ink)); border-color: color-mix(in srgb, #994013 30%, transparent); }
.badge-status8.badge-dot { background: #994013; border-color: #994013; }
.badge-status9 { background: color-mix(in srgb, #5F6B65 15%, transparent); color: color-mix(in srgb, #5F6B65 52%, var(--c-ink)); border-color: color-mix(in srgb, #5F6B65 30%, transparent); }
.badge-status9.badge-dot { background: #5F6B65; border-color: #5F6B65; }
.badge-status10 { background: color-mix(in srgb, #993013 15%, transparent); color: color-mix(in srgb, #993013 52%, var(--c-ink)); border-color: color-mix(in srgb, #993013 30%, transparent); }
.badge-status10.badge-dot { background: #993013; border-color: #993013; }
.badge-status11 { background: color-mix(in srgb, #15a540 15%, transparent); color: color-mix(in srgb, #15a540 52%, var(--c-ink)); border-color: color-mix(in srgb, #15a540 30%, transparent); }
.badge-status11.badge-dot { background: #15a540; border-color: #15a540; }
.badgeneutral { background: var(--c-sunken); color: var(--c-muted); }

.badge-primary, .badgePrimary { background: color-mix(in srgb, #007bff 15%, transparent); color: color-mix(in srgb, #007bff 52%, var(--c-ink)); border: 1px solid color-mix(in srgb, #007bff 30%, transparent); }
.badge-secondary, .badgeSecondary { background: color-mix(in srgb, #aaaabb 15%, transparent); color: color-mix(in srgb, #aaaabb 52%, var(--c-ink)); border: 1px solid color-mix(in srgb, #aaaabb 30%, transparent); }
.badge-info, .badgeInfo { background: color-mix(in srgb, #aaaabb 15%, transparent); color: color-mix(in srgb, #aaaabb 52%, var(--c-ink)); border: 1px solid color-mix(in srgb, #aaaabb 30%, transparent); }
.badge-success, .badgeSuccess { background: color-mix(in srgb, #55a580 15%, transparent); color: color-mix(in srgb, #55a580 52%, var(--c-ink)); border: 1px solid color-mix(in srgb, #55a580 30%, transparent); }
.badge-warning, .badgeWarning { background: color-mix(in srgb, #bc9526 15%, transparent); color: color-mix(in srgb, #bc9526 52%, var(--c-ink)); border: 1px solid color-mix(in srgb, #bc9526 30%, transparent); }
.badge-danger, .badgeDanger { background: color-mix(in srgb, #994013 15%, transparent); color: color-mix(in srgb, #994013 52%, var(--c-ink)); border: 1px solid color-mix(in srgb, #994013 30%, transparent); }
.badge-dark, .badgeDark { background: var(--c-ink); color: var(--c-surface); }
.badge-light, .badgeLight { background: var(--c-sunken); color: var(--c-muted); }

div.ok, div.warning, div.error, div.info {
	padding: var(--sp-3) var(--sp-4); margin-bottom: var(--sp-4);
	border: 1px solid transparent; border-left: 3px solid transparent;
	border-radius: var(--r);
}
div.ok { background: color-mix(in srgb, var(--c-success) 8%, transparent); border-color: color-mix(in srgb, var(--c-success) 25%, transparent); border-left-color: var(--c-success); color: var(--c-success); }
div.warning { background: color-mix(in srgb, var(--c-warning) 8%, transparent); border-color: color-mix(in srgb, var(--c-warning) 25%, transparent); border-left-color: var(--c-warning); color: var(--c-warning); }
div.error { background: color-mix(in srgb, var(--c-danger) 8%, transparent); border-color: color-mix(in srgb, var(--c-danger) 25%, transparent); border-left-color: var(--c-danger); color: var(--c-danger); }
div.info { background: color-mix(in srgb, var(--c-info) 8%, transparent); border-color: color-mix(in srgb, var(--c-info) 25%, transparent); border-left-color: var(--c-info); color: var(--c-info); }


/* ==========================================================================
   Tooltips, dropdowns, select2, jQuery UI
   ========================================================================== */

/* Dolibarr builds tooltip bodies as <br>-separated label/value lines with no
   rhythm of their own, so they arrive as a solid block of text. Padding and
   leading do most of the work; the rest is giving its <u> sub-headings and
   bold labels a role. */
.ui-tooltip {
	max-width: 420px;
	padding: var(--sp-3) var(--sp-4);
	background: var(--tooltipbgcolor);
	color: var(--tooltipfontcolor);
	border: 1px solid var(--c-hairline);
	border-radius: var(--r-lg);
	box-shadow: var(--sh-lg);
	font-size: 0.8125rem;
	line-height: 1.7;
	z-index: 10000;
}
.ui-tooltip .ui-tooltip-content { padding: 0; }

/* "Rules for this module:" and friends act as section headings. */
.ui-tooltip u {
	display: block;
	margin: var(--sp-3) 0 var(--sp-1) 0;
	padding-top: var(--sp-3);
	border-top: 1px solid color-mix(in srgb, currentColor 15%, transparent);
	text-decoration: none;
	font-size: 0.6875rem;
	font-weight: 620;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	opacity: 0.65;
}
.ui-tooltip u:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
/* Labels lead, values follow -- they were previously indistinguishable. */
.ui-tooltip b, .ui-tooltip strong { font-weight: 600; }
.ui-tooltip br + b, .ui-tooltip br + strong { display: inline-block; margin-top: 1px; }
.ui-tooltip hr { margin: var(--sp-2) 0; border-color: color-mix(in srgb, currentColor 15%, transparent); }
.ui-tooltip .fa, .ui-tooltip [class*="fa-"] { margin-right: var(--sp-1); opacity: 0.7; }

/* Dolibarr toggles an .open class rather than inline styles, so the closed
   state must live in CSS or every dropdown renders permanently expanded. */
.dropdown { position: relative; }
.dropdown-menu, .dropdown-search, .dropdown-bookmark, .dropdown-quickadd { display: none; }
.open > .dropdown-menu, .open > .dropdown-search, .open > .dropdown-bookmark,
.open > .dropdown-quickadd, .dropdown dd ul.open { display: block; }
.dropdown-menu {
	position: absolute; right: 0; top: calc(100% + var(--sp-1));
	min-width: 260px; padding: var(--sp-2); margin: 0;
	background: var(--c-surface); border: 1px solid var(--c-border);
	border-radius: var(--r-lg); box-shadow: var(--sh-lg);
	list-style: none; color: var(--c-ink); z-index: 1500;
}
.dropdown-menu a, .dropdown-item { display: block; padding: var(--sp-2) var(--sp-3); border-radius: var(--r); color: var(--c-ink-2); }
.dropdown-menu a:hover, .dropdown-item:hover { background: var(--c-sunken); color: var(--c-ink); }
.dropdown-menu > .user-header { text-align: center; padding: var(--sp-4) var(--sp-3); border-bottom: 1px solid var(--c-hairline); }
.dropdown-menu > .user-footer { border-top: 1px solid var(--c-hairline); display: flex; justify-content: space-between; gap: var(--sp-2); padding: var(--sp-2); }
.dropdown-menu > .user-body, .dropdown-body { padding: var(--sp-2); max-height: 70vh; overflow: auto; }
.dropdown-user-image, .user-header img { width: 72px; height: 72px; border-radius: 50%; object-fit: cover; border: 2px solid var(--c-border); }

/* The dl/dt/dd "selected fields" picker is a separate widget with its own
   open mechanism, and also needs an explicit closed state. */
dl.dropdown { display: inline-block; margin: 0 2px; padding: 0; vertical-align: middle; }
.dropdown dd, .dropdown dt { margin: 0; padding: 0; }
.dropdown dd { position: relative; }
.dropdown dt a { display: block; overflow: hidden; border: 0; cursor: pointer; }
.dropdown span.value { display: none; }
.dropdown dd ul {
	display: none; position: absolute; top: 2px; right: 0; z-index: 95;
	min-width: 220px; max-height: 300px; overflow: auto; margin: 0; padding: var(--sp-1);
	list-style: none; background: var(--c-surface); border: 1px solid var(--c-border);
	border-radius: var(--r); box-shadow: var(--sh-lg);
}
.dropdown dd ul.selectedfieldsleft { right: auto; left: 0; }
.dropdown dd ul li {
	display: flex; align-items: center; gap: var(--sp-2);
	padding: var(--sp-2); border-radius: var(--r-sm); white-space: nowrap; color: var(--c-ink-2);
}
.dropdown dd ul li:hover:not(.liinputsearch) { background: var(--c-sunken); }
input.inputsearch_dropdownselectedfields { width: 100%; }

.select2-container--default .select2-selection--single,
.select2-container--default .select2-selection--multiple {
	background: var(--inputbackgroundcolor);
	border: 1px solid var(--inputbordercolor) !important;
	border-radius: var(--r) !important; min-height: 32px;
}
.select2-container--default .select2-selection--single .select2-selection__rendered { color: var(--c-ink); line-height: 30px; padding-left: var(--sp-2); }
.select2-container--default .select2-selection--single .select2-selection__arrow { height: 30px; }
.select2-container--default.select2-container--focus .select2-selection--single,
.select2-container--default.select2-container--open .select2-selection--single {
	border-color: var(--c-accent) !important; box-shadow: 0 0 0 3px var(--c-accent-ring);
}
.select2-dropdown { background: var(--c-surface); border: 1px solid var(--c-border); border-radius: var(--r); box-shadow: var(--sh-lg); color: var(--c-ink); }
.select2-container--default .select2-results__option { padding: var(--sp-2) var(--sp-3); color: var(--c-ink-2); }
.select2-container--default .select2-results__option--highlighted { background: var(--c-accent-soft) !important; color: var(--c-accent-ink) !important; }
.select2-container--default .select2-selection--multiple .select2-selection__choice {
	background: var(--c-accent-soft); border: 1px solid color-mix(in srgb, var(--c-accent) 26%, transparent);
	border-radius: var(--r-sm); color: var(--c-accent-ink); padding: 1px var(--sp-2);
}

/* Stacking. jQuery UI hands the dialog and its overlay z-index 101/100, which was
   sufficient against eldy's static chrome but sits far below the fixed shells here
   (the bars and rails run 1200-1400): the dialog opened *underneath* the top bar and
   the sidebar, its title clipped, and the scrim failed to dim the chrome it covered.
   jQuery writes that z-index inline, so this has to be !important to win. */
.ui-widget-overlay { z-index: 2400 !important; }
.ui-dialog { z-index: 2500 !important; }

.ui-dialog {
	background: var(--c-surface); border: 1px solid var(--c-border);
	border-radius: var(--r-lg); box-shadow: var(--sh-lg); font-family: var(--c-font); padding: 0;
}
.ui-dialog .ui-dialog-titlebar { background: transparent; border: 0; border-bottom: 1px solid var(--c-hairline); padding: var(--sp-3) var(--sp-4); font-weight: 600; color: var(--c-ink); }
.ui-dialog .ui-dialog-content { padding: var(--sp-4); color: var(--c-ink); }
.ui-dialog .ui-dialog-buttonpane { border: 0; border-top: 1px solid var(--c-hairline); padding: var(--sp-3) var(--sp-4); margin: 0; }
.ui-widget-overlay { background: rgba(11, 18, 32, 0.4); opacity: 1; }
.ui-datepicker {
	background: var(--c-surface); border: 1px solid var(--c-border); border-radius: var(--r-lg);
	box-shadow: var(--sh-lg); padding: var(--sp-2); font-family: var(--c-font);
	/* Above .ui-dialog (2500): date fields inside a dialog would otherwise drop
	   their calendar behind it. */
	font-size: 0.75em; z-index: 2600 !important;
}
.ui-datepicker .ui-datepicker-header { background: transparent; border: 0; color: var(--c-ink); font-weight: 600; }
.ui-datepicker td a, .ui-datepicker td span { text-align: center; border-radius: var(--r-sm); padding: var(--sp-1); color: var(--c-ink-2); border: 0; background: transparent; }
.ui-datepicker td a:hover { background: var(--c-sunken); }
.ui-datepicker .ui-state-active { background: var(--c-accent) !important; color: #fff !important; }
.ui-datepicker td.ui-datepicker-today a { background: var(--c-accent-soft); color: var(--c-accent-ink); font-weight: 600; }
.ui-progressbar, .progress { height: 8px; background: var(--c-sunken); border: 0; border-radius: var(--r-pill); overflow: hidden; }
.ui-progressbar .ui-progressbar-value, .progress-bar { background: var(--c-accent); border: 0; border-radius: var(--r-pill); margin: 0; height: 100%; }


/* ==========================================================================
   Login
   ========================================================================== */

/* Dolibarr paints the login backdrop with an inline background on
   .login_center, so that element must stay full-width; making <body> a flex
   container shrinks it to the form width and the backdrop paints as a stripe. */
body.bodylogin { display: block; min-height: 100vh; background: var(--c-canvas); }
div.login_center {
	display: flex; align-items: center; justify-content: center;
	width: 100%; min-height: 100vh;
	background-color: transparent !important;
	background-image:
		radial-gradient(900px 520px at 50% -10%, var(--c-accent-soft), transparent 70%),
		linear-gradient(180deg, var(--c-canvas), var(--c-canvas)) !important;
	background-repeat: no-repeat !important;
	background-size: cover !important;
}
div.login_vertical_align { width: 100%; }
form#login {
	width: 100%; max-width: 400px; margin: 0 auto; padding: var(--sp-6);
	background: var(--c-surface); border: 1px solid var(--c-border);
	border-radius: var(--r-xl); box-shadow: var(--sh-md);
}
/* The logo ships at its natural size and bursts the card without this. */
#img_logo, #login_left img { max-width: 100%; height: auto; display: block; margin: 0 auto var(--sp-4) auto; }
#login_left { text-align: center; }
div.login_table { width: 100%; background: transparent; border: 0; padding: 0; }
#login .tagtable { display: table; width: 100%; }
#login .trinputlogin { display: table-row; }
#login .tagtd, #login .tdinputlogin { display: table-cell; padding: var(--sp-1) 0; vertical-align: middle; }
#login .tagtd.center:first-child { width: 26px; color: var(--c-muted); }
#login .trinputlogin input { width: 100%; height: 36px; }
.login_table_title { text-align: center; color: var(--c-muted); font-size: 0.75em; padding-bottom: var(--sp-3); }
input.butActionLogin { width: 100%; height: 38px; margin: var(--sp-3) 0 0 0; font-weight: 620; }
.login_main_home { text-align: center; color: var(--c-muted); font-size: 0.75em; margin-top: var(--sp-4); }


/* ==========================================================================
   Responsive and print
   ========================================================================== */

@media only screen and (max-width: 992px) {
	.fiche { padding: var(--sp-4); }
	:root { --nav-w: var(--nav-w-collapsed); }
	.cmd-nav-label, .cmd-nav-sub, .cmd-nav-toggle-label { display: none; }
	.cmd-nav-link { justify-content: center; padding-left: 0; padding-right: 0; }
	.cmd-brand-text, .cmd-crumbs { display: none; }
	.cmd-trigger { min-width: 0; flex: 1; }
	.fichehalfleft, .fichehalfright, .fichethirdleft, .fichetwothirdright { float: none; width: 100%; }
}
@media only screen and (max-width: 767px) {
	div.tabBar { padding: var(--sp-3); }
	.boxhalfleft, .boxhalfright, .box-flex-item { float: none; width: 100%; min-width: 100%; }
	.hideonsmartphone { display: none !important; }
	.cmd-trigger-label, .cmd-kbd { display: none; }
	.cmd-palette-panel { margin-top: var(--sp-4); }
}
@media print {
	header.cmd-bar, .cmd-palette, div.tabsAction, .noprint { display: none !important; }
	.fiche { padding: 0; max-width: none; }
	body { background: #fff; }
}
@media (prefers-reduced-motion: reduce) {
	*, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}



/* ---- Hit areas ----
   Dolibarr emits several controls as bare inline links, which leaves them a
   few pixels tall and awkward to hit. These are the ones that matter on
   every list screen. */

/* Column sort links: make the whole header cell clickable, not just the text. */
tr.liste_titre th a.reposition, tr.liste_titre td a.reposition,
th.liste_titre a.reposition, .liste_titre a.reposition {
	display: inline-flex;
	align-items: center;
	min-height: 28px;
	padding: 0 var(--sp-1);
	margin: 0 calc(var(--sp-1) * -1);
	border-radius: var(--r-sm);
	transition: background var(--t), color var(--t);
}
tr.liste_titre th a.reposition:hover { background: var(--c-surface); }

/* Field-picker, help and other single-glyph triggers. */
a.multiselectpicto, a.help, a.butActionRefused.help,
.divsearchfield > a, .liste_titre .fa-cog {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 24px;
	min-height: 24px;
	border-radius: var(--r-sm);
	transition: background var(--t), color var(--t);
}
a.multiselectpicto:hover, a.help:hover { background: var(--c-sunken); color: var(--c-ink); }

/* Row checkboxes sit in a wide cell; give them a comfortable target. */
input.checkallactions, td.nowrap input[type="checkbox"] {
	width: 16px;
	height: 16px;
	cursor: pointer;
}


/* ---- Stragglers found by the page-by-page audit ---- */

/* Datepicker "now"/"today" shortcuts ship as bare <button>, so they render
   with the browser's stock outset border unless the theme claims them. */
button.dpInvisibleButtons, .dpInvisibleButtons {
	display: inline-flex;
	align-items: center;
	height: 24px;
	padding: 0 var(--sp-2);
	margin-left: var(--sp-1);
	background: var(--c-sunken);
	border: 1px solid var(--c-border);
	border-radius: var(--r-sm);
	color: var(--c-muted);
	font-family: inherit;
	font-size: 0.75em;
	line-height: 1;
	cursor: pointer;
	transition: background var(--t), color var(--t), border-color var(--t);
}
button.dpInvisibleButtons:hover {
	background: var(--c-surface);
	border-color: var(--c-border-strong);
	color: var(--c-ink);
}

/* Agenda/list cells stack several tooltip links; without a min-height the
   line boxes collide and the links physically overlap each other. */
td .classforajaxtooltip, td .classfortooltip {
	display: inline-block;
	max-width: 100%;
	vertical-align: middle;
	overflow: hidden;
	text-overflow: ellipsis;
}
td.tdoverflowmax100 .classforajaxtooltip,
td.tdoverflowmax125 .classforajaxtooltip,
td.tdoverflowmax150 .classforajaxtooltip,
td.tdoverflowmax200 .classforajaxtooltip { white-space: nowrap; }


/* ==========================================================================
   Narrow viewports
   Dolibarr lays its edit forms out as 4-column tables (label | field | label |
   field). Below tablet width the second pair is pushed off-screen entirely,
   so the cells are unwound into stacked rows. List tables are excluded --
   they stay tabular and scroll horizontally inside their container.
   ========================================================================== */

@media only screen and (max-width: 767px) {
	table.border:not(.liste), table.tableforfield:not(.liste),
	div.tabBar table.border, div.tabBar table.tableforfield {
		display: block;
		width: 100%;
	}
	table.border:not(.liste) > tbody,
	table.tableforfield:not(.liste) > tbody { display: block; width: 100%; }

	table.border:not(.liste) > tbody > tr,
	table.tableforfield:not(.liste) > tbody > tr {
		display: block;
		width: 100%;
		padding: var(--sp-2) 0;
		border-bottom: 1px solid var(--c-hairline);
	}
	table.border:not(.liste) > tbody > tr > td,
	table.tableforfield:not(.liste) > tbody > tr > td {
		display: block;
		width: 100% !important;
		max-width: 100% !important;
		padding: 2px 0;
		border: 0;
	}
	/* Labels read as captions above their field. */
	table.border:not(.liste) td.titlefield,
	table.border:not(.liste) td.titlefieldcreate,
	table.tableforfield:not(.liste) td.titlefield {
		font-size: 0.75em;
		font-weight: 600;
		color: var(--c-muted);
	}
	/* Fields fill the row rather than keeping their desktop pixel widths. */
	table.border:not(.liste) input[type="text"],
	table.border:not(.liste) input[type="email"],
	table.border:not(.liste) input[type="password"],
	table.border:not(.liste) textarea,
	table.border:not(.liste) select,
	table.border:not(.liste) td:not(.ts-measure-cell) .select2-container {
		width: 100% !important;
		max-width: 100% !important;
		min-width: 0 !important;
	}
	/* Action rows keep buttons reachable without horizontal scrolling. */
	div.tabsAction { justify-content: stretch; }
	div.tabsAction .butAction,
	div.tabsAction .butActionDelete,
	div.tabsAction .butActionRefused { flex: 1 1 auto; justify-content: center; }
}


/* Icon-only action links inside cards and module tiles are bare inline <a>
   elements; without a min box they are a few pixels tall. */
.fiche a.valignmiddle:not(.butAction):not(.button),
div.info-box a.valignmiddle {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 22px;
	min-width: 18px;
}
/* Not inside truncating cells: inline-flex defeats text-overflow, so the
   label was hard-cut mid-word and its icon clipped instead of ellipsised. */
.fiche [class*="tdoverflowmax"] a.valignmiddle:not(.butAction):not(.button),
.fiche .tdoverflow a.valignmiddle:not(.butAction):not(.button),
[class*="tdoverflowmax"] a.valignmiddle,
.tdoverflow a.valignmiddle {
	display: inline;
	min-height: 0;
	min-width: 0;
}


/* ==========================================================================
   Setup-form furniture
   Found by reading the Display and Translation screens at full size rather
   than in a scaled contact sheet.
   ========================================================================== */

/* Section headers inside edit tables are a liste_titre row carrying a single
   label. As list-header styling they read as an empty grey band. */
table.editmode > tbody > tr.liste_titre > td,
table.tableforfield > tbody > tr.liste_titre > td {
	padding: var(--sp-3) var(--sp-4);
	background: var(--c-sunken);
	font-size: 0.9375rem;
	font-weight: 620;
	color: var(--c-ink);
	text-transform: none;
	letter-spacing: -0.008em;
	border-bottom: 1px solid var(--c-border);
}

/* Dolibarr drops the Save/Cancel row straight after the table with no gap,
   so the buttons collided with the block above. */
div.tabBar div.center,
div.tabBar > .center,
form div.tabBar + div.center {
	margin-top: var(--sp-5);
	margin-bottom: var(--sp-3);
}
div.tabBar div.center .button,
div.tabBar div.center input.button { margin: 0 var(--sp-1); }

/* The colour-picker trigger sat flush against the field's right edge. */
a.colorpickerlink, .colorpicker, td .fa-pencil-alt, td .fa-edit,
input.colorthis + a, input[name^="THEME_"] + a {
	margin-left: var(--sp-2);
	margin-right: var(--sp-2);
	display: inline-flex;
	align-items: center;
	min-height: 22px;
}
/* Breathing room before the "Default: xxxxxx" hint that follows. */
td input[name^="THEME_"] ~ span,
td .opacitymedium + b { margin-left: var(--sp-1); }

/* The rows-per-page select is capped at 75px by Dolibarr; the theme's chevron
   padding then clipped the number inside it. */
div.pagination select.selectlimit,
select.selectlimit {
	min-width: 58px;
	padding-left: var(--sp-2);
	padding-right: var(--sp-4);
	background-position: right 4px center;
	background-size: 11px;
	text-align: left;
}
div.pagination ul { flex-wrap: nowrap; }
div.pagination li { flex: 0 0 auto; }

/* Dashboard tiles: each card sized to its own content, so a one-line tile sat
   visibly shorter than the two-line tile beside it. */
.box-flex-container { align-items: stretch; }
.box-flex-item, .box-flex-item-with-margin { display: flex; }
.box-flex-item > *, .box-flex-item-with-margin > * { width: 100%; }
div.info-box { height: 100%; }

/* A picker with nothing left to offer (e.g. "add widget" once every widget is
   already on the dashboard) leaves Dolibarr's greyed placeholder as the only
   row, holding a single space -- so it rendered as a blank highlighted box.
   :empty cannot match a whitespace node, hence the class hook. */
.select2-results__options > .select2-results__option.optiongrey:only-child {
	font-size: 0;
	background: transparent !important;
	cursor: default;
}
.select2-results__options > .select2-results__option.optiongrey:only-child::after {
	content: "Aucun";
	display: block;
	padding: var(--sp-3) var(--sp-2);
	text-align: center;
	/* rem, not em: the parent is font-size:0 to hide its whitespace node, and
	   an em value would resolve against that zero. */
	font-size: 0.8125rem;
	color: var(--c-faint);
}
.select2-results__option.optiongrey { color: var(--c-faint); }


/* Dolibarr nests a small table inside some label cells to hang an edit pencil
   beside the text. Its first cell collapsed to ~59px, so labels such as
   "Third-party type" broke across three lines at the hyphen. */
td.titlefield table td:first-child,
.tableforfield td table td:first-child,
.fichehalfleft td table td:first-child,
.fichehalfright td table td:first-child {
	width: auto;
	padding-left: 0;
}
td.titlefield table td:last-child,
.tableforfield td table td:last-child,
.fichehalfleft td table td:last-child,
.fichehalfright td table td:last-child {
	width: 1%;
	white-space: nowrap;
	vertical-align: top;
}
td.titlefield table, .tableforfield td table { width: 100%; }


/* Date-field calendar triggers ship as a bare 12x11 <img>, which is both an
   awkward target and visually unrelated to the field it opens. */
img.ui-datepicker-trigger, .ui-datepicker-trigger {
	width: auto;
	height: auto;
	min-width: 26px;
	min-height: 26px;
	padding: var(--sp-1);
	margin-left: calc(var(--sp-1) * -1);
	border-radius: var(--r-sm);
	cursor: pointer;
	opacity: 0.55;
	transition: opacity var(--t), background var(--t);
	vertical-align: middle;
}
img.ui-datepicker-trigger:hover, .ui-datepicker-trigger:hover {
	opacity: 1;
	background: var(--c-sunken);
}


/* ==========================================================================
   Rich-text editor (CKEditor)
   Dolibarr embeds CKEditor for every Description/Note field, and it arrives
   with its own 2010-era chrome. These rules bring the frame, toolbar and
   controls into the theme without touching the editor's own layout.
   ========================================================================== */

/* The frame carries a stronger border than a plain input. An editor is a
   region, not a field: it is often several hundred pixels tall and sits on
   rows that change colour on hover or when checked, and at input-border
   weight its outline disappeared into those backgrounds -- the editor read as
   loose furniture on the page rather than a bounded surface. The small shadow
   holds that separation on any row colour. */
.cke, .cke_chrome {
	border: 1px solid var(--c-border-strong) !important;
	border-radius: var(--r) !important;
	box-shadow: var(--sh-sm) !important;
	overflow: hidden;
	max-width: 100%;
}
.cke_inner { background: var(--c-surface) !important; }

/* Toolbar */
.cke_top {
	background: color-mix(in srgb, var(--c-sunken) 72%, var(--c-surface)) !important;
	border-bottom: 1px solid var(--c-hairline) !important;
	box-shadow: none !important;
	padding: var(--sp-2) var(--sp-2) var(--sp-1) !important;
}
.cke_toolgroup, .cke_combo_button {
	background: var(--c-surface) !important;
	border: 1px solid var(--c-hairline) !important;
	border-radius: var(--r-sm) !important;
	box-shadow: none !important;
	margin: 0 var(--sp-1) var(--sp-1) 0 !important;
}
.cke_toolgroup { padding: 1px !important; }
.cke_button_label { display: none !important; }
.cke_button {
	border-radius: var(--r-sm) !important;
	transition: background var(--t);
}
.cke_button:hover, .cke_button__:hover,
.cke_button_on, .cke_combo_button:hover {
	background: var(--c-surface) !important;
	border-color: var(--c-border) !important;
	box-shadow: none !important;
}
.cke_button_on { box-shadow: inset 0 0 0 1px var(--c-border) !important; }
.cke_combo_text {
	font-family: var(--c-font) !important;
	font-size: 0.75rem !important;
	color: var(--c-muted) !important;
}
.cke_toolbar_separator {
	background: var(--c-border) !important;
	margin: var(--sp-1) !important;
}

/* Editing surface and status bar */
.cke_contents { background: var(--c-surface) !important; }
.cke_bottom {
	background: var(--c-sunken) !important;
	border-top: 1px solid var(--c-hairline) !important;
	box-shadow: none !important;
	padding: var(--sp-1) var(--sp-2) !important;
}
.cke_path_item, .cke_path_empty {
	color: var(--c-faint) !important;
	font-family: var(--c-font) !important;
	font-size: 0.6875rem !important;
}
.cke_resizer { border-color: transparent var(--c-border-strong) transparent transparent !important; }

/* Focus ring on the whole frame, matching every other field. The border keeps
   full strength alongside the ring -- a ring on its own is a soft tint, and on
   a highlighted row it was the only thing marking the edge. */
.cke_focus, .cke_chrome:focus-within {
	border-color: var(--c-accent) !important;
	box-shadow: 0 0 0 3px var(--c-accent-ring), var(--sh-sm) !important;
}

/* Text selection inside the editor. The browser default is an opaque blue
   that buries the text it covers, which is what made a highlighted block look
   like the editor had gone. A tint keeps the words readable while selected.
   Only reaches the editor when it renders inline (divarea); in iframe mode the
   editing surface is a separate document and CKEditor styles it from its own
   contents.css, which a parent stylesheet cannot cross. */
.cke_editable ::selection, .cke_editable::selection,
.cke_contents ::selection {
	background: var(--c-accent-soft);
	color: var(--c-ink);
}

/* Dropdown panels the toolbar opens (Styles, Format, colours). */
.cke_panel {
	border: 1px solid var(--c-border) !important;
	border-radius: var(--r) !important;
	box-shadow: var(--sh-lg) !important;
}
.cke_panel_list, .cke_panel_block { background: var(--c-surface) !important; }
.cke_panel_listItem a { color: var(--c-ink-2) !important; }
.cke_panel_listItem a:hover, .cke_panel_listItem.cke_selected a {
	background: var(--c-accent-soft) !important;
	color: var(--c-accent-ink) !important;
}


/* ==========================================================================
   Agenda
   ========================================================================== */

/* View switcher. Dolibarr emits <a class="btnTitle"><icon><label></a> in a
   row with no separation, so each icon appeared to belong to the label before
   it. Grouping them as a segmented control makes the pairing unambiguous. */
div.navmode {
	display: inline-flex;
	align-items: center;
	gap: 2px;
	padding: 3px;
	background: var(--c-sunken);
	border: 1px solid var(--c-hairline);
	border-radius: var(--r);
}
div.navmode a.btnTitle {
	display: inline-flex;
	align-items: center;
	gap: var(--sp-2);
	padding: 5px var(--sp-3);
	border-radius: var(--r-sm);
	color: var(--c-muted);
	font-size: 0.75em;
	white-space: nowrap;
	transition: background var(--t), color var(--t);
}
div.navmode a.btnTitle:hover { background: var(--c-surface); color: var(--c-ink); }
div.navmode a.btnTitleSelected {
	background: var(--c-surface);
	color: var(--c-accent-ink);
	font-weight: 620;
	box-shadow: var(--sh-sm);
}

/* Per-day "add event" control. At full strength it competed with the dates in
   every empty cell; quiet at rest, obvious on hover, and still reachable by
   keyboard and touch. */
td a.btnTitlePlus {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 24px;
	height: 24px;
	border-radius: var(--r-sm);
	color: var(--c-faint);
	opacity: 0.35;
	transition: opacity var(--t), background var(--t), color var(--t);
}
td:hover > a.btnTitlePlus,
tr:hover a.btnTitlePlus { opacity: 1; }
td a.btnTitlePlus:hover, td a.btnTitlePlus:focus-visible {
	opacity: 1;
	background: var(--c-accent-soft);
	color: var(--c-accent);
}

/* Calendar grid: keep day cells readable and the date anchored top-left. */
table.cal_month td, td.cal_current_month, td.cal_other_month {
	vertical-align: top;
}
td.cal_other_month { background: var(--c-sunken); }
td.cal_today, td.cal_today_am, td.cal_today_pm {
	background: var(--c-accent-soft) !important;
	box-shadow: inset 0 2px 0 var(--c-accent);
}


/* ---- Destructive submits ----
   Dolibarr renders irreversible bulk actions (Purge, mass delete) as a plain
   `input.button`, visually identical to Cancel. The form path is the reliable
   signal; the value match is a best-effort extra that only applies on
   English installs and can never make a non-destructive button look worse. */
form[action*="purge.php"] input[type="submit"].button,
form[action*="delete"] input[type="submit"].button,
input[type="submit"].button[value*="Purge" i],
input[type="submit"].button[value*="Delete" i] {
	background: var(--c-surface);
	border-color: color-mix(in srgb, var(--c-danger) 40%, transparent);
	color: var(--c-danger);
	font-weight: 600;
}
form[action*="purge.php"] input[type="submit"].button:hover,
form[action*="delete"] input[type="submit"].button:hover,
input[type="submit"].button[value*="Purge" i]:hover,
input[type="submit"].button[value*="Delete" i]:hover {
	background: var(--c-danger);
	border-color: var(--c-danger);
	color: #fff;
}


/* The record banner's picto sits in a floated column that pushed the title
   45px right of the fields beneath it. Tightening the gutter brings the two
   left edges close enough to read as aligned; the picto itself is Dolibarr's
   markup and keeping it preserves the record-type cue. */
div.arearef { position: relative; }
/* The picto column is the floated block WITHOUT .valignmiddle (that class marks
   the title block beside it). Lifting it into the card's padding gutter puts
   the record title on the same left edge as the fields below. Real photos
   (.divphotoref, product/user avatars) keep their place in the flow. */
/* Previously pulled to -30px so the record title shared a left edge with the
   fields below. That bought alignment with the table underneath at the cost of
   the picto hanging outside the card's content, detached from the record it
   labels. Reverted to normal flow: the icon reads as part of the heading,
   which is the relationship that actually matters here. */
div.arearef div.inline-block.floatleft:not(.valignmiddle):not(.divphotoref):not(:has(img)) {
	position: static;
	width: auto;
	margin: 0 var(--sp-2) 0 0;
	display: inline-flex;
	align-items: center;
}
div.arearef .refid, div.arearef .refidno { margin-left: 0; }
div.arearef img.photoref, div.arearef .divphotoref { margin-right: var(--sp-4); }


/* ---- Avatars in tables ----
   Dolibarr emits user photos at their stored size (128x128), so a single
   avatar inflated an events row to ~130px tall. Table context wants a
   thumbnail; the record banner keeps the large photo. */
td img.userphoto, td img.photouserphoto,
td img.photoref, td img.photo {
	width: 28px;
	height: 28px;
	min-width: 28px;
	border-radius: 50%;
	object-fit: cover;
	vertical-align: middle;
}
/* Slightly larger where the cell is the record's own portrait column. */
td.center > img.userphoto, td.photo img.userphoto { width: 34px; height: 34px; min-width: 34px; }
/* The banner portrait is deliberately large and must not be caught above. */
div.arearef img.userphoto, div.arearef img.photoref,
.divphotoref img { width: auto; height: auto; min-width: 0; border-radius: var(--r); }

/* The account avatar lives in the top-bar / rail login dropdown, not a table
   cell, so the thumbnail rules above never reach it and Dolibarr renders it at
   its stored size (up to 80-128px) — towering over the ~52px bar. Constrain it
   to a small round thumbnail wherever the account block lands. */
#topmenu-login-dropdown img.photouserphoto,
#topmenu-login-dropdown img.userphoto,
.login-dropdown-a img.photouserphoto, .login-dropdown-a img.userphoto,
.atoplogin img.photouserphoto, .atoplogin img.userphoto {
	width: 28px;
	height: 28px;
	min-width: 28px;
	border-radius: 50%;
	object-fit: cover;
	vertical-align: middle;
}

/* ---- Leading field pictos ----
   Dolibarr prefixes many fields with a bare icon and no spacing, so the glyph
   sat flush against the input's border. The gap goes on the field rather than
   the icon so it applies however the icon is marked up. */
td span[class*="fa-"] + input,
td span[class*="fa-"] + select,
td span[class*="fa-"] + textarea,
td span[class*="fa-"] + .select2-container,
td span[class*="fa-"] ~ .select2-container,
td span.pictofixedwidth ~ .select2-container,
td img.pictofixedwidth + input,
td img.pictofixedwidth + .select2-container,
td span.pictofixedwidth + input,
td span.pictofixedwidth + .select2-container {
	margin-left: var(--sp-2);
}


/* The status badge floats directly beneath the back/prev/next row with no gap
   (both end and start at the same y), so the two collided visually even though
   their right edges line up. */
div.arearef div.statusref { margin-top: var(--sp-2); }
div.arearef .paginationref { margin-bottom: var(--sp-1); }
/* Prev/next arrows are bare links; give them a real target and hover box so
   the hovered one does not look like a stray highlighted glyph. */
.paginationref a, div.pagination .paginationafterarrows a, div.pagination .paginationbeforearrows a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 26px;
	height: 26px;
	border-radius: var(--r-sm);
	color: var(--c-muted);
	transition: background var(--t), color var(--t);
}
.paginationref a:hover { background: var(--c-sunken); color: var(--c-ink); }


/* ---- Trailing pictos ----
   Icons that follow a value (copy-to-clipboard, warning, external link) are
   emitted with no spacing at all, so they sit flush against the text and each
   other. The earlier rule only covered icons that PRECEDE a field.
   :first-child is exempt so a leading picto keeps its original position --
   text nodes are not elements, so the icon after a bare value is not first. */
td span[class*="fa-"], td a[class*="fa-"], td i[class*="fa-"],
td .clipboardCPButton, td .clipboardCPButtonInfo {
	margin-left: var(--sp-2);
}
/* :first-child counts elements only, so a glyph that FOLLOWS a text value
   still matches -- which is how a warning triangle emitted after
   "utf8mb4_unicode_ci" got its gap stripped and collided with the value. The
   status pictos are always trailing marks, so they are exempt from the reset;
   the rest (a genuine leading icon) still start flush. */
td > span[class*="fa-"]:first-child:not([class*="pictowarning"]):not([class*="pictoerror"]):not([class*="pictodanger"]):not([class*="pictostatus"]),
td > a[class*="fa-"]:first-child,
td > i[class*="fa-"]:first-child,
td > span.pictofixedwidth:first-child { margin-left: 0; }

/* Same story in the record banner, where the ref is followed by action icons. */
div.arearef .clipboardCPButton,
div.arearef span[class*="fa-"]:not(:first-child) { margin-left: var(--sp-2); }


/* ==========================================================================
   Module cards (admin/modules.php)
   ========================================================================== */

/* Module logos ship at their source size -- object_paypal.png is 256x256 and
   single-handedly stretched its card to ~900px tall, squeezing the text into
   a one-word column. Every module image is normalised to an icon. */
.box-flex-item img, .box-flex-item-with-margin img,
div.info-box img, .modulebox img {
	max-width: 34px;
	max-height: 34px;
	width: auto;
	height: auto;
	object-fit: contain;
	vertical-align: middle;
}

/* Cards in a row must share a height, and their footer (gear + toggle) must
   sit on a common baseline regardless of how long the description runs. */
.box-flex-container { align-items: stretch; }
.box-flex-item, .box-flex-item-with-margin { display: flex; align-items: stretch; }
.box-flex-item > *, .box-flex-item-with-margin > * { width: 100%; }
.box-flex-item .info-box, .box-flex-item-with-margin .info-box {
	height: 100%;
	display: flex;
	flex-direction: column;
}
.box-flex-item .info-box-content, .box-flex-item-with-margin .info-box-content {
	flex: 1 1 auto;
	display: flex;
	flex-direction: column;
}
/* The action row is pinned to the bottom of the card. */
.box-flex-item .info-box-more, .box-flex-item .info-box-actions,
.box-flex-item-with-margin .info-box-more {
	margin-top: auto;
	padding-top: var(--sp-2);
}


/* Dolibarr's "no image yet" placeholder ships at 100x100 (same in eldy) and
   reads as an unexplained camera glyph next to the upload control. Smaller,
   muted and framed so it registers as an empty preview slot. */
img[src*="nophoto"], img[src*="nophoto.png"] {
	width: 56px;
	height: 56px;
	padding: var(--sp-2);
	border: 1px dashed var(--c-border);
	border-radius: var(--r);
	background: var(--c-sunken);
	opacity: 0.45;
	object-fit: contain;
	vertical-align: middle;
}


/* ---- jQuery treeview (menu editor, category trees) ----
   The plugin draws its hierarchy with bitmap backgrounds: a dotted GIF tiled
   down each <li> for the guide line, and a 16x16 sprite sheet shifted by
   background-position for the +/- control. Both are fixed-size, fixed-colour
   and stuck at a 16px indent, so the tree ignored the theme entirely and the
   control never lined up with the row text beside it.

   Everything below replaces the bitmaps with CSS so the tree inherits the
   theme's ink, spacing and hit-target sizes. */

ul.treeview, ul.treeview ul {
	margin: 0;
	padding: 0;
	list-style: none;
	background-image: none;		/* the tiled dotted GIF */
}
ul.treeview { margin-top: var(--sp-1); padding-left: 24px; }

/* Nested levels: one continuous hairline instead of the dotted tile. */
/* The indent has to clear the chevron, not just the text. The control is
   positioned 20px left of its row, so at an 18px indent it landed within a
   pixel of the guide line and punched a hole in it at every branch -- the line
   read as a column of disconnected stubs rather than one rail. 30px puts the
   chevron clear of the line with room to spare. */
ul.treeview ul {
	margin-left: 11px;
	padding-left: 30px;
	/* No border here: a border on the list spans its whole height, so the rail
	   kept descending past the final entry -- pointing at children that do not
	   exist. Drawn per row instead (below) so the last one can stop. */
}
/* The rail is a segment on each row, full height for every row except the
   last, which stops where its own elbow meets it. */
ul.treeview ul > li::after {
	content: "";
	position: absolute;
	left: -30px;
	top: 0;
	bottom: 0;
	width: 1px;
	background: var(--c-border);
}
ul.treeview ul > li:last-child::after {
	bottom: auto;
	height: 23px;		/* meets the elbow at top:22px */
}

/* The class-qualified selectors are not redundant. The plugin sets its elbow
   bitmap in `.treeview li.lastExpandable` and friends, which outranks a plain
   `ul.treeview li`, so the GIF survived on precisely the last child of each
   branch -- a stray box floating above those labels while every other row was
   clean. Each variant has to be matched at its own weight. */
ul.treeview li,
ul.treeview li.last,
ul.treeview li.expandable, ul.treeview li.collapsable,
ul.treeview li.lastExpandable, ul.treeview li.lastCollapsable {
	position: relative;
	margin: 0;
	padding: 0;
	background-image: none;		/* per-item elbow GIF */
	min-height: 0;
}
/* Same problem on the control: `.treeview .expandable-hitarea` is stronger
   than `ul.treeview div.hitarea`. */
ul.treeview div.hitarea,
ul.treeview div.expandable-hitarea, ul.treeview div.collapsable-hitarea,
ul.treeview div.lastExpandable-hitarea, ul.treeview div.lastCollapsable-hitarea {
	background-image: none;
}

/* Each row is a full table; give it a real hit area and a hover state so the
   tree reads as a list of targets rather than a wall of links. */
ul.treeview li > table {
	border-radius: var(--r-sm);
	transition: background-color var(--t);
}
ul.treeview li > table:hover { background: var(--c-sunken); }
ul.treeview li > table > tbody > tr > td { padding: var(--sp-1) var(--sp-2); }
ul.treeview li > table strong.paddingleft { padding-left: 0; font-weight: 550; }
ul.treeview li a { color: var(--c-ink); }
ul.treeview li a:hover { color: var(--c-accent-ink); }

/* ---- The expand/collapse control ----
   Stock markup is an empty 16px div floated with a -16px margin, which put it
   above the row text rather than beside it. Positioned instead, so it stays
   centred on the row whatever the row height. */
ul.treeview div.hitarea {
	position: absolute;
	left: -20px;
	/* Centred on the row, not the row plus its expanded children: an open
	   branch is as tall as its whole subtree, so this is offset from the top
	   by half a row rather than positioned at 50%. */
	top: 9px;
	float: none;
	width: 22px;
	height: 26px;
	margin: 0;
	background-image: none;		/* the +/- sprite sheet */
	cursor: pointer;
	z-index: 1;
}
ul.treeview div.hitarea::before {
	content: "";
	position: absolute;
	top: 50%;
	left: 50%;
	width: 6px;
	height: 6px;
	margin: -4px 0 0 -4px;
	border-right: 1.6px solid var(--c-muted);
	border-bottom: 1.6px solid var(--c-muted);
	transform: rotate(-45deg);	/* collapsed: points right (left in RTL) */
	transition: transform var(--t), border-color var(--t);
}
ul.treeview li.collapsable > div.hitarea::before {
	margin-top: -6px;
	transform: rotate(45deg);	/* expanded: points down */
}
ul.treeview div.hitarea:hover::before { border-color: var(--c-accent); }

/* A leaf has no hitarea; keep its text on the same grid as its siblings by
   marking the branch point on the guide line instead. */
/* The elbow has to start ON the rail and stop short of the label, so it is
   measured from the same indent rather than a fixed guess -- at the old 18px
   it began 11px clear of the line and the branch looked detached. */
ul.treeview ul li:not(.expandable):not(.collapsable)::before {
	content: "";
	position: absolute;
	left: -30px;
	top: 22px;			/* vertical centre of a 44px row */
	width: 21px;
	height: 1px;
	background: var(--c-border);
}

/* Row action icons: the add/remove controls ship as 12px bitmaps and sat on
   the text baseline, half a line below the pencil beside them. */
ul.treeview img[src*="edit_add"], ul.treeview img[src*="edit_remove"] {
	width: 13px;
	height: 13px;
	vertical-align: middle;
	opacity: 0.6;
	transition: opacity var(--t);
}
ul.treeview a:hover img[src*="edit_add"],
ul.treeview a:hover img[src*="edit_remove"] { opacity: 1; }
ul.treeview span.menuEdit { color: var(--c-muted) !important; vertical-align: middle; }
ul.treeview a:hover span.menuEdit { color: var(--c-accent) !important; }

/* Disabled entries should read as inactive without becoming unreadable. */
ul.treeview li.liuserdisabled > table a { color: var(--c-muted); }


/* ---- Module / kanban card grid ----
   The container is a wrapping flexbox. `align-items: stretch` equalises the
   cards within a single row, but flexbox has no relationship between rows, so
   one long module description made its whole row 232px while every other row
   sat at 210px -- reading as cards of assorted sizes rather than a grid.

   Grid solves what flexbox structurally cannot: `grid-auto-rows: 1fr` sizes
   every row to the tallest card on the page, so the whole board is uniform.
   auto-fill with the same 300px floor keeps the existing wrap points. */
div.box-flex-container.kanban {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
	grid-auto-rows: 1fr;
	align-items: stretch;
}
div.box-flex-container.kanban > .box-flex-item {
	/* flex sizing is inert in grid; the card still lays its own contents out. */
	width: auto;
	max-width: none;
	margin: 0;
}


/* ---- Module card internals ----
   Dolibarr paints the "enabled" tint on .info-box-content, which is inset
   inside .info-box -- 332x208 within a 387x232 card. The result was a
   coloured rectangle floating in a white card with an uneven gutter around
   it, rather than a card that reads as switched on. The tint belongs on the
   card; the content then only has to fill it.

   The icon block is also laid out as a sibling column, so a 17px glyph
   rendered centred above copy that is left-aligned. Stacking the card makes
   both start on the same edge. */
div.box-flex-container.kanban .info-box {
	display: flex;
	flex-direction: column;
	align-items: stretch;
	height: 100%;
	overflow: hidden;
}
div.box-flex-container.kanban .info-box-icon {
	width: 100%;
	height: auto;
	padding: var(--sp-3) var(--sp-4) 0;
	text-align: left;
	background: transparent;
}
div.box-flex-container.kanban .info-box-content {
	width: 100%;
	flex: 1 1 auto;
	background: transparent !important;	/* the misplaced tint */
}
div.box-flex-container.kanban .info-box:has(.info-box-icon-module-enabled) {
	background: var(--infoboxmoduleenabledbgcolor);
	border-color: color-mix(in srgb, var(--c-accent) 30%, var(--c-border));
}

/* The info affordance sat on its own line between the description and the
   action row, orphaned in whitespace. It belongs beside the controls it
   relates to, on the card's baseline. */
div.box-flex-container.kanban .info-box-content > br { display: none; }
div.box-flex-container.kanban .info-box-more,
div.box-flex-container.kanban .info-box-actions {
	display: inline-flex !important;
	align-items: center;
	gap: var(--sp-2);
	padding-top: 0 !important;
	vertical-align: middle;
}
div.box-flex-container.kanban .info-box-content {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
}
/* Actions pinned to the bottom edge so every card's controls share one line. */
div.box-flex-container.kanban .info-box-actions { margin-top: auto; }
/* The content column stacks, so `more` and `actions` cannot share a row as
   siblings without a wrapper Dolibarr does not emit. Pinning the info
   affordance to the card corner puts it on the controls' line and gives every
   card the same footer regardless of how many lines the description ran to. */
div.box-flex-container.kanban .info-box { position: relative; }
div.box-flex-container.kanban .info-box-more {
	position: absolute;
	right: var(--sp-4);
	bottom: var(--sp-3);
	margin: 0;
}
div.box-flex-container.kanban .info-box-actions { order: 4; }
/* Keep the description clear of the pinned badge. */
div.box-flex-container.kanban .info-box-desc { padding-right: var(--sp-5); }


/* ---- Settings form field alignment ----
   Dolibarr puts an optional leading picto inside the value cell, so a row with
   an icon starts its input 27px further right than a row without one. Down a
   16-row form that produced a visibly ragged left edge on the controls -- the
   single most obvious thing wrong with the settings screens.

   Fixing it means reserving the picto gutter on every row, including the ones
   that have no picto. The icon gets a fixed box so the reservation is exact
   rather than dependent on which glyph happens to be used. */
/* The picto is lifted out of the text flow into a fixed gutter. While it was
   inline, a row's field position was the sum of the glyph's width plus every
   margin around it, so picto rows and plain rows drifted apart whenever any of
   those changed -- they were 4px and 12px out on the product form. Out of flow,
   both kinds of row start at exactly the cell's padding. */
div.tabBar table.border:not(.liste):not(.tableforfield) > tbody > tr > td:nth-child(even) > span[class*="fa-"]:first-child,
div.tabBar table.editmode:not(.liste):not(.tableforfield) > tbody > tr > td:nth-child(even) > span[class*="fa-"]:first-child {
	position: absolute;
	left: var(--sp-3);
	/* Aligned to the centre of the control beside it, not the top of the cell.
	   A 34px field inside this cell's padding centres 30px down, so a 16px
	   glyph starts at 22px -- at 14px it sat 8px high on every picto row. On a
	   tall row (a textarea) this keeps the icon on the first line, which is
	   where the label it marks actually is. */
	top: 22px;
	width: 19px;
	margin: 0;
	text-align: left;
}
/* Padding on the cell rather than an inline ::before spacer: a pseudo-element
   only pushes inline controls across, so block-level fields (textareas) broke
   to the next line and started back at the unpadded edge -- the exact ragged
   edge this is meant to remove. */
div.tabBar table.border:not(.liste):not(.tableforfield) > tbody > tr > td:nth-child(even),
div.tabBar table.editmode:not(.liste):not(.tableforfield) > tbody > tr > td:nth-child(even) {
	position: relative;
	padding-left: calc(var(--sp-3) + 27px);
}

/* Short fields were left at whatever `size` attribute the PHP passed, so the
   column's right edge stepped in and out row by row. A floor evens them up
   without forcing a postcode to be as wide as a street address -- fields that
   Dolibarr has explicitly marked narrow keep their intended size. */
/* Dolibarr caps individual fields with utility classes -- maxwidth150 on a
   phone, maxwidth300 on a web address -- sized for its own dense two-column
   card layout. On a full-width settings form those caps are what produced the
   stepped right edge, so inside these tables one shared measure wins over the
   per-field cap. The overrides beat the utility classes, hence !important. */
/* A fixed 420px measure left 411px of a 1194px form empty -- a third of the
   width doing nothing while every control huddled against the left edge. The
   fields now take the column they are in, with a cap so a single line of text
   never runs to an unreadable length. */
div.tabBar table.border:not(.liste) td > input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]):not([type="number"]):not(.button):not([class~="width25"]):not([class~="width50"]):not([class~="width75"]):not([class~="width100"]):not([class~="width125"]):not([class~="maxwidth50"]):not([class~="maxwidth75"]):not([class~="maxwidth100"]):not([class~="ts-measure"]),
div.tabBar table.editmode:not(.liste) td > input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]):not([type="number"]):not(.button):not([class~="width25"]):not([class~="width50"]):not([class~="width75"]):not([class~="width100"]):not([class~="width125"]):not([class~="maxwidth50"]):not([class~="maxwidth75"]):not([class~="maxwidth100"]):not([class~="ts-measure"]) {
	width: 100% !important;
	max-width: 760px !important;
	box-sizing: border-box;
}
/* Fields that hold a count, not a sentence. Stretching a "7 days" box to the
   full column made a two-character value look like a missing paragraph -- the
   width should suggest what belongs in it. */
div.tabBar table td > input[type="number"],
div.tabBar table td > input[class~="width25"],
div.tabBar table td > input[class~="width50"],
div.tabBar table td > input[class~="width75"],
div.tabBar table td > input[class~="width100"],
div.tabBar table td > input[class~="width125"],
div.tabBar table td > input[class~="maxwidth50"],
div.tabBar table td > input[class~="maxwidth75"],
div.tabBar table td > input[class~="maxwidth100"] {
	width: 110px !important;
	max-width: 110px !important;
	text-align: right;
	box-sizing: border-box;
}
/* Textareas take the same edge rather than a percentage of the table, which
   was what made them overhang every input above and below them. */
div.tabBar table.editmode:not(.liste) td > textarea,
div.tabBar table.border:not(.liste) td > textarea { width: 100%; max-width: 760px; box-sizing: border-box; }
div.tabBar table.editmode:not(.liste) td > .select2-container,
div.tabBar table.border:not(.liste) td:not(.ts-measure-cell):not(.ts-pair-cell) > .select2-container { width: 100% !important; max-width: 760px !important; }

/* Cells that pair a select with a second control -- Lead status carries a status
   dropdown and a win-probability percentage -- were stretching the select across
   the whole cell, which pushed its partner onto its own line. Give the select a
   share of the cell so the pair reads as the single field it is. Excluded from
   the full-width rule above rather than fighting its specificity. */
div.tabBar table.border:not(.liste) td.ts-pair-cell > .select2-container {
	width: 320px !important;
	max-width: calc(100% - 190px) !important;
	vertical-align: middle;
}
div.tabBar table.border:not(.liste) td.ts-pair-cell > input {
	vertical-align: middle;
}


/* ---- Dashboard widget cards ----
   Same mismatch as the module board: the icon block is laid out as its own
   centred column while the title and figures below it are left-aligned, so
   every card had its glyph floating off-axis from its own text. Aligning them
   to one edge is what makes a row of cards read as a set. */
/* The icon block is itself a flex container, so text-align does nothing to
   it -- the glyph is centred by the flex main axis and has to be moved with
   justify-content. */
div.box-flex-container > .box-flex-item .info-box-icon {
	display: flex;
	justify-content: flex-start;
	align-items: center;
	width: 100%;
	height: auto;
	/* No horizontal padding: the card already insets its content, and adding
	   more here pushed the glyph one step right of the title beneath it. */
	padding: var(--sp-3) 0 0;
	text-align: left;
	background: transparent;
}
div.box-flex-container > .box-flex-item .info-box {
	display: flex;
	flex-direction: column;
	align-items: stretch;
	height: 100%;
}
div.box-flex-container > .box-flex-item .info-box-content {
	width: 100%;
	flex: 1 1 auto;
	text-align: left;
}


/* ---- Action row hierarchy ----
   Dolibarr gives every enabled action the same .butAction class, so a record
   card commonly presents three or four equally-weighted filled buttons. With
   nothing to separate them the row reads as a wall and the action a user
   actually wants is no faster to find than the ones they don't.

   Dolibarr emits these in significance order -- the primary action first --
   so the first button keeps the filled treatment and the rest step down to
   outlined. Weight is expressed by fill, not colour, so the accent still means
   one thing on the page. Delete and disabled actions already have their own
   classes and are untouched. */
div.tabsAction .butAction:not(:first-of-type),
div.tabsAction a.butAction:not(:first-of-type),
div.tabsAction input.butAction:not(:first-of-type) {
	background: var(--c-surface);
	color: var(--c-accent-ink);
	border-color: var(--c-border);
	box-shadow: none;
}
div.tabsAction .butAction:not(:first-of-type):hover,
div.tabsAction a.butAction:not(:first-of-type):hover {
	background: var(--c-accent-soft);
	border-color: var(--c-accent);
	color: var(--c-accent-ink);
}


/* ---- Chrome label contrast ----
   The search trigger, the nav collapse control and the account name were all
   set in --c-faint, the lightest step of the neutral ramp. That step exists
   for non-essential marks like separators and disabled glyphs; used for real
   words at body size it measured 2.35:1 to 3.73:1 against the bar behind it,
   failing WCAG AA (4.5:1) in every one of the five shells.

   --c-muted is the lightest step intended to carry text. These labels name
   the controls they sit in, so they have to be readable, not decorative. */
.cmd-trigger, .cmd-trigger-label,
.cmd-nav-toggle, .cmd-nav-toggle-label {
	color: var(--c-muted);
}
/* The account name sits on the darkest bar of all, where --c-muted is still
   short of AA, so it takes the next step up. */
.atoplogin, .atoplogin span, .login-dropdown-a .hidden-xs { color: var(--c-ink-2); }
.cmd-trigger:hover, .cmd-trigger:hover .cmd-trigger-label,
.cmd-nav-toggle:hover { color: var(--c-ink-2); }
/* .wb-brand is deliberately excluded: it is a logo tile whose letter sits on
   an accent fill, not chrome text. Recolouring it to a neutral dropped it to
   1.45:1 -- worse than the 3.74:1 it started at. It is fixed in the theme. */


@media only screen and (max-width: 767px) {
	/* The shared 420px field measure has to be released on narrow screens.
	   max-width:100% does not clamp it: these tables use auto layout, so the
	   cell simply grows to fit its widest child and 100% then resolves to the
	   same 420px. Only an explicit width relative to the cell actually binds. */
	div.tabBar table.border:not(.liste) td > input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]):not(.button):not([class~="ts-measure"]),
	div.tabBar table.editmode:not(.liste) td > input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]):not(.button):not([class~="ts-measure"]),
	div.tabBar table.border:not(.liste) td > textarea,
	div.tabBar table.editmode:not(.liste) td > textarea {
		width: 100% !important;
		min-width: 0 !important;
	}
	div.tabBar table.border:not(.liste) td:not(.ts-measure-cell) > .select2-container,
	div.tabBar table.editmode:not(.liste) td > .select2-container {
		width: 100% !important;
		min-width: 0 !important;
	}
	/* The picto gutter is dead weight once rows stack. */
	div.tabBar table.border:not(.liste):not(.tableforfield) > tbody > tr > td:nth-child(even),
	div.tabBar table.editmode:not(.liste):not(.tableforfield) > tbody > tr > td:nth-child(even) {
		padding-left: var(--sp-3);
	}
}


/* ---- Anonymous user placeholder ----
   nophoto.png is only used for object photos. A user with no portrait gets
   user_anonymous.png (or user_man/user_woman), which Dolibarr ships at 128x128
   and renders at full size -- the oversized grey figure that dominated the
   user, member and product cards. It is a placeholder, not content, so it is
   sized and muted like one. The 28px dropdown avatar is left alone. */
/* The banner-portrait rule above (`div.arearef img.userphoto`, 0-2-2) outranks
   a plain attribute selector (0-1-1), so the placeholder kept width:auto and
   stayed at 128px. The banner variants are therefore matched at their own
   weight rather than relying on source order. */
div.arearef img.userphoto[src*="user_anonymous"],
div.arearef img.photoref[src*="user_anonymous"],
.divphotoref img[src*="user_anonymous"],
div.arearef img.userphoto[src*="user_man"],
div.arearef img.userphoto[src*="user_woman"],
.divphotoref img[src*="user_man"], .divphotoref img[src*="user_woman"],
img[src*="user_anonymous"], img[src*="user_man.png"], img[src*="user_woman.png"] {
	width: 80px;
	height: 80px;
	object-fit: contain;
	opacity: 0.5;
	background: var(--c-sunken);
	border: 1px dashed var(--c-border) !important;
	border-radius: var(--r);
}
img.dropdown-user-image[src*="user_"], .dropdown-user-image {
	width: 28px !important;
	height: 28px !important;
	opacity: 1;
	border: 0 !important;
	border-radius: 50%;
}

/* ---- Agenda month grid ----
   Dolibarr hardcodes #666 on the day links. On a light canvas that is fine; on
   a dark one it is grey on near-black -- 2.7:1, the only contrast failure left
   in the sweep, and it hit every variant of the agenda month view. Taking the
   colour from the ramp lets each theme resolve it correctly. */
a.dayevent-aday, .dayevent-aday, td.cal_other_month a, .cal_past a {
	color: var(--c-ink-2) !important;
}
td.cal_other_month, td.cal_other_month a { opacity: 0.75; }


@media only screen and (max-width: 767px) {
	/* The leading-picto rule adds an 8px left margin to the field beside it.
	   Combined with Dolibarr's own width:100% utility that margin pushes the
	   input exactly 8px past its cell -- which is precisely the overflow the
	   sweep reported on every mobile create form. The gap is only meaningful
	   while the picto sits inline before the field; once rows stack it is not. */
	td span[class*="fa-"] + input:not([class~="ts-measure"]),
	td span[class*="fa-"] + select,
	td span[class*="fa-"] + textarea,
	td span[class*="fa-"] + .select2-container,
	td span[class*="fa-"] ~ .select2-container,
	td span.pictofixedwidth ~ .select2-container,
	td img.pictofixedwidth + input,
	td img.pictofixedwidth + .select2-container,
	td span.pictofixedwidth + input,
	td span.pictofixedwidth + .select2-container {
		margin-left: 0;
	}
	/* Belt and braces: nothing in a cell may exceed the cell. */
	td > input, td > select, td > textarea, td > .select2-container {
		max-width: 100% !important;
		box-sizing: border-box;
	}
}

/* ---- Compact-theme hit targets ----
   The dense shell sizes its controls down far enough that row checkboxes and
   inline row links fall under the 24px minimum. The visual size is the point
   of the theme, so the glyph is left alone and only the clickable area grows,
   via a centred pseudo-element that costs no layout space. */
.dn-bar ~ * input.checkforselect, .dn-bar ~ * input.checkallactions,
body:has(.dn-bar) input.checkforselect, body:has(.dn-bar) input.checkallactions {
	position: relative;
}
body:has(.dn-bar) input.checkforselect::after,
body:has(.dn-bar) input.checkallactions::after,
body:has(.dn-bar) td a.refurl::after,
body:has(.dn-bar) td a.customer-back::after {
	content: "";
	position: absolute;
	top: 50%;
	left: 50%;
	width: 24px;
	height: 24px;
	transform: translate(-50%, -50%);
}
body:has(.dn-bar) td a.refurl, body:has(.dn-bar) td a.customer-back { position: relative; }


@media only screen and (max-width: 767px) {
	/* The colour picker puts a swatch and a text field in one cell, so the
	   field's own 100% width starts partway across and runs past the edge.
	   It has to leave room for the swatch beside it. */
	td input.colorpicker {
		width: auto !important;
		max-width: calc(100% - 64px) !important;
	}
}

/* ---- Compact-theme hit targets, sized rather than padded ----
   An ::after hit area enlarges what the pointer can reach but not the element
   box, so it neither shows up in an audit nor helps assistive tooling that
   reports control size. These get a real 24px minimum; the checkbox glyph is
   drawn by the UA at its own size, so only the box around it grows. */
body:has(.dn-bar) input.checkforselect,
body:has(.dn-bar) input.checkallactions,
body:has(.dn-bar) td a.refurl,
body:has(.dn-bar) td a.customer-back {
	min-width: 24px;
	min-height: 24px;
}
body:has(.dn-bar) td a.refurl,
body:has(.dn-bar) td a.customer-back {
	display: inline-flex;
	align-items: center;
}


/* ---- Font Awesome weight ----
   FA5 splits its faces by weight: solid is 900, regular 400, brands 400. The
   v4-style `.fa` alias carries no weight of its own, so it inherited the
   theme's 500 and the browser resolved it to the Regular face -- which in FA5
   *Free* contains almost no glyphs. The bug and print icons in the top bar
   therefore rendered as empty boxes while `.fas` icons beside them were fine.
   Brands and explicit regular icons keep their own weight. */
.fa, .fas, .fa-solid {
	font-family: "Font Awesome 5 Free", "Font Awesome 5 Pro", FontAwesome;
	font-weight: 900;
}
.fab, .fa-brands { font-family: "Font Awesome 5 Brands"; font-weight: 400; }
.far, .fa-regular { font-weight: 400; }

/* ---- Dashboard widget counts ----
   The label is an inline-block aligned to the middle while the count beside it
   is a plain inline on the baseline, so the number rode ~4px high against its
   own label. Both sit on one alignment. */
.info-box-content .info-box-more,
.info-box-content .info-box-more *,
.info-box-content a, .info-box-content .badge,
.info-box-content span.classfortooltip {
	vertical-align: middle;
}
.info-box-content .info-box-more { line-height: 1.5; }

/* ---- Setup landing page ----
   admin/index.php emits a bare full-width table with no border, background or
   radius, so the section links and their descriptions floated directly on the
   page background while every neighbouring screen is carded. */
/* Each entry is a <section class="setupsection">, shipped transparent with no
   border and no padding, so the links and their descriptions sat directly on
   the page background while every neighbouring screen is carded. The section
   is already cursorpointer -- Dolibarr makes the whole block clickable -- so it
   also gets a hover state to match the affordance it already claims. */
section.setupsection {
	display: block;
	margin-bottom: var(--sp-3);
	padding: var(--sp-4);
	background: var(--c-surface);
	border: 1px solid var(--c-border);
	border-radius: var(--r-lg);
	box-shadow: var(--sh-sm);
	transition: border-color var(--t), box-shadow var(--t);
}
section.setupsection:hover {
	border-color: var(--c-border-strong);
	box-shadow: var(--sh-md);
}
/* The heading link is inline and the description follows a <br>. Hiding that
   break ran the two together into one sentence -- the link has to become a
   block instead so the description sits under it. */
section.setupsection a {
	display: inline-block;
	margin-bottom: var(--sp-1);
	font-weight: 600;
}
section.setupsection a + br { display: none; }
section.setupsection > .opacitymedium,
section.setupsection > div { color: var(--c-ink-2); }
/* The picto leads the heading, so it belongs on the heading's line. */
section.setupsection > span[class*="fa-"],
section.setupsection > img { vertical-align: middle; margin-right: var(--sp-2); }

/* The page title on the setup index is a bare table rather than the usual
   header block, so it needs the same card as every other screen's title. */
div.fiche > table.centpercent.notopnoleftnoright {
	display: block;
	margin-bottom: var(--sp-4);
	padding: var(--sp-4) var(--sp-5);
	background: var(--c-surface);
	border: 1px solid var(--c-border);
	border-radius: var(--r-lg);
	box-shadow: var(--sh-sm);
}

/* The shells set a text weight on their tool clusters (.cmd-bar-tools and the
   rail/side equivalents). Those selectors are two classes deep, so they beat
   Font Awesome's own single-class `.fa, .fas { font-weight: 900 }` -- and the
   icons in that cluster silently lost their glyphs, because the weight is what
   selects the font face. Restated at a weight that wins for icons only; the
   surrounding text keeps 500. */
.cmd-bar-tools .atoplogin.fa, .cmd-bar-tools .atoplogin.fas,
.cmd-bar-tools .fa, .cmd-bar-tools .fas,
#cmd-bar-tools .fa, #cmd-bar-tools .fas,
.wb-rail-foot .fa, .wb-rail-foot .fas,
.ed-side-foot .fa, .ed-side-foot .fas,
.au-bar .fa, .au-bar .fas, .dn-bar .fa, .dn-bar .fas {
	font-weight: 900;
}


/* ---- Module card enable/disable control ----
   The toggle is the primary action on every module card and shipped at 17x15,
   smaller than the settings cog beside it and well under a comfortable target.
   It is sized up and given the accent when on, so the card's state is readable
   at a glance instead of requiring a squint at a grey glyph. */
.info-box-actions .fa-toggle-on,
.info-box-actions .fa-toggle-off,
div.box-flex-container.kanban .fa-toggle-on,
div.box-flex-container.kanban .fa-toggle-off {
	font-size: 1.6rem;
	line-height: 1;
	vertical-align: middle;
	opacity: 1;
}
div.box-flex-container.kanban .fa-toggle-on { color: var(--c-accent); }
div.box-flex-container.kanban .fa-toggle-off { color: var(--c-faint); }
.info-box-actions .fa-cog, div.box-flex-container.kanban .fa-cog {
	font-size: 1.05rem;
	vertical-align: middle;
}
div.box-flex-container.kanban .info-box-actions a,
div.box-flex-container.kanban .info-box-actions > div {
	display: inline-flex;
	align-items: center;
	min-height: 30px;
}

/* ---- Marketplace and developer tabs ----
   These panels embed vendor artwork at its native size -- a 626px logo and a
   2683px banner -- so the images dwarfed the text they illustrate and forced
   an inner scrollbar. Nothing here should exceed its column, and the logos
   read fine at a fraction of the size. */
div.tabBar img[src*="dolibarr_logo"],
div.tabBar img[src*="dolistore_logo"],
div.tabBar img[src*="logo_dolistore"] {
	width: auto;
	max-width: 200px;
	max-height: 56px;
	object-fit: contain;
}
div.tabBar img[src*="preferred_partner"],
div.tabBar img[src*="partner"] {
	width: 100%;
	max-width: 520px;
	height: auto;
}
/* Nothing in a settings panel may exceed its container. */
div.tabBar img, div.fiche img { max-width: 100%; height: auto; }
div.tabBar div[style*="overflow"], div.tabBar .div-table-responsive { max-width: 100%; }


/* ---- Page title row ----
   Dolibarr lays the title bar out as three table cells -- title, centre, right
   -- so a short piece of context like "Current language" was centred in the
   page rather than attached to the heading it qualifies, reading as unrelated
   floating text. Collapsing the title cell to its content lets the centre cell
   begin immediately after it, which is where that context belongs. The right
   cell keeps its own alignment. */
/* The first cell is only the picto; the heading lives in .col-title, and that
   is the one that has to shrink to its text for the centre cell to sit next
   to it. */
/* The title cell only shrinks when a centre cell exists to move up beside it.
   On a two-cell title row (picto + title) collapsing both made the table split
   the width between them, which pushed the heading into the middle of the
   page -- "Display" looked deliberately centred when it was just leftovers. */
/* Only collapse the first cell when the row actually has a centre cell to
   pull up beside the title. On a record card the FIRST cell IS the title --
   collapsing it to 1% squeezed it to 5px while its 227px heading overflowed
   into the next cell and sat underneath the view-mode buttons. */
/* Collapse the first cell only when it does NOT hold the heading. On the
   settings pages that cell is a picto and shrinking it pulls the title left;
   on a record card the first cell IS the title, and collapsing it squeezed a
   227px heading into 5px so it overflowed under the view-mode buttons.
   Presence of .titre is the reliable discriminator -- the class list is not,
   because both layouts mark their second cell .col-center. */
tr.toptitle > td:first-child:not(:has(.titre)):not(.col-title) {
	width: 1%;
	white-space: nowrap;
}
/* ...and only when something precedes it. On the settings pages .col-title
   follows a picto cell, so collapsing it pulls the centre cell up beside the
   heading. On a record card .col-title IS the first cell, and collapsing it
   crushed a 227px heading into 5px -- it then overflowed into the next cell
   and sat under the view-mode buttons. */
tr.toptitle:has(> td.col-center) > td.col-title:not(:first-child) {
	width: 1%;
	white-space: nowrap;
}
/* The cell also carries Dolibarr's `.center` utility, which is declared
   !important, so the alignment has to be forced rather than merely outranked. */
tr.toptitle > td.col-center,
tr.toptitle > td.col-center.center {
	text-align: left !important;
	padding-left: var(--sp-4);
}


/* ---- Version chip in the top bar ----
   The version sat 6px from the help icon as bare text with no padding or
   background, so it read as part of the help control rather than a separate
   piece of information -- and being a link, it offered no hover feedback. */
/* Scoped to the bar: `span.hideonsmartphone.small` is a generic Dolibarr
   utility that also wraps page content (the program version on the integrity
   report), and an unscoped margin there shunted that value off its cell. */
.cmd-bar a[href*="wikihelp"], .cmd-bar a[href*="doliwiki"],
.cmd-bar .atoplogin.login_block_elem_name,
.cmd-bar span.hideonsmartphone.small {
	margin-left: var(--sp-3);
}
/* The version is a span.aversion, not a link, so it needs the affordance
   spelled out: it carries a tooltip and nothing about bare grey text said so.
   A quiet chip separates it from the help icon and gives the hover a target. */
span.aversion {
	display: inline-flex;
	align-items: center;
	align-self: center;		/* centre in the bar, not on the text baseline */
	gap: var(--sp-1);
	padding: 0;
	background: none;		/* a filled pill read as a disabled button */
	/* --c-faint is the ramp step for separators and disabled marks; as real
	   words on the bar it measured 2.9:1, under AA. --c-muted is the lightest
	   step meant to carry text and still reads as secondary. */
	color: var(--c-muted);
	font-size: 0.6875rem;
	/* line-height 1.4 left the box a fraction taller than its glyphs, which
	   rounded the centre a pixel above its neighbours. */
	line-height: 1;
	letter-spacing: 0.01em;
	cursor: default;
	transition: color var(--t);
}
/* The tooltip wrapper is the flex item the bar actually positions. */
div.login_block:has(> span.aversion),
div.classfortooltip.login_block:has(span.aversion) {
	display: inline-flex;
	align-items: center;
	align-self: center;
}
span.aversion:hover { color: var(--c-muted); }
div.login_block:has(> span.aversion) { margin-left: var(--sp-2); }

/* ---- Account dropdown ----
   The panel scrolled sideways because long values (the professional IDs) never
   wrap, pushing content to 404px inside a 338px panel. A dropdown should never
   scroll horizontally -- the text wraps instead. */
.dropdown-menu .user-body {
	overflow-x: hidden !important;
	overflow-y: auto;
}
.dropdown-menu .user-body,
.dropdown-menu .user-body td,
.dropdown-menu .user-body div,
#topmenulogincompanyinfo, #topmenuloginmoreinfo {
	overflow-wrap: anywhere;
	word-break: break-word;
	max-width: 100%;
}
#topmenulogincompanyinfo table, #topmenuloginmoreinfo table { width: 100%; table-layout: fixed; }

/* Both detail blocks ship expanded, which made the panel 720px tall and buried
   the Card and Logout actions below the fold. They are disclosure sections --
   collapsed is the sensible default, and Dolibarr's own toggle still opens
   them because it animates from whatever state it finds. */
#topmenulogincompanyinfo, #topmenuloginmoreinfo { display: none; }

/* ---- Trailing row separator ----
   The final row of a detail table drew a separator with nothing beneath it,
   leaving a rule hanging across the bottom of the card. */
div.tabBar table.border > tbody > tr:last-child,
div.tabBar table.tableforfield > tbody > tr:last-child,
table.border:not(.liste) > tbody > tr:last-child,
table.tableforfield:not(.liste) > tbody > tr:last-child {
	border-bottom: 0;
}
div.tabBar table.border > tbody > tr:last-child > td,
table.tableforfield:not(.liste) > tbody > tr:last-child > td {
	border-bottom: 0;
}


/* ---- Save/notification toast (jNotify) ----
   Dolibarr raises these through the jNotify plugin, whose stock container is a
   full-bleed band pinned across the top of the window -- it covered the search
   field and the account menu, and at that size a four-word confirmation read
   like a page-level takeover. Constrained to a toast in the corner, above the
   fixed chrome but not spanning it. */
.jnotify-container {
	position: fixed;
	top: 68px;
	right: var(--sp-4);
	left: auto;
	width: auto;
	max-width: min(420px, calc(100vw - 2 * var(--sp-4)));
	z-index: 2000;
	text-align: left;
}
.jnotify-notification {
	display: flex;
	align-items: flex-start;
	gap: var(--sp-2);
	margin-bottom: var(--sp-2);
	padding: var(--sp-3) var(--sp-4);
	background: var(--c-surface);
	border: 1px solid var(--c-border);
	border-left: 3px solid var(--c-success);
	border-radius: var(--r);
	box-shadow: var(--sh-lg);
	color: var(--c-ink);
	font-size: 0.8125rem;
	line-height: 1.5;
}
.jnotify-notification-warning { border-left-color: var(--c-warning); }
.jnotify-notification-error { border-left-color: var(--c-danger); }
.jnotify-background { background: none !important; opacity: 1 !important; }
.jnotify-message { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.jnotify-close {
	flex: 0 0 auto;
	width: 20px; height: 20px;
	line-height: 18px;
	text-align: center;
	border-radius: var(--r-sm);
	color: var(--c-faint);
	opacity: 1;
}
.jnotify-close:hover { background: var(--c-sunken); color: var(--c-ink); }

/* ---- Trailing info icon ----
   These sit after a value and were dropping below its centre, because an
   icon's glyph box and a text run do not share a baseline. Middle alignment
   plus a matched line-height puts them on one line. */
td .classfortooltip[class*="fa-"], td span[class*="fa-info"],
td .classfortooltip > span[class*="fa-"],
span.classfortooltip.valignmiddle {
	vertical-align: middle;
	line-height: 1;
	position: relative;
	top: -1px;
}

/* ---- Account dropdown disclosures ----
   With both sections collapsed the two headers were left 33px apart, a gap
   inherited from the expanded layout that read as a missing block. */
#topmenulogincompanyinfo-btn, #topmenuloginmoreinfo-btn {
	display: block;
	margin: 0;
	padding: var(--sp-2) 0;
	line-height: 1.4;
}
.dropdown-menu .user-body > br { display: none; }
.dropdown-menu .user-body hr { margin: var(--sp-2) 0; }

/* Optical alignment: the context beside a large heading is much smaller type,
   so centring the two boxes leaves the small text sitting visually high
   against the heading's baseline. A small nudge settles it. */
tr.toptitle > td.col-center { padding-top: 6px; }


/* ---- "Default: <value>" hint rows ----
   These cells mix a colour-picker glyph, a label, a monospace-ish value and a
   tooltip icon. Each is a different element type with its own box, so they
   settled at four different heights -- some riding above the text, some below.
   One flex line puts them on a shared centre regardless of what each is. */
td:has(> .colorpicker), td.nowraponall:has(span[class*="fa-"]),
div.tabBar td:has(> input.colorpicker) {
	white-space: nowrap;
}
div.tabBar td > input.colorpicker ~ *,
div.tabBar td > .colorpicker ~ * { vertical-align: middle; }
div.tabBar table td span[class*="fa-"],
div.tabBar table td img.pictofixedwidth,
div.tabBar table td .classfortooltip {
	vertical-align: middle;
}
/* The value and its label share one baseline box. */
div.tabBar table td b, div.tabBar table td strong { vertical-align: middle; line-height: 1.4; }


/* ---- Toggle controls, everywhere ----
   Only the module-card toggles were sized up earlier; the same glyph is used
   throughout the settings screens and was still rendering at 21x11 -- the
   smallest interactive element on the page, and usually the only control in
   its row. Sized once, globally, so a switch looks like a switch wherever it
   appears. */
span[class*="fa-toggle-on"], span[class*="fa-toggle-off"],
a > span[class*="fa-toggle"], td span[class*="fa-toggle"] {
	font-size: 1.6rem !important;
	line-height: 1;
	vertical-align: middle;
	opacity: 1;
}
span[class*="fa-toggle-on"] { color: var(--c-accent); }
span[class*="fa-toggle-off"] { color: var(--c-faint); }
a:hover > span[class*="fa-toggle-off"] { color: var(--c-muted); }

/* ---- Record banner ----
   .arearef carries a bottom rule, but the portrait beside it is taller than
   the block, so the line ran straight through the photo and the status badge
   instead of sitting under them. The separation belongs below the whole
   banner, not through its middle. */
div.arearef.heightref {
	border-bottom: 0 !important;
	display: flex;
	align-items: center;
	gap: var(--sp-3);
	min-height: 92px;
}
div.arearef.heightref + * { border-top: 1px solid var(--c-hairline); padding-top: var(--sp-3); }

/* The colour-picker pencil sits before the "Default:" text and was riding
   above it -- an icon box and a text run have different baselines. */
td input.colorpicker + span, td .colorpicker,
td span[class*="fa-pencil"], td span[class*="fa-paint"] {
	vertical-align: middle;
	line-height: 1;
}


/* ---- Restore Dolibarr's width utilities ----
   The base input rule matches by excluding ten input types. Every :not()
   carries the specificity of the selector inside it, so that one rule scores
   (0,10,1) and quietly outranked every .maxwidthNN utility in the codebase --
   which is why a field meant to hold "7" was rendering 239px wide. The caps
   are restated here so the utilities mean what they say; the settings-form
   rule above is more specific still and keeps its wide measure where a full
   sentence is expected. */
input.maxwidth50, select.maxwidth50, .maxwidth50 { max-width: 50px !important; }
input.maxwidth75, select.maxwidth75, .maxwidth75 { max-width: 75px !important; }
input.maxwidth100, select.maxwidth100 { max-width: 100px !important; }
input.maxwidth125, select.maxwidth125 { max-width: 125px !important; }
input.maxwidth150, select.maxwidth150 { max-width: 150px !important; }
input.maxwidth200, select.maxwidth200 { max-width: 200px !important; }

/* A number field is sized by the count it holds, not by its column. */
input[type="number"] {
	width: auto;
	min-width: 72px;
	text-align: right;
}


/* ---- Leading pictos in link lists (dictionaries, setup indexes) ----
   Dolibarr emits the glyph as a bare span before the link with no spacing of
   its own. Narrow glyphs ($, document) happen to leave a gap; wider ones
   (city, map, people) fill their box and touch the label -- the icon and the
   first letter ran together. A fixed box makes the spacing independent of
   which glyph lands there, so every row starts on the same grid. */
/* Not scoped to div.tabBar: the dictionary index renders its table inside
   .div-table-responsive-no-min instead, so a tabBar-only rule missed exactly
   the page this was reported on. Any leading picto inside a table-cell link
   gets the same box. */
table td > span[class*="fa-"]:first-child,
table td > a > span[class*="fa-"]:first-child,
table td > a > img.pictofixedwidth:first-child,
table td > span.pictofixedwidth:first-child {
	display: inline-block;
	width: 1.25em;
	min-width: 1.25em;
	margin-right: var(--sp-2);
	text-align: center;
	vertical-align: middle;
	flex: 0 0 auto;
}


/* ---- Report / diagnostic pages (security, PHP setup, integrity, SMS) ----
   These pages alternate a one-row title table with a bare <div class="divsection">
   holding the actual content. The title got the card treatment while the
   content it introduces stayed transparent, so every section read as a
   floating heading followed by unstyled text. Heading and body are joined into
   a single card: the title loses its bottom corners and border, the body picks
   up the matching bottom half. */
div.fiche > table.centpercent.notopnoleftnoright:has(+ div.divsection) {
	margin-bottom: 0;
	border-bottom: 0;
	border-bottom-left-radius: 0;
	border-bottom-right-radius: 0;
	box-shadow: none;
}
div.fiche > div.divsection {
	margin-bottom: var(--sp-4);
	padding: var(--sp-4) var(--sp-5);
	background: var(--c-surface);
	border: 1px solid var(--c-border);
	border-top: 0;
	border-radius: 0 0 var(--r-lg) var(--r-lg);
	box-shadow: var(--sh-sm);
	overflow-wrap: anywhere;
}
/* A settings form that sits straight in .fiche gets the same shape. */
div.fiche > table.noborder.centpercent {
	background: var(--c-surface);
	border: 1px solid var(--c-border);
	border-radius: var(--r-lg);
	box-shadow: var(--sh-sm);
	border-collapse: separate;
	border-spacing: 0;
	overflow: hidden;
}
/* Collapse the run of empty <br> these pages use for vertical rhythm; the
   cards carry their own spacing now and the breaks just add dead height. */
div.fiche > br + br { display: none; }


/* ---- Module card icon alignment ----
   The module-board icon rule and the dashboard-widget icon rule both compute
   to the same specificity, so the dashboard one -- written later and correct
   for a card whose content is already inset -- won on both. Module cards ended
   up with padding-left:0, dropping the glyph onto the card's left border while
   its title stayed inset 16px. Stated one level more specific so the board
   keeps its own inset, and the glyph is sized to hold its own against the
   title rather than reading as a stray mark. */
div.box-flex-container.kanban > .box-flex-item .info-box-icon {
	padding: var(--sp-3) var(--sp-4) 0;
	justify-content: flex-start;
}
div.box-flex-container.kanban > .box-flex-item .info-box-icon > span,
div.box-flex-container.kanban > .box-flex-item .info-box-icon > i,
div.box-flex-container.kanban > .box-flex-item .info-box-icon > img {
	font-size: 1.15rem;
	line-height: 1;
	width: auto;
	min-width: 0;
	margin: 0;
}


/* The version wrapper carries .login_block_elem, the same class as the bug,
   print and help buttons beside it, so the hover background meant for those
   controls painted a grey pill behind a piece of static text. It is a label
   with a tooltip, not a button -- it gets no press affordance. */
.cmd-bar-tools .login_block_elem:has(> span.aversion):hover,
#cmd-bar-tools .login_block_elem:has(> span.aversion):hover,
.wb-rail-foot .login_block_elem:has(> span.aversion):hover,
.ed-side-foot .login_block_elem:has(> span.aversion):hover,
.au-bar .login_block_elem:has(> span.aversion):hover,
.dn-bar .login_block_elem:has(> span.aversion):hover {
	background: none;
	border-radius: 0;
}


/* ---- Trailing status icons ----
   A warning or error glyph emitted straight after a value has no spacing of
   its own, so it collided with the last character -- "utf8mb4_unicode_ci" ran
   into its own warning triangle. The earlier rule only covered the info icon,
   which is a different class, so every other status glyph still touched.
   Keyed off the picto* classes Dolibarr uses for all of them. */
td span[class*="pictowarning"], td span[class*="pictoerror"],
td span[class*="pictodanger"], td span[class*="pictoinfo"],
td span.fa-exclamation-triangle, td span.fa-exclamation-circle,
td span.fa-times-circle, td span.fa-check-circle,
td img[src*="warning"], td img[src*="error"] {
	margin-left: var(--sp-2);
	vertical-align: middle;
}
/* No :first-child reset here. :first-child counts elements only, so a glyph
   that FOLLOWS a text value still matches it -- the reset cancelled the very
   margin above on the one case it was meant to protect. The leading-picto rule
   uses margin-right, so the two never collide anyway. */


/* ---- Date picker trigger ----
   The calendar button is pulled onto the field by a -4px margin, so the glyph
   sat on the input's border instead of beside it. */
img.ui-datepicker-trigger, .ui-datepicker-trigger,
button.dpInvisibleButtons, .dpInvisibleButtons {
	margin-left: var(--sp-2) !important;
	vertical-align: middle;
}

/* ---- Record banner ----
   Two problems, both from the banner being laid out as flex.

   1. "Back to list" lives in .pagination, which Dolibarr floats right in its
      own block layout. As a flex item it simply took its source position --
      first -- and stuck to the left edge above the record name. Pushed back to
      the end with an auto margin rather than a float, which flex ignores.
   2. The logo column is a floated sibling that sits outside the banner, so it
      started at the card's edge (x=3) while every other element began at the
      content inset (x=33) -- the icon looked detached from the record it
      belongs to. */
div.arearef {
	align-items: flex-start;
	flex-wrap: wrap;
}
/* Pinned, not reordered. The wrapper around .pagination also holds the picto
   and the record title, so pushing that wrapper to the end shoved the entire
   banner to the right edge. Taking only the pagination out of flow puts "Back
   to list" in the corner and leaves everything else where it was. */
div.arearef div.pagination.paginationref {
	position: absolute;
	top: 0;
	right: 0;
	margin: 0;
	width: auto;
	text-align: right;
	white-space: nowrap;
}
div.tabBar > div.inline-block.floatleft:has(.divforspanimg),
div.tabBar > div.floatleft:has(> .divforspanimg) {
	margin-left: var(--sp-5);
}
/* The banner picto should share the record title's baseline row. */
div.divforspanimg { display: flex; align-items: center; }


/* ---- Leading pictos inside a wrapper ----
   Some cells wrap their contents in a div before the picto (the export wizard's
   dataset column, among others), so a `td > span:first-child` rule never
   matched and the glyph ran straight into its label. Scoped to a wrapper
   INSIDE a table cell so the settings-form picto gutter -- where the icon is a
   direct child of the td and its spacing is already accounted for in the cell
   padding -- is left alone. */
table td div > span[class*="fa-"]:first-child,
table td div > img.pictofixedwidth:first-child,
table td label > span[class*="fa-"]:first-child {
	margin-right: var(--sp-2);
	vertical-align: middle;
}


/* ---- Agenda month grid ----
   The month view is an auto-layout table, so a single event with a long title
   stretched its own weekday to 409px while the other six sat near 110px --
   a calendar whose columns change width based on what happens to be in them.
   Fixed layout makes every day equal; the week-number column keeps its own
   narrow width, and event text wraps instead of pushing the column out. */
table.cal_pannel {
	table-layout: fixed;
	width: 100%;
}
table.cal_pannel > tbody > tr > td:first-child,
table.cal_pannel > tbody > tr > th:first-child {
	width: 48px;
}
table.cal_pannel td, table.cal_pannel th { overflow-wrap: anywhere; }
table.cal_pannel .cal_event, table.cal_pannel .cal_event * {
	max-width: 100%;
	white-space: normal;
	overflow-wrap: anywhere;
}


/* ---- Fields that follow a leading picto ----
   width:100% is 100% of the CELL, but a picto row also spends 19px on the
   glyph and 8px on the gap -- so the field overflowed and dropped to the next
   line, leaving the barcode input hanging below its own icon while every other
   row stayed on one line. Those 27px have to come off the field's width.
   The selector repeats the width rule's :not() chain so it can outrank it;
   a shorter selector loses no matter where it sits in the file. */
div.tabBar table.border:not(.liste) td > span[class*="fa-"] + input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]):not([type="number"]):not(.button):not([class~="width25"]):not([class~="width50"]):not([class~="width75"]):not([class~="width100"]):not([class~="width125"]):not([class~="maxwidth50"]):not([class~="maxwidth75"]):not([class~="maxwidth100"]):not([class~="ts-measure"]),
div.tabBar table.editmode:not(.liste) td > span[class*="fa-"] + input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]):not([type="number"]):not(.button):not([class~="width25"]):not([class~="width50"]):not([class~="width75"]):not([class~="width100"]):not([class~="width125"]):not([class~="maxwidth50"]):not([class~="maxwidth75"]):not([class~="maxwidth100"]):not([class~="ts-measure"]),
div.tabBar table.border:not(.liste) td > span[class*="fa-"] + textarea,
div.tabBar table.editmode:not(.liste) td > span[class*="fa-"] + textarea,
div.tabBar table.border:not(.liste) td:not(.ts-measure-cell) > span[class*="fa-"] ~ .select2-container,
div.tabBar table.editmode:not(.liste) td > span[class*="fa-"] ~ .select2-container {
	width: 100% !important;	/* the picto is out of flow; nothing to subtract */
}
@media only screen and (max-width: 767px) {
	/* Rows stack on narrow screens; the picto no longer shares the line. */
	div.tabBar table td > span[class*="fa-"] + input:not([class~="ts-measure"]),
	div.tabBar table td > span[class*="fa-"] + textarea,
	div.tabBar table td:not(.ts-measure-cell) > span[class*="fa-"] ~ .select2-container {
		width: 100% !important;
	}
}


/* ---- Contrast: muted text that still has to be read ----
   Three roles were all painted in --c-muted and measured 2.6-2.9:1 against
   their own backgrounds: disabled action buttons, select2 placeholders, and
   the warning banner's body. Disabled controls are exempt from WCAG 1.4.3, but
   2.6:1 is unreadable rather than merely quiet -- a user cannot tell what the
   action they cannot take actually is. Each moves to the darkest tone that
   still reads as secondary. */
/* .textbutton wraps the label of EVERY action button, enabled ones included,
   so darkening it wholesale put near-black text on the filled accent primary
   ("Modify" fell to 1.59:1). Only the refused/disabled variant is retouched. */
a.butActionRefused, a.butActionRefused.classfortooltip,
a.butActionRefused span.textbutton, .butActionRefused span.textbutton {
	color: color-mix(in srgb, var(--c-muted) 55%, var(--c-ink)) !important;
}
/* select2 sets the placeholder colour from its own default theme, which is
   two classes deep -- a bare selector never reaches it. */
.select2-container--default .select2-selection--single .select2-selection__placeholder,
.select2-container--default .select2-selection__placeholder,
input::placeholder, textarea::placeholder {
	color: color-mix(in srgb, var(--c-muted) 70%, var(--c-ink)) !important;
	opacity: 1;
}
div.warning, div.warning a, div.warning span {
	color: color-mix(in srgb, var(--c-warning) 45%, var(--c-ink)) !important;
}

/* ---- Tap targets ----
   Row checkboxes shipped at 16px and the nav carets at 18x22 -- both under any
   reasonable minimum, and the checkbox is the control a user hits most often
   on a list. Sized up without disturbing the row rhythm. */
input.checkforselect, input.checkallactions,
table.liste input[type="checkbox"], .liste input[type="checkbox"] {
	width: 18px;
	height: 18px;
	cursor: pointer;
}
button.ts-caret, .ts-caret {
	min-width: 24px;
	min-height: 24px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
}
button.liste_titre, button.button_search, button.button_removefilter {
	min-width: 30px;
	min-height: 26px;
}
/* Inline icon links in list rows get a real box without changing the glyph. */
td a.customer-back, td a.supplier-back {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 22px;
	min-height: 22px;
}


/* The leading-picto gap is a margin on the FIELD, sized for a glyph sharing
   its line. In these settings tables the picto is now absolutely positioned in
   the cell's gutter, so that margin is 8px of nothing -- and it pushed picto
   rows 8px right of plain ones. Removed here only; elsewhere the picto is
   still inline and still needs it. */
div.tabBar table.border:not(.liste):not(.tableforfield) > tbody > tr > td:nth-child(even) > span[class*="fa-"] + input,
div.tabBar table.editmode:not(.liste):not(.tableforfield) > tbody > tr > td:nth-child(even) > span[class*="fa-"] + input,
div.tabBar table.border:not(.liste):not(.tableforfield) > tbody > tr > td:nth-child(even) > span[class*="fa-"] + textarea,
div.tabBar table.editmode:not(.liste):not(.tableforfield) > tbody > tr > td:nth-child(even) > span[class*="fa-"] + textarea,
div.tabBar table.border:not(.liste):not(.tableforfield) > tbody > tr > td:nth-child(even) > span[class*="fa-"] ~ .select2-container,
div.tabBar table.editmode:not(.liste):not(.tableforfield) > tbody > tr > td:nth-child(even) > span[class*="fa-"] ~ .select2-container,
div.tabBar table.border:not(.liste):not(.tableforfield) > tbody > tr > td:nth-child(even) > span[class*="fa-"] + select,
div.tabBar table.editmode:not(.liste):not(.tableforfield) > tbody > tr > td:nth-child(even) > span[class*="fa-"] + select {
	margin-left: 0;
}


/* ---- Status icons in report prose ----
   The diagnostic pages emit a check or warning glyph immediately before each
   line of text, with no wrapper and no spacing, so every entry read as
   "!PHP session.use_strict_mode". These are not first-child (a <br> or text
   precedes them) and not in a table cell, so none of the earlier picto rules
   reached them. */
div.divsection span[class*="picto"],
div.divsection span[class*="fa-check"],
div.divsection span[class*="fa-exclamation"],
div.divsection span[class*="fa-times"],
div.divsection span[class*="fa-info"] {
	margin-right: var(--sp-2);
	vertical-align: middle;
}
/* These lines are a list of checks; a little leading makes them scannable. */
div.divsection { line-height: 1.7; }


/* ---- Room for a trailing icon or action ----
   A field at width:100% consumes the whole cell, so an icon after it -- a help
   tooltip, or the regenerate control on a password/API-token field -- had
   nowhere to go and dropped to its own line, stranded under the control it
   belongs to. Only cells that actually carry one give the space back.

   The selector repeats the width rule's :not() chain. Without it this scores
   far lower than that rule's fourteen clauses and never applies, however much
   !important it carries. */
div.tabBar table.border:not(.liste):not(.tableforfield) > tbody > tr > td:nth-child(even):has(> span[class*="fa-info"], > span.linkobject, > span[class*="fa-redo"], > a.linkobject) > input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]):not([type="number"]):not(.button):not([class~="width25"]):not([class~="width50"]):not([class~="width75"]):not([class~="width100"]):not([class~="width125"]):not([class~="maxwidth50"]):not([class~="maxwidth75"]):not([class~="maxwidth100"]):not([class~="ts-measure"]),
div.tabBar table.editmode:not(.liste):not(.tableforfield) > tbody > tr > td:nth-child(even):has(> span[class*="fa-info"], > span.linkobject, > span[class*="fa-redo"], > a.linkobject) > input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]):not([type="number"]):not(.button):not([class~="width25"]):not([class~="width50"]):not([class~="width75"]):not([class~="width100"]):not([class~="width125"]):not([class~="maxwidth50"]):not([class~="maxwidth75"]):not([class~="maxwidth100"]):not([class~="ts-measure"]),
div.tabBar table.border:not(.liste):not(.tableforfield) > tbody > tr > td:nth-child(even):has(> span[class*="fa-info"], > span.linkobject, > span[class*="fa-redo"], > a.linkobject) > textarea,
div.tabBar table.editmode:not(.liste):not(.tableforfield) > tbody > tr > td:nth-child(even):has(> span[class*="fa-info"], > span.linkobject, > span[class*="fa-redo"], > a.linkobject) > textarea,
div.tabBar table.border:not(.liste):not(.tableforfield) > tbody > tr > td:nth-child(even):has(> span[class*="fa-info"], > span.linkobject, > span[class*="fa-redo"], > a.linkobject) > .select2-container,
div.tabBar table.editmode:not(.liste):not(.tableforfield) > tbody > tr > td:nth-child(even):has(> span[class*="fa-info"], > span.linkobject, > span[class*="fa-redo"], > a.linkobject) > .select2-container {
	width: calc(100% - 34px) !important;
}


/* ---- Dashboard card consistency ----
   Two things broke the set. Dolibarr gives the weather/global-view widget a
   filled icon strip (.info-box-weather) while every other widget's is
   transparent, so one card in the grid wore a grey band nothing else had. And
   the icon block reserved 40px for a 17px glyph, leaving a 49px canyon between
   the icon and the title it belongs to. */
div.box-flex-container .info-box-icon,
div.box-flex-container .info-box-icon[class*="bg-infobox"],
div.box-flex-container .info-box-weather .info-box-icon,
div.box-flex-container .info-box[class*="weather"] .info-box-icon {
	background: transparent !important;
	/* Dolibarr fixes span.info-box-icon at 40px for a 17px glyph. !important
	   rather than specificity, because the stock rule wins on source order in
	   the compiled sheet regardless of weight. */
	/* `auto` still resolved to 40px through flex sizing, so the box is given an
	   explicit compact height instead of arguing with the cascade. */
	height: 26px !important;
	min-height: 0;
	padding-top: var(--sp-2) !important;
	line-height: 1;
}
div.box-flex-container > .box-flex-item .info-box-content,
div.box-flex-container > .box-flex-item-with-margin .info-box-content {
	padding-top: var(--sp-2);
}
/* The create ("+") affordance rides with the icon rather than floating. */
div.box-flex-container .info-box-icon a.info-box-createlink {
	margin-left: var(--sp-1);
	display: inline-flex;
	align-items: center;
}


/* ---- Role badges in list cells ----
   The customer/vendor/prospect markers are emitted as bare adjacent links
   ("C" then "V" with nothing between), so they read as one two-letter token
   rather than two separate roles. They are distinct affordances -- each links
   somewhere different -- and need to look it. */
td a.customer-back, td a.vendor-back, td a.prospect-back,
td a.customer-back + a, td a.vendor-back + a {
	margin-right: var(--sp-1);
	border-radius: var(--r-sm);
	font-size: 0.6875rem;
	font-weight: 650;
	line-height: 1;
}
td a.customer-back:last-child, td a.vendor-back:last-child { margin-right: 0; }
td a.customer-back:hover, td a.vendor-back:hover, td a.prospect-back:hover {
	background: var(--c-sunken);
}

/* ---- Empty states ----
   "No sales order recorded", "No upcoming events" and friends were emitted as
   bare text flush against the cell edge, indistinguishable from data. An empty
   result is information: centred, muted and given room so a user reads it as
   an answer rather than a rendering failure. */
td.opacitymedium:only-child,
table.liste tr td[colspan]:only-child,
.info-box-content .opacitymedium:only-child,
div.tabBar table td.center.opacitymedium {
	padding: var(--sp-4) var(--sp-3);
	color: var(--c-muted);
	text-align: center;
	font-style: normal;
}

/* ---- Table header consistency ----
   Section headers ranged 33-55px across the same page because some carry a
   control and some only a label. A shared minimum keeps a column of cards
   reading as one system. */
tr.liste_titre > th, tr.liste_titre > td,
div.tabBar table > tbody > tr:first-child > td.liste_titre {
	height: auto;
	min-height: 0;
	padding-top: var(--sp-3);
	padding-bottom: var(--sp-3);
	vertical-align: middle;
}


/* ---- Label -> tooltip icon ----
   Dolibarr appends the help icon straight after a field label with no spacing,
   so "Stock management" and its ⓘ ran together as one word-shape. The earlier
   trailing-icon rule only covered the value side of the row; this is the label
   side, where the icon is wrapped in .classfortooltip rather than emitted bare.
   Applies wherever a tooltip wrapper follows content, not only in forms. */
td > span.classfortooltip:not(:first-child),
td > a.classfortooltip:not(:first-child),
label > span.classfortooltip:not(:first-child),
td.titlefield span.classfortooltip,
td.titlefieldcreate span.classfortooltip,
div.tabBar table td:nth-child(odd) > span.classfortooltip {
	margin-left: var(--sp-2);
	vertical-align: middle;
}
/* The wrapper is inline; give it a real box so the glyph inside centres. */
span.classfortooltip > span[class*="fa-"],
a.classfortooltip > span[class*="fa-"] { vertical-align: middle; }


/* ---- Controls inside table headers ----
   A header cell holding a select ("Doc template") stood 61px against 41px for
   the sixteen plain headers beside it, so the header band stepped up in one
   place. The control is compacted to the header's own rhythm instead of
   setting it. */
tr.liste_titre select, tr.liste_titre .select2-container,
tr.liste_titre input:not([type="checkbox"]):not([type="radio"]) {
	height: 26px;
	min-height: 0;
	font-size: 0.75rem;
	vertical-align: middle;
}
tr.liste_titre .select2-container--default .select2-selection--single { height: 26px; }
tr.liste_titre .select2-container--default .select2-selection--single .select2-selection__rendered { line-height: 24px; }


/* ---- Paired inline actions ("All / None", "Expand all / Undo expand") ----
   These sit either side of a "/" separator with no padding, so the two links
   and the slash read as one run of text rather than two choices. Padding on
   the link keeps the separator visible and gives each a real target. */
a.addexpandedmodulesinparamlist, a.removeexpandedmodulesinparamlist,
td.liste_titre a.commonlink, .liste_titre a.reposition {
	display: inline-block;
	padding: 2px var(--sp-1);
	border-radius: var(--r-sm);
	line-height: 1.4;
}
a.addexpandedmodulesinparamlist:hover, a.removeexpandedmodulesinparamlist:hover,
td.liste_titre a.commonlink:hover { background: var(--c-sunken); }


/* NOTE: an attempt to return the picto to the flow on mobile was reverted --
   it collided with the mobile width rule above and took picto-row wrapping
   from 1 case to 6. The absolute gutter is kept at every width. */


/* ---- Counts and "more" links in card headers ----
   Dolibarr emits area-page card headers as:

       <span>Draft orders</span><a href="..."><span class="badge">0</span></a>

   The badge class never picked up badge styling inside a header cell, so the
   count rendered as bare 12px text jammed against the title -- and the "..."
   link that opens the full list read as punctuation rather than an action.
   The header becomes a row: title left, count or "more" right, as a real pill
   with a real target. */
tr.liste_titre > th:has(> a > .badge),
tr.liste_titre > td:has(> a > .badge),
th:has(> span.valignmiddle + a > .badge) {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--sp-2);
	/* Some of these header rows carry an empty trailing cell. Without this the
	   count stops at its own cell's edge and floats mid-header instead of
	   sitting at the card's right edge; claiming the width squeezes the empty
	   cell to nothing. */
	width: 100%;
}
/* An empty trailing header cell has no job once the title cell spans. */
tr.liste_titre > th:has(> a > .badge) + th:empty,
tr.liste_titre > td:has(> a > .badge) + td:empty { padding: 0; width: 0; }
tr.liste_titre th .badge, tr.liste_titre td .badge,
th > a > .badge, td.liste_titre > a > .badge {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 22px;
	height: 20px;
	padding: 0 var(--sp-2);
	background: var(--c-sunken);
	border: 1px solid var(--c-border);
	border-radius: 999px;
	color: var(--c-ink-2);
	font-size: 0.6875rem;
	font-weight: 650;
	line-height: 1;
}
tr.liste_titre th > a, tr.liste_titre td > a {
	display: inline-flex;
	align-items: center;
	min-height: 22px;
}
tr.liste_titre th > a:hover .badge, tr.liste_titre td > a:hover .badge {
	background: var(--c-accent-soft);
	border-color: color-mix(in srgb, var(--c-accent) 35%, transparent);
	color: var(--c-accent-ink);
}
/* A zero count is information, not an alert -- keep it quiet. */
tr.liste_titre th .badge:empty { display: none; }


/* ---- Action link following a widget ----
   Dolibarr appends a control (manage categories, reset, pick) straight after a
   multiselect or similar widget with no spacing, so the two touched and read
   as one object. The gap goes on the trailing action so it applies wherever
   the pattern appears, not just after multiselects. */
/* `~` not `+`: Dolibarr emits a <script> between the widget and its action,
   and the adjacent-sibling combinator skips text nodes but not elements, so
   `+` matched nothing here. */
td > [class*="multiselectarr"] ~ a,
td > .select2-container ~ a.cursorpointer,
td > .select2-container ~ a.reposition,
td > input ~ a.cursorpointer,
td > a.cursorpointer ~ a.cursorpointer {
	margin-left: var(--sp-2);
	display: inline-flex;
	align-items: center;
	min-height: 22px;
}


/* ---- Label / value baseline on record cards ----
   Dolibarr wraps a card label in a nested table when the field is editable
   (label on the left, inline-edit pencil on the right). That nested table has
   its own height, and the label cell carries 12px of top padding against the
   value cell's 8px -- so the label sat up to 16px below the value it names.
   Both cells centre on the row instead, which holds regardless of whether the
   label is bare text or a nested edit table. */
div.tabBar table.border:not(.liste) > tbody > tr > td,
div.tabBar table.tableforfield:not(.liste) > tbody > tr > td,
table.tableforfield:not(.liste) > tbody > tr > td {
	vertical-align: middle;
	padding-top: var(--sp-2);
	padding-bottom: var(--sp-2);
}
/* A tall control (editor, textarea, multi-select) should keep its label at the
   top -- centring it against 200px of editor looks unmoored. */
div.tabBar table > tbody > tr:has(textarea) > td,
div.tabBar table > tbody > tr:has(.cke) > td,
div.tabBar table > tbody > tr:has(select[multiple]) > td { vertical-align: top; }
/* The nested edit table must not add height of its own -- and it has to
   centre on the row like everything else. Its cells default to
   vertical-align: top, which left the label and its pencil 11px above the
   value they sit beside: four things on one row, on two different lines. */
div.tabBar td > table.nobordernopadding {
	margin: 0;
	height: 100%;
}
div.tabBar td > table.nobordernopadding > tbody,
div.tabBar td > table.nobordernopadding > tbody > tr { height: 100%; }
div.tabBar td > table.nobordernopadding > tbody > tr > td {
	padding: 0;
	vertical-align: middle;
}

/* ---- Long values in the account dropdown ----
   Professional IDs and tokens are unbroken strings with no spaces, so normal
   wrapping cannot split them and they ran under the panel edge. break-all is
   the only thing that breaks a run with no break opportunity. */
.dropdown-menu .user-body td,
.dropdown-menu .user-body div,
#topmenulogincompanyinfo td, #topmenuloginmoreinfo td {
	word-break: break-all;
	overflow-wrap: anywhere;
	white-space: normal;
	max-width: 100%;
}


/* ---- Inline edit affordance (the pencil) ----
   Dolibarr puts the label and its edit pencil in a nested table set to
   centpercent, so the pencil is pushed to the far right of a 320px label cell
   -- stranded mid-row, touching neither the label it edits nor the value it
   sits beside. Collapsing that table to its content puts the pencil directly
   after the label text, where it reads as belonging to it. */
div.tabBar td > table.nobordernopadding.centpercent,
div.tabBar td > table.centpercent.nobordernopadding {
	width: auto;
}
div.tabBar td > table.nobordernopadding a.editfielda,
/* `action=edit` appears in plenty of links that are not the pencil -- Setup >
   Display wraps each skin thumbnail in ihm.php?action=edit&theme=..., inside this
   exact tabBar/nobordernopadding context. Those links were therefore hidden at
   opacity 0 and only surfaced while the pointer was over them, so the skin chooser
   read as an empty band. The pencil is an icon-only link; anything wrapping an
   image is not it. */
div.tabBar td > table.nobordernopadding a[href*="action=edit"]:not(:has(img)) {
	margin-left: var(--sp-2);
	opacity: 0;
	transition: opacity var(--t);
	/* An inline anchor sits on the text baseline, which left the pencil 11px
	   above the row centre its label and value had settled on. A centred flex
	   box puts the glyph on the same line as everything else. */
	display: inline-flex;
	align-items: center;
	vertical-align: middle;
	line-height: 1;
}
div.tabBar td > table.nobordernopadding a[href*="action=edit"] span[class*="fa-"] {
	vertical-align: middle;
	line-height: 1;
}
/* Reveal on row hover or keyboard focus -- the affordance is available without
   being permanent visual noise on every row of the card. */
div.tabBar tr:hover td > table.nobordernopadding a.editfielda,
div.tabBar tr:hover td > table.nobordernopadding a[href*="action=edit"],
div.tabBar td > table.nobordernopadding a:focus-visible { opacity: 1; }

/* ---- Inline edit form ----
   The value cell can be as narrow as 240px in a four-column card, so a 190px
   control plus Save and Cancel could not fit on one line. They wrapped
   according to whatever width was left, which put Save beside the field and
   Cancel underneath it. The control takes its own line and the buttons stay
   together beneath it, at every width. */
/* Descendant, not child: Dolibarr wraps the inline-edit control in a <form>,
   so a `>` selector matched nothing and the control kept select2's inline
   width -- overflowing its cell and covering the card beside it. */
div.tabBar td:has(input[type="submit"]) .select2-container,
div.tabBar td:has(input[type="submit"]) select,
div.tabBar td:has(input[type="submit"]) input:not([type="submit"]):not([type="hidden"]):not([type="checkbox"]):not([type="radio"]) {
	display: block;
	width: 100% !important;
	max-width: 100% !important;
	margin-bottom: var(--sp-2);
}
div.tabBar td input[type="submit"] + input[type="submit"] {
	margin-left: var(--sp-2);
}


/* ---- Inline edit must not resize the card ----
   Entering edit mode swaps a short read-only value for a control plus Save and
   Cancel. Those need more room than the value did, so an auto-layout table
   simply widened the column -- on a two-card row that pushed the left card
   over the right one and clipped its labels.

   The card keeps its width and the form fits inside it: compact buttons, and a
   control that cannot exceed the column. */
div.fichehalfleft > table, div.fichehalfright > table,
div.fichehalfleft table.border, div.fichehalfright table.border,
div.fichehalfleft table.tableforfield, div.fichehalfright table.tableforfield {
	max-width: 100%;
	table-layout: auto;
}
/* `anywhere` let the browser break inside a word, so a value read
   "No particular sales representat / ive assigned". `break-word` only breaks a
   word that genuinely cannot fit, so ordinary values wrap at spaces. */
div.fichehalfleft table td, div.fichehalfright table td { overflow-wrap: break-word; }
/* Under `table-layout: fixed` the columns come from the first row, and Dolibarr
   emits later rows with an extra cell (the edit pencil hangs in its own td).
   Those rows pushed the value column down to ~102px of a 625px card, which is
   what forced the mid-word wrapping above. Pinning the label column leaves the
   rest of the card to the value, whatever the row's cell count. */
div.fichehalfleft table > tbody > tr > td.titlefield,
div.fichehalfleft table > tbody > tr > td.titlefieldmiddle,
div.fichehalfright table > tbody > tr > td.titlefield,
div.fichehalfright table > tbody > tr > td.titlefieldmiddle,
div.fichehalfleft table > tr > td.titlefield,
div.fichehalfright table > tr > td.titlefield {
	width: 40%;
}
/* Compact enough that a control and both buttons fit a half-card column. */
div.tabBar td input[type="submit"].smallpaddingimp,
div.fichehalfleft td input[type="submit"],
div.fichehalfright td input[type="submit"] {
	padding: 4px var(--sp-2);
	font-size: 0.75rem;
	min-height: 26px;
}
div.fichehalfleft td .select2-container,
div.fichehalfright td .select2-container,
div.fichehalfleft td select, div.fichehalfright td select {
	max-width: 100% !important;
}


/* ---- select2 inside an inline-edit cell ----
   select2.inc.php puts a 190px min-width floor on these controls so a short
   select does not truncate its own value. In an inline-edit cell that floor is
   wrong: the cell can be 146px, and min-width beats max-width in the cascade,
   so the control rendered at 190px regardless of any cap -- overflowing the
   cell and covering the card beside it.

   The floor is released here only. Everywhere else it still applies. */
div.tabBar td:has(input[type="submit"]) .select2-container,
div.fichehalfleft td:has(input[type="submit"]) .select2-container,
div.fichehalfright td:has(input[type="submit"]) .select2-container,
td:has(> form input[type="submit"]) .select2-container {
	min-width: 0 !important;
	width: 100% !important;
	max-width: 100% !important;
}
td:has(input[type="submit"]) > form { width: 100%; }


/* ---- Leading picto on a record-card value ----
   The glyph carries its font's line box, which is taller than the text beside
   it, so with vertical-align:middle it still settled ~11px below the label,
   pencil and value that had all landed on the row's centre line. Collapsing
   its line box puts the fourth element on the same line as the other three. */
div.tabBar table.border td > span[class*="fa-"],
div.tabBar table.tableforfield td > span[class*="fa-"],
table.tableforfield td > span[class*="fa-"] {
	line-height: 1;
	vertical-align: middle;
}


/* ---- Linked-event tables inside a half-width card ----
   The "last N events" block carries six columns in a 549px half-card, so its
   table rendered 624px wide and overflowed: the title clipped mid-word and the
   "By" column gave a user name 68px once the avatar had taken its share --
   "SuperAdmin" became "Su...".

   The table is made to fit its card, and the budget is rebalanced: the two
   icon-only columns give up their padding, the title absorbs what is left, and
   the name column gets enough to show a real name. */
div.fichehalfleft .div-table-responsive table.listactions,
div.fichehalfright .div-table-responsive table.listactions,
div.fichehalfleft .div-table-responsive-no-min table.listactions,
div.fichehalfright .div-table-responsive-no-min table.listactions {
	width: 100%;
	max-width: 100%;
	/* width:100% alone cannot shrink a column below its content, so the table
	   still measured wider than the card. Fixed layout is what actually makes
	   the columns share the space available. */
	table-layout: fixed;
}
/* Share out that space rather than splitting it six ways. Under fixed layout
   an unspecified column takes an equal share, which gave a user name the same
   91px as an icon-only column. Stated on the first row's cells, whether they
   are th or td, and forced so the utility width classes on those cells cannot
   claim the space back. */
div.fichehalfleft .div-table-responsive table.listactions tr:first-child > *:nth-child(1),
div.fichehalfleft .div-table-responsive-no-min table.listactions tr:first-child > *:nth-child(1),
div.fichehalfright .div-table-responsive table.listactions tr:first-child > *:nth-child(1),
div.fichehalfright .div-table-responsive-no-min table.listactions tr:first-child > *:nth-child(1) { width: 14% !important; }
div.fichehalfleft .div-table-responsive table.listactions tr:first-child > *:nth-child(2),
div.fichehalfleft .div-table-responsive-no-min table.listactions tr:first-child > *:nth-child(2),
div.fichehalfright .div-table-responsive table.listactions tr:first-child > *:nth-child(2),
div.fichehalfright .div-table-responsive-no-min table.listactions tr:first-child > *:nth-child(2) { width: 17% !important; }
div.fichehalfleft .div-table-responsive table.listactions tr:first-child > *:nth-child(3),
div.fichehalfleft .div-table-responsive-no-min table.listactions tr:first-child > *:nth-child(3),
div.fichehalfright .div-table-responsive table.listactions tr:first-child > *:nth-child(3),
div.fichehalfright .div-table-responsive-no-min table.listactions tr:first-child > *:nth-child(3) { width: 26% !important; }
div.fichehalfleft .div-table-responsive table.listactions tr:first-child > *:nth-child(4),
div.fichehalfleft .div-table-responsive-no-min table.listactions tr:first-child > *:nth-child(4),
div.fichehalfright .div-table-responsive table.listactions tr:first-child > *:nth-child(4),
div.fichehalfright .div-table-responsive-no-min table.listactions tr:first-child > *:nth-child(4) { width: 7% !important; }
div.fichehalfleft .div-table-responsive table.listactions tr:first-child > *:nth-child(5),
div.fichehalfleft .div-table-responsive-no-min table.listactions tr:first-child > *:nth-child(5),
div.fichehalfright .div-table-responsive table.listactions tr:first-child > *:nth-child(5),
div.fichehalfright .div-table-responsive-no-min table.listactions tr:first-child > *:nth-child(5) { width: 29% !important; }
div.fichehalfleft .div-table-responsive table.listactions tr:first-child > *:nth-child(6),
div.fichehalfleft .div-table-responsive-no-min table.listactions tr:first-child > *:nth-child(6),
div.fichehalfright .div-table-responsive table.listactions tr:first-child > *:nth-child(6),
div.fichehalfright .div-table-responsive-no-min table.listactions tr:first-child > *:nth-child(6) { width: 7% !important; }
div.fichehalfleft .div-table-responsive table.listactions td,
div.fichehalfright .div-table-responsive table.listactions td,
div.fichehalfleft .div-table-responsive table.listactions th,
div.fichehalfright .div-table-responsive table.listactions th,
div.fichehalfleft .div-table-responsive-no-min table.listactions td,
div.fichehalfright .div-table-responsive-no-min table.listactions td,
div.fichehalfleft .div-table-responsive-no-min table.listactions th,
div.fichehalfright .div-table-responsive-no-min table.listactions th {
	overflow: hidden;
	text-overflow: ellipsis;
}
/* Icon-only columns do not need a text column's padding. */
div.fichehalfleft .div-table-responsive td:has(> a > span[class*="fa-"]:only-child),
div.fichehalfright .div-table-responsive td:has(> a > span[class*="fa-"]:only-child) {
	width: 1%;
	padding-left: var(--sp-1);
	padding-right: var(--sp-1);
}
/* Room for a name: the cap has to clear the avatar that shares the cell. */
div.fichehalfleft td.tdoverflowmax100, div.fichehalfright td.tdoverflowmax100 {
	max-width: 150px;
}
div.fichehalfleft td.tdoverflowmax100 a, div.fichehalfright td.tdoverflowmax100 a {
	max-width: none;
}


/* ---- Event timeline (messaging / "Events about this" tabs) ----
   ul.timeline was never styled, so it fell back to browser defaults: disc
   bullets, a 40px indent, and no card. Combined with an 80px user portrait
   dropped into a log row, the result read as broken markup rather than a
   history. Each entry becomes a card with a small avatar and a clear stamp. */
ul.timeline {
	list-style: none;
	margin: 0;
	padding: 0;
}
ul.timeline > li { list-style: none; position: relative; }

/* A date heading separates groups of events. */
ul.timeline > li.time-label {
	margin: var(--sp-4) 0 var(--sp-2);
	font-size: 0.6875rem;
	font-weight: 700;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	color: var(--c-muted);
}
ul.timeline > li.time-label > span { background: none; padding: 0; }

/* Each event is a card. */
ul.timeline > li[class*="timeline-code"],
ul.timeline > li:not(.time-label) {
	margin-bottom: var(--sp-3);
	padding: var(--sp-3) var(--sp-4);
	background: var(--c-surface);
	border: 1px solid var(--c-border);
	border-radius: var(--r);
	box-shadow: var(--sh-sm);
}
ul.timeline .timeline-item { margin: 0; padding: 0; background: none; border: 0; box-shadow: none; }
ul.timeline .timeline-header { padding: 0; border: 0; font-weight: 600; }
ul.timeline .timeline-body { padding: var(--sp-2) 0 0; }

/* A log row needs a name and a stamp, not a portrait. */
ul.timeline img.userphoto, ul.timeline img.photouserphoto,
ul.timeline .userimg img, ul.timeline img[src*="user_anonymous"],
ul.timeline img[src*="nophoto"] {
	width: 24px !important;
	height: 24px !important;
	min-width: 0 !important;
	border-radius: 50%;
	vertical-align: middle;
	object-fit: cover;
}
/* An avatar in a list sits directly against the name beside it: Dolibarr wraps
   it in a span carrying both "paddingrightonly" and "nopadding", and the second
   wins, so the padding meant to separate them is removed. A margin is not
   something "nopadding" takes away. */
table td a > span.userimg,
table td a > span.nopadding,
table td > span.userimg {
	margin-right: var(--sp-2);
}
ul.timeline .userimg, ul.timeline span.nopadding { display: inline-flex; align-items: center; }
/* The author name was truncating to "Super..." beside an 80px portrait. */
ul.timeline a.classfortooltip, ul.timeline .timeline-header a { max-width: none; }
ul.timeline [class*="tdoverflowmax"] { max-width: none !important; }


/* ---- Markup present in Dolibarr 22.x ----
   These three classes exist in 22.0.4's stock theme but not in 24.x, so they
   were never covered while developing against 24. Styling them keeps the theme
   complete on both versions; on 24 the rules are simply inert. */
.classfortooltiponclick { cursor: pointer; vertical-align: middle; }
.classfortooltiponclick > span[class*="fa-"] { vertical-align: middle; }
input.linputsearch, .linputsearch {
	height: 34px;
	padding: 0 var(--sp-3);
	background: var(--inputbackgroundcolor);
	border: 1px solid var(--inputbordercolor);
	border-radius: var(--r);
	color: var(--c-ink);
	font-family: inherit;
	font-size: 0.9375rem;
}
input.linputsearch:focus, .linputsearch:focus {
	outline: none;
	border-color: var(--c-accent);
	box-shadow: 0 0 0 3px var(--c-accent-ring);
}
/* 22.x uses fa-question-circle where 24.x moved to a different glyph. */
span.fa-question-circle, .fa-question-circle { vertical-align: middle; line-height: 1; }


/* ---- Treeview plugin background ----
   jquery.treeview.css hardcodes `background-color: white` on the list. On a
   light theme that is invisible; on a dark one it punches a white block into
   the page and drags the muted link colour on top of it down to 2.9:1. The
   list takes the card's own surface instead. */
ul.treeview, ul.treeview ul, .treeview { background-color: transparent; }
ul.treeview a { color: var(--c-ink); }
ul.treeview .opacitymedium, ul.treeview span.small { color: var(--c-muted); opacity: 1; }


/* ---- Widget "more" links on the dashboard ----
   Same construction as the area-page header counts -- an anchor wrapping a
   .badge -- but emitted inside a div rather than a th, so the earlier rule
   never reached them and they stayed 12px of bare text. */
a:has(> span.badge), a.paddingleft:has(.badge) {
	display: inline-flex;
	align-items: center;
	min-height: 22px;
}
div[class*="tdoverflow"] > a > span.badge,
.info-box-content a > span.badge,
div.box a > span.badge {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 22px;
	height: 20px;
	padding: 0 var(--sp-2);
	background: var(--c-sunken);
	border: 1px solid var(--c-border);
	border-radius: 999px;
	color: var(--c-ink-2);
	font-size: 0.6875rem;
	font-weight: 650;
	line-height: 1;
}
div[class*="tdoverflow"] > a:hover > span.badge,
.info-box-content a:hover > span.badge,
div.box a:hover > span.badge {
	background: var(--c-accent-soft);
	border-color: color-mix(in srgb, var(--c-accent) 35%, transparent);
	color: var(--c-accent-ink);
}


/* ---- Icon-only actions in table rows ----
   Edit, delete, move and reorder controls are emitted as a bare glyph inside an
   anchor, so their clickable box is the glyph's own 13-17px. These are the
   controls a user aims at most often on an admin screen, and they are the
   hardest to hit. The box grows to 24px; the glyph does not, so row rhythm is
   unchanged. */
table td > a:has(> span[class*="fa-"]:only-child),
table td > a:has(> img:only-child),
table td > a.editfielda, table td > a.reposition,
ul.treeview td > a:has(> span[class*="fa-"]:only-child),
ul.treeview td > a:has(> img:only-child) {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 24px;
	min-height: 24px;
	border-radius: var(--r-sm);
	transition: background var(--t);
}
table td > a:has(> span[class*="fa-"]:only-child):hover,
table td > a:has(> img:only-child):hover,
ul.treeview td > a:hover:has(> span[class*="fa-"]:only-child) {
	background: var(--c-sunken);
}
/* Sort arrows and reorder chevrons sit in dense clusters -- they get the box
   without the hover fill, which would read as noise repeated down a column. */
table th > a:has(> span[class*="fa-"]:only-child) {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 22px;
	min-height: 22px;
}


/* ---- Avatar in the account control ----
   The 80px cap above is for a card's portrait placeholder. In 24.x the top-bar
   avatar carries .dropdown-user-image and is handled separately, but 22.x uses
   the same .photouserphoto classes as a card portrait -- so the card rule won
   and dropped an 80px photo into the bar, overlapping the chrome.

   Scoped by where it sits rather than what it is called, which holds on both
   versions. */
.login_block img.userphoto, .login_block img.photouserphoto,
.login-dropdown-a img, a.dropdown-toggle img.photo,
.atoplogin img.userphoto, .cmd-bar-tools img.userphoto,
.wb-rail-foot img.userphoto, .au-bar-tools img.userphoto,
.ed-side-foot img.userphoto, .dn-bar-tools img.userphoto {
	width: 26px !important;
	height: 26px !important;
	min-width: 0 !important;
	border: 0 !important;
	border-radius: 50%;
	opacity: 1;
	object-fit: cover;
	vertical-align: middle;
}

/* ==========================================================================
   COMMAND application bar

   This final shell layer intentionally follows the shared Thrive components:
   palette.inc.php also styles the search trigger and components.inc.php owns
   the relocated Dolibarr login block. Keep these rules scoped to .cmd-bar so
   other Dolibarr toolbars retain their native sizing and behaviour.
   ========================================================================== */

header.cmd-bar {
	gap: 16px;
	height: 60px;
	padding: 0 24px;
	background: var(--c-surface);
	-webkit-backdrop-filter: none;
	backdrop-filter: none;
	border-bottom-color: #e7e9ee;
	box-shadow: none;
}


header.cmd-bar .cmd-brand {
	gap: 10px;
	font-size: 0.90625rem;
	font-weight: 600;
}
header.cmd-bar .cmd-brand-mark {
	width: 32px;
	height: 32px;
	border-radius: 8px;
	font-size: 0.875rem;
}
header.cmd-bar .cmd-crumbs { display: none; }

header.cmd-bar .cmd-trigger {
	gap: 10px;
	height: 40px;
	padding: 0 8px 0 14px;
	background: #f8f9fb;
	border-color: #e1e5eb;
	border-radius: 8px;
	box-shadow: none;
	color: var(--c-muted);
	font-size: 0.8125rem;
}
header.cmd-bar .cmd-trigger:hover {
	background: var(--c-surface);
	border-color: var(--c-border-strong);
}
header.cmd-bar .cmd-trigger:focus-visible {
	outline: 0;
	border-color: var(--c-accent);
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--c-accent) 16%, transparent);
}
header.cmd-bar .cmd-trigger-icon {
	font-size: 0.9375rem;
	color: var(--c-faint);
}
header.cmd-bar .cmd-trigger-label { font-size: 0.8125rem; }
header.cmd-bar .cmd-kbd {
	min-width: 21px;
	height: 21px;
	padding: 0 5px;
	background: var(--c-surface);
	border-color: #e1e5eb;
	border-radius: 6px;
	font-size: 0.6875rem;
}

header.cmd-bar #cmd-bar-tools div.login_block {
	gap: 8px;
	font-size: 0.8125rem;
}
header.cmd-bar #cmd-bar-tools .login_block_other,
header.cmd-bar #cmd-bar-tools .login_block_tools {
	gap: 8px;
}
header.cmd-bar #cmd-bar-tools .login_block_user { gap: 0; }

/* Each existing Dolibarr utility keeps its own anchor, title and permission
   checks. Only its visual hit area changes. */
header.cmd-bar #cmd-bar-tools .login_block_other .login_block_elem {
	width: 36px;
	min-width: 36px;
	max-width: 36px;
	height: 36px;
	padding: 0 !important;
	border-radius: 8px;
}
header.cmd-bar #cmd-bar-tools .login_block_other .login_block_elem > a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	padding: 0;
	border-radius: 8px;
}
header.cmd-bar #cmd-bar-tools .login_block_other .login_block_elem > a > .atoplogin {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0;
	width: 36px;
	height: 36px;
	padding: 0;
	border-radius: 8px;
}
header.cmd-bar #cmd-bar-tools .login_block_other .login_block_elem i,
header.cmd-bar #cmd-bar-tools .login_block_other .login_block_elem .fa,
header.cmd-bar #cmd-bar-tools .login_block_other .login_block_elem .fas,
header.cmd-bar #cmd-bar-tools .login_block_other .login_block_elem .far {
	font-size: 0.9375rem;
}

/* Version is informational, not an action. It should not inherit the square
   icon slot used by its siblings. */
header.cmd-bar #cmd-bar-tools .login_block_other .login_block_elem:has(.aversion) {
	width: auto;
	min-width: 0;
	max-width: none;
	padding: 0 4px !important;
	background: transparent;
}
header.cmd-bar #cmd-bar-tools .aversion {
	color: var(--c-faint);
	font-size: 0.6875rem;
	font-weight: 450;
	line-height: 1;
}

header.cmd-bar #cmd-bar-tools .login_block_elem_name {
	height: 36px;
	min-width: 0;
	padding: 0 !important;
	background: transparent;
}
header.cmd-bar #topmenu-login-dropdown { height: 36px; }
header.cmd-bar #topmenu-login-dropdown > .dropdown-toggle {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	height: 36px;
	padding: 2px 8px 2px 2px;
	border: 0;
	border-radius: 8px;
	color: var(--c-ink-2);
	font-size: 0.8125rem;
	font-weight: 550;
}
header.cmd-bar #topmenu-login-dropdown > .dropdown-toggle:hover,
header.cmd-bar #topmenu-login-dropdown.open > .dropdown-toggle {
	background: var(--c-sunken);
	color: var(--c-ink);
}
header.cmd-bar #topmenu-login-dropdown > .dropdown-toggle::after {
	content: '';
	width: 5px;
	height: 5px;
	margin-left: 1px;
	border-right: 1.5px solid currentColor;
	border-bottom: 1.5px solid currentColor;
	transform: translateY(-1px) rotate(45deg);
	opacity: 0.72;
}
header.cmd-bar #cmd-bar-tools img.userphoto {
	width: 32px !important;
	height: 32px !important;
	min-width: 32px;
	margin: 0 !important;
}
header.cmd-bar #topmenu-login-dropdown .atoploginusername {
	padding: 0;
	color: inherit !important;
	font-family: var(--c-font) !important;
	font-size: 0.8125rem;
	font-weight: 550;
}

/* The legacy login block assigns its own grey to the version and username.
   That colour can be readable on the stock white bar but becomes almost
   invisible when an administrator chooses a dark top-menu colour.  All bar
   copy must inherit the contrast tokens calculated from that chosen colour. */
header.cmd-bar #cmd-bar-tools .aversion,
header.cmd-bar #cmd-bar-tools .atoploginusername,
header.cmd-bar #cmd-bar-tools .login_block_elem > a,
header.cmd-bar #cmd-bar-tools .login_block_elem > span {
	color: var(--c-muted) !important;
	font-family: var(--c-font) !important;
}
header.cmd-bar #topmenu-login-dropdown > .dropdown-toggle,
header.cmd-bar #topmenu-login-dropdown > .dropdown-toggle .atoploginusername {
	color: var(--c-ink-2) !important;
}

@media only screen and (min-width: 993px) {
	header.cmd-bar .cmd-trigger {
		width: clamp(420px, 34vw, 520px);
	}
}

/* ==========================================================================
   Responsive and print
   ========================================================================== */

@media only screen and (max-width: 992px) {
	.fiche { padding: var(--sp-4); }
	:root { --nav-w: var(--nav-w-collapsed); }
	.cmd-nav-label, .cmd-nav-sub, .cmd-nav-toggle-label { display: none; }
	.cmd-nav-scroll { padding: var(--sp-2) var(--sp-1); }
	.cmd-nav-link { justify-content: center; padding-left: 0; padding-right: 0; }

	/* The bar carries the way in, where a thumb can reach it. */
	button.cmd-nav-open {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		flex: 0 0 auto;
		width: 40px;
		height: 40px;
		margin-right: calc(var(--sp-2) * -1);
		padding: 0;
		border: 0;
		border-radius: var(--r);
		background: transparent;
		color: var(--c-ink-2);
		cursor: pointer;
	}
	button.cmd-nav-open:hover, body.cmd-nav-open button.cmd-nav-open { background: var(--c-sunken); }
	.cmd-nav-open-bars,
	.cmd-nav-open-bars::before,
	.cmd-nav-open-bars::after {
		display: block;
		width: 18px;
		height: 2px;
		border-radius: 2px;
		background: currentColor;
	}
	.cmd-nav-open-bars { position: relative; }
	.cmd-nav-open-bars::before, .cmd-nav-open-bars::after { content: ""; position: absolute; left: 0; }
	.cmd-nav-open-bars::before { top: -6px; }
	.cmd-nav-open-bars::after { top: 6px; }

	/* An icon rail has room for the modules but not for their sub-entries, and
	   those sub-entries are how most of the app is reached: with them dropped,
	   List, New and every other child page had no way in at all. Here the nav
	   opens over the page as a drawer, so the whole tree stays reachable and
	   nothing reflows behind it. */
	body.cmd-nav-open aside.cmd-nav {
		width: var(--nav-w-expanded);
		box-shadow: 0 24px 60px rgba(15, 23, 42, .3);
		z-index: 3400;
	}
	body.cmd-nav-open .cmd-nav-scroll { padding: var(--sp-3) var(--sp-2); }
	body.cmd-nav-open .cmd-nav-label,
	body.cmd-nav-open .cmd-nav-sub,
	body.cmd-nav-open .cmd-nav-toggle-label { display: revert; }
	body.cmd-nav-open .cmd-nav-link {
		justify-content: flex-start;
		padding-left: var(--sp-3);
		padding-right: var(--sp-3);
	}
	body.cmd-nav-open .cmd-nav-toggle { justify-content: flex-start; }
	body.cmd-nav-open .cmd-nav-toggle-icon {
		transform: rotate(45deg);
		margin-left: 4px;
	}
	/* Below the bar, so the account menu and search stay reachable with the
	   drawer open. */
	body.cmd-nav-open::before {
		content: "";
		position: fixed;
		inset: var(--bar-h) 0 0 0;
		z-index: 3390;
		background: rgba(15, 23, 42, .38);
	}
	.cmd-brand-text, .cmd-crumbs { display: none; }
	header.cmd-bar { gap: 12px; padding: 0 16px; }
	header.cmd-bar .cmd-bar-spacer { display: none; }
	.cmd-trigger { min-width: 0; flex: 1; }
	.fichehalfleft, .fichehalfright, .fichethirdleft, .fichetwothirdright { float: none; width: 100%; }
}
@media only screen and (max-width: 767px) {
	div.tabBar { padding: var(--sp-3); }
	.boxhalfleft, .boxhalfright, .box-flex-item { float: none; width: 100%; min-width: 100%; }
	.hideonsmartphone { display: none !important; }
	.cmd-trigger-label, .cmd-kbd { display: none; }
	header.cmd-bar { gap: 10px; padding: 0 12px; }
	header.cmd-bar #cmd-bar-tools div.login_block,
	header.cmd-bar #cmd-bar-tools .login_block_other,
	header.cmd-bar #cmd-bar-tools .login_block_tools { gap: 6px; }
	header.cmd-bar #cmd-bar-tools .login_block_other .login_block_elem:has(.aversion) { display: none; }
	.cmd-palette-panel { margin-top: var(--sp-4); }

	/* On a phone the icon rail costs 68px of a 390px screen -- a sixth of the
	   width, spent on a strip that cannot show a module's sub-entries anyway,
	   which is what the drawer is for. So the nav takes no width at all until it
	   is asked for: the page runs edge to edge, and the button in the bar opens
	   the nav over it.

	   The width comes from --nav-w, which the body's padding also reads, so
	   zeroing it both closes the rail and gives the page the space in one move.
	   The drawer then opens on its own width without the page reflowing behind
	   it. Hidden means hidden: with only zero width the links would still be
	   painted outside the nav and still be reachable by tab. */
	:root { --nav-w: 0px; }
	aside.cmd-nav {
		overflow: hidden;
		border-right: 0;
		visibility: hidden;
	}
	body.cmd-nav-open aside.cmd-nav {
		overflow: visible;
		border-right: 1px solid var(--c-hairline);
		visibility: visible;
	}
	/* The rail's own collapse control belongs to a rail that is no longer there;
	   the drawer is closed by the button in the bar, the backdrop or Escape. */
	body.cmd-nav-open .cmd-nav-toggle { display: none; }
}
@media print {
	header.cmd-bar, .cmd-palette, div.tabsAction, .noprint { display: none !important; }
	.fiche { padding: 0; max-width: none; }
	body { background: #fff; }
}
@media (prefers-reduced-motion: reduce) {
	*, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}




/* ---- Foldable navigation tree, shared by every shell ----
   Dolibarr's deeper modules (Setup is 20+ pages) are unusable as a flat list,
   so each branch folds and only the path to the current page is open. */
.ts-node { display: block; }
.ts-row {
	display: flex;
	align-items: center;
	gap: 2px;
	padding-left: calc(var(--lvl, 0) * 11px);
}
.ts-caret {
	flex: 0 0 auto;
	width: 18px; height: 22px;
	display: inline-flex; align-items: center; justify-content: center;
	padding: 0; margin: 0;
	background: none; border: 0; cursor: pointer;
	color: var(--c-faint);
	transition: color var(--t);
}
.ts-caret:hover { color: var(--c-ink); }
.ts-caret.is-empty { cursor: default; pointer-events: none; }
.ts-caret:not(.is-empty)::before {
	content: "";
	width: 5px; height: 5px;
	border-right: 1.5px solid currentColor;
	border-bottom: 1.5px solid currentColor;
	transform: rotate(-45deg);
	transition: transform var(--t);
}
.ts-node.is-open > .ts-row > .ts-caret::before { transform: rotate(45deg); }

/* Children are closed unless their branch is open. */
.ts-children { display: none; }
.ts-node.is-open > .ts-children { display: block; }

/* The link fills the remaining width so the whole row is a target. */
.ts-row > a { flex: 1 1 auto; min-width: 0; }

/* ---- select2: single ---- */

.select2-container--default .select2-selection--single {
	display: flex;
	align-items: center;
	height: 34px;
	padding: 0 var(--sp-2);
	background: var(--inputbackgroundcolor);
	border: 1px solid var(--inputbordercolor) !important;
	border-radius: var(--r) !important;
	transition: border-color var(--t), box-shadow var(--t);
}
.select2-container--default .select2-selection--single .select2-selection__rendered {
	flex: 1 1 auto;
	min-width: 0;
	padding: 0;
	padding-right: var(--sp-5);
	line-height: 32px;
	color: var(--c-ink);
	font-size: 0.9375rem;
}
.select2-container--default .select2-selection--single .select2-selection__placeholder { color: var(--c-faint); }

.select2-container--default .select2-selection--single:hover { border-color: var(--c-border-strong) !important; }
.select2-container--default.select2-container--focus .select2-selection--single,
.select2-container--default.select2-container--open .select2-selection--single {
	border-color: var(--c-accent) !important;
	box-shadow: 0 0 0 3px var(--c-accent-ring);
}

/* Arrow: replace select2's CSS-triangle with a chevron matching the native
   selects and the nav carets. */
.select2-container--default .select2-selection--single .select2-selection__arrow {
	position: absolute;
	top: 0;
	right: 0;
	width: 30px;
	height: 100%;
	display: flex;
	align-items: center;
	justify-content: center;
	border: 0;
	background: transparent;
	pointer-events: none;
}
.select2-container--default .select2-selection--single .select2-selection__arrow b {
	display: none;		/* the stock 5px border-triangle */
}
.select2-container--default .select2-selection--single .select2-selection__arrow::after {
	content: "";
	width: 6px;
	height: 6px;
	margin-top: -3px;
	border-right: 1.6px solid var(--c-muted);
	border-bottom: 1.6px solid var(--c-muted);
	transform: rotate(45deg);
	transition: transform var(--t), border-color var(--t);
}
.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow::after {
	margin-top: 2px;
	transform: rotate(-135deg);
	border-color: var(--c-accent);
}

/* Clear ("x") control */
.select2-container--default .select2-selection--single .select2-selection__clear {
	margin-right: var(--sp-4);
	color: var(--c-faint);
	font-weight: 400;
}
.select2-container--default .select2-selection--single .select2-selection__clear:hover { color: var(--c-danger); }


/* ---- select2: multiple ---- */

.select2-container--default .select2-selection--multiple {
	min-height: 34px;
	padding: 2px var(--sp-1);
	background: var(--inputbackgroundcolor);
	border: 1px solid var(--inputbordercolor) !important;
	border-radius: var(--r) !important;
}
.select2-container--default.select2-container--focus .select2-selection--multiple {
	border-color: var(--c-accent) !important;
	box-shadow: 0 0 0 3px var(--c-accent-ring);
}
.select2-container--default .select2-selection--multiple .select2-selection__choice {
	margin: 3px 3px 3px 0;
	padding: 1px var(--sp-2);
	background: var(--c-accent-soft);
	border: 1px solid color-mix(in srgb, var(--c-accent) 26%, transparent);
	border-radius: var(--r-sm);
	color: var(--c-accent-ink);
	line-height: 1.6;
}
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove {
	margin-right: var(--sp-1);
	color: var(--c-accent-ink);
	opacity: 0.7;
}
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover { opacity: 1; }


/* ---- Dropdown panel ---- */

.select2-dropdown {
	background: var(--c-surface);
	border: 1px solid var(--c-border);
	border-radius: var(--r) !important;
	box-shadow: var(--sh-lg);
	color: var(--c-ink);
	overflow: hidden;
}
.select2-container--default .select2-search--dropdown { padding: var(--sp-2); }
.select2-container--default .select2-search--dropdown .select2-search__field {
	height: 32px;
	padding: 0 var(--sp-2);
	background: var(--inputbackgroundcolor);
	border: 1px solid var(--inputbordercolor);
	border-radius: var(--r-sm);
	color: var(--c-ink);
}
.select2-container--default .select2-search--dropdown .select2-search__field:focus {
	outline: none;
	border-color: var(--c-accent);
	box-shadow: 0 0 0 3px var(--c-accent-ring);
}
.select2-container--default .select2-results__options { padding: var(--sp-1); }
.select2-container--default .select2-results__option {
	padding: var(--sp-2) var(--sp-3);
	border-radius: var(--r-sm);
	color: var(--c-ink-2);
}
.select2-container--default .select2-results__option--highlighted[aria-selected],
.select2-container--default .select2-results__option--highlighted {
	background: var(--c-accent-soft) !important;
	color: var(--c-accent-ink) !important;
}
.select2-container--default .select2-results__option[aria-selected="true"] {
	background: var(--c-sunken);
	color: var(--c-ink);
	font-weight: 550;
}
.select2-container--default .select2-results__message { color: var(--c-muted); }


/* ---- Width floor inside edit forms ----
   Dolibarr sizes many of these selects from a maxwidth utility class and
   select2 copies that width verbatim, so short fields truncated their own
   value ("eratosth...", "Euro..."). A floor keeps the value readable and
   stops the column looking ragged; plain <select> elements (the hour/minute
   pairs beside date fields) are deliberately untouched. */
table.border .select2-container,
table.tableforfield .select2-container,
div.tabBar .select2-container {
	min-width: 190px;
	max-width: 100%;
}
/* Narrow-by-design pickers keep their size. */
table.border .select2-container.select2-container--focus[style*="width: 5"],
.select2-container.minwidth50, .select2-container.maxwidth50,
.select2-container.maxwidth75 { min-width: 0; }

@media only screen and (max-width: 767px) {
	table.border .select2-container,
	table.tableforfield .select2-container { min-width: 0; width: 100% !important; }
}


/* ---- Multi-select affordance ----
   A multiple-select with nothing chosen renders as an empty box: no chevron,
   no placeholder, nothing to say it opens a list. It reads as a text field.
   The chevron is drawn on the control so it matches the single selects. */
.select2-container--default .select2-selection--multiple {
	position: relative;
	padding-right: 28px;
	cursor: pointer;
}
.select2-container--default .select2-selection--multiple::after {
	content: "";
	position: absolute;
	top: 50%;
	right: 11px;
	width: 6px;
	height: 6px;
	margin-top: -5px;
	border-right: 1.6px solid var(--c-muted);
	border-bottom: 1.6px solid var(--c-muted);
	transform: rotate(45deg);
	pointer-events: none;
	transition: transform var(--t), border-color var(--t);
}
.select2-container--default.select2-container--open .select2-selection--multiple::after {
	margin-top: -1px;
	transform: rotate(-135deg);
	border-color: var(--c-accent);
}
/* The inline search field is the only thing in an empty control, so it has to
   carry the width rather than collapse to a caret. */
.select2-container--default .select2-selection--multiple .select2-search--inline .select2-search__field {
	margin: 0;
	padding: 0 var(--sp-1);
	min-width: 8em;
	line-height: 30px;
	font-family: inherit;
}

/* ---- Dropdown panel width ----
   `width: auto !important` overrode the inline width select2 copies from the
   control, so the panel collapsed to its content and a 420px field opened a
   260px list -- the panel looked like it belonged to a different control.
   Dropping the override lets it track the control again; the floor stays for
   genuinely narrow filter selects. */
.select2-dropdown {
	min-width: 260px;
	max-width: 90vw;
}
.select2-container--default .select2-results__option {
	line-height: 1.45;
	white-space: normal;
	overflow-wrap: anywhere;
}
.select2-results__options { max-height: 320px; }

/* ==========================================================================
   Status pills
   Dolibarr emits <span class="badge badge-statusN badge-status">. The numbered
   variant carries the meaning (4 = open/active, 8 = closed, ...), so the tint is
   attached to the number and the shape to the shared class.
   ========================================================================== */
.badge-status {
	display: inline-flex;
	align-items: center;
	gap: var(--sp-1);
	padding: 2px var(--sp-2);
	min-height: 22px;
	border-radius: var(--r-pill);
	font-size: 0.75rem;
	font-weight: 600;
	line-height: 1.4;
	letter-spacing: 0;
	border: 1px solid transparent;
	white-space: nowrap;
}
/* Draft / neutral */
.badge-status0, .badge-status9 {
	background: var(--c-sunken); color: var(--c-muted);
	border-color: var(--c-border);
}
/* Open / validated / active */
.badge-status1, .badge-status4 {
	background: color-mix(in srgb, var(--c-success) 10%, transparent);
	color: var(--c-success);
	border-color: color-mix(in srgb, var(--c-success) 22%, transparent);
}
/* In progress / waiting */
.badge-status3, .badge-status7 {
	background: color-mix(in srgb, var(--c-warning) 12%, transparent);
	color: var(--c-warning);
	border-color: color-mix(in srgb, var(--c-warning) 24%, transparent);
}
/* Cancelled / refused */
.badge-status5, .badge-status8 {
	background: color-mix(in srgb, var(--c-danger) 9%, transparent);
	color: var(--c-danger);
	border-color: color-mix(in srgb, var(--c-danger) 20%, transparent);
}
/* Paid / closed positively */
.badge-status6 {
	background: var(--c-accent-soft); color: var(--c-accent-ink);
	border-color: color-mix(in srgb, var(--c-accent) 20%, transparent);
}

/* Semantic record natures are data, not disabled controls. Dolibarr adds
   opacitymedium to some values (notably Prospect), which made otherwise
   identical nature badges look unavailable. Keep their semantic treatment at
   full strength everywhere they are rendered. */
a.opacitymedium:is(.customer-back, .vendor-back, .prospect-back),
span.opacitymedium:is(.customer-back, .vendor-back, .prospect-back) {
	opacity: 1 !important;
}

/* ==========================================================================
   Action hierarchy
   One filled accent action, everything else a quiet surface button. Dolibarr
   decides which is which through its own classes, so the hierarchy follows the
   markup instead of the page.
   ========================================================================== */
.butAction, .butActionDelete, .butActionRefused, .butActionNew,
a.butAction, a.butActionDelete, a.butActionRefused, a.butActionNew {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--sp-2);
	min-height: 34px;
	padding: 0 var(--sp-4);
	border-radius: var(--r);
	font-size: 0.8125rem;
	font-weight: 600;
	line-height: 1;
	text-transform: none;
	letter-spacing: 0;
	border: 1px solid var(--c-border);
	background: var(--c-surface);
	color: var(--c-ink-2);
	box-shadow: var(--sh-sm);
	transition: background var(--t), border-color var(--t), color var(--t), box-shadow var(--t);
}
.butAction:hover, a.butAction:hover {
	background: var(--c-sunken);
	border-color: var(--c-border-strong);
	color: var(--c-ink);
}
.butAction:focus-visible, .butActionNew:focus-visible,
a.butAction:focus-visible, a.butActionNew:focus-visible {
	/* The configured action colour also owns the visible keyboard focus ring. */
	outline: 2px solid color-mix(in srgb, var(--c-btn-action, var(--c-accent)) 62%, transparent);
	outline-offset: 2px;
}
/* The primary action on a record: Dolibarr marks it butActionNew, or it is the
   first butAction in the bar. Only one is filled, so the eye has one target. */
.butActionNew, a.butActionNew,
div.tabsAction .butAction:first-of-type, div.tabsAction a.butAction:first-of-type {
	/* The filled action honours the colour configured in Display > Skin and
	   colours, falling back to the theme accent when none is set. */
	background: var(--c-btn-action, var(--c-accent));
	border-color: var(--c-btn-action, var(--c-accent));
	color: var(--c-btn-action-text, #fff);
	box-shadow: 0 1px 2px var(--c-accent-ring);
}
.butActionNew:hover, a.butActionNew:hover,
div.tabsAction .butAction:first-of-type:hover, div.tabsAction a.butAction:first-of-type:hover {
	background: var(--c-btn-action, var(--c-accent-hover));
	border-color: var(--c-btn-action, var(--c-accent-hover));
	color: var(--c-btn-action-text, #fff);
	filter: brightness(0.94);
}
.butActionDelete, a.butActionDelete {
	background: var(--c-surface);
	border-color: color-mix(in srgb, var(--c-danger) 28%, transparent);
	color: var(--c-danger);
}
.butActionDelete:hover, a.butActionDelete:hover {
	background: color-mix(in srgb, var(--c-danger) 8%, transparent);
	border-color: var(--c-danger);
	color: var(--c-danger);
}
.butActionRefused, a.butActionRefused {
	background: var(--c-sunken);
	border-color: var(--c-border);
	color: var(--c-faint);
	box-shadow: none;
	cursor: not-allowed;
}
/* The action bar itself: a right-aligned row that wraps instead of overflowing. */
div.tabsAction {
	display: flex;
	flex-wrap: wrap;
	justify-content: flex-end;
	align-items: center;
	gap: var(--sp-2);
	margin: var(--sp-4) 0;
}
div.tabsAction > * { margin: 0; }
/* Dolibarr often prints search and clear as adjacent icon submits inside a
   nowrap helper. Give the real controls a deliberate gap and identical square
   geometry everywhere instead of letting their borders fuse. */
.nowraponall:has(> .button_search + .button_removefilter) {
	display: inline-flex;
	align-items: center;
	gap: var(--sp-2);
}
.nowraponall:has(> .button_search + .button_removefilter) > .button_search,
.nowraponall:has(> .button_search + .button_removefilter) > .button_removefilter {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	min-height: 40px;
	margin: 0 !important;
	padding: 0 !important;
	border: 1px solid var(--c-border) !important;
	border-radius: var(--r) !important;
	line-height: 1;
}
/* Only the commercial quick-create group gets a surface of its own.  Other
   action rows stay on their page canvas and inherit no accidental card chrome. */
.ts-commercial-create-actions {
	box-sizing: border-box;
	width: 100%;
	padding: 14px 16px;
	margin: 0 0 var(--sp-4) !important;
	background: var(--c-surface);
	border: 1px solid var(--c-border);
	border-radius: var(--r-lg);
	box-shadow: var(--sh-sm);
}
.ts-commercial-create-actions > * { flex: 0 0 auto; }
@media (max-width: 640px) {
	.ts-commercial-create-actions { justify-content: stretch; }
	.ts-commercial-create-actions > * { flex: 1 1 180px; }
}

/* ==========================================================================
   List filter row
   The filter inputs share the table header band. Giving them one control style
   makes the band read as a filter bar rather than a second header row.
   ========================================================================== */
tr.liste_titre_filter > td, tr.liste_titre_filter > th {
	background: var(--c-surface);
	border-bottom: 1px solid var(--c-hairline);
	padding: var(--sp-2) var(--sp-3);
	vertical-align: middle;
}
tr.liste_titre_filter input[type="text"],
tr.liste_titre_filter input[type="search"],
tr.liste_titre_filter select,
tr.liste_titre_filter .select2-selection {
	min-height: 32px;
	border-radius: var(--r-sm);
	border: 1px solid var(--c-border);
	background: var(--c-surface);
	font-size: 0.8125rem;
}
tr.liste_titre_filter input:focus,
tr.liste_titre_filter select:focus {
	border-color: var(--c-accent);
	box-shadow: 0 0 0 3px var(--c-accent-ring);
	outline: none;
}

/* ==========================================================================
   Pagination
   ========================================================================== */
.pagination select, select.flat.selectlimit {
	min-height: 32px;
	border-radius: var(--r-sm);
	border: 1px solid var(--c-border);
	background: var(--c-surface);
	font-size: 0.8125rem;
	padding: 0 var(--sp-2);
}
.pagination a, .pagination .paginationafterarrows a, li.pagination a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 30px;
	min-height: 30px;
	padding: 0 var(--sp-2);
	border-radius: var(--r-sm);
	color: var(--c-ink-2);
	transition: background var(--t), color var(--t);
}
.pagination a:hover { background: var(--c-sunken); color: var(--c-ink); }
.pagination .active, .pagination li.active > a, .pagination .pageplusone.active {
	background: var(--c-btn-action);
	color: var(--c-btn-action-text);
	font-weight: 600;
}

/* ==========================================================================
   Empty states
   Dolibarr prints a muted "None" / "No record found" where a table would be.
   Centring it and giving it room turns a stray word into a deliberate state.
   ========================================================================== */
tr.oddeven td.opacitymedium:only-child,
td.opacitymedium[colspan]:only-child,
tr td.center.opacitymedium[colspan] {
	padding: var(--sp-7) var(--sp-4);
	text-align: center;
	color: var(--c-faint);
	font-size: 0.875rem;
}

/* ==========================================================================
   Responsive
   The action bar and filter controls are the two rows that overflow first on a
   narrow window, so they stack rather than scroll.
   ========================================================================== */
@media only screen and (max-width: 900px) {
	div.tabsAction { justify-content: stretch; }
	div.tabsAction > * { flex: 1 1 auto; }
	.pagination select, select.flat.selectlimit { width: auto; }
}

/* ==========================================================================
   Record header (paired with thriveshell/modern.js)
   The JS moves Dolibarr's own action bar into the banner and derives a
   breadcrumb from its "Back to list" link. These rules only apply once that has
   happened -- .ts-has-actions is set by the script -- so a page the script
   skipped keeps Dolibarr's original layout untouched.
   ========================================================================== */
.ts-breadcrumb {
	display: flex; align-items: center; gap: var(--sp-2);
	margin: 0 0 var(--sp-3);
	font-size: 0.8125rem; color: var(--c-muted);
}
.ts-breadcrumb a { color: var(--c-accent-ink); font-weight: 500; text-decoration: none; }
.ts-breadcrumb a:hover { text-decoration: underline; }
.ts-breadcrumb-sep { color: var(--c-faint); }
.ts-breadcrumb-current { color: var(--c-ink); font-weight: 600; }

div.arearef.ts-has-actions {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: var(--sp-4);
	flex-wrap: wrap;
}
.ts-header-actions { margin-left: auto; flex: 0 0 auto; }
.ts-header-actions {
	max-width: min(100%, 900px);
}
.ts-header-actions div.tabsAction {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: flex-end;
	gap: var(--sp-2);
	margin: 0;
}
.ts-header-actions div.tabsAction > a,
.ts-header-actions div.tabsAction > button,
.ts-header-actions div.tabsAction > input,
.ts-header-actions div.tabsAction > .inline-block,
.ts-header-actions div.tabsAction > details {
	flex: 0 0 auto;
	margin: 0 !important;
}
@media only screen and (max-width: 900px) {
	div.arearef.ts-has-actions { flex-direction: column; }
	.ts-header-actions { margin-left: 0; width: 100%; }
	/* The identity and the actions carry a flex-basis sized for the row they
	   sit in side by side. Once the banner stacks, that basis is read as a
	   height instead: the identity was held open at 320px and its name floated
	   in the middle of an empty band, on every record with an action bar. */
	div.arearef.ts-has-actions > .refid,
	div.arearef.ts-has-actions > .ts-entity-identity,
	div.arearef.ts-has-actions > .ts-header-actions {
		flex: 0 0 auto !important;
		width: 100%;
		min-width: 0;
	}
}

/* Dolibarr pins its record pager ("Back to list", prev/next) to the top-right of
   the banner, which is exactly where the relocated actions now sit -- the two
   painted over each other. Returning it to normal flow lets the flex row lay both
   out. The pager keeps its arrows: the breadcrumb repeats the "Back to list"
   target but not the record-to-record navigation, so nothing is lost. */
div.arearef.ts-has-actions .pagination.paginationref {
	position: static;
	float: none;
	order: 3;
	margin-left: var(--sp-3);
	white-space: nowrap;
}
div.arearef.ts-has-actions .ts-header-actions { order: 2; }
div.arearef.ts-has-actions .refid {
	display: grid;
	grid-template-columns: auto auto 1fr;
	align-items: center;
	column-gap: var(--sp-2);
	row-gap: var(--sp-1);
}
div.arearef .refidno > a.ts-vcard-download,
div.arearef a.ts-vcard-download {
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	width: 26px !important;
	height: 26px;
	margin: 0 0 0 var(--sp-1) !important;
	border-radius: 7px;
	color: var(--c-muted) !important;
	font-size: 13px !important;
	font-weight: 400 !important;
	vertical-align: middle;
}
div.arearef a.ts-vcard-download:hover,
div.arearef a.ts-vcard-download:focus-visible {
	background: var(--c-accent-soft);
	color: var(--c-accent) !important;
}
div.arearef a.ts-vcard-download > span {
	margin: 0 !important;
	padding: 0 !important;
	font-size: inherit !important;
}
/* A record can print more than one line under its name -- a contact shows both
   its third-party link and its address block -- and pinning them all to row 2
   stacked them in the same cell, one printed over the other. They span the full
   width and take the next row each. */
div.arearef.ts-has-actions .refid .refidno { grid-column: 1 / -1; }
div.arearef.ts-has-actions .refid .statusref { grid-column: 3; grid-row: 1; display: inline-flex; margin: 0 0 0 var(--sp-2); }
div.arearef.ts-has-actions .divphotoref {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 56px;
	height: 56px;
	margin-right: var(--sp-4);
	border-radius: var(--r-lg);
	background: var(--c-accent-soft);
	color: var(--c-accent-ink);
}
div.arearef.ts-has-actions .divphotoref .photoref,
div.arearef.ts-has-actions .divphotoref .pictotitle { margin: 0; font-size: 1.5rem; }

/* Compact entity card: identity and frequent actions share the first row, with
   record navigation immediately below. The containing tabBar supplies the full
   content width, rather than mounting this structure in a title-table cell. */
div.tabBar.ts-entity-card {
	padding: 0;
	background: var(--c-surface);
	border: 1px solid var(--c-hairline);
	border-radius: var(--r-lg);
	box-shadow: var(--sh-sm);
	overflow: visible;
}
div.tabBar.ts-entity-card > div.arearef.ts-has-actions {
	padding: var(--sp-4) var(--sp-5);
	border-bottom: 0;
	border-radius: var(--r-lg) var(--r-lg) 0 0;
}
div.tabBar.ts-entity-card > div.tabs[data-ts-placed="1"] {
	margin: 0;
	padding: 0 var(--sp-4);
	border-top: 1px solid var(--c-hairline);
	border-bottom: 1px solid var(--c-hairline);
	background: var(--c-surface);
}
div.tabBar.ts-entity-card > div.tabs[data-ts-placed="1"] + * { margin-top: var(--sp-4); }

/* Edit stays primary, Send email secondary. The lower-frequency controls are the
   original Dolibarr nodes inside a disclosure, preserving hooks and tokens. */
div.tabsAction .ts-record-primary,
div.tabsAction a.ts-record-primary:first-of-type {
	background: var(--c-btn-action, var(--c-accent));
	border-color: var(--c-btn-action, var(--c-accent));
	color: var(--c-btn-action-text, #fff);
}
div.tabsAction .ts-record-secondary {
	background: var(--c-surface);
	border-color: var(--c-border);
	color: var(--c-ink-2);
}
.ts-header-actions div.tabsAction > .ts-record-primary { order: 1; }
.ts-header-actions div.tabsAction > .ts-record-secondary { order: 2; }
.ts-header-actions div.tabsAction > .ts-more-actions { order: 3; }
/* A legacy first-of-type rule can otherwise promote the first visible action
   (often Send email) even after the composer has identified Modify as the
   primary record action. The header classes are the semantic authority. */
.ts-header-actions div.tabsAction > .ts-record-primary {
	background: var(--c-btn-action, var(--c-accent)) !important;
	border-color: var(--c-btn-action, var(--c-accent)) !important;
	color: var(--c-btn-action-text, #fff) !important;
}
.ts-header-actions div.tabsAction > .ts-record-secondary {
	background: var(--c-surface) !important;
	border-color: var(--c-border) !important;
	color: var(--c-ink-2) !important;
	box-shadow: none !important;
}
.ts-more-actions { position: relative; flex: 0 0 auto; }
.ts-more-actions > summary { list-style: none; }
.ts-more-actions > summary::-webkit-details-marker { display: none; }
.ts-more-actions-trigger {
	display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
	min-height: 34px; padding: 0 var(--sp-3);
	border: 1px solid var(--c-border); border-radius: var(--r);
	background: var(--c-surface); color: var(--c-ink-2);
	font-size: 0.8125rem; font-weight: 600; cursor: pointer;
	box-shadow: var(--sh-sm);
}
.ts-more-actions-trigger:hover,
.ts-more-actions[open] .ts-more-actions-trigger { background: var(--c-sunken); color: var(--c-ink); }
.ts-more-actions-trigger:focus-visible { outline: 2px solid var(--c-accent); outline-offset: 2px; }
.ts-more-actions-trigger .fa-chevron-down { font-size: 0.625rem; transition: transform var(--t); }
.ts-more-actions[open] .fa-chevron-down { transform: rotate(180deg); }
.ts-more-actions-menu {
	position: absolute; z-index: 40; top: calc(100% + var(--sp-2)); right: 0;
	min-width: 180px; padding: var(--sp-1);
	background: var(--c-surface); border: 1px solid var(--c-border);
	border-radius: var(--r); box-shadow: var(--sh-lg);
}
.ts-more-actions-menu .ts-more-action-item,
.ts-more-actions-menu a.ts-more-action-item,
.ts-more-actions-menu span.ts-more-action-item {
	display: flex; align-items: center; justify-content: flex-start;
	width: 100%; min-height: 36px; margin: 0; padding: 0 var(--sp-3);
	border: 0; border-radius: var(--r-sm); box-shadow: none !important;
	/* This overrides the legacy first-of-type filled-action rule for a moved
	   Clone/Create link. Only genuinely destructive actions are red below. */
	background: transparent !important; color: var(--c-ink-2) !important; cursor: pointer;
}
.ts-more-actions-menu .ts-more-action-item:hover { background: var(--c-sunken) !important; color: var(--c-ink) !important; }
.ts-more-actions-menu .ts-more-action-item.butActionDelete { color: var(--c-danger) !important; }

@media only screen and (max-width: 900px) {
	div.tabBar.ts-entity-card > div.arearef.ts-has-actions { padding: var(--sp-4); }
	.ts-header-actions div.tabsAction { width: 100%; }
	.ts-header-actions div.tabsAction > .ts-record-primary,
	.ts-header-actions div.tabsAction > .ts-record-secondary { flex: 1 1 160px; }
	.ts-more-actions { flex: 0 0 auto; }
}
@media only screen and (max-width: 640px) {
	.ts-header-actions div.tabsAction > .ts-record-primary,
	.ts-header-actions div.tabsAction > .ts-record-secondary { flex: 1 1 calc(50% - var(--sp-2)); }
	.ts-header-actions div.tabsAction > .ts-more-actions { flex: 1 1 100%; }
	.ts-more-actions-trigger { width: 100%; }
	.ts-more-actions-menu { left: 0; right: 0; }
}

/* ==========================================================================
   Declarative Third Party field groups
   The companion hook maps translated labels to stable data-field attributes.
   Layout only consumes data-group, and activates only when every native row was
   mapped, so custom or future fields always fall back to Dolibarr's safe layout.
   ========================================================================== */
.ts-thirdparty-groups {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	align-items: stretch;
	gap: var(--sp-4);
	padding: 0 var(--sp-4) var(--sp-4);
}
.ts-field-group {
	min-width: 0;
	background: var(--c-surface);
	border: 1px solid var(--c-hairline);
	border-radius: var(--r-lg);
	box-shadow: var(--sh-sm);
	overflow: hidden;
	display: flex;
	flex-direction: column;
}
.ts-field-group-title {
	margin: 0;
	padding: var(--sp-3) var(--sp-4);
	border-bottom: 1px solid var(--c-hairline);
	font-size: 0.9375rem;
	font-weight: 650;
	line-height: 1.4;
	color: var(--c-ink);
	display: flex;
	align-items: center;
	gap: var(--sp-2);
}
.ts-field-group-icon { color: var(--c-accent); width: 18px; text-align: center; }
.ts-field-group td.ts-empty-value::after { content: "—"; color: var(--c-faint); }
.ts-field-group table.tableforfield { margin: 0; border: 0; box-shadow: none; flex: 1 1 auto; }
.ts-field-group table.tableforfield td { padding: 10px var(--sp-4); font-size: 0.8125rem; line-height: 1.35; }
.ts-field-group table.tableforfield tr + tr { border-top: 1px solid var(--c-hairline); }
.ts-field-group table.tableforfield td:first-child { color: var(--c-ink-2); font-weight: 600; }
@media only screen and (max-width: 1400px) {
	.ts-thirdparty-groups { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.ts-field-group[data-group="identity"] { grid-row: span 2; }
}
@media only screen and (max-width: 900px) {
	.ts-thirdparty-groups { grid-template-columns: minmax(0, 1fr); padding: 0 var(--sp-3) var(--sp-3); }
	.ts-field-group[data-group="identity"] { grid-row: auto; }
}

/* Dolibarr tags Merge with butActionDelete, so it inherited the destructive red
   and sat next to Delete looking equally final -- but merging is not a deletion.
   Only the merge action is exempted, by its own href, and it is exempted *back to*
   the neutral surface button rather than given a style of its own.

   The exemption is deliberately narrow: anything else Dolibarr or a module tags as
   destructive keeps the red. Losing a warning on a genuinely destructive action is
   worse than over-warning on one that is not, so the unknown case stays red. This
   is presentation only -- the href, its confirmation step and its behaviour are
   untouched. */
div.tabsAction a.butActionDelete[href*="action=merge"],
div.tabsAction a.butActionDelete[href*="action=confirm_merge"] {
	background: var(--c-surface);
	border-color: var(--c-border);
	color: var(--c-ink-2);
}
div.tabsAction a.butActionDelete[href*="action=merge"]:hover,
div.tabsAction a.butActionDelete[href*="action=confirm_merge"]:hover {
	background: var(--c-sunken);
	border-color: var(--c-border-strong);
	color: var(--c-ink);
}

/* ==========================================================================
   List page header
   Dolibarr prints "Third parties(39)" as one string in div.titre and renders the
   page actions as icon-only a.btnTitle links whose label lives in @title.
   modern.js splits the count into .ts-count; the label is drawn from the title
   attribute, so it stays translated and no text is invented here.
   ========================================================================== */
div.titre {
	font-size: 1.375rem;
	font-weight: 650;
	letter-spacing: -0.02em;
	color: var(--c-ink);
	display: inline-flex;
	align-items: center;
	gap: var(--sp-2);
}
.ts-count {
	display: inline-flex; align-items: center; justify-content: center;
	min-width: 24px; height: 22px; padding: 0 var(--sp-2);
	border-radius: var(--r-pill);
	background: var(--c-sunken); color: var(--c-muted);
	font-size: 0.75rem; font-weight: 600; letter-spacing: 0;
}
/* The create action is the only btnTitle carrying a plus glyph. Promoting it to a
   labelled primary button uses @title, which Dolibarr has already translated. */
div.pagination a.btnTitle:has(.fa-plus-circle), div.pagination a.btnTitle:has(.fa-plus) {
	display: inline-flex; align-items: center; gap: var(--sp-2);
	min-height: 34px; padding: 0 var(--sp-4);
	border-radius: var(--r);
	background: var(--c-btn-action); border: 1px solid var(--c-btn-action); color: var(--c-btn-action-text);
	font-size: 0.8125rem; font-weight: 600; line-height: 1;
	box-shadow: 0 1px 2px var(--c-btn-action-ring);
	transition: background var(--t), border-color var(--t);
}
div.pagination a.btnTitle:has(.fa-plus-circle):hover, div.pagination a.btnTitle:has(.fa-plus):hover {
	filter: brightness(.94);
}
div.pagination a.btnTitle:has(.fa-plus-circle)::after, div.pagination a.btnTitle:has(.fa-plus)::after {
	content: attr(title);
	font: inherit;
}
div.pagination a.btnTitle:has(.fa-plus-circle) .btnTitle-label,
div.pagination a.btnTitle:has(.fa-plus) .btnTitle-label { display: none; }   /* @title already prints it */
div.pagination a.btnTitle:has(.fa-plus-circle) span[class*="fa-"],
div.pagination a.btnTitle:has(.fa-plus) span[class*="fa-"] { color: currentColor; }
/* Secondary title actions (view mode, tools) stay quiet next to it. */
a.btnTitle:not(:has(.fa-plus-circle)):not(:has(.fa-plus)) {
	display: inline-flex; align-items: center; justify-content: center;
	min-width: 32px; min-height: 32px;
	border-radius: var(--r-sm); color: var(--c-muted);
	transition: background var(--t), color var(--t);
}
a.btnTitle:not(:has(.fa-plus-circle)):not(:has(.fa-plus)):hover {
	background: var(--c-sunken); color: var(--c-ink);
}

/* ==========================================================================
   Record detail sections as cards (generic)
   Dolibarr's own left/right split is the only structure it reliably provides, so
   each half becomes a card. No group titles are invented: the markup carries no
   dependable per-field semantics, so naming them would be guesswork.
   ========================================================================== */
div.fichehalfleft, div.fichehalfright {
	background: var(--c-surface);
	border: 1px solid var(--c-hairline);
	border-radius: var(--r-lg);
	box-shadow: var(--sh-sm);
	padding: var(--sp-2) var(--sp-4);
	box-sizing: border-box;
}
div.fichehalfleft table td, div.fichehalfright table td {
	padding-top: var(--sp-3);
	padding-bottom: var(--sp-3);
}
/* Borrowed from the Novo review: one deliberate breakpoint, so the two halves
   stack instead of the page acquiring a horizontal scrollbar. */
@media only screen and (max-width: 1100px) {
	div.fichehalfleft, div.fichehalfright { width: 100%; float: none; margin-bottom: var(--sp-4); }
}

/* ==========================================================================
   Linked files / events blocks as cards, with a considered empty state
   ========================================================================== */
div.fichecenter div.fichehalfleft .div-table-responsive,
div.fichecenter div.fichehalfright .div-table-responsive { box-shadow: none; border: 0; }
.ts-emptybox {
	border: 1px dashed var(--c-border-strong);
	border-radius: var(--r-lg);
	background: var(--c-canvas);
	padding: var(--sp-7) var(--sp-4);
	text-align: center;
	color: var(--c-faint);
	font-size: 0.875rem;
}
.ts-record-section-card {
	background: var(--c-surface);
	border: 1px solid var(--c-hairline);
	border-radius: var(--r-lg);
	box-shadow: var(--sh-sm);
	padding: var(--sp-4);
	box-sizing: border-box;
	min-height: 270px;
}
.ts-record-section-card table.table-fiche-title td.col-picto { display: none; }
.ts-record-section-card table.table-fiche-title { margin: 0 0 var(--sp-3); }
.ts-record-section-card table.table-fiche-title td.col-title,
.ts-record-section-card .titre {
	display: flex;
	align-items: center;
	gap: var(--sp-2);
	font-size: 0.9375rem;
	font-weight: 650;
}
.ts-record-section-card .ts-section-icon { color: var(--c-accent); }
.ts-record-section-files .ts-native-empty-source { display: none; }
/* The toolbar that generates a document is emitted as the heading row of the
   documents table, so it arrived dressed as a column header: centred, bold,
   and on a tinted band -- a form control wearing a table's clothes. It is a
   toolbar, so it reads as one: label, control and action on a line, aligned
   with the card rather than floating in the middle of it. */
.ts-record-section-files table.formdoc tr.liste_titre,
.ts-record-section-files table.formdoc tr.liste_titre > th,
.ts-record-section-files table.formdoc tr.liste_titre > td {
	padding: 12px 16px !important;
	background: transparent !important;
	border-bottom: 1px solid var(--c-hairline) !important;
	text-align: left !important;
	font-weight: 400 !important;
	white-space: nowrap;
	vertical-align: middle;
}
.ts-record-section-files table.formdoc tr.liste_titre span.hideonsmartphone {
	margin-right: var(--sp-2);
	color: var(--c-muted);
	font-size: 0.75em;
	font-weight: 500;
	vertical-align: middle;
}
.ts-record-section-files table.formdoc select,
.ts-record-section-files table.formdoc .select2-container {
	min-width: 170px !important;
	/* The container reports its own height rather than the control's, which
	   left it half a control short of the button beside it. */
	height: 34px !important;
	margin-right: var(--sp-2);
	vertical-align: middle;
}
/* The value inside the control inherited the heading's weight and centring. */
.ts-record-section-files table.formdoc .select2-selection--single {
	height: 34px !important;
}
.ts-record-section-files table.formdoc .select2-selection--single .select2-selection__rendered {
	padding-left: 10px;
	font-weight: 400 !important;
	line-height: 32px !important;
	text-align: left !important;
}
.ts-record-section-files table.formdoc .select2-selection--single .select2-selection__arrow {
	height: 32px !important;
}
.ts-record-section-files table.formdoc input.buttongen {
	height: 34px !important;
	padding: 0 14px !important;
	font-weight: 550;
	vertical-align: middle;
}
.ts-record-section-card .ts-emptybox {
	min-height: 150px;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: var(--sp-2);
}
.ts-record-section-card .ts-emptybox > .far { font-size: 1.5rem; color: var(--c-muted); }
.ts-record-section-card .ts-emptybox > strong { color: var(--c-ink-2); }
.ts-record-section-card .ts-emptybox > span:last-child { font-size: 0.8125rem; }

/* The title-bar actions share div.pagination with the pager. Adding a label to the
   create button widened that row, and as a rigid row it pushed the button past the
   viewport. It wraps instead -- and below 1200px the label is dropped back to the
   icon, which is a chosen breakpoint rather than an accidental scrollbar. */
div.pagination {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: flex-end;
	gap: var(--sp-2);
	max-width: 100%;
}
@media only screen and (max-width: 1200px) {
	div.pagination a.btnTitle:has(.fa-plus-circle)::after, div.pagination a.btnTitle:has(.fa-plus)::after { content: none; }
	div.pagination a.btnTitle:has(.fa-plus-circle), div.pagination a.btnTitle:has(.fa-plus) { padding: 0 var(--sp-3); }
}

/* At phone widths the title bar is a table row, so the actions cell cannot wrap
   under the heading and the pager ran off the side (clipped, and out of reach).
   Letting those cells become blocks stacks the heading and its actions instead. */
@media only screen and (max-width: 768px) {
	div.titre_list > table, table.centpercent.notopnoleftnoright { display: block; width: 100%; }
	table.centpercent.notopnoleftnoright > tbody,
	table.centpercent.notopnoleftnoright > tbody > tr { display: block; width: 100%; }
	table.centpercent.notopnoleftnoright > tbody > tr > td { display: block; width: 100%; text-align: left; }
	div.pagination { justify-content: flex-left; }
}

/* ==========================================================================
   Record header corrections
   ========================================================================== */
/* Only the anchor the breadcrumb duplicated is hidden -- the pager's prev/next
   arrows sit beside it in the same block and keep working. */
div.arearef.ts-has-actions .paginationref a.ts-crumb-source { display: none; }

/* The banner reserved room for a pager that no longer prints its label, leaving a
   tall empty band between the title and the first field. */
div.arearef.ts-has-actions { padding-top: var(--sp-2); padding-bottom: var(--sp-2); }
div.arearef.ts-has-actions .refid,
div.arearef.ts-has-actions .refidno { margin-top: 0; margin-bottom: 0; }
div.arearef.ts-has-actions + div,
div.tabBar > div.arearef.ts-has-actions { margin-bottom: var(--sp-3); }
div.arearef.ts-has-actions .paginationref { align-self: center; }

/* ==========================================================================
   Tabs: one row, scrolled rather than wrapped
   A wrapped second row is the most legacy-looking part of a record page. Keeping
   them on one line and scrolling the overflow avoids measuring anything in JS.
   The scrollbar chrome is hidden but the strip stays focusable and swipeable, so
   keyboard and touch reach the tabs the scrollbar would have revealed.
   ========================================================================== */
div.tabs, ul.tabs, div.tabBar > div.tabs {
	display: flex;
	flex-wrap: nowrap;
	align-items: stretch;
	gap: var(--sp-1);
	overflow-x: auto;
	overflow-y: hidden;
	scrollbar-width: none;
	-webkit-overflow-scrolling: touch;
	overscroll-behavior-x: contain;
	max-width: 100%;
}
div.tabs::-webkit-scrollbar, ul.tabs::-webkit-scrollbar { height: 0; width: 0; }
div.tabs a.tab, div.tabs .tabsElem, ul.tabs a.tab, ul.tabs li.tabsElem {
	white-space: nowrap;
	flex: 0 0 auto;
}
div.tabs a.tab, ul.tabs a.tab {
	display: inline-flex;
	align-items: center;
	gap: var(--sp-2);
	padding: var(--sp-3) var(--sp-3);
	font-size: 0.8125rem;
	border-radius: var(--r-sm) var(--r-sm) 0 0;
}
/* Focus must stay visible: the strip scrolls, so a tab reached by keyboard has to
   announce itself even though the scrollbar is hidden. */
div.tabs a.tab:focus-visible, ul.tabs a.tab:focus-visible {
	outline: 2px solid var(--c-accent);
	outline-offset: -2px;
}

/* ==========================================================================
   Sections below a record (Linked files, Events, ...)
   Dolibarr reuses div.titre for these, the same class as a list's page title, so
   they inherited page-title weight and read as if each were a new page. Their
   Their location inside div.fichecenter separates a section heading from a
   page heading; td.col-title is used for both and is not a safe discriminator.
   ========================================================================== */
div.fichecenter td.col-title div.titre,
div.fichecenter .col-title div.titre {
	font-size: 1rem;
	font-weight: 620;
	letter-spacing: -0.01em;
}
/* The block that follows each of those headings becomes the card. Scoped to the
   table wrapper Dolibarr already emits, so no section is restructured. */
td.col-title ~ td .div-table-responsive,
.col-title ~ td .div-table-responsive,
div.fichecenter .div-table-responsive,
div.fichecenter .div-table-responsive-no-min {
	background: var(--c-surface);
	border: 1px solid var(--c-hairline);
	border-radius: var(--r-lg);
	box-shadow: var(--sh-sm);
	overflow: hidden;
}
/* Actions that sit beside a section heading were colliding with it; the heading
   row lays them out instead of letting them overlap. */
tr:has(> td.col-title) {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--sp-3);
	flex-wrap: wrap;
	width: 100%;
}
tr:has(> td.col-title) > td { display: inline-flex; align-items: center; gap: var(--sp-2); }
tr:has(> td.col-title) > td.col-title { flex: 1 1 auto; }

/* A genuinely empty section reads as a considered state rather than a stray word.
   Only cells Dolibarr has actually marked empty are treated this way. */
div.fichecenter td.opacitymedium[colspan],
div.fichecenter tr.oddeven td.opacitymedium {
	border: 1px dashed var(--c-border-strong);
	border-radius: var(--r-lg);
	background: var(--c-canvas);
	padding: var(--sp-6) var(--sp-4);
	text-align: center;
	color: var(--c-faint);
}

/* A section heading has nowhere near the room of the page title bar, so a create
   action beside one stays an icon button and is not given a label it would only
   have to clip. */
.col-title ~ td a.btnTitle, tr:has(> td.col-title) a.btnTitle {
	display: inline-flex; align-items: center; justify-content: center;
	min-width: 30px; min-height: 30px; padding: 0 var(--sp-2);
	border-radius: var(--r-sm);
	background: var(--c-accent-soft); border: 1px solid transparent; color: var(--c-accent-ink);
	box-shadow: none; overflow: visible;
}
.col-title ~ td a.btnTitle::after, tr:has(> td.col-title) a.btnTitle::after { content: none; }
.col-title ~ td a.btnTitle span[class*="fa-"],
tr:has(> td.col-title) a.btnTitle span[class*="fa-"] { color: var(--c-accent-ink); }

/* ==========================================================================
   Record header: place the pager deliberately
   The banner is a flex row, and the pager block comes first in Dolibarr's markup,
   so once its "back to list" label was hidden the bare arrows wrapped above the
   title. Ordering the row puts the identity first and groups the pager with the
   actions on the right, where it reads as navigation for this record. No markup
   is moved: only the visual order changes, so prev/next keep their hrefs.
   ========================================================================== */
div.arearef.ts-has-actions > *:not(.ts-header-actions):not(.pagination) {
	order: 1;
	flex: 1 1 auto;
	min-width: 0;
}
div.arearef.ts-has-actions .ts-header-actions { order: 2; align-self: center; }
div.arearef.ts-has-actions .paginationref {
	order: 3;
	align-self: center;
	display: inline-flex;
	align-items: center;
	gap: var(--sp-1);
	flex: 0 0 auto;
}
div.arearef.ts-has-actions .paginationref { opacity: .72; }
div.arearef.ts-has-actions .paginationref a {
	display: inline-flex; align-items: center; justify-content: center;
	min-width: 28px; min-height: 28px;
	border-radius: var(--r-sm);
	color: var(--c-muted);
	transition: background var(--t), color var(--t);
}
div.arearef.ts-has-actions .paginationref a:hover { background: var(--c-sunken); color: var(--c-ink); }

/* ==========================================================================
   List filters as one surface
   Dolibarr splits filtering across a block above the table and a filter row
   inside it. Both are given the same surface treatment so they read as one
   control area, without moving either out of the form they post from.
   ========================================================================== */
div.liste_titre.liste_titre_bydiv {
	background: var(--c-surface);
	border: 1px solid var(--c-hairline);
	border-radius: var(--r-lg);
	box-shadow: var(--sh-sm);
	padding: var(--sp-3);
	margin-bottom: var(--sp-3);
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--sp-2);
}
div.liste_titre.liste_titre_bydiv .select2-container,
div.liste_titre.liste_titre_bydiv select,
div.liste_titre.liste_titre_bydiv input { max-width: 100%; }
@media only screen and (max-width: 900px) {
	div.liste_titre.liste_titre_bydiv > * { flex: 1 1 100%; }
}

/* ==========================================================================
   Results footer
   Dolibarr prints the row range, the page-size select and the pager separately
   at the foot of a list. They are laid out as one row so the foot of every list
   reads the same. Nothing is added that Dolibarr does not already render.
   ========================================================================== */
div.div-table-responsive + div.pagination,
.paginationatbottom,
div.fichecenter > form > div.pagination:last-child {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--sp-3);
	padding: var(--sp-3) var(--sp-1);
	margin-top: var(--sp-2);
	border-top: 1px solid var(--c-hairline);
	font-size: 0.8125rem;
	color: var(--c-muted);
}

/* ==========================================================================
   Corrections found by comparing screenshots against the target
   ========================================================================== */
/* The status pill was being treated as its own flex item in the banner row and
   drifted away from the name it belongs to. Only the identity block absorbs the
   free space; everything else keeps its natural width and stays put. */
div.arearef.ts-has-actions > *:not(.ts-header-actions):not(.pagination) { flex: 0 0 auto; }
div.arearef.ts-has-actions > div:first-of-type,
div.arearef.ts-has-actions > .refid:first-of-type { flex: 1 1 auto; min-width: 0; }

/* The create action shares a fixed-width cell with the pager and the view-mode
   switches, and as the last item in that row it was the one clipped when the
   label made it wider. Ordering it first means the least important controls give
   way instead of the primary action -- and it never shrinks. */
div.pagination a.btnTitle:has(.fa-plus-circle),
div.pagination a.btnTitle:has(.fa-plus) {
	order: -1;
	flex: 0 0 auto;
}
div.pagination { overflow: visible; }

/* The create action keeps the primary treatment but drops the generated label.
   Drawing it from @title widened the control inside a fixed-width cell it shares
   with the pager and the view switches, and it clipped -- first at the viewport
   edge, then inside its own container even after being ordered first. A filled
   icon button reads as the primary action without depending on how much room
   that cell happens to have, which varies by module and by how many pager
   controls a list renders. The label remains available as the tooltip. */
div.pagination a.btnTitle:has(.fa-plus-circle)::after,
div.pagination a.btnTitle:has(.fa-plus)::after { content: none; }
div.pagination a.btnTitle:has(.fa-plus-circle),
div.pagination a.btnTitle:has(.fa-plus) {
	min-width: 34px;
	padding: 0 var(--sp-2);
	justify-content: center;
}

/* ==========================================================================
   Page header (paired with buildPageHeader in modern.js)
   Title and count on the left, the primary create action on the right. The rules
   apply only once the script has built .ts-pagehead, so a page it skipped keeps
   Dolibarr's own header untouched.
   ========================================================================== */
.ts-pagehead {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--sp-4);
	flex-wrap: wrap;
	margin: 0 0 var(--sp-4);
}
.ts-pagehead-title { display: flex; align-items: center; gap: var(--sp-2); min-width: 0; }
.ts-pagehead-title div.titre { font-size: 1.375rem; font-weight: 650; letter-spacing: -0.02em; }
.ts-pagehead-actions { display: flex; align-items: center; gap: var(--sp-2); flex: 0 0 auto; }
.ts-view-switch {
	display: inline-flex;
	align-items: center;
	height: 38px;
	padding: 3px;
	border: 1px solid var(--c-border);
	border-radius: var(--r);
	background: var(--c-surface);
}
.ts-view-switch a.ts-view-switch-option {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 30px;
	height: 30px;
	min-width: 30px;
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: var(--r-sm);
	background: transparent;
	box-shadow: none;
	color: var(--c-muted);
}
.ts-view-switch a.ts-view-switch-option:hover { background: var(--c-sunken); color: var(--c-ink); }
.ts-view-switch a.ts-view-switch-option[aria-current="page"] {
	background: var(--c-accent-soft);
	color: var(--c-accent-ink);
}

/* In the header the create action has room for its label, so it is a full button
   again -- the earlier clipping came from the fixed-width pager cell it used to
   share, which it no longer sits in. */
.ts-pagehead a.btnTitle.ts-primary-action {
	display: inline-flex; align-items: center; gap: var(--sp-2);
	min-height: 36px; padding: 0 var(--sp-4); min-width: 0;
	border-radius: var(--r);
	background: var(--c-btn-action); border: 1px solid var(--c-btn-action); color: var(--c-btn-action-text);
	font-size: 0.8125rem; font-weight: 600; line-height: 1;
	box-shadow: 0 1px 2px var(--c-btn-action-ring);
	white-space: nowrap;
}
.ts-pagehead a.btnTitle.ts-primary-action:hover { filter: brightness(.94); }
.ts-pagehead a.btnTitle.ts-primary-action span[class*="fa-"] { color: currentColor; }
.ts-action-label { font: inherit; }
@media only screen and (max-width: 640px) {
	.ts-pagehead { align-items: stretch; }
	.ts-pagehead-actions { width: 100%; flex-wrap: wrap; }
	.ts-pagehead a.btnTitle.ts-primary-action { flex: 1 1 180px; width: auto; justify-content: center; }
}

/* ==========================================================================
   Coherent list composition (paired with composeListSurface in modern.js)
   The filter block stays in the submitting form, while the table and its result
   footer share a single card edge. Wide tables scroll inside that card only.
   ========================================================================== */
.ts-list-composition { display: grid; gap: var(--sp-3); min-width: 0; }
.ts-list-composition tr.ts-filter-row-extracted { display: none !important; }
body.ts-command-record-secondary .ts-list-composition { gap: 16px; }
body.ts-command-record-secondary .ts-list-composition .ts-filter-surface { padding: 12px; }
body.ts-command-record-secondary .ts-list-composition .ts-filter-surface .ts-quick-search {
	flex: 1 1 340px;
	width: min(100%, 380px);
	max-width: 380px;
}
body.ts-command-record-secondary .ts-list-composition .ts-filter-surface .ts-quick-search-input {
	width: 100% !important;
	max-width: none !important;
}
body.ts-command-record-secondary .ts-column-filters-panel {
	/* This anchored left from when the disclosure sat at the start of the filter
	   row. The toolbar now ends with it, so opening leftwards ran the panel off
	   the card and over the table. Anchor it to the control it belongs to and
	   size it to the filters it actually holds. */
	left: auto;
	right: 0;
	grid-template-columns: repeat(auto-fit, minmax(180px, max-content));
	width: max-content;
	max-width: min(680px, calc(100vw - var(--nav-w) - 48px));
}
body.ts-command-record-secondary .ts-list-card { overflow: visible; }
body.ts-command-record-secondary .ts-list-card .ts-record-tab-surface { margin: 0 !important; }
body.ts-command-record-secondary .ts-list-card .ts-results-footer { border-radius: 0 0 10px 10px; }
.ts-list-composition .ts-filter-surface {
	margin: 0;
	padding: var(--sp-3);
	border: 1px solid var(--c-hairline);
	border-radius: var(--r-lg);
	background: var(--c-surface);
	box-shadow: var(--sh-sm);
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 10px;
}
.ts-filter-surface .ts-quick-search {
	display: flex;
	align-items: center;
	gap: var(--sp-2);
	flex: 1 1 340px;
	width: auto;
	max-width: 380px;
	min-width: 240px;
	height: 38px;
	padding: 0 var(--sp-2) 0 var(--sp-3);
	border: 1px solid var(--c-border);
	border-radius: var(--r);
	background: var(--c-surface);
	color: var(--c-faint);
}
.ts-filter-surface .ts-quick-search:focus-within {
	border-color: var(--c-accent);
	box-shadow: 0 0 0 3px var(--c-accent-ring);
}
.ts-filter-surface input.ts-quick-search-input {
	flex: 1 1 auto;
	width: auto !important;
	min-width: 80px;
	height: 34px;
	padding: 0;
	border: 0 !important;
	box-shadow: none !important;
	background: transparent;
}
.ts-filter-surface .ts-submit-search,
.ts-filter-surface .ts-clear-filters {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 28px;
	height: 28px;
	padding: 0;
	border: 0;
	border-radius: var(--r-sm);
	background: transparent;
	color: var(--c-muted);
}
.ts-filter-surface .ts-submit-search { display: none !important; }
.ts-filter-surface .ts-submit-search:hover { background: var(--c-accent-soft); color: var(--c-accent-ink); }
.ts-filter-surface .ts-clear-filters:hover { background: var(--c-sunken); color: var(--c-ink); }
.ts-filter-surface .ts-clear-all-filters {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--sp-1);
	height: 32px;
	width: auto;
	flex: 0 0 auto;
	margin: 0 0 0 auto;
	padding: 0 var(--sp-1);
	border: 0;
	border-radius: var(--r);
	background: transparent;
	color: var(--c-accent-ink);
	font-size: 0.8125rem;
	font-weight: 550;
	white-space: nowrap;
}
.ts-filter-surface .ts-clear-all-filters:hover { background: var(--c-accent-soft); color: var(--c-accent); }
.ts-filter-surface .ts-clear-all-filters[hidden] { display: none !important; }
.ts-filter-surface .ts-clear-all-filters [class*="fa-"] { display: none; }
.ts-filter-surface .divsearchfield {
	margin: 0;
	flex: 0 1 190px;
	width: 190px;
	min-width: 180px;
}
.ts-filter-surface .ts-toolbar-filter-1 { flex-basis: 270px; width: 270px; min-width: 270px; }
.ts-filter-surface .ts-toolbar-filter-2 { flex-basis: 225px; width: 225px; min-width: 225px; }
.ts-filter-surface .ts-toolbar-filter-3 { flex-basis: 220px; width: 220px; }
.ts-filter-surface .ts-toolbar-filter > span:not([class*="fa-"]) {
	display: block;
	width: 100%;
	min-width: 0;
}
.ts-filter-surface .ts-toolbar-filter .select2-container,
.ts-filter-surface .ts-toolbar-filter .select2-selection {
	box-sizing: border-box;
	width: 100% !important;
	min-width: 0 !important;
	max-width: 100% !important;
}
.ts-filter-surface .ts-toolbar-filter .select2-search--inline,
.ts-filter-surface .ts-toolbar-filter .select2-search__field {
	box-sizing: border-box;
	max-width: 100%;
	white-space: nowrap;
	text-overflow: clip;
}
.ts-filter-surface .divsearchfield > span[class*="fa-"] { display: none; }
.ts-filter-surface .select2-container { width: 100% !important; min-width: 0 !important; }
.ts-filter-surface .select2-selection { min-height: 38px; }
/* Select2's multiple-value control contains a real search input. The global
   input component styled that nested editor as a second bordered control inside
   the already-bordered Select2 surface. Keep one frame: the selection owns it. */
.ts-filter-surface .select2-selection--multiple {
	height: 40px;
	min-height: 40px;
	padding: 2px 28px 2px var(--sp-2) !important;
	overflow: hidden;
}
.ts-filter-surface .select2-selection--multiple .select2-search__field {
	height: 34px;
	margin: 0;
	padding: 0 !important;
	border: 0 !important;
	border-radius: 0 !important;
	background: transparent !important;
	box-shadow: none !important;
}

/* Dolibarr uses fa-list for the selected-columns dropdown. Its glyph includes
   three bullet stems that read as stray dividers beside the select-all box.
   The trigger and dropdown stay intact; only its painted glyph is simplified. */
.ts-list-card tr.liste_titre > :first-child .dropdown .fa-list::before {
	content: "\f1de";
}

/* This is one utility column in Dolibarr's table, not two table columns. Give
   it two fixed internal slots so the chooser cannot alter the table algorithm:
   trigger on the left, select checkbox (and every row checkbox) on the right. */
.ts-list-card table tr.liste_titre > :first-child,
.ts-list-card table tr.oddeven > :first-child,
.ts-list-card table tr.impair > :first-child,
.ts-list-card table tr.pair > :first-child {
	box-sizing: border-box;
	width: 96px;
	min-width: 96px;
	max-width: 96px;
}
/* A sticky layer on every th leaves a compositor seam between otherwise
   identical backgrounds. Keep one sticky painted surface on the row; only the
   utility cell needs positioning, as the containing block for its controls. */
.ts-list-card div.div-table-responsive table.liste tr.liste_titre {
	position: sticky;
	top: 0;
	z-index: 3;
	background: var(--colorbacktitle1);
}
.ts-list-card div.div-table-responsive table.liste tr.liste_titre > th {
	position: static;
	top: auto;
	z-index: auto;
	background: transparent;
}
.ts-list-card div.div-table-responsive table.liste tr.liste_titre > :first-child {
	position: relative;
	padding-left: 0;
	padding-right: 0;
}
.ts-list-card table tr.oddeven > :first-child,
.ts-list-card table tr.impair > :first-child,
.ts-list-card table tr.pair > :first-child {
	padding-right: 15px;
	text-align: right;
}
.ts-list-card table tr.oddeven > :first-child > input.checkforselect,
.ts-list-card table tr.impair > :first-child > input.checkforselect,
.ts-list-card table tr.pair > :first-child > input.checkforselect {
	float: right;
	margin: 0;
}
.ts-list-card tr.liste_titre > :first-child dl.dropdown {
	position: absolute;
	top: 50%;
	left: 12px;
	width: 34px;
	height: 34px;
	margin: 0;
	transform: translateY(-50%);
}
.ts-list-card tr.liste_titre > :first-child div.checkallactions {
	position: absolute;
	top: 50%;
	right: 15px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 18px;
	height: 18px;
	transform: translateY(-50%);
}
.ts-list-card tr.liste_titre > :first-child div.checkallactions input[type="checkbox"] { margin: 0; }
.ts-list-card tr.liste_titre > :first-child dl.dropdown dt a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 34px;
	height: 34px;
	padding: 0;
	border: 0;
	border-radius: 8px;
	background: transparent;
	color: var(--c-muted);
	overflow: visible;
	transition: background var(--t), color var(--t), box-shadow var(--t);
}
.ts-list-card tr.liste_titre > :first-child dl.dropdown dt a:hover {
	background: var(--c-accent-soft);
	color: var(--c-accent-ink);
}
.ts-list-card tr.liste_titre > :first-child dl.dropdown dt a:focus { outline: none; }
.ts-list-card tr.liste_titre > :first-child dl.dropdown dt a:focus-visible {
	background: var(--c-accent-soft);
	color: var(--c-accent-ink);
	box-shadow: 0 0 0 2px var(--c-accent-ring);
}
.ts-list-card tr.liste_titre > :first-child dl.dropdown dt a .fa-list {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 16px;
	height: 16px;
	font-size: 15px;
	line-height: 1;
}
.ts-list-card tr.liste_titre > :first-child dl.dropdown dd { position: static; }

/* Keep Dolibarr's selected-column chooser and its event handlers, but present
   the existing list as a COMMAND popover.  The stock rules leave this control
   at the inherited table font size and add label padding on top of the flex
   gap, which makes the rows look cramped and uneven. */
.ts-list-card tr.liste_titre > :first-child dl.dropdown dd ul.selectedfieldsleft {
	top: calc(100% + 7px);
	left: 0;
	right: auto;
	min-width: 280px;
	width: max-content;
	max-width: 380px;
	min-width: 280px;
	max-width: calc(100vw - 32px);
	max-height: min(380px, calc(100vh - 32px));
	padding: 12px;
	border: 1px solid var(--c-border);
	border-radius: 12px;
	background: var(--c-surface);
	box-shadow: 0 14px 36px rgba(11, 18, 32, 0.14), 0 3px 10px rgba(11, 18, 32, 0.06);
	font-size: 0.8125rem;
	line-height: 1.35;
	scrollbar-width: thin;
	scrollbar-color: #cbd2dc transparent;
}
.ts-list-card tr.liste_titre > :first-child dl.dropdown dd ul.selectedfieldsleft::-webkit-scrollbar { width: 6px; }
.ts-list-card tr.liste_titre > :first-child dl.dropdown dd ul.selectedfieldsleft::-webkit-scrollbar-track { background: transparent; }
.ts-list-card tr.liste_titre > :first-child dl.dropdown dd ul.selectedfieldsleft::-webkit-scrollbar-thumb {
	border-radius: 999px;
	background: #cbd2dc;
}
.ts-list-card tr.liste_titre > :first-child dl.dropdown dd ul.selectedfieldsleft li {
	min-height: 38px;
	padding: 0 8px;
	gap: 10px;
	border: 0;
	border-radius: 8px;
	font-size: 0.8125rem;
	line-height: 1.35;
}
.ts-list-card tr.liste_titre > :first-child dl.dropdown dd ul.selectedfieldsleft li:hover:not(.liinputsearch) {
	background: var(--c-accent-soft);
}
.ts-list-card tr.liste_titre > :first-child dl.dropdown dd ul.selectedfieldsleft li.liinputsearch {
	min-height: 0;
	padding: 0 0 10px;
	background: var(--c-surface);
}
.ts-list-card tr.liste_titre > :first-child dl.dropdown dd ul.selectedfieldsleft input.inputsearch_dropdownselectedfields {
	width: 100% !important;
	min-width: 0 !important;
	height: 38px;
	padding: 0 11px !important;
	border: 1px solid var(--c-border) !important;
	border-radius: 8px !important;
	background: var(--c-surface) !important;
	box-shadow: none !important;
	font-size: 0.8125rem !important;
}
.ts-list-card tr.liste_titre > :first-child dl.dropdown dd ul.selectedfieldsleft input.inputsearch_dropdownselectedfields:focus {
	border-color: var(--c-border-strong) !important;
	box-shadow: none !important;
}
.ts-list-card tr.liste_titre > :first-child dl.dropdown dd ul.selectedfieldsleft input.inputsearch_dropdownselectedfields:focus-visible {
	border-color: var(--c-accent) !important;
	box-shadow: 0 0 0 2px var(--c-accent-ring) !important;
}
.ts-list-card tr.liste_titre > :first-child dl.dropdown dd ul.selectedfieldsleft li > input[type="checkbox"] {
	flex: 0 0 16px;
	width: 16px;
	height: 16px;
	margin: 0;
}
.ts-list-card tr.liste_titre > :first-child dl.dropdown dd ul.selectedfieldsleft li > label {
	flex: 1 1 auto;
	padding: 0;
	font-size: inherit;
	line-height: inherit;
	text-align: left;
	cursor: pointer;
}
@media only screen and (max-width: 900px) {
	.ts-list-card tr.liste_titre > :first-child dl.dropdown dd ul.selectedfieldsleft {
		max-height: min(340px, calc(100vh - 32px));
	}
}

/* Anchored to the toolbar rather than to the Filters button. Positioned against
   the button the panel opened leftwards from wherever that button happened to
   sit, and on a wide toolbar it started left of the content area and was clipped
   under the sidebar. The toolbar's own left edge is a stable anchor, so the
   panel stays inside the content whatever the button's position. */
/* The content column scrolls (overflow-y:auto) and is only as tall as whatever
   it holds, so on a page with no rows a dropdown opening near the bottom of the
   filter panel was clipped by the column's own edge -- the same dropdown was
   fine as soon as the list had data to make the column taller. Floor the column
   at the viewport height so a short page still has somewhere to open into. */
#id-right { min-height: calc(100vh - 108px); }

/* Submit buttons sat in flex toolbars with the default flex-shrink, so a narrow
   toolbar squeezed them below their own label -- the projects filter bar cut
   "Refresh" down to "Refre" against an overflow:clip. A button is not the give
   in a layout; let the fields around it take the pressure instead. */
input[type="submit"],
input[type="button"],
button[type="submit"] {
	flex-shrink: 0;
	min-width: max-content;
}

/* A date range is two fields, and stacking them made its control twice the
   height of every other filter, which set the row height for the whole grid.
   Put the pair on one row under a full-width label so a range costs the same
   height as a single field.

   The field does not shrink on its own: the input sits inside a wrapper that
   holds its own width, and the input carries a matching min-width, so
   constraining either alone left the pair overflowing its box. Release both. */
.ts-column-filter-control:has(> .nowrapfordate ~ .nowrapfordate) {
	grid-column: span 2;
	grid-template-columns: max-content max-content;
	column-gap: var(--sp-3);
	align-items: center;
	justify-content: start;
}
.ts-column-filter-control:has(> .nowrapfordate ~ .nowrapfordate) > .ts-column-filter-label {
	grid-column: 1 / -1;
}
.ts-column-filter-control > .nowrapfordate,
.ts-column-filter-control > .nowrapfordate > .nowraponall {
	display: flex;
	align-items: center;
	gap: var(--sp-1);
	min-width: 0;
	max-width: 100%;
}
.ts-column-filter-control > .nowrapfordate .nowraponall > *:not(input) {
	flex: none;
}

/* A widget with no data still reserved a 200px placeholder box and then wrote
   "Not enough data..." underneath it, so the card was mostly empty space with a
   caption on the floor. There is nothing to plot, so drop the box and let the
   message stand on its own. */
body.ts-command-module-index .nographyet {
	display: none;
}

/* Dashboard toolbar controls. The picker is a select2 like every other dropdown
   in the theme, but it sits straight inside the form rather than in a record
   table, so none of the field styling reached it and it kept the native look
   next to its unstyled Refresh button. */
body.ts-command-module-index form > .select2-container .select2-selection--single,
body.ts-command-module-index .fichecenter .select2-container .select2-selection--single {
	height: 38px;
	border: 1px solid var(--c-border);
	border-radius: var(--r-sm);
	background: var(--c-surface);
}
body.ts-command-module-index form > .select2-container .select2-selection__rendered,
body.ts-command-module-index .fichecenter .select2-container .select2-selection__rendered {
	line-height: 36px;
	color: var(--c-text);
}
body.ts-command-module-index form > .select2-container .select2-selection__arrow,
body.ts-command-module-index .fichecenter .select2-container .select2-selection__arrow {
	height: 36px;
}
body.ts-command-module-index input[type="submit"],
body.ts-command-module-index input[type="button"] {
	height: 38px;
	padding: 0 var(--sp-4);
	border: 1px solid var(--c-border);
	border-radius: var(--r-sm);
	background: var(--c-surface);
	color: var(--c-text);
	font-size: 0.8125rem;
	font-weight: 600;
	line-height: 1;
	vertical-align: middle;
	cursor: pointer;
}
body.ts-command-module-index input[type="submit"]:hover,
body.ts-command-module-index input[type="button"]:hover {
	border-color: var(--c-primary);
	color: var(--c-primary);
}

/* Statistics filter forms, corrected in place rather than restyled. An earlier
   pass rebuilt the table and made things worse -- the label column came out
   narrower and wrapped more than before -- so this touches only the three things
   that are actually wrong: labels wrapping mid-phrase, the picto sitting on its
   own line above the field it belongs to, and the field stretching the row. */
body.ts-command-stats form td {
	vertical-align: middle;
}
body.ts-command-stats form td:first-child {
	white-space: nowrap;
	padding-right: var(--sp-4);
}
/* The gutter has to be reserved, not merely offered. A statistics page is also a
   secondary record tab, and that tab's own cell padding is set from a longer
   selector, so the gutter collapsed to 12px and the icon -- which sits at the
   gutter's left edge -- ended up underneath the field. Match that selector's
   reach so the gutter holds. */
body.ts-command-stats form.ts-record-tab-native-surface td + td,
body.ts-command-stats form td + td {
	padding-left: 40px !important;
}
/* Give the icon a gutter of its own so the fields line up in one column whether
   a row has an icon or not. Previously a row without one started its field where
   the icon would have been, and the form read as two ragged columns.

   Only a leading icon moves into the gutter: some rows carry a trailing hint
   icon after the field, and that one belongs where it is. */
body.ts-command-stats form td + td {
	position: relative;
	padding-left: 40px;
}
/* The markup puts a hard space after a leading icon, and that space stays in
   flow once the icon is lifted into the gutter, so an icon row still sat eight
   pixels right of a plain one. Pad the plain rows by the same amount. */
body.ts-command-stats form td + td:not(:has(> span.fas:first-child)):not(:has(> span.far:first-child)):not(:has(> img.pictofixedwidth:first-child)) {
	padding-left: 48px;
}
body.ts-command-stats form td + td > span.fas:first-child,
body.ts-command-stats form td + td > span.far:first-child,
body.ts-command-stats form td + td > img.pictofixedwidth:first-child {
	position: absolute;
	left: var(--sp-3);
	top: 50%;
	transform: translateY(-50%);
	margin: 0;
}
body.ts-command-stats form td > span.fas,
body.ts-command-stats form td > span.far,
body.ts-command-stats form td > img.pictofixedwidth {
	vertical-align: middle;
	margin-right: var(--sp-2);
}
body.ts-command-stats form td .select2-container {
	width: auto !important;
	min-width: 220px !important;
	max-width: 100%;
	vertical-align: middle;
}
/* Every dropdown here draws its arrow hard against its own right border. On the
   wide ones that only looks tight; on a short one such as the year it collides
   with the value. Hold the arrow off the edge and keep the text clear of it. */
body.ts-command-stats form .select2-container .select2-selection__arrow {
	right: 6px !important;
}
body.ts-command-stats form .select2-container .select2-selection__rendered {
	padding-right: 26px;
}
/* The bordered box does not inherit the width the container was given, so
   widening the container alone left the year field small with its chevron
   stranded outside the border. */
body.ts-command-stats form td .select2-container .select2-selection--single,
body.ts-command-stats form td .select2-container .select2-selection--multiple {
	width: 100% !important;
	box-sizing: border-box;
}
/* Tag pickers are multi-selects, which carry different markup from the single
   selects beside them, so they kept the pre-theme box while everything else on
   the form had been brought into line. */
/* select2 puts its own search field inside the multi-select, so it must not pick
   up the bordered field treatment or the control renders as a box in a box. */
body.ts-command-stats form td .select2-search__field {
	border: 0 !important;
	background: transparent !important;
	height: 30px !important;
	padding: 0 !important;
	min-width: 60px;
}
body.ts-command-stats form td .select2-container .select2-selection--multiple {
	min-height: 38px;
	padding: 2px var(--sp-2);
	border: 1px solid var(--c-border);
	border-radius: var(--r-sm);
	background: var(--c-surface);
}
body.ts-command-stats form td input.flat:not(.select2-search__field):not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]) {
	height: 38px;
	padding: 0 var(--sp-3);
	border: 1px solid var(--c-border);
	border-radius: var(--r-sm);
	background: var(--c-surface);
	box-sizing: border-box;
	vertical-align: middle;
}

/* Avatars inside a dropdown. Dolibarr serves the full-size user photo and the
   option row stretched to it, so picking an author opened a list of portraits.
   The photo is an identifier here, not the content: size it to the line. */
.select2-dropdown img,
.select2-results__option img,
.select2-container .select2-selection__rendered img,
.select2-container .select2-selection__choice img {
	width: 20px !important;
	height: 20px !important;
	max-width: 20px !important;
	max-height: 20px !important;
	border-radius: 50%;
	object-fit: cover;
	vertical-align: middle;
	margin-right: 6px;
}
.select2-results__option {
	display: flex;
	align-items: center;
	gap: 2px;
}

/* Date fields in a filter row. The wrapper was 118px while holding a 112px
   input and a 34px picker, so the picker overflowed its own wrapper and came to
   rest between the two fields, reading as though it belonged to neither. Let the
   wrapper take the width its contents need, and trim the input to make room.
   The inputs also ran shorter than the picker beside them and the search box
   further along the bar, which is what made the row look ragged. */
.ts-column-filter-control .nowrapfordate,
.ts-column-filter-control .nowraponall {
	width: auto !important;
	max-width: none !important;
	flex: 0 0 auto;
}
.ts-column-filter-control .nowrapfordate input.maxwidthdate {
	width: 92px !important;
	min-width: 0 !important;
	max-width: none !important;
}
.ts-column-filter-control .nowrapfordate input:not([type="hidden"]),
.ts-column-filter-control > input.flat:not([type="checkbox"]):not([type="radio"]) {
	height: 34px;
	box-sizing: border-box;
	vertical-align: middle;
}
.ts-column-filter-control .nowrapfordate img.ui-datepicker-trigger {
	width: 30px;
	height: 30px;
	flex: none;
}

/* select2 puts its own search field inside a multi-select. Given the bordered
   field treatment the theme applies to inputs, that inner field draws a second
   box inside the control -- most visible once the control is focused and the
   search field appears. The control already has a border; the field inside it
   should not. Applies wherever a multi-select is used, not just on the pages
   where it was first noticed. */
.select2-container .select2-search--inline .select2-search__field,
.select2-container .select2-selection--multiple .select2-search__field,
.select2-container .select2-search__field,
td .select2-container .select2-search__field {
	height: auto !important;
	min-height: 26px;
	margin: 0 !important;
	padding: 0 2px !important;
	border: 0 !important;
	border-radius: 0 !important;
	background: transparent !important;
	box-shadow: none !important;
	outline: none !important;
}
.select2-container .select2-selection--multiple {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 4px;
	padding: 3px 6px;
}
.select2-container .select2-selection--multiple ul.select2-selection__rendered {
	display: contents;
	margin: 0;
	padding: 0;
	list-style: none;
}

/* The results table below these forms is composed into a card, but the filter
   block above it kept the bare legacy table with a grey bar on top, so the two
   halves of the same page did not look related. Give the filter the same card:
   a bordered surface with its heading as the header row. Chrome only -- the
   field alignment inside is left alone. */
body.ts-command-stats form table.border,
body.ts-command-stats form table.noborder,
body.ts-command-stats form > table {
	width: 100%;
	border: 1px solid var(--c-border);
	border-radius: var(--r-lg);
	background: var(--c-surface);
	border-collapse: separate;
	border-spacing: 0;
	overflow: hidden;
	box-shadow: var(--sh-sm);
}
body.ts-command-stats form tr.liste_titre > td,
body.ts-command-stats form tr.liste_titre > th {
	padding: var(--sp-3) var(--sp-4);
	border: 0;
	border-bottom: 1px solid var(--c-border);
	background: #f6f8fb;
	color: var(--c-text);
	font-size: 0.75rem;
	font-weight: 650;
	letter-spacing: 0.03em;
	text-transform: uppercase;
}
body.ts-command-stats form tr:not(.liste_titre) > td {
	background: var(--c-surface);
}

/* Refresh submits the form, so it carries the action colour the theme uses for
   every other primary button rather than the neutral chrome it inherited. */
body.ts-command-stats form input[type="submit"] {
	height: 38px;
	padding: 0 var(--sp-5);
	border: 1px solid var(--c-btn-action);
	border-radius: var(--r-sm);
	background: var(--c-btn-action);
	color: var(--c-btn-action-text);
	font-size: 0.8125rem;
	font-weight: 600;
	cursor: pointer;
}
body.ts-command-stats form input[type="submit"]:hover {
	filter: brightness(1.07);
}

/* A statistics table with nothing to report rendered as a row of headings over
   empty space, which reads as though it were still loading. */
body.ts-command-stats .ts-stats-empty-row > td {
	padding: var(--sp-6) var(--sp-4) !important;
	border: 0 !important;
	background: var(--c-surface) !important;
	text-align: center;
	color: var(--c-muted);
	font-size: 0.8125rem;
}
body.ts-command-stats .ts-stats-empty-inner {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: var(--sp-2);
}
body.ts-command-stats .ts-stats-empty-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 42px;
	height: 42px;
	background: none;
	color: var(--c-primary);
	font-size: 18px;
}

/* Controls promoted out of the toolbar arrive carrying the toolbar's own layout
   class, which seats a label beside its field. In the panel every control stacks
   its label above a full-width field, so a promoted one squeezed its field into
   whatever the heading left over -- a few characters wide, and its dropdown
   rendered one letter per line. Put them in the panel's layout, and keep a long
   heading to two lines so it cannot crowd the field again. */
.ts-column-filters-panel > .ts-column-filter-control {
	display: grid !important;
	grid-template-columns: minmax(0, 1fr) !important;
	gap: var(--sp-1);
	align-items: start;
	min-width: 0;
}
/* Dolibarr marks several relational selectors minwidth500. That describes the
   old table layout, not a COMMAND filter-panel slot: honoring it here makes one
   filter spill across two columns and breaks the panel rhythm. The shared
   control/popup sizing below already matches a bounded visible trigger. */
.ts-column-filters-panel > .ts-column-filter-control:has(.select2-container.minwidth500),
.ts-column-filters-panel > .ts-column-filter-control:has(select.minwidth500) {
	grid-column: auto;
	width: auto !important;
}
/* A date range still wants its two fields side by side; the single column above
   is for the promoted controls, not for these. */
.ts-column-filters-panel > .ts-column-filter-control:has(> .nowrap ~ .nowrap) {
	grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
	column-gap: var(--sp-3);
	justify-content: start;
	align-items: center;
}
.ts-column-filters-panel > .ts-column-filter-control:has(> .nowrap ~ .nowrap) > .ts-column-filter-label {
	grid-column: 1 / -1;
}
.ts-column-filters-panel > .ts-column-filter-control:has(> .nowrap ~ .nowrap) > .nowrap {
	display: flex;
	align-items: center;
	min-width: 0;
	gap: var(--sp-1);
}
.ts-column-filters-panel > .ts-column-filter-control:has(> .nowrap ~ .nowrap) > .nowrap .divfordateinput {
	display: flex !important;
	align-items: center;
	width: 100%;
	min-width: 0;
}
.ts-column-filters-panel > .ts-column-filter-control:has(> .nowrap ~ .nowrap) > .nowrap input.hasDatepicker {
	width: 100% !important;
	min-width: 0;
}
/* One line per heading. A heading that wrapped pushed its own control down a
   row, so controls on the same line no longer started at the same height and the
   panel read as though it were misaligned. The full wording stays available on
   hover. */
.ts-column-filters-panel > .ts-column-filter-control > .ts-column-filter-label {
	display: block;
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
	line-height: 1.3;
}
.ts-column-filters-panel > .ts-column-filter-control > .select2-container,
.ts-column-filters-panel > .ts-column-filter-control > select,
.ts-column-filters-panel > .ts-column-filter-control > input:not([type="hidden"]):not([type="checkbox"]):not([type="radio"]) {
	width: 100% !important;
	min-width: 0 !important;
	max-width: none !important;
	box-sizing: border-box;
}
/* Some legacy multi-selects (notably role/contact filters) wrap Select2 in an
   extra span and carry minwidth500 on the generated selection. The outer
   container was bounded but the inner selection still expanded to 500px,
   visually escaping its grid slot. Keep every level of an in-panel Select2
   bound to the same filter-control width. */
.ts-column-filters-panel > .ts-column-filter-control :is(.multiselectarraysearch, .multiselectarraysearch_roles, .select2-container, .select2-selection) {
	box-sizing: border-box;
	width: 100% !important;
	min-width: 0 !important;
	max-width: 100% !important;
}

/* While the column picker is open its panel must be allowed out of the boxes
   that hold the list, which otherwise cut it off on a short or empty list. The
   marker is removed as soon as the picker closes, so scrolling a wide list is
   unaffected the rest of the time. */
.ts-list-card.ts-picker-open,
.div-table-responsive.ts-picker-open,
.div-table-responsive-no-min.ts-picker-open {
	overflow: visible !important;
}

/* Module logos are shown at whatever size the file happens to be, and a handful
   ship large -- a 300px and two 256px images sat among icons drawn at 18px, so
   those rows towered over the rest of the list. Cap them and let the image keep
   its proportions inside that box. A ceiling, not a size, so the many logos that
   are already small are left alone. */
img.pictomodule {
	max-width: 24px;
	max-height: 24px;
	object-fit: contain;
	vertical-align: middle;
}

/* Held only while a widget table is measured. Every cap inside it is lifted so
   each column reports the width its content actually needs -- including the
   nested table a reference sits in, which is otherwise capped at the width of
   the cell being measured. Removed again in the same pass. */
body.ts-command-module-index .ts-module-index-card.ts-measuring table,
body.ts-command-module-index .ts-module-index-card.ts-measuring td,
body.ts-command-module-index .ts-module-index-card.ts-measuring a,
body.ts-command-module-index .ts-module-index-card.ts-measuring span {
	max-width: none !important;
	min-width: 0 !important;
	overflow: visible !important;
	text-overflow: clip !important;
}

/* A reference link in a widget carries an icon, which is enough for the
   icon-button treatment elsewhere in the theme to claim it: it was laid out as a
   flex box with a floor of one icon width and its own overflow hidden, so the
   reference beside the icon was cut off whatever width the column had. These
   links are text with an icon in front, not buttons. */
body.ts-command-module-index .ts-module-index-card td a,
body.ts-command-module-index .ts-module-index-card td a.classforajaxtooltip {
	display: inline !important;
	min-width: 0 !important;
	max-width: none !important;
	overflow: visible !important;
	white-space: nowrap;
}
body.ts-command-module-index .ts-module-index-card td a > .fas,
body.ts-command-module-index .ts-module-index-card td a > .far,
body.ts-command-module-index .ts-module-index-card td a > img {
	display: inline-block !important;
	vertical-align: middle;
	margin-right: 4px;
	min-width: 0 !important;
}

/* A user photo standing in a column heading is an identifier, not the content:
   the everybody placeholder came through at its own 64px and towered over the
   headings around it. Size it to the line, as the same photo already is in a
   dropdown. */
table tr.liste_titre img.photouserphoto,
table tr.liste_titre img.userphoto {
	width: 24px !important;
	height: 24px !important;
	max-width: 24px;
	max-height: 24px;
	border-radius: 50%;
	object-fit: cover;
	vertical-align: middle;
}

/* Title-bar buttons.

   The icon inside carries margins of its own, which pushed it off centre in a
   button that holds nothing else -- about four pixels right, enough to read as
   crooked when three sit in a row. Earlier attempts to single out the icon-only
   buttons failed because a labelled one keeps its label as a bare text node,
   which :has() cannot see, so the guard caught those too and squashed them.

   No detection is needed: clear the icon's own margins and let flex spacing
   separate it from a label when there is one. An anonymous text node is still a
   flex item, so the gap applies to a labelled button exactly as it does between
   two elements, and an icon on its own ends up centred because nothing offsets
   it any more. */
a.btnTitle {
	gap: 6px;
}
a.btnTitle > .btnTitle-icon,
a.btnTitle > [class*="fa-"] {
	margin: 0 !important;
}
/* and one button is not the next */
a.btnTitle + a.btnTitle {
	margin-left: 6px;
}

/* A field table that sits straight in a section, with no half-column around it.

   On a record card these tables are inside .fichehalfleft or .fichehalfright,
   which carry the section surface, so they read as cards. The selling price tab
   puts its table directly in the section instead, and it was left standing on
   the page background: rows of tax rate, price and label with no surface under
   them, beside a price-history table that does have one. Give it the same
   surface the halves have. */
body.ts-command-record-page .fichecenter > table.tableforfield {
	width: 100%;
	margin: 0 0 var(--sp-4);
	border: 1px solid var(--c-hairline) !important;
	border-radius: var(--r-lg);
	background: var(--c-surface);
	box-shadow: var(--sh-sm);
	border-collapse: separate !important;
	border-spacing: 0;
	overflow: hidden;
	box-sizing: border-box;
}
body.ts-command-record-page .fichecenter > table.tableforfield > tbody > tr > td {
	padding: 11px var(--sp-4) !important;
	border: 0 !important;
	background: transparent !important;
	font-size: 0.8125rem;
	line-height: 1.35;
}
body.ts-command-record-page .fichecenter > table.tableforfield > tbody > tr + tr > td {
	border-top: 1px solid var(--c-hairline) !important;
}
body.ts-command-record-page .fichecenter > table.tableforfield > tbody > tr > td:first-child {
	width: 260px;
	color: var(--c-ink-2, var(--c-muted));
	font-weight: 600;
}

/* Record page section rows.

   The two halves are floated inside a block, so the next row cannot begin until
   the taller column clears: on a product card the second row touched the card
   above it, and the shorter right column left a gap of its own beneath it.

   Laying the halves out as a row of two gives the columns a common height and
   the rows a gutter. Only the halves are touched -- an earlier attempt also gave
   their children a full height, which made the field tables inside claim the
   whole column and spill their content over the row below. */
body.ts-command-record-page .fichecenter:has(> .fichehalfleft),
body.ts-command-record-page .fichecenter:has(> .fichehalfright) {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 16px;
	align-items: stretch;
}
body.ts-command-record-page .fichecenter > .fichehalfleft,
body.ts-command-record-page .fichecenter > .fichehalfright {
	float: none !important;
	width: auto !important;
	min-width: 0;
	margin: 0 !important;
}
body.ts-command-record-page .fichecenter + .fichecenter,
body.ts-command-record-page .fichecenter + .clearboth + .fichecenter {
	margin-top: 16px;
}
@media (max-width: 900px) {
	body.ts-command-record-page .fichecenter:has(> .fichehalfleft),
	body.ts-command-record-page .fichecenter:has(> .fichehalfright) {
		grid-template-columns: minmax(0, 1fr);
	}
}

/* The submit row of a statistics filter sits after the table rather than inside
   it, so it landed on the card's bottom edge with the border running through the
   button. Give it room of its own. */
body.ts-command-stats form > div.center,
body.ts-command-stats form div.center:has(> input[type="submit"]) {
	margin-top: var(--sp-4);
}

/* A statistics table heads each block with a title and, in a cell of its own, the
   control that recalculates it. That cell is already right aligned, but the title
   beside it is only as wide as its text, so the control came to rest in the
   middle of the card. Let the title take the width and the control keeps to the
   edge. */
body.ts-command-stats table.noborder > tbody > tr.liste_titre > td:first-child:not(:last-child),
body.ts-command-stats table.liste > tbody > tr.liste_titre > td:first-child:not(:last-child) {
	width: calc(100% - 52px) !important;
}
body.ts-command-stats table.noborder > tbody > tr.liste_titre > td:last-child:not(:first-child),
body.ts-command-stats table.liste > tbody > tr.liste_titre > td:last-child:not(:first-child) {
	width: 52px !important;
	padding-left: 0 !important;
	white-space: nowrap;
	text-align: right;
}

.ts-column-filters { position: relative; flex: 0 0 auto; }
.ts-filter-surface { position: relative; }
.ts-column-filters > summary {
	display: inline-flex;
	align-items: center;
	gap: var(--sp-2);
	height: 38px;
	padding: 0 var(--sp-3);
	border: 1px solid var(--c-border);
	border-radius: var(--r);
	background: var(--c-surface);
	color: var(--c-ink-2);
	font-size: 0.8125rem;
	font-weight: 550;
	cursor: pointer;
	list-style: none;
}
.ts-column-filters > summary::-webkit-details-marker { display: none; }
.ts-column-filters[open] > summary,
.ts-column-filters > summary:hover { border-color: var(--c-accent); color: var(--c-accent-ink); }
.ts-column-filters-panel {
	position: absolute;
	z-index: 120;
	top: calc(100% + var(--sp-2));
	/* Anchored to the Filters control so the panel opens beneath the button that
	   summons it. It was anchored to the toolbar instead because a fixed-width
	   panel opening leftwards from a button could start left of the content and
	   be clipped by the sidebar; the width below is capped against the space
	   actually available, so it can shrink rather than overflow. */
	left: auto;
	right: 0;
	display: grid;
	grid-template-columns: repeat(3, minmax(150px, 1fr));
	gap: var(--sp-3);
	width: min(720px, calc(100vw - var(--nav-w) - var(--sp-7)));
	padding: var(--sp-4);
	border: 1px solid var(--c-border);
	border-radius: var(--r-lg);
	background: var(--c-surface);
	box-shadow: var(--sh-lg);
	overflow-y: auto;
	overscroll-behavior: contain;
}
.ts-column-filters-actions {
	grid-column: 1 / -1;
	display: flex;
	justify-content: flex-end;
	align-items: center;
	padding-top: var(--sp-3);
	border-top: 1px solid var(--c-hairline);
}
.ts-filter-surface .ts-column-filters-actions .ts-submit-search {
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	gap: var(--sp-2);
	width: auto;
	min-width: 132px;
	height: 40px;
	padding: 0 var(--sp-4);
	border: 1px solid var(--c-btn-action) !important;
	border-radius: var(--r);
	background: var(--c-btn-action) !important;
	color: var(--c-btn-action-text) !important;
	font: inherit;
	font-weight: 600;
	box-shadow: none !important;
}
.ts-filter-surface .ts-column-filters-actions .ts-submit-search:hover {
	filter: brightness(.94);
}

/* Below this width the Filters button sits far enough left that a panel hanging
   from it would start outside the content and be clipped by the sidebar, which
   CSS cannot prevent while the width is fixed and the anchor is the button. Fall
   back to the toolbar edge, where it always fits. */
@media (max-width: 1439px) {
	/* Release the button as the anchor as well, or left:0 measures from the
	   button and the panel runs off the other edge instead. */
	.ts-column-filters {
		position: static;
	}
	.ts-column-filters-panel {
		left: 0;
		right: auto;
	}
}
@media (max-width: 700px) {
	.ts-column-filters-actions {
		position: sticky;
		bottom: 0;
		margin: 0 calc(var(--sp-3) * -1) calc(var(--sp-3) * -1);
		padding: var(--sp-3);
		background: var(--c-surface);
	}
	.ts-filter-surface .ts-column-filters-actions .ts-submit-search { width: 100%; }
}

.ts-column-filter-control { display: grid; gap: var(--sp-1); min-width: 0; }
.ts-column-filter-label {
	font-size: 0.6875rem;
	font-weight: 620;
	letter-spacing: 0.035em;
	text-transform: uppercase;
	color: var(--c-muted);
}
.ts-column-filter-control input,
.ts-column-filter-control select,
.ts-column-filter-control .select2-container { width: 100% !important; max-width: none !important; }
.ts-column-filter-control .select2-selection--single {
	width: 100% !important;
	height: 40px;
	min-height: 40px;
	padding: 0 34px 0 var(--sp-3);
	border: 1px solid var(--c-border) !important;
	border-radius: var(--r) !important;
	background: var(--c-surface);
	box-shadow: none;
}
.ts-column-filter-control .select2-selection--single .select2-selection__rendered {
	padding: 0;
	line-height: 38px;
}
.ts-column-filter-control .select2-selection--single .select2-selection__arrow {
	top: 0;
	right: 2px;
	height: 38px;
}
.ts-column-filter-control .select2-container--default.select2-container--focus .select2-selection--single,
.ts-column-filter-control .select2-container--default.select2-container--open .select2-selection--single {
	border-color: var(--c-accent) !important;
	box-shadow: 0 0 0 1px var(--c-accent-ring);
}
.select2-dropdown.ts-column-filter-dropdown {
	box-sizing: border-box;
	width: var(--ts-column-filter-width) !important;
	min-width: var(--ts-column-filter-width) !important;
	padding: 0 !important;
	border: 1px solid var(--c-border);
	border-radius: var(--r-lg);
	background: var(--c-surface);
	box-shadow: var(--sh-md);
	overflow: hidden;
}
.select2-dropdown.ts-column-filter-dropdown .select2-search--dropdown { padding: var(--sp-2); }
.select2-dropdown.ts-column-filter-dropdown .select2-search__field {
	width: 100% !important;
	height: 38px;
	padding: 0 var(--sp-3) !important;
	border: 1px solid var(--c-border) !important;
	border-radius: var(--r) !important;
	background: var(--c-surface) !important;
	box-shadow: none !important;
}
.select2-dropdown.ts-column-filter-dropdown .select2-search__field:focus {
	border-color: var(--c-accent) !important;
	box-shadow: 0 0 0 1px var(--c-accent-ring) !important;
}
.select2-dropdown.ts-column-filter-dropdown .select2-results__options { padding: var(--sp-1); }
.select2-dropdown.ts-column-filter-dropdown .select2-results__option {
	display: flex;
	align-items: center;
	min-height: 36px;
	padding: 0 var(--sp-3);
	border-radius: var(--r-sm);
	font-size: 0.8125rem;
}
.select2-dropdown.ts-column-filter-dropdown.ts-compact-select2-dropdown .select2-search--dropdown { display: none; }
.select2-dropdown.ts-page-size-dropdown {
	box-sizing: border-box;
	padding: var(--sp-1) !important;
	border: 1px solid var(--c-border);
	border-radius: var(--r);
	background: var(--c-surface);
	box-shadow: var(--sh-md);
	overflow: hidden;
}
.select2-dropdown.ts-page-size-dropdown .select2-search--dropdown { display: none; }
.select2-dropdown.ts-page-size-dropdown .select2-results__options {
	max-height: none !important;
	padding: 0;
	overflow-y: visible !important;
}
.select2-dropdown.ts-page-size-dropdown .select2-results__option {
	display: flex;
	align-items: center;
	min-height: 35px;
	padding: 0 var(--sp-3);
	border-radius: var(--r-sm);
	font-size: 0.875rem;
}
.select2-dropdown.ts-page-size-dropdown .select2-results__option[aria-selected="true"] {
	background: var(--c-accent-soft);
	color: var(--c-accent-ink);
	font-weight: 620;
}

.ts-list-card tr.liste_titre .ts-sort-indicator {
	display: inline-flex;
	align-items: center;
	margin-left: 5px;
	vertical-align: middle;
}
.ts-list-card tr.liste_titre .ts-sort-indicator .paddingright { padding-right: 0; }

/* AJAX record previews share .mytooltip. Keep ordinary compact help tooltips
   content-sized while giving record cards an opaque, structured surface. */
.ui-tooltip.mytooltip {
	box-sizing: border-box;
	/* Content decides, within a ceiling: a fixed width clipped longer values
	   and left short ones padded out. */
	/* Content decides. An earlier floor of 300px was meant to stop long values
	   clipping, but it also inflated a two-word tooltip into a slab; max-width
	   alone does the job. */
	width: max-content;
	min-width: 0;
	max-width: 420px;
	max-width: calc(100vw - 24px);
	padding: 16px;
	border: 1px solid var(--c-border);
	border-radius: var(--r-lg);
	background: var(--c-surface) !important;
	box-shadow: var(--sh-lg);
	color: var(--c-ink-2);
	font-size: 0.875rem;
	line-height: 1.6;
	opacity: 1 !important;
	z-index: 3000 !important;
}
.ui-tooltip.mytooltip .ui-tooltip-content {
	position: relative;
	padding: 0;
}
/* Company previews may include a 40px logo floated by Dolibarr. Take it out
   of the legacy float flow and reserve a separate slot so the status pill and
   image keep a small, intentional gap instead of colliding. */
.ui-tooltip.mytooltip .ui-tooltip-content > .photointooltip {
	position: absolute;
	top: 0;
	right: 0;
	float: none !important;
	margin: 0;
}
.ui-tooltip.mytooltip .ui-tooltip-content > .photointooltip img {
	display: block;
	width: 40px;
	height: 40px;
	object-fit: contain;
	border-radius: 6px;
}
.ui-tooltip.mytooltip .ui-tooltip-content:has(> .photointooltip) .ts-tooltip-header {
	padding-right: 136px;
}
.ui-tooltip.mytooltip .ui-tooltip-content:has(> .photointooltip) .ts-tooltip-status {
	right: 64px;
}
.ui-tooltip.mytooltip .centpercent {
	position: relative;
}
.ui-tooltip.mytooltip .centpercent > [class*="fa-"]:first-child {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 34px;
	height: 34px;
	margin-right: var(--sp-2);
	border-radius: var(--r);
	background: var(--c-accent-soft);
	vertical-align: middle;
}
.ui-tooltip.mytooltip u.paddingrightonly {
	display: inline-block;
	margin: 0;
	padding: 0;
	border: 0;
	font-size: 0.875rem;
	font-weight: 650;
	letter-spacing: 0;
	text-transform: none;
	opacity: 1;
	vertical-align: middle;
}
.ui-tooltip.mytooltip .customer-back,
.ui-tooltip.mytooltip .vendor-back,
.ui-tooltip.mytooltip .prospect-back {
	display: inline-flex;
	align-items: center;
	min-height: 22px;
	padding: 0 7px;
	border-radius: var(--r-pill);
	background: var(--c-sunken);
	color: var(--c-muted);
	font-size: 0.75rem;
	font-weight: 600;
}
.ui-tooltip.mytooltip .badge-status {
	/* Absolute positioning pinned every badge to the same corner, so a record
	   carrying two statuses -- a product that is neither for sale nor for
	   purchase -- drew them on top of each other. Let them flow to the right so
	   any number sit side by side. */
	position: static;
	float: right;
	margin: 0 0 0 6px;
}
/* Contain the floated badges so they cannot ride over the line beneath. */
.ui-tooltip.mytooltip .ui-tooltip-content::after {
	content: '';
	display: table;
	clear: both;
}
.ui-tooltip.mytooltip b,
.ui-tooltip.mytooltip strong {
	display: inline-block;
	/* A fixed width here collided with its own value: labels longer than 112px,
	   such as "Amount (excl. tax):", overflowed straight into the number. Treat
	   it as a floor and keep a gap after it. */
	min-width: 0;
	padding-right: 0;
	margin-right: 0;
	color: var(--c-muted);
	font-weight: 550;
	white-space: nowrap;
}
.ui-tooltip.mytooltip .pictofixedwidth,
.ui-tooltip.mytooltip .paddingright > [class*="fa-"]:first-child {
	width: 112px;
	padding: 0;
	text-align: left;
}
.ui-tooltip.mytooltip .centpercent[data-ts-structured="1"] { position: static; }
.ui-tooltip.mytooltip .ts-tooltip-header {
	position: relative;
	display: flex;
	align-items: center;
	gap: var(--sp-2);
	min-width: 0;
	padding-right: 72px;
}
.ui-tooltip.mytooltip .ts-tooltip-header .ts-tooltip-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 34px;
	width: 34px;
	height: 34px;
	border-radius: var(--r);
	background: var(--c-accent-soft);
	color: var(--c-accent-ink);
}
.ui-tooltip.mytooltip .ts-tooltip-kind {
	margin: 0;
	padding: 0;
	border: 0;
	color: var(--c-ink);
	font-size: 0.875rem;
	font-weight: 650;
	text-decoration: none;
}
.ui-tooltip.mytooltip .ts-tooltip-header .ts-tooltip-status {
	position: absolute;
	top: 0;
	right: 0;
	margin: 0;
	flex: none;
}
/* One grid for the whole list rather than a fixed column per row: at 112px a
   longer label such as "Amount (excl. tax):" ran straight into its own value,
   and each row measured independently so nothing lined up. Letting the labels
   share a content-sized column aligns them and gives each the width it needs. */
/* The separator Dolibarr writes between contact details and accounting codes,
   drawn as the rule it stands for rather than left as blank space. */
.ui-tooltip.mytooltip .ts-tooltip-rule {
	display: none;
}
/* Any break that survives into the structured list would add space of its own on
   top of the row spacing. */
.ui-tooltip.mytooltip .ts-tooltip-details br {
	display: none;
}
.ui-tooltip.mytooltip .ts-tooltip-details {
	display: flex;
	flex-direction: column;
	gap: 5px;
	margin-top: 8px;
}
.ui-tooltip.mytooltip .ts-tooltip-row {
	display: grid;
	/* Sized to the label, not to a fixed 118px. The email and phone rows label
	   themselves with just an icon, so a fixed column left ~100px of dead space
	   and stranded their values out to the right while the text-labelled rows
	   sat snug against theirs. */
	grid-template-columns: auto minmax(0, 1fr);
	justify-content: start;
	align-items: start;
	column-gap: var(--sp-3);
}
/* An icon standing in for a label still occupies the label track. */
.ui-tooltip.mytooltip .ts-tooltip-row > [class*="fa-"]:first-child {
	justify-self: start;
}
.ui-tooltip.mytooltip .ts-tooltip-label {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	color: var(--c-muted);
	font-weight: 550;
}
.ui-tooltip.mytooltip .ts-tooltip-label [class*="fa-"] {
	flex: 0 0 14px;
	width: 14px;
	text-align: center;
}
/* Structured contact rows use a small predictable icon slot. Override
   Dolibarr's legacy .pictofixedwidth treatment, which reserves a wide label
   track and leaves email/phone values stranded far to the right. */
.ui-tooltip.mytooltip .ts-tooltip-details .ts-tooltip-label > [class*="fa-"] {
	flex: 0 0 16px !important;
	width: 16px !important;
	padding: 0 !important;
	margin: 0 !important;
}
.ui-tooltip.mytooltip .ts-tooltip-value {
	min-width: 0;
	color: var(--c-ink-2);
	font-weight: 400;
	overflow-wrap: anywhere;
}
.ts-column-filters-source { display: none; }
.ts-list-card {
	min-width: 0;
	background: var(--c-surface);
	border: 1px solid var(--c-hairline);
	border-radius: var(--r-lg);
	box-shadow: var(--sh-sm);
	overflow: hidden;
}
.ts-list-card > .div-table-responsive,
.ts-list-card > .div-table-responsive-no-min {
	margin: 0;
	border: 0;
	border-radius: 0;
	box-shadow: none;
	overflow-x: auto;
}
.ts-list-card tr.liste_titre > th:not(:first-child),
.ts-list-card tr.liste_titre > td:not(:first-child) { text-align: center !important; }
/* The Contacts/Addresses grid deliberately uses centered headings. Match its
   visible data cells to those axes as well; leaving the names and metadata at
   the far-left edge of each column made the table read as visibly skewed. The
   leading bulk-selection slot remains untouched. */
body.page-contact-list .ts-list-card tr.oddeven > td:not(:first-child),
body.page-contact-list .ts-list-card tr.impair > td:not(:first-child),
body.page-contact-list .ts-list-card tr.pair > td:not(:first-child) {
	text-align: center !important;
}
.ts-list-card td a.opacitymedium:is(.customer-back, .vendor-back, .prospect-back) { opacity: 1; }
.ts-results-footer {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--sp-3);
	min-height: 50px;
	padding: var(--sp-2) var(--sp-4);
	border-top: 1px solid var(--c-hairline);
	background: var(--c-surface);
	color: var(--c-muted);
	font-size: 0.8125rem;
}
.ts-results-summary { white-space: nowrap; }
.ts-results-nav {
	display: flex;
	align-items: center;
	margin-left: auto;
}
.ts-results-nav div.pagination {
	display: flex;
	align-items: center;
	gap: 8px;
}
.ts-results-nav div.pagination > ul {
	display: flex; align-items: center; gap: 8px;
	margin: 0; padding: 0; list-style: none;
}
.ts-results-nav li { display: inline-flex; align-items: center; min-height: 38px; }
.ts-results-nav li.paginationcombolimit {
	position: relative;
	min-width: 126px;
	width: auto;
	height: 38px;
	box-sizing: border-box;
	padding: 0;
	border: 1px solid var(--c-border);
	border-radius: var(--r);
	background: var(--c-surface);
}
.ts-results-nav li.paginationcombolimit .select2-container { width: 100% !important; }
.ts-results-nav li.paginationcombolimit .selection {
	display: block;
	width: 100%;
	height: 100%;
}
.ts-results-nav li.paginationcombolimit .select2-selection--single {
	box-sizing: border-box;
	width: 100% !important;
	min-width: 100% !important;
	max-width: none !important;
	height: 36px;
	min-height: 36px;
	padding: 0 30px 0 12px;
	border: 0 !important;
	border-radius: 0 !important;
	background: transparent;
	box-shadow: none !important;
}
.ts-results-nav li.paginationcombolimit .select2-selection__rendered {
	line-height: 36px;
	padding: 0 !important;
	overflow: visible;
	text-overflow: clip;
	font-size: 0.875rem;
	color: var(--c-ink-2);
}
.ts-results-nav li.paginationcombolimit .select2-selection__rendered::after { content: " per page"; }
.ts-results-nav li.paginationcombolimit .select2-selection__arrow { width: 24px; height: 36px; right: 6px; }
.ts-per-page-label { display: none; }
.ts-results-nav input.pageplusone {
	width: 38px !important;
	min-width: 38px !important;
	max-width: 38px !important;
	height: 38px !important;
	min-height: 38px !important;
	max-height: 38px !important;
	box-sizing: border-box;
	padding: 0;
	margin: 0 !important;
	border: 1px solid var(--c-btn-action) !important;
	border-radius: var(--r);
	background: var(--c-btn-action) !important;
	box-shadow: none !important;
	color: var(--c-btn-action-text) !important;
	font-weight: 620;
	text-align: center;
}
.ts-results-nav a,
.ts-results-nav .inactive,
.ts-results-nav .ts-pager-value {
	display: inline-flex; align-items: center; justify-content: center;
	width: 38px !important; min-width: 38px !important; max-width: 38px !important;
	height: 38px !important; min-height: 38px !important; max-height: 38px !important;
	box-sizing: border-box; margin: 0 !important; padding: 0 !important;
	border: 1px solid var(--c-border);
	border-radius: var(--r); color: var(--c-ink-2);
	background: var(--c-surface);
	font-size: 0.875rem;
}
.ts-results-nav li.pagination:not(.paginationcombolimit) {
	width: 38px;
	min-width: 38px;
	max-width: 38px;
	height: 38px;
	min-height: 38px;
}
.ts-results-nav li.ts-pagination-ellipsis {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 18px;
	min-width: 18px;
	height: 38px;
	min-height: 38px;
	color: var(--c-muted);
	font-size: 0.875rem;
	line-height: 1;
}
.ts-results-nav .paginationpageleft a,
.ts-results-nav .paginationpageright a,
.ts-results-nav .ts-pagination-disabled .inactive { font-size: 0; }
.ts-results-nav .paginationpageleft a::before,
.ts-results-nav .paginationpageright a::before,
.ts-results-nav .ts-pagination-disabled .inactive::before {
	display: block;
	font-family: "Font Awesome 5 Free", "Font Awesome 6 Free";
	font-size: 0.875rem;
	font-weight: 900;
	line-height: 1;
}
.ts-results-nav .paginationpageleft a::before,
.ts-results-nav .ts-pagination-previous .inactive::before { content: "\f053"; }
.ts-results-nav .paginationpageright a::before { content: "\f054"; }
.ts-results-nav .ts-pagination-next .inactive::before { content: "\f054"; }
.ts-results-nav .paginationpageleft a > i,
.ts-results-nav .paginationpageright a > i { display: none; }
.ts-results-nav .ts-pagination-disabled .inactive { color: var(--c-faint); cursor: default; }
.ts-results-nav .ts-pager-value { border: 1px solid var(--c-border); background: var(--c-surface); }
.ts-results-nav a:hover { background: var(--c-sunken); color: var(--c-ink); }

/* Sort labels stay part of the flat header plane. The shared hit-area rule
   otherwise paints a white rounded chip on hover. */
.ts-list-card tr.liste_titre th a.reposition:hover,
.ts-list-card tr.liste_titre td a.reposition:hover {
	background: transparent;
	box-shadow: none;
	color: var(--c-accent-ink);
}
@media only screen and (max-width: 640px) {
	.ts-list-composition .ts-filter-surface { padding: var(--sp-3); }
	.ts-filter-surface .ts-quick-search,
	.ts-filter-surface .divsearchfield { flex-basis: 100%; width: 100%; min-width: 0; }
	.ts-filter-surface .ts-clear-all-filters { width: auto; flex: 0 0 auto; margin-left: auto; }
	.ts-column-filters { width: 100%; }
	.ts-column-filters > summary { width: 100%; justify-content: center; }
	.ts-column-filters-panel {
		right: auto; left: 0;
		grid-template-columns: 1fr;
		width: calc(100vw - var(--nav-w) - (var(--sp-4) * 2));
	}
	.ts-results-footer {
		flex-wrap: nowrap;
		padding-left: var(--sp-2);
		padding-right: var(--sp-2);
	}
}

/* ==========================================================================
   COMMAND parity scale and surface rhythm
   Shared structural components keep their semantics; this final layer aligns
   their browser proportions with the COMMAND reference system.
   ========================================================================== */
body { font-size: 0.875rem; }
.fiche { max-width: 1600px; padding: var(--sp-6) var(--sp-6) var(--sp-8); }

.ts-pagehead { margin-bottom: var(--sp-5); }
.ts-pagehead-title div.titre, div.titre { font-size: 1.625rem; line-height: 1.15; }
.ts-count { min-width: 30px; height: 26px; font-size: 0.8125rem; }
.ts-pagehead a.btnTitle.ts-primary-action {
	min-height: 40px;
	padding: 0 18px;
	font-size: 0.875rem;
}

.ts-list-composition { gap: var(--sp-5); }
.ts-list-composition .ts-filter-surface {
	padding: var(--sp-4);
	gap: 10px;
	box-shadow: var(--sh);
}
.ts-filter-surface .ts-quick-search,
.ts-column-filters > summary { height: 40px; }
.ts-filter-surface .select2-selection { min-height: 40px; }
.ts-list-card { border-color: var(--c-border); box-shadow: var(--sh); }
.ts-list-card tr.liste_titre th,
.ts-list-card tr.liste_titre td { height: 48px; padding-top: var(--sp-3); padding-bottom: var(--sp-3); background: #f7f9fc; }
.ts-list-card tr.oddeven td,
.ts-list-card tr.impair td,
.ts-list-card tr.pair td { height: 52px; padding-top: var(--sp-3); padding-bottom: var(--sp-3); border-bottom: 1px solid var(--c-hairline); }
.ts-results-footer { min-height: 52px; padding: 6px var(--sp-4); background: #fbfcfe; }

/* Shared data-table headers: Dolibarr's native header font is frequently
   rendered at a tiny, uneven weight, particularly in wide admin grids. Give
   every standard list/data header the same quiet COMMAND hierarchy without
   affecting form labels, calendar headers, or the control/filter row. */
table.liste tr.liste_titre > th,
table.liste tr.liste_titre > td,
table.tagtable tr.liste_titre > th,
table.tagtable tr.liste_titre > td,
table.noborder tr.liste_titre > th,
table.noborder tr.liste_titre > td {
	/* Keep table headers on the configured COMMAND typeface.  A separate
	   system-ui stack here made admin grids visibly different whenever the
	   theme font was changed in Display > Skin and colors. */
	font-family: var(--c-font) !important;
	font-size: 0.8125rem !important;
	font-weight: 600 !important;
	letter-spacing: 0.005em;
	line-height: 1.25 !important;
	color: var(--c-ink-subtle) !important;
	text-transform: none !important;
}
table.liste tr.liste_titre > th > a,
table.liste tr.liste_titre > td > a,
table.tagtable tr.liste_titre > th > a,
table.tagtable tr.liste_titre > td > a,
table.noborder tr.liste_titre > th > a,
table.noborder tr.liste_titre > td > a {
	font: inherit;
	color: inherit !important;
	text-decoration: none;
}
table.liste tr.liste_titre [class*="fa-"],
table.tagtable tr.liste_titre [class*="fa-"],
table.noborder tr.liste_titre [class*="fa-"] {
	font-family: "Font Awesome 5 Free", "Font Awesome 6 Free" !important;
	font-weight: 900 !important;
	letter-spacing: 0;
}

/* Numeric table values are atomic. Let responsive wrappers scroll when space
   is genuinely exhausted, but never split a currency or percentage midway
   (for example 80.00 becoming “80.” / “00”). Margins tables are shared by
   proposals, orders and invoices and must use their content-driven allocation,
   not inherit a record card's unrelated fixed-column budget. */
table.liste td.right,
table.noborder td.right,
table.tagtable td.right,
table.liste td.center,
table.noborder td.center,
table.tagtable td.center {
	white-space: nowrap;
}
table.margintable {
	table-layout: auto !important;
}
table.margintable tr > :first-child {
	width: auto !important;
	min-width: 130px;
}
table.margintable tr > :not(:first-child) {
	width: 1% !important;
	min-width: max-content;
	white-space: nowrap;
}

/* The record is a canvas containing independent surfaces, not one white sheet. */
div.tabBar.ts-entity-card {
	background: transparent;
	border: 0;
	border-radius: 0;
	box-shadow: none;
}
div.tabBar.ts-entity-card > div.arearef.ts-has-actions {
	margin: 0 0 var(--sp-3);
	padding: 20px var(--sp-5);
	background: var(--c-surface);
	border: 1px solid var(--c-border);
	border-radius: var(--r-lg);
	box-shadow: var(--sh);
}
/* Some Third Party tabs emit .arearefnobottom instead of .arearef and omit an
   action bar entirely. The canonical overview-tab context marks both variants
   as the same entity surface, so the shell cannot fall back to the legacy
   banner merely because a tab has no actions. */
body.ts-thirdparty-record-context div.tabBar.ts-entity-card > .ts-entity-banner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: var(--sp-4);
	min-height: 112px;
	margin: 0 0 var(--sp-3);
	padding: 20px var(--sp-5);
	background: var(--c-surface);
	border: 1px solid var(--c-border);
	border-radius: var(--r-lg);
	box-shadow: var(--sh);
	overflow: visible;
}
body.ts-thirdparty-record-context div.tabBar.ts-entity-card > .ts-entity-banner.arearefnobottom > div:first-child {
	display: contents;
}
body.ts-thirdparty-record-context div.tabBar.ts-entity-card > .ts-entity-banner.arearefnobottom > .underrefbanner {
	display: none;
}
body.ts-thirdparty-record-context .ts-entity-banner > .ts-entity-identity {
	display: grid;
	grid-template-columns: 56px minmax(0, 1fr);
	align-items: center;
	gap: var(--sp-4);
	flex: 1 1 430px;
	min-width: 0;
}
body.ts-thirdparty-record-context .ts-entity-banner .ts-entity-identity > .divphotoref {
	display: flex !important;
	align-items: center;
	justify-content: center;
	width: 56px !important;
	height: 56px !important;
	min-width: 56px;
	margin: 0 !important;
	border-radius: var(--r-lg);
	background: var(--c-accent-soft);
	color: var(--c-accent-ink);
}
body.ts-thirdparty-record-context .ts-entity-banner .ts-entity-identity > .refid {
	display: grid;
	grid-template-columns: auto auto minmax(0, 1fr);
	align-items: center;
	column-gap: var(--sp-2);
	row-gap: 3px;
	width: auto !important;
	max-width: none !important;
	margin: 0 !important;
	padding: 0 !important;
}
body.ts-thirdparty-record-context .ts-entity-banner .ts-entity-identity > .refid > .refidno {
	grid-column: 1 / -1;
}
body.ts-thirdparty-record-context .ts-entity-banner .ts-entity-identity > .refid > .statusref {
	grid-column: 2;
	grid-row: 1;
	display: inline-flex;
	justify-self: start;
	margin: 0;
}
body.ts-thirdparty-record-context .ts-entity-banner .ts-legacy-identity-source,
body.ts-thirdparty-record-context .ts-entity-banner .ts-entity-photo-unused {
	display: none !important;
}
body.ts-thirdparty-record-context .ts-entity-banner .refid {
	min-width: 0;
	font-size: 1.625rem;
	font-weight: 650;
	line-height: 1.25;
}
body.ts-thirdparty-record-context .ts-entity-banner .refidno,
body.ts-thirdparty-record-context .ts-entity-banner .refaddress {
	font-size: .8125rem;
	font-weight: 400;
	line-height: 1.55;
	color: var(--c-muted);
}
body.ts-thirdparty-record-context .ts-entity-banner .refaddress .address,
body.ts-thirdparty-record-context .ts-entity-banner .refaddress .paddingright,
body.ts-thirdparty-record-context .ts-entity-banner .refaddress > a {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	max-width: 100%;
	margin: 2px var(--sp-3) 2px 0;
}
body.ts-thirdparty-record-context .ts-entity-banner .refaddress [class*="fa-"] {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 17px;
	min-width: 17px;
	margin: 0 !important;
	padding: 0 !important;
}
body.ts-thirdparty-record-context .ts-entity-banner .pagination.paginationref {
	position: static;
	float: none;
	margin-left: auto;
	white-space: nowrap;
	opacity: .58;
}
body.ts-thirdparty-record-context .ts-entity-banner .paginationref a.ts-crumb-source {
	display: none !important;
}
body.ts-thirdparty-record-context .ts-entity-banner .statusref {
	margin-left: var(--sp-2);
}
body.ts-thirdparty-record-context div.tabBar.ts-entity-card > div.tabs[data-ts-placed="1"] {
	width: 100%;
	max-width: 100%;
	overflow-x: auto;
	overflow-y: hidden;
	white-space: nowrap;
	scrollbar-width: none;
}
body.ts-thirdparty-record-context div.tabBar.ts-entity-card > div.tabs[data-ts-placed="1"]::-webkit-scrollbar {
	display: none;
}
body.ts-thirdparty-record-context div.tabBar.ts-entity-card > div.tabs[data-ts-placed="1"] > * {
	flex: 0 0 auto;
}
body.ts-thirdparty-record-context .ts-record-tab-surface {
	margin: var(--sp-3) 0 var(--sp-4);
	border: 1px solid var(--c-border) !important;
	border-radius: var(--r-lg);
	background: var(--c-surface);
	box-shadow: var(--sh-sm);
	overflow-x: auto;
}
body.ts-thirdparty-record-context .ts-record-tab-surface > table {
	margin: 0 !important;
	border: 0 !important;
	background: transparent !important;
}
body.ts-thirdparty-record-context .ts-record-tab-surface tr.liste_titre th,
body.ts-thirdparty-record-context .ts-record-tab-surface tr.liste_titre td {
	height: 48px;
	background: #f7f9fc !important;
	border-bottom: 1px solid var(--c-hairline) !important;
}
body.ts-thirdparty-record-context .ts-record-tab-surface tr.oddeven td,
body.ts-thirdparty-record-context .ts-record-tab-surface tr.pair td,
body.ts-thirdparty-record-context .ts-record-tab-surface tr.impair td {
	height: 48px;
	border-bottom: 1px solid var(--c-hairline) !important;
}
body.ts-thirdparty-record-context td.ts-record-tab-empty {
	height: 112px !important;
	padding: 28px !important;
	text-align: center !important;
	vertical-align: middle !important;
	color: var(--c-muted) !important;
	font-size: .875rem;
}
body.ts-thirdparty-record-context td.ts-record-tab-empty::before {
	display: block;
	margin: 0 auto 9px;
	color: var(--c-faint);
	font-family: "Font Awesome 5 Free";
	font-size: 20px;
	font-weight: 900;
	content: "\f1ea";
}
div.tabBar.ts-entity-card > div.tabs[data-ts-placed="1"] {
	margin: 0 0 var(--sp-4);
	padding: 0 var(--sp-3);
	background: var(--c-surface);
	border: 1px solid var(--c-border);
	border-radius: var(--r-lg);
	box-shadow: var(--sh-sm);
}
div.tabBar.ts-entity-card > div.tabs[data-ts-placed="1"] + * { margin-top: 0; }
div.tabBar.ts-entity-card div.tabs a.tab {
	min-height: 48px;
	padding: 0 18px;
	font-size: 0.875rem;
	font-weight: 520;
	border: 0;
	border-radius: 0;
	background: transparent;
}
div.tabBar.ts-entity-card div.tabs .tabactive > a.tab,
div.tabBar.ts-entity-card div.tabs .tabsElemActive > a.tab {
	color: var(--c-accent-ink);
	font-weight: 650;
	background: transparent;
}
div.tabBar.ts-entity-card div.tabs .tabactive::after,
div.tabBar.ts-entity-card div.tabs .tabsElemActive::after {
	left: var(--sp-3);
	right: var(--sp-3);
	height: 2px;
}
div.arearef.ts-has-actions .refid { font-size: 1.625rem; }
div.arearef.ts-has-actions .paginationref { opacity: .58; margin-left: var(--sp-2); }
.ts-header-actions .butAction,
.ts-header-actions .butActionRefused,
.ts-header-actions .ts-more-actions-trigger { min-height: 40px; padding: 0 var(--sp-4); font-size: 0.875rem; }

.ts-thirdparty-groups {
	align-items: start;
	gap: var(--sp-4);
	padding: 0;
}
.ts-field-group { display: block; border-color: var(--c-border); box-shadow: var(--sh); }
.ts-field-group-title { padding: var(--sp-4); font-size: 1rem; border-bottom-color: var(--c-hairline); }
.ts-field-group table.tableforfield td { padding: 11px var(--sp-4); font-size: 0.875rem; }
.ts-field-group table.tableforfield tr + tr { border-top-color: var(--c-hairline); }

.ts-record-section-card { border-color: var(--c-border); box-shadow: var(--sh); padding: var(--sp-5); }
.ts-record-section-card table.table-fiche-title { margin-bottom: var(--sp-4); }
.ts-record-section-card table.table-fiche-title td.col-title,
.ts-record-section-card .titre { font-size: 1rem; }
.ts-record-section-card tr.liste_titre th,
.ts-record-section-card tr.liste_titre td { background: #f7f9fc; }
.ts-record-section-card tr.oddeven td { height: 48px; }
.ts-record-section-card a.btnTitle {
	min-width: 34px;
	min-height: 34px;
	background: var(--c-surface);
	border: 1px solid var(--c-border);
	box-shadow: none;
}
.ts-record-section-card tr:has(> td.col-title) a.btnTitle {
	background: var(--c-surface);
	border-color: var(--c-border);
	color: var(--c-accent-ink);
}
.ts-record-section-card .ts-section-labelled-action {
	width: auto;
	padding: 0 var(--sp-3);
	gap: var(--sp-2);
	font-size: 0.8125rem;
	font-weight: 600;
}
.ts-section-action-label { white-space: nowrap; }

@media only screen and (min-width: 1401px) {
	.ts-thirdparty-groups { align-items: stretch; }
	.ts-field-group { display: flex; flex-direction: column; }
	.ts-field-group table.tableforfield { flex: 1 1 auto; }
}

@media only screen and (max-width: 992px) {
	.fiche { padding: var(--sp-5) var(--sp-4) var(--sp-7); }
}
/* The tab strip scrolls sideways when the tabs do not fit, and the "... (n)" tab
   that holds the rest is its last item -- so the one control that reaches the
   collapsed tabs was the first thing to go off the edge. Pinned to the end of the
   strip it stays put while the tabs scroll under it. */
div.tabs.ts-tabs-has-overflow > .ts-tabs-overflow {
	position: sticky;
	right: 0;
	flex: 0 0 auto;
	margin-left: auto;
	z-index: 3;
	background: transparent;
	box-shadow: none;
}
div.tabs.ts-tabs-has-overflow > .ts-tabs-overflow a.moretab {
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	gap: 6px;
	min-width: 78px;
	height: 40px;
	padding: 0 10px !important;
	border-radius: var(--r);
	white-space: nowrap;
}
div.tabs.ts-tabs-has-overflow > .ts-tabs-overflow .ts-tabs-more-count {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 20px;
	height: 20px;
	padding: 0 6px;
	border-radius: 999px;
	background: var(--c-accent-soft);
	color: var(--c-accent);
	font-size: 11px;
	font-weight: 700;
	line-height: 1;
}
div.tabs.ts-tabs-has-overflow > .ts-tabs-overflow .ts-tabs-more-chevron {
	font-size: 10px;
	transition: transform .15s ease;
}
div.tabs.ts-tabs-has-overflow > .ts-tabs-overflow a.moretab[aria-expanded="true"] .ts-tabs-more-chevron {
	transform: rotate(180deg);
}
@media only screen and (max-width: 640px) {
	div.tabs.ts-tabs-has-overflow > .ts-tabs-overflow a.moretab {
		min-width: 52px;
		padding-inline: 8px !important;
		border: 0 !important;
		background: transparent !important;
		box-shadow: none !important;
	}
	div.tabs.ts-tabs-has-overflow > .ts-tabs-overflow a.moretab:hover,
	div.tabs.ts-tabs-has-overflow > .ts-tabs-overflow a.moretab:focus,
	div.tabs.ts-tabs-has-overflow > .ts-tabs-overflow a.moretab:focus-visible {
		outline: 0;
		background: transparent !important;
		box-shadow: inset 0 -2px 0 var(--c-accent) !important;
	}
	div.tabs.ts-tabs-has-overflow > .ts-tabs-overflow .ts-tabs-more-label {
		display: none;
	}
}
/* Dolibarr's legacy overflow opens on mouseenter and can immediately undo an
   explicit click, outside-click or Escape close. Once COMMAND binds the strip,
   the state class is the sole visibility authority on every pointer type. */
div.tabs.ts-tabs-has-overflow [id^="moretabsList"] {
	display: none !important;
}
div.tabs.ts-tabs-has-overflow [id^="moretabsList"].ts-tabs-more-open {
	display: block !important;
	border: 1px solid var(--c-border);
	border-radius: var(--r-lg);
	background: var(--c-surface);
	box-shadow: 0 12px 28px rgba(15, 23, 42, .16);
	padding: 6px !important;
}
[id^="moretabsList"].ts-tabs-more-open .popuptab > a {
	display: block;
	padding: 10px 12px;
	border-radius: var(--r);
	color: var(--c-ink-2);
	font-size: .875rem;
	text-decoration: none;
}
[id^="moretabsList"].ts-tabs-more-open .popuptab > a:hover,
[id^="moretabsList"].ts-tabs-more-open .popuptab > a:focus-visible {
	background: var(--c-accent-soft);
	color: var(--c-accent);
}
@media only screen and (max-width: 640px) {
	.fiche { padding: var(--sp-4) var(--sp-3) var(--sp-6); }
	.ts-pagehead-title div.titre, div.titre { font-size: 1.375rem; }
	div.tabBar.ts-entity-card > div.arearef.ts-has-actions { padding: var(--sp-4); }
	body.ts-thirdparty-record-context div.tabBar.ts-entity-card > .ts-entity-banner {
		align-items: flex-start;
		padding: var(--sp-4);
	}
	body.ts-thirdparty-record-context .ts-entity-banner .pagination.paginationref {
		margin-left: 0;
	}
	.ts-list-composition { gap: var(--sp-4); }
}
@media only screen and (max-width: 767px) {
	/* Read-only semantic cards stay compact on phones; generic edit tables still
	   use the safer label-above-field layout from components.inc.php. */
	.ts-field-group table.tableforfield:not(.liste) > tbody > tr {
		display: grid;
		grid-template-columns: minmax(0, 48%) minmax(0, 1fr);
		align-items: center;
		padding: 0;
	}
	.ts-field-group table.tableforfield:not(.liste) > tbody > tr > td {
		display: table-cell;
		width: auto !important;
		padding: 11px var(--sp-4);
	}
}

/* ==========================================================================
   Shared COMMAND form composition

   modern.js adds these classes only after recognising a supported native form.
   The table, rows, controls, Select2 instances and action inputs are the original
   Dolibarr nodes; CSS changes their layout without changing submission semantics.
   ========================================================================== */

form.ts-modern-form {
	width: 100%;
	max-width: 1100px;
	margin: 0 auto;
}
form.ts-modern-form .ts-modern-form-card {
	margin: 0;
	padding: 22px 24px 24px;
	background: var(--c-surface);
	border: 1px solid #e4e8ef;
	border-radius: 12px;
	box-shadow: 0 6px 24px rgba(20, 31, 56, 0.055);
}

form.ts-modern-form table.ts-modern-form-header {
	width: 100%;
	margin: 0 0 10px;
	padding: 0;
	background: transparent;
	border: 0;
	border-bottom: 1px solid var(--c-hairline);
	border-radius: 0;
	box-shadow: none;
}
form.ts-modern-form table.ts-modern-form-header td {
	padding: 0 0 20px;
	border: 0;
}
form.ts-modern-form table.ts-modern-form-header tr.toptitle {
	display: flex;
	align-items: center;
}
form.ts-modern-form table.ts-modern-form-header td.col-picto {
	display: flex;
	align-items: center;
	width: 38px !important;
	min-width: 38px;
}
form.ts-modern-form table.ts-modern-form-header td.col-title {
	display: block;
	flex: 1 1 auto;
	width: auto !important;
}
form.ts-modern-form table.ts-modern-form-header div.titre {
	display: flex;
	align-items: center;
	gap: 10px;
	font-size: 1.5rem;
	font-weight: 650;
	line-height: 1.25;
	letter-spacing: -0.025em;
}
form.ts-modern-form table.ts-modern-form-header td.col-picto [class*="fa-"] {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 28px;
	height: 28px;
	margin: 0;
	border-radius: 7px;
	background: var(--c-accent-soft);
	color: var(--c-accent) !important;
	font-size: 0.875rem;
}

form.ts-modern-form table.ts-modern-form-table {
	/* One grid for the whole form. Every row -- paired or full width -- uses the
	   same three slots, so a control's x depends on the grid and never on whether
	   its field happens to own an icon.  label | adornment | control  */
	--tsf-label: 160px;
	--tsf-adorn: 26px;
	--tsf-gap: 28px;
	display: block;
	width: 100%;
	margin: 0;
	border: 0;
	background: transparent;
}
form.ts-modern-form table.ts-modern-form-table > tbody {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	column-gap: 24px;
	width: 100%;
}
form.ts-modern-form table.ts-modern-form-table tr.ts-form-row {
	display: grid;
	grid-template-columns: var(--tsf-label) minmax(0, 1fr);
	align-items: center;
	min-width: 0;
	min-height: 64px;
	box-sizing: border-box;
	padding: 12px 0;
	border: 0;
	border-bottom: 0;
	background: transparent;
}
form.ts-modern-form table.ts-modern-form-table tr.ts-form-row-full {
	grid-column: 1 / -1;
	/* Same label slot as a paired row: this is what puts a full-width control on
	   the same axis as the left-hand control of the row above it. The 200px here
	   was the reason the two axes were 11px apart. */
	grid-template-columns: var(--tsf-label) minmax(0, 1fr);
}
form.ts-modern-form table.ts-modern-form-table tr.ts-form-row-paired {
	grid-column: 1 / -1;
	grid-template-columns: var(--tsf-label) minmax(0, 1fr) var(--tsf-gap) var(--tsf-label) minmax(0, 1fr);
	column-gap: 0;
}
/* The centre gap is a real column, so the right-hand half starts at a stated
   position instead of wherever the left half happened to end. */
form.ts-modern-form table.ts-modern-form-table tr.ts-form-row-paired > td:nth-child(3) { grid-column: 4; }
form.ts-modern-form table.ts-modern-form-table tr.ts-form-row-paired > td:nth-child(4) { grid-column: 5; }
form.ts-modern-form table.ts-modern-form-table tr.ts-form-row-empty { display: none; }

body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-label,
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value {
	display: flex;
	align-items: center;
	width: auto !important;
	max-width: none !important;
	min-width: 0;
	min-height: 40px;
	padding: 0;
	border: 0;
}
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-label {
	padding-right: 12px;
	color: var(--c-ink-2);
	font-size: 0.8125rem;
	font-weight: 600;
	line-height: 1.35;
}
/* Removed: the label used to be padded when its field owned an icon, which moved
   the label instead of giving the icon a slot -- the per-field offset this pass
   replaces. The adornment column below reserves the space on every row. */
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value {
	position: relative;
	gap: 8px;
	color: var(--c-ink);
	font-size: 0.8125rem;
}
/* Every paired value reserves the same leading-icon and trailing-help slots.
   Controls therefore share an x-axis whether a particular field has zero, one,
   or both adornments. The native icons stay associated with their value cell. */
/* Applies to EVERY value cell, paired or full width: the adornment column exists
   whether or not the field has an icon, so the control's x never depends on it. */
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value {
	display: grid;
	grid-template-columns: var(--tsf-adorn) minmax(0, 1fr) 16px;
	column-gap: 0;
	align-items: center;
}
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > *:not([type="hidden"]):not(.ts-form-leading-icon):not(.ts-form-help):not(.pictofixedwidth):not(img) {
	grid-column: 2;
	min-width: 0;
}
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > span.ts-form-leading-icon,
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > span.pictofixedwidth:first-child,
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > img.pictofixedwidth:first-child {
	position: static;
	grid-column: 1;
	grid-row: 1;
	justify-self: center;
	width: auto;
	height: auto;
	margin: 0;
	color: var(--c-muted);
}
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > .ts-form-help {
	position: static;
	grid-column: 3;
	grid-row: 1;
	justify-self: center;
	width: auto;
	height: auto;
	margin: 0;
	color: var(--c-muted);
}
/* Relational Select2 fields often carry Dolibarr's adjacent "new" link
   (the fa-plus-circle action).  It is a sibling of the trigger in the
   original table cell; the grid above otherwise auto-places that sibling on
   a second row.  Compose these cells as one inline control group while
   preserving the original link and form behaviour. */
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value:has(> a .fa-plus-circle, > a .fa-plus) {
	display: flex;
	align-items: center;
	gap: 8px;
}
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value:has(> a .fa-plus-circle, > a .fa-plus) > .select2-container,
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value:has(> a .fa-plus-circle, > a .fa-plus) > span:has(> .select2-container),
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value:has(> a .fa-plus-circle, > a .fa-plus) > div:has(> .select2-container) {
	flex: 1 1 auto;
	width: auto !important;
	min-width: 0 !important;
}
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value:has(> a .fa-plus-circle, > a .fa-plus) > a:has(.fa-plus-circle),
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value:has(> a .fa-plus-circle, > a .fa-plus) > a:has(.fa-plus) {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 32px;
	width: 32px;
	height: 32px;
	margin: 0;
	border-radius: 7px;
	color: var(--c-accent) !important;
}
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value:has(> a .fa-plus-circle, > a .fa-plus) > a:has(.fa-plus-circle):hover,
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value:has(> a .fa-plus-circle, > a .fa-plus) > a:has(.fa-plus):hover {
	background: var(--c-accent-soft);
}
body#mainbody form.ts-modern-form table.ts-modern-form-table tr:has(textarea),
body#mainbody form.ts-modern-form table.ts-modern-form-table tr:has(.select2-selection--multiple) {
	align-items: start;
}
body#mainbody form.ts-modern-form table.ts-modern-form-table tr:has(textarea) td.ts-form-label {
	padding-top: 12px;
}

/* Components' generic form alignment reserves an absolute icon gutter. The
   structured grid has a real flex gap, so the original pictogram can return to
   normal flow and remain predictably attached to its control. */
/* Removed: full-width rows used to hang their icon in an absolute gutter at
   -28px while paired rows kept theirs in flow, which is why the two row types
   produced different control axes. Both now use the adornment column above. */

body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not([type="file"]):not([type="submit"]):not([type="button"]),
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > textarea,
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > select,
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > .select2-container,
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > table.nobordernopadding,
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > span:not([class*="fa-"]):has(> .select2-container) {
	width: 100% !important;
	max-width: none !important;
	min-width: 0 !important;
	box-sizing: border-box;
}
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not([type="file"]):not([type="submit"]):not([type="button"]),
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > textarea,
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > .select2-container,
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > span:has(> .select2-container),
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > table.nobordernopadding {
	flex: 1 1 auto;
}
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > span:has(> .select2-container) {
	display: block;
	flex: 1 1 auto;
}
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > div:has(> .select2-container) {
	position: relative;
	display: block;
	flex: 1 1 auto;
	width: 100%;
	min-width: 0;
}
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > span > .select2-container {
	width: 100% !important;
	max-width: none !important;
	min-width: 0 !important;
}
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > div > .select2-container {
	width: 100% !important;
	max-width: none !important;
	min-width: 0 !important;
}
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > div > .fa-info-circle {
	position: absolute;
	right: -20px;
	top: 0;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 16px;
	height: 40px;
	margin: 0;
	color: var(--c-muted);
}
form.ts-modern-form table.ts-modern-form-table td.ts-form-value > table.nobordernopadding input {
	width: 100% !important;
	max-width: none !important;
	box-sizing: border-box;
}
form.ts-modern-form table.ts-modern-form-table input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not([type="file"]):not([type="submit"]):not([type="button"]):not(.select2-search__field),
form.ts-modern-form table.ts-modern-form-table select {
	height: 40px;
	padding-left: 12px !important;
	padding-right: 12px !important;
	padding-top: 0;
	padding-bottom: 0;
	border-color: #e0e6ef;
	border-radius: 8px;
	font-size: 0.875rem;
}
form.ts-modern-form table.ts-modern-form-table textarea {
	min-height: 104px;
	padding: 10px 12px;
	border-color: #e0e6ef;
	border-radius: 8px;
	font-size: 0.875rem;
	resize: vertical;
}
form.ts-modern-form table.ts-modern-form-table input:focus,
form.ts-modern-form table.ts-modern-form-table textarea:focus,
form.ts-modern-form table.ts-modern-form-table select:focus {
	border-color: var(--c-accent);
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--c-accent) 14%, transparent);
}

form.ts-modern-form .select2-container--default .select2-selection--single {
	height: 40px;
	padding: 0 12px;
	border-color: #e0e6ef !important;
	border-radius: 8px !important;
}
form.ts-modern-form .select2-container--default.select2-container--focus .select2-selection--single,
form.ts-modern-form .select2-container--default.select2-container--focus .select2-selection--multiple,
form.ts-modern-form .select2-container--default.select2-container--open .select2-selection--single,
form.ts-modern-form .select2-container--default.select2-container--open .select2-selection--multiple {
	border-color: var(--c-accent) !important;
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--c-accent) 14%, transparent);
}
form.ts-modern-form .select2-container--default .select2-selection--single .select2-selection__rendered {
	line-height: 38px;
	font-size: 0.875rem;
}
form.ts-modern-form .select2-container--default .select2-selection--single .select2-selection__arrow {
	width: 36px;
}
form.ts-modern-form .select2-container--default .select2-selection--multiple {
	position: relative;
	display: flex;
	align-items: center;
	width: 100%;
	min-height: 40px;
	padding: 3px 30px 3px 7px;
	border-color: #e0e6ef !important;
	border-radius: 8px !important;
}
form.ts-modern-form .select2-container--default .select2-selection--multiple .select2-selection__rendered {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 4px;
	width: 100%;
	min-width: 0;
	margin: 0;
	padding: 0;
}
form.ts-modern-form .select2-container--default .select2-selection--multiple .select2-selection__choice {
	margin: 0;
	padding: 3px 8px;
	border: 0;
	border-radius: 6px;
	background: var(--c-accent-soft);
	color: var(--c-accent-ink);
}
form.ts-modern-form .select2-container--default .select2-selection--multiple::after {
	content: "";
	position: absolute;
	right: 13px;
	top: 50%;
	width: 6px;
	height: 6px;
	border-right: 1.5px solid var(--c-muted);
	border-bottom: 1.5px solid var(--c-muted);
	transform: translateY(-65%) rotate(45deg);
	pointer-events: none;
}
form.ts-modern-form .select2-container--default .select2-search--inline {
	display: inline-flex;
	align-items: center;
	flex: 1 1 40px;
	min-width: 24px;
	height: 30px;
	margin: 0;
}
body#mainbody form.ts-modern-form .select2-container--default .select2-search__field {
	width: 100% !important;
	min-width: 24px !important;
	height: 30px !important;
	margin: 0 !important;
	padding: 0 3px !important;
	border: 0 !important;
	border-radius: 0 !important;
	background: transparent !important;
	box-shadow: none !important;
	outline: 0 !important;
}
body#mainbody form.ts-modern-form .select2-selection--multiple .select2-search--inline,
body#mainbody form.ts-modern-form .select2-selection--multiple .select2-search__field {
	border: 0 !important;
	border-radius: 0 !important;
	background: transparent !important;
	box-shadow: none !important;
	outline: 0 !important;
	appearance: none;
}
body .select2-dropdown.ts-form-select2-dropdown {
	border: 1px solid #e0e6ef;
	border-radius: 9px;
	background: var(--c-surface);
	box-shadow: 0 14px 34px rgba(15, 23, 42, .14), 0 3px 8px rgba(15, 23, 42, .06);
	overflow: hidden;
	z-index: 3600;
}
body .ts-form-select2-root { margin: 0 !important; transform: none !important; }
body .ts-form-select2-dropdown .select2-search--dropdown { padding: 10px; }
body .ts-form-select2-dropdown .select2-search__field {
	height: 38px;
	padding: 0 12px;
	border: 1px solid #e0e6ef;
	border-radius: 7px;
	box-shadow: none;
}
body .ts-form-select2-dropdown .select2-search__field:focus {
	border-color: var(--c-accent);
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--c-accent) 12%, transparent);
	outline: 0;
}
body .ts-form-select2-dropdown .select2-results__option { min-height: 34px; padding: 8px 10px; font-size: .8125rem; }
body .ts-form-select2-dropdown .select2-results__options {
	max-width: 100%;
	max-height: 300px;
	padding: 4px;
	scrollbar-width: thin;
	scrollbar-color: #cbd2dc transparent;
}
body .ts-form-select2-dropdown .select2-results__options::-webkit-scrollbar { width: 6px; }
body .ts-form-select2-dropdown .select2-results__options::-webkit-scrollbar-thumb { border-radius: 8px; background: #cbd2dc; }
body .ts-form-select2-dropdown .select2-results__option {
	display: flex;
	align-items: center;
	min-height: 36px;
	border-radius: 6px;
}
body .ts-form-select2-dropdown .select2-results__option--highlighted { background: var(--c-accent-soft); color: var(--c-accent-ink); }
body .ts-form-select2-dropdown .select2-results__option[aria-selected="true"] { font-weight: 600; }
body .ts-form-select2-dropdown .ts-form-select2-empty-option { display: none !important; }
body .ts-form-select2-dropdown-compact .select2-search--dropdown { display: none; }
body .ts-form-select2-dropdown-compact .select2-results__options {
	max-height: min(320px, calc(100vh - 32px));
	overflow-y: auto;
}
body .ts-form-select2-dropdown[data-ts-select-name="commercial[]"] .select2-results__option {
	min-height: 52px;
	max-height: 56px;
	padding: 8px 10px;
	overflow: hidden;
}
body .ts-form-select2-dropdown[data-ts-select-name="commercial[]"] .select2-results__option img {
	flex: 0 0 30px;
	width: 30px !important;
	height: 30px !important;
	margin-right: 10px !important;
	border-radius: 50%;
	object-fit: cover;
}

/* Tags/categories retain Dolibarr's jQuery UI dialog, iframe and routes. This
   scopes COMMAND's shell to those two existing dialog instances only. */
body:has(iframe#iframedialogcustcats) > .ui-widget-overlay,
body:has(iframe#iframedialogsuppcats) > .ui-widget-overlay {
	position: fixed !important;
	inset: 0 !important;
	background: rgba(15, 23, 42, .52) !important;
	opacity: 1 !important;
	z-index: 3400 !important;
}
body > .ui-dialog:has(iframe#iframedialogcustcats),
body > .ui-dialog:has(iframe#iframedialogsuppcats) {
	position: fixed !important;
	top: 50% !important;
	left: 50% !important;
	width: min(1040px, calc(100vw - 32px)) !important;
	height: min(620px, 84vh) !important;
	margin: 0 !important;
	transform: translate(-50%, -50%) !important;
	border: 1px solid #e0e6ef !important;
	border-radius: 12px !important;
	background: var(--c-surface) !important;
	box-shadow: 0 28px 70px rgba(15, 23, 42, .28) !important;
	overflow: hidden !important;
	z-index: 3500 !important;
}
body > .ui-dialog.ts-category-dialog-empty-state:has(iframe#iframedialogcustcats),
body > .ui-dialog.ts-category-dialog-empty-state:has(iframe#iframedialogsuppcats) { height: min(460px, 84vh) !important; }
body > .ui-dialog.ts-category-dialog-create:has(iframe#iframedialogcustcats),
body > .ui-dialog.ts-category-dialog-create:has(iframe#iframedialogsuppcats) { height: min(820px, 84vh) !important; }
body > .ui-dialog:has(iframe#iframedialogcustcats) .ui-dialog-titlebar,
body > .ui-dialog:has(iframe#iframedialogsuppcats) .ui-dialog-titlebar {
	display: flex;
	align-items: center;
	min-height: 64px;
	padding: 0 22px !important;
	border: 0 !important;
	border-bottom: 1px solid #e7e9ee !important;
	border-radius: 0 !important;
	background: #fff !important;
}
body > .ui-dialog:has(iframe#iframedialogcustcats) .ui-dialog-title,
body > .ui-dialog:has(iframe#iframedialogsuppcats) .ui-dialog-title { color: var(--c-ink) !important; font-size: 1.1875rem !important; font-weight: 600 !important; }
body > .ui-dialog:has(iframe#iframedialogcustcats) .ui-dialog-titlebar-close,
body > .ui-dialog:has(iframe#iframedialogsuppcats) .ui-dialog-titlebar-close {
	position: absolute !important;
	top: 14px !important;
	right: 16px !important;
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	width: 36px !important;
	height: 36px !important;
	margin: 0 !important;
	border: 0 !important;
	border-radius: 8px !important;
	background: transparent !important;
}
body > .ui-dialog:has(iframe#iframedialogcustcats) .ui-dialog-titlebar-close:hover,
body > .ui-dialog:has(iframe#iframedialogsuppcats) .ui-dialog-titlebar-close:hover { background: var(--c-accent-soft) !important; }
body > .ui-dialog:has(iframe#iframedialogcustcats) .ui-dialog-titlebar-close:focus-visible,
body > .ui-dialog:has(iframe#iframedialogsuppcats) .ui-dialog-titlebar-close:focus-visible { outline: 2px solid var(--c-accent); outline-offset: 2px; }
body > .ui-dialog:has(iframe#iframedialogcustcats) .ui-dialog-content,
body > .ui-dialog:has(iframe#iframedialogsuppcats) .ui-dialog-content {
	box-sizing: border-box;
	width: 100% !important;
	height: calc(100% - 64px) !important;
	max-height: none !important;
	padding: 0 !important;
	overflow: hidden !important;
}
body > .ui-dialog:has(iframe#iframedialogcustcats) iframe,
body > .ui-dialog:has(iframe#iframedialogsuppcats) iframe { display: block; width: 100% !important; height: 100% !important; border: 0 !important; }

body.ts-category-dialog-page { min-width: 0 !important; padding-top: 0 !important; background: #f7f8fa !important; overflow-x: hidden; }
body.ts-category-dialog-page .fiche { box-sizing: border-box; width: min(100%, 820px); min-width: 0; margin-inline: auto; padding: 22px 24px 24px !important; }
body.ts-category-dialog-page .ts-pagehead { align-items: center; margin: 0 0 14px; }
body.ts-category-dialog-page .ts-pagehead-title { display: block; }
body.ts-category-dialog-page .ts-pagehead div.titre { font-size: 1.125rem; font-weight: 600; }
body.ts-category-dialog-page .ts-pagehead-title.ts-category-redundant-title { display: none !important; }
body.ts-category-dialog-page .ts-pagehead-actions { margin-left: auto; }
body.ts-category-dialog-page .ts-pagehead-actions { display: flex; width: 100%; align-items: center; justify-content: space-between; gap: 12px; }
body.ts-category-dialog-page table.table-fiche-title { box-sizing: border-box; height: 46px; margin: 0 0 14px; padding: 0 !important; }
body.ts-category-dialog-page table.table-fiche-title,
body.ts-category-dialog-page table.table-fiche-title tbody,
body.ts-category-dialog-page table.table-fiche-title tr { display: block; width: 100%; }
body.ts-category-dialog-page table.table-fiche-title td.col-picto,
body.ts-category-dialog-page table.table-fiche-title td.col-title { display: none; }
body.ts-category-dialog-page table.table-fiche-title td.col-right { display: flex !important; align-items: center; justify-content: flex-end; width: 100% !important; height: 46px; padding: 0 !important; text-align: right; }
body.ts-category-dialog-page table.table-fiche-title .pagination,
body.ts-category-dialog-page table.table-fiche-title .pagination ul { position: static !important; display: inline-flex; align-items: center; height: 40px; float: none !important; margin: 0; padding: 0; transform: none !important; }
body.ts-category-dialog-page .ts-category-view-switch {
	display: inline-flex;
	align-items: center;
	padding: 3px;
	border: 1px solid #e0e6ef;
	border-radius: 9px;
	background: #fff;
}
body.ts-category-dialog-page table.table-fiche-title:has(.col-title:empty):not(:has(a)) { display: none !important; }
body.ts-category-dialog-page .ts-category-view-option {
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	gap: 7px;
	min-width: 92px;
	height: 34px;
	margin: 0 !important;
	padding: 0 10px !important;
	border: 0 !important;
	border-radius: 7px !important;
	background: transparent !important;
	color: var(--c-muted) !important;
	font-size: .8125rem;
	font-weight: 550;
}
body.ts-category-dialog-page .ts-category-view-option.btnTitleSelected { background: var(--c-accent-soft) !important; color: var(--c-accent) !important; }
body.ts-category-dialog-page .ts-category-view-option:hover { background: #f5f6fa !important; color: var(--c-ink-2) !important; }
body.ts-category-dialog-page .ts-category-view-option .btnTitle-icon { margin: 0 !important; padding: 0 !important; font-size: .8125rem; }
body.ts-category-dialog-page .ts-pagehead .ts-primary-action {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 7px;
	height: 40px;
	padding: 0 15px !important;
	border: 1px solid var(--c-btn-action) !important;
	border-radius: 8px !important;
	background: var(--c-btn-action) !important;
	color: var(--c-btn-action-text) !important;
	box-shadow: 0 3px 8px var(--c-btn-action-ring);
}
body.ts-category-dialog-page .fichecenter.ts-category-dialog-list {
	border: 1px solid #e7e9ee;
	border-radius: 10px;
	background: #fff;
	box-shadow: 0 4px 14px rgba(15, 23, 42, .05);
	overflow: hidden;
}
body.ts-category-dialog-page .ts-category-dialog-list table.liste { margin: 0 !important; border: 0 !important; background: transparent !important; }
body.ts-category-dialog-page table.liste > tbody > tr.liste_titre,
body.ts-category-dialog-page table.liste > tbody > tr.liste_titre_filter { display: none !important; }
body.ts-category-dialog-page .ts-category-dialog-list tr.oddeven td { min-height: 46px; border-bottom: 1px solid #f0f2f5; }
body.ts-category-dialog-page .ts-category-dialog-list tr.oddeven:hover td { background: #fafbff; }
body.ts-category-dialog-page table.liste tr.ts-category-data-row td.ts-category-row-main { height: 48px; padding: 0 10px 0 16px !important; }
body.ts-category-dialog-page table.liste tr.ts-category-data-row td.ts-category-row-hidden { display: none !important; }
body.ts-category-dialog-page .ts-category-list-row-content { display: flex; width: 100%; min-width: 0; align-items: center; gap: 12px; }
body.ts-category-dialog-page .ts-category-list-row-content > a.classforajaxtooltip { display: inline-flex; min-width: 0; align-items: center; gap: 8px; color: var(--c-ink-2) !important; font-size: .875rem; font-weight: 550 !important; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
body.ts-category-dialog-page .ts-category-list-row-content > a.classforajaxtooltip .paddingright { padding: 0 !important; color: var(--c-accent); }
body.ts-category-dialog-page .ts-category-row-actions { display: inline-flex; flex: 0 0 auto; align-items: center; gap: 4px; margin-left: auto; }
body.ts-category-dialog-page .ts-category-row-actions a,
body.ts-category-dialog-page #iddivjstree a.editfielda,
body.ts-category-dialog-page #iddivjstree a.deletefilelink { display: inline-flex; width: 34px; height: 34px; align-items: center; justify-content: center; border-radius: 8px; color: var(--c-muted); }
body.ts-category-dialog-page .ts-category-row-actions a:hover,
body.ts-category-dialog-page #iddivjstree a.editfielda:hover,
body.ts-category-dialog-page #iddivjstree a.deletefilelink:hover { background: var(--c-accent-soft); color: var(--c-accent); }
body.ts-category-dialog-page .ts-category-dialog-list .noborderoncategories { background: transparent !important; }
body.ts-category-dialog-page .ts-category-dialog-list #iddivjstree,
body.ts-category-dialog-page .ts-category-dialog-list #iddivjstree ul { margin: 0; padding: 0; list-style: none; background: none !important; }
body.ts-category-dialog-page .ts-category-dialog-list #iddivjstree li { box-sizing: border-box; min-height: 46px; padding: 0 0 0 18px; background: none !important; }
body.ts-category-dialog-page .ts-category-dialog-list #iddivjstree li li { padding-left: 24px; }
body.ts-category-dialog-page .ts-category-dialog-list #iddivjstree table { width: 100%; min-height: 46px; margin: 0; background: transparent; }
body.ts-category-dialog-page .ts-category-dialog-list #iddivjstree td { height: 46px; padding: 0 8px; text-align: left; vertical-align: middle; }
body.ts-category-dialog-page .ts-category-dialog-list #iddivjstree td.right,
body.ts-category-dialog-page .ts-category-dialog-list #iddivjstree td.center { width: 34px !important; text-align: center; }
body.ts-category-dialog-page .ts-category-dialog-list #iddivjstree .noborderoncategories { background: transparent !important; }
body.ts-category-dialog-page .ts-category-dialog-list #iddivjstree .noborderoncategories > a { display: inline-flex; align-items: center; gap: 7px; color: var(--c-ink-2) !important; font-size: .8125rem; }
body.ts-category-dialog-page .ts-category-dialog-list #iddivjstree .noborderoncategories > a .paddingright { padding: 0 !important; color: var(--c-accent); }
body.ts-category-dialog-page td.ts-category-dialog-empty { height: 138px; padding: 18px 24px !important; text-align: center; }
body.ts-category-dialog-page td.ts-category-dialog-empty > table { display: flex; flex-direction: column; align-items: center; gap: 10px; margin: auto; }
body.ts-category-dialog-page .ts-category-empty-icon { display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px; background: none; color: var(--c-accent); font-size: 1rem; }
body.ts-category-dialog-page .ts-category-empty-row .ts-category-empty-icon { margin: 0 auto 10px; }
body.ts-category-dialog-page .ts-category-empty-row .opacitymedium { display: block; }
body.ts-category-dialog-page .ts-category-empty-content tbody,
body.ts-category-dialog-page .ts-category-empty-content tr,
body.ts-category-dialog-page .ts-category-empty-content td { display: contents; }
body.ts-category-dialog-page td.ts-category-dialog-empty img { display: none; }
body.ts-category-dialog-page td.ts-category-dialog-empty .opacitymedium { max-width: 520px; color: var(--c-muted); font-size: .875rem; line-height: 1.55; }

body.ts-category-dialog-create-page .fiche { width: min(100%, 760px); }
body.ts-category-dialog-create-page form.ts-category-create-form > table.table-fiche-title { display: none !important; }
body.ts-category-dialog-create-page .tabBar { box-sizing: border-box; margin: 0; padding: 22px 24px; border: 1px solid #e7e9ee; border-radius: 10px; background: #fff; box-shadow: 0 4px 14px rgba(15,23,42,.05); }
body.ts-category-dialog-create-page .tabBar table.border { display: block; width: 100%; }
body.ts-category-dialog-create-page .tabBar table.border > tbody { display: grid; width: 100%; grid-template-columns: minmax(140px, 150px) minmax(0, 1fr); column-gap: 24px; row-gap: 14px; }
body.ts-category-dialog-create-page .tabBar table.border > tbody > tr.ts-category-form-row { display: contents; }
body.ts-category-dialog-create-page .tabBar table.border td.ts-category-form-label { display: flex; width: auto !important; min-width: 0; min-height: 40px; align-items: center; padding: 0 !important; border: 0; color: var(--c-ink-2); font-size: .8125rem; font-weight: 600; vertical-align: middle; }
body.ts-category-dialog-create-page .tabBar table.border td.ts-category-form-label.tdtop { align-items: flex-start; padding-top: 11px !important; }
body.ts-category-dialog-create-page .tabBar table.border td.ts-category-form-control { display: block; min-width: 0; padding: 0 !important; border: 0; vertical-align: top; }
body.ts-category-dialog-create-page .tabBar input:not([type="hidden"]):not([type="submit"]):not([type="button"]),
body.ts-category-dialog-create-page .tabBar select { box-sizing: border-box; width: 100%; height: 40px; padding: 0 12px; border: 1px solid #e0e6ef; border-radius: 8px; }
body.ts-category-dialog-create-page .tabBar #position { width: 120px !important; min-width: 0 !important; max-width: none !important; text-align: left; }
body.ts-category-dialog-create-page .tabBar .cke { width: 100% !important; border: 1px solid #e0e6ef !important; border-radius: 8px !important; overflow: hidden; }
body.ts-category-dialog-create-page .tabBar .cke_top { padding: 8px 8px 4px !important; }
body.ts-category-dialog-create-page .tabBar .cke_toolbox { display: flex !important; flex-wrap: wrap; align-items: flex-start; }
body.ts-category-dialog-create-page .tabBar .cke_toolbar { float: none !important; }
body.ts-category-dialog-create-page .tabBar .cke_toolbar_break { display: none !important; }
body.ts-category-dialog-create-page .tabBar .cke_toolgroup { margin: 0 4px 4px 0 !important; }
body.ts-category-dialog-create-page .tabBar .cke_button { padding: 4px !important; }
body.ts-category-dialog-create-page .tabBar .cke_contents { height: 210px !important; }
body.ts-category-dialog-create-page .ts-category-color-control { display: inline-flex; width: min(100%, 380px); height: 40px; align-items: stretch; overflow: hidden; border: 1px solid #e0e6ef; border-radius: 8px; background: #fff; }
body.ts-category-dialog-create-page .ts-category-color-control #colorpickercolor { flex: 1 1 auto; width: auto !important; min-width: 0; height: 38px; border: 0 !important; border-radius: 0 !important; }
body.ts-category-dialog-create-page .ts-category-color-control > .jPicker { display: inline-flex !important; flex: 0 0 40px; width: 40px !important; height: 40px !important; align-items: center; justify-content: center; border-left: 1px solid #e7e9ee; }
body.ts-category-dialog-create-page .ts-category-color-control > .jPicker .Icon { display: block !important; width: 40px !important; height: 40px !important; margin: 0 !important; }
body.ts-category-dialog-create-page .ts-category-color-control > .jPicker .Icon > span { width: 40px !important; height: 40px !important; }
body.ts-category-dialog-create-page .ts-category-form-control > .pictofixedwidth[title] { display: none; }
body.ts-category-dialog-create-page .ts-category-parent-container { box-sizing: border-box; width: 100% !important; }
body.ts-category-dialog-create-page .ts-category-parent-container .select2-selection { box-sizing: border-box; width: 100%; height: 40px !important; border: 1px solid #e0e6ef !important; border-radius: 8px !important; }
body.ts-category-dialog-create-page .ts-category-parent-container .select2-selection__rendered { height: 38px; padding-inline: 12px 38px !important; line-height: 38px !important; color: var(--c-ink-2); }
body.ts-category-dialog-create-page .ts-category-parent-container .select2-selection__arrow { width: 36px; height: 38px; }
body.ts-category-dialog-create-page .select2-dropdown.ts-category-select2-dropdown { border: 1px solid #e0e6ef !important; border-radius: 8px !important; background: #fff; box-shadow: 0 12px 28px rgba(15,23,42,.16); overflow: hidden; }
body.ts-category-dialog-create-page .ts-category-select2-dropdown .select2-search--dropdown { padding: 8px; }
body.ts-category-dialog-create-page .ts-category-select2-dropdown .select2-search--dropdown.ts-category-select2-search-hidden { display: none !important; }
body.ts-category-dialog-create-page .ts-category-select2-dropdown .select2-search__field { box-sizing: border-box; width: 100%; height: 38px; padding: 0 11px; border: 1px solid #e0e6ef; border-radius: 8px; outline: 0; }
body.ts-category-dialog-create-page .ts-category-select2-dropdown .select2-results__options { max-height: 280px; overflow-y: auto; }
body.ts-category-dialog-create-page .ts-category-select2-dropdown .select2-results__option { display: flex; min-height: 38px; align-items: center; padding: 0 12px; font-size: .8125rem; }
body.ts-category-dialog-create-page .ts-category-select2-dropdown .select2-results__option--highlighted[aria-selected] { background: var(--c-accent-soft); color: var(--c-accent); }
body.ts-category-dialog-create-page .center:has(input[type="submit"]) { display: flex; justify-content: center; gap: 10px; margin-top: 24px; padding-bottom: 4px; }
body.ts-category-dialog-create-page .center:has(input[type="submit"]) input.button { min-width: 110px; height: 40px; margin: 0; border-radius: 8px; }
body.ts-category-dialog-create-page .center:has(input[type="submit"]) input[name="creation"] { border: 1px solid var(--c-btn-action) !important; background: var(--c-btn-action) !important; color: var(--c-btn-action-text) !important; box-shadow: 0 3px 8px var(--c-btn-action-ring); }
body.ts-category-dialog-create-page .center:has(input[type="submit"]) input[name="cancel"] { border: 1px solid #e0e6ef !important; background: #fff !important; color: var(--c-ink-2) !important; }
body .ts-form-select2-dropdown[data-ts-select-name="country_id"] .select2-results__option img,
body .ts-form-select2-dropdown[data-ts-select-name="state_id"] .select2-results__option img {
	flex: 0 0 20px;
	width: 20px !important;
	max-width: 20px !important;
	margin-right: 8px !important;
	object-fit: contain;
}
@media only screen and (max-width: 900px) {
	body > .ui-dialog:has(iframe#iframedialogcustcats),
	body > .ui-dialog:has(iframe#iframedialogsuppcats) { width: calc(100vw - 24px) !important; max-height: 86vh !important; }
	body.ts-category-dialog-page .fiche { width: 100%; padding: 16px !important; }
	body.ts-category-dialog-page .ts-pagehead { align-items: flex-start; gap: 12px; flex-wrap: wrap; }
	body.ts-category-dialog-page .ts-pagehead-actions { margin-left: 0; }
	body.ts-category-dialog-create-page .fiche { padding-inline: 16px !important; }
	body.ts-category-dialog-create-page .tabBar { padding: 18px; }
	body.ts-category-dialog-create-page .tabBar table.border > tbody { grid-template-columns: 1fr; row-gap: 7px; }
	body.ts-category-dialog-create-page .tabBar table.border td.ts-category-form-label { min-height: 26px; align-items: flex-end; }
	body.ts-category-dialog-create-page .tabBar table.border td.ts-category-form-label.tdtop { padding-top: 6px !important; }
}
form.ts-modern-form .ts-form-select2-placeholder { color: var(--c-faint); }

body#mainbody form.ts-modern-form tr.ts-form-choice-row td.ts-form-value {
	gap: 24px;
	flex-wrap: nowrap;
}
form.ts-modern-form tr.ts-form-choice-row td.ts-form-value > .spannature {
	display: inline-flex;
	align-items: center;
	flex: 0 0 auto;
	min-height: 32px;
	margin: 0;
	padding: 0;
	border: 0;
	background: transparent;
	box-shadow: none;
}
form.ts-modern-form tr.ts-form-choice-row td.ts-form-value > .spannature > label {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	margin: 0;
	font-size: 0.8125rem;
	font-weight: 520;
	line-height: 1.25;
	cursor: pointer;
}
form.ts-modern-form input[type="checkbox"],
form.ts-modern-form input[type="radio"] {
	width: 17px;
	height: 17px;
	min-width: 17px;
	margin: 0 !important;
}

/* Compound fields retain every native control while presenting one deliberate
   relationship instead of unrelated fragments. */
body#mainbody form.ts-modern-form tr.ts-form-compound-incoterms td.ts-form-value {
	display: grid;
	grid-template-columns: minmax(170px, .38fr) minmax(0, .62fr);
	gap: 8px;
}
form.ts-modern-form tr.ts-form-compound-incoterms td.ts-form-value > .select2-container { grid-column: 1; width: 100% !important; }
/* The compound layout owns the two tracks, while the shared semantic select
   classifier owns the compact trigger inside track one. This prevents a short
   enum such as Incoterms from leaving a detached chevron across the whole row. */
body#mainbody form.ts-modern-form tr.ts-form-compound-incoterms td.ts-form-value > .select2-container.ts-command-select-compact {
	width: min(100%, 340px) !important;
	justify-self: start;
}
form.ts-modern-form tr.ts-form-compound-incoterms td.ts-form-value .select2-selection--single { width: 100% !important; }
form.ts-modern-form tr.ts-form-compound-incoterms td.ts-form-value > input[name="location_incoterms"] { grid-column: 2; width: 100% !important; }
body#mainbody form.ts-modern-form tr.ts-form-compound-capital td.ts-form-value { gap: 0; }
form.ts-modern-form tr.ts-form-compound-capital td.ts-form-value > input[name="capital"] {
	border-radius: 8px 0 0 8px;
}
form.ts-modern-form tr.ts-form-compound-capital td.ts-form-value > span:not([class*="fa-"]) {
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	flex: 0 0 54px;
	height: 40px;
	box-sizing: border-box;
	border: 1px solid #e0e6ef;
	border-left: 0;
	border-radius: 0 8px 8px 0;
	background: var(--c-sunken);
	color: var(--c-ink-2);
}

/* Width roles affect only the control inside the established value track. They
   deliberately do not alter row columns, labels, icon slots, or help slots. */
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-width-compact > input:not([type="hidden"]),
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-width-compact > select,
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-width-compact > .select2-container,
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-width-compact > span:has(> .select2-container),
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-width-compact .select2-container {
	width: min(100%, 340px) !important;
	max-width: 340px !important;
}
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value.ts-form-width-large > input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not([type="file"]):not([type="submit"]):not([type="button"]),
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-width-large > select,
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-width-large > .select2-container,
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-width-large > span:has(> .select2-container),
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-width-large .select2-container {
	width: min(100%, 820px) !important;
	max-width: 820px !important;
}
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value.ts-form-width-large.ts-form-control--large-email > input[name="email"]:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not([type="file"]):not([type="submit"]):not([type="button"]) {
	width: min(100%, 760px) !important;
	max-width: 760px !important;
}
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value.ts-form-width-medium > input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not([type="file"]):not([type="submit"]):not([type="button"]),
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-width-medium > select,
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-width-medium > .select2-container,
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-width-medium > table.nobordernopadding,
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-width-medium > span:has(> .select2-container) {
	width: min(100%, 320px) !important;
	max-width: 320px !important;
}
body#mainbody form.ts-modern-form .select2-container.ts-form-control-compact {
	width: min(100%, 340px) !important;
	max-width: 340px !important;
}
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-width-full > input:not([type="hidden"]),
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-width-full > textarea,
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-width-full > .select2-container,
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-width-full > span:has(> .select2-container) {
	width: 100% !important;
	max-width: none !important;
}

body#mainbody form.ts-modern-form input[type="file"] {
	width: 100%;
	max-width: none !important;
	height: 40px;
	padding: 4px 10px 4px 4px;
	border-color: #e0e6ef;
	border-radius: 8px;
	background: var(--c-surface);
	color: var(--c-muted);
	font-size: 0.8125rem;
}
form.ts-modern-form input[type="file"]::file-selector-button {
	height: 30px;
	margin-right: 10px;
	padding: 0 12px;
	border: 1px solid var(--c-border);
	border-radius: 6px;
	background: var(--c-sunken);
	color: var(--c-ink-2);
	font: inherit;
	font-weight: 550;
}
form.ts-modern-form table.ts-modern-form-table td.ts-form-value > a.button_custcats,
form.ts-modern-form table.ts-modern-form-table td.ts-form-value > a.button_suppcats {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 40px;
	width: 40px;
	height: 40px;
	margin: 0;
	padding: 0;
	border: 1px solid #e0e6ef;
	border-radius: 8px;
	background: var(--c-surface);
	color: var(--c-accent);
	box-shadow: none;
}
form.ts-modern-form table.ts-modern-form-table td.ts-form-value > a.button_custcats:hover,
form.ts-modern-form table.ts-modern-form-table td.ts-form-value > a.button_suppcats:hover {
	background: var(--c-accent-soft);
	border-color: color-mix(in srgb, var(--c-accent) 25%, #e0e6ef);
}

form.ts-modern-form .ts-modern-form-actions {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 12px;
	margin: 30px 0 0;
	padding: 0 0 8px;
}
form.ts-modern-form .ts-modern-form-actions input.button {
	height: 40px;
	min-width: 110px;
	margin: 0;
	padding: 0 18px;
	border-radius: 8px;
	font-size: 0.8125rem;
	font-weight: 600;
}
form.ts-modern-form .ts-modern-form-actions input.button-save {
	background: var(--c-btn-action, var(--c-accent));
	border-color: var(--c-btn-action, var(--c-accent));
	color: var(--c-btn-action-text, #fff);
	box-shadow: 0 2px 5px var(--c-accent-ring);
}
form.ts-modern-form .ts-modern-form-actions input.button-save:hover {
	background: var(--c-btn-action, var(--c-accent-hover));
	border-color: var(--c-btn-action, var(--c-accent-hover));
}

@media only screen and (max-width: 900px) {
	form.ts-modern-form .ts-modern-form-card { padding: 20px; }
	form.ts-modern-form table.ts-modern-form-table > tbody { column-gap: 20px; }
	form.ts-modern-form table.ts-modern-form-table tr.ts-form-row,
	form.ts-modern-form table.ts-modern-form-table tr.ts-form-row-full {
		grid-template-columns: 150px minmax(0, 1fr);
	}
	form.ts-modern-form table.ts-modern-form-table tr.ts-form-row-paired {
		grid-template-columns: 120px minmax(0, 1fr) 120px minmax(0, 1fr);
		column-gap: 14px;
	}
}

@media only screen and (max-width: 767px) {
	form.ts-modern-form .ts-modern-form-card {
		padding: 18px 16px;
		border-radius: 10px;
	}
	form.ts-modern-form table.ts-modern-form-header div.titre { font-size: 1.375rem; }
	form.ts-modern-form table.ts-modern-form-table > tbody {
		display: block;
	}
	form.ts-modern-form table.ts-modern-form-table tr.ts-form-row,
	form.ts-modern-form table.ts-modern-form-table tr.ts-form-row-full,
	form.ts-modern-form table.ts-modern-form-table tr.ts-form-row-half,
	form.ts-modern-form table.ts-modern-form-table tr.ts-form-row-paired {
		display: grid;
		grid-template-columns: minmax(0, 1fr);
		gap: 5px;
		min-height: 0;
		padding: 12px 0;
	}
	form.ts-modern-form table.ts-modern-form-table tr.ts-form-row-paired {
		grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
		column-gap: 12px;
	}
	form.ts-modern-form table.ts-modern-form-table tr.ts-form-row-paired > td.ts-form-label,
	form.ts-modern-form table.ts-modern-form-table tr.ts-form-row-paired > td.ts-form-value {
		grid-column: auto;
	}
	form.ts-modern-form table.ts-modern-form-table tr.ts-form-row-paired > td.ts-form-label:nth-child(1),
	form.ts-modern-form table.ts-modern-form-table tr.ts-form-row-paired > td.ts-form-label:nth-child(3) {
		grid-row: 1;
	}
	form.ts-modern-form table.ts-modern-form-table tr.ts-form-row-paired > td.ts-form-value:nth-child(2),
	form.ts-modern-form table.ts-modern-form-table tr.ts-form-row-paired > td.ts-form-value:nth-child(4) {
		grid-row: 2;
	}
	form.ts-modern-form table.ts-modern-form-table td.ts-form-label,
	form.ts-modern-form table.ts-modern-form-table td.ts-form-value {
		display: flex;
		width: 100% !important;
		min-height: 0;
		padding: 0;
	}
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value {
		box-sizing: border-box;
		padding-left: 28px;
		padding-right: 20px;
	}
	form.ts-modern-form table.ts-modern-form-table td.ts-form-label { padding-top: 0; }
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-label:has(+ td.ts-form-value-has-leading) {
		padding-right: 12px;
	}
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > span.ts-form-leading-icon,
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > span.pictofixedwidth:first-child,
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > img.pictofixedwidth:first-child,
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > .ts-form-help {
		position: absolute;
		flex: 0 0 20px;
	}
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > span.ts-form-leading-icon,
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > span.pictofixedwidth:first-child,
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > img.pictofixedwidth:first-child {
		left: 0;
	}
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > .ts-form-help {
		right: 0;
	}
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > div > .fa-info-circle {
		right: 0;
	}
	body#mainbody form.ts-modern-form tr.ts-form-compound-incoterms td.ts-form-value {
		grid-template-columns: minmax(0, 1fr);
	}
	form.ts-modern-form tr.ts-form-compound-incoterms td.ts-form-value > .select2-container,
	form.ts-modern-form tr.ts-form-compound-incoterms td.ts-form-value > input[name="location_incoterms"] { grid-column: 1; }
	form.ts-modern-form table.ts-modern-form-table tr.ts-form-row.hideonsmartphone { display: grid !important; }
	form.ts-modern-form .ts-modern-form-actions { align-items: stretch; }
	form.ts-modern-form .ts-modern-form-actions input.button { flex: 1 1 0; min-width: 0; }
}

@media only screen and (max-width: 680px) {
	form.ts-modern-form table.ts-modern-form-table tr.ts-form-row-paired {
		grid-template-columns: minmax(0, 1fr);
	}
	form.ts-modern-form table.ts-modern-form-table tr.ts-form-row-paired > td.ts-form-label,
	form.ts-modern-form table.ts-modern-form-table tr.ts-form-row-paired > td.ts-form-value {
		grid-row: auto !important;
	}
}

/* ==========================================================================
   COMMAND Kanban cards
   The generic component activates only after modern.js identifies Dolibarr's
   native Kanban container. List mode therefore keeps its existing table rules.
   Entity-specific nature colours and detail rows are layered on the shared grid
   and card geometry rather than turning table rows into visual cards.
   ========================================================================== */
.ts-list-card.ts-kanban-card-surface {
	background: transparent;
	border: 0;
	border-radius: 0;
	box-shadow: none;
	overflow: visible;
}
.ts-kanban-table {
	background: transparent !important;
	border: 0 !important;
	box-shadow: none !important;
}
.ts-kanban-table tr.liste_titre,
.ts-kanban-table tr.liste_titre_filter { display: none !important; }
.ts-kanban-table tr.trkanban,
.ts-kanban-table tr.trkanban > td {
	display: table-row;
	width: 100%;
	padding: 0 !important;
	border: 0 !important;
	background: transparent !important;
}
.ts-kanban-table tr.trkanban > td { display: table-cell; }
div.box-flex-container.kanban.ts-command-kanban {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	grid-auto-rows: auto;
	gap: 14px;
	width: 100%;
	margin: 0;
	padding: 0;
	align-items: stretch;
}
div.box-flex-container.kanban.ts-command-kanban > .ts-kanban-item {
	width: auto;
	min-width: 0;
	max-width: none;
	margin: 0;
}
div.box-flex-container.kanban.ts-command-kanban .ts-kanban-card {
	position: relative;
	display: grid;
	grid-template-columns: 40px minmax(0, 1fr);
	grid-template-rows: auto auto;
	align-items: flex-start;
	column-gap: 12px;
	row-gap: 0;
	min-width: 0;
	min-height: 160px;
	height: 100%;
	padding: 16px;
	border: 1px solid var(--c-border);
	border-radius: 11px;
	background: var(--c-surface);
	box-shadow: 0 1px 2px rgba(15, 23, 42, .035), 0 6px 18px rgba(15, 23, 42, .035);
	overflow: visible;
	transform: none;
}
div.box-flex-container.kanban.ts-command-kanban .ts-kanban-card:hover {
	border-color: color-mix(in srgb, var(--c-accent) 20%, var(--c-border));
	box-shadow: 0 2px 4px rgba(15, 23, 42, .05), 0 10px 24px rgba(15, 23, 42, .06);
	transform: translateY(-1px);
}
div.box-flex-container.kanban.ts-command-kanban .ts-kanban-icon-tile {
	grid-column: 1;
	grid-row: 1;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 40px;
	width: 40px;
	height: 40px;
	min-width: 40px;
	min-height: 40px;
	margin: 0;
	padding: 0;
	box-sizing: border-box;
	border: 1px solid color-mix(in srgb, var(--c-accent) 14%, var(--c-border));
	border-radius: 9px;
	background: var(--c-accent-soft) !important;
	color: var(--c-accent-ink);
}
div.box-flex-container.kanban.ts-command-kanban .ts-kanban-icon-tile > span,
div.box-flex-container.kanban.ts-command-kanban .ts-kanban-icon-tile > i,
div.box-flex-container.kanban.ts-command-kanban .ts-kanban-icon-tile > img {
	width: auto;
	max-width: 24px;
	height: auto;
	max-height: 24px;
	margin: 0;
	font-size: 1.125rem;
}
div.box-flex-container.kanban.ts-command-kanban .info-box-content {
	display: contents;
}
.ts-kanban-head {
	grid-column: 2;
	grid-row: 1;
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: 8px;
	min-width: 0;
}
.ts-kanban-title-block { min-width: 0; flex: 1 1 auto; }
.ts-kanban-identity { min-width: 0; }
.ts-kanban-name {
	display: block;
	width: 100%;
	min-width: 0;
	margin: 0;
	padding: 0;
	overflow: hidden;
	color: var(--c-ink);
	font-size: .875rem;
	font-weight: 650;
	line-height: 1.35;
	text-overflow: ellipsis;
	white-space: nowrap;
}
.ts-kanban-name:hover { color: var(--c-accent-ink); }
.ts-kanban-alias {
	display: block;
	margin-top: 1px;
	overflow: hidden;
	color: var(--c-faint);
	font-size: .75rem;
	line-height: 1.3;
	text-overflow: ellipsis;
	white-space: nowrap;
}
.ts-kanban-natures {
	display: flex;
	flex-wrap: wrap;
	gap: 4px;
	margin-top: 6px;
}
.ts-kanban-natures[hidden] { display: none; }
.ts-kanban-nature {
	display: inline-flex;
	align-items: center;
	min-height: 19px;
	padding: 1px 8px;
	border: 1px solid transparent;
	border-radius: 999px;
	font-size: .7rem;
	font-weight: 550;
	line-height: 1.2;
}
.ts-kanban-nature-customer {
	color: #147a4b;
	background: #edf9f2;
	border-color: #ccebd9;
}
.ts-kanban-nature-prospect {
	color: var(--c-accent-ink);
	background: var(--c-accent-soft);
	border-color: color-mix(in srgb, var(--c-accent) 18%, transparent);
}
.ts-kanban-nature-vendor,
.ts-kanban-nature-supplier {
	color: #a64b12;
	background: #fff5e9;
	border-color: #f5dcc1;
}
.ts-kanban-barcode {
	display: block;
	margin-top: 6px;
	color: var(--c-muted);
	font-size: .75rem;
	font-weight: 500;
	line-height: 1.25;
}
.ts-kanban-barcode[hidden] { display: none; }
.ts-kanban-details {
	grid-column: 1 / -1;
	grid-row: 2;
	display: grid;
	gap: 6px;
	min-width: 0;
	margin-top: 10px;
	padding-bottom: 11px;
}
.ts-kanban-detail {
	display: grid;
	grid-template-columns: 40px minmax(0, 1fr);
	align-items: start;
	column-gap: 12px;
	row-gap: 0;
	min-width: 0;
	padding: 0;
	color: var(--c-muted);
	font-size: .8125rem;
	line-height: 1.3;
}
.ts-kanban-detail > .fas {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	justify-self: center;
	width: 18px;
	height: 18px;
	margin: 0;
	color: var(--c-faint);
	font-size: .75rem;
	text-align: center;
}
.ts-kanban-detail-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	justify-self: center;
	width: 18px;
	height: 18px;
	overflow: hidden;
	border-radius: 50%;
	color: var(--c-faint);
}
.ts-kanban-detail-icon img { width: 18px; height: 18px; object-fit: cover; }
.ts-kanban-detail-icon .fas { font-size: .75rem; }
.ts-kanban-detail-value {
	display: block;
	min-width: 0;
	overflow: hidden;
	color: var(--c-ink-2);
	text-overflow: ellipsis;
	white-space: nowrap;
}
.ts-kanban-address .ts-kanban-detail-value {
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 2;
	white-space: normal;
}
.ts-kanban-representative { color: var(--c-ink-2); font-weight: 550; }
.ts-kanban-representative:hover { color: var(--c-accent-ink); }
.ts-kanban-status {
	position: absolute;
	right: 16px;
	bottom: 14px;
	display: inline-flex;
	margin: 0;
}
.ts-kanban-status .badge-status { min-height: 22px; padding: 1px 9px; }
.ts-kanban-bulk-selection { display: none !important; }
@media only screen and (max-width: 1400px) {
	div.box-flex-container.kanban.ts-command-kanban { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media only screen and (max-width: 1050px) {
	div.box-flex-container.kanban.ts-command-kanban { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media only screen and (max-width: 680px) {
	div.box-flex-container.kanban.ts-command-kanban { grid-template-columns: minmax(0, 1fr); gap: 12px; }
	div.box-flex-container.kanban.ts-command-kanban .ts-kanban-card { min-height: 164px; padding: 14px; }
	.ts-kanban-status { right: 14px; bottom: 12px; }
}


/* ts-form-value > *:first-child leading space
   Some values wrap their control in a span that carries Dolibarr's own spacing
   utilities (paddinglarge, marginrightonly, ...). That padding sat before the
   control and pushed it off the column the grid had just established -- the
   radio group and the incoterm select were both doing this. The grid owns the
   leading space now, so the first wrapper inside a value cell contributes none.
   Trailing spacing is left alone: it separates a control from what follows it. */
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > span:first-child:not(.select2-container),
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > div:first-child,
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > table:first-child {
	margin-left: 0;
	padding-left: 0;
}
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > span:first-child > *:first-child {
	margin-left: 0;
}


/* deterministic value-cell columns
   The value cell has to resolve to exactly three columns for every field, or the
   control's x depends on what the field happens to contain. Two ways it was not:
   a 24px column-gap inherited from the row pushed controls to cell+26+24, and a
   cell whose children auto-placed produced a 335px first column instead of the
   26px adornment slot.

   So the template and gap are stated here, and every child is assigned a column
   explicitly: adornments to 1, help to 3, and everything else -- including the
   hidden originals select2 leaves behind -- to 2. Nothing is left to auto
   placement, which is what made this field-dependent. */
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value {
	grid-template-columns: var(--tsf-adorn) minmax(0, 1fr) 16px;
	column-gap: 0;
	gap: 0;
}
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > * {
	grid-column: 2;
}
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > span.ts-form-leading-icon,
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > span.pictofixedwidth:first-child,
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > img.pictofixedwidth:first-child {
	grid-column: 1;
	grid-row: 1;
}
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > .ts-form-help {
	grid-column: 3;
	grid-row: 1;
}

/* An "add" action trailing a control sat flush against it, reading as part of
   the field rather than as its own button. */
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > a.reposition[class*="button_"] {
	margin-left: var(--sp-2) !important;
}

/* Help belongs to the control, not to the value track's far boundary. Only
   cells that actually contain help use this five-track composition. The row
   axes and the universal leading-adornment column remain unchanged. */
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value-has-help.ts-form-width-compact {
	grid-template-columns: var(--tsf-adorn) minmax(0, 340px) 8px 16px minmax(0, 1fr);
}
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value-has-help.ts-form-width-medium {
	grid-template-columns: var(--tsf-adorn) minmax(0, 320px) 8px 16px minmax(0, 1fr);
}
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value-has-help.ts-form-width-large {
	grid-template-columns: var(--tsf-adorn) minmax(0, 820px) 8px 16px minmax(0, 1fr);
}
/* An enum control is sized to its own options rather than to its width class,
   so the class's track left the help icon stranded at the cell's far edge.
   Where that real width is known, the track uses it. Declared after the width
   classes so it refines them. */
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value-has-help.ts-form-control-measured {
	grid-template-columns: var(--tsf-adorn) minmax(0, var(--tsf-ctrl-w)) 8px 16px minmax(0, 1fr);
}
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value-has-help > .ts-form-help {
	grid-column: 4;
	justify-self: start;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 16px !important;
	height: 40px;
	margin: 0 !important;
}
@media only screen and (max-width: 767px) {
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value-has-help > .ts-form-help {
		position: static !important;
		left: auto !important;
		right: auto !important;
		top: auto !important;
	}
}


/* compact enum selects
   Sized by what the control is for, not by how much room happens to be free. A
   short fixed list gets a readable width and stops; a lookup may use the value
   area. Both are capped so neither stretches across the whole form. */
/* The generic control rule above sets every control to the full value width from
   a deeper selector, so the enum cap has to be stated at the same depth to be
   seen at all -- otherwise a seven-item list keeps stretching the whole form. */
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > select.ts-enum,
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > .ts-enum-c,
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > span:has(> .ts-enum-c) {
	width: min(100%, 340px) !important;
	max-width: 340px !important;
	justify-self: start;
}
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > select.ts-lookup,
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > .ts-lookup-c {
	width: 100% !important;
	max-width: 100% !important;
}

/* A menu for a handful of values should be the height of those values. */
.select2-container--open .select2-dropdown {
	border-radius: var(--r);
	border: 1px solid var(--c-border);
	box-shadow: var(--sh-md);
	overflow: hidden;
}
.select2-container--open .select2-results__option {
	min-height: 36px;
	display: flex;
	align-items: center;
	font-size: 0.8125rem;
}
/* Height follows the content and only scrolls once there is genuinely more than
   fits; a short list therefore shows no scrollbar and no empty panel. */
.select2-container--open .select2-results > .select2-results__options {
	max-height: 320px;
}
/* No search box on a list short enough to read at a glance. select2 still renders
   the field for a single select, so it is removed for the compact ones only. */
.select2-container--open.ts-enum-open .select2-search--dropdown { display: none; }


/* enum width driven by the cell
   select2 replaces the control with its own container and sizes it inline, so
   tagging that container from JS meant the width depended on the class landing
   on the right node. The cell already knows what kind of field it holds -- the
   original select is still in there -- so the cap is driven from the cell
   instead. One rule, no class plumbing, and it cannot drift out of sync. */
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value:has(> select.ts-enum) > .select2-container,
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value:has(select.ts-enum) > .select2-container {
	width: min(100%, 340px) !important;
	max-width: 340px !important;
	justify-self: start;
}
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value:has(select.ts-lookup) > .select2-container {
	width: 100% !important;
	max-width: 100% !important;
}


/* paired rows stack below
   Between roughly 700 and 1100px the two halves of a paired row were each too
   narrow to keep the label and control on one line, so labels wrapped by
   different amounts and the controls stopped sharing an axis -- six of them at
   900px. Rather than let the row degrade gradually, the right half moves under
   the left at a stated width. Both halves then use the single-column template
   and every control on the form is back on one axis. */
@media only screen and (max-width: 1100px) {
	body#mainbody form.ts-modern-form table.ts-modern-form-table tr.ts-form-row-paired {
		grid-template-columns: var(--tsf-label) minmax(0, 1fr);
		/* The centre gap belongs to a two-up row. Once the halves are stacked it is
		   just 24px of indent that put these controls off the axis the full-width
		   rows were already using. */
		column-gap: 0;
	}
	body#mainbody form.ts-modern-form table.ts-modern-form-table tr.ts-form-row-paired > td:nth-child(3) {
		grid-column: 1;
	}
	body#mainbody form.ts-modern-form table.ts-modern-form-table tr.ts-form-row-paired > td:nth-child(4) {
		grid-column: 2;
	}
}

/* Compound controls override only the deterministic value cell's internal child
   placement. The form's shared label, adornment, and left/right axes above stay
   untouched. These rules live after the generic `td.ts-form-value > *` mapping
   so Capital and Incoterms cannot be split back into separate visual rows. */
body#mainbody form.ts-modern-form tr.ts-form-compound-capital td.ts-form-value {
	display: grid !important;
	grid-template-columns: var(--tsf-adorn) minmax(0, 1fr) 60px !important;
	gap: 0 !important;
}
body#mainbody form.ts-modern-form tr.ts-form-compound-capital td.ts-form-value.ts-form-control--compound {
	width: min(100%, calc(320px + var(--tsf-adorn))) !important;
	max-width: calc(320px + var(--tsf-adorn)) !important;
	justify-self: start;
}
body#mainbody form.ts-modern-form tr.ts-form-compound-capital td.ts-form-value > input[name="capital"] {
	grid-column: 2 !important;
	grid-row: 1;
	width: 100% !important;
	border-radius: 8px 0 0 8px;
}
body#mainbody form.ts-modern-form tr.ts-form-compound-capital td.ts-form-value > span:not([class*="fa-"]) {
	grid-column: 3 !important;
	grid-row: 1;
	width: 60px;
	height: 40px;
}
body#mainbody form.ts-modern-form tr.ts-form-compound-incoterms td.ts-form-value {
	display: grid !important;
	grid-template-columns: var(--tsf-adorn) minmax(0, .42fr) 8px minmax(0, .58fr) !important;
	column-gap: 0 !important;
	row-gap: 0 !important;
}
body#mainbody form.ts-modern-form tr.ts-form-compound-incoterms td.ts-form-value.ts-form-control--paired {
	width: min(100%, calc(720px + var(--tsf-adorn))) !important;
	max-width: calc(720px + var(--tsf-adorn)) !important;
	justify-self: start;
}
body#mainbody form.ts-modern-form tr.ts-form-compound-incoterms td.ts-form-value > .select2-container {
	grid-column: 2 !important;
	grid-row: 1;
	width: 100% !important;
	max-width: none !important;
}
body#mainbody form.ts-modern-form tr.ts-form-compound-incoterms td.ts-form-value > input[name="location_incoterms"] {
	grid-column: 4 !important;
	grid-row: 1;
	width: 100% !important;
}

/* Semantic exceptions inside the existing paired grid. Zip is intentionally
   short while City retains its native half-track width; VAT is a medium value
   aligned on the right-hand control axis. Neither rule changes table tracks. */
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-control--short > input#zipcode[name="zipcode"] {
	width: min(100%, 210px) !important;
	max-width: 210px !important;
	text-align: left !important;
}
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-control--medium-intent > input#intra_vat[name="tva_intra"] {
	width: min(100%, 300px) !important;
	max-width: 300px !important;
}

/* Category selectors keep the shared adornment and control axes, then reserve a
   real trailing slot for Dolibarr's existing add action. The button stays in the
   same row without being copied or detached from its dialog behavior. */
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value:has(> a.button_custcats),
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value:has(> a.button_suppcats) {
	grid-template-columns: var(--tsf-adorn) minmax(0, 1fr) 48px !important;
	column-gap: 0 !important;
}
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > a.button_custcats,
body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > a.button_suppcats {
	grid-column: 3 !important;
	grid-row: 1;
	justify-self: end;
}

/* Phone form normalization -------------------------------------------------
   This is intentionally the final mobile rule for the composed form system.
   The tablet paired-row rule above has greater specificity than the original
   phone rule and used to restore a 160px label track at 390px. That left only
   ~170px for the value cell, where Dolibarr's native minwidth classes then
   clipped text, Select2 arrows and help actions. On a phone every semantic
   field is one label followed by one value row; original nodes and ordering
   remain unchanged. */
@media only screen and (max-width: 767px) {
	body#mainbody form.ts-modern-form,
	body#mainbody form.ts-modern-form .ts-modern-form-card,
	body#mainbody form.ts-modern-form table.ts-modern-form-table,
	body#mainbody form.ts-modern-form table.ts-modern-form-table > tbody {
		min-width: 0 !important;
		max-width: 100% !important;
	}
	body#mainbody form.ts-modern-form table.ts-modern-form-table tr.ts-form-row,
	body#mainbody form.ts-modern-form table.ts-modern-form-table tr.ts-form-row-full,
	body#mainbody form.ts-modern-form table.ts-modern-form-table tr.ts-form-row-half,
	body#mainbody form.ts-modern-form table.ts-modern-form-table tr.ts-form-row-paired {
		display: grid !important;
		grid-template-columns: minmax(0, 1fr) !important;
		column-gap: 0 !important;
		row-gap: 6px !important;
		min-width: 0 !important;
	}
	body#mainbody form.ts-modern-form table.ts-modern-form-table tr.ts-form-row-paired > td.ts-form-label,
	body#mainbody form.ts-modern-form table.ts-modern-form-table tr.ts-form-row-paired > td.ts-form-value,
	body#mainbody form.ts-modern-form table.ts-modern-form-table tr.ts-form-row-paired > td:nth-child(3),
	body#mainbody form.ts-modern-form table.ts-modern-form-table tr.ts-form-row-paired > td:nth-child(4) {
		grid-column: 1 !important;
		grid-row: auto !important;
	}
	body#mainbody form.ts-modern-form table.ts-modern-form-table tr.ts-form-row,
	body#mainbody form.ts-modern-form table.ts-modern-form-table tr.ts-form-row-full,
	body#mainbody form.ts-modern-form table.ts-modern-form-table tr.ts-form-row-half,
	body#mainbody form.ts-modern-form table.ts-modern-form-table tr.ts-form-row-paired {
		height: auto !important;
		min-height: 0 !important;
		margin: 0 !important;
		padding: 10px 0 !important;
	}
	body#mainbody form.ts-modern-form table.ts-modern-form-table tr.ts-form-row-empty {
		display: none !important;
		min-height: 0 !important;
		padding: 0 !important;
	}
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-label,
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value {
		width: 100% !important;
		max-width: 100% !important;
		min-width: 0 !important;
		box-sizing: border-box;
	}
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-label {
		min-height: 0 !important;
		padding: 0 !important;
		align-items: flex-start;
	}
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value {
		display: grid !important;
		grid-template-columns: var(--tsf-adorn) minmax(0, 1fr) 18px !important;
		column-gap: 0 !important;
		min-height: 40px !important;
		padding: 0 !important;
	}
	/* Width roles are valuable on desktop, where a compact enum should not fill
	   an 800px value track. On a phone those same caps produce a ragged column of
	   90px, 180px and 300px controls. All fields therefore use the one available
	   control track; compound controls retain their own internal proportions. */
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-width-compact,
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-width-medium,
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-width-large,
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-width-full,
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-control--short,
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-control--medium-intent,
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-control--compact,
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-control--large-email {
		width: 100% !important;
		max-width: 100% !important;
	}
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value-has-help.ts-form-width-compact,
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value-has-help.ts-form-width-medium,
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value-has-help.ts-form-width-large,
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value-has-help.ts-form-control-measured {
		grid-template-columns: var(--tsf-adorn) minmax(0, 1fr) 8px 18px !important;
	}
	body#mainbody form.ts-modern-form table.ts-modern-form-table td:is(.ts-form-width-compact, .ts-form-width-medium, .ts-form-width-large, .ts-form-width-full) > :is(input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]), select, textarea, .select2-container, span:has(> .select2-container), table.nobordernopadding),
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > .select2-container:is(.ts-command-select-compact, .ts-form-control-compact) {
		width: 100% !important;
		max-width: 100% !important;
	}
	/* Match the specificity of the desktop semantic-width declarations. Without
	   these forms remained technically responsive but visually ragged because
	   an input kept its 210/320px desktop maximum inside a full phone row. */
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-width-compact > input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]),
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-width-medium > input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]),
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-width-large > input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]),
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-width-compact > select,
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-width-medium > select,
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-width-large > select,
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-width-compact > .select2-container,
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-width-medium > .select2-container,
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-width-large > .select2-container,
	body#mainbody form.ts-modern-form tr.ts-form-compound-incoterms td.ts-form-value > .select2-container.ts-command-select-compact,
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-control--short > input#zipcode[name="zipcode"],
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-control--medium-intent > input#intra_vat[name="tva_intra"] {
		width: 100% !important;
		max-width: 100% !important;
	}
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not([type="submit"]):not([type="button"]),
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > textarea,
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > select,
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > .select2-container,
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value > span:has(> .select2-container),
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value .select2-container {
		width: 100% !important;
		max-width: 100% !important;
		min-width: 0 !important;
		box-sizing: border-box;
	}
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-control--short > input,
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-control--medium-intent > input {
		width: 100% !important;
		max-width: 100% !important;
	}
	body#mainbody form.ts-modern-form tr.ts-form-choice-row td.ts-form-value {
		display: flex !important;
		align-items: center;
		flex-wrap: wrap !important;
		gap: 10px 22px !important;
		padding: 0 !important;
	}
	body#mainbody form.ts-modern-form tr.ts-form-compound-incoterms td.ts-form-value {
		grid-template-columns: var(--tsf-adorn) minmax(0, 1fr) !important;
		row-gap: 8px !important;
	}
	body#mainbody form.ts-modern-form tr.ts-form-compound-incoterms td.ts-form-value > .select2-container,
	body#mainbody form.ts-modern-form tr.ts-form-compound-incoterms td.ts-form-value > input[name="location_incoterms"] {
		grid-column: 2 !important;
		grid-row: auto !important;
	}
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value:has(> a.button_custcats),
	body#mainbody form.ts-modern-form table.ts-modern-form-table td.ts-form-value:has(> a.button_suppcats) {
		grid-template-columns: var(--tsf-adorn) minmax(0, 1fr) 48px !important;
	}
}

/* COMMAND Home dashboard --------------------------------------------------
   Route-gated by modern.js. Dashboard classes such as .box and .info-box are
   shared by many Dolibarr pages, so every rule remains below this body class. */
body.ts-command-dashboard .fiche {
	background: #f7f8fa;
	padding: 20px !important;
}
body.ts-command-dashboard .ts-dashboard-native-title {
	display: none !important;
}
body.ts-command-dashboard .ts-dashboard-pagehead {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 20px;
	margin: 0 0 16px;
}
body.ts-command-dashboard .ts-dashboard-pagehead h1 {
	margin: 0;
	color: #111827;
	font-size: 26px;
	font-weight: 700;
	line-height: 1.2;
}
body.ts-command-dashboard .ts-dashboard-pagehead p {
	margin: 5px 0 0;
	color: #64748b;
	font-size: 14px;
	line-height: 1.4;
}
body.ts-command-dashboard .ts-dashboard-customize {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 9px;
	min-height: 40px;
	padding: 0 14px;
	border: 1px solid #e0e6ef;
	border-radius: 8px;
	background: #fff;
	color: #475569;
	font: inherit;
	font-size: 13px;
	font-weight: 600;
	cursor: pointer;
}
body.ts-command-dashboard .ts-dashboard-customize:hover,
body.ts-command-dashboard .ts-dashboard-customize[aria-pressed="true"] {
	border-color: #c7d2fe;
	background: #f5f3ff;
	color: #4f46e5;
}
body.ts-command-dashboard #boxcombo {
	margin: 0 0 16px auto;
	min-height: 40px;
}
body.ts-command-dashboard .ts-dashboard-summary-grid {
	display: grid !important;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 16px !important;
	margin: 0 0 16px !important;
	width: 100% !important;
}
body.ts-command-dashboard .ts-dashboard-summary-grid > .ts-dashboard-summary-item {
	width: auto !important;
	min-width: 0 !important;
	margin: 0 !important;
	padding: 0 !important;
}
body.ts-command-dashboard .ts-dashboard-summary-item > .box-flex-item-with-margin {
	height: 100%;
	margin: 0 !important;
}
body.ts-command-dashboard .ts-dashboard-summary-card {
	--kpi-tint: #eef2f7;
	--kpi-ink: #475569;
	--kpi-deep: #1e293b;
	position: relative;
	display: grid !important;
	grid-template-columns: 50px minmax(0, 1fr);
	align-items: start !important;
	column-gap: 14px;
	min-height: 118px !important;
	height: 100% !important;
	padding: 16px !important;
	border: 1px solid #e7e9ee !important;
	border-radius: 11px !important;
	background: #fff !important;
	box-shadow: 0 1px 2px rgba(15, 23, 42, .03), 0 10px 26px rgba(15, 23, 42, .05) !important;
	overflow: hidden;
}
/* A wash of the card's own colour in the corner, and a fine dot field over it.
   Both are drawn rather than placed, so there is no image to load and the colour
   follows the accent. They are positioned out of the grid so the two columns are
   unaffected. */
body.ts-command-dashboard .ts-dashboard-summary-card::before {
	content: "";
	position: absolute;
	top: 0;
	right: 0;
	width: 96px;
	height: 96px;
	background: radial-gradient(circle at 100% 0, var(--kpi-tint) 0, var(--kpi-tint) 58px, transparent 59px);
	pointer-events: none;
}
body.ts-command-dashboard .ts-dashboard-summary-card::after {
	content: "";
	position: absolute;
	top: 14px;
	right: 14px;
	width: 34px;
	height: 26px;
	background-image: radial-gradient(var(--kpi-ink) 1px, transparent 1px);
	background-size: 7px 7px;
	opacity: 0.28;
	pointer-events: none;
}
/* The title carries a short rule in the card's colour, which is what gives the
   set its rhythm when several sit side by side. */
body.ts-command-dashboard .ts-dashboard-summary-card .info-box-title::after {
	content: "";
	display: block;
	width: 34px;
	height: 4px;
	margin: 7px 0 2px;
	border-radius: 999px;
	background: linear-gradient(90deg, var(--kpi-ink), var(--kpi-deep));
}
body.ts-command-dashboard .ts-dashboard-summary-card .info-box-icon {
	display: flex !important;
	align-items: center !important;
	justify-content: center !important;
	grid-column: 1;
	grid-row: 1;
	width: 46px !important;
	height: 46px !important;
	min-width: 46px !important;
	border-radius: 50% !important;
	background: linear-gradient(145deg, var(--kpi-ink), var(--kpi-deep)) !important;
	color: #fff !important;
	box-shadow: 0 0 0 4px var(--kpi-tint) !important;
	margin: 0 !important;
	padding: 0 !important;
	border: 0 !important;
	font-size: 20px !important;
}
/* The weather card is styled separately upstream, by a rule that names the
   container and matches the weather class, and that rule is more specific than
   the one describing every other card here -- so this one card kept a short
   square icon while the rest became round tokens. Match its weight so the set
   reads as one. */
body.ts-command-dashboard div.box-flex-container .ts-dashboard-summary-card[class*="weather"] .info-box-icon {
	width: 46px !important;
	height: 46px !important;
	min-width: 46px !important;
	border-radius: 50% !important;
	background: linear-gradient(145deg, var(--kpi-ink), var(--kpi-deep)) !important;
	color: #fff !important;
	box-shadow: 0 0 0 4px var(--kpi-tint) !important;
}

body.ts-command-dashboard .ts-dashboard-summary-card .info-box-icon i,
body.ts-command-dashboard .ts-dashboard-summary-card .info-box-icon span {
	font-size: 20px !important;
}
/* The weather/global-view glyph has materially less painted area than the
   other Font Awesome module icons at the same nominal size. Compensate only
   that glyph while retaining the shared 44px dashboard tile geometry. */
body.ts-command-dashboard .ts-dashboard-summary-card.info-box-weather .info-box-icon i,
body.ts-command-dashboard .ts-dashboard-summary-card .info-box-icon i.fa-weather-level1 {
	font-size: 25px !important;
}
/* Each accent carries a tint, an ink and a deeper shade of the same hue. The
   card, its icon and its rule all read from these, so a colour is described once
   instead of being repeated in every rule that uses it. */
body.ts-command-dashboard .ts-dashboard-summary-card.ts-dashboard-accent-violet { --kpi-tint: #f1edff; --kpi-ink: #7047eb; --kpi-deep: #4a2fb0; }
body.ts-command-dashboard .ts-dashboard-summary-card.ts-dashboard-accent-blue   { --kpi-tint: #eaf1ff; --kpi-ink: #3474e8; --kpi-deep: #1d4ea8; }
body.ts-command-dashboard .ts-dashboard-summary-card.ts-dashboard-accent-green  { --kpi-tint: #eaf8ee; --kpi-ink: #24a65a; --kpi-deep: #14713c; }
body.ts-command-dashboard .ts-dashboard-summary-card.ts-dashboard-accent-cyan   { --kpi-tint: #e8f7fb; --kpi-ink: #1597b8; --kpi-deep: #0c6a83; }
body.ts-command-dashboard .ts-dashboard-summary-card.ts-dashboard-accent-orange { --kpi-tint: #fff1e6; --kpi-ink: #e66a13; --kpi-deep: #a8480a; }
body.ts-command-dashboard .ts-dashboard-summary-card.ts-dashboard-accent-rose { --kpi-tint: #fdebf5; --kpi-ink: #d94b91; --kpi-deep: #9c2f63; }
body.ts-command-dashboard .ts-dashboard-summary-card .info-box-content {
	display: flex !important;
	flex-direction: column;
	justify-content: flex-start !important;
	min-width: 0;
	min-height: 0 !important;
	padding: 1px 0 0 !important;
	text-align: left !important;
}
body.ts-command-dashboard .ts-dashboard-summary-card .info-box-title {
	margin: 0 0 7px !important;
	color: #64748b !important;
	font-size: 11px !important;
	font-weight: 700 !important;
	line-height: 1.25 !important;
	letter-spacing: .035em;
	text-transform: uppercase;
}
body.ts-command-dashboard .ts-dashboard-summary-card .info-box-number {
	margin: 0 !important;
	color: #111827 !important;
	font-size: 21px !important;
	font-weight: 650 !important;
	line-height: 1.15 !important;
}
body.ts-command-dashboard .ts-dashboard-summary-card .progress-description,
body.ts-command-dashboard .ts-dashboard-summary-card .info-box-lines,
body.ts-command-dashboard .ts-dashboard-summary-card .info-box-line {
	margin: 0 !important;
	padding: 0 !important;
	color: #64748b;
	font-size: 13px !important;
	line-height: 1.55 !important;
}
body.ts-command-dashboard .ts-dashboard-summary-card .info-box-line {
	display: flex !important;
	align-items: center;
	gap: 6px;
	min-height: 21px;
}
body.ts-command-dashboard .ts-dashboard-summary-card a {
	font-size: 13px !important;
	font-weight: 500;
}
body.ts-command-dashboard .ts-dashboard-summary-card .badge {
	min-width: 22px;
	padding: 2px 7px;
	border-radius: 999px;
}

/* The widget primitives below are written against the widget markup rather than
   against the home dashboard, so any page that renders Dolibarr boxes -- a module
   dashboard, or one a custom module adds -- is described by the same vocabulary
   without being named here. Only the section grouping and the two-column sorting
   surface stay tied to the home dashboard, which is the page that has them. */
/* Widgets are grouped into sections, and each section packs its own widgets into
   balanced columns.

   Two independent stacks ended at wildly different points -- 4130px against
   3005px on the home dashboard -- and a row grid is no better, because every row
   is as tall as the tallest card in it, so a 429px chart beside an 83px widget
   leaves a hole the height of the difference. Columns pack by height and even
   themselves out, which is what a set of mixed-height cards wants; sections give
   the reader somewhere to look rather than one long undifferentiated stream.

   The native two columns are emptied only while the dashboard is being read.
   Customize puts every widget back into them, because Dolibarr sorts within
   those two elements and dragging must keep working. */
body.ts-command-dashboard .ts-dashboard-lower-grid {
	display: block;
	clear: both;
}
body.ts-command-dashboard:not(.ts-dashboard-customizing) .ts-dashboard-lower-grid > #boxhalfleft,
body.ts-command-dashboard:not(.ts-dashboard-customizing) .ts-dashboard-lower-grid > #boxhalfright {
	display: contents;
}
body.ts-command-dashboard .ts-dash-section {
	margin: 0 0 22px;
}
/* The first semantic group follows the compact KPI grid. Give its heading the
   same deliberate surface-to-section separation used between later groups. */
body.ts-command-dashboard .ts-dashboard-lower-grid > .ts-dash-section:first-of-type {
	margin-top: 8px;
}
body.ts-command-dashboard .ts-dash-section-title {
	margin: 0 0 10px;
	color: var(--c-muted);
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.05em;
	text-transform: uppercase;
}
/* Three columns, laid out as a grid so the cards line up in rows the way they
   do while customising -- rather than being packed by height, which fits more
   cards in but leaves each column ending at a different place. The count is
   fixed rather than derived from the width: at a desk-sized window the old
   rule reached four columns and the cards became too narrow to read. */
body.ts-command-dashboard .ts-dash-section-body {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 16px;
	align-items: stretch;
}
/* Cards in a row share its height, so a row reads as a row rather than as
   three cards that happen to start level. */
body.ts-command-dashboard .ts-dash-section-body > .ts-dashboard-widget {
	height: 100%;
}
.ts-dashboard-widget {
	break-inside: avoid;
	page-break-inside: avoid;
	min-width: 0;
}
/* A section holding one or two widgets should not spread them thinly across
   three columns, and a lone card should not run the width of the page. */
body.ts-command-dashboard .ts-dash-section-body[data-ts-count="1"] {
	grid-template-columns: minmax(0, 1fr);
	max-width: 540px;
}
body.ts-command-dashboard .ts-dash-section-body[data-ts-count="2"] {
	grid-template-columns: repeat(2, minmax(0, 1fr));
}
/* Charts carry two plots side by side and need the width to stay readable. */
body.ts-command-dashboard .ts-dash-section[data-ts-section="analytics"] .ts-dash-section-body {
	grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (max-width: 1200px) {
	body.ts-command-dashboard .ts-dash-section-body {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}
@media (max-width: 900px) {
	body.ts-command-dashboard .ts-dash-section-body,
	body.ts-command-dashboard .ts-dash-section-body[data-ts-count="2"],
	body.ts-command-dashboard .ts-dash-section[data-ts-section="analytics"] .ts-dash-section-body {
		grid-template-columns: minmax(0, 1fr);
	}
	body.ts-command-dashboard .ts-dash-section-body[data-ts-count="1"] { max-width: none; }
}
/* While sorting, Dolibarr's own two columns are back and carry the widgets --
   they have to, because every save Dolibarr makes reads the order out of those
   two elements, the close and add-widget paths included.

   Laid out as two side-by-side columns, though, arranging the dashboard looked
   like a different page from the one being arranged: cards half again as wide,
   two columns instead of three, and no headings. So the columns stack, and each
   lays its own widgets out on the same three-across grid with the same gap as a
   section -- same card size, same rhythm, one page. Each column says which it
   is, since which column a widget sits in is the thing being decided here. */
body.ts-command-dashboard.ts-dashboard-customizing .ts-dashboard-lower-grid {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: 22px;
	align-items: start;
}
body.ts-command-dashboard.ts-dashboard-customizing .ts-dashboard-lower-grid > #boxhalfleft,
body.ts-command-dashboard.ts-dashboard-customizing .ts-dashboard-lower-grid > #boxhalfright {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 16px;
	align-items: stretch;
}
body.ts-command-dashboard.ts-dashboard-customizing .ts-dashboard-lower-grid > #boxhalfleft > .ts-dashboard-widget,
body.ts-command-dashboard.ts-dashboard-customizing .ts-dashboard-lower-grid > #boxhalfright > .ts-dashboard-widget {
	height: 100%;
	margin: 0 !important;
}
body.ts-command-dashboard.ts-dashboard-customizing .ts-dashboard-lower-grid > #boxhalfleft::before,
body.ts-command-dashboard.ts-dashboard-customizing .ts-dashboard-lower-grid > #boxhalfright::before {
	grid-column: 1 / -1;
	margin: 0 0 -4px;
	color: var(--c-muted);
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.05em;
	text-transform: uppercase;
}
body.ts-command-dashboard.ts-dashboard-customizing .ts-dashboard-lower-grid > #boxhalfleft::before {
	content: "First column";
}
body.ts-command-dashboard.ts-dashboard-customizing .ts-dashboard-lower-grid > #boxhalfright::before {
	content: "Second column";
}
/* The landing strip belongs to the whole column, not to one cell of its grid. */
body.ts-dashboard-customizing .ts-dashboard-droptarget {
	grid-column: 1 / -1;
}
/* COMMAND keeps widgets inside semantic sections while editing. The native
   A/B columns remain in the DOM only as Dolibarr persistence anchors, so they
   must not introduce column labels, gaps or landing strips into the grouped
   dashboard. */
body.ts-command-dashboard.ts-dashboard-customizing .ts-dashboard-lower-grid:has(> .ts-dash-section) {
	display: block;
}
body.ts-command-dashboard.ts-dashboard-customizing .ts-dashboard-lower-grid:has(> .ts-dash-section) > #boxhalfleft,
body.ts-command-dashboard.ts-dashboard-customizing .ts-dashboard-lower-grid:has(> .ts-dash-section) > #boxhalfright {
	display: contents;
}
body.ts-command-dashboard.ts-dashboard-customizing .ts-dashboard-lower-grid:has(> .ts-dash-section) > #boxhalfleft::before,
body.ts-command-dashboard.ts-dashboard-customizing .ts-dashboard-lower-grid:has(> .ts-dash-section) > #boxhalfright::before {
	content: none;
}
body.ts-command-dashboard.ts-dashboard-customizing .ts-dashboard-lower-grid:has(> .ts-dash-section) .ts-dashboard-droptarget {
	display: none !important;
}
@media (max-width: 1200px) {
	body.ts-command-dashboard.ts-dashboard-customizing .ts-dashboard-lower-grid > #boxhalfleft,
	body.ts-command-dashboard.ts-dashboard-customizing .ts-dashboard-lower-grid > #boxhalfright {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}
@media (max-width: 900px) {
	body.ts-command-dashboard.ts-dashboard-customizing .ts-dashboard-lower-grid > #boxhalfleft,
	body.ts-command-dashboard.ts-dashboard-customizing .ts-dashboard-lower-grid > #boxhalfright {
		grid-template-columns: minmax(0, 1fr);
	}
}

/* Widget titles are sized for a full-width card and overran a column card, so
   the heading ran past its own border. Keep them to the card. */
.ts-dashboard-widget .box_titre th > div:first-child {
	display: grid !important;
	grid-template-columns: minmax(0, 1fr) auto;
	align-items: center;
	gap: 8px;
	box-sizing: border-box;
	float: none !important;
	width: 100% !important;
	max-width: 100% !important;
	overflow: visible;
	/* The heading text lives in this div and is styled here rather than inherited,
	   so the casing and weight have to be stated on it too. */
	color: #6b7088 !important;
	font-size: 12px !important;
	font-weight: 700 !important;
	letter-spacing: 0.48px !important;
	text-transform: uppercase !important;
}
.ts-dashboard-widget .ts-widget-title-text {
	min-width: 0;
	overflow: visible;
	white-space: normal;
	overflow-wrap: break-word;
	line-height: 1.3;
}
.ts-dashboard-widget .ts-widget-title-action,
.ts-dashboard-widget .ts-widget-title-badge {
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	justify-self: end;
	flex: 0 0 auto;
	min-width: 28px;
	height: 28px;
	margin: 0 !important;
	padding: 0 7px !important;
	border: 1px solid var(--c-hairline);
	border-radius: 8px;
	background: var(--c-sunken);
	color: var(--c-ink-subtle) !important;
	font-size: 12px !important;
	font-weight: 650 !important;
	letter-spacing: 0 !important;
	line-height: 1 !important;
	text-decoration: none !important;
	text-transform: none !important;
}
.ts-dashboard-widget .ts-widget-title-action:hover {
	border-color: color-mix(in srgb, var(--c-accent) 25%, var(--c-hairline));
	background: var(--c-accent-soft);
	color: var(--c-accent) !important;
}
.ts-dashboard-widget .box_titre th > div:first-child > a:last-child {
	flex: 0 0 auto;
	margin-left: auto !important;
}
/* The picture Dolibarr shows beside a "nothing here" line is decoration, and at
   full size it made an empty card twice the height of the message in it. */
.ts-widget--empty tr:not(.box_titre) img,
.ts-widget--empty tr:not(.box_titre) .fas,
.ts-widget--empty tr:not(.box_titre) .far {
	width: 15px !important;
	height: 15px !important;
	max-width: 15px !important;
	max-height: 15px !important;
	font-size: 13px !important;
	line-height: 1 !important;
	vertical-align: middle;
	opacity: 0.55;
}
.ts-widget--empty tr:not(.box_titre) .ts-empty-illustration,
.ts-widget--empty tr:not(.box_titre) [class*="ts-module-index-empty"] {
	display: none !important;
}

/* A widget with nothing to report states that in one line instead of holding a
   card of blank surface. */
.ts-widget--empty tr:not(.box_titre) > td {
	height: auto !important;
	padding: 12px 14px !important;
	border-bottom: 0 !important;
	color: var(--c-muted);
	font-size: 12.5px !important;
	text-align: center;
}
.ts-widget--empty tr.box_titre,
.ts-widget--empty tr.box_titre > th {
	height: 40px !important;
}
.ts-widget--empty .opacitymedium {
	opacity: 1;
}
/* The stray info icon Dolibarr trails after an empty message adds a line of its
   own; it says nothing the message has not. */
.ts-widget--empty tr:not(.box_titre) .fa-info-circle,
.ts-widget--empty tr:not(.box_titre) img[src*="info"] {
	display: none;
}

/* Charts: less air around the canvas, so the card is sized by the plot. */
.ts-widget--chart .dolgraph {
	margin: 0 auto !important;
}
.ts-widget--chart tr:not(.box_titre) > td {
	padding: 8px 10px !important;
}

/* Figure tiles. Each figure is its own link that wrapped three to a row inside a
   narrow card, which made a readout of thirty-one figures 767px tall. Laid out as
   a grid that fills the width available, the same readout is a few rows deep. */
.ts-widget--tiles tr:not(.box_titre) > td {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(124px, 1fr));
	gap: 8px;
	height: auto !important;
	padding: 12px !important;
}
.ts-widget--tiles .boxstatsindicator.thumbstat {
	display: block;
	/* The class carries a width of its own, which left each tile 35px wide inside a
	   130px track and clipped every label to its first letter. */
	width: auto !important;
	min-width: 0 !important;
	max-width: none !important;
	height: auto !important;
	min-height: 0 !important;
	margin: 0 !important;
	padding: 0 !important;
	border: 0 !important;
}
.ts-widget--tiles .boxstats {
	display: flex;
	flex-direction: column;
	gap: 3px;
	min-height: 0;
	padding: 9px 10px;
	border: 1px solid var(--c-border);
	border-radius: 9px;
	background: #fff;
	text-align: left;
}
.ts-widget--tiles .boxstats:hover {
	border-color: var(--c-primary);
}
.ts-widget--tiles .boxstatstext {
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	color: var(--c-muted);
	font-size: 10.5px;
	font-weight: 600;
	line-height: 1.25;
	letter-spacing: 0.02em;
	text-transform: uppercase;
}
.ts-widget--tiles .boxstats br { display: none; }
.ts-widget--tiles .boxstats > .boxstatsindicator {
	display: flex;
	align-items: center;
	gap: 6px;
	color: var(--c-text);
	font-size: 15px;
	font-weight: 650;
}
/* A readout of figures earns the full width of its section rather than sitting in
   a single narrow column. */
body.ts-command-dashboard .ts-dash-section-body[data-ts-count="1"]:has(.ts-widget--tiles) {
	max-width: none;
}
/* Charts stay at two columns however wide the screen. Each of these cards holds
   two plots of about 256px side by side, so a card narrower than roughly 540px
   clips the second one -- at three columns on a 1680px screen the cards came out
   at 449px and the months ran off the axis. */
/* Charts sit in the same columns as everything else. Demanding a card wide
   enough for both plots side by side (560px) meant a single column at 1280,
   where six charts stacked into a longer page than we started with; letting the
   pair wrap inside the card instead keeps the plots at their natural size and
   the section in step with the rest of the dashboard. */
.ts-widget--chart tr:not(.box_titre) > td {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 10px;
	height: auto !important;
}
.ts-widget--chart .dolgraph {
	flex: 0 1 auto;
	min-width: 0;
}
.ts-widget--chart .dolgraph,
.ts-widget--chart canvas {
	max-width: 100%;
}
body.ts-command-dashboard .ts-dashboard-lower-grid > #boxhalfleft,
body.ts-command-dashboard .ts-dashboard-lower-grid > #boxhalfright {
	float: none !important;
	width: auto !important;
	min-width: 0;
	margin: 0 !important;
	padding: 0 !important;
}
.ts-dashboard-widget {
	margin: 0 0 16px !important;
	border: 1px solid #e7e9ee !important;
	border-radius: 11px !important;
	background: #fff !important;
	box-shadow: 0 3px 12px rgba(15, 23, 42, .035) !important;
	overflow: hidden;
}
/* A boxtable is a card in its own right everywhere else in Dolibarr, but inside a
   widget the surrounding div is already the card. Left alone the table paints a
   second white surface with its own radius and shadow just inside the first one,
   which reads as a stray layer behind every widget. Flatten it: no fill, no
   corners, no shadow -- the rows and the heading band supply the colour. */
.ts-dashboard-widget table.boxtable,
.ts-dashboard-widget div.boxtable {
	box-sizing: border-box !important;
	width: 100% !important;
	min-width: 0 !important;
	max-width: 100% !important;
	margin: 0 !important;
	border: 0 !important;
	border-collapse: collapse !important;
	border-radius: 0 !important;
	background: transparent !important;
	box-shadow: none !important;
}
.ts-dashboard-widget table.boxtable {
	table-layout: fixed !important;
}
/* The widget heading sits on a band of its own rather than on the card's white,
   which is what separates one widget from the next when several are stacked in a
   column. Small, upper case and muted, so the record rows beneath it stay the
   thing being read. */
.ts-dashboard-widget tr.box_titre,
.ts-dashboard-widget tr.box_titre > th {
	height: 44px;
	padding: 0 14px !important;
	border: 0 !important;
	border-bottom: 1px solid #e3e8f0 !important;
	background: #eef1f7 !important;
	color: #6b7088 !important;
	font-size: 12px !important;
	font-weight: 700 !important;
	letter-spacing: 0.48px !important;
	text-transform: uppercase !important;
}
.ts-dashboard-widget tr.oddeven > td,
.ts-dashboard-widget table.boxtable > tbody > tr:not(.box_titre) > td {
	height: 44px;
	padding: 10px 14px !important;
	border: 0 !important;
	border-bottom: 1px solid rgba(107, 112, 136, .14) !important;
	background: #fff !important;
	color: #4b4f66 !important;
	font-size: 13px !important;
}
.ts-dashboard-widget table.boxtable > tbody > tr:last-child > td {
	border-bottom: 0 !important;
}
.ts-dashboard-widget tr.oddeven:hover > td {
	background: #fafbff !important;
}
/* The column drop targets Dolibarr appends are only meaningful while widgets are
   being dragged, so they stay out of the layout until then -- otherwise each one
   holds an empty grid cell and pushes the widgets around it out of line. While
   the dashboard is being rearranged they show as the dashed landing strip they
   are. */
.ts-dashboard-droptarget {
	display: none;
}
body.ts-dashboard-customizing .ts-dashboard-droptarget {
	display: block;
	min-height: 48px;
	margin: 0 0 16px;
	border: 1px dashed #c3cbdb;
	border-radius: 11px;
	background: rgba(99, 112, 140, .03);
}
/* Widgets in a row are stretched to a common height, but a table keeps its own
   natural height inside that card, so a one-line "nothing to show" sat just
   under the heading with the rest of the card empty below it -- centred across,
   but not in the middle of the space it was given. Let the body fill the card
   and put the line in the middle of it, which is the only way the text reads as
   placed rather than stranded. */
.ts-dashboard-widget.ts-widget--empty > table.boxtable,
.ts-dashboard-widget.ts-widget--info > table.boxtable {
	height: 100% !important;
}
/* A row given a height in a stretched table still takes a share of the slack, so
   the heading band grew along with the body. Claiming the full height for the
   body row leaves the band at its own 44px and hands the rest to the one thing
   that should absorb it. */
.ts-dashboard-widget.ts-widget--empty table.boxtable > tbody > tr:not(.box_titre),
.ts-dashboard-widget.ts-widget--info table.boxtable > tbody > tr:not(.box_titre) {
	height: 100% !important;
}
.ts-dashboard-widget.ts-widget--empty table.boxtable > tbody > tr:not(.box_titre) > td,
.ts-dashboard-widget.ts-widget--info table.boxtable > tbody > tr:not(.box_titre) > td {
	height: auto !important;
	vertical-align: middle !important;
}
/* Shown only while arranging the dashboard. Quiet at rest -- a muted glyph with
   no box of its own, since a pair of bordered buttons on every heading turns the
   band into a row of chrome -- and each takes its meaning on hover: neutral for
   the handle, red for removal.

   Only the icons are sized. The element wrapping them carries the same boxclose
   class as the remove icon inside it, so a rule written for the class alone
   squeezed the wrapper to one icon's width and pushed both icons out of it --
   the remove icon ended a pixel past the heading's own edge and overlapped the
   title. */
.ts-dashboard-widget .box_titre th > div.boxclose {
	display: inline-flex !important;
	align-items: center;
	gap: 2px;
	width: auto !important;
	min-width: 0 !important;
	height: auto !important;
	padding: 0 !important;
	border: 0 !important;
	background: transparent !important;
}
.ts-dashboard-widget span.boxhandle,
.ts-dashboard-widget span.boxclose {
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	flex: 0 0 26px;
	width: 26px !important;
	min-width: 26px !important;
	height: 26px !important;
	margin: 0 !important;
	padding: 0 !important;
	border: 0 !important;
	border-radius: 8px;
	background: transparent !important;
	box-shadow: none !important;
	color: #99a0b5 !important;
	font-size: 12px !important;
	opacity: 1 !important;
	cursor: pointer;
	transition: background-color .12s ease, color .12s ease;
}
.ts-dashboard-widget span.boxhandle { cursor: move; }
.ts-dashboard-widget span.boxhandle:hover {
	background-color: #e2e8f1 !important;
	color: #475569 !important;
}
.ts-dashboard-widget span.boxclose:hover {
	background-color: #ffe4e6 !important;
	color: #e11d48 !important;
}
/* The legacy dashboard supplies Font Awesome classes for these controls, but
   some mobile builds do not paint those particular glyph aliases. Use stable
   text glyphs and take the control group out of the title's flow so entering
   Customize never changes card height or column geometry. */
body.ts-command-dashboard.ts-dashboard-customizing .ts-dashboard-widget .box_titre th {
	position: relative;
}
body.ts-command-dashboard.ts-dashboard-customizing .ts-dashboard-widget .box_titre th > div.boxclose {
	position: absolute;
	top: 50%;
	right: 10px;
	z-index: 3;
	transform: translateY(-50%);
	gap: 4px;
	opacity: 1 !important;
}
body.ts-command-dashboard.ts-dashboard-customizing .ts-dashboard-widget .box_titre th > div:first-child {
	max-width: calc(100% - 76px) !important;
}
body.ts-command-dashboard.ts-dashboard-customizing .ts-dashboard-widget .box_titre th > div:first-child > a:last-child {
	display: none !important;
}
body.ts-command-dashboard.ts-dashboard-customizing .ts-dashboard-widget span.boxhandle,
body.ts-command-dashboard.ts-dashboard-customizing .ts-dashboard-widget span.boxclose {
	flex-basis: 32px;
	width: 32px !important;
	min-width: 32px !important;
	height: 32px !important;
	font-family: inherit !important;
	font-size: 17px !important;
	font-weight: 700;
	line-height: 1 !important;
	color: #64748b !important;
}
body.ts-command-dashboard.ts-dashboard-customizing .ts-dashboard-widget span.boxhandle > svg,
body.ts-command-dashboard.ts-dashboard-customizing .ts-dashboard-widget span.boxclose > svg {
	display: block !important;
	flex: 0 0 16px;
	width: 16px !important;
	height: 16px !important;
	visibility: visible !important;
	opacity: 1 !important;
}
body.ts-command-dashboard.ts-dashboard-customizing .ts-dashboard-widget span.boxhandle::before {
	content: none !important;
}
body.ts-command-dashboard.ts-dashboard-customizing .ts-dashboard-widget span.boxclose::before {
	content: none !important;
}
body.ts-command-dashboard.ts-dashboard-customizing .ts-dashboard-widget span.boxclose {
	font-size: 20px !important;
	font-weight: 500;
}
body.ts-command-dashboard:not(.ts-dashboard-customizing) .ts-dashboard-widget .boxhandle,
body.ts-command-dashboard:not(.ts-dashboard-customizing) .ts-dashboard-widget .boxclose {
	display: none !important;
}
body.ts-command-dashboard .ts-dashboard-invoices table.boxtable > tbody > tr:not(.box_titre) > td.center {
	height: 150px;
	padding: 28px !important;
	color: #64748b;
	font-size: 14px !important;
}
body.ts-command-dashboard .ts-dashboard-invoices table.boxtable > tbody > tr:not(.box_titre) > td.center::before {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 48px;
	height: 48px;
	margin: 0 auto 12px;
	border-radius: 50%;
	background: #f1edff;
	color: #7047eb;
	font-family: "Font Awesome 5 Free";
	font-size: 20px;
	font-weight: 900;
	content: "\f571";
}
body.ts-command-dashboard .ts-dashboard-prospects table.boxtable > tbody > tr:not(.box_titre) > td:first-child {
	font-weight: 500;
}

@media (max-width: 1350px) {
	body.ts-command-dashboard .ts-dashboard-summary-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 980px) {
	body.ts-command-dashboard .fiche { padding: 16px !important; }
	body.ts-command-dashboard .ts-dashboard-summary-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	body.ts-command-dashboard .ts-dashboard-lower-grid { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 640px) {
	body.ts-command-dashboard .fiche { padding: 12px !important; }
	body.ts-command-dashboard .ts-dashboard-pagehead { align-items: flex-start; }
	body.ts-command-dashboard .ts-dashboard-pagehead h1 { font-size: 24px; }
	body.ts-command-dashboard .ts-dashboard-pagehead p { font-size: 13px; }
	body.ts-command-dashboard .ts-dashboard-customize { flex: 0 0 auto; }
	/* A 600px tablet-sized viewport has room for two useful KPI cards. Collapsing
	   it to one column made the summary alone almost two screens longer than it
	   needed to be. Phones still switch to one column below. */
	body.ts-command-dashboard .ts-dashboard-summary-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 12px !important;
	}
	body.ts-command-dashboard .ts-dashboard-summary-card {
		grid-template-columns: 44px minmax(0, 1fr);
		column-gap: 11px;
		min-height: 108px !important;
		padding: 14px !important;
	}
	/* Dashboard widgets contain legacy tables with several business-data columns.
	   The card deliberately clips its decorative surface, but that also clipped the
	   final columns on a phone. Make the data area an intentional local scroller;
	   the document itself stays fixed to the viewport and no values disappear. */
	body.ts-command-dashboard .ts-dashboard-widget {
		overflow-x: hidden;
		overflow-y: hidden;
	}
	body.ts-command-dashboard .ts-widget--table > table.boxtable,
	body.ts-command-dashboard .ts-widget--table > table.boxtable > tbody {
		display: block;
		width: 100% !important;
		min-width: 0 !important;
	}
	body.ts-command-dashboard .ts-widget--table table.boxtable tr.box_titre {
		display: flex;
		width: 100%;
	}
	body.ts-command-dashboard .ts-widget--table table.boxtable tr.box_titre > th {
		flex: 1 1 auto;
		width: 100% !important;
		min-width: 0 !important;
	}
	body.ts-command-dashboard .ts-dashboard-widget table.boxtable tr.box_titre > th {
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
	}
	/* Populated widgets carry an existing "view all" badge in the same legacy
	   wrapper as their title. Keep the link out of title flow, but keep every
	   heading on the same left axis. Centring this wrapper made some titles start
	   halfway across the card while other widget kinds remained left aligned. */
	body.ts-command-dashboard .ts-widget--table table.boxtable tr.box_titre > th {
		position: relative;
	}
	body.ts-command-dashboard .ts-widget--table .box_titre th > div:first-child {
		box-sizing: border-box;
		justify-content: flex-start;
		min-height: 44px;
		padding: 0 !important;
		text-align: left !important;
	}
	body.ts-command-dashboard .ts-widget--table .box_titre th > div:first-child > a:last-child {
		position: static !important;
		margin: 0 !important;
		transform: none !important;
	}
	body.ts-command-dashboard .ts-dashboard-widget .box_titre th > div:first-child {
		display: grid !important;
		float: none !important;
		width: 100% !important;
		overflow: visible !important;
	}
	body.ts-command-dashboard .ts-widget--table table.boxtable tr:not(.box_titre) {
		display: grid;
		grid-auto-flow: column;
		grid-auto-columns: minmax(0, 1fr);
		width: 100%;
	}
	body.ts-command-dashboard .ts-widget--table table.boxtable tr:not(.box_titre) > td {
		display: flex;
		align-items: center;
		justify-content: center;
		width: 100% !important;
		min-width: 0 !important;
		max-width: none !important;
		padding-inline: 7px !important;
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
	}
	body.ts-command-dashboard .ts-widget--table table.boxtable tr:not(.box_titre) > td:first-child {
		justify-content: flex-start;
	}
	body.ts-command-dashboard .ts-widget--table table.boxtable tr:not(.box_titre) > td:first-child > a {
		display: block !important;
		width: 100%;
		text-align: left;
	}
	body.ts-command-dashboard .ts-widget--table table.boxtable tr:not(.box_titre) > td a {
		min-width: 0;
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
	}
}
@media (max-width: 520px) {
	body.ts-command-dashboard .ts-dashboard-summary-grid { grid-template-columns: minmax(0, 1fr); }
	body.ts-command-dashboard .ts-dashboard-summary-card {
		grid-template-columns: 50px minmax(0, 1fr);
		column-gap: 14px;
		padding: 16px !important;
	}
}

/* Third Parties module landing -------------------------------------------
   Exact route-gated by modern.js. No generic .fichecenter/.box selector leaks
   into lists, records, forms, or other module landing pages. */
body.ts-thirdparty-dashboard .fiche {
	padding: 24px 20px 36px !important;
	background: #f7f8fa;
}
body.ts-thirdparty-dashboard .ts-pagehead {
	align-items: center;
	margin-bottom: 24px;
}
body.ts-thirdparty-dashboard .ts-pagehead-title {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 4px;
}
body.ts-thirdparty-dashboard .ts-pagehead-title .titre {
	font-size: 27px !important;
	font-weight: 700 !important;
	line-height: 1.2;
}
body.ts-thirdparty-dashboard .ts-module-subtitle {
	margin: 0;
	color: #64748b;
	font-size: 14px;
	font-weight: 400;
	line-height: 1.45;
}
body.ts-thirdparty-dashboard .ts-view-all-contacts {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 9px;
	min-height: 42px;
	padding: 0 15px;
	border: 1px solid #c7d2fe;
	border-radius: 8px;
	background: #fff;
	color: #4f46e5;
	font-size: 13px;
	font-weight: 600;
	text-decoration: none;
}
body.ts-thirdparty-dashboard .ts-view-all-contacts:hover {
	background: #f5f3ff;
	border-color: #a5b4fc;
}
body.ts-thirdparty-dashboard .fichecenter.ts-thirdparty-dashboard-grid {
	margin: 0 !important;
	width: 100%;
}
body.ts-thirdparty-dashboard .ts-thirdparty-dashboard-grid > .twocolumns {
	display: grid !important;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	align-items: start;
	gap: 18px;
	width: 100%;
}
body.ts-thirdparty-dashboard .ts-thirdparty-dashboard-grid .ts-module-dashboard-card {
	float: none !important;
	width: auto !important;
	min-width: 0;
	margin: 0 !important;
	padding: 0 22px 20px !important;
	border: 1px solid #e7e9ee;
	border-radius: 12px;
	background: #fff;
	box-shadow: 0 5px 18px rgba(15, 23, 42, .045);
	overflow: hidden;
}
body.ts-thirdparty-dashboard .ts-module-card-header {
	display: grid;
	grid-template-columns: 36px minmax(0, 1fr) auto;
	align-items: center;
	gap: 12px;
	min-height: 72px;
	border-bottom: 1px solid #edf0f4;
}
body.ts-thirdparty-dashboard .ts-module-card-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	border-radius: 9px;
	background: #f1edff;
	color: #7047eb;
	font-size: 16px;
}
body.ts-thirdparty-dashboard .ts-module-card-header h2 {
	margin: 0;
	color: #1e293b;
	font-size: 16px;
	font-weight: 650;
	line-height: 1.3;
}
body.ts-thirdparty-dashboard .ts-module-card-link,
body.ts-thirdparty-dashboard .ts-module-footer-link {
	color: #4f46e5;
	font-size: 13px;
	font-weight: 600;
	text-decoration: none;
}
body.ts-thirdparty-dashboard .ts-module-card-link:hover,
body.ts-thirdparty-dashboard .ts-module-footer-link:hover { text-decoration: underline; }
body.ts-thirdparty-dashboard .ts-module-dashboard-body {
	width: 100% !important;
	margin: 0 !important;
	border: 0 !important;
	border-radius: 0 !important;
	box-shadow: none !important;
	overflow: visible !important;
}
body.ts-thirdparty-dashboard .ts-module-dashboard-table {
	width: 100% !important;
	margin: 0 !important;
	border: 0 !important;
	background: transparent !important;
}

body.ts-thirdparty-dashboard .ts-module-dashboard-stats .ts-statistics-chart-row > td {
	height: 286px;
	padding: 18px 0 12px !important;
	border: 0 !important;
	background: #fff !important;
}
body.ts-thirdparty-dashboard .ts-thirdparty-donut {
	width: 330px !important;
	max-width: 100% !important;
	height: 270px !important;
	min-height: 270px !important;
	max-height: 270px !important;
	margin: 0 auto !important;
}
body.ts-thirdparty-dashboard .ts-thirdparty-donut canvas {
	width: 100% !important;
	height: 270px !important;
}
body.ts-thirdparty-dashboard .ts-chart-composition {
	display: grid;
	grid-template-columns: minmax(260px, 1fr) minmax(150px, .62fr);
	align-items: center;
	gap: 20px;
	width: 100%;
}
body.ts-thirdparty-dashboard .ts-chart-legend {
	display: flex;
	flex-direction: column;
	gap: 15px;
	min-width: 0;
}
body.ts-thirdparty-dashboard .ts-chart-legend-item {
	display: grid;
	grid-template-columns: 10px minmax(0, 1fr) auto;
	align-items: center;
	gap: 9px;
	color: #64748b;
	font-size: 13px;
}
body.ts-thirdparty-dashboard .ts-chart-legend-dot {
	width: 10px;
	height: 10px;
	border-radius: 50%;
}
body.ts-thirdparty-dashboard .ts-chart-legend-item strong {
	color: #334155;
	font-weight: 600;
}
body.ts-thirdparty-dashboard .ts-statistics-total-row {
	display: table-row;
}
body.ts-thirdparty-dashboard .ts-statistics-total-row > td {
	height: 60px;
	padding: 0 16px !important;
	border: 0 !important;
	background: #f5f3ff !important;
	vertical-align: middle;
}
body.ts-thirdparty-dashboard .ts-statistics-total-row > td:first-child {
	border-radius: 10px 0 0 10px;
	color: #334155;
	font-size: 15px;
	font-weight: 550;
}
body.ts-thirdparty-dashboard .ts-statistics-total-row > td:last-child {
	border-radius: 0 10px 10px 0;
	color: #4f46e5;
	font-size: 21px;
	font-weight: 700;
}
/* The tile is a deliberate exception to the generic "leading icon in a table
   cell" rule, which sets display:inline-block, width:1.25em and an 8px gap from a
   selector of higher specificity than a plain class. That is why the tile kept
   rendering 23x36 instead of a 36px square however the class was declared: the
   rule was correct and simply never won. Stated here at the specificity of the
   rule it has to override, and scoped to the same td > span:first-child shape so
   it cannot leak onto other icons. */
body.ts-thirdparty-dashboard table td > span.ts-total-icon:first-child,
body.ts-thirdparty-dashboard td > span.ts-total-icon:first-child,
body.ts-thirdparty-dashboard .ts-total-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	min-width: 36px;
	margin-right: 12px;
	border-radius: 9px;
	background: #e9e4ff;
	color: #7047eb;
	font-size: 18px !important;
	line-height: 1 !important;
	vertical-align: middle;
}
body.ts-thirdparty-dashboard .ts-statistics-total-row > td:first-child {
	white-space: nowrap;
}
body.ts-thirdparty-dashboard .ts-stat-mini-grid {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 12px;
	margin-top: 18px;
}
body.ts-thirdparty-dashboard .ts-stat-mini {
	display: flex;
	align-items: center;
	gap: 10px;
	min-width: 0;
	min-height: 76px;
	padding: 12px;
	border: 1px solid #e7e9ee;
	border-radius: 10px;
	background: #fff;
}
body.ts-thirdparty-dashboard .ts-stat-mini-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 30px;
	height: 30px;
	flex: 0 0 30px;
	border-radius: 8px;
	font-size: 15px;
}
body.ts-thirdparty-dashboard .ts-stat-mini-copy {
	display: flex;
	flex-direction: column;
	min-width: 0;
	line-height: 1.25;
}
body.ts-thirdparty-dashboard .ts-stat-mini-label {
	color: #64748b;
	font-size: 12px;
}
body.ts-thirdparty-dashboard .ts-stat-mini strong {
	margin-top: 3px;
	color: #1e293b;
	font-size: 17px;
	font-weight: 700;
}
body.ts-thirdparty-dashboard .ts-stat-mini-1 .ts-stat-mini-icon { background:#f1edff; color:#8453bd; }
body.ts-thirdparty-dashboard .ts-stat-mini-2 .ts-stat-mini-icon { background:#e8f6fb; color:#2694b5; }
body.ts-thirdparty-dashboard .ts-stat-mini-3 .ts-stat-mini-icon { background:#fff1df; color:#e68a14; }
body.ts-thirdparty-dashboard .ts-stat-mini-4 .ts-stat-mini-icon { background:#eaf7ec; color:#47a354; }

body.ts-thirdparty-dashboard .ts-module-dashboard-recent {
	padding-bottom: 0 !important;
}
body.ts-thirdparty-dashboard .ts-module-dashboard-recent .ts-module-dashboard-body {
	margin-top: 18px !important;
	border: 1px solid #e7e9ee !important;
	border-radius: 10px !important;
	overflow: hidden !important;
}
body.ts-thirdparty-dashboard .ts-module-dashboard-recent .ts-recent-columns th {
	height: 46px;
	padding: 0 14px;
	border: 0;
	border-bottom: 1px solid #e7e9ee;
	background: #f8fafc;
	color: #334155;
	font-size: 12px;
	font-weight: 650;
	text-align: left;
}
body.ts-thirdparty-dashboard .ts-module-dashboard-recent .ts-recent-columns th:nth-child(2),
body.ts-thirdparty-dashboard .ts-module-dashboard-recent .ts-recent-columns th:nth-child(4) { text-align: center; }
body.ts-thirdparty-dashboard .ts-recent-thirdparty-row td {
	height: 68px;
	padding: 9px 14px !important;
	border: 0 !important;
	border-bottom: 1px solid #edf0f4 !important;
	background: #fff !important;
	font-size: 13px;
	vertical-align: middle;
}
body.ts-thirdparty-dashboard .ts-module-dashboard-recent .ts-recent-columns th:nth-child(1),
body.ts-thirdparty-dashboard .ts-recent-thirdparty-row td:nth-child(1) { width: 42%; }
body.ts-thirdparty-dashboard .ts-module-dashboard-recent .ts-recent-columns th:nth-child(2),
body.ts-thirdparty-dashboard .ts-recent-thirdparty-row td:nth-child(2) { width: 18%; }
body.ts-thirdparty-dashboard .ts-module-dashboard-recent .ts-recent-columns th:nth-child(3),
body.ts-thirdparty-dashboard .ts-recent-thirdparty-row td:nth-child(3) { width: 24%; }
body.ts-thirdparty-dashboard .ts-module-dashboard-recent .ts-recent-columns th:nth-child(4),
body.ts-thirdparty-dashboard .ts-recent-thirdparty-row td:nth-child(4) { width: 16%; }
body.ts-thirdparty-dashboard .ts-recent-thirdparty-row:last-child td { border-bottom: 0 !important; }
body.ts-thirdparty-dashboard .ts-recent-thirdparty-row:hover td { background: #fafbff !important; }
body.ts-thirdparty-dashboard .ts-recent-thirdparty-row td:first-child a.refurl {
	display: flex;
	align-items: center;
	min-width: 0;
	color: #3543d4;
	font-weight: 550;
	text-decoration: none;
}
body.ts-thirdparty-dashboard .ts-recent-thirdparty-row td:first-child a.refurl > [class*="fa-"] {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 38px;
	height: 38px;
	margin-right: 11px;
	padding: 0 !important;
	flex: 0 0 38px;
	border-radius: 9px;
	background: #f1edff;
	color: #7047eb !important;
	font-size: 16px;
}
body.ts-thirdparty-dashboard .ts-recent-thirdparty-row td:nth-child(2) { text-align: center; }
body.ts-thirdparty-dashboard .ts-recent-thirdparty-row td:nth-child(2) a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 24px;
	padding: 2px 8px;
	border-radius: 999px;
	background: #eaf8ee;
	color: #21864b;
	font-size: 11px;
	font-weight: 650;
	text-decoration: none;
}
body.ts-thirdparty-dashboard .ts-recent-thirdparty-row td:nth-child(3) {
	color: #475569;
	text-align: left !important;
}
body.ts-thirdparty-dashboard .ts-recent-thirdparty-row td:last-child { text-align: center !important; }

/* Shared compact dashboard-table allocation. The entity/name column receives
   the remaining width; short metadata columns retain only the intrinsic space
   they need. This avoids truncating the primary label while a date or status
   column sits mostly empty, and is applied structurally by modern.js across
   module dashboards rather than being tied to Third Parties. */
table.ts-primary-data-table {
	table-layout: auto !important;
}
table.ts-primary-data-table > tbody > tr > :first-child {
	width: 100% !important;
	min-width: 160px;
}
table.ts-primary-data-table > tbody > tr > :not(:first-child) {
	width: 1% !important;
	white-space: nowrap !important;
}
body.ts-thirdparty-dashboard .ts-recent-thirdparty-row .badge-status {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: auto;
	height: 25px;
	min-width: 48px;
	padding: 0 9px;
	border: 1px solid #b9e5c9;
	border-radius: 999px;
	background: #eaf8ee;
	color: #18733d;
	font-size: 11px;
	font-weight: 650;
}
body.ts-thirdparty-dashboard .ts-recent-thirdparty-row .badge-status::after {
	content: attr(aria-label);
}
body.ts-thirdparty-dashboard .ts-recent-thirdparty-row .badge-status::before { display: none !important; }

@media (max-width: 1180px) {
	body.ts-thirdparty-dashboard .ts-thirdparty-dashboard-grid > .twocolumns { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 900px) {
	body.ts-thirdparty-dashboard .fiche { padding: 20px 16px 32px !important; }
	body.ts-thirdparty-dashboard .ts-pagehead { align-items: flex-start; }
	body.ts-thirdparty-dashboard .ts-stat-mini-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 640px) {
	body.ts-thirdparty-dashboard .fiche { padding: 16px 12px 28px !important; }
	body.ts-thirdparty-dashboard .ts-pagehead { flex-wrap: wrap; gap: 14px; }
	body.ts-thirdparty-dashboard .ts-pagehead-title .titre { font-size: 24px !important; }
	body.ts-thirdparty-dashboard .ts-view-all-contacts { width: 100%; }
	body.ts-thirdparty-dashboard .ts-thirdparty-dashboard-grid .ts-module-dashboard-card { padding: 0 14px 16px !important; }
	body.ts-thirdparty-dashboard .ts-module-card-header { min-height: 64px; }
	body.ts-thirdparty-dashboard .ts-thirdparty-donut,
	body.ts-thirdparty-dashboard .ts-thirdparty-donut canvas { width: 100% !important; height: 230px !important; min-height: 230px !important; max-height: 230px !important; }
	body.ts-thirdparty-dashboard .ts-chart-composition { grid-template-columns: minmax(0, 1fr); gap: 8px; }
	body.ts-thirdparty-dashboard .ts-chart-legend { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 18px; padding: 0 8px; }
	body.ts-thirdparty-dashboard .ts-module-dashboard-stats .ts-statistics-chart-row > td { height: 336px; }
	body.ts-thirdparty-dashboard .ts-stat-mini { min-height: 70px; padding: 10px; }
	body.ts-thirdparty-dashboard .ts-module-dashboard-recent .ts-module-dashboard-body { overflow-x: auto !important; }
	body.ts-thirdparty-dashboard .ts-module-dashboard-recent .ts-module-dashboard-table { min-width: 560px; }
}

/* Partnership create/edit form ------------------------------------------
   Exact-route gated by modern.js; existing native controls are re-parented
   into this shared card/grid rather than replaced. */
body.ts-partnership-form-page .fiche {
	max-width: 1320px;
	margin: 0 auto;
	padding: 20px 24px 40px !important;
	background: #f7f8fa;
}
body.ts-partnership-form-page .ts-partnership-native-title,
body.ts-partnership-form-page .ts-partnership-source-table {
	display: none !important;
}
body.ts-partnership-form-page .ts-partnership-breadcrumb {
	display: flex;
	align-items: center;
	gap: 9px;
	margin: 0 0 14px;
	color: #94a3b8;
	font-size: 13px;
}
body.ts-partnership-form-page .ts-partnership-breadcrumb a {
	color: #4f46e5;
	font-weight: 500;
	text-decoration: none;
}
body.ts-partnership-form-page .ts-partnership-breadcrumb a:hover { text-decoration: underline; }
body.ts-partnership-form-page .ts-partnership-breadcrumb [aria-current="page"] { color: #64748b; }
body.ts-partnership-form-page .ts-partnership-title {
	margin: 0 0 18px;
	color: #111827;
	font-size: 28px;
	font-weight: 700;
	line-height: 1.2;
}
body.ts-partnership-form-page .ts-partnership-info {
	display: flex;
	align-items: center;
	gap: 12px;
	min-height: 50px;
	margin: 0 0 24px;
	padding: 10px 16px;
	border: 1px solid #cfd4ff;
	border-radius: 9px;
	background: #f5f3ff;
	color: #475569;
	font-size: 13px;
	line-height: 1.45;
}
body.ts-partnership-form-page .ts-partnership-info > [class*="fa-"] {
	color: #5b4cf0;
	font-size: 19px;
}
body.ts-partnership-form-page .ts-partnership-card {
	margin: 0 !important;
	padding: 24px !important;
	border: 1px solid #e7e9ee !important;
	border-radius: 12px !important;
	background: #fff !important;
	box-shadow: 0 5px 18px rgba(15, 23, 42, .045) !important;
	overflow: visible !important;
}
body.ts-partnership-form-page .ts-partnership-card-title {
	margin: 0 0 24px;
	color: #1e293b;
	font-size: 18px;
	font-weight: 650;
	line-height: 1.35;
}
body.ts-partnership-form-page .ts-partnership-field-grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 24px 28px;
}
body.ts-partnership-form-page .ts-partnership-field {
	display: flex;
	flex-direction: column;
	min-width: 0;
}
body.ts-partnership-form-page .ts-partnership-label {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 10px;
	min-height: 20px;
	margin: 0 0 8px;
	color: #1e293b;
	font-size: 13px;
	font-weight: 600;
}
body.ts-partnership-form-page .ts-partnership-label label { font: inherit; color: inherit; }
body.ts-partnership-form-page .ts-partnership-required .ts-partnership-label label::after {
	margin-left: 6px;
	color: #dc2626;
	content: "*";
}
body.ts-partnership-form-page .ts-partnership-control {
	display: flex;
	align-items: center;
	gap: 8px;
	min-width: 0;
}
body.ts-partnership-form-page .ts-partnership-control > select,
body.ts-partnership-form-page .ts-partnership-control > .select2-container {
	width: 100% !important;
	max-width: none !important;
	min-width: 0 !important;
}
body.ts-partnership-form-page .ts-partnership-control > [class*="fa-building"] {
	display: none !important;
}
body.ts-partnership-form-page .ts-partnership-control .select2-selection,
body.ts-partnership-form-page .ts-partnership-control .select2-selection--single {
	height: 46px !important;
	min-height: 46px !important;
	border: 1px solid #dbe2ec !important;
	border-radius: 8px !important;
	background: #fff !important;
	box-shadow: none !important;
}
body.ts-partnership-form-page .ts-partnership-control .select2-selection__rendered {
	height: 44px !important;
	padding: 0 42px 0 14px !important;
	color: #334155 !important;
	font-size: 13px !important;
	line-height: 44px !important;
}
body.ts-partnership-form-page .ts-partnership-control .select2-selection__arrow {
	top: 0 !important;
	right: 10px !important;
	height: 44px !important;
}
body.ts-partnership-form-page .ts-partnership-control .select2-selection:focus,
body.ts-partnership-form-page .ts-partnership-control .select2-selection[aria-expanded="true"] {
	border-color: #8b7cf6 !important;
	box-shadow: 0 0 0 3px rgba(91, 76, 240, .12) !important;
	outline: 0 !important;
}
body.ts-partnership-form-page .ts-partnership-related-create {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 26px;
	height: 26px;
	min-width: 26px;
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: 6px;
	background: #f5f3ff;
	color: #4f46e5;
	position: absolute;
	top: -3px;
	right: 0;
}
body.ts-partnership-form-page .ts-partnership-date-field .ts-partnership-control {
	position: relative;
	display: block;
}
body.ts-partnership-form-page .ts-partnership-date-field .divfordateinput {
	position: relative;
	display: block !important;
	width: 100%;
}
body.ts-partnership-form-page .ts-partnership-date-field input.hasDatepicker {
	width: 100% !important;
	height: 46px !important;
	max-width: none !important;
	padding: 0 44px 0 14px !important;
	border: 1px solid #dbe2ec !important;
	border-radius: 8px !important;
	background: #fff !important;
	color: #334155;
	font-size: 13px;
	text-align: left !important;
	box-shadow: none !important;
}
body.ts-partnership-form-page .ts-partnership-date-field input.hasDatepicker:focus {
	border-color: #8b7cf6 !important;
	box-shadow: 0 0 0 3px rgba(91, 76, 240, .12) !important;
	outline: 0;
}
body.ts-partnership-form-page .ts-partnership-date-field .ui-datepicker-trigger {
	position: absolute;
	top: 50%;
	right: 13px;
	width: 19px !important;
	height: 19px !important;
	margin: 0 !important;
	transform: translateY(-50%);
	cursor: pointer;
	opacity: .68;
}
body.ts-partnership-form-page .ts-partnership-today {
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	height: 26px;
	min-width: 48px;
	padding: 0 8px;
	border: 0;
	border-radius: 7px;
	background: transparent;
	color: #4f46e5;
	font-size: 12px;
	font-weight: 600;
	cursor: pointer;
	position: absolute;
	top: -3px;
	right: 0;
}
body.ts-partnership-form-page .ts-partnership-today:hover { background: #f5f3ff; }
body.ts-partnership-form-page .ts-partnership-help {
	margin: 8px 0 0;
	color: #64748b;
	font-size: 12px;
	line-height: 1.4;
}
body.ts-partnership-form-page .ts-partnership-actions {
	display: flex;
	align-items: center;
	justify-content: flex-end;
	gap: 12px;
	margin: 30px 0 0 !important;
	padding: 22px 0 0;
	border-top: 1px solid #e7e9ee;
	text-align: right !important;
}
body.ts-partnership-form-page .ts-partnership-actions input.button {
	height: 44px !important;
	min-height: 44px !important;
	margin: 0 !important;
	padding: 0 22px !important;
	border-radius: 8px !important;
	font-size: 13px !important;
	font-weight: 650 !important;
}
body.ts-partnership-form-page .ts-partnership-actions input[name="cancel"] {
	min-width: 128px;
	border: 1px solid #dbe2ec !important;
	background: #fff !important;
	color: #334155 !important;
}
body.ts-partnership-form-page .ts-partnership-actions input[name="add"],
body.ts-partnership-form-page .ts-partnership-actions input[name="save"] {
	min-width: 205px;
	border: 1px solid var(--c-btn-action) !important;
	background: var(--c-btn-action) !important;
	color: var(--c-btn-action-text) !important;
}
body.ts-partnership-form-page .select2-dropdown.ts-partnership-select-dropdown {
	border: 1px solid #dbe2ec !important;
	border-radius: 9px !important;
	background: #fff !important;
	box-shadow: 0 12px 28px rgba(15, 23, 42, .14) !important;
	overflow: hidden;
}
body.ts-partnership-form-page .ts-partnership-select-dropdown .select2-search__field {
	height: 38px;
	padding: 0 12px !important;
	border: 1px solid #dbe2ec !important;
	border-radius: 7px !important;
	outline: 0;
}
body.ts-partnership-form-page .ts-partnership-compact-dropdown .select2-search { display: none !important; }
body.ts-partnership-form-page .ts-partnership-select-dropdown .select2-results__option {
	min-height: 38px;
	padding: 9px 12px !important;
	font-size: 13px;
}
body.ts-partnership-form-page .ts-partnership-select-dropdown .select2-results__option[aria-selected="true"],
body.ts-partnership-form-page .ts-partnership-select-dropdown .select2-results__option--highlighted {
	background: #f1efff !important;
	color: #4338ca !important;
}

/* Shared COMMAND create/edit form surfaces -------------------------------
   JS marks only a top-level create/edit form with a real field table and submit
   controls. Specialized module adapters opt out before these rules apply. */
body.ts-command-form-page .fiche {
	max-width: 1320px;
	margin: 0 auto;
	padding: 22px 24px 42px !important;
}
body.ts-command-form-page .fiche > table.table-fiche-title,
body.ts-command-form-page .fiche > div > table.table-fiche-title {
	margin: 0 0 16px !important;
	padding: 0 !important;
	border: 0 !important;
	border-radius: 0 !important;
	background: transparent !important;
	box-shadow: none !important;
}
body.ts-command-form-page .fiche div.titre {
	font-size: 26px;
	font-weight: 680;
	line-height: 1.25;
}
body.ts-command-form-page .ts-command-form {
	margin: 0 !important;
	padding: 24px !important;
	border: 1px solid #e7e9ee;
	border-radius: 12px;
	background: #fff;
	box-shadow: 0 5px 18px rgba(15, 23, 42, .045);
}

/* Shared record normalization. The node movement is generic and only activates
   after Dolibarr exposes both its native entity banner and native tabs. This
   keeps dense action sets inside the card without changing their links or order. */
body.ts-command-record-page div.tabBar.ts-entity-card > div.arearef.ts-has-actions {
	display: flex;
	align-items: center;
	gap: 16px;
	min-width: 0;
}
body.ts-command-record-page div.tabBar.ts-entity-card > div.arearefnobottom,
body.ts-command-record-page div.tabBar.ts-entity-card > div.arearefnoborder,
body.ts-command-record-page div.tabBar.ts-entity-card > div.arearef {
	display: flex;
	align-items: center;
	gap: 16px;
	min-height: 104px;
	padding: 20px 24px !important;
	border: 0 !important;
	background: #fff !important;
	box-sizing: border-box;
}
body.ts-command-record-page div.tabBar.ts-entity-card > div.arearefnobottom > div:first-child,
body.ts-command-record-page div.tabBar.ts-entity-card > div.arearefnoborder > div:first-child,
body.ts-command-record-page div.tabBar.ts-entity-card > div.arearef > div:first-child {
	flex: 1 1 auto;
	min-width: 0;
}
body.ts-command-record-page div.tabBar.ts-entity-card > div.arearef .divphotoref,
body.ts-command-record-page div.tabBar.ts-entity-card > div.arearefnobottom .divphotoref,
body.ts-command-record-page div.tabBar.ts-entity-card > div.arearefnoborder .divphotoref {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 56px;
	height: 56px;
	margin-right: 16px;
	border-radius: 10px;
	background: #f0edff;
	color: #5846e8;
}
/* A record with no photo of its own shows a placeholder, which carries its own
   tile: a sunken fill and a dashed border marking the empty slot. In a banner
   that slot is already a tile, so the two stacked -- a pale box sitting on the
   card's own -- and the placeholder's 80px outgrew the 56px tile it sat in.
   Here the placeholder is only its glyph. */
body.ts-command-record-page div.tabBar.ts-entity-card .divphotoref img[src*="user_anonymous"],
body.ts-command-record-page div.tabBar.ts-entity-card .divphotoref img[src*="user_man"],
body.ts-command-record-page div.tabBar.ts-entity-card .divphotoref img[src*="user_woman"] {
	width: 34px !important;
	height: 34px !important;
	background: none !important;
	border: 0 !important;
	border-radius: 0 !important;
}

body.ts-command-record-page div.tabBar.ts-entity-card > div.arearef .refid,
body.ts-command-record-page div.tabBar.ts-entity-card > div.arearefnobottom .refid,
body.ts-command-record-page div.tabBar.ts-entity-card > div.arearefnoborder .refid {
	display: inline-grid;
	grid-template-columns: auto auto;
	align-items: center;
	column-gap: 10px;
	row-gap: 5px;
	min-width: 0;
	font-size: 24px;
	font-weight: 680;
}
body.ts-command-record-page div.tabBar.ts-entity-card > div.arearef .refid > .refidno,
body.ts-command-record-page div.tabBar.ts-entity-card > div.arearefnobottom .refid > .refidno,
body.ts-command-record-page div.tabBar.ts-entity-card > div.arearefnoborder .refid > .refidno {
	grid-column: 1 / -1;
	font-size: 13px;
	font-weight: 400;
	line-height: 1.55;
}
body.ts-command-record-page div.tabBar.ts-entity-card > div.arearef .refid > .statusref,
body.ts-command-record-page div.tabBar.ts-entity-card > div.arearefnobottom .refid > .statusref,
body.ts-command-record-page div.tabBar.ts-entity-card > div.arearefnoborder .refid > .statusref {
	grid-column: 2;
	grid-row: 1;
	margin: 0;
}
body.ts-command-record-page div.tabBar.ts-entity-card > div.arearef .paginationref,
body.ts-command-record-page div.tabBar.ts-entity-card > div.arearefnobottom .paginationref,
body.ts-command-record-page div.tabBar.ts-entity-card > div.arearefnoborder .paginationref {
	position: static !important;
	flex: 0 0 auto;
	float: none !important;
	margin-left: auto;
}
body.ts-command-record-page div.tabBar.ts-entity-card > div.arearef.ts-has-actions > .refid,
body.ts-command-record-page div.tabBar.ts-entity-card > div.arearef.ts-has-actions > .ts-entity-identity {
	flex: 1 1 320px;
	min-width: 0;
}
body.ts-command-record-page .ts-header-actions {
	flex: 1 1 480px;
	min-width: 0;
}
body.ts-command-record-page div.tabs[data-ts-placed="1"] {
	display: flex;
	flex-wrap: nowrap;
	overflow-x: auto;
	overflow-y: hidden;
	scrollbar-width: thin;
}
body.ts-command-record-page div.tabs[data-ts-placed="1"] > a.tab {
	flex: 0 0 auto;
}
body.ts-command-record-page div.tabs[data-ts-placed="1"] {
	min-height: 52px;
	align-items: center;
	border-top: 1px solid #eef0f4 !important;
}
body.ts-command-record-page div.tabs[data-ts-placed="1"] .tabsElem,
body.ts-command-record-page div.tabs[data-ts-placed="1"] .tab { min-height: 50px; }
body.ts-command-record-page div.tabs[data-ts-placed="1"] a.tab {
	display: inline-flex !important;
	align-items: center;
	height: 50px;
	padding-inline: 14px !important;
}
body.ts-command-record-page div.fichehalfleft,
body.ts-command-record-page div.fichehalfright {
	padding: 14px 16px;
}
body.ts-command-record-page div.fichehalfleft table td,
body.ts-command-record-page div.fichehalfright table td {
	padding-top: 10px;
	padding-bottom: 10px;
	border-bottom-color: #f1f3f6 !important;
}
body.ts-command-record-secondary .ts-record-tab-native-surface {
	margin: 16px 0 0 !important;
	border: 1px solid #e7e9ee !important;
	border-radius: 12px !important;
	background: #fff !important;
	box-shadow: 0 4px 14px rgba(15, 23, 42, .04) !important;
	overflow: auto;
}
body.ts-command-record-secondary form.ts-record-tab-native-surface { padding: 16px; }
body.ts-command-record-secondary .ts-record-tab-native-surface table { margin: 0 !important; box-shadow: none !important; }
body.ts-command-record-secondary .ts-record-tab-native-surface table td,
body.ts-command-record-secondary .ts-record-tab-native-surface table th {
	padding: 10px 12px !important;
	border-color: #f0f2f5 !important;
}
body.ts-command-record-secondary .ts-record-tab-native-surface tr.liste_titre td,
body.ts-command-record-secondary .ts-record-tab-native-surface tr.liste_titre th {
	height: 44px;
	background: #f7f9fc !important;
	font-size: 12px;
	font-weight: 650;
}

/* Auxiliary Third Party tabs share one calm context summary instead of leaving
   their record fields as loose rows on the application canvas. */
body.ts-command-record-secondary .ts-record-context-summary {
	margin-top: 16px;
	padding: 8px 20px;
	border: 1px solid var(--c-border);
	border-radius: 12px;
	background: var(--c-surface);
	box-shadow: var(--sh-sm);
}
body.ts-command-record-secondary .ts-record-context-summary table { margin: 0 !important; box-shadow: none !important; }
body.ts-command-record-secondary .ts-record-context-summary td {
	height: 38px;
	padding: 7px 10px !important;
	border-bottom: 0 !important;
}
body.ts-command-record-secondary .ts-record-context-summary td.titlefield { width: 230px; font-weight: 600; }

/* Warehouse activity tabs emit plain text metadata rather than a fiche table.
   Give that compact log the same independent summary-card language as other
   record tabs, while keeping the original user link in place. */
body.page-stock_info .ts-warehouse-log-summary {
	max-width: 920px;
	margin: 16px 0 0 !important;
}
body.page-stock_info .ts-warehouse-log-card {
	padding: 20px 22px;
	border: 1px solid var(--c-border);
	border-radius: var(--r-lg);
	background: var(--c-surface);
	box-shadow: var(--sh-sm);
}
body.page-stock_info .ts-warehouse-log-title {
	display: flex;
	align-items: center;
	gap: 9px;
	margin: 0 0 16px;
	font-size: 1rem;
	font-weight: 650;
	color: var(--c-ink);
}
body.page-stock_info .ts-warehouse-log-title .fas { color: var(--c-accent); }
body.page-stock_info .ts-warehouse-log-grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 12px;
}
body.page-stock_info .ts-warehouse-log-item {
	display: grid;
	grid-template-columns: 36px minmax(0, 1fr);
	align-items: center;
	gap: 10px;
	min-height: 58px;
	padding: 10px 12px;
	border: 1px solid var(--c-hairline);
	border-radius: var(--r);
	background: var(--c-surface);
}
body.page-stock_info .ts-warehouse-log-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	border-radius: 9px;
	background: var(--c-accent-soft);
	color: var(--c-accent);
}
body.page-stock_info .ts-warehouse-log-label {
	display: block;
	margin-bottom: 3px;
	font-size: .75rem;
	font-weight: 600;
	color: var(--c-muted);
}
body.page-stock_info .ts-warehouse-log-value {
	min-width: 0;
	font-size: .8125rem;
	font-weight: 550;
	line-height: 1.35;
	color: var(--c-ink-2);
	word-break: break-word;
}
body.page-stock_info .ts-warehouse-log-value .userimg img {
	width: 26px !important;
	height: 26px !important;
	margin-right: 6px;
	border-radius: 50%;
	vertical-align: middle;
}

/* Product price tabs are detail summary + a native price list.  The native
   page uses bare sibling tables, so retain their forms/links and provide the
   shared record-tab surfaces at the container level. */
body.page-price_suppliers .ts-entity-card .divphotoref + .divphotoref:empty { display: none !important; }
body.page-price_suppliers .ts-product-price-summary {
	max-width: none;
	margin: 16px 0 20px !important;
}
body.page-price_suppliers .ts-product-price-details {
	width: 100%;
	margin: 0 !important;
	border: 1px solid var(--c-hairline) !important;
	border-radius: var(--r-lg);
	border-collapse: separate;
	border-spacing: 0;
	background: var(--c-surface);
	box-shadow: var(--sh-sm);
	overflow: hidden;
}
body.page-price_suppliers .ts-product-price-details > tbody > tr > td {
	padding: 13px 18px !important;
	border: 0 !important;
	border-bottom: 1px solid var(--c-hairline) !important;
	background: transparent !important;
	font-size: .8125rem;
	vertical-align: middle;
}
body.page-price_suppliers .ts-product-price-details > tbody > tr:last-child > td { border-bottom: 0 !important; }
body.page-price_suppliers .ts-product-price-details > tbody > tr > td:first-child {
	width: 42%;
	font-weight: 600;
	color: var(--c-ink-2);
}
body.page-price_suppliers .ts-product-price-details table { background: transparent !important; }
body.page-price_suppliers .ts-product-price-details table td { padding: 0 !important; border: 0 !important; }
body.page-price_suppliers .ts-product-price-list-card {
	margin: 0;
	border: 1px solid var(--c-hairline);
	border-radius: var(--r-lg);
	background: var(--c-surface);
	box-shadow: var(--sh-sm);
	overflow: hidden;
}
body.page-price_suppliers .ts-product-price-list-card > .ts-pagehead {
	min-height: 64px;
	margin: 0 !important;
	padding: 0 20px;
	border-bottom: 1px solid var(--c-hairline);
	background: transparent;
}
body.page-price_suppliers .ts-product-price-list-card > .ts-pagehead .titre {
	font-size: 1.125rem !important;
	font-weight: 650;
}
body.page-price_suppliers .ts-product-price-list-card > form { margin: 0 !important; }
body.page-price_suppliers .ts-product-price-list-card table.liste {
	margin: 0 !important;
	border: 0 !important;
	box-shadow: none !important;
}

/* Stock-card summary data lives inside the tab card, while the stock table
   heading follows it as a fiche sibling. Reserve the normal record-section gap
   so its title/action row never touches the summary or tab strip. */
body.page-stock_card .fiche > .ts-pagehead {
	margin-top: 20px !important;
	margin-bottom: 20px !important;
}
@media only screen and (max-width: 700px) {
	body.page-price_suppliers .ts-product-price-summary { margin: 12px 0 16px !important; }
	body.page-price_suppliers .ts-product-price-details > tbody > tr > td { padding: 11px 12px !important; }
	body.page-price_suppliers .ts-product-price-list-card > .ts-pagehead { padding: 0 14px; }
	body.page-stock_card .fiche > .ts-pagehead { margin-top: 16px !important; margin-bottom: 16px !important; }
}
@media only screen and (max-width: 900px) {
	body.page-stock_info .ts-warehouse-log-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media only screen and (max-width: 600px) {
	body.page-stock_info .ts-warehouse-log-summary { margin-top: 12px !important; }
	body.page-stock_info .ts-warehouse-log-card { padding: 16px; }
	body.page-stock_info .ts-warehouse-log-grid { grid-template-columns: 1fr; }
}
body.ts-thirdparty-notes-tab .ts-notes-card {
	display: grid;
	gap: 0;
	margin-top: 16px;
	padding: 4px 20px;
	border: 1px solid var(--c-border) !important;
	border-radius: 12px;
	background: var(--c-surface);
	box-shadow: var(--sh-sm);
}
body.ts-thirdparty-notes-tab .ts-notes-card .tagtr {
	display: grid;
	grid-template-columns: minmax(180px, 260px) minmax(0, 1fr);
	min-height: 72px;
	align-items: start;
	padding: 16px 0;
	border-bottom: 1px solid var(--c-hairline);
}
body.ts-thirdparty-notes-tab .ts-notes-card .tagtr:last-child { border-bottom: 0; }
body.ts-thirdparty-notes-tab .ts-notes-card .tagtd { width: auto !important; padding: 0 12px !important; border: 0 !important; }
body.ts-thirdparty-notes-tab .ts-notes-card .editfielda {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	border-radius: 8px;
}
body.ts-thirdparty-margins-tab .ts-margin-card { margin-top: 16px !important; }
body.ts-thirdparty-margins-tab .ts-margin-card .ts-pagehead { margin-bottom: 14px; }
body.ts-thirdparty-margins-tab .ts-margin-card .ts-pagehead .titre { font-size: 22px; }
body.ts-thirdparty-margins-tab .ts-margin-card .div-table-responsive {
	border: 1px solid var(--c-border);
	border-radius: 10px;
	overflow: auto;
}
body.ts-thirdparty-documents-tab .ts-documents-heading { margin-top: 16px !important; }
body.ts-thirdparty-documents-tab .ts-documents-card {
	margin-top: 12px !important;
	border: 1px solid var(--c-border) !important;
	border-radius: 12px !important;
	background: var(--c-surface) !important;
	box-shadow: var(--sh-sm) !important;
	overflow: hidden;
}
body.ts-thirdparty-documents-tab .ts-documents-card table { margin: 0 !important; box-shadow: none !important; }
body.ts-thirdparty-documents-tab .ts-documents-card td[colspan] { min-height: 120px; }
body.ts-thirdparty-documents-tab table.ts-documents-heading {
	padding: 0 12px;
	border: 1px solid var(--c-border) !important;
	border-radius: 12px;
	background: var(--c-surface);
}

body.ts-thirdparty-customer-tab .ts-customer-overview-grid {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	/* Independent record columns must retain their intrinsic height.  The default
	   grid stretch makes a short activity stack look like an empty white slab
	   whenever the detail panel beside it happens to be taller. */
	align-items: start;
	gap: 16px;
	margin-top: 16px;
	padding: 0 !important;
	border: 0 !important;
	background: transparent !important;
	box-shadow: none !important;
}
body.ts-thirdparty-customer-tab .ts-customer-overview-card {
	align-self: start;
	width: auto !important;
	margin: 0 !important;
	padding: 20px !important;
	border: 1px solid var(--c-border);
	border-radius: 12px;
	background: var(--c-surface);
	box-shadow: var(--sh-sm);
}
body.ts-thirdparty-customer-tab .ts-customer-overview-card table { margin: 0 !important; box-shadow: none !important; }
body.ts-thirdparty-customer-tab .ts-customer-overview-card table.tableforfield td {
	height: 42px;
	padding: 8px 10px !important;
	border-bottom: 1px solid var(--c-hairline) !important;
}
body.ts-thirdparty-customer-tab .ts-customer-overview-card table.tableforfield tr:last-child td { border-bottom: 0 !important; }
body.ts-thirdparty-customer-tab .ts-customer-overview-card table.tableforfield td:first-child { width: 46%; font-weight: 600; }
body.ts-thirdparty-customer-tab .ts-customer-overview-card table.tableforfield > tbody > tr > td:first-child > table.nobordernopadding {
	display: block !important;
	width: 100% !important;
}
body.ts-thirdparty-customer-tab .ts-customer-overview-card table.tableforfield > tbody > tr > td:first-child > table.nobordernopadding > tbody,
body.ts-thirdparty-customer-tab .ts-customer-overview-card table.tableforfield > tbody > tr > td:first-child > table.nobordernopadding > tbody > tr {
	display: contents !important;
}
body.ts-thirdparty-customer-tab .ts-customer-overview-card table.tableforfield > tbody > tr > td:first-child > table.nobordernopadding td {
	height: auto !important;
	min-height: 0 !important;
	padding: 0 !important;
	border: 0 !important;
}
body.ts-thirdparty-customer-tab .ts-customer-overview-card table.tableforfield > tbody > tr > td:first-child > table.nobordernopadding td:first-child {
	display: inline !important;
	width: auto !important;
}
body.ts-thirdparty-customer-tab .ts-customer-overview-card table.tableforfield > tbody > tr > td:first-child > table.nobordernopadding td.right {
	display: inline-flex !important;
	float: right;
	align-items: center;
	justify-content: flex-end;
	width: 30px !important;
}
body.ts-thirdparty-customer-tab .ts-customer-overview-card .fichecenter,
body.ts-thirdparty-customer-tab .ts-customer-overview-card .fichehalfleft,
body.ts-thirdparty-customer-tab .ts-customer-overview-card .fichehalfright { width: auto !important; margin: 0 !important; padding: 0 !important; }
body.ts-thirdparty-customer-tab .ts-customer-actions {
	display: flex;
	align-items: center;
	justify-content: flex-end;
	flex-wrap: wrap;
	gap: 8px;
	margin: 16px 0 0 !important;
	padding: 16px;
	border: 1px solid var(--c-border);
	border-radius: 12px;
	background: var(--c-surface);
	box-shadow: var(--sh-sm);
}
body.ts-thirdparty-customer-tab .ts-customer-actions .butAction {
	min-height: 38px;
	margin: 0 !important;
	padding: 0 14px !important;
	border-radius: 8px !important;
	font-size: 12px;
}
@media (max-width: 900px) {
	body.ts-thirdparty-customer-tab .ts-customer-overview-grid { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 640px) {
	body.ts-thirdparty-customer-tab .ts-customer-overview-card { padding: 12px !important; }
	body.ts-thirdparty-customer-tab .ts-customer-overview-card table.tableforfield tr {
		display: grid !important;
		grid-template-columns: minmax(130px, 42%) minmax(0, 1fr);
		align-items: center;
	}
	body.ts-thirdparty-customer-tab .ts-customer-overview-card table.tableforfield td,
	body.ts-thirdparty-customer-tab .ts-customer-overview-card table.tableforfield td:first-child {
		display: flex !important;
		align-items: center;
		width: auto !important;
		min-height: 42px !important;
		padding: 7px 8px !important;
	}
	body.ts-thirdparty-customer-tab .ts-customer-actions { justify-content: stretch; padding: 12px; }
	body.ts-thirdparty-customer-tab .ts-customer-actions .butAction { flex: 1 1 180px; text-align: center; }
}

/* Title glyphs occupy a deliberate tile rather than colliding with text. */
.fiche > table.table-fiche-title.ts-command-title-with-icon { margin-bottom: 16px !important; }
.fiche > table.table-fiche-title.ts-command-title-with-icon td.col-picto {
	width: 44px !important;
	min-width: 44px !important;
	padding: 0 !important;
	vertical-align: middle;
}
.fiche > table.table-fiche-title.ts-command-title-with-icon td.col-picto .pictotitle {
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	width: 36px !important;
	height: 36px;
	margin: 0 8px 0 0 !important;
	border-radius: 9px;
	background: var(--c-accent-soft);
	color: var(--c-accent) !important;
	font-size: 16px !important;
}
.fiche > table.table-fiche-title.ts-command-title-with-icon td.col-title { padding-left: 8px !important; }
.fiche > table.table-fiche-title.ts-command-title-with-icon .titre { line-height: 1.2; }
@media (max-width: 900px) {
	body.ts-command-record-page div.tabBar.ts-entity-card > div.arearef.ts-has-actions { align-items: flex-start; }
	body.ts-command-record-page .ts-header-actions { flex-basis: 100%; max-width: 100%; }
}
@media (max-width: 640px) {
	body.ts-command-record-page .ts-header-actions div.tabsAction {
		justify-content: flex-start;
		width: 100%;
	}
	body.ts-command-record-page .ts-header-actions div.tabsAction > a,
	body.ts-command-record-page .ts-header-actions div.tabsAction > button,
	body.ts-command-record-page .ts-header-actions div.tabsAction > input,
	body.ts-command-record-page .ts-header-actions div.tabsAction > .inline-block {
		max-width: 100%;
	}
}

/* Shared module landing dashboards -------------------------------------- */
body.ts-command-module-index .fiche { padding: 28px 32px 48px !important; }
body.ts-command-module-index .fiche > table.table-fiche-title {
	margin-bottom: 8px !important;
	border: 0 !important;
	background: transparent !important;
	box-shadow: none !important;
}
body.ts-command-module-index .fiche > table.table-fiche-title .titre,
body.ts-command-module-index .ts-pagehead .titre { font-size: 26px; font-weight: 680; }
body.ts-command-module-index .ts-pagehead {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 5px;
	margin-bottom: 22px;
}
body.ts-command-module-index .ts-module-index-subtitle {
	color: var(--c-muted);
	font-size: 14px;
	line-height: 1.45;
}
body.ts-command-module-index .fiche > .opacitymedium { display: block; margin-bottom: 20px; font-size: 14px; }
body.ts-command-module-index .ts-module-index-grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 16px;
	align-items: start;
}
body.ts-command-module-index .ts-module-index-column > .div-table-responsive,
body.ts-command-module-index .ts-module-index-column > .div-table-responsive-no-min { min-width: 0; overflow: visible; }
body.ts-products-module-index .ts-module-index-grid { grid-template-columns: minmax(0, .95fr) minmax(0, 1.05fr); }
body.ts-products-module-index .ts-module-index-card td.center:has(.dolgraph) { padding: 16px !important; }
body.ts-products-module-index .ts-module-index-card .dolgraph { margin-inline: auto; }
body.ts-products-module-index .ts-module-index-column:first-child { align-content: start; }
body.ts-products-module-index .ts-module-index-column:first-child .ts-module-index-card { min-height: 360px; }
body.ts-shipments-module-index .ts-module-index-grid { grid-template-columns: minmax(280px, .72fr) minmax(0, 1.28fr); }
body.ts-shipments-module-index .ts-module-index-column > br { display: none; }
body.ts-shipments-module-index .ts-module-index-column .div-table-responsive-no-min,
body.ts-shipments-module-index .ts-module-index-column .div-table-responsive { margin: 0; }

/* Shipment statistics: keep the real form/chart, but present them as two aligned
   dashboard panels instead of one oversized legacy tab sheet. */
body.ts-shipment-statistics .fiche > .tabs { margin-top: 12px; }
body.ts-shipment-statistics .fiche > .tabBar {
	margin-top: 12px;
	padding: 20px;
	border: 1px solid var(--c-border);
	border-radius: 12px;
	background: var(--c-surface);
	box-shadow: var(--sh-sm);
}
body.ts-shipment-statistics .fiche > .tabBar > .fichecenter {
	display: grid;
	grid-template-columns: minmax(300px, .8fr) minmax(0, 1.2fr);
	gap: 24px;
	align-items: start;
}
body.ts-shipment-statistics .ts-statistics-column { width: auto !important; margin: 0 !important; padding: 0 !important; }
body.ts-shipment-statistics .ts-statistics-column table {
	margin: 0 !important;
	border: 1px solid var(--c-border);
	border-radius: 10px;
	background: var(--c-surface);
	box-shadow: none !important;
	overflow: hidden;
}
body.ts-shipment-statistics .ts-statistics-column td { padding: 10px 14px !important; }
body.ts-shipment-statistics .ts-statistics-column tr.liste_titre td { height: 44px; background: var(--c-sunken) !important; }
body.ts-shipment-statistics .ts-statistics-column select,
body.ts-shipment-statistics .ts-statistics-column .select2-container { max-width: 100% !important; }
body.ts-shipment-statistics .ts-statistics-column .dolgraph { margin-inline: auto; }
@media (max-width: 900px) {
	body.ts-shipment-statistics .fiche > .tabBar > .fichecenter { grid-template-columns: minmax(0, 1fr); }
	body.ts-shipments-module-index .ts-module-index-grid,
	body.ts-products-module-index .ts-module-index-grid { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 640px) {
	body.ts-thirdparty-notes-tab .ts-notes-card .tagtr { grid-template-columns: minmax(0, 1fr); gap: 10px; }
	body.ts-command-record-secondary .ts-record-context-summary td.titlefield { width: 46%; }
	.fiche > table.table-fiche-title.ts-command-title-with-icon td.col-picto { width: 40px !important; min-width: 40px !important; }
}
body.ts-command-module-index .ts-module-index-column {
	display: grid;
	gap: 16px;
	width: auto !important;
	margin: 0 !important;
	padding: 0 !important;
	border: 0;
	background: transparent;
	box-shadow: none;
}
body.ts-command-module-index .ts-module-index-empty { display: none; }
body.ts-command-module-index .ts-module-index-card {
	width: 100%;
	margin: 0 !important;
	border: 1px solid #e7e9ee !important;
	border-radius: 12px !important;
	background: #fff !important;
	box-shadow: 0 4px 14px rgba(15, 23, 42, .04) !important;
	overflow: hidden;
	table-layout: auto !important;
}
body.ts-command-module-index .ts-module-index-data-card { table-layout: fixed !important; }
/* Empty widgets have no data cells from which the column measuring pass can
   derive widths. Let their real headings size the columns instead of applying
   a fixed/even split that reduces long titles and labels to fragments. */
body.ts-command-module-index .ts-module-index-data-card:has(.ts-command-empty-state),
body.ts-command-module-index .ts-module-index-data-card:has(.ts-module-index-empty-row) {
	table-layout: auto !important;
}
/* Compact three-column transaction widgets (proposals/orders) size more
   reliably from their reference, customer and amount content. A fixed table
   lets the colspan heading influence the column algorithm and collapses each
   cell to a few pixels. */
body.ts-command-module-index .ts-module-index-data-card.ts-module-index-cols-3 { table-layout: auto !important; }
/* Those three-column widgets size from their content, and a cell that will not
   break a line is as wide as its longest value -- so one long name made the
   table wider than the card holding it and it spilled over the column beside
   it. Giving every cell the same preferred width shares the card between the
   three columns instead of letting the longest value dictate: a reference, an
   amount or a date is comfortably inside its share, and a long name ends in an
   ellipsis. A cap alone is not enough -- with nothing to hold it open, the
   column that can shrink collapses to the ellipsis and nothing else. */
body.ts-command-module-index .ts-module-index-data-card.ts-module-index-cols-3 {
	max-width: 100%;
}
body.ts-command-module-index .ts-module-index-data-card.ts-module-index-cols-3 > tbody > tr:not(.liste_titre) > td {
	width: 190px !important;
	max-width: 190px !important;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}
/* The cell truncates its own line. Its contents are left inline so that they
   form one line for it to truncate -- as inline-blocks each would be measured
   and clipped separately, and a cell holding a picto beside a name ended up
   showing the picto and an ellipsis with the name nowhere. */
body.ts-command-module-index .ts-module-index-data-card.ts-module-index-cols-3 > tbody > tr:not(.liste_titre) > td > a,
body.ts-command-module-index .ts-module-index-data-card.ts-module-index-cols-3 > tbody > tr:not(.liste_titre) > td > span {
	display: inline !important;
	max-width: none !important;
	overflow: visible !important;
}

/* Scoped to the card's own rows. A reference cell holds a nested table of its
   own -- Dolibarr's picto-and-ref layout -- whose row is not a heading row, so an
   unscoped rule reached into it and applied the zero max-width meant for the
   card's cells. The inner cells collapsed and the reference showed as an
   ellipsis, while the cell around it was the full width all along. */
body.ts-command-module-index .ts-module-index-data-card > tbody > tr:not(.liste_titre) > td {
	max-width: none !important;
	min-width: 0 !important;
	box-sizing: border-box;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}
body.ts-command-module-index .ts-module-index-card tr.liste_titre > th,
body.ts-command-module-index .ts-module-index-card tr.liste_titre > td {
	display: table-cell !important;
	width: auto !important;
	min-width: 0 !important;
	height: auto;
	min-height: 48px;
	padding: 12px 16px !important;
	border: 0 !important;
	border-bottom: 1px solid #e7e9ee !important;
	background: #fff !important;
	font-size: 13px;
	font-weight: 650;
	white-space: normal !important;
	line-height: 1.35;
	vertical-align: middle;
}
/* The widget title shares this row with the column labels. Under auto layout
   the labels claimed width by content ratio and left the title 137px, so
   "Latest 3 modified Vendor invoices" wrapped to four lines and longer titles
   truncated. Let each label take only its own width and give the rest to the
   title. */
/* The card carries a min-height so the columns line up, and a table row will
   happily absorb that slack -- the Statistics header stretched to 126px against
   47px on every other card. Pin the header to its content height so the body
   row takes the extra instead. */
body.ts-command-module-index .ts-module-index-card tr.liste_titre {
	height: 1px;
}
/* Keep the labels and the title on one line each and let auto layout size the
   columns from that. Forcing widths here instead starved the data columns: the
   title cell spans two of them, so a percentage on it truncated the reference
   and customer beneath. */
body.ts-command-module-index .ts-module-index-card tr.liste_titre > th,
body.ts-command-module-index .ts-module-index-card tr.liste_titre > td {
	white-space: nowrap !important;
}
body.ts-command-module-index .ts-module-index-card tr.liste_titre > th:first-child,
body.ts-command-module-index .ts-module-index-card tr.liste_titre > td:first-child {
	overflow: hidden;
	text-overflow: ellipsis;
}
body.ts-command-module-index .ts-module-index-card tr.liste_titre > :first-child {
	position: relative;
	padding-left: 62px !important;
}
/* A spanning widget title gets its own full-width row. The original header row
   remains below it for actual column labels, so neither title nor labels have
   to compete for the same horizontal space. */
body.ts-command-module-index .ts-module-index-card tr.ts-module-index-title-row > th {
	white-space: normal !important;
}
body.ts-command-module-index .ts-module-index-card tr.ts-module-index-column-header > th,
body.ts-command-module-index .ts-module-index-card tr.ts-module-index-column-header > td {
	min-height: 40px;
	padding-top: 9px !important;
	padding-bottom: 9px !important;
	background: var(--c-sunken) !important;
	font-size: 12px;
}
body.ts-command-module-index .ts-module-index-card tr.ts-module-index-column-header > .ts-module-index-leading-columns {
	padding-left: 16px !important;
}
body.ts-command-module-index .ts-module-index-heading-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	border-radius: 9px;
	background: #f0edff;
	color: var(--c-primary);
	font-size: 16px;
}
body.ts-command-module-index .ts-module-index-card tr.liste_titre > :first-child > .ts-module-index-heading-icon {
	position: absolute;
	top: 50%;
	left: 16px;
	transform: translateY(-50%);
}
body.ts-command-module-index .ts-module-index-heading-icon [class*="fa-"] {
	margin: 0 !important;
	padding: 0 !important;
	color: inherit !important;
	font-size: inherit !important;
}
body.ts-command-module-index .ts-module-index-card tr.liste_titre > th > a:has(.badge),
body.ts-command-module-index .ts-module-index-card tr.liste_titre > td > a:has(.badge) { float: right; margin-left: 10px; }
body.ts-command-module-index .ts-module-index-card tr:not(.liste_titre) > td {
	height: 48px;
	padding: 10px 16px !important;
	border-bottom-color: #f1f3f6 !important;
	font-size: 13px;
}
body.ts-command-module-index .ts-module-index-empty-row td {
	/* display:flex on a td drops its table-cell behaviour, so the colspan is
	   ignored and the cell shrinks to its own content -- "None" ended up 32px
	   wide against the left edge while sibling widgets centred theirs across the
	   card. Keep the cell a table cell and centre its contents instead. */
	display: table-cell !important;
	height: 112px;
	color: var(--c-muted);
	text-align: center;
	vertical-align: middle;
}
body.ts-command-module-index .ts-module-index-empty-inner {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 8px;
}
body.ts-command-module-index .ts-module-index-empty-row .ts-module-index-empty-icon {
	flex: none;
}

/* These links ship as inline-flex, and a flex container cannot render an
   ellipsis: the name overflowed the anchor and was sheared off by the cell
   instead. Constraining the flex items only made it worse -- the text collapsed
   to zero and the anchor shrank to its icon. Lay the anchor out as inline-block
   so text-overflow applies to it directly, keeping the icon inline. */
body.ts-command-module-index .ts-module-index-data-card > tbody > tr:not(.liste_titre) > td > a,
body.ts-command-module-index .ts-module-index-data-card > tbody > tr:not(.liste_titre) > td > span {
	display: inline-block !important;
	max-width: 100%;
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
	vertical-align: middle;
}
body.ts-command-module-index .ts-module-index-data-card > tbody > tr:not(.liste_titre) > td > a > img,
body.ts-command-module-index .ts-module-index-data-card > tbody > tr:not(.liste_titre) > td > a > .fas,
body.ts-command-module-index .ts-module-index-data-card > tbody > tr:not(.liste_titre) > td > a > .far,
body.ts-command-module-index .ts-module-index-data-card > tbody > tr:not(.liste_titre) > td > a > .fa {
	vertical-align: middle;
	margin-right: 4px;
}
/* Record references are text links with a leading glyph. CSS :only-child sees
   only element nodes, so the shared icon-action selector mistook these for
   icon-only buttons and painted a hover square through the entity tile. Keep
   their hover surface transparent while retaining the text colour and tooltip. */
table td > a.refurl:hover,
table td > a.refurl:focus,
table td > a.refurl:active,
table td > a.classforajaxtooltip.refurl:hover,
table td > a.classforajaxtooltip.refurl:focus,
table td > a.classforajaxtooltip.refurl:active {
	background: transparent !important;
}
/* Recent proposal/order widgets wrap each reference in a small nested table.
   The card's ellipsis rule must not collapse that inner reference cell to the
   icon alone; keep the nested table fluid and let its reference remain readable. */
body.ts-command-module-index .ts-module-index-data-card > tbody > tr:not(.liste_titre) > td > table {
	width: 100% !important;
	table-layout: auto !important;
}
body.ts-command-module-index .ts-module-index-data-card > tbody > tr:not(.liste_titre) > td > table td {
	max-width: none !important;
	min-width: 0 !important;
	overflow: visible !important;
	text-overflow: clip !important;
}
body.ts-command-module-index .ts-module-index-data-card > tbody > tr:not(.liste_titre) > td > table td a {
	display: inline-flex !important;
	max-width: 100% !important;
	overflow: visible !important;
	text-overflow: clip !important;
}
body.ts-command-module-index .ts-module-index-data-card > tbody > tr:not(.liste_titre) > td > table > tbody > tr > td:first-child {
	width: 96px !important;
	min-width: 96px !important;
}
body.ts-command-module-index .ts-module-index-data-card > tbody > tr:not(.liste_titre) > td > table > tbody > tr > td:nth-child(2),
body.ts-command-module-index .ts-module-index-data-card > tbody > tr:not(.liste_titre) > td > table > tbody > tr > td:nth-child(3) {
	width: 16px !important;
	min-width: 16px !important;
}

body.ts-command-module-index .ts-module-stat-summary {
	display: grid;
	gap: 14px;
	padding: 16px;
	border: 1px solid var(--c-border);
	border-radius: 12px;
	background: var(--c-surface);
	box-shadow: var(--sh-sm);
}
body.ts-command-module-index .ts-module-stat-total {
	display: grid;
	grid-template-columns: 36px minmax(0, 1fr) auto;
	align-items: center;
	gap: 12px;
	min-height: 58px;
	padding: 10px 14px;
	border-radius: 10px;
	background: linear-gradient(90deg, #f4f1ff, #faf9ff);
}
body.ts-command-module-index .ts-module-stat-total strong { font-size: 14px; font-weight: 650; }
body.ts-command-module-index .ts-module-stat-total b { color: var(--c-primary); font-size: 24px; }
body.ts-command-module-index .ts-module-stat-tiles {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 10px;
}
body.ts-command-module-index .ts-module-stat-tile {
	display: grid;
	grid-template-columns: 28px minmax(0, 1fr);
	align-items: center;
	gap: 3px 9px;
	min-height: 74px;
	padding: 11px;
	border: 1px solid var(--c-border);
	border-radius: 10px;
	background: #fff;
}
body.ts-command-module-index .ts-module-stat-tile > span:first-child { grid-row: 1 / 3; color: #7654d8; font-size: 17px; text-align: center; }
body.ts-command-module-index .ts-module-stat-tile > span:nth-child(2) { overflow: hidden; color: var(--c-muted); font-size: 11px; line-height: 1.25; }
body.ts-command-module-index .ts-module-stat-tile > b { font-size: 16px; }
body.ts-command-module-index .ts-module-stat-tile-2 > span:first-child { color: #2698bd; }
body.ts-command-module-index .ts-module-stat-tile-3 > span:first-child { color: #ee9b22; }
body.ts-command-module-index .ts-module-stat-tile-4 > span:first-child { color: #48a55f; }
@media (max-width: 900px) {
	body.ts-command-module-index .ts-module-index-grid { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 640px) {
	body.ts-command-module-index .fiche { padding: 18px 12px 36px !important; }
	body.ts-command-module-index .ts-pagehead { margin-bottom: 16px; }
	body.ts-command-module-index .ts-pagehead .titre { font-size: 23px; }
	body.ts-command-module-index .ts-module-stat-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	body.ts-command-module-index .ts-module-index-column > .div-table-responsive:has(.ts-module-index-data-card),
	body.ts-command-module-index .ts-module-index-column > .div-table-responsive-no-min:has(.ts-module-index-data-card) {
		max-width: 100%;
		overflow-x: auto;
		border-radius: 12px;
		scrollbar-width: thin;
	}
	body.ts-command-module-index .ts-module-index-data-card { min-width: 600px; }
}
body.ts-command-form-page .ts-command-form-fields {
	display: block !important;
	width: 100% !important;
	margin: 0 !important;
	border: 0 !important;
	background: transparent !important;
	box-shadow: none !important;
}
body.ts-command-form-page .ts-command-form-fields > tbody {
	display: block !important;
	width: 100% !important;
}
body.ts-command-form-page .ts-command-form-fields > tbody > tr {
	border: 0 !important;
}
body.ts-command-form-page .ts-command-form-fields > tbody > tr > td {
	min-height: 52px;
	padding-top: 8px !important;
	padding-bottom: 8px !important;
	border: 0 !important;
	border-bottom: 0 !important;
	background: transparent !important;
	font-size: 13px;
	vertical-align: middle;
}
body.ts-command-form-page .ts-command-form-fields > tbody > tr:last-child > td { border-bottom: 0 !important; }
body.ts-command-form-page .ts-command-form-generated-label {
	display: inline-flex;
	align-items: center;
	min-height: 24px;
	color: var(--c-ink-2);
	font: inherit;
	font-weight: 600;
	line-height: 1.35;
}
/* Once COMMAND owns a form table, every ordinary row leaves the browser's
   cross-row table sizing algorithm. This prevents one helper/action column from
   changing the geometry of unrelated fields elsewhere in the form. */
body.ts-command-form-page .ts-command-form-fields > tbody > tr.ts-command-form-single-row,
body.ts-command-form-page .ts-command-form-fields > tbody > tr.ts-command-form-action-row {
	display: grid !important;
	grid-template-columns: clamp(180px, 23%, 230px) minmax(0, 1fr);
	align-items: center;
	width: 100%;
}
body.ts-command-form-page .ts-command-form-fields > tbody > tr.ts-command-form-action-row {
	grid-template-columns: clamp(180px, 23%, 230px) minmax(0, 1fr) auto;
}
body.ts-command-form-page .ts-command-form-fields > tbody > tr.ts-command-form-single-row > td,
body.ts-command-form-page .ts-command-form-fields > tbody > tr.ts-command-form-action-row > td {
	box-sizing: border-box;
	width: auto !important;
	min-width: 0 !important;
}
body.ts-command-form-page .ts-command-form-fields > tbody > tr.ts-command-form-single-row > td:first-child::after,
body.ts-command-form-page .ts-command-form-fields > tbody > tr.ts-command-form-action-row > td:first-child::after {
	content: none;
}
body.ts-command-form-page .ts-command-form-fields > tbody > tr.ts-command-form-full-row {
	display: block !important;
	width: 100%;
}
body.ts-command-form-page .ts-command-form-fields > tbody > tr.ts-command-form-full-row > td {
	display: block;
	box-sizing: border-box;
	width: 100% !important;
}
body.ts-command-form-page .ts-command-form-fields > tbody > tr.ts-command-form-native-row {
	display: table !important;
	table-layout: auto;
	width: 100%;
}
/* Four-cell form rows are semantic field pairs, not four independently sized
   table columns. Remove them from legacy table auto-layout so both controls keep
   usable space and every icon/label remains attached to its own field. */
body.ts-command-form-page .ts-command-form-fields > tbody > tr.ts-command-form-paired-row {
	display: grid !important;
	grid-template-columns: clamp(180px, 20%, 230px) minmax(180px, 1fr) clamp(120px, 14%, 150px) minmax(180px, 1fr);
	align-items: center;
	width: 100%;
}
body.ts-command-form-page .ts-command-form-fields > tbody > tr.ts-command-form-paired-row > td {
	box-sizing: border-box;
	width: auto !important;
	min-width: 0 !important;
}
body.ts-command-form-page .ts-command-form-fields > tbody > tr.ts-command-form-paired-row > td:nth-child(odd) {
	padding-right: 18px !important;
	color: var(--c-ink-2);
	font-weight: 600;
}
body.ts-command-form-page .ts-command-form-fields > tbody > tr.ts-command-form-paired-row > td:nth-child(even) {
	display: flex;
	align-items: center;
	gap: 8px;
}
body.ts-command-form-page .ts-command-form-fields > tbody > tr.ts-command-form-paired-row > td:nth-child(even) > input:not([type="hidden"]),
body.ts-command-form-page .ts-command-form-fields > tbody > tr.ts-command-form-paired-row > td:nth-child(even) > select,
body.ts-command-form-page .ts-command-form-fields > tbody > tr.ts-command-form-paired-row > td:nth-child(even) > .select2-container {
	flex: 1 1 auto;
	width: auto !important;
	min-width: 0 !important;
	max-width: none !important;
}
body.ts-command-form-page .ts-command-form-fields > tbody > tr.ts-command-form-paired-row > td:first-child::after {
	content: none;
}
/* Row-spanning helper actions belong to their control. The enhancer moves the
   original action node, so its link and click handler remain authoritative. */
body.ts-command-form-page .ts-command-form-fields td.ts-command-form-value-with-action {
	display: flex;
	align-items: flex-start;
	gap: 10px;
}
body.ts-command-form-page .ts-command-form-fields td.ts-command-form-value-with-action > textarea,
body.ts-command-form-page .ts-command-form-fields td.ts-command-form-value-with-action > input:not([type="hidden"]),
body.ts-command-form-page .ts-command-form-fields td.ts-command-form-value-with-action > .select2-container {
	flex: 1 1 auto;
	min-width: 0 !important;
}
body.ts-command-form-page .ts-command-form-inline-action {
	display: inline-flex;
	align-items: center;
	flex: 0 0 auto;
	min-height: 40px;
}
body.ts-command-form-page .ts-command-form-inline-action > a,
body.ts-command-form-page .ts-command-form-inline-action > button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 36px;
	max-width: 190px;
	padding: 7px 10px;
	border-radius: 8px;
	color: var(--c-accent) !important;
	font-size: 12px;
	font-weight: 600;
	line-height: 1.25;
	text-align: center;
	text-decoration: none !important;
}
body.ts-command-form-page .ts-command-form-inline-action > a:hover,
body.ts-command-form-page .ts-command-form-inline-action > button:hover {
	background: var(--c-accent-soft);
}
/* Keep Dolibarr's adjacent "new" action beside relational selects.  The
   legacy markup emits the plus-circle link as a sibling of Select2; without
   an inline value-group it wraps onto its own line. */
body.ts-command-form-page .ts-command-form-fields td:has(> a .fa-plus-circle, > a .fa-plus) {
	display: flex;
	align-items: center;
	gap: 8px;
}
body.ts-command-form-page .ts-command-form-fields td:has(> a .fa-plus-circle, > a .fa-plus) > .select2-container,
body.ts-command-form-page .ts-command-form-fields td:has(> a .fa-plus-circle, > a .fa-plus) > span:has(> .select2-container),
body.ts-command-form-page .ts-command-form-fields td:has(> a .fa-plus-circle, > a .fa-plus) > div:has(> .select2-container) {
	flex: 1 1 auto;
	width: auto !important;
	min-width: 0 !important;
}
body.ts-command-form-page .ts-command-form-fields td:has(> a .fa-plus-circle, > a .fa-plus) > a:has(.fa-plus-circle),
body.ts-command-form-page .ts-command-form-fields td:has(> a .fa-plus-circle, > a .fa-plus) > a:has(.fa-plus) {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 32px;
	width: 32px;
	height: 32px;
	margin: 0;
	border-radius: 7px;
	color: var(--c-accent) !important;
}
body.ts-command-form-page .ts-command-form-fields td:has(> a .fa-plus-circle, > a .fa-plus) > a:has(.fa-plus-circle):hover,
body.ts-command-form-page .ts-command-form-fields td:has(> a .fa-plus-circle, > a .fa-plus) > a:has(.fa-plus):hover {
	background: var(--c-accent-soft);
}
/* Dolibarr writes an assignee or resource as one line of controls -- a picto,
   the select, and the button that adds it -- and relies on them staying inline.
   The shared select treatment lays a select out as a block, which broke that
   line into three: the picto stranded above the field and the Add button
   below it. Lay the group out as a row and keep the list of people already
   assigned on a line of its own above it. */
body.ts-command-form-page .ts-command-form-fields .assignedtouser,
body.ts-command-form-page .ts-command-form-fields .assignedtoresource {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--sp-2);
}
body.ts-command-form-page .ts-command-form-fields .assignedtouser > ul.attendees {
	flex: 1 0 100%;
	margin: 0;
	padding: 0;
}
body.ts-command-form-page .ts-command-form-fields .assignedtouser > .select2-container,
body.ts-command-form-page .ts-command-form-fields .assignedtoresource > .select2-container {
	display: inline-block;
}
body.ts-command-form-page .ts-command-form-fields .assignedtouser > br,
body.ts-command-form-page .ts-command-form-fields .assignedtoresource > br { display: none; }

/* A row is as tall as its tallest control, and a label centred against a group
   of stacked controls floats into the middle of them, reading as though it
   belongs to none. Labels on those rows sit with the first control instead. */
body.ts-command-form-page .ts-command-form-fields > tbody > tr:has(.assignedtouser) > td:first-child,
body.ts-command-form-page .ts-command-form-fields > tbody > tr:has(.assignedtoresource) > td:first-child,
body.ts-command-form-page .ts-command-form-fields > tbody > tr:has(textarea) > td:first-child,
body.ts-command-form-page .ts-command-form-fields > tbody > tr:has(.cke) > td:first-child {
	vertical-align: top;
	padding-top: 20px !important;
}

/* The "new" action is placed at the end of the value cell, so it follows the
   width of the wrapper around the select rather than the select itself. Where
   the select does not fill its wrapper the button ended up hundreds of pixels
   from the field it belongs to. */
body.ts-command-form-page .ts-command-form-fields td:has(> a .fa-plus-circle, > a .fa-plus) > span:has(> .select2-container) > .select2-container,
body.ts-command-form-page .ts-command-form-fields td:has(> a .fa-plus-circle, > a .fa-plus) > div:has(> .select2-container) > .select2-container {
	width: 100% !important;
	max-width: none !important;
}

body.ts-command-form-page .ts-command-form-fields > tbody > tr > td:first-child,
body.ts-command-form-page .ts-command-form-fields .titlefield,
body.ts-command-form-page .ts-command-form-fields .titlefieldcreate,
body.ts-command-form-page .ts-command-form-fields .titlefieldmiddle {
	width: clamp(180px, 23%, 230px) !important;
	padding-right: 22px !important;
	color: #273449;
	font-size: 13px;
	font-weight: 600;
}
/* A table laid out automatically treats a cell's width as a hint and hands the
   label column whatever the value column does not claim -- so two field tables
   in one form settled on different label widths (266px and 148px here) and
   their controls started at different places. Letting the value column claim
   the row, and giving the label column a floor of its own, settles both on the
   same width without moving the table to a fixed layout, which a row with a
   colspan would not survive. */
body.ts-command-form-page .ts-command-form-fields > tbody > tr > td:first-child::after {
	content: "";
	display: block;
	width: 230px;
	height: 0;
}
body.ts-command-form-page .ts-command-form-fields > tbody > tr:not(:has(> td:nth-child(3))) > td:first-child + td {
	width: 100%;
}

body.ts-command-form-page .ts-command-control,
body.ts-command-form-page .ts-command-form input[type="text"],
body.ts-command-form-page .ts-command-form input[type="email"],
body.ts-command-form-page .ts-command-form input[type="url"],
body.ts-command-form-page .ts-command-form input[type="number"],
body.ts-command-form-page .ts-command-form input[type="password"] {
	min-height: 40px !important;
	padding-left: 13px !important;
	padding-right: 13px !important;
	border: 1px solid #dfe4ec !important;
	border-radius: 8px !important;
	background: #fff !important;
	box-shadow: none !important;
	font-size: 13px !important;
}
body.ts-command-form-page .ts-command-form textarea.ts-command-control {
	min-height: 104px !important;
	padding: 11px 13px !important;
	line-height: 1.5;
}
body.ts-command-form-page .ts-command-form input:focus,
body.ts-command-form-page .ts-command-form textarea:focus,
body.ts-command-form-page .ts-command-form .select2-selection:focus,
body.ts-command-form-page .ts-command-form .select2-selection[aria-expanded="true"] {
	border-color: #8b7cf6 !important;
	box-shadow: 0 0 0 3px rgba(91, 76, 240, .12) !important;
	outline: 0 !important;
}
body.ts-command-form-page .ts-command-form .select2-selection--single {
	height: 40px !important;
	min-height: 40px !important;
	border: 1px solid #dfe4ec !important;
	border-radius: 8px !important;
	background: #fff !important;
	box-shadow: none !important;
}
body.ts-command-form-page .ts-command-form .select2-selection__rendered {
	height: 38px !important;
	padding: 0 40px 0 13px !important;
	font-size: 13px !important;
	line-height: 38px !important;
}
body.ts-command-form-page .ts-command-form .select2-selection__arrow {
	top: 0 !important;
	right: 9px !important;
	height: 38px !important;
}
body.ts-command-form-page .ts-command-form .ts-command-select-compact {
	width: min(100%, 340px) !important;
	max-width: 340px !important;
}
body.ts-command-form-page .ts-command-form .select2-selection--multiple {
	min-height: 40px !important;
	padding: 3px 38px 3px 8px !important;
	border: 1px solid #dfe4ec !important;
	border-radius: 8px !important;
	background: #fff !important;
	box-shadow: none !important;
}
body.ts-command-form-page .ts-command-form .select2-selection--multiple .select2-search--inline,
body.ts-command-form-page .ts-command-form .select2-selection--multiple .select2-search__field {
	border: 0 !important;
	background: transparent !important;
	box-shadow: none !important;
	outline: 0 !important;
}
body .select2-dropdown.ts-command-form-dropdown {
	border: 1px solid #e0e6ef !important;
	border-radius: 9px !important;
	background: #fff !important;
	box-shadow: 0 14px 34px rgba(15, 23, 42, .14) !important;
	overflow: hidden;
}
body .ts-command-form-dropdown .select2-search--dropdown { padding: 9px; }
body .ts-command-form-dropdown .select2-search__field {
	height: 38px;
	padding: 0 12px;
	border: 1px solid #dfe4ec;
	border-radius: 8px;
	outline: 0;
}
body .ts-command-form-dropdown .select2-results__options { max-height: 300px; padding: 4px; scrollbar-width: thin; }
body .ts-command-form-dropdown .select2-results__option { min-height: 36px; padding: 8px 10px; border-radius: 6px; font-size: 13px; }
body .ts-command-form-dropdown .select2-results__option--highlighted { background: var(--c-accent-soft) !important; color: var(--c-accent-ink) !important; }
body .ts-command-form-dropdown-compact .select2-search--dropdown,
body .ts-command-form-dropdown .ts-command-empty-option { display: none !important; }

/* Shared legacy list fallback: retain Dolibarr's real filter inputs and empty
   result semantics while giving pages without a richer adapter COMMAND rhythm. */
body:not(.ts-thirdparty-list) table.liste tr.liste_titre_filter > td,
body:not(.ts-thirdparty-list) table.liste tr.liste_titre_filter > th {
	padding: 9px 7px !important;
	border-bottom: 1px solid #e7e9ee !important;
	background: #fbfcfe !important;
}
body:not(.ts-thirdparty-list) table.liste tr.liste_titre_filter input[type="text"],
body:not(.ts-thirdparty-list) table.liste tr.liste_titre_filter input[type="number"],
body:not(.ts-thirdparty-list) table.liste tr.liste_titre_filter select,
body:not(.ts-thirdparty-list) table.liste tr.liste_titre_filter .select2-selection {
	min-height: 38px !important;
	border: 1px solid #dfe4ec !important;
	border-radius: 8px !important;
	background: #fff !important;
	box-shadow: none !important;
}
td.ts-command-empty-state {
	height: 124px !important;
	padding: 72px 20px 22px !important;
	position: relative;
	text-align: center !important;
	vertical-align: middle !important;
	color: #7a8497 !important;
	font-size: 13px !important;
	font-weight: 500 !important;
}
td.ts-command-empty-state::before {
	content: "\f15c";
	position: absolute;
	/* Lift the tile slightly so the message has a deliberate 6–8px breathing
	   gap without changing the icon, text, or empty-state card dimensions. */
	top: 22px;
	left: 50%;
	width: 36px;
	height: 36px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	transform: translateX(-50%);
	background: none;
	color: var(--c-accent);
	font-family: "Font Awesome 5 Free", "Font Awesome 6 Free", FontAwesome;
	font-size: 16px;
	font-weight: 900;
	line-height: 1;
	box-sizing: border-box;
}
body.ts-command-form-page .ts-command-form-actions {
	display: flex !important;
	align-items: center;
	justify-content: center;
	gap: 11px;
	margin: 28px 0 0 !important;
	padding: 22px 0 0;
	border-top: 1px solid #e7e9ee;
}
body.ts-command-form-page .ts-command-form-actions input,
body.ts-command-form-page .ts-command-form-actions button {
	min-width: 112px;
	height: 40px !important;
	margin: 0 !important;
	padding: 0 18px !important;
	border-radius: 8px !important;
	font-size: 13px !important;
	font-weight: 650 !important;
}
body.ts-command-form-page .ts-command-submit-primary {
	border-color: var(--c-btn-action) !important;
	background: var(--c-btn-action) !important;
	color: var(--c-btn-action-text) !important;
}
body.ts-command-form-page .ts-command-submit-secondary {
	border-color: #dfe4ec !important;
	background: #fff !important;
	color: #334155 !important;
}
/* Native Dolibarr card forms (including Third Party create/edit) may not carry
   the composed form-page marker, but their real submit still uses
   .button-save. Keep that action in the shared COMMAND indigo hierarchy. */
body.page-card input.button-save,
body.page-card button.button-save {
	border-color: var(--c-btn-action) !important;
	background: var(--c-btn-action) !important;
	color: var(--c-btn-action-text) !important;
}
/* Some native card forms expose only the shared action-row marker. */
.ts-modern-form-actions input.button-save,
.ts-modern-form-actions button.button-save {
	border-color: var(--c-btn-action) !important;
	background: var(--c-btn-action) !important;
	color: var(--c-btn-action-text) !important;
}
@media (max-width: 760px) {
	body.ts-command-form-page .fiche { padding: 16px 12px 30px !important; }
	body.ts-command-form-page .ts-command-form { padding: 16px !important; }
	body.ts-command-form-page .ts-command-form-fields > tbody > tr {
		display: grid;
		grid-template-columns: minmax(0, 1fr);
		padding: 10px 0;
		border-bottom: 1px solid #f1f3f6 !important;
	}
	body.ts-command-form-page .ts-command-form-fields > tbody > tr.ts-command-form-paired-row {
		grid-template-columns: minmax(0, 1fr) !important;
	}
	body.ts-command-form-page .ts-command-form-fields > tbody > tr.ts-command-form-single-row,
	body.ts-command-form-page .ts-command-form-fields > tbody > tr.ts-command-form-action-row {
		grid-template-columns: minmax(0, 1fr) !important;
	}
	body.ts-command-form-page .ts-command-form-fields td.ts-command-form-value-with-action {
		flex-wrap: wrap;
	}
	body.ts-command-form-page .ts-command-form-inline-action {
		flex: 1 0 100%;
	}
	body.ts-command-form-page .ts-command-form-fields > tbody > tr > td {
		display: block;
		width: 100% !important;
		min-height: 0;
		padding: 4px 0 !important;
		border: 0 !important;
	}
	body.ts-command-form-page .ts-command-form-fields > tbody > tr > td:first-child,
	body.ts-command-form-page .ts-command-form-fields .titlefield,
	body.ts-command-form-page .ts-command-form-fields .titlefieldcreate,
	body.ts-command-form-page .ts-command-form-fields .titlefieldmiddle { width: 100% !important; padding-right: 0 !important; }
	body.ts-command-form-page .ts-command-form input[type="text"],
	body.ts-command-form-page .ts-command-form input[type="email"],
	body.ts-command-form-page .ts-command-form input[type="url"],
	body.ts-command-form-page .ts-command-form textarea,
	body.ts-command-form-page .ts-command-form .select2-container { max-width: 100% !important; }
	body.ts-command-form-page .ts-command-form-actions { flex-wrap: wrap; }
}

/* Third Party overview reference composition -----------------------------
   Route-gated by modern.js so these refinements cannot alter other record
   tabs or any list/create surface. */
body.ts-thirdparty-overview .ts-thirdparty-record-shell {
	border: 0;
	background: transparent;
	box-shadow: none;
}
body.ts-thirdparty-overview .ts-thirdparty-record-shell > .ts-entity-banner {
	min-height: 142px;
	padding: 24px !important;
	border: 1px solid #e7e9ee !important;
	border-radius: 12px !important;
	background: #fff !important;
	box-shadow: 0 4px 16px rgba(15, 23, 42, .045) !important;
}
body.ts-thirdparty-overview .ts-entity-identity {
	display: grid !important;
	grid-template-columns: 80px minmax(0, 1fr) !important;
	gap: 20px !important;
}
body.ts-thirdparty-overview .ts-entity-banner .ts-entity-identity > .divphotoref.ts-overview-photo-source { display: none !important; }
body.ts-thirdparty-overview .ts-entity-banner .ts-entity-identity.ts-overview-has-logo > .divphotoref.ts-overview-photo-source {
	display: flex !important;
	width: 80px !important;
	height: 80px !important;
	min-width: 80px;
	padding: 8px;
	border: 0;
	border-radius: 14px;
	background: #f0edff;
	box-shadow: 0 6px 15px rgba(79, 70, 229, .09);
}
body.ts-thirdparty-overview .ts-overview-has-logo .ts-overview-photo-source a,
body.ts-thirdparty-overview .ts-overview-has-logo .ts-overview-photo-source img {
	display: block;
	width: 100% !important;
	height: 100% !important;
	max-width: 100% !important;
	max-height: 100% !important;
	margin: 0 !important;
	object-fit: contain;
}
body.ts-thirdparty-overview .ts-overview-has-logo .ts-overview-icon-tile { display: none; }
body.ts-thirdparty-overview .ts-overview-icon-tile {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 80px;
	height: 80px;
	border: 1px solid #e4dfff;
	border-radius: 12px;
	background: #f1edff;
	color: #6551d8;
	font-size: 30px;
}
body.ts-thirdparty-overview .ts-entity-identity > .refid {
	grid-template-columns: minmax(0, auto) auto auto minmax(0, 1fr) !important;
	column-gap: 9px !important;
	font-size: 24px !important;
	font-weight: 650 !important;
	letter-spacing: -.025em;
}
body.ts-thirdparty-overview .ts-entity-identity > .refid > .ts-overview-name {
	grid-column: 1;
	grid-row: 1;
	min-width: 0;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}
body.ts-thirdparty-overview .ts-entity-identity > .refid > a.refid { display: none !important; }
body.ts-thirdparty-overview .ts-overview-secondary-hidden { display: none !important; }
/* Some records emit an unclassified legacy secondary line alongside the
   normalized location/email rows. It can overlap the email at narrow identity
   widths; the concise overview rows are the only metadata shown in this shell. */
body.ts-thirdparty-overview .ts-entity-identity > .refid > .refidno {
	display: none !important;
}
body.ts-thirdparty-overview .ts-overview-location {
	grid-column: 1 / -1;
	grid-row: 2;
	display: inline-flex !important;
	align-items: center;
	gap: 7px;
	margin: 5px 0 0 !important;
	color: #64748b;
	font-size: 13px;
	font-weight: 400;
}
body.ts-thirdparty-overview .ts-entity-identity > .refid > .ts-overview-location {
	display: inline-flex !important;
}
body.ts-thirdparty-overview .ts-overview-location [class*="fa-"] { color: #8491a6 !important; }
body.ts-thirdparty-overview .ts-overview-email {
	grid-column: 1 / -1;
	grid-row: 3;
	display: inline-flex;
	align-items: center;
	gap: 7px;
	max-width: 100%;
	margin-top: 2px;
	color: #4f46e5;
	font-size: 13px;
	font-weight: 450;
	text-decoration: none;
}
body.ts-thirdparty-overview .ts-overview-email [class*="fa-"] {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 16px;
	margin: 0 !important;
	padding: 0 !important;
	color: #64748b !important;
}
/* The entity icon already identifies the record in the header. Repeating it in
   the first Overview tab consumes scarce horizontal space and is what causes
   lower-priority tabs to clip at the right edge. Keep the existing link and
   active state, but use the same text-only tab treatment as the other tabs. */
body.ts-thirdparty-record-context .tabs a[href*="/societe/card.php"] > [class*="fa-"],
body.ts-thirdparty-record-context .tabs a[href*="/societe/card.php"] > svg {
	display: none !important;
}
body.ts-thirdparty-overview .ts-overview-info {
	grid-column: 3;
	grid-row: 1;
	color: #8190a6;
	font-size: 14px;
}
body.ts-thirdparty-overview .ts-header-actions div.tabsAction { gap: 10px; }
body.ts-thirdparty-overview .ts-header-actions .ts-record-primary {
	order: 2 !important;
	min-height: 40px !important;
	border: 1px solid #dfe4ec !important;
	background: #fff !important;
	color: #334155 !important;
	box-shadow: none !important;
}
body.ts-thirdparty-overview .ts-header-actions .ts-record-secondary {
	order: 1 !important;
	min-height: 40px !important;
	/* Send email is the visible primary action on this overview. It must honour
	   Display > Skin and colors just like every other butAction. */
	border: 1px solid var(--c-btn-action, var(--c-accent)) !important;
	background: var(--c-btn-action, var(--c-accent)) !important;
	color: var(--c-btn-action-text, #fff) !important;
	box-shadow: 0 2px 5px color-mix(in srgb, var(--c-btn-action, var(--c-accent)) 24%, transparent) !important;
}
body.ts-thirdparty-overview .ts-header-actions .ts-record-primary,
body.ts-thirdparty-overview .ts-header-actions .ts-record-secondary { gap: 9px; }
body.ts-thirdparty-overview .ts-overview-button-icon { font-size: 14px; }
body.ts-thirdparty-overview .ts-more-actions { order: 3 !important; }
body.ts-thirdparty-overview .ts-more-actions-trigger { min-height: 40px; border-radius: 8px; box-shadow: none; }
body.ts-thirdparty-overview .ts-more-actions-menu {
	min-width: 178px;
	padding: 6px;
	border-color: #e2e7ef;
	border-radius: 10px;
	box-shadow: 0 14px 32px rgba(15, 23, 42, .14);
}
body.ts-thirdparty-overview .ts-more-actions-menu .ts-more-action-item { min-height: 40px; gap: 10px; border-radius: 7px; }
body.ts-thirdparty-overview .ts-overview-action-icon { width: 16px; text-align: center; color: #64748b; }
body.ts-thirdparty-overview .ts-more-action-item.butActionDelete .ts-overview-action-icon { color: #dc2626; }
body.ts-thirdparty-overview .ts-entity-banner .pagination.paginationref {
	order: 4;
	margin-left: 2px;
	display: inline-flex;
	opacity: 1;
}
body.ts-thirdparty-overview .ts-entity-banner .pagination.paginationref li.pagination > a,
body.ts-thirdparty-overview .ts-entity-banner .pagination.paginationref li.pagination > span {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 40px;
	border: 1px solid #dfe4ec;
	border-radius: 7px;
	background: #fff;
	color: #64748b;
}
body.ts-thirdparty-overview .ts-thirdparty-record-shell > .tabs[data-ts-placed="1"] {
	display: flex;
	align-items: stretch;
	gap: 0;
	margin: 16px 0;
	padding: 0 8px;
	border: 1px solid #e7e9ee;
	border-radius: 12px;
	background: #fff;
	box-shadow: 0 4px 14px rgba(15, 23, 42, .04);
}
body.ts-thirdparty-overview .ts-thirdparty-record-shell > .tabs a.tab { min-height: 52px; padding: 0 19px; font-size: 13px; }
body.ts-thirdparty-overview .ts-tabs-more { position: relative; flex: 0 0 auto; }
body.ts-thirdparty-overview .ts-tabs-more > summary {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	min-height: 50px;
	padding: 0 16px;
	list-style: none;
	color: #536078;
	font-size: 14px;
	font-weight: 520;
	cursor: pointer;
}
body.ts-thirdparty-overview .ts-tabs-more > summary::-webkit-details-marker { display: none; }
body.ts-thirdparty-overview .ts-tabs-more > summary .fa-chevron-down { font-size: 10px; }
body.ts-thirdparty-overview .ts-tabs-more-menu {
	position: absolute;
	z-index: 80;
	top: calc(100% + 6px);
	right: 0;
	min-width: 180px;
	padding: 6px;
	border: 1px solid #e2e7ef;
	border-radius: 10px;
	background: #fff;
	box-shadow: 0 14px 32px rgba(15, 23, 42, .14);
}
body.ts-thirdparty-overview .ts-tabs-more-menu .tabsElem { display: block !important; }
body.ts-thirdparty-overview .ts-tabs-more-menu .tab { display: block; margin: 0 !important; }
body.ts-thirdparty-overview .ts-tabs-more-menu a.tab {
	display: flex;
	align-items: center;
	width: 100%;
	min-height: 40px;
	padding: 0 11px;
	border-radius: 7px;
}
body.ts-thirdparty-overview .ts-tabs-more-menu a.tab:hover { background: #f7f7fc; }
body.ts-thirdparty-overview .ts-thirdparty-groups { align-items: stretch; gap: 16px; }
body.ts-thirdparty-overview .ts-field-group {
	display: flex;
	flex-direction: column;
	min-height: 328px;
	border: 1px solid #e6e9ef;
	border-radius: 12px;
	box-shadow: 0 4px 14px rgba(15, 23, 42, .035);
}
body.ts-thirdparty-overview .ts-field-group-title {
	padding: 19px 20px 13px;
	border-bottom: 1px solid #f1f3f6;
	font-size: 16px;
}
body.ts-thirdparty-overview .ts-field-group-icon { width: 22px; font-size: 20px; }
body.ts-thirdparty-overview .ts-field-group > table.tableforfield {
	flex: 0 0 auto;
	width: calc(100% - 40px) !important;
	margin: 10px 20px 16px !important;
	padding: 0;
	table-layout: fixed;
}
body.ts-thirdparty-overview .ts-field-group > table.tableforfield > tbody > tr > td {
	height: 31px;
	padding: 6px 0;
	border: 0 !important;
	font-size: 13px;
	line-height: 1.4;
	vertical-align: top;
}
body.ts-thirdparty-overview .ts-field-group > table.tableforfield > tbody > tr,
body.ts-thirdparty-overview .ts-field-group > table.tableforfield > tbody > tr + tr { border: 0 !important; }
body.ts-thirdparty-overview .ts-field-group > table.tableforfield > tbody > tr > td:first-child {
	width: 56%;
	padding-right: 18px;
	color: #273449;
	font-weight: 550;
}
body.ts-thirdparty-overview .ts-field-group > table.tableforfield > tbody > tr > td:last-child {
	width: 44%;
	color: #526176;
	font-size: 13.5px;
	overflow-wrap: anywhere;
}
body.ts-thirdparty-overview .ts-field-group tr[data-field="nature"] a {
	display: inline-flex;
	align-items: center;
	min-height: 23px;
	padding: 0 8px;
	border-radius: 999px;
	background: #eaf8ee;
	color: #18733d;
	font-size: 11px;
	font-weight: 650;
	text-decoration: none;
}
body.ts-thirdparty-overview .ts-field-group[data-group="relationships"] > table { flex: 0 0 auto !important; }
body.ts-thirdparty-overview .ts-field-group[data-group="relationships"] > table > tbody > tr > td {
	height: auto;
	padding-top: 14px;
	padding-bottom: 14px;
	vertical-align: top;
}
body.ts-thirdparty-overview .ts-field-group[data-group="relationships"] .userimg img {
	width: 29px !important;
	height: 29px !important;
	border-radius: 50%;
}
body.ts-thirdparty-overview .ts-field-group .clipboardCP { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
body.ts-thirdparty-overview .ts-overview-copy {
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	width: 30px;
	height: 30px;
	margin: -6px 0 !important;
	padding: 0 !important;
	border-radius: 7px;
}
body.ts-thirdparty-overview .ts-overview-copy:hover { background: #f3f1ff; color: #5546e8 !important; opacity: 1; }
body.ts-thirdparty-overview .ts-overview-lower-grid {
	display: grid;
	grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr);
	align-items: start;
	gap: 16px;
	margin-top: 16px;
}
body.ts-thirdparty-overview .ts-overview-lower-grid > .ts-record-section-card {
	float: none !important;
	width: auto !important;
	min-width: 0;
	margin: 0 !important;
	padding: 20px !important;
	border: 1px solid #e6e9ef;
	border-radius: 12px;
	box-shadow: 0 4px 14px rgba(15, 23, 42, .035);
}
body.ts-thirdparty-overview .ts-record-section-card table.table-fiche-title { min-height: 36px; margin-bottom: 14px; }
body.ts-thirdparty-overview .ts-record-section-files .ts-emptybox {
	min-height: 166px;
	border: 1px dashed #cfc8ff;
	border-radius: 12px;
	background: #fdfcff;
}
body.ts-thirdparty-overview .ts-record-section-files .ts-emptybox > .far {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 54px;
	height: 54px;
	border-radius: 50%;
	background: #f0edff;
	color: #5b4cf0;
	font-size: 23px;
}
body.ts-thirdparty-overview .ts-record-section-files form + br,
body.ts-thirdparty-overview .ts-record-section-files form + br + br { display: none; }
body.ts-thirdparty-overview .ts-record-section-events .ts-record-tab-surface { margin: 0; border-radius: 9px; box-shadow: none; }
body.ts-thirdparty-overview .ts-record-section-events tr.liste_titre th { height: 40px; padding: 8px 10px; font-size: 11px; color: #64748b; }
body.ts-thirdparty-overview .ts-record-section-events tr.oddeven td { height: 49px; padding: 8px 10px; font-size: 12px; }
body.ts-thirdparty-overview .ts-record-section-events .userimg img { width: 27px !important; height: 27px !important; border-radius: 50%; }
body.ts-thirdparty-overview .ts-overview-event-type { color: #6d5bd0 !important; }
body.ts-thirdparty-overview .ts-overview-event-type > [class*="fa-"] { display: none; }
body.ts-thirdparty-overview .ts-record-section-events tr > :nth-child(4) { display: none; }
body.ts-thirdparty-overview .ts-record-section-events tr > :nth-child(5) { width: 42%; }
body.ts-thirdparty-overview .ts-record-section-events tr.oddeven .badge-dot {
	background: #18a66a !important;
	color: #18a66a !important;
}
body.ts-thirdparty-overview .ts-overview-redundant-event-action { display: none !important; }

@media (min-width: 1101px) {
	body.ts-thirdparty-overview .ts-thirdparty-groups { grid-template-columns: repeat(3, minmax(0, 1fr)); }
	body.ts-thirdparty-overview .ts-field-group[data-group="identity"],
	body.ts-thirdparty-overview .ts-field-group[data-group="relationships"] { grid-column: auto; grid-row: auto; }
}
@media (max-width: 1100px) {
	body.ts-thirdparty-overview .ts-thirdparty-groups { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	body.ts-thirdparty-overview .ts-field-group[data-group="relationships"] { grid-column: 1 / -1; }
}
@media (max-width: 900px) {
	body.ts-thirdparty-overview .ts-thirdparty-record-shell > .ts-entity-banner { align-items: flex-start; }
	body.ts-thirdparty-overview .ts-header-actions { width: 100%; }
	body.ts-thirdparty-overview .ts-overview-lower-grid { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 700px) {
	body.ts-thirdparty-overview .ts-thirdparty-record-shell > .ts-entity-banner { padding: 16px !important; }
	body.ts-thirdparty-overview .ts-entity-identity { grid-template-columns: 48px minmax(0, 1fr) !important; gap: 12px !important; }
	body.ts-thirdparty-overview .ts-overview-icon-tile { width: 48px; height: 48px; }
	body.ts-thirdparty-overview .ts-entity-identity > .refid { font-size: 21px !important; }
	body.ts-thirdparty-overview .ts-thirdparty-groups { grid-template-columns: minmax(0, 1fr); }
	body.ts-thirdparty-overview .ts-field-group[data-group="relationships"] { grid-column: auto; }
	body.ts-thirdparty-overview .ts-field-group > table.tableforfield {
		width: calc(100% - 32px) !important;
		margin-inline: 16px !important;
	}
	body.ts-thirdparty-overview .ts-tabs-more-menu { right: auto; left: 0; }
	/* A phone leaves a field card about 300px wide, and a 48% label column gives a
	   label like "Business entity type" 110px to sit in. Every other label wrapped
	   to a second line while its row was still held at 31px, so the wrap ran into
	   the label below it and the whole card read as one column of collided text.
	   Stacked, each label has the full width and needs one line; the value follows
	   underneath, and a rule between fields says where one ends and the next
	   begins. */
	.ts-field-group table.tableforfield:not(.liste) > tbody > tr,
	body.ts-thirdparty-overview .ts-field-group > table.tableforfield > tbody > tr {
		display: grid !important;
		grid-template-columns: minmax(0, 1fr) !important;
		align-items: start !important;
		row-gap: 2px;
		padding: 11px 0 !important;
	}
	.ts-field-group table.tableforfield:not(.liste) > tbody > tr + tr,
	body.ts-thirdparty-overview .ts-field-group > table.tableforfield > tbody > tr + tr {
		border-top: 1px solid var(--c-hairline) !important;
	}
	.ts-field-group table.tableforfield:not(.liste) > tbody > tr > td,
	body.ts-thirdparty-overview .ts-field-group > table.tableforfield > tbody > tr > td {
		height: auto !important;
		min-height: 0 !important;
		padding: 0 !important;
		width: auto !important;
	}
	body.ts-thirdparty-overview .ts-field-group > table.tableforfield > tbody > tr > td:first-child {
		font-size: 12px;
		font-weight: 600;
		color: var(--c-ink-subtle);
	}
	body.ts-thirdparty-overview .ts-field-group > table.tableforfield > tbody > tr > td:last-child {
		font-size: 13.5px;
		color: var(--c-ink-2);
	}
	/* Dolibarr wraps some labels in a table of their own to hang an edit link on
	   the end of the line. Those labels then keep the table's own type -- larger
	   and darker than the labels beside them -- and hold a 32px row whether the
	   link is there or not, so four fields in the card looked like headings and
	   broke the spacing. The nested table is made to carry the same label type as
	   the rest and to take only the height its text needs. */
	body.ts-thirdparty-overview .ts-field-group > table.tableforfield > tbody > tr > td table.nobordernopadding {
		width: 100% !important;
		margin: 0 !important;
	}
	body.ts-thirdparty-overview .ts-field-group > table.tableforfield > tbody > tr > td table.nobordernopadding td {
		height: auto !important;
		padding: 0 !important;
		font-size: 12px !important;
		font-weight: 600 !important;
		color: var(--c-ink-subtle) !important;
		line-height: 1.4 !important;
	}
	body.ts-thirdparty-overview .ts-field-group > table.tableforfield > tbody > tr > td table.nobordernopadding td.right:empty {
		display: none !important;
	}
}
/* On a phone the banner has no room to seat the identity beside the actions.
   Laid out as a row, its tallest item -- the stack of buttons -- set the height
   and the identity stretched to match, which left the name floating in the
   middle of an empty band. The name also shared its line with the status and
   the info control, and what remained of a 390px screen truncated a company
   name to a word. Stacked, each part takes the width it needs and the name has
   the line to itself. */
@media (max-width: 600px) {
	body.ts-thirdparty-overview .ts-thirdparty-record-shell > .ts-entity-banner {
		flex-direction: column;
		align-items: stretch;
		gap: var(--sp-4);
		min-height: 0;
	}
	body.ts-thirdparty-overview .ts-entity-identity {
		align-items: start !important;
		gap: var(--sp-3) !important;
	}
	body.ts-thirdparty-overview .ts-entity-identity > .refid {
		/* A second, content-width column so the status and the control that
		   explains it keep each other company on one line. */
		grid-template-columns: auto minmax(0, 1fr) !important;
		row-gap: var(--sp-1) !important;
		column-gap: var(--sp-2) !important;
		font-size: 19px !important;
	}
	body.ts-thirdparty-overview .ts-entity-identity > .refid > .ts-overview-name {
		grid-column: 1 / -1 !important;
		grid-row: 1 !important;
		white-space: normal;
		overflow: visible;
		text-overflow: clip;
		line-height: 1.25;
	}
	body.ts-thirdparty-overview .ts-entity-identity > .refid > .statusref {
		grid-column: 1 !important;
		grid-row: 2 !important;
		justify-content: flex-start;
	}
	body.ts-thirdparty-overview .ts-entity-identity > .refid > .ts-overview-info {
		grid-column: 2 !important;
		grid-row: 2 !important;
		justify-self: start;
		align-self: center;
	}
	body.ts-thirdparty-overview .ts-entity-identity > .refid > .ts-overview-location,
	body.ts-thirdparty-overview .ts-entity-identity > .refid > .ts-overview-email {
		grid-column: 1 / -1 !important;
		grid-row: auto !important;
		overflow-wrap: anywhere;
	}
	/* One column of actions, each the width of the card: a row of buttons that
	   wrapped left them at whatever width their label happened to need. */
	body.ts-thirdparty-overview .ts-header-actions div.tabsAction {
		flex-direction: column;
		align-items: stretch;
	}
	body.ts-thirdparty-overview .ts-header-actions div.tabsAction > * {
		width: 100%;
		justify-content: center;
	}
	body.ts-thirdparty-overview .ts-entity-banner .pagination.paginationref {
		align-self: flex-end;
	}
}

/* Third Party Events/Agenda tab -----------------------------------------
   Exact-route gated by modern.js. Native filters, view links, users, dates,
   references and event actions are moved intact into this composition. */
body.ts-thirdparty-events .ts-thirdparty-record-shell { margin-bottom: 16px; }
body.ts-thirdparty-events .ts-thirdparty-record-shell > .tabs[data-ts-placed="1"] { margin-bottom: 0; }
body.ts-thirdparty-events .ts-thirdparty-record-shell .tabsElemActive a#agenda {
	color: #4f46e5;
	font-weight: 650;
}
body.ts-thirdparty-events .fiche > .fichecenter {
	display: block;
	min-width: 0;
}
body.ts-thirdparty-events .ts-events-summary {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	margin: 0 0 16px;
	padding: 4px 18px;
	border: 1px solid #e7e9ee;
	border-radius: 12px;
	background: #fff;
	box-shadow: 0 4px 14px rgba(15, 23, 42, .04);
}
body.ts-thirdparty-events .ts-events-summary-item {
	display: grid;
	grid-template-columns: 42px minmax(0, 1fr);
	align-items: center;
	gap: 14px;
	min-height: 76px;
	padding: 12px 2px;
}
body.ts-thirdparty-events .ts-events-summary-item:nth-child(odd) { padding-right: 24px; }
body.ts-thirdparty-events .ts-events-summary-item:nth-child(even) { padding-left: 24px; }
body.ts-thirdparty-events .ts-events-summary-item:nth-child(n+3) { border-top: 1px solid #edf0f4; }
body.ts-thirdparty-events .ts-events-summary-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 42px;
	height: 42px;
	border-radius: 10px;
	background: #f1edff;
	color: #5b4cf0;
	font-size: 16px;
}
body.ts-thirdparty-events .ts-events-summary-copy { display: grid; gap: 4px; min-width: 0; }
body.ts-thirdparty-events .ts-events-summary-label,
body.ts-thirdparty-events .ts-events-summary-value {
	display: block !important;
	width: auto !important;
	height: auto !important;
	padding: 0 !important;
	border: 0 !important;
	background: transparent !important;
}
body.ts-thirdparty-events .ts-events-summary-label {
	color: #64748b;
	font-size: 12px;
	font-weight: 550;
}
body.ts-thirdparty-events .ts-events-summary-value {
	color: #25324a;
	font-size: 13px;
	font-weight: 550;
}
body.ts-thirdparty-events .ts-events-summary-value .userimg img {
	width: 28px !important;
	height: 28px !important;
	border-radius: 50%;
}
body.ts-thirdparty-events .ts-events-pagehead {
	margin: 0 !important;
	padding: 22px 24px 16px;
	border: 1px solid #e7e9ee;
	border-bottom: 0;
	border-radius: 12px 12px 0 0;
	background: #fff;
}
body.ts-thirdparty-events .ts-events-pagehead .titre { font-size: 23px !important; font-weight: 650; }
body.ts-thirdparty-events .ts-events-create {
	min-height: 42px !important;
	padding: 0 17px !important;
	border-radius: 8px !important;
	background: var(--c-btn-action) !important;
	color: var(--c-btn-action-text) !important;
}
body.ts-thirdparty-events .ts-events-native-title-source { display: none !important; }
body.ts-thirdparty-events .ts-events-toolbar {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	align-items: center;
	gap: 10px;
	margin: 0;
	padding: 0 24px 18px;
	border: 1px solid #e7e9ee;
	border-top: 0;
	background: #fff;
}
body.ts-thirdparty-events .ts-events-view-switch {
	display: inline-flex;
	align-items: center;
	flex: 0 0 auto;
	height: 40px;
	padding: 3px;
	border: 1px solid #dfe4ec;
	border-radius: 8px;
	background: #fff;
}
body.ts-thirdparty-events .ts-events-view-option {
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	width: 36px !important;
	height: 32px !important;
	min-width: 36px !important;
	min-height: 32px !important;
	padding: 0 !important;
	border: 0 !important;
	border-radius: 6px !important;
	background: transparent !important;
	box-shadow: none !important;
	color: #64748b !important;
}
body.ts-thirdparty-events .ts-events-view-option.btnTitleSelected {
	background: #eeebff !important;
	color: #4f46e5 !important;
}
body.ts-thirdparty-events .ts-events-view-switch + .vbar { display: none !important; }
body.ts-thirdparty-events .ts-events-filter-form { flex: 1 1 auto; min-width: 0; margin: 0 !important; }
body.ts-thirdparty-events .ts-events-filter-form .ts-record-tab-surface {
	margin: 0 !important;
	border: 0 !important;
	border-radius: 0;
	box-shadow: none;
	overflow: visible;
}
body.ts-thirdparty-events .ts-events-filter-form table,
body.ts-thirdparty-events .ts-events-filter-form tbody,
body.ts-thirdparty-events .ts-events-filter-form tr {
	display: contents;
}
body.ts-thirdparty-events .ts-events-filter-form .liste_titre {
	display: grid;
	grid-template-columns: minmax(240px, 1fr) 210px 240px minmax(196px, max-content);
	align-items: center;
	gap: 10px;
	width: 100%;
	min-width: 0;
	padding: 0 !important;
	border: 0 !important;
	background: transparent !important;
}
body.ts-thirdparty-events .ts-events-filter-form th {
	display: flex !important;
	align-items: center;
	min-width: 0;
	height: 40px !important;
	padding: 0 !important;
	border: 0 !important;
	background: transparent !important;
}
body.ts-thirdparty-events .ts-events-filter-form th:nth-child(5) { grid-column: 1; grid-row: 1; }
body.ts-thirdparty-events .ts-events-filter-form th:nth-child(2) { grid-column: 2; grid-row: 1; }
body.ts-thirdparty-events .ts-events-filter-form th:nth-child(4) { grid-column: 3; grid-row: 1; }
body.ts-thirdparty-events .ts-events-filter-form th:nth-child(1) { grid-column: 4; grid-row: 1; }
body.ts-thirdparty-events .ts-events-filter-form th:nth-child(3) { display: none !important; }
body.ts-thirdparty-events .ts-events-search-control {
	display: flex;
	align-items: center;
	gap: 9px;
	width: 100%;
	height: 40px;
	padding: 0 12px;
	border: 1px solid #dfe4ec;
	border-radius: 8px;
	background: #fff;
	color: #7c899d;
}
body.ts-thirdparty-events .ts-events-search-input {
	flex: 1 1 auto;
	width: 100% !important;
	height: 38px !important;
	min-width: 0;
	padding: 0 !important;
	border: 0 !important;
	background: transparent !important;
	box-shadow: none !important;
	font-size: 13px;
}
body.ts-thirdparty-events .ts-events-date-control {
	display: flex;
	align-items: center;
	gap: 9px;
	width: 100%;
	height: 40px;
	padding: 0 12px;
	border: 1px solid #dfe4ec;
	border-radius: 8px !important;
	background: #fff;
	color: #475569;
	font-size: 13px;
	font-weight: 500;
	text-decoration: none;
	justify-content: flex-start !important;
}
body.ts-thirdparty-events .ts-events-filter-form th:nth-child(2) > .nowrap,
body.ts-thirdparty-events .ts-events-filter-form th:nth-child(4) > [class*="fa-square"] { display: none !important; }
body.ts-thirdparty-events .ts-events-filter-form .select2-container {
	/* Select2's container is inline and unsized, so the 40px selection inside it
	   sat below the row's shared baseline. Give the container the control height
	   it is standing in for. */
	width: 100% !important;
	display: block;
	height: 40px;
	align-self: center;
}
body.ts-thirdparty-events .ts-events-filter-form .select2-selection--single {
	height: 40px !important;
	min-height: 40px !important;
	border: 1px solid #dfe4ec !important;
	border-radius: 8px !important;
	background: #fff !important;
	box-shadow: none !important;
}
body.ts-thirdparty-events .ts-events-filter-form .select2-selection__rendered {
	height: 38px !important;
	padding: 0 38px 0 12px !important;
	font-size: 13px !important;
	line-height: 38px !important;
}
body.ts-thirdparty-events .ts-events-filter-form .select2-selection__arrow { top: 0 !important; right: 8px !important; height: 38px !important; }
body.ts-thirdparty-events .ts-events-filter-form button.button_search,
body.ts-thirdparty-events .ts-events-filter-form button.button_removefilter {
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	gap: 8px;
	height: 40px !important;
	margin: 0 !important;
	padding: 0 13px !important;
	border: 1px solid #dfe4ec !important;
	border-radius: 8px !important;
	background: #fff !important;
	color: #475569 !important;
	font-size: 13px;
}
body.ts-thirdparty-events .ts-events-filter-form th:nth-child(1) { gap: 8px; justify-content: flex-end; }
body.ts-thirdparty-events .ts-events-filter-form th:nth-child(1) button.button_search { flex: 0 0 auto; min-width: 92px; }
body.ts-thirdparty-events .ts-events-filter-form button.button_removefilter { flex: 0 0 auto; width: 40px; padding: 0 !important; }
/* Dolibarr wraps only part of this column's buttons, so the wrapper box laid
   the group out from its own origin and ran the reset control past the card
   edge. Take the wrapper out of layout entirely and let the column align both
   buttons as one row. */
body.ts-thirdparty-events .ts-events-filter-form th:nth-child(1) > .nowraponall { display: contents; }
body.ts-thirdparty-events .ts-events-filter-label { font-weight: 550; }
body.ts-thirdparty-events .select2-dropdown.ts-events-select-dropdown {
	border: 1px solid #dfe4ec !important;
	border-radius: 9px !important;
	background: #fff !important;
	box-shadow: 0 12px 28px rgba(15, 23, 42, .14) !important;
	overflow: hidden;
}
body.ts-thirdparty-events .ts-events-select-dropdown .select2-search { display: none !important; }
body.ts-thirdparty-events .ts-events-select-dropdown .select2-results__option {
	min-height: 38px;
	padding: 9px 12px !important;
	font-size: 13px;
}
body.ts-thirdparty-events .ts-events-select-dropdown .select2-results__option--highlighted { background: #f0edff !important; color: #4338ca !important; }
body.ts-thirdparty-events .ts-events-timeline {
	position: relative;
	margin: 0;
	padding: 4px 24px 24px 56px;
	border: 1px solid #e7e9ee;
	border-top: 0;
	border-radius: 0 0 12px 12px;
	background: #fff;
	box-shadow: 0 5px 18px rgba(15, 23, 42, .04);
}
body.ts-thirdparty-events .ts-events-timeline::before {
	position: absolute;
	top: 52px;
	bottom: 30px;
	left: 31px;
	width: 1px;
	background: #e2e7ef;
	content: "";
}
body.ts-thirdparty-events .ts-events-timeline > li.time-label {
	margin: 0 0 10px -32px;
	padding-top: 15px;
	color: #64748b;
	font-size: 12px;
	font-weight: 650;
	letter-spacing: .045em;
}
body.ts-thirdparty-events .ts-events-entry {
	position: relative;
	min-height: 86px;
	margin: 0 0 10px !important;
	padding: 14px 16px 14px 72px !important;
	border: 1px solid #e5e9f0 !important;
	border-radius: 11px !important;
	background: #fff !important;
	box-shadow: 0 2px 8px rgba(15, 23, 42, .025) !important;
}
body.ts-thirdparty-events .ts-events-entry::before {
	position: absolute;
	top: 30px;
	left: -38px;
	width: 9px;
	height: 9px;
	border: 2px solid #fff;
	border-radius: 50%;
	background: #aab6c9;
	box-shadow: 0 0 0 1px #d7dde7;
	content: "";
}
body.ts-thirdparty-events .ts-events-entry-icon {
	position: absolute;
	top: 16px;
	left: 16px;
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	width: 42px !important;
	height: 42px !important;
	padding: 0 !important;
	border-radius: 10px;
	background: #f1edff;
	color: #5b4cf0 !important;
	font-size: 17px;
}
body.ts-thirdparty-events .ts-events-entry .timeline-item {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto auto;
	align-items: center;
	gap: 6px 12px;
}
body.ts-thirdparty-events .ts-events-entry .timeline-header {
	display: contents;
}
body.ts-thirdparty-events .ts-events-entry-title {
	grid-column: 1 / -1;
	grid-row: 1;
	color: #1e293b;
	font-size: 14px;
	font-weight: 650;
	line-height: 1.4;
}
body.ts-thirdparty-events .ts-events-entry-author {
	grid-column: 1;
	grid-row: 2;
	margin: 0 !important;
	color: #475569;
	font-size: 13px;
}
body.ts-thirdparty-events .ts-events-entry-author .userimg img { width: 24px !important; height: 24px !important; }
/* A contact or user photo in a list is an identifying mark beside a name, not a
   portrait. Nothing sized these, so the source image set the row height -- a
   related contact stood 80px tall and pushed its row past 120px. */
table.liste td .userimg img,
table.noborder td .userimg img,
table.liste td img.photocontact,
table.noborder td img.photocontact,
table.liste td img.userphotosmall,
table.noborder td img.userphotosmall {
	width: 24px !important;
	height: 24px !important;
	min-width: 0 !important;
	border-radius: 50%;
	object-fit: cover;
	vertical-align: middle;
}
body.ts-thirdparty-events .ts-events-entry-reference,
body.ts-thirdparty-events .ts-events-entry-time,
body.ts-thirdparty-events .ts-events-entry-status {
	position: static !important;
	float: none !important;
	margin: 0 !important;
	color: #64748b;
	font-size: 12px;
}
body.ts-thirdparty-events .ts-events-entry-reference { grid-column: 2; grid-row: 2; }
body.ts-thirdparty-events .ts-events-entry-time { grid-column: 3; grid-row: 2; }
body.ts-thirdparty-events .ts-events-entry-status { grid-column: 4; grid-row: 2; }
body.ts-thirdparty-events .ts-events-entry-reference > a:first-child { color: #4f46e5; font-weight: 650; }
body.ts-thirdparty-events .ts-events-entry-reference .infobox-action { display: none; }
body.ts-thirdparty-events .ts-events-entry-reference .timeline-btn2 {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 28px;
	height: 28px;
	margin-left: 5px;
	padding: 0 !important;
	border-radius: 6px;
}
body.ts-thirdparty-events .ts-events-entry-status .badge-status {
	min-height: 22px;
	padding: 2px 7px;
	border-radius: 999px;
	background: #eef1f6;
	color: #64748b;
	font-size: 10px;
}

@media (max-width: 1100px) {
	body.ts-thirdparty-events .ts-events-toolbar { grid-template-columns: minmax(0, 1fr); }
	body.ts-thirdparty-events .ts-events-view-switch { justify-self: start; }
	body.ts-thirdparty-events .ts-events-filter-form { width: 100%; }
	body.ts-thirdparty-events .ts-events-filter-form .liste_titre { grid-template-columns: minmax(220px, 1fr) minmax(180px, .8fr) minmax(220px, .9fr) 132px; }
	body.ts-thirdparty-events .ts-events-filter-form th:nth-child(1) { grid-column: 4; grid-row: 1; }
}
@media (max-width: 760px) {
	body.ts-thirdparty-events .ts-events-summary { grid-template-columns: minmax(0, 1fr); }
	body.ts-thirdparty-events .ts-events-summary-item:nth-child(n) { padding-left: 2px; padding-right: 2px; }
	body.ts-thirdparty-events .ts-events-summary-item:nth-child(n+2) { border-top: 1px solid #edf0f4; }
	body.ts-thirdparty-events .ts-events-pagehead { align-items: flex-start; flex-wrap: wrap; padding: 18px 16px 14px; }
	body.ts-thirdparty-events .ts-events-pagehead .ts-pagehead-actions { width: 100%; }
	body.ts-thirdparty-events .ts-events-create { width: 100%; }
	body.ts-thirdparty-events .ts-events-toolbar { padding: 0 16px 16px; }
	body.ts-thirdparty-events .ts-events-filter-form .liste_titre { grid-template-columns: minmax(0, 1fr); }
	body.ts-thirdparty-events .ts-events-filter-form th:nth-child(5),
	body.ts-thirdparty-events .ts-events-filter-form th:nth-child(2),
	body.ts-thirdparty-events .ts-events-filter-form th:nth-child(4),
	body.ts-thirdparty-events .ts-events-filter-form th:nth-child(1) { grid-column: 1; }
	body.ts-thirdparty-events .ts-events-filter-form th:nth-child(5) { grid-row: 1; }
	body.ts-thirdparty-events .ts-events-filter-form th:nth-child(2) { grid-row: 2; }
	body.ts-thirdparty-events .ts-events-filter-form th:nth-child(4) { grid-row: 3; }
	body.ts-thirdparty-events .ts-events-filter-form th:nth-child(1) { grid-row: 4; }
	body.ts-thirdparty-events .ts-events-filter-form th:nth-child(1) {
		display: grid !important;
		grid-template-columns: minmax(0, 1fr) 40px;
		gap: 8px;
		width: 100%;
	}
	body.ts-thirdparty-events .ts-events-filter-form th:nth-child(1) button.button_search,
	body.ts-thirdparty-events .ts-events-filter-form th:nth-child(1) button.button_removefilter {
		width: 100% !important;
		min-width: 0;
		margin: 0 !important;
	}
	body.ts-thirdparty-events .ts-events-timeline { padding-right: 16px; padding-left: 44px; }
	body.ts-thirdparty-events .ts-events-timeline::before { left: 24px; }
	body.ts-thirdparty-events .ts-events-entry::before { left: -26px; }
	body.ts-thirdparty-events .ts-events-entry .timeline-item { grid-template-columns: minmax(0, 1fr) auto; }
	body.ts-thirdparty-events .ts-events-entry-title { grid-column: 1 / -1; }
	body.ts-thirdparty-events .ts-events-entry-author { grid-column: 1 / -1; grid-row: 2; }
	body.ts-thirdparty-events .ts-events-entry-reference { grid-column: 1; grid-row: 3; }
	body.ts-thirdparty-events .ts-events-entry-time { grid-column: 2; grid-row: 3; }
	body.ts-thirdparty-events .ts-events-entry-status { grid-column: 3; grid-row: 3; }
}

@media (max-width: 900px) {
	body.ts-partnership-form-page .fiche { padding: 18px 16px 34px !important; }
	body.ts-partnership-form-page .ts-partnership-field-grid { gap: 22px 20px; }
}
@media (max-width: 700px) {
	body.ts-partnership-form-page .fiche { padding: 16px 12px 28px !important; }
	body.ts-partnership-form-page .ts-partnership-title { font-size: 24px; }
	body.ts-partnership-form-page .ts-partnership-info { align-items: flex-start; }
	body.ts-partnership-form-page .ts-partnership-card { padding: 18px !important; }
	body.ts-partnership-form-page .ts-partnership-field-grid { grid-template-columns: minmax(0, 1fr); }
	body.ts-partnership-form-page .ts-partnership-actions { flex-wrap: wrap; }
	body.ts-partnership-form-page .ts-partnership-actions input.button { flex: 1 1 180px; }
}

/* Filters promoted into the record-tab toolbar (Events/Agenda, Contacts).
   These reuse .ts-column-filter-control, which is a stacked grid built for the
   Filters disclosure -- inside the toolbar that stacked the label over the
   control and broke a date range onto two lines, pushing its picker buttons
   over the neighbouring field. Lay them out as one row at the shared 40px
   control height instead. Scoped to controls carrying both classes, so the
   disclosure panel and the main list pages keep their own layout. */
.ts-filter-surface .ts-column-filter-control.ts-toolbar-filter {
	display: flex;
	flex-direction: row;
	align-items: center;
	gap: 8px;
	height: 40px;
	min-height: 40px;
	padding: 0 10px;
	border: 1px solid var(--c-line);
	border-radius: var(--r);
	background: var(--c-surface);
	overflow: hidden;
}
.ts-filter-surface .ts-column-filter-control.ts-toolbar-filter:focus-within {
	border-color: var(--c-accent);
}
.ts-filter-surface .ts-column-filter-control.ts-toolbar-filter > .ts-column-filter-label {
	/* The disclosure-panel rule lays this label out full width above its control.
	   In a row it must size to its text, or it consumes the slot and collapses
	   the field it names to zero. */
	flex: none;
	display: inline-block;
	width: auto;
	min-width: 0;
	max-width: none;
	font-size: 12px;
	font-weight: 600;
	text-transform: none;
	color: var(--c-ink-subtle);
	white-space: nowrap;
}
.ts-filter-surface .ts-column-filter-control.ts-toolbar-filter .divfordateinput {
	display: flex;
	align-items: center;
	gap: 4px;
	min-width: 0;
}
.ts-filter-surface .ts-column-filter-control.ts-toolbar-filter input[type="text"] {
	width: 74px;
	min-width: 0;
	height: 28px;
	padding: 0 6px;
	border: 1px solid var(--c-line);
	border-radius: 6px;
	background: var(--c-surface);
	font-size: 13px;
	text-align: center;
}
.ts-filter-surface .ts-column-filter-control.ts-toolbar-filter img.ui-datepicker-trigger {
	width: 15px;
	height: 15px;
	flex: none;
	cursor: pointer;
	opacity: .6;
}
.ts-filter-surface .ts-column-filter-control.ts-toolbar-filter img.ui-datepicker-trigger:hover { opacity: 1; }
/* The select carries Dolibarr's own max-width utilities; the toolbar slot is
   the authority on width here. */
.ts-filter-surface .ts-column-filter-control.ts-toolbar-filter .select2-container {
	flex: 1 1 auto;
	width: auto !important;
	min-width: 0 !important;
	max-width: none !important;
}
.ts-filter-surface .ts-column-filter-control.ts-toolbar-filter .select2-selection {
	min-height: 28px;
	height: 28px;
	border: 1px solid var(--c-line);
	border-radius: 6px;
	background: var(--c-surface);
}
.ts-filter-surface .ts-column-filter-control.ts-toolbar-filter .select2-selection__rendered {
	line-height: 26px;
	font-size: 13px;
	padding-left: 6px;
}
.ts-filter-surface .ts-column-filter-control.ts-toolbar-filter .select2-selection__arrow { height: 26px; }
/* A date range needs both inputs plus their pickers; the enum next to it does not. */
.ts-filter-surface .ts-column-filter-control.ts-toolbar-filter-1 {
	flex-basis: 300px;
	width: 300px;
	min-width: 300px;
}
.ts-filter-surface .ts-column-filter-control.ts-toolbar-filter-2 {
	flex-basis: 230px;
	width: 230px;
	min-width: 230px;
}
/* Dolibarr's view switch lived in a title table that is now empty. */
table.table-fiche-title.ts-events-native-title-source { display: none !important; }

/* ==========================================================================
   Display > Skin and colors (admin/ihm.php?mode=template)

   Route-gated by composeDisplaySettings() in modern.js. Every selector below
   is scoped to body.ts-display-settings, so no other admin screen is touched.
   ========================================================================== */
body.ts-display-settings .ts-settings-shell {
	display: grid;
	gap: 20px;
	min-width: 0;
}
body.ts-display-settings .ts-settings-card {
	min-width: 0;
	border: 1px solid var(--c-hairline);
	border-radius: var(--r-lg);
	background: var(--c-surface);
	box-shadow: var(--sh-sm);
	overflow: hidden;
}
body.ts-display-settings .ts-settings-card-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	padding: 16px 20px;
	border-bottom: 1px solid var(--c-hairline);
	background: var(--c-sunken);
}
body.ts-display-settings .ts-settings-card-title {
	margin: 0;
	font-size: 0.9375rem;
	font-weight: 650;
	color: var(--c-accent);
}
body.ts-display-settings .ts-settings-card-aside {
	flex: 0 0 auto;
	font-size: 0.8125rem;
	white-space: nowrap;
}
body.ts-display-settings .ts-settings-card-aside a { color: var(--c-accent); text-decoration: none; }
body.ts-display-settings .ts-settings-card-aside a:hover { text-decoration: underline; }

/* ---- skin picker ---- */
body.ts-display-settings .ts-theme-grid {
	/* Flex rather than grid: the skin count is whatever is installed, and a
	   trailing partial row should centre rather than strand itself at column 1. */
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 16px;
	padding: 20px;
}
body.ts-display-settings .ts-theme-card { flex: 0 1 158px; }
body.ts-display-settings .ts-theme-card {
	display: flex !important;
	flex-direction: column;
	align-items: center;
	gap: 8px;
	min-width: 0;
	padding: 10px;
	border: 1px solid var(--c-hairline);
	border-radius: var(--r);
	background: var(--c-surface);
	text-align: center;
}
body.ts-display-settings .ts-theme-card:hover { border-color: var(--c-border); }
body.ts-display-settings .ts-theme-card-selected {
	border-color: var(--c-accent);
	box-shadow: 0 0 0 2px var(--c-accent-soft);
}
/* One thumbnail ratio for every skin, whatever each theme ships. */
body.ts-display-settings .ts-theme-card img.img-skinthumb {
	display: block;
	width: 100%;
	height: 92px;
	margin: 0 !important;
	border: 1px solid var(--c-hairline) !important;
	border-radius: 6px;
	object-fit: cover;
	object-position: top center;
	box-shadow: none !important;
}
body.ts-display-settings .ts-theme-card br { display: none; }
body.ts-display-settings .ts-theme-card input[type="radio"] { margin: 0; }
body.ts-display-settings .ts-theme-card label {
	font-size: 0.8125rem;
	font-weight: 550;
	color: var(--c-ink-2);
	cursor: pointer;
}
body.ts-display-settings .ts-theme-card-selected label { color: var(--c-accent-ink); }

/* ---- general preferences ---- */
body.ts-display-settings .ts-settings-grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 0 32px;
	padding: 4px 20px 20px;
	border-top: 1px solid var(--c-hairline);
}
body.ts-display-settings .ts-setting {
	display: grid;
	grid-template-columns: minmax(0, 150px) minmax(0, 1fr);
	align-items: center;
	gap: 16px;
	min-height: 64px;
	padding: 8px 0;
	border-bottom: 1px solid var(--c-hairline);
}
body.ts-display-settings .ts-settings-grid .ts-setting:nth-last-child(-n + 2) { border-bottom: 0; }
body.ts-display-settings .ts-setting-label {
	font-size: 0.8125rem;
	font-weight: 550;
	color: var(--c-ink-2);
}
body.ts-display-settings .ts-setting-control {
	display: flex;
	align-items: center;
	gap: 10px;
	min-width: 0;
}
body.ts-display-settings .ts-setting-control select { max-width: 100%; }
body.ts-display-settings .ts-setting-control .select2-container {
	width: min(100%, 240px) !important;
	min-width: 0 !important;
}
body.ts-display-settings .ts-setting-control .select2-selection { min-height: 40px; }
body.ts-display-settings .ts-setting-control .select2-selection__rendered { line-height: 38px; }
body.ts-display-settings .ts-setting-control .select2-selection__arrow { height: 38px; }
/* Dolibarr's AJAX switch ships both states; only the live one should show. */
body.ts-display-settings .ts-setting-control span.valignmiddle { display: inline-flex; align-items: center; }

/* ---- colour fields ---- */
body.ts-display-settings .ts-color-grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 0 32px;
	padding: 4px 20px 12px;
}
body.ts-display-settings .ts-color-item {
	display: grid;
	/* A fixed control track, so the swatch and hex field share one x down the
	   column instead of drifting with each label's hint length. */
	grid-template-columns: minmax(0, 1fr) 332px;
	align-items: center;
	gap: 12px;
	min-height: 52px;
	padding: 8px 0;
	border-bottom: 1px solid var(--c-hairline);
}
body.ts-display-settings .ts-color-grid .ts-color-item:nth-last-child(-n + 2) { border-bottom: 0; }
body.ts-display-settings .ts-color-label {
	font-size: 0.8125rem;
	font-weight: 550;
	line-height: 1.35;
	color: var(--c-ink-2);
}
body.ts-display-settings .ts-color-control {
	/* Fixed tracks, not flex: the default hints differ in length, and on flex
	   that pushed every row's swatch and field to a different x. */
	display: grid;
	grid-template-columns: 38px 118px minmax(0, 1fr) 16px;
	align-items: center;
	gap: 10px;
	min-width: 0;
}
/* Every cell is pinned to row 1: the picker markup follows the input in the
   DOM, so assigning it an earlier column alone wrapped it onto a second row. */
body.ts-display-settings .ts-color-control span.jPicker { grid-column: 1; grid-row: 1; }
body.ts-display-settings .ts-color-control input[id^="colorpicker"] { grid-column: 2; grid-row: 1; }
body.ts-display-settings .ts-color-control .ts-color-default { grid-column: 3; grid-row: 1; }
body.ts-display-settings .ts-color-control .classfortooltip { grid-column: 4; grid-row: 1; }
/* jPicker renders the swatch as a bound container next to its input. */
/* jPicker already renders a live swatch; it just needs a size and to sit
   before the hex field, the way the value reads. */
body.ts-display-settings .ts-color-control span.jPicker {
	flex: 0 0 auto;
	margin: 0 !important;
}
body.ts-display-settings .ts-color-control span.jPicker span.Icon {
	display: block !important;
	width: 38px !important;
	height: 36px !important;
	border: 1px solid var(--c-border);
	border-radius: 6px;
	background-image: none !important;
	overflow: hidden;
}
body.ts-display-settings .ts-color-control span.jPicker span.Color {
	display: block !important;
	width: 100% !important;
	height: 100% !important;
	border: 0 !important;
	background-image: none !important;
}
body.ts-display-settings .ts-color-control span.jPicker span.Alpha { display: none !important; }
/* Image is jPicker's click target -- hiding it made the swatch inert and took
   the picker away. Keep it, sized over the swatch with its sprite dropped, so
   it stays the trigger while the colour underneath shows through. */
body.ts-display-settings .ts-color-control span.jPicker span.Image {
	display: block !important;
	width: 100% !important;
	height: 100% !important;
	background-image: none !important;
	background-color: transparent !important;
	border: 0 !important;
	cursor: pointer;
}
body.ts-display-settings .ts-color-control span.jPicker span.Icon { cursor: pointer; }
/* Dolibarr emits both halves of its AJAX switch and hides the inactive one with
   .hideobject; that rule is not reaching here, so both were rendering. */
body.ts-display-settings .ts-setting-control .hideobject { display: none !important; }
body.ts-display-settings .ts-color-control input[type="text"] {
	width: 118px;
	height: 36px;
	padding: 0 10px;
	border: 1px solid var(--c-border);
	border-radius: 6px;
	background: var(--c-surface);
	font-size: 0.8125rem;
	font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
}
body.ts-display-settings .ts-color-default {
	font-size: 0.75rem;
	color: var(--c-ink-subtle);
	white-space: nowrap;
}
/* Dolibarr bolds and link-colours the default value; it is a hint, not a link. */
body.ts-display-settings .ts-color-control b,
body.ts-display-settings .ts-color-control strong,
body.ts-display-settings .ts-color-default-value {
	font-weight: 500 !important;
	color: var(--c-ink-subtle) !important;
}
body.ts-display-settings .ts-color-item .ts-color-control > img,
body.ts-display-settings .ts-setting-control > img {
	flex: 0 0 auto;
	opacity: .55;
}
body.ts-display-settings .ts-results-footer {
	padding: 12px 20px;
	border-top: 1px solid var(--c-hairline);
	font-size: 0.8125rem;
	color: var(--c-ink-subtle);
}

/* ---- action footer ---- */
body.ts-display-settings .ts-settings-actions {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 12px;
	margin: 24px 0 8px;
}
body.ts-display-settings .ts-settings-action {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	height: 42px;
	min-width: 108px;
	padding: 0 20px !important;
	border-radius: var(--r);
	font-size: 0.875rem;
	font-weight: 600;
	cursor: pointer;
}
body.ts-display-settings input.ts-settings-action-primary {
	border: 1px solid var(--c-btn-action, var(--c-accent)) !important;
	background: var(--c-btn-action, var(--c-accent)) !important;
	color: var(--c-btn-action-text, #fff) !important;
}
body.ts-display-settings input.ts-settings-action-primary:hover { filter: brightness(1.06); }
body.ts-display-settings .ts-settings-action-secondary,
body.ts-display-settings .ts-settings-actions a.butAction {
	border: 1px solid var(--c-border) !important;
	background: var(--c-surface) !important;
	color: var(--c-ink-2) !important;
}

@media only screen and (max-width: 1100px) {
	body.ts-display-settings .ts-settings-grid,
	body.ts-display-settings .ts-color-grid { grid-template-columns: minmax(0, 1fr); gap: 0; }
	body.ts-display-settings .ts-settings-grid .ts-setting:nth-last-child(-n + 2),
	body.ts-display-settings .ts-color-grid .ts-color-item:nth-last-child(-n + 2) {
		border-bottom: 1px solid var(--c-hairline);
	}
	body.ts-display-settings .ts-settings-grid .ts-setting:last-child,
	body.ts-display-settings .ts-color-grid .ts-color-item:last-child { border-bottom: 0; }
}
@media only screen and (max-width: 700px) {
	body.ts-display-settings .ts-theme-grid { grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); gap: 12px; padding: 16px; }
	body.ts-display-settings .ts-setting,
	body.ts-display-settings .ts-color-item { grid-template-columns: minmax(0, 1fr); gap: 8px; align-items: start; }
	body.ts-display-settings .ts-settings-card-head { flex-wrap: wrap; gap: 8px; }
	body.ts-display-settings .ts-settings-actions { flex-wrap: wrap; }
	body.ts-display-settings .ts-settings-action { flex: 1 1 140px; }
}

/* ==========================================================================
   Third party > Customer tab, right-hand summary column (comm/card.php)
   Route-gated by composeCustomerSummary(); scoped to body.ts-customer-summary.
   ========================================================================== */
body.ts-customer-summary .ts-cust-stack { display: grid; gap: 16px; min-width: 0; }
body.ts-customer-summary div.fichehalfright > br,
body.ts-customer-summary div.fichehalfright > .underbanner { display: none; }

/* ---- stat cards ---- */
body.ts-customer-summary .ts-kpi-grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 16px;
	min-width: 0;
}
body.ts-customer-summary a.ts-kpi-card {
	display: block !important;
	min-width: 0;
	padding: 16px 18px;
	border: 1px solid var(--c-hairline);
	border-radius: var(--r-lg);
	background: var(--c-surface);
	box-shadow: var(--sh-sm);
	text-decoration: none !important;
}
body.ts-customer-summary a.ts-kpi-card:hover { border-color: var(--c-accent); }
body.ts-customer-summary a.ts-kpi-card .boxstats {
	display: grid !important;
	grid-template-columns: 44px minmax(0, 1fr);
	grid-template-rows: auto auto;
	align-items: center;
	gap: 2px 14px;
	width: auto !important;
	min-height: 0 !important;
	padding: 0 !important;
	border: 0 !important;
	background: none !important;
	text-align: left;
}
body.ts-customer-summary a.ts-kpi-card .ts-kpi-icon {
	display: inline-flex;
	grid-column: 1;
	grid-row: 1 / span 2;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	border-radius: 10px;
	background: var(--c-accent-soft);
	color: var(--c-accent);
}
body.ts-customer-summary a.ts-kpi-card .ts-kpi-icon [class*="fa-"] {
	color: var(--c-accent) !important;
	font-size: 17px !important;
}
body.ts-customer-summary a.ts-kpi-card .ts-kpi-label {
	grid-column: 2;
	grid-row: 1;
	font-size: 0.8125rem;
	font-weight: 550;
	color: var(--c-ink-2);
}
body.ts-customer-summary a.ts-kpi-card .ts-kpi-value {
	grid-column: 2;
	grid-row: 2;
	font-size: 1.375rem;
	font-weight: 700;
	color: var(--c-ink);
}
body.ts-customer-summary a.ts-kpi-card br { display: none; }

/* ---- record list cards ---- */
body.ts-customer-summary .ts-latest-card {
	min-width: 0;
	border: 1px solid var(--c-hairline);
	border-radius: var(--r-lg);
	background: var(--c-surface);
	box-shadow: var(--sh-sm);
	overflow: hidden;
}
body.ts-customer-summary .ts-latest-head {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 14px 18px;
	border-bottom: 1px solid var(--c-hairline);
}
body.ts-customer-summary .ts-latest-title {
	flex: 1 1 auto;
	min-width: 0;
	font-size: 0.9375rem;
	font-weight: 650;
	color: var(--c-ink);
}
body.ts-customer-summary .ts-latest-aside { flex: 0 0 auto; font-size: 0.8125rem; }
body.ts-customer-summary .ts-latest-aside a { color: var(--c-accent); text-decoration: none; }
body.ts-customer-summary .ts-latest-aside a:hover { text-decoration: underline; }
body.ts-customer-summary .ts-latest-aside .badge {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 22px;
	height: 22px;
	margin-left: 6px;
	padding: 0 7px;
	border-radius: 999px;
	background: var(--c-sunken);
	color: var(--c-ink-2);
	font-size: 0.75rem;
	font-weight: 600;
}
body.ts-customer-summary .ts-latest-card .div-table-responsive-no-min,
body.ts-customer-summary .ts-latest-card .div-table-responsive { margin: 0 !important; overflow-x: auto; }
body.ts-customer-summary table.ts-latest-table {
	width: 100%;
	margin: 0 !important;
	border: 0 !important;
	background: transparent !important;
}
body.ts-customer-summary table.ts-latest-table tr.oddeven,
body.ts-customer-summary table.ts-latest-table tr.impair,
body.ts-customer-summary table.ts-latest-table tr.pair { background: transparent !important; }
body.ts-customer-summary table.ts-latest-table tr + tr > td { border-top: 1px solid var(--c-hairline); }
body.ts-customer-summary table.ts-latest-table td {
	padding: 12px 14px !important;
	border-bottom: 0 !important;
	font-size: 0.8125rem;
	vertical-align: middle;
}
body.ts-customer-summary table.ts-latest-table td:first-child { padding-left: 18px !important; }
body.ts-customer-summary table.ts-latest-table td:last-child { padding-right: 18px !important; text-align: right; }
body.ts-customer-summary table.ts-latest-table a { text-decoration: none; }
body.ts-customer-summary table.ts-latest-table td [class*="fa-"] { margin-right: 6px; opacity: .85; }
/* Dolibarr's status label, as a pill. */
body.ts-customer-summary table.ts-latest-table span.badge-status,
body.ts-customer-summary table.ts-latest-table .badge {
	display: inline-flex;
	align-items: center;
	height: 24px;
	padding: 0 10px;
	border-radius: 999px;
	font-size: 0.75rem;
	font-weight: 600;
	white-space: nowrap;
}

@media only screen and (max-width: 1100px) {
	body.ts-customer-summary .ts-kpi-grid { gap: 12px; }
}
@media only screen and (max-width: 700px) {
	body.ts-customer-summary .ts-kpi-grid { grid-template-columns: minmax(0, 1fr); }
	body.ts-customer-summary a.ts-kpi-card { padding: 14px; }
	body.ts-customer-summary table.ts-latest-table td { padding: 10px !important; }
}

/* Corrections after measuring the composed column. */
/* The stat anchor carries Dolibarr's own thumbstat width; the grid cell is the
   authority here, and the label span is hidden by the native boxstats rules. */
body.ts-customer-summary a.ts-kpi-card {
	width: 100% !important;
	max-width: none !important;
	min-width: 0 !important;
	box-sizing: border-box;
}
body.ts-customer-summary a.ts-kpi-card .ts-kpi-label,
body.ts-customer-summary a.ts-kpi-card .ts-kpi-label > span {
	display: inline !important;
	visibility: visible !important;
	overflow: visible !important;
	width: auto !important;
	height: auto !important;
	font-size: 0.8125rem !important;
	color: var(--c-ink-2) !important;
}
body.ts-customer-summary a.ts-kpi-card .ts-kpi-value {
	display: block !important;
	width: auto !important;
}
/* Let the record tables size to their content and scroll inside the card
   rather than clipping refs and stacking dates one character per line. */
body.ts-customer-summary table.ts-latest-table {
	table-layout: auto !important;
	min-width: 100%;
}
body.ts-customer-summary table.ts-latest-table td { white-space: nowrap; }
body.ts-customer-summary table.ts-latest-table td:first-child { width: 38%; }
body.ts-customer-summary table.ts-latest-table td a { white-space: nowrap; }

/* Events/Agenda toolbar: target proportions -- 44px controls, 12px gaps, the
   search taking the slack, Date and Type at fixed widths, reset only when it
   has something to clear. */
body.ts-thirdparty-events .ts-events-toolbar { gap: 12px; padding: 0 24px 20px; }
body.ts-thirdparty-events .ts-events-filter-form .liste_titre {
	grid-template-columns: minmax(260px, 1fr) 190px 210px max-content;
	gap: 12px;
}
body.ts-thirdparty-events .ts-events-filter-form th { height: 44px !important; }
body.ts-thirdparty-events .ts-events-view-switch { height: 44px; }
body.ts-thirdparty-events .ts-events-search-control,
body.ts-thirdparty-events .ts-events-date-control { height: 44px; }
body.ts-thirdparty-events .ts-events-search-input { height: 42px !important; font-size: 0.875rem; }
body.ts-thirdparty-events .ts-events-filter-form .select2-container { height: 44px; }
body.ts-thirdparty-events .ts-events-filter-form .select2-selection--single {
	height: 44px !important;
	min-height: 44px !important;
}
body.ts-thirdparty-events .ts-events-filter-form .select2-selection__rendered {
	height: 42px !important;
	line-height: 42px !important;
	font-size: 0.875rem !important;
}
body.ts-thirdparty-events .ts-events-filter-form .select2-selection__arrow { height: 42px !important; }
body.ts-thirdparty-events .ts-events-filter-form button.button_search,
body.ts-thirdparty-events .ts-events-filter-form button.button_removefilter {
	height: 44px !important;
	padding: 0 16px !important;
	font-size: 0.875rem;
}
/* Reset carries a word now, so it is no longer a bare square. */
body.ts-thirdparty-events .ts-events-filter-form button.button_removefilter {
	width: auto !important;
	gap: 8px;
}
body.ts-thirdparty-events .ts-events-filter-form button.button_removefilter[hidden] { display: none !important; }
body.ts-thirdparty-events .ts-events-date-order { margin-left: auto; font-size: 11px; opacity: .6; }
body.ts-thirdparty-events .ts-events-date-control { justify-content: flex-start !important; gap: 10px; }
/* Segmented view switch: two equal, clearly-stated views. */
body.ts-thirdparty-events .ts-events-view-option {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 38px;
	height: 38px;
	border-radius: 7px;
}

/* ==========================================================================
   Shared COMMAND settings surface -- every Dolibarr admin screen composed by
   composeAdminSettings(). Scoped to body.ts-settings-page.
   ========================================================================== */
/* List enhancement runs before the settings composer on some admin routes.
   Once the native table has become a semantic settings card, its generated
   list-card ancestors are only duplicate visual chrome. Keep those structural
   wrappers for runtime compatibility, but make them layout-transparent so the
   real settings card sits directly on the page surface. */
body:is(.ts-settings-page, .ts-display-settings) .ts-list-composition:has(.ts-settings-card),
body:is(.ts-settings-page, .ts-display-settings) .ts-list-card:has(.ts-settings-card),
body:is(.ts-settings-page, .ts-display-settings) .div-table-responsive:has(.ts-settings-card),
body:is(.ts-settings-page, .ts-display-settings) .div-table-responsive-no-min:has(.ts-settings-card) {
	background: transparent !important;
	border: 0 !important;
	border-radius: 0 !important;
	box-shadow: none !important;
	overflow: visible !important;
}
body.ts-settings-page .ts-settings-card {
	min-width: 0;
	margin: 0 0 20px;
	border: 1px solid var(--c-hairline);
	border-radius: var(--r-lg);
	background: var(--c-surface);
	box-shadow: var(--sh-sm);
	overflow: hidden;
}
body.ts-settings-page .ts-settings-card-head {
	display: grid;
	grid-template-columns: minmax(0, 420px) minmax(0, 1fr);
	align-items: center;
	gap: 18px;
	padding: 15px 20px;
	border-bottom: 1px solid var(--c-hairline);
	background: var(--c-sunken);
}
body.ts-settings-page .ts-settings-card-title {
	display: flex;
	align-items: center;
	gap: 9px;
	margin: 0;
	font-size: 0.9375rem;
	font-weight: 650;
	color: var(--c-accent);
}
body.ts-settings-page .ts-settings-card-title [class*="fa-"] { color: var(--c-accent) !important; }
body.ts-settings-page .ts-settings-card-aside { flex: 0 0 auto; font-size: 0.8125rem; color: var(--c-ink-subtle); }
/* Native settings title rows contain actual column headings. Keep a second
   heading (for example “Late warning after”) above the same value axis as the
   controls instead of letting flexbox push it to the far edge of the card. */
body.ts-settings-page .ts-settings-card-head:not(:has(.ts-settings-card-aside)) .ts-settings-card-title { grid-column: 1 / -1; }
body.ts-settings-page .ts-settings-grid { display: grid; grid-template-columns: minmax(0, 1fr); }
body.ts-settings-page .ts-setting {
	display: grid;
	grid-template-columns: minmax(0, 420px) minmax(0, 1fr);
	align-items: center;
	gap: 18px;
	padding: 12px 20px;
	border-bottom: 1px solid var(--c-hairline);
}
body.ts-settings-page .ts-settings-grid .ts-setting:last-child { border-bottom: 0; }
body.ts-settings-page .ts-setting-label {
	display: flex;
	align-items: center;
	gap: 8px;
	flex-wrap: wrap;
	font-size: 0.8125rem;
	font-weight: 550;
	line-height: 1.4;
	color: var(--c-ink-2);
}
body.ts-settings-page .ts-setting-label [class*="fa-info"] { opacity: .55; }
body.ts-settings-page .ts-setting-control {
	display: flex;
	align-items: center;
	gap: 10px;
	min-width: 0;
}
/* Width bands, so a toggle does not occupy the same room as a URL field. */
body.ts-settings-page .ts-setting-control.ts-control-compact { max-width: 120px; }
body.ts-settings-page .ts-setting-control.ts-control-medium { max-width: 320px; }
body.ts-settings-page .ts-setting-control.ts-control-wide { max-width: 420px; }
body.ts-settings-page .ts-setting-control.ts-control-full { max-width: 100%; }

/* Limits/Precision configuration prints live examples as loose inline nodes.
   composeLimitsExamples() retains those nodes and gives them the same calm,
   compact settings surface used throughout COMMAND. */
body.ts-limits-examples-page .ts-limits-examples-card {
	margin: 20px 0 0;
	border: 1px solid var(--c-hairline);
	border-radius: var(--r-lg);
	background: var(--c-surface);
	box-shadow: var(--sh-sm);
	overflow: hidden;
}
body.ts-limits-examples-page .ts-limits-examples-head {
	display: flex;
	align-items: center;
	min-height: 62px;
	padding: 0 24px;
	border-bottom: 1px solid var(--c-hairline);
}
body.ts-limits-examples-page .ts-limits-examples-title {
	margin: 0;
	font-size: 1.125rem;
	font-weight: 650;
	line-height: 1.25;
	color: var(--c-ink);
}
body.ts-limits-examples-page .ts-limits-examples-body {
	display: grid;
	gap: 8px;
	padding: 18px 24px 20px;
}
body.ts-limits-examples-page .ts-limits-example-line {
	display: flex;
	align-items: baseline;
	flex-wrap: wrap;
	gap: 0 5px;
	min-width: 0;
	font-size: .8125rem;
	line-height: 1.55;
	color: var(--c-ink-subtle);
}
body.ts-limits-examples-page .ts-limits-example-line > * { min-width: 0; }
body.ts-limits-examples-page .ts-limits-example-line b,
body.ts-limits-examples-page .ts-limits-example-line strong {
	font-weight: 650;
	color: var(--c-ink-2);
}
@media only screen and (max-width: 600px) {
	body.ts-limits-examples-page .ts-limits-examples-head { min-height: 56px; padding: 0 16px; }
	body.ts-limits-examples-page .ts-limits-examples-body { padding: 16px; gap: 10px; }
}

/* Constants is the one admin editor whose native table has four meaningful
   editable columns. Treat those columns as a real compact data grid instead
   of squeezing every field into the generic label/control setting row. */
body.ts-settings-page .ts-admin-constants-card .ts-settings-card-head,
body.ts-settings-page .ts-admin-constants-card .ts-admin-const-row {
	display: grid;
	grid-template-columns: minmax(240px, 1.35fr) minmax(150px, .62fr) minmax(260px, 1fr) minmax(118px, .5fr) 32px;
	column-gap: 12px;
}
body.ts-settings-page .ts-admin-constants-card .ts-settings-card-head {
	align-items: center;
	justify-content: unset;
}
body.ts-settings-page .ts-admin-constants-card .ts-settings-card-title,
body.ts-settings-page .ts-admin-constants-card .ts-settings-card-aside {
	min-width: 0;
	margin: 0;
}
body.ts-settings-page .ts-admin-constants-card .ts-settings-card-aside {
	font-weight: 600;
	white-space: nowrap;
}
body.ts-settings-page .ts-admin-constants-card .ts-admin-const-row {
	align-items: center;
	gap: 12px;
	padding: 12px 20px;
}
body.ts-settings-page .ts-admin-constants-card .ts-admin-const-row .ts-setting-label {
	grid-column: 1;
	min-width: 0;
	font-weight: 600;
	overflow-wrap: anywhere;
}
body.ts-settings-page .ts-admin-constants-card .ts-admin-const-row .ts-setting-control {
	display: contents;
}
body.ts-settings-page .ts-admin-constants-card .ts-admin-const-row input:not([type="hidden"]) {
	min-width: 0;
	width: 100% !important;
	max-width: none !important;
}
body.ts-settings-page .ts-admin-constants-card .ts-admin-const-value { grid-column: 2; }
body.ts-settings-page .ts-admin-constants-card .ts-admin-const-comment { grid-column: 3; }
body.ts-settings-page .ts-admin-constants-card .ts-admin-const-date {
	grid-column: 4;
	font-size: .8125rem;
	line-height: 1.35;
	color: var(--c-ink-subtle);
}
body.ts-settings-page .ts-admin-constants-card .ts-admin-const-remove {
	grid-column: 5;
	justify-self: center;
	width: 16px !important;
	height: 16px;
}
body.ts-settings-page .ts-admin-constants-card .ts-admin-const-add {
	grid-column: 4;
	justify-self: start;
	width: 88px !important;
	min-width: 88px !important;
	max-width: 88px !important;
}
@media only screen and (max-width: 900px) {
	body.ts-settings-page .ts-admin-constants-card .ts-settings-card-head { display: none; }
	body.ts-settings-page .ts-admin-constants-card .ts-admin-const-row {
		grid-template-columns: minmax(150px, .8fr) minmax(0, 1fr);
	}
	body.ts-settings-page .ts-admin-constants-card .ts-admin-const-row .ts-setting-label { grid-column: 1; }
	body.ts-settings-page .ts-admin-constants-card .ts-admin-const-value { grid-column: 2; }
	body.ts-settings-page .ts-admin-constants-card .ts-admin-const-comment { grid-column: 2; }
	body.ts-settings-page .ts-admin-constants-card .ts-admin-const-date { grid-column: 2; }
	body.ts-settings-page .ts-admin-constants-card .ts-admin-const-remove { grid-column: 2; justify-self: start; }
	body.ts-settings-page .ts-admin-constants-card .ts-admin-const-add { grid-column: 2; }
}
@media only screen and (max-width: 600px) {
	body.ts-settings-page .ts-admin-constants-card .ts-admin-const-row { grid-template-columns: minmax(0, 1fr); }
	body.ts-settings-page .ts-admin-constants-card .ts-admin-const-row .ts-setting-label,
	body.ts-settings-page .ts-admin-constants-card .ts-admin-const-value,
	body.ts-settings-page .ts-admin-constants-card .ts-admin-const-comment,
	body.ts-settings-page .ts-admin-constants-card .ts-admin-const-date,
	body.ts-settings-page .ts-admin-constants-card .ts-admin-const-remove,
	body.ts-settings-page .ts-admin-constants-card .ts-admin-const-add { grid-column: 1; }
}

/* Widgets administration: the active-widget table is still emitted by
   Dolibarr as a seven-cell table. Keep its native links and ordering controls,
   but give the name/target/order/action columns deliberate space so names do
   not collapse into vertical strips. */
body.page-boxes .ts-boxes-active-table {
	width: 100%;
	table-layout: fixed;
	border-collapse: separate;
	border-spacing: 0;
	border: 1px solid var(--c-hairline);
	border-radius: var(--r-lg);
	overflow: hidden;
	background: var(--c-surface);
}
body.page-boxes .ts-boxes-section-title {
	margin: 28px 0 12px;
	font-size: 1.125rem;
	font-weight: 650;
	color: var(--c-ink);
}
body.page-boxes .ts-boxes-active-table tr {
	height: 48px !important;
	background: var(--c-surface) !important;
}
body.page-boxes .ts-boxes-active-table tr:hover { background: var(--c-accent-soft) !important; }
body.page-boxes .ts-boxes-active-table td {
	padding: 10px 14px !important;
	border-bottom: 1px solid var(--c-hairline) !important;
	vertical-align: middle !important;
	font-size: .8125rem;
	line-height: 1.35;
}
body.page-boxes .ts-boxes-active-table tr:last-child td { border-bottom: 0 !important; }
body.page-boxes .ts-boxes-active-table td:nth-child(1) { width: 34%; min-width: 260px; text-align: left !important; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
body.page-boxes .ts-boxes-active-table td:nth-child(2) { width: 28%; text-align: left !important; color: var(--c-ink-subtle); }
body.page-boxes .ts-boxes-active-table td:nth-child(3) { width: 5%; text-align: center; }
body.page-boxes .ts-boxes-active-table td:nth-child(4) { width: 13%; text-align: center; }
body.page-boxes .ts-boxes-active-table td:nth-child(5) { width: 10%; text-align: center; }
body.page-boxes .ts-boxes-active-table td:nth-child(6) { width: 6%; text-align: center; }
body.page-boxes .ts-boxes-active-table td:nth-child(7) { width: 6%; text-align: center; }
body.page-boxes .ts-boxes-active-table td:first-child > span[class*="fa-"],
body.page-boxes .ts-boxes-active-table td:first-child > img { margin-right: 8px; color: var(--c-accent); }
body.page-boxes .ts-boxes-active-table td a.reposition {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 30px;
	height: 30px;
	margin: 0 2px;
	border-radius: 7px;
	color: var(--c-accent);
	text-decoration: none;
}
body.page-boxes .ts-boxes-active-table td a.reposition:hover { background: var(--c-accent-soft); }
body.page-boxes .ts-boxes-active-table td a.reposition .pictodelete { color: var(--c-danger); }
body.page-boxes .ts-boxes-active-table td a.reposition span[class*="fa-caret"] { font-size: .8rem; }
body.page-boxes .ts-boxes-active-table td a.reposition span.pictodelete { font-size: .9rem; }
body.page-boxes .ts-settings-action-primary,
body.page-boxes input[name="save"] { background: var(--c-btn-action) !important; color: var(--c-btn-action-text) !important; border: 0 !important; }
@media only screen and (max-width: 900px) {
	body.page-boxes .ts-boxes-active-table { table-layout: auto; }
	body.page-boxes .ts-boxes-active-table td:nth-child(1) { min-width: 220px; white-space: normal; }
	body.page-boxes .ts-boxes-active-table td:nth-child(2) { min-width: 120px; }
}
@media only screen and (max-width: 600px) {
	body.page-boxes .ts-boxes-active-table td { padding: 9px 10px !important; }
	body.page-boxes .ts-boxes-active-table td:nth-child(2),
	body.page-boxes .ts-boxes-active-table td:nth-child(3) { display: none; }
	body.page-boxes .ts-boxes-active-table td:nth-child(1) { min-width: 0; width: 55%; }
	body.page-boxes .ts-boxes-active-table td:nth-child(4) { width: 20%; }
	body.page-boxes .ts-boxes-active-table td:nth-child(5) { width: 12%; }
	body.page-boxes .ts-boxes-active-table td:nth-child(6),
	body.page-boxes .ts-boxes-active-table td:nth-child(7) { width: 7%; }
}
body.ts-settings-page .ts-setting-control input[type="text"],
body.ts-settings-page .ts-setting-control input[type="number"],
body.ts-settings-page .ts-setting-control input[type="email"],
body.ts-settings-page .ts-setting-control input[type="url"],
body.ts-settings-page .ts-setting-control input[type="password"],
body.ts-settings-page .ts-setting-control textarea {
	width: 100%;
	min-width: 0;
	height: 40px;
	padding: 0 12px;
	border: 1px solid var(--c-border);
	border-radius: var(--r);
	background: var(--c-surface);
	font-size: 0.8125rem;
}
body.ts-settings-page .ts-setting-control textarea { height: auto; min-height: 80px; padding: 10px 12px; }
body.ts-settings-page .ts-setting-control.ts-control-compact input { text-align: left; }
body.ts-settings-page .ts-setting-control select { max-width: 100%; }
body.ts-settings-page .ts-setting-control .select2-container {
	width: 100% !important;
	min-width: 0 !important;
}
body.ts-settings-page .ts-setting-control .select2-selection { min-height: 40px; }
body.ts-settings-page .ts-setting-control .select2-selection__rendered { line-height: 38px; font-size: 0.8125rem; }
body.ts-settings-page .ts-setting-control .select2-selection__arrow { height: 38px; }
/* Dolibarr renders both halves of its AJAX switch and hides the inactive one
   with .hideobject; that rule does not reach these composed rows. */
body.ts-settings-page .ts-setting-control .hideobject { display: none !important; }
body.ts-settings-page .ts-setting-control .fa-toggle-on,
body.ts-settings-page .ts-setting-control .fa-toggle-off { font-size: 26px; }
body.ts-settings-page .ts-setting-control > img,
body.ts-settings-page .ts-setting-control .classfortooltip { flex: 0 0 auto; }

/* Action row */
body.ts-settings-page .ts-settings-actions {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 12px;
	margin: 22px 0;
}
body.ts-settings-page .ts-settings-action {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	height: 42px;
	min-width: 104px;
	padding: 0 20px !important;
	border-radius: var(--r);
	font-size: 0.875rem;
	font-weight: 600;
	cursor: pointer;
}
body.ts-settings-page .ts-settings-action-primary {
	border: 1px solid var(--c-btn-action) !important;
	background: var(--c-btn-action) !important;
	color: var(--c-btn-action-text) !important;
}
/* A number of native setup forms submit an unnamed input rather than the
   composed .ts-settings-action-primary class. Keep those real Save actions in
   the same COMMAND hierarchy instead of exposing Dolibarr's red default. */
body.ts-settings-page input[type="submit"],
body.ts-settings-page button[type="submit"] {
	border: 1px solid var(--c-btn-action) !important;
	background: var(--c-btn-action) !important;
	color: var(--c-btn-action-text) !important;
	min-height: 42px;
	padding-inline: 20px !important;
	border-radius: var(--r) !important;
	font-weight: 600;
}
body.ts-settings-page input[type="submit"]:hover,
body.ts-settings-page button[type="submit"]:hover { filter: brightness(.94); }
/* Native setup pages often implement Cancel as another submit control. It is
   an escape route, not an action-color button, so it must retain the shared
   neutral treatment even when the configured action color is changed. */
body.ts-settings-page input[type="submit"][name="cancel"],
body.ts-settings-page input[type="submit"].button-cancel,
body.ts-settings-page button[type="submit"][name="cancel"],
body.ts-settings-page button[type="submit"].button-cancel {
	border-color: var(--c-border) !important;
	background: var(--c-surface) !important;
	color: var(--c-ink-2) !important;
	filter: none !important;
}
body.ts-settings-page .ts-settings-action-secondary,
body.ts-settings-page .ts-settings-actions a.butAction {
	border: 1px solid var(--c-border) !important;
	background: var(--c-surface) !important;
	color: var(--c-ink-2) !important;
}

/* Accounting source export: a standalone form that does not pass through the
   settings-table composer. Keep its existing fields/submission intact while
   applying the shared COMMAND card and control geometry. */
body.ts-accounting-files form.ts-accounting-export-form {
	margin: 0;
	padding: 22px 28px 26px;
	border: 0;
	border-radius: 0;
	background: transparent;
	box-shadow: none;
	color: var(--c-ink-2);
	font-size: .8125rem;
	line-height: 1.45;
}
body.ts-accounting-files .ts-accounting-export-intro {
	display: block;
	margin: 0 0 14px;
	color: var(--c-muted);
	font-size: .875rem;
}
/* The legacy form emits two literal breaks after the intro; the intro already
   owns its spacing, so those breaks created the large blank band in the card. */
body.ts-accounting-files .ts-accounting-export-intro + br,
body.ts-accounting-files .ts-accounting-export-intro + br + br { display: none; }
body.ts-accounting-files form[name="searchfiles"] .divfordateinput {
	display: inline-flex;
	align-items: center;
	vertical-align: middle;
}
body.ts-accounting-files form[name="searchfiles"] input.hasDatepicker {
	box-sizing: border-box;
	width: 150px;
	height: 40px;
	padding: 0 12px;
	border: 1px solid var(--c-border);
	border-radius: var(--r);
	background: var(--c-surface);
	font-size: .875rem;
}
body.ts-accounting-files form[name="searchfiles"] img.ui-datepicker-trigger {
	width: 18px;
	height: 18px;
	margin-left: -28px;
	opacity: .65;
}
body.ts-accounting-files form[name="searchfiles"] button.datenowlink {
	height: 32px;
	margin: 0 8px;
	padding: 0 10px;
	border: 1px solid var(--c-border);
	border-radius: var(--r);
	background: var(--c-sunken);
	color: var(--c-muted);
}
body.ts-accounting-files form[name="searchfiles"] .select2-container {
	width: 260px !important;
	max-width: min(260px, 100%);
	vertical-align: middle;
}
body.ts-accounting-files form[name="searchfiles"] .select2-selection,
body.ts-accounting-files form[name="searchfiles"] select {
	min-height: 40px;
	border: 1px solid var(--c-border);
	border-radius: var(--r);
	background: var(--c-surface);
}
body.ts-accounting-files form[name="searchfiles"] input[type="checkbox"] {
	width: 16px;
	height: 16px;
	margin: 0 4px 0 8px;
	accent-color: var(--c-accent);
	vertical-align: middle;
}
body.ts-accounting-files form[name="searchfiles"] input[type="checkbox"] + * {
	font-size: .8125rem;
}
body.ts-accounting-files form[name="searchfiles"] input[type="submit"],
body.ts-accounting-files form[name="searchfiles"] button[type="submit"] {
	height: 40px;
	margin-left: 12px;
	padding: 0 20px;
	border: 1px solid var(--c-btn-action) !important;
	border-radius: var(--r);
	background: var(--c-btn-action) !important;
	color: var(--c-btn-action-text) !important;
	font-weight: 650;
}
@media only screen and (max-width: 700px) {
	body.ts-accounting-files form.ts-accounting-export-form { padding: 18px 16px 20px; }
	body.ts-accounting-files form[name="searchfiles"] .select2-container { width: 100% !important; }
}

@media only screen and (max-width: 1100px) {
	body.ts-settings-page .ts-setting { grid-template-columns: minmax(0, 300px) minmax(0, 1fr); gap: 14px; }
}
@media only screen and (max-width: 700px) {
	body.ts-settings-page .ts-settings-card-head { grid-template-columns: minmax(0, 1fr); gap: 6px; }
	body.ts-settings-page .ts-settings-card-aside { grid-column: 1; }
	body.ts-settings-page .ts-setting { grid-template-columns: minmax(0, 1fr); gap: 8px; align-items: start; }
	/* Long setup labels must wrap as text, not as separate flex items.  Keeping
	   the help affordance in the inline formatting context attaches it to the
	   last text line instead of dropping it onto an orphaned row. */
	body.ts-settings-page .ts-setting-label { display: block; }
	body.ts-settings-page .ts-setting-label > label,
	body.ts-settings-page .ts-setting-label > span,
	body.ts-settings-page .ts-setting-label > label > span { display: inline !important; }
	body.ts-settings-page .ts-setting-label .classfortooltip { margin-inline-start: 6px; white-space: nowrap; }
	/* Dolibarr groups an upload, its delete action and the current preview in
	   one legacy inline container.  A real wrapping flex row supplies a stable
	   gap both beside and below the native file control on narrow screens. */
	body.ts-settings-page .ts-setting-control:has(input[type="file"]) > div {
		display: flex !important;
		flex-wrap: wrap;
		align-items: center;
		gap: 10px 12px;
		width: 100%;
	}
	body.ts-settings-page .ts-setting-control:has(input[type="file"]) > div > * { margin: 0 !important; }
	/* The same label/help primitive is used by modern create/edit forms. */
	body#mainbody form.ts-modern-form td.ts-form-label > .valignmiddle,
	body#mainbody form.ts-modern-form td.ts-form-label > .classfortooltip { display: inline !important; }
	body#mainbody form.ts-modern-form td.ts-form-label > .classfortooltip { margin-inline-start: 6px; white-space: nowrap; }
	body.ts-settings-page .ts-setting-control.ts-control-compact,
	body.ts-settings-page .ts-setting-control.ts-control-medium,
	body.ts-settings-page .ts-setting-control.ts-control-wide { max-width: 100%; }
	body.ts-settings-page .ts-settings-actions { flex-wrap: wrap; }
	body.ts-settings-page .ts-settings-action { flex: 1 1 140px; }
	/* Related text inputs in setup pages (handle + URL, key + value, etc.)
	   become rows of one shared control column instead of overflowing right. */
	body.ts-settings-page .ts-setting-control:has(> input:not([type="hidden"]):nth-of-type(2)) {
		display: grid !important;
		grid-template-columns: minmax(0, 1fr);
		gap: 8px 10px;
		width: 100%;
		max-width: 100%;
		font-size: 0;
	}
	body.ts-settings-page .ts-setting-control:has(> [class*="fa-"]):has(> input:not([type="hidden"]):nth-of-type(2)) {
		grid-template-columns: 22px minmax(0, 1fr);
	}
	body.ts-settings-page .ts-setting-control:has(> input:not([type="hidden"]):nth-of-type(2)) > [class*="fa-"] {
		grid-column: 1;
		grid-row: 1;
		align-self: center;
		justify-self: center;
		margin: 0 !important;
		font-size: .875rem;
	}
	body.ts-settings-page .ts-setting-control:has(> input:not([type="hidden"]):nth-of-type(2)) > input:not([type="hidden"]) {
		grid-column: 1;
		box-sizing: border-box;
		width: 100% !important;
		min-width: 0 !important;
		max-width: none !important;
		margin: 0 !important;
		font-size: .875rem;
	}
	body.ts-settings-page .ts-setting-control:has(> [class*="fa-"]):has(> input:not([type="hidden"]):nth-of-type(2)) > input:not([type="hidden"]) { grid-column: 2; }
}

/* Mobile list rows retain the two most useful data columns and expose every
   other original cell in a per-row disclosure.  The table therefore fits the
   viewport without removing any data or interaction. */
@media only screen and (max-width: 700px) {
	table.liste.ts-mobile-compact-list {
		width: 100% !important;
		min-width: 0 !important;
		max-width: 100% !important;
		table-layout: fixed;
	}
	table.liste.ts-mobile-compact-list .ts-mobile-source-cell { display: none !important; }
	table.liste.ts-mobile-compact-list .ts-mobile-utility-cell { width: 42px !important; padding-inline: 5px !important; text-align: center !important; }
	table.liste.ts-mobile-compact-list .ts-mobile-primary-cell,
	table.liste.ts-mobile-compact-list .ts-mobile-secondary-cell {
		width: auto !important;
		min-width: 0 !important;
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
	}
	table.liste.ts-mobile-compact-list .ts-mobile-more-head,
	table.liste.ts-mobile-compact-list .ts-mobile-more-cell {
		width: 58px !important;
		padding: 5px !important;
		text-align: center !important;
	}
	.ts-mobile-row-more-trigger {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		gap: 5px;
		min-width: 42px;
		height: 34px;
		padding: 0 8px;
		border: 1px solid var(--c-border);
		border-radius: 8px;
		background: var(--c-surface);
		color: var(--c-accent);
		font: inherit;
		font-size: .75rem;
		font-weight: 650;
		line-height: 1;
		box-shadow: none;
	}
	.ts-mobile-row-more-trigger i { margin: 0; font-size: 9px; transition: transform .16s ease; }
	.ts-mobile-row-more-trigger[aria-expanded="true"] i { transform: rotate(180deg); }
	.ts-mobile-row-details[hidden] { display: none !important; }
	table.liste.ts-mobile-compact-list tr.ts-mobile-row-details > td {
		display: table-cell !important;
		padding: 0 10px 10px !important;
		border-bottom: 1px solid var(--c-hairline) !important;
		background: var(--c-canvas) !important;
	}
	.ts-mobile-row-details-list {
		display: grid;
		grid-template-columns: minmax(105px, 38%) minmax(0, 1fr);
		gap: 0;
		margin: 0;
		padding: 8px 12px;
		border: 1px solid var(--c-border);
		border-radius: 9px;
		background: var(--c-surface);
	}
	.ts-mobile-row-details-list dt,
	.ts-mobile-row-details-list dd {
		min-width: 0;
		margin: 0;
		padding: 7px 4px;
		border-bottom: 1px solid var(--c-hairline);
		font-size: .8125rem;
		line-height: 1.35;
		overflow-wrap: anywhere;
	}
	.ts-mobile-row-details-list dt { color: var(--c-muted); font-weight: 600; }
	.ts-mobile-row-details-list dd { color: var(--c-text); }
	.ts-mobile-row-details-list > :nth-last-child(-n + 2) { border-bottom: 0; }
}

/* ==========================================================================
   Record card field panels (Proposal, Order, Invoice, Product, Contact ...)

   Dolibarr renders each detail panel as table.tableforfield inside the
   fichehalfleft/fichehalfright columns. Those rows carry nested tables and
   inline edit links, so this is styling only -- no node is moved, which keeps
   every edit link, tooltip and form exactly where Dolibarr put it.

   The third-party record page has its own composition and is excluded.
   ========================================================================== */
body.ts-command-record-page:not(.ts-thirdparty-record-context) div.fichehalfleft > table.tableforfield,
body.ts-command-record-page:not(.ts-thirdparty-record-context) div.fichehalfright > table.tableforfield,
body.ts-command-record-page:not(.ts-thirdparty-record-context) div.fichehalfleft > div > table.tableforfield,
body.ts-command-record-page:not(.ts-thirdparty-record-context) div.fichehalfright > div > table.tableforfield {
	width: 100%;
	margin: 0 0 16px;
	border: 1px solid var(--c-hairline) !important;
	border-radius: var(--r-lg);
	background: var(--c-surface);
	box-shadow: var(--sh-sm);
	border-collapse: separate;
	border-spacing: 0;
	overflow: hidden;
}
body.ts-command-record-page:not(.ts-thirdparty-record-context) table.tableforfield > tbody > tr > td {
	padding: 11px 16px !important;
	border: 0 !important;
	border-bottom: 1px solid var(--c-hairline) !important;
	font-size: 0.8125rem;
	vertical-align: middle;
	background: transparent !important;
}
body.ts-command-record-page:not(.ts-thirdparty-record-context) table.tableforfield > tbody > tr:last-child > td {
	border-bottom: 0 !important;
}
/* First cell is the label column; keep every panel on one label axis. */
body.ts-command-record-page:not(.ts-thirdparty-record-context) table.tableforfield > tbody > tr > td:first-child {
	width: 38%;
	color: var(--c-ink-2);
	font-weight: 550;
}
body.ts-command-record-page:not(.ts-thirdparty-record-context) table.tableforfield > tbody > tr > td:first-child table {
	width: 100%;
	background: transparent !important;
}
body.ts-command-record-page:not(.ts-thirdparty-record-context) table.tableforfield > tbody > tr > td:first-child table td {
	padding: 0 !important;
	border: 0 !important;
	font-weight: inherit;
	color: inherit;
}
body.ts-command-record-page:not(.ts-thirdparty-record-context) table.tableforfield > tbody > tr > td:last-child {
	color: var(--c-ink);
}
/* Dolibarr stripes these rows; a card reads better flat. */
body.ts-command-record-page:not(.ts-thirdparty-record-context) table.tableforfield > tbody > tr.oddeven,
body.ts-command-record-page:not(.ts-thirdparty-record-context) table.tableforfield > tbody > tr.impair,
body.ts-command-record-page:not(.ts-thirdparty-record-context) table.tableforfield > tbody > tr.pair {
	background: transparent !important;
}
body.ts-command-record-page:not(.ts-thirdparty-record-context) table.tableforfield a.editfielda {
	opacity: .6;
	margin-left: 6px;
}
body.ts-command-record-page:not(.ts-thirdparty-record-context) table.tableforfield a.editfielda:hover { opacity: 1; }

@media only screen and (max-width: 700px) {
	body.ts-command-record-page:not(.ts-thirdparty-record-context) table.tableforfield > tbody > tr > td:first-child { width: 44%; }
	body.ts-command-record-page:not(.ts-thirdparty-record-context) table.tableforfield > tbody > tr > td { padding: 9px 12px !important; }
}

/* ==========================================================================
   Record card line items (Proposal, Order, Invoice)

   All three render their lines as table#tablelines inside a responsive div,
   so one selector covers the set. Styling only -- the drag handles, inline
   edit forms and the "add new line" row keep their markup and behaviour.
   ========================================================================== */
body.ts-command-record-page:not(.ts-thirdparty-record-context) div.div-table-responsive-no-min:has(> table#tablelines),
body.ts-command-record-page:not(.ts-thirdparty-record-context) div.div-table-responsive:has(> table#tablelines) {
	margin: 0 0 16px;
	border: 1px solid var(--c-hairline);
	border-radius: var(--r-lg);
	background: var(--c-surface);
	box-shadow: var(--sh-sm);
	overflow: hidden;
	overflow-x: auto;
}
body.ts-command-record-page:not(.ts-thirdparty-record-context) table#tablelines {
	width: 100%;
	margin: 0 !important;
	border: 0 !important;
	background: transparent !important;
}
body.ts-command-record-page:not(.ts-thirdparty-record-context) table#tablelines > tbody > tr.liste_titre > td,
body.ts-command-record-page:not(.ts-thirdparty-record-context) table#tablelines > tbody > tr.liste_titre > th {
	padding: 11px 12px !important;
	border: 0 !important;
	border-bottom: 1px solid var(--c-hairline) !important;
	background: var(--c-sunken) !important;
	color: var(--c-ink-2) !important;
	font-size: 0.75rem;
	font-weight: 600;
	white-space: nowrap;
}
body.ts-command-record-page:not(.ts-thirdparty-record-context) table#tablelines > tbody > tr > td {
	padding: 11px 12px !important;
	border: 0 !important;
	border-bottom: 1px solid var(--c-hairline) !important;
	font-size: 0.8125rem;
	vertical-align: middle;
}
body.ts-command-record-page:not(.ts-thirdparty-record-context) table#tablelines > tbody > tr:last-child > td { border-bottom: 0 !important; }
/* Dolibarr stripes these; a card reads better flat. */
body.ts-command-record-page:not(.ts-thirdparty-record-context) table#tablelines > tbody > tr.pair,
body.ts-command-record-page:not(.ts-thirdparty-record-context) table#tablelines > tbody > tr.impair,
body.ts-command-record-page:not(.ts-thirdparty-record-context) table#tablelines > tbody > tr.oddeven {
	background: transparent !important;
}
body.ts-command-record-page:not(.ts-thirdparty-record-context) table#tablelines > tbody > tr:hover > td { background: var(--c-sunken); }
body.ts-command-record-page:not(.ts-thirdparty-record-context) table#tablelines input[type="text"],
body.ts-command-record-page:not(.ts-thirdparty-record-context) table#tablelines select {
	height: 36px;
	border-radius: 6px;
	font-size: 0.8125rem;
}

/* Narrow Select2 triggers.

   Dolibarr sizes some selects with its own width50/width75/width100 classes.
   Our Select2 rendering reserves 38px on the right for the arrow, which at
   75px leaves too little room for the value itself -- a year read as "20…".
   Give those triggers a workable floor and tighten their internal spacing so
   the value fits. Applies wherever a narrow select appears, not just the
   product statistics filter where it was noticed. */
body span.select2-container.width50,
body span.select2-container.width75 { min-width: 92px !important; }
body span.select2-container.width100 { min-width: 108px !important; }
body span.select2-container.width50 span.select2-selection__rendered,
body span.select2-container.width75 span.select2-selection__rendered,
body span.select2-container.width100 span.select2-selection__rendered {
	width: auto !important;
	min-width: 0 !important;
	max-width: none !important;
	padding-right: 24px !important;
	padding-left: 9px !important;
	text-overflow: clip !important;
}
body span.select2-container.width50 span.select2-selection__arrow,
body span.select2-container.width75 span.select2-selection__arrow,
body span.select2-container.width100 span.select2-selection__arrow { right: 4px !important; }

/* Categories landing page summary table. Styling only -- the page has no filter
   form, so there is nothing to compose, just a table sitting bare on the page. */
body.ts-category-index table.ts-category-index-table {
	width: 100%;
	margin: 0 0 16px;
	border: 1px solid var(--c-hairline) !important;
	border-radius: var(--r-lg);
	background: var(--c-surface);
	box-shadow: var(--sh-sm);
	border-collapse: separate;
	border-spacing: 0;
	overflow: hidden;
}
body.ts-category-index table.ts-category-index-table > tbody > tr > td,
body.ts-category-index table.ts-category-index-table > tbody > tr > th {
	padding: 12px 16px !important;
	border: 0 !important;
	border-bottom: 1px solid var(--c-hairline) !important;
	font-size: 0.8125rem;
	vertical-align: middle;
}
body.ts-category-index table.ts-category-index-table > tbody > tr.liste_titre > th,
body.ts-category-index table.ts-category-index-table > tbody > tr.liste_titre > td {
	background: var(--c-sunken) !important;
	color: var(--c-ink-2) !important;
	font-size: 0.75rem;
	font-weight: 600;
}
body.ts-category-index table.ts-category-index-table > tbody > tr:last-child > td { border-bottom: 0 !important; }
body.ts-category-index table.ts-category-index-table > tbody > tr.oddeven,
body.ts-category-index table.ts-category-index-table > tbody > tr.impair,
body.ts-category-index table.ts-category-index-table > tbody > tr.pair { background: transparent !important; }


/* Date filter controls and the jQuery UI picker.

   The two halves of a range were sized by different rules, so "from" and "to"
   did not match; the picker trigger was a bare 26px image; and the calendar
   itself inherited jQuery UI's default metrics, which read as cramped next to
   the rest of the toolbar. Size all three together. */
/* A date range is one control, so its two halves belong on one line -- the way
   the filter panel already lays them out. A list search row instead sizes the
   column to its heading, which left no room for the second half and dropped it
   onto a line of its own. Laying the pair out as a row makes the column ask for
   the width it actually needs. */
tr.liste_titre th:has(> .nowrapfordate + .nowrapfordate),
tr.liste_titre td:has(> .nowrapfordate + .nowrapfordate) {
	white-space: nowrap;
}
tr.liste_titre th:has(> .nowrapfordate + .nowrapfordate) > .nowrapfordate,
tr.liste_titre td:has(> .nowrapfordate + .nowrapfordate) > .nowrapfordate {
	display: inline-flex;
	align-items: center;
	vertical-align: middle;
}
tr.liste_titre th:has(> .nowrapfordate + .nowrapfordate) > .nowrapfordate + .nowrapfordate,
tr.liste_titre td:has(> .nowrapfordate + .nowrapfordate) > .nowrapfordate + .nowrapfordate {
	margin-left: var(--sp-2);
}

.ts-filter-surface input.hasDatepicker,
.ts-filter-surface .divfordateinput input[type="text"],
.ts-setting-control input.hasDatepicker {
	width: 112px !important;
	min-width: 112px !important;
	max-width: 112px !important;
	height: 38px;
	box-sizing: border-box;
	text-align: center;
}
.ts-filter-surface img.ui-datepicker-trigger,
.ts-setting-control img.ui-datepicker-trigger {
	width: 34px !important;
	height: 34px !important;
	padding: 8px;
	box-sizing: border-box;
	border: 1px solid var(--c-border);
	border-radius: var(--r);
	background: var(--c-surface);
	cursor: pointer;
	opacity: .75;
}
.ts-filter-surface img.ui-datepicker-trigger:hover,
.ts-setting-control img.ui-datepicker-trigger:hover {
	border-color: var(--c-accent);
	opacity: 1;
}

/* The calendar itself */
#ui-datepicker-div.ui-datepicker {
	width: 268px;
	padding: 10px;
	border: 1px solid var(--c-hairline);
	border-radius: var(--r-lg);
	background: var(--c-surface);
	box-shadow: var(--sh-lg);
	font-size: 0.8125rem;
}
#ui-datepicker-div .ui-datepicker-header {
	padding: 2px 0 8px;
	border: 0;
	background: transparent;
}
#ui-datepicker-div .ui-datepicker-title {
	display: flex;
	gap: 8px;
	justify-content: center;
	margin: 0 28px;
}
#ui-datepicker-div .ui-datepicker-title select.ui-datepicker-month,
#ui-datepicker-div .ui-datepicker-title select.ui-datepicker-year {
	width: auto !important;
	min-width: 78px !important;
	height: 32px;
	padding: 0 6px !important;
	border: 1px solid var(--c-border);
	border-radius: 6px;
	background: var(--c-surface);
	font-size: 0.8125rem;
}
#ui-datepicker-div .ui-datepicker-prev,
#ui-datepicker-div .ui-datepicker-next {
	top: 4px;
	width: 28px;
	height: 28px;
	border: 1px solid var(--c-border) !important;
	border-radius: 6px;
	background: var(--c-surface) !important;
	cursor: pointer;
}
#ui-datepicker-div .ui-datepicker-prev { left: 4px; }
#ui-datepicker-div .ui-datepicker-next { right: 4px; }
#ui-datepicker-div table.ui-datepicker-calendar { margin: 0; font-size: 0.8125rem; }
#ui-datepicker-div .ui-datepicker-calendar th {
	padding: 6px 0;
	color: var(--c-ink-subtle);
	font-size: 0.6875rem;
	font-weight: 600;
}
#ui-datepicker-div .ui-datepicker-calendar td { padding: 2px; border: 0; }
#ui-datepicker-div .ui-datepicker-calendar td a,
#ui-datepicker-div .ui-datepicker-calendar td span {
	display: block;
	width: 32px;
	height: 32px;
	padding: 0;
	border: 0;
	border-radius: 7px;
	background: transparent;
	color: var(--c-ink-2);
	line-height: 32px;
	text-align: center;
}
#ui-datepicker-div .ui-datepicker-calendar td a:hover { background: var(--c-sunken); }
#ui-datepicker-div .ui-datepicker-calendar td a.ui-state-active,
#ui-datepicker-div .ui-datepicker-calendar td a.ui-state-highlight {
	background: var(--c-accent) !important;
	color: #fff !important;
	font-weight: 600;
}

/* Busy month cells retain their real event links but disclose surplus entries
   instead of stretching one week into a page-length column. */
/* A single Dolibarr calendar event can contain a full title, an avatar, and a
   status cell.  In month view that is information density, not a record card:
   constrain the visual preview while preserving the original event link and
   its native title tooltip. */
table.cal_month .agendacell > .event > table.cal_event {
	table-layout: fixed !important;
	width: 100% !important;
	margin: 0 !important;
	font-size: 11px !important;
}
table.cal_month .agendacell > .event > table.cal_event td.cal_event {
	min-width: 0 !important;
	padding: 5px 4px !important;
	white-space: normal !important;
	vertical-align: top !important;
}
table.cal_month .agendacell > .event .cal_event_title {
	display: -webkit-box !important;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 2;
	overflow: hidden !important;
	line-height: 1.35 !important;
	word-break: break-word;
}
table.cal_month .agendacell > .event > table.cal_event td.cal_event > br,
table.cal_month .agendacell > .event > table.cal_event td.cal_event > a.classforajaxtooltip:not(.cal_event_title) {
	display: none !important;
}
table.cal_month .agendacell > .event {
	max-height: 66px;
	margin-bottom: 4px;
	overflow: hidden;
}
table.cal_month .agendacell > .event.ts-agenda-month-overflow { display: none; }
table.cal_month .agendacell.ts-agenda-month-expanded > .event.ts-agenda-month-overflow { display: block; }
table.cal_month .ts-agenda-month-more {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 28px;
	margin: 6px 0 2px;
	padding: 0 8px;
	border: 0;
	border-radius: 6px;
	background: var(--c-accent-soft);
	color: var(--c-accent-ink);
	font: inherit;
	font-size: 12px;
	font-weight: 600;
	cursor: pointer;
}
table.cal_month .ts-agenda-month-more:hover,
table.cal_month .ts-agenda-month-more:focus-visible { background: color-mix(in srgb, var(--c-accent) 16%, #fff); outline: 0; }
@media (max-width: 700px) {
	/* Seven translated weekday names cannot all retain desktop typography on a
	   phone. Give every header a fixed share of the calendar and clip within its
	   own cell instead of allowing neighbouring labels to run together. */
	table.cal_month { table-layout: fixed !important; }
	table.cal_month th,
	table.cal_month td.tdfordaytitle {
		min-width: 0 !important;
		padding-inline: 1px !important;
		font-size: 9px !important;
		letter-spacing: -.15px;
		white-space: nowrap !important;
		overflow: hidden !important;
		text-overflow: ellipsis !important;
	}
}

/* Status dots.

   Dolibarr's .badge-dot carries the pill padding of a full status badge, so it
   measured 18x22 and a 999px radius drew an ellipse rather than a dot. Give it
   equal sides and the radius follows. Scoped to badge-dot so the wider
   badge-status pills keep their shape. */
span.badge.badge-dot,
.badge.badge-dot {
	display: inline-block !important;
	width: 11px !important;
	height: 11px !important;
	min-width: 11px !important;
	min-height: 11px !important;
	max-width: 11px !important;
	padding: 0 !important;
	border-radius: 50% !important;
	font-size: 0 !important;
	line-height: 0 !important;
	vertical-align: middle;
	overflow: hidden;
	/* A translucent status tint works for a labelled pill but is too faint at
	   11px. Use the already-configured semantic foreground as the dot fill, so
	   every status indicator remains legible without introducing a new colour. */
	background: currentColor !important;
	border-color: currentColor !important;
}

/* Colour rows carry the picker's own <link> and <script> tags inside the cell.
   As grid items they auto-placed into a second row, padding each control to
   67px for 36px of visible content -- the swatch stayed at the top while the
   label centred against the taller box, which read as the labels sitting low.
   Take them out of layout. */
.ts-color-control > link,
.ts-color-control > script,
.ts-setting-control > link,
.ts-setting-control > script {
	display: none !important;
}
/* Only the first row holds real cells; template it and pin the extras to zero
   so a stray anonymous item cannot pad the control. */
.ts-color-control {
	grid-template-rows: minmax(38px, auto) !important;
	grid-auto-rows: 0 !important;
	row-gap: 0 !important;
	overflow: hidden;
}

/* The version in the top bar rendered at 8px -- below the point where it can be
   read at all, and the smallest text anywhere in the shell. */
#id-top .hideonsmartphone.small,
.ts-topbar .hideonsmartphone.small {
	font-size: 0.6875rem !important;
	color: var(--c-ink-subtle) !important;
	letter-spacing: 0.01em;
}

/* Page header and tab strip.

   Applies wherever the shell renders a .ts-pagehead with a tab strip, so the
   treatment is shared rather than per-page. */

/* Any picto Dolibarr already prints beside a page title becomes a soft tile.
   Only pages that ship an icon get one -- none is invented. */
.ts-pagehead-title > .ts-pagehead-icon,
.ts-pagehead-title .titre > img.pictotitle,
.ts-pagehead-title .titre > span.pictotitle,
.ts-pagehead-title .titre > [class*="fa-"]:first-child {
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	width: 46px;
	height: 46px;
	margin: 0 14px 0 0 !important;
	padding: 0 !important;
	border-radius: 12px;
	background: var(--c-accent-soft);
	color: var(--c-accent) !important;
	font-size: 20px !important;
	vertical-align: middle;
}

/* Colour picker popup.

   jPicker positions this itself, near the trigger, and a field in the right
   column or low on the page opened it past the edge of the window -- partly
   unreachable. Scripted repositioning proved unreliable because the plugin
   lays the panel out on its own schedule, so pin it in the viewport instead:
   centred, never larger than the window, and scrollable if it ever is. */
.jPicker.Container {
	position: fixed !important;
	top: 50% !important;
	left: 50% !important;
	right: auto !important;
	bottom: auto !important;
	transform: translate(-50%, -50%) !important;
	max-width: calc(100vw - 32px) !important;
	max-height: calc(100vh - 32px) !important;
	overflow: auto !important;
	z-index: 2000 !important;
	border-radius: var(--r-lg);
	box-shadow: var(--sh-lg);
}

/* ==========================================================================
   Compound measurement fields (value + unit)

   Dolibarr renders weight, dimensions, area and volume as a value input and a
   unit select loose in one cell. Two form rules stretched those inputs to the
   full cell, which pushed the unit select onto its own line.

   The winning one scored (0,33,5):
     div.tabBar table.border:not(.liste) td > span[class*="fa-"] + input:not(...)
   It matches because these fields carry an icon immediately before the input.
   Dimensions escaped it only because they ship class="width50", which those
   same rules already exclude.

   So this follows the exclusion the stylesheet already uses -- the inputs are
   marked .ts-measure and added to that :not() list -- rather than escalating
   specificity. Sizing below is then plain, and one pattern covers every
   measurement field wherever Dolibarr renders one.
   ========================================================================== */
.ts-measure-cell { white-space: nowrap; }
.ts-measure-cell > span[class*="fa-"] {
	display: inline-block;
	width: 26px;
	margin-right: 10px;
	color: var(--c-accent);
	text-align: center;
	vertical-align: middle;
}
input.ts-measure {
	display: inline-block;
	height: 40px;
	margin: 0;
	vertical-align: middle;
}
input.ts-measure-value { width: 168px; }
div.tabBar table td > input.ts-measure-dim { width: 116px; margin-right: 4px; }
.ts-measure-cell .ts-measure-x {
	display: inline-block;
	width: 18px;
	color: var(--c-ink-subtle);
	text-align: center;
	vertical-align: middle;
}
.ts-measure-cell > .select2-container {
	display: inline-block !important;
	/* Sized to the longest unit label it has to hold ("mm3 (ul)"), not to the
	   space available -- a unit is a short enum, so a wide box reads as an empty
	   field rather than a compact control. */
	width: 138px !important;
	min-width: 138px !important;
	max-width: 138px !important;
	margin-left: 12px;
	vertical-align: middle;
}
.ts-measure-cell > .select2-container .select2-selection {
	height: 40px !important;
	min-height: 40px !important;
	border: 1px solid var(--c-border) !important;
	border-radius: var(--r) !important;
	background: var(--c-surface) !important;
	box-shadow: none !important;
}
.ts-measure-cell > .select2-container .select2-selection__rendered {
	height: 38px !important;
	line-height: 38px !important;
	padding: 0 26px 0 12px !important;
	font-size: 0.8125rem !important;
}
.ts-measure-cell > .select2-container .select2-selection__arrow { height: 38px !important; right: 6px !important; }

@media only screen and (max-width: 1100px) {
	input.ts-measure-value { width: 132px; }
	div.tabBar table td > input.ts-measure-dim { width: 92px; }
	.ts-measure-cell > .select2-container { width: 126px !important; min-width: 126px !important; max-width: 126px !important; margin-left: 8px; }
}
@media only screen and (max-width: 700px) {
	.ts-measure-cell { white-space: normal; }
	input.ts-measure-value {
		width: 168px !important;
		max-width: 100% !important;
	}
	div.tabBar table td > input.ts-measure-dim {
		width: 96px !important;
		max-width: 96px !important;
	}
	.ts-measure-cell > .select2-container {
		width: 138px !important;
		min-width: 0 !important;
		max-width: 100% !important;
		margin-left: 8px;
	}
}

/* ==========================================================================
   Kanban cards for modules without their own adapter

   The third-party adapter rebuilds its cards into a ts-kanban-* structure.
   Every other module keeps Dolibarr's native card: an .info-box holding
   .info-box-img, .info-box-ref, a select checkbox, .info-box-label and
   .info-box-status. Those parts are the same everywhere, so they can be given
   the same treatment without rebuilding anything -- styling only, so each
   module's own fields, links and tooltips stay exactly as Dolibarr wrote them.

   Scoped to the shared marker so the third-party view, which is already
   composed, is untouched.
   ========================================================================== */
[data-ts-kanban="shared"] > .box-flex-item {
	position: relative;
	padding: 0;
	border: 1px solid var(--c-hairline);
	border-radius: var(--r-lg);
	background: var(--c-surface);
	box-shadow: var(--sh-sm);
	overflow: hidden;
	transition: border-color var(--t), box-shadow var(--t);
}
[data-ts-kanban="shared"] > .box-flex-item:hover {
	border-color: var(--c-border-strong);
	box-shadow: var(--sh-md, var(--sh-sm));
}
div.box-flex-container[data-ts-kanban="shared"] > .box-flex-item .info-box,
[data-ts-kanban="shared"] .info-box {
	display: flex !important;
	flex-direction: row !important;
	align-items: flex-start;
	gap: 12px;
	min-height: 0 !important;
	margin: 0 !important;
	padding: 14px 16px !important;
	border: 0 !important;
	background: transparent !important;
	box-shadow: none !important;
}
/* Picto becomes the same soft tile the rest of the shell uses. */
[data-ts-kanban="shared"] .info-box-img,
[data-ts-kanban="shared"] .info-box-icon {
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	flex: 0 0 auto;
	width: 38px !important;
	height: 38px !important;
	margin: 0 !important;
	padding: 0 !important;
	border-radius: 10px;
	background: var(--c-accent-soft) !important;
	font-size: 15px;
	line-height: 1;
}
[data-ts-kanban="shared"] .info-box-img [class*="fa-"],
[data-ts-kanban="shared"] .info-box-icon [class*="fa-"] { color: var(--c-accent) !important; }
div.box-flex-container[data-ts-kanban="shared"] > .box-flex-item .info-box-content,
[data-ts-kanban="shared"] .info-box-content {
	display: block !important;
	flex: 1 1 auto;
	min-width: 0;
	margin: 0 !important;
	padding: 0 !important;
}
/* Reference reads as the card's title. */
[data-ts-kanban="shared"] .info-box-ref,
[data-ts-kanban="shared"] .info-box-ref a {
	max-width: 100% !important;
	font-size: 0.875rem !important;
	font-weight: 650 !important;
	color: var(--c-ink) !important;
	text-decoration: none;
}
[data-ts-kanban="shared"] .info-box-ref a:hover { color: var(--c-accent) !important; }
[data-ts-kanban="shared"] .info-box-label {
	display: block !important;
	max-width: 100% !important;
	margin-top: 2px;
	color: var(--c-ink-subtle) !important;
	font-size: 0.8125rem !important;
	opacity: 1 !important;
}
/* Remaining rows -- amounts, stock, dates -- read as quiet metadata. */
[data-ts-kanban="shared"] .info-box-status {
	display: flex !important;
	align-items: center;
	gap: 8px;
	margin-top: 10px;
	color: var(--c-ink-2) !important;
	font-size: 0.8125rem !important;
	opacity: 1 !important;
}
[data-ts-kanban="shared"] .info-box-status [class*="fa-"] { opacity: .6; }
/* The select box belongs in the corner, not in the middle of the text. */
[data-ts-kanban="shared"] input.checkforselect {
	position: absolute;
	top: 12px;
	right: 12px;
	float: none !important;
	margin: 0 !important;
}
[data-ts-kanban="shared"] .info-box-content > br { display: none; }

/* Module cards keep their version marker inside the icon element.  Once the
   shared Kanban surface turns that element into a fixed tile, the marker
   must leave inline flow or it can paint over the module title. */
body.page-modules div.box-flex-container[data-ts-kanban="shared"] .info-box-module .info-box {
	position: relative;
	height: 100%;
}
body.page-modules div.box-flex-container[data-ts-kanban="shared"] .info-box-module .info-box-icon {
	position: static;
	overflow: visible;
}
body.page-modules div.box-flex-container[data-ts-kanban="shared"] .info-box-module .info-box-content {
	display: flex !important;
	flex-direction: column;
	align-self: stretch;
	min-height: 0;
}
body.page-modules div.box-flex-container[data-ts-kanban="shared"] .info-box-module .info-box-icon-version {
	position: absolute;
	top: 9px;
	right: 12px;
	z-index: 2;
	max-width: 92px;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	font-size: .6875rem;
	line-height: 1.2;
	font-weight: 600;
	color: var(--c-muted);
	background: var(--c-surface);
}
body.page-modules div.box-flex-container[data-ts-kanban="shared"] .info-box-module .info-box-title {
	display: block !important;
	box-sizing: border-box;
	width: 100%;
	max-width: 100%;
	margin: 0 0 5px !important;
	padding-right: 78px;
	white-space: normal !important;
	line-height: 1.35;
}
body.page-modules div.box-flex-container[data-ts-kanban="shared"] .info-box-module .info-box-desc {
	display: block !important;
	box-sizing: border-box;
	width: 100%;
	max-width: 100% !important;
	margin: 0 !important;
	line-height: 1.4;
}
body.page-modules div.box-flex-container[data-ts-kanban="shared"] .info-box-module .info-box-actions {
	display: flex !important;
	align-items: center;
	gap: 10px;
	min-height: 24px;
	margin-top: auto;
	padding-top: 10px;
}
body.page-modules div.box-flex-container[data-ts-kanban="shared"] .info-box-module .info-box-actions > * {
	margin-left: 0 !important;
	margin-right: 0 !important;
}
body.page-modules div.box-flex-container[data-ts-kanban="shared"] .info-box-module .info-box-more {
	position: absolute;
	right: 16px;
	bottom: 14px;
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	width: 28px;
	height: 28px;
	margin: 0 !important;
}

/* Modules/Application setup ------------------------------------------------
   The page has one repeated row grammar for every family. Keep its filters,
   actions and columns on the same shared axes instead of letting generic fixed
   table sizing truncate the first cell differently in every section. */
body.ts-modules-setup-page .ts-modules-setup-form #dragDropAreaTabBar > .valignmiddle {
	display: flex;
	align-items: center;
	gap: 12px;
	min-width: 0;
}
body.ts-modules-setup-page .ts-modules-setup-form .divfilteralone {
	display: flex !important;
	flex: 1 1 auto;
	flex-wrap: wrap;
	align-items: center;
	gap: 10px;
	min-width: 0;
}
body.ts-modules-setup-page .ts-modules-setup-form .divsearchfield {
	display: inline-flex !important;
	align-items: center;
	margin: 0 !important;
	padding: 0 !important;
}
body.ts-modules-setup-page .ts-modules-version-filter select {
	width: 150px !important;
	min-width: 150px !important;
}
body.ts-modules-setup-page .ts-modules-view-tools {
	position: relative;
	order: 2;
	flex: 0 0 auto;
	float: none !important;
	margin-left: auto;
	padding: 0 !important;
}
body.ts-modules-setup-page .ts-modules-view-tools ul,
body.ts-modules-setup-page .ts-modules-view-tools li {
	display: flex;
	align-items: center;
	gap: 6px;
	margin: 0;
	padding: 0;
}
body.ts-modules-setup-page .ts-modules-view-tools .button-title-separator { display: none; }
body.ts-modules-setup-page .ts-modules-view-tools a.btnTitle {
	position: relative;
	width: 36px;
	height: 36px;
	min-width: 36px;
	min-height: 36px;
	padding: 0 !important;
}
body.ts-modules-setup-page .ts-modules-view-tools a.btnTitle .btnTitle-icon {
	font-size: 16px !important;
	line-height: 1 !important;
}
body.ts-modules-setup-page .ts-modules-view-tools a.btnTitle::after {
	content: attr(data-ts-tooltip);
	position: absolute;
	top: calc(100% + 7px);
	right: 0;
	z-index: 12000;
	width: max-content;
	max-width: 180px;
	padding: 7px 10px;
	border: 1px solid var(--c-border);
	border-radius: 8px;
	background: var(--c-surface);
	box-shadow: var(--sh-md);
	color: var(--c-ink-2);
	font-size: 12px;
	font-weight: 550;
	line-height: 1.3;
	opacity: 0;
	pointer-events: none;
	transform: translateY(-2px);
	transition: opacity var(--t), transform var(--t);
}
body.ts-modules-setup-page .ts-modules-view-tools a.btnTitle:hover::after,
body.ts-modules-setup-page .ts-modules-view-tools a.btnTitle:focus-visible::after {
	opacity: 1;
	transform: translateY(0);
}
body.ts-modules-setup-page table.ts-modules-list-table {
	width: 100% !important;
	table-layout: auto !important;
}
body.ts-modules-setup-page table.ts-modules-list-table tr.ts-module-list-row {
	height: auto !important;
	min-height: 52px;
}
body.ts-modules-setup-page table.ts-modules-list-table tr.ts-module-list-row > td {
	box-sizing: border-box;
	height: auto !important;
	min-height: 52px;
	padding: 12px 14px !important;
	vertical-align: middle;
}
body.ts-modules-setup-page table.ts-modules-list-table .ts-module-name-cell {
	width: 260px !important;
	min-width: 260px !important;
	max-width: 320px !important;
	text-align: left !important;
	overflow: visible !important;
	text-overflow: clip !important;
	white-space: normal !important;
	font-weight: 600;
	line-height: 1.35;
}
body.ts-modules-setup-page table.ts-modules-list-table .ts-module-name-cell > span {
	white-space: normal !important;
}
body.ts-modules-setup-page table.ts-modules-list-table .ts-module-description-cell {
	width: auto !important;
	min-width: 260px !important;
	max-width: none !important;
	white-space: normal !important;
	line-height: 1.4;
}
body.ts-modules-setup-page table.ts-modules-list-table .ts-module-help-cell { width: 48px !important; min-width: 48px !important; }
body.ts-modules-setup-page table.ts-modules-list-table .ts-module-version-cell { width: 170px !important; min-width: 170px !important; }
body.ts-modules-setup-page table.ts-modules-list-table .ts-module-state-cell { width: 64px !important; min-width: 64px !important; }
body.ts-modules-setup-page table.ts-modules-list-table .ts-module-setup-cell { width: 56px !important; min-width: 56px !important; text-align: center !important; }
body.ts-modules-setup-page table.ts-modules-list-table .ts-module-help-cell [class*="fa-"],
body.ts-modules-setup-page table.ts-modules-list-table .ts-module-setup-cell [class*="fa-"] {
	font-size: 16px !important;
	line-height: 1 !important;
}
@media (max-width: 900px) {
	body.ts-modules-setup-page .ts-modules-setup-form #dragDropAreaTabBar > .valignmiddle { flex-wrap: wrap; }
	body.ts-modules-setup-page .ts-modules-setup-form .divfilteralone { order: 2; flex-basis: 100%; }
	body.ts-modules-setup-page .ts-modules-view-tools { order: 1; }
	body.ts-modules-setup-page table.ts-modules-list-table,
	body.ts-modules-setup-page table.ts-modules-list-table tbody { display: block; }
	body.ts-modules-setup-page table.ts-modules-list-table tr.ts-module-list-row {
		display: grid;
		grid-template-columns: minmax(0, 1fr) 40px 40px;
		gap: 4px 8px;
		min-height: 0;
		padding: 12px;
	}
	body.ts-modules-setup-page table.ts-modules-list-table tr.ts-module-list-row > td {
		display: flex;
		align-items: center;
		width: auto !important;
		min-width: 0 !important;
		min-height: 0;
		padding: 2px 4px !important;
		border: 0 !important;
	}
	body.ts-modules-setup-page table.ts-modules-list-table .ts-module-name-cell { grid-column: 1; grid-row: 1; max-width: none !important; }
	body.ts-modules-setup-page table.ts-modules-list-table .ts-module-description-cell { grid-column: 1 / -1; grid-row: 2; color: var(--c-muted); }
	body.ts-modules-setup-page table.ts-modules-list-table .ts-module-help-cell { grid-column: 3; grid-row: 3; justify-content: center; }
	body.ts-modules-setup-page table.ts-modules-list-table .ts-module-version-cell { grid-column: 1; grid-row: 3; }
	body.ts-modules-setup-page table.ts-modules-list-table .ts-module-state-cell { grid-column: 2; grid-row: 1; justify-content: center; }
	body.ts-modules-setup-page table.ts-modules-list-table .ts-module-setup-cell { grid-column: 3; grid-row: 1; justify-content: center; }
}
@media (max-width: 640px) {
	body.ts-modules-setup-page .ts-modules-setup-form .divsearchfield,
	body.ts-modules-setup-page .ts-modules-setup-form .divsearchfield > input:not([type="submit"]),
	body.ts-modules-setup-page .ts-modules-setup-form .divsearchfield > select,
	body.ts-modules-setup-page .ts-modules-setup-form .divsearchfield > .select2-container {
		width: 100% !important;
		max-width: none !important;
	}
	body.ts-modules-setup-page .ts-modules-setup-form .divsearchfield { flex: 1 1 100%; }
	body.ts-modules-setup-page .ts-modules-setup-form .divsearchfield:has(input[type="submit"]) { flex: 0 0 auto; }
}

/* Kanban card metadata rows: one field per line, aligned with the title. */
[data-ts-kanban="shared"] .ts-kanban-meta {
	display: flex;
	flex-direction: row;
	flex-wrap: wrap;
	align-items: center;
	gap: 6px 10px;
	margin-top: 10px;
}
[data-ts-kanban="shared"] .ts-kanban-meta-row {
	display: flex !important;
	align-items: center;
	gap: 8px;
	margin: 0 !important;
	padding: 0 !important;
	color: var(--c-ink-2);
	font-size: 0.8125rem;
	opacity: 1 !important;
}
[data-ts-kanban="shared"] .ts-kanban-meta-row [class*="fa-"] {
	flex: 0 0 16px;
	width: 16px;
	text-align: center;
	opacity: .6;
}
[data-ts-kanban="shared"] .ts-kanban-meta-row .badge-status { margin-left: 0; }

/* ==========================================================================
   Icon-only actions

   Dolibarr's inline edit/copy/view actions rendered at whatever size their
   content and inherited line-height produced: measured across record cards the
   same .editfielda was 14x17 bare inline in one place and 32x24 or 34x24 with a
   radius in another, holding a 22px icon in a 24px box. The glyph is centred in
   that box, but a squat rectangle around a nearly-overflowing icon reads as
   off-centre, and the hover surface differed per page.

   One square interaction box, with the icon's own line-height and spacing
   neutralised so nothing can push it off centre. Only actions that are icon-only
   are matched -- labelled buttons keep their own shape.
   ========================================================================== */
a.editfielda,
a.editfield,
span.editfielda,
.ts-icon-action {
	box-sizing: border-box !important;
	display: inline-flex !important;
	align-items: center !important;
	justify-content: center !important;
	width: 32px !important;
	height: 32px !important;
	min-width: 32px !important;
	padding: 0 !important;
	margin: 0 2px !important;
	border-radius: 8px;
	line-height: 1 !important;
	text-indent: 0 !important;
	vertical-align: middle;
	color: var(--c-ink-subtle);
	transition: background var(--t), color var(--t);
}
a.editfielda:hover,
a.editfield:hover,
.ts-icon-action:hover {
	background: var(--c-sunken);
	color: var(--c-accent);
}
a.editfielda:focus-visible,
a.editfield:focus-visible,
.ts-icon-action:focus-visible {
	outline: 2px solid var(--c-accent);
	outline-offset: 1px;
}
/* The glyph itself carries Dolibarr's line-height and padding; neutralise both
   so the flex centring is the only thing positioning it. */
a.editfielda > [class*="fa-"],
a.editfield > [class*="fa-"],
span.editfielda > [class*="fa-"],
.ts-icon-action > [class*="fa-"],
a.editfielda > svg,
a.editfield > svg,
span.editfielda > svg,
.ts-icon-action > svg {
	display: inline-flex !important;
	align-items: center !important;
	justify-content: center !important;
	width: 14px !important;
	height: 14px !important;
	min-width: 14px !important;
	max-width: 14px !important;
	min-height: 14px !important;
	max-height: 14px !important;
	flex: 0 0 14px !important;
	box-sizing: border-box !important;
	margin: 0 !important;
	padding: 0 !important;
	line-height: 1 !important;
	font-size: 13px !important;
	vertical-align: middle !important;
}

/* Lists whose leading select column is never filled -- see
   collapseUnusedSelectColumn(). Marked in script because emptiness cannot be
   tested in CSS. */
table.liste.ts-list-no-select-col > tbody > tr > *:first-child {
	width: 0 !important;
	min-width: 0 !important;
	max-width: 0 !important;
	padding-left: 0 !important;
	padding-right: 0 !important;
	overflow: hidden;
}

/* Member note tab: turn the native detail and note tables into the same calm
   cards used by the other member/record tabs.  The original tables and edit
   links remain in place so permissions and note actions are untouched. */
body.page-card_note .ts-member-note-details {
	display: block;
	width: 100% !important;
	margin: 0 0 16px !important;
	padding: 16px 20px !important;
	border: 1px solid #e7e9ee !important;
	border-radius: 12px !important;
	background: #fff !important;
	box-shadow: 0 4px 16px rgba(15,23,42,.045) !important;
	border-collapse: separate !important;
}
body.page-card_note .ts-member-note-details tr {
	display: grid;
	width: 100%;
	grid-template-columns: minmax(180px, 32%) minmax(0, 1fr);
	min-height: 44px;
	align-items: center;
	border-bottom: 1px solid #f0f2f5;
}
body.page-card_note .ts-member-note-details tbody { display: block; width: 100%; }
body.page-card_note .ts-member-note-details tr:last-child { border-bottom: 0; }
body.page-card_note .ts-member-note-details td {
	padding: 11px 0 !important;
	border: 0 !important;
	font-size: 13px !important;
}
body.page-card_note .ts-member-note-details td:first-child {
	color: #526581;
	font-weight: 650;
}
body.page-card_note .ts-member-note-details td.valeur {
	color: #24324a;
	font-weight: 500;
}
body.page-card_note .ts-member-note-card {
	display: block;
	width: 100% !important;
	margin: 0 0 16px !important;
	padding: 0 !important;
	border: 1px solid #e7e9ee !important;
	border-radius: 12px !important;
	background: #fff !important;
	box-shadow: 0 4px 16px rgba(15,23,42,.045) !important;
	border-collapse: separate !important;
	overflow: hidden;
}
body.page-card_note .ts-member-note-card tr {
	display: flex;
	width: 100%;
	align-items: center;
	justify-content: space-between;
	min-height: 54px;
	padding: 0 18px;
	border-bottom: 1px solid #edf0f4;
}
body.page-card_note .ts-member-note-card tbody { display: block; width: 100%; }
body.page-card_note .ts-member-note-card tr > td {
	padding: 0 !important;
	border: 0 !important;
	font-size: 15px !important;
	font-weight: 650;
	color: #24324a;
}
body.page-card_note .ts-member-note-card tr > td.right { flex: 0 0 auto; }
body.page-card_note .ts-member-note-card .editfielda {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	border-radius: 7px;
	color: var(--c-accent) !important;
}
body.page-card_note .ts-member-note-card .editfielda:hover,
body.page-card_note .ts-member-note-card .editfielda:focus-visible { background: var(--c-accent-soft); }
body.page-card_note .ts-member-note-card .editfielda .fa-pencil-alt {
	float: none !important;
	color: currentColor !important;
}
/* The tagtable row only ever carried the note's two halves side by side; now
   that the card holds both, the row and its cells step out of the way. */
body.page-card_note .ts-member-note-wrapper {
	display: block;
	border: 0 !important;
	background: none !important;
}
body.page-card_note .ts-member-note-row { display: contents; }
body.page-card_note .ts-member-note-head {
	display: block !important;
	width: auto !important;
	padding: 0 !important;
	border: 0 !important;
	background: none !important;
}
body.page-card_note .ts-member-note-card .ts-member-note-body {
	display: block;
	width: auto !important;
	min-height: 74px;
	padding: 18px !important;
	border: 0 !important;
	background: none !important;
	color: #24324a;
	font-size: 14px;
	line-height: 1.6;
	overflow-wrap: anywhere;
}
/* Editing a note opens inside the card, so the editor is sized to the card
   rather than to the twelve rows the markup asks for. */
body.page-card_note .ts-member-note-card .ts-member-note-body form {
	width: 100% !important;
	max-width: none !important;
	margin: 0 !important;
	padding: 0 !important;
	border: 0 !important;
	border-radius: 0 !important;
	background: none !important;
	box-shadow: none !important;
}
body.page-card_note .ts-member-note-card .ts-member-note-body textarea {
	box-sizing: border-box;
	width: 100% !important;
	min-height: 132px;
	height: 132px;
	resize: vertical;
}
body.page-card_note .ts-member-note-card .ts-member-note-body .clearboth { height: var(--sp-3); }
body.page-card_note .ts-member-note-card .ts-member-note-body input[type="submit"] + input[type="submit"] {
	margin-left: var(--sp-2);
}
/* A note reads as a labelled field: the label names it and the note itself
   belongs beside that label, not on a line of its own underneath. The card is
   laid out in two columns so the two stay on one line. */
body.page-card_note .ts-member-note-card {
	display: grid !important;
	/* A note card is full width on a record tab but shares the page with the
	   details panel on a member, so the label column is capped in both absolute
	   and relative terms -- it never grows past its text, and never squeezes the
	   note beside it on the narrower card. */
	grid-template-columns: minmax(140px, min(220px, 30%)) minmax(0, 1fr);
	align-items: stretch;
}
body.page-card_note .ts-member-note-card > tbody {
	min-width: 0;
	border-right: 1px solid #edf0f4;
}
body.page-card_note .ts-member-note-card > tbody > tr {
	height: 100%;
	border-bottom: 0;
}
body.page-card_note .ts-member-note-card > .ts-member-note-body,
body.page-card_note .ts-member-note-card > .ts-member-note-empty {
	display: flex;
	align-items: center;
	min-height: 54px;
	align-self: stretch;
}
/* While the note is being edited the editor is the tall one, so it and the
   label it belongs to both start at the top of the card rather than floating
   in the middle of it. */
/* Keyed on the editor itself: some records wrap the whole page in a single
   form, so the note cell holds the textarea and its buttons directly. */
body.page-card_note .ts-member-note-card > .ts-member-note-body:has(form),
body.page-card_note .ts-member-note-card > .ts-member-note-body:has(textarea) {
	display: block;
}
body.page-card_note .ts-member-note-card:has(> .ts-member-note-body form) > tbody > tr,
body.page-card_note .ts-member-note-card:has(> .ts-member-note-body textarea) > tbody > tr {
	align-items: flex-start;
	padding-top: 17px;
}

body.page-card_note .ts-member-note-empty {
	display: flex;
	align-items: center;
	min-height: 104px;
	padding: 18px;
	color: #7b8ba3;
	font-size: 13px;
}
/* Secondary record tabs (members, documents, notes, events, etc.) share the
   same entity/header and tab surfaces as the primary record view. */
body.ts-command-record-secondary div.tabBar.ts-entity-card > div.arearef,
body.ts-command-record-secondary div.tabBar.ts-entity-card > div.arearefnobottom,
body.ts-command-record-secondary div.tabBar.ts-entity-card > div.arearefnoborder {
	margin: 0 0 var(--sp-4) !important;
	border: 1px solid var(--c-border) !important;
	border-radius: var(--r-lg) !important;
	background: var(--c-surface) !important;
	box-shadow: var(--sh-sm) !important;
}
body.ts-command-record-secondary div.tabBar.ts-entity-card > :first-child:not(.tabs) {
	background: var(--c-surface) !important;
	border: 1px solid var(--c-border) !important;
	border-radius: var(--r-lg) !important;
	box-shadow: var(--sh-sm) !important;
}
body.ts-command-record-secondary div.tabBar.ts-entity-card > form > .arearef,
body.ts-command-record-secondary div.tabBar.ts-entity-card > form > .arearefnobottom,
body.ts-command-record-secondary div.tabBar.ts-entity-card > form > .arearefnoborder {
	display: flex;
	align-items: center;
	gap: 16px;
	min-height: 104px;
	margin: 0 0 var(--sp-4) !important;
	padding: 20px 24px !important;
	box-sizing: border-box;
	background: var(--c-surface) !important;
	border: 1px solid var(--c-border) !important;
	border-radius: var(--r-lg) !important;
	box-shadow: var(--sh-sm) !important;
}
body.ts-command-record-secondary div.tabBar.ts-entity-card > div.tabs {
	margin: 0 0 var(--sp-4) !important;
	padding: 0 var(--sp-3);
	background: var(--c-surface);
	border: 1px solid var(--c-border);
	border-radius: var(--r-lg);
	box-shadow: var(--sh-sm);
}
body.ts-command-record-secondary div.tabBar.ts-entity-card .tabs {
	background: var(--c-surface);
	border: 1px solid var(--c-border);
	border-radius: var(--r-lg);
	box-shadow: var(--sh-sm);
}
body.ts-command-record-secondary div.tabBar.ts-entity-card > form > .tabs {
	display: block;
	margin: 0 0 var(--sp-4) !important;
	padding: 0 var(--sp-3);
	background: var(--c-surface);
	border: 1px solid var(--c-border);
	border-radius: var(--r-lg);
	box-shadow: var(--sh-sm);
}
body.page-card_note .ts-member-note-layout { display: grid; grid-template-columns: minmax(420px, 48%) minmax(0, 1fr); gap: 16px; width: 100%; align-items: start; }
body.page-card_note .ts-member-note-layout > .ts-member-note-details { width: 100% !important; margin: 0 !important; }
body.page-card_note .ts-member-note-grid { display: grid; grid-template-columns: 1fr; gap: 16px; width: 100%; }
body.page-card_note .ts-member-note-details td:first-child { width: 190px; white-space: nowrap; }
body.page-card_note .ts-member-note-grid .ts-member-note-card { width: 100% !important; margin: 0 !important; min-height: 132px; }
body.page-card_note .ts-member-note-grid .ts-member-note-card tr { min-height: 48px; padding: 0 20px; border-bottom: 1px solid #edf0f4; }
body.page-card_note .ts-member-note-grid .ts-member-note-card .ts-member-note-empty { min-height: 74px; padding: 18px 20px; }
body.page-card_note .ts-member-note-grid .ts-member-note-card .editfielda { width: 34px; height: 34px; border-radius: 8px; }
body.page-card_note .ts-member-note-grid .ts-member-note-card .editfielda .fa-pencil-alt { font-size: 13px !important; }
@media (max-width: 760px) {
	body.page-card_note .ts-member-note-layout { display: block; }
	body.page-card_note .ts-member-note-layout > .ts-member-note-details { width: 100% !important; margin-bottom: 16px !important; }
}

body.ts-member-documents-page .ts-member-files-details { display:block; width:100% !important; margin:0 0 16px !important; padding:12px 18px !important; border:1px solid #e7e9ee !important; border-radius:12px !important; background:#fff !important; box-shadow:0 4px 16px rgba(15,23,42,.045) !important; border-collapse:separate !important; }
body.ts-member-documents-page .ts-member-files-details tbody { display:block; width:100%; }
body.ts-member-documents-page .ts-member-files-details tr { display:grid; width:100%; grid-template-columns:minmax(220px,34%) minmax(0,1fr); align-items:center; min-height:42px; border-bottom:1px solid #f0f2f5; }
body.ts-member-documents-page .ts-member-files-details tr:last-child { border-bottom:0; }
body.ts-member-documents-page .ts-member-files-details td { padding:10px 0 !important; border:0 !important; font-size:13px !important; }
body.ts-member-documents-page table.ts-member-files-details > tbody > tr > td {
	border: 0 !important;
	border-width: 0 !important;
	border-style: none !important;
	box-shadow: none !important;
}
/* The row is a grid, so its cells take their width from the tracks it defines.
   A core rule pins the first cell of a field table to 14%, which here is much
   narrower than the track it sits in: the labels wrapped over two and three
   lines while the space beside them stayed empty. */
body.ts-member-documents-page table.ts-member-files-details > tbody > tr > td:first-child,
body.ts-member-documents-page table.ts-member-files-details > tbody > tr > td:nth-child(n+2) {
	width: auto !important;
	min-width: 0;
}
body.ts-member-documents-page .ts-member-files-details td:first-child { color:#526581; font-weight:650; }
body.ts-member-documents-page .ts-member-files-details td.valeur, body.ts-member-documents-page .ts-member-files-details td[colspan] { color:#24324a; }
body.ts-member-documents-page .ts-member-files-attached-head { display:flex !important; align-items:center; justify-content:space-between; margin:0 0 10px !important; padding:0 !important; min-height:48px; }
body.ts-member-documents-page .ts-member-files-attached-head .ts-pagehead-icon, body.ts-member-documents-page .ts-member-files-linked-head .pictotitle { display:inline-flex; align-items:center; justify-content:center; width:40px; height:40px; margin-right:10px; border-radius:10px; background:var(--c-accent-soft); color:var(--c-accent); }
body.ts-member-documents-page .ts-member-files-attached-head .titre, body.ts-member-documents-page .ts-member-files-linked-head .titre { font-size:20px !important; font-weight:700 !important; color:var(--c-ink) !important; }
body.ts-member-documents-page .ts-member-files-attached-title { display:none !important; }
body.ts-member-documents-page .ts-member-files-attached-head .ts-pagehead-actions { margin-left:auto; }
body.ts-member-documents-page .ts-member-files-upload { display:none; margin:0 0 12px; padding:14px 16px; border:1px dashed #c8bfff; border-radius:10px; background:#faf9ff; }
body.ts-member-documents-page .ts-member-files-upload:not(.hidden) { display:block; }
body.ts-member-documents-page .ts-member-files-upload form { margin:0; }
body.ts-member-documents-page .ts-member-files-upload table { width:100%; margin:0; }
body.ts-member-documents-page .ts-member-files-upload td { padding:0 !important; border:0 !important; }
body.ts-member-documents-page .ts-member-files-upload input[type=file] { width:min(100%,520px); height:40px; padding:5px 8px; border:1px solid #dbe2ec; border-radius:8px; background:#fff; color:#526581; font-size:13px; }
body.ts-member-documents-page .ts-member-files-upload input[type=file]::file-selector-button { margin-right:10px; padding:7px 12px; border:0; border-radius:6px; background:#eef0ff; color:var(--c-accent); font-weight:650; cursor:pointer; }
body.ts-member-documents-page .ts-member-files-upload input[type=submit] { margin-left:10px; }
body.ts-member-documents-page .ts-member-files-documents, body.ts-member-documents-page .ts-member-files-linked-form { display:block; margin:0 0 16px; padding:0 !important; border:1px solid #e7e9ee; border-radius:12px; background:#fff; box-shadow:0 4px 16px rgba(15,23,42,.045); overflow:hidden; }
body.ts-member-documents-page .ts-member-files-doc-table, body.ts-member-documents-page .ts-member-files-link-table { width:100%; margin:0 !important; border:0 !important; }
body.ts-member-documents-page .ts-member-files-doc-table th, body.ts-member-documents-page .ts-member-files-link-table th { height:44px; padding:0 14px !important; background:#f8fafc !important; color:#526581 !important; font-size:12px !important; font-weight:700 !important; border-bottom:1px solid #e7e9ee !important; }
body.ts-member-documents-page .ts-member-files-doc-table td, body.ts-member-documents-page .ts-member-files-link-table td { height:48px; padding:0 14px !important; border-bottom:1px solid #f0f2f5 !important; font-size:13px; }
body.ts-member-documents-page .ts-member-files-doc-table td[colspan], body.ts-member-documents-page .ts-member-files-link-table td[colspan] { height:112px; text-align:center !important; color:#8a9ab3 !important; }
body.ts-member-documents-page .ts-member-files-linked-head { display:block !important; margin:16px 0 10px !important; padding:12px 16px !important; border:1px solid #e7e9ee; border-radius:12px; background:#fff; box-shadow:0 4px 16px rgba(15,23,42,.045); }
body.ts-member-documents-page .ts-member-files-linked-head tbody { display:block; }
body.ts-member-documents-page .ts-member-files-linked-head tr { display:flex; align-items:center; width:100%; }
body.ts-member-documents-page .ts-member-files-linked-head td { border:0 !important; padding:0 !important; }
body.ts-member-documents-page .ts-member-files-linked-head .col-picto { flex:0 0 auto; }
body.ts-member-documents-page .ts-member-files-linked-head .col-title { flex:1 1 auto; }
body.ts-member-documents-page .ts-member-files-linked-head .col-right { margin-left:auto; }
body.ts-member-documents-page .ts-member-files-linked-head .col-right .btnTitle { display:inline-flex; align-items:center; justify-content:center; width:32px; height:32px; }
body.mod-member table.ts-member-recent-events { margin-top:16px !important; }
body.mod-member .ts-member-recent-events-section { margin-top:16px !important; }
body.mod-member .ts-record-section-events { margin-top:16px !important; }
/* Keep the event Type heading/value readable in the compact member card. The
   native auto table algorithm was assigning that column ~30px, producing
   a clipped “T...”; reserve a real label slot and let Title absorb the rest. */
body.mod-member .ts-record-section-events table.listactions th:nth-child(4),
body.mod-member .ts-record-section-events table.listactions td:nth-child(4) {
	min-width:64px !important;
	white-space:nowrap;
}
/* Member detail values (notably the linked Type label) must not collapse into
   a clipped one-letter fragment when the legacy half-column table is placed in
   the COMMAND card. Keep the value/link as one readable inline unit. */
body.mod-member .fichecenter .fichehalfleft td.valeur,
body.mod-member .fichecenter .fichehalfright td.valeur {
	min-width: 0;
	white-space: nowrap;
	overflow: visible !important;
}
body.mod-member .fichecenter .fichehalfleft td.valeur a,
body.mod-member .fichecenter .fichehalfright td.valeur a {
	display: inline-flex;
	align-items: center;
	max-width: 100%;
	white-space: nowrap;
}

/* Translation administration is a real filterable data grid, not a settings
   table. Keep all four rows on the same desktop columns and let filter fields
   use those columns; the old 280px cap left two detached boxes floating inside
   much wider cells. */
body.ts-translation-admin table.ts-translation-grid {
	table-layout: fixed;
	font-size: .875rem;
}
body.ts-translation-admin table.ts-translation-grid tr > :nth-child(1) { width: 18% !important; }
body.ts-translation-admin table.ts-translation-grid tr > :nth-child(2) { width: 38% !important; text-align: left !important; }
body.ts-translation-admin table.ts-translation-grid tr > :nth-child(3) { width: 36% !important; text-align: left !important; }
body.ts-translation-admin table.ts-translation-grid tr > :nth-child(4) { width: 8% !important; text-align: center !important; }
body.ts-translation-admin table.ts-translation-grid tr.liste_titre_filter > td {
	padding: 12px 8px !important;
	vertical-align: middle;
	background: transparent !important;
	border-bottom: 0 !important;
}
body.ts-translation-admin table.ts-translation-grid tr.liste_titre_filter input[type="text"],
body.ts-translation-admin table.ts-translation-grid tr.liste_titre_filter .select2-container {
	width: 100% !important;
	max-width: none !important;
	height: 40px !important;
	min-height: 40px !important;
	margin: 0 !important;
}
body.ts-translation-admin table.ts-translation-grid tr.liste_titre_filter .select2-selection--single {
	height: 40px !important;
	min-height: 40px !important;
}
body.ts-translation-admin table.ts-translation-grid tr.liste_titre_filter .select2-selection__rendered { line-height: 38px !important; }
body.ts-translation-admin table.ts-translation-grid tr.liste_titre_filter .select2-selection__arrow { height: 38px !important; }
body.ts-translation-admin table.ts-translation-grid tr.liste_titre_filter td:last-child > .nowraponall {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
}
body.ts-translation-admin table.ts-translation-grid tr.liste_titre_filter .button_search,
body.ts-translation-admin table.ts-translation-grid tr.liste_titre_filter .button_removefilter {
	width: 36px !important;
	height: 36px !important;
	min-width: 36px !important;
	padding: 0 !important;
	display: inline-flex;
	align-items: center;
	justify-content: center;
}
body.ts-translation-admin table.ts-translation-grid tr.oddeven > td,
body.ts-translation-admin table.ts-translation-grid tr.impair > td,
body.ts-translation-admin table.ts-translation-grid tr.pair > td {
	font-family: inherit !important;
	font-size: .875rem !important;
	line-height: 1.4;
}
body.ts-translation-admin table.ts-translation-grid tr.oddeven > td:nth-child(2),
body.ts-translation-admin table.ts-translation-grid tr.impair > td:nth-child(2),
body.ts-translation-admin table.ts-translation-grid tr.pair > td:nth-child(2) {
	font-weight: 520;
	overflow-wrap: anywhere;
}
body.ts-translation-admin table.ts-translation-grid tr.oddeven > td:nth-child(3),
body.ts-translation-admin table.ts-translation-grid tr.impair > td:nth-child(3),
body.ts-translation-admin table.ts-translation-grid tr.pair > td:nth-child(3) {
	color: var(--c-ink-2);
	overflow-wrap: anywhere;
}
body.ts-translation-admin table.ts-translation-grid td:last-child .ts-icon-action {
	margin: 0 auto;
}
@media (max-width:700px) {
	body.ts-translation-admin table.ts-translation-grid,
	body.ts-translation-admin table.ts-translation-grid > tbody { display: block; width: 100%; }
	body.ts-translation-admin table.ts-translation-grid tr.liste_titre_filter {
		display: grid;
		grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto;
		gap: 8px;
		padding: 12px;
		background: var(--c-surface);
	}
	body.ts-translation-admin table.ts-translation-grid tr.liste_titre_filter > td {
		display: block;
		width: auto !important;
		padding: 0 !important;
		min-width: 0;
	}
	body.ts-translation-admin table.ts-translation-grid tr.liste_titre_filter > td:first-child {
		grid-column: 1 / -1;
		width: 100% !important;
		background: transparent;
	}
	body.ts-translation-admin table.ts-translation-grid tr.liste_titre_filter > td:first-child .select2-container {
		width: min(100%, 300px) !important;
	}
	body.ts-translation-admin table.ts-translation-grid tr.liste_titre_filter > td:last-child { align-self: center; }
	body.ts-translation-admin table.ts-translation-grid tr.liste_titre:not(.liste_titre_filter) { display: none; }
	body.ts-translation-admin table.ts-translation-grid tr.oddeven,
	body.ts-translation-admin table.ts-translation-grid tr.impair,
	body.ts-translation-admin table.ts-translation-grid tr.pair {
		display: grid;
		grid-template-columns: minmax(0, 1fr) 36px;
		grid-template-rows: auto auto;
		column-gap: 8px;
		padding: 10px 12px;
		min-height: 68px;
	}
	body.ts-translation-admin table.ts-translation-grid tr.oddeven > td,
	body.ts-translation-admin table.ts-translation-grid tr.impair > td,
	body.ts-translation-admin table.ts-translation-grid tr.pair > td {
		display: block;
		width: auto !important;
		height: auto !important;
		min-width: 0;
		padding: 3px 0 !important;
		border: 0 !important;
	}
	body.ts-translation-admin table.ts-translation-grid tr.oddeven > td:first-child,
	body.ts-translation-admin table.ts-translation-grid tr.impair > td:first-child,
	body.ts-translation-admin table.ts-translation-grid tr.pair > td:first-child { display: none; }
	body.ts-translation-admin table.ts-translation-grid tr.oddeven > td:nth-child(2),
	body.ts-translation-admin table.ts-translation-grid tr.impair > td:nth-child(2),
	body.ts-translation-admin table.ts-translation-grid tr.pair > td:nth-child(2) { grid-column: 1; grid-row: 1; }
	body.ts-translation-admin table.ts-translation-grid tr.oddeven > td:nth-child(3),
	body.ts-translation-admin table.ts-translation-grid tr.impair > td:nth-child(3),
	body.ts-translation-admin table.ts-translation-grid tr.pair > td:nth-child(3) { grid-column: 1; grid-row: 2; font-size: .8125rem !important; }
	body.ts-translation-admin table.ts-translation-grid tr.oddeven > td:last-child,
	body.ts-translation-admin table.ts-translation-grid tr.impair > td:last-child,
	body.ts-translation-admin table.ts-translation-grid tr.pair > td:last-child {
		grid-column: 2;
		grid-row: 1 / 3;
		align-self: center;
	}
}
@media (max-width:700px) {
	body.mod-member .fichecenter .fichehalfleft td.valeur,
	body.mod-member .fichecenter .fichehalfright td.valeur,
	body.mod-member .fichecenter .fichehalfleft td.valeur a,
	body.mod-member .fichecenter .fichehalfright td.valeur a { white-space: normal; }
}
@media (max-width:700px) { body.ts-member-documents-page .ts-member-files-details tr { grid-template-columns:1fr; gap:0; padding:5px 0; } body.ts-member-documents-page .ts-member-files-upload input[type=file] { width:100%; margin-bottom:8px; } body.ts-member-documents-page .ts-member-files-upload input[type=submit] { margin-left:0; } }
body.page-card_note div.tabBar.ts-entity-card > form {
	margin: 0 !important;
	padding: 0 !important;
	background: transparent !important;
	border: 0 !important;
	box-shadow: none !important;
}
body.page-card_note form {
	background: transparent !important;
	border: 0 !important;
	box-shadow: none !important;
}
body.page-card_note div.tabBar.ts-entity-card > form > .arearef {
	min-height: 104px !important;
	height: 145px !important;
}
body.page-card_note div.tabBar.ts-entity-card > form > .fichecenter {
	margin: 0 !important;
	padding: 0 !important;
	background: transparent !important;
}

/* Shared User-record tab rhythm. User detail tabs expose the same Dolibarr
   heading and field-table structures as other records, so normalize the
   structure once instead of relying on each individual URL. */
body.mod-user .ts-user-record-content { display: flow-root; }
body.mod-user .ts-user-detail-card { display:block; width:100% !important; margin:0 0 16px !important; padding:0 !important; border:1px solid var(--c-border) !important; border-radius:var(--r-lg) !important; background:var(--c-surface) !important; box-shadow:var(--sh-sm) !important; overflow:hidden; border-collapse:separate !important; }
body.mod-user .ts-user-detail-card tbody { display:block; width:100%; }
body.mod-user .ts-user-detail-card tr { display:grid; grid-template-columns:minmax(210px,34%) minmax(0,1fr); align-items:center; min-height:46px; border-bottom:1px solid var(--c-border-subtle); }
body.mod-user .ts-user-detail-card tr:last-child { border-bottom:0; }
body.mod-user .ts-user-detail-card td { width:auto !important; min-width:0 !important; max-width:none !important; padding:11px 18px !important; border:0 !important; line-height:1.35; overflow:visible !important; white-space:normal !important; }
body.mod-user .ts-user-detail-card td:first-child { font-weight:650; color:var(--c-ink); }
body.mod-user .ts-user-detail-card td.valeur { color:var(--c-text); }
body.mod-user .ts-user-section-heading { display:flex !important; align-items:center; gap:10px; min-height:48px; margin:24px 0 12px !important; padding:0 !important; }
body.mod-user .ts-user-section-heading .ts-pagehead-actions { margin-left:auto; }
body.mod-user .ts-user-section-surface, body.mod-user .ts-user-section-heading + form, body.mod-user .ts-user-section-heading + .div-table-responsive, body.mod-user .ts-user-section-heading + .div-table-responsive-no-min { margin:0 0 20px !important; }
/* A page heading begins a new section. It must not fuse with the preceding
   detail-card, and side-by-side record cards must retain intrinsic height. */
body.mod-user .fichecenter:has(> .ts-pagehead) { margin-top:24px !important; }
body.mod-user .fichehalfleft, body.mod-user .fichehalfright { align-self:start !important; }
body.mod-user .ts-record-section-events { margin-top:20px !important; }
/* Event header utilities are true icon actions, not loose adjacent glyphs. */
body.mod-user .ts-record-section-events .btnTitle, body.mod-user .ts-record-section-events a[class*="butAction"]:has(> [class*="fa-"]) { display:inline-flex !important; align-items:center !important; justify-content:center !important; width:34px !important; height:34px !important; min-width:34px !important; padding:0 !important; margin-left:8px !important; line-height:1 !important; border-radius:8px !important; }
body.mod-user .ts-record-section-events .btnTitle > [class*="fa-"], body.mod-user .ts-record-section-events a[class*="butAction"]:has(> [class*="fa-"]) > [class*="fa-"] { margin:0 !important; line-height:1 !important; }
/* Agenda tables need space for owner/type/label, rather than letting Ref/Date
   absorb the row. The filter row is a stable COMMAND toolbar. */
body.mod-user .ts-user-agenda-filter { display:flex !important; flex-wrap:wrap; align-items:end; gap:10px !important; margin:0 0 14px !important; padding:14px 16px !important; border:1px solid var(--c-border) !important; border-radius:var(--r-lg) !important; background:var(--c-surface) !important; box-shadow:var(--sh-sm) !important; }
body.mod-user .ts-user-agenda-filter > * { margin:0 !important; }
body.mod-user .ts-user-agenda-table { table-layout:fixed; }
body.mod-user .ts-user-agenda-table th:nth-child(1), body.mod-user .ts-user-agenda-table td:nth-child(1) { width:8% !important; }
body.mod-user .ts-user-agenda-table th:nth-child(2), body.mod-user .ts-user-agenda-table td:nth-child(2) { width:13% !important; }
body.mod-user .ts-user-agenda-table th:nth-child(3), body.mod-user .ts-user-agenda-table td:nth-child(3) { width:17% !important; }
body.mod-user .ts-user-agenda-table th:nth-child(4), body.mod-user .ts-user-agenda-table td:nth-child(4) { width:13% !important; }
body.mod-user .ts-user-agenda-table th:nth-child(5), body.mod-user .ts-user-agenda-table td:nth-child(5) { width:auto !important; }
body.mod-user .ts-user-agenda-table th > img, body.mod-user .ts-user-agenda-table td > img, body.page-card_perms .div-table-responsive-no-min img.pictofixedwidth { max-width:20px !important; max-height:20px !important; width:auto !important; height:auto !important; object-fit:contain; vertical-align:middle; }
/* Inline note editors occur in Member, Contact and User tabs. Constrain the
   real form to a calm card without changing its submit/token behaviour. */
body.page-card_note form:has(textarea[name*="note"]), body.page-contact-card_note form:has(textarea[name*="note"]), body.page-user-note form:has(textarea[name*="note"]) { max-width:900px; margin:16px 0 !important; padding:20px !important; border:1px solid var(--c-border) !important; border-radius:var(--r-lg) !important; background:var(--c-surface) !important; box-shadow:var(--sh-sm) !important; }
body.page-card_note form textarea[name*="note"], body.page-contact-card_note form textarea[name*="note"], body.page-user-note form textarea[name*="note"] { width:100% !important; min-height:150px !important; box-sizing:border-box; }
body.mod-user textarea#note_public, body.mod-user textarea#note_private { width:100% !important; height:150px !important; min-height:150px !important; max-height:220px; box-sizing:border-box !important; resize:vertical; }
@media (max-width:900px) { body.mod-user .ts-user-detail-card tr { grid-template-columns:minmax(160px,36%) minmax(0,1fr); } }
@media (max-width:700px) { body.mod-user .ts-user-detail-card tr { grid-template-columns:1fr; padding:5px 0; } body.mod-user .ts-user-detail-card td { padding:6px 14px !important; } body.mod-user .ts-user-agenda-filter { align-items:stretch; } body.mod-user .ts-user-agenda-filter > * { width:100%; } }

/* COMMAND action colour contract.

   Native setup pages do not all receive the settings-page composer (Display
   deliberately has its own layout), but their Save control still carries the
   same semantic Dolibarr classes.  Resolve every real Save action through the
   configured action-button tokens instead of letting an inherited native
   button rule choose a separate colour.  Cancel remains a neutral escape
   route. */
body:not(.bodylogin) input.button-save,
body:not(.bodylogin) button.button-save,
body:not(.bodylogin) input.buttonforacesave,
body:not(.bodylogin) button.buttonforacesave,
body:not(.bodylogin) input[type="submit"][name="submit"]:not(.button-cancel),
body:not(.bodylogin) button[type="submit"][name="submit"]:not(.button-cancel),
body:not(.bodylogin) input[type="submit"][name="modify"]:not(.button-cancel),
body:not(.bodylogin) button[type="submit"][name="modify"]:not(.button-cancel) {
	border-color: var(--c-btn-action) !important;
	background: var(--c-btn-action) !important;
	color: var(--c-btn-action-text) !important;
	box-shadow: 0 1px 2px var(--c-btn-action-ring) !important;
}
body:not(.bodylogin) input.button-save:hover,
body:not(.bodylogin) button.button-save:hover,
body:not(.bodylogin) input.buttonforacesave:hover,
body:not(.bodylogin) button.buttonforacesave:hover,
body:not(.bodylogin) input[type="submit"][name="submit"]:not(.button-cancel):hover,
body:not(.bodylogin) button[type="submit"][name="submit"]:not(.button-cancel):hover,
body:not(.bodylogin) input[type="submit"][name="modify"]:not(.button-cancel):hover,
body:not(.bodylogin) button[type="submit"][name="modify"]:not(.button-cancel):hover {
	filter: brightness(.94);
}
body:not(.bodylogin) input.button-cancel,
body:not(.bodylogin) button.button-cancel,
body:not(.bodylogin) input[name="cancel"],
body:not(.bodylogin) button[name="cancel"] {
	border-color: var(--c-border) !important;
	background: var(--c-surface) !important;
	color: var(--c-ink-2) !important;
	box-shadow: none !important;
}

/* A Select2 container owns the trigger width.  Native widthNN classes are
   duplicated onto the inner selection by Dolibarr; if that inner width wins,
   the visible border ends before its arrow (as on Menu handler).  Make the
   selection fill its real container so text, border and chevron remain one
   control everywhere. */
body .select2-container > .selection,
body .select2-container > .selection > .select2-selection {
	display: block;
	width: 100% !important;
	box-sizing: border-box;
}
/* The generic selection-width rule above must not turn a multiple Select2 back
   into a block formatting context.  Its rendered choices and inline editor are
   one control row; when the outer selection is block while the UL is
   display:contents, Select2's floated choice is painted above the border and
   only the empty editor remains visible.  Restore the flex ownership globally,
   then keep toolbar filters on one stable line so choosing an option never
   changes the control's width or height. */
body .select2-container > .selection > .select2-selection--multiple {
	display: flex;
	align-items: center;
}
body .select2-container .select2-selection--multiple > .select2-selection__rendered {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 4px;
	width: 100%;
	min-width: 0;
	margin: 0;
	padding: 0;
}
body .select2-container .select2-selection--multiple .select2-selection__choice {
	box-sizing: border-box;
	min-width: 0;
	max-width: 100%;
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
}
body .ts-filter-surface .select2-container .select2-selection--multiple > .select2-selection__rendered {
	flex-wrap: nowrap;
	overflow: hidden;
}
body .ts-filter-surface .select2-selection--multiple .select2-selection__choice {
	flex: 0 1 auto;
}
body .ts-filter-surface .select2-selection--multiple .select2-search--inline {
	display: flex;
	align-items: center;
	flex: 1 1 24px;
	min-width: 1px;
	height: 32px;
	overflow: hidden;
}
body .ts-filter-surface .select2-selection--multiple .select2-search__field {
	box-sizing: border-box;
	width: 100% !important;
	min-width: 0 !important;
}
/* Promoted multiple filters must keep every committed value legible. Their
   closed control may grow by a chip row, but must never shrink two labels into
   anonymous fragments or widen the toolbar. */
body .ts-filter-surface > .ts-toolbar-filter .select2-selection--multiple {
	height: auto !important;
	min-height: 40px !important;
	padding-block: 3px !important;
	overflow: visible !important;
}
body .ts-filter-surface > .ts-toolbar-filter .select2-selection--multiple > .select2-selection__rendered {
	flex-wrap: wrap !important;
	align-content: center;
	overflow: visible !important;
}
body .ts-filter-surface > .ts-toolbar-filter .select2-selection--multiple .select2-selection__choice {
	flex: 0 0 auto;
	max-width: calc(100% - 4px);
}
body .ts-filter-surface > .ts-toolbar-filter .select2-container:not(.select2-container--open) .select2-selection--multiple:has(.select2-selection__choice) .select2-search--inline {
	flex-basis: 1px;
	min-width: 1px;
	height: 1px;
	overflow: hidden;
}
/* The compact toolbar owns a fixed one-line control, but the advanced panel
   must show every chosen value.  Let its multiple selections grow into tidy
   chip rows instead of collapsing two representatives into anonymous "..."
   pills.  A single unusually long value may truncate at the control edge; the
   control itself never widens or escapes its grid slot. */
body .ts-column-filters-panel .ts-column-filter-control .select2-selection--multiple {
	height: auto !important;
	min-height: 40px !important;
	padding-block: 3px !important;
	overflow: visible !important;
}
body .ts-column-filters-panel .ts-column-filter-control .select2-selection--multiple > .select2-selection__rendered {
	flex-wrap: wrap !important;
	align-content: center;
	overflow: visible !important;
}
body .ts-column-filters-panel .ts-column-filter-control .select2-selection--multiple .select2-selection__choice {
	flex: 0 1 auto;
	max-width: 100%;
}
body .ts-column-filters-panel .ts-column-filter-control .select2-selection--multiple .select2-search--inline {
	flex: 1 1 42px;
	min-width: 42px;
}
body .ts-column-filters-panel .ts-column-filter-control .select2-container:not(.select2-container--open) .select2-selection--multiple:has(.select2-selection__choice) .select2-search--inline {
	flex-basis: 1px;
	min-width: 1px;
	height: 1px;
	overflow: hidden;
}
body .select2-container--default .select2-selection--single .select2-selection__arrow {
	display: flex;
	align-items: center;
	justify-content: center;
	top: 0 !important;
	right: 0 !important;
	height: 100% !important;
	line-height: 1;
}
body .select2-container--default .select2-selection--single .select2-selection__arrow b {
	position: static !important;
	margin: 0 !important;
}

/* Dolibarr's AJAX on/off controls render both action halves and rely on this
   semantic class to keep the inactive half out of the flow.  A legacy display
   override was leaking it back into COMMAND pages, leaving two toggle icons
   fused together.  Honour the framework contract globally. */
body .hideobject { display: none !important; }

/* AJAX enable/disable controls are actions, not decorative status colours.
   Tie their live state to the administrator-configured action colour instead
   of Font Awesome's fixed status palette.  This keeps every switch in COMMAND
   consistent with Save, Create and other configured primary actions. */
body a:has(> .fa-toggle-on) > .fa-toggle-on,
body button:has(> .fa-toggle-on) > .fa-toggle-on,
body .ts-setting-control .fa-toggle-on,
body .fa-toggle-on.font-status4 {
	color: var(--c-btn-action) !important;
}
body a:has(> .fa-toggle-off) > .fa-toggle-off,
body button:has(> .fa-toggle-off) > .fa-toggle-off,
body .ts-setting-control .fa-toggle-off {
	color: var(--c-faint) !important;
}

/* Shared search/reset icon actions.  Their glyph inherits different native
   line-heights across admin tables; normalize the inner glyph rather than
   letting Search and Clear sit high or low in otherwise identical controls. */
body button.button_search,
body button.button_removefilter,
body input.button_search,
body input.button_removefilter {
	display: inline-flex !important;
	align-items: center !important;
	justify-content: center !important;
	line-height: 1 !important;
}
body button.button_search > [class*="fa-"],
body button.button_removefilter > [class*="fa-"],
body input.button_search > [class*="fa-"],
body input.button_removefilter > [class*="fa-"] {
	margin: 0 !important;
	line-height: 1 !important;
}

/* Empty mandatory cells are layout placeholders in a number of native forms,
   not validation messages.  Rendering them after a file picker produces bare
   vertical asterisks.  Remove only rows with no actual form control/content. */
body form tr:has(> td.fieldrequired:empty):not(:has(input, select, textarea, button, a, img, .select2-container)) {
	display: none !important;
}

/* Email test compose uses the same settings form primitive as the rest of
   admin, but its attach/send/cancel actions are compact inline utilities.
   Keep their hierarchy while avoiding oversized controls in that row. */
body.page-mails form#mailform input.button.smallpaddingimp,
body.page-mails form#mailform .ts-settings-actions .ts-settings-action {
	min-height: 38px !important;
	height: 38px !important;
	min-width: auto;
	padding-inline: 15px !important;
	font-size: 0.8125rem !important;
}
body.page-mails form#mailform input.button.smallpaddingimp {
	border-color: var(--c-btn-action) !important;
	background: var(--c-btn-action) !important;
	color: var(--c-btn-action-text) !important;
}

/* System tools submit real operations, so they follow the configured action
   colour instead of the incidental native .button palette. */
body.page-system_filecheck input[name="check"],
body.page-tools_dolibarr_export input#buttonGo,
body.page-system_dolibarr a.butAction.smallpaddingimp {
	border-color: var(--c-btn-action) !important;
	background: var(--c-btn-action) !important;
	color: var(--c-btn-action-text) !important;
	box-shadow: 0 1px 2px var(--c-btn-action-ring) !important;
}

/* Performance reports are made from repeated heading + divsection pairs.
   Present those native sections as a readable COMMAND report without changing
   any diagnostic content or links. */
body.page-system_perf .fiche > br { display: none; }
body.page-system_perf .fiche > strong {
	display: inline-flex;
	align-items: center;
	margin: 22px 0 8px;
	font-size: 0.875rem;
	font-weight: 650;
	color: var(--c-ink);
}
body.page-system_perf .fiche > span.fas.fa-folder {
	margin: 22px 5px 8px 0;
	color: var(--c-accent);
}
/* The first native heading follows the Reload link directly.  Make that link
   its own line so the Version section begins as a proper section heading,
   consistent with XDebug and the following diagnostic sections. */
body.page-system_perf .fiche > a[href*="/perf.php"] {
	display: block;
	width: fit-content;
	margin: 14px 0 0;
}
body.page-system_perf .fiche > span.fas.fa-folder + strong { margin-left: 5px; }
body.page-system_perf .fiche > .divsection {
	margin: 0 0 18px !important;
	padding: 16px 20px !important;
	border: 1px solid var(--c-border) !important;
	border-radius: var(--r-lg) !important;
	background: var(--c-surface) !important;
	box-shadow: var(--sh-sm);
	line-height: 1.55;
	color: var(--c-ink-2);
}
body.page-system_about .divsection,
body.page-system_about td {
	white-space: normal;
	overflow-wrap: anywhere;
}

/* Native Update/Purge tools place prose, controls, and forms as sibling text
   nodes.  The enhancer groups those nodes, letting the existing settings card
   language give operational instructions a deliberate, readable surface. */
body.page-tools_update .ts-admin-tools-content,
body.page-tools_purge .ts-admin-tools-content {
	max-width: 980px;
	margin: 18px 0 28px;
	padding: 22px 24px;
	border: 1px solid var(--c-border);
	border-radius: var(--r-lg);
	background: var(--c-surface);
	box-shadow: var(--sh-sm);
	line-height: 1.6;
	color: var(--c-ink-2);
}
body.page-tools_update .ts-admin-tools-content hr {
	margin: 14px 0;
	border: 0;
	border-top: 1px solid var(--c-border);
}
body.page-tools_update .ts-admin-tools-content > a.button,
body.page-tools_purge .ts-admin-tools-content input.button {
	min-height: 38px;
	padding-inline: 16px;
	vertical-align: middle;
}
body.page-tools_purge .ts-admin-tools-content .divsection {
	margin: 16px 0 18px !important;
	padding: 16px 18px !important;
	border: 1px solid var(--c-border) !important;
	border-radius: var(--r-md) !important;
	background: color-mix(in srgb, var(--c-canvas) 62%, var(--c-surface)) !important;
}
body.page-tools_purge .ts-admin-tools-content label {
	line-height: 1.55;
}

/* Dashboard widget identities pair a Font Awesome star and a user name.  Keep
   the glyph in the same inline-flex baseline slot as every other compact icon. */
body.ts-command-module-index .ts-module-index-card .fa-star,
body.ts-command-module-index .ts-module-index-card .fa-star-o {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 1em;
	height: 1em;
	margin: 0 .28em 0 0;
	vertical-align: -0.08em;
	line-height: 1;
}
@media (max-width: 700px) {
	body.page-card_note .ts-member-note-details tr { grid-template-columns: 1fr; gap: 2px; padding: 8px 0; }
	body.page-card_note .ts-member-note-details td { padding: 5px 0 !important; }
	body.page-card_note div.tabBar.ts-entity-card > form > .arearef { height: auto !important; }
}




/* IDE Hack <style type="text/css"> */

.mainmenu::before, .mainmenu span::before {
	font-weight: 900;
	font-style: normal;
	font-variant: normal;
	text-rendering: auto;
	line-height: 28px;
	-webkit-font-smoothing: antialiased;
	text-align:center;
	text-decoration:none;
}
.mainmenu:not(.fab)::before, .mainmenu:not(.fab) span:not(.fab)::before {
	font-family: "Font Awesome 5 Free";
}

div.mainmenu.menu {
	background-image: none;
}


div.mainmenu.generic1::before {
	content: "\f249";
}

div.mainmenu.generic2::before {
	content: "\f249";
}

div.mainmenu.generic3::before {
	content: "\f249";
}

div.mainmenu.generic4::before {
	content: "\f249";
}

/* Define color of some picto */

.fa-phone, .fa-mobile-alt, .fa-fax {
	opacity: 0.7;
	color: #440;
}
.fa-at, .fa-external-link-alt, .fa-share-alt {
	opacity: 0.7;
	color: #304;
}
.fa-trash {
	color: #666;
}
.fa-trash:hover:before {
	color: #800;
}
.fa-play {
	color: #444;
}
.fa-link, .fa-unlink {
	color: #555;
}
.fa-project-diagram:before {
	font-size: 0.9em;
}

/* Define square Dolibarr logo in pure CSS */

.fa-dolibarr-css{
	color: #235481;
	background: currentColor;
	height: 150px;
	width: 150px;
	position: relative;
}
.fa-dolibarr-css:before{
	content: '';
	position: absolute;
	left: 19%;
	top: 17%;
	width: 25%;
	height: 25%;
	border: solid 30px white;
	border-radius: 0% 200% 200% 0% / 0% 180% 180% 0%;
}
.fa-dolibarr-css:after{
	content: '';
	position: absolute;
	left: 19%;
	top: 17%;
	width: 5px;
	height: 25%;
	border-bottom: solid 60px currentColor;
	margin-left: 30px;
}
.tmenu span.fas, .tmenu span.far {
	color: unset !important;;
	line-height: 28px;
	text-align: center;
}

.em092 {
	font-size: 0.92em;
}

.em088 {
	font-size: 0.88em;
}

.em080 {
	font-size: 0.80em;
}
/* IDE Hack <style type="text/css"> */

.flag-sprite {
	background:url(/dolibarr/theme/common/flags/flag-sprite.png) no-repeat top left; display:inline-block;
}
.flag-sprite.ad {
	background-position:0 -0px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ae {
	background-position:0 -11px;
	width: 16px;
	height: 11px;
}
.flag-sprite.af {
	background-position:0 -22px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ag {
	background-position:0 -33px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ai {
	background-position:0 -44px;
	width: 16px;
	height: 11px;
}
.flag-sprite.al {
	background-position:0 -55px;
	width: 16px;
	height: 11px;
}
.flag-sprite.am {
	background-position:0 -66px;
	width: 16px;
	height: 11px;
}
.flag-sprite.an {
	background-position:0 -77px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ao {
	background-position:0 -88px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ar {
	background-position:0 -99px;
	width: 16px;
	height: 11px;
}
.flag-sprite.as {
	background-position:0 -110px;
	width: 16px;
	height: 11px;
}
.flag-sprite.at {
	background-position:0 -121px;
	width: 16px;
	height: 11px;
}
.flag-sprite.au {
	background-position:0 -132px;
	width: 16px;
	height: 11px;
}
.flag-sprite.aw {
	background-position:0 -143px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ax {
	background-position:0 -154px;
	width: 16px;
	height: 11px;
}
.flag-sprite.az {
	background-position:0 -165px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ba {
	background-position:0 -176px;
	width: 16px;
	height: 11px;
}
.flag-sprite.bb {
	background-position:0 -187px;
	width: 16px;
	height: 11px;
}
.flag-sprite.bd {
	background-position:0 -198px;
	width: 16px;
	height: 11px;
}
.flag-sprite.be {
	background-position:0 -209px;
	width: 16px;
	height: 11px;
}
.flag-sprite.bf {
	background-position:0 -220px;
	width: 16px;
	height: 11px;
}
.flag-sprite.bg {
	background-position:0 -231px;
	width: 16px;
	height: 11px;
}
.flag-sprite.bh {
	background-position:0 -242px;
	width: 16px;
	height: 11px;
}
.flag-sprite.bi {
	background-position:0 -253px;
	width: 16px;
	height: 11px;
}
.flag-sprite.bj {
	background-position:0 -264px;
	width: 16px;
	height: 11px;
}
.flag-sprite.bm {
	background-position:0 -275px;
	width: 16px;
	height: 11px;
}
.flag-sprite.bn {
	background-position:0 -286px;
	width: 16px;
	height: 11px;
}
.flag-sprite.bo {
	background-position:0 -297px;
	width: 16px;
	height: 11px;
}
.flag-sprite.br {
	background-position:0 -308px;
	width: 16px;
	height: 11px;
}
.flag-sprite.bs {
	background-position:0 -319px;
	width: 16px;
	height: 11px;
}
.flag-sprite.bt {
	background-position:0 -330px;
	width: 16px;
	height: 11px;
}
.flag-sprite.bv {
	background-position:0 -341px;
	width: 16px;
	height: 11px;
}
.flag-sprite.bw {
	background-position:0 -352px;
	width: 16px;
	height: 11px;
}
.flag-sprite.by {
	background-position:0 -363px;
	width: 16px;
	height: 11px;
}
.flag-sprite.bz {
	background-position:0 -374px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ca {
	background-position:0 -385px;
	width: 16px;
	height: 11px;
}
.flag-sprite.catalonia {
	background-position:0 -396px;
	width: 16px;
	height: 11px;
}
.flag-sprite.cc {
	background-position:0 -407px;
	width: 16px;
	height: 11px;
}
.flag-sprite.cd {
	background-position:0 -418px;
	width: 16px;
	height: 11px;
}
.flag-sprite.cf {
	background-position:0 -429px;
	width: 16px;
	height: 11px;
}
.flag-sprite.cg {
	background-position:0 -440px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ch {
	background-position:0 -451px;
	width: 11px;
	height: 11px;
}
.flag-sprite.ci {
	background-position:0 -462px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ck {
	background-position:0 -473px;
	width: 16px;
	height: 11px;
}
.flag-sprite.cl {
	background-position:0 -484px;
	width: 16px;
	height: 11px;
}
.flag-sprite.cm {
	background-position:0 -495px;
	width: 16px;
	height: 11px;
}
.flag-sprite.cn {
	background-position:0 -506px;
	width: 16px;
	height: 11px;
}
.flag-sprite.co {
	background-position:0 -517px;
	width: 16px;
	height: 11px;
}
.flag-sprite.cr {
	background-position:0 -528px;
	width: 16px;
	height: 11px;
}
.flag-sprite.cs {
	background-position:0 -539px;
	width: 16px;
	height: 11px;
}
.flag-sprite.cu {
	background-position:0 -550px;
	width: 16px;
	height: 11px;
}
.flag-sprite.cv {
	background-position:0 -561px;
	width: 16px;
	height: 11px;
}
.flag-sprite.cx {
	background-position:0 -572px;
	width: 16px;
	height: 11px;
}
.flag-sprite.cy {
	background-position:0 -583px;
	width: 16px;
	height: 11px;
}
.flag-sprite.cz {
	background-position:0 -594px;
	width: 16px;
	height: 11px;
}
.flag-sprite.de {
	background-position:0 -605px;
	width: 16px;
	height: 11px;
}
.flag-sprite.dj {
	background-position:0 -616px;
	width: 16px;
	height: 11px;
}
.flag-sprite.dk {
	background-position:0 -627px;
	width: 16px;
	height: 11px;
}
.flag-sprite.dm {
	background-position:0 -638px;
	width: 16px;
	height: 11px;
}
.flag-sprite.do {
	background-position:0 -649px;
	width: 16px;
	height: 11px;
}
.flag-sprite.dz {
	background-position:0 -660px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ec {
	background-position:0 -671px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ee {
	background-position:0 -682px;
	width: 16px;
	height: 11px;
}
.flag-sprite.eg {
	background-position:0 -693px;
	width: 16px;
	height: 11px;
}
.flag-sprite.eh {
	background-position:0 -704px;
	width: 16px;
	height: 11px;
}
.flag-sprite.england {
	background-position:0 -715px;
	width: 16px;
	height: 11px;
}
.flag-sprite.en {
	background-position:0 -726px;
	width: 16px;
	height: 11px;
}
.flag-sprite.er {
	background-position:0 -737px;
	width: 16px;
	height: 11px;
}
.flag-sprite.es {
	background-position:0 -748px;
	width: 16px;
	height: 11px;
}
.flag-sprite.et {
	background-position:0 -759px;
	width: 16px;
	height: 11px;
}
.flag-sprite.eu {
	background-position:0 -770px;
	width: 16px;
	height: 11px;
}
.flag-sprite.fam {
	background-position:0 -781px;
	width: 16px;
	height: 11px;
}
.flag-sprite.fi {
	background-position:0 -792px;
	width: 16px;
	height: 11px;
}
.flag-sprite.fj {
	background-position:0 -803px;
	width: 16px;
	height: 11px;
}
.flag-sprite.fk {
	background-position:0 -814px;
	width: 16px;
	height: 11px;
}
.flag-sprite.fm {
	background-position:0 -825px;
	width: 16px;
	height: 11px;
}
.flag-sprite.fo {
	background-position:0 -836px;
	width: 16px;
	height: 11px;
}
.flag-sprite.fr {
	background-position:0 -847px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ga {
	background-position:0 -858px;
	width: 16px;
	height: 11px;
}
.flag-sprite.gb {
	background-position:0 -869px;
	width: 16px;
	height: 11px;
}
.flag-sprite.gd {
	background-position:0 -880px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ge {
	background-position:0 -891px;
	width: 16px;
	height: 11px;
}
.flag-sprite.gf {
	background-position:0 -902px;
	width: 16px;
	height: 11px;
}
.flag-sprite.gg {
	background-position:0 -913px;
	width: 16px;
	height: 11px;
}
.flag-sprite.gh {
	background-position:0 -924px;
	width: 16px;
	height: 11px;
}
.flag-sprite.gi {
	background-position:0 -935px;
	width: 16px;
	height: 11px;
}
.flag-sprite.gl {
	background-position:0 -946px;
	width: 16px;
	height: 11px;
}
.flag-sprite.gm {
	background-position:0 -957px;
	width: 16px;
	height: 11px;
}
.flag-sprite.gn {
	background-position:0 -968px;
	width: 16px;
	height: 11px;
}
.flag-sprite.gp {
	background-position:0 -979px;
	width: 16px;
	height: 11px;
}
.flag-sprite.gq {
	background-position:0 -990px;
	width: 16px;
	height: 11px;
}
.flag-sprite.gr {
	background-position:0 -1001px;
	width: 16px;
	height: 11px;
}
.flag-sprite.gs {
	background-position:0 -1012px;
	width: 16px;
	height: 11px;
}
.flag-sprite.gt {
	background-position:0 -1023px;
	width: 16px;
	height: 11px;
}
.flag-sprite.gu {
	background-position:0 -1034px;
	width: 16px;
	height: 11px;
}
.flag-sprite.gw {
	background-position:0 -1045px;
	width: 16px;
	height: 11px;
}
.flag-sprite.gy {
	background-position:0 -1056px;
	width: 16px;
	height: 11px;
}
.flag-sprite.hk {
	background-position:0 -1067px;
	width: 16px;
	height: 11px;
}
.flag-sprite.hm {
	background-position:0 -1078px;
	width: 16px;
	height: 11px;
}
.flag-sprite.hn {
	background-position:0 -1089px;
	width: 16px;
	height: 11px;
}
.flag-sprite.hr {
	background-position:0 -1100px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ht {
	background-position:0 -1111px;
	width: 16px;
	height: 11px;
}
.flag-sprite.hu {
	background-position:0 -1122px;
	width: 16px;
	height: 11px;
}
.flag-sprite.id {
	background-position:0 -1133px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ie {
	background-position:0 -1144px;
	width: 16px;
	height: 11px;
}
.flag-sprite.il {
	background-position:0 -1155px;
	width: 16px;
	height: 11px;
}
.flag-sprite.in {
	background-position:0 -1166px;
	width: 16px;
	height: 11px;
}
.flag-sprite.int {
	background-position:0 -1177px;
	width: 16px;
	height: 11px;
}
.flag-sprite.io {
	background-position:0 -1188px;
	width: 16px;
	height: 11px;
}
.flag-sprite.iq {
	background-position:0 -1199px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ir {
	background-position:0 -1210px;
	width: 16px;
	height: 11px;
}
.flag-sprite.is {
	background-position:0 -1221px;
	width: 16px;
	height: 11px;
}
.flag-sprite.it {
	background-position:0 -1232px;
	width: 16px;
	height: 11px;
}
.flag-sprite.jm {
	background-position:0 -1243px;
	width: 16px;
	height: 11px;
}
.flag-sprite.jo {
	background-position:0 -1254px;
	width: 16px;
	height: 11px;
}
.flag-sprite.jp {
	background-position:0 -1265px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ke {
	background-position:0 -1276px;
	width: 16px;
	height: 11px;
}
.flag-sprite.kg {
	background-position:0 -1287px;
	width: 16px;
	height: 11px;
}
.flag-sprite.kh {
	background-position:0 -1298px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ki {
	background-position:0 -1309px;
	width: 16px;
	height: 11px;
}
.flag-sprite.km {
	background-position:0 -1320px;
	width: 16px;
	height: 11px;
}
.flag-sprite.kn {
	background-position:0 -1331px;
	width: 16px;
	height: 11px;
}
.flag-sprite.kp {
	background-position:0 -1342px;
	width: 16px;
	height: 11px;
}
.flag-sprite.kr {
	background-position:0 -1353px;
	width: 16px;
	height: 11px;
}
.flag-sprite.kw {
	background-position:0 -1364px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ky {
	background-position:0 -1375px;
	width: 16px;
	height: 11px;
}
.flag-sprite.kz {
	background-position:0 -1386px;
	width: 16px;
	height: 11px;
}
.flag-sprite.la {
	background-position:0 -1397px;
	width: 16px;
	height: 11px;
}
.flag-sprite.lb {
	background-position:0 -1408px;
	width: 16px;
	height: 11px;
}
.flag-sprite.lc {
	background-position:0 -1419px;
	width: 16px;
	height: 11px;
}
.flag-sprite.li {
	background-position:0 -1430px;
	width: 16px;
	height: 11px;
}
.flag-sprite.lk {
	background-position:0 -1441px;
	width: 16px;
	height: 11px;
}
.flag-sprite.lr {
	background-position:0 -1452px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ls {
	background-position:0 -1463px;
	width: 16px;
	height: 11px;
}
.flag-sprite.lt {
	background-position:0 -1474px;
	width: 16px;
	height: 11px;
}
.flag-sprite.lu {
	background-position:0 -1485px;
	width: 16px;
	height: 11px;
}
.flag-sprite.lv {
	background-position:0 -1496px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ly {
	background-position:0 -1507px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ma {
	background-position:0 -1518px;
	width: 16px;
	height: 11px;
}
.flag-sprite.mc {
	background-position:0 -1529px;
	width: 16px;
	height: 11px;
}
.flag-sprite.md {
	background-position:0 -1540px;
	width: 16px;
	height: 11px;
}
.flag-sprite.me {
	background-position:0 -1551px;
	width: 16px;
	height: 12px;
}
.flag-sprite.mf {
	background-position:0 -847px;
	width: 16px;
	height: 12px;
}
.flag-sprite.mg {
	background-position:0 -1563px;
	width: 16px;
	height: 11px;
}
.flag-sprite.mh {
	background-position:0 -1574px;
	width: 16px;
	height: 11px;
}
.flag-sprite.mk {
	background-position:0 -1585px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ml {
	background-position:0 -1596px;
	width: 16px;
	height: 11px;
}
.flag-sprite.mm {
	background-position:0 -1607px;
	width: 16px;
	height: 11px;
}
.flag-sprite.mn {
	background-position:0 -1618px;
	width: 16px;
	height: 11px;
}
.flag-sprite.mo {
	background-position:0 -1629px;
	width: 16px;
	height: 11px;
}
.flag-sprite.mp {
	background-position:0 -1640px;
	width: 16px;
	height: 11px;
}
.flag-sprite.mq {
	background-position:0 -1651px;
	width: 16px;
	height: 11px;
}
.flag-sprite.mr {
	background-position:0 -1662px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ms {
	background-position:0 -1673px;
	width: 16px;
	height: 11px;
}
.flag-sprite.mt {
	background-position:0 -1684px;
	width: 16px;
	height: 11px;
}
.flag-sprite.mu {
	background-position:0 -1695px;
	width: 16px;
	height: 11px;
}
.flag-sprite.mv {
	background-position:0 -1706px;
	width: 16px;
	height: 11px;
}
.flag-sprite.mw {
	background-position:0 -1717px;
	width: 16px;
	height: 11px;
}
.flag-sprite.mx {
	background-position:0 -1728px;
	width: 16px;
	height: 11px;
}
.flag-sprite.my {
	background-position:0 -1739px;
	width: 16px;
	height: 11px;
}
.flag-sprite.mz {
	background-position:0 -1750px;
	width: 16px;
	height: 11px;
}
.flag-sprite.na {
	background-position:0 -1761px;
	width: 16px;
	height: 11px;
}
.flag-sprite.nc {
	background-position:0 -1772px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ne {
	background-position:0 -1783px;
	width: 16px;
	height: 11px;
}
.flag-sprite.nf {
	background-position:0 -1794px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ng {
	background-position:0 -1805px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ni {
	background-position:0 -1816px;
	width: 16px;
	height: 11px;
}
.flag-sprite.nl {
	background-position:0 -1827px;
	width: 16px;
	height: 11px;
}
.flag-sprite.no {
	background-position:0 -1838px;
	width: 16px;
	height: 11px;
}
.flag-sprite.np {
	background-position:0 -1849px;
	width: 9px;
	height: 11px;
}
.flag-sprite.nr {
	background-position:0 -1860px;
	width: 16px;
	height: 11px;
}
.flag-sprite.nu {
	background-position:0 -1871px;
	width: 16px;
	height: 11px;
}
.flag-sprite.nz {
	background-position:0 -1882px;
	width: 16px;
	height: 11px;
}
.flag-sprite.om {
	background-position:0 -1893px;
	width: 16px;
	height: 11px;
}
.flag-sprite.pa {
	background-position:0 -1904px;
	width: 16px;
	height: 11px;
}
.flag-sprite.pe {
	background-position:0 -1915px;
	width: 16px;
	height: 11px;
}
.flag-sprite.pf {
	background-position:0 -1926px;
	width: 16px;
	height: 11px;
}
.flag-sprite.pg {
	background-position:0 -1937px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ph {
	background-position:0 -1948px;
	width: 16px;
	height: 11px;
}
.flag-sprite.pk {
	background-position:0 -1959px;
	width: 16px;
	height: 11px;
}
.flag-sprite.pl {
	background-position:0 -1970px;
	width: 16px;
	height: 11px;
}
.flag-sprite.pm {
	background-position:0 -1981px;
	width: 16px;
	height: 11px;
}
.flag-sprite.pn {
	background-position:0 -1992px;
	width: 16px;
	height: 11px;
}
.flag-sprite.pr {
	background-position:0 -2003px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ps {
	background-position:0 -2014px;
	width: 16px;
	height: 11px;
}
.flag-sprite.pt {
	background-position:0 -2025px;
	width: 16px;
	height: 11px;
}
.flag-sprite.pw {
	background-position:0 -2036px;
	width: 16px;
	height: 11px;
}
.flag-sprite.py {
	background-position:0 -2047px;
	width: 16px;
	height: 11px;
}
.flag-sprite.qa {
	background-position:0 -2058px;
	width: 16px;
	height: 11px;
}
.flag-sprite.re {
	background-position:0 -2069px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ro {
	background-position:0 -2080px;
	width: 16px;
	height: 11px;
}
.flag-sprite.rs {
	background-position:0 -2091px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ru {
	background-position:0 -2102px;
	width: 16px;
	height: 11px;
}
.flag-sprite.rw {
	background-position:0 -2113px;
	width: 16px;
	height: 11px;
}
.flag-sprite.sa {
	background-position:0 -2124px;
	width: 16px;
	height: 11px;
}
.flag-sprite.sb {
	background-position:0 -2135px;
	width: 16px;
	height: 11px;
}
.flag-sprite.scotland {
	background-position:0 -2146px;
	width: 16px;
	height: 11px;
}
.flag-sprite.sc {
	background-position:0 -2157px;
	width: 16px;
	height: 11px;
}
.flag-sprite.sd {
	background-position:0 -2168px;
	width: 16px;
	height: 11px;
}
.flag-sprite.se {
	background-position:0 -2179px;
	width: 16px;
	height: 11px;
}
.flag-sprite.sg {
	background-position:0 -2190px;
	width: 16px;
	height: 11px;
}
.flag-sprite.sh {
	background-position:0 -2201px;
	width: 16px;
	height: 11px;
}
.flag-sprite.si {
	background-position:0 -2212px;
	width: 16px;
	height: 11px;
}
.flag-sprite.sj {
	background-position:0 -2223px;
	width: 16px;
	height: 11px;
}
.flag-sprite.sk {
	background-position:0 -2234px;
	width: 16px;
	height: 11px;
}
.flag-sprite.sl {
	background-position:0 -2245px;
	width: 16px;
	height: 11px;
}
.flag-sprite.sm {
	background-position:0 -2256px;
	width: 16px;
	height: 11px;
}
.flag-sprite.sn {
	background-position:0 -2267px;
	width: 16px;
	height: 11px;
}
.flag-sprite.so {
	background-position:0 -2278px;
	width: 16px;
	height: 11px;
}
.flag-sprite.sr {
	background-position:0 -2289px;
	width: 16px;
	height: 11px;
}
.flag-sprite.st {
	background-position:0 -2300px;
	width: 16px;
	height: 11px;
}
.flag-sprite.sv {
	background-position:0 -2311px;
	width: 16px;
	height: 11px;
}
.flag-sprite.sy {
	background-position:0 -2322px;
	width: 16px;
	height: 11px;
}
.flag-sprite.sz {
	background-position:0 -2333px;
	width: 16px;
	height: 11px;
}
.flag-sprite.tc {
	background-position:0 -2344px;
	width: 16px;
	height: 11px;
}
.flag-sprite.td {
	background-position:0 -2355px;
	width: 16px;
	height: 11px;
}
.flag-sprite.tf {
	background-position:0 -2366px;
	width: 16px;
	height: 11px;
}
.flag-sprite.tg {
	background-position:0 -2377px;
	width: 16px;
	height: 11px;
}
.flag-sprite.th {
	background-position:0 -2388px;
	width: 16px;
	height: 11px;
}
.flag-sprite.tj {
	background-position:0 -2399px;
	width: 16px;
	height: 11px;
}
.flag-sprite.tk {
	background-position:0 -2410px;
	width: 16px;
	height: 11px;
}
.flag-sprite.tl {
	background-position:0 -2421px;
	width: 16px;
	height: 11px;
}
.flag-sprite.tm {
	background-position:0 -2432px;
	width: 16px;
	height: 11px;
}
.flag-sprite.tn {
	background-position:0 -2443px;
	width: 16px;
	height: 11px;
}
.flag-sprite.to {
	background-position:0 -2454px;
	width: 16px;
	height: 11px;
}
.flag-sprite.trans {
	background-position:0 -2465px;
	width: 1px;
	height: 1px;
}
.flag-sprite.tr {
	background-position:0 -2466px;
	width: 16px;
	height: 11px;
}
.flag-sprite.tt {
	background-position:0 -2477px;
	width: 16px;
	height: 11px;
}
.flag-sprite.tv {
	background-position:0 -2488px;
	width: 16px;
	height: 11px;
}
.flag-sprite.tw {
	background-position:0 -2499px;
	width: 16px;
	height: 11px;
}
.flag-sprite.tz {
	background-position:0 -2510px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ua {
	background-position:0 -2521px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ug {
	background-position:0 -2532px;
	width: 16px;
	height: 11px;
}
.flag-sprite.uk {
	background-position:0 -2543px;
	width: 16px;
	height: 11px;
}
.flag-sprite.um {
	background-position:0 -2554px;
	width: 16px;
	height: 11px;
}
.flag-sprite.unknown {
	background-position:0 -2565px;
	width: 16px;
	height: 16px;
}
.flag-sprite.us {
	background-position:0 -2581px;
	width: 16px;
	height: 11px;
}
.flag-sprite.uy {
	background-position:0 -2592px;
	width: 16px;
	height: 11px;
}
.flag-sprite.uz {
	background-position:0 -2603px;
	width: 16px;
	height: 11px;
}
.flag-sprite.va {
	background-position:0 -2614px;
	width: 16px;
	height: 11px;
}
.flag-sprite.vc {
	background-position:0 -2625px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ve {
	background-position:0 -2636px;
	width: 16px;
	height: 11px;
}
.flag-sprite.vg {
	background-position:0 -2647px;
	width: 16px;
	height: 11px;
}
.flag-sprite.vi {
	background-position:0 -2658px;
	width: 16px;
	height: 11px;
}
.flag-sprite.vn {
	background-position:0 -2669px;
	width: 16px;
	height: 11px;
}
.flag-sprite.vu {
	background-position:0 -2680px;
	width: 16px;
	height: 11px;
}
.flag-sprite.wales {
	background-position:0 -2691px;
	width: 16px;
	height: 11px;
}
.flag-sprite.wf {
	background-position:0 -2702px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ws {
	background-position:0 -2713px;
	width: 16px;
	height: 11px;
}
.flag-sprite.xk {
	background-position:0 -2724px;
	width: 16px;
	height: 11px;
}
.flag-sprite.ye {
	background-position:0 -2735px;
	width: 16px;
	height: 11px;
}
.flag-sprite.yt {
	background-position:0 -2746px;
	width: 16px;
	height: 11px;
}
.flag-sprite.za {
	background-position:0 -2757px;
	width: 16px;
	height: 11px;
}
.flag-sprite.zm {
	background-position:0 -2768px;
	width: 16px;
	height: 11px;
}
.flag-sprite.zw {
	background-position:0 -2779px;
	width: 16px;
	height: 11px;
}
