/* ══════════════════════════════════════════════════════════════
   APEX DASHBOARD V3 · LAYOUT  (AppShell)
   Estructura de la imagen canónica:
     fondo fotográfico a sangre
       └ sidebar oscura opaca, pegada al borde, altura completa
       └ panel principal flotante, redondeado, separado 8px
            └ franja fotográfica superior (topbar + saludo)
            └ contenido claro
   ══════════════════════════════════════════════════════════════ */

/* ── fondo ambiental ─────────────────────────────────────────── */
.ambient{
  position:fixed;inset:0;z-index:0;overflow:hidden;
  background:var(--ambient-fallback);
}
/* Mismo origen que el hero, muy desenfocado: el fondo de la app
   acompaña a la imagen editorial en vez de traer el color de un
   producto cualquiera. */
.ambient::before{
  content:'';position:absolute;inset:-8%;
  background-image:var(--hero-image), var(--hero-fallback);
  background-size:cover;background-position:center;
  filter:blur(var(--ambient-blur)) saturate(120%);
  transform:scale(1.08);
  opacity:1;
  transition:opacity var(--dur-slow) var(--ease);
}
.ambient::after{
  content:'';position:absolute;inset:0;
  background:
    radial-gradient(120% 90% at 80% 0%, rgba(0,0,0,.18), transparent 60%),
    linear-gradient(180deg, rgba(0,0,0,.30), rgba(0,0,0,.62));
  opacity:var(--ambient-dim);
}

/* ── shell ───────────────────────────────────────────────────── */
.shell{position:relative;z-index:1;display:flex;height:100vh;height:100dvh}

/* ── sidebar ─────────────────────────────────────────────────── */
.sidebar{
  width:var(--sidebar-w);flex:0 0 var(--sidebar-w);
  background:var(--sb-bg);color:var(--sb-ink);
  display:flex;flex-direction:column;
  border-right:1px solid var(--sb-hair);
}
.sb-brand{
  min-height:var(--topbar-h);display:flex;align-items:center;
  padding:var(--sp-2) var(--sp-6);flex-shrink:0;   /* 46 + 12 = alineado con la topbar */
}
/* Asset real de Apex, variante para fondo oscuro generada offline.
   Sin canvas, sin red: funciona igual por file:// que servido. */
.sb-brand img{height:var(--logo-h);width:auto}
.sb-scroll{flex:1;overflow-y:auto;padding:var(--sp-3) var(--sp-4) var(--sp-6)}
.sb-group{
  font-size:var(--fs-2xs);font-weight:var(--fw-semi);letter-spacing:var(--ls-label);
  text-transform:uppercase;color:var(--sb-ink-3);
  padding:var(--sp-7) var(--sp-4) var(--sp-3);
}
.sb-group:first-child{padding-top:var(--sp-3)}

.nav-item{
  width:100%;display:flex;align-items:center;gap:var(--sp-5);
  padding:var(--sp-4) var(--sp-4);border-radius:var(--r-sm);
  font-size:var(--fs-body);font-weight:var(--fw-regular);color:var(--sb-ink-2);
  border:1px solid transparent;text-align:left;
  transition:background var(--dur) var(--ease), color var(--dur) var(--ease),
             border-color var(--dur) var(--ease);
}
.nav-item .ico{flex:0 0 auto;color:currentColor}
.nav-item .lbl{flex:1;min-width:0}
.nav-item:hover{
  background:var(--sb-hover);color:var(--sb-ink);
  border-color:var(--sb-hover-line);
}
/* Estado activo: material, no color.
   Superficie apenas levantada + borde blanco translúcido finísimo.
   El acento de marca NO se usa para indicar navegación. */
.nav-item[aria-current="page"]{
  background:var(--sb-active);color:#fff;font-weight:var(--fw-medium);
  border-color:var(--sb-active-line);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.06);
}
.nav-item[aria-current="page"] .chev{opacity:.55}
.nav-item .chev{opacity:0;transition:opacity var(--dur) var(--ease)}
.nav-item .badge{margin-left:auto}

/* `.sb-foot`, `.sb-user`, `.who` y `.sb-flag` vivían acá y se
   eliminaron: eran el pie del sidebar —identidad, Cerrar sesión y la
   bandera de etapa— que se quitó cuando la cuenta pasó a ser el
   popover del avatar. Sin markup que las use, eran reglas que sólo
   podían confundir a quien leyera el archivo.

   `.sb-link` SÍ sigue viva: la usa el menú de navegación de mobile. */
.sb-link{
  width:100%;display:flex;align-items:center;gap:var(--sp-5);
  padding:var(--sp-4);border-radius:var(--r-sm);
  font-size:var(--fs-sm);color:var(--sb-ink-2);text-align:left;
  transition:background var(--dur) var(--ease),color var(--dur) var(--ease);
}
.sb-link:hover{background:var(--sb-hover);color:var(--sb-ink)}

/* ── panel principal ─────────────────────────────────────────── */
.panel{
  flex:1;min-width:0;position:relative;
  margin:var(--panel-gap) var(--panel-gap) var(--panel-gap) 0;
  border-radius:var(--r-xl);
  background:var(--panel);
  box-shadow:var(--sh-panel);
  display:flex;flex-direction:column;overflow:hidden;
  transition:background var(--dur) var(--ease);
}

/* ══════════════════════════════════════════════════════════════
   CONTEXTUAL COLLAPSING HEADER
   Un único valor continuo, --hp (0 expandido → 1 colapsado), deriva
   todo: alto, reencuadre de la foto, protagonismo del saludo y
   aparición del identificador de pantalla. No hay dos estados
   discretos: el header es una función del scroll.
   ══════════════════════════════════════════════════════════════ */
/* El hero YA NO usa una foto de producto. Una foto de blister dentro
   de su caja es catálogo, no editorial: en una franja apaisada se lee
   como un auto metido en una vitrina. Va una imagen automotriz propia
   —el slot `--hero-image`— y, mientras no exista, el degradado de
   tokens.css, compuesto para dejar la izquierda limpia. */
.hero{
  position:relative;flex-shrink:0;overflow:hidden;
  height:calc(var(--topbar-h) + var(--hero-h) * (1 - var(--hp)));
  min-height:var(--topbar-h);
  background-image:var(--hero-image), var(--hero-fallback);
  background-size:cover;
  /* el encuadre sube a medida que la franja se angosta, para no
     recortar el sujeto justo cuando queda menos alto disponible */
  background-position:center calc(38% + var(--hp) * 14%);
  background-color:var(--hero-bg);
}
/* La foto va en su propia capa para poder tratarla sin afectar al
   texto: una imagen muy saturada compite con la interfaz. */
.hero{isolation:isolate}
/* Velo base. Es lo que hace que el saludo se lea sobre CUALQUIER
   fotografía, no sólo sobre las oscuras: la imagen la elige el
   usuario desde Configuración y puede subir una clara.

   Tres capas: un degradado horizontal que hunde la izquierda —donde
   va el texto—, uno vertical que asienta la franja, y un piso plano
   mínimo que garantiza contraste aunque la foto sea blanca. */
.hero::after{
  content:'';position:absolute;inset:0;
  background:
    linear-gradient(100deg,
      rgba(8,8,10,.94) 0%, rgba(8,8,10,.86) 32%,
      rgba(8,8,10,.40) 62%, rgba(8,8,10,.14) 100%),
    linear-gradient(180deg, rgba(8,8,10,.34) 0%, rgba(8,8,10,.10) 46%, rgba(8,8,10,.30) 100%),
    rgba(8,8,10,.16);
}
/* velo adicional que entra con el colapso: deja una barra translúcida
   legible sin que la foto desaparezca del todo */
.hero::before{
  content:'';position:absolute;inset:0;z-index:1;
  background:rgba(8,8,10,.55);
  opacity:var(--hp);
}
.hero > *{position:relative;z-index:2}

/* borde inferior suave hacia el contenido; se retira al colapsar */
.hero-edge{
  position:absolute;left:0;right:0;bottom:0;height:26px;z-index:2;
  background:linear-gradient(to bottom, transparent, var(--panel));
  opacity:calc(1 - var(--hp));
  pointer-events:none;
}

/* ── topbar ──────────────────────────────────────────────────── */
.topbar{
  height:var(--topbar-h);display:flex;align-items:center;gap:var(--sp-5);
  padding:0 var(--sp-7);flex-shrink:0;
}
.topbar .spacer{flex:1}
.tb-right{display:flex;align-items:center;gap:var(--sp-2)}

/* identificador de pantalla: sólo existe cuando el header está colapsado.
   Interpola ancho además de opacidad para que no haya salto de layout. */
.tb-title{
  color:#fff;font-size:var(--fs-h2);font-weight:var(--fw-semi);
  letter-spacing:-.018em;white-space:nowrap;overflow:hidden;
  opacity:var(--hp);
  max-width:calc(var(--hp) * 180px);
  margin-left:calc(var(--hp) * var(--sp-2));
}

/* fecha discreta: contexto del saludo, sin card propia y sin semana */
.hero-fecha{
  color:rgba(255,255,255,.6);font-size:var(--fs-xs);
  letter-spacing:.02em;margin-bottom:var(--sp-3);
  text-shadow:0 1px 10px rgba(0,0,0,.4);
}

/* saludo — pierde protagonismo antes de que el header termine de cerrarse */
.hero-head{
  display:flex;align-items:flex-start;justify-content:space-between;gap:var(--sp-8);
  padding:var(--sp-4) var(--sp-7) var(--sp-9);
  opacity:clamp(0, calc(1 - var(--hp) * 1.7), 1);
  transform:translateY(calc(var(--hp) * -12px));
}
.hero-greet .t-display{
  color:#fff;
  text-shadow:0 1px 18px rgba(0,0,0,.45);
  transform:scale(calc(1 - var(--hp) * .05));
  transform-origin:left center;
}
.hero-greet p{
  color:rgba(255,255,255,.74);font-size:var(--fs-body);margin-top:var(--sp-2);
  text-shadow:0 1px 12px rgba(0,0,0,.4);
}

/* ── contenido ───────────────────────────────────────────────── */
.content{
  flex:1;overflow-y:auto;overflow-x:hidden;
  padding:var(--sp-7);
  scroll-behavior:smooth;
}
.content-inner{max-width:var(--content-max);margin:0 auto;display:flex;flex-direction:column;gap:var(--sp-5)}

/* rejillas de la referencia */
.row-kpi{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:var(--sp-5)}
.row-ops{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:var(--sp-5)}
.row-main{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.32fr) minmax(0,.92fr);gap:var(--sp-5)}
.row-lists{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--sp-5)}

/* ── bottom nav (mobile) ─────────────────────────────────────── */
.bottomnav{display:none}

/* ══════════════ RESPONSIVE ══════════════ */
@media (max-width:1500px){
  .row-ops{grid-template-columns:repeat(3,minmax(0,1fr))}
}
@media (max-width:1240px){
  .row-main{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
  .row-main > :nth-child(3){grid-column:1/-1}
  .row-lists{grid-template-columns:repeat(2,minmax(0,1fr))}
  .row-lists > :nth-child(3){grid-column:1/-1}
}
@media (max-width:1040px){
  .row-kpi{grid-template-columns:repeat(2,minmax(0,1fr))}
}

@media (max-width:860px){
  :root{--topbar-h:54px;--hero-h:112px;--panel-gap:0px}
  .sidebar{display:none}
  .panel{margin:0;border-radius:0}
  /* ── Topbar mobile ────────────────────────────────────────────
     Problema medido en iPhone real: a 375px el buscador se quedaba
     con ~100px útiles y "Buscar en Apex…" se partía en dos líneas,
     rompiendo la altura de la topbar. Tres causas sumadas:

       · `.spacer` competía por el espacio con `flex:1`;
       · el `⌘ K` se mostraba igual, ocupando ~46px para informar
         un atajo que en un teléfono no existe;
       · el texto no tenía por qué no envolver.

     Se resuelve con CSS: no hace falta otra topbar. */
  .topbar{padding:0 var(--sp-5);gap:var(--sp-3)}

  /* el espaciador deja de pelear: el buscador toma lo que queda */
  .topbar .spacer{display:none}
  .searchfield{max-width:none;flex:1 1 auto;min-width:0}

  /* ⌘K no existe en un teléfono */
  .searchfield .kbd{display:none}

  /* Target táctil de 44px. La caja visual sigue midiendo 38 —no se
     engorda el diseño— y el área tocable crece con padding invisible
     usando un pseudo-elemento. */
  .topbar .iconbtn,
  .topbar .avatar--btn{position:relative}
  .topbar .iconbtn::after,
  .topbar .avatar--btn::after{
    content:'';position:absolute;top:50%;left:50%;
    transform:translate(-50%,-50%);
    width:44px;height:44px;
  }
  .searchfield{min-height:44px}

  /* el título de pantalla no puede empujar al buscador fuera */
  .tb-title{max-width:calc(var(--hp) * 96px)}
  .hero-head{padding:var(--sp-2) var(--sp-6) var(--sp-7);flex-direction:column;gap:var(--sp-5)}
  .content{padding:var(--sp-6) var(--sp-6) calc(76px + env(safe-area-inset-bottom))}
  .row-kpi{grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--sp-4)}
  .row-ops{grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--sp-4)}
  .row-main,.row-lists{grid-template-columns:minmax(0,1fr)}
  .row-main > :nth-child(3),.row-lists > :nth-child(3){grid-column:auto}

  .bottomnav{
    display:flex;position:fixed;left:0;right:0;bottom:0;z-index:60;
    padding:var(--sp-2) var(--sp-3) calc(var(--sp-2) + env(safe-area-inset-bottom));
    border-top:1px solid var(--glass-line);
  }
  .bn-item{
    flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;
    padding:var(--sp-3) 2px;border-radius:var(--r-sm);
    font-size:var(--fs-2xs);font-weight:var(--fw-medium);color:var(--ink-3);
    transition:color var(--dur) var(--ease);
  }
  .bn-item[aria-current="page"]{color:var(--ink)}
  .bn-item .ico{position:relative}
  .bn-item .bn-dot{
    position:absolute;top:-2px;right:-5px;min-width:15px;height:15px;padding:0 4px;
    border-radius:var(--r-full);background:var(--apex-accent);color:#fff;
    font-size:9px;font-weight:var(--fw-bold);display:grid;place-items:center;
  }
}
/* ══════════════════════════════════════════════════════════════
   TELÉFONO CHICO (≤430px)
   ──────────────────────────────────────────────────────────────
   Acá va SÓLO lo que depende de que la pantalla sea chica de verdad
   (un SE, un mini): texto que no entra, aire que sobra.

   Lo que depende de que una TARJETA quede angosta no va acá: eso
   pasa en toda la banda de teléfonos y vive en el bloque de ≤640px
   de components.css. Mezclar las dos cosas fue el error que dejó al
   iPhone de 440px afuera de sus propias correcciones.

   Sobre los KPI: la fila ya está a dos columnas desde ≤860px, así
   que no hace falta declararlo otra vez acá. Antes había un
   `.row-kpi{repeat(2,…)}` en este bloque; existía sólo para anular un
   `1fr` de ≤420px que ya no está. Se eliminó: una regla que no hace
   nada es una regla que miente sobre lo que hace.
   ══════════════════════════════════════════════════════════════ */
@media (max-width:430px){
  /* En un iPhone SE o un mini, "Buscar" solo. Dice lo mismo y no
     deja al ícono sin aire. */
  .sf-mas{display:none}
  .tb-right{gap:0}

  /* 4px más de ancho útil por lado, sin que el contenido toque el
     borde. El colchón de abajo lo sigue poniendo la bottom nav. */
  .content{padding:var(--sp-5) var(--sp-5) calc(76px + env(safe-area-inset-bottom))}
}

/* Sello de versión de esta hoja. Sin efecto visual: lo lee el panel
   de diagnóstico para saber si el navegador está ejecutando esta
   versión o una cacheada. Ver la nota en tokens.css. */
:root{ --build-layout: cierre-2; }
