/* Overrides Tailwind / polish */

/* V2.15e (C1) — l'espace de la scrollbar verticale est TOUJOURS réservé :
   sans ça, le contenu centré (max-w-7xl) se décale horizontalement entre une
   page courte (pas de scrollbar) et une page longue (scrollbar) → «glissement»
   perçu entre navigations. */
html { scrollbar-gutter: stable; }

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: #D4C9B8; border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: #A89F92; }
::-webkit-scrollbar-track { background: transparent; }

input[type=number] { font-variant-numeric: tabular-nums; }
input[type=search]::-webkit-search-cancel-button { cursor: pointer; }

.htmx-request { opacity: 0.6; }
.htmx-request.htmx-indicator { opacity: 1; }

/* ── V2.15e (C2) — indicador global de carga (rond fin qui tourne) ──────────
   Décision Théo : «un simple rond qui tourne, classique, assez fin et design».
   Affiché par app.js pendant les requêtes HTMX ; le transition-delay de 300 ms
   fait office d'anti-flash (une réponse rapide repasse opacity:0 avant la fin
   du délai → l'utilisateur ne voit rien). */
#indicador-global {
  position: fixed;
  top: 0.9rem;
  right: 0.9rem;
  z-index: 9998;
  width: 1.4rem;
  height: 1.4rem;
  border-radius: 9999px;
  border: 2.5px solid rgba(30, 38, 64, 0.14);   /* indigo pâle */
  border-top-color: #C68B3C;                    /* ocre */
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease;
}
#indicador-global.htmx-request {
  opacity: 1;
  transition-delay: 0.3s;
  animation: giro-indicador 0.8s linear infinite;
}
@keyframes giro-indicador { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  #indicador-global.htmx-request { animation: none; border-color: rgba(30, 38, 64, 0.35); }
}

/* ── V2.15e (C3) — splash de arranque : jean → chamarra (flip 3D) ───────────
   Affiché UNE FOIS par session par le script inline du partial splash.html
   (sessionStorage + prefers-reduced-motion). Caché par défaut : un revisiteur
   ne voit RIEN même avant l'exécution du script. Timeline ~2 s :
   0.00-0.30 s fondu d'entrée · 0.30-1.55 s flip pantalon→veste ·
   1.30-1.90 s wordmark · 2.00 s fondu de sortie (JS). */
#splash-ruberts {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.75rem;
  background: radial-gradient(circle at 50% 38%, #2A3556 0%, #1E2640 58%, #10152A 100%);
  opacity: 1;
  transition: opacity 0.5s ease;
}
#splash-ruberts.splash-activo { display: flex; }
#splash-ruberts.splash-saliendo { opacity: 0; pointer-events: none; }

.splash-escena { perspective: 900px; width: 132px; height: 165px; }
.splash-flip {
  position: relative;
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
  animation: splash-giro 1.25s cubic-bezier(0.55, 0.06, 0.28, 1) 0.3s both;
  filter: drop-shadow(0 14px 30px rgba(0, 0, 0, 0.45));
}
.splash-cara {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}
.splash-cara--veste { transform: rotateY(180deg); }
@keyframes splash-giro {
  0%   { transform: rotateY(0deg) scale(0.9); }
  100% { transform: rotateY(180deg) scale(1); }
}

.splash-marca { text-align: center; animation: splash-marca-in 0.6s ease 1.3s both; }
.splash-nombre {
  font-family: 'Space Grotesk', system-ui, sans-serif;
  font-weight: 700;
  font-size: 1.9rem;
  letter-spacing: 0.01em;
  color: #F5F0E8;
  line-height: 1.1;
}
.splash-nombre span { color: #C68B3C; }
.splash-tagline {
  margin-top: 0.35rem;
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.35em;
  color: rgba(245, 240, 232, 0.55);
}
@keyframes splash-marca-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Ceinture + bretelles : si l'OS refuse les animations, le splash n'existe pas
   (le script le retire), et même si le JS échouait il resterait invisible. */
@media (prefers-reduced-motion: reduce) {
  #splash-ruberts { display: none !important; }
}

/* ── V0.3 Toast notifications ────────────────────────────────────── */
.toast-container {
  position: fixed;
  bottom: 1.5rem;
  right: 1.5rem;
  z-index: 9999;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  pointer-events: none;
  max-width: calc(100vw - 3rem);
}
.toast {
  background: #1A1A1A;
  color: #F5F0E8;
  padding: 0.7rem 1rem;
  border-radius: 0.375rem;
  font-size: 0.85rem;
  font-weight: 500;
  box-shadow: 0 6px 24px -4px rgba(0,0,0,.35);
  border-left: 4px solid #6B7B8C;
  transform: translateX(20px);
  opacity: 0;
  transition: transform .3s ease, opacity .3s ease;
  pointer-events: auto;
  min-width: 260px;
  max-width: 380px;
}
.toast-visible { transform: translateX(0); opacity: 1; }
.toast-success { border-left-color: #16A34A; }
.toast-error   { border-left-color: #DC2626; }
.toast-warning { border-left-color: #D97706; }
.toast-info    { border-left-color: #2563EB; }

/* ── V0.3 SortableJS drag&drop visuels ────────────────────────────── */
.sortable-ghost {
  opacity: 0.35;
  background: #EBE3D4 !important;
}
.sortable-drag {
  cursor: grabbing;
  box-shadow: 0 14px 40px -8px rgba(0,0,0,.35) !important;
  transform: rotate(-1.5deg);
}
.kanban-card-handle { cursor: grab; }
.kanban-card-handle:active { cursor: grabbing; }
.kanban-col-body.drag-over {
  background: rgba(198, 139, 60, 0.07);
  border-radius: 0.5rem;
}

/* ── V0.3 Lista style Excel ───────────────────────────────────────── */
.tbl-excel {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.8rem;
}
.tbl-excel thead {
  background: #1E2640;
  color: #F5F0E8;
  position: sticky;
  top: 0;
  z-index: 5;
}
.tbl-excel th {
  padding: 0.55rem 0.7rem;
  text-align: left;
  font-weight: 600;
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  border-right: 1px solid rgba(255,255,255,0.08);
  white-space: nowrap;
}
.tbl-excel tbody tr {
  border-bottom: 1px solid #EBE3D4;
  transition: background .15s ease;
}
.tbl-excel tbody tr:nth-child(even) { background: #FAF7F0; }
.tbl-excel tbody tr:hover { background: #FFF6E0; }
.tbl-excel td {
  padding: 0.45rem 0.7rem;
  border-right: 1px solid #EBE3D4;
  white-space: nowrap;
}
.tbl-excel td.col-num { font-family: 'JetBrains Mono', monospace; }
.tbl-excel .sla-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.15rem 0.4rem;
  border-radius: 9999px;
  font-size: 0.7rem;
  font-weight: 600;
  font-family: 'JetBrains Mono', monospace;
}
.tbl-excel .sla-verde   { background: #DCFCE7; color: #166534; }
.tbl-excel .sla-naranja { background: #FED7AA; color: #9A3412; }
.tbl-excel .sla-rojo    { background: #FECACA; color: #991B1B; }
.tbl-excel .sla-gris    { background: #E5E7EB; color: #475569; }

/* ── V0.3 Cloche notifications dropdown ───────────────────────────── */
.notif-dropdown {
  position: absolute;
  top: calc(100% + 0.5rem);
  right: 0;
  width: 22rem;
  max-width: calc(100vw - 2rem);
  background: white;
  border: 1px solid #EBE3D4;
  border-radius: 0.5rem;
  box-shadow: 0 18px 50px -8px rgba(0,0,0,.25);
  z-index: 50;
  max-height: 70vh;
  overflow-y: auto;
}
/* V0.7 (hotfix) — cloche dans le cadre profil (bas de sidebar) : le dropdown
   s'ouvre vers la DROITE de la cloche, aligné en bas (ne sort pas par le bas). */
.notif-dd-sidebar .notif-dropdown {
  top: auto;
  bottom: 0;
  left: calc(100% + 0.5rem);
  right: auto;
  width: 20rem;
  max-width: calc(100vw - 5rem);
}
.notif-item {
  padding: 0.65rem 0.85rem;
  border-bottom: 1px solid #F5F0E8;
  display: block;
  text-decoration: none;
  color: inherit;
  transition: background .15s ease;
}
.notif-item:hover { background: #FAF7F0; }
.notif-item.is-unread { background: #FFF6E0; }
.notif-badge {
  position: absolute;
  top: -0.25rem;
  right: -0.25rem;
  background: #DC2626;
  color: white;
  font-size: 0.65rem;
  font-weight: 700;
  border-radius: 9999px;
  padding: 0.05rem 0.35rem;
  min-width: 1.1rem;
  text-align: center;
  line-height: 1.1;
}
[x-cloak] { display: none !important; }

/* ── V2.9 (récupération V2.7) — workflow steps : PAS de line-through, animation check-pop ── */
.workflow-step--completado .step-label { color: rgb(75, 85, 99); text-decoration: none !important; }
.workflow-step--completado { background: rgba(34, 197, 94, 0.05); }
.workflow-step--en_curso { background: rgba(99, 102, 241, 0.08); border-left: 3px solid rgb(99, 102, 241); }
.workflow-step--atrasado { background: rgba(239, 68, 68, 0.06); border-left: 3px solid rgb(239, 68, 68); }

@keyframes check-pop {
  0%   { transform: scale(0) rotate(-45deg); opacity: 0; }
  50%  { transform: scale(1.3) rotate(0deg); opacity: 1; }
  100% { transform: scale(1) rotate(0deg); opacity: 1; }
}
.check-pop-in { animation: check-pop 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) forwards; }

@keyframes glow-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(34, 197, 94, 0); }
  50%      { box-shadow: 0 0 0 8px rgba(34, 197, 94, 0.18); }
}
.glow-success { animation: glow-pulse 1.2s ease-out; }

/* Badges retard cumulé (V2.9 vague 2) — gravité low/medium/high */
.badge-retard { display: inline-flex; align-items: center; gap: 0.2rem; font-size: 0.7rem; font-weight: 700;
  border-radius: 9999px; padding: 0.1rem 0.45rem; line-height: 1.1; white-space: nowrap; }
.badge-retard--low    { background: rgb(254, 243, 199); color: rgb(146, 64, 14); }
.badge-retard--medium { background: rgb(255, 237, 213); color: rgb(154, 52, 18); }
.badge-retard--high   { background: rgb(254, 226, 226); color: rgb(153, 27, 27); animation: glow-pulse 1.6s ease-out infinite; }

/* ══ V2.17 (design Nora) ═══════════════════════════════════════════════════
   Avatar, liens cliquables dans les réponses, repli des longues listes et
   animations Lottie. Tout est ici (et non dans un <style> de page) parce que
   ces éléments vivent sur /nora, sur le dashboard et sur /entregas. */

/* Avatar de Nora — ⚠️ DÉCOR SEULEMENT (V2.17c).
   La géométrie (position, taille, cercle, recadrage) vit EN LIGNE dans la macro
   `nora/_avatar.html` : ces règles-ci ont été absentes des navigateurs pendant
   une semaine (cache statique de 7 jours sans cache-buster) et l'avatar s'est
   décomposé en prod — étoile de repli et illustration empilées. Un composant
   d'identité ne doit pas dépendre de l'arrivée d'une feuille de style.
   Ce qui reste ici est purement cosmétique : si ça manque, rien ne casse. */
.nora-avatar {
  background: #F5F0E8; box-shadow: inset 0 0 0 1px rgba(30, 38, 64, 0.10);
}
.nora-avatar-fallback { color: #C68B3C; }

/* Débordement : un code sans séparateur (TELA-MEZCLILLA-E2E-2-2) doit casser. */
.nora-wrap { overflow-wrap: anywhere; word-break: break-word; }

/* Liens vers les fichas — discrets : même couleur que le texte, soulignés au
   survol. Une réponse pleine de liens bleus serait illisible. */
.nora-enlace {
  color: inherit; text-decoration: underline;
  text-decoration-color: rgba(198, 139, 60, 0.45);
  text-underline-offset: 2px; border-radius: 2px;
  transition: color 120ms ease, text-decoration-color 120ms ease;
}
.nora-enlace:hover { color: #1E2640; text-decoration-color: #C68B3C; }
.nora-enlace:focus-visible { outline: 2px solid #C68B3C; outline-offset: 1px; }

/* Repli des longues listes : « Ver más » / « Ver menos » en CSS pur (aucun JS,
   donc jamais de contenu bloqué caché si Alpine ne charge pas). */
.nora-mas > summary { list-style: none; cursor: pointer; }
.nora-mas > summary::-webkit-details-marker { display: none; }
.nora-mas > summary .nora-mas-cerrar { display: none; }
.nora-mas[open] > summary .nora-mas-abrir { display: none; }
.nora-mas[open] > summary .nora-mas-cerrar { display: inline; }

/* Indicateur « Nora está consultando… » — repli si Lottie n'est pas chargé. */
.nora-puntos > span {
  width: .375rem; height: .375rem; border-radius: 9999px;
  background-color: #C46B3E; display: inline-block;
  animation: nora-latido 1.2s infinite ease-in-out;
}
.nora-puntos > span:nth-child(2) { animation-delay: .16s; }
.nora-puntos > span:nth-child(3) { animation-delay: .32s; }
@keyframes nora-latido {
  0%, 80%, 100% { opacity: .25; transform: translateY(0); }
  40%           { opacity: 1;   transform: translateY(-2px); }
}

/* V2.17b — transition « consultando → réponse ». Le fragment inséré par HTMX
   attend que l'indicateur ait été visible au moins `DELAI_MIN_MS` (chat.html) :
   `display:none` (et non `opacity`) pour qu'il ne pousse rien pendant l'attente,
   puis une apparition très courte. Sans JS, aucune de ces classes n'est posée —
   la réponse s'affiche normalement (skill frontend-ui §8). */
.nora-oculto { display: none !important; }
.nora-aparece { animation: nora-aparecer 180ms ease-out both; }
@keyframes nora-aparecer {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: none; }
}

/* Conteneur d'une animation Lottie : l'animation se pose sur le repli statique
   (icône/points), qui reste visible tant qu'elle n'a pas démarré. */
.lottie-caja { position: relative; display: inline-flex; align-items: center; justify-content: center; }
.lottie-caja > .lottie-anim { position: absolute; inset: 0; }
.lottie-caja.lottie-lista > .lottie-repli { visibility: hidden; }

@media (prefers-reduced-motion: reduce) {
  .nora-puntos > span { animation: none; opacity: .6; }
  .nora-enlace { transition: none; }
  .nora-aparece { animation: none; }
}

/* ═══ Sprint A (A6) — cibles tactiles ═══════════════════════════════════════
   Références : 44×44 px (Apple HIG) · 24×24 px minimum (WCAG 2.2 AA, 2.5.8).
   Mesuré AVANT (Chromium headless, 390 px) : cases à cocher 13×13 px sur
   /materias-primas (35 cibles < 32 px) et /subcontratistas (153), « Editar » /
   « Desactivar » à 33×16 et 62×16 px sur /admin/parametros, « leída / borrar »
   à 20×16 px sur /notificaciones. Écrans d'atelier, doigts, écran de 6 pouces.

   Deux niveaux :
   1) les cases à cocher grossissent PARTOUT (13 px n'est visible nulle part) ;
   2) `.tap` porte la zone de tap à 40 px — UNIQUEMENT sous md: (768 px), pour
      ne pas gonfler les lignes de tableau sur un écran de bureau. La zone
      s'étend autour du libellé : l'aspect visuel ne change pas, la surface si. */
input[type="checkbox"], input[type="radio"] { width: 1.05rem; height: 1.05rem; }

.tap { display: inline-flex; align-items: center; }

/* `pointer: coarse` autant que la largeur : un téléphone en PAYSAGE fait
   844 px de large — une règle purement en max-width le raterait. */
@media (max-width: 767px), (pointer: coarse) {
  input[type="checkbox"], input[type="radio"] { width: 1.4rem; height: 1.4rem; }
  .tap { min-height: 40px; min-width: 40px; justify-content: center; }
  .tap-izq { justify-content: flex-start; }
  /* champ de saisie (prix inline /materias-primas : 96×30 px mesurés) */
  .tap-campo { min-height: 40px; }
}
