/* ============================================================
   Deck de presentaciones — estilos compartidos
   ============================================================
   Los usan la vista previa del BackOffice y el enlace público. Todo cuelga de `.pd-root`
   y de variables `--pd-*` propias, así que:

     · En el enlace público mandan los valores de abajo (look de marca, fondo oscuro).
     · Dentro del BackOffice, `.pd-app` reasigna esas variables a las del tema, para que
       el deck se vea en claro y en oscuro sin redefinir NADA del sistema glass.

   Es la regla de la casa: el deck se adapta al tema, no impone el suyo dentro de la app. */

.pd-root {
  --pd-bg: #05070f;
  --pd-panel: rgba(255, 255, 255, 0.05);
  --pd-border: rgba(255, 255, 255, 0.11);
  --pd-fg: #eaf1ff;
  --pd-muted: #9fb0cd;
  --pd-accent: #5b95ff;
  --pd-ok: #34d399;
  --pd-warn: #fbbf24;
  --pd-radius: 18px;

  display: block;
  outline: none;
  color: var(--pd-fg);
}

.pd-root.pd-app {
  --pd-bg: transparent;
  --pd-panel: var(--glass-bg-strong);
  --pd-border: var(--glass-border);
  --pd-fg: var(--text);
  --pd-muted: var(--muted);
  --pd-accent: var(--accent);
  --pd-ok: var(--good);
  --pd-warn: #f59e0b;
}

/* The public viewer shows the slide as the focus. The surrounding page remains part of
   the brand canvas, instead of becoming unused black letterboxing. */
.pd-root.pd-public-canvas .pd-viewport {
  height: clamp(360px, calc(100dvh - 132px), 1080px);
  min-height: 0;
  background: transparent;
  border: 0;
  border-radius: 0;
  overflow: visible;
}
.pd-root.pd-public-canvas .pd-slide.pd-canvas { padding: clamp(6px, 1vw, 18px) clamp(52px, 5vw, 96px); }
.pd-root.pd-public-canvas .pd-lienzo {
  border: 1px solid rgba(197, 216, 255, .14);
  border-radius: clamp(12px, 1.1vw, 20px);
  box-shadow: 0 30px 80px -28px rgba(0, 0, 0, .72), 0 0 0 1px rgba(66, 126, 255, .08);
}
.pd-root.pd-public-canvas .pd-progress {
  top: 8px; left: 18%; right: 18%; height: 2px;
  background: rgba(208, 224, 255, .18); border-radius: 999px; overflow: hidden;
}
.pd-root.pd-public-canvas .pd-progress span { border-radius: inherit; }
.pd-root.pd-public-canvas .pd-nav {
  width: 48px; height: 48px; background: rgba(13, 25, 56, .72);
  border-color: rgba(207, 222, 255, .18); box-shadow: 0 10px 30px rgba(0, 0, 0, .2);
}
.pd-root.pd-public-canvas .pd-nav.prev { left: 0; }
.pd-root.pd-public-canvas .pd-nav.next { right: 0; }
.pd-root.pd-public-canvas .pd-barra {
  bottom: clamp(12px, 2.2vh, 24px); padding: 5px 5px 5px 13px;
  background: rgba(13, 25, 56, .76); border-color: rgba(207, 222, 255, .18);
  box-shadow: 0 12px 32px rgba(0, 0, 0, .22);
}
.pd-root.pd-public-canvas .pd-full {
  display: grid; place-items: center; width: 32px; height: 32px;
  background: rgba(112, 156, 255, .19); transition: background .15s ease, transform .15s ease;
}
.pd-root.pd-public-canvas .pd-full:hover { background: rgba(112, 156, 255, .35); transform: scale(1.06); }
.pd-full svg { display: block; width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.pd-root.pd-public-canvas .pd-viewport:fullscreen,
.pd-root.pd-public-canvas .pd-viewport:-webkit-full-screen {
  height: 100dvh; background: #05070f; overflow: hidden;
}
.pd-root.pd-public-canvas .pd-viewport:fullscreen .pd-slide.pd-canvas,
.pd-root.pd-public-canvas .pd-viewport:-webkit-full-screen .pd-slide.pd-canvas { padding: clamp(8px, 2vh, 26px) clamp(54px, 5vw, 110px); }

.pd-viewport {
  position: relative;
  background: var(--pd-bg);
  border: 1px solid var(--pd-border);
  border-radius: var(--pd-radius);
  overflow: hidden;
  min-height: min(72vh, 620px);
  display: flex;
  flex-direction: column;
}
.pd-root.pd-app .pd-viewport { background: var(--pd-panel); }
.pd-viewport:fullscreen { border-radius: 0; border: 0; min-height: 100vh; background: #05070f; }

/* Barra de avance: dice cuánto queda sin obligar a contar diapositivas. */
.pd-progress {
  position: absolute; top: 0; left: 0; right: 0; height: 3px;
  background: rgba(127, 145, 180, 0.18); z-index: 3;
}
.pd-progress span {
  display: block; height: 100%; background: var(--pd-accent);
  transition: width .35s cubic-bezier(.2, .8, .2, 1);
}

.pd-slide {
  flex: 1;
  display: flex;
  padding: clamp(20px, 4vw, 52px);
  gap: clamp(18px, 3vw, 40px);
  animation: pd-entra .32s cubic-bezier(.2, .8, .2, 1);
}
@keyframes pd-entra { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .pd-slide { animation: none; }
  .pd-progress span { transition: none; }
}

/* ---- Portada y cierre ---- */
.pd-cover, .pd-end, .pd-section {
  flex-direction: column; align-items: center; justify-content: center; text-align: center;
}
.pd-cover-eyebrow, .pd-eyebrow {
  text-transform: uppercase; letter-spacing: .14em; font-size: 12px; color: var(--pd-accent);
}
.pd-cover-title { font-size: clamp(28px, 4.6vw, 52px); margin: 12px 0 0; line-height: 1.1; font-weight: 700; }
.pd-cover-mes { color: var(--pd-muted); margin-top: 10px; text-transform: capitalize; }
.pd-cover-intro { color: var(--pd-muted); max-width: 62ch; margin: 18px 0 0; line-height: 1.6; }
.pd-end h2 { font-size: clamp(26px, 4vw, 44px); margin: 0; }
.pd-end p { color: var(--pd-muted); margin: 8px 0 0; }

.pd-stats { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; margin-top: 30px; }
.pd-stat {
  background: var(--pd-panel); border: 1px solid var(--pd-border); border-radius: 14px;
  padding: 14px 22px; min-width: 104px;
}
.pd-stat b { display: block; font-size: 26px; line-height: 1.1; }
.pd-stat span { font-size: 12px; color: var(--pd-muted); }

.pd-section-n { font-size: clamp(56px, 10vw, 120px); font-weight: 800; color: var(--pd-accent); line-height: 1; }
.pd-section h2 { font-size: clamp(22px, 3vw, 34px); margin: 8px 0 0; font-weight: 600; }

/* ---- Pieza: media grande + panel de contexto ---- */
.pd-item { align-items: stretch; }
.pd-media {
  flex: 1 1 62%; min-width: 0;
  display: flex; align-items: center; justify-content: center;
  background: rgba(127, 145, 180, 0.07);
  border: 1px solid var(--pd-border); border-radius: 14px; overflow: hidden;
}
.pd-img { max-width: 100%; max-height: min(62vh, 560px); object-fit: contain; display: block; }
.pd-video { width: 100%; max-height: min(62vh, 560px); background: #000; }
.pd-frame { width: 100%; aspect-ratio: 16 / 9; }
.pd-frame-doc { aspect-ratio: 3 / 4; }
.pd-frame iframe { width: 100%; height: 100%; border: 0; display: block; }
.pd-vacio, .pd-doclink { color: var(--pd-muted); padding: 40px; text-align: center; }
.pd-doclink { color: var(--pd-accent); text-decoration: none; font-weight: 600; }

/* El guion es texto y merece un ancho de lectura, no una caja cuadrada. */
.pd-k-script .pd-media { background: none; border: 0; align-items: flex-start; }
.pd-guion {
  white-space: pre-wrap; line-height: 1.7; font-size: 16px; max-width: 68ch;
  background: var(--pd-panel); border: 1px solid var(--pd-border); border-radius: 14px;
  padding: 22px 24px; max-height: min(62vh, 560px); overflow: auto; width: 100%;
}
.pd-guion.pequeno { font-size: 13px; padding: 12px 14px; margin-top: 12px; max-height: 180px; }

.pd-info { flex: 0 0 clamp(240px, 30%, 340px); display: flex; flex-direction: column; }
.pd-info h3 { margin: 8px 0 0; font-size: 22px; line-height: 1.25; }
.pd-nota-texto { color: var(--pd-muted); line-height: 1.6; margin: 12px 0 0; }

.pd-badge {
  display: inline-block; margin-top: 16px; padding: 5px 12px; border-radius: 999px;
  font-size: 12px; font-weight: 600; width: fit-content;
}
.pd-badge.ok { background: color-mix(in srgb, var(--pd-ok) 18%, transparent); color: var(--pd-ok); }
.pd-badge.warn { background: color-mix(in srgb, var(--pd-warn) 18%, transparent); color: var(--pd-warn); }

.pd-acciones, .pd-cambios-btns { display: flex; gap: 10px; margin-top: auto; padding-top: 20px; }
.pd-cambios { margin-top: auto; padding-top: 20px; }
.pd-nota {
  width: 100%; resize: vertical; border-radius: 10px; padding: 10px 12px;
  background: var(--pd-panel); border: 1px solid var(--pd-border); color: var(--pd-fg);
  font: inherit; font-size: 14px;
}
.pd-cambios-btns { padding-top: 10px; }
.pd-btn {
  flex: 1; padding: 11px 14px; border-radius: 11px; border: 1px solid var(--pd-border);
  background: var(--pd-panel); color: var(--pd-fg); font: inherit; font-weight: 600;
  font-size: 14px; cursor: pointer; transition: transform .12s ease, filter .12s ease;
}
.pd-btn:hover:not(:disabled) { transform: translateY(-1px); filter: brightness(1.12); }
.pd-btn:disabled { opacity: .5; cursor: default; }
.pd-btn.ok { background: color-mix(in srgb, var(--pd-ok) 20%, transparent); border-color: color-mix(in srgb, var(--pd-ok) 38%, transparent); color: var(--pd-ok); }
.pd-btn.warn { background: color-mix(in srgb, var(--pd-warn) 18%, transparent); border-color: color-mix(in srgb, var(--pd-warn) 36%, transparent); color: var(--pd-warn); }
.pd-btn.ghost { background: none; }
.pd-respuesta {
  margin-top: 16px; padding: 12px 14px; border-radius: 12px; font-size: 13px; line-height: 1.5;
  background: color-mix(in srgb, var(--pd-warn) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--pd-warn) 30%, transparent);
}

/* ---- Grilla de contenido: mockup del feed ---- */
/* Centrado como pareja y no estirado a los bordes: el texto pegado a la izquierda y el
   teléfono pegado a la derecha dejaban un vacío en medio que no dice nada. */
.pd-feed { align-items: center; justify-content: center; gap: clamp(20px, 4vw, 56px); }
.pd-feed-side { flex: 0 1 clamp(240px, 34%, 400px); min-width: 0; }
.pd-feed-side h2 { font-size: clamp(24px, 3.4vw, 40px); margin: 6px 0 0; }
.pd-feed-hint { color: var(--pd-muted); line-height: 1.6; margin: 14px 0 0; max-width: 40ch; }

/* El marco es lo que hace que se lea como "así se va a ver tu perfil" y no como una
   rejilla de imágenes cualquiera. */
.pd-telefono {
  flex: 0 0 auto; width: min(340px, 46%);
  background: rgba(10, 14, 26, .55); border: 1px solid var(--pd-border);
  border-radius: 26px; padding: 10px; overflow: hidden;
}
.pd-root.pd-app .pd-telefono { background: var(--pd-panel); }
.pd-tabs { display: flex; justify-content: space-around; padding: 4px 0 10px; color: var(--pd-muted); font-size: 13px; }
.pd-tabs .on { color: var(--pd-fg); }
.pd-rejilla {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 3px;
  max-height: min(56vh, 480px); overflow: auto;
}
.pd-celda {
  position: relative; aspect-ratio: 1; padding: 0; border: 0; cursor: pointer;
  background: rgba(127, 145, 180, .14); overflow: hidden; display: block;
}
.pd-celda img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pd-celda:hover img { filter: brightness(1.12); }
.pd-celda-vacia { color: var(--pd-muted); font-size: 10px; display: grid; place-items: center; height: 100%; }
.pd-celda-tag {
  position: absolute; top: 0; left: 0; right: 0; padding: 3px 4px;
  background: linear-gradient(to bottom, rgba(0, 0, 0, .72), transparent);
  color: #fff; font-size: 9px; font-weight: 600; letter-spacing: .01em; text-align: left;
}
.pd-celda-reel { position: absolute; bottom: 4px; right: 5px; color: #fff; font-size: 10px; text-shadow: 0 1px 3px rgba(0,0,0,.6); }
.pd-celda-ok, .pd-celda-warn {
  position: absolute; bottom: 4px; left: 5px; width: 15px; height: 15px; border-radius: 50%;
  display: grid; place-items: center; font-size: 9px; color: #04140c; font-weight: 700;
}
.pd-celda-ok { background: var(--pd-ok); }
.pd-celda-warn { background: var(--pd-warn); }

/* ---- Pieza de la grilla ---- */
.pd-post-media { position: relative; width: 100%; display: flex; align-items: center; justify-content: center; }
.pd-post-media .pd-img, .pd-post-media .pd-video { max-height: min(62vh, 560px); border-radius: 8px; }
.pd-post-media.pd-vertical .pd-img, .pd-post-media.pd-vertical .pd-video { max-height: min(64vh, 600px); }
.pd-car {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 32px; height: 32px; border-radius: 50%; border: 0; cursor: pointer;
  background: rgba(6, 10, 20, .62); color: #fff; font-size: 18px; line-height: 1;
}
.pd-car.prev { left: 8px; }
.pd-car.next { right: 8px; }
.pd-dots { position: absolute; bottom: 10px; left: 50%; transform: translateX(-50%); display: flex; gap: 5px; }
.pd-dots span { width: 6px; height: 6px; border-radius: 50%; background: rgba(255, 255, 255, .45); }
.pd-dots span.on { background: #fff; }

.pd-fecha { font-size: 19px; }
.pd-canal {
  margin-top: 8px; font-size: 12px; color: var(--pd-accent); font-weight: 600;
  text-transform: uppercase; letter-spacing: .06em;
}
/* El copy del post es el protagonista de su diapositiva: es lo que el cliente aprueba. */
.pd-k-post .pd-guion.pequeno { font-size: 14px; max-height: 34vh; }

/* ---- Navegación ---- */
.pd-nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 42px; height: 42px; border-radius: 50%; z-index: 2;
  background: var(--pd-panel); border: 1px solid var(--pd-border); color: var(--pd-fg);
  font-size: 22px; line-height: 1; cursor: pointer; backdrop-filter: blur(8px);
  transition: transform .14s ease, filter .14s ease;
}
.pd-nav:hover { filter: brightness(1.2); transform: translateY(-50%) scale(1.06); }
.pd-nav.prev { left: 12px; }
.pd-nav.next { right: 12px; }

.pd-barra {
  position: absolute; bottom: 12px; left: 50%; transform: translateX(-50%);
  display: flex; align-items: center; gap: 10px; z-index: 2;
  background: var(--pd-panel); border: 1px solid var(--pd-border);
  border-radius: 999px; padding: 5px 6px 5px 14px; backdrop-filter: blur(8px);
}
.pd-cuenta { font-size: 12px; color: var(--pd-muted); font-variant-numeric: tabular-nums; }
.pd-full {
  width: 28px; height: 28px; border-radius: 50%; border: 0; cursor: pointer;
  background: rgba(127, 145, 180, 0.16); color: var(--pd-fg); font-size: 13px;
}

/* ============================================================
   Lienzo — la plantilla que se compone a mano
   ============================================================
   Dos contenedores anidados, y cada uno resuelve una cosa distinta:

     · `.pd-canvas` (container-type: size) es el HUECO. Sirve para encajar el artboard sin
       deformarlo: `min(100cqw, 100cqh * ratio)` da el mayor rectángulo con la proporción
       correcta que cabe, sin una línea de JS ni escuchar `resize`.
     · `.pd-lienzo` (container-type: inline-size) es el ARTBOARD. Dentro de él todo se mide
       en `cqw`, así que la maqueta entera escala junta: el texto crece igual que el marco
       que lo contiene, y la misma diapositiva vale para la vista previa y el proyector. */

.pd-slide.pd-canvas {
  container-type: size;
  padding: clamp(8px, 1.6vw, 26px);
  align-items: center;
  justify-content: center;
}

/* SOLO dentro del visor (enlace público y vista previa del BackOffice): el alto del
   lienzo debe ser DEFINIDO en ambos ejes para que `container-type: size` califique como
   size container y `cqh` resuelva. Viniendo de flex dentro de un viewport con solo
   `min-height`, Chrome reciente trata el alto como indefinido y `100cqh` da 0 — el
   lienzo entero media 0×0 y la diapositiva salía en blanco (desktop sí, móvil no).
   `position: absolute` da el tamaño definido y el viewport ya es el ancestro
   posicionado. No se aplica al editor: miniaturas y artboard dan altos explícitos en
   styles.css (`.lz-thumb`, `.lz-canvas`) y un absoluto les robaría su caja. */
.pd-viewport .pd-slide.pd-canvas {
  position: absolute;
  inset: 0;
}

.pd-lienzo {
  container-type: inline-size;
  position: relative;
  aspect-ratio: var(--pd-ar, 16/9);
  width: min(100cqw, calc(100cqh * var(--pd-arn, 1.7778)));
  overflow: hidden;
  border-radius: 12px;
  box-shadow: 0 24px 60px -22px rgba(0, 0, 0, .62);
  background: #0a2f86;
}

/* El degradado de marca de la portada: el mismo azul del deck que esto sustituye. */
.pd-lienzo.grad {
  background:
    radial-gradient(120% 120% at 22% 30%, #2f7bff 0%, #1652c7 38%, #0a2f86 68%, #02050f 100%);
}

.pd-el {
  position: absolute;
  margin: 0;
  transform-origin: center;
}

.pd-el-text {
  display: flex;
  flex-direction: column;
  justify-content: center;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.pd-el-img { display: block; }

/* Hueco de un elemento sin imagen todavía. Se ve en la vista previa del equipo; en el
   enlace del cliente casi nunca, porque una presentación se comparte llena. */
.pd-el-hueco {
  display: flex; align-items: center; justify-content: center;
  border: 1px dashed rgba(255, 255, 255, .34);
  border-radius: 8px;
  color: rgba(255, 255, 255, .6);
  font-size: 1.1cqw;
  text-align: center;
}

/* ---- Mockup del perfil de Instagram ----
   Es un CONTENEDOR propio, y no es un detalle de implementación: sin esto, los `cqw` de
   dentro se medirían contra el lienzo entero, así que un marco estrecho llevaría los
   márgenes y los iconos de uno ancho y la última fila de celdas quedaría cortada.
   Siendo contenedor, todo lo de dentro se mide contra el marco y encoge con él — y el alto
   que calcula `presLIgAlto()` en app.js, que usa estos mismos coeficientes, cuadra. */
.pd-el-ig {
  container-type: inline-size;
  overflow: hidden;
}
/* Todas las medidas de dentro son `cqw` del MARCO, y por eso están aquí y no en el marco:
   un contenedor no se consulta a sí mismo. Los coeficientes (2.4 · 1.9 · 1.2 · 2.1 · 0.6)
   son los mismos que usa `presLIgAlto()` en app.js para calcular el alto que hace que la
   rejilla quepa exacta. Si cambian aquí, hay que cambiarlos allí. */
.pd-ig-inner {
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: 2.4cqw 1.9cqw;
  gap: 1.2cqw;
}
.pd-ig-tabs {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  place-items: center;
  padding-bottom: .6cqw;
}
.pd-ig-tabs svg {
  width: 2.1cqw; height: 2.1cqw;
  fill: none; stroke: #10473f; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round;
}
.pd-ig-grid { display: grid; align-content: start; }
.pd-ig-cell {
  position: relative;
  overflow: hidden;
  background: rgba(16, 71, 63, .07);
}
.pd-ig-cell img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* En el visor la celda del feed es un BOTÓN —se toca para abrir la publicación— y en el
   editor sigue siendo un div, porque allí el clic es del editor, que con él selecciona y
   arrastra el elemento. Misma clase para las dos, así que el reset del botón va aparte. */
button.pd-ig-cell { appearance: none; -webkit-appearance: none; border: 0; padding: 0; cursor: pointer; }
/* «Encaje: Entera» también en las celdas del feed. Sin esta regla el selector del inspector
   llegaba al nodo y no lo consumía nadie: doce artes verticales seguían recortadas a 4:5 y
   sin aviso. Las del marco de Instagram (`.pd-el-ig`) siguen siempre recortadas: ese elemento
   no ofrece encaje. */
.pd-el-phone.contain .pd-ig-cell img { object-fit: contain; }

/* ---- Carrusel de imágenes ---- */
.pd-el-carousel {
  overflow: hidden;
  background: rgba(5, 12, 30, .22);
  border-radius: var(--pd-carousel-radius, 0);
}
.pd-carousel-track { width: 100%; height: 100%; }
.pd-carousel-slide { display: none; width: 100%; height: 100%; }
.pd-carousel-slide.on { display: block; }
.pd-carousel-slide img { width: 100%; height: 100%; object-fit: var(--pd-carousel-fit, cover); display: block; }
.pd-carousel-empty {
  width: 100%; height: 100%; display: grid; place-items: center;
  color: rgba(255, 255, 255, .72); font-size: 1.25cqw;
  border: 1px dashed rgba(255, 255, 255, .42); box-sizing: border-box;
}
.pd-carousel-nav {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 1;
  display: grid; place-items: center; width: 5cqw; height: 5cqw; min-width: 22px; min-height: 22px;
  border: 0; border-radius: 50%; cursor: pointer; background: rgba(4, 8, 18, .58); color: #fff;
  font-size: 3.2cqw; line-height: 1; transition: background .15s ease, transform .15s ease;
}
.pd-carousel-nav:hover { background: rgba(4, 8, 18, .8); transform: translateY(-50%) scale(1.06); }
.pd-carousel-nav.prev { left: 1.5cqw; }
.pd-carousel-nav.next { right: 1.5cqw; }
.pd-carousel-dots {
  position: absolute; left: 50%; bottom: 2cqw; transform: translateX(-50%); z-index: 1;
  display: flex; gap: 1.15cqw;
}
.pd-carousel-dots span { width: 1.55cqw; height: 1.55cqw; min-width: 5px; min-height: 5px; border-radius: 50%; background: rgba(255, 255, 255, .55); }
.pd-carousel-dots span.on { background: #fff; }

/* ---- Teléfono con Instagram (iPhone 17 Pro Max) ----

   Dos contenedores anidados, y cada uno tiene su razón:

     · `.pd-el-phone` es el contenedor de la FILA. El hueco entre teléfonos va en `cqw` sobre
       `.pd-phone-row`, que es su HIJO: un elemento que establece un contenedor no se
       consulta a sí mismo, así que un `gap` declarado en el propio marco se mediría contra
       el lienzo entero (1440 u) y saldría enorme. Es la misma trampa que documenta el marco
       de Instagram, aquí con flex en vez de grid.
     · `.pd-phone` es el contenedor del TELÉFONO. Todo lo de dentro —biseles, radios, isla,
       tipografía— se mide contra el ancho de UN teléfono, así que tres teléfonos en fila se
       ven igual que uno solo, en pequeño.

   Los coeficientes son `PresDeck.PHONE` multiplicado por 100. NO se copian en app.js: el
   editor los lee del motor, que es lo que impide que las dos mitades discrepen.

   `box-sizing` se declara aquí y no se hereda: el reset vive en styles.css (solo el SPA) y
   en un `<style>` propio de p.html, y el motor no es dueño de ninguno de los dos. Sin él,
   `aspect-ratio` mediría la caja de contenido y el relleno del bisel se sumaría por fuera. */
.pd-el-phone {
  container-type: inline-size;
}
.pd-phone-row {
  display: flex;
  align-items: flex-start;
  width: 100%;
}
.pd-phone {
  container-type: inline-size;
  flex: 1 1 0;
  min-width: 0;
}
.pd-phone-body,
.pd-phone-screen,
.pd-phone-label,
.pd-phone-hueco { box-sizing: border-box; }

/* El bisel ES el relleno, y el alto sale de `aspect-ratio`. De ahí que el scroll del feed no
   necesite una sola medición en JS: su contenedor tiene alto definido en los dos ejes. */
.pd-phone-body {
  position: relative;
  aspect-ratio: 1 / 2.0949;
  padding: 3.28cqw;
  border-radius: 16.45cqw;
  background: #0b0b0d;
  box-shadow: 0 1.4cqw 3.4cqw rgba(2, 5, 15, .38), inset 0 0 0 .34cqw rgba(255, 255, 255, .16);
}
/* Sin marco: la pantalla sola, para cuando el teléfono estorba. Se quita el relleno, no el
   radio: una captura de Instagram tiene las esquinas redondeadas igual. */
.pd-phone-body.sin-marco {
  padding: 0;
  border-radius: 13.17cqw;
  box-shadow: none;
}
/* El color lo pone `phoneHtml` en línea (`el.bg`); esto es solo el respaldo para una maqueta
   que no lo traiga. El del chasis NO se puede pisar: va en `.pd-phone-body`. */
.pd-phone-screen {
  position: relative;
  height: 100%;
  overflow: hidden;
  border-radius: 13.17cqw;
  background: #fff;
  display: flex;
  flex-direction: column;
}
.pd-phone-island {
  position: absolute;
  left: 50%;
  top: 2.34cqw;
  transform: translateX(-50%);
  width: 26.76cqw;
  height: 7.93cqw;
  border-radius: 4cqw;
  background: #06060a;
  z-index: 4;
}
/* La fecha bajo el teléfono. La banda se reserva con o sin fecha escrita, para que añadir
   una historia no mueva el alto del elemento mientras alguien teclea. */
/* La BANDA se reserva siempre; la pastilla solo aparece con fecha escrita. Así el alto del
   elemento no salta mientras alguien teclea la fecha. */
.pd-phone-label {
  height: 25cqw;
  display: grid;
  place-items: start center;
  padding-top: 6cqw;
}
/* Pastilla blanca con el texto en azul de marca, como en el deck que esto sustituye. */
.pd-phone-label span {
  padding: 1.6cqw 4cqw;
  border-radius: 1.6cqw;
  background: #fff;
  color: #0a2f86;
  font-size: 5.6cqw;
  font-weight: 700;
  letter-spacing: .03em;
  white-space: nowrap;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pd-phone-hueco {
  width: 100%;
  height: 100%;
  display: grid;
  place-items: center;
  text-align: center;
  padding: 4cqw;
  color: rgba(16, 71, 63, .6);
  font-size: 4.4cqw;
  background: repeating-linear-gradient(-45deg, rgba(16, 71, 63, .06) 0 3cqw, rgba(16, 71, 63, .12) 3cqw 6cqw);
}

/* -- Elementos comunes de la interfaz -- */
.pd-ig-av {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  border-radius: 50%;
  overflow: hidden;
  background: #fff;
}
.pd-ig-av img { width: 100%; height: 100%; object-fit: contain; padding: 8%; box-sizing: border-box; }
.pd-ig-av.vacio { background: rgba(16, 71, 63, .1); }
.pd-ig-av.vacio svg { width: 62%; height: 62%; fill: none; stroke: rgba(16, 71, 63, .5); stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.pd-ig-av.mini { width: 8cqw; height: 8cqw; }
.pd-ig-av.grande { width: 19cqw; height: 19cqw; }
.pd-ig-av.anillo { width: 9.4cqw; height: 9.4cqw; box-shadow: 0 0 0 .55cqw #fff, 0 0 0 1.1cqw #d9457f; }
.pd-ig-acc svg, .pd-ig-mas svg {
  width: 6.4cqw; height: 6.4cqw;
  fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round;
}
.pd-ig-mas svg { width: 5cqw; height: 5cqw; }

/* -- Historia -- */
.pd-ig-story { position: relative; height: 100%; background: #111; }
.pd-ig-story-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.pd-el-phone.contain .pd-ig-story-img { object-fit: contain; }
.pd-ig-story-top {
  position: absolute; left: 0; right: 0; top: 0; z-index: 3;
  padding: 11cqw 4cqw 0;
  background: linear-gradient(rgba(0, 0, 0, .42), transparent);
}
.pd-ig-barra { display: block; height: 1cqw; border-radius: 1cqw; background: rgba(255, 255, 255, .38); overflow: hidden; }
.pd-ig-barra i { display: block; width: 42%; height: 100%; background: #fff; }
.pd-ig-story-fila {
  display: flex; align-items: center; gap: 2.4cqw;
  padding: 3.2cqw 0;
  color: #fff; font-size: 4.4cqw; font-weight: 600;
}
.pd-ig-story-fila b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pd-ig-story-fila .pd-ig-mas { margin-left: auto; }
.pd-ig-story-pie {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 3;
  display: flex; align-items: center; gap: 3cqw;
  padding: 4cqw 4cqw 5cqw;
  color: #fff;
  background: linear-gradient(transparent, rgba(0, 0, 0, .4));
}
.pd-ig-responder {
  flex: 1 1 auto; padding: 2.6cqw 4cqw; border-radius: 20cqw;
  border: .4cqw solid rgba(255, 255, 255, .6);
  font-size: 4cqw; color: rgba(255, 255, 255, .9);
}

/* -- Vista previa del feed --
   El scroll va sobre una caja de alto DEFINIDO, así que es CSS puro: nada que recalcular al
   girar el móvil, al entrar en pantalla completa ni al redimensionar. */
/* `position: relative` es lo que ancla la publicación abierta: se superpone al perfil sin
   salirse del teléfono, igual que en Instagram. */
.pd-ig-feed { position: relative; display: flex; flex-direction: column; height: 100%; min-height: 0; background: #fff; color: #10473f; }
.pd-ig-topbar {
  display: flex; align-items: center; gap: 2cqw;
  padding: 11.5cqw 4cqw 2.6cqw;
  font-size: 4.6cqw; font-weight: 700;
  border-bottom: .3cqw solid rgba(16, 71, 63, .1);
}
.pd-ig-topbar b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pd-ig-topbar .pd-ig-mas { margin-left: auto; }
.pd-ig-feed-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.pd-ig-feed-scroll::-webkit-scrollbar { display: none; }
.pd-ig-perfil { display: flex; align-items: center; gap: 4cqw; padding: 4cqw; }
.pd-ig-perfil-txt { min-width: 0; display: flex; flex-direction: column; gap: .8cqw; }
.pd-ig-perfil-txt b { font-size: 4.4cqw; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pd-ig-perfil-txt span { font-size: 3.8cqw; color: rgba(16, 71, 63, .68); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pd-ig-feed .pd-ig-tabs { padding: 2.4cqw 0; border-top: .3cqw solid rgba(16, 71, 63, .1); }
.pd-ig-feed .pd-ig-tabs svg { width: 5.6cqw; height: 5.6cqw; stroke-width: 1.5; }
.pd-ig-feed-vacio {
  margin: 4cqw; padding: 12cqw 4cqw; text-align: center;
  font-size: 4cqw; color: rgba(16, 71, 63, .6);
  border: .5cqw dashed rgba(16, 71, 63, .3); border-radius: 3cqw;
}
/* Que la rejilla se toca no se adivina, así que se dice — pero solo cuando hay algún copy
   escrito, que anunciarlo sobre un feed sin textos sería prometer una pantalla vacía. */
.pd-ig-pista {
  padding: 2.6cqw 4cqw 4cqw; text-align: center;
  font-size: 3.4cqw; color: rgba(16, 71, 63, .55);
}

/* -- La publicación abierta --

   Cubre la pantalla del teléfono como la vista de post de Instagram cubre el perfil. NO es
   un modal de la página: vive dentro del teléfono, así que se mide en `cqw` como todo lo de
   ahí dentro, hereda el recorte de `.pd-phone-screen` y se queda por debajo de la isla
   (`z-index: 4`), que es chasis y no se tapa con software. */
.pd-ig-detalle {
  position: absolute; inset: 0; z-index: 3;
  display: flex; flex-direction: column; min-height: 0;
  background: #fff;
}
.pd-ig-detalle-top {
  display: flex; align-items: center; gap: 3cqw;
  padding: 11.5cqw 4cqw 2.6cqw;
  font-size: 4.2cqw; font-weight: 700;
  border-bottom: .3cqw solid rgba(16, 71, 63, .1);
}
.pd-el-phone.sin-marco .pd-ig-detalle-top { padding-top: 4cqw; }
.pd-ig-atras {
  display: grid; place-items: center; flex: 0 0 auto;
  width: 6.4cqw; height: 6.4cqw; min-width: 18px; min-height: 18px;
  padding: 0; border: 0; background: none; color: inherit; cursor: pointer;
}
.pd-ig-atras svg {
  width: 100%; height: 100%;
  fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round;
}
.pd-ig-detalle-n { margin-left: auto; font-size: 3.6cqw; font-weight: 500; color: rgba(16, 71, 63, .6); }
.pd-ig-detalle-scroll {
  flex: 1 1 auto; min-height: 0;
  overflow-y: auto; overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch; scrollbar-width: none;
}
.pd-ig-detalle-scroll::-webkit-scrollbar { display: none; }
/* La vista abierta ya trae su propia cabecera, así que la del post no repite el aire que
   despeja la isla: quedaría un hueco blanco entre las dos. */
.pd-ig-detalle .pd-ig-post-top { padding-top: 3.4cqw; }
/* Y aquí el pie de foto se lee ENTERO, al contrario que en el post fijo. Allí el copy
   completo está en el cuadro grande de la diapositiva y recortarlo a cinco líneas no esconde
   nada; aquí esta vista es el único sitio donde ese texto existe. Se desplaza en vez de
   recortarse, y con los saltos de línea puestos: un pie de foto se escribe por párrafos. */
.pd-ig-detalle .pd-ig-post-pie {
  display: block; -webkit-line-clamp: none; overflow: visible;
  white-space: pre-wrap; overflow-wrap: anywhere;
  padding-bottom: 4cqw;
}
/* Pasar de post sin volver a la rejilla.
 *
 * La franja es un hermano del scroll, no una banda superpuesta: probado superpuesto, con un
 * copy largo las flechas caen ENCIMA del texto —un degradado blanco no lo arregla, solo lo
 * difumina—, y metidas dentro del scroll obligarían a bajar hasta el final del copy para
 * cambiar de post. Fuera del scroll siempre están, y no tapan una línea. */
.pd-ig-detalle-nav {
  flex: 0 0 auto;
  display: flex; justify-content: space-between;
  padding: 2.2cqw 3cqw;
  background: #fff;
  border-top: .3cqw solid rgba(16, 71, 63, .1);
}
.pd-ig-detalle-nav button {
  display: grid; place-items: center;
  width: 8cqw; height: 8cqw; min-width: 24px; min-height: 24px;
  padding: 0; border: 0; border-radius: 50%; cursor: pointer;
  background: rgba(4, 8, 18, .58); color: #fff;
  font-size: 4.4cqw; line-height: 1;
}
.pd-ig-detalle-nav button:hover { background: rgba(4, 8, 18, .8); }

/* -- Post fijo -- */
.pd-ig-post { display: flex; flex-direction: column; height: 100%; min-height: 0; background: #fff; color: #10473f; }
.pd-ig-post-top {
  display: flex; align-items: center; gap: 3cqw;
  padding: 12cqw 4cqw 3cqw;
  font-size: 4.4cqw; font-weight: 600;
}
.pd-ig-post-top b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pd-ig-post-top .pd-ig-mas { margin-left: auto; }
.pd-ig-post-img { position: relative; width: 100%; overflow: hidden; background: rgba(16, 71, 63, .07); }
.pd-ig-post-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pd-el-phone.contain .pd-ig-post-img img { object-fit: contain; }
.pd-ig-post-acc { display: flex; align-items: center; gap: 4.4cqw; padding: 3.4cqw 4cqw 2cqw; }
.pd-ig-post-acc .guardar { margin-left: auto; }
/* El pie de foto se recorta como en Instagram en vez de empujar el post fuera de la
   pantalla: un copy de dos mil caracteres no cabe en un teléfono y estirarlo rompería el
   marco, que es lo único que esta diapositiva viene a enseñar. El copy completo se lee en el
   cuadro grande de la diapositiva, que es para lo que está. */
.pd-ig-post-pie {
  padding: 0 4cqw 4cqw;
  font-size: 3.9cqw; line-height: 1.45;
  overflow: hidden;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 5;
}
.pd-ig-post-pie b { font-weight: 700; }
.pd-ig-post-pie.vacio { color: rgba(16, 71, 63, .45); font-style: italic; }

/* Sin marco no hay isla, así que el aire que la despeja sobra: sin esto la cabecera queda
   flotando en el vacío justo cuando se ha pedido enseñar la pantalla sola. */
.pd-el-phone.sin-marco .pd-ig-story-top { padding-top: 4cqw; }
.pd-el-phone.sin-marco .pd-ig-topbar { padding-top: 4cqw; }
.pd-el-phone.sin-marco .pd-ig-post-top { padding-top: 4cqw; }

/* Al imprimir, el feed se congela arriba: así la hoja sale igual siempre. Desplegar el feed
   entero daría un teléfono de tres metros, que no es un mockup. La exportación honesta de un
   feed largo es trabajo del ticket de PDF, que sigue pendiente. */
@media print {
  .pd-ig-feed-scroll { overflow: hidden; }
  /* Y la publicación que estuviera abierta no sale en la hoja: lo que la diapositiva viene a
     enseñar impresa es el feed, no el post que alguien dejó abierto al imprimir. */
  .pd-ig-detalle { display: none; }
}

@media (max-width: 860px) {
  .pd-item, .pd-feed { flex-direction: column; }
  .pd-telefono { width: min(320px, 92%); }
  .pd-rejilla { max-height: 44vh; }
  .pd-info { flex: 0 0 auto; }
  .pd-acciones, .pd-cambios { margin-top: 16px; padding-top: 0; }
  .pd-nav.prev { left: 6px; }
  .pd-nav.next { right: 6px; }
  .pd-root.pd-public-canvas .pd-viewport { height: calc(100dvh - 120px); }
  /* Las canaletas de las flechas se comían 84 px de 375 — el 22% del ancho, que en vertical
     es EL recurso escaso: el lienzo es 16:9 y su alto sale del ancho, así que cada píxel
     lateral cuesta medio píxel de alto. Las flechas pasan a superponerse sobre el lienzo,
     que es lo que hace cualquier visor en un teléfono. Medido a 375 px: 267 → 343 de ancho
     (+28%) y 150 → 193 de alto. */
  .pd-root.pd-public-canvas .pd-slide.pd-canvas { padding: 8px; }
  .pd-root.pd-public-canvas .pd-nav {
    width: 38px; height: 38px;
    background: rgba(5, 7, 15, .58);
    border-color: rgba(207, 222, 255, .24);
  }
  .pd-root.pd-public-canvas .pd-nav.prev { left: 4px; }
  .pd-root.pd-public-canvas .pd-nav.next { right: 4px; }
  .pd-root.pd-public-canvas .pd-progress { left: 24%; right: 24%; }

}

/* Girar el teléfono es el único cambio que de verdad mueve la aguja.
 *
 * Quitar las canaletas gana un 25% de ancho, pero un artboard 16:9 en vertical tiene un
 * techo duro: a 375 px el texto de 30 unidades pasa de 5,6 px a 7 px — mejor, y todavía
 * ilegible. En horizontal el mismo texto mide 11,1 px. La diferencia no está en el CSS,
 * está en la orientación.
 *
 * Se resuelve con una media query y ni una línea de JS: aparece en vertical, desaparece al
 * girar. Se descartó la Screen Orientation API porque en iPhone no existe — y el iPhone es
 * justo donde más falta hace, ya que Safari tampoco permite pantalla completa fuera de un
 * <video>. Un aviso que funciona en todos los teléfonos vale más que un bloqueo que solo
 * funciona en Android. */
.pd-girar { display: none; }

/* El visor reclama la altura cuando el teléfono está en horizontal.
   `100dvh - 132px` reserva sitio para la cabecera y el pie de p.html, que ahí se ocultan
   (ver su @media). Sin esto, girar el teléfono daba MENOS lienzo que dejarlo en vertical. */
@media (orientation: landscape) and (max-height: 500px) {
  .pd-root.pd-public-canvas .pd-viewport { height: calc(100dvh - 10px); }
  .pd-root.pd-public-canvas .pd-slide.pd-canvas { padding: 6px; }
}

@media (max-width: 860px) and (orientation: portrait) {
  .pd-root.pd-public-canvas .pd-girar {
    display: block; margin: 10px auto 0; max-width: 30ch; text-align: center;
    font-size: 12.5px; line-height: 1.4; color: var(--pd-muted);
  }
  .pd-root.pd-public-canvas .pd-girar::before { content: "↻ "; opacity: .8; }
}

/* ============================================================
   Respuesta del cliente por slide (solo lienzo)
   ============================================================
   En el enlace público, cada diapositiva lleva una barra inferior con «Aprobar» y
   «Comentar». Comentar abre nota + lápiz: los trazos se dibujan sobre el lienzo en
   unidades del artboard y viajan con el comentario. En la vista previa del equipo la
   barra no existe: solo un badge de solo lectura cuando el cliente ya respondió. */

/* El hueco que ocupa la barra, en UNA variable y declarada en el viewport.
 *
 * Antes esto era `.pd-canvas-resp { padding-bottom: 64px }` y NO reservaba nada: lo pisaba
 * el shorthand `.pd-root.pd-public-canvas .pd-slide.pd-canvas { padding: … }`, más
 * específico (0,4,0 contra 0,1,0). El navegador computaba 12,8 px y la barra tapaba 37 px
 * de diapositiva — el CSS documentaba una intención que no ocurría.
 *
 * Subir la especificidad habría funcionado hasta la próxima regla que tocara `padding`.
 * Con una variable no hay pelea: nadie más la declara, así que el valor gana siempre y el
 * lienzo, la barra y la píldora del contador leen todos el MISMO número.
 *
 * Va en el viewport y no en la slide porque `.pd-barra` (el contador) es hermano de la
 * diapositiva, no descendiente, y también necesita saber cuánto sitio ocupa la barra.
 *
 * `:not(.ro)` deja fuera la vista previa del equipo: ahí la barra es un badge flotante en
 * la esquina, no ocupa el ancho y no hay nada que reservar. */
.pd-viewport:has(.pd-slide-resp:not(.ro)) { --pd-hueco-barra: 60px; }
/* Con los cambios de la ronda anterior abiertos, la barra gana una fila: 38 px de nota más
   su separador. Sin declararlo aquí, esa fila se comía la diapositiva en vez de reservar
   sitio — es el mismo fallo que documenta el bloque de arriba, y la variable existe justo
   para que añadir un estado sea una línea y no una pelea de especificidad. */
.pd-viewport:has(.pd-slide-resp.con-previos) { --pd-hueco-barra: 116px; }
.pd-viewport:has(.pd-slide-resp.panel) { --pd-hueco-barra: 136px; }

/* El lienzo se encoge para dejar sitio, en vez de que la barra lo tape.
 *
 * Se le resta el hueco al PRESUPUESTO de alto y se empuja hacia arriba con el margen. Las
 * dos ramas del `min()` siguen cabiendo: si manda el alto, el lienzo mide justo
 * `100cqh - hueco` y con el margen suma `100cqh`; si manda el ancho, es aún más bajo. */
.pd-canvas-resp .pd-lienzo {
  width: min(100cqw, calc((100cqh - var(--pd-hueco-barra, 0px)) * var(--pd-arn, 1.7778)));
  margin-bottom: var(--pd-hueco-barra, 0px);
}

/* Los trazos del lápiz, dentro del lienzo y por encima de la maqueta. */
.pd-marks {
  position: absolute; inset: 0; width: 100%; height: 100%;
  pointer-events: none; z-index: 2; overflow: visible;
}
.pd-marks path {
  fill: none; stroke: #ff5c5c; stroke-width: 7;
  stroke-linecap: round; stroke-linejoin: round; opacity: .92;
}
.pd-marks.dibujo { pointer-events: auto; cursor: crosshair; touch-action: none; }

/* Los trazos de la RONDA ANTERIOR, cuando el cliente los abre desde la barra.
 *
 * En ámbar y no en el rojo de los vivos, y por debajo de ellos (`z-index` menor): las dos
 * capas pueden estar puestas a la vez —lo que pediste antes y lo que estás pidiendo ahora—
 * y en el mismo color serían un solo garabato ilegible. Punteados además del color, porque
 * distinguir dos rojos y dos ámbares no puede depender de ver bien el color. */
.pd-marks.previos { z-index: 1; }
.pd-marks.previos path {
  stroke: var(--pd-warn); stroke-dasharray: 14 10; opacity: .72;
}

/* La barra pertenece a la DIAPOSITIVA, así que mide lo que mide el lienzo.
 *
 * Iba de borde a borde del viewport —211 px más ancha que el lienzo a 1280— y cruzaba las
 * canaletas de las flechas, así que no se leía como parte de la diapositiva que estás
 * juzgando: parecía chrome del visor. Se le da la MISMA fórmula de ancho que al lienzo y
 * se centra, de modo que las dos cajas comparten borde izquierdo y derecho. */
.pd-slide-resp {
  position: absolute; bottom: 0; z-index: 4;
  left: 50%; right: auto; transform: translateX(-50%);
  width: min(100cqw, calc((100cqh - var(--pd-hueco-barra, 0px)) * var(--pd-arn, 1.7778)));
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 9px 12px;
  background: rgba(5, 7, 15, .82); backdrop-filter: blur(8px);
  border: 1px solid var(--pd-border);
  border-radius: 14px;
}
.pd-root.pd-app .pd-slide-resp { background: var(--pd-panel); }
.pd-slide-resp .pd-btn { flex: 0 0 auto; padding: 8px 14px; font-size: 13px; }
.pd-slide-resp-estado { display: flex; align-items: center; gap: 8px; min-width: 0; }
.pd-slide-resp-pend { font-size: 12px; color: var(--pd-muted); }
.pd-slide-resp-nota {
  font-size: 12px; color: var(--pd-muted); white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis; max-width: 320px;
}
.pd-slide-resp-spacer { flex: 1; }

/* El bloque de la ronda anterior: ocupa su propia fila dentro de la barra.
 *
 * `flex: 0 0 100%` fuerza el salto sin envolver los controles en otro div, que habría
 * roto los selectores de hijo directo de más abajo. */
.pd-previos {
  flex: 0 0 100%; display: flex; align-items: baseline; gap: 8px; min-width: 0;
  padding-bottom: 7px; border-bottom: 1px solid var(--pd-border);
}
.pd-previos-tag {
  flex: 0 0 auto; font-size: 11px; letter-spacing: .04em; text-transform: uppercase;
  color: var(--pd-warn); opacity: .9;
}
/* La nota se lee entera: es el motivo por el que se abrió el bloque. Se le pone techo y
   scroll en vez de recortarla con puntos suspensivos, que es lo que hace la nota de la
   barra —ahí sobra el detalle, aquí es lo único que importa. */
.pd-previos-nota {
  flex: 1; min-width: 0; font-size: 12.5px; line-height: 1.4; color: var(--pd-fg);
  max-height: 38px; overflow-y: auto; overscroll-behavior: contain;
}
.pd-previos-nota.vacia { color: var(--pd-muted); font-style: italic; }
.pd-ver-previos.on { border-color: color-mix(in srgb, var(--pd-warn) 45%, transparent); }

/* La slide aprobada en un enlace anterior no tiene acciones, así que su mensaje dispone
   de toda la barra: se deja crecer en vez de recortarse a 320 px como la nota normal. */
.pd-slide-resp.bloqueada .pd-slide-resp-estado { flex: 1; flex-wrap: wrap; }
.pd-slide-resp.bloqueada .pd-slide-resp-nota { white-space: normal; max-width: none; }

/* Jerarquía: aprobar es la acción esperada y comentar la excepción.
 *
 * Eran dos botones rellenos del mismo peso compitiendo entre sí. Aprobar se queda sólido y
 * comentar pasa a contorno: se sigue leyendo, pero deja de disputar la mirada. */
.pd-slide-resp > .pd-btn.warn {
  background: none;
  border-color: color-mix(in srgb, var(--pd-warn) 30%, transparent);
}
.pd-slide-resp > .pd-btn.warn:hover:not(:disabled) {
  background: color-mix(in srgb, var(--pd-warn) 14%, transparent);
}

/* El contador se mete DENTRO de la barra en vez de apilarse encima.
 *
 * Vivía en `bottom: 12–24px` con menos `z-index`, así que la barra se lo tragaba. Subirlo
 * por encima del hueco reservado solo mueve el problema: mide 44 px de alto y entre el
 * lienzo y la barra quedan 20, así que volvería a taparle contenido a la diapositiva.
 *
 * La barra ya tiene el centro vacío —estado a la izquierda, acciones a la derecha— y el
 * contador va centrado, así que cae justo en ese hueco. Una sola fila de chrome en vez de
 * dos capas. Se le quitan fondo y borde para que se lea como parte de la barra y no como
 * una pastilla flotando encima. */
.pd-viewport:has(.pd-slide-resp:not(.ro)) .pd-barra {
  bottom: 8px;
  z-index: 5;
  background: none;
  border-color: transparent;
  box-shadow: none;
  backdrop-filter: none;
}

/* Mientras se escribe el comentario, la barra crece a panel y el contador sobra: taparía
   el textarea o volvería a montarse sobre la diapositiva. Se retira hasta que se cierre. */
.pd-viewport:has(.pd-slide-resp.panel) .pd-barra { display: none; }

/* Los dos estados nuevos sacan el contador de la barra.
 *
 * Meterlo dentro funciona porque el centro de la barra está vacío —estado a la izquierda,
 * acciones a la derecha—, y los dos lo llenan por motivos distintos:
 *
 *   · Un tercer botón ensancha el grupo de acciones hasta pasarse del centro, así que la
 *     píldora aterrizaba sobre «Ver cambios solicitados». La condición es que el botón
 *     EXISTA, no que el bloque esté abierto: con el bloque cerrado el choque es el mismo,
 *     y `con-previos` habría dejado justo ese caso fuera.
 *   · `bloqueada` no tiene acciones, así que su mensaje ocupa el ancho entero y el
 *     contador se le montaba encima a media frase.
 *
 * Se sube por encima del hueco reservado, que es lo mismo que hace la regla de móvil por
 * la misma razón. Va después de la regla de arriba a propósito: misma especificidad, gana
 * la última. */
.pd-viewport:has(.pd-slide-resp .pd-ver-previos) .pd-barra,
.pd-viewport:has(.pd-slide-resp.bloqueada) .pd-barra {
  bottom: calc(var(--pd-hueco-barra, 0px) + 10px);
}

/* En móvil la barra recupera el ancho completo.
 *
 * Anclarla al lienzo es lo correcto en escritorio: hace que se lea como parte de la
 * diapositiva. Pero con el lienzo a 267 px de 351 la barra envuelve a tres filas —96 px
 * donde el hueco reservado son 60—, así que los botones se salían por debajo del viewport.
 * A ancho completo entra en una sola fila. Medido a 375 px: 96 px contra 53 px.
 *
 * Va DESPUÉS de las reglas de arriba a propósito: con la misma especificidad, gana la
 * última, y el bloque `@media` original vive antes en el fichero. */
@media (max-width: 860px) {
  .pd-root.pd-public-canvas .pd-slide-resp:not(.ro) {
    left: 0; right: 0; width: auto; transform: none;
    border-radius: 14px 14px 0 0;
  }
  /* Y el contador sale de la barra. Meterlo dentro funciona en escritorio porque ahí el
     centro está vacío; a 375 px los botones ocupan todo el ancho y la píldora caía JUSTO
     encima de «Aprobar». Arriba de la barra sobra sitio: el lienzo móvil es pequeño y deja
     hueco por debajo (eso es TEC-338, no esto). */
  .pd-viewport:has(.pd-slide-resp:not(.ro)) .pd-barra {
    bottom: calc(var(--pd-hueco-barra, 0px) + 10px);
  }

  /* Los dos estados nuevos envuelven en móvil y reservan otra cosa que en escritorio.
   *
   * A 375 px el bloque de la ronda anterior ocupa dos líneas y el tercer botón baja a su
   * propia fila. Medido aquí: 96 px con la barra bloqueada y 176 px con los cambios
   * abiertos, contra los 60/116 que basta reservar a partir de 861. Reservar de menos no
   * encoge la barra —crece igual—: se lo come a la diapositiva, y de paso deja al contador
   * (que se coloca desde esta misma variable) aterrizando dentro de la barra otra vez. */
  /* Lo que la barra mide DE VERDAD en un teléfono, que no es lo que reserva escritorio.
   *
   * El bloque de arriba da por hecho que a ancho completo la barra entra en una fila y
   * reserva 60 px. No entra: medido a 375 px son 96 px sin responder y 103 px con una nota
   * corta, porque el separador flexible empuja los botones a su propia línea. Llevaba
   * tapando ~36 px de diapositiva en todo enlace de lienzo abierto desde el móvil, y
   * dejando el contador encima de «Aprobar» — que es de donde salió la regla de subirlo.
   *
   * Reservar de menos no encoge la barra: crece igual y se lo come a la diapositiva. */
  .pd-viewport:has(.pd-slide-resp:not(.ro)) { --pd-hueco-barra: 106px; }
  .pd-viewport:has(.pd-slide-resp.bloqueada) { --pd-hueco-barra: 100px; }
  .pd-viewport:has(.pd-slide-resp.con-previos) { --pd-hueco-barra: 194px; }

  /* Y el rótulo se pone ENCIMA de la nota en vez de al lado.
     «Pediste en el enlace anterior» mide 22 caracteres: en una fila de 375 px dejaba a la
     nota una columna de siete, y el comentario del cliente —lo único por lo que se abre
     este bloque— salía partido en cuatro líneas dentro de un canalón. */
  .pd-previos { flex-direction: column; align-items: stretch; gap: 3px; }
  .pd-previos-nota { max-height: 52px; }
}

.pd-slide-resp.panel { flex-direction: column; align-items: stretch; gap: 8px; }
.pd-slide-resp-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.pd-slide-resp-row .pd-nota { flex: 1; margin: 0; min-width: 200px; }
.pd-slide-resp-hint { flex: 1; font-size: 12px; color: var(--pd-muted); }
.pd-lapiz.on { border-color: var(--pd-accent); color: var(--pd-accent); }

/* El badge de solo lectura de la vista previa del equipo.
   Anula el centrado de la barra pública: aquí flota en la esquina y no ocupa el ancho. */
.pd-slide-resp.ro {
  right: 12px; bottom: 12px; left: auto; width: auto; transform: none;
  display: flex; align-items: flex-start; gap: 10px; max-width: 62%;
  border-radius: 16px; padding: 8px 14px;
}

/* La nota del cliente, ENTERA, en la vista previa del equipo.
   Solo aquí: el `.ro` lo emite `barraSoloLecturaHtml`, que únicamente corre cuando NO hay
   `slideResponder` — o sea, nunca en el enlace del cliente. En la barra pública la nota
   sigue recortada a una línea, y ahora por una razón distinta a la de TEC-337: el hueco
   reservado es un número fijo (`--pd-hueco-barra`), así que una barra que creciera con el
   texto volvería a comerse la diapositiva. El cliente no pierde nada — «Editar comentario»
   le abre su propio texto completo en el textarea. */
.pd-slide-resp.ro .pd-slide-resp-nota {
  white-space: pre-wrap; overflow-wrap: anywhere; max-width: none;
  overflow: auto; max-height: 24vh; line-height: 1.5;
}
