*,
*::before,
*::after {
  box-sizing: border-box;
}

html, body {
  margin: 0;
  padding: 0;
}

body {
  font-family: var(--font-primary);
  font-size: var(--text-base);
  font-weight: var(--font-regular);
  color: var(--text-primary);
  background: var(--bg-page);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4, h5, h6 {
  margin: 0;
  font-weight: var(--font-semibold);
  color: var(--text-primary);
}

h1 { font-size: var(--text-2xl); }
h2 { font-size: var(--text-xl); }
h3 { font-size: var(--text-lg); }
h4 { font-size: var(--text-md); }

p { margin: 0 0 var(--space-3) 0; }
p:last-child { margin-bottom: 0; }

a {
  color: var(--info);
  text-decoration: none;
  transition: color var(--transition-fast);
}
a:hover { color: var(--accent); }

button { font-family: inherit; }

img, svg { display: block; max-width: 100%; }

code, kbd, samp, pre {
  font-family: var(--font-mono);
  font-size: 0.9em;
}

::selection {
  background: var(--accent-light);
  color: var(--accent);
}

/* Layout: sidebar + topbar + content.
   Estructura body:
     body
     ├─ .mode-banner (opcional, sticky-like en top)
     └─ .app-shell  (grid 2x2: sidebar | topbar / sidebar | content)

   El banner se cuenta vía --banner-h (0 si no hay banner; 32px si hay).
   Esto asegura que sticky topbar/sidebar nunca se traslapen con el banner.
*/
:root { --banner-h: 0px; }
body.has-banner { --banner-h: 32px; }

.app-shell {
  display: grid;
  grid-template-columns: var(--sidebar-w-expanded) 1fr;
  grid-template-rows: var(--topbar-h) 1fr;
  grid-template-areas:
    "sidebar topbar"
    "sidebar content";
  min-height: calc(100vh - var(--banner-h));
}

.app-shell__sidebar {
  grid-area: sidebar;
  position: sticky;
  top: var(--banner-h);
  align-self: start;
  height: calc(100vh - var(--banner-h));
  overflow-y: auto;
}
.app-shell__topbar  {
  grid-area: topbar;
  position: sticky;
  top: var(--banner-h);
  z-index: 50;
}
.app-shell__content {
  grid-area: content;
  padding: var(--space-6);
  min-width: 0;            /* permite que tablas/grids hagan overflow correctamente */
}

/* Sidebar colapsable manual SOLO en desktop (≥1024px). El usuario lo togglea
   con el botón o con Cmd+B. La preferencia se persiste en localStorage.
   En tablet (640-1023px) y mobile (<640px) el comportamiento lo deciden los
   media queries de abajo, no la clase --collapsed. */
@media (min-width: 1024px) {
  .app-shell:has(.sidebar--collapsed) {
    grid-template-columns: var(--sidebar-w-collapsed) 1fr;
  }
  .sidebar--collapsed .sidebar__label,
  .sidebar--collapsed .sidebar__workspace,
  .sidebar--collapsed .sidebar__badge { display: none; }
  .sidebar--collapsed .sidebar__item {
    justify-content: center;
    padding: 0;
    position: relative;
  }
  .sidebar--collapsed .sidebar__top {
    padding: 0 var(--space-2);
    display: flex;
    justify-content: center;
  }
  .sidebar--collapsed .sidebar__nav,
  .sidebar--collapsed .sidebar__bottom { padding: 0 var(--space-2); }
}

/* En 640-1023px forzamos colapsado por default (poco espacio), pero el usuario
   puede expandirlo (la clase override). */
@media (min-width: 640px) and (max-width: 1023px) {
  .app-shell { grid-template-columns: var(--sidebar-w-collapsed) 1fr; }
  .app-shell__sidebar:not(.sidebar--expanded) .sidebar__label,
  .app-shell__sidebar:not(.sidebar--expanded) .sidebar__workspace,
  .app-shell__sidebar:not(.sidebar--expanded) .sidebar__badge { display: none; }
  .app-shell__sidebar:not(.sidebar--expanded) .sidebar__item {
    justify-content: center;
    padding: 0;
    position: relative;
  }
  .app-shell__sidebar:not(.sidebar--expanded) .sidebar__top {
    padding: 0 var(--space-2);
    display: flex;
    justify-content: center;
  }
  .app-shell__sidebar:not(.sidebar--expanded) .sidebar__nav,
  .app-shell__sidebar:not(.sidebar--expanded) .sidebar__bottom { padding: 0 var(--space-2); }
}

@media (max-width: 639px) {
  .app-shell {
    grid-template-columns: 1fr;
    grid-template-areas:
      "topbar"
      "content";
  }
  .app-shell__sidebar { display: none; }   /* se muestra como overlay con .is-open */
  .app-shell__content { padding: var(--space-4); min-width: 0; }
}
@media (max-width: 480px) {
  .app-shell__content { padding: var(--space-3); }
}

/* Utilidades genéricas */
.stack > * + * { margin-top: var(--space-3); }
.stack-lg > * + * { margin-top: var(--space-6); }
.row { display: flex; align-items: center; gap: var(--space-3); }
.row--between { justify-content: space-between; }
.muted { color: var(--text-secondary); }
.mono { font-family: var(--font-mono); }
.text-sm { font-size: var(--text-sm); }
.text-lg { font-size: var(--text-lg); }
.semibold { font-weight: var(--font-semibold); }
