﻿/* ==========================================================================
   Konima Support — knm-theme.css
   Tema admin per Bootstrap 5.3+
   · Tutte le variabili custom usano il prefisso  --knm-theme-*
   · Tutte le classi di estensione/override usano il prefisso  .knm-t-*
   · Modalità chiaro/scuro via [data-bs-theme="light|dark"]
   · Colore accento via [data-knm-accent="orange|blue|teal|violet|green"]
   · Densità: i livelli sono della libreria (KNM.RazorComponents #319, token --knm-density-*); questo file
     dà solo i valori di Tickets per livello e i token del template --knm-theme-gap/-card-pad/-cell-pad-*
   · Dimensione testo via --knm-theme-font-size (impostata su <html>)
   ========================================================================== */

/* --------------------------------------------------------------------------
   1 · TOKEN DI BASE (tipografia, geometrie, densità)
   -------------------------------------------------------------------------- */
:root {
  /* Tipografia */
  --knm-theme-font-size: 16px;
  --knm-theme-font-body: "Manrope", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --knm-theme-font-display: "Sora", var(--knm-theme-font-body);
  --knm-theme-font-mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;

  /* Geometrie */
  --knm-theme-radius: 12px;
  --knm-theme-radius-sm: 8px;
  --knm-theme-sidebar-w: 264px;
  --knm-theme-topbar-h: 60px;

  /* KNM.RazorComponents KNMDataGrid: every grid's .WithStickyHeader() pins its <thead> at `top: 0`.
     .knm-t-topbar below is ALSO position:sticky/top:0 but at z-index 1020 vs the grid header's z-index 2,
     so without an offset the topbar paints over the grid header during scroll. Derived from
     --knm-theme-topbar-h (not a separate literal) so the two cannot drift apart. */
  --knm-grid-sticky-offset: var(--knm-theme-topbar-h);

  /* Accento — default: arancio */
  --knm-theme-accent: #ea580c;
  --knm-theme-accent-rgb: 234, 88, 12;
  --knm-theme-accent-hover: color-mix(in oklab, var(--knm-theme-accent), #000 14%);
  --knm-theme-accent-soft: color-mix(in oklab, var(--knm-theme-accent), transparent 90%);
  --knm-theme-accent-border: color-mix(in oklab, var(--knm-theme-accent), transparent 65%);
  --knm-theme-accent-contrast: #fff;
  /* Opaque, low-chroma wash of the accent — the "off" half of a two-state control (a switch's track, an idle
     rail) where --knm-theme-accent-soft is too transparent to read as a filled shape. Defined per surface
     polarity in section 2: on a light ground it is the accent lightened, on a dark one the accent darkened.
     Declared here as a fallback so the token always resolves even before section 2 is reached. */
  --knm-theme-accent-muted: color-mix(in oklab, var(--knm-theme-accent), #fff 62%);
}

/* Densità (ui-density-adoption, KNM.RazorComponents #319). The levels, the tokens and the size of every Auto control
   are the library's; these four rules only give Tickets' values per level (once, nowhere else: DensityEngineGuardTests)
   and the template's own spacing. Normal = today's Tickets look; compact and airy = Tickets' values where it had
   them, the library's otherwise. Buttons shift one step (Corrado, 16/10): normal = today's Small, airy = today's
   Medium at airy. The normal rule names [data-knm-density="normal"] too: the router's scope can be at normal inside an
   <html> painted at another level, and a value declared on :root alone would reach it inherited from <html>.
   No --knm-density-control-font-size at normal (the library's 1rem), 1rem at the other two: the text size is the
   person's own slider, density changes spacing, never type. No chip token: the library's chips take their size from
   the size map (DensityRegistration), not from --knm-density-chip-*. */
:root, [data-knm-density="normal"] {
  --knm-density-btn-padding-y: .27rem;          /* .btn-sm normal (.45 × .6) */
  --knm-density-btn-padding-x: .75rem;          /* .btn-sm normal */
  --knm-density-btn-font-size: .8125rem;        /* .btn-sm */
  --knm-density-card-spacer-y: 1.25rem;         /* today's card padding */
  --knm-density-card-spacer-x: 1.25rem;
  --knm-density-control-padding-y: .45rem;      /* today's field padding */
  --knm-density-control-padding-x: .75rem;
  --knm-theme-gap: 1.25rem;
  --knm-theme-cell-pad-y: .7rem;                /* .knm-t-table only */
  --knm-theme-cell-pad-x: .75rem;
}
[data-knm-density="compact"] {
  --knm-density-btn-padding-y: .192rem;         /* .btn-sm compact (.32 × .6) */
  --knm-density-btn-padding-x: .6rem;
  --knm-density-btn-font-size: .8125rem;
  --knm-density-card-spacer-y: .9rem;
  --knm-density-card-spacer-x: .9rem;
  --knm-density-control-padding-y: .32rem;
  --knm-density-control-padding-x: .6rem;
  --knm-density-control-font-size: 1rem;
  --knm-density-row-height: 2.125rem;           /* 34px, walk-fixes-1016 */
  --knm-density-cell-padding-y: .3rem;
  --knm-density-cell-padding-x: .6rem;
  --knm-theme-gap: .8rem;
  --knm-theme-cell-pad-y: .42rem;
  --knm-theme-cell-pad-x: .6rem;
}
[data-knm-density="airy"] {
  --knm-density-btn-padding-y: .6rem;           /* .btn airy */
  --knm-density-btn-padding-x: 1.08rem;         /* .btn airy (.9 × 1.2) */
  --knm-density-btn-font-size: .875rem;         /* .btn */
  --knm-density-card-spacer-y: 1.75rem;
  --knm-density-card-spacer-x: 1.75rem;
  --knm-density-control-padding-y: .6rem;
  --knm-density-control-padding-x: .9rem;
  --knm-density-control-font-size: 1rem;
  --knm-density-row-height: 3.25rem;            /* 52px, walk-fixes-1016 */
  --knm-density-cell-padding-y: .8rem;
  --knm-density-cell-padding-x: 1rem;
  --knm-theme-gap: 1.75rem;
  --knm-theme-cell-pad-y: 1rem;
  --knm-theme-cell-pad-x: 1rem;
}
/* One number for KNMCard and the template's .knm-t-card-pad; re-declared on every element that carries a level, because
   a var() is resolved where it is declared. */
:root, [data-knm-density] {
  --knm-theme-card-pad: var(--knm-density-card-spacer-y);
}

/* Preset colore accento */
[data-knm-accent="blue"]   { --knm-theme-accent: #2563eb; --knm-theme-accent-rgb: 37, 99, 235; }
[data-knm-accent="teal"]   { --knm-theme-accent: #0d9488; --knm-theme-accent-rgb: 13, 148, 136; }
[data-knm-accent="violet"] { --knm-theme-accent: #7c3aed; --knm-theme-accent-rgb: 124, 58, 237; }
[data-knm-accent="green"]  { --knm-theme-accent: #16a34a; --knm-theme-accent-rgb: 22, 163, 74; }

/* --------------------------------------------------------------------------
   2 · SUPERFICI — modalità chiara e scura
   -------------------------------------------------------------------------- */
:root,
[data-bs-theme="light"] {
  --knm-theme-bg: #f6f5f3;
  --knm-theme-surface: #ffffff;
  --knm-theme-surface-2: #f1efec;
  --knm-theme-border: #e7e4df;
  --knm-theme-border-strong: #d7d3cc;
  --knm-theme-text: #1d1b18;
  --knm-theme-text-muted: #74706a;
  --knm-theme-shadow: 0 1px 2px rgb(28 25 20 / .05), 0 4px 14px rgb(28 25 20 / .04);
  --knm-theme-sidebar-bg: #171511;
  --knm-theme-sidebar-border: #2b2823;
  --knm-theme-sidebar-text: #b9b4ac;
  --knm-theme-sidebar-heading: #7c776e;
  --knm-theme-accent-muted: color-mix(in oklab, var(--knm-theme-accent), #fff 62%);
}
[data-bs-theme="dark"] {
  --knm-theme-bg: #121110;
  --knm-theme-surface: #1b1917;
  --knm-theme-surface-2: #242220;
  --knm-theme-border: #2d2a27;
  --knm-theme-border-strong: #3b3733;
  --knm-theme-text: #edeae6;
  --knm-theme-text-muted: #99948d;
  --knm-theme-shadow: 0 1px 2px rgb(0 0 0 / .35), 0 4px 14px rgb(0 0 0 / .25);
  --knm-theme-sidebar-bg: #0e0d0b;
  --knm-theme-sidebar-border: #262420;
  --knm-theme-sidebar-text: #aaa59d;
  --knm-theme-sidebar-heading: #6e6961;
  /* Darkened, not lightened: on the dark surfaces above, the light-mode wash would out-glare the ACTIVE state
     it is supposed to sit under. */
  --knm-theme-accent-muted: color-mix(in oklab, var(--knm-theme-accent), #000 52%);
}

/* --------------------------------------------------------------------------
   3 · MAPPATURA SU BOOTSTRAP
   -------------------------------------------------------------------------- */
:root,
[data-bs-theme="light"],
[data-bs-theme="dark"] {
  --bs-body-bg: var(--knm-theme-bg);
  --bs-body-color: var(--knm-theme-text);
  --bs-border-color: var(--knm-theme-border);
  --bs-secondary-color: var(--knm-theme-text-muted);
  --bs-secondary-bg: var(--knm-theme-surface-2);
  --bs-tertiary-bg: var(--knm-theme-surface-2);
  --bs-emphasis-color: var(--knm-theme-text);
  --bs-primary: var(--knm-theme-accent);
  --bs-primary-rgb: var(--knm-theme-accent-rgb);
  --bs-link-color: var(--knm-theme-accent);
  --bs-link-hover-color: var(--knm-theme-accent-hover);
  --bs-link-color-rgb: var(--knm-theme-accent-rgb);
  --bs-link-hover-color-rgb: var(--knm-theme-accent-rgb);
  --bs-body-font-family: var(--knm-theme-font-body);
  --bs-border-radius: var(--knm-theme-radius-sm);
}

html { font-size: var(--knm-theme-font-size, 16px); }

body {
  font-family: var(--knm-theme-font-body);
  background-color: var(--knm-theme-bg);
  color: var(--knm-theme-text);
  font-size: .9375rem;
  letter-spacing: .005em;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, h6, .knm-t-display {
  font-family: var(--knm-theme-font-display);
  letter-spacing: -.015em;
}

/* Pulsanti */
/* Sizes go through Bootstrap's variables, never padding/font-size directly: .btn-sm and .btn-lg only change
   the variables, so a direct value would make them do nothing (issue #161).
   ui-density-adoption: an Auto KNMButton takes the --knm-density-btn-* tokens through the library's adapter at compact
   and airy (0,2,0, it beats these two), and at normal its size map gives it .btn-sm. .btn follows the level through the
   library's control token (plain class="btn" elements, an explicit Medium); an explicit Small stays Small at every
   level (the library's contract), so .btn-sm is fixed. */
.btn {
  --bs-btn-border-radius: var(--knm-theme-radius-sm);
  --bs-btn-font-weight: 600;
  --bs-btn-font-size: .875rem;
  --bs-btn-padding-y: var(--knm-density-control-padding-y);
  --bs-btn-padding-x: calc(var(--knm-density-control-padding-x) * 1.2);
}
.btn-sm {
  --bs-btn-font-size: .8125rem;
  --bs-btn-padding-y: .27rem;
  --bs-btn-padding-x: .75rem;
}
.btn-primary {
  --bs-btn-bg: var(--knm-theme-accent);
  --bs-btn-border-color: var(--knm-theme-accent);
  --bs-btn-color: var(--knm-theme-accent-contrast);
  --bs-btn-hover-bg: var(--knm-theme-accent-hover);
  --bs-btn-hover-border-color: var(--knm-theme-accent-hover);
  --bs-btn-hover-color: var(--knm-theme-accent-contrast);
  --bs-btn-active-bg: var(--knm-theme-accent-hover);
  --bs-btn-active-border-color: var(--knm-theme-accent-hover);
  --bs-btn-active-color: var(--knm-theme-accent-contrast);
  --bs-btn-disabled-bg: var(--knm-theme-accent);
  --bs-btn-disabled-border-color: var(--knm-theme-accent);
  --bs-btn-focus-shadow-rgb: var(--knm-theme-accent-rgb);
}
.btn-outline-primary {
  --bs-btn-color: var(--knm-theme-accent);
  --bs-btn-border-color: var(--knm-theme-accent-border);
  --bs-btn-hover-bg: var(--knm-theme-accent-soft);
  --bs-btn-hover-color: var(--knm-theme-accent);
  --bs-btn-hover-border-color: var(--knm-theme-accent);
  --bs-btn-active-bg: var(--knm-theme-accent);
  --bs-btn-active-border-color: var(--knm-theme-accent);
  --bs-btn-focus-shadow-rgb: var(--knm-theme-accent-rgb);
}
.btn-outline-secondary {
  --bs-btn-color: var(--knm-theme-text);
  --bs-btn-bg: var(--knm-theme-surface);
  --bs-btn-border-color: var(--knm-theme-border-strong);
  --bs-btn-hover-bg: var(--knm-theme-surface-2);
  --bs-btn-hover-color: var(--knm-theme-text);
  --bs-btn-hover-border-color: var(--knm-theme-border-strong);
  --bs-btn-active-bg: var(--knm-theme-surface-2);
  --bs-btn-active-color: var(--knm-theme-text);
  --bs-btn-active-border-color: var(--knm-theme-border-strong);
}
/* Variante "soft" sull'accento */
.knm-t-btn-soft {
  background: var(--knm-theme-accent-soft);
  color: var(--knm-theme-accent);
  border: 1px solid transparent;
}
.knm-t-btn-soft:hover {
  background: color-mix(in oklab, var(--knm-theme-accent), transparent 82%);
  color: var(--knm-theme-accent-hover);
}

/* Form */
.form-label { font-size: .8125rem; font-weight: 700; margin-bottom: .35rem; }
.form-text { color: var(--knm-theme-text-muted); font-size: .78rem; }
.form-control, .form-select {
  background-color: var(--knm-theme-surface);
  border-color: var(--knm-theme-border-strong);
  border-radius: var(--knm-theme-radius-sm);
  color: var(--knm-theme-text);
  font-size: .9rem;
  padding: var(--knm-density-control-padding-y) var(--knm-density-control-padding-x);
}
.form-control::placeholder { color: var(--knm-theme-text-muted); opacity: .8; }
.form-control:focus, .form-select:focus {
  background-color: var(--knm-theme-surface);
  color: var(--knm-theme-text);
  border-color: var(--knm-theme-accent);
  box-shadow: 0 0 0 3px var(--knm-theme-accent-soft);
}
.form-check-input:checked {
  background-color: var(--knm-theme-accent);
  border-color: var(--knm-theme-accent);
}
.form-check-input:focus {
  border-color: var(--knm-theme-accent);
  box-shadow: 0 0 0 3px var(--knm-theme-accent-soft);
}
.form-range::-webkit-slider-thumb { background: var(--knm-theme-accent); }
.form-range::-moz-range-thumb { background: var(--knm-theme-accent); }

/* Dropdown — since KNM.RazorComponents 3.19 the panels of KNMSelect, KNMMenu and the grid column chooser
   carry .knm-dropdown-panel instead of Bootstrap's .dropdown-menu, so both are themed here. */
.dropdown-menu,
.knm-dropdown-panel {
  --bs-dropdown-bg: var(--knm-theme-surface);
  --bs-dropdown-border-color: var(--knm-theme-border);
  --bs-dropdown-link-color: var(--knm-theme-text);
  --bs-dropdown-link-hover-bg: var(--knm-theme-surface-2);
  --bs-dropdown-link-hover-color: var(--knm-theme-text);
  --bs-dropdown-link-active-bg: var(--knm-theme-accent);
  border-radius: 10px;
  box-shadow: var(--knm-theme-shadow);
  font-size: .875rem;
  padding: .35rem;
}
.dropdown-item { border-radius: 7px; padding: .4rem .6rem; }
/* 3.19 dropped its fade-in from Bootstrap's own menus (the user menu): kept here with the same timing. */
.dropdown-menu.show { animation: knm-t-menu-fade-in .15s ease; }
@keyframes knm-t-menu-fade-in { from { opacity: 0; transform: scale(.95); } to { opacity: 1; transform: scale(1); } }

/* Paginazione */
.pagination {
  --bs-pagination-bg: var(--knm-theme-surface);
  --bs-pagination-color: var(--knm-theme-text-muted);
  --bs-pagination-border-color: var(--knm-theme-border);
  --bs-pagination-hover-bg: var(--knm-theme-surface-2);
  --bs-pagination-hover-color: var(--knm-theme-text);
  --bs-pagination-hover-border-color: var(--knm-theme-border);
  --bs-pagination-focus-bg: var(--knm-theme-surface-2);
  --bs-pagination-focus-color: var(--knm-theme-text);
  --bs-pagination-active-bg: var(--knm-theme-accent);
  --bs-pagination-active-border-color: var(--knm-theme-accent);
  --bs-pagination-disabled-bg: var(--knm-theme-surface);
  --bs-pagination-disabled-color: var(--knm-theme-border-strong);
  --bs-pagination-disabled-border-color: var(--knm-theme-border);
  --bs-pagination-focus-box-shadow: 0 0 0 3px var(--knm-theme-accent-soft);
}
.page-link { font-size: .85rem; font-weight: 600; }

/* Offcanvas */
.offcanvas {
  --bs-offcanvas-bg: var(--knm-theme-surface);
  --bs-offcanvas-color: var(--knm-theme-text);
  --bs-offcanvas-border-color: var(--knm-theme-border);
}

/* --------------------------------------------------------------------------
   4 · LAYOUT APPLICATIVO
   -------------------------------------------------------------------------- */
.knm-t-app { display: flex; min-height: 100vh; }
.knm-t-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
/* The content column of the shell. TWO mechanisms live here and NEITHER replaces the other — do not delete
   one believing the other covers it:

   1. Bootstrap's .container-fluid (carried by <main> in MainLayout.razor) owns the WIDTH and the HORIZONTAL
      padding. It reads --bs-gutter-x, set here to twice the theme step so the shell keeps its own rhythm
      instead of Bootstrap's 1.5rem default (.container-fluid applies gutter-x * .5 per side).
   2. `flex: 1 0 auto` owns the HEIGHT. .knm-t-main is a flex column of header / main / footer; without a
      grow factor <main> is sized to its content, so on a short page the content box stops early and the
      remaining column height belongs to nobody. Bootstrap's container classes govern width, never height —
      adopting them does not make this line redundant.

   align-content is pinned to `start` BECAUSE of (2): this is also a grid container (.knm-t-grid) whose rows
   are implicit and auto-sized, and the initial `align-content: normal` behaves as `stretch` for grid. Once
   <main> is taller than its content, stretch would inflate a single card to the full viewport height. */
.knm-t-content {
  --bs-gutter-x: calc(var(--knm-theme-gap) * 2.6);
  flex: 1 0 auto;
  align-content: start;
  padding-top: calc(var(--knm-theme-gap) * 1.3);
  padding-bottom: calc(var(--knm-theme-gap) * 1.3);
}
/* .knm-t-content is a grid container (.knm-t-grid, below) with a single implicit auto-sized column.
   Per the CSS Grid spec, a grid item's automatic minimum size defaults to min-width: auto — i.e. its
   min-content size — which lets an unshrinkable child (e.g. a wide, non-wrapping data grid table) blow
   out the track and overflow the shell instead of shrinking with the viewport. Scoped to direct children
   of .knm-t-content only, so it does not touch .knm-t-card (or anything else) nested elsewhere — e.g.
   inside .knm-t-cols-* columns or flex rows — where the default min-content floor is not a problem. */
.knm-t-content > * { min-width: 0; }

.knm-t-grid { display: grid; gap: var(--knm-theme-gap); }
.knm-t-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.knm-t-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.knm-t-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.knm-t-cols-main { grid-template-columns: minmax(0, 2.1fr) minmax(0, 1fr); }
.knm-t-cols-detail { grid-template-columns: minmax(0, 1fr) 340px; }
.knm-t-cols-settings { grid-template-columns: 230px minmax(0, 1fr); align-items: start; }
@media (max-width: 1199.98px) {
  .knm-t-cols-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .knm-t-cols-main, .knm-t-cols-detail { grid-template-columns: 1fr; }
}
@media (max-width: 767.98px) {
  .knm-t-cols-4, .knm-t-cols-3, .knm-t-cols-2, .knm-t-cols-settings { grid-template-columns: 1fr; }
}

/* --------------------------------------------------------------------------
   5 · SIDEBAR (scura)
   -------------------------------------------------------------------------- */
.knm-t-sidebar {
  background-color: var(--knm-theme-sidebar-bg) !important;
  color: var(--knm-theme-sidebar-text);
  display: flex;
  flex-direction: column;
  border-right: 1px solid var(--knm-theme-sidebar-border);
}
@media (min-width: 992px) {
  .knm-t-sidebar {
    width: var(--knm-theme-sidebar-w) !important;
    flex: 0 0 var(--knm-theme-sidebar-w);
    position: sticky;
    top: 0;
    height: 100vh;
  }
}
@media (max-width: 991.98px) {
  .knm-t-sidebar { --bs-offcanvas-width: var(--knm-theme-sidebar-w); }
}
.knm-t-sidebar-brand {
  display: flex;
  align-items: center;
  gap: .7rem;
  padding: 1rem 1.15rem;
  border-bottom: 1px solid var(--knm-theme-sidebar-border);
  color: #fff;
  font-family: var(--knm-theme-font-display);
  font-weight: 600;
  font-size: .95rem;
  letter-spacing: -.01em;
  min-height: var(--knm-theme-topbar-h);
}
.knm-t-sidebar-brand em { font-style: normal; font-weight: 400; color: var(--knm-theme-sidebar-text); }
/* The brand mark (BrandLogo): always an image, the organization's logo or the product icon (CTO 27/10/2026). */
.knm-t-logo {
  width: 30px; height: 30px;
  border-radius: 9px;
  display: inline-flex; align-items: center; justify-content: center;
  overflow: hidden;
  flex-shrink: 0;
}
.knm-t-sidebar-nav {
  flex: 1;
  overflow-y: auto;
  padding: .9rem .8rem;
  display: flex;
  flex-direction: column;
  gap: 2px;
  /* Scroll stays functional, but the scrollbar is hidden (Firefox + legacy Edge). */
  scrollbar-width: none;
  -ms-overflow-style: none;
}
/* WebKit/Blink (Chrome, Edge, Safari): hide the sidebar-nav scrollbar too. */
.knm-t-sidebar-nav::-webkit-scrollbar { width: 0; height: 0; display: none; }
.knm-t-nav-section {
  font-size: .67rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .11em;
  color: var(--knm-theme-sidebar-heading);
  padding: .95rem .75rem .4rem;
}
.knm-t-navlink {
  position: relative;
  display: flex;
  align-items: center;
  gap: .7rem;
  padding: .48rem .75rem;
  border-radius: 8px;
  font-size: .875rem;
  font-weight: 600;
  color: var(--knm-theme-sidebar-text);
  text-decoration: none;
  background: none;
  border: 0;
  width: 100%;
  text-align: left;
}
.knm-t-navlink i { font-size: 1rem; width: 1.15rem; text-align: center; opacity: .9; }
.knm-t-navlink:hover { color: #fff; background: rgb(255 255 255 / .05); }
.knm-t-navlink.active { color: #fff; background: rgb(255 255 255 / .07); }
.knm-t-navlink.active::before {
  content: "";
  position: absolute;
  left: -8px;
  top: 22%;
  bottom: 22%;
  width: 3px;
  border-radius: 99px;
  background: var(--knm-theme-accent);
}
.knm-t-navlink.active i { color: var(--knm-theme-accent); opacity: 1; }
.knm-t-sidebar-footer {
  padding: .8rem;
  border-top: 1px solid var(--knm-theme-sidebar-border);
  display: flex;
  flex-direction: column;
  gap: .35rem;
}
.knm-t-sidebar-user {
  display: flex;
  align-items: center;
  gap: .65rem;
  padding: .4rem .45rem;
  border-radius: 8px;
}
.knm-t-sidebar-user-name { color: #fff; font-size: .85rem; font-weight: 600; line-height: 1.2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.knm-t-sidebar-user-role { font-size: .72rem; color: var(--knm-theme-sidebar-heading); }
.knm-t-sidebar .knm-t-iconbtn { color: var(--knm-theme-sidebar-text); }
.knm-t-sidebar .knm-t-iconbtn:hover { color: #fff; background: rgb(255 255 255 / .07); border-color: transparent; }

/* --------------------------------------------------------------------------
   6 · TOPBAR
   -------------------------------------------------------------------------- */
.knm-t-topbar {
  min-height: var(--knm-theme-topbar-h);
  display: flex;
  align-items: center;
  gap: .65rem;
  padding: 0 calc(var(--knm-theme-gap) * 1.3);
  background: var(--knm-theme-surface);
  border-bottom: 1px solid var(--knm-theme-border);
  position: sticky;
  top: 0;
  z-index: 1020;
}
.knm-t-pagetitle {
  font-family: var(--knm-theme-font-display);
  font-size: 1rem;
  font-weight: 600;
  margin: 0;
  letter-spacing: -.01em;
}
.knm-t-breadcrumb { font-size: .8125rem; color: var(--knm-theme-text-muted); display: flex; align-items: center; gap: .4rem; }
.knm-t-breadcrumb a { color: var(--knm-theme-text-muted); text-decoration: none; }
.knm-t-breadcrumb a:hover { color: var(--knm-theme-accent); }
/* RazorComponents 3.34 made its --knm-breadcrumb-* colours apply (the old selector never matched), and its link rule
   (.knm-breadcrumb-wrapper .breadcrumb-item a) outranks ours above, so every link of the path turned accent. Feed the
   library the same look through its variables: muted links, accent on hover, muted current item (Valerio, 19/10). */
.knm-breadcrumb-wrapper {
  --knm-breadcrumb-color: var(--knm-theme-text-muted);
  --knm-breadcrumb-hover-color: var(--knm-theme-accent);
  --knm-breadcrumb-active-color: var(--knm-theme-text-muted);
  --knm-breadcrumb-separator-color: var(--knm-theme-text-muted);
}

.knm-t-iconbtn {
  width: 36px; height: 36px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 8px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--knm-theme-text-muted);
  font-size: 1.02rem;
  padding: 0;
  flex-shrink: 0;
  text-decoration: none;
}
.knm-t-iconbtn:hover { background: var(--knm-theme-surface-2); color: var(--knm-theme-text); border-color: var(--knm-theme-border); }
.knm-t-notif-dot {
  position: absolute;
  top: 7px; right: 8px;
  width: 7px; height: 7px;
  border-radius: 99px;
  background: var(--knm-theme-accent);
  box-shadow: 0 0 0 2px var(--knm-theme-surface);
}

/* Icone visibili solo in un tema (toggle chiaro/scuro) */
[data-bs-theme="light"] .knm-t-only-dark { display: none; }
[data-bs-theme="dark"] .knm-t-only-light { display: none; }

/* --------------------------------------------------------------------------
   7 · CARD, TABELLE, COMPONENTI
   -------------------------------------------------------------------------- */
.knm-t-card {
  background: var(--knm-theme-surface);
  border: 1px solid var(--knm-theme-border);
  border-radius: var(--knm-theme-radius);
  box-shadow: var(--knm-theme-shadow);
}
.knm-t-card-pad { padding: var(--knm-theme-card-pad); }
.knm-t-card-head {
  display: flex;
  align-items: center;
  gap: .75rem;
  padding: calc(var(--knm-theme-card-pad) * .75) var(--knm-theme-card-pad);
  border-bottom: 1px solid var(--knm-theme-border);
}
.knm-t-card-title { font-family: var(--knm-theme-font-display); font-size: .95rem; font-weight: 600; margin: 0; letter-spacing: -.01em; }
.knm-t-card-foot {
  display: flex;
  align-items: center;
  gap: .75rem;
  padding: calc(var(--knm-theme-card-pad) * .7) var(--knm-theme-card-pad);
  border-top: 1px solid var(--knm-theme-border);
}

.knm-t-table { width: 100%; margin: 0; border-collapse: collapse; }
.knm-t-table th {
  font-size: .7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .07em;
  color: var(--knm-theme-text-muted);
  padding: calc(var(--knm-theme-cell-pad-y) * .9) var(--knm-theme-cell-pad-x);
  border-bottom: 1px solid var(--knm-theme-border);
  white-space: nowrap;
  text-align: left;
}
.knm-t-table td {
  padding: var(--knm-theme-cell-pad-y) var(--knm-theme-cell-pad-x);
  border-bottom: 1px solid var(--knm-theme-border);
  vertical-align: middle;
  font-size: .875rem;
}
.knm-t-table tbody tr:last-child td { border-bottom: 0; }
.knm-t-table tbody tr { transition: background-color .1s; }
.knm-t-table tbody tr:hover { background: color-mix(in oklab, var(--knm-theme-surface-2), transparent 40%); }
.knm-t-rowtitle { color: var(--knm-theme-text); font-weight: 600; text-decoration: none; }
.knm-t-rowtitle:hover { color: var(--knm-theme-accent); }
.knm-t-subtext { font-size: .76rem; color: var(--knm-theme-text-muted); }

.knm-t-id {
  font-family: var(--knm-theme-font-mono);
  font-size: .76rem;
  color: var(--knm-theme-text-muted);
  white-space: nowrap;
}

/* Stato ticket */
.knm-t-status {
  display: inline-flex;
  align-items: center;
  gap: .45em;
  font-size: .73rem;
  font-weight: 700;
  padding: .25em .75em .25em .6em;
  border-radius: 99px;
  white-space: nowrap;
  background: color-mix(in oklab, var(--knm-status, #6b7280), transparent 88%);
  color: color-mix(in oklab, var(--knm-status, #6b7280), var(--knm-theme-text) 25%);
}
.knm-t-status::before { content: ""; width: 6px; height: 6px; border-radius: 99px; background: var(--knm-status, #6b7280); }
.knm-t-status-aperto      { --knm-status: #2563eb; }
.knm-t-status-lavorazione { --knm-status: #d97706; }
.knm-t-status-attesa      { --knm-status: #7c3aed; }
.knm-t-status-risolto     { --knm-status: #16a34a; }
.knm-t-status-chiuso      { --knm-status: #6b7280; }

/* Priorità */
.knm-t-prio {
  display: inline-flex;
  align-items: center;
  gap: .4em;
  font-size: .8125rem;
  font-weight: 600;
  color: var(--knm-theme-text-muted);
  white-space: nowrap;
}
.knm-t-prio i { font-size: .95em; }
.knm-t-prio-urgente i { color: #dc2626; }
.knm-t-prio-alta i    { color: #ea580c; }
.knm-t-prio-media i   { color: #d97706; }
.knm-t-prio-bassa i   { color: #6b7280; }

/* Chip / tag */
.knm-t-chip {
  display: inline-flex;
  align-items: center;
  gap: .4em;
  font-size: .74rem;
  font-weight: 600;
  padding: .22em .65em;
  border-radius: 99px;
  background: var(--knm-theme-surface-2);
  border: 1px solid var(--knm-theme-border);
  color: var(--knm-theme-text-muted);
  white-space: nowrap;
}
.knm-t-chip-accent {
  background: var(--knm-theme-accent-soft);
  border-color: var(--knm-theme-accent-border);
  color: var(--knm-theme-accent);
}
.knm-t-chip-warn {
  background: color-mix(in oklab, #d97706, transparent 89%);
  border-color: color-mix(in oklab, #d97706, transparent 60%);
  color: color-mix(in oklab, #d97706, var(--knm-theme-text) 25%);
}

/* Punto di presenza */
.knm-t-dot { width: 8px; height: 8px; border-radius: 99px; display: inline-block; background: var(--knm-theme-border-strong); flex-shrink: 0; }
.knm-t-dot-online { background: #16a34a; }
.knm-t-dot-away { background: #d97706; }
.knm-t-dot-offline { background: #dc2626; }

/* Statistiche */
.knm-t-stat-label {
  font-size: .72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--knm-theme-text-muted);
}
.knm-t-stat-value {
  font-family: var(--knm-theme-font-display);
  font-size: 1.7rem;
  font-weight: 600;
  letter-spacing: -.025em;
  line-height: 1.2;
}
.knm-t-delta {
  display: inline-flex;
  align-items: center;
  gap: .25em;
  font-size: .73rem;
  font-weight: 700;
  border-radius: 99px;
  padding: .18em .6em;
  white-space: nowrap;
}
.knm-t-delta-good { color: #15803d; background: rgb(22 163 74 / .12); }
.knm-t-delta-bad  { color: #b91c1c; background: rgb(220 38 38 / .1); }
.knm-t-delta-flat { color: var(--knm-theme-text-muted); background: var(--knm-theme-surface-2); }
.knm-t-stat-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  border-radius: 12px;
  background: var(--knm-theme-accent-soft);
  color: var(--knm-theme-accent);
  font-size: 1.3rem;
  flex-shrink: 0;
}

/* Grafico a barre (solo CSS) */
.knm-t-bars {
  display: grid;
  grid-template-columns: repeat(14, 1fr);
  gap: 7px;
  align-items: end;
  height: 168px;
}
.knm-t-bar {
  border-radius: 4px;
  background: color-mix(in oklab, var(--knm-theme-accent), transparent 30%);
  min-height: 6px;
  transition: background-color .12s;
}
.knm-t-bar:hover, .knm-t-bar:last-child { background: var(--knm-theme-accent); }
.knm-t-bars-labels {
  display: grid;
  grid-template-columns: repeat(14, 1fr);
  gap: 7px;
  margin-top: .55rem;
  font-family: var(--knm-theme-font-mono);
  font-size: .65rem;
  color: var(--knm-theme-text-muted);
  text-align: center;
}

/* Barre di ripartizione */
.knm-t-meter {
  height: 6px;
  border-radius: 99px;
  background: var(--knm-theme-surface-2);
  overflow: hidden;
}
.knm-t-meter > span {
  display: block;
  height: 100%;
  border-radius: 99px;
  background: var(--knm-status, var(--knm-theme-accent));
}

/* --------------------------------------------------------------------------
   8 · TAB, TOOLBAR
   -------------------------------------------------------------------------- */
.knm-t-tabs { display: flex; gap: .15rem; border-bottom: 1px solid var(--knm-theme-border); overflow-x: auto; }
.knm-t-tab {
  display: flex;
  align-items: center;
  gap: .45rem;
  padding: .55rem .85rem;
  font-size: .865rem;
  font-weight: 600;
  color: var(--knm-theme-text-muted);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  white-space: nowrap;
}
.knm-t-tab:hover { color: var(--knm-theme-text); }
.knm-t-tab.active { color: var(--knm-theme-text); border-bottom-color: var(--knm-theme-accent); }
.knm-t-count {
  font-size: .67rem;
  font-weight: 700;
  background: var(--knm-theme-surface-2);
  border: 1px solid var(--knm-theme-border);
  border-radius: 99px;
  padding: .05rem .45rem;
  color: var(--knm-theme-text-muted);
}
.knm-t-tab.active .knm-t-count {
  background: var(--knm-theme-accent-soft);
  border-color: var(--knm-theme-accent-border);
  color: var(--knm-theme-accent);
}
.knm-t-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; }

/* --------------------------------------------------------------------------
   9 · CONVERSAZIONE TICKET
   -------------------------------------------------------------------------- */
.knm-t-thread { display: flex; flex-direction: column; gap: var(--knm-theme-gap); }
.knm-t-msg { display: flex; gap: .8rem; }
.knm-t-msg-body { flex: 1; min-width: 0; }
.knm-t-msg-head { display: flex; align-items: baseline; gap: .55rem; margin-bottom: .35rem; flex-wrap: wrap; }
.knm-t-msg-author { font-weight: 700; font-size: .865rem; }
.knm-t-msg-time { font-size: .73rem; color: var(--knm-theme-text-muted); }
.knm-t-msg-bubble {
  background: var(--knm-theme-surface);
  border: 1px solid var(--knm-theme-border);
  border-radius: var(--knm-theme-radius);
  padding: calc(var(--knm-theme-card-pad) * .75) var(--knm-theme-card-pad);
  font-size: .885rem;
  line-height: 1.65;
}
.knm-t-msg-bubble p:last-child { margin-bottom: 0; }
/* A text/plain article body — everything written before the rich-text composer, plus every mail that carried a
   text part — is rendered by ArticleBody inside a bare <p>, and a <p> collapses every run of whitespace: a reply
   typed on four lines, or a quoted email, arrived on screen as one run-on paragraph. pre-wrap keeps the author's
   line breaks and indentation while still wrapping at the bubble's edge. break-word so an unbroken URL cannot
   widen the thread column.
   Scoped with :not() so it never reaches a text/html body: that one carries its own <p> elements, where pre-wrap
   would turn the source formatting of the markup into blank lines on screen. */
.knm-t-msg-bubble > p { white-space: pre-wrap; overflow-wrap: break-word; }

/* A text/html article body (ArticleBody's sanitized branch). The allow-list admits p, div, br, span, b/strong,
   i/em, u, ul/ol/li and a — nothing that carries its own spacing — so the only rules needed here are the ones
   that keep author markup inside the bubble's typography and inside its width. */
.knm-t-msg-html { overflow-wrap: break-word; }
.knm-t-msg-html > :last-child { margin-bottom: 0; }
.knm-t-msg-html p { margin-bottom: .6rem; }
.knm-t-msg-html ul, .knm-t-msg-html ol { margin-bottom: .6rem; padding-left: 1.35rem; }
.knm-t-msg-html a { overflow-wrap: anywhere; }
/* An image pasted into a message (portal-gaps #18) is stored at its own size: a screenshot is wider than the
   thread column and ran under the details card. Scaled down to the bubble, never up. */
.knm-t-msg-bubble img { max-width: 100%; height: auto; }

/* Trailing boilerplate toggle (WP6): a confidentiality/GDPR notice or "received this message in error" text
   collapsed behind a one-click KNMButton, muted and left-bordered like a quote rather than more of the
   message. Zeroing the button's own padding keeps it flush with the bubble's left edge. */
.knm-t-msg-tail-toggle { padding-left: 0; padding-right: 0; }
.knm-t-msg-tail {
  margin-top: .5rem;
  padding: .5rem .75rem;
  border-left: 2px solid var(--knm-theme-border);
  color: var(--knm-theme-text-muted);
  font-size: .9em;
}
/* A plain-text tail (ArticleBody's escaped branch) sits two levels below .knm-t-msg-bubble —
   bubble > .knm-t-msg-tail > p — so the bubble's own direct-child pre-wrap rule above (line 800) does not
   reach it. Same rule, scoped one level deeper, for the same reason: a multi-line notice must not collapse
   into one run-on paragraph once expanded. (An HTML tail needs no equivalent: it wraps in .knm-t-msg-html,
   which already carries its own spacing via p/ul/ol margins above.) */
.knm-t-msg-tail > p { white-space: pre-wrap; overflow-wrap: break-word; }
/* On paper the notice comes back. The tail is hidden with the `hidden` attribute, which also takes it out of
   find-in-page, of a selection over the thread and of the printed page — acceptable on screen, where the
   toggle is one click away, and wrong on a print-out, where there is nothing to click. A printed ticket
   therefore carries the whole message, and the toggle, now a dead control, does not print. */
@media print {
  .knm-t-msg-tail[hidden] { display: block !important; }
  .knm-t-msg-tail-toggle { display: none; }
}
.knm-t-msg-agent .knm-t-msg-bubble {
  border-color: var(--knm-theme-accent-border);
  background: color-mix(in oklab, var(--knm-theme-accent), var(--knm-theme-surface) 95%);
}
.knm-t-msg-note .knm-t-msg-bubble {
  border-color: color-mix(in oklab, #d97706, transparent 60%);
  background: color-mix(in oklab, #d97706, var(--knm-theme-surface) 93%);
}
/* Collapsed attachment picker (AttachmentComposer). A link-styled row, not a button: it opens a section of
   the same card rather than performing an action. Padding is zeroed so it lines up with the fields above it. */
.knm-t-attach-toggle {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  padding: 0;
  font-weight: 600;
  text-decoration: none;
  color: var(--knm-theme-text-muted);
}
.knm-t-attach-toggle:hover { color: var(--knm-theme-accent); }
.knm-t-attach-toggle .badge { font-size: .68rem; }
/* Bootstrap's reboot already carries [hidden]{display:none!important}, so the collapsed panel needs no rule
   of its own — only the gap for when it is open. */
.knm-t-attach-toggle + div { margin-top: .6rem; }

.knm-t-attachment {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  font-size: .78rem;
  font-weight: 600;
  padding: .3rem .65rem;
  border-radius: 8px;
  border: 1px solid var(--knm-theme-border-strong);
  background: var(--knm-theme-surface);
  color: var(--knm-theme-text);
  text-decoration: none;
}
.knm-t-attachment:hover { border-color: var(--knm-theme-accent); color: var(--knm-theme-accent); }

/* Article attachment chips (message thread) */
.knm-t-atts-label {
  display: block;
  margin-top: .5rem;
  font-size: .75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .03em;
  color: var(--knm-theme-text-muted);
}
.knm-t-msg-atts { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .5rem; }
.knm-t-att {
  display: inline-flex; align-items: center; gap: .375rem;
  padding: .25rem .625rem;
  border: 1px solid var(--knm-theme-border-strong);
  border-radius: var(--knm-theme-radius-sm);
  background: var(--knm-theme-surface-2);
  color: var(--knm-theme-text);
  text-decoration: none;
  font-size: .8125rem;
}
.knm-t-att:hover { border-color: var(--knm-theme-accent); }
.knm-t-att-size { color: var(--knm-theme-text-muted); }

/* Timeline attività */
.knm-t-timeline {
  margin-left: 4px;
  border-left: 1px solid var(--knm-theme-border);
  display: flex;
  flex-direction: column;
  gap: 1.05rem;
  padding-left: 1rem;
}
.knm-t-tl-item { position: relative; font-size: .8rem; line-height: 1.45; }
.knm-t-tl-item::before {
  content: "";
  position: absolute;
  left: -1.31rem;
  top: .28rem;
  width: 9px; height: 9px;
  border-radius: 99px;
  background: var(--knm-theme-surface);
  border: 2px solid var(--knm-theme-border-strong);
}
.knm-t-tl-item.knm-t-tl-accent::before { border-color: var(--knm-theme-accent); }
.knm-t-tl-time { display: block; font-size: .7rem; color: var(--knm-theme-text-muted); margin-top: .1rem; }

/* Riga proprietà (dettagli ticket) */
.knm-t-proprow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
  font-size: .835rem;
  padding: .42rem 0;
}
.knm-t-proprow > span:first-child { color: var(--knm-theme-text-muted); font-weight: 600; flex-shrink: 0; }

/* --------------------------------------------------------------------------
   10 · FORM AVANZATI
   -------------------------------------------------------------------------- */
.knm-t-dropzone {
  border: 1.5px dashed var(--knm-theme-border-strong);
  border-radius: var(--knm-theme-radius);
  padding: calc(var(--knm-theme-card-pad) * 1.1);
  text-align: center;
  color: var(--knm-theme-text-muted);
  background: color-mix(in oklab, var(--knm-theme-surface-2), transparent 40%);
  font-size: .85rem;
  cursor: pointer;
  transition: border-color .12s, background-color .12s;
}
.knm-t-dropzone:hover { border-color: var(--knm-theme-accent); background: var(--knm-theme-accent-soft); }
.knm-t-dropzone i { font-size: 1.4rem; display: block; margin-bottom: .35rem; }

.knm-t-switchrow {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  padding: .8rem 0;
  border-bottom: 1px solid var(--knm-theme-border);
}
.knm-t-switchrow:last-child { border-bottom: 0; padding-bottom: 0; }
.knm-t-switchrow:first-child { padding-top: 0; }

/* --------------------------------------------------------------------------
   11 · CUSTOMIZER (pannello aspetto)
   -------------------------------------------------------------------------- */
.knm-t-customizer { --bs-offcanvas-width: 340px; }
.knm-t-opt-label {
  font-size: .72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--knm-theme-text-muted);
  margin: 1.35rem 0 .55rem;
}
.knm-t-opt-label:first-child { margin-top: 0; }
/* «Menu di navigazione» (portal only, decision of 19/10) is hidden in two cases:
   - below 992 px, where the top menu does not exist (section 20) and the menu always opens from its button, so the
     choice would change nothing on a phone;
   - while the page's menu is locked to the side (knm-theme.js marks <html>): the lock comes from the document's first
     request, so after an in-circuit move to /portal the choice would change nothing until the page is reloaded.
   The options also carry .knm-t-seg, whose «display: flex» is one class and comes LATER in this file: a one-class rule
   here lost to it at 390 px (the title hid, the buttons stayed). The compound .knm-t-seg.knm-appearance-nav has two
   classes, so these rules win wherever they sit in the file. */
@media (max-width: 991.98px) {
  .knm-appearance-nav, .knm-t-seg.knm-appearance-nav { display: none; }
}
[data-knm-nav-locked] .knm-appearance-nav,
[data-knm-nav-locked] .knm-t-seg.knm-appearance-nav { display: none; }

.knm-t-seg {
  display: flex;
  background: var(--knm-theme-surface-2);
  border: 1px solid var(--knm-theme-border);
  border-radius: 9px;
  padding: 3px;
  gap: 2px;
}
.knm-t-seg > button,
.knm-t-seg > a {
  flex: 1;
  border: 0;
  background: none;
  border-radius: 6px;
  padding: .38rem .5rem;
  font-size: .8rem;
  font-weight: 600;
  color: var(--knm-theme-text-muted);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .4em;
  white-space: nowrap;
  text-decoration: none;
}
.knm-t-seg > button:hover,
.knm-t-seg > a:hover { color: var(--knm-theme-text); }
.knm-t-seg > button.active,
.knm-t-seg > a.active {
  background: var(--knm-theme-surface);
  color: var(--knm-theme-text);
  box-shadow: 0 1px 2px rgb(0 0 0 / .1);
}

.knm-t-swatch {
  width: 34px; height: 34px;
  border-radius: 10px;
  border: 1px solid var(--knm-theme-border);
  background: var(--swatch, var(--knm-theme-accent));
  padding: 0;
  cursor: pointer;
  position: relative;
}
.knm-t-swatch.active {
  box-shadow: 0 0 0 2px var(--knm-theme-surface), 0 0 0 4px var(--swatch, var(--knm-theme-accent));
}
.knm-t-swatch.active::after {
  content: "✓";
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-size: .85rem;
  font-weight: 700;
}

.knm-t-help { font-size: .76rem; color: var(--knm-theme-text-muted); line-height: 1.5; }

/* Messaggio di validazione sotto un campo. Non ".knm-t-help" ma il suo contrario: un rifiuto che si legge come un
   suggerimento non viene letto affatto, ed è così che «Acme Corp» faceva sembrare rotto il pulsante (H9). */
.knm-t-field-error {
  display: block;
  margin-top: 4px;
  font-size: .76rem;
  line-height: 1.5;
  color: var(--bs-danger, #dc3545);
}

/* Esito positivo sotto un campo (nome utente libero): stessa misura del rifiuto, colore di successo. */
.knm-t-field-ok {
  display: block;
  margin-top: 4px;
  font-size: .76rem;
  line-height: 1.5;
  color: var(--bs-success, #198754);
}

/* Navigazione verticale (impostazioni) */
.knm-t-vnav { display: flex; flex-direction: column; gap: 2px; }
.knm-t-vnav a {
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .5rem .75rem;
  border-radius: 8px;
  color: var(--knm-theme-text-muted);
  font-weight: 600;
  font-size: .865rem;
  text-decoration: none;
}
.knm-t-vnav a i { width: 1.1rem; text-align: center; }
.knm-t-vnav a:hover { color: var(--knm-theme-text); background: var(--knm-theme-surface-2); }
.knm-t-vnav a.active { background: var(--knm-theme-accent-soft); color: var(--knm-theme-accent); }

/* Bersaglio di una voce di knm-t-vnav: lo scroll si ferma sotto la barra superiore fissa invece di
   nascondere il titolo della sezione dietro di essa. Vale sia per lo scroll da codice
   (knmPageNav.scrollToSection) sia per il salto nativo del browser su /settings#sezione. */
.knm-t-anchor-section { scroll-margin-top: calc(var(--knm-theme-topbar-h) + var(--knm-theme-gap)); }

/* --------------------------------------------------------------------------
   12 · LOGIN
   -------------------------------------------------------------------------- */
.knm-t-login {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 2rem 1rem;
  background:
    radial-gradient(820px 420px at 50% -8%, var(--knm-theme-accent-soft), transparent 70%),
    var(--knm-theme-bg);
}
.knm-t-login-card { width: 100%; max-width: 400px; }

/* --------------------------------------------------------------------------
   13 · UTILITÀ
   -------------------------------------------------------------------------- */
.knm-t-muted { color: var(--knm-theme-text-muted); }
.knm-t-mono { font-family: var(--knm-theme-font-mono); }
.knm-t-divider { border: 0; border-top: 1px solid var(--knm-theme-border); margin: var(--knm-theme-gap) 0; opacity: 1; }
.knm-t-scroll-x { overflow-x: auto; }

/* --------------------------------------------------------------------------
   14 · SIDEBAR COMPRIMIBILE (desktop) — [data-knm-sidebar="collapsed"]
   -------------------------------------------------------------------------- */
@media (min-width: 992px) {
  .knm-t-sidebar { transition: width .18s ease, flex-basis .18s ease; }
  [data-knm-sidebar="collapsed"] .knm-t-sidebar {
    width: 78px !important;
    flex-basis: 78px;
  }
  [data-knm-sidebar="collapsed"] .knm-t-brand-text,
  [data-knm-sidebar="collapsed"] .knm-t-sidebar-user > div,
  [data-knm-sidebar="collapsed"] .knm-t-sidebar-user > a,
  [data-knm-sidebar="collapsed"] .knm-t-sidebar-user > form { display: none; }
  [data-knm-sidebar="collapsed"] .knm-t-sidebar-brand { justify-content: center; padding-left: 0; padding-right: 0; }
  [data-knm-sidebar="collapsed"] .knm-t-navlink {
    font-size: 0;
    gap: 0;
    justify-content: center;
    padding: .55rem 0;
  }
  [data-knm-sidebar="collapsed"] .knm-t-navlink i { font-size: 1.1rem; }
  [data-knm-sidebar="collapsed"] .knm-t-navlink.active::before { left: -5px; }
  [data-knm-sidebar="collapsed"] .knm-t-nav-section {
    font-size: 0;
    line-height: 0;
    padding: 0;
    margin: .55rem .55rem;
    border-top: 1px solid var(--knm-theme-sidebar-border);
  }
  [data-knm-sidebar="collapsed"] .knm-t-sidebar-nav .knm-t-nav-section:first-child { border-top: 0; margin: 0; }
  [data-knm-sidebar="collapsed"] .knm-t-sidebar-user { justify-content: center; padding: .3rem 0; }
}

/* --------------------------------------------------------------------------
   15 · MOBILE
   -------------------------------------------------------------------------- */
@media (max-width: 767.98px) {
  /* Longhands, not the `padding` shorthand: horizontally the box is a .container-fluid driven by
     --bs-gutter-x (see section 4), and a shorthand here would silently take that back. */
  .knm-t-content { --bs-gutter-x: 1.8rem; padding-top: .9rem; padding-bottom: .9rem; }
  .knm-t-topbar { padding: 0 .75rem; gap: .45rem; }
  .knm-t-pagetitle { font-size: .92rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .knm-t-stat-value { font-size: 1.45rem; }
  /* The Kanban toolbar reflows on a phone: the search takes the full row, the filters share the next one.
     Both selectors follow the KNMInput conversion (item 5) — the search wrapper replaced the bespoke
     .knm-t-search, and the filters are KNMSelect divs, not .form-select elements. Renaming the markup without
     these two lines left the toolbar rigid at 260px + 2x12rem on a narrow viewport. The generic .form-select
     rule stays for any future toolbar that still uses a native select. */
  .knm-t-toolbar > .knm-t-kanban-search { width: 100% !important; }
  .knm-t-toolbar > .knm-t-kanban-filter { flex: 1 1 auto; width: auto !important; min-width: 0; }
  .knm-t-toolbar > .form-select { flex: 1 1 auto; width: auto !important; }
  .knm-t-toolbar .ms-auto { margin-left: 0 !important; }
  .knm-t-toolbar > .btn, .knm-t-toolbar > a.btn { flex: 1 1 auto; text-align: center; }
  .knm-t-bars { height: 120px; }
  .knm-t-bars-labels { font-size: .55rem; }
  .knm-t-msg { gap: .55rem; }
}

/* --------------------------------------------------------------------------
   16 · BREADCRUMB
   -------------------------------------------------------------------------- */
.knm-t-breadcrumb a { display: inline-flex; align-items: center; gap: .3rem; }
.knm-t-breadcrumb i { flex-shrink: 0; }
.knm-t-breadcrumb-current {
  color: var(--knm-theme-text);
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* --------------------------------------------------------------------------
   17 · KANBAN  — the board is KNMKanban (KNM.RazorComponents); what is left here is the
   product skin over it. The bespoke .knm-t-kanban/.knm-t-kcol grid is gone with the
   hand-rolled board it styled; the class names that survive are the ones passed to the
   component through KNMKanbanBuilder (WithBoardCssClass / WithColumnHeaderCssClass /
   WithCardCssClass) plus the card's own inner markup.
   -------------------------------------------------------------------------- */

/* FULL WIDTH — CTO 2026-09-04, item 8 ("pagina con troppo spazio libero ... espandila su tutte").
   The board became KNMKanban in this same branch, so the rule moved one level down with it: the
   component owns .knm-t-kanban (its root: position/overflow) and lays the columns out on its inner
   .knm-kanban__grid, which is what has to carry the track list. The rule that was written for the
   bespoke board — grid-auto-columns: minmax(292px, 1fr) on .knm-t-kanban itself — would now be
   styling the wrong element, so it is expressed here instead; the BEHAVIOUR is unchanged and so is
   the number, measured on the running host at 1680px: container 1364px, four columns, 326px each.

   292px stays the FLOOR — below it a card's number, subject and footer stop fitting — so on a narrow
   viewport the board overflows into the component's own horizontal scroll, which is what a board
   should do. auto-fit is deliberately NOT used: the four columns are fixed and always present, so
   the count is known and a track list is honest about it. */
/* Since KNM.RazorComponents 3.26.0 the track list is the component's own, driven by
   --knm-kanban-visible-columns: no override of its grid any more. */
@media (max-width: 767.98px) {
  .knm-t-kanban { --knm-kanban-column-min-width: 260px; }
}

/* The theme's surfaces, so the board reads as part of the app rather than as the component's
   own default grey, in light and dark alike. */
.knm-t-kanban {
  --knm-kanban-visible-columns: 4;
  --knm-kanban-column-min-width: 292px;
  --knm-kanban-column-bg: color-mix(in oklab, var(--knm-theme-surface-2), transparent 35%);
  --knm-kanban-card-bg: var(--knm-theme-surface);
  --knm-kanban-card-radius: var(--knm-theme-radius-sm);
  /* WithCellScroll: each column scrolls on its own below the page's header and filters. */
  --knm-kanban-cell-max-height: calc(100vh - 260px);
}

/* The header is our ColumnHeaderTemplate (title + the SERVER-side total), so it needs the count
   badge pushed to the end; the component's own header is a flex row already. */
.knm-t-kcol-head { text-transform: none; letter-spacing: 0; font-size: .8rem; }
.knm-t-kcol-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* The card is a KNMCard and a real link (WithCardHref); its body keeps the theme's text colour. */
.knm-t-kcard-link { display: block; color: var(--knm-theme-text); }
.knm-t-kcard-title {
  font-size: .85rem;
  font-weight: 600;
  line-height: 1.35;
  margin: .3rem 0 .55rem;
  text-wrap: pretty;
}
.knm-t-kcard-foot { display: flex; align-items: center; gap: .5rem; }
@media (max-width: 767.98px) {
  .knm-t-kanban { --knm-kanban-cell-max-height: none; }
}

/* --------------------------------------------------------------------------
   18 · KNOWLEDGE BASE
   -------------------------------------------------------------------------- */
.knm-t-kbrow {
  display: flex;
  align-items: center;
  gap: .85rem;
  padding: var(--knm-theme-cell-pad-y) var(--knm-theme-card-pad);
  border-bottom: 1px solid var(--knm-theme-border);
  text-decoration: none;
  color: var(--knm-theme-text);
}
.knm-t-kbrow:hover { background: color-mix(in oklab, var(--knm-theme-surface-2), transparent 40%); color: var(--knm-theme-text); }
.knm-t-kbrow:last-child { border-bottom: 0; }

/* A counter card that is a link (portal home, portal-gaps 3a): the whole card opens the list it counts. */
.knm-t-statlink { display: block; color: inherit; text-decoration: none; border-radius: var(--bs-border-radius-lg); }
.knm-t-statlink:hover { color: inherit; }
.knm-t-statlink:hover .knm-t-card { border-color: var(--knm-theme-accent); }
.knm-t-statlink:focus-visible { outline: 2px solid var(--knm-theme-accent); outline-offset: 2px; }

/* The portal's top-bar search (portal-gaps): the desk's .knm-t-search-host width, the field filling it, and no field
   margin, which would lift the box off the top bar's centre line (same reset as the Kanban toolbar). */
.knm-t-portal-search { width: 280px; max-width: 40vw; flex: 0 1 auto; --knm-field-spacing: 0; }
.knm-t-portal-search > * { width: 100%; }

/* --------------------------------------------------------------------------
   19 · PORTALE CLIENTI
   -------------------------------------------------------------------------- */
.knm-t-hero {
  text-align: center;
  padding: calc(var(--knm-theme-gap) * 2.2) 1.25rem calc(var(--knm-theme-gap) * 1.8);
  background: radial-gradient(720px 340px at 50% -45%, var(--knm-theme-accent-soft), transparent 72%);
  border-bottom: 1px solid var(--knm-theme-border);
}
.knm-t-hero-title {
  font-family: var(--knm-theme-font-display);
  font-size: 1.55rem;
  font-weight: 600;
  letter-spacing: -.02em;
  margin-bottom: .35rem;
}
/* The portal's content column — sister surface of .knm-t-content above, same flex column (.knm-t-main) and
   therefore the same two lines, for the same reasons: grow to own the leftover column height, and pin
   align-content so the grid rows do not stretch to fill it. Unlike the agent desk this one is centered on a
   max-width rather than full-bleed, so it keeps its own horizontal padding instead of a Bootstrap container. */
.knm-t-customer-main {
  max-width: 1160px;
  width: 100%;
  margin: 0 auto;
  flex: 1 0 auto;
  align-content: start;
  padding: calc(var(--knm-theme-gap) * 1.3) 1.25rem;
}
.knm-t-customer-footer {
  margin-top: auto;
  border-top: 1px solid var(--knm-theme-border);
  padding: 1.1rem 1.25rem;
  text-align: center;
  font-size: .78rem;
  color: var(--knm-theme-text-muted);
}
.knm-t-customer-footer a { color: var(--knm-theme-text-muted); text-decoration: none; }
.knm-t-customer-footer a:hover { color: var(--knm-theme-accent); }

/* The staff sign-in is a <button>, not an anchor: it has to leave the circuit with forceLoad, which an
   intercepted anchor cannot do (see CustomerLayout.razor). It should still read as the link it replaced. */
.knm-t-footer-link {
    background: none; border: 0; padding: 0; font: inherit; cursor: pointer;
    color: var(--knm-theme-text-muted); text-decoration: none;
}
.knm-t-footer-link:hover { color: var(--knm-theme-accent); }

/* Footer area admin */
.knm-t-footer {
  margin-top: auto;
  border-top: 1px solid var(--knm-theme-border);
  padding: .9rem calc(var(--knm-theme-gap) * 1.3);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .35rem 1.25rem;
  font-size: .78rem;
  color: var(--knm-theme-text-muted);
}
.knm-t-footer a { color: var(--knm-theme-text-muted); text-decoration: none; }
.knm-t-footer a:hover { color: var(--knm-theme-accent); }

.modal-content {
  background: var(--knm-theme-surface);
  color: var(--knm-theme-text);
  border: 1px solid var(--knm-theme-border);
  border-radius: var(--knm-theme-radius);
}
.modal-header, .modal-footer { border-color: var(--knm-theme-border); }

/* --------------------------------------------------------------------------
   20 · MENU ORIZZONTALE — [data-knm-nav="top"] (opzione, solo desktop)
   Stesso markup della sidebar: l'orientamento è una preferenza del tema.
   Sotto i 992px resta sempre l'offcanvas mobile.
   -------------------------------------------------------------------------- */
@media (min-width: 992px) {
  [data-knm-nav="top"] .knm-t-app { flex-direction: column; }
  [data-knm-nav="top"] .knm-t-sidebar {
    width: 100% !important;
    flex: 0 0 auto;
    height: auto;
    flex-direction: row;
    align-items: center;
    position: sticky;
    top: 0;
    z-index: 1030;
    border-right: 0;
    border-bottom: 1px solid var(--knm-theme-sidebar-border);
  }
  [data-knm-nav="top"] .knm-t-sidebar-brand {
    border-bottom: 0;
    min-height: 0;
    padding: .55rem .5rem .55rem 1.15rem;
  }
  [data-knm-nav="top"] .knm-t-brand-text { display: inline; }
  [data-knm-nav="top"] .knm-t-sidebar-nav {
    flex-direction: row;
    align-items: center;
    gap: .15rem;
    padding: .5rem;
    overflow-y: visible;
    overflow-x: auto;
  }
  [data-knm-nav="top"] .knm-t-nav-section { display: none; }
  [data-knm-nav="top"] .knm-t-navlink {
    width: auto;
    font-size: .875rem;
    gap: .55rem;
    justify-content: flex-start;
    padding: .45rem .8rem;
  }
  [data-knm-nav="top"] .knm-t-navlink.active::before { display: none; }
  [data-knm-nav="top"] .knm-t-sidebar-footer {
    flex-direction: row;
    align-items: center;
    gap: .4rem;
    border-top: 0;
    padding: .5rem 1rem .5rem .5rem;
    margin-left: auto;
  }
  [data-knm-nav="top"] .knm-t-sidebar-footer > .knm-t-navlink {
    width: auto;
    font-size: 0;
    gap: 0;
    padding: .5rem;
  }
  [data-knm-nav="top"] .knm-t-sidebar-footer > .knm-t-navlink i { font-size: 1.05rem; }
  [data-knm-nav="top"] .knm-t-sidebar-user { padding: .2rem; gap: .45rem; }
  [data-knm-nav="top"] .knm-t-sidebar-user > div { display: none; }
  [data-knm-nav="top"] [data-knm-toggle-sidebar] { display: none !important; }
  [data-knm-nav="top"] .knm-t-topbar { position: static; }
}

/* Global search (top-bar). The box is the Search type of KNMInput: its results panel, the cards per type, the highlight
   and the keyboard are the library's, dressed with the theme tokens in custom.css (.knm-gsearch-panel). What is left
   here is the box's width in the top bar (Corrado, 09/10). */
.knm-t-search-host { width: 280px; flex: 0 0 auto; }
/* The host is a d-md-flex box, so the field has to be told to fill it along the main axis. */
.knm-t-search-host > * { flex: 1 1 auto; min-width: 0; }

/* Notification bell */
.knm-t-notif { position: relative; }
.knm-t-notif-badge {
  position: absolute; top: 2px; right: 2px; min-width: 16px; height: 16px; padding: 0 4px;
  border-radius: 9px; background: var(--knm-theme-accent, #ea580c); color: #fff;
  font-size: .62rem; font-weight: 700; line-height: 16px; text-align: center; }
.knm-t-notif-panel {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 1200; width: 340px; max-height: 60vh;
  overflow-y: auto; background: var(--knm-theme-surface, #fff); color: var(--knm-theme-text, #1a1a1a);
  border: 1px solid var(--knm-theme-border, #e2e2e2); border-radius: 10px; box-shadow: 0 12px 28px rgb(0 0 0 / .18); }
.knm-t-notif-head { display: flex; align-items: center; justify-content: space-between; padding: .6rem .75rem;
  border-bottom: 1px solid var(--knm-theme-border, #e2e2e2); font-weight: 700; font-size: .8rem; }
.knm-t-notif-item { display: flex; gap: .6rem; width: 100%; text-align: left; padding: .55rem .75rem; border: 0;
  background: none; cursor: pointer; color: inherit; border-bottom: 1px solid var(--knm-theme-border, #eee); }
.knm-t-notif-item:hover { background: var(--knm-theme-hover, rgb(0 0 0 / .05)); }
.knm-t-notif-item.is-unread { background: var(--knm-theme-accent-soft, rgb(234 88 12 / .08)); }
.knm-t-notif-item i { font-size: 1rem; opacity: .75; }
.knm-t-notif-title { font-weight: 600; font-size: .82rem; }
.knm-t-notif-sub { font-size: .72rem; opacity: .6; }
.knm-t-notif-empty { padding: 1rem; text-align: center; font-size: .82rem; opacity: .65; }

/* Idle warning strip — the last seconds before the screen locks itself (Berruto's model).
   Fixed across the top, above everything: it interrupts, so it does not queue behind the topbar's stacking
   context. Colours from the theme tokens, so it reads the same in light and dark without a rule for each. */
.knm-t-idlewarn { position: fixed; top: 0; left: 0; right: 0; z-index: 1080; }
.knm-t-idlewarn[hidden] { display: none; }
.knm-t-idlewarn-body { display: flex; align-items: center; justify-content: center; gap: .5rem;
  padding: .5rem 1rem; background: var(--bs-warning-bg-subtle, #fff3cd);
  color: var(--bs-warning-text-emphasis, #664d03);
  border-bottom: 1px solid var(--bs-warning-border-subtle, #ffe69c); }
.knm-t-idlewarn-icon { font-size: 1rem; }
.knm-t-idlewarn-text { font-size: .85rem; font-weight: 600; font-variant-numeric: tabular-nums; }
/* 4px, like the bar this is modelled on: enough to read as a countdown, not enough to be a component. */
.knm-t-idlewarn-track { height: 4px; background: var(--bs-warning-border-subtle, #ffe69c); }
/* Emptying, not filling — it is time left, not progress towards something wanted. The transition is shorter
   than the tick so a second does not read as a jump and a reset does not lag behind the mouse. */
.knm-t-idlewarn-bar { height: 100%; width: 100%; background: var(--bs-warning, #ffc107);
  transition: width .3s linear; }

/* 404 Not Found page */
.knm-t-notfound { display: flex; align-items: center; justify-content: center; min-height: 60vh; padding: 1.5rem; }
.knm-t-notfound-card { max-width: 460px; width: 100%; text-align: center; }
.knm-t-notfound-icon { font-size: 3.5rem; color: var(--knm-theme-accent, #ea580c); margin-bottom: .5rem; }
.knm-t-notfound-code { font-family: var(--knm-theme-font-display); font-size: 3.5rem; font-weight: 800;
  line-height: 1; color: var(--knm-theme-accent, #ea580c); margin-bottom: .5rem; }
.knm-t-notfound-title { font-size: 1.35rem; margin: 0 0 .5rem; }
.knm-t-notfound-desc { font-size: .9rem; margin: 0 0 1rem; }
.knm-t-notfound-path { font-size: .78rem; margin: 0 0 1.25rem; }
.knm-t-notfound-path code { background: var(--knm-theme-surface-2, #f1efec); padding: .2rem .5rem; border-radius: 6px; }
.knm-t-notfound-actions { display: flex; gap: .6rem; justify-content: center; flex-wrap: wrap; }
