/* Clintel: app shell + inbox layout.
   Brand lives in tokens.css; this file only arranges Clintel's screens against
   the semantic aliases (--color-*, --sidebar-*, --urgency-*). No raw hex. */

/* ============ Base ============ */
body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--text-base);
  background: var(--color-bg);
  color: var(--color-text);
}

h1 {
  font-family: var(--font-serif);
  color: var(--color-primary);
  margin: 0 0 var(--space-2);
  font-size: var(--text-3xl);
  letter-spacing: var(--tracking-tight);
  line-height: 1.12;
}

h2 {
  font-family: var(--font-serif);
  color: var(--color-text);
  margin: 0;
  font-size: var(--text-2xl);
  letter-spacing: var(--tracking-tight);
  line-height: 1.15;
}

/* ============ Base motion + focus (2026-07-30 motion pass) ============
   Site-wide defaults so every link/input gets a consistent feel without
   hunting down each one-off form: any selector below with its OWN
   :focus-visible rule (buttons, nav, rows…) still wins on specificity —
   this just fills the gaps (plain <input>/<select>/<textarea> in
   master-form/task-new-form/doc-filters/entry-form/expediente forms that
   never had an explicit focus treatment before, falling back to whatever
   the browser's own default ring looked like). */
a {
  transition: color var(--duration-fast) var(--ease-out-quart);
}

input,
select,
textarea {
  transition: border-color var(--duration-fast) var(--ease-out-quart),
              box-shadow var(--duration-fast) var(--ease-out-quart);
}

:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

/* ============ Panel primitive (2026-07-30 UI deep-dive, fix B) ============
   The one container primitive: lifts a major page section off the (now
   deepened) --page ground so it visually separates from the surrounding
   chrome. ONE level of containment only — never nest .panel inside .panel,
   never combine with .master-card. Hairline sub-dividers (.record-section,
   .record-section-label) stay INSIDE a panel, they don't replace it. */
.panel {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-5) var(--space-6);
}

/* ============ Entrance choreography (2026-07-30 motion pass) ============
   A one-time, subtle rise-in for the page's major containers (.panel,
   .stat-item, .record-aside — crm.css's identity rail, which shares this
   file's cascade) on load: opacity 0->1 + translateY(6px)->0. Deliberately
   quiet (Jakub — "the best animation is that which goes unnoticed"): this
   is a console opened dozens of times a day, not a marketing page, so it
   plays ONCE per load, never loops, and is fully inert under
   prefers-reduced-motion. A tiny nth-child stagger (~40ms/step, capped at 5)
   gives sibling panels/KPI tiles a hair of sequence without turning into a
   slideshow. */
@media (prefers-reduced-motion: no-preference) {
  .panel,
  .stat-item,
  .record-aside {
    animation: rise-in var(--duration-modal) var(--ease-out-quint) both;
  }

  .panel:nth-of-type(2),
  .stat-item:nth-child(2) { animation-delay: 40ms; }
  .panel:nth-of-type(3),
  .stat-item:nth-child(3) { animation-delay: 80ms; }
  .panel:nth-of-type(4),
  .stat-item:nth-child(4) { animation-delay: 120ms; }
  .panel:nth-of-type(n+5),
  .stat-item:nth-child(n+5) { animation-delay: 160ms; }
}

@keyframes rise-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ============ Page head pattern (fix C) ============
   h1 (serif, existing rule above) + one-line muted purpose sentence +
   optional right-aligned action slot. Every top-level page gets one. */
.page-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}

.page-head-main { min-width: 0; }

.page-head-sub {
  margin: var(--space-1) 0 0;
  color: var(--color-text-muted);
  font-size: var(--text-base);
}

.page-head-actions {
  flex: 0 0 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}

/* A filter/search form sitting at the top of a table's .panel (fix G — "a
   search box is a TOOL, not a content section"), instead of its own labeled
   .record-section. */
.toolbar-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-5);
}

/* A quiet, hairline-topped strip at the bottom of a .panel (e.g. a
   collapsed "create new…" affordance) — sits inside the SAME panel as the
   table above it rather than opening a new boxed section (fix G). */
.panel-footer {
  margin-top: var(--space-5);
  padding-top: var(--space-5);
  border-top: 1px solid var(--color-border);
}

/* ============ Pill discipline: taxonomic metadata (fix D) ============
   .task-tag stays reserved for STATE (task status, urgency, SLA, health,
   compliance estado, pending/enabled). Anything TAXONOMIC — role names, doc
   categories, folder labels, item types — uses this instead: no border, no
   background, no uppercase-shouting, sentence case. */
.meta-text {
  font-size: var(--text-2xs);
  font-weight: 500;
  color: var(--color-text-muted);
  letter-spacing: 0.02em;
}

/* ============ Three-pane shell ============ */
.shell { display: flex; min-height: 100vh; }

/* Width discipline: on wide monitors the content column previously stretched
   edge-to-edge, so stat cells and panels sprawled (a lone "2" with 400px of
   air) — every reference layout caps and centers the working column instead.
   #main-content is the shared page container across the console templates. */
#main-content {
  max-width: 1480px;
  margin-inline: auto;
}

.content {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

/* The inner content-body wrapper: a plain flex item filling whatever
   height remains under the topbar (min-height:0 so a scrollable page like
   .master-page/.dashboard-page can actually clip+scroll instead of forcing
   .content taller than the viewport). Each page's own content_class
   (.master-page, .dashboard-page, .content-body.inbox, …) still owns its
   OWN internal layout exactly as before this wrapper was introduced. */
.content-body {
  flex: 1;
  min-height: 0;
}

/* The login fallback centres a single card. */
.content-body.center {
  display: flex;
  align-items: center;
  justify-content: center;
}

/* ============ Topbar: breadcrumbs · global search · avatar menu ============
   Three-zone flex, 2026-07-29 restructure: [breadcrumbs] ——— [search]
   [avatar ▾]. Crumbs grow and truncate first on narrow widths (min-width:0);
   search keeps its fixed pill width; the avatar menu never shrinks.
   Deliberately no notification bell — no notification source exists yet, a
   placeholder would just be dead chrome. */
.topbar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-8);
  border-bottom: 1px solid var(--color-border);
  background: var(--color-surface);
}

/* ---- Breadcrumbs (top-left) ---- */
.crumbs {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  white-space: nowrap;
  overflow: hidden;
}

.crumbs a {
  color: var(--color-text-muted);
  text-decoration: none;
  max-width: 28ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 0 1 auto;
}

.crumbs a:hover { color: var(--color-text); text-decoration: underline; }

.crumbs [aria-current="page"] {
  color: var(--color-text);
  font-weight: 500;
  max-width: 28ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 0 1 auto;
}

.crumb-sep {
  width: 12px;
  height: 12px;
  flex: 0 0 12px;
  color: var(--color-text-soft);
}

/* ---- Global search (center-right, fixed pill width) ---- */
.global-search {
  position: relative;
  flex: 0 1 440px;
  width: 100%;
  max-width: 440px;
}

.global-search .search-icon {
  position: absolute;
  left: var(--space-3);
  top: 50%;
  transform: translateY(-50%);
  width: 16px;
  height: 16px;
  color: var(--color-text-soft);
  pointer-events: none;
}

/* Review #13 — input-radius decision, documented so nobody 'fixes' it either
   direction: this is a DELIBERATE EXCEPTION to the 8px-input rule. The one
   global topbar search is a pill by design (an approved modern pattern);
   every in-page input stays --radius-md (8px) per brand. */
.global-search input[type="search"] {
  width: 100%;
  box-sizing: border-box;
  padding: var(--space-2) var(--space-3) var(--space-2) var(--space-10);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-pill);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--color-text);
  background: var(--color-surface);
  transition: border-color var(--duration-fast) var(--ease-out-quart),
              box-shadow var(--duration-fast) var(--ease-out-quart);
}

.global-search input[type="search"]:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}

.search-dropdown {
  position: absolute;
  top: calc(100% + var(--space-2));
  left: 0;
  width: 100%;
  min-width: 360px;
  max-height: 60vh;
  overflow-y: auto;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  z-index: 20;
  padding: var(--space-2);
  box-sizing: border-box;
}

.search-dropdown:empty { display: none; }

.search-group-label {
  margin: var(--space-3) var(--space-2) var(--space-1);
  color: var(--color-text-muted);
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
}

.search-group-label:first-child { margin-top: var(--space-1); }

.search-hit {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-2);
  border-radius: var(--radius-md);
  color: var(--color-text);
  text-decoration: none;
  transition: background-color var(--duration-fast) var(--ease-out-quart);
}

.search-hit:hover,
.search-hit[aria-selected="true"] {
  background: var(--color-surface-muted);
}

.search-hit:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: -2px;
}

.search-hit-icon {
  width: 18px;
  height: 18px;
  flex: 0 0 18px;
  color: var(--color-text-soft);
}

.search-hit-main {
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.search-hit-title {
  font-size: var(--text-sm);
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.search-hit-sub {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.search-empty {
  padding: var(--space-3) var(--space-2);
  color: var(--color-text-muted);
  font-size: var(--text-sm);
}

/* Review #11 — match highlighting: WHY a hit row matched (e.g. an
   email-domain match, not the name). Subtle, tokens only. */
.search-mark {
  background: var(--sky-100);
  border-radius: 2px;
  padding: 0 1px;
  font-weight: 600;
}

/* /search full results page: same .search-hit rows, stacked with a little
   more breathing room than the compact dropdown. */
.search-hit-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.search-hit-list .search-hit { padding: var(--space-3) var(--space-2); }

@media (max-width: 640px) {
  .topbar { padding: var(--space-3) var(--space-4); }
  .global-search { max-width: none; }
}

/* ============ Sidebar (own navy context) ============ */
.sidebar {
  width: 240px;
  flex: 0 0 240px;
  background: var(--sidebar-bg);
  color: var(--sidebar-text);
  display: flex;
  flex-direction: column;
  padding: var(--space-6) var(--space-4);
  box-sizing: border-box;
}

.brand {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-xl);
  letter-spacing: var(--tracking-snug);
  color: var(--sidebar-text);
  padding: 0 var(--space-3) var(--space-6);
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.brand-mark { flex-shrink: 0; }

.nav { display: flex; flex-direction: column; gap: 2px; }

.nav-item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-pill);
  color: var(--sidebar-text);
  text-decoration: none;
  font-size: var(--text-sm);
  font-weight: 500;
  transition: background-color var(--duration-fast) var(--ease-out-quart),
              color var(--duration-fast) var(--ease-out-quart);
}

.nav-item:hover { background: var(--sidebar-hover-bg); }

.nav-item.is-active {
  background: var(--sidebar-active-bg);
  color: var(--sidebar-active-text);
  font-weight: 600;
}

.nav-icon { width: 18px; height: 18px; flex: 0 0 18px; }

.nav-label { flex: 1; min-width: 0; }

.nav-count {
  font-size: var(--text-xs);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: inherit;
  opacity: 0.85;
}

.nav-item.is-active .nav-count { opacity: 1; }

/* ============ Sidebar expandable submenu (Informes department submenu,
   Preline-style reference, 2026-07-29) ============ */

.nav-group { display: flex; flex-direction: column; }

.nav-item-parent { justify-content: space-between; }

.nav-chevron {
  width: 16px;
  height: 16px;
  flex: 0 0 16px;
  transition: transform var(--duration-fast) var(--ease-out-quart);
}

/* Points right when collapsed, rotates down when the submenu is expanded. */
.nav-item-parent[aria-expanded="true"] .nav-chevron { transform: rotate(90deg); }

.nav-children {
  list-style: none;
  margin: 2px 0 0;
  padding: 2px 0 2px var(--space-4);
  display: flex;
  flex-direction: column;
  gap: 2px;
  /* the subtle left rail marking the indented child group */
  border-left: 1px solid var(--sidebar-hover-bg);
  margin-left: var(--space-4);
}

.nav-children[hidden] { display: none; }

.nav-micro-label {
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--sidebar-text-soft);
  padding: var(--space-2) var(--space-3) 2px;
}

.nav-child {
  display: block;
  padding: 6px var(--space-3);
  border-radius: var(--radius-pill);
  color: var(--sidebar-text-soft);
  text-decoration: none;
  font-size: var(--text-sm);
  font-weight: 500;
  transition: background-color var(--duration-fast) var(--ease-out-quart),
              color var(--duration-fast) var(--ease-out-quart);
}

.nav-child:hover { background: var(--sidebar-hover-bg); color: var(--sidebar-text); }

.nav-child.is-active {
  background: var(--sidebar-active-bg);
  color: var(--sidebar-active-text);
  font-weight: 600;
}

/* Keyboard focus rings (sidebar is dark → use a light ring). Language switch
   + Salir moved OUT of the sidebar footer into the topbar avatar menu
   (2026-07-29 restructure, see ".avatar-menu" below) — .sidebar-foot/
   .nav-logout retired along with it. */
.nav-item:focus-visible,
.nav-child:focus-visible {
  outline: 2px solid var(--sidebar-active-bg);
  outline-offset: 2px;
}

/* ============ Topbar avatar account menu ============
   2026-07-29 restructure: a native <details>/<summary> disclosure (works
   with zero JS — avatar_menu.js only adds close-on-click-outside/Escape on
   top) holding the operator identity header, the ES|EN language switch, and
   Salir — all MOVED here from the old navy sidebar footer, hence the
   .lang-switch rules below being restyled for a light surface panel instead
   of the dark sidebar (same markup/class names, new context). */
.avatar-menu {
  position: relative;
  flex: 0 0 auto;
}

.avatar-menu-trigger {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  cursor: pointer;
  list-style: none;
  padding: var(--space-1);
  border-radius: var(--radius-md);
}

.avatar-menu-trigger::-webkit-details-marker { display: none; }
.avatar-menu-trigger::marker { content: ""; }

.avatar-menu-trigger:hover { background: var(--color-surface-muted); }

.avatar-menu-trigger:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
}

.avatar-circle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  flex: 0 0 32px;
  border-radius: 50%;
  background: var(--navy-800);
  color: #fff;
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: var(--text-xs);
}

.avatar-menu-chevron {
  width: 16px;
  height: 16px;
  color: var(--color-text-soft);
  transition: transform var(--duration-fast) var(--ease-out-quart);
}

.avatar-menu[open] .avatar-menu-chevron { transform: rotate(180deg); }

.avatar-menu-panel {
  position: absolute;
  top: calc(100% + var(--space-2));
  right: 0;
  min-width: 240px;
  box-sizing: border-box;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  padding: var(--space-3);
  z-index: 30;
}

.avatar-menu-header { padding: 0 var(--space-2) var(--space-2); }

.avatar-menu-name {
  margin: 0;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-text);
}

.avatar-menu-email {
  margin: var(--space-1) 0 0;
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

.avatar-menu-divider {
  height: 1px;
  background: var(--color-border);
  margin: var(--space-2) 0;
}

.avatar-menu-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  box-sizing: border-box;
  padding: var(--space-2);
  border: 0;
  background: transparent;
  color: var(--color-text);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  font-weight: 500;
  border-radius: var(--radius-md);
  cursor: pointer;
  text-align: left;
}

.avatar-menu-row:hover { background: var(--color-surface-muted); }

.avatar-menu-row:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: -2px;
}

.avatar-menu-logout { color: var(--color-danger); }

/* i18n foundation: the compact ES | EN switch, now inside the avatar panel
   (light surface — was the navy sidebar footer before this restructure). */
.avatar-menu-panel .lang-switch {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-2);
}

.avatar-menu-panel .lang-switch .lang-current,
.avatar-menu-panel .lang-switch .lang-option {
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-snug);
}

.avatar-menu-panel .lang-switch .lang-current { color: var(--color-text); }

.avatar-menu-panel .lang-switch .lang-option {
  border: 0;
  background: transparent;
  color: var(--color-text-muted);
  cursor: pointer;
  padding: 2px 4px;
  border-radius: var(--radius-sm, 4px);
}

.avatar-menu-panel .lang-switch .lang-option:hover,
.avatar-menu-panel .lang-switch .lang-option:focus-visible {
  background: var(--color-surface-muted);
  color: var(--color-text);
}

.avatar-menu-panel .lang-switch .lang-option:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
}

.avatar-menu-panel .lang-switch .lang-sep {
  color: var(--color-text-soft);
  opacity: 0.6;
  font-size: var(--text-xs);
}

/* ============ Connected / login fallback card ============ */
.card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-10) var(--space-12);
  text-align: center;
}

.card p { color: var(--color-text-muted); margin: 0; font-size: var(--text-base); }

/* The login card's h1 IS the wordmark (same role as the sidebar .brand) —
   it must use the display face, not the generic serif h1 default, or the
   very first thing an operator sees reads like a headline rather than the
   Clintel mark. */
.brand-login {
  font-family: var(--font-display);
  color: var(--color-primary);
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

/* ============ Inbox: list + reading panes ============ */
.content-body.inbox { display: flex; align-items: stretch; }

/* Message list (middle pane) */
.msg-list {
  flex: 0 0 360px;
  width: 360px;
  display: flex;
  flex-direction: column;
  border-right: 1px solid var(--color-border);
  background: var(--color-surface);
  min-height: 100vh;
  box-sizing: border-box;
}

.msg-list-head {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  padding: var(--space-6) var(--space-5) var(--space-4);
  border-bottom: 1px solid var(--color-border);
}

.msg-list-count {
  font-size: var(--text-sm);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--color-text-muted);
}

.msg-rows { list-style: none; margin: 0; padding: 0; overflow-y: auto; }

/* Rows are native <a>: strip the link chrome so they read as rows, not links. */
.msg-row {
  display: flex;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--color-border);
  cursor: pointer;
  text-decoration: none;
  color: inherit;
  transition: background-color var(--duration-fast) var(--ease-out-quart);
}

.msg-row:hover { background: var(--color-surface-muted); }
.msg-row.is-active { background: var(--color-primary-soft); }

.msg-row:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: -2px;
}

.urgency-dot {
  flex: 0 0 8px;
  width: 8px; height: 8px;
  margin-top: 6px;
  border-radius: 50%;
  /* Pendiente (no enrichment): neutral. The --urgency-dot--* variants paint a
     solid dot from the ramp's saturated border hue (the legible ramp anchor). */
  background: var(--ink-300);
}

.urgency-dot--low  { background: var(--urgency-low-border); }
.urgency-dot--med  { background: var(--urgency-med-border); }
.urgency-dot--high { background: var(--urgency-high-border); }
.urgency-dot--crit { background: var(--urgency-crit-border); }

.msg-main { flex: 1; min-width: 0; }

.msg-top {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  margin-bottom: 2px;
}

.msg-sender {
  flex: 1;
  min-width: 0;
  font-weight: 600;
  font-size: var(--text-sm);
  color: var(--color-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.msg-time {
  flex: 0 0 auto;
  font-size: var(--text-xs);
  /* ink-600: AA on white (6.9:1) and on the row hover/active tints (>6:1).
     ink-500 would drop to 4.21:1 on the hover tint and fail. */
  color: var(--ink-600);
  font-variant-numeric: tabular-nums;
}

.msg-subject {
  font-size: var(--text-sm);
  color: var(--color-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.msg-snippet {
  font-size: var(--text-sm);
  /* ink-600 so it stays AA on white and on the row hover/active tints. */
  color: var(--ink-600);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Reading pane (right) */
.reading {
  flex: 1;
  min-width: 0;
  overflow-y: auto;
  min-height: 100vh;
  box-sizing: border-box;
}

.read { padding: var(--space-8); max-width: 1180px; }

/* Two-column reading pane (design p.3): message body | Asistente IA. The AI
   column is a fixed, comfortable width; the body takes the rest. Below ~1100px
   the grid collapses to one column (AI below the body) so it never overflows. */
.read-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 340px;
  gap: var(--space-8);
  align-items: start;
}

.read-col-body { min-width: 0; }

@media (max-width: 1100px) {
  .read-grid { grid-template-columns: minmax(0, 1fr); gap: var(--space-6); }
}

.read-head { padding-bottom: var(--space-5); border-bottom: 1px solid var(--color-border); }

.read-head-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
}

.read-subject { flex: 1; min-width: 0; }

/* Focus target after an htmx swap (it carries tabindex="-1"). Keep the move
   discreet — a soft ring, not the loud row outline. */
.read-subject:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 4px;
  border-radius: var(--radius-xs);
}

.read-date {
  flex: 0 0 auto;
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
}

.read-from {
  margin: var(--space-3) 0 0;
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
  font-size: var(--text-sm);
}

.read-from-name { font-weight: 600; color: var(--color-text); }
.read-from-addr { color: var(--color-text-muted); }

/* AI one-line strip: quiet info tint, never coral. Sits at the top of the AI
   column, right under its label. */
.ai-strip {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--color-info-border);
  background: var(--color-info-surface);
  border-radius: var(--radius-pill);
  /* sky-700-level info text: AA-passing (5.46:1) on the sky-50 surface;
     --color-info (sky-600) only reaches 3.67:1 here. */
  color: var(--sky-700);
  font-size: var(--text-sm);
  font-weight: 600;
  width: fit-content;
}

.ai-strip-icon { width: 16px; height: 16px; }

.read-body {
  margin-top: var(--space-6);
  max-width: 68ch;
  white-space: pre-wrap;
  line-height: 1.5;
  font-size: var(--text-base);
  color: var(--color-text);
  word-break: break-word;
}

/* Asistente IA: the right column — a section set off by a left hairline divider,
   never a card. On the stacked layout the divider moves to the top instead. */
.ai-pane {
  padding-left: var(--space-8);
  border-left: 1px solid var(--color-border);
}

@media (max-width: 1100px) {
  .ai-pane {
    padding-left: 0;
    padding-top: var(--space-6);
    border-left: 0;
    border-top: 1px solid var(--color-border);
  }
}

.ai-pane-label,
.thread-label {
  margin: 0 0 var(--space-3);
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--color-text-muted);
}

.ai-rows { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-3); }

.ai-row { display: flex; flex-direction: column; gap: 2px; }

.ai-row-label { font-size: var(--text-sm); font-weight: 600; color: var(--color-text); }

.ai-row-empty {
  font-size: var(--text-sm);
  /* Real content (not a faint hint): --color-text-soft (ink-400) is only
     2.66:1 on white. --color-text-muted (ink-500) reaches AA (4.55:1). */
  color: var(--color-text-muted);
  font-style: italic;
}

.ai-row-value {
  font-size: var(--text-sm);
  color: var(--color-text);
  line-height: 1.45;
}

/* ---- Filled AI strip (enrichment present) ---- */
/* When filled the strip carries a summary sentence, so it grows past a pill:
   keep the info tint but let it wrap and align its glyphs to the first line. */
.ai-strip--filled,
.ai-strip--failed {
  width: auto;
  align-items: flex-start;
  border-radius: var(--radius-lg);
  font-weight: 500;
  line-height: 1.4;
  flex-wrap: wrap;
}

.ai-strip--filled .ai-strip-text,
.ai-strip--failed .ai-strip-text { flex: 1; min-width: 0; }

.ai-strip--filled .ai-strip-icon,
.ai-strip--failed .ai-strip-icon { margin-top: 2px; flex: 0 0 auto; }

/* Failed: a quiet warning tint, not alarm-red. */
.ai-strip--failed {
  border-color: var(--color-warning-border);
  background: var(--color-warning-surface);
  color: var(--color-warning);
}

/* ---- Urgency badge: the 4-hue clinical ramp ---- */
.urgency-badge {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  padding: 2px var(--space-2);
  border-radius: var(--radius-pill);
  border: 1px solid transparent;
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
}

.urgency-badge--low  { background: var(--urgency-low-bg);  border-color: var(--urgency-low-border);  color: var(--urgency-low-text); }
.urgency-badge--med  { background: var(--urgency-med-bg);  border-color: var(--urgency-med-border);  color: var(--urgency-med-text); }
.urgency-badge--high { background: var(--urgency-high-bg); border-color: var(--urgency-high-border); color: var(--urgency-high-text); }
.urgency-badge--crit { background: var(--urgency-crit-bg); border-color: var(--urgency-crit-border); color: var(--urgency-crit-text); }

/* ---- Sentiment glyph: quiet, monochrome — never a colored pill ---- */
.sentiment-glyph {
  flex: 0 0 auto;
  display: inline-flex;
  color: var(--color-text-muted);
}
.sentiment-glyph svg { width: 18px; height: 18px; }

/* ---- Open items ---- */
.open-items { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }

.open-item {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  font-size: var(--text-sm);
  color: var(--color-text);
}

.open-item-icon { width: 14px; height: 14px; flex: 0 0 auto; color: var(--color-text-muted); align-self: center; }
.open-item-text { flex: 1; min-width: 0; }
.open-item-meta { flex: 0 0 auto; font-size: var(--text-xs); color: var(--color-text-muted); }

/* ---- Tone trend trajectory ---- */
.tone-trend {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  color: var(--color-text);
}
.tone-trend-icon { width: 16px; height: 16px; color: var(--color-text-muted); }
.tone-trend--improving .tone-trend-icon { color: var(--color-success); }
.tone-trend--deteriorating .tone-trend-icon { color: var(--color-danger); }

/* ---- Suggested reply: shown, never sent. Copy only. ---- */
.reply-draft {
  margin-top: 2px;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface-muted);
}

.reply-draft-text {
  margin: 0;
  white-space: pre-wrap;
  font-size: var(--text-sm);
  line-height: 1.5;
  color: var(--color-text);
}

.reply-copy-btn,
.reenrich-btn {
  margin-top: var(--space-3);
  padding: var(--space-1) var(--space-3);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-pill);
  background: var(--color-surface);
  color: var(--color-text);
  font-size: var(--text-xs);
  font-weight: 600;
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease-out-quart);
}

.reenrich-btn { margin-top: 0; }

.reply-copy-btn:hover,
.reenrich-btn:hover { background: var(--color-surface-muted); }

.reply-copy-btn:focus-visible,
.reenrich-btn:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
}

.reenrich-form { margin: 0; flex: 0 0 auto; }

/* Thread */
.thread {
  margin-top: var(--space-8);
  padding-top: var(--space-5);
  border-top: 1px solid var(--color-border);
}

.thread-rows { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }

.thread-row {
  display: flex;
  gap: var(--space-3);
  align-items: baseline;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  cursor: pointer;
  text-decoration: none;
  color: inherit;
  transition: background-color var(--duration-fast) var(--ease-out-quart);
}

.thread-row:hover { background: var(--color-surface-muted); }

.thread-row:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: -2px;
}

.thread-row-date {
  flex: 0 0 auto;
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
}

.thread-row-snippet {
  flex: 1;
  min-width: 0;
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Empty states */
.empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
  padding: var(--space-16) var(--space-8);
  text-align: center;
  margin: auto;
}

.empty-title { margin: 0; font-weight: 600; color: var(--color-text); font-size: var(--text-base); }
.empty-sub { margin: 0; color: var(--color-text-muted); font-size: var(--text-sm); }

/* ============ Accessibility utilities ============ */

/* Visually hidden, still in the accessibility tree (headings, labels). */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Skip link: off-screen until focused, then pins to the top-left. */
.skip-link {
  position: absolute;
  left: var(--space-2);
  top: -100%;
  z-index: 100;
  padding: var(--space-2) var(--space-4);
  background: var(--color-surface);
  color: var(--color-primary);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-pill);
  font-size: var(--text-sm);
  font-weight: 600;
  text-decoration: none;
  transition: top var(--duration-fast) var(--ease-out-quart);
}

.skip-link:focus { top: var(--space-2); }

/* ============ Tasks board ============ */

/* Page shell */
.tasks-page {
  flex: 1;
  min-width: 0;
  padding: var(--space-8);
  overflow-y: auto;
  box-sizing: border-box;
}

.tasks-head {
  margin-bottom: var(--space-6);
}

/* Header row that also carries the "+ Nueva tarea" pop-CTA (the single
   coral .btn-accent for this view) top-right of the board heading. */
.tasks-head-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}

/* Board section headings: Source Serif 4 (inherits h2 rule above). */
.board-section-heading {
  font-family: var(--font-serif);
  font-size: var(--text-xl);
  color: var(--color-text);
  margin: 0 0 var(--space-4);
  letter-spacing: var(--tracking-tight);
}

/* Más urgente rail */
.urgent-rail {
  margin-bottom: var(--space-8);
  padding-bottom: var(--space-6);
  border-bottom: 1px solid var(--color-border);
}

.urgent-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
}

.urgent-card {
  flex: 0 0 280px;
  max-width: 320px;
}

/* Board columns — compact FIXED-width lanes (Bigin-style density) so 7-8
   columns sit comfortably before scrolling, rather than a `1fr` track that
   balloons each lane to fill the viewport and caps the row at ~5 columns.
   Columns stay left-aligned and uniform width; SCROLLS horizontally only
   once there are genuinely more columns than fit. The scroll lives inside
   .board, never on the page body — .tasks-page keeps its own
   vertical-only overflow above. */
.board {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 244px;
  gap: var(--space-4);
  align-items: start;
  overflow-x: auto;
}

/* Column — a colored top accent + header dot + tinted count make each stage
   distinct (the ramp/brand palette, not blue-on-grey). */
.board-col {
  background: var(--color-surface-muted);
  border: 1px solid var(--color-border);
  border-top: 3px solid var(--color-border-strong);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  min-height: 120px;
  box-sizing: border-box;
  transition: background-color var(--duration-fast) var(--ease-out-quart),
              border-color var(--duration-fast) var(--ease-out-quart);
}

.board-col[data-col-status="suggested"]   { border-top-color: var(--sky-500); }
.board-col[data-col-status="pending"]     { border-top-color: var(--sky-500); }
.board-col[data-col-status="assigned"]    { border-top-color: var(--navy-500); }
.board-col[data-col-status="in_progress"] { border-top-color: var(--butter-600); }
.board-col[data-col-status="issue"]       { border-top-color: var(--rose-500); }
.board-col[data-col-status="completed"]   { border-top-color: var(--leaf-500); }

/* Drag-over highlight */
.board-col.drag-over {
  background: var(--color-primary-soft);
  border-color: var(--color-primary);
}

.board-col-heading {
  font-family: var(--font-serif);
  font-size: var(--text-lg);
  color: var(--color-text);
  margin: 0 0 var(--space-3);
  letter-spacing: var(--tracking-tight);
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.board-col-heading::before {
  content: "";
  width: 9px;
  height: 9px;
  border-radius: 50%;
  flex: 0 0 9px;
  background: var(--color-border-strong);
}

.board-col[data-col-status="suggested"]   .board-col-heading::before { background: var(--sky-500); }
.board-col[data-col-status="pending"]     .board-col-heading::before { background: var(--sky-500); }
.board-col[data-col-status="assigned"]    .board-col-heading::before { background: var(--navy-500); }
.board-col[data-col-status="in_progress"] .board-col-heading::before { background: var(--butter-600); }
.board-col[data-col-status="issue"]       .board-col-heading::before { background: var(--rose-500); }
.board-col[data-col-status="completed"]   .board-col-heading::before { background: var(--leaf-500); }

/* ============ Category filter (the /tasks status board's category chips) ============
   Unified Task model: the board is always the status kanban; category is a
   FILTER strip on top, not a separate set of columns (retired playbook
   board). Same chip styling as the former playbook-selector view switch. */
.category-filter {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: 0 0 var(--space-5);
}

.category-chip {
  display: inline-flex;
  align-items: center;
  padding: var(--space-1) var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-pill);
  color: var(--color-text-muted);
  font-size: var(--text-sm);
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
  background: var(--color-surface);
}

.category-chip:hover { color: var(--color-text); border-color: var(--color-border-strong); }

.category-chip.is-active {
  border-color: var(--color-primary);
  color: var(--color-primary);
  background: var(--color-primary-surface, var(--sky-50));
}

.board-col-count {
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--color-text-muted);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-pill);
  padding: 1px var(--space-2);
  margin-left: auto;
}

.board-col[data-col-status="suggested"]   .board-col-count { color: var(--sky-700);    background: var(--sky-50);    border-color: var(--sky-100); }
.board-col[data-col-status="pending"]     .board-col-count { color: var(--sky-700);    background: var(--sky-50);    border-color: var(--sky-100); }
.board-col[data-col-status="assigned"]    .board-col-count { color: var(--navy-700);   background: var(--navy-50);   border-color: var(--navy-200); }
.board-col[data-col-status="in_progress"] .board-col-count { color: var(--butter-700); background: var(--butter-50);  border-color: var(--butter-300); }
.board-col[data-col-status="issue"]       .board-col-count { color: var(--rose-600);   background: var(--rose-50);   border-color: var(--rose-100); }
.board-col[data-col-status="completed"]   .board-col-count { color: var(--leaf-700);   background: var(--leaf-50);   border-color: var(--leaf-100); }

.board-col-cards {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.board-col-empty,
.board-empty {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  font-style: italic;
}

/* Task card */
.task-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  cursor: grab;
  box-shadow: var(--shadow-xs);
  transition: border-color var(--duration-fast) var(--ease-out-quart),
              box-shadow var(--duration-fast) var(--ease-out-quart);
}

.task-card:hover {
  border-color: var(--color-border-strong);
  box-shadow: var(--shadow-sm);
}

/* Completed cards de-emphasise: the work is finished, not the focus. */
.task-card.is-completed { opacity: 0.9; }
.task-card.is-completed .task-title { color: var(--color-text-muted); }

.task-card:focus-visible {
  outline: 2px solid var(--color-ring, var(--color-focus-ring));
  outline-offset: 2px;
}

.task-card:active { cursor: grabbing; }

/* SLA-breached card: quiet warning tint, not alarm-red. */
.task-card--sla {
  border-color: var(--color-warning-border);
  background: var(--color-warning-surface);
}

/* Dragging state */
.task-card.is-dragging {
  opacity: 0.45;
  box-shadow: var(--shadow-md);
}

/* Top row: labels (type + priority) left, SLA badge right */
.task-card-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
  min-height: 16px;
}

.task-card-labels {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1) var(--space-2);
}

/* Tag pill (legacy suggestion category) */
.task-tag {
  display: inline-flex;
  align-items: center;
  padding: 1px var(--space-2);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-pill);
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--color-text-muted);
  background: var(--color-surface-muted);
}

/* Type tag — navy for projects, sky for to-dos. */
.task-type {
  display: inline-flex;
  align-items: center;
  padding: 1px var(--space-2);
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
}

.task-type.is-project { color: var(--navy-700); background: var(--navy-50); border-color: var(--navy-200); }
.task-type.is-todo    { color: var(--sky-700);  background: var(--sky-50);  border-color: var(--sky-100); }

/* Category tag — the card's prominent chip in the unified Task model
   (replaces the removed Proyecto/Tarea type chip as the card's leading
   label); reuses the navy tint .task-type.is-project used to carry. */
.task-category {
  display: inline-flex;
  align-items: center;
  padding: 1px var(--space-2);
  border: 1px solid var(--navy-200);
  border-radius: var(--radius-pill);
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--navy-700);
  background: var(--navy-50);
}

/* /documents visibility chip: Cliente gets a leaf (success) tint on top of
   the neutral .task-tag base, same "reuse the pill, tint by role colour"
   pattern as .task-type above — Interno stays the plain neutral .task-tag. */
.task-tag.is-client {
  color: var(--color-success);
  background: var(--color-success-surface);
  border-color: var(--color-success-border);
}

/* Priority pill — the urgency ramp carries the level. */
.prio-pill {
  display: inline-flex;
  align-items: center;
  padding: 1px var(--space-2);
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  font-size: var(--text-2xs);
  font-weight: 600;
  white-space: nowrap;
}

.prio-pill.is-low,    .prio-pill.is-urg-low  { color: var(--urgency-low-text);  background: var(--urgency-low-bg);  border-color: var(--urgency-low-border); }
.prio-pill.is-normal                         { color: var(--sky-700);           background: var(--sky-50);          border-color: var(--sky-100); }
.prio-pill.is-urg-med                        { color: var(--urgency-med-text);  background: var(--urgency-med-bg);  border-color: var(--urgency-med-border); }
.prio-pill.is-high,   .prio-pill.is-urg-high { color: var(--urgency-high-text); background: var(--urgency-high-bg); border-color: var(--urgency-high-border); }
.prio-pill.is-urgent, .prio-pill.is-urg-crit { color: var(--urgency-crit-text); background: var(--urgency-crit-bg); border-color: var(--urgency-crit-border); }

/* Status pill — the expediente Estado chip + Subtareas status chips (CRM
   de-box pass). Mirrors the board-column status colours (~line 855 above):
   pending=sky, assigned=navy, in_progress=butter, issue=rose, completed=leaf,
   cancelled=neutral (same shape/sizing as .prio-pill). */
.status-pill {
  display: inline-flex;
  align-items: center;
  padding: 1px var(--space-2);
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  font-size: var(--text-2xs);
  font-weight: 600;
  white-space: nowrap;
}

.status-pill.is-pending     { color: var(--sky-700);    background: var(--sky-50);    border-color: var(--sky-100); }
.status-pill.is-assigned    { color: var(--navy-700);   background: var(--navy-50);   border-color: var(--navy-200); }
.status-pill.is-in_progress { color: var(--butter-700); background: var(--butter-50);  border-color: var(--butter-300); }
.status-pill.is-issue       { color: var(--rose-600);   background: var(--rose-50);    border-color: var(--rose-100); }
.status-pill.is-completed   { color: var(--leaf-700);   background: var(--leaf-50);    border-color: var(--leaf-100); }
.status-pill.is-cancelled   { color: var(--color-text-muted); background: var(--color-surface-muted); border-color: var(--color-border-strong); }

/* SLA breach badge. */
.sla-pill {
  display: inline-flex;
  align-items: center;
  padding: 1px var(--space-2);
  border: 1px solid var(--color-danger-border);
  border-radius: var(--radius-pill);
  font-size: var(--text-2xs);
  font-weight: 600;
  white-space: nowrap;
  color: var(--color-danger);
  background: var(--color-danger-surface);
}

/* Title */
.task-title {
  margin: 0 0 var(--space-2);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-text);
  line-height: 1.4;
}

.task-title-link {
  color: inherit;
  text-decoration: none;
}

.task-title-link:hover { text-decoration: underline; }

.task-title-link:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
  border-radius: var(--radius-xs);
}

/* Description */
.task-desc {
  margin: 0 0 var(--space-2);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  line-height: 1.45;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Meta row */
.task-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}

/* Community chip — a navy tint, so the account each card belongs to reads at a glance. */
.task-community {
  display: inline-flex;
  align-items: center;
  padding: 1px var(--space-2);
  border: 1px solid var(--navy-100);
  border-radius: var(--radius-pill);
  font-size: var(--text-2xs);
  font-weight: 600;
  color: var(--navy-700);
  background: var(--navy-50);
}

.task-due {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
}

.task-due.is-overdue { color: var(--color-danger); font-weight: 600; }

.task-due-icon {
  width: 12px;
  height: 12px;
  flex: 0 0 12px;
}

/* Footer: assignee avatar (left) + status actions (right), hairline-separated. */
.task-card-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border);
}

.task-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  flex: 0 0 26px;
  border-radius: 50%;
  background: var(--navy-100);
  color: var(--navy-700);
  font-size: var(--text-2xs);
  font-weight: 700;
}

.task-avatar.is-empty { background: transparent; }

/* Actions row */
.task-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  justify-content: flex-end;
}

.task-action-form { margin: 0; }

/* Glance data (replaces the old move-button pills) — the ref code + a
   relative last-activity signal, quiet and compact so the card content
   still leads. Moving cards is drag-and-drop (tasks.js) or the expediente's
   status/stage selects, not a footer button. */
.task-glance {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  justify-content: flex-end;
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

.task-refcode {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--navy-700);
}

.task-updated {
  white-space: nowrap;
}

/* Accent button: coral, the SINGLE commit action per card (Añadir on suggested). */
.btn-accent {
  display: inline-flex;
  align-items: center;
  padding: var(--space-1) var(--space-3);
  background: var(--color-accent);
  color: var(--paper);
  border: 1px solid var(--color-accent);
  border-radius: var(--radius-pill);
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  font-weight: 600;
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease-out-quart),
              border-color var(--duration-fast) var(--ease-out-quart),
              transform var(--duration-fast) var(--ease-out-quart);
}

.btn-accent:hover {
  background: var(--color-accent-hover);
  border-color: var(--color-accent-hover);
}

.btn-accent:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
}

/* Primary button: solid navy pill — the Equipo redesign's ".range" filter
   CTA. A third tier alongside .btn-accent (coral, single commit action) and
   .btn-ghost (neutral hairline) — reusable wherever a filter/form wants a
   filled brand-navy submit rather than the ghost default. */
/* .btn-ghost.is-dirty (review #16, Usuarios grid unsaved-changes indicator)
   reuses this exact rule: a checkbox edit marks its row's Guardar button
   dirty, and it should look like a filled-navy .btn-primary CTA (not a new
   style) while staying textually "Guardar". */
.btn-primary,
.btn-ghost.is-dirty {
  display: inline-flex;
  align-items: center;
  padding: var(--space-2) var(--space-4);
  background: var(--color-primary);
  color: #fff;
  border: 1px solid var(--color-primary);
  border-radius: var(--radius-pill);
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  font-weight: 700;
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease-out-quart),
              transform var(--duration-fast) var(--ease-out-quart);
}

.btn-primary:hover,
.btn-ghost.is-dirty:hover { background: var(--color-primary-hover); border-color: var(--color-primary-hover); }

.btn-primary:focus-visible,
.btn-ghost.is-dirty:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
}

/* Ghost button: neutral hairline pill for all non-coral actions (move, dismiss). */
.btn-ghost {
  display: inline-flex;
  align-items: center;
  padding: var(--space-1) var(--space-3);
  background: var(--color-surface);
  color: var(--color-text);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-pill);
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  font-weight: 500;
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease-out-quart),
              transform var(--duration-fast) var(--ease-out-quart);
}

.btn-ghost:hover { background: var(--color-surface-muted); }

.btn-ghost:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
}

/* Press feel (Emil — "scale your buttons"): a barely-there scale(0.99) on
   :active across all three button tiers, immediate tactile feedback without
   the unnatural "popping back" a bigger scale would cause. */
.btn-accent:active,
.btn-primary:active,
.btn-ghost:active,
.btn-ghost.is-dirty:active {
  transform: scale(0.99);
}

/* ============ Reply-SLA: inbox list badge ============ */

/* Quiet pill badge on the message row: urgency-ramp tint, not coral. */
.msg-sla-badge {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  margin-top: var(--space-1);
  padding: 1px var(--space-2);
  border: 1px solid var(--urgency-med-border);
  border-radius: var(--radius-pill);
  background: var(--urgency-med-bg);
  color: var(--urgency-med-text);
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  width: fit-content;
}

/* Breached: step up to the high ramp (the nudge is richer, not coral). */
.msg-sla-badge--breached {
  border-color: var(--urgency-high-border);
  background: var(--urgency-high-bg);
  color: var(--urgency-high-text);
}

.msg-sla-icon { width: 11px; height: 11px; flex: 0 0 11px; }

/* ============ Reply-SLA: reading pane alert strip ============ */

/* Urgency-tinted strip (not coral, not alarm-red). Sits inside the AI pane,
   above the suggested-task chips. */
.sla-strip {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-top: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--urgency-high-border);
  background: var(--urgency-high-bg);
  border-radius: var(--radius-md);
  color: var(--urgency-high-text);
}

.sla-strip-icon { width: 16px; height: 16px; flex: 0 0 16px; }

.sla-strip-text {
  font-size: var(--text-sm);
  font-weight: 600;
}

.sla-reply-hint { margin-top: var(--space-2); }

.sla-reply-hint-label {
  display: block;
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--urgency-high-text);
  margin-bottom: var(--space-1);
}

/* ============ Suggested task chips in reading pane ============ */

.suggested-tasks { margin-top: var(--space-5); }

.suggested-tasks-label {
  margin: 0 0 var(--space-2);
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--color-text-muted);
}

.suggested-task-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.suggested-task-chip {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-3);
  background: var(--color-surface);
}

.suggested-task-chip-body {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
  flex-wrap: wrap;
}

.suggested-task-title {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-text);
}

/* ============ Master: /master communities page ============ */
.master-page {
  flex: 1;
  min-width: 0;
  padding: var(--space-8);
  overflow-y: auto;
  box-sizing: border-box;
}

.master-head { margin-bottom: var(--space-6); }

.master-subhead {
  color: var(--color-text-muted);
  margin: 0;
  font-size: var(--text-base);
}

.master-back { margin: 0 0 var(--space-4); }
.master-back a { color: var(--color-text-muted); text-decoration: none; font-size: var(--text-sm); }
.master-back a:hover { color: var(--color-text); text-decoration: underline; }

.master-search {
  display: flex;
  gap: var(--space-2);
  margin-bottom: var(--space-6);
}

.master-search input[type="search"] {
  flex: 1;
  max-width: 320px;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
}

/* /documents document-manager filter row: search + community/scope/
   visibility selects + submit, one hairline-free flex row (mirrors
   .master-search/.contacts-search but with three selects instead of one). */
.doc-filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
}

.doc-filters input[type="search"] {
  flex: 1 1 220px;
  min-width: 180px;
  max-width: 320px;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
}

.doc-filters select {
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--color-text);
}

/* /documents pagination footer: "Mostrando X–Y de N" + Anterior/Siguiente. */
.pagination {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-top: var(--space-4);
}

.pagination-summary { color: var(--color-text-muted); font-size: var(--text-sm); }

.pagination-links {
  display: flex;
  gap: var(--space-2);
}

.master-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  margin-bottom: var(--space-6);
}

.master-card h2 {
  font-size: var(--text-lg);
  margin-bottom: var(--space-4);
}

.master-empty { color: var(--color-text-muted); margin: 0; }

/* P6 Task 7 — the one-time portal-invite link reveal: shown exactly once,
   right after the operator's own invite POST. */
.master-invite-reveal {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin: 0 0 var(--space-4);
  padding: var(--space-4);
  background: var(--color-warning-surface);
  border: 1px solid var(--color-warning-border);
  border-radius: var(--radius-md);
  color: var(--color-warning);
  font-size: var(--text-sm);
}

.master-invite-reveal input {
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  font-family: var(--font-mono, monospace);
  font-size: var(--text-xs);
  color: var(--color-text);
  background: var(--color-surface);
}

.master-form {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  align-items: flex-end;
}

.master-form label {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.master-form input,
.master-form select {
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--color-text);
  min-width: 200px;
}

/* GET/POST /tasks/new — the board's create-task form. Mirrors .master-form's
   label/input rhythm; description + submit sit on their own full-width row
   via .task-new-full. */
.task-new-form {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  max-width: 640px;
}

.task-new-form label {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  flex: 1 1 220px;
}

.task-new-form input,
.task-new-form select,
.task-new-form textarea {
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--color-text);
}

.task-new-form textarea {
  min-height: 100px;
  resize: vertical;
}

.task-new-form .task-new-full {
  flex: 1 1 100%;
}

.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
}

.data-table thead tr {
  background: var(--color-surface-header);
}

.data-table th {
  text-align: left;
  color: var(--color-text-muted);
  font-weight: 600;
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--color-border-strong);
}

.data-table td {
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--color-border);
  transition: background-color var(--duration-fast) var(--ease-out-quart),
              border-color var(--duration-fast) var(--ease-out-quart);
}

/* Row hover (fix E) — no zebra, just a quiet hover tint. Alert/overdue/
   under-served row tints (below) win over the hover tint since they carry
   real signal. */
.data-table tbody tr { transition: background-color var(--duration-fast) var(--ease-out-quart); }
.data-table tbody tr:hover { background: var(--ink-50); }
.data-table tbody tr:hover td { border-color: var(--color-border-strong); }

.data-table a { color: var(--color-primary); text-decoration: none; font-weight: 500; }
.data-table a:hover { text-decoration: underline; }

/* /master CRM index: a non-zero "Sin responder" cell reads in the same rose
   urgency tone as everywhere else (never a new palette) — the row itself
   stays untinted since the health pill already carries the served-level cue. */
.data-table td.is-alert { color: var(--urgency-high-text); font-weight: 600; }

/* P8.1: /insights/comparison — the over/under-served ranked table reuses
   .data-table + .master-card; these graduate the under-served rows with the
   SAME urgency tokens as the /tasks overdue row above, never a new palette.
   never-answered (worst) gets the strong high-urgency tint + the
   .insights-flag chip; answered-but-slower-than-SLA gets the lighter
   medium tint — a subtle cue on top of community_comparison's already
   under-served-first ordering. */
.data-table tr.is-under-served td { background: var(--urgency-high-bg); }
.data-table tr.is-slow td { background: var(--urgency-med-bg); }

.insights-flag {
  display: inline-flex;
  align-items: center;
  padding: 1px var(--space-2);
  border: 1px solid var(--urgency-high-border);
  border-radius: var(--radius-pill);
  background: var(--urgency-high-bg);
  color: var(--urgency-high-text);
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
}

/* The honest "figures count from <date>" note (response-time metrics, DR-6) —
   shared quiet-caption styling with .master-empty. */
.master-note { color: var(--color-text-muted); font-size: var(--text-sm); margin: 0 0 var(--space-4); }

/* ============ Folder tree (document folders) — shared primitive ============ */
/* Native <details>/<summary> recursion, no floating boxes. Lives in app.css
   (not crm.css) because the general /documents page loads only app.css; the
   community Documentos tab (crm.css + app.css) shares the same rules. */

.folder-tree {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.folder-node {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}

.folder-node + .folder-node {
  margin-top: var(--space-2);
}

.folder-node .folder-node {
  margin: var(--space-2) 0 0 var(--space-5);
}

.folder-summary {
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  background: var(--color-primary-soft);
  border-radius: var(--radius-md);
  font-weight: 500;
  color: var(--color-primary);
  list-style: none;
}

.folder-summary::-webkit-details-marker {
  display: none;
}

.folder-node[open] > .folder-summary {
  border-radius: var(--radius-md) var(--radius-md) 0 0;
}

.folder-icon {
  color: var(--color-primary);
}

.folder-node[open] > .folder-summary .folder-icon {
  transform: rotate(90deg);
  display: inline-block;
}

.folder-name {
  flex: 1;
}

.folder-count {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  font-weight: 400;
}

.folder-body {
  padding: var(--space-3);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.folder-doc-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.folder-doc-list-root {
  margin-bottom: var(--space-2);
}

.folder-doc-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  flex-wrap: wrap;
}

.folder-doc-link {
  flex: 1;
  min-width: 160px;
}

.folder-doc-size,
.folder-doc-date {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  white-space: nowrap;
}

.folder-move-form {
  display: flex;
  gap: var(--space-2);
  align-items: center;
}

.community-folder-root > summary.folder-summary {
  background: var(--color-primary);
  color: var(--color-bg);
}

/* ============ StatGroup + Record section — shared KPI/record primitives
   (CRM M1/M5: app/web/templates/master/actividad.html), also used by
   dashboard.html below. StatGroup is a bounded Gentelella-style tile grid
   (see the primitive itself, further down) — no shadow (brand); everything
   else here (.record-section-label etc.) stays hairline. Moved here from
   crm.css since dashboard.html doesn't load crm.css and both pages need
   them. ============ */

.record-section-label {
  margin: 0 0 var(--space-2);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--color-border);
  color: var(--color-text-muted);
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
}

.record-section-label + * {
  margin-top: var(--space-4);
}

/* Subtle sub-label INSIDE a .record-section (e.g. "En expedientes" under a
   community's pinned Notas) — same muted/uppercase/small treatment as
   .record-section-label but no hairline, so it reads as a subdivision of the
   section rather than a new section. */
.record-subsection-label {
  margin: var(--space-4) 0 var(--space-2);
  color: var(--color-text-muted);
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
}

/* StatGroup — bounded Gentelella-style KPI tiles (each stat a tile with a
   small tinted icon chip, big value, label), NOT the old hairline-divided
   row. Two variants, selected purely by context — no template class
   changes needed to switch between them:
     1. On-ground (.stat-group NOT inside a .panel): a grid of white
        bordered cards, no shadow (brand).
     2. In-panel (.panel .stat-group): tinted cells instead of nested
        cards — keeps the no-nested-panels rule while giving every
        in-panel stat row (record tabs, informe tab, insights cards,
        cumplimiento, master list) real structure automatically. */
.stat-group {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: var(--space-4);
  border: none;
  margin-bottom: var(--space-2);
}

.stat-item {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
  padding: var(--space-5);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  text-decoration: none;
  color: inherit;
  transition: border-color var(--duration-fast) var(--ease-out-quart),
              background-color var(--duration-fast) var(--ease-out-quart),
              transform var(--duration-fast) var(--ease-out-quart);
}

/* Only a LINKED stat-item (a.stat-item — record navigation shortcuts) lifts
   on hover; the plain KPI-tile divs (Mi día) stay put, they aren't clickable. */
a.stat-item:hover {
  border-color: var(--color-border-strong);
  transform: translateY(-1px);
}

.panel .stat-group .stat-item {
  background: var(--color-surface-muted);
  border: none;
  border-radius: var(--radius-md);
}

/* Icon-chip markup (additive, optional): .stat-icon + a .stat-item-body
   text wrapper (value/label/sub) as the two children of .stat-item — row
   instead of column, chip aligned to the top of the text block. */
.stat-item:has(.stat-icon) {
  flex-direction: row;
  align-items: flex-start;
  gap: var(--space-3);
}

.stat-item-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}

.stat-item-value {
  font-size: var(--text-3xl);
  font-weight: 700;
  line-height: 1;
  color: var(--color-primary);
  font-variant-numeric: tabular-nums;
}

.stat-item-label {
  font-size: var(--text-2xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--color-text-muted);
}

.stat-item.is-alert .stat-item-value { color: var(--urgency-high-text); }
a.stat-item:hover .stat-item-value { color: var(--color-primary); }

/* Icon chip — 38px tinted square, tint classes at low-alpha bg + full-
   strength stroke color (vivid viz ramp), inline Lucide SVGs (20px,
   stroke currentColor). */
.stat-icon {
  flex-shrink: 0;
  width: 38px;
  height: 38px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-lg);
}
.stat-icon svg { width: 20px; height: 20px; }

.stat-icon--navy  { color: #023467; background: rgba(2, 52, 103, .08); }
.stat-icon--sky   { color: #1D9BD8; background: rgba(29, 155, 216, .10); }
.stat-icon--leaf  { color: #2FAE60; background: rgba(47, 174, 96, .10); }
.stat-icon--amber { color: #F2A93B; background: rgba(242, 169, 59, .12); }
.stat-icon--rose  { color: var(--color-danger); background: var(--color-danger-surface); }

/* is-alert wins over whichever tint the template picked, so a chip never
   reads "fine" (navy/amber) next to an alert value. */
.stat-item.is-alert .stat-icon { color: var(--color-danger); background: var(--color-danger-surface); }

/* Third, muted line inside a .stat-item (e.g. "3 recibidos / 1 enviados"
   under the Correos count) — also usable as a standalone small note
   paragraph outside a stat-item (insights community card's SLA-hours
   footnote). Insights-originated (P8 UI de-box pass) but generic enough to
   live with the other StatGroup primitives. */
.insights-metric-sub {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

/* Compact SLA-met donut (marketing-infographic redesign follow-through,
   insights/_charts.html's donut() macro) — reused on master/informe.html's
   Informe tab (~96px) and insights/_community_card.html. Self-contained
   inline SVG attrs live in the macro itself; only the wrapper/caption chrome
   is here, mirroring insights.css's identical rule for the standalone AGM
   report (this page loads app.css instead, never insights.css). */
.chart-donut {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
}

.chart-donut-label {
  margin: 0;
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  text-align: center;
}

/* Ring-draw flourish (2026-07-30 motion pass) — the progress arc reveals
   itself once on load instead of appearing fully drawn. Console-only by
   construction: report.html loads insights.css, not app.css, so
   .chart-donut-arc/--donut-circumference (set inline by the shared
   donut() macro) are simply never read there — no extra gating needed to
   keep the printable AGM report static. */
@media (prefers-reduced-motion: no-preference) {
  .chart-donut-arc {
    animation: chart-donut-draw var(--duration-slow) var(--ease-out-quint) both;
  }
}

@keyframes chart-donut-draw {
  from { stroke-dashoffset: calc(var(--donut-circumference, 0) * 1px); }
  to   { stroke-dashoffset: 0; }
}

.informe-response-row {
  display: flex;
  align-items: center;
  gap: var(--space-6);
  flex-wrap: wrap;
}

.informe-response-row .stat-group {
  flex: 1 1 320px;
}

.informe-response-donut {
  flex-shrink: 0;
}

/* Health/served-level pill — moved here from crm.css (P8 UI de-box pass):
   /insights (dashboard.html/detail.html) extends base.html, which loads
   app.css only, not crm.css, so this shared indicator needs to live
   wherever both the /master record aside AND /insights read it. Role
   colours only (leaf=good/well-served, butter=warn/slow, rose=bad/
   under-served) — reused verbatim, never redefined per page. */
.health-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0 0 var(--space-5);
  padding: var(--space-1) var(--space-4);
  border-radius: var(--radius-pill);
  border: 1px solid transparent;
  font-size: var(--text-sm);
  font-weight: 500;
}

.health-pill.is-good {
  background: var(--color-success-surface);
  border-color: var(--color-success-border);
  color: var(--color-success);
}

.health-pill.is-warn {
  background: var(--color-warning-surface);
  border-color: var(--color-warning-border);
  color: var(--color-warning);
}

.health-pill.is-bad {
  background: var(--color-danger-surface);
  border-color: var(--color-danger-border);
  color: var(--color-danger);
}

/* Mirrors .chip .health-dot below — same solid currentColor circle, reused
   here so the health-pill's status glyph is a real styled element instead of
   a Unicode "●" character (screen readers announce the latter inconsistently
   across platforms/fonts). */
.health-pill .health-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }

/* Directory chip — /master/personas' Comunidades cell: one small pill per
   current membership ("Community · RoleLabel · Apt X"), muted rather than
   a status indicator (that's .health-pill's job). Several sit inline in one
   table cell, so keep them small + tightly spaced. */
.dir-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  margin: 0 var(--space-2) var(--space-1) 0;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  border: 1px solid var(--color-border);
  background: var(--color-surface-muted);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

.dir-chip a { color: var(--color-primary); text-decoration: none; font-weight: 500; }
.dir-chip a:hover { text-decoration: underline; }

/* /insights dashboard: one hairline-separated .record-section per
   community (replaces the old bordered .insights-card grid — P8 UI de-box
   pass), stacked with the same rhythm as .dashboard-sections. */
.insights-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
}

/* 2026-07-30 UI deep-dive part 2: the panel's HEADER ROW — community name
   (+ period) left, served-health pill right — rather than a stacked column,
   now that the outer .insights-community-section is a .panel and this is
   its title row (fix: "community name + health as the panel's header row"). */
.insights-card-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-5);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--color-border);
}

.insights-card-head-main {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}

.insights-card-head h2 { margin: 0; }

.insights-card-period {
  margin: 0;
  color: var(--color-text-muted);
  font-size: var(--text-sm);
}

/* Inline in the header row now, not stacked above the stat-groups. */
.insights-card-head .health-pill { margin: 0; flex: 0 0 auto; }

/* ============ Dashboard: home ("/") ============ */
.dashboard-page {
  flex: 1;
  min-width: 0;
  padding: var(--space-8);
  overflow-y: auto;
  box-sizing: border-box;
}

.dashboard-head { margin-bottom: var(--space-6); }

.dashboard-subline {
  margin: var(--space-1) 0 0;
  font-size: var(--text-xs);
}

.dashboard-subline a {
  color: var(--color-primary);
  text-decoration: none;
}

.dashboard-subline a:hover { text-decoration: underline; }

/* Three sections: open hairline-divided groups, not bordered cards. Reuses
   .record-section/.record-section-label from the StatGroup block above. */
.dashboard-sections {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
  gap: var(--space-8);
  align-items: start;
}

.dashboard-empty { color: var(--color-text-muted); margin: 0; }

/* Quiet empty-state treatment (2026-07-30 professional-finish pass): a small
   muted icon above the existing copy, centered with comfortable padding —
   not a new illustration/graphic, just enough presence that an empty Mi día
   block doesn't read as a rendering error. */
.dashboard-empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-6) var(--space-4);
  text-align: center;
}

.dashboard-empty-icon {
  width: 20px;
  height: 20px;
  color: var(--color-text-muted);
}

/* Overdue row: quiet high-ramp tint, matching .task-card--sla / .msg-sla-badge--breached. */
.data-table tr.is-overdue td { background: var(--urgency-high-bg); }

.chip-overdue {
  display: inline-flex;
  align-items: center;
  margin-left: var(--space-2);
  padding: 1px var(--space-2);
  border: 1px solid var(--urgency-high-border);
  border-radius: var(--radius-pill);
  background: var(--urgency-high-bg);
  color: var(--urgency-high-text);
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
}

/* Urgentes list: message rows with a leading urgency-badge chip. */
.dashboard-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }

.dashboard-list-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-1);
  border-radius: var(--radius-md);
  text-decoration: none;
  color: inherit;
  transition: background-color var(--duration-fast) var(--ease-out-quart);
}

.dashboard-list-row:hover { background: var(--color-surface-muted); }

.dashboard-list-main { display: flex; flex-direction: column; min-width: 0; }

.dashboard-list-title {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.dashboard-list-sub {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

/* A dashboard-list-title used as a link (Mi día's Mis tareas rows nest a
   real <a> inside the row instead of making the whole row a link, since the
   row also carries a due-date/pill slot that isn't part of the link). */
a.dashboard-list-title {
  color: var(--color-text);
  text-decoration: none;
}

a.dashboard-list-title:hover { color: var(--color-primary); text-decoration: underline; }

/* Trailing slot on a .dashboard-list-row (due date + state pill), pushed to
   the row's far edge — Mi día's Mis tareas list. */
.dashboard-list-side {
  margin-left: auto;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  white-space: nowrap;
}

.is-overdue-text { color: var(--urgency-high-text); font-weight: 600; }

/* Small solid dot leading an Actividad row — a real styled element (not a
   Unicode bullet) for consistent cross-platform/screen-reader rendering,
   mirroring .health-pill's .health-dot. */
.timeline-dot {
  width: 6px;
  height: 6px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--color-primary);
}

/* ============ Mi día: personalized home dashboard ("/") ============ */

.mi-dia-cuentas-banner { margin-bottom: var(--space-6); }
.mi-dia-kpis { margin-top: var(--space-6); margin-bottom: var(--space-8); }

/* Row 2: main column (Mis tareas / Actividad) + rail (Agenda / Asistente).
   Stacks to one column under 1000px. */
.mi-dia-grid {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: var(--space-8);
  align-items: start;
}

@media (max-width: 1000px) {
  .mi-dia-grid { grid-template-columns: 1fr; }
}

.mi-dia-main, .mi-dia-rail {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  min-width: 0;
}

/* Agenda: one date-heading group per day, entries listed under it. */
.agenda-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.agenda-date {
  margin: 0 0 var(--space-2);
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--color-text-muted);
}

.agenda-entries {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.agenda-entry {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  padding: var(--space-1) 0;
}

.agenda-dot {
  width: 8px;
  height: 8px;
  flex-shrink: 0;
  border-radius: 50%;
}

.agenda-dot--task    { background: var(--agenda-dot-task); }
.agenda-dot--renewal { background: var(--agenda-dot-renewal); }
.agenda-dot--cuentas { background: var(--agenda-dot-cuentas); }

.agenda-entry-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Asistente: a one-line prompt + inline search-style form, coral submit
   (the page's single accent action), then a compact Sugerencias list. */
.assistant-intro {
  margin: 0 0 var(--space-3);
  color: var(--color-text-muted);
  font-size: var(--text-sm);
}

.assistant-form {
  display: flex;
  gap: var(--space-2);
}

.assistant-form input[type="text"] {
  flex: 1;
  min-width: 0;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  font-family: var(--font-sans);
  color: var(--color-text);
  background: var(--color-surface);
}

.assistant-form input[type="text"]:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 1px;
}

.assistant-suggestions {
  margin-top: var(--space-5);
  padding-top: var(--space-5);
  border-top: 1px solid var(--color-border);
}

.assistant-suggestions-list {
  list-style: none;
  margin: 0 0 var(--space-2);
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.assistant-suggestions-list li {
  font-size: var(--text-sm);
  color: var(--color-text);
}

.assistant-suggestions-more {
  font-size: var(--text-xs);
}

.assistant-suggestions-more a { color: var(--color-primary); text-decoration: none; }
.assistant-suggestions-more a:hover { text-decoration: underline; }

/* ============ Filing queue: /inbox/filing ("Clasificar") ============ */
.filing-page {
  flex: 1;
  min-width: 0;
  padding: var(--space-8);
  overflow-y: auto;
  box-sizing: border-box;
}

.filing-head { margin-bottom: var(--space-6); }

.filing-intro {
  color: var(--color-text-muted);
  margin: 0;
  font-size: var(--text-base);
}

.filing-rows {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.filing-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-5) var(--space-6);
}

.filing-card-top {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  margin-bottom: var(--space-1);
}

.filing-sender { font-weight: 600; color: var(--color-text); font-size: var(--text-sm); }

.filing-sender-addr { color: var(--color-text-muted); font-size: var(--text-xs); }

.filing-time {
  margin-left: auto;
  color: var(--ink-600);
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
}

.filing-subject {
  margin: 0 0 var(--space-1);
  font-size: var(--text-sm);
  color: var(--color-text);
}

.filing-snippet {
  margin: 0 0 var(--space-3);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.filing-suggested-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}

.filing-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}

.filing-action-form { margin: 0; display: flex; align-items: center; gap: var(--space-2); }

.filing-file-form { flex-wrap: wrap; }

.filing-select-label select {
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--color-text);
  min-width: 200px;
}

/* Reading pane's inline community-assign row (reuses .filing-* forms above,
   just needs its own bottom margin to sit above the ai-strip). */
.community-assign {
  padding-bottom: var(--space-4);
  margin-bottom: var(--space-4);
  border-bottom: 1px solid var(--color-border);
}

/* ============ Item detail: /items/{id} ("Expediente") ============ */
.expediente-page {
  flex: 1;
  min-width: 0;
  padding: var(--space-8);
  overflow-y: auto;
  box-sizing: border-box;
}

/* .expediente-back retired 2026-07-29 (topbar restructure): the "← Tareas"/
   "← Documentos" back-links it styled are superseded by the topbar
   breadcrumb on items/detail.html and documents/detail.html. */

.expediente-head { margin-bottom: var(--space-6); }

.expediente-chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
}

/* Cancelled banner: quiet warning tint (matches .task-card--sla / .sla-strip
   — informational, not alarm-red, never coral). */
.expediente-cancelled-banner {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin: var(--space-2) 0 0;
  padding: var(--space-2) var(--space-3);
  background: var(--color-warning-surface);
  border: 1px solid var(--color-warning-border);
  border-radius: var(--radius-md);
  color: var(--color-warning);
  font-size: var(--text-sm);
  font-weight: 600;
}

.expediente-status-readonly { margin: 0; }

.expediente-parent { margin: var(--space-1) 0 0; font-size: var(--text-sm); color: var(--color-text-muted); }
.expediente-parent a { color: var(--color-primary); text-decoration: none; font-weight: 500; }
.expediente-parent a:hover { text-decoration: underline; }

/* .expediente-main: still used by documents/detail.html (a plain flex
   column wrapper around its .record-section blocks — NOT a card; that
   page never had the boxed .expediente-section card the expediente page
   used to). .expediente-body/.expediente-aside/.expediente-section (the
   boxed-card layout) were retired in the CRM de-box pass — /items/{id}
   now uses the shared .record-layout/.record-aside/.record-section
   primitives from crm.css/app.css instead. */
.expediente-main {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  min-width: 0;
}

.expediente-empty { color: var(--color-text-muted); margin: 0; font-size: var(--text-sm); }

.expediente-description { margin: 0; color: var(--color-text); font-size: var(--text-sm); white-space: pre-wrap; }

/* Historia — status-dot idiom: open/resolved/info map to the warning/
   success/info chip tones used elsewhere (urgency-badge, sla-strip). */
.timeline-rows { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-4); }

.timeline-row { display: flex; gap: var(--space-3); align-items: flex-start; }

.timeline-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin-top: 6px;
  flex: 0 0 8px;
  background: var(--color-text-soft);
}
.timeline-dot--open     { background: var(--color-warning); }
.timeline-dot--resolved { background: var(--color-success); }
.timeline-dot--info     { background: var(--color-info); }

.timeline-main { flex: 1; min-width: 0; }

.timeline-top {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-2);
}

.timeline-label { font-weight: 600; font-size: var(--text-sm); color: var(--color-text); }
.timeline-time { font-size: var(--text-xs); color: var(--color-text-muted); white-space: nowrap; }
.timeline-detail { margin: 2px 0 0; color: var(--color-text-muted); font-size: var(--text-sm); }

/* Notas del equipo */
.entry-rows { list-style: none; margin: 0 0 var(--space-4); padding: 0; display: flex; flex-direction: column; gap: var(--space-3); }
.entry-row { border-top: 1px solid var(--color-border); padding-top: var(--space-3); }
.entry-row:first-child { border-top: 0; padding-top: 0; }

.entry-top {
  display: flex;
  justify-content: space-between;
  gap: var(--space-2);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

.entry-body { margin: var(--space-1) 0 0; font-size: var(--text-sm); color: var(--color-text); white-space: pre-wrap; }

.entry-form { display: flex; flex-direction: column; gap: var(--space-2); align-items: flex-start; }
.entry-form textarea {
  width: 100%;
  min-height: 80px;
  box-sizing: border-box;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-3);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--color-text);
  resize: vertical;
}

/* Subtareas */
.subitem-rows { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.subitem-row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); }
.subitem-row a { color: var(--color-primary); text-decoration: none; font-weight: 500; }
.subitem-row a:hover { text-decoration: underline; }

/* Documentos (plain list; T6 swaps this block for _documents_section.html) */
.doc-rows { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.doc-row { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-2); font-size: var(--text-sm); }
.doc-row a { color: var(--color-primary); text-decoration: none; font-weight: 500; }
.doc-row a:hover { text-decoration: underline; }
.doc-meta { color: var(--color-text-muted); font-size: var(--text-xs); white-space: nowrap; }

/* Aside forms: Estado / Asignados / Portal del cliente. */
.expediente-status-form,
.expediente-cancel-form,
.expediente-assign-form,
.expediente-portal-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  align-items: flex-start;
}

.expediente-cancel-form { margin-top: var(--space-3); }

.expediente-field-label {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  width: 100%;
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.expediente-status-form select,
.expediente-assign-form select,
.expediente-field-label input[type="text"] {
  width: 100%;
  box-sizing: border-box;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--color-text);
}

.assignee-rows { list-style: none; margin: 0 0 var(--space-3); padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.assignee-row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); font-size: var(--text-sm); }
.assignee-row form { margin: 0; }

.expediente-checkbox { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); color: var(--color-text); }
.expediente-hint { margin: 0; color: var(--color-text-muted); font-size: var(--text-xs); }

/* ============ /documents: best-in-class file manager (P5.x rebuild) ========
   Two-pane "Clouds"/Drive-style manager: a navigable folder tree on the
   left, a Recientes strip + breadcrumb + enriched contents table on the
   right. Reuses .record-section/.data-table/.task-tag/.dashboard-empty —
   no new card/box primitives, hairline sections only. ========================= */

.filemanager {
  display: grid;
  grid-template-columns: 240px 1fr;
  gap: var(--space-8);
  align-items: start;
}

.fm-side {
  position: sticky;
  top: var(--space-8);
}

.fm-main {
  min-width: 0;
}

/* Left nav tree: a flat link list, fully expanded (no JS disclosure state),
   nested one indent step per depth. */
.fm-tree {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding-right: var(--space-4);
  border-right: 1px solid var(--color-border);
}

.fm-tree-link {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-md);
  color: var(--color-text);
  text-decoration: none;
  font-size: var(--text-sm);
}

.fm-tree-link:hover { background: var(--color-surface-muted); }

.fm-tree-link.is-active {
  background: var(--color-primary-soft);
  color: var(--color-primary);
  font-weight: 500;
}

.fm-tree-root {
  font-weight: 600;
  color: var(--color-text);
  margin-bottom: var(--space-1);
}

.fm-tree-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.fm-tree-list-root { margin-top: var(--space-1); }

.fm-tree-item .fm-tree-list {
  margin-left: var(--space-5);
}

.fm-tree-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Breadcrumb: "Documentos › Comunidad › Carpeta" per the Google-Drive-style
   location line above the contents table. */
.fm-breadcrumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin: 0 0 var(--space-5);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.fm-breadcrumb a {
  color: var(--color-text-muted);
  text-decoration: none;
}

.fm-breadcrumb a:hover { color: var(--color-primary); text-decoration: underline; }

.fm-breadcrumb-sep { color: var(--color-text-soft); }

.fm-breadcrumb-current {
  color: var(--color-text);
  font-weight: 500;
}

/* Recientes: a compact cross-scope activity strip (icon + name + two meta
   columns), not a full data-table — it sits above the location-scoped
   contents table and deliberately spans every scope. */
.fm-recent-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

/* Grid (not flex) so the two meta columns land in a fixed position
   regardless of each row's name length — a ragged flex chain left the date
   column unaligned row-to-row. */
.fm-recent-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) minmax(120px, 220px) 52px;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-1) 0;
}

.fm-recent-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--color-primary);
  text-decoration: none;
  font-weight: 500;
}

.fm-recent-name:hover { text-decoration: underline; }

.fm-recent-meta {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  white-space: nowrap;
  text-align: right;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Icons: Lucide only, restrained to two roles — folders/communities navy,
   every file kind muted ink (kind reads via glyph shape, never a per-kind
   tint rainbow). */
.fm-icon {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}

.fm-icon-folder { color: var(--color-primary); }
.fm-icon-file { color: var(--color-text-muted); }

/* The contents table's name cell: icon + link/label inline. */
.fm-name-cell {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.fm-row-nav .fm-name-cell a { font-weight: 500; }

/* The filename link's own stacking column, so a reference code can render
   on its own line underneath without disturbing the icon's alignment. */
.fm-name-main {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

/* Referencia — a document's editable doc-code, shown inline under its
   filename (no dedicated table column, CRM detail-page task). */
.fm-ref {
  display: block;
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

/* Wide tables (the Mover column especially) scroll inside their own
   container, never the page body. */
.fm-table-scroll {
  overflow-x: auto;
}

.fm-move-form {
  display: flex;
  gap: var(--space-2);
  align-items: center;
}

.fm-move-form select {
  max-width: 160px;
  padding: var(--space-1) var(--space-2);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  color: var(--color-text);
}

@media (max-width: 880px) {
  .filemanager { grid-template-columns: 1fr; }
  .fm-side {
    position: static;
    padding-right: 0;
    border-right: 0;
    border-bottom: 1px solid var(--color-border);
    padding-bottom: var(--space-4);
    margin-bottom: var(--space-2);
  }
}

/* ============ Equipo (Team) insights redesign — reusable components ============
   Approved mockup (2026-07-28): KPI deck blocks, count/health chips,
   response-time severity dots, sentiment mix bar, operator avatar, and the
   Por-operador/Por-comunidad view-tab switch. Built for /insights/operators
   but deliberately generic — any other metrics page (dashboard.html,
   comparison.html, detail.html) can reuse these classes rather than
   inventing page-specific ones. Tokens only, no raw hex (mirrors the rest of
   this file); the mockup's literal colours are mapped to their nearest
   existing --navy/--coral/--leaf/--butter/--rose/--sky scale step. */

.masthead {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-6);
  flex-wrap: wrap;
  margin-bottom: var(--space-2);
}

.kicker {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  background: var(--color-primary-soft);
  color: var(--navy-700);
  font-size: var(--text-2xs);
  font-weight: 700;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  margin-bottom: var(--space-2);
}

/* ---- KPI strip: solid-fill deck blocks ---- */
.kpis {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-3);
  margin: var(--space-6) 0 var(--space-8);
}

.kpi {
  border-radius: var(--radius-xl);
  padding: var(--space-5) var(--space-5) var(--space-4);
  min-height: 132px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

.kpi-icon {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.16);
}

.kpi-icon svg { width: 18px; height: 18px; }

.kpi.navy { background: var(--navy-800); color: #fff; }
.kpi.navy .kpi-label { color: var(--navy-200); }

.kpi.coral { background: var(--coral-500); color: #fff; }
.kpi.coral .kpi-label { color: var(--coral-50); }

.kpi.leaf { background: var(--leaf-600); color: #fff; }
.kpi.leaf .kpi-label { color: var(--leaf-100); }

.kpi.paper {
  background: var(--color-surface);
  color: var(--color-text);
  border: 1px solid var(--color-border);
}
.kpi.paper .kpi-icon { background: var(--color-primary-soft); }
.kpi.paper .kpi-icon svg { color: var(--navy-700); }
.kpi.paper .kpi-label { color: var(--color-text-muted); }

.kpi-value {
  font-family: var(--font-serif);
  font-size: var(--text-3xl);
  font-weight: 700;
  line-height: 1;
}

.kpi-label {
  font-size: var(--text-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--tracking-snug);
  margin-top: var(--space-1);
}

.kpi-delta {
  font-size: var(--text-xs);
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  margin-top: 2px;
}

.kpi.paper .kpi-delta.good { color: var(--color-success); }
.kpi.paper .kpi-delta.bad { color: var(--color-danger); }

@media (max-width: 900px) { .kpis { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .kpis { grid-template-columns: 1fr; } }

/* ---- masthead date-range filter pill (wraps the existing Desde/Hasta form) ---- */
.range {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-pill);
  padding: var(--space-1) var(--space-1) var(--space-1) var(--space-4);
  box-shadow: var(--shadow-xs);
}

.range label {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  font-weight: 600;
}

.range input {
  border: none;
  background: var(--color-surface-muted);
  border-radius: var(--radius-md);
  padding: var(--space-1) var(--space-2);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--color-text);
}

/* ---- count/health chips (small colour-coded pills, inline in table cells) ---- */
.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 3px var(--space-3);
  border-radius: var(--radius-pill);
  font-size: var(--text-xs);
  font-weight: 700;
  line-height: 1.4;
}

.chip.leaf {
  background: var(--color-success-surface);
  color: var(--leaf-700);
  border: 1px solid var(--color-success-border);
}
.chip.rose {
  background: var(--color-danger-surface);
  color: var(--color-danger-hover);
  border: 1px solid var(--color-danger-border);
}
.chip.ink {
  background: var(--color-surface-muted);
  color: var(--color-text-muted);
  border: 1px solid var(--color-border);
}
/* "Late" / mid-severity chip — same butter role as .status-pill.is-in_progress
   and .rt-dot.mid, just chip-sized (Gestión · Cumplimiento's "Tarde" state). */
.chip.butter {
  background: var(--butter-50);
  color: var(--butter-700);
  border: 1px solid var(--butter-300);
}

/* Served-level chip — same leaf/butter/rose roles as .health-pill (good/warn/
   bad), just chip-sized for a dense table cell rather than a page-head pill. */
.chip.health-good {
  background: var(--color-success-surface);
  color: var(--color-success);
  border: 1px solid var(--color-success-border);
}
.chip.health-warn {
  background: var(--color-warning-surface);
  color: var(--color-warning);
  border: 1px solid var(--color-warning-border);
}
.chip.health-bad {
  background: var(--color-danger-surface);
  color: var(--color-danger);
  border: 1px solid var(--color-danger-border);
}
.chip .health-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }

/* ---- response-time severity indicator ---- */
.rt { display: flex; align-items: center; gap: var(--space-2); }
.rt-dot { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; }
.rt-dot.fast { background: var(--leaf-500); }
.rt-dot.mid { background: var(--butter-600); }
.rt-dot.slow { background: var(--rose-500); }
.rt-val { font-weight: 700; font-size: var(--text-sm); }
.rt-val.fast { color: var(--leaf-700); }
.rt-val.mid { color: var(--butter-700); }
.rt-val.slow { color: var(--color-danger-hover); }
.rt-unit { color: var(--color-text-muted); font-size: var(--text-xs); }

/* ---- sentiment mix bar (stacked positive/neutral/negative) ---- */
.sentiment-bar { display: flex; align-items: center; gap: var(--space-2); min-width: 150px; }
.sbar {
  flex: 1;
  height: 7px;
  border-radius: var(--radius-pill);
  background: var(--color-surface-muted);
  overflow: hidden;
  display: flex;
}
.sbar span { height: 100%; }
.sbar .pos { background: var(--leaf-500); }
.sbar .neu { background: var(--ink-300); }
.sbar .neg { background: var(--rose-500); }
.sentiment-pct { font-size: var(--text-xs); color: var(--color-text-muted); }
.sentiment-empty { font-size: var(--text-sm); color: var(--color-text-soft); }
.sentiment-legend {
  display: flex;
  gap: var(--space-3);
  font-size: var(--text-2xs);
  color: var(--color-text-muted);
  margin-top: var(--space-4);
}
.sentiment-legend span { display: inline-flex; align-items: center; gap: var(--space-1); }
.sentiment-legend .dot { width: 7px; height: 7px; border-radius: 50%; display: inline-block; }

/* ---- operator avatar + name/role (table "person" cell) ---- */
.person { display: flex; align-items: center; gap: var(--space-3); }
.avatar {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--navy-800);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: var(--text-xs);
  flex: 0 0 34px;
}
.p-name { font-weight: 600; color: var(--color-text); font-size: var(--text-sm); }
.p-role { font-size: var(--text-xs); color: var(--color-text-muted); }

/* ---- community name/city (table "comunidad" cell) ---- */
.comm-name { font-weight: 600; color: var(--color-text); font-size: var(--text-sm); }
.comm-city { font-size: var(--text-xs); color: var(--color-text-muted); }

/* ---- view tabs (Por operador / Por comunidad) ---- */
.view-tabs {
  display: flex;
  gap: var(--space-1);
  margin-bottom: var(--space-4);
  background: var(--color-surface-muted);
  border-radius: var(--radius-pill);
  padding: var(--space-1);
  width: max-content;
}
.view-tab {
  border: none;
  background: none;
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease-out-quart),
              color var(--duration-fast) var(--ease-out-quart);
}
.view-tab.is-active {
  background: var(--color-surface);
  color: var(--color-primary);
  box-shadow: var(--shadow-xs);
}
.view-tab:active { transform: scale(0.99); }
.view-tab:focus-visible { outline: 2px solid var(--color-focus-ring); outline-offset: 2px; }
.view-panel { display: none; }
.view-panel.is-active { display: block; }

/* ============ Windows High Contrast / forced-colors ============ */
/* In forced-colors mode authored backgrounds/borders are flattened, so the
   active-row tint and the urgency dot can vanish. Re-assert visible chrome
   with system colors and outlines that the OS keeps. */
@media (forced-colors: active) {
  .msg-row:focus-visible,
  .thread-row:focus-visible,
  .read-subject:focus-visible,
  .nav-item:focus-visible,
  .nav-child:focus-visible,
  .avatar-menu-row:focus-visible,
  .skip-link:focus {
    outline: 2px solid currentColor;
    outline-offset: 2px;
  }

  /* Keep the selected row legible without relying on the tint. */
  .msg-row.is-active {
    outline: 2px solid Highlight;
    outline-offset: -2px;
  }

  /* The urgency dot is a background fill, which forced-colors strips. Draw it
     with a border so it stays visible. */
  .urgency-dot {
    background: currentColor;
    border: 1px solid currentColor;
    forced-color-adjust: none;
  }

  /* Equipo redesign: the response-severity + health-chip dots are also
     background-only fills — same currentColor-border rescue. */
  .rt-dot,
  .chip .health-dot,
  .health-pill .health-dot {
    background: currentColor;
    border: 1px solid currentColor;
    forced-color-adjust: none;
  }
}
