.control-slider {
	margin: 0;
	background-color: #e0e0e0;
	border-width: 0.125em;
	border-style: solid;
	border-color: #d0d0d0;
	border-radius: 0.5em;
	color: #303030;
}
.control-slider__wrap {}
.control-slider--horizontal__wrap {
	padding: 2em 1.375em;
}
.control-slider--vertical__wrap {
	padding: 1.375em 2em;
	height: 100%;
}
.control-slider__track {
	position: relative;
	z-index: 1;
	/* // border: '1px solid black', */
	border-width: 0.0625em;
	border-style: solid;
	border-color: #a0a0a0;
	border-radius: 1px;
}
.control-slider__track-actual {
	position: relative;
	width: 100%;
}
.control-slider__bt {
	position: absolute;
}
.control-slider--horizontal__wrap .control-slider__bt {
	top: 0;
}
.control-slider--vertical__wrap .control-slider__bt {
	left: 0;
}
.control-slider__bt-single {}
.control-slider__bt-min {}
.control-slider__bt-max {}
.control-slider__bt-handle {
	position: absolute;
	top: 0;
	width: 2.25em;
	height: 2.25em;
	font-size: 0.625em;
	line-height: 1.875em;
	text-align: center;
	color: #f0f0f0;
	background: #2080f0;
	border-width: 0.1875em;
	border-style: solid;
	border-color: #2080f0;
	/* // border: '2px solid red', */
	border-radius: 100%;
	transform: translateY(-50%);
	cursor: pointer;
}
.control-slider--horizontal__wrap .control-slider__bt-single .control-slider__bt-handle {
	left: 0;
	transform: translate(-50%, -50%);
}
.control-slider--horizontal__wrap .control-slider__bt-min .control-slider__bt-handle {
	right: 0;
}
.control-slider--horizontal__wrap .control-slider__bt-max .control-slider__bt-handle {
	left: 0;
}
.control-slider--vertical__wrap .control-slider__bt-single .control-slider__bt-handle {
	left: 0;
	top: 0;
	transform: translate(-50%, -50%);
}
.control-slider--vertical__wrap .control-slider__bt-min .control-slider__bt-handle {
	right: auto;
	top: auto;
	bottom: 0;
}
.control-slider--vertical__wrap .control-slider__bt-max .control-slider__bt-handle {
	left: 0;
	top: 0;
}
.control-slider__range {
	position: absolute;
	background: #2080f0;
}
.control-slider--horizontal__wrap .control-slider__range {
	top: -0.25em;
	height: 0.5em;
}
.control-slider--vertical__wrap .control-slider__range {
	left: -0.25em;
	width: 0.5em;
}
.control-slider__ticks {
	display: flex;
	flex-wrap: nowrap;
	justify-content: space-between;
	align-items: flex-start;
}
.control-slider--horizontal__ticks {
	width: 100%;
	height: 0;
	flex-direction: row;
}
.control-slider--vertical__ticks {
	width: 0;
	height: 100%;
	flex-direction: column;
}
.control-slider__ticks--start {}
.control-slider__ticks--end {}
.control-slider__ticks-item--big2 {}
.control-slider__ticks-item--big1 {}
.control-slider__ticks-item {
	position: relative;
}
.control-slider--horizontal__ticks > .control-slider__ticks-item {
	width: 0;
}
.control-slider--horizontal__ticks.control-slider__ticks--start > .control-slider__ticks-item {
	bottom: 0.75em;
}
.control-slider--horizontal__ticks.control-slider__ticks--end > .control-slider__ticks-item {
	top: 0.75em;
}
.control-slider__ticks-item__mark {
	position: absolute;
	background-color: black;
}
.control-slider--horizontal__ticks.control-slider__ticks--start > .control-slider__ticks-item > .control-slider__ticks-item__mark {
	bottom: 0;
}
.control-slider--horizontal__ticks.control-slider__ticks--end > .control-slider__ticks-item > .control-slider__ticks-item__mark {
	top: 0;
}
.control-slider--horizontal__ticks > .control-slider__ticks-item > .control-slider__ticks-item__mark {
	width: 1px;
	height: 0.3em;
}
.control-slider--horizontal__ticks > .control-slider__ticks-item--big1 > .control-slider__ticks-item__mark {
	width: 1px;
	height: 0.55em;
}
.control-slider--horizontal__ticks > .control-slider__ticks-item--big2 > .control-slider__ticks-item__mark {
	width: 1px;
	height: 0.8em;
}
.text-transparent { color: transparent; }

.text-primary-0 { color: #020033; }
.text-primary-10 { color: #030066; }
.text-primary-20 { color: #050099; }
.text-primary-30 { color: #0700CC; }
.text-primary-40 { color: #3A33FF; }
.text-primary-50 { color: #5F59FF; }
.text-primary-60 { color: #6B66FF; }
.text-primary-70 { color: #9C99FF; }
.text-primary-80 { color: #CECCFF; }
.text-primary-90 { color: #E6E5FF; }
.text-primary-100 { color: #F2F1FF; }

.text-error-0 { color: #410E0B; }
.text-error-10 { color: #601410; }
.text-error-20 { color: #8C1D18; }
.text-error-30 { color: #B3261E; }
.text-error-40 { color: #DC362E; }
.text-error-50 { color: #E46962; }
.text-error-60 { color: #EC928E; }
.text-error-70 { color: #F2B8B5; }
.text-error-80 { color: #F9DEDC; }
.text-error-90 { color: #FCEEEE; }

.text-alert-0 { color: #5C5300; }
.text-alert-10 { color: #857700; }
.text-alert-20 { color: #AD9C00; }
.text-alert-30 { color: #D6C100; }
.text-alert-40 { color: #FFE500; }
.text-alert-50 { color: #FFEA2E; }
.text-alert-60 { color: #FFEE5C; }
.text-alert-70 { color: #FFF38A; }
.text-alert-80 { color: #FFF8B7; }
.text-alert-90 { color: #FFFCE5; }

.text-success-0 { color: #11592C; }
.text-success-10 { color: #1F7B42; }
.text-success-20 { color: #339D5B; }
.text-success-30 { color: #4ABF77; }
.text-success-40 { color: #67E195; }
.text-success-50 { color: #85FFB4; }
.text-success-60 { color: #A0FFC4; }
.text-success-70 { color: #BCFFD5; }
.text-success-80 { color: #D7FFE6; }
.text-success-90 { color: #F3FFF7; }

.text-neutral-0 { color: #000000; }
.text-neutral-10 { color: #1D1B20; }
.text-neutral-20 { color: #3D3D3D; }
.text-neutral-30 { color: #666666; }
.text-neutral-40 { color: #808080; }
.text-neutral-50 { color: #969696; }
.text-neutral-60 { color: #B4B4B4; }
.text-neutral-70 { color: #CCCCCC; }
.text-neutral-80 { color: #E9E9E9; }
.text-neutral-90 { color: #F4F4F4; }
.text-neutral-100 { color: #FFFFFF; }

.bg-transparent { background-color: transparent; }

.bg-primary-0 { background-color: #020033; }
.bg-primary-10 { background-color: #030066; }
.bg-primary-20 { background-color: #050099; }
.bg-primary-30 { background-color: #0700CC; }
.bg-primary-40 { background-color: #3A33FF; }
.bg-primary-50 { background-color: #5F59FF; }
.bg-primary-60 { background-color: #6B66FF; }
.bg-primary-70 { background-color: #9C99FF; }
.bg-primary-80 { background-color: #CECCFF; }
.bg-primary-90 { background-color: #E6E5FF; }
.bg-primary-100 { background-color: #F2F1FF; }

.bg-error-0 { background-color: #410E0B; }
.bg-error-10 { background-color: #601410; }
.bg-error-20 { background-color: #8C1D18; }
.bg-error-30 { background-color: #B3261E; }
.bg-error-40 { background-color: #DC362E; }
.bg-error-50 { background-color: #E46962; }
.bg-error-60 { background-color: #EC928E; }
.bg-error-70 { background-color: #F2B8B5; }
.bg-error-80 { background-color: #F9DEDC; }
.bg-error-90 { background-color: #FCEEEE; }

.bg-alert-0 { background-color: #5C5300; }
.bg-alert-10 { background-color: #857700; }
.bg-alert-20 { background-color: #AD9C00; }
.bg-alert-30 { background-color: #D6C100; }
.bg-alert-40 { background-color: #FFE500; }
.bg-alert-50 { background-color: #FFEA2E; }
.bg-alert-60 { background-color: #FFEE5C; }
.bg-alert-70 { background-color: #FFF38A; }
.bg-alert-80 { background-color: #FFF8B7; }
.bg-alert-90 { background-color: #FFFCE5; }

.bg-success-0 { background-color: #11592C; }
.bg-success-10 { background-color: #1F7B42; }
.bg-success-20 { background-color: #339D5B; }
.bg-success-30 { background-color: #4ABF77; }
.bg-success-40 { background-color: #67E195; }
.bg-success-50 { background-color: #85FFB4; }
.bg-success-60 { background-color: #A0FFC4; }
.bg-success-70 { background-color: #BCFFD5; }
.bg-success-80 { background-color: #D7FFE6; }
.bg-success-90 { background-color: #F3FFF7; }

.bg-neutral-0 { background-color: #000000; }
.bg-neutral-10 { background-color: #1D1B20; }
.bg-neutral-20 { background-color: #3D3D3D; }
.bg-neutral-30 { background-color: #666666; }
.bg-neutral-40 { background-color: #808080; }
.bg-neutral-50 { background-color: #969696; }
.bg-neutral-60 { background-color: #B4B4B4; }
.bg-neutral-70 { background-color: #CCCCCC; }
.bg-neutral-80 { background-color: #E9E9E9; }
.bg-neutral-90 { background-color: #F4F4F4; }
.bg-neutral-100 { background-color: #FFFFFF; }

.border-transparent { border-color: transparent; }

.border-primary-0 { border-color: #020033; }
.border-primary-10 { border-color: #030066; }
.border-primary-20 { border-color: #050099; }
.border-primary-30 { border-color: #0700CC; }
.border-primary-40 { border-color: #3A33FF; }
.border-primary-50 { border-color: #5F59FF; }
.border-primary-60 { border-color: #6B66FF; }
.border-primary-70 { border-color: #9C99FF; }
.border-primary-80 { border-color: #CECCFF; }
.border-primary-90 { border-color: #E6E5FF; }
.border-primary-100 { border-color: #F2F1FF; }

.border-error-0 { border-color: #410E0B; }
.border-error-10 { border-color: #601410; }
.border-error-20 { border-color: #8C1D18; }
.border-error-30 { border-color: #B3261E; }
.border-error-40 { border-color: #DC362E; }
.border-error-50 { border-color: #E46962; }
.border-error-60 { border-color: #EC928E; }
.border-error-70 { border-color: #F2B8B5; }
.border-error-80 { border-color: #F9DEDC; }
.border-error-90 { border-color: #FCEEEE; }

.border-alert-0 { border-color: #5C5300; }
.border-alert-10 { border-color: #857700; }
.border-alert-20 { border-color: #AD9C00; }
.border-alert-30 { border-color: #D6C100; }
.border-alert-40 { border-color: #FFE500; }
.border-alert-50 { border-color: #FFEA2E; }
.border-alert-60 { border-color: #FFEE5C; }
.border-alert-70 { border-color: #FFF38A; }
.border-alert-80 { border-color: #FFF8B7; }
.border-alert-90 { border-color: #FFFCE5; }

.border-success-0 { border-color: #11592C; }
.border-success-10 { border-color: #1F7B42; }
.border-success-20 { border-color: #339D5B; }
.border-success-30 { border-color: #4ABF77; }
.border-success-40 { border-color: #67E195; }
.border-success-50 { border-color: #85FFB4; }
.border-success-60 { border-color: #A0FFC4; }
.border-success-70 { border-color: #BCFFD5; }
.border-success-80 { border-color: #D7FFE6; }
.border-success-90 { border-color: #F3FFF7; }

.border-neutral-0 { border-color: #000000; }
.border-neutral-10 { border-color: #1D1B20; }
.border-neutral-20 { border-color: #3D3D3D; }
.border-neutral-30 { border-color: #666666; }
.border-neutral-40 { border-color: #808080; }
.border-neutral-50 { border-color: #969696; }
.border-neutral-60 { border-color: #B4B4B4; }
.border-neutral-70 { border-color: #CCCCCC; }
.border-neutral-80 { border-color: #E9E9E9; }
.border-neutral-90 { border-color: #F4F4F4; }
.border-neutral-100 { border-color: #FFFFFF; }

/** Tabler css fix */
.btn {
	--tblr-btn-hover-color: var(--tblr-body-color);
}
/** End Tables css fix */

body {
	background: linear-gradient(180deg, #0042, #0042), linear-gradient(0deg, var(--bs-body-bg, var(--tblr-body-bg)), var(--bs-body-bg, var(--tblr-body-bg)));
}

.page-width {
	margin: 0 auto;
	width: 90em;
	max-width: calc(100vw - 4em);
}

.border-dotted {
	border-style: dotted;
}
.border-dashed {
	border-style: dashed;
}
.border-dashed.border-dark {
	border-image: url("data:image/svg+xml,%3csvg width='100%25' height='100%25' xmlns='http://www.w3.org/2000/svg'%3e%3crect width='100%25' height='100%25' fill='none' stroke='%23333' stroke-width='24' stroke-dasharray='24%2c 62' stroke-dashoffset='0' stroke-linecap='square'/%3e%3c/svg%3e") 12 / 3px / 0px repeat;
}
.border-dashed.border-success {
	border-image: url("data:image/svg+xml,%3csvg width='100%25' height='100%25' xmlns='http://www.w3.org/2000/svg'%3e%3crect width='100%25' height='100%25' fill='none' stroke='%230a0' stroke-width='24' stroke-dasharray='24%2c 62' stroke-dashoffset='0' stroke-linecap='square'/%3e%3c/svg%3e") 12 / 3px / 0px repeat;
}
.border-dashed.border-danger {
	border-image: url("data:image/svg+xml,%3csvg width='100%25' height='100%25' xmlns='http://www.w3.org/2000/svg'%3e%3crect width='100%25' height='100%25' fill='none' stroke='%23c11' stroke-width='24' stroke-dasharray='24%2c 62' stroke-dashoffset='0' stroke-linecap='square'/%3e%3c/svg%3e") 12 / 3px / 0px repeat;
}
.cursor-pointer {
	cursor: pointer;
}
.pointer-events-all {
	pointer-events: all !important;
}
.overflow-visible {
	overflow: visible !important;
}

.w-e1 {
	width: 1em;
}
.w-e1-5 {
	width: 1.5em;
}
.w-e8 {
	width: 8em;
}
.w-e12 {
	width: 12em;
}
.w-e16 {
	width: 16em;
}
.w-15div100 {
	width: calc(15% - 1em);
}
.h-e1 {
	height: 1em;
}
.h-e1-5 {
	height: 1.5em;
}
.w-maxc {
	width: max-content;
}
.w-fitc {
	width: fit-content;
}
.max-w-e12 {
	max-width: 12em;
}
.max-w-e16 {
	max-width: 16em;
}
.max-w-e18 {
	max-width: 18em;
}
.max-w-full {
	max-width: 100%;
}
.left-0 {
	left: 0 !important;
}
.right-0 {
	right: 0 !important;
}
.left-1s2 {
	left: 50%;
}
.pl-1o2 {
	padding-left: 0.125em;
}
.pr-1o2 {
	padding-right: 0.125em;
}
.flex-grow-4 {
	flex-grow: 4 !important;
}
.flex-grow-50 {
	flex-grow: 50 !important;
}
.flex-shrink-4 {
	flex-shrink: 4 !important;
}
.flex-shrink-8 {
	flex-shrink: 8 !important;
}
.flex-shrink-16 {
	flex-shrink: 16 !important;
}
.fs-5o8 {
	font-size: 0.625em;
}
.fs-3o4 {
	font-size: 0.75em;
}
.fs-7o8 {
	font-size: 0.875em;
}
.lead-1 {
	line-height: 1 !important;
}
.text-left {
	text-align: left !important;
}
.text-center {
	text-align: center !important;
}
.text-right {
	text-align: right !important;
}
.opacity-50 {
	opacity: 0.5;
}
.opacity-65 {
	opacity: 0.65;
}
.opacity-75 {
	opacity: 0.75;
}
.-translate-x-1s2 {
	transform: translateX(-50%);
}
.z-index-100 {
	z-index: 100;
}
.z-index-1000 {
	z-index: 1000;
}
.tsit-opacity-500 {
	transition: opacity .5s;
}
.shadow-strong {
	box-shadow: 0 0.5em 1em #00000060;
}
.text-link-over-secondary {
	color: #91bbed;
	text-decoration: underline;
}

.form-floating > .form-control-ata-answer-text {
	height: calc(5.75rem + calc(var(--tblr-border-width) * 2));
}

.chat-dialog-bg {
	background-color: #f2f2f7 !important;
}
.chat-dialog-text-color {
	color: black !important;
}
.chat-bubble-origin-host {
	margin-inline-start: 1.5em;
	color: white;
	background-color: #4675bf;
}
.chat-bubble-origin-host-text {
	color: white;
}
.chat-bubble-origin-user {
	margin-inline-end: 1.5em;
	color: black;
	background-color: #c8dcfb;
}
.chat-bubble-origin-user-text {
	color: black;
}
.chat-bubble-attachment-deleted {
	text-decoration: line-through;
}
.chat-bubble-attachment-deleted.chat-bubble-origin-host-text {
	color: #ffffff80;
}
.chat-bubble-attachment-deleted.chat-bubble-origin-user-text {
	color: #00000080;
}

.form-select-plaintext:disabled {
	/* background-color: transparent; */
	padding-left: 0;
	color: var(--bs-body-color);
	background: none;
	border-style: none;
}
.form-floating .form-select-plaintext:disabled {
	padding-left: 0.75rem;
}
.form-check-label.stretched-link::after {
	display: none;
}

.jb-toast-container {
	bottom: 5em;
	right: 5em;
	max-width: calc(100vw - 10em);
	max-height: calc(100vh - 10em);
}
@media only screen and (max-width: 575px) {
	.jb-toast-container {
		bottom: 2em;
		right: 2em;
		max-width: calc(100vw - 4em);
		max-height: calc(100vh - 4em);
	}
}

.modal-dialog,
.modal-content {
	pointer-events: all !important;
}
.modal-dialog__content {
	width: 70em;
	max-width: calc(100vw - 2em);
}
.modal-dialog__content--sm {
	width: 24em;
	max-width: calc(100vw - 2em);
}

/* Fix for Bootswatch theme Sketchy */
.btn-close::before {
	position: static;
}

.nav-item {
	display: flex;
	align-items: stretch;
}
.nav-link {
	cursor: pointer;
}
.btn-default.nav-link {
	font-weight: 600;
	color: var(--tblr-body-color);
}


.form-switch .form-check-input {
	/* --tblr-form-switch-bg: url(/img/input-switch-button.svg); */
	background-color: #808080;
}
.form-switch .form-check-input:checked {
	background-color: #3A33FF;
}

.chat-status-tabs .nav-item .nav-link {
	--tblr-card-bg: #c8dcfb;
	--tblr-nav-link-color: black;
	background: var(--tblr-card-bg);
}
.chat-status-tabs .nav-item .nav-link.active {
	--tblr-card-bg: #4675bf;
	--tblr-nav-tabs-link-active-color: white;
}

.chat-list {
	display: flex;
	flex-flow: row wrap;
	justify-content: center;
	align-items: flex-start;
}
.chat-list-card {
	margin: 0 1em 4em;
	min-width: 20em;
}
.chat-list__header {
	display: flex;
	flex-flow: row wrap;
	justify-content: space-between;
	align-items: baseline;
	margin: 0 0 1em;
}

.row-last-replier > .col {
	min-width: 7em;
}
.row-last-replier > .col-sep {
	min-width: unset;
}

.arrow-right {
	position: relative;
	padding: 0em 0.5em;
	border: 1px solid #a0a0a0;
	box-shadow: 0.25em 0.25em 0.5em #00000080;
	opacity: 0.75;
}

.bucket-title h3 {
	margin: 1.5em 0 0.25em;
}
.bucket-title h3 .title-agent-status {
	font-size: 0.875em;
	line-height: 1.25em;
}
.bucket-box {
	min-height: 5.6em;
	background-color: #cacdd1;
}
@media screen and (max-width: 1280px) {
	/* .bucket-box {
		min-width: calc((100vw - 12em) * 0.5);
	} */
}
.chat-bucket-button {
	font-size: 16px;
	width: 3em;
	height: 3em;
	transition: transform .5s;
	background-color: #dadcdf;
	border: 1px solid #b0b4b9;
}
.chat-bucket-button:hover {
	transform: scale(1.125);
}
.chat-bucket-button::after {
	content: '';
	position: absolute;
	left: 0;
	top: 0;
	width: 100%;
	height: 0;
	/* background-color: #ffffff; */
	background-image: linear-gradient(0.5turn, #ffffff80 0%, #ffffff00 100%);
	opacity: 0;
	transition: left .5s, top .5s, width .5s, height .5s, opacity .5s;
}
.chat-bucket-button:hover::after {
	left: 0;
	top: 0;
	width: 100%;
	height: 100%;
	opacity: 1;
}
.cbb-standby {
	background: #d7d9dd;
	border: 1px solid #B1B1B1;
}
.cbb-standby .cbi-jb {
	opacity: 0.55;
}
.cbb-white {
	background: #F0F0F0;
}
.cbb-green {
	background: #9BFC83;
}
.cbb-yellow {
	background: #FCF083;
}
.cbb-red {
	background: #E1BDB5;
}
.cbb-label {
	height: 1.25rem;
	line-height: 1.25rem;
	overflow: hidden;
	white-space: nowrap;
	text-overflow: clip;
	text-align: center;
}
.chat-bucket-icon {
	display: block;
	margin: 0 auto;
	width: 1.5em;
	height: 1.5em;
}
.cbi-lower {
	position: relative;
	top: 0.25em;
}
.cbi-agent {
	color: #657e9a;
}
.chat-bucket-rp-icon,
.chat-bucket-tl-icon,
.chat-bucket-bl-icon {
	width: 1em;
	height: 1em;
	font-size: 0.75em;
}
.chat-bucket-rp-icon {
	text-align: center;
}
.chat-bucket-tooltip {
	transition: opacity .5s;
}
.csp-zindex-10 {
	z-index: 10;
}

.chatdlg-list_row > .col {
	min-width: 20%;
	width: 18.9625rem;
	max-width: 100%;
	height: 45em;
	max-height: calc(100vw - 5em);
}

/* 
Sometimes this happens and I don't know why:
<div class="h-100 chat-lcc-root">
  <div class="h-100">...</div> // empty chat instance
  <div class="h-100">...</div> // real chat instance
</div>
So the position: absolute below helps to hide this error.
There should be only one chat instance.
 */
.chat-lcc-wrap {
	display: flex;
	flex-direction: row;
	flex-wrap: nowrap;
	justify-content: center;
	align-items: stretch;
}
.chat-lcc-root {
	position: relative;
	flex-grow: 0;
	flex-shrink: 2;
	width: 100%;
}
.chat-lcc-root > .h-100 {
	position: absolute;
	left: 0;
	top: 0;
	width: 100%;
	height: 100%;
}
.lcc-chat-expand {
	position: fixed !important;
	left: 0;
	top: 0;
	width: 100%;
	height: 100%;
	background: #00000080;
	z-index: 1000;
}
.lcc-chat-expand .chat-lcc-root {
	/* position: absolute;
	left: 50%;
	top: 0; */
	position: relative;
	padding: 2em 0;
	width: calc(100vw - 37.5vw) !important;
	height: 100%;
	max-width: 40em;
	/* padding-top: 2em;
	padding-bottom: 2em;
	transform: translateX(-50%); */
}

.chat-lcc-sidebar {
	flex-grow: 0;
	flex-shrink: 1;
	display: flex;
	flex-direction: column;
	flex-wrap: nowrap;
	width: 25em;
	max-width: 37.5%;
	border-left: 1px solid #00000040;
	background-color: #e2e2e7;
	border-radius: 0.5em;
	overflow: auto;
}
.chat-lcc-sidebar-content {
	flex-grow: 1;
	padding: 1px 0;
	background-color: #00000030;
}
.chat-lcc-sidebar-nav {
	display: flex;
	flex-grow: 0;
	flex-flow: row wrap;
	justify-content: flex-start;
	align-items: center;
	gap: 0.5em;
	padding: 0.5em;
	border-bottom: 1px solid #00000040;
}
.lcc-sidebar-tab-trigger {
	height: 2.5em;
	background-color: transparent;
	border: 1px solid transparent;
}
.lcc-sidebar-tab-trigger-active {
	background-color: #3A33FF20;
	border: 1px solid #3A33FF;
	border-radius: 0.25em;
}
.lcc-sidebar-tab-trigger-notification {
	min-width: 1.25em;
	height: 1.25em;
	padding: 0 0.25em;
	font-size: 0.75em;
	line-height: 1.25em;
	color: white;
	background-color: #ff3a3a;
	border-radius: 100vw;
	text-align: center;
	vertical-align: super;
}
.lcc-sidebar-tab-panel {
	margin: 0.25em;
	padding: 0.5em;
	background-color: #e2e2e7;
	border: 1px solid #00000060;
}
.lcc-sidebar-tab-panel-empty {
	/* margin: 0.25em; */
	padding: 0.75em;
	text-align: center;
}
.lcc-sidebar-list {
	list-style: circle;
	margin: 0;
	padding: 0 0 0 1em;
}
.lcc-sidebar-list-item {
	margin: 0;
	padding: 0;
}
.lcc-sidebar-list-meta {
	font-size: 0.75em;
	font-weight: 600;
}
.lcc-sidebar-list-ticket-id {
	color: rgba(var(--tblr-link-color-rgb),var(--tblr-link-opacity,1));
}
.lcc-sidebar-list-snippet {
	font-size: 0.75em;
}
.lcc-sidebar-list-actions-inputfield {
	flex-grow: 1;
}

.lcc-sidebar-list-comments-list {
	margin: 0;
	padding: 0;
	list-style: none;
	font-size: 0.75em;
}
.lcc-sidebar-list-comments-list-item {
	margin: 1em 0 0;
	padding: 0.75em 0.5em 0.5em;
	border-top: 1px solid #00000080;
	/* background-color: #ffffff80; */
}
.lcc-sidebar-list-comments-list-item-agent {
	background: #ffd70040;
}
.lcc-sidebar-list-comments-list-item-customer {
	background: #cc66cc40;
}
.lcc-sidebar-list-comments-list-item-private {
	background: #00000018;
}
.lcc-sidebar-list-actions-row {
	display: flex;
	flex-direction: row;
	flex-wrap: wrap;
	justify-content: space-between;
	align-items: flex-end;
	gap: 0.5em;
	padding: 1em 0;
	width: 100%;
}
.lcc-sidebar-list-actions-row-end {
	justify-content: flex-end;
}
.chat-session-comment {
	position: relative;
}
.chat-session-comment::before {
	content: 'Session comment';
	display: none;
	position: absolute;
	left: 0;
	top: 0;
	width: 100%;
	font-size: 0.75em;
	text-align: center;
	opacity: 0.375;
}
.chat-session-comment > textarea {
	display: block;
	height: 1.75em;
	max-height: 10em;
	padding: 0.125em; /* 1em 0.25em*/
	appearance: none;
	color: inherit;
	background: transparent;
	border: 1px solid #00000040;
	border-radius: 0.25em;
	resize: none;
}
.chat-session-comment > textarea::placeholder {
	color: #969696;
	line-height: 1.25rem;
	font-size: 0.875em;
	font-style: italic;
}
.chat-session-comment > textarea:focus-visible {
	outline: white auto 1px;
	color: black;
	background: white;
}
.chat-session-id {
	height: 1.5em;
	line-height: 1.5em;
	font-size: 0.875em;
}
.chat-sessionenv-display {
	max-width: 6em;
	height: 1.5em;
	line-height: 1.5em;
	font-size: 0.875em;
	overflow: hidden;
	word-break: break-all;
	white-space: nowrap;
	/* text-overflow: ellipsis; */
	cursor: default;
}
.chat-email-display {
	height: 1.5em;
	line-height: 1.5em;
	font-size: 0.875em;
	color: #606060;
}
.chat-email-display-label {
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
	text-align: center;
}

.chat-takeover-switch {
	width: 7em;
	margin-right: 0.375em;
	padding-left: 4em;
}
.chat-header-status {
	border: 1px solid #00000040;
}

.caf-hide {
	display: none !important;
}

.caf--modal-dialog__backdrop.modal-backdrop.show {
	opacity: 0.625;
}
.caf--modal-dialog__content {
	width: 90em;
}
.caf--modal-dialog__bt-close {
	color: white;
}
.caf-modal-body {
	padding: 0;
}
.caf-modal-title {
	padding: 0.25em 0.5em;
	font-weight: normal;
	color: #fff;
	background-color: #1d6082;
}
.caf-modal-title h2 {
	font-size: 1.5em;
	font-weight: bold;
}

.caf-table {
	width: 100%;
	border-collapse: collapse;
	border-radius: 1em;
}
.caf-table > tbody > tr {
	height: 1px;
}
.caf-table > tbody > tr > td {
	padding: 0.5em;
	height: inherit;
	border-top: 0.1875em solid #00000060;
}
.caf-table > tbody > tr > td:nth-child(1) {
	max-width: 5em;
}
.caf-table > tbody > tr > td:nth-child(2) {
	max-width: 20em;
}

.caf-grouprow-even {
	background-color: #ccd2d8;
}
.caf-grouprow-odd {
	background-color: #e7eaed;
}

.caf-group-timestamp {
	font-size: 0.875em;
	color: #606060;
}

.caf-group-transactions {
	display: flex;
	flex-flow: column nowrap;
	justify-content: flex-start;
	align-items: flex-start;
	padding: 0.25em;
	height: 100%;
	background-color: #fff;
	border: 0.1875em solid #00000040;
	border-radius: 0.5em;
}

.caf-error-msg {
	max-width: 24em;
	color: #844;
}

.caf-group-kedata-table {
	width: 100%;
}
.caf-group-kedata > hr {
	margin: 0.5em 0;
}

.caf-group-kedata select,
.caf-group-kedata input[type="text"] {
	padding: 0.125em 0.5em;
	border: 1px solid #606060;
	border-radius: 100vw;
}

.caf-group-kedata dl {
	margin: 0;
}

.caf-group-kedata dl dt {
	display: inline;
	margin-inline-end: 0.5em;
	font-size: 12px;
	font-weight: bold;
	color: gray;
}
.caf-group-kedata .bg-secondary dl dt {
	display: inline-block;
	color: lightgray;
}
.caf-group-kedata dl dt h3 {
	font-size: 14px;
}
.caf-group-kedata dl dd {
	display: inline;
}
.caf-group-kedata dl dd > a + span {
	margin-inline-start: 0.5em;
}
.caf-group-kedata dl dd > textarea {
	width: 100%;
}
.caf-group-kedata h3 {
	font-weight: bold;
	color: #606060;
}

.caf-group-kedata .dl-block {
	display: flex;
	flex-flow: row nowrap;
	justify-content: flex-start;
	align-items: flex-start;
	gap: 0.5em;
}
.caf-group-kedata .dl-block > dt {
	flex: 0 0 auto;
}
.caf-group-kedata .dl-block > dd {
	flex: 1 1 auto;
}

.caf-gkt-td-quality {
	min-width: 22em;
	max-width: 22em;
}

.caf-group-radio-row {
	display: flex;
	flex-flow: row wrap;
	justify-content: space-evenly;
	align-items: center;
}
.caf-group-radio-row label {
	text-align: center;
}
.caf-group-radio-row label > span {
	display: block;
	font-weight: bold;
}
.caf-group-rri-ok {
	color: #0a0;
}
.caf-group-rri-nok {
	color: #a00;
}

.caf-group-quality-rating fieldset label.caf-group-qr-item input {
	width: 1.25em;
	height: 1.25em;
}
.caf-group-quality-rating fieldset label.caf-group-qri-ok input {
	accent-color: rgb(29, 171, 29);
}
.caf-group-quality-rating fieldset label.caf-group-qri-nok input {
	accent-color: rgb(255, 52, 52);
}

.caf-group-quality-relevance.dl-block {
	margin: 0 auto 0.5em;
}

.caf-group-quality-relevance fieldset {
	display: flex;
	flex-flow: row wrap;
	justify-content: center;
	align-items: center;
	gap: 0.25em;
	margin: 0 auto;
	padding: 0.25em 0.5em;
	/* width: fit-content; */
	max-width: 17em;
	background-color: #ffffff80;
	border: 0.1875em solid #00000040;
	border-radius: 0.5em;
}
.caf-group-quality-relevance fieldset > .caf-group-qrel {
	/* width: calc(50% - 0.25em); */
	/* max-width: 8em; */
	/* width: 8em; */
	flex: 1 1 auto;
	text-align: end;
}
.caf-group-quality-relevance fieldset > .caf-group-qrel > input {
	margin-inline-start: 0.5em;
}

/* .caf-group-quality-review dd > input[type="checkbox"] {
	width: 1.25em;
	height: 1.25em;
} */

.caf-group-isres-quality fieldset label.caf-group-irq-item input {
	width: 1.25em;
	height: 1.25em;
}
.caf-group-isres-quality fieldset label.caf-group-irq-item > span {
	/* display: block; */
	margin: 0.5em 0;
}
.caf-group-isres-quality fieldset label.caf-group-irqi-ok input {
	accent-color: #1dab1d;
}
.caf-group-isres-quality fieldset label.caf-group-irqi-nok input {
	accent-color: #ff3434;
}

.caf-group-isres-quality .caf-group-irqi-icon {
	width: 1.25em;
	position: relative;
	bottom: 0.125em;
}
.caf-group-isres-quality .caf-group-irqi-res5 .caf-group-irqi-icon {
	color: #1dab1d;
}
.caf-group-isres-quality .caf-group-irqi-res4 .caf-group-irqi-icon,
.caf-group-isres-quality .caf-group-irqi-res3 .caf-group-irqi-icon {
	color: #ab8a1d;
}
.caf-group-isres-quality .caf-group-irqi-res2 .caf-group-irqi-icon {
	color: #888888;
}

.caf-group-isres-experience fieldset label.caf-group-ire-item input {
	width: 1.25em;
	height: 1.25em;
}
.caf-group-isres-experience fieldset label.caf-group-ire-item > span {
	/* display: block; */
	margin: 0.5em 0;
}
.caf-group-isres-experience fieldset label.caf-group-irei-ok input {
	accent-color: #1dab1d;
}
.caf-group-isres-experience fieldset label.caf-group-irei-nok input {
	accent-color: #ff3434;
}

.caf-group-isres-experience .caf-group-irei-icon {
	width: 1.25em;
	position: relative;
	bottom: 0.125em;
}
.caf-group-isres-experience .caf-group-irei-exp3 .caf-group-irei-icon {
	color: #1dab1d;
}

.caf-group-kedata dl.caf-group-isres-issue-name dd {
	display: flex;
	flex-flow: row nowrap;
	justify-content: flex-start;
	align-items: center;
}
.caf-group-isres-issue-name .caf-group-irin__issue-description {
	flex: 1 1 auto;
}

.caf-group-isres-issue-name .caf-group-irin__right-issue label > span {
	display: block;
	margin: 0 0 0.5em;
}

.caf-transaction {
	margin: 0.25em;
	/* padding: 0.25em; */
}
.caf-transaction-source-enduser {
	margin-inline-end: 1.25em;
	align-self: flex-start;
}
.caf-transaction-source-sessionengine {
	margin-inline-start: 1.25em;
	align-self: flex-end;
}
.caf-transaction-source-aim {
	margin-inline-start: 1.25em;
	align-self: flex-end;
}
.caf-transaction-type-message {
	padding: 0.25em 0.5em;
	border-radius: 0.5em;
}

.caf-transaction-source-enduser .caf-transaction-type-message {
	color: #000;
	background-color: #c8dcfb;
}
.caf-transaction-source-sessionengine .caf-transaction-type-message {
	color: #fff;
	background-color: #4675bf;
}
.caf-transaction-source-aim .caf-transaction-type-message {
	color: #fff;
	background-color: rgb(101, 126, 154);
}

.caf-group-isres-frame {
	padding: 0.5em 0.75em;
	background: rgb(101, 151, 118);
	border: 0.125em solid #000;
}
.caf-group-isres-frame dl dt h3 {
	margin: 0;
}

.caf-group-kedata dl dd.caf-group-isres-issue-name {
	display: inline-flex;
	flex-flow: row nowrap;
	justify-content: flex-start;
	align-items: center;
}
.caf-group-isres-issue-name input[type="checkbox"] {
	width: 1.25em;
	height: 1.25em;
}
.caf-group-isres-issue-name textarea {
	width: 100%;
}
.caf-group-isres-issue-name .caf-group-irin__right-issue {
	flex: 0 1 auto;
}
.caf-group-isres-issue-name .caf-group-irin__issue-description {
	flex: 1 1 auto;
}

.caf-acsearch-wrapper {
	width: 100%;
}
.caf-acsearch-input {
	width: 100%;
}
.caf-acsearch-anchor {
	width: 100%;
}
.caf-acsearch-container {
	width: 100%;
	padding: 0.5em;
	background-color: #c0c0c0;
	border: 1px solid #a0a0a0;
	border-radius: 0.5em;
	z-index: 10;
}
.caf-acsearch-container select {
	width: 100%;
	width: calc(100% - 1.5em);
	border-radius: 0.5em;
}
.caf-acsearch-loading-overlay {
	background-color: #c0c0c0a0;
}
.caf-acsearch-option-cbIssue {
	font-weight: 500;
	color: #4675bf;
}

.caf-group-should-match label {
	width: 100%;
	font-style: italic;
	color: red;
}
.caf-group-should-match label .caf-gic-acsearch-input {
	width: 100%;
}
.caf-group-should-match label > div {
	padding-inline-start: 0.5em;
}

.caf-group-choose-issue-handling {
	display: flex;
	flex-flow: row wrap;
	justify-content: flex-start;
	align-items: center;
	gap: 1em;
	padding: 0.5em 0;
}
.caf-group-choose-issue-handling::before {
	content: '';
	display: block;
	flex: 0 1 2em;
}
.caf-group-choose-issue-handling::after {
	content: '';
	display: block;
	flex: 1 1 auto;
}
.caf-group-choose-issue-handling label {
	font-style: italic;
}
.caf-group-choose-issue-handling input[type="checkbox"] {
	display: inline-block;
	margin-inline-start: 0.5em;
}

.caf-group-issue-category label {
	display: block;
}
.caf-group-issue-category .caf-acsearch-wrapper {
	width: calc(100% - 4em);
}
.caf-group-new-issue-name label {
	display: block;
}
.caf-group-new-issue-name input {
	width: calc(100% - 4em);
}
.caf-group-new-issue-name label a {
	display: inline-block;
	margin-inline-start: 0.5em;
}

.caf-group-kedata dl.caf-group-add-variant {
	margin-block-start: 0.5em;
}
.caf-group-kedata dl.caf-group-business-intel {
	margin-block-start: 0.5em;
}
.caf-group-business-intel dt {
	width: min-content;
}

.chat-lcc-agent-transfer-select-menu {
	max-width: 21em;
	max-height: 33em;
	overflow-x: hidden;
	overflow-y: auto;
	background-clip: border-box;
}
.chat-lcc-agent-transfer-select-options-subtitle {
	font-size: 0.875em;
}
.dropdown > .btn > .chat-lcc-agent-transfer-select-options-subtitle {
	font-size: 1em;
}

.chat-lcc-input-command {
	position: absolute;
	left: 0;
	top: 0;
	width: 100%;
	z-index: 1000;
}
.chat-lcc-template-search {
	position: absolute;
	left: 0;
	bottom: 0;
	width: 100%;
	max-height: 33em;
	padding: 1em;
	color: #ffffff;
	background-color: #657e9a;
	overflow-y: auto;
}

.chat-lcc-template-search-item + .chat-lcc-template-search-item {
	margin-top: 1em;
}
.chat-lcc-template-search-item-template {
	cursor: pointer;
	border: 1px solid #ffffff00;
}
.chat-lcc-template-search-item-template-selected {
	background-color: #3a33ff;
	border-color: #3a33ff;
}

.chat-takeover-popover {
	color: white !important;
	background: #e53935 !important;
}

.chat-atsearch-popover {
	width: 20.5em;
	max-width: unset;
}
.chat-atsearch-wrapper {
	width: 100%;
	font-size: 0.875em;
}
.chat-atsearch-label {
	display: block;
	width: 100%;
}
.chat-atsearch-input {
	width: 100%;
}
.chat-atsearch-input::placeholder {
	font-style: italic;
}
.chat-atsearch-anchor {
	width: 100%;
}
.chat-atsearch-container {
	width: 100%;
}
.chat-atsearch-options {
	padding: 0.5em;
	background-color: #616876;
	border: 1px solid #494f5c;
	border-radius: 0.5em;
	z-index: 10;
}
.chat-atsearch-container select {
	width: 100%;
	/* width: calc(100% - 1.5em); */
	border-radius: 0.5em;
}
.chat-atsearch-loading-overlay {
	background-color: #c0c0c0a0;
}
/* ── Agent queue (stage 1 of the console redesign) ──────────────────
   One row per session, scannable. Density is the point: the current
   console shows three or four conversations at a time because each is a
   full chat client. These rows are ~52px, so twenty fit on a laptop and
   the list stays readable on a phone. */

/* Wider overall, because the point is to fit the list AND one or more
   conversations side by side. */
.queue-page { max-width: 100%; margin: 0; padding: 1rem 1rem 3rem; }

.queue-head { display: flex; align-items: baseline; gap: .75rem; margin-bottom: .75rem; }
.queue-head h2 { margin: 0; font-size: 1.25rem; }
.queue-total { font-size: .8rem; color: #6b7280; font-variant-numeric: tabular-nums; }
.queue-fetched { color: #9ca3af; }

/* (The original .queue-filters / .queue-chip block lived here. Superseded by
   the filter-bar section further down — one chip style for every row.) */

.queue-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .15rem; }

/* FIXED COLUMNS, like the agent table. A flex row let every cell size itself,
   so nothing lined up between rows and the eye had to re-find each field on
   every line. Now: wait · identity and preview · meta, all aligned down the
   list. */
.queue-row {
  width: 100%; display: grid;
  grid-template-columns: 2.6rem minmax(0, 1fr) auto;
  align-items: center; gap: .7rem; text-align: left;
  background: #fff; border: 1px solid #e5e7eb; border-radius: .3rem;
  padding: .35rem .6rem; cursor: pointer; font: inherit; min-height: 46px;
}
.queue-row:hover { border-color: #c7d2fe; background: #fbfcff; }
/* Solid = pinned open. Dashed = the PREVIEW, the one the next click replaces —
   the difference has to be visible BEFORE clicking, or pinning is guesswork. */
.queue-row.is-open { border-color: #1d4ed8; background: #f5f8ff; }
.queue-row.is-preview { border-style: dashed; }
.queue-row:focus-visible { outline: 2px solid #1d4ed8; outline-offset: 1px; }

/* The wait is the most useful number and the one the console never showed. */
.queue-wait {
  text-align: right; font-variant-numeric: tabular-nums;
  font-size: .78rem; font-weight: 600;
}
.wait-crit { color: #b91c1c; }
.wait-warn { color: #b45309; }
.wait-calm { color: #374151; }
.wait-none { color: #d1d5db; font-weight: 400; }

.queue-main { min-width: 0; display: flex; flex-direction: column; gap: .1rem; }
.queue-who { font-size: .85rem; font-weight: 600; display: flex; align-items: center; gap: .35rem; }
.queue-live {
  font-size: .62rem; text-transform: uppercase; letter-spacing: .04em;
  background: #dcfce7; color: #15803d; border-radius: 999px; padding: .05rem .35rem;
}
.queue-flag {
  font-size: .62rem; text-transform: uppercase; letter-spacing: .04em;
  background: #fef3c7; color: #b45309; border-radius: 999px; padding: .05rem .35rem;
}
/* Quiet, monospace, secondary — findable when you are looking for it, ignorable
   when you are not. */
.queue-id {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .68rem; color: #9ca3af; font-weight: 400;
}
.queue-preview {
  font-size: .78rem; color: #4b5563;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.queue-from { color: #9ca3af; }
.queue-nopreview { color: #d1d5db; font-style: italic; }

/* One line, not three. Stacking these tripled the row height and cost the
   density that is the whole argument for a list. */
/* The meta column is itself a grid, so "58m ago", the owner and the channel sit
   under each other down the list instead of drifting with name length. */
.queue-meta {
  display: grid; grid-template-columns: 4.2rem minmax(6rem, auto) 2.6rem;
  align-items: baseline; gap: .45rem; font-size: .7rem; white-space: nowrap;
  justify-items: end;
}
.queue-by { font-weight: 600; }
.by-bot { color: #6d28d9; }
.by-me { color: #1d4ed8; }
.by-unassigned { color: #b91c1c; }
.by-agent { color: #4b5563; }
.queue-channel, .queue-solution { color: #9ca3af; }

/* Centred ON THE FILTER BAR, not on the column — Johan, 2026-08-19.
   ⚠ The column runs the full width of the page, so centring in it put the
   message far to the right of everything else on screen and it read as
   floating loose. Bounding the box to the bar's width and keeping it flush
   left means "centre" lands between the first and last filter, which is where
   the eye already is.

   Italic because it is a statement about the ABSENCE of content, not content. */
.queue-empty {
  width: 100%; max-width: var(--queue-bar-width); min-height: 14rem;
  margin-right: auto;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: .35rem;
  padding: 2rem 1rem; text-align: center;
  color: #6b7280; font-size: .875rem; font-style: italic;
}
.queue-empty p { margin: 0; }
.queue-error { color: #b91c1c; }
.queue-clear {
  margin-top: .5rem; border: 1px solid #d1d5db; background: #fff;
  border-radius: .3rem; padding: .35rem .7rem; font-size: .8rem; cursor: pointer;
}
/* Sits with the count and the load time — the three facts about freshness in
   one place, so the button is found where the doubt arises. */
.queue-refresh {
  margin-left: .6rem; border: 1px solid #d5dae2; background: #fff;
  border-radius: .3rem; padding: .18rem .55rem; font-size: .72rem;
  color: #374151; cursor: pointer; min-height: 24px;
}
.queue-refresh:hover:not(:disabled) { border-color: #97a3b1; background: #f7f9fb; }
.queue-refresh:disabled { opacity: .6; cursor: default; }

.queue-note { margin-top: 1.5rem; font-size: .72rem; color: #9ca3af; text-align: center; }

/* Phone: the meta column moves under the preview rather than squeezing it. */
@media (max-width: 640px) {
  .queue-page { padding: .75rem .6rem 3rem; }
  /* Phone: the meta column would squeeze the preview to nothing, so it drops
     below rather than competing for the same line. */
  .queue-row { grid-template-columns: 2.4rem minmax(0, 1fr); gap: .5rem; }
  .queue-meta {
    grid-column: 2; grid-template-columns: repeat(3, auto);
    justify-items: start; gap: .4rem;
  }
}

/* ── Conversation pane (new console) ────────────────────────────────
   Not the shopper's widget. An agent-grade transcript: denser, events
   distinguishable from utterances, and a composer this app owns rather
   than a textarea living inside an embedded widget. */

/*
 * ⚠ NEVER WRAPS. It used to, as an anti-overflow measure — every pane stayed
 * reachable, but the ones that did not fit stacked DOWN THE PAGE below the
 * fold, with nothing on screen saying they were there. Johan, 2026-08-19: that
 * should never happen; what does not fit belongs in the "n more open" menu.
 *
 * How many fit is measured — see `paneFit.ts`. Nothing is put out of reach:
 * the overflow menu is somewhere the agent already looks, and a second row is
 * not.
 */
.queue-shell { display: flex; flex-wrap: nowrap; gap: 1rem; align-items: stretch; min-height: 0; }

/* The panes and their overflow menu, as one column so the menu sits ABOVE the
   row rather than beside it — a rail beside them competed for the very width
   that caused the overflow. */
.cv-stack { display: flex; flex-direction: column; gap: .35rem; min-width: 0; margin-top: .9rem; }
.cv-panes { display: flex; flex-wrap: nowrap; gap: 1rem; align-items: stretch; min-height: 0; }

/* ── "n more open" ──────────────────────────────────────────────────────── */
.cv-more { position: relative; align-self: flex-start; }
.cv-more-btn {
  display: inline-flex; align-items: center; gap: .3rem;
  border: 1px solid #d5dae2; background: #fff; border-radius: .3rem;
  padding: .2rem .5rem; font-size: .72rem; font-weight: 600; color: #374151;
  cursor: pointer; min-height: 26px;
}
.cv-more-btn:hover, .cv-more-btn.is-on { border-color: #97a3b1; background: #f7f9fb; }
.cv-more-caret { font-size: .9rem; line-height: 1; color: #6b7280; }
.cv-more-list {
  position: absolute; top: calc(100% + .25rem); left: 0; z-index: 40;
  width: 22rem; max-height: 20rem; overflow-y: auto;
  display: flex; flex-direction: column; gap: .1rem; padding: .25rem;
  background: #fff; border: 1px solid #d5dae2; border-radius: .4rem;
  box-shadow: 0 12px 28px -10px rgba(16, 24, 40, .28), 0 2px 6px rgba(16, 24, 40, .08);
}
.cv-more-item {
  display: flex; flex-direction: column; gap: .1rem; text-align: left;
  border: 0; background: none; cursor: pointer;
  padding: .35rem .45rem; border-radius: .3rem; width: 100%;
}
.cv-more-item:hover { background: #eff6ff; }
.cv-more-top { display: flex; align-items: baseline; gap: .35rem; min-width: 0; }
.cv-more-who {
  font-size: .76rem; font-weight: 600; color: #111827;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cv-more-id { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .64rem; color: #8d97a3; }
.cv-more-waiting {
  font-size: .58rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  color: #b91c1c; background: #fdeaea; border-radius: .2rem; padding: 0 .25rem;
}
/* Pushed right and never squeezed — it is the one thing scanned down a column. */
.cv-more-ago { margin-left: auto; flex: 0 0 auto; font-size: .66rem; color: #8d97a3; font-variant-numeric: tabular-nums; }
.cv-more-msg {
  font-size: .7rem; color: #6b7280;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.queue-shell .queue-page { flex: 1 1 auto; min-width: 0; }

/* ⚠ MUCH NARROWER than it was (34rem basis, unbounded). A conversation is a
   column of short messages; giving it half the screen wastes it on whitespace
   and makes long lines hard to track. Bounded at 30rem so two or three can sit
   side by side, which is where this is heading — an agent working several
   chats at once. */
/*
 * ⚠ NOTHING RENDERS OUTSIDE THE PANE. Johan, 2026-08-19, as a general rule —
 * the header's controls used to spill past the right edge and sit on top of the
 * next conversation, so a button belonging to one chat appeared to belong to
 * another.
 *
 * Two parts, and the order matters. The header rows WRAP, so a control that no
 * longer fits moves to a new line and stays reachable. `overflow: hidden` is
 * only the backstop that guarantees nothing paints past the border — it must
 * never be the mechanism, because clipping a control does not tidy it away, it
 * makes it unusable while still looking present.
 *
 * Safe because the transcript scrolls in its own container, and the transfer
 * picker is narrower than the pane's minimum width.
 */
.cv-pane {
  flex: 0 1 30rem; max-width: 30rem; min-width: 22rem;
  display: flex; flex-direction: column;
  background: #fff; border: 1px solid #e5e7eb; border-radius: .4rem;
  max-height: calc(100vh - 6rem); position: sticky; top: 1rem;
  overflow: hidden;
}

/*
 * SEVERAL AT ONCE. The pane's basis tightens as more open, so three fit beside
 * the list rather than pushing it off screen; below three the extra width goes
 * back to the conversation.
 *
 * THE ARITHMETIC, so the next person changing a number knows what it costs.
 * Three panes need: 3 × basis + 2 gaps, beside sidebar 10.5rem + list + gaps.
 *
 *   at basis 21rem  →  65rem + 11.5 + list 20 + 1  =  97.5rem  (1560px)
 *   at min   18rem  →  56rem + 11.5 + list 20 + 1  =  88.5rem  (1416px)
 *
 * So three are comfortable from about a 15" laptop up; below that the panes
 * ride their floor and the list keeps its own. Narrower still and the shell
 * wraps rather than overflowing — nothing is pushed out of reach.
 */
.queue-shell.open-2 .cv-pane { flex-basis: 25rem; max-width: 25rem; }
.queue-shell.open-3 .cv-pane { flex-basis: 21rem; max-width: 21rem; min-width: 18rem; }


/* TWO ROWS. Row one is what this conversation IS; row two is where it STANDS.
   See the comment in ConversationPane.tsx. */
.cv-head {
  display: flex; flex-direction: column; gap: .3rem;
  padding: .45rem .6rem; border-bottom: 1px solid #e5e7eb; flex: 0 0 auto;
}
.cv-head-row {
  display: flex; align-items: center; gap: .3rem; min-width: 0;
  /* Wrap rather than spill — see the rule on .cv-pane. */
  flex-wrap: wrap; row-gap: .25rem;
}
/* Everything after this is pushed right. One spacer per row, so the pin/close
   pair and the answering switch line up down the right edge.
   `1 1 0` and not `1 1 auto`: an auto basis lets the spacer claim a line of its
   own once the row wraps, which pushes the controls onto a third line. */
.cv-head-push { flex: 1 1 0; min-width: 0; }

/* The handle a session is referred to by, everywhere. Monospace because it is
   read character by character when someone reads one out. */
.cv-sid {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .8rem; font-weight: 600; color: #111827; letter-spacing: -.01em;
}
/* Its own row, so it gets the pane's full width before it has to truncate —
   half an email cannot be read out, searched for, or recognised. */
.cv-head-email { margin-top: -.1rem; }
.cv-email {
  font-size: .74rem; color: #4b5563; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cv-chip {
  flex: 0 0 auto;
  font-size: .6rem; font-weight: 600; line-height: 1.5;
  padding: .05rem .35rem; border-radius: .2rem;
  background: #f1f3f7; color: #4b5563; box-shadow: inset 0 0 0 1px #e2e6ee;
  white-space: nowrap;
}
/* The CBVA, when shown at all, is a coarser fact than the two beside it. */
.cv-chip-solution { background: #eef2ff; color: #4338ca; box-shadow: inset 0 0 0 1px #dfe3fb; }

/* Icon-only controls, right-aligned on row one. */
.cv-icon {
  flex: 0 0 auto;
  border: 1px solid transparent; background: none; cursor: pointer;
  border-radius: .3rem; padding: .15rem .3rem; line-height: 1;
  font-size: .95rem; color: #6b7280; min-height: 24px;
}
.cv-icon:hover { background: #f3f4f6; }
.cv-icon.cv-close { font-size: 1.15rem; }
/*
 * PINNED is the same grey mark, just filled in — Johan, 2026-08-19: no frame,
 * and grey rather than red.
 *
 * The emoji carries its own colour, so both states are desaturated and the
 * difference is weight alone. A red pin and a blue frame made a small,
 * reversible preference look like a warning.
 */
.cv-pin { filter: grayscale(1); opacity: .45; }
.cv-pin.is-on { filter: grayscale(1); opacity: .95; }

/* Wrap stays as the BACKSTOP — the containment rule on .cv-pane means a control
   that genuinely cannot fit must move to a new line rather than spill. With the
   owner name capped it should not come to that at ordinary pane widths. */
.cv-head-state { flex-wrap: wrap; row-gap: .25rem; }
/* Neither of these gives: the link is the only way to reach the picker, and a
   squeezed switch is the control most likely to be mis-hit. */
.cv-transfer, .cv-toggle { flex: 0 0 auto; }
/* Centred like the old console's, and quiet: it is context, never an action. */
.cv-head-when { justify-content: center; }
.cv-when {
  font-size: .66rem; color: #8b96a5;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}

/* The handover marker. Coloured by what is OUTSTANDING, not by the request
   type — see TransferMark for why the old console's two colours are one. */
.cv-transfermark {
  flex: 0 0 auto; display: inline-flex; align-items: center;
  padding: .05rem .15rem; border-radius: .2rem;
}
.cv-transfermark.is-pending {
  gap: .25rem; padding: .05rem .35rem .05rem .3rem;
  font-size: .6rem; font-weight: 600; white-space: nowrap;
  color: #92400e; background: #fdf1de;
}
.cv-transfermark.is-done { color: #15803d; }
/* Cancelled, refused, or a status we cannot read — present but spent. */
.cv-transfermark.is-off { color: #9ca3af; }
/* Sized to the pills beside it, so row two reads as one band. */
.cv-btn-sm { padding: .12rem .45rem; font-size: .68rem; min-height: 22px; }

/*
 * WHO IS ANSWERING — a switch, because it has two states and flips between
 * them. Same height as the pills so it sits on their row.
 */
.cv-toggle {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; gap: .3rem;
  border: 0; background: none; cursor: pointer; padding: 0 0 0 .2rem;
  min-height: 22px;
}
.cv-toggle:disabled { opacity: .5; cursor: not-allowed; }
.cv-toggle-track {
  width: 1.85rem; height: 1rem; border-radius: 999px;
  background: #9ca3af; position: relative; flex: 0 0 auto;
  transition: background .12s ease;
}
.cv-toggle-knob {
  position: absolute; top: 2px; left: 2px;
  width: .75rem; height: .75rem; border-radius: 50%; background: #fff;
  transition: transform .12s ease;
}
/* Matches the agent's own bubbles — the switch and the messages it produces are
   the same colour, which is the point of the split. */
.cv-toggle.is-agent .cv-toggle-track { background: #657e9a; }
.cv-toggle.is-agent .cv-toggle-knob { transform: translateX(.85rem); }
.cv-toggle.is-bot .cv-toggle-track { background: #4675bf; }
.cv-toggle-label { font-size: .68rem; font-weight: 600; color: #374151; }

/*
 * A HANDOVER IS WAITING. Loud on purpose — Johan, 2026-08-19 — because it is
 * the one thing on this header that somebody has to act on, and the control
 * that answers it is this same switch.
 *
 * ⚠ It is NOT disabled. It used to be, which disabled the only control that
 * resolves the situation: `takeOverSession` refuses only an already-taken-over
 * session, and taking over is what sets the request to Fulfilled.
 */
/*
 * ⚠ NO SPECIAL TREATMENT WHILE A TRANSFER IS WAITING — Johan, 2026-08-19.
 *
 * It was first a filled amber pill carrying the words, then a ring. Both were
 * the same mistake in different sizes: the "Transfer requested" pill on the row
 * above already says it, and a second mark for one fact makes the quieter of
 * the two read as a different thing. The switch says who is answering, and
 * only that.
 *
 * ⚠ It is not disabled either. `takeOverSession` refuses only an
 * already-taken-over session, and taking over is what fulfils the request.
 */
@media (prefers-reduced-motion: reduce) {
  .cv-toggle-track, .cv-toggle-knob { transition: none; }
}
.cv-back {
  border: 0; background: none; color: #1d4ed8; font-size: 1.4rem; line-height: 1;
  cursor: pointer; padding: 0 .2rem; display: none;   /* desktop keeps the list visible */
}
/* `.cv-ident`, `.cv-who` and `.cv-sub` were the old one-row header. The two-row
   one above replaced them — deleted rather than left as dead rules nobody can
   tell are unused. */
.cv-online { color: #15803d; font-size: .66rem; font-weight: 600; white-space: nowrap; }
/* WHO has it and WHICH BUCKET it is in, on the conversation header.
   The state half reuses the sidebar's .sc-* colours rather than restating them,
   so a bucket cannot be one colour in the list and another here. */
/*
 * ⚠ THE WHOLE ROW STAYS ON ONE LINE. Johan, 2026-08-19 — an agent named
 * "Agent 1 AllSolutions" pushed the answering switch onto a second line.
 *
 * The group shrinks instead of wrapping, and the pressure lands on the OWNER
 * name first because it is the only part that is arbitrarily long. Everything
 * else here is a fixed vocabulary — Replied, Action request — and truncating a
 * known word to "Act…" costs more than it saves.
 */
.cv-pills {
  display: flex; align-items: center; gap: .25rem;
  flex: 0 1 auto; min-width: 0; flex-wrap: nowrap;
}
.cv-pill {
  flex: 0 0 auto;
  font-size: .6rem; font-weight: 600; line-height: 1.5;
  padding: .05rem .35rem; border-radius: .2rem; color: #fff; white-space: nowrap;
}
/* The one variable-length pill, so the one that gives. Floor is wide enough to
   still tell "Mine" from "Unassigned" from a person's first name. */
.cv-pill-owner {
  flex: 0 1 auto; min-width: 3.2rem; max-width: 8rem;
  overflow: hidden; text-overflow: ellipsis;
}
/* The owner pill is outlined, the state pill filled — so at a glance the eye
   separates "whose" from "how urgent" without reading either. */
.cv-pill-owner-bot        { background: #f5f3ff; color: #6d28d9; box-shadow: inset 0 0 0 1px #ddd6fe; }
.cv-pill-owner-me         { background: #eff6ff; color: #1d4ed8; box-shadow: inset 0 0 0 1px #bfdbfe; }
.cv-pill-owner-unassigned { background: #fef2f2; color: #b91c1c; box-shadow: inset 0 0 0 1px #fecaca; }
.cv-pill-owner-agent      { background: #f9fafb; color: #4b5563; box-shadow: inset 0 0 0 1px #e5e7eb; }
/* Missing from the sidebar set because neither is ever a sub-count there. */
.sc-bot { background: #6d28d9; }
/* Quieter than every bucket colour ON PURPOSE — this one is not work, and it
   should not compete for attention with the four that are. */
.sc-history { background: #e5e7eb; color: #4b5563; }

/* Pin. Pressed means the pane survives the next row click. */
.cv-pin { padding: .3rem .4rem; line-height: 1; filter: grayscale(1); opacity: .55; }
.cv-pin.is-on { filter: none; opacity: 1; border-color: #1d4ed8; background: #eff6ff; }

.cv-btn {
  border: 1px solid #d1d5db; background: #fff; border-radius: .3rem;
  padding: .3rem .6rem; font-size: .78rem; cursor: pointer; min-height: 32px;
}
.cv-btn:disabled { opacity: .5; cursor: not-allowed; }
.cv-btn-primary { background: #1d4ed8; border-color: #1d4ed8; color: #fff; }
.cv-btn-send { background: #1d4ed8; border-color: #1d4ed8; color: #fff; }

.cv-blocked {
  margin: 0; padding: .4rem .7rem; font-size: .74rem;
  background: #fef3c7; color: #92400e; border-bottom: 1px solid #fde68a;
}
.cv-blocked.cv-error { background: #fee2e2; color: #991b1b; border-bottom-color: #fecaca; }

.cv-transcript {
  flex: 1 1 auto; overflow-y: auto; padding: .7rem;
  display: flex; flex-direction: column; gap: .35rem;
}
.cv-warn {
  background: #fee2e2; color: #991b1b; border: 1px solid #fecaca;
  border-radius: .3rem; padding: .4rem .6rem; font-size: .74rem; margin-bottom: .3rem;
}
.cv-day {
  align-self: center; font-size: .68rem; color: #9ca3af;
  text-transform: uppercase; letter-spacing: .05em; margin: .5rem 0 .2rem;
}

.cv-row { display: flex; }
/* OUR side (agent AND bot) right, the shopper left — matching the shopper's own
   widget, and the division an agent actually reads the thread by. */
.cv-row-ours { justify-content: flex-end; }
.cv-row-theirs { justify-content: flex-start; }

/*
 * ⚠ BLOCK, not a column flex. The timestamp has to be able to sit at the END OF
 * THE LAST LINE of the message (Johan, 2026-08-19), and a float can only be
 * pulled onto a line box — in a column flex it is always its own row instead.
 */
.cv-bubble {
  max-width: 78%; border-radius: .5rem; padding: .35rem .55rem;
  font-size: .82rem; line-height: 1.4; display: block;
}
/* The float is the last thing in the box, so without this the box has no height
   of its own and the bubble collapses behind its own text. */
.cv-bubble::after { content: ''; display: block; clear: both; }
.cv-from-shopper { background: #f3f4f6; color: #111827; }
.cv-from-agent { background: #dbeafe; color: #0f172a; }
.cv-from-bot { background: #ede9fe; color: #1f1235; }
.cv-from-system { background: #f9fafb; color: #4b5563; }
.cv-bubble.is-pending { opacity: .65; }
.cv-bubble.is-failed { background: #fee2e2; color: #991b1b; }

.cv-label {
  display: block;
  font-size: .62rem; text-transform: uppercase; letter-spacing: .05em;
  opacity: .6; font-weight: 600;
}
/* INLINE so the timestamp after it lands on the same line box. `pre-wrap` still
   honours the message's own line breaks. */
.cv-text { display: inline; white-space: pre-wrap; word-break: break-word; }
/* Trails the last line when there is room and drops below when there is not —
   which is what a float does, and why this is one. */
.cv-time {
  float: right; margin: .3rem 0 0 .7rem;
  font-size: .62rem; opacity: .55; white-space: nowrap;
}
.cv-sending { font-style: italic; }
.cv-failedmark { font-weight: 600; }

.cv-chosen {
  font-size: .62rem; opacity: .6; font-style: italic;
}
/* Read-only: the shopper's buttons, shown so an agent knows what was offered. */
.cv-options { display: flex; flex-wrap: wrap; gap: .25rem; margin-top: .2rem; }
.cv-option {
  font-size: .68rem; border: 1px dashed currentColor; opacity: .65;
  border-radius: 999px; padding: .05rem .4rem;
}
.cv-attach { display: flex; align-items: baseline; gap: .4rem; }
.cv-attach-name { text-decoration: underline; }
.cv-attach-size { font-size: .65rem; opacity: .6; }
.cv-suggest-tag {
  font-size: .62rem; text-transform: uppercase; letter-spacing: .05em;
  color: #6d28d9; font-weight: 600;
}

/* Events read as a line across the thread, not as someone speaking. */
.cv-event {
  align-self: center; display: flex; align-items: baseline; gap: .4rem;
  font-size: .7rem; color: #6b7280; background: #f9fafb;
  border: 1px solid #f3f4f6; border-radius: 999px; padding: .1rem .6rem;
}
.cv-event-time { font-size: .62rem; opacity: .6; }

.cv-composer {
  flex: 0 0 auto; display: flex; align-items: flex-end; gap: .4rem;
  padding: .5rem .6rem; border-top: 1px solid #e5e7eb;
}
.cv-input {
  flex: 1 1 auto; resize: none; border: 1px solid #d1d5db; border-radius: .4rem;
  padding: .4rem .5rem; font: inherit; font-size: 16px;  /* 16px stops iOS auto-zoom */
  max-height: 8rem; min-height: 36px;
}
.cv-cantsend { margin: 0; font-size: .76rem; color: #92400e; }

/* Only ever shown when live updates are NOT working. */
.cv-stale { color: #b45309; font-size: .66rem; font-weight: 600; white-space: nowrap; }

/* Transfer picker — under the header, where the Transfer button is. */
/* The anchor. The picker hangs off the Transfer link rather than sitting in the
   pane's flow, which is what stops it shoving the conversation down. */
.cv-transfer { position: relative; flex: 0 0 auto; }

/* A link, not a button — Johan, 2026-08-19. It opens something rather than
   doing something, which is what a link is for, and it stops competing with
   the answering switch beside it for "the control on this row". */
.cv-link {
  border: 0; background: none; cursor: pointer; padding: .12rem .25rem;
  font-size: .7rem; font-weight: 600; color: #1d4ed8; text-decoration: underline;
  text-underline-offset: 2px; min-height: 22px;
}
.cv-link:hover { color: #1e40af; }
.cv-link.is-on { color: #1e40af; text-decoration: none; background: #eff6ff; border-radius: .25rem; }

.tf-panel {
  /* FLOATS. Reading the last few messages is exactly what an agent does while
     deciding who to hand to, so the panel must not take that away. */
  position: absolute; top: calc(100% + .35rem); right: 0; z-index: 40;
  width: 17rem; max-height: 18rem;
  display: flex; flex-direction: column;
  border: 1px solid #d5dae2; border-radius: .45rem; background: #fff;
  box-shadow: 0 12px 28px -10px rgba(16, 24, 40, .28), 0 2px 6px rgba(16, 24, 40, .08);
}
/* On a phone the pane is the whole screen, so a 17rem panel pinned to the right
   edge can hang off it. Anchor to both edges instead. */
@media (max-width: 860px) {
  .tf-panel { left: 0; right: 0; width: auto; }
}
.tf-head { display: flex; gap: .3rem; padding: .45rem .55rem .3rem; }
.tf-filter {
  flex: 1 1 auto; border: 1px solid #d1d5db; border-radius: .3rem;
  padding: .3rem .45rem; font: inherit; font-size: 16px;  /* no iOS zoom */
}
.tf-close {
  flex: 0 0 auto; border: none; background: none; cursor: pointer;
  font-size: 1.1rem; line-height: 1; color: #6b7280; padding: 0 .3rem;
}
.tf-list { overflow-y: auto; padding: 0 .4rem; }
.tf-item {
  display: flex; align-items: baseline; gap: .5rem; width: 100%;
  text-align: left; border: none; background: none; cursor: pointer;
  padding: .35rem .4rem; border-radius: .3rem; font-size: .82rem; color: #1f2937;
}
.tf-item:hover:not(:disabled) { background: #e0e7ff; }
.tf-item:disabled { cursor: default; opacity: .7; }
.tf-item.is-active { background: #eff6ff; }
.tf-item.is-current { background: #f3f4f6; }
.tf-name { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tf-you { color: #6b7280; font-size: .72rem; }
.tf-avail { flex: 0 0 auto; font-size: .66rem; }
/* Availability is the point of this list, so it carries the only colour. */
.tf-avail-focused   { color: #059669; font-weight: 600; }
.tf-avail-available { color: #059669; }
.tf-avail-busy      { color: #b45309; }
.tf-avail-offline   { color: #9ca3af; }
.tf-avail-unknown   { color: #9ca3af; font-style: italic; }
.tf-busy { flex: 0 0 auto; color: #6b7280; }
.tf-msg { margin: .45rem .5rem; font-size: .78rem; color: #6b7280; }
.tf-msg.tf-error { color: #b91c1c; }
.tf-foot {
  display: flex; align-items: center; justify-content: space-between;
  padding: .35rem .55rem .45rem; border-top: 1px solid #e5e7eb;
}
.tf-unassign {
  border: 1px solid #d1d5db; background: #fff; border-radius: .3rem;
  padding: .2rem .5rem; font-size: .74rem; cursor: pointer; color: #374151;
}
.tf-unassign:disabled { opacity: .6; cursor: default; }
.tf-hint { font-size: .64rem; color: #9ca3af; }

/* Attachments. Images preview inline; everything else is a labelled link. */
.cv-attach {
  display: flex; align-items: baseline; gap: .4rem;
  text-decoration: none; color: inherit;
}
a.cv-attach:hover .cv-attach-name { text-decoration: underline; }
.cv-attach-name { font-size: .82rem; font-weight: 500; }
.cv-attach-size { font-size: .68rem; opacity: .7; }
.cv-attach-img { display: block; margin-bottom: .3rem; }
.cv-attach-img img {
  display: block; max-width: 100%; max-height: 14rem;
  border-radius: .3rem; background: #fff;
}
.cv-file-input { display: none; }
.cv-btn-attach { flex: 0 0 auto; min-width: 2.6rem; }

/* Template picker — sits directly above the composer, so the inserted text
   appears next to where it came from. */
.cv-btn-tpl { flex: 0 0 auto; white-space: nowrap; }
.cv-btn-tpl.is-on { background: #e0e7ff; border-color: #a5b4fc; }
.tpl-panel {
  flex: 0 0 auto; display: flex; flex-direction: column;
  max-height: 16rem; border-top: 1px solid #e5e7eb; background: #f9fafb;
}
.tpl-head { display: flex; gap: .3rem; padding: .4rem .5rem .3rem; }
.tpl-filter {
  flex: 1 1 auto; border: 1px solid #d1d5db; border-radius: .3rem;
  padding: .25rem .45rem; font: inherit; font-size: 16px;  /* no iOS zoom */
}
.tpl-close {
  flex: 0 0 auto; border: none; background: none; cursor: pointer;
  font-size: 1.1rem; line-height: 1; color: #6b7280; padding: 0 .3rem;
}
.tpl-list { overflow-y: auto; padding: 0 .35rem .35rem; }
.tpl-group { margin-bottom: .3rem; }
.tpl-cat {
  font-size: .62rem; text-transform: uppercase; letter-spacing: .05em;
  color: #9ca3af; padding: .25rem .2rem .1rem;
}
.tpl-item {
  display: flex; align-items: baseline; gap: .4rem; width: 100%;
  text-align: left; border: none; background: none; cursor: pointer;
  padding: .3rem .35rem; border-radius: .3rem; font-size: .8rem; color: #1f2937;
}
.tpl-item.is-active { background: #e0e7ff; }
.tpl-text { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tpl-lang {
  flex: 0 0 auto; font-size: .6rem; text-transform: uppercase;
  color: #6b7280; background: #e5e7eb; border-radius: 999px; padding: .05rem .3rem;
}
.tpl-msg { margin: .4rem .35rem; font-size: .76rem; color: #6b7280; }
.tpl-msg.tpl-error { color: #b91c1c; }
.tpl-foot {
  margin: 0; padding: .25rem .55rem .35rem; font-size: .62rem; color: #9ca3af;
  border-top: 1px solid #e5e7eb;
}
.cv-foot-note { margin: 0; padding: 0 .7rem .5rem; font-size: .68rem; color: #9ca3af; }
.cv-empty { padding: 2rem 1rem; text-align: center; color: #6b7280; font-size: .85rem; }
.cv-empty.cv-error { color: #b91c1c; }

/* Phone: one pane at a time. The conversation replaces the list, and the back
   arrow appears — the platform's push/pop rather than a reimplementation. */
/* THE REFINEMENT BAR, under the state row.
   Compact and content-sized — Johan asked for the old console's capability
   "smooth and not too large", and eight equal-width boxes is what made the old
   one heavy. Wraps rather than scrolls: a filter that has scrolled out of sight
   is a filter the agent cannot see is on. */
/* Measured, not the window — see the comment in QueueFilters.tsx. */
.qf-shell { container-type: inline-size; }

/*
 * How wide the filter bar runs at its comfortable size: the sum of the field
 * bases plus their gaps. The fields never GROW (`flex: 0 1 basis`), so the bar
 * stops here however wide the column gets, and shrinks below it when squeezed.
 *
 * Named because the empty-list message is centred on the BAR rather than on the
 * column — see `.queue-empty`. Keep the two in step: change a field's basis and
 * this moves with it.
 */
:root { --queue-bar-width: 53rem; }

.qf {
  display: flex; flex-wrap: wrap; align-items: center; gap: .3rem;
  padding: .4rem 0 .1rem;
}
/*
 * ONE ROW UNTIL A THIRD OF THE ROOM IS GONE, then two.
 *
 * The fields are `0 1 basis`: they never grow past their comfortable width and
 * they shrink under pressure to a floor that still lets each one be read.
 *
 *   comfortable  ~53rem    + Clear ~3.2 = ~56.2rem
 *   floor        ~33.7rem  + gaps 2.4 + Clear = ~39.3rem
 *
 * ⚠ Both grew when channel and store moved in from the sidebar. That gives back
 * some of the 20% cut — the trade for those two never disappearing.
 *
 * ⚠ The threshold must clear the FLOOR WITH CLEAR SHOWING, not without it. With
 * `nowrap` an item that no longer fits overflows the container instead of
 * wrapping, and Clear appears exactly when filters are on — which is exactly
 * when the bar matters. 40rem is ~71% of comfortable and just above the floor,
 * so the row compresses all the way down and only then splits.
 */
@container (min-width: 40rem) {
  .qf-shell:not(.is-range) .qf { flex-wrap: nowrap; }
}
/* An explicit date range adds two date pickers — far more than the row can
   absorb. It wraps whatever the width, rather than crushing everything else. */
.qf-shell.is-range .qf { flex-wrap: wrap; }

.qf-field {
  border: 1px solid #e5e7eb; border-radius: .3rem; background: #fff;
  padding: .25rem .4rem; font-size: .72rem; min-height: 28px;
  /* An explicit min-width is what lets these shrink at all: a flex item
     defaults to `min-width: auto`, which for a text input is its intrinsic
     size, and the row would push past its container rather than compress. */
  flex: 0 1 7.2rem; min-width: 3.6rem;
}
.qf-field::placeholder { color: #9ca3af; }
.qf-field:focus { outline: 2px solid #1d4ed8; outline-offset: -1px; }
/* A set field must be visible as set at a glance — the whole failure mode of a
   filter bar is a stale filter nobody notices. */
.qf-field.is-set { border-color: #1d4ed8; background: #eff6ff; font-weight: 600; }
/* Floors sized to what each control must still be able to SAY: a select has to
   show its longest option, an id needs a few characters to be recognisable. */
/* All 20% narrower than they were — Johan, 2026-08-19: the list column was
   reserving more width than the list needs, at the expense of the panes. The
   FLOORS came down with the bases: a floor left at its old value would simply
   stop the field shrinking and hand the saving back. */
.qf-range { flex-basis: 6.4rem; min-width: 5rem; }
.qf-date { flex-basis: 6.8rem; min-width: 6rem; }
.qf-id { flex-basis: 5.2rem; min-width: 3.4rem; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
/* Channel and store: the two shortest answers on the row, so the two narrowest
   fields. They earn their place by being ALWAYS present rather than by being
   large. */
.qf-where { flex-basis: 5.5rem; min-width: 4.2rem; }
select.qf-field { flex-basis: 6.8rem; min-width: 5.5rem; }
/* Never shrinks — it is the way out of a filtered state, and a squeezed
   "Clear" is the last thing that should become unreadable. Counted into the
   threshold above for exactly that reason. */
.qf-clear { flex: 0 0 auto; }
.qf-dash { color: #9ca3af; font-size: .75rem; }
.qf-clear {
  border: 0; background: none; color: #1d4ed8; font-size: .72rem;
  cursor: pointer; padding: .25rem .3rem; min-height: 28px;
}
.qf-clear:hover { text-decoration: underline; }
.queue-empty-why { font-size: .78rem; color: #6b7280; margin-top: .3rem; }

/* The lookups sit apart from the state pills — they are not work. */
.queue-tab-lookup { font-style: italic; }

/* THE PHONE'S TAB STRIP. Rendered only on a phone (React decides, not CSS —
   see useIsPhone), so it needs no desktop rules beyond not existing there. */
.cv-tabs {
  display: flex; gap: .25rem; overflow-x: auto; padding: .35rem .5rem;
  background: #f9fafb; border-bottom: 1px solid #e5e7eb;
  position: sticky; top: 0; z-index: 2;
  /* Snapping keeps a half-scrolled tab from being the thing under the thumb. */
  scroll-snap-type: x proximity;
}
.cv-tab {
  scroll-snap-align: start;
  display: flex; align-items: center; gap: .3rem; flex: 0 0 auto;
  max-width: 9rem; min-height: 34px;   /* a thumb target, not a mouse target */
  border: 1px solid #e5e7eb; background: #fff; border-radius: .3rem;
  padding: .25rem .5rem; font-size: .75rem; cursor: pointer;
}
.cv-tab.is-on { border-color: #1d4ed8; background: #eff6ff; font-weight: 600; }
/* Set apart from the conversations — it is a different KIND of destination,
   and it should not read as one more chat in the row. */
.cv-tab-queue { background: #f3f4f6; color: #374151; margin-right: .3rem; }
.cv-tab-queue.is-on { background: #eff6ff; }
.cv-tab-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cv-tab-dot {
  width: .45rem; height: .45rem; border-radius: 50%; flex: 0 0 auto;
  /* Inherits the bucket colour from .sc-*, whose padding would distort it. */
  padding: 0;
}

@media (max-width: 860px) {
  .queue-shell { display: block; }
  .queue-shell.has-open .queue-page { display: none; }
  .cv-pane {
    position: static; max-height: none; border: 0; border-radius: 0;
    min-height: calc(100vh - 4rem);
  }
  .cv-back { display: block; }
  .cv-bubble { max-width: 88%; }
}

/* A finished session appears only under "Recent"; it must not read as work. */
.queue-closed {
  font-size: .62rem; text-transform: uppercase; letter-spacing: .04em;
  background: #f3f4f6; color: #6b7280; border-radius: 999px; padding: .05rem .35rem;
}

/* "Load earlier messages" — offered, not just announced. The endpoint pages at
   50, and a note saying the thread was incomplete gave the agent no way to
   complete it. */
.cv-older { display: flex; justify-content: center; padding: .3rem 0 .5rem; }
.cv-older-btn {
  border: 1px solid #d1d5db; background: #fff; border-radius: 999px;
  padding: .2rem .7rem; font-size: .72rem; color: #374151; cursor: pointer;
}
.cv-older-btn:hover:not(:disabled) { background: #f3f4f6; }
.cv-older-btn:disabled { opacity: .6; cursor: default; }

/* Agent note — internal, never seen by the shopper. Sits under the header so it
   is read before the conversation, which is when it is useful. */
.cv-note-open {
  display: block; width: 100%; text-align: left; cursor: pointer;
  border: none; border-bottom: 1px solid #e5e7eb; background: #fffbeb;
  padding: .3rem .6rem; font-size: .76rem; color: #78350f;
}
.cv-note-open:hover { background: #fef3c7; }
.cv-note-open:not(.has-note) { background: transparent; color: #9ca3af; }
.cv-note-open:not(.has-note):hover { background: #f9fafb; }
.cv-note-tag {
  font-size: .6rem; text-transform: uppercase; letter-spacing: .05em;
  background: #fde68a; color: #78350f; border-radius: 999px; padding: .05rem .35rem;
  margin-right: .3rem;
}
.cv-note-add { font-size: .72rem; }
.cv-note-edit {
  border-bottom: 1px solid #e5e7eb; background: #fffbeb; padding: .4rem .6rem;
}
.cv-note-input {
  width: 100%; resize: vertical; border: 1px solid #fcd34d; border-radius: .3rem;
  padding: .3rem .4rem; font: inherit; font-size: 16px;  /* no iOS zoom */
  background: #fff;
}
.cv-note-actions {
  display: flex; align-items: center; justify-content: flex-end; gap: .4rem;
  margin-top: .3rem;
}
.cv-note-error { flex: 1 1 auto; font-size: .7rem; color: #b91c1c; }
.cv-note-cancel, .cv-note-save {
  border: 1px solid #d1d5db; background: #fff; border-radius: .3rem;
  padding: .2rem .5rem; font-size: .72rem; cursor: pointer; color: #374151;
}
.cv-note-save:not(:disabled) { background: #78350f; border-color: #78350f; color: #fff; }
.cv-note-cancel:disabled, .cv-note-save:disabled { opacity: .6; cursor: default; }

/* The handover reason — WHY the bot passed this over. Distinct from the amber
   transfer flag: that says a handover happened, this says what for. */
/* The handover reason, exactly as jBKE authored it — "InfoRequest", not
   "INFOREQUEST". It is one of five fixed values and the camel case is part of
   how it is recognised. */
.queue-reason {
  font-size: .64rem; letter-spacing: .01em;
  background: #ede9fe; color: #5b21b6; border-radius: 999px; padding: .05rem .4rem;
}

/* --- Queue: views sidebar + tabs ------------------------------------------
   Shape from how real agent consoles work (Intercom Inbox, Front, Zendesk,
   Help Scout, Gmail): views on the left, a filter strip above the list.

   Colour from jBKB, which reserves BLUE for actions and uses near-black for
   selection. A blue selected row and a blue "Send" button teach two different
   meanings for one colour, and the one that loses is the button. */

.queue-body { display: flex; gap: 1rem; align-items: flex-start; }

/* Narrower, and everything left-justified. The counts used to be pushed to the
   right edge, which set the width from the longest label plus a gap — space the
   list needs more. Left-justified they sit next to the name and the whole rail
   costs ~20% less. */
.queue-views {
  flex: 0 0 10.5rem; display: flex; flex-direction: column; gap: .7rem;
}
.queue-viewgroup {
  display: flex; flex-direction: column; gap: .2rem;
  /* A card, so the sidebar reads as a panel rather than as text floating on the
     page ground. */
  background: #fff;
  border: 1px solid #dfe3e8;
  border-radius: .5rem;
  padding: .35rem;
}
.queue-viewlabel {
  font-size: .58rem; text-transform: uppercase; letter-spacing: .07em;
  color: #98a2ad; font-weight: 600; padding: .25rem .45rem .1rem;
}

/*
 * ⚠ FLEX, NOT GRID. The breakdown pills sit on their own line spanning the
 * whole card, and as a grid item spanning both columns their ~124px minimum was
 * distributed BACK into the two columns above — so the name column was sized by
 * the pill row beneath it and "Unassigned" rendered as "U…".
 *
 * As flex items nothing shares a track: the name and count size themselves, and
 * the breakdown is forced onto its own line by a 100% basis instead of by
 * spanning anything.
 */
.queue-view {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: .1rem .4rem;
  width: 100%; text-align: left;
  /* A visible border on EVERY option, not just the select — otherwise only
     "Another agent" looked like something you could choose, and the rest read
     as labels. */
  border: 1px solid #dde2e8;
  /* ⚠ The SAME shade as the agent select's field (#f7f9fb), not white — Johan,
     2026-08-19. White made the unselected options read as the page ground with
     a line drawn round them, while the one control that was obviously
     choosable was the shaded select. Sharing its fill makes the whole rail
     read as one set of things you pick from. */
  background: #f7f9fb;
  border-radius: .35rem; padding: .38rem .5rem; cursor: pointer;
  font: inherit; font-size: .82rem; color: #313a45;
}
.queue-view:hover { background: #e9eef3; border-color: #97a3b1; }
/* SELECTION IS NEAR-BLACK, not blue. Blue belongs to action buttons. */
.queue-view.is-on {
  background: #1c2530; border-color: #1c2530; color: #fff; font-weight: 600;
}
/* Shrinks only when the name genuinely does not fit — not because something
   below it wanted room.

   ⚠ The max-width keeps the count ON THE SAME LINE. Flex decides line breaks
   from an item's natural size BEFORE shrinking it, so a long agent name — and
   they get long, "Agent 1 AllSolutions" — would otherwise claim the whole line
   and drop the count beneath it. Bounding the name means the pair always fits
   together and the name truncates instead. */
.queue-viewname {
  flex: 0 1 auto; min-width: 0; max-width: calc(100% - 2.4rem);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/*
 * RIGHT-JUSTIFIED and heavier — Johan, 2026-08-19. (Supersedes an earlier call
 * to keep it tucked beside the name.) The number is what the rail is SCANNED
 * for: the names are fixed and learned within a day, the counts are the only
 * thing that changes. Aligned down a column they can be compared at a glance;
 * beside a ragged name they cannot.
 */
.queue-viewcount {
  flex: 0 0 auto; margin-left: auto;
  font-variant-numeric: tabular-nums; font-size: .92rem; font-weight: 700;
  color: #4b5563;
}
.queue-view.is-on .queue-viewcount { color: rgba(255,255,255,.82); }
/* Its own line, by basis rather than by spanning columns — that is the whole
   point of the change above. */
.queue-view .queue-breakdown { flex: 0 0 100%; margin-top: .15rem; }
/* Sub-rows sit INSIDE a chosen group, so they are quieter — a border on every
   nested row would turn the sidebar into a grid of boxes. */
.queue-view-sub {
  font-size: .78rem; padding-left: 1rem; color: #4b5563;
  border-color: transparent; background: transparent;
}
.queue-view-sub:hover { background: #e9eef3; border-color: #dde2e8; }
.queue-agentlist { display: flex; flex-direction: column; gap: .1rem; }

/* The agent picker is a SELECT and has to look like one.
   With every view row now bordered, a bordered row with a small chevron was not
   enough to say "choose one of these". So it gets the full field treatment jBKB
   uses for its own filters: a label above, a shaded field, and the caret in its
   own segment at the end. */
.queue-selectwrap { display: flex; flex-direction: column; gap: .15rem; padding: .15rem .1rem .1rem; }
/* Same type as Unassigned and Mine, because it names the same kind of thing:
   whose work you are looking at. As a .56rem uppercase caption it read as a
   form label for the field below, not as a third option. */
.queue-selectlabel {
  display: flex; align-items: center; gap: .4rem;
  padding: .38rem .5rem .2rem; color: #313a45;
}
.queue-select {
  display: flex; align-items: stretch; width: 100%;
  border: 1px solid #c3ccd6; border-radius: .35rem;
  background: #f7f9fb; cursor: pointer; font: inherit; font-size: .8rem;
  color: #313a45; overflow: hidden; min-height: 2rem;
}
.queue-select:hover { border-color: #97a3b1; background: #fff; }
.queue-selectvalue {
  flex: 1 1 auto; text-align: left; padding: .35rem .5rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Its own segment, with a divider — the detail that reads as "select" rather
   than "button with an arrow". */
/* ⚠ Sized to be SEEN. At .8rem the glyph was a speck, and the caret is the one
   mark that says "this opens" — the rest of the field looks like a label. */
.queue-selectcaret {
  flex: 0 0 auto; display: flex; align-items: center; justify-content: center;
  width: 1.9rem; border-left: 1px solid #c3ccd6;
  background: #eef2f6; color: #3d4854; font-size: 1.15rem; line-height: 1;
}
.queue-select.is-on {
  border-color: #1c2530; background: #1c2530; color: #fff; font-weight: 600;
}
.queue-select.is-on .queue-selectcaret {
  border-left-color: rgba(255,255,255,.28);
  background: rgba(255,255,255,.12); color: #fff;
}
/* The open list sits under the field as its options. */
.queue-agentlist {
  display: flex; flex-direction: column; gap: .1rem;
  border: 1px solid #dde2e8; border-top: none;
  border-radius: 0 0 .35rem .35rem;
  padding: .2rem; background: #fff;
}
.queue-agentlist .queue-view-sub { padding-left: .5rem; }

/* Tabs above the list. Meaning colours on the label and the underline, as in
   the sidebar pills — the same vocabulary in both places. */
/* ⚠ A FLOOR, where there was none. With `min-width: 0` the list could be
   squeezed to nothing by three open panes — present, scrollable, and unusable.
   20rem still shows the wait, the shopper and the state on every row. */
.queue-main-col { flex: 1 1 auto; min-width: 20rem; }
/*
 * ⚠ Bounded to the FILTER BAR's width, like the empty message. The list column
 * runs the full page, so the right-pushed lookups landed far off to the right
 * of everything else on screen — Recent and History floated in space instead of
 * sitting over the last filter. Capped here, the push lands them directly above
 * "Any status", which is the right edge of the controls the agent is reading.
 */
.queue-tabs {
  display: flex; align-items: center; gap: .1rem;
  width: 100%; max-width: var(--queue-bar-width);
  border-bottom: 1px solid #dfe3e8; margin-bottom: .9rem;
}
.queue-tabs-push { flex: 1 1 auto; }
.queue-tab {
  border: none; background: none; cursor: pointer; font: inherit;
  font-size: .82rem; color: #5b6673;
  padding: .45rem .65rem; border-bottom: 2px solid transparent;
  margin-bottom: -1px; display: inline-flex; align-items: center; gap: .3rem;
}
.queue-tab:hover { color: #1c2530; background: #f2f4f7; border-radius: .3rem .3rem 0 0; }
.queue-tabcount { font-variant-numeric: tabular-nums; font-size: .74rem; color: #98a2ad; }
.queue-tab.is-on { font-weight: 600; }
.queue-tab.is-on .queue-tabcount { color: inherit; opacity: .75; }

/* ⚠ COLOUR TRACKS CONTENT, NOT SELECTION.
   These colours exist to pull the eye toward work. A bucket with nothing in it
   must not wear one — a red "Urgent 0" spends attention on nothing, which is
   how people learn to stop seeing red. So: coloured whenever the count is above
   zero, selected or not; grey when empty. Selection is carried by weight and
   the underline. */
.queue-tab-urgent    { color: #c81e1e; }
.queue-tab-important { color: #b45309; }
.queue-tab-action    { color: #6d28d9; }
.queue-tab-replied   { color: #475569; }
.queue-tab-urgent .queue-tabcount,
.queue-tab-important .queue-tabcount,
.queue-tab-action .queue-tabcount,
.queue-tab-replied .queue-tabcount { color: inherit; opacity: .8; }

.queue-tab-empty { color: #a2abb5; }
.queue-tab-empty .queue-tabcount { color: #b8c0c9; }

.queue-tab-urgent.is-on    { border-bottom-color: #c81e1e; }
.queue-tab-important.is-on { border-bottom-color: #b45309; }
.queue-tab-action.is-on    { border-bottom-color: #6d28d9; }
.queue-tab-replied.is-on   { border-bottom-color: #475569; }
/* An empty bucket you have selected still needs to show it is selected. */
.queue-tab-empty.is-on { color: #4b5563; border-bottom-color: #98a2ad; }
.queue-tab.is-on:not([class*="queue-tab-"]) { color: #1c2530; border-bottom-color: #1c2530; }

/* The per-view breakdown. Colour AND initial, never colour alone. */
/* A TABLE, not a list. Fixed slots so each state keeps its position whether or
   not it has a number — a column can then be read down the sidebar, and "3"
   means the same thing on every row. */
.queue-breakdown {
  display: grid; grid-template-columns: repeat(4, 1.85rem); gap: .12rem;
}
.sc-slot { display: flex; justify-content: flex-start; min-height: .95rem; }
/*
 * ⚠ COLOUR ON THE TEXT, not behind it — Johan, 2026-08-19: the number and its
 * letter were hard to read. White type at .56rem on a saturated fill is the
 * worst case for small text; the fill wins and the glyphs disappear into it.
 *
 * Now: the bucket's colour IS the type, on a pale wash of itself, one size up
 * and bolder. The pill still reads as that bucket at a glance — the hue is
 * doing the same job — but the digit is legible, which is the whole reason the
 * pill exists.
 */
.sc {
  font-size: .64rem; font-weight: 700; line-height: 1.4;
  padding: 0 .28rem; border-radius: .2rem;
  font-variant-numeric: tabular-nums;
}
.sc-urgent    { color: #b91c1c; background: #fdeaea; }
.sc-important { color: #92400e; background: #fdf1de; }
.sc-action    { color: #6d28d9; background: #f1ebfd; }
.sc-replied   { color: #475569; background: #eef1f5; }
.sc-tag { opacity: .72; margin-left: .05em; font-size: .92em; }
/* On the selected near-black card a pale wash would glare, so the pills invert:
   the colour stays on the type, the ground goes translucent-light. */
.queue-view.is-on .sc { background: rgba(255,255,255,.92); }

.queue-stale { color: #b45309; }

/* Phone: the sidebar becomes a scrolling strip above the list. */
@media (max-width: 52rem) {
  .queue-body { flex-direction: column; gap: .6rem; }
  .queue-views {
    flex: 0 0 auto; flex-direction: row; gap: .4rem;
    overflow-x: auto; padding-bottom: .2rem;
  }
  .queue-viewgroup { flex-direction: row; gap: .25rem; padding: .25rem; }
  .queue-viewlabel { display: none; }
  .queue-view { width: auto; }
  .queue-view .queue-breakdown { display: none; }
}

/* Country flag and conversation language. Both omitted when unknown, so these
   only ever style something real. */
.queue-flag-emoji { font-size: .85rem; line-height: 1; }
.queue-lang {
  font-size: .58rem; text-transform: uppercase; letter-spacing: .04em;
  background: #f3f4f6; color: #4b5563; border-radius: .2rem; padding: .05rem .25rem;
}
.queue-lastmsg { font-size: .66rem; color: #9ca3af; font-variant-numeric: tabular-nums; }

/* Overlay chips — Action requests and Auto are true ALONGSIDE the exclusive
   states, not instead of them, so they read as a separate group. */

.sc-bot { background: #ede9fe; color: #4c1d95; }

/* The initial beside each sub-pill number. Slightly lighter than the digit so
   the count still reads first — the letter is there to disambiguate, not to
   compete. */
.sc-tag { opacity: .72; margin-left: .06em; font-size: .92em; }

/* The agent picker — a TABLE, not a list of pills.
   Fixed columns with a header each, so a column of numbers can be read down.
   Inline pills of varying width could not be compared between agents at all. */
.queue-agentrow {
  display: grid;
  grid-template-columns: minmax(7rem, 1fr) repeat(4, 3.1rem);
  align-items: center; gap: .2rem;
  width: 100%; text-align: left;
  padding: .3rem .45rem; border-radius: .3rem;
}
.queue-agenthead {
  padding-bottom: .2rem; margin-bottom: .1rem;
  border-bottom: 1px solid #e5e7eb;
}
.ac-h {
  font-size: .55rem; text-transform: uppercase; letter-spacing: .04em;
  text-align: right; font-weight: 600;
}
.ac-n {
  font-size: .78rem; text-align: right;
  font-variant-numeric: tabular-nums; font-weight: 600;
}
/* Same four colours as the pills, as TEXT here — a coloured chip per cell would
   fight the alignment the columns exist to create. All four clear 4.5:1 on
   white as text. */
.ac-urgent    { color: #dc2626; }
.ac-important { color: #b45309; }
.ac-replied   { color: #6b7280; }
.ac-action    { color: #7c3aed; }

/* Close the conversation. Distinct from the phone back-chevron: when the list
   and the pane fit side by side there is nothing to go "back" to, so dismissing
   needs its own affordance. */
.cv-close {
  border: none; background: none; cursor: pointer;
  font-size: 1.35rem; line-height: 1; color: #94a3b8;
  padding: 0 .3rem; margin-left: .2rem;
}
.cv-close:hover { color: #334155; }

/* "Enter comment" — quieter than the note itself, so an empty field reads as an
   invitation rather than as content. */
.cv-note-input::placeholder { font-style: italic; font-size: .82rem; color: #a8a29e; }

/* Air above the first row. The list started hard against the filters, which made
   the two read as one block. */
.queue-list { padding-top: .35rem; }

/* A floor under every bubble, so "hi" is not a sliver with a timestamp wider
   than its own message. Best practice in every chat client: short messages keep
   a readable minimum. */
/* Wide enough that a short message and its trailing timestamp sit on ONE line
   rather than the time dropping under two words. */
.cv-bubble { min-width: 10.5rem; }

/* The small formatting a message actually carries. Built as React elements from
   parsed segments — never injected HTML, since the same field carries whatever a
   shopper types. */
.rt-b { font-weight: 600; }
.rt-i { font-style: italic; }
.rt-u { text-decoration: underline; }
.cv-text a { color: inherit; text-decoration: underline; }
.cv-text a:hover { opacity: .85; }

/* Stands in for the state tabs under Bot, so the strip does not collapse to an
   empty rule and the view says what it is. */
.queue-tabnote {
  font-size: .8rem; color: #5b6673; padding: .45rem .2rem;
  font-style: italic;
}

/* An auto session a human has been in. Quiet, because in an agent-served list
   it would be true of everything — it only means something among bot rows. */
.queue-touched {
  font-size: .62rem; letter-spacing: .01em;
  background: #eef2f6; color: #4b5563;
  border-radius: 999px; padding: .05rem .4rem;
}

/* --- Conversation: dates, colours, ticks ---------------------------------- */

/* Each date pins to the top of the scroller until the next pushes it out, so
   scrolling back always shows which day you are reading. Sticky on the
   separator itself, not a floating overlay tracking scroll — nothing to
   measure and nothing to drift. */
/*
 * ONE SECTION PER DAY. This is what makes the separator behave.
 *
 * ⚠ Sticky siblings sharing a container all pin at the same offset and overlap —
 * two date pills sat stacked a few millimetres apart. A sticky element is
 * bounded by its own containing block, so a section per day means the next
 * section's arrival PUSHES the previous pill out instead of landing on it.
 */
/*
 * `padding-top` is the HANDOVER DISTANCE, not decoration. It sits above the
 * pill, so the outgoing separator is pushed out while the incoming one is still
 * this far short of the top: ~20px, the low end of the 5–10mm Johan asked for.
 * Raising it makes the new date take over earlier and opens the gap between
 * days; lowering it delays the handover until they nearly touch.
 */
.cv-daygroup {
  display: flex; flex-direction: column; gap: .35rem;
  padding-top: 1.25rem;
}
/* No leading gap above the very first day in the thread. */
.cv-daygroup:first-of-type { padding-top: .35rem; }

.cv-day {
  position: sticky; top: 0; z-index: 5;
  align-self: center; width: max-content;
  /*
   * ⚠ The space above the pill belongs to the SECTION, not to the pill.
   *
   * A margin here would sit inside the sticky element's own scroll area and
   * delay the handover until the two pills were touching. As section padding it
   * is above the pill, so the outgoing one is pushed out while the incoming one
   * is still this far short of the top — the new date takes over with a gap
   * rather than after a collision, which is what Johan asked for (2026-08-19).
   */
  margin: 0 auto .35rem;
  padding: .15rem .6rem;
  font-size: .66rem; letter-spacing: .04em; text-transform: uppercase;
  color: #4b5563; background: #eef1f5;
  border: 1px solid #dfe3e8; border-radius: 999px;
}

/* ALL THREE are the old ACI's own colours, so an agent moving between the two
   consoles reads the same conversation the same way.

   ⚠ They are NOT in this repo's CSS. The old console embeds the shopper widget
   to render its thread, so the real values live in
   `lib-chat-client/src/themes/sans-blue.css.ts` as theme variables:
   `bubbleEngine` #4675bf (the bot), `bubbleAgent` #657e9a (a person),
   `bubbleHost` #c8dcfb (the visitor). Searching this repo finds only
   `chat-bubble-origin-*`, which styles the ATTACHMENT popover and has just two
   colours — which is why the agent's grey looks absent from here and is not.

   ⚠ The theme is per client, so these are sans-blue's. A client on a different
   widget theme sees different bubbles in their own widget; the agent console is
   always this one. */
.cv-from-bot { background: #4675bf; color: #fff; }
.cv-from-agent { background: #657e9a; color: #fff; }
.cv-from-shopper { background: #c8dcfb; color: #10131a; }
.cv-from-system { background: #f2f4f7; color: #4b5563; }
.cv-bubble .cv-label { color: rgba(255,255,255,.78); }
.cv-from-shopper .cv-label { color: #3f5170; }
.cv-bubble .cv-time { color: rgba(255,255,255,.72); }
.cv-from-shopper .cv-time { color: #4a5a75; }
.cv-bubble.is-failed { background: #fee2e2; color: #991b1b; }
.cv-bubble.is-failed .cv-time { color: #b91c1c; }
.cv-text a { color: inherit; }

/* Delivery ticks — our side only. */
.cv-ticks { margin-left: .3rem; letter-spacing: -.08em; opacity: .85; }

/* The offered buttons: ONE bubble, no header, no timestamp, stacked. They
   belong to the message above rather than to a turn of their own. */
.cv-optionbox {
  display: flex; flex-direction: column; align-items: stretch; gap: .25rem;
  max-width: 78%; padding: .35rem;
  background: #eef1f8; border: 1px solid #d7deec; border-radius: .5rem;
}
.cv-option {
  display: block; text-align: center;
  border: 1px dashed #9aa9c9; border-radius: .35rem;
  padding: .22rem .5rem; font-size: .78rem; color: #3c4a66; background: #fff;
}

/* Events are notes in the margin, not messages: italic, no fill. */
.cv-event {
  align-self: center; text-align: center;
  margin: .3rem auto; padding: .1rem .3rem;
  font-size: .74rem; font-style: italic; color: #6b7280;
  background: none; border: none;
}
.cv-event-time { margin-left: .4rem; font-style: normal; color: #9ca3af; font-size: .68rem; }

/* OLD ↔ NEW console. Deliberately a segmented control rather than a link: it
   shows which one you are in as well as offering the other, and while the new
   console is in trial the way BACK is the more important half. */
.console-switch {
  display: inline-flex; align-items: center;
  border: 1px solid rgba(255, 255, 255, .35); border-radius: .3rem;
  overflow: hidden; margin-right: .6rem;
}
.console-switch-opt {
  border: 0; background: none; cursor: pointer;
  padding: .12rem .45rem; font-size: .7rem; font-weight: 600;
  color: rgba(255, 255, 255, .8); line-height: 1.5; min-height: 22px;
}
.console-switch-opt:hover { background: rgba(255, 255, 255, .12); color: #fff; }
.console-switch-opt.is-on { background: #fff; color: #1d4ed8; }


/* The send guard's question. Amber, because it is a doubt rather than a failure
   — an error red would say the message could not be sent, and it can. */
.cv-doubt {
  flex: 0 0 auto; display: flex; flex-wrap: wrap; align-items: center;
  gap: .4rem .6rem; padding: .5rem .7rem;
  background: #fdf1de; border-bottom: 1px solid #f0dcb8;
  font-size: .78rem; color: #7a4a06; line-height: 1.45;
}
.cv-doubt-acts { display: flex; gap: .35rem; margin-left: auto; flex: 0 0 auto; }

/* An action that has been dealt with. Green and quiet: it is a record, not a
   thing to act on — the loud purple belongs to the ones still outstanding. */
.sc-actiondone { background: #e7f5ec; color: #15803d; box-shadow: inset 0 0 0 1px #cbe9d6; }
.cv-actiondone-btn { font-size: .68rem; }

/* The action request and its control, on their own row — a parallel axis to the
   states above, so it reads as its own statement rather than one more pill. */
.cv-head-action { gap: .45rem; }
/* The lookups' neighbour: a toggle that NARROWS a view rather than replacing
   it, so it is upright where Recent and History are italic. */
.queue-tab-action { font-weight: 600; }

/* "The agent says their work here is finished" — quiet, because it is a
   statement about intent rather than a thing needing attention. Distinct from
   the answering switch on purpose: done and handed-back are different acts. */
.sc-finalized { background: #eef1f5; color: #4b5563; box-shadow: inset 0 0 0 1px #dfe3e8; }

/* ⚠ NEEDS AN ANSWER — the mark that survived whose-turn being demoted from a
   bucket boundary to an ordering. Urgent now holds live conversations whoever
   spoke last, so the ones actually waiting on us have to be visible at a
   glance; the sort already puts them first, this says why they are there. */
.queue-row.is-waiting { border-left: 3px solid #dc2626; }
.queue-row.is-waiting .queue-wait { font-weight: 700; }
