/* Compact editor workspace: three rails — structure | text | suggestions. */
:root {
  /* Acento = azul de marca arText. El cromo del editor (cabecera, cabeceras de
     panel, lienzo) toma el color; el folio blanco destaca encima. */
  --insp-primary:#006fc0; --insp-line:#e4e8f0; --insp-line-2:#eef1f6; --insp-muted:#6b7688; --insp-ink:#1a2030; --insp-surface-2:#f5f7fb;
  --ed-accent:#006fc0; --ed-accent-dark:#005596; --ed-chrome:#006fc0; --ed-chrome-dark:#00558f;
  --ed-ctx:#7c3aed; --ed-ctx-wash:#f3efff; --ed-rail-head:#eef4fb; --ed-rail-line:#dbe7f4; --ed-active-bg:#eaf3fc;
}

/* Este fichero es el unico dueno de la reticula del editor: las reglas rivales
   se retiraron de analytics.css, asi que aqui no hace falta pelear
   especificidad. El orden estructurar → escribir → revisar viene del arText
   original: el layout es el modelo mental. */
/* El carril de aplicación azul (52px) es la primera columna SIEMPRE: es la
   navegación del flujo (nuevo/editor/informe) y la única superficie de color
   pleno del rediseño «Cinta de marca». */
.public-editor-shell { position:relative; display:grid; grid-template-columns:var(--appnav-w) 1fr; grid-template-areas:"appnav editor"; gap:12px; width:100%; min-height:calc(100vh - 96px); }
.public-editor-shell .editor-main-panel { grid-area:editor; min-width:0; }
.editor-appnav { grid-area:appnav; }
.editor-structure-rail { grid-area:structure; }
.editor-suggestions-rail { grid-area:suggestions; }

@media (min-width: 1280px) {
  /* Ancho de carril redimensionable: variable CSS con el mismo valor por
     defecto que antes; el arrastre del separador solo cambia la variable
     (ver [data-rail-resizer] en public_editor.js), la retícula la sigue. */
  .public-editor-shell.is-structure-open { grid-template-columns:var(--appnav-w) clamp(240px,var(--rail-structure-w,290px),560px) minmax(0,1fr); grid-template-areas:"appnav structure editor"; }
  .public-editor-shell.is-suggestions-open { grid-template-columns:var(--appnav-w) minmax(0,1fr) clamp(240px,var(--rail-suggestions-w,384px),560px); grid-template-areas:"appnav editor suggestions"; }
  .public-editor-shell.is-structure-open.is-suggestions-open { grid-template-columns:var(--appnav-w) clamp(240px,var(--rail-structure-w,290px),560px) minmax(0,1fr) clamp(240px,var(--rail-suggestions-w,384px),560px); grid-template-areas:"appnav structure editor suggestions"; }
  /* top = barra de 64px + 16px de aire: la pagina se desplaza como documento,
     asi que sin offset el carril se metería bajo la barra pegajosa. Altura fija
     y scroll propio, como los carriles del arText original. */
  .editor-rail { position:sticky; top:80px; align-self:start; height:calc(100vh - 96px); }
  .editor-appnav { position:sticky; top:80px; align-self:start; height:calc(100vh - 96px); }
}

/* ---- carriles ---- */
/* Sin position propio aquí: el carril ya llega posicionado (sticky en
   escritorio, fixed en el cajón estrecho) desde las reglas de breakpoint más
   arriba y más abajo en este fichero; ambos valores sirven igual de bien de
   contenedor de posicionamiento para el separador de redimensionado. */
.editor-rail { display:flex; flex-direction:column; min-height:0; background:#fff; border:1px solid var(--insp-line); border-radius:12px; overflow:hidden; }
.public-editor-shell:not(.is-structure-open) .editor-structure-rail,
.public-editor-shell:not(.is-suggestions-open) .editor-suggestions-rail { display:none; }
.editor-rail > .editor-structure-panel,
.editor-rail > .editor-suggestions-panel { flex:1; min-height:0; display:flex; flex-direction:column; }

/* Separador de redimensionado (tipo LibreOffice): vive en el borde interior
   del carril, dentro de su caja (nunca a caballo, el carril recorta con
   overflow:hidden). El hilo visible es una franja de 2px centrada; el resto
   del área de 9px es solo zona de agarre, más fácil de acertar con el ratón. */
.rail-resizer {
  position:absolute; top:0; bottom:0; width:9px; z-index:20;
  background:transparent; border:0; padding:0; margin:0; cursor:col-resize; touch-action:none;
}
.rail-resizer::after {
  content:""; position:absolute; top:0; bottom:0; left:50%; width:2px;
  background:transparent; transform:translateX(-50%); border-radius:2px; transition:background .12s ease;
}
.editor-structure-rail > .rail-resizer { right:0; }
.editor-suggestions-rail > .rail-resizer { left:0; }
.rail-resizer:hover::after, .rail-resizer:focus-visible::after { background:var(--ed-rail-line); }
.rail-resizer.is-dragging::after { background:var(--ed-accent); width:3px; }
.rail-resizer.is-collapsing::after { background:#dc2626; }
.rail-resizer:focus-visible { outline:2px solid var(--ed-accent); outline-offset:-2px; border-radius:3px; }
/* Mientras se arrastra, nada de selección de texto ni de interferencia del
   editor rico bajo el puntero (el separador vive fuera del folio, pero el
   drag puede pasar por encima). */
body.is-resizing-rail { cursor:col-resize !important; user-select:none; }
body.is-resizing-rail .rich-editor-surface,
body.is-resizing-rail iframe { pointer-events:none; }
@media (max-width: 1279px) {
  /* Cajón estrecho: ancho fijo, sin arrastre. */
  .rail-resizer { display:none; }
}
.editor-rail > .editor-structure-panel { overflow:hidden; }
.editor-suggestions-rail [data-unified-suggestion-panel] { flex:1; min-height:0; }

.rail-head { display:flex; align-items:center; gap:8px; padding:10px 8px 10px 14px; background:var(--ed-rail-head); border-bottom:1px solid var(--ed-rail-line); }
/* El rótulo cede antes que el botón: el carril se puede arrastrar hasta 240px y
   «Analizar claridad» es más largo que el «Analizar texto» de antes. Recortar el
   rótulo mantiene la acción entera y la barra en una sola línea. */
.rail-head-title { display:flex; align-items:center; gap:7px; min-width:0; overflow:hidden; color:var(--ed-accent-dark); font:650 13.5px/1 var(--font-heading, inherit); }
.rail-head-title i, .rail-head-title svg { flex:0 0 auto; width:16px; height:16px; color:var(--insp-primary); }
.rail-head-tools { margin-left:auto; display:flex; align-items:center; gap:2px; }
/* margin-left:auto de .rail-collapse: sigue haciendo falta donde va suelto
   (cabecera de sugerencias, sin .rail-head-tools); dentro del grupo no tiene
   espacio libre que ocupar, así que ahí es un no-op inocuo. */
.rail-collapse { margin-left:auto; }
.rail-collapse, .rail-head-action { display:grid; place-items:center; width:32px; height:32px; border:0; background:transparent; border-radius:9px; color:var(--insp-muted); cursor:pointer; }
.rail-collapse:hover, .rail-head-action:hover { background:var(--insp-surface-2); color:var(--insp-ink); }
.rail-collapse svg, .rail-head-action svg { width:16px; height:16px; }
.rail-head-action:disabled { color:#c7cdd8; cursor:default; pointer-events:none; }

/* Pestanas para devolver un carril cerrado. */
.rail-reopen { position:fixed; z-index:45; top:50%; display:grid; place-items:center; width:34px; height:44px; padding:0; color:var(--insp-muted); background:#fff; border:1px solid var(--insp-line); box-shadow:0 8px 24px rgba(15,23,42,.12); cursor:pointer; transform:translateY(-50%); transition:color .15s ease, background .15s ease; }
.rail-reopen:hover { color:var(--insp-primary); background:var(--insp-surface-2); }
.rail-reopen svg { width:17px; height:17px; }
/* left:52px: a la izquierda vive el carril de aplicación; la pestaña asoma
   pegada a su borde. */
.rail-reopen-left { left:var(--appnav-w); border-left:0; border-radius:0 11px 11px 0; }
.rail-reopen-right { right:0; border-right:0; border-radius:11px 0 0 11px; }
.public-editor-shell.is-structure-open .rail-reopen-left,
.public-editor-shell.is-suggestions-open .rail-reopen-right { display:none; }

/* «Analizar texto» vive en la cabecera del panel, con casa fija: la acción
   siempre a la vista (la cabecera es pegajosa) y sin renglón propio que
   apile otra barra. Primario cuando aún no hay informe; con él, se degrada
   a secundario («Volver a analizar», is-secondary). */
.rail-analyze-btn { display:inline-flex; flex:0 0 auto; align-items:center; gap:6px; min-height:30px; padding:0 12px; color:#fff; background:var(--ed-accent); border:1px solid transparent; border-radius:9px; font:650 12px var(--font-heading, inherit); cursor:pointer; box-shadow:0 3px 9px rgba(0,111,192,.25); transition:background .15s ease, box-shadow .15s ease; white-space:nowrap; }
.rail-analyze-btn:hover { background:var(--ed-accent-dark); box-shadow:0 4px 11px rgba(0,85,150,.3); }
.rail-analyze-btn svg { width:14px; height:14px; }
.rail-analyze-btn.is-secondary { color:var(--ed-accent); background:#fff; border-color:var(--insp-line); box-shadow:none; font-weight:600; }
.rail-analyze-btn.is-secondary:hover { background:var(--insp-surface-2, #f5f7fb); box-shadow:none; }
/* Estado de carga: botón deshabilitado y con el icono girando mientras se
   analiza, para que se note que la acción está en marcha. */
.rail-analyze-btn.is-loading, .rail-analyze-btn:disabled { cursor:progress; background:var(--ed-accent-dark); box-shadow:none; opacity:.9; }
.rail-analyze-btn.is-loading svg, .ribbon-btn.is-loading svg { animation:ed-spin .8s linear infinite; }
.ribbon-btn.is-loading { cursor:progress; }
@keyframes ed-spin { to { transform:rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .rail-analyze-btn.is-loading svg, .ribbon-btn.is-loading svg { animation:none; } }

/* El género rotula el panel de estructura (es su plantilla), con el acceso a
   cambiarlo al lado. */
.rail-genre { display:flex; flex:0 0 auto; align-items:center; gap:8px; padding:9px 10px 9px 14px; border-bottom:1px solid var(--insp-line-2); }
.rail-genre-id { display:flex; min-width:0; flex:1; flex-direction:column; gap:1px; overflow:hidden; }
.rail-genre-id strong { min-width:0; color:var(--insp-ink); font:700 13.5px/1.25 var(--font-heading, inherit); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.rail-genre-id small { min-width:0; color:var(--insp-muted); font-size:10.5px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.rail-genre-change { display:inline-flex; flex:0 0 auto; align-items:center; gap:5px; min-height:28px; padding:3px 8px; color:var(--insp-primary); background:transparent; border:0; border-radius:7px; font:600 11.5px var(--font-heading, inherit); cursor:pointer; }
.rail-genre-change:hover { background:var(--insp-surface-2); }
.rail-genre-change svg { width:13px; height:13px; }

/* Los paneles ya no llevan chapa propia: la pone el carril. */
.editor-structure-panel { padding:0; border:0; border-radius:0; box-shadow:none; background:transparent; }
/* El carril de sugerencias desplaza como un todo: al bajar por la lista, la
   cabecera del documento y «Analizar» se van, y la fila de control con los
   chips se queda pegada arriba (`.sg-sticky` del panel compartido). */
.editor-suggestions-panel { display:flex; flex-direction:column; min-height:0; gap:0; padding:0; border:0; border-radius:0; box-shadow:none; background:transparent; overflow-y:auto; overflow-x:hidden; overscroll-behavior:contain; }
.editor-suggestions-panel > .rail-head,
.editor-suggestions-panel > .editor-report-status { flex:0 0 auto; }
/* La cabecera acompaña: pegajosa sobre el desplazamiento del panel, para que
   «Analizar / Volver a analizar» no se vaya con el scroll. */
.editor-suggestions-panel > .rail-head { position:sticky; top:0; z-index:6; }
/* Pie del panel: el ciclo del análisis termina donde nace. «Ver el informe»
   y su PDF viven bajo las recomendaciones que los producen, pegados al borde
   inferior, y nacen apagados con el mismo contrato que la pastilla del
   carril: existir ya enseña que el informe está a un análisis de distancia. */
.rail-report-foot { position:sticky; bottom:0; display:flex; flex:0 0 auto; gap:8px; margin-top:auto; padding:9px 10px; background:var(--ed-rail-head, #fff); border-top:1px solid var(--insp-line-2); }
.rail-report-open, .rail-report-pdf { display:inline-flex; align-items:center; justify-content:center; gap:7px; flex:1; min-height:32px; padding:0 10px; border:1px solid var(--insp-line); border-radius:9px; background:#fff; color:var(--ed-accent); font:600 12px/1.2 var(--font-heading, inherit); text-decoration:none; cursor:pointer; }
.rail-report-open:hover, .rail-report-pdf:hover { background:var(--ed-active-bg); border-color:var(--ed-accent); }
.rail-report-open svg, .rail-report-pdf svg { flex:0 0 auto; width:14px; height:14px; }
/* Apagado pero no mudo: sin pointer-events:none, el clic llega y abre el
   aviso de openReportGate (por qué no hay informe y cómo tenerlo). */
.rail-report-open[aria-disabled="true"], .rail-report-pdf.is-disabled { color:var(--insp-muted); background:transparent; border-color:var(--insp-line-2); cursor:default; opacity:.75; }
.rail-report-open[aria-disabled="true"]:hover, .rail-report-pdf.is-disabled:hover { background:transparent; border-color:var(--insp-line-2); }
.rail-report-open span, .rail-report-pdf span { min-width:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
/* `overflow:visible` es imprescindible: con un antecesor recortado, el bloque
   pegajoso se ancla a esa caja (que no desplaza) y nunca se queda arriba. */
.editor-suggestions-panel > [data-unified-suggestion-panel] { display:block; flex:0 0 auto; height:auto; min-height:0; overflow:visible; }
.editor-suggestions-panel .sg-panel .sg-list { flex:none; overflow:visible; }

/* ---- structure tree ---- */
.structure-head { padding:12px 13px 11px; }
.structure-head-actions { display:flex; align-items:center; justify-content:space-between; gap:8px; }
.structure-head h1 { margin:8px 0 1px; font-size:14.5px; }
.structure-head p { margin:0; font-size:11px; color:var(--insp-muted); }
.structure-head .back-link { display:inline-flex; align-items:center; gap:5px; min-height:28px; padding:3px 5px; font-size:11.5px; color:var(--insp-muted); text-decoration:none; }
.structure-head .back-link:hover { color:var(--insp-ink); }
/* Velo global de arrastre: subir es soltar sobre el editor. */
.editor-dropveil { position:fixed; inset:10px; z-index:140; display:flex; align-items:center; justify-content:center; border:3px dashed var(--ed-accent); border-radius:18px; background:color-mix(in srgb, var(--ed-active-bg) 88%, transparent); pointer-events:none; }
.editor-dropveil[hidden] { display:none; }
.editor-dropveil-inner { text-align:center; color:var(--ed-accent-dark); }
.editor-dropveil-inner svg { width:40px; height:40px; margin-bottom:8px; }
.editor-dropveil-inner strong { display:block; font-size:18px; font-weight:800; }
.editor-dropveil-inner p { margin:4px 0 0; font-size:13px; color:var(--insp-muted); }
/* Línea de ayuda: qué hace este panel, como el «Estructura y contenidos» del
   sistema anterior. */
.structure-intro { margin:0; padding:9px 14px 11px; color:var(--insp-muted); font:400 12.5px/1.55 var(--font-body); border-bottom:1px solid var(--insp-line-2); }

.structure-tree { min-height:0; flex:1; overflow:auto; overscroll-behavior:contain; scrollbar-gutter:stable; padding:0; display:flex; flex-direction:column; gap:0; }

/* Árbol en tres niveles, como un explorador de ficheros / árbol de IDE:
   indentación limpia con guías finas (línea vertical de 1px por nivel),
   filas compactas, SIN caja ni lámina rellena por ítem — el activo se marca
   con un acento fino (barra o borde de color) más un tinte muy sutil, nunca
   un bloque grande. Ritmo vertical apretado en los tres niveles.
   1 · Apartado: fila de una lista desplegable, separada por líneas.
   2 · Contenido: fila con barra de acento a la izquierda (gris → azul al
       activarse), colgada de la guía de indentación del apartado.
   3 · Fraseología: lista plana colgada de su propia guía; el resalte es del
       renglón pulsado, no de todo el bloque. */
.structure-tree-section { flex:0 0 auto; background:transparent; border:0; border-bottom:1px solid var(--ed-rail-line); border-radius:0; overflow:visible; }
.structure-tree-section:last-child { border-bottom:0; }
/* El apartado activo se marca con un lomo de color y el título en azul, NADA
   más: la banda tintada a todo lo ancho llenaba el panel de láminas y era lo
   que más se alejaba del diseño aprobado. */
.structure-tree-section.is-active > .structure-tree-row { background:transparent; box-shadow:inset 3px 0 0 var(--ed-accent); }
.structure-tree-row { display:flex; align-items:center; }
.structure-tree-toggle { flex:1; min-width:0; display:flex; align-items:center; gap:8px; padding:8px 4px 8px 11px; color:var(--insp-ink); text-align:left; background:transparent; border:0; cursor:pointer; transition:background .12s ease; }
.structure-tree-toggle:hover { background:rgba(0,111,192,.06); }
.structure-tree-section.is-active > .structure-tree-row .structure-tree-toggle:hover,
.structure-tree-content.is-active > .structure-tree-row .structure-tree-toggle:hover { background:transparent; }
.structure-tree-toggle > svg { flex:0 0 auto; width:14px; height:14px; color:#9aa7b8; transition:transform .18s ease, color .15s ease; }
/* Hoja del árbol: lo que no tiene nada dentro no lleva galón, pero conserva
   su hueco para que los rótulos sigan alineados en columna. */
.structure-tree-leaf { flex:0 0 auto; width:14px; }
.structure-tree-row.content-row .structure-tree-leaf { width:12px; }
.structure-tree-section.is-active > .structure-tree-row .structure-tree-toggle > svg,
.structure-tree-content.is-active > .structure-tree-row .structure-tree-toggle > svg { transform:rotate(90deg); color:var(--ed-accent); }
/* :not(.structure-tree-leaf) — imprescindible. Esta regla viste el ENVOLTORIO
   del rótulo, pero como selector de hijo directo también capturaba el hueco de
   las ramas sin hijos (que es otro span) y le daba flex:1: el hueco se comía
   el ancho de la fila y empujaba el texto contra el borde derecho. */
.structure-tree-toggle > span:not(.structure-tree-leaf) { display:flex; min-width:0; flex:1; align-items:center; justify-content:space-between; gap:8px; }
.structure-tree-toggle strong { min-width:0; overflow-wrap:anywhere; font:700 13.5px/1.35 var(--font-heading); white-space:normal; }
.structure-tree-section.is-active .structure-tree-toggle strong { color:var(--ed-accent-dark); }
/* El apartado ya no lleva contador: el número de contenidos no le decía nada
   a quien escribe (equipo lingüístico, 2026-07-31). Lo único que queda en esta
   posición es el multiplicador de un contenido que se repite («3×»). */
.structure-tree-toggle small { flex:0 0 auto; padding:0; color:var(--insp-muted); font:700 10.5px/1 var(--font-body); text-align:right; background:transparent; }
/* El estado normal no necesita etiqueta: todos los apartados se distribuyen
   automáticamente. «Sin ubicar» solo aparece después de quitarlos de forma
   explícita desde el bocadillo lateral. */
.structure-anchor-state { display:inline-flex; align-items:center; gap:4px; font-weight:600 !important; }
.structure-anchor-state[hidden] { display:none !important; }
.structure-anchor-state::before { content:""; width:6px; height:6px; border-radius:50%; background:#a8b3c1; }
.structure-anchor-pin { flex:0 0 auto; display:grid; place-items:center; width:28px; height:28px; margin-right:6px; padding:0; color:#7c8999; background:transparent; border:0; border-radius:7px; opacity:0; pointer-events:none; cursor:pointer; transition:opacity .12s ease, color .12s ease, background .12s ease; }
.structure-anchor-pin:focus-visible,
.structure-tree-section.is-unplaced .structure-anchor-pin { opacity:1; pointer-events:auto; }
.structure-anchor-pin:hover { color:var(--ed-accent); background:var(--ed-active-bg); }
.structure-anchor-pin svg { width:14px; height:14px; }
.structure-guides-toggle[aria-pressed="false"] { color:#9aa7b8; }
.structure-guides-toggle[aria-pressed="true"] { color:var(--ed-accent); background:color-mix(in srgb, var(--ed-active-bg) 72%, transparent); }
/* Insertar (+): solo al posar el cursor sobre SU fila. Dejarlo fijo en las
   filas activas llenaba el panel de cruces grandes permanentes. */
.structure-insert-action { flex:0 0 auto; display:grid; place-items:center; width:24px; height:24px; margin-right:8px; color:var(--ed-accent); background:transparent; border:0; border-radius:6px; opacity:0; pointer-events:none; cursor:pointer; transition:opacity .12s ease, background .12s ease; }
.structure-tree-row:hover .structure-insert-action { opacity:1; pointer-events:auto; }
.structure-insert-action:focus-visible { opacity:1; pointer-events:auto; }
.structure-insert-action:hover { background:var(--ed-active-bg); }
.structure-insert-action svg { width:13px; height:13px; }

/* Desplegado animado, como el editor anterior: el contenedor pasa de 0fr a 1fr
   y el .acc-inner (overflow:hidden) recorta el contenido mientras crece. */
.structure-tree-contents, .structure-tree-phrases { display:grid; grid-template-rows:0fr; transition:grid-template-rows .2s ease; }
.structure-tree-contents.is-open, .structure-tree-phrases.is-open { grid-template-rows:1fr; }
.structure-tree-contents > .acc-inner, .structure-tree-phrases > .acc-inner { display:flex; flex-direction:column; min-height:0; overflow:hidden; }
@media (prefers-reduced-motion: reduce) { .structure-tree-contents, .structure-tree-phrases { transition:none; } }
/* Contenidos (nivel 2): SIN lámina ni tarjeta — el envoltorio solo aporta una
   guía de indentación fina (border-left de 1px) heredera de la fila del
   apartado, como el conector de un árbol de fichero. El resaltado de fila
   (hover/activo) es a sangre, igual que en el apartado (nivel 1): un tinte de
   fondo a todo el ancho de la fila y una franja fina en el borde, no una
   tarjeta separada con su propio margen y borde de color. Plegado no deja
   hilo visible: a 0fr colapsa a 0 (recortado por overflow:hidden), el respiro
   lo dan los márgenes de los propios ítems. */
/* Sin guías verticales: la jerarquía la da la sangría, como en el diseño
   aprobado. Las líneas de árbol de IDE añadían ruido en un panel de tres
   niveles cortos. */
/* Los contenidos son una INDICACIÓN de qué va en ese apartado, no ítems que
   se insertan: en el arText original vivían dentro de un bloque de aviso
   azul. Aquí eso se traduce en un lavado tenue que enmarca la zona sin
   dibujar una caja, y en texto de peso normal y tono apagado. Lo que sí se
   inserta —la fraseología— vuelve al blanco para despegarse de la
   indicación. */
.structure-tree-contents > .acc-inner { gap:0; padding:2px 0; margin:0; border-left:0; background:#f6fafe; }
.structure-tree-contents > .acc-inner > :last-child { margin-bottom:2px; }
.structure-tree-content { flex:0 0 auto; }
.structure-tree-content .structure-tree-row { border-radius:0; transition:background .12s ease, box-shadow .12s ease; }
.structure-tree-content:hover .structure-tree-row { background:rgba(0,111,192,.045); }
.structure-tree-content.is-active .structure-tree-row { background:transparent; }
.structure-tree-content.is-active .structure-tree-toggle > svg { color:var(--ed-accent); }
.structure-tree-row.content-row .structure-tree-toggle { padding:6px 4px 6px 30px; }
.structure-tree-row.content-row .structure-tree-toggle > svg { width:12px; height:12px; }
.structure-tree-row.content-row .structure-tree-toggle strong { font:400 13px/1.45 var(--font-body); color:var(--insp-muted); }
.structure-tree-content.is-active .structure-tree-toggle strong { color:var(--insp-ink); font-weight:600; }

/* Fraseología (nivel 3): lista plana colgada de su propia guía fina (sin
   lámina tintada ni radio grande); cada frase se inserta al pulsarla y solo
   ESE renglón se resalta al pasar el cursor. */
.structure-tree-phrases > .acc-inner { gap:0; margin:0; padding:0; border-left:0; }
.structure-tree-phrases > .acc-inner > :last-child { margin-bottom:3px; }
/* Las frases se leen como citas insertables: serif itálica, sangradas bajo su
   contenido, con el «+» asomando a la derecha solo al pasar el cursor. */
.structure-tree-phrases .phraseology-btn { display:flex; align-items:flex-start; gap:8px; min-height:0; padding:5px 12px 5px 44px; color:#3b4a5e; font:italic 400 13.5px/1.5 var(--ed-doc-font); text-align:left; background:#fff; border:0; border-radius:0; cursor:pointer; transition:background .12s ease, color .12s ease; }
.structure-tree-phrases .phraseology-btn:hover { color:var(--ed-accent-dark); background:var(--ed-active-bg); }
/* `pre-line`: la fraseología legacy trae saltos con significado (bloques de
   firma, enumeraciones a)/b)) que el importador convierte de `<br>` en `\n`.
   Sin esto el salto se colapsaría y las dos líneas se leerían pegadas. Solo
   preserva los saltos: el resto del espacio en blanco sigue colapsando. */
.structure-tree-phrases .phraseology-btn span { flex:1; min-width:0; white-space:pre-line; }
/* El «+» está SIEMPRE: es lo que distingue una frase insertable de un rótulo
   que solo se lee. Atenuado en reposo para no gritar en una lista larga, a
   plena tinta y en círculo al posar el cursor. */
.structure-tree-phrases .phraseology-btn svg { flex:0 0 auto; width:13px; height:13px; margin-top:4px; color:var(--ed-accent); opacity:.5; border-radius:50%; box-shadow:0 0 0 1px transparent; transition:opacity .12s ease, box-shadow .12s ease; }
.structure-tree-phrases .phraseology-btn:hover svg,
.structure-tree-phrases .phraseology-btn:focus-visible svg { opacity:1; box-shadow:0 0 0 1px currentColor; }

.structure-empty { padding:6px 8px 7px; color:#94a3b8; font:400 11.5px/1.5 var(--font-body); }

/* ---- editor column ----
   .agent-editor-frame / .editor-toolbar / .editor-document-card /
   .rich-editor-surface used to be redeclared here too (pre-"Word-editor"
   compact layout); removed — the "Word-like" editor block below is now the
   only owner of those four, deliberately scoped under [data-public-editor]
   to beat analytics.css's own same-named rules regardless of load order (see
   the note there). .editor-workbar/.editor-analyze-btn are dead (no longer
   in the template) and left alone. */
.document-status-line { position:relative; z-index:1; flex:0 0 auto; align-items:center; min-height:38px; padding:7px 11px; overflow:visible; font-size:11px; line-height:1.35; box-sizing:border-box; }
.document-status-line [data-editor-engine] { flex:0 0 auto; }
.document-status-line [data-editor-dirty] { min-width:0; }
.document-status-line [data-occurrence-count] { flex:0 0 auto; margin-left:auto; }
.rich-editor-content { max-width:740px; font-size:calc(16px * var(--editor-zoom,1)); line-height:1.7; }
/* Texto de ayuda de las zonas de apartado. En TipTap lo pinta la extension
   Placeholder (clase is-empty + data-placeholder); en el respaldo, :empty. En
   ambos es contenido generado por CSS, nunca texto real: el analisis no lo ve. */
.rich-editor-surface .is-empty::before,
.rich-editor-surface [data-placeholder]:empty::before {
  content: attr(data-placeholder);
  display: block;
  height: 0;
  color: #97a5b6;
  font-family: var(--ed-doc-font);
  font-style: italic;
  pointer-events: none;
}
/* Separador punteado sobre cada zona vacia, como el folio del arText original */
.rich-editor-surface p.is-empty[data-section]:not(:first-child),
.rich-editor-surface p[data-section][data-placeholder]:empty:not(:first-child) {
  margin-top: 26px;
  padding-top: 12px;
  border-top: 1px dotted #b7c3d2;
}
/* El estado del análisis es un renglón informativo, no una tarjeta: plano,
   pegado al borde, sin marco propio — deja de leerse como un pegote y de
   sumar caja al apilamiento del panel. Selectores con el panel delante a
   propósito: analytics.css (que carga DESPUÉS de este fichero) trae la
   versión tarjeta del analizador y hay que ganarle por especificidad. */
.editor-suggestions-panel > .editor-report-status { flex:0 0 auto; display:flex; align-items:flex-start; gap:9px; margin:0; padding:9px 14px; background:transparent; border:0; border-bottom:1px solid var(--insp-line-2); border-radius:0; }
.editor-suggestions-panel > .editor-report-status > svg { flex:0 0 auto; width:15px; height:15px; margin-top:1px; color:var(--ed-accent); }
/* Título y texto en un renglón corrido («Revisión en curso — las
   recomendaciones…»), no en columnas: informa de pasada, como una línea de
   estado, sin partir el título en tres líneas. */
.editor-suggestions-panel > .editor-report-status > div { display:block; min-width:0; flex:1; font-size:11.5px; line-height:1.5; }
.editor-suggestions-panel > .editor-report-status h3 { display:inline; margin:0 5px 0 0; font-size:12px; font-weight:700; color:var(--insp-ink); }
.editor-suggestions-panel > .editor-report-status p { display:inline; margin:0; font-size:11.5px; color:var(--insp-muted); }
/* ---- estrecho: cada carril pasa a ser un cajon sobre el texto ---- */
@media (max-width: 1279px) {
  /* El carril de aplicación se ancla fijo a la izquierda y el shell le hace
     hueco: sigue siendo la navegación aunque los carriles sean cajones. */
  .public-editor-shell { display:block; min-height:0; padding-left:var(--appnav-w); }
  /* Especificidad a propósito (.public-editor-shell delante): la regla base
     de .editor-appnav vive MÁS ABAJO en este fichero (bloque «Word-like»,
     añadido al final) con position:relative y la misma especificidad, así
     que ganaba por orden de origen y dejaba el carril en el flujo: por
     debajo de 1280px se apilaba sobre el contenido en vez de quedarse
     pegado, y en móvil pisaba el panel de estructura. */
  .public-editor-shell .editor-appnav { position:fixed; z-index:70; top:0; left:0; bottom:0; }
  .editor-main-panel { width:100%; }
  .editor-rail { position:fixed; z-index:60; top:72px; bottom:0; width:min(384px,calc(100vw - 74px)); max-height:none; transition:opacity .18s ease, transform .18s ease; }
  /* El carril cerrado se aparta; ocultarlo con display:none impediria animar. */
  .public-editor-shell:not(.is-structure-open) .editor-structure-rail,
  .public-editor-shell:not(.is-suggestions-open) .editor-suggestions-rail { display:flex; opacity:0; pointer-events:none; }
  .editor-structure-rail { left:var(--appnav-w); border-radius:0 12px 12px 0; transform:translateX(calc(-105% - var(--appnav-w))); }
  .editor-suggestions-rail { right:0; border-radius:12px 0 0 12px; transform:translateX(105%); }
  .public-editor-shell.is-structure-open .editor-structure-rail,
  .public-editor-shell.is-suggestions-open .editor-suggestions-rail { opacity:1; pointer-events:auto; transform:none; }
}

/* Las reglas de móvil (≤768px) viven todas juntas al final del fichero, en el
   bloque «modo móvil». Antes había dos capas sueltas a 700px que ya no
   existen: había tres anchuras de corte (1279 / 760 / 700) para el mismo
   propósito y las reglas de folio que declaraban se perdían igualmente
   contra analytics.css por orden de carga. */

/* =====================================================================
   El editor es una aplicacion: la cabecera y el pie del sitio se apartan y
   el editor se queda con la ventana. Se detecta con :has sobre el shell del
   editor, no con una clase de body: la navegacion htmx (hx-boost) intercambia
   el contenido pero no los atributos del body, y una clase se quedaria pegada
   al salir del editor, dejando el menu del sitio oculto.
   ===================================================================== */
body:has([data-public-editor]) .topbar,
body:has([data-public-editor]) .site-footer { display:none; }
body:has([data-public-editor]) .shell { max-width:none; padding:0; }
body:has([data-public-editor]) .public-editor-shell { gap:0; min-height:100vh; }
body:has([data-public-editor]) .editor-rail { border-radius:0; border-top:0; border-bottom:0; }
body:has([data-public-editor]) .editor-structure-rail { border-left:0; }
body:has([data-public-editor]) .editor-suggestions-rail { border-right:0; }
body:has([data-public-editor]) .agent-editor-frame { height:100vh; min-height:100vh; border-radius:0; border-top:0; border-bottom:0; }

@media (min-width: 1280px) {
  body:has([data-public-editor]) .editor-rail { position:sticky; top:0; height:100vh; }
  body:has([data-public-editor]) .editor-appnav { position:sticky; top:0; height:100vh; }
}

@media (max-width: 1279px) {
  body:has([data-public-editor]) .editor-rail { top:0; }
}

/* ---- carril de aplicación: azul de marca ----
   La única superficie de color pleno. Acción ≠ navegación: «Nuevo…» es un
   círculo con + (abre diálogo); los destinos (Editor, y en el futuro el
   Informe) son pastillas cuadradas con activo en blanco. Ayuda y salir viven
   abajo del todo. */
/* Ancho en reposo y desplegado. El carril NO empuja la retícula al crecer:
   la columna sigue midiendo --appnav-w y el carril se superpone al contenido
   (de ahí el z-index y la sombra), porque desplazar el folio al pasar el
   ratón por el borde de la pantalla sería insufrible. */
/* Ancho del carril: lo lee la retícula, el propio carril y las posiciones
   fijas del modo estrecho. Vive en el shell para poder estrecharlo en móvil. */
.public-editor-shell { --appnav-w:52px; --appnav-w-open:212px; }
.editor-appnav {
  position:relative; z-index:70; box-sizing:border-box;
  display:flex; flex-direction:column; align-items:stretch; gap:4px;
  width:var(--appnav-w); padding:10px 7px 12px; overflow:hidden;
  background:linear-gradient(180deg, #0a4d8c 0%, var(--ed-chrome) 55%, var(--ed-chrome-dark) 100%);
  transition:width .2s cubic-bezier(.2,.7,.3,1), box-shadow .2s ease;
}
/* Solo con puntero fino: en táctil no hay «pasar el cursor», y un carril que
   se quedara abierto tras el toque taparía el folio sin manera de cerrarlo. */
@media (hover: hover) and (pointer: fine) {
  .editor-appnav:hover { width:var(--appnav-w-open); box-shadow:8px 0 26px rgba(6,40,70,.24); }
}
/* Fila: el icono ocupa una caja fija de 38px centrada en el ancho de reposo
   (7px de padding + 19 = 26 = mitad de 52), así nada se mueve al desplegar;
   el rótulo entra a continuación y el recorte del carril lo tapa en reposo. */
.appnav-logo, .appnav-btn {
  display:flex; align-items:center; gap:10px; flex:0 0 auto;
  height:38px; padding:0; border:0; border-radius:11px;
  color:rgba(255,255,255,.78); background:transparent;
  text-decoration:none; cursor:pointer; white-space:nowrap;
  transition:background .15s ease, color .15s ease;
}
.appnav-btn > svg, .appnav-btn > i { flex:0 0 auto; width:38px; height:17px; }
.appnav-btn > svg { width:17px; height:17px; margin:0 10.5px; }
.appnav-logo { height:34px; margin-bottom:6px; color:#fff; }
.appnav-logo-mark { flex:0 0 auto; display:grid; place-items:center; width:34px; height:34px; margin:0 2px; color:var(--ed-accent); background:#fff; border-radius:10px; font:800 14px/1 var(--font-heading, inherit); }
.appnav-logo .appnav-label { font-weight:800; font-size:15px; letter-spacing:-.01em; }
.appnav-logo:hover .appnav-label { text-decoration:underline; }
/* El rótulo vive siempre en el marcado (teclado y lectores de pantalla lo
   necesitan); lo que se anima es su visibilidad. */
.appnav-label { min-width:0; font:600 13px/1 var(--font-heading, inherit); opacity:0; transform:translateX(-6px); transition:opacity .16s ease, transform .2s ease; }
.editor-appnav:hover .appnav-label { opacity:1; transform:none; }
.appnav-btn:hover { color:#fff; background:rgba(255,255,255,.14); }
.appnav-btn[aria-pressed="true"] { color:#fff; background:rgba(255,255,255,.20); }
.appnav-view[aria-current="true"] { color:var(--ed-accent); background:#fff; box-shadow:0 2px 8px rgba(6,40,70,.28); }
.appnav-sep { flex:0 0 auto; height:1px; margin:5px 7px; background:rgba(255,255,255,.25); }
.appnav-spacer { flex:1; }
@media (prefers-reduced-motion: reduce) {
  .editor-appnav, .appnav-label { transition:none; }
}
/* Destino todavía inalcanzable (el informe antes del primer análisis): se ve
   pero no invita. Nada de ocultarlo — que exista enseña que el informe está
   ahí, a un análisis de distancia. Y desde 2026-07-31, apagado no es mudo:
   va con aria-disabled (no disabled) para que el clic llegue y el aviso de
   openReportGate explique qué falta. */
.appnav-btn[disabled], .appnav-btn[aria-disabled="true"] { opacity:.42; cursor:default; }
.appnav-btn[disabled]:hover, .appnav-btn[aria-disabled="true"]:hover { color:rgba(255,255,255,.78); background:transparent; }

/* =====================================================================
   VISTA «INFORME DE CLARIDAD»
   Segunda vista del área principal, hermana del editor en la retícula: el
   shell lleva data-editor-view y aquí se decide cuál de las dos ocupa la
   pantalla. El informe se lee a todo lo ancho — sin carriles: ni estructura
   ni recomendaciones tienen nada que decir sobre un PDF ya generado.
   ===================================================================== */
.editor-report-view { grid-area:report; display:none; flex-direction:column; min-width:0; min-height:100vh; background:var(--insp-surface-2); }
.public-editor-shell[data-editor-view="informe"] .editor-report-view { display:flex; }
.public-editor-shell[data-editor-view="informe"] .editor-main-panel,
.public-editor-shell[data-editor-view="informe"] .editor-rail,
.public-editor-shell[data-editor-view="informe"] .rail-reopen,
.public-editor-shell[data-editor-view="informe"] .editor-appnav [data-rail-toggle] { display:none; }
/* La columna de contenido es una sola en la vista de informe. Los selectores
   repiten las clases de apertura de carril porque las reglas de la retícula
   (arriba) las llevan: sin igualar su especificidad, la vista de informe
   heredaría columnas para carriles que ya no se pintan. */
.public-editor-shell.is-structure-open.is-suggestions-open[data-editor-view="informe"],
.public-editor-shell.is-structure-open[data-editor-view="informe"],
.public-editor-shell.is-suggestions-open[data-editor-view="informe"],
.public-editor-shell[data-editor-view="informe"] { grid-template-columns:var(--appnav-w) minmax(0,1fr); grid-template-areas:"appnav report"; }

.report-view-head { display:flex; align-items:center; gap:14px; padding:12px 18px; background:#fff; border-bottom:1px solid var(--insp-line); }
.report-view-id { display:flex; flex-direction:column; min-width:0; }
.report-view-id strong { font-size:14px; color:var(--insp-ink); }
.report-view-id small { font-size:11.5px; color:var(--insp-muted); }
/* Descargar el PDF es LA acción de esta vista: el informe se lee aquí y se
   guarda ahí. Va con cuerpo de botón principal, no de enlace discreto. */
.report-view-download { display:inline-flex; align-items:center; gap:9px; margin-left:auto; padding:11px 20px; color:#fff; background:var(--ed-accent); border-radius:10px; font-size:14px; font-weight:600; letter-spacing:.01em; text-decoration:none; box-shadow:0 4px 12px rgba(16,40,70,.16); }
.report-view-download:hover { background:var(--ed-accent-dark); }
.report-view-download svg { width:18px; height:18px; }
.report-view-download.is-disabled { color:var(--insp-muted); background:var(--insp-line-2); box-shadow:none; }
.report-view-download.is-disabled:hover { background:var(--insp-line-2); }

/* El cuerpo es el contenedor de desplazamiento: el informe HTML crece hacia
   abajo tanto como haga falta, no se pagina. */
.report-view-body { flex:1; display:flex; flex-direction:column; min-height:0; overflow:auto; padding:22px 16px 40px; }
/* El fragmento del servidor trae su propio ancho y su propia hoja; aquí solo
   se le da sitio. Todo lo que pinta cuelga de .artext-dossier. */
.report-view-doc { width:100%; }
.report-view-doc[hidden] { display:none; }
.report-view-empty { display:flex; flex-direction:column; align-items:center; justify-content:center; gap:8px; flex:1; color:var(--insp-muted); text-align:center; }
.report-view-empty[hidden] { display:none; }
.report-view-empty svg { width:34px; height:34px; opacity:.5; }
.report-view-empty h2 { font-size:15px; color:var(--insp-ink); }
.report-view-empty p { max-width:38ch; font-size:12.5px; }
.report-view-retry { margin-top:6px; padding:8px 15px; color:#fff; background:var(--ed-accent); border:0; border-radius:9px; font-size:12.5px; font-weight:600; cursor:pointer; }
.report-view-retry:hover { background:var(--ed-accent-dark); }

/* =====================================================================
   VISTA «NUEVO DOCUMENTO»
   Tercera vista del área principal, hermana del editor y del informe. Ocupa
   la pantalla porque elegir el género es la decisión que manda sobre todo lo
   demás —estructura, recomendaciones, glosarios— y merece el mismo espacio
   que le da el catálogo de fuera, no un cuadro de 640px.
   Retícula propia con cabecera y pie fijos y un cuerpo que se desplaza: la
   acción no puede quedarse debajo del pliegue cuando hay once géneros
   desplegados.
   ===================================================================== */
.editor-start { grid-area:report; display:none; flex-direction:column; min-width:0; min-height:100vh; max-height:100vh; background:var(--insp-surface-2); }
.public-editor-shell[data-editor-view="nuevo"] .editor-start { display:flex; }
.public-editor-shell[data-editor-view="nuevo"] .editor-main-panel,
.public-editor-shell[data-editor-view="nuevo"] .editor-report-view,
.public-editor-shell[data-editor-view="nuevo"] .editor-rail,
.public-editor-shell[data-editor-view="nuevo"] .rail-reopen,
.public-editor-shell[data-editor-view="nuevo"] .editor-ribbon,
.public-editor-shell[data-editor-view="nuevo"] .editor-appnav [data-rail-toggle] { display:none; }
/* Igual que en la vista de informe: los selectores repiten las clases de
   apertura de carril para empatar en especificidad con las reglas de la
   retícula, que si no dejarían columnas para carriles que ya no se pintan. */
.public-editor-shell.is-structure-open.is-suggestions-open[data-editor-view="nuevo"],
.public-editor-shell.is-structure-open[data-editor-view="nuevo"],
.public-editor-shell.is-suggestions-open[data-editor-view="nuevo"],
.public-editor-shell[data-editor-view="nuevo"] { grid-template-columns:var(--appnav-w) minmax(0,1fr); grid-template-areas:"appnav report"; }

.start-head { display:flex; align-items:flex-start; gap:16px; flex:0 0 auto; padding:22px 26px 18px; background:#fff; border-bottom:1px solid var(--insp-line); }
.start-head-id { flex:1; min-width:0; }
.start-head-id h2 { margin:4px 0 3px; font-size:21px; font-weight:800; color:var(--insp-ink); }
.start-head-id p { margin:0; font-size:13px; color:var(--insp-muted); }
.start-resume { display:inline-flex; align-items:center; gap:7px; flex:0 0 auto; min-height:36px; padding:8px 14px; color:var(--ed-accent-dark); background:var(--ed-active-bg); border:1px solid var(--ed-rail-line); border-radius:9px; font:700 12.5px var(--font-heading, inherit); cursor:pointer; }
.start-resume:hover { background:#fff; }
.start-resume[hidden] { display:none; }
.start-resume svg { width:15px; height:15px; }

.start-body { display:flex; align-items:flex-start; gap:38px; flex:1; min-height:0; overflow:auto; padding:22px 26px 26px; }
.start-main { flex:1; min-width:0; }
.start-main > * { max-width:1040px; }
/* La columna de marca: el mismo logotipo (y claim) de las páginas de
   elección de género, llenando el vacío de la derecha en pantallas grandes.
   Pegajosa para acompañar el desplazamiento del paso 1; por debajo del
   corte, no existe. */
.start-aside { display:none; }
@media (min-width: 1480px) {
  /* Rejilla de una sola celda, no flex: las dos marcas se apilan EN EL MISMO
     sitio para que el relevo sea un cambio de identidad y no un salto de
     maquetación. La altura la fija la más alta de las dos, así que el bloque
     no se mueve al cambiar. */
  .start-aside { position:sticky; top:8vh; display:grid; flex:0 0 clamp(300px, 24vw, 420px); place-items:center; padding:40px 10px; }
}
.start-aside-card { grid-area:1/1; display:flex; flex-direction:column; align-items:center; gap:20px; text-align:center; }
.start-aside-card img { width:min(320px, 90%); height:auto; opacity:.96; }
.start-aside-card p { margin:0; max-width:32ch; color:var(--insp-muted); font:600 14px/1.65 var(--font-heading, inherit); }
/* El relevo: la que sale cae y se desvanece, la que entra sube. Se anima
   porque hay que NOTARLO —es la respuesta a lo que se acaba de pulsar en el
   paso 1—, y la que no toca queda inerte, sin robar el cursor ni el foco. */
.start-aside-card { opacity:0; transform:translateY(14px) scale(.98); pointer-events:none; transition:opacity .34s ease, transform .34s cubic-bezier(.2,.7,.3,1); }
.start-aside[data-start-brand="especializado"] [data-start-brand-card="especializado"],
.start-aside[data-start-brand="claro"] [data-start-brand-card="claro"] { opacity:1; transform:none; pointer-events:auto; }
@media (prefers-reduced-motion: reduce) { .start-aside-card { transition:none; } }
.start-step + .start-step { margin-top:30px; }
.start-step[hidden] { display:none; }
.start-step-label { display:flex; align-items:baseline; flex-wrap:wrap; gap:9px; margin:0 0 13px; }
.start-step-label span { color:var(--insp-ink); font:800 13px var(--font-heading, inherit); letter-spacing:.1em; text-transform:uppercase; }
.start-step-label em { color:var(--insp-muted); font:600 12.5px var(--font-body); font-style:normal; }
/* Los dos grupos del paso 1: los ámbitos especializados en acordeón y el
   lenguaje claro aparte, como en /ambitos-especializados y /lenguaje-claro.
   Mezclarlos aquí contradiría a la web, donde son dos páginas distintas. */
.start-group + .start-group { margin-top:20px; }
.start-group[hidden] { display:none; }
.start-group-title { margin:0 0 9px; color:var(--insp-muted); font:800 10.5px var(--font-heading, inherit); letter-spacing:.1em; text-transform:uppercase; }
/* El acordeón y las tarjetas de género son los de landing.css: aquí solo se
   ajusta lo que cambia de significado. Pulsar YA NO navega —selecciona—, y
   por eso hay estado elegido, y no solo hover. */
.editor-start .field-genre { width:100%; font:inherit; text-align:left; cursor:pointer; }
.editor-start .field-genre.is-chosen { border-color:var(--ed-accent); background:var(--ed-active-bg); box-shadow:0 0 0 1px var(--ed-accent) inset; }
.editor-start .field-genre:focus-visible { outline:2px solid var(--ed-accent); outline-offset:2px; }
.editor-start .field-genre-current { flex:0 0 auto; padding:2px 7px; color:var(--ed-accent-dark); background:var(--ed-active-bg); border-radius:999px; font:800 9.5px var(--font-heading, inherit); letter-spacing:.07em; text-transform:uppercase; }
.editor-start .field-genre.is-chosen .field-genre-current { background:#fff; }

/* El paso «cómo empiezas», con el empaque de una decisión de verdad
   (Guillermo, 2026-07-31: parecía pequeñito al lado del paso 1): tarjetas
   más grandes, icono en azulejo y tipografía a la altura de los acordeones. */
.start-origins { display:grid; grid-template-columns:repeat(auto-fit, minmax(280px, 1fr)); gap:14px; max-width:780px; }
.start-origin { display:flex; align-items:center; gap:15px; padding:20px 22px; text-align:left; background:#fff; border:1.5px solid var(--insp-line); border-radius:14px; cursor:pointer; transition:border-color .15s ease, background .15s ease; }
.start-origin:hover { border-color:var(--ed-accent); background:var(--ed-active-bg); }
.start-origin.is-chosen { border-color:var(--ed-accent); background:var(--ed-active-bg); box-shadow:0 0 0 1px var(--ed-accent) inset; }
.start-origin:focus-visible { outline:2px solid var(--ed-accent); outline-offset:2px; }
.start-origin svg { flex:0 0 auto; width:46px; height:46px; padding:12px; color:var(--ed-accent); background:var(--ed-active-bg); border-radius:12px; }
.start-origin.is-chosen svg { background:#fff; }
.start-origin-text { display:flex; flex-direction:column; gap:4px; min-width:0; }
.start-origin-text strong { font-size:15.5px; font-weight:800; color:var(--insp-ink); }
.start-origin-text small { font-size:12.5px; line-height:1.5; color:var(--insp-muted); }
@media (prefers-reduced-motion: reduce) { .start-origin, .start-dropstrip { transition:none; } }

.start-dropstrip { display:flex; align-items:center; gap:11px; max-width:640px; margin-top:12px; padding:13px; background:#fff; border:1.5px dashed var(--insp-line); border-radius:12px; cursor:pointer; transition:border-color .15s ease, background .15s ease; }
.start-dropstrip[hidden] { display:none; }
.start-dropstrip:hover, .start-dropstrip.is-dragover { border-color:var(--ed-accent); background:var(--ed-active-bg); }
.start-dropstrip:focus-visible { outline:2px solid var(--ed-accent); outline-offset:2px; }
.start-dropstrip-icon { display:grid; place-items:center; flex:0 0 auto; width:34px; height:34px; border-radius:10px; background:var(--ed-rail-head); color:var(--ed-accent); }
.start-dropstrip-icon svg { width:17px; height:17px; }
.start-dropstrip-text { flex:1; min-width:0; display:flex; flex-direction:column; gap:1px; }
.start-dropstrip-text strong { font-size:12.5px; font-weight:700; color:var(--insp-ink); }
.start-dropstrip-text small { font-size:11px; color:var(--insp-muted); }
.start-dropstrip-formats { display:flex; flex:0 0 auto; gap:4px; }
.start-dropstrip-formats span { padding:2px 5px; border:1px solid var(--insp-line); border-radius:5px; color:var(--insp-muted); font-size:9.5px; font-weight:800; letter-spacing:.04em; }
.start-file-chip { display:flex; align-items:center; gap:10px; max-width:640px; margin-top:12px; padding:11px 13px; background:var(--ed-active-bg); border:1px solid var(--ed-rail-line); border-radius:12px; }
.start-file-chip[hidden] { display:none; }
.start-file-chip svg { flex:0 0 auto; width:17px; height:17px; color:var(--ed-accent); }
.start-file-name { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--ed-accent-dark); font-size:12.5px; font-weight:800; }
.start-file-chip small { flex:1; min-width:0; color:var(--insp-muted); font-size:11px; }
.start-file-chip button { display:grid; place-items:center; flex:0 0 auto; width:26px; height:26px; padding:0; border:0; border-radius:7px; background:transparent; color:var(--insp-muted); cursor:pointer; }
.start-file-chip button:hover { background:#fff; color:var(--insp-ink); }
.start-file-chip button svg { width:14px; height:14px; color:currentColor; }

/* Pie: lo que va a pasar, escrito al lado del botón que lo hace. El aviso
   lleva su remedio dentro (descargar antes), porque mandar al usuario a
   buscarlo en otro menú mientras se le avisa de una pérdida es dejarlo solo. */
.start-foot { display:flex; align-items:center; gap:18px; flex:0 0 auto; padding:14px 26px; background:#fff; border-top:1px solid var(--insp-line); }
.start-foot-say { flex:1; min-width:0; display:flex; flex-direction:column; gap:5px; }
.start-summary { margin:0; min-height:17px; font-size:12.5px; color:var(--insp-muted); }
.start-warn { display:flex; align-items:center; gap:8px; margin:0; font-size:12.5px; color:#8a5300; }
.start-warn[hidden] { display:none; }
.start-warn svg { flex:0 0 auto; width:15px; height:15px; }
.start-download { flex:0 0 auto; padding:3px 9px; color:var(--ed-accent-dark); background:transparent; border:1px solid var(--ed-rail-line); border-radius:7px; font:700 11.5px var(--font-heading, inherit); cursor:pointer; }
.start-download:hover { background:var(--ed-active-bg); }
.start-confirm { display:inline-flex; align-items:center; gap:8px; flex:0 0 auto; min-height:40px; padding:10px 20px; color:#fff; background:var(--ed-accent); border:0; border-radius:10px; font:800 13.5px var(--font-heading, inherit); cursor:pointer; }
.start-confirm:hover:not([disabled]) { background:var(--ed-accent-dark); }
.start-confirm[disabled] { color:var(--insp-muted); background:var(--insp-line-2); cursor:default; }
.start-confirm:focus-visible { outline:2px solid var(--ed-accent-dark); outline-offset:2px; }
.start-confirm svg { width:16px; height:16px; }


/* Controles de color: el icono es la etiqueta y el input de color va detras. */
.ribbon-color { position:relative; overflow:hidden; }
.ribbon-color input[type="color"] { position:absolute; inset:0; opacity:0; width:100%; height:100%; padding:0; border:0; cursor:pointer; }

/* =====================================================================
   "Word-like" editor: menu bar + connected toolbar, A4 page on a grey
   canvas, docked agent bar and a bottom status bar. Appended last so it
   wins ties against the earlier compact rules (same file: source order
   settles same-specificity ties). It does NOT automatically win against
   analytics.css: that is a SEPARATE stylesheet loaded AFTER this one (see
   base.html — head_extra, where compact_workspace.css is injected, comes
   before the <link> to analytics.css), so for same-specificity flat-class
   selectors analytics.css's declarations win the tie, not this file's.
   analytics.css still carries its OWN unscoped `.agent-editor-frame` /
   `.editor-toolbar` / `.editor-document-card` rules (a leftover "compact"
   block plus an unrelated admin "editor preview card" rule reusing the
   `.editor-document-card` name) that bleed into this page: they silently
   overrode `align-items:stretch` → `center` (shrinking the appbar/toolbar to
   content width instead of the full width), `min-height:0` → a fixed
   `calc(100vh - 205px)` floor (which stopped the canvas from ever shrinking
   to fit, so it grew with its content instead of scrolling internally — the
   lost page/document scroll), and gave the toolbar a floating rounded card
   look (border + border-radius + shadow + backdrop-filter) instead of the
   flush bar under the appbar. The three root selectors below are scoped
   under `[data-public-editor]` (+1 specificity) so they always win instead
   of depending on load order — do not remove that prefix. */
/* --editor-web-w: anchura de la columna de lectura del «diseño web». No es
   una medida de papel (el A4 son --editor-page-w/h): es el ancho de línea
   cómodo del continuo. Escala con el zoom como el folio. */
:root { --editor-canvas:#dbe3ee; --editor-page-w:794px; --editor-page-h:1123px; --editor-margin:96px; --editor-web-w:760px; --ed-doc-font:Georgia, 'Times New Roman', Times, serif; }

/* Las marcas de revisión ya no son controles inline. Siguen pintando el
   rango que selecciona el panel derecho, pero sobre ellas se edita texto con
   el mismo cursor y el mismo hover que en cualquier otro fragmento. */
[data-public-editor] [data-editor-surface] .text-hit { cursor:text; }
[data-public-editor] [data-editor-surface] .text-hit:hover { filter:none; }

/* editor column becomes a fixed-height flex stack: chrome pinned top,
   canvas scrolls in the middle, agent bar + status bar pinned bottom. */
[data-public-editor] .agent-editor-frame {
  display:flex; flex-direction:column; align-items:stretch; gap:0;
  height:calc(100vh - 96px); min-height:calc(100vh - 96px); padding:0;
}

/* ---- cinta de comandos: pestañas + una fila por pestaña ----
   Sustituye a la barra de menús y a la barra de formato. Es cromo, no panel:
   superficie propia (tinte azulado sutil, distinto del blanco de los
   paneles) y sombra que la despega del contenido. Server-rendered: los
   listeners se cablean una vez (bindActions) y editor_ribbon.js solo alterna
   atributos — nada aquí depende de re-render. */
.editor-ribbon { position:relative; z-index:30; flex:0 0 auto; background:linear-gradient(180deg, #fdfeff 0%, #f2f7fc 100%); border-bottom:1px solid #cddbe8; box-shadow:0 3px 10px rgba(16,42,67,.08); }
.ribbon-tabs { display:flex; align-items:center; gap:2px; height:32px; padding:0 8px 0 12px; }
.ribbon-wordmark { display:inline-flex; align-items:baseline; gap:4px; margin-right:12px; color:var(--ed-accent-dark); font:800 13px/1 var(--font-heading, inherit); letter-spacing:.01em; white-space:nowrap; }
.ribbon-wordmark em { font:600 9px/1 var(--font-heading, inherit); font-style:normal; letter-spacing:.09em; text-transform:uppercase; color:var(--insp-muted); }
.ribbon-tab { flex:0 0 auto; height:32px; padding:0 11px; color:#52697e; background:transparent; border:0; border-bottom:2px solid transparent; font:600 12px var(--font-heading, inherit); cursor:pointer; white-space:nowrap; }
.ribbon-tab:hover { color:var(--ed-accent-dark); }
.ribbon-tab[aria-selected="true"] { color:var(--ed-accent-dark); border-bottom-color:var(--ed-accent); }
/* Plegar la cinta: cromo puro, y el único habitante del extremo derecho de
   la tira. Sin fondo ni contorno —no es una acción sobre el texto, es la
   cinta hablando de sí misma—, y el hueco libre lo abre él (margin-left:auto).
   Es un galón que GIRA: apunta a donde va la cinta. Por eso el botón «Más»
   de la fila de abajo no puede ser otro galón (ver el bloque de
   desbordamiento): allí se abre un cajón, no se pliega nada. */
.ribbon-fold { display:grid; place-items:center; flex:0 0 auto; width:28px; height:28px; margin-left:auto; padding:0; color:var(--insp-muted); background:transparent; border:0; border-radius:7px; cursor:pointer; }
.ribbon-fold:hover { color:var(--ed-accent-dark); background:#eaf3fc; }
.ribbon-fold svg { width:15px; height:15px; transition:transform .18s ease; }
.editor-ribbon.is-folded .ribbon-fold svg { transform:rotate(180deg); }
/* Una sola fila de 44px que cambia con la pestaña; nunca crece en vertical.
   Si no cabe, manda el botón «Más» (ver el bloque de desbordamiento, más
   abajo); el overflow-x de aquí es solo la red por si no hay JavaScript. */
.ribbon-row { display:flex; align-items:center; gap:2px; height:44px; padding:0 8px; border-top:1px solid var(--insp-line-2); flex-wrap:nowrap; overflow-x:auto; scrollbar-width:thin; }
.ribbon-row::-webkit-scrollbar { height:6px; }
.ribbon-row::-webkit-scrollbar-thumb { background:#d3dbe6; border-radius:999px; }
.ribbon-row[hidden] { display:none; }
.editor-ribbon.is-folded .ribbon-row { display:none; }
/* Cambio de pestaña, como en Word: los comandos de la fila entrante no
   aparecen de golpe, suben un par de píxeles y se revelan en cascada de
   izquierda a derecha. El escalón es corto a propósito (12 ms): tiene que
   leerse como un gesto, no como una espera. La animación se dispara sola al
   quitar [hidden], porque display:none la reinicia. */
@keyframes ribbon-reveal { from { opacity:0; transform:translateY(-5px); } to { opacity:1; transform:none; } }
.ribbon-row:not([hidden]) > * { animation:ribbon-reveal .22s cubic-bezier(.2,.7,.3,1) both; }
.ribbon-row > :nth-child(1) { animation-delay:0ms; }
.ribbon-row > :nth-child(2) { animation-delay:12ms; }
.ribbon-row > :nth-child(3) { animation-delay:24ms; }
.ribbon-row > :nth-child(4) { animation-delay:36ms; }
.ribbon-row > :nth-child(5) { animation-delay:48ms; }
.ribbon-row > :nth-child(6) { animation-delay:60ms; }
.ribbon-row > :nth-child(7) { animation-delay:72ms; }
.ribbon-row > :nth-child(8) { animation-delay:84ms; }
.ribbon-row > :nth-child(9) { animation-delay:96ms; }
.ribbon-row > :nth-child(n+10) { animation-delay:108ms; }
/* Al desplegar la cinta plegada, la fila entera entra de una pieza. */
.editor-ribbon:not(.is-folded) .ribbon-row:not([hidden]) { animation:ribbon-reveal .18s ease both; }

/* Desbordamiento de la fila (editor_ribbon.js): con JS la fila no se
   desplaza — se mide, la cola que no cabe se esconde (is-overflowed) y el
   botón «Más» la ofrece en un cajón anclado bajo la cinta. Los comandos
   conservan su clase y por tanto su aspecto: solo cambian de contenedor
   mientras el cajón está abierto. */
.editor-ribbon.has-overflow-chrome .ribbon-row { overflow:hidden; }
.ribbon-row > .is-overflowed { display:none; }
/* «Más»: puntos suspensivos dentro de una pastilla con contorno, pegada al
   borde. Deliberadamente distinto del plegador de la tira, que le queda
   justo encima: aquel es un galón sin contorno que gira, este es un menú
   que se abre. Mismo icono en los dos sitios habría sido la misma promesa
   para dos cosas que no se parecen en nada. */
.ribbon-more { margin-left:auto; min-width:28px; padding:0 6px; color:var(--insp-muted); background:#fff; border:1px solid var(--insp-line); }
.ribbon-more:hover:not([disabled]) { color:var(--ed-accent); background:var(--ed-active-bg); border-color:#bcd6ee; }
.ribbon-more svg { width:16px; height:16px; }
.ribbon-more.is-open { color:#fff; background:var(--ed-accent); border-color:var(--ed-accent); }
.ribbon-overflow { position:absolute; top:100%; right:6px; z-index:55; display:flex; flex-wrap:wrap; align-items:center; gap:2px; max-width:min(480px, calc(100vw - 24px)); padding:6px 8px; background:#fff; border:1px solid var(--insp-line); border-top:0; border-radius:0 0 12px 12px; box-shadow:0 14px 30px rgba(6,40,70,.16); }
.ribbon-overflow[hidden] { display:none; }
/* Los separadores no viajan al cajón: allí la cola se relee como grupo. */
.ribbon-overflow .ribbon-sep { display:none; }

/* Desplegables de la cinta (editor_ribbon.js): «Descargar como» y los que
   vengan. Mismo material que el cajón «Más» —panel blanco colgado del borde
   inferior de la cinta, sin borde superior porque nace pegado a ella, y la
   misma sombra—, pero en columna: cada formato es una fila con su icono, su
   nombre y la explicación que antes vivía escondida en un title. La izquierda
   la pone el JS, alineada con el botón que lo abrió. */
.ribbon-menu { position:absolute; top:100%; left:6px; z-index:56; display:flex; flex-direction:column; gap:2px; min-width:250px; max-width:min(340px, calc(100vw - 24px)); padding:7px; background:#fff; border:1px solid var(--insp-line); border-top:0; border-radius:0 0 12px 12px; box-shadow:0 14px 30px rgba(6,40,70,.16); }
.ribbon-menu[hidden] { display:none; }
/* La cascada de la cinta, otra vez: el menú no aparece de golpe, sus filas
   suben y se revelan de arriba abajo. Se dispara sola al quitar [hidden]. */
.ribbon-menu:not([hidden]) > * { animation:ribbon-reveal .2s cubic-bezier(.2,.7,.3,1) both; }
.ribbon-menu > :nth-child(1) { animation-delay:0ms; }
.ribbon-menu > :nth-child(2) { animation-delay:22ms; }
.ribbon-menu > :nth-child(3) { animation-delay:44ms; }
.ribbon-menu > :nth-child(4) { animation-delay:66ms; }
.ribbon-menu > :nth-child(n+5) { animation-delay:88ms; }
.ribbon-menu-item { display:flex; align-items:center; gap:11px; width:100%; min-height:40px; padding:7px 10px; color:#3f4f61; background:transparent; border:0; border-radius:9px; font:inherit; text-align:left; cursor:pointer; }
.ribbon-menu-item:hover:not([disabled]) { color:var(--ed-accent); background:#eaf3fc; }
.ribbon-menu-item:focus-visible { outline:2px solid var(--ed-accent); outline-offset:-2px; }
.ribbon-menu-item[disabled] { color:#c0c9d6; cursor:default; }
.ribbon-menu-item > svg { flex:0 0 auto; width:18px; height:18px; }
.ribbon-menu-text { display:flex; flex-direction:column; gap:1px; min-width:0; }
.ribbon-menu-text strong { font:700 12.5px/1.25 var(--font-heading, inherit); color:inherit; }
.ribbon-menu-text small { font-size:11px; line-height:1.3; color:var(--insp-muted); }
/* El botón que lo abre: un comando de la cinta con galón. Abierto se queda
   encendido —igual que un comando activo—, para que se vea de dónde cuelga
   el panel; el galón gira, como el del plegador. */
.ribbon-menu-btn .ribbon-menu-caret { width:13px; height:13px; margin-left:1px; color:var(--insp-muted); transition:transform .18s ease; }
.ribbon-menu-btn.is-open { color:var(--ed-accent); background:#dceefe; box-shadow:inset 0 0 0 1px #a9d2f3; }
.ribbon-menu-btn.is-open .ribbon-menu-caret { color:inherit; transform:rotate(180deg); }
@media (prefers-reduced-motion: reduce) {
  .ribbon-menu:not([hidden]) > * { animation:none; }
  .ribbon-menu-btn .ribbon-menu-caret { transition:none; }
}

/* La nota de privacidad de la fila de Archivo: rótulo informativo empujado
   al extremo, con la frase completa en su title. */
.ribbon-note { display:inline-flex; align-items:center; gap:6px; flex:0 0 auto; margin-left:auto; padding:0 6px; color:var(--insp-muted); font:600 11px var(--font-heading, inherit); white-space:nowrap; }
.ribbon-note svg { flex:0 0 auto; width:14px; height:14px; color:var(--ed-accent); }

/* La lista del diálogo de ayuda: filas con el cuerpo de botón de la cinta
   (icono plano de 17px, rótulo semibold, mismo hover). */
.editor-help-dialog .help-links { display:flex; flex-direction:column; gap:2px; }
.fm-item { display:flex; align-items:center; gap:9px; width:100%; padding:7px 9px; border:0; border-radius:8px; background:transparent; color:#3f4f61; font:inherit; text-align:left; text-decoration:none; cursor:pointer; }
.fm-item:hover { color:var(--ed-accent); background:#eaf3fc; }
.fm-item:focus-visible { outline:2px solid var(--ed-accent); outline-offset:2px; }
.fm-ico { display:grid; place-items:center; flex:0 0 auto; width:20px; height:20px; color:inherit; }
.fm-ico svg { width:17px; height:17px; }
.fm-text { display:flex; align-items:baseline; gap:7px; min-width:0; }
.fm-text strong { font:600 12.5px/1.3 var(--font-heading, inherit); color:inherit; white-space:nowrap; }
.fm-text small { min-width:0; font-size:11.5px; color:var(--insp-muted); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }

/* Aviso «el informe aún no está listo»: un bocadillo anclado al acceso
   pulsado (no un modal — la pregunta es pequeña). positionReportGate lo
   coloca del lado con sitio (is-right/is-left) y la flecha apunta al centro
   del botón. La razón en una frase y el remedio como acción principal, en
   el azul de Analizar: es la misma acción. */
.report-gate-pop { position:fixed; z-index:150; width:272px; padding:12px 14px; background:#fff; border:1px solid var(--insp-line); border-radius:12px; box-shadow:0 14px 34px rgba(6,40,70,.22); }
.report-gate-pop[hidden] { display:none; }
.report-gate-pop > strong { display:block; margin-bottom:3px; font:700 13px/1.35 var(--font-heading, inherit); color:var(--insp-ink); }
.report-gate-pop > p { margin:0 0 10px; font-size:12.5px; line-height:1.5; color:var(--insp-muted); }
.report-gate-arrow { position:absolute; width:10px; height:10px; background:#fff; }
.report-gate-pop.is-right .report-gate-arrow { left:-5.5px; border-left:1px solid var(--insp-line); border-bottom:1px solid var(--insp-line); transform:rotate(45deg); }
.report-gate-pop.is-left .report-gate-arrow { right:-5.5px; border-right:1px solid var(--insp-line); border-top:1px solid var(--insp-line); transform:rotate(45deg); }
.report-gate-analyze { display:inline-flex; width:100%; align-items:center; justify-content:center; gap:8px; padding:9px 14px; color:#fff; background:var(--ed-accent); border:0; border-radius:9px; font:600 12.5px var(--font-heading, inherit); cursor:pointer; }
.report-gate-analyze:hover { background:var(--ed-accent-dark); }
.report-gate-analyze svg { width:15px; height:15px; }
.report-gate-analyze[hidden] { display:none; }
@media (prefers-reduced-motion: reduce) {
  .ribbon-row:not([hidden]) > *,
  .editor-ribbon:not(.is-folded) .ribbon-row:not([hidden]) { animation:none; }
}
.ribbon-sep { flex:0 0 auto; width:1px; height:22px; margin:0 6px; background:var(--insp-line); }
.ribbon-label { flex:0 0 auto; padding:0 4px; color:var(--insp-muted); font:600 11px var(--font-heading, inherit); white-space:nowrap; }
.ribbon-btn { flex:0 0 auto; display:inline-flex; align-items:center; justify-content:center; gap:7px; min-width:31px; height:31px; padding:0 7px; color:#3f4f61; background:transparent; border:0; border-radius:8px; font:600 12px var(--font-heading, inherit); cursor:pointer; white-space:nowrap; text-decoration:none; }
.ribbon-btn:hover:not([disabled]) { color:var(--ed-accent); background:#eaf3fc; }
.ribbon-btn svg { width:17px; height:17px; }
.ribbon-btn.is-labeled { padding:0 10px 0 8px; }
.ribbon-btn[disabled] { color:#c0c9d6; cursor:default; }
.ribbon-btn-state { font-size:10px; color:var(--insp-muted); }
/* Estados perceptibles (negrita activa, corrector encendido…): mismo
   tratamiento que tenía la barra de formato. */
.ribbon-btn.is-active,
.ribbon-btn[aria-pressed="true"],
.ribbon-btn[aria-checked="true"] { color:var(--ed-accent); background:#dceefe; box-shadow:inset 0 0 0 1px #a9d2f3; }
/* Selectores compactos, en azul de marca. */
.ribbon-select { flex:0 0 auto; min-width:0; width:72px; height:31px; padding:0 22px 0 10px; color:var(--ed-accent-dark); background:#f2f6fb; border:1px solid transparent; border-radius:8px; font:700 12px var(--font-heading, inherit); cursor:pointer; }
.ribbon-select:hover { background:#eaf3fc; }
.ribbon-select-font { width:106px; }
/* Botones-radio de espaciado/márgenes como pastilla segmentada (mismo dato y
   mismos data-attributes que sincroniza editor_chrome: is-selected). */
.ribbon-seg { display:inline-flex; flex:0 0 auto; padding:2px; gap:1px; background:#e6edf5; border-radius:999px; }
.ribbon-seg button { border:0; background:transparent; padding:3px 9px; border-radius:999px; font:600 11.5px var(--font-heading, inherit); color:var(--insp-muted); cursor:pointer; white-space:nowrap; }
.ribbon-seg button:hover { color:var(--insp-ink); }
.ribbon-seg button.is-selected { background:#fff; color:var(--insp-ink); box-shadow:0 1px 3px rgba(15,23,42,.18); }
.ribbon-seg button[disabled] { color:#c0c9d6; cursor:default; }
.editor-info-dialog { width:min(560px,calc(100vw - 32px)); }
.editor-info-body { margin:0 0 10px; color:var(--insp-ink); font-size:13px; line-height:1.6; }
.editor-info-body a { color:var(--ed-accent); font-weight:600; }
/* ---- pestaña contextual (patrón de Word) ----
   Aparece al final de la tira cuando el cursor entra en un objeto con
   comandos propios. Lleva rótulo encima y color propio —violeta, ajeno a la
   paleta del cromo— para que se lea como algo que ha aparecido y se irá, no
   como una pestaña más del editor. */
.ribbon-ctx-wrap { display:flex; flex-direction:column; align-items:stretch; align-self:stretch; justify-content:flex-end; flex:0 0 auto; margin-left:10px; }
.ribbon-ctx-wrap[hidden] { display:none; }
.ribbon-ctx-label { padding:1px 12px 0; color:var(--ed-ctx); background:var(--ed-ctx-wash); border-radius:7px 7px 0 0; font:800 9px/1.35 var(--font-heading, inherit); letter-spacing:.09em; text-transform:uppercase; text-align:center; }
.ribbon-ctx-tab { height:23px; padding:0 12px; border:0; border-bottom:2px solid var(--ed-ctx); background:var(--ed-ctx-wash); color:var(--ed-ctx); font:700 12px var(--font-heading, inherit); cursor:pointer; }
.ribbon-ctx-tab[aria-selected="true"] { background:#fff; }
.ribbon-row-ctx { background:linear-gradient(180deg,#faf8ff,#f5f1ff); border-top-color:#e4dcfb; }
.ribbon-row-ctx .ribbon-btn { color:#4c2d92; }
.ribbon-row-ctx .ribbon-btn:hover:not([disabled]) { color:var(--ed-ctx); background:#ece5fd; }
.ribbon-row-ctx .ribbon-label { color:var(--ed-ctx); font-weight:800; }
.ribbon-btn-danger { color:#b42318 !important; }
.ribbon-btn-danger:hover:not([disabled]) { color:#912018 !important; background:#fee4e2 !important; }

.rich-editor-content table { width:100%; margin:1rem 0; border-collapse:collapse; table-layout:fixed; }
.rich-editor-content th, .rich-editor-content td { min-width:80px; padding:7px 9px; border:1px solid #9daabd; vertical-align:top; }
.rich-editor-content th { background:#eef4fa; font-weight:700; }
.rich-editor-content .selectedCell { background:#dceefe; }
.rich-editor-content img { display:block; max-width:100%; height:auto; margin:1rem auto; border-radius:4px; }
.rich-editor-content p img { display:inline-block; max-height:1.4em; width:auto; margin:0 .15em; vertical-align:text-bottom; }
.rich-editor-content .artext-page-break { height:0; margin:2rem 0; border:0; border-top:2px dashed #8ba3bc; break-after:page; page-break-after:always; }
.rich-editor-content .artext-page-break::after { content:""; display:block; }
/* Cita en bloque: la extensión Blockquote del StarterKit aplica el nodo, pero
   sin estilo propio quedaba idéntica a un párrafo («no parece funcionar»).
   Barra azul de marca e indentación, coherente con el cromo del editor. */
.rich-editor-content blockquote, .rich-editor-surface blockquote { margin:1rem 0; padding:.25rem 0 .25rem 1rem; border-left:3px solid var(--ed-accent, #006fc0); color:#3a4658; font-style:italic; }
.rich-editor-content blockquote p, .rich-editor-surface blockquote p { margin:0; }
.editor-find-dialog .dialog-card, .editor-image-dialog .dialog-card, .editor-special-dialog .dialog-card { width:min(540px,calc(100vw - 32px)); }
.editor-find-dialog .dialog-fields, .editor-image-dialog .dialog-fields { display:grid; gap:12px; }
.editor-find-dialog label, .editor-image-dialog label { display:grid; gap:5px; color:var(--insp-ink); font-size:13px; font-weight:650; }
.editor-find-dialog input, .editor-image-dialog input { min-height:40px; padding:8px 10px; border:1px solid var(--insp-line); border-radius:8px; font:inherit; }
.editor-dialog-message { min-height:1.25em; margin:0; color:var(--insp-muted); font-size:12px; }
.editor-dialog-message[role="alert"] { color:#b42318; }
.editor-special-grid { display:grid; grid-template-columns:repeat(8,minmax(38px,1fr)); gap:6px; padding:18px; }
.editor-special-grid button { min-height:40px; border:1px solid var(--insp-line); border-radius:7px; background:#fff; font-size:19px; cursor:pointer; }
.editor-special-grid button:hover, .editor-special-grid button:focus-visible { color:var(--ed-accent); background:#eaf3fc; outline:2px solid #78afe0; outline-offset:1px; }
.is-limited-editor [data-analyze-text] { cursor:not-allowed; opacity:.55; }
.editor-file-status { display:inline-block; min-height:1.2em; max-width:min(360px,35vw); overflow:hidden; color:var(--insp-muted); font-size:11px; line-height:1.3; text-overflow:ellipsis; white-space:nowrap; }
.editor-file-status.is-success { color:#087443; }
.editor-file-status.is-error { color:#b42318; }
.editor-discard-dialog { width:min(520px,calc(100vw - 32px)); }
.danger-button { display:inline-flex; align-items:center; justify-content:center; gap:7px; min-height:40px; padding:0 15px; color:#fff; background:#d92d20; border:0; border-radius:9px; font:650 13px var(--font-heading); cursor:pointer; }
.danger-button:hover { background:#b42318; }
.danger-button svg { width:15px; height:15px; }

/* La antigua barra de formato (.editor-toolbar) desapareció: sus controles
   viven ahora en las filas de la cinta (.ribbon-row), con clases nuevas para
   no pelear con las reglas homónimas de analytics.css. */

/* =====================================================================
   LIENZO Y CAJA DE TEXTO: LOS DOS MODOS DE VISTA
   =====================================================================
   Como en Word, el editor tiene dos modos de vista y son estado del
   DOCUMENTO (se guardan con el zoom y el margen), no del tamaño de la
   ventana:

     · «Diseño de impresión» — folio A4 de 794px sobre lienzo gris, con
       sombra, borde de hoja, márgenes de papel y guías de cambio de página.
     · «Diseño web» — un continuo: una columna de lectura centrada sobre
       fondo blanco, sin sombra, sin borde de hoja, sin guías ni contador de
       páginas.

   La palanca única es el atributo `data-editor-layout` de la raíz del editor
   (`[data-public-editor]`), que fija public_editor.js con el modo EFECTIVO
   (preferencia del documento + valor por defecto + forzado en móvil: ver
   `effectiveLayout()` allí). De ese atributo cuelga TODO lo que distingue
   los dos modos; las reglas comunes se declaran una sola vez aquí arriba y
   no se repiten en ningún bloque de media query.

   El modo de impresión se escribe como `:not([data-editor-layout="web"])`
   en vez de `[data-editor-layout="print"]`: así el atributo ausente (el
   instante anterior a que el JS resuelva el modo, o un fallo de JS) cae en
   el folio A4, que es el comportamiento histórico.

   Prefijo `[data-public-editor]`: analytics.css declara sus propias
   `.editor-document-card` / `.rich-editor-surface` SIN ámbito — un resto
   «compact» (min-height:calc(100vh - 205px), un suelo fijo que impedía que
   el lienzo encogiera para caber en la columna flex, de ahí el «se pierde
   el scroll de la página») y una regla de tarjeta de previsualización del
   admin (border-radius + sombra) — y se carga DESPUÉS de esta hoja, así que
   sin ámbito ganarían el empate por orden de carga.

   Nada de esto afecta a la impresión: el bloque @media print del final
   pagina A4 siempre, en cualquier modo, y sus declaraciones son
   `!important`, por encima de las de los dos modos. Ver allí.
   ===================================================================== */
[data-public-editor] .editor-document-card {
  /* Lienzo desplazable en los dos ejes: en modo impresión el folio mantiene
     su anchura A4, así que cuando la ventana es más estrecha hay que poder
     desplazarse en horizontal en vez de encoger la página.
     `align-items:safe center` centra la caja de texto mientras cabe y la
     pega al borde inicial cuando desborda (con `center` a secas el navegador
     recorta el lado izquierdo y lo deja inalcanzable al hacer scroll).
     `position:relative`: contexto de posicionamiento para la capa de guías
     de página (editor_pagination.js), que es un hermano absoluto del folio,
     nunca un hijo de .rich-editor-surface. */
  position:relative;
  flex:1 1 auto; min-height:0; width:100%; overflow:auto;
  display:flex; flex-direction:column; align-items:safe center;
  border:1px solid var(--insp-line); border-top:0; border-radius:0; box-shadow:none;
}
.editor-document-card .rich-editor-surface {
  /* Reclaim inheritance: analytics.css's own unscoped `.rich-editor-surface`
     rule sets `--editor-zoom: 1` directly on this element (0,1,0, wins by
     default since nothing here redeclared the variable), which silently
     froze the zoom slider — the sheet's own width/min-height/padding below,
     and .rich-editor-content's font-size, all read var(--editor-zoom) as
     cascaded AT this element, not the live value set by JS on the editor
     root. `unset` on a higher-specificity (0,2,0) rule discards that
     declaration and falls back to normal inheritance from the root. */
  --editor-zoom: unset;
  display:block; box-sizing:border-box; margin:0; overflow:visible;
  flex:0 0 auto;
  color:#1f3147;
  font-family:var(--ed-doc-font); font-size:16.5px; line-height:1.75;
}
.editor-document-card .rich-editor-content { max-width:none; width:100%; margin:0; }

/* ---- diseño de impresión: folio A4 sobre lienzo gris ---- */
[data-public-editor]:not([data-editor-layout="web"]) .editor-document-card {
  padding:26px 24px 40px; background:var(--editor-canvas);
}
[data-public-editor]:not([data-editor-layout="web"]) .rich-editor-surface {
  /* Anchura A4 real, sin `min(..., 100%)`: aquel min encogía el folio por
     debajo del A4 en cuanto el lienzo era más estrecho, de modo que la caja
     de texto (y con ella el salto de línea y el reparto en páginas) dejaba de
     corresponderse con el papel. El desbordamiento lo absorbe el scroll
     horizontal de .editor-document-card. */
  max-width:none;
  width:calc(var(--editor-page-w, 794px) * var(--editor-zoom, 1));
  min-height:calc(var(--editor-page-h, 1123px) * var(--editor-zoom, 1));
  padding:calc(var(--editor-margin, 96px) * var(--editor-zoom, 1)) calc(var(--editor-margin, 96px) * var(--editor-zoom, 1));
  /* Folio blanco liso. Las guías de cambio de página YA NO son un degradado
     ciego sobre este fondo (repartía la altura de página a partes iguales,
     sin mirar dónde empezaba o acababa cada bloque real). Las dibuja
     editor_pagination.js, midiendo el contenido, en una capa hermana de este
     elemento — ver .editor-page-guides más abajo. Nunca dentro de este nodo
     ni de .rich-editor-content: son el contenido editable y sus
     desplazamientos de texto no se pueden alterar. */
  background-color:#fff;
  /* Sharp corners: it is a page, not a card — the previous 2px radius plus
     the (now fixed, see above) canvas rounding/shadow leaking in from
     analytics.css read as a rounded blob stuck onto the grey canvas. */
  border:1px solid #cbd5e3; border-radius:0;
  box-shadow:0 1px 2px rgba(18,38,63,.22), 0 10px 24px rgba(18,38,63,.14), 0 28px 60px rgba(18,38,63,.12);
}

/* ---- diseño web: un continuo, no un folio ----
   Sin lienzo gris, sin sombra, sin borde de hoja y sin altura mínima de
   página: solo una columna de lectura centrada. El aire lateral lo pone el
   padding del lienzo (crece con la ventana hasta 72px); la anchura de la
   columna la limita --editor-web-w y escala con el zoom, igual que el folio.
   Los márgenes de papel (--editor-margin) NO se aplican: en un continuo no
   hay papel del que apartarse, y seguir aplicándolos era justo lo que hacía
   que el modo siguiera pareciendo una hoja. */
[data-public-editor][data-editor-layout="web"] .editor-document-card {
  padding:30px clamp(16px, 5vw, 72px) 72px; background:#fff;
}
[data-public-editor][data-editor-layout="web"] .rich-editor-surface {
  width:100%;
  max-width:calc(var(--editor-web-w, 760px) * var(--editor-zoom, 1));
  min-height:0;
  padding:0;
  background:none; border:0; box-shadow:none;
}
/* Guías y contador de páginas: en un continuo no describen nada de lo que se
   ve. editor_pagination.js además ni las calcula (recibe `isWebLayout`). */
[data-public-editor][data-editor-layout="web"] .editor-page-guides,
[data-public-editor][data-editor-layout="web"] .statusbar-page { display:none; }

/* ---- guías de cambio de página (editor_pagination.js) ----
   Capa superpuesta, hermana de .rich-editor-surface (nunca hija ni de esta ni
   de .rich-editor-content): el JS la crea con insertAdjacentElement("afterend")
   y la posiciona/dimensiona por JS para calcar el rectángulo del folio, así
   que aquí solo hace falta declarar el tipo de posicionamiento. Cada línea de
   corte se coloca por JS (top:Npx) en el punto donde de verdad terminaría la
   página según la altura acumulada de los bloques reales, no cada N píxeles
   iguales. pointer-events:none: es puramente visual, los clics deben llegar
   al editor de debajo. */
.editor-page-guides { position:absolute; top:0; left:0; z-index:1; pointer-events:none; }
.editor-page-guide {
  position:absolute; left:0; right:0; height:29px; margin-top:-14px;
  background:
    linear-gradient(rgba(15,23,42,.24), rgba(15,23,42,.24)) center/100% 1px no-repeat,
    linear-gradient(to bottom, transparent, rgba(15,23,42,.09) 46%, rgba(15,23,42,.09) 54%, transparent);
}

/* ---- Word-style bottom status bar ----
   A discreet strip, not a second toolbar: slimmer height/padding/font and
   tighter gaps than the rest of the chrome, while keeping every piece of
   information (engine, page, words, saved state, occurrence count, spell
   toggle, language, zoom) legible. */
.editor-statusbar {
  flex:0 0 auto; display:flex; align-items:center; justify-content:space-between;
  gap:8px; width:100%; min-height:26px; margin-top:0; padding:3px 10px;
  color:var(--insp-muted); background:#f4f7fb; border:0; border-top:1px solid #dde5ef;
  border-radius:0; font:500 10.5px var(--font-heading, inherit);
}
.statusbar-left, .statusbar-right { display:flex; align-items:center; gap:6px; min-width:0; }
.statusbar-left { overflow:hidden; }
.statusbar-left > span { flex:0 0 auto; white-space:nowrap; }
.statusbar-sep { width:1px; height:10px; background:var(--insp-line); }
.statusbar-dirty { flex:0 1 auto !important; min-width:0; max-width:230px; overflow:hidden; color:#b45309; font-weight:600; text-overflow:ellipsis; }
.statusbar-lang { padding:0 6px; color:var(--insp-ink); background:var(--insp-surface-2); border-radius:5px; font-weight:700; letter-spacing:.03em; }
.statusbar-right .badge { flex:0 0 auto; padding:1px 8px; font-size:10px; }
/* Selector de modo de vista (diseño de impresión / diseño web). Vive en la
   barra de estado, a la izquierda del zoom: es donde Word pone el cambio de
   vista y, sobre todo, es la misma clase de propiedad que el zoom — cómo se
   presenta el documento en pantalla, no qué contiene ni qué paneles hay
   abiertos. Por eso no va en el grupo de acciones de vista de la cabecera,
   que es de visibilidad de carriles, ni en un menú «Ver» nuevo.
   Misma pastilla de dos segmentos que .rail-marks-switch, para que se lea
   como un conmutador y no como dos botones sueltos. */
.statusbar-layout { display:inline-flex; flex:0 0 auto; padding:2px; background:#e6edf5; border-radius:999px; }
.statusbar-layout button { display:grid; place-items:center; width:26px; height:22px; padding:0; color:var(--insp-muted); background:transparent; border:0; border-radius:999px; cursor:pointer; }
.statusbar-layout button svg { width:13px; height:13px; }
.statusbar-layout button[aria-pressed="true"] { color:var(--insp-ink); background:#fff; box-shadow:0 1px 3px rgba(15,23,42,.18); }
.statusbar-zoom { display:flex; align-items:center; gap:4px; }
.statusbar-zoom .icon-tool { width:22px; height:22px; }
.statusbar-zoom .icon-tool svg { width:13px; height:13px; }
.statusbar-zoom .editor-zoom-label { min-width:34px; font-size:10.5px; text-align:right; }
.zoom-slider { width:78px; accent-color:var(--insp-primary); cursor:pointer; }

@media (max-width: 1279px) {
  /* Same specificity as the base rules above (both scoped under
     [data-public-editor]), so these still win at this breakpoint instead of
     silently losing to the unscoped base rule now that it outranks a bare
     analytics.css same-name selector. */
  [data-public-editor] .agent-editor-frame { height:auto; min-height:calc(100vh - 96px); }
  [data-public-editor] .editor-document-card { min-height:52vh; }
}


/* ---- printing: only the document, as real paged output ----
   Before this block there was no @media print anywhere in the app, so
   window.print() dumped the raw screen chrome (menus, rails, status bar)
   instead of the page content. The physical @page margin is injected by
   editor_file_io.js's print() (CSS custom properties in @page aren't
   reliable across browsers), so the surface's own padding/shadow/page-guide
   background — all screen-only simulations of a printed page — are cleared
   here and the zoom var is reset so print always renders at natural size. */
@media print {
  [data-public-editor] { --editor-zoom: 1; }
  [data-public-editor] .editor-appnav,
  [data-public-editor] .editor-ribbon,
  [data-public-editor] .editor-statusbar,
  [data-public-editor] .editor-rail,
  [data-public-editor] .rail-reopen,
  /* Ni la vista de informe ni la de «Nuevo documento» son el documento:
     imprimir se pide desde el menú Archivo con el editor detrás, pero si el
     usuario imprimiera DESDE una de ellas el papel saldría con lo que hay en
     pantalla y el folio oculto. La regla de abajo devuelve .editor-main-panel
     a display:block con !important, que es lo que imprime el folio esté la
     vista que esté. */
  [data-public-editor] .editor-report-view,
  [data-public-editor] .editor-start,
  [data-public-editor] .editor-page-guides {
    display: none !important;
  }
  [data-public-editor] .public-editor-shell,
  [data-public-editor] .editor-main-panel,
  [data-public-editor] .agent-editor-frame {
    display: block !important;
    height: auto !important;
    min-height: 0 !important;
    padding: 0 !important;
  }
  [data-public-editor] .editor-document-card {
    display: block !important;
    width: auto !important;
    height: auto !important;
    min-height: 0 !important;
    margin: 0 !important;
    padding: 0 !important;
    overflow: visible !important;
    background: none !important;
    border: 0 !important;
  }
  [data-public-editor] .rich-editor-surface {
    width: auto !important;
    /* La impresión pagina A4 SIEMPRE, esté el editor en diseño de impresión o
       en diseño web (como Word). Este bloque no mira `data-editor-layout`, y
       por eso hay que anular también la columna de lectura del diseño web
       (max-width: --editor-web-w): sin esto, imprimir desde el modo web
       encajonaría el texto en 760px en mitad del papel. */
    max-width: none !important;
    min-height: 0 !important;
    margin: 0 !important;
    padding: 0 !important;
    background: none !important;
    border: 0 !important;
    box-shadow: none !important;
    color: #000 !important;
  }
  [data-public-editor] .rich-editor-content { max-width: none !important; width: 100% !important; }
}

/* ---- Corrector ortográfico ----
   Capa de decoraciones ProseMirror (extensión Spellcheck del bundle): NO son
   marcas de regla ni tocan el documento. Se distinguen por diseño de las marcas
   de sugerencia (.text-hit, borde inferior sólido de color + relleno): el error
   ortográfico es un subrayado ONDULADO rojo, sin relleno, de prioridad visual
   baja. En un solapamiento con una marca de regla, la regla (envoltorio) mantiene
   su relleno y su borde legibles y su clic sigue abriendo el popover; el ondulado
   queda como capa inferior en el span interior. */
.spellcheck-error {
  text-decoration-line: underline;
  text-decoration-style: wavy;
  text-decoration-color: #dc2626;
  text-decoration-skip-ink: none;
  text-underline-offset: 2px;
  /* Sin fondo: no compite con el relleno de las marcas de regla. */
  background: none;
}

/* Pastilla del corrector en la barra de estado: indicador de idioma + estado
   por color (verde activo, ámbar cargando, rojo error, gris apagado) y a la vez
   interruptor. Discreta, en línea con .statusbar-lang. */
.statusbar-spell {
  display:inline-flex; align-items:center; gap:5px; flex:0 0 auto;
  padding:1px 7px 1px 6px; color:var(--insp-muted); background:var(--insp-surface-2);
  border:1px solid transparent; border-radius:6px; font:inherit; cursor:pointer;
  transition:color .15s ease, background .15s ease, border-color .15s ease;
}
.statusbar-spell:hover { color:var(--insp-ink); border-color:var(--insp-line); }
.statusbar-spell svg { width:14px; height:14px; }
.statusbar-spell-lang { font-weight:700; letter-spacing:.03em; }
.statusbar-spell.is-active { color:var(--insp-ink); }
/* Etiqueta corta de estado (Activo/Cargando…/Inactivo/Error): junto al color
   de la pastilla, deja el estado en texto para que no dependa de pasar el
   ratón por encima ni de interpretar un color. */
.statusbar-spell-state { font-size:10.5px; font-weight:650; letter-spacing:.02em; white-space:nowrap; }
.statusbar-spell-state:empty { display:none; }
.statusbar-spell[data-spell-state="on"] { color:#15803d; background:#effaf1; }
.statusbar-spell[data-spell-state="off"] { color:var(--insp-muted); background:var(--insp-surface-2); }
.statusbar-spell[data-spell-state="loading"] { color:#b45309; background:#fff7ed; }
.statusbar-spell[data-spell-state="loading"] svg { animation:spellPulse 1.1s ease-in-out infinite; }
.statusbar-spell[data-spell-state="error"] { color:#b91c1c; background:#fef2f2; }
@keyframes spellPulse { 0%,100%{opacity:.4;} 50%{opacity:1;} }
@media (prefers-reduced-motion: reduce) {
  .statusbar-spell[data-spell-state="loading"] svg { animation:none; }
}

/* Estado del interruptor del corrector en la cinta (pestaña Revisar), con la
   misma etiqueta corta que la pastilla de la barra de estado. */
.ribbon-btn .ribbon-btn-state:empty { display:none; }
.ribbon-btn[data-spell-state="on"] .ribbon-btn-state { color:#15803d; }
.ribbon-btn[data-spell-state="loading"] .ribbon-btn-state { color:#b45309; }
.ribbon-btn[data-spell-state="error"] .ribbon-btn-state { color:#b91c1c; }

/* Menú de corrección: flota fijo junto a la palabra, independiente del popover
   de reglas. */
.spellcheck-menu {
  position:fixed; z-index:80; min-width:200px; max-width:280px;
  display:flex; flex-direction:column; gap:6px; padding:8px;
  background:#fff; border:1px solid var(--insp-line); border-radius:12px;
  box-shadow:0 18px 44px rgba(15,23,42,.18);
  font:500 12.5px var(--font-heading, inherit);
}
.spellcheck-menu[hidden] { display:none; }
.spellcheck-menu-word {
  margin:0; padding:2px 8px 6px; color:var(--insp-muted); font-size:11px; font-weight:650;
  letter-spacing:.02em; border-bottom:1px solid var(--insp-line-2);
}
.spellcheck-menu-word::before { content:"“"; }
.spellcheck-menu-word::after { content:"”"; }
.spellcheck-menu-suggestions { display:flex; flex-direction:column; gap:1px; }
.spellcheck-menu-suggestion {
  display:block; width:100%; padding:7px 9px; color:var(--insp-ink); text-align:left;
  background:transparent; border:0; border-radius:7px; font:600 13px var(--font-heading, inherit);
  cursor:pointer;
}
.spellcheck-menu-suggestion:hover, .spellcheck-menu-suggestion:focus-visible {
  background:#f5f5ff; color:var(--insp-primary); outline:none;
}
.spellcheck-menu-empty { margin:0; padding:6px 9px; color:var(--insp-muted); font-size:12px; font-style:italic; }
.spellcheck-menu-actions { display:flex; gap:4px; padding-top:6px; border-top:1px solid var(--insp-line-2); }
.spellcheck-menu-action {
  flex:1; display:inline-flex; align-items:center; justify-content:center; gap:5px;
  padding:6px 8px; color:var(--insp-muted); background:transparent; border:0; border-radius:7px;
  font:600 11.5px var(--font-heading, inherit); cursor:pointer;
}
.spellcheck-menu-action:hover { background:var(--insp-surface-2); color:var(--insp-ink); }
.spellcheck-menu-action svg { width:14px; height:14px; }

/* En impresión, la ayuda de edición no debe verse. */
@media print {
  .spellcheck-error { text-decoration:none !important; }
  .spellcheck-menu, .statusbar-spell { display:none !important; }
}

/* =====================================================================
   TARJETA DE ACIERTO: UNA SOLA ZONA DESPLAZABLE
   =====================================================================
   La caja (`.editor-hit-popover`) la declara analytics.css, que se carga
   DESPUÉS de esta hoja: de ahí el prefijo [data-public-editor] en cada
   regla, que rompe el empate de especificidad.

   La altura la fija `positionHitPopover` (estilo en línea) con el hueco
   real que queda entre la marca y el borde de la ventana. Lo que no entra
   se alcanza desplazando dentro de `.hit-popover-body`, que es el ÚNICO
   desplazador de la tarjeta: el panel de propuestas pierde el suyo para
   que no haya dos anidados y la recomendación, la navegación entre
   ocurrencias y las propuestas del catálogo formen una sola tirada.
   `overscroll-behavior:contain` evita que al llegar al final el gesto
   siga arrastrando el folio de detrás.
   ===================================================================== */
[data-public-editor] .hit-popover-body {
  display:flex; flex-direction:column; flex:1 1 auto; min-height:0;
  overflow-y:auto; overscroll-behavior:contain;
  scrollbar-width:thin; scrollbar-color:rgba(100,116,139,.55) transparent;
}
[data-public-editor] .hit-popover-body::-webkit-scrollbar { width:8px; }
[data-public-editor] .hit-popover-body::-webkit-scrollbar-thumb { background:rgba(100,116,139,.42); border-radius:999px; }
/* Dentro de un contenedor con desplazamiento, un hijo flexible se encoge en
   vez de alargar la tirada: el panel de propuestas se quedaba aplastado y sus
   tarjetas se salían por encima del botón de detalles. Aquí cada bloque mide
   lo suyo y lo que sobra lo absorbe el desplazamiento. */
[data-public-editor] .hit-popover-body > * { flex:0 0 auto; }
[data-public-editor] .hit-ai-panel { max-height:none; overflow:visible; }
/* El botón de cerrar queda fuera de la zona desplazable, anclado a la
   esquina: con el texto pasando por debajo necesita fondo propio. */
[data-public-editor] .hit-popover-close { background:rgba(255,255,255,.94); border-radius:8px; }
/* Anclada al alto de la ventana (no hay hueco útil ni encima ni debajo de
   la marca): la flecha no señalaría a nada. */
[data-public-editor] .editor-hit-popover.is-anchored::before { display:none; }

/* =====================================================================
   MODO MÓVIL (≤768px)
   =====================================================================
   Punto de ruptura único de móvil. El editor tiene dos cortes y solo dos:

     ≤1279px  «estrecho»: los carriles dejan de ser columnas de la retícula
              y pasan a ser cajones sobre el texto (bloques de más arriba).
     ≤768px   «móvil»: este bloque.

   Va al final del fichero a propósito: varias de las reglas que corrige
   (barra de estado, pastilla del corrector) se declaran más arriba con la
   misma especificidad, y el orden de origen es lo que decide el empate.

   Decisión de producto: EN MÓVIL SE CAE LA METÁFORA DEL A4. Por debajo de
   este corte el folio deja de medir 794px fijos y ocupa el ancho útil, con
   márgenes proporcionados a la pantalla. Consecuencias obligadas:

     · las guías de cambio de página se ocultan (una guía calculada sobre
       proporciones A4 es falsa cuando la caja de texto no es un A4);
       editor_pagination.js además ni las calcula;
     · el contador «página X de Y» se oculta: contaría páginas de un reparto
       que la pantalla no muestra. La exportación y la impresión siguen
       paginando en A4 de verdad, con las reglas de @media print intactas;
     · el zoom deja de ser «ajustar el folio a la ventana» (no hay nada que
       ajustar) y queda como escala de lectura del texto; el zoom de ajuste
       automático arranca al 100 % (computeFitZoom en public_editor.js).

   Nada de esto toca escritorio ni impresión: por encima de 768px siguen el
   A4 de anchura fija, las guías medidas y el bloque @media print.

   `screen and`: una consulta de anchura a secas también se evalúa al
   imprimir, contra la caja de página; con papel estrecho (o apaisado en
   ciertos tamaños) este bloque se colaría en la impresión. La salida
   impresa no depende del ancho de la pantalla.
   ===================================================================== */
@media screen and (max-width: 768px) {
  /* Altura de la aplicación en unidades dinámicas: con 100vh el navegador
     móvil cuenta la barra de direcciones retraída y la barra de estado del
     editor quedaba fuera de la pantalla hasta que se desplazaba la página. */
  body:has([data-public-editor]) .public-editor-shell { min-height:100dvh; }
  body:has([data-public-editor]) .agent-editor-frame { height:100dvh; min-height:100dvh; }

  /* ---- vista del informe ----
     El rótulo del género se recorta a una línea y la descarga no parte
     palabras: en 375px, «Descargar informe PDF» en tres renglones se comía la
     cabecera entera. El informe pega con los bordes, que es todo el ancho que
     hay (el propio fragmento retira su marco en pantallas estrechas). */
  .report-view-head { gap:10px; padding:9px 12px; }
  .report-view-id small { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .report-view-download { flex:0 0 auto; padding:9px 13px; font-size:12.5px; white-space:nowrap; }
  .report-view-body { padding:0 0 32px; }

  /* ---- vista «Nuevo documento» ----
     La cabecera se apila (el botón de volver bajo el título, no a su lado) y
     el pie pasa a dos renglones con el botón a todo lo ancho: en 375px, el
     resumen y «Crear documento» en la misma línea dejaban al botón en 90px.
     La altura la manda el visor, no 100vh: con el teclado abierto, el pie fijo
     a 100vh se iba fuera de pantalla. */
  .editor-start { min-height:100dvh; max-height:100dvh; }
  .start-head { flex-direction:column; gap:12px; padding:16px 14px 14px; }
  .start-head-id h2 { font-size:18px; }
  .start-resume { align-self:stretch; justify-content:center; min-height:44px; }
  .start-body { padding:16px 14px 22px; }
  .start-origins { grid-template-columns:1fr; }
  .start-foot { flex-direction:column; align-items:stretch; gap:12px; padding:12px 14px; }
  .start-confirm { justify-content:center; min-height:46px; font-size:14.5px; }
  .start-warn { flex-wrap:wrap; }
  .start-download { min-height:34px; }
  .start-file-chip button { width:34px; height:34px; }

  /* ---- cinta ----
     Las dos filas se desplazan con el dedo; objetivos de 40px. La fila de
     pestañas gana altura y la de comandos pasa a 52px. */
  .ribbon-tabs { height:40px; overflow-x:auto; overscroll-behavior-x:contain; scrollbar-width:none; }
  .ribbon-tabs::-webkit-scrollbar { display:none; }
  .ribbon-wordmark { display:none; }
  .ribbon-tab { height:40px; padding:0 12px; font-size:13.5px; }
  .ribbon-fold { width:36px; height:36px; }
  .ribbon-row { height:52px; gap:2px; padding:0 6px; }
  .ribbon-btn { min-width:40px; height:40px; border-radius:9px; font-size:13px; }
  .ribbon-btn svg { width:20px; height:20px; }
  .ribbon-sep { height:26px; margin:0 4px; }
  .ribbon-select { height:40px; font-size:13px; }
  .ribbon-select-font { width:98px; }
  /* Los tres selectores (formato, fuente, tamaño) ocupan ~240px: al principio
     de la fila dejaban negrita/cursiva fuera de la primera pantalla. En móvil
     se van al final, donde se llega desplazando. */
  .ribbon-row-format .ribbon-select { order:1; }
  /* El carril de aplicación estrecha un poco en móvil. */
  /* En táctil el carril no se despliega (ver la regla de puntero fino), así
     que aquí solo estrecha: --appnav-w manda sobre la retícula y el propio
     carril, y las filas conservan su caja de icono. */
  .public-editor-shell { --appnav-w:46px; padding-left:46px; }
  .editor-appnav { padding-left:4px; padding-right:4px; }
  .appnav-btn > svg { margin:0 7.5px; }
  .editor-structure-rail { left:46px; }
  .rail-reopen-left { left:46px; }

  /* ---- caja de texto ----
     Aquí NO se repiten las reglas del folio: por debajo de este corte
     public_editor.js fuerza `data-editor-layout="web"`, así que la caja
     fluida la dan las reglas de «diseño web» de más arriba, una sola vez.
     Lo único propio de móvil es el cuerpo de texto, 16px en vez de los 15px
     que analytics.css impone sin ámbito (de ahí el prefijo, que se carga
     después de esta hoja y si no ganaría el empate). */
  [data-public-editor] .editor-document-card .rich-editor-surface { font-size:16px; }
  [data-public-editor] .editor-document-card .rich-editor-content { font-size:calc(16px * var(--editor-zoom,1)); }
  /* El selector de modo de vista se retira: por debajo de este corte el A4 no
     cabe y el modo impresión no se ofrece (public_editor.js fuerza web). Se
     oculta en vez de dejarlo deshabilitado porque un control apagado sin
     explicación invita a preguntarse por qué, y aquí no hay elección posible
     ni sitio en la barra para justificarla. */
  .statusbar-layout { display:none; }

  /* ---- barra de estado ----
     Una fila desplazable en horizontal, no envuelta en varias: envolver le
     comía hasta tres renglones de alto. Se retiran los separadores, el
     indicador de idioma (ya está en la pastilla del corrector), el contador
     de páginas y el deslizador de zoom (los botones −/+ bastan con el dedo). */
  .editor-statusbar { min-height:0; padding:4px 8px; font-size:12px; flex-wrap:nowrap; overflow-x:auto; overscroll-behavior-x:contain; scrollbar-width:none; }
  .editor-statusbar::-webkit-scrollbar { display:none; }
  /* Grupo de la derecha primero: en 390px no cabe la barra entera, y lo que
     tiene que estar a la vista sin desplazar es lo accionable (coincidencias,
     corrector, zoom). Lo informativo (estado del motor, palabras, guardado)
     queda a continuación, alcanzable desplazando. Nada se oculta. */
  .statusbar-right { order:1; }
  .statusbar-left { order:2; }
  /* flex:0 0 auto + min-width:auto: los dos grupos traen `min-width:0`, que
     con la barra sin envolver les dejaba encogerse por debajo de su contenido
     y los renglones se solapaban unos con otros. Aquí cada grupo mide lo suyo
     y lo que sobra lo absorbe el desplazamiento de la barra. */
  .statusbar-left, .statusbar-right { flex:0 0 auto; min-width:auto; gap:8px; }
  .statusbar-left { overflow:visible; }
  .statusbar-sep, .statusbar-lang, .statusbar-page, .zoom-slider { display:none; }
  .statusbar-dirty { max-width:none; font-size:12px; }
  .statusbar-right .badge { padding:2px 9px; font-size:12px; }
  .editor-file-status { max-width:60vw; font-size:12px; }
  .statusbar-spell { min-height:40px; padding:4px 10px; }
  .statusbar-spell svg { width:16px; height:16px; }
  .statusbar-spell-lang, .statusbar-spell-state { font-size:12px; }
  .statusbar-zoom .icon-tool { width:40px; height:40px; }
  .statusbar-zoom .icon-tool svg { width:18px; height:18px; }
  .statusbar-zoom .editor-zoom-label { min-width:38px; font-size:12px; }

  /* ---- carriles a pantalla completa ----
     Cubren la cabecera, así que la única salida es el botón de cerrar de su
     propia cabecera: tiene que ser grande. */
  /* El cajón ocupa todo salvo el carril de aplicación, que sigue a la vista
     (es la navegación y lleva los interruptores de panel). */
  .editor-rail { inset:0 0 0 46px; width:auto; border-radius:0; }
  .rail-head { padding:8px 8px 8px 14px; }
  .rail-head-title { font-size:15px; }
  .rail-head-title i, .rail-head-title svg { width:18px; height:18px; }
  .rail-collapse, .rail-head-action { width:44px; height:44px; border-radius:11px; }
  .rail-collapse svg, .rail-head-action svg { width:20px; height:20px; }
  /* Las pestañas laterales de reapertura se retiran: flotan a media altura
     sobre el folio, tapan el texto y no se pueden apartar. Los dos
     interruptores de la cabecera hacen lo mismo y están siempre a la vista. */
  .rail-reopen { display:none; }
  .rail-genre { padding:8px 10px 8px 14px; }
  .rail-genre-id strong { font-size:14px; }
  .rail-genre-id small { font-size:12px; }
  .rail-genre-change { min-height:40px; font-size:12.5px; }
  .rail-analyze-btn { min-height:46px; font-size:14px; }
  .rail-analyze-btn svg { width:18px; height:18px; }
  .rail-analyze-btn.is-secondary { min-height:36px; font-size:12.5px; }
  .rail-analyze-btn.is-secondary svg { width:15px; height:15px; }
  [data-public-editor] .editor-report-status h3 { font-size:13.5px; }
  [data-public-editor] .editor-report-status p { font-size:12.5px; }

  /* ---- árbol de estructura ----
     El «+» de insertar aparecía solo al posar el cursor: sin ratón no hay
     hover, así que en móvil está siempre visible o no se puede usar. */
  .structure-intro { font-size:12.5px; }
  .structure-head h1 { font-size:15.5px; }
  .structure-head p { font-size:12px; }
  .structure-head .back-link { min-height:40px; font-size:12.5px; }
  .structure-tree-toggle { min-height:44px; padding:10px 6px 10px 12px; }
  .structure-tree-toggle > svg { width:16px; height:16px; }
  .structure-tree-toggle strong { font-size:14px; }
  .structure-tree-toggle small { font-size:12px; }
  .structure-tree-row.content-row .structure-tree-toggle { min-height:42px; padding:9px 6px 9px 8px; }
  .structure-tree-row.content-row .structure-tree-toggle > svg { width:14px; height:14px; }
  .structure-tree-row.content-row .structure-tree-toggle strong { font-size:13.5px; }
  /* [data-public-editor]: analytics.css declara su propia
     `.structure-insert-action` de 32x32 sin ámbito y se carga después. */
  [data-public-editor] .structure-insert-action { width:40px; height:40px; margin-right:4px; opacity:1; border:0; background:transparent; }
  [data-public-editor] .structure-insert-action svg { width:18px; height:18px; }
  .structure-tree-phrases .phraseology-btn { min-height:44px; padding:10px 9px; font-size:13px; }
  .structure-tree-phrases .phraseology-btn svg { width:17px; height:17px; }
  .structure-empty { font-size:12.5px; }

  /* ---- panel de sugerencias (acotado al editor) ----
     original_suggestions.css y analytics.css los comparte el analizador; las
     correcciones de móvil del editor van aquí bajo [data-public-editor] para
     no tocar esa hoja compartida. */
  [data-public-editor] .sg-panel .sg-iconbtn { width:40px; height:40px; }
  [data-public-editor] .sg-panel .sg-iconbtn svg { width:18px; height:18px; }
  [data-public-editor] .sg-panel .sg-chip { min-height:34px; padding:6px 12px; font-size:12.5px; }
  [data-public-editor] .sg-panel .sg-card-head { padding:14px 13px; }
  [data-public-editor] .sg-panel .sg-point-head { padding:13px 12px; }
  [data-public-editor] .sg-panel .sg-points-head span,
  [data-public-editor] .sg-panel .sg-points-head .c,
  [data-public-editor] .sg-panel .sg-point-flag,
  [data-public-editor] .sg-panel .sg-cut,
  [data-public-editor] .sg-panel .sg-rel-head .n { font-size:12px; }
  [data-public-editor] .sg-panel .sg-rel-head { padding:11px; }
  [data-public-editor] .sg-panel .sg-opt-main { padding:10px 14px; }
  [data-public-editor] .sg-panel .sg-opt-icon { width:40px; }
  [data-public-editor] .sg-panel .sg-btn { min-height:44px; }
  [data-public-editor] .sg-panel .sg-preview section > span { font-size:12px; }

  /* ---- tarjeta de acierto: hoja inferior ----
     Por debajo de este corte el globo anclado a la marca se cambia por una
     hoja pegada al borde inferior, como la del analizador. Razón: con una
     recomendación larga y propuestas de catálogo no hay hueco suficiente ni
     encima ni debajo de la marca en una pantalla de teléfono, así que el
     globo acababa fuera de la ventana o encogido a media altura. La hoja
     tiene siempre el mismo sitio, el mismo alto máximo y el pulgar cerca.

     La colocación es toda de aquí: `positionHitPopover` retira sus estilos
     en línea (izquierda, arriba, alto máximo, flecha) al entrar en este
     modo, y añade `is-sheet`.

     72dvh: unidades dinámicas, para que la barra del navegador al replegarse
     no deje la hoja más alta que la ventana. Se declara detrás de la versión
     en vh, que sirve de respaldo donde no haya dvh. */
  [data-public-editor] .editor-hit-popover.is-sheet {
    left:0; right:0; top:auto; bottom:0;
    width:100%; max-width:none;
    max-height:72vh;
    max-height:72dvh;
    padding:16px 14px calc(14px + env(safe-area-inset-bottom, 0px));
    border-width:1px 0 0;
    border-radius:16px 16px 0 0;
    box-shadow:0 -14px 36px rgba(15,23,42,.24);
  }
  [data-public-editor] .editor-hit-popover.is-sheet::before { display:none; }

  /* ---- popover de acierto y diálogos ---- */
  [data-public-editor] .hit-popover-close { width:40px; height:40px; }
  [data-public-editor] .hit-popover-assist,
  [data-public-editor] .hit-popover-details { min-height:44px; }
  [data-public-editor] .dialog-close { width:40px; height:40px; }
  [data-public-editor] .dialog-footer .ghost-button,
  [data-public-editor] .dialog-footer .secondary-btn,
  [data-public-editor] .dialog-footer .primary-btn,
  [data-public-editor] .dialog-footer .danger-button { min-height:44px; }
  .editor-special-grid button { min-height:44px; }
  /* 16px: por debajo de ese tamaño iOS amplía la página al enfocar un campo
     de texto y deja el editor descuadrado al volver. */
  .editor-find-dialog input, .editor-image-dialog input { min-height:44px; font-size:16px; }
}

/* ---- lanzador de diálogo (patrón de Word: la flechita del grupo) ----
   Lo que no cabe en la cinta no se recoge en un menú flotante: se va a un
   diálogo con sitio para verlo entero. Aquí, el espaciado de párrafo, que
   ocupaba diez segmentos en fila. */
.ribbon-launcher { flex:0 0 auto; display:grid; place-items:center; width:22px; height:22px; margin-left:2px; padding:0; color:#9aa7b8; background:transparent; border:0; border-radius:6px; cursor:pointer; }
.ribbon-launcher:hover { color:var(--ed-accent); background:var(--ed-active-bg); }
.ribbon-launcher svg { width:13px; height:13px; }
.editor-paragraph-dialog { width:min(470px, calc(100vw - 32px)); }
.editor-paragraph-dialog .dialog-fields { display:flex; flex-direction:column; gap:13px; }
.paragraph-field { display:flex; align-items:center; gap:12px; }
.paragraph-field-label { flex:0 0 132px; color:var(--insp-ink); font:600 12.5px var(--font-heading, inherit); }
.paragraph-field .ribbon-seg { flex:1; }
.paragraph-field .ribbon-seg button { flex:1; }
/* Vista previa: dos párrafos, porque lo que se decide es el espacio ENTRE
   ellos. Se ve con la letra del folio para que el juicio sea sobre lo real. */
.paragraph-preview { margin-top:3px; padding:14px 16px; background:#fbfdff; border:1px solid var(--insp-line-2); border-radius:11px; color:#7b8798; font:400 12.5px/1.5 var(--ed-doc-font); }
.paragraph-preview p { margin:0; }
