/* ============================================================
   SEO Optimizer — Frontend custom CSS
   Tokens canónicos: docs/design_system/colors_and_type.css.
   Reusa de docs/internal/code-to-reuse/admin.css: tokens, inputs,
   buttons, cards, drawer, error pattern. DROP: cualquier selector
   bajo #wpcontent o resets de wp-admin. REDESIGN: layout grid sin
   chrome de wp-admin, sidebar 240px, topbar sticky 56px.
   TODO Fase 10: self-host Inter en assets/fonts/. — HECHO: Inter self-hosted
   más abajo vía @font-face (assets/fonts/*.woff2). El enqueue de Google Fonts
   se retiró de FrontendAssets para no depender de red externa.
   ============================================================ */

/* ============================================================================
 * Inter self-hosted (pesos 400/500/600/700, subsets latin + latin-ext).
 * Sustituye la dependencia de fonts.googleapis.com: los títulos ya no caen a
 * la serif por defecto del navegador cuando Google Fonts no está disponible
 * (entornos locales/offline, CSP, bloqueadores). Rutas relativas al CSS
 * (assets/css/ → ../fonts/). `font-display: swap` = texto visible ya con la
 * fallback sans-serif mientras carga el woff2.
 * ==========================================================================*/
@font-face {
	font-family: 'Inter';
	font-style: normal;
	font-weight: 400;
	font-display: swap;
	src: url('../fonts/inter-latin-400-normal.woff2') format('woff2');
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
	font-family: 'Inter';
	font-style: normal;
	font-weight: 400;
	font-display: swap;
	src: url('../fonts/inter-latin-ext-400-normal.woff2') format('woff2');
	unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
	font-family: 'Inter';
	font-style: normal;
	font-weight: 500;
	font-display: swap;
	src: url('../fonts/inter-latin-500-normal.woff2') format('woff2');
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
	font-family: 'Inter';
	font-style: normal;
	font-weight: 500;
	font-display: swap;
	src: url('../fonts/inter-latin-ext-500-normal.woff2') format('woff2');
	unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
	font-family: 'Inter';
	font-style: normal;
	font-weight: 600;
	font-display: swap;
	src: url('../fonts/inter-latin-600-normal.woff2') format('woff2');
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
	font-family: 'Inter';
	font-style: normal;
	font-weight: 600;
	font-display: swap;
	src: url('../fonts/inter-latin-ext-600-normal.woff2') format('woff2');
	unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
	font-family: 'Inter';
	font-style: normal;
	font-weight: 700;
	font-display: swap;
	src: url('../fonts/inter-latin-700-normal.woff2') format('woff2');
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
	font-family: 'Inter';
	font-style: normal;
	font-weight: 700;
	font-display: swap;
	src: url('../fonts/inter-latin-ext-700-normal.woff2') format('woff2');
	unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
	--surface-base:        #FFFFFF;
	--surface-raised:      #FAFAFA;
	--surface-sunken:      #F4F4F5;
	--surface-hover:       #F4F4F5;

	--border-subtle:       #EAEAEA;
	--border-default:      #D4D4D8;
	--border-strong:       #A1A1AA;

	--text-primary:        #09090B;
	--text-secondary:      #52525B;
	--text-tertiary:       #A1A1AA;
	--text-disabled:       #D4D4D8;
	--text-on-primary:     #FFFFFF;

	--brand-primary:       #6366F1;
	--brand-primary-hover: #4F46E5;
	--brand-primary-soft:  #EEF2FF;

	--success:             #10B981;
	--success-soft:        #ECFDF5;
	--warning:             #F59E0B;
	--warning-soft:        #FFFBEB;
	--danger:              #EF4444;
	--danger-soft:         #FEF2F2;
	--info:                #0EA5E9;
	--info-soft:           #F0F9FF;

	/* Acento coral (rediseño visual). Único color de marca de la nueva
	   dirección: hoy lo usa el sidebar (sitio activo) globalmente + el wizard
	   de generar artículo (objetivo seleccionado, total, botón Generar). Al
	   extender el rediseño a más pantallas, el resto consumirá estos tokens. */
	--nseo-coral:          #6366F1;
	--nseo-coral-hover:    #5558E8;
	--nseo-coral-soft:     rgba( 99, 102, 241, 0.06 );

	--shadow-sm: 0 1px 2px 0 rgba(0,0,0,0.04);
	--shadow-md: 0 4px 6px -1px rgba(0,0,0,0.04), 0 2px 4px -2px rgba(0,0,0,0.03);
	--shadow-lg: 0 10px 15px -3px rgba(0,0,0,0.05), 0 4px 6px -4px rgba(0,0,0,0.03);

	--space-1:   4px;
	--space-2:   8px;
	--space-3:   12px;
	--space-4:   16px;
	--space-5:   20px;
	--space-6:   24px;
	--space-8:   32px;
	--space-10:  40px;
	--space-12:  48px;
	--space-16:  64px;
	--space-20:  80px;

	--radius-sm:    6px;
	--radius-md:    8px;
	--radius-lg:    12px;
	--radius-xl:    16px;
	--radius-full:  9999px;
	--radius-pill:  4px; /* etiquetas/pills/badges: cuadrado de vértices ligeramente redondeados (afinable aquí) */

	--font-sans: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;

	--text-xs-size:   11px; --text-xs-lh:   16px;
	--text-sm-size:   13px; --text-sm-lh:   20px;
	--text-base-size: 14px; --text-base-lh: 21px;
	--text-md-size:   15px; --text-md-lh:   24px;
	--text-lg-size:   18px; --text-lg-lh:   28px;
	--text-xl-size:   22px; --text-xl-lh:   30px;
	--text-2xl-size:  28px; --text-2xl-lh:  36px;
	--text-3xl-size:  36px; --text-3xl-lh:  44px;

	--motion-hover: 200ms ease-out;
	--motion-focus: 150ms ease-in-out;

	/* Compensación dinámica para la admin bar de WP. Se sobreescribe a
	   32px (o 46px en mobile) sólo cuando el body lleva la clase
	   .admin-bar (es decir, sólo para operadores con manage_options). */
	--nseo-admin-bar-h: 0px;
}

body.admin-bar { --nseo-admin-bar-h: 32px; }
@media (max-width: 782px) {
	body.admin-bar { --nseo-admin-bar-h: 46px; }
}

/* ============================================================
   Reset mínimo (sólo en .nseo-frontend, no toca otras páginas)
   ============================================================ */
body.nseo-frontend {
	margin: 0;
	padding: 0;
	font-family: var(--font-sans);
	font-size: var(--text-base-size);
	line-height: var(--text-base-lh);
	color: var(--text-primary);
	background: var(--surface-base);
	-webkit-font-smoothing: antialiased;
}
body.nseo-frontend *,
body.nseo-frontend *::before,
body.nseo-frontend *::after { box-sizing: border-box; }
/*
 * Reset de links — separado en dos reglas por propiedad para controlar la
 * batalla de especificidades:
 *
 * - text-decoration en regla NORMAL (specificity 0,0,1,2). Necesita ganar
 *   ante hojas que WordPress pueda inyectar vía wp_head() (admin bar, core,
 *   tema), donde un `a { text-decoration: underline }` (0,0,0,1) bastaría
 *   para sobrescribir un reset en :where() (0,0,0,0).
 *
 * - color/transition en :where(), especificidad 0. Permite que cualquier
 *   componente con clase única (.nseo-btn--primary, .nseo-scope-toggle__item,
 *   etc.) gane sin !important ni prefijar selectores.
 *
 * Estado de reposo: SIN subrayado en ningún <a>. Sólo hover de links inline
 * (auth footer, párrafos de prosa) lleva subrayado — opt-in explícito por
 * componente (ver .nseo-auth__footer-links abajo).
 */
body.nseo-frontend a,
body.nseo-frontend a:hover,
body.nseo-frontend a:focus {
	text-decoration: none;
}
:where(body.nseo-frontend a) {
	color: var(--brand-primary);
	transition: color var(--motion-hover);
}
:where(body.nseo-frontend a):hover { color: var(--brand-primary-hover); }

/* Focus-visible queda con especificidad normal: aplica a TODOS los <a> + buttons. */
body.nseo-frontend a:focus-visible { outline: 2px solid var(--brand-primary); outline-offset: 2px; }
body.nseo-frontend .nseo-btn:focus-visible,
body.nseo-frontend button:focus-visible {
	outline: 2px solid var(--brand-primary);
	outline-offset: 2px;
}

/* El atributo `hidden` SIEMPRE gana. Footgun recurrente: una clase con
   `display: flex|block|…` tiene la misma especificidad que el `[hidden]` de UA
   y gana por orden de cascada → el elemento se ve aunque tenga `hidden`. En vez
   de parchear clase por clase con `.foo[hidden]{display:none}` (hay ~20 así en
   este archivo), se fija aquí de raíz: nada visible que lleve `hidden`. Auditado:
   ninguna regla muestra a propósito un `[hidden]` vía display, así que es seguro. */
[hidden] {
	display: none !important;
}

/*
 * Underline opt-in: SÓLO links inline en bloques de prosa.
 * Por ahora únicamente los del footer del login. Cualquier futuro bloque
 * de texto largo (descripción de Sitios, ayuda contextual…) tendrá que
 * añadirse explícitamente aquí o usar una clase utilitaria.
 */
.nseo-auth__footer-links a:hover { text-decoration: underline; }
body.nseo-frontend h1, body.nseo-frontend h2, body.nseo-frontend h3,
body.nseo-frontend p { margin: 0; padding: 0; }

/* ============================================================
   Auth layout — pantalla centrada (login, registro, recovery)
   ============================================================ */
/*
 * Body de pantallas auth: alineado arriba (no centrado vertical),
 * con padding-top generoso para que el wrapper empiece a ~96px del top.
 * Horizontalmente centrado.
 */
/*
 * Modifiers del body (auth/app) prefijados con body.nseo-frontend para subir
 * especificidad a (0,0,2,1) y ganar al reset body.nseo-frontend (0,0,1,1)
 * de las líneas ~90. Sin este prefijo el reset pisa padding y background
 * (observado en DevTools: las propiedades aparecían tachadas en la regla
 * del modifier). Aplica esta convención a cualquier futuro modifier
 * (body.nseo-frontend--app, --print, …) que tenga reglas propias.
 */
body.nseo-frontend.nseo-frontend--auth {
	min-height: 100vh;
	display: flex;
	justify-content: center;
	align-items: flex-start;
	background: var(--surface-raised);
	/* 200px superior (80 + 80 + 40) + compensación admin bar. */
	padding: calc(var(--space-20) + var(--space-20) + var(--space-10) + var(--nseo-admin-bar-h)) var(--space-4) var(--space-8);
}

/* Wrapper común: 440px de ancho, contiene header + card. */
.nseo-auth__wrapper {
	width: 100%;
	max-width: 440px;
}

/* Header FUERA de la card: logo + nombre del producto, centrados horizontalmente. */
.nseo-auth__header {
	display: flex;
	align-items: center;
	justify-content: center; /* Centrado horizontal dentro del wrapper. */
	gap: var(--space-3); /* 12px entre logo y nombre. */
	margin-bottom: var(--space-6); /* 24px de separación con la card. */
}
.nseo-auth__logo {
	width: 40px;
	height: 40px;
	background: var(--brand-primary);
	color: var(--text-on-primary);
	border-radius: var(--radius-md); /* 8px — cuadrado redondeado, no circular. */
	display: grid;
	place-items: center;
	font-weight: 700;
	font-size: var(--text-md-size);
}
.nseo-auth__product-name {
	font-size: var(--text-lg-size);
	line-height: var(--text-lg-lh);
	font-weight: 600;
	color: var(--text-primary);
}

.nseo-auth__card {
	width: 100%;
	max-width: 440px; /* Redundante con el wrapper, defensivo. */
	background: var(--surface-base);
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-xl);
	box-shadow: var(--shadow-md);
	padding: var(--space-10); /* 40px en las 4 direcciones. */
}

/* Título y subtítulo: alineados a la izquierda dentro de la card. */
.nseo-auth__title {
	text-align: left;
	font-size: var(--text-2xl-size);
	line-height: var(--text-2xl-lh);
	font-weight: 600;
	letter-spacing: -0.02em;
	margin-bottom: var(--space-3) !important; /* 12px hasta el subtítulo. */
}
.nseo-auth__subtitle {
	text-align: left;
	font-size: var(--text-base-size);
	line-height: var(--text-base-lh);
	color: var(--text-secondary);
	margin-bottom: var(--space-10); /* 40px hasta el primer campo del form. */
}

/* Footer links: alineados a la izquierda. */
.nseo-auth__footer-links {
	margin-top: var(--space-6); /* 24px desde el botón. */
	padding-top: var(--space-6); /* 24px sobre el primer link. */
	border-top: 1px solid var(--border-subtle);
	font-size: var(--text-sm-size);
	color: var(--text-secondary);
	text-align: left;
}
.nseo-auth__footer-links p {
	margin-bottom: var(--space-2); /* 8px entre líneas. */
}
.nseo-auth__footer-links p:last-child {
	margin-bottom: 0;
}
/*
 * Color brand para los <a> del footer del login. Specificity (0,0,2,1):
 * gana al reset color en :where() y a cualquier estilo de WP que
 * inyecte `a { color: ... }` con specificity (0,0,0,1) o (0,0,1,1).
 */
body.nseo-frontend .nseo-auth__footer-links a {
	color: var(--brand-primary);
}
body.nseo-frontend .nseo-auth__footer-links a:hover {
	color: var(--brand-primary-hover);
}


/* ============================================================
   App layout — sidebar 240px + main (sin chrome de wp-admin)
   ============================================================ */
.nseo-app {
	/* VIS: paleta de navegación (sidebar + topbar) sobre indigo sólido.
	   Definida aquí (ancestro común) para que sidebar y topbar la compartan. */
	--nseo-sidebar-bg: var(--brand-primary);
	--nseo-sidebar-item: #fff;
	--nseo-sidebar-dim: rgba(255, 255, 255, 0.70);
	--nseo-sidebar-hover: rgba(255, 255, 255, 0.18);
	--nseo-sidebar-active: rgba(255, 255, 255, 0.28);
	--nseo-sidebar-chip: rgba(255, 255, 255, 0.18);
	--nseo-sidebar-line: rgba(255, 255, 255, 0.18);
	display: grid;
	grid-template-columns: 240px 1fr;
	min-height: calc(100vh - var(--nseo-admin-bar-h));
	margin-top: var(--nseo-admin-bar-h);
}
@media (max-width: 960px) {
	.nseo-app { grid-template-columns: 1fr; }
	.nseo-sidebar { display: none; }
	.nseo-sidebar__inner { display: none; }
}

/* Sidebar */
.nseo-sidebar {
	/* VIS.2: menú en indigo sólido (vars en .nseo-app, compartidas con la topbar). */
	background: var(--nseo-sidebar-bg);
	border-right: 0;
	/* La columna del grid se estira a TODA la altura de la página (crezca lo que
	   crezca el contenido), así el color de fondo llega siempre hasta abajo. El
	   contenido del menú (brand+nav+footer) se queda pegado vía `__inner` sticky. */
}
.nseo-sidebar__inner {
	display: flex; flex-direction: column;
	padding: var(--space-5) 0;
	/* Menú FIJO respecto al viewport: se queda quieto mientras el contenido
	   central se desliza. `fixed` (no `sticky`) es inmune a overflow/transform
	   de ancestros, que rompían el sticky. El ancho lo hereda de la columna del
	   grid (240px, igual que .nseo-sidebar); el fondo de color lo pone la propia
	   columna .nseo-sidebar, que sí se estira a toda la altura de la página. */
	position: fixed;
	top: var(--nseo-admin-bar-h);
	left: 0;
	width: 240px;
	height: calc(100vh - var(--nseo-admin-bar-h));
	overflow: hidden;
}
.nseo-sidebar__brand {
	padding: 0 var(--space-5) var(--space-4);
	display: flex; align-items: center; gap: var(--space-3);
	font-weight: 600;
	font-size: var(--text-md-size);
	color: var(--nseo-sidebar-item);
}
.nseo-sidebar__brand-mark {
	width: 28px; height: 28px;
	background: #fff;
	color: var(--brand-primary);
	border-radius: var(--radius-md);
	display: grid; place-items: center;
	font-weight: 700;
}
.nseo-sidebar__nav {
	display: flex; flex-direction: column;
	padding: var(--space-2) var(--space-3);
	gap: 2px; flex: 1;
	/* Aire bajo el logo: baja el arranque de los items (~50px). margin-top (no
	   padding-top) para que el espacio quede FUERA del área scrollable y no se
	   pierda al hacer scroll; el logo (hermano superior) no se mueve. */
	margin-top: 50px;
	/* Marco fijo: si la lista de sitios es larga, el menú scrollea DENTRO del
	   sidebar (la marca queda fija arriba) sin mover topbar ni contenido. */
	min-height: 0;
	overflow-y: auto;
}
.nseo-sidebar__link {
	display: flex; align-items: center; gap: var(--space-3);
	padding: var(--space-2) var(--space-3);
	border-radius: var(--radius-md);
	color: var(--nseo-sidebar-dim);
	font-size: var(--text-sm-size);
	transition: background var(--motion-hover), color var(--motion-hover);
}
.nseo-sidebar__link:hover { background: var(--nseo-sidebar-hover); color: var(--nseo-sidebar-item); }
.nseo-sidebar__link.is-active {
	background: var(--nseo-sidebar-active);
	color: var(--nseo-sidebar-item);
	font-weight: 600;
}

/* Sidebar dinámico Fase 4.5.0a: lista de sitios + sub-items. */
.nseo-sidebar__sites {
	list-style: none; padding: 0; margin: 2px 0 var(--space-2);
	display: flex; flex-direction: column; gap: 2px;
}
.nseo-sidebar__site { padding: 0 var(--space-3); }
.nseo-sidebar__site-row {
	display: flex; align-items: center; gap: var(--space-3);
	padding: var(--space-2) var(--space-3);
	border-radius: var(--radius-md);
	font-size: var(--text-sm-size);
	color: var(--nseo-sidebar-item);
	width: 100%; text-align: left;
	background: transparent; border: 0; cursor: pointer;
	transition: background var(--motion-hover), color var(--motion-hover);
}
.nseo-sidebar__site-row:hover { background: var(--nseo-sidebar-hover); color: var(--nseo-sidebar-item); }
.nseo-sidebar__site-row--current {
	color: var(--nseo-sidebar-item);
	font-weight: 600;
	cursor: pointer;   /* SIDE-B: ahora es un toggle del submenú */
	background: var(--nseo-sidebar-active);
}
.nseo-sidebar__site-row--current:hover { background: var(--nseo-sidebar-active); }
/* SIDE-B: caret del sitio activo — rota suave; el submenú se oculta al plegar. */
.nseo-sidebar__site-caret { margin-left: auto; font-size: 10px; line-height: 1; transition: transform 150ms ease; }
.nseo-sidebar__site.is-collapsed .nseo-sidebar__site-caret { transform: rotate(-90deg); }
.nseo-sidebar__site.is-collapsed .nseo-sidebar__subitems { display: none; }
.nseo-sidebar__site-row--switch:disabled { opacity: 0.5; cursor: progress; }
.nseo-sidebar__site-favicon {
	display: grid; place-items: center;
	width: 22px; height: 22px;
	border-radius: var(--radius-sm);
	background: var(--nseo-sidebar-chip);
	border: 0;
	color: var(--nseo-sidebar-item);
	font-size: 11px; font-weight: 700;
	flex-shrink: 0;
}
.nseo-sidebar__site-name {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}
.nseo-sidebar__subitems {
	list-style: none; padding: 0; margin: 0 0 0 var(--space-5);
	display: flex; flex-direction: column; gap: 1px;
	border-left: 1px solid var(--nseo-sidebar-line);
}
.nseo-sidebar__subitem {
	display: block;
	padding: var(--space-2) var(--space-3);
	margin-left: -1px;
	border-left: 2px solid transparent;
	font-size: var(--text-sm-size);
	color: var(--nseo-sidebar-dim);
	border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
	transition: background var(--motion-hover), color var(--motion-hover), border-color var(--motion-hover);
}
.nseo-sidebar__subitem:hover { background: var(--nseo-sidebar-hover); color: var(--nseo-sidebar-item); }
.nseo-sidebar__subitem.is-active {
	border-left-color: var(--nseo-sidebar-item);
	color: var(--nseo-sidebar-item);
	background: var(--nseo-sidebar-active);
	font-weight: 600;
}

.nseo-sidebar__footer {
	border-top: 1px solid var(--nseo-sidebar-line);
	margin-top: auto;
	padding: var(--space-4) var(--space-5);
}
/* VIS.2: user-menu del footer sobre indigo (avatar compartido → scopeado aquí). */
.nseo-sidebar__footer .nseo-avatar { background: var(--nseo-sidebar-chip); color: var(--nseo-sidebar-item); }
.nseo-sidebar__footer .nseo-user-menu__name { color: var(--nseo-sidebar-item); }
.nseo-sidebar__footer .nseo-user-menu__email { color: var(--nseo-sidebar-dim); }

.nseo-user-menu {
	display: flex; align-items: center; gap: var(--space-3);
}
.nseo-user-menu__name {
	font-size: var(--text-sm-size);
	font-weight: 500;
	color: var(--text-primary);
}
.nseo-user-menu__email {
	font-size: var(--text-xs-size);
	color: var(--text-tertiary);
	overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
	max-width: 160px;
}

/* Avatar (compartido) */
.nseo-avatar {
	width: 32px; height: 32px;
	border-radius: var(--radius-full);
	background: var(--brand-primary);
	color: var(--text-on-primary);
	display: grid; place-items: center;
	font-weight: 600;
	font-size: var(--text-sm-size);
	flex-shrink: 0;
}

/* Main + Topbar */
.nseo-app__main {
	display: flex; flex-direction: column;
	min-width: 0;
	background: var(--surface-base);
	/* Fase 4.5.0c: el cromo deja de centrar su contenido en viewports
	 * anchos. Mismo padding-x fijo que ya usa `.nseo-detail-layout`
	 * (32px) — todo el contenido del cromo queda alineado a la izquierda
	 * del canvas, sin gutters dinámicos. Las pantallas con layout propio
	 * (article detail, post-analysis-show) siguen overriding estas vars
	 * para gestionar su grid 3-col interno. */
	--nseo-canvas-max: none;
	--nseo-canvas-padding-x: 32px;
}
.nseo-topbar {
	/* VIS: topbar en indigo SÓLIDO, igual que el sidebar (la "L" de marca).
	   Contenido en blanco/atenuado reusando las vars de navegación. */
	position: sticky;
	top: var(--nseo-admin-bar-h);
	z-index: 50;
	display: flex; align-items: center; justify-content: space-between;
	height: 56px;
	padding-top: 0;
	padding-bottom: 0;
	padding-left: var(--nseo-canvas-padding-x);
	padding-right: var(--nseo-canvas-padding-x);
	border-bottom: 0;
	background: var(--nseo-sidebar-bg);
	color: var(--nseo-sidebar-item);
}
.nseo-topbar__title {
	font-size: var(--text-lg-size);
	line-height: var(--text-lg-lh);
	font-weight: 600;
	letter-spacing: -0.01em;
}
.nseo-topbar__right { display: flex; align-items: center; gap: var(--space-3); }

/* VIS: contenido de la topbar sobre indigo (scopeado a .nseo-topbar; balance y
   botón ghost son compartidos, por eso no se tocan globalmente). */
.nseo-topbar .nseo-site-switcher {
	background: var(--nseo-sidebar-chip);
	border-color: var(--nseo-sidebar-line);
	color: var(--nseo-sidebar-item);
}
.nseo-topbar .nseo-site-switcher:hover { background: var(--nseo-sidebar-active); border-color: var(--nseo-sidebar-line); }
.nseo-topbar .nseo-site-switcher--empty { background: transparent; color: var(--nseo-sidebar-dim); }
.nseo-topbar .nseo-site-switcher__chevron { color: var(--nseo-sidebar-dim); }
.nseo-topbar .nseo-balance {
	background: var(--nseo-sidebar-chip);
	color: var(--nseo-sidebar-item);
}
.nseo-topbar .nseo-balance--empty { color: var(--nseo-sidebar-dim); }
.nseo-topbar .nseo-btn--ghost {
	background: transparent;
	border-color: var(--nseo-sidebar-line);
	color: var(--nseo-sidebar-item);
}
.nseo-topbar .nseo-btn--ghost:hover { background: var(--nseo-sidebar-hover); color: var(--nseo-sidebar-item); }
/* El desplegable del switcher es un popover sobre fondo claro → su contenido se
   mantiene OSCURO (resetea el color blanco heredado de la topbar). */
.nseo-topbar .nseo-site-switcher__dropdown { color: var(--text-primary); }

.nseo-balance {
	display: inline-flex; align-items: center;
	font-size: var(--text-sm-size);
	color: var(--text-secondary);
	padding: var(--space-2) var(--space-3);
	background: var(--surface-raised);
	border-radius: var(--radius-md);
}
.nseo-balance--empty { color: var(--text-tertiary); }

.nseo-app__content {
	flex: 1;
	padding-top: var(--space-8);
	padding-bottom: var(--space-8);
	padding-left: var(--nseo-canvas-padding-x);
	padding-right: var(--nseo-canvas-padding-x);
	width: 100%;
}

/* ============================================================
   Buttons (rescatado tal cual del design system)
   ============================================================ */
.nseo-btn {
	display: inline-flex; align-items: center; gap: var(--space-2);
	padding: var(--space-2) var(--space-4);
	border-radius: var(--radius-md);
	border: 1px solid transparent;
	font: inherit; font-weight: 500; font-size: var(--text-sm-size);
	cursor: pointer;
	transition: background var(--motion-hover), border-color var(--motion-hover), color var(--motion-hover);
	line-height: 1.2;
}
.nseo-btn--primary {
	background: var(--brand-primary);
	color: var(--text-on-primary);
}
.nseo-btn--primary:hover { background: var(--brand-primary-hover); color: var(--text-on-primary); }
.nseo-btn--ghost {
	background: var(--surface-base);
	border-color: var(--border-default);
	color: var(--text-primary);
}
.nseo-btn--ghost:hover { background: var(--surface-hover); }
.nseo-btn--danger {
	background: var(--danger);
	color: var(--text-on-primary);
}
.nseo-btn--danger:hover { background: #DC2626; }
/* BD.3: borrar — destructivo pero discreto (ghost con texto en rojo). */
.nseo-btn--danger-ghost {
	background: var(--surface-base);
	border-color: var(--border-default);
	color: var(--danger);
}
.nseo-btn--danger-ghost:hover { background: var(--danger-soft); border-color: var(--danger); }
.nseo-btn--block {
	width: 100%;
	justify-content: center;
	padding: var(--space-3) var(--space-4);
}
.nseo-btn[disabled],
.nseo-btn:disabled,
.nseo-site-switcher__option[disabled] {
	opacity: 0.6;
	cursor: not-allowed;
	pointer-events: none;
}

/* ============================================================
   Forms (rescatado tal cual)
   ============================================================ */
.nseo-form-field { margin-bottom: var(--space-4); }
.nseo-form-field__label {
	display: block;
	font-size: var(--text-sm-size);
	font-weight: 500;
	color: var(--text-primary);
	margin-bottom: var(--space-2);
}
.nseo-form-field__hint {
	font-size: var(--text-xs-size);
	color: var(--text-tertiary);
	margin-top: var(--space-1);
}
.nseo-field-error {
	font-size: var(--text-xs-size);
	color: var(--danger);
	margin-top: var(--space-1);
}
.nseo-input--invalid {
	border-color: var(--danger) !important;
	background: var(--danger-soft);
}
.nseo-input {
	width: 100%;
	padding: var(--space-3) var(--space-3);
	border: 1px solid var(--border-default);
	border-radius: var(--radius-md);
	background: var(--surface-base);
	font: inherit;
	font-size: var(--text-sm-size);
	color: var(--text-primary);
	transition: border-color var(--motion-focus), box-shadow var(--motion-focus);
}
.nseo-input:focus {
	outline: none;
	border-color: var(--brand-primary);
	box-shadow: 0 0 0 3px var(--brand-primary-soft);
}

/* ============================================================
   Notices (flash messages in-page, no wp-admin notices)
   ============================================================ */
.nseo-notice {
	padding: var(--space-3) var(--space-4);
	border-radius: var(--radius-md);
	margin-bottom: var(--space-5);
	font-size: var(--text-sm-size);
}
.nseo-notice--success { background: var(--success-soft); color: var(--success); }
.nseo-notice--danger  { background: var(--danger-soft);  color: var(--danger); }
.nseo-notice--info    { background: var(--info-soft);    color: var(--info); }

/* ============================================================
   Status badges — portado desde docs/internal/code-to-reuse/admin.css.
   Variantes: success | warning | danger | neutral. Tamaño compacto.
   ============================================================ */
.nseo-badge {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	padding: 2px var(--space-2);
	font-size: var(--text-xs-size);
	line-height: var(--text-xs-lh);
	font-weight: 500;
	border-radius: var(--radius-pill);
	border: 1px solid transparent;
	white-space: nowrap;
}
.nseo-badge--success {
	background: var(--success-soft);
	color: var(--success);
	border-color: rgba(16, 185, 129, 0.25);
}
.nseo-badge--warning {
	background: var(--warning-soft);
	color: var(--warning);
	border-color: rgba(245, 158, 11, 0.25);
}
.nseo-badge--danger {
	background: var(--danger-soft);
	color: var(--danger);
	border-color: rgba(239, 68, 68, 0.25);
}
.nseo-badge--neutral {
	background: var(--surface-sunken);
	color: var(--text-tertiary);
	border-color: var(--border-subtle);
}

/* Chip — usado en el panel de resultado de la prueba de conexión. */
.nseo-chip {
	display: inline-flex;
	align-items: center;
	padding: 2px var(--space-2);
	font-size: var(--text-xs-size);
	line-height: var(--text-xs-lh);
	font-weight: 500;
	color: var(--text-primary);
	background: var(--brand-primary-soft);
	border-radius: var(--radius-sm);
}

/* ============================================================
   Test connection result panel (en el form de Sitios).
   ============================================================ */
.nseo-test-result {
	margin-top: var(--space-4);
	padding: var(--space-3) var(--space-4);
	border-radius: var(--radius-md);
	border: 1px solid transparent;
	font-size: var(--text-sm-size);
}
.nseo-test-result--loading {
	background: var(--surface-sunken);
	color: var(--text-secondary);
	border-color: var(--border-subtle);
}
.nseo-test-result--success {
	background: var(--success-soft);
	color: var(--success);
	border-color: rgba(16, 185, 129, 0.25);
}
.nseo-test-result--danger {
	background: var(--danger-soft);
	color: var(--danger);
	border-color: rgba(239, 68, 68, 0.25);
}
.nseo-test-result__chips {
	margin-top: var(--space-2);
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-1);
}
.nseo-spinner {
	display: inline-block;
	width: 12px; height: 12px;
	border: 2px solid currentColor;
	border-right-color: transparent;
	border-radius: 50%;
	animation: nseo-spin 600ms linear infinite;
	vertical-align: -2px;
}
@keyframes nseo-spin { to { transform: rotate(360deg); } }

/* ============================================================
   Page header (h1 + actions + subtitle)
   ============================================================ */
.nseo-page-header {
	display: flex; align-items: flex-start; justify-content: space-between;
	gap: var(--space-4);
	margin-bottom: var(--space-6);
	/* Parche anti-"baile" (opción B): reserva el alto de la zona de cabecera
	   para que el contenido de abajo no salte al navegar entre pantallas con
	   cabeceras de distinto alto (unas con breadcrumb/subtítulo/meta, otras no).
	   Cubre el grupo dominante (breadcrumb + título + subtítulo): 32 (breadcrumb
	   20 lh + 12 mb) + 36 (título 2xl lh) + 24 (subtítulo 20 lh + 4 mt) = 92px.
	   Las pantallas con bloque "meta" (detalle, brand-style) quedan ~8px por
	   encima; remote-posts (subtítulo + meta) es la más alta. El fix de raíz
	   (partial único de page-header con slots) queda en backlog. */
	min-height: 92px;
}
.nseo-page-header__title {
	font-size: var(--text-2xl-size);
	line-height: var(--text-2xl-lh);
	font-weight: 600;
	letter-spacing: -0.01em;
}
/* Reserva el hueco del breadcrumb cuando está AUSENTE (dashboard, créditos):
   si el <h1> es el primer hijo de su contenedor (no hay breadcrumb antes), se
   le da el margen superior que ocuparía el breadcrumb (20 text-sm lh + 12
   space-3), para que el título arranque a la MISMA altura que en las pantallas
   que sí lo llevan. El header es flex (BFC) → este margen no colapsa hacia fuera. */
.nseo-page-header__title:first-child {
	margin-top: calc(var(--text-sm-lh) + var(--space-3));
}
.nseo-page-header__subtitle {
	font-size: var(--text-sm-size);
	color: var(--text-tertiary);
	margin-top: var(--space-1);
}

/* Meta inline bajo el título: badge + datos secundarios (estado,
   palabras, focus keyword, fechas…). Reutilizable — la usan
   `articles/detail` y `sites/analysis-detail`. Es un `<div>` para
   esquivar el reset agresivo `body.nseo-frontend p { margin: 0 }`
   (línea 147) sin necesitar `!important`. Cada hijo directo es un
   item; el `gap` los separa visualmente sin separadores manuales. */
.nseo-page-header__meta {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: var(--space-3);
	margin-top: var(--space-3);
	font-size: var(--text-sm-size);
	color: var(--text-secondary);
}

.nseo-page-header__actions {
	display: flex; align-items: center; gap: var(--space-3); flex-shrink: 0;
}
/* Ty: botón "Generar más temas" + subtexto de coste apilados (a la derecha). */
.nseo-page-header__actions--stack {
	flex-direction: column;
	align-items: flex-end;
	gap: var(--space-1);
}
.nseo-page-header__actions-hint {
	font-size: 11px;
	color: var(--text-tertiary);
}
/* Ty / D2: aviso blando al acumular muchas propuestas pendientes. */
.nseo-page-header__notice {
	font-size: var(--text-sm-size);
	color: var(--text-secondary);
	background: var(--surface-subtle, #f8fafc);
	border-left: 3px solid var(--warning, #d97706);
	padding: 2px var(--space-2);
	border-radius: var(--radius-sm);
}

/* ============================================================
   Sites grid (3 cols → 2 → 1)
   ============================================================ */
.nseo-sites-grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: var(--space-5);
}
@media (max-width: 1024px) {
	.nseo-sites-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 768px) {
	.nseo-sites-grid { grid-template-columns: 1fr; }
}

.nseo-site-card {
	background: var(--surface-base);
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-lg);
	padding: var(--space-5);
	display: flex; flex-direction: column; gap: var(--space-4);
	transition: border-color var(--motion-hover), box-shadow var(--motion-hover);
}
.nseo-site-card:hover {
	border-color: var(--border-default);
	box-shadow: var(--shadow-sm);
}
.nseo-site-card__head {
	display: flex; align-items: center; gap: var(--space-3);
}
.nseo-site-card__favicon {
	width: 48px; height: 48px;
	border-radius: var(--radius-md);
	display: grid; place-items: center;
	color: #fff; font-weight: 700;
	font-size: var(--text-md-size);
	flex-shrink: 0;
}
.nseo-site-card__id { min-width: 0; flex: 1; }
.nseo-site-card__title {
	font-size: var(--text-md-size);
	line-height: var(--text-md-lh);
	font-weight: 600;
}
.nseo-site-card__url {
	font-size: var(--text-sm-size);
	color: var(--text-secondary);
	overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.nseo-site-card__meta {
	font-size: var(--text-xs-size);
	color: var(--text-tertiary);
	text-transform: uppercase; letter-spacing: 0.04em;
	font-weight: 500;
}
.nseo-site-card__footer {
	display: flex; justify-content: space-between; align-items: center;
	border-top: 1px solid var(--border-subtle);
	padding-top: var(--space-3);
	margin-top: auto;
}

/* Card menu (⋯ dropdown) */
.nseo-card-menu { position: relative; }
.nseo-card-menu__trigger {
	background: none; border: 0; cursor: pointer;
	padding: 4px 10px;
	font-size: 18px; line-height: 1;
	color: var(--text-tertiary);
	border-radius: var(--radius-sm);
}
.nseo-card-menu__trigger:hover { background: var(--surface-hover); color: var(--text-primary); }
.nseo-card-menu__items {
	position: absolute; right: 0; top: calc(100% + var(--space-1));
	background: var(--surface-base);
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-md);
	box-shadow: var(--shadow-md);
	display: none; min-width: 160px;
	padding: var(--space-1);
	z-index: 30;
}
.nseo-card-menu.is-open .nseo-card-menu__items { display: block; }
.nseo-card-menu__items a,
.nseo-card-menu__items button {
	display: block; width: 100%; text-align: left;
	background: none; border: 0; cursor: pointer;
	padding: var(--space-2) var(--space-3);
	border-radius: var(--radius-sm);
	font: inherit; font-size: var(--text-sm-size);
	color: var(--text-primary);
	text-decoration: none;
}
.nseo-card-menu__items a:hover,
.nseo-card-menu__items button:hover { background: var(--surface-hover); }
.nseo-card-menu__items .is-danger { color: var(--danger); }
.nseo-card-menu__items .is-danger:hover { background: var(--danger-soft); color: var(--danger); }
.nseo-card-menu__delete { margin: 0; padding: 0; }

/* ============================================================
   Site switcher (topbar)
   ============================================================ */
.nseo-site-switcher-wrapper { position: relative; }
.nseo-site-switcher {
	display: inline-flex; align-items: center; gap: var(--space-2);
	padding: var(--space-1) var(--space-3);
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-md);
	background: var(--surface-base);
	cursor: pointer;
	font: inherit; font-size: var(--text-sm-size);
	color: var(--text-primary);
	transition: border-color var(--motion-hover);
	min-height: 36px;
}
.nseo-site-switcher:hover { border-color: var(--border-default); }
.nseo-site-switcher--empty {
	color: var(--text-tertiary); text-decoration: none;
}
.nseo-site-switcher--empty:hover { color: var(--brand-primary); }
.nseo-site-switcher--single { cursor: default; }
.nseo-site-switcher__favicon {
	width: 24px; height: 24px;
	border-radius: var(--radius-sm);
	display: grid; place-items: center;
	color: #fff; font-weight: 700;
	font-size: 11px;
	flex-shrink: 0;
}
.nseo-site-switcher__name {
	max-width: 200px;
	overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.nseo-site-switcher__chevron { font-size: 10px; color: var(--text-tertiary); }

.nseo-site-switcher__dropdown {
	position: absolute; top: calc(100% + var(--space-2)); left: 0;
	min-width: 280px;
	background: var(--surface-base);
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-md);
	box-shadow: var(--shadow-lg);
	padding: var(--space-1);
	z-index: 40;
}
.nseo-site-switcher__option {
	display: flex; align-items: center; gap: var(--space-2);
	width: 100%; text-align: left;
	background: none; border: 0; cursor: pointer;
	padding: var(--space-2) var(--space-3);
	border-radius: var(--radius-sm);
	font: inherit; font-size: var(--text-sm-size);
	color: var(--text-primary);
}
.nseo-site-switcher__option:hover { background: var(--surface-hover); }
.nseo-site-switcher__option.is-current {
	background: var(--brand-primary-soft);
	color: var(--brand-primary-hover);
	font-weight: 500;
}
.nseo-site-switcher__divider {
	height: 1px;
	background: var(--border-subtle);
	margin: var(--space-1) 0;
}
.nseo-site-switcher__manage {
	display: block;
	padding: var(--space-2) var(--space-3);
	font-size: var(--text-sm-size);
	color: var(--brand-primary);
	border-radius: var(--radius-sm);
}
.nseo-site-switcher__manage:hover { background: var(--surface-hover); }

/* ============================================================
   Scope toggle (Mis sitios / Todos los sitios)
   ============================================================ */
.nseo-scope-toggle {
	display: inline-flex;
	background: var(--surface-sunken);
	border-radius: var(--radius-md);
	padding: 2px;
}
.nseo-scope-toggle__item {
	padding: var(--space-1) var(--space-3);
	font-size: var(--text-sm-size);
	color: var(--text-secondary);
	border-radius: var(--radius-sm);
	transition: background var(--motion-hover), color var(--motion-hover);
}
.nseo-scope-toggle__item:hover { color: var(--text-primary); }
.nseo-scope-toggle__item.is-active {
	background: var(--surface-base);
	color: var(--brand-primary);
	box-shadow: var(--shadow-sm);
	font-weight: 500;
}

/* ============================================================
   Empty state
   ============================================================ */
.nseo-empty {
	display: flex; flex-direction: column; align-items: center;
	text-align: center;
	padding: var(--space-16) var(--space-6);
	background: var(--surface-raised);
	border: 1px dashed var(--border-default);
	border-radius: var(--radius-lg);
	max-width: 640px;
	margin: var(--space-8) auto 0;
}
.nseo-empty__icon {
	color: var(--text-tertiary);
	margin-bottom: var(--space-5); /* 20px — respiración con el título. */
}
/* Reset global `body.nseo-frontend h2/p { margin: 0 }` (línea 147) tiene
   especificidad (0,1,2) y pisa estas reglas a (0,1,0). Prefijamos con
   `body.nseo-frontend` para igualar especificidad y ganar por orden —
   sin esto el título y el lead del empty state aparecen pegados sin
   respiración. */
body.nseo-frontend .nseo-empty__title {
	font-size: var(--text-lg-size); font-weight: 500;
	color: var(--text-primary);
	margin-bottom: var(--space-3); /* 12px entre título y descripción. */
}
body.nseo-frontend .nseo-empty__lead {
	font-size: var(--text-sm-size); color: var(--text-secondary);
	max-width: 480px;
	margin: 0 auto var(--space-6); /* 24px hasta el CTA (o hasta el cierre del card). */
}

/* ============================================================
   Form extras (toggle avanzadas, acciones, has-error)
   ============================================================ */
.nseo-input.has-error,
.nseo-input.has-error:focus {
	border-color: var(--danger);
	box-shadow: 0 0 0 3px var(--danger-soft);
}
.nseo-form { max-width: 640px; }
.nseo-form-actions {
	display: flex; gap: var(--space-3);
	margin-top: var(--space-6);
}
.nseo-form-toggle {
	display: flex; align-items: center; gap: var(--space-2);
	font-size: var(--text-sm-size); color: var(--text-secondary);
	cursor: pointer;
}
.nseo-form-advanced {
	margin-top: var(--space-5);
	border-top: 1px dashed var(--border-subtle);
	padding-top: var(--space-4);
}
.nseo-form-advanced > summary {
	font-size: var(--text-sm-size); font-weight: 500;
	color: var(--text-secondary); cursor: pointer;
	margin-bottom: var(--space-3);
	list-style: none;
}
.nseo-form-advanced > summary::-webkit-details-marker { display: none; }
.nseo-form-advanced > summary::before {
	content: '▸ '; display: inline-block;
	transition: transform var(--motion-hover);
	margin-right: var(--space-1);
}
.nseo-form-advanced[open] > summary::before { transform: rotate(90deg); }

/* ============================================================
   Flash messages (fixed top-right, slide-in, auto-dismiss)
   ============================================================ */
.nseo-flash {
	position: fixed;
	top: calc(var(--nseo-admin-bar-h) + var(--space-4));
	right: var(--space-6);
	z-index: 100;
	min-width: 280px;
	max-width: 400px;
	padding: var(--space-3) var(--space-4);
	border-radius: var(--radius-md);
	font-size: var(--text-sm-size);
	box-shadow: var(--shadow-md);
	animation: nseo-flash-slide-in 200ms ease-out;
	transition: opacity 200ms ease-out, transform 200ms ease-out;
}
.nseo-flash.is-dismissed {
	opacity: 0;
	transform: translateY(-8px);
	pointer-events: none;
}
.nseo-flash--success { background: var(--success); color: #fff; }
.nseo-flash--danger  { background: var(--danger);  color: #fff; }
.nseo-flash--info    { background: var(--info);    color: #fff; }

@keyframes nseo-flash-slide-in {
	from { opacity: 0; transform: translateY(-12px); }
	to   { opacity: 1; transform: translateY(0); }
}

/* ============================================================
   Section title (reusable h2 dentro de páginas)
   ============================================================ */
.nseo-section-title {
	font-size: var(--text-md-size);
	line-height: var(--text-md-lh);
	font-weight: 600;
	color: var(--text-primary);
	margin: var(--space-8) 0 var(--space-4);
}

/* ============================================================
   Balance grid (página /creditos/)
   ============================================================ */
.nseo-balance-grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: var(--space-4);
	margin-bottom: var(--space-6);
}
@media (max-width: 768px) {
	.nseo-balance-grid { grid-template-columns: 1fr; }
}
.nseo-balance-card {
	background: var(--surface-base);
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-lg);
	padding: var(--space-5);
}
.nseo-balance-card__label {
	font-size: var(--text-xs-size);
	color: var(--text-tertiary);
	text-transform: uppercase;
	letter-spacing: 0.04em;
	font-weight: 500;
	margin-bottom: var(--space-2);
}
.nseo-balance-card__value {
	font-size: var(--text-2xl-size);
	line-height: var(--text-2xl-lh);
	font-weight: 600;
	color: var(--text-primary);
	letter-spacing: -0.01em;
}
.nseo-balance-card__hint {
	font-size: var(--text-sm-size);
	color: var(--text-secondary);
	margin-top: var(--space-2);
}
.nseo-progress {
	margin-top: var(--space-3);
	height: 6px;
	background: var(--surface-sunken);
	border-radius: var(--radius-full);
	overflow: hidden;
}
.nseo-progress__bar {
	height: 100%;
	background: var(--success);
	transition: width 200ms ease-out;
}
.nseo-progress.is-warn .nseo-progress__bar { background: var(--warning); }
.nseo-progress.is-danger .nseo-progress__bar { background: var(--danger); }

/* ============================================================
   Costes info + transactions history
   ============================================================ */
.nseo-cost-info {
	margin-bottom: var(--space-8);
}
.nseo-cost-table {
	width: 100%;
	border-collapse: collapse;
	font-size: var(--text-sm-size);
}
.nseo-cost-table td {
	padding: var(--space-3) var(--space-2);
	border-bottom: 1px solid var(--border-subtle);
}
.nseo-cost-table td:first-child { color: var(--text-secondary); }

.nseo-tx-history { margin-top: var(--space-4); }
/* La tabla de transacciones usa la base canónica (.nseo-table + clases
   __header-cell / __row / __cell). Aquí sólo viven los modificadores
   propios del historial: coloreado de la columna numérica según signo.
   Las reglas legacy de padding/border/hover de `.nseo-tx-table th,td` y
   `.nseo-tx-table tbody tr:hover` pisaban la base con especificidad
   (0,1,1) > (0,1,0) y se eliminaron — la tabla ahora hereda el mismo
   padding (16/18px), header (11px uppercase, text-secondary, 600) y
   hover (surface-sunken) que `articles/index` y `remote-posts/index`. */
.nseo-tx-table__num.is-positive { color: var(--success); }
.nseo-tx-table__num.is-negative { color: var(--danger); }
.nseo-pagination {
	display: flex; align-items: center; justify-content: center;
	gap: var(--space-3);
	margin-top: var(--space-4);
	font-size: var(--text-sm-size);
}

/* ============================================================
   Form sections colapsables (config SEO)
   ============================================================ */
.nseo-form-section {
	border: 1px solid var(--brand-primary);
	border-radius: var(--radius-lg);
	margin-bottom: var(--space-4);
	background: var(--surface-base);
}
/* Borde de acento idéntico en las dos pestañas de la pantalla del sitio:
   "Conexión y publicación" (.nseo-form) y "Marca y SEO" (.nseo-form--config).
   Ahora es el borde base de .nseo-form-section, así ambas se ven igual. */
.nseo-form-section > summary {
	padding: var(--space-4) var(--space-5);
	font-weight: 600;
	font-size: var(--text-md-size);
	cursor: pointer;
	list-style: none;
}
.nseo-form-section > summary::-webkit-details-marker { display: none; }
.nseo-form-section > summary::before {
	content: '▸';
	display: inline-block;
	margin-right: var(--space-2);
	color: var(--text-tertiary);
	transition: transform var(--motion-hover);
}
.nseo-form-section[open] > summary::before { transform: rotate(90deg); }
.nseo-form-section__body {
	padding: 0 var(--space-5) var(--space-5);
	border-top: 1px solid var(--border-subtle);
	padding-top: var(--space-5);
}

/* ── Config: mosaico de 2 columnas ──────────────────────────────
   Los apartados (ya tarjetas .nseo-form-section) se reparten en 2
   columnas tipo masonry. "Nombre del sitio" queda fuera de la rejilla,
   a ancho completo arriba. Las tarjetas son colapsables y de altura
   muy dispar: column-count empaqueta sin huecos (vs. grid alineado).
   El form de config se ensancha del cap global de 640px. */
.nseo-form--config { max-width: 1080px; }
.nseo-config-mosaic {
	column-count: 2;
	column-gap: var(--space-4);
}
.nseo-config-mosaic > .nseo-form-section {
	/* Evita que una tarjeta se parta entre columnas. margin-top:0 para que
	   la primera de cada columna no quede desalineada respecto a la otra. */
	break-inside: avoid;
	margin-top: 0;
}
@media (max-width: 960px) {
	.nseo-config-mosaic { column-count: 1; }
}

/* ============================================================
   CTAs (P1): repeater de la card "CTAs y conversión".
   ============================================================ */
.nseo-cta-list {
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
	margin-bottom: var(--space-3);
}
.nseo-cta-list__head,
.nseo-cta-row {
	display: grid;
	grid-template-columns: 1fr 1fr 8rem auto;
	gap: var(--space-2);
	align-items: center;
}
.nseo-cta-list__head {
	font-size: var(--text-sm-size);
	font-weight: 500;
	color: var(--text-tertiary);
}
.nseo-cta-row__remove {
	padding: 0 var(--space-3);
	line-height: 1;
}
.nseo-cta-row__error {
	grid-column: 1 / -1;
}
@media (max-width: 720px) {
	.nseo-cta-list__head { display: none; }
	.nseo-cta-row { grid-template-columns: 1fr; }
}

/* ============================================================
   CTAs (P3.6-A / B3): sección a ancho completo + tabla compartida
   (.nseo-cta-table) por la lista guardada y las propuestas.
   ============================================================ */
/* La card "CTAs y conversión" rompe el mosaico de 2 columnas y ocupa todo
   el ancho — la tabla guardada + la de propuestas aprovechan el espacio. */
.nseo-config-mosaic > .nseo-form-section--full {
	column-span: all;
}

.nseo-cta-proposals {
	margin-top: var(--space-3);
}
.nseo-cta-proposals__title {
	font-size: var(--text-base-size, 1rem);
	font-weight: 600;
	margin-bottom: var(--space-2);
}

/* Tabla compartida (B3): lista guardada y propuestas. */
.nseo-cta-table {
	width: 100%;
	border-collapse: collapse;
	margin-top: var(--space-2);
}
.nseo-cta-table th,
.nseo-cta-table td {
	text-align: left;
	padding: var(--space-2) var(--space-3);
	border-bottom: 1px solid var(--border-subtle);
	vertical-align: middle;
}
.nseo-cta-table th {
	font-size: var(--text-sm-size);
	font-weight: 500;
	color: var(--text-tertiary);
}
.nseo-cta-table__row {
	cursor: pointer;
}
.nseo-cta-table__row:hover,
.nseo-cta-table__row:focus-visible {
	background: rgba(0, 0, 0, 0.035);
	outline: none;
}
.nseo-cta-table__row--error {
	background: var(--danger-surface, rgba(220, 38, 38, 0.06));
}
.nseo-cta-table__url {
	color: var(--text-secondary);
	word-break: break-all;
}
.nseo-cta-table__url-empty {
	color: var(--text-tertiary);
	font-style: italic;
}
.nseo-cta-proposal__just {
	margin-top: var(--space-3);
	font-size: var(--text-sm-size);
	color: var(--text-secondary);
}

/* ============================================================
   Placeholder (en construcción)
   ============================================================ */
.nseo-placeholder {
	display: flex; align-items: center; justify-content: center;
	min-height: 60vh;
}
.nseo-placeholder__inner {
	display: flex; flex-direction: column; align-items: center;
	text-align: center; max-width: 480px;
}
.nseo-placeholder__title {
	font-size: var(--text-xl-size);
	line-height: var(--text-xl-lh);
	font-weight: 600;
	color: var(--text-primary);
	margin-bottom: var(--space-2) !important;
}
.nseo-placeholder__lead {
	font-size: var(--text-sm-size);
	color: var(--text-secondary);
}

/* Breadcrumb canónico (Fase 4.5.0f). Renderizado por
   `partials/breadcrumb.php` con `<nav aria-label>` — todas las pantallas
   del plugin lo usan. Separadores `›` van en spans con
   `aria-hidden="true"`. El último crumb lleva la modifier --current y
   `aria-current="page"` (más peso visual, sin link salvo edge case). */
.nseo-page__breadcrumb {
	color: var(--text-secondary);
	font-size: var(--text-sm-size);
	margin-bottom: var(--space-3);
}
.nseo-page__breadcrumb a { color: var(--brand-primary); text-decoration: none; }
.nseo-page__breadcrumb a:hover { text-decoration: underline; }
.nseo-page__breadcrumb-sep { margin: 0 var(--space-2); }
.nseo-page__breadcrumb-current { color: var(--text-primary); font-weight: 500; }
.nseo-page__breadcrumb-current[href]:hover { text-decoration: underline; }

.nseo-analysis-score {
	display: flex; gap: var(--space-5); align-items: center;
}
.nseo-analysis-score__ring {
	width: 120px; height: 120px;
	flex-shrink: 0;
	border-radius: var(--radius-lg);
	display: flex; flex-direction: column; align-items: center; justify-content: center;
	color: #ffffff;
	font-weight: 700;
}
.nseo-analysis-score__value { font-size: 36px; line-height: 1; }
.nseo-analysis-score__suffix { font-size: var(--text-sm-size); opacity: 0.9; }
.nseo-analysis-score__ring--red    { background: var(--danger);  }
.nseo-analysis-score__ring--amber  { background: var(--warning); }
.nseo-analysis-score__ring--green  { background: var(--success); }
.nseo-analysis-score__ring--pending { background: var(--text-secondary); }
.nseo-analysis-score__detail { flex: 1; }

/* Barra de potencial (iterativa): comunica el salto actual → potencial estimado
   y que queda recorrido hasta 100 (siguiente escalón, no techo). */
.nseo-potential {
	margin-top: var(--space-5);
}
.nseo-potential__copy {
	margin: 0 0 var(--space-2);
	font-size: var(--text-sm-size);
	color: var(--text-secondary);
}
.nseo-potential__bar {
	position: relative;
	height: 10px;
	margin: 0 0 var(--space-6);
	background: var(--surface-sunken);
	border-radius: var(--radius-full);
}
/* Tramo sólido = puntuación actual. */
.nseo-potential__fill {
	position: absolute;
	top: 0;
	bottom: 0;
	left: 0;
	background: var(--brand-primary);
	border-radius: var(--radius-full) 0 0 var(--radius-full);
}
/* Tramo proyectado = ganancia estimada con las recomendaciones (rayado, se lee
   como proyección, no como logro real). */
.nseo-potential__projected {
	position: absolute;
	top: 0;
	bottom: 0;
	background: repeating-linear-gradient(
		45deg,
		rgba(99, 102, 241, 0.45) 0 6px,
		rgba(99, 102, 241, 0.18) 6px 12px
	);
}
.nseo-potential__mark {
	position: absolute;
	top: calc(100% + 4px);
	transform: translateX(-50%);
	white-space: nowrap;
	font-size: var(--text-xs-size);
	font-weight: 600;
}
.nseo-potential__mark--current { color: var(--brand-primary); }
.nseo-potential__mark--potential { color: var(--text-secondary); }
.nseo-potential__hint {
	margin: 0;
	font-size: var(--text-xs-size);
	color: var(--text-tertiary);
}

/* Aviso discreto cuando el análisis es legado (sin scorecard): nota informativa,
   no error. Ocupa la zona donde iría el score, con CTA a Re-analizar. */
.nseo-analysis-legacy-note {
	display: flex; align-items: center; gap: var(--space-4); flex-wrap: wrap;
	background: var(--surface-sunken);
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-md);
	padding: var(--space-4);
	margin-bottom: var(--space-5);
}
.nseo-analysis-legacy-note__msg {
	flex: 1; min-width: 0; margin: 0;
	color: var(--text-secondary);
	font-size: var(--text-sm-size); line-height: var(--text-sm-lh);
}
.nseo-analysis-legacy-note__cta { flex-shrink: 0; }

.nseo-score-components { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: var(--space-4); }
.nseo-score-components__header { display: flex; justify-content: space-between; font-weight: 500; margin-bottom: var(--space-2); }
.nseo-progress { background: var(--bg-muted); border-radius: 999px; height: 8px; overflow: hidden; }
.nseo-progress__bar { background: var(--brand-primary); height: 100%; }
.nseo-score-components__notes { margin: var(--space-2) 0 0; color: var(--text-secondary); font-size: var(--text-sm-size); }

.nseo-suggestions { padding-left: var(--space-5); display: flex; flex-direction: column; gap: var(--space-2); }
.nseo-collapsible summary { cursor: pointer; }
.nseo-chip { display: inline-block; background: var(--bg-muted); border: 1px solid var(--border-subtle); border-radius: var(--radius-pill); padding: 2px 10px; margin: 0 4px 4px 0; font-size: var(--text-sm-size); }
.nseo-definition-list { display: grid; grid-template-columns: max-content 1fr; gap: var(--space-2) var(--space-4); margin: 0; }
.nseo-definition-list dt { color: var(--text-secondary); font-weight: 500; }
.nseo-definition-list dd { margin: 0; }
.nseo-card--info { border-left: 4px solid var(--brand-primary); }
.nseo-card--danger { border-left: 4px solid var(--danger); }
.nseo-card__hint { color: var(--text-secondary); font-style: italic; margin-top: var(--space-2); }

/* Badges de estado (algunos ya existen en sites; añadimos las variantes que faltan) */
.nseo-badge--info     { background: rgba(59,130,246,0.12); color: #1d4ed8; border: 1px solid rgba(59,130,246,0.3); }
.nseo-badge--warning  { background: rgba(217,119,6,0.12); color: #92400e; border: 1px solid rgba(217,119,6,0.3); }
.nseo-badge--neutral  { background: var(--bg-muted); color: var(--text-secondary); border: 1px solid var(--border-subtle); }

/* ============================================================
   Wizard de generación de artículo (Fase 3.2, mockup-fiel)
   ============================================================ */
.nseo-wizard-layout { display: grid; grid-template-columns: 1fr 360px; gap: var(--space-8); align-items: start; }
@media (max-width: 1100px) { .nseo-wizard-layout { grid-template-columns: 1fr; } }
.nseo-wizard-form { display: flex; flex-direction: column; gap: var(--space-8); min-width: 0; }

.nseo-section-card { padding: 0 0 0 42px; }
.nseo-section-head { margin-left: -42px; margin-bottom: var(--space-4); display: flex; gap: 14px; align-items: flex-start; }
.nseo-step-badge { width: 28px; height: 28px; flex-shrink: 0; border-radius: 999px; background: rgba(99,102,241,0.10); color: var(--brand-primary); display: inline-flex; align-items: center; justify-content: center; font-size: 13px; font-weight: 600; }
.nseo-step-badge--quality { background: rgba(16,185,129,0.10); color: var(--success); }
.nseo-section-eyebrow { font-size: 11px; font-weight: 600; color: var(--brand-primary); text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: 4px; }
.nseo-section-eyebrow--quality { color: var(--success); }
.nseo-section-title { font-size: 18px; line-height: 28px; font-weight: 600; margin: 0; }
.nseo-section-help { font-size: 13px; color: var(--text-secondary); margin: 4px 0 0; }

.nseo-field { margin-bottom: var(--space-5); }
.nseo-field-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4); margin-bottom: var(--space-5); }
@media (max-width: 720px) { .nseo-field-grid { grid-template-columns: 1fr; } }
.nseo-field-label { font-size: 13px; font-weight: 500; color: var(--text-primary); margin-bottom: var(--space-2); display: flex; align-items: center; gap: 6px; }
.nseo-field-label__optional { font-size: 11px; font-weight: 400; color: var(--text-tertiary); }
.nseo-field-meta { font-size: 12px; color: var(--text-tertiary); margin-top: 4px; text-align: right; }
.nseo-field-help { font-size: 12px; color: var(--text-secondary); margin: 4px 0 0; }

.nseo-input, .nseo-textarea { width: 100%; padding: 0 12px; height: 40px; font-family: inherit; font-size: 14px; color: var(--text-primary); background: #fff; border: 1px solid var(--border-default); border-radius: 8px; outline: none; transition: border-color 150ms ease, box-shadow 150ms ease; }
/* Los textareas de config usan .nseo-input (no .nseo-textarea), así que sin
   este reset heredaban el `height:40px` de la regla de arriba y quedaban
   atascados en una línea. Les damos el mismo trato que a .nseo-textarea:
   altura por `rows`, redimensionable en vertical. */
.nseo-textarea, textarea.nseo-input { height: auto; padding: 10px 12px; resize: vertical; min-height: 60px; line-height: 21px; }
.nseo-input:hover, .nseo-textarea:hover { border-color: var(--border-strong, #a1a1aa); }
.nseo-input:focus, .nseo-textarea:focus { border-color: var(--brand-primary); box-shadow: 0 0 0 3px rgba(99,102,241,0.20); }

/* Lang chips */
.nseo-lang-row { display: flex; gap: 8px; flex-wrap: wrap; }
.nseo-lang-chip { padding: 6px 12px; border: 1px solid var(--border-default); border-radius: var(--radius-pill); font-size: 13px; font-weight: 500; cursor: pointer; background: #fff; text-transform: uppercase; letter-spacing: 0.04em; }
.nseo-lang-chip.is-active { background: rgba(99,102,241,0.10); border-color: transparent; color: var(--brand-primary); }

/* Objective cards (2x2) */
.nseo-obj-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
.nseo-obj-card { text-align: left; border: 1px solid var(--border-subtle); border-radius: 12px; padding: 16px; cursor: pointer; background: #fff; transition: all 200ms ease; }
.nseo-obj-card:hover { border-color: var(--border-default); background: var(--bg-muted); }
.nseo-obj-card.is-active { border-color: var(--brand-primary); background: rgba(99,102,241,0.06); box-shadow: 0 0 0 1px var(--brand-primary); }
.nseo-obj-head { display: flex; align-items: center; gap: 10px; margin-bottom: 6px; }
.nseo-obj-title { font-size: 14px; font-weight: 600; }
.nseo-obj-desc { font-size: 12px; color: var(--text-secondary); line-height: 18px; }

/* Stepper */
.nseo-stepper-row { display: flex; align-items: center; justify-content: space-between; padding: var(--space-3) 0; gap: var(--space-4); }
.nseo-stepper-row + .nseo-stepper-row { border-top: 1px solid var(--border-subtle); }
.nseo-stepper-meta { flex: 1; min-width: 0; }
.nseo-stepper-label { font-size: 14px; font-weight: 500; }
.nseo-stepper-help { font-size: 12px; color: var(--text-secondary); margin-top: 2px; }
.nseo-stepper { display: inline-flex; align-items: center; border: 1px solid var(--border-default); border-radius: 8px; overflow: hidden; flex-shrink: 0; }
.nseo-stepper__btn { width: 32px; height: 32px; background: #fff; border: none; cursor: pointer; font-size: 16px; }
.nseo-stepper__btn:hover { background: var(--bg-muted); }
.nseo-stepper__btn:disabled { color: var(--text-tertiary); cursor: not-allowed; }
.nseo-stepper__value { min-width: 56px; text-align: center; font-variant-numeric: tabular-nums; font-weight: 500; padding: 0 8px; line-height: 32px; border-left: 1px solid var(--border-default); border-right: 1px solid var(--border-default); }

/* Switch */
.nseo-switch { position: relative; display: inline-block; width: 34px; height: 20px; background: var(--border-default); border-radius: 999px; cursor: pointer; border: none; padding: 0; flex-shrink: 0; }
.nseo-switch.is-on { background: var(--brand-primary); }
.nseo-switch__knob { position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; background: #fff; border-radius: 50%; box-shadow: 0 1px 2px rgba(0,0,0,0.15); transition: left 200ms ease; }
.nseo-switch.is-on .nseo-switch__knob { left: 16px; }
.nseo-switch:disabled { opacity: 0.6; cursor: not-allowed; }

/* Toggle row (extras) */
.nseo-toggle-row { display: flex; align-items: center; gap: 14px; padding: 14px 0; }
.nseo-toggle-row + .nseo-toggle-row { border-top: 1px solid var(--border-subtle); }
.nseo-toggle-row.is-disabled { opacity: 0.65; }
/* Nota "se mantienen las imágenes/el vídeo del original" (conserve por defecto). */
.nseo-conserve-note { font-size: 13px; line-height: 19px; color: var(--text-secondary); background: var(--success-soft); border-radius: var(--radius-sm); padding: 8px 12px; margin-top: 12px; }
.nseo-conserve-note strong { color: var(--text-primary); }
/* Variante warn: el elemento NO se conserva (enlaces internos) — rompe la expectativa. */
.nseo-conserve-note--warn { background: var(--warning-soft); border-left: 3px solid var(--warning); }
/* Intro de la sección de extras: el principio "conservas por defecto / regeneras con coste". */
.nseo-extras-intro { font-size: 13px; line-height: 20px; color: var(--text-secondary); margin: 0 0 16px; }
.nseo-toggle-meta { flex: 1; min-width: 0; }
.nseo-toggle-label-line { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.nseo-toggle-label { font-size: 14px; font-weight: 500; }
.nseo-cost-pill { font-size: 11px; font-weight: 500; color: var(--text-tertiary); background: var(--bg-muted); padding: 2px 6px; border-radius: var(--radius-pill); font-variant-numeric: tabular-nums; }
/* A3: pastilla "incluido · 0" para conservar medios (0 créditos). */
.nseo-cost-pill--free { color: #16794a; background: rgba(22,121,74,0.12); }
.nseo-soon-pill { font-size: 10px; font-weight: 600; letter-spacing: 0.04em; background: rgba(217,119,6,0.12); color: #92400e; padding: 2px 6px; border-radius: var(--radius-pill); text-transform: uppercase; }
/* 0.12.9: pastilla "Actualmente: N" que muestra el conteo actual del elemento
   (imágenes, FAQ, vídeos, fuentes...) al lado del coste de cada extra en el
   Paso 5 del wizard de curación. Fondo neutro más suave que .nseo-cost-pill
   para no competir con la información de precio. */
.nseo-current-pill { font-size: 11px; font-weight: 400; color: var(--text-secondary); background: transparent; border: 1px solid var(--border-subtle); padding: 2px 6px; border-radius: var(--radius-pill); font-variant-numeric: tabular-nums; }
/* 0.12.21: bloque de ordenación rápida en el listado de artículos publicados
   (/sitios/{id}/posts/). Dos botones que fijan orderby+orderdir preservando
   type y q. El activo se resalta con `.is-active`. */
.nseo-remote-posts-quicksort { display: flex; align-items: center; gap: 8px; }
.nseo-remote-posts-quicksort__label { font-size: 11px; letter-spacing: 0.06em; color: var(--text-tertiary); text-transform: uppercase; font-weight: 600; }
.nseo-remote-posts-quicksort .nseo-btn.is-active { background: var(--brand-100, rgba(124,58,237,0.10)); color: var(--brand-700, #6d28d9); border-color: var(--brand-300, rgba(124,58,237,0.30)); }
/* 0.12.24: cabecera de columnas fusionadas (Visibilidad/Aporte y Modificado/Publicación).
   Dos enlaces sortables apilados verticalmente en la misma celda. Cada línea es click
   independiente con su propia flecha. */
.nseo-table__header-cell--stacked { padding-top: 4px; padding-bottom: 4px; }
.nseo-table__header-stack { display: flex; flex-direction: column; gap: 2px; align-items: flex-end; }
.nseo-table__header-sort--stack { display: inline-flex; align-items: center; gap: 4px; padding: 1px 0; font-size: 11px; line-height: 1.15; text-decoration: none; color: inherit; }
.nseo-table__header-sort--stack.nseo-table__header-sort--secondary { color: var(--text-tertiary); font-weight: 400; }
.nseo-table__header-sort--stack .nseo-table__header-sort-label { white-space: nowrap; }
/* Celda del body con dos líneas apiladas: valor principal (fuerte) + secundario (débil).
   Mismo patrón visual que el título con la URL debajo. Alineación derecha en columnas
   numéricas. */
.nseo-table__cell--stacked { padding-top: 6px; padding-bottom: 6px; }
.nseo-table__cell-stack { display: flex; flex-direction: column; gap: 1px; align-items: flex-end; }
.nseo-table__cell-stack__primary { font-size: 13px; font-weight: 500; color: var(--text-primary); font-variant-numeric: tabular-nums; }
.nseo-table__cell-stack__secondary { font-size: 11px; font-weight: 400; color: var(--text-tertiary); font-variant-numeric: tabular-nums; }
/* 0.12.22: buscador + botones de ordenación en la misma línea. El buscador
   ocupa ~1/4 del ancho disponible; los botones flanquean a la derecha. Se
   colapsa a filas apiladas en móvil. */
.nseo-remote-posts-toolbar { display: flex; align-items: flex-end; gap: 16px; flex-wrap: wrap; margin: 8px 0 0; }
.nseo-remote-posts-toolbar .nseo-remote-posts-search { flex: 0 1 25%; min-width: 220px; margin: 0; }
.nseo-remote-posts-toolbar .nseo-remote-posts-quicksort { margin: 0; }
@media ( max-width: 720px ) {
	.nseo-remote-posts-toolbar .nseo-remote-posts-search { flex-basis: 100%; }
}
.nseo-toggle-help { font-size: 12px; color: var(--text-secondary); margin-top: 2px; }

/* Quality info */
.nseo-quality-info { display: flex; gap: 12px; align-items: flex-start; padding: 14px; background: rgba(16,185,129,0.08); border-radius: 10px; }
.nseo-quality-info__title { font-size: 13px; font-weight: 600; color: #065f46; display: flex; align-items: center; gap: 8px; }
.nseo-quality-info__text p { font-size: 12px; color: #047857; margin: 4px 0 0; }

/* Summary sticky */
.nseo-wizard-summary-sticky { position: sticky; top: 90px; }
.nseo-wizard-summary { background: #fff; border: 1px solid var(--border-subtle); border-radius: 14px; overflow: hidden; }
.nseo-wizard-summary__head { padding: 18px 20px 14px; border-bottom: 1px solid var(--border-subtle); }
.nseo-wizard-summary__eyebrow { font-size: 11px; font-weight: 500; color: var(--text-tertiary); text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 4px; }
.nseo-wizard-summary__title { font-size: 16px; font-weight: 600; }
.nseo-wizard-summary__body { padding: 16px 20px; }
.nseo-wizard-summary__fact { display: flex; justify-content: space-between; align-items: center; padding: 8px 0; font-size: 13px; }
.nseo-wizard-summary__fact + .nseo-wizard-summary__fact { border-top: 1px dashed var(--border-subtle); }
.nseo-wizard-summary__k { color: var(--text-secondary); }
.nseo-wizard-summary__v { font-weight: 500; }
.nseo-wizard-summary__cost { background: var(--bg-muted); padding: 16px 20px; }
.nseo-wizard-summary__cost-row { display: flex; justify-content: space-between; padding: 4px 0; font-size: 13px; color: var(--text-secondary); }
/* `display:flex` pisaba el `display:none` implícito del atributo `hidden` →
   las filas de extras (web search / imágenes / enlaces) se veían aunque el
   JS las marcara hidden. Bug ancestral de Fase 3.2/3.3c. */
.nseo-wizard-summary__cost-row[hidden] { display: none; }
.nseo-wizard-summary__cost-total { display: flex; justify-content: space-between; align-items: baseline; padding-top: 12px; margin-top: 8px; border-top: 1px solid var(--border-subtle); }
.nseo-wizard-summary__total { font-variant-numeric: tabular-nums; font-size: 24px; font-weight: 700; }
.nseo-wizard-summary__total small { font-size: 11px; font-weight: 500; color: var(--text-tertiary); margin-left: 4px; text-transform: uppercase; letter-spacing: 0.04em; }
.nseo-wizard-summary__balance-after { padding: 12px 0 0; font-size: 12px; color: var(--text-secondary); }
.nseo-wizard-summary__cta { padding: 16px 20px 20px; }
.nseo-wizard-summary__estimate { padding: 12px 20px; border-top: 1px solid var(--border-subtle); background: var(--bg-muted); font-size: 12px; color: var(--text-secondary); }
.nseo-btn--block { width: 100%; }
.nseo-cost-tag { font-size: 12px; font-weight: 500; opacity: 0.9; padding-left: 10px; border-left: 1px solid rgba(255,255,255,0.3); margin-left: 6px; }

/* Suggestions row */
.nseo-suggestions-row { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
/* Mismo bug latente: la fila de sugerencias se renderiza `hidden` hasta que
   llegan; sin esto, `display:flex` la dejaba como flex vacío ocupando layout. */
.nseo-suggestions-row[hidden] { display: none; }
.nseo-suggestion { padding: 6px 12px; background: var(--bg-muted); border: 1px solid var(--border-subtle); border-radius: 14px; font-size: 12px; color: var(--text-secondary); cursor: pointer; line-height: 1.35; }
.nseo-suggestion:hover { background: var(--bg-surface); color: var(--text-primary); }
/* Fase 3.5: chip enriquecido en 2 líneas (keyword arriba, métricas debajo). */
.nseo-suggestion__keyword { display: block; color: var(--text-primary); font-weight: 500; }
.nseo-suggestion__meta { display: block; margin-top: 2px; font-size: 11px; opacity: 0.75; }
.nseo-suggestion__dif--low { color: var(--state-success, #2e7d32); }
.nseo-suggestion__dif--mid { color: var(--state-warning, #b26a00); }
.nseo-suggestion__dif--high { color: var(--state-danger, #c62828); }

/* Error inline */
.nseo-error { color: var(--danger); font-size: 12px; margin-top: 8px; }

/* ============================================================
   Article detail (Fase 3.2)
   ============================================================ */
.nseo-card--center { text-align: center; padding: var(--space-8); }
.nseo-spinner { width: 48px; height: 48px; border: 4px solid var(--bg-muted); border-top-color: var(--brand-primary); border-radius: 999px; animation: nseo-spin 800ms linear infinite; margin: 0 auto var(--space-4); }
@keyframes nseo-spin { to { transform: rotate(360deg); } }

/* Stepper de fases de generación (v2): movimiento por estado real (barra + clases
   done/current desde el polling de generation.phase_key). Sobrio, sin animación
   decorativa; spinner 12px solo en la fase actual (única excepción de motion). */
.nseo-genprogress { max-width: 460px; margin: 0 auto; text-align: left; }
.nseo-genprogress .nseo-card__title { text-align: center; }
.nseo-genprogress__sub { font-size: var(--text-sm-size); line-height: var(--text-sm-lh); color: var(--text-secondary); text-align: center; margin: var(--space-1) 0 var(--space-5); }
.nseo-genprogress__bar { height: 6px; background: var(--surface-sunken); border-radius: var(--radius-full); overflow: hidden; margin-bottom: var(--space-2); }
.nseo-genprogress__fill { height: 100%; width: 0; background: var(--brand-primary); border-radius: var(--radius-full); transition: width 300ms ease-out; }
.nseo-genprogress__cap { display: flex; justify-content: space-between; font-size: var(--text-xs-size); line-height: var(--text-xs-lh); color: var(--text-tertiary); margin-bottom: var(--space-6); }
.nseo-genprogress__steps { list-style: none; margin: 0; padding: 0; }
.nseo-genstep { display: flex; gap: var(--space-3); align-items: flex-start; padding-bottom: var(--space-4); position: relative; }
.nseo-genstep:last-child { padding-bottom: 0; }
.nseo-genstep:not(:last-child)::before { content: ""; position: absolute; left: 13px; top: 28px; bottom: 0; width: 2px; background: var(--border-subtle); }
.nseo-genstep.is-done:not(:last-child)::before { background: var(--success); }
.nseo-genstep__icon { flex: 0 0 auto; width: 28px; height: 28px; border-radius: var(--radius-full); display: flex; align-items: center; justify-content: center; background: var(--surface-sunken); color: var(--text-tertiary); position: relative; z-index: 1; }
.nseo-genstep__icon svg { width: 16px; height: 16px; }
.nseo-genstep__glyph { display: inline-flex; align-items: center; }
.nseo-genstep__check { display: none; align-items: center; }
.nseo-genstep__label { padding-top: 5px; font-size: var(--text-base-size); color: var(--text-tertiary); }
.nseo-genstep__spin { display: none; width: 12px; height: 12px; border: 2px solid var(--brand-primary-soft); border-top-color: var(--brand-primary); border-radius: var(--radius-full); margin-left: 6px; vertical-align: -1px; animation: nseo-spin 700ms linear infinite; }
.nseo-genstep.is-done .nseo-genstep__icon { background: var(--success-soft); color: var(--success); }
.nseo-genstep.is-done .nseo-genstep__glyph { display: none; }
.nseo-genstep.is-done .nseo-genstep__check { display: inline-flex; }
.nseo-genstep.is-done .nseo-genstep__label { color: var(--text-secondary); }
.nseo-genstep.is-current .nseo-genstep__icon { background: var(--brand-primary-soft); color: var(--brand-primary); }
.nseo-genstep.is-current .nseo-genstep__label { color: var(--text-primary); font-weight: 500; }
.nseo-genstep.is-current .nseo-genstep__spin { display: inline-block; }

/* Fila de acciones de una tarjeta (rama de fallo: Reintentar / Borrar / Volver). */
.nseo-card__actions { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-4); }

.nseo-article-detail { display: flex; flex-direction: column; gap: 16px; }

/* ─────────────────────────────────────────────────────────────
   Article detail — three-column layout (Phase 3.7h)

   Grid de la pantalla detalle del artículo:
     [columna central fluida] [aside ayuda 320px]

   El sidebar global de la app (Dashboard / Sitios / Créditos) NO
   entra en este grid — vive en `.nseo-app` (cromo global) y queda
   intacto. Este grid es interno a `.nseo-app__content` para esta
   pantalla.

   Responsive: en viewports < 1180px, el aside se oculta y el centro
   ocupa todo el ancho.
   ─────────────────────────────────────────────────────────── */

.nseo-detail-layout {
	display: grid;
	grid-template-columns: 1fr 320px;
	gap: 32px;
	padding: 0 32px;
}

/* La pantalla detalle del artículo no usa el canvas centrado del
   cromo global: su grid de 3 columnas gestiona su propia
   distribución horizontal y el centrado del padre crea margen
   asimétrico al estar el sidebar izquierdo fuera del flujo. */
body.nseo-frontend .nseo-app__main:has(.nseo-detail-layout) {
	--nseo-canvas-max: none;
	--nseo-canvas-padding-x: 0;
	padding-left: 0;
	padding-right: 0;
}

.nseo-detail-layout__main {
	/* min-width: 0 permite que el contenido del centro se contraiga
	   cuando el aside reclama sus 320px — sin esto, el grid item
	   se desbordaría al ancho intrínseco de tablas y figures. */
	min-width: 0;
}

.nseo-detail-layout__help {
	border-left: 1px solid #e4e7ec;
	padding-left: 24px;
	min-width: 0;
}

.nseo-detail-layout__help-title {
	font-size: 13px;
	font-weight: 600;
	letter-spacing: -0.01em;
	color: #0f172a;
	margin: 0 0 18px 0;
	padding-bottom: 14px;
	border-bottom: 1px solid #e4e7ec;
}

.nseo-help-card {
	background: #ffffff;
	border: 1px solid #e4e7ec;
	border-radius: 8px;
	padding: 12px 14px;
	margin-bottom: 10px;
	transition: border-color 140ms ease;
}

.nseo-help-card:hover {
	border-color: #cbd5e1;
}

.nseo-help-card:last-of-type {
	margin-bottom: 0;
}

.nseo-help-card__title {
	font-size: 11.5px;
	font-weight: 500;
	color: #4338ca;
	margin: 0 0 8px 0;
	letter-spacing: 0.02em;
}

.nseo-help-card__body {
	font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
	font-size: 12.5px;
	font-weight: 400;
	line-height: 1.55;
	color: #475569;
	margin: 0;
}

@media (max-width: 1180px) {
	.nseo-detail-layout {
		grid-template-columns: 1fr;
	}
	.nseo-detail-layout__help {
		display: none;
	}
}

/* ─────────────────────────────────────────────────────────────
   Article detail — card chrome (Phase 3.7g)

   Cada sección del cromo (Metadata SEO, Verificación, Imágenes,
   Enlaces internos, Contenido, …) se renderiza dentro de un
   `<section class="nseo-card">`. Hasta 3.7g no había base styling
   para `.nseo-card` (sólo modifiers --info/--danger/--center), así
   que las secciones aparecían como bloques sin contención visual.
   Aquí añadimos card chrome: fondo blanco, borde sutil, padding,
   esquinas redondeadas.

   Scope estricto al wrapper `.nseo-article-detail` para no
   contaminar otros usos de `.nseo-card` (sites/index,
   sites/analysis-detail). El cuerpo del artículo dentro de
   `.nseo-article-content` mantiene su propio sistema (Fase 3.7d).
   ─────────────────────────────────────────────────────────── */

/* Canvas behind cards: gris muy suave para que las cards blancas
   destaquen. `:has()` scopea por presencia del wrapper → otras
   pantallas (dashboard, sites, settings) NO se ven afectadas. */
body.nseo-frontend:has(.nseo-article-detail) {
	background: #f8fafc;
}

.nseo-article-detail > .nseo-card,
.nseo-tabpanel > .nseo-card {
	position: relative;
	background: #fff;
	border: 1px solid #e4e7ec;
	border-radius: 12px;
	box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
	padding: 32px;
}

/* Restaurar acentos `--danger` / `--info` que el `border` shorthand
   de arriba pisaría. Mantenemos el border-left grueso de las
   variantes para que el card de fallo siga siendo identificable. */
.nseo-article-detail > .nseo-card.nseo-card--danger,
.nseo-tabpanel > .nseo-card.nseo-card--danger { border-left: 4px solid var(--danger); }
.nseo-article-detail > .nseo-card.nseo-card--info,
.nseo-tabpanel > .nseo-card.nseo-card--info   { border-left: 4px solid var(--brand-primary); }

/* Header del card unificado (Phase 3.7m).

   Layout flex con título a la izquierda y badge/acción a la derecha,
   alineados al centro vertical. Sustituye al patrón anterior de 3.7g
   (badge en `position: absolute`) — con un título de varias líneas
   ese anclaje al corner dejaba el badge desalineado respecto al
   centro vertical del título. Ahora ambos viven en el flow del flex
   y se centran entre sí.

   `gap: 24px` separa título y elemento derecho. `margin-bottom: 24px`
   da el aire al contenido del card que antes daba el `margin-bottom`
   del propio `.nseo-card__title` cuando el título estaba suelto. */
.nseo-card__header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 24px;
	margin-bottom: 24px;
}

/* Cuando el título vive dentro del header, no necesita margin propio:
   lo da el wrapper. `!important` para vencer al `margin: 0 0 16px 0`
   declarado en `.nseo-article-detail .nseo-card__title` (línea 1529).
   `flex: 1` permite que el título se expanda y empuje al badge/acción
   al borde derecho; `min-width: 0` permite truncado/wrap si el título
   es muy largo. */
.nseo-card__header .nseo-card__title {
	margin: 0 !important;
	flex: 1;
	min-width: 0;
}

/* `.nseo-card__action` ahora vive dentro del header flex, no como
   sibling absoluto del 3.7k. Anular el anclaje absoluto y dejarlo
   en flow. `flex-shrink: 0` evita que el botón se comprima cuando
   el título es largo. */
.nseo-card__header .nseo-card__action {
	position: static !important;
	top: auto !important;
	right: auto !important;
	flex-shrink: 0;
}

/* Card title: escala intermedia (26px) entre el page title del cromo
   y el H2 del cuerpo del artículo (20px). Crea la jerarquía
   editorial: page > card > article. */
.nseo-article-detail .nseo-card__title {
	font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
	font-size: 26px;
	font-weight: 600;
	line-height: 1.2;
	letter-spacing: -0.02em;
	color: #0f172a;
	margin: 0 0 16px 0;
}

/* Acción en la esquina superior derecha del card (Phase 3.7k).
   Mismo anclaje que el badge de verify/links pero con estilo
   "botón ghost compacto" para acciones interactivas. La card es
   `position: relative` (línea 1494), así que el botón se ancla a
   su esquina sin desbordar fuera. */
.nseo-card__action {
	position: absolute;
	top: 24px;
	right: 24px;
	display: inline-flex;
	align-items: center;
	padding: 6px 14px;
	border-radius: 8px;
	font-size: 13px;
	font-weight: 500;
	line-height: 1.4;
	background: transparent;
	border: 1px solid #cbd5e1;
	color: #475569;
	cursor: pointer;
	transition: background 140ms ease, border-color 140ms ease;
	white-space: nowrap;
}

.nseo-card__action:hover {
	background: #f1f5f9;
	border-color: #94a3b8;
}

/* Aire entre el título del card y el cuerpo del artículo. Más
   específico que el reset `> :first-child { margin-top: 0 }` del
   bloque de tipografía del artículo (3.7b/c) — ese reset
   garantiza que el H2 inicial no añada margen propio; este
   margen lo da el wrapper para que el control viva en la card,
   no en la tipografía editorial. */
.nseo-card .nseo-article-content {
	margin-top: 24px;
}

/* Fase detail-sticky: el toolbar deja de ser sticky. El rol de "acciones
 * siempre accesibles al scrollear" lo asume la barra compacta
 * `.nseo-detail-sticky__compact` (más abajo), que además incluye título y
 * badge de estado. El magic `top: 80px` de aquí estaba desincronizado de
 * la altura real de la topbar — al desaparecer el sticky, desaparece el
 * bug. */
.nseo-article-toolbar { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; background: #fff; padding: var(--space-3) 0; border-bottom: 1px solid var(--border-subtle); }

/* Fase detail-sticky: cabecera de detalle de draft en dos estados.
 *
 *   - Estado completo (tope de página): muestra `.nseo-page-header` como
 *     hoy, sin cambios. La barra compacta está oculta.
 *   - Estado compacto (post-umbral de scroll): el JS añade `.is-compact`
 *     al wrapper, que oculta el page-header y muestra la barra compacta
 *     pegada a la topbar.
 *
 * El `top` viene de `--nseo-detail-sticky-top`, una CSS variable que el JS
 * (article-detail.js) calcula al cargar como `getBoundingClientRect().bottom`
 * de `.nseo-topbar`. Se recalcula en resize debounced. La idea: una sola
 * fuente de verdad para la altura de la barra superior, sin magic numbers
 * que se desincronicen si la admin bar de WP cambia de tamaño. */
.nseo-detail-sticky {
	position: sticky;
	top: var(--nseo-detail-sticky-top, 88px);
	z-index: 40;             /* topbar es 50 — la compacta queda debajo. */
	background: var(--surface-base);
}
.nseo-detail-sticky__compact {
	display: none;
	align-items: center;
	gap: var(--space-3);
	height: 48px;
	padding-left: var(--nseo-canvas-padding-x);
	padding-right: var(--nseo-canvas-padding-x);
	border-bottom: 1px solid var(--border-subtle);
	background: var(--surface-base);
	opacity: 0;
	transform: translateY(-4px);
	transition: opacity 120ms ease, transform 120ms ease;
}
.nseo-detail-sticky.is-compact > .nseo-page-header {
	display: none;
}
.nseo-detail-sticky.is-compact > .nseo-detail-sticky__compact {
	display: flex;
	opacity: 1;
	transform: translateY(0);
}
.nseo-detail-sticky__title {
	flex: 1;
	min-width: 0;            /* permite que el flex item se encoja para que ellipsis funcione. */
	font-size: 1rem;
	line-height: 1.4;
	font-weight: 600;
	letter-spacing: -0.01em;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}
.nseo-detail-sticky__actions {
	display: flex;
	align-items: center;
	gap: var(--space-2);
	flex-shrink: 0;
}
/* Mobile: el título no cabe en 48px con badge + 3 botones; lo ocultamos
 * SÓLO en el estado compacto (el <h1> del estado completo se ve normal
 * en cualquier viewport — no se cuela un display:none global). */
@media (max-width: 720px) {
	.nseo-detail-sticky__compact > .nseo-detail-sticky__title {
		display: none;
	}
}
.nseo-article-toolbar__reason { font-size: 12px; color: var(--text-secondary); font-style: italic; }

/* Phase 3.7m — Altura uniforme para badge + botones del toolbar de
   estado. Aprobar/Rechazar/Revertir/Regenerar + badge "Aprobado · …"
   y "Rechazado · …" comparten min-height 36px y mismo padding
   horizontal/font-size para verse como un mismo set de chips de
   estado. No tocamos colores ni border-radius — el badge mantiene su
   pill (border-radius var --radius-full) y los botones su radius-md. */
.nseo-article-toolbar .nseo-btn,
.nseo-article-toolbar .nseo-badge {
	min-height: 36px;
	padding: 0 16px;
	line-height: 1;
	font-size: 14px;
}
.nseo-btn--success { background: var(--success); color: #fff; border: none; padding: 8px 16px; border-radius: 8px; font-weight: 500; cursor: pointer; }
.nseo-btn--success:hover { background: #059669; }

.nseo-edit-field { display: grid; grid-template-columns: 160px 1fr auto; gap: var(--space-3); align-items: start; padding: var(--space-3) 0; }
.nseo-edit-field + .nseo-edit-field { border-top: 1px dashed var(--border-subtle); }
.nseo-edit-field__label { font-size: 13px; font-weight: 500; color: var(--text-secondary); }
.nseo-edit-field__display { font-size: 14px; word-break: break-word; }
.nseo-edit-field__prefix { color: var(--text-tertiary); }

/* ─────────────────────────────────────────────────────────────
   Metadata SEO card — 2-column editorial layout (Phase 3.7j)

   Reorganiza los `.nseo-edit-field` del card "Metadata SEO" en un
   grid de 2 columnas con label (eyebrow uppercase) + botón Editar
   arriba y el value debajo. Solo aplica dentro de `.nseo-meta-grid`
   — el `.nseo-edit-field` legacy (label | value | botón en una
   única fila) sigue intacto para futuros consumidores.

   `!important` en color/font-size del label y value para vencer
   el reset interno `body.nseo-frontend *` y posibles overrides del
   tema WP host.
   ─────────────────────────────────────────────────────────── */
.nseo-meta-grid {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 24px;
}

.nseo-meta-grid .nseo-edit-field {
	display: flex;
	flex-direction: column;
	gap: 6px;
	min-width: 0;
	padding: 0;
}

.nseo-meta-grid .nseo-edit-field + .nseo-edit-field {
	border-top: none;
}

.nseo-meta-grid .nseo-edit-field--full {
	grid-column: 1 / -1;
}

.nseo-meta-grid .nseo-edit-field__header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
}

.nseo-meta-grid .nseo-edit-field__label {
	font-size: 11px !important;
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: #64748b !important;
}

.nseo-meta-grid .nseo-edit-field__display {
	font-size: 14px !important;
	line-height: 1.5;
	color: #0f172a !important;
	word-break: break-word;
}

/* Re-skin el botón Editar como text-link mientras está en modo
   lectura. Cuando el JS entra en modo edición añade
   `.nseo-btn--primary` al toggle (article-detail.js:121) — el
   `:not()` excluye ese estado para que "Guardar" recupere el
   estilo de botón primario sin conflicto. */
.nseo-meta-grid [data-nseo-edit-toggle]:not(.nseo-btn--primary) {
	background: transparent;
	border: none;
	padding: 4px 8px;
	font-size: 12px;
	font-weight: 500;
	color: #4338ca;
	border-radius: 6px;
	transition: background 140ms ease;
}

.nseo-meta-grid [data-nseo-edit-toggle]:not(.nseo-btn--primary):hover {
	background: #eef2ff;
}

@media (max-width: 720px) {
	.nseo-meta-grid {
		grid-template-columns: 1fr;
	}
}

/* ─────────────────────────────────────────────────────────────
   Metadata SEO — patrón del wizard "Cuéntanos sobre tu empresa"
   (article-metadata-seo.php, compartido Contenido + traducciones).

   Reutiliza las clases del wizard (.nseo-section-eyebrow, .nseo-form-field,
   __label, __hint). Solo añade: el valor estático con presencia, el
   reposicionamiento del "Editar" (reveal en hover/focus) y el grid de 2
   columnas. Escalera 4/8/16.
   ─────────────────────────────────────────────────────────── */
/* Cabecera de la card Metadata: fila con el rótulo "METADATA SEO" a la
   izquierda y la franja de acciones de estado a la derecha, mismo eje
   horizontal. En viewport estrecho los botones envuelven debajo del rótulo
   (flex-wrap) sin solaparse. */
.nseo-meta-card__head {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-2);
	margin-bottom: var(--space-4);
}
.nseo-meta-card__head .nseo-section-eyebrow {
	margin-bottom: 0; /* el margen inferior lo lleva ahora .nseo-meta-card__head */
}
/* 2 columnas: col1 [Título · Slug · Meta description] | col2 [Focus keyword ·
   Secondary keywords]. Columnas EXPLÍCITAS (no auto-flow) para que las dos
   keywords queden CONSECUTIVAS en la misma columna. `align-items:start` →
   cada columna toma su altura natural (no se estiran a la del vecino). */
.nseo-meta-card .nseo-meta-cols {
	display: grid;
	grid-template-columns: 1fr 1fr;
	column-gap: var(--space-8);
	align-items: start;
}
.nseo-meta-card .nseo-meta-col {
	display: flex;
	flex-direction: column;
	gap: var(--space-4);
	min-width: 0;
}
.nseo-meta-card .nseo-form-field {
	position: relative; /* ancla del "Editar" reveal */
	margin-bottom: 0;   /* el gap de la columna maneja la separación */
}
@media (max-width: 720px) {
	.nseo-meta-card .nseo-meta-cols {
		grid-template-columns: 1fr;
		row-gap: var(--space-4);
	}
}
/* Valor con presencia (estático). La versión editable usa
   .nseo-edit-field__display (clase que el JS de edición preserva al revertir,
   article-detail.js:166); la read-only usa .nseo-meta-value. Mismo aspecto. */
.nseo-meta-card .nseo-meta-value,
.nseo-meta-card .nseo-edit-field__display {
	font-size: var(--text-base-size);
	line-height: var(--text-base-lh);
	color: var(--text-primary);
	word-break: break-word;
}
.nseo-meta-card .nseo-edit-field__prefix {
	color: var(--text-tertiary);
}
.nseo-meta-card .nseo-meta-value--chips {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-2);
}
/* "Editar" (solo Contenido editable): sin ruido en reposo, se revela al pasar
   el ratón o al enfocar el campo por teclado (focus-within). En modo edición
   el JS añade .nseo-btn--primary (Guardar) → recupera el botón normal. */
.nseo-meta-card [data-nseo-edit-toggle]:not(.nseo-btn--primary) {
	position: absolute;
	top: 0;
	right: 0;
	opacity: 0;
	background: transparent;
	border: none;
	padding: var(--space-1) var(--space-2);
	font-size: var(--text-xs-size);
	font-weight: 500;
	color: var(--brand-primary);
	border-radius: var(--radius-sm);
	cursor: pointer;
	transition: opacity var(--motion-focus), background var(--motion-focus);
}
.nseo-meta-card .nseo-form-field:hover [data-nseo-edit-toggle]:not(.nseo-btn--primary),
.nseo-meta-card .nseo-form-field:focus-within [data-nseo-edit-toggle]:not(.nseo-btn--primary),
.nseo-meta-card [data-nseo-edit-toggle]:not(.nseo-btn--primary):focus-visible {
	opacity: 1;
	background: var(--surface-hover);
}

/* ─────────────────────────────────────────────────────────────
   Article content typography (Phase 3.7b — final, 3.7c reinforced)

   Sistema de tokens aislado bajo `.nseo-article-content`.
   Patrón replicado de business-analyzer (`--report-*` bajo
   `.ba-report-content`). Valores literales del design system
   de referencia, no aproximaciones.

   3.7c: añadido reset defensivo (`all: revert-layer`) y `!important`
   quirúrgico en las propiedades que el tema activo del WP host pisa
   (font-weight, font-size, line-height, margin, color). Sin
   `!important` el tema gana porque sus selectores son más globales
   (body, p genérico) y nuestro CSS plano no llega. Patrón estándar
   para plugins WP que necesitan tipografía consistente.

   NO usar fuera del cuerpo del artículo: chrome del plugin tiene su
   propio sistema de tokens.
   ─────────────────────────────────────────────────────────── */

/* Reset defensivo: neutraliza estilos heredados del tema WP activo.
   `revert-layer` revierte a la capa anterior (user-agent default),
   saltándose lo que haya añadido el tema. Nuestras reglas
   sobreescriben desde un baseline limpio. */
.nseo-article-content,
.nseo-article-content > *,
.nseo-article-content p,
.nseo-article-content h1,
.nseo-article-content h2,
.nseo-article-content h3,
.nseo-article-content h4,
.nseo-article-content h5,
.nseo-article-content h6,
.nseo-article-content ul,
.nseo-article-content ol,
.nseo-article-content li,
.nseo-article-content figure,
.nseo-article-content blockquote {
	all: revert-layer;
	box-sizing: border-box;
}

/* EEAT (E3): bloque "Fuentes" al final del artículo. Separador sutil del cuerpo. */
.nseo-article-content .nseo-sources {
	margin-top: var(--space-6, 2rem);
	padding-top: var(--space-4, 1rem);
	border-top: 1px solid var(--border-subtle, #e5e7eb);
}
.nseo-article-content .nseo-sources h2 {
	font-size: 1.1em;
}

.nseo-article-content {
	/* === Tokens propios del cuerpo del artículo === */

	--article-font:           'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;

	--article-text-xs:        0.8125rem;   /* 13px — figcaption */
	--article-text-sm:        0.9375rem;   /* 15px — h4, caption */
	--article-text-base:      0.9375rem;   /* 15px — lede editorial (Fase 3.7e) */
	--article-text-lg:        1.25rem;     /* 20px — h2 */
	--article-text-xl:        1.5rem;      /* 24px — h1 (si aparece) */

	--article-weight-regular:  400;
	--article-weight-semibold: 600;

	--article-color-text:        hsl(220, 25%, 15%);     /* headings, strong */
	--article-color-text-body:   hsl(220, 12%, 38%);     /* prose: párrafos, listas */
	--article-color-text-muted:  hsl(220, 12%, 38%);     /* captions, blockquote, figcaption */

	--article-space-2:  0.5rem;   /* 8px */
	--article-space-3:  0.75rem;  /* 12px */
	--article-space-4:  1rem;     /* 16px */
	--article-space-5:  1.5rem;   /* 24px */
	--article-space-6:  2rem;     /* 32px */

	/* === Base del wrapper === */

	font-family: var(--article-font) !important;
	font-size:   var(--article-text-base) !important;
	font-weight: var(--article-weight-regular) !important;
	line-height: 1.55 !important;
	color:       var(--article-color-text) !important;

	/* Fase 3.7h: max-width 720px removido. La columna ahora la marca el
	   grid de `.nseo-detail-layout` (centro + aside derecho). El body del
	   artículo ocupa el ancho completo de la columna central. */
}

/* Primer/último elemento no añade su propio margen */
.nseo-article-content > :first-child { margin-top: 0 !important; }
.nseo-article-content > :last-child  { margin-bottom: 0 !important; }

/* === Headings === */

.nseo-article-content h1 {
	font-family:  var(--article-font) !important;
	font-size:    var(--article-text-xl) !important;
	font-weight:  var(--article-weight-semibold) !important;
	line-height:  1.2 !important;
	color:        var(--article-color-text) !important;
	margin:       var(--article-space-6) 0 var(--article-space-4) !important;
}
.nseo-article-content h2 {
	font-family:  var(--article-font) !important;
	font-size:    var(--article-text-lg) !important;
	font-weight:  var(--article-weight-semibold) !important;
	line-height:  1.25 !important;
	color:        var(--article-color-text) !important;
	margin:       var(--article-space-6) 0 var(--article-space-4) !important;
}
.nseo-article-content h3 {
	font-family:  var(--article-font) !important;
	font-size:    var(--article-text-base) !important;
	font-weight:  var(--article-weight-semibold) !important;
	line-height:  1.35 !important;
	color:        var(--article-color-text) !important;
	margin:       var(--article-space-5) 0 var(--article-space-3) !important;
}
.nseo-article-content h4 {
	font-family:  var(--article-font) !important;
	font-size:    var(--article-text-sm) !important;
	font-weight:  var(--article-weight-semibold) !important;
	line-height:  1.4 !important;
	color:        var(--article-color-text) !important;
	margin:       var(--article-space-4) 0 var(--article-space-2) !important;
}

/* === Párrafos === */

.nseo-article-content p {
	margin:      0 0 var(--article-space-5) !important;   /* 24px abajo — clave para el aire entre párrafos */
	font-size:   var(--article-text-base) !important;
	font-weight: var(--article-weight-regular) !important;
	line-height: 1.55 !important;
	color:       var(--article-color-text-body) !important;
}

/* === Énfasis inline === */

/* strong vuelve al color oscuro de headings para crear contraste editorial
   sobre el body muted: prose en gris medio, entidades destacadas en negro. */
.nseo-article-content strong {
	font-weight: var(--article-weight-semibold) !important;
	color:       var(--article-color-text) !important;
}
.nseo-article-content em { font-style: italic !important; }

/* === Listas === */

.nseo-article-content ul,
.nseo-article-content ol {
	margin:       var(--article-space-3) 0 var(--article-space-5) !important;
	padding-left: var(--article-space-5) !important;
}
.nseo-article-content li {
	margin-bottom: var(--article-space-2) !important;
	line-height:   1.55 !important;
	font-size:     var(--article-text-base) !important;
	color:         var(--article-color-text-body) !important;
}
.nseo-article-content li:last-child {
	margin-bottom: 0 !important;
}

/* === Figures (de Phase 3.6 — imágenes IA) === */

.nseo-article-content figure {
	margin: var(--article-space-6) 0;
}
.nseo-article-content figure img {
	width: 100%;
	height: auto;
	border-radius: 8px;
	display: block;
}
.nseo-article-content figcaption {
	font-size:   var(--article-text-xs);
	font-style:  italic;
	color:       var(--article-color-text-muted);
	margin-top:  var(--article-space-2);
	text-align:  center;
}

/* === Vídeo YouTube embebido (YT.4) === */
/* YT.4 fix: el ratio 16:9 lo lleva el iframe INLINE (aspect-ratio + width:100% +
   height:auto), auto-contenido para que el WP cliente lo renderice 16:9 sin
   depender de su tema. Aquí (panel) la misma inline manda; solo añadimos
   cosmética (border-radius). NO ponemos sizing aquí para no entrar en conflicto
   con el inline del iframe (inline gana a la clase). */
.nseo-article-content .nseo-video-embed {
	width: 100%;
}
.nseo-article-content .nseo-video-embed iframe {
	border:        0;
	border-radius: 8px;
	display:       block;
}

/* === Blockquote === */

.nseo-article-content blockquote {
	margin: var(--article-space-5) 0;
	padding: var(--article-space-2) 0 var(--article-space-2) var(--article-space-4);
	border-left: 3px solid var(--article-color-text-muted);
	font-style: italic;
	color: var(--article-color-text-muted);
}

/* === Links === */

.nseo-article-content a {
	color: var(--accent, #4338ca);
	text-decoration: underline;
	text-underline-offset: 2px;
	text-decoration-thickness: 1px;
}
.nseo-article-content a:hover {
	text-decoration-thickness: 2px;
}

/* === Tabla (por si Sonnet la genera) === */

.nseo-article-content table {
	width: 100%;
	border-collapse: collapse;
	margin: var(--article-space-5) 0;
	font-size: var(--article-text-sm);
}
.nseo-article-content th,
.nseo-article-content td {
	padding: var(--article-space-3) var(--article-space-4);
	border-bottom: 1px solid hsl(220, 18%, 88%);
	text-align: left;
}
.nseo-article-content th {
	font-weight: var(--article-weight-semibold);
	background: hsl(220, 22%, 97%);
}

/* Outline funcional del editor inline (no es tipografía, pero comparte
   selector raíz — se mantiene aquí para que viva junto al wrapper que
   afecta). Usa el chrome accent del plugin, no los tokens --article-*. */
.nseo-article-content[contenteditable="true"] {
	outline: 2px dashed var(--brand-primary);
	padding: var(--space-3);
	border-radius: var(--radius-md);
}
.nseo-editor-toolbar { display: flex; gap: 4px; padding: var(--space-2); background: var(--bg-muted); border-radius: 8px 8px 0 0; border-bottom: 1px solid var(--border-subtle); margin-bottom: var(--space-2); }
.nseo-editor-toolbar button { padding: 4px 10px; background: #fff; border: 1px solid var(--border-default); border-radius: 4px; cursor: pointer; font-size: 13px; font-weight: 500; }
.nseo-editor-toolbar button:hover { background: var(--bg-surface); }

/* Tarjeta de contenido: barra Visual/HTML + Descargar/Editar. */
.nseo-content-toolbar {
	display: flex;
	align-items: center;
	gap: var(--space-3);
}
.nseo-content-tools {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
	margin-left: auto;
}
/* Conmutador segmentado Visual/HTML. */
.nseo-content-views {
	display: inline-flex;
	border: 1px solid var(--border-default);
	border-radius: var(--radius-sm);
	overflow: hidden;
}
.nseo-content-view-btn {
	border: 0;
	background: var(--surface-base);
	color: var(--text-secondary);
	padding: 4px 12px;
	font-size: var(--text-sm-size);
	font-weight: 500;
	cursor: pointer;
}
.nseo-content-view-btn + .nseo-content-view-btn { border-left: 1px solid var(--border-default); }
.nseo-content-view-btn.is-active { background: var(--brand-primary); color: #fff; }
/* Descargar deshabilitado en modo Visual (DOCX próximamente). */
.nseo-card__action.is-disabled { opacity: 0.5; cursor: not-allowed; }
/* Vista HTML (código fuente) + su editor (textarea). */
.nseo-article-html,
.nseo-article-html-editor {
	margin: 0;
	padding: var(--space-4);
	background: var(--bg-muted);
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-sm);
	font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
	font-size: 12px;
	line-height: 1.6;
	white-space: pre-wrap;
	word-break: break-word;
	max-height: 600px;
	overflow: auto;
}
.nseo-article-html-editor {
	width: 100%;
	min-height: 360px;
	resize: vertical;
	white-space: pre;
}

/* Bloque modal legacy eliminado: `.nseo-modal-backdrop` (con guion),
   `.nseo-modal-backdrop.is-open` y `.nseo-modal__actions` estaban muertos
   (0 usos en templates/JS). El `.nseo-modal { background; width:90%;
   max-width:480px; ... }` (estilo de "caja blanca" del patrón viejo) y el
   `.nseo-modal__title` legacy contaminaban la MISMA clase `.nseo-modal` que
   usan los modales vivos (`__dialog` en 2289, `__panel` en 3821), ambos
   `position:fixed; inset:0; flex center`. Como el cascade combina por
   propiedad, ese `width/max-width/background` sobrevivía y colapsaba el
   contenedor full-screen a una caja de 480px anclada a la izquierda → modal
   descentrado + overlay en franja izquierda. El centrado y el overlay a
   pantalla completa viven en los bloques canónicos (2289 / 3821). */

/* Reglas legacy de .nseo-table movidas al nuevo system (línea ~2498).
   Las viejas reglas `.nseo-table th, .nseo-table td` tenían especificidad
   (0,1,1), superior a la del nuevo `.nseo-table__cell` (0,1,0), lo que
   provocaba que el padding y el text-align legacy ganaran el cascade y
   el rediseño no se aplicara visualmente aunque las clases sí estuvieran
   presentes en el HTML. */

.nseo-btn--sm { padding: 4px 10px; font-size: 12px; }

/* ============================================================
   Fase 3.3 — Verificación, regenerate y audit trail
   ============================================================ */

/* "Próximamente" pill recolored a verde "Incluido" para el sello de calidad. */
.nseo-soon-pill--included { background: rgba(16,185,129,0.12); color: #047857; }

/* Cost preview placeholder rows en el wizard (extras "—"). */
.nseo-wizard-summary__cost-row--placeholder { color: var(--text-tertiary); opacity: 0.7; }

/* ------- Modal de regeneración ------- */
.nseo-modal { position: fixed; inset: 0; z-index: 9999; display: flex; align-items: center; justify-content: center; }
.nseo-modal[hidden] { display: none; }
.nseo-modal__backdrop { position: absolute; inset: 0; background: rgba(0,0,0,0.45); }
.nseo-modal__dialog {
	position: relative;
	background: var(--surface-base);
	border-radius: var(--radius-lg);
	box-shadow: 0 20px 50px rgba(0,0,0,0.18);
	width: min(520px, 92vw);
	max-height: 86vh;
	overflow: auto;
}
/* Modal de publicar más ancho (mismo tratamiento que el modal "Confirmar
   curación", 51ea862): tiene muchos campos (estado, fecha, autor, plantilla,
   categorías, tags, traducciones). Scopeado por su data-attr para no tocar el
   520px genérico de los demás `__dialog`. */
.nseo-modal[data-nseo-publish-modal] .nseo-modal__dialog {
	width: min(820px, 92vw);
}
.nseo-modal__header { display: flex; align-items: center; justify-content: space-between; padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--border-subtle); }
.nseo-modal__header h2 { margin: 0; font-size: 18px; }
.nseo-modal__close { background: transparent; border: none; font-size: 22px; cursor: pointer; color: var(--text-secondary); line-height: 1; }
.nseo-modal__body { padding: var(--space-5); display: flex; flex-direction: column; gap: var(--space-3); }
.nseo-modal__cost { background: var(--surface-sunken); padding: var(--space-3); border-radius: var(--radius-md); }
.nseo-modal__cost strong { color: var(--text-primary); }
.nseo-modal__cost-breakdown { color: var(--text-secondary); font-size: 12px; }
.nseo-modal__toggle { display: flex; align-items: center; gap: var(--space-2); cursor: pointer; }
.nseo-modal__overrides { display: flex; flex-direction: column; gap: var(--space-3); border: 1px solid var(--border-subtle); padding: var(--space-3); border-radius: var(--radius-md); }
.nseo-modal__overrides label { display: flex; flex-direction: column; gap: var(--space-1); font-size: 13px; }
/* P3.5b: selector de idiomas destino del modal de traducción. */
.nseo-modal__langs { display: flex; flex-direction: column; gap: var(--space-2); border: 1px solid var(--border-subtle); padding: var(--space-3); border-radius: var(--radius-md); margin: 0; }
.nseo-modal__langs-legend { font-size: 13px; font-weight: 600; color: var(--text-secondary); padding: 0; }
.nseo-modal__lang { display: flex; align-items: center; gap: var(--space-2); cursor: pointer; font-size: 14px; }
/* P3.5b: idioma ya traducido → fila atenuada, no marcable, con enlace a la traducción. */
.nseo-modal__lang--done { cursor: default; color: var(--text-secondary); }
.nseo-modal__lang--done input { cursor: default; }
.nseo-modal__lang-note { font-size: 12px; color: var(--text-tertiary, var(--text-secondary)); }
/* B4: nota de un idioma desactualizado (re-traducir reemplaza) — ámbar de atención. */
.nseo-modal__lang-note--stale { color: #b45309; }
.nseo-modal__lang-link { margin-left: auto; font-size: 13px; color: var(--brand-primary); text-decoration: none; }
.nseo-modal__lang-link:hover { text-decoration: underline; }
/* P4: badge "sin aprobar" en una traducción completed del checklist de publicar. */
.nseo-modal__lang-badge { margin-left: auto; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .02em; color: #b45309; background: #fef3c7; border-radius: var(--radius-sm, 4px); padding: 1px 6px; }
/* P4: resumen por idioma del publish-set async (✓ publicada / ✗ error / … pendiente). */
.nseo-publish-set-result { list-style: none; margin: var(--space-2) 0; padding: 0; display: flex; flex-direction: column; gap: 4px; font-size: 13px; }
.nseo-publish-set-result li.is-ok { color: var(--success, #15803d); }
.nseo-publish-set-result li.is-error { color: var(--danger, #b91c1c); }
.nseo-publish-set-result li.is-pending { color: var(--text-secondary); }

/* (c) Panel de estado del modal de publicar: el JS añade is-publishing al dialog,
   que oculta el formulario + footer y muestra solo el panel (publicando/resultado),
   para que el éxito sea siempre visible sin scroll. */
.nseo-modal__dialog.is-publishing .nseo-modal__body > :not([data-nseo-publish-panel]) { display: none !important; }
.nseo-modal__dialog.is-publishing .nseo-modal__footer { display: none; }
.nseo-publish-panel { display: flex; flex-direction: column; gap: var(--space-3); }
.nseo-publish-panel__publishing {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--space-2);
	padding: var(--space-6) 0;
	font-size: 14px;
	color: var(--text-secondary);
}
.nseo-publish-panel__head { display: flex; align-items: center; gap: var(--space-2); font-size: 16px; color: var(--text-primary); }
.nseo-publish-panel__check { font-size: 24px; line-height: 1; }
.nseo-publish-panel__head.is-ok .nseo-publish-panel__check { color: #10b981; }
.nseo-publish-panel__head.is-error .nseo-publish-panel__check { color: #ef4444; }
.nseo-publish-panel__error { margin: 0; font-size: 13px; color: #b91c1c; }
.nseo-publish-panel__actions { display: flex; justify-content: flex-end; gap: var(--space-2); margin-top: var(--space-2); }
.nseo-modal__overrides input, .nseo-modal__overrides textarea { padding: 8px 10px; border: 1px solid var(--border-default); border-radius: 8px; font: inherit; }
.nseo-modal__footer { display: flex; gap: var(--space-2); justify-content: flex-end; padding: var(--space-4) var(--space-5); border-top: 1px solid var(--border-subtle); }

/* ------- Modal de publicación al WP cliente (Fase 5A.4) ------- */
/* Badge: estado terminal "publicado en cliente". Mismo lenguaje visual que
   --success pero con tonalidad propia para que la transición approved →
   published sea reconocible de un vistazo desde el listado. */
.nseo-badge--published {
	background: rgba(59, 130, 246, 0.12);
	color: #1d4ed8;
	border-color: rgba(59, 130, 246, 0.3);
}
/* Aviso destacado dentro de la modal. Variante --danger para el caso
   curación (sobreescritura del post original); base neutra para `new`. */
.nseo-publish-warning {
	padding: var(--space-3);
	border-radius: var(--radius-md);
	background: var(--surface-sunken);
	border-left: 3px solid var(--border-default);
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
}
.nseo-publish-warning--danger {
	background: rgba(217, 119, 6, 0.08);
	border-left-color: #d97706;
}
.nseo-publish-warning strong { color: var(--text-primary); }
.nseo-publish-warning p { margin: 0; font-size: 13px; color: var(--text-secondary); }
.nseo-publish-warning__safety { font-size: 12px; color: var(--text-tertiary); }
.nseo-publish-warning__target { font-size: 13px; }
.nseo-publish-warning__target a { color: var(--text-primary); text-decoration: none; font-weight: 500; }
.nseo-publish-warning__target a:hover { text-decoration: underline; }
.nseo-publish-warning__target code { background: var(--surface-sunken); border-radius: var(--radius-sm); padding: 1px 5px; }
/* Selector de status remoto: dos opciones tipo "card radio". */
.nseo-publish-status { border: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.nseo-publish-status legend { font-size: 13px; font-weight: 500; color: var(--text-primary); margin-bottom: var(--space-1); padding: 0; }
.nseo-publish-status__option {
	display: flex;
	gap: var(--space-3);
	align-items: flex-start;
	padding: var(--space-3);
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-md);
	cursor: pointer;
}
.nseo-publish-status__option:hover { background: var(--surface-hover); }
.nseo-publish-status__option input[type="radio"] { margin-top: 3px; }
.nseo-publish-status__option strong { display: block; font-size: 14px; color: var(--text-primary); }
.nseo-publish-status__option small { display: block; font-size: 12px; color: var(--text-secondary); margin-top: 2px; }
.nseo-publish-status__option--locked { opacity: 0.6; cursor: not-allowed; }
.nseo-publish-status__option--locked:hover { background: transparent; }
/* Bloque de fecha programada (P1): espeja el patrón de .nseo-publish-status
   (fieldset reset + legend) para que se vea como un bloque más del modal. El
   <input type="datetime-local"> usa .nseo-input (ya estilado globalmente). */
.nseo-publish-schedule { border: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.nseo-publish-schedule legend { font-size: 13px; font-weight: 500; color: var(--text-primary); margin-bottom: var(--space-1); padding: 0; }
.nseo-publish-schedule__label { display: block; font-size: 14px; color: var(--text-primary); }
.nseo-publish-schedule__hint { font-size: 12px; color: var(--text-secondary); margin: 0; }

/* Jerarquía: los encabezados de sección (legends) del modal de publicar deben
   pesar al menos como las etiquetas de campo que contienen (que son 14px). Sin
   esto, los legends a 13px/500 se veían MÁS pequeños que sus propios campos
   (ej. "¿Cuándo se publica?" < "Fecha y hora"). Scopeado al modal de publicar. */
.nseo-modal[data-nseo-publish-modal] fieldset legend {
	font-size: 14px;
	font-weight: 600;
}

/* Categorías en columnas (el modal es ancho): grid responsive en vez de lista
   vertical larga. auto-fill + minmax → 2-3 columnas según ancho, 1 en estrecho. */
.nseo-publish-taxonomy__checklist {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
	gap: var(--space-1) var(--space-4);
}
.nseo-publish-taxonomy__checkbox {
	display: flex;
	align-items: center;
	gap: var(--space-2);
}
/* Jerarquía con aire en la tarjeta "Categorías y tags": título (legend 14px/600)
   > subtítulos ("Categorías"/"Tags", 13px/600) > contenido, con separación entre
   niveles y entre el bloque Categorías y el de Tags. */
.nseo-modal[data-nseo-publish-modal] .nseo-publish-taxonomy legend {
	margin-bottom: var(--space-3); /* título → primer subtítulo */
}
.nseo-publish-taxonomy__group + .nseo-publish-taxonomy__group {
	margin-top: var(--space-4); /* bloque Categorías → bloque Tags */
}
.nseo-publish-taxonomy__label {
	display: block;
	font-size: 13px;
	font-weight: 600;
	color: var(--text-primary);
	margin-bottom: var(--space-2); /* subtítulo → su contenido */
}
.nseo-publish-taxonomy__hint {
	font-size: 12px;
	color: var(--text-secondary);
	margin: var(--space-2) 0 0; /* contenido → hint */
}
/* Bloque de autor (P2): mismo patrón de fieldset/legend; el <select> usa
   .nseo-input (estilado globalmente). */
.nseo-publish-author { border: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.nseo-publish-author legend { font-size: 13px; font-weight: 500; color: var(--text-primary); margin-bottom: var(--space-1); padding: 0; }
.nseo-publish-author__hint { font-size: 12px; color: var(--text-secondary); margin: 0; }
/* Bloque de plantilla (P3): mismo patrón; el input usa .nseo-input. */
.nseo-publish-template { border: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.nseo-publish-template legend { font-size: 13px; font-weight: 500; color: var(--text-primary); margin-bottom: var(--space-1); padding: 0; }
.nseo-publish-template__hint { font-size: 12px; color: var(--text-secondary); margin: 0; }
/* Error inline tras un POST fallido. */
.nseo-publish-error {
	padding: var(--space-3);
	border-radius: var(--radius-md);
	background: rgba(239, 68, 68, 0.08);
	color: #b91c1c;
	border: 1px solid rgba(239, 68, 68, 0.25);
	font-size: 13px;
}
/* Bloque de imágenes locales en la modal (Fase 5B.4). Dos radios mutuamente
   excluyentes: sync (default, neutro) vs strip (fallback Fase 5A, ámbar). */
.nseo-publish-images { border: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.nseo-publish-images legend { font-size: 13px; font-weight: 500; color: var(--text-primary); margin-bottom: var(--space-1); padding: 0; }
.nseo-publish-images__option {
	display: flex;
	gap: var(--space-3);
	align-items: flex-start;
	padding: var(--space-3);
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-md);
	cursor: pointer;
}
.nseo-publish-images__option:hover { background: var(--surface-hover); }
.nseo-publish-images__option input[type="radio"] { margin-top: 3px; }
.nseo-publish-images__option strong { display: block; font-size: 14px; color: var(--text-primary); }
.nseo-publish-images__option small { display: block; font-size: 12px; color: var(--text-secondary); margin-top: 2px; }
.nseo-publish-images__option--fallback {
	border-color: rgba(217, 119, 6, 0.3);
	background: rgba(217, 119, 6, 0.04);
}
.nseo-publish-images__preview {
	margin: 0;
	padding: var(--space-2) var(--space-3);
	font-size: 12px;
	color: var(--text-secondary);
	background: var(--surface-sunken);
	border-radius: var(--radius-sm);
	border-left: 2px solid var(--border-default);
}
/* Aviso "esto puede tardar" mientras corre el publish. El timing real es
   6s por imagen subida — con 3-4 imágenes la barra puede tardar 20-30s. */
.nseo-publish-progress {
	display: flex;
	align-items: center;
	gap: var(--space-2);
	padding: var(--space-3);
	border-radius: var(--radius-md);
	background: rgba(59, 130, 246, 0.06);
	border: 1px solid rgba(59, 130, 246, 0.25);
	font-size: 13px;
	color: var(--text-secondary);
}
.nseo-publish-progress__spinner {
	width: 14px;
	height: 14px;
	border: 2px solid rgba(59, 130, 246, 0.3);
	border-top-color: #2563eb;
	border-radius: 50%;
	animation: nseo-publish-spin 0.8s linear infinite;
	flex-shrink: 0;
}
@keyframes nseo-publish-spin { to { transform: rotate(360deg); } }
.nseo-publish-success {
	padding: var(--space-3);
	border-radius: var(--radius-md);
	background: rgba(16, 185, 129, 0.06);
	border: 1px solid rgba(16, 185, 129, 0.25);
	color: var(--text-primary);
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
	font-size: 13px;
}
.nseo-publish-success__counts {
	list-style: none;
	padding: 0;
	margin: 0;
	display: flex;
	gap: var(--space-3);
	flex-wrap: wrap;
	font-size: 12px;
	color: var(--text-secondary);
}
/* Bloque post-publish junto al toolbar de la pantalla de detalle.
   JS lo inyecta tras leer sessionStorage del último publish. */
.nseo-publish-result {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-2) var(--space-3);
	margin-left: var(--space-2);
	padding: var(--space-1) var(--space-3);
	border-radius: var(--radius-sm);
	background: var(--surface-sunken);
	font-size: 12px;
	color: var(--text-secondary);
}
.nseo-publish-result__title { font-weight: 500; color: var(--text-primary); }
.nseo-publish-result__counts {
	list-style: none;
	padding: 0;
	margin: 0;
	display: flex;
	gap: var(--space-3);
}
.nseo-publish-result__count strong { font-weight: 600; color: var(--text-primary); }
.nseo-publish-result__count--ok strong { color: #047857; }
.nseo-publish-result__count--warn strong { color: #b45309; }
/* P3.4.3b (camino A): resultado por traducción tras publicar. */
.nseo-publish-result__translations { width: 100%; list-style: none; padding: 0; margin: var(--space-1) 0 0 0; display: flex; flex-direction: column; gap: 2px; }
.nseo-publish-result__translation { font-size: 13px; }
.nseo-publish-result__translation--ok strong { color: #047857; }
.nseo-publish-result__translation--warn strong { color: #b45309; }
.nseo-modal__langs-hint { font-size: 12px; color: var(--text-secondary); margin: var(--space-1) 0 0 0; }
.nseo-publish-result__warnings { width: 100%; margin-top: var(--space-1); }
.nseo-publish-result__warnings summary { cursor: pointer; font-size: 12px; color: var(--text-tertiary); }
.nseo-publish-result__warnings ul { margin: var(--space-2) 0 0 var(--space-4); padding: 0; font-size: 12px; }
.nseo-publish-result__warnings li { margin-bottom: var(--space-1); color: var(--text-secondary); }

/* ------- Historial de versiones ------- */
.nseo-versions { list-style: none; padding: 0; margin: var(--space-3) 0 0 0; }
.nseo-versions__item { padding: var(--space-2) 0; border-bottom: 1px dashed var(--border-subtle); }
.nseo-versions__item:last-child { border-bottom: none; }
.nseo-versions__item a { display: block; padding: var(--space-2); border-radius: 8px; text-decoration: none; color: inherit; }
.nseo-versions__item a:hover { background: var(--surface-hover); }
.nseo-versions__item--active a { background: var(--brand-primary-soft); }
/* P3.5c: lista de traducciones del original (hermana de .nseo-versions). */
.nseo-translations { list-style: none; padding: 0; margin: var(--space-3) 0 0 0; }
.nseo-translations__item { border-bottom: 1px dashed var(--border-subtle); display: flex; align-items: center; gap: var(--space-2); }
.nseo-translations__item:last-child { border-bottom: none; }
.nseo-translations__link { flex: 1; display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2); border-radius: 8px; text-decoration: none; color: inherit; min-width: 0; }
/* P3.4.2 (camino B): CTA "Publicar" de la fila de traducción. */
.nseo-translations__publish { flex-shrink: 0; text-decoration: none; }
.nseo-translations__link:hover { background: var(--surface-hover); }
.nseo-translations__lang { font-weight: 600; }
.nseo-translations__title { color: var(--text-secondary); font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nseo-translations__go { margin-left: auto; color: var(--text-secondary); }
/* P3.5c: backlink "↑ Traducción de «…»" bajo el H1 del page-header. */
/* Subtítulo de traducción: título del ORIGINAL en texto plano (enlace limpio,
   sin flecha ni comillas), bajo el H1 traducido. Más ligero que el título. */
.nseo-detail-origin-subtitle { margin: var(--space-1) 0 0 0; font-size: 15px; font-weight: 400; }
.nseo-detail-origin-subtitle a { color: var(--brand-primary); text-decoration: none; }
.nseo-detail-origin-subtitle a:hover { text-decoration: underline; }

/* Conmutador de idiomas (cabecera): grupo completo del artículo.
   v0.12.4: vive como SEGUNDO HIJO directo del `<header class="nseo-page-header">`,
   NO dentro de la toolbar. El header es flex space-between (ver bloque
   `.nseo-page-header` arriba en este archivo, ~L832), así que quitamos el
   `margin-left:auto` que necesitaba antes. `align-self: flex-start` + un
   `margin-top` compensan la altura del breadcrumb (que queda encima del
   título en la columna izquierda) para alinear los chips con el `<h1>`. */
.nseo-lang-switcher { display: inline-flex; align-items: center; gap: var(--space-1); align-self: flex-start; margin-top: calc(var(--text-sm-lh, 20px) + var(--space-3)); flex-shrink: 0; }
.nseo-lang-switcher__btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 34px;
	padding: 5px 8px;
	border: 1px solid var(--border-default);
	border-radius: var(--radius-sm);
	font-size: 12px;
	font-weight: 600;
	line-height: 1;
	color: var(--text-secondary);
	background: var(--surface-base);
	text-decoration: none;
}
.nseo-lang-switcher__btn:hover { background: var(--bg-surface); color: var(--text-primary); }
.nseo-lang-switcher__btn--active {
	background: var(--brand-primary);
	border-color: var(--brand-primary);
	color: #fff;
	cursor: default;
}
.nseo-lang-switcher__btn--disabled {
	opacity: 0.45;
	cursor: not-allowed;
	background: var(--bg-muted);
}

/* ------- Bloque de verificación ------- */
/* `.nseo-card__header` ahora gestiona el layout flex en el bloque
   unificado de la Phase 3.7m. Regla específica del card eliminada. */
.nseo-verify-card__summary { color: var(--text-secondary); font-size: 14px; margin: var(--space-2) 0 0 0; }
.nseo-verify-card__diff-hint { background: rgba(217,119,6,0.08); color: #92400e; padding: var(--space-2) var(--space-3); border-radius: 8px; font-size: 13px; margin: var(--space-3) 0 0 0; }
.nseo-verify-card__findings { margin-top: var(--space-3); }
.nseo-verify-card__findings > summary { cursor: pointer; font-weight: 500; color: var(--text-primary); padding: var(--space-2) 0; }
.nseo-verify-card__telemetry { margin: var(--space-3) 0 0 0; color: var(--text-tertiary); font-size: 12px; }

/* ------- Findings list -------
 *
 * Espaciado interno por flex gap en el `<li>` (Pieza B5). Los hijos del
 * `<li class="nseo-finding">` son una mezcla de `<div>`, `<blockquote>`
 * y `<p>`. Si hubiéramos puesto `margin-top: var(--space-3)` en los
 * selectores hijos, los `<p>` lo habrían IGNORADO por el reset agresivo
 * `body.nseo-frontend p { margin: 0 }` (frontend.css:147) — especificidad
 * (0,1,2) que gana a `.nseo-finding__expl` (0,1,0). El resultado eran
 * 12px declarados pero 0px reales entre bloques internos del finding,
 * y el operador veía la cita + explicación + sugerencia + estado
 * pegados unos a otros.
 *
 * Solución estructural: `.nseo-finding` es flex column con gap. El gap
 * separa los hijos directos independientemente de qué tipo de elemento
 * sean — `<p>` reseteado o no, da igual; el reset es irrelevante. Mismo
 * patrón que ya usa `.nseo-findings` para los gaps entre tarjetas y
 * `.nseo-page-header__meta` para los items del meta del header.
 *
 * `text-transform: capitalize` retirado del `__type` — el tipo viene
 * ya traducido al español desde el template (mapa
 * `$nseo_finding_type_labels`), no es la versión `str_replace('_',' ')`
 * del valor crudo.
 */
.nseo-findings { list-style: none; padding: 0; margin: var(--space-4) 0 0 0; display: flex; flex-direction: column; gap: var(--space-5); }
.nseo-finding {
	border-left: 3px solid var(--border-default);
	padding: var(--space-3) var(--space-4);
	background: var(--surface-sunken);
	border-radius: 0 8px 8px 0;
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
}
.nseo-finding--error { border-left-color: #DC2626; }
.nseo-finding--warning { border-left-color: #D97706; }
.nseo-finding--info { border-left-color: #3B82F6; }
.nseo-finding__head { display: flex; align-items: center; gap: var(--space-2); }
.nseo-finding__type { font-size: 12px; color: var(--text-secondary); }
.nseo-finding__span { margin: 0; padding: var(--space-3); background: var(--surface-base); border-left: 2px solid var(--border-default); font-style: italic; color: var(--text-secondary); font-size: var(--text-sm-size); line-height: var(--text-sm-lh); }
.nseo-finding__expl { font-size: var(--text-sm-size); line-height: var(--text-sm-lh); }
.nseo-finding__sugg { font-size: var(--text-sm-size); line-height: var(--text-sm-lh); color: var(--text-secondary); }
/* Rama "Corrección necesaria por el usuario" + razón muted en una segunda
 * línea. `__manual-block` es el hijo único del flex `.nseo-finding`, y
 * dentro contiene el copy principal y la razón. Usamos `<div>` (no `<p>`)
 * en ambas líneas para que sus margins respeten — patrón documentado en
 * el proyecto para esquivar el reset de p. */
.nseo-finding__manual-block { font-size: var(--text-sm-size); line-height: var(--text-sm-lh); }
.nseo-finding__manual-note { color: var(--text-primary); font-weight: 500; }
.nseo-finding__manual-reason { margin-top: var(--space-1); font-size: var(--text-xs-size); line-height: var(--text-xs-lh); color: var(--text-tertiary); font-style: italic; }
.nseo-finding__applied { font-size: var(--text-sm-size); line-height: var(--text-sm-lh); color: var(--success); font-weight: 500; }
.nseo-finding__auto-corrected { font-size: var(--text-sm-size); line-height: var(--text-sm-lh); color: var(--success); font-weight: 500; }
.nseo-finding__actions { }

/* Badges adicionales para findings. */
.nseo-badge--error { background: rgba(220,38,38,0.12); color: #b91c1c; border: 1px solid rgba(220,38,38,0.3); }

/* ====================================================================== */
/* Fase 3.6 — Imágenes IA (wizard radio + detalle galería)                */
/* ====================================================================== */

/* --- Wizard: detalle del bloque imágenes --- */
.nseo-extra-detail {
	margin: var(--space-3) 0 var(--space-2);
	padding: var(--space-3) var(--space-4);
	background: var(--surface-sunken);
	border-radius: var(--radius-md);
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
}
.nseo-extra-detail[hidden] { display: none; }

.nseo-radio-group {
	margin: 0;
	border: none;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
}
.nseo-radio-group legend {
	font-weight: 500;
	font-size: 13px;
	color: var(--text-primary);
	margin: 0 0 var(--space-1) 0;
	padding: 0;
}
.nseo-radio-group label {
	display: flex;
	align-items: center;
	gap: var(--space-2);
	margin: 0;
	font-size: 13px;
	color: var(--text-secondary);
	cursor: pointer;
}
.nseo-radio-group input[type="radio"] { margin: 0; }

.nseo-field--images-style { display: flex; flex-direction: column; gap: var(--space-1); }
/* U1-fix: el wrapper tiene display:flex (pisa el [hidden] del atributo). Al elegir
   "Subir mis propias imágenes" el JS hace hidden=true; esta regla lo hace efectivo
   (ocultar label + textarea + ayuda). Reaparece con otra fuente (ai/pexels/pixabay). */
.nseo-field--images-style[hidden] { display: none; }
.nseo-field--images-style .nseo-field-label { font-weight: 500; font-size: 13px; color: var(--text-primary); }
.nseo-field--images-style .nseo-textarea { min-height: 48px; }
.nseo-field--images-style .nseo-field-hint { font-size: 12px; color: var(--text-tertiary); display: flex; gap: var(--space-2); align-items: center; flex-wrap: wrap; }
.nseo-field-counter { color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.nseo-field-counter[hidden] { display: none; }

/* U1: zonas de subida de imágenes propias (fuente "upload"). [hidden] debe ganar
   al display:flex (clase con display pisa el atributo si no se reafirma). */
.nseo-upload-zones { display: flex; flex-direction: column; gap: var(--space-3); }
.nseo-upload-zones[hidden] { display: none; }
.nseo-upload-zones > .nseo-field-label { font-weight: 500; font-size: 13px; color: var(--text-primary); }
.nseo-upload-zone { display: flex; flex-direction: column; gap: var(--space-1); padding: var(--space-2); border: 1px solid var(--border-subtle, #e2e8f0); border-radius: var(--radius-sm, 6px); }
.nseo-upload-zone[hidden] { display: none; }
.nseo-upload-zone__title { font-size: 12px; font-weight: 600; color: var(--text-secondary); }
.nseo-upload-zone__drop { display: inline-flex; }
.nseo-upload-zone__cta { display: inline-block; padding: 6px 10px; font-size: 13px; border: 1px dashed var(--border-strong, #94a3b8); border-radius: var(--radius-sm, 6px); cursor: pointer; color: var(--text-primary); }
.nseo-upload-zone__preview { display: flex; align-items: center; gap: var(--space-2); }
.nseo-upload-zone__preview[hidden] { display: none; }
.nseo-upload-zone__preview img { max-width: 80px; max-height: 80px; border-radius: var(--radius-sm, 6px); object-fit: cover; }
.nseo-upload-zone__remove { background: none; border: none; padding: 0; color: var(--brand-primary); font: inherit; text-decoration: underline; cursor: pointer; }
.nseo-upload-zone__alt { font-size: 13px; }
.nseo-upload-zone__status { font-size: 12px; color: var(--text-tertiary); }
.nseo-upload-zone__status[hidden] { display: none; }
.nseo-upload-zone__status.is-error { color: #b91c1c; }

/* --- Pantalla detalle: bloque galería --- */
/* `.nseo-card__header` ahora gestiona el layout flex en el bloque
   unificado de la Phase 3.7m. Regla específica del card eliminada. */
.nseo-images-style-hint {
	margin: var(--space-3) 0 var(--space-4) 0;
	padding: var(--space-2) var(--space-3);
	background: var(--surface-sunken);
	border-radius: var(--radius-sm);
	font-size: 13px;
	color: var(--text-secondary);
}
.nseo-images-style-hint strong { color: var(--text-primary); margin-right: var(--space-1); }

.nseo-images-gallery {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
	gap: var(--space-4);
	margin: var(--space-3) 0 0 0;
}
.nseo-image-card {
	display: flex;
	flex-direction: column;
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-md);
	overflow: hidden;
	background: var(--surface-base);
}
.nseo-image-card > a {
	display: block;
	line-height: 0;
	border-bottom: 1px solid var(--border-subtle);
}
.nseo-image-card img {
	display: block;
	width: 100%;
	aspect-ratio: 1 / 1;
	object-fit: cover;
}
.nseo-image-meta { padding: var(--space-3); font-size: 13px; color: var(--text-secondary); }
.nseo-image-position {
	display: block;
	font-weight: 600;
	color: var(--text-primary);
	margin-bottom: var(--space-2);
	font-size: 13px;
}
.nseo-image-prompt {
	margin: var(--space-2) 0;
	color: var(--text-secondary);
	font-size: 12px;
	line-height: 1.45;
}
.nseo-image-prompt strong { color: var(--text-primary); }
.nseo-image-telemetry {
	margin: var(--space-2) 0 0 0;
	color: var(--text-tertiary);
	font-size: 11px;
}
/* S5.2: picker de candidatos de stock. */
.nseo-image-picker {
	margin: var(--space-3) 0 0 0;
	padding: var(--space-3) 0 0 0;
	border-top: 1px solid var(--border-subtle);
}
.nseo-image-picker__hint {
	margin: 0 0 var(--space-2) 0;
	font-size: 11px;
	color: var(--text-tertiary);
}
.nseo-image-picker__grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
	gap: var(--space-2);
}
.nseo-image-picker__option {
	display: block;
	padding: 0;
	border: 2px solid transparent;
	border-radius: var(--radius-sm);
	overflow: hidden;
	background: var(--surface-base);
	cursor: pointer;
	line-height: 0;
}
.nseo-image-picker__option img {
	display: block;
	width: 100%;
	aspect-ratio: 1 / 1;
	object-fit: cover;
}
.nseo-image-picker__option.is-chosen {
	border-color: var(--accent, #2563eb);
}
.nseo-image-picker__author {
	display: block;
	padding: 2px 4px;
	font-size: 10px;
	line-height: 1.3;
	color: var(--text-tertiary);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}
/* S5.3: estado mientras re-materializa (descarga + sube). */
.nseo-image-picker.is-loading {
	position: relative;
	opacity: 0.6;
	pointer-events: none;
}
.nseo-image-picker.is-loading .nseo-image-picker__grid {
	cursor: progress;
}
.nseo-image-picker__option:disabled {
	cursor: progress;
}
.nseo-image-picker__error {
	margin: 0 0 var(--space-2) 0;
	font-size: 11px;
	color: var(--danger, #b91c1c);
}
.nseo-images-block__footer {
	margin: var(--space-4) 0 0 0;
	padding: var(--space-2) 0 0 0;
	border-top: 1px solid var(--border-subtle);
	color: var(--text-tertiary);
	font-size: 12px;
}

/* --- Fase 3.7a: bloque de enlaces internos en detail screen --- */
.nseo-internal-links-block .nseo-card__header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-3);
}
.nseo-internal-links-adhoc {
	margin: var(--space-3) 0 var(--space-4) 0;
	padding: var(--space-2) var(--space-3);
	background: var(--surface-sunken);
	border-radius: var(--radius-sm);
	font-size: 13px;
	color: var(--text-secondary);
	white-space: pre-wrap;
}
.nseo-internal-links-adhoc strong { color: var(--text-primary); margin-right: var(--space-1); }
.nseo-internal-links-table {
	width: 100%;
	margin: var(--space-3) 0 0 0;
	border-collapse: collapse;
	font-size: 13px;
}
.nseo-internal-links-table th,
.nseo-internal-links-table td {
	padding: var(--space-2) var(--space-3);
	text-align: left;
	border-bottom: 1px solid var(--border-subtle);
}
.nseo-internal-links-table th {
	color: var(--text-tertiary);
	font-weight: 600;
	font-size: 12px;
	text-transform: uppercase;
	letter-spacing: 0.04em;
}
.nseo-internal-links-table td code {
	background: var(--surface-sunken);
	padding: 2px 6px;
	border-radius: var(--radius-sm);
	font-size: 12px;
}
.nseo-internal-links-table td a {
	color: var(--text-link);
	text-decoration: none;
	word-break: break-all;
}
.nseo-internal-links-table td a:hover { text-decoration: underline; }
.nseo-internal-links-block__footer {
	margin: var(--space-4) 0 0 0;
	padding: var(--space-2) 0 0 0;
	border-top: 1px solid var(--border-subtle);
	color: var(--text-tertiary);
	font-size: 12px;
}

/* --- Wizard: detalle extra de enlaces internos --- */
.nseo-field--internal-links-anchors textarea,
.nseo-field--internal-links-max select { width: 100%; }

/* --- Site form: panel de anchors permanentes --- */
.nseo-internal-anchors-panel { margin-top: var(--space-5); }
.nseo-internal-anchors-panel .nseo-form-actions {
	display: flex;
	gap: var(--space-3);
	margin-top: var(--space-3);
}

/* ============================================================
   Posts publicados (Phase 4.1)
   ============================================================ */

/* Empty state centrado cuando aún no se ha sincronizado. */
.nseo-remote-posts-empty { max-width: 560px; margin: var(--space-6) auto; }
.nseo-remote-posts-empty__progress { margin-top: var(--space-3); color: var(--text-secondary); font-size: 14px; }
.nseo-remote-posts-empty__error { margin-top: var(--space-2); color: var(--danger); font-size: 14px; }

/* Fila de filtros plegables ENCIMA del list-toolbar (Artículos publicados).
   Botón "Filtrar [N]" alineado a la izquierda, sobre el panel de filtros
   que se despliega justo debajo. Sólo lo usa remote-posts/index — articles
   /index no tiene filtros y no pinta este bloque. */
.nseo-list-filters {
	display: flex;
	align-items: center;
	gap: var(--space-2);
	margin: 0 0 var(--space-3) 0;
}

/* Modificadores de la línea de metadata de sync, inline en el subtítulo
   del header de Artículos publicados. Antes vivían en una franja propia
   `.nseo-list-status`; ahora viajan dentro de `.nseo-page-header__subtitle`
   después del recuento, separados con " | ". Sólo el __progress y __error
   pueden aparecer dinámicamente (al pulsar Sincronizar), embedidos en el
   slot derecho del toolbar de tabs. */
.nseo-page-header__subtitle-sep { color: var(--border-default); margin: 0 4px; }
.nseo-list-status__label { color: var(--text-secondary); font-weight: 500; margin-right: 2px; }
.nseo-list-status__sep   { color: var(--text-tertiary); margin: 0 6px; }
.nseo-list-status__muted { color: var(--text-tertiary); }
.nseo-list-status__progress { color: var(--text-secondary); font-size: 13px; }
.nseo-list-status__error    { color: var(--danger); font-size: 13px; }

/* Filtros en una fila con wrap. */
.nseo-remote-posts-filters {
	display: flex;
	gap: var(--space-3);
	flex-wrap: wrap;
	align-items: flex-end;
	margin-bottom: var(--space-4);
}
.nseo-remote-posts-filters__field { display: flex; flex-direction: column; gap: var(--space-1); min-width: 180px; flex: 1; }
.nseo-remote-posts-filters__label { font-size: 12px; font-weight: 500; color: var(--text-secondary); }
.nseo-remote-posts-filters__actions { display: flex; gap: var(--space-2); align-items: center; }

/* Anchos de columna fijos: sin esto, el navegador reajusta el ancho de cada
   columna según el contenido de las filas, que cambia al reordenar — y la
   cabecera "baila". Con table-layout:fixed, los <col> del colgroup mandan y la
   cabecera queda idéntica ordenes por lo que ordenes. */
.nseo-remote-posts-table { table-layout: fixed; }
.nseo-remote-posts-table th,
.nseo-remote-posts-table td { overflow: hidden; text-overflow: ellipsis; }
/* La celda de idiomas no lleva texto largo que truncar (son cuadraditos) —
   sin este permiso, sus tooltips quedaban recortados por el overflow:hidden
   de arriba, tapados en vez de mostrarse por encima. */
.nseo-remote-posts-table td.nseo-remote-posts-table__lang-cell { overflow: visible; }
/* KW-12: la línea del artículo del idioma principal en negrita; sus
   traducciones (filas añadidas debajo) en tipografía normal, con una
   flechita antes del título para dejar clara la relación jerárquica sin
   necesitar una columna de sangría aparte. */
.nseo-remote-posts-table tbody tr.nseo-table__row:not(.nseo-table__row--translation) {
	font-weight: 600;
	background: var(--surface-hover);
}
/* .nseo-table__cell-primary trae su propio font-weight:500 fijo (para el
   resto de tablas de la app) -- sin este override explícito, pisaba el 600
   heredado de la fila y el título/opportunity-keyword se quedaban con peso
   normal aunque el resto de la fila sí se viera en negrita. */
.nseo-remote-posts-table tbody tr.nseo-table__row:not(.nseo-table__row--translation) .nseo-table__cell-primary {
	font-weight: 600;
}
.nseo-remote-posts-table tbody tr.nseo-table__row--translation {
	font-weight: 400;
}
.nseo-remote-posts-table__translation-arrow {
	color: var(--text-tertiary);
	margin-right: 2px;
}
/* KW-13: solo redimensionar (no reordenar, a diferencia de la tabla de
   Enlaces de traducción) -- por eso el <th> no lleva cursor:grab ni
   draggable, solo la asa a la derecha con cursor:col-resize. */
.nseo-remote-posts-table th {
	position: relative;
}
.nseo-remote-posts-table__resize-handle {
	position: absolute;
	top: 0;
	right: 0;
	width: 8px;
	height: 100%;
	cursor: col-resize;
	z-index: 2;
}
.nseo-remote-posts-table__resize-handle:hover,
.nseo-remote-posts-table__resize-handle.is-resizing {
	background: var(--brand-primary);
	opacity: 0.4;
}

/* KW-18: pantalla de configuración de campos ACF. */
.nseo-empty-state {
	background: var(--surface-elevated, #ffffff);
	border: 1px solid var(--border-subtle);
	border-radius: 10px;
	padding: var(--space-6, 32px);
	text-align: center;
	color: var(--text-secondary);
}
.nseo-empty-state p {
	margin: 0 0 var(--space-3, 12px);
}
.nseo-acf-fields__table td {
	vertical-align: top;
}
.nseo-acf-fields__sample {
	font-size: 12px;
	color: var(--text-tertiary);
	max-width: 320px;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	display: block;
}
.nseo-acf-fields__description {
	width: 100%;
	min-height: 44px;
	resize: vertical;
	font-family: inherit;
	font-size: 13px;
	padding: 8px 10px;
	border: 1px solid var(--border-default);
	border-radius: 6px;
}
.nseo-acf-fields__description:disabled {
	background: var(--surface-hover);
	color: var(--text-tertiary);
}

.nseo-remote-posts-table__check { color: var(--success); font-weight: 600; }

.nseo-remote-posts-footer {
	margin-top: var(--space-3);
	font-size: 13px;
	color: var(--text-tertiary);
}

.nseo-help-card--remote-posts {
	margin-top: var(--space-6);
	background: var(--surface-sunken);
	padding: var(--space-4);
	border-radius: 12px;
	border: 1px solid var(--border-subtle);
	color: var(--text-secondary);
}
.nseo-help-card--remote-posts .nseo-help-card__title {
	font-size: 12px;
	font-weight: 600;
	letter-spacing: 0.08em;
	color: var(--text-tertiary);
	margin: 0 0 var(--space-2);
}
.nseo-help-card--remote-posts p { margin: 0 0 var(--space-2); font-size: 13px; line-height: 1.6; }
.nseo-help-card--remote-posts p:last-child { margin-bottom: 0; }

/* Toggle "solo candidatos" + "mostrar score" en la barra de filtros. */
.nseo-remote-posts-filters__toggle {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
	font-size: 13px;
	color: var(--text-secondary);
	white-space: nowrap;
}
.nseo-remote-posts-filters__toggle input[type="checkbox"] { margin: 0; }

/* Badge "Candidato" en la celda título — ámbar discreto + tooltip nativo. */
.nseo-badge--candidate {
	background: rgba(217, 119, 6, 0.12);
	color: #92400e;
	border: 1px solid rgba(217, 119, 6, 0.3);
	font-size: 11px;
	padding: 2px 8px;
	border-radius: var(--radius-pill);
	margin-right: 6px;
	cursor: help;
	white-space: nowrap;
}

/* Columna Score: siempre visible desde commit 6.2. */
.nseo-remote-posts-table__score { font-variant-numeric: tabular-nums; font-weight: 600; }
.nseo-remote-posts-table__score--high { color: #b91c1c; }
.nseo-remote-posts-table__score--mid  { color: #b45309; }
.nseo-remote-posts-table__score--low  { color: var(--text-tertiary); }
.nseo-remote-posts-table__score--none { color: #15803d; }
.nseo-remote-posts-table__score--unknown { color: var(--text-tertiary); font-weight: 400; }

/* Columna asterisco "candidato" (commit 6.6). Primera columna del
   listado, ancho estrecho centrado. El asterisco sólo se renderiza
   cuando score >= threshold; su color hex viene inline desde
   `siteColor` (Colors::fromString) para coincidir con el avatar del
   sitio en el site switcher. */
.nseo-remote-posts-table__asterisk-col {
	width: 36px;
	text-align: center;
	padding-left: var(--space-2);
	padding-right: var(--space-2);
}

/* "Kw top 10 / 100": el contenido (ej. "13 / 21") en una sola línea, sin
   romper por el espacio alrededor de la barra. El ancho del <col> ya lo
   acomoda; esto lo garantiza. */
.nseo-remote-posts-table__kwtop {
	white-space: nowrap;
}
.nseo-remote-posts-table__asterisk {
	font-size: 28px;
	font-weight: 700;
	line-height: 1;
	cursor: help;
	display: inline-block;
}

/* Columna Trend (commit 6.4 / fusionada en Score · Trend en 4.5.0c).
   Iconos ↑→↓— con color por estado. La clase __trend-inline aplica el
   color al span dentro del td fusionado; la antigua __trend se conserva
   por si quedan usos en otros templates. */
.nseo-remote-posts-table__trend { font-weight: 600; }
.nseo-remote-posts-table__trend-inline { font-weight: 600; margin-left: 4px; }
.nseo-remote-posts-table__trend--rising  { color: #15803d; } /* verde */
.nseo-remote-posts-table__trend--stable  { color: var(--text-tertiary); }
.nseo-remote-posts-table__trend--falling { color: #b91c1c; } /* rojo */
.nseo-remote-posts-table__trend--unknown { color: var(--border-subtle); }

/* Score value (parte numérica del td fusionado Score · Trend). */
.nseo-remote-posts-table__score-value { font-variant-numeric: tabular-nums; }

/* Utility WP-core compatible: oculta el elemento visualmente pero lo
   mantiene accesible para lectores de pantalla. Usado por commit 6.10
   como destino de `aria-describedby` (asterisco "candidato": el
   desglose largo vive en un sibling con esta clase). Réplica del
   `.screen-reader-text` de WordPress core para no depender de que
   wp-admin/load-styles.php inyecte la suya en frontend. */
.screen-reader-text {
	border: 0;
	clip: rect(1px, 1px, 1px, 1px);
	-webkit-clip-path: inset(50%);
	clip-path: inset(50%);
	height: 1px;
	margin: -1px;
	overflow: hidden;
	padding: 0;
	position: absolute;
	width: 1px;
	word-wrap: normal !important;
}

/* Tooltip custom CSS-only (commit 6.9). El `title=""` nativo del
   navegador tarda 2-3 segundos en aparecer y requiere el cursor
   quieto. Esta versión:
     - Lee el contenido desde `data-tooltip` vía `attr()`.
     - Aparece a los 250 ms con transition-delay (en vez de
       `display:none` instantáneo).
     - Respeta los `\n` literales del helper `tooltipFor()` gracias a
       `white-space: pre-line`.
     - Centrada bajo el elemento, max-width 320px, flecha hacia arriba.
   El `title=""` se mantiene en paralelo por accesibilidad (lectores
   de pantalla) y como fallback si el CSS no carga. */
.nseo-tooltip {
	position: relative;
}
.nseo-tooltip--inline-block {
	display: inline-block;
}
.nseo-tooltip::after {
	content: attr(data-tooltip);
	position: absolute;
	top: 100%;
	left: 50%;
	transform: translateX(-50%);
	margin-top: 10px;
	background: #1f2937;
	color: #ffffff;
	padding: 10px 14px;
	border-radius: 6px;
	box-shadow: 0 4px 12px rgba(0, 0, 0, 0.18);
	font-size: 12px;
	font-weight: 400;
	line-height: 1.45;
	text-align: left;
	white-space: pre-line;
	max-width: 320px;
	width: max-content;
	z-index: 10000;
	opacity: 0;
	visibility: hidden;
	pointer-events: none;
	transition: opacity 120ms ease-in-out 250ms, visibility 0s linear 250ms;
}
.nseo-tooltip::before {
	content: '';
	position: absolute;
	top: 100%;
	left: 50%;
	transform: translateX(-50%);
	margin-top: -2px;
	border: 6px solid transparent;
	border-bottom-color: #1f2937;
	z-index: 10000;
	opacity: 0;
	visibility: hidden;
	pointer-events: none;
	transition: opacity 120ms ease-in-out 250ms, visibility 0s linear 250ms;
}
.nseo-tooltip:hover::after,
.nseo-tooltip:hover::before,
.nseo-tooltip:focus-within::after,
.nseo-tooltip:focus-within::before {
	/* KW-9: DESACTIVADO a propósito -- este mecanismo (pseudo-elementos
	   `position:absolute` DENTRO del propio disparador) se recorta con
	   cualquier `overflow:hidden` de un antepasado, sin importar el
	   z-index; iba reapareciendo en pantallas distintas cada vez porque es
	   un fallo estructural, no de un sitio en concreto. Sustituido por
	   `tooltip-portal.js`, que pinta el tooltip en <body> directamente
	   (fuera de cualquier contenedor que pudiera recortarlo) y lo
	   posiciona por JS. Esta regla se deja comentada como referencia y
	   fallback documentado, no se borra el resto del bloque (measurements,
	   flecha, etc.) por si hiciera falta reactivarla en el futuro. */
}
.nseo-tooltip-portal {
	position: absolute;
	z-index: 100000;
	background: #1f2937;
	color: #ffffff;
	padding: 10px 14px;
	border-radius: 6px;
	box-shadow: 0 4px 12px rgba(0, 0, 0, 0.18);
	font-size: 12px;
	font-weight: 400;
	line-height: 1.45;
	text-align: left;
	white-space: pre-line;
	max-width: 320px;
	width: max-content;
	pointer-events: none;
	opacity: 0;
	transition: opacity 120ms ease-in-out;
}
.nseo-tooltip-portal.is-visible {
	opacity: 1;
}
.nseo-tooltip-portal::before {
	content: '';
	position: absolute;
	bottom: 100%;
	left: var(--nseo-tooltip-arrow-left, 50%);
	transform: translateX(-50%);
	border: 6px solid transparent;
	border-bottom-color: #1f2937;
}
/* Cuando no cabe debajo (pegado al borde inferior de la ventana), el JS
   coloca el tooltip ENCIMA del disparador -- la flecha tiene que voltearse
   para seguir apuntando hacia el disparador, no hacia arriba. */
.nseo-tooltip-portal--above::before {
	bottom: auto;
	top: 100%;
	border-bottom-color: transparent;
	border-top-color: #1f2937;
}
/* Tooltips vacíos (data-tooltip="") NO deben mostrar el bloque ni la flecha. */
.nseo-tooltip[data-tooltip=""]::after,
.nseo-tooltip[data-tooltip=""]::before,
.nseo-tooltip:not([data-tooltip])::after,
.nseo-tooltip:not([data-tooltip])::before {
	display: none;
}

/* Resumen agregado bajo la tabla: "316 posts · 87 candidatos (28%) · 229 OK". */
.nseo-remote-posts-aggregate {
	margin-top: var(--space-3);
	font-size: 13px;
	color: var(--text-secondary);
	padding: var(--space-2) var(--space-3);
	background: var(--surface-sunken);
	border-radius: 8px;
	border: 1px solid var(--border-subtle);
}

/* ============================================================
   Sistema de tablas denso (commit 6.11).

   Componentes reusables aplicables a todos los listados tabulares
   del plugin (Posts publicados, Sitios, Artículos, Créditos).
   Posts publicados es la primera implementación de referencia;
   las demás tablas migrarán en commit posterior una vez validado
   visualmente este patrón.

   Convenciones:
     - Headers en mayúsculas con tracking abierto y color secundario.
     - Filas altas (~64-72px efectivos via padding) para escaneo.
     - Celdas con dos niveles: primary (14px, color principal) +
       secondary (12px, gris) para metadata derivada.
     - Filtros en una sola línea con labels en uppercase ENCIMA del
       control.
     - Acciones como icon-buttons con aria-label.
   ============================================================ */

/* Filtros encima de la tabla. Layout en UNA SOLA FILA horizontal — el
   primer intento usaba `flex-wrap: wrap`, lo que en desktop dejaba el
   layout indistinguible del legacy (labels arriba pero controles en 2
   filas). Forzamos `nowrap`; los hijos llevan `min-width: 0` para
   permitir contracción y el grow field crece para absorber el espacio
   restante. */
.nseo-table__filters {
	display: flex;
	flex-wrap: nowrap;
	align-items: flex-end;
	gap: var(--space-3);
	margin-bottom: var(--space-4);
}
/* El `display:flex` de arriba pisaba el atributo `hidden` (la regla UA
   `[hidden]{display:none}` tiene menor prioridad), dejando el panel siempre
   visible y el toggle "Filtrar" visualmente inerte. Este override restaura el
   plegado para que el botón "Filtrar" sea operativo. */
.nseo-table__filters[hidden] {
	display: none;
}
.nseo-table__filter-field {
	display: flex;
	flex-direction: column;
	gap: 4px;
	min-width: 0;
}
.nseo-table__filter-field--grow {
	/* Ajuste 2: el campo "Título" dejaba de crecer para llenar toda la fila
	   (flex-grow:1 lo hacía demasiado ancho y descuadraba Aplicar/Limpiar).
	   Basis razonable + tope; las acciones quedan a la derecha por su
	   margin-left:auto, así la fila queda equilibrada. */
	flex: 0 1 280px;
	min-width: 180px;
	max-width: 360px;
}
.nseo-table__filter-label {
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	color: var(--text-secondary);
	line-height: 1;
}
.nseo-table__filter-toggles {
	display: inline-flex;
	/* Retoque A: los dos checkboxes (candidatos / Top 25 Sistrix) apilados
	   verticalmente en vez de en línea, para ahorrar ancho del toolbar. */
	flex-direction: column;
	flex-wrap: nowrap;
	align-items: flex-start;
	gap: var(--space-2);
	align-self: center;
	font-size: 13px;
	color: var(--text-primary);
	white-space: nowrap;
}
.nseo-table__filter-toggle {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	cursor: pointer;
	user-select: none;
}
.nseo-table__filter-actions {
	display: flex;
	gap: var(--space-2);
	margin-left: auto;
	align-self: flex-end;
	flex-shrink: 0;
}

/* Wrapper de scroll horizontal interno (Fase 4.5.0c). Las tablas densas
   con muchas columnas escapan al ancho del canvas en viewports normales
   — el wrapper concentra el scroll-X aquí en lugar de provocarlo a nivel
   página. Sticky thead mantiene el contexto al scrollear. */
.nseo-table-scroll {
	overflow-x: auto;
	width: 100%;
	border: 1px solid var(--border-subtle);
	border-radius: 10px;
	background: var(--surface-elevated, #ffffff);
}
.nseo-table-scroll .nseo-table {
	/* Cuando la tabla vive dentro del wrapper, el wrapper ya tiene el
	   border + radius — la tabla pierde los suyos para no duplicarlos. */
	border: 0;
	border-radius: 0;
}
.nseo-table-scroll .nseo-table thead {
	position: sticky;
	top: 0;
	z-index: 1;
}

/* Tabla base. */
.nseo-table {
	width: 100%;
	border-collapse: collapse;
	background: var(--surface-elevated, #ffffff);
	border: 1px solid var(--border-subtle);
	border-radius: 10px;
	overflow: hidden;
	font-family: inherit;
}

/* KW-16: columnas redimensionables genéricas -- cualquier tabla con esta
   clase + `data-nseo-resize-table` en el <table> + `data-nseo-col`/asa en
   cada <th> queda arrastrable, sin CSS propio por tabla. */
.nseo-table--resizable {
	table-layout: fixed;
}
.nseo-table--resizable th {
	position: relative;
}
.nseo-table__col-resize-handle {
	position: absolute;
	top: 0;
	right: 0;
	width: 8px;
	height: 100%;
	cursor: col-resize;
	z-index: 2;
}
.nseo-table__col-resize-handle:hover,
.nseo-table__col-resize-handle.is-resizing {
	background: var(--brand-primary);
	opacity: 0.4;
}

/* Headers. */
.nseo-table__header-cell {
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--text-secondary);
	text-align: left;
	padding: 16px 14px;
	border-bottom: 1px solid var(--border-subtle);
	background: var(--surface-sunken, #fafafa);
	vertical-align: middle;
	white-space: nowrap;
}
.nseo-table__header-cell--num { text-align: right; }
.nseo-table__header-cell--center { text-align: center; }
.nseo-table__header-cell--asterisk { width: 36px; padding-left: 12px; padding-right: 12px; }

.nseo-table__header-sort {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	color: inherit;
	text-decoration: none;
	cursor: pointer;
}
.nseo-table__header-sort:hover { color: var(--text-primary); }

/* Label de la cabecera ordenable. Necesita `white-space: normal` para
   que `<br>` en el label rompa de verdad (el `<th>` padre lleva
   `white-space: nowrap` para el resto de columnas de una sola línea).
   `line-height` ligeramente comprimido para que el bloque de dos
   líneas no eleve demasiado la fila de cabecera. (4.5.0d post-fix
   scroll lateral 2026-05-20.) */
.nseo-table__header-sort-label {
	white-space: normal;
	line-height: 1.2;
}
.nseo-table__sort-arrow {
	display: inline-flex;
	align-items: center;
	color: var(--text-secondary);
}
.nseo-table__sort-arrow svg { display: block; }
/* Las flechas se dibujan via SVG (path data-dir="up"/"down"). En
   variante "neutral" ambos triángulos van atenuados a 0.4 de opacidad
   para no competir visualmente con la columna activa. Variantes asc/desc
   ponen el chevron correspondiente a opacidad plena y color brand. */
.nseo-table__sort-arrow svg [data-dir] { opacity: 0.4; }
.nseo-table__sort-arrow--asc svg [data-dir="up"],
.nseo-table__sort-arrow--desc svg [data-dir="down"] {
	opacity: 1;
}
.nseo-table__sort-arrow--active { color: var(--brand, #6d28d9); }

/* Filas + celdas. */
.nseo-table__row {
	border-bottom: 1px solid var(--border-subtle);
	transition: background-color 120ms ease-in-out;
}
.nseo-table__row:last-child { border-bottom: 0; }
.nseo-table__row:hover { background: var(--surface-sunken, #fafafa); }

.nseo-table__cell {
	padding: 18px 14px;
	font-size: 14px;
	color: var(--text-primary);
	vertical-align: middle;
	line-height: 1.4;
}
.nseo-table__cell--num {
	text-align: right;
	font-variant-numeric: tabular-nums;
}
.nseo-table__cell--center { text-align: center; }
.nseo-table__cell--asterisk { width: 36px; padding-left: 12px; padding-right: 12px; text-align: center; }
.nseo-table__cell--actions { text-align: right; white-space: nowrap; }

/* Celdas con dos niveles. */
.nseo-table__cell-primary {
	font-size: 14px;
	font-weight: 500;
	color: var(--text-primary);
	line-height: 1.35;
}
.nseo-table__cell-primary a {
	color: inherit;
	text-decoration: none;
}
.nseo-table__cell-primary a:hover {
	color: var(--brand, #6d28d9);
	text-decoration: underline;
}
.nseo-table__cell-secondary {
	margin-top: 2px;
	font-size: 12px;
	color: var(--text-tertiary);
	line-height: 1.35;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

/* Acciones: botones-icono. */
.nseo-table__actions {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	justify-content: flex-end;
}
.nseo-table__icon-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	padding: 0;
	border: none;
	background: transparent;
	color: var(--text-secondary);
	border-radius: 50%;
	cursor: pointer;
	transition: background-color 120ms, color 120ms;
}
.nseo-table__icon-btn:hover:not(:disabled):not([aria-disabled="true"]) {
	background: var(--surface-sunken, #f5f5f5);
	color: var(--brand, #6d28d9);
}
.nseo-table__icon-btn:disabled,
.nseo-table__icon-btn[aria-disabled="true"] {
	opacity: 0.45;
	cursor: not-allowed;
}
.nseo-table__icon-btn svg {
	display: block;
	width: 18px;
	height: 18px;
}

/* Lupa "Analizar" como PASTILLA CUADRADA (esquinas suaves) con fondo, para
 * que el estado contraste de un vistazo. El estado lo decide el flag
 * $nseo_has_any en PHP; aquí solo el aspecto (click/tooltip intactos).
 *  - --analyze-none → fondo gris suave + lupa negra (sin análisis).
 *  - --analyze-has  → fondo acento + lupa blanca (con análisis: fresco o viejo).
 * El icono SVG hereda el color vía `stroke="currentColor"`. */
.nseo-table__icon-btn--analyze {
	border-radius: var(--radius-md);
}
.nseo-table__icon-btn--analyze-none {
	background: var(--surface-sunken);
	color: var(--text-primary);
}
.nseo-table__icon-btn--analyze-none:hover:not(:disabled):not([aria-disabled="true"]) {
	background: var(--border-subtle);
	color: var(--text-primary);
}
.nseo-table__icon-btn--analyze-has {
	background: var(--brand-primary);
	color: #fff;
}
.nseo-table__icon-btn--analyze-has:hover:not(:disabled):not([aria-disabled="true"]) {
	background: var(--brand-primary-hover);
	color: #fff;
}

/* Pills (badges compactos). */
.nseo-pill {
	display: inline-flex;
	align-items: center;
	padding: 2px 8px;
	font-size: 11px;
	font-weight: 600;
	line-height: 1.6;
	border-radius: var(--radius-pill);
	letter-spacing: 0.02em;
	white-space: nowrap;
}
.nseo-pill--primary { background: rgba(109, 40, 217, 0.12); color: #6d28d9; }
.nseo-pill--success { background: rgba(21, 128, 61, 0.12); color: #15803d; }
.nseo-pill--warn    { background: rgba(180, 83, 9, 0.12);  color: #b45309; }
.nseo-pill--danger  { background: rgba(185, 28, 28, 0.12); color: #b91c1c; }
.nseo-pill--muted   { background: var(--surface-sunken);   color: var(--text-secondary); }

/* Pills de origen del draft (Fase 4.5.0e). Distinguen entre artículos
   nuevos generados desde cero (source='new', azul calmado) y propuestas
   de curación derivadas de un análisis (source='curation', ámbar más
   cargado para que el operador identifique de un vistazo qué filas
   nacieron de qué flujo). El de curación es a la vez un <a> al análisis
   de origen — hover lo subraya levemente. */
.nseo-pill--source-new { background: rgba(37, 99, 235, 0.12); color: #1d4ed8; }
/* L.3 (Modelo B): chips de idioma de la columna "Idiomas". Cada chip = inicial
   del idioma, enlace a la traducción, color por bucket de estado. */
.nseo-lang-cell { display: flex; flex-wrap: wrap; gap: 4px; }
.nseo-lang-empty { color: var(--text-secondary); }
.nseo-lang-chip {
	display: inline-flex; align-items: center; gap: 4px;
	min-width: 26px; justify-content: center;
	padding: 2px 6px; border-radius: 6px;
	font-size: 11px; font-weight: 700; letter-spacing: 0.02em;
	text-decoration: none; border: 1px solid transparent;
}
.nseo-lang-chip--published { background: rgba(21, 128, 61, 0.16); color: #15803d; }
.nseo-lang-chip--draft     { background: transparent; border-color: rgba(37, 99, 235, 0.4); color: #1d4ed8; }
.nseo-lang-chip--failed    { background: var(--danger-soft); color: var(--danger); opacity: 0.75; }
.nseo-lang-chip--progress  { background: rgba(180, 83, 9, 0.12); color: #b45309; }
.nseo-lang-chip--progress::before {
	content: ''; width: 6px; height: 6px; border-radius: 50%;
	background: currentColor; animation: nseo-lang-pulse 1.4s ease-in-out infinite;
}
@keyframes nseo-lang-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.3; } }

/* T2: cuadraditos de idioma del listado. Color = paso del proceso: blanco (no
   existe, clicable) → azul claro (generada) → azul fuerte (publicada). */
.nseo-lang-sq {
	display: inline-flex; align-items: center; gap: 4px;
	min-width: 28px; justify-content: center;
	padding: 2px 6px; border-radius: var(--radius-sm);
	font-size: 11px; font-weight: 700; letter-spacing: 0.02em; line-height: 1.6;
	text-decoration: none; border: 1px solid var(--border-default);
	background: #fff; color: var(--text-secondary); font-family: inherit;
}
button.nseo-lang-sq { cursor: pointer; }
button.nseo-lang-sq:hover { border-color: var(--nseo-coral); color: var(--nseo-coral); background: var(--nseo-coral-soft); }
.nseo-lang-sq--none { background: #fff; color: var(--text-tertiary); border-style: dashed; }
.nseo-lang-sq--none.is-disabled { opacity: 0.45; }
.nseo-lang-sq--generated { background: rgba(99, 102, 241, 0.12); color: #4f46e5; border-color: transparent; }
.nseo-lang-sq--published { background: var(--nseo-coral); color: #fff; border-color: transparent; }
.nseo-lang-sq--original { background: var(--surface-sunken); color: var(--text-secondary); border-color: transparent; }
.nseo-lang-sq--original::before { content: ''; width: 5px; height: 5px; border-radius: 50%; background: currentColor; opacity: 0.7; }
.nseo-lang-sq--progress { background: rgba(180, 83, 9, 0.12); color: #b45309; border-color: transparent; }
.nseo-lang-sq--progress::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: currentColor; animation: nseo-lang-pulse 1.4s ease-in-out infinite; }
.nseo-lang-sq--queued { background: rgba(180, 83, 9, 0.12); color: #b45309; border-color: transparent; cursor: default; }
.nseo-lang-sq--queued::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: currentColor; animation: nseo-lang-pulse 1.4s ease-in-out infinite; }
.nseo-lang-sq--failed { background: var(--danger-soft); color: var(--danger); border-color: transparent; }
.nseo-lang-sq--stale { background: rgba(99, 102, 241, 0.12); color: #4f46e5; border: 1px solid var(--warning); }

.nseo-pill--source-curation {
	background: rgba(217, 119, 6, 0.14);
	color: #b45309;
	text-decoration: none;
}
a.nseo-pill--source-curation:hover {
	background: rgba(217, 119, 6, 0.22);
	color: #92400e;
}

/* Toolbar horizontal de listado (compartida por articles/index y
   remote-posts/index). Combina las tabs a la izquierda con un slot
   derecho opcional (ej. botón "Filtrar" que despliega un panel debajo).
   El border-bottom vive en el toolbar — no en las tabs internas — para
   que la línea base baje hasta el botón derecho. Misma fila de altura
   en ambas pantallas: las dos tablas arrancan a la misma `y` en estado
   default. Si el filtro se despliega, el panel aparece debajo y empuja
   la tabla (estado interactivo, no default). */
.nseo-list-toolbar {
	display: flex;
	align-items: stretch;
	justify-content: space-between;
	gap: var(--space-4);
	margin: 0 0 var(--space-4) 0;
	border-bottom: 1px solid var(--border-subtle);
}
.nseo-list-toolbar .nseo-tabs {
	margin: 0;
	border-bottom: 0;
}
.nseo-list-toolbar__right {
	display: flex;
	align-items: center;
	gap: var(--space-2);
	padding-bottom: var(--space-2);
}
/* 1d: grupo izquierdo del toolbar — tabs de origen + desplegable "Estado"
   alineados horizontalmente (el segundo eje de filtro vive junto a las tabs). */
.nseo-list-toolbar__left {
	display: flex;
	align-items: center;
	gap: var(--space-5);
}
.nseo-status-filter {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
	padding-bottom: var(--space-2);
}
.nseo-status-filter__label {
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	color: var(--text-secondary);
	white-space: nowrap;
}
.nseo-status-filter__select {
	padding-top: 6px;
	padding-bottom: 6px;
	font-size: 13px;
}
.nseo-status-filter__checks {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-2);
	align-items: center;
}
.nseo-status-filter__check {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	font-size: 13px;
	color: var(--text-primary);
	cursor: pointer;
	padding: 4px 10px;
	border: 1px solid var(--border-subtle, #e2e2e2);
	border-radius: 999px;
	white-space: nowrap;
	user-select: none;
}
.nseo-status-filter__check:hover {
	border-color: var(--accent, #7c3aed);
}
.nseo-status-filter__check input {
	margin: 0;
	cursor: pointer;
}
/* Badge "Filtrado: N de M" en la fila del toolbar (a la derecha, por el
   justify-content:space-between de .nseo-list-toolbar). Pill de acento, visible
   al aplicar — deja claro el recorte que el orden por defecto enmascara. */
.nseo-filter-badge {
	align-self: center;
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 4px 12px;
	border-radius: var(--radius-pill);
	background: var(--brand-primary-soft);
	color: var(--brand-primary);
	font-size: 13px;
	font-weight: 600;
	white-space: nowrap;
}

/* Tabs (Fase 4.5.0e — listado de Borradores). Lenguaje visual similar a
   los headers sortables: tipografía 12px uppercase, gap entre tabs,
   underline en la activa con color brand. Cada tab lleva un contador
   discreto a su derecha. */
.nseo-tabs {
	display: flex;
	gap: 4px;
	margin: 0 0 var(--space-4) 0;
	border-bottom: 1px solid var(--border-subtle);
}
.nseo-tabs__tab {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 12px 16px;
	font-size: 13px;
	font-weight: 500;
	color: var(--text-secondary);
	text-decoration: none;
	border-bottom: 2px solid transparent;
	margin-bottom: -1px; /* compensa el border-bottom del nav */
	transition: color 120ms ease-in-out, border-color 120ms ease-in-out;
}
.nseo-tabs__tab:hover {
	color: var(--text-primary);
}
.nseo-tabs__tab--active {
	color: var(--brand, #6d28d9);
	border-bottom-color: var(--brand, #6d28d9);
	font-weight: 600;
}
.nseo-tabs__tab-count {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 22px;
	height: 18px;
	padding: 0 6px;
	font-size: 11px;
	font-weight: 600;
	background: var(--surface-sunken);
	color: var(--text-tertiary);
	border-radius: 999px;
}
.nseo-tabs__tab--active .nseo-tabs__tab-count {
	background: rgba(109, 40, 217, 0.12);
	color: var(--brand, #6d28d9);
}

/* Pieza 1: pestañas de la ficha de detalle (Contenido / Datos técnicos /
   Traducción N). Reutiliza el chrome .nseo-tabs; aquí las tabs son <button>
   (no <a>) → reset de apariencia nativa, y los paneles ocultan con [hidden]. */
.nseo-detail-tabs {
	margin-top: var(--space-4);
}
.nseo-detail-tabs .nseo-tabs__tab {
	background: none;
	border: none;
	border-bottom: 2px solid transparent;
	margin-bottom: -1px;
	cursor: pointer;
	font-family: inherit;
}
/* Los paneles replican el layout-en-columna que .nseo-article-detail daba a
   las secciones antes de envolverlas en pestañas: flex column + gap, para que
   los cards vuelvan a respirar (sin esto quedaban pegados). */
.nseo-tabpanel {
	display: flex;
	flex-direction: column;
	gap: var(--space-4);
}
.nseo-tabpanel[hidden] {
	display: none; /* gana por especificidad sobre .nseo-tabpanel (clase+attr). */
}

/* Franja de acciones de estado por versión (Aprobar · Rechazar · Borrar).
   Vive en la cabecera de la card Metadata (.nseo-meta-card__head), a la
   derecha del rótulo "METADATA SEO". Grupo flex con los 3 botones juntos. */
.nseo-status-strip {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-2);
}

/* Stale-translations (B3): marcador "Desactualizada" en la pestaña de una
   traducción desfasada (el original cambió tras traducirse) + banner de aviso
   sobre su card. Ámbar = atención, no error. */
.nseo-tabs__tab-flag {
	margin-left: var(--space-2);
	padding: 1px var(--space-2);
	border-radius: var(--radius-pill);
	background: #fef3c7;
	color: #92400e;
	font-size: 11px;
	font-weight: 600;
	line-height: 1.5;
	white-space: nowrap;
}
.nseo-stale-notice {
	border: 1px solid #fcd34d;
	border-left: 4px solid #f59e0b;
	background: #fffbeb;
	color: #92400e;
	border-radius: 8px;
	padding: var(--space-3) var(--space-4);
	font-size: var(--text-sm-size, 14px);
	line-height: 1.5;
}
.nseo-stale-notice strong {
	display: block;
	margin-bottom: 2px;
	color: #78350f;
}

/* incomplete_article: aviso sobre el contenido PARCIAL de un draft fallido por
   truncado estructural (se conserva y se muestra read-only). Ámbar de atención. */
.nseo-partial-notice {
	border-left: 4px solid #f59e0b;
	background: #fffbeb;
	color: #92400e;
	border-radius: 8px;
	padding: var(--space-3) var(--space-4);
	margin-bottom: var(--space-4);
}

/* ============================================================
 * Post Analysis screen (Fase 4.4.2b)
 * ----------------------------------------------------------------
 * Pantalla /sitios/<id>/posts/<localId>/analisis/ — reporta el VO
 * PostAnalysisResult con un layout de 3 columnas heredando el patrón
 * del wizard de artículos (Fase 3.7h) pero con una columna extra a
 * la izquierda para anclas de navegación in-page.
 *
 *   nav (240) │ center (1fr) │ aside (360)
 *
 * Colapsa a 1-col bajo 1100px (mismo breakpoint que el wizard).
 * ============================================================ */

/* Saneamiento UI homogeneización: las reglas `.nseo-page-header`,
   `.nseo-page-header__title` y `.nseo-page-header__sub` vivían aquí
   redefinidas sin scoping y ganaban en cascada sobre las canónicas
   (línea ~653). Quitadas — la pantalla de análisis pasa al patrón
   común (`__subtitle` en lugar de `__sub`).
   Las clases `.nseo-breadcrumbs*` se retiraron en Fase 4.5.0f a favor
   del partial canónico `partials/breadcrumb.php` (clases
   `.nseo-page__breadcrumb*`). Si alguien grep-ea por la clase antigua
   y aterriza aquí, ese es el camino. */

/* ─── 3-col layout shell ─────────────────────────────────────── */
.nseo-post-analysis-layout {
	display: grid;
	grid-template-columns: minmax(0, 1fr) 360px;
	gap: var(--space-8);
	align-items: start;
}
@media (max-width: 900px) {
	.nseo-post-analysis-layout { grid-template-columns: 1fr; }
	.nseo-post-analysis__aside { grid-column: 1 / -1; }
}

/* ─── Center column + card primitive ────────────────────────── */
.nseo-post-analysis__content {
	display: flex;
	flex-direction: column;
	gap: var(--space-6);
	min-width: 0; /* permite que tablas y previews internos no desborden el grid. */
}
.nseo-post-analysis__card {
	background: var(--surface-base);
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-lg);
	padding: var(--space-6);
	box-shadow: var(--shadow-sm);
	scroll-margin-top: 100px; /* anclas no quedan tapadas por la topbar sticky. */
}
.nseo-post-analysis__card h2 {
	margin: 0 0 var(--space-4) 0;
	font-size: var(--text-lg-size);
	line-height: var(--text-lg-lh);
	font-weight: 600;
	color: var(--text-primary);
}
.nseo-post-analysis__empty-line {
	color: var(--text-tertiary);
	font-style: italic;
	margin: 0;
}

/* ─── Main topic card ───────────────────────────────────────── */
/* Fase 4.5.x: aire vertical entre pretítulo (h2), título violeta y párrafo.
   Antes los tres elementos estaban demasiado juntos visualmente — h2 con
   space-4 abajo, título con space-3 abajo. Subimos ambos a space-5 para
   crear separación clara entre los tres bloques de información. */
#main-topic.nseo-post-analysis__card h2 {
	margin-bottom: var(--space-5);
}
.nseo-post-analysis__main-topic {
	font-size: var(--text-xl-size);
	line-height: var(--text-xl-lh);
	font-weight: 600;
	color: var(--brand-primary);
	margin: 0 0 var(--space-5) 0;
}
.nseo-post-analysis__assessment {
	font-size: var(--text-md-size);
	line-height: var(--text-md-lh);
	color: var(--text-secondary);
	margin: 0;
}
.nseo-post-analysis__assessment strong {
	color: var(--text-primary);
	font-weight: 600;
}

/* ─── Structure card (8 metrics 2-col grid) ─────────────────── */
.nseo-post-analysis__structure {
	margin: 0;
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--space-3) var(--space-6);
}
.nseo-post-analysis__structure > div {
	display: flex;
	justify-content: space-between;
	align-items: center;
	gap: var(--space-3);
	padding: var(--space-3) 0;
	border-bottom: 1px solid var(--border-subtle);
}
.nseo-post-analysis__structure dt {
	font-size: var(--text-sm-size);
	color: var(--text-secondary);
	font-weight: 500;
}
.nseo-post-analysis__structure dd {
	margin: 0;
	font-size: var(--text-md-size);
	font-weight: 600;
	color: var(--text-primary);
}

/* Bool chip (✓ / ✗) */
.nseo-bool {
	display: inline-flex;
	align-items: center;
	gap: var(--space-1);
	padding: 2px var(--space-2);
	border-radius: var(--radius-full);
	font-size: var(--text-xs-size);
	line-height: var(--text-xs-lh);
	font-weight: 600;
	border: 1px solid transparent;
}
.nseo-bool svg { width: 14px; height: 14px; }
.nseo-bool--yes {
	background: var(--success-soft);
	color: var(--success);
	border-color: rgba(16, 185, 129, 0.25);
}
.nseo-bool--no {
	background: var(--danger-soft);
	color: var(--danger);
	border-color: rgba(239, 68, 68, 0.25);
}

/* ─── Coverage table ────────────────────────────────────────── */
/* Fase 4.5.x: el card de Cobertura tenía contenido que visualmente se
   percibía centrado (el `text-align` del td no estaba especificado y
   heredaba defaults variables). Forzamos left-align defensivo en el
   card entero, la tabla y celdas para evitar cualquier herencia centrada. */
#coverage.nseo-post-analysis__card { text-align: left; }
.nseo-post-analysis__coverage {
	width: 100%;
	border-collapse: collapse;
	font-size: var(--text-sm-size);
	text-align: left;
}
.nseo-post-analysis__coverage thead th {
	text-align: left;
	font-weight: 600;
	color: var(--text-secondary);
	font-size: var(--text-xs-size);
	text-transform: uppercase;
	letter-spacing: 0.04em;
	padding: var(--space-2) var(--space-3);
	border-bottom: 1px solid var(--border-subtle);
	white-space: nowrap;
}
.nseo-post-analysis__coverage tbody td {
	padding: var(--space-3);
	border-bottom: 1px solid var(--border-subtle);
	color: var(--text-primary);
	vertical-align: middle;
	text-align: left;
}
.nseo-post-analysis__coverage tbody tr:last-child td { border-bottom: none; }

/* ─── Sistrix opportunities sub-block dentro del card de Estructura ──
   Lista compacta de keywords donde el dominio rankea pos 11-100 con
   potencial de subir al top10. Vive bajo el dl de Estructura pero
   visualmente separada con margin-top y un divider sutil. */
.nseo-post-analysis__opportunities {
	margin-top: var(--space-5);
	padding-top: var(--space-5);
	border-top: 1px solid var(--border-subtle);
}
.nseo-post-analysis__opportunities-title {
	margin: 0 0 var(--space-2) 0;
	font-size: var(--text-sm-size);
	font-weight: 600;
	color: var(--text-secondary);
	text-transform: uppercase;
	letter-spacing: 0.04em;
}
.nseo-post-analysis__opportunities-help {
	margin: 0 0 var(--space-3) 0;
	font-size: var(--text-xs-size);
	line-height: var(--text-sm-lh);
	color: var(--text-tertiary);
}
.nseo-post-analysis__opportunities-table {
	width: 100%;
	border-collapse: collapse;
	font-size: var(--text-sm-size);
	text-align: left;
}
.nseo-post-analysis__opportunities-table thead th {
	text-align: left;
	font-weight: 600;
	color: var(--text-secondary);
	font-size: var(--text-xs-size);
	text-transform: uppercase;
	letter-spacing: 0.04em;
	padding: var(--space-2) var(--space-3);
	border-bottom: 1px solid var(--border-subtle);
	white-space: nowrap;
}
.nseo-post-analysis__opportunities-table tbody td {
	padding: var(--space-2) var(--space-3);
	border-bottom: 1px solid var(--border-subtle);
	color: var(--text-primary);
	vertical-align: middle;
	text-align: left;
}
.nseo-post-analysis__opportunities-table tbody tr:last-child td { border-bottom: none; }
.nseo-post-analysis__opportunities-table tbody td:nth-child(n+2) {
	font-variant-numeric: tabular-nums;
	width: 1%;
	white-space: nowrap;
}

/* Presence badges — keyword visibility map */
.nseo-presence {
	display: inline-flex;
	align-items: center;
	padding: 2px var(--space-2);
	border-radius: var(--radius-full);
	font-size: var(--text-xs-size);
	line-height: var(--text-xs-lh);
	font-weight: 500;
	border: 1px solid transparent;
	text-transform: lowercase;
	white-space: nowrap;
}
.nseo-presence--title {
	background: var(--success-soft);
	color: var(--success);
	border-color: rgba(16, 185, 129, 0.25);
}
.nseo-presence--h2 {
	background: rgba(59, 130, 246, 0.12);
	color: #1d4ed8;
	border-color: rgba(59, 130, 246, 0.3);
}
.nseo-presence--body {
	background: var(--surface-sunken);
	color: var(--text-secondary);
	border-color: var(--border-subtle);
}
.nseo-presence--missing {
	background: var(--danger-soft);
	color: var(--danger);
	border-color: rgba(239, 68, 68, 0.25);
}

/* ─── Gaps list ─────────────────────────────────────────────── */
.nseo-post-analysis__gaps {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
}
.nseo-post-analysis__gaps li {
	display: flex;
	align-items: flex-start;
	gap: var(--space-3);
	padding: var(--space-3) var(--space-4);
	background: var(--warning-soft);
	border: 1px solid rgba(245, 158, 11, 0.25);
	border-radius: var(--radius-md);
	color: var(--text-primary);
	font-size: var(--text-sm-size);
	line-height: var(--text-sm-lh);
}
.nseo-post-analysis__gap-icon {
	flex: 0 0 18px;
	width: 18px;
	height: 18px;
	color: var(--warning);
	margin-top: 1px;
}

/* Nota discreta: aclara que los +N son independientes y por eso su suma no
   cuadra con el potencial (varias mejoras pueden tocar el mismo eje). */
.nseo-rec-impacts-note {
	margin: 0 0 var(--space-4);
	font-size: var(--text-sm-size);
	color: var(--text-secondary);
}

/* ─── Recommendations: numbered list with custom counter ────── */
.nseo-post-analysis__recommendations {
	margin: 0;
	padding: 0;
	list-style: none;
	counter-reset: nseo-recs;
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
}
/* Botón "Lo cubre mi plantilla" / "Devolver a pendientes". */
.nseo-rec-resolve,
.nseo-rec-unresolve {
	flex-shrink: 0;
	align-self: center;
	margin-left: auto;
	padding: 4px 10px;
	font-size: var(--text-xs-size);
	line-height: 1.4;
	border-radius: var(--radius-sm);
	border: 1px solid var(--border-default);
	background: var(--surface-base);
	color: var(--text-secondary);
	cursor: pointer;
	white-space: nowrap;
	transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.nseo-rec-resolve:hover {
	background: var(--brand-primary-soft);
	border-color: var(--brand-primary);
	color: var(--brand-primary);
}
.nseo-rec-resolve:disabled,
.nseo-rec-unresolve:disabled {
	opacity: 0.5;
	cursor: default;
}
/* Sección "Resueltas por tu plantilla". */
.nseo-resolved-section {
	margin-top: var(--space-5);
	padding-top: var(--space-4);
	border-top: 1px dashed var(--border-default);
}
.nseo-resolved-section__title {
	font-size: var(--text-base-size);
	margin: 0 0 var(--space-1);
	color: var(--text-secondary);
}
.nseo-resolved-section__hint {
	font-size: var(--text-xs-size);
	color: var(--text-muted);
	margin: 0 0 var(--space-3);
}
.nseo-post-analysis__recommendations--resolved li {
	background: var(--surface-subtle, rgba(0, 0, 0, 0.03));
	border-style: dashed;
	border-color: var(--border-default);
	color: var(--text-secondary);
	padding-right: var(--space-4);
}
.nseo-post-analysis__recommendations--resolved li::before {
	opacity: 0.5;
}
.nseo-post-analysis__recommendations li {
	counter-increment: nseo-recs;
	position: relative;
	overflow: hidden;
	display: flex;
	align-items: flex-start;
	gap: var(--space-3);
	padding: var(--space-3) var(--space-4);
	/* Reserva el ancho de la banda de impacto (pegada al borde derecho). */
	padding-right: calc(84px + var(--space-4));
	background: var(--brand-primary-soft);
	border: 1px solid rgba(99, 102, 241, 0.18);
	border-radius: var(--radius-md);
	color: var(--text-primary);
	font-size: var(--text-sm-size);
	line-height: var(--text-sm-lh);
}
.nseo-post-analysis__recommendations li::before {
	content: counter(nseo-recs);
	flex: 0 0 22px;
	height: 22px;
	border-radius: var(--radius-full);
	background: var(--brand-primary);
	color: var(--text-on-primary);
	font-size: var(--text-xs-size);
	font-weight: 700;
	display: inline-flex;
	align-items: center;
	justify-content: center;
}
/* fix(ui): la frase completa va en un solo bloque (un flex item) → fluye y
   ajusta línea como párrafo; antes el <strong> inicial y el resto del texto eran
   flex items separados del li y se partían en dos "columnas". */
.nseo-post-analysis__recommendations li .nseo-post-analysis__rec-text {
	flex: 1;
	min-width: 0;
}
/* Impacto DERIVADO por recomendación como BANDA de acento a altura completa,
   pegada al borde derecho del rectángulo (familia de los badges de paso: indigo
   sólido + número blanco grande). El número lo calcula el sistema (delta real
   del overall, método b). El `overflow:hidden` + border-radius del li redondean
   solo las esquinas DERECHAS de la banda; las izquierdas quedan rectas (pegan
   con el texto). Solo aparece en análisis nuevos con eje/objetivo. */
.nseo-post-analysis__recommendations li .nseo-rec-impact {
	position: absolute;
	top: 0;
	right: 0;
	bottom: 0;
	width: 84px;
	display: flex;
	align-items: center;
	justify-content: center;
	background: var(--brand-primary);
	color: #fff;
	font-size: 30px;
	font-weight: 700;
	line-height: 1;
}

/* ─── Footer meta line ──────────────────────────────────────── */
.nseo-post-analysis__meta {
	font-size: var(--text-xs-size);
	line-height: var(--text-xs-lh);
	color: var(--text-tertiary);
	padding: var(--space-3) 0 0 0;
	border-top: 1px solid var(--border-subtle);
	margin-top: 0;
}

/* ─── Right aside ───────────────────────────────────────────── */
.nseo-post-analysis__aside {
	position: sticky;
	top: 90px;
	display: flex;
	flex-direction: column;
	gap: var(--space-4);
	align-self: start;
}
@media (max-width: 1300px) {
	.nseo-post-analysis__aside {
		position: static;
	}
}

/* Post preview — iframe aislado vía srcdoc + sandbox.
 *
 * El iframe se renderiza con altura fija; el contenido del post scrollea
 * dentro de la propia iframe. Aísla `<style>`, `<script>` y estilos
 * inline del post (Elementor / Rank Math / JSON-LD) que de otro modo se
 * filtrarían al scope global y romperían el max-height del aside. La
 * tipografía base se inyecta dentro del srcdoc por el template. */
.nseo-post-analysis__preview {
	display: block;
	width: 100%;
	height: 420px;
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-md);
	background: var(--surface-sunken);
}

/* Actions list (Próximos pasos) */
.nseo-post-analysis__actions {
	list-style: none;
	padding: 0;
	margin: 0;
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
}
.nseo-post-analysis__actions .nseo-btn,
.nseo-post-analysis__actions .nseo-btn--ghost { width: 100%; justify-content: center; }

/* ─── Empty state (no cached analysis) ──────────────────────── */
/* Nota discreta de la pantalla de análisis de DRAFT (pre-publicación, sin
   datos de ranking). Informa que la ausencia de Sistrix es intencional. */
.nseo-analysis-prepublish-note {
	margin: 0 0 var(--space-4);
	padding: var(--space-2) var(--space-3);
	background: var(--surface-sunken);
	border-left: 3px solid var(--brand-primary);
	border-radius: var(--radius-sm);
	font-size: var(--text-sm-size);
	color: var(--text-secondary);
}

.nseo-analysis-empty {
	display: flex;
	justify-content: center;
}
.nseo-analysis-empty__inner {
	background: var(--surface-base);
	border: 1px dashed var(--border-default);
	border-radius: var(--radius-lg);
	padding: var(--space-12) var(--space-8);
	text-align: center;
	max-width: 560px;
	width: 100%;
}
.nseo-analysis-empty__title {
	margin: 0 0 var(--space-3) 0;
	font-size: var(--text-xl-size);
	font-weight: 600;
	color: var(--text-primary);
}
.nseo-analysis-empty__lead {
	margin: 0 0 var(--space-6) 0;
	color: var(--text-secondary);
	font-size: var(--text-md-size);
	line-height: var(--text-md-lh);
}

/* ============================================================
 * Post Analysis click flow (Fase 4.4.2c)
 * ----------------------------------------------------------------
 * Modal de confirmación + overlay de loading full-page + toasts.
 * ============================================================ */

.nseo-no-scroll {
	overflow: hidden;
}

/* ─── Modal ────────────────────────────────────────────────── */
.nseo-modal {
	position: fixed;
	inset: 0;
	z-index: 1000;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: var(--space-4);
}
.nseo-modal[hidden] { display: none; }
.nseo-modal__backdrop {
	position: absolute;
	inset: 0;
	background: rgba(9, 9, 11, 0.55);
	backdrop-filter: blur(2px);
}
.nseo-modal__panel {
	position: relative;
	background: var(--surface-base);
	border-radius: var(--radius-lg);
	box-shadow: var(--shadow-lg);
	width: 100%;
	max-width: 520px;
	max-height: calc(100vh - var(--space-8));
	overflow-y: auto;
	display: flex;
	flex-direction: column;
}
.nseo-modal__header {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: var(--space-3);
	padding: var(--space-5) var(--space-6) 0;
}
.nseo-modal__title {
	margin: 0;
	font-size: var(--text-lg-size);
	line-height: var(--text-lg-lh);
	font-weight: 600;
	color: var(--text-primary);
}
.nseo-modal__close {
	flex: 0 0 32px;
	width: 32px;
	height: 32px;
	border-radius: var(--radius-sm);
	border: none;
	background: transparent;
	color: var(--text-secondary);
	cursor: pointer;
	display: inline-flex;
	align-items: center;
	justify-content: center;
}
.nseo-modal__close svg { width: 18px; height: 18px; }
.nseo-modal__close:hover {
	background: var(--surface-hover);
	color: var(--text-primary);
}
.nseo-modal__body {
	padding: var(--space-4) var(--space-6) var(--space-2);
	color: var(--text-secondary);
	font-size: var(--text-sm-size);
	line-height: var(--text-sm-lh);
}
.nseo-modal__body p { margin: 0 0 var(--space-3); }
.nseo-modal__body p:last-child { margin-bottom: 0; }
.nseo-modal__warning {
	margin-top: var(--space-3);
	padding: var(--space-3);
	border-radius: var(--radius-md);
	background: var(--danger-soft);
	color: var(--danger);
	font-size: var(--text-sm-size);
	line-height: var(--text-sm-lh);
	font-weight: 500;
}
.nseo-modal__field {
	margin-top: var(--space-4);
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
}
.nseo-modal__field label {
	font-size: var(--text-sm-size);
	font-weight: 600;
}
.nseo-modal__field input {
	width: 100%;
}
.nseo-modal__field small {
	color: var(--text-muted);
	font-size: var(--text-xs-size);
	line-height: var(--text-xs-lh);
}
.nseo-modal__footer {
	display: flex;
	justify-content: flex-end;
	gap: var(--space-2);
	padding: var(--space-4) var(--space-6) var(--space-6);
	border-top: 1px solid var(--border-subtle);
	margin-top: var(--space-4);
}

/* ─── Resumen read-only del modal de confirmación de gasto ────
 * Compartido por el modal de creación ([data-nseo-generate-confirm]) y el de
 * curación ([data-nseo-curation-confirm]). Lo rellena {article,curation}-wizard.js
 * desde buildSummaryModel (fuente única con el cost preview sticky). */
.nseo-confirm-lead {
	margin: 0 0 var(--space-4);
	color: var(--text-secondary);
}
.nseo-confirm-summary {
	display: grid;
	grid-template-columns: minmax(120px, max-content) 1fr;
	gap: var(--space-2) var(--space-4);
	margin: 0 0 var(--space-4);
}
.nseo-confirm-summary dt {
	font-weight: 600;
	color: var(--text-secondary);
}
.nseo-confirm-summary dd {
	margin: 0;
	color: var(--text-primary);
}
.nseo-confirm-extras {
	margin: var(--space-1) 0 0;
	padding-left: var(--space-4);
	list-style: disc;
}
.nseo-confirm-extras li { margin: 0 0 var(--space-1); }
.nseo-confirm-cost {
	margin: 0;
	padding-top: var(--space-3);
	border-top: 1px solid var(--border-subtle);
	font-size: var(--text-md-size);
	color: var(--text-primary);
}
.nseo-confirm-proposal {
	margin: var(--space-3) 0 0;
	padding: var(--space-3);
	border-radius: var(--radius-md);
	background: var(--surface-muted);
	color: var(--text-secondary);
	font-size: var(--text-sm-size);
	line-height: var(--text-sm-lh);
}

/* ─── Loading overlay ─────────────────────────────────────── */
.nseo-loading-overlay {
	position: fixed;
	inset: 0;
	z-index: 1100;
	display: flex;
	align-items: center;
	justify-content: center;
	background: rgba(255, 255, 255, 0.92);
	backdrop-filter: blur(4px);
}
.nseo-loading-overlay[hidden] { display: none; }
.nseo-loading-overlay__inner {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--space-4);
	padding: var(--space-8);
	text-align: center;
}
.nseo-loading-overlay__spinner {
	width: 48px;
	height: 48px;
	border-radius: var(--radius-full);
	border: 3px solid var(--brand-primary-soft);
	border-top-color: var(--brand-primary);
	animation: nseo-spin 0.8s linear infinite;
}
@keyframes nseo-spin {
	to { transform: rotate(360deg); }
}
.nseo-loading-overlay__text {
	margin: 0;
	font-size: var(--text-md-size);
	line-height: var(--text-md-lh);
	font-weight: 500;
	color: var(--text-primary);
}
.nseo-loading-overlay__hint {
	margin: 0;
	font-size: var(--text-sm-size);
	color: var(--text-tertiary);
}

/* ─── Toasts ──────────────────────────────────────────────── */
.nseo-toast-container {
	position: fixed;
	bottom: var(--space-6);
	right: var(--space-6);
	z-index: 1200;
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
	pointer-events: none;
}
.nseo-toast {
	pointer-events: auto;
	padding: var(--space-3) var(--space-4);
	border-radius: var(--radius-md);
	background: var(--surface-base);
	box-shadow: var(--shadow-lg);
	font-size: var(--text-sm-size);
	line-height: var(--text-sm-lh);
	max-width: 360px;
	border-left: 4px solid var(--text-secondary);
	color: var(--text-primary);
	opacity: 0;
	transform: translateX(16px);
	transition: opacity 0.2s ease, transform 0.2s ease;
}
.nseo-toast--shown {
	opacity: 1;
	transform: translateX(0);
}
.nseo-toast--error   { border-left-color: var(--danger); }
.nseo-toast--success { border-left-color: var(--success); }
.nseo-toast--warning { border-left-color: var(--warning); }

/* ============================================================
   Brand style screen (Fase 8.4b.1.1 — armonizada con article-detail)
   ------------------------------------------------------------
   El template envuelve con doble clase
   `<div class="nseo-article-detail nseo-page--brand-style">`. La
   primera hereda el chrome real del idioma del plugin (canvas gris
   suave, cards con border/radius/shadow/padding, .nseo-card__title
   26px). La segunda mantiene el scope local para 1) reset de UL
   dentro de cards y 2) cualquier ajuste mínimo de esta pantalla.

   CERO regla nueva para `.nseo-card` aquí: la heredamos de
   `.nseo-article-detail > .nseo-card` (línea ~1549). NO toques esa
   regla global desde aquí.
   ============================================================ */
.nseo-page--brand-style .nseo-card ul {
	margin: 0;
	padding-left: 20px;
	color: var(--text-secondary);
}
.nseo-page--brand-style .nseo-card ul li {
	margin-bottom: 6px;
}
.nseo-page--brand-style .nseo-card ul li:last-child {
	margin-bottom: 0;
}

/* Layout específico (Fase 8.4b.1.1): grid 2 cols con Voz extendida en
   full-width al final. Pisa el `display: flex` que .nseo-article-detail
   declara en línea 1424 — el flex genérico funciona en article-detail
   real (cards de tamaños muy dispares) pero para perfil editorial las
   7 secciones cortas + 1 narrativa larga encajan mejor en grid 2 cols.
   Scope estricto a .nseo-page--brand-style: NO contamina
   .nseo-article-detail global. */
.nseo-page--brand-style {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--space-4);
}
.nseo-page--brand-style > .nseo-page-header,
.nseo-page--brand-style > .nseo-card--wide {
	grid-column: 1 / -1;
}
@media (max-width: 900px) {
	.nseo-page--brand-style {
		grid-template-columns: 1fr;
	}
}

/* Alineación al lenguaje común (config/curación): las cards del perfil pasan a
   borde de acento indigo + tokens + padding space-6, planas (sin sombra), y los
   títulos de card a 18px. SCOPEADO a .nseo-page--brand-style — la regla
   compartida `.nseo-article-detail > .nseo-card` (detalle de artículo) NO se
   toca; esta override gana por orden de fuente a igual especificidad (0,2,0). */
.nseo-page--brand-style .nseo-card {
	border-color: var(--brand-primary);
	border-radius: var(--radius-lg);
	padding: var(--space-6);
	box-shadow: none;
}
.nseo-page--brand-style .nseo-card__title {
	font-size: var(--text-lg-size);
	line-height: var(--text-lg-lh);
	letter-spacing: normal;
	color: var(--text-primary);
}

/* Reset de párrafos para Voz extendida — `body.nseo-frontend p` (línea
   147) aplica `margin: 0` global. Aquí restauramos separación entre
   párrafos consecutivos y entre párrafos y listas para que el Markdown
   renderizado por MarkdownLite se lea con aire. */
.nseo-page--brand-style .nseo-card--wide p + p,
.nseo-page--brand-style .nseo-card--wide p + ul,
.nseo-page--brand-style .nseo-card--wide ul + p {
	margin-top: 16px;
}

/* Modal de progreso del job async (L52: movido de panel inline a
   `.nseo-modal--progress`, mismo patrón que Próximos temas). El cuerpo centra
   spinner + estado + timer + hint en columna dentro del `.nseo-modal__panel`.
   Duplicación deliberada del scope de topic-proposals — misma política que el
   resto de reglas 8.4 (memoria phase-8-4-scoped-card-pattern); cada pantalla
   porta su copia hasta que se consensúe una base compartida. Los tokens de
   elemento (`__status/__timer/__hint`) se reusan tal cual dentro del modal. */
.nseo-page--brand-style .nseo-modal__progress {
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
	gap: var(--space-2);
	padding-top: var(--space-6);
	padding-bottom: var(--space-5);
}
.nseo-page--brand-style .nseo-modal__progress .nseo-spinner {
	margin: 0 0 var(--space-2);
	width: 40px;
	height: 40px;
	border-width: 3px;
}
.nseo-page--brand-style .nseo-modal__progress .nseo-spinner[hidden] {
	display: none;
}
.nseo-page--brand-style .nseo-brand-progress__status {
	font-size: 14px;
	font-weight: 500;
	margin: 0;
	color: var(--text-primary);
}
.nseo-page--brand-style .nseo-brand-progress__timer {
	font-variant-numeric: tabular-nums;
	font-size: 13px;
	color: var(--text-secondary);
	margin: 4px 0 0;
}
.nseo-page--brand-style .nseo-brand-progress__timer:empty {
	display: none;
}
.nseo-page--brand-style .nseo-brand-progress__hint {
	font-size: 12px;
	color: var(--text-tertiary);
	margin: 8px 0 0;
}
.nseo-page--brand-style .nseo-brand-progress__hint[hidden] {
	display: none;
}
/* En error el spinner se oculta vía [hidden] desde JS; el estado pasa a danger. */
.nseo-page--brand-style .nseo-modal--error .nseo-modal__progress .nseo-brand-progress__status {
	color: var(--danger);
}
/* Footer de acciones: arranca oculto; el JS lo revela en error
   (Reintentar/Cerrar). El `.nseo-modal__footer` base fija display:flex y
   pisaría el [hidden] por defecto. */
.nseo-page--brand-style .nseo-modal__footer[hidden] {
	display: none;
}

/* ============================================================
   Próximos temas a publicar (Fase 8.4c.1).

   Wrapper doble `<div class="nseo-article-detail nseo-page--topic-proposals">`.
   La primera clase aporta el chrome real (canvas gris, cards con padding
   32px, .nseo-card__title 26px); la segunda es el scope local de esta
   pantalla.

   CERO regla nueva para `.nseo-card` aquí: la heredamos de
   `.nseo-article-detail > .nseo-card` (línea ~1549).

   `.nseo-chip` y `.nseo-brand-progress` viven aquí scopeadas a la
   pantalla — duplicación deliberada respecto a 8.4b.2, anotada en la
   memoria phase-8-4-scoped-card-pattern. Cada pantalla 8.4 porta su
   propia copia para no contaminar reglas globales mientras la
   extracción a base compartida no está consensuada.
   ============================================================ */
.nseo-page--topic-proposals {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 12px 20px;
}
.nseo-page--topic-proposals > .nseo-page-header,
.nseo-page--topic-proposals > .nseo-card--wide {
	grid-column: 1 / -1;
}
.nseo-page--topic-proposals > .nseo-page-header {
	margin-bottom: var(--space-3);
}

/* Aprovechar espacio: las tarjetas de esta pantalla van SIN marco (sin borde,
 * sombra ni fondo de tarjeta) y con padding reducido. Se separan por una línea
 * fina superior en lugar del recuadro. Todo scopeado a esta pantalla para no
 * afectar a las cards del resto de la app. */
.nseo-page--topic-proposals > .nseo-card,
.nseo-page--topic-proposals > .nseo-card--wide {
	border: 0;
	box-shadow: none;
	background: transparent;
	border-radius: 0;
	padding: 16px 0 4px;
}
.nseo-page--topic-proposals > .nseo-card + .nseo-card {
	border-top: 1px solid var(--border-subtle);
}
/* El bloque de filtros: sin marco y sin padding lateral, alineado al contenido. */
.nseo-page--topic-proposals .nseo-topic-proposals-filters {
	padding: 0 0 4px;
	border-top: 0;
}

/* En Próximos temas, la fila de filtros/switcher sube para quedar pegada al
 * subtítulo: neutralizamos el min-height del parche anti-baile y reducimos el
 * margen inferior de la cabecera (scopeado a esta pantalla). */
.nseo-page--topic-proposals > .nseo-page-header {
	min-height: 0;
	margin-bottom: var(--space-3);
}

@media (max-width: 900px) {
	.nseo-page--topic-proposals {
		grid-template-columns: 1fr;
	}
}

/* Filtros — fila full-width con dos selects + botón "Limpiar filtros". */
.nseo-page--topic-proposals .nseo-topic-proposals-filters > form {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	gap: 16px;
}
.nseo-page--topic-proposals .nseo-topic-proposals-filters__group {
	display: flex;
	flex-direction: column;
	gap: 4px;
	min-width: 200px;
}
.nseo-page--topic-proposals .nseo-topic-proposals-filters__group .nseo-edit-field__label {
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.06em;
	color: var(--text-tertiary);
	text-transform: uppercase;
}

/* Header del card (título + chips). El título 26px lo aporta
   `.nseo-card__title` global; aquí sólo añadimos el layout. */
.nseo-page--topic-proposals .nseo-topic-proposal__header {
	display: flex;
	flex-direction: column;
	gap: 10px;
	margin-bottom: 10px;
}
.nseo-page--topic-proposals .nseo-topic-proposal__chips {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
}

/* Justification — párrafo del cuerpo. Restauramos margin que el reset
   global de `body.nseo-frontend p` (línea 147) pisa a 0. */
.nseo-page--topic-proposals .nseo-topic-proposal__body {
	margin: 0 0 10px;
	color: var(--text-primary);
	line-height: 1.55;
}

/* Meta ENCAJE — label corto + valor en línea. */
.nseo-page--topic-proposals .nseo-topic-proposal__meta {
	display: flex;
	gap: 12px;
	align-items: flex-start;
	padding: 12px 14px;
	background: var(--surface-sunken);
	border-radius: 8px;
	margin-bottom: 10px;
	color: var(--text-secondary);
	font-size: 14px;
	line-height: 1.5;
}
.nseo-page--topic-proposals .nseo-topic-proposal__meta-label {
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.06em;
	color: var(--text-tertiary);
	text-transform: uppercase;
	flex-shrink: 0;
	padding-top: 2px;
}

/* Keywords — fila de chips secundarias debajo del meta. */
.nseo-page--topic-proposals .nseo-topic-proposal__keywords {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	margin-bottom: 12px;
}

/* Footer del card — acciones primaria + destructiva alineadas a la
   izquierda. `nseo-btn--ghost.nseo-btn--danger` es la combinación que
   usa "Eliminar" para parecer ghost pero con el matiz destructivo. */
.nseo-page--topic-proposals .nseo-topic-proposal__footer {
	display: flex;
	gap: 12px;
	flex-wrap: wrap;
	border-top: 1px solid var(--border-subtle);
	padding-top: 12px;
}

/* Chip local — declaración scopeada que pisa la regla global de la
   línea 596 sólo dentro de esta pantalla. Mantiene la geometría tipo
   pill (consistente con el resto del plugin) pero permite la variante
   por prioridad (`--alta`/`--media`/`--baja`) y secundaria.

   Decisión consciente (memoria phase-8-4-scoped-card-pattern): cuando
   se aborde la extracción global de chip, esta capa local se borra. */
.nseo-page--topic-proposals .nseo-chip {
	display: inline-flex;
	align-items: center;
	padding: 4px 10px;
	font-size: 12px;
	font-weight: 500;
	color: var(--text-primary);
	background: var(--bg-muted);
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-pill);
	line-height: 1.4;
}
.nseo-page--topic-proposals .nseo-chip--alta {
	color: #92400e;
	background: rgba(217, 119, 6, 0.12);
	border-color: rgba(217, 119, 6, 0.3);
}
.nseo-page--topic-proposals .nseo-chip--media {
	color: #1d4ed8;
	background: rgba(59, 130, 246, 0.12);
	border-color: rgba(59, 130, 246, 0.3);
}
.nseo-page--topic-proposals .nseo-chip--baja {
	color: var(--text-secondary);
	background: var(--bg-muted);
	border-color: var(--border-subtle);
}
.nseo-page--topic-proposals .nseo-chip--secondary {
	font-weight: 400;
	color: var(--text-secondary);
}

/* Empty state CTA (estado B) — mismo espaciado que perfil editorial. */
.nseo-page--topic-proposals .nseo-brand-empty__cta {
	margin-top: 16px;
}

/* ── Empty-state con CTA y coste destacado (.nseo-empty-cta) ─────────────
   Patrón COMPARTIDO (partial empty-state-cta.php). Lo usan pantallas
   estructuralmente idénticas — Próximos temas ("Arranca tu cadena editorial")
   y Perfil editorial ("Aún no hay perfil editorial"). NO scopeado por pantalla
   a propósito: ambas comparten exactamente el mismo layout para no divergir.
   Tres niveles de jerarquía (qué es / qué cuesta / qué haces) con aire entre
   ellos, contenido centrado y en columna de lectura dentro de la card
   full-width. Reusa el idioma del patrón .nseo-empty (icono, título, lead)
   pero sin su caja punteada — aquí el contenedor es la propia card. */
.nseo-empty-cta {
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
}
/* Borde neutro: en Perfil editorial `.nseo-page--brand-style .nseo-card` pinta
   el borde con acento de marca; el empty-state no debe llevarlo. `.nseo-card`
   + `.nseo-empty-cta` iguala especificidad (0,2,0) y gana por orden de fuente,
   sin scope de pantalla (en Próximos temas ya era neutro; queda consistente). */
.nseo-card.nseo-empty-cta {
	border-color: var(--border-default);
}
/* display:flex pisaría el [hidden] con que el JS oculta el bloque al arrancar
   el análisis (topic-proposals + brand-style). Restituye el hide. */
.nseo-empty-cta[hidden] { display: none; }
/* Columna de lectura: limita el ancho de los bloques de texto (~560px) en vez
   de estirarse a todo el ancho de la card. */
.nseo-empty-cta .nseo-empty__lead,
.nseo-empty-cta__note,
.nseo-empty-cta__alt {
	max-width: 560px;
}
/* El lead trae margin-bottom 24px del patrón .nseo-empty; en flex column los
   márgenes no colapsan, así que lo anulamos y dejamos que el espaciado entre
   niveles lo lleve el margin-top de cada bloque siguiente (explícito y único). */
.nseo-empty-cta .nseo-empty__lead {
	margin-bottom: 0;
}

/* Nivel 2 — coste destacado (fuera de la cursiva gris) + desglose secundario. */
.nseo-empty-cta__cost {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--space-1);
	margin-top: var(--space-6);
}
.nseo-empty-cta__cost-amount {
	font-size: var(--text-xl-size);
	line-height: var(--text-xl-lh);
	font-weight: 600;
	color: var(--text-primary);
}
.nseo-empty-cta__cost-breakdown {
	font-size: var(--text-sm-size);
	color: var(--text-secondary);
}
/* Nota informativa "corre en segundo plano" — línea aparte, sutil, con icono. */
.nseo-empty-cta__note {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
	margin-top: var(--space-3);
	font-size: var(--text-sm-size);
	line-height: var(--text-sm-lh);
	color: var(--text-tertiary);
}
.nseo-empty-cta__note svg { flex: 0 0 auto; }

/* Nivel 3 — más aire antes del primario; la acción secundaria queda como
   enlace diferenciado, separada del botón (no cursiva suelta). */
.nseo-empty-cta__action {
	margin-top: var(--space-6);
}
.nseo-empty-cta__alt {
	margin-top: var(--space-4);
	font-size: var(--text-sm-size);
	line-height: var(--text-sm-lh);
	color: var(--text-secondary);
}

/* ── Wizard de onboarding SECUENCIAL (una pantalla por paso) ──────────────
   La pantalla a mostrar la decide OnboardingController::resolveScreen; aquí solo
   el estilo de una pantalla a la vez + el indicador de progreso. */
.nseo-onboarding__title {
	font-size: var(--text-xl-size);
	line-height: var(--text-xl-lh);
	font-weight: 600;
	color: var(--text-primary);
	margin: 0 0 var(--space-3);
}
.nseo-onboarding__lead {
	color: var(--text-secondary);
	margin: 0 0 var(--space-5);
}
.nseo-onboarding__cost {
	color: var(--text-secondary);
	font-size: var(--text-sm-size);
	margin: 0 0 var(--space-4);
}
.nseo-onboarding__cta {
	display: flex;
	gap: var(--space-3);
	flex-wrap: wrap;
	align-items: center;
	margin-top: var(--space-5);
}
.nseo-onboarding__back {
	margin-top: var(--space-4);
	font-size: var(--text-sm-size);
}
.nseo-page--onboarding .nseo-onboarding-instructions {
	margin: 0 0 var(--space-4);
	padding-left: var(--space-5);
	color: var(--text-secondary);
	display: flex;
	flex-direction: column;
	gap: var(--space-1);
}
.nseo-onboarding-recheck { display: inline; margin: 0; }

/* Vista previa de los 5 pasos en la bienvenida. */
.nseo-onboarding-preview {
	list-style: none;
	margin: 0 0 var(--space-8);
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: var(--space-4);
}
.nseo-onboarding-preview__item {
	display: flex;
	align-items: center;
	gap: var(--space-3);
	color: var(--text-secondary);
}
.nseo-onboarding-preview__n {
	flex: 0 0 24px;
	width: 24px;
	height: 24px;
	border-radius: var(--radius-pill);
	display: inline-flex;
	align-items: center;
	justify-content: center;
	font-size: var(--text-sm-size);
	font-weight: 600;
	background: var(--surface-muted);
	border: 1px solid var(--border-default);
}

/* Indicador de progreso: "Paso N de 5" + puntos. */
.nseo-onboarding-progress {
	display: flex;
	align-items: center;
	gap: var(--space-3);
	margin-bottom: var(--space-5);
}
.nseo-onboarding-progress__label {
	font-size: var(--text-sm-size);
	color: var(--text-secondary);
	font-weight: 600;
}
.nseo-onboarding-progress__dots { display: inline-flex; gap: var(--space-1); }
.nseo-onboarding-progress__dot {
	width: 8px;
	height: 8px;
	border-radius: var(--radius-pill);
	background: var(--border-default);
}
.nseo-onboarding-progress__dot.is-done { background: var(--brand-primary); opacity: 0.5; }
.nseo-onboarding-progress__dot.is-current { background: var(--brand-primary); }

/* Layout enfocado del wizard (sin sidebar): topbar de marca + columna ancha. */
.nseo-frontend--wizard { background: var(--surface-raised); }
.nseo-wizard-topbar {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-3);
	padding: var(--space-4) var(--space-6);
	background: var(--surface-base);
	border-bottom: 1px solid var(--border-subtle);
}
.nseo-wizard-topbar__brand {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
}
.nseo-wizard-topbar__exit {
	font-size: var(--text-sm-size);
	color: var(--text-secondary);
	text-decoration: none;
}
.nseo-wizard-topbar__exit:hover { color: var(--text-primary); }
.nseo-wizard-main {
	/* +50% (720→1080): los pasos opcionales embeben pantallas densas y a 720px
	   quedaban apretadas. max-width (no width) → responsive: en viewports menores
	   se ajusta al ancho disponible menos el padding, sin desbordar. */
	max-width: 1080px;
	margin: 0 auto;
	padding: var(--space-8) var(--space-4);
}

/* Forma 2: dentro del wizard (OnboardingChrome) la cabecera propia de la pantalla
   embebida sobra y contradice — la cabecera "Paso N de M" ya cumple esa función.
   Ocultamos breadcrumb + título + subtítulo/meta de estado, pero NO las acciones
   (Sincronizar / Analizar / Proponer viven en .nseo-page-header__actions y deben
   seguir funcionando). Scopeado a .nseo-onboarding-embed__content, que solo existe
   dentro del wizard → en acceso normal desde el menú la cabecera sigue visible. */
.nseo-onboarding-embed__content .nseo-page__breadcrumb,
.nseo-onboarding-embed__content .nseo-page-header__title,
.nseo-onboarding-embed__content .nseo-page-header__subtitle,
.nseo-onboarding-embed__content .nseo-page-header__meta {
	display: none;
}

/* Banner "Volver a la configuración" en las pantallas dedicadas (?from=onboarding).
   Genérico (no scopeado a una pantalla): aparece en perfil-editorial/temas/posts. */
.nseo-onboarding-return {
	display: flex;
	align-items: center;
	gap: var(--space-3);
	padding: var(--space-3) var(--space-4);
	margin-bottom: var(--space-4);
	border-radius: var(--radius-md);
	background: var(--info-soft);
	color: var(--text-secondary);
	font-size: var(--text-sm-size);
}
.nseo-onboarding-return a { font-weight: 600; }

/* Sugerencias de onboarding pendientes en la ficha de sitio del dashboard (O4). */
.nseo-dash-suggestions {
	margin-top: var(--space-3);
	padding: var(--space-3) var(--space-4);
	border-radius: var(--radius-md);
	background: var(--surface-muted);
}
.nseo-dash-suggestions__title {
	display: block;
	font-size: var(--text-sm-size);
	font-weight: 600;
	color: var(--text-secondary);
	margin-bottom: var(--space-2);
}
.nseo-dash-suggestions__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: var(--space-1);
}
.nseo-dash-suggestion__label { font-size: var(--text-sm-size); }
.nseo-dash-suggestion.is-locked { opacity: 0.6; }
.nseo-dash-suggestion.is-locked .nseo-dash-suggestion__lock {
	font-size: var(--text-sm-size);
	color: var(--text-tertiary);
	margin-left: var(--space-2);
}

/* Panel inline de progreso/error para POST /generate (estado B). Mismo
   layout que `.nseo-page--brand-style .nseo-brand-progress` — copia
   deliberada bajo el scope local. */
.nseo-page--topic-proposals .nseo-brand-progress {
	grid-column: 1 / -1;
	display: flex;
	gap: 20px;
	background: var(--surface-raised);
	border: 1px solid var(--border-subtle);
	border-left: 4px solid var(--brand-primary);
	border-radius: 12px;
	padding: 24px;
	align-items: center;
}
.nseo-page--topic-proposals .nseo-brand-progress--error {
	border-left-color: var(--danger);
	align-items: flex-start;
}
.nseo-page--topic-proposals .nseo-brand-progress .nseo-spinner {
	margin: 0;
	width: 36px;
	height: 36px;
	border-width: 3px;
	flex-shrink: 0;
}
.nseo-page--topic-proposals .nseo-brand-progress--error .nseo-spinner {
	display: none;
}
.nseo-page--topic-proposals .nseo-brand-progress__body {
	flex: 1;
	min-width: 0;
}
.nseo-page--topic-proposals .nseo-brand-progress__status {
	font-size: 14px;
	font-weight: 500;
	margin: 0;
	color: var(--text-primary);
}
.nseo-page--topic-proposals .nseo-brand-progress__timer {
	font-variant-numeric: tabular-nums;
	font-size: 13px;
	color: var(--text-secondary);
	margin: 4px 0 0;
}
.nseo-page--topic-proposals .nseo-brand-progress__timer:empty {
	display: none;
}
.nseo-page--topic-proposals .nseo-brand-progress__hint {
	font-size: 12px;
	color: var(--text-tertiary);
	margin: 8px 0 0;
}
.nseo-page--topic-proposals .nseo-brand-progress__hint[hidden] {
	display: none;
}
.nseo-page--topic-proposals .nseo-brand-progress__actions {
	display: flex;
	gap: 12px;
	margin-top: 16px;
}
.nseo-page--topic-proposals .nseo-brand-progress__actions[hidden] {
	display: none;
}

/* M4: modal de progreso de generación ("Generar más" + "Analizar y proponer").
   El cuerpo centra spinner + estado + timer + hint en columna dentro del
   `.nseo-modal__panel`; reusa los tokens `.nseo-brand-progress__status/__timer/
   __hint` definidos arriba y sólo aporta el layout y el estado de error. */
.nseo-page--topic-proposals .nseo-modal__progress {
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
	gap: var(--space-2);
	padding-top: var(--space-6);
	padding-bottom: var(--space-5);
}
.nseo-page--topic-proposals .nseo-modal__progress .nseo-spinner {
	margin: 0 0 var(--space-2);
	width: 40px;
	height: 40px;
	border-width: 3px;
}
.nseo-page--topic-proposals .nseo-modal__progress .nseo-spinner[hidden] {
	display: none;
}
/* En error el spinner se oculta vía [hidden] desde JS; el estado pasa a danger. */
.nseo-page--topic-proposals .nseo-modal--error .nseo-modal__progress .nseo-brand-progress__status {
	color: var(--danger);
}
/* Footer de acciones: arranca oculto (sin "Seguir"). El JS lo revela en
   completado (Seguir) o error (Reintentar/Cerrar). Hace falta porque el
   `.nseo-modal__footer` base fija display:flex y pisaría el [hidden] por defecto. */
.nseo-page--topic-proposals .nseo-modal__footer[hidden] {
	display: none;
}

/* ----------------------------------------------------------------------
 * 8.4d: banner "Desde Próximos temas" en el wizard de generación.
 * Se inserta entre el page-header y el form cuando el wizard se carga con
 * `?from_proposal=ID`. La estructura es card con identidad propia (acento
 * de marca) para que el operador entienda que el wizard está "anclado" a
 * una propuesta y no empezó vacío.
 * ---------------------------------------------------------------------- */
.nseo-from-proposal-banner {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: 24px;
	margin: 0 0 24px;
	padding: 16px 20px;
	background: var(--brand-primary-soft, #eef2ff);
	border: 1px solid var(--brand-primary, #6366f1);
	border-left-width: 4px;
	border-radius: 8px;
}
.nseo-from-proposal-banner__body {
	flex: 1 1 auto;
	min-width: 0;
}
.nseo-from-proposal-banner__eyebrow {
	font-size: 12px;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	font-weight: 600;
	color: var(--brand-primary, #6366f1);
	margin-bottom: 4px;
}
.nseo-from-proposal-banner__title {
	font-size: 18px;
	font-weight: 600;
	color: var(--ink-1, #1f2937);
	line-height: 1.4;
}
.nseo-from-proposal-banner__help {
	margin: 6px 0 0;
	color: var(--ink-2, #4b5563);
	font-size: 13.5px;
	line-height: 1.55;
}
.nseo-from-proposal-banner__cta {
	flex: 0 0 auto;
}

/* ============================================================================
 * Rediseño visual del wizard de generar artículo (/articulos/nuevo/).
 *
 * Scopeado a `.nseo-page--article-new` (clase en el <form> del wizard + en su
 * modal de confirmación) para no tocar el resto de pantallas, que siguen
 * leyendo los tokens/clases globales. Base negro/gris/blanco; coral
 * (`--nseo-coral`) SOLO en: objetivo seleccionado, número del total y botón
 * Generar. El indicador de sitio activo del sidebar (también coral) vive en
 * el bloque global del sidebar, no aquí. Patrón scopeado por pantalla (mismo
 * que el resto del proyecto): duplicar reglas es intencional, no refactor.
 * ========================================================================= */

/* Rejilla invisible de 2 columnas para las cajas numeradas. Contexto(1),
 * Tema(2) y Validación(★) ocupan ancho completo (subcolumnas internas / texto
 * largo); Estructura(3) y Extras(4) comparten fila. */
.nseo-page--article-new .nseo-wizard-form {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--space-6);
	align-items: start;
}
.nseo-page--article-new .nseo-wizard-form > .nseo-section-card--full {
	grid-column: 1 / -1;
}
@media (max-width: 1100px) {
	.nseo-page--article-new .nseo-wizard-form {
		grid-template-columns: 1fr;
	}
}

/* --- Limpieza de color: indigo/verde → grayscale dentro del wizard --- */
/* VIS.1: el badge de paso pasa a ser un CUADRO indigo de alto completo, con el
   número (o la ★ de Calidad) en blanco y grande. La altura se iguala a la de la
   cabecera vía align-stretch (varía con el largo de la descripción). */
.nseo-page--article-new .nseo-step-badge,
.nseo-page--article-new .nseo-step-badge--quality {
	width: 48px;
	height: auto;
	align-self: stretch;
	border-radius: var(--radius-md);
	background: var(--brand-primary);
	color: #fff;
	font-size: 22px;
	font-weight: 700;
}
.nseo-page--article-new .nseo-section-eyebrow,
.nseo-page--article-new .nseo-section-eyebrow--quality {
	color: var(--text-secondary);
}
.nseo-page--article-new .nseo-lang-chip.is-active {
	background: var(--surface-sunken);
	border-color: var(--border-default);
	color: var(--text-primary);
}
.nseo-page--article-new .nseo-input:focus,
.nseo-page--article-new .nseo-textarea:focus,
.nseo-page--article-new .nseo-select:focus {
	border-color: var(--border-strong);
	box-shadow: 0 0 0 3px rgba( 9, 9, 11, 0.08 );
}
.nseo-page--article-new .nseo-quality-info {
	background: var(--surface-sunken);
}
.nseo-page--article-new .nseo-quality-info__title { color: var(--text-primary); }
.nseo-page--article-new .nseo-quality-info__text p { color: var(--text-secondary); }
/* Píldora "[Próximamente]" (ámbar) si aparece en Extras → gris. */
.nseo-page--article-new .nseo-soon-pill {
	background: var(--surface-sunken);
	color: var(--text-tertiary);
}

/* --- Rediseño layout: cards con borde fino + radio; Extras al sidebar --- */
/* Cada sección pasa a ser un rectángulo bordeado (mismo borde que el Resumen).
   El step-badge sale del gutter de -42px y se ubica dentro del padding. */
.nseo-page--article-new .nseo-section-card {
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-lg);
	background: #fff;
	padding: var(--space-6);
}
.nseo-page--article-new .nseo-section-head {
	margin-left: 0;
	align-items: stretch;   /* VIS.1: el cuadro del badge se estira al alto de la cabecera */
	gap: var(--space-4);
}

/* ============================================================
   Wizard de curación (curate.php) — porta el lenguaje visual del
   wizard de creación SOLO en su subconjunto que aplica (badge indigo,
   cards bordeadas, head stretch, eyebrow gris). NO reusa
   .nseo-page--article-new porque ese mueve Extras al sidebar y trae el
   acento coral; aquí Extras es inline y el acento es indigo. Se duplica
   el subconjunto a propósito (convención del proyecto: scope por pantalla).
   ============================================================ */
/* Modal "Confirmar curación": ensanche scopeado a 820px (las 7 recs + textos
   largos respiran). Scope COMPUESTO (.nseo-page--curation Y .nseo-modal en el
   MISMO overlay = curate.php:768) → NO toca el max-width:520px genérico de
   .nseo-modal__panel que usan los demás modales (article-new, brand-style,
   topic-proposals, config, post-analysis). Sigue responsive: el panel es
   width:100% dentro del overlay con padding, así que en viewports estrechos
   se adapta y el max-width:820px solo topa en pantallas anchas. */
.nseo-page--curation.nseo-modal .nseo-modal__panel { max-width: 820px; }
.nseo-page--curation .nseo-step-badge,
.nseo-page--curation .nseo-step-badge--quality {
	width: 48px;
	height: auto;
	align-self: stretch;
	border-radius: var(--radius-md);
	background: var(--brand-primary);
	color: #fff;
	font-size: 22px;
	font-weight: 700;
}
.nseo-page--curation .nseo-section-eyebrow {
	color: var(--text-secondary);
}
/* Badge "Próximamente" en gris (como en el wizard de creación), no ámbar. */
.nseo-page--curation .nseo-soon-pill {
	background: var(--surface-sunken);
	color: var(--text-tertiary);
}
.nseo-page--curation .nseo-section-card {
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-lg);
	background: #fff;
	padding: var(--space-6);
}
/* Borde de acento en los apartados de curación (mismo enfoque que la config).
   Solo el color; mismo grosor. Scopeado a .nseo-page--curation. */
.nseo-page--curation .nseo-section-card { border-color: var(--brand-primary); }
.nseo-page--curation .nseo-section-head {
	margin-left: 0;
	align-items: stretch;
	gap: var(--space-4);
}

/* Paso 1 · Contexto: pares etiqueta/valor estructurados (no <dl> indentado),
   repartidos en DOS columnas para aprovechar el ancho. 6 pares → 3 por columna
   (auto-flow por filas: lectura natural izq→der). 1 columna en estrecho. */
.nseo-page--curation .nseo-curation-context {
	margin: 0;
	display: grid;
	grid-template-columns: 1fr 1fr;
	column-gap: var(--space-8);
	row-gap: var(--space-3);
}
.nseo-page--curation .nseo-curation-context__row {
	display: flex;
	gap: var(--space-5);
	min-width: 0;
}
.nseo-page--curation .nseo-curation-context dt {
	flex: 0 0 120px;
	color: var(--text-primary);
	font-size: var(--text-sm-size);
	font-weight: 600;
}
.nseo-page--curation .nseo-curation-context dd {
	flex: 1;
	min-width: 0;
	margin: 0;
	color: var(--text-primary);
	font-size: var(--text-sm-size);
	word-wrap: break-word;
}
.nseo-page--curation .nseo-curation-context dd small {
	color: var(--text-tertiary);
}
@media (max-width: 900px) {
	.nseo-page--curation .nseo-curation-context { grid-template-columns: 1fr; }
}

/* Paso 2 · Recomendaciones: checkboxes legibles, cada uno en su fila bordeada. */
.nseo-page--curation .nseo-curation-recs {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
}
.nseo-page--curation .nseo-curation-recs__item label {
	display: flex;
	gap: var(--space-3);
	align-items: flex-start;
	padding: var(--space-3);
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-md);
	cursor: pointer;
	transition: border-color var(--motion-hover), background var(--motion-hover);
}
.nseo-page--curation .nseo-curation-recs__item label:hover {
	border-color: var(--brand-primary);
	background: var(--brand-primary-soft);
}
.nseo-page--curation .nseo-curation-recs__item input {
	margin-top: 3px;
	flex-shrink: 0;
}
.nseo-page--curation .nseo-curation-recs__item span {
	flex: 1;
	min-width: 0;
	font-size: var(--text-sm-size);
	line-height: 1.5;
	color: var(--text-primary);
}

/* Sidebar: la card de Extras (estática) va encima del Resumen; SOLO el Resumen
   es sticky, para que coste + botón Generar no desaparezcan al hacer scroll
   aunque Extras sea alta. */
.nseo-page--article-new .nseo-wizard-summary-sticky {
	position: static;
	display: flex;
	flex-direction: column;
	gap: var(--space-6);
}
.nseo-page--article-new .nseo-wizard-summary {
	position: sticky;
	top: 90px;
}

/* --- Coral: los 3 detalles de esta pantalla --- */
.nseo-page--article-new .nseo-obj-card.is-active {
	border-color: var(--nseo-coral);
	background: var(--nseo-coral-soft);
	box-shadow: 0 0 0 1px var(--nseo-coral);
}
.nseo-page--article-new .nseo-wizard-summary__total {
	color: var(--nseo-coral);
}
.nseo-page--article-new .nseo-btn--primary {
	background: var(--nseo-coral);
	border-color: var(--nseo-coral);
	color: var(--text-on-primary);
}
.nseo-page--article-new .nseo-btn--primary:hover:not(:disabled) {
	background: var(--nseo-coral-hover);
	border-color: var(--nseo-coral-hover);
}

/* Banner "Desde Próximos temas" (componente exclusivo de esta pantalla, queda
 * fuera del <form>, así que se recolorea sin scope): indigo → gris. */
.nseo-from-proposal-banner {
	background: var(--surface-sunken);
	border-color: var(--border-default);
}
.nseo-from-proposal-banner__eyebrow {
	color: var(--text-secondary);
}

/* R6: versiones anteriores plegables en el listado de Artículos. El estilo
   vigente (filas reales por versión + toggle JS) está más abajo, junto a
   .nseo-row-version. */
.nseo-row-versions-row > .nseo-table__cell { padding-top: 0; padding-bottom: 0; }

/* ======================================================================
 * Dashboard / cuadro de mandos (Paso 4 — fachada). Una ficha por sitio,
 * apiladas; cabecera de color por sitio (--nseo-site-color), 5 tarjetas-
 * métrica clicables y huecos de gráficas. Scopeado a `.nseo-dashboard`.
 * ====================================================================== */
.nseo-dashboard__controls {
	display: flex;
	align-items: flex-end;
	gap: var(--space-4);
	flex-wrap: wrap;
}
.nseo-dashboard__control {
	display: flex;
	flex-direction: column;
	gap: 4px;
}
.nseo-dashboard__control-label {
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	color: var(--text-secondary);
}
.nseo-dashboard__sites {
	display: grid;
	grid-template-columns: repeat( 2, minmax( 0, 1fr ) );
	gap: var(--space-5);
}
/* Responsive: a 1 columna en tablet/móvil (las fichas son legibles a ancho completo). */
@media ( max-width: 1024px ) {
	.nseo-dashboard__sites { grid-template-columns: 1fr; }
}
.nseo-dash-card {
	background: var(--surface-base);
	/* Marco de la ficha entera en el color de acento del sitio (heredado vía
	   --nseo-site-color del <article>). Refuerza la identidad del bloque. */
	border: 1px solid var(--nseo-site-color, var(--border-subtle));
	border-radius: var(--radius-lg);
	box-shadow: var(--shadow-sm);
	overflow: hidden;
}
.nseo-dash-card[hidden] { display: none; }
.nseo-dash-card__header {
	display: flex;
	align-items: center;
	gap: var(--space-3);
	padding: var(--space-4) var(--space-5);
	border-left: 4px solid var(--nseo-site-color, var(--brand-primary));
	background: linear-gradient( 90deg, color-mix( in srgb, var(--nseo-site-color, var(--brand-primary)) 10%, transparent ), transparent 60% );
}
.nseo-dash-card__avatar {
	flex: 0 0 36px;
	width: 36px;
	height: 36px;
	border-radius: var(--radius-full, 999px);
	background: var(--nseo-site-color, var(--brand-primary));
	color: #fff;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	font-weight: 700;
	font-size: 15px;
}
.nseo-dash-card__id { flex: 1; min-width: 0; }
.nseo-dash-card__name {
	margin: 0;
	font-size: var(--text-md-size, 16px);
	font-weight: 600;
	color: var(--text-primary);
}
.nseo-dash-card__domain {
	margin: 2px 0 0;
	font-size: var(--text-sm-size, 13px);
	color: var(--text-tertiary);
}
.nseo-dash-card__open { flex: 0 0 auto; }
.nseo-dash-card__body {
	padding: var(--space-5);
	display: flex;
	flex-direction: column;
	gap: var(--space-5);
	/* Contenedor para que el interior (tarjetas + gráficas) reaccione al ANCHO
	   de la ficha, no al del viewport — clave con las fichas en 2 columnas. */
	container-type: inline-size;
}
.nseo-dash-metrics {
	display: grid;
	grid-template-columns: repeat( auto-fit, minmax( 140px, 1fr ) );
	gap: var(--space-3);
}
.nseo-dash-metric {
	display: flex;
	flex-direction: column;
	gap: 4px;
	padding: var(--space-4);
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-md);
	background: var(--surface-sunken);
	text-decoration: none;
	transition: border-color 120ms ease, transform 120ms ease;
}
.nseo-dash-metric:hover {
	border-color: var(--nseo-site-color, var(--brand-primary));
	transform: translateY( -1px );
}
.nseo-dash-metric__value {
	font-size: 26px;
	font-weight: 700;
	line-height: 1;
	color: var(--text-primary);
}
.nseo-dash-metric__label {
	font-size: 12px;
	color: var(--text-secondary);
}
.nseo-dash-charts {
	display: grid;
	/* Por defecto apiladas (ficha estrecha → legible). Lado a lado solo cuando
	   la ficha tiene ancho de sobra (container query — ver __body). */
	grid-template-columns: 1fr;
	gap: var(--space-4);
}
@container ( min-width: 520px ) {
	.nseo-dash-charts { grid-template-columns: 2fr 1fr; }
}
.nseo-dash-chart {
	border: 1px dashed var(--border-default, var(--border-subtle));
	border-radius: var(--radius-md);
	padding: var(--space-4);
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
	min-height: 160px;
}
.nseo-dash-chart__title {
	font-size: 12px;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var(--text-secondary);
}
/* Contenedor con alto definido: Chart.js (maintainAspectRatio:false) dimensiona
   el canvas a esta caja. El canvas se posiciona absoluto para llenarla. */
.nseo-dash-chart__canvas-wrap {
	position: relative;
	flex: 1;
	min-height: 120px;
}
.nseo-dash-chart__canvas {
	position: absolute;
	inset: 0;
}
.nseo-dash-chart__empty {
	font-size: 12px;
	color: var(--text-tertiary);
}
.nseo-dash-chart--visibility .nseo-dash-chart__empty {
	flex: 1;
	display: flex;
	align-items: center;
	justify-content: center;
	text-align: center;
}

/* ---------------------------------------------------------------------------
   F4 · Selector de tipos de contenido a importar/analizar (CPTs).
   Compartido por la pantalla de posts (.nseo-type-select dentro del header) y
   la tarjeta del form de config (--card). Solo se pinta si el sitio tiene CPTs.
--------------------------------------------------------------------------- */
.nseo-type-select {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-2) var(--space-4);
	margin: var(--space-3) 0 0;
	padding: 0;
	border: 0;
}
.nseo-type-select__legend,
.nseo-type-select--card .nseo-type-select__legend {
	width: 100%;
	margin: 0 0 var(--space-2);
	padding: 0;
	font-size: 0.85rem;
	font-weight: 600;
	color: var(--text-secondary);
}
.nseo-type-select__option {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
	padding: var(--space-1) var(--space-3);
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-pill);
	background: var(--surface-base);
	font-size: 0.9rem;
	cursor: pointer;
}
.nseo-type-select__option:hover {
	background: var(--surface-hover);
}
.nseo-type-select__option.is-disabled {
	color: var(--text-secondary);
	background: var(--surface-muted);
	cursor: not-allowed;
	opacity: 0.7;
}
.nseo-type-select__note {
	font-size: 0.75rem;
	color: var(--text-secondary);
}

/* En el form de config: tarjeta apilada (cada chip en su contexto vertical). */
.nseo-type-select--card {
	flex-direction: column;
	align-items: stretch;
	gap: var(--space-2);
	margin-top: var(--space-4);
	padding: var(--space-4);
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-lg);
	background: var(--surface-raised);
}
.nseo-type-select--card .nseo-type-select__option {
	justify-content: flex-start;
}

/* ---------------------------------------------------------------------------
   Perfil editorial — form editable (1b). Ancho completo del área de contenido
   + rejilla de 2 columnas responsive con textareas a ancho de celda y altura
   por tipo. El <form> NO lleva la clase `.nseo-form` (cuyo max-width:640px lo
   encajonaba); este override es defensa adicional por si se reañadiera.
--------------------------------------------------------------------------- */
.nseo-page--brand-style .nseo-brand-style-form {
	/* `.nseo-page--brand-style` es un grid de 2 columnas (layout heredado de la
	   pantalla read-only). El form es hijo directo → sin esto cae en UNA columna
	   (~409px) y `width:100%` era 100% de esa columna. Span a las 2 columnas →
	   ocupa el ancho completo del área de contenido; la rejilla interna
	   `.nseo-bs-grid` hace entonces sus 2 columnas a ancho real. */
	grid-column: 1 / -1;
	max-width: none;
	width: 100%;
}
.nseo-page--brand-style .nseo-bs-grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--space-5);
	margin-bottom: var(--space-6);
}
.nseo-page--brand-style .nseo-bs-field {
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
	min-width: 0; /* permite que el textarea encoja dentro de la celda en vez de desbordar. */
	padding: var(--space-4);
	background: var(--surface-base);
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-lg);
}
.nseo-page--brand-style .nseo-bs-field--wide {
	grid-column: 1 / -1;
}
.nseo-page--brand-style .nseo-bs-field__label {
	font-size: 13px;
	font-weight: 600;
	color: var(--text-secondary);
}
.nseo-page--brand-style .nseo-bs-field__hint {
	margin: 0;
	font-size: 12px;
	color: var(--text-secondary);
}
.nseo-page--brand-style .nseo-bs-field textarea {
	width: 100%;
	box-sizing: border-box;
	resize: vertical;
	font-family: inherit;
	font-size: 14px;
	line-height: 1.5;
	padding: 10px 12px;
	color: var(--text-primary);
	background: #fff;
	border: 1px solid var(--border-default);
	border-radius: var(--radius-md);
	outline: none;
	transition: border-color 150ms ease, box-shadow 150ms ease;
}
.nseo-page--brand-style .nseo-bs-field textarea:hover {
	border-color: var(--border-strong, #a1a1aa);
}
.nseo-page--brand-style .nseo-bs-field textarea:focus {
	border-color: var(--brand-primary);
	box-shadow: 0 0 0 3px rgba( 99, 102, 241, 0.20 );
}
.nseo-page--brand-style .nseo-bs-field--short textarea  { min-height: 68px; }
.nseo-page--brand-style .nseo-bs-field--medium textarea { min-height: 120px; }
.nseo-page--brand-style .nseo-bs-field--tall textarea   { min-height: 190px; }

/* 1c: badge "editado" + "restaurar al de la IA" en campos bloqueados (sticky). */
.nseo-page--brand-style .nseo-bs-field__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-2);
}
.nseo-page--brand-style .nseo-bs-field__badge {
	flex-shrink: 0;
	font-size: 11px;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.02em;
	padding: 2px 8px;
	border-radius: var(--radius-pill);
	color: var(--brand-primary);
	background: rgba( 99, 102, 241, 0.12 );
}
.nseo-page--brand-style .nseo-bs-field.is-edited {
	border-color: var(--brand-primary);
}
.nseo-page--brand-style .nseo-bs-field__restore {
	align-self: flex-start;
}

@media ( max-width: 720px ) {
	.nseo-page--brand-style .nseo-bs-grid { grid-template-columns: 1fr; }
	.nseo-page--brand-style .nseo-bs-field--wide { grid-column: auto; }
}

/* ============================================================
   M3 — Matriz de enlaces internos (panel read-only en config)
   Scopeado a .nseo-matrix-summary (norma CSS scopeada por pantalla).
   ============================================================ */
.nseo-internal-links-page {
	margin-top: var(--space-6);
}
.nseo-matrix-summary {
	margin-top: var(--space-5);
	padding: var(--space-4);
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-md);
	background: var(--surface-raised);
}
.nseo-matrix-summary__title {
	margin: 0 0 var(--space-2);
	font-size: var(--text-sm-size);
	font-weight: 600;
	color: var(--text-primary);
}
.nseo-matrix-summary__meta {
	margin: 0 0 var(--space-1);
	font-size: var(--text-xs-size);
	color: var(--text-tertiary);
}
.nseo-matrix-summary__empty {
	margin: 0;
	font-size: var(--text-sm-size);
	color: var(--text-secondary);
}
.nseo-matrix-summary__notice {
	margin: var(--space-3) 0 0;
	padding: var(--space-2) var(--space-3);
	font-size: var(--text-xs-size);
	color: #92660a;
	background: var(--warning-soft);
	border: 1px solid var(--warning);
	border-radius: var(--radius-sm);
}
.nseo-matrix-summary__without {
	margin: var(--space-2) 0 0;
	font-size: var(--text-xs-size);
	color: var(--text-secondary);
}
.nseo-matrix-summary__without > summary {
	cursor: pointer;
	color: var(--text-tertiary);
}
.nseo-matrix-summary__without ul {
	margin: var(--space-2) 0 0;
	padding-left: var(--space-5);
}

/* Variantes de pill por origen (solo se usan aquí → scopeadas). */
.nseo-matrix-summary .nseo-pill--curated    { background: rgba(99, 102, 241, 0.12); color: #4f46e5; }
.nseo-matrix-summary .nseo-pill--commercial { background: rgba(21, 128, 61, 0.12);  color: #15803d; }
.nseo-matrix-summary .nseo-pill--other      { background: var(--surface-sunken);    color: var(--text-secondary); }

/* Tabla resumen: head + cada fila <details> comparten el mismo grid. */
.nseo-matrix-summary__rows {
	margin-top: var(--space-3);
}
.nseo-matrix-summary__head,
.nseo-matrix-summary__row-summary {
	display: grid;
	grid-template-columns: minmax(0, 2fr) 84px minmax(0, 3fr) 52px 64px;
	gap: var(--space-3);
	align-items: center;
}
.nseo-matrix-summary__head {
	padding: 0 var(--space-2) var(--space-2);
	font-size: var(--text-xs-size);
	font-weight: 600;
	color: var(--text-tertiary);
	text-transform: uppercase;
	letter-spacing: 0.04em;
	border-bottom: 1px solid var(--border-default);
}
.nseo-matrix-summary__head span:nth-child(4),
.nseo-matrix-summary__head span:nth-child(5),
.nseo-matrix-summary__score,
.nseo-matrix-summary__count {
	text-align: right;
	font-variant-numeric: tabular-nums;
}
.nseo-matrix-summary__row {
	border-bottom: 1px solid var(--border-subtle);
}
.nseo-matrix-summary__row-summary {
	list-style: none;
	cursor: pointer;
	padding: var(--space-2);
	font-size: var(--text-sm-size);
}
.nseo-matrix-summary__row-summary::-webkit-details-marker { display: none; }
.nseo-matrix-summary__row-summary:hover { background: var(--surface-hover); }
.nseo-matrix-summary__anchor {
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
	min-width: 0;
	color: var(--text-primary);
}
.nseo-matrix-summary__best {
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
	min-width: 0;
	font-size: var(--text-xs-size);
	color: var(--nseo-coral);
}
.nseo-matrix-summary__score { color: var(--text-secondary); }
.nseo-matrix-summary__count { color: var(--text-secondary); }

/* Detalle expandido: top-5 destinos. */
.nseo-matrix-summary__dests {
	margin: 0;
	padding: 0 var(--space-2) var(--space-3) var(--space-4);
	list-style: none;
	font-size: var(--text-xs-size);
}
.nseo-matrix-summary__dests li {
	display: grid;
	grid-template-columns: 52px minmax(0, 1fr);
	gap: var(--space-3);
	align-items: center;
	padding: var(--space-1) 0;
}
.nseo-matrix-summary__dests li > a {
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
	min-width: 0;
	color: var(--text-secondary);
}

@media ( max-width: 720px ) {
	.nseo-matrix-summary__head { display: none; }
	.nseo-matrix-summary__row-summary {
		grid-template-columns: minmax(0, 1fr) auto;
		row-gap: var(--space-1);
	}
	.nseo-matrix-summary__best { grid-column: 1 / -1; }
	.nseo-matrix-summary__score,
	.nseo-matrix-summary__count { text-align: left; }
}

/* ============================================================================
 * Calendario global de publicaciones (filas = horas, columnas = días del mes).
 * Vista introducida junto al item de sidebar "Calendario".
 * ==========================================================================*/

/* Barra de filtros + navegación bajo el título, pegajosa sobre el calendario.
 * Se ancla justo debajo de la topbar (sticky con z-index 50). */
/* Cabecera (título) + toolbar del calendario se pegan JUNTAS bajo la topbar al
 * hacer scroll, como un solo bloque. Así el título no se corta y los filtros
 * quedan siempre accesibles. */
.nseo-calendar__stickyhead {
	flex: 0 0 auto;
	position: sticky;
	top: calc(var(--nseo-admin-bar-h) + 56px);
	z-index: 21;
	background: var(--surface-base);
	padding-top: var(--space-4);
	margin-bottom: var(--space-2);
	border-bottom: 1px solid var(--border-subtle);
}

/* Título/subtítulo a la izquierda y filtros/navegación a la derecha, en la
 * misma fila y alineados por su base (con el subtítulo). */
.nseo-calendar__header {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: var(--space-4);
	flex-wrap: wrap;
	margin-bottom: var(--space-3);
}

.nseo-calendar__toolbar {
	display: flex;
	align-items: center;
	gap: var(--space-3);
	flex-wrap: wrap;
}

/* Filtro por sitio: se presenta como filtro (label + select compacto), no como
 * el site-switcher global del topbar, para no confundirlos. */
.nseo-calendar__filter {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
	margin: 0;
}

.nseo-calendar__filter-label {
	font-size: var(--text-xs-size);
	line-height: var(--text-xs-lh);
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var(--text-tertiary);
}

.nseo-calendar__filter-select {
	min-width: 160px;
	height: 34px;
	padding-top: 0;
	padding-bottom: 0;
}

.nseo-calendar__nav {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
}

.nseo-calendar__navbtn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 34px;
	height: 34px;
	border: 1px solid var(--border-default);
	border-radius: var(--radius-md);
	background: var(--surface-base);
	color: var(--text-primary);
	text-decoration: none;
	font-size: var(--text-lg-size);
	line-height: 1;
	transition: background 0.12s ease, border-color 0.12s ease;
}

.nseo-calendar__navbtn:hover {
	background: var(--surface-hover);
	border-color: var(--border-strong);
}

.nseo-calendar__month {
	min-width: 150px;
	text-align: center;
	font-size: var(--text-md-size);
	font-weight: 600;
	color: var(--text-primary);
	text-transform: capitalize;
}

.nseo-calendar__today-btn {
	white-space: nowrap;
}

/* Layout de la página de calendario: columna a la altura del viewport. El
 * bloque cabecera+filtros arriba, la rejilla en el medio (con su propio scroll)
 * y la bandeja de aprobados SIEMPRE abajo, sin subir con el scroll. */
.nseo-page--calendar {
	display: flex;
	flex-direction: column;
	/* viewport − admin bar − topbar (56) − padding vertical del content (2×32) */
	height: calc(100vh - var(--nseo-admin-bar-h) - 56px - (2 * var(--space-8)));
}

/* --- Rejilla --- */
.nseo-calendar__scroll {
	overflow: auto;
	flex: 1 1 auto;
	min-height: 0;
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-lg);
	background: var(--surface-base);
}

.nseo-calendar__grid {
	border-collapse: separate;
	border-spacing: 0;
	table-layout: fixed;
	width: 100%;
	min-width: 720px;
}

/* Cabecera pegajosa (horas y días quedan visibles al hacer scroll). */
.nseo-calendar__grid thead th {
	position: sticky;
	top: 0;
	z-index: 2;
	background: var(--surface-raised);
}

.nseo-calendar__corner {
	position: sticky;
	left: 0;
	z-index: 3;
	width: 64px;
	min-width: 64px;
	background: var(--surface-raised);
	border-right: 1px solid var(--border-subtle);
	border-bottom: 1px solid var(--border-subtle);
}

.nseo-cal-vh {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip: rect(0 0 0 0);
	white-space: nowrap;
}

.nseo-calendar__daycol {
	width: auto;
	padding: var(--space-2) var(--space-3);
	text-align: left;
	border-right: 1px solid var(--border-subtle);
	border-bottom: 1px solid var(--border-subtle);
}

.nseo-calendar__dow {
	display: block;
	font-size: var(--text-xs-size);
	line-height: var(--text-xs-lh);
	font-weight: 500;
	color: var(--text-tertiary);
	text-transform: uppercase;
	letter-spacing: 0.04em;
}

.nseo-calendar__daynum {
	display: inline-block;
	font-size: var(--text-lg-size);
	line-height: var(--text-lg-lh);
	font-weight: 700;
	color: var(--text-primary);
}

.nseo-calendar__colmonth {
	display: inline-block;
	margin-left: var(--space-1);
	font-size: var(--text-xs-size);
	color: var(--text-tertiary);
	text-transform: uppercase;
}

/* Barritas de color bajo el número del día: una por sitio con artículos ese
 * día. Localizan de un vistazo qué días tienen publicaciones y de quién. */
.nseo-calendar__daybars {
	display: flex;
	gap: 2px;
	margin-top: 4px;
	flex-wrap: wrap;
}

.nseo-calendar__daybar {
	display: block;
	height: 3px;
	min-width: 14px;
	flex: 1 1 auto;
	max-width: 28px;
	border-radius: 2px;
}

.nseo-calendar__hour {
	position: sticky;
	left: 0;
	z-index: 1;
	width: 64px;
	min-width: 64px;
	padding: var(--space-2);
	text-align: right;
	vertical-align: top;
	background: var(--surface-raised);
	border-right: 1px solid var(--border-subtle);
	border-bottom: 1px solid var(--border-subtle);
	font-size: var(--text-xs-size);
	line-height: var(--text-xs-lh);
	font-variant-numeric: tabular-nums;
	color: var(--text-tertiary);
	font-weight: 500;
}

.nseo-calendar__cell {
	width: auto;
	height: 40px;
	vertical-align: top;
	padding: var(--space-1);
	border-right: 1px solid var(--border-subtle);
	border-bottom: 1px solid var(--border-subtle);
}

.nseo-calendar__cell.is-empty {
	background: repeating-linear-gradient(
		45deg,
		transparent,
		transparent 9px,
		rgba(0, 0, 0, 0.012) 9px,
		rgba(0, 0, 0, 0.012) 10px
	);
}

.nseo-calendar__cell > .nseo-pub + .nseo-pub {
	margin-top: var(--space-1);
}

/* --- Tarjeta de publicación --- */
.nseo-pub {
	--nseo-pub-color: var(--brand-primary);
	display: block;
	overflow: hidden;
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-md);
	background: var(--surface-base);
	text-decoration: none;
	color: inherit;
	transition: box-shadow 0.12s ease, transform 0.12s ease;
}

.nseo-pub:hover {
	box-shadow: 0 2px 8px rgba(0, 0, 0, 0.10);
	transform: translateY(-1px);
}

.nseo-pub:focus-visible {
	outline: 2px solid var(--nseo-pub-color);
	outline-offset: 2px;
}

.nseo-pub__bar {
	display: flex;
	align-items: center;
	gap: 6px;
	padding: 3px var(--space-2);
	background: var(--nseo-pub-color);
	color: #fff;
	font-size: var(--text-xs-size);
	line-height: var(--text-xs-lh);
	font-weight: 600;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}
/* 0.12.27: hora y nombre del sitio dentro de la barra de la publicación
   (vista mensual). La hora se queda fija, el nombre se expande y trunca. */
.nseo-pub__hour { flex: 0 0 auto; font-variant-numeric: tabular-nums; }
.nseo-pub__site { flex: 1 1 auto; min-width: 0; font-size: 10px; font-weight: 500; opacity: 0.85; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.nseo-pub__body {
	display: block;
	padding: var(--space-2);
}

.nseo-pub__title {
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	font-size: var(--text-sm-size);
	line-height: var(--text-sm-lh);
	font-weight: 600;
	color: var(--text-primary);
}

.nseo-pub__author {
	display: block;
	margin-top: var(--space-1);
	font-size: var(--text-xs-size);
	line-height: var(--text-xs-lh);
	color: var(--text-secondary);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.nseo-pub__when {
	display: block;
	margin-top: 2px;
	font-size: var(--text-xs-size);
	line-height: var(--text-xs-lh);
	color: var(--text-tertiary);
	font-variant-numeric: tabular-nums;
}

@media (prefers-reduced-motion: reduce) {
	.nseo-pub,
	.nseo-calendar__navbtn {
		transition: none;
	}
	.nseo-pub:hover {
		transform: none;
	}
}

/* Post programado (aún no publicado): borde punteado + badge en la barra. */
.nseo-pub.is-scheduled {
	border-style: dashed;
	opacity: 0.92;
}
.nseo-pub__badge {
	display: inline-block;
	margin-left: var(--space-1);
	padding: 0 4px;
	border-radius: var(--radius-sm);
	background: rgba(255, 255, 255, 0.28);
	font-size: 9px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.03em;
	vertical-align: middle;
}

/* Resaltado de la columna del día de hoy. */
.nseo-calendar__daycol.is-today {
	background: var(--brand-primary-soft);
}
.nseo-calendar__daycol.is-today .nseo-calendar__daynum {
	color: var(--brand-primary);
}
.nseo-calendar__cell.is-today-col {
	background: color-mix(in srgb, var(--brand-primary) 4%, transparent);
}
.nseo-calendar__cell.is-today-col.is-empty {
	background:
		color-mix(in srgb, var(--brand-primary) 4%, transparent),
		repeating-linear-gradient(
			45deg,
			transparent,
			transparent 9px,
			rgba(0, 0, 0, 0.012) 9px,
			rgba(0, 0, 0, 0.012) 10px
		);
}


/* ============================================================================
 * Blindaje de tipografía frente al TEMA de WordPress.
 * El plugin renderiza en el frontend del propio WP, así que hereda el CSS del
 * tema activo. Temas como Twenty Twenty-Four cargan una serif (Cardo) para los
 * títulos vía theme.json a nivel global, lo que pisaba Inter en nuestras
 * pantallas (títulos saliendo en serifa). Forzamos Inter en TODO lo que cuelga
 * de body.nseo-frontend con !important — acotado a nuestras pantallas, no toca
 * el resto del sitio ni el contenido de artículos (que usa --article-font).
 * ==========================================================================*/
body.nseo-frontend,
body.nseo-frontend h1,
body.nseo-frontend h2,
body.nseo-frontend h3,
body.nseo-frontend h4,
body.nseo-frontend h5,
body.nseo-frontend h6,
body.nseo-frontend p,
body.nseo-frontend a,
body.nseo-frontend span,
body.nseo-frontend div,
body.nseo-frontend button,
body.nseo-frontend input,
body.nseo-frontend select,
body.nseo-frontend textarea,
body.nseo-frontend label,
body.nseo-frontend li,
body.nseo-frontend td,
body.nseo-frontend th {
	font-family: var(--font-sans) !important;
}

/* Excepción: el cuerpo del artículo generado conserva su fuente propia
 * (--article-font), que es una decisión de producto para la vista de lectura. */
body.nseo-frontend .nseo-article-content,
body.nseo-frontend .nseo-article-content h1,
body.nseo-frontend .nseo-article-content h2,
body.nseo-frontend .nseo-article-content h3,
body.nseo-frontend .nseo-article-content h4,
body.nseo-frontend .nseo-article-content p,
body.nseo-frontend .nseo-article-content li {
	font-family: var(--article-font) !important;
}

/* Celda "Fecha de publicación" en el listado de artículos: cuando el post está
 * programado (fecha futura), fondo en tono pastel del color del sitio para
 * distinguirlo de los ya publicados. color-mix diluye el color a ~15%. */
.nseo-pubdate-cell.is-scheduled {
	--nseo-site-color: var(--brand-primary);
	background: color-mix(in srgb, var(--nseo-site-color) 15%, transparent);
	font-weight: 600;
}

/* Drag & drop de reprogramación en el calendario. */
.nseo-pub[data-nseo-drag] {
	cursor: grab;
}
.nseo-pub.is-dragging {
	opacity: 0.5;
	cursor: grabbing;
}
.nseo-pub.is-saving {
	opacity: 0.6;
	pointer-events: none;
}
.nseo-calendar__cell.is-drop-target {
	background: color-mix(in srgb, var(--brand-primary) 12%, transparent);
	outline: 2px dashed var(--brand-primary);
	outline-offset: -2px;
}

/* Conmutador de vista Semana/Mes. */
.nseo-calendar__viewswitch {
	display: inline-flex;
	border: 1px solid var(--border-default);
	border-radius: var(--radius-md);
	overflow: hidden;
}
.nseo-calendar__viewbtn {
	padding: 6px var(--space-3);
	font-size: var(--text-sm-size);
	line-height: var(--text-sm-lh);
	font-weight: 600;
	color: var(--text-secondary);
	background: var(--surface-base);
	text-decoration: none;
}
.nseo-calendar__viewbtn + .nseo-calendar__viewbtn {
	border-left: 1px solid var(--border-default);
}
.nseo-calendar__viewbtn:hover {
	background: var(--surface-sunken);
}
.nseo-calendar__viewbtn.is-active {
	background: var(--brand-primary);
	color: #fff;
}

/* ============================================================================
 * Vista MENSUAL del calendario: 6 semanas × 7 días, cada celda es un día
 * completo (no una franja horaria). Arrastrar conserva la hora original de
 * la tarjeta — ver `resolveHour()` en calendar.js.
 * ==========================================================================*/
.nseo-monthgrid {
	overflow-x: auto;
}
.nseo-monthgrid__table {
	width: 100%;
	border-collapse: collapse;
	table-layout: fixed;
}
.nseo-monthgrid__dowhead {
	padding: var(--space-2);
	text-align: left;
	font-size: var(--text-xs-size);
	line-height: var(--text-xs-lh);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var(--text-tertiary);
	border-bottom: 1px solid var(--border-default);
}
.nseo-monthgrid__cell {
	width: 14.2857%;
	height: 120px;
	vertical-align: top;
	padding: var(--space-1);
	border-right: 1px solid var(--border-subtle);
	border-bottom: 1px solid var(--border-subtle);
}
.nseo-monthgrid__cell.is-empty {
	background: repeating-linear-gradient(
		45deg,
		transparent,
		transparent 9px,
		rgba(0, 0, 0, 0.012) 9px,
		rgba(0, 0, 0, 0.012) 10px
	);
}
.nseo-monthgrid__cell.is-outside-month {
	background: var(--surface-sunken);
	opacity: 0.55;
}
.nseo-monthgrid__cell.is-today {
	background: var(--brand-primary-soft);
}
.nseo-monthgrid__cell.is-today .nseo-monthgrid__daynum {
	color: var(--brand-primary);
	font-weight: 700;
}
.nseo-monthgrid__cell.is-drop-target {
	background: color-mix(in srgb, var(--brand-primary) 12%, transparent);
	outline: 2px dashed var(--brand-primary);
	outline-offset: -2px;
}
.nseo-monthgrid__cellhead {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-1);
	margin-bottom: var(--space-1);
}
.nseo-monthgrid__daynum {
	font-size: var(--text-sm-size);
	line-height: var(--text-sm-lh);
	font-weight: 600;
	color: var(--text-secondary);
	font-variant-numeric: tabular-nums;
}
.nseo-monthgrid__items {
	display: flex;
	flex-direction: column;
	gap: 3px;
	min-height: 24px; /* zona de drop utilizable incluso con el día vacío. */
}
.nseo-monthgrid__items > .nseo-pub + .nseo-pub {
	margin-top: 0; /* el gap del flex ya separa; evita doble espaciado. */
}

/* Tarjeta compacta (vista mensual): una línea de hora + una de título, sin
 * autor ni fecha completa — no cabe en una celda de día. */
.nseo-pub--compact .nseo-pub__bar {
	padding: 2px 6px;
	font-size: 10px;
	font-variant-numeric: tabular-nums;
}
.nseo-pub--compact .nseo-pub__body {
	padding: 3px 6px;
}
.nseo-pub--compact .nseo-pub__title {
	-webkit-line-clamp: 1;
	font-size: var(--text-xs-size);
	line-height: var(--text-xs-lh);
	font-weight: 500;
}

/* ============================================================================
 * Bandeja horizontal de aprobados pendientes de publicar (bajo el calendario).
 * Scroll lateral; tarjetas con el mismo look que las del calendario, arrastrables.
 * ==========================================================================*/
.nseo-tray {
	flex: 0 0 auto;
	margin-top: var(--space-3);
	border-top: 1px solid var(--border-default);
	padding-top: var(--space-3);
	background: var(--surface-base);
}

.nseo-tray__head {
	display: flex;
	align-items: center;
	gap: var(--space-2);
	margin-bottom: var(--space-2);
}

.nseo-tray__title {
	font-size: var(--text-sm-size);
	line-height: var(--text-sm-lh);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var(--text-secondary);
	margin: 0;
}

.nseo-tray__count {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 20px;
	height: 20px;
	padding: 0 6px;
	border-radius: 10px;
	background: var(--surface-sunken);
	color: var(--text-secondary);
	font-size: var(--text-xs-size);
	font-weight: 700;
}

.nseo-tray__empty {
	font-size: var(--text-sm-size);
	color: var(--text-tertiary);
	margin: var(--space-2) 0 var(--space-4);
}

.nseo-tray__scroll {
	display: flex;
	gap: var(--space-3);
	overflow-x: auto;
	padding-bottom: var(--space-3);
	scroll-snap-type: x proximity;
}

.nseo-tray__card {
	flex: 0 0 240px;
	max-width: 240px;
	scroll-snap-align: start;
	cursor: grab;
}

.nseo-tray__card.is-dragging {
	opacity: 0.5;
	cursor: grabbing;
}

/* Soltar aquí una tarjeta del calendario -> despublica/desprograma. */
.nseo-tray.is-drop-target {
	outline: 2px dashed var(--brand-primary);
	outline-offset: -2px;
	background: color-mix(in srgb, var(--brand-primary) 6%, transparent);
}

/* Campo de semilla (tema/keyword) para enfocar la generación de propuestas. */
.nseo-topic-seed {
	min-width: 280px;
	max-width: 380px;
}
.nseo-page-header__actions--stack .nseo-topic-seed {
	margin-bottom: 8px;
}
.nseo-topic-seed-row {
	display: flex;
	gap: 12px;
	align-items: center;
	flex-wrap: wrap;
}

/* Estado C: toolbar en UNA fila — filtros (izq) + campo tema + botón (der),
 * todos alineados por su base. */
.nseo-topic-proposals-toolbar {
	display: flex;
	align-items: flex-end;
	gap: 16px;
	flex-wrap: wrap;
}
.nseo-topic-proposals-toolbar__filters {
	display: flex;
	align-items: flex-end;
	gap: 16px;
	flex-wrap: wrap;
	margin: 0;
}
.nseo-topic-proposals-toolbar__seed {
	margin-left: auto;
}
.nseo-topic-proposals-toolbar__seed .nseo-topic-seed {
	min-width: 240px;
}
.nseo-topic-proposals-toolbar__generate {
	white-space: nowrap;
}
.nseo-topic-count {
	width: 72px;
	text-align: center;
}
@media (max-width: 900px) {
	.nseo-topic-proposals-toolbar__seed {
		margin-left: 0;
	}
}

/* Versiones anteriores como filas reales de la tabla, plegables.
 * El toggle (fila-resumen) muestra/oculta las filas de versión de su grupo
 * añadiendo la clase is-open (lo gestiona article-versions.js). */
.nseo-row-versions__summary-cell {
	background: var(--surface-sunken);
}
.nseo-row-versions__summary {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	cursor: pointer;
	font-size: var(--text-sm-size);
	font-weight: 600;
	color: var(--text-secondary);
	user-select: none;
	background: none;
	border: 0;
	padding: 0;
}
.nseo-row-versions__summary:hover { color: var(--text-primary); }
.nseo-row-versions__caret {
	display: inline-block;
	transition: transform 0.15s ease;
	font-size: 10px;
}
.nseo-row-versions-row.is-open .nseo-row-versions__caret {
	transform: rotate(90deg);
}
/* Filas de versión: ocultas por defecto; visibles cuando el grupo está abierto. */
.nseo-row-version { display: none; }
.nseo-row-version.is-open { display: table-row; }
/* Guía visual de anidamiento en la primera celda. */
.nseo-row-version > .nseo-table__cell:first-child {
	box-shadow: inset 3px 0 0 var(--border-default);
}

/* Publicación programada — editor del patrón por defecto (días × horarios). */
.nseo-publish-schedule__intro {
	margin: 0 0 var(--space-6) 0;
	color: var(--text-secondary);
}
.nseo-publish-schedule__toolbar {
	display: flex;
	justify-content: flex-end;
	margin-bottom: var(--space-4);
}
.nseo-schedule-grid {
	display: flex;
	flex-direction: column;
	gap: 4px;
}
.nseo-schedule-grid__head,
.nseo-schedule-grid__row {
	display: grid;
	grid-template-columns: 140px repeat(3, 1fr);
	gap: 12px;
	align-items: center;
}
.nseo-schedule-grid__head {
	padding: 0 8px 8px 8px;
	font-size: var(--text-sm-size);
	font-weight: 600;
	color: var(--text-secondary);
	text-transform: uppercase;
	letter-spacing: 0.03em;
}
.nseo-schedule-grid__row {
	padding: 8px;
	border-radius: var(--radius-md);
	transition: background 0.12s ease;
}
.nseo-schedule-grid__row.is-active {
	background: var(--surface-sunken);
}
.nseo-schedule-grid__day {
	font-weight: 600;
	color: var(--text-primary);
}
.nseo-schedule-grid__select {
	width: 100%;
}
.nseo-schedule-grid__slot {
	display: flex;
	align-items: center;
	gap: 4px;
}
.nseo-schedule-grid__select--hour,
.nseo-schedule-grid__select--minute {
	width: auto;
	flex: 1 1 0;
	min-width: 0;
}
.nseo-schedule-grid__colon {
	color: var(--text-secondary);
	font-weight: 600;
}
@media (max-width: 720px) {
	.nseo-schedule-grid__head { display: none; }
	.nseo-schedule-grid__row {
		grid-template-columns: 1fr;
		gap: 8px;
		border: 1px solid var(--border-subtle);
		margin-bottom: 8px;
	}
}

/* Switcher de vista (tarjetas / tabla) en Próximos temas. Integrado como un
 * grupo más de la fila de filtros. */
.nseo-view-switcher {
	display: inline-flex;
	gap: 2px;
	padding: 3px;
	background: var(--surface-sunken);
	border-radius: var(--radius-md);
}
.nseo-view-switcher__opt {
	padding: 6px 16px;
	border-radius: calc(var(--radius-md) - 2px);
	font-size: var(--text-sm-size);
	font-weight: 600;
	color: var(--text-secondary);
	text-decoration: none;
	transition: background 0.12s ease, color 0.12s ease;
}
.nseo-view-switcher__opt:hover { color: var(--text-primary); }
.nseo-view-switcher__opt.is-active {
	background: var(--surface-raised);
	color: var(--text-primary);
	box-shadow: var(--shadow-sm);
}

/* Vista de tabla de propuestas. */
.nseo-topic-proposals-table-wrap { padding: 0; overflow: hidden; }
.nseo-topic-proposals-table { width: 100%; border-collapse: collapse; }
.nseo-topic-proposals-table__check-col {
	width: 44px;
	text-align: center;
}
.nseo-topic-proposals-table__title { font-weight: 600; color: var(--text-primary); }
.nseo-topic-proposals-table__keywords .nseo-chip {
	display: inline-block;
	margin: 2px 4px 2px 0;
}
.nseo-topic-proposals-table__empty { color: var(--text-secondary); }

/* Modal de generar y programar en lote. */
.nseo-batch-fields {
	display: flex;
	flex-direction: column;
	gap: var(--space-4);
	margin: var(--space-4) 0;
}
.nseo-batch-fields .nseo-edit-field {
	display: flex;
	flex-direction: column;
	gap: 4px;
}
.nseo-batch-fields .nseo-input {
	width: 100%;
	box-sizing: border-box;
}
.nseo-batch-note {
	color: var(--text-secondary);
	font-size: var(--text-sm-size);
}
.nseo-batch-error {
	color: var(--danger, #dc2626);
	font-size: var(--text-sm-size);
	margin-top: var(--space-2);
}
.nseo-topic-proposals-toolbar__batch:disabled {
	opacity: 0.5;
	cursor: not-allowed;
}

/* ============================================================================
 * Facilities (KW-6): panel de herramientas de mantenimiento/corrección SEO.
 * ==========================================================================*/
.nseo-facilities-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
	gap: var(--space-4);
}
.nseo-facility-card {
	display: block;
	padding: var(--space-5);
	border: 1px solid var(--border-default);
	border-radius: var(--radius-lg);
	background: var(--surface-base);
	text-decoration: none;
	transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.nseo-facility-card:hover {
	border-color: var(--brand-primary);
	box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}
.nseo-facility-card.is-disabled {
	opacity: 0.55;
	cursor: default;
	pointer-events: none;
}
.nseo-facility-card__title {
	margin: 0 0 var(--space-2);
	font-size: var(--text-md-size);
	line-height: var(--text-md-lh);
	font-weight: 600;
	color: var(--text-primary);
}
.nseo-facility-card__desc {
	margin: 0;
	font-size: var(--text-sm-size);
	line-height: var(--text-sm-lh);
	color: var(--text-secondary);
}
.nseo-facility-card .nseo-badge {
	display: inline-block;
	margin-top: var(--space-3);
}

.nseo-facility-tool {
	max-width: none;
}
.nseo-facility-tool-toolbar {
	display: flex;
	align-items: flex-end;
	justify-content: flex-start;
	gap: var(--space-3);
	flex-wrap: wrap;
	margin-bottom: var(--space-5);
}
.nseo-facility-tool-toolbar__group {
	display: flex;
	flex-direction: column;
	gap: var(--space-1);
	min-width: 260px;
}
.nseo-facility-tool-toolbar__group--button {
	min-width: 0;
}
.nseo-facility-tool-toolbar__analyze {
	white-space: nowrap;
	height: 47px;
	box-sizing: border-box;
}
.nseo-facility-tool__status {
	margin-bottom: var(--space-4);
	color: var(--text-secondary);
	font-size: var(--text-sm-size);
}
.nseo-facility-tool__status.is-error {
	color: var(--danger);
}
.nseo-facility-tool__summary {
	margin-bottom: var(--space-3);
	font-weight: 600;
	color: var(--text-primary);
}
.nseo-facility-tool__results .nseo-table-scroll {
	margin-bottom: var(--space-4);
}
.nseo-facility-tool__cell {
	max-width: 260px;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}
.nseo-facility-tool__cell a {
	color: var(--brand-primary);
	text-decoration: none;
}
.nseo-facility-tool__cell a:hover {
	text-decoration: underline;
}
.nseo-facility-tool__table {
	table-layout: fixed;
}
.nseo-facility-tool__table th {
	position: relative;
	cursor: grab;
	user-select: none;
}
.nseo-facility-tool__table th:active {
	cursor: grabbing;
}
.nseo-facility-tool__table th.is-drag-over {
	background: var(--brand-primary-soft);
	box-shadow: inset 2px 0 0 var(--brand-primary);
}
.nseo-facility-tool__resize-handle {
	position: absolute;
	top: 0;
	right: 0;
	width: 8px;
	height: 100%;
	cursor: col-resize;
	z-index: 2;
}
.nseo-facility-tool__resize-handle:hover,
.nseo-facility-tool__resize-handle.is-resizing {
	background: var(--brand-primary);
	opacity: 0.4;
}
.nseo-facility-tool__warnings {
	margin-bottom: var(--space-4);
	padding: var(--space-3);
	border-radius: var(--radius-md);
	background: var(--warning-soft, #FFFBEB);
	color: var(--text-secondary);
	font-size: var(--text-sm-size);
}
.nseo-facility-tool__warnings p {
	margin: 0 0 var(--space-1);
}
.nseo-facility-tool__warnings p:last-child {
	margin-bottom: 0;
}
.nseo-facility-tool__table tbody tr.is-pending {
	color: var(--text-secondary);
	opacity: 0.6;
}
.nseo-facility-tool__table tbody tr.is-processing {
	background: var(--brand-primary-soft);
}
.nseo-facility-tool__table tbody tr.is-processing td:first-child {
	box-shadow: inset 3px 0 0 var(--brand-primary);
}
.nseo-facility-tool__table tbody tr.is-done td:first-child {
	box-shadow: inset 3px 0 0 var(--success, #16A34A);
}
.nseo-facility-tool__table tbody tr.is-issue {
	background: var(--surface-hover);
}
.nseo-facility-tool__table tbody tr.is-issue td:first-child {
	box-shadow: inset 3px 0 0 var(--text-tertiary);
}
.nseo-facility-tool__table tbody tr.is-failed {
	background: var(--danger-soft, #FEF2F2);
}
.nseo-facility-tool__table tbody tr.is-failed td:first-child {
	box-shadow: inset 3px 0 0 var(--danger, #DC2626);
}

/* KW-22: seccion de "dar de baja el sitio" -- visualmente separada del
   resto del formulario para que no se confunda con una accion rutinaria. */
.nseo-form-section--danger {
	margin-top: var(--space-6, 32px);
	padding: var(--space-5, 24px);
	background: var(--surface-elevated, #ffffff);
	border: 1px solid var(--danger, #DC2626);
	border-radius: 10px;
}
.nseo-form-section--danger .nseo-form-section__title {
	margin: 0 0 var(--space-2, 8px);
	font-size: 15px;
	font-weight: 600;
	color: var(--danger, #DC2626);
}
.nseo-form-section--danger .nseo-form-field__hint {
	margin-bottom: var(--space-4, 16px);
}
