/* ── RESET ─────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
  /* ── Paleta oficial Palma Pictures ───────────────────────── */
  --space-indigo:  #2b2d42;
  --lavender-grey: #8d99ae;
  --platinum:      #edf2f4;
  --punch-red:     #ef233c;
  --flag-red:      #d90429;

  /* ── Sistema de color ────────────────────────────────────── */
  --bg:          #edf2f4;
  --surface:     #ffffff;
  --surface-2:   #f3f5f7;
  --surface-sunk:#e8ecef;
  --border:      rgba(43,45,66,0.09);
  --border-med:  rgba(43,45,66,0.16);
  --border-strong: rgba(43,45,66,0.28);
  --text:        #2b2d42;
  --text-2:      rgba(43,45,66,0.78);
  --text-soft:   #8d99ae;
  --text-xsoft:  rgba(141,153,174,0.6);

  /* Accent = punch-red · hover = flag-red */
  --blue:        #ef233c;
  --blue-hover:  #d90429;
  --blue-light:  rgba(239,35,60,0.07);

  /* Estados dentro de la paleta */
  --green:       #2b2d42;
  --green-dark:  #1d1f30;
  --orange:      #8d99ae;
  --orange-dark: #6b7589;
  --red:         #ef233c;
  --red-dark:    #d90429;
  --indigo:      #2b2d42;

  --sidebar-bg:  #2b2d42;
  --sidebar-w:   268px;

  --radius-lg: 0;
  --radius:    0;
  --radius-sm: 0;
  --radius-xs: 0;
  --radius-pill: 999px;

  --shadow-xs: none;   /* las tarjetas no flotan: se separan con 1px de borde */
  --shadow-sm: none;   /* los modales usan --shadow-md, que sí se conserva */
  --shadow:    0 4px 14px rgba(43,45,66,0.10), 0 0 0 0.5px rgba(43,45,66,0.06);
  --shadow-md: 0 12px 34px rgba(43,45,66,0.18), 0 0 0 0.5px rgba(43,45,66,0.07);
  --shadow-lift: 0 6px 20px rgba(43,45,66,0.13), 0 0 0 0.5px rgba(43,45,66,0.06);

  --ring: 0 0 0 3px rgba(239,35,60,0.22);

  /* ── Alias ─────────────────────────────────────────────── */
  --accent:         var(--punch-red);
  /* Componentes del acento: permiten tintes rgba(var(--acento-rgb), x) que
     siguen a la paleta. Si cambia el acento, cambian todos los tintes. */
  --acento-rgb:     239, 35, 60;
  --accent-blue:    var(--punch-red);
  --accent-hover:   var(--flag-red);
  --bg-card:        var(--surface);
  --bg-hover:       rgba(43,45,66,0.04);
  --border-light:   var(--border);
  --border-color:   var(--border-med);
  --text-primary:   var(--text);
  --text-secondary: var(--text-2);
  --text-muted:     var(--text-soft);
  --radius-md:      var(--radius);
  --font-mono:      'SF Mono', 'Monaco', 'Menlo', ui-monospace, monospace;

  --font:         -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Helvetica Neue', sans-serif;
  --font-display: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Helvetica Neue', sans-serif;
  --transition: 0.12s ease;

  --cal-bar-radius: 3px;
}

html { height: 100%; }
body {
  font-family: var(--font);
  background: var(--bg);
  color: var(--text);
  height: 100%;
  overflow: hidden;
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

/* ── LAYOUT ────────────────────────────────────────────────────── */
#login-screen, #app { position: fixed; inset: 0; }
#app { display: flex; align-items: stretch; }

/* ── SIDEBAR ───────────────────────────────────────────────────── */
.sidebar {
  width: var(--sidebar-w);
  background: var(--sidebar-bg);
  border-right: none;
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
  height: 100%;
  overflow: hidden;
  position: relative;
  transition: width 0.22s cubic-bezier(0.4,0,0.2,1);
}
.sidebar.collapsed {
  width: 64px;
}

/* Palm tree watermark */
.sidebar-palm-watermark {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  opacity: 0.05;
  pointer-events: none;
  z-index: 0;
  overflow: hidden;
  transition: opacity 0.6s ease;
}
.sidebar-palm-watermark img {
  width: 72%;
  height: auto;
  object-fit: contain;
  object-position: center top;
  filter: invert(1) brightness(1.3);
  transform: scale(1) translateY(0);
  transition: transform 0.65s cubic-bezier(0.22,1,0.36,1);
}
/* Hover: subtle reveal with upward drift */
.sidebar:hover .sidebar-palm-watermark {
  opacity: 0.13;
}
.sidebar:hover .sidebar-palm-watermark img {
  transform: scale(1.03) translateY(-5px);
}
.sidebar-palm-watermark svg { width: 100%; height: 100%; object-fit: cover; }

.sidebar-logo {
  padding: 16px 12px 14px;
  border-bottom: 1px solid rgba(255,255,255,0.07);
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 10px;
  position: relative;
  z-index: 1;
  flex-shrink: 0;
  margin-bottom: 4px;
  /* overflow visible so collapse btn stays clickable when sidebar collapses */
  overflow: visible;
}
.logo-mark {
  transition: opacity 0.18s, width 0.22s;
  width: 36px; height: 36px;
  background: rgba(255,255,255,0.06);
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  flex-shrink: 0;
}
.logo-text {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  transition: opacity 0.18s, width 0.22s;
}
.logo-title {
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 700;
  color: #FFFFFF;
  letter-spacing: -0.02em;
  line-height: 1.2;
  white-space: nowrap;
}
.logo-sub {
  font-size: 10px;
  color: rgba(255,255,255,0.4);
  margin-top: 2px;
  font-weight: 500;
  letter-spacing: 0.02em;
  white-space: nowrap;
}
/* Collapse button */
.sidebar-collapse-btn {
  width: 26px; height: 26px;
  border-radius: 0;
  border: 1px solid rgba(255,255,255,0.1);
  background: rgba(255,255,255,0.05);
  color: rgba(255,255,255,0.45);
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  transition: background 0.15s, color 0.15s, opacity 0.22s;
  padding: 0;
}
.sidebar-collapse-btn:hover { background: rgba(255,255,255,0.12); color: #fff; }
.sidebar-collapse-btn svg { width: 12px; height: 12px; }
/* Hide text when collapsed */
.sidebar.collapsed .logo-text { opacity: 0; width: 0; overflow: hidden; }
.sidebar.collapsed .logo-mark { opacity: 0; width: 0; overflow: hidden; margin: 0; }
.sidebar.collapsed .sidebar-logo { gap: 0; justify-content: center; overflow: visible; }
.sidebar.collapsed .sidebar-collapse-btn { margin-left: 0; background: rgba(255,255,255,0.12); color: rgba(255,255,255,0.85); }

.sidebar-nav {
  padding: 10px 8px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  overflow-y: auto;
  position: relative;
  z-index: 1;
}
.sidebar-nav::-webkit-scrollbar { width: 3px; }
.sidebar-nav::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.1); border-radius: 0; }
.nav-section-label {
  font-size: 9.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: rgba(255,255,255,0.32);
  padding: 14px 10px 4px;
  overflow: hidden;
  transition: opacity 0.15s, height 0.22s, padding 0.22s;
}
/* Collapsed: hide labels with zero height */
.sidebar.collapsed .nav-section-label {
  height: 0;
  padding-top: 0;
  padding-bottom: 0;
  opacity: 0;
  pointer-events: none;
}
/* nav-label: the text span inside each nav-item */
.nav-label {
  transition: opacity 0.15s;
  white-space: nowrap;
  overflow: hidden;
}
.sidebar.collapsed .nav-label { opacity: 0; width: 0; overflow: hidden; }
.nav-item {
  display: flex;
  align-items: center;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  color: rgba(255,255,255,0.58);
  text-decoration: none;
  font-size: 13.5px;
  font-weight: 500;
  transition: all var(--transition);
  letter-spacing: -0.01em;
  gap: 9px;
  position: relative;
  overflow: hidden;
}
/* Collapsed: center icon, add tooltip */
.sidebar.collapsed .nav-item {
  justify-content: center;
  padding: 9px 0;
  gap: 0;
}
.sidebar.collapsed .nav-item .nav-badge { display: none !important; }
.sidebar.collapsed .nav-item::after {
  content: attr(title);
  position: absolute;
  left: calc(100% + 10px);
  top: 50%;
  transform: translateY(-50%);
  background: var(--text);
  color: var(--surface);
  font-size: 12px;
  font-weight: 500;
  padding: 5px 10px;
  border-radius: 0;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.15s;
  z-index: 100;
  border: 1px solid rgba(255,255,255,0.1);
  box-shadow: 0 4px 16px rgba(0,0,0,0.4);
}
.sidebar.collapsed .nav-item:hover::after { opacity: 1; }
.nav-item:hover  { background: rgba(255,255,255,0.09); color: rgba(255,255,255,0.92); }
.nav-item.active {
  background: rgba(239,35,60,0.18);
  color: #FFFFFF;
  font-weight: 600;
}
.nav-item.active::before {
  content: '';
  position: absolute;
  left: -8px; top: 50%;
  transform: translateY(-50%);
  width: 3px; height: 20px;
  background: var(--red);
  border-radius: 0 3px 3px 0;
}
.nav-icon {
  width: 15px; height: 15px;
  flex-shrink: 0;
  opacity: 0.55;
}
.nav-item.active .nav-icon,
.nav-item:hover .nav-icon { opacity: 1; }
.nav-item-admin  { display: none; }

.nav-badge {
  margin-left: auto;
  background: var(--red);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  min-width: 16px; height: 16px;
  border-radius: 0;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 0 4px;
}
.nav-badge.show { display: flex; }
.nav-badge-warn { background: #F59E0B; }
.nav-badge-warn.show { display: flex; }

.sidebar-user {
  padding: 11px 12px 16px;
  border-top: 1px solid rgba(255,255,255,0.06);
  position: relative;
  z-index: 1;
  overflow: hidden;
}
.sidebar.collapsed .sidebar-user { padding: 10px 0; display: flex; justify-content: center; }
.sidebar-user-info {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-bottom: 9px;
}
.sidebar.collapsed .sidebar-user-info { margin-bottom: 0; }
.sidebar-user-text { overflow: hidden; transition: opacity 0.15s, width 0.22s; }
.sidebar.collapsed .sidebar-user-text { opacity: 0; width: 0; overflow: hidden; }
.sidebar-avatar {
  width: 28px; height: 28px;
  border-radius: 50%;
  background: rgba(239,35,60,0.25);
  border: 1.5px solid rgba(239,35,60,0.4);
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700;
  color: #4FC3FF;
  flex-shrink: 0;
}
.sidebar-user-name {
  font-size: 12.5px; font-weight: 600;
  color: #FFFFFF; line-height: 1.2;
}
.sidebar-user-role { font-size: 10.5px; color: #48484A; font-weight: 500; }
.btn-logout {
  background: rgba(255,255,255,0.06);
  border: 1px solid rgba(255,255,255,0.1);
  color: #636366;
  padding: 6px 12px;
  border-radius: var(--radius-xs);
  font-size: 11.5px; cursor: pointer;
  font-family: var(--font);
  transition: all var(--transition);
  width: 100%; font-weight: 500;
}
.btn-logout:hover { background: rgba(255,255,255,0.1); color: #AEAEB2; border-color: rgba(255,255,255,0.18); }

/* ── MAIN ──────────────────────────────────────────────────────── */
.main { flex: 1; overflow-y: auto; padding: 28px 30px; min-width: 0; }

/* ── PAGES ─────────────────────────────────────────────────────── */
.page { display: none; }
.page.active { display: block; }

.page-header {
  display: flex; align-items: center;
  justify-content: space-between;
  margin-bottom: 20px;
}
.page-header h1 {
  font-family: var(--font-display);
  font-size: 24px; font-weight: 700;
  letter-spacing: -0.03em; color: var(--text);
}
.page-date { color: var(--text-soft); font-size: 12.5px; font-weight: 500; }

/* ── DASHBOARD LAYOUT ──────────────────────────────────────────── */
.dashboard-grid {
  display: grid;
  grid-template-columns: 1fr 278px;
  gap: 20px;
  align-items: start;
}
.dashboard-col-side { display: flex; flex-direction: column; gap: 14px; }

/* ── CHART CARD ────────────────────────────────────────────────── */
.chart-card {
  background: var(--surface);
  border-radius: var(--radius);
  border: 1px solid var(--border);
  padding: 16px;
}
.chart-donut-wrap {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 8px 0 6px;
}
.chart-donut-wrap svg { overflow: visible; }
.chart-legend {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 4px;
}
.chart-legend-item {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--text-2);
}
.chart-legend-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}
.chart-legend-label { flex: 1; font-weight: 500; }
.chart-legend-val {
  font-weight: 700;
  font-size: 12.5px;
  color: var(--text);
  font-family: var(--font-display);
}

/* ── STATS GRID ────────────────────────────────────────────────── */
.stats-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
  margin-bottom: 24px;
}
.stat-card {
  background: var(--surface);
  border-radius: var(--radius-lg);
  padding: 18px 18px 16px;
  border: none;
  box-shadow: 0 2px 8px rgba(0,0,0,0.05), 0 0 0 0.5px rgba(0,0,0,0.06);
  position: relative;
  overflow: hidden;
  transition: transform 0.14s ease, box-shadow 0.14s ease;
}
.stat-card[style*="cursor:pointer"]:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(0,0,0,0.1), 0 0 0 0.5px rgba(0,0,0,0.06);
}
.stat-card-accent {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 3px;
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}
.stat-card.blue   .stat-card-accent { background: linear-gradient(90deg, var(--red), #34AADC); }
.stat-card.green  .stat-card-accent { background: linear-gradient(90deg, var(--text), #30D158); }
.stat-card.orange .stat-card-accent { background: linear-gradient(90deg, var(--text-soft), #FFCC02); }
.stat-card.red    .stat-card-accent { background: linear-gradient(90deg, var(--red), #FF6961); }
.stat-card.indigo .stat-card-accent { background: linear-gradient(90deg, #5856D6, #34AADC); }
.stat-card.purple .stat-card-accent { background: linear-gradient(90deg, #AF52DE, #FF375F); }
.stat-card-icon {
  width: 28px; height: 28px;
  margin-bottom: 10px;
  margin-top: 4px;
}
.stat-card-icon svg { width: 100%; height: 100%; }
.stat-value {
  font-family: var(--font-display);
  font-size: 46px; font-weight: 800;
  line-height: 1; margin-bottom: 6px;
  letter-spacing: -0.05em;
  color: var(--text);
}
.stat-label {
  font-size: 10.5px; color: var(--text-soft);
  font-weight: 600; letter-spacing: 0.03em;
  text-transform: uppercase;
  line-height: 1.3;
}

/* ── SECTION TITLE ─────────────────────────────────────────────── */
.section-title {
  font-size: 10.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.07em;
  color: var(--text-soft); margin-bottom: 8px; padding-left: 2px;
}

/* ── ALERT STRIP ───────────────────────────────────────────────── */
.alert-strip {
  background: rgba(255,149,0,0.07);
  border: 1px solid rgba(255,149,0,0.2);
  border-radius: var(--radius-sm);
  padding: 10px 13px; margin-bottom: 8px;
  font-size: 12.5px; display: flex; align-items: center; gap: 9px; color: var(--text-2);
}
.alert-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--orange); flex-shrink: 0; }
.alert-strip.red { background: rgba(255,59,48,0.06); border-color: rgba(255,59,48,0.2); }
.alert-strip.red .alert-dot { background: var(--red); }

/* ── CALENDAR WIDGET ───────────────────────────────────────────── */
.calendar-widget {
  background: var(--surface);
  border-radius: var(--radius);
  border: 1px solid var(--border);
  padding: 14px;
}
.calendar-header {
  display: flex; align-items: center;
  justify-content: space-between; margin-bottom: 10px;
}
.calendar-title { font-size: 13px; font-weight: 700; color: var(--text); letter-spacing: -0.01em; }
.cal-nav {
  background: none; border: none; color: var(--blue);
  cursor: pointer; width: 24px; height: 24px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 14px; transition: background var(--transition);
}
.cal-nav:hover { background: var(--blue-light); }
.calendar-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 1px;
}
.cal-day-label {
  text-align: center; font-size: 9px; font-weight: 700;
  color: var(--text-soft); text-transform: uppercase;
  padding: 3px 0 5px; letter-spacing: 0.05em;
}
.cal-day {
  aspect-ratio: 1;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  border-radius: 0; cursor: default;
  font-size: 11px; color: var(--text);
  transition: background var(--transition);
  gap: 2px; padding: 2px;
}
.cal-day.other-month { color: var(--text-xsoft); }
.cal-day.today .cal-day-num {
  background: var(--blue); color: white;
  border-radius: 50%; width: 20px; height: 20px;
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 11px;
}
.cal-day.has-event { cursor: pointer; }
.cal-day.has-event:hover { background: var(--bg); }
.cal-day-num { line-height: 1; }
.cal-dots {
  display: flex; gap: 2px; height: 4px;
  align-items: center; justify-content: center;
}
.cal-dot { width: 4px; height: 4px; border-radius: 50%; }
.cal-dot.orange { background: var(--orange); }
.cal-dot.red    { background: var(--red); }

/* ── AGENDA WIDGET ─────────────────────────────────────────────── */
.agenda-widget {
  background: var(--surface);
  border-radius: var(--radius);
  border: 1px solid var(--border);
  overflow: hidden;
}
.agenda-item {
  display: flex; gap: 11px;
  padding: 10px 13px;
  border-bottom: 1px solid var(--border);
  align-items: flex-start;
}
.agenda-item:last-child { border-bottom: none; }
.agenda-date { min-width: 30px; text-align: center; padding-top: 1px; }
.agenda-date-day {
  font-size: 17px; font-weight: 700;
  line-height: 1; color: var(--text);
  letter-spacing: -0.03em;
  font-family: var(--font-display);
}
.agenda-date-month {
  font-size: 9px; text-transform: uppercase;
  font-weight: 700; color: var(--text-soft);
  letter-spacing: 0.04em;
}
.agenda-content { flex: 1; min-width: 0; }
.agenda-equipo {
  font-size: 12px; font-weight: 600; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.agenda-meta {
  font-size: 10.5px; color: var(--text-soft); margin-top: 1px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.agenda-tag {
  font-size: 9.5px; font-weight: 600; margin-top: 3px;
  padding: 1px 6px; border-radius: 0; display: inline-block;
}
.agenda-tag.vencido { background: rgba(255,59,48,0.1); color: var(--red); }
.agenda-tag.hoy     { background: rgba(239,35,60,0.1); color: var(--blue); }
.agenda-empty {
  padding: 24px 13px; text-align: center;
  color: var(--text-soft); font-size: 12px;
}

/* ── CARDS ─────────────────────────────────────────────────────── */
.card {
  background: var(--surface);
  border-radius: var(--radius);
  border: 1px solid var(--border);
  overflow: hidden; margin-bottom: 14px;
}

/* ── TABLE ─────────────────────────────────────────────────────── */
.table-wrap {
  background: var(--surface);
  border-radius: var(--radius);
  border: 1px solid var(--border);
  overflow: hidden; overflow-x: auto;
}
.tabla { width: 100%; border-collapse: collapse; }
.tabla th {
  background: var(--surface);
  padding: 10px 15px; text-align: left;
  font-size: 10px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.07em;
  color: var(--text-soft); border-bottom: 1px solid var(--border);
}
.tabla td {
  padding: 11px 15px; border-bottom: 1px solid var(--border);
  font-size: 13px; color: var(--text); vertical-align: middle;
}
.tabla tr:last-child td { border-bottom: none; }
.tabla tbody tr { transition: background var(--transition); }
.tabla tbody tr:hover { background: rgba(239,35,60,0.025); }
.tabla .empty-row td {
  text-align: center; color: var(--text-soft);
  padding: 48px; font-size: 13.5px;
}

/* ── BADGES ────────────────────────────────────────────────────── */
.badge {
  display: inline-flex; align-items: center;
  padding: 2px 8px; border-radius: 0;
  font-size: 11px; font-weight: 600; letter-spacing: 0.01em;
}
.badge-green  { background: rgba(52,199,89,0.10);  color: var(--green-dark); }
.badge-orange { background: rgba(255,149,0,0.10);  color: var(--orange-dark); }
.badge-blue   { background: rgba(239,35,60,0.10);  color: var(--blue); }
.badge-red    { background: rgba(255,59,48,0.10);  color: var(--red-dark); }
.badge-gray   { background: rgba(0,0,0,0.06);      color: var(--text-soft); }
.badge-purple { background: rgba(88,86,214,0.10);  color: var(--indigo); }

/* ── SEGMENTED CONTROL ─────────────────────────────────────────── */
.seg-control {
  display: inline-flex;
  background: rgba(116,116,128,0.12);
  border-radius: 0;
  padding: 2px; gap: 1px;
}
.seg-btn {
  padding: 5px 13px; border-radius: 0;
  font-size: 12.5px; font-weight: 500;
  cursor: pointer; transition: all var(--transition);
  color: var(--text-2); border: none; background: none;
  font-family: var(--font); white-space: nowrap; letter-spacing: -0.01em;
}
.seg-btn.active {
  background: var(--surface); color: var(--text); font-weight: 600;
  box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 0 0 0.5px rgba(0,0,0,0.04);
}

/* ── BUTTONS ───────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 5px; padding: 8px 15px;
  border-radius: 0;
  font-size: 13px; font-weight: 600;
  cursor: pointer; border: none;
  transition: all var(--transition);
  font-family: var(--font); letter-spacing: -0.01em; white-space: nowrap;
}
.btn-primary { background: var(--blue); color: #fff; }
.btn-primary:hover { background: var(--blue-hover); }
.btn-success { background: var(--green); color: #fff; }
.btn-success:hover { filter: brightness(0.92); }
.btn-ghost { background: var(--surface); color: var(--blue); border: 1px solid var(--border-med); font-weight: 500; }
.btn-ghost:hover { background: var(--bg); }
.btn-sm { padding: 5px 10px; font-size: 11.5px; border-radius: 0; }
.btn-danger { background: transparent; color: var(--red); border: 1px solid rgba(255,59,48,0.22); font-weight: 500; }
.btn-danger:hover { background: rgba(255,59,48,0.05); }

/* ── FILTERS BAR ───────────────────────────────────────────────── */
.filters-bar {
  display: flex; gap: 8px; margin-bottom: 12px;
  flex-wrap: wrap; align-items: center;
}
.filter-input, .filter-select {
  background: var(--surface);
  border: 1px solid var(--border-med);
  color: var(--text); border-radius: var(--radius-sm);
  padding: 7px 11px; font-size: 13px;
  outline: none; transition: all var(--transition);
  font-family: var(--font); box-shadow: var(--shadow-xs);
}
.filter-input { flex: 1; min-width: 200px; }
.filter-input:focus, .filter-select:focus {
  border-color: var(--blue);
  box-shadow: 0 0 0 3px rgba(239,35,60,0.12);
}

/* ── FORM CARD ─────────────────────────────────────────────────── */
.form-card {
  background: var(--surface); border-radius: var(--radius);
  border: 1px solid var(--border); padding: 20px 22px; margin-bottom: 20px;
}
.form-card-title { font-size: 14px; font-weight: 700; margin-bottom: 15px; color: var(--text); letter-spacing: -0.02em; }
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 13px; }
.form-group { display: flex; flex-direction: column; gap: 5px; }
.form-group-full { grid-column: 1 / -1; }
.form-group label {
  font-size: 10.5px; font-weight: 700;
  color: var(--text-soft); text-transform: uppercase; letter-spacing: 0.05em;
}
.form-group input,
.form-group select,
.form-group textarea {
  background: var(--bg); border: 1px solid var(--border-med);
  color: var(--text); border-radius: var(--radius-sm);
  padding: 8px 11px; font-size: 13.5px;
  font-family: var(--font); outline: none;
  transition: all var(--transition); -webkit-appearance: none;
}
.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
  border-color: var(--blue); background: var(--surface);
  box-shadow: 0 0 0 3px rgba(239,35,60,0.12);
}
.form-group textarea { min-height: 72px; resize: vertical; }
.form-actions {
  display: flex; gap: 8px; justify-content: flex-end;
  margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--border);
}

/* ── MODAL ─────────────────────────────────────────────────────── */
.modal-overlay {
  display: none; position: fixed; inset: 0;
  background: rgba(0,0,0,0.2);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  z-index: 1000; align-items: center; justify-content: center; padding: 16px;
}
.modal-overlay.open { display: flex; }
.modal {
  background: var(--surface); border-radius: var(--radius-lg);
  padding: 24px; width: 100%; max-width: 560px;
  max-height: 90vh; overflow-y: auto; box-shadow: var(--shadow-md);
}
.modal-sm { max-width: 400px; }
.modal-header {
  display: flex; align-items: center;
  justify-content: space-between;
  margin-bottom: 18px; padding-bottom: 13px;
  border-bottom: 1px solid var(--border);
}
.modal-header h2 {
  font-family: var(--font-display);
  font-size: 16px; font-weight: 700; letter-spacing: -0.02em;
}
.modal-close {
  background: var(--bg); border: none; color: var(--text-soft);
  font-size: 12px; cursor: pointer;
  width: 24px; height: 24px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  transition: all var(--transition);
  font-family: var(--font); font-weight: 700;
}
.modal-close:hover { background: var(--border-med); color: var(--text); }
.dev-info-text {
  color: var(--text-2); font-size: 13px; margin-bottom: 15px;
  padding: 10px 13px; background: var(--blue-light);
  border-radius: var(--radius-sm); border-left: 3px solid var(--blue); font-weight: 500;
}

/* ── LOGIN ─────────────────────────────────────────────────────── */
#login-screen {
  background: var(--bg); display: flex;
  align-items: center; justify-content: center; z-index: 9000;
}
.login-box {
  background: var(--surface); border-radius: var(--radius-lg);
  padding: 32px 28px; width: 100%; max-width: 320px;
  box-shadow: var(--shadow-md);
}
.login-logo { margin-bottom: 22px; }
.login-logo-mark {
  width: 52px; height: 52px; background: var(--bg);
  border-radius: 0;
  border: 1px solid var(--border-med);
  display: flex; align-items: center; justify-content: center;
  margin-bottom: 14px;
  overflow: hidden;
}
.login-title {
  font-family: var(--font-display);
  font-size: 20px; font-weight: 700;
  letter-spacing: -0.03em; color: var(--text);
}
.login-sub { font-size: 11.5px; color: var(--text-soft); margin-top: 2px; font-weight: 500; }
.login-error {
  margin-top: 10px; padding: 8px 11px;
  background: rgba(255,59,48,0.07); color: var(--red);
  border-radius: var(--radius-xs); font-size: 12.5px; font-weight: 500;
}
.btn-login { width: 100%; margin-top: 16px; padding: 11px; font-size: 13.5px; }

/* ── TOAST ─────────────────────────────────────────────────────── */
.toast {
  position: fixed; bottom: 22px; left: 50%;
  transform: translateX(-50%) translateY(10px);
  background: rgba(29,29,31,0.9);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  color: #FFFFFF; padding: 9px 18px; border-radius: 0;
  font-size: 13px; font-weight: 500; box-shadow: var(--shadow);
  opacity: 0; transition: opacity 0.18s, transform 0.18s;
  pointer-events: none; z-index: 9999;
  white-space: nowrap; letter-spacing: -0.01em;
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
.toast.err  { background: rgba(255,59,48,0.9); }

/* ── SCROLLBAR ─────────────────────────────────────────────────── */
::-webkit-scrollbar { width: 5px; height: 5px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(0,0,0,0.1); border-radius: 0; }
::-webkit-scrollbar-thumb:hover { background: rgba(0,0,0,0.18); }

/* ── TELEFONÍA ─────────────────────────────────────────────────── */
.tel-stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 10px;
  margin-bottom: 16px;
}
.tel-stat {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px 18px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.tel-stat-num {
  font-family: var(--font-display);
  font-size: 36px; font-weight: 800;
  letter-spacing: -0.05em; line-height: 1;
  color: var(--text);
}
.tel-stat-lbl {
  font-size: 10.5px; color: var(--text-soft);
  font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Type pills for telefonia */
.tel-pill {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 9px; border-radius: 0;
  font-size: 11px; font-weight: 600; letter-spacing: 0.01em;
}
.tel-pill.movil {
  background: rgba(239,35,60,0.08);
  color: var(--blue);
}
.tel-pill.fijo {
  background: rgba(88,86,214,0.08);
  color: var(--indigo);
}
.tel-pill-dot {
  width: 5px; height: 5px;
  border-radius: 50%;
  background: currentColor;
}

/* Sensitive field (PIN/PUK) */
.pin-cell {
  font-family: var(--font-mono, monospace);
  font-size: 12px; color: var(--text-soft);
  letter-spacing: 0.05em;
}

/* Activo indicator */
.activo-dot {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; font-weight: 500;
}
.activo-dot::before {
  content: '';
  display: inline-block;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--green);
}
.activo-dot.baja::before { background: var(--text-xsoft); }
.activo-dot.baja { color: var(--text-soft); }

/* Import/Export action row */
.page-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }

/* ── DASHBOARD TELEPHONY SECTION ───────────────────────────────── */
.tel-dash-section {
  margin-bottom: 16px;
  padding: 18px 20px;
  background: var(--surface);
  border-radius: var(--radius);
  border: 1px solid var(--border);
  position: relative;
}
.tel-dash-section::before {
  content: '';
  position: absolute;
  top: 0; left: 0;
  width: 3px; height: 100%;
  background: linear-gradient(180deg, var(--red), #5856D6);
  border-radius: var(--radius) 0 0 var(--radius);
}
.tel-dash-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
  gap: 12px;
}
.tel-dash-stat {
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.tel-dash-num {
  font-family: var(--font-display);
  font-size: 34px; font-weight: 800;
  line-height: 1; letter-spacing: -0.05em;
  color: var(--text);
}
.tel-dash-lbl {
  font-size: 10.5px; font-weight: 600;
  color: var(--text-soft);
  text-transform: uppercase; letter-spacing: 0.04em;
}
.tel-dash-dept {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
  display: flex; flex-wrap: wrap; gap: 6px;
}
.tel-dash-dept-pill {
  display: inline-flex; align-items: center; gap: 5px;
  background: rgba(0,0,0,0.04);
  border: 1px solid var(--border);
  border-radius: 0;
  padding: 3px 10px;
  font-size: 11.5px; font-weight: 500;
  color: var(--text-2);
}
.tel-dash-dept-count {
  font-weight: 700;
  color: var(--text);
}

/* ── TELEFONÍA PAGE — visual distinction ───────────────────────── */
#page-telefonia {
  background: linear-gradient(180deg, rgba(88,86,214,0.02) 0%, transparent 120px);
}
#page-telefonia .page-header h1::before {
  content: '';
  display: inline-block;
  width: 10px; height: 10px;
  background: linear-gradient(135deg, var(--red), #5856D6);
  border-radius: 50%;
  margin-right: 9px;
  vertical-align: middle;
  margin-bottom: 2px;
}
.tel-page-divider {
  display: flex; align-items: center; gap: 12px;
  margin: 0 0 20px;
  opacity: 0.4;
}
.tel-page-divider::before,
.tel-page-divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--indigo), transparent);
}

/* ── PRESUPUESTOS ──────────────────────────────────────────────── */

/* Builder layout */
.builder-wrap {
  display: grid;
  grid-template-columns: 1fr 320px;
  gap: 16px;
  height: calc(100vh - 90px);
  overflow: hidden;
}
.builder-left {
  overflow-y: auto;
  padding-right: 4px;
  padding-bottom: 40px;
}
.builder-right {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.builder-section {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px 18px;
  margin-bottom: 12px;
}
.builder-section-title {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-soft);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-bottom: 14px;
}

/* Empty state */
.pres-empty-items {
  text-align: center;
  padding: 32px 20px;
  color: var(--text-soft);
  font-size: 13px;
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* Line items table in builder */
.pres-items-table {
  font-size: 12px;
}
.pres-items-table th {
  font-size: 10.5px;
  padding: 6px 8px;
}
.pres-items-table td {
  padding: 6px 8px;
  vertical-align: middle;
}
.pres-items-table input {
  background: transparent;
  border: none;
  border-bottom: 1px solid transparent;
  padding: 2px 4px;
  width: 100%;
  font-size: 12px;
  font-family: var(--font);
  color: var(--text);
  transition: border-color var(--transition);
}
.pres-items-table input:focus {
  outline: none;
  border-bottom-color: var(--blue);
  background: var(--blue-light);
  border-radius: 0 3px 0 0;
}
.pres-item-del {
  background: none;
  border: none;
  color: var(--text-xsoft);
  cursor: pointer;
  font-size: 15px;
  padding: 2px 4px;
  border-radius: 0;
  transition: color var(--transition), background var(--transition);
  line-height: 1;
}
.pres-item-del:hover {
  color: var(--red);
  background: rgba(255,59,48,0.08);
}

/* Totals panel */
.pres-totals {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px 18px;
  margin-bottom: 12px;
}
.pres-totals-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 5px 0;
  font-size: 13px;
  color: var(--text-2);
  border-bottom: 1px solid var(--border);
}
.pres-totals-row:last-child { border-bottom: none; }
.pres-totals-base {
  color: var(--text-soft);
  font-size: 12.5px;
}
.pres-totals-final {
  font-weight: 700;
  font-size: 16px;
  color: var(--text);
  padding-top: 8px;
}
.pres-totals-row input[type="number"] {
  width: 48px;
  border: 1px solid var(--border-med);
  border-radius: 0;
  padding: 1px 5px;
  font-size: 12px;
  font-family: var(--font);
  color: var(--text);
  background: var(--bg);
  text-align: center;
}

/* Catalog panel */
.catalog-panel-header {
  padding: 12px 14px 8px;
  border-bottom: 1px solid var(--border);
}
.catalog-panel-title {
  font-size: 11px;
  font-weight: 600;
  color: var(--text-soft);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-bottom: 8px;
}
.catalog-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  padding: 8px 14px;
  border-bottom: 1px solid var(--border);
}
.catalog-tab {
  font-size: 10.5px;
  font-weight: 500;
  padding: 3px 8px;
  border-radius: 0;
  border: 1px solid var(--border-med);
  background: none;
  color: var(--text-soft);
  cursor: pointer;
  transition: background var(--transition), color var(--transition), border-color var(--transition);
  white-space: nowrap;
}
.catalog-tab.active,
.catalog-tab:hover {
  background: var(--blue);
  color: #fff;
  border-color: transparent;
}
.catalog-items-grid {
  flex: 1;
  overflow-y: auto;
  padding: 8px 10px 12px;
}
.catalog-card {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 9px 10px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  border: 1px solid transparent;
  transition: background var(--transition), border-color var(--transition);
  margin-bottom: 4px;
}
.catalog-card:hover {
  background: var(--blue-light);
  border-color: rgba(239,35,60,0.15);
}
.catalog-card-info {
  flex: 1;
  min-width: 0;
}
.catalog-card-name {
  font-size: 12px;
  font-weight: 500;
  color: var(--text);
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.catalog-card-desc {
  font-size: 11px;
  color: var(--text-soft);
  line-height: 1.3;
  margin-top: 1px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.catalog-card-price {
  font-size: 11px;
  font-weight: 600;
  color: var(--blue);
  white-space: nowrap;
}
.catalog-card-add {
  width: 22px; height: 22px;
  border-radius: 50%;
  background: var(--blue);
  color: #fff;
  border: none;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  transition: transform var(--transition), background var(--transition);
}
.catalog-card-add:hover {
  background: var(--blue-hover);
  transform: scale(1.12);
}
.catalog-cat-label {
  font-size: 10px;
  font-weight: 700;
  color: var(--text-xsoft);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding: 10px 10px 4px;
}

/* Presupuesto badges */
.badge-borrador  { background: rgba(174,174,178,0.15); color: #6E6E73; }
.badge-enviado   { background: rgba(239,35,60,0.1);    color: var(--red); }
.badge-aceptado  { background: rgba(52,199,89,0.12);   color: var(--text); }
.badge-rechazado { background: rgba(255,59,48,0.1);    color: var(--red); }

/* Presupuestos page gradient */
#page-presupuestos {
  overflow: hidden;
}
#pres-list-view, #pres-catalog-view {
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
#pres-list-view .table-wrap,
#pres-catalog-view .table-wrap {
  flex: 1;
  overflow-y: auto;
  min-height: 0;
}

/* ── INVENTARIO ────────────────────────────────────────────────── */
.inv-counter {
  font-size: 12px;
  color: var(--text-soft);
  padding: 8px 2px;
  text-align: right;
}
.badge-disponible { background: rgba(43,45,66,0.09); color: var(--text); }
.badge-en_uso { background: rgba(239,35,60,0.10); color: var(--red); }
.badge-mantenimiento { background: rgba(141,153,174,0.15); color: var(--text-soft); }
.badge-baja { background: rgba(217,4,41,0.09); color: var(--red-dark); }

/* ── VEHÍCULOS ─────────────────────────────────────────────────── */
#page-vehiculos { overflow-y: auto; }
.veh-tabs {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 20px;
  padding-bottom: 0;
}
.veh-tab {
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  padding: 8px 16px;
  font-size: 14px;
  font-weight: 500;
  color: var(--text-soft);
  cursor: pointer;
  margin-bottom: -1px;
  transition: color .15s, border-color .15s;
}
.veh-tab:hover { color: var(--text); }
.veh-tab.active { color: var(--accent); border-bottom-color: var(--accent); }

.veh-tab-content { }

.veh-info-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 12px;
  margin-bottom: 20px;
}
.veh-info-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px 16px;
}
.veh-info-label {
  font-size: 11px;
  font-weight: 600;
  color: var(--text-soft);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-bottom: 4px;
}
.veh-info-value {
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
}
.veh-info-value.warn { color: #F59E0B; }
.veh-info-value.danger { color: var(--red); }
.veh-info-value.ok { color: var(--text); }

.veh-alerta-banner {
  background: rgba(245,158,11,.12);
  border: 1px solid rgba(245,158,11,.35);
  border-radius: var(--radius);
  padding: 10px 14px;
  margin-bottom: 12px;
  font-size: 13px;
  font-weight: 500;
  color: #D97706;
  display: flex;
  align-items: center;
  gap: 8px;
}
.veh-alerta-banner.danger {
  background: rgba(255,59,48,.1);
  border-color: rgba(255,59,48,.3);
  color: var(--red);
}

/* ── VEHICLE FOTOS LATERALES ─────────────────────────────────── */
.veh-fotos-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
  margin-bottom: 8px;
}
.veh-foto-slot {
  cursor: pointer;
  border-radius: 0;
  overflow: hidden;
  aspect-ratio: 4/3;
  border: 2px dashed var(--border);
  transition: border-color 0.15s, box-shadow 0.15s;
}
.veh-foto-slot:hover { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(239,35,60,.12); }
.veh-foto-preview {
  width: 100%; height: 100%;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 6px; color: var(--text-soft); font-size: 12px;
}
.veh-foto-preview span { font-size: 24px; }
@media (max-width:700px) { .veh-fotos-grid { grid-template-columns: repeat(2, 1fr); } }

/* ── VEHICLE PRÓXIMO PROYECTO BANNER ─────────────────────────── */
.veh-proximo-banner {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  background: var(--bg-card);
  border-radius: 0;
  padding: 12px 16px;
  margin-bottom: 16px;
  border: 1.5px solid var(--border);
}
.veh-proximo-banner.active { border-color: var(--text); background: rgba(52,199,89,.06); }
.veh-proximo-banner.upcoming { border-color: var(--red); background: rgba(239,35,60,.05); }
.veh-proximo-dot {
  width: 10px; height: 10px;
  border-radius: 50%;
  margin-top: 4px;
  flex-shrink: 0;
}
.veh-proximo-dot.active { background: var(--text); }
.veh-proximo-dot.upcoming { background: var(--red); }
.veh-proximo-label { font-size: 11px; color: var(--text-soft); margin-bottom: 2px; }
.veh-proximo-nombre { font-size: 14px; font-weight: 600; color: var(--text-primary); }
.veh-proximo-dates { font-size: 12px; color: var(--text-soft); margin-top: 2px; }

.veh-docs-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 12px;
}
.veh-doc-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  position: relative;
}
.veh-doc-icon { font-size: 28px; line-height: 1; }
.veh-doc-name { font-size: 13px; font-weight: 600; color: var(--text); word-break: break-word; }
.veh-doc-meta { font-size: 11px; color: var(--text-soft); }
.veh-doc-actions { display: flex; gap: 6px; margin-top: 4px; }

.veh-svc-list { display: flex; flex-direction: column; gap: 10px; }
.veh-svc-entry {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px 16px;
  display: grid;
  grid-template-columns: 90px 1fr auto;
  gap: 12px;
  align-items: start;
}
.veh-svc-date { font-size: 12px; font-weight: 600; color: var(--text-soft); }
.veh-svc-desc { font-size: 14px; font-weight: 500; color: var(--text); }
.veh-svc-meta { font-size: 12px; color: var(--text-soft); margin-top: 3px; }
.veh-svc-coste { font-size: 14px; font-weight: 700; color: var(--text); white-space: nowrap; }

.badge-activo       { background: rgba(52,199,89,.15); color: var(--text); }
.badge-en_servicio  { background: rgba(239,35,60,.13); color: var(--red); }
.badge-en_reparacion { background: rgba(255,149,0,.15); color: var(--text-soft); }

/* ── GANTT CALENDAR ────────────────────────────────────────────── */
.gantt-section {
  background: var(--surface);
  border-radius: var(--radius);
  border: 1px solid var(--border);
  padding: 16px 18px;
  margin-bottom: 18px;
}
.gantt-controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
  flex-wrap: wrap;
}
.gantt-legend { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.gantt-leg-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; }
.gantt-leg-lbl { font-size: 11px; color: var(--text-soft); }
.gantt-scroll { overflow-x: auto; }

.gantt-header-row {
  display: flex;
  border-bottom: 1.5px solid var(--border-med);
  margin-bottom: 2px;
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--surface);
}
.gantt-label-col {
  width: 148px;
  min-width: 148px;
  flex-shrink: 0;
  font-size: 11px;
  color: var(--text-soft);
  font-weight: 600;
  display: flex;
  align-items: flex-end;
  padding-bottom: 6px;
}
.gantt-day-hdr {
  width: 30px;
  min-width: 30px;
  flex-shrink: 0;
  text-align: center;
  padding-bottom: 4px;
}
.gantt-day-hdr .gd-wd {
  font-size: 9px;
  font-weight: 600;
  color: var(--text-xsoft);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.gantt-day-hdr .gd-num {
  font-size: 12px;
  font-weight: 700;
  color: var(--text-soft);
  margin-top: 1px;
}
.gantt-day-hdr.g-today .gd-num {
  color: var(--red);
}
.gantt-day-hdr.g-today .gd-num::after {
  content: '';
  display: block;
  width: 4px;
  height: 4px;
  background: var(--red);
  border-radius: 50%;
  margin: 2px auto 0;
}
.gantt-day-hdr.g-weekend { opacity: 0.45; }

.gantt-group-label {
  font-size: 10px;
  font-weight: 700;
  color: var(--text-xsoft);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding: 8px 0 3px 148px;
}
.gantt-event-row {
  display: flex;
  align-items: center;
  min-height: 40px;
  border-bottom: 1px solid rgba(43,45,66,0.05);
}
.gantt-event-row:nth-child(even) { background: rgba(43,45,66,0.018); }
.gantt-event-row:last-child { border-bottom: none; }
.gantt-event-row:hover { background: var(--bg-hover); }
.gantt-event-label {
  width: 148px;
  min-width: 148px;
  flex-shrink: 0;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text);
  padding-right: 12px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 1.2;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 2px;
}
.gantt-event-label small {
  display: block;
  font-size: 10.5px;
  color: var(--text-soft);
  font-weight: 400;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.gantt-cells {
  position: relative;
  flex: 1;
  height: 40px;
}
.gantt-today-line {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 2px;
  background: rgba(239,35,60,0.5);
  z-index: 1;
  pointer-events: none;
  border-radius: 0;
}
.gantt-bar {
  position: absolute;
  top: 7px;
  bottom: 7px;
  border-radius: 0;
  display: flex;
  align-items: center;
  padding: 0 10px;
  white-space: nowrap;
  overflow: hidden;
  font-size: 11.5px;
  font-weight: 600;
  color: #fff;
  z-index: 2;
  cursor: default;
  min-width: 6px;
  transition: filter 0.15s, opacity 0.15s;
  text-shadow: 0 1px 2px rgba(0,0,0,0.25);
  letter-spacing: -0.01em;
}

.gantt-bar:hover { filter: brightness(1.08); box-shadow: 0 2px 8px rgba(43,45,66,0.22); }
.gantt-bar.b-proyecto { background: var(--text); }
.gantt-bar.b-proyecto.activo { background: var(--red); }
.gantt-bar.b-alquiler { background: var(--text-soft); }
.gantt-bar.b-alquiler-overdue { background: var(--red); }
.gantt-bar.b-itv { background: var(--red); min-width: 60px !important; }
.gantt-bar.b-seguro { background: var(--text-soft); min-width: 60px !important; }
.gantt-empty { padding: 28px; text-align: center; color: var(--text-soft); font-size: 13px; }

/* ── DASHBOARD BOTTOM GRID ─────────────────────────────────────── */
.dash-bottom-grid {
  display: grid;
  grid-template-columns: 1fr 1.4fr 1fr;
  gap: 16px;
  align-items: start;
}
.dash-widget {
  background: var(--surface);
  border-radius: var(--radius);
  border: 1px solid var(--border);
  padding: 18px;
  position: relative;
  transition: opacity 0.15s, box-shadow 0.15s;
}
.dash-widget.dragging { opacity: 0.4; }
.dash-widget.drag-over {
  box-shadow: 0 0 0 2px var(--blue);
  border-color: var(--blue);
}
.dash-widget-drag-handle {
  position: absolute; top: 10px; right: 12px;
  font-size: 13px; color: var(--text-soft);
  opacity: 0; transition: opacity 0.15s;
  cursor: grab; user-select: none;
  pointer-events: none; letter-spacing: 2px;
}
.dash-widget:hover .dash-widget-drag-handle { opacity: 0.45; }

/* ── FLEET WIDGET ──────────────────────────────────────────────── */
.fleet-project-header {
  background: linear-gradient(135deg, var(--red) 0%, #0056B8 100%);
  border-radius: 0;
  padding: 14px 16px;
  color: #fff;
  margin-bottom: 14px;
}
.fleet-project-name {
  font-size: 16px;
  font-weight: 800;
  line-height: 1.2;
  margin-bottom: 4px;
}
.fleet-project-dates {
  font-size: 11px;
  opacity: 0.8;
  font-weight: 500;
}
.fleet-veh-list { display: flex; flex-direction: column; gap: 8px; }
.fleet-veh-card {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--bg);
  border-radius: 0;
  padding: 10px 12px;
  border: 1px solid var(--border);
}
.fleet-veh-icon {
  font-size: 22px;
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--surface);
  border-radius: 0;
  flex-shrink: 0;
  border: 1px solid var(--border);
}
.fleet-veh-info { flex: 1; min-width: 0; }
.fleet-veh-name { font-size: 13px; font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fleet-conductor { font-size: 11px; color: var(--text-soft); margin-top: 1px; }
.fleet-conductor.no-driver { color: var(--red); font-style: italic; }
.fleet-add-btn { margin-top: 12px; width: 100%; }

/* Flota row en modal proyecto */
.flota-row {
  display: flex;
  gap: 6px;
  align-items: center;
}
.flota-row select, .flota-row input {
  flex: 1;
  min-width: 0;
}

/* ── DOCUMENT PREVIEW ──────────────────────────────────────────── */
#preview-content img {
  max-width: 100%;
  max-height: 65vh;
  border-radius: 0;
  object-fit: contain;
}
#preview-content canvas {
  max-width: 100%;
  border-radius: 0;
  box-shadow: 0 4px 20px rgba(0,0,0,0.15);
}
.preview-no-preview {
  text-align: center;
  padding: 40px;
  color: var(--text-soft);
}
.preview-no-preview .preview-icon { font-size: 48px; margin-bottom: 10px; }

/* ── EMPLEADOS ────────────────────────────────────────────────── */
.emp-card {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px 16px;
  cursor: pointer;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.emp-card:hover { border-color: var(--accent); box-shadow: 0 2px 8px rgba(239,35,60,0.12); }
.emp-avatar {
  width: 44px; height: 44px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--red), var(--text));
  color: #fff;
  font-weight: 800;
  font-size: 16px;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.emp-info { flex: 1; min-width: 0; }
.emp-nombre { font-size: 14px; font-weight: 700; color: var(--text); }
.emp-meta { font-size: 12px; color: var(--text-soft); margin-top: 2px; }
.emp-contact { font-size: 11px; color: var(--text-soft); margin-top: 3px; }

/* ── STAT ICON ─────────────────────────────────────────────────── */
.stat-icon-lg {
  font-size: 22px;
  margin-bottom: 6px;
  display: block;
  line-height: 1;
}
.stat-card { transition: box-shadow 0.15s, transform 0.15s; }
.stat-card:hover { box-shadow: 0 4px 16px rgba(0,0,0,0.10); transform: translateY(-1px); }

/* ── VEHICLE BRAND BADGE ───────────────────────────────────────── */
.veh-brand-badge {
  width: 38px;
  height: 38px;
  border-radius: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 800;
  font-size: 11px;
  letter-spacing: 0.02em;
  flex-shrink: 0;
  box-shadow: 0 2px 6px rgba(0,0,0,0.18);
}

/* ── FLEET SECTION LABEL ───────────────────────────────────────── */
.fleet-section-label {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-soft);
  margin-bottom: 6px;
}
.fleet-project-header { margin-bottom: 8px; }

/* ── FLEET WIDGET REDESIGN ──────────────────────────────────────────── */
.fleet-proj-card {
  border-radius: 0;
  padding: 12px 14px;
  margin-bottom: 10px;
  border: 1px solid var(--border-light);
  background: var(--bg-card);
}
.active-proj {
  /* border-left color set dynamically per project via inline style */
}
.upcoming-proj {
  border-left: 3px solid var(--red);
  opacity: 0.85;
}
.fleet-proj-top {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 4px;
}
.fleet-proj-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}
.fleet-proj-dot.active   { background: var(--text); box-shadow: 0 0 0 3px rgba(52,199,89,0.2); }
.fleet-proj-dot.upcoming { background: var(--red); }
.fleet-proj-title {
  font-weight: 700;
  font-size: 13.5px;
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.fleet-proj-days {
  font-size: 11px;
  white-space: nowrap;
  flex-shrink: 0;
}
.fleet-proj-client {
  font-size: 11px;
  color: var(--text-soft);
  margin-bottom: 8px;
  margin-left: 16px;
}
.fleet-proj-dates-row {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 11.5px;
  color: var(--text-soft);
  margin-top: 6px;
}
.fleet-proj-progress-track {
  flex: 1;
  height: 4px;
  background: var(--border);
  border-radius: 0;
  overflow: hidden;
}
.fleet-proj-progress-fill {
  height: 4px;
  background: linear-gradient(90deg, var(--text), #30D158);
  border-radius: 0;
  transition: width 0.4s;
}
.fleet-proj-vehs {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 10px;
}
.fleet-proj-veh-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: var(--bg);
  border: 1px solid var(--border-light);
  border-radius: 0;
  padding: 3px 10px 3px 6px;
  font-size: 11.5px;
}
.fleet-pill-icon { font-size: 13px; }
.fleet-pill-name { font-weight: 500; }
.fleet-pill-driver { color: var(--text-soft); font-size: 10.5px; }
.fleet-upcoming-label {
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--text-soft);
  margin: 10px 0 6px;
}
.fleet-pill-count {
  background: var(--bg);
  border: 1px solid var(--border-light);
  border-radius: 0;
  padding: 2px 8px;
  font-size: 10.5px;
}

/* ── INVENTORY CHART (visual bars) ────────────────────────────── */
.inv-chart-total {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 12px;
}
.inv-chart-num {
  font-family: var(--font-display);
  font-size: 42px;
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.04em;
  color: var(--text);
}
.inv-chart-lbl {
  font-size: 12px;
  color: var(--text-soft);
  font-weight: 500;
}
.inv-stacked-bar {
  width: 100%;
  height: 10px;
  border-radius: 99px;
  overflow: hidden;
  display: flex;
  background: var(--bg);
  margin-bottom: 16px;
}
.inv-chart-rows { display: flex; flex-direction: column; gap: 10px; }
.inv-chart-row {
  display: flex;
  align-items: center;
  gap: 10px;
}
.inv-chart-dot {
  width: 10px; height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
}
.inv-chart-bar-wrap { flex: 1; min-width: 0; }
.inv-chart-bar-label {
  font-size: 11.5px;
  font-weight: 600;
  color: var(--text);
  margin-bottom: 4px;
}
.inv-chart-bar-track {
  width: 100%;
  height: 6px;
  background: var(--bg);
  border-radius: 99px;
  overflow: hidden;
}
.inv-chart-bar-fill {
  height: 100%;
  border-radius: 99px;
  transition: width 0.6s cubic-bezier(0.4, 0, 0.2, 1);
}
.inv-chart-nums {
  text-align: right;
  flex-shrink: 0;
  width: 56px;
}
.inv-chart-val {
  font-weight: 700;
  font-size: 13px;
  color: var(--text);
  display: block;
}
.inv-chart-pct {
  font-size: 11px;
  color: var(--text-soft);
}

/* ── INVENTARIO BULK TOOLBAR ────────────────────────────────────── */
.inv-bulk-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  background: var(--accent-blue, var(--red));
  border-radius: var(--radius-md, 8px);
  margin-bottom: 10px;
  animation: fadeIn 0.15s ease;
}
.inv-bulk-count {
  color: #fff;
  font-size: 13px;
  font-weight: 600;
  margin-right: 8px;
  white-space: nowrap;
}
.inv-bulk-bar .btn-ghost {
  background: rgba(255,255,255,0.18);
  color: #fff;
  border: 1px solid rgba(255,255,255,0.3);
}
.inv-bulk-bar .btn-ghost:hover {
  background: rgba(255,255,255,0.28);
}
.row-selected td {
  background: rgba(239,35,60, 0.05);
}

/* ── VEHÍCULOS MINI-DASHBOARD ───────────────────────────────────── */
#veh-dashboard {
  margin-bottom: 20px;
}
.veh-dash-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 10px;
  margin-bottom: 4px;
}
.veh-dash-card {
  background: var(--bg-card, #fff);
  border-radius: var(--radius-lg, 12px);
  box-shadow: 0 2px 8px rgba(0,0,0,0.06);
  padding: 14px 16px;
  position: relative;
  overflow: hidden;
  cursor: pointer;
  transition: transform 0.15s, box-shadow 0.15s;
}
.veh-dash-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 16px rgba(0,0,0,0.10);
}
.veh-dash-accent {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 3px;
  border-radius: 0 3px 0 0;
}
.veh-dash-card.green .veh-dash-accent  { background: linear-gradient(90deg, var(--text), #30D158); }
.veh-dash-card.red .veh-dash-accent    { background: linear-gradient(90deg, var(--red), #FF6961); }
.veh-dash-card.orange .veh-dash-accent { background: linear-gradient(90deg, var(--text-soft), #FFCC02); }
.veh-dash-card.yellow .veh-dash-accent { background: linear-gradient(90deg, #FFCC02, var(--text-soft)); }
.veh-dash-card.blue .veh-dash-accent   { background: linear-gradient(90deg, var(--red), #34AADC); }
.veh-dash-val {
  font-size: 36px;
  font-weight: 800;
  letter-spacing: -0.04em;
  line-height: 1;
  margin-top: 10px;
  margin-bottom: 4px;
}
.veh-dash-card.green .veh-dash-val  { color: var(--text); }
.veh-dash-card.red .veh-dash-val    { color: var(--red); }
.veh-dash-card.orange .veh-dash-val { color: var(--text-soft); }
.veh-dash-card.yellow .veh-dash-val { color: #B8860B; }
.veh-dash-card.blue .veh-dash-val   { color: var(--red); }
.veh-dash-label {
  font-size: 11.5px;
  font-weight: 500;
  color: var(--text-secondary, #86868b);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* ── ECONOMÍA ──────────────────────────────────────────────────── */
.eco-stats-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
  margin-bottom: 24px;
}
.eco-stats-row.eco-stats-5 {
  grid-template-columns: repeat(5, 1fr);
}
.eco-stat-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 0;
  padding: 22px 20px 18px;
  position: relative;
  overflow: hidden;
}
.eco-stat-card::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 3px;
  border-radius: 0 16px 0 0;
}
.eco-stat-green::before  { background: var(--green); }
.eco-stat-blue::before   { background: var(--blue); }
.eco-stat-orange::before { background: var(--text-soft); }
.eco-stat-gray::before   { background: var(--text-soft); }
.eco-stat-purple::before { background: #AF52DE; }
.eco-stat-icon {
  font-size: 18px; font-weight: 700;
  margin-bottom: 10px;
  opacity: 0.6;
}
.eco-stat-green .eco-stat-icon  { color: var(--green); }
.eco-stat-blue .eco-stat-icon   { color: var(--blue); }
.eco-stat-orange .eco-stat-icon { color: var(--text-soft); }
.eco-stat-purple .eco-stat-icon { color: #AF52DE; }
.eco-stat-val {
  font-size: 26px; font-weight: 800;
  letter-spacing: -0.03em; color: var(--text);
  margin-bottom: 4px; line-height: 1.1;
}
.eco-stat-lbl {
  font-size: 12px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--text-soft);
}
.eco-stat-sub {
  font-size: 11px; color: var(--text-muted);
  margin-top: 4px;
}
.eco-body { display: flex; flex-direction: column; gap: 20px; }
.eco-panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 0;
  padding: 20px 22px;
}
.eco-panel-title {
  font-size: 13px; font-weight: 700;
  color: var(--text); margin-bottom: 16px;
  display: flex; align-items: center; gap: 10px;
}
.eco-panel-legend { margin-left: auto; display: flex; gap: 10px; }
.eco-leg {
  font-size: 10px; font-weight: 600;
  padding: 2px 8px; border-radius: 0;
  text-transform: uppercase; letter-spacing: 0.04em;
}
.eco-leg-aceptado { background: rgba(52,199,89,0.15); color: var(--green); }
.eco-leg-pipeline  { background: rgba(255,149,0,0.15); color: var(--text-soft); }
.eco-panel-badge {
  font-size: 11px; font-weight: 700; padding: 1px 7px; border-radius: 0; margin-left: auto;
}
.eco-badge-blue   { background: rgba(239,35,60,0.12); color: var(--blue); }
.eco-badge-gray   { background: rgba(141,153,174,0.15); color: var(--text-soft); }
.eco-month-row {
  display: grid;
  grid-template-columns: 90px 1fr 160px;
  align-items: center;
  gap: 14px;
  padding: 6px 0;
  border-bottom: 1px solid var(--border-light);
}
.eco-month-row:last-child { border-bottom: none; }
.eco-month-label {
  font-size: 12px; font-weight: 600;
  color: var(--text-soft);
}
.eco-month-bar-bg {
  height: 8px; background: var(--bg);
  border-radius: 0; overflow: hidden;
  display: flex;
}
.eco-month-bar-fill {
  height: 100%;
  border-radius: 0;
  transition: width 0.3s ease;
}
.eco-bar-aceptado { background: var(--green); }
.eco-month-amount {
  text-align: right; font-size: 13px;
  white-space: nowrap;
}
.eco-cols {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}
.eco-proy-row {
  display: grid;
  grid-template-columns: 160px 1fr 120px;
  align-items: center;
  gap: 12px;
  padding: 5px 0;
  border-bottom: 1px solid var(--border-light);
}
.eco-proy-row:last-child { border-bottom: none; }
.eco-proy-name {
  font-size: 12px; font-weight: 500; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.eco-proy-bar-wrap {
  height: 6px; background: var(--bg); border-radius: 0; overflow: hidden;
}
.eco-proy-bar {
  height: 100%; border-radius: 0;
  background: var(--blue);
  transition: width 0.3s ease;
}
.eco-proy-amount {
  text-align: right; font-size: 12px; font-weight: 600; color: var(--text);
}

/* ── MANTENIMIENTO DASHBOARD ──────────────────────────────────── */
.mant-dashboard {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 0;
  padding: 16px 20px;
  margin-bottom: 20px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.mant-filter-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}
.mant-filter-label {
  font-size: 11px;
  font-weight: 600;
  color: var(--text-soft);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  min-width: 70px;
}
.mant-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 12px;
  border-radius: 0;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--text);
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.12s;
}
.mant-chip:hover { border-color: var(--accent); color: var(--accent); }
.mant-chip.active {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.mant-chip.active .mant-chip-count { background: rgba(255,255,255,0.2); color: #fff; }
.mant-chip-sm { padding: 3px 9px; font-size: 11px; }
.mant-chip-count {
  background: var(--border);
  color: var(--text-soft);
  border-radius: 0;
  padding: 0 5px;
  font-size: 10px;
  font-weight: 700;
  min-width: 16px;
  text-align: center;
}
.mant-filter-cats { padding-top: 2px; border-top: 1px solid var(--border-light); }

/* ── TELEFONÍA BULK BAR ──────────────────────────────────────── */
.tel-bulk-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 14px;
  background: var(--blue-light);
  border: 1px solid rgba(239,35,60,0.18);
  border-radius: 0;
  margin-bottom: 10px;
}
.tel-bulk-count {
  font-size: 13px;
  font-weight: 600;
  color: var(--blue);
  flex: 1;
}
.tel-row-selected {
  background: rgba(239,35,60,0.04) !important;
}
.tel-row-cb {
  cursor: pointer;
  width: 15px;
  height: 15px;
  accent-color: var(--blue);
}

/* ── RESPONSIVE ────────────────────────────────────────────────── */
@media (max-width: 1100px) {
  .dash-bottom-grid { grid-template-columns: 1fr; }
  .dashboard-grid { grid-template-columns: 1fr; }
  .dashboard-col-side { display: none; }
  .veh-dash-grid { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 720px) {
  .sidebar { display: none; }
  .main { padding: 0; }   /* el padding vive ahora en .main-scroll */
  .form-grid { grid-template-columns: 1fr; }
  .stats-grid { grid-template-columns: 1fr 1fr; }
  .veh-dash-grid { grid-template-columns: 1fr 1fr; }
}

/* ── IT TABS ──────────────────────────────────────────────────── */
.it-tabs {
  display: flex;
  gap: 4px;
  margin-bottom: 20px;
  background: var(--bg-card);
  padding: 4px;
  border-radius: 0;
  width: fit-content;
  box-shadow: 0 1px 3px rgba(0,0,0,.08);
}
.it-tab {
  background: transparent;
  border: none;
  padding: 7px 18px;
  border-radius: 0;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-soft);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.it-tab:hover { background: var(--bg-hover, rgba(0,0,0,.06)); color: var(--text-primary); }
.it-tab.active {
  background: var(--accent);
  color: #fff;
  font-weight: 600;
}
.it-tab.active:hover { background: var(--accent); color: #fff; }
.it-panel { }

/* ── IT DASHBOARD ────────────────────────────────────────────── */
.it-dash-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
  margin-bottom: 20px;
}
.it-dash-card {
  background: var(--bg-card);
  border-radius: 0;
  padding: 18px 20px 16px;
  cursor: pointer;
  border: 1.5px solid transparent;
  transition: border-color 0.15s, box-shadow 0.15s, transform 0.12s;
  position: relative;
  overflow: hidden;
  box-shadow: 0 1px 4px rgba(0,0,0,.07);
}
.it-dash-card:hover { box-shadow: 0 4px 14px rgba(0,0,0,.12); transform: translateY(-1px); border-color: var(--border); }
.it-dash-accent {
  position: absolute;
  top: 0; left: 0;
  width: 4px;
  height: 100%;
  border-radius: 0;
}
.it-dash-accent.blue   { background: #3b82f6; }
.it-dash-accent.orange { background: #f97316; }
.it-dash-accent.purple { background: #8b5cf6; }
.it-dash-val {
  font-size: 32px;
  font-weight: 700;
  color: var(--text-primary);
  line-height: 1.1;
  margin-bottom: 4px;
  padding-left: 10px;
}
.it-dash-label {
  font-size: 12px;
  color: var(--text-soft);
  font-weight: 500;
  padding-left: 10px;
}

/* ── PROYECTOS DASHBOARD ─────────────────────────────────────── */
.proy-dash-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 14px;
  margin-bottom: 20px;
}
.proy-dash-card {
  background: var(--bg-card);
  border-radius: 0;
  padding: 16px 18px 14px;
  box-shadow: 0 2px 8px rgba(0,0,0,.07);
  position: relative;
  overflow: hidden;
  cursor: default;
}
.proy-dash-accent {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 3px;
}
.proy-dash-icon {
  font-size: 20px;
  margin-bottom: 6px;
  opacity: 0.7;
}
.proy-dash-val {
  font-size: 34px;
  font-weight: 800;
  letter-spacing: -0.04em;
  line-height: 1;
  margin-bottom: 4px;
}
.proy-dash-label {
  font-size: 11.5px;
  font-weight: 500;
  color: var(--text-secondary, #86868b);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.proy-dash-card.green .proy-dash-accent { background: linear-gradient(90deg, var(--text), #30D158); }
.proy-dash-card.yellow .proy-dash-accent { background: linear-gradient(90deg, #FFCC02, var(--text-soft)); }
.proy-dash-card.blue .proy-dash-accent { background: linear-gradient(90deg, var(--red), #34AADC); }
.proy-dash-card.purple .proy-dash-accent { background: linear-gradient(90deg, #AF52DE, #7B61FF); }
.proy-dash-card.green .proy-dash-val { color: var(--text); }
.proy-dash-card.yellow .proy-dash-val { color: #B8860B; }
.proy-dash-card.blue .proy-dash-val { color: var(--red); }
.proy-dash-card.purple .proy-dash-val { color: #AF52DE; }
@media (max-width:900px) { .proy-dash-grid { grid-template-columns: 1fr 1fr; } }

/* ── CREW ROSTER ────────────────────────────────────────────── */
.crew-proj-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 20px;
}
.crew-proj-tab {
  background: var(--bg-card);
  border: none;
  border-radius: 0;
  padding: 8px 16px;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-soft);
  cursor: pointer;
  box-shadow: 0 1px 4px rgba(0,0,0,.07);
  transition: background 0.15s, color 0.15s, box-shadow 0.15s;
  display: flex;
  align-items: center;
  gap: 6px;
}
.crew-proj-tab:hover { background: var(--bg-hover, #f0f0f2); color: var(--text-primary); }
.crew-proj-tab.active {
  background: var(--accent);
  color: #fff;
  font-weight: 700;
  box-shadow: 0 2px 8px rgba(239,35,60,.25);
}
.crew-roles-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
}
.crew-role-card {
  background: var(--bg-card);
  border-radius: 0;
  box-shadow: 0 2px 8px rgba(0,0,0,.07);
  overflow: hidden;
}
.crew-role-label {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--text-soft);
  background: var(--bg-hover, rgba(0,0,0,.04));
  padding: 8px 14px;
  border-bottom: 1px solid var(--border-color, rgba(0,0,0,.06));
}
.crew-role-body {
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.crew-role-empty {
  font-size: 12px;
  color: var(--text-soft);
  opacity: 0.5;
  padding: 4px 0;
}
.crew-member-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--bg, #fafafa);
  border-radius: 0;
  padding: 7px 10px;
  gap: 8px;
}
.crew-member-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.crew-member-name {
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.crew-member-veh {
  font-size: 11px;
  color: var(--accent);
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.crew-member-noveh {
  font-size: 11px;
  color: var(--text-soft);
  opacity: 0.5;
}
.crew-add-btn {
  background: none;
  border: 1.5px dashed var(--border-color, rgba(0,0,0,.15));
  border-radius: 0;
  padding: 7px 12px;
  font-size: 12px;
  color: var(--text-soft);
  cursor: pointer;
  width: 100%;
  text-align: center;
  transition: border-color 0.15s, color 0.15s, background 0.15s;
}
.crew-add-btn:hover {
  border-color: var(--accent);
  color: var(--accent);
  background: rgba(239,35,60,.04);
}
.btn-xs {
  padding: 3px 8px;
  font-size: 11px;
  border-radius: 0;
}
@media (max-width: 900px) { .crew-roles-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 600px) { .crew-roles-grid { grid-template-columns: 1fr; } }

/* ── INVENTORY DASHBOARD ────────────────────────────────────── */
.inv-dash-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 18px;
}
.inv-dash-card {
  background: var(--bg-card);
  border-radius: 0;
  padding: 12px 16px 10px;
  box-shadow: 0 1px 5px rgba(0,0,0,.07);
  position: relative;
  overflow: hidden;
  cursor: pointer;
  transition: box-shadow 0.15s, transform 0.12s;
  min-width: 90px;
  text-align: center;
  border: 2px solid transparent;
}
.inv-dash-card:hover { box-shadow: 0 4px 12px rgba(0,0,0,.12); transform: translateY(-1px); }
.inv-dash-card.active { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(239,35,60,.15); }
.inv-dash-accent {
  position: absolute; top: 0; left: 0; right: 0; height: 3px;
}
.inv-dash-val {
  font-size: 26px;
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.1;
  margin-top: 4px;
}
.inv-dash-label {
  font-size: 11px;
  font-weight: 500;
  color: var(--text-secondary, #86868b);
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 110px;
}
/* Color variants */
.inv-dash-card.all .inv-dash-accent    { background: linear-gradient(90deg,#1D1D1F,#6E6E73); }
.inv-dash-card.all .inv-dash-val       { color: var(--text-primary); }
.inv-dash-card.blue .inv-dash-accent   { background: linear-gradient(90deg,var(--red),#34AADC); }
.inv-dash-card.blue .inv-dash-val      { color: var(--red); }
.inv-dash-card.green .inv-dash-accent  { background: linear-gradient(90deg,var(--text),#30D158); }
.inv-dash-card.green .inv-dash-val     { color: var(--text); }
.inv-dash-card.purple .inv-dash-accent { background: linear-gradient(90deg,#AF52DE,#7B61FF); }
.inv-dash-card.purple .inv-dash-val    { color: #AF52DE; }
.inv-dash-card.orange .inv-dash-accent { background: linear-gradient(90deg,var(--text-soft),#FFCC02); }
.inv-dash-card.orange .inv-dash-val    { color: var(--text-soft); }
.inv-dash-card.teal .inv-dash-accent   { background: linear-gradient(90deg,#5AC8FA,#30B0C7); }
.inv-dash-card.teal .inv-dash-val      { color: #30B0C7; }
.inv-dash-card.red .inv-dash-accent    { background: linear-gradient(90deg,var(--red),#FF6961); }
.inv-dash-card.red .inv-dash-val       { color: var(--red); }
.inv-dash-card.yellow .inv-dash-accent { background: linear-gradient(90deg,#FFCC02,var(--text-soft)); }
.inv-dash-card.yellow .inv-dash-val    { color: #B8860B; }
.inv-dash-card.indigo .inv-dash-accent { background: linear-gradient(90deg,#5856D6,#AF52DE); }
.inv-dash-card.indigo .inv-dash-val    { color: #5856D6; }

/* ── Badge: en proyecto ───────────────────────────────────────────────────── */
.badge-proyecto { background: rgba(239,35,60,.14); color: var(--red); max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.badge-reparacion { background: rgba(255,59,48,.13); color: var(--red); }

/* ── Fleet widget — Vehículos en proyecto ─────────────────────────────────── */
.fleet-ep-widget {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 0;
  padding: 14px 18px;
  margin-bottom: 18px;
}
.fleet-ep-header {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--text-secondary);
  margin-bottom: 10px;
}
.fleet-ep-list {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.fleet-ep-row {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 0;
  padding: 8px 12px;
  min-width: 190px;
  max-width: 280px;
  flex: 1;
}
.fleet-ep-proyecto {
  margin-left: auto;
  font-size: 11px;
  color: var(--red);
  background: rgba(239,35,60,.12);
  border-radius: 0;
  padding: 2px 7px;
  font-weight: 600;
  white-space: nowrap;
  max-width: 120px;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ── Vehicle brand logo ───────────────────────────────────────────────────── */
.veh-brand-logo-wrap {
  width: 44px;
  height: 32px;
  flex-shrink: 0;
  border-radius: 0;
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: center;
}
.veh-brand-logo-img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: 3px;
}
.veh-brand-badge {
  width: 44px;
  height: 32px;
  border-radius: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  flex-shrink: 0;
}


/* ── VEHICLE CALENDAR ────────────────────────────────────────────────────────── */

/* Page layout */
#page-veh-calendar .page-header { margin-bottom: 0; border-bottom: 1px solid var(--border); padding-bottom: 16px; }

/* Month navigator */
.cal-month-nav {
  display: flex;
  align-items: center;
  gap: 6px;
  background: var(--surface);
  border: 1px solid var(--border-med);
  border-radius: var(--radius);
  padding: 4px 6px;
  box-shadow: var(--shadow-xs);
}
.cal-month-nav-btn {
  width: 32px; height: 32px;
  border: none; background: none;
  cursor: pointer;
  border-radius: var(--radius-sm);
  color: var(--text-soft);
  font-size: 16px;
  display: flex; align-items: center; justify-content: center;
  transition: background 0.1s, color 0.1s;
}
.cal-month-nav-btn:hover { background: var(--platinum); color: var(--text); }
.cal-month-nav-label {
  font-size: 15px;
  font-weight: 700;
  color: var(--text);
  min-width: 160px;
  text-align: center;
  letter-spacing: -0.02em;
}

/* Project palette */
.cal-project-palette {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 14px 0 10px;
  overflow-x: auto;
  scrollbar-width: none;
  flex-wrap: wrap;
}
.cal-project-palette::-webkit-scrollbar { display: none; }

.cal-proj-card {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px 8px 10px;
  border-radius: 0;
  border: 2px solid transparent;
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  cursor: pointer;
  transition: all 0.12s;
  user-select: none;
  white-space: nowrap;
}
.cal-proj-card:hover { box-shadow: var(--shadow); transform: translateY(-1px); }
.cal-proj-card.selected {
  border-color: currentColor;
  box-shadow: 0 0 0 3px rgba(0,0,0,0.08), var(--shadow);
  transform: translateY(-1px);
}
.cal-proj-swatch {
  width: 16px; height: 16px;
  border-radius: 50%;
  flex-shrink: 0;
}
.cal-proj-card-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
}
.cal-proj-card-dates {
  font-size: 11px;
  color: var(--text-soft);
  margin-top: 1px;
}

.cal-eraser-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border-radius: 0;
  border: 2px solid var(--border-med);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-soft);
  transition: all 0.12s;
  white-space: nowrap;
}
.cal-eraser-btn:hover, .cal-eraser-btn.selected { border-color: var(--red); color: var(--red); background: rgba(239,35,60,0.06); }

/* Calendar grid wrapper */
.cal-veh-wrap {
  overflow-x: auto;
  overflow-y: auto;
  flex: 1;
  border-radius: var(--radius-lg);
  border: 1px solid var(--border-med);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  margin-top: 8px;
  max-height: calc(100vh - 300px);
}

.cal-veh-table {
  border-collapse: separate;
  border-spacing: 0;
  width: max-content;
  min-width: 100%;
  font-family: var(--font);
}

/* Sticky header */
/* ── LAS DOS FILAS DE CABECERA, UNA ENCIMA DE OTRA ────────────────────────────
   Aquí estaba lo de «SEM 39» pisando el «24» de la captura de Xavi.

   Las dos filas del `thead` —la de semanas y la de días— se pegaban arriba con
   el MISMO `top: 0`. O sea que al bajar, las dos se quedaban clavadas en la
   misma línea y se dibujaban una sobre la otra. No era un texto que se
   desbordaba: eran dos filas ocupando el mismo sitio.

   Ahora se apilan: la de semanas arriba del todo, y la de días justo debajo, a
   la altura exacta de la primera. La altura se fija a mano —no se puede leer en
   CSS la de otra fila— y por eso las dos reglas comparten el mismo 18 px. */
.cal-veh-table thead tr { position: sticky; z-index: var(--cal-z-cabecera, 40); }
.cal-veh-table thead tr.cal-veh-th-week-row,
.cal-veh-table thead tr.cal-veh-th-week-row th { top: 0; height: 18px; }
/* La altura de la fila de semanas la mide `_calMedirColumna` y la publica como
   `--cal-sem-h`: con el zoom del calendario esa fila crece y encoge, así que un
   número escrito a mano dejaría los días medio tapados en cuanto se toca el
   zoom. */
.cal-veh-table thead tr:not(.cal-veh-th-week-row),
.cal-veh-table thead tr:not(.cal-veh-th-week-row) th { top: var(--cal-sem-h, 25px); }
/* En Chrome `position: sticky` no la aplica al `<tr>`, solo a las celdas; en
   Safari y Firefox sí. Se pone en los dos para que se peguen en todos. */
.cal-veh-table thead th { position: sticky; }
.cal-veh-table thead tr.cal-veh-th-week-row th { z-index: var(--cal-z-cabecera, 40); }

/* Sticky vehicle column */
.cal-veh-th-veh, .cal-veh-td-veh { position: sticky; left: 0; z-index: var(--cal-z-columna, 30); }
.cal-veh-table thead .cal-veh-th-veh { z-index: var(--cal-z-esquina, 50); }

.cal-veh-th-veh {
  background: var(--text);
  color: var(--surface);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding: 14px 18px;
  text-align: left;
  min-width: 190px;
  border-right: 1px solid rgba(255,255,255,0.08);
  border-bottom: 1px solid rgba(255,255,255,0.06);
}

.cal-veh-th-day {
  background: var(--text);
  color: var(--surface);
  text-align: center;
  padding: 10px 2px 8px;
  min-width: 62px;
  border-right: 1px solid rgba(255,255,255,0.05);
  border-bottom: 1px solid rgba(255,255,255,0.06);
}
.cal-veh-th-day.cal-weekend { background: #1a1a1f; }
.cal-veh-th-day.cal-today-col { background: #1c2340; }

.cal-day-num {
  display: block;
  font-size: 20px;
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.02em;
}
.cal-day-name {
  display: block;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  opacity: 0.5;
  margin-top: 3px;
}
.cal-today-col .cal-day-num { color: var(--accent); }
.cal-today-col .cal-day-name { color: var(--accent); opacity: 0.8; }

/* Data rows */
.cal-veh-table tbody tr { border-bottom: 1px solid var(--border); transition: background 0.08s; }
.cal-veh-table tbody tr:last-child { border-bottom: none; }
.cal-veh-table tbody tr:hover .cal-veh-td-veh { background: rgba(67,97,238,0.03); }

.cal-veh-td-veh {
  padding: 8px 14px;
  border-right: 1px solid var(--border-med);
  min-width: 190px;
  background: var(--surface);
  vertical-align: middle;
  transition: background 0.1s;
}
.cal-veh-row-inner {
  display: flex;
  align-items: center;
  gap: 10px;
}
.cal-veh-logo-cell {
  flex-shrink: 0;
  width: 40px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.cal-veh-logo-cell .veh-brand-logo-wrap {
  width: 40px;
  height: 28px;
}
.cal-veh-logo-cell .veh-brand-logo-img {
  max-width: 36px;
  max-height: 24px;
  object-fit: contain;
}
.cal-veh-logo-cell .veh-brand-badge {
  width: 36px;
  height: 24px;
  font-size: 10px;
}
.cal-veh-name {
  font-size: 13px;
  font-weight: 700;
  color: var(--text);
  white-space: nowrap;
  line-height: 1.2;
}
.cal-veh-mat {
  font-size: 11px;
  color: var(--text-soft);
  margin-top: 1px;
  white-space: nowrap;
  font-family: 'SF Mono', 'Monaco', monospace;
  letter-spacing: 0.04em;
}

/* Day cells — NO display:flex on <td> (breaks table layout in some browsers) */
.cal-veh-td-day {
  /* El mismo ancho que declara el `<colgroup>`. Estaban en desacuerdo —la
     columna decía 32 y la casilla 62— y ganaba la casilla, así que el
     `<colgroup>` no servía para nada y el ancho real solo se sabía midiendo.
     Con los dos iguales, el navegador reparte a la primera. */
  min-width: 62px;
  height: 60px;
  padding: 0;
  border-right: 1px solid var(--border);
  cursor: pointer;
  position: relative;
  transition: background 0.1s;
  box-sizing: border-box;
  vertical-align: middle;
}
/* Inner wrapper carries the flex layout instead of the <td> itself.

   VA ABSOLUTO, pegado a los cuatro lados de la casilla, y no con `height:100%`.
   Es lo que arreglaba la captura de Xavi, donde las barras no cuadraban con sus
   filas: un porcentaje de alto dentro de un `<td>` se resuelve contra un alto
   AUTOMÁTICO, así que en cuanto una fila crecía —y crece sola en cuanto el
   vehículo lleva la chapa de «ITV 12/09», la de «Taller» o la de «En
   reparación»— la casilla se estiraba y este envoltorio se quedaba a 60 px. La
   barra de color se centraba respecto a un alto que ya no era el de la fila, y
   aparecía desplazada arriba o abajo, invadiendo la fila de al lado.

   Con `position:absolute; inset:0` contra el `<td>` (que ya es `relative`) el
   envoltorio mide SIEMPRE lo que mide su casilla, crezca lo que crezca. */
.cal-cell-wrap {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: center;
  gap: 2px;
}
.cal-veh-td-day:hover {
  background: rgba(239,35,60,0.06);
}
.cal-veh-td-day:hover::after {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: rgba(239,35,60,0.30);
  pointer-events: none;
}
.cal-veh-td-day.cal-assigned:hover::after { display: none; }
.cal-veh-td-day.cal-weekend { background: rgba(43,45,66,0.035); }
.cal-veh-td-day.cal-today-col { background: rgba(239,35,60,0.055); }
.cal-veh-td-day.cal-today-col::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: var(--blue);
  pointer-events: none;
  z-index: 3;
}
.cal-veh-td-day.cal-drag-over  { background: rgba(239,35,60,0.16) !important; }
.cal-veh-td-day.cal-erase-over { background: rgba(239,35,60,0.10) !important; }

/* Cell inner content */
.cal-cell-inner {
  flex: 0 0 auto;
  min-height: 38px;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  position: relative;
  /* Solo el brillo se anima. La sombra NO: el realce de la fila entera
     (`.cal-veh-row:hover`) la cambia en TODAS las celdas pintadas de la fila,
     y animarla obligaba a repintar la fila completa —noventa columnas— cada
     vez que el ratón cruzaba de una fila a otra. Se ve igual y ya no tironea. */
  transition: filter var(--transition);
}
/* Relieve de la barra. Sólo sombras INSET verticales: una sombra exterior
   crearía costuras verticales donde se unen los días de un mismo tramo. */
.cal-cell-inner.filled {
  box-shadow:
    inset 0  1px 0 rgba(255,255,255,0.30),
    inset 0 -1px 0 rgba(0,0,0,0.20);
}
/* Degradado vertical: da volumen sin cortar el tramo horizontalmente. */
.cal-cell-inner.filled::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom,
    rgba(255,255,255,0.18) 0%,
    rgba(255,255,255,0.04) 45%,
    rgba(0,0,0,0.10) 100%);
  pointer-events: none;
}
.cal-veh-td-day.cal-assigned .cal-cell-inner:hover {
  filter: brightness(1.10) saturate(1.05);
}
.cal-cell-label {
  font-size: 10px;
  font-weight: 700;
  color: #fff;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 56px;
  padding: 0 3px;
  position: relative;
  z-index: 1;
  text-shadow: 0 1px 2px rgba(0,0,0,0.3);
}

/* Legend */
.cal-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 0 0 10px;
}
.cal-legend-item {
  display: flex;
  align-items: center;
  gap: 5px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 0;
  padding: 4px 10px 4px 7px;
  font-size: 12px;
  font-weight: 500;
  color: var(--text);
  box-shadow: var(--shadow-xs);
}
.cal-legend-dot {
  width: 10px; height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
}

/* Selection hint */
.cal-selection-hint {
  font-size: 12px;
  color: var(--text-soft);
  padding: 8px 0 4px;
  display: flex;
  align-items: center;
  gap: 6px;
}
.cal-selection-hint strong { color: var(--text); }
.cal-sel-hint-text {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: var(--surface);
  border: 1px solid var(--border-med);
  border-radius: 0;
  padding: 5px 14px;
  font-size: 12px;
  font-weight: 500;
  color: var(--text-soft);
  box-shadow: var(--shadow-xs);
}
.cal-veh-td-day.cal-assigned .cal-cell-inner { cursor: cell; }
.cal-veh-td-day { user-select: none; -webkit-user-select: none; }

/* ── Vehicle Calendar: row stripes & conductor ─────────────────────────── */
.cal-veh-row { transition: background 0.05s; }
.cal-veh-row.cal-row-alt .cal-veh-td-day:not(.cal-assigned) {
  background: rgba(141,153,174,0.06);
}
/* La columna de vehículos va OPACA: es sticky y, si es translúcida, la barra
   del evento que queda por debajo al desplazar en horizontal se transparenta.
   rgb(248,249,250) es ese mismo rgba(141,153,174,0.06) compuesto sobre blanco. */
.cal-veh-row.cal-row-alt .cal-veh-td-veh { background: rgb(248,249,250); }
.cal-veh-row:hover .cal-veh-td-veh { background: rgb(244,246,254); }
.cal-veh-table tbody tr { border-bottom: 1px solid var(--border-med); }
.cal-veh-table tbody tr:last-child { border-bottom: none; }

/* Conductor name inside cell */
.cal-cell-conductor {
  display: block;
  font-size: 9.5px;
  font-weight: 600;
  color: rgba(255,255,255,0.88);
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 52px;
  padding: 0 3px;
  margin-top: 1px;
  position: relative;
  z-index: 1;
  text-shadow: 0 1px 2px rgba(0,0,0,0.4);
  letter-spacing: 0.01em;
  background: rgba(0,0,0,0.18);
  border-radius: 0;
}

/* Conductor edit popup */
.cal-conductor-popup {
  position: fixed;
  z-index: 2000;
  background: var(--surface);
  border: 1px solid var(--border-med);
  border-radius: 0;
  padding: 12px 14px 10px;
  width: 240px;
  box-shadow: 0 8px 32px rgba(0,0,0,0.22);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.cal-conductor-popup-header {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-soft);
  display: flex;
  align-items: center;
  gap: 5px;
}
.cal-conductor-inp {
  width: 100%;
  box-sizing: border-box;
  padding: 7px 10px;
  border: 1px solid var(--border-med);
  border-radius: 0;
  font-size: 13px;
  background: var(--bg);
  color: var(--text);
  outline: none;
}
.cal-conductor-inp:focus { border-color: var(--accent); box-shadow: 0 0 0 2px rgba(67,97,238,0.15); }
.cal-conductor-actions {
  display: flex;
  justify-content: flex-end;
  gap: 6px;
}

/* Gantt: clickable labels */
.gantt-event-label.gantt-label-link {
  cursor: pointer;
}
.gantt-event-label.gantt-label-link:hover {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.gantt-bar { cursor: default; }
.gantt-bar[onclick] { cursor: pointer; }
.gantt-bar[onclick]:hover { filter: brightness(1.12); }

/* ===================================================
   Vehicle Calendar — Run bars (merged consecutive days)
   =================================================== */

/* Remove right border on start/mid so bars merge seamlessly */
.cal-veh-td-day.cal-run-start,
.cal-veh-td-day.cal-run-mid {
  border-right: none !important;
  padding-right: 0 !important;
}
/* Remove left padding on mid/end so bars are flush */
.cal-veh-td-day.cal-run-mid,
.cal-veh-td-day.cal-run-end {
  padding-left: 0 !important;
}

/* Base cell inner — shared by all run positions.
   La barra "flota" dentro de la fila: margen vertical fijo, y el redondeo se
   aplica sólo en los extremos del tramo para que los días consecutivos se
   lean como una sola píldora continua. */
.cal-veh-td-day .cal-cell-inner {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  height: 38px;
  margin: 0;
  position: relative;
  font-size: 11px;
  font-weight: 500;
  color: #fff;
  overflow: hidden;
  border-radius: 0;
  background: transparent;
  padding: 0 4px;
  box-sizing: border-box;
}

/* Unassigned / empty cells */
.cal-veh-td-day:not(.cal-assigned) .cal-cell-inner {
  background: transparent;
  color: transparent;
  box-shadow: none;
}
.cal-veh-td-day:not(.cal-assigned) .cal-cell-inner::after { display: none; }

/* Un solo día: píldora completa */
.cal-veh-td-day.cal-run-solo .cal-cell-inner {
  border-radius: var(--cal-bar-radius);
  margin: 0 3px;
  padding: 0 5px;
  justify-content: center;
  align-items: center;
  box-shadow:
    inset 0  1px 0 rgba(255,255,255,0.30),
    inset 0 -1px 0 rgba(0,0,0,0.20),
    0 1px 3px rgba(43,45,66,0.20);
}

/* Inicio de tramo: redondeado sólo a la izquierda */
.cal-veh-td-day.cal-run-start .cal-cell-inner {
  border-radius: var(--cal-bar-radius) 0 0 var(--cal-bar-radius);
  margin: 0 0 0 3px;
  padding-left: 8px;
  padding-right: 0;
  align-items: flex-start;
}

/* Centro de tramo: recto por ambos lados, ancho completo */
.cal-veh-td-day.cal-run-mid .cal-cell-inner {
  border-radius: 0;
  margin: 0;
  padding: 0;
  width: 100%;
}

/* Fin de tramo: redondeado sólo a la derecha */
.cal-veh-td-day.cal-run-end .cal-cell-inner {
  border-radius: 0 var(--cal-bar-radius) var(--cal-bar-radius) 0;
  margin: 0 3px 0 0;
  padding-left: 0;
  padding-right: 6px;
}

/* Marca vertical al inicio del tramo: ancla visualmente dónde empieza */
.cal-veh-td-day.cal-run-start .cal-cell-inner::before,
.cal-veh-td-day.cal-run-solo .cal-cell-inner::before {
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 2.5px;
  background: rgba(255,255,255,0.48);
  border-radius: var(--cal-bar-radius) 0 0 var(--cal-bar-radius);
  pointer-events: none;
  z-index: 2;
}

/* Al pasar el ratón, el tramo entero se realza */
.cal-veh-row:hover .cal-cell-inner.filled {
  box-shadow:
    inset 0  1px 0 rgba(255,255,255,0.38),
    inset 0 -1px 0 rgba(0,0,0,0.22);
}

/* Run label — only shown in start/solo positions */
.cal-run-label {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 120px;
  pointer-events: none;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0em;
  opacity: 0.98;
  position: relative;
  z-index: 1;
  text-shadow: 0 1px 3px rgba(0,0,0,0.4);
}
/* Project sub-label shown below conductor name */
.cal-proy-sub {
  font-size: 10px;
  font-weight: 500;
  opacity: 0.82;
  pointer-events: none;
  letter-spacing: 0em;
  text-shadow: 0 1px 2px rgba(0,0,0,0.3);
}

/* Conductor chip — shown inline when conductor is assigned (name on top, bigger) */
.cal-cond-chip {
  font-size: 11.5px;
  font-weight: 700;
  color: rgba(255,255,255,0.98);
  background: rgba(0,0,0,0.22);
  border: 1px solid rgba(255,255,255,0.2);
  border-radius: 0;
  padding: 2px 9px;
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 110px;
  line-height: 1.45;
  position: relative;
  z-index: 1;
  transition: background var(--transition), border-color var(--transition);
  pointer-events: auto;
  text-shadow: 0 1px 3px rgba(0,0,0,0.35);
}
.cal-cond-chip:hover {
  background: rgba(0,0,0,0.42);
  border-color: rgba(255,255,255,0.34);
}

/* "+ conductor" — shown when no conductor, subtle until hover */
.cal-cond-add {
  font-size: 9px;
  font-weight: 500;
  color: rgba(255,255,255,0.62);
  cursor: pointer;
  padding: 0 5px;
  border-radius: 0;
  white-space: nowrap;
  opacity: 0;
  position: relative;
  z-index: 1;
  transition: opacity var(--transition), background var(--transition);
  pointer-events: auto;
}
.cal-veh-td-day:hover .cal-cond-add { opacity: 1; }
.cal-cond-add:hover { background: rgba(0,0,0,0.26); color: #fff; }

/* ===================================================
   Vehicle Calendar — Vehicle row repair state
   =================================================== */

/* Dim the entire row when vehicle estado = reparacion */
.cal-row-repair .cal-veh-td-day {
  opacity: 0.55;
}
/* Solo las celdas de DÍA: el `position: relative` es para anclar el rayado
   del día, y puesto en todas las celdas pisaba el `position: sticky` del
   nombre del vehículo, que en las filas en reparación se iba con el fondo al
   desplazar. El nombre tiene que quedarse fijo siempre, esté como esté el
   vehículo. */
.cal-row-repair td.cal-veh-td-day {
  position: relative;
}

/* Repair overlay stripe on a specific day */
.cal-day-repair .cal-cell-inner {
  background: repeating-linear-gradient(
    -45deg,
    rgba(239,68,68,0.15),
    rgba(239,68,68,0.15) 4px,
    transparent 4px,
    transparent 10px
  ) !important;
  border-radius: 0;
  margin: 2px 3px;
}

/* Repair badge on the vehicle name cell */
.cal-veh-repair-badge {
  display: inline-block;
  background: #ef4444;
  color: #fff;
  font-size: 9px;
  font-weight: 700;
  padding: 1px 5px;
  border-radius: 0;
  margin-left: 4px;
  vertical-align: middle;
  letter-spacing: 0.3px;
}

/* ===================================================
   Vehicle Calendar — Vehicle event (ITV / Seguro) badges
   =================================================== */

/* Event badge row — normal flow, below the bar */
.cal-vev-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 2px;
  min-height: 14px;
  flex-shrink: 0;
}

.cal-vev {
  font-size: 9px;
  font-weight: 700;
  padding: 1px 5px;
  border-radius: 0;
  line-height: 13px;
  letter-spacing: 0.2px;
  cursor: default;
  white-space: nowrap;
}

.cal-vev-itv {
  background: #f59e0b;
  color: #fff;
}

.cal-vev-seg {
  background: #8b5cf6;
  color: #fff;
}

/* ===================================================
   Vehicle Calendar — Manual event cells (ITV / Mant)
   =================================================== */

/* ITV manual — rayado diagonal ámbar */
.cal-veh-td-day.cal-event-itv .cal-cell-inner,
.cal-veh-td-day.cal-event-itv.cal-run-solo .cal-cell-inner,
.cal-veh-td-day.cal-event-itv.cal-run-start .cal-cell-inner,
.cal-veh-td-day.cal-event-itv.cal-run-mid .cal-cell-inner,
.cal-veh-td-day.cal-event-itv.cal-run-end .cal-cell-inner {
  background: repeating-linear-gradient(
    -45deg,
    #f0a018,
    #f0a018 5px,
    #d98a0c 5px,
    #d98a0c 10px
  ) !important;
}

/* Mantenimiento manual — rayado diagonal rojo */
.cal-veh-td-day.cal-event-mantenimiento .cal-cell-inner,
.cal-veh-td-day.cal-event-mantenimiento.cal-run-solo .cal-cell-inner,
.cal-veh-td-day.cal-event-mantenimiento.cal-run-start .cal-cell-inner,
.cal-veh-td-day.cal-event-mantenimiento.cal-run-mid .cal-cell-inner,
.cal-veh-td-day.cal-event-mantenimiento.cal-run-end .cal-cell-inner {
  background: repeating-linear-gradient(
    -45deg,
    #e84b4b,
    #e84b4b 5px,
    #cc3333 5px,
    #cc3333 10px
  ) !important;
}
/* En los eventos rayados el degradado de volumen estorba: se atenúa */
.cal-veh-td-day.cal-event-itv .cal-cell-inner::after,
.cal-veh-td-day.cal-event-mantenimiento .cal-cell-inner::after {
  background: linear-gradient(to bottom, rgba(0,0,0,0.06), rgba(0,0,0,0.16));
}

/* ===================================================
   Vehicle Calendar — Vehicle name edit button
   =================================================== */

.cal-veh-edit-btn {
  display: none;
  background: none;
  border: none;
  cursor: pointer;
  font-size: 11px;
  color: var(--text-muted);
  padding: 1px 3px;
  border-radius: 0;
  margin-left: 4px;
  vertical-align: middle;
  line-height: 1;
}
.cal-veh-name-cell:hover .cal-veh-edit-btn { display: inline-block; }
.cal-veh-edit-btn:hover { background: var(--bg-hover); color: var(--accent); }

/* ===================================================
   Vehicle Calendar — Quick edit popup (ITV / Seguro / Estado)
   =================================================== */

.cal-veh-qedit {
  position: fixed;
  z-index: 9999;
  background: var(--bg-card, #fff);
  border: 1px solid var(--border-med, #e2e8f0);
  border-radius: 0;
  padding: 14px 16px;
  min-width: 230px;
  box-shadow: 0 8px 32px rgba(0,0,0,0.18);
  font-family: inherit;
}

.cal-veh-qedit-title {
  font-size: 13px;
  font-weight: 700;
  color: var(--text);
  margin-bottom: 12px;
  display: flex;
  align-items: center;
  gap: 6px;
}

.cal-veh-qedit-row {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-bottom: 10px;
}

.cal-veh-qedit-row label {
  font-size: 11px;
  font-weight: 600;
  color: var(--text-muted, #64748b);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.cal-veh-qedit-row input,
.cal-veh-qedit-row select {
  padding: 6px 9px;
  border: 1px solid var(--border-med, #e2e8f0);
  border-radius: 0;
  font-size: 13px;
  background: var(--bg, #fff);
  color: var(--text, #1a202c);
  outline: none;
  width: 100%;
  box-sizing: border-box;
}

.cal-veh-qedit-row input:focus,
.cal-veh-qedit-row select:focus {
  border-color: var(--accent, #4361ee);
  box-shadow: 0 0 0 2px rgba(67,97,238,0.15);
}

.cal-veh-qedit-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  margin-top: 4px;
}

.cal-veh-qedit-actions button {
  padding: 6px 14px;
  border-radius: 0;
  border: none;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: opacity 0.15s;
}

.cal-veh-qedit-actions button:first-child {
  background: var(--bg-hover, #f1f5f9);
  color: var(--text-muted, #64748b);
}

.cal-veh-qedit-actions button:last-child {
  background: var(--accent, #4361ee);
  color: #fff;
}

.cal-veh-qedit-actions button:hover { opacity: 0.85; }

/* Backdrop to close popup on outside click */
.cal-veh-qedit-backdrop {
  position: fixed;
  inset: 0;
  z-index: 9998;
  background: transparent;
}

/* ===================================================
   Vehicle Calendar — Week / Month header row
   =================================================== */

.cal-veh-th-week-row th {
  background: #18181f;
  color: rgba(255,255,255,0.5);
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding: 4px 0 3px;
  text-align: center;
  border-bottom: 1px solid rgba(255,255,255,0.06);
}
.cal-veh-th-week-cell {
  border-right: 1px solid rgba(255,255,255,0.1) !important;
  background: #18181f !important;
  color: rgba(255,255,255,0.55) !important;
  font-size: 9px !important;
  font-weight: 700 !important;
  text-align: left !important;
  padding: 4px 6px 3px !important;
}
.cal-veh-th-week-span {
  background: #18181f !important;
  color: rgba(255,255,255,0.35) !important;
  font-size: 9px !important;
  font-weight: 600 !important;
  text-align: center !important;
  padding: 4px 0 3px !important;
  border-right: 1px solid rgba(255,255,255,0.04) !important;
}
.cal-veh-th-week-span:last-child {
  border-right: none !important;
}
/* Today accent on week header */
.cal-veh-th-week-span.cal-today-col {
  background: rgba(76,201,240,0.1) !important;
  color: var(--accent) !important;
}

/* ===================================================
   Flota Checklists — Tasks page
   =================================================== */

.flt-page { display: flex; flex-direction: column; gap: 0; height: 100%; }

/* Dashboard stats bar */
.flt-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 20px;
  margin-bottom: 28px;
}
.flt-stat {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 0;
  padding: 22px 24px 20px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  transition: box-shadow 0.15s, border-color 0.15s;
}
.flt-stat:hover {
  border-color: var(--blue);
  box-shadow: 0 2px 12px rgba(239,35,60,0.08);
}
.flt-stat-val {
  font-size: 32px;
  font-weight: 800;
  line-height: 1;
  color: var(--text);
  letter-spacing: -0.02em;
}
.flt-stat-lbl {
  font-size: 11px;
  color: var(--text-muted);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  margin-top: 2px;
}
.flt-stat-bar {
  height: 4px;
  background: var(--border);
  border-radius: 0;
  margin-top: 10px;
  overflow: hidden;
}
.flt-stat-bar-fill {
  height: 100%;
  border-radius: 0;
  background: var(--accent);
  transition: width 0.4s ease;
}

/* Main layout — 3 columns: projects | checklists | detail */
.flt-body {
  display: grid;
  grid-template-columns: 200px 260px 1fr;
  gap: 16px;
  min-height: 0;
  flex: 1;
}

/* Sidebar: list of checklists */
.flt-sidebar {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.flt-sidebar-header {
  padding: 14px 16px;
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 12px;
  font-weight: 700;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.07em;
  flex-shrink: 0;
}
.flt-list {
  overflow-y: auto;
  flex: 1;
  padding: 8px 0;
}
.flt-list-item {
  padding: 10px 16px;
  cursor: pointer;
  border-left: 3px solid transparent;
  transition: background 0.1s, border-color 0.1s;
}
.flt-list-item:hover { background: var(--bg-hover); }
.flt-list-item.active {
  background: rgba(67,97,238,0.08);
  border-left-color: var(--accent);
}
.flt-list-item-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.flt-list-item-meta {
  font-size: 11px;
  color: var(--text-muted);
  margin-top: 2px;
  display: flex;
  align-items: center;
  gap: 6px;
}
.flt-progress-mini {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 10px;
  font-weight: 700;
}
.flt-progress-mini-bar {
  width: 36px;
  height: 3px;
  background: var(--border);
  border-radius: 0;
  overflow: hidden;
}
.flt-progress-mini-fill {
  height: 100%;
  border-radius: 0;
  background: #06d6a0;
  transition: width 0.3s ease;
}

/* Detail panel */
.flt-detail {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.flt-detail-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  gap: 10px;
  color: var(--text-soft);
}
.flt-detail-empty svg { opacity: 0.25; }
.flt-detail-header {
  padding: 16px 20px;
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-shrink: 0;
  gap: 12px;
}
.flt-detail-title {
  font-size: 17px;
  font-weight: 800;
  color: var(--text);
  flex: 1;
  min-width: 0;
}
.flt-detail-subtitle {
  font-size: 12px;
  color: var(--text-muted);
  margin-top: 2px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.flt-progress-bar {
  width: 80px;
  height: 5px;
  background: var(--border);
  border-radius: 0;
  overflow: hidden;
  display: inline-block;
  vertical-align: middle;
}
.flt-progress-fill {
  height: 100%;
  border-radius: 0;
  background: #06d6a0;
  transition: width 0.4s ease;
}

/* Add item form */
.flt-add-form {
  background: var(--bg);
  border-bottom: 1px solid var(--border);
  padding: 12px 20px;
  display: flex;
  gap: 8px;
  align-items: flex-end;
  flex-wrap: wrap;
  flex-shrink: 0;
}
.flt-add-form .form-group {
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.flt-add-form label {
  font-size: 10px;
  font-weight: 700;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.flt-add-form input,
.flt-add-form select {
  padding: 6px 10px;
  border: 1px solid var(--border-med);
  border-radius: 0;
  font-size: 13px;
  background: var(--surface);
  color: var(--text);
  outline: none;
}
.flt-add-form input:focus,
.flt-add-form select:focus { border-color: var(--accent); }
.flt-add-form input.flt-task-input { min-width: 200px; flex: 1; }

/* Items list */
.flt-items {
  overflow-y: auto;
  flex: 1;
  padding: 8px 20px 16px;
}

/* Group by vehicle */
.flt-veh-group {
  margin-bottom: 18px;
}
.flt-veh-group-header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 0 6px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 6px;
  font-size: 12px;
  font-weight: 700;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

/* Individual task item */
.flt-task {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 14px;
  border-radius: 0;
  border: 1px solid var(--border);
  background: var(--surface);
  transition: background 0.1s, border-color 0.1s, box-shadow 0.1s;
  margin-bottom: 8px;
}
.flt-task:hover {
  background: var(--bg-hover);
  border-color: var(--border);
}
.flt-task.done {
  opacity: 0.55;
}
.flt-task-check {
  width: 18px;
  height: 18px;
  border-radius: 0;
  border: 2px solid var(--border-med);
  background: transparent;
  cursor: pointer;
  flex-shrink: 0;
  margin-top: 1px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: border-color 0.15s, background 0.15s;
}
.flt-task-check:hover { border-color: var(--accent); }
.flt-task.done .flt-task-check {
  background: #06d6a0;
  border-color: #06d6a0;
}
.flt-task-check-icon { display: none; color: #fff; font-size: 12px; font-weight: 900; }
.flt-task.done .flt-task-check-icon { display: block; }

.flt-task-body { flex: 1; min-width: 0; }
.flt-task-text {
  font-size: 13px;
  font-weight: 500;
  color: var(--text);
  line-height: 1.4;
}
.flt-task.done .flt-task-text { text-decoration: line-through; color: var(--text-muted); }
.flt-task-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 3px;
  font-size: 11px;
  color: var(--text-soft);
}
.flt-task-notas {
  font-size: 11px;
  color: var(--text-muted);
  margin-top: 2px;
  font-style: italic;
}
.flt-task-actions { display: flex; gap: 4px; opacity: 0; transition: opacity 0.1s; flex-shrink: 0; }
.flt-task:hover .flt-task-actions { opacity: 1; }

/* Priority pill */
.flt-prio {
  font-size: 10px;
  font-weight: 700;
  padding: 1px 6px;
  border-radius: 0;
  letter-spacing: 0.04em;
}
.flt-prio-alta { background: rgba(239,68,68,0.12); color: #ef4444; }
.flt-prio-media { background: rgba(245,158,11,0.12); color: #f59e0b; }
.flt-prio-baja { background: rgba(6,214,160,0.12); color: #06d6a0; }

/* Category pill */
.flt-cat {
  font-size: 10px;
  color: var(--text-muted);
  background: var(--bg);
  padding: 1px 6px;
  border-radius: 0;
  border: 1px solid var(--border);
}

/* Create checklist modal */
.flt-new-modal {
  position: fixed;
  z-index: 9999;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 0;
  padding: 20px 24px;
  min-width: 340px;
  max-width: 420px;
  box-shadow: 0 12px 48px rgba(0,0,0,0.22);
  top: 50%;
  left: 50%;
  transform: translate(-50%,-50%);
}
.flt-new-modal-title {
  font-size: 17px;
  font-weight: 800;
  margin-bottom: 14px;
  color: var(--text);
}
.flt-new-modal .form-group { margin-bottom: 12px; }
.flt-new-modal label {
  font-size: 11px;
  font-weight: 700;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  display: block;
  margin-bottom: 4px;
}
.flt-new-modal input,
.flt-new-modal select,
.flt-new-modal textarea {
  width: 100%;
  box-sizing: border-box;
  padding: 8px 12px;
  border: 1px solid var(--border-med);
  border-radius: 0;
  font-size: 13px;
  background: var(--bg);
  color: var(--text);
  outline: none;
}
.flt-new-modal input:focus,
.flt-new-modal select:focus,
.flt-new-modal textarea:focus { border-color: var(--accent); }
.flt-new-modal-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  margin-top: 16px;
}
.flt-modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 9998;
  background: rgba(0,0,0,0.3);
}

/* Palette — manual event type buttons */
.cal-event-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border-radius: 0;
  border: 2px solid transparent;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  transition: all 0.15s;
  background: var(--bg);
  color: var(--text);
}
.cal-event-btn:hover { opacity: 0.85; }
.cal-event-btn.cal-event-itv-btn {
  border-color: #f59e0b;
  color: #f59e0b;
}
.cal-event-btn.cal-event-itv-btn.selected {
  background: #f59e0b;
  color: #fff;
}
.cal-event-btn.cal-event-mant-btn {
  border-color: #ef4444;
  color: #ef4444;
}
.cal-event-btn.cal-event-mant-btn.selected {
  background: #ef4444;
  color: #fff;
}

/* Calendar week/month header cells */
/* La etiqueta de la semana, encerrada en su cabecera.

   Sin esto, una semana cortada por el borde de la ventana —dos días de la
   semana 39, por ejemplo— dejaba «SEM 39» más ancho que su propia celda, y el
   texto se derramaba encima del número del día de al lado. Es lo que se ve en
   la captura, con «SEM 39» pisando el 24. */
.cal-week-label {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.cal-veh-th-week-span { overflow: hidden; }

/* ===================================================
   Mi Perfil
   =================================================== */
.perfil-layout {
  display: grid;
  grid-template-columns: 280px 1fr;
  gap: 24px;
  align-items: flex-start;
  max-width: 900px;
}
@media (max-width: 700px) { .perfil-layout { grid-template-columns: 1fr; } }
.perfil-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 0;
  padding: 28px 24px;
  box-shadow: var(--shadow-xs);
}
.perfil-foto-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  text-align: center;
}
.perfil-avatar {
  position: relative;
  width: 96px;
  height: 96px;
  border-radius: 50%;
  overflow: visible;
  margin-bottom: 4px;
}
.perfil-avatar-img {
  width: 96px;
  height: 96px;
  border-radius: 50%;
  object-fit: cover;
  display: block;
  border: 3px solid var(--border);
}
.perfil-avatar-placeholder {
  width: 96px;
  height: 96px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--accent), var(--flag-red));
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 36px;
  font-weight: 700;
  color: #fff;
  border: 3px solid var(--border);
}
.perfil-avatar-change {
  position: absolute;
  bottom: 0;
  right: 0;
  width: 30px;
  height: 30px;
  background: var(--accent);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  cursor: pointer;
  border: 2px solid var(--surface);
  transition: background 0.15s, transform 0.15s;
  z-index: 2;
}
.perfil-avatar-change:hover { background: var(--accent-hover); transform: scale(1.08); }
.perfil-name-big {
  font-size: 18px;
  font-weight: 700;
  color: var(--text);
  margin-top: 4px;
}
.perfil-role-badge {
  font-size: 11px;
  font-weight: 600;
  padding: 3px 10px;
  border-radius: 0;
  background: rgba(67,97,238,0.12);
  color: var(--accent);
  border: 1px solid rgba(67,97,238,0.2);
}
.perfil-username {
  font-size: 12px;
  color: var(--text-soft);
  font-family: monospace;
}
.perfil-info-card { }
.perfil-section-title {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-soft);
  margin-bottom: 16px;
}

/* ===================================================
   Registro de Actividad
   =================================================== */
.act-list {
  max-width: 760px;
  display: flex;
  flex-direction: column;
  gap: 24px;
}
.act-day-group {}
.act-day-label {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-soft);
  padding: 0 0 10px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 12px;
}
.act-entry {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--border-light, var(--border));
}
.act-entry:last-child { border-bottom: none; }
.act-icon {
  font-size: 18px;
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  border-radius: 0;
  background: var(--surface-2, var(--surface));
  border: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 15px;
}
.act-body { flex: 1; min-width: 0; }
.act-text {
  font-size: 13.5px;
  font-weight: 500;
  color: var(--text);
  margin-bottom: 3px;
}
.act-meta {
  font-size: 11.5px;
  color: var(--text-soft);
  display: flex;
  gap: 10px;
}
.act-user { font-weight: 600; color: var(--accent); }
.act-empty {
  text-align: center;
  padding: 80px 20px;
  color: var(--text-soft);
}

/* ── FLOTA TASKS — Projects panel ──────────────────────────────── */
.flt-projects {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}
.flt-projects-header {
  padding: 12px 14px 8px;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--text-soft);
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.flt-proj-item {
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  transition: background 0.1s;
  display: flex;
  align-items: center;
  gap: 8px;
}
.flt-proj-item:last-child { border-bottom: none; }
.flt-proj-item:hover { background: var(--bg); }
.flt-proj-item.active {
  background: var(--blue-light);
  border-left: 3px solid var(--blue);
  padding-left: 11px;
}
.flt-proj-item-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.flt-proj-item-count {
  font-size: 11px;
  color: var(--text-soft);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 0;
  padding: 1px 7px;
  flex-shrink: 0;
}
.flt-proj-item.active .flt-proj-item-count {
  background: var(--blue-light);
  border-color: var(--blue);
  color: var(--blue);
}

/* ── VEHÍCULOS — Category dashboard ────────────────────────────── */
.veh-cat-dash {
  display: flex;
  gap: 10px;
  margin-bottom: 16px;
  flex-wrap: wrap;
}
.veh-cat-card {
  flex: 1;
  min-width: 100px;
  background: var(--surface);
  border: 2px solid var(--border);
  border-radius: var(--radius);
  padding: 12px 14px;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s, box-shadow 0.15s;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  text-align: center;
}
.veh-cat-card:hover {
  border-color: var(--blue);
  background: var(--blue-light);
}
.veh-cat-card.active {
  border-color: var(--blue);
  background: var(--blue-light);
  box-shadow: 0 0 0 3px rgba(239,35,60,0.12);
}
.veh-cat-card-icon { font-size: 22px; line-height: 1; }
.veh-cat-card-label {
  font-size: 11px;
  font-weight: 700;
  color: var(--text);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.veh-cat-card-count {
  font-size: 20px;
  font-weight: 800;
  color: var(--text);
  line-height: 1;
}

/* ── PRESUPUESTOS — Project filter dashboard ────────────────────── */
.pres-proy-dash {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 16px;
}
.pres-proy-card {
  background: var(--surface);
  border: 1.5px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 8px 14px;
  cursor: pointer;
  font-size: 13px;
  font-weight: 500;
  color: var(--text);
  transition: border-color 0.12s, background 0.12s;
  display: flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}
.pres-proy-card:hover {
  border-color: var(--blue);
  background: var(--blue-light);
}
.pres-proy-card.active {
  border-color: var(--blue);
  background: var(--blue-light);
  font-weight: 700;
  color: var(--blue);
}
.pres-proy-card-count {
  font-size: 11px;
  color: var(--text-soft);
  background: var(--bg);
  border-radius: 0;
  padding: 1px 6px;
}
.pres-proy-card.active .pres-proy-card-count {
  background: rgba(239,35,60,0.15);
  color: var(--blue);
}


/* =============================================================================
   CAPA DE ACABADO — sistema de diseño
   Va al final a propósito: refina los componentes existentes sin reescribir las
   reglas de arriba, para no desestabilizar el resto de la hoja.
   ========================================================================== */

/* ── Tipografía ───────────────────────────────────────────────────────────── */
body {
  font-size: 13.5px;
  letter-spacing: -0.006em;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

.page-header h1 {
  font-size: 22px;
  font-weight: 680;
  letter-spacing: -0.025em;
  line-height: 1.2;
}
.page-header { gap: 16px; flex-wrap: wrap; }

/* Cifras siempre en versalitas tabulares: en una app de datos, las columnas de
   números tienen que alinearse dígito a dígito. */
.tabla td, .tabla th,
.stat-value, .stat-num, .kpi-value,
.cal-day-num, .cal-week-label,
.veh-km, .cal-veh-mat {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}

/* ── Superficies y tarjetas ──────────────────────────────────────────────── */
.card, .chart-card, .form-card, .stat-card, .panel, .widget {
  border: 1px solid var(--border);
  box-shadow: var(--shadow-xs);
}

/* Los galones de color saturado en el borde superior de las tarjetas de
   métrica eran el detalle más estridente: se reducen a una línea fina. */
.stat-card::before,
.kpi-card::before {
  height: 2px !important;
  opacity: 0.75;
}

/* ── Tablas ──────────────────────────────────────────────────────────────── */
.tabla th {
  background: var(--surface-2);
  font-size: 10px;
  letter-spacing: 0.08em;
  color: var(--text-soft);
  border-bottom: 1px solid var(--border-med);
  white-space: nowrap;
  padding: 9px 14px;
}
.tabla td { padding: 10px 14px; }
.tabla tbody tr:hover { background: rgba(239,35,60,0.035); }

/* Importes y cantidades: a la derecha, en una sola línea. Antes "150,00 €"
   se partía en dos líneas y descuadraba la fila. */
.tabla td.num, .tabla th.num,
.tabla td.precio, .tabla td.importe,
.tabla td:has(> .eur) {
  text-align: right;
  white-space: nowrap;
}

/* Cabecera fija sólo en tablas largas (>= 25 filas): en las cortas un scroller
   propio molestaría más que ayudar. */
.table-wrap:has(tbody tr:nth-child(25)) {
  max-height: calc(100vh - 265px);
  overflow: auto;
  overscroll-behavior: contain;
}
.table-wrap:has(tbody tr:nth-child(25)) .tabla thead th {
  position: sticky;
  top: 0;
  z-index: 4;
  background: var(--surface-2);
  box-shadow: inset 0 -1px 0 var(--border-med);
}

/* ── Botones ─────────────────────────────────────────────────────────────── */
.btn {
  border-radius: var(--radius-xs);
  letter-spacing: -0.005em;
  transition: background var(--transition), box-shadow var(--transition),
              transform 0.06s ease, color var(--transition);
}
.btn:active { transform: translateY(0.5px); }
.btn-primary {
  box-shadow: 0 1px 2px rgba(239,35,60,0.28);
}
.btn-primary:hover { box-shadow: 0 2px 6px rgba(239,35,60,0.30); }
.btn-ghost {
  box-shadow: var(--shadow-xs);
  border-color: var(--border-med);
  color: var(--text-2);
}
.btn-ghost:hover {
  background: var(--surface-2);
  border-color: var(--border-strong);
  color: var(--text);
}
.btn-sm { border-radius: 0; }
.btn:disabled, .btn[disabled] {
  opacity: 0.45;
  cursor: not-allowed;
  box-shadow: none;
}

/* ── Foco visible: no existía en ningún control ──────────────────────────── */
:where(a, button, input, select, textarea, [tabindex], .nav-item, .seg-btn,
       .btn, .filter-input, .filter-select, .form-control):focus-visible {
  outline: none;
  box-shadow: var(--ring);
  border-radius: var(--radius-xs);
}

/* ── Campos de formulario ────────────────────────────────────────────────── */
.form-control, .filter-input, .filter-select {
  border-radius: var(--radius-xs);
  border-color: var(--border-med);
}
.form-control:hover, .filter-input:hover, .filter-select:hover {
  border-color: var(--border-strong);
}
.form-control:focus, .filter-input:focus, .filter-select:focus {
  border-color: var(--blue);
  box-shadow: var(--ring);
}
.form-control::placeholder, .filter-input::placeholder {
  color: var(--text-xsoft);
}
label, .form-label {
  letter-spacing: 0.04em;
}

/* ── Badges y control segmentado ─────────────────────────────────────────── */
.badge {
  border-radius: var(--radius-pill);
  padding: 2px 9px;
  font-size: 10.5px;
  font-weight: 650;
  letter-spacing: 0.015em;
  box-shadow: inset 0 0 0 1px rgba(20,22,43,0.05);
}
.seg-control {
  background: var(--surface-sunk);
  box-shadow: inset 0 0 0 1px var(--border);
  border-radius: 0;
}
.seg-btn.active, .seg-btn[aria-selected="true"] {
  box-shadow: var(--shadow-xs), 0 0 0 0.5px rgba(20,22,43,0.06);
}

/* ── Barra lateral ───────────────────────────────────────────────────────── */
.sidebar { box-shadow: inset -1px 0 0 rgba(255,255,255,0.06); }
.nav-item {
  border-radius: var(--radius-xs);
  letter-spacing: -0.005em;
  transition: background var(--transition), color var(--transition);
}
.nav-section-title, .nav-group-title {
  font-size: 9.5px;
  letter-spacing: 0.13em;
  font-weight: 700;
}

/* ── Modales ─────────────────────────────────────────────────────────────── */
.modal-overlay {
  background: rgba(20,22,43,0.42);
  backdrop-filter: saturate(120%) blur(3px);
  -webkit-backdrop-filter: saturate(120%) blur(3px);
}
.modal {
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  border: 1px solid rgba(255,255,255,0.6);
}

/* ── Barras de scroll: finas y discretas ─────────────────────────────────── */
.main, .table-wrap, .modal, .sidebar-nav, [class*="-scroll"] {
  scrollbar-width: thin;
  scrollbar-color: rgba(43,45,66,0.22) transparent;
}
.main::-webkit-scrollbar,
.table-wrap::-webkit-scrollbar,
.modal::-webkit-scrollbar { width: 10px; height: 10px; }
.main::-webkit-scrollbar-thumb,
.table-wrap::-webkit-scrollbar-thumb,
.modal::-webkit-scrollbar-thumb {
  background: rgba(43,45,66,0.20);
  border-radius: var(--radius-pill);
  border: 2.5px solid transparent;
  background-clip: content-box;
}
.main::-webkit-scrollbar-thumb:hover,
.table-wrap::-webkit-scrollbar-thumb:hover { background-clip: content-box; background-color: rgba(43,45,66,0.34); }
.main::-webkit-scrollbar-track { background: transparent; }

/* ── Selección de texto en tono de marca ─────────────────────────────────── */
::selection { background: rgba(239,35,60,0.18); }

/* ── Respeto por "reducir movimiento" ───────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* Celdas numéricas: a la derecha, sin partir, con cifras tabulares.
   Sustituye al `font-family: monospace` en línea (Courier del navegador). */
.tabla td.cell-num, .tabla th.cell-num {
  text-align: right;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
  font-family: var(--font);
  letter-spacing: 0;
}

/* La columna de vehículos se mantiene por encima de las barras al desplazar
   en horizontal. El fondo tiene que ser OPACO (ver reglas de fila alterna y
   hover): con un fondo translúcido la barra se transparentaba a través.
   SU z-index NO SE PONE AQUÍ: lo reparte la escalera del final de la hoja,
   que es el único sitio que decide quién tapa a quién. */

/* ── Rejillas de métricas: adaptables ────────────────────────────────────────
   Varias rejillas fijaban un número de columnas (repeat(5,1fr)) y por debajo de
   ~1200px las etiquetas se partían en tres líneas. Con auto-fit + minmax las
   tarjetas se reordenan solas en vez de comprimirse. */
.stats-grid,
.eco-stats-row,
.eco-stats-row.eco-stats-5,
.veh-dash-grid,
.it-dash-grid,
.inv-dash-row {
  grid-template-columns: repeat(auto-fit, minmax(168px, 1fr));
}

/* Las etiquetas de métrica no se parten a mitad de palabra */
.eco-stat-label, .stat-label, .inv-dash-label,
.it-dash-label, .veh-dash-label {
  overflow-wrap: break-word;
  hyphens: none;
}

/* La cabecera de página se apila si no cabe, en vez de solaparse con los
   botones de acción (pasaba por debajo de ~900px). */
.page-header {
  align-items: flex-start;
  row-gap: 10px;
}
.page-header > *:last-child { flex-shrink: 0; }

/* ── Modo sin login (AUTH_DISABLED en server.js) ──────────────────────────── */
body.sin-login #login-screen { display: none !important; }
body.sin-login .sidebar-user { padding-bottom: 14px; }
/* El botón de cerrar sesión se enseña SIEMPRE, también con el login
   desactivado: se pidió expresamente y tenerlo escondido hacía pensar que no
   existía. Con `AUTH_DISABLED` avisa de que la sesión aún no se está
   comprobando en el servidor, en vez de fingir que cierra algo. */

/* ═══════════════════════════════════════════════════════════════════════════
   INVENTARIO — selector de árbol, migas, chips y vista en cuadrícula
   ═══════════════════════════════════════════════════════════════════════════ */

/* El desplegable del árbol necesita más ancho: las rutas son largas */
.filter-select-arbol {
  min-width: 260px;
  max-width: 340px;
  font-variant-numeric: tabular-nums;
}
.filter-select-arbol option { font-family: var(--font); }

.inv-view-toggle { flex-shrink: 0; }
.inv-view-toggle .seg-btn { display: inline-flex; align-items: center; gap: 5px; }
.inv-view-toggle .seg-btn.active { background: var(--surface); color: var(--text); font-weight: 600; }

/* ── Migas de pan de la categoría activa ─────────────────────────────────── */
.inv-breadcrumb {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: 2px; margin: -4px 0 12px;
  font-size: 12.5px;
}
.crumb {
  background: none; border: none; padding: 3px 7px;
  border-radius: var(--radius-xs);
  font: inherit; color: var(--blue); cursor: pointer;
  transition: background var(--transition);
}
.crumb:hover { background: var(--bg-hover); }
.crumb-actual { color: var(--text); font-weight: 600; cursor: default; }
.crumb-actual:hover { background: none; }
.crumb-sep { color: var(--text-xsoft); }

/* ── Chip de categoría (tabla y tarjetas) ────────────────────────────────── */
.cat-chip {
  display: inline-block; max-width: 100%;
  background: var(--surface-sunk);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  padding: 2px 9px;
  font: inherit; font-size: 11.5px; font-weight: 500;
  color: var(--text-2);
  cursor: pointer; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
  transition: background var(--transition), border-color var(--transition), color var(--transition);
}
.cat-chip:hover {
  background: var(--bg-hover);
  border-color: var(--blue);
  color: var(--blue);
}

/* ── Vista en cuadrícula ─────────────────────────────────────────────────── */
.inv-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(232px, 1fr));
  gap: 12px;
  align-items: start;
}
.inv-card {
  position: relative;
  display: flex; flex-direction: column; gap: 7px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 13px 14px 11px;
  box-shadow: var(--shadow-xs);
  transition: box-shadow var(--transition), border-color var(--transition), transform var(--transition);
}
.inv-card:hover {
  box-shadow: var(--shadow-lift);
  border-color: var(--border-med);
  transform: translateY(-1px);
}
.inv-card.sel {
  border-color: var(--blue);
  box-shadow: 0 0 0 2px rgba(239,35,60,0.16);
}

/* Inventory card image */
.inv-card-img {
  width: 100%;
  height: 110px;
  border-radius: 0;
  background: var(--surface-sunk);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  margin-bottom: 8px;
  flex-shrink: 0;
}
.inv-card-img img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 0;
}
.inv-card-img .inv-card-img-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  color: var(--text-xsoft);
  font-size: 11px;
}
.inv-card-img .inv-card-img-placeholder svg { opacity: 0.35; }
.inv-card-check { position: absolute; top: 10px; right: 10px; }
.inv-card-check input { cursor: pointer; }
.inv-card-cod {
  font-size: 11px; font-weight: 600; letter-spacing: 0.05em;
  color: var(--text-xsoft);
  font-variant-numeric: tabular-nums;
}
.inv-card-nom {
  font-size: 13.5px; font-weight: 600; line-height: 1.32;
  letter-spacing: -0.01em; color: var(--text);
  /* Máximo 3 líneas: si no, las tarjetas de nombres larguísimos descuadran */
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  overflow: hidden;
  padding-right: 20px;   /* hueco de la casilla de selección */
}
.inv-card > .cat-chip { align-self: flex-start; }
.inv-card-datos {
  display: flex; align-items: baseline; gap: 12px;
  font-size: 12px; color: var(--text-soft);
  font-variant-numeric: tabular-nums;
}
.inv-card-datos strong { color: var(--text); font-weight: 650; font-size: 13px; }
.inv-card-pie {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px; margin-top: 2px;
  padding-top: 9px; border-top: 1px solid var(--border);
}
.inv-card-acciones { display: flex; gap: 4px; }
/* Las acciones solo aparecen al pasar por encima: la cuadrícula se lee mejor */
.inv-card-acciones { opacity: 0; transition: opacity var(--transition); }
.inv-card:hover .inv-card-acciones,
.inv-card:focus-within .inv-card-acciones { opacity: 1; }

.inv-grid-vacio {
  grid-column: 1 / -1;
  display: flex; flex-direction: column; align-items: center;
  padding: 56px 20px; color: var(--text-soft);
}
.inv-grid-mas {
  grid-column: 1 / -1;
  display: flex; justify-content: center; padding: 10px 0 4px;
}

/* Las tarjetas de departamento son botones: se resetea el estilo nativo */
.inv-dash-card {
  font: inherit; text-align: center;
  background: var(--surface);
  border: 2px solid transparent;
  cursor: pointer;
}

/* ═══════════════════════════════════════════════════════════════════════════
   VEHICLE CALENDAR — pasada "fluida"
   Las barras pesaban demasiado para la altura de la fila: ocupaban casi toda
   la celda, llevaban una marca blanca a la izquierda que cortaba el tramo y
   sombras marcadas arriba y abajo. Resultado: cajas apiladas en vez de una
   barra continua. Aquí se aligera todo y se da aire entre filas.
   ═══════════════════════════════════════════════════════════════════════════ */

:root { --cal-bar-radius: 6px; }

/* Barra más baja: deja un canal claro entre filas */
.cal-veh-table .cal-veh-td-day .cal-cell-inner {
  height: 30px;
  min-height: 30px;
  font-size: 10.5px;
}

/* Relieve mínimo: una sola línea inferior muy tenue, nada arriba */
.cal-veh-table .cal-cell-inner.filled {
  box-shadow: inset 0 -1px 0 rgba(0,0,0,0.10);
}
/* Degradado casi plano — el volumen fuerte era parte de la sensación de "caja" */
.cal-veh-table .cal-cell-inner.filled::after {
  background: linear-gradient(to bottom,
    rgba(255,255,255,0.10) 0%,
    rgba(255,255,255,0.02) 60%,
    rgba(0,0,0,0.05) 100%);
}

/* Fuera la marca blanca del inicio del tramo: era lo que más cortaba la
   continuidad visual. El inicio ya se distingue por el redondeo y la etiqueta. */
.cal-veh-table .cal-veh-td-day.cal-run-start .cal-cell-inner::before,
.cal-veh-table .cal-veh-td-day.cal-run-solo .cal-cell-inner::before {
  display: none;
}

/* Sin sombra exterior en las píldoras de un día: se igualan a los tramos */
.cal-veh-table .cal-veh-td-day.cal-run-solo .cal-cell-inner {
  box-shadow: inset 0 -1px 0 rgba(0,0,0,0.10);
}

/* Márgenes laterales menores: el tramo respira sin separarse de su columna */
.cal-veh-table .cal-veh-td-day.cal-run-solo  .cal-cell-inner { margin: 0 2px; }
.cal-veh-table .cal-veh-td-day.cal-run-start .cal-cell-inner { margin-left: 2px; padding-left: 7px; }
.cal-veh-table .cal-veh-td-day.cal-run-end   .cal-cell-inner { margin-right: 2px; }

/* Etiquetas: un poco más discretas, sin sombra dura de texto */
.cal-veh-table .cal-run-label {
  font-weight: 600;
  text-shadow: 0 1px 1px rgba(0,0,0,0.18);
}
.cal-veh-table .cal-proy-sub {
  opacity: 0.82;
  text-shadow: none;
}
.cal-veh-table .cal-cond-chip {
  background: rgba(0,0,0,0.16);
  border-color: rgba(255,255,255,0.13);
  font-weight: 650;
}

/* ── Rayado continuo entre días (ITV y mantenimiento) ─────────────────────
   Cada celda desplaza el patrón según su índice de día, así las diagonales
   siguen de una casilla a la siguiente y el tramo se lee como una sola pieza.
   --cal-col-w lo publica App._calMedirColumna() midiendo la columna real. */
.cal-veh-table {
  --cal-col-w: 62px;
}
.cal-veh-table .cal-veh-td-day.cal-event-itv .cal-cell-inner,
.cal-veh-table .cal-veh-td-day.cal-event-mantenimiento .cal-cell-inner {
  /* !important obligatorio: las reglas de más arriba usan el atajo
     `background: ... !important`, que resetea background-position. */
  background-repeat: repeat !important;
  background-position-x: calc(var(--cal-dia, 0) * -1 * var(--cal-col-w)) !important;
  background-position-y: 0 !important;
}

/* Rayas más finas y con menos contraste: menos ruido a lo largo del tramo */
.cal-veh-table .cal-veh-td-day.cal-event-itv .cal-cell-inner,
.cal-veh-table .cal-veh-td-day.cal-event-itv.cal-run-solo .cal-cell-inner,
.cal-veh-table .cal-veh-td-day.cal-event-itv.cal-run-start .cal-cell-inner,
.cal-veh-table .cal-veh-td-day.cal-event-itv.cal-run-mid .cal-cell-inner,
.cal-veh-table .cal-veh-td-day.cal-event-itv.cal-run-end .cal-cell-inner {
  background-image: repeating-linear-gradient(-45deg,
    #eda31c, #eda31c 6px, #dd9411 6px, #dd9411 12px) !important;
}
.cal-veh-table .cal-veh-td-day.cal-event-mantenimiento .cal-cell-inner,
.cal-veh-table .cal-veh-td-day.cal-event-mantenimiento.cal-run-solo .cal-cell-inner,
.cal-veh-table .cal-veh-td-day.cal-event-mantenimiento.cal-run-start .cal-cell-inner,
.cal-veh-table .cal-veh-td-day.cal-event-mantenimiento.cal-run-mid .cal-cell-inner,
.cal-veh-table .cal-veh-td-day.cal-event-mantenimiento.cal-run-end .cal-cell-inner {
  background-image: repeating-linear-gradient(-45deg,
    #e05555, #e05555 6px, #d04545 6px, #d04545 12px) !important;
}

/* ── Rejilla más ligera ──────────────────────────────────────────────────── */
.cal-veh-table .cal-veh-td-day { border-right-color: var(--border); }
.cal-veh-table tbody tr { border-bottom-color: var(--border); }
/* El hover de celda ya no pinta la franja azul superior: sobraba ruido */
.cal-veh-table .cal-veh-td-day:hover::after { display: none; }
.cal-veh-table .cal-veh-td-day:hover { background: rgba(239,35,60,0.05); }

/* ── Fila activa durante el arrastre ─────────────────────────────────────── */
/* Un arrastre afecta a un solo vehículo: se resalta su fila para que se vea. */
.cal-fila-arrastrando .cal-veh-td-veh { background: rgba(239,35,60,0.09) !important; }
.cal-fila-arrastrando .cal-veh-td-day:not(.cal-assigned) { background: rgba(239,35,60,0.035); }
.cal-fila-arrastrando .cal-veh-name { color: var(--blue); }

/* ═══════════════════════════════════════════════════════════════════════════
   PRESUPUESTOS — dashboard de estados, proyectos y clientes
   ═══════════════════════════════════════════════════════════════════════════ */
.pres-kpi-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
  gap: 10px;
  margin-bottom: 14px;
}
.pres-kpi {
  display: flex; flex-direction: column; gap: 2px;
  text-align: left; font: inherit; cursor: pointer;
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--text-xsoft);
  border-radius: var(--radius-sm);
  padding: 10px 13px 11px;
  box-shadow: var(--shadow-xs);
  transition: box-shadow var(--transition), border-color var(--transition), transform var(--transition);
}
.pres-kpi:hover { box-shadow: var(--shadow-lift); transform: translateY(-1px); }
.pres-kpi.active {
  border-color: var(--blue);
  box-shadow: 0 0 0 2px rgba(239,35,60,0.15);
}
.pres-kpi.gray   { border-left-color: var(--text-soft); }
.pres-kpi.blue   { border-left-color: var(--blue); }
.pres-kpi.green  { border-left-color: var(--green); }
.pres-kpi.red    { border-left-color: var(--red); }
.pres-kpi-label {
  font-size: 10px; font-weight: 700; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--text-soft);
}
.pres-kpi-val {
  font-size: 22px; font-weight: 680; letter-spacing: -0.03em;
  line-height: 1.1; color: var(--text);
  font-variant-numeric: tabular-nums;
}
.pres-kpi-eur {
  font-size: 12px; font-weight: 550; color: var(--text-2);
  font-variant-numeric: tabular-nums;
}

/* ── Chips de proyecto y cliente ─────────────────────────────────────────── */
.pres-chip-row {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: 6px; margin-bottom: 8px;
}
.pres-chip-titulo {
  font-size: 10px; font-weight: 700; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--text-xsoft);
  margin-right: 4px; min-width: 62px;
}
.pres-chip {
  display: inline-flex; align-items: center; gap: 6px;
  font: inherit; font-size: 12.5px; font-weight: 500;
  background: var(--surface);
  border: 1px solid var(--border-med);
  border-radius: var(--radius-pill);
  padding: 4px 11px;
  color: var(--text-2); cursor: pointer;
  box-shadow: var(--shadow-xs);
  transition: background var(--transition), border-color var(--transition), color var(--transition);
}
.pres-chip:hover { background: var(--surface-2); border-color: var(--border-strong); }
.pres-chip.active {
  background: var(--blue); border-color: var(--blue); color: #fff;
  box-shadow: 0 1px 3px rgba(239,35,60,0.3);
}
.pres-chip-n {
  font-size: 11px; font-weight: 700;
  background: var(--surface-sunk); color: var(--text-soft);
  border-radius: var(--radius-pill); padding: 0 6px;
  font-variant-numeric: tabular-nums;
}
.pres-chip.active .pres-chip-n { background: rgba(255,255,255,0.24); color: #fff; }

/* El contenedor del dashboard de presupuestos era flex en fila (para las
   viejas tarjetas de proyecto) y aplastaba la rejilla de KPIs. Ahora apila
   bloques en vertical: KPIs, chips de proyecto y chips de cliente. */
.pres-proy-dash {
  display: block;
  margin-bottom: 16px;
}
.pres-proy-dash .pres-kpi-row { width: 100%; }

/* ═══════════════════════════════════════════════════════════════════════════
   PROYECTOS — widgets de últimos proyectos
   Deliberadamente más pequeños que las tarjetas de métrica de arriba: son un
   atajo para saltar a un proyecto reciente, no una métrica.
   ═══════════════════════════════════════════════════════════════════════════ */
.proy-recientes { margin: 14px 0 18px; }
.proy-recientes-titulo {
  font-size: 10px; font-weight: 700; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--text-xsoft);
  margin-bottom: 8px;
}
.proy-recientes-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(196px, 1fr));
  gap: 8px;
}
.proy-mini {
  display: flex; align-items: stretch; gap: 0;
  font: inherit; text-align: left; cursor: pointer;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0; overflow: hidden;
  box-shadow: var(--shadow-xs);
  transition: box-shadow var(--transition), border-color var(--transition), transform var(--transition);
}
.proy-mini:hover {
  box-shadow: var(--shadow-lift);
  border-color: var(--border-med);
  transform: translateY(-1px);
}
/* Banda del color del proyecto: identifica el proyecto de un vistazo y usa el
   mismo color que el calendario de vehículos */
.proy-mini-color { width: 4px; flex-shrink: 0; }
.proy-mini-cuerpo {
  display: flex; flex-direction: column; gap: 3px;
  padding: 8px 11px 9px; min-width: 0; flex: 1;
}
.proy-mini-nombre {
  font-size: 12.5px; font-weight: 640; letter-spacing: -0.01em;
  color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.proy-mini-meta {
  font-size: 10.5px; color: var(--text-soft);
  font-variant-numeric: tabular-nums;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.proy-mini-pies { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; margin-top: 1px; }
.proy-mini-badge {
  font-size: 9.5px; font-weight: 700; letter-spacing: 0.04em;
  text-transform: uppercase;
  border-radius: var(--radius-pill); padding: 1px 7px;
  background: var(--surface-sunk); color: var(--text-soft);
}
.proy-mini-badge.est-activo     { background: rgba(52,199,89,0.13);  color: var(--green-dark); }
.proy-mini-badge.est-finalizado { background: rgba(43,45,66,0.08);   color: var(--text-soft); }
.proy-mini-badge.est-pendiente  { background: rgba(255,149,0,0.14);  color: var(--orange-dark); }
.proy-mini-dato {
  font-size: 10px; color: var(--text-xsoft);
  font-variant-numeric: tabular-nums;
}
/* Los iconos de las tarjetas de métrica ahora son SVG, no emoji */
.proy-dash-icon { display: inline-flex; align-items: center; color: var(--text-soft); }

/* ═══════════════════════════════════════════════════════════════════════════
   DASHBOARD — Gantt más legible
   Se mantiene el diagrama; lo que cambia es la lectura: rejilla de días
   visible, fines de semana sombreados, "hoy" marcado de verdad, barras en
   píldora con el color real del proyecto y filas alternas.
   ═══════════════════════════════════════════════════════════════════════════ */

.gantt-day-hdr { width: 34px; min-width: 34px; }
.gantt-label-col, .gantt-event-label { width: 164px; min-width: 164px; }
.gantt-group-label { padding-left: 164px; }

/* Cabecera: número del día más nítido y fin de semana atenuado sin desaparecer */
.gantt-day-hdr .gd-num { font-size: 12.5px; color: var(--text-2); font-variant-numeric: tabular-nums; }
.gantt-day-hdr.g-weekend { opacity: 1; }
.gantt-day-hdr.g-weekend .gd-num,
.gantt-day-hdr.g-weekend .gd-wd { color: var(--text-xsoft); }

/* Hoy: pastilla azul en la cabecera en vez de un puntito */
.gantt-day-hdr.g-today .gd-num {
  color: #fff;
  background: var(--blue);
  border-radius: var(--radius-pill);
  width: 21px; height: 21px; line-height: 21px;
  margin: 1px auto 0;
  font-weight: 700;
}
.gantt-day-hdr.g-today .gd-num::after { display: none; }
.gantt-day-hdr.g-today .gd-wd { color: var(--blue); font-weight: 700; }

/* Línea de hoy: visible pero sin tapar las barras */
.gantt-today-line {
  width: 0;
  border-left: 1.5px dashed rgba(239,35,60,0.55);
  background: none;
}

/* Filas alternas y separadores más suaves */
.gantt-event-row { min-height: 34px; border-bottom: none; }
.gantt-event-row:nth-child(even) { background: rgba(43,45,66,0.018); }
.gantt-event-row:hover { background: rgba(239,35,60,0.04); }

/* Etiqueta de fila: punto del color del proyecto + nombre */
.gantt-event-label {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 0 7px;
  font-size: 12.5px; font-weight: 550;
  padding-right: 12px;
}
.gantt-punto {
  width: 8px; height: 8px; border-radius: 50%;
  flex-shrink: 0;
}
.gantt-lbl-txt { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gantt-event-label small { flex-basis: 100%; padding-left: 15px; }

/* Barras en píldora, con volumen suave */
.gantt-bar {
  top: 6px; bottom: 6px;
  /* Radio suave, no píldora: en barras de 22px de alto el redondeo completo
     se comía los extremos y costaba ver dónde empieza y acaba cada tramo. */
  border-radius: 0;
  font-size: 10.5px; font-weight: 650;
  padding: 0 9px;
  box-shadow: inset 0 -1px 0 rgba(0,0,0,0.12);
  transition: filter var(--transition), box-shadow var(--transition);
}
.gantt-bar::after {
  content: '';
  position: absolute; inset: 0;
  border-radius: inherit;
  background: linear-gradient(to bottom, rgba(255,255,255,0.16), rgba(255,255,255,0) 60%);
  pointer-events: none;
}
.gantt-bar:hover { opacity: 1; filter: brightness(1.07); box-shadow: var(--shadow-sm); }

/* Los avisos de ITV y seguro siguen destacando en rojo/ámbar */
.gantt-bar.b-itv    { background: var(--red) !important; min-width: 66px !important; }
.gantt-bar.b-seguro { background: var(--orange) !important; min-width: 66px !important; }

/* Cabecera del Gantt pegada arriba, con separación más discreta */
.gantt-header-row { border-bottom: 1px solid var(--border-med); }

/* La columna de nombres del Gantt se queda fija al desplazar en horizontal:
   antes, al llegar a los días con barras, ya no se veía de qué fila eran.
   El fondo tiene que ser OPACO o las barras se transparentan por debajo. */
.gantt-event-label,
.gantt-label-col {
  position: sticky;
  left: 0;
  z-index: 3;
  background: var(--surface);
  box-shadow: 1px 0 0 var(--border);
}
/* En las filas alternas el fondo fijo debe coincidir con el de la fila */
.gantt-event-row:nth-child(even) .gantt-event-label { background: #fafbfc; }
.gantt-event-row:hover .gantt-event-label { background: #f2f7fe; }
.gantt-group-label {
  position: sticky;
  left: 0;
  background: var(--surface);
  z-index: 3;
}

/* Los iconos SVG que sustituyen a los emoji se alinean con el texto */
.ico, .ico-wrap svg { vertical-align: -0.14em; flex-shrink: 0; }
.ico-wrap { display: inline-flex; align-items: center; color: var(--text-soft); }
.btn svg, .seg-btn svg, .crumb svg { vertical-align: -0.14em; }
.modal-close svg { display: block; }
/* Los iconos heredan el color del contexto, no van en color propio */
.eco-stat-icon svg, .eco-panel-title svg, .proy-dash-icon svg { vertical-align: -0.14em; }
.eco-panel-title { display: flex; align-items: center; gap: 6px; }

/* ── PRESUPUESTO TEMPLATE PICKER ──────────────────────────────── */
.pres-tpl-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}
.pres-tpl-card {
  background: var(--bg-card);
  border: 1.5px solid var(--border);
  border-radius: 0;
  padding: 16px 14px;
  cursor: pointer;
  text-align: left;
  transition: border-color 0.15s, background 0.15s, box-shadow 0.15s;
  width: 100%;
}
.pres-tpl-card:hover {
  border-color: var(--blue);
  background: rgba(239,35,60,0.04);
  box-shadow: 0 0 0 3px rgba(239,35,60,0.10);
}
.pres-tpl-icon {
  font-size: 22px;
  margin-bottom: 8px;
  display: block;
}
.pres-tpl-name {
  font-size: 13px;
  font-weight: 700;
  color: var(--text);
  margin-bottom: 4px;
}
.pres-tpl-desc {
  font-size: 11.5px;
  color: var(--text-soft);
  line-height: 1.45;
  margin-bottom: 8px;
}
.pres-tpl-sections {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: 6px;
}
.pres-tpl-sections span {
  font-size: 10px;
  background: var(--bg-hover);
  border: 1px solid var(--border);
  border-radius: 0;
  padding: 2px 6px;
  color: var(--text-2);
  white-space: nowrap;
}

/* ── PRESUPUESTO SECTION ROWS ──────────────────────────────────── */
.pres-section-row td {
  padding: 0 !important;
}
.pres-section-cell {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--bg-hover);
  border-top: 1px solid var(--border-med);
  border-bottom: 1px solid var(--border-med);
  padding: 7px 10px;
  margin-top: 2px;
}
.pres-section-icon {
  color: var(--text-soft);
  flex-shrink: 0;
}
.pres-section-input {
  flex: 1;
  border: none !important;
  background: transparent !important;
  font-size: 11.5px;
  font-weight: 700;
  color: var(--text-2);
  text-transform: uppercase;
  letter-spacing: 0.07em;
  outline: none !important;
  padding: 0 !important;
  box-shadow: none !important;
}
.pres-section-input:focus { color: var(--blue); }
.pres-section-actions {
  display: flex;
  gap: 3px;
  align-items: center;
}
.pres-section-move {
  background: none;
  border: 1px solid var(--border);
  cursor: pointer;
  color: var(--text-soft);
  font-size: 11px;
  padding: 2px 5px;
  border-radius: 0;
  line-height: 1;
  transition: background 0.12s, color 0.12s;
}
.pres-section-move:hover { background: var(--border); color: var(--text); }

/* ── Fin de semana sin tinte propio (calendario de vehículos) ──────────────
   Pedido: sábados y domingos con el mismo fondo que el resto de días. Solo se
   quita el color; la cabecera sigue mostrando "SA"/"DO" para ubicarse. */
.cal-veh-table .cal-veh-td-day.cal-weekend { background: transparent; }
/* La cabecera es oscura: aquí "igual que los demás" es #2b2d42, NO transparente
   (transparente dejaba sábado y domingo en blanco sobre blanco, invisibles). */
.cal-veh-table .cal-veh-th-day.cal-weekend { background: var(--text); }
/* Las filas alternas mantienen su banda también en sábado y domingo */
.cal-veh-table .cal-veh-row.cal-row-alt .cal-veh-td-day.cal-weekend:not(.cal-assigned) {
  background: rgba(141,153,174,0.06);
}
/* La columna de hoy y el arrastre siguen mandando sobre el fin de semana */
.cal-veh-table .cal-veh-td-day.cal-weekend.cal-today-col { background: rgba(var(--acento-rgb), 0.055); }
.cal-veh-table .cal-veh-td-day.cal-weekend:hover { background: rgba(var(--acento-rgb), 0.05); }

/* El texto de la barra del Gantt se queda pegado al borde visible: si la barra
   empieza antes del mes mostrado, su etiqueta quedaba cortada a mitad de
   palabra justo en el borde de la columna de nombres. */
.gantt-bar-txt {
  position: sticky;
  /* 164px es el ancho de la columna de nombres (también sticky): así el texto
     se detiene justo a su derecha en vez de quedar cortado por debajo. */
  left: 170px;
  white-space: nowrap;
}

/* Logotipo de marca en el inventario IT. Va en el gris del texto secundario y
   no en negro puro, para que no pese más que el nombre del dispositivo. */
.logo-apple {
  color: var(--text-2);
  vertical-align: -0.16em;
  margin-right: 1px;
}

/* ═══════════════════════════════════════════════════════════════════════════
   VEHICLE CALENDAR — legibilidad de conductor y proyecto dentro de la barra
   Dos problemas: (1) al adelgazar la barra a 30px las dos líneas (conductor +
   proyecto) ya no cabían y el nombre del proyecto salía cortado por abajo;
   (2) el texto era blanco fijo, y sobre los colores claros de la paleta
   (#e9c46a, #06d6a0, #4cc9f0, #fb8500) no había contraste suficiente.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Altura suficiente para dos líneas, dejando aún canal entre filas */
.cal-veh-table .cal-veh-td-day .cal-cell-inner {
  height: 36px;
  min-height: 36px;
  padding-top: 1px;
  padding-bottom: 1px;
  gap: 1px;
}

/* Conductor: primera línea, la que más se busca de un vistazo */
.cal-veh-table .cal-cond-chip {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.005em;
  line-height: 1.32;
  padding: 0 6px;
  max-width: 100%;
  background: rgba(0,0,0,0.20);
  border-color: rgba(255,255,255,0.18);
  text-shadow: none;
}
.cal-veh-table .cal-cond-chip:hover { background: rgba(0,0,0,0.38); }

/* Proyecto: segunda línea. Sube de 9 a 10px y de 0.82 a opacidad plena;
   la jerarquía la marca el tamaño, no el desvanecido. */
.cal-veh-table .cal-proy-sub {
  font-size: 10px;
  font-weight: 600;
  line-height: 1.24;
  opacity: 0.95;
  letter-spacing: 0.004em;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Etiqueta de tramo sin conductor: una sola línea, puede ser más grande */
.cal-veh-table .cal-run-label:not(.cal-proy-sub) {
  font-size: 11px;
  font-weight: 650;
  letter-spacing: 0.004em;
}

/* ── Texto oscuro cuando el color del proyecto es claro ──────────────────── */
.cal-veh-table .cal-cell-inner.txt-oscuro,
.cal-veh-table .cal-cell-inner.txt-oscuro .cal-run-label,
.cal-veh-table .cal-cell-inner.txt-oscuro .cal-proy-sub {
  color: #16182c;
  text-shadow: none;
}
.cal-veh-table .cal-cell-inner.txt-oscuro .cal-cond-chip {
  color: #16182c;
  background: rgba(255,255,255,0.46);
  border-color: rgba(0,0,0,0.10);
}
.cal-veh-table .cal-cell-inner.txt-oscuro .cal-cond-chip:hover {
  background: rgba(255,255,255,0.78);
}
.cal-veh-table .cal-cell-inner.txt-oscuro .cal-cond-add {
  color: rgba(0,0,0,0.55);
}
.cal-veh-table .cal-cell-inner.txt-oscuro .cal-cond-add:hover {
  background: rgba(255,255,255,0.5);
  color: #16182c;
}
/* Con texto oscuro el degradado de volumen tiene que aclarar, no oscurecer */
.cal-veh-table .cal-cell-inner.txt-oscuro.filled::after {
  background: linear-gradient(to bottom,
    rgba(255,255,255,0.14) 0%,
    rgba(255,255,255,0.03) 60%,
    rgba(0,0,0,0.06) 100%);
}

/* ── La etiqueta puede salirse de su celda ────────────────────────────────
   El render centra la etiqueta en la celda del medio del tramo, pero esa
   celda mide ~67px: con `overflow:hidden` el nombre del proyecto se cortaba
   en mitad de una barra de 300px. Solo en la celda que lleva etiqueta se
   permite desbordar y se centra el texto sobre el tramo.
   El fondo redondeado sigue recortado porque `border-radius` recorta el
   pintado del propio fondo aunque overflow sea visible. */
.cal-veh-table .cal-cell-inner.con-label {
  overflow: visible;
  align-items: center;
  justify-content: center;
  z-index: 2;              /* por encima del fondo de las celdas vecinas */
}
.cal-veh-table .cal-cell-inner.con-label::after {
  border-radius: inherit;
}
.cal-veh-table .cal-cell-inner.con-label > * {
  max-width: none;
  white-space: nowrap;
  overflow: visible;
  text-overflow: clip;
}
/* En un tramo de un solo día no hay sitio para desbordar: se recorta */
.cal-veh-table .cal-run-solo .cal-cell-inner.con-label > * {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ═══════════════════════════════════════════════════════════════════════════
   BARRA LATERAL — negra, activo en rojo, interactiva
   Antes: fondo #2b2d42 (azul marino) y activo en rojo al 18% de opacidad, que
   apenas se distinguía del hover. Ahora: casi negro con degradado, activo en
   rojo sólido y realimentación en todo lo que se puede pulsar.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  --sidebar-bg:     #0a0a0c;
  --sidebar-bg-alt: #121216;
  --sidebar-rojo:   #ef233c;
  --sidebar-rojo-2: #d90429;
}

.sidebar {
  background:
    radial-gradient(120% 55% at 50% 100%, rgba(239,35,60,0.10) 0%, transparent 62%),
    linear-gradient(180deg, var(--sidebar-bg-alt) 0%, var(--sidebar-bg) 46%, #060607 100%);
  box-shadow: inset -1px 0 0 rgba(255,255,255,0.055), 4px 0 22px rgba(0,0,0,0.30);
}

/* ── Elementos de navegación ─────────────────────────────────────────────── */
.sidebar .nav-item {
  color: rgba(255,255,255,0.62);
  font-weight: 500;
  padding: 8px 11px;
  transition: background 0.16s ease, color 0.16s ease,
              transform 0.16s cubic-bezier(0.34,1.4,0.64,1), box-shadow 0.16s ease;
}
/* Barra roja que crece desde el borde: se insinúa en hover y se afirma al activar */
.sidebar .nav-item::before {
  content: '';
  position: absolute;
  left: 0; top: 50%;
  transform: translateY(-50%);
  width: 3px; height: 0;
  background: var(--sidebar-rojo);
  border-radius: 0 3px 3px 0;
  transition: height 0.2s cubic-bezier(0.34,1.4,0.64,1);
}
.sidebar .nav-item:hover {
  background: rgba(255,255,255,0.07);
  color: #fff;
  transform: translateX(2px);
}
.sidebar .nav-item:hover::before { height: 14px; }
.sidebar .nav-item:hover .nav-icon { transform: scale(1.12); }

/* Activo: rojo sólido, no un tinte translúcido */
.sidebar .nav-item.active {
  background: linear-gradient(90deg, var(--sidebar-rojo) 0%, var(--sidebar-rojo-2) 100%);
  color: #fff;
  font-weight: 650;
  transform: none;
  box-shadow: 0 2px 10px rgba(239,35,60,0.38), inset 0 1px 0 rgba(255,255,255,0.16);
}
.sidebar .nav-item.active::before { height: 100%; background: #fff; opacity: 0.85; }
.sidebar .nav-item.active .nav-icon { opacity: 1; transform: none; }
.sidebar .nav-item.active:hover {
  background: linear-gradient(90deg, #f5384f 0%, #e40b2e 100%);
  transform: none;
}

.sidebar .nav-icon {
  opacity: 0.6;
  transition: opacity 0.16s ease, transform 0.16s cubic-bezier(0.34,1.4,0.64,1);
}

/* Rótulos de sección: legibles pero sin competir */
.sidebar .nav-section-label {
  color: rgba(255,255,255,0.34);
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  padding: 15px 11px 5px;
}

/* Contador/badge del elemento de navegación */
.sidebar .nav-badge {
  background: var(--sidebar-rojo);
  color: #fff;
  font-weight: 700;
  box-shadow: 0 0 0 2px rgba(239,35,60,0.22);
  transition: transform 0.16s cubic-bezier(0.34,1.4,0.64,1);
}
.sidebar .nav-item:hover .nav-badge { transform: scale(1.1); }
.sidebar .nav-item.active .nav-badge {
  background: #fff;
  color: var(--sidebar-rojo-2);
  box-shadow: none;
}

/* ── Cabecera y pie ──────────────────────────────────────────────────────── */
.sidebar .sidebar-logo,
.sidebar .sidebar-brand { transition: transform 0.2s cubic-bezier(0.34,1.4,0.64,1); }
.sidebar .sidebar-logo:hover,
.sidebar .sidebar-brand:hover { transform: scale(1.04); }

.sidebar .sidebar-user {
  border-top: 1px solid rgba(255,255,255,0.08);
  transition: background 0.16s ease;
}
.sidebar .sidebar-user:hover { background: rgba(255,255,255,0.06); }
.sidebar .sidebar-user:hover .sidebar-user-name { color: #fff; }
.sidebar .sidebar-avatar {
  transition: transform 0.18s cubic-bezier(0.34,1.4,0.64,1), box-shadow 0.18s ease;
}
.sidebar .sidebar-user:hover .sidebar-avatar {
  transform: scale(1.07);
  box-shadow: 0 0 0 2px rgba(239,35,60,0.5);
}

/* Botón de plegar */
.sidebar .sidebar-collapse-btn,
.sidebar [class*="collapse"] {
  transition: background 0.16s ease, transform 0.16s ease, color 0.16s ease;
}
.sidebar .sidebar-collapse-btn:hover,
.sidebar [class*="collapse"]:hover {
  background: rgba(255,255,255,0.10);
  color: #fff;
}

/* ── Palmera: más grande y reactiva ──────────────────────────────────────── */
.sidebar-palm-watermark {
  opacity: 0.07;
  transition: opacity 0.5s ease, transform 0.7s cubic-bezier(0.34,1.1,0.64,1);
  transform: scale(1.28) translateY(6%);
  transform-origin: 50% 100%;
  filter: drop-shadow(0 0 22px rgba(239,35,60,0.28));
}
.sidebar-palm-watermark img { width: 100%; height: auto; }
/* Al entrar en la barra, la palmera se abre y se enciende un poco */
.sidebar:hover .sidebar-palm-watermark {
  opacity: 0.16;
  transform: scale(1.36) translateY(3%) rotate(-1.2deg);
}
/* Plegada no cabe: se reduce para que no invada los iconos */
.sidebar.collapsed .sidebar-palm-watermark { transform: scale(1.05) translateY(10%); opacity: 0.05; }

/* Barra de scroll de la navegación, discreta sobre fondo negro */
.sidebar-nav::-webkit-scrollbar { width: 8px; }
.sidebar-nav::-webkit-scrollbar-thumb {
  background: rgba(255,255,255,0.14);
  border-radius: var(--radius-pill);
  border: 2px solid transparent;
  background-clip: content-box;
}
.sidebar-nav::-webkit-scrollbar-thumb:hover { background-color: rgba(255,255,255,0.26); background-clip: content-box; }
.sidebar-nav::-webkit-scrollbar-track { background: transparent; }

/* La cabecera del calendario de vehículos usaba el color viejo de la barra */
.cal-veh-th-veh, .cal-veh-th-week-cell { background: #14141a; }
.cal-veh-table .cal-veh-th-day,
.cal-veh-table .cal-veh-th-day.cal-weekend { background: #1b1b22; }
.cal-veh-table .cal-veh-th-day.cal-today-col { background: #2a1420; }

/* ═══════════════════════════════════════════════════════════════════════════
   VEHICLE CALENDAR — más contraste entre evento y rejilla
   Las barras iban "a ras" de la rejilla y a media distancia se perdían.
   Se les da un borde propio y una sombra suave, y se aclara la rejilla vacía
   para que el color del proyecto destaque.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Rejilla vacía más clara: el contraste se gana también restando peso al fondo */
.cal-veh-table .cal-veh-td-day { border-right-color: rgba(43,45,66,0.07); }
.cal-veh-table tbody tr { border-bottom-color: rgba(43,45,66,0.07); }

/* La barra se separa del fondo con un borde del propio color, más oscuro */
.cal-veh-table .cal-cell-inner.filled {
  box-shadow:
    inset 0  1px 0 rgba(255,255,255,0.22),
    inset 0 -1px 0 rgba(0,0,0,0.28),
    0 1px 2px rgba(20,22,43,0.20);
}
/* Los extremos del tramo llevan además sombra lateral; los centros no, para
   que no aparezcan costuras verticales en las uniones. */
.cal-veh-table .cal-run-solo .cal-cell-inner.filled {
  box-shadow:
    inset 0  1px 0 rgba(255,255,255,0.22),
    inset 0 -1px 0 rgba(0,0,0,0.28),
    0 1px 3px rgba(20,22,43,0.26);
}
/* Saturación un pelín más alta: el color del proyecto se lee antes */
.cal-veh-table .cal-cell-inner.filled { filter: saturate(1.06); }
.cal-veh-table .cal-veh-td-day.cal-assigned .cal-cell-inner:hover {
  filter: saturate(1.12) brightness(1.06);
  box-shadow:
    inset 0  1px 0 rgba(255,255,255,0.3),
    inset 0 -1px 0 rgba(0,0,0,0.3),
    0 2px 8px rgba(20,22,43,0.30);
}

/* Texto con algo más de cuerpo sobre el color */
.cal-veh-table .cal-proy-sub { opacity: 1; font-weight: 650; }
.cal-veh-table .cal-cell-inner:not(.txt-oscuro) .cal-run-label,
.cal-veh-table .cal-cell-inner:not(.txt-oscuro) .cal-proy-sub {
  text-shadow: 0 1px 2px rgba(0,0,0,0.30);
}
.cal-veh-table .cal-cell-inner:not(.txt-oscuro) .cal-cond-chip {
  background: rgba(0,0,0,0.26);
  border-color: rgba(255,255,255,0.22);
}

/* ═══════════════════════════════════════════════════════════════════════════
   FICHAS QR
   ═══════════════════════════════════════════════════════════════════════════ */
.fichas-paso {
  display: flex; gap: 14px; align-items: flex-start;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px 18px;
  margin-bottom: 12px;
  box-shadow: var(--shadow-xs);
}
.fichas-paso-num {
  flex-shrink: 0;
  width: 26px; height: 26px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--text); color: var(--surface);
  font-size: 12.5px; font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.fichas-paso-cuerpo { flex: 1; min-width: 0; }
.fichas-paso-titulo {
  display: flex; align-items: center; gap: 10px;
  font-size: 13.5px; font-weight: 650; letter-spacing: -0.01em;
  margin-bottom: 12px;
}
.fichas-contador {
  font-size: 11px; font-weight: 600;
  background: var(--surface-sunk); color: var(--text-soft);
  border-radius: var(--radius-pill); padding: 2px 9px;
  transition: background var(--transition), color var(--transition);
}
.fichas-contador.activo { background: var(--blue); color: #fff; }

/* ── Selector de plantilla ───────────────────────────────────────────────── */
.fichas-plantillas {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(196px, 1fr));
  gap: 9px;
}
.ficha-plantilla {
  display: flex; flex-direction: column; gap: 3px;
  text-align: left; font: inherit; cursor: pointer;
  background: var(--surface);
  border: 1.5px solid var(--border-med);
  border-radius: var(--radius-sm);
  padding: 11px 13px;
  transition: border-color var(--transition), box-shadow var(--transition),
              transform var(--transition), background var(--transition);
}
.ficha-plantilla:hover {
  border-color: var(--border-strong);
  background: var(--surface-2);
  transform: translateY(-1px);
  box-shadow: var(--shadow-lift);
}
.ficha-plantilla.active {
  border-color: var(--blue);
  background: var(--bg-hover);
  box-shadow: 0 0 0 2px rgba(var(--acento-rgb), 0.14);
}
.ficha-plantilla-nom  { font-size: 12.5px; font-weight: 650; color: var(--text); }
.ficha-plantilla-desc { font-size: 11px; color: var(--text-soft); line-height: 1.34; }
.ficha-plantilla-n    { font-size: 10px; font-weight: 600; color: var(--text-xsoft); margin-top: 2px; }

/* ── Lista de registros ──────────────────────────────────────────────────── */
.fichas-lista {
  max-height: 300px; overflow: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  overscroll-behavior: contain;
}
.ficha-item {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 12px; cursor: pointer;
  border-bottom: 1px solid var(--border);
  font-size: 12.5px;
  transition: background var(--transition);
}
.ficha-item:last-child { border-bottom: none; }
.ficha-item:hover { background: var(--bg-hover); }
.ficha-item.sel { background: rgba(var(--acento-rgb), 0.075); }
.ficha-item input { cursor: pointer; flex-shrink: 0; }
.ficha-item-cod {
  font-size: 11px; font-weight: 650; color: var(--text-soft);
  font-variant-numeric: tabular-nums;
  min-width: 74px; flex-shrink: 0;
}
.ficha-item-nom { font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fichas-vacio {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 26px 16px; text-align: center;
  color: var(--text-soft); font-size: 12.5px;
}

.fichas-campo { display: flex; flex-direction: column; gap: 4px; font-size: 11px; color: var(--text-soft); font-weight: 600; }
.fichas-campo-check { flex-direction: row; align-items: center; gap: 7px; font-size: 12.5px; color: var(--text-2); cursor: pointer; }
.fichas-campo-check input { cursor: pointer; }

/* ── Vista previa (imita la hoja impresa) ────────────────────────────────── */
.fichas-preview-marco {
  background: var(--surface-sunk);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 16px;
  max-height: 520px; overflow: auto;
}
/* La etiqueta en sí la pinta la hoja compartida `App._fqlEstilos` (app.js),
   la misma para la previa y para el papel. Aquí solo el marco de la previa. */
.fichas-preview { display: block; }
.fichas-preview .fichas-vacio { font-size: 13px; }

/* Widget del dashboard que ocupa toda la fila (tabla ancha) */
.dash-widget-ancho { grid-column: 1 / -1; }
.filter-select-sm { padding: 3px 8px; font-size: 11.5px; min-width: 0; }
/* El asa de arrastre ahora es un SVG: se centra y reacciona al hover */
.dash-widget-drag-handle {
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--text-xsoft);
  transition: color var(--transition), transform var(--transition);
}
.dash-widget:hover .dash-widget-drag-handle { color: var(--text-soft); }
.dash-widget-drag-handle:hover { color: var(--blue); transform: scale(1.15); cursor: grab; }
.dash-widget-drag-handle:active { cursor: grabbing; }

/* ═══════════════════════════════════════════════════════════════════════════
   CAPA DE INTERACCIÓN GLOBAL
   Todo lo que se puede pulsar responde: elevación, desplazamiento sutil o
   cambio de color. Nada se mueve más de 1-2px ni tarda más de 0.18s, para que
   la interfaz se sienta viva sin resultar saltarina.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Filas de tabla: resaltado y acciones que aparecen al acercarse ──────── */
.tabla tbody tr { transition: background var(--transition), box-shadow var(--transition); }
.tabla tbody tr:hover { box-shadow: inset 3px 0 0 var(--blue); }
.tabla tbody tr .actions { opacity: 0.55; transition: opacity var(--transition); }
.tabla tbody tr:hover .actions,
.tabla tbody tr:focus-within .actions { opacity: 1; }

/* ── Tarjetas: elevación al pasar por encima ─────────────────────────────── */
.card, .chart-card, .panel, .dash-widget, .inv-dash-card,
.eco-stat-card, .veh-card, .emp-card, .flt-card, .mifi-card {
  transition: box-shadow var(--transition), border-color var(--transition),
              transform var(--transition);
}
.dash-widget:hover, .eco-stat-card:hover, .veh-card:hover,
.emp-card:hover, .flt-card:hover, .mifi-card:hover {
  box-shadow: var(--shadow-lift);
  border-color: var(--border-med);
}
.inv-dash-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-lift); }
.inv-dash-card:active { transform: translateY(0); }

/* ── Botones: hundido al pulsar y anillo al enfocar con teclado ──────────── */
.btn { will-change: transform; }
.btn:active:not(:disabled) { transform: translateY(1px) scale(0.985); }
.btn-primary:hover:not(:disabled) { transform: translateY(-1px); }
.btn-primary:active:not(:disabled) { transform: translateY(0) scale(0.985); }

/* ── Control segmentado: la pastilla activa se asienta ───────────────────── */
.seg-btn { transition: background var(--transition), color var(--transition), transform var(--transition); }
.seg-btn:hover:not(.active) { background: rgba(255,255,255,0.55); color: var(--text); }
.seg-btn:active { transform: scale(0.97); }

/* ── Chips y badges pulsables ────────────────────────────────────────────── */
.badge { transition: transform var(--transition); }
button.badge:hover, a .badge:hover { transform: scale(1.06); }
.cat-chip:active, .pres-chip:active { transform: scale(0.97); }

/* ── Campos de formulario: el borde se anima ─────────────────────────────── */
.form-control, .filter-input, .filter-select {
  transition: border-color var(--transition), box-shadow var(--transition), background var(--transition);
}
.filter-input:hover, .filter-select:hover, .form-control:hover { background: var(--surface); }

/* ── Enlaces internos ────────────────────────────────────────────────────── */
a:not(.nav-item):not(.btn) { transition: color var(--transition); }

/* ── Pestañas ────────────────────────────────────────────────────────────── */
.it-tab, .veh-tab, [class$="-tab"] {
  transition: background var(--transition), color var(--transition), box-shadow var(--transition);
}
.it-tab:hover:not(.active), .veh-tab:hover:not(.active) {
  background: var(--bg-hover);
  color: var(--text);
}

/* ── Modales: entran con un ligero impulso ──────────────────────────────── */
@keyframes modal-entra {
  from { opacity: 0; transform: translateY(10px) scale(0.985); }
  to   { opacity: 1; transform: none; }
}
.modal-overlay.open .modal { animation: modal-entra 0.19s cubic-bezier(0.2,0.9,0.3,1); }
.modal-close {
  transition: background var(--transition), color var(--transition), transform var(--transition);
  border-radius: var(--radius-xs);
}
.modal-close:hover { background: var(--surface-sunk); color: var(--red); transform: rotate(90deg); }

/* ── Avisos (toast) ──────────────────────────────────────────────────────── */
.toast { transition: transform 0.24s cubic-bezier(0.2,0.9,0.3,1), opacity 0.2s ease; }

/* ── Estado de carga: el cursor lo dice ─────────────────────────────────── */
[aria-busy="true"], .cargando { cursor: progress; }

/* Nada de esto se mueve si el sistema pide reducir movimiento (regla ya
   declarada arriba en la capa de acabado). */

/* ═══════════════════════════════════════════════════════════════════════════
   WIDGET "MATERIAL MÁS ALQUILADO"
   Antes iba con estilos en línea; aquí se llevan a clases y se añade el
   selector de departamento (top 10 global o top 10 de Cámara / Luces / Grip).
   ═══════════════════════════════════════════════════════════════════════════ */
.topmat-tabs {
  display: flex; flex-wrap: wrap; gap: 4px;
  margin-bottom: 10px;
  padding-bottom: 9px;
  border-bottom: 1px solid var(--border);
}
.topmat-tab {
  display: inline-flex; align-items: center; gap: 5px;
  font: inherit; font-size: 11.5px; font-weight: 600;
  background: none; border: 1px solid transparent;
  border-radius: var(--radius-pill);
  padding: 3px 9px;
  color: var(--text-soft); cursor: pointer;
  transition: background var(--transition), color var(--transition),
              border-color var(--transition), transform var(--transition);
}
.topmat-tab:hover { background: var(--surface-sunk); color: var(--text); }
.topmat-tab:active { transform: scale(0.97); }
.topmat-tab.active {
  background: var(--text); color: var(--surface); border-color: var(--text);
}
/* Un departamento sin alquileres se muestra atenuado, pero se muestra: si
   desapareciera parecería que falta algo. */
.topmat-tab.vacia { opacity: 0.5; }
.topmat-tab.vacia.active { opacity: 1; }
.topmat-n {
  font-size: 10px; font-weight: 700;
  background: var(--surface-sunk); color: var(--text-soft);
  border-radius: var(--radius-pill); padding: 0 5px;
  font-variant-numeric: tabular-nums;
}
.topmat-tab.active .topmat-n { background: rgba(255,255,255,0.22); color: #fff; }

.topmat-lista { list-style: none; margin: 0; padding: 0; }
.topmat-fila {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 4px;
  border-bottom: 1px solid var(--border);
  border-radius: var(--radius-xs);
  transition: background var(--transition);
}
.topmat-fila:last-child { border-bottom: none; }
.topmat-fila:hover { background: var(--bg-hover); }

.topmat-pos {
  flex-shrink: 0; min-width: 20px;
  font-size: 12px; font-weight: 700; text-align: right;
  color: var(--text-xsoft);
  font-variant-numeric: tabular-nums;
}
/* Los tres primeros destacan: es un ranking, se debe ver de un vistazo */
.topmat-pos.podio { color: var(--text); }

.topmat-cuerpo { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.topmat-nombre {
  font-size: 12.5px; font-weight: 550; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.topmat-cat { font-size: 10.5px; color: var(--text-soft); }
.topmat-barra {
  display: block; height: 4px; margin-top: 2px;
  background: var(--surface-sunk);
  border-radius: var(--radius-pill);
  overflow: hidden;
}
.topmat-barra-fill {
  display: block; height: 100%;
  background: linear-gradient(90deg, var(--accent) 0%, rgba(var(--acento-rgb), 0.55) 100%);
  border-radius: var(--radius-pill);
  transition: width 0.32s cubic-bezier(0.2,0.9,0.3,1);
}
.topmat-cifras {
  flex-shrink: 0; text-align: right; min-width: 52px;
  font-variant-numeric: tabular-nums;
}
/* Los días mandan y las veces son el pie: es lo que se viene a mirar.
   Estaba al revés, y a la vez se contaban mal. */
.topmat-dias  { display: block; font-size: 14px; font-weight: 700; color: var(--text); letter-spacing: -0.02em; }
.topmat-veces { display: block; font-size: 10.5px; color: var(--text-soft); }

.topmat-vacio {
  padding: 24px 12px; text-align: center;
  color: var(--text-soft); font-size: 12.5px; line-height: 1.5;
}

/* El widget no debe cambiar de alto al cambiar de departamento: se reserva la
   altura de la lista más larga (--topmat-filas lo fija el render) y se da
   altura fija a la fila, que además deja la lista más regular. */
#top-material-widget { min-height: calc(var(--topmat-filas, 10) * 44px); }
.topmat-fila { height: 44px; box-sizing: border-box; }
/* El mensaje de "sin datos" se centra en el hueco reservado en vez de dejarlo
   arriba con un vacío raro debajo. */
.topmat-vacio {
  min-height: calc(var(--topmat-filas, 10) * 44px);
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  padding: 12px;
}

/* ── Rejilla del dashboard: columnas que no las empuja el contenido ────────
   `1fr` equivale a `minmax(auto, 1fr)`, y ese mínimo `auto` deja que el texto
   más largo de un widget ensanche su columna. Efecto observado: al filtrar el
   widget de material más alquilado, el nombre más largo desaparecía, la columna
   se encogía de 640 a 432px y la barra de pestañas pasaba a dos líneas.
   Con `minmax(0, 1fr)` las columnas mantienen su proporción siempre. */
/* Acotada a partir de 1101px: por debajo, la media query de arriba ya colapsa
   la rejilla a una columna, y sin este límite esta regla la anulaba y dejaba
   columnas de 118px. */
@media (min-width: 1101px) {
  .dash-bottom-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr) minmax(0, 1fr); }
}
.dash-widget { min-width: 0; }

/* Y la barra de pestañas no envuelve: si no cabe, se desplaza en horizontal.
   Así su altura es constante pase lo que pase con el ancho. */
.topmat-tabs {
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
  min-height: 26px;
}
.topmat-tabs::-webkit-scrollbar { height: 0; }
.topmat-tab { flex-shrink: 0; }

/* ═══════════════════════════════════════════════════════════════════════════
   EQUIPO DE RODAJE — cuadrícula tipo hoja de cálculo
   Filas = plazas fijas agrupadas por departamento, columnas = proyectos.
   La primera columna y la cabecera quedan fijas al desplazar; los fondos de
   ambas son OPACOS a propósito (con fondo translúcido el contenido de las
   celdas se transparenta por debajo al hacer scroll).
   ═══════════════════════════════════════════════════════════════════════════ */

.crew-barra {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; flex-wrap: wrap; margin-bottom: 12px;
}
.crew-leyenda { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.crew-leyenda-item {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 11.5px; font-weight: 600; color: var(--text-2);
}
.crew-leyenda-punto { width: 9px; height: 9px; border-radius: 0; flex-shrink: 0; }
.crew-toggle {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 12.5px; color: var(--text-2); cursor: pointer;
}
.crew-toggle input { cursor: pointer; }

.crew-grid-wrap {
  overflow: auto;
  max-height: calc(100vh - 300px);
  border: 1px solid var(--border-med);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow-xs);
  overscroll-behavior: contain;
}
.crew-grid {
  border-collapse: separate;
  border-spacing: 0;
  width: max-content;
  min-width: 100%;
  font-variant-numeric: tabular-nums;
}

/* ── Cabecera ────────────────────────────────────────────────────────────── */
.crew-grid thead th {
  position: sticky; top: 0; z-index: 6;
  background: #14141a;
  color: rgba(255,255,255,0.9);
  padding: 9px 12px;
  text-align: left;
  border-bottom: 1px solid rgba(255,255,255,0.10);
  border-right: 1px solid rgba(255,255,255,0.07);
}
.crew-th-esquina {
  left: 0; z-index: 8 !important;
  min-width: 152px; width: 152px;
  font-size: 10px; font-weight: 700; letter-spacing: 0.11em;
  text-transform: uppercase; color: rgba(255,255,255,0.5);
}
.crew-grid thead .crew-th-esquina { position: sticky; }
.crew-th-proy {
  min-width: 178px;
  display: table-cell;
  border-top: 3px solid var(--proy-color, var(--text-soft));
}
.crew-th-punto {
  display: inline-block; width: 8px; height: 8px; border-radius: 50%;
  background: var(--proy-color, var(--text-soft));
  margin-right: 7px; vertical-align: 1px;
}
.crew-th-nom {
  font-size: 13px; font-weight: 650; letter-spacing: -0.01em;
  color: #fff;
}
.crew-th-fechas {
  display: block; margin-top: 2px; padding-left: 15px;
  font-size: 10px; font-weight: 500; color: rgba(255,255,255,0.45);
}

/* ── Franja de departamento ──────────────────────────────────────────────── */
.crew-fila-grupo th, .crew-fila-grupo td {
  background: var(--surface-sunk);
  border-bottom: 1px solid var(--border-med);
  border-top: 1px solid var(--border-med);
  padding: 4px 12px;
}
.crew-td-grupo {
  position: sticky; left: 0; z-index: 4;
  background: var(--surface-sunk);
  text-align: left;
  font-size: 9.5px; font-weight: 800; letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--grupo-color, var(--text-soft));
  box-shadow: inset 3px 0 0 var(--grupo-color, transparent);
}

/* ── Filas de plaza ──────────────────────────────────────────────────────── */
.crew-fila th, .crew-fila td {
  border-bottom: 1px solid var(--border);
  border-right: 1px solid var(--border);
  height: 50px;
}
.crew-td-rol {
  position: sticky; left: 0; z-index: 4;
  /* Fondo opaco obligatorio: es columna fija y por debajo pasan las celdas */
  background: var(--surface);
  padding: 0 12px;
  text-align: left;
  font-size: 11.5px; font-weight: 700; letter-spacing: 0.03em;
  color: var(--text);
  white-space: nowrap;
  box-shadow: inset 3px 0 0 var(--grupo-color, transparent), 1px 0 0 var(--border-med);
}
.crew-rol-n {
  display: inline-block; margin-left: 5px;
  font-size: 9.5px; font-weight: 700;
  background: var(--surface-sunk); color: var(--text-soft);
  border-radius: var(--radius-pill); padding: 0 5px;
}
.crew-fila:hover .crew-td-rol { background: #f7f9fb; }

/* ── Celdas ──────────────────────────────────────────────────────────────── */
.crew-celda {
  padding: 6px 12px;
  cursor: pointer;
  vertical-align: middle;
  transition: background var(--transition), box-shadow var(--transition);
}
.crew-celda:hover {
  background: var(--bg-hover);
  box-shadow: inset 0 0 0 2px rgba(var(--acento-rgb), 0.30);
}
/* Una celda cubierta se tiñe del color de su departamento, muy suave: así de
   un vistazo se ve qué está cubierto y de qué equipo es. */
.crew-celda.llena {
  background: color-mix(in srgb, var(--grupo-color) 7%, transparent);
}
@supports not (background: color-mix(in srgb, red 7%, transparent)) {
  .crew-celda.llena { background: var(--surface-2); }
}
.crew-celda-cond {
  display: block;
  font-size: 12.5px; font-weight: 650; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.crew-celda-veh {
  display: block; margin-top: 1px;
  font-size: 10.5px; font-weight: 550;
  color: var(--grupo-color, var(--text-soft));
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.crew-celda-sinveh {
  display: block; margin-top: 1px;
  font-size: 10.5px; font-style: italic; color: var(--text-xsoft);
}
/* El "+" solo se insinúa: una cuadrícula llena de signos sería ruido */
.crew-celda-add {
  display: block; text-align: center;
  font-size: 17px; font-weight: 400; line-height: 1;
  color: var(--text-xsoft);
  opacity: 0;
  transition: opacity var(--transition);
}
.crew-celda:hover .crew-celda-add { opacity: 1; }

/* ── Pie con el recuento ─────────────────────────────────────────────────── */
.crew-grid tfoot th, .crew-grid tfoot td {
  position: sticky; bottom: 0; z-index: 5;
  background: var(--surface-2);
  border-top: 1px solid var(--border-med);
  padding: 7px 12px;
  font-size: 11.5px; font-weight: 700;
  color: var(--text-2);
}
.crew-pie-rol {
  left: 0; z-index: 7 !important;
  text-align: left;
  font-size: 10px; letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--text-soft);
  box-shadow: 1px 0 0 var(--border-med);
}
.crew-pie-celda { text-align: left; }

/* ── Asignaciones fuera de plaza ─────────────────────────────────────────── */
.crew-huerfanos {
  margin-top: 12px; padding: 12px 14px;
  background: rgba(255,149,0,0.07);
  border: 1px solid rgba(255,149,0,0.28);
  border-radius: var(--radius-sm);
  font-size: 12.5px; color: var(--text-2); line-height: 1.5;
}
.crew-huerfanos ul { margin: 6px 0 0; padding-left: 4px; list-style: none; }
.crew-huerfano-btn {
  font: inherit; font-size: 12px;
  background: var(--surface); border: 1px solid var(--border-med);
  border-radius: var(--radius-xs); padding: 3px 9px; margin: 3px 0;
  cursor: pointer; color: var(--text);
  transition: border-color var(--transition), background var(--transition);
}
.crew-huerfano-btn:hover { border-color: var(--orange); background: var(--surface-2); }

.crew-vacio {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding: 50px 20px; color: var(--text-soft); font-size: 13px;
}

/* ═══════════════════════════════════════════════════════════════════════════
   WIDGET DE FLOTA EN PROYECTOS — versión escalable
   El problema era el crecimiento: una píldora por vehículo convertía la
   tarjeta en una columna interminable con flotas grandes. Ahora hay un resumen
   por tipo (siempre del mismo tamaño) y las píldoras van con tope y "+N más".
   ═══════════════════════════════════════════════════════════════════════════ */

.fleet-proj-resumen {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 9px 0 7px;
  padding: 6px 9px;
  background: var(--surface-sunk);
  border-radius: var(--radius-xs);
}
.fleet-tipo {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 12px; color: var(--text-2);
}
.fleet-tipo svg { color: var(--text-soft); }
.fleet-tipo b { font-weight: 700; font-variant-numeric: tabular-nums; }
.fleet-total {
  margin-left: auto;
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--text-xsoft);
  font-variant-numeric: tabular-nums;
}

.fleet-proj-vehs { display: flex; flex-direction: column; gap: 4px; }
.fleet-proj-veh-pill {
  display: flex; align-items: center; gap: 7px;
  padding: 4px 8px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-xs);
  font-size: 11.5px;
  transition: border-color var(--transition), background var(--transition);
}
.fleet-proj-veh-pill:hover { border-color: var(--border-med); background: var(--surface); }
/* Los que llevan conductor se marcan: son los que aportan el dato útil */
.fleet-proj-veh-pill.con-conductor { border-left: 2px solid var(--accent); }
.fleet-pill-icon { display: inline-flex; color: var(--text-soft); flex-shrink: 0; }
.fleet-pill-name {
  flex: 1; min-width: 0;
  font-weight: 550; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.fleet-pill-mat { opacity: 0.55; font-variant-numeric: tabular-nums; }
.fleet-pill-driver {
  flex-shrink: 0; max-width: 45%;
  font-size: 10.5px; font-weight: 650;
  color: var(--accent);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.fleet-mas {
  align-self: flex-start;
  font: inherit; font-size: 11px; font-weight: 650;
  background: none; border: 1px dashed var(--border-strong);
  border-radius: var(--radius-xs);
  padding: 3px 10px; margin-top: 1px;
  color: var(--text-soft); cursor: pointer;
  transition: border-color var(--transition), color var(--transition), background var(--transition);
}
.fleet-mas:hover { border-color: var(--accent); color: var(--accent); background: var(--bg-hover); }

.fleet-proj-sinflota { font-size: 12px; color: var(--text-soft); margin-top: 8px; }
.fleet-link {
  font: inherit; background: none; border: none; padding: 0;
  color: var(--accent); cursor: pointer; text-decoration: underline;
}

/* ═══════════════════════════════════════════════════════════════════════════
   AJUSTES: tarjeta de economía, logo en claro y desplegable de flota
   ═══════════════════════════════════════════════════════════════════════════ */

/* Un importe con miles y decimales no cabe al tamaño de un contador ("3570,0"
   salía cortado). Se reduce y se deja que se ajuste al ancho disponible. */
.stat-value-eur {
  font-size: clamp(17px, 2vw, 25px);
  letter-spacing: -0.03em;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* ── Logo de la barra lateral en claro ────────────────────────────────────
   El PNG es oscuro y la barra ahora es negra: se invierte, igual que ya se
   hacía con la palmera de fondo. */
.logo-mark img {
  filter: invert(1) brightness(1.08);
}
.logo-mark {
  background: rgba(255,255,255,0.07);
  border-color: rgba(255,255,255,0.14);
}
.sidebar-logo:hover .logo-mark {
  background: rgba(239,35,60,0.16);
  border-color: rgba(239,35,60,0.42);
}
.logo-title { color: #fff; }
.logo-sub   { color: rgba(255,255,255,0.42); }

/* ── La barra de resumen del widget de flota es un desplegable ───────────── */
.fleet-proj-resumen {
  width: 100%;
  font: inherit;
  text-align: left;
  cursor: pointer;
  border: 1px solid var(--border);
  transition: background var(--transition), border-color var(--transition);
}
.fleet-proj-resumen:hover {
  background: var(--bg-hover);
  border-color: var(--border-strong);
}
.fleet-proj-resumen.abierto {
  border-color: var(--accent);
  background: rgba(var(--acento-rgb), 0.05);
}
.fleet-chevron {
  color: var(--text-soft);
  flex-shrink: 0;
  transition: transform 0.2s cubic-bezier(0.34,1.2,0.64,1), color var(--transition);
}
.fleet-proj-resumen:hover .fleet-chevron { color: var(--accent); }
.fleet-proj-resumen.abierto .fleet-chevron { transform: rotate(180deg); color: var(--accent); }
/* El total deja de empujar al chevron al borde */
.fleet-proj-resumen .fleet-total { margin-left: auto; }
.fleet-proj-vehs { margin-top: 5px; }

/* ── Etiquetas del widget de devoluciones ────────────────────────────────── */
.agenda-etiquetas {
  display: flex; align-items: center; gap: 5px; flex-wrap: wrap;
  margin-top: 4px;
}
.agenda-dep {
  font-size: 10px; font-weight: 700; letter-spacing: 0.04em;
  text-transform: uppercase;
  background: rgba(var(--acento-rgb), 0.10);
  color: var(--accent);
  border-radius: var(--radius-pill); padding: 1px 8px;
}
.agenda-cat {
  font-size: 10px; font-weight: 600;
  background: var(--surface-sunk); color: var(--text-soft);
  border-radius: var(--radius-pill); padding: 1px 8px;
}
/* Botón para asignar departamento: discreto hasta que se pasa por encima */
.agenda-dep-add {
  font: inherit; font-size: 10px; font-weight: 600;
  background: none; border: 1px dashed var(--border-strong);
  border-radius: var(--radius-pill); padding: 1px 8px;
  color: var(--text-xsoft); cursor: pointer;
  transition: color var(--transition), border-color var(--transition), background var(--transition);
}
.agenda-dep-add:hover {
  color: var(--accent); border-color: var(--accent);
  background: rgba(var(--acento-rgb), 0.07);
}

/* ── Barra lateral en pantallas de poca altura ─────────────────────────────
   `.sidebar-nav` es un contenedor flex en columna, y por defecto sus hijos
   pueden encogerse por debajo de su contenido (`flex-shrink: 1`). En una
   ventana baja los rótulos de sección quedaban a 20px necesitando 34 y se
   recortaban, y la barra no llegaba a hacer scroll porque todo cabía
   "comprimido". Con flex-shrink: 0 mantienen su tamaño y aparece el scroll. */
.sidebar-nav > * { flex-shrink: 0; }
.sidebar .nav-item,
.sidebar .nav-section-label { flex-shrink: 0; }

/* ═══════════════════════════════════════════════════════════════════════════
   PROYECTOS — pestañas, cajón lateral y calendario resumido
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Distribución: la lista cede ancho al cajón, no lo tapa ──────────────── */
.proy-layout { display: flex; gap: 0; align-items: flex-start; }
.proy-main {
  flex: 1; min-width: 0;
  transition: padding-right 0.26s cubic-bezier(0.2,0.9,0.3,1);
}
.proy-layout.con-drawer .proy-main { padding-right: 22px; }

.proy-drawer {
  width: 0;
  flex-shrink: 0;
  overflow: hidden;
  transition: width 0.26s cubic-bezier(0.2,0.9,0.3,1);
  align-self: stretch;
}
.proy-layout.con-drawer .proy-drawer { width: min(520px, 46vw); }
.proy-drawer-inner {
  width: min(520px, 46vw);
  position: sticky;
  top: 0;
  max-height: calc(100vh - 48px);
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--surface);
  border: 1px solid var(--border-med);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
}
/* En pantallas estrechas el cajón pasa a ocupar todo: partir la vista en dos
   columnas de 300px no serviría de nada. */
@media (max-width: 1200px) {
  .proy-layout.con-drawer .proy-main { display: none; }
  .proy-layout.con-drawer .proy-drawer { width: 100%; }
  .proy-drawer-inner { width: 100%; }
}

/* ── Pestañas superiores ─────────────────────────────────────────────────── */
.proy-tabs {
  display: flex; gap: 3px; flex-wrap: wrap;
  margin-bottom: 16px;
  padding-bottom: 2px;
  border-bottom: 1px solid var(--border-med);
}
.proy-tab {
  display: inline-flex; align-items: center; gap: 7px;
  font: inherit; font-size: 13px; font-weight: 600;
  background: none; border: none;
  border-bottom: 2px solid transparent;
  padding: 9px 14px; margin-bottom: -1px;
  color: var(--text-soft); cursor: pointer;
  transition: color var(--transition), border-color var(--transition), background var(--transition);
}
.proy-tab:hover { color: var(--text); background: var(--bg-hover); }
.proy-tab.active { color: var(--accent); border-bottom-color: var(--accent); }
.proy-tab svg { opacity: 0.7; }
.proy-tab.active svg { opacity: 1; }
.proy-tab-n {
  font-size: 10.5px; font-weight: 700;
  background: var(--surface-sunk); color: var(--text-soft);
  border-radius: var(--radius-pill); padding: 0 6px;
  font-variant-numeric: tabular-nums;
}
.proy-tab.active .proy-tab-n { background: rgba(var(--acento-rgb), 0.12); color: var(--accent); }

/* ── Tabla de proyectos ──────────────────────────────────────────────────── */
.proy-fila { cursor: pointer; }
.proy-fila.abierta {
  background: rgba(var(--acento-rgb), 0.06) !important;
  box-shadow: inset 3px 0 0 var(--accent) !important;
}
.proy-celda-nombre { display: flex; align-items: center; gap: 9px; }
.proy-punto { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; }
.proy-cliente { font-size: 11px; color: var(--text-soft); margin-top: 1px; }
.proy-chips { display: flex; gap: 4px; margin-left: auto; }
.proy-chip {
  display: inline-flex; align-items: center; gap: 3px;
  font-size: 10.5px; font-weight: 650;
  background: var(--surface-sunk); color: var(--text-soft);
  border-radius: var(--radius-pill); padding: 1px 7px;
  font-variant-numeric: tabular-nums;
}
.proy-chip svg { opacity: 0.65; }
.proy-pista {
  font-size: 11.5px; color: var(--text-xsoft);
  padding: 9px 2px 0;
}

/* ── Cajón: cabecera ────────────────────────────────────────────────────── */
.drawer-cargando { padding: 44px 20px; text-align: center; color: var(--text-soft); font-size: 13px; }
.drawer-head {
  padding: 16px 18px 14px;
  border-bottom: 1px solid var(--border);
  border-top: 3px solid var(--proy-color, var(--accent));
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  background: linear-gradient(180deg, var(--surface-2) 0%, var(--surface) 100%);
  position: sticky; top: 0; z-index: 3;
}
.drawer-head-top { display: flex; align-items: center; gap: 9px; }
.drawer-punto {
  width: 11px; height: 11px; border-radius: 50%;
  background: var(--proy-color, var(--accent)); flex-shrink: 0;
}
.drawer-titulo {
  flex: 1; min-width: 0; margin: 0;
  font-size: 18px; font-weight: 700; letter-spacing: -0.025em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.drawer-cerrar {
  flex-shrink: 0;
  background: none; border: none; cursor: pointer;
  color: var(--text-soft); padding: 5px;
  border-radius: var(--radius-xs);
  transition: background var(--transition), color var(--transition), transform var(--transition);
}
.drawer-cerrar:hover { background: var(--surface-sunk); color: var(--red); transform: rotate(90deg); }
.drawer-head-meta {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-top: 8px;
}
.drawer-cliente { font-size: 12px; color: var(--text-2); font-weight: 550; }
.drawer-restantes {
  font-size: 11px; font-weight: 650;
  color: var(--accent);
  background: rgba(var(--acento-rgb), 0.09);
  border-radius: var(--radius-pill); padding: 1px 9px;
}
.drawer-restantes.pasado { color: var(--red-dark); background: rgba(217,4,41,0.10); }
.drawer-progreso { margin-top: 11px; }
.drawer-progreso-track {
  height: 5px; background: var(--surface-sunk);
  border-radius: var(--radius-pill); overflow: hidden;
}
.drawer-progreso-fill {
  height: 100%; background: var(--proy-color, var(--accent));
  border-radius: var(--radius-pill);
  transition: width 0.4s cubic-bezier(0.2,0.9,0.3,1);
}
.drawer-progreso-fechas {
  display: flex; justify-content: space-between;
  margin-top: 4px;
  font-size: 10.5px; color: var(--text-soft);
  font-variant-numeric: tabular-nums;
}
.drawer-acciones { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 12px; }

/* ── Cajón: secciones ───────────────────────────────────────────────────── */
.drawer-cuerpo { padding: 4px 18px 22px; }
.drawer-sec { padding: 16px 0; border-bottom: 1px solid var(--border); }
.drawer-sec:last-child { border-bottom: none; }
.drawer-sec-tit {
  display: flex; align-items: center; gap: 8px;
  margin: 0 0 11px;
  font-size: 10.5px; font-weight: 800; letter-spacing: 0.11em;
  text-transform: uppercase; color: var(--text-soft);
}
.drawer-sec-n {
  font-size: 10px; font-weight: 700; letter-spacing: 0;
  background: var(--surface-sunk); color: var(--text-soft);
  border-radius: var(--radius-pill); padding: 0 6px;
  font-variant-numeric: tabular-nums;
}
.drawer-sec-eur {
  margin-left: auto; letter-spacing: 0;
  font-size: 12px; font-weight: 700; color: var(--text);
  font-variant-numeric: tabular-nums;
}
.drawer-sec-add {
  margin-left: auto; letter-spacing: 0; text-transform: none;
  font: inherit; font-size: 11px; font-weight: 600;
  background: none; border: none; padding: 0;
  color: var(--accent); cursor: pointer;
}
.drawer-sec-add:hover { text-decoration: underline; }
.drawer-vacio { font-size: 12.5px; color: var(--text-soft); line-height: 1.5; }

.drawer-datos { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 9px 14px; }
.drawer-datos dt { font-size: 10px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase; color: var(--text-xsoft); }
.drawer-datos dd { margin: 2px 0 0; font-size: 13px; font-weight: 600; color: var(--text); }
.drawer-notas {
  margin-top: 12px; padding: 10px 12px;
  background: var(--surface-sunk); border-radius: var(--radius-xs);
  font-size: 12.5px; color: var(--text-2); line-height: 1.5;
  white-space: pre-wrap;
}

/* ── Contactos ──────────────────────────────────────────────────────────── */
.drawer-contactos { display: flex; flex-direction: column; gap: 7px; }
.drawer-contacto {
  padding: 9px 11px;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius-xs);
}
.drawer-contacto-rol {
  display: inline-block;
  font-size: 9.5px; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--accent); background: rgba(var(--acento-rgb), 0.09);
  border-radius: var(--radius-pill); padding: 1px 7px;
}
.drawer-contacto-nombre { display: block; margin-top: 4px; font-size: 13px; font-weight: 650; }
.drawer-contacto-vias { display: flex; flex-direction: column; gap: 1px; margin-top: 3px; }
.drawer-via { font-size: 11.5px; color: var(--text-soft); text-decoration: none; }
.drawer-via:hover { color: var(--accent); text-decoration: underline; }

/* ── Flota ──────────────────────────────────────────────────────────────── */
.drawer-flota { display: flex; flex-direction: column; gap: 5px; }
.drawer-veh {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 10px;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius-xs); font-size: 12.5px;
}
.drawer-veh-ico { color: var(--text-soft); display: inline-flex; flex-shrink: 0; }
.drawer-veh-nom { flex: 1; min-width: 0; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.drawer-veh-mat { opacity: 0.55; font-weight: 500; font-variant-numeric: tabular-nums; }
.drawer-veh-cond { font-size: 11px; font-weight: 650; color: var(--accent); flex-shrink: 0; }

/* ── Presupuestos y desglose ────────────────────────────────────────────── */
.drawer-pres { display: flex; flex-direction: column; gap: 4px; }
.drawer-pres-fila {
  display: flex; align-items: center; gap: 8px;
  width: 100%; font: inherit; text-align: left; cursor: pointer;
  padding: 7px 10px;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius-xs);
  transition: border-color var(--transition), background var(--transition);
}
.drawer-pres-fila:hover { border-color: var(--accent); background: var(--bg-hover); }
.drawer-pres-num { font-size: 11px; font-weight: 700; color: var(--text-soft); font-variant-numeric: tabular-nums; flex-shrink: 0; }
.drawer-pres-cli { flex: 1; min-width: 0; font-size: 12.5px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.drawer-pres-eur { font-size: 12.5px; font-weight: 700; font-variant-numeric: tabular-nums; flex-shrink: 0; }

.drawer-dep-tit {
  margin: 15px 0 8px;
  font-size: 10px; font-weight: 800; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--text-xsoft);
}
.drawer-deps { display: flex; flex-direction: column; gap: 3px; }
.drawer-dep {
  display: flex; align-items: center; gap: 9px;
  width: 100%; font: inherit; text-align: left; cursor: pointer;
  padding: 5px 8px; border-radius: var(--radius-xs);
  background: none; border: 1px solid transparent;
  transition: background var(--transition), border-color var(--transition);
}
.drawer-dep:hover { background: var(--bg-hover); }
.drawer-dep.activo { border-color: var(--accent); background: rgba(var(--acento-rgb), 0.06); }
.drawer-dep-nom { width: 92px; flex-shrink: 0; font-size: 11.5px; font-weight: 650; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.drawer-dep-barra { flex: 1; height: 6px; background: var(--surface-sunk); border-radius: var(--radius-pill); overflow: hidden; }
.drawer-dep-barra > span { display: block; height: 100%; background: var(--accent); border-radius: var(--radius-pill); }
.drawer-dep-eur { font-size: 11.5px; font-weight: 700; font-variant-numeric: tabular-nums; flex-shrink: 0; min-width: 74px; text-align: right; }

.drawer-dep-lineas { margin-top: 10px; padding: 10px; background: var(--surface-sunk); border-radius: var(--radius-xs); }
.drawer-dep-lineas-tit {
  display: flex; align-items: center; gap: 8px;
  margin-bottom: 7px;
  font-size: 11px; font-weight: 700; color: var(--text-2);
}
.drawer-linea {
  display: flex; align-items: center; gap: 9px;
  padding: 4px 0; border-bottom: 1px solid var(--border);
  font-size: 11.5px;
}
.drawer-linea:last-child { border-bottom: none; }
.drawer-linea-desc { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.drawer-linea-cant { color: var(--text-soft); flex-shrink: 0; font-variant-numeric: tabular-nums; }
.drawer-linea-eur { font-weight: 700; flex-shrink: 0; min-width: 66px; text-align: right; font-variant-numeric: tabular-nums; }

/* ── Material ───────────────────────────────────────────────────────────── */
.drawer-material { display: flex; flex-direction: column; }
.drawer-mat {
  display: flex; align-items: center; gap: 9px;
  padding: 5px 2px; border-bottom: 1px solid var(--border);
  font-size: 11.5px;
}
.drawer-mat:last-child { border-bottom: none; }
.drawer-mat-cod { width: 54px; flex-shrink: 0; font-weight: 650; color: var(--text-soft); font-variant-numeric: tabular-nums; overflow: hidden; text-overflow: ellipsis; }
.drawer-mat-nom { flex: 1; min-width: 0; font-weight: 550; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.drawer-mat-dep { font-size: 10px; font-weight: 650; color: var(--text-soft); background: var(--surface-sunk); border-radius: var(--radius-pill); padding: 0 6px; flex-shrink: 0; }
.drawer-mat-dias { width: 42px; text-align: right; flex-shrink: 0; font-weight: 700; font-variant-numeric: tabular-nums; }

/* ── Modal de contactos ─────────────────────────────────────────────────── */
.contactos-cab, .contacto-fila {
  display: grid;
  grid-template-columns: 130px 1fr 1fr 120px 34px;
  gap: 7px; align-items: center;
}
.contactos-cab {
  font-size: 10px; font-weight: 700; letter-spacing: 0.07em;
  text-transform: uppercase; color: var(--text-xsoft);
  padding: 0 2px 6px;
}
.contacto-fila { margin-bottom: 6px; }
.contacto-fila .form-control { font-size: 12.5px; padding: 5px 8px; }

/* ── Calendario resumido de proyectos ───────────────────────────────────── */
.proy-cal-card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 14px 16px 12px;
  box-shadow: var(--shadow-xs);
}
.proy-cal-barra {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-bottom: 14px;
}
.proy-cal-titulo {
  font-size: 14px; font-weight: 680; letter-spacing: -0.02em;
  min-width: 190px;
}
.proy-cal-rango { display: inline-flex; gap: 2px; margin-left: auto; background: var(--surface-sunk); border-radius: 0; padding: 2px; }

.proy-cal-cabecera { display: flex; border-bottom: 1px solid var(--border-med); }
.proy-cal-etq-hueco, .proy-cal-etq { width: 178px; min-width: 178px; flex-shrink: 0; }
.proy-cal-meses { flex: 1; display: flex; }
.proy-cal-mes {
  text-align: center; padding: 5px 2px 7px;
  border-left: 1px solid var(--border);
  font-size: 11px; font-weight: 700; color: var(--text-2);
}
.proy-cal-mes small { display: block; font-size: 9.5px; font-weight: 500; color: var(--text-xsoft); }

.proy-cal-filas { display: flex; flex-direction: column; }
.proy-cal-fila {
  display: flex; align-items: center;
  min-height: 38px;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  transition: background var(--transition);
}
.proy-cal-fila:last-child { border-bottom: none; }
.proy-cal-fila:hover { background: var(--bg-hover); }
.proy-cal-fila.abierta { background: rgba(var(--acento-rgb), 0.06); box-shadow: inset 3px 0 0 var(--accent); }
.proy-cal-etq { display: flex; align-items: center; gap: 7px; padding-right: 12px; }
.proy-cal-etq-nom { font-size: 12.5px; font-weight: 620; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.proy-cal-etq-est {
  margin-left: auto; flex-shrink: 0;
  font-size: 9px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--text-xsoft);
}
.proy-cal-pista { position: relative; flex: 1; height: 38px; }
.proy-cal-hoy {
  position: absolute; top: 0; bottom: 0; width: 0;
  border-left: 1.5px dashed rgba(var(--acento-rgb), 0.6);
  pointer-events: none; z-index: 1;
}
.proy-cal-barra-p {
  position: absolute; top: 8px; bottom: 8px;
  border: none; border-radius: 0;
  display: flex; align-items: center;
  padding: 0 8px; overflow: hidden;
  cursor: pointer; z-index: 2;
  box-shadow: inset 0 -1px 0 rgba(0,0,0,0.14);
  transition: filter var(--transition), box-shadow var(--transition);
}
.proy-cal-barra-p:hover { filter: brightness(1.08); box-shadow: var(--shadow-sm); }
/* Un proyecto que empieza o acaba fuera del rango se marca con el borde recto
   y una muesca, para que se vea que continúa */
.proy-cal-barra-p.corta-izq { border-radius: 0 4px 4px 0; border-left: 3px dotted rgba(255,255,255,0.75); }
.proy-cal-barra-p.corta-der { border-radius: 0 0 0 4px; border-right: 3px dotted rgba(255,255,255,0.75); }
.proy-cal-barra-p.corta-izq.corta-der { border-radius: 0; }
.proy-cal-barra-p.fin { opacity: 0.62; }
.proy-cal-barra-txt {
  position: sticky; left: 0;
  font-size: 10.5px; font-weight: 650; color: #fff;
  white-space: nowrap;
  text-shadow: 0 1px 2px rgba(0,0,0,0.28);
}
.proy-cal-pie { padding-top: 10px; font-size: 11.5px; color: var(--text-xsoft); }
.proy-cal-vacio {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 46px 20px; color: var(--text-soft); font-size: 13px;
}
.proy-cal-nota { font-size: 11.5px; color: var(--text-xsoft); }

/* El desglose por departamento suma bases de línea, mientras que el total del
   presupuesto incluye IVA y descuento global: sin aclararlo, los números
   parecen no cuadrar. */
.drawer-dep-tit {
  display: flex; align-items: baseline; gap: 8px;
}
.drawer-dep-nota {
  letter-spacing: 0; text-transform: none;
  font-size: 10px; font-weight: 500; color: var(--text-xsoft);
}

/* ═══════════════════════════════════════════════════════════════════════════
   PRÓXIMAS DEVOLUCIONES — desplegable por proyecto
   El material sale de los presupuestos sin contabilizar. Cada proyecto es un
   desplegable y su lista de material tiene alto máximo con scroll: un
   presupuesto de 200 líneas no debe estirar el dashboard.
   ═══════════════════════════════════════════════════════════════════════════ */
.agenda-widget { display: flex; flex-direction: column; gap: 6px; }

.agenda-grupo {
  border: 1px solid var(--border);
  border-radius: var(--radius-xs);
  background: var(--surface-2);
  overflow: hidden;
  transition: border-color var(--transition);
}
.agenda-grupo:hover { border-color: var(--border-med); }
.agenda-grupo.abierto { border-color: var(--accent); background: var(--surface); }
/* La urgencia se marca en el borde izquierdo, no tiñendo todo */
.agenda-grupo.urgente { box-shadow: inset 3px 0 0 var(--orange); }
.agenda-grupo.vencido { box-shadow: inset 3px 0 0 var(--red); }

.agenda-cab {
  display: flex; align-items: center; gap: 10px;
  width: 100%; font: inherit; text-align: left; cursor: pointer;
  background: none; border: none;
  padding: 9px 11px;
  transition: background var(--transition);
}
.agenda-cab:hover { background: var(--bg-hover); }

.agenda-fecha {
  flex-shrink: 0; width: 34px; text-align: center;
  font-variant-numeric: tabular-nums;
}
.agenda-fecha-dia { display: block; font-size: 17px; font-weight: 700; line-height: 1.05; color: var(--text); }
.agenda-fecha-mes { display: block; font-size: 9.5px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-soft); }
.agenda-grupo.vencido .agenda-fecha-dia { color: var(--red); }
.agenda-grupo.urgente .agenda-fecha-dia { color: var(--orange-dark); }

.agenda-cab-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.agenda-proy {
  display: flex; align-items: center; gap: 6px;
  font-size: 12.5px; font-weight: 650; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.agenda-punto { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.agenda-sub {
  font-size: 10.5px; color: var(--text-soft);
  font-variant-numeric: tabular-nums;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.agenda-chips { display: flex; gap: 4px; flex-wrap: wrap; margin-top: 2px; }
.agenda-chips .agenda-dep {
  display: inline-flex; align-items: center; gap: 4px;
  text-transform: none; letter-spacing: 0;
  font-size: 9.5px; font-weight: 600;
  background: var(--surface-sunk); color: var(--text-soft);
  border-radius: var(--radius-pill); padding: 0 6px;
}
.agenda-chips .agenda-dep b { font-weight: 800; color: var(--text-2); }

.agenda-cab-der { display: flex; align-items: center; gap: 7px; flex-shrink: 0; }
.agenda-dias {
  font-size: 10px; font-weight: 700; letter-spacing: 0.03em;
  color: var(--text-soft); white-space: nowrap;
}
.agenda-grupo.vencido .agenda-dias { color: var(--red); }
.agenda-grupo.urgente .agenda-dias { color: var(--orange-dark); }
.agenda-chevron { color: var(--text-xsoft); transition: transform 0.2s cubic-bezier(0.34,1.2,0.64,1), color var(--transition); }
.agenda-cab:hover .agenda-chevron { color: var(--accent); }
.agenda-grupo.abierto .agenda-chevron { transform: rotate(180deg); color: var(--accent); }

/* Lista de material: tope de altura con scroll propio */
.agenda-material {
  max-height: 232px;
  overflow-y: auto;
  overscroll-behavior: contain;
  border-top: 1px solid var(--border);
  padding: 4px 11px;
  scrollbar-width: thin;
}
.agenda-material::-webkit-scrollbar { width: 8px; }
.agenda-material::-webkit-scrollbar-thumb {
  background: rgba(43,45,66,0.20); border-radius: var(--radius-pill);
  border: 2px solid transparent; background-clip: content-box;
}
.agenda-mat {
  display: flex; align-items: center; gap: 8px;
  padding: 5px 0; border-bottom: 1px solid var(--border);
  font-size: 11.5px;
}
.agenda-mat:last-child { border-bottom: none; }
.agenda-mat-cant {
  flex-shrink: 0; min-width: 38px;
  font-weight: 700; color: var(--text-2);
  font-variant-numeric: tabular-nums;
}
.agenda-mat-cant i { font-style: normal; font-weight: 500; font-size: 10px; color: var(--text-soft); }
.agenda-mat-desc { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.agenda-mat-dep {
  flex-shrink: 0; font-size: 9.5px; font-weight: 650;
  background: var(--surface-sunk); color: var(--text-soft);
  border-radius: var(--radius-pill); padding: 0 6px;
}
.agenda-mat-eur {
  flex-shrink: 0; min-width: 62px; text-align: right;
  font-weight: 700; font-variant-numeric: tabular-nums;
}
.agenda-pie { padding: 7px 11px 9px; border-top: 1px solid var(--border); }

.agenda-empty { padding: 26px 14px; text-align: center; color: var(--text-soft); font-size: 12.5px; line-height: 1.6; }
.agenda-empty-nota { font-size: 11px; color: var(--text-xsoft); }

/* ═══════════════════════════════════════════════════════════════════════════
   DASHBOARD DE PROYECTOS — bajar el ruido visual
   Había 15 colores distintos en una banda de 226px: cuatro degradados de
   métrica + cuatro colores de proyecto + los badges de estado. El problema no
   era la cantidad de información, era que el color no significaba nada (¿por
   qué "Finalizados" en rojo?).
   Criterio: el color se reserva para lo que IDENTIFICA (el proyecto) o avisa
   (una métrica que requiere atención). Las métricas neutras van en gris.
   ═══════════════════════════════════════════════════════════════════════════ */

.proy-dash-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 13px 15px 12px;
  box-shadow: var(--shadow-xs);
  transition: border-color var(--transition), box-shadow var(--transition);
}
.proy-dash-card:hover { border-color: var(--border-med); box-shadow: var(--shadow-sm); }

/* Fuera los cuatro degradados; queda una línea gris fina y discreta */
.proy-dash-card .proy-dash-accent,
.proy-dash-card.green .proy-dash-accent,
.proy-dash-card.yellow .proy-dash-accent,
.proy-dash-card.blue .proy-dash-accent,
.proy-dash-card.purple .proy-dash-accent {
  background: var(--border-med);
  height: 1px;
}

/* Las cifras, todas del mismo color: la que informa es la cifra, no el tono */
.proy-dash-card .proy-dash-val,
.proy-dash-card.green .proy-dash-val,
.proy-dash-card.yellow .proy-dash-val,
.proy-dash-card.blue .proy-dash-val,
.proy-dash-card.purple .proy-dash-val {
  color: var(--text);
  font-size: 27px;
  font-weight: 700;
  letter-spacing: -0.035em;
}
.proy-dash-icon { color: var(--text-xsoft); opacity: 1; margin-bottom: 4px; }
.proy-dash-label {
  font-size: 10px; font-weight: 700; letter-spacing: 0.09em;
  color: var(--text-soft);
}

/* Única excepción: si "Activos" tiene valor, se marca con el acento. Es el dato
   sobre el que se actúa; el resto son consulta. */
.proy-dash-card.destacada .proy-dash-accent { background: var(--accent); height: 2px; }
.proy-dash-card.destacada .proy-dash-val { color: var(--accent); }
.proy-dash-card.destacada .proy-dash-icon { color: var(--accent); }

/* ── Últimos proyectos: el color del proyecto pasa a punto ───────────────── */
.proy-mini {
  border-radius: var(--radius-sm);
  background: var(--surface);
}
/* La banda vertical de 4px competía con las métricas; un punto identifica
   igual de bien y pesa mucho menos. */
.proy-mini-color {
  width: 8px; height: 8px;
  border-radius: 50%;
  margin: 11px 0 0 11px;
  align-self: flex-start;
}
.proy-mini-cuerpo { padding: 9px 11px 10px 7px; }
.proy-mini-nombre { font-size: 12.5px; }
.proy-mini-meta { color: var(--text-xsoft); }
/* Badges de estado en gris salvo el activo, que sí es información de estado */
.proy-mini-badge,
.proy-mini-badge.est-finalizado {
  background: var(--surface-sunk);
  color: var(--text-soft);
}
.proy-mini-badge.est-activo {
  background: rgba(var(--acento-rgb), 0.10);
  color: var(--accent);
}
.proy-mini-badge.est-pendiente { background: var(--surface-sunk); color: var(--text-2); }

.proy-recientes-titulo { color: var(--text-xsoft); }
.proy-recientes { margin: 12px 0 14px; }

/* ═══════════════════════════════════════════════════════════════════════════
   ENVÍO DE PRESUPUESTOS — selección de destinatarios
   ═══════════════════════════════════════════════════════════════════════════ */
.enviar-aviso {
  padding: 10px 12px; margin-bottom: 14px;
  border-radius: var(--radius-xs);
  font-size: 12px; line-height: 1.5;
}
/* El aviso de "no configurado" tiene que verse: si no, alguien creerá que ha
   mandado un correo que no ha salido. */
.enviar-aviso.pendiente {
  background: rgba(255,149,0,0.09);
  border: 1px solid rgba(255,149,0,0.32);
  color: var(--text-2);
}
.enviar-aviso.ok {
  background: rgba(52,199,89,0.09);
  border: 1px solid rgba(52,199,89,0.30);
  color: var(--text-2);
}
.enviar-n { font-weight: 700; color: var(--accent); }

.enviar-sugeridos { margin-bottom: 9px; }
.enviar-sug-tit {
  font-size: 10px; font-weight: 700; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--text-xsoft);
  margin-bottom: 5px;
}
.enviar-sug {
  display: flex; align-items: center; gap: 9px;
  width: 100%; font: inherit; text-align: left; cursor: pointer;
  padding: 6px 9px; margin-bottom: 3px;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius-xs);
  transition: border-color var(--transition), background var(--transition);
}
.enviar-sug:hover { border-color: var(--accent); background: var(--bg-hover); }
.enviar-sug-nom { font-size: 12.5px; font-weight: 620; flex-shrink: 0; }
.enviar-sug-mail { font-size: 11.5px; color: var(--text-soft); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.enviar-sug-fuente {
  font-size: 9.5px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
  background: var(--surface-sunk); color: var(--text-soft);
  border-radius: var(--radius-pill); padding: 1px 7px; flex-shrink: 0;
}
.enviar-sug-mas { font-size: 15px; color: var(--accent); font-weight: 400; flex-shrink: 0; }
.enviar-sin-sug {
  font-size: 12px; color: var(--text-soft); line-height: 1.5;
  padding: 9px 11px; background: var(--surface-sunk); border-radius: var(--radius-xs);
}

.enviar-elegidos { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 9px; min-height: 30px; }
.enviar-pastilla {
  display: inline-flex; align-items: center; gap: 6px;
  background: rgba(var(--acento-rgb), 0.09);
  border: 1px solid rgba(var(--acento-rgb), 0.30);
  border-radius: var(--radius-pill);
  padding: 3px 5px 3px 10px;
  font-size: 12px; font-weight: 620; color: var(--text);
}
.enviar-pastilla i { font-style: normal; font-size: 11px; font-weight: 500; color: var(--text-soft); }
.enviar-pastilla button {
  display: inline-flex; align-items: center; justify-content: center;
  width: 17px; height: 17px; flex-shrink: 0;
  background: rgba(var(--acento-rgb), 0.14); border: none;
  border-radius: 50%; color: var(--accent); cursor: pointer;
  transition: background var(--transition);
}
.enviar-pastilla button:hover { background: var(--accent); color: #fff; }
.enviar-vacio { font-size: 12px; color: var(--text-xsoft); padding: 6px 2px; }

.enviar-manual { display: grid; grid-template-columns: 1fr 1.3fr auto; gap: 6px; }
.enviar-manual .form-control { font-size: 12.5px; padding: 6px 9px; }

/* ── Calendario de proyectos: vista de 1 mes con días ─────────────────────── */
.proy-cal-cabecera-dias { border-bottom: 1px solid var(--border); }
.proy-cal-dias { flex: 1; display: flex; }
.proy-cal-dia {
  flex: 1 0 0; min-width: 0;
  text-align: center; padding: 3px 0 4px;
  border-left: 1px solid var(--border);
  font-variant-numeric: tabular-nums;
}
.proy-cal-dia-n { display: block; font-size: 10px; font-weight: 700; color: var(--text-2); }
.proy-cal-dia-s { display: block; font-size: 8px; font-weight: 600; color: var(--text-xsoft); text-transform: uppercase; }
.proy-cal-dia.finde { background: rgba(43,45,66,0.035); }
.proy-cal-dia.finde .proy-cal-dia-n { color: var(--text-xsoft); }
.proy-cal-dia.hoy { background: rgba(var(--acento-rgb), 0.10); }
.proy-cal-dia.hoy .proy-cal-dia-n,
.proy-cal-dia.hoy .proy-cal-dia-s { color: var(--accent); }

/* Rejilla diaria de fondo en las pistas, para poder contar días de un vistazo.
   Se dibuja con un degradado repetido en vez de 31 divs por fila. */
.proy-cal-filas.con-dias .proy-cal-pista {
  background-image: repeating-linear-gradient(90deg,
    var(--border) 0 1px,
    transparent 1px calc(100% / var(--cal-dias, 31)));
  background-size: calc(100% / var(--cal-dias, 31)) 100%;
}

/* ═══════════════════════════════════════════════════════════════════════════
   CAJÓN DE PROYECTO — pestañas y creador de presupuestos
   ═══════════════════════════════════════════════════════════════════════════ */
.drawer-tabs {
  display: flex; gap: 2px;
  margin: 12px -18px -14px;
  padding: 0 18px;
  border-top: 1px solid var(--border);
}
.drawer-tab {
  font: inherit; font-size: 12px; font-weight: 650;
  background: none; border: none;
  border-bottom: 2px solid transparent;
  padding: 9px 12px; margin-bottom: -1px;
  color: var(--text-soft); cursor: pointer;
  transition: color var(--transition), border-color var(--transition), background var(--transition);
}
.drawer-tab:hover { color: var(--text); background: var(--bg-hover); }
.drawer-tab.active { color: var(--accent); border-bottom-color: var(--accent); }

.drawer-pres-acciones { display: flex; gap: 6px; padding: 14px 0 4px; }

/* ── Panel de nuevo presupuesto ──────────────────────────────────────────── */
.np-panel {
  margin: 10px 0 6px;
  border: 1px solid var(--accent);
  border-radius: var(--radius-sm);
  background: var(--surface);
  box-shadow: 0 0 0 3px rgba(var(--acento-rgb), 0.08);
  overflow: hidden;
}
.np-cab {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 12px;
  background: rgba(var(--acento-rgb), 0.06);
  border-bottom: 1px solid var(--border);
}
.np-cab-tit { flex: 1; font-size: 12px; font-weight: 700; color: var(--text); }
.np-cerrar {
  background: none; border: none; cursor: pointer; color: var(--text-soft);
  padding: 3px; border-radius: var(--radius-xs);
  transition: background var(--transition), color var(--transition);
}
.np-cerrar:hover { background: var(--surface-sunk); color: var(--red); }

.np-datos { display: grid; grid-template-columns: 1fr 130px 78px; gap: 7px; padding: 11px 12px 9px; }
.np-campo { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.np-campo > span { font-size: 9.5px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase; color: var(--text-xsoft); }
.np-campo .form-control { font-size: 12.5px; padding: 5px 8px; }

/* Selector de departamento: el número en negrita son las líneas ya añadidas de
   ese departamento; en cursiva y claro, cuántas hay disponibles. */
.np-deps { display: flex; flex-wrap: wrap; gap: 4px; padding: 0 12px 9px; }
.np-dep {
  display: inline-flex; align-items: center; gap: 5px;
  font: inherit; font-size: 11px; font-weight: 650;
  background: var(--surface-2); border: 1px solid var(--border-med);
  border-radius: var(--radius-pill); padding: 3px 10px;
  color: var(--text-2); cursor: pointer;
  transition: border-color var(--transition), background var(--transition), color var(--transition);
}
.np-dep:hover { border-color: var(--border-strong); background: var(--surface); }
.np-dep.activo { background: var(--accent); border-color: var(--accent); color: #fff; }
.np-dep b { font-weight: 800; font-variant-numeric: tabular-nums; }
.np-dep i {
  font-style: normal; font-weight: 500; font-size: 10px;
  color: var(--text-xsoft); font-variant-numeric: tabular-nums;
}
.np-dep.activo b, .np-dep.activo i { color: #fff; }

.np-busca { margin: 0 12px 8px; width: calc(100% - 24px); font-size: 12.5px; padding: 6px 9px; }

/* Catálogo con tope de altura: es para picar rápido, no para leerlo entero */
.np-catalogo {
  max-height: 176px; overflow-y: auto; overscroll-behavior: contain;
  margin: 0 12px; border: 1px solid var(--border); border-radius: var(--radius-xs);
  scrollbar-width: thin;
}
.np-item {
  display: flex; align-items: center; gap: 8px;
  width: 100%; font: inherit; text-align: left; cursor: pointer;
  padding: 5px 9px; background: none; border: none;
  border-bottom: 1px solid var(--border);
  font-size: 11.5px;
  transition: background var(--transition);
}
.np-item:last-child { border-bottom: none; }
.np-item:hover:not(:disabled) { background: var(--bg-hover); }
.np-item:disabled { opacity: 0.45; cursor: default; }
.np-item-cod { width: 48px; flex-shrink: 0; font-weight: 650; color: var(--text-soft); font-variant-numeric: tabular-nums; }
.np-item-nom { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.np-item-eur { flex-shrink: 0; font-weight: 650; font-variant-numeric: tabular-nums; }
.np-item-mas { width: 14px; text-align: center; flex-shrink: 0; color: var(--accent); font-weight: 700; }

.np-lineas-tit {
  display: flex; align-items: center; gap: 7px;
  padding: 12px 12px 6px;
  font-size: 9.5px; font-weight: 800; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--text-soft);
}
.np-lineas-tit span {
  letter-spacing: 0; background: var(--surface-sunk); color: var(--text-soft);
  border-radius: var(--radius-pill); padding: 0 6px; font-size: 10px;
}
.np-lineas { padding: 0 12px; max-height: 210px; overflow-y: auto; overscroll-behavior: contain; }
.np-linea {
  display: grid;
  grid-template-columns: 62px 1fr 52px 66px 72px 22px;
  gap: 6px; align-items: center;
  padding: 4px 0; border-bottom: 1px solid var(--border);
  font-size: 11.5px;
}
.np-linea:last-child { border-bottom: none; }
.np-linea-dep {
  font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em;
  background: var(--surface-sunk); color: var(--text-soft);
  border-radius: var(--radius-pill); padding: 1px 5px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.np-linea-desc { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.np-linea-cant, .np-linea-precio {
  font: inherit; font-size: 11.5px;
  border: 1px solid var(--border-med); border-radius: 0;
  padding: 3px 5px; text-align: right;
  font-variant-numeric: tabular-nums;
  background: var(--surface);
}
.np-linea-cant:focus, .np-linea-precio:focus { border-color: var(--accent); outline: none; }
.np-linea-eur { text-align: right; font-weight: 700; font-variant-numeric: tabular-nums; }
.np-linea-quitar {
  background: none; border: none; cursor: pointer; color: var(--text-xsoft);
  padding: 2px; border-radius: 0;
  transition: color var(--transition), background var(--transition);
}
.np-linea-quitar:hover { color: var(--red); background: rgba(239,35,60,0.09); }

.np-pie {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; flex-wrap: wrap;
  padding: 10px 12px 11px; margin-top: 8px;
  background: var(--surface-2); border-top: 1px solid var(--border);
}
.np-totales { display: flex; gap: 12px; font-size: 11px; color: var(--text-soft); font-variant-numeric: tabular-nums; }
.np-totales b { color: var(--text); font-weight: 700; font-size: 12px; }
.np-total b { color: var(--accent); font-size: 13.5px; }
.np-botones { display: flex; gap: 6px; margin-left: auto; }
.np-vacio { padding: 14px 12px; font-size: 11.5px; color: var(--text-xsoft); text-align: center; }

/* ═══════════════════════════════════════════════════════════════════════════
   PROYECTOS — ficha a pantalla casi completa
   Con la ficha abierta la lista de proyectos se convierte en un carril estrecho
   pegado a la barra lateral de siempre, y la ficha se queda con el resto. Antes
   la ficha eran 520px y la tabla seguía ocupando la mitad, que es justo lo que
   hacía incómodo trabajar dentro del proyecto.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Por defecto (sin ficha) el carril no existe y manda la tabla */
.proy-rail { display: none; }

.proy-layout.con-drawer {
  gap: 0;
  /* La ficha necesita todo el alto disponible */
  align-items: stretch;
  min-height: calc(100vh - 48px);
}
/* La lista pasa a carril: se oculta todo menos la lista compacta */
.proy-layout.con-drawer .proy-main {
  flex: 0 0 232px;
  width: 232px;
  padding-right: 0;
  border-right: 1px solid var(--border-med);
  background: var(--surface-2);
  margin-right: 16px;
}
.proy-layout.con-drawer .proy-main > .page-header,
.proy-layout.con-drawer .proy-main > .proy-tabs,
.proy-layout.con-drawer .proy-main > #proy-dashboard,
.proy-layout.con-drawer .proy-main > #proy-filtros,
.proy-layout.con-drawer .proy-main > #proy-vista-tabla,
.proy-layout.con-drawer .proy-main > #proy-vista-calendario { display: none !important; }
.proy-layout.con-drawer .proy-rail { display: flex; flex-direction: column; }

/* La ficha se come el resto del ancho */
.proy-layout.con-drawer .proy-drawer { flex: 1 1 auto; width: auto; min-width: 0; }
.proy-drawer-inner { width: 100%; }
.proy-layout.con-drawer .proy-drawer-inner {
  max-height: calc(100vh - 44px);
  border-radius: var(--radius-lg);
}

/* ── Carril de proyectos ─────────────────────────────────────────────────── */
.proy-rail-cab { padding: 10px 10px 8px; border-bottom: 1px solid var(--border); }
.proy-rail-busca {
  width: 100%; font: inherit; font-size: 12px;
  background: var(--surface); border: 1px solid var(--border-med);
  border-radius: var(--radius-xs); padding: 5px 9px;
  color: var(--text);
}
.proy-rail-busca:focus { border-color: var(--accent); outline: none; box-shadow: var(--ring); }
.proy-rail-lista {
  flex: 1; overflow-y: auto; overscroll-behavior: contain;
  padding: 6px; scrollbar-width: thin;
}
.proy-rail-item {
  display: flex; align-items: center; gap: 8px;
  width: 100%; font: inherit; text-align: left; cursor: pointer;
  background: none; border: 1px solid transparent;
  border-radius: var(--radius-xs);
  padding: 7px 9px; margin-bottom: 2px;
  transition: background var(--transition), border-color var(--transition);
}
.proy-rail-item:hover { background: var(--surface); border-color: var(--border); }
.proy-rail-item.activo {
  background: var(--surface);
  border-color: var(--accent);
  box-shadow: inset 3px 0 0 var(--accent);
}
.proy-rail-punto { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.proy-rail-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.proy-rail-nom {
  font-size: 12.5px; font-weight: 650; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.proy-rail-meta {
  font-size: 10px; color: var(--text-xsoft);
  font-variant-numeric: tabular-nums;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.proy-rail-n {
  flex-shrink: 0; font-size: 9.5px; font-weight: 700;
  background: var(--surface-sunk); color: var(--text-soft);
  border-radius: var(--radius-pill); padding: 0 5px;
}
.proy-rail-vacio { padding: 20px 10px; text-align: center; font-size: 11.5px; color: var(--text-xsoft); }

/* Con la ficha grande, los datos y la flota pueden ir a más columnas */
.proy-layout.con-drawer .drawer-datos { grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); }
.proy-layout.con-drawer .drawer-contactos { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 7px; }
.proy-layout.con-drawer .drawer-flota { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 5px; }
.proy-layout.con-drawer .drawer-cuerpo { padding-left: 22px; padding-right: 22px; }
.proy-layout.con-drawer .drawer-head { padding-left: 22px; padding-right: 22px; }
.proy-layout.con-drawer .drawer-tabs { margin-left: -22px; margin-right: -22px; padding: 0 22px; }

/* En pantallas estrechas el carril estorba: se oculta y la ficha ocupa todo */
@media (max-width: 1100px) {
  .proy-layout.con-drawer .proy-main { display: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   CREADOR DE PRESUPUESTO — dos columnas: árbol de categorías + catálogo
   Con una sola barra de búsqueda era muy incómodo montar un presupuesto: hay
   que poder recorrer el inventario por categorías, no adivinar nombres.
   ═══════════════════════════════════════════════════════════════════════════ */
.np-grande { margin: 12px 0 8px; }

.np-grande .np-cab { gap: 10px; flex-wrap: wrap; }
.np-cab-datos { display: flex; gap: 6px; margin-left: auto; }
.np-cab-datos .form-control { font-size: 12px; padding: 5px 8px; width: 150px; }
.np-cab-datos .np-iva { width: 62px; text-align: right; }

.np-cuerpo {
  display: grid;
  grid-template-columns: 248px minmax(0, 1fr);
  min-height: 430px;
}

/* ── Árbol de categorías ─────────────────────────────────────────────────── */
.np-arbol {
  border-right: 1px solid var(--border);
  background: var(--surface-2);
  display: flex; flex-direction: column;
  min-height: 0;
}
.np-arbol-tit {
  padding: 8px 11px 6px;
  font-size: 9.5px; font-weight: 800; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--text-xsoft);
  border-bottom: 1px solid var(--border);
}
.np-arbol-lista {
  flex: 1; overflow-y: auto; overscroll-behavior: contain;
  padding: 5px 6px 10px;
  max-height: 430px;
  scrollbar-width: thin;
}
.np-nodo {
  display: flex; align-items: center; gap: 2px;
  /* La sangría marca el nivel; sin ella el árbol no se lee */
  padding-left: calc(var(--niv, 0) * 13px);
  border-radius: var(--radius-xs);
  transition: background var(--transition);
}
.np-nodo:hover { background: var(--surface); }
.np-nodo.sel { background: rgba(var(--acento-rgb), 0.10); }
.np-nodo-chev {
  display: inline-flex; align-items: center; justify-content: center;
  width: 17px; height: 20px; flex-shrink: 0;
  background: none; border: none; cursor: pointer;
  color: var(--text-xsoft);
  transition: transform 0.16s cubic-bezier(0.34,1.2,0.64,1), color var(--transition);
}
.np-nodo-chev.vacio { cursor: default; }
.np-nodo-chev:hover { color: var(--accent); }
.np-nodo-chev.abierto { transform: rotate(90deg); color: var(--text-soft); }
.np-nodo-btn {
  display: flex; align-items: center; gap: 6px;
  flex: 1; min-width: 0;
  font: inherit; text-align: left; cursor: pointer;
  background: none; border: none; padding: 3px 4px;
}
.np-nodo-nom {
  flex: 1; min-width: 0;
  font-size: 11.5px; font-weight: 550; color: var(--text-2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.np-nodo.sel .np-nodo-nom { color: var(--accent); font-weight: 700; }
.np-nodo-n {
  flex-shrink: 0;
  font-size: 9.5px; font-weight: 700;
  background: var(--surface-sunk); color: var(--text-soft);
  border-radius: var(--radius-pill); padding: 0 5px;
  font-variant-numeric: tabular-nums;
}
.np-nodo.sel .np-nodo-n { background: rgba(var(--acento-rgb), 0.16); color: var(--accent); }

/* ── Columna derecha ─────────────────────────────────────────────────────── */
.np-derecha { display: flex; flex-direction: column; min-width: 0; min-height: 0; }
.np-barra {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 11px; border-bottom: 1px solid var(--border);
}
.np-grande .np-busca { margin: 0; width: auto; flex: 1; }
.np-barra-info {
  flex-shrink: 0; font-size: 10.5px; color: var(--text-xsoft);
  font-variant-numeric: tabular-nums;
}

.np-grande .np-catalogo {
  margin: 0; border: none; border-bottom: 1px solid var(--border-med);
  max-height: 232px; border-radius: 0;
}
/* Cabecera de columnas, pegada al desplazar */
.np-cat-cab {
  position: sticky; top: 0; z-index: 2;
  display: grid; grid-template-columns: 58px minmax(0,1fr) 110px 44px 78px 22px;
  gap: 8px; padding: 5px 10px;
  background: var(--surface-2);
  border-bottom: 1px solid var(--border-med);
  font-size: 9px; font-weight: 800; letter-spacing: 0.07em;
  text-transform: uppercase; color: var(--text-xsoft);
}
.np-cat-cab span:nth-child(4), .np-cat-cab span:nth-child(5) { text-align: right; }
.np-grande .np-item {
  display: grid; grid-template-columns: 58px minmax(0,1fr) 110px 44px 78px 22px;
  gap: 8px; padding: 5px 10px;
}
.np-item-cat {
  font-size: 9.5px; font-weight: 650;
  background: var(--surface-sunk); color: var(--text-soft);
  border-radius: var(--radius-pill); padding: 0 6px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  justify-self: start; align-self: center; max-width: 100%;
}
.np-item-uds { text-align: right; color: var(--text-soft); font-variant-numeric: tabular-nums; }
.np-grande .np-item-eur { text-align: right; }

.np-lineas-zona { flex: 1; display: flex; flex-direction: column; min-height: 0; }
.np-grande .np-lineas { max-height: 190px; padding: 0 11px; }
.np-grande .np-lineas-tit { padding: 9px 11px 6px; }
.np-lineas-deps { display: flex; gap: 5px; margin-left: auto; letter-spacing: 0; }
.np-lineas-deps i {
  font-style: normal; font-size: 9.5px; font-weight: 650;
  background: var(--surface-sunk); color: var(--text-soft);
  border-radius: var(--radius-pill); padding: 0 6px;
}

/* En ficha estrecha el árbol se pliega arriba en vez de partir la pantalla */
@media (max-width: 1100px) {
  .np-cuerpo { grid-template-columns: 1fr; }
  .np-arbol { border-right: none; border-bottom: 1px solid var(--border); }
  .np-arbol-lista { max-height: 168px; }
  .np-cat-cab, .np-grande .np-item { grid-template-columns: 52px minmax(0,1fr) 60px 22px; }
  .np-item-cat, .np-item-uds { display: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   PRESUPUESTOS — constructor en panel lateral, sin cambiar de pantalla
   Antes editar un presupuesto ocultaba la lista entera. Ahora la lista pasa a
   carril y el constructor ocupa el resto, igual que la ficha de proyecto.
   ═══════════════════════════════════════════════════════════════════════════ */
.pres-layout { display: block; }
.pres-rail { display: none; }

.pres-layout.con-panel {
  display: flex;
  align-items: stretch;
  gap: 0;
  min-height: calc(100vh - 48px);
}
.pres-layout.con-panel .pres-rail {
  display: flex; flex-direction: column;
  flex: 0 0 240px; width: 240px;
  border-right: 1px solid var(--border-med);
  background: var(--surface-2);
  margin-right: 16px;
}
.pres-layout.con-panel #pres-builder-view {
  flex: 1 1 auto; min-width: 0;
}

.pres-rail-cab {
  display: flex; gap: 6px; align-items: center;
  padding: 10px; border-bottom: 1px solid var(--border);
}
.pres-rail-busca {
  flex: 1; min-width: 0;
  font: inherit; font-size: 12px;
  background: var(--surface); border: 1px solid var(--border-med);
  border-radius: var(--radius-xs); padding: 5px 8px; color: var(--text);
}
.pres-rail-busca:focus { border-color: var(--accent); outline: none; box-shadow: var(--ring); }
.pres-rail-lista { flex: 1; overflow-y: auto; overscroll-behavior: contain; padding: 6px; scrollbar-width: thin; }
.pres-rail-item {
  display: flex; align-items: center; gap: 7px;
  width: 100%; font: inherit; text-align: left; cursor: pointer;
  background: none; border: 1px solid transparent;
  border-radius: var(--radius-xs); padding: 6px 8px; margin-bottom: 2px;
  transition: background var(--transition), border-color var(--transition);
}
.pres-rail-item:hover { background: var(--surface); border-color: var(--border); }
.pres-rail-item.activo {
  background: var(--surface); border-color: var(--accent);
  box-shadow: inset 3px 0 0 var(--accent);
}
.pres-rail-num {
  flex-shrink: 0; font-size: 9.5px; font-weight: 700;
  color: var(--text-soft); font-variant-numeric: tabular-nums;
  writing-mode: horizontal-tb;
}
.pres-rail-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.pres-rail-cli {
  font-size: 12px; font-weight: 650; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pres-rail-meta {
  font-size: 10px; color: var(--text-xsoft);
  font-variant-numeric: tabular-nums;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pres-rail-est {
  flex-shrink: 0; font-size: 9px; font-weight: 800;
  text-transform: uppercase; letter-spacing: 0.04em;
  border-radius: var(--radius-pill); padding: 1px 5px;
  background: var(--surface-sunk); color: var(--text-soft);
}
.pres-rail-est.est-aceptado { background: rgba(52,199,89,0.14); color: var(--green-dark); }
.pres-rail-est.est-enviado  { background: rgba(var(--acento-rgb),0.12); color: var(--accent); }
.pres-rail-est.est-rechazado{ background: rgba(239,35,60,0.12); color: var(--red-dark); }

@media (max-width: 1100px) {
  .pres-layout.con-panel .pres-rail { display: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   BARRA LATERAL CON GRUPOS DESPLEGABLES
   Se sube el tamaño de las filas en vez de bajarlo: al añadir cabeceras de
   grupo la tentación es comprimir para que quepa todo, y queda apretado.
   Los grupos ocasionales vienen cerrados, así que hay sitio de sobra.
   ═══════════════════════════════════════════════════════════════════════════ */

.sidebar-nav { padding: 12px 8px 16px; gap: 3px; }

/* Filas más generosas que antes (era 8px/13.5px/15px). */
.nav-item {
  padding: 9.5px 11px;
  font-size: 13.8px;
  gap: 10px;
}
.nav-icon { width: 16px; height: 16px; }

.nav-fijos {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding-bottom: 10px;
  margin-bottom: 4px;
  border-bottom: 1px solid rgba(255,255,255,0.07);
}

/* ── Cabecera de grupo ───────────────────────────────────────────────────── */
.nav-group-head {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 9px 11px 9px 9px;
  margin: 0;
  background: none;
  border: 0;
  border-radius: var(--radius-sm);
  color: rgba(255,255,255,0.46);
  font-family: inherit;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.085em;
  text-align: left;
  cursor: pointer;
  transition: background var(--transition), color var(--transition);
}
.nav-group-head:hover {
  background: rgba(255,255,255,0.06);
  color: rgba(255,255,255,0.78);
}
.nav-group-head:focus-visible {
  outline: 2px solid rgba(239,35,60,0.6);
  outline-offset: -2px;
}
.nav-group-nombre { flex: 1; }

.nav-group-chevron {
  width: 12px; height: 12px;
  flex-shrink: 0;
  opacity: 0.65;
  transform: rotate(90deg);
  transition: transform 0.24s cubic-bezier(0.4, 0, 0.2, 1);
}
.nav-group.cerrado .nav-group-chevron { transform: rotate(0deg); }
.nav-group-head:hover .nav-group-chevron { opacity: 1; }

/* Punto rojo: cerrado, sigue diciendo en qué grupo estás. */
.nav-group-activo {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--red);
  flex-shrink: 0;
  opacity: 0;
  transform: scale(0.4);
  transition: opacity 0.2s, transform 0.2s;
}
.nav-group.cerrado.tiene-activo .nav-group-activo { opacity: 1; transform: scale(1); }
.nav-group.cerrado.tiene-activo .nav-group-head { color: rgba(255,255,255,0.72); }

/* ── Cuerpo del grupo ────────────────────────────────────────────────────── */
/* El padding/margin negativo de la izquierda deja que la marca roja del item
   activo (left:-8px) caiga dentro de la caja de relleno y no la recorte
   `overflow:hidden`. */
.nav-group-items {
  display: flex;
  flex-direction: column;
  gap: 3px;
  overflow: hidden;
  max-height: 400px;
  padding-left: 8px;
  margin-left: -8px;
  transition: max-height 0.26s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.2s;
}
.nav-group.cerrado .nav-group-items {
  max-height: 0;
  opacity: 0;
}
.nav-group + .nav-group { margin-top: 1px; }

/* ── Barra contraída a iconos ────────────────────────────────────────────── */
/* Sin etiquetas no se puede saber qué hay dentro de un grupo cerrado, así que
   los grupos dejan de existir: todos los iconos a la vista, separados por una
   línea. `overflow: visible` es imprescindible o se recortarían los tooltips. */
.sidebar.collapsed .nav-group-head { display: none; }
.sidebar.collapsed .nav-group-items {
  max-height: none;
  opacity: 1;
  overflow: visible;
  padding-left: 0;
  margin-left: 0;
}
.sidebar.collapsed .nav-fijos { padding-bottom: 8px; margin-bottom: 2px; }
.sidebar.collapsed .nav-group + .nav-group {
  border-top: 1px solid rgba(255,255,255,0.07);
  margin-top: 7px;
  padding-top: 7px;
}

/* ═══════════════════════════════════════════════════════════════════════════
   DASHBOARD PRINCIPAL — bajar el ruido visual
   Mismo tratamiento que ya se dio al dashboard de proyectos. Aquí había seis
   degradados distintos en la banda superior (azul, índigo, morado, verde,
   naranja, rojo) más seis iconos de seis colores, todos escritos a pelo en el
   JS saltándose los tokens. El color no señalaba nada: "Equipos en alquiler"
   iba en verde y "Vehículos fuera de servicio" en rojo, con el mismo peso.
   Criterio: gris por defecto, color solo cuando la cifra exige actuar.
   ═══════════════════════════════════════════════════════════════════════════ */

.stat-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-xs);
  cursor: pointer;
  transition: border-color var(--transition), box-shadow var(--transition),
              transform var(--transition);
}
.stat-card:hover {
  border-color: var(--border-med);
  box-shadow: var(--shadow-sm);
  transform: translateY(-1px);
}

/* Fuera los seis degradados: una línea gris de 1px */
.stat-card .stat-card-accent,
.stat-card.blue   .stat-card-accent,
.stat-card.green  .stat-card-accent,
.stat-card.orange .stat-card-accent,
.stat-card.red    .stat-card-accent,
.stat-card.indigo .stat-card-accent,
.stat-card.purple .stat-card-accent {
  background: var(--border-med);
  height: 1px;
}

.stat-card-icon { color: var(--text-xsoft); }
.stat-card-icon svg { stroke: currentColor; }

.stat-card .stat-value { color: var(--text); letter-spacing: -0.035em; }
.stat-card .stat-label {
  font-size: 10px; font-weight: 700; letter-spacing: 0.09em;
  color: var(--text-soft);
}

/* Única excepción: la tarjeta se enciende cuando su cifra > 0 y significa que
   algo está parado (material en mantenimiento, vehículo fuera de servicio).
   Con todo en orden la banda es completamente neutra. */
.stat-card.alerta .stat-card-accent { background: var(--accent); height: 2px; }
.stat-card.alerta .stat-value       { color: var(--accent); }
.stat-card.alerta .stat-card-icon   { color: var(--accent); }

/* ── Leyenda del Gantt: más discreta ────────────────────────────────────── */
.gantt-leg-dot { width: 7px; height: 7px; }
.gantt-leg-lbl {
  font-size: 10px; font-weight: 600; letter-spacing: 0.05em;
  color: var(--text-soft); text-transform: uppercase;
}

/* ═══════════════════════════════════════════════════════════════════════════
   BOTÓN DE PLEGAR / ABRIR LA BARRA LATERAL
   El icono es un panel en miniatura: marco + barra lateral rellena + flecha.
   Al plegar, la barra del glifo se estrecha igual que la de verdad y la flecha
   gira: el icono representa el estado, no hace falta leer el tooltip.

   Bug que se arregla aquí: `.logo-text` conservaba `flex: 1` al plegarse, así
   que aunque midiera 0 de ancho seguía CRECIENDO y empujaba el botón contra el
   borde derecho (centro en x=39 con la barra de 64px, cuando los iconos de
   navegación van centrados en x=32). Se veía torcido y pequeño.
   ═══════════════════════════════════════════════════════════════════════════ */

.sidebar-collapse-btn {
  width: 30px; height: 30px;
  border-radius: 0;
  border: 1px solid rgba(255,255,255,0.11);
  background: rgba(255,255,255,0.04);
  color: rgba(255,255,255,0.5);
  transition: background 0.18s ease, color 0.18s ease,
              border-color 0.18s ease, width 0.22s ease, height 0.22s ease;
}
.sidebar-collapse-btn:hover {
  background: rgba(255,255,255,0.10);
  border-color: rgba(255,255,255,0.2);
  color: #fff;
}
.sidebar-collapse-btn:active { background: rgba(255,255,255,0.16); }
.sidebar-collapse-btn:focus-visible {
  outline: 2px solid rgba(239,35,60,0.65);
  outline-offset: 2px;
}
.sidebar-collapse-btn svg.sb-tog { width: 17px; height: 17px; overflow: visible; }

.sb-tog-marco  { opacity: 0.55; transition: opacity 0.18s ease; }
.sb-tog-barra  {
  opacity: 0.9;
  transform-box: fill-box;
  transform-origin: left center;
  transition: transform 0.26s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.18s ease;
}
.sb-tog-flecha {
  transform-box: fill-box;
  transform-origin: center;
  transition: transform 0.26s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.18s ease;
}
.sidebar-collapse-btn:hover .sb-tog-marco { opacity: 0.8; }

/* Plegada: la barra del glifo se estrecha y la flecha apunta al otro lado. */
.sidebar.collapsed .sb-tog-barra  { transform: scaleX(0.46); }
.sidebar.collapsed .sb-tog-flecha { transform: rotate(180deg); }

/* La flecha se asoma al pasar el ratón, en la dirección en la que va a moverse. */
.sidebar-collapse-btn:hover .sb-tog-flecha { transform: translateX(-1.5px); }
.sidebar.collapsed .sidebar-collapse-btn:hover .sb-tog-flecha {
  transform: rotate(180deg) translateX(-1.5px);
}

/* ── Plegada: botón más grande y de verdad centrado ─────────────────────── */
/* `flex: 0 0 0` mata el flex-grow que descentraba el botón. */
.sidebar.collapsed .logo-text { flex: 0 0 0; }
.sidebar.collapsed .sidebar-collapse-btn {
  width: 36px; height: 36px;
  margin: 0 auto;
  background: rgba(255,255,255,0.07);
  border-color: rgba(255,255,255,0.14);
  color: rgba(255,255,255,0.72);
}
.sidebar.collapsed .sidebar-collapse-btn:hover {
  background: rgba(255,255,255,0.13);
  color: #fff;
}
.sidebar.collapsed .sidebar-collapse-btn svg.sb-tog { width: 19px; height: 19px; }
/* `width: 0` no basta: el borde de 1px a cada lado deja una caja de 2px que
   descentraba el botón 1px respecto a los iconos de navegación. */
.sidebar.collapsed .logo-mark { border: 0; }

/* ═══════════════════════════════════════════════════════════════════════════
   REVISIONES DE VEHÍCULOS
   La pantalla la usa un driver de pie en un parking, con una mano y con prisa.
   Todo lo tocable pasa de 48 px de alto (el mínimo cómodo con el pulgar) y el
   asistente ocupa la pantalla entera para que no haya nada más que tocar.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Las dos acciones ────────────────────────────────────────────────────── */
.rev-acciones {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 14px;
  margin-bottom: 6px;
}
.rev-accion {
  display: flex; align-items: center; gap: 16px;
  padding: 22px 22px;
  min-height: 96px;
  background: var(--surface);
  border: 1.5px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  transition: border-color var(--transition), box-shadow var(--transition),
              transform var(--transition);
}
.rev-accion:hover {
  border-color: var(--accent);
  box-shadow: var(--shadow);
  transform: translateY(-2px);
}
.rev-accion:active { transform: translateY(0); }
.rev-accion-ico {
  width: 52px; height: 52px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  border-radius: 0;
  background: rgba(var(--acento-rgb), 0.08);
  color: var(--accent);
}
.rev-accion-ico svg { width: 28px; height: 28px; }
.rev-accion-txt { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.rev-accion-txt strong { font-size: 16.5px; font-weight: 650; color: var(--text); }
.rev-accion-txt small  { font-size: 12.5px; color: var(--text-soft); }

/* ── Fuera ahora mismo ───────────────────────────────────────────────────── */
.rev-pend-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 12px;
}
.rev-pend {
  display: flex; flex-direction: column; gap: 8px;
  padding: 15px 16px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  cursor: pointer; text-align: left; font-family: inherit;
  transition: border-color var(--transition), box-shadow var(--transition);
}
.rev-pend:hover { box-shadow: var(--shadow-sm); border-color: var(--border-med); border-left-color: var(--accent); }
.rev-pend-cab { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.rev-pend-cab strong { font-size: 15.5px; font-weight: 650; }
.rev-pend-mat {
  font-size: 11px; font-weight: 600; letter-spacing: 0.04em;
  padding: 2px 7px; border-radius: var(--radius-xs);
  background: var(--bg); color: var(--text-soft);
  font-variant-numeric: tabular-nums;
}
.rev-pend-meta {
  display: flex; flex-wrap: wrap; gap: 4px 8px;
  font-size: 12px; color: var(--text-soft);
}
.rev-pend-proy { display: inline-flex; align-items: center; gap: 5px; }
.rev-pend-proy i { width: 7px; height: 7px; border-radius: 50%; }
.rev-pend-sinproy { color: var(--text-xsoft); }
.rev-pend-cta {
  margin-top: 2px; font-size: 12.5px; font-weight: 650; color: var(--accent);
}

.rev-vacio { padding: 34px 18px; text-align: center; }
.rev-vacio-tit { font-size: 15px; font-weight: 600; color: var(--text); margin-bottom: 5px; }
.rev-vacio-sub { font-size: 13px; color: var(--text-soft); line-height: 1.6; }

/* ── Historial (flota) ───────────────────────────────────────────────────── */
.rev-hist-cab { margin: 26px 0 12px; }
.rev-hist-filtros {
  display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1fr);
  gap: 8px; margin-top: 10px;
}
.rev-hist-lista {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); overflow: hidden;
}
.rev-hist-fila {
  display: grid;
  grid-template-columns: 76px minmax(0, 1.4fr) minmax(0, 1.2fr) minmax(0, 1fr) 62px 84px 110px 96px;
  align-items: center; gap: 10px;
  width: 100%; padding: 11px 14px;
  background: none; border: 0; border-bottom: 1px solid var(--border);
  font-family: inherit; font-size: 12.5px; text-align: left; cursor: pointer;
  transition: background var(--transition);
}
.rev-hist-fila:last-child { border-bottom: 0; }
.rev-hist-fila:hover { background: var(--bg); }
.rev-hist-fila.incompleta { box-shadow: inset 3px 0 0 var(--orange); }
.rev-hist-tipo {
  font-size: 10px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  padding: 3px 7px; border-radius: var(--radius-xs); text-align: center;
}
.rev-hist-tipo-salida  { background: rgba(43,45,66,0.08);  color: var(--text); }
.rev-hist-tipo-entrada { background: rgba(var(--acento-rgb),0.10); color: var(--accent); }
.rev-hist-veh { display: flex; flex-direction: column; }
.rev-hist-veh strong { font-size: 13px; font-weight: 620; }
.rev-hist-veh small  { font-size: 10.5px; color: var(--text-soft); font-variant-numeric: tabular-nums; }
.rev-hist-proy, .rev-hist-driver, .rev-hist-fecha { color: var(--text-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rev-hist-fotos, .rev-hist-km { font-variant-numeric: tabular-nums; color: var(--text-soft); }
.rev-hist-est {
  font-size: 10px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
  padding: 3px 7px; border-radius: var(--radius-xs); text-align: center;
}
.rev-hist-est.ok      { background: rgba(43,45,66,0.07); color: var(--text-soft); }
.rev-hist-est.falta   { background: rgba(141,153,174,0.18); color: #6b7589; }
.rev-hist-est.abierta { background: rgba(var(--acento-rgb),0.10); color: var(--accent); }

/* ═══ ASISTENTE A PANTALLA COMPLETA ═══════════════════════════════════════ */
.rev-wizard {
  position: fixed; inset: 0; z-index: 900;
  background: var(--bg);
  display: none; flex-direction: column;
}
.rev-wizard.abierto { display: flex; }
body.rev-wz-activo { overflow: hidden; }

.rev-wz-barra {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.rev-wz-atras, .rev-wz-cerrar {
  width: 40px; height: 40px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--bg); border: 1px solid var(--border);
  border-radius: var(--radius-sm); color: var(--text-soft);
  cursor: pointer; transition: background var(--transition), color var(--transition);
}
.rev-wz-atras:hover, .rev-wz-cerrar:hover { background: var(--border); color: var(--text); }
.rev-wz-atras svg, .rev-wz-cerrar svg { width: 17px; height: 17px; }
.rev-wz-tit { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.rev-wz-tit strong { font-size: 15.5px; font-weight: 650; }
.rev-wz-tit small  { font-size: 12px; color: var(--text-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.rev-wz-progreso { height: 3px; background: var(--border); flex-shrink: 0; }
.rev-wz-progreso-barra {
  height: 100%; background: var(--accent);
  transition: width 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.rev-wz-cuerpo {
  flex: 1; overflow-y: auto;
  padding: 20px 16px 24px;
  max-width: 860px; width: 100%; margin: 0 auto;
}
.rev-wz-pie {
  flex-shrink: 0; padding: 12px 16px;
  padding-bottom: max(12px, env(safe-area-inset-bottom));
  background: var(--surface); border-top: 1px solid var(--border);
}
.rev-wz-pie:empty { display: none; }

.rev-paso-tit { font-size: 20px; font-weight: 680; letter-spacing: -0.02em; margin-bottom: 5px; }
.rev-paso-sub { font-size: 13.5px; color: var(--text-soft); line-height: 1.55; margin-bottom: 18px; }

.rev-btn-grande {
  width: 100%; min-height: 54px;
  background: var(--accent); color: #fff;
  border: 0; border-radius: var(--radius);
  font-family: inherit; font-size: 16px; font-weight: 650;
  cursor: pointer; transition: filter var(--transition);
}
.rev-btn-grande:hover  { filter: brightness(1.08); }
.rev-btn-grande:active { filter: brightness(0.94); }
.rev-btn-grande.aviso  { background: #6b7589; }
.rev-pie-aviso {
  font-size: 12.5px; color: var(--text-soft); line-height: 1.5;
  margin-bottom: 10px; text-align: center;
}

.rev-busca-grande { height: 50px; font-size: 15px; margin-bottom: 14px; }
.rev-input-grande { height: 52px; font-size: 17px; font-variant-numeric: tabular-nums; }

/* ── Elegir vehículo / proyecto ──────────────────────────────────────────── */
.rev-veh-grid, .rev-proy-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px;
}
.rev-veh, .rev-proy {
  display: flex; flex-direction: column; gap: 4px;
  min-height: 72px; padding: 14px;
  background: var(--surface); border: 1.5px solid var(--border);
  border-radius: var(--radius); cursor: pointer; font-family: inherit; text-align: left;
  transition: border-color var(--transition), box-shadow var(--transition);
}
.rev-veh:hover, .rev-proy:hover { border-color: var(--accent); box-shadow: var(--shadow-sm); }
.rev-veh strong, .rev-proy strong { font-size: 15px; font-weight: 640; }
.rev-veh-mat {
  font-size: 11.5px; color: var(--text-soft); font-variant-numeric: tabular-nums;
  letter-spacing: 0.03em;
}
.rev-veh-est { font-size: 10.5px; color: var(--orange-dark); text-transform: capitalize; }
.rev-proy { flex-direction: row; align-items: center; gap: 9px; }
.rev-proy i { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; }
.rev-proy-salta { border-style: dashed; }
.rev-proy-salta strong { color: var(--text-soft); font-weight: 560; }

/* ── Los huecos de foto ──────────────────────────────────────────────────── */
.rev-huecos {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 14px;
}
.rev-hueco {
  background: var(--surface); border: 1.5px solid var(--border);
  border-radius: var(--radius); overflow: hidden;
  transition: border-color var(--transition);
}
.rev-hueco.hecha { border-color: rgba(43,45,66,0.28); }
.rev-hueco-cab {
  display: flex; align-items: center; gap: 9px;
  padding: 10px 12px; border-bottom: 1px solid var(--border);
}
.rev-hueco-num {
  width: 22px; height: 22px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%; font-size: 11.5px; font-weight: 700;
  background: var(--bg); color: var(--text-soft);
}
.rev-hueco.hecha .rev-hueco-num { background: var(--text); color: var(--surface); }
.rev-hueco-nom { font-size: 13.5px; font-weight: 620; }
.rev-hueco-cuerpo { display: flex; gap: 0; }
.rev-hueco-foto {
  flex: 1; min-width: 0; position: relative;
  aspect-ratio: 4 / 3;
  display: flex; align-items: center; justify-content: center;
  background: var(--bg); border: 0; cursor: pointer; padding: 0;
  font-family: inherit; overflow: hidden;
}
.rev-hueco-foto img { width: 100%; height: 100%; object-fit: cover; display: block; }
.rev-hueco-camara {
  display: flex; flex-direction: column; align-items: center; gap: 7px;
  padding: 12px; color: var(--text-xsoft); text-align: center;
}
.rev-hueco-camara svg { width: 30px; height: 30px; }
.rev-hueco-camara em { font-style: normal; font-size: 11px; line-height: 1.4; color: var(--text-soft); }
.rev-hueco-foto:hover .rev-hueco-camara { color: var(--accent); }
.rev-hueco-rehacer {
  position: absolute; bottom: 7px; right: 7px;
  background: rgba(43,45,66,0.82); color: #fff;
  font-size: 10.5px; font-weight: 650; padding: 3px 8px; border-radius: var(--radius-pill);
  opacity: 0; transition: opacity var(--transition);
}
.rev-hueco-foto:hover .rev-hueco-rehacer { opacity: 1; }
/* Referencia "así salió", solo en las entradas */
.rev-hueco-ref {
  width: 76px; flex-shrink: 0; position: relative;
  border-left: 1px solid var(--border); background: var(--bg);
  display: block; text-decoration: none;
}
.rev-hueco-ref img { width: 100%; height: 100%; object-fit: cover; display: block; opacity: 0.85; }
.rev-hueco-ref span {
  position: absolute; inset: auto 0 0 0;
  background: rgba(43,45,66,0.78); color: #fff;
  font-size: 9.5px; font-weight: 650; text-align: center; padding: 2px 0;
}
.rev-hueco-ref:hover img { opacity: 1; }

/* ── Daños ───────────────────────────────────────────────────────────────── */
.rev-danos {
  margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--border);
}
.rev-danos-cab {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  flex-wrap: wrap; margin-bottom: 10px;
}
.rev-danos-cab span { font-size: 14px; font-weight: 620; }
.rev-danos-vacio { font-size: 12.5px; color: var(--text-soft); }
.rev-danos-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px;
}
.rev-dano {
  position: relative; background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius-sm); overflow: hidden;
}
.rev-dano img { width: 100%; aspect-ratio: 4/3; object-fit: cover; display: block; }
.rev-dano-nota {
  width: 100%; border: 0; border-top: 1px solid var(--border);
  padding: 8px 9px; font-family: inherit; font-size: 12px; background: var(--surface);
}
.rev-dano-nota:focus { outline: 2px solid rgba(var(--acento-rgb), 0.4); outline-offset: -2px; }
.rev-dano-x {
  position: absolute; top: 6px; right: 6px;
  width: 26px; height: 26px; border: 0; border-radius: 50%;
  background: rgba(43,45,66,0.78); color: #fff; cursor: pointer; font-size: 12px;
}
.rev-dano-x:hover { background: var(--accent); }

/* ── Último paso ─────────────────────────────────────────────────────────── */
.rev-datos { display: flex; flex-direction: column; gap: 18px; }
.rev-campo { display: flex; flex-direction: column; gap: 7px; }
.rev-campo > span { font-size: 12px; font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--text-soft); }
.rev-comb { display: grid; grid-template-columns: repeat(5, 1fr); gap: 7px; }
.rev-comb-op {
  min-height: 48px; padding: 6px 4px;
  background: var(--surface); border: 1.5px solid var(--border);
  border-radius: var(--radius-sm); cursor: pointer;
  font-family: inherit; font-size: 13px; font-weight: 600; color: var(--text-soft);
  transition: all var(--transition);
}
.rev-comb-op:hover { border-color: var(--border-med); color: var(--text); }
.rev-comb-op.sel { background: var(--accent); border-color: var(--accent); color: #fff; }

/* ── Detalle de una revisión cerrada ────────────────────────────────────── */
.modal.modal-ancho { max-width: 1000px; width: calc(100vw - 40px); }
.revv-meta {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 12px; margin-bottom: 16px;
}
.revv-meta > div { display: flex; flex-direction: column; gap: 3px; }
.revv-meta span { font-size: 10px; font-weight: 700; letter-spacing: 0.07em;
  text-transform: uppercase; color: var(--text-soft); }
.revv-meta strong { font-size: 14px; font-weight: 620; }
.revv-notas, .revv-aviso {
  padding: 11px 13px; border-radius: var(--radius-sm); margin-bottom: 14px;
  font-size: 13px; line-height: 1.55;
}
.revv-notas { background: var(--bg); }
.revv-notas span { display: block; font-size: 10px; font-weight: 700;
  letter-spacing: 0.07em; text-transform: uppercase; color: var(--text-soft); margin-bottom: 4px; }
.revv-aviso { background: rgba(141,153,174,0.14); color: #5b6474; }
.revv-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 14px;
}
.revv-celda { }
.revv-nom { font-size: 11.5px; font-weight: 700; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--text-soft); margin-bottom: 6px; }
.revv-par { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.revv-foto {
  position: relative; display: block; border-radius: var(--radius-sm);
  overflow: hidden; border: 1px solid var(--border); text-decoration: none;
}
.revv-foto img { width: 100%; aspect-ratio: 4/3; object-fit: cover; display: block; }
.revv-foto span {
  position: absolute; inset: auto 0 0 0;
  background: rgba(43,45,66,0.78); color: #fff;
  font-size: 9.5px; font-weight: 650; padding: 3px 5px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.revv-foto:hover { border-color: var(--accent); }
.revv-falta {
  display: flex; align-items: center; justify-content: center;
  aspect-ratio: 4/3; border: 1px dashed var(--border-med);
  border-radius: var(--radius-sm); font-size: 11px; color: var(--text-xsoft);
}
.revv-danos { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }

/* ── Móvil: es el caso principal, no una adaptación ─────────────────────── */
@media (max-width: 720px) {
  .rev-hist-fila {
    grid-template-columns: 70px minmax(0, 1fr) 86px;
    grid-template-areas: 'tipo veh est' 'tipo proy est';
    row-gap: 2px;
  }
  .rev-hist-tipo   { grid-area: tipo; }
  .rev-hist-veh    { grid-area: veh; }
  .rev-hist-proy   { grid-area: proy; font-size: 11.5px; }
  .rev-hist-est    { grid-area: est; }
  .rev-hist-driver, .rev-hist-fotos, .rev-hist-km, .rev-hist-fecha { display: none; }
  .rev-hist-filtros { grid-template-columns: 1fr; }
  .rev-huecos { grid-template-columns: 1fr; }
  .rev-hueco-foto { aspect-ratio: 16 / 10; }
  .rev-veh-grid, .rev-proy-grid { grid-template-columns: 1fr 1fr; }
  .rev-comb { grid-template-columns: repeat(3, 1fr); }
  .rev-accion { min-height: 84px; padding: 18px; }
  .rev-wz-cuerpo { padding: 16px 12px 20px; }
  .revv-par { grid-template-columns: 1fr; }
}
/* La barra lateral se come 268px, así que el área útil ya va justa antes de
   llegar a "móvil": el nombre del driver salía cortado ("Adm..."). Se sacrifica
   la columna de proyecto, que es la menos crítica en el histórico. */
@media (max-width: 1250px) {
  .rev-hist-fila {
    grid-template-columns: 76px minmax(0, 1.5fr) minmax(0, 1.1fr) 58px 90px 106px 92px;
  }
  .rev-hist-proy { display: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   USUARIOS Y PERMISOS
   La matriz va dentro de un <details> cerrado: dar de alta a alguien tiene que
   ser elegir un perfil y darle a guardar. Quien necesite afinar, lo abre.
   ═══════════════════════════════════════════════════════════════════════════ */

.modal.modal-usuario-ancho { max-width: 720px; width: calc(100vw - 40px); }

.usr-bloque { margin: 18px 0 4px; }
.usr-bloque-tit {
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--text-soft); margin-bottom: 9px;
}
.usr-plantillas {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 9px;
}
.usr-plantilla {
  display: flex; flex-direction: column; gap: 3px;
  padding: 11px 13px; text-align: left;
  background: var(--surface); border: 1.5px solid var(--border);
  border-radius: var(--radius-sm); cursor: pointer; font-family: inherit;
  transition: border-color var(--transition), background var(--transition);
}
.usr-plantilla:hover { border-color: var(--border-med); }
.usr-plantilla.sel {
  border-color: var(--accent);
  background: rgba(var(--acento-rgb), 0.04);
}
.usr-plantilla strong { font-size: 13.5px; font-weight: 640; }
.usr-plantilla small  { font-size: 11.5px; color: var(--text-soft); line-height: 1.45; }

.usr-avanzado { margin-top: 16px; }
.usr-avanzado > summary {
  cursor: pointer; padding: 9px 0;
  font-size: 12.5px; font-weight: 620; color: var(--text-soft);
  list-style: none;
}
.usr-avanzado > summary::-webkit-details-marker { display: none; }
.usr-avanzado > summary::before { content: '▸ '; }
.usr-avanzado[open] > summary::before { content: '▾ '; }
.usr-avanzado > summary:hover { color: var(--text); }

.usr-matriz {
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  overflow: hidden; margin-bottom: 14px;
}
.usr-matriz-cab, .usr-matriz-fila {
  display: grid; grid-template-columns: minmax(0, 1fr) repeat(4, 74px);
  align-items: center; gap: 4px;
}
.usr-matriz-cab {
  padding: 8px 12px; background: var(--bg);
  border-bottom: 1px solid var(--border);
}
.usr-matriz-cab span {
  font-size: 9.5px; font-weight: 700; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--text-soft); text-align: center;
}
.usr-matriz-fila {
  padding: 9px 12px; border-bottom: 1px solid var(--border);
}
.usr-matriz-fila:last-child { border-bottom: 0; }
.usr-matriz-fila:hover { background: var(--bg); }
.usr-area { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.usr-area strong { font-size: 13px; font-weight: 620; }
.usr-area small  { font-size: 10.5px; color: var(--text-soft); line-height: 1.35; }
.usr-radio {
  display: flex; align-items: center; justify-content: center;
  min-height: 30px; cursor: pointer;
}
.usr-radio input { position: absolute; opacity: 0; pointer-events: none; }
.usr-radio span {
  width: 17px; height: 17px; border-radius: 50%;
  border: 1.5px solid var(--border-med); background: var(--surface);
  transition: border-color var(--transition), background var(--transition);
}
.usr-radio:hover span { border-color: var(--text-soft); }
.usr-radio input:checked + span {
  border-color: var(--accent); background: var(--accent);
  box-shadow: inset 0 0 0 3px var(--surface);
}
.usr-radio input:focus-visible + span { outline: 2px solid rgba(var(--acento-rgb),0.5); outline-offset: 2px; }

.usr-caps { display: flex; flex-direction: column; gap: 8px; }
.usr-cap {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 10px 12px; background: var(--bg);
  border-radius: var(--radius-sm); cursor: pointer;
}
.usr-cap input { margin-top: 2px; width: 16px; height: 16px; accent-color: var(--accent); }
.usr-cap-txt { display: flex; flex-direction: column; gap: 1px; }
.usr-cap-txt strong { font-size: 13px; font-weight: 620; }
.usr-cap-txt small  { font-size: 11.5px; color: var(--text-soft); }

/* ── Etiquetas de la columna "Acceso" ───────────────────────────────────── */
.usr-tag {
  display: inline-flex; align-items: center; gap: 3px;
  font-size: 10.5px; font-weight: 620;
  padding: 2px 7px; margin: 1px 3px 1px 0;
  border-radius: var(--radius-xs);
  background: var(--bg); color: var(--text-soft);
  white-space: nowrap;
}
.usr-tag i {
  font-style: normal; font-size: 8.5px; font-weight: 800;
  opacity: 0.7; letter-spacing: 0.03em;
}
.usr-tag-total   { background: rgba(43,45,66,0.10);            color: var(--text); }
.usr-tag-edicion { background: rgba(141,153,174,0.18);         color: #5b6474; }
.usr-tag-lectura { background: var(--bg);                      color: var(--text-soft); }
.usr-tag-admin   { background: rgba(var(--acento-rgb),0.10);   color: var(--accent); font-weight: 700; }
.usr-tag-nada    { background: transparent; color: var(--text-xsoft); font-style: italic; }
.usr-tag-cap     { background: rgba(43,45,66,0.06); color: var(--text-soft); font-size: 9.5px; }

@media (max-width: 640px) {
  .usr-matriz-cab, .usr-matriz-fila { grid-template-columns: minmax(0, 1fr) repeat(4, 50px); }
  .usr-matriz-cab span { font-size: 8.5px; }
  .usr-plantillas { grid-template-columns: 1fr; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   VEHÍCULOS — bajar la densidad sin quitar información
   Antes había DIEZ tarjetas grandes antes del primer vehículo, repartidas en dos
   filas que hacían lo mismo: filtrar la lista. Tres mostraban el mismo número
   (Todos = Disponibles = Flota total, porque los 26 están activos) y cuatro
   estaban a cero ocupando lo mismo que las útiles.

   Criterio: lo que es un control se pinta como control (chip), no como tarjeta
   de dashboard; lo que está a cero no ocupa sitio; y lo grande pero secundario
   se pliega con un rótulo que diga qué hay dentro.
   ═══════════════════════════════════════════════════════════════════════════ */

.veh-barra {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin-bottom: 10px;
}
.veh-chips { display: flex; gap: 5px; flex-wrap: wrap; }
.veh-chip {
  display: inline-flex; align-items: center; gap: 6px;
  height: 34px; padding: 0 12px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  font-family: inherit; font-size: 13px; font-weight: 560; color: var(--text-soft);
  cursor: pointer; white-space: nowrap;
  transition: all var(--transition);
}
.veh-chip span {
  font-size: 11px; font-weight: 700; font-variant-numeric: tabular-nums;
  padding: 1px 6px; border-radius: var(--radius-pill);
  background: var(--bg); color: var(--text-soft);
}
.veh-chip:hover { border-color: var(--border-med); color: var(--text); }
.veh-chip.activo {
  background: var(--text); border-color: var(--text); color: var(--surface); font-weight: 620;
}
.veh-chip.activo span { background: rgba(255,255,255,0.18); color: #fff; }
/* Una categoría sin vehículos sigue estando (se puede llenar mañana) pero no
   compite: atenuada y sin borde. */
.veh-chip.vacio { opacity: 0.45; }
.veh-chip.vacio:hover { opacity: 0.75; }

.veh-buscador { flex: 1; min-width: 220px; max-width: 380px; height: 34px; }

/* ── Avisos: solo existen si hay algo ───────────────────────────────────── */
.veh-avisos-chips { display: flex; gap: 7px; flex-wrap: wrap; }
.veh-avisos-chips:empty { display: none; }
.veh-aviso-chip {
  display: inline-flex; align-items: center; gap: 5px;
  height: 30px; padding: 0 11px; margin-bottom: 10px;
  background: rgba(var(--acento-rgb), 0.07);
  border: 1px solid rgba(var(--acento-rgb), 0.18);
  border-radius: var(--radius-pill);
  font-family: inherit; font-size: 12.5px; color: var(--accent);
  cursor: pointer; white-space: nowrap;
  transition: all var(--transition);
}
.veh-aviso-chip strong { font-weight: 700; font-variant-numeric: tabular-nums; }
.veh-aviso-chip:hover { background: rgba(var(--acento-rgb), 0.13); }
.veh-aviso-chip.activo { background: var(--accent); border-color: var(--accent); color: #fff; }

/* ── Qué se está viendo ─────────────────────────────────────────────────── */
.veh-resumen {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-bottom: 14px; min-height: 22px;
}
.veh-resumen-txt { font-size: 12px; color: var(--text-soft); }
.veh-resumen-txt strong { color: var(--text); font-variant-numeric: tabular-nums; }
.veh-resumen-pill {
  font-size: 11px; font-weight: 620;
  padding: 2px 8px; border-radius: var(--radius-pill);
  background: var(--bg); color: var(--text-soft);
}
.veh-resumen-limpiar {
  background: none; border: 0; padding: 2px 4px;
  font-family: inherit; font-size: 11.5px; font-weight: 620;
  color: var(--accent); cursor: pointer;
}
.veh-resumen-limpiar:hover { text-decoration: underline; }

/* ── Plegables ──────────────────────────────────────────────────────────── */
.veh-plegable {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); margin-bottom: 14px;
}
.veh-plegable > summary {
  display: flex; align-items: center; gap: 9px;
  padding: 12px 15px; cursor: pointer; list-style: none;
  font-size: 12.5px; font-weight: 700; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--text-soft);
  transition: color var(--transition);
}
.veh-plegable > summary::-webkit-details-marker { display: none; }
.veh-plegable > summary::before {
  content: ''; width: 0; height: 0; flex-shrink: 0;
  border-left: 5px solid currentColor;
  border-top: 4px solid transparent; border-bottom: 4px solid transparent;
  transition: transform 0.2s ease;
}
.veh-plegable[open] > summary::before { transform: rotate(90deg) translateX(1px); }
.veh-plegable > summary:hover { color: var(--text); }
.veh-pleg-info {
  margin-left: auto; text-transform: none; letter-spacing: 0;
  font-size: 11.5px; font-weight: 560; color: var(--text-xsoft);
}
.veh-plegable[open] > summary { border-bottom: 1px solid var(--border); }
.veh-plegable > *:not(summary) { padding: 4px 15px 14px; }
/* El widget de flota trae su propia tarjeta: dentro del plegable sobra. */
.veh-plegable #veh-fleet-widget .dash-widget {
  border: 0; box-shadow: none; padding: 0; background: none;
}

/* ── Tabla: ITV y seguro en una sola columna ────────────────────────────── */
.tabla-veh .veh-doc {
  display: flex; flex-direction: column; gap: 1px;
  font-size: 11.5px; font-variant-numeric: tabular-nums;
}
.veh-doc-linea { display: flex; align-items: baseline; gap: 5px; }
.veh-doc-linea em {
  font-style: normal; font-size: 9.5px; font-weight: 700;
  letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--text-xsoft); min-width: 24px;
}

@media (max-width: 820px) {
  .veh-buscador { max-width: none; }
  .veh-chips { width: 100%; }
}
/* Avisos de documentación: llevaban ⛔ y ⚠️ metidos en el texto, que es
   exactamente el tipo de ruido que se está quitando. Un punto de color basta. */
.veh-alerta-banner {
  display: flex; align-items: center; gap: 9px;
  padding: 8px 2px; font-size: 12.5px; color: var(--text);
  border-bottom: 1px solid var(--border);
}
.veh-alerta-banner:last-child { border-bottom: 0; }
.veh-alerta-banner strong { font-weight: 620; }
.veh-alerta-banner em {
  font-style: normal; margin-left: auto;
  font-size: 11.5px; color: var(--text-soft); font-variant-numeric: tabular-nums;
}
.veh-alerta-pt {
  width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0;
  background: var(--text-xsoft);
}
.veh-alerta-banner.danger .veh-alerta-pt { background: var(--accent); }
.veh-alerta-banner.danger strong { color: var(--accent); }
/* Cada plegable se queda SIEMPRE en su media columna, abierto o cerrado. Antes
   el que se abría pasaba a ancho completo y empujaba al otro a la línea de
   abajo: abrir uno reorganizaba la pantalla entera y el segundo se perdía de
   vista. Cada uno en su sitio, y el contenido se apaña con el ancho que tiene. */
.veh-plegables {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 12px; margin-bottom: 14px; align-items: start;
}
.veh-plegables > .veh-plegable { margin-bottom: 0; min-width: 0; }
/* Lo que se meta dentro no puede desbordar la media columna. */
.veh-plegables > .veh-plegable > *:not(summary) { overflow-x: auto; }
@media (max-width: 900px) {
  .veh-plegables { grid-template-columns: 1fr; }
}
/* Un poco más apretados: así los cinco caben en una línea también cuando el
   área útil se estrecha (la barra lateral se lleva 268px). */
.veh-chip { height: 32px; padding: 0 10px; font-size: 12.5px; gap: 5px; }
.veh-chip span { font-size: 10.5px; padding: 1px 5px; }
.veh-chips { gap: 4px; }
.veh-buscador { height: 32px; min-width: 190px; }
/* Las reglas de la línea 1353 pintaban la fila entera de ámbar o rojo con
   borde. Con un punto de color y el nombre en rojo ya se entiende, y así diez
   avisos seguidos no son diez rectángulos de color. */
.veh-alerta-banner,
.veh-alerta-banner.danger {
  background: none;
  border: 0;
  border-bottom: 1px solid var(--border);
  border-radius: 0;
  margin-bottom: 0;
  color: var(--text);
}
.veh-alerta-banner:last-child,
.veh-alerta-banner.danger:last-child { border-bottom: 0; }
.veh-alerta-banner.danger strong { color: var(--accent); }

/* `flex-shrink: 1` (el valor por defecto) comprimía la fila de chips por debajo
   de su contenido y partía el último a la línea siguiente aunque hubiera sitio.
   Mismo patrón que ya apareció en la barra lateral: si no debe encogerse, hay
   que decirlo. Aquí el que cede es el buscador. */
.veh-chips { flex: 0 0 auto; }
.veh-buscador { flex: 1 1 190px; }
/* Los cinco chips piden ~461px y el área útil da 416 con la barra desplegada,
   así que el último se caía a una segunda línea. En vez de recortar 45px a base
   de padding (y volver a romperse el día que se añada una categoría), una sola
   línea con scroll: es el patrón normal para filtros en pantallas estrechas. */
.veh-chips {
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
  padding-bottom: 2px;
  flex: 1 1 auto;
  min-width: 0;
}
.veh-chips::-webkit-scrollbar { height: 0; }
.veh-chip { flex-shrink: 0; }
/* El buscador solo comparte línea cuando de verdad cabe. */
.veh-buscador { flex: 0 1 240px; }
@media (max-width: 1150px) {
  .veh-buscador { flex: 1 1 100%; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   BARRA LATERAL — acabado profesional y minimalista

   Qué había apilado en el elemento activo: un degradado de rojo a rojo, un
   `box-shadow` de resplandor rojo, un bisel interior blanco (`inset 0 1px 0`) y
   una barra blanca de 3px encima del propio rojo. Cuatro efectos para decir una
   sola cosa: "estás aquí". Y en hover el item se desplazaba 2px Y el icono
   crecía un 12 %: dos movimientos a la vez, que se lee como nervioso.

   El rojo se queda, que es lo que se pidió, pero PLANO. Rojo sólido con texto
   blanco ya es el máximo contraste posible; el degradado y el resplandor no
   añadían contraste, solo ruido.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Activo: un solo rojo, plano ─────────────────────────────────────────── */
.sidebar .nav-item.active,
.sidebar .nav-item.active:hover {
  background: var(--sidebar-rojo);
  color: #fff;
  font-weight: 600;
  box-shadow: none;              /* fuera resplandor y bisel */
  transform: none;
}
/* La barra blanca sobre el rojo era redundante: la fila entera ya está roja. */
.sidebar .nav-item.active::before { display: none; }
.sidebar .nav-item.active .nav-icon { opacity: 1; transform: none; }

/* ── Hover: solo cambia el fondo ─────────────────────────────────────────── */
/* Sin desplazamiento lateral ni icono creciendo. Un cambio de fondo es
   suficiente para saber dónde está el cursor, y no mueve la lista. */
.sidebar .nav-item {
  transition: background 0.14s ease, color 0.14s ease;
}
.sidebar .nav-item:hover {
  background: rgba(255,255,255,0.055);
  color: #fff;
  transform: none;
}
.sidebar .nav-item:hover .nav-icon { transform: none; opacity: 0.9; }
/* La barra roja que crecía en hover se queda, pero fina y solo en los
   inactivos: es la única pista de color y no compite con nada. */
.sidebar .nav-item:hover::before { height: 16px; }
.sidebar .nav-icon { transition: opacity 0.14s ease; }

/* ── Badges: planos ──────────────────────────────────────────────────────── */
.sidebar .nav-badge {
  box-shadow: none;
  font-weight: 650;
  transition: none;
}
.sidebar .nav-item:hover .nav-badge { transform: none; }
.sidebar .nav-item.active .nav-badge {
  background: rgba(255,255,255,0.22);
  color: #fff;
  box-shadow: none;
}

/* ── Cabeceras de grupo: un poco más finas ──────────────────────────────── */
.nav-group-head {
  font-size: 10px;
  font-weight: 650;
  letter-spacing: 0.12em;
  color: rgba(255,255,255,0.38);
}
.nav-group-head:hover { background: rgba(255,255,255,0.045); color: rgba(255,255,255,0.7); }
.nav-group.cerrado.tiene-activo .nav-group-head { color: rgba(255,255,255,0.66); }

/* ── Botón de plegar: sin caja ───────────────────────────────────────────── */
/* Un botón con borde y fondo propio junto al logo pesaba más que el logo. Sin
   caja hasta que se pasa el ratón. */
.sidebar-collapse-btn {
  background: none;
  border-color: transparent;
  color: rgba(255,255,255,0.4);
}
.sidebar-collapse-btn:hover {
  background: rgba(255,255,255,0.07);
  border-color: transparent;
  color: #fff;
}
.sidebar.collapsed .sidebar-collapse-btn {
  background: none;
  border-color: transparent;
  color: rgba(255,255,255,0.55);
}
.sidebar.collapsed .sidebar-collapse-btn:hover {
  background: rgba(255,255,255,0.08);
  color: #fff;
}

/* ═══════════════════════════════════════════════════════════════════════════
   LA PALMERA DEL FONDO
   Estaba al 100 % de ancho, escalada 1.28, con `drop-shadow` rojo y girando
   1,2° al pasar el ratón. Resultado: una mancha grande que chocaba con los
   rótulos de PERSONAL y SISTEMA, y el resplandor rojo es justo lo que la hacía
   parecer barata.

   Ahora es una marca de agua contenida: más pequeña, anclada abajo, sin brillo
   ni giro, y con una máscara que la desvanece hacia arriba para que nunca se
   cruce con el texto del menú.
   ═══════════════════════════════════════════════════════════════════════════ */
.sidebar-palm-watermark {
  top: auto;
  bottom: 0;
  height: 46%;                    /* solo la franja inferior */
  align-items: flex-end;
  justify-content: center;
  opacity: 0.06;
  filter: none;                   /* fuera el drop-shadow rojo */
  transform: none;
  transition: opacity 0.45s ease;
  /* Se desvanece hacia arriba: así el menú siempre queda limpio por encima. */
  -webkit-mask-image: linear-gradient(to top, #000 0%, #000 34%, transparent 88%);
          mask-image: linear-gradient(to top, #000 0%, #000 34%, transparent 88%);
}
.sidebar-palm-watermark img {
  width: 74%;
  max-width: 200px;
  margin: 0 auto;
  filter: invert(1);
  transform: translateY(6%);
  transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}
/* Interacción: solo se aclara y sube un pelo. Sin giro. */
.sidebar:hover .sidebar-palm-watermark { opacity: 0.11; transform: none; }
.sidebar:hover .sidebar-palm-watermark img { transform: translateY(2%); }

.sidebar.collapsed .sidebar-palm-watermark {
  transform: none;
  opacity: 0.05;
  height: 30%;
}
.sidebar.collapsed .sidebar-palm-watermark img { width: 62%; max-width: 46px; }
/* Segunda pasada: con 46 % de alto y 74 % de ancho seguía siendo una silueta
   grande justo detrás de TECNOLOGÍA y PERSONAL. Una silueta grande tras el texto
   del menú es lo que hace que una barra lateral parezca de plantilla; como marca
   de agua pequeña de esquina se lee como intencionada.
   Si se prefiere quitarla del todo: `display: none` aquí y listo. */
.sidebar-palm-watermark {
  height: 210px;                 /* franja fija: no crece con la pantalla */
  opacity: 0.05;
  align-items: flex-end;
  justify-content: flex-end;
  padding: 0 14px 10px 0;
  -webkit-mask-image: linear-gradient(to top, #000 0%, #000 20%, transparent 78%);
          mask-image: linear-gradient(to top, #000 0%, #000 20%, transparent 78%);
}
.sidebar-palm-watermark img {
  width: 128px;
  max-width: 128px;
  margin: 0;
}
.sidebar:hover .sidebar-palm-watermark { opacity: 0.09; }
.sidebar.collapsed .sidebar-palm-watermark {
  height: 120px;
  justify-content: center;
  padding: 0 0 8px 0;
  opacity: 0.045;
}
.sidebar.collapsed .sidebar-palm-watermark img { width: 40px; max-width: 40px; }

/* ═══════════════════════════════════════════════════════════════════════════
   CONSTRUCTOR DE PRESUPUESTOS — panel derecho con árbol de categorías
   Es el mismo componente que la ficha de proyecto. Al panel se le pone también
   la clase `np-grande`, que es la que activa la maquetación en rejilla de
   `.np-item` y de la cabecera, así que aquí solo hace falta el contenedor y las
   dos cosas que este sitio tiene y el otro no: el pie con el catálogo de
   servicios y la cabecera de 5 columnas de ese modo.
   ═══════════════════════════════════════════════════════════════════════════ */

.builder-right-arbol {
  display: grid;
  grid-template-columns: 240px minmax(0, 1fr);
  min-height: 0;
  overflow: hidden;
}
.builder-right-arbol .np-arbol {
  border-right: 1px solid var(--border);
  border-bottom: 0;
  display: flex; flex-direction: column; min-height: 0;
}
.builder-right-arbol .np-arbol-lista { flex: 1; overflow-y: auto; }
.builder-right-arbol .np-derecha { min-width: 0; min-height: 0; }
.builder-right-arbol .np-catalogo { flex: 1; overflow-y: auto; max-height: none; }

/* Pie con el catálogo de servicios y personal: no está en el árbol de
   inventario porque no es material físico, así que tiene su propio acceso. */
.np-cat-pie {
  flex-shrink: 0;
  padding: 8px 11px;
  border-top: 1px solid var(--border);
  background: var(--surface-2);
}

/* El modo servicios tiene 5 columnas, no 6: sin código y con unidad. */
.np-cat-cab-serv,
.np-grande .np-item-serv {
  grid-template-columns: 110px minmax(0, 1fr) 62px 78px 22px;
}
.np-cat-cab-serv span:nth-child(3),
.np-cat-cab-serv span:nth-child(4) { text-align: right; }
.np-grande .np-item-serv .np-item-uds,
.np-grande .np-item-serv .np-item-eur { text-align: right; }

@media (max-width: 1200px) {
  .builder-right-arbol { grid-template-columns: 200px minmax(0, 1fr); }
}
@media (max-width: 900px) {
  .builder-right-arbol { grid-template-columns: 1fr; }
  .builder-right-arbol .np-arbol {
    border-right: 0; border-bottom: 1px solid var(--border); max-height: 190px;
  }
  .np-cat-cab-serv, .np-grande .np-item-serv {
    grid-template-columns: minmax(0, 1fr) 62px 22px;
  }
  .np-cat-cab-serv span:nth-child(1), .np-grande .np-item-serv .np-item-cat { display: none; }
}
/* El panel derecho era una lista plana de 320px. Ahora lleva árbol (240px) +
   catálogo en rejilla de 6 columnas, que pide ~420px, así que la columna fija de
   320px estrangulaba la izquierda hasta dejarla en una palabra por línea.

   `minmax(0, ...)` en las dos y `min-width: 0` en los hijos: `1fr` es
   `minmax(auto, 1fr)` y ese mínimo `auto` es justo lo que deja que el contenido
   decida el ancho. Es la tercera vez que aparece en el proyecto. */
.builder-wrap {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.06fr);
}
.builder-wrap > .builder-left,
.builder-wrap > .builder-right { min-width: 0; }

/* Por debajo de 1150px las dos columnas no caben: se apilan y el catálogo pasa
   debajo con altura propia, en vez de comprimir el formulario. */
@media (max-width: 1150px) {
  .builder-wrap {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto;
    height: auto;
    overflow: visible;
  }
  .builder-wrap > .builder-left { overflow: visible; }
  .builder-right-arbol { min-height: 420px; max-height: 60vh; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   CONSTRUCTOR DE PRESUPUESTOS — dos modos

   El problema era mezclar dos trabajos en la misma columna: meter material y
   reestructurar el documento. Al lado del catálogo había inputs de renombrar
   sección, flechas de subir/bajar, un aspa por fila y campos de descuento, así
   que metiendo material se podía tocar algo sin querer.

   Modo material (por defecto): el catálogo manda, la izquierda es casi de
   lectura y solo se ajustan cantidades.
   Modo personalizar: el catálogo se va, la izquierda ocupa todo y ahí sí está
   todo editable.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Todo lo estructural se esconde salvo en modo personalizar. */
.pres-solo-personalizar { display: none !important; }
.modo-personalizar .pres-solo-personalizar { display: flex !important; }
.modo-personalizar #pres-forma { display: block !important; }

/* En modo material el catálogo es lo grande (se pidió la lista más grande). */
.builder-wrap { grid-template-columns: minmax(0, 0.82fr) minmax(0, 1.18fr); }

/* En personalizar desaparece el catálogo y la izquierda ocupa todo el ancho. */
.modo-personalizar .builder-wrap { grid-template-columns: minmax(0, 1fr); }
.modo-personalizar .builder-right { display: none; }

#btn-personalizar { white-space: nowrap; }

/* ── Datos del presupuesto: tira de una línea ────────────────────────────── */
.pres-datos {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 11px 14px;
  margin-bottom: 12px;
}
.pres-datos-fila { display: flex; gap: 10px; align-items: flex-end; }
.pres-datos-extra {
  display: flex; gap: 10px; flex-wrap: wrap; align-items: flex-end;
  margin-top: 11px; padding-top: 11px; border-top: 1px solid var(--border);
}
.pres-dato { display: flex; flex-direction: column; gap: 4px; flex: 1; min-width: 0; }
.pres-dato > span {
  font-size: 10px; font-weight: 700; letter-spacing: 0.07em;
  text-transform: uppercase; color: var(--text-soft);
}
.pres-dato input, .pres-dato select, .pres-dato textarea {
  width: 100%; font-family: inherit; font-size: 13px;
  padding: 7px 9px; border: 1px solid var(--border);
  border-radius: var(--radius-sm); background: var(--surface); color: var(--text);
}
.pres-dato input:focus, .pres-dato select:focus, .pres-dato textarea:focus {
  outline: none; border-color: var(--accent);
}
.pres-dato-ancho { flex: 1 1 100%; }
.pres-datos-mas {
  flex-shrink: 0; height: 33px; padding: 0 11px;
  background: var(--bg); border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-family: inherit; font-size: 12px; font-weight: 600; color: var(--text-soft);
  cursor: pointer; white-space: nowrap;
  transition: all var(--transition);
}
.pres-datos-mas:hover { border-color: var(--border-med); color: var(--text); }
.pres-datos-mas.abierto { background: var(--accent); border-color: var(--accent); color: #fff; }
.pres-forma-fila { display: flex; gap: 12px; align-items: flex-end; }

/* ── Filas en modo material: casi de lectura ─────────────────────────────── */
.pres-mat-desc { font-size: 13px; line-height: 1.4; }
.pres-mat-desc em {
  display: block; font-style: normal; font-size: 11px; color: var(--text-soft);
}
.pres-mat-precio, .pres-mat-sub {
  text-align: right; font-variant-numeric: tabular-nums; font-size: 12.5px;
}
.pres-mat-sub { font-weight: 650; }
/* Sección en modo material: se ve, no se toca. */
.pres-section-ro .pres-section-cell { padding: 4px 0; }
.pres-section-nom {
  font-size: 11px; font-weight: 700; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--text-soft);
}

/* ── Contadores de cantidad ──────────────────────────────────────────────── */
.pres-cant, .pc-cant {
  display: inline-flex; align-items: center;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  overflow: hidden; background: var(--surface);
}
.pres-cant button, .pc-cant button {
  width: 26px; height: 28px; flex-shrink: 0;
  background: var(--bg); border: 0; cursor: pointer;
  font-family: inherit; font-size: 14px; font-weight: 700; color: var(--text-soft);
  transition: background var(--transition), color var(--transition);
}
.pres-cant button:hover, .pc-cant button:hover { background: var(--accent); color: #fff; }
.pres-cant input {
  width: 42px; height: 28px; border: 0; text-align: center;
  font-family: inherit; font-size: 13px; font-weight: 650;
  font-variant-numeric: tabular-nums; background: var(--surface); color: var(--text);
  -moz-appearance: textfield;
}
.pres-cant input::-webkit-outer-spin-button,
.pres-cant input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.pres-cant input:focus { outline: none; background: rgba(var(--acento-rgb), 0.05); }
/* En el catálogo la cantidad es más pequeña: la fila mide 30px. */
.pc-cant { height: 22px; }
.pc-cant button { width: 20px; height: 20px; font-size: 12px; }
.pc-cant b {
  min-width: 22px; text-align: center; font-size: 11.5px; font-weight: 700;
  font-variant-numeric: tabular-nums; color: var(--accent);
}

/* ── Columna de orden en modo personalizar ──────────────────────────────── */
.pres-orden { text-align: center; white-space: nowrap; }
.pres-orden .pres-section-move { margin: 0 1px; }

/* ── El catálogo, más grande y más legible ──────────────────────────────── */
/* Se pidió "la lista así como la tienes pero más grande". Filas más altas y
   texto un punto mayor; el ítem pasa de <button> a <div role=button> porque
   ahora contiene botones (el contador) y un botón no puede anidar botones. */
.builder-right-arbol .np-item {
  min-height: 30px;
  font-size: 12.5px;
  cursor: pointer;
  align-items: center;
}
.builder-right-arbol .np-item:hover { background: var(--bg-hover); }
.builder-right-arbol .np-item.puesto {
  background: rgba(var(--acento-rgb), 0.045);
}
.builder-right-arbol .np-item:focus-visible {
  outline: 2px solid rgba(var(--acento-rgb), 0.5); outline-offset: -2px;
}
.builder-right-arbol .np-item-nom { font-weight: 500; }
.builder-right-arbol .np-arbol-lista .np-nodo { min-height: 28px; }

@media (max-width: 1150px) {
  .builder-wrap, .modo-personalizar .builder-wrap { grid-template-columns: minmax(0, 1fr); }
  .pres-datos-fila { flex-wrap: wrap; }
  .pres-dato { flex: 1 1 200px; }
}
/* El catálogo del constructor tiene su propia rejilla de 4 columnas (el de la
   ficha de proyecto sigue con 6; usan renderizadores distintos). Y el árbol baja
   a 200px: con 240 la columna del nombre se quedaba sin espacio. */
.builder-right-arbol { grid-template-columns: 200px minmax(0, 1fr); }
.builder-right-arbol .np-cat-cab,
.builder-right-arbol .np-item {
  grid-template-columns: 52px minmax(0, 1fr) 74px 58px;
  gap: 8px;
}
.builder-right-arbol .np-cat-cab span:nth-child(3) { text-align: right; }
.builder-right-arbol .np-item-eur { text-align: right; }
.builder-right-arbol .np-item-mas { text-align: center; }
/* El modo servicios mantiene sus 5 columnas propias. */
.builder-right-arbol .np-cat-cab-serv,
.builder-right-arbol .np-item-serv {
  grid-template-columns: 96px minmax(0, 1fr) 56px 74px 30px;
}
@media (max-width: 1250px) {
  .builder-right-arbol { grid-template-columns: 176px minmax(0, 1fr); }
  .builder-right-arbol .np-cat-cab,
  .builder-right-arbol .np-item { grid-template-columns: 46px minmax(0, 1fr) 66px 54px; gap: 6px; }
}
/* Descuento global e IVA: visibles siempre, editables solo en personalizar. */
.pres-totals-row input:disabled {
  background: none; border-color: transparent; color: var(--text-soft);
  cursor: default; font-weight: 650;
}

/* ═══════════════════════════════════════════════════════════════════════════
   SELECTOR DE MATERIAL — modelo Rentman
   Un solo árbol donde las carpetas se despliegan en línea, casilla en cada fila
   y un único botón "Añadir". Filas cuadradas, densas y sin adornos: lo que hace
   que la lista de Rentman se lea de un vistazo es que todas las filas miden lo
   mismo y la sangría es la única jerarquía.
   ═══════════════════════════════════════════════════════════════════════════ */

.builder-wrap { grid-template-columns: minmax(0, 1.02fr) minmax(0, 1fr); }

.pk {
  display: flex; flex-direction: column; min-height: 0; min-width: 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}

/* ── Cabecera: cuenta de seleccionados + añadir ─────────────────────────── */
.pk-cab {
  display: flex; align-items: center; gap: 9px;
  padding: 9px 11px; flex-shrink: 0;
  border-bottom: 1px solid var(--border);
  background: var(--surface-2, var(--bg));
}
.pk-cab-x {
  width: 22px; height: 22px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: none; border: 0; border-radius: var(--radius-xs);
  color: var(--text-soft); cursor: pointer; visibility: hidden;
}
.pk-cab-x:hover { background: var(--border); color: var(--text); }
.pk-cab-n {
  flex: 1; min-width: 0;
  font-size: 12px; font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--text-soft);
}
.pk-add {
  display: inline-flex; align-items: center; gap: 4px; flex-shrink: 0;
  height: 27px; padding: 0 10px;
  background: var(--accent); border: 0; border-radius: var(--radius-xs);
  font-family: inherit; font-size: 12.5px; font-weight: 650; color: #fff;
  cursor: pointer; transition: filter var(--transition);
}
.pk-add:hover:not(:disabled) { filter: brightness(1.08); }
.pk-add:disabled { background: var(--border); color: var(--text-xsoft); cursor: default; }

/* ── Buscador ───────────────────────────────────────────────────────────── */
.pk-busca-wrap { position: relative; flex-shrink: 0; border-bottom: 1px solid var(--border); }
.pk-busca-ico {
  position: absolute; left: 11px; top: 50%; transform: translateY(-50%);
  color: var(--text-xsoft); pointer-events: none;
}
.pk-busca-wrap input {
  width: 100%; height: 34px; padding: 0 11px 0 32px;
  border: 0; background: none; font-family: inherit; font-size: 12.5px; color: var(--text);
}
.pk-busca-wrap input:focus { outline: none; background: rgba(var(--acento-rgb), 0.03); }

/* ── La lista ───────────────────────────────────────────────────────────── */
.pk-lista { flex: 1; overflow-y: auto; min-height: 0; }
.pk-res-info {
  padding: 6px 11px; font-size: 10.5px; font-weight: 650; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--text-xsoft);
  background: var(--bg); border-bottom: 1px solid var(--border);
  position: sticky; top: 0; z-index: 1;
}
.pk-vacio { padding: 26px 14px; text-align: center; font-size: 12.5px; color: var(--text-soft); }

/* Filas cuadradas, todas del mismo alto. La sangría (--niv) es la jerarquía. */
.pk-fila {
  display: flex; align-items: center; gap: 7px;
  height: 30px; padding: 0 10px 0 calc(10px + var(--niv, 0) * 15px);
  border-bottom: 1px solid var(--border);
  font-size: 12.5px; cursor: pointer;
  transition: background 0.1s ease;
}
.pk-fila:last-child { border-bottom: 0; }
.pk-fila:hover { background: var(--bg); }

/* Casilla: cuadrada, como en Rentman. */
.pk-check {
  width: 15px; height: 15px; flex-shrink: 0; padding: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface); border: 1.5px solid var(--border-med);
  border-radius: 0; cursor: pointer; color: #fff;
  transition: background 0.12s ease, border-color 0.12s ease;
}
.pk-check:hover:not(:disabled) { border-color: var(--accent); }
.pk-check.todo { background: var(--accent); border-color: var(--accent); }
.pk-check.parte { background: var(--surface); border-color: var(--accent); }
.pk-check.parte i { width: 7px; height: 2px; background: var(--accent); border-radius: 0; }
.pk-check:disabled { opacity: 0.3; cursor: default; }

.pk-chev {
  width: 15px; height: 15px; flex-shrink: 0; padding: 0;
  display: flex; align-items: center; justify-content: center;
  background: none; border: 0; color: var(--text-soft); cursor: pointer;
  transition: transform 0.16s ease;
}
.pk-chev.abierto { transform: rotate(90deg); }
.pk-chev:disabled { visibility: hidden; }

.pk-carpeta { flex-shrink: 0; color: var(--text-xsoft); }
.pk-cat { background: rgba(43,45,66,0.022); }
.pk-cat .pk-nom { font-weight: 650; }
.pk-cat:hover { background: rgba(43,45,66,0.05); }

.pk-guion {
  flex-shrink: 0; width: 11px; text-align: center;
  color: var(--text-xsoft); font-size: 11px; line-height: 1;
}
.pk-nom {
  flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pk-cuenta {
  flex-shrink: 0; font-size: 10.5px; font-weight: 700;
  font-variant-numeric: tabular-nums; color: var(--text-xsoft);
}
.pk-cod {
  flex-shrink: 0; width: 46px; text-align: right;
  font-size: 10.5px; font-variant-numeric: tabular-nums; color: var(--text-xsoft);
}
.pk-eur {
  flex-shrink: 0; width: 62px; text-align: right;
  font-size: 11.5px; font-variant-numeric: tabular-nums; color: var(--text-soft);
}
.pk-ya { flex-shrink: 0; color: var(--accent); font-weight: 700; font-size: 11px; }

/* Fila seleccionada: barra roja a la izquierda, como el azul de Rentman. */
.pk-item.sel {
  background: rgba(var(--acento-rgb), 0.05);
  box-shadow: inset 2px 0 0 var(--accent);
}
.pk-item.sel .pk-nom { font-weight: 600; }
.pk-item.puesto .pk-nom { color: var(--text-soft); }

/* En personalizar el selector desaparece y el documento ocupa todo. */
.modo-personalizar .pk { display: none; }
.modo-personalizar .builder-wrap { grid-template-columns: minmax(0, 1fr); }

@media (max-width: 1150px) {
  .builder-wrap { grid-template-columns: minmax(0, 1fr); }
  .pk { min-height: 400px; max-height: 60vh; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   BARRA LATERAL — estructura de Rentman con nuestra paleta

   Qué hace que la de Rentman se lea de un vistazo, y que aquí se copia:
     · TODO cuadrado. Ni una esquina redondeada. Las píldoras con margen que
       había antes flotaban; una fila cuadrada de borde a borde se lee como una
       lista, que es lo que es.
     · El activo ocupa el ancho COMPLETO, sin márgenes laterales.
     · El padre de un grupo lleva icono a la izquierda y el chevron a la
       DERECHA; los hijos van sangrados y SIN icono. Esa diferencia es la que
       hace que la jerarquía se entienda sin leer.
     · Filas densas y del mismo alto. Cero animaciones de movimiento.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Sin padding lateral: las filas llegan a los dos bordes. */
.sidebar-nav { padding: 0 0 16px; gap: 0; }

.nav-fijos {
  gap: 0; padding-bottom: 0; margin-bottom: 0;
  border-bottom: 1px solid rgba(255,255,255,0.07);
}

/* ── Filas ──────────────────────────────────────────────────────────────── */
.sidebar .nav-item {
  border-radius: 0;
  padding: 0 14px;
  height: 34px;
  gap: 11px;
  font-size: 13px;
  font-weight: 500;
}
.sidebar .nav-item.active,
.sidebar .nav-item.active:hover {
  border-radius: 0;
  background: var(--sidebar-rojo);
  font-weight: 600;
}
/* La marca de -8px ya no tiene sentido sin padding lateral. */
.sidebar .nav-item::before { display: none; }
.sidebar .nav-item:hover::before { display: none; }
.sidebar .nav-item:hover { background: rgba(255,255,255,0.05); }
.nav-icon { width: 15px; height: 15px; }

/* ── Cabecera de grupo: icono + nombre + chevron a la derecha ───────────── */
.nav-group-head {
  border-radius: 0;
  height: 34px;
  padding: 0 14px;
  gap: 11px;
  font-size: 12.5px;
  font-weight: 560;
  letter-spacing: 0;
  text-transform: none;
  color: rgba(255,255,255,0.62);
}
.nav-group-head:hover { background: rgba(255,255,255,0.05); color: #fff; }
.nav-group-ico { width: 15px; height: 15px; flex-shrink: 0; opacity: 0.62; }
.nav-group-head:hover .nav-group-ico { opacity: 1; }
.nav-group-nombre { flex: 1; text-align: left; }

/* El chevron apunta abajo abierto y a la izquierda cerrado, como Rentman. */
.nav-group-chevron {
  width: 11px; height: 11px; flex-shrink: 0;
  opacity: 0.45; transform: none;
  transition: transform 0.18s ease, opacity 0.15s ease;
}
.nav-group.cerrado .nav-group-chevron { transform: rotate(-90deg); }
.nav-group-head:hover .nav-group-chevron { opacity: 0.9; }

/* ── Hijos: sangrados y sin icono ───────────────────────────────────────── */
/* Es la diferencia clave con lo que había: el icono lo lleva el padre, y el
   hijo se identifica por la sangría. Con icono en las dos alturas no se
   distinguía el nivel. */
.nav-group-items {
  padding-left: 0; margin-left: 0;
  gap: 0;
  background: rgba(0,0,0,0.16);
}
.nav-group-items .nav-item { padding-left: 40px; height: 32px; font-size: 12.5px; }
.nav-group-items .nav-item .nav-icon { display: none; }
.nav-group-items .nav-item.active { background: var(--sidebar-rojo); }

/* Punto del grupo cerrado con la página activa dentro. */
.nav-group-activo { width: 5px; height: 5px; margin-right: 2px; }

/* ── Barra contraída: los iconos vuelven, sin sangría ni grupos ─────────── */
.sidebar.collapsed .nav-group-items { background: none; }
.sidebar.collapsed .nav-group-items .nav-item { padding: 0; height: 36px; }
.sidebar.collapsed .nav-group-items .nav-item .nav-icon { display: block; }
.sidebar.collapsed .nav-item { height: 36px; }
.sidebar.collapsed .nav-fijos { border-bottom: 1px solid rgba(255,255,255,0.07); }

/* Cabecera del logo, también cuadrada y a juego de alto. */
.sidebar-logo { padding: 0 14px; height: 52px; margin-bottom: 0; }
.logo-mark { width: 28px; height: 28px; border-radius: 0; }
.logo-mark img { width: 22px !important; height: 22px !important; }
.sidebar-collapse-btn { border-radius: 0; }
.sidebar.collapsed .sidebar-collapse-btn { border-radius: 0; }
.sidebar-user { border-radius: 0; }
.sidebar-avatar { border-radius: 0 !important; }

/* ═══════════════════════════════════════════════════════════════════════════
   CONTROLES — modernización global

   Los filtros parecían de 1999 por tres motivos concretos, todos de fondo:

   1. `.filter-select` NO tenía `appearance: none`, así que los 50 <select> de la
      web pintaban el cromo del sistema: en Safari/macOS, la doble flecha con
      bisel. Eso es lo que cantaba.
   2. Llevaban `box-shadow: var(--shadow-xs)`, que sobre un borde de 1px da
      exactamente el relieve de un control de Windows 98.
   3. `.form-group select` sí tenía `appearance: none` pero SIN flecha propia, o
      sea que esos se quedaban sin ninguna pista de que fueran desplegables. Dos
      errores opuestos conviviendo.

   Se arregla en el primitivo, no pantalla por pantalla: una flecha propia en
   SVG, alturas iguales entre <select> e <input> (con `height`, no con padding,
   que en los select se comporta distinto), foco de acento y nada de relieve.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Una sola definición de la flecha, en SVG, del color del texto suave. */
:root {
  --sel-flecha: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 16 16' fill='none' stroke='%238d99ae' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 6.3l4 4 4-4'/%3E%3C/svg%3E");
  --ctrl-alto: 34px;
}

/* ── Todos los desplegables de la app ───────────────────────────────────── */
select.filter-select,
select.form-control,
.form-group select,
.pres-dato select,
.rev-wz-cuerpo select,
.filters-bar select {
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  background-image: var(--sel-flecha);
  background-repeat: no-repeat;
  background-position: right 9px center;
  padding-right: 30px !important;
  cursor: pointer;
  /* Sin relieve: era la mitad del aspecto antiguo. */
  box-shadow: none;
}
/* Firefox pinta el texto del select con un color propio si no se le dice. */
select.filter-select, select.form-control, .form-group select { text-shadow: none; }

/* ── Alturas iguales para que una barra de filtros quede alineada ───────── */
.filters-bar .filter-select,
.filters-bar .filter-input,
.filters-bar .form-control,
.filters-bar select,
.filters-bar input,
.filters-bar .btn {
  height: var(--ctrl-alto);
  padding-top: 0; padding-bottom: 0;
  font-size: 13px;
  border-radius: var(--radius-sm);
  box-shadow: none;
}
.filters-bar { gap: 7px; align-items: center; }

/* ── Aspecto base, limpio ───────────────────────────────────────────────── */
.filter-select, .filter-input, .form-control {
  background-color: var(--surface);
  border: 1px solid var(--border);
  box-shadow: none;
  color: var(--text);
  transition: border-color 0.14s ease, box-shadow 0.14s ease, background-color 0.14s ease;
}
.filter-select:hover, .filter-input:hover, .form-control:hover {
  border-color: var(--border-med);
  background-color: var(--surface);
}
.filter-select:focus, .filter-input:focus, .form-control:focus,
.form-group input:focus, .form-group select:focus, .form-group textarea:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(var(--acento-rgb), 0.13);
  background-color: var(--surface);
}
/* El foco global metía un `border-radius` que rompía la forma del control. */
:where(.btn, .filter-input, .filter-select, .form-control):focus-visible {
  border-radius: var(--radius-sm);
}

/* ── Campos de formulario, mismo lenguaje ───────────────────────────────── */
.form-group input, .form-group select, .form-group textarea {
  /* `background-color` y NO el atajo `background`: el atajo resetea
     `background-image` a `none` y se llevaba por delante la flecha de los
     <select> declarada más arriba. Los selects de los modales se quedaban sin
     ninguna pista de que fueran desplegables. */
  background-color: var(--surface);
  border-color: var(--border);
  border-radius: var(--radius-sm);
  box-shadow: none;
  height: auto;
  min-height: 36px;
}
.form-group textarea { min-height: 76px; padding: 9px 11px; }

/* ── Fechas: el icono nativo del calendario también delataba la edad ───── */
input[type="date"], input[type="time"], input[type="month"] {
  -webkit-appearance: none;
          appearance: none;
}
input[type="date"]::-webkit-calendar-picker-indicator,
input[type="time"]::-webkit-calendar-picker-indicator {
  opacity: 0.4;
  cursor: pointer;
  transition: opacity 0.14s ease;
  filter: grayscale(1);
}
input[type="date"]:hover::-webkit-calendar-picker-indicator,
input[type="time"]:hover::-webkit-calendar-picker-indicator { opacity: 0.85; }

/* ── Números: fuera las flechitas del sistema ──────────────────────────── */
input[type="number"] { -moz-appearance: textfield; }
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

/* ── Casillas y radios: en azul del sistema, ahora del acento ──────────── */
input[type="checkbox"], input[type="radio"] {
  accent-color: var(--accent);
  width: 15px; height: 15px;
  cursor: pointer;
}

/* ── Botones pequeños de acción (los grises de las tablas) ─────────────── */
/* Eran cajas grises con relieve. Ahora: sin fondo, borde de 1px muy suave y
   el color solo al pasar por encima. Dejan de competir con los datos. */
.btn-sm {
  height: 26px;
  padding: 0 9px;
  font-size: 11.5px;
  border-radius: var(--radius-xs);
  box-shadow: none;
}
.btn-ghost.btn-sm {
  background: transparent;
  border-color: var(--border);
  color: var(--text-soft);
  box-shadow: none;
}
.btn-ghost.btn-sm:hover {
  background: var(--bg);
  border-color: var(--border-med);
  color: var(--text);
}
/* Los ghost grandes tampoco necesitan relieve. */
.btn-ghost { box-shadow: none; }
.btn-ghost:hover { box-shadow: none; }

/* ── "Limpiar" y demás acciones de una barra de filtros ───────────────── */
.filters-bar .btn-ghost {
  background: transparent;
  border-color: var(--border);
  color: var(--text-soft);
  font-weight: 550;
}
.filters-bar .btn-ghost:hover {
  background: var(--bg); border-color: var(--border-med); color: var(--text);
}

/* La barra de filtros de vehículos y la del histórico de revisiones usan sus
   propias rejillas; heredan el aspecto pero conservan su reparto. */
.rev-hist-filtros .form-control,
.veh-barra .filter-input { height: var(--ctrl-alto); padding-top: 0; padding-bottom: 0; }
/* Unificar el radio: había controles a 6px (--radius-xs, de una capa anterior) y
   otros a 8px. Un solo radio para todos los campos de la app. */
.filter-select, .filter-input, .form-control,
.form-group input, .form-group select, .form-group textarea,
.pres-dato input, .pres-dato select, .pres-dato textarea {
  border-radius: var(--radius-sm);
}
/* NOTA: el bloque `.pres-tpl-*` (línea ~5160) es CSS del selector de plantillas
   de presupuesto, eliminado el 27/08/2026. Ya no se usa nada; se deja por si se
   reaprovecha para otra rejilla de tarjetas, pero se puede borrar. */

/* ═══════════════════════════════════════════════════════════════════════════
   MENOS ESQUINA REDONDA — "así es más limpio"
   Se bajan los radios de los tokens en vez de ir clase por clase: así cambia
   toda la app de una vez y las proporciones se mantienen coherentes.
   No se pone todo a 0: un 3-4px sigue leyéndose como intencionado y evita el
   aspecto de tabla HTML sin CSS. Lo que era 14px pasa a 4, lo que era 10 a 3.
   ═══════════════════════════════════════════════════════════════════════════ */
:root {
  --radius-lg:  4px;   /* era 14px */
  --radius:     3px;   /* era 10px */
  --radius-sm:  3px;   /* era  8px */
  --radius-xs:  2px;   /* era  6px */
  /* --radius-pill se queda: los chips y las píldoras de estado sí deben ser
     redondos, es lo que los distingue de un botón. */
}

/* Las tarjetas y paneles pierden también la sombra difusa, que acompañaba al
   redondeo. Un borde de 1px define mejor el límite. */
.card, .form-card, .stat-card, .dash-widget, .builder-section,
.veh-plegable, .pk, .pres-datos, .modal {
  box-shadow: none;
  border: 1px solid var(--border);
}
.modal { box-shadow: 0 18px 50px rgba(43,45,66,0.20); }

/* Avatares y puntos de color siguen redondos: son marcas, no contenedores. */
.sidebar-avatar, .emp-avatar, .avatar,
.pk-check, .usr-radio span { border-radius: 0; }
.rev-pend-proy i, .pres-mini-dot, .proy-dot, .gantt-leg-dot,
.veh-alerta-pt, .nav-group-activo, .pk-cat i { border-radius: 50%; }

/* ═══════════════════════════════════════════════════════════════════════════
   PANTALLA DE ACCESO — dos mitades
   Izquierda la marca sobre negro, derecha el formulario sobre blanco. El
   contraste entre las dos mitades es lo que da el efecto; no hace falta una
   foto de stock, y además así no hay que cargar ni servir una imagen grande:
   el fondo es la propia palmera de Palma Pictures a gran tamaño.
   ═══════════════════════════════════════════════════════════════════════════ */

.login-screen {
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  background: var(--surface);
  overflow: hidden;
}

/* ── Mitad izquierda ────────────────────────────────────────────────────── */
.login-marca {
  position: relative;
  display: flex; flex-direction: column; justify-content: space-between;
  padding: 46px 52px;
  background: #08080a;
  overflow: hidden;
  isolation: isolate;
}
/* Un resplandor rojo muy bajo, abajo a la izquierda: rompe el negro plano sin
   convertirse en un degradado de plantilla. */
.login-marca::before {
  content: '';
  position: absolute; z-index: -2;
  left: -18%; bottom: -28%;
  width: 78%; aspect-ratio: 1;
  background: radial-gradient(circle,
    rgba(var(--acento-rgb), 0.30) 0%,
    rgba(var(--acento-rgb), 0.10) 42%,
    transparent 70%);
  pointer-events: none;
}
/* Vela de textura muy fina para que el negro no se vea "digital". */
.login-marca::after {
  content: '';
  position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(160deg, rgba(255,255,255,0.045) 0%, transparent 55%);
  pointer-events: none;
}

.login-marca-palma {
  position: absolute; z-index: -1;
  right: -8%; bottom: -12%;
  width: 62%; max-width: 460px;
  opacity: 0.10;
  pointer-events: none;
}
.login-marca-palma img {
  width: 100%; height: auto; display: block;
  filter: invert(1);                 /* el PNG es la palmera negra */
}

.login-marca-cuerpo { position: relative; }
.login-marca-eyebrow {
  font-size: 11px; font-weight: 700; letter-spacing: 0.16em;
  text-transform: uppercase; color: rgba(255,255,255,0.42);
  margin-bottom: 18px;
}
.login-marca-tit {
  font-family: var(--font-display, inherit);
  font-size: clamp(38px, 5.2vw, 62px);
  line-height: 1.02;
  font-weight: 700;
  letter-spacing: -0.035em;
  color: #fff;
  margin: 0 0 20px;
}
.login-marca-txt {
  max-width: 34ch;
  font-size: 14.5px; line-height: 1.62;
  color: rgba(255,255,255,0.55);
  margin: 0;
}
.login-marca-pie {
  position: relative;
  display: flex; align-items: center; gap: 9px;
  font-size: 12.5px; font-weight: 600; letter-spacing: 0.04em;
  color: rgba(255,255,255,0.4);
}
.login-marca-pie-ico { width: 17px; height: 17px; filter: invert(1); opacity: 0.6; }

/* ── Mitad derecha ──────────────────────────────────────────────────────── */
.login-panel {
  display: flex; align-items: center; justify-content: center;
  padding: 40px 44px;
  background: var(--surface);
}
.login-form-wrap { width: 100%; max-width: 348px; }

.login-form-cab { margin-bottom: 26px; }
.login-form-cab h2 {
  font-size: 25px; font-weight: 700; letter-spacing: -0.025em;
  color: var(--text); margin: 0 0 6px;
}
.login-form-cab p { font-size: 13.5px; color: var(--text-soft); margin: 0; }

.login-campo { display: block; margin-bottom: 15px; }
.login-campo > span {
  display: block; margin-bottom: 6px;
  font-size: 11px; font-weight: 700; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--text-soft);
}
.login-campo input {
  width: 100%; height: 42px; padding: 0 12px;
  background: var(--surface);
  border: 1px solid var(--border-med);
  border-radius: var(--radius-sm);
  font-family: inherit; font-size: 14.5px; color: var(--text);
  transition: border-color 0.14s ease, box-shadow 0.14s ease;
}
.login-campo input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(var(--acento-rgb), 0.13);
}
.login-campo input::placeholder { color: var(--text-xsoft); }

/* Ojo para ver la contraseña */
.login-pass-wrap { position: relative; }
.login-pass-wrap input { padding-right: 42px; }
.login-ver {
  position: absolute; right: 4px; top: 50%; transform: translateY(-50%);
  width: 34px; height: 34px;
  display: flex; align-items: center; justify-content: center;
  background: none; border: 0; border-radius: var(--radius-xs);
  color: var(--text-xsoft); cursor: pointer;
  transition: color 0.14s ease, background 0.14s ease;
}
.login-ver:hover { color: var(--text-soft); background: var(--bg); }
.login-ver.activo { color: var(--accent); }

.login-btn {
  width: 100%; height: 44px; margin-top: 6px;
  background: var(--accent); color: #fff;
  border: 0; border-radius: var(--radius-sm);
  font-family: inherit; font-size: 15px; font-weight: 650;
  cursor: pointer; transition: filter 0.14s ease;
}
.login-btn:hover  { filter: brightness(1.08); }
.login-btn:active { filter: brightness(0.94); }
.login-btn:disabled { opacity: 0.6; cursor: default; }

.login-error {
  margin: 4px 0 12px; padding: 9px 11px;
  background: rgba(var(--acento-rgb), 0.07);
  border-left: 2px solid var(--accent);
  border-radius: 0 var(--radius-xs) var(--radius-xs) 0;
  font-size: 13px; color: var(--accent);
}

.login-ayuda {
  margin-top: 22px; padding-top: 18px;
  border-top: 1px solid var(--border);
  font-size: 12px; line-height: 1.6; color: var(--text-soft);
}
.login-ayuda strong { color: var(--text); font-weight: 600; }

/* ── Estrecho: se apila y la marca queda como cabecera ─────────────────── */
@media (max-width: 900px) {
  .login-screen { grid-template-columns: 1fr; grid-template-rows: auto 1fr; overflow-y: auto; }
  .login-marca { padding: 30px 26px 26px; min-height: 210px; }
  .login-marca-tit { font-size: clamp(30px, 9vw, 40px); }
  .login-marca-txt { display: none; }
  .login-marca-pie { display: none; }
  .login-marca-palma { width: 46%; right: -6%; bottom: -18%; }
  .login-panel { padding: 30px 26px 44px; align-items: flex-start; }
}
/* La regla de la línea ~806 es `#login-screen` (selector de id) y gana a
   `.login-screen` por especificidad, así que seguía en `display:flex` centrando
   las dos mitades como si fueran dos cajas pequeñas. Se repite el id para
   igualar la especificidad. */
#login-screen.login-screen {
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  place-items: stretch;
  align-items: stretch;
  justify-content: stretch;
  padding: 0;
  background: var(--surface);
}
@media (max-width: 900px) {
  #login-screen.login-screen { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   EVENTOS DE LOS CALENDARIOS — rediseño
   Los tres calendarios se quedan claros como estaban. Lo que se rehace son las
   BARRAS de evento, que es lo que se veía mal.

   Qué llevaba cada barra apilado (en los tres calendarios, igual):
     · `border-radius: 0` — píldora, cuando se pidió cuadrado;
     · `box-shadow: inset 0 -1px 0 rgba(0,0,0,.12)` — un bisel falso abajo;
     · un `::after` con degradado blanco encima — brillo de botón de 2008;
     · `text-shadow: 0 1px 3px rgba(0,0,0,.4)` — para tapar que el texto no
       contrastaba, en vez de arreglar el color del texto;
     · `box-shadow: var(--shadow-sm)` al pasar el ratón;
     · una marca vertical blanca translúcida al inicio del tramo.
   Seis efectos para pintar un rectángulo de color.

   Ahora: relleno plano, esquina viva, y el contraste resuelto de verdad por
   luminancia (clase `txt-oscuro`, que ya calculaba el JS y solo usaba uno de
   los tres calendarios). La legibilidad sale del color del texto, no de una
   sombra que lo emborrona.
   ═══════════════════════════════════════════════════════════════════════════ */
:root { --cal-bar-radius: 0px; }

/* ── Base común a las barras de los tres calendarios ───────────────────── */
.gantt-bar,
.proy-cal-barra-p,
.cal-veh-td-day .cal-cell-inner.filled {
  border-radius: 0;
  box-shadow: none;
  transition: filter 0.14s ease, outline-color 0.14s ease;
}
/* Fuera el brillo de degradado del gantt */
.gantt-bar::after { display: none !important; }

/* Al pasar el ratón: solo brillo, y un contorno fino que no descoloca nada
   (una sombra desplazaba visualmente la barra respecto a su día). */
.gantt-bar:hover,
.proy-cal-barra-p:hover {
  filter: brightness(1.06);
  box-shadow: none;
  outline: 1px solid rgba(255,255,255,0.55);
  outline-offset: -1px;
}

/* ── Texto: contraste de verdad, sin sombras ───────────────────────────── */
.gantt-bar-txt,
.proy-cal-barra-txt,
.cal-run-label,
.cal-proy-sub {
  text-shadow: none;
}
.gantt-bar, .proy-cal-barra-p { color: #fff; }
/* Sobre un color claro (amarillo, beis, gris claro) el texto pasa a tinta. */
.gantt-bar.txt-oscuro, .gantt-bar.txt-oscuro .gantt-bar-txt,
.proy-cal-barra-p.txt-oscuro, .proy-cal-barra-p.txt-oscuro .proy-cal-barra-txt {
  color: #17181f;
}
.proy-cal-barra-txt { color: inherit; }
.gantt-bar-txt, .proy-cal-barra-txt {
  font-size: 11px; font-weight: 650; letter-spacing: -0.005em;
}
.cal-run-label { font-size: 11.5px; font-weight: 680; letter-spacing: -0.005em; }
.cal-proy-sub  { font-size: 10px;  font-weight: 550; opacity: 0.9; }
/* `.cal-veh-table .cal-proy-sub` (líneas 5330 y 5603) es más específico que la
   clase sola, así que su `text-shadow` ganaba. Se igualan los selectores. */
.cal-veh-table .cal-run-label,
.cal-veh-table .cal-proy-sub,
.cal-veh-table .cal-run-label:not(.cal-proy-sub) { text-shadow: none; }

/* ── Marca de inicio de tramo ──────────────────────────────────────────── */
/* Una franja sólida más oscura del propio color, no un blanco translúcido:
   funciona sobre cualquier tono y no ensucia el relleno. */
.cal-veh-td-day.cal-run-start .cal-cell-inner::before,
.cal-veh-td-day.cal-run-solo .cal-cell-inner::before {
  width: 3px;
  background: rgba(0,0,0,0.30);
  border-radius: 0;
}
.cal-veh-td-day.cal-run-start .cal-cell-inner.txt-oscuro::before,
.cal-veh-td-day.cal-run-solo  .cal-cell-inner.txt-oscuro::before {
  background: rgba(0,0,0,0.20);
}

/* ── Tramos: esquinas vivas y separación de 1px entre eventos seguidos ─── */
.cal-veh-td-day.cal-run-solo .cal-cell-inner,
.cal-veh-td-day.cal-run-start .cal-cell-inner,
.cal-veh-td-day.cal-run-mid .cal-cell-inner,
.cal-veh-td-day.cal-run-end .cal-cell-inner {
  border-radius: 0;
  box-shadow: none;
}
/* Los márgenes laterales dejaban huecos de 3px dentro del propio tramo. El
   tramo pasa a ser continuo y el corte se marca solo al principio y al final. */
.cal-veh-td-day.cal-run-solo  .cal-cell-inner { margin: 0 1px; }
.cal-veh-td-day.cal-run-start .cal-cell-inner { margin: 0 0 0 1px; }
.cal-veh-td-day.cal-run-end   .cal-cell-inner { margin: 0 1px 0 0; }
/* Aire vertical. OJO: aquí había `align-self: center`, y como `.cal-cell-wrap`
   es un flex en COLUMNA, el eje transversal es el horizontal — así que centrar
   encogía la barra al ancho de su contenido. Los tramos `mid` se salvaban por
   tener `width: 100%` explícito, pero los de inicio y fin se quedaban en 7px:
   un evento de tres días se pintaba como astilla + bloque + astilla.
   El aire se da con padding en el contenedor, que no toca la alineación. */
.cal-veh-td-day .cal-cell-wrap { padding: 4px 0; }
.cal-veh-td-day .cal-cell-inner.filled { align-self: stretch; }
/* Los tramos de inicio y fin ocupan su celda entera, como los del centro.
   OJO con el eje: `.cal-cell-wrap` es un flex en COLUMNA, así que
     · el ANCHO se controla con `align-self` (eje transversal),
     · el ALTO se controla con `flex` (eje principal).
   Aquí había `flex: 1 1 auto`, que arreglaba el ancho de rebote pero hacía
   CRECER en vertical: el inicio y el fin salían a 52px de alto y el centro a 36,
   o sea un bloque más gordo en los dos extremos de cada tramo. */
.cal-veh-td-day.cal-run-start .cal-cell-inner,
.cal-veh-td-day.cal-run-end   .cal-cell-inner,
.cal-veh-td-day.cal-run-solo  .cal-cell-inner {
  flex: 0 0 auto;        /* no crecer en alto */
  align-self: stretch;   /* sí ocupar todo el ancho */
  width: auto;
}

/* Y una sola altura para los tres tipos de tramo, para que un evento se lea como
   una barra continua y no como bloques de distinto grosor. */
.cal-veh-td-day .cal-cell-inner.filled,
.cal-veh-td-day.cal-run-start .cal-cell-inner,
.cal-veh-td-day.cal-run-mid   .cal-cell-inner,
.cal-veh-td-day.cal-run-end   .cal-cell-inner,
.cal-veh-td-day.cal-run-solo  .cal-cell-inner {
  height: 34px;
  min-height: 0;
}

/* Los rellenos laterales de inicio (7-8px) y fin (6px) eran para el texto cuando
   iba en el flujo. Ahora la etiqueta va posicionada y centrada en el tramo, así
   que ese padding solo desplazaba el bloque dentro de su casilla. */
.cal-veh-td-day.cal-run-start .cal-cell-inner,
.cal-veh-td-day.cal-run-end   .cal-cell-inner,
.cal-veh-td-day.cal-run-solo  .cal-cell-inner { padding-left: 0; padding-right: 0; }

.cal-veh-row:hover .cal-cell-inner.filled {
  box-shadow: none;
  filter: brightness(1.05);
}

/* ── Continuación fuera de rango (calendario de proyectos) ─────────────── */
/* El borde de puntos blanco se veía sucio. Una muesca en diagonal dice "sigue"
   mucho mejor y no añade color. */
.proy-cal-barra-p.corta-izq, .proy-cal-barra-p.corta-der,
.proy-cal-barra-p.corta-izq.corta-der { border-radius: 0; border-left: 0; border-right: 0; }
.proy-cal-barra-p.corta-izq {
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 7px);
          mask-image: linear-gradient(to right, transparent 0, #000 7px);
}
.proy-cal-barra-p.corta-der {
  -webkit-mask-image: linear-gradient(to left, transparent 0, #000 7px);
          mask-image: linear-gradient(to left, transparent 0, #000 7px);
}
.proy-cal-barra-p.corta-izq.corta-der {
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 7px, #000 calc(100% - 7px), transparent 100%);
          mask-image: linear-gradient(to right, transparent 0, #000 7px, #000 calc(100% - 7px), transparent 100%);
}

/* ── Alturas y aire ───────────────────────────────────────────────────── */
.gantt-bar { top: 5px; bottom: 5px; padding: 0 8px; }
.proy-cal-barra-p { top: 7px; bottom: 7px; padding: 0 8px; }
/* Un proyecto acabado se atenúa, pero no tanto que no se lea. */
.proy-cal-barra-p.fin { opacity: 0.55; }
/* La línea 5604 usa `.cal-veh-table .cal-cell-inner:not(.txt-oscuro) .cal-run-label`
   — tres clases y un `:not()` — y gana a cualquier selector más corto. Se repite
   la forma exacta para poder quitarle la sombra.
   La sombra estaba ahí para que el blanco se leyera sobre colores medios, pero
   eso ya lo resuelve `txt-oscuro` eligiendo el color del texto por luminancia:
   la sombra solo emborronaba las letras. */
.cal-veh-table .cal-cell-inner:not(.txt-oscuro) .cal-run-label,
.cal-veh-table .cal-cell-inner:not(.txt-oscuro) .cal-proy-sub {
  text-shadow: none;
}
/* Filas de presupuesto en economía: la fila entera lleva al presupuesto, así que
   tiene que parecerlo. */
.eco-fila-pres { cursor: pointer; transition: background var(--transition); }
.eco-fila-pres:hover { background: rgba(var(--acento-rgb), 0.04); }
.eco-fila-pres:hover a { text-decoration: underline; }

/* ═══════════════════════════════════════════════════════════════════════════
   LUZ DE LA BARRA LATERAL — la palmera se enciende bajo el cursor
   La marca de agua estaba al 5 % y en hover subía al 9 %: no se notaba. Subirla
   más ensucia el menú, así que en vez de iluminar TODO se ilumina solo el
   círculo donde está el cursor. La palmera aparece y desaparece al pasar por
   encima, como si la enfocaras con una linterna.
   ═══════════════════════════════════════════════════════════════════════════ */
.sidebar { --luz-x: 50%; --luz-y: 60%; }

.sidebar-luz {
  position: absolute; inset: 0;
  z-index: 0;                 /* debajo de .sidebar-nav, que va en z-index: 1 */
  pointer-events: none;
  display: flex;
  align-items: center; justify-content: center;
  opacity: 0;
  transition: opacity 0.42s ease;
  /* El círculo que revela. Se mueve con las dos variables que pone el JS. */
  -webkit-mask-image: radial-gradient(210px 210px at var(--luz-x) var(--luz-y),
                        #000 0%, rgba(0,0,0,0.55) 42%, transparent 72%);
          mask-image: radial-gradient(210px 210px at var(--luz-x) var(--luz-y),
                        #000 0%, rgba(0,0,0,0.55) 42%, transparent 72%);
}
.sidebar.con-luz .sidebar-luz { opacity: 1; }

.sidebar-luz img {
  width: 116%;                /* grande y desbordando: se ve "dentro" de la barra */
  max-width: none;
  height: auto;
  filter: invert(1);          /* el PNG es la palmera negra */
  opacity: 0.17;
  transform: translateY(2%);
}

/* Un tinte rojo muy leve en el mismo círculo: ata el efecto a la marca sin
   pintar la barra de rojo. */
.sidebar-luz::after {
  content: '';
  position: absolute; inset: 0;
  background: radial-gradient(200px 200px at var(--luz-x) var(--luz-y),
                rgba(var(--acento-rgb), 0.10) 0%,
                rgba(var(--acento-rgb), 0.03) 45%,
                transparent 70%);
}

/* Plegada la barra mide 64px: el círculo se reduce para no ser una mancha. */
.sidebar.collapsed .sidebar-luz {
  -webkit-mask-image: radial-gradient(120px 120px at var(--luz-x) var(--luz-y),
                        #000 0%, transparent 72%);
          mask-image: radial-gradient(120px 120px at var(--luz-x) var(--luz-y),
                        #000 0%, transparent 72%);
}
.sidebar.collapsed .sidebar-luz img { width: 200%; opacity: 0.14; }

/* Sin luz, la marca de agua de la esquina sigue como estaba. */
.sidebar.con-luz .sidebar-palm-watermark { opacity: 0.05; }

@media (prefers-reduced-motion: reduce) {
  .sidebar-luz { display: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   CALENDARIO DE FLOTA — limpieza al estilo de la referencia (Jira Timeline)
   Qué lo hacía ilegible:
     · una línea vertical por CADA día → 31 líneas, una reja;
     · columnas de 54px, así que solo cabían 7 días y no se veía el mes;
     · dos filas de cabecera (semana + día) más la letra del día: tres etiquetas
       por columna;
     · 26 filas seguidas sin ninguna jerarquía;
     · una barra de navegación arriba robando una franja de alto.

   Lo que hace limpia la referencia y se ha copiado: pocas líneas, columnas
   estrechas para ver el rango entero, grupos plegables con una banda que dice
   qué hay dentro, y el mando flotando abajo a la derecha.
   ═══════════════════════════════════════════════════════════════════════════ */

#page-veh-calendar { position: relative; }
.cal-veh-mes {
  font-size: 14px; font-weight: 600; color: var(--text-soft);
  margin-left: 14px; letter-spacing: -0.01em;
}

/* ── La reja se va: solo una línea por semana (los lunes) ───────────────── */
.cal-veh-td-day, .cal-veh-th-day { border-right: 0 !important; }
.cal-veh-td-day.cal-lunes, .cal-veh-th-day.cal-lunes {
  box-shadow: inset 1px 0 0 var(--border-med);
}
/* El fin de semana se marca con un tinte, no con bordes. */
.cal-veh-td-day.cal-weekend { background: rgba(43,45,66,0.028); }
.cal-veh-th-day.cal-weekend { background: rgba(43,45,66,0.02); }

/* ── Cabecera: una sola etiqueta por columna ────────────────────────────── */
.cal-veh-th-day { padding: 0; height: 30px; }
.cal-day-num {
  font-size: 10px; font-weight: 500; color: var(--text-xsoft);
  font-variant-numeric: tabular-nums;
}
.cal-veh-th-day.cal-lunes .cal-day-num { font-weight: 750; color: var(--text-soft); }
.cal-veh-th-day.cal-today-col .cal-day-num { color: #fff; font-weight: 750; }
.cal-day-name { display: none; }          /* la letra del día sobra con 31 columnas */
/* La banda de semanas se queda pero mucho más discreta. */
.cal-veh-th-week-row th { height: 20px; }
.cal-week-label { font-size: 9px; font-weight: 650; letter-spacing: 0.07em; opacity: 0.55; }

/* ── Columna de vehículo: más ligera ───────────────────────────────────── */
.cal-veh-name { font-size: 12.5px; font-weight: 620; }
.cal-veh-mat  { font-size: 10px; opacity: 0.7; }
.cal-veh-logo-cell { transform: scale(0.86); transform-origin: left center; }
.cal-veh-td-veh, .cal-veh-th-veh { padding-left: 10px; padding-right: 8px; }

/* ── Filas: ritmo constante y sin cebra (la cebra con 31 columnas vibra) ── */
.cal-veh-row { height: 42px; }
.cal-veh-row.cal-row-alt { background: transparent; }
.cal-veh-table tbody tr { border-bottom: 1px solid var(--border); }
.cal-veh-row:hover { background: rgba(43,45,66,0.02); }

/* ── Cabecera de grupo ─────────────────────────────────────────────────── */
.cal-grupo td { background: var(--bg); border-bottom: 1px solid var(--border-med); }
.cal-grupo-cab {
  position: sticky; left: 0; z-index: 8;
  display: flex; align-items: center; gap: 8px;
  height: 34px; padding: 0 10px;
  background: var(--bg) !important;
  cursor: pointer; user-select: none;
  box-shadow: inset -1px 0 0 var(--border-med);
}
.cal-grupo-cab:hover { background: var(--border) !important; }
.cal-grupo-chev {
  display: flex; flex-shrink: 0; color: var(--text-soft);
  transform: rotate(90deg);
  transition: transform 0.18s ease;
}
.cal-grupo.cerrado .cal-grupo-chev { transform: none; }
.cal-grupo-nom {
  flex: 1; font-size: 11px; font-weight: 750; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--text-2, var(--text));
}
.cal-grupo-n {
  flex-shrink: 0; font-size: 10px; font-weight: 700;
  font-variant-numeric: tabular-nums; color: var(--text-xsoft);
  background: var(--surface); padding: 1px 6px; border-radius: var(--radius-pill);
}
/* Banda de proyectos del grupo: el equivalente a los "sprints" de la
   referencia. Dice qué hay dentro sin tener que desplegarlo. */
.cal-grupo-banda {
  padding: 0 10px; white-space: nowrap; overflow: hidden;
  background: var(--bg) !important;
}
.cal-grupo-chip {
  display: inline-flex; align-items: center;
  height: 18px; padding: 0 7px; margin-right: 4px;
  border-left: 3px solid var(--c, var(--text-soft));
  background: var(--surface);
  font-size: 10px; font-weight: 620; color: var(--text-2, var(--text));
  max-width: 130px; overflow: hidden; text-overflow: ellipsis;
}
.cal-grupo-chip.cal-grupo-mas { border-left-color: transparent; color: var(--text-xsoft); }

/* ── Mando flotante ────────────────────────────────────────────────────── */
.cal-mando {
  position: absolute; right: 18px; bottom: 18px; z-index: 30;
  display: flex; align-items: center; gap: 2px;
  padding: 4px;
  background: var(--surface);
  border: 1px solid var(--border-med);
  border-radius: var(--radius-pill);
  box-shadow: 0 6px 20px rgba(43,45,66,0.16);
}
.cal-mando button {
  height: 28px; min-width: 28px; padding: 0 8px;
  display: inline-flex; align-items: center; justify-content: center;
  background: none; border: 0; border-radius: var(--radius-pill);
  font-family: inherit; font-size: 12px; font-weight: 620; color: var(--text-soft);
  cursor: pointer; transition: background var(--transition), color var(--transition);
}
.cal-mando button:hover { background: var(--bg); color: var(--text); }
.cal-mando-hoy { padding: 0 11px !important; }
.cal-mando-sep { width: 1px; height: 18px; background: var(--border-med); margin: 0 3px; }
.cal-mando-plegar svg { transition: transform 0.18s ease; }
.cal-mando-plegar.plegado svg { transform: rotate(-90deg); }

@media (max-width: 900px) {
  .cal-mando { right: 12px; bottom: 12px; }
}
/* Con `table-layout: auto` (el defecto) el ANCHO lo decide el contenido, así que
   las etiquetas de los eventos (`white-space: nowrap`) ensanchaban las columnas
   y el `<colgroup>` de 31px se ignoraba: la tabla medía 2120px en vez de 1147 y
   el mes no cabía nunca. Con `fixed`, el colgroup manda. */
.cal-veh-table { table-layout: fixed; }
/* Los `min-width: 62px` de las líneas 2839 y 2923 ganan al `colgroup` y al
   `table-layout: fixed`: son lo que mantenía la tabla en 2120px. */
.cal-veh-th-day, .cal-veh-td-day { min-width: 32px; }

/* La etiqueta del tramo SÍ puede salir de su casilla: un tramo son varias
   casillas seguidas con el mismo fondo, así que el texto se lee sobre el propio
   tramo. Si se recortara a 32px no cabría ni una palabra. */
.cal-veh-td-day { overflow: visible; }
.cal-cell-inner { min-width: 0; overflow: visible; }
.cal-run-label, .cal-proy-sub {
  max-width: none;
  /* El texto se centra en la casilla del medio del tramo y crece hacia los dos
     lados sin empujar nada, porque no participa en el flujo. */
  position: absolute; left: 50%; transform: translateX(-50%);
  pointer-events: none;
}
/* Con dos líneas (conductor + proyecto) hay que separarlas a mano, ya que las
   dos están posicionadas. */
.cal-cell-inner.con-label .cal-run-label:not(.cal-proy-sub) { top: 7px; }
.cal-cell-inner.con-label .cal-proy-sub { bottom: 7px; }
/* Un tramo de un solo día no muestra etiqueta (no cabe): la info va en el
   tooltip, que ya la tiene completa. */
.cal-veh-td-day.cal-run-solo .cal-run-label { display: none; }
/* El contenedor NO recorta: la etiqueta del evento está posicionada y tiene que
   poder salir de su casilla para ocupar el tramo entero. El relleno no necesita
   recorte porque mide exactamente lo que su casilla (`align-self: stretch`). */
.cal-cell-wrap { overflow: visible; }
.cal-cell-inner.filled { overflow: visible; }
/* La línea de semana no se dibuja sobre un evento: un tramo de 12 días tiene que
   leerse como UNA barra, no como bloques cortados cada lunes. La rejilla va
   detrás de las barras, como en la referencia. */
.cal-veh-td-day.cal-lunes.cal-assigned { box-shadow: none; }
/* Pero el inicio de un tramo que cae en lunes sí conserva su marca, que es la
   que dice dónde empieza. */
.cal-veh-td-day.cal-lunes.cal-run-start { box-shadow: inset 1px 0 0 var(--border-med); }

/* ═══════════════════════════════════════════════════════════════════════════
   TEXTO DE LOS EVENTOS — estilo Apple Calendar
   Lo que hace legible el texto de Apple y aquí no estaba:
     · arranca en el BORDE IZQUIERDO del evento, no centrado. Centrado, en una
       barra de 12 días, el texto queda a 6 días del principio y hay que buscar
       con la vista dónde empieza la reserva;
     · cuerpo de verdad (12.5px) y peso medio-alto, no 11px light;
     · dos alturas de texto con jerarquía clara: título y dato secundario;
     · el recorte lo hace el navegador con puntos suspensivos sobre el ancho real
       del tramo, no un contador de caracteres (una "i" y una "W" no miden igual).
   ═══════════════════════════════════════════════════════════════════════════ */

.cal-ev-txt {
  position: absolute;
  left: 7px; top: 50%;
  transform: translateY(-50%);
  display: flex; flex-direction: column;
  gap: 0;
  /* Ancho real del tramo: días × ancho de columna (que publica
     _calMedirColumna) menos el margen del principio y un poco de aire. */
  max-width: calc(var(--cal-col-w, 32px) * var(--run-len, 1) - 14px);
  min-width: 0;
  z-index: 2;
  line-height: 1.18;
  overflow: hidden;
}

.cal-ev-tit {
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: -0.012em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cal-ev-sub {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: -0.006em;
  opacity: 0.82;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* El conductor sigue siendo clicable para editarlo, así que necesita puntero y
   una pista al pasar por encima — pero sin la píldora de antes, que competía
   con el título. */
.cal-ev-sub.cal-cond-chip,
.cal-ev-sub.cal-cond-add {
  background: none !important;
  border: 0 !important;
  padding: 0 !important;
  margin: 0 !important;
  pointer-events: auto;
  cursor: pointer;
  text-decoration-color: transparent;
  transition: opacity 0.14s ease;
}
.cal-ev-sub.cal-cond-chip:hover { opacity: 1; text-decoration: underline; }
.cal-ev-sub.cal-cond-add { opacity: 0.6; font-style: italic; }
.cal-ev-sub.cal-cond-add:hover { opacity: 0.95; }

/* Un solo día: no hay sitio para dos líneas, solo el título y en 11px. */
.cal-veh-td-day.cal-run-solo .cal-ev-txt { left: 4px; max-width: calc(var(--cal-col-w, 32px) - 8px); }
.cal-veh-td-day.cal-run-solo .cal-ev-tit { font-size: 11px; }
.cal-veh-td-day.cal-run-solo .cal-ev-sub { display: none; }

/* Las etiquetas viejas ya no se emiten; si quedara alguna, que no estorbe. */
.cal-run-label:not(.cal-ev-tit):not(.cal-ev-sub) { position: static; transform: none; }
/* `.cal-veh-table .cal-cell-inner.con-label > *` (dos clases y un combinador)
   gana a `.cal-ev-txt` por especificidad y le ponía `max-width: none` y
   `overflow: visible`, así que el ancho calculado del tramo no se aplicaba y el
   texto se cortaba a 39px. Se repite la forma del selector para superarla. */
.cal-veh-table .cal-cell-inner.con-label > .cal-ev-txt {
  max-width: calc(var(--cal-col-w, 32px) * var(--run-len, 1) - 14px);
  overflow: hidden;
}
.cal-veh-table .cal-cell-inner.con-label > .cal-ev-txt > .cal-ev-tit,
.cal-veh-table .cal-cell-inner.con-label > .cal-ev-txt > .cal-ev-sub {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cal-veh-td-day.cal-run-solo .cal-veh-table .cal-cell-inner.con-label > .cal-ev-txt,
.cal-veh-table .cal-veh-td-day.cal-run-solo .cal-cell-inner.con-label > .cal-ev-txt {
  max-width: calc(var(--cal-col-w, 32px) - 8px);
}

/* ═══════════════════════════════════════════════════════════════════════════
   CAPA — DEPARTAMENTOS EN LA FICHA DE PROYECTO
   Tarjeta por departamento con barra proporcional al que más factura. Cuadrado
   y en gris como el resto: el color solo aparece en el punto de identidad.
   ═══════════════════════════════════════════════════════════════════════════ */
.dep-cards { display: flex; flex-direction: column; gap: 6px; }

.dep-card { border: 1px solid var(--border); background: var(--surface); }
.dep-card.abierta { border-color: var(--text-soft); }

.dep-card-cab {
  display: grid;
  grid-template-columns: 8px minmax(0, 1fr) auto auto;
  align-items: center; gap: 10px;
  width: 100%; padding: 9px 11px;
  background: none; border: 0; cursor: pointer; text-align: left;
  font: inherit; color: var(--text);
}
.dep-card-cab:hover { background: var(--surface-2); }
.dep-card-punto { width: 8px; height: 8px; }
.dep-card-nom { min-width: 0; font-weight: 600; font-size: 13px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dep-card-sub { display: block; font-weight: 400; font-size: 11px; color: var(--text-soft); }
.dep-card-n {
  min-width: 22px; padding: 1px 6px; text-align: center;
  font-size: 11px; color: var(--text-2); background: var(--surface-2);
}
.dep-card-eur { font-variant-numeric: tabular-nums; font-size: 13px; font-weight: 600; }

.dep-card-barra { height: 2px; background: var(--surface-2); }
.dep-card-barra > span { display: block; height: 100%; background: var(--text-soft); }

.dep-detalle { padding: 8px 11px 10px; border-top: 1px solid var(--border); }
.dep-detalle-acciones {
  display: flex; align-items: center; gap: 12px; margin-top: 8px;
  padding-top: 8px; border-top: 1px solid var(--border);
}
.fleet-link.dep-borrar { color: var(--red); }

.dep-sueltos-tit {
  margin: 14px 0 6px; font-size: 11px; text-transform: uppercase;
  letter-spacing: .04em; color: var(--text-soft);
}
.dep-total {
  display: flex; align-items: baseline; gap: 10px;
  margin-top: 14px; padding-top: 10px; border-top: 1px solid var(--border);
  font-size: 13px; font-weight: 600;
}
.dep-total-n { margin-left: auto; font-weight: 400; font-size: 12px; color: var(--text-soft); }
.dep-total-eur { font-variant-numeric: tabular-nums; }

/* Modal de alta en lote */
.dep-modal-nota { margin: 0 0 10px; font-size: 12px; color: var(--text-soft); }
.dep-modal-lista { display: flex; flex-direction: column; gap: 2px; max-height: 340px; overflow-y: auto; }
.dep-op {
  display: flex; align-items: center; gap: 9px;
  padding: 7px 9px; cursor: pointer; font-size: 13px;
  border: 1px solid transparent;
}
.dep-op:hover { background: var(--surface-2); }
.dep-op.ya { cursor: default; color: var(--text-soft); }
.dep-op.ya:hover { background: none; }
.dep-op-nom { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dep-op-ya { margin-left: auto; font-size: 11px; color: var(--text-soft); }

/* ═══════════════════════════════════════════════════════════════════════════
   CAPA — FILTROS DEL REGISTRO DE ACTIVIDAD
   Chips por área arriba (con su contador, que es lo que dice de un vistazo
   dónde ha pasado algo) y la letra pequeña de los filtros debajo.
   ═══════════════════════════════════════════════════════════════════════════ */
.act-filtros { margin-bottom: 16px; }

.act-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.act-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 10px; font: inherit; font-size: 12.5px;
  color: var(--text-2); background: var(--surface);
  border: 1px solid var(--border); cursor: pointer;
}
.act-chip:hover { background: var(--surface-2); color: var(--text); }
.act-chip.sel { background: var(--text); border-color: var(--text); color: var(--surface); }
.act-chip > i {
  font-style: normal; font-size: 11px; font-variant-numeric: tabular-nums;
  color: var(--text-soft);
}
.act-chip.sel > i { color: var(--surface); opacity: .7; }

.act-filtros-fila {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
}
.act-filtros-fila .form-control { width: auto; min-width: 150px; font-size: 12.5px; padding: 5px 9px; }
.act-filtros-fila .act-busca { flex: 1 1 240px; min-width: 200px; }

/* Etiqueta de área dentro de cada apunte: es un botón, filtra por esa área. */
.act-area {
  padding: 1px 6px; font: inherit; font-size: 11px;
  color: var(--text-2); background: var(--surface-2);
  border: 1px solid var(--border); cursor: pointer;
}
.act-area:hover { color: var(--text); border-color: var(--text-soft); }
.act-verbo-borrar {
  padding: 1px 6px; font-size: 11px;
  color: var(--red); border: 1px solid currentColor;
}

/* ═══════════════════════════════════════════════════════════════════════════
   CAPA — CREW (personas y permisos)
   La tabla de seis columnas no aguantaba nueve áreas: cada persona es ahora una
   tarjeta con su puesto y SOLO las áreas donde tiene acceso. Lo que no sale es
   lo que no puede — leer ausencias es más rápido que leer nueves "ninguno".
   ═══════════════════════════════════════════════════════════════════════════ */
.crew-barra {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 14px;
}
.crew-barra .form-control { width: auto; font-size: 12.5px; padding: 6px 9px; }
.crew-busca { flex: 1 1 260px; min-width: 200px; }
.crew-cuenta { margin-left: auto; font-size: 12px; color: var(--text-soft); }

.crew-cards {
  display: grid; gap: 10px;
  grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
}

.crew-card {
  display: flex; flex-direction: column; gap: 10px;
  padding: 13px; background: var(--surface); border: 1px solid var(--border);
}
.crew-card.baja { opacity: .55; }

.crew-card-cab { display: flex; align-items: center; gap: 10px; }
.crew-avatar {
  flex: 0 0 auto; width: 34px; height: 34px;
  display: grid; place-items: center;
  font-size: 12px; font-weight: 600; letter-spacing: .02em;
  color: var(--text-2); background: var(--surface-2); border: 1px solid var(--border);
}
.crew-avatar.es-admin { color: var(--surface); background: var(--text); border-color: var(--text); }
.crew-ident { min-width: 0; flex: 1; }
.crew-nombre {
  font-size: 13.5px; font-weight: 600; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.crew-user { font-size: 11.5px; color: var(--text-soft); }
.crew-baja-tag { font-size: 11px; font-weight: 400; color: var(--red); }
.crew-puesto {
  flex: 0 0 auto; padding: 2px 7px; font-size: 11px;
  color: var(--text-2); background: var(--surface-2); border: 1px solid var(--border);
}
.crew-puesto.es-admin { color: var(--surface); background: var(--text); border-color: var(--text); }

.crew-acceso { display: flex; flex-wrap: wrap; gap: 4px; }
.crew-area {
  display: inline-flex; align-items: baseline; gap: 5px;
  padding: 2px 7px; font-size: 11.5px;
  color: var(--text); background: var(--surface-2);
  border: 1px solid var(--border);
}
.crew-area > i { font-style: normal; font-size: 10px; color: var(--text-soft); }
/* El nivel se marca con el borde izquierdo, no con el fondo: siete etiquetas de
   colores distintos convierten la tarjeta en un semáforo ilegible. */
.crew-niv-lectura { border-left: 2px solid var(--text-soft); }
.crew-niv-edicion { border-left: 2px solid var(--text-2); }
.crew-niv-total   { border-left: 2px solid var(--text); }

.crew-todo, .crew-sin { font-size: 12px; color: var(--text-soft); }
.crew-sin { color: var(--red); }

.crew-caps { display: flex; flex-wrap: wrap; gap: 4px; }
.crew-cap {
  padding: 1px 6px; font-size: 10.5px; color: var(--text-soft);
  border: 1px dashed var(--border);
}

.crew-acciones {
  display: flex; align-items: center; gap: 8px;
  margin-top: auto; padding-top: 9px; border-top: 1px solid var(--border);
}
.crew-baja-btn:hover { color: var(--red); }
.crew-nota { font-size: 11px; color: var(--text-soft); }

/* ── Matriz de permisos: grupos ── */
.usr-matriz-grupo { margin-top: 10px; }
.usr-matriz-grupo-tit {
  display: flex; align-items: center; gap: 10px;
  padding: 5px 0; margin-bottom: 2px;
  font-size: 11px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--text-soft); border-bottom: 1px solid var(--border);
}
.usr-grupo-todo {
  padding: 0; font: inherit; font-size: 10.5px; text-transform: none; letter-spacing: 0;
  color: var(--text-soft); background: none; border: 0; cursor: pointer;
  text-decoration: underline; text-underline-offset: 2px;
}
.usr-grupo-todo:hover { color: var(--text); }
.usr-grupo-todo:first-of-type { margin-left: auto; }

.usr-cap-ui {
  margin-left: auto; padding: 1px 6px; font-size: 10px;
  color: var(--text-soft); border: 1px dashed var(--border); cursor: help;
}

/* Área deducida del texto (apuntes anteriores al registro por ruta): se marca
   con borde discontinuo y una interrogación. Presentarla igual que la que puso
   el servidor sería vender como exacto algo que es una suposición. */
.act-area.inferida { border-style: dashed; }
.act-area.inferida > i { font-style: normal; margin-left: 3px; opacity: .55; }

/* La cabecera de columnas se repite por grupo (ver app.js): sticky no agarraba
   porque quien hace scroll es el modal, no la matriz. Repetida, se aligera para
   que no compita con el título del grupo. */
.usr-matriz-grupo .usr-matriz-cab { padding-top: 2px; padding-bottom: 2px; opacity: .75; }

/* ═══════════════════════════════════════════════════════════════════════════
   CAPA — PESTAÑAS

   `.main` pasa a ser una columna: la barra arriba, fija, y el contenido
   desplazándose debajo. Antes `.main` era el propio contenedor con scroll y el
   padding; ahora eso lo hace `.main-scroll`, para que la barra no se vaya hacia
   arriba justo cuando hace falta para cambiar de sitio.
   ═══════════════════════════════════════════════════════════════════════════ */
.main {
  display: flex; flex-direction: column;
  overflow: hidden;           /* quien hace scroll ahora es .main-scroll */
  padding: 0;
}
.main-scroll {
  flex: 1; min-height: 0;     /* sin esto un hijo alto desborda en vez de scrollear */
  overflow-y: auto;
  padding: 28px 30px;
}

.tabbar {
  display: flex; align-items: stretch; gap: 1px;
  flex: 0 0 auto;
  padding: 0 10px;
  background: var(--surface-2);
  border-bottom: 1px solid var(--border);
  overflow-x: auto; overflow-y: hidden;
  scrollbar-width: none;
}
.tabbar::-webkit-scrollbar { display: none; }
.tabbar:empty { display: none; }

.tab {
  display: flex; align-items: center; gap: 8px;
  /* Se encogen para que quepan más, pero con suelo: por debajo de ~110px el
     título se convierte en "Proye…" y la pestaña deja de servir para nada.
     Pasado ese punto es mejor que la barra desplace. */
  flex: 0 1 auto; min-width: 110px; max-width: 230px;
  padding: 8px 8px 8px 13px;
  font-size: 12.5px; color: var(--text-2);
  background: transparent;
  border-right: 1px solid var(--border);
  cursor: pointer; user-select: none;
  position: relative;
}
.tab:hover { background: var(--bg-hover); color: var(--text); }

/* La activa se pinta como la hoja de delante: mismo fondo que el contenido y
   una banda arriba. Sin la banda, con fondos tan claros, no se distingue. */
.tab.activa {
  background: var(--surface);
  color: var(--text);
  font-weight: 600;
}
.tab.activa::before {
  content: ''; position: absolute; left: 0; right: 0; top: 0; height: 2px;
  background: var(--accent);
}

.tab-txt { min-width: 0; display: flex; flex-direction: column; line-height: 1.25; }
.tab-tit {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Segunda línea para el contexto (el proyecto al que pertenece un presupuesto,
   por ejemplo): dos pestañas "Presupuesto" sin más no se distinguen. */
.tab-sub {
  font-size: 10.5px; font-weight: 400; color: var(--text-soft);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.tab-x {
  flex: 0 0 auto;
  display: grid; place-items: center;
  width: 18px; height: 18px; padding: 0;
  color: var(--text-soft); background: none; border: 0;
  border-radius: var(--radius-xs); cursor: pointer;
  opacity: 0;                 /* aparece al pasar por encima, como el navegador */
}
.tab:hover .tab-x, .tab.activa .tab-x { opacity: 1; }
.tab-x:hover { background: var(--border-med); color: var(--text); }

@media (max-width: 700px) {
  .main-scroll { padding: 14px; }
  .tab { max-width: 150px; padding-left: 10px; }
  .tab-sub { display: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   CAPA — FICHA DE PROYECTO A PÁGINA COMPLETA

   Criterio, tomado de la referencia de Rentman que mandó el usuario: mucho
   blanco, filas finas separadas por una línea de 1px y nada más, sin cajas
   dentro de cajas, y el color reservado al punto de identidad del proyecto y a
   lo que avisa. Todo con tokens, para que el modo oscuro lo herede.
   ═══════════════════════════════════════════════════════════════════════════ */
.pf { max-width: 1180px; }
.pf-vacia { padding: 48px 0; text-align: center; color: var(--text-soft); }

.pf-volver {
  display: inline-flex; align-items: center; gap: 5px;
  margin-bottom: 14px; padding: 0;
  font: inherit; font-size: 12.5px; color: var(--text-soft);
  background: none; border: 0; cursor: pointer;
}
.pf-volver:hover { color: var(--text); }

/* ── Cabecera ── */
.pf-cab {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 20px;
  padding-bottom: 18px;
}
.pf-cab-izq { display: flex; align-items: flex-start; gap: 12px; min-width: 0; }
.pf-punto {
  flex: 0 0 auto; width: 10px; height: 10px; margin-top: 9px;
  background: var(--proy-color, var(--text-soft));
}
.pf-nombre {
  margin: 0; font-family: var(--font-display);
  font-size: 26px; font-weight: 700; letter-spacing: -0.02em; color: var(--text);
}
.pf-meta {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
  margin-top: 5px; font-size: 12.5px; color: var(--text-soft);
}
.pf-tarde { color: var(--red); }
.pf-cab-der { flex: 0 0 auto; display: flex; gap: 8px; }

/* ── Franja de cifras ── */
.pf-cifras {
  display: grid; gap: 0;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  padding: 16px 0;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
.pf-cifra { display: flex; flex-direction: column; gap: 3px; padding-right: 18px; }
.pf-cifra + .pf-cifra { padding-left: 18px; border-left: 1px solid var(--border); }
.pf-cifra-n {
  font-family: var(--font-display); font-size: 19px; font-weight: 700;
  letter-spacing: -0.02em; color: var(--text); font-variant-numeric: tabular-nums;
}
/* Solo se enciende lo que ya está cobrado; el resto es informativo. */
.pf-cifra.bien .pf-cifra-n { color: var(--green); }
.pf-cifra-l {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--text-soft);
}
.pf-progreso { grid-column: 1 / -1; margin-top: 14px; }
.pf-progreso-track { height: 3px; background: var(--surface-sunk); }
.pf-progreso-fill { height: 100%; background: var(--proy-color, var(--text-soft)); }
.pf-progreso-pie {
  display: flex; justify-content: space-between;
  margin-top: 5px; font-size: 11px; color: var(--text-soft);
}

/* ── Secciones internas ── */
.pf-tabs {
  display: flex; gap: 2px; flex-wrap: wrap;
  margin: 0 0 22px; border-bottom: 1px solid var(--border);
}
.pf-tab {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 11px 14px; margin-bottom: -1px;
  font: inherit; font-size: 13px; color: var(--text-soft);
  background: none; border: 0; border-bottom: 2px solid transparent;
  cursor: pointer;
}
.pf-tab:hover { color: var(--text); }
.pf-tab.activa { color: var(--text); font-weight: 600; border-bottom-color: var(--accent); }
.pf-tab > i {
  font-style: normal; font-size: 10.5px; padding: 1px 5px;
  color: var(--text-soft); background: var(--surface-2);
}

.pf-cols {
  display: grid; gap: 34px;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
}
.pf-sec { margin-bottom: 30px; }
.pf-sec-tit {
  display: flex; align-items: center; gap: 9px;
  margin: 0 0 12px;
  font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: .05em;
  color: var(--text-soft);
}
.pf-sec-n {
  padding: 1px 6px; font-size: 11px; letter-spacing: 0; text-transform: none;
  color: var(--text-2); background: var(--surface-2);
}
.pf-sec-eur {
  margin-left: auto; font-size: 13px; letter-spacing: 0; text-transform: none;
  color: var(--text); font-variant-numeric: tabular-nums;
}
.pf-sec-add {
  margin-left: auto; padding: 0; font: inherit; font-size: 11px;
  letter-spacing: 0; text-transform: none;
  color: var(--text-soft); background: none; border: 0; cursor: pointer;
  text-decoration: underline; text-underline-offset: 2px;
}
.pf-sec-add:hover { color: var(--text); }
.pf-sec-ayuda { margin: -6px 0 10px; font-size: 12px; color: var(--text-soft); }
.pf-acciones-sec { display: flex; gap: 8px; margin-bottom: 20px; }

.pf-nada {
  padding: 26px 0; font-size: 13px; color: var(--text-soft); line-height: 1.6;
}

/* ── Datos ── */
.pf-datos { margin: 0; display: flex; flex-direction: column; }
.pf-dato {
  display: grid; grid-template-columns: 130px minmax(0, 1fr); gap: 12px;
  padding: 9px 0; border-bottom: 1px solid var(--border);
}
.pf-dato dt { font-size: 12.5px; color: var(--text-soft); }
.pf-dato dd { margin: 0; font-size: 13px; color: var(--text); }
.pf-notas {
  margin-top: 14px; padding: 12px 14px; font-size: 12.5px; line-height: 1.6;
  color: var(--text-2); background: var(--surface-2); white-space: pre-wrap;
}

/* ── Contactos ── */
.pf-contactos { display: flex; flex-direction: column; }
.pf-contacto {
  display: flex; align-items: center; gap: 11px;
  padding: 10px 0; border-bottom: 1px solid var(--border);
}
.pf-contacto-ini {
  flex: 0 0 auto; width: 30px; height: 30px; display: grid; place-items: center;
  font-size: 11px; font-weight: 600; color: var(--text-2);
  background: var(--surface-2);
}
.pf-contacto-txt { min-width: 0; flex: 1; display: flex; flex-direction: column; }
.pf-contacto-nom { font-size: 13px; font-weight: 600; color: var(--text); }
.pf-contacto-rol { font-size: 11.5px; color: var(--text-soft); }
.pf-contacto-vias { display: flex; gap: 10px; }
.pf-contacto-vias a { font-size: 12px; color: var(--accent); text-decoration: none; }
.pf-contacto-vias a:hover { text-decoration: underline; }

/* ── Presupuestos ── */
.pf-pres-lista { display: flex; flex-direction: column; }
.pf-pres {
  display: grid; align-items: center; gap: 14px;
  grid-template-columns: 110px minmax(0, 1fr) auto auto 92px;
  width: 100%; padding: 11px 8px; margin: 0 -8px;
  font: inherit; text-align: left; color: var(--text);
  background: none; border: 0; border-bottom: 1px solid var(--border);
  cursor: pointer;
}
.pf-pres:hover { background: var(--bg-hover); }
.pf-pres-num { font-size: 12.5px; font-weight: 600; font-variant-numeric: tabular-nums; }
.pf-pres-cli { font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pf-pres-dep {
  padding: 1px 7px; font-size: 11px; color: var(--text-2); background: var(--surface-2);
}
.pf-pres-fec { font-size: 12px; color: var(--text-soft); }
.pf-pres-eur { text-align: right; font-size: 13px; font-weight: 600; font-variant-numeric: tabular-nums; }

/* ── Tablas simples de la ficha ── */
.pf-tabla { display: flex; flex-direction: column; }
.pf-tabla-cab, .pf-tabla-fila {
  display: grid; align-items: center; gap: 14px;
  grid-template-columns: 100px minmax(0, 1fr) 170px 70px;
  padding: 9px 0; border-bottom: 1px solid var(--border);
}
.pf-tabla-cab {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--text-soft);
}
.pf-tabla-fila { font-size: 13px; color: var(--text); }
.pf-tabla-fila .mono { font-family: var(--font-mono); font-size: 12px; color: var(--text-soft); }
.pf-tabla-fila .suave { color: var(--text-soft); font-size: 12.5px; }
.pf-tabla-fila .num { text-align: right; font-variant-numeric: tabular-nums; }

/* ── Flota ── */
.pf-flota {
  display: grid; gap: 8px;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
}
.pf-veh {
  display: flex; align-items: center; gap: 10px;
  padding: 11px 13px; border: 1px solid var(--border); background: var(--surface);
}
.pf-veh-ico { flex: 0 0 auto; color: var(--text-soft); display: grid; place-items: center; }
.pf-veh-txt { min-width: 0; flex: 1; display: flex; flex-direction: column; }
.pf-veh-nom {
  font-size: 13px; font-weight: 600; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pf-veh-mat { font-family: var(--font-mono); font-size: 11px; color: var(--text-soft); }
.pf-veh-cond { font-size: 11.5px; color: var(--text-soft); }

@media (max-width: 860px) {
  .pf-cifras { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px 0; }
  .pf-cifra + .pf-cifra { padding-left: 0; border-left: 0; }
  .pf-cifra:nth-child(even) { padding-left: 18px; border-left: 1px solid var(--border); }
  .pf-pres { grid-template-columns: 90px minmax(0, 1fr) 80px; }
  .pf-pres-dep, .pf-pres-fec { display: none; }
  .pf-tabla-cab, .pf-tabla-fila { grid-template-columns: minmax(0, 1fr) 70px; }
  .pf-tabla-cab span:nth-child(1), .pf-tabla-fila span:nth-child(1),
  .pf-tabla-cab span:nth-child(3), .pf-tabla-fila span:nth-child(3) { display: none; }
}

/* La fila de proyecto es un enlace entero: se avisa con el cursor y un realce,
   porque una fila que no parece pulsable no se pulsa. */
.proy-fila-click { cursor: pointer; }
.proy-fila-click:hover { background: var(--bg-hover); }

/* ═══════════════════════════════════════════════════════════════════════════
   CAPA — MODO OSCURO

   No se duplica ni una regla: se redefinen los TOKENS y todo lo que ya está
   escrito con `var(--…)` cambia solo. Por eso ha merecido la pena escribir las
   capas nuevas de esta sesión usando únicamente tokens.

   El tema se marca en `<html data-tema="oscuro|claro">`. Si el usuario no ha
   elegido nada se sigue al sistema (`prefers-color-scheme`), que es lo que la
   gente espera hoy; en cuanto toca el interruptor, manda su elección.

   Dos cosas que NO son un simple "invertir":

   1. `--green` en claro es el azul marino oscuro (#2b2d42): en esta paleta lo
      "bueno" se marca con el color serio, no con verde. Sobre fondo oscuro eso
      desaparece, así que en oscuro pasa a un verde real y legible.
   2. El rojo de marca (#ef233c) sobre negro vibra y cansa. Se sube el brillo y
      se baja un punto la saturación (#ff4d5f) para que el contraste sea el
      mismo sin quemar.
   ═══════════════════════════════════════════════════════════════════════════ */
:root[data-tema="oscuro"] {
  --space-indigo:  #e9eaf0;
  --lavender-grey: #8b90a3;
  --platinum:      #17171c;
  --punch-red:     #ff4d5f;
  --flag-red:      #ff6b7a;

  --bg:            #0f0f13;
  --surface:       #17171d;
  --surface-2:     #1e1e26;
  --surface-sunk:  #0b0b0f;

  --border:        rgba(255,255,255,0.10);
  --border-med:    rgba(255,255,255,0.17);
  --border-strong: rgba(255,255,255,0.30);

  --text:        #e9eaf0;
  --text-2:      rgba(233,234,240,0.76);
  --text-soft:   #8b90a3;
  --text-xsoft:  rgba(139,144,163,0.55);

  --blue:        #ff4d5f;
  --blue-hover:  #ff6b7a;
  --blue-light:  rgba(255,77,95,0.12);

  /* Ver nota 1 de la cabecera */
  --green:       #4ade80;
  --green-dark:  #22c55e;
  --orange:      #a8b0c2;
  --orange-dark: #c2c8d6;
  --red:         #ff4d5f;
  --red-dark:    #ff6b7a;
  --indigo:      #e9eaf0;

  /* Las sombras en oscuro no pueden ser tinta azulada sobre negro: no se ven y
     solo ensucian. Se usan negras y más marcadas. */
  --shadow-xs:   none;
  --shadow-sm:   none;
  --shadow:      0 4px 14px rgba(0,0,0,0.50), 0 0 0 0.5px rgba(255,255,255,0.06);
  --shadow-md:   0 12px 34px rgba(0,0,0,0.60), 0 0 0 0.5px rgba(255,255,255,0.07);
  --shadow-lift: 0 6px 20px rgba(0,0,0,0.55), 0 0 0 0.5px rgba(255,255,255,0.06);
  --ring:        0 0 0 3px rgba(255,77,95,0.28);

  --accent:         var(--punch-red);
  --accent-blue:    var(--punch-red);
  --accent-hover:   var(--flag-red);
  --bg-card:        var(--surface);
  --bg-hover:       rgba(255,255,255,0.055);
  --border-light:   var(--border);
  --border-color:   var(--border-med);
  --text-primary:   var(--text);
  --text-secondary: var(--text-2);
  --text-muted:     var(--text-soft);

  /* La barra lateral ya era oscura. En modo oscuro tiene que seguir siendo la
     zona MÁS oscura o el contenido deja de separarse de ella. */
  --sidebar-bg:     #050507;   /* casi negra: en oscuro tiene que ser MÁS oscura que el contenido, o menú y página se funden */
  --sidebar-bg-alt: #0a0a0d;

  color-scheme: dark;   /* barras de scroll y controles nativos del navegador */
}

/* Sin elección explícita se sigue al sistema. Se repiten los tokens con la
   misma definición en vez de encadenar selectores: encadenarlos obligaba a que
   `data-tema` estuviera puesto siempre, y en el primer pintado todavía no lo
   está — la página parpadeaba en claro antes de ponerse oscura. */
@media (prefers-color-scheme: dark) {
  :root:not([data-tema="claro"]) {
    --space-indigo:  #e9eaf0;
    --lavender-grey: #8b90a3;
    --platinum:      #17171c;
    --punch-red:     #ff4d5f;
    --flag-red:      #ff6b7a;
    --bg:            #0f0f13;
    --surface:       #17171d;
    --surface-2:     #1e1e26;
    --surface-sunk:  #0b0b0f;
    --border:        rgba(255,255,255,0.10);
    --border-med:    rgba(255,255,255,0.17);
    --border-strong: rgba(255,255,255,0.30);
    --text:        #e9eaf0;
    --text-2:      rgba(233,234,240,0.76);
    --text-soft:   #8b90a3;
    --text-xsoft:  rgba(139,144,163,0.55);
    --blue:        #ff4d5f;
    --blue-hover:  #ff6b7a;
    --blue-light:  rgba(255,77,95,0.12);
    --green:       #4ade80;
    --green-dark:  #22c55e;
    --orange:      #a8b0c2;
    --orange-dark: #c2c8d6;
    --red:         #ff4d5f;
    --red-dark:    #ff6b7a;
    --indigo:      #e9eaf0;
    --shadow-xs:   none;
    --shadow-sm:   none;
    --shadow:      0 4px 14px rgba(0,0,0,0.50), 0 0 0 0.5px rgba(255,255,255,0.06);
    --shadow-md:   0 12px 34px rgba(0,0,0,0.60), 0 0 0 0.5px rgba(255,255,255,0.07);
    --shadow-lift: 0 6px 20px rgba(0,0,0,0.55), 0 0 0 0.5px rgba(255,255,255,0.06);
    --ring:        0 0 0 3px rgba(255,77,95,0.28);
    --accent:         var(--punch-red);
    --accent-blue:    var(--punch-red);
    --accent-hover:   var(--flag-red);
    --bg-card:        var(--surface);
    --bg-hover:       rgba(255,255,255,0.055);
    --border-light:   var(--border);
    --border-color:   var(--border-med);
    --text-primary:   var(--text);
    --text-secondary: var(--text-2);
    --text-muted:     var(--text-soft);
    --sidebar-bg:     #050507;   /* casi negra: en oscuro tiene que ser MÁS oscura que el contenido, o menú y página se funden */
    --sidebar-bg-alt: #0a0a0d;
    color-scheme: dark;
  }
}

/* Interruptor de tema, al final de la barra de pestañas: es el único sitio que
   está siempre a la vista sin robarle espacio al contenido. */
.tabbar-fila {
  display: flex; align-items: stretch;
  flex: 0 0 auto; min-width: 0;
  background: var(--surface-2);
  border-bottom: 1px solid var(--border);
}
.tabbar-fila > .tabbar { flex: 1; min-width: 0; border-bottom: 0; }

.tema-btn {
  flex: 0 0 auto;
  display: grid; place-items: center;
  width: 40px; padding: 0;
  color: var(--text-soft); background: none;
  border: 0; border-left: 1px solid var(--border);
  cursor: pointer;
}
.tema-btn:hover { color: var(--text); background: var(--bg-hover); }
/* Se enseña el icono de a DÓNDE vas, no el de dónde estás: en claro se ofrece
   la luna. Al revés hay que pararse a pensar qué significa. */
.tema-ico-luna { display: block; }
.tema-ico-sol  { display: none; }
:root[data-tema="oscuro"] .tema-ico-luna { display: none; }
:root[data-tema="oscuro"] .tema-ico-sol  { display: block; }
@media (prefers-color-scheme: dark) {
  :root:not([data-tema="claro"]) .tema-ico-luna { display: none; }
  :root:not([data-tema="claro"]) .tema-ico-sol  { display: block; }
}

/* ── Modo oscuro: remates que los tokens no alcanzan ──────────────────────
   Cuatro sitios que fijaban blanco o casi-blanco a pelo. La columna de
   vehículos del calendario es `position: sticky`, así que su fondo tiene que
   ser OPACO sí o sí (el contenido pasa por debajo); lo que no puede es ser
   blanco fijo. */
.cal-veh-td-veh,
.cal-veh-table tbody .cal-veh-td-veh { background: var(--surface); }
.cal-veh-table tbody tr:hover .cal-veh-td-veh { background: var(--surface-2); }

/* Etiqueta de evento del Gantt: llevaba fondo blanco fijo para taparse a sí
   misma sobre la barra. Ahora se tapa con el fondo del tema. */
.gantt-event-label.gantt-label-link { background: var(--surface); color: var(--text); }

.tel-pill-dot { background: var(--text-soft); }

/* La cabecera de la columna de vehículos lleva un fondo OSCURO fijo puesto por
   el rediseño estilo Jira, que gana a la regla de más arriba. Como ese fondo no
   cambia con el tema, su texto tampoco puede: claro en ambos. Se descubrió al
   sustituir a ciegas `color:#fff` por `var(--surface)` en las reglas invertidas
   — sirve para las que invierten de verdad, no para las de fondo fijo. */
.cal-veh-th-veh,
.cal-veh-th-week-cell,
.cal-veh-table .cal-veh-th-day,
.cal-veh-table .cal-veh-th-day.cal-weekend { color: rgba(255,255,255,0.9); }
.cal-veh-table .cal-veh-th-day .cal-veh-th-dia,
.cal-veh-table .cal-veh-th-day small { color: rgba(255,255,255,0.55); }

/* Bandas cebra del calendario de flota y del Gantt: estaban en gris claro fijo,
   que en modo oscuro son dos rayas blancas en mitad de la tabla. Se sustituyen
   por el token hundido, que es gris claro en claro y casi negro en oscuro —
   mismo efecto de banda, en los dos temas. */
.cal-veh-row.cal-row-alt .cal-veh-td-veh,
.cal-veh-table .cal-veh-row.cal-row-alt .cal-veh-td-veh { background: var(--surface-2); }
.cal-veh-row.cal-row-alt .cal-veh-td-day:not(.cal-assigned),
.cal-veh-table .cal-veh-row.cal-row-alt .cal-veh-td-day.cal-weekend:not(.cal-assigned) {
  background: var(--surface-2);
}
.gantt-event-row:nth-child(even) .gantt-event-label { background: var(--surface-2); }

/* Logo en las fichas QR: la palmera junto al nombre. Antes solo había texto.
   El fichero es el mismo favicon.png (5 KB) que ya se sirve, así que no añade
   ninguna descarga nueva. */
.ficha-empresa { display: flex; align-items: center; gap: 5px; }
.ficha-logo { flex: 0 0 auto; display: block; object-fit: contain; }

/* Al imprimir, los fondos y los logos se van si el navegador no los fuerza. */
@media print {
  .ficha-logo { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   CAPA — VEHÍCULOS EN CUADRÍCULA
   La foto manda: es lo que hace reconocible un vehículo de un vistazo. Debajo,
   matrícula y las tres fechas por las que se entra a esta pantalla.
   ═══════════════════════════════════════════════════════════════════════════ */
.veh-vista-barra { display: flex; justify-content: flex-end; margin-bottom: 10px; }

.veh-grid {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fill, minmax(232px, 1fr));
}
.veh-grid-vacio { padding: 36px; text-align: center; color: var(--text-soft); }

.veh-card {
  display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--border);
  cursor: pointer; overflow: hidden;
}
.veh-card:hover { border-color: var(--border-strong); }

.veh-card-img {
  position: relative;
  aspect-ratio: 16 / 10;
  background: var(--surface-2);
  display: grid; place-items: center;
  overflow: hidden;
}
.veh-card-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.veh-card-sinfoto { display: grid; place-items: center; opacity: .55; transform: scale(1.6); }
.veh-card-estado { position: absolute; top: 7px; right: 7px; }

.veh-card-txt { padding: 10px 12px 12px; display: flex; flex-direction: column; gap: 3px; }
.veh-card-nom {
  font-size: 13.5px; font-weight: 600; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.veh-card-sub { display: flex; align-items: baseline; gap: 8px; font-size: 12px; color: var(--text-soft); }
.veh-card-mat {
  font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .02em;
  color: var(--text-2); padding: 1px 5px; background: var(--surface-2);
}
.veh-card-marca {
  font-size: 11.5px; color: var(--text-soft);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.veh-card-docs {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px;
  margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--border);
}
.veh-card-docs span { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.veh-card-docs em {
  font-style: normal; font-size: 9.5px; text-transform: uppercase;
  letter-spacing: .05em; color: var(--text-soft);
}
.veh-card-docs b {
  font-size: 11.5px; font-weight: 600; font-variant-numeric: tabular-nums;
  color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ═══════════════════════════════════════════════════════════════════════════
   CAPA — CABECERA DE INVENTARIO EN CHIPS
   Sustituye a la fila de ocho tarjetas de colores. Mismo componente y mismo
   gesto que la barra de Vehículos: gris, y solo se enciende el activo.
   Las reglas `.inv-dash-*` de más arriba quedan sin uso; se dejan en su sitio
   en vez de borrarlas a mano en un fichero de 10.000 líneas donde el orden es
   la resolución de conflictos.
   ═══════════════════════════════════════════════════════════════════════════ */
.inv-chips {
  display: flex; flex-wrap: wrap; gap: 6px;
  margin-bottom: 14px;
}
.inv-chip {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 6px 11px;
  font: inherit; font-size: 12.5px; color: var(--text-2);
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  cursor: pointer;
}
.inv-chip:hover { background: var(--surface-2); color: var(--text); }
.inv-chip.activo {
  background: var(--text); border-color: var(--text); color: var(--surface);
  font-weight: 600;
}
.inv-chip-nom { white-space: nowrap; }
.inv-chip-n {
  font-size: 11px; font-variant-numeric: tabular-nums; color: var(--text-soft);
}
.inv-chip.activo .inv-chip-n { color: var(--surface); opacity: .72; }

/* ═══════════════════════════════════════════════════════════════════════════
   CAPA — BUSCADOR GLOBAL Y CENTRO DE NOTIFICACIONES

   La barra crece al enfocarla y levanta una sombra: el gesto dice "esto se ha
   abierto y ahora manda", que es lo que hace falta cuando el desplegable va a
   tapar la página. Todo con tokens, así que hereda el modo oscuro.
   ═══════════════════════════════════════════════════════════════════════════ */
.dash-barra {
  display: flex; align-items: center; gap: 10px;
  margin-bottom: 20px;
  /* La barra tiene que crear su PROPIO contexto de apilamiento por encima de
     las tarjetas que vienen después en el DOM. El `z-index: 60` del
     desplegable no bastaba: sin z-index en un antepasado posicionado, el
     desplegable compite dentro del contexto raíz y las tarjetas, al ir
     después, se pintan encima. */
  position: relative; z-index: 60;
}

.busca-caja {
  position: relative; z-index: 1; flex: 1; min-width: 0; max-width: 640px;
  display: flex; align-items: center; gap: 9px;
  padding: 0 12px;
  background: var(--surface);
  border: 1px solid var(--border-med);
  border-radius: var(--radius);
  transition: box-shadow .16s ease, border-color .16s ease, transform .16s ease;
}
.busca-caja:hover { border-color: var(--border-strong); box-shadow: var(--shadow-xs); }
/* :focus-within y no :focus — quien recibe el foco es el input de dentro. */
.busca-caja:focus-within {
  border-color: var(--accent);
  box-shadow: var(--ring), var(--shadow-sm);
  transform: translateY(-1px);
}
.busca-ico { flex: 0 0 auto; color: var(--text-soft); transition: color .16s ease; }
.busca-caja:focus-within .busca-ico { color: var(--accent); }

.busca-input {
  flex: 1; min-width: 0;
  padding: 11px 0; font: inherit; font-size: 13.5px;
  color: var(--text); background: none; border: 0; outline: none;
}
.busca-input::placeholder { color: var(--text-soft); }
/* La cruz nativa de <input type=search> se sale del diseño y duplica la nuestra */
.busca-input::-webkit-search-cancel-button { display: none; }

.busca-kbd {
  flex: 0 0 auto;
  padding: 2px 6px; font-family: var(--font); font-size: 10.5px;
  color: var(--text-soft); background: var(--surface-2);
  border: 1px solid var(--border); border-radius: var(--radius-xs);
}
.busca-caja:focus-within .busca-kbd { opacity: 0; }
.busca-limpiar {
  flex: 0 0 auto; display: grid; place-items: center;
  width: 20px; height: 20px; padding: 0;
  color: var(--text-soft); background: none; border: 0; cursor: pointer;
  border-radius: var(--radius-pill);
}
.busca-limpiar:hover { background: var(--surface-2); color: var(--text); }

/* ── Desplegable ── */
.busca-pop {
  position: absolute; top: calc(100% + 6px); left: 0; right: 0; z-index: 60;
  max-height: 62vh; overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--border-med); border-radius: var(--radius);
  box-shadow: var(--shadow-md);
  padding: 5px;
}
.busca-grupo + .busca-grupo { margin-top: 4px; border-top: 1px solid var(--border); padding-top: 4px; }
.busca-grupo-tit {
  display: flex; justify-content: space-between; align-items: center;
  padding: 7px 9px 4px;
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--text-soft);
}
.busca-fila {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 8px 9px; font: inherit; text-align: left;
  color: var(--text); background: none; border: 0; cursor: pointer;
  border-radius: var(--radius-sm);
}
.busca-fila.sel, .busca-fila:hover { background: var(--surface-2); }
.busca-fila-ico { flex: 0 0 auto; color: var(--text-soft); display: grid; place-items: center; }
.busca-fila.sel .busca-fila-ico { color: var(--accent); }
.busca-fila-txt { min-width: 0; flex: 1; display: flex; flex-direction: column; }
.busca-fila-tit {
  font-size: 13px; font-weight: 500;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.busca-fila-sub {
  font-size: 11.5px; color: var(--text-soft);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.busca-fila-extra {
  flex: 0 0 auto; font-size: 11px; color: var(--text-soft);
  padding: 1px 6px; background: var(--surface-2); border-radius: var(--radius-xs);
}
.busca-pop mark {
  background: rgba(var(--acento-rgb), .18); color: inherit;
  padding: 0 1px; border-radius: 0;
}
.busca-todos {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  width: 100%; margin-top: 4px; padding: 9px;
  font: inherit; font-size: 12.5px; color: var(--text-2);
  background: var(--surface-2); border: 0; border-radius: var(--radius-sm);
  cursor: pointer;
}
.busca-todos:hover { background: var(--bg-hover); color: var(--text); }
.busca-todos kbd {
  font-family: var(--font); font-size: 10px; padding: 1px 5px;
  border: 1px solid var(--border); border-radius: var(--radius-xs);
}
.busca-vacio { padding: 20px 14px; font-size: 13px; color: var(--text-soft); }
.busca-vacio-nota { display: block; margin-top: 5px; font-size: 11.5px; opacity: .8; }

/* ── Página de resultados ── */
.busca-pag { max-width: 1100px; }
.busca-pag-vacio { padding: 46px 0; text-align: center; color: var(--text-soft); }
.busca-pag-tit {
  margin: 0; font-family: var(--font-display);
  font-size: 23px; font-weight: 700; letter-spacing: -0.02em; color: var(--text);
}
.busca-pag-nota { margin: 5px 0 26px; font-size: 12.5px; color: var(--text-soft); }
.busca-pag-grupos {
  display: grid; gap: 26px;
  grid-template-columns: repeat(auto-fit, minmax(330px, 1fr));
}
.busca-pag-grupo-tit {
  display: flex; align-items: center; gap: 8px; margin: 0 0 10px;
  font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: .05em;
  color: var(--text-soft);
}
.busca-pag-grupo-ico { display: grid; place-items: center; }
.busca-pag-n {
  margin-left: auto; padding: 1px 6px; font-size: 11px; letter-spacing: 0;
  color: var(--text-2); background: var(--surface-2);
}
.busca-pag-lista { display: flex; flex-direction: column; }
.busca-tarjeta {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 11px 10px; margin: 0 -10px;
  font: inherit; text-align: left; color: var(--text);
  background: none; border: 0; border-bottom: 1px solid var(--border);
  cursor: pointer;
  transition: background .12s ease, padding-left .12s ease;
}
.busca-tarjeta:hover { background: var(--bg-hover); padding-left: 15px; }
.busca-tarjeta-color { flex: 0 0 auto; width: 4px; align-self: stretch; }
.busca-tarjeta-txt { min-width: 0; flex: 1; display: flex; flex-direction: column; }
.busca-tarjeta-tit {
  font-size: 13.5px; font-weight: 500;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.busca-tarjeta-sub {
  font-size: 12px; color: var(--text-soft);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.busca-tarjeta-extra { flex: 0 0 auto; font-size: 11.5px; color: var(--text-soft); }
.busca-tarjeta mark { background: rgba(var(--acento-rgb), .18); color: inherit; }
.busca-pag-mas { padding: 10px 0; font-size: 12px; color: var(--text-soft); }

/* ── Campana y panel ── */
.notif-btn {
  position: relative; flex: 0 0 auto;
  display: grid; place-items: center;
  width: 42px; height: 42px; padding: 0;
  color: var(--text-2); background: var(--surface);
  border: 1px solid var(--border-med); border-radius: var(--radius);
  cursor: pointer;
  transition: box-shadow .16s ease, border-color .16s ease, transform .16s ease;
}
.notif-btn:hover {
  border-color: var(--border-strong); box-shadow: var(--shadow-xs);
  transform: translateY(-1px); color: var(--text);
}
.notif-btn[aria-expanded="true"] { border-color: var(--accent); color: var(--text); }
.notif-btn.urgente { color: var(--red); border-color: rgba(var(--acento-rgb), .35); }

.notif-punto {
  position: absolute; top: -5px; right: -5px;
  min-width: 17px; height: 17px; padding: 0 4px;
  display: grid; place-items: center;
  font-size: 10px; font-weight: 700; line-height: 1;
  color: #fff; background: var(--red);
  border: 2px solid var(--bg); border-radius: var(--radius-pill);
}

/* Popup anclado a la campana. Antes era una tira de 420px suelta debajo del
   buscador: se leía como un bloque más del dashboard, no como algo desplegado,
   y empujaba el contenido al abrirse. Ahora sale de la campana, flota por
   encima y no mueve nada. */
.notif-wrap { position: relative; flex: 0 0 auto; }

.notif-panel {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 70;
  width: 340px; max-width: calc(100vw - 32px);
  background: var(--surface);
  border: 1px solid var(--border-med); border-radius: var(--radius);
  box-shadow: var(--shadow-md);
  overflow: hidden;
  /* Nace desde la campana en vez de aparecer de golpe: dice de dónde sale. */
  transform-origin: top right;
  animation: notifAparece .13s ease-out;
}
@keyframes notifAparece {
  from { opacity: 0; transform: scale(.96) translateY(-4px); }
  to   { opacity: 1; transform: none; }
}
/* Piquito hacia la campana */
.notif-panel::before {
  content: ''; position: absolute; top: -5px; right: 14px;
  width: 9px; height: 9px; transform: rotate(45deg);
  background: var(--surface);
  border-left: 1px solid var(--border-med); border-top: 1px solid var(--border-med);
}

.notif-cab {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 12px; border-bottom: 1px solid var(--border);
  font-size: 12.5px; color: var(--text);
}
.notif-cerrar {
  display: grid; place-items: center; width: 22px; height: 22px; padding: 0;
  color: var(--text-soft); background: none; border: 0; cursor: pointer;
  border-radius: var(--radius-xs);
}
.notif-cerrar:hover { background: var(--surface-2); color: var(--text); }

.notif-filtros { display: flex; gap: 4px; padding: 8px 12px 4px; flex-wrap: wrap; }
.notif-chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px; font: inherit; font-size: 11.5px;
  color: var(--text-2); background: var(--surface-2);
  border: 1px solid transparent; border-radius: var(--radius-pill); cursor: pointer;
}
.notif-chip > i { font-style: normal; font-size: 10.5px; color: var(--text-soft); }
.notif-chip:hover { border-color: var(--border-med); }
.notif-chip.sel { background: var(--text); color: var(--surface); }
.notif-chip.sel > i { color: var(--surface); opacity: .7; }
.notif-chip.nv-urgente { color: var(--red); }
.notif-chip.nv-urgente.sel { background: var(--red); color: #fff; }

.notif-lista { max-height: min(52vh, 420px); overflow-y: auto; padding: 4px 6px 8px; }
.notif-item {
  display: flex; align-items: flex-start; gap: 10px; width: 100%;
  padding: 10px; font: inherit; text-align: left;
  color: var(--text); background: none; border: 0;
  border-left: 2px solid transparent; border-radius: var(--radius-sm);
  cursor: pointer;
}
.notif-item:disabled { cursor: default; }
.notif-item:not(:disabled):hover { background: var(--surface-2); }
.notif-item.nv-urgente { border-left-color: var(--red); }
.notif-item.nv-aviso   { border-left-color: var(--text-soft); }
.notif-item-ico { flex: 0 0 auto; margin-top: 1px; color: var(--text-soft); display: grid; place-items: center; }
.notif-item.nv-urgente .notif-item-ico { color: var(--red); }
.notif-item-txt { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 2px; }
.notif-item-tit { font-size: 12.5px; font-weight: 500; }
.notif-item-det { font-size: 11.5px; color: var(--text-soft); }
.notif-item-fecha {
  flex: 0 0 auto; font-size: 11px; color: var(--text-soft);
  font-variant-numeric: tabular-nums;
}
.notif-vacio { padding: 26px 16px; text-align: center; font-size: 12.5px; color: var(--text-soft); }
.notif-vacio-ok { font-size: 14px; font-weight: 600; color: var(--text); margin-bottom: 4px; }

@media (max-width: 700px) {
  .busca-caja { max-width: none; }
  .notif-panel { width: calc(100vw - 32px); right: -8px; }
  .busca-kbd { display: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   CAPA — DASHBOARD PERSONALIZABLE
   ═══════════════════════════════════════════════════════════════════════════ */
.dash-cab-der { display: flex; align-items: center; gap: 14px; }
.dash-personalizar {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 11px; font: inherit; font-size: 12px;
  color: var(--text-2); background: var(--surface);
  border: 1px solid var(--border-med); border-radius: var(--radius-sm);
  cursor: pointer;
  transition: border-color .16s ease, color .16s ease, box-shadow .16s ease;
}
.dash-personalizar:hover {
  color: var(--text); border-color: var(--border-strong); box-shadow: var(--shadow-xs);
}

.dash-panel {
  margin-bottom: 20px;
  background: var(--surface);
  border: 1px solid var(--border-med); border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}
.dash-panel-cab {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 14px;
  padding: 14px 16px; border-bottom: 1px solid var(--border);
}
.dash-panel-cab strong { display: block; font-size: 13.5px; color: var(--text); }
.dash-panel-cab span { display: block; margin-top: 3px; font-size: 12px; color: var(--text-soft); }
.dash-panel-x {
  flex: 0 0 auto; display: grid; place-items: center; width: 24px; height: 24px; padding: 0;
  color: var(--text-soft); background: none; border: 0; cursor: pointer; border-radius: var(--radius-xs);
}
.dash-panel-x:hover { background: var(--surface-2); color: var(--text); }

.dash-panel-lista { padding: 4px 8px; }
.dash-panel-fila {
  display: flex; align-items: center; gap: 12px;
  padding: 8px 8px; border-bottom: 1px solid var(--border);
}
.dash-panel-fila:last-child { border-bottom: 0; }
.dash-panel-fila.no-disp { opacity: .5; }
.dash-panel-check {
  display: flex; align-items: center; gap: 10px; flex: 1; min-width: 0; cursor: pointer;
}
.dash-panel-fila.no-disp .dash-panel-check { cursor: default; }
.dash-panel-txt { min-width: 0; display: flex; flex-direction: column; }
.dash-panel-txt strong { font-size: 13px; font-weight: 600; color: var(--text); }
.dash-panel-txt small { font-size: 11.5px; color: var(--text-soft); }

.dash-panel-mover { flex: 0 0 auto; display: flex; gap: 3px; }
.dash-panel-mover button {
  display: grid; place-items: center; width: 26px; height: 26px; padding: 0;
  color: var(--text-2); background: var(--surface-2);
  border: 1px solid var(--border); border-radius: var(--radius-xs); cursor: pointer;
}
.dash-panel-mover button:hover:not(:disabled) { background: var(--bg-hover); color: var(--text); }
.dash-panel-mover button:disabled { opacity: .3; cursor: default; }

.dash-panel-pie {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 12px 16px; border-top: 1px solid var(--border); background: var(--surface-2);
}

/* "Cerrar todo": no es una pestaña, así que no puede parecerlo. Va al final,
   sin fondo y en letra pequeña, y solo se distingue al pasar por encima. */
.tab-cerrar-todas {
  flex: 0 0 auto; align-self: center;
  margin-left: 8px; padding: 3px 9px;
  font: inherit; font-size: 11px; white-space: nowrap;
  color: var(--text-soft); background: none;
  border: 1px solid transparent; border-radius: var(--radius-pill);
  cursor: pointer;
}
.tab-cerrar-todas:hover { color: var(--text); border-color: var(--border-med); }

/* La barra de pestañas vacía no se esconde: dice para qué sirve. Esconderla
   hacía creer que las pestañas se habían perdido, y la página daba un salto al
   abrirse la primera. */
.tabbar:empty { display: flex; }
.tabbar-vacia {
  align-self: center; padding: 0 4px;
  font-size: 11.5px; color: var(--text-xsoft);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ═══════════════════════════════════════════════════════════════════════════
   CAPA — CONSTRUCTOR DE PRESUPUESTOS A SANGRE (referencia: Rentman)

   Petición del usuario, con captura delante: *"tiene que ser más grande, que
   cubra más… no me gusta el estilo ventanas… que se vea como en rentman"*.

   Lo que se copia de la referencia y por qué:
     · **Toda la ventana.** Montar un presupuesto de cuarenta líneas dentro de un
       margen de 30px y una tarjeta redondeada deja un hueco ridículo.
     · **Dos paneles pegados**, separados por UNA línea de 1px. Nada de dos
       tarjetas flotando con un canal de aire entre medias.
     · **Cabecera fija** con las acciones a la derecha, sin scroll.
     · **Filas finas y planas.** Aquí se leen precios en columna; el adorno
       estorba y las esquinas redondeadas rompen la alineación de la rejilla.
   ═══════════════════════════════════════════════════════════════════════════ */

/* El contenedor con scroll deja de tener márgenes mientras el constructor está
   abierto: es lo que permite llegar a los bordes de la ventana. */
body.constructor-abierto .main-scroll { padding: 0; overflow: hidden; }
/* La cadena de alturas tiene que llegar ENTERA desde .main-scroll hasta los dos
   paneles: basta con que un eslabón se quede en `auto` para que el constructor
   se encoja a lo que ocupe su contenido. Medido: se rompía en #pres-layout. */
body.constructor-abierto #page-presupuestos,
body.constructor-abierto #pres-layout { height: 100%; min-height: 0; }
body.constructor-abierto #pres-list-view,
body.constructor-abierto #pres-catalog-view { display: none !important; }

body.constructor-abierto #pres-builder-view {
  display: flex !important; flex-direction: column;
  height: 100%; min-height: 0;
}

/* ── Cabecera ── */
body.constructor-abierto #pres-builder-view > .page-header {
  flex: 0 0 auto;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  margin: 0; padding: 12px 18px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}
body.constructor-abierto #pres-builder-title {
  font-size: 17px; font-weight: 700; letter-spacing: -0.02em; margin: 0;
}
body.constructor-abierto #pres-builder-view > .page-header .page-actions {
  display: flex; align-items: center; gap: 8px;
}

/* ── Los dos paneles ── */
body.constructor-abierto .builder-wrap {
  flex: 1; min-height: 0; height: auto;
  display: grid;
  grid-template-columns: minmax(300px, 0.85fr) minmax(0, 1.15fr);
  gap: 0;                       /* pegados: los separa una línea, no un canal */
  overflow: hidden;
}
body.constructor-abierto .pk,
body.constructor-abierto .builder-left {
  min-width: 0; min-height: 0;
  background: var(--surface);
  border: 0; border-radius: 0; box-shadow: none;
  overflow-y: auto;
}
body.constructor-abierto .pk {
  border-right: 1px solid var(--border);   /* la única separación entre paneles */
  display: flex; flex-direction: column; overflow: hidden;
}
body.constructor-abierto .pk-lista { flex: 1; min-height: 0; overflow-y: auto; }
body.constructor-abierto .builder-left { padding: 16px 18px 60px; }

/* En "Personalizar" el árbol sobra y el documento ocupa todo. */
body.constructor-abierto.modo-personalizar .builder-wrap { grid-template-columns: minmax(0, 1fr); }
body.constructor-abierto.modo-personalizar .pk { display: none; }

/* ── Nada de tarjetas dentro del constructor ── */
body.constructor-abierto .pres-datos,
body.constructor-abierto .pres-tabla-wrap,
body.constructor-abierto .pres-totales,
body.constructor-abierto .pres-seccion {
  border-radius: 0; box-shadow: none;
}

/* Debajo de 1000px los dos paneles no caben: se apilan, el árbol arriba con
   altura propia y el documento debajo. */
@media (max-width: 1000px) {
  body.constructor-abierto .builder-wrap {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: minmax(0, 42vh) minmax(0, 1fr);
  }
  body.constructor-abierto .pk { border-right: 0; border-bottom: 1px solid var(--border); }
  body.constructor-abierto .builder-left { padding: 14px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   CAPA — AJUSTES PEDIDOS

   1) La campana, pegada al borde derecho. El buscador tiene ancho máximo, así
      que sin esto la campana quedaba flotando en mitad de la fila.
   2) La cabecera del calendario de flota seguía el tema en el texto pero NO en
      el fondo: llevaba un gris casi negro fijo del rediseño estilo Jira, así
      que en modo CLARO salía una franja oscura en medio de una página blanca.
      Ahora el fondo también es un token y el texto se resuelve por contraste.
   ═══════════════════════════════════════════════════════════════════════════ */
.notif-wrap { margin-left: auto; }

/* ── Cabecera del calendario de flota: sigue el tema ── */
.cal-veh-table .cal-veh-th-day,
.cal-veh-table .cal-veh-th-day.cal-weekend,
.cal-veh-th-veh,
.cal-veh-th-week-cell,
.cal-veh-table .cal-veh-th-week-cell {
  background: var(--surface-2);
  color: var(--text-2);
}
.cal-veh-th-veh, .cal-veh-th-week-cell {
  /* La fila de rótulos, un punto más marcada que la de números */
  background: var(--surface-sunk);
  color: var(--text);
}
.cal-veh-table .cal-veh-th-day .cal-day-num { color: var(--text); }
.cal-veh-table .cal-veh-th-day .cal-day-name { color: var(--text-soft); }
.cal-veh-table .cal-veh-th-day.cal-weekend { background: var(--surface-sunk); }

/* La columna de HOY se sigue marcando en rojo de marca: es la referencia que
   más se usa al leer un calendario. */
.cal-veh-table .cal-veh-th-day.cal-today-col {
  background: rgba(var(--acento-rgb), 0.10);
}
.cal-veh-table .cal-veh-th-day.cal-today-col .cal-day-num,
.cal-veh-table .cal-veh-th-day.cal-today-col .cal-day-name {
  color: var(--accent); font-weight: 750;
}
.cal-veh-th-week-span.cal-today-col { color: var(--accent); }

/* Filas que se abren con doble clic. El cursor y el realce son el único aviso
   de que se puede: una fila que no parece pulsable no se pulsa. */
.fila-abrible { cursor: pointer; }
.fila-abrible:hover { background: var(--bg-hover); }

/* ── Ficha de dispositivo (IT Stock) ───────────────────────────────────────
   Reutiliza el armazón `.pf-*` de la ficha de proyecto: misma estructura, mismo
   aspecto, una sola cosa que mantener. Solo se añade lo propio del parque. */
.disp-ico {
  flex: 0 0 auto; width: 40px; height: 40px; margin-top: 2px;
  display: grid; place-items: center;
  color: var(--text-2); background: var(--surface-2);
  border: 1px solid var(--border);
}
.disp-cifras { grid-template-columns: repeat(4, minmax(0, 1fr)); }
/* El estado de la garantía es lo que más se consulta, así que es lo único de la
   franja que se permite encenderse. */
.disp-gar-bien  .pf-cifra-n { color: var(--green); }
.disp-gar-aviso .pf-cifra-n { color: var(--accent); }
.disp-gar-mal   .pf-cifra-n { color: var(--red); }
.disp-gar-nd    .pf-cifra-n { color: var(--text-soft); font-weight: 500; }

.disp-hist .pf-tabla-cab,
.disp-hist .pf-tabla-fila {
  grid-template-columns: minmax(0, 1.2fr) 110px 110px minmax(0, 1fr);
}
.disp-hist em { color: var(--green); font-style: normal; font-weight: 600; }

.pf-cab-izq .mono, .pf-datos .mono {
  font-family: var(--font-mono); font-size: 12px;
}

@media (max-width: 860px) {
  .disp-cifras { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .disp-hist .pf-tabla-cab, .disp-hist .pf-tabla-fila { grid-template-columns: minmax(0,1fr) 92px; }
  .disp-hist .pf-tabla-cab span:nth-child(n+3), .disp-hist .pf-tabla-fila span:nth-child(n+3) { display: none; }
}

/* ── Campos editables en sitio (ficha de línea) ────────────────────────────
   Se guardan al salir del campo. Parecen texto hasta que los tocas: una ficha
   llena de cajas de formulario se lee como un formulario, no como una ficha. */
.lf-datos .pf-dato { align-items: center; }
.lf-input {
  width: 100%; padding: 5px 8px; margin: -5px -8px;
  font: inherit; font-size: 13px; color: var(--text);
  background: transparent; border: 1px solid transparent;
  border-radius: 0;
}
.lf-input:hover  { border-color: var(--border); background: var(--surface-2); }
.lf-input:focus  { border-color: var(--accent); background: var(--surface); outline: none; }
.lf-input.mono   { font-family: var(--font-mono); font-size: 12.5px; }
.lf-input::placeholder { color: var(--text-xsoft); }
select.lf-input { cursor: pointer; }

.lf-notas {
  width: 100%; min-height: 88px; margin: 0; padding: 9px 11px;
  border-color: var(--border); background: var(--surface-2);
  resize: vertical; line-height: 1.55;
}
.lf-notas:hover { background: var(--surface-2); }

/* ── Chips de cabecera para IT Stock y Telefonía ───────────────────────────
   Mismo componente que la barra de Inventario: tres pantallas que hacen lo
   mismo (contar y filtrar) tienen que hacerlo igual. Gris salvo el activo, y
   los que avisan de algo pendiente llevan el rojo de marca en la cifra. */
.it-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }
.it-chip {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 6px 11px;
  font: inherit; font-size: 12.5px; color: var(--text-2);
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-pill); cursor: pointer;
}
.it-chip:hover { background: var(--surface-2); color: var(--text); }
.it-chip > i {
  font-style: normal; font-size: 11px; font-variant-numeric: tabular-nums;
  color: var(--text-soft);
}
.it-chip.aviso > i { color: var(--red); font-weight: 700; }
.it-chip.activo {
  background: var(--text); border-color: var(--text); color: var(--surface); font-weight: 600;
}
.it-chip.activo > i { color: var(--surface); opacity: .72; }

/* ── Logos de marca vectoriales ────────────────────────────────────────────
   Un solo recurso para los dos temas: el SVG hereda `currentColor`, así que
   sale negro sobre fondo claro y blanco sobre fondo oscuro sin mantener dos
   imágenes. Y ocupa exactamente la misma caja que los logos en PNG, que es lo
   que hacía que unas marcas se vieran más grandes que otras. */
.veh-brand-svg {
  display: grid; place-items: center;
  color: var(--text);
  background: transparent; border: 0;
}
.veh-logo-svg {
  width: 78%; height: 78%;
  display: block;
}

/* ── Cabeceras ordenables ──────────────────────────────────────────────────
   La flecha solo aparece en la columna activa; en las demás basta el cursor y
   el cambio de color al pasar por encima. Poner una flecha gris en todas
   ensucia la cabecera y no ayuda a nadie. */
.th-orden { cursor: pointer; user-select: none; white-space: nowrap; }
.th-orden:hover { color: var(--text); }
.th-orden.orden-activa { color: var(--text); font-weight: 700; }
.th-orden.orden-activa::after {
  content: '↑'; margin-left: 5px; font-size: 10px; opacity: .75;
}
.th-orden.orden-activa.orden-desc::after { content: '↓'; }

/* Selector de subproyecto en el constructor: va pegado al del proyecto porque
   es la misma decisión (a qué cuelga esto), con el "+" a mano para crear uno
   sin salir de aquí. */
.pres-sub-fila { display: flex; align-items: stretch; gap: 0; }
.pres-sub-fila select { flex: 1; min-width: 0; }
.pres-sub-nuevo {
  flex: 0 0 auto; width: 30px;
  display: grid; place-items: center;
  font: inherit; font-size: 16px; line-height: 1;
  color: var(--text-2); background: var(--surface-2);
  border: 1px solid var(--border); border-left: 0;
  cursor: pointer;
}
.pres-sub-nuevo:hover { background: var(--bg-hover); color: var(--accent); }

/* ── Selector con búsqueda ─────────────────────────────────────────────────
   La lista se ve entera desde el principio y se filtra escribiendo. Cabe una
   docena sin desplazar; a partir de ahí se desplaza, que es cuando el filtro
   empieza a hacer falta de verdad. */
.elegir-ayuda { margin: 0 0 12px; font-size: 12.5px; color: var(--text-soft); line-height: 1.5; }

.elegir-busca {
  display: flex; align-items: center; gap: 8px;
  padding: 0 11px; margin-bottom: 8px;
  background: var(--surface); border: 1px solid var(--border-med);
  transition: border-color .14s ease, box-shadow .14s ease;
}
.elegir-busca:focus-within { border-color: var(--accent); box-shadow: var(--ring); }
.elegir-busca > svg { flex: 0 0 auto; color: var(--text-soft); }
.elegir-busca input {
  flex: 1; min-width: 0; padding: 9px 0;
  font: inherit; font-size: 13.5px; color: var(--text);
  background: none; border: 0; outline: none;
}

.elegir-lista {
  max-height: 46vh; overflow-y: auto;
  border: 1px solid var(--border); background: var(--surface);
}
.elegir-op {
  display: flex; align-items: center; width: 100%;
  padding: 9px 12px; font: inherit; text-align: left;
  color: var(--text); background: none; border: 0;
  border-bottom: 1px solid var(--border); cursor: pointer;
}
.elegir-op:last-child { border-bottom: 0; }
.elegir-op.sel { background: var(--surface-2); }
/* La barra izquierda marca la fila activa sin cambiarle el tamaño: un borde
   completo movería el texto un pixel al recorrer con las flechas. */
.elegir-op.sel { box-shadow: inset 2px 0 0 var(--accent); }
.elegir-op-txt { min-width: 0; display: flex; flex-direction: column; }
.elegir-op-tit { font-size: 13.5px; font-weight: 500; }
.elegir-op-sub { font-size: 11.5px; color: var(--text-soft); }
.elegir-vacio { padding: 22px 14px; text-align: center; font-size: 13px; color: var(--text-soft); }

/* ── Botón que se comporta como desplegable ────────────────────────────────
   Para listas que no caben en un <select> nativo (el árbol de inventario son
   705 categorías). Se ve igual que un desplegable para que no haya que
   aprender nada nuevo, pero al pulsarlo abre el selector con búsqueda. */
.selector-boton {
  display: inline-flex; align-items: center; justify-content: space-between; gap: 8px;
  text-align: left; cursor: pointer;
  font: inherit; color: var(--text-2);
  background: var(--surface); border: 1px solid var(--border-med);
  padding-right: 9px !important;
}
.selector-boton > span {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.selector-boton > svg { flex: 0 0 auto; color: var(--text-soft); }
.selector-boton:hover { border-color: var(--border-strong); color: var(--text); }
.selector-boton.con-valor { color: var(--text); font-weight: 600; border-color: var(--border-strong); }

/* ── Pulido de los desplegables nativos ──────────────────────────────────── */
select.filter-select:hover,
select.form-control:hover,
.form-group select:hover,
.filters-bar select:hover { border-color: var(--border-strong); }

select.filter-select:focus,
select.form-control:focus,
.form-group select:focus,
.filters-bar select:focus {
  border-color: var(--accent); box-shadow: var(--ring); outline: none;
}
/* Las opciones heredan el tema: en oscuro, Safari las pintaba en blanco. */
select option { background: var(--surface); color: var(--text); }

/* ── Crew: resumen compacto ────────────────────────────────────────────────
   La tarjeta enseñaba las 9 áreas y las 5 capacidades: catorce etiquetas por
   persona. Ahora salen solo las áreas donde puede TOCAR algo, y lo demás se
   cuenta con el detalle en el `title`. */
.crew-resumen { display: flex; flex-direction: column; gap: 7px; }
.crew-areas { display: flex; flex-wrap: wrap; gap: 4px; }
.crew-extra {
  display: flex; flex-wrap: wrap; gap: 10px;
  font-size: 11.5px; color: var(--text-soft);
}
.crew-extra span { cursor: help; border-bottom: 1px dotted var(--border-med); }

.usr-copiar {
  margin-left: auto; padding: 0;
  font: inherit; font-size: 11.5px; text-transform: none; letter-spacing: 0;
  color: var(--accent); background: none; border: 0; cursor: pointer;
  text-decoration: underline; text-underline-offset: 2px;
}
.usr-copiar:hover { color: var(--accent-hover); }
.usr-bloque-tit { display: flex; align-items: center; gap: 10px; }

/* El año aproximado de ITV no se pinta como una fecha: en la hoja del mecánico
   hay ITVs anotadas solo con el año, y enseñarlo igual que "26/11/2026" haría
   creer que se sabe el día. */
.veh-aprox { font-style: italic; opacity: .75; }
.veh-doc-linea.veh-cita em { color: var(--accent); }

/* ── Logos de marca en modo oscuro ─────────────────────────────────────────
   Los que son negro sobre transparente se invierten y quedan blancos. Se marca
   cuáles con la clase `logo-mono`, puesta desde el mapa de marcas, en vez de
   invertirlos todos: Ford lleva su óvalo AZUL y al invertirlo saldría naranja.
   Se comprobó midiendo los píxeles de cada PNG, no mirándolos. */
:root[data-tema="oscuro"] .logo-mono { filter: invert(1) brightness(1.6); }
@media (prefers-color-scheme: dark) {
  :root:not([data-tema="claro"]) .logo-mono { filter: invert(1) brightness(1.6); }
}

/* Proyecto y subproyecto en la lista de presupuestos: el subproyecto va debajo
   y más pequeño, porque es el matiz — con dos presupuestos del mismo rodaje es
   lo único que los distingue. */
.pres-proy { display: block; font-size: 13px; color: var(--text); }
.pres-sub {
  display: inline-block; margin-top: 2px; padding: 1px 6px;
  font-size: 11px; color: var(--text-2); background: var(--surface-2);
  border-left: 2px solid var(--accent);
}

/* ── Eventos del calendario: un pelín de redondeo ──────────────────────────
   Petición literal: *"SUPER poco redondeado. Pero super poco. Que se note un
   pelín. Que no sea cuadrado completo."*

   2px. Es suficiente para que la esquina no corte y para que las barras
   contiguas se distingan una de otra, y lo bastante poco como para no romper la
   alineación de la rejilla ni pelearse con el resto de la app, que es cuadrada.
   Se toca el token, así que afecta a los tres calendarios a la vez. */
:root { --cal-bar-radius: 2px; }

.gantt-bar,
.gantt-event-bar,
.cal-ev,
.cal-vev,
.cal-cell-inner.con-label,
.proy-cal-barra {
  border-radius: var(--cal-bar-radius);
}
/* Las barras que continúan de un día al siguiente solo redondean su extremo:
   redondear los cuatro lados partiría visualmente un evento de cinco días en
   cinco trozos. */
.cal-run-ini { border-radius: var(--cal-bar-radius) 0 0 var(--cal-bar-radius); }
.cal-run-fin { border-radius: 0 var(--cal-bar-radius) var(--cal-bar-radius) 0; }
.cal-run-med { border-radius: 0; }

/* ═══════════════════════════════════════════════════════════════════════════
   CAPA — DESPLEGABLE DE CATEGORÍAS
   Anclado al botón y por encima del contenido: el inventario se sigue viendo
   detrás mientras se elige, que es lo que un modal impedía.
   ═══════════════════════════════════════════════════════════════════════════ */
.cat-dd-wrap { position: relative; display: inline-flex; }

.cat-dd {
  position: absolute; top: calc(100% + 4px); left: 0; z-index: 55;
  width: 340px; max-width: calc(100vw - 40px);
  background: var(--surface);
  border: 1px solid var(--border-med);
  box-shadow: var(--shadow-md);
  display: flex; flex-direction: column;
}

.cat-dd-busca {
  display: flex; align-items: center; gap: 7px;
  padding: 0 10px; border-bottom: 1px solid var(--border);
}
.cat-dd-busca > svg { flex: 0 0 auto; color: var(--text-soft); }
.cat-dd-busca input {
  flex: 1; min-width: 0; padding: 9px 0;
  font: inherit; font-size: 13px; color: var(--text);
  background: none; border: 0; outline: none;
}

/* Doce filas visibles: suficiente para abarcar una rama entera sin desplazar,
   y poco para que el desplegable no tape media pantalla. */
.cat-dd-lista { max-height: 340px; overflow-y: auto; padding: 3px 0; }

.cat-dd-cab {
  padding: 7px 12px 4px; font-size: 10.5px; text-transform: uppercase;
  letter-spacing: .05em; color: var(--text-soft);
}

.cat-dd-fila {
  display: flex; align-items: center; gap: 6px;
  /* La sangría marca el nivel; el chevron ocupa su hueco aunque no haya hijos,
     para que los nombres queden alineados en columna. */
  padding: 6px 10px 6px calc(10px + var(--niv, 0) * 15px);
  font-size: 13px; color: var(--text); cursor: pointer;
}
.cat-dd-fila:hover { background: var(--surface-2); }
.cat-dd-fila.activa {
  background: var(--surface-2); font-weight: 600;
  box-shadow: inset 2px 0 0 var(--accent);
}
.cat-dd-todas { border-bottom: 1px solid var(--border); margin-bottom: 3px; }

.cat-dd-chev {
  flex: 0 0 auto; width: 16px; height: 16px;
  display: grid; place-items: center; padding: 0;
  color: var(--text-soft); background: none; border: 0; cursor: pointer;
  transition: transform .12s ease;
}
.cat-dd-chev.abierta { transform: rotate(90deg); }
.cat-dd-chev:hover { color: var(--text); }
.cat-dd-chev.vacio { cursor: default; }

.cat-dd-nom { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cat-dd-ruta {
  flex: 0 1 auto; min-width: 0; font-size: 11px; color: var(--text-soft);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cat-dd-n {
  margin-left: auto; flex: 0 0 auto;
  font-size: 11px; color: var(--text-soft); font-variant-numeric: tabular-nums;
}
.cat-dd-vacio { padding: 20px 12px; text-align: center; font-size: 12.5px; color: var(--text-soft); }
/* Anclado por la derecha cuando por la izquierda se saldría de la pantalla. */
.cat-dd.a-la-derecha { left: auto; right: 0; }

/* ═══════════════════════════════════════════════════════════════════════════
   CAPA — BARRA LATERAL MÁS GRANDE Y GRUPO ACTIVO

   1) Un 15 % más grande. El usuario dudaba entre 10 y 20: a 10 % apenas se
      nota y no habría valido la pena tocarlo; a 20 % la barra se come 54px de
      contenido, que en una tabla de inventario con siete columnas se paga.
      15 % es donde se nota que respira sin quitarle sitio al trabajo.
      Se escala TODO junto —ancho, altura de fila, texto e iconos— porque subir
      solo la fuente deja las filas apretadas y subir solo el alto las deja
      vacías.

   2) Estando dentro de un grupo, el grupo ENTERO se tiñe un poco. El item
      activo sigue en rojo; el grupo solo cambia lo justo para que de un vistazo
      sepas en qué bloque estás, sin competir con el rojo. Antes esa pista solo
      existía con el grupo plegado (un punto rojo), y abierto no había ninguna.
   ═══════════════════════════════════════════════════════════════════════════ */
:root { --sidebar-w: 252px; }
/* 308 era demasiado: se comía 40px de contenido y el usuario lo notó enseguida.
   Y no hacía falta — medido, la etiqueta más larga ("Calendario de Flota") pide
   unos 195px con su sangría, más el distintivo: con 252 sobra sitio. Queda
   incluso MÁS estrecha que el original (268) y con el texto más grande, que era
   lo que se buscaba: filas que respiran sin robarle ancho a las tablas. */

.sidebar .nav-item {
  padding: 10px 12px;                  /* 8/10 */
  font-size: 15px;                     /* 13.5 */
  gap: 11px;                           /* 9 */
  letter-spacing: -0.005em;
}
.sidebar .nav-icon { width: 18px; height: 18px; }   /* 16 */

.sidebar .nav-group-head {
  padding: 11px 13px 11px 11px;        /* 9/11/9/9 */
  gap: 9px;
  font-size: 12px;                     /* 11 */
  letter-spacing: 0.075em;
}
.sidebar .nav-group-ico { width: 18px; height: 18px; }
.sidebar .nav-group-items { gap: 4px; padding-left: 9px; margin-left: -9px; }
.sidebar-nav { gap: 4px; }
.sidebar-user { padding: 13px 14px 18px; }
.sidebar-user .sidebar-user-nombre, .sidebar-user strong { font-size: 14px; }

/* ── El grupo donde estás ────────────────────────────────────────────────── */
/* Un lavado muy tenue y una línea a la izquierda que abarca el grupo entero.
   Nada de rojo aquí: el rojo es del item activo y si se repite deja de señalar.
   Es blanco al 3,5 %, que sobre la barra casi negra se ve como un escalón de
   luz — se nota que ese bloque está "encendido" sin leerlo. */
.sidebar .nav-group.tiene-activo {
  background: rgba(255,255,255,0.035);
  box-shadow: inset 2px 0 0 rgba(255,255,255,0.16);
}
.sidebar .nav-group.tiene-activo > .nav-group-head {
  color: rgba(255,255,255,0.82);       /* de 0.46: el rótulo del grupo despierta */
}
.sidebar .nav-group.tiene-activo > .nav-group-head .nav-group-ico { opacity: 1; }

/* Plegado ya tenía su punto rojo; se conserva y se le suma el lavado. */
.sidebar .nav-group.cerrado.tiene-activo { background: rgba(255,255,255,0.05); }

@media (max-width: 900px) {
  /* En pantallas estrechas se aprieta un poco más. */
  :root { --sidebar-w: 234px; }
  .sidebar .nav-item { font-size: 13.5px; padding: 8px 10px; }
}

/* Los logos que son texto (ISUZU) necesitan más caja a lo ancho que un símbolo
   redondo como la estrella: la palabra es apaisada. */
.veh-logo-svg.veh-logo-texto { width: 94%; height: auto; }

/* Los items DENTRO de un grupo llevan su propia altura fija y su sangría, en
   una regla más específica (`.nav-group-items .nav-item`) que la de arriba. Sin
   escalarlas también, la fuente crecía pero la fila se quedaba en 32px y el
   texto salía apretado — que es peor que no haber tocado nada. */
.sidebar .nav-item { height: 39px; }                       /* 34 → 39 */
.sidebar .nav-group-items .nav-item {
  height: 37px;                                            /* 32 → 37 */
  padding-left: 40px;   /* la sangría no crece: con la barra más estrecha, cada
                            píxel de sangría es un píxel menos de etiqueta */
  font-size: 14.5px;                                       /* 12.5 → 14.5 */
}
.sidebar .nav-fijos .nav-item { font-size: 15px; }

@media (max-width: 900px) {
  .sidebar .nav-item { height: 34px; }
  .sidebar .nav-group-items .nav-item { height: 32px; padding-left: 40px; font-size: 12.5px; }
  .sidebar .nav-fijos .nav-item { font-size: 13px; }
}

/* Vehículo privado (el Volvo): no es flota de producción. Se marca en vez de
   esconderlo — sigue estando en la casa, pero nadie debería contar con él para
   un rodaje sin preguntar. */
.veh-privado {
  display: inline-block; margin-left: 6px; padding: 1px 6px;
  font-size: 10px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--text-soft); border: 1px dashed var(--border-med);
}

/* ═══════════════════════════════════════════════════════════════════════════
   CAPA — UNA SOLA PALMERA, Y LA BARRA MÁS AIREADA

   La palmera se veía DOS veces y ahora se entiende por qué: son dos capas con
   la misma imagen pero colocadas distinto — la marca de agua anclada abajo
   (`align-items: flex-end`, ancho 100%) y la capa de luz centrada (ancho 116%).
   Nunca llegaron a solaparse, así que en vez de "una palmera que se ilumina
   bajo el cursor" se veían dos palmeras sueltas.

   Se alinean: misma caja, mismo ancho, mismo anclaje. Queda UNA, más grande, y
   la luz la recorre por dentro. El movimiento se baja de -1,2° a -0,35° y el
   salto de escala a la mitad: se nota que responde, no que salta.
   ═══════════════════════════════════════════════════════════════════════════ */
.sidebar-palm-watermark {
  align-items: flex-end;
  justify-content: center;
  /* Más grande, como se pidió. Sube desde el borde inferior, que es donde
     nace: `transform-origin` abajo hace que crecer no la despegue. */
  transform: scale(1.62) translateY(4%);
  transform-origin: 50% 100%;
  opacity: 0.075;
  /* La sombra roja se rebaja: encendía media barra. */
  filter: drop-shadow(0 0 26px rgba(var(--acento-rgb), 0.16));
  transition: opacity 0.55s ease, transform 0.75s cubic-bezier(0.22,1,0.36,1);
}
.sidebar-palm-watermark img { width: 100%; height: auto; transform: none; }

/* Hover: apenas se mueve. Antes giraba 1,2° y saltaba de 1,28 a 1,36. */
.sidebar:hover .sidebar-palm-watermark {
  opacity: 0.13;
  transform: scale(1.66) translateY(2.5%) rotate(-0.35deg);
}
.sidebar:hover .sidebar-palm-watermark img { transform: none; }

/* La capa de luz deja de ser una segunda palmera: se coloca EXACTAMENTE encima
   de la marca de agua para que sea la misma, iluminada. */
.sidebar-luz {
  align-items: flex-end;
  justify-content: center;
}
.sidebar-luz img {
  width: 100%;
  transform: scale(1.62) translateY(4%);
  transform-origin: 50% 100%;
  opacity: 0.16;
}
.sidebar:hover .sidebar-luz img { transform: scale(1.66) translateY(2.5%) rotate(-0.35deg); }
.sidebar.collapsed .sidebar-luz img { width: 100%; transform: scale(1.2) translateY(8%); opacity: 0.12; }
.sidebar.collapsed .sidebar-palm-watermark { transform: scale(1.2) translateY(8%); opacity: 0.05; }

/* ── Barra lateral: menos letra, más aire ────────────────────────────────────
   Petición: *"no pongas el texto tan grande, solo quiero que cada texto tenga
   más separación"*. Así que la fuente vuelve casi a su tamaño original y lo que
   crece es la CAJA: más alto de fila y más hueco entre ellas. */
.sidebar .nav-item { font-size: 13.5px; height: 40px; padding: 0 12px; }
.sidebar .nav-group-items .nav-item { font-size: 13px; height: 38px; padding-left: 40px; }
.sidebar .nav-fijos .nav-item { font-size: 13.5px; }
.sidebar .nav-group-items { gap: 6px; }      /* 4 → 6 entre hermanos */
.sidebar-nav { gap: 7px; }                   /* 4 → 7 entre grupos */
.sidebar .nav-group-head { font-size: 11px; padding: 12px 13px 12px 11px; }
.sidebar .nav-group.tiene-activo { padding-bottom: 3px; }

@media (max-width: 900px) {
  .sidebar .nav-item { height: 36px; }
  .sidebar .nav-group-items .nav-item { height: 34px; }
  .sidebar .nav-group-items { gap: 4px; }
  .sidebar-nav { gap: 5px; }
}

/* ── Una sola palmera, de verdad ─────────────────────────────────────────────
   Dos correcciones sobre lo de arriba, las dos medidas y no supuestas:

   1. La imagen de la marca de agua se quedaba en 128px porque una regla
      anterior le pone `max-width: 128px`, y un `width: 100%` NO anula un
      max-width. Hay que reponerlo a `none`.
   2. Alinear dos capas con la misma imagen es pelearse con la especificidad
      cada vez que se toque algo. Se elimina la SEGUNDA imagen: la palmera pasa
      a ser una sola —la marca de agua— y la capa de luz se queda solo con su
      halo, que es lo que sigue al cursor. Menos piezas, mismo efecto y más
      difícil de romper. */
.sidebar-palm-watermark img {
  width: 100%;
  max-width: none;
  height: auto;
  margin: 0;
  transform: none;
}

/* La capa de luz ya no lleva palmera: solo el halo. */
.sidebar-luz img { display: none; }
.sidebar-luz {
  /* Sin imagen, la máscara sobra: el halo se pinta en ::after. */
  -webkit-mask-image: none;
          mask-image: none;
  opacity: 1;                 /* el ::after ya nace transparente si no hay cursor */
}
.sidebar-luz::after {
  background: radial-gradient(240px 240px at var(--luz-x, 50%) var(--luz-y, 50%),
                rgba(255,255,255,0.055) 0%,
                rgba(var(--acento-rgb), 0.055) 38%,
                transparent 68%);
  opacity: 0;
  transition: opacity 0.4s ease;
}
.sidebar.con-luz .sidebar-luz::after { opacity: 1; }
.sidebar.collapsed .sidebar-luz { -webkit-mask-image: none; mask-image: none; }

/* ── Calendario de flota: mando de mes y zoom en la cabecera ─────────────── */
.cal-cab-mando { display: flex; align-items: center; gap: 6px; margin-left: auto; }
.cal-mes-btn {
  display: grid; place-items: center; width: 28px; height: 28px; padding: 0;
  color: var(--text-2); background: var(--surface);
  border: 1px solid var(--border-med); cursor: pointer;
}
.cal-mes-btn:hover { color: var(--text); border-color: var(--border-strong); background: var(--surface-2); }
.cal-cab-mando .cal-veh-mes {
  min-width: 130px; text-align: center;
  font-size: 14px; font-weight: 600; color: var(--text);
}
.cal-mes-hoy {
  padding: 0 11px; height: 28px;
  font: inherit; font-size: 12.5px; color: var(--text-2);
  background: var(--surface); border: 1px solid var(--border-med); cursor: pointer;
}
.cal-mes-hoy:hover { color: var(--text); border-color: var(--border-strong); }
.cal-cab-sep { width: 1px; height: 20px; background: var(--border-med); margin: 0 4px; }

.cal-zoom {
  display: flex; align-items: center;
  border: 1px solid var(--border-med); background: var(--surface);
}
.cal-zoom button {
  width: 26px; height: 28px; padding: 0;
  font: inherit; font-size: 15px; line-height: 1;
  color: var(--text-2); background: none; border: 0; cursor: pointer;
}
.cal-zoom button:hover:not(:disabled) { background: var(--surface-2); color: var(--text); }
.cal-zoom button:disabled { opacity: .3; cursor: default; }
.cal-zoom span {
  min-width: 44px; text-align: center;
  font-size: 11.5px; color: var(--text-soft); font-variant-numeric: tabular-nums;
  border-left: 1px solid var(--border); border-right: 1px solid var(--border);
  line-height: 28px;
}

/* Al hacer zoom, las celdas siguen al token. Se fija aquí para que las reglas
   que llevan el ancho a pelo no ganen. */
.cal-veh-table .cal-veh-th-day,
.cal-veh-table .cal-veh-td-day {
  width: var(--cal-zoom-w, 62px);
  min-width: var(--cal-zoom-w, 62px);
  max-width: var(--cal-zoom-w, 62px);
}

@media (max-width: 820px) {
  .cal-cab-mando { flex-wrap: wrap; }
  .cal-zoom, .cal-cab-sep { display: none; }   /* con ratón no hay pellizco */
}

/* ═══════════════════════════════════════════════════════════════════════════
   MANTENIMIENTO  (prefijo .mo-*)

   Plano a propósito: nada de tarjetas redondeadas ni sombras. La rejilla de
   cifras y la tabla van pegadas al fondo y se separan con líneas de 1px, que es
   como se lee un panel de taller de un vistazo.

   Los tres colores de aviso (ámbar, rojo, verde) se definen como tokens aquí y
   se redefinen en oscuro: son los únicos colores que se salen de la paleta de
   la casa, y lo hacen porque "vencido" tiene que gritar.
   ═══════════════════════════════════════════════════════════════════════════ */
:root {
  --mo-alerta:     #c62828;
  --mo-alerta-bg:  rgba(198,40,40,0.08);
  --mo-aviso:      #a86416;
  --mo-aviso-bg:   rgba(168,100,22,0.10);
  --mo-ok:         #2f6b46;
  --mo-ok-bg:      rgba(47,107,70,0.10);
  --mo-neutro-bg:  rgba(43,45,66,0.06);
}
:root[data-tema="oscuro"] {
  --mo-alerta:     #ff6b6b;
  --mo-alerta-bg:  rgba(255,107,107,0.13);
  --mo-aviso:      #e0a458;
  --mo-aviso-bg:   rgba(224,164,88,0.13);
  --mo-ok:         #6fcf97;
  --mo-ok-bg:      rgba(111,207,151,0.13);
  --mo-neutro-bg:  rgba(255,255,255,0.07);
}

/* ── Cifras de cabecera ─────────────────────────────────────────────────── */
.mo-kpis {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
  border: 1px solid var(--border);
  border-left: none;
  margin-bottom: 20px;
  background: var(--surface);
}
.mo-kpi {
  padding: 14px 16px;
  border-left: 1px solid var(--border);
}
.mo-kpi-num {
  font-size: 26px; font-weight: 700; line-height: 1.1;
  letter-spacing: -0.035em; color: var(--text);
}
.mo-kpi-eur .mo-kpi-num { font-size: 20px; }
.mo-kpi-lbl {
  margin-top: 3px;
  font-size: 10px; font-weight: 700; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--text-soft);
}
/* Solo se enciende cuando la cifra significa que algo va mal y hay que actuar.
   Si se encendiera siempre, dejaría de mirarse. */
.mo-kpi-alerta .mo-kpi-num { color: var(--mo-alerta); }

/* ── Pestañas internas ──────────────────────────────────────────────────── */
.mo-tabs {
  display: flex; gap: 2px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 16px;
}
.mo-tab {
  background: none; border: none; cursor: pointer;
  padding: 9px 15px; margin-bottom: -1px;
  font-size: 13.5px; font-weight: 600; color: var(--text-soft);
  border-bottom: 2px solid transparent;
  display: flex; align-items: center; gap: 7px;
  transition: color var(--transition), border-color var(--transition);
}
.mo-tab:hover { color: var(--text); }
.mo-tab.active { color: var(--text); border-bottom-color: var(--red); }
.mo-tab-n {
  font-size: 11px; font-weight: 700; padding: 1px 6px;
  background: var(--mo-neutro-bg); color: var(--text-soft);
}
.mo-tab.active .mo-tab-n { color: var(--text); }
.mo-tab-n.rojo { background: var(--mo-alerta-bg); color: var(--mo-alerta); }

/* ── Etiquetas de estado y prioridad ────────────────────────────────────── */
.mo-pill {
  display: inline-block; padding: 2px 8px;
  font-size: 11px; font-weight: 700; letter-spacing: 0.01em;
  white-space: nowrap;
  background: var(--mo-neutro-bg); color: var(--text-soft);
}
.mo-e-abierta { background: var(--mo-aviso-bg);   color: var(--mo-aviso); }
.mo-e-taller  { background: var(--mo-alerta-bg);  color: var(--mo-alerta); }
.mo-e-pieza   { background: var(--mo-neutro-bg);  color: var(--text); }
.mo-e-cerrada { background: var(--mo-ok-bg);      color: var(--mo-ok); }
.mo-e-venc    { background: var(--mo-alerta-bg);  color: var(--mo-alerta); }
.mo-e-urg     { background: var(--mo-aviso-bg);   color: var(--mo-aviso); }
.mo-e-prox    { background: var(--mo-neutro-bg);  color: var(--text-soft); }

/* La prioridad se lee de reojo: solo las dos que importan llevan color, y las
   otras dos se quedan en gris para no competir con ellas. */
.mo-prio { font-size: 12px; font-weight: 600; color: var(--text-soft); }
.mo-p-alta { color: var(--mo-aviso); }
.mo-p-crit { color: var(--mo-alerta); font-weight: 700; }

.mo-tabla td { vertical-align: top; }
.mo-tabla tbody tr { cursor: pointer; }
.mo-sub  { font-size: 11.5px; color: var(--text-soft); margin-top: 2px; }
.mo-nada { color: var(--text-xsoft); }
.mo-num, .mo-dias { text-align: right; white-space: nowrap; }
.mo-vencida { color: var(--mo-alerta); font-weight: 700; }
.mo-link { color: var(--red); text-decoration: none; }
.mo-link:hover { text-decoration: underline; }
.mo-nota {
  font-size: 12.5px; color: var(--text-soft);
  margin: 0 0 14px; max-width: 78ch; line-height: 1.5;
}
.mo-vacio { padding: 56px 20px; text-align: center; }
.mo-vacio-tit { font-size: 16px; font-weight: 600; margin: 10px 0 5px; }
.mo-vacio-sub { font-size: 13.5px; color: var(--text-soft); }

/* ── Ficha de la orden ──────────────────────────────────────────────────── */
.mo-ficha-top {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding-bottom: 14px; border-bottom: 1px solid var(--border); margin-bottom: 0;
}
.mo-ficha-tit    { font-size: 19px; font-weight: 700; letter-spacing: -0.02em; }
.mo-ficha-activo { font-size: 13px; color: var(--text-soft); }

/* Barra de estados: es lo que más se toca, así que va arriba y a tamaño de
   botón de verdad, no escondida en un desplegable. */
.mo-est-barra {
  display: flex; gap: 0; flex-wrap: wrap;
  border: 1px solid var(--border); border-top: none;
  margin-bottom: 20px; background: var(--surface);
}
.mo-est-btn {
  flex: 1; min-width: 120px;
  padding: 10px 12px; border: none; border-right: 1px solid var(--border);
  background: none; cursor: pointer;
  font-size: 12.5px; font-weight: 600; color: var(--text-soft);
  transition: background var(--transition), color var(--transition);
}
.mo-est-btn:last-child { border-right: none; }
.mo-est-btn:hover  { background: var(--bg-hover); color: var(--text); }
.mo-est-btn.active { color: var(--text); box-shadow: inset 0 -2px 0 var(--red); }
.mo-est-btn.active.mo-e-taller  { background: var(--mo-alerta-bg); }
.mo-est-btn.active.mo-e-cerrada { background: var(--mo-ok-bg); }
.mo-est-btn.active.mo-e-abierta { background: var(--mo-aviso-bg); }

.mo-ficha-cols { display: grid; grid-template-columns: 1fr 300px; gap: 28px; align-items: start; }
@media (max-width: 900px) { .mo-ficha-cols { grid-template-columns: 1fr; } }
.mo-bloque-tit {
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--text-soft);
  padding-bottom: 7px; border-bottom: 1px solid var(--border);
  margin: 0 0 14px;
}
.mo-ficha-main .mo-bloque-tit:not(:first-child) { margin-top: 28px; }
.mo-campo { margin-bottom: 13px; }
.mo-campo label {
  display: block; margin-bottom: 4px;
  font-size: 11.5px; font-weight: 600; color: var(--text-soft);
}
.mo-input {
  width: 100%; padding: 7px 10px;
  border: 1px solid var(--border-med); background: var(--surface);
  color: var(--text); font-size: 13.5px; font-family: inherit;
  border-radius: 0;
}
.mo-input:focus { outline: none; border-color: var(--red); }
.mo-input:disabled { background: var(--surface-2); color: var(--text-soft); cursor: default; }
.mo-input textarea, textarea.mo-input { resize: vertical; line-height: 1.5; }
.mo-fila2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.mo-elige {
  width: 100%; text-align: left; padding: 8px 10px;
  border: 1px solid var(--border-med); background: var(--surface);
  color: var(--text); font-size: 13.5px; font-family: inherit; cursor: pointer;
}
.mo-elige:hover { border-color: var(--red); }
.mo-meta {
  margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--border);
  font-size: 11.5px; color: var(--text-soft); line-height: 1.7;
}

/* Hilo de seguimiento: cada nota con su autor y su fecha. */
.mo-nota-nueva { display: flex; gap: 8px; align-items: flex-start; margin-bottom: 16px; }
.mo-nota-nueva textarea { flex: 1; }
.mo-nota-item { padding: 9px 0; border-bottom: 1px solid var(--border); }
.mo-nota-item:last-child { border-bottom: none; }
.mo-nota-meta { font-size: 11px; color: var(--text-soft); margin-bottom: 3px; }
.mo-nota-txt  { font-size: 13.5px; line-height: 1.5; white-space: pre-wrap; }

/* El tema tiene tres estados: claro forzado, oscuro forzado y automático (sin
   atributo). Sin este bloque los avisos de mantenimiento se quedarían con los
   colores de claro para quien no ha tocado el interruptor y tiene el sistema
   en oscuro — que es la mayoría. */
@media (prefers-color-scheme: dark) {
  :root:not([data-tema="claro"]) {
    --mo-alerta:     #ff6b6b;
    --mo-alerta-bg:  rgba(255,107,107,0.13);
    --mo-aviso:      #e0a458;
    --mo-aviso-bg:   rgba(224,164,88,0.13);
    --mo-ok:         #6fcf97;
    --mo-ok-bg:      rgba(111,207,151,0.13);
    --mo-neutro-bg:  rgba(255,255,255,0.07);
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   ECONOMÍA  (prefijo .eco-*, capa nueva)

   Mismo lenguaje que Mantenimiento: rejillas planas separadas por líneas de
   1px, sin tarjetas flotantes ni franjas de color. Las clases antiguas
   (.eco-stat-card, .eco-panel…) siguen en el archivo pero ya no se usan: el
   render nuevo no las emite.

   Los cuatro tonos de las barras NO son decorativos — codifican cuánto de firme
   es el dinero, de lo más seguro (facturado, tono lleno) a lo más incierto
   (borrador, casi transparente). Por eso van del mismo color en distinta
   intensidad y no de cuatro colores distintos: la escala tiene un orden y los
   colores tienen que enseñarlo.
   ═══════════════════════════════════════════════════════════════════════════ */
:root {
  --eco-firme:  #2b2d42;
  --eco-gasto:  #c62828;
}
:root[data-tema="oscuro"] { --eco-firme: #cdd3e0; --eco-gasto: #ff6b6b; }
@media (prefers-color-scheme: dark) {
  :root:not([data-tema="claro"]) { --eco-firme: #cdd3e0; --eco-gasto: #ff6b6b; }
}

.eco-t-cont  { background: var(--eco-firme); }
.eco-t-acep  { background: color-mix(in srgb, var(--eco-firme) 62%, transparent); }
.eco-t-env   { background: color-mix(in srgb, var(--eco-firme) 34%, transparent); }
.eco-t-borr  { background: color-mix(in srgb, var(--eco-firme) 16%, transparent); }
.eco-t-gasto { background: var(--eco-gasto); }

/* ── Cifras ─────────────────────────────────────────────────────────────── */
.eco-kpis {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(158px, 1fr));
  border: 1px solid var(--border); border-left: none;
  background: var(--surface); margin-bottom: 26px;
}
.eco-kpi { padding: 15px 17px; border-left: 1px solid var(--border); }
.eco-kpi-num {
  font-size: 22px; font-weight: 700; letter-spacing: -0.035em;
  line-height: 1.15; color: var(--text);
}
.eco-kpi-lbl {
  margin-top: 4px; font-size: 10px; font-weight: 700; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--text-soft);
}
.eco-kpi-sub { margin-top: 3px; font-size: 11.5px; color: var(--text-xsoft); }
.eco-kpi-gasto .eco-kpi-num { color: var(--eco-gasto); }

/* ── Secciones ──────────────────────────────────────────────────────────── */
.eco-seccion { margin-bottom: 30px; }
.eco-tit {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--text-soft);
  padding-bottom: 8px; border-bottom: 1px solid var(--border); margin-bottom: 14px;
}
.eco-tit-n {
  font-size: 11px; letter-spacing: 0; padding: 1px 6px;
  background: var(--mo-neutro-bg); color: var(--text-soft);
}
.eco-leyenda { display: flex; gap: 13px; flex-wrap: wrap; margin-left: auto; }
.eco-lg {
  display: flex; align-items: center; gap: 5px;
  font-size: 10px; letter-spacing: 0.04em; color: var(--text-soft);
}
.eco-lg i { width: 9px; height: 9px; display: block; }
.eco-nota { font-size: 12.5px; color: var(--text-soft); margin: -6px 0 12px; }
.eco-sinDatos { padding: 26px 0; color: var(--text-soft); font-size: 13px; }

/* ── Embudo ─────────────────────────────────────────────────────────────── */
.eco-embudo {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  border: 1px solid var(--border); border-left: none; background: var(--surface);
}
.eco-etapa { padding: 13px 15px; border-left: 1px solid var(--border); }
.eco-etapa-cab { display: flex; align-items: center; gap: 7px; }
.eco-etapa-txt { font-size: 11.5px; font-weight: 600; color: var(--text-soft); }
.eco-etapa-n {
  font-size: 10.5px; font-weight: 700; padding: 0 5px;
  background: var(--mo-neutro-bg); color: var(--text-soft);
}
.eco-etapa-val {
  margin: 5px 0 8px; font-size: 18px; font-weight: 700;
  letter-spacing: -0.03em; color: var(--text);
}
.eco-etapa-barra { height: 3px; background: var(--mo-neutro-bg); }
.eco-etapa-barra i {
  display: block; height: 100%;
  background: color-mix(in srgb, var(--eco-firme) 40%, transparent);
}
.eco-etapa-fin .eco-etapa-barra i { background: var(--eco-firme); }
.eco-etapa-fin .eco-etapa-val { color: var(--text); }

/* ── Gráfico mensual ────────────────────────────────────────────────────── */
.eco-graf {
  display: flex; gap: 12px; align-items: flex-start;
  border: 1px solid var(--border); background: var(--surface);
  padding: 16px 16px 10px;
}
/* El eje da la referencia que faltaba: sin un número arriba, una barra alta no
   dice si son mil euros o cien mil. */
/* La altura del eje tiene que ser EXACTAMENTE la del área de barras (180px) y
   empezar en la misma línea, o el "0" del eje no cae donde apoyan las barras y
   toda la referencia queda corrida. */
.eco-eje {
  display: flex; flex-direction: column; justify-content: space-between;
  height: 180px; margin-top: 19px;
  font-size: 10px; color: var(--text-xsoft); text-align: right;
  white-space: nowrap; border-right: 1px solid var(--border); padding-right: 9px;
}
/* `overflow-x: auto` también recorta por arriba, y la cifra de la columna más
   alta vive justo encima de la barra. Estos 19px son el sitio donde cabe; el
   eje lleva el mismo margen para que su "0" siga cayendo en la base. */
.eco-cols {
  flex: 1; display: flex; align-items: flex-end; gap: 3px;
  overflow-x: auto; min-width: 0; padding-top: 19px;
}
.eco-col { flex: 1; min-width: 34px; display: flex; flex-direction: column; }
/* La cifra va pegada a SU barra, no en una fila fija arriba: con un mes flojo
   el número se quedaba flotando lejos de la columna que describía. */
.eco-col-cima {
  position: absolute; left: 0; right: 0;
  font-size: 9.5px; color: var(--text-soft);
  text-align: center; white-space: nowrap; pointer-events: none;
}
.eco-col-pistas {
  position: relative;
  height: 180px; display: flex; align-items: flex-end;
  justify-content: center; gap: 2px;
}
/* Ingreso y gasto van uno al lado del otro, no apilados: apilarlos sugeriría
   que suman, cuando en realidad se restan. */
.eco-col-ingreso, .eco-col-gasto {
  display: flex; flex-direction: column; justify-content: flex-end; height: 100%;
}
.eco-col-ingreso { width: 60%; max-width: 30px; }
.eco-col-gasto   { width: 26%; max-width: 12px; }
.eco-col-ingreso i, .eco-col-gasto i { display: block; width: 100%; }
.eco-col:hover .eco-col-ingreso i { filter: brightness(1.15); }
.eco-col-mes {
  padding-top: 6px; font-size: 10px; color: var(--text-soft);
  text-align: center; white-space: nowrap;
}

/* ── Por proyecto ───────────────────────────────────────────────────────── */
.eco-proy {
  display: grid; grid-template-columns: minmax(120px, 200px) 1fr 42px 100px;
  align-items: center; gap: 14px;
  padding: 9px 0; border-bottom: 1px solid var(--border);
}
.eco-proy:last-child { border-bottom: none; }
.eco-proy-nom {
  font-size: 13.5px; font-weight: 600; display: flex; align-items: center; gap: 7px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.eco-proy-n {
  font-size: 10px; font-weight: 700; padding: 0 5px; flex-shrink: 0;
  background: var(--mo-neutro-bg); color: var(--text-soft);
}
.eco-proy-barra { display: flex; height: 12px; background: var(--mo-neutro-bg); }
.eco-proy-barra i { display: block; height: 100%; }
.eco-proy-pct { font-size: 11.5px; color: var(--text-soft); text-align: right; }
.eco-proy-eur { font-size: 13.5px; font-weight: 700; text-align: right; white-space: nowrap; }

@media (max-width: 720px) {
  .eco-proy { grid-template-columns: 1fr 60px; }
  .eco-proy-barra, .eco-proy-pct { display: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   PRESUPUESTOS: DOCUMENTO, SELLOS Y PAPELERA

   Dos colores con significado, y solo dos:
     · VERDE  = contabilizado. Está cerrado y cobrado, no hay nada que hacer.
     · ROJO   = anulado. Existe, pero no cuenta.
   Se pintan sobre la FILA ENTERA, no en un icono al final: la pregunta "¿cuál
   de estos ya está?" se responde barriendo la lista con la vista, no leyendo
   columna por columna.

   El rojo de la casa (--accent) se usa aquí para lo accionable —el botón de
   editar, el número del documento, la línea del estado activo—, que es lo que
   pedía más contraste. El rojo de "anulado" es OTRO tono, más apagado, para que
   no compita con él.
   ═══════════════════════════════════════════════════════════════════════════ */
:root {
  --pres-ok:      #2f6b46;
  --pres-ok-bg:   rgba(47,107,70,0.09);
  --pres-ok-bd:   rgba(47,107,70,0.30);
  --pres-no:      #a33a3a;
  --pres-no-bg:   rgba(163,58,58,0.09);
  --pres-no-bd:   rgba(163,58,58,0.30);
}
:root[data-tema="oscuro"] {
  --pres-ok:      #6fcf97;
  --pres-ok-bg:   rgba(111,207,151,0.11);
  --pres-ok-bd:   rgba(111,207,151,0.34);
  --pres-no:      #e57373;
  --pres-no-bg:   rgba(229,115,115,0.11);
  --pres-no-bd:   rgba(229,115,115,0.34);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-tema="claro"]) {
    --pres-ok:    #6fcf97;
    --pres-ok-bg: rgba(111,207,151,0.11);
    --pres-ok-bd: rgba(111,207,151,0.34);
    --pres-no:    #e57373;
    --pres-no-bg: rgba(229,115,115,0.11);
    --pres-no-bd: rgba(229,115,115,0.34);
  }
}

/* ── Filas teñidas ──────────────────────────────────────────────────────── */
/* El borde izquierdo es lo que hace que se lea como una fila marcada y no como
   un fallo de zebra: el fondo solo, tan tenue, se confunde con el hover. */
.tabla tbody tr.pres-fila-contab {
  background: var(--pres-ok-bg);
  box-shadow: inset 3px 0 0 var(--pres-ok);
}
.tabla tbody tr.pres-fila-contab:hover { background: color-mix(in srgb, var(--pres-ok-bg) 170%, transparent); }
.tabla tbody tr.pres-fila-anulada {
  background: var(--pres-no-bg);
  box-shadow: inset 3px 0 0 var(--pres-no);
  opacity: 0.78;
}
.tabla tbody tr.pres-fila-anulada:hover { opacity: 1; }
/* Tachado solo en el número: tachar la fila entera la vuelve ilegible, y sigue
   habiendo que poder leer de quién era y por cuánto. */
.tabla tbody tr.pres-fila-anulada .pres-td-num { text-decoration: line-through; }

.pres-td-num {
  font-family: var(--font-mono); font-size: 12px;
  font-weight: 600; color: var(--text-soft);
}
.pres-fila-contab .pres-td-num { color: var(--pres-ok); }
.pres-fila-anulada .pres-td-num { color: var(--pres-no); }

.pres-sello-ok {
  display: inline-block; margin-left: 6px; padding: 1px 6px;
  font-size: 10px; font-weight: 700; letter-spacing: 0.03em;
  background: var(--pres-ok-bg); color: var(--pres-ok);
  border: 1px solid var(--pres-ok-bd);
}

/* Botón de contabilizar: cuadrado como todo lo demás. Antes llevaba el verde
   #34C759 y un radio de 6px metidos a pelo en el HTML — el único botón
   redondeado de la pantalla. */
/* El texto del botón no puede ser blanco fijo: en claro el verde es oscuro
   (#2f6b46) y pide blanco, pero en oscuro es claro (#6fcf97) y el blanco sobre
   él no se lee. `--pres-ok-txt` lleva el color que contrasta en cada tema. */
:root { --pres-ok-txt: #fff; }
:root[data-tema="oscuro"] { --pres-ok-txt: #10241a; }
@media (prefers-color-scheme: dark) {
  :root:not([data-tema="claro"]) { --pres-ok-txt: #10241a; }
}
.btn.btn-contab {
  background: var(--pres-ok); color: var(--pres-ok-txt);
  border: 1px solid var(--pres-ok); border-radius: 0;
  font-weight: 600;
}
.btn.btn-contab:hover { filter: brightness(1.08); }
.btn.pd-borrar:hover, .btn.pres-borrar-def:hover {
  color: var(--pres-no); border-color: var(--pres-no-bd);
}
.seg-btn.seg-btn-papelera.active { color: var(--pres-no); }

/* ── Barra del documento ────────────────────────────────────────────────── */
.pd-barra {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 12px 0 13px; margin-bottom: 0;
  border-bottom: 2px solid var(--accent);
}
.pd-ident { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
/* Aquí es donde pega el rojo de la casa: es la identidad del documento que
   estás mirando, y con ella la pantalla deja de ser gris sobre gris. */
.pd-num {
  font-family: var(--font-mono); font-size: 15px; font-weight: 700;
  letter-spacing: -0.01em; color: var(--accent);
}
.pd-cli { font-size: 12px; color: var(--text-soft); }
.pd-total { margin-left: auto; text-align: right; }
.pd-total-n { font-size: 19px; font-weight: 700; letter-spacing: -0.03em; }
.pd-acciones { display: flex; gap: 6px; flex-wrap: wrap; }

.pd-sello {
  display: inline-block; margin-left: 6px; padding: 2px 7px;
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.04em;
}
.pd-sello-ok { background: var(--pres-ok-bg); color: var(--pres-ok); border: 1px solid var(--pres-ok-bd); }
.pd-sello-no { background: var(--pres-no-bg); color: var(--pres-no); border: 1px solid var(--pres-no-bd); }

.pd-cinta {
  padding: 9px 14px; font-size: 12.5px; line-height: 1.5;
  border-left: 3px solid;
}
.pd-cinta-ok { background: var(--pres-ok-bg); color: var(--pres-ok); border-left-color: var(--pres-ok); }
.pd-cinta-no { background: var(--pres-no-bg); color: var(--pres-no); border-left-color: var(--pres-no); }
.pd-cinta-motivo { font-style: italic; opacity: 0.85; }

/* ── El papel ───────────────────────────────────────────────────────────── */
/* Fondo hundido y sombra bajo la hoja: es el único sitio de la web donde una
   sombra está justificada, porque lo que hay dentro ES una hoja de papel y
   tiene que leerse como tal, no como otro panel de la interfaz. */
.pd-lienzo {
  background: var(--surface-sunk);
  border: 1px solid var(--border); border-top: none;
  padding: 22px; display: flex; justify-content: center;
  min-height: 60vh;
  /* Con la ventana estrecha la hoja no cabe y hay que poder arrastrarla, no
     verla cortada: el documento tiene un ancho de papel, no responsive. */
  overflow-x: auto;
}
@media (max-width: 820px) { .pd-lienzo { padding: 10px; } }
/* El ancho, el alto y la escala los pone `_pdAjustarEscala()` en JS: dependen
   del formato de hoja configurado (A3/A4) y del sitio disponible. */
.pd-lienzo { display: block; overflow: hidden; }
.pd-lienzo iframe {
  display: block; margin: 0 auto;
  border: none; background: #fff;
  box-shadow: 0 2px 14px rgba(0,0,0,0.18);
}

/* ═══════════════════════════════════════════════════════════════════════════
   PESTAÑAS DE TAMAÑO FIJO

   Antes eran `flex: 0 1 auto` entre 110 y 230px: cada pestaña medía según su
   título y todas cambiaban de ancho al abrir o cerrar otra. Con anchos que
   bailan, el aspa nunca está dos veces en el mismo sitio y cerrar exige
   apuntar. Ahora todas miden lo mismo y el aspa cae siempre en el mismo píxel
   relativo, con un hueco claro respecto al texto.
   ═══════════════════════════════════════════════════════════════════════════ */
.tabbar .tab {
  flex: 0 0 208px;
  width: 208px; min-width: 208px; max-width: 208px;
  gap: 10px;                 /* separación evidente entre el texto y el aspa */
  padding: 8px 6px 8px 13px;
}
/* El texto ocupa lo que sobra y se recorta con puntos suspensivos; el aspa no
   se encoge nunca. Ese es el mecanismo que la fija en su sitio. */
.tabbar .tab .tab-txt { flex: 1 1 auto; min-width: 0; }
.tabbar .tab .tab-x   { flex: 0 0 auto; margin-left: 0; }

/* Con anchos fijos, la barra desplaza cuando no caben. Es lo correcto: antes
   se estrujaban hasta ser ilegibles. */
.tabbar { scroll-behavior: smooth; }

/* NO se encogen en pantallas estrechas. Se pidió expresamente que el ancho no
   varíe nunca: una pestaña que mide distinto según la ventana vuelve a mover el
   aspa de sitio, que era justo el problema que se arregló. Si no caben, la
   barra desplaza. */

/* ═══════════════════════════════════════════════════════════════════════════
   CABECERA DE LA BARRA LATERAL: MÁS ALTA Y PULSABLE
   ═══════════════════════════════════════════════════════════════════════════ */
.sidebar-logo {
  height: 66px;              /* 52 → 66 */
  padding: 0 14px;
  cursor: pointer;
  transition: background var(--transition);
}
.sidebar-logo:hover { background: var(--bg-hover); }
.sidebar-logo:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.sidebar-logo .logo-title { font-size: 15px; }
.sidebar-logo .logo-sub   { font-size: 11px; }
.sidebar-logo .logo-mark img { width: 32px !important; height: 32px !important; }

/* ═══════════════════════════════════════════════════════════════════════════
   PALMERA: HOVER UN 15% MÁS VISTOSO
   Sube la opacidad (0,13 → 0,15), el salto de escala y el giro. Sigue siendo
   un gesto contenido —no salta—, solo se nota más que responde.
   ═══════════════════════════════════════════════════════════════════════════ */
.sidebar:hover .sidebar-palm-watermark {
  opacity: 0.15;
  transform: scale(1.70) translateY(2%) rotate(-0.5deg);
  filter: drop-shadow(0 0 30px rgba(var(--acento-rgb), 0.22));
}

/* ═══════════════════════════════════════════════════════════════════════════
   MODO CLARO: CONTRASTE

   El oscuro funciona porque el rojo cae sobre un fondo casi negro. El claro no
   tenía ese salto, y medido se veía por qué:

     · --text-soft (#8d99ae) sobre blanco = 2,88:1. El mínimo legible es 4,5.
       Y ese token pinta CASI TODO el texto secundario: rótulos, subtítulos,
       cabeceras de tabla, etiquetas de cifras. De ahí la sensación de lavado.
     · --bg contra --surface = 1,13:1. Las tarjetas no se despegaban del fondo.
     · --accent (#ef233c) sobre blanco = 4,22:1, justo por debajo del listón
       tanto como texto rojo como con texto blanco encima.

   Se corrigen los tres. No se toca --text (13,49:1, ya estaba bien) ni nada del
   modo oscuro. El rojo se oscurece lo justo para cruzar la línea (4,89:1): es
   el mismo rojo a la vista, solo que legible.

   Va scopeado a los DOS estados claros —el forzado y el automático— porque un
   `:root` suelto aquí, al final del archivo, pisaría también al oscuro.
   ═══════════════════════════════════════════════════════════════════════════ */
:root[data-tema="claro"],
:root:not([data-tema="oscuro"]) {
  /* Texto secundario: 2,88 → 5,38:1 */
  --text-soft:     #5f6b80;
  /* Terciario: sigue siendo el más flojo, pero ya se lee (≈3,6:1) */
  --text-xsoft:    #7b8698;
  --text-2:        rgba(43,45,66,0.86);

  /* El fondo se aleja del blanco para que las superficies se despeguen */
  --bg:            #dde5eb;
  --surface-sunk:  #d3dde4;
  --surface-2:     #eef2f5;

  /* Bordes de verdad: con 9% de opacidad las líneas de 1px no existían */
  --border:        rgba(43,45,66,0.15);
  --border-med:    rgba(43,45,66,0.26);
  --border-strong: rgba(43,45,66,0.40);
  --bg-hover:      rgba(43,45,66,0.06);

  /* Rojo de la casa, un punto más profundo SOLO en claro: 4,22 → 4,89:1 */
  --punch-red:     #e01230;
  --acento-rgb:    224, 18, 48;
}
/* En automático solo debe aplicarse si el sistema está en claro; el bloque de
   arriba usa :not([data-tema="oscuro"]), que también atrapa el automático. */
@media (prefers-color-scheme: dark) {
  :root:not([data-tema="claro"]) {
    --text-soft:     #8b93a8;
    --text-xsoft:    rgba(139,147,168,0.66);
    --text-2:        rgba(233,234,240,0.76);
    --bg:            #0f0f13;
    --surface-sunk:  #0b0b0f;
    --surface-2:     #1e1e26;
    --border:        rgba(255,255,255,0.10);
    --border-med:    rgba(255,255,255,0.17);
    --border-strong: rgba(255,255,255,0.30);
    --bg-hover:      rgba(255,255,255,0.05);
    --punch-red:     #ff4d5f;
    --acento-rgb:    255, 77, 95;
  }
}

/* ── Ficha de vehículo: bloques agrupados ─────────────────────────────────── */
.vf-bloques {
  display: grid; grid-template-columns: 1.35fr 1fr; gap: 22px;
  align-items: start; margin-bottom: 22px;
}
@media (max-width: 900px) { .vf-bloques { grid-template-columns: 1fr; gap: 16px; } }
.vf-bloque { margin-bottom: 22px; }
.vf-bloque-tit {
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--text-soft);
  padding-bottom: 7px; border-bottom: 1px solid var(--border); margin-bottom: 13px;
}
.vf-notas { font-size: 13.5px; line-height: 1.6; white-space: pre-wrap; }
.vf-menor { font-size: 11.5px; font-weight: 400; color: var(--text-soft); }
.eco-tit-ayuda {
  font-size: 10px; font-weight: 500; letter-spacing: 0;
  text-transform: none; color: var(--text-xsoft);
}

/* El desplegable genérico ocupa el ancho de su campo, no el del texto. */
.cat-dd-wrap.dd-bloque { display: flex; width: 100%; }
.cat-dd-wrap.dd-bloque > .selector-boton {
  width: 100%; justify-content: space-between;
  display: flex; align-items: center; gap: 8px;
}
.cat-dd-wrap.dd-bloque > .selector-boton.vacio { color: var(--text-soft); }
.cat-dd-wrap.dd-bloque .cat-dd { min-width: 100%; }
.pres-sub-fila .cat-dd-wrap.dd-bloque { flex: 1; min-width: 0; }
/* Fila resaltada con las flechas del teclado */
.cat-dd-fila.resaltada { background: var(--surface-2); box-shadow: inset 2px 0 0 var(--accent); }

/* ── Ajustes generales ────────────────────────────────────────────────────── */
.aj-seccion { margin-bottom: 32px; max-width: 900px; }
.aj-tit {
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--text-soft);
  padding-bottom: 8px; border-bottom: 1px solid var(--border); margin-bottom: 12px;
}
.aj-nota { font-size: 12.5px; color: var(--text-soft); line-height: 1.55; margin: 0 0 14px; }
.aj-nota code {
  font-family: var(--font-mono); font-size: 11.5px;
  background: var(--mo-neutro-bg); padding: 1px 5px;
}
.aj-aviso {
  padding: 9px 14px; margin-bottom: 22px;
  background: var(--mo-neutro-bg); color: var(--text-soft);
  font-size: 12.5px; border-left: 3px solid var(--border-med);
}

/* Se elige mirando, no leyendo: cada plantilla enseña una miniatura de cómo
   queda el papel. Con cuatro nombres a secas nadie sabe cuál es cuál. */
.aj-plantillas { display: grid; grid-template-columns: repeat(auto-fit, minmax(168px, 1fr)); gap: 12px; }
.aj-plantilla {
  display: flex; flex-direction: column; gap: 7px;
  padding: 12px; text-align: left; cursor: pointer;
  background: var(--surface); border: 1px solid var(--border);
  color: var(--text); font-family: inherit;
  transition: border-color var(--transition), background var(--transition);
}
.aj-plantilla:hover:not(:disabled) { border-color: var(--border-med); }
.aj-plantilla:disabled { cursor: default; opacity: 0.7; }
.aj-plantilla.activa { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.aj-pl-nom { font-size: 13.5px; font-weight: 600; display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.aj-pl-tag {
  font-size: 9.5px; font-weight: 700; letter-spacing: 0.05em;
  padding: 1px 5px; background: var(--accent); color: #fff;
}
.aj-pl-desc { font-size: 11.5px; color: var(--text-soft); line-height: 1.45; }

/* Miniatura: una hoja con su banda de cabecera y tres renglones. */
.aj-pl-vista {
  display: block; height: 74px; padding: 8px;
  background: #fff; border: 1px solid var(--border-med); overflow: hidden;
}
.aj-pl-vista i { display: block; background: #c9ced8; height: 4px; margin-bottom: 5px; }
.aj-pl-vista .aj-pl-cab { height: 13px; margin-bottom: 8px; }
.aj-pl-vista .corta { width: 55%; }
.aj-pl-palma  .aj-pl-cab { background: #ef233c; }
.aj-pl-clasico .aj-pl-cab { background: #1d1d1f; }
.aj-pl-moderno .aj-pl-cab { background: #8d99ae; height: 18px; }
.aj-pl-cine   { background: #17171d; }
.aj-pl-cine .aj-pl-cab { background: #ef233c; }
.aj-pl-cine i:not(.aj-pl-cab) { background: #444a58; }

.aj-rejilla { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 16px; }
.aj-campo { display: block; }
.aj-campo > span {
  display: block; margin-bottom: 5px;
  font-size: 11.5px; font-weight: 600; color: var(--text-soft);
}
.aj-campo input {
  width: 100%; padding: 7px 10px; border-radius: 0;
  border: 1px solid var(--border-med); background: var(--surface);
  color: var(--text); font-size: 13.5px; font-family: inherit;
}
.aj-campo input:focus { outline: none; border-color: var(--accent); }
.aj-campo input:disabled { background: var(--surface-2); color: var(--text-soft); }
.aj-campo em { display: block; margin-top: 4px; font-size: 11px; font-style: normal; color: var(--text-xsoft); }

/* ── IT Stock: secciones del parque ───────────────────────────────────────── */
.it-familias { display: flex; gap: 8px; flex-wrap: wrap; margin: 0 0 14px; }
.it-fam {
  display: inline-flex; align-items: center; gap: 7px;
  height: 34px; padding: 0 13px; cursor: pointer;
  background: var(--surface); border: 1px solid var(--border);
  color: var(--text-soft); font-family: inherit; font-size: 13px; font-weight: 600;
  transition: border-color var(--transition), color var(--transition);
}
.it-fam:hover { color: var(--text); border-color: var(--border-med); }
.it-fam i {
  font-style: normal; font-size: 11px; font-weight: 700;
  padding: 1px 6px; background: var(--mo-neutro-bg); color: var(--text-soft);
}
.it-fam.activa { color: var(--text); border-color: var(--accent); box-shadow: inset 0 -2px 0 var(--accent); }
.it-fam.activa i { background: var(--accent); color: #fff; }

/* ═══════════════════════════════════════════════════════════════════════════
   BARRA LATERAL: LA PALMERA SIN CAJA, Y EL AVATAR SIN EL ROJO

   El logo vivía dentro de un cuadrado de 36px con fondo y borde que le comía
   la silueta: una palmera recortada dentro de una caja no se lee como un logo,
   se lee como un icono metido a la fuerza. Fuera la caja — queda la palmera y,
   al lado, el nombre.

   El avatar llevaba fondo y borde rojos con la inicial en AZUL (#4FC3FF).
   Además de ser el único azul de toda la web, el rojo ahí no significaba nada:
   en el resto de la interfaz el rojo es "esto se puede pulsar" o "esto va mal",
   y una inicial no es ninguna de las dos.
   ═══════════════════════════════════════════════════════════════════════════ */
.logo-mark,
.sidebar-logo .logo-mark {
  width: 40px; height: 40px;
  background: none;
  border: none;
  overflow: visible;
}
.sidebar-logo:hover .logo-mark {
  background: none;
  border: none;
}
.logo-mark img,
.sidebar-logo .logo-mark img {
  width: 40px !important; height: 40px !important;
  object-fit: contain;
  filter: invert(1) brightness(1.08);
  transition: transform 0.25s cubic-bezier(0.22,1,0.36,1);
}
.sidebar-logo:hover .logo-mark img { transform: scale(1.06); }
.sidebar.collapsed .logo-mark,
.sidebar.collapsed .logo-mark img { width: 32px !important; height: 32px !important; }

/* Avatar: gris neutro con la inicial legible, del mismo material que el resto
   de la barra. */
.sidebar-avatar {
  background: rgba(255,255,255,0.10);
  border: 1px solid rgba(255,255,255,0.16);
  color: rgba(255,255,255,0.88);
}
.perfil-avatar-img,
.perfil-avatar-placeholder { border-color: var(--border-med); }

/* ═══════════════════════════════════════════════════════════════════════════
   CALENDARIO DE FLOTA: EL EVENTO OCUPA LA FILA ENTERA

   La barra medía 38px dentro de una fila de 60, así que flotaba con 11px de
   aire arriba y abajo. Ocupando el alto completo la rejilla se lee como una
   hoja de cálculo: la celda está pintada o no lo está, sin ambigüedad, y el
   ojo puede seguir una columna de días de arriba abajo sin saltos.
   ═══════════════════════════════════════════════════════════════════════════ */
/* Dos cosas hacían que no bastara con `height: 100%`:

     1. La barra no cuelga del `td` sino de un `.cal-cell-wrap` intermedio, que
        además llevaba `padding: 4px 0` — cuatro píxeles arriba y abajo que
        impedían llegar al borde.
     2. La altura real la fijaba una regla MÁS ESPECÍFICA por posición dentro
        del tramo (`.cal-veh-td-day.cal-run-start .cal-cell-inner`, etc.) con
        34px. Una regla de un solo nivel no la gana.

   Así que se anula el padding del envoltorio y se pone la altura en las mismas
   posiciones de tramo, que son las que mandan. */
.cal-veh-td-day .cal-cell-wrap { padding: 0; gap: 0; }
.cal-veh-td-day .cal-cell-inner.filled,
.cal-veh-td-day.cal-run-start .cal-cell-inner,
.cal-veh-td-day.cal-run-mid   .cal-cell-inner,
.cal-veh-td-day.cal-run-end   .cal-cell-inner,
.cal-veh-td-day.cal-run-solo  .cal-cell-inner,
.cal-veh-table .cal-veh-td-day .cal-cell-inner {
  height: 100%;
  min-height: 0;
  /* Sin margen lateral: los tramos de días consecutivos tienen que tocarse,
     como en una hoja de cálculo. */
  margin: 0;
  justify-content: center;
}

/* El relieve se rebaja: a 38px daba volumen a una píldora; a toda altura,
   sobre una rejilla, ese brillo interior solo ensucia la línea de la celda. */
.cal-cell-inner.filled {
  box-shadow:
    inset 0  1px 0 rgba(255,255,255,0.18),
    inset 0 -1px 0 rgba(0,0,0,0.14);
}
.cal-cell-inner.filled::after {
  background: linear-gradient(to bottom,
    rgba(255,255,255,0.10) 0%,
    rgba(255,255,255,0.02) 50%,
    rgba(0,0,0,0.07) 100%);
}
/* La etiqueta se centra también en horizontal cuando el tramo es de un solo
   día: pegada a la izquierda en una celda estrecha se corta enseguida. */
.cal-veh-td-day.cal-run-solo .cal-cell-inner { align-items: center; }

/* ── Pedir un texto ───────────────────────────────────────────────────────── */
.mt-ayuda { font-size: 12.5px; color: var(--text-soft); line-height: 1.5; margin: 0 0 14px; }
.mt-input {
  width: 100%; padding: 9px 11px; border-radius: 0;
  border: 1px solid var(--border-med); background: var(--surface);
  color: var(--text); font-size: 14px; font-family: inherit;
}
.mt-input:focus { outline: none; border-color: var(--accent); }
.mt-sugerencias { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 11px; }
.mt-sug {
  padding: 4px 10px; cursor: pointer; font-family: inherit; font-size: 12px;
  background: var(--surface-2); border: 1px solid var(--border);
  color: var(--text-soft);
}
.mt-sug:hover { color: var(--text); border-color: var(--accent); }

/* ── Ficha de material ────────────────────────────────────────────────────── */
/* Con la ficha abierta se esconde el resto de la sección. Es una clase en la
   página y no cirugía en el HTML: la lista, el panel de cifras y los filtros
   son hermanos sueltos sin contenedor común. */
#page-inventario.mat-ficha-abierta > *:not(#mat-ficha) { display: none !important; }

.mat-top {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding-bottom: 14px; border-bottom: 2px solid var(--accent); margin-bottom: 18px;
}
.mat-ident { min-width: 0; }
.mat-nombre { font-size: 18px; font-weight: 700; letter-spacing: -0.02em; }
.mat-ruta { font-size: 12px; color: var(--text-soft); }

.mat-cifras {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  border: 1px solid var(--border); border-left: none;
  background: var(--surface); margin-bottom: 26px;
}
.mat-cifra { padding: 13px 16px; border-left: 1px solid var(--border); }
.mat-cifra b { display: block; font-size: 21px; font-weight: 700; letter-spacing: -0.035em; }
.mat-cifra span {
  display: block; margin-top: 3px;
  font-size: 10px; font-weight: 700; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--text-soft);
}

.mat-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 30px; align-items: start; }
@media (max-width: 900px) { .mat-cols { grid-template-columns: 1fr; gap: 20px; } }
.mat-datos { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 1px; background: var(--border); }
.mat-dato { padding: 10px 12px; background: var(--surface); }
.mat-dato-etq { font-size: 10px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-soft); }
.mat-dato-val { margin-top: 3px; font-size: 13.5px; font-weight: 600; }

.mat-hist-fila {
  display: grid; grid-template-columns: 1fr auto; gap: 4px 12px;
  padding: 10px 0; border-bottom: 1px solid var(--border); cursor: pointer;
}
.mat-hist-fila:last-child { border-bottom: none; }
.mat-hist-fila:hover .mat-hist-proy { color: var(--accent); }
.mat-hist-proy { font-size: 13.5px; font-weight: 600; }
.mat-hist-meta { grid-column: 1; font-size: 11.5px; color: var(--text-soft); }
.mat-hist-dias { grid-row: 1 / span 2; align-self: center; font-size: 13px; font-weight: 700; color: var(--text-soft); }
.mat-vacio { padding: 22px 0; font-size: 13px; color: var(--text-soft); }

/* El widget de material más alquilado lleva a la ficha */
.topmat-fila.topmat-clic { cursor: pointer; }
.topmat-fila.topmat-clic:hover .topmat-nombre { color: var(--accent); text-decoration: underline; }

/* ── Mi Perfil: el resumen ────────────────────────────────────────────────── */
#mp-resumen { margin-bottom: 30px; }
.mp-bloque { margin-bottom: 28px; }
.mp-admin, .mp-plantilla {
  margin-left: auto; text-transform: none; letter-spacing: 0;
  font-size: 11px; font-weight: 600; color: var(--text-soft);
}
.mp-admin { color: var(--accent); }

/* Mapa de permisos: las áreas SIN acceso también salen. Ver lo que no tienes
   es la mitad de la información. */
.mp-permisos { display: grid; grid-template-columns: repeat(auto-fit, minmax(168px, 1fr)); gap: 1px; background: var(--border); }
.mp-perm { padding: 10px 12px; background: var(--surface); }
.mp-perm-area { display: block; font-size: 13px; font-weight: 600; }
.mp-perm-nivel {
  display: block; margin-top: 3px;
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
}
.mp-n-ninguno            { opacity: 0.55; }
.mp-n-ninguno .mp-perm-nivel { color: var(--text-xsoft); }
.mp-n-lectura .mp-perm-nivel { color: var(--text-soft); }
.mp-n-edicion .mp-perm-nivel { color: var(--mo-aviso); }
.mp-n-total   .mp-perm-nivel { color: var(--accent); }
.mp-n-total   { box-shadow: inset 2px 0 0 var(--accent); }

.mp-caps { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
.mp-cap {
  font-size: 11px; font-weight: 600; padding: 2px 8px;
  background: var(--mo-neutro-bg); color: var(--text-soft);
}

.mp-cifras {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  border: 1px solid var(--border); border-left: none;
  background: var(--surface); margin-bottom: 16px;
}
.mp-cifra { padding: 13px 15px; border-left: 1px solid var(--border); }
.mp-cifra b { display: block; font-size: 20px; font-weight: 700; letter-spacing: -0.035em; }
.mp-cifra span {
  display: block; margin-top: 3px;
  font-size: 10px; font-weight: 700; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--text-soft);
}
.mp-cifra i { display: block; margin-top: 2px; font-size: 11px; font-style: normal; color: var(--text-xsoft); }

.mp-fila {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 9px 0; border-bottom: 1px solid var(--border); cursor: pointer;
}
.mp-fila:last-child { border-bottom: none; }
.mp-fila:hover .mp-fila-txt { color: var(--accent); }
.mp-fila-num { font-family: var(--font-mono); font-size: 12px; font-weight: 600; color: var(--text-soft); }
.mp-fila-txt { flex: 1; min-width: 0; font-size: 13.5px; font-weight: 600; }
.mp-fila-eur { font-size: 13.5px; font-weight: 700; white-space: nowrap; }

.mp-areas { display: grid; gap: 7px; margin-bottom: 16px; }
.mp-area { display: grid; grid-template-columns: 120px 1fr 40px; align-items: center; gap: 12px; }
.mp-area-nom { font-size: 12.5px; font-weight: 600; }
.mp-area-barra { height: 10px; background: var(--mo-neutro-bg); }
.mp-area-barra i { display: block; height: 100%; background: var(--eco-firme); }
.mp-area-n { font-size: 12px; color: var(--text-soft); text-align: right; }

.mp-lista-log .mp-log {
  display: grid; grid-template-columns: 110px 1fr; gap: 10px;
  padding: 6px 0; border-bottom: 1px solid var(--border);
  font-size: 12.5px;
}
.mp-lista-log .mp-log:last-child { border-bottom: none; }
.mp-log-ts { color: var(--text-xsoft); font-size: 11px; white-space: nowrap; }

/* ═══════════════════════════════════════════════════════════════════════════
   EDITOR DE PLANTILLAS
   Tres columnas: los bloques que puedes meter, la hoja, y las propiedades de
   lo seleccionado. La hoja va sobre fondo hundido y en blanco siempre —también
   en modo oscuro— porque lo que se está montando es papel, y el papel se
   imprime blanco.
   ═══════════════════════════════════════════════════════════════════════════ */
.pl-barra {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding-bottom: 13px; border-bottom: 2px solid var(--accent); margin-bottom: 0;
}
.pl-nombre { font-size: 17px; font-weight: 700; letter-spacing: -0.02em; }
.pl-sub { font-size: 12px; color: var(--text-soft); }
.pl-sucio {
  font-size: 11px; font-weight: 700; letter-spacing: 0.04em;
  padding: 3px 8px; background: var(--mo-aviso-bg); color: var(--mo-aviso);
}

.pl-cols {
  display: grid; grid-template-columns: 210px 1fr 260px;
  gap: 0; align-items: stretch;
  border: 1px solid var(--border); border-top: none;
  min-height: 70vh;
}
@media (max-width: 1100px) { .pl-cols { grid-template-columns: 180px 1fr; } .pl-props { display: none; } }
@media (max-width: 780px)  { .pl-cols { grid-template-columns: 1fr; } .pl-paleta { display: none; } }

.pl-paleta, .pl-props { padding: 14px; background: var(--surface); overflow-y: auto; max-height: 78vh; }
.pl-paleta { border-right: 1px solid var(--border); }
.pl-props  { border-left: 1px solid var(--border); }
.pl-props-vacio { font-size: 12.5px; color: var(--text-soft); line-height: 1.55; }
.pl-props-acciones { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--border); }

.pl-pieza {
  padding: 8px 10px; margin-bottom: 6px; cursor: grab;
  background: var(--surface-2); border: 1px solid var(--border);
  transition: border-color var(--transition);
}
.pl-pieza:hover { border-color: var(--accent); }
.pl-pieza:active { cursor: grabbing; }
.pl-pieza-nom  { display: block; font-size: 12.5px; font-weight: 600; }
.pl-pieza-desc { display: block; margin-top: 2px; font-size: 10.5px; color: var(--text-soft); line-height: 1.35; }

.pl-lienzo { background: var(--surface-sunk); padding: 22px; overflow-y: auto; max-height: 78vh; }
/* La hoja siempre blanca: se está montando papel. */
.pl-hoja {
  max-width: 720px; margin: 0 auto; min-height: 60vh;
  background: #fff; color: #1d1d1f;
  padding: 34px 38px; box-shadow: 0 2px 14px rgba(0,0,0,0.18);
}
.pl-hoja-vacia { padding: 70px 20px; text-align: center; color: #98a0ae; font-size: 13.5px; line-height: 1.7; }

.pl-bloque { position: relative; padding: 4px 0; cursor: grab; border: 1px dashed transparent; }
.pl-bloque:hover { border-color: #d7dbe3; }
.pl-bloque.sel { border-color: var(--accent); background: rgba(239,35,60,0.03); }
.pl-bloque.encima { border-top: 2px solid var(--accent); }
.pl-bloque-eti {
  position: absolute; top: -9px; left: 0; z-index: 2;
  display: none; align-items: center; gap: 6px;
  background: var(--accent); color: #fff; padding: 1px 4px 1px 7px;
  font-size: 9.5px; font-weight: 700; letter-spacing: 0.05em;
}
.pl-bloque:hover .pl-bloque-eti, .pl-bloque.sel .pl-bloque-eti { display: flex; }
.pl-bloque-x { background: none; border: none; color: #fff; cursor: pointer; font-size: 13px; line-height: 1; padding: 0 4px; }
.pl-bloque-x:hover { opacity: 0.7; }

.pl-vista.al-centro   { text-align: center; }
.pl-vista.al-derecha  { text-align: right; }
.pl-vista.tam-pequeno { font-size: 11px; }
.pl-vista.tam-normal  { font-size: 13px; }
.pl-vista.tam-grande  { font-size: 16px; }

/* Vistas de cada bloque, con los datos de ejemplo */
.plv-logo { display: flex; align-items: center; gap: 10px; }
.plv-logo img { width: 34px; height: 34px; object-fit: contain; }
.plv-logo span { font-size: 17px; font-weight: 700; letter-spacing: -0.02em; }
/* Los colores salen del estilo de la plantilla (variables puestas en la hoja),
   para que el editor enseñe lo mismo que va a salir impreso. */
.plv-empresa { color: var(--doc-suave, #55607a); line-height: 1.6; font-size: 11.5px; }
.plv-titulo { font-size: 20px; font-weight: 700; letter-spacing: -0.02em; margin: 4px 0; color: var(--doc-titulo, #1d1d1f); }
.plv-titulo span { color: var(--doc-acento, var(--accent)); }
.plv-etq { display: block; font-size: 9.5px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--doc-suave, #98a0ae); margin-bottom: 3px; opacity: 0.85; }
.plv-cliente { background: color-mix(in srgb, var(--doc-th-bg, #2b2d42) 10%, transparent); padding: 10px 13px; }
.plv-menor { color: var(--doc-suave, #55607a); font-size: 11.5px; }
.plv-fechas { display: flex; gap: 22px; color: var(--doc-suave, #55607a); font-size: 11.5px; }
.plv-tabla { width: 100%; border-collapse: collapse; font-size: 11px; }
.plv-tabla th { background: var(--doc-th-bg, #2b2d42); color: var(--doc-th-tx, #fff); text-align: left; padding: 6px 8px; font-size: 9.5px; letter-spacing: 0.04em; text-transform: uppercase; }
.plv-tabla td { padding: 6px 8px; border-bottom: 1px solid color-mix(in srgb, var(--doc-suave, #55607a) 25%, transparent); }
.plv-tabla .n { text-align: right; }
.plv-totales { margin-left: auto; max-width: 260px; font-size: 12px; }
.plv-totales > div { display: flex; justify-content: space-between; padding: 4px 0; }
.plv-totales .plv-total { border-top: 2px solid var(--doc-th-bg, #2b2d42); margin-top: 4px; padding-top: 7px; font-size: 15px; font-weight: 700; }
.plv-notas, .plv-texto { color: var(--doc-suave, #55607a); font-size: 11.5px; line-height: 1.6; white-space: pre-wrap; }
.plv-firma { display: inline-block; min-width: 200px; }
.plv-firma span { font-size: 10.5px; color: var(--doc-suave, #98a0ae); }
.plv-firma i { display: block; height: 40px; border-bottom: 1px solid color-mix(in srgb, var(--doc-suave, #55607a) 55%, transparent); }
.plv-sep { height: 1px; background: color-mix(in srgb, var(--doc-suave, #55607a) 35%, transparent); margin: 6px 0; }

.pl-seg { display: flex; border: 1px solid var(--border-med); }
.pl-seg button {
  flex: 1; padding: 5px 4px; cursor: pointer; font-family: inherit; font-size: 11.5px;
  background: none; border: none; border-right: 1px solid var(--border);
  color: var(--text-soft);
}
.pl-seg button:last-child { border-right: none; }
.pl-seg button.activo { background: var(--accent); color: #fff; font-weight: 600; }

.aj-pl-editar { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 10px; }

/* ═══════════════════════════════════════════════════════════════════════════
   BARRA CERRADA: REABRE LA PALMERA, NO EL BOTÓN

   Cerrada, la barra es una tira estrecha y el botón de reabrir era un cuadrito
   más dentro de ella: había que apuntar. La palmera ya está ahí, es lo más
   grande y lo único que se reconoce de un vistazo, así que es ella la que
   reabre. El botón se retira mientras está cerrada —no hay dos formas de hacer
   lo mismo compitiendo por el mismo sitio— y vuelve al abrirla, que es cuando
   sí hace falta un control explícito para cerrar.
   ═══════════════════════════════════════════════════════════════════════════ */
.sidebar.collapsed .sidebar-collapse-btn { display: none; }
.sidebar.collapsed .sidebar-logo {
  cursor: pointer;
  justify-content: center;
  padding: 0;
}
/* La palmera crece un poco y se enciende al pasar por encima: es la señal de
   que ahí se pulsa. */
.sidebar.collapsed .logo-mark img {
  transition: transform 0.22s cubic-bezier(0.22,1,0.36,1), filter 0.22s;
}
.sidebar.collapsed .sidebar-logo:hover .logo-mark img {
  transform: scale(1.16);
  filter: invert(1) brightness(1.3) drop-shadow(0 0 10px rgba(var(--acento-rgb), 0.55));
}
.sidebar.collapsed .sidebar-logo:hover { background: rgba(255,255,255,0.06); }

/* ═══════════════════════════════════════════════════════════════════════════
   CALENDARIO DE FLOTA: RAYAS CONTINUAS, HOVER DE TRAMO, TEXTO Y "HOY"
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 1. Las rayas de ITV y mantenimiento continúan de un día al siguiente ──
   Cada celda pintaba su propio degradado desde SU esquina, así que el patrón
   se reiniciaba en cada día y las diagonales se rompían en cada línea de la
   rejilla. Desplazando el origen del fondo por la posición de la celda dentro
   del mes (`--cal-dia`, que ya venía en el `<td>`), las diagonales de un tramo
   de cinco días se leen como una sola banda continua. */
.cal-veh-td-day.cal-event-itv .cal-cell-inner,
.cal-veh-td-day.cal-event-mantenimiento .cal-cell-inner,
.cal-veh-table .cal-veh-td-day.cal-event-itv .cal-cell-inner,
.cal-veh-table .cal-veh-td-day.cal-event-mantenimiento .cal-cell-inner {
  /* El desfase lo calcula `_calSincronizarRayas()` en JS con la posición REAL
     de la celda. Calcularlo en CSS a partir del ancho teórico no valía: entre
     celda y celda hay 1px de borde, así que el patrón se iba desviando un
     píxel por día y las diagonales acababan sin cuadrar. Aquí solo se declara
     el valor de partida. */
  background-position: var(--raya-x, 0px) 0;
  background-repeat: repeat;
}

/* ── 2. El hover cubre el TRAMO entero, no una celda ──
   Un evento de cinco días es una sola cosa; iluminar solo el cuadrado bajo el
   cursor lo partía en cinco. La clase la pone `_calResaltarTramo()`, que
   recorre los días contiguos del mismo vehículo y el mismo evento. */
.cal-veh-td-day.tramo-hover .cal-cell-inner {
  filter: brightness(1.13) saturate(1.04);
}
.cal-veh-td-day.tramo-hover { background: rgba(var(--acento-rgb), 0.04); }
/* El realce de una sola celda se retira: lo sustituye el del tramo. */
.cal-veh-td-day.cal-assigned .cal-cell-inner:hover,
.cal-veh-table .cal-veh-td-day.cal-assigned .cal-cell-inner:hover { filter: none; }

/* ── 3. Texto un punto más grande ──
   Con la barra a 38px el texto a 10px era lo que cabía. Ahora ocupa los 60px
   de la fila y ese tamaño se queda pequeño para el espacio que tiene. */
.cal-veh-table .cal-cell-label,
.cal-cell-label { font-size: 11.5px; letter-spacing: -0.005em; }
.cal-veh-td-day .cal-cell-inner { font-size: 12px; }

/* ── 4. "Hoy" como en el calendario del dashboard ──
   Allí el día actual se marca tiñendo la columna y poniendo en rojo el número
   y el nombre del día. Aquí era una raya azul de 2px sobre CADA celda de la
   columna: una línea horizontal repetida 30 veces que se confundía con la
   rejilla en vez de señalar la columna. */
.cal-veh-td-day.cal-today-col::before { display: none; }
.cal-veh-table .cal-veh-th-day.cal-today-col,
.cal-veh-th-day.cal-today-col {
  /* El resalte de HOY es un tinte, y la cabecera se queda quieta mientras el
     cuerpo pasa por debajo: sin papel opaco debajo se le transparentan las
     barras a través. Va en dos propiedades y no en el atajo `background`
     porque el atajo con `!important` borraba también la imagen. */
  background-color: var(--surface-2) !important;
  background-image: linear-gradient(rgba(var(--acento-rgb), 0.14), rgba(var(--acento-rgb), 0.14)) !important;
  box-shadow: inset 0 -2px 0 var(--accent);
}
.cal-veh-th-day.cal-today-col .cal-day-num {
  color: var(--accent) !important; font-weight: 800;
}
.cal-veh-th-day.cal-today-col .cal-day-name {
  color: var(--accent) !important; opacity: 1;
}
.cal-veh-table .cal-veh-td-day.cal-today-col,
.cal-veh-table .cal-veh-td-day.cal-weekend.cal-today-col {
  background: rgba(var(--acento-rgb), 0.055);
}

/* ── Ajustes: empresa y fondo ─────────────────────────────────────────────── */
.aj-textarea {
  width: 100%; padding: 8px 10px; border-radius: 0; resize: vertical;
  border: 1px solid var(--border-med); background: var(--surface);
  color: var(--text); font-size: 13.5px; font-family: inherit; line-height: 1.5;
}
.aj-textarea:focus { outline: none; border-color: var(--accent); }
.aj-falta { color: var(--mo-alerta) !important; font-weight: 600; }

.aj-fondo { display: flex; gap: 18px; align-items: flex-start; flex-wrap: wrap; }
/* La proporción de la vista previa es la de la hoja, no un cuadrado: un fondo
   se juzga por cómo cae en la página. */
.aj-fondo-vista {
  width: 148px; aspect-ratio: 1 / 1.414;
  border: 1px solid var(--border-med); background: #fff;
  display: flex; align-items: center; justify-content: center; overflow: hidden;
  flex-shrink: 0;
}
.aj-fondo-vista img { width: 100%; height: 100%; object-fit: cover; display: block; }
.aj-fondo-vista span { font-size: 11.5px; color: #98a0ae; }
.aj-fondo-acciones { display: flex; flex-direction: column; gap: 8px; align-items: flex-start; }
.aj-fondo-nota { font-size: 11.5px; color: var(--text-soft); max-width: 34ch; line-height: 1.5; }

/* ── Editor de plantillas: hoja con su formato real y su fondo ────────────── */
/* La hoja del editor mide lo que va a medir el documento. Antes era una caja
   de ancho fijo sin relación con el papel, así que se montaba a ciegas: lo que
   parecía media página podía salir ocupando dos. */
.pl-hoja { position: relative; }
.pl-hoja.hoja-a4 { max-width: 700px; aspect-ratio: 210 / 297; }
.pl-hoja.hoja-a3 { max-width: 760px; aspect-ratio: 297 / 420; }
/* `aspect-ratio` marca la proporción de la PRIMERA página; si los bloques
   ocupan más, la hoja crece (como crecería el documento). */
.pl-hoja.hoja-a4, .pl-hoja.hoja-a3 { height: auto; min-height: 0; }
.pl-fondo {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; z-index: 0; pointer-events: none;
}
/* Los bloques van POR ENCIMA del fondo, y con un velo blanco muy leve detrás
   del texto para que se lea sobre fondos oscuros sin tapar el diseño. */
.pl-hoja > .pl-bloque, .pl-hoja > .pl-hoja-vacia { position: relative; z-index: 1; }

/* ── Proyectos: calendario resumido arriba de General ─────────────────────── */
/* Duplica la vista del calendario en corto. Va plegado en un <details> para
   que no coma pantalla: quien viene a la lista tiene la lista a un clic, y
   quien viene a ver fechas ya las tiene delante. */
.proy-cal-mini {
  background: var(--surface); border: 1px solid var(--border);
  margin-bottom: 16px;
}
.proy-cal-mini > summary {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 14px; cursor: pointer; list-style: none;
  font-size: 12px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--text-soft);
}
.proy-cal-mini > summary::-webkit-details-marker { display: none; }
.proy-cal-mini > summary::before {
  content: ''; width: 0; height: 0; flex-shrink: 0;
  border-left: 5px solid currentColor;
  border-top: 4px solid transparent; border-bottom: 4px solid transparent;
  transition: transform 0.2s ease;
}
.proy-cal-mini[open] > summary::before { transform: rotate(90deg) translateX(1px); }
.proy-cal-mini > summary:hover { color: var(--text); }
.pcm-sub {
  text-transform: none; letter-spacing: 0; font-weight: 500;
  font-size: 11.5px; color: var(--text-xsoft);
}
.pcm-ver {
  margin-left: auto; background: none; border: none; cursor: pointer;
  font-family: inherit; font-size: 11.5px; font-weight: 600;
  text-transform: none; letter-spacing: 0; color: var(--accent);
}
.pcm-ver:hover { text-decoration: underline; }
#proy-cal-mini-grid { padding: 0 14px 12px; }
/* Más bajo que el completo: aquí se mira el conjunto, no cada barra. */
#proy-cal-mini-grid .proy-cal-fila { min-height: 26px; }
#proy-cal-mini-grid .proy-cal-etq { font-size: 11.5px; }
#proy-cal-mini-grid .proy-cal-barra-txt { font-size: 10.5px; }
#proy-cal-mini-grid .proy-cal-vacio { padding: 20px 0; }

/* ═══════════════════════════════════════════════════════════════════════════
   ITV Y MANTENIMIENTO: COLOR DE TALLER Y ETIQUETA LEGIBLE

   El ámbar anterior tiraba a naranja de aviso y competía con los colores de
   los proyectos. La ITV y el mantenimiento no son proyectos: son taller, así
   que van en azul acero y grafito —el color de las herramientas— y quedan
   claramente fuera de la paleta de los rodajes.

   Se distinguen entre sí por tono, no por saturación: la ITV en acero (es un
   trámite, previsible) y el mantenimiento en grafito rojizo (algo se rompió).
   ═══════════════════════════════════════════════════════════════════════════ */
.cal-veh-td-day.cal-event-itv .cal-cell-inner,
.cal-veh-td-day.cal-event-itv.cal-run-solo .cal-cell-inner,
.cal-veh-td-day.cal-event-itv.cal-run-start .cal-cell-inner,
.cal-veh-td-day.cal-event-itv.cal-run-mid .cal-cell-inner,
.cal-veh-td-day.cal-event-itv.cal-run-end .cal-cell-inner,
.cal-veh-table .cal-veh-td-day.cal-event-itv .cal-cell-inner,
.cal-veh-table .cal-veh-td-day.cal-event-itv.cal-run-solo .cal-cell-inner,
.cal-veh-table .cal-veh-td-day.cal-event-itv.cal-run-start .cal-cell-inner,
.cal-veh-table .cal-veh-td-day.cal-event-itv.cal-run-mid .cal-cell-inner,
.cal-veh-table .cal-veh-td-day.cal-event-itv.cal-run-end .cal-cell-inner {
  background-image: repeating-linear-gradient(-45deg,
    #5c7d99, #5c7d99 7px, #4d6b83 7px, #4d6b83 14px) !important;
}
.cal-veh-td-day.cal-event-mantenimiento .cal-cell-inner,
.cal-veh-td-day.cal-event-mantenimiento.cal-run-solo .cal-cell-inner,
.cal-veh-td-day.cal-event-mantenimiento.cal-run-start .cal-cell-inner,
.cal-veh-td-day.cal-event-mantenimiento.cal-run-mid .cal-cell-inner,
.cal-veh-td-day.cal-event-mantenimiento.cal-run-end .cal-cell-inner,
.cal-veh-table .cal-veh-td-day.cal-event-mantenimiento .cal-cell-inner,
.cal-veh-table .cal-veh-td-day.cal-event-mantenimiento.cal-run-solo .cal-cell-inner,
.cal-veh-table .cal-veh-td-day.cal-event-mantenimiento.cal-run-start .cal-cell-inner,
.cal-veh-table .cal-veh-td-day.cal-event-mantenimiento.cal-run-mid .cal-cell-inner,
.cal-veh-table .cal-veh-td-day.cal-event-mantenimiento.cal-run-end .cal-cell-inner {
  background-image: repeating-linear-gradient(-45deg,
    #8f5a52, #8f5a52 7px, #7a4a43 7px, #7a4a43 14px) !important;
}

/* La etiqueta, más grande y con sombra: sobre un rayado, el texto fino a 10px
   se pierde entre las diagonales. */
.cal-veh-td-day.cal-event-itv .cal-cell-label,
.cal-veh-td-day.cal-event-mantenimiento .cal-cell-label,
.cal-veh-table .cal-veh-td-day.cal-event-itv .cal-cell-label,
.cal-veh-table .cal-veh-td-day.cal-event-mantenimiento .cal-cell-label {
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.04em;
  color: #fff;
  text-shadow: 0 1px 2px rgba(0,0,0,0.45);
  max-width: none;
}

/* Los chips del selector de arriba, con los mismos colores que pintan. */
.cal-veh-chip-itv, .cal-tipo-itv { border-color: #5c7d99 !important; color: #7d9db8 !important; }
.cal-veh-chip-mant, .cal-tipo-mantenimiento { border-color: #8f5a52 !important; color: #b07d74 !important; }
/* La etiqueta real de estos eventos es `.cal-ev-tit` dentro de `.cal-ev-txt`,
   no `.cal-cell-label`. Se le aplica lo mismo. */
.cal-veh-td-day.cal-event-itv .cal-ev-tit,
.cal-veh-td-day.cal-event-mantenimiento .cal-ev-tit,
.cal-veh-table .cal-veh-td-day.cal-event-itv .cal-ev-tit,
.cal-veh-table .cal-veh-td-day.cal-event-mantenimiento .cal-ev-tit {
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.04em;
  color: #fff;
  text-shadow: 0 1px 2px rgba(0,0,0,0.45);
}

/* Dentro de un mismo tramo de ITV o mantenimiento no se pinta la línea que
   separa los días: con la fase del rayado ya sincronizada, ese 1px era lo
   último que seguía partiendo la banda en trozos. La línea sí se mantiene al
   final del tramo, que es donde de verdad separa algo. */
.cal-veh-table .cal-veh-td-day.cal-event-itv.cal-run-start,
.cal-veh-table .cal-veh-td-day.cal-event-itv.cal-run-mid,
.cal-veh-table .cal-veh-td-day.cal-event-mantenimiento.cal-run-start,
.cal-veh-table .cal-veh-td-day.cal-event-mantenimiento.cal-run-mid,
.cal-veh-td-day.cal-event-itv.cal-run-start,
.cal-veh-td-day.cal-event-itv.cal-run-mid,
.cal-veh-td-day.cal-event-mantenimiento.cal-run-start,
.cal-veh-td-day.cal-event-mantenimiento.cal-run-mid {
  border-right-color: transparent;
}
/* Y el remate: una línea fina arriba y abajo que cierra la banda de punta a
   punta, para que se lea como una sola pieza. */
.cal-veh-td-day.cal-event-itv .cal-cell-inner,
.cal-veh-td-day.cal-event-mantenimiento .cal-cell-inner {
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.22), inset 0 -1px 0 rgba(0,0,0,0.22) !important;
}

/* ── La causa real de la asimetría ────────────────────────────────────────
   El primer y el último día de un tramo llevaban 3px de margen y un padding
   distinto —el redondeo tipo "píldora" de los eventos de proyecto—, así que
   medían 48px mientras los del medio medían 50. Como el degradado se origina
   en el CENTRO de su caja, dos cajas de distinto ancho tienen distinta fase:
   por eso las diagonales cuadraban entre los días centrales y se rompían justo
   en los extremos.

   Para ITV y mantenimiento la banda va a sangre: mismo ancho en todas las
   celdas, sin margen, sin padding lateral y sin redondeo. Los eventos de
   proyecto conservan su píldora, que ahí sí tiene sentido. */
.cal-veh-td-day.cal-event-itv .cal-cell-inner,
.cal-veh-td-day.cal-event-itv.cal-run-solo .cal-cell-inner,
.cal-veh-td-day.cal-event-itv.cal-run-start .cal-cell-inner,
.cal-veh-td-day.cal-event-itv.cal-run-mid .cal-cell-inner,
.cal-veh-td-day.cal-event-itv.cal-run-end .cal-cell-inner,
.cal-veh-table .cal-veh-td-day.cal-event-itv .cal-cell-inner,
.cal-veh-table .cal-veh-td-day.cal-event-itv.cal-run-solo .cal-cell-inner,
.cal-veh-table .cal-veh-td-day.cal-event-itv.cal-run-start .cal-cell-inner,
.cal-veh-table .cal-veh-td-day.cal-event-itv.cal-run-mid .cal-cell-inner,
.cal-veh-table .cal-veh-td-day.cal-event-itv.cal-run-end .cal-cell-inner,
.cal-veh-td-day.cal-event-mantenimiento .cal-cell-inner,
.cal-veh-td-day.cal-event-mantenimiento.cal-run-solo .cal-cell-inner,
.cal-veh-td-day.cal-event-mantenimiento.cal-run-start .cal-cell-inner,
.cal-veh-td-day.cal-event-mantenimiento.cal-run-mid .cal-cell-inner,
.cal-veh-td-day.cal-event-mantenimiento.cal-run-end .cal-cell-inner,
.cal-veh-table .cal-veh-td-day.cal-event-mantenimiento .cal-cell-inner,
.cal-veh-table .cal-veh-td-day.cal-event-mantenimiento.cal-run-solo .cal-cell-inner,
.cal-veh-table .cal-veh-td-day.cal-event-mantenimiento.cal-run-start .cal-cell-inner,
.cal-veh-table .cal-veh-td-day.cal-event-mantenimiento.cal-run-mid .cal-cell-inner,
.cal-veh-table .cal-veh-td-day.cal-event-mantenimiento.cal-run-end .cal-cell-inner {
  margin: 0 !important;
  padding-left: 0 !important;
  padding-right: 0 !important;
  border-radius: 0 !important;
  width: 100% !important;
}
/* La marca vertical de inicio de tramo tampoco: parte la banda. */
.cal-veh-td-day.cal-event-itv .cal-cell-inner::before,
.cal-veh-td-day.cal-event-mantenimiento .cal-cell-inner::before { display: none !important; }
/* El velo vertical de volumen se quita: sobre un rayado solo lo ensucia. */
.cal-veh-td-day.cal-event-itv .cal-cell-inner::after,
.cal-veh-td-day.cal-event-mantenimiento .cal-cell-inner::after { display: none !important; }
/* La etiqueta necesita su hueco ahora que no hay padding en la celda. */
.cal-veh-td-day.cal-event-itv.cal-run-start .cal-ev-txt,
.cal-veh-td-day.cal-event-itv.cal-run-solo .cal-ev-txt,
.cal-veh-td-day.cal-event-mantenimiento.cal-run-start .cal-ev-txt,
.cal-veh-td-day.cal-event-mantenimiento.cal-run-solo .cal-ev-txt { padding-left: 8px; }

/* ── La palmera SÍ se ve con la barra cerrada ─────────────────────────────
   Había una regla de la época en que el botón de contraer ocupaba ese hueco:
   `.sidebar.collapsed .logo-mark { opacity: 0; width: 0 }`. Como ahora la
   palmera ES el botón de reabrir, esa regla la dejaba invisible — el elemento
   estaba ahí, con su tamaño y su imagen cargada, pero a opacidad 0. Por eso la
   cabecera salía en blanco.

   Es también la razón de que las comprobaciones de posición y tamaño no
   detectaran nada: lo único mal era la opacidad del PADRE. */
.sidebar.collapsed .logo-mark {
  opacity: 1;
  width: 34px;
  margin: 0;
  overflow: visible;
}
.sidebar.collapsed .logo-mark img { width: 34px !important; height: 34px !important; }

/* ── Avatares por defecto: rojo y negro, planos y variados ────────────────
   Todos llevaban el mismo degradado rojo→negro. Con 42 empleados la lista se
   convertía en una pared repetida y las iniciales dejaban de distinguir a
   nadie. Seis variantes planas dentro de la paleta de la casa, repartidas por
   el nombre para que cada persona tenga siempre la suya. */
.emp-avatar {
  background: var(--accent) !important;
  color: #fff;
  border: 1px solid transparent;
  letter-spacing: 0.02em;
}
.emp-avatar[data-av="1"] { background: var(--text) !important; color: #fff; }
.emp-avatar[data-av="2"] {
  background: transparent !important; color: var(--accent);
  border-color: var(--accent);
}
.emp-avatar[data-av="3"] {
  background: transparent !important; color: var(--text);
  border-color: var(--border-strong);
}
.emp-avatar[data-av="4"] { background: #a3122a !important; color: #fff; }
.emp-avatar[data-av="5"] {
  background: var(--mo-neutro-bg) !important; color: var(--text);
  border-color: var(--border-med);
}

/* ── Ajustes: cada plantilla con su botón de editar debajo ────────────────── */
.aj-pl-caja {
  display: flex; flex-direction: column;
  border: 1px solid var(--border); background: var(--surface);
}
.aj-pl-caja.activa { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.aj-pl-caja .aj-plantilla { border: none; background: none; flex: 1; }
.aj-pl-caja .aj-plantilla:hover:not(:disabled) { background: var(--bg-hover); }
.aj-pl-editar {
  border: none; border-top: 1px solid var(--border);
  background: none; cursor: pointer; font-family: inherit;
  padding: 8px; font-size: 12px; font-weight: 600; color: var(--text-soft);
  transition: color var(--transition), background var(--transition);
}
.aj-pl-editar:hover { color: var(--accent); background: var(--bg-hover); }
.pl-seg-tipo { max-width: 240px; }

/* ── La barra de pestañas no cambia de tamaño nunca ───────────────────────
   Ni las pestañas se encogen, ni la barra pierde altura cuando no hay ninguna.
   Antes, al cerrar la última, la barra se quedaba baja y todo el contenido de
   debajo pegaba un salto hacia arriba; y al abrir una, otro salto hacia abajo.
   Con altura fija la página se queda quieta. */
.tabbar {
  min-height: 45px;
  height: 45px;
  flex: 0 0 45px;
  box-sizing: border-box;
}
.tabbar:empty, .tabbar:has(.tabbar-vacia) { display: flex; align-items: center; }

/* El logo de marca dentro de la píldora del widget de flota: pequeño y sin
   caja, para que acompañe al nombre sin robarle sitio. */
/* Tres formas de logo conviven: SVG en línea (Mercedes, Renault…), PNG y el
   distintivo de texto de reserva. Las tres tienen que medir lo mismo aquí. */
.fleet-pill-icon .veh-brand-logo-wrap { width: 18px; height: 18px; min-width: 18px; }
.fleet-pill-icon .veh-brand-logo-img  { max-width: 18px; max-height: 14px; }
.fleet-pill-icon .veh-logo-svg        { width: 16px; height: 16px; }
.fleet-pill-icon .veh-logo-svg.veh-logo-texto { width: 18px; height: auto; }
.fleet-pill-icon .veh-brand-badge     { font-size: 7.5px; padding: 1px 3px; }
.fleet-pill-icon { display: flex; align-items: center; }
.btn.pres-enviar-fac:hover { color: var(--accent); border-color: var(--accent); }

/* ── Cerrar sesión: lo último de la barra lateral ─────────────────────────── */
.sidebar-salir {
  display: flex; align-items: center; gap: 11px;
  width: 100%; flex-shrink: 0;
  padding: 13px 16px;
  background: none; border: none; border-top: 1px solid rgba(255,255,255,0.08);
  color: rgba(255,255,255,0.55);
  font-family: inherit; font-size: 13.5px; font-weight: 600;
  cursor: pointer; text-align: left;
  position: relative; z-index: 2;
  transition: background var(--transition), color var(--transition);
}
.sidebar-salir svg { flex-shrink: 0; }
/* Rojo al pasar por encima: es la única acción de la barra que te saca de la
   web, y conviene que se note antes de pulsarla, no después. */
.sidebar-salir:hover { background: rgba(var(--acento-rgb), 0.16); color: #fff; }
.sidebar-salir:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
/* Cerrada: solo el icono, centrado como el resto de la barra. */
.sidebar.collapsed .sidebar-salir { justify-content: center; padding: 13px 0; gap: 0; }
.sidebar.collapsed .sidebar-salir .nav-label { display: none; }

/* ── MiFi: PIN y PUK en una columna ───────────────────────────────────────── */
.mifi-claves { font-variant-numeric: tabular-nums; line-height: 1.35; }
.mifi-pin { display: block; font-size: 13px; font-weight: 700; }
/* El PUK, más discreto: solo hace falta cuando el PIN ya ha fallado tres veces.
   Y si no está registrado se dice, porque es justo cuando hace falta. */
.mifi-puk { display: block; font-size: 11px; color: var(--text-soft); }
.mifi-puk:not(:empty) { white-space: nowrap; }

/* ═══════════════════════════════════════════════════════════════════════════
   MENÚ DE ACCIONES
   Panel flotante anclado al botón de tres puntos. Va en `position: fixed` y
   colgado del <body>: dentro de la tabla lo recortaría el `overflow` del
   contenedor con desplazamiento.
   ═══════════════════════════════════════════════════════════════════════════ */
.menu-acc {
  position: fixed; z-index: 9000;
  min-width: 232px; max-width: 300px;
  padding: 5px 0;
  background: var(--surface);
  border: 1px solid var(--border-med);
  box-shadow: var(--shadow-md);
  animation: menuAcc 0.11s ease-out;
}
@keyframes menuAcc { from { opacity: 0; transform: translateY(-3px); } }

.menu-acc-item {
  display: flex; align-items: flex-start; gap: 9px;
  width: 100%; padding: 8px 13px;
  background: none; border: none; cursor: pointer; text-align: left;
  font-family: inherit; font-size: 13.5px; color: var(--text);
  transition: background var(--transition);
}
.menu-acc-item:hover, .menu-acc-item.resaltado { background: var(--bg-hover); }
.menu-acc-item:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.menu-acc-txt { display: block; min-width: 0; }
/* La segunda línea explica lo que hace la acción: «Descontabilizar» a secas no
   dice que devuelve los días al inventario. */
.menu-acc-txt em {
  display: block; margin-top: 1px;
  font-style: normal; font-size: 11.5px; color: var(--text-soft); line-height: 1.35;
}
.menu-acc-ico { flex: 0 0 0; }
.menu-acc-item.destacado { font-weight: 650; }
.menu-acc-item.destacado .menu-acc-txt { color: var(--accent); }
/* Las destructivas, en rojo y siempre al final tras un separador: hay que
   llegar a ellas a propósito. */
.menu-acc-item.peligro .menu-acc-txt { color: var(--pres-no); }
.menu-acc-item.peligro:hover { background: var(--pres-no-bg); }
.menu-acc-sep { height: 1px; background: var(--border); margin: 5px 0; }
.menu-acc-tit {
  padding: 7px 13px 3px;
  font-size: 10px; font-weight: 700; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--text-soft);
}

/* El botón de tres puntos */
.btn.pres-mas { padding: 4px 7px; line-height: 0; }
.btn.pres-mas[aria-expanded="true"] { background: var(--bg-hover); color: var(--text); }

/* ── Editor de plantillas: panel de estilo ────────────────────────────────── */
.pl-estilo { margin-bottom: 18px; border-bottom: 1px solid var(--border); padding-bottom: 14px; }
.pl-estilo > summary {
  cursor: pointer; list-style: none; padding-bottom: 8px;
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--text-soft);
  display: flex; align-items: center; gap: 7px;
}
.pl-estilo > summary::-webkit-details-marker { display: none; }
.pl-estilo > summary::before {
  content: ''; width: 0; height: 0;
  border-left: 5px solid currentColor;
  border-top: 4px solid transparent; border-bottom: 4px solid transparent;
  transition: transform 0.2s ease;
}
.pl-estilo[open] > summary::before { transform: rotate(90deg) translateX(1px); }
.pl-colores { display: grid; gap: 4px; margin-bottom: 12px; }
.pl-color { display: flex; align-items: center; gap: 9px; font-size: 12.5px; cursor: pointer; }
.pl-color input[type="color"] {
  width: 30px; height: 24px; padding: 0; flex-shrink: 0; cursor: pointer;
  border: 1px solid var(--border-med); background: none; border-radius: 0;
}
.pl-check { display: flex; align-items: center; gap: 8px; font-size: 12.5px; margin: 10px 0; cursor: pointer; }
.pl-estilo-cuerpo input[type="range"] { width: 100%; accent-color: var(--accent); }

/* ── Ajustes: barra de guardado ───────────────────────────────────────────
   Pegada arriba mientras se recorre la página: los ajustes son largos y el
   botón al final se pierde de vista justo cuando hay algo que guardar. */
.aj-barra {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; gap: 10px;
  padding: 11px 14px; margin-bottom: 22px;
  background: var(--surface); border: 1px solid var(--border);
}
.aj-barra-txt { flex: 1; font-size: 12.5px; color: var(--text-soft); }
/* Se enciende solo cuando hay algo pendiente: si estuviera siempre en rojo
   dejaría de significar nada. */
.aj-barra.sucia { border-color: var(--mo-aviso); background: var(--mo-aviso-bg); }
.aj-barra.sucia .aj-barra-txt { color: var(--mo-aviso); font-weight: 600; }

/* ═══════════════════════════════════════════════════════════════════════════
   MiFi: TABLERO
   El color dice el estado sin leer: verde libre, rojo en rodaje, gris parado.
   Es lo que permite contestar «¿cuál cojo?» de un vistazo, que es la pregunta
   que se hace todos los días.
   ═══════════════════════════════════════════════════════════════════════════ */
#mifis-dashboard { display: none; }   /* lo sustituyen las cifras del tablero */
.mifi-vista-barra { display: flex; justify-content: flex-end; margin: 4px 0 14px; }

.mf-cifras {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  border: 1px solid var(--border); border-left: none;
  background: var(--surface); margin-bottom: 14px;
}
.mf-cifra { padding: 12px 15px; border-left: 1px solid var(--border); }
.mf-cifra b { display: block; font-size: 22px; font-weight: 700; letter-spacing: -0.03em; }
.mf-cifra span {
  display: block; margin-top: 2px;
  font-size: 10px; font-weight: 700; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--text-soft);
}
.mf-cifra.libre b { color: var(--pres-ok); }
.mf-cifra.fuera b { color: var(--accent); }
.mf-cifra.mant  b { color: var(--mo-aviso); }
.mf-cifra.aviso b { color: var(--mo-aviso); }

.mf-enproy { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 16px; }
.mf-enproy-tit { font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-soft); }
.mf-enproy-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 9px; font-size: 12.5px; font-weight: 600;
  background: rgba(var(--acento-rgb), 0.10); color: var(--accent);
}
.mf-enproy-chip i { font-style: normal; font-size: 11px; opacity: 0.75; }

.mf-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(238px, 1fr)); gap: 12px; }
.mf-card {
  display: flex; flex-direction: column; gap: 8px;
  padding: 13px 14px 12px;
  background: var(--surface); border: 1px solid var(--border);
  /* La banda de color va a la izquierda, no de fondo: teñir la tarjeta entera
     compite con el texto y con seis tarjetas cansa. */
  box-shadow: inset 3px 0 0 var(--border-med);
  transition: border-color var(--transition), box-shadow var(--transition);
}
.mf-card:hover { border-color: var(--border-med); }
.mf-libre { box-shadow: inset 3px 0 0 var(--pres-ok); }
.mf-fuera { box-shadow: inset 3px 0 0 var(--accent); }
.mf-mant  { box-shadow: inset 3px 0 0 var(--mo-aviso); }
.mf-baja  { opacity: 0.55; }

.mf-card-cab { display: flex; align-items: center; gap: 8px; }
.mf-num {
  font-family: var(--font-mono); font-size: 12px; font-weight: 700;
  padding: 1px 6px; background: var(--mo-neutro-bg); color: var(--text-soft);
}
.mf-estado {
  margin-left: auto; font-size: 10px; font-weight: 700;
  letter-spacing: 0.07em; text-transform: uppercase; color: var(--text-soft);
}
.mf-libre .mf-estado { color: var(--pres-ok); }
.mf-fuera .mf-estado { color: var(--accent); }
.mf-mant  .mf-estado { color: var(--mo-aviso); }
.mf-nombre { font-size: 14.5px; font-weight: 700; letter-spacing: -0.01em; }

.mf-destino { padding: 7px 9px; background: var(--surface-2); font-size: 12.5px; }
.mf-destino-proy { display: block; font-weight: 700; }
.mf-destino-meta { display: block; margin-top: 1px; font-size: 11.5px; color: var(--text-soft); }
.mf-destino-libre { color: var(--text-soft); font-style: italic; }

.mf-datos { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; margin: 0; }
.mf-datos dt {
  font-size: 9.5px; font-weight: 700; letter-spacing: 0.07em;
  text-transform: uppercase; color: var(--text-xsoft);
}
.mf-datos dd { margin: 1px 0 0; font-size: 13px; font-weight: 600; font-variant-numeric: tabular-nums; }
.mf-falta { color: var(--mo-aviso); font-weight: 500; font-size: 11px; }
.mf-acciones { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 2px; }

/* ── Empleados: vista en lista ────────────────────────────────────────────── */
.emp-vista-barra { display: flex; justify-content: flex-end; margin-bottom: 6px; }
.emp-grupo-tit {
  font-size: 11px; font-weight: 700; color: var(--text-soft);
  text-transform: uppercase; letter-spacing: 0.06em; margin: 18px 0 10px;
}
.emp-avatar-sm { width: 30px; height: 30px; font-size: 11.5px; }
.emp-tabla td { vertical-align: middle; }
.emp-tabla a { color: var(--text-soft); text-decoration: none; }
.emp-tabla a:hover { color: var(--accent); text-decoration: underline; }

/* ── IT Stock: en proyectos ───────────────────────────────────────────────── */
.it-tab-n {
  margin-left: 6px; font-size: 11px; font-weight: 700;
  padding: 1px 6px; background: var(--mo-neutro-bg); color: var(--text-soft);
}
.it-tab-n.rojo { background: var(--mo-alerta-bg); color: var(--mo-alerta); }
.it-tab-n:empty { display: none; }
.tabla tbody tr.itp-vencido { background: var(--mo-alerta-bg); }
.it-salida-acciones { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }

/* ── Empleados: chips de departamento ─────────────────────────────────────── */
.emp-deps { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 14px; }
.emp-dep-chip {
  display: inline-flex; align-items: center; gap: 6px;
  height: 30px; padding: 0 11px; cursor: pointer;
  background: var(--surface); border: 1px solid var(--border);
  color: var(--text-soft); font-family: inherit; font-size: 12.5px; font-weight: 600;
  transition: color var(--transition), border-color var(--transition);
}
.emp-dep-chip:hover { color: var(--text); border-color: var(--border-med); }
.emp-dep-chip i {
  font-style: normal; font-size: 11px; font-weight: 700;
  padding: 0 5px; background: var(--mo-neutro-bg); color: var(--text-soft);
}
.emp-dep-chip.activo { color: #fff; background: var(--accent); border-color: var(--accent); }
.emp-dep-chip.activo i { background: rgba(255,255,255,0.22); color: #fff; }

/* ── Microsoft 365: pantalla de sincronización ────────────────────────────── */
.ms-tabs { display: flex; gap: 2px; flex-wrap: wrap; border-bottom: 1px solid var(--border); margin-bottom: 14px; }
.ms-tab {
  background: none; border: none; cursor: pointer; margin-bottom: -1px;
  padding: 9px 14px; font-family: inherit; font-size: 13.5px; font-weight: 600;
  color: var(--text-soft); border-bottom: 2px solid transparent;
  display: flex; align-items: center; gap: 7px;
}
.ms-tab:hover { color: var(--text); }
.ms-tab.activa { color: var(--text); border-bottom-color: var(--accent); }
.ms-tab i {
  font-style: normal; font-size: 11px; font-weight: 700; padding: 1px 6px;
  background: var(--mo-neutro-bg); color: var(--text-soft);
}
.ms-tab.activa i { color: var(--text); }
.ms-badge {
  margin-left: 7px; padding: 1px 6px; font-size: 10px; font-weight: 700;
  background: var(--mo-neutro-bg); color: var(--text-soft);
}
.tabla tbody tr.ms-inactivo { opacity: 0.55; }
/* Barra de acción pegada abajo: con 127 filas, el botón al final de la tabla
   queda a un scroll de distancia justo cuando ya has decidido. */
.ms-barra {
  position: sticky; bottom: 0; z-index: 10;
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 12px 16px; margin-top: 14px;
  background: var(--surface); border: 1px solid var(--accent);
  box-shadow: 0 -4px 14px rgba(0,0,0,0.12);
}
.ms-barra span { flex: 1; font-size: 13px; }

/* ═══════════════════════════════════════════════════════════════════════════
   MICROSOFT 365 · ALTA DE USUARIO  (_ma*)
   ═══════════════════════════════════════════════════════════════════════════ */

.ma-switch {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  margin-bottom: 18px;
  background: var(--surface-2, var(--surface));
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.ma-sw {
  padding: 7px 16px;
  border: 0;
  border-radius: var(--radius-xs);
  background: transparent;
  color: var(--text-soft);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background .15s, color .15s;
}
.ma-sw:hover { color: var(--text); }
.ma-sw.activa { background: var(--accent); color: #fff; }

/* ── Pantalla de bloqueo ─────────────────────────────────────────────────── */
.ma-bloqueo {
  max-width: 680px;
  margin: 24px auto;
  padding: 32px;
  text-align: center;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}
.ma-bloqueo-icono { font-size: 34px; line-height: 1; margin-bottom: 12px; }
.ma-bloqueo h2 { margin: 0 0 8px; font-size: 19px; }
.ma-bloqueo > p { margin: 0; color: var(--text-soft); }
.ma-bloqueo-porque {
  margin-top: 24px;
  padding-top: 20px;
  border-top: 1px solid var(--border);
  text-align: left;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--text-soft);
}
.ma-bloqueo-porque p { margin: 0 0 12px; }
.ma-bloqueo-porque b { color: var(--text); }
.ma-bloqueo-porque code {
  padding: 1px 5px;
  border-radius: var(--radius-xs);
  background: var(--surface-2, rgba(127,127,127,.14));
  font-size: 12.5px;
}
.ma-cmd {
  margin: 0 0 12px;
  padding: 11px 14px;
  border-radius: var(--radius-sm);
  background: #14161a;
  color: #d8dee9;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12.5px;
  overflow-x: auto;
}

/* ── Formulario ──────────────────────────────────────────────────────────── */
.ma-form {
  max-width: 720px;
  padding: 26px 28px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}
.ma-rejilla {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px 18px;
  margin: 20px 0 4px;
}
.ma-ancho { grid-column: 1 / -1; }
.ma-campo { display: flex; flex-direction: column; gap: 6px; }
.ma-campo label {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .02em;
  text-transform: uppercase;
  color: var(--text-soft);
}
.ma-campo label i { color: var(--accent); font-style: normal; }
.ma-campo input,
.ma-campo select,
.ma-correo input,
.ma-correo select {
  padding: 9px 11px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg);
  color: var(--text);
  font: inherit;
  font-size: 14px;
}
.ma-campo input:focus,
.ma-campo select:focus,
.ma-correo input:focus,
.ma-correo select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
}
.ma-correo { display: flex; align-items: center; gap: 8px; }
.ma-correo input { flex: 1 1 auto; min-width: 0; }
.ma-correo > span { color: var(--text-soft); font-size: 15px; }
.ma-correo select { flex: 0 1 auto; max-width: 240px; }
.ma-pista { margin: 2px 0 0; font-size: 12.5px; color: var(--text-soft); }
.ma-pista b { color: var(--text); font-weight: 600; }

.ma-check {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-top: 20px;
  font-size: 14px;
  cursor: pointer;
}
.ma-acciones {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 24px;
  padding-top: 20px;
  border-top: 1px solid var(--border);
}

/* ── Resultado: la contraseña, una vez ───────────────────────────────────── */
.ma-hecho {
  max-width: 640px;
  padding: 28px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}
.ma-hecho-cab { display: flex; align-items: center; gap: 14px; margin-bottom: 24px; }
.ma-tick {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 40px; height: 40px;
  border-radius: var(--radius-sm);
  background: #1f9d5522;
  color: #1f9d55;
  font-size: 20px;
  font-weight: 700;
}
.ma-hecho-cab h2 { margin: 0; font-size: 18px; }
.ma-hecho-cab p { margin: 2px 0 0; color: var(--text-soft); font-size: 13.5px; }

.ma-pass {
  padding: 18px;
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--accent) 7%, transparent);
}
.ma-pass > label {
  display: block;
  margin-bottom: 9px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .02em;
  text-transform: uppercase;
  color: var(--text-soft);
}
.ma-pass-fila { display: flex; align-items: center; gap: 10px; }
.ma-pass-fila code {
  flex: 1 1 auto;
  padding: 11px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 17px;
  letter-spacing: .06em;
  user-select: all;
  overflow-x: auto;
}
.ma-pass-aviso {
  margin: 12px 0 0;
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--text-soft);
}
.ma-pass-aviso b { color: var(--text); }
.ma-hecho-acciones {
  display: flex;
  gap: 10px;
  margin-top: 24px;
  padding-top: 20px;
  border-top: 1px solid var(--border);
}

@media (max-width: 720px) {
  .ma-rejilla { grid-template-columns: 1fr; }
  .ma-correo { flex-wrap: wrap; }
  .ma-correo select, .ma-correo input { max-width: none; width: 100%; }
  .ma-correo > span { display: none; }
}

/* El código de la contraseña es largo y se comía el botón de copiar. */
.ma-pass-fila code { min-width: 0; }
.ma-pass-fila .btn { flex: 0 0 auto; white-space: nowrap; }

/* ── Alta de usuario · licencias ─────────────────────────────────────────── */
.ma-bloque-lic { margin-top: 22px; }
.ma-bloque-tit {
  display: block;
  margin-bottom: 9px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .02em;
  text-transform: uppercase;
  color: var(--text-soft);
}
.ma-lic-lista {
  display: flex;
  flex-direction: column;
  gap: 1px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--border);
}
.ma-lic {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 11px 13px;
  background: var(--bg);
  cursor: pointer;
  transition: background .12s;
}
.ma-lic:hover { background: var(--surface-2, var(--surface)); }
.ma-lic-nombre { flex: 1 1 auto; font-size: 14px; }
.ma-lic-plazas {
  flex: 0 0 auto;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-soft);
}
.ma-lic-plazas i { font-style: normal; font-weight: 400; opacity: .65; }
.ma-lic-plazas.cero { color: var(--accent); }
.ma-lic.agotada .ma-lic-nombre { color: var(--text-soft); }

.ma-lic-alerta {
  margin: 10px 0 0;
  padding: 10px 12px;
  border-left: 3px solid var(--accent);
  border-radius: 0;
  background: color-mix(in srgb, var(--accent) 8%, transparent);
  font-size: 12.5px;
  line-height: 1.5;
}

/* Resultado */
.ma-lic-res {
  margin-top: 14px;
  padding: 11px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: 13px;
  color: var(--text-soft);
}
.ma-lic-res.bien { border-color: #1f9d5566; color: var(--text); }
.ma-lic-res.mal {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 8%, transparent);
  color: var(--text);
}
.ma-lic-res.mal b { display: block; margin-bottom: 6px; }
.ma-lic-res.mal p { margin: 0 0 6px; font-size: 12.5px; color: var(--text-soft); }
.ma-lic-res.mal p:last-child { margin-bottom: 0; }

.ma-lic-plazas.gratis { color: var(--text-soft); opacity: .8; font-weight: 400; }
.ma-lic-mas {
  margin-top: 9px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--text-soft);
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
}
.ma-lic-mas:hover { color: var(--text); }
.ma-lic-lista.gratis { margin-top: 9px; opacity: .85; }

/* ═══════════════════════════════════════════════════════════════════════════
   ALTA DE USUARIO · pantalla nueva (.mn*)
   ═══════════════════════════════════════════════════════════════════════════ */
.mn {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
  gap: 22px;
  align-items: start;
}
.mn-col { display: flex; flex-direction: column; gap: 14px; min-width: 0; }

.mn-bloque {
  padding: 22px 24px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}
.mn-bloque h3 {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 18px;
  font-size: 15px;
  font-weight: 600;
}
.mn-num {
  display: grid;
  place-items: center;
  width: 22px; height: 22px;
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  color: var(--accent);
  font-size: 11px;
  font-weight: 700;
}

.mn-rejilla { display: grid; grid-template-columns: 1fr 1fr; gap: 14px 16px; }
.mn-campo { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.mn-campo.ancho { grid-column: 1 / -1; }
.mn-campo label {
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: .03em;
  text-transform: uppercase;
  color: var(--text-soft);
}
.mn-campo input,
.mn-correo input,
.mn-correo select {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg);
  color: var(--text);
  font: inherit;
  font-size: 14px;
  transition: border-color .14s, box-shadow .14s;
}
.mn-campo input:focus,
.mn-correo input:focus,
.mn-correo select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 16%, transparent);
}
.mn-correo { display: flex; align-items: center; gap: 9px; }
.mn-correo input { flex: 1 1 auto; min-width: 0; }
.mn-correo > span { flex: 0 0 auto; color: var(--text-soft); }
.mn-correo select { flex: 0 1 auto; width: auto; max-width: 250px; }
.mn-pista { margin: 10px 0 0; font-size: 12.5px; color: var(--text-soft); }
.mn-pista b { color: var(--text); font-weight: 600; }

/* ── Licencias como tarjetas seleccionables ──────────────────────────────── */
.mn-lics { display: flex; flex-direction: column; gap: 8px; }
.mn-lics.gratis { margin-top: 8px; }
.mn-lic {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
  cursor: pointer;
  transition: border-color .14s, background .14s;
}
.mn-lic:hover { border-color: color-mix(in srgb, var(--accent) 45%, var(--border)); }
.mn-lic.on {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 7%, transparent);
}
.mn-lic input { position: absolute; opacity: 0; pointer-events: none; }
.mn-tick {
  flex: 0 0 auto;
  position: relative;
  width: 19px; height: 19px;
  border: 1.5px solid var(--border);
  border-radius: var(--radius-xs);
  background: var(--surface);
  transition: background .14s, border-color .14s;
}
.mn-lic.on .mn-tick { background: var(--accent); border-color: var(--accent); }
.mn-lic.on .mn-tick::after {
  content: '';
  position: absolute;
  left: 6px; top: 2px;
  width: 4px; height: 9px;
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.mn-lic-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.mn-lic-txt b { font-size: 13.5px; font-weight: 500; }
.mn-lic-txt i { font-style: normal; font-size: 11.5px; color: var(--text-soft); }
.mn-lic-txt i.cero { color: var(--accent); font-weight: 600; }
.mn-lic.agotada .mn-lic-txt b { color: var(--text-soft); }

.mn-mas {
  margin-top: 10px; padding: 0;
  border: 0; background: none;
  color: var(--text-soft);
  font: inherit; font-size: 12.5px; font-weight: 600;
  cursor: pointer;
}
.mn-mas:hover { color: var(--text); }
.mn-alerta {
  margin: 12px 0 0;
  padding: 10px 13px;
  border-left: 3px solid var(--accent);
  border-radius: 0;
  background: color-mix(in srgb, var(--accent) 8%, transparent);
  font-size: 12.5px;
  line-height: 1.5;
}

/* ── Tarjeta de resumen ──────────────────────────────────────────────────── */
.mn-lado { position: sticky; top: 16px; }
.mn-tarjeta {
  padding: 24px 20px 20px;
  text-align: center;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}
.mn-avatar {
  display: grid;
  place-items: center;
  width: 62px; height: 62px;
  margin: 0 auto 14px;
  border-radius: var(--radius-sm);
  background: linear-gradient(140deg,
    color-mix(in srgb, var(--accent) 85%, #000),
    color-mix(in srgb, var(--accent) 45%, #000));
  color: #fff;
  font-size: 21px;
  font-weight: 600;
  letter-spacing: .04em;
}
.mn-nombre { font-size: 16px; font-weight: 600; word-break: break-word; }
.mn-nombre i, .mn-mail i { font-style: normal; color: var(--text-soft); opacity: .55; font-weight: 400; }
.mn-mail { margin-top: 3px; font-size: 12.5px; color: var(--text-soft); word-break: break-all; }
.mn-sub { margin-top: 7px; font-size: 12px; color: var(--text-soft); }
.mn-sep { height: 1px; margin: 18px 0; background: var(--border); }

.mn-chips { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; }
.mn-chip {
  padding: 4px 10px;
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--accent) 13%, transparent);
  color: var(--text);
  font-size: 11.5px;
  font-weight: 500;
}
.mn-chip.cero { background: var(--accent); color: #fff; }
.mn-chip.vacio { background: transparent; border: 1px dashed var(--border); color: var(--text-soft); }

.mn-toggle {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 18px 0 16px;
  text-align: left;
  font-size: 12.5px;
  cursor: pointer;
}
.mn-crear, .mn-limpiar { width: 100%; justify-content: center; }
.mn-limpiar { margin-top: 8px; }

@media (max-width: 900px) {
  .mn { grid-template-columns: 1fr; }
  .mn-lado { position: static; }
  .mn-rejilla { grid-template-columns: 1fr; }
}

/* ── Empleados: filtro por área + departamento ───────────────────────────── */
.emp-filtros {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin: 0 0 16px;
}
/* `.cat-dd-wrap` es display:block, así que sin base fija los desplegables se
   estiraban a todo el ancho y se apilaban uno debajo de otro. */
.emp-dd { flex: 0 0 auto; width: 230px; }
.emp-dd .selector-boton { width: 100%; }
.emp-cuenta {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text-soft);
}
.emp-limpiar {
  padding: 0;
  border: 0;
  background: none;
  color: var(--text-soft);
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.emp-limpiar:hover { color: var(--text); }

@media (max-width: 620px) {
  .emp-dd { min-width: 0; flex: 1 1 100%; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   MICROSOFT 365 · BUZONES Y GRUPOS  (.bz* y .gr*)
   ═══════════════════════════════════════════════════════════════════════════ */
.bz-elige {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  padding: 16px 18px;
  margin-bottom: 16px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}
.bz-elige > label {
  font-size: 11.5px; font-weight: 600; letter-spacing: .03em;
  text-transform: uppercase; color: var(--text-soft);
}
.bz-dd { flex: 0 0 auto; width: 300px; }
.bz-dd .selector-boton { width: 100%; }
.bz-quien { font-size: 12.5px; color: var(--text-soft); }
.bz-vacio {
  padding: 40px 24px; text-align: center; color: var(--text-soft);
  border: 1px dashed var(--border); border-radius: var(--radius-lg);
}

.bz-paneles { display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); gap: 14px; }
.bz-panel {
  padding: 20px 22px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}
.bz-panel h3 {
  display: flex; align-items: center; gap: 9px;
  margin: 0 0 16px; font-size: 14.5px; font-weight: 600;
}
.bz-cuenta {
  padding: 1px 7px; border-radius: var(--radius-xs);
  background: var(--mo-neutro-bg); color: var(--text-soft);
  font-size: 11px; font-weight: 700;
}

.bz-estado { display: flex; align-items: center; gap: 8px; margin-bottom: 14px; font-size: 13px; font-weight: 600; }
.bz-punto { width: 8px; height: 8px; border-radius: 50%; background: var(--text-soft); }
.bz-estado.on .bz-punto { background: #1f9d55; box-shadow: 0 0 0 3px #1f9d5533; }
.bz-estado.off { color: var(--text-soft); }

.bz-seg { display: flex; gap: 2px; padding: 3px; background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-sm); }
.bz-seg-b {
  flex: 1 1 0; padding: 7px 10px; border: 0; border-radius: var(--radius-xs);
  background: transparent; color: var(--text-soft);
  font: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer;
  transition: background .14s, color .14s;
}
.bz-seg-b:hover { color: var(--text); }
.bz-seg-b.activa { background: var(--accent); color: #fff; }
.bz-seg.chico .bz-seg-b { padding: 5px 8px; font-size: 11.5px; }

.bz-fechas { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 14px; }
.bz-fechas label, .bz-campo label {
  display: block; margin-bottom: 6px;
  font-size: 11.5px; font-weight: 600; letter-spacing: .03em;
  text-transform: uppercase; color: var(--text-soft);
}
.bz-campo { margin-top: 16px; }
.bz-fechas input, .bz-campo textarea {
  width: 100%; padding: 9px 11px;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--bg); color: var(--text); font: inherit; font-size: 13.5px;
  resize: vertical;
}
.bz-fechas input:focus, .bz-campo textarea:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 16%, transparent);
}
.bz-acciones {
  display: flex; justify-content: flex-end; gap: 9px;
  margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--border);
}

.bz-grupos { display: flex; flex-direction: column; gap: 7px; }
.bz-grupo {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg);
}
.bz-grupo-txt { flex: 1 1 auto; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.bz-grupo-txt b { font-size: 13px; font-weight: 500; }
.bz-grupo-txt i { font-style: normal; font-size: 11.5px; color: var(--text-soft); }
.bz-nota { font-size: 11.5px; color: var(--text-soft); }
.bz-anadir { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--border); }
.bz-anadir > label {
  display: block; margin-bottom: 7px;
  font-size: 11.5px; font-weight: 600; letter-spacing: .03em;
  text-transform: uppercase; color: var(--text-soft);
}
.bz-anadir .bz-dd { width: 100%; }

/* ── Grupos ─────────────────────────────────────────────────────────────── */
.gr-barra { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-bottom: 14px; }
.gr-barra .filter-input { flex: 1 1 220px; min-width: 0; }
.gr-lista { display: flex; flex-direction: column; gap: 7px; }
.gr-item { border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); }
.gr-item.abierto { border-color: color-mix(in srgb, var(--accent) 50%, var(--border)); }
.gr-cab {
  display: flex; align-items: center; gap: 11px; width: 100%;
  padding: 12px 14px; border: 0; background: none; color: var(--text);
  font: inherit; text-align: left; cursor: pointer;
}
.gr-flecha { flex: 0 0 12px; color: var(--text-soft); font-size: 11px; }
.gr-nombre { flex: 1 1 auto; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.gr-nombre b { font-size: 13.5px; font-weight: 500; }
.gr-nombre i { font-style: normal; font-size: 11.5px; color: var(--text-soft); }
.gr-tipo {
  flex: 0 0 auto; padding: 3px 9px; border-radius: var(--radius-xs);
  background: var(--mo-neutro-bg); color: var(--text-soft);
  font-size: 11px; font-weight: 600;
}
.gr-tipo.t-microsoft365 { background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--accent); }
.gr-tipo.t-dinamico { background: color-mix(in srgb, #d19a00 22%, transparent); color: #d19a00; }
.gr-cuerpo { padding: 4px 14px 16px 37px; border-top: 1px solid var(--border); }
.gr-cuerpo > .mn-pista:first-child { margin-top: 12px; }
.gr-miembros { display: flex; flex-direction: column; gap: 6px; margin-top: 12px; }
.gr-miembro {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 11px; border: 1px solid var(--border);
  border-radius: var(--radius-sm); background: var(--bg);
}
.gr-ini {
  flex: 0 0 auto; display: grid; place-items: center;
  width: 26px; height: 26px; border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--accent) 20%, transparent);
  color: var(--accent); font-size: 12px; font-weight: 700;
}
.gr-m-txt { flex: 1 1 auto; display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.gr-m-txt b { font-size: 13px; font-weight: 500; }
.gr-m-txt i { font-style: normal; font-size: 11.5px; color: var(--text-soft); }

@media (max-width: 700px) {
  .bz-dd { width: 100%; }
  .bz-paneles { grid-template-columns: 1fr; }
  .bz-fechas { grid-template-columns: 1fr; }
  .gr-cuerpo { padding-left: 14px; }
}
.bz-formato {
  margin: 8px 0 0; font-size: 11.5px; line-height: 1.5;
  color: #d19a00;
}

/* ═══════════════════════════════════════════════════════════════════════════
   LOGIN · EL FOCO  (.lfx*)
   Los valores los pone el JS en variables; aquí solo se dice qué hacer con
   ellos. Así el fotograma no toca estilos uno a uno, solo cuatro variables.
   ═══════════════════════════════════════════════════════════════════════════ */
.login-marca {
  --lfx-x: 50%;
  --lfx-y: 62%;
  --lfx-fuerza: 0.45;
  --lfx-destello: 0;
  --lfx-px: 0px; --lfx-py: 0px;
  --lfx-tx: 0px; --lfx-ty: 0px;
}

/* El haz. Va detrás de todo (z-index -3) para que no tape ni el texto ni la
   palmera: enciende la escena, no se pone delante. */
.lfx-foco {
  position: absolute; inset: 0; z-index: -3;
  pointer-events: none;
  background:
    radial-gradient(circle 42vmax at var(--lfx-x) var(--lfx-y),
      rgba(var(--acento-rgb), calc(0.26 * var(--lfx-fuerza) + 0.30 * var(--lfx-destello))) 0%,
      rgba(var(--acento-rgb), calc(0.11 * var(--lfx-fuerza))) 28%,
      transparent 62%),
    radial-gradient(circle 16vmax at var(--lfx-x) var(--lfx-y),
      rgba(255, 236, 226, calc(0.10 * var(--lfx-fuerza) + 0.14 * var(--lfx-destello))) 0%,
      transparent 70%);
  transition: opacity .5s ease;
}

.lfx-polvo {
  position: absolute; inset: 0; z-index: -2;
  pointer-events: none;
}

/* Profundidad: la palmera del fondo se desplaza más que el texto de delante, y
   en sentido contrario al ratón. Es lo que hace que parezca que hay hueco. */
.login-marca-palma {
  transform: translate3d(var(--lfx-px), var(--lfx-py), 0);
  transition: opacity .4s ease;
}
.login-marca:hover .login-marca-palma { opacity: 0.15; }

.login-marca-cuerpo,
.login-marca-pie {
  transform: translate3d(var(--lfx-tx), var(--lfx-ty), 0);
}

/* El título se enciende un pelín cuando el foco anda cerca. */
.login-marca-tit {
  transition: text-shadow .45s ease;
}
.login-marca:hover .login-marca-tit {
  text-shadow: 0 0 38px rgba(var(--acento-rgb), 0.34);
}

@media (prefers-reduced-motion: reduce) {
  .lfx-polvo { display: none; }
  .lfx-foco { transition: none; }
  .login-marca-palma,
  .login-marca-cuerpo,
  .login-marca-pie { transform: none; }
}

/* En pantallas estrechas la mitad negra desaparece o se encoge: el adorno sobra. */
@media (max-width: 860px) {
  .lfx-polvo { display: none; }
}

/* ── Selects adoptados: el nativo se esconde pero sigue ahí ──────────────── */
select.sel-oculto {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px; border: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
}
/* El envoltorio hereda las clases del select para caer en el mismo hueco, pero
   NO debe pintarse: quien se ve es el botón de dentro. Se le quita todo lo
   decorativo con `!important` porque las reglas originales (`.filter-select`,
   `.form-input`) son más específicas que esta. */
.sel-dd {
  position: relative;
  background: none !important;
  border: 0 !important;
  padding: 0 !important;
  box-shadow: none !important;
  height: auto !important;
  min-height: 0 !important;
  color: inherit !important;
  font: inherit !important;
  appearance: none !important;
}
.sel-dd > .selector-boton { width: 100%; }
.sel-dd > .selector-boton.desactivado { opacity: .55; cursor: not-allowed; }

/* ═══════════════════════════════════════════════════════════════════════════
   PASADA DE COHERENCIA

   La web había crecido por capas y cada sección traía sus medidas: campos de
   32, 34, 36 y 42 píxeles de alto, y el avatar del perfil redondo mientras el
   de la barra lateral era cuadrado — la misma persona con dos formas.

   Esto no inventa un estilo nuevo: iguala al que ya usaba la mayoría.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Campos: todos con el mismo alto ─────────────────────────────────────── */
.filter-input,
.form-input,
.form-control,
.selector-boton,
input[type="text"]:not(.busca-input),
input[type="search"]:not(.busca-input),
input[type="email"],
input[type="tel"],
input[type="number"],
input[type="date"],
input[type="datetime-local"],
input[type="password"]:not(#login-pass),
textarea {
  font-size: 13.5px;
  font-family: var(--font);
}
.filter-input,
.form-input,
.form-control,
.selector-boton,
input[type="text"]:not(.busca-input):not(.cat-dd-busca input),
input[type="search"]:not(.busca-input),
input[type="email"],
input[type="tel"],
input[type="number"],
input[type="date"],
input[type="datetime-local"],
input[type="password"]:not(#login-pass) {
  min-height: 34px;
  padding-top: 7px;
  padding-bottom: 7px;
}

/* El avatar del perfil, cuadrado como el de la barra lateral. */
.perfil-avatar,
.perfil-avatar-img { border-radius: var(--radius-sm) !important; }

/* Los botones de acción de Revisiones traían su propio redondeo. */
.rev-accion { border-radius: var(--radius-sm) !important; }

/* Los desplegables salían 2px más altos que los campos de texto: el botón lleva
   dentro un span y un icono, y su altura de línea es mayor que la de un input.
   Se fija el alto en vez de perseguir la altura de línea. */
.selector-boton {
  box-sizing: border-box;
  height: 34px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  line-height: 1;
}
.selector-boton > span:first-child {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-align: left;
}
.selector-boton > svg { flex: 0 0 auto; opacity: .6; }

/* El panel de un select adoptado no debe ser mucho más ancho que su botón:
   antes salía a 340px fijos aunque el botón midiera 130 y quedaba descolgado. */
.sel-dd > .cat-dd { min-width: 100%; width: max-content; max-width: min(420px, 90vw); }

/* ── Estados vacíos ──────────────────────────────────────────────────────── */
.vacio-estado {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 46px 24px;
  text-align: center;
}
.vacio-icono {
  display: grid;
  place-items: center;
  width: 46px; height: 46px;
  margin-bottom: 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  font-size: 20px;
  opacity: .75;
}
.vacio-estado h3 {
  margin: 0;
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
}
.vacio-estado p {
  max-width: 420px;
  margin: 0;
  font-size: 13px;
  line-height: 1.55;
  color: var(--text-soft);
}
.vacio-estado .btn { margin-top: 10px; }
.vacio-pista { font-size: 12px !important; opacity: .8; }
.vacio-fila td { padding: 0 !important; background: none !important; border: 0 !important; }

/* ═══════════════════════════════════════════════════════════════════════════
   MODO CLARO · LOS GRISES QUE SE QUEDARON DEL OSCURO

   `--text-soft` se corrigió en su día, pero `--text-xsoft` y `--lavender-grey`
   se quedaron con tonos pensados para fondo negro. Sobre blanco daban entre
   2,88 y 3,68 de contraste (el mínimo legible es 4,5): fechas, subtítulos,
   etiquetas de gráfico y las pistas bajo los títulos salían lavadas.

   No es un ajuste a ojo: son 83 reglas que usan `--text-xsoft`, así que se
   arregla el token y no las 83. En oscuro no se toca nada.
   ═══════════════════════════════════════════════════════════════════════════ */
:root[data-tema="claro"],
html[data-tema="claro"] {
  /* #596478 pasa el 4,5 en LOS TRES fondos que tiene la web: tarjeta blanca
     (5,97), fondo de página #dde5eb (4,68) y superficie intermedia (5,30).
     Con #6b7689 se quedaba en 3,60 sobre el fondo de página, que es justo
     donde viven las pistas y los subtítulos. */
  --text-xsoft:     #596478;   /* antes #7b8698 → 2,89:1 */
  --lavender-grey:  #596478;   /* antes #8d99ae → 2,88:1 */
  /* `--text-soft` (#5f6b80) daba 5,38 sobre tarjeta blanca —correcto— pero
     4,22 sobre el fondo de página, y ahí es donde viven los contadores y las
     fechas. Un punto más oscuro y pasa en los dos sitios. */
  --text-soft:      #596478;
  --text-muted:     #596478;
  /* El rojo de marca sobre blanco se queda en 3,31 cuando hace de TEXTO
     (enlaces, avisos, chips). Un punto más oscuro sirve igual de fondo con
     texto blanco encima, así que vale para los dos usos. */
  --red:            #d1102c;
}
@media (prefers-color-scheme: light) {
  :root:not([data-tema="oscuro"]) {
    --text-xsoft:     #596478;
    --lavender-grey:  #596478;
    --text-soft:      #596478;
    --text-muted:     #596478;
    --red:            #d1102c;
  }
}

/* Los dos últimos colores fijos que se quedaban cortos en claro. Van dentro del
   tema para no tocar el oscuro, donde ya se ven bien. */
:root[data-tema="claro"],
html[data-tema="claro"] {
  --orange-dark: #5c6577;   /* era #6b7589 → 4,12:1 en las fechas de la agenda */
  --mo-alerta:   #b21c1c;   /* era #c62828 → 3,92:1 en los contadores de taller */
  --eco-gasto:   #b21c1c;
}
@media (prefers-color-scheme: light) {
  :root:not([data-tema="oscuro"]) {
    --orange-dark: #5c6577;
    --mo-alerta:   #b21c1c;
    --eco-gasto:   #b21c1c;
  }
}

/* `.badge-borrador` era el único badge con un gris fijo (#6E6E73) en vez de un
   token: en oscuro daba 2,67 sobre su propio fondo y costaba leerlo. El resto
   ya usaban `var(--text-soft)`, que se adapta al tema. */
.badge-borrador { color: var(--text-soft); }

/* ═══════════════════════════════════════════════════════════════════════════
   CABECERA DE SECCIÓN

   `.page-subtitle` no tenía NINGUNA regla: heredaba el color del texto normal
   y salía tan marcado como el título, en las 22 secciones. Parecía un segundo
   titular en vez de una explicación.

   Y la cabecera era un flex sin `wrap`: en pantalla estrecha el subtítulo se
   cortaba a media palabra en vez de bajar a su línea.
   ═══════════════════════════════════════════════════════════════════════════ */
.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 6px 18px;
  margin-bottom: 20px;
}
.page-header h1,
.page-header .page-title { flex: 0 0 auto; margin: 0; }

.page-subtitle {
  flex: 1 1 240px;
  min-width: 0;
  margin: 0;
  font-size: 13px;
  line-height: 1.45;
  color: var(--text-soft);
}
.page-actions { flex: 0 0 auto; margin-left: auto; }
.page-date { flex: 0 0 auto; }

/* En estrecho cada cosa a su línea, y las acciones alineadas a la izquierda
   como todo lo demás en vez de colgando a la derecha. */
@media (max-width: 720px) {
  .page-header { flex-direction: column; align-items: flex-start; gap: 8px; }
  .page-subtitle { flex: 1 1 auto; }
  .page-actions { margin-left: 0; width: 100%; }
}

/* ── Menú en pantalla estrecha ───────────────────────────────────────────── */
.menu-movil {
  display: none;               /* solo aparece cuando la barra se esconde */
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  width: 34px; height: 34px;
  margin-left: 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text-soft);
  cursor: pointer;
  transition: color var(--transition), border-color var(--transition);
}
.menu-movil:hover { color: var(--text); border-color: var(--border-med); }

.menu-velo {
  position: fixed; inset: 0; z-index: 900;
  background: rgba(0,0,0,.5);
  backdrop-filter: blur(2px);
  animation: menu-velo-entra .16s ease;
}
@keyframes menu-velo-entra { from { opacity: 0 } to { opacity: 1 } }

@media (max-width: 720px) {
  .menu-movil { display: inline-flex; }

  /* La barra deja de ocupar sitio y pasa a deslizarse por encima. `display`
     vuelve a ser normal —estaba en `none`, y lo que no se pinta no se puede
     animar ni leer con el teclado. */
  .sidebar {
    display: flex !important;
    position: fixed;
    top: 0; bottom: 0; left: 0;
    z-index: 901;
    width: min(280px, 86vw);
    transform: translateX(-102%);
    transition: transform .22s cubic-bezier(.2,.9,.3,1);
    box-shadow: none;
  }
  body.menu-movil-abierto .sidebar {
    transform: translateX(0);
    box-shadow: 0 0 42px rgba(0,0,0,.5);
  }
  /* Con el menú fuera, el fondo no debe poder desplazarse detrás. */
  body.menu-movil-abierto { overflow: hidden; }
}

@media (prefers-reduced-motion: reduce) {
  .sidebar { transition: none; }
  .menu-velo { animation: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   PANTALLA DE ACCESO · misma cara que la web de presentación

   Se rehace la mitad izquierda con el lenguaje de la web: papel milimetrado,
   el logo de Stock It, Archivo para el titular e IBM Plex Mono para las
   etiquetas. El foco que sigue al ratón y el polvo del haz se quedan — son
   de esta pantalla y no chocan con la retícula.

   Va al final del archivo a propósito: sobrescribe las reglas de arriba sin
   tocarlas, que es como está montado el resto de este CSS.
   ═══════════════════════════════════════════════════════════════════════════ */
.login-screen {
  --lg-tinta:  #eaecf2;
  --lg-tinta2: #a6adbc;
  --lg-tinta3: #838a9a;
  --lg-regla:  rgba(255,255,255,.10);
  --lg-trama:  rgba(255,255,255,.045);
  --lg-sello:  #ff4d5f;
}

/* ── Mitad izquierda ─────────────────────────────────────────────────────── */
.login-marca {
  background: #0b0b0d;
  padding: 46px 52px;
}
/* La retícula de la web, fija bajo el contenido. El foco que ya existía la
   revela alrededor del cursor, igual que en la página de presentación. */
.login-marca::before {
  content: '';
  position: absolute; inset: 0; z-index: -2;
  left: auto; bottom: auto; width: 100%; height: 100%;
  aspect-ratio: auto;
  background:
    linear-gradient(to right,  var(--lg-trama) 1px, transparent 1px),
    linear-gradient(to bottom, var(--lg-trama) 1px, transparent 1px);
  background-size: 58px 58px;
}
.login-marca::after {
  content: '';
  position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(160deg, rgba(255,255,255,0.03) 0%, transparent 55%);
}

.login-marca-eyebrow {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: 'IBM Plex Mono', ui-monospace, Menlo, monospace;
  font-size: 10.5px; font-weight: 600;
  letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--lg-tinta3);
  margin-bottom: 22px;
}
.login-punto { width: 7px; height: 7px; background: var(--lg-sello); flex: 0 0 auto; }

.login-marca-tit {
  font-family: Archivo, ui-sans-serif, system-ui, sans-serif;
  font-weight: 500;
  font-size: clamp(38px, 4.4vw, 62px);
  letter-spacing: -0.045em;
  line-height: .98;
  color: var(--lg-tinta);
  margin: 0;
}
.login-marca-txt {
  font-family: 'IBM Plex Sans', ui-sans-serif, system-ui, sans-serif;
  font-size: 16px; line-height: 1.6;
  color: var(--lg-tinta2);
  max-width: 42ch;
  margin-top: 22px;
}

.login-marca-pie {
  display: flex; align-items: center; gap: 11px;
  position: relative;
}
.login-logo { display: block; width: 20px; height: 20px; color: var(--lg-tinta); }
.login-logo path { fill: currentColor; }
.login-marca-pie span {
  font-family: Archivo, sans-serif; font-weight: 800;
  font-size: 16px; letter-spacing: -0.035em;
  color: var(--lg-tinta);
}

/* ── Mitad derecha: el formulario ────────────────────────────────────────── */
.login-logo-form {
  width: 26px; height: 26px;
  margin-bottom: 20px;
  color: var(--text);
}
.login-form-cab h2 {
  font-family: Archivo, ui-sans-serif, system-ui, sans-serif;
  font-weight: 600; letter-spacing: -0.035em;
}
.login-form-cab p { font-family: 'IBM Plex Sans', ui-sans-serif, system-ui, sans-serif; }

.login-campo > span {
  font-family: 'IBM Plex Mono', ui-monospace, Menlo, monospace;
  font-size: 10.5px; font-weight: 600;
  letter-spacing: 0.2em; text-transform: uppercase;
}
.login-campo input,
.login-btn {
  border-radius: var(--radius-sm);
  font-family: 'IBM Plex Sans', ui-sans-serif, system-ui, sans-serif;
}
/* El botón, igual que los de la web: versalita monoespaciada y ancha. */
.login-btn {
  font-family: 'IBM Plex Mono', ui-monospace, Menlo, monospace;
  font-size: 11.5px; font-weight: 600;
  letter-spacing: 0.11em; text-transform: uppercase;
}
.login-ayuda { font-family: 'IBM Plex Sans', ui-sans-serif, system-ui, sans-serif; }

/* La retícula se mueve un poco con el ratón, como hacía la palmera. */
.login-marca::before { transform: translate3d(var(--lfx-px, 0), var(--lfx-py, 0), 0); }

/* ═══════════════════════════════════════════════════════════════════════════
   LOGO DE STOKIT EN LA BARRA LATERAL

   Las reglas de arriba estaban escritas para un PNG de palmera (`img`, con
   `filter: invert(1)` para pasarlo a blanco). Ahora es un SVG que hereda el
   color, así que no hace falta invertir nada — y de paso funciona igual en
   claro que en oscuro.
   ═══════════════════════════════════════════════════════════════════════════ */
.marca-logo { display: block; }
.marca-logo path { fill: currentColor; }

/* La marca de agua del fondo: el logo, grande y muy tenue, apoyado abajo. */
.sidebar-palm-watermark { align-items: flex-end; justify-content: center; }
.sidebar-palm-watermark .marca-logo {
  width: 62%; height: auto; object-fit: contain;
  color: var(--text);
  margin-bottom: -8%;
}
/* En la luz no va ninguna imagen: la pinta un pseudo-elemento. Si se cuela
   un logo aquí sale a toda potencia, porque la regla que ocultaba el `img`
   original no alcanza a un `svg`. */
.sidebar-luz .marca-logo { display: none; }

/* El de la cabecera: cuadrado, sin caja, y toma el rojo al pasar por encima. */
.logo-mark { display: grid; place-items: center; background: none !important; border: 0 !important; }
.logo-mark .marca-logo {
  width: 24px; height: 24px;
  color: var(--text);
  transition: color .2s ease;
}
.sidebar-logo:hover .logo-mark .marca-logo { color: var(--red); }
/* Con la barra plegada, el logo es lo que la reabre: tiene que verse. */
.sidebar.collapsed .logo-mark { opacity: 1 !important; width: auto !important; overflow: visible !important; }

/* ═══════════════════════════════════════════════════════════════════════════
   REVISIONES · el parte del día

   Lo que falta va primero y en rojo; lo que está bien se resume en una línea.
   La jerarquía es la de una lista de tareas, no la de un panel de estadísticas:
   aquí se viene a ver a quién hay que llamar.
   ═══════════════════════════════════════════════════════════════════════════ */
.rvh {
  border: 1px solid var(--border);
  background: var(--surface);
  padding: 18px 20px;
  margin-bottom: 18px;
}
.rvh-libre {
  display: flex; align-items: center; gap: 10px;
  font-size: 14px; color: var(--text-soft);
}
.rvh-punto { width: 8px; height: 8px; border-radius: 50%; background: var(--text-soft); flex: 0 0 auto; }
.rvh-punto.ok { background: #1f9d55; box-shadow: 0 0 0 3px rgba(31,157,85,.18); }

.rvh-cifras { display: flex; flex-wrap: wrap; gap: 26px; margin-bottom: 4px; }
.rvh-cifra { display: flex; flex-direction: column; gap: 1px; }
.rvh-cifra b {
  font-family: var(--font-display);
  font-size: 30px; font-weight: 700; line-height: 1;
  letter-spacing: -.03em; font-variant-numeric: tabular-nums;
}
.rvh-cifra span {
  font-size: 10.5px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--text-soft);
}
.rvh-cifra.ok b    { color: #1f9d55; }
.rvh-cifra.falta b { color: var(--red); }

.rvh-bloque { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--border); }
.rvh-tit {
  font-size: 11px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; margin-bottom: 10px; color: var(--text-soft);
}
.rvh-bloque.falta .rvh-tit { color: var(--red); }
.rvh-bloque.ok    .rvh-tit { color: #1f9d55; }

.rvh-lista { list-style: none; margin: 0; padding: 0; display: grid; gap: 1px; background: var(--border-fina, var(--border)); }
.rvh-item {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 10px 12px; background: var(--bg);
}
.rvh-veh { font-weight: 600; font-size: 14px; }
.rvh-mat { font-size: 12px; color: var(--text-soft); }
.rvh-proy { margin-inline-start: auto; font-size: 12.5px; color: var(--text-soft); }
.rvh-bloque.falta .rvh-item { border-inline-start: 3px solid var(--red); }
.rvh-nota { margin: 10px 0 0; font-size: 12.5px; color: var(--text-soft); }

/* ═══════════════════════════════════════════════════════════════════════════
   FOTOS DEL MATERIAL

   Cuadrícula de miniaturas con la portada marcada. Las acciones aparecen al
   pasar por encima para que la rejilla se lea como fotos y no como una tabla
   de botones.
   ═══════════════════════════════════════════════════════════════════════════ */
.mfo { margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--border); }
.mfo-cab { display: flex; align-items: center; gap: 9px; margin-bottom: 12px; }
.mfo-tit {
  font-size: 11px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--text-soft);
}
.mfo-n {
  padding: 1px 7px; background: var(--mo-neutro-bg);
  font-size: 11px; font-weight: 700; color: var(--text-soft);
}
.mfo-rejilla {
  display: grid; gap: 10px;
  grid-template-columns: repeat(auto-fill, minmax(126px, 1fr));
}
.mfo-foto {
  position: relative; margin: 0; aspect-ratio: 4 / 3;
  border: 1px solid var(--border); background: var(--surface-sunk, var(--surface));
  overflow: hidden;
}
.mfo-foto img { width: 100%; height: 100%; object-fit: cover; display: block; }
.mfo-foto.portada { border-color: var(--red); }
.mfo-marca {
  position: absolute; left: 0; bottom: 0;
  padding: 3px 8px; background: var(--red); color: #fff;
  font-size: 10px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
}
.mfo-acciones {
  position: absolute; top: 6px; right: 6px; display: flex; gap: 4px;
  opacity: 0; transition: opacity .16s;
}
.mfo-foto:hover .mfo-acciones,
.mfo-foto:focus-within .mfo-acciones { opacity: 1; }
.mfo-acciones button {
  width: 24px; height: 24px; display: grid; place-items: center;
  border: 0; background: rgba(0,0,0,.62); color: #fff;
  font-size: 12px; cursor: pointer;
}
.mfo-acciones button:hover { background: #000; }
.mfo-acciones .mfo-borrar:hover { background: var(--red); }

/* La zona de soltar es una casilla más de la rejilla, no un cajón aparte. */
.mfo-soltar {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 6px; aspect-ratio: 4 / 3; cursor: pointer; text-align: center;
  border: 1px dashed var(--border-med); color: var(--text-soft);
  transition: border-color .16s, color .16s, background .16s;
}
.mfo-soltar:hover, .mfo-soltar.encima { border-color: var(--red); color: var(--text); background: rgba(127,127,127,.05); }
.mfo-soltar.subiendo { opacity: .55; pointer-events: none; }
.mfo-mas { font-size: 22px; line-height: 1; }
.mfo-txt { font-size: 12px; display: grid; gap: 2px; }
.mfo-txt small { font-size: 11px; opacity: .75; }

/* ═══════════════════════════════════════════════════════════════════════════
   GESTIÓN DE CATEGORÍAS

   Lista con sangría por nivel, no un árbol con líneas: con 107 categorías y
   cuatro niveles, las guías de conexión ensucian más de lo que aclaran. La
   sangría sola ya dice la jerarquía.
   ═══════════════════════════════════════════════════════════════════════════ */
.modal.modal-ancho { max-width: 720px; width: 100%; }

.gc-cab {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  margin-bottom: 14px; padding-bottom: 14px; border-bottom: 1px solid var(--border);
}
.gc-cab .mn-pista { margin: 0; flex: 1 1 240px; }

.gc-lista { max-height: 56vh; overflow-y: auto; display: grid; gap: 1px; }
.gc-fila {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px;
  padding-inline-start: calc(10px + var(--nivel, 0) * 20px);
  background: var(--bg);
  border-inline-start: 2px solid transparent;
}
.gc-fila:hover { background: var(--surface); border-inline-start-color: var(--border-med); }
.gc-nombre { font-size: 13.5px; }
.gc-n {
  padding: 1px 7px; background: var(--mo-neutro-bg); color: var(--text-soft);
  font-size: 11px; font-weight: 700; font-variant-numeric: tabular-nums;
}

/* Las acciones solo al pasar por encima: con 107 filas, tres botones en cada
   una convierten la lista en una pared de botones. */
.gc-acciones {
  margin-inline-start: auto; display: flex; gap: 4px;
  opacity: 0; transition: opacity .15s;
}
.gc-fila:hover .gc-acciones,
.gc-fila:focus-within .gc-acciones { opacity: 1; }
.gc-acciones button {
  border: 1px solid var(--border); background: var(--surface); color: var(--text-soft);
  font: inherit; font-size: 11.5px; padding: 3px 9px; cursor: pointer;
  transition: color .15s, border-color .15s;
}
.gc-acciones button:hover { color: var(--text); border-color: var(--border-med); }
.gc-acciones .gc-borrar:hover { color: var(--red); border-color: var(--red); }

/* ═══════════════════════════════════════════════════════════════════════════
   BARRA LATERAL

   Tres problemas medidos, no de percepción:

     · Los encabezados de grupo eran blanco puro a 13,5px — más brillantes y del
       mismo tamaño que los enlaces. La jerarquía estaba invertida: los títulos
       gritaban más que la navegación de debajo.
     · Los enlaces iban a `rgba(255,255,255,.62)`, que sobre este fondo se queda
       corto de contraste.
     · El elemento activo era un bloque de rojo saturado a sangre. Es el rasgo
       que más abarata: el rojo de marca funciona como MARCA, no como relleno.

   Se rehace con el lenguaje de la web de presentación: etiquetas en versalita
   monoespaciada, superficies sobrias y el rojo reducido a un filo.
   ═══════════════════════════════════════════════════════════════════════════ */
.sidebar {
  --sb-texto:   rgba(255,255,255,.80);
  --sb-apagado: rgba(255,255,255,.50);   /* .42 daba 4,1 de contraste; el mínimo es 4,5 */
  --sb-vivo:    #fff;
  --sb-hover:   rgba(255,255,255,.055);
  --sb-activo:  rgba(255,255,255,.085);
  padding-inline: 10px;
}

/* ── Encabezados de grupo: etiquetas, no titulares ───────────────────────── */
.sidebar .nav-group-head {
  display: flex; align-items: center; gap: 9px;
  width: 100%; height: 30px;
  margin-top: 14px; padding-inline: 10px;
  border: 0; background: none; cursor: pointer;
  font-family: 'IBM Plex Mono', ui-monospace, Menlo, monospace;
  font-size: 9.5px; font-weight: 600;
  letter-spacing: .16em; text-transform: uppercase;
  color: var(--sb-apagado);
  transition: color var(--transition);
}
.sidebar .nav-group-head:hover { color: var(--sb-texto); }
.sidebar .nav-group-ico { width: 13px; height: 13px; opacity: .8; flex: 0 0 auto; }
.sidebar .nav-group:first-of-type .nav-group-head { margin-top: 6px; }

/* ── Enlaces ─────────────────────────────────────────────────────────────── */
.sidebar .nav-item {
  position: relative;
  height: 34px;
  padding-inline: 10px;
  border-radius: var(--radius-sm);
  color: var(--sb-texto);
  font-size: 13px; font-weight: 450;
  transition: background var(--transition), color var(--transition);
}
.sidebar .nav-group-items .nav-item {
  padding-inline-start: 32px;              /* alineados bajo el texto del grupo */
  /* NO se atenúan. Al principio los puse a la misma opacidad que las etiquetas
     de grupo (.42) y el contraste caía a 4,0 — justo el «contrasta mal» que
     había que arreglar. La jerarquía la da que la etiqueta sea diminuta, en
     versalita y monoespaciada; no hace falta apagar los enlaces. */
  color: var(--sb-texto);
}
.sidebar .nav-item:hover { background: var(--sb-hover); color: var(--sb-vivo); }
.sidebar .nav-group-items .nav-item:hover { color: var(--sb-vivo); }

/* El activo: superficie discreta y un filo rojo. La marca señala, no rellena. */
.sidebar .nav-item.active,
.sidebar .nav-group-items .nav-item.active {
  background: var(--sb-activo);
  color: var(--sb-vivo);
  font-weight: 550;
}
.sidebar .nav-item.active::before {
  content: '';
  position: absolute; left: 0; top: 50%;
  width: 2px; height: 18px;
  background: var(--red);
  transform: translateY(-50%);
}

/* ── Ritmo ───────────────────────────────────────────────────────────────── */
.sidebar .nav-group-items { display: grid; gap: 1px; margin-top: 2px; }
.sidebar .nav-fijos { display: grid; gap: 1px; }
.sidebar-logo { padding-block: 16px 14px; }

/* Pie separado por una regla, no flotando. */
.sidebar-user { border-top: 1px solid rgba(255,255,255,.08); padding-block: 11px; }

/* Un punto más de ancho: «Calendario de Flota» y «Microsoft 365» iban
   apretados contra el borde a 234px. */
:root { --sidebar-w: 264px; }
@media (max-width: 1180px) { :root { --sidebar-w: 248px; } }
@media (max-width: 900px)  { :root { --sidebar-w: 238px; } }

/* ═══════════════════════════════════════════════════════════════════════════
   AVISO DE SIN CONEXIÓN

   Fijo abajo y a lo ancho. Arriba competiría con la barra de pestañas, y en una
   esquina se confunde con un aviso pasajero — esto no se va hasta que vuelva la
   red, así que tiene que ocupar sitio.
   ═══════════════════════════════════════════════════════════════════════════ */
.offline-barra {
  position: fixed; inset-inline: 0; bottom: 0; z-index: 9000;
  display: flex; align-items: center; gap: 12px;
  padding: 11px 18px;
  background: #4a1218; color: #ffe9ec;
  border-top: 2px solid var(--red);
  font-size: 13.5px;
  animation: offline-entra .22s cubic-bezier(.2,.9,.3,1);
}
@keyframes offline-entra { from { transform: translateY(100%) } to { transform: none } }
.offline-punto {
  width: 9px; height: 9px; border-radius: 50%; background: var(--red); flex: 0 0 auto;
  animation: offline-late 1.6s ease-in-out infinite;
}
@keyframes offline-late { 0%,100% { opacity: 1 } 50% { opacity: .35 } }
.offline-txt { flex: 1 1 auto; }
.offline-txt b { color: #fff; font-weight: 600; }
.offline-btn {
  flex: 0 0 auto;
  border: 1px solid rgba(255,255,255,.35); background: transparent; color: #ffe9ec;
  font: inherit; font-size: 12.5px; padding: 5px 12px; cursor: pointer;
  transition: background .15s;
}
.offline-btn:hover { background: rgba(255,255,255,.12); }
@media (prefers-reduced-motion: reduce) {
  .offline-barra { animation: none; }
  .offline-punto { animation: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   LOGIN · claro / oscuro

   Un interruptor de verdad, con la bola que se desliza: la gracia de estos
   controles es que se ven cambiar, y aquí hay sitio de sobra. Va abajo a la
   derecha del panel del formulario, lejos de los campos.
   ═══════════════════════════════════════════════════════════════════════════ */
.login-tema {
  position: absolute; right: 26px; bottom: 22px; z-index: 3;
  display: inline-flex; align-items: center; gap: 10px;
  border: 0; background: none; cursor: pointer;
  font-family: 'IBM Plex Mono', ui-monospace, Menlo, monospace;
  font-size: 10px; font-weight: 600; letter-spacing: .12em; text-transform: uppercase;
  color: var(--text-soft);
  transition: color .18s;
}
.login-tema:hover { color: var(--text); }

.login-tema-pastilla {
  position: relative; width: 40px; height: 22px; flex: 0 0 auto;
  border: 1px solid var(--border-med); border-radius: 999px;
  background: var(--surface);
  transition: background .3s, border-color .3s;
}
.login-tema-bola {
  position: absolute; top: 2px; left: 2px;
  width: 16px; height: 16px; border-radius: 50%;
  background: var(--text-soft);
  transition: transform .32s cubic-bezier(.2,1.3,.4,1), background .3s;
}
/* En oscuro la bola se va a la derecha y se pone del rojo de marca: el
   recorrido es la mitad de la gracia. */
.login-tema.es-oscuro .login-tema-bola { transform: translateX(18px); background: var(--red); }
.login-tema:hover .login-tema-pastilla { border-color: var(--red); }

@media (prefers-reduced-motion: reduce) {
  .login-tema-bola { transition: none; }
}
@media (max-width: 720px) { .login-tema { right: 20px; bottom: 16px; } }

/* ═══════════════════════════════════════════════════════════════════════════
   FONDO MÁS CLARO Y SELECCIÓN SÓLIDA EN LA BARRA

   Dos cosas pedidas juntas, y van juntas de verdad:

   1. El fondo estaba en #0f0f13 — casi negro. Sube a #16161c, y las superficies
      con él. Sigue siendo oscuro, pero deja de parecer un agujero: las tarjetas
      se separan del fondo por tono en vez de por borde.

   2. La selección de la barra. La anterior era un matiz sutil con un filo rojo
      y no se veía; la de antes era rojo saturado a sangre y quedaba barata. La
      referencia que pasó Xavi hace lo correcto: un BLOQUE SÓLIDO, macizo, en
      color NEUTRO —no el de acento— y con el texto invertido. Como aquí la
      barra es oscura, el bloque va claro y el texto oscuro.
   ═══════════════════════════════════════════════════════════════════════════ */
/* ⚠ AQUÍ METÍ LA PATA: puse estos valores oscuros en `:root`, que es la
   definición del tema CLARO. Resultado: el modo claro se volvió oscuro y con
   los bordes en blanco translúcido, ilegible. Los valores oscuros van SOLO en
   sus dos bloques (media query y `[data-tema="oscuro"]`), nunca en `:root`. */
@media (prefers-color-scheme: dark) {
  :root:not([data-tema="claro"]) {
    --bg:         #16161c;
    --surface:    #1e1e25;
    --surface-2:  #26262f;
    --sidebar-bg: #101015;
  }
}
:root[data-tema="oscuro"] {
  --bg:         #16161c;
  --surface:    #1e1e25;
  --surface-2:  #26262f;
  --sidebar-bg: #101015;
}

/* Y lo que se pedía del claro era otra cosa: que el fondo dejara de ser tan
   gris y tirara a blanco. Era #dde5eb —un gris azulado bastante cargado—;
   ahora es casi blanco y las tarjetas se separan por borde, no por tono. */
:root[data-tema="claro"],
html[data-tema="claro"] {
  --bg:        #f7f8fa;
  --surface:   #ffffff;
  --surface-2: #f0f2f5;
}
@media (prefers-color-scheme: light) {
  :root:not([data-tema="oscuro"]) {
    --bg:        #f7f8fa;
    --surface:   #ffffff;
    --surface-2: #f0f2f5;
  }
}

/* ── La selección ─────────────────────────────────────────────────────────── */
.sidebar .nav-item {
  border-radius: 7px;                 /* la referencia va redondeada, no a canto vivo */
  margin-inline: 2px;
}

/* Fuera el filo rojo del intento anterior: la referencia no usa el color de
   acento para señalar, usa contraste. */
.sidebar .nav-item.active::before { display: none; }

.sidebar .nav-item.active,
.sidebar .nav-group-items .nav-item.active {
  background: #f2f2f5;
  color: #14141a;
  font-weight: 600;
}
.sidebar .nav-item.active:hover,
.sidebar .nav-group-items .nav-item.active:hover {
  background: #fff;
  color: #14141a;
}
/* Los iconos y contadores de dentro tienen que invertirse también, o se quedan
   claros sobre claro. */
.sidebar .nav-item.active svg { color: #14141a; opacity: .9; }
.sidebar .nav-item.active .nav-badge {
  background: var(--red); color: #fff;
}

/* La marca de agua del fondo de la barra se diseñó para la palmera, sobre un
   fondo casi negro. Con el fondo aclarado, un logo al 7,5% deja de leerse como
   textura y se lee como una mancha — se veía un borrón rojizo justo encima del
   usuario. Fuera: la barra se sostiene sin adornos. */
.sidebar-palm-watermark { display: none; }

/* ── Diálogo de importación ──────────────────────────────────────────────── */
.imp-soltar {
  display: flex; align-items: center; gap: 14px;
  padding: 22px 20px; cursor: pointer; text-align: left;
  border: 1px dashed var(--border-med); color: var(--text-soft);
  transition: border-color .16s, color .16s, background .16s;
}
.imp-soltar:hover, .imp-soltar.encima {
  border-color: var(--red); color: var(--text); background: rgba(127,127,127,.05);
}
.imp-ico { flex: 0 0 auto; opacity: .8; }
.imp-txt { display: grid; gap: 3px; }
.imp-txt b { font-size: 14.5px; font-weight: 600; color: var(--text); }
.imp-txt small { font-size: 12px; }

.imp-resumen {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 14px; padding: 11px 13px;
  background: var(--surface-2); border-inline-start: 3px solid var(--red);
  font-size: 13px;
}
.imp-arch { font-weight: 600; }
.imp-peso, .imp-cargando { color: var(--text-soft); font-size: 12px; }
.imp-cargando { margin-inline-start: auto; }

/* La plantilla, al final y separada: es la salida de quien no sabe qué
   columnas hacen falta, no una opción del mismo rango que importar. */
.imp-pie {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--border);
}
.imp-pie-txt { flex: 1 1 auto; margin: 0; font-size: 13px; color: var(--text-soft); }

/* ── Proyectos: filtros plegables ────────────────────────────────────────── */
.proy-barra-filtros { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
#proy-btn-filtros { display: inline-flex; align-items: center; gap: 7px; }
#proy-btn-filtros.activo { color: var(--text); border-color: var(--border-med); }
#proy-btn-filtros.con-filtros { border-color: var(--red); color: var(--text); }
.proy-filtros-n {
  display: none; min-width: 17px; padding: 0 5px;
  background: var(--red); color: #fff;
  font-size: 10.5px; font-weight: 700; line-height: 17px; text-align: center;
  border-radius: 999px;
}
.proy-filtros-n.hay { display: inline-block; }

/* ── Editar sobre la ficha de material ───────────────────────────────────── */
.mat-input {
  width: 100%;
  padding: 5px 8px;
  border: 1px solid var(--border-med);
  border-radius: var(--radius-sm);
  background: var(--bg);
  color: var(--text);
  font: inherit; font-size: 13.5px;
}
.mat-input:focus {
  outline: none; border-color: var(--red);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--red) 16%, transparent);
}
.mat-input-nombre { font-size: 19px; font-weight: 600; padding: 6px 10px; }
/* Mientras se edita, la ficha se marca: sin señal, no se distingue de la
   versión de lectura y se pierde el hilo de si hay cambios sin guardar. */
.mat-editando { box-shadow: inset 3px 0 0 var(--red); }
.mat-editando .mat-dato { background: var(--surface-2); }

/* ── Editar sobre la ficha de dispositivo ────────────────────────────────── */
.pf-input {
  width: 100%;
  padding: 5px 8px;
  border: 1px solid var(--border-med);
  border-radius: var(--radius-sm);
  background: var(--bg); color: var(--text);
  font: inherit; font-size: 13.5px;
}
.pf-input:focus {
  outline: none; border-color: var(--red);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--red) 16%, transparent);
}
.pf-editando { box-shadow: inset 3px 0 0 var(--red); }
.pf-editando .pf-dato[data-campo] { background: var(--surface-2); }
.pf-input-titulo { font-size: 21px; font-weight: 700; padding: 6px 10px; }

/* La línea vertical que marcaba el grupo con la sección activa. Tenía sentido
   cuando el elemento activo era un matiz sutil y hacía falta una segunda pista;
   con el bloque sólido sobra, y además el rasgo —una guía de árbol— es de otra
   época. El bloque ya dice dónde estás. */
.sidebar .nav-group.tiene-activo { box-shadow: none; }

/* ═══════════════════════════════════════════════════════════════════════════
   BARRA LATERAL · sin hover

   Pedido explícito: fuera el resaltado al pasar por encima. Y tiene sentido —
   con el bloque sólido marcando dónde estás, un segundo resaltado que aparece
   y desaparece bajo el ratón compite con él y ensucia el conjunto. El puntero
   ya dice que se puede pulsar; no hace falta pintarlo.

   Solo se conserva el cambio de COLOR del texto, que no mueve ni pinta nada.
   ═══════════════════════════════════════════════════════════════════════════ */
.sidebar .nav-item:hover,
.sidebar .nav-group-items .nav-item:hover,
.sidebar .nav-fijos .nav-item:hover {
  background: transparent;
}
.sidebar .nav-item:hover { color: var(--sb-vivo); }
.sidebar .nav-group-items .nav-item:hover { color: var(--sb-vivo); }
/* El activo mantiene su bloque también bajo el ratón: si se aclarara al pasar
   por encima parecería que se puede «activar más». */
.sidebar .nav-item.active:hover,
.sidebar .nav-group-items .nav-item.active:hover {
  background: #f2f2f5;
  color: #14141a;
}

/* ═══════════════════════════════════════════════════════════════════════════
   FICHA DE PROYECTO MÁS ANCHA

   «Las fichas de proyecto son enanas y hacer cosas encima es muy difícil».
   Estaban limitadas a un ancho de lectura, que va bien para un texto pero no
   para una tabla de material con precios y cantidades.
   ═══════════════════════════════════════════════════════════════════════════ */
#proy-ficha .pf,
#disp-ficha .pf { max-width: none; }
#proy-ficha .pf-datos { grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }

/* ── Diálogo de elección ─────────────────────────────────────────────────── */
.modal.elg { max-width: 480px; }
.elg-cuerpo { padding: 26px 26px 22px; }
.elg-titulo { margin: 0 0 10px; font-size: 19px; font-weight: 650; letter-spacing: -.02em; }
.elg-texto { margin: 0 0 20px; font-size: 14px; line-height: 1.55; color: var(--text-soft); }
.elg-texto b { color: var(--text); font-weight: 600; }
.elg-opciones { display: grid; gap: 8px; }
.elg-opcion {
  display: grid; gap: 3px; text-align: left;
  padding: 13px 15px; cursor: pointer;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--text); font: inherit;
  transition: border-color .15s, background .15s;
}
.elg-opcion:hover { border-color: var(--border-med); background: var(--surface-2); }
.elg-opcion.destacada { border-color: var(--red); }
.elg-opcion.destacada:hover { background: color-mix(in srgb, var(--red) 8%, var(--surface)); }
.elg-op-tit { font-size: 14.5px; font-weight: 600; }
.elg-op-sub { font-size: 12.5px; color: var(--text-soft); }
.elg-nota {
  margin: 18px 0 0; padding-top: 14px; border-top: 1px solid var(--border);
  font-size: 12.5px; line-height: 1.55; color: var(--text-soft);
}
.elg-nota b { color: var(--text); }

/* ═══════════════════════════════════════════════════════════════════════════
   CALENDARIO DEL PANEL · dos meses y arrastre
   El Gantt pinta el mes en curso y el siguiente seguidos, para que un proyecto
   que cruza el cambio de mes se vea entero en lugar de morir contra el borde.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Primer día del segundo mes: línea vertical que separa sin gritar, y el
   nombre del mes en lugar de la letra del día de la semana. */
.gantt-day-hdr.g-mes-ini { box-shadow: inset 1px 0 0 var(--border); }
/* Cabe justo en los 34 px de la columna, medido a 9 px/700. */
.gantt-day-hdr.g-mes-ini .gd-wd {
  color: var(--text);
  font-weight: 700;
  opacity: 1;
  white-space: nowrap;
}

/* Arrastre: la mano solo aparece donde de verdad se puede agarrar. */
.gantt-scroll.gantt-arrastrable { cursor: grab; }
.gantt-scroll.gantt-agarrado    { cursor: grabbing; user-select: none; }
/* Sobre las barras manda el cursor de la barra, que sí son clicables. */
.gantt-scroll .gantt-bar { cursor: pointer; }

/* ═══════════════════════════════════════════════════════════════════════════
   PROYECTO · EQUIPMENT Y FINANZAS

   Dos pestañas nuevas que separan el material del dinero. Se dimensionan a lo
   ancho de la ficha y con filas altas: son tablas de trabajo, se pasan horas
   dentro, y las que se hicieron pequeñas para «caber» acabaron siendo las que
   nadie usa.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Barra de arriba ── */
.eq-barra {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
  margin-bottom: 18px;
}
.eq-barra-izq { display: flex; align-items: center; gap: 16px; }
/* La acción principal de la pestaña, a la altura de las filas de 60 px que
   tiene debajo: con el alto estándar de botón se perdía contra la tabla. */
.eq-btn-add { padding: 10px 18px; font-size: 14px; }
.eq-resumen { font-size: 14px; color: var(--text-soft); }
.eq-resumen strong { color: var(--text); font-weight: 650; }
.eq-link {
  font-size: 13px; color: var(--accent); cursor: pointer;
  background: none; border: 0; padding: 0;
}
.eq-link:hover { text-decoration: underline; }
.eq-vacio p { margin: 0 0 8px; }
.eq-vacio p:last-child { margin-bottom: 0; }

/* ── Bloques por subproyecto ── */
.eq-sub { margin-bottom: 26px; }
.eq-sub-cab {
  display: flex; align-items: baseline; justify-content: space-between;
  flex-wrap: wrap;
  gap: 6px 12px; padding-bottom: 8px; margin-bottom: 10px;
  border-bottom: 1px solid var(--border);
}
.eq-sub-tit { font-size: 16px; font-weight: 650; margin: 0; }
/* `margin-left:auto` se come el hueco libre, así que el recuento sigue pegado a
   la derecha tanto si hay botón al lado como si no, sin tocar el reparto de la
   cabecera para el caso de siempre. */
/* `nowrap`: el recuento va en monoespaciada con letra separada y, sin esto, un
   «6 líneas · 2160,00 €» se parte en cuatro renglones en cuanto el panel es
   estrecho. Y la cabecera envuelve, así que el botón baja a su línea en vez de
   salirse por el canto. */
.eq-sub-meta { font-size: 13px; color: var(--text-soft); margin-left: auto; white-space: nowrap; }
/* «Mover todo a…»: a la derecha del todo y discreto. Es una operación en bloque
   y no se pulsa sin querer; por eso no tiene el color de la casa hasta que se
   pasa por encima. */
.eq-sub-mover {
  flex-shrink: 0; align-self: center;
  padding: 4px 10px;
  border: 1px solid var(--border); border-radius: 20px;
  background: none;
  font: inherit; font-size: 11.5px; font-weight: 650; color: var(--text-soft);
  white-space: nowrap; cursor: pointer;
  transition: color var(--transition), border-color var(--transition), background var(--transition);
}
.eq-sub-mover:hover {
  color: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 45%, var(--border));
  background: var(--bg-hover);
}

/* «Estás viendo el proyecto entero». Informativo, no una alarma: va en la tinta
   suave de la casa sobre el papel hundido, no en ámbar ni en rojo, que están
   reservados a lo que hay que atender y a lo que está roto. */
.eq-todo-aviso {
  margin: 0 0 14px; padding: 10px 13px;
  border: 1px solid var(--border); border-radius: 9px;
  background: var(--bg-hover);
  font-size: 12.5px; line-height: 1.55; color: var(--text-2, var(--text));
}
.eq-todo-aviso strong { color: var(--text); }

/* El subproyecto al que pertenece una carpeta, encima de su nombre. En micro y
   en gris: es la respuesta a «¿de cuál era esto?», no un segundo título. */
.eqf-nomcol { display: flex; flex-direction: column; justify-content: center; min-width: 0; gap: 1px; }
.eqf-sub {
  font-size: 10px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  color: var(--text-soft);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Material fuera de todos los subproyectos: no es una sección, es un pendiente.
   Se usa el mismo ámbar que ya lleva `.badge-orange` en el resto de la casa
   —rgba(255,149,0) sobre tinta `--orange-dark`— y no el rojo, que aquí está
   reservado a lo que ya está roto. Esto no está roto: está sin colocar. */
.eq-sub-huerfano .eq-sub-tit { color: var(--orange-dark); }
.eq-sub-huerfano .eq-sub-cab { border-bottom-color: rgba(255,149,0,0.45); }
.eq-sub-aviso {
  margin: 0 0 10px; padding: 9px 12px;
  border-radius: 8px;
  background: rgba(255,149,0,0.10);
  font-size: 12.5px; line-height: 1.5; color: var(--orange-dark);
}

.eq-grupo { margin-bottom: 14px; }
.eq-grupo-tit {
  font-size: 12px; font-weight: 650; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--text-soft);
  padding: 6px 0 4px;
}

/* La rejilla: el nombre se lleva el hueco que sobra y los números van a la
   derecha, en columnas de ancho fijo para que se puedan comparar de un vistazo. */
.eq-tabla { display: flex; flex-direction: column; }
.eq-cab, .eq-fila {
  display: grid;
  grid-template-columns: 34px 90px minmax(180px, 1fr) 78px 78px 96px 104px 40px;
  align-items: center;
  gap: 10px;
}
.eq-cab {
  font-size: 11px; font-weight: 650; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--text-soft);
  padding: 4px 8px 8px;
}
.eq-fila {
  padding: 10px 8px;            /* filas altas: se pulsan y se leen mejor */
  border-radius: 8px;
  border-bottom: 1px solid var(--border);
  font-size: 14px;
}
.eq-fila:last-child { border-bottom: none; }
.eq-fila:hover { background: var(--bg-hover); }
.eq-fila.sel { background: color-mix(in srgb, var(--accent) 10%, transparent); }
.eq-check { display: flex; align-items: center; justify-content: center; }
.eq-nombre { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.eq-nombre > em {
  font-style: normal; font-size: 11px; color: var(--text-soft);
}
.eq-total { font-variant-numeric: tabular-nums; font-weight: 600; }

/* Campos editables en la propia fila. Se ven como texto hasta que los tocas:
   una tabla con veinte cajas de formulario dibujadas parece un formulario, no
   una lista. */
.eq-num {
  width: 100%; text-align: right;
  padding: 6px 8px; font-size: 14px;
  font-variant-numeric: tabular-nums;
  background: transparent;
  border: 1px solid transparent; border-radius: 6px;
  color: var(--text);
}
.eq-num:hover  { border-color: var(--border); }
.eq-num:focus  { border-color: var(--accent); background: var(--bg-card); outline: none; }
/* Las flechitas del number roban ancho y no se usan con el teclado a mano. */
.eq-num::-webkit-inner-spin-button, .eq-num::-webkit-outer-spin-button {
  -webkit-appearance: none; margin: 0;
}
.eq-num { -moz-appearance: textfield; appearance: textfield; }

/* El número de cantidad y días es un BOTÓN, no una caja de escribir: se toca y
   sale el paso. Se sigue viendo como texto —una tabla con veinte cajas
   dibujadas parece un formulario— pero ahora dice que se puede tocar. */
.eq-paso {
  width: 100%; text-align: right; cursor: pointer;
  font: inherit; font-size: 14px;
  font-variant-numeric: tabular-nums;
}
.eq-paso:hover { border-color: var(--border); background: var(--bg-hover); }
.eq-paso:focus-visible { border-color: var(--accent); outline: none; }

/* El menú del botón derecho sobre una carpeta de material. Igual de sobrio que
   el panel del paso: los dos salen de donde está el dedo y los dos se van solos
   al tocar fuera. */
.eqm {
  position: fixed; z-index: 1100;
  min-width: 232px; padding: 6px;
  background: var(--surface);
  border: 1px solid var(--border); border-radius: 12px;
  box-shadow: 0 8px 26px rgba(0,0,0,.18);
  opacity: 0; transform: translateY(3px);
  transition: opacity .12s ease, transform .12s ease;
}
.eqm.visible { opacity: 1; transform: none; }
.eqm-tit {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  padding: 7px 10px 9px; margin-bottom: 4px;
  border-bottom: 1px solid var(--border);
  font-size: 13px; font-weight: 700; color: var(--text);
  overflow: hidden;
}
.eqm-tit span { font-size: 11px; font-weight: 600; color: var(--text-soft); white-space: nowrap; }
.eqm-op {
  display: block; width: 100%; text-align: left;
  padding: 9px 10px;
  border: 0; border-radius: 8px; background: none;
  font: inherit; font-size: 13.5px; color: var(--text);
  cursor: pointer;
}
.eqm-op:hover { background: var(--bg-hover); color: var(--accent); }
.eqm-op em {
  display: block; margin-top: 2px;
  font-style: normal; font-size: 11.5px; color: var(--text-soft);
}
/* Una raya antes de lo que cambia o quita cosas: en un menú donde todo se ve
   igual, la opción que borra se pulsa sin querer. */
.eqm-op.raya { margin-top: 5px; padding-top: 10px; border-top: 1px solid var(--border); border-radius: 0 0 8px 8px; }
.eqm-op.malo { color: var(--red, #c1121f); }
.eqm-op.malo:hover { background: color-mix(in srgb, var(--red, #c1121f) 10%, transparent); color: var(--red, #c1121f); }

/* El panel del paso. Flota sobre todo porque las columnas de la tabla bajan a
   56 px y ahí no caben dos botones que se puedan tocar con el dedo. */
.eqp {
  position: fixed; z-index: 1100;
  min-width: 190px; padding: 12px 14px 11px;
  background: var(--surface);
  border: 1px solid var(--border); border-radius: 12px;
  box-shadow: 0 8px 26px rgba(0,0,0,.18);
  opacity: 0; transform: translateY(3px);
  transition: opacity .13s ease, transform .13s ease;
}
.eqp.visible { opacity: 1; transform: none; }
.eqp-tit {
  font-size: 10.5px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  color: var(--text-soft); margin-bottom: 8px;
}
.eqp-fila { display: flex; align-items: center; gap: 10px; }
.eqp-btn {
  width: 40px; height: 40px; flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  font-size: 21px; line-height: 1; font-weight: 600;
  color: var(--text);
  background: var(--bg-hover); border: 1px solid var(--border);
  border-radius: 10px; cursor: pointer;
  transition: background var(--transition), color var(--transition);
}
.eqp-btn:hover:not(:disabled) { background: var(--accent); border-color: var(--accent); color: #fff; }
.eqp-btn:disabled { opacity: .35; cursor: default; }
.eqp-cifra {
  width: 100%; min-width: 0; text-align: center;
  padding: 6px 2px;
  font-size: 22px; font-weight: 700; font-variant-numeric: tabular-nums;
  color: var(--text);
  background: none; border: 0; border-radius: 8px;
}
.eqp-cifra:focus { outline: none; background: var(--bg-hover); }
.eqp-cifra::-webkit-inner-spin-button, .eqp-cifra::-webkit-outer-spin-button {
  -webkit-appearance: none; margin: 0;
}
.eqp-cifra { -moz-appearance: textfield; appearance: textfield; }
.eqp-pie {
  margin-top: 9px; max-width: 220px;
  font-size: 11.5px; color: var(--text-soft);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.eq-acc { display: flex; justify-content: flex-end; }
.eq-x {
  width: 28px; height: 28px; line-height: 1;
  font-size: 18px; color: var(--text-soft);
  background: none; border: 0; border-radius: 6px; cursor: pointer;
}
.eq-x:hover { background: var(--bg-hover); color: var(--red); }

/* ── Acciones en bloque ── */
.eq-selbarra {
  position: sticky; top: 0; z-index: 3;
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 12px 16px; margin-bottom: 16px;
  border-radius: 10px;
  background: var(--bg-card);
  border: 1px solid var(--accent);
  box-shadow: 0 2px 10px rgba(0,0,0,0.10);
}
.eq-selbarra-n { font-weight: 650; font-size: 14px; }
.eq-selbarra-campo {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; color: var(--text-soft);
}
.eq-selbarra-campo select { padding: 6px 10px; font-size: 13px; }
.eq-peligro:hover { border-color: var(--red); color: var(--red); }

/* ── Lo ya contabilizado, plegado ── */
.eq-historico { margin-top: 28px; border-top: 1px solid var(--border); padding-top: 14px; }
.eq-historico > summary {
  cursor: pointer; font-size: 13px; font-weight: 600; color: var(--text-soft);
  padding: 6px 0; list-style: revert;
}
.eq-historico > summary:hover { color: var(--text); }
.eq-historico-cuerpo { padding-top: 12px; }

/* ── Diálogo de grupo ── */
.modal.eqg .eqg-inp {
  width: 100%; padding: 11px 14px; margin-top: 4px; font-size: 15px;
  border: 1px solid var(--border); border-radius: 10px;
  background: var(--bg-card); color: var(--text);
}
.modal.eqg .eqg-inp:focus { border-color: var(--accent); outline: none; }
.eqg-ya { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.eqg-chip {
  padding: 5px 12px; font-size: 13px;
  border: 1px solid var(--border); border-radius: 999px;
  background: none; color: var(--text-soft); cursor: pointer;
}
.eqg-chip:hover { border-color: var(--accent); color: var(--text); }
.eqg-acc { display: flex; gap: 10px; justify-content: flex-end; margin-top: 20px; }

/* ═══ Finanzas: el exportador ════════════════════════════════════════════ */
.fz-exp {
  border: 1px solid var(--border); border-radius: 12px;
  background: var(--bg-card);
  margin-bottom: 28px;
  overflow: hidden;
}
.fz-exp-cab { padding: 18px 20px 14px; }
.fz-tit { margin: 0 0 4px; font-size: 16px; font-weight: 650; }
.fz-sub { margin: 0; font-size: 13px; color: var(--text-soft); }
.fz-exp-vacio { padding: 18px 20px; }
.fz-exp-vacio .fz-tit { margin-bottom: 6px; }

.fz-subs { border-top: 1px solid var(--border); }
.fz-sub-fila {
  display: grid; grid-template-columns: 26px minmax(140px, 1fr) 120px 120px;
  align-items: center; gap: 12px;
  padding: 12px 20px;
  border-bottom: 1px solid var(--border);
  font-size: 14px; cursor: pointer;
}
.fz-sub-fila:last-child { border-bottom: none; }
.fz-sub-fila:hover { background: var(--bg-hover); }
.fz-sub-fila.sel { background: color-mix(in srgb, var(--accent) 10%, transparent); }
/* Un subproyecto sin material no se puede cobrar: se deja ver, apagado, en vez
   de esconderlo, porque su ausencia también es información. */
.fz-sub-fila.vacio { opacity: 0.5; cursor: default; }
.fz-sub-fila.vacio:hover { background: none; }
.fz-sub-nom { font-weight: 550; }
.fz-sub-n   { font-size: 12px; color: var(--text-soft); }
.fz-sub-eur { font-variant-numeric: tabular-nums; }

.fz-exp-pie {
  display: flex; align-items: center; gap: 12px;
  padding: 16px 20px;
  border-top: 1px solid var(--border);
  background: var(--surface-2);
}
.fz-total { flex: 1; font-size: 15px; }

/* ── Pantallas estrechas: las rejillas se relajan antes de romperse ── */
@media (max-width: 900px) {
  .eqb-ajustes { grid-template-columns: 1fr 1fr; }
  .eqb-fila { grid-template-columns: 26px minmax(140px, 1fr) 84px; }
  .eqb-fila > :nth-child(2), .eqb-fila > :nth-child(4), .eqb-fila > :nth-child(5) { display: none; }
  .fz-sub-fila { grid-template-columns: 26px 1fr 100px; }
  .fz-sub-fila > .fz-sub-n { display: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   FICHA DE PROYECTO · dejar de ser enana

   La ficha se escribió para caber en un cajón lateral estrecho, y de ahí venían
   los 12,5 px de los valores, los 10,5 px de las cabeceras y las filas de 9 px
   de alto. Ahora ocupa la pantalla entera y esa letra se quedaba flotando en
   medio de un montón de sitio vacío.

   Se sube todo un escalón, con la misma proporción entre etiqueta y valor que
   ya tenía: no es un rediseño, es la misma ficha a su tamaño. Los datos que se
   leen —el valor, el nombre, el importe— crecen más que las etiquetas, que solo
   dicen de qué es el dato.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Fichas de datos ── */
.pf-dato {
  grid-template-columns: 150px minmax(0, 1fr);
  padding: 12px 0;
}
.pf-dato dt { font-size: 13px; }
.pf-dato dd { font-size: 15px; line-height: 1.45; }

/* ── Tablas ── */
.pf-tabla-cab, .pf-tabla-fila { padding: 12px 0; }
.pf-tabla-cab  { font-size: 11px; }
.pf-tabla-fila { font-size: 14.5px; }
.pf-tabla-fila .mono  { font-size: 13px; }
.pf-tabla-fila .suave { font-size: 13.5px; }

/* ── Cabeceras de sección ── */
.pf-sec-tit { font-size: 13px; }
.pf-sec-eur { font-size: 14px; }
.pf-nada    { font-size: 14px; }

/* ── Presupuestos ── */
.pf-pres { padding: 14px 8px; }
.pf-pres-num { font-size: 13.5px; }
.pf-pres-cli { font-size: 14.5px; }
.pf-pres-fec { font-size: 13px; }
.pf-pres-eur { font-size: 15px; }

/* ── Contactos ── */
.pf-contacto { padding: 13px 0; }
.pf-contacto-nom { font-size: 14.5px; }
.pf-contacto-rol { font-size: 12.5px; }
.pf-contacto-vias a { font-size: 13px; }

/* En pantallas de verdad estrechas se vuelve al tamaño de antes: ahí la letra
   grande no da desahogo, quita sitio. */
@media (max-width: 700px) {
  .pf-dato { grid-template-columns: 1fr; gap: 2px; padding: 10px 0; }
  .pf-dato dd { font-size: 14px; }
  .pf-tabla-fila { font-size: 13.5px; }
  .pf-pres-cli, .pf-contacto-nom { font-size: 13.5px; }
}

/* ── Subproyectos: la misma subida ────────────────────────────────────────
   Esta pestaña se quedó fuera del cambio de arriba porque tiene clases propias
   (`.dep-*`, heredadas del cajón lateral que había antes). Las tarjetas de
   subproyecto son lo que más se pulsa de la ficha: 9 px de alto y 13 px de
   letra las dejaban como una lista de notas al pie. */
.dep-card-cab { padding: 13px 14px; gap: 12px; }
.dep-card-nom { font-size: 15px; }
.dep-card-sub { font-size: 12px; }
.dep-card-n   { font-size: 12px; padding: 2px 8px; min-width: 26px; }
.dep-card-eur { font-size: 15px; }
.dep-card-barra { height: 3px; }
.dep-detalle  { padding: 12px 14px 14px; }
.dep-sueltos-tit { font-size: 12px; margin: 16px 0 8px; }
.dep-total    { font-size: 14.5px; margin-top: 16px; padding-top: 12px; }
.dep-total-n  { font-size: 13px; }

/* Las secciones internas venían del cajón estrecho: 10 y 10,5 px es tamaño de
   pie de foto, no de cabecera de sección. */
.pf-cuerpo .drawer-sec-tit { font-size: 12px; }
.pf-cuerpo .drawer-sec-n   { font-size: 11.5px; }
.pf-cuerpo .drawer-sec-eur { font-size: 13.5px; }

@media (max-width: 700px) {
  .dep-card-cab { padding: 11px 12px; }
  .dep-card-nom, .dep-card-eur { font-size: 13.5px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   EQUIPMENT · los dos paneles

   El catálogo a la izquierda y el material del proyecto a la derecha, a la
   vista los dos a la vez. Con el diálogo de antes, mientras elegías material
   dejabas de ver el que ya habías elegido, que es justo lo que hay que mirar
   para saber si falta algo.
   ═══════════════════════════════════════════════════════════════════════════ */
.eq-2col {
  display: grid;
  grid-template-columns: 340px minmax(0, 1fr);
  gap: 24px;
  align-items: start;
}

/* ── Panel izquierdo: el catálogo ── */
.eq-cat {
  border: 1px solid var(--border); border-radius: 12px;
  background: var(--surface);
  /* Sin `overflow: hidden`: recortaba el desplegable de subproyecto contra el
     borde del panel. Quien tiene que desplazarse es el árbol, y ese lleva su
     propio overflow. */
  /* Se queda a la vista al bajar por el material del proyecto: si se fuera
     hacia arriba, para añadir la línea veinte habría que subir del todo. */
  position: sticky; top: 12px;
}
/* Alto de pantalla menos el margen del sticky: el árbol scrollea por dentro y
   el panel nunca se sale por abajo. */
.ecat { display: flex; flex-direction: column; max-height: calc(100vh - 24px); }
.ecat-cab { padding: 14px 14px 12px; border-bottom: 1px solid var(--border); }
.ecat-tit {
  margin: 0 0 10px; font-size: 12px; font-weight: 650;
  letter-spacing: .05em; text-transform: uppercase; color: var(--text-soft);
}
.ecat-q {
  width: 100%; padding: 9px 12px; font-size: 14px;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--bg-card); color: var(--text);
}
.ecat-q:focus { border-color: var(--accent); outline: none; }

.ecat-cuerpo { flex: 1; overflow-y: auto; padding: 6px; min-height: 220px; }
.ecat-pista { padding: 20px 12px; text-align: center; font-size: 13px; color: var(--text-soft); }

/* La sangría dice de qué cuelga cada cosa. Se lleva en una variable para que
   ramas e ítems compartan la misma escala y no bailen entre sí. */
.ecat-rama, .ecat-item { padding-left: calc(8px + var(--nivel, 0) * 14px); }

.ecat-rama {
  display: grid; grid-template-columns: 14px minmax(0, 1fr) auto;
  align-items: center; gap: 8px;
  width: 100%; padding-top: 9px; padding-bottom: 9px; padding-right: 10px;
  border: 0; border-radius: 7px;
  background: none; color: var(--text);
  font-size: 14px; font-weight: 550; text-align: left; cursor: pointer;
}
.ecat-rama:hover { background: var(--bg-hover); }
.ecat-flecha { font-size: 10px; color: var(--text-soft); }
.ecat-nom { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ecat-n {
  font-size: 11px; color: var(--text-2);
  background: var(--surface-2); border-radius: 999px;
  padding: 1px 7px; font-variant-numeric: tabular-nums;
}

.ecat-item {
  display: grid; grid-template-columns: 18px minmax(0, 1fr) auto;
  align-items: center; gap: 9px;
  padding-top: 8px; padding-bottom: 8px; padding-right: 10px;
  border-radius: 7px; font-size: 13.5px; cursor: pointer;
}
.ecat-item:hover { background: var(--bg-hover); }
.ecat-item.sel   { background: color-mix(in srgb, var(--accent) 12%, transparent); }
.ecat-item-nom { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ecat-item-eur { font-size: 12.5px; color: var(--text-soft); font-variant-numeric: tabular-nums; }
.ecat-estado {
  font-size: 10.5px; padding: 1px 6px; border-radius: 999px;
  background: var(--mo-aviso-bg); color: var(--text);
}

/* ── La barra de añadir, abajo y siempre visible ── */
/* Va arriba, entre el buscador y el árbol. Abajo se quedaba fuera de la
   pantalla —el panel es alto y la ficha empieza a media página—, y para añadir
   había que bajar a buscar el botón. Aquí no se mueve: el árbol scrollea por
   debajo, así que marques lo que marques el botón sigue donde estaba. */
.ecat-anadir {
  padding: 12px 14px;
  border-bottom: 1px solid var(--border);
  background: var(--surface-2);
}
/* Los cuatro campos en dos filas, no en tres. Con «Subproyecto» y «Grupo»
   ocupando el ancho entero, la barra medía 220 px y del árbol solo asomaba la
   primera categoría: el sitio es para el catálogo, que es lo que se mira. */
.ecat-campos {
  display: grid; grid-template-columns: 1fr 1fr; gap: 9px; margin-bottom: 10px;
}
/* El select se queda en su columna aunque el nombre del subproyecto sea largo:
   se recorta con puntos suspensivos en vez de ensanchar la rejilla. */
.ecat-campos select, .ecat-campos input { min-width: 0; }
/* Etiqueta al lado del campo, no encima. Apiladas, las dos filas medían 195 px
   y del árbol solo asomaban dos categorías: en un panel de 340 px la etiqueta
   cabe al lado y se recuperan 55 px para lo que de verdad se mira. */
/* Un hijo de rejilla no baja de su ancho mínimo salvo que se le diga. Sin
   esto, «Subproyecto» + su desplegable pedían 217 px cada columna en un panel
   de 340 y los campos se salían por el lado derecho. */
.ecat-campos > * { min-width: 0; }
.ecat-campos label, .ecat-campos .ecat-campo {
  display: flex; flex-direction: row; align-items: center; gap: 7px;
  font-size: 11.5px; font-weight: 600; color: var(--text-soft);
}
.ecat-campos label > input,
.ecat-campos label > select,
.ecat-campos .ecat-campo > .sel-dd { flex: 1; min-width: 0; }
/* La primera fila la ocupan dos números cortos; la segunda, dos campos largos. */
.ecat-campos .ecat-cant, .ecat-campos .ecat-dias { max-width: 90px; }
.ecat-campos input, .ecat-campos select {
  padding: 7px 9px; font-size: 13.5px;
  border: 1px solid var(--border); border-radius: 7px;
  background: var(--bg-card); color: var(--text);
}
.ecat-campos input:focus, .ecat-campos select:focus { border-color: var(--accent); outline: none; }
.ecat-btn { width: 100%; padding: 11px; font-size: 14px; }
/* Apagada mientras no hay nada marcado: la barra está siempre ahí, pero no
   pide que la pulses hasta que hay algo que añadir. */
.ecat-anadir:not(.activa) .ecat-campos { opacity: 0.6; }

/* ── Panel derecho ── */
.eq-panel-tit {
  margin: 0; font-size: 12px; font-weight: 650;
  letter-spacing: .05em; text-transform: uppercase; color: var(--text-soft);
}
.eq-panel .eq-barra { gap: 14px; }
.eq-panel .eq-link { margin-left: auto; }

/* ── Estrecho: el catálogo pasa arriba, plegado en su propia caja ── */
@media (max-width: 1100px) {
  .eq-2col { grid-template-columns: minmax(0, 1fr); gap: 20px; }
  .eq-cat { position: static; }
  .ecat { max-height: 60vh; }
  .ecat-campos { grid-template-columns: repeat(4, 1fr); }
}


/* ═══════════════════════════════════════════════════════════════════════════
   EQUIPMENT · la tabla se mide contra su panel, no contra la ventana

   Con el catálogo a la izquierda, el panel de la derecha ya no crece con la
   pantalla: en una ventana de 1150 px la tabla se quedaba en 478 y sus ocho
   columnas pedían 770. Se salía por el lado sin que ninguna media query se
   enterara, porque la ventana sí era ancha.

   Una consulta de contenedor pregunta lo que de verdad importa: cuánto sitio
   tiene ESTA tabla.
   ═══════════════════════════════════════════════════════════════════════════ */
.eq-panel { container-type: inline-size; container-name: eqpanel; }

@container eqpanel (max-width: 800px) {
  /* La cabecera se queda. Quitarla dejaba tres cajas de números seguidas sin
     decir cuál era la cantidad, cuáles los días y cuál el precio: no hay forma
     de adivinarlo mirando la fila. Lo que cede el sitio son el código y el
     total de línea —el subtotal del subproyecto ya está en su cabecera—. */
  .eq-cab, .eq-fila {
    grid-template-columns: 30px minmax(110px, 1fr) 60px 60px 84px 34px;
  }
  .eq-cab > :nth-child(2), .eq-fila > :nth-child(2) { display: none; }
  .eq-cab > :nth-child(7), .eq-fila > .eq-total     { display: none; }
  .eq-cab { font-size: 10.5px; padding-bottom: 6px; }
}

/* Más estrecho todavía —el panel bajo el catálogo en una pantalla pequeña—
   el precio por día también se va: cantidad y días son lo que se corrige a
   diario; el precio, casi nunca. Sigue estando en Finanzas. */
@container eqpanel (max-width: 460px) {
  .eq-cab, .eq-fila { grid-template-columns: 28px minmax(90px, 1fr) 56px 56px 32px; }
  .eq-cab > :nth-child(6), .eq-fila > :nth-child(6) { display: none; }
}

/* Dirección que no corresponde a ningún cliente: se dice en la propia pantalla
   de acceso en vez de dejar que alguien pruebe una contraseña que no puede
   funcionar. */
.login-sin-cliente {
  margin-top: 10px; padding: 10px 12px;
  font-size: 13.5px; line-height: 1.5;
  color: var(--text);
  background: var(--mo-aviso-bg);
  border-radius: 8px;
}



/* ═══════════════════════════════════════════════════════════════════════════
   PANTALLA DE ACCESO EN CLARO

   La pantalla de acceso tiene su propia paleta, `--lg-*`, y estaba escrita en
   oscuro sin más. Por eso en modo claro salía partida por la mitad: el
   formulario seguía al tema y el panel de marca no, negro contra blanco.

   Se arregla donde está el problema —la paleta— y no regla a regla. Así el
   logotipo, la retícula y las líneas se recolocan solos, que es lo que pasa
   cuando los colores salen de un sitio y no de veinte.

   El aspecto es el de la página de entrada del landing: papel claro, retícula
   tenue y el rojo solo como acento.
   ═══════════════════════════════════════════════════════════════════════════ */
:root[data-tema="claro"] .login-screen,
:root:not([data-tema="oscuro"]) .login-screen {
  --lg-tinta:  #14161f;
  --lg-tinta2: #4e5566;
  /* Más oscuro que el gris del landing: aquí este tono lleva el NOMBRE DEL
     CLIENTE y el pie, no una volandita decorativa. Con #767d8d daban 3,88:1,
     por debajo de lo legible a 11 px. */
  --lg-tinta3: #5b6273;
  --lg-regla:  rgba(20,22,31,.13);
  --lg-trama:  rgba(20,22,31,.055);
  --lg-sello:  #c8102e;
}

/* El panel de marca era negro fijo. Ahora es el papel del tema. */
:root[data-tema="claro"] .login-marca,
:root:not([data-tema="oscuro"]) .login-marca { background: var(--bg); }

/* Estos dos están calculados para el negro: sobre papel, el resplandor rojo
   mancha y el barniz blanco no se ve. */
:root[data-tema="claro"] .login-marca::before,
:root:not([data-tema="oscuro"]) .login-marca::before { opacity: .3; }
:root[data-tema="claro"] .login-marca::after,
:root:not([data-tema="oscuro"]) .login-marca::after { display: none; }

/* El logotipo del pie y la palmera son PNG negros que se invertían para verse
   sobre el fondo oscuro. Sobre papel se dejan como son. */
:root[data-tema="claro"] .login-marca-pie-ico,
:root:not([data-tema="oscuro"]) .login-marca-pie-ico { filter: none; opacity: .55; }
:root[data-tema="claro"] .login-marca-palma img,
:root:not([data-tema="oscuro"]) .login-marca-palma img { filter: none; }
:root[data-tema="claro"] .login-marca-palma,
:root:not([data-tema="oscuro"]) .login-marca-palma { opacity: .05; }

/* Los textos del panel llevaban el blanco escrito a mano, no la paleta. */
:root[data-tema="claro"] .login-marca-tit,
:root:not([data-tema="oscuro"]) .login-marca-tit { color: var(--lg-tinta); }
:root[data-tema="claro"] .login-marca-eyebrow,
:root:not([data-tema="oscuro"]) .login-marca-eyebrow { color: var(--lg-tinta3); }
:root[data-tema="claro"] .login-marca-txt,
:root:not([data-tema="oscuro"]) .login-marca-txt { color: var(--lg-tinta2); }
:root[data-tema="claro"] .login-marca-pie,
:root:not([data-tema="oscuro"]) .login-marca-pie { color: var(--lg-tinta3); }

/* Con los dos lados claros hace falta una línea que los separe: sin ella el
   formulario parecía flotar sin sitio propio. */
:root[data-tema="claro"] .login-panel,
:root:not([data-tema="oscuro"]) .login-panel { border-left: 1px solid var(--lg-regla); }

/* ═══════════════════════════════════════════════════════════════════════════
   PROYECTO · SELECTOR DE SUBPROYECTO

   Va junto al nombre del proyecto porque es parte de dónde estás, no un filtro
   más. Cuando hay uno elegido cambia de aspecto: tiene que verse de un vistazo
   que lo que estás mirando NO es el proyecto entero.
   ═══════════════════════════════════════════════════════════════════════════ */
.sub-sel { position: relative; display: inline-flex; }

.sub-sel-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 9px;
  font-family: inherit; font-size: 12.5px; font-weight: 600;
  color: var(--text-soft);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 999px;
  cursor: pointer;
}
.sub-sel-btn:hover { color: var(--text); border-color: var(--text-soft); }
/* Dentro de un subproyecto: el botón deja de ser un control gris y pasa a ser
   una etiqueta con color, porque ya no dice "elige" sino "estás aquí". */
.sub-sel-btn.en-sub {
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
}

.sub-menu {
  position: absolute; top: calc(100% + 7px); left: 0; z-index: 30;
  min-width: 268px; max-height: 62vh; overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 8px 28px rgba(0,0,0,.16);
  padding: 6px;
}
.sub-menu-cab {
  padding: 7px 10px 8px;
  font-size: 10.5px; font-weight: 650; letter-spacing: .06em;
  text-transform: uppercase; color: var(--text-soft);
}
.sub-op {
  display: flex; flex-direction: column; gap: 2px;
  width: 100%; padding: 9px 10px;
  text-align: left; font-family: inherit;
  background: none; border: 0; border-radius: 7px;
  color: var(--text); cursor: pointer;
}
.sub-op:hover { background: var(--bg-hover); }
.sub-op.activa { background: color-mix(in srgb, var(--accent) 12%, transparent); }
.sub-op-nom { font-size: 14px; font-weight: 550; }
.sub-op-eti { font-size: 11.5px; color: var(--text-soft); }
.sub-op.activa .sub-op-nom { color: var(--accent); }
/* La opción de «ver todo junto» se separa de la lista de subproyectos: puesta
   igual que ellos parecía una caja hermana, y entonces ver el mismo material en
   las dos no tiene sentido. Separada y con su rótulo, se lee como lo que es —un
   resumen de las de abajo— y deja de chirriar. */
.sub-op-todo { border-bottom: 1px solid var(--border); }
.sub-menu-cab + .sub-op-todo { border-bottom: none; }
.sub-op-todo + .sub-menu-cab { margin-top: 4px; border-top: 1px solid var(--border); padding-top: 10px; }

.sub-menu-pie { margin-top: 4px; padding-top: 6px; border-top: 1px solid var(--border); }
.sub-gestionar {
  width: 100%; padding: 8px 10px;
  text-align: left; font-family: inherit; font-size: 13px;
  background: none; border: 0; border-radius: 7px;
  color: var(--text-soft); cursor: pointer;
}
.sub-gestionar:hover { background: var(--bg-hover); color: var(--text); }

/* ═══════════════════════════════════════════════════════════════════════════
   BARRA LATERAL · que siga al tema, y que la selección sea un bloque

   Estaba fijada en negro con el tema en claro, y el contraste contra una
   aplicación blanca era demasiado: un tajo negro pegado al contenido. Ahora
   sigue al tema, como todo lo demás.

   Y la selección deja de ser una pastilla flotando con aire a los lados: pasa
   a tocar el borde derecho, de modo que el elemento activo y el contenido de
   la derecha se leen como una sola pieza en lugar de dos cosas separadas por
   una franja oscura.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── En claro ── */
:root[data-tema="claro"] .sidebar,
:root:not([data-tema="oscuro"]) .sidebar {
  background: var(--surface-2);
  box-shadow: inset -1px 0 0 var(--border);
  color: var(--text);
}
:root[data-tema="claro"] .sidebar .nav-item,
:root:not([data-tema="oscuro"]) .sidebar .nav-item { color: var(--text-2); }
:root[data-tema="claro"] .sidebar .nav-item:hover,
:root:not([data-tema="oscuro"]) .sidebar .nav-item:hover { color: var(--text); }
:root[data-tema="claro"] .sidebar .nav-group-head,
:root:not([data-tema="oscuro"]) .sidebar .nav-group-head { color: var(--text-soft); }
:root[data-tema="claro"] .sidebar .logo-title,
:root:not([data-tema="oscuro"]) .sidebar .logo-title { color: var(--text); }
:root[data-tema="claro"] .sidebar .logo-sub,
:root:not([data-tema="oscuro"]) .sidebar .logo-sub { color: var(--text-soft); }
:root[data-tema="claro"] .sidebar .sidebar-user-text,
:root:not([data-tema="oscuro"]) .sidebar .sidebar-user-text { color: var(--text-2); }

/* En claro la selección tiene que ser OSCURA para destacar sobre el papel;
   en oscuro es clara. En los dos casos es el mismo gesto: el bloque contrario
   al fondo. */
:root[data-tema="claro"] .sidebar .nav-item.active,
:root[data-tema="claro"] .sidebar .nav-group-items .nav-item.active,
:root:not([data-tema="oscuro"]) .sidebar .nav-item.active,
:root:not([data-tema="oscuro"]) .sidebar .nav-group-items .nav-item.active {
  background: var(--text);
  color: var(--surface);
}
:root[data-tema="claro"] .sidebar .nav-item.active:hover,
:root:not([data-tema="oscuro"]) .sidebar .nav-item.active:hover {
  background: var(--text); color: var(--surface);
}
:root[data-tema="claro"] .sidebar .nav-item.active svg,
:root:not([data-tema="oscuro"]) .sidebar .nav-item.active svg { color: var(--surface); }

/* ── La selección, pegada al borde ────────────────────────────────────────────
   Tenía 2 px de margen a cada lado, así que quedaba una franja del fondo de la
   barra entre el bloque y el contenido.

   El relleno derecho y el redondeo que llevaba aquí se han quitado: los
   sustituyó la capa de abajo, que lo deja todo cuadrado, y encima descentraban
   el icono 7 px con la barra plegada. */
.sidebar .nav-item.active,
.sidebar .nav-group-items .nav-item.active {
  margin-inline: 0 0;
}

/* ── El logo ──────────────────────────────────────────────────────────────────
   Blanco apagado en reposo y blanco entero al pulsar: el logotipo es también
   el botón de inicio, y tiene que responder como tal. */
.sidebar .sidebar-logo .logo-mark svg,
.sidebar .sidebar-logo svg.logo,
.sidebar .logo-icon svg {
  color: #fff; opacity: .72;
  transition: opacity .15s;
}
.sidebar .sidebar-logo:hover .logo-mark svg,
.sidebar .sidebar-logo:hover svg.logo,
.sidebar .sidebar-logo:hover .logo-icon svg { opacity: 1; }
.sidebar .sidebar-logo:active .logo-mark svg,
.sidebar .sidebar-logo:active svg.logo,
.sidebar .sidebar-logo:active .logo-icon svg { opacity: 1; }
/* En claro el blanco desaparece: el logotipo toma la tinta del tema. */
:root[data-tema="claro"] .sidebar .sidebar-logo svg,
:root:not([data-tema="oscuro"]) .sidebar .sidebar-logo svg { color: var(--text); }

/* ── La foto del usuario, sin caja ────────────────────────────────────────────
   Tenía un recuadro alrededor que no aportaba nada: la foto ya es un objeto
   con forma propia y el borde solo añadía una línea que contar. */
.sidebar .sidebar-user,
.sidebar .sidebar-user-info {
  border: 0; background: none; box-shadow: none;
}
.sidebar .sidebar-avatar {
  border: 0; box-shadow: none; background: none;
}

/* ═══════════════════════════════════════════════════════════════════════════
   SELECTOR DE SUBPROYECTO · que se vea

   Era una píldora gris pequeña entre las demás etiquetas de la cabecera, y ahí
   se perdía. Es el control que más se usa de la ficha —cambia lo que estás
   mirando— así que tiene que pesar más que el estado o las fechas que lleva al
   lado.
   ═══════════════════════════════════════════════════════════════════════════ */
.sub-sel { margin-right: 4px; }

.sub-sel-btn {
  gap: 8px;
  padding: 7px 14px;
  font-size: 13.5px; font-weight: 650;
  letter-spacing: -.005em;
  border-radius: 8px;
  border: 1px solid var(--accent);
  background: var(--accent);
  color: #fff;
  box-shadow: 0 1px 2px rgba(0,0,0,.10);
}
.sub-sel-btn:hover {
  color: #fff;
  filter: brightness(1.08);
  border-color: var(--accent);
}
.sub-sel-btn svg { opacity: .85; }

/* Dentro de un subproyecto se le añade el nombre del departamento delante, en
   letra pequeña, para que se lea "estás dentro de ESTO" y no solo el nombre
   suelto, que podría confundirse con el del proyecto. */
.sub-sel-btn.en-sub {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.sub-sel-btn.en-sub::before {
  content: '';
  width: 6px; height: 6px; border-radius: 50%;
  background: #fff; opacity: .9; flex: none;
}

/* El menú, más ancho y con más aire: es una lista para elegir, no un submenú
   apretado. */
.sub-menu { min-width: 300px; padding: 7px; }
.sub-op { padding: 10px 12px; }
.sub-op-nom { font-size: 14.5px; }

/* Los que se quedaron con el blanco escrito a mano. Se localizaron recorriendo
   la barra en claro y midiendo qué texto salía casi blanco sobre papel: el
   nombre del usuario, cerrar sesión y el botón de plegar. */
:root[data-tema="claro"] .sidebar .sidebar-user-name,
:root:not([data-tema="oscuro"]) .sidebar .sidebar-user-name { color: var(--text); }
:root[data-tema="claro"] .sidebar .sidebar-salir,
:root[data-tema="claro"] .sidebar .sidebar-salir .nav-label,
:root:not([data-tema="oscuro"]) .sidebar .sidebar-salir,
:root:not([data-tema="oscuro"]) .sidebar .sidebar-salir .nav-label { color: var(--text-2); }
:root[data-tema="claro"] .sidebar .sidebar-salir:hover,
:root:not([data-tema="oscuro"]) .sidebar .sidebar-salir:hover { color: var(--red); }
:root[data-tema="claro"] .sidebar .sidebar-collapse-btn,
:root:not([data-tema="oscuro"]) .sidebar .sidebar-collapse-btn { color: var(--text-soft); }
:root[data-tema="claro"] .sidebar .sidebar-collapse-btn:hover,
:root:not([data-tema="oscuro"]) .sidebar .sidebar-collapse-btn:hover { color: var(--text); }

/* El texto de cada enlace vive en un `.nav-label` dentro del `.nav-item`, con
   su propio color. Pintar solo el contenedor dejaba las etiquetas en blanco
   sobre papel — las 23 del menú. */
:root[data-tema="claro"] .sidebar .nav-label,
:root:not([data-tema="oscuro"]) .sidebar .nav-label { color: var(--text-2); }
:root[data-tema="claro"] .sidebar .nav-item:hover .nav-label,
:root:not([data-tema="oscuro"]) .sidebar .nav-item:hover .nav-label { color: var(--text); }
:root[data-tema="claro"] .sidebar .nav-group-nombre,
:root:not([data-tema="oscuro"]) .sidebar .nav-group-nombre { color: var(--text-soft); }
:root[data-tema="claro"] .sidebar .nav-item.active .nav-label,
:root:not([data-tema="oscuro"]) .sidebar .nav-item.active .nav-label { color: var(--surface); }

/* ═══════════════════════════════════════════════════════════════════════════
   BARRA LATERAL · más tranquila

   Tres cosas que chirriaban:

   · Los grupos tenían el fondo oscurecido un 16%, así que "Material" o
     "Tecnología" se leían como bandejas dentro de la barra. La sangría ya dice
     que son de segundo nivel; el fondo repetía lo mismo con más ruido.

   · El elemento activo era un bloque casi negro sobre papel claro. Tanto
     contraste no se lee como "estás aquí" sino como algo roto.

   · Y redondeaba por la izquierda, que dejaba un mordisco raro.

   Ahora el activo es del MISMO color que la página que abre, cuadrado y
   pegado al borde: se lee como que la pestaña y el contenido son la misma
   pieza, que es exactamente lo que son.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Fuera el fondo de los grupos, en los dos temas. */
.sidebar .nav-group-items { background: none; }

/* Todo cuadrado. */
.sidebar .nav-item,
.sidebar .nav-item.active,
.sidebar .nav-group-items .nav-item.active { border-radius: 0; }

/* El activo, del color del contenido. Sin bordes redondeados y llegando al
   borde derecho, de modo que no hay línea que separe la barra de la página. */
.sidebar .nav-item.active,
.sidebar .nav-group-items .nav-item.active,
:root[data-tema="claro"] .sidebar .nav-item.active,
:root[data-tema="claro"] .sidebar .nav-group-items .nav-item.active,
:root:not([data-tema="oscuro"]) .sidebar .nav-item.active,
:root:not([data-tema="oscuro"]) .sidebar .nav-group-items .nav-item.active {
  background: var(--surface);
  color: var(--text);
  font-weight: 600;
  margin-inline: 0;
  border-radius: 0;
}
.sidebar .nav-item.active:hover,
.sidebar .nav-group-items .nav-item.active:hover,
:root[data-tema="claro"] .sidebar .nav-item.active:hover,
:root:not([data-tema="oscuro"]) .sidebar .nav-item.active:hover {
  background: var(--surface);
  color: var(--text);
}
.sidebar .nav-item.active svg,
:root[data-tema="claro"] .sidebar .nav-item.active svg,
:root:not([data-tema="oscuro"]) .sidebar .nav-item.active svg { color: var(--text); opacity: .85; }
.sidebar .nav-item.active .nav-label,
:root[data-tema="claro"] .sidebar .nav-item.active .nav-label,
:root:not([data-tema="oscuro"]) .sidebar .nav-item.active .nav-label { color: var(--text); }

/* Una marca fina de acento a la izquierda: es lo que dice "aquí" sin gritar.
   El color lo pone el acento, no el contraste. */
.sidebar .nav-item.active { box-shadow: inset 3px 0 0 var(--accent); }

/* ═══════════════════════════════════════════════════════════════════════════
   QUE SE LEA SIN ESFORZARSE

   Medido: en la pantalla de proyectos había texto a 9, 9,5, 10 y 10,5 px.
   A ese tamaño una etiqueta no se lee, se adivina — y quien lleva gafas para
   cerca directamente no la ve. Esto no es una cuestión de gusto: es gente
   trabajando ocho horas contra esta pantalla.

   Se sube el suelo de toda la aplicación en torno a un punto y medio. Los
   tamaños se mantienen en escala entre sí, así que la jerarquía no cambia:
   lo que era pequeño sigue siendo lo más pequeño, pero ya se lee.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Etiquetas en versalitas, que eran las peores: de 9-10 px a 11. */
.proy-cal-etq-est,
.proy-dash-label,
.proy-recientes-titulo,
.gantt-leg-lbl,
.proy-mini-dato,
.proy-mini-badge,
.proy-rail-n,
.section-title { font-size: 11px; }

/* Las de 10,5: metadatos y contadores. */
.proy-tab-n,
.proy-cal-barra-txt,
.proy-mini-meta,
.badge,
.pf-sec-n,
.fichas-contador { font-size: 11.5px; }

/* Texto de apoyo: de 11,5-12 a 13. */
.proy-pista,
.pf-sec-ayuda,
.pcm-sub,
.pk-cab-n,
.dash-personalizar { font-size: 13px; }

/* Y lo que de verdad se lee: nombres, datos, pestañas. */
.proy-mini-nombre,
.proy-rail-nom,
.proy-cal-etq-nom,
.tab-tit,
.pf-volver { font-size: 13.5px; }
.proy-tab,
.page-subtitle { font-size: 14px; }

/* ── Últimos proyectos, en el panel ──────────────────────────────────────────
   Es lo primero que mira todo el mundo al entrar, así que es lo que más
   merece el sitio. */
.proy-recientes-titulo { font-size: 11.5px; letter-spacing: .06em; }
.proy-mini { padding: 14px 16px; }
.proy-mini-nombre { font-size: 15px; font-weight: 600; }
.proy-mini-meta { font-size: 12.5px; }
.proy-mini-dato { font-size: 12px; }

/* ── La lista de proyectos ── */
.proy-fila { font-size: 14.5px; }
.proy-fila td { padding-top: 13px; padding-bottom: 13px; }
.proy-rail-item { padding: 11px 12px; }
.proy-rail-nom { font-size: 14px; font-weight: 550; }

/* Los títulos de página, con más presencia: son el "dónde estoy". */
.page-title { font-size: 29px; }

/* Lo que faltaba, y era el grueso: 125 etiquetas de formulario y 75 cabeceras
   de tabla a 10 px. No son adorno —dicen qué se escribe en cada casilla y qué
   hay en cada columna— y a ese tamaño hay que acercarse a la pantalla para
   leerlas. */
.form-group > label,
label.form-label,
.filtros label,
.modal label { font-size: 12px; letter-spacing: .04em; }
/* `.tabla th` (0,1,1) le gana a un `th` a secas (0,0,1), así que hay que
   nombrar la tabla. Es el motivo de que las 75 cabeceras siguieran a 10 px
   después del primer intento. */
.tabla th, table th, .th-orden { font-size: 11.5px; letter-spacing: .05em; }
/* Y los sueltos de dentro de las fichas. */
.pres-dato span, .contactos-cab span, .proy-cal-mes small { font-size: 11.5px; }

/* Los pocos que quedaban sueltos. */
.proy-cal-barra-txt, .proy-rail-meta, .vf-bloque-tit,
.usr-bloque-tit, .proy-chip, small { font-size: 11.5px; }

/* ═══════════════════════════════════════════════════════════════════════════
   BARRA LATERAL PLEGADA · todo centrado

   Con la barra plegada solo se ven iconos, así que basta un par de píxeles de
   desvío para que la columna se vea torcida. Medido: el elemento activo salía
   7 px a la izquierda por el relleno derecho que se le puso para que llegara
   al borde —relleno que plegada no pinta nada— y la foto del usuario 4.

   En vez de corregir uno a uno, plegada se centra TODO: así lo que se añada
   mañana nace centrado sin que nadie se acuerde.
   ═══════════════════════════════════════════════════════════════════════════ */
/* OJO: aquí NO va `.nav-group-head`. Estaba oculta al plegar, y meterla en
   esta lista con `display: flex` la volvía a enseñar: salían las cabeceras de
   grupo con su icono y su flechita entre los iconos de navegación, que es lo
   que hacía que la barra plegada pareciera una lista de iconos sueltos. */
.sidebar.collapsed .nav-item,
.sidebar.collapsed .sidebar-logo,
.sidebar.collapsed .sidebar-user,
.sidebar.collapsed .sidebar-user-info,
.sidebar.collapsed .sidebar-salir {
  display: flex;
  align-items: center;
  justify-content: center;
  padding-left: 0;
  padding-right: 0;
  gap: 0;
  text-align: center;
}
/* El icono, sin margen: cualquier margen lateral lo descentra. */
.sidebar.collapsed .nav-item .nav-icon,
.sidebar.collapsed .sidebar-logo svg,
.sidebar.collapsed .sidebar-avatar,
.sidebar.collapsed .sidebar-salir svg { margin: 0; }

/* La marca del elemento activo sigue a la izquierda, pero el icono ya no se
   mueve por ella. */
.sidebar.collapsed .nav-item.active { box-shadow: inset 3px 0 0 var(--accent); }

/* El botón de plegar, centrado también: plegada es el único modo de volver. */
.sidebar.collapsed .sidebar-collapse-btn { margin: 0 auto; }

/* El logotipo del pie de la pantalla de acceso, alineado con su texto.

   `.login-logo` lleva `margin-bottom: 22px`, que es para el logo de la
   cabecera del formulario —donde separa del título— pero se aplicaba también
   al del pie. En un contenedor centrado, ese margen forma parte de la caja:
   centrarla subía el logo 11 px respecto al texto de al lado. */
.login-marca-pie .login-logo { margin-bottom: 0; }

/* ═══════════════════════════════════════════════════════════════════════════
   FORMULARIOS · que no parezcan de hace veinte años

   Lo que fallaba, medido: etiquetas a 10,5 px en versalitas apretadas, campos
   de 34 px de alto con 8 px de relleno, y bordes al mismo peso que el texto.
   El resultado es el aspecto de formulario de intranet antigua: todo pequeño,
   todo gritando en mayúsculas, y los campos sin sitio para respirar.

   Los cambios, y por qué:

   · La etiqueta deja las versalitas. Escribir "NOMBRE DE LA EMPRESA" en
     mayúsculas a 10,5 px es el doble de difícil de leer que "Nombre de la
     empresa" a 13: las mayúsculas quitan la silueta de la palabra, que es por
     donde se reconoce sin deletrear.
   · El campo pasa de 34 a 44 px de alto. Es lo que mide un botón, y es lo que
     hace que se pueda pulsar sin apuntar.
   · El borde se afina y el fondo se aclara: el campo se distingue por su
     hueco, no por el marco. Al enfocarlo se marca con el color de acento, que
     es cuando de verdad hace falta señalar dónde estás escribiendo.
   ═══════════════════════════════════════════════════════════════════════════ */

.form-group { gap: 7px; }

.form-group > label,
.form-group > .form-label {
  font-size: 13px; font-weight: 550;
  text-transform: none; letter-spacing: 0;
  color: var(--text-2);
}

.form-group input,
.form-group select,
.form-group textarea,
input.form-control,
select.form-control,
textarea.form-control {
  min-height: 44px;
  padding: 11px 13px;
  font-size: 15px;
  line-height: 1.4;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text);
  transition: border-color .15s, box-shadow .15s, background .15s;
}
.form-group textarea, textarea.form-control { min-height: 96px; line-height: 1.55; }

.form-group input::placeholder,
.form-group textarea::placeholder,
.form-control::placeholder { color: var(--text-soft); }

.form-group input:hover,
.form-group select:hover,
.form-group textarea:hover,
.form-control:hover { border-color: var(--border-med); }

.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus,
.form-control:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 16%, transparent);
  background: var(--surface);
}

/* Un campo obligatorio sin rellenar se marca solo cuando ya lo has tocado y
   lo has dejado vacío. Marcarlo antes es regañar por algo que aún no ha
   pasado. */
.form-group input:required:invalid:not(:placeholder-shown) {
  border-color: var(--red);
}

/* Las rejillas de formulario, con más aire entre campos. */
.form-grid, .form-row, .modal .form-grid { gap: 18px 20px; }

/* Y los grupos de campos con su título, que es lo que convierte una lista de
   casillas en un formulario legible. */
.form-seccion-tit {
  font-size: 12px; font-weight: 650; letter-spacing: .06em;
  text-transform: uppercase; color: var(--text-soft);
  margin: 6px 0 2px;
}

/* ═══════════════════════════════════════════════════════════════════════════
   BOTONES, ETIQUETAS Y CHIPS · el resto de la letra pequeña

   Medido en vehículos, inventario, IT Stock, telefonía, MiFis y presupuestos:
   lo que quedaba por debajo de 12 px eran siempre los mismos tres —los
   botones, las etiquetas de estado y los chips de categoría—, repetidos
   cientos de veces por pantalla.

   Un botón no es un adorno: es lo que hay que leer para saber qué va a pasar
   al pulsarlo. Y una etiqueta de estado —"disponible", "de baja", "en
   mantenimiento"— es el dato más consultado de una lista de material.
   ═══════════════════════════════════════════════════════════════════════════ */
.btn { font-size: 13.5px; }
.btn-sm { font-size: 12.5px; }
.btn-lg { font-size: 15px; }

.badge { font-size: 11.5px; padding: 3px 9px; }
.cat-chip { font-size: 12px; }

/* Los datos de las fichas y las tablas de estas pantallas. */
.tabla td, .tabla-fila { font-size: 14px; }
.tabla td { padding-top: 12px; padding-bottom: 12px; }
.dato-valor, .item-nombre, .veh-nombre, .inv-nombre { font-size: 14.5px; }
em { font-size: inherit; }

/* Las tarjetas de vehículo y de material, con más aire: se miran a diario. */
.veh-card, .inv-card, .it-card { padding: 16px 18px; }

/* ═══════════════════════════════════════════════════════════════════════════
   AJUSTES · dos paneles

   Menú de secciones a la izquierda, una sola cosa a la vez a la derecha. El
   menú se queda a la vista al bajar por una sección larga: si se fuera hacia
   arriba, cambiar de sección obligaría a volver al principio.
   ═══════════════════════════════════════════════════════════════════════════ */
.ajn {
  display: grid;
  grid-template-columns: 236px minmax(0, 1fr);
  gap: 28px;
  align-items: start;
}

.ajn-menu {
  position: sticky; top: 12px;
  display: flex; flex-direction: column; gap: 22px;
  padding-right: 4px;
}
.ajn-grupo { display: flex; flex-direction: column; gap: 1px; }
.ajn-grupo-tit {
  padding: 0 10px 8px;
  font-size: 11px; font-weight: 650; letter-spacing: .07em;
  text-transform: uppercase; color: var(--text-soft);
}
.ajn-op {
  padding: 9px 12px;
  text-align: left; font-family: inherit; font-size: 14px;
  background: none; border: 0; border-radius: 7px;
  color: var(--text-2); cursor: pointer;
}
.ajn-op:hover { background: var(--bg-hover); color: var(--text); }
/* La sección abierta se marca con el acento a la izquierda, igual que la
   navegación principal: dos menús que señalan igual se aprenden una vez. */
.ajn-op.activa {
  background: var(--surface-2);
  color: var(--text);
  font-weight: 600;
  box-shadow: inset 3px 0 0 var(--accent);
}

/* El panel: la sección ya no necesita separarse de las de al lado, porque no
   hay ninguna al lado. */
.ajn-panel > .aj-seccion { border: 0; padding: 0; margin: 0; }
.ajn-panel > .aj-seccion .aj-tit {
  font-size: 20px; font-weight: 650; letter-spacing: -.02em;
  text-transform: none; color: var(--text);
  padding-bottom: 14px; margin-bottom: 20px;
  border-bottom: 1px solid var(--border);
}

@media (max-width: 900px) {
  .ajn { grid-template-columns: minmax(0, 1fr); gap: 18px; }
  .ajn-menu {
    position: static; flex-direction: row; flex-wrap: wrap; gap: 8px;
  }
  .ajn-grupo { flex-direction: row; flex-wrap: wrap; gap: 4px; }
  .ajn-grupo-tit { width: 100%; padding-bottom: 2px; }
}

/* AQUÍ ESTABA la capa que subía un punto toda la barra lateral. Fuera: al
   verla montada, más grande no era mejor —ocupaba sitio sin ganar nada—.
   Vuelve a los tamaños de la capa anterior. */

/* ═══════════════════════════════════════════════════════════════════════════
   BARRA PLEGADA · una columna de iconos con ritmo

   Plegada solo hay iconos, así que lo único que la ordena es el espacio: si
   los huecos son irregulares, se lee como una pila de cosas sueltas en vez de
   como un menú.

   Los grupos ya no ponen su título —no cabe— pero siguen existiendo, así que
   se marcan con una raya fina. Es lo justo para que se vea que "Vehículos" y
   "Revisiones" van juntos y "Inventario" es otra cosa.
   ═══════════════════════════════════════════════════════════════════════════ */
.sidebar.collapsed .nav-group-head { display: none !important; }

.sidebar.collapsed { --sb-icono: 40px; }

/* Mismo alto para todo lo que se pulsa, arriba y dentro de los grupos: es lo
   que da la cuadrícula. */
.sidebar.collapsed .nav-item,
.sidebar.collapsed .nav-group-items .nav-item {
  height: var(--sb-icono);
  width: var(--sb-icono);
  margin: 0 auto;
  padding: 0;
  border-radius: 9px;
}
.sidebar.collapsed .nav-group-items { gap: 4px; padding: 0; margin: 0; }
.sidebar.collapsed .nav-menu { gap: 4px; }

/* La raya entre grupos, dentro del hueco y no encima de un icono. */
.sidebar.collapsed .nav-group + .nav-group {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}

/* El seleccionado, plegada, es un cuadrado relleno y no una franja al borde:
   con 40 px de ancho una franja no se lee, se ve como un defecto. */
.sidebar.collapsed .nav-item.active,
.sidebar.collapsed .nav-group-items .nav-item.active {
  background: var(--accent);
  box-shadow: none;
  border-radius: 9px;
}
.sidebar.collapsed .nav-item.active svg,
.sidebar.collapsed .nav-item.active .nav-icon svg { color: #fff; opacity: 1; }

/* El logotipo y el pie, con el mismo aire que los iconos. */
.sidebar.collapsed .sidebar-logo { height: 52px; margin-bottom: 8px; }
.sidebar.collapsed .sidebar-user { padding: 12px 0; }
.sidebar.collapsed .sidebar-salir { height: var(--sb-icono); }
.sidebar.collapsed .sidebar-avatar { width: 28px; height: 28px; }

/* El contador de un icono no cabe al lado: se pone encima, como una chincheta. */
.sidebar.collapsed .nav-badge {
  position: absolute; top: 3px; right: 3px;
  min-width: 16px; height: 16px; padding: 0 4px;
  font-size: 10px; line-height: 16px; border-radius: 999px;
}
.sidebar.collapsed .nav-item { position: relative; }

/* ═══════════════════════════════════════════════════════════════════════════
   BARRA LATERAL AJUSTABLE                                    (prefijo `.sb-ras`)

   El ancho lo fijaba yo a 264 px y no había forma de discutirlo. Pero el ancho
   bueno depende de la pantalla y de quién mira: en un portátil roba sitio a las
   tablas, y a quien le cuesta leer le viene bien más.

   El tirador es una franja de 6 px en el borde derecho. Invisible hasta que se
   acerca el ratón, porque un separador siempre visible parte la barra en dos y
   se lee como un borde que no pinta nada. Al pasar por encima aparece una línea
   fina; al arrastrar, la línea se enciende.

   Plegada no se puede arrastrar: plegada el ancho es el del icono, no una
   preferencia.
   ═══════════════════════════════════════════════════════════════════════════ */
.sb-ras {
  position: absolute;
  top: 0; right: 0; bottom: 0;
  width: 6px;
  cursor: col-resize;
  z-index: 40;
  background: transparent;
  transition: background 0.12s;
}
.sb-ras::after {
  content: '';
  position: absolute;
  top: 0; bottom: 0; right: 0;
  width: 2px;
  background: var(--accent);
  opacity: 0;
  transition: opacity 0.12s;
}
.sb-ras:hover::after      { opacity: 0.45; }
.sb-ras:focus-visible::after,
body.sb-ajustando .sb-ras::after { opacity: 1; }
.sb-ras:focus-visible { outline: none; }

.sidebar.collapsed .sb-ras { display: none; }

/* Mientras se arrastra: el cursor no cambia al salirse de la franja, no se
   selecciona texto sin querer, y la barra no "persigue" al ratón con la
   animación de plegado —que existe para el plegado, no para esto—. */
body.sb-ajustando { cursor: col-resize; user-select: none; }
body.sb-ajustando .sidebar { transition: none; }

/* El nombre del cliente al estrechar la barra: se cortaba a hueso —"Palma
   Pictur"— porque no lo recortaba él, sino la barra por encima. Sin puntos
   suspensivos eso no se lee como "no cabe", se lee como que falta texto.
   Con nombres de cliente más largos que "Palma Pictures" pasaría siempre. */
.sidebar .logo-text { min-width: 0; }
.sidebar .logo-title,
.sidebar .logo-sub {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ═══════════════════════════════════════════════════════════════════════════
   FICHAS QR · navegador de material                          (prefijo `.fqr`)

   Tres columnas: categorías, disponible, y lo que se va a imprimir. Mismas
   proporciones que el navegador de presupuestos, para que se reconozca.

   Altura fija de 380 px y cada columna con su propio desplazamiento. Si se
   dejara crecer, elegir 40 etiquetas alargaría la página metros y el paso 3
   —el formato de la hoja— acabaría fuera de la pantalla.
   ═══════════════════════════════════════════════════════════════════════════ */
.fqr {
  display: grid;
  grid-template-columns: 226px minmax(0, 1fr) 268px;
  gap: 14px;
  height: 380px;
  margin-top: 14px;
}
.fqr.sin-arbol { grid-template-columns: minmax(0, 1fr) 268px; }
.fqr-arbol, .fqr-centro, .fqr-derecha {
  display: flex;
  flex-direction: column;
  min-height: 0;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-card);
  overflow: hidden;
}
.fqr-panel-tit {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-soft);
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.fqr-pill {
  background: var(--accent);
  color: #fff;
  border-radius: 20px;
  padding: 1px 8px;
  font-size: 11.5px;
  letter-spacing: 0;
}
.fqr-vaciar {
  margin-left: auto;
  background: none;
  border: 0;
  color: var(--text-soft);
  font: inherit;
  font-size: 11.5px;
  letter-spacing: 0;
  text-transform: none;
  cursor: pointer;
  padding: 2px 4px;
}
.fqr-vaciar:hover:not(:disabled) { color: var(--red); }
.fqr-vaciar:disabled { opacity: 0.35; cursor: default; }

.fqr-arbol-lista, .fqr-lista, .fqr-elegidas { overflow-y: auto; flex: 1; padding: 6px; }

/* Barra de búsqueda del panel central */
.fqr-barra {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.fqr-busca { flex: 1; min-width: 0; height: 34px; font-size: 13.5px; }
.fqr-info { font-size: 12px; color: var(--text-soft); white-space: nowrap; }

/* Una fila de material. Es un botón entero, no una casilla de 13 px: el objetivo
   que hay que acertar con el ratón es la fila completa. */
.fqr-item {
  display: grid;
  grid-template-columns: 62px minmax(0, 1fr) 22px;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 10px;
  background: none;
  border: 0;
  border-radius: 6px;
  cursor: pointer;
  text-align: left;
  font: inherit;
  color: var(--text);
}
.fqr-item:hover:not(:disabled) { background: var(--bg-hover); }
.fqr-item-cod {
  font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: 12px;
  color: var(--text-soft);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.fqr-item-nom {
  font-size: 13.5px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.fqr-item-mas {
  font-size: 15px;
  font-weight: 600;
  color: var(--accent);
  text-align: center;
}
.fqr-item.puesto { opacity: 0.45; cursor: default; }
.fqr-item.puesto .fqr-item-mas { color: var(--green, #2e9e5b); }

/* Lo elegido. Va con marca de color a la izquierda para que se lea de un
   vistazo cuántas etiquetas llevas sin tener que contarlas. */
.fqr-eleg {
  display: grid;
  grid-template-columns: 54px minmax(0, 1fr) 22px;
  align-items: center;
  gap: 8px;
  padding: 7px 8px 7px 10px;
  border-radius: 6px;
  border-left: 3px solid var(--accent);
  background: var(--bg-hover);
  margin-bottom: 4px;
}
.fqr-eleg-cod {
  font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: 11.5px;
  color: var(--text-soft);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.fqr-eleg-nom { font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fqr-eleg-x {
  background: none;
  border: 0;
  color: var(--text-soft);
  cursor: pointer;
  padding: 2px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
}
.fqr-eleg-x:hover { color: var(--red); background: var(--bg-card); }

.fqr-vacio {
  padding: 24px 16px;
  text-align: center;
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-soft);
}

/* Pantallas estrechas: el árbol y lo elegido se apilan bajo el material, que
   es lo que más sitio necesita. */
@media (max-width: 1120px) {
  .fqr, .fqr.sin-arbol { grid-template-columns: minmax(0, 1fr); height: auto; }
  .fqr-arbol-lista { max-height: 200px; }
  .fqr-lista       { max-height: 320px; }
  .fqr-elegidas    { max-height: 240px; }
}

/* El buscador se quedaba en un canal con "Añadir 734" al lado y se leía
   "Buscar en etiqueta (". El buscador manda: los otros dos ceden sitio. */
.fqr-busca { min-width: 150px; }
.fqr-info, #fqr-add-todos { flex-shrink: 0; }

/* ═══════════════════════════════════════════════════════════════════════════
   CALENDARIO DE PRODUCCIÓN · la columna de nombres se queda quieta DE VERDAD

   La columna de nombres ya era fija al desplazar. El hueco de la cabecera que
   le corresponde, no. Así que al mover el calendario la cabecera se despegaba
   de las filas: los cinco primeros días quedaban tapados por los nombres y el
   resto de números no cuadraba con las barras de debajo. Se leía como un fallo
   porque lo era.

   Ahora la esquina se queda fija con la columna. Y la separación entre nombres
   y días es una línea de verdad, no una sombra: el texto tiene que quedarse
   quieto a un lado de una raya, y los días empezar al otro.
   ═══════════════════════════════════════════════════════════════════════════ */
.gantt-hdr-esquina {
  position: sticky;
  left: 0;
  z-index: 4;                    /* por encima de los números de día */
  background: var(--surface);
  border-right: 1px solid var(--border-med);
}

/* Misma raya en las filas, para que la columna se lea como una columna y no
   como unas etiquetas flotando encima de la rejilla. */
.gantt-event-label,
.gantt-label-col {
  border-right: 1px solid var(--border-med);
  box-shadow: none;
}

/* El título del grupo: la fila ocupa todo el ancho (no se le puede quitar, el
   ancho va en el atributo `style` del propio elemento y gana a cualquier regla
   de aquí), así que quien se queda quieto es el TEXTO de dentro. Su sitio es la
   columna de nombres, que es donde se mira de qué es cada fila. */
.gantt-group-label { padding-left: 0; }
.gantt-group-txt {
  position: sticky;
  left: 0;
  z-index: 4;
  display: inline-block;
  width: 164px;
  padding-left: 12px;
  background: var(--surface);
}

/* ═══════════════════════════════════════════════════════════════════════════
   CALENDARIO DEL PANEL · la columna de nombres, una columna entera

   El fondo se pintaba SOLO detrás del texto: la etiqueta medía 23 px dentro de
   una fila de 40, y el título de grupo 15 dentro de 26. Los 17 px que sobraban
   en cada fila dejaban ver la rejilla y las franjas de fin de semana por
   detrás, así que la columna no se leía como una columna sino como unos textos
   sueltos flotando encima del calendario. De ahí la sensación de fallo.

   La caja se estira hasta ocupar la fila entera. El fondo pasa a ser una banda
   continua de arriba abajo, que es lo que separa "esto es la lista de qué hay
   en cada fila" de "esto son los días".
   ═══════════════════════════════════════════════════════════════════════════ */
.gantt-event-label {
  align-self: stretch;
  height: auto;
  min-height: 100%;
}

/* El título de grupo hace lo mismo con su fila. El relleno vertical (8 px
   arriba, 3 abajo) estaba en la FILA, y un hijo estirado solo llega hasta el
   borde del contenido: esos 11 px se quedaban sin pintar y volvía a verse la
   rejilla por detrás. El relleno se lo queda el bloque del texto, que es el
   que lleva el fondo. */
.gantt-group-label { display: flex; align-items: stretch; padding: 0; }
.gantt-group-txt   {
  display: flex; align-items: center; flex-shrink: 0;
  padding: 8px 12px 3px;
}

/* Los 2 px entre la cabecera y la primera fila eran los únicos que quedaban sin
   pintar. Se los queda la cabecera, y la banda ya no tiene ni un corte. */
.gantt-header-row { margin-bottom: 0; padding-bottom: 2px; }

/* La etiqueta era una fila que se envolvía sola: el punto de color, el nombre
   y el subtítulo iban sueltos y caían donde cupieran. Resultado medido: los
   nombres empezaban cada uno en una x distinta —25, 42, 47, 35, 48— porque
   quedaban centrados, y el subtítulo unas veces bajaba de línea y otras se
   quedaba al lado. Una columna de nombres se lee bajando por un borde; con los
   bordes bailando, no se lee.

   Con una rejilla de dos columnas cada cosa tiene su sitio: el punto en la
   primera —de ancho FIJO, para que las filas sin punto empiecen exactamente
   donde las que sí lo tienen— y el nombre encima del subtítulo en la segunda.
   El bloque entero, centrado en la altura de la fila. */
.gantt-event-label {
  display: grid;
  grid-template-columns: 15px minmax(0, 1fr);
  grid-template-areas: "punto nombre" "punto sub";
  align-content: center;
  justify-items: start;
  align-items: center;
  column-gap: 0;
  row-gap: 1px;
  padding-left: 12px;
}
.gantt-punto              { grid-area: punto; }
.gantt-lbl-txt            { grid-area: nombre; max-width: 100%; }
.gantt-event-label small  { grid-area: sub; max-width: 100%; padding-left: 0; text-align: left; }

/* ═══════════════════════════════════════════════════════════════════════════
   LOGIN · la retícula pasa al lienzo

   Las líneas las pintaba CSS con dos degradados. Ahora las pinta el lienzo,
   porque además de líneas hay que encender celdas sueltas y CSS no sabe hacer
   eso. Dos retículas superpuestas se verían dobles, así que la de CSS se apaga
   —pero SOLO cuando el lienzo está vivo de verdad (clase `lfx-vivo`, que la
   pone el propio bucle al arrancar). Con movimiento reducido o en pantalla
   estrecha el lienzo no arranca y la de CSS sigue haciendo su trabajo.

   En claro el panel entero estaba al 30 % de opacidad para que el resplandor
   rojo no manchara el papel. Ese resplandor ya no está —lo que hay es la
   retícula— y ese 30 % era justo lo que la dejaba invisible.
   ═══════════════════════════════════════════════════════════════════════════ */
.login-marca.lfx-vivo::before { background: none; }
.lfx-polvo { z-index: -2; }

:root[data-tema="claro"] .login-marca.lfx-vivo::before,
:root:not([data-tema="oscuro"]) .login-marca.lfx-vivo::before { opacity: 1; }

/* El recuadro estático de la foto de perfil ya se quitó, pero quedaba el de
   pasar el ratón por encima: un anillo rojo de 2 px que, al ser una sombra de
   caja sobre una caja cuadrada, dibujaba un CUADRADO alrededor de una foto
   redonda. Fuera, y con él el saltito de escala: la fila entera ya se ilumina
   al pasar por encima, que es señal de sobra de que se puede pulsar. */
.sidebar .sidebar-user:hover .sidebar-avatar {
  transform: none;
  box-shadow: none;
}

/* ═══════════════════════════════════════════════════════════════════════════
   CALENDARIO DE FLOTA · la banda de semanas, legible

   Era un negro fijo (#18181f) escrito a mano, con el texto en blanco al 35 %.
   Y encima `.cal-week-label` le aplicaba OTRO `opacity: .55`. Las dos opacidades
   se multiplican: 0,19 efectivo. A 9 px eso no es "poco contraste", es texto
   invisible — y en tema claro, además, una franja negra atravesando una página
   blanca.

   El negro escrito a mano era el problema de fondo: la barra no seguía el tema.
   Ahora sale de la paleta, así que es una banda discreta en claro y en oscuro,
   y el número de semana se lee.
   ═══════════════════════════════════════════════════════════════════════════ */
.cal-veh-th-week-span {
  /* Mismo caso que HOY: tinte sobre papel opaco, o se transparenta. */
  background-color: var(--surface-2) !important;
  background-image: linear-gradient(var(--bg-hover), var(--bg-hover)) !important;
  color: var(--text-2) !important;
  font-size: 10px !important;
  font-weight: 700 !important;
  padding: 5px 0 4px !important;
  border-right: 1px solid var(--border) !important;
  border-bottom: 1px solid var(--border) !important;
}
/* La opacidad se quita de aquí: el color ya lo pone la regla de arriba, y una
   opacidad encima de un color pensado solo vuelve a apagarlo. */
.cal-week-label { opacity: 1; font-size: 10px; letter-spacing: 0.08em; }

.cal-veh-th-week-span.cal-today-col {
  background-color: var(--surface-2) !important;
  background-image: linear-gradient(rgba(var(--acento-rgb), 0.10), rgba(var(--acento-rgb), 0.10)) !important;
  color: var(--accent) !important;
}

/* ═══════════════════════════════════════════════════════════════════════════
   MI PERFIL A PANTALLA COMPLETA                              (prefijo `.mpf`)

   Era una columna estrecha con todo en fila india sobre una pantalla de 1400 px
   que dejaba media a la derecha en blanco, y los campos uno por línea a todo el
   ancho: una casilla de teléfono de 780 px para escribir nueve cifras.

   Un campo debe medir lo que mide lo que se escribe en él. Por eso los campos
   van en rejilla de dos y solo el nombre y la biografía ocupan las dos.
   ═══════════════════════════════════════════════════════════════════════════ */
.mpf { display: flex; flex-direction: column; gap: 18px; }

/* ── La cabecera: la tarjeta de quién eres ─────────────────────────────── */
.mpf-hero {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 26px;
  padding: 26px 30px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background:
    linear-gradient(120deg, rgba(var(--acento-rgb), 0.07) 0%, transparent 42%),
    var(--bg-card);
}
.mpf-hero-foto .perfil-avatar { width: 104px; height: 104px; }
.mpf-hero-nom {
  font-size: 27px; font-weight: 700; letter-spacing: -0.02em;
  line-height: 1.15; color: var(--text);
}
.mpf-hero-sub {
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px;
  margin-top: 8px;
}
.mpf-chip {
  font-size: 11.5px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
  padding: 3px 10px; border-radius: 20px;
  background: var(--bg-hover); color: var(--text-2);
}
.mpf-chip.es-admin { background: rgba(var(--acento-rgb), 0.12); color: var(--accent); }
.mpf-user {
  font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: 13px; color: var(--text-soft);
}
.mpf-cargo { font-size: 13.5px; color: var(--text-2); }
.mpf-cargo:empty { display: none; }
.mpf-hero-bio {
  margin: 10px 0 0; max-width: 62ch;
  font-size: 13.5px; line-height: 1.5; color: var(--text-2);
}
.mpf-hero-bio:empty { display: none; }

.mpf-hero-cifras { display: flex; gap: 30px; }
.mpf-cifra { text-align: right; }
.mpf-cifra b {
  display: block; font-size: 23px; font-weight: 700;
  letter-spacing: -0.02em; color: var(--text);
  font-variant-numeric: tabular-nums;
}
.mpf-cifra span {
  display: block; margin-top: 2px;
  font-size: 11px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--text-soft);
}

/* ── Las columnas ─────────────────────────────────────────────────────── */
.mpf-rejilla {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
  gap: 18px;
  align-items: start;
}
.mpf-rejilla-baja { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.mpf-col { display: flex; flex-direction: column; gap: 18px; min-width: 0; }

.mpf-caja {
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--bg-card);
  padding: 20px 22px 18px;
}
.mpf-caja-tit {
  font-size: 12px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--text-soft);
  padding-bottom: 12px; margin-bottom: 16px;
  border-bottom: 1px solid var(--border);
}

/* ── Los campos ───────────────────────────────────────────────────────── */
.mpf-campos {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px 16px;
}
.mpf-ancho { grid-column: 1 / -1; }
.mpf-campo { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.mpf-campo > span {
  font-size: 12.5px; font-weight: 600; color: var(--text-2);
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px;
}
/* La explicación va junto a la etiqueta, no debajo del campo: se lee ANTES de
   escribir, que es cuando sirve. */
.mpf-campo > span i {
  font-style: normal; font-weight: 400; font-size: 11.5px; color: var(--text-soft);
}
.mpf-campo input,
.mpf-campo textarea {
  width: 100%;
  padding: 9px 12px;
  font: inherit; font-size: 14px;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 7px;
  outline: none;
  transition: border-color .14s, box-shadow .14s;
}
.mpf-campo textarea { resize: vertical; min-height: 78px; line-height: 1.5; }
.mpf-campo input:focus,
.mpf-campo textarea:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(var(--acento-rgb), 0.14);
}
.mpf-campo input::placeholder,
.mpf-campo textarea::placeholder { color: var(--text-xsoft); }

.mpf-acciones { display: flex; gap: 10px; margin-top: 18px; }

/* Los bloques del resumen ya traen su propia caja: aquí solo se les quita el
   margen suelto que traían de ir apilados en una columna. */
.mpf-hueco > .mp-bloque { margin: 0; }

/* ── Pantallas medianas y estrechas ───────────────────────────────────── */
@media (max-width: 1240px) {
  .mpf-rejilla, .mpf-rejilla-baja { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 860px) {
  .mpf-hero {
    grid-template-columns: auto minmax(0, 1fr);
    gap: 18px; padding: 20px;
  }
  /* Las cifras pasan debajo, en fila: al lado de la foto no caben y partirían
     los números en dos líneas. */
  .mpf-hero-cifras {
    grid-column: 1 / -1;
    justify-content: space-between; gap: 14px;
    padding-top: 16px; border-top: 1px solid var(--border);
  }
  .mpf-cifra { text-align: left; }
  .mpf-campos { grid-template-columns: minmax(0, 1fr); }
  .mpf-hero-foto .perfil-avatar { width: 76px; height: 76px; }
  .mpf-hero-nom { font-size: 22px; }
}

/* El botón de cambiar la foto colgaba de la esquina, con un aro del color de
   `--surface` que en la cabecera no es el fondo que hay detrás: se veía un
   borde claro sobre otro tono. Se mete DENTRO de la foto y se queda cuadrado,
   como el resto de la aplicación. */
.mpf-hero-foto .perfil-avatar-change {
  bottom: 6px; right: 6px;
  width: 28px; height: 28px;
  border: 0;
  border-radius: var(--radius-sm);
  box-shadow: 0 2px 8px rgba(0,0,0,0.35);
}
.mpf-hero-foto .perfil-avatar-change:hover { transform: none; background: var(--accent-hover); }
/* La foto, del tamaño que le pide la cabecera y no del que traía de la ficha
   pequeña que había antes. */
.mpf-hero-foto .perfil-avatar-img,
.mpf-hero-foto .perfil-avatar-placeholder { width: 100%; height: 100%; object-fit: cover; }
.mpf-hero-foto .perfil-avatar-placeholder { font-size: 40px; display: grid; place-items: center; }

/* ═══════════════════════════════════════════════════════════════════════════
   MÓVIL                                                       (prefijo `.mov-`)

   Punto de corte en 760 px: por debajo de ahí no caben dos columnas de datos
   sin que una de las dos deje de leerse.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 760px) {

  /* ── Tiras de pestañas: se desplazan ellas, no la página ──────────────
     Marcadas por `_movTiras` cuando de verdad no caben. Sin esto empujaban el
     ancho de la aplicación entera y todo se movía de lado al bajar con el dedo. */
  .mov-tira {
    overflow-x: auto;
    overflow-y: hidden;
    flex-wrap: nowrap !important;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    /* El desplazamiento se para en cada botón: media pestaña a la vista se lee
       como que la lista se ha quedado a medias. */
    scroll-snap-type: x proximity;
  }
  .mov-tira::-webkit-scrollbar { display: none; }
  .mov-tira > * { flex-shrink: 0; scroll-snap-align: start; }

  /* ── Tablas en tarjetas ───────────────────────────────────────────────
     Una tabla de mil píxeles en una pantalla de 375 se puede desplazar de
     lado, pero leer una ficha así es ir y venir por cada dato. Cada fila pasa
     a ser una tarjeta y cada celda una línea "etiqueta · valor". La etiqueta
     sale de la cabecera, que ya estaba escrita. */
  .mov-tabla { display: block; width: 100%; border: 0; }
  .mov-tabla thead { display: none; }          /* los nombres van ya en cada celda */
  .mov-tabla tbody { display: block; }
  .mov-tabla tbody tr {
    display: block;
    margin-bottom: 10px;
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-card);
  }
  .mov-tabla tbody tr:hover { background: var(--bg-card); }
  .mov-tabla tbody td {
    display: flex;
    align-items: baseline;
    gap: 10px;
    width: auto !important;
    padding: 4px 0 !important;
    border: 0 !important;
    white-space: normal !important;
    text-align: left !important;
  }
  /* La etiqueta, delante y en gris. Ancho fijo para que los valores queden
     alineados entre sí: una columna de valores dentada se lee peor que una
     etiqueta cortada. */
  .mov-tabla tbody td::before {
    content: attr(data-mov-col);
    flex: 0 0 34%;
    max-width: 34%;
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--text-soft);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  /* Celda sin nombre de columna —casillas, botones de acción—: sin etiqueta y
     a todo el ancho. Poner "" delante de un botón es ruido. */
  .mov-tabla tbody td[data-mov-col=""]::before { content: none; }
  .mov-tabla tbody td[data-mov-col=""] { justify-content: flex-start; }
  /* AQUÍ ESTABA "la primera celda hace de título". No sirve: en casi todas las
     tablas de esta aplicación la primera celda es la CASILLA de selección, así
     que el estilo de título se lo llevaba un cuadradito de 14 px y el nombre
     de verdad se quedaba como una línea más. Las etiquetas ya ordenan la
     tarjeta; no hace falta un título inventado. */

  /* La celda de acciones: los botones se ponen en fila y se salían por la
     derecha —"Ficha · Mant. · Editar · Bo…"—. Que bajen de línea. */
  .mov-tabla tbody td[data-mov-col="Acciones"],
  .mov-tabla tbody td[data-mov-col="ACCIONES"],
  .mov-tabla tbody td:last-child { flex-wrap: wrap; row-gap: 6px; }
  .mov-tabla tbody td[data-mov-col=""] > *,
  .mov-tabla tbody td:last-child > * { flex-shrink: 0; }
  /* Con los botones abajo, la etiqueta al lado los estrecha: pasa arriba y los
     deja a lo ancho de la tarjeta. */
  .mov-tabla tbody td:last-child::before { flex-basis: 100%; max-width: 100%; margin-bottom: 2px; }
  /* El envoltorio ya no tiene que desplazarse: la tabla cabe. */
  .mov-tabla { min-width: 0 !important; }
  .table-wrap:has(.mov-tabla) { overflow-x: visible; }

  /* ── Cabeceras de página ──────────────────────────────────────────────
     Título y acciones en la misma línea no caben: el título se parte en tres
     líneas para dejar sitio a dos botones. */
  .page-header {
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
  }
  .page-header h1 { font-size: 24px; }
  .page-header > div { display: flex; flex-wrap: wrap; gap: 8px; }

  /* ── Márgenes ─────────────────────────────────────────────────────────
     28/30 px de margen en una pantalla de 375 son 60 px, un sexto del ancho,
     gastados en aire alrededor de tablas que ya van justas. */
  .main-scroll { padding: 16px 14px; }

  /* ── Botones: que se puedan dar ───────────────────────────────────────
     44 px es lo que ocupa un dedo. Por debajo se falla y se pulsa lo de al
     lado, que en una lista de material es abrir la ficha equivocada. */
  .btn, .btn-sm, .filter-input, .filter-select, input, select, textarea {
    min-height: 42px;
  }
  .btn-sm { min-height: 38px; }
}

/* Una tira que desbordaba a su padre seguía siendo más ancha que el hueco
   aunque pudiera desplazarse: hay que obligarla a caber para que el
   desplazamiento sea suyo y no de la página. */
@media (max-width: 760px) {
  .mov-tira { max-width: 100%; min-width: 0; }
}

/* El botón de quitar una foto de vehículo: encima de la foto, arriba a la
   derecha, y solo existe cuando hay foto. Fuera de la foto habría que dejarle
   sitio siempre, y un hueco reservado para un botón que casi nunca está
   descuadra las cuatro casillas. */
.veh-foto-preview { position: relative; }
.veh-foto-quitar {
  position: absolute; top: 6px; right: 6px;
  width: 24px; height: 24px;
  display: grid; place-items: center;
  border: 0; border-radius: var(--radius-sm);
  background: rgba(10,10,12,0.62);
  color: #fff;
  cursor: pointer;
  opacity: 0;
  transition: opacity .14s ease, background .14s ease;
}
.veh-foto-preview:hover .veh-foto-quitar { opacity: 1; }
.veh-foto-quitar:hover { background: var(--accent); }
/* En pantalla táctil no hay "pasar por encima": si solo apareciera al hover,
   en el móvil no habría forma de quitar una foto. */
@media (hover: none) {
  .veh-foto-quitar { opacity: 1; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   CAMBIO DE SUBPROYECTO · que se vea                          (prefijo `.scb`)
   ═══════════════════════════════════════════════════════════════════════════ */

/* La banda permanente. Mientras haya un subproyecto activo, la ficha va
   marcada por la izquierda con su color. Es el único aviso que no caduca: los
   otros dos se van y el filtro se queda. */
#proy-ficha { position: relative; }
/* La banda va como SOMBRA INTERIOR, no como borde con margen negativo.

   Con `border-left: 3px` + `margin-left: -18px` la banda quedaba pegada al
   borde, sí — pero desplazaba la ficha entera 18 px a la izquierda mientras el
   ancho seguía siendo el 100 % del padre, así que se salía 18 px por la
   derecha. Efecto visible: un filo rojo a la izquierda y la última cifra
   cortada («0 VEHÍ…»). Un adorno que mueve la maqueta no es un adorno, es un
   fallo de maquetación.

   Una sombra interior se pinta DENTRO de la caja: no ocupa sitio, no desplaza
   nada y no puede sacar el contenido del contenedor. */
#proy-ficha.en-sub {
  box-shadow: inset 3px 0 0 var(--scb-color, var(--accent));
  padding-left: 15px;
}

/* El barrido: una franja de color que cruza la ficha una vez, y el contenido
   entrando desde abajo. Lo que se anima es el contenedor, no cada tarjeta:
   veinte tarjetas animándose a la vez se lee como un fallo de pintado. */
#proy-ficha.scb-cambio { animation: scb-entrar 420ms cubic-bezier(.22,.9,.28,1); }
#proy-ficha.scb-cambio::after {
  content: '';
  position: absolute; inset: 0;
  pointer-events: none;
  background: linear-gradient(100deg,
    transparent 0%,
    color-mix(in srgb, var(--scb-color, #ef233c) 22%, transparent) 45%,
    transparent 70%);
  animation: scb-barrido 560ms ease-out forwards;
}
@keyframes scb-entrar {
  from { opacity: .35; transform: translateY(9px); }
  to   { opacity: 1;   transform: none; }
}
@keyframes scb-barrido {
  from { transform: translateX(-100%); opacity: 1; }
  to   { transform: translateX(100%);  opacity: 0; }
}

/* El cartel de "ahora ves". Se va solo a los tres segundos: es la respuesta a
   "¿qué acaba de pasar?", y esa pregunta caduca. */
.scb-aviso {
  display: flex; align-items: center; gap: 10px;
  margin-bottom: 14px; padding: 9px 14px;
  border: 1px solid color-mix(in srgb, var(--scb-color, #ef233c) 40%, var(--border));
  border-left: 3px solid var(--scb-color, #ef233c);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--scb-color, #ef233c) 8%, var(--bg-card));
  font-size: 13.5px; color: var(--text);
  animation: scb-aviso-entra 260ms cubic-bezier(.22,.9,.28,1);
}
.scb-aviso i {
  width: 8px; height: 8px; flex-shrink: 0;
  background: var(--scb-color, #ef233c);
  border-radius: 2px;
}
.scb-aviso.yendose { animation: scb-aviso-sale 380ms ease forwards; }
@keyframes scb-aviso-entra {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}
@keyframes scb-aviso-sale {
  to { opacity: 0; transform: translateY(-6px); margin-bottom: 0; padding-block: 0; height: 0; }
}

/* Quien pide menos movimiento se queda con los avisos que no se mueven: el
   cartel y la banda. Perder el destello no le quita información. */
@media (prefers-reduced-motion: reduce) {
  #proy-ficha.scb-cambio { animation: none; }
  #proy-ficha.scb-cambio::after { display: none; }
  .scb-aviso { animation: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   FINANZAS · elegir qué se cobra, y luego cómo                (prefijo `.fz-`)
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Las opciones: una sola ──────────────────────────────────────────────
   Filas cuadradas, del ancho entero, con el importe alineado a la derecha.
   Se leen bajando por la columna de euros, que es lo que se compara. */
.fz-ops {
  display: grid; gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  overflow: hidden;
  margin-bottom: 20px;
}
.fz-op {
  display: grid;
  grid-template-columns: 16px minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 12px 14px;
  border: 0;
  background: var(--bg-card);
  font: inherit; font-size: 14px; color: var(--text);
  text-align: left; cursor: pointer;
  transition: background .12s ease;
}
.fz-op:hover { background: var(--bg-hover); }
/* La marca de elegido: un cuadrado que se rellena. Redondo diría "puedes
   elegir varios"; cuadrado y lleno dice "esta es". */
.fz-op-marca {
  width: 15px; height: 15px;
  border: 1.5px solid var(--border-med);
  border-radius: 3px;
}
.fz-op.sel { background: color-mix(in srgb, var(--accent) 7%, var(--bg-card)); }
.fz-op.sel .fz-op-marca {
  border-color: var(--accent);
  background: var(--accent);
  box-shadow: inset 0 0 0 3px var(--bg-card);
}
.fz-op-nom { font-weight: 600; display: flex; align-items: baseline; gap: 9px; min-width: 0; }
.fz-op-nom i {
  font-style: normal; font-size: 10.5px; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase;
  color: var(--text-soft);
  border: 1px solid var(--border-med);
  border-radius: 3px; padding: 1px 5px;
  flex-shrink: 0;
}
.fz-op-n   { font-size: 12.5px; color: var(--text-soft); white-space: nowrap; }
.fz-op-eur { font-weight: 700; min-width: 92px; text-align: right; }

.fz-vacios {
  padding: 9px 14px;
  background: var(--bg-card);
  font-size: 12px; color: var(--text-xsoft);
}

/* ── Las dos salidas ─────────────────────────────────────────────────────
   El presupuesto se manda y se cambia; lo que
   lleva número fiscal y no se deshace. Antes eran dos botones seguidos en el
   mismo pie, del mismo tamaño, y el segundo se pulsa por inercia. Separados en
   dos paneles, el sitio y el marco hacen de aviso sin necesidad de un cartel. */
.fz-salidas {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}
.fz-salida {
  display: flex; flex-direction: column; align-items: flex-start; gap: 8px;
  padding: 16px 18px 18px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-card);
}
.fz-salida h3 {
  margin: 0; font-size: 15px; font-weight: 700; letter-spacing: -0.01em;
}
.fz-salida p {
  margin: 0; font-size: 12.5px; line-height: 1.5; color: var(--text-2);
  flex: 1;
}
.fz-salida .fz-btn { margin-top: 4px; }


/* Sin nada elegido los paneles siguen ahí pero apagados: quitarlos haría
   saltar la página al elegir, y no se entendería qué va a pasar después. */
.fz-salidas.apagadas { opacity: .5; }

.fz-resumen {
  margin: 16px 0 0;
  font-size: 13px; color: var(--text-2);
}

@media (max-width: 760px) {
  .fz-salidas { grid-template-columns: minmax(0, 1fr); }
  .fz-op { grid-template-columns: 16px minmax(0, 1fr) auto; row-gap: 4px; }
  .fz-op-n { grid-column: 2; }
  .fz-op-eur { grid-row: 1; grid-column: 3; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   CALENDARIO DE FLOTA · el zoom escala TODO

   Antes solo escalaba el ancho de día. Con 29 vehículos y filas de 42 px fijos
   no había vista general: alejar te daba más días pero las mismas nueve filas.

   Se escalan las medidas y se deja que el navegador vuelva a componer, en vez
   de un `transform: scale()` sobre la tabla: escalado con transform el texto se
   emborrona —se estira un dibujo ya pintado— y la columna fija y el cálculo del
   desplazamiento dejan de cuadrar porque el navegador sigue creyendo que la
   tabla mide lo de antes.
   ═══════════════════════════════════════════════════════════════════════════ */
.cal-veh-row,
.cal-veh-table .cal-veh-row { height: var(--cal-fila-h, 42px); }
.cal-veh-table .cal-veh-td-veh,
.cal-veh-table .cal-veh-td-day { height: var(--cal-fila-h, 42px); }

.cal-veh-table .cal-veh-th-veh,
.cal-veh-table .cal-veh-td-veh {
  width: var(--cal-veh-w, 190px);
  min-width: var(--cal-veh-w, 190px);
  max-width: var(--cal-veh-w, 190px);
}

.cal-veh-name { font-size: var(--cal-txt, 12.5px); }
.cal-veh-mat  { font-size: var(--cal-txt-2, 10px); display: var(--cal-mat-vis, block); }
.cal-day-num  { font-size: var(--cal-txt, 12.5px); }

/* Las barras de ocupación: el texto sigue al zoom y desaparece cuando ya no
   cabe. Una barra con media palabra dentro se lee peor que una barra limpia:
   el color ya dice de qué proyecto es. */
.cal-ev-txt { font-size: var(--cal-txt-2, 10px); }
.cal-veh-table[data-z-min="1"] .cal-ev-txt { display: none; }

/* Alejado del todo, la rejilla vertical de cada día es más ruido que ayuda:
   con columnas de 26 px las líneas ocupan más que los huecos. */
.cal-veh-table[data-z-min="1"] .cal-veh-td-day { border-right-color: transparent; }

/* El logo del vehículo no cabe en una fila de 18 px. */
.cal-veh-logo-cell { display: var(--cal-mat-vis, block); }

/* El porcentaje invita a que se pueda pulsar, porque el doble clic lo devuelve
   al 100 %. */
#cal-zoom-nivel { cursor: pointer; user-select: none; }
#cal-zoom-nivel:hover { color: var(--accent); }

/* La fila no bajaba de 44 px aunque el zoom dijera 64 %. Medido: 8 px de
   relleno arriba, 8 abajo y un bloque interior de 28 px con letra de 13,5 px
   —el envoltorio tenía su propio tamaño, así que mi variable no le llegaba—.
   Una altura de fila que no obedece al zoom no es un zoom.

   Ahora el relleno, la letra del envoltorio, el hueco y el logo salen todos
   del mismo factor, y la fila mide lo que se le pide. */
.cal-veh-table .cal-veh-td-veh,
.cal-veh-table .cal-veh-th-veh {
  padding-block: calc(8px * var(--cal-z, 1));
}
.cal-veh-row-inner {
  font-size: var(--cal-txt, 12.5px);
  line-height: 1.2;
  gap: calc(10px * var(--cal-z, 1));
  min-width: 0;
}
.cal-veh-logo-cell {
  width:  calc(40px * var(--cal-z, 1));
  height: calc(28px * var(--cal-z, 1));
}

/* ═══════════════════════════════════════════════════════════════════════════
   BARRA DE AÑADIR MATERIAL                                    (prefijo `.ebr`)

   El desplegable de subproyecto medía lo que le sobraba después de los otros
   tres campos, y lo que sobraba eran 40 px: "Producción" salía como "Pro…" y a
   veces como "S". Un campo que no se puede leer no se puede comprobar — y ahí
   había justo un fallo que solo se detectaba leyéndolo.

   Ahora es una rejilla: los dos números ocupan lo que ocupa un número, y el
   subproyecto se lleva el sitio, porque es el campo que decide dónde acaba el
   material. El grupo va detrás porque es opcional.
   ═══════════════════════════════════════════════════════════════════════════ */
.ecat-anadir.ebr {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 14px 16px;
  border-top: 1px solid var(--border);
  background: var(--bg-card);
}
.ebr-campos {
  display: grid;
  grid-template-columns: 82px 82px minmax(150px, 1.2fr) minmax(120px, 1fr);
  gap: 10px;
  align-items: end;
}
.ebr-c { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.ebr-c > span {
  font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--text-soft);
  display: flex; align-items: baseline; gap: 6px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ebr-c > span i {
  font-style: normal; font-weight: 500; letter-spacing: 0;
  text-transform: none; color: var(--text-xsoft); font-size: 10.5px;
}
.ebr-c input,
.ebr-c select,
.ebr-c .sel-dd {
  width: 100%; min-width: 0;
  height: 38px;
  padding: 0 11px;
  font: inherit; font-size: 13.5px;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  outline: none;
}
.ebr-c input:focus,
.ebr-c select:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 16%, transparent);
}
.ebr-num input { text-align: center; font-variant-numeric: tabular-nums; }

/* El desplegable adoptado hereda las clases, así que el ancho se le impone
   aquí: si no, vuelve a medir lo que le sobre. */
.ebr-sub .sel-dd,
.ebr-sub .sel-dd-btn { width: 100%; min-width: 0; }
.ebr-sub .sel-dd-btn { justify-content: space-between; }

.ebr-btn { width: 100%; height: 42px; }
.ecat-anadir.ebr:not(.activa) .ebr-btn { opacity: .55; }

/* El aviso de que no ha entrado nada, PEGADO a la barra. Un toast en la
   esquina para "no se ha añadido nada" es justo el sitio donde no estás
   mirando, y se va en tres segundos. */
.ebr-fallo {
  padding: 8px 11px;
  border: 1px solid color-mix(in srgb, var(--red, #ef233c) 45%, var(--border));
  border-left: 3px solid var(--red, #ef233c);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--red, #ef233c) 9%, var(--bg-card));
  font-size: 12.5px; color: var(--text);
}

@media (max-width: 900px) {
  .ebr-campos { grid-template-columns: 1fr 1fr; }
  .ebr-sub, .ebr-grupo { grid-column: 1 / -1; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   LOGOS DE MARCA · todos como el de Mercedes

   Había tres aspectos distintos para lo mismo:

   · Mercedes y las marcas con SVG en línea: el dibujo suelto, sin fondo ni
     borde, heredando el color del tema. Limpio.
   · Las marcas con PNG: el mismo dibujo pero dentro de una CAJA —fondo
     `--surface` y borde de 1 px—. La caja estaba para dar una placa uniforme a
     PNG de proporciones distintas, pero al ponerla al lado de un SVG sin caja,
     lo que se ve no es uniformidad: se ve que a unos les falta algo.
   · Las marcas sin fichero: un rectángulo de color con dos letras dentro.

   Ahora los tres son lo mismo: el dibujo o el nombre, sin caja. Un rectángulo
   rojo con "NS" dentro no dice más que "Nissan" escrito, y sí mete una caja
   donde las demás filas no tienen ninguna.
   ═══════════════════════════════════════════════════════════════════════════ */
.veh-brand-logo-wrap {
  background: transparent;
  border: 0;
}
.veh-brand-badge {
  background: transparent;
  border: 0;
  color: var(--text-soft);
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-align: center;
  line-height: 1.15;
  /* El nombre entero cabe en dos líneas; si no cabe, se corta. Vale más
     "Isuzu" que "IS". */
  display: flex; align-items: center; justify-content: center;
  padding: 0 2px;
  overflow: hidden;
  word-break: break-word;
}

/* La segunda línea de la pestaña ahora dice de QUÉ es. Va más apagada y más
   pequeña que el nombre para que la barra se siga leyendo por los nombres: el
   tipo es la respuesta a una duda, no lo primero que se busca. */
.tab .tab-sub {
  display: block;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.03em;
  color: var(--text-xsoft);
  line-height: 1.25;
  margin-top: 1px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* En la activa se sube un punto: es la única que se está mirando. */
.tab.activa .tab-sub { color: var(--text-soft); }

/* ═══════════════════════════════════════════════════════════════════════════
   MI PERFIL · "Qué puedo hacer" resumido                       (prefijo `.mpp`)

   Eran nueve tarjetas repitiendo la misma palabra. Ahora son cuatro filas como
   máximo —o una frase, si todo es igual— agrupadas por lo que se puede hacer.
   ═══════════════════════════════════════════════════════════════════════════ */
.mpp-todo {
  margin: 0;
  font-size: 14px; line-height: 1.5; color: var(--text-2);
}
.mpp-todo strong { color: var(--text); }

.mpp-filas { display: grid; gap: 1px; background: var(--border); }
.mpp-fila {
  display: grid;
  grid-template-columns: 104px minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 12px;
  padding: 9px 0;
  background: var(--bg-card);
}
.mpp-nivel {
  font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--text-soft);
  white-space: nowrap;
}
.mpp-areas { font-size: 13px; line-height: 1.45; color: var(--text); }
.mpp-n {
  font-size: 11.5px; font-weight: 700; color: var(--text-xsoft);
  font-variant-numeric: tabular-nums;
}
/* El nivel se distingue por el color de su etiqueta, no por un fondo: nueve
   áreas con cuatro fondos distintos era lo que hacía que esto pareciera un
   semáforo en vez de una lista. */
.mpp-total   .mpp-nivel { color: var(--accent); }
.mpp-edicion .mpp-nivel { color: var(--mo-aviso, var(--text-2)); }
.mpp-ninguno .mpp-areas { color: var(--text-xsoft); }

.mpp-caps {
  display: flex; flex-wrap: wrap; gap: 6px;
  margin-top: 14px; padding-top: 12px;
  border-top: 1px solid var(--border);
}

@media (max-width: 560px) {
  .mpp-fila { grid-template-columns: minmax(0, 1fr) auto; }
  .mpp-nivel { grid-column: 1 / -1; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   EQUIPMENT · el catálogo, ancho proporcional a lo que lleva dentro

   La barra de añadir que puse pedía 464 px como mínimo —dos números, el
   subproyecto y el grupo en una fila— y el panel del catálogo estaba clavado a
   340 px. Resultado: el campo GRUPO se salía del panel y se metía en la
   columna del material del proyecto.

   Dos arreglos, porque con uno solo el problema vuelve en la siguiente
   pantalla más estrecha:

   1. El panel crece con la ventana en vez de estar clavado. Un mínimo de
      340 px —lo que necesita el árbol de categorías— y un techo de 430, porque
      pasado eso el sitio se lo está quitando a la tabla de material, que es
      donde se lee lo que llevas puesto.

   2. LA BARRA SE ADAPTA A SU PROPIO ANCHO, no al de la ventana. Es una consulta
      de contenedor y no una `@media` a propósito: este panel puede medir 340 o
      430 px con la MISMA ventana —depende del ancho disponible— así que
      preguntar por la ventana no contesta la pregunta. Se pregunta por la caja.

   Por defecto van en dos filas de dos, que caben siempre; los cuatro en línea
   solo cuando la barra pasa de 470 px. Si el navegador no entendiera las
   consultas de contenedor, se queda en dos filas: nunca desborda.
   ═══════════════════════════════════════════════════════════════════════════ */
.eq-2col { grid-template-columns: clamp(340px, 27vw, 430px) minmax(0, 1fr); }

.ecat-anadir.ebr { container-type: inline-size; container-name: ebr; }

/* Dos filas de dos: la base, la que cabe siempre. */
.ebr-campos { grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* AQUÍ HABÍA una rama para poner los cuatro campos en línea cuando la barra
   pasara de 470 px. La escribí y luego eché la cuenta: el panel está limitado
   a 430 px de techo, así que la barra no pasa de ~398 y esa rama NO SE EJECUTA
   NUNCA. CSS que parece hacer algo y no se aplica es peor que no tenerlo: el
   siguiente que venga a cambiar el ancho lo tocará creyendo que sirve.

   Y de paso: dos filas de dos es mejor aquí que cuatro en línea. En 390 px,
   cuatro campos en fila dejan al subproyecto con 110 px, que es justo el
   problema que vine a arreglar. */

/* Los números no necesitan la mitad del panel: en dos filas se quedan
   estrechos y el hueco se lo lleva el subproyecto, que es el que hay que leer. */
@container ebr (max-width: 469.9px) {   /* el único caso real; ver la nota de arriba */
  /* Dos huecos estrechos para los números y un tercero VACÍO que se come el
     espacio que sobra. Con dos columnas, "Días" se quedaba con 269 px para
     escribir un 3 mientras "Cantidad" tenía 76: la rejilla reparte lo que
     sobra entre las columnas que existen, así que hay que darle una que no
     lleve nada. */
  .ebr-campos { grid-template-columns: 76px 76px minmax(0, 1fr); }
  .ebr-num:nth-of-type(1) { grid-column: 1; }
  .ebr-num:nth-of-type(2) { grid-column: 2; }
  .ebr-sub, .ebr-grupo { grid-column: 1 / -1; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   EQUIPMENT · barra mínima y grupos como carpetas
   ═══════════════════════════════════════════════════════════════════════════ */

/* La barra de añadir: un botón y una línea que dice dónde va a caer. Los
   cuatro campos que había se fueron —el subproyecto ya está elegido arriba, la
   cantidad y los días se cambian en la línea, y el grupo se hace después, con
   las cosas delante. */
.ecat-anadir.eqs {
  display: flex; flex-direction: column; gap: 7px;
  padding: 13px 16px;
  border-top: 1px solid var(--border);
  background: var(--bg-card);
}
.eqs-btn { width: 100%; height: 42px; }
.ecat-anadir.eqs:not(.activa) .eqs-btn { opacity: .55; }
.eqs-destino {
  margin: 0; text-align: center;
  font-size: 11.5px; color: var(--text-soft);
}
.eqs-destino strong { color: var(--text-2); font-weight: 650; }

/* El botón de crear grupo, en el panel del material. Antes estaba solo en la
   barra de selección, que aparece únicamente si YA habías marcado algo: para
   abrir una carpeta vacía no había forma de llegar. */
.eqs-grupos {
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px;
  margin: 0 0 14px;
}
.eqs-activo {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 4px 6px 4px 11px;
  border: 1px solid color-mix(in srgb, var(--accent) 40%, var(--border));
  border-radius: 20px;
  background: color-mix(in srgb, var(--accent) 9%, transparent);
  font-size: 12.5px; color: var(--text-2);
}
.eqs-activo strong { color: var(--text); }
.eqs-x {
  border: 0; background: none; cursor: pointer;
  color: var(--text-soft); font-size: 15px; line-height: 1;
  padding: 0 4px; border-radius: 4px;
}
.eqs-x:hover { color: var(--accent); background: var(--bg-hover); }

/* ── Las carpetas ────────────────────────────────────────────────────────
   Un grupo era un título suelto encima de una tabla: con tres grupos, tres
   títulos y tres tablas seguidas sin saber dónde acaba cada uno. Plegada, una
   carpeta ocupa una línea con su total, así que con seis grupos se ve el
   reparto del rodaje de un vistazo. */
.eq-grupo.eqf { border: 1px solid var(--border); border-radius: 9px; overflow: hidden; }
.eq-grupo.eqf + .eq-grupo { margin-top: 10px; }
/* La cabecera lleva DOS botones: abrir la carpeta y elegirla como destino. Por
   eso es una fila, y la rejilla de siempre vive ahora en el de abrir. */
.eqf-cab {
  display: flex; align-items: stretch; flex-wrap: wrap;
  background: var(--bg-hover);
}
/* `1 1 230px`: con sitio, los dos botones van en la misma línea; sin él, el de
   «Añadir aquí» baja a la suya en vez de estrujar el nombre del grupo hasta
   hacerlo desaparecer —que es justo lo que pasaba con el panel estrecho. */
.eqf-abrir {
  display: grid;
  grid-template-columns: 16px minmax(0, 1fr) auto auto;
  align-items: center; gap: 11px;
  flex: 1 1 230px; min-width: 0; padding: 10px 13px;
  border: 0; background: none;
  font: inherit; text-align: left; cursor: pointer;
}
.eqf-abrir:hover { background: var(--bg-hover-2, var(--bg-hover)); filter: brightness(1.06); }
.eqf-flecha { color: var(--text-soft); font-size: 11px; }
/* El nombre se recorta, no se come a los de al lado. Un grupo puede llamarse
   «Segunda unidad noche» y el panel del material es estrecho: sin esto el
   nombre pisaba el recuento y el total, y se veía desde antes de que hubiera
   un botón aquí. */
.eqf-nom {
  font-size: 14px; font-weight: 650; color: var(--text);
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.eqf-n { font-size: 11.5px; color: var(--text-soft); white-space: nowrap; }
.eqf-total { font-size: 13.5px; font-weight: 700; text-align: right; white-space: nowrap; }
/* En un panel estrecho sobra el recuento antes que el dinero: «3 líneas» se ve
   abriendo la carpeta, el total no. */
@container eqpanel (max-width: 420px) {
  .eqf-n { display: none; }
  /* Y el total baja a su propia línea. Con el panel así de estrecho, el nombre
     del grupo y el dinero no caben a la vez, y lo que se recortaba era el
     nombre: «Utility» se quedaba en «U.», que no dice nada. */
  .eqf-abrir { grid-template-columns: 16px minmax(0, 1fr); row-gap: 2px; }
  .eqf-total { grid-column: 2; text-align: left; }
}
/* La carpeta a la que están cayendo las cosas se marca: es un estado que dura
   y hay que poder verlo sin recordarlo. */
.eq-grupo.eqf.activa { border-color: color-mix(in srgb, var(--accent) 50%, var(--border)); }
.eq-grupo.eqf.activa .eqf-cab { background: color-mix(in srgb, var(--accent) 10%, var(--bg-hover)); }

/* «Añadir aquí»: el selector de destino, en la propia carpeta. En reposo es
   discreto —hay uno por carpeta y no pueden gritar todos—; puesto, es el único
   sitio de la pantalla con el color de la casa. */
.eqf-aqui {
  flex-shrink: 0; align-self: center;
  /* Los márgenes verticales sirven para cuando baja a su propia línea; en la
     misma línea no estorban, porque va centrado. */
  margin: 4px 0 4px 9px; padding: 5px 11px;
  border: 1px solid var(--border); border-radius: 20px;
  background: var(--surface);
  font: inherit; font-size: 11.5px; font-weight: 650; color: var(--text-soft);
  white-space: nowrap; cursor: pointer;
  transition: color var(--transition), border-color var(--transition), background var(--transition);
}
.eqf-aqui:hover {
  color: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 45%, var(--border));
}
.eqf-aqui.puesto {
  background: var(--accent); border-color: var(--accent); color: #fff;
}
.eqf-aqui.puesto:hover { color: #fff; filter: brightness(1.07); }
/* Con material marcado toda carpeta es un destino de un clic: se nota en el
   borde, pero sin el relleno rojo —si se pintan todas de rojo, el rojo deja de
   querer decir «aquí es donde está cayendo». */
.eqf-aqui.cargado {
  color: var(--text); border-color: color-mix(in srgb, var(--accent) 55%, var(--border));
}
.eqf-aqui.cargado:hover { background: var(--accent); border-color: var(--accent); color: #fff; }

/* «Mover a…», al lado de «Añadir aquí». Mismo tamaño y misma forma: son las dos
   cosas que se le hacen a una carpeta y ninguna manda sobre la otra. Más
   apagado porque mover es más raro que añadir. */
.eqf-mover {
  flex-shrink: 0; align-self: center;
  margin: 4px 9px 4px 0; padding: 5px 11px;
  border: 1px solid transparent; border-radius: 20px;
  background: none;
  font: inherit; font-size: 11.5px; font-weight: 650; color: var(--text-soft);
  white-space: nowrap; cursor: pointer;
  transition: color var(--transition), border-color var(--transition), background var(--transition);
}
.eqf-mover:hover {
  color: var(--text); border-color: var(--border); background: var(--surface);
}

/* El cajón de lo que no está en ninguna carpeta. No se pliega: esconder lo que
   queda por ordenar es esconder justo lo que hay que hacer. */
.eqf-sueltas { margin-top: 10px; }
.eqf-sueltas-tit {
  display: flex; align-items: baseline; gap: 10px;
  padding: 6px 2px 8px;
  font-size: 11.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--text-xsoft);
}
.eqf-meta { font-weight: 600; letter-spacing: 0; text-transform: none; color: var(--text-soft); }

/* ═══════════════════════════════════════════════════════════════════════════
   BARRA LATERAL · retícula viva, muy tenue                    (prefijo `.sbr`)
   [PRUEBA — para quitarlo: borrar este bloque y el `_sbr` de app.js]

   Lo mismo que el login pero bajado hasta donde casi no se nota. El login es
   una pantalla de cinco segundos sin nada que leer; la barra está SIEMPRE y
   tiene texto encima que hay que leer todo el día.

   PRIMER INTENTO demasiado bajo: retícula al 1,6 % y celdas al 5,5 %. Cuando
   dijiste "super sutil" me fui al extremo, y el resultado era que había que
   quedarse mirando la barra a ver si pasaba algo. Subido a 3,8 % y 12 %: sigue
   estando muy por debajo del login, pero ya se ve sin buscarlo.
   ═══════════════════════════════════════════════════════════════════════════ */
.sbr-capa {
  position: absolute; inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
  /* La trama sale del tema, igual que en el login: en claro es tinta y en
     oscuro es blanca, que son dos colores distintos y no uno con otra
     opacidad. */
  background-image:
    linear-gradient(to right,  var(--sbr-linea) 1px, transparent 1px),
    linear-gradient(to bottom, var(--sbr-linea) 1px, transparent 1px);
  background-size: 34px 34px;
}
:root { --sbr-linea: rgba(20, 22, 31, 0.045); }
:root:not([data-tema="claro"]) { --sbr-linea: rgba(255, 255, 255, 0.038); }
@media (prefers-color-scheme: dark) {
  :root:not([data-tema="claro"]) { --sbr-linea: rgba(255, 255, 255, 0.038); }
}
:root[data-tema="oscuro"] { --sbr-linea: rgba(255, 255, 255, 0.038); }
:root[data-tema="claro"]  { --sbr-linea: rgba(20, 22, 31, 0.045); }

/* El contenido de la barra, por encima de la capa. */
.sidebar > *:not(.sbr-capa) { position: relative; z-index: 1; }

.sbr-celda {
  position: absolute;
  width: 34px; height: 34px;
  background: var(--accent);
  opacity: 0;
  animation: sbr-marcar 2.4s cubic-bezier(.22,.9,.28,1) forwards;
}
/* Sube rápido y baja despacio. El tope de opacidad es 0,055: por encima de eso
   se lee como un parpadeo detrás del menú, y el menú es lo que se está mirando. */
@keyframes sbr-marcar {
  0%   { opacity: 0;    transform: scale(.86); }
  16%  { opacity: .12;  transform: scale(1); }
  46%  { opacity: .12;  transform: scale(1); }
  100% { opacity: 0;    transform: scale(1); }
}

@media (prefers-reduced-motion: reduce) { .sbr-capa { display: none; } }

/* La tarjeta de "material fuera hoy" lleva dos líneas más que las otras: qué
   rodajes son, y el aviso de lo que está en borrador. Van pequeñas para que la
   cifra siga siendo lo primero que se lee. */
.stat-card .stat-sub {
  margin-top: 6px;
  font-size: 11.5px; line-height: 1.35;
  color: var(--text-soft);
}
.stat-card .stat-aviso {
  margin-top: 4px;
  font-size: 11px; font-weight: 600; line-height: 1.35;
  color: var(--mo-aviso, var(--accent));
}

/* ═══════════════════════════════════════════════════════════════════════════
   BARRA LATERAL · el hover vuelve, pero suave

   Se quitó del todo cuando lo pediste, y con motivo: el resaltado de entonces
   era un bloque claro que competía con el del elemento activo. Pero quitarlo
   entero se lleva algo que sí hacía falta: saber cuál de las diecisiete filas
   está debajo del ratón antes de pulsar. En una lista larga y estrecha, el
   puntero solo no basta — no se ve DÓNDE está sin mirar el puntero.

   Vuelve a un tercio de lo que era (0,09 → 0,03 sobre oscuro) y sin mover
   nada: ni desplazamiento ni escala. Lo justo para localizar la fila.

   El activo sigue sin cambiar bajo el ratón: si se aclarara parecería que se
   puede «activar más».
   ═══════════════════════════════════════════════════════════════════════════ */
.sidebar .nav-item:hover,
.sidebar .nav-group-items .nav-item:hover,
.sidebar .nav-fijos .nav-item:hover {
  background: var(--sb-hover-suave);
  transition: background .12s ease;
}
.sidebar .nav-item.active:hover,
.sidebar .nav-group-items .nav-item.active:hover {
  background: var(--accent);
}

:root                             { --sb-hover-suave: rgba(20, 22, 31, 0.045); }
:root:not([data-tema="claro"])    { --sb-hover-suave: rgba(255, 255, 255, 0.03); }
:root[data-tema="oscuro"]         { --sb-hover-suave: rgba(255, 255, 255, 0.03); }
:root[data-tema="claro"]          { --sb-hover-suave: rgba(20, 22, 31, 0.045); }
@media (prefers-color-scheme: dark) {
  :root:not([data-tema="claro"])  { --sb-hover-suave: rgba(255, 255, 255, 0.03); }
}

/* La fila de cifras del proyecto: cinco columnas que a según qué ancho no caben
   y cortaban la última («0 VEHÍ…»). Se reparten en dos filas antes de cortar:
   una cifra a medias no informa de nada, y el hueco vertical sobra. */
@media (max-width: 1250px) {
  .pf-cifras { grid-template-columns: repeat(3, minmax(0, 1fr)); row-gap: 14px; }
  /* Con el reparto en varias filas, la raya de separación por la izquierda
     deja de tener sentido en la primera de cada fila. */
  .pf-cifra:nth-child(3n+1) { padding-left: 0; border-left: 0; }
}
.pf-cifra { min-width: 0; }
.pf-cifra .pf-cifra-l,
.pf-cifra > span:last-child { overflow-wrap: anywhere; }

/* ═══════════════════════════════════════════════════════════════════════════
   ITV · apuntar y cerrar                                       (prefijo `.itv`)
   ═══════════════════════════════════════════════════════════════════════════ */

/* El diálogo de apuntar. Se monta desde JS y no vive en index.html: es una
   pantalla de cuatro campos y no merece estar cargada siempre. */
.itv-ov {
  position: fixed; inset: 0; z-index: 9000;
  display: grid; place-items: center;
  padding: 20px;
  background: rgba(6, 6, 9, 0.55);
  backdrop-filter: blur(2px);
}
.itv-caja {
  width: 100%; max-width: 430px;
  padding: 22px 24px 20px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--bg-card);
  box-shadow: 0 18px 50px rgba(0,0,0,.35);
}
.itv-tit { margin: 0; font-size: 18px; font-weight: 700; letter-spacing: -.01em; }
.itv-sub { margin: 6px 0 18px; font-size: 12.5px; line-height: 1.5; color: var(--text-2); }
.itv-campo { display: flex; flex-direction: column; gap: 5px; margin-bottom: 14px; min-width: 0; }
.itv-campo > span {
  font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--text-soft);
  display: flex; align-items: baseline; gap: 7px;
}
.itv-campo > span i {
  font-style: normal; font-weight: 500; letter-spacing: 0; text-transform: none;
  color: var(--text-xsoft); font-size: 10.5px;
}
.itv-campo input, .itv-campo select {
  width: 100%; height: 40px; padding: 0 11px;
  font: inherit; font-size: 14px; color: var(--text);
  background: var(--bg); border: 1px solid var(--border);
  border-radius: var(--radius-sm); outline: none;
}
.itv-campo input:focus, .itv-campo select:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 16%, transparent);
}
.itv-fila2 { display: grid; grid-template-columns: 1fr 130px; gap: 12px; }
.itv-pie { display: flex; justify-content: flex-end; gap: 9px; margin-top: 4px; }

/* ── El panel de pendientes en Tareas / ITV ─────────────────────────── */
.itv-panel {
  border: 1px solid var(--border); border-radius: 10px;
  background: var(--bg-card);
  margin-bottom: 18px; overflow: hidden;
}
.itv-panel-cab {
  display: flex; align-items: center; gap: 12px;
  padding: 13px 16px;
  border-bottom: 1px solid var(--border);
}
.itv-panel-cab h2 { margin: 0; font-size: 15px; font-weight: 700; }
.itv-panel-meta { font-size: 12.5px; color: var(--text-soft); margin-right: auto; }
.itv-panel-meta strong { color: var(--accent); }

.itv-grupo-tit {
  padding: 9px 16px 7px;
  font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--text-soft);
  background: var(--bg-hover);
}
.itv-fila {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto;
  align-items: center; gap: 12px;
  padding: 11px 16px;
  border-top: 1px solid var(--border);
}
/* La vencida se marca: es la que pide una acción, y en una lista mezclada hay
   que poder distinguirla sin leer la fecha. */
.itv-fila.vencida { background: color-mix(in srgb, var(--accent) 6%, transparent); }
.itv-fila-veh { display: flex; align-items: baseline; gap: 9px; min-width: 0; }
.itv-mat {
  font-size: 11.5px; color: var(--text-soft);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.itv-fila-cita {
  font-size: 13px; color: var(--text-2);
  display: flex; align-items: baseline; gap: 9px; min-width: 0;
}
.itv-lugar {
  font-size: 11.5px; color: var(--text-soft);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.itv-fila-acc { display: flex; gap: 7px; flex-shrink: 0; }

/* Apto y no apto NO son el mismo botón con otro texto: uno cierra el trámite y
   el otro dice que el vehículo sigue sin poder salir. Se distinguen por color
   para no pulsar el de al lado por inercia. */
.itv-apto {
  background: var(--verde, #2a9d3f); color: #fff; border: 0;
}
.itv-apto:hover { filter: brightness(1.08); }
.itv-noapto {
  background: transparent; color: var(--red, #ef233c);
  border: 1px solid color-mix(in srgb, var(--red, #ef233c) 45%, var(--border));
}
.itv-noapto:hover { background: color-mix(in srgb, var(--red, #ef233c) 10%, transparent); }

@media (max-width: 760px) {
  .itv-fila { grid-template-columns: minmax(0, 1fr); row-gap: 6px; }
  .itv-fila-acc { justify-content: flex-start; }
  .itv-fila2 { grid-template-columns: 1fr; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   FINANZAS · las opciones, más a la vista

   Eran filas de texto con un número al final. Comparar dos departamentos
   obligaba a leer los importes y restar de cabeza. Ahora cada opción lleva la
   parte que le toca del total en una barra de su color: quién se lleva el
   rodaje se ve de un golpe, que es la pregunta que se hace uno antes de
   decidir qué factura.
   ═══════════════════════════════════════════════════════════════════════════ */
.fz-op {
  grid-template-columns: 16px minmax(0, 1fr);
  align-items: center;
  padding: 11px 14px 12px;
}
.fz-op-cuerpo { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.fz-op-linea1 {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: baseline; gap: 10px;
}
.fz-op-nom { font-weight: 650; font-size: 14.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fz-op-eti {
  font-style: normal; font-size: 10px; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase;
  color: var(--fz-color, var(--accent));
  border: 1px solid color-mix(in srgb, var(--fz-color, var(--accent)) 45%, var(--border));
  border-radius: 3px; padding: 1px 5px; white-space: nowrap;
  grid-column: 2;
}
.fz-op-n   { font-size: 12px; color: var(--text-soft); white-space: nowrap; }
.fz-op-eur { font-weight: 700; font-size: 15px; min-width: 96px; text-align: right; }

/* La barra. Fondo tenue y relleno del color del subproyecto: sin el fondo no
   se sabe respecto a qué es la proporción. */
.fz-op-barra {
  display: block; height: 4px; border-radius: 2px;
  background: var(--border);
  overflow: hidden;
}
.fz-op-barra i {
  display: block; height: 100%;
  background: var(--fz-color, var(--accent));
  border-radius: 2px;
  transition: width .18s ease;
}
/* La marca de elegido toma el color del subproyecto: así el color dice a la vez
   de qué departamento es y que está elegido, sin dos señales distintas. */
.fz-op.sel { background: color-mix(in srgb, var(--fz-color, var(--accent)) 8%, var(--bg-card)); }
.fz-op.sel .fz-op-marca {
  border-color: var(--fz-color, var(--accent));
  background: var(--fz-color, var(--accent));
}

@media (max-width: 620px) {
  .fz-op-linea1 { grid-template-columns: minmax(0, 1fr) auto; row-gap: 3px; }
  .fz-op-eti { grid-column: 1; justify-self: start; }
  .fz-op-eur { grid-column: 2; grid-row: 1; }
}

/* El aviso de cambiar el nombre de usuario: va pegado al campo, porque la
   consecuencia —que esa persona entrará con el nuevo— hay que leerla ANTES de
   escribir, no después de guardar. */
.usr-aviso {
  display: block; margin-top: 5px;
  font-size: 11.5px; line-height: 1.4;
  color: var(--text-soft);
}
.usr-aviso:empty { display: none; }

/* ── La dirección de la pantalla de oficina ───────────────────────────────
   Una dirección larga con una clave dentro. En monoespaciada, porque se lee
   carácter a carácter cuando alguien la teclea en la tele. */
.pant-url { display: flex; gap: 8px; align-items: center; margin-bottom: 12px; }
.pant-url input {
  flex: 1; min-width: 0;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px; padding: 8px 11px;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border-med); border-radius: 0;
}
.pant-url input:focus { outline: none; border-color: var(--accent); }

/* El desplegable de Ajustes. `.aj-campo input` ya tenía su estilo pero no
   había ningún `select` en esa pantalla hasta el del aspecto de la pantalla de
   oficina, así que salía con el control del sistema y desentonaba con el resto
   de la columna. */
.aj-campo select {
  width: 100%; padding: 7px 10px; border-radius: 0;
  border: 1px solid var(--border-med); background: var(--surface);
  color: var(--text); font-size: 13.5px; font-family: inherit;
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--text-soft) 50%),
                    linear-gradient(135deg, var(--text-soft) 50%, transparent 50%);
  background-position: calc(100% - 15px) 50%, calc(100% - 10px) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 28px;
}
.aj-campo select:focus { outline: none; border-color: var(--accent); }
.aj-campo select:disabled { background-color: var(--surface-2); color: var(--text-soft); }

/* ═══════════════════════════════════════════════════════════════════════════
   LA BARRA LATERAL EN EL MÓVIL · defensa en profundidad

   El JS ya no aplica `collapsed` en pantalla estrecha, pero esto queda como
   red por debajo: si la clase llega por cualquier vía —una versión antigua en
   caché, un `localStorage` de antes, código futuro— la barra del móvil sigue
   siendo usable en vez de una tira de 64 px.

   Cada regla repite la especificidad de la que corrige (`.sidebar.collapsed`,
   dos clases) porque una `@media` no añade especificidad: ir después en el
   archivo solo gana si se empata en clases.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 720px) {
  .sidebar.collapsed { width: min(280px, 86vw); }
  .sidebar.collapsed .logo-text,
  .sidebar.collapsed .logo-mark,
  .sidebar.collapsed .nav-label,
  .sidebar.collapsed .sidebar-user-text { opacity: 1; width: auto; overflow: visible; }
  .sidebar.collapsed .nav-section-label,
  .sidebar.collapsed .nav-group-head { display: block; }
  .sidebar.collapsed .nav-group-items { padding: inherit; }
  .sidebar.collapsed .nav-item { justify-content: flex-start; }
  /* El rótulo flotante que sustituye a la etiqueta cuando está contraída no
     tiene sentido aquí: la etiqueta se ve. */
  .sidebar.collapsed .nav-item::after { content: none; }
  .sidebar.collapsed .sidebar-user { padding: 10px 14px; display: block; }
  .sidebar.collapsed .sidebar-logo { gap: 10px; justify-content: flex-start; }

  /* El tirador de ajustar el ancho tampoco: en el móvil el ancho lo fija la
     pantalla, y un tirador invisible pegado al borde derecho del panel roba
     los arrastres a la lista. */
  .sb-ras { display: none; }
}

/* ── La banda de "no se está guardando" ──────────────────────────────────────
   Arriba, ancho completo y por encima de todo, incluidos los modales: si no se
   está guardando, es más importante que cualquier cosa que haya abierta. No se
   puede cerrar mientras el problema siga. */
.grd-banda {
  position: fixed; top: 0; left: 0; right: 0; z-index: 99999;
  padding: 11px 18px;
  font-size: 13.5px; line-height: 1.45;
  text-align: center;
  color: #fff;
  box-shadow: 0 2px 14px rgba(0,0,0,.3);
  animation: grd-entra .2s ease;
}
.grd-banda.mal  { background: #b3132a; }
.grd-banda.bien { background: #1c8c48; }
.grd-banda strong { font-weight: 700; }
@keyframes grd-entra { from { transform: translateY(-100%) } to { transform: none } }
@media (prefers-reduced-motion: reduce) { .grd-banda { animation: none } }

/* La banda EMPUJA, no tapa. `#app` es `position: fixed; inset: 0`, así que un
   padding en el body no lo movería: hay que bajarle el borde de arriba. Sin
   esto la banda se comía la cabecera de la barra lateral y las pestañas, y un
   aviso que estorba para trabajar acaba siendo un aviso que se ignora. */
body.grd-avisando #app { top: 42px; }
@media (max-width: 720px) {
  /* En un móvil el texto ocupa dos o tres líneas. */
  body.grd-avisando #app { top: 78px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   DOS COSAS QUE EN EL MÓVIL SE SALÍAN DE LA PANTALLA

   Medido en 375 px, comprobando qué elementos quedan a la derecha del borde
   SIN un contenedor que se pueda deslizar. Casi todo lo ancho de la web —el
   calendario de flota, las tablas, el Gantt del panel— vive dentro de una caja
   con `overflow-x: auto` y se alcanza arrastrando. Estos dos, no:

   · LOS FILTROS DE PRESUPUESTOS. Son seis y miden 476 px en total: «Rechazado»
     acababa en 406 y «Anulados» en 488. En un móvil no había forma de filtrar
     por rechazados ni de ver los anulados: los botones estaban ahí, fuera de
     la pantalla, sin nada que deslizar.

   · EL BOTÓN «AÑADIR» DE FICHAS QR, que es la acción principal de esa
     pantalla, acabando en 423 px dentro de una barra de 267.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 720px) {
  /* Se desliza, y los botones no se encogen: un filtro con el texto cortado no
     se puede leer, y aquí la diferencia entre «Aceptado» y «Anulados» importa.
     `scroll-snap` para que pare en un botón entero y no a medias. */
  .seg-control {
    display: flex;
    max-width: 100%;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .seg-control::-webkit-scrollbar { display: none; }
  .seg-btn { flex: 0 0 auto; scroll-snap-align: start; }

  /* La barra de fichas envuelve en vez de empujar el botón fuera. */
  .fqr-barra { flex-wrap: wrap; }
  .fqr-barra .btn { flex: 0 0 auto; }
  .fqr-busca { flex: 1 1 100%; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   OBJETIVOS TÁCTILES EN EL MÓVIL

   Medido en 375 px: los controles de navegación se quedaban en 18 y 24 px de
   alto. Un dedo necesita unos 44; por debajo de 30 se falla a menudo, y fallar
   en «mes anterior» significa acabar en marzo cuando querías febrero.

   SOLO se agrandan los controles AISLADOS: la navegación del calendario, los
   enlaces del panel y las pestañas de filtro. Lo que está dentro de una tabla
   —los chips de categoría del inventario, las barras del mini calendario de
   proyecto— se queda como está a propósito: van pegados unos a otros, y una
   zona de toque más grande se solaparía con la del vecino y acabarías pulsando
   el de al lado. En una tabla el objetivo cómodo es la fila, no el chip.

   Se hace con relleno y alto mínimo, no con un pseudo-elemento invisible: aquí
   hay sitio de sobra en vertical y un botón que se ve del tamaño que se puede
   pulsar es mejor que uno que engaña.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 720px) {
  /* Mes anterior / mes siguiente: 24×24 → 38×38. */
  .cal-nav {
    min-width: 38px; min-height: 38px;
    display: inline-flex; align-items: center; justify-content: center;
  }

  /* Los enlaces del panel, que estaban en 18 px de alto. */
  .fleet-link { min-height: 32px; padding-top: 6px; padding-bottom: 6px; }

  /* Pestañas de filtro: 25 → 34 px, que con el deslizamiento de arriba caben
     de sobra. */
  .seg-btn,
  .topmat-tab { padding-top: 9px; padding-bottom: 9px; min-height: 34px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   EL BOTÓN DE GUARDAR, SIEMPRE A LA VISTA EN EL MÓVIL

   Medido: el formulario de un proyecto en 375 px tiene 976 px de contenido en
   una caja de 720. «Guardar» está al final, así que había que arrastrar 256 px
   hasta el fondo para encontrarlo. Se podía llegar —la caja se desplaza—, pero
   la acción principal de un formulario no debería haber que buscarla, y en un
   móvil se rellena con una mano mientras pasa algo alrededor.

   Con `sticky` se queda pegado abajo mientras se rellena el formulario y no
   ocupa sitio de más: sigue siendo la última fila del formulario, solo que no
   se va de la pantalla. El fondo tiene que ser opaco o el campo de debajo se
   leería por detrás.

   Solo en el móvil: en un ordenador el formulario cabe entero y un pie pegado
   sería una barra donde no hace falta.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 720px) {
  .modal .form-actions,
  .modal-footer {
    position: sticky;
    bottom: 0;
    z-index: 2;
    margin-top: 16px;
    /* El relleno negativo a los lados compensa el del modal, para que la barra
       llegue de borde a borde y no queden dos franjas transparentes. */
    margin-left: -18px; margin-right: -18px;
    padding: 12px 18px;
    background: var(--surface);
    border-top: 1px solid var(--border);
    box-shadow: 0 -6px 14px rgba(0,0,0,.16);
  }
  /* Los dos botones al mismo ancho: con el pulgar se acierta mejor en dos
     mitades iguales que en dos botones de tamaños distintos. */
  .modal .form-actions .btn,
  .modal-footer .btn { flex: 1 1 0; min-height: 42px; justify-content: center; }
}

/* Las dos direcciones de la pantalla de oficina, una por tele. */
.pant-bloque { margin-bottom: 18px; }
.pant-bloque:last-of-type { margin-bottom: 14px; }
.pant-etq {
  font-size: 11px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--text-soft); margin-bottom: 6px;
}
.pant-explica { font-size: 12px; color: var(--text-xsoft); line-height: 1.5; margin-top: -6px; }

/* ═══════════════════════════════════════════════════════════════════════════
   MI PERFIL · el patrón de un perfil de verdad              (prefijo `.ig`)

   Las medidas salen de Instagram en escritorio porque están bien resueltas y
   porque son las que hacen que se reconozca de un vistazo: foto de 150 px con
   un hueco generoso a su derecha, el usuario en peso ligero y cuerpo grande,
   las cifras en una fila con el número en negrita, y las pestañas centradas con
   la línea ENCIMA de la activa (no debajo, que es lo que hace todo el mundo).

   Lo que cambia respecto a allí: aquí la rejilla no son fotos cuadradas de
   1080 px sino cosas con nombre, así que la casilla lleva icono, título y pie,
   y el velo del ratón enseña de qué tipo es y que se puede abrir. Y en el móvil
   la fila de cifras se va a su propia banda con líneas arriba y abajo, que es
   lo que hace la aplicación de Instagram cuando no hay ancho.
   ═══════════════════════════════════════════════════════════════════════════ */
.ig { max-width: 980px; margin: 0 auto; padding-bottom: 40px; }

/* ── La cabecera ─────────────────────────────────────────────────────────── */
.ig-cab {
  display: grid;
  grid-template-columns: 290px minmax(0, 1fr);
  align-items: start;
  padding: 22px 0 34px;
}

.ig-foto {
  position: relative;
  width: 150px; height: 150px;
  margin: 0 auto;
  border-radius: 50%;
  overflow: visible;
}
.ig-foto-img,
.ig-foto-ini {
  width: 150px; height: 150px; border-radius: 50%;
  object-fit: cover; display: block;
}
.ig-foto-ini {
  display: grid; place-items: center;
  font-family: var(--font-display);
  font-size: 58px; font-weight: 700;
  color: #fff;
  /* Del acento a un tono más oscuro: un círculo de color plano con una letra
     dentro parece un error de carga. */
  background: linear-gradient(140deg, var(--accent), color-mix(in srgb, var(--accent) 45%, #1a1c22));
}
/* El anillo. Muy fino y del color de la casa: es lo único de la cabecera que
   dice de quién es esta aplicación. */
.ig-foto::before {
  content: ''; position: absolute; inset: -5px;
  border-radius: 50%;
  border: 1.5px solid color-mix(in srgb, var(--accent) 55%, transparent);
  pointer-events: none;
}
.ig-foto-btn {
  position: absolute; right: 2px; bottom: 2px;
  width: 34px; height: 34px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--accent); color: #fff;
  border: 3px solid var(--bg);
  cursor: pointer;
  transition: transform var(--transition);
}
.ig-foto-btn:hover { transform: scale(1.08); }

.ig-datos { padding-top: 6px; }

.ig-linea1 { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-bottom: 22px; }
.ig-user {
  margin: 0;
  font-family: var(--font-display);
  font-size: 26px; font-weight: 400;   /* ligero a propósito, como allí */
  letter-spacing: -0.01em;
  color: var(--text);
}
.ig-verif,
.ig-rol {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11.5px; font-weight: 600; letter-spacing: 0.03em;
  padding: 3px 9px; border-radius: var(--radius-pill);
}
.ig-verif { background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--accent); }
.ig-verif svg { width: 14px; height: 14px; flex: none; }
.ig-rol { background: var(--surface-2); color: var(--text-soft); }

.ig-btn {
  margin-left: auto;
  padding: 7px 16px;
  font-size: 13px; font-weight: 600; font-family: inherit;
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--border-med);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background var(--transition), border-color var(--transition);
}
.ig-btn:hover { background: var(--bg-hover); border-color: var(--border-strong); }

/* Las tres cifras. Número y palabra en la MISMA línea, que es lo que las hace
   reconocibles: en dos líneas serían tres tarjetas de panel. */
.ig-cifras { display: flex; gap: 34px; margin-bottom: 20px; flex-wrap: wrap; }
.ig-cifra { display: flex; align-items: baseline; gap: 6px; font-size: 15px; }
.ig-cifra b {
  font-weight: 700; color: var(--text);
  font-variant-numeric: tabular-nums;
}
.ig-cifra span { color: var(--text-soft); }

.ig-bio { max-width: 60ch; }
.ig-nombre { font-size: 15px; font-weight: 700; color: var(--text); }
.ig-cargo  { font-size: 14px; color: var(--text-soft); margin-top: 1px; }
.ig-texto  { font-size: 14px; color: var(--text); line-height: 1.5; margin: 7px 0 0; }
.ig-tel    { font-size: 13.5px; color: var(--text-soft); margin-top: 6px; font-variant-numeric: tabular-nums; }
.ig-vacio  { color: var(--text-xsoft); font-style: italic; }

/* ── Las pestañas ────────────────────────────────────────────────────────── */
.ig-tabs {
  display: flex; justify-content: center; gap: 56px;
  border-top: 1px solid var(--border);
  margin-bottom: 4px;
}
.ig-tab {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 17px 4px 0;
  margin-top: -1px;                    /* la línea de la activa tapa la de arriba */
  border: none; border-top: 1.5px solid transparent;
  background: none; cursor: pointer;
  font-family: var(--font-display);
  font-size: 11.5px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--text-soft);
  /* SIN transición en el borde. La tenía, y la línea de la pestaña activa se
     quedaba UN PASO POR DETRÁS: pulsabas «Actividad» y la línea seguía sobre
     «Rodajes». Medido cambiando de pestaña y leyendo el color calculado: la
     clase se movía bien y el estilo iba con retraso de uno.
     En el original tampoco hay transición aquí — la línea salta, y salta bien:
     es un indicador de dónde estás, no una animación. */
  transition: color var(--transition);
}
.ig-tab svg { width: 13px; height: 13px; flex: none; }
.ig-tab i {
  font-style: normal; font-weight: 700; letter-spacing: 0;
  color: var(--text-xsoft);
}
.ig-tab:hover { color: var(--text); }
.ig-tab.activa { color: var(--text); border-top-color: var(--text); }
.ig-tab.activa i { color: var(--accent); }

.ig-panel { display: none; padding-top: 26px; }
.ig-panel.visible { display: block; }

/* ── La rejilla de cosas ─────────────────────────────────────────────────── */
.ig-rejilla {
  display: grid;
  /* Allí son TRES columnas porque el contenido es la foto y una foto grande se
     mira. Aquí el contenido es un nombre y un código: con tres columnas en 980
     px salían casillas de 325 px con un icono en medio y mucho vacío alrededor.
     Con `auto-fill` caben cinco de 190, que es la densidad de una rejilla de
     verdad y deja ver de un vistazo todo lo que uno tiene. */
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: 4px;                            /* el gap de Instagram, no un gap de tarjetas */
}
.ig-rejilla-ancha { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 10px; }

.ig-casilla {
  position: relative;
  aspect-ratio: 1;                     /* cuadrada, como una publicación */
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 9px; padding: 18px 14px;
  background: var(--surface); border: none;
  font-family: inherit; text-align: center; cursor: pointer;
  overflow: hidden;
}
.ig-casilla-ico { color: var(--text-xsoft); transition: color var(--transition); }
.ig-casilla-ico svg { width: 30px; height: 30px; }
.ig-casilla-tit {
  font-size: 13.5px; font-weight: 600; color: var(--text); line-height: 1.3;
  /* Dos líneas y a partir de ahí puntos: los nombres de material son largos
     («ARRI Ria 1 + ARRI 2400 Orange Modules») y no pueden romper la cuadrícula. */
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.ig-casilla-pie {
  font-family: var(--font-mono);
  font-size: 11px; color: var(--text-soft);
}
/* El velo del ratón, como al pasar por una foto: aparece de qué es y que se
   puede abrir. En una pantalla táctil no hay ratón, así que ahí se queda el
   contenido normal, que ya se lee. */
.ig-casilla-velo {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  /* Bastante opaco: al .82 se leía el nombre por debajo y las dos capas de
     texto competían. */
  background: rgba(10,11,14,.94);
  opacity: 0;
  transition: opacity var(--transition);
}
.ig-casilla:hover .ig-casilla-velo,
.ig-casilla:focus-visible .ig-casilla-velo { opacity: 1; }
.ig-casilla:hover .ig-casilla-ico { color: var(--accent); }
.ig-casilla-clase {
  font-family: var(--font-display);
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
  color: #fff;
}
.ig-casilla-ver { font-size: 12px; color: rgba(255,255,255,.72); }
@media (hover: none) { .ig-casilla-velo { display: none; } }

/* Un rodaje: no es cuadrado porque lleva tres líneas de texto y un nombre de
   proyecto no cabe en una casilla de 100 px. */
.ig-rodaje {
  position: relative;
  display: flex; flex-direction: column; align-items: flex-start; gap: 3px;
  padding: 15px 16px 15px 19px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-md);
  font-family: inherit; text-align: left; cursor: pointer;
  transition: border-color var(--transition), background var(--transition);
}
.ig-rodaje::before {
  content: ''; position: absolute; left: 0; top: 0; bottom: 0;
  width: 4px; border-radius: var(--radius-md) 0 0 var(--radius-md);
  background: var(--col);
}
.ig-rodaje:hover { border-color: var(--border-strong); background: var(--bg-hover); }
.ig-rodaje-rol {
  font-family: var(--font-display);
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--text-soft);
}
.ig-rodaje-nom { font-size: 16px; font-weight: 650; color: var(--text); }
.ig-rodaje-fechas { font-size: 12.5px; color: var(--text-xsoft); font-variant-numeric: tabular-nums; }

/* ── El feed de actividad ────────────────────────────────────────────────── */
.ig-feed { list-style: none; margin: 0; padding: 0; }
.ig-post {
  display: grid; grid-template-columns: 92px minmax(0, 1fr) auto;
  gap: 14px; align-items: baseline;
  padding: 12px 2px;
  border-bottom: 1px solid var(--border);
  font-size: 13.5px;
}
.ig-post:last-child { border-bottom: none; }
.ig-post-area {
  font-family: var(--font-display);
  font-size: 10px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--text-soft);
}
.ig-post-txt { color: var(--text); }
.ig-post-cuando { color: var(--text-xsoft); font-size: 12.5px; white-space: nowrap; }
.ig-feed-pie { margin-top: 16px; font-size: 13px; color: var(--text-soft); }

/* ── Ajustes ─────────────────────────────────────────────────────────────── */
.ig-ajustes {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px;
  align-items: start;
}
.ig-form {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px 16px;
  padding: 20px 22px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-md);
}
.ig-form-ancha { grid-column: 1 / -1; grid-template-columns: 1fr; }
.ig-form-tit {
  grid-column: 1 / -1;
  font-family: var(--font-display);
  font-size: 11px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--text-soft);
}
.ig-campo { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.ig-ancho { grid-column: 1 / -1; }
.ig-campo > span { font-size: 12.5px; font-weight: 600; color: var(--text); }
.ig-campo > i { font-size: 11.5px; font-style: normal; color: var(--text-xsoft); line-height: 1.4; }
.ig-campo input,
.ig-campo textarea {
  width: 100%; padding: 8px 11px;
  font-family: inherit; font-size: 13.5px;
  color: var(--text); background: var(--bg);
  border: 1px solid var(--border-med); border-radius: var(--radius-sm);
}
.ig-campo textarea { resize: vertical; min-height: 68px; }
.ig-campo input:focus,
.ig-campo textarea:focus { outline: none; border-color: var(--accent); }
.ig-form-acciones { grid-column: 1 / -1; display: flex; gap: 8px; margin-top: 2px; }

/* ── Cuando no hay nada ──────────────────────────────────────────────────── */
.ig-nada { text-align: center; padding: 46px 20px 30px; max-width: 46ch; margin: 0 auto; }
.ig-nada-ico { display: block; color: var(--text-xsoft); margin-bottom: 14px; }
.ig-nada-ico svg { width: 42px; height: 42px; }
.ig-nada-tit {
  font-family: var(--font-display);
  font-size: 19px; font-weight: 650; color: var(--text); margin-bottom: 7px;
}
.ig-nada p { font-size: 13.5px; color: var(--text-soft); line-height: 1.55; margin: 0; }

/* ── Móvil ───────────────────────────────────────────────────────────────── */
@media (max-width: 860px) {
  .ig-cab { grid-template-columns: 88px minmax(0, 1fr); gap: 18px; padding: 14px 0 22px; }
  .ig-foto, .ig-foto-img, .ig-foto-ini { width: 88px; height: 88px; }
  .ig-foto-ini { font-size: 34px; }
  .ig-foto-btn { width: 28px; height: 28px; border-width: 2px; }
  .ig-user { font-size: 20px; }
  .ig-linea1 { gap: 9px; margin-bottom: 12px; }
  .ig-btn { margin-left: 0; flex: 1 1 100%; text-align: center; }

  /* Las cifras salen del bloque de datos y se ponen en su propia banda de
     borde a borde, como en la aplicación de Instagram. */
  .ig-cifras {
    grid-column: 1 / -1;
    justify-content: space-around; gap: 0;
    margin: 16px -4px 0;
    padding: 12px 0;
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
  }
  .ig-cifra { flex-direction: column; align-items: center; gap: 1px; font-size: 12.5px; text-align: center; }
  .ig-cifra b { font-size: 16px; }
  .ig-bio { grid-column: 1 / -1; margin-top: 14px; }

  /* SOLO ICONOS. Con cuatro pestañas y texto, «A tu nombre» se partía en dos
     líneas y se montaba encima del contador. La aplicación de Instagram hace
     exactamente esto en el móvil: iconos grandes y nada de texto. El nombre
     sigue estando en `aria-label` y en el `title`. */
  .ig-tabs { gap: 0; justify-content: space-around; }
  .ig-tab { flex: 1; justify-content: center; padding: 14px 2px 12px; gap: 5px; }
  .ig-tab-txt { display: none; }
  .ig-tab svg { width: 19px; height: 19px; }
  .ig-tab i { font-size: 11px; }
  .ig-rejilla { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 2px; }
  .ig-ajustes, .ig-form { grid-template-columns: 1fr; }
}
@media (max-width: 480px) {
  /* Con menos de 480 px caben dos y punto: un nombre de material de cuarenta
     letras en una casilla de 110 px no se lee. */
  .ig-rejilla { grid-template-columns: repeat(2, 1fr); }
}

/* El título «Mi Perfil» y su subtítulo, fuera. En un perfil la cabecera del
   perfil ES el título: la foto, el usuario y las cifras dicen de quién es esto
   mucho mejor que un rótulo encima. Y en un móvil ese rótulo se comía 200 px
   de los 812 antes de que empezara el contenido.
   El nombre de la sección sigue en el menú y en la pestaña. */
#page-mi-perfil > .page-header { display: none; }

/* El separador de los roles de producción en la ficha del proyecto: seis
   campos seguidos sin un rótulo que los agrupe se leen como seis cosas
   sueltas. */
.proy-roles-tit {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  margin-top: 6px; padding-top: 14px;
  border-top: 1px solid var(--border);
}
.proy-roles-tit > span {
  font-family: var(--font-display);
  font-size: 11px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--text-soft);
}
.proy-roles-tit > em {
  font-style: normal; font-size: 11.5px; color: var(--text-xsoft);
}

/* ═══════════════════════════════════════════════════════════════════════════
   A QUIÉN SE LE MANDA UN DOCUMENTO                          (prefijo `.env`)

   Antes la lista de sugeridos traía los contactos del proyecto y detrás los
   164 empleados con correo. Encontrar al que recibe el presupuesto costaba más
   que escribir el correo a mano.

   Un presupuesto se le manda a producción, y producción son tres personas que
   ya están en la ficha del proyecto. Así que esas tres van solas y grandes, y
   todo lo demás se pliega detrás de «Alguien más».
   ═══════════════════════════════════════════════════════════════════════════ */
.env-roles { display: grid; gap: 6px; margin-bottom: 10px; }
.env-rol {
  display: grid;
  grid-template-columns: 152px minmax(0, 1fr) auto;
  grid-template-areas: 'puesto nombre marca' 'puesto mail marca';
  gap: 0 12px; align-items: center;
  padding: 9px 13px;
  text-align: left; font-family: inherit; cursor: pointer;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border-med); border-radius: var(--radius-sm);
  transition: border-color var(--transition), background var(--transition);
}
.env-rol:hover:not(:disabled) { border-color: var(--accent); background: var(--bg-hover); }
.env-rol-puesto {
  grid-area: puesto;
  font-family: var(--font-display);
  font-size: 10px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--text-soft);
}
.env-rol-nom  { grid-area: nombre; font-size: 13.5px; font-weight: 600; }
.env-rol-mail { grid-area: mail; font-size: 12px; color: var(--text-soft); }
.env-rol-marca {
  grid-area: marca;
  font-size: 15px; font-weight: 700; color: var(--accent);
  width: 20px; text-align: center;
}
/* Ya añadido: se queda visible pero apagado, para que se vea que está puesto
   en vez de desaparecer y dejar dudando si se pulsó. */
.env-rol.puesto { border-color: var(--green); background: color-mix(in srgb, var(--green) 8%, var(--surface)); cursor: default; }
.env-rol.puesto .env-rol-marca { color: var(--green); }
/* Con nombre pero sin correo: sale igualmente, porque lo que falta es el
   correo en la ficha, no la persona. */
.env-rol.sin-mail { opacity: .62; cursor: not-allowed; }
.env-rol.sin-mail .env-rol-mail { color: var(--orange); font-style: italic; }

.env-mas-abrir {
  display: flex; align-items: baseline; gap: 8px; width: 100%;
  padding: 8px 12px;
  font-family: inherit; font-size: 12.5px; font-weight: 600;
  color: var(--text-soft); background: none; cursor: pointer;
  border: 1px dashed var(--border-med); border-radius: var(--radius-sm);
}
.env-mas-abrir:hover { color: var(--text); border-color: var(--border-strong); }
.env-mas-abrir i { font-style: normal; font-weight: 400; font-size: 11.5px; color: var(--text-xsoft); }

.env-mas-caja {
  padding: 10px; margin-top: 2px;
  background: var(--surface-2); border-radius: var(--radius-sm);
}
.env-mas-busca {
  width: 100%; padding: 7px 10px; margin-bottom: 8px;
  font-family: inherit; font-size: 13px;
  color: var(--text); background: var(--bg);
  border: 1px solid var(--border-med); border-radius: var(--radius-sm);
}
.env-mas-busca:focus { outline: none; border-color: var(--accent); }
.env-mas-lista { display: grid; gap: 3px; max-height: 232px; overflow-y: auto; }
.env-mas-uno {
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  gap: 2px 10px; padding: 6px 10px;
  text-align: left; font-family: inherit; cursor: pointer;
  background: var(--surface); color: var(--text);
  border: 1px solid transparent; border-radius: var(--radius-xs);
}
.env-mas-uno:hover { border-color: var(--accent); }
.env-mas-nom    { grid-column: 1; grid-row: 1; font-size: 13px; font-weight: 600; }
.env-mas-mail   { grid-column: 1; grid-row: 2; font-size: 11.5px; color: var(--text-soft); }
/* La columna y la fila explícitas: con colocación automática el puesto se iba
   a la primera celda libre, que era la de la izquierda, y quedaba delante del
   nombre. */
.env-mas-fuente { grid-column: 2; grid-row: 1 / 3; align-self: center; font-size: 10.5px; color: var(--text-xsoft); text-transform: uppercase; letter-spacing: .05em; }
.env-mas-hay    { font-size: 11.5px; color: var(--text-xsoft); padding: 6px 2px; }
.env-mas-cerrar {
  margin-top: 6px; padding: 5px 10px;
  font-family: inherit; font-size: 12px; color: var(--text-soft);
  background: none; border: 1px solid var(--border); border-radius: var(--radius-xs);
  cursor: pointer;
}

@media (max-width: 720px) {
  /* El puesto encima del nombre: en 375 px una columna de 152 px para el
     rótulo deja el correo en dos líneas. */
  .env-rol {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: 'puesto marca' 'nombre marca' 'mail marca';
    gap: 2px 10px;
  }
}

/* ── A quién se le mandó el documento ────────────────────────────────────────
   El envío se registraba desde el principio y no se veía en ninguna parte. Es
   lo que hay que saber cuando el cliente dice que no lo ha recibido: a qué
   dirección fue y qué día. */
.pd-envios {
  margin-top: 10px; padding: 12px 15px;
  background: var(--surface-2); border-radius: var(--radius-sm);
  border-left: 3px solid var(--green);
}
.pd-envios-vacio {
  border-left-color: var(--orange);
  font-size: 12.5px; color: var(--text-soft); line-height: 1.5;
}
.pd-envios-tit {
  font-family: var(--font-display);
  font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--text-soft); margin-bottom: 9px;
}
.pd-envios-tit span { font-weight: 400; letter-spacing: 0; text-transform: none; color: var(--text-xsoft); }
.pd-envios-lista { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.pd-envio { padding-left: 11px; border-left: 2px solid var(--border-med); }
/* El último, marcado: es el que se pregunta. */
.pd-envio.ultimo { border-left-color: var(--accent); }
.pd-envio-cab { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; font-size: 12px; }
.pd-envio-cuando { font-weight: 600; color: var(--text); }
.pd-envio-quien { color: var(--text-soft); }
.pd-envio-sello {
  font-size: 10px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
  padding: 1px 6px; border-radius: var(--radius-pill);
  background: var(--surface); color: var(--text-xsoft);
}
.pd-envio-sello.ok { background: color-mix(in srgb, var(--green) 16%, transparent); color: var(--green); }
.pd-envio-dest { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 5px; }
.pd-envio-uno {
  font-size: 12px; padding: 2px 8px;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-pill);
}
.pd-envio-uno i { font-style: normal; color: var(--text-soft); }
.pd-envio-asunto { font-size: 11.5px; color: var(--text-xsoft); margin-top: 4px; }

/* ── Borrar una cuenta de Microsoft 365 ──────────────────────────────────────
   El botón se distingue del resto: «Descartar» solo esconde una fila, esto se
   lleva el correo de una persona. */
.ms-borrar { color: var(--red); margin-left: 5px; }
.ms-borrar:hover { background: color-mix(in srgb, var(--red) 12%, transparent); border-color: var(--red); }
.ms-borrar svg { margin-right: 3px; vertical-align: -1px; }

.msb-quien {
  padding: 12px 15px; margin-bottom: 14px;
  background: color-mix(in srgb, var(--red) 8%, var(--surface));
  border-left: 3px solid var(--red); border-radius: var(--radius-sm);
}
.msb-nom { font-size: 16px; font-weight: 700; }
.msb-upn { font-family: var(--font-mono); font-size: 12.5px; color: var(--text-soft); margin-top: 2px; }
.msb-pierde { margin: 0 0 12px; padding-left: 20px; font-size: 13px; line-height: 1.7; color: var(--text); }
.msb-nota { font-size: 12.5px; color: var(--text-soft); line-height: 1.55; margin: 0 0 10px; }
.msb-campo { display: flex; flex-direction: column; gap: 5px; margin-bottom: 4px; }
.msb-campo > span { font-size: 12.5px; font-weight: 600; }
.msb-campo input {
  width: 100%; padding: 9px 11px;
  font-family: var(--font-mono); font-size: 13px;
  color: var(--text); background: var(--bg);
  border: 1px solid var(--border-med); border-radius: var(--radius-sm);
}
.msb-campo input:focus { outline: none; border-color: var(--red); }
.msb-campo > i { font-size: 11.5px; font-style: normal; color: var(--text-xsoft); }
.msb-campo > i.msb-ok { color: var(--green); font-weight: 600; }
/* El botón se queda apagado hasta que la dirección coincide: es la única
   barrera real contra pulsar en la fila equivocada. */
.msb-ir:disabled { opacity: .45; cursor: not-allowed; }
.msb-ir:not(:disabled) { background: var(--red); border-color: var(--red); }

/* ── Vehículos de un rodaje sin días en el calendario ────────────────────────
   Un coche puede estar en la flota del proyecto y no tener ni una fecha: se
   añadió desde la ficha, donde no hay calendario. No es un error, pero sin
   verlo nadie sabe que ese coche no sale en ninguna planificación. */
.pf-veh-dias {
  margin-left: auto;
  font-size: 10px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
  padding: 2px 7px; border-radius: var(--radius-pill);
}
.pf-veh-dias:empty { display: none; }
.pf-veh-dias.falta  { background: color-mix(in srgb, var(--orange) 18%, transparent); color: var(--orange); }
.pf-veh-dias.pasado { background: var(--surface-2); color: var(--text-xsoft); }

.pf-flota-aviso {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  margin-top: 10px; padding: 9px 12px;
  font-size: 12.5px; color: var(--text-soft);
  background: color-mix(in srgb, var(--orange) 8%, var(--surface));
  border-left: 3px solid var(--orange); border-radius: var(--radius-sm);
}
.pf-flota-aviso:empty { display: none; }
.pf-flota-aviso b { color: var(--text); }

/* ═══════════════════════════════════════════════════════════════════════════
   FLOTA DE UN PROYECTO · agrupada, con logo y con los días

   Antes era una lista plana de tarjetas con un icono genérico y, como mucho,
   una etiqueta naranja diciendo que faltaban fechas. Faltaba justo lo que se
   va a mirar: QUÉ vehículo es (el logo lo dice antes que el nombre interno) y
   CUÁNDO está en el rodaje.

   Los grupos son las mismas categorías que los chips de Vehículos —Camión
   Pesado, Camión Ligero, Vitos…—, no una taxonomía nueva.
   ═══════════════════════════════════════════════════════════════════════════ */
.pf-flota-grupo + .pf-flota-grupo { margin-top: 16px; }

.pf-flota-grupo-tit {
  display: flex; align-items: center; gap: 7px;
  margin: 0 0 7px;
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--text-xsoft);
}
.pf-flota-grupo-tit span {
  /* El número del grupo, no un botón: mismo peso visual que el contador de las
     cabeceras de sección para que se lea como parte del epígrafe. */
  font-size: 10px; font-weight: 700; letter-spacing: 0;
  padding: 1px 6px; border-radius: var(--radius-pill);
  background: var(--surface-2); color: var(--text-soft);
}

/* La tarjeta crece: tres líneas de texto (nombre / matrícula y marca / fechas)
   piden alinear arriba y no al centro, o el logo queda flotando. */
.pf-veh { align-items: flex-start; gap: 11px; }
.pf-veh-logo { flex: 0 0 auto; }
.pf-veh-logo .veh-brand-logo-wrap,
.pf-veh-logo .veh-brand-badge { width: 40px; height: 29px; }
.pf-veh-logo .veh-brand-badge { font-size: 9.5px; }

.pf-veh-linea2 {
  display: flex; align-items: baseline; gap: 7px; flex-wrap: wrap;
  min-width: 0;
}
/* La marca puede bajar de línea: "Nissan Athleon 130.21" no cabe junto a la
   matrícula en una tarjeta de 260px y se cortaba justo en el modelo, que es la
   mitad que distingue un camión de otro. */
.pf-veh-marca { font-size: 11px; color: var(--text-xsoft); }

/* Las fechas son el dato nuevo y el que se venía a buscar: se pintan con la
   cifra tabular para que dos tarjetas seguidas se lean en columna. */
.pf-veh-fechas {
  display: block; margin-top: 3px;
  font-size: 11.5px; font-variant-numeric: tabular-nums;
}
.pf-veh-rango { color: var(--text-soft); }
.pf-veh-cargando { color: var(--text-xsoft); }
.pf-veh-sinfecha { color: var(--orange); }

/* La cuenta de días deja de ser solo un aviso y pasa a ser información
   normal: el estado neutro ya no es "invisible" sino un recuento discreto. */
.pf-veh-dias {
  margin-left: auto; margin-top: 1px;
  background: var(--surface-2); color: var(--text-soft);
  font-variant-numeric: tabular-nums;
}
.pf-veh-dias.pasado { color: var(--text-xsoft); }

/* El conductor bajo la cuenta de días, no en la misma línea: con la matrícula,
   la marca y las fechas ya hay tres cosas compitiendo por el ancho. */
.pf-veh-cond {
  align-self: flex-end; margin-top: auto;
  font-size: 11px; color: var(--text-xsoft);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 40%;
}

@media (max-width: 620px) {
  .pf-flota { grid-template-columns: 1fr; }
  .pf-veh-cond { display: none; }   /* el ancho no da para cuatro datos */
}

/* Dos acciones en la misma cabecera de sección: solo la PRIMERA empuja hacia
   la derecha. Con `margin-left:auto` en las dos, una se quedaba en el centro
   del título y la otra pegada al borde, como si no fueran pareja. */
.pf-sec-add + .pf-sec-add { margin-left: 12px; }

/* La dirección pública de la etiqueta de un dispositivo. Se enseña entera y no
   recortada: se lee en voz alta por teléfono cuando alguien llama diciendo que
   ha encontrado un equipo. */
.disp-qr-url {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 9px 12px; background: var(--surface-2); border-radius: var(--radius-sm);
  font-size: 12.5px;
}
.disp-qr-url a { color: var(--text); text-decoration: underline; text-underline-offset: 2px;
                 overflow-wrap: anywhere; }

/* ── Quién tiene cada equipo, en la lista de "elige qué imprimir" ────────────
   La lista eran ocho renglones idénticos que decían «Móvil · Apple iPhone 16»:
   se elige la etiqueta de alguien, no la de un modelo. La persona va en la
   misma línea y a la derecha, en tono suave, para que la columna del nombre
   siga leyéndose de un tirón. */
.fqr-item { grid-template-columns: 62px minmax(0, 1fr) minmax(0, auto) 22px; }
.fqr-item-sub {
  font-size: 12px; color: var(--text-soft); text-align: right;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fqr-item-sub:empty { display: none; }

/* En el panel de lo elegido no hay ancho para dos columnas de texto: ahí sí van
   una debajo de otra. */
.fqr-eleg-txt { min-width: 0; display: flex; flex-direction: column; }
.fqr-eleg-sub {
  font-size: 11.5px; color: var(--text-soft);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ═══════════════════════════════════════════════════════════════════════════
   TAREAS / ITV EN PANTALLA ESTRECHA

   La rejilla eran tres columnas fijas: `200px 260px 1fr`. Con menos de ~750 px
   de hueco las dos primeras no caben, se desbordan, y al `1fr` no le queda
   nada: en un móvil el panel de detalle medía DOS píxeles. Estaba ahí, con su
   contenido dentro, y no se veía — que es peor que no estar, porque no hay nada
   que indique que falta algo.

   Se reparte en dos pasos, no en uno: a media pantalla los dos listados siguen
   cabiendo lado a lado y solo baja el detalle; en el móvil, todo en columna.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 1080px) {
  .flt-body {
    grid-template-columns: minmax(0, 200px) minmax(0, 1fr);
  }
  /* El detalle pasa a la fila de abajo, a todo el ancho: es donde se marcan las
     tareas y es lo que más sitio necesita. */
  .flt-detail { grid-column: 1 / -1; min-height: 260px; }
}

@media (max-width: 720px) {
  .flt-body { grid-template-columns: minmax(0, 1fr); }
  .flt-detail { grid-column: auto; }
  /* SIN techo de altura. Lo primero que puse fue `max-height: 40vh` en los dos
     listados, y como llevan `overflow: hidden` en su regla base, eso cortaba
     14 px de la última fila. Y aunque no cortara: una lista con su propio
     scroll dentro de una página que también se desplaza es de lo peor que se
     puede hacer en un móvil, porque el dedo nunca sabe a quién le está
     hablando. Aquí las tres cajas crecen y se desplaza la página. */
  .flt-projects, .flt-sidebar { max-height: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   EL FILTRO SEGMENTADO SE DESLIZA SIEMPRE QUE HAGA FALTA, NO SOLO EN MÓVIL

   Ya había una regla para esto, pero colgaba de `@media (max-width: 720px)`, y
   el que manda aquí no es el ancho de la PANTALLA sino el del CONTENEDOR: con
   la ventana a 768 px la barra lateral se lleva 200 y al filtro le quedan 470,
   así que "Todos · Borrador · Enviado · Aceptado · Rechazado · Anulados" pide
   476 y "Anulados" quedaba cortado por el `overflow: hidden` del panel. Justo
   por encima del punto de corte, que es donde nadie mira.

   Sin media query: cuando cabe no pasa nada —`overflow-x: auto` no dibuja
   barra si no hay nada que desplazar— y cuando no cabe, se desliza. Una regla
   que se cumple sola vale más que un punto de corte bien elegido.
   ═══════════════════════════════════════════════════════════════════════════ */
.seg-control {
  max-width: 100%;
  overflow-x: auto;
  scrollbar-width: none;
}
.seg-control::-webkit-scrollbar { display: none; }
/* Los botones NO se encogen: un filtro con el texto a medias no se puede leer,
   y aquí la diferencia entre "Aceptado" y "Anulados" importa. */
.seg-btn { flex: 0 0 auto; }

/* ═══════════════════════════════════════════════════════════════════════════
   EL BOTÓN DE AYUDA DE CADA PANTALLA

   Lleva al apartado del manual que corresponde, en stokit.es. Es discreto a
   propósito: tiene que estar donde se busca cuando hace falta y no competir con
   la acción principal de la pantalla, que casi siempre es el botón rojo de al
   lado.
   ═══════════════════════════════════════════════════════════════════════════ */
.ayuda-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 11px;
  font-size: 12.5px; font-weight: 500; line-height: 1;
  color: var(--text-soft); text-decoration: none;
  border: 1px solid var(--border); background: none;
  white-space: nowrap;
}
.ayuda-btn:hover { color: var(--text); border-color: var(--text-xsoft); }
.ayuda-btn svg { width: 14px; height: 14px; flex-shrink: 0; }

/* En estrecho se queda el icono: el texto «Ayuda» es lo primero que se puede
   ceder cuando la cabecera empieza a apretar. */
@media (max-width: 720px) {
  .ayuda-btn span { display: none; }
  .ayuda-btn { padding: 6px 8px; }
}

/* Un enlace del menú que sale FUERA de la aplicación. La flechita lo dice
   antes de pulsar: abrir una pestaña nueva sin avisar desconcierta, y aquí
   además el destino es otra web. */
.nav-item-fuera .nav-fuera-ico {
  width: 11px; height: 11px; margin-left: auto; flex-shrink: 0;
  color: var(--text-xsoft); opacity: .75;
}
.nav-item-fuera:hover .nav-fuera-ico { opacity: 1; color: var(--text-soft); }
/* Con la barra estrecha solo quedan los iconos y la flecha no cabe. */
.sidebar.collapsed .nav-item-fuera .nav-fuera-ico { display: none; }

/* ═══════════════════════════════════════════════════════════════════════════
   INSTALADA EN EL IPHONE: LAS ZONAS SEGURAS

   Con `viewport-fit=cover` y la barra de estado translúcida, la página llega a
   los bordes del teléfono y queda POR DEBAJO de la muesca y de la barra de
   inicio. Eso es lo que hace que parezca una aplicación y no una web con dos
   franjas negras.

   El precio es que hay que apartarse de esas dos zonas a mano, y si no se hace:
     · la barra de pestañas se mete debajo del reloj y no se lee la hora ni las
       pestañas;
     · el pie de la barra lateral —«Cerrar sesión»— cae debajo de la barra de
       inicio, donde el dedo no pulsa el botón sino que hace el gesto de salir de
       la aplicación.

   `env(safe-area-inset-*)` vale 0 en cualquier navegador de escritorio y en
   Android, así que estas reglas NO cambian nada fuera del iPhone. No van dentro
   de un `@media`: no hay ninguno que diga «iPhone con muesca», y el propio
   `env()` ya es la condición.

   NOTA sobre la de ARRIBA: con la barra de estado en `default` —que es lo que
   se usa, porque `black-translucent` pinta la hora siempre en blanco y esta
   aplicación tiene tema claro— iOS reserva la barra y `safe-area-inset-top`
   vale 0. Las reglas de arriba se quedan porque no cuestan nada y porque el día
   que se cambie de idea ya están; las que trabajan de verdad hoy son las de
   ABAJO y las de los LADOS, y esas hacen falta en cualquier caso: la barra de
   inicio y el borde curvo están ahí con cualquier estilo de barra de estado.
   ═══════════════════════════════════════════════════════════════════════════ */

/* El fondo de la propia página, para que al rebotar el scroll no aparezca
   blanco por los bordes. */
html { background: var(--bg); }

/* Arriba: la barra de pestañas baja lo que mida la muesca. Es el primer
   elemento de la columna, así que apartarla aparta todo lo de debajo.

   Y CRECE lo mismo. Su altura está clavada en 45 px a propósito —para que la
   página no dé un salto al cerrar la última pestaña—, así que con solo poner el
   relleno el contenido se sale de la caja: probado con las medidas de un
   iPhone 15 Pro, la primera pestaña acababa entre 50 y 68 px, o sea DENTRO de
   la muesca, que es exactamente lo que se quería evitar.

   La altura sigue siendo fija: la muesca de un teléfono no cambia, así que
   45 px + la muesca es igual de constante y la página sigue sin saltar. */
.tabbar {
  padding-top: env(safe-area-inset-top);
  height:     calc(45px + env(safe-area-inset-top));
  min-height: calc(45px + env(safe-area-inset-top));
  flex-basis: calc(45px + env(safe-area-inset-top));
}

/* Si no hay pestañas abiertas, la barra no se pinta y quien tiene que apartarse
   es el contenido. */
.main-scroll { padding-top: calc(28px + env(safe-area-inset-top)); }
.tabbar + .main-scroll { padding-top: 28px; }

/* Abajo y a los lados: el contenido no se pega al borde curvo de la pantalla. */
.main-scroll {
  padding-bottom: calc(28px + env(safe-area-inset-bottom));
  padding-left:  calc(30px + env(safe-area-inset-left));
  padding-right: calc(30px + env(safe-area-inset-right));
}

/* La barra lateral: arriba el logo se aparta de la muesca y abajo «Cerrar
   sesión» se aparta de la barra de inicio. */
.sidebar { padding-top: env(safe-area-inset-top); }
.sidebar-salir { padding-bottom: calc(10px + env(safe-area-inset-bottom)); }

/* En móvil la barra lateral es un panel que entra desde la izquierda: también
   tiene que respetar el borde izquierdo. */
@media (max-width: 860px) {
  .sidebar { padding-left: env(safe-area-inset-left); }
  .main-scroll {
    padding-left:  calc(16px + env(safe-area-inset-left));
    padding-right: calc(16px + env(safe-area-inset-right));
  }
}

/* Lo que va pegado abajo por su cuenta sube lo mismo. El aviso de guardado va
   ARRIBA, así que baja. (La primera versión de esto nombraba tres clases que no
   existen —`.sidebar-logout`, `.banda-guardado`, `.toast-caja`—: las escribí de
   memoria en vez de mirarlas, y una regla sobre una clase inexistente no falla,
   simplemente no hace nada, que es la peor forma de equivocarse en CSS.) */
.toast { bottom: calc(22px + env(safe-area-inset-bottom)); }
.grd-banda { padding-top: calc(10px + env(safe-area-inset-top)); }

/* INSTALADA, ADEMÁS: sin selección accidental de texto al mantener pulsado, que
   en un móvil es lo que sale en vez del menú que esperabas; y sin el resaltado
   azul de iOS al tocar, que delata que es una web. El texto de las tablas y de
   las fichas SÍ se puede seleccionar: copiar un número de serie o una matrícula
   es algo que se hace a diario. */
@media (display-mode: standalone) {
  body { -webkit-tap-highlight-color: transparent; }
  .sidebar, .tabbar, .nav-item, .btn, .page-header { -webkit-user-select: none; user-select: none; }
  /* El rebote elástico de iOS en el cuerpo hace que la aplicación entera se
     mueva y asome el fondo. El scroll vive en `.main-scroll`, así que el cuerpo
     no tiene por qué desplazarse. */
  html, body { overscroll-behavior-y: none; }
}

/* La fila de «ver más» de la tabla de inventario. Centrada y sin los bordes de
   una fila de datos: no es un ítem, es un control. */
.inv-tabla-mas td {
  text-align: center; padding: 14px 10px;
  background: var(--surface-2); border-bottom: 0;
}
.inv-tabla-mas-n {
  margin-left: 10px; font-size: 12.5px; color: var(--text-soft);
  font-variant-numeric: tabular-nums;
}

/* El botón de borrar un proyecto. En rojo solo al pasar por encima: en la
   cabecera de la ficha convive con "Editar" y "+ Presupuesto", y un botón rojo
   permanente al lado de la acción principal se pulsa por error. */
.pf-borrar { color: var(--text-soft); }
.pf-borrar:hover { color: var(--red); border-color: var(--red); }

/* ═══════════════════════════════════════════════════════════════════════════
   EL TIRADOR DE LA BARRA LATERAL — la línea roja vertical

   "Mira cómo se ve... ¿arreglamos este bug?", con una raya roja de arriba
   abajo pegada al borde del menú. No era un solape ni un desborde: era este
   tirador, y llevaba dos fallos encima.

   1. NO SE PODÍA AGARRAR. La regla que levanta el contenido de la barra por
      encima de la trama decorativa —`.sidebar > *:not(.sbr-capa)`— le pegaba
      también al tirador, y su `position: absolute` es lo único que lo sostiene.
      Convertido en `relative` pasaba a ser un hijo más de la columna: 6 px de
      ancho y CERO de alto, al final de la barra. La función llevaba muerta
      desde que se añadió la trama, sin dar error y sin que nada la probara.

   2. LA LÍNEA SE QUEDABA ENCENDIDA. `body.sb-ajustando` la pone a opacidad 1,
      y esa clase se quitaba sólo con un `pointerup` en el propio tirador. Un
      arrastre que acabe en otro sitio la deja puesta para siempre. Y no es
      cosmética: además de la raya, pone el cursor de redimensionar en toda la
      aplicación y desactiva la selección de texto. Se arregla en el JS.

   Y el color. Rojo de marca, de arriba abajo, en el borde del menú, se lee como
   un aviso —que es justo lo que pasó—. El rojo se queda sólo para el instante
   del arrastre; al pasar por encima y al enfocar con el teclado, gris fuerte:
   dice "esto se puede mover" sin decir "algo va mal".
   ═══════════════════════════════════════════════════════════════════════════ */
.sidebar > .sb-ras { position: absolute; z-index: 40; }

.sb-ras::after { background: var(--border-strong); }
.sb-ras:hover::after { opacity: 0.55; }
.sb-ras:focus-visible::after { opacity: 1; }
body.sb-ajustando .sb-ras::after { background: var(--accent); opacity: 1; }

/* ═══════════════════════════════════════════════════════════════════════════
   LA RAYA ROJA AL PULSAR «EDITAR»

   "Este fallo aparece cuando le damos al botón de editar proyecto. Si entramos
   normal no."

   La marca de "estás editando" era una sombra interior en el contenedor de la
   ficha:

     .pf-editando { box-shadow: inset 3px 0 0 var(--red); }

   Con dos problemas, y el segundo es el que se ve:

   1. El contenedor de la ficha mide MÁS DE MIL DOSCIENTOS PÍXELES de alto —es
      toda la ficha, con sus cifras, sus pestañas y su cuerpo—. Una marca de
      3 px en su borde izquierdo no se lee como "estás editando": se lee como
      una raya roja de punta a punta, o sea, como algo roto.
   2. `inset` pinta HACIA DENTRO, y el contenedor no reserva hueco
      (`padding-left: 0`). El primer campo empieza exactamente en el borde, así
      que la raya se pinta ENCIMA del texto: por eso se cortaban «24.963,51 €»
      y «PRESUPUESTADO».

   La marca se va al bloque de campos, que es lo que de verdad se está
   editando: 416 px en vez de 1.219, con su hueco para no comerse nada, y con
   el `border-left` que ya usa el resto de la aplicación para señalar un bloque
   (las revisiones pendientes, los avisos de licencias). El modo se sigue
   notando por lo que importa: los campos son cajas de texto, las filas
   editables están teñidas y los botones dicen «Cancelar» y «Guardar».
   ═══════════════════════════════════════════════════════════════════════════ */
.pf-editando { box-shadow: none; }
.pf-editando .pf-datos {
  border-left: 3px solid var(--accent);
  padding-left: 13px;
}

/* Lo mismo en la ficha de material, que llevaba el fallo calcado: la marca de
   edición era una sombra interior en el contenedor entero. Aquí la rejilla de
   datos va a hueso —`gap: 1px` sobre el color del borde—, así que la marca es
   sólo el `border-left`, sin hueco: un borde de verdad empuja el contenido
   hacia dentro en vez de pintarse encima, que es justo lo que hacía mal el
   `inset box-shadow`. */
.mat-editando { box-shadow: none; }
.mat-editando .mat-datos { border-left: 3px solid var(--accent); }

/* ═══════════════════════════════════════════════════════════════════════════
   LA COLUMNA «DOCUMENTACIÓN» DE LA TABLA DE VEHÍCULOS

   "¿Por qué se ve tan separado y mal?"

   Porque la celda era `display: flex`. Un `<td>` con `display: flex` DEJA DE
   SER UNA CELDA DE TABLA, y se le cae encima todo lo que eso implica:

     · No se estira a la altura de la fila. Medido: 61 px la de documentación,
       82 px todas las demás de la misma fila. Su borde inferior se dibuja 21 px
       más arriba que el del resto — de ahí la raya corta a media fila que no
       llega al ancho de la tabla.
     · No cuenta para el reparto de anchos de las columnas, así que la de al
       lado se queda sin sitio y «120.000 km» se parte en dos líneas.
     · Y el contenido queda flotando en medio de una fila alta, que es lo que
       se lee como "separado".

   El `flex` no hacía falta para nada: `.veh-doc-linea` ya es `display: flex`,
   o sea de nivel bloque, así que las dos líneas se apilan solas. Lo único que
   aportaba era el `gap`, y eso se resuelve con un margen entre líneas.
   ═══════════════════════════════════════════════════════════════════════════ */
.tabla-veh .veh-doc {
  display: table-cell;
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
}
.tabla-veh .veh-doc .veh-doc-linea + .veh-doc-linea { margin-top: 1px; }

/* ═══════════════════════════════════════════════════════════════════════════
   BORRAR UNA LISTA DE TAREAS DESDE SU TARJETA

   "En Tareas / ITV, en los proyectos creados para apuntar cosas se tienen que
    poder eliminar."

   Se podía: había un «Eliminar» en la cabecera del DETALLE de la lista. El
   problema es dónde caía. Medido con el panel de ITV arriba y las dos columnas
   debajo, el botón quedaba en y=864 de una ventana de 900: había que
   seleccionar la lista y luego bajar hasta el final de la página a buscarlo.
   Un botón que existe y no se encuentra es un botón que no existe.

   Ahora está en la propia tarjeta, que es donde se mira cuando quieres quitar
   una lista. Y SIEMPRE VISIBLE, no al pasar el ratón: descubrir un botón
   pasando por encima es el mismo problema de antes, y en el móvil —donde esto
   se usa— no hay «pasar por encima». Apagado en gris, rojo solo al apuntarlo.
   ═══════════════════════════════════════════════════════════════════════════ */
.flt-list-item-top { display: flex; align-items: center; gap: 8px; }
.flt-list-item-top .flt-list-item-name { flex: 1; min-width: 0; }
.flt-list-del {
  flex-shrink: 0;
  border: 0; background: none; padding: 3px; margin: -3px -7px -3px 0;
  border-radius: 5px; line-height: 0; cursor: pointer;
  color: var(--text-xsoft); opacity: 0.5;
  transition: opacity 0.12s, color 0.12s, background 0.12s;
}
.flt-list-item:hover .flt-list-del { opacity: 0.8; }
.flt-list-del:hover {
  opacity: 1; color: var(--red);
  background: color-mix(in srgb, var(--red) 12%, transparent);
}
.flt-list-del:focus-visible { opacity: 1; outline: 2px solid var(--accent); outline-offset: 1px; }

/* ═══════════════════════════════════════════════════════════════════════════
   BIBLIOTECA DE CORREOS  (prefijo `.co-`)

   Rejilla con miniatura y no una lista, porque lo que se busca es «el del
   WireGuard» y eso se reconoce por la pinta antes que leyendo un asunto. La
   miniatura es la primera imagen del correo; cuando no hay ninguna se pinta el
   principio del texto, que para un manual dice bastante.
   ═══════════════════════════════════════════════════════════════════════════ */
.co-barra { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.co-busca {
  flex: 1; max-width: 420px;
  padding: 8px 12px; font-family: inherit; font-size: 13.5px;
  color: var(--text); background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.co-busca:focus { outline: none; border-color: var(--accent); }
.co-cuenta { font-size: 12.5px; color: var(--text-soft); }

/* La zona de soltar es toda la rejilla, no un recuadro aparte: se arrastra el
   correo desde Outlook y se suelta donde están los demás. */
.co-zona {
  border: 2px dashed transparent; border-radius: var(--radius);
  transition: border-color 0.12s, background 0.12s;
  min-height: 160px;
}
.co-zona.co-encima {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 6%, transparent);
}

.co-rejilla {
  display: grid; gap: 14px;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
}
.co-card {
  display: flex; flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius);
  overflow: hidden; cursor: pointer;
  transition: border-color 0.12s, box-shadow 0.12s, transform 0.12s;
}
.co-card:hover {
  border-color: var(--border-strong);
  box-shadow: var(--shadow-sm);
  transform: translateY(-1px);
}
.co-thumb {
  height: 132px; background: var(--surface-sunk);
  border-bottom: 1px solid var(--border);
  display: flex; align-items: flex-start; justify-content: center; overflow: hidden;
}
.co-thumb img { width: 100%; height: 100%; object-fit: cover; object-position: top center; }
.co-thumb-txt {
  padding: 12px 13px; font-size: 11px; line-height: 1.5;
  color: var(--text-soft); overflow: hidden;
}
.co-card-cuerpo { padding: 11px 13px; flex: 1; display: flex; flex-direction: column; gap: 4px; }
.co-card-tit {
  margin: 0; font-size: 13.5px; font-weight: 650; color: var(--text); line-height: 1.35;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.co-card-asunto {
  margin: 0; font-size: 11.5px; color: var(--text-soft);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.co-card-pie {
  display: flex; flex-wrap: wrap; gap: 4px 9px; margin-top: auto;
  font-size: 11px; color: var(--text-xsoft); font-variant-numeric: tabular-nums;
}
.co-adj { color: var(--text-soft); }
.co-etqs { display: flex; flex-wrap: wrap; gap: 4px; }
.co-etq {
  padding: 1px 7px; border-radius: 999px;
  background: var(--bg-hover); font-size: 10.5px; color: var(--text-soft);
}
.co-card-acc {
  display: flex; gap: 6px; padding: 0 13px 12px;
}
.co-vacio {
  padding: 34px 18px; font-size: 13.5px; line-height: 1.65; color: var(--text-soft);
}
.co-vacio code {
  font-family: var(--font-mono); font-size: 12.5px;
  padding: 1px 5px; border-radius: 4px; background: var(--bg-hover);
}
.co-vacio-como { margin-top: 10px; font-size: 12.5px; color: var(--text-xsoft); }

/* ── El visor ──────────────────────────────────────────────────────────── */
.co-ov {
  position: fixed; inset: 0; z-index: 9000;
  background: rgba(10,11,15,0.55);
  display: flex; align-items: center; justify-content: center; padding: 22px;
}
.co-visor {
  display: flex; flex-direction: column;
  width: min(920px, 100%); max-height: 90vh;
  background: var(--surface); border-radius: var(--radius);
  box-shadow: 0 18px 60px rgba(0,0,0,0.35); overflow: hidden;
}
.co-visor-cab {
  display: flex; align-items: flex-start; gap: 14px;
  padding: 15px 18px; border-bottom: 1px solid var(--border);
}
.co-visor-cab h2 { margin: 0; font-size: 16px; font-weight: 700; color: var(--text); }
.co-visor-cab p { margin: 3px 0 0; font-size: 12.5px; color: var(--text-soft); }
.co-visor-acc { margin-left: auto; display: flex; gap: 7px; flex-shrink: 0; }
.co-visor-adj {
  display: flex; flex-wrap: wrap; gap: 6px;
  padding: 9px 18px; border-bottom: 1px solid var(--border);
  background: var(--surface-sunk);
}
.co-visor-adj span {
  font-size: 11.5px; color: var(--text-soft);
  padding: 2px 8px; border: 1px solid var(--border); border-radius: 999px;
}
/* El cuerpo del correo va sobre BLANCO y no sobre el tema: un correo se
   escribió para fondo blanco, y pintarlo sobre el fondo oscuro deja texto
   negro sobre negro. */
.co-visor-cuerpo { flex: 1; min-height: 0; background: #fff; }
.co-visor-cuerpo iframe { width: 100%; height: 100%; min-height: 420px; border: 0; display: block; }

/* Los botones de la tarjeta se envuelven en vez de cortarse.

   Al añadir «Fichero» quedaron tres en una tarjeta de 230 px y el tercero
   salía partido por la mitad. Se quitó el tercero, pero la regla se queda como
   red: el día que alguien añada otro botón o traduzca una etiqueta a algo más
   largo, la fila pasa a dos líneas en vez de cortar nada. */
.co-card-acc { flex-wrap: wrap; }

/* ═══════════════════════════════════════════════════════════════════════════
   DASHBOARD DE FLOTA  (prefijo `.fd-`)

   Cifras arriba en una rejilla que se adapta, el calendario en medio a ancho
   completo, y los widgets debajo en columnas. Las cifras son BOTONES cuando
   llevan a algún sitio y están apagadas cuando no: si un número no se puede
   pulsar, más vale que se note antes de intentarlo.
   ═══════════════════════════════════════════════════════════════════════════ */
.fd-cifras {
  display: grid; gap: 10px; margin-bottom: 18px;
  grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
}
.fd-cifra {
  display: flex; flex-direction: column; gap: 2px;
  padding: 12px 14px; text-align: left; font-family: inherit;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); cursor: pointer;
  transition: border-color 0.12s, box-shadow 0.12s, transform 0.12s;
}
.fd-cifra:not(:disabled):hover {
  border-color: var(--border-strong); box-shadow: var(--shadow-sm); transform: translateY(-1px);
}
.fd-cifra:disabled { cursor: default; }
.fd-cifra-n {
  font-size: 26px; font-weight: 700; line-height: 1.1; color: var(--text);
  font-variant-numeric: tabular-nums;
}
.fd-cifra-e {
  font-size: 11px; font-weight: 600; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--text-xsoft);
}
/* Rojo solo cuando el número pide hacer algo. Un cero en «ITV caducada» no es
   una alarma apagada: es una buena noticia, y se pinta en verde. */
.fd-cifra.mal .fd-cifra-n { color: var(--red); }
.fd-cifra.mal .fd-cifra-e { color: color-mix(in srgb, var(--red) 70%, var(--text-xsoft)); }
.fd-cifra.ok  .fd-cifra-n { color: #1c8c48; }

.fd-cal {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); margin-bottom: 18px; overflow: hidden;
}
.fd-cal-cab {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 13px 16px; border-bottom: 1px solid var(--border);
}
.fd-cal-cab h2 { margin: 0; font-size: 15px; font-weight: 700; color: var(--text); }
.fd-cal-nav { margin-left: auto; display: flex; align-items: center; gap: 7px; }
.fd-cal-titulo {
  min-width: 190px; text-align: center;
  font-size: 13px; font-weight: 600; color: var(--text-2);
}

.fd-widgets {
  display: grid; gap: 14px;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  align-items: start;
}
.fd-w {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); overflow: hidden;
}
.fd-w-cab {
  display: flex; align-items: center; gap: 10px;
  padding: 11px 14px; border-bottom: 1px solid var(--border);
}
.fd-w-cab h3 { margin: 0; font-size: 13px; font-weight: 700; color: var(--text); }
.fd-w-cab .btn { margin-left: auto; }
.fd-w-vacio { margin: 0; padding: 16px 14px; font-size: 12.5px; color: var(--text-soft); }

.fd-lista { margin: 0; padding: 0; list-style: none; }
.fd-lista li {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 9px 14px; font-size: 12.5px; color: var(--text-2);
  border-top: 1px solid var(--border);
}
.fd-lista li:first-child { border-top: 0; }
.fd-lista li strong { font-weight: 650; color: var(--text); }
.fd-lista li.mal   { background: color-mix(in srgb, var(--red) 5%, transparent); }
.fd-lista li.aviso { background: color-mix(in srgb, var(--orange) 8%, transparent); }
.fd-mat { font-size: 11.5px; color: var(--text-soft); }
.fd-der {
  margin-left: auto; font-size: 11.5px; color: var(--text-soft);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
/* La barra de ocupación: se lee de un vistazo cuánto tiene comprometido cada
   vehículo, que es la pregunta de «¿a quién puedo mandar la semana que viene?». */
.fd-barra {
  flex: 1; min-width: 60px; height: 6px; border-radius: 999px;
  background: var(--bg-hover); overflow: hidden;
}
.fd-barra i { display: block; height: 100%; background: var(--accent); border-radius: 999px; }
.fd-cargando { padding: 30px 4px; font-size: 13.5px; color: var(--text-soft); }

/* ═══════════════════════════════════════════════════════════════════════════
   CALENDARIO DE FLOTA · leyenda de colores mascada                  (`clv-`)

   La leyenda ahora dibuja lo mismo que la celda: un bloque de color macizo con
   el nombre encima. Es el truco por el que el Excel de producción se lee de un
   vistazo — no hay que traducir nada, el bloque de la leyenda y la barra de la
   rejilla son literalmente el mismo objeto.
   ═══════════════════════════════════════════════════════════════════════════ */

.clv-leyenda { margin: 0 0 4px; }

.clv-cabecera {
  display: flex; align-items: baseline; gap: 9px;
  flex-wrap: wrap; margin: 0 2px 8px;
}
.clv-titulo {
  font-size: 11px; font-weight: 800; letter-spacing: .09em;
  text-transform: uppercase; color: var(--text);
}
.clv-como { font-size: 12px; color: var(--text-soft); }

.clv-fila { display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-start; }

/* La tarjeta no es una tarjeta: es el bloque de color y, debajo, su letra
   pequeña. Sin marco propio, porque un marco alrededor de un color macizo
   compite con el color y le quita fuerza. */
.clv-card {
  display: flex; flex-direction: column; gap: 3px;
  padding: 0; margin: 0; border: 0; background: none;
  font: inherit; text-align: left; cursor: pointer;
  border-radius: 8px;
}
.clv-card:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

.clv-bloque {
  display: flex; align-items: center; gap: 6px;
  min-width: 96px; max-width: 190px;
  padding: 8px 13px;
  background: var(--clv-c, var(--bg-soft));
  border-radius: 6px;
  box-shadow: inset 0 0 0 1px rgb(0 0 0 / .14);
  color: #fff; font-size: 13.5px; font-weight: 700; line-height: 1.2;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  transition: transform .12s ease, box-shadow .12s ease;
}
.clv-card.clv-oscuro .clv-bloque { color: #16181d; }
.clv-card:hover .clv-bloque { transform: translateY(-1px); }

/* El pincel puesto: un aro grueso del color del texto, que contrasta con
   cualquier color de proyecto, más la palabra "Pintando" debajo. Antes era un
   borde de 1 px y se perdía de vista. */
.clv-card.puesto .clv-bloque {
  box-shadow: 0 0 0 3px var(--text), inset 0 0 0 1px rgb(0 0 0 / .14);
  transform: translateY(-1px);
}

.clv-pie {
  display: block; padding: 0 3px;
  font-size: 10.5px; color: var(--text-soft);
  font-variant-numeric: tabular-nums;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 190px; min-height: 13px;
}
.clv-marca {
  font-weight: 800; letter-spacing: .05em; text-transform: uppercase;
  color: var(--text);
}

/* ITV y Taller llevan su color relleno igual que un proyecto: son estados que
   se pintan en la misma rejilla, así que hablan el mismo idioma. */
.clv-evt .clv-bloque { text-transform: uppercase; letter-spacing: .04em; font-size: 12px; }

.clv-goma .clv-bloque {
  background: var(--bg-soft);
  color: var(--text);
  box-shadow: inset 0 0 0 1px var(--border);
}
.clv-goma.puesto .clv-bloque { box-shadow: 0 0 0 3px var(--text), inset 0 0 0 1px var(--border); }

.clv-sep {
  align-self: stretch; width: 1px; margin: 2px 5px;
  background: var(--border);
}
.clv-vacio { font-size: 13px; color: var(--text-soft); padding: 9px 3px; }

/* Los dos pasos, para quien entra por primera vez. */
.clv-pasos { display: inline-flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.clv-paso b {
  display: inline-flex; align-items: center; justify-content: center;
  width: 17px; height: 17px; margin-right: 5px;
  border-radius: 50%; background: var(--accent); color: #fff;
  font-size: 10.5px; font-weight: 800;
}
.clv-flecha { color: var(--text-soft); }
.clv-punto {
  display: inline-block; width: 10px; height: 10px; border-radius: 50%;
  margin-right: 6px; vertical-align: -1px;
  box-shadow: inset 0 0 0 1px rgb(0 0 0 / .18);
}

/* Con el pincel puesto, la rejilla entera avisa: cursor de pintar y la casilla
   vacía se tiñe del color al pasar por encima. Se ve lo que va a pasar antes
   de pulsar, que es lo que el Excel no puede hacer. */
body.cal-pintando .cal-veh-td-day { cursor: cell; }
body.cal-pintando .cal-veh-td-day:hover .cal-cell-inner:not(.filled) {
  background: var(--cal-pincel);
  opacity: .42;
}
body.cal-borrando .cal-veh-td-day { cursor: crosshair; }
body.cal-borrando .cal-veh-td-day:hover .cal-cell-inner.filled { opacity: .35; }

/* ═══════════════════════════════════════════════════════════════════════════
   CALENDARIO DE FLOTA · banda del mes, ITV unificada y remates    (`cvb-`)
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── La banda del mes ─────────────────────────────────────────────────────── */
.cvb-mes-row th {
  position: sticky; top: 0; z-index: var(--cal-z-cabecera, 40);
  height: 24px;
  background: var(--surface-2);
  border-bottom: 1px solid var(--border);
  padding: 0;
}
.cvb-mes-esq {
  position: sticky; left: 0; z-index: var(--cal-z-esquina, 50);
  background: var(--surface-2);
  border-right: 1px solid var(--border);
  text-align: left; padding: 0 8px !important;
  font-size: 9px; font-weight: 800; letter-spacing: .09em;
  text-transform: uppercase; color: var(--text-soft);
}
.cvb-mes-celda {
  border-right: 1px solid var(--border);
  text-align: left;
  overflow: hidden;
}
/* El nombre se queda pegado al borde izquierdo de su tramo: con cuatro meses y
   scroll horizontal, un nombre centrado se va de la pantalla justo cuando lo
   estás mirando. Los 190 px son el ancho de la columna de vehículos. */
.cvb-mes-txt {
  position: sticky; left: 194px;
  display: inline-block; padding: 0 4px;
  font-size: 11px; font-weight: 800; letter-spacing: .04em;
  text-transform: uppercase; color: var(--text);
  white-space: nowrap;
}
.cvb-mes-celda.cvb-ahora {
  background-color: var(--surface-2);
  background-image: linear-gradient(rgba(var(--acento-rgb), .12), rgba(var(--acento-rgb), .12));
}
.cvb-mes-celda.cvb-ahora .cvb-mes-txt { color: var(--accent); }

/* La fila de semanas deja de estar pegada arriba: ahora la de arriba es el mes.
   Dos filas `sticky top:0` se solapan. */
.cal-veh-table thead .cal-veh-th-week-row th { top: 24px; }

/* ── ITV / seguro automáticos: el MISMO dibujo que los manuales ──────────── */
/* El rayado del seguro repite el patrón de ITV y taller en violeta, que es el
   color que ya tenía su etiqueta. Un tercer dibujo distinto sería justo el
   problema que esto viene a arreglar. */
.cal-veh-td-day.cal-event-seguro .cal-cell-inner,
.cal-veh-td-day.cal-event-seguro.cal-run-solo .cal-cell-inner,
.cal-veh-td-day.cal-event-seguro.cal-run-start .cal-cell-inner,
.cal-veh-td-day.cal-event-seguro.cal-run-mid .cal-cell-inner,
.cal-veh-td-day.cal-event-seguro.cal-run-end .cal-cell-inner {
  background: repeating-linear-gradient(
    -45deg, #8b5cf6, #8b5cf6 5px, #7040dd 5px, #7040dd 10px) !important;
}
.cal-veh-td-day.cal-event-seguro .cal-cell-inner::after {
  background: linear-gradient(to bottom, rgba(0,0,0,.06), rgba(0,0,0,.16));
}

/* Una casilla de 32 px no da para escribir "ITV" sin que se corte, así que el
   texto se deja salir por encima de las casillas vecinas: el evento dura un
   día, pero su etiqueta puede medir lo que necesite. */
.cal-veh-td-day.cal-event-itv .cal-ev-txt,
.cal-veh-td-day.cal-event-seguro .cal-ev-txt,
.cal-veh-td-day.cal-event-mantenimiento .cal-ev-txt {
  font-size: 9.5px; font-weight: 800; letter-spacing: .02em;
  text-transform: uppercase;
}

/* ── El vehículo afectado, en su propia fila ─────────────────────────────── */
/* Es el único hueco de la fila donde cabe "ITV 12/09" entero, y el único donde
   se lee de quién es sin cruzar la vista por la rejilla. */
.cal-veh-itv-badge {
  display: inline-block; margin-top: 3px;
  padding: 1px 5px; border-radius: 3px;
  background: rgba(240, 160, 24, .16);
  box-shadow: inset 0 0 0 1px rgba(240, 160, 24, .45);
  color: #d98a0c;
  font-size: 9.5px; font-weight: 800; letter-spacing: .02em;
  white-space: nowrap; font-variant-numeric: tabular-nums;
}
:root[data-tema="oscuro"] .cal-veh-itv-badge { color: #f0a018; }
@media (prefers-color-scheme: dark) {
  :root:not([data-tema="claro"]) .cal-veh-itv-badge { color: #f0a018; }
}

/* ── El aro del pincel no se recorta contra el borde ─────────────────────── */
/* El aro se dibuja 3 px por FUERA del bloque. La primera tarjeta iba pegada al
   borde del contenedor, así que se le comía el aro por la izquierda y quedaba
   una rayita de color que no era nada. */
.clv-fila { padding: 3px 3px 0; margin-left: -3px; }

/* ═══════════════════════════════════════════════════════════════════════════
   CALENDARIO DE FLOTA · la chapa de los eventos                     (`cal-evt-`)

   Dos objetos distintos porque significan cosas opuestas:
     · RODAJE  → barra plana de color, nombre pegado a la izquierda. "Sale."
     · EVENTO  → chapa redondeada con icono y sombra sobre rayado de peligro,
                 y encima de un fondo apagado. "No sale."
   ═══════════════════════════════════════════════════════════════════════════ */

/* El fondo pasa de rayado saturado a rayado tenue sobre superficie apagada: el
   rayado a todo color competía con la chapa y con los colores de los rodajes,
   y era justo lo que hacía que un aviso pareciera una reserva más. */
.cal-veh-td-day.cal-event-itv .cal-cell-inner,
.cal-veh-td-day.cal-event-itv.cal-run-solo .cal-cell-inner,
.cal-veh-td-day.cal-event-itv.cal-run-start .cal-cell-inner,
.cal-veh-td-day.cal-event-itv.cal-run-mid .cal-cell-inner,
.cal-veh-td-day.cal-event-itv.cal-run-end .cal-cell-inner {
  background:
    repeating-linear-gradient(-45deg,
      rgba(240,160,24,.34) 0 5px, rgba(240,160,24,.09) 5px 10px),
    var(--surface-2) !important;
  box-shadow: inset 0 0 0 1px rgba(240,160,24,.5) !important;
}
.cal-veh-td-day.cal-event-mantenimiento .cal-cell-inner,
.cal-veh-td-day.cal-event-mantenimiento.cal-run-solo .cal-cell-inner,
.cal-veh-td-day.cal-event-mantenimiento.cal-run-start .cal-cell-inner,
.cal-veh-td-day.cal-event-mantenimiento.cal-run-mid .cal-cell-inner,
.cal-veh-td-day.cal-event-mantenimiento.cal-run-end .cal-cell-inner {
  background:
    repeating-linear-gradient(-45deg,
      rgba(232,75,75,.34) 0 5px, rgba(232,75,75,.09) 5px 10px),
    var(--surface-2) !important;
  box-shadow: inset 0 0 0 1px rgba(232,75,75,.5) !important;
}
.cal-veh-td-day.cal-event-seguro .cal-cell-inner,
.cal-veh-td-day.cal-event-seguro.cal-run-solo .cal-cell-inner,
.cal-veh-td-day.cal-event-seguro.cal-run-start .cal-cell-inner,
.cal-veh-td-day.cal-event-seguro.cal-run-mid .cal-cell-inner,
.cal-veh-td-day.cal-event-seguro.cal-run-end .cal-cell-inner {
  background:
    repeating-linear-gradient(-45deg,
      rgba(139,92,246,.34) 0 5px, rgba(139,92,246,.09) 5px 10px),
    var(--surface-2) !important;
  box-shadow: inset 0 0 0 1px rgba(139,92,246,.5) !important;
}
/* El degradado de volumen de las barras aquí ensucia el rayado. */
.cal-veh-td-day.cal-event-itv .cal-cell-inner::after,
.cal-veh-td-day.cal-event-mantenimiento .cal-cell-inner::after,
.cal-veh-td-day.cal-event-seguro .cal-cell-inner::after { background: none; }

/* La chapa. Se sale de la casilla a propósito: las celdas del calendario llevan
   `overflow: visible`, así que una etiqueta de un evento de un día puede medir
   lo que necesite en vez de cortarse a media palabra. */
.cal-evt-chapa {
  position: absolute; top: 50%;
  left: 6px; transform: translateY(-50%);
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 8px 3px 6px;
  border-radius: 999px;
  max-width: none; white-space: nowrap;
  font-size: 10.5px; font-weight: 800; letter-spacing: .045em;
  text-transform: uppercase;
  color: #1c1408;
  box-shadow: 0 1px 5px rgb(0 0 0 / .38), inset 0 0 0 1px rgb(255 255 255 / .3);
  z-index: 4; pointer-events: none;
}
/* Un evento de un solo día centra la chapa; uno de varios la arranca a la
   izquierda del tramo, como el nombre de un rodaje. */
.cal-evt-chapa.cal-evt-solo {
  left: 50%; transform: translate(-50%, -50%);
}
.cal-evt-chapa svg { flex: 0 0 auto; }

.cal-evt-itv           { background: #f6b93b; }
.cal-evt-mantenimiento { background: #ff8080; }
.cal-evt-seguro        { background: #c3a6ff; }

/* Muy alejado, la chapa entera no cabe: se queda solo el icono, que ya avisa. */
.cal-veh-table[data-z-min="1"] .cal-evt-chapa { padding: 3px; gap: 0; }
.cal-veh-table[data-z-min="1"] .cal-evt-txt { display: none; }

/* ═══════════════════════════════════════════════════════════════════════════
   /calendario · el calendario compartido a pantalla completa        (`pcal-`)

   Todo el ancho para la rejilla, como la hoja de Excel que sustituye.
   ═══════════════════════════════════════════════════════════════════════════ */

body.pcal .sidebar,
body.pcal .tabbar-fila,
body.pcal .menu-movil { display: none !important; }

/* #app es normalmente una FILA: barra lateral + contenido. Sin barra lateral el
   contenido ocupa el ancho entero y la tira se apila encima, así que pasa a
   columna. */
body.pcal #app { flex-direction: column; }
body.pcal .main { width: 100%; max-width: none; min-height: 0; }

.pcal-tira {
  display: flex; align-items: center; gap: 12px;
  height: 42px; flex: 0 0 42px;
  padding: 0 14px 0 16px;
  background: var(--surface-2);
  border-bottom: 1px solid var(--border);
  padding-top: env(safe-area-inset-top);
  box-sizing: content-box;
}
.pcal-marca {
  font-size: 12.5px; font-weight: 800; letter-spacing: .02em; color: var(--text);
}
.pcal-hueco { flex: 1; }
.pcal-quien { font-size: 12px; color: var(--text-soft); }
.pcal-enlace {
  font-size: 12px; color: var(--accent); text-decoration: none; font-weight: 600;
}
.pcal-enlace:hover { text-decoration: underline; }
.pcal-btn {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 9px; border-radius: 6px;
  border: 1px solid var(--border); background: transparent;
  color: var(--text-soft); font: inherit; font-size: 12px; cursor: pointer;
}
.pcal-btn:hover { color: var(--text); border-color: var(--border-med); }

/* La cabecera de la página pierde el aire de sección: aquí la página ES el
   calendario, no hace falta presentarlo. */
body.pcal .main-scroll { padding: 12px 14px; }
body.pcal #page-veh-calendar .page-title { font-size: 17px; }
body.pcal #page-veh-calendar .page-subtitle { display: none; }
body.pcal #page-veh-calendar .page-header { margin-bottom: 10px; }

/* Y la rejilla se come el alto que sobra. */
body.pcal .cal-veh-wrap { max-height: calc(100vh - 250px); }

/* ── La chapa del evento no puede quedar debajo del día siguiente ────────── */
/* Las casillas se pintan en orden, así que la chapa —que se sale a propósito de
   su casilla para poder leerse— quedaba tapada por la celda del día siguiente.
   Eso era el "a veces no se ve el texto completo": no se cortaba, se cubría.
   El 6 está elegido: por encima de las demás casillas (`auto`) y por debajo de
   la columna de vehículos, que va pegada a la izquierda con z-index 9 y tiene
   que seguir tapando lo que pase por detrás. */
.cal-veh-td-day.cal-event-itv,
.cal-veh-td-day.cal-event-mantenimiento,
.cal-veh-td-day.cal-event-seguro { z-index: 6; }

/* Y un borde oscuro alrededor de la chapa: cuando se solapa con la barra de un
   rodaje vecino, hace falta algo que la separe del color de debajo. */
.cal-evt-chapa {
  box-shadow: 0 1px 5px rgb(0 0 0 / .45), 0 0 0 1px rgb(0 0 0 / .3),
              inset 0 0 0 1px rgb(255 255 255 / .3);
  padding: 3px 7px 3px 5px;
  font-size: 10px; letter-spacing: .03em;
}

/* ── El botón «Ayuda» no se estira a lo ancho de la cabecera ─────────────── */
/* En pantalla estrecha la cabecera se apila en columna y el botón, al ser un
   hijo estirable, se convertía en una caja vacía de 520 px con un "?" perdido
   en la esquina. Se ve en el calendario, pero le pasaba a todas las secciones. */
.page-header > .ayuda-btn { align-self: flex-start; flex: 0 0 auto; }

/* En /calendario el nombre de la sección ya lo dice la tira de arriba. */
body.pcal #page-veh-calendar .page-title { display: none; }

/* ── Reservas sin proyecto: gris rayado, no invisibles ───────────────────── */
/* Existían en la base y la rejilla las pintaba como casilla vacía. Ahora se ven
   en gris —ni color de rodaje, ni ámbar de aviso— con el conductor debajo y el
   texto "Sin proyecto", que es exactamente lo que les falta. */
.cal-veh-td-day.cal-sin-proy .cal-cell-inner,
.cal-veh-td-day.cal-sin-proy.cal-run-solo .cal-cell-inner,
.cal-veh-td-day.cal-sin-proy.cal-run-start .cal-cell-inner,
.cal-veh-td-day.cal-sin-proy.cal-run-mid .cal-cell-inner,
.cal-veh-td-day.cal-sin-proy.cal-run-end .cal-cell-inner {
  background:
    repeating-linear-gradient(-45deg,
      rgba(141,153,174,.30) 0 5px, rgba(141,153,174,.13) 5px 10px),
    var(--surface-2) !important;
  box-shadow: inset 0 0 0 1px rgba(141,153,174,.42) !important;
}
.cal-veh-td-day.cal-sin-proy .cal-cell-inner::after { background: none; }
.cal-veh-td-day.cal-sin-proy .cal-ev-tit {
  color: var(--text-soft); font-weight: 800;
  text-transform: uppercase; font-size: 9px; letter-spacing: .04em;
}
.cal-veh-td-day.cal-sin-proy .cal-ev-sub { color: var(--text-2); }

/* ── Tareas / ITV: los bloqueos que vienen del calendario ────────────────── */
.itv-bloq-tipo {
  display: inline-block; margin-left: 7px;
  padding: 1px 6px; border-radius: 3px;
  font-size: 9.5px; font-weight: 800; letter-spacing: .04em;
  text-transform: uppercase; vertical-align: 1px;
}
.itv-bloq-itv {
  background: rgba(240,160,24,.16); color: #d98a0c;
  box-shadow: inset 0 0 0 1px rgba(240,160,24,.45);
}
.itv-bloq-mantenimiento {
  background: rgba(232,75,75,.16); color: #cc3333;
  box-shadow: inset 0 0 0 1px rgba(232,75,75,.45);
}
:root[data-tema="oscuro"] .itv-bloq-itv { color: #f0a018; }
@media (prefers-color-scheme: dark) {
  :root:not([data-tema="claro"]) .itv-bloq-itv { color: #f0a018; }
}
:root[data-tema="oscuro"] .itv-bloq-mantenimiento { color: #ff8080; }
@media (prefers-color-scheme: dark) {
  :root:not([data-tema="claro"]) .itv-bloq-mantenimiento { color: #ff8080; }
}

/* La casilla a la que se salta desde Tareas / ITV. Sin una señal, "ver en el
   calendario" te deja mirando una rejilla de 29 × 120 sin saber dónde. */
.cal-veh-td-day.cal-td-senalada {
  outline: 3px solid var(--accent);
  outline-offset: -2px;
  animation: cal-senal 2.4s ease-out;
  z-index: 8;
}
@keyframes cal-senal {
  0%, 55% { outline-color: var(--accent); }
  100%    { outline-color: transparent; }
}
@media (prefers-reduced-motion: reduce) {
  .cal-veh-td-day.cal-td-senalada { animation: none; }
}

/* ── Dashboard general: la flota según el calendario ─────────────────────── */
.fw-cifras { margin: 0 0 14px; }
.fw-cifras-fila { display: flex; gap: 8px; flex-wrap: wrap; }
.fw-cifra {
  flex: 1 1 84px; min-width: 84px;
  display: flex; flex-direction: column; gap: 1px;
  padding: 8px 10px; border-radius: 8px;
  border: 1px solid var(--border); background: var(--surface-2);
  font: inherit; text-align: left; cursor: pointer;
  transition: border-color .12s ease;
}
.fw-cifra:hover { border-color: var(--border-med); }
.fw-cifra-n {
  font-size: 19px; font-weight: 750; line-height: 1.1; color: var(--text);
  font-variant-numeric: tabular-nums;
}
.fw-cifra-e { font-size: 10.5px; color: var(--text-soft); line-height: 1.25; }
.fw-cifra.mal .fw-cifra-n { color: var(--red); }

/* Los bloqueos con nombre y fechas: "2 bloqueos" no dice si es el camión que
   te hace falta el jueves. */
.fw-bloqueos {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  margin-top: 9px;
}
.fw-bloqueos-tit {
  font-size: 9.5px; font-weight: 800; letter-spacing: .07em;
  text-transform: uppercase; color: var(--text-soft); margin-right: 2px;
}
.fw-bloqueo {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 8px; border-radius: 999px;
  border: 1px solid var(--border); background: transparent;
  font: inherit; font-size: 11px; cursor: pointer; color: var(--text-2);
}
.fw-bloqueo:hover { border-color: var(--border-med); color: var(--text); }
.fw-bloq-veh { font-weight: 700; color: var(--text); }
.fw-bloq-tipo {
  font-size: 9px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase;
}
.fw-bloq-itv .fw-bloq-tipo { color: #d98a0c; }
.fw-bloq-mantenimiento .fw-bloq-tipo { color: #cc3333; }
:root[data-tema="oscuro"] .fw-bloq-itv .fw-bloq-tipo { color: #f0a018; }
@media (prefers-color-scheme: dark) {
  :root:not([data-tema="claro"]) .fw-bloq-itv .fw-bloq-tipo { color: #f0a018; }
}
:root[data-tema="oscuro"] .fw-bloq-mantenimiento .fw-bloq-tipo { color: #ff8080; }
@media (prefers-color-scheme: dark) {
  :root:not([data-tema="claro"]) .fw-bloq-mantenimiento .fw-bloq-tipo { color: #ff8080; }
}
.fw-bloq-dias { font-variant-numeric: tabular-nums; }

/* ── Lista de vehículos: reserva futura frente a rodaje en curso ─────────── */
/* Un coche que sale hoy y uno reservado para dentro de tres semanas no pueden
   llevar la misma insignia: la pregunta que se hace mirando la lista es "¿puedo
   contar con él?", y la respuesta es distinta. */
.badge-proyecto.badge-reservado {
  background: transparent;
  color: var(--text-2);
  box-shadow: inset 0 0 0 1px var(--border-med);
}

/* ═══════════════════════════════════════════════════════════════════════════
   EVENTOS DEL CALENDARIO · el sello                             (`cal-evt-`)

   Un día = un SELLO redondo con icono. Varios días = chapa con la palabra.

   El motivo es geométrico y no había manera de esquivarlo: una casilla mide
   31 px, así que "Mant." se leía "MA". Se intentó dejar que la etiqueta se
   saliera de la casilla, pero `.cal-veh-table .cal-run-solo
   .cal-cell-inner.con-label > *` le pone `max-width: 100%` con especificidad
   0,4,1 y gana. Da igual: escribir una palabra donde no cabe es el problema,
   no la solución. Un icono de 13 px entra siempre y se lee más rápido.
   ═══════════════════════════════════════════════════════════════════════════ */

/* El sello de un día. Redondo, macizo y con un aro claro que lo despega del
   rayado de debajo: es el objeto que dice "este día el coche no sale". */
.cal-veh-table .cal-evt-chapa.cal-evt-sello {
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  width: 24px; height: 24px; min-width: 24px;
  padding: 0; gap: 0;
  border-radius: 50%;
  display: grid; place-items: center;
  max-width: none;
  box-shadow: 0 1px 4px rgb(0 0 0 / .45),
              0 0 0 1.5px rgb(255 255 255 / .55),
              inset 0 -1px 2px rgb(0 0 0 / .18);
}

/* La chapa con palabra, para tramos de dos días o más. El ancho se calcula con
   los días del tramo —igual que hace `.cal-ev-txt`— y con `!important` porque
   lo que hay que vencer es una regla de especificidad 0,4,1. */
.cal-veh-table .cal-evt-chapa {
  max-width: calc(var(--cal-col-w, 32px) * var(--evt-dias, 1) - 10px) !important;
}
.cal-veh-table .cal-evt-chapa.cal-evt-sello {
  max-width: none !important;
}

/* Más peso al fondo: el rayado sube de contraste y el evento gana un filete
   del color arriba y abajo, que es lo que lo separa de un rodaje de un vistazo
   incluso cuando el sello queda tapado por el ratón. */
.cal-veh-td-day.cal-event-itv .cal-cell-inner {
  background:
    repeating-linear-gradient(-45deg,
      rgba(240,160,24,.40) 0 5px, rgba(240,160,24,.12) 5px 10px),
    var(--surface-2) !important;
  box-shadow: inset 0 0 0 1px rgba(240,160,24,.55),
              inset 0 2px 0 rgba(240,160,24,.95),
              inset 0 -2px 0 rgba(240,160,24,.95) !important;
}
.cal-veh-td-day.cal-event-mantenimiento .cal-cell-inner {
  background:
    repeating-linear-gradient(-45deg,
      rgba(232,75,75,.40) 0 5px, rgba(232,75,75,.12) 5px 10px),
    var(--surface-2) !important;
  box-shadow: inset 0 0 0 1px rgba(232,75,75,.55),
              inset 0 2px 0 rgba(232,75,75,.95),
              inset 0 -2px 0 rgba(232,75,75,.95) !important;
}
.cal-veh-td-day.cal-event-seguro .cal-cell-inner {
  background:
    repeating-linear-gradient(-45deg,
      rgba(139,92,246,.40) 0 5px, rgba(139,92,246,.12) 5px 10px),
    var(--surface-2) !important;
  box-shadow: inset 0 0 0 1px rgba(139,92,246,.55),
              inset 0 2px 0 rgba(139,92,246,.95),
              inset 0 -2px 0 rgba(139,92,246,.95) !important;
}

/* Y el aviso de taller en la casilla del nombre, junto al de ITV: saber de qué
   vehículo es un sello no puede depender de seguir la fila con el dedo. */
.cal-veh-mant-badge {
  display: inline-block; margin-top: 3px; margin-left: 4px;
  padding: 1px 5px; border-radius: 3px;
  background: rgba(232,75,75,.16);
  box-shadow: inset 0 0 0 1px rgba(232,75,75,.45);
  color: #cc3333;
  font-size: 9.5px; font-weight: 800; letter-spacing: .02em;
  white-space: nowrap;
}
:root[data-tema="oscuro"] .cal-veh-mant-badge { color: #ff8080; }
@media (prefers-color-scheme: dark) {
  :root:not([data-tema="claro"]) .cal-veh-mant-badge { color: #ff8080; }
}

/* Muy alejado el sello se queda igual: es lo único que sigue siendo legible a
   ese tamaño, así que la regla que escondía el texto ya no hace falta aquí. */
.cal-veh-table[data-z-min="1"] .cal-evt-chapa.cal-evt-sello {
  width: 18px; height: 18px; min-width: 18px;
}

/* ═══════════════════════════════════════════════════════════════════════════
   CALENDARIO DE PRODUCCIÓN                                          (`pc-`)

   La rejilla reutiliza las clases del calendario de flota entero, así que aquí
   solo está lo propio: la barra de crear espacios, la marca del arrastre y el
   interruptor de "todos los vehículos".
   ═══════════════════════════════════════════════════════════════════════════ */

.pc-nuevo {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 10px 12px; margin: 0 0 12px;
  background: var(--surface-2);
  border: 1px solid var(--border); border-radius: 10px;
}
.pc-nuevo .form-control { flex: 1 1 160px; min-width: 0; }

/* El interruptor de la cabecera. Por defecto solo salen los Vitos, que es lo
   que producción reserva; el resto de la flota está a un clic para el día que
   haga falta un camión. */
.pc-todos {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; color: var(--text-soft); cursor: pointer;
  user-select: none; white-space: nowrap;
}
.pc-todos input { margin: 0; cursor: pointer; }
.pc-todos:hover { color: var(--text); }

/* Lo que se está a punto de pintar, mientras se arrastra. */
.cal-veh-td-day.pc-marcada .cal-cell-inner {
  background: var(--cal-pincel, var(--accent)) !important;
  opacity: .55;
}

.pc-vacio {
  padding: 46px 30px; text-align: center;
  color: var(--text-soft); font-size: 13.5px; line-height: 1.6;
}

/* En producción el nombre del recurso puede ser largo («Vestuario y
   maquillaje»), así que la columna respira un poco más que en flota. */
#pc-tabla .cal-veh-name { font-size: 12.5px; }
#pc-tabla .cal-veh-mat { font-size: 10px; }

/* El icono de los espacios, al peso del logo de una marca: ni más ni menos. */
.pc-ico-esp { color: var(--text-2); display: block; }
#pc-tabla .cal-veh-logo-cell { display: grid; place-items: center; }

/* ═══════════════════════════════════════════════════════════════════════════
   UN COLOR POR CONCEPTO                                          (`--evt-*`)

   La ITV estaba pintada con CINCO ámbares distintos según la pantalla
   (#f59e0b, #f0a018, #d98a0c, #f6b93b, #f0a020) y el mantenimiento con cinco
   rojos (#e84b4b, #cc3333, #ff8080, #e5484d, #ff7a7a). Cada uno se añadió en
   su momento, ninguno estaba mal por sí solo, y juntos hacen que la misma cosa
   parezca dos cosas: el botón de la paleta, el sello de la casilla, el aviso
   de la fila, la chapa de Tareas/ITV y la del dashboard no eran del mismo
   color, y eso lía.

   Ahora hay un token por concepto y todo lo demás sale de él:
     `--evt-X`       el color, el que se ve;
     `--evt-X-txt`   qué color de texto va ENCIMA de ese color;
     `--evt-X-suave` el fondo tenue de las chapas pequeñas.

   Definidos sobre `color-mix` a partir del color base, así que cambiar el
   ámbar es cambiar UNA línea y se mueve toda la aplicación con él.
   ═══════════════════════════════════════════════════════════════════════════ */
:root {
  /* ÁMBAR DE AVISO para la ITV, no el mostaza de antes (#e0940f), que tiraba a
     marrón y en la rejilla parecía sucio. Este es el ámbar que se usa para
     "atención, hay algo que caduca": la ITV no es una avería, es un trámite con
     fecha límite. El rojo se reserva para lo que de verdad inmoviliza el coche
     —el taller—, y así los dos avisos no se confunden entre ellos. */
  --evt-itv:  #f5a524;
  --evt-mant: #d94a4a;
  --evt-seg:  #7c5cf0;
}
:root {
  /* Texto encima del color: oscuro sobre el ámbar (que es claro) y blanco
     sobre el rojo y el violeta. No se calcula: se decide, porque un cálculo
     automático deja el ámbar con texto blanco ilegible. */
  --evt-itv-txt:   #241701;
  --evt-mant-txt:  #ffffff;
  --evt-seg-txt:   #ffffff;

  /* Fondo tenue para las chapas de las listas. */
  --evt-itv-suave:  color-mix(in srgb, var(--evt-itv) 16%, transparent);
  --evt-mant-suave: color-mix(in srgb, var(--evt-mant) 16%, transparent);
  --evt-seg-suave:  color-mix(in srgb, var(--evt-seg) 16%, transparent);

  /* Y el color del texto de esas chapas: el mismo tono, oscurecido en claro y
     aclarado en oscuro, para que contraste con el fondo de la aplicación. */
  --evt-itv-tinta:  color-mix(in srgb, var(--evt-itv) 82%, #000);
  --evt-mant-tinta: color-mix(in srgb, var(--evt-mant) 82%, #000);
  --evt-seg-tinta:  color-mix(in srgb, var(--evt-seg) 82%, #000);
}
/* El tema se marca en `<html data-tema="oscuro|claro">`, que es el mecanismo
   de esta aplicación. Escribí estas reglas con `data-theme` —el nombre que uso
   por costumbre— y no coincidían con nada: el `:not()` era siempre verdadero,
   así que el tono oscuro se aplicaba también en modo claro. Mismo patrón que
   el resto de la hoja: el atributo explícito y, aparte, el sistema. */
:root[data-tema="oscuro"] {
  --evt-itv-tinta:  color-mix(in srgb, var(--evt-itv) 88%, #fff);
  --evt-mant-tinta: color-mix(in srgb, var(--evt-mant) 88%, #fff);
  --evt-seg-tinta:  color-mix(in srgb, var(--evt-seg) 88%, #fff);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-tema="claro"]) {
    --evt-itv-tinta:  color-mix(in srgb, var(--evt-itv) 88%, #fff);
    --evt-mant-tinta: color-mix(in srgb, var(--evt-mant) 88%, #fff);
    --evt-seg-tinta:  color-mix(in srgb, var(--evt-seg) 88%, #fff);
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   LA CASILLA DE UN EVENTO, REHECHA

   El sello redondo no funcionaba: un disco rosa sobre rayas rojas es el mismo
   tono sobre el mismo tono, así que no destacaba, y el icono de 13 px dentro
   del disco era un borrón. Parecía una pegatina puesta encima.

   Lo que se hace ahora es lo contrario: la casilla ENTERA es el aviso. Bloque
   macizo del color del evento —como la barra de un rodaje, que es lo que ya se
   sabe leer— con un rayado diagonal por encima que lo marca como "no
   disponible", y el texto escrito directamente sobre él con su icono delante.

   El texto usa la misma maquinaria que el nombre de un rodaje (`.cal-ev-txt`),
   que ya sabe medir el ancho real del tramo y cortar con puntos suspensivos.
   A 100 % la columna mide 62 px y "ITV" o "MANT" entran de sobra; solo en el
   zoom mínimo (32 px) se queda el icono solo.
   ═══════════════════════════════════════════════════════════════════════════ */

.cal-veh-td-day.cal-event-itv .cal-cell-inner,
.cal-veh-td-day.cal-event-itv.cal-run-solo .cal-cell-inner,
.cal-veh-td-day.cal-event-itv.cal-run-start .cal-cell-inner,
.cal-veh-td-day.cal-event-itv.cal-run-mid .cal-cell-inner,
.cal-veh-td-day.cal-event-itv.cal-run-end .cal-cell-inner {
  background:
    repeating-linear-gradient(-45deg,
      rgb(0 0 0 / .16) 0 4px, rgb(0 0 0 / 0) 4px 9px),
    var(--evt-itv) !important;
  box-shadow: inset 0 0 0 1px rgb(0 0 0 / .22) !important;
}
.cal-veh-td-day.cal-event-mantenimiento .cal-cell-inner,
.cal-veh-td-day.cal-event-mantenimiento.cal-run-solo .cal-cell-inner,
.cal-veh-td-day.cal-event-mantenimiento.cal-run-start .cal-cell-inner,
.cal-veh-td-day.cal-event-mantenimiento.cal-run-mid .cal-cell-inner,
.cal-veh-td-day.cal-event-mantenimiento.cal-run-end .cal-cell-inner {
  background:
    repeating-linear-gradient(-45deg,
      rgb(0 0 0 / .16) 0 4px, rgb(0 0 0 / 0) 4px 9px),
    var(--evt-mant) !important;
  box-shadow: inset 0 0 0 1px rgb(0 0 0 / .22) !important;
}
.cal-veh-td-day.cal-event-seguro .cal-cell-inner,
.cal-veh-td-day.cal-event-seguro.cal-run-solo .cal-cell-inner,
.cal-veh-td-day.cal-event-seguro.cal-run-start .cal-cell-inner,
.cal-veh-td-day.cal-event-seguro.cal-run-mid .cal-cell-inner,
.cal-veh-td-day.cal-event-seguro.cal-run-end .cal-cell-inner {
  background:
    repeating-linear-gradient(-45deg,
      rgb(0 0 0 / .16) 0 4px, rgb(0 0 0 / 0) 4px 9px),
    var(--evt-seg) !important;
  box-shadow: inset 0 0 0 1px rgb(0 0 0 / .22) !important;
}

/* El texto del evento: icono + palabra, sobre el bloque. Ya no flota nada. */
.cal-evt-rot {
  /* CENTRADA SOBRE EL TRAMO ENTERO, no pegada a la izquierda del primer día.
     La etiqueta vive en la casilla donde empieza el tramo, así que `left` se
     mide desde ahí: media anchura del tramo (días × ancho de columna) cae justo
     en su centro. Antes iba a la izquierda y un taller de cinco días se leía
     como "un día con texto y cuatro días vacíos", cuando es UNA sola cosa. */
  position: absolute;
  left: calc(var(--cal-col-w, 32px) * var(--evt-dias, 1) / 2);
  top: 50%;
  transform: translate(-50%, -50%);
  display: inline-flex; align-items: center; gap: 4px;
  /* El ancho REAL del tramo: días × ancho de columna. Con `!important` porque
     `.cal-veh-table .cal-run-solo .cal-cell-inner.con-label > *` lo capaba al
     ancho de una sola casilla (especificidad 0,4,1) y en un tramo de seis días
     la palabra se cortaba igualmente. */
  max-width: calc(var(--cal-col-w, 32px) * var(--evt-dias, 1) - 9px) !important;
  min-width: 0; overflow: hidden;
  font-size: 9.5px; font-weight: 800; letter-spacing: .03em;
  text-transform: uppercase; white-space: nowrap;
  z-index: 2; pointer-events: none;
  text-shadow: 0 1px 0 rgb(0 0 0 / .16);
}
.cal-evt-rot svg { flex: 0 0 auto; }
.cal-evt-rot .cal-evt-txt { overflow: hidden; text-overflow: ellipsis; }

.cal-event-itv           .cal-evt-rot { color: var(--evt-itv-txt); }
.cal-event-mantenimiento .cal-evt-rot { color: var(--evt-mant-txt); }
.cal-event-seguro        .cal-evt-rot { color: var(--evt-seg-txt); }

/* En el zoom mínimo la columna baja a 32 px: se queda el icono, centrado. */
.cal-veh-table[data-z-min="1"] .cal-evt-rot { gap: 0; }
.cal-veh-table[data-z-min="1"] .cal-evt-rot .cal-evt-txt { display: none; }

/* ── Y todo lo demás, del mismo color ──────────────────────────────────────
   El botón de la paleta, el aviso de la fila, la chapa de Tareas/ITV y la del
   dashboard. Antes cada uno tenía su tono. */
.clv-evt.clv-itv-b   .clv-bloque { background: var(--evt-itv)  !important; color: var(--evt-itv-txt)  !important; }
.clv-evt.clv-mant-b  .clv-bloque { background: var(--evt-mant) !important; color: var(--evt-mant-txt) !important; }

.cal-veh-itv-badge {
  background: var(--evt-itv-suave);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--evt-itv) 45%, transparent);
  color: var(--evt-itv-tinta);
}
.cal-veh-mant-badge {
  background: var(--evt-mant-suave);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--evt-mant) 45%, transparent);
  color: var(--evt-mant-tinta);
}
/* Sin variante de tema: el token `--evt-*-tinta` ya cambia solo. */

.itv-bloq-itv {
  background: var(--evt-itv-suave); color: var(--evt-itv-tinta);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--evt-itv) 45%, transparent);
}
.itv-bloq-mantenimiento {
  background: var(--evt-mant-suave); color: var(--evt-mant-tinta);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--evt-mant) 45%, transparent);
}
/* Sin variante de tema: el token `--evt-*-tinta` ya cambia solo. */

.fw-bloq-itv .fw-bloq-tipo           { color: var(--evt-itv-tinta); }
.fw-bloq-mantenimiento .fw-bloq-tipo { color: var(--evt-mant-tinta); }

/* Las etiquetas pequeñas que sobreviven para los días ya ocupados. */
.cal-vev-itv { background: var(--evt-itv)  !important; color: var(--evt-itv-txt)  !important; }
.cal-vev-seg { background: var(--evt-seg)  !important; color: var(--evt-seg-txt)  !important; }

/* Y el botón viejo de la paleta de eventos, por si queda alguno pintado. */
.cal-event-btn.cal-event-itv-btn {
  border-color: var(--evt-itv) !important;
  color: var(--evt-itv-tinta) !important;
}
.cal-event-btn.cal-event-itv-btn.selected {
  background: var(--evt-itv) !important; color: var(--evt-itv-txt) !important;
}

/* ── «Añadir al calendario»: el buscador de recursos ─────────────────────── */
/* Un panel bajo la cabecera, no un diálogo encima: se añaden varias cosas
   seguidas y hay que ver la rejilla cambiar mientras tanto. */
.pc-anadir {
  margin: 0 0 12px; padding: 10px 12px 6px;
  background: var(--surface-2);
  border: 1px solid var(--border); border-radius: 10px;
}
.pc-anadir-cab { display: flex; gap: 8px; align-items: center; }
.pc-anadir-cab .form-control { flex: 1; min-width: 0; }
.pc-anadir-res {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 6px 18px; margin-top: 8px; max-height: 320px; overflow: auto;
}
.pc-anadir-tit {
  font-size: 10px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  color: var(--text-soft); padding: 6px 4px 4px;
}
.pc-anadir-tit span { font-weight: 600; color: var(--text-2); margin-left: 4px; }
.pc-anadir-vacio { font-size: 12.5px; color: var(--text-soft); padding: 6px 4px 10px; }

.pc-cand {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 7px 8px; border: 0; border-radius: 8px;
  background: transparent; font: inherit; text-align: left; cursor: pointer;
  color: var(--text);
}
.pc-cand:hover { background: var(--bg-hover); }
.pc-cand:disabled { opacity: .5; cursor: default; }
.pc-cand-ico { flex: 0 0 auto; width: 22px; display: grid; place-items: center; color: var(--text-2); }
.pc-cand-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.pc-cand-nom { font-size: 13px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pc-cand-det { font-size: 11px; color: var(--text-soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pc-cand-mas {
  flex: 0 0 auto; font-size: 11.5px; font-weight: 700; color: var(--accent);
  opacity: 0; transition: opacity .12s;
}
.pc-cand:hover .pc-cand-mas, .pc-cand:focus-visible .pc-cand-mas { opacity: 1; }

/* ── Importar material: la previa ─────────────────────────────────────────── */
.impc { display: flex; flex-direction: column; gap: 12px; margin-top: 6px; }
.impc-cifras { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
.impc-cifra {
  display: flex; flex-direction: column; gap: 2px; padding: 9px 10px;
  border-radius: 8px; border: 1px solid var(--border); background: var(--surface-2);
}
.impc-cifra b { font-size: 20px; font-weight: 750; line-height: 1.1; font-variant-numeric: tabular-nums; }
.impc-cifra span { font-size: 10.5px; color: var(--text-soft); }
.impc-cifra.mal b { color: var(--red); }
.impc-prob { margin: 0; padding: 0 0 0 18px; font-size: 12.5px; color: var(--text-2); line-height: 1.5; }
.impc-tit { font-size: 11px; font-weight: 800; letter-spacing: .07em; text-transform: uppercase; color: var(--text-soft); }
.impc-tit span { font-weight: 600; }
.impc-tit.ok { color: var(--text-2); text-transform: none; letter-spacing: 0; font-weight: 500; font-size: 13px; }
/* El árbol de categorías nuevas, sangrado por nivel: una lista plana de cien
   rutas se lee mal; sangrada se ve qué cuelga de qué. */
.impc-arbol {
  max-height: 260px; overflow: auto; padding: 6px 8px;
  border: 1px solid var(--border); border-radius: 8px; background: var(--surface-2);
  font-size: 12.5px; line-height: 1.55;
}
.impc-cat { padding-left: calc(var(--n, 0) * 16px); display: flex; align-items: baseline; gap: 7px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.impc-cat-nivel {
  flex: 0 0 auto; width: 15px; height: 15px; border-radius: 4px; display: grid; place-items: center;
  font-size: 9.5px; font-weight: 800; background: var(--bg-hover); color: var(--text-soft);
}
.impc-cat-ruta { font-size: 11px; color: var(--text-soft); overflow: hidden; text-overflow: ellipsis; }
.impc-acciones { display: flex; justify-content: flex-end; gap: 8px; margin-top: 2px; }

/* ── Constructor de presupuestos: «+ todo» en el árbol de categorías ──────── */
/* Aparece al pasar por el nodo y siempre en el seleccionado. Pequeño y a la
   derecha, para que el nombre de la categoría siga siendo lo que se lee. */
.np-nodo-mas {
  flex: 0 0 auto; margin-left: auto;
  padding: 1px 7px; border-radius: 999px;
  border: 1px solid var(--border); background: var(--surface-2);
  color: var(--text-2); font: inherit; font-size: 10.5px; font-weight: 700;
  letter-spacing: .02em; white-space: nowrap; cursor: pointer;
  opacity: 0; transition: opacity .12s ease, border-color .12s ease;
}
.np-nodo:hover .np-nodo-mas,
.np-nodo.sel .np-nodo-mas,
.np-nodo-mas:focus-visible { opacity: 1; }
.np-nodo-mas:hover { border-color: var(--accent); color: var(--accent); }
.np-nodo { display: flex; align-items: center; }

/* Selector de material del constructor: «+ todo» en la fila de categoría. */
.pk-todo {
  flex: 0 0 auto; margin-left: 6px;
  padding: 1px 7px; border-radius: 999px;
  border: 1px solid var(--border); background: var(--surface-2);
  color: var(--text-2); font: inherit; font-size: 10.5px; font-weight: 700;
  white-space: nowrap; cursor: pointer; opacity: 0; transition: opacity .12s, border-color .12s;
}
.pk-fila.pk-cat:hover .pk-todo, .pk-todo:focus-visible { opacity: 1; }
.pk-todo:hover { border-color: var(--accent); color: var(--accent); }

/* ── Material del proyecto: «+ todo» en la fila de categoría ─────────────── */
/* La fila pasó de <button> a <div role="button"> para poder llevar dentro este
   botón; se le da lo que el botón tenía de serie. */
/* Se respeta la rejilla que ya tenía (flecha | nombre | contador) y se le
   añade una cuarta columna para el botón: pasarla a flex la desalineaba. */
.ecat-rama { grid-template-columns: 14px minmax(0, 1fr) auto auto; cursor: pointer; user-select: none; }
.ecat-rama:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.ecat-todo {
  flex: 0 0 auto; margin-left: 6px;
  padding: 1px 7px; border-radius: 999px;
  border: 1px solid var(--border); background: var(--surface-2);
  color: var(--text-2); font: inherit; font-size: 10.5px; font-weight: 700;
  white-space: nowrap; cursor: pointer; opacity: 0; transition: opacity .12s, border-color .12s;
}
.ecat-rama:hover .ecat-todo, .ecat-todo:focus-visible,
.ecat-todo.puesto, .ecat-todo.parte { opacity: 1; }
.ecat-todo:hover { border-color: var(--accent); color: var(--accent); }
.ecat-todo.puesto { background: var(--accent); border-color: var(--accent); color: #fff; }
.ecat-todo.parte  { border-color: var(--accent); color: var(--accent); }

/* ── Desplegables con color: la muestra del proyecto ─────────────────────── */
.dd-muestra {
  display: inline-block; flex: 0 0 auto;
  width: 12px; height: 12px; border-radius: 3px;
  margin-right: 8px; vertical-align: -1px;
  box-shadow: inset 0 0 0 1px rgb(0 0 0 / .18);
}
.cat-dd-fila .dd-muestra { margin-right: 0; }

/* Importar: la opción extra del diálogo (tipo de las líneas). */
.imp-opcion { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 0 0 12px; font-size: 13px; color: var(--text-2); }
.imp-opcion .form-control { max-width: 280px; }

/* ── General de Flota: «Los que más salen» ───────────────────────────────── */
.fd-top-tog { display: inline-flex; gap: 2px; padding: 2px; border-radius: 7px; background: var(--bg-hover); margin: 0 0 8px; }
.fd-top-tog button {
  border: 0; background: transparent; color: var(--text-soft); font: inherit; font-size: 11.5px; font-weight: 600;
  padding: 3px 9px; border-radius: 5px; cursor: pointer;
}
.fd-top-tog button.activo { background: var(--surface); color: var(--text); box-shadow: 0 1px 2px rgb(0 0 0 / .12); }
.fd-top-fila { cursor: pointer; }
.fd-top-fila:hover { background: var(--bg-hover); }
.fd-top-pos {
  flex: 0 0 auto; width: 18px; height: 18px; border-radius: 50%; display: grid; place-items: center;
  font-size: 10.5px; font-weight: 800; color: var(--text-soft); background: var(--bg-hover); margin-right: 8px;
  font-variant-numeric: tabular-nums;
}
.fd-top-fila:nth-child(1) .fd-top-pos { background: var(--accent); color: #fff; }

/* ═══════════════════════════════════════════════════════════════════════════
   MIFI · ENTREGAR Y DEVOLVER DESDE EL QR (.mfq-*)
   Pantalla de móvil: dos botones grandes que se pulsan con el pulgar. En
   pantallas estrechas sube desde abajo como una hoja; en escritorio es un
   modal normal.
   ═══════════════════════════════════════════════════════════════════════ */
.mfq { max-width: 440px; padding: 22px 22px 18px; display: flex; flex-direction: column; gap: 14px; }
.mfq-cab { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.mfq-cod { font: 700 12px/1 var(--font); letter-spacing: .08em; text-transform: uppercase; color: var(--text-secondary); margin-bottom: 6px; }
.mfq-tit { margin: 0; font: 700 22px/1.15 var(--font-display); color: var(--text-primary); }
.mfq-red { margin-top: 6px; font-size: 13px; color: var(--text-secondary); }
.mfq-red b { color: var(--text-primary); font-weight: 600; }

.mfq-estado { border-radius: 12px; padding: 14px 16px; border: 1px solid var(--border); background: var(--surface-2); }
.mfq-estado-et { font: 700 12px/1 var(--font); letter-spacing: .06em; text-transform: uppercase; color: var(--text-secondary); }
.mfq-estado.libre .mfq-estado-et { color: #2e9e5b; }
.mfq-estado.fuera .mfq-estado-et { color: var(--accent); }
.mfq-estado.tarde { border-color: color-mix(in srgb, var(--evt-mant, #d94a4a) 55%, transparent); }
.mfq-estado.tarde .mfq-estado-et { color: var(--evt-mant, #d94a4a); }
.mfq-estado-quien { font: 700 18px/1.2 var(--font-display); color: var(--text-primary); margin-top: 6px; }
.mfq-estado-proy { font-size: 14px; color: var(--text-primary); margin-top: 2px; }
.mfq-estado-sub { font-size: 13px; color: var(--text-secondary); margin-top: 6px; line-height: 1.4; }

.mfq-acciones { display: flex; flex-direction: column; gap: 10px; }
.mfq-btn {
  min-height: 54px; border-radius: 14px; border: 1px solid var(--border-strong);
  background: var(--surface); color: var(--text-primary);
  font: 600 16px/1.2 var(--font); cursor: pointer; padding: 0 18px;
}
.mfq-btn:hover { background: var(--bg-hover); }
.mfq-btn.primario { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 700; font-size: 17px; }
.mfq-btn.primario:hover { filter: brightness(1.05); }
.mfq-btn:disabled { opacity: .6; cursor: default; }
.mfq-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.mfq-form { display: flex; flex-direction: column; gap: 10px; }
.mfq-form label { display: flex; flex-direction: column; gap: 5px; font: 600 13px/1.2 var(--font); color: var(--text-secondary); }
.mfq-form .form-control { font-size: 16px; min-height: 44px; }
.mfq-opc { font-weight: 400; color: var(--text-muted); }
.mfq-nota { margin: 0; font-size: 14px; line-height: 1.45; color: var(--text-secondary); }
.mfq-enlace { align-self: center; border: 0; background: none; color: var(--accent); font: 500 13px/1 var(--font); cursor: pointer; padding: 6px; text-decoration: underline; text-underline-offset: 3px; }

@media (max-width: 600px) {
  .modal-overlay.mfq-capa { align-items: flex-end; padding: 0; }
  .mfq { max-width: 100%; width: 100%; border-radius: 18px 18px 0 0; max-height: 92vh; padding-bottom: calc(18px + env(safe-area-inset-bottom, 0px)); }
}

/* «Bulx está arrancando»: franja fija arriba mientras el servidor se
   reinicia (capa _caida de app.js). Encima de todo, incluido el login. */
.caida-aviso {
  position: fixed; top: 0; left: 0; right: 0; z-index: 9500;
  display: flex; align-items: center; justify-content: center; gap: 10px;
  padding: 10px 16px; background: #0b0b0d; color: #eaecf2;
  font: 500 13px/1.35 var(--font); border-bottom: 1px solid rgba(255,255,255,.12);
  box-shadow: 0 6px 24px rgba(0,0,0,.35);
}
.caida-aviso b { font-weight: 700; }
.caida-punto { width: 8px; height: 8px; flex: 0 0 auto; background: #ff4d5f; animation: caida-late 1.6s ease-in-out infinite; }
@keyframes caida-late { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: .35; transform: scale(.75); } }
@media (prefers-reduced-motion: reduce) { .caida-punto { animation: none; } }

/* ═══════════════════════════════════════════════════════════════════════════
   TELEFONÍA · LA LISTA REHECHA (.tel-barra, .tel-card, .tel-tabla)
   Una barra, tarjetas por defecto, códigos tapados. Negro, gris y el acento.
   ═══════════════════════════════════════════════════════════════════════ */
.tel-barra {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 12px; margin-bottom: 10px;
  background: var(--surface); border: 1px solid var(--border);
}
.tel-buscar {
  flex: 1 1 260px; min-width: 220px; display: flex; align-items: center; gap: 9px;
  padding: 0 12px; height: 38px; background: var(--surface-2); border: 1px solid var(--border);
  color: var(--text-soft);
}
.tel-buscar:focus-within { border-color: var(--accent); color: var(--text); }
.tel-buscar input { flex: 1; min-width: 0; border: 0; background: transparent; color: var(--text); font: 13.5px/1.2 var(--font); outline: none; }
.tel-buscar input::-webkit-search-cancel-button { -webkit-appearance: none; }
.tel-barra .seg-control { margin: 0; }
.tel-barra-der { display: flex; align-items: center; gap: 8px; margin-left: auto; }
.tel-herr {
  display: inline-flex; align-items: center; gap: 7px; height: 36px; padding: 0 12px;
  border: 1px solid var(--border); background: var(--surface-2); color: var(--text-2);
  font: 500 12.5px/1 var(--font); cursor: pointer;
}
.tel-herr:hover { color: var(--text); border-color: var(--border-strong); }
.tel-herr.activo { color: var(--text); border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.tel-vista .seg-btn { padding: 0 10px; height: 34px; display: inline-flex; align-items: center; }
.tel-mas {
  display: flex; gap: 8px; flex-wrap: wrap; align-items: center;
  padding: 10px 12px; margin: -4px 0 10px; background: var(--surface-sunk); border: 1px dashed var(--border);
}
.tel-mas .filter-input { flex: 1 1 140px; min-width: 130px; max-width: 220px; }
.tel-resumen-linea { font-size: 12px; color: var(--text-soft); margin: 0 2px 10px; font-variant-numeric: tabular-nums; }

/* ── Tarjetas ── */
.tel-grid { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(268px, 1fr)); }
.tel-grid[hidden] { display: none; }
.tel-card {
  position: relative; display: flex; flex-direction: column; gap: 10px;
  padding: 14px 16px 12px; background: var(--surface); border: 1px solid var(--border);
  cursor: default; transition: border-color .12s ease, transform .12s ease;
}
.tel-card:hover { border-color: var(--border-strong); }
.tel-card.sel { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.tel-card.baja { opacity: .62; }
.tel-card.baja:hover { opacity: 1; }
.tel-card-sel { position: absolute; top: 10px; right: 12px; display: inline-flex; opacity: 0; transition: opacity .12s ease; }
.tel-card:hover .tel-card-sel, .tel-card.sel .tel-card-sel, .tel-card-sel:focus-within { opacity: 1; }
.tel-card-sel input { width: 15px; height: 15px; cursor: pointer; accent-color: var(--accent); }
.tel-card-cab { display: flex; align-items: center; gap: 8px; padding-right: 26px; }
.tel-tipo {
  display: inline-flex; align-items: center; height: 20px; padding: 0 8px;
  font: 700 10px/1 var(--font); letter-spacing: .08em; text-transform: uppercase;
  color: var(--text-2); background: var(--surface-2); border: 1px solid var(--border);
}
.tel-tipo.movil { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 45%, transparent); background: color-mix(in srgb, var(--accent) 10%, transparent); }
.tel-estado { display: inline-flex; align-items: center; gap: 6px; font: 600 11px/1 var(--font); color: var(--text-soft); margin-left: auto; }
.tel-estado i { width: 7px; height: 7px; border-radius: 50%; background: var(--green, #4ade80); }
.tel-estado.baja i { background: var(--text-xsoft); }
.tel-num {
  font: 600 22px/1.1 var(--font-mono); letter-spacing: .01em; color: var(--text);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.tel-quien { display: flex; align-items: center; gap: 10px; min-width: 0; }
.tel-avatar {
  flex: 0 0 auto; width: 34px; height: 34px; display: grid; place-items: center;
  background: var(--surface-2); border: 1px solid var(--border); color: var(--text);
  font: 700 12px/1 var(--font); letter-spacing: .04em;
}
.tel-avatar.libre { color: var(--text-xsoft); border-style: dashed; }
.tel-quien-txt { min-width: 0; }
.tel-nombre { font: 600 14px/1.25 var(--font); color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tel-dep { font-size: 12px; color: var(--text-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tel-libre { color: var(--text-xsoft); font-style: italic; font-weight: 500; }
.tel-datos {
  display: grid; grid-template-columns: .8fr 1fr 1.1fr 1.25fr; gap: 0 6px; margin: 2px 0 0;
  border-top: 1px solid var(--border); padding-top: 10px;
}
.tel-datos > div { min-width: 0; }
.tel-datos dt { font: 700 9.5px/1 var(--font); letter-spacing: .1em; text-transform: uppercase; color: var(--text-xsoft); margin-bottom: 5px; }
.tel-datos dd { margin: 0; font: 12.5px/1.2 var(--font-mono); color: var(--text); font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tel-datos dd b { font-weight: 600; }
.tel-tapado { letter-spacing: .12em; color: var(--text-soft); user-select: none; }
.tel-vacio { color: var(--text-xsoft); }
.tel-card-pie { display: flex; align-items: center; gap: 6px; margin-top: 2px; padding-top: 10px; border-top: 1px solid var(--border); }
.tel-card-pie .tel-acc:not(.fuerte) { padding: 0 8px; }
.tel-card-pie a.tel-acc, .tel-card-pie .tel-acc[title="Copiar el número"] { width: 32px; padding: 0; justify-content: center; }
.tel-pie-hueco { flex: 1; }
.tel-acc {
  display: inline-flex; align-items: center; gap: 6px; height: 30px; padding: 0 10px;
  border: 1px solid transparent; background: transparent; color: var(--text-2);
  font: 500 12.5px/1 var(--font); cursor: pointer; text-decoration: none;
}
.tel-acc:hover { color: var(--text); background: var(--surface-2); border-color: var(--border); }
.tel-acc.fuerte { color: var(--text); border-color: var(--border); }
.tel-acc.fuerte:hover { border-color: var(--accent); color: var(--accent); }
.tel-acc.peligro:hover { color: var(--red); border-color: color-mix(in srgb, var(--red) 40%, transparent); }

.tel-vacio-caja { grid-column: 1 / -1; text-align: center; padding: 44px 20px; color: var(--text-soft); border: 1px dashed var(--border); }
.tel-vacio-tit { font: 600 15px/1.3 var(--font); color: var(--text); margin-bottom: 6px; }
.tel-vacio-txt { font-size: 13px; margin-bottom: 14px; }

/* ── Tabla, aligerada ── */
.tel-tabla-wrap[hidden] { display: none; }
.tel-tabla th { font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--text-xsoft); font-weight: 700; border-bottom: 1px solid var(--border-strong); }
.tel-tabla td { padding: 11px 10px; vertical-align: middle; border-bottom: 1px solid var(--border); }
.tel-tabla tr.fila-abrible:hover td { background: var(--surface-2); }
.tel-td-num { font: 600 14px/1 var(--font-mono); font-variant-numeric: tabular-nums; white-space: nowrap; color: var(--text); }
.tel-td-quien { font-weight: 600; color: var(--text); }
.tel-td-suave { font-size: 12px; color: var(--text-soft); }
.tel-td-mono { font: 13px/1 var(--font-mono); font-variant-numeric: tabular-nums; color: var(--text); }
.tel-td-acc { white-space: nowrap; text-align: right; }
.tel-td-acc .tel-acc { height: 28px; padding: 0 9px; }
.tel-fila-baja td { opacity: .6; }
.tel-tabla .tel-row-cb { width: 15px; height: 15px; accent-color: var(--accent); cursor: pointer; }

@media (max-width: 700px) {
  .tel-barra-der { margin-left: 0; width: 100%; justify-content: space-between; }
  .tel-datos { grid-template-columns: repeat(2, 1fr); row-gap: 10px; }
}

/* Operadora en Telefonía: logo a color + nombre. */
.tel-op { display: inline-flex; align-items: center; gap: 7px; min-width: 0; color: var(--text-2); font: 600 12px/1 var(--font); }
.tel-op-logo { width: 22px; height: 22px; border-radius: 5px; flex: 0 0 auto; display: block; }
.tel-op-logo.neutro { display: grid; place-items: center; background: var(--surface-2); border: 1px solid var(--border); color: var(--text-soft); font: 700 9px/1 var(--font); letter-spacing: .04em; }
.tel-op-nom { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tel-card-cab .tel-op { margin-right: 2px; max-width: 55%; }
.tel-card-cab .tel-op .tel-op-nom { color: var(--text); }
.tel-tabla .tel-op-logo { width: 20px; height: 20px; }

/* ═══════════════════════════════════════════════════════════════════════════
   CAPA UX · IT STOCK, MIFI Y MICROSOFT 365
   El mismo lenguaje que Telefonía: una barra, tarjetas limpias, tabla ligera,
   cifras grandes y pocas líneas. Clases genéricas (.ux-*) para no repetir.
   ═══════════════════════════════════════════════════════════════════════ */
.ux-barra {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 12px; margin-bottom: 10px;
  background: var(--surface); border: 1px solid var(--border);
}
.ux-buscar {
  flex: 1 1 260px; min-width: 220px; display: flex; align-items: center; gap: 9px;
  padding: 0 12px; height: 38px; background: var(--surface-2); border: 1px solid var(--border); color: var(--text-soft);
}
.ux-buscar:focus-within { border-color: var(--accent); color: var(--text); }
.ux-buscar input { flex: 1; min-width: 0; border: 0; background: transparent; color: var(--text); font: 13.5px/1.2 var(--font); outline: none; }
.ux-buscar input::-webkit-search-cancel-button { -webkit-appearance: none; }
.ux-select {
  height: 38px; padding: 0 30px 0 12px; border: 1px solid var(--border); background: var(--surface-2); color: var(--text);
  font: 500 13px/1 var(--font); cursor: pointer; appearance: none; -webkit-appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--text-soft) 50%), linear-gradient(135deg, var(--text-soft) 50%, transparent 50%);
  background-position: calc(100% - 15px) 17px, calc(100% - 10px) 17px; background-size: 5px 5px, 5px 5px; background-repeat: no-repeat;
}
.ux-select:focus { outline: none; border-color: var(--accent); }
.ux-barra-der { display: flex; align-items: center; gap: 8px; margin-left: auto; }
.ux-orden { display: inline-flex; align-items: center; gap: 8px; font: 600 11px/1 var(--font); letter-spacing: .06em; text-transform: uppercase; color: var(--text-soft); }
.ux-orden .ux-select { height: 36px; }
.ux-herr {
  display: inline-flex; align-items: center; gap: 7px; height: 36px; padding: 0 12px;
  border: 1px solid var(--border); background: var(--surface-2); color: var(--text-2);
  font: 500 12.5px/1 var(--font); cursor: pointer;
}
.ux-herr:hover { color: var(--text); border-color: var(--border-strong); }
.ux-herr.activo { color: var(--text); border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.ux-vista .seg-btn { padding: 0 10px; height: 34px; display: inline-flex; align-items: center; }
.ux-barra .seg-control { margin: 0; }
.ux-contador { font-size: 12px; color: var(--text-soft); margin: 0 2px 10px; font-variant-numeric: tabular-nums; }

/* Cifras: números grandes, etiqueta en versalitas, separadas por líneas finas. */
.ux-cifras {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  border: 1px solid var(--border); border-left: none; background: var(--surface); margin-bottom: 14px;
}
.ux-cifra { padding: 14px 16px; border-left: 1px solid var(--border); text-align: left; background: none; font: inherit; color: inherit; cursor: default; }
.ux-cifra b { display: block; font-size: 26px; font-weight: 700; letter-spacing: -.03em; line-height: 1; color: var(--text); font-variant-numeric: tabular-nums; }
.ux-cifra span { display: block; margin-top: 6px; font-size: 10px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: var(--text-soft); }
.ux-cifra.ok b { color: var(--pres-ok); }
.ux-cifra.acento b { color: var(--accent); }
.ux-cifra.aviso b { color: var(--mo-aviso); }
.ux-cifra.apagado b { color: var(--text-soft); }
button.ux-cifra { cursor: pointer; }
button.ux-cifra:hover { background: var(--surface-2); }
button.ux-cifra.activa { box-shadow: inset 0 -2px 0 var(--accent); }

/* Tarjetas */
.ux-grid { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(268px, 1fr)); }
.ux-grid[hidden] { display: none; }
.ux-card {
  position: relative; display: flex; flex-direction: column; gap: 10px;
  padding: 14px 16px 12px; background: var(--surface); border: 1px solid var(--border);
  transition: border-color .12s ease;
}
.ux-card:hover { border-color: var(--border-strong); }
.ux-card.apagada { opacity: .6; }
.ux-card.apagada:hover { opacity: 1; }
.ux-card-cab { display: flex; align-items: center; gap: 8px; }
.ux-tile {
  width: 34px; height: 34px; flex: 0 0 auto; display: grid; place-items: center;
  background: var(--surface-2); border: 1px solid var(--border); color: var(--text); border-radius: 8px;
}
.ux-tile svg { width: 18px; height: 18px; }
.ux-pill {
  display: inline-flex; align-items: center; height: 20px; padding: 0 8px;
  font: 700 10px/1 var(--font); letter-spacing: .08em; text-transform: uppercase;
  color: var(--text-2); background: var(--surface-2); border: 1px solid var(--border);
}
.ux-pill.acento { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 45%, transparent); background: color-mix(in srgb, var(--accent) 10%, transparent); }
.ux-estado { display: inline-flex; align-items: center; gap: 6px; font: 600 11px/1 var(--font); color: var(--text-soft); margin-left: auto; white-space: nowrap; }
.ux-estado i { width: 7px; height: 7px; border-radius: 50%; background: var(--green, #4ade80); flex: 0 0 auto; }
.ux-estado.uso i { background: var(--accent); }
.ux-estado.aviso i { background: var(--mo-aviso); }
.ux-estado.apagado i { background: var(--text-xsoft); }
.ux-tit { font: 700 16px/1.2 var(--font-display); color: var(--text); letter-spacing: -.01em; overflow-wrap: anywhere; }
.ux-num { font: 600 22px/1.1 var(--font-mono); letter-spacing: .01em; color: var(--text); font-variant-numeric: tabular-nums; }
.ux-quien { display: flex; align-items: center; gap: 10px; min-width: 0; }
.ux-avatar {
  flex: 0 0 auto; width: 32px; height: 32px; display: grid; place-items: center;
  background: var(--surface-2); border: 1px solid var(--border); color: var(--text);
  font: 700 11.5px/1 var(--font); letter-spacing: .04em; border-radius: 50%;
}
.ux-avatar.libre { color: var(--text-xsoft); border-style: dashed; }
.ux-quien-txt { min-width: 0; }
.ux-nombre { font: 600 13.5px/1.25 var(--font); color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ux-sub { font-size: 12px; color: var(--text-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ux-libre { color: var(--text-xsoft); font-style: italic; font-weight: 500; }
.ux-datos { display: grid; grid-template-columns: repeat(auto-fit, minmax(56px, 1fr)); gap: 0 8px; margin: 0; border-top: 1px solid var(--border); padding-top: 10px; }
.ux-datos > div { min-width: 0; }
.ux-datos dt { font: 700 9.5px/1 var(--font); letter-spacing: .1em; text-transform: uppercase; color: var(--text-xsoft); margin-bottom: 5px; white-space: nowrap; }
.ux-datos dd { margin: 0; font: 12.5px/1.2 var(--font-mono); color: var(--text); font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ux-datos dd b { font-weight: 600; }
.ux-tapado { letter-spacing: .12em; color: var(--text-soft); user-select: none; }
.ux-vacio { color: var(--text-xsoft); }
.ux-card-pie { display: flex; align-items: center; gap: 6px; margin-top: 2px; padding-top: 10px; border-top: 1px solid var(--border); }
.ux-pie-hueco { flex: 1; }
.ux-acc {
  display: inline-flex; align-items: center; gap: 6px; height: 30px; padding: 0 10px;
  border: 1px solid transparent; background: transparent; color: var(--text-2);
  font: 500 12.5px/1 var(--font); cursor: pointer; text-decoration: none; white-space: nowrap;
}
.ux-acc:hover { color: var(--text); background: var(--surface-2); border-color: var(--border); }
.ux-acc.fuerte { color: var(--text); border-color: var(--border); }
.ux-acc.fuerte:hover { border-color: var(--accent); color: var(--accent); }
.ux-acc.primario { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600; }
.ux-acc.primario:hover { filter: brightness(1.08); color: #fff; }
.ux-acc.peligro:hover { color: var(--red); border-color: color-mix(in srgb, var(--red) 40%, transparent); }
.ux-acc.icono { width: 30px; padding: 0; justify-content: center; }
.ux-vacio-caja { grid-column: 1 / -1; text-align: center; padding: 44px 20px; color: var(--text-soft); border: 1px dashed var(--border); }
.ux-vacio-tit { font: 600 15px/1.3 var(--font); color: var(--text); margin-bottom: 6px; }
.ux-vacio-txt { font-size: 13px; margin-bottom: 14px; }
.ux-nota-linea { display: flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--text-2); min-width: 0; }
.ux-nota-linea svg { flex: 0 0 auto; color: var(--text-soft); }
.ux-nota-linea b { font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Tabla ligera */
.ux-tabla-wrap[hidden] { display: none; }
.ux-tabla th { font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--text-xsoft); font-weight: 700; border-bottom: 1px solid var(--border-strong); white-space: nowrap; }
.ux-tabla td { padding: 11px 10px; vertical-align: middle; border-bottom: 1px solid var(--border); }
.ux-tabla tr.fila-abrible:hover td { background: var(--surface-2); }
.ux-td-fuerte { font-weight: 600; color: var(--text); }
.ux-td-suave { font-size: 12px; color: var(--text-soft); }
.ux-td-mono { font: 12.5px/1 var(--font-mono); font-variant-numeric: tabular-nums; color: var(--text); white-space: nowrap; }
.ux-td-acc { white-space: nowrap; text-align: right; }
.ux-td-acc .ux-acc { height: 28px; padding: 0 9px; }
.ux-fila-apagada td { opacity: .6; }
.ux-tabla .th-orden { cursor: pointer; }

/* Pestañas de sección (IT: Dispositivos · En proyectos · …): subrayado fino. */
.it-tabs { background: none; padding: 0; gap: 0; border-bottom: 1px solid var(--border); width: 100%; margin-bottom: 16px; }
.it-tab { padding: 10px 16px; margin-bottom: -1px; border-bottom: 2px solid transparent; font-weight: 600; color: var(--text-soft); }
.it-tab:hover { color: var(--text); background: none; }
.it-tab.active { color: var(--text); background: none; border-bottom-color: var(--accent); box-shadow: none; }

/* Familias del parque (Equipos PC/Mac · Móviles · Tablets): como un segmentado. */
.it-familias { gap: 0; border: 1px solid var(--border); background: var(--surface); width: fit-content; padding: 3px; margin-bottom: 12px; }
.it-fam { height: 32px; border: 0; background: transparent; color: var(--text-soft); font-weight: 600; font-size: 12.5px; padding: 0 12px; }
.it-fam:hover { color: var(--text); background: var(--surface-2); }
.it-fam.activa { background: var(--surface-2); color: var(--text); box-shadow: inset 0 0 0 1px var(--border-strong); }
.it-fam i { font-style: normal; font-size: 11px; color: var(--text-soft); font-variant-numeric: tabular-nums; }

/* Microsoft 365: conmutador y pestañas de clase con el mismo trazo. */
.ma-switch { background: var(--surface); border: 1px solid var(--border); padding: 3px; gap: 0; margin-bottom: 14px; }
.ma-sw { height: 32px; padding: 0 14px; border: 0; background: transparent; color: var(--text-soft); font: 600 12.5px/1 var(--font); cursor: pointer; }
.ma-sw:hover { color: var(--text); background: var(--surface-2); }
.ma-sw.activa { background: var(--surface-2); color: var(--text); box-shadow: inset 0 0 0 1px var(--border-strong); }
#page-m365 .mf-cifras { border-left: none; }
#page-m365 .mf-cifra b { font-size: 26px; line-height: 1; }
#page-m365 .mf-cifra span { margin-top: 6px; }
.ms-tabs { border-bottom: 1px solid var(--border); gap: 0; }
.ms-tab { padding: 10px 14px; font-size: 13px; }
.ms-tab i { font-style: normal; font-size: 11px; color: var(--text-soft); font-variant-numeric: tabular-nums; }
.ms-tab.activa { color: var(--text); border-bottom-color: var(--accent); }
#page-m365 .mo-nota { font-size: 13px; color: var(--text-soft); margin: 0 0 14px; }
#page-m365 .tabla th { font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--text-xsoft); font-weight: 700; border-bottom: 1px solid var(--border-strong); }
#page-m365 .tabla td { padding: 11px 10px; border-bottom: 1px solid var(--border); vertical-align: middle; }
#page-m365 .tabla tbody tr:hover td { background: var(--surface-2); }
#page-m365 .tabla td strong { font-weight: 600; }
#page-m365 .tabla .btn.btn-sm { height: 28px; padding: 0 9px; font-size: 12.5px; border-color: transparent; }
#page-m365 .tabla .btn.btn-sm:hover { border-color: var(--border); background: var(--surface-2); }

@media (max-width: 700px) {
  .ux-barra-der { margin-left: 0; width: 100%; justify-content: space-between; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   EMPLEADOS COMO EJE: selector de persona, ficha, salida y panel de Tecnología
   ═══════════════════════════════════════════════════════════════════════ */
.ux-picker { display: flex; align-items: center; gap: 6px; }
.ux-picker-btn {
  flex: 1; min-width: 0; display: flex; align-items: center; gap: 9px; height: 40px; padding: 0 10px 0 6px;
  border: 1px solid var(--border-strong); background: var(--surface-2); color: var(--text-soft); text-align: left;
  font: 13.5px/1.2 var(--font); cursor: pointer;
}
.ux-picker-btn:hover { border-color: var(--accent); }
.ux-picker.con-valor .ux-picker-btn { color: var(--text); }
.ux-picker-av { width: 26px; height: 26px; flex: 0 0 auto; display: grid; place-items: center; border-radius: 50%;
  background: var(--surface); border: 1px dashed var(--border-strong); font: 700 10.5px/1 var(--font); color: var(--text-xsoft); }
.ux-picker.con-valor .ux-picker-av { border-style: solid; color: var(--text); }
.ux-picker.sin-ficha .ux-picker-av { border-style: dashed; }
.ux-picker-txt { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ux-picker-txt small { color: var(--mo-aviso); font-size: 11px; }
.ux-picker-x { width: 34px; height: 40px; border: 1px solid var(--border); background: transparent; color: var(--text-soft); cursor: pointer; font-size: 16px; }
.ux-picker-x:hover { color: var(--text); border-color: var(--border-strong); }

.emp-chapa-ret { display: inline-block; margin-left: 8px; vertical-align: middle; padding: 2px 7px; font: 700 10px/1.3 var(--font); letter-spacing: .06em; text-transform: uppercase;
  color: var(--text-soft); background: var(--surface-2); border: 1px solid var(--border); }
.emp-chapa-ret.vencida { color: var(--red); border-color: color-mix(in srgb, var(--red) 45%, transparent); }

.emp-cab { display: flex; align-items: center; gap: 16px; padding: 18px 20px; background: var(--surface); border: 1px solid var(--border); margin-bottom: 12px; flex-wrap: wrap; }
.emp-cab.retirado { opacity: .95; }
.emp-cab-av { width: 54px; height: 54px; font-size: 18px; }
.emp-cab-txt { flex: 1; min-width: 200px; }
.emp-cab-nom { font: 700 20px/1.2 var(--font-display); color: var(--text); display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.emp-cab-sub { font-size: 13.5px; color: var(--text-2); margin-top: 3px; }
.emp-cab-con { font-size: 12.5px; color: var(--text-soft); margin-top: 4px; }
.emp-cab-con a { color: inherit; }
.emp-cab-acc { display: flex; gap: 6px; }
.emp-tots { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; margin-bottom: 12px; }
.emp-tot { display: flex; align-items: center; gap: 10px; padding: 12px 14px; background: var(--surface); border: 1px solid var(--border); }
.emp-tot b { font: 700 22px/1 var(--font-display); color: var(--text); letter-spacing: -.02em; }
.emp-tot > span:last-child { font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--text-soft); }
.emp-sec { background: var(--surface); border: 1px solid var(--border); margin-bottom: 12px; }
.emp-sec-tit, .td-sec-tit { padding: 12px 16px; font: 700 11px/1 var(--font); letter-spacing: .1em; text-transform: uppercase; color: var(--text-soft); border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 8px; }
.td-sec-tit i { font-style: normal; color: var(--text-xsoft); font-variant-numeric: tabular-nums; }
.emp-sec-vacio { padding: 16px; font-size: 13px; color: var(--text-xsoft); }
.emp-filas { display: flex; flex-direction: column; }
.emp-fila { display: flex; align-items: center; gap: 12px; padding: 10px 16px; border-bottom: 1px solid var(--border); }
.emp-fila:last-child { border-bottom: 0; }
.emp-fila-txt { flex: 1; min-width: 0; }
.emp-fila-tit { font: 600 13.5px/1.3 var(--font); color: var(--text); }
.emp-fila-sub { font-size: 12px; color: var(--text-soft); margin-top: 2px; }
.emp-fila-acc { display: flex; gap: 6px; flex: 0 0 auto; }
.emp-notas { padding: 14px 16px; font-size: 13px; color: var(--text-2); white-space: pre-wrap; }

.ret-panel { background: var(--surface); border: 1px solid color-mix(in srgb, var(--accent) 45%, var(--border)); margin-bottom: 12px; }
.ret-panel.vencido { border-color: var(--red); }
.ret-cab { display: flex; align-items: flex-start; gap: 18px; padding: 16px 18px; border-bottom: 1px solid var(--border); flex-wrap: wrap; }
.ret-tit { font: 700 11px/1 var(--font); letter-spacing: .1em; text-transform: uppercase; color: var(--accent); margin-bottom: 8px; }
.ret-panel.vencido .ret-tit { color: var(--red); }
.ret-sub { font-size: 13.5px; color: var(--text-2); line-height: 1.5; }
.ret-sub b { color: var(--text); }
.ret-venc { color: var(--red); font-weight: 700; margin-left: 6px; }
.ret-dias { color: var(--text-soft); margin-left: 6px; }
.ret-motivo { margin-top: 6px; font-size: 13px; color: var(--text-soft); font-style: italic; }
.ret-prog { margin-left: auto; min-width: 180px; text-align: right; }
.ret-prog-n { font: 700 22px/1 var(--font-display); color: var(--text); font-variant-numeric: tabular-nums; }
.ret-prog-n b { color: var(--accent); }
.ret-barra { height: 6px; background: var(--surface-2); border: 1px solid var(--border); margin: 8px 0 6px; overflow: hidden; }
.ret-barra i { display: block; height: 100%; background: var(--accent); transition: width .3s ease; }
.ret-prog-t { font-size: 12px; color: var(--text-soft); }
.ret-acc { align-self: center; }
.ret-grupos { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 0; }
.ret-grupo { padding: 12px 18px 14px; border-right: 1px solid var(--border); border-bottom: 1px solid var(--border); }
.ret-grupo-tit { font: 700 10.5px/1 var(--font); letter-spacing: .1em; text-transform: uppercase; color: var(--text-xsoft); margin-bottom: 8px; }
.ret-tarea { display: flex; align-items: flex-start; gap: 10px; padding: 8px 0; border-bottom: 1px dashed var(--border); cursor: pointer; }
.ret-tarea:last-child { border-bottom: 0; }
.ret-tarea input { margin-top: 3px; width: 16px; height: 16px; accent-color: var(--accent); flex: 0 0 auto; cursor: pointer; }
.ret-tarea.auto { cursor: default; }
.ret-tarea.auto input { accent-color: var(--text-soft); }
.ret-tarea-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ret-tarea-tit { font: 600 13.5px/1.3 var(--font); color: var(--text); }
.ret-tarea.hecha .ret-tarea-tit { color: var(--text-soft); text-decoration: line-through; }
.ret-tarea-sub { font-size: 12px; color: var(--text-soft); }
.ret-tarea .ux-acc { flex: 0 0 auto; height: 28px; }
.ret-explica { font-size: 13.5px; line-height: 1.5; color: var(--text-2); margin: 0 0 14px; }

.td-sec { background: var(--surface); border: 1px solid var(--border); margin-bottom: 12px; }
.td-sec .ux-grid { padding: 14px; }
.td-ret .ret-barra { margin: 4px 0; }
.td-pend { margin: 4px 0 0; padding-left: 18px; font-size: 12.5px; color: var(--text-2); line-height: 1.5; }
.td-pend .mas { color: var(--text-xsoft); list-style: none; margin-left: -18px; }
.td-ret.vencido { border-color: var(--red); }
.td-dos { display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); gap: 12px; }
.td-cerrados { border-top: 1px solid var(--border); }
.td-cerrados summary { padding: 10px 16px; font-size: 12.5px; color: var(--text-soft); cursor: pointer; }

/* ── Bandas de color en tarjetas y filas: verde libre, rojo en uso/rodaje,
      ámbar avería o vencido, gris baja/neutro. Lo que gustaba de los MiFi. ── */
.ux-card.banda-ok, .td-fila.banda-ok       { border-left: 3px solid var(--pres-ok); }
.ux-card.banda-uso, .td-fila.banda-uso     { border-left: 3px solid var(--accent); }
.ux-card.banda-aviso, .td-fila.banda-aviso { border-left: 3px solid var(--mo-aviso); }
.ux-card.banda-apagado, .td-fila.banda-apagado, .td-fila.banda-neutro { border-left: 3px solid var(--border-strong); }

.emp-btn-retirar { color: var(--text-2); }
.ux-acc.retirar { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 45%, transparent); font-weight: 600; }
.ux-acc.retirar:hover { background: color-mix(in srgb, var(--accent) 10%, transparent); border-color: var(--accent); }

/* ── Tecnología › General, minimalista: cuatro cifras y UNA lista ── */
.td-cifras { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px; background: var(--border); border: 1px solid var(--border); margin-bottom: 16px; }
.td-cifra { background: var(--surface); padding: 18px 20px; }
.td-cifra b { display: block; font: 700 32px/1 var(--font-display); letter-spacing: -.03em; color: var(--text); font-variant-numeric: tabular-nums; }
.td-cifra span { display: block; margin-top: 8px; font: 700 10.5px/1 var(--font); letter-spacing: .1em; text-transform: uppercase; color: var(--text-soft); }
.td-cifra.acento b { color: var(--accent); }
.td-cifra.mal b { color: var(--red); }
.td-lista { display: flex; flex-direction: column; gap: 14px; }
.td-grupo { background: var(--surface); border: 1px solid var(--border); }
.td-grupo-tit { padding: 12px 18px; font: 700 11px/1 var(--font); letter-spacing: .1em; text-transform: uppercase; color: var(--text-soft); border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 8px; }
.td-grupo-tit i { font-style: normal; color: var(--text-xsoft); font-variant-numeric: tabular-nums; }
.td-vacio { padding: 18px; font-size: 13px; color: var(--text-xsoft); }
.td-fila { display: flex; align-items: center; gap: 14px; padding: 12px 18px 12px 15px; border-bottom: 1px solid var(--border); }
.td-fila:last-child { border-bottom: 0; }
.td-av { width: 34px; height: 34px; font-size: 12px; }
.td-fila-txt { flex: 1; min-width: 0; }
.td-fila-tit { font: 600 14px/1.3 var(--font); color: var(--text); display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.td-fila-sub { font-size: 12.5px; color: var(--text-soft); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.td-cod { font: 500 11.5px/1 var(--font-mono); color: var(--text-soft); }
.td-chapa { font: 700 10px/1 var(--font); letter-spacing: .06em; text-transform: uppercase; color: var(--text-soft); padding: 3px 6px; border: 1px solid var(--border); }
.td-chapa.mal { color: var(--red); border-color: color-mix(in srgb, var(--red) 45%, transparent); }
.td-prog { width: 90px; height: 5px; background: var(--surface-2); border: 1px solid var(--border); overflow: hidden; flex: 0 0 auto; }
.td-prog i { display: block; height: 100%; background: var(--accent); }
.td-fila-acc { flex: 0 0 auto; }
.td-cerrados { background: var(--surface); border: 1px solid var(--border); }
.td-cerrados summary { padding: 12px 18px; font-size: 12.5px; color: var(--text-soft); cursor: pointer; }
@media (max-width: 720px) { .td-cifras { grid-template-columns: repeat(2, 1fr); } .td-prog { display: none; } .td-fila-sub { white-space: normal; } }

/* ═══════════════════════════════════════════════════════════════════════════
   PROYECTOS, EN CALMA: una barra, tarjetas con una sola acción, ficha por
   secciones con superficie propia. Lo que se pulsa parece un botón; lo demás,
   no.
   ═══════════════════════════════════════════════════════════════════════ */
.proy-barra .proy-tabs { margin: 0; border-bottom: 0; padding: 0; }
.proy-barra .proy-tab { border-bottom: 0; margin-bottom: 0; padding: 0 14px; height: 34px; font-size: 13px; }
.proy-barra .proy-tab.active { color: var(--text); }
.proy-tab-n { font-size: 11px; color: var(--text-soft); font-variant-numeric: tabular-nums; margin-left: 4px; }
.proy-buscar-caja { flex: 1 1 240px; }
.proy-filtros-n { margin-left: 4px; font-size: 11px; color: var(--accent); font-weight: 700; }
.proy-filtros-n:empty { display: none; }
.proy-mas .ux-select { flex: 1 1 160px; max-width: 220px; }
.proy-cal-mini { margin-bottom: 12px; }
.proy-cal-mini > summary .pcm-tit { font: 700 11px/1 var(--font); letter-spacing: .1em; text-transform: uppercase; color: var(--text-soft); }

.proy-grid { grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); }
.proy-grid[hidden] { display: none; }
.proy-card { cursor: pointer; border-left: 3px solid var(--proy-color, var(--border-strong)); }
.proy-card:hover { border-color: var(--border-strong); border-left-color: var(--proy-color, var(--border-strong)); transform: translateY(-1px); }
.proy-card:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.proy-card-color { width: 10px; height: 10px; border-radius: 50%; background: var(--proy-color); flex: 0 0 auto; }
.proy-card-cli { font: 600 11px/1 var(--font); letter-spacing: .06em; text-transform: uppercase; color: var(--text-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.proy-card-nom { font-size: 18px; }
.proy-card-cuando { font-size: 13px; color: var(--text-2); }
.proy-card-cuando.tarde { color: var(--red); font-weight: 600; }
.proy-card-prog { height: 4px; background: var(--surface-2); border: 1px solid var(--border); overflow: hidden; }
.proy-card-prog i { display: block; height: 100%; background: var(--proy-color, var(--text-soft)); }
.proy-card-fechas { display: flex; justify-content: space-between; font: 11px/1 var(--font-mono); color: var(--text-xsoft); margin-top: -4px; }
.proy-card-pie { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding-top: 10px; border-top: 1px solid var(--border); margin-top: 2px; }
.proy-card-quien { font-size: 12.5px; color: var(--text-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.proy-card-chips { display: flex; gap: 6px; flex: 0 0 auto; }
.proy-card-chip { display: inline-flex; align-items: center; gap: 4px; height: 22px; padding: 0 7px; font: 600 11.5px/1 var(--font); color: var(--text-2); background: var(--surface-2); border: 1px solid var(--border); font-variant-numeric: tabular-nums; }
.proy-card-chip.eur { color: var(--text); }
#proy-vista-tabla[hidden] { display: none; }

/* ── La ficha del proyecto ── */
.pf { max-width: 1240px; }
.pf-volver { color: var(--text-soft); }
.pf-cab { padding: 18px 20px; background: var(--surface); border: 1px solid var(--border); border-left: 4px solid var(--proy-color, var(--border-strong)); margin-bottom: 12px; align-items: center; }
.pf-punto { display: none; }
.pf-nombre { font-size: 24px; }
.pf-meta { gap: 12px; font-size: 13px; margin-top: 6px; }
.pf-cab-der .btn { height: 34px; }
.pf-cifras { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 1px; padding: 0; background: var(--border); border: 1px solid var(--border); margin-bottom: 12px; }
.pf-cifra { background: var(--surface); padding: 14px 16px; }
.pf-cifra-n { font-size: 22px; }
.pf-cifra-l { font-size: 10px; letter-spacing: .09em; font-weight: 700; margin-top: 6px; display: block; }
.pf-progreso { background: var(--surface); padding: 12px 16px 14px; margin-top: 0; }
.pf-progreso-track { height: 4px; }
.pf-tabs { gap: 0; margin: 0 0 14px; padding: 3px; background: var(--surface); border: 1px solid var(--border); width: fit-content; border-bottom: 1px solid var(--border); }
.pf-tab { height: 34px; padding: 0 14px; margin-bottom: 0; border-bottom: 0; font-weight: 600; font-size: 13px; }
.pf-tab:hover { color: var(--text); background: var(--surface-2); }
.pf-tab.activa { color: var(--text); background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--border-strong); border-bottom: 0; }
.pf-tab i { font-style: normal; font-size: 11px; color: var(--text-soft); font-variant-numeric: tabular-nums; margin-left: 4px; }
.pf-cols { gap: 12px; align-items: start; }
.pf-sec { margin-bottom: 12px; background: var(--surface); border: 1px solid var(--border); padding: 0; }
.pf-sec-tit { margin: 0; padding: 12px 16px; border-bottom: 1px solid var(--border); font-size: 11px; letter-spacing: .1em; font-weight: 700; }
.pf-sec > *:not(.pf-sec-tit) { margin-left: 16px; margin-right: 16px; }
.pf-sec > .pf-datos, .pf-sec > .pf-contactos, .pf-sec > .pf-nada, .pf-sec > .pf-notas, .pf-sec > .pf-pres-lista, .pf-sec > .pf-tabla, .pf-sec > .pf-flota, .pf-sec > .pf-vacia { margin-top: 4px; margin-bottom: 12px; }
.pf-sec > .pf-nada, .pf-sec > .pf-vacia { padding: 14px 0; color: var(--text-xsoft); font-size: 13px; }
.pf-sec-add { text-decoration: none; height: 26px; padding: 0 9px; border: 1px solid var(--border); color: var(--text-2); font-size: 12px; letter-spacing: 0; text-transform: none; display: inline-flex; align-items: center; }
.pf-sec-add:hover { color: var(--text); border-color: var(--border-strong); background: var(--surface-2); }
.pf-dato { grid-template-columns: 160px minmax(0, 1fr); padding: 10px 0; }
.pf-dato dt { font-size: 12px; color: var(--text-soft); }
.pf-dato dd { font-size: 14px; }
.pf-datos .pf-dato:last-child { border-bottom: 0; }
.pf-editando .pf-dato dd input, .pf-editando .pf-dato dd select, .pf-editando .pf-dato dd textarea { background: var(--surface-2); border: 1px solid var(--accent); }

/* Ficha de proyecto: una sola acción destacada («+ Presupuesto»). El selector
   de subproyecto es un control, no una llamada a la acción; «Eliminar» se
   deja discreto hasta pasar por encima. Cinco cifras y la barra de progreso
   ocupando la fila entera, sin hueco. */
.pf-cab .sub-sel-btn { background: var(--surface-2) !important; color: var(--text) !important; border: 1px solid var(--border-strong) !important; box-shadow: none !important; font-weight: 600; }
.pf-cab .sub-sel-btn:hover { border-color: var(--accent) !important; }
.pf-cab .sub-sel-btn svg, .pf-cab .sub-sel-btn * { color: inherit !important; }
.pf-cab .pf-borrar { color: var(--text-soft); border-color: transparent; }
.pf-cab .pf-borrar:hover { color: var(--red); border-color: color-mix(in srgb, var(--red) 40%, transparent); background: transparent; }
.pf-cifras { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.pf-cifras .pf-progreso { grid-column: 1 / -1; }

/* Constructor de presupuestos: fecha y número a la vista, junto al proyecto. */
.pres-dato-fecha input, .pres-dato-num input { height: 36px; }
.pres-dato-fecha { min-width: 160px; }
.pres-dato-num { min-width: 150px; }
.pres-dato-num input { font-family: var(--font-mono); font-size: 13px; }
.pres-dato > span small { font-weight: 400; color: var(--text-xsoft); }

/* Constructor: la fila de datos deja respirar al proyecto (que se quedaba en
   2 px al meter la fecha y el número), y el panel de «Más datos» es una
   rejilla ordenada en vez de una fila apretada. */
#pres-doc .pres-datos-fila { flex-wrap: wrap; align-items: flex-end; gap: 10px 14px; }
#pres-doc .pres-datos-fila > .pres-dato:first-child { flex: 1 1 260px; min-width: 240px; }
#pres-doc .pres-datos-fila > .pres-dato-fecha { flex: 0 0 170px; }
#pres-doc .pres-datos-fila > .pres-dato-num { flex: 0 0 160px; }
#pres-doc .pres-datos-fila > .pres-datos-mas { align-self: flex-end; }
#pres-doc .pres-datos-extra { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 12px 14px; align-items: start; }
#pres-doc .pres-datos-extra .pres-dato { min-width: 0; flex: none; }
#pres-doc .pres-datos-extra .pres-dato-ancho { grid-column: 1 / -1; }
#pres-doc .pres-datos-extra .pres-dato > span { display: block; white-space: normal; line-height: 1.25; margin-bottom: 4px; }
#pres-doc .pres-datos-extra input, #pres-doc .pres-datos-extra textarea { width: 100%; }
/* El subproyecto, en la fila de datos: tenía el «+» encima del selector y el
   selector aplastado. Ancho fijo y los dos en línea. */
#pres-doc .pres-datos-fila > #pres-sub-wrap { flex: 0 0 250px; min-width: 250px; }
#pres-doc #pres-sub-wrap .pres-sub-fila { display: flex; flex-wrap: nowrap; align-items: stretch; }
#pres-doc #pres-sub-wrap .dd-bloque { flex: 1 1 auto; min-width: 0; display: block; }
#pres-doc #pres-sub-wrap .selector-boton { width: 100%; min-width: 0; }
#pres-doc #pres-sub-wrap .pres-sub-nuevo { height: auto; align-self: stretch; }

/* ── El presupuesto, DENTRO del proyecto ────────────────────────────────────
   Desde Finanzas se abre el documento (y su constructor) en la misma pestaña
   del proyecto: el visor y el constructor se trasladan a #proy-ficha-pres y
   vuelven a Presupuestos al cerrar. Una miga arriba dice dónde estás. */
#proy-ficha-pres { display: flex; flex-direction: column; min-height: 0; }
.fz-miga {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 10px 0 14px; font-size: 12.5px; color: var(--text-soft);
}
.fz-miga b { color: var(--text); font-weight: 600; }
.fz-miga .sep { color: var(--text-xsoft); }
.fz-miga button { background: none; border: 0; padding: 0; font: inherit; color: var(--accent); cursor: pointer; }
.fz-miga button:hover { text-decoration: underline; }
#proy-ficha-pres > #pres-doc-view { flex: 1 1 auto; min-height: 0; }
body.constructor-abierto #page-proyecto,
body.constructor-abierto #proy-ficha-pres { height: 100%; min-height: 0; }
body.constructor-abierto #proy-ficha-pres .fz-miga { display: none; }
body.constructor-abierto #proy-ficha-pres > #pres-builder-view { flex: 1 1 auto; height: auto; }
.impc-cifra.bien b { color: var(--green, #2e9e5b); }
.impc-notas { margin: 12px 0 0; padding-left: 18px; font-size: 12.5px; color: var(--text-soft); line-height: 1.5; }
.impc-notas li + li { margin-top: 4px; }

/* Aspecto por bloque en el editor de plantillas: si el bloque lleva fondo o
   borde propios, la vista no pinta el suyo encima. */
.pl-vista.asp-propio .plv-cliente { background: transparent; padding: 0; }
.pl-asp { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border); }
.pl-asp-tit { font: 700 10.5px/1 var(--font); letter-spacing: .08em; text-transform: uppercase; color: var(--text-soft); margin-bottom: 10px; }
.pl-asp-fila { display: flex; align-items: center; gap: 10px; }
.pl-asp-color { margin-top: 8px; }
.pl-asp-color span { font-family: var(--font-mono); font-size: 11.5px; color: var(--text-soft); }

/* ═══════════════════════════════════════════════════════════════════════════
   TECNOLOGÍA · GENERAL, POR WIDGETS
   Rejilla de dos columnas; cada widget a media anchura o a toda, se arrastra
   por su asa y se esconde desde «Personalizar». Se guarda por usuario.
   ═══════════════════════════════════════════════════════════════════════ */
.td-rejilla { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; align-items: start; }
.td-widget { background: var(--surface); border: 1px solid var(--border); min-width: 0; }
.td-widget.ancho { grid-column: 1 / -1; }
.td-widget-cab { display: flex; align-items: center; gap: 10px; padding: 10px 14px 10px 10px; border-bottom: 1px solid var(--border); }
.td-widget-cab h3 { flex: 1; margin: 0; font: 700 11px/1 var(--font); letter-spacing: .1em; text-transform: uppercase; color: var(--text-soft); display: flex; align-items: center; gap: 8px; min-width: 0; }
.td-widget-cab h3 i { font-style: normal; color: var(--text-xsoft); font-variant-numeric: tabular-nums; }
.td-asa { width: 18px; height: 18px; display: grid; place-items: center; color: var(--text-xsoft); cursor: grab; border-radius: 4px; flex: 0 0 auto; }
.td-asa:hover { background: var(--surface-2); color: var(--text-soft); }
.td-widget.dragging { opacity: .45; }
.td-widget.drag-over { outline: 2px dashed var(--accent); outline-offset: 2px; }
.td-widget-acc { display: flex; gap: 4px; }
.td-widget-acc button { width: 26px; height: 26px; border: 1px solid transparent; border-radius: 5px; background: none; color: var(--text-xsoft); cursor: pointer; display: grid; place-items: center; }
.td-widget-acc button:hover { border-color: var(--border); color: var(--text); background: var(--surface-2); }
.td-widget .td-cifras { border: 0; }
.td-widget .td-fila:first-child { border-top: 0; }
.td-widget .td-vacio { padding: 16px 14px; }
.td-mas { display: block; width: 100%; padding: 9px; background: none; border: 0; border-top: 1px solid var(--border); font: 600 12px/1 var(--font); color: var(--accent); cursor: pointer; }
.td-mas:hover { background: var(--surface-2); }
@media (max-width: 960px) { .td-rejilla { grid-template-columns: 1fr; } .td-widget.ancho { grid-column: auto; } }

/* Accesos rápidos */
.td-accesos { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1px; background: var(--border); }
.td-acceso { background: var(--surface); border: 0; padding: 16px 12px; display: flex; flex-direction: column; align-items: center; gap: 8px; font: 600 12.5px/1.2 var(--font); color: var(--text); cursor: pointer; }
.td-acceso:hover { background: var(--surface-2); color: var(--accent); }
.td-acceso .ux-tile { width: 34px; height: 34px; }

/* Últimos movimientos */
.td-act { display: flex; gap: 12px; padding: 10px 14px; border-top: 1px solid var(--border); font-size: 12.5px; line-height: 1.4; }
.td-act:first-child { border-top: 0; }
.td-act-cuando { flex: 0 0 74px; color: var(--text-xsoft); font-variant-numeric: tabular-nums; font-size: 11.5px; padding-top: 1px; }
.td-act-txt { flex: 1; min-width: 0; color: var(--text); }
.td-act-txt b { font-weight: 600; }

/* Tareas de IT */
.tdt-barra { display: flex; align-items: center; gap: 10px; padding: 10px 14px; border-bottom: 1px solid var(--border); flex-wrap: wrap; }
.tdt-filtros { display: flex; border: 1px solid var(--border); border-radius: 6px; overflow: hidden; }
.tdt-filtros button { padding: 5px 10px; border: 0; background: none; font: 600 11.5px/1 var(--font); color: var(--text-soft); cursor: pointer; }
.tdt-filtros button + button { border-left: 1px solid var(--border); }
.tdt-filtros button.activo { background: var(--text); color: var(--bg); }
.tdt-nueva { display: flex; gap: 8px; padding: 10px 14px; border-bottom: 1px solid var(--border); }
.tdt-nueva input { flex: 1; min-width: 0; height: 34px; padding: 0 11px; border: 1px solid var(--border); border-radius: 6px; background: var(--bg); color: var(--text); font: 13px var(--font); }
.tdt-nueva input:focus { outline: none; border-color: var(--accent); }
.tdt-fila { display: flex; align-items: flex-start; gap: 10px; padding: 10px 14px; border-top: 1px solid var(--border); }
.tdt-fila:first-child { border-top: 0; }
.tdt-fila.hecha .tdt-tit { text-decoration: line-through; color: var(--text-xsoft); }
.tdt-check { width: 18px; height: 18px; margin: 2px 0 0; flex: 0 0 auto; accent-color: var(--accent); cursor: pointer; }
.tdt-txt { flex: 1; min-width: 0; }
.tdt-tit { font: 500 13.5px/1.35 var(--font); color: var(--text); cursor: pointer; word-break: break-word; }
.tdt-tit:hover { color: var(--accent); }
.tdt-sub { display: flex; flex-wrap: wrap; gap: 6px 10px; margin-top: 4px; font-size: 11.5px; color: var(--text-soft); align-items: center; }
.tdt-chip { display: inline-flex; align-items: center; gap: 4px; padding: 2px 7px; border: 1px solid var(--border); border-radius: 999px; font: 600 10.5px/1.3 var(--font); color: var(--text-soft); }
.tdt-chip.alta { color: var(--red); border-color: color-mix(in srgb, var(--red) 45%, transparent); }
.tdt-chip.vencida { color: var(--red); border-color: color-mix(in srgb, var(--red) 45%, transparent); background: color-mix(in srgb, var(--red) 8%, transparent); }
.tdt-chip.hoy { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 45%, transparent); }
.tdt-av { width: 24px; height: 24px; font-size: 9.5px; flex: 0 0 auto; margin-top: 1px; }
.tdt-editor { margin-top: 10px; padding: 12px; background: var(--bg); border: 1px solid var(--border); border-radius: 6px; display: grid; gap: 10px; }
.tdt-editor .fila2 { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.tdt-editor label { display: flex; flex-direction: column; gap: 4px; font: 700 10px/1 var(--font); letter-spacing: .07em; text-transform: uppercase; color: var(--text-soft); }
.tdt-editor input, .tdt-editor textarea, .tdt-editor select { height: 32px; padding: 0 9px; border: 1px solid var(--border); border-radius: 5px; background: var(--surface); color: var(--text); font: 13px var(--font); text-transform: none; letter-spacing: 0; }
.tdt-editor textarea { height: auto; min-height: 60px; padding: 7px 9px; resize: vertical; }
.tdt-editor .pl-seg { height: 32px; }
.tdt-editor .pl-seg button { flex: 1; }
.tdt-editor-pie { display: flex; justify-content: space-between; align-items: center; gap: 8px; font-size: 11.5px; color: var(--text-xsoft); }
.dash-panel-mover .td-panel-ancho { width: auto; padding: 0 8px; font: 600 10.5px/1 var(--font); letter-spacing: .04em; text-transform: uppercase; }

/* ═══════════════════════════════════════════════════════════════════════════
   TAREAS DE IT · AL ESTILO THINGS
   Dos columnas: listas inteligentes y personas a la izquierda; a la derecha,
   filas limpias con su círculo y la tarjeta que se abre en el sitio.
   ═══════════════════════════════════════════════════════════════════════ */
.tt { display: grid; grid-template-columns: 232px minmax(0, 1fr); gap: 0; min-height: calc(100vh - 120px); background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.tt-lados { background: var(--bg); border-right: 1px solid var(--border); padding: 14px 10px; display: flex; flex-direction: column; gap: 18px; }
.tt-listas { display: flex; flex-direction: column; gap: 2px; }
.tt-lista-btn, .tt-persona { display: flex; align-items: center; gap: 10px; width: 100%; padding: 7px 10px; border: 0; border-radius: 7px; background: none; font: 500 13.5px/1.2 var(--font); color: var(--text); cursor: pointer; text-align: left; }
.tt-lista-btn:hover, .tt-persona:hover { background: var(--surface-2); }
.tt-lista-btn.activa, .tt-persona.activa { background: color-mix(in srgb, var(--text) 9%, transparent); font-weight: 600; }
.tt-lista-btn span, .tt-persona span:not(.ux-avatar):not(.tt-persona-av) { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tt-lista-btn i, .tt-persona i { font-style: normal; font-size: 12px; color: var(--text-xsoft); font-variant-numeric: tabular-nums; }
.tt-ico { flex: 0 0 auto; }
.tt-lados-tit { padding: 0 10px 6px; font: 700 10px/1 var(--font); letter-spacing: .1em; text-transform: uppercase; color: var(--text-xsoft); }
.tt-persona-av { width: 20px; height: 20px; font-size: 8.5px; flex: 0 0 auto; }
.tt-persona-av.todos { display: grid; place-items: center; color: var(--text-soft); font-size: 12px; }

.tt-main { position: relative; padding: 26px 34px 90px; min-width: 0; }
.tt-cab { display: flex; align-items: center; gap: 12px; margin-bottom: 18px; }
.tt-cab h2 { margin: 0; font: 700 24px/1.1 var(--font-display, var(--font)); letter-spacing: -.02em; color: var(--text); }
.tt-cab h2 small { font-size: 15px; font-weight: 500; color: var(--text-soft); }
.tt-cab p { margin: 3px 0 0; font-size: 13px; color: var(--text-soft); }
.tt-grupo + .tt-grupo { margin-top: 18px; }
.tt-grupo-tit { font: 700 13px/1 var(--font); color: var(--text); padding: 0 0 8px 34px; border-bottom: 1px solid var(--border); margin-bottom: 4px; }
.tt-lista { display: flex; flex-direction: column; }

.tt-fila { display: flex; align-items: flex-start; gap: 12px; padding: 8px 8px 8px 4px; border-radius: 8px; transition: opacity .45s ease, transform .45s ease, background .15s; }
.tt-fila:hover { background: color-mix(in srgb, var(--text) 4%, transparent); }
.tt-fila.abierta { display: block; padding: 0; margin: 8px 0; background: none; }
.tt-fila.abierta:hover { background: none; }
.tt-fila.abierta > .tt-circ { display: none; }
.tt-fila.yendose { opacity: 0; transform: translateX(14px); }
.tt-fila.hecha .tt-tit { color: var(--text-xsoft); text-decoration: line-through; }
.tt-fila.arrastrando { opacity: .4; }
.tt-fila.sobre { box-shadow: 0 -2px 0 var(--accent); }
.tt-circ { width: 18px; height: 18px; margin-top: 2px; flex: 0 0 auto; border-radius: 50%; border: 1.6px solid var(--text-xsoft); background: none; color: #fff; display: grid; place-items: center; cursor: pointer; padding: 0; transition: background .15s, border-color .15s; }
.tt-circ svg { opacity: 0; transition: opacity .15s; }
.tt-circ:hover { border-color: var(--text-soft); background: color-mix(in srgb, var(--text) 8%, transparent); }
.tt-circ.on { background: #3b82f6; border-color: #3b82f6; }
.tt-circ.on svg { opacity: 1; }
.tt-circ.vacio { border-style: dashed; cursor: default; }
.tt-txt { flex: 1; min-width: 0; cursor: default; }
.tt-tit { font: 500 14px/1.4 var(--font); color: var(--text); word-break: break-word; }
.tt-nota { font-size: 12px; color: var(--text-xsoft); margin-top: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tt-meta { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; padding-top: 2px; font-size: 11.5px; color: var(--text-xsoft); }
.tt-flag { color: var(--red); display: inline-flex; }
.tt-cuando.pasada { color: var(--red); font-weight: 600; }
.tt-subs-n { font-variant-numeric: tabular-nums; }
.tt-av { width: 20px; height: 20px; font-size: 8.5px; }
.tt-nueva input { flex: 1; min-width: 0; border: 0; background: none; font: 500 14px/1.4 var(--font); color: var(--text); padding: 0; outline: none; }
.tt-nueva input::placeholder { color: var(--text-xsoft); }
.tt-vacio { padding: 60px 0; text-align: center; color: var(--text-xsoft); font-size: 14px; line-height: 2; }
.tt-vacio-btn { background: none; border: 0; color: var(--accent); font: 600 13px var(--font); cursor: pointer; }
.tt-mas { position: absolute; right: 26px; bottom: 26px; width: 46px; height: 46px; border-radius: 50%; border: 0; background: #3b82f6; color: #fff; display: grid; place-items: center; cursor: pointer; box-shadow: 0 6px 18px rgba(59,130,246,.35); }
.tt-mas:hover { filter: brightness(1.08); }

/* La tarjeta abierta */
.tt-card { background: var(--bg); border: 1px solid var(--border); border-radius: 10px; padding: 14px 16px 12px; box-shadow: 0 8px 28px rgba(0,0,0,.18); display: grid; gap: 8px; }
.tt-card-tit { border: 0; background: none; padding: 0; font: 600 16px/1.3 var(--font); color: var(--text); outline: none; width: 100%; }
.tt-card-notas { border: 0; background: none; padding: 0; font: 13.5px/1.5 var(--font); color: var(--text-soft); resize: none; outline: none; width: 100%; }
.tt-card-notas::placeholder, .tt-card-tit::placeholder { color: var(--text-xsoft); }
.tt-subs { display: flex; flex-direction: column; gap: 2px; margin: 2px 0 4px; }
.tt-sub { display: flex; align-items: center; gap: 9px; }
.tt-sub input { flex: 1; border: 0; background: none; padding: 4px 0; font: 13.5px/1.3 var(--font); color: var(--text); outline: none; }
.tt-sub.on input { color: var(--text-xsoft); text-decoration: line-through; }
.tt-sub.nueva input { color: var(--text-soft); }
.tt-sub-circ { width: 15px; height: 15px; border-radius: 50%; border: 1.5px solid var(--text-xsoft); background: none; color: #fff; display: grid; place-items: center; padding: 0; cursor: pointer; flex: 0 0 auto; }
.tt-sub-circ svg { opacity: 0; }
.tt-sub.on .tt-sub-circ { background: #3b82f6; border-color: #3b82f6; }
.tt-sub.on .tt-sub-circ svg { opacity: 1; }
.tt-sub-circ.vacio { border-style: dashed; cursor: default; }
.tt-card-pie { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; padding-top: 8px; border-top: 1px solid var(--border); }
.tt-chips { display: flex; gap: 6px; flex-wrap: wrap; }
.tt-chip { display: inline-flex; align-items: center; gap: 6px; height: 26px; padding: 0 9px; border: 1px solid var(--border); border-radius: 999px; background: var(--surface); font: 600 11.5px/1 var(--font); color: var(--text-soft); cursor: pointer; list-style: none; user-select: none; }
.tt-chip::-webkit-details-marker { display: none; }
.tt-chip:hover { border-color: var(--text-xsoft); color: var(--text); }
.tt-chip.con { color: var(--text); border-color: color-mix(in srgb, var(--text) 25%, transparent); }
.tt-chip.alta { color: var(--red); border-color: color-mix(in srgb, var(--red) 45%, transparent); }
.tt-chip .tt-av { width: 16px; height: 16px; font-size: 7px; }
.tt-dd { position: relative; }
.tt-dd-menu { position: absolute; left: 0; top: 30px; z-index: 30; min-width: 190px; background: var(--surface); border: 1px solid var(--border); border-radius: 9px; box-shadow: 0 10px 30px rgba(0,0,0,.25); padding: 6px; display: flex; flex-direction: column; gap: 1px; }
.tt-dd-menu button { text-align: left; padding: 7px 10px; border: 0; border-radius: 6px; background: none; font: 500 13px/1.2 var(--font); color: var(--text); cursor: pointer; }
.tt-dd-menu button:hover, .tt-dd-menu button.activo { background: var(--surface-2); }
.tt-dd-menu button.quitar { color: var(--red); }
.tt-dd-fecha { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 6px 10px; font: 500 12.5px var(--font); color: var(--text-soft); }
.tt-dd-fecha input { border: 1px solid var(--border); border-radius: 5px; background: var(--bg); color: var(--text); font: 12.5px var(--font); padding: 3px 6px; }
.tt-card-acc { display: flex; align-items: center; gap: 8px; }
.tt-card-quien { font-size: 11.5px; color: var(--text-xsoft); }
.tt-borrar { width: 28px; height: 28px; border: 0; border-radius: 6px; background: none; color: var(--text-xsoft); display: grid; place-items: center; cursor: pointer; }
.tt-borrar:hover { color: var(--red); background: color-mix(in srgb, var(--red) 10%, transparent); }
.tt-cerrar { height: 28px; padding: 0 12px; border: 0; border-radius: 6px; background: #3b82f6; color: #fff; font: 600 12.5px var(--font); cursor: pointer; }
@media (max-width: 860px) { .tt { grid-template-columns: 1fr; } .tt-lados { border-right: 0; border-bottom: 1px solid var(--border); flex-direction: row; flex-wrap: wrap; } .tt-listas { flex-direction: row; flex-wrap: wrap; } .tt-personas { display: none; } .tt-main { padding: 18px 16px 80px; } }

/* El widget del panel, con el mismo círculo */
.tdt-fila .tt-circ { margin-top: 3px; }
.tdt-bloque-tit { padding: 10px 14px 4px; font: 700 10.5px/1 var(--font); letter-spacing: .08em; text-transform: uppercase; color: var(--text-xsoft); }
.tdt-bloque-tit i { font-style: normal; color: var(--text-xsoft); }
/* El aspecto del bloque, a la vista: arriba del panel y con su botón en la etiqueta. */
.pl-asp { margin: 0 0 14px; padding: 10px 12px 12px; border: 1px solid var(--border); border-radius: 8px; background: color-mix(in srgb, var(--text) 3%, transparent); transition: outline-color .3s; outline: 2px solid transparent; }
.pl-asp.destacar { outline-color: var(--accent); }
.pl-bloque-asp { width: 20px; height: 20px; border: 0; border-radius: 4px; background: none; color: inherit; opacity: .8; cursor: pointer; display: grid; place-items: center; padding: 0; }
.pl-bloque-asp:hover { opacity: 1; background: rgba(255,255,255,.18); }
.tt-lista-btn i, .tt-persona i { margin-left: auto; padding-left: 8px; }

/* ── IT Stock, menos plano ─────────────────────────────────────────────── */
.it-marca { width: 30px; height: 30px; border-radius: 8px; display: inline-grid; place-items: center; color: #fff; font: 800 11px/1 var(--font); letter-spacing: -.02em; flex: 0 0 auto; text-transform: none; }
/* ── EL AZULEJO DE APPLE ──────────────────────────────────────────────────
   (15/9/2026) Todas las marcas pintan su azulejo con el color de la marca y
   las letras en blanco; Apple era la única sin fondo, con el logo en blanco
   suelto. En modo oscuro colaba —blanco sobre carta oscura— y en modo claro
   era blanco sobre blanco: setenta y tres logos invisibles en IT Stock.

   Ahora tiene su fondo como el resto. En oscuro se aclara un punto para que
   el azulejo siga distinguiéndose de la tarjeta, que ahí también es casi
   negra; el logo sigue blanco en los dos. */
.it-marca.apple { background: #1d1d1f; }
:root[data-tema="oscuro"] .it-marca.apple { background: #34343a; }
@media (prefers-color-scheme: dark) {
  :root:not([data-tema="claro"]) .it-marca.apple { background: #34343a; }
}
.it-marca.apple svg { color: #fff; }
.ux-card-cab .it-marca { width: 34px; height: 34px; font-size: 12px; }
.ux-tabla tr.it-fila td:first-child { border-left: 3px solid transparent; }
.ux-tabla tr.it-fila.banda-ok td:first-child { border-left-color: var(--pres-ok); }
.ux-tabla tr.it-fila.banda-uso td:first-child { border-left-color: var(--accent); }
.ux-tabla tr.it-fila.banda-aviso td:first-child { border-left-color: var(--mo-aviso); }
.ux-tabla tr.it-fila.banda-apagado td:first-child { border-left-color: var(--border-strong); }
.it-cod { display: inline-block; font: 600 11.5px/1 var(--font-mono); padding: 5px 7px; border-radius: 6px; background: var(--surface-2); color: var(--text-soft); letter-spacing: .02em; }
.it-nom { display: flex; align-items: center; gap: 10px; min-width: 0; }
.it-nom-txt { min-width: 0; }
.it-nom-txt b { display: block; font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.it-nom-txt small { display: block; font-size: 11.5px; color: var(--text-xsoft); margin-top: 1px; }
.it-tipo { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--text-soft); white-space: nowrap; }
.it-tipo svg { opacity: .65; }
.it-serie { color: var(--text-soft); font-size: 12px; }
.it-quien { display: flex; align-items: center; gap: 8px; white-space: nowrap; }
.it-quien .ux-avatar { width: 24px; height: 24px; font-size: 9px; }
.ux-estado.it-estado { margin-left: 0; padding: 5px 9px 5px 8px; border-radius: 999px; font-weight: 700; }
.ux-estado.it-estado.ok      { background: color-mix(in srgb, var(--pres-ok) 14%, transparent); color: var(--pres-ok); }
.ux-estado.it-estado.uso     { background: color-mix(in srgb, var(--accent) 13%, transparent); color: var(--accent); }
.ux-estado.it-estado.aviso   { background: color-mix(in srgb, var(--mo-aviso) 16%, transparent); color: var(--mo-aviso); }
.ux-estado.it-estado.apagado { background: color-mix(in srgb, var(--text-xsoft) 16%, transparent); color: var(--text-soft); }
.ux-estado.it-estado.ok i { background: var(--pres-ok); }
.it-resumen { display: inline-flex; flex-wrap: wrap; gap: 6px; margin-left: 14px; vertical-align: middle; }
.it-res { display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 10px 0 8px; border: 1px solid var(--border); border-radius: 999px; background: var(--surface); font: 600 11.5px/1 var(--font); color: var(--text-soft); cursor: pointer; }
.it-res i { width: 8px; height: 8px; border-radius: 50%; }
.it-res b { font-weight: 800; color: var(--text); font-variant-numeric: tabular-nums; }
.it-res.ok i { background: var(--pres-ok); } .it-res.uso i { background: var(--accent); } .it-res.aviso i { background: var(--mo-aviso); } .it-res.apagado i { background: var(--text-xsoft); }
.it-res:hover { border-color: var(--text-xsoft); color: var(--text); }
.it-res.activo { background: var(--text); color: var(--bg); border-color: var(--text); } .it-res.activo b { color: var(--bg); }

/* ═══════════════════════════════════════════════════════════════════════════
   LA CAPA DE CARÁCTER · lo que hace que dentro se parezca al login
   (11/9/2026) «El login es súper moderno y vistoso, pero entras y pierde».
   Lo que tiene el login y no tenía el interior: la retícula fina de fondo, el
   rótulo en monoespaciada con letra separada, el punto rojo como firma, la
   tipografía grande de display y un poco de profundidad al pasar el ratón.
   Todo con los tokens de la paleta (space indigo · lavender grey · platinum ·
   punch red), así que vale igual en claro y en oscuro.
   ═══════════════════════════════════════════════════════════════════════ */
:root {
  --trama:        color-mix(in srgb, var(--text) 5.5%, transparent);
  --trama-lado:   38px;
  --mono-rotulo:  'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
}

/* 1 · El fondo: la retícula de la web y un resplandor rojo bajo, arriba a la
   derecha, que rompe el plano sin parecer un degradado de plantilla. */
.main-scroll {
  background-color: var(--bg);
  background-image:
    linear-gradient(to right,  var(--trama) 1px, transparent 1px),
    linear-gradient(to bottom, var(--trama) 1px, transparent 1px);
  background-size: var(--trama-lado) var(--trama-lado);
}
.main { position: relative; isolation: isolate; }
.main::before {
  content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: radial-gradient(ellipse 70% 42% at 100% 0%, rgba(var(--acento-rgb), .085), transparent 62%);
}

/* 2 · La cabecera de cada pantalla: título grande de display con el punto rojo
   delante, como el «· Bulx» del login. */
.page-title {
  font-family: var(--font-display); font-size: 31px; font-weight: 750;
  letter-spacing: -.035em; line-height: 1.05;
  display: inline-flex; align-items: center; gap: 13px;
}
.page-title::before {
  content: ''; width: 10px; height: 10px; flex: 0 0 auto;
  background: var(--accent);
  box-shadow: 0 0 0 4px rgba(var(--acento-rgb), .14);
}
.page-subtitle { color: var(--text-soft); font-size: 13.5px; }

/* 3 · Los rótulos de sección, en monoespaciada separada: la firma tipográfica
   del login, repetida en cada caja. */
.section-title, .td-widget-cab h3, .td-grupo-tit, .vf-bloque-tit, .usr-bloque-tit, .tt-lados-tit,
.pl-asp-tit, .tdt-bloque-tit, .stat-label, .ux-cifra span, .td-cifra span, .ux-datos dt, .pf-cifras dt,
.tabla th, table th, .th-orden, .ux-tabla th, .nav-group-nombre, .impc-cifra span, .tt-grupo-tit {
  font-family: var(--mono-rotulo);
  letter-spacing: .13em; font-weight: 600; text-transform: uppercase;
}
.tabla th, table th, .th-orden, .ux-tabla th { font-size: 10.5px; color: var(--text-soft); }
.tt-grupo-tit { font-size: 11px; color: var(--text-soft); }
.nav-group-nombre { font-size: 10px; letter-spacing: .16em; }

/* 4 · Las tarjetas: mismo borde fino de siempre, pero se levantan al pasar por
   encima. Las que se abren (proyectos, dispositivos, empleados, MiFi) responden
   al ratón; las de cifras se quedan quietas. */
.ux-card, .proy-card, .stat-card, .td-widget, .card, .tel-card, .mf-card, .emp-card, .veh-card {
  transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease;
}
.ux-card:hover, .proy-card:hover, .stat-card[onclick]:hover, .tel-card:hover, .mf-card:hover, .emp-card:hover, .veh-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-lift);
  border-color: var(--border-med);
}
/* Las cifras del dashboard: sin sombra de tarjeta flotante, con el borde de la
   casa y una marca roja corta arriba a la izquierda en vez de un degradado. */
.stat-card { border: 1px solid var(--border); box-shadow: none; }
.stat-card .stat-card-accent { height: 3px; width: 34px; right: auto; background: var(--accent) !important; }
.stat-card.alerta .stat-card-accent { width: 100%; }
.stat-value { font-weight: 800; letter-spacing: -.05em; }

/* 5 · El botón principal proyecta un poco de su rojo. */
.btn-primary { box-shadow: 0 6px 16px -7px rgba(var(--acento-rgb), .6); transition: transform .14s ease, box-shadow .14s ease, filter .14s ease; }
.btn-primary:hover:not(:disabled) { transform: translateY(-1px); box-shadow: 0 9px 20px -7px rgba(var(--acento-rgb), .7); }

/* 6 · La barra lateral lleva la misma retícula, más tenue. */
.sidebar {
  background-image:
    linear-gradient(to right,  rgba(255,255,255,.035) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(255,255,255,.035) 1px, transparent 1px);
  background-size: var(--trama-lado) var(--trama-lado);
}
.nav-item.active { background: rgba(255,255,255,.075); }

/* 7 · Las tablas: cabecera en monoespaciada y la fila se ilumina entera. */
.tabla tbody tr:hover td, .ux-tabla tbody tr:hover td { background: var(--bg-hover); }
.tabla thead th, .ux-tabla thead th { background: var(--surface); }

/* 8 · Los vacíos llevan la retícula dentro: son parte del sistema, no un hueco. */
.ux-vacio-caja, .td-vacio, .tt-vacio, .pl-hoja-vacia {
  background-image:
    linear-gradient(to right,  var(--trama) 1px, transparent 1px),
    linear-gradient(to bottom, var(--trama) 1px, transparent 1px);
  background-size: 19px 19px;
}

/* 9 · Entrar en una pantalla: el contenido asienta con un pelo de movimiento. */
/* ── LA ENTRADA NO DEJA RASTRO ─────────────────────────────────────────────
   (15/9/2026) Estos fotogramas van con `backwards` y NO con `both`, y la
   diferencia no es estética: con `both` el navegador deja aplicado el valor
   del último fotograma para siempre, y ese valor es una transformación —la
   identidad, pero transformación—. Un elemento transformado crea contexto de
   apilado, así que cualquier desplegable abierto dentro de un bloque animado
   se quedaba ENCERRADO en él y lo tapaba el bloque siguiente. Es lo que le
   pasaba al selector de tipo en el alta de dispositivos.

   `backwards` mantiene lo único que hacía falta —el estado inicial durante el
   retardo, para que nada parpadee antes de empezar— y al terminar devuelve el
   elemento a sus propios estilos, sin transformación y sin contexto. */
@keyframes stk-entra { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.page.active > .page-header { animation: stk-entra .28s cubic-bezier(.2,.7,.2,1) backwards; }
.page.active > :not(.page-header) { animation: stk-entra .38s cubic-bezier(.2,.7,.2,1) backwards; }
@media (prefers-reduced-motion: reduce) { .page.active > * { animation: none; } .ux-card:hover, .proy-card:hover, .btn-primary:hover:not(:disabled) { transform: none; } }

/* 10 · El aviso de "sin guardar", los sellos y las cápsulas, con la misma letra. */
.badge, .ux-pill, .tdt-chip, .it-cod, .td-chapa, .pl-sucio { font-family: var(--mono-rotulo); letter-spacing: .06em; }

/* 11 · Los estados, iguales en toda la web: cápsula tintada con su punto y la
   letra monoespaciada. Vale para los `.badge` de presupuestos, vehículos,
   inventario y empleados, y para los `.ux-estado` de las tarjetas. */
.badge { border-radius: 999px; padding: 3px 9px; font-size: 10.5px; gap: 6px; }
.badge:not(.badge-proyecto) { text-transform: uppercase; letter-spacing: .07em; }
.badge-proyecto { letter-spacing: .02em; }
.badge-disponible, .badge-aceptado, .badge-activo, .badge-green { background: color-mix(in srgb, var(--pres-ok, #22c55e) 14%, transparent); color: var(--pres-ok, #16a34a); }
.badge-baja, .badge-rechazado, .badge-reparacion, .badge-red { background: color-mix(in srgb, var(--red) 13%, transparent); color: var(--red); }
.badge-enviado, .badge-proyecto, .badge-blue { background: color-mix(in srgb, var(--accent) 13%, transparent); color: var(--accent); }
.badge-borrador, .badge-gray, .badge-mantenimiento, .badge-purple { background: color-mix(in srgb, var(--text-soft) 16%, transparent); color: var(--text-soft); }
.badge-disponible::before, .badge-aceptado::before, .badge-activo::before, .badge-green::before,
.badge-baja::before, .badge-rechazado::before, .badge-reparacion::before, .badge-red::before,
.badge-enviado::before, .badge-blue::before, .badge-borrador::before, .badge-gray::before, .badge-mantenimiento::before, .badge-purple::before {
  content: ''; width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: 0 0 auto;
}
.ux-estado { padding: 4px 9px 4px 7px; border-radius: 999px; font-family: var(--mono-rotulo); font-size: 10.5px; letter-spacing: .07em; text-transform: uppercase;
  background: color-mix(in srgb, var(--pres-ok, #22c55e) 14%, transparent); color: var(--pres-ok, #16a34a); }
.ux-estado i { background: currentColor; }
.ux-estado.uso     { background: color-mix(in srgb, var(--accent) 13%, transparent); color: var(--accent); }
.ux-estado.aviso   { background: color-mix(in srgb, var(--mo-aviso) 16%, transparent); color: var(--mo-aviso); }
.ux-estado.apagado, .ux-estado.neutro { background: color-mix(in srgb, var(--text-soft) 16%, transparent); color: var(--text-soft); }
.ux-estado.uso i, .ux-estado.aviso i, .ux-estado.apagado i { background: currentColor; }

/* ═══════════════════════════════════════════════════════════════════════════
   EL SISTEMA DE FORMAS · una sola regla para toda la web
   (11/9/2026) «Hay cosas redondas y otras cuadradas; quiero orden». La casa
   es cuadrada —la retícula, el punto del login, los cuadraditos del 502—, así
   que TODO va a esquinas rectas: testigos, avatares, etiquetas, botones,
   pestañas, campos, tarjetas y menús. Una regla universal, y debajo los
   tamaños iguales para botones, campos, segmentos y pestañas.
   ═══════════════════════════════════════════════════════════════════════ */
*, *::before, *::after { border-radius: 0 !important; }

/* Botones: tres altos y nada más. */
.btn { height: 34px; padding: 0 14px; font-size: 13px; font-weight: 600; letter-spacing: 0; line-height: 1; }
.btn-sm { height: 30px; padding: 0 11px; font-size: 12.5px; }
.btn-lg { height: 40px; padding: 0 18px; font-size: 14px; }
.btn-ghost { background: var(--surface); color: var(--text); border: 1px solid var(--border-med); font-weight: 600; }
.btn-ghost:hover:not(:disabled) { background: var(--surface-2); border-color: var(--text-xsoft); }
.btn-primary { background: var(--accent); color: #fff; }
.btn-danger { height: 34px; }
.ux-acc { height: 30px; font-weight: 600; font-size: 12.5px; }
.ux-acc.fuerte { background: var(--text); color: var(--bg); border-color: var(--text); }
.ux-acc.fuerte:hover { filter: brightness(1.1); }
.tt-mas { width: 44px; height: 44px; background: var(--accent); box-shadow: 0 8px 20px -8px rgba(var(--acento-rgb), .7); }
.tt-cerrar, .tt-circ.on, .tt-sub.on .tt-sub-circ { background: var(--accent); border-color: var(--accent); }
.modal-close { width: 28px; height: 28px; border: 1px solid var(--border); }
button:focus-visible, .btn:focus-visible, a:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Campos: un alto, un borde. */
.form-control, .filter-select, .filter-input, .selector-boton, .tdt-nueva input, .tt-dd-fecha input,
.form-group input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]), .form-group select,
.pres-dato input:not([type="color"]), .pres-dato select, .mo-input:not(textarea), .login-campo input {
  height: 34px; border: 1px solid var(--border-med); background: var(--surface); color: var(--text); font-size: 13px;
}
.login-campo input { height: 42px; font-size: 14.5px; }
.form-group textarea, .form-control:is(textarea), textarea.mo-input { border: 1px solid var(--border-med); background: var(--surface); }
.form-control:focus, .filter-select:focus, .filter-input:focus, .form-group input:focus, .form-group select:focus, .form-group textarea:focus, .mo-input:focus, .tdt-nueva input:focus {
  border-color: var(--accent); box-shadow: 0 0 0 3px rgba(var(--acento-rgb), .14); outline: none;
}

/* Segmentos (Todos · En uso · Libres…): grupo con borde, la pieza activa
   rellena en tinta. */
.seg-btn, .pl-seg button, .tdt-filtros button, .fd-top-tog button, .bz-seg-b, .enviar-pastilla button {
  height: 32px; padding: 0 12px; font: 600 12.5px/1 var(--font); color: var(--text-soft);
  background: var(--surface); border: 1px solid var(--border-med); margin-left: -1px; box-shadow: none;
}
.seg-btn:first-child, .pl-seg button:first-child, .tdt-filtros button:first-child, .fd-top-tog button:first-child, .bz-seg-b:first-child { margin-left: 0; }
.seg-btn:hover, .pl-seg button:hover, .tdt-filtros button:hover, .fd-top-tog button:hover, .bz-seg-b:hover { color: var(--text); background: var(--surface-2); }
.seg-btn.active, .pl-seg button.activo, .tdt-filtros button.activo, .fd-top-tog button.activo, .bz-seg-b.activa, .enviar-pastilla button.activa {
  background: var(--text); color: var(--bg); border-color: var(--text); box-shadow: none; font-weight: 700;
}
.pl-seg, .tdt-filtros { border: 0; overflow: visible; }

/* Pestañas internas (Dispositivos · En proyectos · Historial…): línea roja
   debajo de la activa, contador en monoespaciada. Mismo alto en todas. */
.it-tab, .proy-tab, .pf-tab, .ms-tab, .veh-tab, .mo-tab, .topmat-tab, .ig-tab, .drawer-tab, .catalog-tab, .crew-proj-tab {
  height: 36px; padding: 0 12px; background: none; border: 0; border-bottom: 2px solid transparent;
  font: 600 13px/1 var(--font); color: var(--text-soft); display: inline-flex; align-items: center; gap: 7px; box-shadow: none;
}
.it-tab:hover, .proy-tab:hover, .pf-tab:hover, .ms-tab:hover, .veh-tab:hover, .mo-tab:hover, .topmat-tab:hover, .ig-tab:hover, .drawer-tab:hover, .catalog-tab:hover, .crew-proj-tab:hover { color: var(--text); }
.it-tab.active, .proy-tab.active, .pf-tab.activa, .ms-tab.activa, .veh-tab.active, .mo-tab.active, .topmat-tab.active, .ig-tab.activa, .drawer-tab.active, .catalog-tab.active, .crew-proj-tab.active {
  color: var(--text); border-bottom-color: var(--accent); background: none;
}
.it-tab-n, .proy-tab-n, .topmat-n, .proy-filtros-n, .crew-rol-n, .proy-rail-n, .cal-grupo-n, .ecat-n {
  font: 600 10.5px/1 var(--mono-rotulo); padding: 3px 6px; background: var(--surface-2); color: var(--text-soft); letter-spacing: .04em;
}
.it-tabs, .proy-tabs, .pf-tabs, .ms-tabs, .veh-tabs, .topmat-tabs, .ig-tabs { border-bottom: 1px solid var(--border); gap: 2px; background: none; padding: 0; }
/* La barra de pestañas de arriba (los documentos abiertos). */
.tab.activa { box-shadow: inset 0 -2px 0 var(--accent); }

/* Testigos: cuadrados de 7 px, todos del mismo tamaño. */
.ux-estado i, .tel-estado i, .it-res i, .alert-dot, .cal-dot, .gantt-leg-dot, .cal-legend-dot, .chart-legend-dot, .inv-chart-dot, .fleet-proj-dot, .veh-proximo-dot, .activo-dot::before, .tel-pill-dot,
.proy-punto, .agenda-punto, .drawer-punto, .proy-rail-punto, .bz-punto, .rvh-punto, .clv-punto, .gantt-punto, .offline-punto, .notif-punto, .login-punto {
  width: 7px; height: 7px; flex: 0 0 auto;
}

/* Etiquetas y cápsulas: rectas, mismo relleno. */
.badge, .ux-pill, .tdt-chip, .tt-chip, .it-res, .it-cod, .td-chapa, .cat-chip, .pres-chip, .proy-chip, .inv-chip, .it-chip, .veh-chip, .notif-chip, .eqg-chip, .agenda-dep, .agenda-cat, .np-dep {
  padding-top: 3px; padding-bottom: 3px;
}
.tt-chip, .it-res { height: 26px; padding-top: 0; padding-bottom: 0; }

/* Tarjetas y widgets: mismo borde, misma superficie, misma cabecera. */
.ux-card, .td-widget, .stat-card, .card, .gantt-section, .dash-widget, .tt, .proy-card, .tel-card, .mf-card, .emp-card, .veh-card, .dash-panel, .tt-card, .tdt-editor, .tt-dd-menu, .cat-dd, .sub-menu, .modal {
  border: 1px solid var(--border); background: var(--surface);
}
.td-widget-cab, .ux-card-cab { min-height: 44px; }
.tt-card { background: var(--bg); box-shadow: var(--shadow-md); }
.tt-dd-menu, .cat-dd, .sub-menu { box-shadow: var(--shadow-md); }

/* La cabecera de las tarjetas (MiFi, Telefonía, IT): el código y el estado no
   se partem ni se aplastan; lo que cede es el nombre de la operadora. */
.ux-card-cab { flex-wrap: nowrap; }
.ux-card-cab .ux-pill, .ux-card-cab .ux-estado, .ux-card-cab .ux-tile, .ux-card-cab .it-marca, .ux-card-cab .tel-op-logo { flex: 0 0 auto; white-space: nowrap; }
.ux-card-cab > *:not(.ux-pill):not(.ux-estado):not(.ux-tile):not(.it-marca) { min-width: 0; }
.ux-pill { letter-spacing: .05em; white-space: nowrap; height: 22px; }
.mf-card .ux-card-cab { gap: 8px; }

/* ── Avatares: foto o retícula generada ─────────────────────────────────── */
.ux-avatar[data-av-ok], .emp-avatar[data-av-ok] {
  position: relative; overflow: hidden;
  background: var(--av-fondo, var(--surface-2)) var(--av-trama, none) center / 100% 100% no-repeat !important;
  color: #fff !important; border-color: transparent !important; text-shadow: 0 1px 2px rgba(0,0,0,.25);
}
.av-foto { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.emp-cab-avwrap { position: relative; display: inline-block; }
.emp-cab-av { width: 72px; height: 72px; font-size: 22px; }
.emp-cab-foto { position: absolute; right: -6px; bottom: -6px; height: 22px; padding: 0 7px; border: 1px solid var(--border); background: var(--surface); color: var(--text-soft); font: 700 10px/1 var(--mono-rotulo); letter-spacing: .06em; text-transform: uppercase; cursor: pointer; }
.emp-cab-foto:hover { color: var(--text); border-color: var(--text-xsoft); }

/* ── Calendario de Flota: la columna fija no deja escapar el texto ─────────
   Los nombres largos de los espacios («Small Client Office # 1 (next to
   Paul's Office)») se salían de la columna y pisaban la rejilla, y «Studio
   Bookings» se partía en dos líneas. La columna recorta: el nombre cabe en
   dos líneas como mucho y el grupo en una, y el nombre completo va en el
   title. */
.cal-veh-td-veh, .cal-veh-th-veh { overflow: hidden; max-width: 260px; }
.cal-veh-name {
  white-space: normal; overflow: hidden;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow-wrap: anywhere; line-height: 1.25;
}
.cal-veh-row-inner { min-width: 0; }
.cal-veh-row-inner > div:not(.cal-veh-logo-cell) { min-width: 0; flex: 1 1 auto; }
.cal-grupo-nom { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.cal-grupo-cab { display: flex; align-items: center; gap: 8px; }
/* La columna fija tiene un ancho FIJO (con el zoom del calendario) y el
   contenido se adapta a ella, no al revés: en pruebas la columna se ensanchaba
   hasta 370 px para hacer sitio a un nombre largo. */
.cal-veh-th-veh, .cal-veh-td-veh { width: calc(210px * var(--cal-z, 1)); min-width: calc(210px * var(--cal-z, 1)); max-width: calc(210px * var(--cal-z, 1)); box-sizing: border-box; }
.cal-veh-td-veh .cal-veh-row-inner { max-width: 100%; }
.cal-veh-td-veh .cal-veh-name, .cal-veh-td-veh .cal-veh-mat { max-width: 100%; }
/* La tabla del calendario es de anchura automática, así que `max-width` en la
   celda no manda: lo que fija la columna es el ancho del CONTENIDO. */
.cal-veh-td-veh > .cal-veh-row-inner { width: calc(210px * var(--cal-z, 1) - 20px); max-width: calc(210px * var(--cal-z, 1) - 20px); }
.cal-grupo-nom { max-width: calc(210px * var(--cal-z, 1) - 76px); }

/* ═══════════════════════════════════════════════════════════════════════════
   NUEVO PROYECTO · la página
   ═══════════════════════════════════════════════════════════════════════ */
.pn { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 28px; align-items: start; max-width: 1180px; }
.pn-col { min-width: 0; }
.pn-cab { display: flex; align-items: flex-start; gap: 18px; margin-bottom: 22px; animation: stk-entra .3s ease backwards; }
.pn-eyebrow { display: inline-flex; align-items: center; gap: 8px; font: 600 10.5px/1 var(--mono-rotulo); letter-spacing: .16em; text-transform: uppercase; color: var(--text-soft); margin-bottom: 8px; }
.pn-eyebrow i { width: 7px; height: 7px; background: var(--accent); animation: pn-punto 1.6s ease-in-out infinite; }
@keyframes pn-punto { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }
.pn-tit { margin: 0; font: 750 30px/1.05 var(--font-display); letter-spacing: -.035em; color: var(--text); min-height: 32px; transition: color .2s; }

.pn-sec { background: var(--surface); border: 1px solid var(--border); padding: 20px 22px 22px; margin-bottom: 14px;
  animation: stk-entra .45s cubic-bezier(.2,.7,.2,1) backwards; animation-delay: calc(60ms * var(--i, 0)); transition: border-color .2s, box-shadow .2s; }
.pn-sec:focus-within { border-color: var(--border-strong); box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 6%, transparent); }
.pn-sec-cab { display: flex; gap: 14px; align-items: flex-start; margin-bottom: 16px; }
.pn-sec-cab h2 { margin: 0; font: 700 16px/1.2 var(--font-display); letter-spacing: -.02em; color: var(--text); }
.pn-sec-cab p { margin: 4px 0 0; font-size: 12.5px; color: var(--text-soft); line-height: 1.45; }
.pn-num { width: 26px; height: 26px; flex: 0 0 auto; display: grid; place-items: center; background: var(--text); color: var(--bg); font: 700 12px/1 var(--mono-rotulo); }
.pn-sec:focus-within .pn-num { background: var(--accent); color: #fff; }

.pn-nombre { width: 100%; height: 56px; padding: 0 16px; border: 1px solid var(--border-med); background: var(--bg); color: var(--text);
  font: 700 24px/1 var(--font-display); letter-spacing: -.025em; outline: none; transition: border-color .15s, box-shadow .15s; }
.pn-nombre::placeholder { color: var(--text-xsoft); font-weight: 600; }
.pn-nombre:focus { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(var(--acento-rgb), .14); }
.pn-fila2 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-top: 14px; }
.pn-campo { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.pn-campo > span, .pn-rol-cab b { font: 600 10.5px/1 var(--mono-rotulo); letter-spacing: .12em; text-transform: uppercase; color: var(--text-soft); }
.pn-inp { height: 36px; padding: 0 11px; border: 1px solid var(--border-med); background: var(--bg); color: var(--text); font: 13.5px var(--font); outline: none; transition: border-color .15s, box-shadow .15s, background .3s; width: 100%; }
.pn-inp:focus { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(var(--acento-rgb), .14); }
.pn-inp.pn-relleno { background: color-mix(in srgb, var(--accent) 12%, var(--bg)); }
.pn-notas { height: auto; min-height: 84px; padding: 10px 11px; resize: vertical; line-height: 1.5; }

.pn-swatches { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; padding-top: 2px; }
.pn-sw { position: relative; width: 28px; height: 28px; border: 0; background: var(--c); cursor: pointer; padding: 0; transition: transform .14s cubic-bezier(.2,.7,.2,1), box-shadow .14s; box-shadow: inset 0 0 0 1px rgba(0,0,0,.12); }
.pn-sw:hover { transform: translateY(-3px) scale(1.08); }
.pn-sw.activo { box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--c); transform: scale(1.06); }
.pn-sw.activo::after { content: ''; position: absolute; inset: 0; margin: auto; width: 8px; height: 8px; background: #fff; }
.pn-sw-otro { display: grid; place-items: center; background: var(--surface-2); border: 1px dashed var(--border-strong); color: var(--text-soft); font: 700 16px/1 var(--font); }
.pn-sw-otro.activo { border-style: solid; color: #fff; }
.pn-sw-otro input { position: absolute; inset: 0; opacity: 0; cursor: pointer; }

.pn-chips { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 12px; }
.pn-chip { height: 28px; padding: 0 11px; border: 1px solid var(--border-med); background: var(--surface); color: var(--text-soft); font: 600 12px/1 var(--font); cursor: pointer; transition: transform .12s, border-color .12s, color .12s, background .12s; }
.pn-chip:hover { color: var(--text); border-color: var(--text-xsoft); background: var(--surface-2); transform: translateY(-1px); }
.pn-chip-sep { width: 1px; height: 18px; background: var(--border-med); margin: 0 4px; }
.pn-dias { margin-left: auto; font: 600 12px/1 var(--mono-rotulo); letter-spacing: .04em; color: var(--accent); }

.pn-rol { display: grid; grid-template-columns: 220px 1fr; gap: 14px; align-items: center; padding: 12px 0; border-top: 1px solid var(--border); }
.pn-rol:first-of-type { border-top: 0; padding-top: 0; }
.pn-rol-cab b { display: block; margin-bottom: 4px; }
.pn-rol-cab span { font-size: 11.5px; color: var(--text-xsoft); line-height: 1.4; }
.pn-rol-campos { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }

.pn-deps { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px; }
.pn-dep { display: flex; align-items: center; gap: 10px; height: 42px; padding: 0 12px; border: 1px solid var(--border-med); background: var(--bg); color: var(--text-soft); font: 600 13px/1 var(--font); text-align: left; cursor: pointer; transition: transform .14s cubic-bezier(.2,.7,.2,1), border-color .14s, background .14s, color .14s, box-shadow .14s; }
.pn-dep i { width: 10px; height: 10px; border: 1.5px solid var(--text-xsoft); flex: 0 0 auto; transition: background .14s, border-color .14s, transform .14s; }
.pn-dep:hover { transform: translateY(-2px); border-color: var(--text-xsoft); color: var(--text); box-shadow: var(--shadow-lift); }
.pn-dep.on { background: var(--text); color: var(--bg); border-color: var(--text); }
.pn-dep.on i { background: var(--accent); border-color: var(--accent); transform: rotate(45deg); }
.pn-deps-nota { margin-top: 12px; font-size: 12px; color: var(--text-soft); line-height: 1.8; }
.pn-deps-nota code { font: 11.5px var(--mono-rotulo); background: var(--surface-2); padding: 2px 6px; margin-right: 4px; color: var(--text); }
.pn-vacio { font-size: 12.5px; color: var(--text-xsoft); padding: 6px 0; }

.pn-pie { position: sticky; bottom: 0; display: flex; align-items: center; gap: 10px; padding: 14px 0 6px; background: linear-gradient(to top, var(--bg) 70%, transparent); animation: stk-entra .5s ease backwards; animation-delay: .32s; }
.pn-pie-ayuda { margin-right: auto; font: 500 12px/1 var(--mono-rotulo); letter-spacing: .04em; color: var(--text-xsoft); }

.pn-lado { position: sticky; top: 20px; animation: stk-entra .5s cubic-bezier(.2,.7,.2,1) backwards; animation-delay: .18s; }
.pn-lado-tit { font: 600 10.5px/1 var(--mono-rotulo); letter-spacing: .14em; text-transform: uppercase; color: var(--text-soft); margin-bottom: 10px; }
.pn-lado-ayuda { margin: 12px 0 0; font-size: 12px; color: var(--text-xsoft); line-height: 1.5; }
.pn-card { background: var(--surface); border: 1px solid var(--border); border-left: 4px solid var(--proy-color); padding: 16px 18px 14px; transition: border-color .3s; }
.pn-card.latido { animation: pn-latido .5s cubic-bezier(.2,.7,.2,1); }
@keyframes pn-latido { 0% { transform: scale(1); } 35% { transform: scale(1.018); box-shadow: 0 0 0 6px color-mix(in srgb, var(--proy-color) 18%, transparent); } 100% { transform: scale(1); } }
.pn-card-cab { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.pn-card-cli { font: 600 10.5px/1 var(--mono-rotulo); letter-spacing: .12em; text-transform: uppercase; color: var(--text-soft); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pn-card-nom { font: 750 22px/1.1 var(--font-display); letter-spacing: -.03em; color: var(--text); overflow-wrap: anywhere; }
.pn-card-nom.vacio { color: var(--text-xsoft); }
.pn-card-fechas { margin-top: 8px; font: 500 12.5px/1 var(--mono-rotulo); color: var(--text-soft); }
.pn-card-roles { display: flex; align-items: center; gap: 4px; margin-top: 14px; font-size: 12px; color: var(--text-soft); }
.pn-card-roles .ux-avatar { width: 24px; height: 24px; font-size: 9px; margin-right: -4px; box-shadow: 0 0 0 2px var(--surface); }
.pn-card-roles > span:last-child { margin-left: 10px; }
.pn-card-deps { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 12px; }
.pn-card-pie { display: flex; gap: 16px; margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border); }
.pn-card-cifra { font-size: 11.5px; color: var(--text-soft); }
.pn-card-cifra b { font: 700 16px/1 var(--font-display); color: var(--text); margin-right: 4px; letter-spacing: -.02em; }
@media (max-width: 1000px) { .pn { grid-template-columns: 1fr; } .pn-lado { position: static; order: -1; } .pn-rol { grid-template-columns: 1fr; } .pn-rol-campos { grid-template-columns: 1fr; } .pn-fila2 { grid-template-columns: 1fr; } }
.pn.quieto .pn-cab, .pn.quieto .pn-sec, .pn.quieto .pn-pie, .pn.quieto .pn-lado { animation: none; }

/* ═══════════════════════════════════════════════════════════════════════════
   PROYECTOS · con la misma estética que «Nuevo proyecto»
   (12/9/2026) Lista y ficha vestidas con las mismas piezas: cajas de sección
   con título de display y explicación, rótulos en monoespaciada, cifras como
   tarjetas, color del proyecto como hilo conductor, y hovers que se notan:
   las tarjetas se levantan y su banda de color crece, las filas se deslizan.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── La lista: la tarjeta de proyecto ─────────────────────────────────── */
.proy-card { padding: 16px 18px 14px; border-left: 4px solid var(--proy-color, var(--border-strong)); transition: transform .18s cubic-bezier(.2,.7,.2,1), box-shadow .18s, border-color .18s, border-left-width .18s; }
.proy-card:hover { transform: translateY(-4px); border-left-width: 8px; border-color: var(--border-med); border-left-color: var(--proy-color); box-shadow: var(--shadow-lift), 0 0 0 4px color-mix(in srgb, var(--proy-color, var(--accent)) 14%, transparent); }
.proy-card .proy-card-color { display: none; }
.proy-card-cli { font: 600 10.5px/1 var(--mono-rotulo); letter-spacing: .12em; text-transform: uppercase; color: var(--text-soft); }
.proy-card-nom { font: 750 20px/1.1 var(--font-display); letter-spacing: -.03em; transition: color .18s; }
.proy-card:hover .proy-card-nom { color: var(--proy-color, var(--text)); }
.proy-card-cuando { font-size: 12.5px; color: var(--text-soft); margin-top: 6px; }
.proy-card-fechas { font: 500 11px/1 var(--mono-rotulo); letter-spacing: .04em; }
.proy-card-prog { background: var(--surface-2); border: 0; height: 4px; margin-top: 12px; }
.proy-card-prog i { background: var(--proy-color, var(--accent)); display: block; height: 100%; transition: width .4s ease; }
.proy-card-pie { padding-top: 12px; margin-top: 12px; }
.proy-card-quien { font-size: 12.5px; }
.proy-card-chip { display: inline-flex; align-items: center; gap: 4px; padding: 3px 7px; border: 1px solid var(--border); font: 600 10.5px/1 var(--mono-rotulo); letter-spacing: .04em; color: var(--text-soft); transition: transform .14s, border-color .14s, color .14s; }
.proy-card:hover .proy-card-chip { border-color: var(--border-med); color: var(--text); }

/* ── La ficha: cabecera ───────────────────────────────────────────────── */
.pf-volver { display: inline-flex; align-items: center; gap: 6px; font: 600 12px/1 var(--font); color: var(--text-soft); margin-bottom: 14px; transition: color .14s, transform .14s; }
.pf-volver:hover { color: var(--text); transform: translateX(-2px); }
.pf-cab { padding: 22px 24px; border-left: 4px solid var(--proy-color, var(--border-strong)); margin-bottom: 14px; animation: stk-entra .3s ease backwards; position: relative; overflow: hidden; }
.pf-cab::before { content: ''; position: absolute; inset: 0; pointer-events: none; background: radial-gradient(ellipse 60% 80% at 0% 50%, color-mix(in srgb, var(--proy-color, var(--accent)) 9%, transparent), transparent 60%); }
.pf-cab > * { position: relative; }
.pf-nombre { font: 750 30px/1.05 var(--font-display); letter-spacing: -.035em; }
.pf-meta { font: 500 12.5px/1 var(--mono-rotulo); letter-spacing: .03em; color: var(--text-soft); margin-top: 10px; align-items: center; }
.pf-cab-der .btn { transition: transform .14s, box-shadow .14s, background .14s, border-color .14s; }
.pf-cab-der .btn:hover { transform: translateY(-2px); box-shadow: var(--shadow-lift); }
.sub-sel-btn { transition: transform .14s, border-color .14s, color .14s, background .14s; }
.sub-sel-btn:hover { transform: translateY(-1px); }

/* ── Cifras como tarjetas ─────────────────────────────────────────────── */
.pf-cifras { gap: 10px; background: none; border: 0; padding: 0; margin-bottom: 14px; }
.pf-cifra { border: 1px solid var(--border); padding: 16px 18px 14px; position: relative; transition: transform .16s cubic-bezier(.2,.7,.2,1), box-shadow .16s, border-color .16s; animation: stk-entra .45s cubic-bezier(.2,.7,.2,1) backwards; }
.pf-cifra:nth-child(2) { animation-delay: 40ms; } .pf-cifra:nth-child(3) { animation-delay: 80ms; } .pf-cifra:nth-child(4) { animation-delay: 120ms; } .pf-cifra:nth-child(5) { animation-delay: 160ms; }
.pf-cifra::after { content: ''; position: absolute; left: 0; top: 0; width: 28px; height: 3px; background: var(--proy-color, var(--accent)); }
.pf-cifra:hover { transform: translateY(-3px); box-shadow: var(--shadow-lift); border-color: var(--border-med); }
.pf-cifra-n { font: 800 26px/1 var(--font-display); letter-spacing: -.04em; }
.pf-cifra-l { font: 600 10px/1 var(--mono-rotulo); letter-spacing: .12em; text-transform: uppercase; color: var(--text-soft); margin-top: 8px; }
.pf-progreso { border: 1px solid var(--border); padding: 14px 18px; }
.pf-progreso-track { height: 5px; background: var(--surface-2); }
.pf-progreso-fill { background: var(--proy-color, var(--accent)); }
.pf-progreso-pie { font: 500 11px/1 var(--mono-rotulo); letter-spacing: .04em; color: var(--text-xsoft); }

/* ── Las secciones, como los bloques de «Nuevo proyecto» ──────────────── */
.pf-sec, .pf-contactos, .fz-exp, .eq-panel, .eq-historico { background: var(--surface); border: 1px solid var(--border); margin-bottom: 14px; transition: border-color .2s, box-shadow .2s; }
.pf-sec:hover, .fz-exp:hover, .eq-panel:hover { border-color: var(--border-med); box-shadow: 0 0 0 4px color-mix(in srgb, var(--proy-color, var(--accent)) 6%, transparent); }
.pf-sec { padding: 0 0 6px; }
.pf-sec-tit { display: flex; align-items: center; gap: 10px; padding: 18px 22px 12px; border-bottom: 0; font: 700 16px/1.2 var(--font-display); letter-spacing: -.02em; text-transform: none; color: var(--text); }
.pf-sec-tit::before { content: ''; width: 8px; height: 8px; background: var(--proy-color, var(--accent)); flex: 0 0 auto; }
.pf-sec-n { font: 600 10.5px/1 var(--mono-rotulo); letter-spacing: .06em; padding: 3px 7px; background: var(--surface-2); color: var(--text-soft); }
.pf-sec-eur { font: 700 14px/1 var(--font-display); color: var(--text); }
.pf-sec-ayuda { padding: 0 22px 10px; font-size: 12.5px; color: var(--text-soft); line-height: 1.45; }
.pf-sec > *:not(.pf-sec-tit):not(.pf-sec-ayuda) { margin-left: 22px; margin-right: 22px; }
.pf-sec-add { height: 30px; padding: 0 11px; border: 1px solid var(--border-med); font: 600 12px/1 var(--font); color: var(--text); transition: transform .14s, border-color .14s, background .14s, box-shadow .14s; }
.pf-sec-add:hover { transform: translateY(-2px); border-color: var(--text-xsoft); background: var(--surface-2); box-shadow: var(--shadow-lift); }
.pf-nada { color: var(--text-xsoft); font-size: 13px; padding: 14px 0 18px; }

/* Datos del proyecto: etiqueta en monoespaciada, fila que se ilumina. */
.pf-dato { padding: 11px 8px; margin: 0 -8px; border-bottom: 1px solid var(--border); transition: background .14s; }
.pf-dato:hover { background: var(--bg-hover); }
.pf-dato dt { font: 600 10.5px/1.4 var(--mono-rotulo); letter-spacing: .1em; text-transform: uppercase; color: var(--text-soft); padding-top: 3px; }
.pf-dato dd { font-size: 14px; }

/* Filas que se deslizan: presupuestos, contactos, vehículos, material. */
.pf-pres, .pf-contacto, .pf-veh, .pf-tabla-fila, .eq-fila, .fz-sub-fila, .ecat-item { position: relative; transition: transform .16s cubic-bezier(.2,.7,.2,1), background .16s, box-shadow .16s; }
.pf-pres::before, .pf-contacto::before, .pf-veh::before { content: ''; position: absolute; left: -22px; top: 8px; bottom: 8px; width: 3px; background: var(--proy-color, var(--accent)); transform: scaleY(0); transition: transform .18s cubic-bezier(.2,.7,.2,1); }
.pf-pres:hover, .pf-contacto:hover, .pf-veh:hover { transform: translateX(6px); background: var(--bg-hover); }
.pf-pres:hover::before, .pf-contacto:hover::before, .pf-veh:hover::before { transform: scaleY(1); }
.pf-tabla-fila:hover, .eq-fila:hover, .fz-sub-fila:hover, .ecat-item:hover { background: var(--bg-hover); transform: translateX(3px); }
.pf-pres-num { font: 600 12.5px/1 var(--mono-rotulo); letter-spacing: .04em; }
.pf-pres-eur, .fz-sub-eur, .fz-total, .eq-total { font-family: var(--font-display); font-weight: 750; letter-spacing: -.02em; }
.pf-tabla-cab { font: 600 10.5px/1 var(--mono-rotulo); letter-spacing: .12em; text-transform: uppercase; color: var(--text-soft); }
.pf-contacto-ini { transition: transform .16s; }
.pf-contacto:hover .pf-contacto-ini { transform: scale(1.08); }

/* Finanzas y Equipment: mismas cabeceras. */
.fz-exp { border-radius: 0; margin-bottom: 14px; }
.fz-exp-cab, .eq-sub-cab, .eq-panel-tit, .fz-tit, .eq-grupo-tit { font: 700 16px/1.2 var(--font-display); letter-spacing: -.02em; text-transform: none; color: var(--text); }
.eq-sub-tit { font: 700 15px/1.2 var(--font-display); letter-spacing: -.02em; }
.eq-sub-meta, .fz-sub-n, .eq-dep, .eq-selbarra-n { font: 600 10.5px/1 var(--mono-rotulo); letter-spacing: .06em; color: var(--text-soft); }
.fz-sub { border: 1px solid var(--border); padding: 14px 16px; transition: transform .16s, box-shadow .16s, border-color .16s; }
.fz-sub:hover { transform: translateY(-2px); box-shadow: var(--shadow-lift); border-color: var(--border-med); }
.eq-x, .eq-link { transition: transform .14s, color .14s; }
.eq-x:hover, .eq-link:hover { transform: scale(1.12); }

/* La ficha entra como la página de creación: cada bloque asienta a su ritmo. */
.pf-cuerpo > *, .pf-cols > * { animation: stk-entra .45s cubic-bezier(.2,.7,.2,1) backwards; }
.pf-cols > *:nth-child(2) { animation-delay: 70ms; }
.pf-cuerpo > *:nth-child(2) { animation-delay: 70ms; } .pf-cuerpo > *:nth-child(3) { animation-delay: 140ms; } .pf-cuerpo > *:nth-child(4) { animation-delay: 210ms; }
.pf-tabs { margin-bottom: 14px; }
@media (prefers-reduced-motion: reduce) { .proy-card:hover, .pf-cifra:hover, .pf-pres:hover, .pf-contacto:hover, .pf-veh:hover, .pf-sec-add:hover, .pf-cab-der .btn:hover { transform: none; } .pf-cuerpo > *, .pf-cols > *, .pf-cifra, .pf-cab { animation: none; } }

/* ── Pulido de Proyectos (12/9/2026) ─────────────────────────────────────── */
/* El selector de subproyecto heredaba la monoespaciada de la fila de meta. */
.pf-meta .sub-sel-btn, .pf-meta .sub-sel-txt, .pf-meta .badge { font-family: var(--font); letter-spacing: 0; }
.pf-meta .badge { font-family: var(--mono-rotulo); letter-spacing: .07em; }
.pf-meta .sub-sel-btn { font: 600 12.5px/1 var(--font); height: 30px; padding: 0 10px; }
/* Las notas del proyecto, si están vacías, no dejan una caja en blanco. */
.pf-cab .pf-notas:empty { display: none; }
/* Contactos: fila sin caja, solo la línea de abajo; el correo como acción. */
.pf-contacto { border: 0 !important; border-bottom: 1px solid var(--border) !important; padding: 12px 0; background: none; }
.pf-contactos .pf-contacto:last-child { border-bottom: 0 !important; }
.pf-contacto-vias a { display: inline-flex; align-items: center; height: 28px; padding: 0 10px; border: 1px solid var(--border-med); font: 600 12px/1 var(--font); color: var(--text); text-decoration: none; transition: transform .14s, border-color .14s, background .14s; }
.pf-contacto-vias a:hover { transform: translateY(-2px); border-color: var(--text-xsoft); background: var(--surface-2); }
/* Equipment: el panel de material con sus márgenes, y el botón «Crear grupo»
   como los demás fantasma (`.btn-sec` no tenía estilo: salía gris del sistema). */
.eq-panel { padding: 18px 22px 22px; }
.eq-panel .eq-barra { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }
.btn-sec { background: var(--surface); color: var(--text); border: 1px solid var(--border-med); font-weight: 600; }
.btn-sec:hover:not(:disabled) { background: var(--surface-2); border-color: var(--text-xsoft); transform: translateY(-1px); }
.eq-vacio { padding: 10px 0; }
/* La caja vacía bajo la cabecera: era el menú del selector de subproyecto,
   recortado por el `overflow: hidden` que puse para el resplandor. Fuera. */
.pf-cab { overflow: visible; }
/* El menú de subproyectos por ENCIMA de las cifras: al pasar por una cifra,
   su hover la levantaba (transform) y la ponía delante del desplegable. La
   cabecera entera va en una capa superior mientras el menú está abierto. */
.pf-cab { position: relative; z-index: 5; }
.pf-cab:has(.sub-menu) { z-index: 60; }
.pf-meta .sub-menu { font-family: var(--font); letter-spacing: 0; z-index: 60; }
.pf-meta .sub-menu .sub-menu-cab { font-family: var(--mono-rotulo); letter-spacing: .1em; text-transform: uppercase; }
.pf-meta .sub-op-nom { font: 550 14px/1.2 var(--font); }
.pf-meta .sub-op-eti { font-size: 11.5px; }

/* ── Diálogos de la casa ─────────────────────────────────────────────────── */
.dlg-overlay { backdrop-filter: blur(3px); }
.modal.dlg { width: min(460px, calc(100vw - 32px)); padding: 24px 26px 22px; animation: dlg-entra .22s cubic-bezier(.2,.7,.2,1) both; }
@keyframes dlg-entra { from { opacity: 0; transform: translateY(8px) scale(.98); } to { opacity: 1; transform: none; } }
.dlg-eyebrow { display: inline-flex; align-items: center; gap: 8px; font: 600 10.5px/1 var(--mono-rotulo); letter-spacing: .16em; text-transform: uppercase; color: var(--text-soft); margin-bottom: 12px; }
.dlg-eyebrow i { width: 7px; height: 7px; background: var(--accent); }
.modal.dlg.peligro .dlg-eyebrow i { background: var(--red); }
.dlg-tit { margin: 0 0 8px; font: 700 20px/1.2 var(--font-display); letter-spacing: -.025em; color: var(--text); overflow-wrap: anywhere; }
.dlg-txt { margin: 0 0 16px; font-size: 13.5px; line-height: 1.55; color: var(--text-soft); overflow-wrap: anywhere; }
.dlg-inp { width: 100%; height: 38px; padding: 0 12px; margin: 4px 0 16px; border: 1px solid var(--border-med); background: var(--bg); color: var(--text); font: 14px var(--font); outline: none; }
.dlg-inp:focus { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(var(--acento-rgb), .14); }
.dlg-area { height: auto; padding: 9px 12px; line-height: 1.5; resize: vertical; }
.dlg-acc { display: flex; justify-content: flex-end; gap: 8px; padding-top: 4px; }
.btn-peligro { background: var(--red); color: #fff; border: 0; height: 34px; padding: 0 14px; font: 600 13px/1 var(--font); cursor: pointer; box-shadow: 0 6px 16px -7px color-mix(in srgb, var(--red) 60%, transparent); transition: transform .14s, filter .14s; }
.btn-peligro:hover { transform: translateY(-1px); filter: brightness(1.06); }
/* Repintados de la ficha (subproyecto, pestaña): sin coreografía, solo el
   contenido asienta en un cuarto de segundo. */
.pf.pf-quieto .pf-cab, .pf.pf-quieto .pf-cifra, .pf.pf-quieto .pf-cols > *:nth-child(2) { animation: none; }
.pf.pf-quieto .pf-cuerpo > *, .pf.pf-quieto .pf-cols > * { animation: stk-entra .22s ease backwards; animation-delay: 0s; }

/* ═══════════════════════════════════════════════════════════════════════════
   VEHÍCULOS · con la misma estética que Proyectos
   (12/9/2026) Lista, cuadrícula y ficha vestidas con las mismas piezas:
   bloques con título de display y cuadradito, rótulos en monoespaciada,
   datos como tarjetas, bandas de color por estado y hovers que se notan.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── La lista ─────────────────────────────────────────────────────────── */
.tabla-veh tbody tr { transition: background .14s, transform .14s; }
.tabla-veh tbody tr.veh-fila td:first-child { border-left: 3px solid transparent; }
.tabla-veh tbody tr.banda-ok td:first-child { border-left-color: var(--pres-ok); }
.tabla-veh tbody tr.banda-uso td:first-child { border-left-color: var(--accent); }
.tabla-veh tbody tr.banda-aviso td:first-child { border-left-color: var(--mo-aviso); }
.tabla-veh tbody tr.banda-apagado td:first-child { border-left-color: var(--border-strong); }
.tabla-veh tbody tr:hover td { background: var(--bg-hover); }
.tabla-veh tbody tr:hover td:first-child { border-left-width: 6px; }
.tabla-veh td[style*="tabular-nums"] { font-family: var(--mono-rotulo); font-size: 12.5px; }
.veh-doc-linea em { font: 600 10px/1 var(--mono-rotulo); letter-spacing: .1em; text-transform: uppercase; color: var(--text-xsoft); font-style: normal; }
.veh-doc-linea > span { font-family: var(--mono-rotulo); font-size: 12px; }
.veh-plegable { transition: border-color .2s, box-shadow .2s; }
.veh-plegable:hover { border-color: var(--border-med); }
.veh-plegable > summary { font: 700 13px/1.2 var(--font-display); letter-spacing: -.01em; padding: 14px 18px; }
.veh-plegable > summary::before { content: ''; display: inline-block; width: 8px; height: 8px; background: var(--accent); margin-right: 10px; vertical-align: 1px; }

/* La cuadrícula: la tarjeta se levanta y su banda crece. */
.veh-card { border-left: 4px solid var(--vc-banda, var(--border-strong)); transition: transform .18s cubic-bezier(.2,.7,.2,1), box-shadow .18s, border-color .18s, border-left-width .18s; }
.veh-card.banda-ok { --vc-banda: var(--pres-ok); } .veh-card.banda-uso { --vc-banda: var(--accent); } .veh-card.banda-aviso { --vc-banda: var(--mo-aviso); } .veh-card.banda-apagado { --vc-banda: var(--border-strong); }
.veh-card:hover { transform: translateY(-4px); border-left-width: 8px; border-color: var(--border-med); border-left-color: var(--vc-banda, var(--border-strong)); box-shadow: var(--shadow-lift), 0 0 0 4px color-mix(in srgb, var(--vc-banda, var(--accent)) 14%, transparent); }

/* ── La ficha ─────────────────────────────────────────────────────────── */
#veh-ficha-view > .page-header { padding: 22px 24px; background: var(--surface); border: 1px solid var(--border); border-left: 4px solid var(--accent); margin-bottom: 14px; position: relative; animation: stk-entra .3s ease backwards; align-items: center; }
#veh-ficha-view > .page-header::before { content: ''; position: absolute; inset: 0; pointer-events: none; background: radial-gradient(ellipse 60% 80% at 0% 50%, rgba(var(--acento-rgb), .08), transparent 60%); }
#veh-ficha-view > .page-header > * { position: relative; }
#veh-ficha-titulo { font: 750 30px/1.05 var(--font-display) !important; letter-spacing: -.035em; margin-left: 14px !important; }
#veh-ficha-view .page-actions .btn { transition: transform .14s, box-shadow .14s; }
#veh-ficha-view .page-actions .btn:hover { transform: translateY(-2px); box-shadow: var(--shadow-lift); }
.veh-tabs { margin-bottom: 14px; }
.veh-tab-content > * { animation: stk-entra .4s cubic-bezier(.2,.7,.2,1) backwards; }
.veh-tab-content > *:nth-child(2) { animation-delay: 70ms; } .veh-tab-content > *:nth-child(3) { animation-delay: 140ms; }

.vf-bloque { background: var(--surface); border: 1px solid var(--border); padding: 18px 22px 20px; margin-bottom: 14px; transition: border-color .2s, box-shadow .2s; }
.vf-bloque:hover { border-color: var(--border-med); box-shadow: 0 0 0 4px rgba(var(--acento-rgb), .06); }
.vf-bloques { gap: 14px; margin-bottom: 0; }
.vf-bloques .vf-bloque { margin-bottom: 14px; }
.vf-bloque-tit { display: flex; align-items: center; gap: 10px; padding: 0 0 12px; border-bottom: 0; margin-bottom: 4px; font: 700 16px/1.2 var(--font-display); letter-spacing: -.02em; text-transform: none; color: var(--text); }
.vf-bloque-tit::before { content: ''; width: 8px; height: 8px; background: var(--accent); flex: 0 0 auto; }
.veh-info-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
.veh-info-card { border: 1px solid var(--border); padding: 14px 16px 12px; position: relative; transition: transform .16s cubic-bezier(.2,.7,.2,1), box-shadow .16s, border-color .16s; }
.veh-info-card::after { content: ''; position: absolute; left: 0; top: 0; width: 24px; height: 3px; background: var(--accent); }
.veh-info-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lift); border-color: var(--border-med); }
.veh-info-label { font: 600 10px/1 var(--mono-rotulo); letter-spacing: .12em; text-transform: uppercase; color: var(--text-soft); }
.veh-info-value { margin-top: 8px; font: 700 17px/1.15 var(--font-display); letter-spacing: -.02em; }
.veh-info-value.ok { color: var(--pres-ok); } .veh-info-value.warn { color: var(--mo-aviso); } .veh-info-value.danger { color: var(--red); }
.veh-proximo-banner { border: 1px solid var(--border); border-left: 4px solid var(--accent); padding: 14px 18px; margin-bottom: 14px; }
.veh-proximo-label { font: 600 10.5px/1 var(--mono-rotulo); letter-spacing: .12em; text-transform: uppercase; color: var(--text-soft); }
.veh-proximo-nombre { font: 700 16px/1.2 var(--font-display); letter-spacing: -.02em; }
.veh-proximo-dates { font: 500 12px/1 var(--mono-rotulo); color: var(--text-soft); }
.vf-notas { font-size: 13.5px; line-height: 1.55; color: var(--text-2); }

/* Documentos, fotos e historial: mismas cabeceras, mismos hovers. */
#veh-tab-documentos > .page-header, #veh-tab-historial > .page-header { padding: 0 0 12px !important; }
#veh-tab-documentos > .page-header > div:first-child, #veh-tab-historial > .page-header > div:first-child { font: 700 16px/1.2 var(--font-display) !important; letter-spacing: -.02em; display: flex; align-items: center; gap: 10px; }
#veh-tab-documentos > .page-header > div:first-child::before, #veh-tab-historial > .page-header > div:first-child::before { content: ''; width: 8px; height: 8px; background: var(--accent); }
.veh-foto-slot { border: 1px solid var(--border); transition: transform .16s cubic-bezier(.2,.7,.2,1), box-shadow .16s, border-color .16s; }
.veh-foto-slot:hover { transform: translateY(-3px); box-shadow: var(--shadow-lift); border-color: var(--border-med); }
.veh-foto-preview > div { font: 600 10.5px/1 var(--mono-rotulo); letter-spacing: .1em; text-transform: uppercase; }
.veh-docs-grid > * { transition: transform .16s cubic-bezier(.2,.7,.2,1), box-shadow .16s; }
.veh-docs-grid > *:hover { transform: translateY(-3px); box-shadow: var(--shadow-lift); }
#veh-historial-list > * { transition: transform .16s, background .16s; }
#veh-historial-list > *:hover { transform: translateX(4px); background: var(--bg-hover); }
@media (prefers-reduced-motion: reduce) { .veh-card:hover, .veh-info-card:hover, .veh-foto-slot:hover, .veh-docs-grid > *:hover, #veh-historial-list > *:hover, #veh-ficha-view .page-actions .btn:hover { transform: none; } .veh-tab-content > *, #veh-ficha-view > .page-header { animation: none; } }
/* Repintados de la ficha de proyecto: NADA se anima. Un fundido de un cuarto
   de segundo en cada cambio de subproyecto se veía como un amago que se
   corta. La coreografía es solo de la primera apertura. */
.pf.pf-quieto, .pf.pf-quieto * { animation: none !important; }
/* La entrada de la ficha, RETOMABLE: si la ficha se repinta mientras entra,
   cada pieza sigue desde donde estaba gracias al retraso negativo (--pf-t es
   lo transcurrido en ms). Así la coreografía se ve entera y una sola vez. */
.pf.pf-entra .pf-cab { animation: stk-entra .3s ease backwards !important; animation-delay: calc(var(--pf-t, 0) * -1ms) !important; }
.pf.pf-entra .pf-cifra { animation: stk-entra .45s cubic-bezier(.2,.7,.2,1) backwards !important; animation-delay: calc(var(--pf-t, 0) * -1ms) !important; }
.pf.pf-entra .pf-cifra:nth-child(2) { animation-delay: calc(40ms - var(--pf-t, 0) * 1ms) !important; }
.pf.pf-entra .pf-cifra:nth-child(3) { animation-delay: calc(80ms - var(--pf-t, 0) * 1ms) !important; }
.pf.pf-entra .pf-cifra:nth-child(4) { animation-delay: calc(120ms - var(--pf-t, 0) * 1ms) !important; }
.pf.pf-entra .pf-cifra:nth-child(5) { animation-delay: calc(160ms - var(--pf-t, 0) * 1ms) !important; }
.pf.pf-entra .pf-cuerpo > *, .pf.pf-entra .pf-cols > * { animation: stk-entra .45s cubic-bezier(.2,.7,.2,1) backwards !important; animation-delay: calc(var(--pf-t, 0) * -1ms) !important; }
.pf.pf-entra .pf-cuerpo > *:nth-child(2), .pf.pf-entra .pf-cols > *:nth-child(2) { animation-delay: calc(70ms - var(--pf-t, 0) * 1ms) !important; }
.pf.pf-entra .pf-cuerpo > *:nth-child(3) { animation-delay: calc(140ms - var(--pf-t, 0) * 1ms) !important; }
.pf.pf-entra .pf-cuerpo > *:nth-child(4) { animation-delay: calc(210ms - var(--pf-t, 0) * 1ms) !important; }
@media (prefers-reduced-motion: reduce) { .pf.pf-entra * { animation: none !important; } }

/* ═══════════════════════════════════════════════════════════════════════════
   EL MISMO DISEÑO EN TODA LA WEB
   (12/9/2026) Los títulos de sección que iban en versalitas pequeñas pasan al
   título de display con el cuadradito rojo, como en Proyectos y Vehículos; los
   bloques responden al ratón igual. Las etiquetas de dato siguen en
   monoespaciada pequeña (eso ya lo hace la capa de carácter).
   ═══════════════════════════════════════════════════════════════════════ */
.section-title, .aj-tit, .ajn-grupo-tit, .builder-section-title, .busca-grupo-tit, .busca-pag-grupo-tit, .clv-titulo,
.contactos-cab, .dep-sueltos-tit, .drawer-dep-tit, .drawer-sec-tit, .ecat-tit, .eco-tit, .emp-grupo-tit, .emp-sec-tit,
.enviar-sug-tit, .eq-cab, .eq-grupo-tit, .eqf-sueltas-tit, .flt-projects-header, .flt-sidebar-header, .flt-veh-group-header,
.form-seccion-tit, .fqr-panel-tit, .fw-bloqueos-tit, .ig-form-tit, .itv-grupo-tit, .ma-bloque-tit, .mfo-tit, .mo-bloque-tit,
.np-arbol-tit, .np-lineas-tit, .pc-anadir-tit, .pd-envios-tit, .perfil-section-title, .proy-recientes-titulo, .ret-grupo-tit,
.ret-tit, .rvh-tit, .usr-bloque-tit, .usr-matriz-grupo-tit, .mf-enproy-tit, .fichas-paso-tit, .co-sec-tit, .act-sec-tit, .fd-sec-tit {
  display: flex; align-items: center; gap: 10px;
  font: 700 15px/1.2 var(--font-display); letter-spacing: -.02em; text-transform: none; color: var(--text);
}
.section-title::before, .aj-tit::before, .ajn-grupo-tit::before, .builder-section-title::before, .busca-grupo-tit::before, .busca-pag-grupo-tit::before,
.clv-titulo::before, .contactos-cab::before, .dep-sueltos-tit::before, .drawer-dep-tit::before, .drawer-sec-tit::before, .ecat-tit::before, .eco-tit::before,
.emp-grupo-tit::before, .emp-sec-tit::before, .enviar-sug-tit::before, .eq-cab::before, .eq-grupo-tit::before, .eqf-sueltas-tit::before,
.flt-projects-header::before, .flt-sidebar-header::before, .flt-veh-group-header::before, .form-seccion-tit::before, .fqr-panel-tit::before,
.fw-bloqueos-tit::before, .ig-form-tit::before, .itv-grupo-tit::before, .ma-bloque-tit::before, .mfo-tit::before, .mo-bloque-tit::before,
.np-arbol-tit::before, .np-lineas-tit::before, .pc-anadir-tit::before, .pd-envios-tit::before, .perfil-section-title::before, .proy-recientes-titulo::before,
.ret-grupo-tit::before, .ret-tit::before, .rvh-tit::before, .usr-bloque-tit::before, .usr-matriz-grupo-tit::before, .mf-enproy-tit::before,
.fichas-paso-tit::before, .co-sec-tit::before, .act-sec-tit::before, .fd-sec-tit::before {
  content: ''; width: 8px; height: 8px; background: var(--accent); flex: 0 0 auto;
}
/* Los contadores y botones que van dentro de esos títulos, con la letra pequeña de la casa. */
.section-title i, .drawer-sec-tit i, .emp-sec-tit i, .eq-cab i, .drawer-sec-n, .emp-sec-n, .eco-tit i, .ret-tit i, .usr-bloque-tit i, .mo-bloque-tit i {
  font: 600 10.5px/1 var(--mono-rotulo); letter-spacing: .06em; color: var(--text-soft); font-style: normal; padding: 3px 7px; background: var(--surface-2);
}
/* Los bloques que envuelven esas secciones responden al ratón igual que en Proyectos. */
.aj-bloque, .ajn-grupo, .mo-bloque, .ma-bloque, .usr-bloque, .emp-sec, .perfil-section, .drawer-sec, .eq-grupo, .fqr-panel, .fw-bloqueos, .rvh-bloque,
.ret-grupo, .itv-grupo, .clv-card, .eco-bloque, .card, .gantt-section, .tel-dash-section, .dash-widget, .flt-sidebar, .flt-projects, .mfo-caja, .co-sec, .act-sec {
  transition: border-color .2s, box-shadow .2s;
}
.aj-bloque:hover, .ajn-grupo:hover, .mo-bloque:hover, .ma-bloque:hover, .usr-bloque:hover, .emp-sec:hover, .perfil-section:hover, .drawer-sec:hover, .eq-grupo:hover,
.fqr-panel:hover, .fw-bloqueos:hover, .rvh-bloque:hover, .ret-grupo:hover, .itv-grupo:hover, .clv-card:hover, .eco-bloque:hover, .card:hover, .gantt-section:hover,
.tel-dash-section:hover, .dash-widget:hover, .mfo-caja:hover, .co-sec:hover, .act-sec:hover {
  border-color: var(--border-med); box-shadow: 0 0 0 4px rgba(var(--acento-rgb), .06);
}
/* Botones dentro de los títulos y en las cabeceras de sección: suben al pasar. */
.drawer-sec-tit .btn, .emp-sec-tit .btn, .eq-cab .btn, .aj-tit .btn, .usr-bloque-tit .btn, .mo-bloque-tit .btn, .section-title .btn, .pf-sec-tit .btn {
  margin-left: auto; transition: transform .14s, box-shadow .14s;
}
.drawer-sec-tit .btn:hover, .emp-sec-tit .btn:hover, .eq-cab .btn:hover, .aj-tit .btn:hover, .usr-bloque-tit .btn:hover, .mo-bloque-tit .btn:hover, .section-title .btn:hover, .pf-sec-tit .btn:hover {
  transform: translateY(-2px); box-shadow: var(--shadow-lift);
}

/* ═══════════════════════════════════════════════════════════════════════════
   PRESUPUESTOS, INVENTARIO Y LO QUE FALTABA · misma estética
   ═══════════════════════════════════════════════════════════════════════ */
/* ── Presupuestos: la lista ─────────────────────────────────────────────── */
.pres-kpi { position: relative; border: 1px solid var(--border); background: var(--surface); padding: 16px 18px 14px; transition: transform .16s cubic-bezier(.2,.7,.2,1), box-shadow .16s, border-color .16s; }
.pres-kpi::after { content: ''; position: absolute; left: 0; top: 0; width: 28px; height: 3px; background: var(--accent); }
.pres-kpi:hover { transform: translateY(-3px); box-shadow: var(--shadow-lift); border-color: var(--border-med); }
.pres-kpi-val { font: 800 26px/1 var(--font-display); letter-spacing: -.04em; }
.pres-kpi-eur { font: 500 12px/1 var(--mono-rotulo); letter-spacing: .02em; color: var(--text-soft); margin-top: 6px; }
.pres-kpi-label { font: 600 10px/1 var(--mono-rotulo); letter-spacing: .12em; text-transform: uppercase; color: var(--text-soft); margin-top: 8px; }
#pres-list-view .tabla tbody tr { transition: background .14s, transform .14s; }
#pres-list-view .tabla tbody tr:hover td { background: var(--bg-hover); }
#pres-list-view .tabla tbody tr:hover { transform: translateX(3px); }
#pres-list-view .tabla td:first-child { font-family: var(--mono-rotulo); font-size: 12.5px; letter-spacing: .02em; }

/* ── El constructor ─────────────────────────────────────────────────────── */
body.constructor-abierto #pres-builder-title { display: inline-flex; align-items: center; gap: 10px; }
body.constructor-abierto #pres-builder-title::before { content: ''; width: 9px; height: 9px; background: var(--accent); flex: 0 0 auto; }
.pres-datos { transition: border-color .2s, box-shadow .2s; }
.pres-datos:focus-within { border-color: var(--border-strong); box-shadow: 0 0 0 4px rgba(var(--acento-rgb), .06); }
.pres-items-table tbody tr { transition: background .14s, transform .14s; }
.pres-items-table tbody tr:hover td { background: var(--bg-hover); }
.pres-totals { border: 1px solid var(--border); background: var(--surface); padding: 14px 16px; }
.pres-totals-row { font-size: 13px; }
.pres-totals-row span:first-child, .pres-totals-base span:first-child { font: 600 10.5px/1 var(--mono-rotulo); letter-spacing: .1em; text-transform: uppercase; color: var(--text-soft); }
.pres-totals-final { font: 800 22px/1 var(--font-display); letter-spacing: -.03em; }
.pres-totals-final span:first-child { font: 700 11px/1 var(--mono-rotulo); letter-spacing: .12em; text-transform: uppercase; color: var(--text); }
.builder-left .ecat-rama, .builder-left .cat-row, .builder-left .ecat-item { transition: background .14s, transform .14s; }
.builder-left .ecat-rama:hover, .builder-left .cat-row:hover, .builder-left .ecat-item:hover { background: var(--bg-hover); transform: translateX(3px); }

/* ── El visor del documento: cabecera como una ficha ───────────────────── */
.pd-barra { padding: 16px 22px; background: var(--surface); border: 1px solid var(--border); border-left: 4px solid var(--accent); margin-bottom: 14px; position: relative; align-items: center; gap: 14px; flex-wrap: wrap; }
.pd-barra::before { content: ''; position: absolute; inset: 0; pointer-events: none; background: radial-gradient(ellipse 50% 90% at 0% 50%, rgba(var(--acento-rgb), .08), transparent 60%); }
.pd-barra > * { position: relative; }
.pd-num { font: 800 22px/1 var(--font-display); letter-spacing: -.03em; color: var(--text); }
.pd-cli { font: 500 12px/1 var(--mono-rotulo); letter-spacing: .04em; color: var(--text-soft); margin-top: 4px; display: block; }
.pd-total-n { font: 800 22px/1 var(--font-display); letter-spacing: -.03em; }
.pd-acciones .btn { transition: transform .14s, box-shadow .14s; }
.pd-acciones .btn:hover { transform: translateY(-2px); box-shadow: var(--shadow-lift); }
.pd-lienzo { border: 1px solid var(--border); }

/* ── Inventario: bandas por estado y filas vivas ────────────────────────── */
#tbody-inventario tr.inv-fila td:first-child { border-left: 3px solid transparent; }
#tbody-inventario tr.banda-ok td:first-child { border-left-color: var(--pres-ok); }
#tbody-inventario tr.banda-uso td:first-child { border-left-color: var(--accent); }
#tbody-inventario tr.banda-aviso td:first-child { border-left-color: var(--mo-aviso); }
#tbody-inventario tr.banda-apagado td:first-child { border-left-color: var(--border-strong); }
#tbody-inventario tr { transition: background .14s; }
#tbody-inventario tr:hover td { background: var(--bg-hover); }
#tbody-inventario tr:hover td:first-child { border-left-width: 6px; }
#tbody-inventario td[style*="tabular-nums"] { font-family: var(--mono-rotulo); }
.cat-chip { transition: transform .14s, border-color .14s, color .14s; }
.cat-chip:hover { transform: translateY(-1px); color: var(--text); border-color: var(--text-xsoft); }

/* ── Crew, empleados y otras tarjetas que faltaban ─────────────────────── */
.crew-card, .emp-card, .usr-card, .ig-card, .co-card, .fqr-item, .pant-card { transition: transform .16s cubic-bezier(.2,.7,.2,1), box-shadow .16s, border-color .16s; }
.crew-card:hover, .emp-card:hover, .usr-card:hover, .ig-card:hover, .co-card:hover, .fqr-item:hover, .pant-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lift); border-color: var(--border-med); }

/* ── Calendarios: la paleta de proyectos y los grupos ───────────────────── */
#cal-proj-palette > *, .pcal-pal > * { transition: transform .14s, box-shadow .14s; }
#cal-proj-palette > *:hover, .pcal-pal > *:hover { transform: translateY(-2px); box-shadow: var(--shadow-lift); }
.cal-grupo-cab { transition: background .14s; }
@media (prefers-reduced-motion: reduce) { .pres-kpi:hover, #pres-list-view .tabla tbody tr:hover, .builder-left .ecat-item:hover, .pd-acciones .btn:hover, .crew-card:hover, .emp-card:hover, .cat-chip:hover { transform: none; } }

/* ── La estructura de «Nuevo proyecto» aplicada por el decorador ────────── */
.pn-auto { display: flex !important; align-items: flex-start !important; gap: 14px !important; border-bottom: 0 !important; text-transform: none !important; letter-spacing: 0 !important; font: 400 13px/1.3 var(--font) !important; color: var(--text) !important; margin-bottom: 14px; }
.pn-auto::before { display: none !important; content: none !important; }
.pn-auto .pn-num { width: 26px; height: 26px; flex: 0 0 auto; display: grid; place-items: center; background: var(--text); color: var(--bg); font: 700 12px/1 var(--mono-rotulo); margin-top: 1px; }
.pn-auto-txt { flex: 1 1 auto; min-width: 0; }
.pn-auto-txt h2 { margin: 0; font: 700 16px/1.2 var(--font-display); letter-spacing: -.02em; color: var(--text); display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.pn-auto-txt h2 > i, .pn-auto-txt h2 > small, .pn-auto-txt h2 > span { font: 600 10.5px/1 var(--mono-rotulo) !important; letter-spacing: .06em !important; text-transform: none; font-style: normal; padding: 3px 7px; background: var(--surface-2); color: var(--text-soft); margin: 0 !important; }
.pn-auto-txt p { margin: 4px 0 0; font: 400 12.5px/1.45 var(--font); color: var(--text-soft); }
.pn-sec-acc { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; margin-left: auto; flex-wrap: wrap; justify-content: flex-end; }
.pn-sec-acc .btn, .pn-sec-acc .ux-acc, .pn-sec-acc .pf-sec-add { transition: transform .14s, box-shadow .14s; }
.pn-sec-acc .btn:hover, .pn-sec-acc .ux-acc:hover, .pn-sec-acc .pf-sec-add:hover { transform: translateY(-2px); box-shadow: var(--shadow-lift); }
/* Los bloques que envuelven un título decorado respiran como en «Nuevo proyecto». */
.pf-sec .pn-auto { padding: 18px 22px 0 !important; margin-bottom: 12px; }
.vf-bloque > .pn-auto, .emp-sec > .pn-auto, .aj-bloque > .pn-auto, .mo-bloque > .pn-auto, .ma-bloque > .pn-auto, .usr-bloque > .pn-auto, .perfil-section > .pn-auto, .drawer-sec > .pn-auto, .eq-panel > .pn-auto, .ret-grupo > .pn-auto, .itv-grupo > .pn-auto, .fz-exp > .pn-auto, .fqr-panel > .pn-auto, .card > .pn-auto { margin-bottom: 14px; }
.pn-auto:focus-within .pn-num { background: var(--accent); color: #fff; }
/* La cabecera de cada pantalla: el rótulo del grupo encima del título. */
.page-header[data-pn] { flex-wrap: wrap; }
.page-header[data-pn] .pn-auto-eyebrow { flex: 1 1 100%; margin-bottom: 2px; }
.page-header[data-pn] .page-title::before { display: none; }
.page-header[data-pn] .page-title { font-size: 30px; }
.page-header[data-pn] h1::before, .page-header[data-pn] .page-title::before { display: none !important; }
.ajn-grupo-tit { font: 600 10px/1 var(--mono-rotulo); letter-spacing: .14em; text-transform: uppercase; color: var(--text-xsoft); }

/* ═══════════════════════════════════════════════════════════════════════════
   MOVIMIENTO · hovers y animaciones de toda la web
   Regla: el hover responde (sube, se ilumina, desliza) y el active devuelve;
   las barras crecen con transform (no tocan el layout); nada se anima en los
   repintados, solo al entrar. Con `prefers-reduced-motion` todo se apaga.
   ═══════════════════════════════════════════════════════════════════════ */
@keyframes stk-crece-x { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes stk-crece-y { from { transform: scaleY(0); } to { transform: scaleY(1); } }
@keyframes stk-aparece { from { opacity: 0; } to { opacity: 1; } }
@keyframes mov-giro { to { transform: rotate(360deg); } }

/* Controles: todos responden igual. */
.btn, .ux-acc, .ux-herr, .seg-btn, .tab, .it-tab, .proy-tab, .pf-tab, .veh-tab, .ms-tab, .mo-tab, .topmat-tab, .inv-chip, .it-chip, .veh-chip, .cat-chip, .pres-chip, .proy-chip, .eqg-chip, .clv-card, .fd-cifra, .fw-cifra, .pres-kpi, .dep-card-cab, .ficha-plantilla, .np-nodo-btn, .tt-lista-btn, .tt-persona, .td-acceso, .pn-dep, .pn-chip, .aj-nav-item, .ajn-item, .sub-op, .cat-dd-item, .notif-btn, .modal-close, .dash-panel-x, .pl-pieza, .ecat-rama, .ecat-item {
  transition: transform .14s cubic-bezier(.2,.7,.2,1), box-shadow .14s, background-color .14s, border-color .14s, color .14s, opacity .14s;
}
.btn:not(:disabled):hover, .ux-herr:not(:disabled):hover, .inv-chip:hover, .it-chip:hover, .veh-chip:hover, .pres-chip:hover, .proy-chip:hover, .eqg-chip:hover, .ficha-plantilla:hover, .np-nodo-btn:hover, .pl-pieza:hover, .notif-btn:hover { transform: translateY(-1px); }
.btn-primary:not(:disabled):hover { box-shadow: 0 8px 20px -8px rgba(var(--acento-rgb), .7); }
.btn:not(:disabled):active, .ux-acc:active, .seg-btn:active, .inv-chip:active, .it-chip:active, .clv-card:active, .fd-cifra:active, .fw-cifra:active, .pres-kpi:active, .td-acceso:active, .pn-dep:active { transform: translateY(0) scale(.98); transition-duration: .06s; }
.seg-btn:hover, .it-tab:hover, .proy-tab:hover, .pf-tab:hover, .veh-tab:hover, .ms-tab:hover, .mo-tab:hover, .topmat-tab:hover { color: var(--text); }
.tab:hover { background: var(--surface-2); }
.clv-card:hover, .fd-cifra:hover, .fw-cifra:hover, .pres-kpi:hover, .dep-card-cab:hover, .td-acceso:hover, .pn-dep:hover { transform: translateY(-2px); box-shadow: var(--shadow-lift); }
.sidebar .nav-item { transition: background .14s, color .14s, transform .14s; }
.sidebar .nav-item:hover { transform: translateX(2px); }
.sidebar .nav-item:hover .nav-icon { transform: scale(1.08); }
.sidebar .nav-icon { transition: transform .14s, opacity .14s; }
.sidebar-avatar, .ux-avatar, .emp-avatar, .tt-av { transition: transform .14s; }
.sidebar-user:hover .sidebar-avatar { transform: scale(1.06); }
input[type="checkbox"], input[type="radio"] { transition: transform .12s; }
input[type="checkbox"]:hover, input[type="radio"]:hover { transform: scale(1.1); }
.tabla tbody tr, .ux-tabla tbody tr, table.tabla-ligera tbody tr { transition: background .14s; }
.tabla tbody tr:hover td { background: var(--bg-hover); }
.tabla tbody tr:hover .btn, .tabla tbody tr:hover .ux-acc { opacity: 1; }
a { transition: color .14s; }
/* El foco por teclado también se ve. */
.btn:focus-visible, .ux-acc:focus-visible, .seg-btn:focus-visible, .tt-circ:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Barras que crecen (transform: no tocan el layout). */
.eco-etapa-barra i, .eco-proy-barra i, .fd-barra i, .pf-progreso-fill, .proy-card-prog i, .td-prog i, .drawer-dep-barra > span, .topmat-barra-fill, .drawer-progreso-fill, .tt-prog i, .veh-dash-barra i, .cat-barra i, .fw-barra i, .lic-barra i {
  transform-origin: left center; animation: stk-crece-x .7s cubic-bezier(.2,.7,.2,1) both;
}
.eco-col-ingreso i, .eco-col-gasto i { transform-origin: center bottom; animation: stk-crece-y .7s cubic-bezier(.2,.7,.2,1) both; }
.eco-col:nth-child(2) i { animation-delay: 40ms; } .eco-col:nth-child(3) i { animation-delay: 80ms; } .eco-col:nth-child(4) i { animation-delay: 120ms; } .eco-col:nth-child(5) i { animation-delay: 160ms; } .eco-col:nth-child(6) i { animation-delay: 200ms; } .eco-col:nth-child(7) i { animation-delay: 240ms; } .eco-col:nth-child(8) i { animation-delay: 280ms; } .eco-col:nth-child(9) i { animation-delay: 320ms; } .eco-col:nth-child(10) i { animation-delay: 360ms; } .eco-col:nth-child(11) i { animation-delay: 400ms; } .eco-col:nth-child(12) i { animation-delay: 440ms; }
.eco-col-cima { animation: stk-aparece .4s .6s ease both; }
.eco-etapa:nth-child(2) .eco-etapa-barra i { animation-delay: 80ms; } .eco-etapa:nth-child(3) .eco-etapa-barra i { animation-delay: 160ms; } .eco-etapa:nth-child(4) .eco-etapa-barra i { animation-delay: 240ms; }
.eco-proy:nth-child(2) .eco-proy-barra i { animation-delay: 60ms; } .eco-proy:nth-child(3) .eco-proy-barra i { animation-delay: 120ms; } .eco-proy:nth-child(4) .eco-proy-barra i { animation-delay: 180ms; } .eco-proy:nth-child(5) .eco-proy-barra i { animation-delay: 240ms; }
.eco-col, .eco-proy, .eco-etapa { transition: transform .16s, background .16s; }
.eco-col:hover { transform: translateY(-2px); }
.eco-proy:hover, .eco-etapa:hover { background: var(--bg-hover); }
.eco-col-ingreso i, .eco-col-gasto i { transition: filter .14s; }
.eco-col:hover .eco-col-ingreso i { filter: brightness(1.12); }
/* Las cifras que cuentan van en tabulares para no bailar. */
.stat-value, .stat-card b, .pf-cifra-n, .td-cifra b, .eco-kpi-num, .eco-etapa-val, .pres-kpi-val, .fd-cifra b, .fw-cifra b, .ux-cifra b { font-variant-numeric: tabular-nums; display: inline-block; }
/* Los repintados de la ficha no vuelven a crecer las barras. */
.pf.pf-quieto .pf-progreso-fill, .pf.pf-quieto .proy-card-prog i { animation: none; }

/* El documento entra con un fundido, y SOLO con un fundido.
   (14/9/2026) Antes usaba `stk-entra`, que anima `transform` y acaba en
   `transform: none`. Con `both`, ese valor final se queda puesto para siempre,
   y una animación gana a un estilo en línea: la escala que el visor le pone al
   iframe para que la hoja quepa no se aplicaba nunca. Se veía el documento a
   tamaño real y recortado por el lienzo. */
@keyframes pd-fundido { from { opacity: 0; } to { opacity: 1; } }
#pd-frame.pd-entra { animation: pd-fundido .35s ease both; }

/* El aviso de «Preparando el PDF…». */
.mov-pdf { position: fixed; left: 50%; bottom: 84px; transform: translate(-50%, 12px); z-index: 9000; display: flex; align-items: center; gap: 10px; padding: 10px 14px; background: var(--text); color: var(--bg); font: 600 12.5px/1 var(--font); opacity: 0; transition: opacity .2s, transform .24s cubic-bezier(.2,.9,.3,1); pointer-events: none; }
.mov-pdf.on { opacity: 1; transform: translate(-50%, 0); }
.mov-pdf i { width: 12px; height: 12px; border: 2px solid color-mix(in srgb, var(--bg) 35%, transparent); border-top-color: var(--bg); border-radius: 50% !important; animation: mov-giro .7s linear infinite; }
.mov-pdf.listo i { border-color: var(--pres-ok); animation: none; background: var(--pres-ok); border-radius: 0 !important; }

/* El widget «Material más alquilado»: sus pestañas no se salen de la caja. */
.topmat-tabs { flex-wrap: wrap; overflow: visible; }

@media (prefers-reduced-motion: reduce) {
  .btn:hover, .inv-chip:hover, .clv-card:hover, .fd-cifra:hover, .pres-kpi:hover, .sidebar .nav-item:hover, .eco-col:hover, .td-acceso:hover, .pn-dep:hover { transform: none; }
  .eco-etapa-barra i, .eco-proy-barra i, .fd-barra i, .pf-progreso-fill, .proy-card-prog i, .td-prog i, .eco-col-ingreso i, .eco-col-gasto i, .eco-col-cima, #pd-frame.pd-entra { animation: none; }
}
/* Tarjeta de empleado: el correo largo no se mete debajo de los botones. */
.emp-card { align-items: flex-start; }
.emp-card .emp-info { flex: 1 1 auto; min-width: 0; }
.emp-card .emp-contact { display: flex; align-items: center; gap: 5px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.emp-card .emp-contact > svg { flex: 0 0 auto; }
.emp-card > div[style*="margin-left:auto"] { flex: 0 0 auto; }
.emp-nombre { overflow-wrap: anywhere; }
/* Tarjeta MiFi: código y estado en la primera línea, el operador con su logo
   en la segunda. Antes iban los tres en una y el operador salía «Telef…». */
.mf-card2 .ux-card-cab { flex-wrap: wrap; row-gap: 8px; }
.mf-card2 .ux-card-cab .ux-pill { order: 1; }
.mf-card2 .ux-card-cab .ux-estado { order: 2; margin-left: auto; }
.mf-card2 .ux-card-cab .tel-op { order: 3; flex: 1 1 100%; }
.mf-card2 .ux-card-cab .tel-op-nom { overflow: visible; white-space: normal; }
.veh-plegable > summary { text-transform: none; letter-spacing: -.01em; }

/* ── Formularios como página (`.fp`) ─────────────────────────────────────── */
.fp .fp-sec .form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px 16px; }
.fp .fp-sec .form-grid.full, .fp .fp-sec .form-group.full { grid-column: 1 / -1; }
.fp .fp-sec .form-group { display: flex; flex-direction: column; gap: 6px; min-width: 0; margin: 0 0 12px; }
.fp .fp-sec .form-group > label, .fp .fp-sec label:not(.checkbox):not(.form-check) { font: 600 10.5px/1 var(--mono-rotulo); letter-spacing: .12em; text-transform: uppercase; color: var(--text-soft); }
.fp .fp-sec input:not([type="checkbox"]):not([type="radio"]):not([type="color"]):not([type="file"]), .fp .fp-sec select, .fp .fp-sec textarea, .fp .fp-sec .selector-boton { height: 36px; padding: 0 11px; border: 1px solid var(--border-med); background: var(--bg); color: var(--text); font: 13.5px var(--font); width: 100%; box-sizing: border-box; transition: border-color .15s, box-shadow .15s; }
.fp .fp-sec textarea { height: auto; min-height: 84px; padding: 9px 11px; line-height: 1.5; resize: vertical; }
.fp .fp-sec input:focus, .fp .fp-sec select:focus, .fp .fp-sec textarea:focus { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(var(--acento-rgb), .14); outline: none; }
.fp .fp-sec .form-hint, .fp .fp-sec small { font-size: 12px; color: var(--text-xsoft); }
.fp .fp-pie { position: sticky; bottom: 0; display: flex; align-items: center; justify-content: flex-end; gap: 10px; padding: 14px 0 6px; margin: 0; border: 0; background: linear-gradient(to top, var(--bg) 70%, transparent); z-index: 2; }
.fp .fp-pie-ayuda { margin-right: auto; font: 500 12px/1 var(--mono-rotulo); color: var(--text-soft); }
.fp .fp-pie .btn { height: 38px; padding: 0 16px; }
.fp .fp-pie .btn-primary { box-shadow: 0 8px 20px -8px rgba(var(--acento-rgb), .7); }
.fp-card { border-left-color: var(--accent); }
.fp-card .pn-card-cab { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 8px; }
.fp-card .pn-card-nom { font: 750 20px/1.15 var(--font-display); letter-spacing: -.03em; overflow-wrap: anywhere; }
.fp-card-sub { margin-top: 4px; font-size: 13px; color: var(--text-soft); min-height: 18px; }
.fp-card-mono { margin-top: 6px; font: 500 12px/1 var(--mono-rotulo); letter-spacing: .04em; color: var(--text-soft); min-height: 12px; }
.fp-card-prog { height: 4px; background: var(--surface-2); margin: 14px 0 6px; }
.fp-card-prog i { display: block; height: 100%; width: 0; background: var(--accent); transition: width .35s cubic-bezier(.2,.7,.2,1); }
.fp-card-pie { font: 600 10.5px/1 var(--mono-rotulo); letter-spacing: .08em; text-transform: uppercase; color: var(--text-xsoft); }
.fp .fp-sec .ux-picker, .fp .fp-sec .cat-dd-wrap { width: 100%; }
@media (max-width: 960px) { .fp.pn { grid-template-columns: 1fr; } .fp .pn-lado { position: static; } .fp .fp-sec .form-grid { grid-template-columns: 1fr; } }
/* El cartel «Ahora ves solo Cámara» flotaba DENTRO del flujo: empujaba toda la
   ficha 50 px hacia abajo y, al irse a los tres segundos, todo subía de golpe;
   parecía que la página hacía scroll sola. Ahora es una capa fija encima del
   contenido, en la esquina de la ficha, y no mueve nada. */
.scb-aviso { position: fixed; top: 74px; right: 28px; z-index: 950; margin: 0; box-shadow: var(--shadow-lift); max-width: min(420px, calc(100vw - 56px)); }
@media (max-width: 760px) { .scb-aviso { top: auto; bottom: 84px; right: 16px; left: 16px; } }
/* Al cambiar de subproyecto la ficha entera se desplazaba 9 px hacia abajo y
   volvía: ese salto, sumado al cartel, era «la página se mueve sola». Queda
   el barrido de color (es una capa encima, no mueve nada) y la ficha solo
   parpadea de opacidad, sin desplazarse. */
@keyframes scb-entrar-quieto { from { opacity: .55; } to { opacity: 1; } }
#proy-ficha.scb-cambio { animation: scb-entrar-quieto 320ms ease; }

/* ═══════════════════════════════════════════════════════════════════════════
   PRESUPUESTOS · tramo 1: clientes, versiones, línea de tiempo, días
   ═══════════════════════════════════════════════════════════════════════ */
.cli-tabla td.mono { font-family: var(--mono-rotulo); font-size: 12px; }
.cli-tabla td.n, .cli-tabla th.n { text-align: right; font-variant-numeric: tabular-nums; }
.cli-tabla .cli-razon { font-size: 11.5px; color: var(--text-soft); margin-top: 2px; }
.cli-tabla td.cli-pend { color: var(--accent); font-weight: 600; }
.ux-cuenta { font: 500 11.5px/1 var(--mono-rotulo); color: var(--text-xsoft); margin-left: auto; }
.pres-ver { display: inline-flex; align-items: center; height: 18px; padding: 0 6px; margin-left: 4px; border: 1px solid var(--border-med); font: 600 10px/1 var(--mono-rotulo); letter-spacing: .04em; color: var(--text-soft); vertical-align: middle; }
/* Selector de cliente en el constructor */
.pres-cliente-chapa { display: none; align-items: center; gap: 6px; margin-top: 6px; font: 500 11.5px/1.3 var(--font); color: var(--text-soft); }
.pres-cliente-chapa.con, .pres-cliente-chapa.nuevo { display: flex; }
.pres-cliente-chapa i { width: 7px; height: 7px; background: var(--pres-ok); flex: 0 0 auto; }
.pres-cliente-chapa.nuevo i { background: var(--mo-aviso); }
.pres-cliente-chapa button { background: none; border: 0; padding: 0; font: 600 11.5px var(--font); color: var(--accent); cursor: pointer; }
.pres-dias input { width: 58px; text-align: center; }
/* Versiones */
.pv-versiones { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; padding: 12px 0 4px; }
.pv-versiones-tit { font: 600 10.5px/1 var(--mono-rotulo); letter-spacing: .12em; text-transform: uppercase; color: var(--text-soft); margin-right: 6px; }
.pv-ver { display: inline-flex; flex-direction: column; align-items: flex-start; gap: 2px; padding: 6px 10px; border: 1px solid var(--border-med); background: var(--surface); font: 700 12px/1 var(--mono-rotulo); color: var(--text); cursor: pointer; transition: transform .14s, border-color .14s, background .14s; }
.pv-ver small { font: 500 9.5px/1 var(--mono-rotulo); letter-spacing: .04em; text-transform: uppercase; color: var(--text-xsoft); }
.pv-ver:hover { transform: translateY(-1px); border-color: var(--text-xsoft); }
.pv-ver.act { background: var(--text); color: var(--bg); border-color: var(--text); }
.pv-ver.act small { color: color-mix(in srgb, var(--bg) 70%, transparent); }
.pv-ver.vieja { opacity: .7; }
/* Línea de tiempo */
.pv-linea-caja { margin-top: 12px; padding: 14px 18px 8px; background: var(--surface); border: 1px solid var(--border); }
.pv-linea-tit { font: 600 10.5px/1 var(--mono-rotulo); letter-spacing: .12em; text-transform: uppercase; color: var(--text-soft); margin-bottom: 10px; }
.pv-linea { position: relative; padding-left: 20px; }
.pv-linea::before { content: ''; position: absolute; left: 5px; top: 8px; bottom: 8px; width: 2px; background: var(--border-med); }
.pv-hito { position: relative; padding: 5px 0 9px; font-size: 13px; color: var(--text-soft); }
.pv-hito::before { content: ''; position: absolute; left: -19px; top: 11px; width: 8px; height: 8px; background: var(--text-xsoft); outline: 3px solid var(--surface); }
.pv-hito.hecho::before { background: var(--accent); }
.pv-hito.ok::before { background: var(--pres-ok); }
.pv-hito.pendiente::before { background: transparent; border: 2px dashed var(--text-xsoft); box-sizing: border-box; }
.pv-hito b { color: var(--text); font-weight: 600; display: block; }
.pv-hito span { display: block; font-size: 12.5px; }
.pv-hito small { display: block; margin-top: 2px; font: 500 10.5px/1.4 var(--mono-rotulo); letter-spacing: .03em; color: var(--text-xsoft); }
.pv-hito.pendiente b { color: var(--text-soft); }
/* Diálogo con formulario y comparación */
.modal.dlg.dlg-ancho { width: min(620px, calc(100vw - 32px)); }
.dlg-form { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 14px; margin: 6px 0 16px; }
.dlg-campo { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.dlg-campo:has(textarea) { grid-column: 1 / -1; }
.dlg-campo > span { font: 600 10.5px/1 var(--mono-rotulo); letter-spacing: .12em; text-transform: uppercase; color: var(--text-soft); }
.dlg-form .dlg-inp { margin: 0; }
.pv-cmp-cab { display: flex; align-items: center; gap: 12px; margin: 4px 0 14px; font: 600 13px/1 var(--mono-rotulo); color: var(--text-soft); }
.pv-cmp-cab i { flex: 0 0 24px; height: 2px; background: var(--border-med); }
.pv-cmp-cab b { margin-left: auto; font: 800 16px/1 var(--font-display); }
.pv-cmp-cab b.mas { color: var(--pres-ok); } .pv-cmp-cab b.menos { color: var(--accent); }
.pv-cmp { margin-bottom: 14px; font-size: 13px; }
.pv-cmp td.n, .pv-cmp th.n { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.pv-cmp td small { display: block; font-size: 11px; color: var(--text-xsoft); }
.pv-cmp-quitada td { color: var(--text-xsoft); text-decoration: line-through; }
.pv-cmp-quitada td:first-child { text-decoration: none; }
@media (max-width: 640px) { .dlg-form { grid-template-columns: 1fr; } }
/* Línea de tiempo compacta */
.pv-linea-caja { padding: 12px 16px 6px; }
.pv-linea-tit { display: flex; align-items: center; gap: 8px; }
.pv-linea-tit i { font-style: normal; color: var(--text-xsoft); }
.pv-linea-btn { margin-left: auto; background: none; border: 0; padding: 0; font: 600 11.5px/1 var(--font); color: var(--accent); cursor: pointer; letter-spacing: 0; text-transform: none; }
.pv-hito { padding: 3px 0 7px; font-size: 12.5px; }
.pv-hito b { display: inline; font-size: 12.5px; }
.pv-hito span { display: inline; font-size: 12px; }
.pv-hito b + span::before { content: ' · '; color: var(--text-xsoft); }
.pv-hito small { display: block; margin-top: 1px; font-size: 10px; }
.pv-hito.aviso::before { background: var(--mo-aviso); }
.pv-hito.mas { cursor: pointer; color: var(--text-xsoft); }
.pv-hito.mas b { color: var(--text-soft); font-weight: 500; }
.pv-hito.mas::before { background: transparent; border: 2px dotted var(--text-xsoft); box-sizing: border-box; }

/* ── Respuestas del cliente, bien visibles (12/9/2026) ─────────────────────── */
.rc-barra { flex: 0 0 auto; background: var(--surface); border-bottom: 1px solid var(--border); border-left: 4px solid var(--red); padding: 10px 18px 8px; }
.rc-cab { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 6px; }
.rc-punto { width: 8px; height: 8px; background: var(--red); animation: rc-late 1.6s ease-in-out infinite; }
@keyframes rc-late { 0%, 100% { opacity: 1 } 50% { opacity: .35 } }
.rc-tit { font-weight: 800; font-size: 13px; letter-spacing: -.01em; }
.rc-sub { font-size: 12px; color: var(--text-soft); }
.rc-escritorio { margin-left: auto; background: transparent; border: 1px solid var(--border); color: var(--text-soft); font: 600 11.5px/1 inherit; padding: 6px 10px; cursor: pointer; }
.rc-escritorio:hover { color: var(--text); border-color: var(--text); }
.rc-fila { display: flex; align-items: center; gap: 12px; padding: 7px 0; border-top: 1px solid var(--border); cursor: pointer; font-size: 13px; }
.rc-fila:hover .rc-acc { background: var(--text); color: var(--surface); }
.rc-tipo { flex: 0 0 auto; font: 700 10.5px/1 ui-monospace, Menlo, monospace; letter-spacing: .12em; text-transform: uppercase; padding: 5px 8px; background: rgba(239,35,60,.12); color: var(--red); }
.rc-fila.ok .rc-tipo { background: rgba(52,199,89,.16); color: #1f9d55; }
.rc-txt { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rc-txt i { color: var(--text-soft); font-style: italic; }
.rc-txt small { color: var(--text-xsoft); font-size: 11.5px; margin-left: 6px; }
.rc-acc { flex: 0 0 auto; font-weight: 700; font-size: 12px; padding: 6px 12px; border: 1px solid var(--text); transition: background .12s ease, color .12s ease; }
.rc-mas { padding: 7px 0 2px; font-size: 12px; color: var(--text-soft); cursor: pointer; border-top: 1px solid var(--border); }
.badge-resp { background: var(--red); color: #fff; font-weight: 700; animation: rc-late 1.6s ease-in-out infinite; }
.badge-resp::before { display: none !important; }
.pd-cinta-resp { display: flex; gap: 16px; align-items: flex-start; justify-content: space-between; padding: 14px 16px; font-size: 13px; border-left-width: 4px; }
.pd-cinta-resp.ok { background: rgba(52,199,89,.10); border-left-color: #1f9d55; color: var(--text); }
.pd-cinta-resp.cambios { background: rgba(239,35,60,.08); border-left-color: var(--red); color: var(--text); }
.pd-cinta-resp .rc-eyebrow { display: block; font: 700 10.5px/1 ui-monospace, Menlo, monospace; letter-spacing: .14em; text-transform: uppercase; margin-bottom: 6px; }
.pd-cinta-resp.ok .rc-eyebrow { color: #1f9d55; }
.pd-cinta-resp.cambios .rc-eyebrow { color: var(--red); }
.pd-cinta-resp blockquote { margin: 8px 0; padding: 8px 12px; background: var(--surface); border-left: 3px solid var(--border); font-style: italic; }
.pd-cinta-resp small { display: block; color: var(--text-soft); margin-top: 4px; }
.rc-cinta-txt { flex: 1; min-width: 0; }
.rc-cinta-acc { display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; flex: 0 0 auto; }
@media (max-width: 720px) { .pd-cinta-resp { flex-direction: column; } .rc-txt { white-space: normal; } }
tr.pres-fila-resp > td { background: rgba(239,35,60,.06); }
tr.pres-fila-resp > td:first-child { box-shadow: inset 3px 0 0 var(--red); }
@media (max-width: 720px) { .rc-txt i { display: none; } }
/* En pantalla estrecha la franja se queda en dos líneas por respuesta. */
@media (max-width: 720px) {
  .rc-barra { padding: 8px 14px 6px; }
  .rc-sub, .rc-tipo, .rc-txt small, .rc-escritorio { display: none; }
  .rc-fila { gap: 10px; padding: 6px 0; }
  .rc-txt { white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; font-size: 12.5px; }
  .rc-acc { padding: 5px 10px; font-size: 11.5px; }
}

/* ── Selección de líneas y descuento por lote; versión a la vista (12/9/2026) ── */
.pres-sel-th input, .pres-sel-td input { width: 15px; height: 15px; margin: 0; accent-color: var(--red); cursor: pointer; }
.pres-sel-td { width: 34px; text-align: center; }
tr.pres-fila-sel > td { background: rgba(239,35,60,.06); }
.pres-dto-chip { display: inline-block; margin-left: 8px; padding: 2px 6px; font: 700 10.5px/1 var(--mono-rotulo, ui-monospace, Menlo, monospace); letter-spacing: .04em; background: rgba(239,35,60,.12); color: var(--red); vertical-align: middle; }
.pres-sel-barra { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 8px 12px; margin-bottom: 8px; background: var(--surface-2); border: 1px solid var(--border); border-left: 3px solid var(--red); font-size: 13px; }
.pres-sel-barra .pres-sel-n { margin-right: auto; color: var(--text-soft); }
.pres-sel-barra .pres-sel-n b { color: var(--text); font-size: 15px; }
.pres-version-cinta { margin: -6px 0 14px; padding: 10px 14px; background: color-mix(in srgb, var(--accent) 10%, transparent); border-left: 3px solid var(--accent); font-size: 13px; line-height: 1.5; }
.pres-version-cinta b { font-weight: 800; }
.pres-version-ant { color: var(--text-soft); }
.pres-version-ant button, .pd-cinta-enlace { background: none; border: 0; padding: 0; font: inherit; font-weight: 700; color: var(--text); text-decoration: underline; cursor: pointer; }
.pd-cinta-version { background: color-mix(in srgb, var(--accent) 10%, transparent); border-left-color: var(--accent); color: var(--text); }

/* ── Licencias de Microsoft 365 (13/9/2026) ────────────────────────────────
   Lo primero es cuántas quedan; el resto es el detalle por licencia. La barra
   enseña la ocupación y el color dice si hay margen: verde con holgura, ámbar
   cuando quedan dos o menos, rojo cuando no queda ninguna. */
.lic-panel { margin-bottom: 26px; }
.lic-cifras { margin-bottom: 10px; }
.lic-cargando { padding: 22px 4px; font-size: 13.5px; color: var(--text-soft); }
.lic-lista { display: flex; flex-direction: column; border-top: 1px solid var(--border); }
.lic {
  display: grid; grid-template-columns: minmax(170px, 1.4fr) minmax(90px, 2fr) minmax(190px, auto);
  gap: 18px; align-items: center;
  padding: 12px 4px; border-bottom: 1px solid var(--border-soft, var(--border));
}
.lic:hover { background: var(--bg-hover); }
.lic-nombre b { display: block; font-size: 14px; font-weight: 600; letter-spacing: -0.01em; }
.lic-cod { font-size: 11px; color: var(--text-xsoft); font-family: ui-monospace, Menlo, Consolas, monospace; }
.lic-barra { height: 8px; background: var(--bg-hover); overflow: hidden; }
.lic-barra i { display: block; height: 100%; background: var(--text-soft); }
.lic.holgada .lic-barra i { background: var(--pres-ok, #1f9d55); }
.lic.justa   .lic-barra i { background: var(--mo-aviso, #b8860b); }
.lic.agotada .lic-barra i { background: var(--red); }
.lic-cuenta { font-size: 12.5px; color: var(--text-soft); text-align: right; }
.lic-libres { font-size: 19px; font-weight: 700; letter-spacing: -0.03em; color: var(--text); }
.lic.holgada .lic-libres { color: var(--pres-ok, #1f9d55); }
.lic.justa   .lic-libres { color: var(--mo-aviso, #b8860b); }
.lic.agotada .lic-libres { color: var(--red); }
.lic-cuenta em { display: block; font-style: normal; font-variant-numeric: tabular-nums; }
.lic-cuenta small { display: block; color: var(--mo-aviso, #b8860b); font-size: 11.5px; }
.lic-mas { margin-top: 10px; }
.lic-otras .lic { grid-template-columns: minmax(170px, 1.4fr) minmax(190px, auto); opacity: .75; }
.lic-otras .lic-cuenta { text-align: left; }
@media (max-width: 720px) {
  .lic, .lic-otras .lic { grid-template-columns: 1fr; gap: 8px; }
  .lic-cuenta, .lic-otras .lic-cuenta { text-align: left; }
}

/* ── Cambiar contraseña de Microsoft 365 (13/9/2026) ───────────────────────── */
.ms-pass { color: var(--text-soft); }
.ms-pass:hover { color: var(--text); }
.pw-opcion { display: flex; gap: 10px; align-items: flex-start; padding: 12px 0 2px; cursor: pointer; }
.pw-opcion input { margin-top: 3px; flex: 0 0 auto; }
.pw-opcion span { font-size: 13.5px; }
.pw-opcion small { display: block; color: var(--text-soft); font-size: 12.5px; margin-top: 2px; }
.pw-caja { display: flex; align-items: center; gap: 12px; margin: 4px 0 10px; padding: 14px 16px; background: var(--bg-hover); border-left: 3px solid var(--accent); }
.pw-valor {
  flex: 1; min-width: 0; user-select: all; word-break: break-all;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 21px; font-weight: 600; letter-spacing: 0.06em; color: var(--text);
}
.pw-copiar { flex: 0 0 auto; }
.pw-aviso { font-size: 12.5px; color: var(--text-soft); margin: 0 0 12px; }
.pw-pasos { margin: 0; padding-left: 18px; font-size: 13.5px; line-height: 1.7; }
.pw-pasos li { margin-bottom: 2px; }
/* En «Todos» conviven las cuatro clases: la chapa verde distingue de un vistazo
   lo que ya está en Empleados de lo que sigue pendiente. */
.ms-badge.ms-badge-ok { background: rgba(52,199,89,.14); color: var(--pres-ok, #1f9d55); }

/* ── Versiones: decir siempre dónde estás (13/9/2026) ──────────────────────── */
.pvc-tit { display: flex; align-items: center; gap: 9px; font-size: 14px; letter-spacing: -0.01em; }
.pvc-tit i { width: 7px; height: 7px; flex: 0 0 auto; background: var(--accent); }
.pvc-pasos { margin: 8px 0 0; padding-left: 17px; font-size: 13px; line-height: 1.65; color: var(--text-soft); }
.pvc-pasos li { margin-bottom: 2px; }
.pvc-pasos b { color: var(--text); font-weight: 600; }
.pvc-pasos .ux-acc { margin-left: 4px; }
.enviar-version {
  margin: 0 0 14px; padding: 11px 14px; font-size: 13px; line-height: 1.55;
  background: var(--bg-hover); border-left: 3px solid var(--accent); color: var(--text);
}

/* El buscador de Empleados comparte barra con el selector de vista. */
.emp-vista-barra { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.emp-buscar { flex: 1 1 260px; min-width: 200px; max-width: 520px; }
@media (max-width: 640px) { .emp-buscar { flex-basis: 100%; max-width: none; } }

/* «Pasar a Finanzas» era un enlace de texto y se perdía: es el paso siguiente
   del camino, así que ahora es un botón de verdad. */
.eq-a-finanzas { margin-left: auto; }

/* ── El proyecto, con su color, en la lista de presupuestos (15/9/2026) ─────
   El color se mezcla con el color del texto en vez de usarse tal cual: los
   tonos del calendario están pensados para barras de color macizo y algunos,
   en texto pequeño sobre blanco, se leen mal: hay proyectos con amarillo puro.
   La proporción está medida, no elegida a ojo: con un 55 % el peor color de
   los que hay en la casa pasa de 2,1 a más de 4,5 de contraste, que es el
   mínimo legible. El punto de la izquierda sí lleva el color puro, y es el que
   hace el trabajo de distinguir de un vistazo. Funciona igual en claro y en
   oscuro porque el que manda en la mezcla es el texto del tema. */
.pres-proy-nom {
  display: inline-flex; align-items: center; gap: 7px;
  font-weight: 600; letter-spacing: -0.01em;
  color: var(--ct, var(--text));
}
:root[data-tema="oscuro"] .pres-proy-nom { color: var(--cto, var(--text)); }
@media (prefers-color-scheme: dark) {
  :root:not([data-tema="claro"]) .pres-proy-nom { color: var(--cto, var(--text)); }
}
.pres-proy-nom i { width: 8px; height: 8px; flex: 0 0 auto; background: var(--c, var(--text-xsoft)); }

/* ── Enlaces de solo calendario (15/9/2026) ────────────────────────────────── */
.enl-lista { display: flex; flex-direction: column; gap: 10px; margin-bottom: 14px; }
.enl { display: flex; align-items: flex-start; gap: 14px; padding: 12px 14px; background: var(--surface-2); border-left: 3px solid var(--accent); }
.enl-datos { flex: 1; min-width: 0; }
.enl-datos b { display: block; font-size: 13.5px; }
.enl-datos small { display: block; color: var(--text-soft); font-size: 12px; margin: 2px 0 8px; }
.enl-url { width: 100%; font-family: var(--font-mono); font-size: 12px; padding: 7px 9px; background: var(--surface); border: 1px solid var(--border); color: var(--text-soft); }
.enl-acc { display: flex; gap: 6px; flex-wrap: wrap; flex: 0 0 auto; }
@media (max-width: 640px) { .enl { flex-direction: column; } }

/* ── EL ENLACE DE SOLO CALENDARIO: PANTALLA DESNUDA (15/9/2026) ─────────────
   Sin barra lateral y sin pestañas. No hace falta menú donde solo hay una
   pantalla, y quien entra por el enlace no puede abrir ninguna otra. El
   calendario gana todo el ancho, que es justo lo que le hace falta a una
   rejilla de vehículos por días. */
body.kiosko .sidebar,
body.kiosko .tabbar-fila { display: none !important; }
body.kiosko .main { width: 100%; }
body.kiosko .main-scroll { padding-top: 14px; }
/* La cabecera de la pantalla ya dice dónde estás; el resto de adornos de
   navegación, fuera. */
body.kiosko .page-header .page-subtitle { max-width: 70ch; }

/* ── Los grupos del calendario YA NO BAJAN (8/10/2026) ──────────────────────
   Se pegaron arriba el 15/9/2026 para no perder de vista de qué grupo era la
   fila que estabas mirando. En la práctica hace lo contrario: la banda viaja
   hacia abajo contigo, se mete entre las filas y tapa barras, que es lo que se
   veía en la captura. Xavi: «NO quiero que bajen las filas. Quítalo. Quiero
   que esté todo estático».

   Se queda quieta en su sitio, como una fila más. Lo único que sigue pegado
   es lo que tiene que estarlo de verdad: la cabecera arriba y la columna de
   nombres a la izquierda.

   El rótulo del grupo SÍ conserva su `left: 0` (regla propia, más abajo): al
   desplazar a los lados el nombre del grupo tiene que seguir leyéndose, igual
   que el del vehículo. Lo que se quita es bajar, no quedarse a la izquierda. */
.cal-grupo-fila > td { position: static; z-index: auto; }
.cal-grupo-fila .cal-grupo-banda { background: var(--surface-2); }


/* El calendario de producción, mientras se vuelve a pedir después de pintar.
   No se vacía la rejilla: solo se apaga un poco, para que se note que está
   trabajando sin que la pantalla dé un salto. */
.pc-refrescando { opacity: 0.72; transition: opacity 0.12s ease; }

/* ── Avisos por correo (Ajustes) ─────────────────────────────────────────── */
/* Tres pasos numerados, como el resto de la casa. Lo primero de todo es la
   casilla donde se escribe el correo: la pregunta que se hizo mirando la
   pantalla fue «¿qué pongo ahí, mi mail?», y una pantalla que hay que
   preguntar está mal puesta. */
.avq-paso { padding: 16px 0; border-top: 1px solid var(--border); }
.avq-paso:first-child { border-top: 0; padding-top: 4px; }
.avq-paso-tit {
  display: block; font-size: 12px; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--text-soft); margin-bottom: 10px;
}
.avq-apagado { opacity: 0.5; }

/* La casilla y su botón, uno al lado del otro y grandes. */
.avq-alta { display: flex; gap: 8px; flex-wrap: wrap; }
.avq-alta input {
  flex: 1 1 260px; height: 42px; padding: 0 12px; font-size: 15px;
  font-family: inherit; color: var(--text);
  background: var(--surface); border: 1px solid var(--border-med);
}
.avq-alta input:focus { outline: 2px solid var(--accent); outline-offset: -1px; }
.avq-alta .btn { height: 42px; padding: 0 20px; }

.avq-lista { list-style: none; margin: 12px 0 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.avq-fila {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 10px 12px; background: var(--surface-2); border: 1px solid var(--border);
}
.avq-mail { font-size: 14.5px; font-weight: 600; word-break: break-all; }
.avq-vacio { margin-top: 12px; font-size: 13.5px; color: var(--text-soft); }

.aj-check { display: flex; align-items: center; gap: 9px; cursor: pointer;
            font-size: 14.5px; padding: 5px 0; }
.aj-check input { flex: 0 0 auto; }
.aj-check b { font-weight: 700; }
.avq-maestro { margin-top: 8px; padding-top: 10px; border-top: 1px dashed var(--border); }

/* El ejemplo del correo. Enseñarlo evita la pregunta «¿y qué me va a llegar?»
   mucho mejor que cualquier párrafo explicándolo. */
.avq-muestra {
  border: 1px solid var(--border-med); background: var(--surface);
  padding: 14px 16px; max-width: 26rem; margin-bottom: 12px;
}
.avq-muestra-de { font-size: 11.5px; color: var(--text-soft); }
.avq-muestra-asunto { font-size: 15px; font-weight: 700; margin: 4px 0 10px; }
.avq-muestra-datos { margin: 0; display: flex; flex-direction: column; gap: 3px; }
.avq-muestra-datos > div { display: flex; gap: 10px; font-size: 13.5px; }
.avq-muestra-datos dt { min-width: 74px; color: var(--text-soft); }
.avq-muestra-datos dd { margin: 0; font-weight: 600; }

.avq-de { margin-top: 14px; }
.avq-estado { margin-top: 14px; font-size: 13.5px; }
.avq-estado.ok { color: var(--text-soft); }
.avq-estado.mal {
  display: flex; flex-direction: column; gap: 3px;
  padding: 11px 13px; border: 1px solid var(--red);
  background: color-mix(in srgb, var(--red) 7%, transparent);
}
.avq-estado.mal b { color: var(--red); font-size: 13.5px; }
.avq-estado.mal span { color: var(--text-2); }
.avq-estado.mal small { color: var(--text-soft); font-size: 12px; }

/* ── Historial completo de un MiFi ───────────────────────────────────────── */
.modal.mfh { max-width: 640px; width: 100%; }
.mfh-estado { margin: 2px 0 16px; font-size: 14.5px; color: var(--text-2); }
.mfh-estado.fuera b { color: var(--red); }

/* Las cuatro cifras de cabecera: cuánto se mueve esto, de un vistazo. */
.mfh-cifras { display: flex; gap: 10px; margin-bottom: 18px; flex-wrap: wrap; }
.mfh-cifras > div {
  flex: 1 1 96px; padding: 10px 12px;
  background: var(--surface-2); border: 1px solid var(--border);
}
.mfh-cifras b { display: block; font-size: 21px; line-height: 1.1; font-variant-numeric: tabular-nums; }
.mfh-cifras span { font-size: 11.5px; letter-spacing: .04em; text-transform: uppercase; color: var(--text-soft); }

/* La línea de tiempo. El filete de la izquierda la ata; el de la salida
   abierta va en rojo porque es la única fila sobre la que se puede actuar. */
.mfh-lista { list-style: none; margin: 0; padding: 0; max-height: 46vh; overflow-y: auto; }
.mfh-item {
  padding: 11px 0 12px 14px; border-left: 2px solid var(--border-med);
  margin-left: 2px;
}
.mfh-item + .mfh-item { border-top: 1px solid var(--border); }
.mfh-item.abierta { border-left-color: var(--red); }
.mfh-linea { display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap; }
.mfh-linea b { font-size: 15px; }
.mfh-fechas { font-size: 13.5px; color: var(--text-2); font-variant-numeric: tabular-nums; }
.mfh-dias {
  font-size: 11.5px; color: var(--text-soft);
  border: 1px solid var(--border); padding: 1px 6px;
}
.mfh-tarde { font-size: 11.5px; color: var(--red); font-weight: 700; }
.mfh-gente { display: flex; flex-direction: column; gap: 2px; margin-top: 6px; font-size: 13.5px; color: var(--text-2); }
.mfh-gente b { color: var(--text); }
.mfh-gente em { color: var(--text-soft); font-style: normal; font-size: 12.5px; }
.mfh-ico { display: inline-block; width: 14px; color: var(--text-soft); font-style: normal; }
.mfh-pend { color: var(--red); font-weight: 600; }
.mfh-nota { margin-top: 6px; font-size: 13px; color: var(--text-soft); }

@media (max-width: 560px) {
  .mfh-cifras > div { flex: 1 1 calc(50% - 5px); }
}

/* ═══════════════════════════════════════════════════════════════════════════
   EL INVENTARIO EN EL MÓVIL

   MEDIDO antes de esto en un iPhone (390×844): 346-367 px por artículo, o sea
   2,3 por pantalla. Con 809 artículos no se puede buscar nada.

   La causa era el apaño general de tablas (`.mov-tabla`), que pinta una línea
   por columna — y esta tabla tiene nueve. Aquí el inventario se sale de ese
   apaño: el nombre arriba, y el resto en UNA línea debajo.

   Va por CLASES (`.inv-c-*`) y no por el `data-mov-col` del apaño general, por
   dos razones: ese atributo lo pone un pase aparte que puede no haber corrido
   cuando se repinta la tabla —medido: llegaba con las celdas sin atributo—, y
   además depende del TEXTO de la cabecera, que cambia el día que alguien
   renombre una columna.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 720px) {
  #page-inventario .mov-tabla tbody tr {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 2px 8px;
    /* Hueco a la derecha para el botón de foto, que va anclado: si va en el
       flujo se cae a una tercera línea en cuanto el nombre es largo, y una
       tercera línea son 35 px por artículo que no valen nada. */
    padding: 11px 74px 11px 13px;
    margin-bottom: 7px;
    border-radius: 0;
  }

  /* Ninguna etiqueta delante: con el nombre arriba y tres datos cortos debajo,
     «CÓDIGO:» y «CATEGORÍA:» son más letra que el dato. */
  #page-inventario .mov-tabla tbody td::before { content: none !important; }

  #page-inventario .mov-tabla tbody td {
    display: inline-flex;
    align-items: baseline;
    width: auto !important;
    flex: 0 0 auto;
    padding: 0 !important;
    border: 0 !important;
    font-size: 12.5px;
    color: var(--text-soft);
    text-align: left !important;
  }

  /* Fuera de la tarjeta lo que no se mira en un almacén, y la casilla de
     selección: seleccionar en bloque para exportar o borrar es trabajo de
     escritorio, y con el dedo solo estorba. */
  #page-inventario .mov-tabla tbody td.inv-c-precio,
  #page-inventario .mov-tabla tbody td.inv-c-alq,
  #page-inventario .mov-tabla tbody td.inv-c-sel { display: none; }

  /* El nombre es lo que se busca: línea propia, arriba y legible. */
  #page-inventario .mov-tabla tbody td.inv-c-nom {
    flex: 1 0 100%;
    order: -1;
    font-size: 15px;
    font-weight: 600;
    color: var(--text);
    line-height: 1.3;
    margin-bottom: 3px;
  }

  /* Código · categoría · unidades, separados por puntos medios en vez de por
     etiquetas: ocupa la mitad y se lee igual. */
  #page-inventario .mov-tabla tbody td.inv-c-cod::after,
  #page-inventario .mov-tabla tbody td.inv-c-cat::after {
    content: '·';
    margin-left: 8px;
    color: var(--text-xsoft);
  }
  #page-inventario .mov-tabla tbody td.inv-c-uds::after {
    content: ' ud.';
    color: var(--text-xsoft);
  }
  #page-inventario .mov-tabla .cat-chip {
    background: none; border: 0; padding: 0; height: auto;
    font-size: 12.5px; color: var(--text-soft);
  }
  #page-inventario .mov-tabla .badge { font-size: 10.5px; padding: 1px 6px; }

  /* De los cinco botones queda «Foto», que es a lo que se viene. Editar y
     Borrar NO: un borrado a dedo, en un almacén y con una mano ocupada, es un
     accidente esperando. La ficha se abre tocando la tarjeta. */
  #page-inventario .mov-tabla td.actions {
    position: absolute; right: 12px; top: 50%; transform: translateY(-50%);
    flex: 0 0 auto;
  }
  #page-inventario .mov-tabla td.actions .btn { display: none; }
  #page-inventario .mov-tabla td.actions .inv-foto {
    display: inline-flex; height: 30px; padding: 0 12px; font-size: 12.5px;
  }

  #page-inventario .mov-tabla tbody tr.inv-fila { cursor: pointer; }
}

/* En escritorio el botón de foto no hace falta: ahí se abre la ficha y se
   arrastran las fotos, que es más cómodo con ratón. */
@media (min-width: 721px) { .inv-foto { display: none; } }


/* La ruta va DELANTE del nombre en los resultados de búsqueda. Xavi, viendo
   «4x5.65  Camera / Accesories / Filters»: «¿por qué sale el material? Tiene
   que salir solamente la categoría». No salía ningún material —eran todo
   categorías— pero con el nombre primero se leen como cosas y no como sitios.
   Puesta delante, «Camera / Accesories / Filters / 4x5.65» ya es una ruta. */
/* Órdenes explícitos: el chevron primero, la ruta después y el nombre al
   final. Con solo `order:-1` en la ruta se colaba DELANTE del chevron. */
.cat-dd-fila .cat-dd-chev { order: -2; }
.cat-dd-fila .cat-dd-ruta { order: -1; margin-right: -2px; }
.cat-dd-fila .cat-dd-nom  { order: 0; font-weight: 600; }

/* ═══════════════════════════════════════════════════════════════════════════
   DENTRO DEL KIT

   La forma la eligió Xavi enseñándome el «Accessory Compatibility Wizard» de
   Aputure: rejilla de tarjetas con la foto grande arriba y dos líneas debajo.
   Funciona porque la foto hace el trabajo de reconocer la pieza.

   El problema: hoy NINGUNO de los 809 artículos tiene foto. Así que el hueco de
   la imagen no es un placeholder gris esperando: lleva el CÓDIGO en grande, que
   es lo que se dice por radio y lo que está escrito en el flight. Sirve solo, y
   el día que alguien haga la foto desde el móvil la tarjeta mejora sin tocar
   nada.
   ═══════════════════════════════════════════════════════════════════════════ */

/* La respuesta antes que la lista: cuántos salen y qué lo impide. */
.kit-cabeza {
  display: flex; align-items: baseline; gap: 16px; flex-wrap: wrap;
  padding: 14px 16px; margin-bottom: 14px;
  background: var(--surface-2); border-left: 3px solid var(--accent);
}
.kit-cabeza.cero { border-left-color: var(--red); }
.kit-montables { display: flex; align-items: baseline; gap: 8px; }
.kit-montables b { font-size: 30px; line-height: 1; font-variant-numeric: tabular-nums; }
.kit-cabeza.cero .kit-montables b { color: var(--red); }
.kit-montables span { font-size: 12px; letter-spacing: .05em; text-transform: uppercase; color: var(--text-soft); }
.kit-tope { font-size: 13.5px; color: var(--text-2); }
.kit-tope b { color: var(--text); }

.kit-n {
  font-size: 11px; font-weight: 700; color: var(--text-soft);
  border: 1px solid var(--border); padding: 1px 6px; margin-left: 6px;
}

.kit-rejilla {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 12px; margin-bottom: 14px;
}

.kit-tarjeta {
  display: flex; flex-direction: column; text-align: left;
  border: 1px solid var(--border); background: var(--surface);
  cursor: pointer; padding: 0; font-family: inherit;
  transition: border-color .12s ease;
}
.kit-tarjeta:hover { border-color: var(--border-strong); }
.kit-tarjeta.limita { border-color: var(--accent); }
.kit-tarjeta.rota { opacity: .55; cursor: default; }

/* El hueco de la foto: cuadrado, con el mismo fondo tenga imagen o no, para que
   la rejilla no baile mientras se van llenando. */
.kit-foto {
  position: relative; aspect-ratio: 1 / 1; background: var(--surface-sunk);
  display: flex; align-items: center; justify-content: center; overflow: hidden;
}
.kit-foto img { width: 100%; height: 100%; object-fit: contain; }
.kit-foto-cod {
  font-size: 19px; font-weight: 700; letter-spacing: -.01em;
  color: var(--text-xsoft); font-variant-numeric: tabular-nums;
  padding: 0 10px; text-align: center; overflow-wrap: anywhere;
}
.kit-cant {
  position: absolute; left: 0; top: 0;
  background: var(--text); color: var(--surface);
  font-size: 12px; font-weight: 700; padding: 2px 8px;
  font-variant-numeric: tabular-nums;
}
.kit-limita {
  position: absolute; right: 0; bottom: 0;
  background: var(--accent); color: #fff;
  font-size: 10px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  padding: 2px 7px;
}
.kit-quitar {
  position: absolute; right: 4px; top: 4px; width: 22px; height: 22px;
  border: 0; background: rgba(0,0,0,.5); color: #fff; font-size: 12px;
  cursor: pointer; opacity: 0; transition: opacity .12s ease;
}
.kit-tarjeta:hover .kit-quitar { opacity: 1; }
.kit-quitar:hover { background: var(--red); }

.kit-txt { padding: 9px 10px 11px; display: flex; flex-direction: column; gap: 2px; }
.kit-txt b { font-size: 13.5px; font-weight: 600; line-height: 1.25; }
.kit-txt small { font-size: 12px; color: var(--text-soft); font-variant-numeric: tabular-nums; }

/* La tarjeta de añadir: mismo tamaño, sin peso visual. */
.kit-mas {
  align-items: center; justify-content: center; gap: 6px;
  border-style: dashed; background: none; color: var(--text-soft);
}
.kit-mas-signo { font-size: 26px; line-height: 1; }
.kit-mas-txt { font-size: 12.5px; }
.kit-mas:hover { color: var(--text); border-color: var(--border-strong); }

.kit-vacio {
  display: flex; flex-direction: column; align-items: flex-start; gap: 7px;
  padding: 16px; margin-top: 22px; border: 1px dashed var(--border-med);
}
.kit-vacio b { font-size: 14px; }
.kit-vacio span { font-size: 13px; color: var(--text-soft); max-width: 42ch; }

.kit-padres { margin-top: 16px; font-size: 13px; color: var(--text-soft); }
.kit-padres b { color: var(--text); margin-right: 6px; }
.kit-ir {
  border: 0; background: none; padding: 0 6px 0 0; font: inherit;
  color: var(--accent); cursor: pointer; text-decoration: underline;
}
.kit-chip {
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
  color: var(--text-soft); border: 1px solid var(--border); padding: 0 5px; margin-left: 6px;
}

/* El elegir entre varios resultados. */
.kit-hits { display: flex; flex-direction: column; gap: 5px; max-height: 44vh; overflow-y: auto; margin: 4px 0 6px; }
.kit-hit {
  display: flex; flex-direction: column; gap: 2px; text-align: left;
  padding: 9px 11px; border: 1px solid var(--border); background: var(--surface);
  font-family: inherit; cursor: pointer;
}
.kit-hit:hover { border-color: var(--accent); }
.kit-hit b { font-size: 13.5px; }
.kit-hit small { font-size: 12px; color: var(--text-soft); }

@media (max-width: 720px) {
  .kit-rejilla { grid-template-columns: repeat(auto-fill, minmax(128px, 1fr)); gap: 9px; }
  .kit-quitar { opacity: 1; }
}
/* Sin código, el hueco lleva el nombre: más pequeño, porque es más largo. */
.kit-foto-cod.sin-cod { font-size: 13px; font-weight: 600; line-height: 1.3; }
#mat-kit { margin-top: 4px; }

/* ── Qué es kit y qué es pieza, en la lista ──────────────────────────────────
   Xavi: «no veo nada de lo que has hecho; que se distinga si algo es de un kit
   o no». El panel del kit solo vivía dentro de la ficha, y a la ficha hay que
   entrar: en la lista —que es donde se mira— no había ni rastro.

   Dos marcas distintas a propósito. Ser un kit es una PROPIEDAD (lleva dentro)
   y va en fuerte, con el número de piezas. Estar dentro de un kit es una
   RELACIÓN (pertenece a otro) y va en gris: informa, no compite con el nombre.
   ═══════════════════════════════════════════════════════════════════════════ */
.inv-kit {
  display: inline-flex; align-items: center; gap: 4px; vertical-align: middle;
  margin-left: 8px; padding: 1px 6px;
  background: var(--accent); color: #fff;
  font-size: 9.5px; font-weight: 800; letter-spacing: .09em;
}
.inv-kit b { font-size: 11px; font-weight: 800; letter-spacing: 0; }
.inv-pieza {
  margin-left: 8px; font-size: 11.5px; font-weight: 400; color: var(--text-soft);
}
.inv-pieza::before { content: '↳ '; color: var(--text-xsoft); }

/* La fila de un kit lleva un filete: se encuentran de un vistazo al pasar la
   lista, sin leer. */
.inv-fila.es-kit > td:first-child { box-shadow: inset 3px 0 0 var(--accent); }

/* En la cuadrícula, una cinta arriba. */
.inv-card { position: relative; }
.inv-card.es-kit { border-color: var(--accent); }
.inv-card-kit {
  position: absolute; left: 0; top: 0; z-index: 2;
  background: var(--accent); color: #fff;
  font-size: 9.5px; font-weight: 800; letter-spacing: .07em; text-transform: uppercase;
  padding: 2px 8px;
}
.inv-card-pieza {
  font-size: 11.5px; color: var(--text-soft); margin-top: -2px;
}
.inv-card-pieza::before { content: '↳ '; color: var(--text-xsoft); }

/* El filtro «Kits», encendido. */
.inv-filtro-kits { display: inline-flex; align-items: center; gap: 6px; }
.inv-filtro-kits.activo {
  background: var(--accent); color: #fff; border-color: var(--accent);
}
.inv-filtro-kits.activo:hover { background: var(--accent); }

@media (max-width: 720px) {
  /* En el móvil el nombre ya va en su línea: la marca cabe detrás. */
  #page-inventario .mov-tabla tbody td.inv-c-nom .inv-kit,
  #page-inventario .mov-tabla tbody td.inv-c-nom .inv-pieza { margin-left: 6px; }
}

/* ── El kit desplegable en la lista ───────────────────────────────────────────
   Xavi: «que en el inventario general, si tienes un material con materiales
   dentro, con un desplegable puedas verlo; pero si no, que salga escondido».

   Las piezas ya no salen sueltas en la lista —contarlas dos veces al pasar el
   inventario es justo lo que hacía que no se entendiera nada— y se ven
   abriendo su kit. */
.inv-abrir-kit {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; margin-right: 6px; vertical-align: middle;
  border: 1px solid var(--border-med); background: var(--surface);
  color: var(--text-soft); cursor: pointer; padding: 0;
  transition: transform .12s ease, color .12s ease, border-color .12s ease;
}
.inv-abrir-kit:hover { color: var(--accent); border-color: var(--accent); }
.inv-abrir-kit.abierta { transform: rotate(90deg); color: var(--accent); border-color: var(--accent); }

/* Las filas de dentro. Xavi, viendo un kit de 36 piezas desplegado: «queda un
   poco atropellado el diseño, ¿no?». Y sí: cada fila repetía «dentro de Arri
   Alexa 35 Camera Package 4.6K (S35 Sensor)» —36 veces, partido en dos líneas—,
   y el filete salía troceado por los bordes de cada fila.

   Ahora el bloque se lee como UNO: sin separadores dentro, el filete corrido de
   arriba abajo, filas de una línea y ni una palabra repetida. Lo que dice a qué
   kit pertenecen es la sangría y la banda, no un texto en cada fila. */
.inv-fila-dentro > td {
  background: var(--surface-2);
  font-size: 12.5px;
  padding-top: 5px !important;
  padding-bottom: 5px !important;
  border-top: 0 !important;
  border-bottom: 0 !important;
  white-space: nowrap;
}
/* El filete, corrido: va en el primer td de cada fila y, al no haber bordes
   entre ellas, se lee como una sola banda. */
.inv-fila-dentro > td:first-child { box-shadow: inset 3px 0 0 var(--accent); }
.inv-fila-dentro.ultima > td { border-bottom: 1px solid var(--border) !important; }
.inv-fila-dentro .inv-c-cod { font-size: 11.5px; color: var(--text-xsoft); font-variant-numeric: tabular-nums; }
.inv-fila-dentro .inv-c-nom { padding-left: 30px !important; font-weight: 400; }
.inv-fila-dentro .actions .btn { opacity: 0; transition: opacity .12s ease; }
.inv-fila-dentro:hover .actions .btn { opacity: 1; }
.inv-dentro-cant {
  display: inline-block; min-width: 24px; margin-right: 8px;
  font-weight: 700; color: var(--accent); font-variant-numeric: tabular-nums;
}
.inv-fila.es-kit.abierto > td { border-bottom: 0; }

/* ── Elegir varias piezas de una vez ─────────────────────────────────────── */
.kit-dlg { max-width: 560px; width: 100%; }
.kit-busca { margin-bottom: 10px; }
.kit-ops {
  display: flex; flex-direction: column;
  max-height: 46vh; overflow-y: auto;
  border: 1px solid var(--border);
}
.kit-op {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 11px; cursor: pointer; border-bottom: 1px solid var(--border);
}
.kit-op:last-child { border-bottom: 0; }
.kit-op:hover { background: var(--surface-2); }
.kit-op.ya { opacity: .5; cursor: default; }
.kit-op input { flex: 0 0 auto; }
.kit-op-txt { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.kit-op-txt b { font-size: 13.5px; font-weight: 600; }
.kit-op-txt small { font-size: 11.5px; color: var(--text-soft); }
.kit-nada { padding: 16px; text-align: center; font-size: 13px; color: var(--text-soft); }
.kit-cuenta { margin-right: auto; font-size: 13px; color: var(--text-soft); }

/* El «2×» de la tarjeta se toca para cambiarlo. */
button.kit-cant { border: 0; font-family: inherit; cursor: pointer; }
button.kit-cant:hover { background: var(--accent); }

@media (max-width: 720px) {
  /* En la tarjeta del móvil, la categoría de una pieza va vacía —el bloque ya
     dice de qué kit es— y su punto de separación quedaba suelto: «4149 · · 1 ud».
     Se quita la celda entera, no solo el punto. */
  #page-inventario .mov-tabla tbody tr.inv-fila-dentro td.inv-c-cat { display: none; }
  /* Y las filas de dentro no llevan `nowrap` aquí: en 390 px, el nombre tiene
     que poder partirse. */
  #page-inventario .mov-tabla tbody tr.inv-fila-dentro > td { white-space: normal; }
}

/* ── Firma de correo (Ajustes) ───────────────────────────────────────────────
   Los campos a la izquierda y la firma a la derecha, para ver el efecto de cada
   tecla. El lienzo va BLANCO siempre, aunque Bulx esté en oscuro: el correo
   se lee sobre blanco, y enseñarla sobre gris sería enseñar algo que nadie va a
   ver. */
.frm-rejilla { display: grid; grid-template-columns: minmax(220px, 300px) 1fr; gap: 20px; align-items: start; }
.frm-campos { display: flex; flex-direction: column; gap: 11px; }
.frm-campo { display: flex; flex-direction: column; gap: 4px; }
.frm-campo > span { font-size: 12px; font-weight: 700; color: var(--text-soft); }
.frm-campo input {
  height: 38px; padding: 0 11px; font-size: 14px; font-family: inherit; color: var(--text);
  background: var(--surface); border: 1px solid var(--border-med);
}
.frm-campo input:focus { outline: 2px solid var(--accent); outline-offset: -1px; }
.frm-campo input:disabled { background: var(--surface-2); color: var(--text-soft); }

.frm-vista-caja { border: 1px solid var(--border); background: var(--surface); }
.frm-vista-cab {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 9px 12px; border-bottom: 1px solid var(--border);
  font-size: 11.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--text-soft);
}
.frm-lienzo { background: #ffffff; padding: 22px 18px; overflow-x: auto; }

.frm-logo { margin-top: 18px; max-width: 520px; }
.frm-aviso { margin-top: 7px; max-width: 66ch; }
.frm-codigo { margin-top: 16px; }
.frm-codigo summary { cursor: pointer; font-size: 13px; font-weight: 600; color: var(--text-soft); }
.frm-codigo textarea {
  width: 100%; min-height: 170px; margin-top: 9px; padding: 11px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 11.5px;
  line-height: 1.55; background: var(--surface-2); color: var(--text);
  border: 1px solid var(--border-med);
}

@media (max-width: 860px) { .frm-rejilla { grid-template-columns: 1fr; } }

/* ── Material del rodaje, ofrecido al presupuesto ────────────────────────── */
.pres-del-proyecto {
  margin-bottom: 14px; padding: 13px 15px;
  background: var(--surface-2); border: 1px solid var(--border); border-left: 3px solid var(--accent);
}
.ppm-tit { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; font-size: 13.5px; color: var(--text-2); }
.ppm-tit b { font-size: 16px; color: var(--text); }
.ppm-total { margin-left: auto; font-weight: 700; font-variant-numeric: tabular-nums; }
.ppm-lista { display: flex; flex-wrap: wrap; gap: 5px; margin: 9px 0 11px; }
.ppm-chip {
  display: inline-flex; align-items: baseline; gap: 5px;
  padding: 2px 8px; background: var(--surface); border: 1px solid var(--border);
  font-size: 12px;
}
.ppm-chip small { color: var(--text-soft); font-variant-numeric: tabular-nums; }
.ppm-chip.mas { color: var(--text-soft); border-style: dashed; }
.ppm-aviso { margin: 0 0 10px; font-size: 12.5px; color: var(--orange-dark); }

/* El ofrecimiento de convertir una categoría en kit. Va en la ruta, al final,
   porque es donde ya estás mirando lo que tiene dentro — y en hueco, porque no
   es lo que has venido a hacer. */
.crumb-kit {
  margin-left: auto; padding: 3px 10px; font-size: 12px; font-weight: 600;
  font-family: inherit; cursor: pointer;
  color: var(--accent); background: none; border: 1px dashed var(--accent);
}
.crumb-kit:hover { background: var(--accent); color: #fff; border-style: solid; }

/* ── El color del proyecto, editable desde la ficha (17/9/2026) ──────────────
   Vive en la cabecera, al lado de Guardar, y solo aparece en modo edición. El
   cuadrado es el propio <input type="color">: darle un aspecto de muestra en
   vez de esconderlo detrás de un botón evita tener que explicar qué hace. */
.pf-color-lbl {
  display: inline-flex; align-items: center; gap: 7px;
  height: 34px; padding: 0 10px 0 7px;
  background: var(--surface); border: 1px solid var(--border);
  font: 600 12.5px/1 var(--font); color: var(--text-2);
  cursor: pointer; user-select: none;
}
.pf-color-lbl:hover { border-color: var(--border-strong); color: var(--text); }
.pf-color {
  width: 22px; height: 22px; flex: 0 0 auto;
  padding: 0; border: 1px solid var(--border-strong); background: none; cursor: pointer;
}
.pf-color::-webkit-color-swatch-wrapper { padding: 0; }
.pf-color::-webkit-color-swatch { border: none; }

/* Las notas, en la ficha del dispositivo: un campo de varias líneas dentro de
   la misma rejilla de datos, para que editar sea un solo sitio. */
.pf-input-area { min-height: 62px; resize: vertical; line-height: 1.45; }
select.pf-input { height: 30px; padding: 0 6px; }

/* ── IT Stock: la línea entera dice el estado (17/9/2026) ─────────────────────
   «Creo que tenemos que conseguir un poco más de visión en la lista.» La chapa
   del estado estaba bien, pero para saber cuántos equipos hay libres había que
   leer setenta y nueve chapas de derecha a izquierda. Con la fila teñida se ve
   de un vistazo y sin leer nada.

   El tinte va en el `td` y no en el `tr` porque las celdas pintan su propio
   fondo y taparían el de la fila. Y al pasar por encima sube un poco, que si no
   la fila teñida se comía el resalte del ratón y no se sabía en cuál estabas.

   Qué dice cada color (y por qué el rojo NO es «en uso»): un equipo en uso es
   lo normal —sesenta de setenta y nueve—, así que teñirlos dejaba la lista roja
   entera y el color no distinguía nada. El rojo se guarda para lo que de verdad
   hay que mirar dos veces: lo descatalogado. Verde lo que puedes coger hoy,
   blanco lo que está trabajando, ámbar lo que está en el taller. */
.ux-tabla tr.it-fila.banda-ok      { --fila-tinte: var(--pres-ok); }
.ux-tabla tr.it-fila.banda-aviso   { --fila-tinte: var(--mo-aviso); }
.ux-tabla tr.it-fila.banda-apagado { --fila-tinte: var(--accent); }

.ux-tabla tr.it-fila.banda-ok td,
.ux-tabla tr.it-fila.banda-aviso td,
.ux-tabla tr.it-fila.banda-apagado td {
  background: color-mix(in srgb, var(--fila-tinte) 20%, transparent);
}
.ux-tabla tr.it-fila.banda-ok:hover td,
.ux-tabla tr.it-fila.banda-aviso:hover td,
.ux-tabla tr.it-fila.banda-apagado:hover td {
  background: color-mix(in srgb, var(--fila-tinte) 32%, transparent);
}
/* Lo descatalogado sí se lee: atenuado al 60% sobre un fondo rojo claro, la
   matrícula y el nombre se perdían justo en la fila que más se mira. */
.ux-tabla tr.it-fila.banda-apagado.ux-fila-apagada td { opacity: .85; }

/* ── La pegatina del vehículo y sus partes (17/9/2026) ───────────────────────
   Va dentro de la ficha, con los mismos bloques que el resto de Información
   (`.vf-bloque`), para que no parezca una pantalla aparte pegada con cinta. */
.vf-ayuda { font-size: 13px; color: var(--text-soft); line-height: 1.5; margin: 2px 0 12px; max-width: 62ch; }

.vqr-alerta { border-left: 3px solid var(--accent); padding-left: 14px; }
.vqr-partes { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-direction: column; gap: 1px; background: var(--border); border: 1px solid var(--border); }
.vqr-parte { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding: 11px 13px; background: var(--surface); border-left: 3px solid var(--border-strong); }
.vqr-parte.vqr-serio  { border-left-color: var(--mo-aviso); }
.vqr-parte.vqr-parado { border-left-color: var(--accent); }
.vqr-parte-txt { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.vqr-parte-txt b { font-size: 14.5px; }
.vqr-parte-txt small { font-size: 12.5px; color: var(--text-soft); }
.vqr-parte-nota { font-size: 13px; color: var(--text-2); }

.vqr-caja { display: flex; align-items: flex-start; gap: 16px; flex-wrap: wrap; }
.vqr-img { flex: 0 0 auto; border: 1px solid var(--border); background: #fff; padding: 6px; }
.vqr-sinqr { width: 150px; height: 150px; display: grid; place-items: center; color: var(--text-soft); font-size: 13px; }
.vqr-caja-der { flex: 1 1 260px; min-width: 0; display: flex; flex-direction: column; gap: 10px; }
.vqr-enlace { font-size: 12.5px; color: var(--text-2); word-break: break-all; }
.vqr-ops { display: flex; flex-wrap: wrap; gap: 6px; }

.vqr-hist summary { font-size: 13.5px; font-weight: 700; color: var(--text-2); cursor: pointer; }
.vqr-n { display: inline-block; margin-left: 6px; padding: 1px 6px; font-size: 11.5px; background: var(--surface-2); border: 1px solid var(--border); color: var(--text-soft); }
.vqr-hist-lista { list-style: none; margin: 10px 0 0; padding: 0; }
.vqr-hist-fila { display: grid; grid-template-columns: 82px minmax(0, 1fr) 140px 88px; gap: 10px; padding: 7px 0; border-bottom: 1px solid var(--border); font-size: 13px; }
.vqr-hist-fila.es-parte .vqr-hist-que { color: var(--accent); font-weight: 600; }
.vqr-hist-fila em { color: var(--text-soft); font-style: normal; font-weight: 400; }
.vqr-hist-dia, .vqr-hist-km { color: var(--text-soft); font-variant-numeric: tabular-nums; }
.vqr-hist-quien { color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 720px) {
  .vqr-hist-fila { grid-template-columns: 72px minmax(0, 1fr); }
  .vqr-hist-quien, .vqr-hist-km { grid-column: 2; font-size: 12.5px; }
}

/* ── Ajustes: la hora de la casa (17/9/2026) ────────────────────────────────
   El desplegable no estaba peinado: solo `input` lo estaba, y un `select` al
   lado se veía como de otra aplicación. Y `.aj-ahora` enseña la hora que tiene
   el servidor AHORA, que es lo único que demuestra que la zona está bien. */
.aj-campo select {
  width: 100%; padding: 7px 10px; border-radius: 0;
  border: 1px solid var(--border-med); background: var(--surface);
  color: var(--text); font-size: 13.5px; font-family: inherit;
}
.aj-campo select:focus { outline: none; border-color: var(--accent); }
.aj-ahora {
  padding: 7px 10px; border: 1px solid var(--border);
  background: var(--surface-2); color: var(--text);
  font-size: 13.5px; font-variant-numeric: tabular-nums;
}
.aj-nota-ojo { color: var(--text-2); }

/* ── Presupuestar la flota del rodaje de un tirón (17/9/2026) ────────────── */
.np-flota {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  margin: 10px 0 0; padding: 11px 13px;
  background: var(--surface-2); border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
}
.np-flota-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.np-flota-txt b { font-size: 13.5px; }
.np-flota-txt span { font-size: 12.5px; color: var(--text-soft); }
.np-flota-txt em { font-size: 12px; font-style: normal; color: var(--accent); }
.np-flota-ok { font-size: 12.5px; color: var(--text-soft); white-space: nowrap; }

/* ── IN-HOUSE EN RODAJE (19/9/2026, prefijo .ih-) ────────────────────────────
   Misma gramática que el resto: bloques `.pf-sec`, cero redondeo, cifras
   grandes con su rótulo debajo. Lo único propio son las tres cifras de la
   comparativa, que son el motivo de la pantalla. */
.ih-tabs { display: flex; gap: 2px; margin-bottom: 14px; border-bottom: 1px solid var(--border); }
.ih-tab {
  padding: 9px 15px; border: 0; background: none; cursor: pointer;
  font: 600 13.5px/1 var(--font); color: var(--text-soft);
  border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.ih-tab:hover { color: var(--text); }
.ih-tab.activa { color: var(--text); border-bottom-color: var(--accent); }

.ih-form, .ih-filtros {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 14px; align-items: end;
}
.ih-form .ih-ancho { grid-column: 1 / -1; }
.ih-form-pie { grid-column: 1 / -1; display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-top: 2px; }
.ih-quien { font-size: 12.5px; color: var(--text-soft); }
.ih-rapidos { display: flex; gap: 6px; align-items: end; }
.aj-campo em { font-style: normal; font-weight: 400; color: var(--text-xsoft); }
.ih-nota { font-size: 12px; color: var(--text-soft); margin-top: 2px; }

/* Las tres cifras. La del medio es la que contesta la pregunta del jefe, así
   que es la única con color: lo demás es contexto para entenderla. */
.ih-cifras {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 1px; background: var(--border); border: 1px solid var(--border); margin-bottom: 14px;
}
.ih-cifra { background: var(--surface); padding: 16px 18px; display: flex; flex-direction: column; gap: 4px; }
.ih-cifra-buena { border-top: 3px solid var(--accent); }
.ih-cifra-n { font: 700 26px/1 var(--font-display); letter-spacing: -.025em; font-variant-numeric: tabular-nums; }
.ih-cifra-l { font: 700 10px/1 var(--font); letter-spacing: .09em; text-transform: uppercase; color: var(--text-soft); }
.ih-cifra-s { font-size: 12px; color: var(--text-xsoft); }

.ih-tabla th:not(:first-child), .ih-tabla td:not(:first-child) { text-align: right; }
.ih-tabla td { font-variant-numeric: tabular-nums; }
.ih-eur { font-weight: 600; }
.ih-fl { color: var(--text-soft); }
.ih-aviso { margin: 0 0 14px; padding: 10px 13px; font-size: 13px;
  background: var(--surface-2); border-left: 3px solid var(--accent); }

.ih-inp {
  width: 100%; padding: 6px 9px; border: 1px solid var(--border-med);
  background: var(--surface); color: var(--text); font: 13.5px var(--font); border-radius: 0;
}
.ih-inp:focus { outline: none; border-color: var(--accent); }
.ih-num { text-align: right; font-variant-numeric: tabular-nums; }
.ih-todas { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; font-weight: 500; }
.ih-todas input { margin: 0; }

/* ── MIS HORAS (19/9/2026, prefijo .ihh-) ────────────────────────────────────
   Esta pantalla se abre con el móvil, de noche y con prisa, al acabar el día
   de rodaje. Así que todo va a dedo: campos altos, tres botones para la comida
   en vez de un campo de minutos, y un botón de guardar que ocupa el ancho. */
.ihh-form { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 14px; }
.ihh-form .ihh-rodaje, .ihh-form .ihh-ancho, .ihh-form .ihh-comida, .ihh-form .ihh-pie { grid-column: 1 / -1; }
.ihh-form .aj-campo input, .ihh-form .aj-campo select { height: 44px; font-size: 15px; }
.ihh-hora { font-variant-numeric: tabular-nums; font-weight: 600; }
.ihh-botones { display: flex; gap: 8px; flex-wrap: wrap; }
.ihh-op {
  flex: 1 1 110px; min-height: 44px; padding: 0 12px;
  border: 1px solid var(--border-med); background: var(--surface); color: var(--text-2);
  font: 600 13.5px/1.2 var(--font); cursor: pointer; border-radius: 0;
}
.ihh-op.activa { border-color: var(--text); background: var(--text); color: var(--bg); }
.ihh-pie .btn-grande { width: 100%; height: 48px; font-size: 15.5px; }

.ihh-recien {
  margin-bottom: 14px; padding: 12px 14px; font-size: 14px;
  background: var(--surface-2); border-left: 3px solid var(--accent);
}

.ihh-dias { display: flex; flex-direction: column; gap: 1px; background: var(--border); border: 1px solid var(--border); }
.ihh-dia { background: var(--surface); padding: 12px 14px; border-left: 3px solid transparent; }
.ihh-dia.mal { border-left-color: var(--accent); }
.ihh-dia-cab { display: flex; align-items: baseline; gap: 9px; }
.ihh-dia-cab b { font-size: 14.5px; font-variant-numeric: tabular-nums; }
.ihh-dia-cab span { flex: 1; min-width: 0; font-size: 13px; color: var(--text-soft);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ihh-x { border: 0; background: none; color: var(--text-xsoft); font-size: 19px; line-height: 1;
  cursor: pointer; padding: 0 2px; }
.ihh-x:hover { color: var(--accent); }
.ihh-dia-horas { margin-top: 3px; font-size: 13.5px; color: var(--text-2); font-variant-numeric: tabular-nums; }
.ihh-dia-horas i { font-style: normal; color: var(--text-soft); }
.ihh-dia-chips { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 7px; }
.ihh-chip {
  padding: 2px 7px; font: 600 11.5px/1.5 var(--font);
  background: var(--surface-2); border: 1px solid var(--border); color: var(--text-2);
}
.ihh-chip.buena { border-color: var(--border-strong); color: var(--text); }
.ihh-chip.mala { border-color: var(--accent); color: var(--accent); }
.ihh-chip.ok { color: var(--text-soft); }
.ihh-dia-nota { margin-top: 6px; font-size: 12.5px; color: var(--text-soft); }

.ih-cifra-mal { border-top: 3px solid var(--accent); }
.ih-cifra-n small { font-size: 14px; font-weight: 600; color: var(--text-soft); }

@media (max-width: 720px) {
  .ihh-form { grid-template-columns: 1fr 1fr; }
  .ih-cifras { grid-template-columns: 1fr 1fr; }
  .ih-tabs { overflow-x: auto; }
}

/* ── Tarifas: todos los precios (19/9/2026, prefijo .pr-) ─────────────────── */
.pr-tabla td:first-child { width: 60%; }
.pr-sub { font-size: 12px; color: var(--text-soft); margin-top: 2px; }
.pr-buscar { display: flex; gap: 8px; margin-bottom: 10px; }
.pr-buscar input {
  flex: 1; min-width: 0; padding: 7px 10px; border: 1px solid var(--border-med);
  background: var(--surface); color: var(--text); font: 13.5px var(--font); border-radius: 0;
}
.pr-buscar input:focus { outline: none; border-color: var(--accent); }

/* ── «¿Quién eres?» (19/9/2026) ──────────────────────────────────────────── */
.ihq-probables { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px; }
.ihq-lista { display: flex; flex-direction: column; gap: 1px; background: var(--border); border: 1px solid var(--border); max-height: 420px; overflow-y: auto; }
.ihq-ficha {
  display: flex; flex-direction: column; gap: 2px; align-items: flex-start;
  width: 100%; padding: 11px 14px; text-align: left; cursor: pointer;
  background: var(--surface); border: 0; border-left: 3px solid transparent; font: inherit;
}
.ihq-ficha:hover { border-left-color: var(--accent); background: var(--bg-hover); }
.ihq-ficha b { font-size: 14.5px; color: var(--text); }
.ihq-ficha span { font-size: 12.5px; color: var(--text-soft); }
.ihq-probables .ihq-ficha { border: 1px solid var(--border-strong); border-left: 3px solid var(--accent); }
/* Las dos mitades de la tabla de cargos: lo que cobra el empleado y lo que se
   usa para el informe. Una línea las separa, que si no son siete columnas de
   números iguales. */
.ih-tabla th.ih-grupo, .ih-tabla td.ih-grupo { border-left: 1px solid var(--border-strong); }
.ih-tabla th small { display: block; font-weight: 500; color: var(--text-soft); }
.ih-tabla th em { font-style: normal; font-weight: 400; color: var(--text-xsoft); }
.ih-lista-ayuda { margin: 6px 0 12px 18px; font-size: 13px; color: var(--text-soft); line-height: 1.55; }
.ih-lista-ayuda li + li { margin-top: 5px; }

/* ── Lo que ganas en cada rodaje (19/9/2026, prefijo .ihg-) ──────────────────
   Una tarjeta por rodaje con el importe grande a la derecha. La pregunta que
   contesta es «¿cuánto me llevo por este rodaje?», así que esa cifra manda y
   todo lo demás explica de dónde sale. */
.ihg-tit {
  margin: 18px 0 10px; font: 700 11px/1 var(--font);
  letter-spacing: .11em; text-transform: uppercase; color: var(--text-soft);
}
.ihg-tit small { font-weight: 400; letter-spacing: .04em; text-transform: none; color: var(--text-xsoft); }
.ihg-rodajes { display: flex; flex-direction: column; gap: 12px; }
.ihg-rodaje { background: var(--surface); border: 1px solid var(--border); border-left: 3px solid var(--accent); }
.ihg-cab {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 15px 17px; border-bottom: 1px solid var(--border);
}
.ihg-nom { min-width: 0; }
.ihg-nom b { display: block; font: 700 18px/1.2 var(--font-display); letter-spacing: -.02em; }
.ihg-nom span { font-size: 12.5px; color: var(--text-soft); }
.ihg-eur { text-align: right; flex: 0 0 auto; }
.ihg-eur b { display: block; font: 700 24px/1 var(--font-display); letter-spacing: -.025em; font-variant-numeric: tabular-nums; }
.ihg-eur span { font: 600 10px/1 var(--font); letter-spacing: .09em; text-transform: uppercase; color: var(--text-soft); }

.ihg-trozos { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 1px; background: var(--border); }
.ihg-trozo { background: var(--surface); padding: 11px 14px; display: flex; flex-direction: column; gap: 2px; }
.ihg-trozo b { font-size: 16px; font-variant-numeric: tabular-nums; }
.ihg-trozo span { font: 600 10px/1.2 var(--font); letter-spacing: .07em; text-transform: uppercase; color: var(--text-soft); }
.ihg-trozo i { font-style: normal; font-size: 13px; font-weight: 600; color: var(--text-2); }
.ihg-trozo.mal b, .ihg-trozo.mal i { color: var(--accent); }

.ihg-limpio { padding: 12px 17px; font-size: 13px; color: var(--text-soft); }
.ihg-dias { border-top: 1px solid var(--border); }
.ihg-dias summary { padding: 11px 17px; font-size: 13px; font-weight: 600; color: var(--text-soft); cursor: pointer; }
.ihg-dias summary:hover { color: var(--text); }
.ihg-dias .ihh-dias { border: 0; border-top: 1px solid var(--border); }

.ihg-todo {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  margin-top: 12px; padding: 14px 17px; background: var(--surface-2); border: 1px solid var(--border);
}
.ihg-todo span { font-size: 13.5px; color: var(--text-2); }
.ihg-todo b { font: 700 20px/1 var(--font-display); font-variant-numeric: tabular-nums; }

/* ── Mis días: el recuento (19/9/2026, prefijo .ihd-) ────────────────────── */
.ihd-grupos { display: flex; flex-direction: column; gap: 10px; }
.ihd-grupo { background: var(--surface); border: 1px solid var(--border); }
.ihd-cab {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 12px 15px; border-bottom: 1px solid var(--border);
}
.ihd-cab b { font: 700 16px/1.2 var(--font-display); letter-spacing: -.02em; }
.ihd-dias { font: 700 20px/1 var(--font-display); font-variant-numeric: tabular-nums; }
.ihd-dias small { font: 600 10px/1 var(--font); letter-spacing: .08em; text-transform: uppercase; color: var(--text-soft); margin-left: 5px; }
.ihd-filas { display: flex; flex-direction: column; }
.ihd-fila {
  display: grid; grid-template-columns: minmax(0, 1fr) auto 46px 24px; gap: 10px;
  align-items: center; padding: 8px 15px; font-size: 13px; border-top: 1px solid var(--border);
}
.ihd-fila:first-child { border-top: 0; }
.ihd-que { color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ihd-cuando { color: var(--text-soft); font-variant-numeric: tabular-nums; }
.ihd-n { text-align: right; font-weight: 600; font-variant-numeric: tabular-nums; }

/* ── Tu cargo (19/9/2026, prefijo .ihc-) ─────────────────────────────────── */
.ihc {
  margin-bottom: 14px; padding: 12px 15px;
  background: var(--surface); border: 1px solid var(--border); border-left: 3px solid var(--text);
  display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap;
}
.ihc.sin { border-left-color: var(--accent); }
.ihc-txt b { font-size: 14.5px; }
.ihc-txt span { display: block; font-size: 12.5px; color: var(--text-soft); }
.ihc-estado { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.ihc-ok { font: 600 11px/1 var(--font); letter-spacing: .08em; text-transform: uppercase; color: var(--text-soft); }
.ihc-mal { font-size: 12.5px; color: var(--accent); }
.ihc-picker { flex: 1 1 100%; border-top: 1px solid var(--border); padding-top: 12px; margin-top: 2px; }
.ihc-picker p { font-size: 12.5px; color: var(--text-soft); margin-bottom: 9px; }
.ihc-ops { display: flex; flex-wrap: wrap; gap: 7px; }
.ihc-op {
  padding: 8px 12px; text-align: left; cursor: pointer; font: inherit;
  background: var(--bg); border: 1px solid var(--border-med); color: var(--text);
}
.ihc-op:hover { border-color: var(--text); }
.ihc-op.activa { background: var(--text); color: var(--bg); border-color: var(--text); }
.ihc-op b { display: block; font-size: 13.5px; }
.ihc-op span { font-size: 11.5px; color: var(--text-soft); }
.ihc-op.activa span { color: var(--bg); opacity: .7; }
.ihc-vacio { font-size: 12.5px; color: var(--text-soft); }

/* El importe del día, a la derecha de su cabecera. */
.ihh-dia-cab { display: flex; align-items: baseline; gap: 9px; }
.ihh-dia-eur {
  margin-left: auto; font-style: normal; font-variant-numeric: tabular-nums;
  font: 700 15px/1 var(--font-display);
}
.ihg-todo em { display: block; font-style: normal; font-size: 12px; color: var(--text-soft); margin-top: 3px; }

/* ── Quién soy en la plantilla, en Mi Perfil (21/9/2026) ─────────────────── */
.mpf-ayuda { font-size: 12.5px; color: var(--text-soft); margin: 0 0 12px; line-height: 1.5; }
.mpf-actual { padding: 11px 13px; background: var(--surface-2); border-left: 3px solid var(--text); margin-bottom: 12px; }
.mpf-actual.sin { border-left-color: var(--accent); }
.mpf-actual b { display: block; font-size: 14.5px; }
.mpf-actual span { font-size: 12.5px; color: var(--text-soft); }
.mpf-picker { margin-top: 12px; }
.mpf-picker input {
  width: 100%; padding: 8px 11px; margin-bottom: 9px; border-radius: 0;
  border: 1px solid var(--border-med); background: var(--surface); color: var(--text); font: 13.5px var(--font);
}
.mpf-picker input:focus { outline: none; border-color: var(--accent); }
.ih-sub { margin: 18px 0 2px; font: 700 13px/1.3 var(--font-display); letter-spacing: -.01em; }
.ihh-ojo { border-left: 3px solid var(--border-strong); padding-left: 11px; }

/* ── Llevártelo: partes y Excel (21/9/2026, prefijo .ihx-) ──────────────── */
.ihx { margin-top: 12px; border: 1px solid var(--border); background: var(--surface); }
.ihx-tit {
  padding: 10px 15px; border-bottom: 1px solid var(--border);
  font: 700 10.5px/1 var(--font); letter-spacing: .11em; text-transform: uppercase; color: var(--text-soft);
}
.ihx-fila {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap;
  padding: 11px 15px; border-top: 1px solid var(--border); font-size: 13.5px;
}
.ihx-fila:first-of-type { border-top: 0; }
.ihx-todo { background: var(--surface-2); }
.ihx-bots { display: flex; gap: 6px; flex-wrap: wrap; }

/* ── LOS CUATRO PAPELES DEL COCHE ─────────────────────────────────────────────
   Permiso, ficha técnica, ITV y seguro, cada uno en su hueco y salgan o no.
   Los mismos cuatro que la app enseña en la ficha de un vehículo: lo que sube
   uno lo ve el otro al momento.

   El que falta se marca con el color del aviso, no con el del error: que no
   esté escaneado no es un fallo del sistema, es trabajo pendiente. */
.veh-papeles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 8px;
  margin-bottom: 4px;
}
.veh-papel {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}
.veh-papel.falta {
  border-color: color-mix(in srgb, var(--orange-dark) 40%, var(--border));
  background: color-mix(in srgb, var(--orange-dark) 6%, var(--surface));
}
.veh-papel-ico { display: flex; color: var(--text-2); flex: 0 0 auto; }
.veh-papel.falta .veh-papel-ico { color: var(--orange-dark); }
.veh-papel-txt { min-width: 0; flex: 1 1 auto; }
.veh-papel-tit { font-size: 13px; font-weight: 600; }
.veh-papel-sub { font-size: 12px; color: var(--text-soft); }
.veh-papel.falta .veh-papel-sub { color: var(--orange-dark); }
.veh-papel-acc { display: flex; gap: 6px; flex: 0 0 auto; }

.veh-papeles-aviso,
.veh-papeles-ok {
  grid-column: 1 / -1;
  margin: 4px 0 0;
  font-size: 12px;
  color: var(--text-soft);
}
.veh-papeles-aviso strong { color: var(--orange-dark); }

/* ═══════════════════════════════════════════════════════════════════════════
   LICENCIAS Y SOFTWARE                                        (prefijo `lic-`)
   La pregunta de cada día es «¿queda alguna plaza?», así que las plazas llevan
   barra: un 8/10 se lee, pero un 8/10 con la barra casi llena se ve sin leer.
   ═══════════════════════════════════════════════════════════════════════════ */
.lic-chips { display: flex; gap: 6px; flex-wrap: wrap; margin: 0 0 14px; }
.lic-sub   { font-size: 11.5px; color: var(--text-soft); margin-top: 2px; }
.lic-quien { color: var(--text-2); font-size: 12.5px; }
.lic-nota  { margin-top: 18px; font-size: 12px; color: var(--text-xsoft); max-width: 70ch; }
.lic-mal    { color: var(--red); font-weight: 650; }
.lic-pronto { color: var(--orange); font-weight: 600; }

/* La barra de plazas. Lleno = naranja; sobrepasado = rojo, que es un problema
   de licencia y no un redondeo. */
.lic-plazas { display: inline-flex; flex-direction: column; align-items: flex-end; gap: 3px; min-width: 66px; }
.lic-plazas span { font-variant-numeric: tabular-nums; font-weight: 600; font-size: 12.5px; }
.lic-plazas i {
  display: block; height: 3px; background: var(--text-2); border-radius: 0;
  min-width: 2px; max-width: 100%;
}
.lic-plazas { position: relative; }
.lic-plazas::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0;
  height: 3px; background: var(--border); z-index: -1;
}
.lic-plazas.lleno i { background: var(--orange); }
.lic-plazas.mal span { color: var(--red); }
.lic-plazas.mal i    { background: var(--red); }

/* Los avisos de renovación, arriba y pulsables: llevan a su ficha. */
.lic-avisos { display: flex; gap: 8px; flex-wrap: wrap; margin: 0 0 16px; }
.lic-aviso {
  display: inline-flex; align-items: baseline; gap: 8px;
  padding: 7px 12px; border: 1px solid var(--border-med); background: var(--surface);
  font: inherit; font-size: 12.5px; cursor: pointer; text-align: left;
  border-left: 3px solid var(--orange);
}
.lic-aviso:hover { background: var(--bg-hover); }
.lic-aviso span  { color: var(--text-soft); font-size: 11.5px; }
.lic-aviso.mal   { border-left-color: var(--red); }
.lic-aviso.mal span { color: var(--red); }

/* ── La hoja lateral ──────────────────────────────────────────────────────── */
.lic-hoja {
  position: fixed; top: 0; right: 0; bottom: 0; width: min(460px, 92vw);
  z-index: 60; display: flex; flex-direction: column;
  background: var(--surface); border-left: 1px solid var(--border-med);
  box-shadow: -8px 0 32px rgba(0,0,0,.14);
}
.lic-hoja-cab {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 18px 20px 14px; border-bottom: 1px solid var(--border-med);
}
.lic-hoja-cab h2 { margin: 0; font-size: 18px; }
.lic-hoja-cab p  { margin: 4px 0 0; font-size: 12px; color: var(--text-soft); }
.lic-hoja-cab .modal-close { margin-left: auto; }
.lic-hoja-cuerpo { flex: 1; overflow-y: auto; padding: 16px 20px; }
.lic-hoja-pie {
  display: flex; gap: 8px; padding: 12px 20px;
  border-top: 1px solid var(--border-med); background: var(--surface-2);
}
.lic-hoja-pie .btn-ghost { margin-left: auto; }
body.lic-hoja-abierta { overflow: hidden; }

.lic-banda {
  padding: 9px 12px; margin-bottom: 14px; font-size: 12.5px;
  background: rgba(255,159,10,.10); border-left: 3px solid var(--orange); color: var(--text);
}
.lic-banda.mal { background: rgba(239,35,60,.08); border-left-color: var(--red); }

.lic-sec { margin-bottom: 22px; }
.lic-sec h3 {
  margin: 0 0 10px; font-size: 11px; font-weight: 750; letter-spacing: .09em;
  text-transform: uppercase; color: var(--text-soft);
  display: flex; align-items: baseline; gap: 8px;
}
.lic-sec-n { font-weight: 600; letter-spacing: 0; color: var(--text-xsoft); text-transform: none; }
.lic-vacio { margin: 0 0 10px; font-size: 12.5px; color: var(--text-xsoft); }

.lic-plazas-lista { list-style: none; margin: 0 0 10px; padding: 0; }
.lic-plazas-lista li {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  padding: 7px 0; border-bottom: 1px solid var(--border);
}
.lic-plazas-lista li:last-child { border-bottom: none; }
.lic-plaza-quien { font-weight: 600; font-size: 13px; }
.lic-plaza-maq   { font-size: 11.5px; color: var(--text-2); }
.lic-plaza-desde { font-size: 11.5px; color: var(--text-xsoft); margin-left: auto; }
.lic-plazas-lista.pasadas .lic-plaza-quien { font-weight: 500; color: var(--text-soft); }

.lic-datos { margin: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 10px 16px; }
.lic-dato dt { font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--text-xsoft); }
.lic-dato dd { margin: 2px 0 0; font-size: 13px; word-break: break-word; }
.lic-clave {
  display: flex; align-items: center; gap: 8px; margin-top: 12px;
  padding: 8px 10px; background: var(--surface-2); border: 1px solid var(--border);
}
.lic-clave span { font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--text-xsoft); }
.lic-clave code { flex: 1; font-size: 12.5px; word-break: break-all; }
.lic-notas { margin: 12px 0 0; font-size: 12.5px; color: var(--text-2); line-height: 1.55; }

@media (max-width: 640px) {
  .lic-datos { grid-template-columns: 1fr; }
}

/* La cabecera del widget de licencias del panel de IT: las dos cifras que se
   miran antes que la lista. */
.td-lic-cab {
  display: flex; gap: 18px; flex-wrap: wrap;
  padding: 0 0 10px; margin-bottom: 6px;
  border-bottom: 1px solid var(--border);
  font-size: 12px; color: var(--text-soft);
}
.td-lic-cab b { font-size: 15px; color: var(--text); font-variant-numeric: tabular-nums; }

/* ═══════════════════════════════════════════════════════════════════════════
   QUIÉN ESTÁ TRABAJANDO AHORA                                (prefijo `pre-`)
   Las iniciales, como en un documento compartido. El color lo pone el guion y
   es estable por persona: la misma inicial siempre del mismo tono.
   ═══════════════════════════════════════════════════════════════════════════ */
.presencia { display: none; align-items: center; gap: 4px; margin-left: auto; padding: 0 10px; flex: 0 0 auto; }
.presencia.hay { display: flex; }
.pre-yo {
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; flex: 0 0 auto;
  background: var(--pre-c, var(--text-soft)); color: #fff;
  font: 700 10px/1 var(--font); letter-spacing: .02em;
  cursor: default; user-select: none;
}
/* Cuadradas y sin solaparse. El montoncito de círculos pisados es de otras
   casas; aquí las fichas van en fila, como las casillas de un parte. */
.pre-yo + .pre-yo { margin-left: 3px; }
.pre-yo.pre-mas { background: var(--text-soft); font-size: 9.5px; }

/* La franja de dentro del documento. Ámbar y no roja: no es un error, es un
   aviso de que hay alguien más en la misma mesa. */
.pre-aqui {
  display: flex; align-items: center; gap: 10px;
  margin: 0 0 14px; padding: 9px 13px;
  background: rgba(255,159,10,.10); border-left: 3px solid var(--orange);
  font-size: 12.5px; color: var(--text); line-height: 1.45;
}
.pre-aqui-quien { display: inline-flex; flex: 0 0 auto; }

@media (max-width: 860px) {
  .presencia { padding: 0 6px; }
  .pre-yo { width: 21px; height: 21px; font-size: 9px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   EL AVISO DEL GUARDADO SOLO                             (junto a «Guardar»)
   Se guarda sin que nadie pulse nada, así que tiene que poder verse. Callado
   cuando todo va bien —es lo normal— y en rojo solo cuando ha dejado de
   guardar, que es lo único que pide hacer algo.
   ═══════════════════════════════════════════════════════════════════════════ */
.autoguardado {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 0 10px 0 2px; margin-right: 2px;
  font: 500 10.5px/1 var(--font-mono, var(--font));
  letter-spacing: .06em; text-transform: uppercase;
  color: var(--text-soft); white-space: nowrap;
  transition: color .18s ease;
}
.autoguardado:empty { display: none; }
.autoguardado::before {
  content: ''; width: 5px; height: 5px; flex: 0 0 auto;
  background: currentColor;
}
.autoguardado.as-guardando { color: var(--text-soft); }
.autoguardado.as-cambios   { color: var(--orange); }
.autoguardado.as-parado    { color: var(--red, #e01230); cursor: help; }

@media (max-width: 980px) { .autoguardado { display: none; } }

/* ═══════════════════════════════════════════════════════════════════════════
   LAS CASILLAS DE FABRICANTE, EN LICENCIAS            (prefijo `lic-fab`)
   Un atajo, no un escaparate: cada casilla lleva a sus licencias y deja
   apuntar una nueva. El color de la marca va de filo y de fondo del monograma;
   pintar la casilla entera convertiría la pantalla en un bote de caramelos.
   ═══════════════════════════════════════════════════════════════════════════ */
.lic-fabs-caja { margin: 18px 0 6px; }
.lic-fabs-cab { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; }
.lic-fabs-tit {
  font: 600 10.5px/1 var(--font-mono, var(--font));
  letter-spacing: .18em; text-transform: uppercase; color: var(--text-soft);
}
.lic-fabs-quitar {
  background: none; border: 0; padding: 0; cursor: pointer;
  font: 500 12px/1 var(--font); color: var(--azul, #0071e3);
}
.lic-fabs-quitar:hover { text-decoration: underline; }

.lic-fabs {
  display: grid; gap: 10px;
  grid-template-columns: repeat(auto-fill, minmax(168px, 1fr));
}
.lic-fab {
  display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--border);
  border-top: 2px solid var(--fab-c, var(--border));
  transition: border-color .16s ease, transform .16s ease;
}
.lic-fab:hover { transform: translateY(-2px); border-color: var(--fab-c, var(--border)); }
.lic-fab.activo { border-color: var(--fab-c, var(--text)); box-shadow: inset 0 0 0 1px var(--fab-c, var(--text)); }
.lic-fab.vacio { opacity: .62; }
.lic-fab.vacio:hover { opacity: 1; }

.lic-fab-ir {
  display: flex; flex-direction: column; align-items: flex-start; gap: 3px;
  flex: 1 1 auto; width: 100%; text-align: left; cursor: pointer;
  background: none; border: 0; padding: 12px 13px 11px; color: inherit; font: inherit;
}
.lic-fab-marca {
  display: flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; margin-bottom: 7px; flex: 0 0 auto;
  background: var(--surface-2); overflow: hidden;
}
.lic-fab-marca img { max-width: 100%; max-height: 100%; object-fit: contain; }
.lic-fab-mono {
  display: flex; align-items: center; justify-content: center;
  width: 100%; height: 100%; background: var(--fab-c);
  color: #fff; font: 700 12.5px/1 var(--font); letter-spacing: .02em;
}
.lic-fab-ir b { font-size: 14px; font-weight: 600; line-height: 1.25; }
.lic-fab-dato { font-size: 11.5px; color: var(--text-soft); font-variant-numeric: tabular-nums; }
.lic-fab-aviso { font-size: 11px; color: var(--orange); font-variant-numeric: tabular-nums; }

.lic-fab-pie {
  display: flex; border-top: 1px solid var(--border-soft, var(--border));
}
.lic-fab-pie button {
  flex: 1 1 auto; background: none; border: 0; cursor: pointer;
  padding: 7px 4px; color: var(--text-soft);
  font: 500 11px/1 var(--font); letter-spacing: .02em;
}
.lic-fab-pie button + button { border-left: 1px solid var(--border-soft, var(--border)); flex: 0 0 auto; padding-inline: 11px; }
.lic-fab-pie button:hover { background: var(--surface-2); color: var(--text); }

@media (max-width: 640px) {
  .lic-fabs { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
}

/* ═══════════════════════════════════════════════════════════════════════════
   DIRECCIÓN · IN-HOUSE                                     (prefijo `ihd-`)
   Los filtros mandan: van arriba, siempre visibles, y lo primero que se lee.
   La tabla es de consulta —se compara en vertical—, así que todo lo que sea
   número va en cifras tabulares y alineado a la derecha.
   ═══════════════════════════════════════════════════════════════════════════ */
.ihd-filtros {
  display: flex; flex-wrap: wrap; gap: 14px 26px; align-items: flex-end;
  background: var(--surface); border: 1px solid var(--border);
  padding: 13px 15px; margin-bottom: 16px;
}
.ihd-filtros label {
  display: flex; flex-direction: column; gap: 4px;
  font: 600 10px/1 var(--font-mono, var(--font));
  letter-spacing: .16em; text-transform: uppercase; color: var(--text-soft);
}
.ihd-filtros input, .ihd-filtros select {
  height: 34px; padding: 0 9px; min-width: 150px;
  background: var(--surface-2); color: var(--text);
  border: 1px solid var(--border); font: 400 13px/1 var(--font);
}
.ihd-fechas, .ihd-selects { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end; }
.ihd-atajos { display: flex; gap: 0; align-self: flex-end; }
.ihd-atajos button {
  height: 34px; padding: 0 11px; cursor: pointer;
  background: var(--surface-2); color: var(--text-soft);
  border: 1px solid var(--border); border-left-width: 0;
  font: 500 11.5px/1 var(--font);
}
.ihd-atajos button:first-child { border-left-width: 1px; }
.ihd-atajos button:hover { background: var(--surface); color: var(--text); }

.ihd-tabla .num, .ihd-detalle .num { text-align: right; font-variant-numeric: tabular-nums; }
.ihd-tabla td.mal, .ihd-detalle td.mal { color: var(--orange); }
.ihd-sub { display: block; font-size: 11.5px; color: var(--text-soft); margin-top: 2px; }
.ihd-detalle { margin-top: 14px; }
.ihd-detalle .ihd-fecha { font-variant-numeric: tabular-nums; white-space: nowrap; }

/* El salto a la otra pantalla, dentro de la fila de pestañas: se ve que es un
   viaje y no una pestaña más. */
.ih-tab-ir { margin-left: auto; color: var(--text-soft); }
.ih-tab-ir:hover { color: var(--text); }

@media (max-width: 720px) {
  .ihd-filtros { gap: 12px; }
  .ihd-filtros input, .ihd-filtros select { min-width: 0; width: 100%; }
  .ihd-selects label { flex: 1 1 100%; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   LA ESCALERA DE LOS CALENDARIOS                      (quién tapa a quién)

   Xavi, viendo una barra de rodaje pisando el rótulo «SEM 40»: «tenemos que
   bloquear las columnas y filas que TENGAN sí o sí que mantenerse bloqueadas
   en su posición».

   El fallo no era que faltara `position: sticky` —estaba puesto— sino que los
   números valían lo mismo a los dos lados. Medido en el navegador antes de
   tocar nada:

     · `cal-veh-th-day` (los números del día, cabecera) … sin z-index
     · `cal-veh-td-day` (las casillas con las barras) ……… sin z-index

   EMPATE. Y con el mismo número gana el que va DESPUÉS en el documento, que es
   siempre el cuerpo de la tabla. La barra no «traspasaba» la cabecera: es que
   ganaba la cuenta. Lo mismo arriba a la izquierda, donde la columna de
   vehículos valía 12, igual que la fila de semanas y más que la esquina (11).

   Los escalones se declaran aquí y se USAN en la regla original de cada capa.
   No se repiten al final: una segunda regla pelea por especificidad con la
   primera y, probándolo, unas veces gana y otras no — que es exactamente cómo
   nace este tipo de fallo. Lo de abajo son solo las capas que no tenían regla
   propia donde poner el número.

   Vale para los dos calendarios —flota y producción— porque comparten tabla.
   ═══════════════════════════════════════════════════════════════════════════ */
:root {
  --cal-z-fila-grupo:  20;   /* la banda que separa grupos (se pega arriba) */
  --cal-z-columna:     30;   /* la columna de nombres (se pega a la izquierda) */
  --cal-z-grupo-cab:   35;   /* el rótulo del grupo: se pega por los dos lados */
  --cal-z-cabecera:    40;   /* días, semanas y meses: se pegan arriba */
  --cal-z-esquina:     50;   /* el cruce de los dos ejes: por encima de todo */
}

/* Las casillas del cuerpo no llevan z-index: les basta `position: relative`
   para que las barras se dibujen, y así no compiten con nada. */

/* La cabecera entera. `thead th` no tenía número —ése era el fallo que se
   veía— y la fila `<tr>` se pone también porque Safari y Firefox pegan la
   fila mientras que Chrome solo pega las celdas. */
.cal-veh-table thead th { z-index: var(--cal-z-cabecera, 40); }

/* El rótulo del grupo ya no se pega arriba —se quitó, ver «YA NO BAJAN»— pero
   sí a la izquierda, así que necesita su escalón para no quedar por debajo de
   las barras al desplazar a los lados. Se le devuelve el `sticky` que acaba de
   perder su fila, solo en ese eje. */
.cal-veh-table .cal-grupo-fila > td.cal-grupo-cab {
  position: sticky; left: 0; top: auto;
  z-index: var(--cal-z-grupo-cab, 35);
}

/* La esquina de los meses: su regla general (`.cvb-mes-row th`) la dejaba al
   nivel de la cabecera, y la esquina tiene que estar por encima. */
.cvb-mes-row th.cvb-mes-esq { z-index: var(--cal-z-esquina, 50); }

/* Y el requisito que no es de orden sino de PINTURA: lo que se queda quieto
   tiene que ser OPACO. Con un fondo translúcido el apilado da igual —se ve lo
   de debajo igualmente— y es la mitad de los «se me cuela el texto» que
   parecen de z-index y no lo son.

   La cabecera ya era opaca casi entera y NO se toca: es oscura a propósito.
   Los que no lo eran son los resaltes —hoy, y la semana en curso—, que son un
   tinte pensado para ir ENCIMA de algo. Se les pone su propio papel debajo, en
   vez de aclarar el tinte, para que el resalte siga viéndose igual. */
.cvb-mes-row th.cvb-mes-celda.cvb-ahora {
  background-color: var(--surface-2);
  background-image: linear-gradient(rgba(var(--acento-rgb), .12), rgba(var(--acento-rgb), .12));
}

/* ═══════════════════════════════════════════════════════════════════════════
   FLOTA EN EL DASHBOARD · la barra de ocupación         (prefijo `fw-ocu`)
   Sustituye a tres fichas de cifra. «Fuera hoy» y «Libres hoy» eran la misma
   pregunta partida en dos números que había que sumar; la barra la contesta
   sin leer. El rojo es lo que SALE —lo que puede faltarte—, el carril es el
   resto. Las cifras van escritas: el gris del carril no llega a 3:1 contra el
   papel, así que el color no puede ser el único que lo diga.
   ═══════════════════════════════════════════════════════════════════════════ */
.fw-ocupacion { padding: 2px 0 10px; }
.fw-ocu-cab {
  display: flex; align-items: baseline; gap: 8px;
  font-size: 13px; color: var(--text-2); margin-bottom: 7px;
}
.fw-ocu-cab b {
  font-size: 23px; font-weight: 700; color: var(--text);
  line-height: 1; font-variant-numeric: tabular-nums;
}
.fw-ocu-resto { margin-left: auto; font-size: 12px; color: var(--text-soft); font-variant-numeric: tabular-nums; }
.fw-ocu-barra {
  height: 10px; background: var(--surface-sunk, var(--surface-2));
  overflow: hidden;
}
.fw-ocu-fuera {
  display: block; height: 100%; background: var(--accent);
  transition: width .3s cubic-bezier(.2,.7,.2,1);
}
.fw-ocu-pie {
  margin-top: 7px; font-size: 11.5px; color: var(--text-soft);
  font-variant-numeric: tabular-nums;
}

/* El vacío de un widget del panel: UNA línea, no una caja. Un bloque sin datos
   ocupaba lo mismo que uno lleno y en tres columnas eso es un tercio de la
   pantalla diciendo que no hay nada. El porqué vive en el `title`. */
.dash-nada {
  margin: 0; padding: 10px 0 4px;
  font-size: 12.5px; color: var(--text-soft);
  cursor: help;
}

/* La ficha de presencia con foto. Mismo cuadrado que las iniciales: la foto
   sustituye a las letras, no cambia la forma ni el sitio. */
.pre-yo.pre-foto { background: var(--surface-2); padding: 0; overflow: hidden; }
.pre-yo.pre-foto img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ═══════════════════════════════════════════════════════════════════════════
   MEDIDAS Y PESO                                            (13/10/2026)

   Una rejilla de almacén: se mira de arriba abajo por columnas, no de
   izquierda a derecha por filas. De ahí lo que manda aquí — cifras tabulares,
   columnas estrechas y pegadas, y la fila medida apagándose un punto para que
   lo que resalte sea el hueco que falta y no el trabajo ya hecho.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Cabecera: cuánto falta ─────────────────────────────────────────────── */
/* ── Conjuntos: marcar y meter en una caja ──────────────────────────────── */
.med-check { display: inline-flex; align-items: center; margin-right: 9px; vertical-align: middle; }
.med-fila.med-marcada { background: color-mix(in srgb, var(--accent) 8%, transparent); }
/* ── LA BARRA DE LO MARCADO, FLOTANDO ────────────────────────────────────────
   Xavi (15/10/2026): «cuando seleccionamos material, como aparece el menú de
   arriba, se va para abajo la lista y en ese momento seleccionar se hace un
   poco pesado».

   Claro: la barra ocupaba sitio en la página, así que aparecer empujaba la
   rejilla entera hacia abajo y lo que estabas a punto de marcar se te movía
   del dedo. Marcando quince cosas seguidas, eso es quince veces.

   Ahora flota sobre la rejilla, abajo y centrada, como las barras de acción de
   cualquier gestor de archivos: aparece y desaparece sin mover un píxel de lo
   que hay debajo. */
.med-selbarra { display: none; }
.med-selbarra.hay {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  /* FIJA A LA VENTANA, no al marco de la rejilla: la rejilla es más alta que
     la pantalla, así que anclada a ella la barra se quedaba fuera de la vista
     justo cuando hace falta. */
  position: fixed; z-index: 60;
  left: 50%; bottom: 26px; transform: translateX(-50%);
  width: max-content; max-width: calc(100% - 32px);
  padding: 9px 10px 9px 16px;
  border: 1px solid var(--text); border-radius: 999px;
  background: var(--text); color: var(--surface);
  box-shadow: 0 10px 30px rgba(0,0,0,.22);
  animation: medSelEntra .14s ease-out;
}
@keyframes medSelEntra { from { opacity: 0; transform: translate(-50%, 10px); } }
@media (prefers-reduced-motion: reduce) { .med-selbarra.hay { animation: none; } }

.med-selbarra-n { font-size: 12.5px; font-weight: 650; color: #fff; white-space: nowrap; }
/* Los botones, en negativo sobre la barra. */
.med-selbarra .btn-primary {
  background: #fff; color: var(--text); border-color: #fff;
}
.med-selbarra .btn-primary:hover { background: rgba(255,255,255,.88); }
.med-selbarra .btn-sec {
  background: rgba(255,255,255,.14); color: #fff; border-color: rgba(255,255,255,.3);
}
.med-selbarra .btn-sec:hover { background: rgba(255,255,255,.24); }
.med-selbarra .eq-link { color: rgba(255,255,255,.75); }
.med-selbarra .eq-link:hover { color: #fff; }


.med-conj-rot {
  display: block; margin: 14px 0 6px;
  font-size: 10.5px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  color: var(--text-soft);
}
/* «Entera»: el total sale de la báscula y no de sumar. Se dice porque las dos
   cosas no valen lo mismo, y un número sin saber de dónde viene no se puede
   defender delante de un cliente. */
.med-entero {
  margin-left: 7px; padding: 1px 6px; border-radius: 10px;
  font-size: 10px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  background: rgba(43,45,66,0.08); color: var(--text-soft);
}

/* La franja del rodaje: va encima de la cobertura de la casa porque es la
   cuenta que se puede terminar hoy. Verde cuando ya no falta nada de ese
   rodaje, que es la única buena noticia de esta pantalla. */
.med-proy {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  padding: 13px 16px; margin-bottom: 12px;
  border: 1px solid color-mix(in srgb, var(--accent) 45%, var(--border));
  border-radius: 10px;
  background: color-mix(in srgb, var(--accent) 7%, transparent);
}
.med-proy.lleno {
  border-color: color-mix(in srgb, var(--green, #2e7d32) 45%, var(--border));
  background: color-mix(in srgb, var(--green, #2e7d32) 8%, transparent);
}
.med-proy-txt { display: flex; flex-direction: column; gap: 2px; min-width: 190px; }
.med-proy-txt strong { font-size: 15px; font-weight: 700; }
.med-proy-txt span { font-size: 12.5px; color: var(--text-soft); }
.med-proy .med-barra { flex: 1 1 160px; min-width: 120px; }

.med-cab {
  display: flex; gap: 28px; align-items: stretch; flex-wrap: wrap;
  background: var(--surface); border: 1px solid var(--border);
  padding: 20px 22px; margin-bottom: 12px;
}
.med-cab-izq { flex: 1 1 320px; min-width: 260px; display: flex; flex-direction: column; justify-content: center; }
.med-cab-cifra { display: flex; align-items: baseline; gap: 8px; }
.med-cab-cifra b { font-size: 34px; font-weight: 700; letter-spacing: -0.03em; line-height: 1; font-variant-numeric: tabular-nums; }
.med-cab-cifra span { font-size: 13px; color: var(--text-soft); }
.med-barra {
  height: 8px; background: var(--surface-sunk); margin: 12px 0 7px; overflow: hidden;
}
.med-barra > i { display: block; height: 100%; background: var(--accent); transition: width .4s ease; }
.med-cab-pie {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .03em;
  text-transform: uppercase; color: var(--text-soft);
}
.med-cab-der { display: flex; gap: 26px; align-items: center; flex-wrap: wrap; }
.med-cifra { display: flex; flex-direction: column; gap: 3px; }
.med-cifra b { font-size: 21px; font-weight: 650; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.med-cifra b small { font-size: 12px; font-weight: 500; color: var(--text-soft); margin-left: 2px; }
.med-cifra span {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .05em;
  text-transform: uppercase; color: var(--text-soft);
}

/* ── Departamentos: una barra por cada uno, y se pulsan ─────────────────── */
.med-deps {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 1px; background: var(--border); border: 1px solid var(--border); margin-bottom: 16px;
}
.med-dep {
  display: grid; grid-template-columns: 1fr 64px auto; align-items: center; gap: 10px;
  background: var(--surface); border: none; padding: 9px 13px;
  font-family: var(--font); cursor: pointer; text-align: left;
  transition: background var(--transition);
}
.med-dep:hover { background: var(--blue-light); }
.med-dep-nom { font-size: 12.5px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.med-dep-barra { height: 5px; background: var(--surface-sunk); overflow: hidden; }
.med-dep-barra > i { display: block; height: 100%; background: var(--text-soft); }
.med-dep.lleno .med-dep-barra > i { background: var(--accent); }
.med-dep-cifra { font-family: var(--font-mono); font-size: 11px; color: var(--text-soft); font-variant-numeric: tabular-nums; }
.med-dep-cifra small { opacity: .6; }

/* ── La rejilla ─────────────────────────────────────────────────────────── */
.med-cuenta { font-size: 12px; color: var(--text-soft); margin-left: auto; align-self: center; }
.med-tabla td { padding: 6px 10px; }
.med-tabla th { padding: 8px 10px; }
.med-th-num, .med-td-num { text-align: right; white-space: nowrap; }
.med-th-num small { display: block; font-size: 9px; opacity: .65; font-weight: 500; letter-spacing: .04em; }
.med-td-num { font-variant-numeric: tabular-nums; }
.med-td-art { min-width: 260px; }
.med-nombre {
  background: none; border: none; padding: 0; font-family: var(--font);
  font-size: 13px; font-weight: 550; color: var(--text); cursor: pointer; text-align: left;
}
.med-nombre:hover { color: var(--accent); }
.med-sub { display: flex; gap: 8px; align-items: center; font-size: 11px; color: var(--text-soft); margin-top: 1px; }
.med-cod { font-family: var(--font-mono); font-size: 10.5px; }
.med-caja {
  font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .05em; text-transform: uppercase;
  color: var(--text); background: var(--surface-sunk); padding: 1px 5px;
}
.med-gris { color: var(--text-xsoft); }
.med-falta {
  font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .04em; text-transform: uppercase;
  color: var(--accent); margin-left: 6px; cursor: help;
}
.med-firma { font-family: var(--font-mono); font-size: 10.5px; color: var(--text-soft); white-space: nowrap; }

/* Las casillas. Sin borde hasta que se tocan: 780 filas con cuatro recuadros
   cada una son 3.120 rectángulos y la pantalla deja de leerse. */
.med-in {
  width: 62px; text-align: right; padding: 4px 6px;
  font-family: var(--font-mono); font-size: 12px; font-variant-numeric: tabular-nums;
  color: var(--text); background: transparent;
  border: 1px solid transparent; border-radius: 0;
  transition: border-color var(--transition), background var(--transition);
}
.med-in::placeholder { color: var(--text-xsoft); }
.med-in:hover { border-color: var(--border-med); }
.med-in:focus { outline: none; border-color: var(--accent); background: var(--surface); box-shadow: var(--ring); }

/* El estado de la fila mientras se guarda. Una raya roja a la izquierda y
   nada más: un «guardando…» por fila sería un parpadeo constante. */
.med-fila { position: relative; }
.med-fila.med-ok .med-td-art .med-sub { opacity: .75; }
.med-fila.med-guardando td:first-child { box-shadow: inset 3px 0 0 var(--text-soft); }
.med-fila.med-mal td:first-child { box-shadow: inset 3px 0 0 var(--accent); }
.med-fila.med-mal { background: var(--blue-light); }
.med-nada { padding: 48px; text-align: center; color: var(--text-soft); font-size: 13.5px;
            background: var(--surface); border: 1px solid var(--border); }

@media (max-width: 720px) {
  .med-cab { gap: 16px; padding: 16px; }
  .med-cab-der { gap: 18px; }
  .med-deps { grid-template-columns: 1fr; }
  .med-in { width: 54px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   MEDIDAS Y PESO EN EL MÓVIL

   Esta pantalla es la que MÁS se va a usar con el teléfono en la mano: medir
   es trabajo de almacén, de pie, con la cinta en la otra mano. Así que aquí el
   móvil no es una versión reducida de la de escritorio, es la principal.

   Una tarjeta por artículo: el nombre arriba, las cuatro casillas en fila —con
   su rótulo encima, que sin cabecera de tabla no hay manera de saber cuál es
   el alto— y debajo, en una línea, lo que sale de ellas.

   Las clases `med-c-*` las pone el pintado, no el pase general de tablas.
   ═══════════════════════════════════════════════════════════════════════ */
@media (max-width: 720px) {
  #page-medidas .mov-tabla tbody tr {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 8px 6px;
    padding: 12px 13px;
    margin-bottom: 7px;
    background: var(--surface);
    border: 1px solid var(--border);
  }
  #page-medidas .mov-tabla tbody td::before { content: none !important; }
  #page-medidas .mov-tabla tbody td {
    display: block; width: auto !important; padding: 0 !important;
    border: 0 !important; text-align: left !important;
  }

  #page-medidas .mov-tabla tbody td.med-c-art { grid-column: 1 / -1; }
  #page-medidas .med-c-art .med-nombre { font-size: 14px; }

  /* Rótulo encima de cada casilla: sin la cabecera de la tabla, cuatro huecos
     iguales en fila no se distinguen. */
  #page-medidas .mov-tabla tbody td.med-c-largo_cm,
  #page-medidas .mov-tabla tbody td.med-c-ancho_cm,
  #page-medidas .mov-tabla tbody td.med-c-alto_cm,
  #page-medidas .mov-tabla tbody td.med-c-peso_kg { position: relative; padding-top: 15px !important; }
  #page-medidas .mov-tabla tbody td.med-c-largo_cm::after,
  #page-medidas .mov-tabla tbody td.med-c-ancho_cm::after,
  #page-medidas .mov-tabla tbody td.med-c-alto_cm::after,
  #page-medidas .mov-tabla tbody td.med-c-peso_kg::after {
    position: absolute; top: 0; left: 0;
    font-family: var(--font-mono); font-size: 9px; letter-spacing: .05em;
    text-transform: uppercase; color: var(--text-soft);
  }
  #page-medidas .mov-tabla tbody td.med-c-largo_cm::after { content: 'Largo cm'; }
  #page-medidas .mov-tabla tbody td.med-c-ancho_cm::after { content: 'Ancho cm'; }
  #page-medidas .mov-tabla tbody td.med-c-alto_cm::after  { content: 'Alto cm'; }
  #page-medidas .mov-tabla tbody td.med-c-peso_kg::after  { content: 'Peso kg'; }

  /* Las casillas, a dedo: 44 px de alto y todo el ancho de su columna. */
  #page-medidas .med-in {
    width: 100%; min-height: 40px; text-align: left;
    font-size: 16px;                 /* menos de 16 y iOS hace zoom al tocar */
    border-color: var(--border-med); background: var(--surface-2);
  }

  /* Lo que sale de las casillas, en una línea debajo. */
  #page-medidas .mov-tabla tbody td.med-c-vol,
  #page-medidas .mov-tabla tbody td.med-c-total,
  #page-medidas .mov-tabla tbody td.med-c-firma {
    grid-column: span 2; font-size: 11.5px; color: var(--text-soft);
    align-self: center;
  }
  #page-medidas .mov-tabla tbody td.med-c-firma { grid-column: 1 / -1; }
  #page-medidas .mov-tabla tbody td.med-c-total { text-align: right !important; }

  /* La cabecera de cifras, apilada. `flex: 0 0 auto` no es cosmético: la base
     de 320 px que en fila es ANCHO, al apilar pasa a ser ALTO, y la caja salía
     con 320 px de aire dentro. */
  #page-medidas .med-cab { flex-direction: column; gap: 14px; }
  #page-medidas .med-cab-izq { flex: 0 0 auto; min-width: 0; }
  #page-medidas .med-cab-der { gap: 14px 22px; }
}

/* ── Medidas en la ficha de material ───────────────────────────────────── */
.mf-caja {
  display: flex; gap: 24px; align-items: flex-start; flex-wrap: wrap;
  background: var(--surface-2); border: 1px solid var(--border); padding: 16px 18px;
}
.mf-caja.mf-guardando { opacity: .6; }
.mf-campos { display: flex; gap: 14px; flex-wrap: wrap; }
.mf-campo { display: flex; flex-direction: column; gap: 5px; }
.mf-campo label {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .05em;
  text-transform: uppercase; color: var(--text-soft);
}
.mf-in-wrap { display: flex; align-items: baseline; gap: 5px; }
.mf-in {
  width: 74px; padding: 7px 9px; text-align: right;
  font-family: var(--font-mono); font-size: 14px; font-variant-numeric: tabular-nums;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border-med); border-radius: 0;
}
.mf-in:focus { outline: none; border-color: var(--accent); box-shadow: var(--ring); }
.mf-in-wrap > span, .mf-valor > span { font-size: 11.5px; color: var(--text-soft); }
.mf-valor { font-family: var(--font-mono); font-size: 14px; padding: 7px 0; }
.mf-resumen { display: flex; gap: 22px; margin-left: auto; align-items: center; }
.mf-cifra { display: flex; flex-direction: column; gap: 2px; }
.mf-cifra b { font-size: 20px; font-weight: 650; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.mf-cifra b small { font-size: 11px; font-weight: 500; color: var(--text-soft); margin-left: 2px; }
.mf-cifra span { font-size: 11px; color: var(--text-soft); }
.mf-cifra.incompleta span { color: var(--accent); }
.mf-firma {
  float: right; font-family: var(--font-mono); font-size: 10px; letter-spacing: .04em;
  text-transform: uppercase; color: var(--text-soft); font-weight: 500;
}
.mf-firma.mf-sin { color: var(--accent); }
.mf-nota { margin-top: 8px; font-size: 12px; color: var(--text-soft); line-height: 1.5; }
.mf-nota b { color: var(--text); }
@media (max-width: 720px) {
  .mf-caja { gap: 14px; padding: 13px; }
  .mf-resumen { margin-left: 0; gap: 18px; }
  .mf-in { width: 64px; font-size: 16px; }
}

/* ── Transporte de un rodaje ───────────────────────────────────────────── */
.mt-cifras {
  display: flex; gap: 32px; align-items: center; flex-wrap: wrap;
  background: var(--surface); border: 1px solid var(--border);
  border-left: 3px solid var(--accent); padding: 18px 22px;
}
.mt-cifras.completo { border-left-color: var(--text); }
.mt-cifra { display: flex; flex-direction: column; gap: 2px; }
.mt-cifra b { font-size: 28px; font-weight: 700; letter-spacing: -0.03em; font-variant-numeric: tabular-nums; }
.mt-cifra b small { font-size: 13px; font-weight: 500; color: var(--text-soft); margin-left: 2px; }
.mt-cifra span {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .05em;
  text-transform: uppercase; color: var(--text-soft);
}
.mt-sello { flex: 1 1 220px; font-size: 12.5px; color: var(--accent); line-height: 1.45; }
.mt-cifras.completo .mt-sello { color: var(--text-soft); }
.mt-excel { flex: 0 0 auto; }
.mt-n {
  font-family: var(--font-mono); font-size: 11px; color: var(--text-soft);
  background: var(--surface-sunk); padding: 1px 6px; margin-left: 6px;
}
.mt-nombre {
  background: none; border: none; padding: 0; font-family: var(--font);
  font-size: 13px; font-weight: 550; color: var(--text); cursor: pointer; text-align: left;
}
.mt-nombre:hover:not(:disabled) { color: var(--accent); }
.mt-nombre:disabled { cursor: default; color: var(--text-2); }
.mt-sub { display: flex; gap: 8px; font-size: 11px; color: var(--text-soft); margin-top: 1px; }
.mt-dim { font-family: var(--font-mono); font-size: 11.5px; color: var(--text-2); }
.mt-conten {
  display: block; font-family: var(--font-mono); font-size: 9px; letter-spacing: .05em;
  text-transform: uppercase; color: var(--text-soft);
}
.mt-pend { font-size: 12px; color: var(--accent); }
.mt-dentro { background: var(--surface); border: 1px solid var(--border); }
.mt-dentro-fila {
  display: flex; gap: 10px; align-items: baseline; justify-content: space-between;
  padding: 9px 15px; border-bottom: 1px solid var(--border);
}
.mt-dentro-fila:last-child { border-bottom: none; }
.mt-dentro-fila > span { font-size: 12px; color: var(--text-soft); }
.mt-dentro-fila b { color: var(--text); font-weight: 600; }
.mt-nota { margin-top: 8px; font-size: 12px; color: var(--text-soft); line-height: 1.5; }
.mt-cargando, .mt-vacio {
  padding: 44px; text-align: center; color: var(--text-soft); font-size: 13.5px;
  background: var(--surface); border: 1px solid var(--border);
}
.mt-vacio b { display: block; color: var(--text); font-size: 14.5px; margin-bottom: 5px; }
@media (max-width: 720px) {
  .mt-cifras { gap: 18px; padding: 15px; }
  .mt-cifra b { font-size: 23px; }
}

/* El transporte en el móvil. El apaño general de tablas pinta una línea por
   columna con su etiqueta delante: cinco columnas son cinco líneas y 160 px
   por artículo. Aquí el nombre va arriba y lo demás en una sola línea, como
   en el inventario, por el mismo motivo y con la misma técnica (clases
   propias, no el `data-mov-col` que pone un pase aparte). */
@media (max-width: 720px) {
  #page-proyecto .mt-tabla.mov-tabla tbody tr {
    display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px;
    padding: 11px 13px; margin-bottom: 7px;
  }
  #page-proyecto .mt-tabla.mov-tabla tbody td::before { content: none !important; }
  #page-proyecto .mt-tabla.mov-tabla tbody td {
    display: inline-flex; align-items: baseline; width: auto !important;
    flex: 0 0 auto; padding: 0 !important; border: 0 !important;
    font-size: 12px; color: var(--text-soft); text-align: left !important;
  }
  #page-proyecto .mt-tabla.mov-tabla tbody td:first-child { flex: 1 0 100%; display: block; }
  /* Sin cabecera, un «1» suelto no dice nada; con la equis sí. */
  #page-proyecto .mt-tabla.mov-tabla tbody td.mt-c-uds::before {
    content: '\00d7' !important; margin-right: 2px; color: var(--text-xsoft);
  }
  #page-proyecto .mt-tabla.mov-tabla .mt-conten { display: inline; margin-left: 4px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   MEDIDAS: EL MODO EDICIÓN Y EL PANEL DE LA DERECHA        (13/10/2026)

   La distribución es la de Proyectos, que ya está rodada: la lista CEDE ancho
   al panel en vez de que el panel la tape. Debajo de 1200 px no se parte en
   dos —dos columnas de 300 px no sirven para nada— y el panel pasa a ocupar
   todo.
   ═══════════════════════════════════════════════════════════════════════ */
.med-layout { display: flex; gap: 0; align-items: flex-start; }
.med-main { flex: 1; min-width: 0; transition: padding-right 0.26s cubic-bezier(0.2,0.9,0.3,1); }
.med-layout.con-drawer .med-main { padding-right: 20px; }
.med-drawer {
  width: 0; flex-shrink: 0; align-self: stretch;
  /* `clip` y no `hidden`, y solo en horizontal. Con `overflow: hidden` el
     cajón se convierte en el contenedor de desplazamiento del panel, y
     entonces su `position: sticky` deja de agarrarse a la página: al bajar por
     la lista el panel se iba hacia arriba y desaparecía. Medido: con la lista
     bajada, el panel quedaba en top -712. `clip` recorta la animación de
     ancho igual, pero no crea contenedor de desplazamiento. */
  overflow-x: clip; overflow-y: visible;
  transition: width 0.26s cubic-bezier(0.2,0.9,0.3,1);
}
.med-layout.con-drawer .med-drawer { width: min(430px, 40vw); }
.med-drawer-inner {
  width: min(430px, 40vw);
  position: sticky; top: 0;
  max-height: calc(100vh - 48px);
  overflow-y: auto; overscroll-behavior: contain;
  background: var(--surface);
  border: 1px solid var(--border-med);
}
/* El corte está en 1100 y no en 1200 como el de Proyectos porque aquí el menú
   de la izquierda se recoge al abrir el panel: son 200 px más de sitio para la
   lista, y partir en dos sigue valiendo la pena hasta más abajo. */
@media (max-width: 1100px) {
  .med-layout.con-drawer .med-main { display: none; }
  .med-layout.con-drawer .med-drawer { width: 100%; }
  .med-drawer-inner { width: 100%; max-height: none; }
}

/* ── El interruptor ─────────────────────────────────────────────────────── */
.med-modo {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 5px 11px 5px 8px; cursor: pointer; user-select: none;
  border: 1px solid var(--border-med); background: var(--surface);
  transition: border-color var(--transition), background var(--transition);
}
.med-modo:hover { border-color: var(--border-strong); }
.med-modo input { position: absolute; opacity: 0; width: 0; height: 0; }
.med-modo-pista {
  width: 30px; height: 17px; flex-shrink: 0;
  background: var(--surface-sunk); position: relative;
  transition: background var(--transition);
}
.med-modo-pista::after {
  content: ''; position: absolute; top: 2px; left: 2px;
  width: 13px; height: 13px; background: var(--text-soft);
  transition: transform var(--transition), background var(--transition);
}
.med-modo-txt {
  font-size: 12.5px; font-weight: 550; color: var(--text-2);
  white-space: nowrap;
}
.med-modo.encendido { border-color: var(--accent); background: var(--blue-light); }
.med-modo.encendido .med-modo-pista { background: rgba(var(--acento-rgb), 0.25); }
.med-modo.encendido .med-modo-pista::after { transform: translateX(13px); background: var(--accent); }
.med-modo.encendido .med-modo-txt { color: var(--accent); }
.med-modo input:focus-visible + .med-modo-pista { box-shadow: var(--ring); }

/* Mientras está encendido, la tabla lo dice sin letra: una raya roja arriba.
   Es el aviso que falta cuando llevas media hora y ya no miras el botón. */
#page-medidas.med-editando .med-tabla thead th { border-top: 2px solid var(--accent); }

/* La fila que tiene el panel abierto. */
.med-fila.med-abierta {
  background: rgba(var(--acento-rgb), 0.06) !important;
  box-shadow: inset 3px 0 0 var(--accent);
}
.med-fila { cursor: default; }
#page-medidas:not(.med-editando) .med-fila:hover { background: var(--blue-light); }

/* ── El panel ───────────────────────────────────────────────────────────── */
.mp-cab {
  padding: 13px 16px 14px;
  border-bottom: 1px solid var(--border);
  border-top: 3px solid var(--accent);
  background: var(--surface-2);
  position: sticky; top: 0; z-index: 3;
}
.mp-cab-top { display: flex; align-items: center; gap: 8px; margin-bottom: 9px; }
.mp-pos {
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .04em;
  text-transform: uppercase; color: var(--text-soft);
  font-variant-numeric: tabular-nums;
}
.mp-nav { margin-left: auto; display: flex; gap: 4px; }
.mp-flecha, .mp-cerrar {
  width: 26px; height: 26px; display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--border-med); background: var(--surface);
  color: var(--text-2); cursor: pointer; font-size: 13px; line-height: 1;
  transition: all var(--transition);
}
.mp-flecha:hover:not(:disabled), .mp-cerrar:hover { border-color: var(--accent); color: var(--accent); }
.mp-flecha:disabled { opacity: .35; cursor: default; }
.mp-nombre { font-size: 16px; font-weight: 650; letter-spacing: -0.015em; line-height: 1.25; }
.mp-sub { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; font-size: 11.5px; color: var(--text-soft); margin-top: 4px; }

.mp-cuerpo { padding: 14px 16px 20px; }
.mp-sec-tit {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .07em;
  text-transform: uppercase; color: var(--text-soft);
  margin: 18px 0 9px;
}
.mp-cuerpo > .mp-sec-tit:first-child { margin-top: 0; }
.mp-candado {
  background: var(--surface-2); border-left: 3px solid var(--text-soft);
  padding: 10px 12px; font-size: 12.5px; color: var(--text-2); line-height: 1.5;
}
.mp-candado b { color: var(--text); }
.mp-candado span { display: block; margin-top: 2px; }

.mp-campos { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
.mp-campo { display: flex; flex-direction: column; gap: 5px; }
.mp-campo label {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .05em;
  text-transform: uppercase; color: var(--text-soft);
}
.mp-in-wrap { display: flex; align-items: baseline; gap: 5px; }
.mp-in {
  width: 100%; padding: 8px 10px; text-align: right;
  font-family: var(--font-mono); font-size: 14px; font-variant-numeric: tabular-nums;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border-med); border-radius: 0;
}
.mp-in:focus { outline: none; border-color: var(--accent); box-shadow: var(--ring); }
.mp-in-wrap > span, .mp-valor > span { font-size: 11px; color: var(--text-soft); }
.mp-valor { font-family: var(--font-mono); font-size: 14px; padding: 8px 0; }

.mp-cifras {
  display: flex; gap: 24px; margin-top: 16px; padding-top: 14px;
  border-top: 1px solid var(--border);
}
.mp-cifra { display: flex; flex-direction: column; gap: 2px; }
.mp-cifra b { font-size: 20px; font-weight: 650; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.mp-cifra b small { font-size: 11px; font-weight: 500; color: var(--text-soft); margin-left: 2px; }
.mp-cifra span { font-size: 11px; color: var(--text-soft); }
.mp-cifra.incompleta span { color: var(--accent); }
.mp-nota { margin-top: 10px; font-size: 11.5px; color: var(--text-soft); line-height: 1.5; }
.mp-nota b { color: var(--text); }

.mp-dentro { border: 1px solid var(--border); }
.mp-pieza {
  display: flex; align-items: baseline; gap: 9px;
  padding: 8px 11px; border-bottom: 1px solid var(--border);
}
.mp-pieza:last-child { border-bottom: none; }
.mp-pieza-n { font-family: var(--font-mono); font-size: 11px; color: var(--text-soft); min-width: 26px; }
.mp-pieza-nom {
  background: none; border: none; padding: 0; font-family: var(--font);
  font-size: 12.5px; color: var(--text); cursor: pointer; text-align: left; flex: 1; min-width: 0;
}
.mp-pieza-nom:hover:not(:disabled) { color: var(--accent); }
.mp-pieza-nom:disabled { cursor: default; color: var(--text-soft); }
.mp-pieza-kg { font-family: var(--font-mono); font-size: 11.5px; color: var(--text-2); font-variant-numeric: tabular-nums; }
.mp-sin { font-style: normal; color: var(--accent); font-size: 10px; letter-spacing: .04em; text-transform: uppercase; }
.mp-vacio { padding: 12px; font-size: 12px; color: var(--text-soft); }

.mp-firma {
  margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--border);
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .03em;
  color: var(--text-soft);
}
.mp-pie { margin-top: 14px; display: flex; flex-direction: column; gap: 8px; align-items: flex-start; }
.mp-pista { font-size: 11px; color: var(--text-xsoft); line-height: 1.5; }

/* ═══════════════════════════════════════════════════════════════════════════
   JUNTAR COSAS EN MEDIDAS Y PESO                   (14/10/2026, `.med-jun-*`)

   Xavi: «juntar la Venice con el Rialto y hacerlo un pack… y que este grupo
   poder convertirlo en una caja o simplemente en un grupo».

   Dos chapas nuevas en la fila y una ventana con lista. Las chapas van en el
   mismo mono pequeño que «caja · 4», que ya estaba: son la misma clase de dato
   —qué es esto y dónde está— y verlas distintas sería inventar una jerarquía
   que no existe.
   ═══════════════════════════════════════════════════════════════════════════ */

/* GRUPO en vez de CAJA: la misma chapa con el fondo hueco. No es un color
   nuevo —la app ya tiene bastantes— sino la misma forma sin rellenar, que es
   justo lo que es: un bulto sin caja. */
.med-caja.med-grupo {
  background: transparent; color: var(--text-soft);
  box-shadow: inset 0 0 0 1px var(--border);
}

/* Dónde está metida una cosa. En gris y sin caja: es contexto, no un estado. */
.med-dentro {
  font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .04em;
  text-transform: uppercase; color: var(--text-xsoft); cursor: help;
}

/* El pie del menú del botón derecho: una línea que dice qué es esto antes de
   que elijas qué hacerle. */
.eqm-pie {
  padding: 0 10px 8px; margin-top: -2px;
  font-size: 11px; line-height: 1.45; color: var(--text-soft);
}

/* ── LA VENTANA DE «JUNTAR CON…» ─────────────────────────────────────────── */
.med-jun-busca { margin-top: 4px; }

.med-jun-lista {
  max-height: 260px; overflow: auto; margin: 10px 0 4px;
  border: 1px solid var(--border); background: var(--surface-sunk);
}
.med-jun-f {
  display: grid; grid-template-columns: 20px 1fr auto; align-items: center; gap: 10px;
  padding: 8px 12px; cursor: pointer;
  border-bottom: 1px solid var(--border);
}
.med-jun-f:last-child { border-bottom: 0; }
.med-jun-f:hover { background: var(--bg-hover); }
/* Lo ya elegido va arriba y se queda a la vista aunque la búsqueda lo excluya:
   por eso necesita verse marcado de lejos y no solo por la casilla. */
.med-jun-f.puesta { background: var(--surface); box-shadow: inset 3px 0 0 var(--accent); }
.med-jun-n { font-size: 13px; color: var(--text); }
.med-jun-m {
  font-family: var(--font-mono); font-size: 10.5px; color: var(--text-xsoft);
  white-space: nowrap;
}
.med-jun-nada { padding: 14px 12px; font-size: 12.5px; color: var(--text-soft); }

/* Caja o grupo. Dos bloques con su explicación debajo, no dos palabras sueltas:
   la diferencia entre los dos es precisamente lo que hay que explicar. */
.med-jun-tipo { display: grid; gap: 8px; margin-top: 4px; }
.med-jun-tipo label {
  display: grid; grid-template-columns: 20px 1fr; align-items: baseline;
  gap: 4px 10px; padding: 10px 12px; cursor: pointer;
  border: 1px solid var(--border); background: var(--surface);
}
.med-jun-tipo label:hover { background: var(--bg-hover); }
.med-jun-tipo label:has(input:checked) { box-shadow: inset 0 0 0 1px var(--text); }
.med-jun-tipo b { font-size: 13px; color: var(--text); }
.med-jun-tipo span {
  grid-column: 2; font-size: 11.5px; line-height: 1.45; color: var(--text-soft);
}
.med-conj-tipo { margin-top: 8px; }

/* ═══════════════════════════════════════════════════════════════════════════
   QUE SE VEA QUE VAN JUNTOS                     (14/10/2026, `.med-padre/hija`)

   Xavi: «se tiene que ver que están juntos, se tiene que diferenciar desde la
   interfaz; que se vea que la Alexa Mini LF y la Arri Alexa Mini LF Cámara 4K
   son un pack, una caja».

   Lo que ata las filas es un FILETE VERTICAL a la izquierda del bloque, de la
   cabecera del conjunto hasta su última pieza, más la sangría del nombre. No
   hay color nuevo, ni fondo de color, ni una caja dentro de la tabla: es una
   llave de las de toda la vida, que es exactamente el signo que significa
   «esto va con esto» y no hace falta explicarlo.
   ═══════════════════════════════════════════════════════════════════════════ */

/* El bloque entero —cabecera y piezas— sobre un papel ligeramente hundido. Es
   lo que de verdad hace que se lea como UNA cosa y no como filas seguidas, y
   con 781 filas en la lista los packs saltan a la vista sin buscarlos.

   El filete va de fondo y no de `box-shadow`: la tabla es `border-collapse:
   collapse` y ahí las sombras de las celdas se las come el navegador a ratos.
   Un degradado de dos píxeles se pinta siempre. */
.med-tabla tr.med-padre > td,
.med-tabla tr.med-hija  > td { background-color: var(--surface-sunk); }

.med-tabla tr.med-padre > td:first-child,
.med-tabla tr.med-hija  > td:first-child {
  background-image: linear-gradient(90deg, var(--text-xsoft) 0 2px, transparent 2px);
}

/* La cabecera del pack: el nombre pesa un poco más, como un encabezado. */
.med-tabla tr.med-padre .med-nombre { font-weight: 650; }

/* Y las piezas: el nombre sangrado y un travesaño que lo cuelga del filete.
   La sangría va en el TD y no en el botón para que la lleven también el código
   y la categoría de debajo: lo que se sangra es la fila entera, no una palabra. */
.med-tabla tr.med-hija > td:first-child {
  padding-left: 30px;
  position: relative;
}
/* El travesaño de la llave. 10 px, lo justo para que el ojo cierre la forma. */
.med-tabla tr.med-hija > td:first-child::before {
  content: ''; position: absolute; left: 2px; top: 50%;
  width: 10px; height: 1px; background: var(--border);
}
.med-tabla tr.med-hija .med-nombre { font-size: 12.5px; color: var(--text-soft); }
.med-tabla tr.med-hija:hover .med-nombre { color: var(--text); }

/* El conjunto que ha venido de arrastre: no pasaba el filtro, está ahí para
   decir de quién es la pieza que sí pasaba. Se apaga, no se disfraza. */
.med-tabla tr.med-contexto > td { opacity: .55; }
.med-tabla tr.med-contexto:hover > td { opacity: 1; }

/* ═══════════════════════════════════════════════════════════════════════════
   EL CONJUNTO SE ABRE Y SE CIERRA              (14/10/2026, `.med-abrir-conj`)

   Xavi: «si meto todo en un conjunto de la Arri Package, que todo el material
   se esconda en la Arri Package y salga solo si le das al desplegable».

   Cerrado, el conjunto es UN renglón que dice cuántas cosas lleva. Es lo que
   hace que juntar sirva de algo: si la caja y sus doce piezas siguen ocupando
   trece sitios, la lista no está más ordenada, solo más junta.
   ═══════════════════════════════════════════════════════════════════════════ */

/* El triángulo. Gira, no cambia de icono: el giro dice «esto se abre» sin que
   haya que aprender dos dibujos. */
.med-abrir-conj {
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; margin-right: 2px; padding: 0;
  background: none; border: 0; cursor: pointer; color: var(--text-soft);
  transition: transform .14s ease, color .14s ease;
  vertical-align: -4px;
}
.med-abrir-conj:hover { color: var(--text); }
.med-fila[data-abierto="si"] .med-abrir-conj { transform: rotate(90deg); }
@media (prefers-reduced-motion: reduce) { .med-abrir-conj { transition: none; } }

/* La chapa «caja · 4» ahora también abre y cierra: es lo que el dedo busca
   primero, porque es lo que dice que hay algo dentro. */
button.med-caja {
  border: 0; cursor: pointer; font-family: var(--font-mono);
  display: inline-block;
}
button.med-caja:hover { background: var(--text); color: var(--surface); }
button.med-caja.med-grupo:hover { background: var(--text); color: var(--surface); box-shadow: none; }

/* La casilla de la cabecera, para marcarlo todo de una vez. */
.med-check-todo { margin-right: 8px; }

/* El peso del bulto entero, escrito en la propia fila. Va alineado a la
   derecha como el resto de los números y con el total calculado de marca de
   agua, para que se vea qué saldría si no lo escribes. */
.med-in.med-in-total { text-align: right; font-weight: 600; }
.med-in.med-in-total::placeholder { font-weight: 400; color: var(--text-xsoft); }

/* ═══════════════════════════════════════════════════════════════════════════
   UN CONJUNTO ES UNA CAJA, Y SE VE             (14/10/2026, `.med-padre/hija`)

   Xavi, después de la primera versión: «lo has hecho fatal. Si creamos un
   conjunto, que se junte literalmente. No quiero que simplemente pongas un
   texto. Tiene que ser SUPER visual».

   Tenía razón: lo anterior era un fondo un 3 % más oscuro y una chapa pequeña.
   Eso no es una caja, es una fila con un matiz. Ahora el bloque tiene cuatro
   cosas que lo hacen un objeto y no un renglón:

     · una barra de 4 px en tinta a la izquierda, de arriba abajo del bloque,
     · fondo propio para toda la caja y sus piezas,
     · un icono de bulto delante del nombre, y el nombre más grande,
     · y una tapa abajo que lo cierra.

   Son devices de toda la vida —rail, fondo, icono, cierre— y juntos dicen
   «esto es un contenedor» sin que haya que leer nada.
   ═══════════════════════════════════════════════════════════════════════════ */

/* La cabecera de la caja. */
.med-tabla tr.med-padre > td {
  background-color: var(--surface-sunk);
  border-top: 1px solid var(--text-xsoft);
  padding-top: 11px; padding-bottom: 11px;
}
.med-tabla tr.med-padre > td:first-child { box-shadow: inset 4px 0 0 var(--text); }
.med-tabla tr.med-padre .med-nombre { font-weight: 700; font-size: 14px; }

/* (El `.med-ico-caja` de insignia rellena se quitó el 15/10/2026: era una
   insignia de color en una casa que dibuja todos sus iconos a trazo. Ahora el
   icono del bulto es el propio botón de abrir, `.med-abrir-conj`.) */

/* Las piezas: mismo papel que su caja, sangradas y colgando del rail. */
.med-tabla tr.med-hija > td { background-color: var(--surface-sunk); }
.med-tabla tr.med-hija > td:first-child { box-shadow: inset 4px 0 0 var(--text); }

/* La tapa: cierra el bloque por abajo, que es lo que lo convierte en una caja
   y no en «unas filas sombreadas». */
.med-tabla tr.med-conj-fin > td {
  height: 7px; padding: 0;
  background-color: var(--surface-sunk);
  box-shadow: inset 4px 0 0 var(--text);
  border-bottom: 1px solid var(--text-xsoft);
}

/* ── ARRASTRAR ──────────────────────────────────────────────────────────── */

/* Lo que llevas en el puño se apaga en su sitio: ya no está «ahí». */
.med-tabla tr.med-arrastrando > td { opacity: .4; }

/* Y donde vas a soltar se enciende ENTERO —la caja y sus piezas—, porque lo
   que estás diciendo es «va aquí dentro». */
.med-tabla tr.med-suelta-aqui > td {
  background-color: color-mix(in srgb, var(--accent) 12%, var(--surface));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 35%, transparent);
}
.med-tabla tr.med-suelta-aqui > td:first-child { box-shadow: inset 4px 0 0 var(--accent); }

/* La zona de arriba: solo aparece mientras arrastras, y dice qué va a pasar. */
.med-zona {
  display: none;
  margin: 0 0 10px; padding: 14px 16px;
  border: 2px dashed var(--border); border-radius: 10px;
  font-size: 13px; color: var(--text-soft); text-align: center;
}
.med-zona.visible { display: block; }
.med-zona.med-suelta-aqui {
  border-color: var(--accent); color: var(--accent);
  background: color-mix(in srgb, var(--accent) 8%, transparent);
}

/* El cursor dice que se puede coger. */
.med-tabla tr.med-fila[draggable="true"] .med-td-art { cursor: grab; }
.med-tabla tr.med-fila[draggable="true"]:active .med-td-art { cursor: grabbing; }

/* ═══════════════════════════════════════════════════════════════════════════
   EL CONJUNTO, EN TINTA                        (15/10/2026, segunda pasada)

   Xavi: «si es una caja o es un grupo TIENE QUE SALIR bien visionado en el
   listado; lo veo super cutre todo».

   La pasada anterior sombreaba la fila y le ponía una barra. Seguía siendo una
   fila. Ahora la cabecera del conjunto es una BANDA EN TINTA con el texto en
   blanco —la misma que separa las secciones en el Excel de la casa— y lo que
   lleva dentro cuelga de ella sobre papel hundido. Eso no se confunde con un
   renglón de lista ni de reojo.
   ═══════════════════════════════════════════════════════════════════════════ */

.med-tabla tr.med-padre > td {
  background-color: var(--text);
  border-top: 0;
  color: var(--surface);
  padding-top: 12px; padding-bottom: 12px;
}
.med-tabla tr.med-padre > td:first-child { box-shadow: none; }
.med-tabla tr.med-padre .med-nombre { color: #fff; font-weight: 700; font-size: 14px; }
.med-tabla tr.med-padre .med-sub,
.med-tabla tr.med-padre .med-sub span,
.med-tabla tr.med-padre .med-cod { color: rgba(255,255,255,.62); }
.med-tabla tr.med-padre .med-abrir-conj,
.med-tabla tr.med-padre .med-agarre { color: rgba(255,255,255,.55); }
.med-tabla tr.med-padre .med-abrir-conj:hover,
.med-tabla tr.med-padre .med-agarre:hover { color: #fff; }
.med-tabla tr.med-padre .med-gris,
.med-tabla tr.med-padre .med-firma { color: rgba(255,255,255,.5); }
.med-tabla tr.med-padre b { color: #fff; }

/* El icono del bulto, en negativo sobre la banda. */
.med-tabla tr.med-padre .med-ico-caja { background: rgba(255,255,255,.16); color: #fff; }

/* Las casillas de medir, sobre la banda: se ven pero no gritan. */
.med-tabla tr.med-padre .med-in {
  color: #fff; background: rgba(255,255,255,.10);
  border-color: rgba(255,255,255,.22);
}
.med-tabla tr.med-padre .med-in::placeholder { color: rgba(255,255,255,.45); }
.med-tabla tr.med-padre .med-in:focus {
  background: rgba(255,255,255,.18); border-color: #fff; color: #fff;
}
.med-tabla tr.med-padre .med-check input { accent-color: #fff; }

/* La chapa, en negativo. */
.med-tabla tr.med-padre button.med-caja {
  background: rgba(255,255,255,.16); color: #fff; box-shadow: none;
}
.med-tabla tr.med-padre button.med-caja:hover { background: #fff; color: var(--text); }

/* De dónde sale el peso bueno: de la báscula o de sumar. */
.med-entero, .med-suma {
  font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .04em;
  text-transform: uppercase; margin-left: 6px; cursor: help;
}
.med-suma { color: var(--text-xsoft); }
.med-tabla tr.med-padre .med-entero { color: rgba(255,255,255,.8); }
.med-tabla tr.med-padre .med-suma { color: rgba(255,255,255,.55); }

/* ── MARCAR PINTANDO ────────────────────────────────────────────────────── */

/* La fila entera marca, así que lo dice el cursor y se nota al pasar. */
.med-tabla tr.med-fila .med-td-art { cursor: default; user-select: none; }
.med-tabla tr.med-fila:hover > td { background-color: var(--bg-hover); }
.med-tabla tr.med-padre:hover > td { background-color: color-mix(in srgb, var(--text) 88%, #fff); }

/* El tirador: seis puntitos, lo único que se arrastra. */
.med-agarre {
  display: inline-flex; align-items: center; justify-content: center;
  width: 14px; height: 20px; margin-right: 2px; vertical-align: -5px;
  color: var(--text-xsoft); cursor: grab;
  opacity: 0; transition: opacity .12s ease;
}
.med-fila:hover .med-agarre, .med-fila.med-marcada .med-agarre { opacity: 1; }
.med-agarre:active { cursor: grabbing; }
@media (hover: none) { .med-agarre { opacity: 1; } }

/* Marcado: que se vea de lejos cuántas llevas. */
.med-tabla tr.med-marcada > td {
  background-color: color-mix(in srgb, var(--accent) 10%, var(--surface));
}
.med-tabla tr.med-marcada > td:first-child { box-shadow: inset 3px 0 0 var(--accent); }

/* ═══════════════════════════════════════════════════════════════════════════
   LA COLUMNA DEL ARTÍCULO, EN RETÍCULA         (15/10/2026, `.med-art`)

   Xavi: «este icono no me gusta nada, queda super cutre; vamos a hacerlo
   respecto al diseño de la página».

   Lo cutre no era el dibujo: eran cinco cosas en línea —tirador, casilla,
   flecha, icono y nombre— empujándose entre ellas, así que un nombre largo se
   partía en tres renglones y cada fila empezaba en una raya distinta.

   Ahora son tres huecos: mandos (ancho fijo), símbolo (ancho fijo) y texto
   (el único que crece). Todos los nombres arrancan en la misma vertical, el
   subtítulo cae debajo del nombre y no debajo de los iconos, y el icono del
   bulto es de trazo como todos los de la casa — aquí no hay insignias
   rellenas.
   ═══════════════════════════════════════════════════════════════════════════ */

.med-art {
  display: grid;
  grid-template-columns: 34px 22px minmax(0, 1fr);
  align-items: start;
  column-gap: 8px;
}
/* Sin mandos —sin permiso— la retícula se cierra sola y no deja el hueco. */
.med-art:not(:has(.med-check)) { grid-template-columns: 0 22px minmax(0, 1fr); column-gap: 6px; }

.med-mandos { display: flex; align-items: center; gap: 2px; height: 20px; }
.med-simbolo { display: flex; align-items: center; justify-content: center; height: 20px; }
.med-texto { display: block; min-width: 0; }

/* El nombre: una línea y, si no cabe, dos — pero partidas por donde toca. */
.med-tabla .med-nombre {
  display: block; text-align: left; text-wrap: pretty;
}

/* El icono del bulto: trazo, sin fondo, sin insignia. Hace de botón de abrir
   junto con la flecha, así que crece un poco al pasar por encima. */
.med-abrir-conj {
  width: 22px; height: 22px; margin: 0;
  vertical-align: 0;
}
.med-fila[data-abierto="si"] .med-abrir-conj { transform: none; }
.med-abrir-conj svg { transition: transform .14s ease; }
.med-fila[data-abierto="si"] .med-abrir-conj svg { transform: translateY(1px) scale(1.06); }

/* La chapa, ahora en palabras: «4 dentro». Dice lo que hay, no cómo se llama
   la clase de bulto —eso ya lo dice el icono y la banda—. */
.med-tabla tr.med-padre button.med-caja {
  background: rgba(255,255,255,.14); color: rgba(255,255,255,.92);
}

/* Y el subtítulo, con sus trozos separados de verdad. */
.med-tabla .med-sub {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px;
  margin-top: 2px;
}

/* ═══════════════════════════════════════════════════════════════════════════
   QUIÉN MANDA EN EL CONJUNTO                   (15/10/2026, `.med-madre-*`)

   Xavi: «podemos hacer el material MADRE. Si ya tengo las medidas de la Alexa
   MINI LF Camera Package, que todo lo que diga se meta dentro de ese
   material».

   Así que al juntar ya no se pide un nombre: se elige CUÁL de las cosas
   marcadas hace de bulto. Inventar un artículo nuevo pasa a ser la última
   opción de la lista, no la única.
   ═══════════════════════════════════════════════════════════════════════════ */

.med-madre {
  display: grid; gap: 6px; margin-top: 4px;
  max-height: 200px; overflow: auto;
}
.med-madre-f {
  display: grid; grid-template-columns: 18px minmax(0, 1fr) auto;
  align-items: center; gap: 10px;
  padding: 9px 12px; cursor: pointer;
  border: 1px solid var(--border); background: var(--surface);
}
.med-madre-f:hover { background: var(--bg-hover); }
.med-madre-f.puesta { box-shadow: inset 0 0 0 1px var(--text); }
.med-madre-nuevo { grid-template-columns: 18px minmax(0, 1fr); }
.med-madre-nuevo .med-jun-nombre { grid-column: 2; margin-top: 6px; }
.med-madre-nuevo:not(.puesta) .med-jun-nombre { display: none; }

/* ═══════════════════════════════════════════════════════════════════════════
   LA REJILLA, COMO UNA HOJA DE INVENTARIO     (15/10/2026)

   Xavi: «¿podemos hacerlo más visual? Que la lista parezca súper profesional,
   que se comporte como un gestor súper currado de inventario y que se vea
   como tal».

   Lo que separa una tabla de una REJILLA DE INVENTARIO no es el adorno, son
   cinco cosas que se notan a los diez segundos de usarla:

     1. La cabecera no se va: se queda arriba mientras bajas 781 renglones.
     2. Se ordena por cualquier columna, y lo que no se sabe cae al final.
     3. Los números están en cifras de ancho fijo, así que las columnas se
        leen en vertical y un 1.234,5 no baila respecto al 9,9 de abajo.
     4. Las unidades están UNA vez, en la cabecera. No setecientas.
     5. Lo que falta está en blanco, no lleno de guiones y de «sin medir».
   ═══════════════════════════════════════════════════════════════════════════ */

/* 1 · La cabecera se queda. */
.med-tabla thead th {
  position: sticky; top: 0; z-index: 3;
  background: var(--surface);
  box-shadow: inset 0 -1px 0 var(--text-xsoft);
}

/* 2 · Y se puede pulsar para ordenar. */
.med-th-b {
  display: inline-flex; align-items: baseline; gap: 5px;
  padding: 0; border: 0; background: none; cursor: pointer;
  font: inherit; color: inherit; letter-spacing: inherit; text-transform: inherit;
}
/* (La flecha ya va delante en el HTML de las columnas de números; invertir
   aquí con `row-reverse` dejaba la unidad antes que el nombre: «cm LARGO».) */
.med-th-b:hover { color: var(--text); }
.med-th-b.activa { color: var(--text); font-weight: 700; }
.med-th-b small { opacity: .6; font-size: 9px; }
.med-th-flecha { flex: none; transition: transform .15s ease; }

/* 3 · Cifras de ancho fijo: las columnas se leen en vertical. */
.med-tabla .med-td-num,
.med-tabla .med-td-num .med-in,
.med-tabla .med-firma {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}

/* 5 · Lo que no se sabe se deja en blanco, con una rayita apenas visible para
   que la celda no parezca rota. Setecientos guiones y setecientos «sin medir»
   era la mitad del ruido de esta pantalla. */
.med-vacio { display: inline-block; width: 10px; height: 1px; background: var(--border); vertical-align: middle; }

/* El nombre, en una línea: si no cabe, se corta y se lee entero en el título.
   Un nombre partido en tres renglones rompe la altura de la fila y con ella la
   sensación de rejilla. En la cabecera de un conjunto sí se deja crecer: ahí
   es un titular, no un renglón. */
.med-tabla tr.med-fila:not(.med-padre) .med-nombre {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* Las casillas de escribir, más discretas: en una rejilla de ochocientas
   filas, ochocientos recuadros son ochocientos recuadros. El borde sale al
   pasar por encima o al escribir. */
.med-tabla .med-in {
  border-color: transparent; background: transparent;
  transition: background-color .12s ease, border-color .12s ease;
}
.med-tabla tr:hover .med-in { border-color: var(--border); background: var(--surface); }
.med-tabla .med-in:focus { border-color: var(--text); background: var(--surface); }
.med-tabla tr.med-padre:hover .med-in { border-color: rgba(255,255,255,.22); background: rgba(255,255,255,.10); }

/* El subtítulo, en una línea. Una categoría larga —«Lights / Accessories /
   Grip accessories / Mirrors and Open Ends»— partía la fila en tres renglones
   y con ella la altura de toda la rejilla. */
.med-tabla tr.med-fila:not(.med-padre) .med-sub { flex-wrap: nowrap; }
.med-tabla tr.med-fila:not(.med-padre) .med-sub > span:not(.med-cod) {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}

/* El marco de la rejilla: alto propio y scroll propio, que es lo que hace que
   la cabecera se quede arriba. Sin esto, `position: sticky` no tiene a qué
   agarrarse y la cabecera se va con el resto a los veinte renglones. */
.med-wrap {
  max-height: calc(100vh - 300px);
  min-height: 320px;
  overflow: auto;
  overscroll-behavior: contain;
  border-bottom: 1px solid var(--border);
}

/* «No hace falta»: lo que va dentro de un bulto no se mide. Xavi (15/10/2026):
   «si creamos un conjunto, que todo lo que esté dentro no lleve medidas, solo
   tiene que llevar las medidas el conjunto». Se dice en la columna de la firma
   —donde el ojo pregunta «¿y esto por qué está en blanco?»— y en gris, porque
   no es un aviso: es que ahí no hay trabajo pendiente. */
.med-nofalta {
  font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .04em;
  text-transform: uppercase; color: var(--text-xsoft); cursor: help;
}

/* ═══════════════════════════════════════════════════════════════════════════
   LA LISTA A LA IZQUIERDA, LO DEMÁS A LA DERECHA   (15/10/2026, `.med-lado`)

   Xavi: «podemos hacer que la info se ponga a la derecha y la lista a la
   izquierda, porque así no se ve casi la lista».

   Tenía razón, y en su captura se veía: la franja del rodaje, el bloque grande
   de la cobertura y la rejilla de catorce departamentos se comían la mitad de
   arriba, así que la primera fila de la tabla empezaba a media pantalla. En
   una pantalla que existe para rellenar renglones, eso es el error más caro
   que puede tener.

   Ahora la rejilla manda —arranca donde arranca la página— y todo lo que es
   «cómo va la cosa» se va a un carril de la derecha, estrecho y en vertical.
   ═══════════════════════════════════════════════════════════════════════════ */

.med-lado {
  width: 290px; flex: none; align-self: stretch;
  padding-left: 20px; margin-left: 4px;
  border-left: 1px solid var(--border);
}

/* Cuando se abre la ficha de un artículo, el carril le deja el sitio: son la
   misma pregunta a dos distancias y no caben dos columnas de información a la
   derecha de una rejilla. */
.med-layout.con-drawer .med-lado { display: none; }

/* El bloque de la cobertura, en vertical. */
.med-lado .med-cab { display: block; padding: 0; border: 0; background: none; }
.med-lado .med-cab-izq { margin-bottom: 18px; }
.med-lado .med-cab-der {
  display: grid; grid-template-columns: 1fr; gap: 12px;
  padding-top: 16px; border-top: 1px solid var(--border);
}
.med-lado .med-cifra { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.med-lado .med-cifra span { text-align: right; }

/* Los departamentos, uno debajo de otro: así caben los catorce sin hacer una
   rejilla de tres columnas que no se lee. */
.med-lado .med-deps {
  display: grid; grid-template-columns: 1fr; gap: 0;
  margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--border);
  max-height: 46vh; overflow: auto;
}
.med-lado .med-dep { border: 0; border-bottom: 1px solid var(--border); }
.med-lado .med-dep:last-child { border-bottom: 0; }

/* La franja del rodaje elegido, también en vertical y sin gritar. */
.med-lado .med-proy { display: block; margin-bottom: 18px; }
.med-lado .med-proy .btn { margin-top: 10px; width: 100%; }

/* En pantallas estrechas vuelve a ponerse debajo, que es donde cabe. */
@media (max-width: 1100px) {
  .med-layout { flex-wrap: wrap; }
  .med-lado {
    width: 100%; order: 2; margin: 18px 0 0; padding: 18px 0 0;
    border-left: 0; border-top: 1px solid var(--border);
  }
  .med-lado .med-cab-der { grid-template-columns: repeat(3, 1fr); }
  .med-lado .med-deps { grid-template-columns: repeat(2, 1fr); max-height: none; }
}

/* ── Cambiar el nombre de una línea del presupuesto ───────────────────────── */
/* El lápiz no está siempre encendido: la columna es para leer qué material
   hay, y un icono en cada fila convierte la lista en un panel de botones.
   Aparece al pasar por encima y al llegar con el tabulador. */
.pres-mat-desc { position: relative; }
.pres-mat-lapiz {
  display: inline-flex; align-items: center; justify-content: center;
  margin-left: 6px; padding: 2px 3px; vertical-align: -2px;
  background: none; border: none; border-radius: 0; cursor: pointer;
  color: var(--text-xsoft); opacity: 0;
  transition: opacity var(--transition), color var(--transition), background var(--transition);
}
.pres-mat-desc:hover .pres-mat-lapiz,
.pres-mat-lapiz:focus-visible { opacity: 1; }
.pres-mat-lapiz:hover { color: var(--accent); background: var(--blue-light); }
/* En un móvil o una tableta no hay «pasar por encima»: ahí el lápiz tiene que
   estar puesto, o no hay manera de llegar a él. */
@media (hover: none) {
  .pres-mat-lapiz { opacity: .55; }
}
/* El campo ocupa exactamente lo que ocupaba el texto: al abrirlo la fila no
   se mueve ni empuja a las de al lado. */
.pres-mat-editar {
  width: 100%; padding: 3px 6px;
  font-size: 13px; font-family: inherit; color: var(--text);
  background: var(--surface);
  border: 1px solid var(--accent); border-radius: 0;
  outline: none;
}

/* Los dos botones de una entrada del historial de servicio, juntos y a la
   derecha, debajo del coste. Van en fila y no apilados: son dos y cortos, y
   apilados empujan la entrada a lo alto sin ganar nada. */
.veh-svc-acciones { display: flex; gap: 6px; justify-content: flex-end; margin-top: 6px; }

/* `.form-group` es `display:flex`, y eso gana al `display:none` que el
   navegador le da por su cuenta a un `hidden`: poner `hidden` en un grupo de
   formulario no lo escondía. Y dentro del formulario en panel la regla es
   `.fp .fp-sec .form-group`, que pesa más que cualquier cosa razonable que se
   escriba aquí. El `!important` va solo contra `hidden`, que quiere decir
   exactamente «esto no se ve»: no hay un caso en el que deba perder. */
.form-group[hidden] { display: none !important; }

/* ═══════════════════════════════════════════════════════════════════════════
   FACTURA DE COMPRA DEL MATERIAL  (.mfa*)

   Filas, no cuadrícula: de una factura no hay nada que mirar en miniatura —lo
   que se mira es el nombre, el número y el importe—, y en fila cabe eso sin
   abrir el archivo. La galería de fotos de arriba sí es cuadrícula porque ahí
   la miniatura ES la información.
   ═══════════════════════════════════════════════════════════════════════════ */
.mfa { margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--border); }
.mfa-cab { display: flex; align-items: center; gap: 9px; margin-bottom: 12px; }
.mfa-tit {
  font-size: 11px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--text-soft);
}
.mfa-n {
  padding: 1px 7px; background: var(--mo-neutro-bg);
  font-size: 11px; font-weight: 700; color: var(--text-soft);
}
.mfa-vacio { margin: 0; font-size: 13px; color: var(--text-soft); }

.mfa-lista { display: flex; flex-direction: column; gap: 8px; margin-bottom: 10px; }
.mfa-fila {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 11px 13px;
  background: var(--surface); border: 1px solid var(--border);
}
/* El cuadradito dice de qué tipo es el archivo sin tener que abrirlo. */
.mfa-ico {
  flex: none; width: 34px; padding: 5px 0; text-align: center;
  font: 700 9.5px/1 var(--mono-rotulo, ui-monospace, Menlo, monospace);
  letter-spacing: .06em;
  background: var(--mo-neutro-bg); color: var(--text-soft);
}
.mfa-txt { flex: 1 1 auto; min-width: 0; }
/* El nombre es el botón de abrir: es lo que uno va a pulsar, no el «Ver». */
.mfa-nom {
  display: block; max-width: 100%; padding: 0; text-align: start;
  background: none; border: 0; cursor: pointer;
  font-size: 13.5px; font-weight: 550; color: var(--text);
  overflow-wrap: anywhere;
}
.mfa-nom:hover { color: var(--accent); text-decoration: underline; }
.mfa-datos { margin-top: 3px; font-size: 12px; color: var(--text); font-variant-numeric: tabular-nums; }
.mfa-meta  { margin-top: 2px; font-size: 11.5px; color: var(--text-soft); }
.mfa-editar {
  width: 100%; padding: 3px 6px;
  font-size: 13.5px; font-family: inherit; color: var(--text);
  background: var(--bg); border: 1px solid var(--accent); border-radius: 0; outline: none;
}

.mfa-acciones { flex: none; display: flex; align-items: center; gap: 6px; }
.mfa-lapiz, .mfa-borrar {
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; padding: 0;
  background: none; border: 0; border-radius: 0; cursor: pointer;
  color: var(--text-xsoft);
  transition: color var(--transition), background var(--transition);
}
.mfa-lapiz:hover  { color: var(--accent); background: var(--blue-light); }
.mfa-borrar:hover { color: var(--red); background: rgba(255,59,48,.08); }

/* La zona de soltar, en ancho completo: aquí no compite con miniaturas. */
.mfa-soltar {
  display: flex; align-items: center; gap: 10px;
  padding: 13px 15px; cursor: pointer;
  border: 1px dashed var(--border-med); color: var(--text-soft);
  transition: border-color .16s, color .16s, background .16s;
}
.mfa-soltar:hover, .mfa-soltar.encima { border-color: var(--red); color: var(--text); background: rgba(127,127,127,.05); }
.mfa-soltar.subiendo { opacity: .55; pointer-events: none; }
.mfa-mas { font-size: 20px; line-height: 1; }
.mfa-txt-soltar { font-size: 13px; display: grid; gap: 2px; }
.mfa-txt-soltar small { font-size: 11.5px; opacity: .75; }

@media (max-width: 600px) {
  .mfa-fila { flex-wrap: wrap; }
  .mfa-acciones { width: 100%; justify-content: flex-end; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   ABRIR Y CERRAR UN CONJUNTO, CON MOVIMIENTO        (16/10/2026)

   Xavi: «cuando despliegas cosas o listas o grupos de material, añádele un
   poco de animación, que no sea tan seco».

   Era seco porque abrir repinta la tabla entera y las piezas aparecían de
   golpe. El movimiento dice DE DÓNDE sale lo que acaba de aparecer: baja desde
   la fila del conjunto, una detrás de otra.

   Y CORTO. El primer intento iba a 0,22 s con 22 ms entre filas y Xavi lo paró
   el mismo día: «la animación de los grupos del listado va muy lenta». Tenía
   razón y el motivo es de uso, no de gusto: esto no se mira, se atraviesa —se
   abre una caja para LEER lo que hay dentro, no para ver cómo entra—. Ahora son
   0,12 s y el escalonado entero cabe en 40 ms, así que abrir un conjunto de
   cuarenta piezas termina en menos de dos décimas.

   El escalonado va en `--i`, que lo pone el JavaScript fila a fila y corta a la
   quinta: pasada esa, el retraso solo se nota como espera.
   ═══════════════════════════════════════════════════════════════════════════ */
@keyframes med-entra-fila {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: none; }
}
@keyframes med-sale-fila {
  from { opacity: 1; transform: none; }
  to   { opacity: 0; transform: translateY(-4px); }
}

/* `backwards` y no `both` a propósito: con `both`, una fila que entra mientras
   la pestaña está en segundo plano se queda congelada en el primer fotograma
   —opacidad cero— hasta que alguien vuelve a mirar. Con `backwards`, el
   fotograma inicial solo vale durante la espera del escalonado y, pase lo que
   pase, al terminar la fila se queda con su estilo normal: visible. */
.med-tabla tr.med-entrando {
  animation: med-entra-fila .12s cubic-bezier(.22, .61, .36, 1) backwards;
  animation-delay: calc(var(--i, 0) * 8ms);
}
/* Al cerrar no hay escalonado al revés: las de abajo se van antes, para que el
   bloque parezca que se recoge hacia su conjunto y no que se cae. */
.med-tabla tr.med-plegando {
  animation: med-sale-fila .09s ease-in both;
  pointer-events: none;
}

/* La tapa del bloque acompaña: si se quedara quieta mientras las piezas se
   van, el bloque se cerraría dejando una raya suelta un instante. */
.med-tabla tr.med-conj-fin.med-entrando > td,
.med-tabla tr.med-conj-fin.med-plegando > td { overflow: hidden; }

@media (prefers-reduced-motion: reduce) {
  .med-tabla tr.med-entrando,
  .med-tabla tr.med-plegando { animation: none; }
}

/* ── «ÚLTIMOS AÑADIDOS» ───────────────────────────────────────────────────────
   Mismo botón que «Kits» —se enciende igual— porque hace lo mismo desde el
   punto de vista de quien lo usa: cambia qué estás viendo y se queda puesto
   hasta que lo apagas. Que uno recorte y el otro ordene es cosa nuestra. */
.inv-filtro-nuevos { display: inline-flex; align-items: center; gap: 6px; }
.inv-filtro-nuevos.activo {
  background: var(--accent); color: #fff; border-color: var(--accent);
}
.inv-filtro-nuevos.activo:hover { background: var(--accent); }

/* La fecha de alta, debajo del código y solo con ese orden puesto: es la
   prueba de que la lista está ordenada por lo que dice estarlo. */
.inv-c-alta {
  display: block; margin-top: 2px;
  font-size: 10.5px; letter-spacing: .02em; color: var(--text-xsoft);
}

/* ═══════════════════════════════════════════════════════════════════════════
   LA ETIQUETA DEL CALENDARIO  (.gantt-pista)                 (16/10/2026)

   Tinta sobre la página, como los bloques de conjunto de Medidas y peso: es
   lo que en esta casa quiere decir «esto es una nota que flota por encima, no
   una pieza más de la pantalla». Cuadrada, como todo. La punta de abajo la
   coloca el JavaScript en `--punta` para que señale la barra aunque la nota se
   haya tenido que correr para no salirse por un lado.

   Sale con un fundido de 70 ms y dos píxeles de recorrido. Más que eso y
   barrer el calendario con el ratón se convierte en una lluvia de notas
   entrando y saliendo; menos y aparece de un golpe, que es lo que ya hacía el
   `title` del navegador y era parte de lo que molestaba.
   ═══════════════════════════════════════════════════════════════════════════ */
.gantt-pista {
  position: fixed; z-index: 1200;
  max-width: 300px; padding: 9px 12px 10px;
  background: var(--text); color: var(--bg);
  border-radius: 0;
  box-shadow: 0 6px 22px rgba(0,0,0,.22);
  font-size: 12.5px; line-height: 1.35;
  pointer-events: none;
  /* `backwards`, no `both`: con `both` una nota abierta mientras la pestaña
     está en segundo plano se queda en el primer fotograma —invisible— hasta
     que el reloj de animaciones vuelve a andar. Es el mismo fallo que tuvieron
     las filas de los conjuntos en Medidas y peso. */
  animation: gantt-pista-entra .07s ease-out backwards;
}
.gantt-pista[hidden] { display: none; }
.gantt-pista-tit {
  display: flex; align-items: center; gap: 7px;
  font-weight: 700; font-size: 13px;
}
.gantt-pista-tit i {
  flex: none; width: 9px; height: 9px;
  outline: 1px solid rgba(255,255,255,.35); outline-offset: 1px;
}
.gantt-pista-tit span { overflow-wrap: anywhere; }
.gantt-pista-sub { margin-top: 2px; opacity: .78; }
.gantt-pista-cuando {
  margin-top: 5px;
  font: 600 11px/1 var(--mono-rotulo, ui-monospace, Menlo, monospace);
  letter-spacing: .04em; opacity: .9;
}
/* La punta: un cuadrado girado que asoma por debajo (o por arriba si la nota
   ha tenido que bajar porque no cabía encima). */
.gantt-pista::after {
  content: ''; position: absolute;
  left: var(--punta, 50%); bottom: -5px;
  width: 10px; height: 10px; margin-left: -5px;
  background: var(--text); transform: rotate(45deg);
}
.gantt-pista.abajo::after { bottom: auto; top: -5px; }

@keyframes gantt-pista-entra {
  from { opacity: 0; transform: translateY(2px); }
  to   { opacity: 1; transform: none; }
}
.gantt-pista.abajo { animation-name: gantt-pista-entra-abajo; }
@keyframes gantt-pista-entra-abajo {
  from { opacity: 0; transform: translateY(-2px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .gantt-pista { animation: none; }
}


/* ══════════════════════════════════════════════════════════════════════════
   EL CHAT (public/chat.js). Un botón que flota abajo a la derecha y un
   panel encima, en cualquier página. Las burbujas propias en tinta, las
   de los demás en blanco; las tarjetas de presupuesto y rodaje, vivas.
   ══════════════════════════════════════════════════════════════════════════ */
/* El chat es un PANEL LATERAL a la derecha (17/10/2026, Xavi: «que sea
   más sencillo acceder, como un desplegable siempre en la web a la
   derecha, estés donde estés»). La pestaña vive pegada al canto derecho a
   media altura; al abrir, el panel entra deslizándose y la pestaña se va
   con él, pegada a su borde, así que abrir y cerrar es siempre el mismo
   botón en el mismo sitio. */
.chat-fab {
  position: fixed; right: 0; top: 50%; z-index: 91;
  transform: translateY(-50%);
  width: 40px; min-height: 112px; padding: 14px 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px;
  color: var(--surface); background: var(--text);
  border: 0; border-radius: var(--radius) 0 0 var(--radius);
  box-shadow: var(--shadow-md); cursor: pointer;
  transition: right .22s cubic-bezier(.2,.8,.2,1), background .16s ease, color .16s ease;
}
.chat-fab:hover { background: var(--text-2); }
/* La pestaña del chat va fija sobre el canto derecho: el contenido le deja
   su sitio para que no tape nada (18/10/2026, tapaba la tarjeta de flota). */
.main-scroll { padding-right: 70px; }
@media (max-width: 520px) { .main-scroll { padding-right: 52px; } }
.chat-fab svg { width: 20px; height: 20px; }
.chat-fab-texto { writing-mode: vertical-rl; transform: rotate(180deg); font-size: 11px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; }
.chat-fab[aria-expanded="true"] { right: 420px; background: var(--surface); color: var(--text); border: 1px solid var(--border-med); border-right: 0; box-shadow: none; }
.chat-globo {
  position: absolute; top: -6px; left: -8px;
  min-width: 19px; height: 19px; padding: 0 5px;
  display: grid; place-items: center;
  font-size: 11px; font-weight: 700; line-height: 1;
  color: #fff; background: var(--blue);
  border: 2px solid var(--bg); border-radius: 999px;
}
.chat-panel {
  position: fixed; right: 0; top: 0; bottom: 0; z-index: 90;
  width: 420px; max-width: 100vw;
  display: flex; flex-direction: column;
  background: var(--bg);
  border-left: 1px solid var(--border-med);
  box-shadow: var(--shadow-md); overflow: hidden;
  animation: chatEntra .22s cubic-bezier(.2,.8,.2,1);
}
@keyframes chatEntra { from { transform: translateX(100%); } to { transform: translateX(0); } }
.chat-cab {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 12px; background: var(--surface);
  border-bottom: 2px solid var(--text);
}
.chat-cab-tit { flex: 1; min-width: 0; font-weight: 700; font-size: 17px; color: var(--text); display: flex; align-items: center; gap: 8px; }
.chat-cab-hilo > span { display: flex; flex-direction: column; min-width: 0; }
.chat-cab-nombre { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.chat-cab-sub { font-size: 11px; font-weight: 500; color: var(--text-soft); }
.chat-cab-n { font-size: 11px; font-weight: 600; color: var(--blue); letter-spacing: .04em; text-transform: uppercase; }
.chat-cab-acc { display: flex; gap: 4px; }
.chat-ico {
  width: 34px; height: 34px; padding: 0; display: grid; place-items: center;
  color: var(--text-2); background: transparent; border: 0; border-radius: var(--radius); cursor: pointer;
}
.chat-ico:hover { background: var(--surface-2); color: var(--text); }
.chat-lista { flex: 1; overflow: auto; padding: 8px; display: flex; flex-direction: column; gap: 2px; }
.chat-fila {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  padding: 8px 10px; background: var(--surface); border: 0; border-radius: var(--radius);
  cursor: pointer; color: var(--text); font: inherit;
}
.chat-fila:hover { background: var(--surface-2); }
.chat-fila-quieta { cursor: default; }
.chat-fila-cuerpo { flex: 1; min-width: 0; }
.chat-fila-arriba, .chat-fila-abajo { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.chat-fila-nombre { font-weight: 600; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.chat-fila-nl .chat-fila-nombre { font-weight: 700; }
.chat-fila-hora { font-size: 11px; color: var(--text-soft); flex: 0 0 auto; }
.chat-fila-nl .chat-fila-hora { color: var(--blue); }
.chat-fila-ult { font-size: 13px; color: var(--text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.chat-suave { color: var(--text-soft); }
.chat-globo-fila { flex: 0 0 auto; min-width: 20px; height: 20px; padding: 0 6px; display: grid; place-items: center; font-size: 11px; font-weight: 700; color: #fff; background: var(--blue); border-radius: 999px; }
.chat-avatar {
  flex: 0 0 auto; display: grid; place-items: center; object-fit: cover;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; font-weight: 600;
  color: var(--text-2); background: var(--surface-2); border-radius: 999px;
}
.chat-avatar-grupo svg { width: 45%; height: 45%; }
.chat-vacio { padding: 28px 16px; text-align: center; color: var(--text-2); font-size: 13px; display: flex; flex-direction: column; gap: 10px; align-items: center; }
.chat-vacio-tit { font-weight: 700; font-size: 16px; color: var(--text); }
.chat-vacio-hilo { margin: auto; }
.chat-msgs { flex: 1; overflow: auto; padding: 12px; display: flex; flex-direction: column; gap: 4px; }
.chat-dia { align-self: center; margin: 10px 0 6px; font-size: 10px; letter-spacing: .08em; text-transform: uppercase; color: var(--text-soft); }
.chat-m { display: flex; flex-direction: column; align-items: flex-start; max-width: 85%; margin-top: 8px; }
.chat-m-sigue { margin-top: 0; }
.chat-m-mia { align-self: flex-end; align-items: flex-end; }
.chat-m-autor { font-size: 11px; color: var(--text-2); margin: 0 4px 2px; }
.chat-burbuja {
  padding: 8px 12px; font-size: 14px; line-height: 1.35; color: var(--text);
  background: var(--surface); border-radius: 18px; word-break: break-word;
}
.chat-m-mia .chat-burbuja { color: var(--bg); background: var(--text); }
.chat-m-pie { display: flex; align-items: center; gap: 4px; margin: 2px 4px 0; font-size: 10px; color: var(--text-soft); }
.chat-visto { display: inline-grid; place-items: center; color: var(--text-soft); }
.chat-visto-si { color: var(--blue); }
.chat-borrar { display: none; padding: 0; border: 0; background: transparent; color: var(--text-soft); cursor: pointer; }
.chat-m:hover .chat-borrar { display: inline-grid; }
.chat-tarjeta {
  width: 260px; text-align: left; padding: 10px 12px; margin-bottom: 4px; font: inherit; color: var(--text);
  background: var(--surface); border: 1px solid var(--border-med); border-radius: 12px; cursor: pointer;
  display: flex; flex-direction: column; gap: 4px;
}
.chat-tarjeta:hover { border-color: var(--text); }
.chat-tarjeta-muerta { cursor: default; color: var(--text-2); font-size: 13px; }
.chat-tarjeta-cab { display: flex; justify-content: space-between; align-items: center; font-size: 10px; letter-spacing: .08em; color: var(--text-2); }
.chat-tarjeta-cab > span:first-child { display: inline-flex; align-items: center; gap: 5px; }
.chat-tarjeta-num { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 14px; }
.chat-tarjeta-nombre { font-family: inherit; font-weight: 700; }
.chat-tarjeta-sub { font-size: 12px; color: var(--text-2); }
.chat-tarjeta-pie { display: flex; justify-content: space-between; align-items: baseline; font-size: 13px; }
.chat-abrir { color: var(--blue); font-size: 12px; font-weight: 600; }
.chat-pastilla { font-size: 10px; letter-spacing: .06em; text-transform: uppercase; padding: 2px 7px; border-radius: 999px; background: var(--surface-2); color: var(--text-2); }
.chat-pastilla-aceptado { color: #1d7a4a; background: rgba(29,122,74,.12); }
.chat-pastilla-enviado { color: #b7791f; background: rgba(183,121,31,.12); }
.chat-pastilla-rechazado, .chat-pastilla-caducado { color: var(--blue); background: rgba(239,35,60,.1); }
.chat-punto { display: inline-block; width: 8px; height: 8px; border-radius: 999px; }
.chat-foto img { display: block; max-width: 240px; max-height: 240px; border-radius: 12px; margin-bottom: 4px; }
.chat-redactor { background: var(--surface); border-top: 1px solid var(--border-med); padding: 8px; }
.chat-redactor-fila { display: flex; align-items: flex-end; gap: 6px; }
.chat-texto {
  flex: 1; resize: none; max-height: 120px; padding: 8px 12px; font: inherit; font-size: 14px; color: var(--text);
  background: var(--surface-2); border: 0; border-radius: 18px; outline: none;
}
.chat-enviar { width: 36px; height: 36px; padding: 0; display: grid; place-items: center; color: #fff; background: var(--blue); border: 0; border-radius: 999px; cursor: pointer; }
.chat-enviar:disabled { background: var(--text-soft); cursor: default; }
.chat-mas-wrap { position: relative; }
.chat-mas-menu { position: absolute; bottom: calc(100% + 6px); left: 0; z-index: 2; min-width: 180px; padding: 4px; background: var(--surface); border: 1px solid var(--border-med); border-radius: var(--radius); box-shadow: var(--shadow-md); display: flex; flex-direction: column; }
.chat-mas-menu button { display: flex; align-items: center; gap: 8px; padding: 8px 10px; text-align: left; font: inherit; font-size: 13px; color: var(--text); background: transparent; border: 0; border-radius: var(--radius); cursor: pointer; }
.chat-mas-menu button:hover { background: var(--surface-2); }
.chat-adjunto-prev { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 6px; }
.chat-chip { display: inline-flex; align-items: center; gap: 6px; max-width: 100%; padding: 4px 4px 4px 8px; font-size: 12px; color: var(--text); background: var(--surface-2); border: 1px solid var(--border-med); border-radius: 999px; }
.chat-chip > span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 200px; }
.chat-chip img { width: 22px; height: 22px; object-fit: cover; border-radius: 999px; }
.chat-chip svg { flex: 0 0 auto; color: var(--text-2); }
.chat-chip button { width: 22px; height: 22px; padding: 0; display: grid; place-items: center; color: var(--text-2); background: transparent; border: 0; border-radius: 999px; cursor: pointer; }
.chat-chip button:hover { background: var(--border-med); color: var(--text); }
.chat-chip-subiendo { color: var(--text-2); }
.chat-chip-rueda { width: 14px; height: 14px; border: 2px solid var(--border-med); border-top-color: var(--text); border-radius: 999px; animation: chatGira .8s linear infinite; }
@keyframes chatGira { to { transform: rotate(360deg); } }
/* Lo que se ve al arrastrar un archivo encima del panel. */
.chat-soltar { position: absolute; inset: 0; z-index: 3; display: none; flex-direction: column; align-items: center; justify-content: center; gap: 10px; font-size: 14px; font-weight: 600; color: var(--text); background: color-mix(in srgb, var(--bg) 88%, transparent); border: 2px dashed var(--text); pointer-events: none; }
.chat-soltar svg { width: 32px; height: 32px; }
.chat-soltar-si { display: flex; }
.chat-elegir { display: flex; flex-direction: column; gap: 8px; height: 100%; }
.chat-elegir-cab { display: flex; align-items: center; justify-content: space-between; font-size: 14px; color: var(--text); }
.chat-elegir-lista { flex: 1; overflow: auto; display: flex; flex-direction: column; gap: 2px; }
.chat-busca, .chat-select { width: 100%; padding: 9px 12px; font: inherit; font-size: 14px; color: var(--text); background: var(--surface); border: 1px solid var(--border-med); border-radius: var(--radius); outline: none; box-sizing: border-box; }
.chat-modos { display: flex; gap: 2px; padding: 8px 8px 0; }
.chat-modo { flex: 1; padding: 7px 4px; font: inherit; font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--text-2); background: transparent; border: 0; border-bottom: 2px solid transparent; cursor: pointer; }
.chat-modo-si { color: var(--text); border-bottom-color: var(--blue); }
.chat-nuevo-cuerpo { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: 8px; padding: 8px; }
.chat-lista-nuevo { padding: 0; }
.chat-nuevo-pie { padding-top: 4px; }
.chat-check { flex: 0 0 auto; width: 18px; height: 18px; border: 1.5px solid var(--text-soft); border-radius: 999px; }
.chat-check-si { border-color: var(--blue); background: var(--blue); box-shadow: inset 0 0 0 3px var(--surface); }
@media (max-width: 520px) {
  .chat-panel { width: 100vw; }
  .chat-fab[aria-expanded="true"] { right: 0; z-index: 92; top: 12px; transform: none; min-height: 0; padding: 8px 0; border-radius: var(--radius) 0 0 var(--radius); }
  .chat-fab[aria-expanded="true"] .chat-fab-texto { display: none; }
}
