/* ================================================================
   CAPA RESPONSIVE / MÓVIL — HORES_SEMANALS
   Se carga SIEMPRE DESPUÉS de app.css: a igualdad de especificidad
   gana esta hoja, así que aquí no hace falta !important salvo para
   pisar estilos en línea o reglas ya marcadas como !important.

   Tres cortes, y ninguno más. Cada uno responde a un problema DISTINTO,
   y por eso no coinciden — no intentes unificarlos:
     · 1100px  la CUADRÍCULA deja de caber como tabla y pasa a TARJETAS.
               Medido: la tabla de 10 columnas tiene un ancho mínimo real
               de 821px, y por debajo de ~1053px de ventana `.grid-wrap`
               ya no se lo da y `overflow: clip` se come Observaciones sin
               ninguna barra de scroll que lo delate. Aquí también se
               relajan el rail y los KPIs.
     ·  900px  la BARRA LATERAL deja de caber fija y pasa a cajón (drawer)
               con barra superior propia. Es otro problema y otro ancho.
     ·  560px  móvil estrecho: se aprieta tipografía y espaciado.

   Y dos consultas por CAPACIDAD, que no son "tamaño de pantalla":
     · (pointer: coarse)  dedo => objetivos de 40px y nada de hover.
     · (hover: none)      no hay ratón => todo lo que se revelaba al
                          pasar por encima tiene que estar SIEMPRE visible.
   ================================================================ */

/* ================================================================
   0 · CIMIENTOS — valen en cualquier tamaño
================================================================ */

/* 100vh miente en móvil: no descuenta la barra de direcciones del navegador,
   así que un contenedor a 100vh queda cortado por abajo. dvh sí la sigue. */
@supports (height: 100dvh) {
  .sidebar { height: 100dvh; }
}

/* Nada de la app debe provocar scroll horizontal de la PÁGINA. Los textos
   largos sin espacios (rutas, correos, códigos) son la causa habitual. */
.pf-txt, .pf-sub, .notif-msg, .cb-t, .cb-s,
.cli-row-name, .oc2-name, .od-row-val, .an-empty { overflow-wrap: anywhere; }

/* La barra superior móvil y el velo del cajón sólo existen por debajo de 900px.
   Fuera de ahí no ocupan ni pintan nada. */
.appbar, .nav-scrim { display: none; }

/* ================================================================
   1 · TÁCTIL — sin ratón no hay "pasar por encima"
   Toda la cuadrícula esconde controles tras :hover. En un dedo eso
   equivale a "no existen": aquí se hacen permanentes.
================================================================ */
@media (hover: none) {
  table.grid .rowsel,
  table.grid .daysel { opacity: 1; }
  .dur-btns { opacity: 1; pointer-events: auto; }
  /* El pie de la cuadrícula son sólo atajos de teclado: sin teclado, ruido. */
  .footnote { display: none; }
  /* El asa de arrastrar usa drag&drop HTML5, que no existe en táctil. Se oculta
     y el movimiento entre días se hace con la fecha de la fila, con la ventana
     de edición o con la selección múltiple ("Mover a…"), que sí funcionan. */
  .grip { display: none !important; }
  .dayempty-hint { display: none; }
}

/* Objetivos de pulsación: 40px reales. Debajo de eso el dedo falla. */
@media (pointer: coarse) {
  .iconbtn { min-width: 38px; min-height: 38px; padding: 8px; font-size: 16px; }
  /* flex:0 0 auto además del ancho: `.weeknav` es flex y el título le comía el sitio,
     así que las flechas de semana se encogían a 23px pese a tener width:42px —
     `width` no impide que un elemento flexible se encoja, `flex-shrink: 0` sí. */
  .ic-btn { width: 42px; height: 42px; flex: 0 0 auto; }
  .issues-chip { min-height: 38px; padding: 8px 14px; }
  .btn { padding: 11px 16px; }
  .btn.sm { padding: 10px 14px; font-size: 13.5px; }
  .side-nav button { padding: 13px 12px; }
  table.grid input[type=checkbox] { width: 20px; height: 20px; }
  .durb { width: 30px; height: 30px; font-size: 15px; border-radius: 8px; }
  .dur-btns { flex-direction: row; gap: 4px; }
  .quick { padding: 13px 12px; }
  .cmdk-item { padding: 12px 10px; }
  .an-preset { padding: 9px 13px; }
  .pm-tab { padding: 14px 13px; }
  .modal-hd .iconbtn, .pm-x { min-width: 38px; min-height: 38px; }
  /* Elegir a quién incluir en el Excel: la fila entera es la zona de pulsación
     (es un <label>), así que se le da el alto del dedo y una casilla que se vea. */
  .xl-row { min-height: 44px; padding: 11px 10px; }
  .xl-row input[type=checkbox] { width: 20px; height: 20px; }
}

/* ================================================================
   2 · ≤1100px — LA CUADRÍCULA DEJA DE SER UNA TABLA
   Medido, no estimado: la tabla de 10 columnas tiene un ancho mínimo
   real de 821px y `.grid-wrap` sólo le ofrece (ventana − barra lateral
   − márgenes). Por debajo de ~1053px de ventana no cabe y `overflow:
   clip` se COME las últimas columnas: Observaciones deja de existir sin
   ninguna barra de scroll que lo delate. Y bastante antes de eso ya es
   inservible (Cliente a 63px). Por eso el corte va aquí y no en 900:
   entre 901 y 1053 había una banda con columnas inalcanzables.

   Este corte es INDEPENDIENTE del de la barra lateral (900px): que la
   cuadrícula no quepa como tabla y que la barra lateral no quepa fija
   son dos problemas distintos y ocurren a anchos distintos.
================================================================ */
@media (max-width: 1100px) {

  /* ---- 2.0 El shell se relaja ---- */
  .shell { grid-template-columns: 200px 1fr; }
  .workspace { padding: 16px 16px 32px; }
  .kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .kpis .kcard:last-child { grid-column: 1 / -1; }
  .an-hero-value { font-size: 42px; }

  /* ---- 2.1 CUADRÍCULA => TARJETAS ---------------------------------
     Una tabla de 10 columnas no cabe. Cada tramo pasa a ser una tarjeta
     con la misma información y los mismos campos (los inputs son los
     mismos nodos: NO hay una segunda plantilla que mantener, sólo cambia
     el display). Las etiquetas salen del atributo data-l de cada celda. */
  .grid-wrap { border-radius: 12px; }
  table.grid, table.grid tbody { display: block; width: 100%; }
  table.grid thead { display: none; }               /* las cabeceras las da data-l */

  table.grid tbody tr.entry {
    display: grid;
    grid-template-columns: 26px minmax(0,1fr) minmax(0,1fr) auto;
    grid-template-areas:
      "sel  date  date  act"
      ".    start end   tot"
      "cli  cli   cli   cli"
      "proj proj  proj  proj"
      "task task  task  task"
      "note note  note  note";
    gap: 6px 8px; align-items: center;
    padding: 12px 12px 14px; margin: 0;
    border-bottom: 8px solid var(--bg-soft);
  }
  /* width:auto es OBLIGATORIO. app.css fija el ancho de cada columna (.c-cli 160px,
     .c-date 116px, .c-time 66px…) para la tabla de escritorio, y un elemento de rejilla
     con ancho propio NO se estira a su celda: las tarjetas salían con el cliente a 160px
     y las horas descolocadas dentro de columnas de 147px. */
  table.grid tbody tr.entry td {
    display: block; height: auto; padding: 0; border: 0; width: auto; min-width: 0;
  }
  /* app.css fija el padding del asa con !important (columna de 42px en tabla);
     en tarjeta esa celda es sólo la casilla de selección. */
  table.grid tbody tr.entry td.c-grip { padding: 0 !important; }
  /* El asa arrastra con drag&drop HTML5: en una lista de tarjetas donde los días
     son cabeceras pegajosas no hay destino fiable al que soltar. Fuera.
     El selector repite el de app.css (`table.grid td.c-grip .grip`) porque allí lleva
     display:inline-block y con menos especificidad no se le gana. */
  table.grid td.c-grip .grip { display: none; }
  td.c-grip   { grid-area: sel; }
  td.c-date   { grid-area: date; }
  td.c-cli    { grid-area: cli; }
  td.c-proj   { grid-area: proj; }
  td.c-start  { grid-area: start; }
  td.c-end    { grid-area: end; }
  td.c-tot    { grid-area: tot; }
  td.c-task   { grid-area: task; }
  td.c-notes  { grid-area: note; }
  td.act      { grid-area: act; text-align: right; }

  /* Etiqueta encima del campo: sin cabecera de tabla, "09:00" a secas no dice
     si es inicio o fin. data-l lo pone el JS al construir la fila. */
  table.grid tbody tr.entry td[data-l]::before {
    content: attr(data-l);
    display: block; font-size: 10px; font-weight: 700; letter-spacing: .5px;
    text-transform: uppercase; color: var(--grey-500); margin-bottom: 3px;
  }
  td.c-grip::before, td.act::before { content: none; }

  /* Los campos dejan de ser "invisibles hasta el foco": en tarjeta hay que ver
     dónde se puede escribir. */
  table.grid input, table.grid select {
    border-color: var(--grey-200); background: var(--bg-card);
    padding: 10px; border-radius: 9px; min-height: 42px;
  }
  table.grid input.tinput { text-align: left; min-width: 0; padding-left: 10px; }
  table.grid td.c-time, table.grid td.c-start, table.grid td.c-end { padding: 0; }

  /* Total: píldora grande + los ±15 min a tamaño de dedo, ya en el flujo
     (en tarjeta no hay hueco a la derecha que aprovechar como en la tabla). */
  td.tot { position: static; display: flex !important; align-items: center; gap: 6px; }
  td.tot::before { align-self: center; margin: 0 4px 0 0 !important; }
  td.tot .ro { margin-right: 0; min-width: 62px; padding: 11px 6px; font-size: 15px; }
  .dur-btns { position: static; transform: none; flex-direction: row; gap: 4px;
              opacity: 1; pointer-events: auto; }

  td.act { display: flex !important; justify-content: flex-end; gap: 2px; }
  table.grid input[type=checkbox] { margin: 0; }

  /* Cabecera de día pegajosa. Aquí se pega al borde de la ventana; por debajo de
     900px, donde hay barra superior fija, la sección 4 la baja a su altura. */
  tr.daygroup {
    display: flex; align-items: center; gap: 6px; padding: 0 10px;
    position: sticky; top: 0; z-index: 4;
    background: #f3f6fb;
  }
  tr.daygroup td { position: static; background: transparent; padding: 11px 2px; }
  tr.daygroup .dg-label { flex: 1 1 auto; min-width: 0; }
  tr.daygroup.today { background: #eef6da; }
  [data-theme="dark"] tr.daygroup { background: var(--grey-100); }
  [data-theme="dark"] tr.daygroup.today { background: rgba(163,212,59,.12); }

  tr.taskgroup { display: block; }
  tr.taskgroup td { display: block; }
  tr.dayempty { display: flex; align-items: center; padding: 8px 12px; }
  tr.dayempty td { display: block; padding: 0; border: 0; }
  tr.dayempty td.c-grip { display: none; }
  .dayempty-btn { padding: 11px 16px; }

  /* La barra de estado por fila iba en la primera celda; en tarjeta la primera
     celda es la casilla de selección, así que se pinta sobre la tarjeta entera. */
  tr.entry.row-saving td:first-child,
  tr.entry.row-saved td:first-child,
  tr.entry.row-error td:first-child,
  tr.warn td:first-child { box-shadow: none; }
  tr.entry.row-saving { box-shadow: inset 4px 0 0 var(--grey-300); }
  tr.entry.row-saved  { box-shadow: inset 4px 0 0 var(--lima); }
  tr.entry.row-error  { box-shadow: inset 4px 0 0 var(--danger); }
  tr.entry.warn       { box-shadow: inset 4px 0 0 var(--danger); background: #fdf4f2; }
  [data-theme="dark"] tr.entry.warn { background: rgba(192,57,43,.13); }
  tr.entry.sel { background: var(--marino-soft) !important; }
  .addrow { padding: 16px; font-size: 14.5px; }

  /* El desplegable de cliente es position:fixed y lo coloca el JS; aquí sólo
     se le quita el ancho mínimo de escritorio, que se salía de la pantalla. */
  .combo .ac-list { min-width: 0; max-height: 50vh; max-height: 50dvh; }
  .combo .ac-list div { padding: 13px 12px; }
  .ac-list div { padding: 12px 11px; }
  /* ---- 2.2 Campos de formulario ----
     16px es el mínimo en iOS: por debajo, Safari AMPLÍA la página al poner el foco
     y ya no vuelve — el usuario se queda con la app descuadrada. Es una regla de
     supervivencia, no un gusto.

     El `!important` es deliberado y la alternativa es peor. app.css fija el
     font-size de los campos desde selectores MÁS específicos que cualquiera que se
     pueda escribir aquí (`.toolbar input[type=text]`, `.cli-search input`,
     `.cli-newrow input`, `.org2-search-wrap input`, `.select-pretty`…), y una lista
     enumerada se queda corta en cuanto alguien añade un campo nuevo — que es
     exactamente como se coló media docena de ellos en la primera versión.
     Se excluyen las casillas (a las que el font-size no les afecta) y el único
     campo pensado a propósito para ser MÁS grande, que si no encogería. */
  input:not([type=checkbox]):not([type=radio]):not(.cli-name-input),
  select, textarea { font-size: 16px !important; }

  .field input, .em-body select, .em-body input { min-height: 44px; }
  /* input[type=date] en iOS se encoge a su contenido: sin ancho fijo la fila baila. */
  input[type=date] { width: 100%; min-height: 44px; }

  /* Red de seguridad: un <select> sin ancho declarado se dimensiona a su opción más
     larga y se sale de la pantalla (le pasaba a `a_recmode`, 410px en una ventana de
     390). max-width en vez de width:100% para no estirar los cortos. */
  select { max-width: 100%; }

  /* ---- 2.3 Nota ampliada (observaciones) ----
     El panel lo coloca el JS: se ancla a la celda y se recorta contra visualViewport,
     que es lo único que descuenta el teclado en pantalla. Aquí sólo la letra — el
     cuadro de escritura es un <textarea> y ya sube a 16px con la regla de arriba, así
     que el de lectura tiene que subir con él o la nota cambiaría de tamaño al tocarla. */
  .np-txt { font-size: 16px; }
}

/* ================================================================
   3 · ≤900px — MÓVIL Y TABLETA
   La barra lateral pasa a cajón y aparece la barra superior. La
   cuadrícula ya son tarjetas desde la sección 2 (corte de 1100px).
================================================================ */
@media (max-width: 900px) {

  /* ---- 3.1 Shell: una sola columna ---- */
  .shell { grid-template-columns: 1fr; min-height: 100vh; min-height: 100dvh; }

  /* overflow-x: CLIP y no hidden. `hidden` obliga al eje contrario a `auto`,
     convirtiendo .workspace en su propio contenedor de scroll y matando el
     position:sticky de la cabecera de la tabla y de los días (mismo error que
     ya se pagó en .grid-wrap). `clip` recorta sin crear scrollport. */
  .workspace {
    overflow-x: clip;
    padding: calc(56px + env(safe-area-inset-top) + 12px) 12px
             calc(24px + env(safe-area-inset-bottom));
  }

  /* ---- 3.2 Barra superior fija (hamburguesa + título + reloj + buscar) ---- */
  .appbar {
    display: flex; align-items: center; gap: 8px;
    position: fixed; inset: 0 0 auto 0; z-index: 260;
    height: calc(56px + env(safe-area-inset-top));
    padding: env(safe-area-inset-top) 10px 0;
    background: var(--bg-card, #fff);
    border-bottom: 1px solid var(--border);
    box-shadow: 0 1px 3px rgba(0,24,104,.06);
  }
  /* position:relative para que el punto de aviso se ancle AL BOTÓN. Sin él, el
     ascendiente posicionado más cercano es la propia .appbar (que es fixed) y el punto
     se iba a la esquina de la pantalla. */
  .appbar-btn {
    position: relative;
    flex: 0 0 auto; width: 40px; height: 40px; border: 0; border-radius: 10px;
    background: transparent; color: var(--marino); font-size: 19px; line-height: 1;
    cursor: pointer; display: flex; align-items: center; justify-content: center;
  }
  .appbar-btn:active { background: var(--grey-100); }
  .appbar-title {
    flex: 1 1 auto; min-width: 0; font-size: 15px; font-weight: 700; color: var(--marino);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  /* Reloj espejo del cronómetro: en el cajón no se ve, y un cronómetro corriendo
     que no se ve es un cronómetro que se olvida parado. Sólo aparece en marcha. */
  .appbar-timer {
    display: none; align-items: center; gap: 6px; flex: 0 0 auto;
    background: var(--marino); color: #fff; border: 0; border-radius: 20px;
    padding: 7px 12px; font: inherit; font-size: 13px; font-weight: 800;
    font-variant-numeric: tabular-nums; cursor: pointer;
  }
  body.timer-on .appbar-timer { display: inline-flex; }
  .appbar-timer .tmr-live { width: 7px; height: 7px; }
  .appbar-badge {
    position: absolute; top: 5px; right: 5px; min-width: 8px; height: 8px;
    border-radius: 50%; background: var(--danger); display: none;
  }
  body.has-notif .appbar-badge { display: block; }

  /* ---- 3.3 Barra lateral => cajón lateral ----
     z-index 280 (velo 270) queda POR DEBAJO de los modales (300), del toast (400)
     y de la paleta de comandos (500): un modal abierto siempre tapa el cajón. */
  .sidebar {
    position: fixed; top: 0; bottom: 0; left: 0; z-index: 280;
    width: min(86vw, 300px); height: 100vh; height: 100dvh;
    padding: calc(16px + env(safe-area-inset-top)) 14px calc(16px + env(safe-area-inset-bottom));
    overflow-y: auto; -webkit-overflow-scrolling: touch;
    border-right: 1px solid var(--border);
    box-shadow: 12px 0 40px rgba(0,24,104,.18);
    transform: translateX(-101%);
    transition: transform .24s cubic-bezier(.4,0,.2,1);
    visibility: hidden;
  }
  body.nav-open .sidebar { transform: none; visibility: visible; }
  .nav-scrim {
    display: block; position: fixed; inset: 0; z-index: 270;
    background: rgba(0,24,104,.45); opacity: 0; pointer-events: none;
    transition: opacity .24s;
  }
  body.nav-open .nav-scrim { opacity: 1; pointer-events: auto; }
  /* Con el cajón abierto el fondo no se mueve. overflow:hidden (y NO position:fixed)
     porque fixed pierde la posición de scroll al cerrar. */
  body.nav-open { overflow: hidden; }
  @media (prefers-reduced-motion: reduce) {
    .sidebar, .nav-scrim { transition: none; }
  }

  /* El panel de notificaciones cuelga de la barra lateral: dentro del cajón se
     quedaría escondido. Se saca a hoja completa por encima del cajón. */
  .notif-panel {
    left: 10px; right: 10px; width: auto;
    top: calc(56px + env(safe-area-inset-top) + 8px); bottom: auto;
    max-height: 65vh; max-height: 65dvh; z-index: 290;
  }

  /* ---- 3.4 Topbar de semana ---- */
  .topbar { flex-direction: column; align-items: stretch; gap: 12px; padding: 12px; }
  .weeknav { gap: 8px; }
  .weektitle { flex: 1 1 auto; min-width: 0; }
  .weektitle h1 { font-size: 17px; }
  .wt-row { flex-wrap: wrap; gap: 7px; }
  .wt-sub { font-size: 12px; }
  .menu { left: 0; top: 34px; }
  .menu button { width: 100%; min-width: 190px; padding: 13px 14px; font-size: 14px; }
  .topbar-right { width: 100%; gap: 10px; }

  /* Tira de acciones: en vez de seis botones envueltos en cuatro líneas, una
     sola fila deslizable. Todas siguen alcanzables y la topbar no crece. */
  .actions-row {
    flex-wrap: nowrap; overflow-x: auto; gap: 8px; width: 100%;
    padding-bottom: 2px; scrollbar-width: none; overscroll-behavior-x: contain;
  }
  .actions-row::-webkit-scrollbar { display: none; }
  .actions-row > * { flex: 0 0 auto; }
  #validateActions:empty { display: none; }

  /* ---- 3.5 KPIs: apilados, uno debajo de otro ----
     Se probó un carrusel horizontal para ahorrar alto, y se descartó: una tarjeta
     cortada por el borde derecho se lee como un fallo de maquetación, no como algo
     que se pueda deslizar. Apilados no hay nada que adivinar. */
  .kpis { display: grid; grid-template-columns: 1fr; gap: 12px; margin: 0 0 14px; padding: 0; }
  .kpis .kcard:last-child { grid-column: auto; }
  .kcard { min-height: 0; padding: 14px; }

  /* ---- 3.6 Barra de filtros ---- */
  .toolbar { gap: 8px; padding: 10px; }
  .toolbar select { flex: 1 1 calc(50% - 4px); min-width: 0; }
  .toolbar input[type=search], .toolbar input[type=text] { flex: 1 1 100%; min-width: 0; }
  .toolbar .sp { display: none; }
  .toolbar .chk { flex: 1 1 auto; }
  #toggleDaysBtn { flex: 0 0 auto; }


  /* ---- 3.8 Rail ---- */
  .rail { grid-template-columns: 1fr !important; }

  /* ---- 3.9 Barra de selección múltiple / toast ---- */
  .bulkbar {
    left: 8px; right: 8px; transform: none; flex-wrap: wrap; justify-content: center;
    bottom: calc(10px + env(safe-area-inset-bottom)); padding: 10px;
  }
  .bulkbar.open { animation: none; transform: none; }
  .bb-sep { display: none; }
  .bb-menu { left: auto; right: 0; }
  .toast {
    left: 12px; right: 12px; bottom: calc(12px + env(safe-area-inset-bottom));
    justify-content: space-between;
  }

  /* ---- 3.10 Modales => hojas inferiores ----
     Pegadas abajo: es donde llega el pulgar, y así el teclado virtual no
     empuja el contenido fuera de la vista. */
  .modal-back { align-items: flex-end; }
  .modal-box {
    width: 100%; max-width: none; border-radius: 18px 18px 0 0;
    max-height: 92vh; max-height: 92dvh;
    padding: 20px 16px calc(16px + env(safe-area-inset-bottom));
  }
  .modal-hd h2 { font-size: 16px; }
  .modal-ft {
    position: sticky; bottom: calc(-1 * env(safe-area-inset-bottom));
    background: inherit; margin: 16px -16px calc(-1 * env(safe-area-inset-bottom));
    padding: 14px 16px calc(14px + env(safe-area-inset-bottom));
    flex-wrap: wrap;
  }
  .modal-ft .btn { flex: 1 1 auto; }
  .em-ft .em-spacer { display: none; }
  .mp-row { grid-template-columns: 1fr; gap: 4px; }
  .mp-row label { padding-top: 0; }
  .pf-body { max-height: 60vh; max-height: 60dvh; }
  .pf-item { flex-wrap: wrap; }
  .pf-acts { width: 100%; justify-content: flex-end; }
  .pp-modal { width: 100%; }
  .pp-folder-list { grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); }

  /* Perfil */
  .pm-shell {
    width: 100%; max-width: none; border-radius: 18px 18px 0 0;
    max-height: 94vh; max-height: 94dvh;
  }
  .pm-hero { padding: 20px 16px 16px; gap: 14px; }
  .pm-avatar-ring { width: 64px; height: 64px; }
  .pm-avatar-hover { opacity: 1; background: rgba(0,0,0,.28); font-size: 14px; }
  .pm-tabs { padding: 0 8px; overflow-x: auto; scrollbar-width: none; }
  .pm-tabs::-webkit-scrollbar { display: none; }
  .pm-panel { padding: 18px 16px 8px; }
  .pm-fields { grid-template-columns: 1fr; }

  /* Paleta de comandos: a pantalla completa. Con teclado virtual abierto, una
     caja centrada al 70% de alto se queda sin sitio para la lista. */
  .cmdk-back { padding: 0; align-items: stretch; }
  .cmdk-box {
    max-width: none; border-radius: 0;
    height: 100vh; height: 100dvh; max-height: none;
    padding-top: env(safe-area-inset-top);
  }
  .cmdk-foot { display: none; }

  /* ---- 3.11 Paneles y formularios genéricos ---- */
  .panel { padding: 16px; border-radius: 12px; }
  .panel.narrow { margin: 8px auto; }
  .panel-hd { flex-wrap: wrap; gap: 8px; }
  .grid2 { grid-template-columns: 1fr; }

  /* Tablas de datos que no se convierten en tarjetas: scroll horizontal propio,
     nunca de la página. display:block sobre <table> no rompe el reparto de
     columnas (las filas siguen formando su caja de tabla anónima). */
  table.maptable, table.usertable, #billTable {
    display: block; overflow-x: auto; white-space: nowrap;
    -webkit-overflow-scrolling: touch;
  }
  table.maptable input[type=text] { min-width: 160px; }

  /* Horas por proyecto: la tabla ya scrollea en su caja por la regla de table.maptable de
     arriba; lo que falta es que los dos selectores no se estrangulen al ponerse en columna. */
  .ph-pickers { width: 100%; }
  .ph-pickers .field { flex: 1 1 160px; }

  /* Informe con IA: en el móvil la cabecera de cada fase no cabe en una fila. */
  .ai-figs { flex-wrap: wrap; }
  .ai-fig { flex: 1 1 40%; }
  .ai-fase-hd { flex-wrap: wrap; }
  .ai-fase-hd .af-nom { flex: 1 1 100%; }
  .ai-fase-hd .af-per { flex: 1 1 auto; }

  .bill-controls { flex-direction: column; align-items: stretch; gap: 12px; }
  .bill-right { flex-wrap: wrap; }
  .bill-right .field { flex: 1 1 100%; }
  .select-pretty { min-width: 0; width: 100%; }

  /* ---- 3.12 Análisis ---- */
  .an-filters { padding: 10px; gap: 8px; }
  .an-presets { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; margin: 0 -2px; padding: 0 2px; }
  .an-presets::-webkit-scrollbar { display: none; }
  .an-preset { flex: 0 0 auto; }
  .an-range { flex: 1 1 100%; }
  .an-range input { flex: 1 1 0; min-width: 0; }
  .an-sp { display: none; }
  #anScope { flex: 1 1 auto; min-width: 0; }
  .an-hero { padding: 16px; }
  .an-hero-value { font-size: 40px; }
  .an-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .an-tile .t-val { font-size: 21px; }
  .an-card { padding: 14px; }
  .an-card-hd { flex-wrap: wrap; }
  .an-goto-row input { flex: 1 1 auto; }

  /* ---- 3.13 Clientes ---- */
  .cli-detail { padding: 14px 0 8px; }
  .cli-list { max-height: 40vh; max-height: 40dvh; }
  .cli-row { padding: 12px 10px; }
  .cli-name-input { font-size: 18px; }
  .cli-detail-toggles { flex-wrap: wrap; gap: 14px; }
  .proj-row { padding: 3px 0; }
  .proj-name { padding: 11px 9px; }
  .sub-name { padding: 10px 9px; }

  /* ---- 3.14 Calendario ----
     Siete días no caben en 360px. Se conserva la semana entera y se desplaza en
     horizontal DENTRO de .cal-scroll: cabecera y cuerpo comparten ese mismo
     scroll, así que siguen alineados (que es justo por lo que van en el mismo
     contenedor). La cabecera sigue siendo sticky en vertical. */
  #calendario.view.active {
    height: auto; min-height: 0;
  }
  #calendario .topbar .hint { display: none; }
  #calendario .panel { max-height: none; }
  .cal-scroll {
    overflow-x: auto; -webkit-overflow-scrolling: touch;
    max-height: 68vh; max-height: 68dvh;
  }
  .cal-head, .cal-body { min-width: 720px; grid-template-columns: 48px repeat(7, minmax(96px, 1fr)); }
  .cal-dh { padding: 10px 4px; font-size: 11.5px; }
  .cal-hr { font-size: 10px; right: 5px; }
  .cal-col { cursor: pointer; }

  /* ---- 3.15 Equipo / organigrama ---- */
  #equipo .org2-container {
    height: calc(100vh - 56px - env(safe-area-inset-top));
    height: calc(100dvh - 56px - env(safe-area-inset-top));
  }
  .org2-toolbar { flex-wrap: wrap; gap: 8px; padding: 10px 12px; }
  .org2-search-wrap { max-width: none; flex: 1 1 100%; order: 2; }
  .org2-zoom-btns { margin-left: 0; }
  .org2-drawer { width: 100%; }
  .org2-canvas { padding: 32px 24px 48px; }

  /* ---- 3.16 Cabecera de día bajo la barra superior ----
     La sección 3 la pega al borde de la ventana; aquí hay una barra superior fija
     de 56px encima y tiene que quedarse justo debajo, no debajo de ella. */
  tr.daygroup { top: calc(56px + env(safe-area-inset-top)); }
}

/* ================================================================
   5 · ≤560px — móvil estrecho
================================================================ */
@media (max-width: 560px) {
  body { font-size: 14px; }
  .workspace { padding-left: 10px; padding-right: 10px; }
  .weektitle h1 { font-size: 16px; }
  .week-total-pill { font-size: 11.5px; padding: 5px 9px; }

  /* La tarjeta pasa a una sola columna útil: fecha arriba, horas en dos mitades. */
  table.grid tbody tr.entry {
    grid-template-columns: 24px minmax(0,1fr) minmax(0,1fr);
    grid-template-areas:
      "sel  date  date"
      ".    start end"
      ".    tot   act"
      "cli  cli   cli"
      "proj proj  proj"
      "task task  task"
      "note note  note";
    padding: 12px 10px 14px;
  }
  td.tot { justify-content: flex-start; }

  .an-hero-value { font-size: 34px; }
  .an-tiles { grid-template-columns: 1fr; }
  .pp-folder-list { grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); }
  .hm-cell { width: 11px; height: 11px; }
  .hm-dow { flex: 0 0 11px; }
  .hm-dow span { width: 11px; height: 11px; line-height: 11px; font-size: 8.5px; }
  .cal-head, .cal-body { min-width: 640px; grid-template-columns: 42px repeat(7, minmax(84px, 1fr)); }

  /* Vitrina de medallas: a tres columnas la medalla se queda en ~85px y la etiqueta
     ("Platino III") empieza a partirse. Mejor dos columnas y la medalla a su tamaño. */
  .ach-grid { grid-template-columns: repeat(2, 1fr); }
  .ach-total { font-size: 34px; }
}

/* ================================================================
   6 · Apaisado bajo (móvil girado): el alto es el recurso escaso
================================================================ */
@media (max-height: 480px) and (orientation: landscape) {
  .modal-box, .pm-shell { max-height: 96vh; max-height: 96dvh; }
  .cal-scroll { max-height: 60vh; max-height: 60dvh; }
  .cmdk-box { height: 100vh; height: 100dvh; }
  .kcard { min-height: 0; }
}
