/*
  Clínica Dental Balú — sistema visual (Fase 2A).
  HTML5 + CSS3 + JS vanilla, sin frameworks (docs/TECHNICAL_RULES.md §1).
  Mobile-first. Ver docs/DESIGN_SYSTEM.md para la justificación de cada decisión.
*/

/* =========================================================
   0. Tipografía (auto-hospedada, sin peticiones externas)
   ========================================================= */
@font-face {
  font-family: 'Poppins';
  font-style: normal; font-weight: 400; font-display: swap;
  src: url('../fonts/poppins-400.woff2') format('woff2');
}
@font-face {
  font-family: 'Poppins';
  font-style: normal; font-weight: 600; font-display: swap;
  src: url('../fonts/poppins-600.woff2') format('woff2');
}
@font-face {
  font-family: 'Poppins';
  font-style: normal; font-weight: 700; font-display: swap;
  src: url('../fonts/poppins-700.woff2') format('woff2');
}

/* =========================================================
   1. Tokens de diseño
   ========================================================= */
:root {
  /* Marca: negro + rosa (identidad real de clinicabalu.com), ejecutados con calidez y
     mesura — el rosa se usa como ACENTO puntual, no como relleno grande; el negro se
     suaviza a un carbón cálido en vez de #000 puro. Fondo cálido, no blanco frío. */
  --color-ink: #17161a;            /* texto principal, casi negro */
  --color-charcoal: #1b1a1f;       /* header/footer/paneles oscuros */
  --color-primary: #ec1263;        /* rosa de marca, algo más contenido que el #ff0064 original */
  --color-primary-dark: #c50e53;
  --color-primary-tint: #fdeaf1;   /* rosa muy pálido, para fondos suaves/badges */
  --color-cream: #faf8f6;          /* fondo cálido general (no blanco puro) */
  --color-cream-deep: #f3efec;     /* fondo de sección alterna */
  --color-surface: #ffffff;        /* tarjetas */
  --color-border: #e9e3de;
  --color-text: #2a282d;
  --color-text-muted: #6f6b70;
  --color-text-on-dark: #f3f1ee;
  --color-text-on-dark-muted: #b9b5bd;
  --color-danger: #c0293f;
  --color-success: #1f8f4e;
  --color-whatsapp: #25d366;       /* verde de marca de WhatsApp, solo para su propio CTA */
  --color-whatsapp-dark: #1da851;

  --font-head: 'Poppins', system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-base: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;

  --container-max: 1180px;
  --container-narrow: 760px;

  --space-1: 0.25rem;  /* 4  */
  --space-2: 0.5rem;   /* 8  */
  --space-3: 1rem;     /* 16 */
  --space-4: 1.5rem;   /* 24 */
  --space-5: 2.5rem;   /* 40 */
  --space-6: 4rem;     /* 64 */
  --space-7: 6rem;     /* 96 */

  --radius-sm: 10px;
  --radius: 16px;
  --radius-lg: 24px;
  --radius-pill: 100px;

  --shadow-sm: 0 1px 3px rgba(23, 22, 26, 0.06), 0 1px 2px rgba(23, 22, 26, 0.04);
  --shadow-md: 0 10px 30px rgba(23, 22, 26, 0.08);
  --shadow-lg: 0 20px 50px rgba(23, 22, 26, 0.14);

  --transition: 180ms ease;
  --header-h: 76px;
}

/* =========================================================
   2. Reset y base
   ========================================================= */
*, *::before, *::after { box-sizing: border-box; }
html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 16px);
  overflow-x: hidden;
}
body {
  margin: 0;
  font-family: var(--font-base);
  font-size: 17px;
  color: var(--color-text);
  background: var(--color-cream);
  line-height: 1.65;
  overflow-x: hidden;
}
img, picture, svg, iframe { max-width: 100%; display: block; }
/* Enlaces sin subrayado (decisión de diseño): resaltan por color + peso de fuente,
   nunca por línea. El hover oscurece el color en vez de subrayar. */
a { color: var(--color-primary); text-decoration: none; font-weight: 600; transition: color var(--transition); }
/* :not(.btn) es imprescindible aquí: sin él, esta regla (más específica que .btn--primary
   por llevar :hover) pinta el texto de los botones de rosa oscuro al pasar el ratón —
   justo el mismo color que .btn--primary:hover pone de fondo, así que el texto
   "desaparecía" (bug real detectado por el usuario). */
a:not(.btn):hover, a:not(.btn):focus-visible { color: var(--color-primary-dark); }
h1, h2, h3, h4 {
  font-family: var(--font-head); line-height: 1.18; margin: 0 0 var(--space-3);
  color: var(--color-ink); font-weight: 700; letter-spacing: -0.015em;
}
h1 { font-size: clamp(2.1rem, 4.4vw + 1rem, 3.4rem); }
h2 { font-size: clamp(1.6rem, 2vw + 1rem, 2.3rem); }
h3 { font-size: 1.2rem; }
p { margin: 0 0 var(--space-3); }
ul, ol { margin: 0; padding: 0; list-style: none; }
button { font: inherit; }

.skip-link {
  position: absolute; left: -999px; top: 0;
  background: var(--color-primary); color: #fff;
  padding: var(--space-2) var(--space-3); z-index: 1000; border-radius: 0 0 var(--radius-sm) 0;
}
.skip-link:focus { left: 0; top: 0; }

/* =========================================================
   3. Layout
   ========================================================= */
.container { width: 100%; max-width: var(--container-max); margin-inline: auto; padding-inline: var(--space-4); }
.container--narrow { max-width: var(--container-narrow); }

.grid { display: grid; gap: var(--space-4); grid-template-columns: 1fr; }
.grid > * { min-width: 0; }
@media (min-width: 640px)  { .grid--2 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 860px)  { .grid--3 { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 640px) and (max-width: 859px) { .grid--3 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 860px)  { .grid--4 { grid-template-columns: repeat(4, 1fr); } }
@media (min-width: 640px) and (max-width: 859px) { .grid--4 { grid-template-columns: repeat(2, 1fr); } }

.section { padding-block: var(--space-6); }
@media (min-width: 860px) { .section { padding-block: var(--space-7); } }
.section--alt { background: var(--color-cream-deep); }
.section--dark { background: var(--color-charcoal); color: var(--color-text-on-dark); }
.section--dark h2, .section--dark h3 { color: #fff; }
.section--dark .text-muted { color: var(--color-text-on-dark-muted); }
.section--tight { padding-block: var(--space-5); }

.section__eyebrow {
  display: inline-block; font-family: var(--font-head); font-weight: 600; font-size: 0.82rem;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--color-primary);
  margin-bottom: var(--space-2);
}
.section__heading { max-width: 680px; margin-bottom: var(--space-5); }
.section__heading--center { margin-inline: auto; text-align: center; }
.section__heading p { color: var(--color-text-muted); font-size: 1.05rem; }

/* =========================================================
   4. Header
   ========================================================= */
.site-header {
  background: var(--color-charcoal);
  position: sticky; top: 0; z-index: 100;
  box-shadow: 0 1px 0 rgba(255,255,255,0.06);
  transition: box-shadow var(--transition);
}
.site-header.is-scrolled { box-shadow: 0 4px 20px rgba(0,0,0,0.25); }
.site-header__inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-3); min-height: var(--header-h);
}
.site-header__logo { display: flex; align-items: center; flex-shrink: 0; }
.site-header__logo img { height: 34px; width: auto; }

.site-nav__toggle {
  background: transparent; color: #fff;
  border: 1.5px solid rgba(255,255,255,0.28); border-radius: var(--radius-sm);
  padding: 0.5rem 0.7rem; cursor: pointer; line-height: 1; display: inline-flex; align-items: center; gap: 6px;
  min-height: 44px; min-width: 44px; justify-content: center;
}
.site-nav__toggle:hover { border-color: rgba(255,255,255,0.5); }

.site-nav__list {
  display: none; flex-direction: column; gap: 2px;
  position: absolute; left: 0; right: 0; top: 100%;
  background: var(--color-charcoal); padding: var(--space-3);
  box-shadow: var(--shadow-lg); border-top: 1px solid rgba(255,255,255,0.08);
}
.site-nav__list.is-open { display: flex; }
.site-nav__list a {
  display: block; padding: 0.85rem var(--space-2); border-radius: var(--radius-sm);
  color: var(--color-text-on-dark); text-decoration: none; font-weight: 600; font-family: var(--font-head);
}
.site-nav__list a:hover, .site-nav__list a:focus-visible { background: rgba(255,255,255,0.08); }
.site-nav__list li:last-child { margin-top: var(--space-2); padding-top: var(--space-2); border-top: 1px solid rgba(255,255,255,0.1); }

.site-header .site-header__cta { display: none; }

@media (min-width: 900px) {
  .site-nav__toggle { display: none; }
  .site-nav__list {
    display: flex; flex-direction: row; align-items: center; position: static;
    background: none; box-shadow: none; padding: 0; gap: var(--space-5); border: 0;
  }
  .site-nav__list a { padding: 0.4rem 0; font-weight: 500; font-family: var(--font-base); color: var(--color-text-on-dark-muted); }
  .site-nav__list a:hover, .site-nav__list a:focus-visible { background: none; color: #fff; }
  /* El teléfono en texto es solo para el menú móvil desplegable: en desktop ya está
     el botón .site-header__cta, mostrarlo dos veces es redundante (bug detectado por
     captura real). */
  .site-nav__list li:last-child { display: none; }
  .site-header .site-header__cta { display: inline-flex; }
}

/* =========================================================
   5. Botones — jerarquía clara, sin ruido de colores
   ========================================================= */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.55em;
  padding: 0.85rem 1.5rem; border-radius: var(--radius-sm); font-family: var(--font-head);
  font-weight: 600; font-size: 0.98rem; text-decoration: none; border: 1.5px solid transparent;
  cursor: pointer; transition: transform var(--transition), box-shadow var(--transition), background var(--transition), border-color var(--transition), color var(--transition);
  max-width: 100%; text-align: center; white-space: normal; min-height: 48px;
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0); }

.btn--primary { background: var(--color-primary); color: #fff; box-shadow: var(--shadow-sm); }
.btn--primary:hover { background: var(--color-primary-dark); box-shadow: var(--shadow-md); }

.btn--outline { background: transparent; color: var(--color-ink); border-color: var(--color-ink); }
.btn--outline:hover { background: var(--color-ink); color: #fff; }

.btn--outline-light { background: transparent; color: #fff; border-color: rgba(255,255,255,0.5); }
.btn--outline-light:hover { background: #fff; color: var(--color-ink); border-color: #fff; }

.btn--ghost { background: transparent; color: var(--color-primary); padding-inline: 0.3rem; min-height: auto; }
.btn--ghost:hover { color: var(--color-primary-dark); transform: none; }
.btn--ghost::after { content: "→"; transition: transform var(--transition); }
.btn--ghost:hover::after { transform: translateX(3px); }

.btn--whatsapp { background: var(--color-whatsapp); color: #fff; box-shadow: var(--shadow-sm); }
.btn--whatsapp:hover { background: var(--color-whatsapp-dark); box-shadow: var(--shadow-md); }

.btn--sm { padding: 0.6rem 1.1rem; font-size: 0.9rem; min-height: 40px; }
.btn--block { width: 100%; }

.btn-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); }
.btn-row--center { justify-content: center; }

/* Botones flotantes de contacto rápido. Iconos SVG propios (no emoji: los emoji cambian
   de color/estilo según el sistema operativo y podían verse mal — ej. teléfono rosado
   sobre fondo rosa). */
.floating-ctas { position: fixed; right: 1rem; bottom: 1rem; display: flex; flex-direction: column; gap: var(--space-2); z-index: 200; }
.floating-ctas__btn {
  width: 56px; height: 56px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  text-decoration: none; box-shadow: var(--shadow-lg); color: #fff;
  transition: transform var(--transition);
}
.floating-ctas__btn svg { width: 26px; height: 26px; stroke: #fff; }
.floating-ctas__btn:hover { transform: scale(1.07); }
.floating-ctas__btn--call { background: var(--color-primary); }
.floating-ctas__btn--wa { background: var(--color-whatsapp); }

/* Banner de consentimiento de cookies (includes/cookie_banner.php). z-index por encima de
   los botones flotantes (200) a propósito: mientras el banner esté visible tapa la esquina
   inferior derecha, pero desaparece en cuanto se acepta/rechaza — no vale la pena
   coordinar posiciones para un aviso que se ve una sola vez. Anclado a la izquierda en
   escritorio (dónde sí hay sitio de sobra sin chocar con los botones flotantes); a todo el
   ancho en móvil. `hidden` en el HTML = oculto sin JS por defecto (mejora progresiva: sin
   JS nunca se pide consentimiento, así que nunca se activa nada no esencial). */
.cookie-banner { position: fixed; left: var(--space-3); right: var(--space-3); bottom: var(--space-3); z-index: 300; }
.cookie-banner[hidden] { display: none; }
@media (min-width: 900px) { .cookie-banner { right: auto; max-width: 420px; } }
.cookie-banner__inner { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius); box-shadow: var(--shadow-lg); padding: var(--space-4); }
.cookie-banner__text { margin: 0 0 var(--space-3); font-size: 0.88rem; line-height: 1.5; color: var(--color-text); }
.cookie-banner__actions { display: flex; gap: var(--space-2); flex-wrap: wrap; }

/* =========================================================
   6. Hero
   ========================================================= */
.hero { padding-block: var(--space-6); background: linear-gradient(175deg, var(--color-primary-tint) 0%, var(--color-cream) 55%); }
@media (min-width: 860px) { .hero { padding-block: var(--space-7); } }
.hero__grid { display: grid; gap: var(--space-5); grid-template-columns: 1fr; align-items: center; }
.hero__grid > * { min-width: 0; }
@media (min-width: 900px) { .hero__grid { grid-template-columns: 1.05fr 0.95fr; gap: var(--space-6); } }

.hero__eyebrow {
  display: inline-flex; align-items: center; gap: 0.5em; font-family: var(--font-head); font-weight: 600;
  font-size: 0.85rem; color: var(--color-primary-dark); background: var(--color-primary-tint);
  padding: 0.4rem 0.9rem; border-radius: var(--radius-pill); margin-bottom: var(--space-3);
}
.hero h1 { margin-bottom: var(--space-2); }
.hero__tagline { font-family: var(--font-head); font-weight: 600; font-size: 1.2rem; color: var(--color-primary-dark); margin: 0 0 var(--space-3); }
.hero__lead { font-size: 1.1rem; max-width: 58ch; color: var(--color-text-muted); margin-bottom: var(--space-4); }

.hero__trust { display: flex; flex-wrap: wrap; gap: var(--space-4); margin-top: var(--space-5); padding-top: var(--space-4); border-top: 1px solid var(--color-border); }
.hero__trust-item { display: flex; align-items: center; gap: 0.6em; font-weight: 600; font-size: 0.92rem; color: var(--color-ink); }
.hero__trust-item svg { flex-shrink: 0; color: var(--color-primary); }

.hero__media { position: relative; border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-lg); }
.hero__media img { width: 100%; height: 100%; object-fit: cover; aspect-ratio: 4 / 3; }
.hero__media::after {
  content: ""; position: absolute; inset: 0; border-radius: var(--radius-lg);
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.06);
}

/* =========================================================
   7. Barra de confianza / localización
   ========================================================= */
.trust-bar { background: var(--color-surface); border-block: 1px solid var(--color-border); }
.trust-bar__list {
  display: grid; grid-template-columns: 1fr; gap: var(--space-3); padding-block: var(--space-4);
  text-align: center;
}
@media (min-width: 640px) { .trust-bar__list { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 900px) { .trust-bar__list { grid-template-columns: repeat(4, 1fr); text-align: left; } }
.trust-bar__item { display: flex; align-items: center; justify-content: center; gap: 0.6em; font-weight: 600; font-size: 0.95rem; }
@media (min-width: 900px) { .trust-bar__item { justify-content: flex-start; } }
.trust-bar__item svg { color: var(--color-primary); flex-shrink: 0; }

/* =========================================================
   8. Cards
   ========================================================= */
.card {
  background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius);
  padding: var(--space-4); box-shadow: var(--shadow-sm);
  display: flex; flex-direction: column; gap: var(--space-2);
  transition: transform var(--transition), box-shadow var(--transition), border-color var(--transition);
}
a.card { text-decoration: none; color: inherit; }
a.card:hover, .card--hover:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); border-color: transparent; }
.card__title { margin: 0; font-size: 1.15rem; }
.card__excerpt { color: var(--color-text-muted); flex-grow: 1; }
.card__link { font-weight: 600; text-decoration: none; font-family: var(--font-head); color: var(--color-primary); display: inline-flex; align-items: center; gap: 0.4em; }
.card__link::after { content: "→"; transition: transform var(--transition); }
.card__link:hover::after { transform: translateX(3px); }

.service-card { align-items: flex-start; }
.service-card__icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 56px; height: 56px; padding: 12px; margin-bottom: var(--space-2);
  background: var(--color-primary-tint); border-radius: var(--radius-sm);
}
.service-card__icon img { width: 100%; height: 100%; object-fit: contain; filter: brightness(0) saturate(100%) invert(14%) sepia(80%) saturate(6000%) hue-rotate(325deg) brightness(95%) contrast(95%); }

/* Placeholder elegante cuando no hay foto real (sin inventar fotos) */
.media-placeholder {
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(155deg, var(--color-charcoal), #2b2a30);
  border-radius: var(--radius-lg); aspect-ratio: 4 / 3; color: var(--color-primary);
}
.media-placeholder svg { width: 30%; height: 30%; opacity: 0.9; }

/* =========================================================
   9. Estadísticas / cifras
   ========================================================= */
.stats { display: grid; grid-template-columns: 1fr; gap: var(--space-4); }
@media (min-width: 640px) { .stats { grid-template-columns: repeat(3, 1fr); } }
.stat { text-align: center; padding: var(--space-4) var(--space-3); border-radius: var(--radius); background: var(--color-surface); border: 1px solid var(--color-border); }
.stat__value { font-family: var(--font-head); font-size: 2.6rem; font-weight: 700; color: var(--color-primary); margin: 0; line-height: 1; }
.stat__label { color: var(--color-text-muted); font-weight: 500; margin-top: var(--space-1); }

/* =========================================================
   10. Proceso para pedir cita
   ========================================================= */
.process { display: grid; grid-template-columns: 1fr; gap: var(--space-5); counter-reset: step; }
@media (min-width: 780px) { .process { grid-template-columns: repeat(4, 1fr); gap: var(--space-4); } }
.process__step { position: relative; text-align: center; }
.process__number {
  counter-increment: step; content: counter(step);
  width: 52px; height: 52px; margin: 0 auto var(--space-3); border-radius: 50%;
  background: var(--color-ink); color: #fff; font-family: var(--font-head); font-weight: 700; font-size: 1.2rem;
  display: flex; align-items: center; justify-content: center;
}
.process__step:nth-child(odd) .process__number { background: var(--color-primary); }
.process__title { font-family: var(--font-head); font-weight: 700; margin-bottom: var(--space-1); }
.process__text { color: var(--color-text-muted); font-size: 0.95rem; margin: 0; }
@media (min-width: 780px) {
  .process__step:not(:last-child)::after {
    content: ""; position: absolute; top: 26px; left: calc(50% + 40px); width: calc(100% - 80px);
    height: 2px; background: var(--color-border);
  }
}

/* =========================================================
   11. FAQ
   ========================================================= */
.faqs { max-width: var(--container-narrow); margin-inline: auto; }
.faqs__list { display: grid; gap: var(--space-2); }
.faqs__item { border: 1px solid var(--color-border); border-radius: var(--radius); background: var(--color-surface); overflow: hidden; }
.faqs__question {
  cursor: pointer; padding: var(--space-3) var(--space-4); font-weight: 600; font-family: var(--font-head);
  list-style: none; color: var(--color-ink); display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
}
.faqs__question::-webkit-details-marker { display: none; }
.faqs__question::after { content: "+"; font-size: 1.4rem; color: var(--color-primary); flex-shrink: 0; line-height: 1; transition: transform var(--transition); }
.faqs__item[open] .faqs__question::after { transform: rotate(45deg); }
.faqs__answer { padding: 0 var(--space-4) var(--space-4); }
.faqs__answer p { margin: 0; color: var(--color-text-muted); }
.section--dark .faqs__item { background: #242329; border-color: rgba(255,255,255,0.1); }
.section--dark .faqs__question { color: #fff; }

/* Galería de fotos de "La Clínica" (sobre-nosotros.php), añadida 2026-07-04: gestionada
   desde admin/galeria.php, pensada para 8 fotos — 2 columnas (4 filas) en móvil, 4 columnas
   (2 filas) en escritorio, ver docs/CHECKLIST_QA.md. Funciona igual con cualquier cantidad. */
.gallery-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-3); }
@media (min-width: 780px) { .gallery-grid { grid-template-columns: repeat(4, 1fr); gap: var(--space-4); } }
.gallery-grid__item { border-radius: var(--radius); overflow: hidden; aspect-ratio: 1 / 1; box-shadow: var(--shadow-sm); }
.gallery-grid__item img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 400ms ease; }
.gallery-grid__item:hover img { transform: scale(1.05); }

/* Fichas de equipo (La Clínica): foto real o avatar-iniciales de respaldo si no hay foto
   confirmada (ej. Natividad, sin ficha propia en la web original). */
/* object-position: top — probado con comparativa visual real de las 5 fotos (no solo una)
   antes de fijar el valor: top(0%) es el que mejor deja la cara Y el gorro visibles en las
   5 a la vez, sin cortar ninguno. Los valores intermedios que se probaron antes (15%/35%)
   quedaban peor según el usuario — revertido a este tras su aviso "estaban mejor como
   estaba antes". */
.team-card__photo { width: 96px; height: 96px; margin: 0 auto var(--space-2); border-radius: 50%; object-fit: cover; object-position: top; }
.team-card__avatar {
  display: flex; align-items: center; justify-content: center; width: 96px; height: 96px;
  margin: 0 auto var(--space-2); border-radius: 50%; background: var(--color-primary-tint);
  color: var(--color-primary-dark); font-family: var(--font-head); font-weight: 700; font-size: 1.2rem;
}
/* Formación completa: no se abre en la propia tarjeta (agrandarla desplaza toda la rejilla
   de la sección) sino en un popup (<dialog> nativo) — la tarjeta se queda siempre del mismo
   tamaño. El botón abre el <dialog> vía JS (assets/js/main.js); cerrar es 100% nativo con
   <form method="dialog"> (funciona sin JS). */
.team-card__bio-toggle {
  cursor: pointer; font-size: 0.85rem; font-weight: 600; color: var(--color-primary);
  background: none; border: none; border-top: 1px solid var(--color-border); width: 100%;
  margin-top: var(--space-2); padding-top: var(--space-2); font-family: inherit;
}
.team-card__bio-toggle:hover, .team-card__bio-toggle:focus-visible { color: var(--color-primary-dark); }
/* IMPORTANTE: .team-modal (el propio <dialog>) NO lleva position:relative — el navegador ya
   le pone position:fixed y lo centra en el viewport por su cuenta cuando se abre con
   showModal() (capa superior/"top layer"); ponerle position:relative aquí PISABA ese fixed
   nativo y el diálogo volvía a su sitio normal en el flujo del documento (al final de la
   página), lo que hacía saltar la página entera al abrir el popup (bug real reportado por el
   usuario). El position:relative para anclar el botón "×" va en .team-modal__inner, un div
   de dentro, no en el <dialog>. El botón de cerrar está FUERA de .team-modal__scroll (el
   único elemento con overflow-y) para que no se mueva al deslizar el contenido largo. */
.team-modal { border: none; border-radius: var(--radius-lg); padding: 0; max-width: 560px; width: calc(100% - 2.5rem); max-height: 80vh; overflow: hidden; box-shadow: var(--shadow-lg); text-align: left; }
.team-modal::backdrop { background: rgba(23, 22, 26, 0.6); }
.team-modal__inner { position: relative; max-height: 80vh; }
.team-modal__scroll { max-height: 80vh; overflow-y: auto; padding: var(--space-5); }
.team-modal__close-row { position: absolute; top: var(--space-3); right: var(--space-3); margin: 0; z-index: 2; }
.team-modal__close {
  background: var(--color-surface); border: 1px solid var(--color-border); border-radius: 50%;
  width: 36px; height: 36px; display: flex; align-items: center; justify-content: center;
  font-size: 1.4rem; line-height: 1; cursor: pointer; color: var(--color-text-muted);
  box-shadow: var(--shadow-sm); padding: 0;
}
.team-modal__close:hover { color: #fff; background: var(--color-primary); border-color: var(--color-primary); }
/* Es un <p>, no un <h3> (antes duplicaba el nombre del equipo como heading en el DOM,
   bug real detectado por el usuario — el <dialog> ya lleva su propio aria-label con el
   nombre, no necesita un heading visual repetido para ser accesible). Estilos explícitos
   aquí porque ya no hereda el font-family/peso que el sitio aplica a h1-h4 por etiqueta. */
.team-modal__title { margin: 0 0 0.2em; padding-right: 2.5rem; font-family: var(--font-head); font-weight: 700; font-size: 1.15rem; color: var(--color-ink); }
.team-card__bio-label { font-family: var(--font-head); font-weight: 600; font-size: 0.9rem; color: var(--color-ink); margin: var(--space-3) 0 0.3em; }
.team-card__bio-label:first-child { margin-top: 0; }
.team-card__bio-list { margin: 0; padding-left: 1.1em; }
.team-card__bio-list li { font-size: 0.88rem; line-height: 1.55; color: var(--color-text-muted); margin-bottom: 0.35em; }

/* =========================================================
   12. Formularios
   ========================================================= */
.form-field { display: flex; flex-direction: column; gap: var(--space-1); margin-bottom: var(--space-3); }
.form-field label { font-weight: 600; font-size: 0.92rem; }
.form-field input, .form-field textarea, .form-field select {
  padding: 0.8rem 0.95rem; border: 1.5px solid var(--color-border); border-radius: var(--radius-sm);
  font: inherit; background: var(--color-surface); min-height: 48px; color: var(--color-text);
}
.form-field textarea { min-height: 120px; }
.form-field input:focus, .form-field textarea:focus, .form-field select:focus { outline: 2px solid var(--color-primary); outline-offset: 1px; border-color: var(--color-primary); }
/* <select> no heredaba ningún estilo (solo input/textarea estaban cubiertos) y se veía
   como un desplegable nativo del sistema operativo al lado de campos ya pulidos — uno de
   los "campos horribles" señalados. Flecha propia en SVG (sin fuente de iconos externa,
   igual criterio que el resto del proyecto) en vez del icono nativo del navegador. */
.form-field select {
  appearance: none; -webkit-appearance: none; -moz-appearance: none; cursor: pointer;
  padding-right: 2.6rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236f6b70' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 0.85rem center; background-size: 16px;
}
.form-field select::-ms-expand { display: none; }
.form-error { color: var(--color-danger); font-size: 0.9rem; }
.form-honeypot { position: absolute; left: -9999px; }
.form-check { display: flex; align-items: flex-start; gap: 0.6em; font-size: 0.92rem; }
.form-check input { margin-top: 3px; width: 18px; height: 18px; flex-shrink: 0; accent-color: var(--color-primary); }

/* Varios campos en la misma fila (petición del cliente 2026-07-04, para que los formularios
   del panel no ocupen tanto alto): cada .form-field/.form-check hijo se reparte el ancho a
   partes iguales; en móvil se apilan como siempre (una columna). */
.form-row { display: flex; gap: var(--space-3); flex-wrap: wrap; align-items: start; }
.form-row > .form-field { flex: 1 1 200px; margin-bottom: var(--space-3); }
/* flex:0 0 auto (no crecer): un checkbox es corto por naturaleza — si crece como los campos
   de texto, deja un hueco enorme entre la casilla y lo que venga después (bug real visto en
   captura: "Cerrado todo el día" ... [hueco] ... "Guardar"). */
.form-row > .form-check { flex: 0 0 auto; padding-top: 0.9rem; white-space: nowrap; }
.form-row > .btn { flex: 0 0 auto; margin-top: 1.6rem; }

/* =========================================================
   13. Footer
   ========================================================= */
/* Sin margin-top: si la página termina en una sección oscura (.section--dark), pegar el
   footer (también oscuro) directamente evita el hueco claro entre ambos (bug detectado
   por captura real en la home). Cuando la sección anterior es clara, su propio padding
   ya da suficiente aire. */
/* border-top rosa: separa el footer de la sección que venga antes (a menudo también
   oscura, .section--dark) sin reintroducir el hueco claro de antes — y de paso es el
   acento de línea rosa pedido por el cliente entre "¿Hablamos de tu sonrisa?" y el pie. */
.site-footer { background: var(--color-charcoal); color: var(--color-text-on-dark); border-top: 3px solid var(--color-primary); }
.site-footer__inner { display: grid; gap: var(--space-5); grid-template-columns: 1fr; padding-block: var(--space-6); }
/* Las redes sociales ya no son una columna de texto: viven en su propia fila centrada
   (.site-footer__social-bar), así que solo quedan 3 columnas (marca+dirección, horario,
   enlaces) — las 2 primeras más anchas para que cada día del horario quepa en una línea. */
@media (min-width: 780px) { .site-footer__inner { grid-template-columns: 1.3fr 1.4fr 1fr; } }
/* "Enlaces" alineado a la derecha (a petición del cliente) — solo en el layout de
   escritorio, donde las columnas están en fila; apilado en móvil se queda a la izquierda
   para que se siga leyendo con normalidad. */
@media (min-width: 780px) { .site-footer__block--right { text-align: right; } }
.site-footer a { color: var(--color-text-on-dark); }
.site-footer a:hover { color: var(--color-primary); }
.site-footer__logo { height: 32px; width: auto; margin-bottom: var(--space-3); }
.site-footer__heading { font-family: var(--font-head); font-weight: 600; color: #fff; margin-bottom: var(--space-2); font-size: 0.95rem; text-transform: uppercase; letter-spacing: 0.04em; }
.site-footer__hours li, .site-footer__links li { padding-block: 4px; }
.site-footer__hours li { display: flex; justify-content: space-between; gap: var(--space-3); color: var(--color-text-on-dark-muted); font-size: 0.92rem; }
.site-footer__hours li span:first-child { color: var(--color-text-on-dark); flex-shrink: 0; }
.site-footer__hours li span:last-child { white-space: nowrap; }
.site-footer__social-bar { display: flex; justify-content: center; align-items: center; gap: var(--space-3); padding-block: var(--space-4); border-top: 1px solid rgba(255,255,255,0.1); }
.site-footer__social-bar a { display: flex; align-items: center; justify-content: center; width: 42px; height: 42px; border-radius: 50%; border: 1px solid rgba(255,255,255,0.25); color: var(--color-text-on-dark); transition: background var(--transition), border-color var(--transition), color var(--transition); }
.site-footer__social-bar a:hover, .site-footer__social-bar a:focus-visible { background: var(--color-primary); border-color: var(--color-primary); color: #fff; }
.site-footer__social-bar svg { width: 20px; height: 20px; stroke: currentColor; }
.site-footer__legal { border-top: 1px solid rgba(255,255,255,0.1); padding-block: var(--space-3); font-size: 0.8rem; opacity: 0.75; text-align: center; }
/* Móvil: "© año Clínica Dental Balú — Razón Social." no cabe en una línea junto con
   "Todos los derechos reservados." y el navegador lo partía en un punto feo/impredecible.
   Se fuerza el salto justo entre las dos frases (mobile-first: bloque por defecto); en
   escritorio, donde sí cabe de sobra, vuelve a quedar en una sola línea. */
.site-footer__legal-line2 { display: block; margin-top: 0.2em; }
@media (min-width: 780px) { .site-footer__legal-line2 { display: inline; margin-top: 0; } }
/* Razón social: se oculta en móvil a petición del cliente (queda igualmente accesible en
   /aviso-legal/, que es donde legalmente corresponde el detalle completo de la entidad) —
   solo se ve en escritorio, donde ya cabe de sobra en la misma línea. */
.site-footer__legal-company { display: none; }
@media (min-width: 780px) { .site-footer__legal-company { display: inline; } }
.site-footer address { font-style: normal; color: var(--color-text-on-dark-muted); }

/* =========================================================
   14. Breadcrumbs
   ========================================================= */
.breadcrumbs { padding-block: var(--space-3) 0; }
.breadcrumbs__list { display: flex; flex-wrap: wrap; gap: var(--space-2); font-size: 0.85rem; color: var(--color-text-muted); }
.breadcrumbs__item:not(:last-child)::after { content: "/"; margin-left: var(--space-2); color: var(--color-border); }
.breadcrumbs__item a { color: var(--color-text-muted); text-decoration: none; }
.breadcrumbs__item a:hover { color: var(--color-primary); }

/* =========================================================
   15. Prose (bloques de texto largo: legales, blog, servicio)
   ========================================================= */
.prose { max-width: 72ch; }
.prose--centered { margin-inline: auto; text-align: center; }
.prose h2 { margin-top: var(--space-5); }
.prose a:not(.btn) { color: var(--color-primary); }

.disclaimer {
  margin-top: var(--space-4); padding: 0.4rem var(--space-4);
  background: var(--color-primary-tint); border-left: 4px solid var(--color-primary);
  border-radius: var(--radius-sm); font-size: 0.75rem; line-height: 1.25; color: var(--color-text);
}

.check-list { display: grid; gap: var(--space-2); }
.check-list li { padding-left: 1.9rem; position: relative; }
.check-list li::before {
  content: "✓"; position: absolute; left: 0; top: 1px; display: inline-grid; place-items: center;
  width: 22px; height: 22px; background: var(--color-primary-tint); color: var(--color-primary-dark);
  border-radius: 50%; font-size: 0.78rem; font-weight: 700;
}
.link-list li { padding-block: var(--space-1); }
.link-list a {
  font-weight: 600; display: -webkit-box; -webkit-box-orient: vertical;
  -webkit-line-clamp: 2; overflow: hidden; text-overflow: ellipsis;
}

/* =========================================================
   16. Layout artículo/servicio con aside
   ========================================================= */
.article-layout { display: grid; gap: var(--space-5); grid-template-columns: 1fr; }
@media (min-width: 900px) { .article-layout { grid-template-columns: minmax(0, 2fr) minmax(260px, 1fr); align-items: start; } }
.article-layout__aside { display: grid; gap: var(--space-4); }
@media (min-width: 900px) { .article-layout__aside { position: sticky; top: calc(var(--header-h) + 20px); } }
.card--cta { background: var(--color-charcoal); color: #fff; align-items: stretch; border: 0; }
.card--cta .card__title { color: #fff; }
.card--cta .text-muted { color: var(--color-text-on-dark-muted); }
.card--cta .btn { width: 100%; }
.service-hero-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 64px; height: 64px; padding: 14px; margin-bottom: var(--space-3);
  background: var(--color-primary-tint); border-radius: var(--radius);
}
.service-hero-icon img { width: 100%; height: 100%; object-fit: contain; filter: brightness(0) saturate(100%) invert(14%) sepia(80%) saturate(6000%) hue-rotate(325deg) brightness(95%) contrast(95%); }

/* =========================================================
   17. Blog
   ========================================================= */
/* Listado del blog: tarjetas horizontales, una debajo de otra — no una rejilla de columnas
   (petición del cliente 2026-07-04). Tarjeta compacta en móvil, 5 áreas de rejilla
   independientes (sin agrupar nada en un `<div>` envoltorio) para poder recolocarlas sin
   tocar el HTML: fecha/categoría arriba a todo lo ancho, luego foto+título en la misma fila,
   extracto (más pequeño, aviso del cliente) y por último "Leer artículo", ambos a todo lo
   ancho. En escritorio (≥640px) las mismas 5 piezas se reparten distinto: foto grande a la
   izquierda ocupando toda la altura, fecha/título/extracto/enlace apilados a la derecha. */
/* Filtro de categorías del blog: fila única con scroll horizontal (en vez de
   .admin-toolbar, pensado para el panel y que aquí desbordaba a 3 líneas). Píldoras
   más compactas y sin salto de línea; el desvanecido lateral insinúa que hay más
   categorías fuera de la vista sin necesitar una flecha o botón adicional. */
.blog-filter {
  position: relative; margin-top: var(--space-3);
}
.blog-filter__scroll {
  display: flex; gap: var(--space-2); overflow-x: auto; padding-block: 0.2rem;
  scrollbar-width: none; -ms-overflow-style: none; scroll-snap-type: x proximity;
}
.blog-filter__scroll::-webkit-scrollbar { display: none; }
.blog-filter__pill {
  flex-shrink: 0; scroll-snap-align: start; max-width: min(58vw, 230px);
  display: inline-flex; align-items: center; gap: 0.3em;
  padding: 0.4rem 0.85rem; border-radius: var(--radius-pill);
  font-family: var(--font-head); font-weight: 600; font-size: 0.82rem;
  border: 1.5px solid var(--color-border); color: var(--color-ink);
  background: var(--color-surface); text-decoration: none;
  transition: background var(--transition), border-color var(--transition), color var(--transition);
}
/* Nombres largos ("Odontología General y Conservadora") se truncan con "…"
   (el nombre completo queda en el atributo title, visible al pasar el ratón). */
.blog-filter__pill-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.blog-filter__pill:hover { border-color: var(--color-primary); color: var(--color-primary); }
.blog-filter__pill.is-active {
  background: var(--color-primary); border-color: var(--color-primary); color: #fff;
}
.blog-filter::before, .blog-filter::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: 1.5rem; pointer-events: none; z-index: 1;
}
.blog-filter::before { left: 0; background: linear-gradient(90deg, var(--color-cream), transparent); }
.blog-filter::after { right: 0; background: linear-gradient(270deg, var(--color-cream), transparent); }

/* Flechas: sin JS quedan ocultas por [hidden] (mejora progresiva, ver main.js).
   Con JS, initBlogFilterArrows() las muestra u oculta según cuánto queda por scrollear. */
.blog-filter__arrow {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
  width: 28px; height: 28px; border-radius: 50%; border: 1.5px solid var(--color-border);
  background: var(--color-surface); color: var(--color-ink); box-shadow: var(--shadow-sm);
  display: flex; align-items: center; justify-content: center; cursor: pointer; padding: 0;
  font-size: 0.8rem; line-height: 1; transition: background var(--transition), color var(--transition), border-color var(--transition);
}
.blog-filter__arrow:hover { background: var(--color-primary); border-color: var(--color-primary); color: #fff; }
.blog-filter__arrow--prev { left: -6px; }
.blog-filter__arrow--next { right: -6px; }
.blog-filter__arrow[hidden] { display: none; }

.blog-list { display: flex; flex-direction: column; gap: var(--space-4); }
.blog-list .card {
  display: grid; grid-template-columns: 84px 1fr;
  grid-template-areas: "meta meta" "thumb title" "excerpt excerpt" "link link";
  column-gap: var(--space-3); row-gap: var(--space-2);
  padding: var(--space-3); align-items: start;
}
.blog-list .blog-post__meta { grid-area: meta; margin: 0; }
.blog-list .blog-card__thumb { grid-area: thumb; width: 84px; height: 84px; aspect-ratio: 1 / 1; margin: 0; }
.blog-list .card__title { grid-area: title; align-self: center; margin: 0; }
.blog-list .card__excerpt { grid-area: excerpt; margin: 0; font-size: 0.85rem; }
.blog-list .card__link { grid-area: link; }
@media (min-width: 640px) {
  .blog-list .card {
    grid-template-columns: 280px 1fr;
    grid-template-areas: "thumb meta" "thumb title" "thumb excerpt" "thumb link";
    padding: 0; overflow: hidden; row-gap: 0.4em;
  }
  .blog-list .blog-card__thumb { width: 280px; height: auto; aspect-ratio: 4 / 3; align-self: stretch; }
  .blog-list .blog-post__meta { padding: var(--space-4) var(--space-4) 0; }
  .blog-list .card__title { align-self: start; padding-inline: var(--space-4); }
  .blog-list .card__excerpt { padding-inline: var(--space-4); font-size: 1rem; }
  .blog-list .card__link { padding: 0 var(--space-4) var(--space-4); }
}
.blog-post__meta { color: var(--color-text-muted); font-size: 0.85rem; }
/* Ancho del artículo ampliado (antes 74ch, se veía demasiado estrecho — aviso del cliente). */
.blog-post__content { max-width: 900px; margin-inline: auto; }
/* Foto destacada (petición del cliente 2026-07-04, includes/blog_images.php): la propia
   imagen ya lleva su borde/rotación/sello incorporados (procesados con GD), aquí solo se
   limita el ancho y se dan márgenes — nunca recortar con object-fit, se vería mal la
   rotación. */
.blog-post__figure { margin: var(--space-4) 0; text-align: center; }
.blog-post__figure img { max-width: 100%; height: auto; margin-inline: auto; }
.blog-post__figure figcaption { font-size: 0.78rem; color: var(--color-text-muted); margin-top: var(--space-2); }
.blog-card__thumb { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; margin-bottom: 0; }

/* Cabecera de artículo con la foto destacada de fondo (petición del cliente 2026-07-04: "la
   foto detrás del título, con cierta opacidad para que se vea el título correctamente") —
   sustituye a .blog-post__figure cuando el artículo tiene foto; sin foto, el título se
   queda como antes (H1 normal, sin cabecera). */
.blog-post__hero { position: relative; overflow: hidden; min-height: 320px; display: flex; align-items: flex-end; }
.blog-post__hero-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.blog-post__hero-overlay { position: absolute; inset: 0; background: linear-gradient(180deg, rgba(23,22,26,0.25) 0%, rgba(23,22,26,0.82) 100%); }
.blog-post__hero-inner { position: relative; z-index: 1; padding-block: var(--space-6) var(--space-5); }
.blog-post__hero-inner h1 { color: #fff; margin-bottom: 0; }
.blog-post__meta--hero { color: rgba(255,255,255,0.85); margin-bottom: var(--space-2); }
.blog-post__meta--hero a { color: #fff; }
/* Crédito de la foto: DENTRO de la foto, arriba a la derecha — muy sutil, gris, una sola
   línea ("Foto: Nombre", sin URL ni "(Pexels)", ver includes/blog_images.php). */
.blog-post__hero-credit {
  position: absolute; top: var(--space-3); right: var(--space-3); z-index: 1;
  margin: 0; max-width: 300px; text-align: right;
  font-size: 0.7rem; line-height: 1.3; color: rgba(233,231,234,0.55);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  text-shadow: 0 1px 3px rgba(0,0,0,0.6);
}
.blog-post__hero-credit a { color: inherit; }
/* Migas de pan dentro de la cabecera, en blanco (aviso del cliente 2026-07-04: "quitar esa
   parte blanca... ponerlo en blanco y dentro de la foto, así no rompe el diseño") — antes
   header.php las pintaba automáticamente en su propia barra blanca entre la cabecera del
   sitio y la foto; con foto destacada, articulo.php evita ese renderizado automático y las
   pinta aquí, superpuestas arriba de la foto. `.breadcrumbs` ya trae su propia clase
   `.container`, por eso no hace falta envolverla en nada más para alinearla con el resto. */
.blog-post__hero .breadcrumbs { position: absolute; top: 0; left: 0; right: 0; z-index: 1; padding-top: var(--space-3); }
.blog-post__hero .breadcrumbs__list, .blog-post__hero .breadcrumbs__item a { color: rgba(255,255,255,0.75); }
.blog-post__hero .breadcrumbs__item a:hover { color: #fff; }
.blog-post__hero .breadcrumbs__item:not(:last-child)::after { color: rgba(255,255,255,0.4); }
/* En móvil, la ruta completa (Inicio/Blog/Categoría/Título del artículo) no cabe en el
   ancho disponible y se amontona sobre la foto — se oculta (aviso del cliente 2026-07-04),
   el título y la categoría siguen visibles más abajo en la propia cabecera. */
@media (max-width: 640px) { .blog-post__hero .breadcrumbs { display: none; } }
@media (min-width: 780px) { .blog-post__hero { min-height: 420px; } }

/* =========================================================
   18. Horario y mapa
   ========================================================= */
.hours-list li { display: flex; justify-content: space-between; gap: var(--space-3); padding-block: 6px; max-width: 360px; border-bottom: 1px dashed var(--color-border); }
.hours-list li:last-child { border-bottom: 0; }
/* Móvil: el horario con turno partido ("09:30–13:30, 16:30–20:30") se salía a una
   segunda línea con el tamaño de letra normal; se reduce solo aquí para que cada
   día quede en una sola fila (petición del cliente 2026-07-05). */
@media (max-width: 639px) {
  .hours-list li { font-size: 0.82rem; gap: var(--space-2); }
}
/* Excepción puntual de horario (horarios_especiales, admin/ajustes.php) sobrescribiendo el
   día de la semana que le corresponde — decisión del cliente 2026-07-04: que se note sobre
   el propio día, no en un aviso aparte. */
.hours-list li.is-exception span:last-child { color: var(--color-primary-dark); font-weight: 700; }
.site-footer__hours li.is-exception span:last-child { color: var(--color-primary); font-weight: 700; }
.map-embed { border-radius: var(--radius); overflow: hidden; border: 1px solid var(--color-border); line-height: 0; box-shadow: var(--shadow-sm); }

/* =========================================================
   19. Utilidades
   ========================================================= */
.text-muted { color: var(--color-text-muted); }
.text-center { text-align: center; }
.mt-4 { margin-top: var(--space-4); }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; }

/* =========================================================
   20. Accesibilidad y preferencias del usuario
   ========================================================= */
a:focus-visible, button:focus-visible, summary:focus-visible, input:focus-visible, textarea:focus-visible {
  outline: 3px solid var(--color-primary); outline-offset: 2px; border-radius: 3px;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .btn, .card, .floating-ctas__btn { transition: none; }
  .gallery-grid__item:hover img { transform: none; }
}

/* =========================================================
   21. Admin / Dashboard (Fase 3) — reutiliza tokens/.btn/.card/.form-field ya
   existentes (docs/TECHNICAL_RULES.md §7); solo añade lo propio de un panel privado
   (barra superior, nav de secciones, tablas, badges de estado editorial).
   ========================================================= */
/* El panel reutilizaba los mismos --space-* y tamaños de heading que la web pública
   (pensados para una página de marketing, con mucho "aire" a propósito, ver
   docs/DESIGN_SYSTEM.md) — en un panel de trabajo eso se traducía en todo demasiado grande
   y scroll constante para ver contenido que cabría de sobra (bug real reportado por el
   cliente 2026-07-04). Aquí se redefine una escala más compacta SOLO dentro de
   `.admin-body`, sin tocar los tokens globales que usa el sitio público. */
.admin-body {
  font-size: 15px;
  --space-3: 0.75rem;   /* 16 → 12px */
  --space-4: 1.125rem;  /* 24 → 18px */
  --space-5: 1.75rem;   /* 40 → 28px */
  --space-6: 2.5rem;    /* 64 → 40px */
  /* Tema oscuro del panel (petición del cliente 2026-07-04) — redefine los mismos tokens de
     color que ya usa todo el sitio (tarjetas, tablas, formularios, botones...), así que se
     propaga solo con esto, sin reescribir cada componente uno a uno. Nunca afecta al sitio
     público: .admin-body solo existe en el <body> de las páginas de /admin/, que son
     documentos HTML aparte. */
  --color-cream-deep: #17161a;      /* fondo de página */
  --color-cream: #2a2731;           /* hover de filas de tabla (antes fondo alterno claro) */
  --color-surface: #221f27;         /* tarjetas, sidebar, tablas */
  --color-border: #3a3641;
  --color-ink: #f5f3f6;             /* títulos */
  --color-text: #e7e4ea;            /* texto de cuerpo */
  --color-text-muted: #a49dae;      /* texto secundario */
  --color-primary-tint: rgba(236, 18, 99, 0.16); /* fondo suave rosa (nav activo) sobre fondo oscuro */
  background: var(--color-cream-deep);
  color: var(--color-text);
}
.admin-body h1 { font-size: 1.6rem; margin-bottom: var(--space-3); }
.admin-body h2 { font-size: 1.15rem; }
.admin-body h3 { font-size: 1rem; }
/* .btn--outline usa --color-ink para su fondo en :hover (funciona en el sitio público
   porque ahí --color-ink es oscuro); aquí --color-ink es CLARO (para los títulos), así que
   ese mismo hover se corrige aparte con el rosa de marca en vez de heredar el genérico. */
.admin-body .btn--outline:hover { background: var(--color-primary); color: #fff; border-color: var(--color-primary); }
/* Iconos nativos del selector de fecha/hora: el navegador los pinta oscuros por defecto,
   casi invisibles sobre un campo ya oscuro — se invierten a claro solo aquí. */
.admin-body input[type="date"]::-webkit-calendar-picker-indicator,
.admin-body input[type="time"]::-webkit-calendar-picker-indicator { filter: invert(0.85); }
/* Los badges de estado son chips de acento con fondo pastel fijo (no cambian con el tema);
   ".admin-badge--borrador" es el único que heredaba el color de texto genérico
   (--color-text-muted, ahora claro) — se fija en su tono oscuro original para no quedar
   texto claro sobre fondo claro. */
.admin-body .admin-badge--borrador { color: #6f6b70; }

/* Estructura: topbar arriba a todo lo ancho + menú lateral izquierdo en escritorio (como
   cualquier dashboard) — en móvil el menú se queda arriba como barra horizontal con
   scroll (no cabe un lateral fijo en una pantalla estrecha). Un único <div class="admin-shell">
   como grid resuelve las dos disposiciones sin duplicar el HTML de la navegación. */
.admin-shell { min-height: 100vh; }
@media (min-width: 900px) {
  .admin-shell {
    display: grid;
    grid-template-columns: 232px 1fr;
    grid-template-rows: auto 1fr;
    grid-template-areas: "topbar topbar" "sidebar main";
    min-height: 100vh;
  }
}

.admin-topbar { grid-area: topbar; background: var(--color-charcoal); color: var(--color-text-on-dark); }
.admin-topbar__inner { padding: var(--space-3) var(--space-4); display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; justify-content: space-between; }
.admin-topbar__brand { font-family: var(--font-head); font-weight: 700; }
.admin-topbar__user { display: flex; align-items: center; gap: var(--space-3); font-size: 0.9rem; color: var(--color-text-on-dark-muted); }
.admin-topbar__user .btn--ghost { color: #fff; }

.admin-sidebar { grid-area: sidebar; background: var(--color-surface); border-bottom: 1px solid var(--color-border); position: sticky; top: 0; z-index: 20; }
.admin-nav__inner { padding-inline: var(--space-4); display: flex; gap: var(--space-1); overflow-x: auto; -webkit-overflow-scrolling: touch; }
.admin-nav__link { flex-shrink: 0; padding: var(--space-3) var(--space-3); font-weight: 600; color: var(--color-text-muted); border-bottom: 3px solid transparent; white-space: nowrap; }
.admin-nav__link:hover { color: var(--color-ink); }
.admin-nav__link.is-active { color: var(--color-primary); border-bottom-color: var(--color-primary); }

@media (min-width: 900px) {
  .admin-sidebar { border-bottom: none; border-right: 1px solid var(--color-border); align-self: stretch; }
  .admin-nav__inner { flex-direction: column; gap: 2px; padding: var(--space-4) var(--space-3); overflow-x: visible; }
  .admin-nav__link {
    padding: 0.7em 0.9em; border-bottom: none; border-left: 3px solid transparent;
    border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  }
  .admin-nav__link.is-active { background: var(--color-primary-tint); border-left-color: var(--color-primary); }
}

.admin-main { grid-area: main; padding-block: var(--space-5); min-width: 0; }
/* Sin max-width propio: el ancho ya lo limita la rejilla del panel (sidebar + main), un
   segundo límite de ancho aquí (el mismo --container-max del sitio público, pensado para
   una página sin sidebar) solo desperdiciaba espacio en pantallas anchas y forzaba a los
   títulos largos de las tablas a partirse en varias líneas (aviso real del cliente). */
.admin-container { padding-inline: var(--space-4); margin-inline: auto; }
.admin-title { margin-bottom: var(--space-4); }
.admin-section { margin-bottom: var(--space-6); }

.admin-flash { padding: var(--space-3) var(--space-4); border-radius: var(--radius-sm); margin-bottom: var(--space-4); font-weight: 600; }
.admin-flash--ok { background: #e7f6ec; color: var(--color-success); }
.admin-flash--error { background: #fbe9ec; color: var(--color-danger); }

/* Mensajes de resultado de una acción (guardado, error de validación, etc.) se muestran
   como "toast": entran deslizándose desde la esquina inferior derecha, esperan un tiempo
   prudencial y se esconden solos por el mismo sitio (assets/js/admin.js, initToasts()).
   Los avisos PERSISTENTES (modo demo del agente, banner de vista previa) llevan la clase
   admin-flash--sticky y quedan excluidos a propósito: no deben desaparecer solos.
   Sin JavaScript: se quedan como bloque estático arriba del contenido (igual que antes),
   mejora progresiva, no dependencia dura. */
.toast-stack {
  position: fixed; right: var(--space-4); bottom: var(--space-4); z-index: 200;
  display: flex; flex-direction: column-reverse; gap: var(--space-2);
  width: calc(100% - (var(--space-4) * 2)); max-width: 380px; pointer-events: none;
}
.toast-stack .admin-flash {
  margin: 0;
  /* Como toast flota sobre el contenido del dashboard, con el mismo fondo pastel de antes
     (pensado para un aviso estático en el flujo normal) se veía plano y costaba distinguirlo
     por encima de la página (aviso real del cliente). Borde rosa + sombra muy sutil (como si
     se despegara ligeramente de la hoja, no una sombra grande) en vez de --shadow-lg, que el
     cliente vio demasiado marcada. */
  border: 1.5px solid var(--color-primary);
  box-shadow: var(--shadow-sm);
  transform: translateX(140%); opacity: 0; pointer-events: auto;
  transition: transform 350ms ease, opacity 350ms ease;
}
.toast-stack .admin-flash.is-visible { transform: translateX(0); opacity: 1; }

.admin-toolbar { display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: end; margin-bottom: var(--space-4); }
.admin-toolbar .form-field { margin-bottom: 0; }

.admin-table-wrap { overflow-x: auto; background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius); }
.admin-table { width: 100%; border-collapse: collapse; font-size: 0.92rem; min-width: 720px; }
.admin-table th, .admin-table td { padding: var(--space-3); text-align: left; border-bottom: 1px solid var(--color-border); vertical-align: middle; }
.admin-table th { font-family: var(--font-head); font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--color-text-muted); }
.admin-table tr:last-child td { border-bottom: none; }
.admin-table tr:hover td { background: var(--color-cream); }
.admin-table td.is-numeric, .admin-table th.is-numeric { text-align: right; }

.admin-badge { display: inline-block; padding: 0.2em 0.7em; border-radius: var(--radius-pill); font-size: 0.75rem; font-weight: 700; white-space: nowrap; }
.admin-badge--borrador { background: #ece9e6; color: var(--color-text-muted); }
.admin-badge--pendiente_revision, .admin-badge--pendiente { background: #fdf3d8; color: #8a6d1c; }
.admin-badge--aprobado { background: #e3ecfb; color: #2c50a0; }
.admin-badge--publicado, .admin-badge--aceptada { background: #e0f3e6; color: var(--color-success); }
.admin-badge--rechazado { background: #fbe9ec; color: var(--color-danger); }
.admin-badge--alta { background: #fbe9ec; color: var(--color-danger); }
.admin-badge--media { background: #fdf3d8; color: #8a6d1c; }
.admin-badge--baja { background: #e3ecfb; color: #2c50a0; }

.admin-stat-grid { display: grid; gap: var(--space-3); grid-template-columns: 1fr; margin-bottom: var(--space-5); }
@media (min-width: 640px) { .admin-stat-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 960px) { .admin-stat-grid { grid-template-columns: repeat(4, 1fr); } }
.admin-stat { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius); padding: var(--space-4); }
.admin-stat__value { display: block; font-family: var(--font-head); font-weight: 700; font-size: 1.6rem; color: var(--color-primary); }
.admin-stat__label { color: var(--color-text-muted); font-size: 0.88rem; }

.admin-pagination { display: flex; gap: var(--space-2); justify-content: center; margin-top: var(--space-4); flex-wrap: wrap; }
.admin-pagination a, .admin-pagination span { padding: 0.4em 0.8em; border-radius: var(--radius-sm); border: 1px solid var(--color-border); font-size: 0.88rem; }
.admin-pagination .is-active { background: var(--color-primary); color: #fff; border-color: var(--color-primary); }

.admin-form-grid { display: grid; gap: var(--space-4); grid-template-columns: 1fr; }
@media (min-width: 900px) { .admin-form-grid { grid-template-columns: 2fr 1fr; } }
.admin-form-grid textarea { min-height: 240px; font-family: ui-monospace, monospace; font-size: 0.9rem; }
.admin-form-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-4); }

/* Galería de fotos de "La Clínica" (admin/galeria.php), añadida 2026-07-04. */
.gallery-admin-grid { display: grid; gap: var(--space-4); grid-template-columns: repeat(2, 1fr); }
@media (min-width: 640px) { .gallery-admin-grid { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 960px) { .gallery-admin-grid { grid-template-columns: repeat(4, 1fr); } }
.gallery-admin-item { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius); padding: var(--space-2); }
.gallery-admin-item img { width: 100%; aspect-ratio: 1 / 1; object-fit: cover; border-radius: var(--radius-sm); display: block; }
.gallery-admin-item__actions { display: flex; gap: var(--space-2); flex-wrap: wrap; }
.gallery-admin-item__actions form { display: inline-block; }
.gallery-admin-item__actions button[disabled] { opacity: 0.35; cursor: not-allowed; }

.admin-empty { padding: var(--space-5); text-align: center; color: var(--color-text-muted); }
