Files
fspm-web/src/app/(sitio)/cumplimiento-nom-002/page.tsx
T
Uriel JarethandClaude Opus 5 31ee899987 fix: defectos encontrados por la suite de extremo a extremo
La primera corrida completa dio 57 fallas. Solo una parte eran del
producto; el resto era instrumentación mal escrita. Queda en 261 en verde.

Defectos del producto:

- La atribución de campaña se perdía. La captura vivía en un efecto de
  React, así que si la persona llegaba con parámetros de campaña y
  navegaba antes de hidratar, el primer toque nunca se guardaba y
  utmCampaign llegaba vacío al CRM. Ahora se captura en un script en
  línea que corre al analizar el documento.
- Siete páginas sin og:image: una página que declara su propio openGraph
  no hereda las imágenes del layout, las sobreescribe. Solo se nota al
  compartir el enlace. Se resuelve con una función compartida en seo.ts.
- El panel no se podía usar desde Safari por HTTP: la cookie Secure no se
  guarda y el acceso falla en silencio. Queda explícito y documentado.
- El panel se corría de lado en móvil: la cabecera no cabía a 375px.
- Las tarjetas de perfil del acceso se cortaban en móvil. Un elemento de
  rejilla nace con min-width auto y no puede encogerse bajo su contenido.
  Era además el origen de un desplazamiento que se arrastraba al tablero.
- Las tablas accesibles de las gráficas volvían desplazable la página:
  sr-only fija width 1px y el algoritmo de tablas lo ignora.
- El campo de búsqueda del catálogo no tenía nombre accesible.
- Límite de tasa de 5 envíos por IP: bloqueaba una demostración en vivo
  con varias personas en la misma red. Configurable, ahora 20.
- El salto de contenido pasa de left:-9999px a recorte de 1px.

Instrumentación corregida, con la razón escrita en cada caso:

- El desborde horizontal se mide intentando desplazar la página, no con
  documentElement.scrollWidth, que sobreinforma con contenedores propios.
- La comprobación de accesibilidad respeta el árbol de accesibilidad.
- El aislamiento entre roles se prueba pidiendo por URL una oportunidad
  ajena, no comparando folios entre listados paginados.
- Fuera las esperas por networkidle, que agotaban el tiempo sin fallar.
- Que el panel no esté enlazado se comprueba leyendo el HTML servido.
- Safari no enfoca enlaces con Tab: declarado como del navegador.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-08-28 02:37:42 -06:00

598 lines
26 KiB
TypeScript

import type { Metadata } from "next";
import Link from "next/link";
import { FormularioContacto } from "@/components/formulario/FormularioContacto";
import { TarjetaEscenario } from "@/components/marca/IconoEscenario";
import { Migas } from "@/components/site/contenido/Migas";
import { FOTOS, HeroeLanding } from "@/components/site/HeroeLanding";
import { Revelar } from "@/components/site/Revelar";
import { EMPRESA, NORMAS, SITIO_URL } from "@/data/empresa";
import { ESCENARIOS, type Escenario } from "@/data/escenarios";
import { INDUSTRIAS } from "@/data/industrias";
import { imagenesOg } from "@/lib/seo";
/**
* /cumplimiento-nom-002 — la página de mayor intención de compra del sitio.
*
* Orden deliberado: primero las tres preguntas que hace el dueño de un negocio
* —me aplica, qué me pueden multar, qué tengo que tener— y solo después la
* precisión normativa. Cada bloque está escrito en dos niveles: la primera
* frase la entiende cualquiera, la segunda le da al experto el dato.
*
* Regla del contenido: no se citan artículos, umbrales, plazos ni montos de
* sanción que no estén en src/data/empresa.ts o en la fuente pública. Lo que no
* está verificado se declara como no reproducido; no se estima.
*/
const TITULO = "Cumplimiento NOM-002-STPS-2010: qué te van a pedir";
const DESCRIPCION =
"¿La NOM-002-STPS-2010 te aplica y qué te van a pedir en una verificación? Explicado sin tecnicismos y con la precisión normativa después: clasificación de riesgo, equipo, plan de emergencia, brigadas, simulacros y los ocho documentos del expediente.";
export const metadata: Metadata = {
title: TITULO,
description: DESCRIPCION,
alternates: { canonical: `${SITIO_URL}/cumplimiento-nom-002` },
openGraph: {
title: `${TITULO} | ${EMPRESA.nombreCorto}`,
description: DESCRIPCION,
url: `${SITIO_URL}/cumplimiento-nom-002`,
...imagenesOg(),
},
};
const AVISO_ALCANCE =
"Esta página es una referencia orientativa construida con información pública. La normativa puede actualizarse y complementarse por estado, municipio, tipo de instalación y autoridad competente. No sustituye un dictamen técnico ni una opinión jurídica.";
const MENSAJE_INICIAL = "Necesito saber si cumplo con la NOM-002. Mi instalación es un ";
/**
* Las tres preguntas reales, en el orden en el que llegan. Cada respuesta abre
* en lenguaje llano y cierra con el dato normativo.
*/
const PREGUNTAS_REALES = [
{
id: "me-aplica",
pregunta: "¿Esto me aplica a mí?",
llano:
"Si tienes gente trabajando, sí. No hay tamaño mínimo: aplica igual a una oficina de quince personas que a una planta de trescientas.",
tecnico:
"La NOM-002-STPS-2010 rige para todo centro de trabajo en México. Lo que cambia entre una oficina y una planta no es la norma: es el nivel de riesgo de incendio con el que se clasifica el centro, y de ese nivel dependen el equipo, los sistemas y el plan que te corresponden.",
},
{
id: "que-me-multan",
pregunta: "¿Qué me pueden multar?",
llano:
"No te vamos a dar una cifra. Quien te promete un monto exacto en una página web se lo está inventando, y con eso no se toma una decisión.",
tecnico:
"El monto de una sanción lo determina la autoridad competente según lo que encuentre en la verificación, y no lo publicamos porque no podemos sostenerlo con una fuente verificable. Lo que sí es concreto —y es lo que conviene preparar— son los ocho documentos del expediente que aparece más abajo.",
},
{
id: "que-necesito",
pregunta: "¿Qué tengo que tener?",
llano:
"Equipo que sirva para lo que se puede quemar en cada área, un plan escrito, personal que sepa qué hacer y registro de todo lo anterior. No se cumple solo comprando extintores.",
tecnico:
"En el orden que sigue la norma: clasificación del riesgo de incendio, equipo contra incendio, sistemas fijos y medios de detección y alarma cuando el nivel lo exige, plan de atención a emergencias por escrito, brigadas con capacitación acreditada y simulacros ejecutados y documentados.",
},
];
/** Elementos que la norma contempla, según la referencia de NORMAS. */
const ELEMENTOS = [
{
n: "01",
titulo: "Clasificación del riesgo de incendio",
llano:
"Es el primer paso y define todo lo demás. Si se hace mal, todo lo que se compre encima queda mal.",
detalle:
"De la clasificación depende qué equipo, qué sistemas y qué plan te corresponden. Se determina con el procedimiento de la propia norma; los umbrales no se reproducen aquí porque dependen del material y de la superficie de cada centro de trabajo.",
},
{
n: "02",
titulo: "Equipo contra incendio",
llano: "Extintores que se vean, se alcancen y sirvan para lo que hay en esa área concreta.",
detalle:
"Disponibles, accesibles y señalizados, seleccionados según la clase de fuego presente en cada zona. El equipo correcto en el lugar equivocado no cumple, y el conteo total no sustituye a la distancia de recorrido.",
},
{
n: "03",
titulo: "Sistemas fijos y de alarma",
llano: "Si tu riesgo es alto, con equipo portátil no alcanza.",
detalle:
"Según el nivel de riesgo, el centro de trabajo puede requerir sistemas fijos de supresión y medios de detección y alarma, además del equipo portátil. Es el punto donde la conversación deja de ser una compra y pasa a ser un proyecto.",
},
{
n: "04",
titulo: "Plan de atención a emergencias",
llano: "Un documento que diga quién hace qué el día del incidente. Por escrito, no de palabra.",
detalle:
"Es lo primero que se pide en una verificación y lo que con más frecuencia no existe o quedó desactualizado tras un cambio de instalación, de proceso o de personal.",
},
{
n: "05",
titulo: "Brigadas y capacitación",
llano: "Personas con nombre y apellido que sepan operar el equipo, y un papel que lo compruebe.",
detalle:
"Personal designado, entrenado y con constancia por persona y fecha. La capacitación sin registro documental no es demostrable ante una autoridad, aunque haya ocurrido.",
},
{
n: "06",
titulo: "Simulacros",
llano: "Practicarlo antes, y dejar constancia de que se practicó.",
detalle:
"Ejecutados y documentados. El registro del simulacro es evidencia doble, del plan y de la capacitación, y es donde se detectan los huecos que un plano no muestra.",
},
];
const EXPEDIENTE = [
{
documento: "Clasificación de riesgo de incendio",
quePrueba: "Que el nivel de exigencia aplicado al centro de trabajo es el correcto.",
quienLoPide: "Verificación STPS, Protección Civil, aseguradora",
},
{
documento: "Plan de atención a emergencias",
quePrueba: "Que existe un procedimiento escrito y vigente para el escenario.",
quienLoPide: "Verificación STPS, Protección Civil",
},
{
documento: "Inventario y ubicación del equipo",
quePrueba: "Qué hay instalado, dónde, de qué clase y con qué capacidad.",
quienLoPide: "Verificación STPS, auditoría interna",
},
{
documento: "Ficha técnica y certificado por modelo",
quePrueba: "Que el equipo instalado es el que se declara y cubre las clases que se afirman.",
quienLoPide: "Auditoría, aseguradora, cliente corporativo",
},
{
documento: "Hoja de datos de seguridad del agente",
quePrueba: "Manejo, almacenamiento y respuesta ante exposición del agente extintor.",
quienLoPide: "Seguridad industrial, ambiental, auditoría",
},
{
documento: "Bitácora de revisión mensual",
quePrueba: "Que la revisión de extintores se realiza con la periodicidad debida.",
quienLoPide: "Verificación STPS, Protección Civil",
},
{
documento: "Constancias de capacitación y brigadas",
quePrueba: "Que hay personal designado y entrenado, con nombre y fecha.",
quienLoPide: "Verificación STPS",
},
{
documento: "Registro de simulacros",
quePrueba: "Que el plan se ejecuta y se corrige con lo aprendido.",
quienLoPide: "Verificación STPS, Protección Civil",
},
];
/** Los ocho escenarios más frecuentes en una conversación de cumplimiento. */
const SLUGS_CUMPLIMIENTO = [
"industria",
"gasolineras",
"bodegas",
"cocinas-hoteles",
"oficinas",
"auditorios-afluencia",
"flotas-maquinaria",
"minas",
];
const ESCENARIOS_CUMPLIMIENTO = ESCENARIOS.filter((e) => SLUGS_CUMPLIMIENTO.includes(e.slug));
function hrefEscenario(escenario: Escenario): string {
if (escenario.industria) return `/soluciones/${escenario.industria}`;
const categoria = escenario.categorias[0];
return categoria ? `/catalogo/${categoria}` : "/catalogo";
}
export default function PaginaCumplimiento() {
return (
<>
<HeroeLanding
antes={<Migas actual="Cumplimiento NOM-002" />}
eyebrow="Cumplimiento NOM-002-STPS-2010"
titulo="¿La NOM-002 te aplica? Sí. Esto es lo que te van a pedir"
entrada="Primero en español llano y después con la precisión normativa. Si solo quieres saber por dónde empezar, empieza por la revisión: te decimos qué te falta antes de venderte nada."
foto={FOTOS.normas}
enfoque="62% 42%"
altura="alto"
prioridad
>
<div className="flex flex-col gap-4 sm:flex-row sm:items-center">
<Link href="#validar" className="btn btn-signal w-full sm:w-auto">
Revisar mi cumplimiento
</Link>
<p className="font-mono text-[0.625rem] uppercase leading-relaxed tracking-[0.1em] text-faint">
Cuatro campos · Sin costo · Sin compromiso de compra
</p>
</div>
</HeroeLanding>
{/* ---------- las tres preguntas reales ---------- */}
<section className="grid-bg-lite bg-paper py-14 sm:py-20" aria-labelledby="preguntas-titulo">
<div className="shell">
<Revelar>
<p className="eyebrow mb-4">Empecemos por lo básico</p>
<h2
id="preguntas-titulo"
className="max-w-2xl font-display text-2xl font-extrabold text-deep sm:text-3xl"
>
Las tres preguntas que hace todo el mundo, respondidas sin rodeos
</h2>
<p className="mt-4 max-w-2xl text-sm leading-relaxed text-deep-muted sm:text-base">
En cada respuesta, lo primero es lo que necesitas para decidir. Lo segundo es el
detalle normativo, para quien tiene que sostenerlo ante una auditoría.
</p>
</Revelar>
<div className="mt-10 grid gap-px bg-rule-lite lg:grid-cols-3">
{PREGUNTAS_REALES.map((item) => (
<article key={item.id} id={item.id} className="bg-white p-6 sm:p-7">
<h3 className="font-display text-lg font-extrabold leading-tight text-deep sm:text-xl">
{item.pregunta}
</h3>
<p className="mt-4 text-base leading-relaxed text-deep">{item.llano}</p>
<hr className="hair-lite my-5" />
<p className="font-mono text-[0.625rem] uppercase tracking-[0.14em] text-deep-muted">
El dato normativo
</p>
<p className="mt-2.5 text-sm leading-relaxed text-deep-muted">{item.tecnico}</p>
</article>
))}
</div>
<div
role="note"
aria-label="Alcance de esta página"
className="mt-10 max-w-3xl rounded-[6px] border border-rule-lite border-l-2 border-l-ember bg-white p-5 sm:p-6"
>
<p className="font-mono text-[0.6875rem] uppercase tracking-[0.16em] text-deep-muted">
Alcance de esta página
</p>
<p className="mt-3 text-sm leading-relaxed text-deep-muted">{AVISO_ALCANCE}</p>
</div>
</div>
</section>
{/* ---------- identifica tu caso con la iconografía de escenarios ---------- */}
<section
className="border-t border-rule bg-ink py-14 sm:py-20"
aria-labelledby="escenarios-titulo"
>
<div className="shell">
<Revelar>
<p className="eyebrow mb-4">Encuentra tu caso</p>
<h2
id="escenarios-titulo"
className="max-w-2xl font-display text-2xl font-extrabold sm:text-3xl"
>
Busca el lugar que se parece al tuyo
</h2>
<p className="mt-4 max-w-2xl text-sm leading-relaxed text-muted sm:text-base">
No hace falta que sepas qué clase de fuego tienes. Si administras una gasolinera, un
hotel o una bodega, eso ya define el perfil de riesgo y, con él, las obligaciones que
se te aplican con más peso.
</p>
</Revelar>
<ul className="mt-10 grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
{ESCENARIOS_CUMPLIMIENTO.map((escenario) => (
<li key={escenario.slug} className="grid">
<TarjetaEscenario
escenario={escenario}
href={hrefEscenario(escenario)}
conRiesgo={false}
/>
</li>
))}
</ul>
<p className="mt-8 max-w-3xl text-sm leading-relaxed text-muted">
Si el tuyo no está en la lista, escríbelo tal cual en la revisión: lo clasificamos
nosotros.{" "}
<Link href="#validar" className="link">
Ir a la revisión
</Link>
.
</p>
</div>
</section>
{/* ---------- qué contempla la norma ---------- */}
<section
className="grid-bg-lite border-t border-rule bg-paper py-14 sm:py-20"
aria-labelledby="elementos-titulo"
>
<div className="shell">
<Revelar>
<p className="eyebrow mb-4">Qué contempla la norma</p>
<h2
id="elementos-titulo"
className="max-w-2xl font-display text-2xl font-extrabold text-deep sm:text-3xl"
>
Seis frentes, y ninguno se cierra con una compra
</h2>
<p className="mt-4 max-w-2xl text-sm leading-relaxed text-deep-muted sm:text-base">
Cada frente genera un documento distinto. Los expedientes incompletos casi siempre
fallan en los tres que no se compran: el plan, la capacitación y el registro.
</p>
</Revelar>
<ol className="mt-10 grid gap-px bg-rule-lite sm:grid-cols-2 lg:grid-cols-3">
{ELEMENTOS.map((elemento) => (
<li key={elemento.n} className="bg-white p-6 sm:p-7">
<p className="font-mono text-[0.625rem] font-semibold tracking-[0.1em] text-signal">
{elemento.n}
</p>
<h3 className="mt-3 font-display text-base font-extrabold leading-tight text-deep">
{elemento.titulo}
</h3>
<p className="mt-3 text-sm leading-relaxed text-deep">{elemento.llano}</p>
<p className="mt-3 text-sm leading-relaxed text-deep-muted">{elemento.detalle}</p>
</li>
))}
</ol>
<div className="mt-10 rounded-[6px] border border-rule-lite bg-white p-5 sm:p-6">
<p className="font-mono text-[0.6875rem] uppercase tracking-[0.16em] text-deep-muted">
La obligación que más se pierde de vista
</p>
<h3 className="mt-3 font-display text-lg font-extrabold text-deep">
Los extintores se revisan cada mes
</h3>
<p className="mt-3 max-w-3xl text-sm leading-relaxed text-deep-muted">
{NORMAS[1].aplica} Casi nunca se pierde por desconocerla: se pierde porque nadie
quedó a cargo de la bitácora.
</p>
</div>
</div>
</section>
{/* ---------- el expediente ---------- */}
<section
className="border-t border-rule bg-ink py-14 sm:py-20"
aria-labelledby="expediente-titulo"
>
<div className="shell-wide">
<Revelar>
<p className="eyebrow mb-4">Expediente</p>
<h2
id="expediente-titulo"
className="max-w-2xl font-display text-2xl font-extrabold sm:text-3xl"
>
Los ocho documentos que piden en una verificación
</h2>
<p className="mt-4 max-w-2xl text-sm leading-relaxed text-muted sm:text-base">
Esta es la lista con la que conviene compararse antes de que alguien llegue a
pedirla. Ninguno es opcional cuando se pregunta, y cada uno prueba algo distinto.
</p>
</Revelar>
<p className="mt-6 font-mono text-[0.6875rem] uppercase tracking-[0.14em] text-faint sm:hidden">
Desliza la tabla para ver todas las columnas
</p>
<div
className="mt-4 overflow-x-auto rounded-[6px] border border-rule bg-ink-2 [-webkit-overflow-scrolling:touch]"
tabIndex={0}
role="region"
aria-label="Documentos del expediente, tabla desplazable en horizontal"
>
<table className="w-full min-w-[46rem] border-collapse text-left">
<caption className="sr-only">
Documentos que integran un expediente de cumplimiento, qué prueba cada uno y quién
lo solicita.
</caption>
<thead>
<tr className="border-b border-rule bg-ink-3">
{["Documento", "Qué prueba", "Quién lo pide"].map((c) => (
<th
key={c}
scope="col"
className="whitespace-nowrap px-4 py-3 font-mono text-[0.625rem] font-medium uppercase tracking-[0.14em] text-faint"
>
{c}
</th>
))}
</tr>
</thead>
<tbody>
{EXPEDIENTE.map((fila) => (
<tr key={fila.documento} className="border-b border-rule last:border-b-0">
<th scope="row" className="px-4 py-4 text-left align-top">
<span className="font-sans text-sm font-semibold text-bright">
{fila.documento}
</span>
</th>
<td className="max-w-[24rem] px-4 py-4 align-top text-sm leading-relaxed text-muted">
{fila.quePrueba}
</td>
<td className="px-4 py-4 align-top font-mono text-xs leading-relaxed text-muted">
{fila.quienLoPide}
</td>
</tr>
))}
</tbody>
</table>
</div>
<div className="mt-8 flex flex-col gap-4 sm:flex-row sm:items-center">
<Link href="#validar" className="btn btn-signal w-full sm:w-auto">
Ver qué me falta del expediente
</Link>
<p className="max-w-lg text-xs leading-relaxed text-faint">
En una compra con nosotros, los documentos que dependen del equipo se entregan por
número de modelo.{" "}
<Link href="/evidencia" className="link">
Ver el índice de documentación por categoría
</Link>
.
</p>
</div>
</div>
</section>
{/* ---------- lo que cambia por operación ---------- */}
<section
className="grid-bg-lite border-t border-rule bg-paper py-14 sm:py-20"
aria-labelledby="segmentos-titulo"
>
<div className="shell">
<Revelar>
<p className="eyebrow mb-4">Por operación</p>
<h2
id="segmentos-titulo"
className="max-w-2xl font-display text-2xl font-extrabold text-deep sm:text-3xl"
>
Lo que además se te pide según dónde trabajas
</h2>
<p className="mt-4 max-w-2xl text-sm leading-relaxed text-deep-muted sm:text-base">
La NOM-002 es el piso común. Encima de ella, cada sector acumula requisitos propios
de su autoridad, de su aseguradora o de su cliente corporativo.
</p>
</Revelar>
<ul className="mt-10 grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
{INDUSTRIAS.map((industria) => (
<li key={industria.slug} className="flex">
<Link
href={`/soluciones/${industria.slug}`}
className="group flex h-full w-full flex-col rounded-[6px] border border-rule-lite bg-white p-5 transition-colors duration-200 hover:border-signal [-webkit-tap-highlight-color:transparent]"
>
<h3 className="font-display text-base font-extrabold leading-tight text-deep">
{industria.nombre}
</h3>
<p className="mt-2 text-sm leading-relaxed text-deep">{industria.dolor}</p>
<ul className="mt-4 space-y-2">
{industria.cumplimiento.map((obligacion) => (
<li
key={obligacion}
className="flex gap-2.5 text-xs leading-relaxed text-deep-muted"
>
<span
aria-hidden="true"
className="mt-1.5 h-1 w-1 shrink-0 rounded-full bg-signal"
/>
{obligacion}
</li>
))}
</ul>
<span className="mt-auto pt-5 font-mono text-[0.625rem] uppercase tracking-[0.14em] text-signal transition-colors group-hover:text-signal-hi">
Ver el segmento &rarr;
</span>
</Link>
</li>
))}
</ul>
</div>
</section>
{/* ---------- referencias normativas ---------- */}
<section
className="border-t border-rule bg-ink-2 py-14 sm:py-16"
aria-labelledby="referencias-titulo"
>
<div className="shell">
<Revelar>
<p className="eyebrow eyebrow-muted mb-4">Referencias</p>
<h2 id="referencias-titulo" className="font-display text-xl font-extrabold sm:text-2xl">
Normas citadas en esta página
</h2>
</Revelar>
<ul className="mt-8 grid gap-4 lg:grid-cols-2">
{NORMAS.map((norma) => (
<li key={norma.clave} className="panel p-5 sm:p-6">
<p className="font-mono text-xs font-semibold uppercase tracking-[0.12em] text-signal">
{norma.clave}
</p>
<h3 className="mt-3 font-display text-base font-extrabold leading-tight text-bright">
{norma.titulo}
</h3>
<p className="mt-3 text-sm leading-relaxed text-muted">{norma.aplica}</p>
<a
href={norma.fuente}
target="_blank"
rel="noopener noreferrer"
className="mt-4 inline-block font-mono text-[0.625rem] uppercase tracking-[0.14em] text-bright underline decoration-rule-2 underline-offset-4 hover:decoration-signal"
>
Ver la fuente oficial
</a>
</li>
))}
</ul>
<p className="mt-8 max-w-3xl text-xs leading-relaxed text-faint">
Los enlaces apuntan al sitio del Diario Oficial de la Federación. Verifica siempre la
versión vigente: la publicación oficial manda sobre cualquier resumen, incluido este.
</p>
</div>
</section>
{/* ---------- conversión ---------- */}
<section
id="validar"
className="grid-bg-lite border-t border-rule bg-paper py-14 sm:py-20"
aria-labelledby="validar-titulo"
>
<div className="shell">
<div className="grid gap-10 lg:grid-cols-[1fr_1.05fr] lg:items-start lg:gap-16">
<div>
<Revelar>
<p className="eyebrow mb-4">Siguiente paso</p>
<h2
id="validar-titulo"
className="font-display text-2xl font-extrabold text-deep sm:text-3xl"
>
Te decimos qué te falta antes de venderte nada
</h2>
<p className="mt-4 text-sm leading-relaxed text-deep-muted sm:text-base">
Revisamos qué tienes, qué te falta y en qué orden conviene resolverlo. Si tu
situación requiere un dictamen formal, te lo decimos en lugar de venderte equipo.
</p>
</Revelar>
<ul className="mt-8 space-y-3.5">
{[
"No necesitas saber tu nivel de riesgo para escribirnos: eso es justo lo que revisamos.",
"Si ya te levantaron una observación, mándala tal cual y respondemos sobre ella.",
"Si lo que te falta no es equipo sino documentación, lo decimos así.",
].map((punto) => (
<li key={punto} className="flex gap-3 text-sm leading-relaxed text-deep-muted">
<span
aria-hidden="true"
className="mt-2 h-1 w-1 shrink-0 rounded-full bg-signal"
/>
{punto}
</li>
))}
</ul>
<div
role="note"
aria-label="Recordatorio de alcance"
className="mt-8 rounded-[6px] border border-rule-lite border-l-2 border-l-ember bg-white p-5"
>
<p className="font-mono text-[0.6875rem] uppercase tracking-[0.16em] text-deep-muted">
Recordatorio de alcance
</p>
<p className="mt-3 text-sm leading-relaxed text-deep-muted">{AVISO_ALCANCE}</p>
</div>
</div>
<FormularioContacto
id="formulario-cumplimiento"
canal="cumplimiento"
variante="claro"
titulo="Revisar mi cumplimiento NOM-002"
descripcion="Completa la frase del mensaje con tu tipo de instalación y envía. Respondemos con el hueco documental que vemos y por dónde empezar."
mensajeInicial={MENSAJE_INICIAL}
textoBoton="Solicitar revisión"
/>
</div>
</div>
</section>
</>
);
}