:root{
  color-scheme: light;
  --bg: #EFF1EA;
  --surface: #FAFAF6;
  --surface-2: #F3F4EE;
  --ink: #1C211D;
  --ink-2: #565F58;
  --muted: #8A9088;
  --border: rgba(28,33,29,0.11);
  --border-strong: rgba(28,33,29,0.18);
  --wine: #7A2E3A;
  --wine-fill: rgba(122,46,58,0.10);
  --gold: #A9781C;
  --gold-fill: rgba(169,120,28,0.14);
  --teal: #1B756D;
  --blue: #33587F;
  --blue-soft: #6C93B8;
  --good: #0ca30c;
  --good-fill: rgba(12,163,12,0.10);
  --warning: #b8790a;
  --warning-fill: rgba(250,178,25,0.16);
  --critical: #b23a3a;
  --critical-fill: rgba(208,59,59,0.13);
  --shadow: 0 1px 2px rgba(28,33,29,0.06), 0 8px 24px -12px rgba(28,33,29,0.18);
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    color-scheme: dark;
    --bg: #14170F; --surface: #1C2016; --surface-2: #22271A;
    --ink: #F1F2EA; --ink-2: #BEC5B6; --muted: #8B9285;
    --border: rgba(241,242,234,0.10); --border-strong: rgba(241,242,234,0.18);
    --wine: #D98A9A; --wine-fill: rgba(217,138,154,0.14);
    --gold: #E0AC4A; --gold-fill: rgba(224,172,74,0.16);
    --teal: #4FB3A8; --blue: #86ABD1; --blue-soft: #5A7FA3;
    --good: #34c759; --good-fill: rgba(52,199,89,0.14);
    --warning: #f0a83a; --warning-fill: rgba(240,168,58,0.16);
    --critical: #e2665f; --critical-fill: rgba(226,102,95,0.16);
    --shadow: 0 1px 2px rgba(0,0,0,0.3), 0 8px 24px -12px rgba(0,0,0,0.5);
  }
}
:root[data-theme="dark"]{
  color-scheme: dark;
  --bg: #14170F; --surface: #1C2016; --surface-2: #22271A;
  --ink: #F1F2EA; --ink-2: #BEC5B6; --muted: #8B9285;
  --border: rgba(241,242,234,0.10); --border-strong: rgba(241,242,234,0.18);
  --wine: #D98A9A; --wine-fill: rgba(217,138,154,0.14);
  --gold: #E0AC4A; --gold-fill: rgba(224,172,74,0.16);
  --teal: #4FB3A8; --blue: #86ABD1; --blue-soft: #5A7FA3;
  --good: #34c759; --good-fill: rgba(52,199,89,0.14);
  --warning: #f0a83a; --warning-fill: rgba(240,168,58,0.16);
  --critical: #e2665f; --critical-fill: rgba(226,102,95,0.16);
  --shadow: 0 1px 2px rgba(0,0,0,0.3), 0 8px 24px -12px rgba(0,0,0,0.5);
}

*{box-sizing:border-box;}
html,body{margin:0;padding:0;}
body{
  background:var(--bg); color:var(--ink);
  font-family:Karla, "Work Sans", system-ui, sans-serif;
  font-size:17px; line-height:1.5; -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
.wrap{max-width:1120px;margin:0 auto;padding:10px 20px 70px;}
.wrap.map-wrap{max-width:none; padding:0; height:calc(100vh - 56px); display:flex; flex-direction:column;}
#map-view{width:100%; height:100%; flex:1; min-height:0;}
/* header.top (0,0,1,1) le gana en especificidad a .map-toolbar (0,0,1,0) --
   sin el .top de mas aqui, header.top{padding:5px 0 16px;} (ver mas abajo)
   pisaba el padding lateral y lo dejaba a 0, con los botones pegados al
   borde de la pantalla en desktop (mobile no se ve afectado, .map-toolbar
   usa header.top{display:none;} como el resto de paginas). */
header.top.map-toolbar{position:static; padding:14px 20px; background:var(--surface); border-bottom:1px solid var(--border); flex:0 0 auto; gap:12px;}
.map-toolbar .card-toggle{margin:0; width:100%;}
/* Leaflet usa z-index internos de hasta 800-1000 en sus panes/controles; sin esto
   se salen de su propio contenedor y tapan los desplegables del nav (que van a
   z-index 20). Al fijarle su propio z-index, .leaflet-container (ya viene con
   position:relative de la librería) pasa a contener esos z-index por dentro. */
.leaflet-container{z-index:0;}
.mobile-footer-nav{display:none;}
.mobile-popup-bar{display:none;}
.map-mobile-filters{display:none;}
.eyebrow{
  font-family:"IBM Plex Mono", ui-monospace, monospace; font-size:13px;
  letter-spacing:0.14em; text-transform:uppercase; color:var(--muted);
}

nav.topnav{
  display:flex; justify-content:space-between; align-items:center; gap:16px;
  height:56px; padding:0 20px; border-bottom:1px solid var(--border); background:var(--surface);
  position:sticky; top:0; z-index:10;
}
nav.topnav .brand{
  font-family:Archivo,sans-serif; font-weight:800; font-size:17px; letter-spacing:-0.01em;
  color:inherit; text-decoration:none;
}
.nav-link{
  display:inline-flex; align-items:center; gap:8px;
  font-family:"IBM Plex Mono",monospace; font-size:14px; color:var(--ink-2);
  text-decoration:none; padding:6px 12px; border-radius:8px; white-space:nowrap;
  border:1px solid var(--border-strong);
}
.nav-link i{font-size:13px;}
.nav-link:hover{background:var(--surface-2);}
.nav-link.active{
  background:color-mix(in srgb, var(--surface-2) 85%, black 10%);
  color:var(--ink); font-weight:600;
}
.pill{
  display:inline-flex; align-items:center; gap:6px;
  font-family:"IBM Plex Mono", ui-monospace, monospace; font-size:13px; font-weight:500;
  padding:4px 10px; border-radius:99px; background:var(--surface-2); border:1px solid var(--border-strong); color:var(--ink-2);
}
.pill .dot{width:7px;height:7px;border-radius:50%; background:var(--muted);}
.pill.online .dot{background:var(--good); box-shadow:0 0 0 3px color-mix(in srgb, var(--good) 22%, transparent);}
.pill.offline .dot{background:var(--critical); box-shadow:0 0 0 3px color-mix(in srgb, var(--critical) 22%, transparent);}
button.pill{cursor:pointer; font:inherit; appearance:none; -webkit-appearance:none;}
button.pill:hover{background:color-mix(in srgb, var(--surface-2) 85%, black 6%);}
button.pill:disabled{opacity:.6; cursor:default;}

/* Estación: icono (mismo verde/rojo online-offline que el desplegable de
   estaciones, ver .station-status-dot) + nombre + "hace cuanto se actualizo"
   (mismo pill que antes vivia suelto en el topnav) en una fila -- visible en
   mobile y desktop por igual, por eso va fuera de header.top (ese si se
   oculta en mobile, ver mas abajo). */
.station-title-row{display:flex; align-items:center; gap:10px; flex-wrap:wrap; padding:16px 0 4px;}
.station-title-row h1{font-family:Archivo,sans-serif; font-weight:800; font-size:clamp(22px,3.2vw,32px); letter-spacing:-0.01em; margin:0;}
.station-title-row .station-status-dot{width:28px; height:28px; flex-shrink:0;}
.station-title-row .station-status-dot i{font-size:13px;}

header.top{
  display:flex; justify-content:space-between; align-items:flex-start; gap:24px; flex-wrap:wrap;
  padding:5px 0 16px; position:sticky; top:56px; z-index:9; background:var(--bg);
}
.header-info{flex:1 1 0; min-width:0;}

/* Estación (unica pagina con .station-header): titulo + coordenadas +
   filtros forman una columna izquierda de 3 filas, y el mapa (mismo tamaño
   fijo 150x150 de siempre, ver .header-map) arranca a la altura de la fila
   del titulo en vez de la de coordenadas/filtros -- de ahi el grid en vez
   del flex de arriba, con el mapa anclado arriba (align-self:start) de su
   columna en vez de estirado. header.top y .header-info pasan a
   display:contents aqui dentro (pierden su caja, incluido el sticky -- ya
   no tiene sentido con el mapa arrancando en la fila del titulo) para que
   sus hijos entren directos en el grid; en el resto de paginas que reusan
   header.top (Histórico, Fitosanitario...) no hay .station-header por
   medio, asi que siguen con el flex+sticky de arriba sin tocar. En mobile
   esto se deshace, ver mas abajo: vuelve a ser exactamente lo que era antes
   de esta cabecera compartida. */
.station-header{
  display:grid; grid-template-columns:1fr auto; grid-template-areas:"title map" "meta map" "toggle map";
  column-gap:24px; row-gap:4px; margin-bottom:20px;
}
.station-header .station-title-row{grid-area:title;}
.station-header header.top{display:contents;}
.station-header .header-info{display:contents;}
.station-header .loc-meta{grid-area:meta; align-self:center;}
.station-header .card-toggle{grid-area:toggle;}
.station-header .header-map{align-self:start;}

header.top h1{font-family:Archivo,sans-serif; font-weight:800; font-size:clamp(28px,3.8vw,38px); letter-spacing:-0.01em; margin:0 0 4px;}
.title-row{position:relative; display:inline-block; max-width:100%;}
.title-badge{
  position:absolute; left:100%; top:50%; transform:translateY(-50%); margin-left:10px;
  white-space:nowrap; font-family:"IBM Plex Mono",monospace; font-size:14px; font-weight:600;
  color:var(--ink-2); background:var(--surface-2); border:1px solid var(--border-strong);
  border-radius:8px; padding:3px 10px;
}
.loc-meta{display:flex; font-family:"IBM Plex Mono",monospace; font-size:14px; color:var(--ink-2); gap:12px; flex-wrap:wrap;}
/* Histórico y Fitosanitario llevan un badge junto al título que Estación no tiene -- se usa para
   ocultar las coordenadas solo en esas dos vistas, sin necesidad de una clase de pagina aparte. */
.title-row:has(.title-badge) + .loc-meta{display:none;}

.header-map{grid-area:map; width:150px; height:150px; border-radius:14px; overflow:hidden; border:1px solid var(--border); box-shadow:var(--shadow); background:var(--surface-2);}
.header-map iframe{width:100%; height:100%; border:0; display:block;}
@media (max-width:760px){
  .station-header{display:block; margin-bottom:0;}
  .station-header header.top{display:none;}
  .header-map{display:none;}
  .header-info .card-toggle{flex-wrap:nowrap; overflow-x:auto; -webkit-overflow-scrolling:touch; padding-bottom:2px;}
  .header-info .card-toggle label{flex:0 0 auto;}
}

section{margin-bottom:30px;}
.section-head{margin-bottom:12px;}
.section-head h2{font-family:Archivo,sans-serif; font-weight:700; font-size:21px; margin:0 0 3px;}
.section-head p{margin:0; font-size:14.5px; color:var(--ink-2); max-width:70ch;}

.status-strip{display:grid; grid-template-columns:repeat(3,1fr); gap:14px; margin-bottom:26px;}
.status-card{background:var(--surface); border:1px solid var(--border); border-radius:14px; padding:16px 18px; box-shadow:var(--shadow); position:relative; overflow:hidden;}
.status-card::before{content:'';position:absolute;left:0;top:0;bottom:0;width:4px;}
.status-card.risk-high::before{background:var(--critical);}
.status-card.risk-mid::before{background:var(--warning);}
.status-card.risk-low::before{background:var(--good);}
.status-card-head{display:flex; justify-content:space-between; align-items:flex-start; gap:8px;}
.disease-name{font-family:Archivo,sans-serif; font-weight:700; font-size:16px;}
.risk-pill{font-family:"IBM Plex Mono",monospace; font-size:11.5px; font-weight:600; padding:3px 8px; border-radius:99px; white-space:nowrap;}
.risk-pill.alto{background:var(--critical-fill); color:var(--critical);}
.risk-pill.medio{background:var(--warning-fill); color:var(--warning);}
.risk-pill.bajo{background:var(--good-fill); color:var(--good);}
.status-figure{font-family:"IBM Plex Mono",monospace; font-weight:600; font-size:30px; margin:8px 0 2px; font-variant-numeric:tabular-nums;}
.status-note{font-size:14px; color:var(--ink-2); line-height:1.45;}


.device-grid{display:grid; grid-template-columns:repeat(4,1fr); gap:14px; align-items:stretch; margin-bottom:22px;}
.device-card{background:var(--surface); border:1px solid var(--border); border-radius:16px; padding:0 18px 15px; box-shadow:var(--shadow); display:flex; flex-direction:column; height:100%; overflow:hidden;}
.device-card-head{display:flex; justify-content:space-between; align-items:center; margin:0 -18px 13px; padding:12px 18px; background:#DCEBDF; color:#1C211D;}
.device-card-title{font-family:Archivo,sans-serif; font-weight:700; font-size:17px; letter-spacing:-0.005em;}
.device-card-head i{font-size:19px;}
/* El icono de la cabecera es un link a Histórico (misma metrica, ver
   dashboard.js) -- mismo aspecto que el icono suelto de antes, solo con un
   hover sutil para insinuar que ahora es clicable. */
.device-card-head a{color:inherit; text-decoration:none; display:inline-flex; align-items:center; justify-content:center; padding:5px; margin:-5px; border-radius:7px;}
.device-card-head a:hover{background:rgba(0,0,0,0.08);}

.metric-row{display:flex; gap:16px;}
.metric-row + .metric-row{margin-top:12px;}
.metric-block{flex:1; min-width:0;}
.metric-label{font-family:"IBM Plex Mono",monospace; font-size:12.5px; letter-spacing:0.06em; text-transform:uppercase; color:var(--muted); margin-bottom:4px;}
.metric-value{font-family:Archivo,sans-serif; font-weight:800; font-size:25px; line-height:1; letter-spacing:-0.01em; font-variant-numeric:tabular-nums;}
.metric-value small{font-size:14.5px; font-weight:600; color:var(--ink-2); margin-left:1px;}
.metric-trend{font-family:"IBM Plex Mono",monospace; font-size:12px; margin-top:5px; color:var(--ink-2); white-space:nowrap;}
.metric-trend.up{color:var(--warning);}
.metric-trend.down{color:var(--teal);}
.metric-hilo{font-family:"IBM Plex Mono",monospace; font-size:12px; color:var(--muted); display:flex; flex-wrap:wrap; gap:3px 9px; margin-top:5px;}
.metric-hilo span{white-space:nowrap;}
.metric-hilo .hi{color:var(--critical);}
.metric-hilo .lo{color:var(--blue);}

.mini-list{display:flex; flex-direction:column; gap:7px; margin-top:12px; padding-top:11px; border-top:1px solid var(--border);}
.mini-list[hidden]{display:none;}
.mini-grid2{display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:7px 16px; margin-top:12px; padding-top:11px; border-top:1px solid var(--border);}
.mini-row{display:flex; flex-wrap:wrap; justify-content:space-between; align-items:baseline; font-size:14px; gap:2px 8px; min-width:0;}
.mini-row .ml{color:var(--ink-2); min-width:0;}
.mini-row .mv{font-family:"IBM Plex Mono",monospace; font-weight:600; font-variant-numeric:tabular-nums; white-space:nowrap;}
/* Dato derivado de la fila de arriba (cantidad total/coste bajo la dosis de
   un producto, ver renderAplicarDosisResumen) -- mismo formato, mas
   pequeño y desplazado para leerse como un detalle, no como un dato mas. */
.mini-row-sub{padding-left:14px; font-size:12.5px;}
.mini-row-sub .mv{font-weight:500;}
/* Paso 4 (confirmar) del asistente: detalle fila a fila de cada combinacion
   parcela x tratamiento/trabajo que "Se crearán" va a generar -- fecha
   (todas comparten la misma, ver renderAplicarResumen) + parcela + nombre,
   truncados con "..." en vez de desbordar la card horizontalmente (mismo
   criterio que el resto del asistente en mobile). */
.aplicar-combo-list{display:flex; flex-direction:column; gap:5px; margin-top:10px; padding-top:10px; border-top:1px solid var(--border);}
.aplicar-combo-row{display:flex; align-items:baseline; gap:8px; font-size:12.5px; min-width:0;}

/* Paso 4 (confirmar): productos y dosis a aplicar (ver renderAplicarDosisResumen
   en parcelas.js) -- son los mismos para todas las parcelas elegidas, asi que
   van en una unica seccion aparte en vez de repetirse en cada fila de
   .aplicar-combo-list. */
.aplicar-resumen-section{margin-top:10px; padding-top:10px; border-top:1px solid var(--border);}
.aplicar-resumen-section-title{font-size:12.5px; font-weight:700; color:var(--ink-2); text-transform:uppercase; letter-spacing:.02em; margin-bottom:6px;}
.aplicar-resumen-maestro{margin-bottom:8px;}
.aplicar-resumen-maestro:last-child{margin-bottom:0;}
.aplicar-resumen-maestro-nombre{font-size:13.5px; font-weight:600; color:var(--ink); margin-bottom:2px;}
.aplicar-combo-fecha{font-family:"IBM Plex Mono",monospace; color:var(--muted); flex:0 0 auto;}
.aplicar-combo-txt{flex:1 1 0; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--ink-2);}
/* Excepcion al nowrap de arriba: aqui los valores pueden ser una direccion
   catastral entera, no una cifra corta -- sin esto se salia de la card por
   la derecha en vez de partir en varias lineas. */
#detail-info .mv, #detail-catastro .mv, #item-detalle-body .mv, #aplicar-resumen .mv{white-space:normal; overflow-wrap:anywhere; text-align:right;}

.moon-row{display:flex; align-items:center; gap:9px; margin-top:12px; padding-top:11px; border-top:1px solid var(--border); font-size:14.5px; color:var(--ink-2);}
.moon-icon{font-size:21px; line-height:1;}

.batt-status{display:inline-flex; align-items:center; gap:6px; font-family:"IBM Plex Mono",monospace; font-size:12px; font-weight:600; letter-spacing:0.04em; padding:4px 10px; border-radius:99px; margin-bottom:13px;}
.batt-status.normal{background:var(--good-fill); color:var(--good);}
.batt-status.low{background:var(--critical-fill); color:var(--critical);}

.compass-wrap{display:flex; justify-content:center; margin:2px 0 4px;}
.compass-svg text{font-family:"IBM Plex Mono",monospace; fill:var(--muted); font-size:9px; text-anchor:middle;}
.compass-svg .needle{stroke:var(--wine); stroke-width:2.4; stroke-linecap:round;}
.compass-svg .center-deg{font-size:13px; font-weight:600; fill:var(--ink);}
.compass-svg .center-dir{font-size:9.5px; fill:var(--ink-2);}

@media (max-width:980px){
  .device-grid{grid-template-columns:repeat(2,1fr);}
}
@media (max-width:520px){
  .device-grid{grid-template-columns:1fr;}
}

.range-selector{display:flex; align-items:center; gap:6px; flex-wrap:wrap; margin-bottom:14px;}
.range-btn{
  font-family:"IBM Plex Mono",monospace; font-size:14px; color:var(--ink-2);
  background:var(--surface); border:1px solid var(--border-strong); border-radius:8px;
  padding:6px 12px; cursor:pointer;
}
.range-btn:hover{background:var(--surface-2);}
.range-btn.active{background:var(--ink); color:var(--bg); border-color:var(--ink);}
.range-btn:disabled{opacity:.4; cursor:default;}
.range-btn:disabled:hover{background:var(--surface);}
.range-btn.danger-outline{border-color:var(--critical); color:var(--critical);}
.range-btn.danger-outline:hover{background:color-mix(in srgb, var(--critical) 10%, var(--surface));}
.range-btn.danger-fill{background:var(--critical); border-color:var(--critical); color:#fff;}
.range-btn.danger-fill:hover{background:color-mix(in srgb, var(--critical) 85%, black);}

.type-filter-row{display:flex; flex-wrap:wrap; gap:6px; margin-bottom:12px;}
.type-filter-row:empty{display:none;}
.type-filter-row .range-btn{font-size:12.5px; padding:5px 10px;}

.table-pagination{display:flex; align-items:center; justify-content:center; gap:12px; margin-top:10px;}
.table-pagination .pagination-label{font-family:"IBM Plex Mono",monospace; font-size:13px; color:var(--ink-2);}
.range-label-short{display:none;}
.cat-label-short{display:none;}
.range-custom-inputs{display:flex; align-items:center; gap:6px; margin-left:4px; font-family:"IBM Plex Mono",monospace; font-size:14px; color:var(--ink-2);}
.range-custom-inputs[hidden]{display:none;}
.range-custom-inputs input[type="date"]{
  font-family:"IBM Plex Mono",monospace; font-size:14px; color:var(--ink);
  background:var(--surface); border:1px solid var(--border-strong); border-radius:8px; padding:5px 8px;
}
.range-apply{
  font-family:"IBM Plex Mono",monospace; font-size:14px; color:var(--bg); background:var(--teal);
  border:none; border-radius:8px; padding:6px 12px; cursor:pointer;
}
.range-apply:hover{opacity:0.88;}
.range-apply.danger{background:var(--critical);}
.modal-actions-row{display:flex; gap:10px; justify-content:flex-end;}

.card-toggle{display:flex; align-items:center; gap:6px 14px; flex-wrap:wrap; margin:10px 0 12px;}
.card-toggle label{
  display:inline-flex; align-items:center; gap:8px; cursor:pointer;
  font-family:"IBM Plex Mono",monospace; font-size:14.5px; color:var(--ink-2);
  background:var(--surface); border:1px solid var(--border-strong); border-radius:8px;
  padding:6px 14px; transition:background .12s, color .12s, border-color .12s;
}
.card-toggle label i{font-size:13px;}
.card-toggle label:hover{background:var(--surface-2);}
.card-toggle label:focus-within{outline:2px solid var(--teal); outline-offset:2px;}
.card-toggle input[type="checkbox"]{
  position:absolute; width:1px; height:1px; margin:-1px; padding:0; overflow:hidden;
  clip:rect(0,0,0,0); white-space:nowrap; border:0;
}
.card-toggle label.is-active{background:#1F5D3A; border-color:#1F5D3A; color:#fff;}
.icon-letter{display:none;}

/* Boton "pastilla" con el mismo aspecto que un .card-toggle label pero sin
   semantica de checkbox -- reusable suelto (p.ej. la barra de acciones de
   Parcelas en mobile) o dentro de un .card-toggle (p.ej. "Centrar" en el
   mapa, que ademas se empuja al extremo derecho de la fila con
   margin-left:auto mientras los demas siguen fluyendo a la izquierda). */
.toggle-action{
  display:inline-flex; align-items:center; gap:8px; cursor:pointer;
  font:inherit; font-family:"IBM Plex Mono",monospace; font-size:14.5px; color:var(--ink-2);
  background:var(--surface); border:1px solid var(--border-strong); border-radius:8px;
  padding:6px 14px; transition:background .12s, color .12s, border-color .12s;
}
.toggle-action i{font-size:13px;}
.toggle-action:hover{background:var(--surface-2);}
.card-toggle .toggle-action{margin-left:auto;}

.chart-grid{display:grid; grid-template-columns:repeat(2,1fr); gap:14px; align-items:stretch;}
.panel-wide{grid-column:1/-1;}
.two-col{display:grid; grid-template-columns:1.3fr 1fr; gap:14px;}
/* Card "Datos" de la ficha de parcela: en desktop, datos a la izquierda
   (40% de ancho) y el mapa de Ubicacion a la derecha (60%), dentro de la
   misma card (ya no son dos cards independientes) -- en mobile se apilan,
   ver la regla mobile mas abajo. */
.datos-ubicacion-grid{display:grid; grid-template-columns:40% 60%; gap:16px; align-items:start;}
/* display:grid arriba tiene la misma especificidad que la regla del
   navegador [hidden]{display:none} pero llega despues en la cascada, asi
   que gana y el boton de plegar/desplegar de la card "Datos" no hacia nada
   -- mismo bug ya visto con .mini-list/.modal-backdrop/.panel, misma
   solucion: hacerlo explicito aqui tambien. */
.datos-ubicacion-grid[hidden]{display:none;}
.datos-ubicacion-col-datos{min-width:0;}
/* Columna "Notas" de tratamientos/trabajos: en vez de cabecera de texto y
   el contenido completo (no cabe bien en ninguna resolucion), un icono
   amarillo -- en la cabecera fijo, en cada fila solo si ese registro tiene
   notas. Click abre un mini-modal solo con el texto (reusa openItemDetalle,
   ver parcelas.js) sin necesidad de abrir el detalle completo de la fila. */
.col-notas-icon{text-align:center;}
.col-notas-icon i{color:#FDD835;}
.notas-icon-btn{background:none; border:none; padding:6px; margin:-6px; cursor:pointer; display:inline-flex; align-items:center;}
/* Lupa y notas de las filas de tratamientos/trabajos: mas grandes que el
   texto de la tabla para que el objetivo tactil sea comodo en movil, tanto
   el icono como (en el boton de notas) su zona clicable real (padding). */
.row-icon-lg{font-size:19px;}
@media (min-width:761px){
  /* Tratamientos (55%) y Trabajos (el resto, ahora con notas en texto y
     necesita algo mas de sitio) uno junto al otro en vez de apilados --
     solo en desktop, en mobile cada uno se queda a lo ancho. */
  .tratamientos-trabajos-grid{display:grid; grid-template-columns:55% 1fr; gap:16px; align-items:start;}
}
.panel{background:var(--surface); border:1px solid var(--border); border-radius:14px; padding:15px 17px 12px; box-shadow:var(--shadow); display:flex; flex-direction:column;}
.panel[hidden]{display:none;}
.panel-head{display:flex; justify-content:space-between; align-items:center; margin-bottom:2px; gap:8px; flex-wrap:wrap;}
/* Boton de plegar/desplegar + titulo van juntos a la izquierda de la card,
   en un grupo aparte de las demas acciones (que se quedan a la derecha via
   panel-head-actions) -- ver parcelas.html. */
.panel-head-left{display:flex; align-items:center; gap:8px; min-width:0;}
.panel-title{font-family:Archivo,sans-serif; font-weight:700; font-size:20px; flex-shrink:0;}
.panel-range{font-family:"IBM Plex Mono",monospace; font-size:12px; color:var(--muted);}
.panel-head-actions{display:flex; align-items:center; gap:10px; flex-shrink:0;}
.panel-toggle-btn{
  display:inline-flex; align-items:center; justify-content:center; flex-shrink:0;
  width:26px; height:26px; border-radius:8px; background:var(--surface-2); border:1px solid var(--border-strong);
  color:var(--ink-2); cursor:pointer; font-size:12px;
}
.panel-toggle-btn:hover{background:var(--surface);}
.panel-toggle-btn i{transition:transform .15s;}
.panel-toggle-btn.expanded i{transform:rotate(180deg);}
.panel-expand-btn{
  display:inline-flex; align-items:center; justify-content:center; flex-shrink:0;
  width:30px; height:30px; border-radius:8px;
  background:var(--gold); border:1px solid var(--gold); color:#2A1E06;
  cursor:pointer; font-size:14px;
}
.panel-expand-btn:hover{opacity:0.85;}
.panel.is-expanded .panel-expand-btn{
  background:var(--critical); border-color:var(--critical); color:#fff;
  width:38px; height:38px; font-size:18px;
}
.metric-switch{
  display:flex; align-items:center; gap:6px; flex-wrap:wrap; flex-basis:100%;
  overflow-x:auto; -webkit-overflow-scrolling:touch; scrollbar-width:none;
}
.metric-switch::-webkit-scrollbar{display:none;}
.metric-btn{
  display:inline-flex; align-items:center; gap:6px; flex-shrink:0;
  font-family:"IBM Plex Mono",monospace; font-size:13px; color:var(--ink-2);
  background:var(--surface); border:1px solid var(--border-strong); border-radius:8px;
  padding:5px 11px; cursor:pointer;
}
.metric-btn:hover{background:var(--surface-2);}
.metric-btn.active{background:var(--ink); color:var(--bg); border-color:var(--ink);}
.metric-label-full{display:inline-flex; align-items:center; gap:5px;}
.metric-label-short{display:none; align-items:center; gap:5px;}
.chart-period-block{margin-top:14px;}
.chart-period-block:first-of-type{margin-top:6px;}
.chart-period-block + .chart-period-block{padding-top:14px; border-top:1px solid var(--border);}
.chart-period-head{display:flex; justify-content:space-between; align-items:baseline; margin-bottom:2px; gap:8px; flex-wrap:wrap;}
.chart-period-label{font-family:"IBM Plex Mono",monospace; font-weight:600; font-size:23px; text-transform:uppercase; letter-spacing:0.04em; color:var(--ink-2);}
.legend{display:flex; gap:12px; margin:4px 0 4px; flex-wrap:wrap;}
.legend-item{display:flex; align-items:center; gap:6px; font-size:15px; color:var(--ink-2); font-family:"IBM Plex Mono",monospace;}
.legend-swatch{width:9px;height:9px;border-radius:2px;}
.wind-dir-row{margin-top:2px;}
.wind-dir-row[hidden]{display:none;}
.wind-dir-arrow path{fill:#7C5C9C;}

/* Boton "ampliar" de cada card: saca ese panel a un recuadro grande fijo
   por encima del resto (desktop) o a pantalla completa (mobile). El SVG de
   dentro no necesita ningun cambio -- ya es width:100%/height:auto, asi
   que escala solo con el hueco mas grande. */
#chart-expand-backdrop{position:fixed; inset:0; z-index:40; background:rgba(0,0,0,0.55);}
#chart-expand-backdrop[hidden]{display:none;}
.panel.is-expanded{
  position:fixed; z-index:50; top:5vh; left:5vw; right:5vw; bottom:5vh;
  margin:0; overflow-y:auto;
}
@media (max-width:760px){
  .panel.is-expanded{top:0; left:0; right:0; bottom:0; border-radius:0;}
}

.chart-svg{width:100%; height:auto; display:block; overflow:visible;}
.chart-svg .grid-line{stroke:var(--border); stroke-width:1;}
.chart-svg .axis-label{fill:var(--muted); font-family:"IBM Plex Mono",monospace; font-size:13px;}
.chart-svg .hover-line{stroke:var(--muted); stroke-width:1; stroke-dasharray:2,3; opacity:0;}
.chart-svg .annot-line{stroke:var(--ink-2); stroke-width:1.2; stroke-dasharray:3,3;}
.chart-svg .annot-label{fill:var(--ink-2); font-family:"IBM Plex Mono",monospace; font-size:10.5px;}
.chart-hit{fill:transparent; cursor:crosshair;}
.tooltip{
  position:absolute; pointer-events:none; z-index:5; background:var(--ink); color:var(--bg);
  font-family:"IBM Plex Mono",monospace; font-size:12.5px; line-height:1.5;
  padding:7px 10px; border-radius:8px; box-shadow:var(--shadow);
  opacity:0; transform:translate(-50%,-115%); transition:opacity .08s; white-space:nowrap;
}
.tooltip.show{opacity:1;}
.tooltip .t-time{color:color-mix(in srgb, var(--bg) 65%, transparent); display:block; margin-bottom:2px;}
.chart-wrap{position:relative;}
.bar{transition:opacity .1s;}
.bar:hover{opacity:0.78;}
.empty-note{font-size:14px; color:var(--muted); padding:30px 4px; text-align:center;}

.trigger-table{width:100%; border-collapse:collapse; font-size:14px; margin-top:2px;}
.trigger-table th,.trigger-table td{padding:6px 8px; text-align:left; border-bottom:1px solid var(--border);}
.trigger-table th{font-family:"IBM Plex Mono",monospace; font-size:11.5px; text-transform:uppercase; letter-spacing:0.05em; color:var(--muted); font-weight:500;}
.trigger-table td.num{font-family:"IBM Plex Mono",monospace; font-variant-numeric:tabular-nums; text-align:right;}

/* Columna Producto del Cuaderno de campo: una linea por producto (en vez de
   una lista separada por comas) cuando el tratamiento lleva varios -- ver
   productosCelda en parcelas.js. */
.cuaderno-productos{display:flex; flex-direction:column; gap:3px;}
.cuaderno-producto-row{display:flex; justify-content:space-between; align-items:baseline; gap:10px;}
.cuaderno-producto-row + .cuaderno-producto-row{padding-top:3px; border-top:1px dashed var(--border);}
.cuaderno-producto-nombre{min-width:0;}
.cuaderno-producto-cant{font-family:"IBM Plex Mono",monospace; font-size:12.5px; color:var(--ink-2); white-space:nowrap;}
/* Tratamientos/Trabajos de la ficha de parcela: menos aire entre columnas
   que el resto de tablas -- en mobile y desktop por igual (antes solo en
   mobile). El padding de la card en si (arriba/lados) sigue reduciendose
   solo en mobile, junto con Datos/Riesgo (ver esa regla mas abajo). */
#tabla-tratamientos th, #tabla-tratamientos td,
#tabla-trabajos th, #tabla-trabajos td{padding:5px 3px;}
#tabla-tratamientos th:first-child, #tabla-tratamientos td:first-child,
#tabla-trabajos th:first-child, #tabla-trabajos td:first-child{padding-left:0;}
#tabla-tratamientos th:last-child, #tabla-tratamientos td:last-child,
#tabla-trabajos th:last-child, #tabla-trabajos td:last-child{padding-right:0;}
/* % Eficaz: solo el titulo a la derecha (los datos ya van a la derecha por
   .num, sin tocar). */
#tabla-tratamientos th.col-eficaz{text-align:right;}

.note{display:flex; gap:10px; padding:13px 15px; border-radius:12px; background:var(--surface-2); border:1px solid var(--border); font-size:14.5px; color:var(--ink-2); align-items:flex-start;}
.note b{color:var(--ink);}

footer{margin-top:30px; padding-top:14px; border-top:1px solid var(--border); font-size:12.5px; color:var(--muted); font-family:"IBM Plex Mono",monospace;}

@media (max-width:760px){
  .status-strip{grid-template-columns:1fr;}
  .chart-grid, .two-col{grid-template-columns:1fr;}
  /* Card "Datos" de la ficha de parcela: en vez de las 2 columnas de
     desktop (30% datos / mapa), se apila una debajo de otra. */
  .datos-ubicacion-grid{grid-template-columns:1fr;}
  /* Mismo espacio vertical entre Datos->Riesgo que el que ya hay entre otras
     secciones (14px) -- por defecto section{margin-bottom:30px} deja mas
     hueco del que toca ahi. */
  #parcela-detail-view section:has(#panel-datos){margin-bottom:14px;}
  /* Riesgo->Tratamientos: mismos 14px que el resto. */
  #parcela-detail-view section:has(#panel-riesgo){margin-bottom:14px;}
  /* Tratamientos->Trabajos (apiladas en mobile, .tratamientos-trabajos-grid
     solo hace 2 columnas en desktop): mismos 14px que Datos->Riesgo. */
  #parcela-detail-view .tratamientos-trabajos-grid section:has(#panel-tratamientos){margin-bottom:14px;}
  /* Padding interno minimo (no cero) en Datos/Riesgo/Tratamientos/Trabajos. */
  #parcela-detail-view #panel-datos,
  #parcela-detail-view #panel-riesgo,
  #parcela-detail-view #panel-tratamientos,
  #parcela-detail-view #panel-trabajos{
    padding:8px 10px 8px;
  }
  /* Mas aire entre el boton "Datos Catastrales" y el mapa que va debajo al
     apilarse -- el resto de cards usan el mismo padding minimo de arriba,
     esta necesita algo mas. */
  #parcela-detail-view #detail-map{margin-top:10px;}
  /* Riesgo fitosanitario: el icono de ampliar grafica siempre en la misma
     linea que el titulo, pegado a la derecha -- con flex-wrap:wrap el titulo
     largo podia empujarlo a una segunda linea; con nowrap es el titulo el
     que se trunca (min-width:0 + ellipsis ya puestos) y el icono no se mueve. */
  #panel-riesgo .panel-head{flex-wrap:nowrap;}
  /* Titulos de las cards de esta vista al 75% de su tamaño normal. */
  #parcela-detail-view .panel-title{font-size:15px;}
  .metric-label-full{display:none;}
  .metric-label-short{display:inline-flex;}
  /* Tarjetas de parcela del asistente Aplicar (ver aplicarParcelaCardHtml en
     parcelas.js): en mobile solo interesan las hectareas para decidir que
     parcelas marcar, el cultivo sobra y ocupa una linea entera.
     Selector doblado (no ".mini-select-sub-cultivo" solo) a proposito: hay
     otra regla ".mini-select-sub{display:block}" mas abajo en este mismo
     fichero, misma especificidad -- por orden de aparicion ganaria ella y
     dejaria esto sin efecto. */
  .mini-select-sub.mini-select-sub-cultivo{display:none;}
  /* Desactivado en mobile: el texto "nombre min - max unidad" por serie
     (ver renderMultiSeriesPanel/renderPointsForType en historico.js, que
     siguen calculandolo y asignandolo igual) ocupa demasiado en pantallas
     estrechas con varias series activas a la vez. En desktop se mantiene.
     Al ampliar la card (`.is-expanded`, ver #chart-expand-backdrop) si hay
     hueco de sobra, asi que ahi se vuelve a mostrar. */
  /* Escopado a #chart-grid (Historico) a proposito: .panel-range tambien la
     usan paneles de otras paginas sin la funcion "ampliar" que la trae de
     vuelta (p.ej. el GDD acumulado y el rango de fechas del oidio en
     Fitosanitario) -- una regla global aqui los dejaba sin ese dato en
     mobile para siempre, sin ningun gesto que lo recuperase. */
  #chart-grid .panel-range{display:none;}
  #chart-grid .panel.is-expanded .panel-range{display:inline;}
}
@media (max-width:440px){
  nav.topnav{padding:10px 14px;}
  nav.topnav .brand{font-size:15px;}
}

/* ---- auth (login/registro) ---- */
.auth-wrap{display:flex; justify-content:center; padding-top:60px;}
.auth-card{
  width:100%; max-width:360px; background:var(--surface); border:1px solid var(--border);
  border-radius:14px; padding:28px 26px; box-shadow:var(--shadow);
  display:flex; flex-direction:column; gap:14px;
}
.auth-card h1{font-family:Archivo,sans-serif; font-weight:800; font-size:22px; margin:0 0 4px;}
.auth-card label{display:flex; flex-direction:column; gap:6px; font-size:13.5px; color:var(--ink-2);}
.auth-card input{
  font:inherit; font-size:15px; padding:9px 11px; border-radius:8px;
  border:1px solid var(--border-strong); background:var(--surface-2); color:var(--ink);
}
.auth-card input:focus{outline:2px solid var(--teal); outline-offset:1px;}
.auth-card button{
  font:inherit; font-weight:700; font-size:15px; padding:10px 14px; border-radius:9px;
  border:none; background:#1F5D3A; color:#fff; cursor:pointer; margin-top:4px;
}
.auth-card button:hover{opacity:0.92;}
.auth-error{color:var(--critical); font-size:13.5px;}
.auth-alt{font-size:13.5px; color:var(--muted); margin:0;}
.auth-alt a{color:var(--teal);}

/* ---- menu de usuario (desplegable) en el nav ---- */
.nav-left{display:flex; align-items:center; gap:14px;}
.nav-right{display:flex; align-items:center; gap:12px; flex-shrink:0;}
.user-menu{position:relative;}
.user-menu-trigger{
  display:inline-flex; align-items:center; gap:8px;
  font:inherit; font-family:"IBM Plex Mono",monospace; font-size:13px; font-weight:500;
  padding:6px 12px; border-radius:99px; background:var(--surface-2); border:1px solid var(--border-strong); color:var(--ink);
  cursor:pointer;
}
.user-menu-trigger:hover{background:var(--surface);}
.user-menu-trigger i.fa-circle-user{font-size:15px; color:var(--ink-2);}
.user-menu-trigger i.fa-chevron-down{font-size:10px; color:var(--muted);}
.nav-right .user-menu-trigger i.fa-bars{display:none;}
.station-status-dot{
  display:inline-flex; align-items:center; justify-content:center; flex:0 0 auto;
  width:20px; height:20px; border-radius:50%; background:var(--muted); color:#fff;
}
.station-status-dot i{font-size:10px;}
.station-status-dot.online{background:var(--good);}
.station-status-dot.offline{background:var(--critical);}
.user-menu-dropdown{
  position:absolute; right:0; top:calc(100% + 8px); min-width:200px;
  background:var(--surface); border:1px solid var(--border); border-radius:12px;
  box-shadow:var(--shadow); padding:6px; z-index:20;
  display:flex; flex-direction:column; gap:1px;
}
.user-menu-dropdown[hidden]{display:none;}
.user-menu-item{
  display:flex; align-items:center; gap:10px; padding:8px 10px; border-radius:8px;
  font:inherit; font-size:14px; color:var(--ink); text-decoration:none;
  background:none; border:none; text-align:left; width:100%; cursor:pointer;
}
.user-menu-item:hover{background:var(--surface-2);}
.user-menu-item.active{background:var(--surface-2); font-weight:600;}
.user-menu-item i{width:16px; text-align:center; color:var(--ink-2); font-size:13px;}
.user-menu-item.user-menu-logout{color:var(--critical);}
.user-menu-item.user-menu-logout i{color:var(--critical);}
.user-menu-sep{height:1px; background:var(--border); margin:5px 2px;}

@media (max-width:760px){
  .nav-link{display:none;}
  .nav-right .user-menu-trigger i.fa-circle-user,
  .nav-right .user-menu-trigger i.fa-chevron-down,
  .nav-right .user-menu-trigger span{display:none;}
  .nav-right .user-menu-trigger i.fa-bars{display:inline-block; font-size:16px;}

  /* El botón de estación va centrado (.station-switcher), así que su desplegable se
     centra igual, ajustado al ancho de los nombres en vez de ocupar todo el ancho
     disponible hasta el borde de la pantalla. */
  .station-dropdown.user-menu-dropdown{
    position:fixed; top:64px; left:50%; right:auto; transform:translateX(-50%);
    min-width:0; width:max-content; max-width:calc(100vw - 40px);
  }
  .station-dropdown .user-menu-item span{
    overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0;
  }

  .nav-left .user-menu-trigger{gap:4px;}
  .nav-left .user-menu-trigger .station-name{
    max-width:25ch; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  }

  /* El icono del logo iguala la altura del botón de selección de estación (20px de
     círculo + 6px de padding arriba/abajo + 1px de borde a cada lado = 34px). */
  .brand-icon{
    display:inline-flex; align-items:center; justify-content:center;
    height:34px; font-size:26px; vertical-align:middle;
  }
  .brand-text-full{display:none;}

  /* nav.topnav (sticky) hace de contenedor de referencia para centrar el select de
     estación en el ancho de la pantalla, al margen de dónde caiga el logo. */
  .station-switcher{
    position:absolute; left:50%; top:50%; transform:translate(-50%,-50%);
  }

  .range-label-full{display:none;}
  .range-label-short{display:inline;}

  /* Filtros de tipo (Exterior/Interior/Lluvia/...) en solo icono -- compartido por
     #device-toggle (Estación) y #chart-toggle (Histórico), ambos con clase .card-toggle.
     Todos los botones miden lo mismo (ancho y alto) y van más juntos entre sí. */
  .card-toggle{gap:6px 6px;}
  .card-toggle label span:not(.icon-letter){display:none;}
  .card-toggle label{
    width:38px; height:38px; padding:0; justify-content:center; flex:0 0 auto;
  }
  .card-toggle label i{font-size:17px;}

  /* Exterior/Interior comparten el icono de termómetro -- sin el texto, la E/I junto
     al icono es lo único que los distingue. Estos dos botones son algo más anchos
     que el resto para hacerle sitio a la letra. */
  .card-toggle label.temp-toggle{
    width:auto; min-width:38px; padding:0 8px; gap:2px;
  }
  .icon-letter{
    display:inline-block; font-family:"IBM Plex Mono",monospace; font-size:12px; font-weight:700;
  }

  /* Toda la barra sticky de cabecera (título, coordenadas, mapa y filtros de
     arriba) fuera en mobile -- Vista/Filtros del footer cubren lo mismo. */
  header.top{display:none;}
  /* Nombre de la estación (fuera de header.top, ver arriba de todo del CSS):
     letra mas pequeña y menos aire respecto al menu superior, pero mas aire
     por debajo hacia la primera card -- mismo espacio que hay entre cards
     (.device-grid gap:14px), antes se notaba mas pegado que el resto. */
  .station-title-row{padding:6px 0 16px;}
  .station-title-row h1{font-size:19px;}
  /* Todas las cards de la vista Estacion: datos centrados y todo un escalon
     mas grande -- titulos, el valor principal (+50%), los indicadores de
     debajo (tendencia y maximo/minimo) y las lineas de detalle (Sensacion,
     Evento de lluvia, Amanecer/Atardecer...). Escopado a #device-grid para
     no tocar estas mismas clases en Historico o en otras paginas. */
  #device-grid .metric-block{text-align:center;}
  #device-grid .metric-label{font-size:15px;}
  #device-grid .metric-value{font-size:37.5px;}
  #device-grid .metric-trend{font-size:15px;}
  #device-grid .metric-hilo{font-size:15px; justify-content:center;}
  #device-grid .mini-row{font-size:17px;}
  /* Card de Viento: puntos cardinales de la rosa y el dato central (grados +
     direccion) tambien mas grandes, mismo criterio que el resto. */
  #device-grid .compass-svg text{font-size:12px;}
  #device-grid .compass-svg .center-deg{font-size:17px;}
  #device-grid .compass-svg .center-dir{font-size:12.5px;}
  /* Menos margen a los lados de la pantalla en Estacion, Historico,
     Fitosanitario, Parcelas (listado, detalle y cuaderno -- #parcelas-view
     esta siempre en el DOM, solo se oculta/muestra), Estaciones, Tratamientos
     y Trabajos -- :has() para no tocar el padding de .wrap en el resto de
     paginas (admin/login/register/mapa), que lo comparten todas. */
  .wrap:has(#device-grid), .wrap:has(#chart-grid), .wrap:has(#status-strip),
  .wrap:has(#parcelas-view), .wrap:has(#estaciones-grid), .wrap:has(#lista-grid){
    padding-left:12px; padding-right:12px;
  }
  #device-grid{gap:10px;}

  /* Barra de navegación fija al pie en mobile -- mismo verde que los botones de
     filtro cuando están seleccionados (#1F5D3A). El .wrap gana margen inferior
     de sobra para que el contenido (y el footer de texto) no quede debajo. */
  .wrap{padding-bottom:calc(160px + env(safe-area-inset-bottom));}
  .mobile-footer-nav{
    display:flex; position:fixed; left:0; right:0; bottom:0; z-index:15;
    background:#1F5D3A; padding-bottom:env(safe-area-inset-bottom);
  }
  .mobile-footer-item{
    flex:1; display:flex; flex-direction:column; align-items:center; justify-content:center;
    gap:3px; padding:9px 4px 8px; text-decoration:none; color:rgba(255,255,255,0.7);
    font-family:"IBM Plex Mono",monospace; font-size:11px;
    background:none; border:none; font:inherit; cursor:pointer;
  }
  .mobile-footer-item i{font-size:18px;}
  .mobile-footer-item.active{color:#fff; font-weight:600;}
  .mobile-footer-item.open{background:rgba(255,255,255,0.15);}
  .mobile-footer-item.disabled{opacity:0.4; pointer-events:none;}

  /* Barra emergente fija justo encima de la barra de navegación inferior --
     la usan tanto el selector de vista (Estación/Histórico/Fitosanitario) como
     el duplicado de los filtros de arriba. Solo una a la vez, controlado por
     initMobileFooterNav() en api.js con el atributo [hidden]. */
  .mobile-popup-bar:not([hidden]){
    display:flex; position:fixed; left:0; right:0; z-index:14;
    bottom:calc(55px + env(safe-area-inset-bottom));
    margin:0; padding:8px 10px 16px; gap:6px; justify-content:center;
    background:var(--surface); border-top:1px solid var(--border); box-shadow:var(--shadow);
  }
  /* El popup de filtros puede llevar más de una fila (p.ej. Histórico: tipos +
     períodos) apiladas verticalmente, cada una centrada en su propia línea. */
  .mobile-filters-popup:not([hidden]){flex-direction:column; align-items:stretch;}
  #device-toggle-mobile, #chart-toggle-mobile, #disease-toggle-mobile, #range-selector-mobile{
    margin:0; justify-content:center;
  }

  /* Filtros del mapa: a diferencia del resto de popups de filtros (que se
     abren/cierran con el boton "Filtros" del pie), esta barra esta siempre
     visible -- no usa [hidden] ni pasa por initMobileFooterNav(). */
  .map-mobile-filters{
    display:flex; flex-direction:column; align-items:stretch; position:fixed; left:0; right:0; z-index:14;
    bottom:calc(55px + env(safe-area-inset-bottom));
    margin:0; padding:8px 10px 16px;
    background:var(--surface); border-top:1px solid var(--border); box-shadow:var(--shadow);
  }
  /* Sin justify-content:center (a diferencia de los de arriba): aqui interesa
     que los filtros sigan pegados a la izquierda y "Centrar" se vaya solo al
     extremo derecho via su propio margin-left:auto (ver .toggle-action). */
  #map-toggle-mobile{margin:0;}
  #range-selector-mobile .range-custom-inputs{
    flex-wrap:wrap; justify-content:center; width:100%; margin:4px 0 0;
  }

  .mobile-vista-item{
    flex:1; display:flex; flex-direction:column; align-items:center; justify-content:center;
    gap:3px; padding:8px 4px; border-radius:10px; text-decoration:none;
    color:var(--ink-2); font-family:"IBM Plex Mono",monospace; font-size:11px;
  }
  .mobile-vista-item i{font-size:18px;}
  .mobile-vista-item.active{background:#1F5D3A; color:#fff;}
}

.empty-state{padding:60px 20px; text-align:center; color:var(--ink-2);}
.empty-state h2{font-family:Archivo,sans-serif; margin-bottom:8px;}

/* ---- panel admin ---- */
#admin-content section{margin-bottom:34px;}
.table-scroll{overflow-x:auto;}
.role-badge{
  font-family:"IBM Plex Mono",monospace; font-size:11.5px; text-transform:uppercase; letter-spacing:0.04em;
  padding:2px 8px; border-radius:99px; background:var(--surface-2); border:1px solid var(--border-strong); color:var(--ink-2);
}
.role-badge.admin{background:var(--wine-fill); color:var(--wine); border-color:transparent;}
.role-badge.manager{background:var(--gold-fill); color:var(--gold); border-color:transparent;}
.role-badge.owner{background:var(--good-fill); color:var(--good); border-color:transparent;}
.link-btn{
  background:none; border:none; padding:0; font:inherit; font-size:13px; cursor:pointer;
  color:var(--teal); text-decoration:underline;
}
.link-btn.danger{color:var(--critical);}
.grant-form{display:flex; gap:8px; flex-wrap:wrap; margin-top:12px; align-items:center;}
.grant-form input, .grant-form select{
  font:inherit; font-size:14px; padding:8px 10px; border-radius:8px;
  border:1px solid var(--border-strong); background:var(--surface-2); color:var(--ink);
}
.grant-form button{
  font:inherit; font-weight:700; font-size:14px; padding:8px 14px; border-radius:8px;
  border:none; background:#1F5D3A; color:#fff; cursor:pointer;
}
.grant-form button:hover{opacity:0.92;}

/* ---- parcelas ---- */
.parcelas-head{display:flex; justify-content:space-between; align-items:center; gap:12px; flex-wrap:wrap; margin-bottom:18px;}
.parcelas-head h1{font-family:Archivo,sans-serif; font-weight:800; font-size:clamp(18px,2.55vw,24px); margin:0;}
/* Migas de pan dentro del propio h1 (p.ej. "Parcelas / Cesar / Solana") --
   los tramos ya recorridos son un link mas apagado, el ultimo (donde estas)
   se queda con el peso normal del titulo. */
.crumb-link{
  background:none; border:none; padding:0; font:inherit; color:var(--muted); cursor:pointer; text-decoration:none;
}
.crumb-link:hover{color:var(--ink); text-decoration:underline;}
.crumb-sep{color:var(--muted); margin:0 8px; font-weight:400;}
.parcelas-head-left{display:flex; align-items:center; gap:10px; flex-wrap:wrap;}
.parcela-detail-actions{display:flex; gap:8px; flex-wrap:wrap;}

/* Desktop: breadcrumb + botones (Tratamiento/Trabajo/Cuaderno/Nueva
   parcela/Editar/Eliminar, segun la vista) fijos al hacer scroll, igual que
   ya pasa en mobile (ver @media max-width:760px mas abajo, con su propio
   ajuste de padding/margenes) -- aqui basta con pegarlo bajo el topnav
   (56px de alto, sticky con z-index:10). */
@media (min-width:761px){
  #parcelas-view .parcelas-head, #parcela-detail-view .parcelas-head, #cuaderno-view .parcelas-head{
    position:sticky; top:56px; z-index:9; background:var(--bg);
    padding:14px 0; margin-bottom:8px;
  }
}

/* Mini-cards seleccionables del modal "Aplicar tratamiento/trabajo": parcelas
   (multi-seleccion) y maestro (seleccion unica), mismo aspecto para las dos. */
.mini-select-grid{display:grid; grid-template-columns:repeat(auto-fill, minmax(150px,1fr)); gap:8px; margin:8px 0 16px;}
.mini-select-card{
  display:flex; flex-direction:column; align-items:flex-start; gap:2px; text-align:left;
  padding:9px 12px; border-radius:10px; border:1px solid var(--border-strong); background:var(--surface);
  cursor:pointer; font:inherit; color:var(--ink); font-size:13.5px; transition:background .12s, border-color .12s;
  /* Sin esto, un grid item no se encoge por debajo del contenido minimo de
     su texto (min-width:auto por defecto) -- una card con un nombre largo
     ("Sercadis, Daramun y Biabrio"...) se salia de su columna y ensanchaba
     toda la fila en vez de quedarse a la mitad de ancho y dejar que el texto
     salte de linea (nombre) o trunque con "..." (mini-select-sub). */
  min-width:0; overflow:hidden;
}
.mini-select-card:hover{background:var(--surface-2);}
.mini-select-card .mini-select-sub{font-size:12px; color:var(--muted);}
/* "Ver mas..."/"Ver menos" (paso 1 del asistente): revela/oculta los tipos
   sin datos (p.ej. "Otro (0)"), ocultos por defecto -- ver
   aplicarTiposVerMas. Ocupa toda la fila (no es una card de dato mas) y va
   sin relleno ni borde solido, para que se note que es una accion distinta
   de seleccionar un tipo. */
.aplicar-ver-mas{
  grid-column:1/-1; display:flex; align-items:center; justify-content:center; gap:6px;
  padding:8px; border:1px dashed var(--border-strong); border-radius:10px; background:none;
  cursor:pointer; font:inherit; font-size:13px; color:var(--ink-2);
}
.aplicar-ver-mas:hover{color:var(--ink); background:var(--surface-2);}
.mini-select-card.selected{background:#1F5D3A; border-color:#1F5D3A; color:#fff;}
.mini-select-card.selected .mini-select-sub{color:rgba(255,255,255,0.75);}
/* Paso 1 del asistente (tipo de tratamiento/tipo de trabajo, misma grid
   #aplicar-tipos-grid para los 2 kinds): negro en vez del verde de arriba,
   para distinguir de un vistazo "tipo elegido" (filtra la lista de abajo)
   de "tratamiento/trabajo elegido" (#aplicar-maestros-grid, se van a crear
   registros de eso). */
#aplicar-tipos-grid .mini-select-card.selected, #tipos-grid .mini-select-card.selected{background:#000; border-color:#000; color:#fff;}
/* Cards de tipo, de tratamiento/trabajo y de parcela del asistente: si esta
   seleccionada se ve una X a la derecha, centrada verticalmente -- pista
   visual de que volver a pulsar la card entera la deselecciona. Mismo
   mecanismo en #tipos-grid (catalogo de tratamientos/trabajos, ver
   catalogo-maestro.js), que solo filtra abajo -- no "elige" nada. */
#aplicar-tipos-grid .mini-select-card, #aplicar-maestros-grid .mini-select-card, #aplicar-parcelas-grid .mini-select-card, #lista-parcelas-check .mini-select-card, #tipos-grid .mini-select-card{position:relative;}
#aplicar-tipos-grid .aplicar-card-remove-icon, #aplicar-maestros-grid .aplicar-card-remove-icon, #aplicar-parcelas-grid .aplicar-card-remove-icon, #lista-parcelas-check .aplicar-card-remove-icon, #tipos-grid .aplicar-card-remove-icon{
  display:none; position:absolute; right:10px; top:50%; transform:translateY(-50%);
  font-size:13px; color:currentColor;
}
#aplicar-tipos-grid .mini-select-card.selected .aplicar-card-remove-icon,
#aplicar-maestros-grid .mini-select-card.selected .aplicar-card-remove-icon,
#aplicar-parcelas-grid .mini-select-card.selected .aplicar-card-remove-icon,
#lista-parcelas-check .mini-select-card.selected .aplicar-card-remove-icon,
#tipos-grid .mini-select-card.selected .aplicar-card-remove-icon{display:inline-block;}
#aplicar-tipos-grid .mini-select-card.selected, #aplicar-maestros-grid .mini-select-card.selected, #aplicar-parcelas-grid .mini-select-card.selected, #lista-parcelas-check .mini-select-card.selected, #tipos-grid .mini-select-card.selected{padding-right:30px;}
/* Nombre de la parcela mas grande en el filtro de Contabilidad -- aqui es
   el unico dato de la card (sin tipo/cantidad debajo, ver mini-select-sub),
   asi que puede permitirse mas peso visual que en el asistente. */
#lista-parcelas-check .mini-select-card > span:first-child{font-size:16px; font-weight:600;}
/* Paso 2 (parcelas) del asistente "Aplicar tratamiento/trabajo": una vez
   elegida una parcela de un propietario, las de los demas (y sus cards de
   grupo) se deshabilitan -- no se puede mezclar en la misma tanda. */
.mini-select-card:disabled{opacity:0.35; cursor:not-allowed;}
.mini-select-card:disabled:hover{background:var(--surface);}

/* Asistente por pasos del modal "Aplicar tratamiento/trabajo". El paso
   actual ("(1/4) Tratamiento") va directamente en el titulo del modal
   (#aplicar-modal-title), no hace falta una etiqueta aparte. */
.wizard-breadcrumb{margin-bottom:8px; font-size:13.5px;}
.wizard-breadcrumb:empty{display:none;}
.wizard-nav{display:flex; justify-content:space-between; align-items:center; gap:10px; margin-top:18px;}
/* Anterior/Siguiente/Confirmar van agrupados a la derecha, junto a Cancelar
   a la izquierda -- el "(x/y)" se queda solo como texto en la cabecera de
   color, sin botones de navegacion ahi (ver .aplicar-step-count). */
.wizard-nav-right{display:flex; align-items:center; gap:10px;}
.aplicar-step-count{font-family:"IBM Plex Mono",monospace; font-size:20px; color:#1C211D; opacity:0.75;}
.aplicar-step-title-suffix{font-size:14px; font-weight:400; color:var(--muted);}

/* Paso 3 (fecha) del asistente: calendario del mes en curso, navegable, en
   vez de un <input type="date"> pelado que depende del picker nativo. */
.mini-calendar{max-width:320px; margin:0 auto;}
.mini-calendar-head{display:flex; align-items:center; justify-content:space-between; margin-bottom:12px;}
.mini-calendar-label{font-family:Archivo,sans-serif; font-weight:700; font-size:15.5px; text-transform:capitalize;}
.mini-calendar-nav{
  display:inline-flex; align-items:center; justify-content:center;
  width:32px; height:32px; border-radius:8px; border:1px solid var(--border-strong); background:var(--surface);
  cursor:pointer; color:var(--ink-2);
}
.mini-calendar-nav:hover{background:var(--surface-2);}
.mini-calendar-weekdays{
  display:grid; grid-template-columns:repeat(7,1fr); text-align:center;
  font-family:"IBM Plex Mono",monospace; font-size:11.5px; color:var(--muted); margin-bottom:4px;
}
.mini-calendar-grid{display:grid; grid-template-columns:repeat(7,1fr); gap:4px;}
.mini-calendar-cell{
  aspect-ratio:1; display:flex; align-items:center; justify-content:center;
  border-radius:8px; border:1px solid transparent; background:none; cursor:pointer;
  font-family:"IBM Plex Mono",monospace; font-size:13.5px; color:var(--ink);
}
.mini-calendar-cell:hover{background:var(--surface-2);}
.mini-calendar-cell.today{border-color:var(--border-strong); font-weight:700;}
.mini-calendar-cell.selected{background:#1F5D3A; color:#fff; border-color:#1F5D3A;}
.mini-calendar-cell.empty{cursor:default; pointer-events:none;}
/* Mes siguiente apilado debajo del principal -- solo en mobile (ver mas
   abajo), en desktop hay de sobra con el mes activo + nav prev/next. */
.mini-calendar-secondary{display:none; margin-top:14px;}
.mini-calendar-secondary .mini-calendar-head{justify-content:center;}
.parcelas-mobile-actions{display:none;}
.head-icon-btn{display:none;}
/* Editar/Eliminar de la ficha de parcela (ahora dentro de la card "Datos",
   a la derecha del titulo): mismo relleno de color que ya usaba el icono
   suelto del breadcrumb (head-icon-btn.secondary/.danger) -- aqui se ve en
   todas las resoluciones, con icono+texto en desktop e icono solo en
   mobile (ver la regla mobile mas abajo). */
.panel-action-btn{
  display:inline-flex; align-items:center; justify-content:center; gap:6px; flex-shrink:0;
  border:none; border-radius:8px; cursor:pointer;
  font-family:"IBM Plex Mono",monospace; font-size:13px;
  padding:6px 12px; color:var(--bg);
}
.panel-action-btn:hover{opacity:0.88;}
.panel-action-btn.secondary{background:var(--wine);}
.panel-action-btn.danger{background:var(--critical);}
@media (max-width:760px){
  /* En mobile, "Cuaderno de campo"/"Nueva parcela"/"Editar"/"Eliminar" ya no
     van bajo el titulo -- "Nueva parcela" (y en la ficha, tambien Editar y
     Eliminar) pasan a icono suelto en la propia fila de breadcrumbs, y
     Cuaderno + los dos "+Tratamiento/+Trabajo" bajan a la barra fija sobre
     el pie de pagina (misma barra para listado y ficha, ver parcelas.js). */
  #parcelas-view .parcelas-head .parcela-detail-actions{display:none;}
  #parcelas-view .parcelas-head-left .range-btn{display:none;}
  #parcela-detail-view .parcelas-head .parcela-detail-actions{display:none;}
  #cuaderno-view .parcelas-head .parcela-detail-actions{display:none;}
  /* Breadcrumb + botones de cabecera fijos al hacer scroll (justo debajo del
     topnav, que ya es sticky con 56px de alto) en las 3 vistas de parcelas:
     listado, ficha y cuaderno de campo -- todas comparten .parcelas-head. */
  .parcelas-head{
    position:sticky; top:56px; z-index:9; background:var(--bg);
    padding:10px 0; margin-bottom:8px;
  }
  /* Listado y ficha de parcela: menos aire arriba (entre el menu superior y
     el breadcrumb) y a los lados (el breadcrumb se acerca mas al borde que
     el resto del contenido, que se queda con el margen de .wrap de siempre). */
  #parcelas-view .parcelas-head, #parcela-detail-view .parcelas-head, #cuaderno-view .parcelas-head{
    padding-top:2px; padding-bottom:6px;
    margin-left:-8px; margin-right:-8px; padding-left:8px; padding-right:8px;
  }
  #parcela-detail-view .parcelas-head{flex-wrap:nowrap;}
  /* Los botones (+/Editar/Eliminar) tienen que verse siempre en la misma
     fila que el breadcrumb, aunque el nombre de la parcela sea muy largo --
     en vez de bajar a una segunda linea (parcelas-head ya no envuelve, ver
     arriba), es el propio nombre el que se trunca con puntos suspensivos. */
  #detail-nombre{min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; flex:1 1 auto;}
  /* Fondo solido (no solo borde) para que se distinga de un vistazo en la
     fila de breadcrumbs -- "+ Parcela" (icono+texto, no solo icono). */
  .head-icon-btn{
    display:inline-flex; align-items:center; justify-content:center; gap:6px; flex-shrink:0;
    height:34px; padding:0 12px; border-radius:8px; border:none;
    background:var(--teal); color:var(--bg); cursor:pointer; font-size:14px;
    font-family:"IBM Plex Mono",monospace; white-space:nowrap;
  }
  .head-icon-btn:hover{opacity:0.88;}
  /* Editar/Eliminar de la card "Datos": en mobile solo el icono (mismo
     cuadrado 34x34 que el resto de head-icon-btn), sin el texto. */
  .panel-action-btn{width:34px; height:34px; padding:0;}
  .panel-action-btn span{display:none;}
  .parcelas-mobile-actions:not([hidden]){
    display:flex; flex-wrap:wrap; position:fixed; left:0; right:0; z-index:14;
    bottom:calc(55px + env(safe-area-inset-bottom));
    margin:0; padding:8px 10px 16px; gap:8px; justify-content:center;
    background:var(--surface); border-top:1px solid var(--border); box-shadow:var(--shadow);
  }
  .parcelas-wrap{padding-bottom:calc(180px + env(safe-area-inset-bottom));}
  /* Tablas de tratamientos/trabajos de la ficha de parcela: en mobile solo
     lo imprescindible para reconocer la fila de un vistazo -- el resto de
     campos se ven en el modal de detalle (lupa o toda la fila, ver
     parcelas.js). En escritorio se siguen viendo todas las columnas. */
  #tabla-tratamientos .col-mobile-hide, #tabla-trabajos .col-mobile-hide, #tabla-cuaderno .col-mobile-hide{display:none;}
  /* Segmentos de breadcrumb que en mobile se colapsan a solo icono (menos
     ruido en la fila): "Parcelas" cuando es un link seguido de mas tramos
     (ver crumbHomeHtml en parcelas.js) y el usuario dentro de la ficha de
     una parcela (renderDetailBreadcrumb) -- en el listado de un usuario
     (renderListBreadcrumb) el nombre si se mantiene. */
  .crumb-collapsible{display:none;}
  /* Titulo de panel demasiado largo para su fila (p.ej. "Riesgo fitosanitario
     vs tratamientos"): en vez de salirse por la derecha de la card, se trunca
     con puntos suspensivos. flex-shrink:0 de la regla base es justo lo que
     hay que revertir aqui para que pueda encogerse y truncar. */
  .panel-head-left{flex:1 1 auto; min-width:0;}
  .panel-title{flex:1 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
  .panel-range, .panel-head-actions{flex-shrink:0;}
  /* Breadcrumb ya al 75% en la regla base (aplica a todas las resoluciones,
     ver .parcelas-head h1 arriba) -- nada que hacer aqui. */
  /* "Actualizar desde Catastro": en mobile solo el icono (mismo texto queda
     para lectores de pantalla via aria-label), pegado justo a la izquierda
     del boton de plegar/desplegar -- ver panel-head-actions en el HTML. */
  #btn-refresh-catastro span{display:none;}
  #btn-refresh-catastro{
    display:inline-flex; align-items:center; justify-content:center;
    width:26px; height:26px; border-radius:8px; background:var(--surface-2); border:1px solid var(--border-strong);
    text-decoration:none;
  }
  /* Modal de detalle de tratamiento/trabajo: etiqueta y valor apilados (uno
     debajo del otro) en vez de en la misma fila -- mas legible en mobile,
     sobre todo con valores largos (producto, notas). */
  #item-detalle-body .mini-row{flex-direction:column; align-items:flex-start; gap:2px;}
  #item-detalle-body .mv{text-align:left;}
  /* Listado de parcelas: 2 columnas en vez de 1 -- el ancho minimo de
     .parcela-grid (220px) no dejaba sitio para dos en un movil normal. */
  #parcelas-grid, #lista-grid{grid-template-columns:1fr 1fr;}
  /* Cuaderno de campo: menos aire entre columnas ahora que quedan menos
     visibles (ver .col-mobile-hide arriba) -- el margen a los lados de la
     vista se queda con el mismo estandar que el resto (.wrap), sin acercar
     esta tabla mas al borde que las demas. */
  #tabla-cuaderno th, #tabla-cuaderno td{padding:6px 2px;}
  #tabla-cuaderno th:first-child, #tabla-cuaderno td:first-child{padding-left:0;}
  #tabla-cuaderno th:last-child, #tabla-cuaderno td:last-child{padding-right:0;}
  /* "Categoría" -> "CAT." en la cabecera para que quepa en menos ancho
     (el contenido de cada fila ya usa TTO/TRA, ver categoriaLabelEvento). */
  .cat-label-full{display:none;}
  .cat-label-short{display:inline;}
  /* Card de Riesgo fitosanitario: leyenda 2px mas pequeña -- se mantiene asi
     tambien en el modal a pantalla completa (misma leyenda, no se duplica). */
  #panel-riesgo .legend-item{font-size:13px;}
  /* En el modal a pantalla completa, el chevron de plegar/desplegar la card
     ya no pinta nada (redundante con la X de cerrar, que es el mismo boton
     de ampliar/#btn-expand-riesgo re-etiquetado) -- se oculta y solo queda
     la X. */
  #panel-riesgo.is-expanded .panel-toggle-btn{display:none;}
}

.parcela-grid{display:grid; grid-template-columns:repeat(auto-fill, minmax(220px,1fr)); gap:14px;}
.parcela-card{
  text-align:left; display:flex; flex-direction:column; gap:4px; min-width:0;
  background:var(--surface); border:1px solid var(--border); border-radius:14px;
  padding:14px 16px; box-shadow:var(--shadow); cursor:pointer; font:inherit; color:inherit;
}
.parcela-card:hover{background:var(--surface-2);}
/* "Ver todas" (solo admin, web/static/parcelas.js): parcelas que no son del
   usuario actual llevan un fondo claro distinto (azulado) para que se
   distingan de un vistazo de las propias, que se quedan tal cual. */
.parcela-card.foreign{background:color-mix(in srgb, var(--blue) 8%, var(--surface)); border-color:color-mix(in srgb, var(--blue) 25%, var(--border));}
.parcela-card.foreign:hover{background:color-mix(in srgb, var(--blue) 14%, var(--surface));}
.parcela-card-title{font-family:Archivo,sans-serif; font-weight:700; font-size:16px; display:flex; align-items:center; gap:8px; min-width:0;}
.parcela-card-title i{color:var(--wine); flex-shrink:0;}
/* Texto del titulo (nombre de parcela o de usuario en las group-cards):
   si no cabe en el ancho de la card (nombres largos, 2 columnas en movil)
   se trunca con "..." en vez de forzar la card a crecer y romper el grid. */
.pc-title-text{min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.parcela-card-line{font-size:14px; color:var(--ink-2); overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.parcela-card-line.muted{color:var(--muted); font-size:13px;}
.muted{color:var(--muted);}   /* utilidad generica -- fuera de .parcela-card-line, p.ej. en el breadcrumb de /contabilidad */
.parcela-card-line.badges{display:flex; gap:8px; flex-wrap:wrap; align-items:center; margin:2px 0 6px; white-space:normal; overflow:visible;}

#btn-volver-parcelas{margin-bottom:14px; font-size:14.5px;}
#btn-volver-parcelas i{margin-right:4px;}

.parcela-mini-map{width:100%; height:220px; border-radius:12px; overflow:hidden; border:1px solid var(--border);}

.parcela-form{display:flex; flex-direction:column; gap:12px; margin-bottom:16px;}
.parcela-form[hidden]{display:none;}
.parcela-form label{display:flex; flex-direction:column; gap:6px; font-size:13.5px; color:var(--ink-2); flex:1; min-width:0;}
.parcela-form input, .parcela-form select, .parcela-form textarea{
  font:inherit; font-size:15px; padding:9px 11px; border-radius:8px;
  border:1px solid var(--border-strong); background:var(--surface-2); color:var(--ink);
}
.parcela-form textarea{resize:vertical;}
.parcela-form input:focus, .parcela-form select:focus, .parcela-form textarea:focus{outline:2px solid var(--teal); outline-offset:1px;}
.parcela-form .field-row{display:flex; gap:12px; flex-wrap:wrap;}
/* display:flex de arriba gana al [hidden]{display:none} nativo del
   navegador (misma trampa que .panel[hidden] mas abajo) -- sin esto, un
   field-row oculto por JS (campos que solo aplican a tratamientos o solo a
   trabajos en el formulario de detalle, ver openItemForm en parcelas.js)
   se queda visible aunque el atributo hidden este puesto. */
.parcela-form .field-row[hidden]{display:none;}

/* Productos fitosanitarios de una receta (form-maestro de Tratamientos, ver
   catalogo-maestro.js): 0..N filas, cada una con su propia cantidad/unidad
   -- sustituye al antiguo campo suelto "Producto". */
.form-productos-label{font-size:13.5px; color:var(--ink-2);}
.form-productos-label .muted{color:var(--muted); font-weight:400;}
.producto-row{
  display:flex; align-items:flex-start; gap:8px; flex-wrap:wrap;
  padding:10px; margin-top:8px; border:1px solid var(--border-strong); border-radius:10px; background:var(--surface-2);
}
.producto-row-main{display:flex; flex-direction:column; gap:2px; flex:1 1 160px; min-width:0;}
.producto-row-nombre{font-size:13.5px; font-weight:600; color:var(--ink);}
.producto-row-hint{font-size:12px; color:var(--ink-2);}
.producto-row-hint.warn{color:var(--critical); font-weight:600;}
.producto-row-badge{font-size:12px; color:var(--muted); font-style:italic;}
.producto-row-total{font-size:12px; color:var(--muted);}
.producto-row-total:empty{display:none;}
.producto-row-cantidad{width:80px; flex:0 0 auto;}
.producto-row-unidad{flex:0 0 auto; min-width:110px;}
.producto-row-unidad-label{font-size:13px; color:var(--ink-2); flex:0 0 auto; align-self:center;}
.producto-row input, .producto-row select{font-size:14px; padding:7px 9px;}
.producto-row.exceeds{border-color:var(--critical);}
/* Campo extra de una fila de producto con su propia etiqueta encima --
   "Coste" (€/kg o €/l, catalogo-maestro.js) y "Total" (cantidad a preparar
   para toda la superficie, bidireccional con la dosis -- ver
   dosisDesdeTotal/totalDesdeDosis en parcelas.js). */
.producto-row-total-field{display:flex; align-items:flex-end; gap:6px; flex:0 0 auto;}
.producto-row-total-field label{display:flex; flex-direction:column; gap:3px; font-size:11px; color:var(--muted);}
.producto-row-total-input{width:80px; border-radius:8px; border:1px solid var(--border-strong); background:var(--surface); color:var(--ink);}
.producto-row-importe{background:var(--surface-2); color:var(--ink-2); font-weight:600;}
.producto-row-total-unidad{font-size:13px; color:var(--ink-2); padding-bottom:7px;}

/* Paso "Dosis" del asistente Aplicar tratamiento (ver renderAplicarDosis en
   parcelas.js): una seccion por receta elegida en el paso 1, con sus
   productos y la dosis que se va a aplicar esta vez -- reutiliza las mismas
   .producto-row de arriba. */
.aplicar-dosis-maestro{margin-bottom:16px;}
.aplicar-dosis-maestro:last-child{margin-bottom:0;}
.aplicar-dosis-maestro-nombre{font-size:14px; font-weight:700; color:var(--ink); margin-bottom:2px;}
/* Eficacia estimada de ESTA aplicacion (no se guarda en la receta, ver
   aplicarEficacia en parcelas.js) -- una fila mas, debajo de sus productos. */
.aplicar-dosis-eficacia{
  display:flex; align-items:center; justify-content:flex-start; gap:10px;
  margin-top:8px; font-size:13.5px; color:var(--ink-2);
}
/* Eficacia a la izquierda y, si la receta lleva varios productos, la suma de
   sus importes a la derecha (aplicarImporteTratamientoTxt en parcelas.js). */
.aplicar-dosis-eficacia-row{display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap:wrap;}
.aplicar-dosis-importe-total{
  margin-top:8px; padding:6px 14px; border-radius:10px;
  font-size:18px; font-weight:800; line-height:1.3;
  background:#B4D6BB; color:#12301B;
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) .aplicar-dosis-importe-total{background:#2F5236; color:#E6F4E9;}
}
:root[data-theme="dark"] .aplicar-dosis-importe-total{background:#2F5236; color:#E6F4E9;}
.aplicar-dosis-eficacia input{width:80px; font-size:14px; padding:7px 9px; border-radius:8px; border:1px solid var(--border-strong); background:var(--surface-2); color:var(--ink);}
/* Ritmo (h/ha) y precio (€/h) de un trabajo (ver aplicarHoras en
   parcelas.js) -- mismo aspecto de input que la eficacia de arriba, pero en
   dos columnas con su etiqueta encima en vez de al lado, porque aqui son
   dos campos en vez de uno. */
.aplicar-dosis-maestro .field-row{display:flex; gap:8px; margin-top:8px; flex-wrap:wrap;}
.aplicar-dosis-maestro .field-row label{display:flex; flex-direction:column; gap:4px; font-size:13.5px; color:var(--ink-2); flex:1; min-width:60px;}
.aplicar-horas-input{font-size:14px; padding:7px 9px; border-radius:8px; border:1px solid var(--border-strong); background:var(--surface-2); color:var(--ink); width:100%;}
.producto-remove-btn{
  background:none; border:none; color:var(--muted); cursor:pointer; padding:6px; margin:-6px -4px -6px 0;
  font-size:15px; flex:0 0 auto;
}
.producto-remove-btn:hover{color:var(--critical);}
.producto-search-row{position:relative; margin-top:10px;}
.producto-search-results{
  position:absolute; left:0; right:0; top:calc(100% + 4px); z-index:5;
  background:var(--surface); border:1px solid var(--border-strong); border-radius:10px;
  box-shadow:var(--shadow); max-height:220px; overflow-y:auto;
}
.producto-search-result{
  display:block; width:100%; text-align:left; padding:9px 12px; border:none; background:none;
  cursor:pointer; font:inherit; font-size:13.5px; color:var(--ink);
}
.producto-search-result:hover{background:var(--surface-2);}
.producto-search-result .muted{display:block; font-size:12px; color:var(--muted);}
.producto-search-empty{padding:9px 12px; font-size:13px; color:var(--muted);}
/* Producto sin registro fitosanitario (catalogo-maestro.js): buscador aparte
   del de arriba porque pega contra el catalogo propio del usuario
   (productos_manuales), no contra el registro MAPA -- mismo aspecto que
   .producto-search-row/-result, mas la opcion de crear uno nuevo si no hay
   coincidencia exacta con lo escrito. */
.producto-manual-row{position:relative; margin-top:8px;}
.producto-search-result-nuevo{color:var(--teal); font-weight:600;}

.modal-backdrop{position:fixed; inset:0; z-index:40; background:rgba(0,0,0,0.55); display:flex; align-items:flex-start; justify-content:center; padding:40px 16px; overflow-y:auto;}
.modal-backdrop[hidden]{display:none;}
.modal-box{
  width:100%; max-width:520px; background:var(--surface); border:1px solid var(--border);
  border-radius:16px; padding:18px 20px 20px; box-shadow:var(--shadow);
}
.modal-box-wide{max-width:1040px;}
.modal-box-narrow{max-width:420px;}
/* Detalle de un tratamiento con productos (#item-detalle-backdrop, ver
   openItemForm en parcelas.js): dosis/unidad/total/precio de cada producto
   necesitan mas sitio que el resto de usos de este mismo modal (Notas,
   eventos del Cuaderno, trabajos) -- se ensancha solo cuando de verdad hay
   productos que mostrar (clase .has-productos), igual que .step-dosis en
   el asistente Aplicar. */
#item-detalle-backdrop.has-productos .modal-box{max-width:680px;}
/* Misma reestructuracion que el paso "Dosis" del asistente (ver mas abajo,
   #aplicar-dosis-list): nombre+aviso de superficie arriba a todo lo ancho,
   dosis/unidad/total/precio en su propia fila debajo. */
#form-item-productos-list .producto-row{flex-direction:column; align-items:stretch;}
#form-item-productos-list .producto-row-main{flex:none;}
#form-item-productos-list .producto-row-inputs{display:flex; align-items:flex-end; gap:10px; flex-wrap:wrap; margin-top:8px;}
.producto-row-total-input-select{width:100px;}
/* El asistente "Aplicar tratamiento/trabajo" (#aplicar-modal-backdrop) usa a
   proposito el .modal-box normal (520px en vez de los 1040px de
   .modal-box-wide) en desktop -- la mitad de ancho, a peticion. En mobile no
   cambia nada: las reglas de mas abajo ya lo fuerzan a 100% de ancho.
   Excepcion: el paso "Dosis" (nombre+avisos del producto a todo lo ancho,
   ver aplicarDosisRowHtml en parcelas.js) necesita algo mas de sitio para
   que quepa el aviso de dosis autorizada en una sola linea -- se ensancha
   solo mientras se ve ese paso concreto (clase .step-dosis puesta/quitada
   en goToAplicarStep), el resto de pasos se quedan en la anchura de siempre. */
#aplicar-modal-backdrop.step-dosis .modal-box{max-width:760px;}
/* Fila de producto del paso "Dosis": nombre+avisos a la izquierda y
   Dosis/Hectareas/Total/Precio/Importe a la derecha, en la misma linea, para
   que la tarjeta sea baja. Si no caben (mobile), los campos bajan solos
   debajo del nombre por el flex-wrap de .producto-row. */
#aplicar-dosis-list .producto-row{align-items:center; gap:6px 12px;}
#aplicar-dosis-list .producto-row-main{flex:1 1 130px;}
#aplicar-dosis-list .producto-row-inputs{display:flex; gap:8px; flex-wrap:wrap; margin-top:0; flex:0 1 auto;}
#aplicar-dosis-list .producto-row-total-input{width:68px; padding:7px 6px;}
/* Cabecera del asistente "Aplicar tratamiento/trabajo" con banda de color de
   punta a punta, mismo criterio que .device-card-head en la vista de
   Estacion -- color fijo (no cambia con el tema oscuro), igual que alli. */
#aplicar-modal-backdrop .panel-head, #modal-parcelas-backdrop .panel-head{
  background:#DCEBDF; color:#1C211D;
  margin:-18px -20px 16px; padding:14px 20px;
  border-radius:16px 16px 0 0;
}

.modal-close-btn{
  display:inline-flex; align-items:center; justify-content:center; flex-shrink:0;
  width:30px; height:30px; border-radius:8px; font-size:15px;
  background:var(--critical-fill); color:var(--critical); border:1px solid transparent; cursor:pointer;
}
.modal-close-btn:hover{background:var(--critical); color:#fff;}

/* Dos columnas (datos / mapa) a partir de la anchura de escritorio -- en
   mobile cada .parcela-form-col ya es de por si una columna vertical, asi
   que sin el grid simplemente se apilan una tras otra. */
.parcela-form-cols{display:flex; flex-direction:column; gap:12px;}
.parcela-form-col{display:flex; flex-direction:column; gap:12px; min-width:0;}
@media (min-width:761px){
  .parcela-form-cols{display:grid; grid-template-columns:1fr 1fr; gap:24px; align-items:start;}
}
@media (max-width:760px){
  .modal-backdrop{padding:0; align-items:flex-end;}
  .modal-box{max-width:none; border-radius:16px 16px 0 0; max-height:92vh; overflow-y:auto;}
  /* Asistente "Aplicar tratamiento/trabajo": 2 columnas fijas de mini-cards
     (tipos, parcelas) en vez de que auto-fill decida cuantas caben. */
  .mini-select-grid{grid-template-columns:1fr 1fr;}
  /* Tratamientos/trabajos maestros (paso 1, nivel 2): 2 columnas como el
     resto -- el nombre largo salta de linea dentro de su columna en vez de
     ensanchar la card (ver align-items:stretch, hace que el texto ocupe
     todo el ancho de la columna en vez de encogerse a su contenido). */
  #aplicar-maestros-grid{grid-template-columns:1fr 1fr;}
  #aplicar-maestros-grid .mini-select-card{align-items:stretch;}
  #aplicar-maestros-grid .mini-select-card > span:first-child{white-space:normal; overflow-wrap:anywhere;}
  /* Subtitulo de las mini-cards seleccionables (tipo+producto en tratamiento/
     trabajo, cultivo en parcela, "N parcelas" en las de usuario): una sola
     linea con "..." si no cabe, en vez de partirse en varias. */
  .mini-select-sub{
    display:block; align-self:stretch; max-width:100%;
    overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  }
  /* Modal de detalle de tratamiento/trabajo, de datos catastrales, de
     confirmar eliminar parcela (ficha de parcela) y de nuevo tratamiento/
     trabajo maestro (paginas /tratamientos y /trabajos): a diferencia del
     resto de modales en mobile (hoja que sube desde abajo), estos van
     centrados verticalmente -- vuelven a tener bordes redondeados en las 4
     esquinas en vez de solo arriba. */
  #item-detalle-backdrop, #catastro-modal-backdrop, #confirmar-eliminar-backdrop, #confirmar-eliminar-maestro-backdrop, #modal-backdrop{align-items:center; padding:16px;}
  #item-detalle-backdrop .modal-box, #catastro-modal-backdrop .modal-box, #confirmar-eliminar-backdrop .modal-box, #confirmar-eliminar-maestro-backdrop .modal-box, #modal-backdrop .modal-box{border-radius:16px; max-height:85vh;}
  /* Asistente "Aplicar tratamiento/trabajo": ocupa casi todo el alto, con
     el margin minimo (12px, el mismo inset que el resto de vistas en
     mobile, ver .wrap:has(...) mas abajo) para que se le sigan viendo los
     border-radius de las 4 esquinas -- el modal-box es una columna flex de
     3 partes: cabecera (fija), paso actual (crece y scrollea el solo, para
     que un paso con mucho contenido no empuje los botones) y
     Cancelar/Anterior/Siguiente (fijos abajo, misma posicion en los 4
     pasos). El "bleed" de la cabecera de color (ver #aplicar-modal-backdrop
     .panel-head, mas arriba) se reajusta igual para seguir llegando justo
     al borde. */
  #aplicar-modal-backdrop{align-items:stretch; padding:12px;}
  #aplicar-modal-backdrop .modal-box{
    display:flex; flex-direction:column;
    width:100%; max-width:none; height:auto; max-height:none;
    border-radius:16px; padding:8px 10px 10px; overflow-y:hidden;
  }
  #aplicar-modal-backdrop .panel-head{margin:-8px -10px 10px; flex-shrink:0;}
  #aplicar-modal-backdrop .wizard-panel{flex:1; min-height:0; overflow-y:auto;}
  #aplicar-modal-backdrop #aplicar-form-error{flex-shrink:0;}
  #aplicar-modal-backdrop .wizard-nav{flex-shrink:0; border-top:1px solid var(--border); padding-top:12px;}
  /* Paso 1: texto de las cards de tipo mas grande. */
  #aplicar-tipos-grid .mini-select-card, #aplicar-maestros-grid .mini-select-card, #aplicar-parcelas-grid .mini-select-card{font-size:15.5px;}
  /* Paso 3 (fecha): mes actual + siguiente apilados, sin nav (no hace falta
     navegar para ver 2 meses fijos) -- mas compactos que en desktop para
     que los 2 quepan bien en la altura del paso (que ya scrollea el solo
     si hiciera falta, ver .wizard-panel mas arriba). */
  #aplicar-modal-backdrop .mini-calendar-secondary{display:block;}
  #aplicar-modal-backdrop .mini-calendar{max-width:280px;}
  #aplicar-modal-backdrop .mini-calendar-head{margin-bottom:6px;}
  #aplicar-modal-backdrop .mini-calendar-label{font-size:14px;}
  #aplicar-modal-backdrop .mini-calendar-nav{width:38px; height:38px; font-size:15px;}
  #aplicar-modal-backdrop .mini-calendar-weekdays{font-size:10.5px; margin-bottom:2px;}
  #aplicar-modal-backdrop .mini-calendar-grid{gap:2px;}
  /* Filas de semana mas bajas que anchas (en vez de 1:1) -- con 2 meses
     apilados, la altura de cada fila pesa mas que el ancho a la hora de
     que quepa todo bien. */
  #aplicar-modal-backdrop .mini-calendar-cell{font-size:12px; aspect-ratio:1.6;}
  /* Anterior/Siguiente desactivados: en mobile desaparecen en vez de
     quedarse grises (Confirmar ya se oculta via JS, ver goToAplicarStep) --
     Siguiente ademas resaltado en negro (llamada a la accion principal del
     paso, distinto de Cancelar/Anterior que son secundarios). */
  #btn-aplicar-anterior:disabled{display:none;}
  #btn-aplicar-siguiente{background:#000; color:#fff; border-color:#000;}
  /* Paso 4 (confirmar): sin la linea superior de .mini-list -- es el primer
     bloque del paso, ya separado del titulo por el espacio de la cabecera,
     asi que el borde ahi solo se veia como una raya suelta. */
  #aplicar-resumen{border-top:none; margin-top:0; padding-top:0;}
}

/* Cuaderno de campo impreso: solo la tabla, sin nav/botones/mapas de fondo. */
@media print{
  nav.topnav, .mobile-footer-nav, .mobile-popup-bar,
  #parcelas-view, #parcela-detail-view,
  #cuaderno-view #btn-volver-cuaderno, #cuaderno-view .parcela-detail-actions{
    display:none !important;
  }
  #cuaderno-view{display:block !important;}
}
