/* Sea Direct visual overrides for client_web only. */

:root {
	--sea-primary: #00A8FF;
	--sea-primary-deep: #0087cc;
	/* Fill for white-on-fill controls (selected toggles, active pills).
	   White on it is 4.87:1, AA for small text; --sea-primary is 2.61:1 and
	   --sea-primary-deep 3.93:1. theme_dark.css re-points it for dark. */
	--sea-primary-fill: #0077b6;
	--sea-primary-soft: #e8f7ff;
	--sea-primary-mist: #eef8ff;
	/* Solid fills under white text. The bright brand blue gives white only
	   2.6:1, so buttons and filled badges use a deeper blue of the same hue
	   (5.3:1); the bright blue stays for accents and the logo. */
	--sea-fill-primary: #0b6fb8;
	--sea-fill-primary-hover: #095d9b;
	--sea-secondary: #242424;
	--sea-secondary-soft: #f4f4f4;
	--sea-surface: #ffffff;
	--sea-surface-strong: #ffffff;
	--sea-text: #242424;
	--sea-muted: #5f5f5f;
	--sea-border: rgba(74, 74, 74, 0.12);
	--sea-shadow: 0 20px 45px rgba(0, 0, 0, 0.08);
	--sea-shell-gutter: clamp(1.25rem, 2vw, 2rem);
	--sea-shell-inline-padding: max(1.25rem, var(--sea-shell-gutter));
	--sea-section-gap: clamp(1.5rem, 3vw, 2.75rem);
	--sea-panel-padding: clamp(1.5rem, 3vw, 2.5rem);
	/* Threat-response elevation. Hues match the existing .ki-sev-* palette so a
	   red border and a red notification bar are the same red. */
	--sea-danger: #e14e5a;
	--sea-danger-ink: #c43a45;
	--sea-warning: #f0a020;
	--sea-warning-ink: #a8690a;
}

body.auth-theme,
body.portal-theme {
	color: var(--sea-text);
}

body.auth-theme {
	background:
		radial-gradient(circle at top left, rgba(0, 168, 255, 0.22), transparent 34%),
		linear-gradient(135deg, #f8fcff 0%, #ffffff 46%, #f6f6f6 100%);
}

body.portal-theme {
	background:
		radial-gradient(circle at top right, rgba(0, 168, 255, 0.16), transparent 30%),
		linear-gradient(180deg, #fafcfe 0%, #ffffff 58%, #f7f7f7 100%);
}

body.auth-theme .app-wrapper,
body.portal-theme .app-wrapper {
	color: var(--sea-text);
	font-family: "Rubik", "Segoe UI", "Helvetica Neue", sans-serif;
}

body.auth-theme .main-container,
body.portal-theme main.container,
body.portal-theme footer.container {
	padding-left: var(--sea-shell-gutter);
	padding-right: var(--sea-shell-gutter);
}

.app-shell-header {
	background: #ffffff !important;
	border-bottom-color: var(--sea-border) !important;
	box-shadow: 0 8px 30px rgba(0, 0, 0, 0.04);
}

.app-shell-header > .container-fluid,
.app-shell-header .container {
	padding-left: var(--sea-shell-gutter);
	padding-right: var(--sea-shell-gutter);
}

.app-shell-footer {
	border-top-color: var(--sea-border) !important;
	margin-top: var(--sea-section-gap);
}

/* Keep the footer's "Need Help" link clear of the floating buttons in the
   bottom-right corner: the tenant quick-view button (.tqv-fab, 52px at
   1.5rem from the edge) and, on register pages, the "View examples" pill. */
@media (min-width: 768px) {
	body.ki-portal-shell-body:has(.tqv-fab) footer .app-shell-footer {
		padding-right: calc(1.5rem + 52px + 1rem);
	}

	body.ki-portal-shell-body:has(.ki-examples-fab) footer .app-shell-footer {
		padding-right: calc(1.5rem + 11rem + 1rem);
	}
}

@media (max-width: 767.98px) {
	body.ki-portal-shell-body:has(.tqv-fab, .ki-examples-fab) footer .app-shell-footer {
		padding-bottom: calc(1.5rem + 52px + 1rem);
	}
}

.brand-lockup {
	min-width: 0;
}

.brand-logo-image {
	height: 54px;
	width: auto;
	display: block;
}

/* The official SeaDirect Protect logo on the sign-in screens: sized by height,
   width follows the artwork (145x48). */
.auth-brand-image {
	display: inline-block;
	height: 56px;
	width: auto;
	max-width: 100%;
}

.auth-brand-image.compact {
	height: 48px;
}

/* Links take the brand ink, except links drawn as a solid fill: a solid button
   or the selected pill keeps its own white (or dark) label instead of link blue
   on the blue fill. :where() keeps the weight at (0,1,1) / (0,2,1), so every
   rule that out-ranked these before still does. */
.app-wrapper a:where(:not(.btn-primary, .btn-success, .btn-danger, .btn-warning, .btn-info, .btn-secondary, .btn-dark, .btn-light, .nav-pills .nav-link.active)),
.app-wrapper .text-primary,
.app-wrapper .text-white-800,
.app-wrapper .link-white,
.app-wrapper .btn-link {
	color: var(--sea-primary-deep) !important;
}

.app-wrapper a:where(:not(.btn-primary, .btn-success, .btn-danger, .btn-warning, .btn-info, .btn-secondary, .btn-dark, .btn-light, .nav-pills .nav-link.active)):hover,
.app-wrapper .btn-link:hover {
	color: var(--sea-primary) !important;
}

.app-wrapper .text-dark,
.app-wrapper h1,
.app-wrapper h2,
.app-wrapper h3,
.app-wrapper h4,
.app-wrapper h5,
.app-wrapper h6,
.app-wrapper strong,
.app-wrapper .h1,
.app-wrapper .h2,
.app-wrapper .h3,
.app-wrapper .h4,
.app-wrapper .h5,
.app-wrapper .h6 {
	color: var(--sea-text) !important;
}

.app-wrapper .text-muted,
.app-wrapper p,
.app-wrapper label,
.app-wrapper li,
.app-wrapper small,
.app-wrapper .form-floating > label {
	color: var(--sea-muted) !important;
	opacity: 1 !important;
}

/* .text-white on a solid fill (a primary / success / danger button or
   background, a badge, the selected pill) stays white; elsewhere it maps to
   the body ink. */
.app-wrapper .text-white:where(:not(.btn-primary, .bg-primary, .btn-success, .bg-success, .btn-danger, .bg-danger, .badge, .nav-pills .nav-link.active)) {
	color: var(--sea-text) !important;
}

.btn-primary,
.bg-primary,
.badge.bg-primary-subtle,
.btn-light-primary:hover,
.btn-light-primary:focus,
.btn-light-primary:active {
	background-color: var(--sea-fill-primary) !important;
	border-color: var(--sea-fill-primary) !important;
}

.btn-primary,
.btn-primary:hover,
.btn-primary:focus,
.btn-primary:active {
	color: #ffffff !important;
	box-shadow: 0 12px 24px rgba(11, 111, 184, 0.22);
}

.btn-primary:hover,
.btn-primary:focus,
.btn-primary:active {
	background-color: var(--sea-fill-primary-hover) !important;
	border-color: var(--sea-fill-primary-hover) !important;
}

.btn-light-primary {
	background: var(--sea-primary-soft) !important;
	border: 1px solid rgba(0, 168, 255, 0.16) !important;
	color: var(--sea-primary-deep) !important;
}

.btn-light-primary:hover,
.btn-light-primary:focus,
.btn-light-primary:active,
.app-wrapper a.btn-light-primary:hover,
.app-wrapper a.btn-light-primary:focus,
.app-wrapper a.btn-light-primary:active {
	background-color: var(--sea-fill-primary) !important;
	border-color: var(--sea-fill-primary) !important;
	color: #ffffff !important;
}

.btn-outline-primary {
	background: transparent !important;
	border-color: rgba(0, 168, 255, 0.38) !important;
	color: var(--sea-primary-deep) !important;
}

.btn-outline-primary:hover,
.btn-outline-primary:focus,
.btn-outline-primary:active {
	background: var(--sea-primary) !important;
	border-color: var(--sea-primary) !important;
	color: #ffffff !important;
}

.btn-light-secondary,
.btn-outline-danger {
	background: #ffffff !important;
	border: 1px solid var(--sea-border) !important;
	color: var(--sea-secondary) !important;
}

.btn-outline-secondary {
	background: #ffffff !important;
	border: 1px solid var(--sea-border) !important;
	color: var(--sea-secondary) !important;
}

.btn-outline-danger:hover,
.btn-light-secondary:hover,
.btn-outline-secondary:hover,
.btn-outline-secondary:focus,
.btn-outline-secondary:active {
	background: var(--sea-secondary-soft) !important;
	border-color: rgba(74, 74, 74, 0.24) !important;
	color: var(--sea-secondary) !important;
}

/* A selected btn-check toggle. The !important outline fills above (and
   `.app-wrapper label`) hide Bootstrap's checked state, so a picked option
   never looked picked. Weighted (0,2,0) / (0,3,0): above those rules, below
   the dark theme's own (0,3,1) and a page's scoped `.x .btn-check:checked +
   .btn` (0,4,0). */
:where(.btn-check:checked, .btn-check:active) + .btn.btn-outline-secondary,
:where(.btn-check:checked, .btn-check:active) + .btn.btn-outline-danger,
:where(.btn-check:checked, .btn-check:active) + .btn.btn-outline-primary,
:where(.btn-check:checked, .btn-check:active) + .btn.btn-outline-success,
.btn.btn-outline-secondary.active,
.btn.btn-outline-primary.active {
	background: var(--sea-primary-fill) !important;
	border-color: var(--sea-primary-fill) !important;
	color: #ffffff !important;
}

.sea-breadcrumb-wrap {
	margin-bottom: 0.5rem;
	display: block;
	width: 100%;
	min-width: 0;
}

.sea-breadcrumb {
	margin-bottom: 0;
	padding: 0;
	background: transparent;
	width: auto;
	min-width: max-content;
}

.sea-breadcrumb .breadcrumb-item,
.sea-breadcrumb .breadcrumb-item.active,
.sea-breadcrumb .breadcrumb-item + .breadcrumb-item::before {
	color: var(--sea-muted) !important;
	opacity: 1;
}

.sea-breadcrumb .breadcrumb-item a {
	color: var(--sea-primary-deep) !important;
	font-weight: 500;
}

.sea-table-toolbar-actions {
	min-width: fit-content;
}

.sea-page-heading-row {
	width: 100%;
}

.sea-page-heading-copy {
	min-width: 0;
}

.sea-table-summary {
	text-align: right;
}

.sea-filter-field {
	min-width: 0;
}

.sea-filter-search {
	flex: 1 1 18rem;
}

.sea-filter-rows {
	width: 6rem;
}

.sea-entity-page {
	padding-bottom: 1rem;
}

.sea-entity-side-card {
	position: relative;
	overflow: hidden;
}

.sea-entity-avatar {
	width: 4rem;
	height: 4rem;
	border-radius: 1.25rem;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	font-weight: 700;
	letter-spacing: 0.08em;
}

.sea-entity-stats {
	display: grid;
	gap: 0.85rem;
}

.sea-entity-stats > div {
	display: flex;
	justify-content: space-between;
	gap: 1rem;
	padding-bottom: 0.75rem;
	border-bottom: 1px solid var(--sea-border);
}

.sea-entity-stats > div:last-child {
	padding-bottom: 0;
	border-bottom: 0;
}

.sea-related-list {
	display: grid;
	gap: 0.75rem;
}

.sea-related-list-item {
	display: flex;
	justify-content: space-between;
	align-items: center;
	gap: 1rem;
	padding: 0.95rem 1rem;
	border: 1px solid var(--sea-border);
	border-radius: 1rem;
	background: linear-gradient(180deg, #ffffff 0%, #fbfdff 100%);
	text-decoration: none;
	transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
}

.sea-related-list-item:hover {
	transform: translateY(-1px);
	border-color: rgba(0, 168, 255, 0.22);
	box-shadow: 0 12px 24px rgba(0, 0, 0, 0.05);
	color: inherit !important;
}

.sea-detail-grid {
	row-gap: 1rem;
}

.sea-detail-tile {
	height: 100%;
	padding: 1rem 1.1rem;
	border-radius: 1rem;
	border: 1px solid var(--sea-border);
	background: linear-gradient(180deg, #ffffff 0%, #fafcff 100%);
	display: flex;
	flex-direction: column;
	gap: 0.45rem;
}

.sea-detail-tile > span {
	font-size: 0.8rem;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--sea-muted);
}

.sea-detail-tile > strong {
	font-size: 1rem;
	line-height: 1.45;
	font-weight: 600;
}

@media (max-width: 991.98px) {
	.sea-table-summary {
		text-align: left;
	}
}

.card,
.border.rounded-3,
.form-container,
.main-content-box,
.sign-in-content-bg {
	background: var(--sea-surface);
	border-color: var(--sea-border) !important;
	box-shadow: var(--sea-shadow);
	opacity: 1;
}

.card,
.border.rounded-3 {
	background: var(--sea-surface);
}

.form-content-box .form-container,
.image-content-box .form-container,
.image-contentbox .form-container {
	position: relative;
	background: #ffffff;
}

.form-container {
	padding: var(--sea-panel-padding);
    padding-bottom: 15px!important;
    padding-top: 15px!important;
}

.main-content-box,
.sign-in-content-bg {
	border-radius: 28px;
	overflow: hidden;
	margin-top: var(--sea-section-gap);
	margin-bottom: var(--sea-section-gap);
}

.image-content-box,
.image-contentbox {
	background: #ffffff;
}

.form-content-box {
	background: #ffffff;
}

.app-form .row {
	row-gap: 0.5rem;
}

.app-form .mb-5 {
	margin-bottom: 2.5rem !important;
}

.app-form .mt-4 {
	margin-top: 2rem !important;
}

.app-form .mt-3 {
	margin-top: 1.5rem !important;
}

.app-form .mb-3,
.app-form .form-floating {
	margin-bottom: 1.25rem !important;
}

.form-floating {
	position: relative;
}

.card .card-body,
.border.rounded-3 {
	padding: var(--sea-panel-padding) !important;
}

.alert {
	padding: 1rem 1.125rem;
	margin-bottom: 1.5rem;
}

.custom-forms .form-floating > .form-control,
.custom-forms .form-control {
	border: 1.5px solid rgba(74, 74, 74, 0.24);
	color: var(--sea-text);
	background: var(--sea-surface-strong);
	min-height: 3.75rem;
	border-radius: 14px;
	padding-left: 1rem;
	padding-right: 1rem;
	-webkit-text-fill-color: var(--sea-text);
	opacity: 1;
	caret-color: var(--sea-primary-deep);
	box-shadow: 0 1px 0 rgba(74, 74, 74, 0.03);
}

.form-floating > .form-control {
	padding: 1.625rem 1rem 0.625rem;
}

.form-floating > .form-control::placeholder {
	color: transparent !important;
	opacity: 0 !important;
}

.form-floating > .form-control:focus::placeholder,
.form-floating > .form-control:not(:placeholder-shown)::placeholder {
	color: transparent !important;
}

.form-floating > label {
	padding: 1rem;
	color: var(--sea-muted) !important;
	opacity: 1 !important;
	transform-origin: 0 0;
	left: 0.75rem;
	width: auto;
	height: auto;
	padding-left: 0.35rem;
	padding-right: 0.35rem;
	border-radius: 999px;
}

.form-floating > .form-control:focus,
.form-floating > .form-control:not(:placeholder-shown) {
	padding-top: 1.625rem;
	padding-bottom: 0.625rem;
}

.form-floating > .form-control:focus ~ label,
.form-floating > .form-control:not(:placeholder-shown) ~ label,
.form-floating > .form-control:-webkit-autofill ~ label {
	color: var(--sea-primary-deep) !important;
}

.form-floating > .form-control:-webkit-autofill,
.form-floating > .form-control:-webkit-autofill:hover,
.form-floating > .form-control:-webkit-autofill:focus {
	-webkit-text-fill-color: var(--sea-text);
	transition: background-color 9999s ease-out 0s;
}

.form-floating > .form-control:focus,
.form-control:focus,
.form-check-input:focus {
	border-color: rgba(0, 168, 255, 0.38);
	box-shadow: 0 0 0 0.2rem rgba(0, 168, 255, 0.14);
}

.form-floating > .form-control:not(:focus) {
	border-color: rgba(74, 74, 74, 0.24);
}

.form-check {
	align-items: center;
	gap: 0.75rem;
}

/* Native controls: appearance:auto draws a checkbox as a checkbox and a radio
   as a radio (forcing `-webkit-appearance: checkbox` drew every radio square).
   A .form-switch is Bootstrap's drawn switch, so it keeps appearance:none. */
.form-check-input {
	appearance: auto !important;
	width: 1.15rem;
	height: 1.15rem;
	display: inline-block;
	margin-top: 0;
	flex: 0 0 auto;
	border: 1.5px solid rgba(74, 74, 74, 0.45);
	background-color: #ffffff;
	background-image: none;
	opacity: 1 !important;
	accent-color: var(--sea-primary);
	box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.9);
}

.form-check-input:checked {
	background-color: var(--sea-primary);
	border-color: var(--sea-primary);
}

.form-check-input:hover {
	border-color: rgba(0, 168, 255, 0.55);
}

.form-switch .form-check-input {
	appearance: none !important;
	width: 2.1rem;
	/* Wider than Bootstrap's 2em gutter, so keep the label off the track. */
	margin-right: 0.4rem;
	border-radius: 2rem;
	background-image: var(--bs-form-switch-bg);
	background-repeat: no-repeat;
	background-position: left center;
	background-size: contain;
	box-shadow: none;
}

.form-switch .form-check-input:checked {
	background-position: right center;
}

.form-check-label,
.form-label {
	color: var(--sea-text) !important;
}

.form-check-label {
	margin-top: 0 !important;
	line-height: 1.35;
}

.btn {
	padding: 0.85rem 1.35rem;
}

.btn-lg {
	padding: 1rem 1.5rem;
}

.alert-success {
	background: var(--sea-primary-mist);
	border-color: rgba(0, 168, 255, 0.2);
	color: var(--sea-text);
}

.alert-warning {
	background: #f5f5f5;
	border-color: rgba(74, 74, 74, 0.16);
	color: var(--sea-text);
}

.alert-danger {
	background: #f1f1f1;
	border-color: rgba(74, 74, 74, 0.2);
	color: var(--sea-text);
}

.alert a {
	color: var(--sea-primary-deep) !important;
}

.avatar-md {
	background: var(--sea-primary-soft) !important;
	color: var(--sea-primary-deep) !important;
}

.badge.bg-primary-subtle {
	background: var(--sea-primary-soft) !important;
	border: 1px solid rgba(0, 168, 255, 0.14);
	color: var(--sea-primary-deep) !important;
}

/* Tabler's light-tint badge names (`bg-*-lt`). The client portal is Tabler, this
   portal is Bootstrap, so templates written against the wrong one rendered
   Bootstrap's default white-on-nothing badge — invisible on a white row. Keep
   these defined rather than rewriting every call site as it keeps happening. */
.badge[class*="-lt"] {
	font-weight: 600;
}

.badge.bg-secondary-lt {
	background: rgba(138, 147, 161, 0.16) !important;
	border: 1px solid rgba(138, 147, 161, 0.24);
	color: #4d5563 !important;
}

.badge.bg-warning-lt,
.badge.bg-yellow-lt,
.badge.bg-orange-lt {
	background: rgba(240, 160, 32, 0.16) !important;
	border: 1px solid rgba(240, 160, 32, 0.28);
	color: var(--sea-warning-ink) !important;
}

.badge.bg-danger-lt,
.badge.bg-red-lt {
	background: rgba(225, 78, 90, 0.14) !important;
	border: 1px solid rgba(225, 78, 90, 0.26);
	color: var(--sea-danger-ink) !important;
}

.badge.bg-success-lt,
.badge.bg-green-lt,
.badge.bg-teal-lt {
	background: rgba(0, 184, 148, 0.16) !important;
	border: 1px solid rgba(0, 184, 148, 0.26);
	color: #0a7a60 !important;
}

.badge.bg-info-lt,
.badge.bg-azure-lt,
.badge.bg-cyan-lt,
.badge.bg-blue-lt,
.badge.bg-primary-lt {
	background: var(--sea-primary-soft) !important;
	border: 1px solid rgba(0, 168, 255, 0.2);
	color: var(--sea-primary-deep) !important;
}

.badge.bg-purple-lt {
	background: rgba(155, 107, 255, 0.16) !important;
	border: 1px solid rgba(155, 107, 255, 0.26);
	color: #6b3fc0 !important;
}

.badge.bg-dark-lt,
.badge.bg-muted-lt {
	background: rgba(36, 36, 36, 0.1) !important;
	border: 1px solid rgba(36, 36, 36, 0.18);
	color: var(--sea-text) !important;
}

.bg-light-primary,
.bg-light-success,
.bg-light-warning {
	background: var(--sea-primary-soft) !important;
}

.text-success,
.text-warning {
	color: var(--sea-primary-deep) !important;
}

@media (max-width: 991.98px) {
	.brand-logo-image {
		height: 46px;
	}

	.auth-brand-image {
		max-width: 180px;
	}

	.main-content-box,
	.sign-in-content-bg {
		border-radius: 20px;
	}

	.form-container,
	.card .card-body,
	.border.rounded-3 {
		padding: 1.25rem !important;
	}
}

/* Portal shell overrides modeled after the ki-admin project dashboard base. */

body.ki-portal-shell-body {
	background: linear-gradient(180deg, #f5fbff 0%, #ffffff 52%, #f4f4f4 100%);
}

body.ki-portal-shell-body nav {
	background: linear-gradient(180deg, #ffffff 0%, #f7fbff 56%, #f0f6fb 100%);
	border-right: 1px solid var(--sea-border);
	box-shadow: 16px 0 36px rgba(10, 37, 64, 0.05);
}

body.ki-portal-shell-body .app-logo {
	background: rgba(255, 255, 255, 0.92);
	border-bottom: 1px solid var(--sea-border);
}

body.ki-portal-shell-body .app-logo .logo {
	width: 100%;
	min-height: 4.5rem;
	padding: 0.9rem 1rem;
	justify-content: flex-start;
	position: relative;
}

/* The official SeaDirect Protect logo; the bare tile replaces it on the
   collapsed rail (rules further down, under nav.semi-nav). The widths are
   !important because style.css pins `nav.semi-nav .app-logo .logo img` to
   `width: 180px !important` below 1199px, which would stretch the tile. */
body.ki-portal-shell-body nav .app-logo .logo img.sd-logo {
	display: block;
	float: none;
	height: 44px;
	width: auto !important;
	max-width: 100%;
	object-fit: contain;
}

body.ki-portal-shell-body nav .app-logo .logo img.logo-compact-mark {
	display: none;
	float: none;
	width: 2.35rem !important;
	height: 2.35rem;
}

body.ki-portal-shell-body .nav-profile {
	background: linear-gradient(180deg, rgba(0, 168, 255, 0.12), rgba(255, 255, 255, 0));
	border-top: 1px solid rgba(0, 168, 255, 0.08);
	gap: 0.75rem;
}

body.ki-portal-shell-body .main-nav > li > a,
body.ki-portal-shell-body .main-nav > li > ul > li > a {
	color: var(--sea-secondary) !important;
	border-radius: 14px;
}

body.ki-portal-shell-body .main-nav > li + li {
	margin-top: 0.75rem;
}

body.ki-portal-shell-body .main-nav > li > a {
	display: flex;
	align-items: center;
	gap: 0.75rem;
	min-height: 3.25rem;
	padding: 0.8rem 0.95rem;
	font-weight: 700;
	letter-spacing: 0.01em;
	box-shadow: inset 0 0 0 1px rgba(20, 32, 51, 0.03);
}

body.ki-portal-shell-body .main-nav > li > a > span,
body.ki-portal-shell-body .main-nav > li > ul > li > a > span {
	flex: 1 1 auto;
	min-width: 0;
}

body.ki-portal-shell-body .main-nav > li > a i,
body.ki-portal-shell-body .main-nav > li > ul > li > a i {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 2rem;
	height: 2rem;
	font-size: 1rem;
	border-radius: 10px;
	background: rgba(14, 92, 181, 0.1);
	color: var(--sea-primary-deep) !important;
	flex-shrink: 0;
}

body.ki-portal-shell-body .main-nav > li > ul {
	margin-top: 0.65rem;
	padding-left: 0.35rem;
}

body.ki-portal-shell-body .main-nav > li > ul > li + li {
	margin-top: 0.35rem;
}

body.ki-portal-shell-body .main-nav > li > ul > li > a {
	display: flex;
	align-items: center;
	gap: 0.65rem;
	padding: 0.7rem 0.85rem;
	min-height: 3rem;
	font-weight: 600;
	background: rgba(255, 255, 255, 0.72);
}

/* Collapsed icon-rail (`semi-nav`) styling. Every rule is gated behind
 * `:not(:hover):not(:focus-within)` so that hovering (or keyboard-focusing)
 * the rail drops back to the full expanded styles — the rail temporarily
 * widens (style.css) and the labels/logo/profile/chevrons reappear. This is
 * what makes "minimised but expands on hover" work in the portal shell. */
body.ki-portal-shell-body nav.semi-nav:not(:hover):not(:focus-within) .main-nav > li > a,
body.ki-portal-shell-body nav.semi-nav:not(:hover):not(:focus-within) .main-nav > li > ul > li > a {
	justify-content: center;
	padding-left: 0.5rem;
	padding-right: 0.5rem;
	gap: 0;
}

body.ki-portal-shell-body nav.semi-nav:not(:hover):not(:focus-within) .app-logo .logo {
	justify-content: center;
	padding-left: 0.5rem;
	padding-right: 0.5rem;
}

body.ki-portal-shell-body nav.semi-nav:not(:hover):not(:focus-within) .app-logo .logo img.sd-logo {
	display: none;
}

body.ki-portal-shell-body nav.semi-nav:not(:hover):not(:focus-within) .app-logo .logo img.logo-compact-mark {
	display: block;
}

body.ki-portal-shell-body nav.semi-nav:not(:hover):not(:focus-within) .nav-profile {
	justify-content: center;
	padding: 0.75rem 0.4rem !important;
}

body.ki-portal-shell-body nav.semi-nav:not(:hover):not(:focus-within) .nav-profile > .flex-grow-1,
body.ki-portal-shell-body nav.semi-nav:not(:hover):not(:focus-within) .nav-profile .profile-menu-dropdown {
	display: none !important;
}

body.ki-portal-shell-body nav.semi-nav:not(:hover):not(:focus-within) .nav-profile > span.h-45.w-45 {
	margin: 0 auto;
}

body.ki-portal-shell-body nav.semi-nav:not(:hover):not(:focus-within) .main-nav > li > a > span,
body.ki-portal-shell-body nav.semi-nav:not(:hover):not(:focus-within) .main-nav > li > ul > li > a > span,
body.ki-portal-shell-body nav.semi-nav:not(:hover):not(:focus-within) .nav-section-badge {
	display: none;
}

body.ki-portal-shell-body nav.semi-nav:not(:hover):not(:focus-within) .main-nav > li > a i,
body.ki-portal-shell-body nav.semi-nav:not(:hover):not(:focus-within) .main-nav > li > ul > li > a i {
	margin: 0;
	width: 2.25rem;
	height: 2.25rem;
	font-size: 1.05rem;
}

body.ki-portal-shell-body .nav-section-badge {
	margin-left: auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 1.8rem;
	height: 1.8rem;
	padding: 0 0.45rem;
	border-radius: 999px;
	background: rgba(14, 92, 181, 0.1);
	font-size: 0.74rem;
	font-weight: 700;
	color: var(--sea-primary-deep);
}

body.ki-portal-shell-body .main-nav > li > a:hover,
body.ki-portal-shell-body .main-nav > li > ul > li > a:hover,
body.ki-portal-shell-body .main-nav > li > ul > li > a.active {
	color: var(--sea-primary-deep) !important;
}

body.ki-portal-shell-body .main-nav > li > a[aria-expanded="true"],
body.ki-portal-shell-body .main-nav > li.active > a,
body.ki-portal-shell-body .main-nav > li > ul > li.active > a {
	background: linear-gradient(135deg, #123867 0%, #0e5cb5 100%) !important;
	border-color: transparent !important;
	color: #ffffff !important;
	box-shadow: 0 14px 24px rgba(14, 92, 181, 0.2);
}

body.ki-portal-shell-body .main-nav > li > a[aria-expanded="true"] svg,
body.ki-portal-shell-body .main-nav > li.active > a svg,
body.ki-portal-shell-body .main-nav > li > ul > li.active > a svg,
body.ki-portal-shell-body .main-nav > li > a[aria-expanded="true"] i,
body.ki-portal-shell-body .main-nav > li.active > a i,
body.ki-portal-shell-body .main-nav > li > ul > li.active > a i {
	color: #ffffff !important;
	stroke: #ffffff !important;
}

body.ki-portal-shell-body .main-nav > li > a[aria-expanded="true"] .badge-notification {
	background: #ffffff !important;
	color: var(--sea-secondary) !important;
	border-color: var(--sea-secondary) !important;
}

body.ki-portal-shell-body .main-nav > li > a[aria-expanded="true"] .nav-section-badge {
	background: rgba(255, 255, 255, 0.18);
	color: #ffffff !important;
}

body.ki-portal-shell-body nav .app-nav .main-nav > li:not(.menu-title) ul li.active a::before {
	background-color: #00A8FF !important;
}

body.ki-portal-shell-body .menu-title span {
	color: var(--sea-muted) !important;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

/* -----------------------------------------------------------------------------
 * Side-menu group expand/collapse polish
 *
 * Groups collapse by default and toggle as an accordion (one open at a time);
 * the open one is driven by ki_nav.js. These rules give the toggle a smooth
 * colour transition, an in-flow rotating chevron, and ellipsis truncation so
 * long labels never spill out of the rail.
 * -------------------------------------------------------------------------- */

/* Smooth state changes on the group header. */
body.ki-portal-shell-body .main-nav > li > a,
body.ki-portal-shell-body .main-nav > li > ul > li > a {
	transition: background 0.2s ease, color 0.2s ease, box-shadow 0.2s ease;
}

/* Labels truncate with an ellipsis instead of overflowing the sidebar. */
body.ki-portal-shell-body .main-nav > li > a > span,
body.ki-portal-shell-body .main-nav > li > ul > li > a > span {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* Expand/collapse chevron. The theme's default arrow uses a Phosphor icon font
 * that this portal never loads (it rendered as a blank glyph), so we draw it
 * with the always-loaded Tabler font and rotate a single glyph between states.
 * In-flow at the end of the flex row (not absolutely positioned) so it can
 * never sit on top of the label. */
body.ki-portal-shell-body nav .app-nav .main-nav > li:not(.menu-title):not(.no-sub) > a::after {
	content: "\ea5f" !important;        /* tabler ti-chevron-down */
	font-family: "tabler-icons" !important;
	font-weight: 400 !important;
	font-size: 0.95rem;
	line-height: 1;
	position: static !important;
	top: auto;
	right: auto;
	margin-left: 0.5rem;
	flex-shrink: 0;
	opacity: 0.55;
	transform: rotate(-90deg);          /* collapsed → points right */
	transition: transform 0.3s ease, opacity 0.2s ease;
}

body.ki-portal-shell-body nav .app-nav .main-nav > li:not(.menu-title):not(.no-sub) > a[aria-expanded="true"]::after {
	transform: rotate(0deg);            /* expanded → points down */
	opacity: 0.9;
}

/* The collapsed-icon rail hides labels and arrows entirely — but only while it
 * is actually collapsed; on hover/focus the group chevrons come back too. */
body.ki-portal-shell-body nav.semi-nav:not(:hover):not(:focus-within) .main-nav > li > a::after {
	display: none !important;
}

/* Hover feedback (soft tints). The solid-gradient rules for the open header and
 * active leaf carry !important, so they still win in those states. */
body.ki-portal-shell-body .main-nav > li > a:hover {
	background: var(--sea-primary-mist);
}

body.ki-portal-shell-body .main-nav > li > ul > li > a:hover {
	background: var(--sea-primary-soft);
}

body.ki-portal-shell-body .app-content {
	background: transparent;
	padding-top: 0 !important;
	padding-bottom: 0 !important;
	display: flex;
	flex-direction: column;
	min-height: 100vh;
}

body.ki-portal-shell-body .app-wrapper {
	align-items: stretch;
}

body.ki-portal-shell-body .header-main {
	position: sticky;
	top: 0;
	z-index: 50;
	min-height: 5.4rem;
	padding-left: 0 !important;
	padding-right: 0 !important;
	background: rgba(255, 255, 255, 0.82);
	backdrop-filter: blur(12px);
	border-bottom: 1px solid var(--sea-border);
	box-shadow: 0 10px 28px rgba(10, 37, 64, 0.06);
}

body.ki-portal-shell-body .header-main::before {
	display: none;
}

body.ki-portal-shell-body .app-wrapper .semi-nav ~ .app-content {
	padding-left: var(--semi-nav) !important;
	padding-right: 0 !important;
}

body.ki-portal-shell-body .app-wrapper nav:not(.horizontal-sidebar):not(.semi-nav) ~ .app-content {
	padding-left: var(--sidebar-width) !important;
	padding-right: 0 !important;
}

body.ki-portal-shell-body .app-wrapper .semi-nav ~ .app-content .header-main,
body.ki-portal-shell-body .app-wrapper nav:not(.horizontal-sidebar):not(.semi-nav) ~ .app-content .header-main {
	padding-left: 0 !important;
}

body.ki-portal-shell-body .app-wrapper .semi-nav ~ .app-content footer,
body.ki-portal-shell-body .app-wrapper nav:not(.horizontal-sidebar):not(.semi-nav) ~ .app-content footer {
	padding-left: 0 !important;
	padding-right: 0 !important;
}

/* Under 768px the theme hides the side menu (nav width 0) and opens it as an
   overlay (`semi-nav`, script.js §04), so the content takes the full width.
   The two rules above reserved the sidebar's width at every size, which left
   phones a ~100px column beside an empty strip. */
@media (max-width: 767.98px) {
	body.ki-portal-shell-body .app-wrapper .semi-nav ~ .app-content,
	body.ki-portal-shell-body .app-wrapper nav:not(.horizontal-sidebar):not(.semi-nav) ~ .app-content {
		padding-left: 0 !important;
	}

	/* The header's two halves cannot share one phone-width row: the icon
	   group alone is ~270px. Stack them (menu toggle + search, then the
	   icons) and keep the search prompt on one line. */
	/* The theme pins the header at 65px and the container at 100% of it;
	   header.header-main out-ranks the full-height rule further down. */
	body.ki-portal-shell-body header.header-main,
	body.ki-portal-shell-body header.header-main .container-fluid {
		height: auto;
	}

	body.ki-portal-shell-body .header-right ul {
		gap: 0.5rem;
	}

	body.ki-portal-shell-body .header-right ul > li {
		margin-left: 0 !important;
		margin-right: 0 !important;
	}

	body.ki-portal-shell-body .header-main .container-fluid > .row {
		flex-wrap: wrap;
		row-gap: 0.6rem;
		padding-top: 0.6rem;
		padding-bottom: 0.6rem;
	}

	body.ki-portal-shell-body .header-left.col-6,
	body.ki-portal-shell-body .header-right.col-6 {
		flex: 0 0 100%;
		max-width: 100%;
	}

	body.ki-portal-shell-body .header-search-trigger .form-control {
		display: block;
		min-height: 3rem;
		padding-top: 0;
		padding-bottom: 0;
		padding-right: 1rem;
		line-height: calc(3rem - 2px);
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
	}
}

body.ki-portal-shell-body .header-main .container-fluid,
body.ki-portal-shell-body footer .container-fluid,
body.ki-portal-shell-body .ki-main-container {
	box-sizing: border-box;
	padding-left: var(--sea-shell-inline-padding);
	padding-right: var(--sea-shell-inline-padding);
}

body.ki-portal-shell-body .header-main .container-fluid,
body.ki-portal-shell-body footer .container-fluid {
	max-width: none;
	width: 100%;
	margin-left: 0;
	margin-right: 0;
	height: 100%;
	display: flex;
	align-items: center;
	padding-left: var(--sea-shell-inline-padding);
	padding-right: var(--sea-shell-inline-padding);
}

body.ki-portal-shell-body .header-main .container-fluid > .row,
body.ki-portal-shell-body footer .container-fluid > .row {
	width: 100%;
	align-items: center;
	margin-left: 0;
	margin-right: 0;
}

body.ki-portal-shell-body .ki-main-shell {
	flex: 1 0 auto;
	width: 100%;
	margin: 0;
	padding-top: 1.5rem;
	padding-bottom: 2rem;
}

body.ki-portal-shell-body .head-icon,
body.ki-portal-shell-body .head-user-link {
	color: var(--sea-secondary) !important;
}

body.ki-portal-shell-body .head-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 3rem;
	height: 3rem;
	padding: 0 !important;
}

body.ki-portal-shell-body .head-icon i,
body.ki-portal-shell-body .head-user-link i {
	font-size: 1.15rem;
	line-height: 1;
}

body.ki-portal-shell-body .header-toggle {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 3rem;
	height: 3rem;
	padding: 0;
	border: 0;
	border-radius: 999px;
	background: rgba(0, 168, 255, 0.12);
	color: var(--sea-primary-deep) !important;
	flex-shrink: 0;
	box-shadow: inset 0 0 0 1px rgba(14, 92, 181, 0.08);
}

body.ki-portal-shell-body .header-toggle i {
	font-size: 1.35rem;
	line-height: 1;
}

body.ki-portal-shell-body .header-left {
	gap: 0.85rem;
	min-width: 0;
}

body.ki-portal-shell-body .header-searchbar {
	flex: 1 1 auto;
	min-width: 0;
	max-width: 38rem;
}

body.ki-portal-shell-body .header-right {
	min-width: 0;
}

body.ki-portal-shell-body .header-right ul {
	display: flex;
	align-items: center;
	justify-content: flex-end;
	gap: 0.85rem;
	margin: 0;
	padding: 0;
	list-style: none;
	width: 100%;
}

body.ki-portal-shell-body .header-searchbar form,
body.ki-portal-shell-body .header-search-trigger {
	margin-left: 0 !important;
	margin-right: 0 !important;
}

body.ki-portal-shell-body .header-search-trigger {
	display: block;
	width: 100%;
	padding: 0;
	border: 0;
	background: transparent;
	text-align: left;
}

body.ki-portal-shell-body .header-search-trigger-inner {
	position: relative;
}

body.ki-portal-shell-body .head-icon.bg-light-dark,
body.ki-portal-shell-body .head-user-link {
	background: #ffffff !important;
	border: 1px solid var(--sea-border);
	box-shadow: 0 12px 22px rgba(10, 37, 64, 0.05);
}

body.ki-portal-shell-body .head-user-link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border-radius: 16px;
	padding: 0.35rem 0.75rem;
	text-decoration: none;
	gap: 0.45rem;
	min-width: 3rem;
}

body.ki-portal-shell-body .head-user-chevron {
	width: 1.9rem;
	height: 1.9rem;
	border-radius: 999px;
	align-items: center;
	justify-content: center;
	background: rgba(20, 32, 51, 0.06);
	color: var(--sea-secondary);
}

body.ki-portal-shell-body .head-user-avatar {
	width: 40px;
	height: 40px;
	padding: 0;
}

body.ki-portal-shell-body .head-user-avatar img,
body.ki-portal-shell-body .header-user img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	border-radius: 10px;
}

body.ki-portal-shell-body .badge-notification {
	background: var(--sea-primary-deep) !important;
	color: #ffffff !important;
	border: 2px solid #ffffff;
}

body.ki-portal-shell-body .header-searchbar .form-control,
body.ki-portal-shell-body .workspace-search-modal-content .form-control {
	display: flex;
	align-items: center;
	background: rgba(255, 255, 255, 0.96);
	border-radius: 16px;
	border: 1px solid rgba(74, 74, 74, 0.14);
	min-height: 3.25rem;
	padding-left: 2.8rem;
	box-shadow: 0 12px 24px rgba(10, 37, 64, 0.04);
}

body.ki-portal-shell-body .header-search-trigger .form-control {
	color: var(--sea-muted);
	cursor: pointer;
	padding-right: 4rem;
}

body.ki-portal-shell-body .header-search-kbd {
	position: absolute;
	right: 0.9rem;
	top: 50%;
	transform: translateY(-50%);
	background: var(--sea-secondary-soft);
	color: var(--sea-muted);
	border-radius: 7px;
	padding: 0.2rem 0.5rem;
	font-size: 0.7rem;
	font-family: inherit;
	z-index: 2;
	pointer-events: none;
}

@media (max-width: 767.98px) {
	body.ki-portal-shell-body .header-search-kbd {
		display: none;
	}
}

body.ki-portal-shell-body .header-searchbar i,
body.ki-portal-shell-body .workspace-search-modal-content .app-icon-form i {
	position: absolute;
	left: 1rem;
	top: 50% !important;
	transform: translateY(-50%);
	z-index: 2;
	line-height: 1;
	color: var(--sea-muted) !important;
}

body.ki-portal-shell-body header.header-main .container-fluid .header-left .header-searchbar i,
body.ki-portal-shell-body .workspace-search-modal-content .header-searchbar i,
body.ki-portal-shell-body .workspace-search-modal-content .app-icon-form i {
	top: 50% !important;
	transform: translateY(-50%) !important;
}

body.ki-portal-shell-body .workspace-search-modal-content {
	border: 1px solid var(--sea-border);
	border-radius: 24px;
	overflow: hidden;
	box-shadow: var(--sea-shadow);
}

body.ki-portal-shell-body .workspace-search-results .list-group-item {
	border: 0;
	border-top: 1px solid rgba(74, 74, 74, 0.08);
	padding: 1rem 0;
}

body.ki-portal-shell-body .workspace-search-results .list-group-item:first-child {
	border-top: 0;
}

body.ki-portal-shell-body .workspace-search-results .list-group-item:hover {
	background: var(--sea-primary-soft);
}

/* ===================================================================== */
/*  Scrollable modals whose <form> wraps the header/body/footer          */
/* ===================================================================== */
/* Bootstrap's .modal-dialog-scrollable relies on .modal-content being a  */
/* flex column so .modal-body gets a bounded height and scrolls. Many of  */
/* our modals put a <form> directly inside .modal-content (form wraps     */
/* header+body+footer), which breaks that flex chain: the body never gets */
/* a bounded height, doesn't scroll, and the overflow (incl. the footer)  */
/* is clipped by .modal-content { overflow:hidden }. Make the wrapping    */
/* form a transparent flex pass-through, mirroring .modal-content itself. */
.modal-dialog-scrollable .modal-content > form {
	display: flex;
	flex-direction: column;
	max-height: 100%;
	overflow: hidden;
}

/* ===================================================================== */
/*  Workspace command palette (reworked, streaming search)               */
/* ===================================================================== */

.ws-search-modal .modal-dialog.ws-search-dialog {
	max-width: min(1040px, 94vw);
	width: 100%;
	margin: 3.25rem auto;
}

.ws-search-modal .ws-search-content {
	border: 1px solid var(--sea-border);
	border-radius: 22px;
	overflow: hidden;
	background: var(--sea-surface);
	box-shadow: 0 32px 80px rgba(10, 37, 64, 0.28);
	display: flex;
	flex-direction: column;
	height: min(78vh, 760px);
}

/* --- search bar --- */
.ws-search-bar {
	display: flex;
	align-items: center;
	gap: 0.85rem;
	padding: 1.1rem 1.35rem;
	border-bottom: 1px solid var(--sea-border);
	flex-shrink: 0;
}

.ws-search-bar__icon {
	font-size: 1.5rem;
	color: var(--sea-primary);
	flex-shrink: 0;
}

.ws-search-modal input.ws-search-input {
	flex: 1 1 auto;
	min-width: 0;
	border: 0;
	outline: 0;
	background: transparent;
	font-size: 1.3rem;
	font-weight: 500;
	color: var(--sea-text);
	padding: 0.25rem 0;
}

.ws-search-modal input.ws-search-input::placeholder {
	color: var(--sea-muted);
	font-weight: 400;
}

.ws-search-input::-webkit-search-cancel-button {
	-webkit-appearance: none;
}

.ws-search-spinner {
	width: 18px;
	height: 18px;
	border-radius: 50%;
	border: 2px solid var(--sea-primary-soft);
	border-top-color: var(--sea-primary);
	opacity: 0;
	flex-shrink: 0;
	animation: ws-spin 0.7s linear infinite;
}

.ws-search-spinner.is-active {
	opacity: 1;
}

.ws-search-close {
	border: 0;
	background: transparent;
	padding: 0.2rem;
	cursor: pointer;
	flex-shrink: 0;
	line-height: 1;
}

.ws-search-close kbd {
	background: var(--sea-secondary-soft);
	color: var(--sea-muted);
	border-radius: 7px;
	padding: 0.25rem 0.5rem;
	font-size: 0.72rem;
	font-family: inherit;
}

.ws-search-close:hover kbd {
	background: var(--sea-primary-soft);
	color: var(--sea-primary-deep);
}

/* --- body / scroll area --- */
.ws-search-body {
	flex: 1 1 auto;
	overflow-y: auto;
	padding: 0.85rem 0.9rem 1.1rem;
}

.ws-search-placeholder {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	text-align: center;
	height: 100%;
	min-height: 220px;
	color: var(--sea-muted);
	gap: 0.35rem;
	padding: 2rem;
}

.ws-search-placeholder i {
	font-size: 2.6rem;
	color: var(--sea-primary);
	opacity: 0.55;
	margin-bottom: 0.4rem;
}

.ws-search-placeholder__title {
	margin: 0;
	font-size: 1.05rem;
	font-weight: 600;
	color: var(--sea-text);
}

.ws-search-placeholder__hint {
	margin: 0;
	font-size: 0.82rem;
}

/* --- result groups --- */
.ws-group {
	margin-bottom: 0.6rem;
}

.ws-group__head {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	padding: 0.5rem 0.65rem 0.35rem;
	font-size: 0.72rem;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--sea-muted);
}

.ws-group__icon i {
	font-size: 1rem;
	color: var(--sea-primary);
}

.ws-group__count {
	background: var(--sea-secondary-soft);
	color: var(--sea-muted);
	border-radius: 999px;
	padding: 0.05rem 0.5rem;
	font-size: 0.7rem;
}

.ws-group__spin {
	width: 13px;
	height: 13px;
	border-radius: 50%;
	border: 2px solid var(--sea-primary-soft);
	border-top-color: var(--sea-primary);
	animation: ws-spin 0.7s linear infinite;
}

.ws-group.is-loading {
	opacity: 0.85;
}

/* --- a single hit --- */
.ws-search-modal a.ws-hit {
	display: flex;
	align-items: center;
	gap: 0.85rem;
	padding: 0.7rem 0.75rem;
	border-radius: 12px;
	text-decoration: none;
	color: var(--sea-text);
	transition: background 0.12s ease;
}

.ws-search-modal a.ws-hit.is-active,
.ws-search-modal a.ws-hit:hover {
	background: var(--sea-primary-soft);
}

.ws-hit__icon {
	width: 40px;
	height: 40px;
	border-radius: 11px;
	display: flex;
	align-items: center;
	justify-content: center;
	background: var(--sea-secondary-soft);
	color: var(--sea-secondary);
	flex-shrink: 0;
}

.ws-hit.is-active .ws-hit__icon {
	background: #ffffff;
	color: var(--sea-primary-deep);
}

.ws-hit__icon i {
	font-size: 1.2rem;
}

.ws-hit__body {
	display: flex;
	flex-direction: column;
	min-width: 0;
	flex: 1 1 auto;
}

.ws-hit__title {
	font-weight: 600;
	font-size: 0.95rem;
	color: var(--sea-text);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.ws-hit__subtitle {
	font-size: 0.8rem;
	color: var(--sea-muted);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.ws-hit__badge {
	flex-shrink: 0;
	font-size: 0.7rem;
	font-weight: 600;
}

.ws-hit__enter {
	flex-shrink: 0;
	color: var(--sea-primary-deep);
	opacity: 0;
	transition: opacity 0.12s ease;
}

.ws-hit.is-active .ws-hit__enter {
	opacity: 1;
}

/* --- footer --- */
.ws-search-foot {
	display: flex;
	align-items: center;
	gap: 1.1rem;
	padding: 0.6rem 1.35rem;
	border-top: 1px solid var(--sea-border);
	font-size: 0.74rem;
	color: var(--sea-muted);
	flex-shrink: 0;
}

.ws-search-foot__keys {
	display: inline-flex;
	align-items: center;
	gap: 0.3rem;
}

.ws-search-foot__brand {
	margin-left: auto;
	display: inline-flex;
	align-items: center;
	gap: 0.35rem;
	font-weight: 600;
	color: var(--sea-primary-deep);
}

.ws-search-foot kbd {
	background: var(--sea-secondary-soft);
	color: var(--sea-muted);
	border-radius: 6px;
	padding: 0.1rem 0.4rem;
	font-size: 0.7rem;
	font-family: inherit;
	line-height: 1.4;
}

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

@media (max-width: 575.98px) {
	.ws-search-modal .modal-dialog.ws-search-dialog {
		margin: 0;
		max-width: 100%;
	}

	.ws-search-modal .ws-search-content {
		height: 100vh;
		border-radius: 0;
	}

	.ws-search-foot__keys:not(:first-child) {
		display: none;
	}
}

body.ki-portal-shell-body .offcanvas {
	border-left: 1px solid var(--sea-border);
}

body.ki-portal-shell-body .offcanvas-header,
body.ki-portal-shell-body .offcanvas-body,
body.ki-portal-shell-body .head-box,
body.ki-portal-shell-body .footer-text,
body.ki-portal-shell-body .box-list a,
body.ki-portal-shell-body .app-dropdown a {
	color: var(--sea-secondary) !important;
}

body.ki-portal-shell-body .head-box {
	padding: 1rem 1.25rem;
	border-bottom: 1px solid rgba(74, 74, 74, 0.08);
}

body.ki-portal-shell-body .head-box:last-child {
	border-bottom: 0;
}

body.ki-portal-shell-body footer {
	background: transparent;
	position: static !important;
	inset: auto !important;
	width: auto !important;
	margin-top: auto;
	box-shadow: none !important;
	padding: unset !important;
}

body.ki-portal-shell-body footer .container-fluid {
	border-top: 1px solid var(--sea-border);
	margin-top: 0;
	padding-top: 1rem;
	padding-bottom: 1.2rem;
}

body.ki-portal-shell-body .customizer-btn,
body.ki-portal-shell-body .app-customizer,
body.ki-portal-shell-body #customizer {
	display: none !important;
}

body.ki-portal-shell-body.portal-nav-hidden nav {
	display: none !important;
}

body.ki-portal-shell-body.portal-nav-hidden .app-content {
	padding-left: 0 !important;
	margin-left: 0 !important;
	width: 100% !important;
}

body.ki-portal-shell-body.portal-nav-hidden .app-wrapper .semi-nav ~ .app-content,
body.ki-portal-shell-body.portal-nav-hidden .app-wrapper nav:not(.horizontal-sidebar) ~ .app-content {
	padding-left: 0 !important;
	margin-left: 0 !important;
	width: 100% !important;
}

body.ki-portal-shell-body.portal-nav-hidden .header-main,
body.ki-portal-shell-body.portal-nav-hidden footer {
	left: 0 !important;
	right: 0 !important;
	width: 100% !important;
}

body.ki-portal-shell-body.portal-nav-hidden .header-main .container-fluid,
body.ki-portal-shell-body.portal-nav-hidden footer .container-fluid,
body.ki-portal-shell-body.portal-nav-hidden .ki-main-shell,
body.ki-portal-shell-body.portal-nav-hidden .ki-main-container {
	max-width: none;
	width: 100%;
	margin-left: 0;
	margin-right: 0;
	padding-left: var(--sea-shell-inline-padding);
	padding-right: var(--sea-shell-inline-padding);
}

@media (max-width: 1199.98px) {
	body.ki-portal-shell-body .head-user-link > span:not(.head-user-avatar) {
		display: none !important;
	}
}

@media (min-width: 992px) and (max-width: 1199.98px) {
	body.ki-portal-shell-body {
		--sea-shell-inline-padding: 1rem;
	}

	body.ki-portal-shell-body .header-main .container-fluid > .row {
		gap: 0.75rem;
	}

	body.ki-portal-shell-body .header-left.col-6,
	body.ki-portal-shell-body .header-right.col-6 {
		padding-left: 0 !important;
		padding-right: 0 !important;
	}

	body.ki-portal-shell-body .header-left.col-6 {
		flex: 0 0 62%;
		max-width: 62%;
	}

	body.ki-portal-shell-body .header-right.col-6 {
		flex: 0 0 calc(38% - 0.75rem);
		max-width: calc(38% - 0.75rem);
	}

	body.ki-portal-shell-body .header-searchbar {
		max-width: none;
	}

	body.ki-portal-shell-body .header-search-trigger .form-control {
		min-height: 3rem;
		font-size: 0.95rem;
	}

	body.ki-portal-shell-body .header-right ul {
		gap: 0.65rem;
	}

	body.ki-portal-shell-body .ki-main-shell {
		padding-top: 1.25rem;
	}

	body.ki-portal-shell-body footer .container-fluid {
		padding-top: 0.85rem;
	}
}

/* ---- Side-menu polish (2026-06-10) -----------------------------------
   Tighter, more even spacing now that there are four nav sections, and we
   drop the base theme's left "accent bar" (::before) on sub-items: the active
   item is already a solid filled pill, so the extra bar only read as a
   detached, mis-aligned sliver in the gutter. */
body.ki-portal-shell-body .main-nav > li + li { margin-top: 0.45rem; }
body.ki-portal-shell-body .main-nav > li > a { min-height: 3rem; padding: 0.7rem 0.9rem; }
body.ki-portal-shell-body .main-nav > li > ul { margin-top: 0.35rem; padding-left: 0.25rem; }
body.ki-portal-shell-body .main-nav > li > ul > li + li { margin-top: 0.25rem; }
body.ki-portal-shell-body .main-nav > li > ul > li > a { min-height: 2.55rem; padding: 0.5rem 0.8rem; }
body.ki-portal-shell-body nav .app-nav .main-nav > li:not(.menu-title) ul li a::before { display: none !important; }

/* ---- Side-menu label overflow (2026-09-11) ----------------------------
   Labels too long for the sidebar stopped at an ellipsis ("Detection &
   Re…", "Active Enfor…"), so the title could not be read. ki_nav.js
   measures each label and sets the classes and custom properties used here:
     - group headers and top-level links roll an overflowing label to its end
       and back, continuously (`.is-rolling`);
     - sub-items keep the ellipsis at rest. On hover or keyboard focus the pill
       widens to the right, up to the group header's right edge, and whatever
       still does not fit slides (`.can-slide`).
   ki_nav.js wraps each label's text in `.ki-nav-text`: the label stays put as
   the clipping window and the wrapper moves. */

/* The theme clips every sub-item <li> (overflow:hidden inside its own 1.5rem
   side padding), which would cut a widened pill off at its resting edge. The
   label span does its own clipping. */
body.ki-portal-shell-body nav .app-nav .main-nav > li:not(.menu-title) ul li {
	overflow: visible;
}

/* Width only: a negative right margin grows the pill rightwards into the
   gutter the theme leaves beside sub-items. `--ki-grow` is the measured
   shortfall, capped at the room left before the group header's edge. */
body.ki-portal-shell-body .main-nav > li > ul > li > a {
	transition: background 0.2s ease, color 0.2s ease, box-shadow 0.2s ease,
		margin-right 0.28s cubic-bezier(0.2, 0.8, 0.2, 1);
}

body.ki-portal-shell-body .main-nav > li > ul > li > a:hover,
body.ki-portal-shell-body .main-nav > li > ul > li > a:focus-visible {
	margin-right: calc(-1 * var(--ki-grow, 0px));
}

/* A moving label fades out at its edges instead of slicing glyphs. The fade
   lives in side padding that an equal negative margin cancels, so the row does
   not shift and the text is fully opaque at either end of its travel. */
body.ki-portal-shell-body .main-nav > li > a > span.is-rolling,
body.ki-portal-shell-body .main-nav > li > ul > li > a:hover > span.can-slide,
body.ki-portal-shell-body .main-nav > li > ul > li > a:focus-visible > span.can-slide {
	text-overflow: clip;
	margin-inline: -0.5rem;
	padding-inline: 0.5rem;
	-webkit-mask-image: linear-gradient(90deg, transparent 0, #000 0.5rem, #000 calc(100% - 0.5rem), transparent 100%);
	mask-image: linear-gradient(90deg, transparent 0, #000 0.5rem, #000 calc(100% - 0.5rem), transparent 100%);
}

/* inline-block because a transform does not apply to a plain inline box. */
body.ki-portal-shell-body .main-nav > li > a > span.is-rolling > .ki-nav-text,
body.ki-portal-shell-body .main-nav > li > ul > li > a:hover > span.can-slide > .ki-nav-text,
body.ki-portal-shell-body .main-nav > li > ul > li > a:focus-visible > span.can-slide > .ki-nav-text {
	display: inline-block;
	animation: ki-nav-roll var(--ki-roll-dur, 4s) ease-in-out infinite alternate;
}

/* One leg: pause, travel, pause. `alternate` plays it back, so the text holds
   at each end and never snaps back to the start. */
@keyframes ki-nav-roll {
	0%, 20% { transform: translateX(0); }
	80%, 100% { transform: translateX(var(--ki-roll-shift, 0px)); }
}

/* Reduced motion: nothing rolls or slides. Labels wrap onto a second line
   instead, which also leaves ki_nav.js nothing overflowing to animate. The
   theme's line-height of 2 would make a wrapped sub-item twice as tall. */
@media (prefers-reduced-motion: reduce) {
	body.ki-portal-shell-body .main-nav > li > a > span,
	body.ki-portal-shell-body .main-nav > li > ul > li > a > span {
		white-space: normal;
		line-height: 1.3;
	}

	body.ki-portal-shell-body .main-nav > li > ul > li > a {
		transition: none;
	}
}

/* Group headers and top-level links wrap a long label onto a second line at
   every motion setting. Rolling slid the start of the label under the left
   fade, so it read as "tection & Response" / "er Resilience Portal" for half
   of every cycle. A wrapped label no longer overflows, so ki_nav.js leaves
   it still; sub-items keep the ellipsis and the hover slide. */
body.ki-portal-shell-body .main-nav > li > a > span {
	white-space: normal;
	line-height: 1.3;
}

/* "View examples" floating action button on NIS2 compliance register pages.
   Sits above page content but below an open Bootstrap modal (z-index 1055). */
.ki-examples-fab { z-index: 1040; }

/* ====================================================================
   Notifications — bell button + slide-out panel redesign (2026-06-27)
   Scoped to the admin portal shell. The bell glyph is now perfectly
   centred in a circular hit-target; the panel is a soft floating card
   that pops from the top-right with staggered, animated feed items.
   ==================================================================== */

/* ---- Bell button ---- */
.header-notification .ki-bell-btn {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 42px;
	height: 42px;
	border-radius: 50%;
	background: var(--sea-secondary-soft);
	color: var(--sea-muted);
	text-decoration: none;
	transition: background .2s ease, color .2s ease, box-shadow .2s ease, transform .15s ease;
}

.header-notification .ki-bell-btn:hover {
	background: var(--sea-primary-soft);
	color: var(--sea-primary-deep);
	box-shadow: 0 0 0 4px rgba(0, 168, 255, 0.12);
}

.header-notification .ki-bell-btn:active {
	transform: scale(0.93);
}

.header-notification .ki-bell-icon {
	font-size: 21px;
	line-height: 1;
	transform-origin: 50% 3px;
}

.header-notification .ki-bell-btn:hover .ki-bell-icon {
	animation: ki-bell-ring 0.7s ease;
}

/* Gentle attention ring whenever there are unread items. */
.header-notification .ki-bell-btn:has(.ki-bell-badge:not(.d-none)) .ki-bell-icon {
	animation: ki-bell-ring 4s ease-in-out infinite;
}

@keyframes ki-bell-ring {
	0%, 50%, 80%, 100% { transform: rotate(0); }
	53% { transform: rotate(15deg); }
	57% { transform: rotate(-13deg); }
	61% { transform: rotate(9deg); }
	65% { transform: rotate(-6deg); }
	69% { transform: rotate(3deg); }
	73% { transform: rotate(0); }
}

/* ---- "Make a task" header button: icon-only twin of the bell ---- */
.header-make-task .ki-make-task-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex-shrink: 0;
	width: 42px;
	height: 42px;
	border-radius: 50%;
	background: var(--sea-primary-soft);
	color: var(--sea-primary-deep);
	text-decoration: none;
	transition: background .2s ease, color .2s ease, box-shadow .2s ease, transform .15s ease;
}

.header-make-task .ki-make-task-btn:hover,
.header-make-task .ki-make-task-btn:focus-visible {
	box-shadow: 0 0 0 4px rgba(0, 168, 255, 0.12);
	color: var(--sea-primary-deep);
}

.header-make-task .ki-make-task-btn:active {
	transform: scale(0.93);
}

.header-make-task .ki-make-task-icon {
	display: block;
}

/* The plus badge sits over the clipboard corner, so fill it with the
   button colour to cut the outline underneath. */
.header-make-task .ki-make-task-plus-bg {
	fill: var(--sea-primary-soft);
}

/* ---- Unread badge ---- */
.header-notification .ki-bell-badge {
	position: absolute;
	top: -3px;
	right: -3px;
	min-width: 18px;
	height: 18px;
	padding: 0 5px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	font-size: 10px;
	font-weight: 700;
	line-height: 1;
	color: #fff;
	background: #e14e5a;
	border-radius: 999px;
	border: 2px solid var(--sea-surface);
	box-shadow: 0 2px 6px rgba(225, 78, 90, 0.45);
	z-index: 1;
}

/* Soft expanding pulse behind the badge while unread. */
.header-notification .ki-bell-badge:not(.d-none)::after {
	content: "";
	position: absolute;
	inset: -2px;
	border-radius: inherit;
	background: #e14e5a;
	z-index: -1;
	animation: ki-badge-pulse 2.2s ease-out infinite;
}

@keyframes ki-badge-pulse {
	0% { transform: scale(0.9); opacity: 0.55; }
	70%, 100% { transform: scale(2.1); opacity: 0; }
}

/* ---- Panel shell ---- */
body.ki-portal-shell-body .header-notification-canvas {
	width: 400px !important;
	max-width: calc(100vw - 24px);
	top: 72px !important;
	right: 16px !important;
	bottom: auto;
	max-height: calc(100vh - 96px) !important;
	border: 1px solid var(--sea-border) !important;
	border-radius: 18px !important;
	background: var(--sea-surface);
	box-shadow: 0 24px 60px rgba(15, 23, 42, 0.18), 0 4px 14px rgba(15, 23, 42, 0.06);
	overflow: hidden;
	transform-origin: top right;
	transform: translateY(-12px) scale(0.96) !important;
	opacity: 0;
	transition: transform 0.42s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.28s ease !important;
}

body.ki-portal-shell-body .header-notification-canvas.show,
body.ki-portal-shell-body .header-notification-canvas.showing {
	transform: translateY(0) scale(1) !important;
	opacity: 1;
}

/* Softer, slightly blurred backdrop while the panel is open. */
body.ki-portal-shell-body:has(.header-notification-canvas.show) .offcanvas-backdrop {
	--bs-backdrop-bg: #0f172a;
	--bs-backdrop-opacity: 0.18;
	backdrop-filter: blur(2px);
}

/* ---- Panel header ---- */
body.ki-portal-shell-body .header-notification-canvas .ki-notif-header {
	padding: 1rem 1.15rem;
	background: linear-gradient(180deg, var(--sea-primary-mist), var(--sea-surface));
	border-bottom: 1px solid var(--sea-border);
}

.ki-notif-header-title {
	display: flex;
	align-items: center;
	gap: 0.65rem;
}

.ki-notif-header-icon {
	width: 32px;
	height: 32px;
	flex: 0 0 32px;
	border-radius: 10px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	background: var(--sea-primary-soft);
	color: var(--sea-primary-deep);
	font-size: 18px;
}

body.ki-portal-shell-body .header-notification-canvas .ki-notif-header .offcanvas-title {
	font-weight: 700;
	font-size: 1rem;
	color: var(--sea-text) !important;
}

.ki-notif-close {
	transition: transform 0.2s ease, opacity 0.2s ease;
}

.ki-notif-close:hover {
	transform: rotate(90deg);
	opacity: 1;
}

/* ---- Panel body / scroll ---- */
body.ki-portal-shell-body .header-notification-canvas .ki-notif-body {
	height: auto !important;
	max-height: min(62vh, 540px) !important;
	padding: 0 !important;
	overflow-y: auto;
	overscroll-behavior: contain;
}

body.ki-portal-shell-body .header-notification-canvas .ki-notif-body::-webkit-scrollbar {
	width: 6px;
}

body.ki-portal-shell-body .header-notification-canvas .ki-notif-body::-webkit-scrollbar-thumb {
	background: rgba(74, 74, 74, 0.22);
	border-radius: 999px;
}

.ki-notif-loading {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	text-align: center;
	color: var(--sea-muted);
	padding: 3.5rem 1.5rem;
}

/* ---- Unread bar ---- */
.ki-notif-bar {
	position: sticky;
	top: 0;
	z-index: 2;
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 0.6rem 1.1rem;
	background: rgba(255, 255, 255, 0.92);
	backdrop-filter: blur(6px);
	border-bottom: 1px solid var(--sea-border);
}

.ki-notif-count {
	display: inline-flex;
	align-items: center;
	gap: 0.45rem;
	font-weight: 600;
	font-size: 13px;
	color: var(--sea-text);
}

.ki-notif-count .ki-count-chip {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 20px;
	height: 20px;
	padding: 0 6px;
	font-size: 11px;
	font-weight: 700;
	color: #fff;
	background: var(--sea-primary);
	border-radius: 999px;
}

.ki-mark-all {
	display: inline-flex;
	align-items: center;
	gap: 0.3rem;
	background: none;
	border: 0;
	color: var(--sea-primary-deep);
	font-size: 12px;
	font-weight: 600;
	padding: 0.25rem 0.5rem;
	border-radius: 7px;
	cursor: pointer;
	transition: background 0.16s ease;
}

.ki-mark-all:hover {
	background: var(--sea-primary-soft);
}

/* ---- Feed items ---- */
.ki-notif-list {
	list-style: none;
	margin: 0;
	padding: 0;
}

.ki-notif-item {
	/* sensible defaults; overridden per severity below */
	--ki-bar: var(--sea-primary);
	--ki-ink: var(--sea-primary-deep);
	--ki-soft: var(--sea-primary-soft);
	position: relative;
	padding: 0.85rem 1.1rem 0.9rem 1.25rem;
	border-bottom: 1px solid var(--sea-border);
	transition: background 0.16s ease;
	animation: ki-notif-in 0.4s ease both;
}

.ki-notif-item::before {
	content: "";
	position: absolute;
	left: 0;
	top: 12px;
	bottom: 12px;
	width: 3px;
	border-radius: 0 3px 3px 0;
	background: var(--ki-bar);
	opacity: 0.9;
}

.ki-notif-item:hover {
	background: var(--sea-secondary-soft);
}

.ki-notif-item:last-child {
	border-bottom: 0;
}

.ki-sev-danger    { --ki-bar: #e14e5a; --ki-ink: #c43a45; --ki-soft: #fdecee; }  /* Action needed */
.ki-sev-warning   { --ki-bar: #f0a020; --ki-ink: #a8690a; --ki-soft: #fff4e0; }  /* Notice */
.ki-sev-secondary { --ki-bar: #94a3b8; --ki-ink: #556070; --ki-soft: #f0f3f7; }  /* Info / FYI */
.ki-sev-info      { --ki-bar: #4196fa; --ki-ink: #2f74cc; --ki-soft: #eaf3ff; }
.ki-sev-success   { --ki-bar: #0ab964; --ki-ink: #0a9b54; --ki-soft: #e7f8f0; }

.ki-notif-item-top {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 0.5rem;
}

.ki-sev-pill {
	display: inline-flex;
	align-items: center;
	gap: 0.35rem;
	font-size: 10.5px;
	font-weight: 700;
	letter-spacing: 0.02em;
	text-transform: uppercase;
	padding: 0.22rem 0.5rem;
	border-radius: 999px;
	color: var(--ki-ink);
	background: var(--ki-soft);
}

.ki-sev-pill .ki-dot {
	width: 6px;
	height: 6px;
	border-radius: 50%;
	background: var(--ki-bar);
}

.ki-notif-time {
	font-size: 11px;
	color: var(--sea-muted);
	white-space: nowrap;
}

.ki-notif-title {
	margin-top: 0.4rem;
	font-weight: 600;
	font-size: 13px;
	color: var(--sea-text);
	line-height: 1.35;
}

.ki-notif-detail {
	margin-top: 0.15rem;
	font-size: 12px;
	color: var(--sea-muted);
	line-height: 1.45;
}

.ki-notif-actions {
	display: flex;
	gap: 0.5rem;
	margin-top: 0.65rem;
}

.ki-notif-btn {
	display: inline-flex;
	align-items: center;
	gap: 0.3rem;
	font-size: 12px;
	font-weight: 600;
	padding: 0.34rem 0.7rem;
	border-radius: 8px;
	border: 1px solid transparent;
	text-decoration: none;
	cursor: pointer;
	transition: background 0.16s ease, color 0.16s ease, border-color 0.16s ease, transform 0.12s ease;
}

.ki-notif-btn:active {
	transform: scale(0.96);
}

.ki-notif-btn--open {
	color: var(--sea-primary-deep);
	background: var(--sea-primary-soft);
}

.ki-notif-btn--open:hover {
	color: #fff;
	background: var(--sea-primary);
}

.ki-notif-btn--read {
	color: var(--sea-muted);
	background: var(--sea-surface);
	border-color: var(--sea-border);
}

.ki-notif-btn--read:hover {
	color: var(--sea-text);
	background: var(--sea-secondary-soft);
}

.ki-notif-more {
	text-align: center;
	padding: 0.7rem;
}

.ki-notif-more a {
	display: inline-flex;
	align-items: center;
	gap: 0.3rem;
	font-size: 12px;
	font-weight: 600;
	color: var(--sea-primary-deep);
	text-decoration: none;
}

.ki-notif-more a:hover {
	text-decoration: underline;
}

/* Staggered entrance for the first dozen items. */
@keyframes ki-notif-in {
	from { opacity: 0; transform: translateY(8px); }
	to   { opacity: 1; transform: none; }
}

.ki-notif-item:nth-child(1)  { animation-delay: 0.02s; }
.ki-notif-item:nth-child(2)  { animation-delay: 0.06s; }
.ki-notif-item:nth-child(3)  { animation-delay: 0.10s; }
.ki-notif-item:nth-child(4)  { animation-delay: 0.14s; }
.ki-notif-item:nth-child(5)  { animation-delay: 0.18s; }
.ki-notif-item:nth-child(6)  { animation-delay: 0.22s; }
.ki-notif-item:nth-child(7)  { animation-delay: 0.26s; }
.ki-notif-item:nth-child(8)  { animation-delay: 0.30s; }
.ki-notif-item:nth-child(9)  { animation-delay: 0.34s; }
.ki-notif-item:nth-child(10) { animation-delay: 0.38s; }
.ki-notif-item:nth-child(11) { animation-delay: 0.42s; }
.ki-notif-item:nth-child(12) { animation-delay: 0.46s; }

/* ---- Empty state ---- */
.ki-notif-empty {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	text-align: center;
	padding: 3.5rem 1.5rem;
	color: var(--sea-muted);
}

.ki-notif-empty-icon {
	width: 64px;
	height: 64px;
	border-radius: 18px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	background: var(--sea-primary-soft);
	color: var(--sea-primary);
	font-size: 1.9rem;
	margin-bottom: 1rem;
	animation: ki-notif-float 3.5s ease-in-out infinite;
}

@keyframes ki-notif-float {
	0%, 100% { transform: translateY(0); }
	50% { transform: translateY(-6px); }
}

.ki-notif-empty-title {
	margin: 0 0 0.2rem;
	font-weight: 700;
	font-size: 14px;
	color: var(--sea-text);
}

.ki-notif-empty-sub {
	margin: 0;
	font-size: 13px;
}

/* ---- Footer ---- */
body.ki-portal-shell-body .header-notification-canvas .ki-notif-footer {
	display: flex;
	gap: 0.6rem;
	padding: 0.75rem 1rem;
	border-top: 1px solid var(--sea-border);
	background: var(--sea-surface);
}

.ki-notif-foot-btn {
	flex: 1;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.4rem;
	font-size: 12.5px;
	font-weight: 600;
	padding: 0.55rem 0.75rem;
	border-radius: 10px;
	text-decoration: none;
	transition: background 0.16s ease, color 0.16s ease, box-shadow 0.16s ease, transform 0.12s ease;
}

.ki-notif-foot-btn:active {
	transform: scale(0.97);
}

.ki-notif-foot-btn--ghost {
	color: var(--sea-muted);
	background: var(--sea-secondary-soft);
}

.ki-notif-foot-btn--ghost:hover {
	color: var(--sea-text);
	background: #ececec;
}

.ki-notif-foot-btn--primary {
	color: #fff;
	background: var(--sea-primary);
	box-shadow: 0 6px 16px rgba(0, 168, 255, 0.25);
}

.ki-notif-foot-btn--primary:hover {
	color: #fff;
	background: var(--sea-primary-deep);
}

/* ---- Respect reduced-motion preferences ---- */
@media (prefers-reduced-motion: reduce) {
	.header-notification .ki-bell-btn:has(.ki-bell-badge:not(.d-none)) .ki-bell-icon,
	.header-notification .ki-bell-btn:hover .ki-bell-icon,
	.header-notification .ki-bell-badge:not(.d-none)::after,
	.ki-notif-item,
	.ki-notif-empty-icon,
	.ki-threat-frame--critical {
		animation: none !important;
	}

	body.ki-portal-shell-body .header-notification-canvas {
		transform: none !important;
		transition: opacity 0.2s ease !important;
	}
}

/* Sidebar nav-profile — initials monogram + live online dot (matches the
   header chip and profile panel). Keeps the .h-45.w-45 sizing classes so the
   collapsed icon-rail centring rule still applies. */
body.ki-portal-shell-body .nav-profile .ki-nav-avatar {
	flex-shrink: 0;
	border-radius: 12px;
	font-size: 15px;
	font-weight: 700;
	letter-spacing: 0.01em;
	color: #fff;
	background: linear-gradient(135deg, var(--sea-primary) 0%, var(--sea-primary-deep) 100%);
	box-shadow: 0 6px 16px rgba(0, 168, 255, 0.32);
	transition: transform 0.18s ease, box-shadow 0.18s ease;
}

body.ki-portal-shell-body .nav-profile:hover .ki-nav-avatar {
	transform: translateY(-1px);
	box-shadow: 0 8px 20px rgba(0, 168, 255, 0.42);
}

.ki-nav-online {
	position: absolute;
	top: -2px;
	right: -2px;
	width: 12px;
	height: 12px;
	border-radius: 50%;
	background: #0ab964;
	border: 2px solid #fff;
	animation: ki-online-pulse 2.2s ease-out infinite;
}

@keyframes ki-online-pulse {
	0% { box-shadow: 0 0 0 0 rgba(10, 185, 100, 0.5); }
	70%, 100% { box-shadow: 0 0 0 7px rgba(10, 185, 100, 0); }
}

@media (prefers-reduced-motion: reduce) {
	.ki-nav-online {
		animation: none !important;
	}
}

/* Settings gear — circular hover target. */
body.ki-portal-shell-body .nav-profile .ki-nav-gear {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 34px;
	height: 34px;
	border-radius: 50%;
	color: var(--sea-muted);
	cursor: pointer;
	transition: background 0.16s ease, color 0.16s ease, transform 0.2s ease;
}

body.ki-portal-shell-body .nav-profile .ki-nav-gear:hover {
	background: var(--sea-primary-soft);
	color: var(--sea-primary-deep);
	transform: rotate(45deg);
}

/* Gear dropdown — soft card to match the redesign. */
body.ki-portal-shell-body .profile-menu-dropdown .ki-nav-menu {
	border: 1px solid var(--sea-border);
	border-radius: 14px;
	padding: 0.4rem;
	min-width: 232px;
	box-shadow: 0 18px 44px rgba(15, 23, 42, 0.16);
}

body.ki-portal-shell-body .profile-menu-dropdown .ki-nav-menu .dropdown-item {
	padding: 0;
	border-radius: 10px;
	overflow: hidden;
}

body.ki-portal-shell-body .profile-menu-dropdown .ki-nav-menu .dropdown-item a {
	display: flex;
	align-items: center;
	gap: 0.3rem;
	padding: 0.55rem 0.7rem;
	border-radius: 10px;
	font-size: 13.5px;
	color: var(--sea-text);
	transition: background 0.14s ease, color 0.14s ease;
}

body.ki-portal-shell-body .profile-menu-dropdown .ki-nav-menu .dropdown-item a:hover {
	background: var(--sea-secondary-soft);
}

body.ki-portal-shell-body .profile-menu-dropdown .ki-nav-menu .dropdown-item a.text-danger:hover {
	background: #fdecee;
}

.ki-nav-menu-sep {
	margin: 0.35rem 0.2rem;
	border: 0;
	border-top: 1px solid var(--sea-border);
	opacity: 1;
}

/* Header user chip — initials monogram (matches the profile panel). */
.header-user .ki-head-avatar {
	border-radius: 11px;
	font-size: 14px;
	font-weight: 700;
	letter-spacing: 0.01em;
	color: #fff;
	background: linear-gradient(135deg, var(--sea-primary) 0%, var(--sea-primary-deep) 100%);
	box-shadow: 0 4px 12px rgba(0, 168, 255, 0.32);
	transition: transform 0.16s ease, box-shadow 0.16s ease;
}

.header-user .head-user-link:hover .ki-head-avatar {
	transform: translateY(-1px);
	box-shadow: 0 6px 16px rgba(0, 168, 255, 0.4);
}

/* ====================================================================
   Workspace Profile — slide-out panel redesign (2026-06-27)
   Same floating-card language as the notifications panel: initials
   monogram avatar, role + 2FA status chips, and grouped, icon-led
   menu rows with hover affordances.
   ==================================================================== */

body.ki-portal-shell-body .ki-profile-canvas {
	width: 372px !important;
	max-width: calc(100vw - 24px);
	top: 72px !important;
	right: 16px !important;
	bottom: auto;
	max-height: calc(100vh - 96px) !important;
	border: 1px solid var(--sea-border) !important;
	border-radius: 18px !important;
	background: var(--sea-surface);
	box-shadow: 0 24px 60px rgba(15, 23, 42, 0.18), 0 4px 14px rgba(15, 23, 42, 0.06);
	overflow: hidden;
	transform-origin: top right;
	transform: translateY(-12px) scale(0.96) !important;
	opacity: 0;
	transition: transform 0.42s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.28s ease !important;
}

body.ki-portal-shell-body .ki-profile-canvas.show,
body.ki-portal-shell-body .ki-profile-canvas.showing {
	transform: translateY(0) scale(1) !important;
	opacity: 1;
}

body.ki-portal-shell-body:has(.ki-profile-canvas.show) .offcanvas-backdrop {
	--bs-backdrop-bg: #0f172a;
	--bs-backdrop-opacity: 0.18;
	backdrop-filter: blur(2px);
}

/* ---- Topbar ---- */
body.ki-portal-shell-body .ki-profile-canvas .ki-profile-topbar {
	padding: 0.85rem 1.15rem;
	border-bottom: 1px solid var(--sea-border);
	background: var(--sea-surface);
}

body.ki-portal-shell-body .ki-profile-canvas .ki-profile-topbar .offcanvas-title {
	font-weight: 700;
	font-size: 0.95rem;
	color: var(--sea-text) !important;
}

body.ki-portal-shell-body .ki-profile-canvas .ki-profile-body {
	padding: 0 !important;
	overflow-y: auto;
	overscroll-behavior: contain;
}

body.ki-portal-shell-body .ki-profile-canvas .ki-profile-body::-webkit-scrollbar {
	width: 6px;
}

body.ki-portal-shell-body .ki-profile-canvas .ki-profile-body::-webkit-scrollbar-thumb {
	background: rgba(74, 74, 74, 0.22);
	border-radius: 999px;
}

/* ---- Hero ---- */
.ki-profile-hero {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
	padding: 1.6rem 1.25rem 1.35rem;
	background:
		radial-gradient(120% 90% at 50% -20%, var(--sea-primary-soft) 0%, rgba(232, 247, 255, 0) 70%),
		linear-gradient(180deg, var(--sea-primary-mist), var(--sea-surface));
	border-bottom: 1px solid var(--sea-border);
}

.ki-profile-avatar {
	width: 74px;
	height: 74px;
	border-radius: 20px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	font-size: 1.55rem;
	font-weight: 700;
	letter-spacing: 0.01em;
	color: #fff;
	background: linear-gradient(135deg, var(--sea-primary) 0%, var(--sea-primary-deep) 100%);
	box-shadow: 0 10px 24px rgba(0, 168, 255, 0.35);
	margin-bottom: 0.85rem;
	animation: ki-avatar-pop 0.5s cubic-bezier(0.22, 1, 0.36, 1) both;
}

@keyframes ki-avatar-pop {
	from { opacity: 0; transform: scale(0.6) translateY(6px); }
	to   { opacity: 1; transform: none; }
}

.ki-profile-name {
	margin: 0 0 0.15rem;
	font-weight: 700;
	font-size: 1.05rem;
	color: var(--sea-text);
}

.ki-profile-email {
	margin: 0 0 0.85rem;
	font-size: 12.5px;
	color: var(--sea-muted);
	word-break: break-all;
}

.ki-profile-meta {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 0.4rem;
}

.ki-profile-chip {
	display: inline-flex;
	align-items: center;
	gap: 0.32rem;
	font-size: 11px;
	font-weight: 600;
	padding: 0.28rem 0.6rem;
	border-radius: 999px;
	text-decoration: none;
	border: 1px solid transparent;
}

.ki-profile-chip i {
	font-size: 13px;
}

.ki-profile-role {
	color: var(--sea-primary-deep);
	background: var(--sea-primary-soft);
}

.ki-2fa-on {
	color: #0a9b54;
	background: #e7f8f0;
}

.ki-2fa-off {
	color: #a8690a;
	background: #fff4e0;
	transition: filter 0.16s ease;
}

.ki-2fa-off:hover {
	filter: brightness(0.96);
}

/* ---- Menu ---- */
.ki-profile-menu {
	padding: 0.5rem 0.6rem 0.85rem;
}

.ki-profile-group-label {
	margin: 0.85rem 0.65rem 0.35rem;
	font-size: 10.5px;
	font-weight: 700;
	letter-spacing: 0.07em;
	text-transform: uppercase;
	color: var(--sea-muted);
}

.ki-profile-menu .ki-profile-group-label:first-child {
	margin-top: 0.35rem;
}

.ki-profile-link {
	display: flex;
	align-items: center;
	gap: 0.75rem;
	padding: 0.6rem 0.65rem;
	border-radius: 12px;
	text-decoration: none;
	color: var(--sea-text);
	transition: background 0.16s ease, transform 0.12s ease;
}

.ki-profile-link:hover {
	background: var(--sea-secondary-soft);
}

.ki-profile-link:active {
	transform: scale(0.985);
}

.ki-pl-icon {
	flex: 0 0 38px;
	width: 38px;
	height: 38px;
	border-radius: 11px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	font-size: 19px;
	background: var(--sea-secondary-soft);
	color: var(--sea-muted);
	transition: transform 0.16s ease;
}

.ki-profile-link:hover .ki-pl-icon {
	transform: scale(1.06);
}

.ki-pl-text {
	flex: 1 1 auto;
	display: flex;
	flex-direction: column;
	line-height: 1.25;
	min-width: 0;
}

.ki-pl-text strong {
	font-weight: 600;
	font-size: 13.5px;
	color: var(--sea-text);
}

.ki-pl-text small {
	font-size: 11.5px;
	color: var(--sea-muted);
}

.ki-pl-chev {
	flex: 0 0 auto;
	font-size: 16px;
	color: var(--sea-muted);
	opacity: 0.5;
	transition: transform 0.16s ease, opacity 0.16s ease;
}

.ki-profile-link:hover .ki-pl-chev {
	transform: translateX(3px);
	opacity: 1;
}

/* Icon tile tints */
.ki-pl-blue   { background: #eaf3ff; color: #2f74cc; }
.ki-pl-indigo { background: #eef0ff; color: #5b5bd6; }
.ki-pl-green  { background: #e7f8f0; color: #0a9b54; }
.ki-pl-slate  { background: #f0f3f7; color: #556070; }
.ki-pl-violet { background: #f4ecff; color: #8a3ffc; }
.ki-pl-cyan   { background: #e6f8fb; color: #0a93ad; }
.ki-pl-amber  { background: #fff4e0; color: #a8690a; }
.ki-pl-teal   { background: #e3f7f4; color: #0a8d7e; }
.ki-pl-red    { background: #fdecee; color: #c43a45; }

/* Log out row reads as a quiet danger action. */
.ki-profile-link--danger strong {
	color: #c43a45;
}

.ki-profile-link--danger:hover {
	background: #fdecee;
}

/* Staggered entrance for menu rows + group labels. */
.ki-profile-menu > * {
	animation: ki-notif-in 0.38s ease both;
}

.ki-profile-menu > *:nth-child(1)  { animation-delay: 0.03s; }
.ki-profile-menu > *:nth-child(2)  { animation-delay: 0.06s; }
.ki-profile-menu > *:nth-child(3)  { animation-delay: 0.09s; }
.ki-profile-menu > *:nth-child(4)  { animation-delay: 0.12s; }
.ki-profile-menu > *:nth-child(5)  { animation-delay: 0.15s; }
.ki-profile-menu > *:nth-child(6)  { animation-delay: 0.18s; }
.ki-profile-menu > *:nth-child(7)  { animation-delay: 0.21s; }
.ki-profile-menu > *:nth-child(8)  { animation-delay: 0.24s; }
.ki-profile-menu > *:nth-child(9)  { animation-delay: 0.27s; }
.ki-profile-menu > *:nth-child(10) { animation-delay: 0.30s; }
.ki-profile-menu > *:nth-child(11) { animation-delay: 0.33s; }
.ki-profile-menu > *:nth-child(12) { animation-delay: 0.36s; }

@media (prefers-reduced-motion: reduce) {
	body.ki-portal-shell-body .ki-profile-canvas {
		transform: none !important;
		transition: opacity 0.2s ease !important;
	}

	.ki-profile-avatar,
	.ki-profile-menu > * {
		animation: none !important;
	}
}

/* Rendered Markdown (AI audit summary/narrative/roadmap, and any `| markdown`
   field). Keeps AI prose readable — tight leading, list indents, blockquotes. */
.markdown-body > :first-child { margin-top: 0; }
.markdown-body > :last-child { margin-bottom: 0; }
.markdown-body p { margin: 0 0 .7rem; line-height: 1.55; }
.markdown-body ul,
.markdown-body ol { margin: .3rem 0 .8rem 1.35rem; padding: 0; }
.markdown-body li { margin: .2rem 0; }
.markdown-body li > p { margin: 0; }
.markdown-body h1,
.markdown-body h2,
.markdown-body h3,
.markdown-body h4 { margin: 1.1rem 0 .5rem; line-height: 1.25; font-weight: 600; }
.markdown-body h1 { font-size: 1.25rem; }
.markdown-body h2 { font-size: 1.1rem; }
.markdown-body h3 { font-size: 1rem; }
.markdown-body h4 { font-size: .9rem; }
.markdown-body blockquote {
	margin: .7rem 0;
	padding: .35rem .9rem;
	border-left: 3px solid var(--bs-border-color, #d0d5dd);
	color: var(--bs-secondary-color, #667085);
	background: var(--bs-tertiary-bg, #f8f9fa);
	border-radius: 0 .35rem .35rem 0;
}
.markdown-body code {
	background: var(--bs-tertiary-bg, #f1f3f5);
	padding: .1rem .35rem;
	border-radius: .25rem;
	font-size: .875em;
}
.markdown-body pre { background: var(--bs-tertiary-bg, #f1f3f5); padding: .75rem 1rem; border-radius: .4rem; overflow-x: auto; }
.markdown-body pre code { background: none; padding: 0; }
.markdown-body table { width: 100%; margin: .6rem 0; border-collapse: collapse; }
.markdown-body th,
.markdown-body td { border: 1px solid var(--bs-border-color, #e5e7eb); padding: .35rem .55rem; text-align: left; }
.markdown-body hr { border: 0; border-top: 1px solid var(--bs-border-color, #e5e7eb); margin: 1rem 0; }


/* ==========================================================================
   Elevated-threat indicator
   --------------------------------------------------------------------------
   Driven by /app/threat-defense/elevated (polled from the header, see
   partials/app/header_app.html). Two surfaces:

     .ki-threat-frame  a fixed overlay tinting the whole window, so the state is
                       visible from every page rather than only the ones an
                       operator happened to open;
     .ki-threat-pill   a counted pill in the header linking to the queue.

   Red = at least one ENFORCING action (block / ban / quarantine) is live.
   Amber = alert-only findings. Even one is enough to colour the shell: the
   product default is monitor-mode, so anything reaching this point is already
   past a threshold somebody set deliberately.
   ========================================================================== */

/* z-index sits BELOW Bootstrap's overlay stack (offcanvas 1045, backdrop 1050,
   modal 1055, popover 1070, tooltip 1080), matching .ki-examples-fab above. A
   full-viewport frame painted over an open dialog does not read as a border on
   the window — it reads as a rendering fault, and it obscured the thing the
   operator opened. When a dialog is up, the dialog is what matters; the frame
   correctly dims under its backdrop. */
.ki-threat-frame {
	position: fixed;
	inset: 0;
	z-index: 1030;
	pointer-events: none;
	border: 0 solid transparent;
	transition: border-color .35s ease, border-width .35s ease, box-shadow .35s ease;
}

.ki-threat-frame--critical {
	border-width: 3px;
	border-color: rgba(225, 78, 90, 0.55);
	box-shadow: inset 0 0 0 1px rgba(225, 78, 90, 0.18), inset 0 0 34px rgba(225, 78, 90, 0.12);
	animation: ki-threat-frame-breathe 4s ease-in-out infinite;
	/* Promote to its own compositor layer so the breathe below never repaints
	   the page underneath it. */
	will-change: opacity;
}

.ki-threat-frame--elevated {
	border-width: 3px;
	border-color: rgba(240, 160, 32, 0.5);
	box-shadow: inset 0 0 0 1px rgba(240, 160, 32, 0.16), inset 0 0 30px rgba(240, 160, 32, 0.1);
}

/* Slow, low-amplitude — it must read as "still true" from peripheral vision
   without competing with whatever the operator is actually reading.

   Animates OPACITY, not border-color: a colour change on a full-viewport
   element with a 34px inset shadow forces a full-page repaint every frame,
   which tore the UI while dialogs were open. Opacity is composited on the GPU
   and touches nothing else. */
@keyframes ki-threat-frame-breathe {
	0%, 100% { opacity: 1; }
	50% { opacity: .5; }
}

.ki-threat-pill-slot { display: inline-flex; align-items: center; }

.ki-threat-pill {
	display: inline-flex;
	align-items: center;
	gap: .4rem;
	padding: .25rem .7rem;
	margin-right: .5rem;
	border-radius: 999px;
	font-size: 12px;
	font-weight: 600;
	line-height: 1.6;
	text-decoration: none;
	border: 1px solid transparent;
	transition: background .2s ease, border-color .2s ease;
}

.ki-threat-pill i { font-size: 14px; }

.ki-threat-pill--critical {
	color: var(--sea-danger-ink);
	background: rgba(225, 78, 90, 0.12);
	border-color: rgba(225, 78, 90, 0.4);
}

.ki-threat-pill--critical:hover {
	color: var(--sea-danger-ink);
	background: rgba(225, 78, 90, 0.2);
}

.ki-threat-pill--elevated {
	color: var(--sea-warning-ink);
	background: rgba(240, 160, 32, 0.14);
	border-color: rgba(240, 160, 32, 0.42);
}

.ki-threat-pill--elevated:hover {
	color: var(--sea-warning-ink);
	background: rgba(240, 160, 32, 0.22);
}

/* Read failed — status genuinely unknown. Deliberately muted rather than green
   or red: it is neither an all-clear nor a threat, it is a blind indicator, and
   it must be visibly distinct from both. */
.ki-threat-pill--unknown {
	color: var(--sea-muted, #6b7280);
	background: rgba(107, 114, 128, 0.12);
	border-color: rgba(107, 114, 128, 0.38);
	border-style: dashed;
}

.ki-threat-pill--unknown:hover {
	color: var(--sea-muted, #6b7280);
	background: rgba(107, 114, 128, 0.2);
}

.ki-threat-pill-count {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 18px;
	height: 18px;
	padding: 0 5px;
	border-radius: 999px;
	background: var(--sea-danger);
	color: #fff;
	font-size: 10px;
	font-weight: 700;
}

.ki-threat-pill--elevated .ki-threat-pill-count { background: var(--sea-warning); }

.ki-threat-pill-text { white-space: nowrap; }

@media (max-width: 575.98px) {
	.ki-threat-pill-text { display: none; }
}

/* ---- Response-queue row emphasis ----
   Same red/amber, applied as a left accent bar on the action card, mirroring
   the .ki-notif-item::before idiom. A queue where every row looks identical
   makes the operator read all of them to find the one that enforces. */

.ki-action-card { position: relative; overflow: hidden; }

.ki-action-card::before {
	content: "";
	position: absolute;
	inset: 0 auto 0 0;
	width: 3px;
	background: transparent;
}

.ki-action-card--critical::before { background: var(--sea-danger); opacity: .9; }
.ki-action-card--elevated::before { background: var(--sea-warning); opacity: .9; }

.ki-action-card--critical { background: rgba(225, 78, 90, 0.035); }
.ki-action-card--elevated { background: rgba(240, 160, 32, 0.035); }

/* ── IAM · Users & Roles ─────────────────────────────────────────────────────
   Calmer table rhythm, one uniform quiet action style (intent shows on hover
   instead of five competing button colours), and role chips that read as
   assignments rather than errors. */

.iam-table thead th {
	font-size: .72rem;
	text-transform: uppercase;
	letter-spacing: .06em;
	font-weight: 600;
	color: var(--sea-muted);
	border-bottom: 1px solid var(--sea-border);
	padding: .55rem .6rem;
	/* Two-word headings may wrap: "Last sign-in" held its column at full
	   heading width and pushed Actions past the card edge. */
	white-space: normal;
}
.iam-table tbody td {
	padding: .95rem .6rem;
	border-bottom: 1px solid var(--sea-border);
	vertical-align: middle;
}
.iam-table tbody tr:last-child td { border-bottom: 0; }
.iam-table tbody tr { transition: background .14s ease; }
.iam-table tbody tr:hover { background: var(--sea-primary-mist); }
.iam-table .badge { font-weight: 600; }

/* Actions stay pinned to the right edge when a narrow window makes the table
   scroll sideways, instead of scrolling out of view. The cell needs its own
   opaque fill (the row-hover tint is laid over it) so the columns passing
   underneath do not show through. */
.iam-table thead th:last-child,
.iam-table tbody td:last-child {
	position: sticky;
	right: 0;
	z-index: 1;
	background-color: var(--sea-surface);
}
.iam-table tbody tr:hover td:last-child {
	background-image: linear-gradient(var(--sea-primary-mist), var(--sea-primary-mist));
}

/* Uniform icon actions: quiet at rest, intent-coloured on hover. */
/* Up to eight icon actions per user: they wrap four to a line in a fixed-width block, so
   the Actions column fits the card instead of running past its right edge. */
.iam-actions {
	display: inline-flex;
	flex-wrap: wrap;
	justify-content: flex-end;
	gap: .3rem;
	width: calc(4 * 2rem + 3 * .3rem);
	vertical-align: middle;
}
.iam-act {
	width: 2rem;
	height: 2rem;
	display: inline-grid;
	place-items: center;
	border: 1px solid var(--sea-border);
	background: var(--sea-surface);
	color: var(--sea-muted);
	border-radius: 10px;
	font-size: 1rem;
	line-height: 1;
	padding: 0;
	transition: background .15s ease, color .15s ease, border-color .15s ease,
		transform .12s ease, box-shadow .15s ease;
}
.iam-act:hover {
	transform: translateY(-1px);
	box-shadow: 0 8px 18px rgba(0, 0, 0, .08);
	color: var(--sea-text);
	background: var(--sea-secondary-soft);
}
.iam-act:active { transform: translateY(0); }
.iam-act-primary:hover {
	background: var(--sea-primary-soft);
	color: var(--sea-primary-deep);
	border-color: var(--sea-primary);
}
.iam-act-success:hover {
	background: rgba(23, 160, 100, .1);
	color: #128054;
	border-color: rgba(23, 160, 100, .45);
}
.iam-act-warning:hover {
	background: rgba(240, 160, 32, .12);
	color: var(--sea-warning-ink);
	border-color: rgba(240, 160, 32, .5);
}
.iam-act-danger:hover {
	background: rgba(225, 78, 90, .1);
	color: var(--sea-danger-ink);
	border-color: rgba(225, 78, 90, .5);
}

/* Assigned-role chips: neutral pills whose remove affordance only turns
   destructive when you aim at it. */
.iam-role-chip {
	display: inline-flex;
	align-items: center;
	gap: .35rem;
	padding: .22rem .7rem;
	border-radius: 999px;
	border: 1px solid var(--sea-border);
	background: var(--sea-secondary-soft);
	color: var(--sea-text);
	font-size: .78rem;
	font-weight: 600;
	line-height: 1.3;
	transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.iam-role-chip .ti { font-size: .78rem; opacity: .5; transition: opacity .15s ease; }
.iam-role-chip:hover {
	background: rgba(225, 78, 90, .08);
	border-color: rgba(225, 78, 90, .45);
	color: var(--sea-danger-ink);
}
.iam-role-chip:hover .ti { opacity: 1; }
.iam-role-chip:disabled { opacity: .55; cursor: not-allowed; }
.iam-role-chip:disabled:hover {
	background: var(--sea-secondary-soft);
	border-color: var(--sea-border);
	color: var(--sea-text);
}

/* Endpoint view, Device checks card: before the agent reports its checks the
   network-access notice is the card's last block and had no bottom inset. */
#ed-network-access:last-child { padding-bottom: 1.5rem; }

/* ==========================================================================
   Status timelines
   --------------------------------------------------------------------------
   The operator-console copy of the customer portal's history bar. Same class
   names and the same server-rendered segments (see `common::status_strip`), so
   an outage looks identical in both consoles; only the palette is bound to the
   admin design tokens.

   The 1px flex gap draws a hairline at every state change, and a non-healthy
   segment carries a minimum width — one bad hour is 0.05% of a 90-day window
   and would otherwise render as nothing at all.
   ========================================================================== */
.status-timeline { display: flex; flex-direction: column; gap: .35rem; width: 100%; }

.hist-bar {
	display: flex;
	gap: 1px;
	width: 100%;
	height: 20px;
	border-radius: 6px;
	overflow: hidden;
	background: var(--sea-secondary-soft);
	box-shadow: inset 0 0 0 1px var(--sea-border);
}

/* A fragment is a real <button>: clickable, and the outages are keyboard
   reachable (healthy stretches carry tabindex="-1", so tabbing walks you from
   interruption to interruption rather than through 180 identical green slots). */
.hist-seg {
	display: block;
	height: 100%;
	min-width: 2px;
	padding: 0;
	border: 0;
	border-radius: 0;
	appearance: none;
	font: inherit;
	color: inherit;
	cursor: pointer;
	transition: filter .12s ease;
}
.hist-seg:hover { filter: brightness(1.15); }
.hist-seg:focus-visible { outline: 2px solid var(--sea-text); outline-offset: 1px; z-index: 1; }
.hist-seg.is-active { filter: brightness(1.25); box-shadow: inset 0 0 0 1px var(--sea-text); }
.hist-seg.hist-event { min-width: 4px; }

.hist-ok { background: #2fb37a; }
.hist-degraded { background: var(--sea-warning); }
.hist-down { background: var(--sea-danger); }
/* Unsampled time is a gap in the record and is drawn as one — never as green. */
.hist-unknown,
.hist-bar-empty {
	background: repeating-linear-gradient(
		135deg,
		var(--sea-secondary-soft) 0 4px,
		transparent 4px 8px
	);
}

.hist-axis { display: flex; justify-content: space-between; align-items: baseline; font-size: .7rem; color: var(--sea-muted); }
.hist-caption { display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap; }
.hist-uptime { font-weight: 700; font-size: .95rem; color: var(--sea-text); }
.hist-coverage { border-bottom: 1px dotted var(--sea-muted); cursor: help; }

.status-timeline-compact .hist-bar { height: 9px; border-radius: 4px; }
.hist-inline { display: flex; flex-direction: column; gap: .2rem; min-width: 150px; }
.hist-inline-meta { font-size: .7rem; white-space: nowrap; }

.hist-windows { display: flex; align-items: center; gap: .35rem; flex-wrap: wrap; }
.hist-window {
	padding: .15rem .55rem;
	border: 1px solid var(--sea-border);
	border-radius: 999px;
	background: var(--sea-surface);
	color: var(--sea-muted);
	font-size: .74rem;
	text-decoration: none;
	transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.hist-window:hover { background: var(--sea-secondary-soft); color: var(--sea-text); }
.hist-window.is-active { background: var(--sea-primary-fill); border-color: var(--sea-primary-fill); color: #fff; }
/* The pills are links: out-rank `.app-wrapper a` so the active label is white. */
.app-wrapper a.hist-window.is-active { color: #fff !important; }

.hist-rollup { display: flex; flex-direction: column; gap: .6rem; }
.hist-host { display: flex; flex-direction: column; gap: .3rem; padding: .55rem 0; border-top: 1px solid var(--sea-border); }
.hist-host:first-of-type { border-top: 0; }
.hist-host-name { font-weight: 600; font-size: .88rem; }

/* Detail panel for one fragment. Positioned in the viewport by timeline.js and
   torn down on scroll/resize/htmx swap rather than re-measured. */
.hist-pop {
	position: fixed;
	z-index: 1200;
	min-width: 210px;
	padding: .7rem .85rem;
	border: 1px solid var(--sea-border);
	border-radius: 12px;
	background: var(--sea-surface);
	box-shadow: var(--sea-shadow);
	font-size: .8rem;
	color: var(--sea-text);
}
.hist-pop-head { display: flex; align-items: center; gap: .4rem; margin-bottom: .45rem; padding-right: 1rem; }
.hist-pop-dot { width: 10px; height: 10px; border-radius: 3px; flex: 0 0 auto; }
.hist-pop-row { display: flex; justify-content: space-between; gap: 1.2rem; padding: .12rem 0; }
.hist-pop-row span:first-child { color: var(--sea-muted); }
.hist-pop-close {
	position: absolute;
	top: .3rem;
	right: .45rem;
	border: 0;
	background: none;
	color: var(--sea-muted);
	font-size: 1.1rem;
	line-height: 1;
	cursor: pointer;
}
.hist-pop-close:hover { color: var(--sea-text); }

/* The interactive rollup bar: equal-width sections rather than proportional
   runs, so every section is a click target of the same size. The wider gap is
   what makes them read as separate sections instead of one continuous bar. */
.hist-bar-slots { gap: 2px; height: 26px; }
.hist-bar-slots .hist-seg { flex: 1 1 0; min-width: 0; border-radius: 2px; }
.hist-bar-drill .hist-seg { transition: filter .12s ease, transform .12s ease; }
.hist-bar-drill .hist-seg:hover { filter: brightness(1.2); transform: scaleY(1.12); }

/* Time-travel banner: the table below is a reconstruction, and it says so. */
.hist-asof {
	display: flex;
	align-items: center;
	gap: .6rem;
	flex-wrap: wrap;
	padding: .55rem .8rem;
	margin-bottom: .9rem;
	border: 1px solid var(--sea-warning);
	border-radius: 10px;
	background: rgba(240, 160, 32, .1);
	font-size: .84rem;
}
.hist-pop-detail { margin-top: .4rem; padding-top: .4rem; border-top: 1px solid var(--sea-border); color: var(--sea-muted); font-size: .75rem; }

/* ==========================================================================
   Daily Tasks: one look per task state, everywhere a task is shown
   (the list, the task page, the dialogs and the dashboard panels).
   ========================================================================== */

/* A status pill: tinted background, strong text, and the status's own icon
   (`tasks::status_icon`), so it reads by shape as well as by colour. The
   same colours drive the row rail, the status strip and the dashboard chart
   (`status_hue` in handlers/dashboards.rs). */
.ki-state {
	--ki-state-bg: #eef2f7;
	--ki-state-fg: #475569;
	--ki-state-line: transparent;
	display: inline-flex;
	align-items: center;
	gap: .3rem;
	padding: .2rem .55rem;
	border: 1px solid var(--ki-state-line);
	border-radius: 999px;
	background: var(--ki-state-bg);
	color: var(--ki-state-fg);
	font-size: .75rem;
	font-weight: 600;
	line-height: 1.25;
	white-space: nowrap;
}
.ki-state .ti { font-size: .9rem; }
.ki-state-lg { padding: .35rem .8rem; font-size: .88rem; }
.ki-state-lg .ti { font-size: 1.05rem; }
/* To do is outlined and dashed: nothing has happened to it yet. */
.ki-state-open { --ki-state-bg: #f8fafc; --ki-state-fg: #475569; --ki-state-line: #94a3b8; border-style: dashed; }
.ki-state-in_progress { --ki-state-bg: #dbeafe; --ki-state-fg: #1d4ed8; }
.ki-state-waiting { --ki-state-bg: #cffafe; --ki-state-fg: #0e7490; }
.ki-state-blocked { --ki-state-bg: #fee2e2; --ki-state-fg: #b91c1c; --ki-state-line: #fca5a5; }
.ki-state-in_review { --ki-state-bg: #ede9fe; --ki-state-fg: #6d28d9; }
.ki-state-deferred { --ki-state-bg: #f1f5f9; --ki-state-fg: #64748b; }
.ki-state-done { --ki-state-bg: #dcfce7; --ki-state-fg: #15803d; }
.ki-state-cancelled { --ki-state-bg: #f1f5f9; --ki-state-fg: #6b7280; text-decoration: line-through; }

/* The rail: a coloured left edge per row (and on the task page's state
   card), so a column of red rails is a column of blocked work. A border, not
   a box-shadow: Bootstrap paints table hover and stripes with an inset
   box-shadow, which a shadow here would replace. */
.ki-task-table > tbody > tr > td:first-child { border-left: 4px solid var(--ki-rail, transparent); }
.ki-task-state { border-left: 4px solid var(--ki-rail, transparent) !important; }
.ki-rail-open { --ki-rail: #94a3b8; }
.ki-rail-in_progress { --ki-rail: #2563eb; }
.ki-rail-waiting { --ki-rail: #06b6d4; }
.ki-rail-blocked { --ki-rail: #dc2626; }
.ki-rail-in_review { --ki-rail: #7c3aed; }
.ki-rail-deferred { --ki-rail: #cbd5e1; }
.ki-rail-done { --ki-rail: #16a34a; }
.ki-rail-cancelled { --ki-rail: #d1d5db; }
.ki-task-row.ki-rail-done td, .ki-task-row.ki-rail-cancelled td { color: var(--sea-muted, #6b7280); }

/* The status strip above the list: every status with its count. The chips
   are the status filter and the legend at once. */
.ki-state-strip { display: flex; flex-wrap: wrap; align-items: center; gap: .3rem; }
.ki-state-strip-sep { width: 1px; align-self: stretch; margin: .1rem .3rem; background: #dfe3ea; }
/* `.ki-state-strip a.ki-chip`: the theme tints every `.app-wrapper a` with
   !important, which a bare class would lose to. */
.ki-chip {
	--ki-chip: #475569;
	display: inline-flex;
	align-items: center;
	gap: .3rem;
	padding: .25rem .55rem;
	border: 1px solid #dfe3ea;
	border-radius: 999px;
	background: #fff;
	font-size: .78rem;
	font-weight: 500;
	text-decoration: none !important;
	white-space: nowrap;
	transition: border-color .12s ease, background-color .12s ease;
}
.ki-state-strip a.ki-chip { color: #1f2937 !important; }
.ki-chip .ti { color: var(--ki-chip); font-size: .95rem; }
.ki-chip:hover { border-color: var(--ki-chip); }
.ki-chip-count {
	min-width: 1.4rem;
	padding: .05rem .4rem;
	border-radius: 999px;
	background: #f1f5f9;
	color: #334155;
	font-size: .72rem;
	font-weight: 700;
	text-align: center;
}
.ki-chip.is-empty { opacity: .55; }
.ki-state-strip a.ki-chip.is-active { border-color: var(--ki-chip); background: var(--ki-chip); color: #fff !important; font-weight: 600; opacity: 1; }
.ki-chip.is-active .ti { color: #fff; }
.ki-chip.is-active .ki-chip-count { background: rgba(255, 255, 255, .25); color: #fff; }
.ki-chip-all { --ki-chip: #334155; }
.ki-chip-open { --ki-chip: #64748b; }
.ki-chip-in_progress { --ki-chip: #2563eb; }
.ki-chip-waiting { --ki-chip: #0891b2; }
.ki-chip-blocked { --ki-chip: #dc2626; }
.ki-chip-in_review { --ki-chip: #7c3aed; }
.ki-chip-deferred { --ki-chip: #94a3b8; }
.ki-chip-done { --ki-chip: #16a34a; }
.ki-chip-cancelled { --ki-chip: #9ca3af; }

/* Tiers. Tier 2 wears its own colour (not a status colour, not a priority
   colour), because an escalated task can be in any status at any priority. */
.ki-tier, .ki-tier2 {
	display: inline-flex;
	align-items: center;
	gap: .25rem;
	padding: .12rem .5rem;
	border-radius: 999px;
	font-size: .72rem;
	font-weight: 700;
	line-height: 1.3;
	white-space: nowrap;
	vertical-align: middle;
}
.ki-tier-1 { background: #f1f5f9; color: #475569; }
.ki-tier-2, .ki-tier2 { background: #fae8ff; color: #a21caf; }
.ki-text-tier2 { color: #a21caf !important; }
.ki-escalation {
	padding: .6rem .8rem;
	border-left: 3px solid #c026d3;
	border-radius: 6px;
	background: #fdf4ff;
}

/* Daily Tasks recommendations (written by an assistant through /mcp): the
   list's "Advice" pill and the task page's card, railed in amber like a bulb. */
.ki-recommended {
	display: inline-flex;
	align-items: center;
	gap: .25rem;
	padding: .12rem .5rem;
	border-radius: 999px;
	font-size: .72rem;
	font-weight: 700;
	line-height: 1.3;
	white-space: nowrap;
	vertical-align: middle;
	background: #fef3c7;
	color: #92400e;
}
.ki-recommendation { border-left: 3px solid #f59e0b !important; }
.ki-recommendation-body { font-size: .92rem; }
.ki-recommendation-body a { text-decoration: underline; }
.ki-recommendation-body ul li:has(> input[type="checkbox"]) { list-style: none; margin-left: -1.2rem; }

/* The task page's progress line: To do, In progress, In review, Done. A
   parked status (waiting, blocked, deferred) replaces the step it paused on
   with its own pill. */
.ki-steps { display: flex; margin: 0; padding: 0; list-style: none; }
.ki-steps li {
	position: relative;
	flex: 1 1 0;
	min-width: 0;
	padding-top: 1.65rem;
	color: #94a3b8;
	font-size: .78rem;
	text-align: center;
}
.ki-steps li::before {
	content: "";
	position: absolute;
	top: .35rem;
	left: 50%;
	z-index: 1;
	width: 1rem;
	height: 1rem;
	margin-left: -.5rem;
	border: 2px solid #cbd5e1;
	border-radius: 50%;
	background: #fff;
}
.ki-steps li::after {
	content: "";
	position: absolute;
	top: .78rem;
	left: -50%;
	width: 100%;
	height: 2px;
	background: #e2e8f0;
}
.ki-steps li:first-child::after { display: none; }
.ki-steps .ki-step-label { display: block; }
.ki-steps .ki-step-sub { display: block; font-size: .7rem; color: #b6c0cc; }
.ki-steps li.is-done { color: #15803d; }
.ki-steps li.is-done::before { border-color: #16a34a; background: #16a34a; }
.ki-steps li.is-done::after,
.ki-steps li.is-current::after,
.ki-steps li.is-paused::after,
.ki-steps li.is-cancelled::after { background: #86efac; }
.ki-steps li.is-current { color: #1d4ed8; font-weight: 700; }
.ki-steps li.is-current::before { border-color: #2563eb; background: #2563eb; box-shadow: 0 0 0 4px rgba(37, 99, 235, .18); }
.ki-steps li.is-paused::before { border-style: dashed; border-color: #f59e0b; box-shadow: 0 0 0 4px rgba(245, 158, 11, .15); }
.ki-steps li.is-skipped { color: #cbd5e1; }
.ki-steps li.is-skipped .ki-step-label { text-decoration: line-through; }
.ki-steps li.is-skipped::before { border-style: dashed; }
.ki-steps li.is-cancelled { color: #6b7280; font-weight: 700; }
.ki-steps li.is-cancelled::before { border-color: #9ca3af; background: #9ca3af; }
@media (max-width: 575.98px) {
	.ki-steps li { font-size: .7rem; }
	.ki-steps li .ki-state { padding: .15rem .4rem; font-size: .68rem; }
}
