/*
 * Tell brand theme for the SFTPGo web portal.
 *
 * Ported from tell-mobile (TellMobile/src/components/auth/LoginForm.tsx and
 * web/index.html), which is the current design language: #faf9ff page, white
 * cards, the #395da6 -> #8037c7 gradient on primary actions, pill buttons,
 * LexendDeca headlines, LexendExa uppercase labels, Inter body text.
 *
 * SFTPGo 2.7.5 ships the KeenThemes Metronic theme on Bootstrap 5, so almost
 * everything is reachable through Bootstrap custom properties — no template
 * forking, which would have to be re-merged on every SFTPGo upgrade.
 *
 * Loaded through httpd.branding.*.extra_css. The templates emit extra_css
 * AFTER SFTPGo's own stylesheets, so equal-specificity rules win on document
 * order; !important appears only where Metronic itself uses it.
 *
 * Served from /static/tell/, so the @font-face URLs below are relative to this
 * file and need no knowledge of the static prefix.
 */

/* Inter is already bundled by SFTPGo (static/vendor/fonts/inter), so only the
   two Lexend faces travel with us. */
@font-face {
  font-family: 'LexendDeca';
  src: url('LexendDeca.ttf') format('truetype');
  font-display: swap;
}

@font-face {
  font-family: 'LexendExa';
  src: url('LexendExa.ttf') format('truetype');
  font-display: swap;
}

/*
 * Dark mode neutraliser — MUST come before the Tell palette below.
 *
 * Metronic follows the OS colour scheme: templates/common/base.html runs
 * defaultThemeMode = "system", so prefers-color-scheme: dark sets
 * <html data-bs-theme="dark">. Forcing it would need data-bs-theme-mode on <html>,
 * which lives in the template — out of reach from a stylesheet.
 *
 * Overriding dark values one variable at a time turned into whack-a-mole across a
 * 1.3 MB stylesheet (the near-black card headers came from --bs-light, the washed-out
 * sidebar from the inverted grey ramp). So instead the entire light palette is replayed
 * into the dark scope: 252 variables lifted verbatim from Metronic's own
 * [data-bs-theme=light] blocks. Dark mode stops existing, and the Tell overrides that
 * follow apply on top at equal specificity, winning on document order.
 *
 * The mobile app has no dark variant to match, so a half-themed dark portal would read
 * as broken. Regenerate with the extraction script documented in the README if SFTPGo
 * ships a new Metronic build.
 */
[data-bs-theme='dark'] {
  --bs-blue: #0d6efd;
  --bs-indigo: #6610f2;
  --bs-purple: #6f42c1;
  --bs-pink: #d63384;
  --bs-red: #dc3545;
  --bs-orange: #fd7e14;
  --bs-yellow: #ffc107;
  --bs-green: #198754;
  --bs-teal: #20c997;
  --bs-cyan: #0dcaf0;
  --bs-black: #000000;
  --bs-white: #ffffff;
  --bs-gray: #78829D;
  --bs-gray-dark: #252F4A;
  --bs-gray-100: #F9F9F9;
  --bs-gray-200: #F1F1F4;
  --bs-gray-300: #DBDFE9;
  --bs-gray-400: #C4CADA;
  --bs-gray-500: #6D6D97;
  --bs-gray-600: #78829D;
  --bs-gray-700: #4B5675;
  --bs-gray-800: #252F4A;
  --bs-gray-900: #071437;
  --bs-light: #F9F9F9;
  --bs-primary: #0069E0;
  --bs-secondary: #F1F1F4;
  --bs-success: #17C653;
  --bs-info: #7239EA;
  --bs-warning: #F6C000;
  --bs-danger: #F8285A;
  --bs-dark: #1E2129;
  --bs-light-rgb: 249,249,249;
  --bs-primary-rgb: 0,105,224;
  --bs-secondary-rgb: 241,241,244;
  --bs-success-rgb: 23,198,83;
  --bs-info-rgb: 114,57,234;
  --bs-warning-rgb: 246,192,0;
  --bs-danger-rgb: 248,40,90;
  --bs-dark-rgb: 30,33,41;
  --bs-primary-text-emphasis: #002a5a;
  --bs-secondary-text-emphasis: #606062;
  --bs-success-text-emphasis: #094f21;
  --bs-info-text-emphasis: #2e175e;
  --bs-warning-text-emphasis: #624d00;
  --bs-danger-text-emphasis: #631024;
  --bs-light-text-emphasis: #4B5675;
  --bs-dark-text-emphasis: #4B5675;
  --bs-primary-bg-subtle: #cce1f9;
  --bs-secondary-bg-subtle: #fcfcfd;
  --bs-success-bg-subtle: #d1f4dd;
  --bs-info-bg-subtle: #e3d7fb;
  --bs-warning-bg-subtle: #fdf2cc;
  --bs-danger-bg-subtle: #fed4de;
  --bs-light-bg-subtle: #fcfcfc;
  --bs-dark-bg-subtle: #C4CADA;
  --bs-primary-border-subtle: #99c3f3;
  --bs-secondary-border-subtle: #f9f9fb;
  --bs-success-border-subtle: #a2e8ba;
  --bs-info-border-subtle: #c7b0f7;
  --bs-warning-border-subtle: #fbe699;
  --bs-danger-border-subtle: #fca9bd;
  --bs-light-border-subtle: #F1F1F4;
  --bs-dark-border-subtle: #6D6D97;
  --bs-white-rgb: 255,255,255;
  --bs-black-rgb: 0,0,0;
  --bs-font-sans-serif: Inter,Helvetica,"sans-serif";
  --bs-font-monospace: SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;
  --bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
  --bs-body-font-family: var(--bs-font-sans-serif);
  --bs-body-font-size: 1rem;
  --bs-body-font-weight: 400;
  --bs-body-line-height: 1.5;
  --bs-body-color: #071437;
  --bs-body-color-rgb: 7,20,55;
  --bs-body-bg: #ffffff;
  --bs-body-bg-rgb: 255,255,255;
  --bs-emphasis-color: #000000;
  --bs-emphasis-color-rgb: 0,0,0;
  --bs-secondary-color: rgba(7, 20, 55, 0.75);
  --bs-secondary-color-rgb: 7,20,55;
  --bs-secondary-bg: #F1F1F4;
  --bs-secondary-bg-rgb: 241,241,244;
  --bs-tertiary-color: rgba(7, 20, 55, 0.5);
  --bs-tertiary-color-rgb: 7,20,55;
  --bs-tertiary-bg: #F9F9F9;
  --bs-tertiary-bg-rgb: 249,249,249;
  --bs-heading-color: #071437;
  --bs-link-color: #0069E0;
  --bs-link-color-rgb: 0,105,224;
  --bs-link-decoration: none;
  --bs-link-hover-color: #056EE9;
  --bs-link-hover-color-rgb: 5,110,233;
  --bs-link-hover-decoration: none;
  --bs-code-color: #b93993;
  --bs-highlight-color: #071437;
  --bs-highlight-bg: #fff3cd;
  --bs-border-width: 1px;
  --bs-border-style: solid;
  --bs-border-color: #F1F1F4;
  --bs-border-color-translucent: rgba(0, 0, 0, 0.175);
  --bs-border-radius: 0.475rem;
  --bs-border-radius-sm: 0.425rem;
  --bs-border-radius-lg: 0.625rem;
  --bs-border-radius-xl: 1rem;
  --bs-border-radius-xxl: 2rem;
  --bs-border-radius-2xl: var(--bs-border-radius-xxl);
  --bs-border-radius-pill: 50rem;
  --bs-box-shadow: 0 0.5rem 1.5rem 0.5rem rgba(0, 0, 0, 0.075);
  --bs-box-shadow-sm: 0 0.1rem 1rem 0.25rem rgba(0, 0, 0, 0.05);
  --bs-box-shadow-lg: 0 1rem 2rem 1rem rgba(0, 0, 0, 0.1);
  --bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075);
  --bs-focus-ring-width: 0.25rem;
  --bs-focus-ring-opacity: 0.25;
  --bs-focus-ring-color: rgba(0, 105, 224, 0.25);
  --bs-form-valid-color: #17C653;
  --bs-form-valid-border-color: #17C653;
  --bs-form-invalid-color: #F8285A;
  --bs-form-invalid-border-color: #F8285A;
  --bs-carousel-indicator-active-bg: #ffffff;
  --bs-carousel-caption-color: #ffffff;
  --bs-text-muted: #6D6D97;
  --bs-gray-100-rgb: 249,249,249;
  --bs-gray-200-rgb: 241,241,244;
  --bs-gray-300-rgb: 219,223,233;
  --bs-gray-400-rgb: 196,202,218;
  --bs-gray-500-rgb: 109,109,151;
  --bs-gray-600-rgb: 120,130,157;
  --bs-gray-700-rgb: 75,86,117;
  --bs-gray-800-rgb: 37,47,74;
  --bs-gray-900-rgb: 7,20,55;
  --bs-primary-active: #056EE9;
  --bs-secondary-active: #C4CADA;
  --bs-light-active: #F1F1F4;
  --bs-success-active: #04B440;
  --bs-info-active: #5014D0;
  --bs-warning-active: #DEAD00;
  --bs-danger-active: #D81A48;
  --bs-dark-active: #111318;
  --bs-primary-light: #E9F3FF;
  --bs-secondary-light: #F9F9F9;
  --bs-success-light: #DFFFEA;
  --bs-info-light: #F8F5FF;
  --bs-warning-light: #FFF8DD;
  --bs-danger-light: #FFEEF3;
  --bs-dark-light: #F9F9F9;
  --bs-light-light: #ffffff;
  --bs-primary-inverse: #ffffff;
  --bs-secondary-inverse: #252F4A;
  --bs-light-inverse: #252F4A;
  --bs-success-inverse: #ffffff;
  --bs-info-inverse: #ffffff;
  --bs-warning-inverse: #ffffff;
  --bs-danger-inverse: #ffffff;
  --bs-dark-inverse: #ffffff;
  --bs-primary-clarity: rgba(0, 105, 224, 0.2);
  --bs-secondary-clarity: rgba(249, 249, 249, 0.2);
  --bs-success-clarity: rgba(23, 198, 83, 0.2);
  --bs-info-clarity: rgba(114, 57, 234, 0.2);
  --bs-warning-clarity: rgba(246, 192, 0, 0.2);
  --bs-danger-clarity: rgba(248, 40, 90, 0.2);
  --bs-dark-clarity: rgba(30, 33, 41, 0.2);
  --bs-light-clarity: rgba(255, 255, 255, 0.2);
  --bs-text-white: #ffffff;
  --bs-text-primary: #0069E0;
  --bs-text-secondary: #F1F1F4;
  --bs-text-light: #F9F9F9;
  --bs-text-success: #17C653;
  --bs-text-info: #7239EA;
  --bs-text-warning: #F6C000;
  --bs-text-danger: #F8285A;
  --bs-text-dark: #1E2129;
  --bs-text-gray-100: #F9F9F9;
  --bs-text-gray-200: #F1F1F4;
  --bs-text-gray-300: #DBDFE9;
  --bs-text-gray-400: #C4CADA;
  --bs-text-gray-500: #6D6D97;
  --bs-text-gray-600: #78829D;
  --bs-text-gray-700: #4B5675;
  --bs-text-gray-800: #252F4A;
  --bs-text-gray-900: #071437;
  --bs-border-dashed-color: #DBDFE9;
  --bs-component-active-color: #ffffff;
  --bs-component-active-bg: #0069E0;
  --bs-component-hover-color: #0069E0;
  --bs-component-hover-bg: #F9F9F9;
  --bs-component-checked-color: #ffffff;
  --bs-component-checked-bg: #0069E0;
  --bs-box-shadow-xs: 0 0.1rem 0.75rem 0.25rem rgba(0, 0, 0, 0.05);
  --bs-input-bg: var(--bs-body-bg);
  --bs-input-color: var(--bs-gray-700);
  --bs-input-solid-color: var(--bs-gray-700);
  --bs-input-solid-bg: var(--bs-gray-100);
  --bs-input-solid-bg-focus: var(--bs-gray-200);
  --bs-input-solid-placeholder-color: var(--bs-gray-500);
  --bs-root-card-box-shadow: 0px 3px 4px 0px rgba(0, 0, 0, 0.03);
  --bs-root-card-border-color: #F1F1F4;
  --bs-tooltip-box-shadow: 0px 0px 30px rgba(0, 0, 0, 0.15);
  --bs-table-striped-bg: rgba(var(--bs-gray-100-rgb), 0.75);
  --bs-table-loading-message-box-shadow: 0px 0px 50px 0px rgba(82, 63, 105, 0.15);
  --bs-dropdown-bg: var(--bs-body-bg);
  --bs-dropdown-box-shadow: 0px 0px 50px 0px rgba(82, 63, 105, 0.15);
  --bs-code-bg: #f1f3f8;
  --bs-code-shadow: 0px 3px 9px rgba(0, 0, 0, 0.08);
  --bs-code-border-color: transparent;
  --bs-symbol-label-color: var(--bs-gray-800);
  --bs-symbol-label-bg: var(--bs-gray-100);
  --bs-symbol-border-color: rgba(var(--bs-body-bg), 0.5);
  --bs-bullet-bg-color: var(--bs-gray-400);
  --bs-scrolltop-opacity: 0;
  --bs-scrolltop-opacity-on: 0.3;
  --bs-scrolltop-opacity-hover: 1;
  --bs-scrolltop-box-shadow: var(--bs-box-shadow);
  --bs-scrolltop-bg-color: var(--bs-primary);
  --bs-scrolltop-bg-color-hover: var(--bs-primary);
  --bs-scrolltop-icon-color: var(--bs-primary-inverse);
  --bs-scrolltop-icon-color-hover: var(--bs-primary-inverse);
  --bs-drawer-box-shadow: 0px 1px 9px -3px rgba(0, 0, 0, 0.05);
  --bs-drawer-bg-color: #ffffff;
  --bs-drawer-overlay-bg-color: rgba(0, 0, 0, 0.2);
  --bs-menu-dropdown-box-shadow: 0px 0px 50px 0px rgba(82, 63, 105, 0.15);
  --bs-menu-dropdown-bg-color: var(--bs-body-bg);
  --bs-menu-heading-color: #6D6D97;
  --bs-menu-link-color-hover: #0069E0;
  --bs-menu-link-color-show: #0069E0;
  --bs-menu-link-color-here: #0069E0;
  --bs-menu-link-color-active: #0069E0;
  --bs-menu-link-bg-color-hover: #F9F9F9;
  --bs-menu-link-bg-color-show: #F9F9F9;
  --bs-menu-link-bg-color-here: #F9F9F9;
  --bs-menu-link-bg-color-active: #F9F9F9;
  --bs-scrollbar-color: #F1F1F4;
  --bs-scrollbar-hover-color: #DBDFE9;
  --bs-overlay-bg: rgba(0, 0, 0, 0.05);
  --bs-blockui-overlay-bg: rgba(0, 0, 0, 0.05);
  --bs-rating-color-default: #C4CADA;
  --bs-rating-color-active: #FFAD0F;
  --bs-ribbon-label-box-shadow: 0px -1px 5px 0px rgba(30, 33, 41, 0.1);
  --bs-ribbon-label-bg: #0069E0;
  --bs-ribbon-label-border-color: #00397a;
  --bs-ribbon-clip-bg: #1E2129;
  --bs-engage-btn-bg: #ffffff;
  --bs-engage-btn-box-shadow: 0px 0px 22px #E0E0E0;
  --bs-engage-btn-border-color: #E8E8E8;
  --bs-engage-btn-color: #252F4A;
  --bs-engage-btn-icon-color: #78829D;
  --bs-engage-btn-color-active: #252F4A;
  --bs-app-bg-color: #ffffff;
  --bs-app-blank-bg-color: #ffffff;
  --bs-app-header-base-bg-color: #ffffff;
  --bs-app-header-minimize-bg-color: rgba(255, 255, 255, 0.5);
  --bs-app-sidebar-base-bg-color: #0B0C10;
  --bs-app-sidebar-base-box-shadow: none;
}

/*
 * Tell palette. Listed against all three scopes so it lands on top of the
 * neutraliser above at equal specificity, winning on document order — this is what
 * makes the brand colours survive a visitor whose OS is in dark mode.
 *
 * Note --bs-app-sidebar-base-bg-color: Metronic ships #0B0C10 even in its light
 * theme, so the sidebar is deliberately dark by design. Turning it white means its
 * menu colours have to be re-derived too; see the Sidebar section at the bottom.
 */
:root,
[data-bs-theme='light'],
[data-bs-theme='dark'] {
  /* Brand */
  --tell-blue: #395da6;
  --tell-blue-dark: #1c458c;
  --tell-purple: #8037c7;
  --tell-tint: #d9e2ff;
  --tell-surface: #f4f3f9;
  --tell-page: #faf9ff;
  --tell-ink: #1a1b20;
  --tell-ink-soft: #434651;
  --tell-ink-muted: #747782;
  --tell-placeholder: #c4c6d2;
  --tell-line: #e8eaf0;
  --tell-gradient: linear-gradient(135deg, #395da6 0%, #8037c7 100%);

  /* Bootstrap primary */
  --bs-primary: #395da6;
  --bs-primary-rgb: 57, 93, 166;
  --bs-primary-active: #1c458c;
  --bs-primary-light: #d9e2ff;
  --bs-primary-inverse: #ffffff;
  --bs-primary-clarity: rgba(57, 93, 166, 0.2);
  --bs-primary-bg-subtle: #d9e2ff;
  --bs-primary-border-subtle: #b9c9ef;
  --bs-primary-text-emphasis: #203256;

  --bs-link-color: #1c458c;
  --bs-link-color-rgb: 28, 69, 140;
  --bs-link-hover-color: #395da6;
  --bs-link-hover-color-rgb: 57, 93, 166;

  /* Menu states. Metronic's defaults are built for a near-black surface: #1B1C22
     backgrounds with #1F87FF text, which on white gives a black slab on hover.
     These are the generic menu variables — they cover the header menu and the
     dropdowns. The sidebar does NOT read them for its text colour; see the Sidebar
     section at the bottom for why. It does read the two bg-color ones, because the
     background comes from the generic .menu-item .menu-link:hover rule. */
  --bs-menu-link-color-hover: #1c458c;
  --bs-menu-link-bg-color-hover: #eef2ff;
  --bs-menu-link-color-active: #1c458c;
  --bs-menu-link-bg-color-active: #d9e2ff;
  --bs-menu-link-color-here: #1c458c;
  --bs-menu-link-bg-color-here: #d9e2ff;
  --bs-menu-link-color-show: #1c458c;
  --bs-menu-link-bg-color-show: #eef2ff;

  /* Surfaces. body-bg stays white so cards, modals and .bg-body read as sheets
     of paper; the tinted page colour is applied to the shell separately below. */
  --bs-body-bg: #ffffff;
  --bs-card-bg: #ffffff;
  --bs-app-bg-color: #faf9ff;
  --bs-app-header-base-bg-color: #ffffff;
  --bs-app-sidebar-base-bg-color: #ffffff;

  /* Text */
  --bs-body-color: #1a1b20;
  --bs-body-color-rgb: 26, 27, 32;
  --bs-heading-color: #1a1b20;
  --bs-secondary-color: #434651;
  --bs-tertiary-color: #747782;
  --bs-border-color: #e8eaf0;

  /* The login h1 is <h1 class="text-gray-900">, and Metronic declares
     .text-gray-900 { color: var(--bs-text-gray-900) !important }. No selector can
     outrank that, so the variable is the only way in. Metronic ships #071437 for
     light and #F5F5F5 for dark — the latter would be invisible on our white login
     box. */
  --bs-text-gray-900: #1a1b20;
  --bs-gray-900: #1a1b20;

  /* Set alongside the body rule below: .app-blank reads this one directly, and
     [data-bs-theme='dark'] would otherwise paint the login page #151521. */
  --bs-app-blank-bg-color: #faf9ff;

  /* Feedback colours, taken from the app's error and success tokens. */
  --bs-danger: #ba1a1a;
  --bs-danger-rgb: 186, 26, 26;
  --bs-success: #22c55e;
  --bs-success-rgb: 34, 197, 94;

  /* Shape. The app leans on generous radii; Metronic ships 0.475rem. */
  --bs-border-radius: 0.9rem;
  --bs-border-radius-sm: 0.65rem;
  --bs-border-radius-lg: 1.25rem;
  --bs-border-radius-xl: 1.5rem;

  --bs-body-font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
}

/* The login and error pages use body.app-blank, which has no app shell to take
   --bs-app-bg-color, so the tinted background is set directly. */
body,
body.app-blank {
  background-color: var(--tell-page);
}

/* ─── Type ──────────────────────────────────────────────────────────────── */

h1,
h2,
h3,
.section-title,
.section-title-inner,
.modal-title {
  font-family: 'LexendDeca', 'Inter', sans-serif;
  font-weight: 800;
  color: var(--tell-ink);
  letter-spacing: -0.01em;
}

/* The login page prints Branding.ShortName in an h1 next to the logo. */
.app-blank h1 {
  font-size: 2.5rem;
  line-height: 1.1;
}

/* Field labels: LexendExa, uppercase, widely tracked — the app's fieldLabel. */
.form-label,
.form-check-label,
label.fs-6 {
  font-family: 'LexendExa', 'Inter', sans-serif;
  font-size: 0.66rem;
  font-weight: 600;
  color: var(--tell-ink-soft);
  letter-spacing: 0.24em;
  text-transform: uppercase;
}

/* ─── Inputs ────────────────────────────────────────────────────────────── */

.form-control,
.form-select {
  background-color: var(--tell-surface);
  border: 1.5px solid transparent;
  border-radius: 0.9rem;
  color: var(--tell-ink);
  padding-top: 0.8rem;
  padding-bottom: 0.8rem;
}

.form-control:focus,
.form-select:focus {
  background-color: #ffffff;
  border-color: var(--tell-blue);
  box-shadow: 0 0 0 4px rgba(57, 93, 166, 0.13);
  color: var(--tell-ink);
}

/* The login and admin forms use .form-control-solid, and Metronic styles its focus
   state at .form-control.form-control-solid:focus — two classes plus a pseudo-class,
   which outranks the .form-control:focus rule above. Matching that specificity and
   winning on document order is what actually turns the field white on focus. */
.form-control.form-control-solid {
  background-color: var(--tell-surface);
  border-color: transparent;
  color: var(--tell-ink);
}

.form-control.form-control-solid:focus,
.form-control.form-control-solid:active,
.form-control.form-control-solid.focus,
.form-control.form-control-solid.active {
  background-color: #ffffff;
  border-color: var(--tell-blue);
  box-shadow: 0 0 0 4px rgba(57, 93, 166, 0.13);
  color: var(--tell-ink);
}

.form-control::placeholder,
.form-control-solid::placeholder {
  color: var(--tell-placeholder);
}

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

/* ─── Buttons ───────────────────────────────────────────────────────────── */

/* Pill shape across the board, as in the app. */
.btn {
  border-radius: 9999px;
  font-weight: 500;
}

/* The signature gradient, plus the blue drop shadow the app puts under its
   primary action. background-image beats Metronic's background-color without
   needing !important. */
.btn.btn-primary,
.btn.btn-primary:active,
.btn.btn-primary:focus {
  background-image: var(--tell-gradient);
  background-color: var(--tell-blue);
  border-color: transparent;
  color: #ffffff;
  font-family: 'LexendExa', 'Inter', sans-serif;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  padding-top: 0.95rem;
  padding-bottom: 0.95rem;
  box-shadow: 0 10px 25px rgba(57, 93, 166, 0.25);
}

.btn.btn-primary:hover:not(:disabled):not(.disabled) {
  background-image: linear-gradient(135deg, #1c458c 0%, #7130b3 100%);
  box-shadow: 0 12px 28px rgba(57, 93, 166, 0.32);
  color: #ffffff;
}

.btn.btn-primary:disabled,
.btn.btn-primary.disabled {
  background-image: var(--tell-gradient);
  opacity: 0.55;
  box-shadow: none;
}

/* Secondary and cancel actions: outlined pill on the tint, per modalCancelButton. */
.btn.btn-light,
.btn.btn-secondary,
.btn.btn-active-light-primary {
  background-color: var(--tell-surface);
  border: 1.5px solid var(--tell-tint);
  color: var(--tell-ink-soft);
}

.btn.btn-light:hover,
.btn.btn-secondary:hover {
  background-color: var(--tell-tint);
  color: var(--tell-blue-dark);
}

/* ─── Containers ────────────────────────────────────────────────────────── */

.card {
  border: none;
  border-radius: 1.5rem;
  box-shadow: 0 2px 18px rgba(26, 27, 32, 0.06);
}

/* The login box is a plain div with .bg-body.rounded.shadow-sm, not a .card. */
.app-blank .bg-body.rounded {
  border-radius: 1.75rem !important;
  box-shadow: 0 18px 45px rgba(57, 93, 166, 0.12) !important;
}

.modal-content {
  border: none;
  border-radius: 1.75rem;
}

.app-header,
.app-sidebar {
  border-bottom: 1px solid var(--tell-line);
}

.app-sidebar {
  border-bottom: none;
  border-right: 1px solid var(--tell-line);
}

/* Table headers pick up the label treatment, lightly. */
.table thead th {
  font-family: 'LexendExa', 'Inter', sans-serif;
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--tell-ink-muted);
}

/* ─── Progress and feedback ─────────────────────────────────────────────── */

/* Upload progress is the most-watched element in a 1000-file batch. */
.progress {
  background-color: var(--tell-surface);
  border-radius: 9999px;
}

.progress-bar {
  background-image: var(--tell-gradient);
  background-color: var(--tell-blue);
}

.spinner-border,
.spinner-grow {
  color: var(--tell-blue);
}

.alert-primary,
.bg-light-primary {
  background-color: var(--tell-tint);
  color: var(--tell-blue-dark);
}

/* Drag-and-drop target in the file manager. */
.dropzone,
.dz-clickable {
  background-color: var(--tell-surface);
  border: 2px dashed var(--tell-tint);
  border-radius: 1.5rem;
}

/* ─── Navigation ────────────────────────────────────────────────────────── */

.nav-line-tabs .nav-item .nav-link.active {
  border-bottom-color: var(--tell-blue);
  color: var(--tell-blue-dark);
}

/* ─── Sidebar ───────────────────────────────────────────────────────────── */

/*
 * Metronic's sidebar is dark by design — --bs-app-sidebar-base-bg-color is #0B0C10
 * even in its light theme — so every colour it ships there is picked for contrast
 * against near-black. Turning the sidebar white (in the palette above) means all of
 * them have to be re-derived.
 *
 * The catch, and the reason this section is long: the .app-sidebar-navs block in
 * style.bundle.css does NOT use custom properties. It hardcodes hex. Resting text is
 * #dbdfe9, resting icons #78829d, and hover / .show / .here / .active are all plain
 * #fff. That is the whole bug: on a white sidebar #dbdfe9 is the barely-legible grey,
 * and #fff on hover is text that vanishes. No amount of --bs-menu-link-* overriding
 * reaches it.
 *
 * So the fix mirrors Metronic's selectors verbatim and only swaps the colour. Copying
 * them exactly is deliberate rather than lazy: it guarantees identical specificity —
 * the hover selector alone is ten classes deep — so the outcome rests on document
 * order, and extra_css is emitted last. Hand-tuned shorter selectors would be a
 * specificity bet re-lost on every Metronic bump.
 *
 * Backgrounds are the exception and still come from the palette's
 * --bs-menu-link-bg-color-* variables, because those are applied by the generic
 * .menu-item .menu-link:hover rule, which the sidebar block never overrides.
 */

/* Resting state. */
.app-sidebar-navs .menu .menu-item .menu-link,
.app-sidebar-navs .menu .menu-item .menu-link .menu-title {
  color: var(--tell-ink-soft);
}

.app-sidebar-navs .menu .menu-item .menu-link .menu-icon,
.app-sidebar-navs .menu .menu-item .menu-link .menu-icon .svg-icon,
.app-sidebar-navs .menu .menu-item .menu-link .menu-icon i {
  color: var(--tell-ink-muted);
}

.app-sidebar-navs .menu .menu-item .menu-link .menu-bullet .bullet {
  background-color: var(--tell-ink-muted);
}

/* Hover — the invisible-text case. */
.app-sidebar-navs .menu .menu-item.hover:not(.here) > .menu-link:not(.disabled):not(.active):not(.here),
.app-sidebar-navs .menu .menu-item:not(.here) .menu-link:hover:not(.disabled):not(.active):not(.here),
.app-sidebar-navs .menu .menu-item.hover:not(.here) > .menu-link:not(.disabled):not(.active):not(.here) .menu-title,
.app-sidebar-navs .menu .menu-item:not(.here) .menu-link:hover:not(.disabled):not(.active):not(.here) .menu-title {
  color: var(--tell-blue-dark);
}

.app-sidebar-navs .menu .menu-item.hover:not(.here) > .menu-link:not(.disabled):not(.active):not(.here) .menu-icon,
.app-sidebar-navs .menu .menu-item.hover:not(.here) > .menu-link:not(.disabled):not(.active):not(.here) .menu-icon .svg-icon,
.app-sidebar-navs .menu .menu-item.hover:not(.here) > .menu-link:not(.disabled):not(.active):not(.here) .menu-icon i,
.app-sidebar-navs .menu .menu-item:not(.here) .menu-link:hover:not(.disabled):not(.active):not(.here) .menu-icon,
.app-sidebar-navs .menu .menu-item:not(.here) .menu-link:hover:not(.disabled):not(.active):not(.here) .menu-icon .svg-icon,
.app-sidebar-navs .menu .menu-item:not(.here) .menu-link:hover:not(.disabled):not(.active):not(.here) .menu-icon i {
  color: var(--tell-blue);
}

/* Open submenu (.show) and the ancestor of the current page (.here). */
.app-sidebar-navs .menu .menu-item.show > .menu-link,
.app-sidebar-navs .menu .menu-item.show > .menu-link .menu-title,
.app-sidebar-navs .menu .menu-item.here > .menu-link,
.app-sidebar-navs .menu .menu-item.here > .menu-link .menu-title {
  color: var(--tell-blue-dark);
}

.app-sidebar-navs .menu .menu-item.show > .menu-link .menu-icon,
.app-sidebar-navs .menu .menu-item.show > .menu-link .menu-icon .svg-icon,
.app-sidebar-navs .menu .menu-item.show > .menu-link .menu-icon i,
.app-sidebar-navs .menu .menu-item.here > .menu-link .menu-icon,
.app-sidebar-navs .menu .menu-item.here > .menu-link .menu-icon .svg-icon,
.app-sidebar-navs .menu .menu-item.here > .menu-link .menu-icon i {
  color: var(--tell-blue);
}

/* Current page: Metronic's #15171c slab becomes the brand tint pill. */
.app-sidebar-navs .menu .menu-item .menu-link.active {
  background-color: var(--tell-tint);
  border-radius: 0.9rem;
  color: var(--tell-blue-dark);
}

.app-sidebar-navs .menu .menu-item .menu-link.active .menu-title {
  color: var(--tell-blue-dark);
  font-weight: 600;
}

/* The active icon needs the .menu-icon i tail to outrank the resting icon rule
   above, which Metronic writes at the same depth. */
.app-sidebar-navs .menu .menu-item .menu-link.active .menu-icon,
.app-sidebar-navs .menu .menu-item .menu-link.active .menu-icon .svg-icon,
.app-sidebar-navs .menu .menu-item .menu-link.active .menu-icon i {
  color: var(--tell-blue-dark);
}

/* Section headings and the collapse toggle at the bottom. Metronic marks the toggle
   !important, so this has to as well. */
.app-sidebar-navs .menu .menu-item .menu-heading {
  color: var(--tell-ink-muted);
  font-family: 'LexendExa', 'Inter', sans-serif;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.app-sidebar-navs .menu .menu-collapse-toggle .menu-title {
  color: var(--tell-ink-muted) !important;
}

/*
 * The portal name beside the logo. templates/common/base.html renders it as
 * <span class="text-sidebar"> and hardcodes color: var(--bs-white) in an inline
 * <style> — white text, invisible on a white sidebar. That style block is emitted
 * just before Branding.ExtraCSS, and its dark-mode form is
 * [data-bs-theme="dark"] .text-sidebar, so matching two compound selectors here is
 * enough to win on order in both themes.
 */
.app-sidebar .text-sidebar {
  color: var(--tell-ink);
  font-family: 'LexendDeca', 'Inter', sans-serif;
}

/* Now that the sidebar and the page are both white, they need a seam. */
.app-sidebar {
  border-right: 1px solid var(--tell-line);
}

.app-sidebar .separator {
  border-color: var(--tell-line);
}
