Auditoría de Diseño de Sitio Web → Wireframes → Libro de Decisiones
Propósito
Convertir un clon local de un sitio web en: (1) evidencia con hash vinculada a un commit de git, (2) hallazgos que cada uno cita una regla y apunta a archivos fuente probables, (3) wireframes actuales y futuros en Figma, (4) registros de decisiones que explican cada cambio, (5) registros de aprobación humana y (6) resúmenes de implementación para decisiones aprobadas que Claude Code o Codex ejecutan en una sesión separada. El libro de git es la fuente de verdad. Figma es una proyección de él. Esta habilidad diseña y registra; nunca edita el código fuente del sitio.
Flujo de trabajo previsto
- El estudiante clona el repositorio de su sitio (desde GitHub, o el repositorio del que se despliega un proyecto de Vercel) y lo ejecuta localmente. Se espera que los estudiantes tengan acceso educativo al Figma MCP.
- Esta habilidad captura del servidor de desarrollo local, audita y construye wireframes en Figma.
- Un humano clasifica los hallazgos, revisa las decisiones y las aprueba.
- Esta habilidad escribe un resumen de entrega por decisión aprobada. Claude Code o Codex implementa cada uno en su propia rama. Esta habilidad recaptura para verificar.
Comandos
La carpeta de la habilidad tiene un comando, fwd, y un CLAUDE.md que dice cómo responderlo. Cuando el usuario escribe help, check, init o tutorial, siga CLAUDE.md:
helpejecutafwd help(verificaciones de configuración más un siguiente paso) y, con las herramientas de Figma presentes,whoamipara el asiento. Primero lo que falta; un siguiente paso; no se realizan cambios en nombre del estudiante.tutorialejecuta el primer tutorial de siete pasos (rediseñar su página de inicio). Son las fases propias de esta habilidad, impulsadas paso a paso.fwd approve|reject|defer <D-id>es del estudiante, ejecutado en su propio terminal. Escribe el archivo de aprobación y el evento del libro de decisiones. No negociable 1 aplica: nunca lo ejecute, nunca escribaaudit/approvals/.fwd ledger verifyverifica la cadena de hash y que cada archivo de aprobación coincida con el libro de decisiones.
No negociables
- Solo un humano puede establecer una decisión como aprobada, rechazada o diferida, o reabrir una. Nunca escriba esos estados. Nunca escriba archivos en
audit/approvals/. - Cada hallazgo cita un
rule_iddeaudit/rulebook/rules.yaml. Sin regla, sin hallazgo: regístrelo como unaobservaciónpara el humano. - Las etiquetas de los hallazgos siguen el nivel de la regla: normativo →
failure, heurístico →concern, interno →deviation. Nunca llame a un hallazgo heurístico un fallo. Nunca use iconos o palabras de aprobado/fallo (✅ ❌ "violated") en hallazgos heurísticos. - Cada diferencia entre un marco actual y su marco futuro lleva al menos un ID de decisión. Marque las diferencias sin etiquetar; no las absorba.
- Nunca edite la página
00 As-Is. Nunca modifique o elimine nodos que la habilidad no creó. Solo toque las anotaciones en las categorías propias de la habilidad, y siempre lea-funda-escriba. - Nunca establezca el estado de Modo Dev (Listo para desarrollo / Completado). Nunca resuelva o elimine comentarios humanos.
- Sin escrituras en Figma en un archivo existente hasta que el humano haya guardado una versión base nombrada y su ID esté registrado. Excepción: un archivo de Figma que esta ejecución creó por sí misma. Comienza vacío, por lo que el archivo vacío es su propia línea base; regístrelo en
capabilities.json. - Capture solo de un clon local de un repositorio que el usuario posea o tenga derechos para trabajar, servido desde localhost, o del sitio desplegado o una vista previa de Vercel de ese mismo repositorio cuando el usuario proporcione su URL. Nunca capture, inyecte scripts en o elimine encabezados de seguridad en sitios en vivo de terceros.
intent.yamldebe registrar el repositorio y el commit fijado. - Nunca sobrescriba un marco de hallazgos anterior o la salida de una ejecución anterior. Las re-ejecuciones crean un nuevo marco versionado (ver Fase 7). Nunca localice sus propios nodos por nombre de capa, color de relleno o heurísticas de texto; use los ID de nodo registrados en el libro de decisiones.
- Nunca edite el código fuente del sitio. La implementación ocurre solo en una sesión separada de Claude Code o Codex, a partir de un resumen de entrega para una decisión aprobada.
Diseño de directorio
audit/
intent.yaml # llenado por humano (Fase 0)
rulebook/rules.yaml # confirmado por humano (Fase 1)
schema/ # esquemas de hallazgo, decisión, aprobación, evento
runs/R-YYYYMMDD-NN/
capabilities.json # lo que esta ejecución pudo hacer realmente
manifest.json # hashes de captura y estado
captures/{width}/ # screenshot.png, dom.html, axe.json, checks.json, skeleton.json
findings.json
decisions/D-NNNN.json
approvals/A-NNNN.json # solo humanos
handoff/ # resúmenes de implementación, solo decisiones aprobadas
README.md # reglas compartidas para el agente implementador
D-NNNN.md # un resumen por decisión aprobada
ledger.jsonl # solo adición, eventos con cadena de hash
El clon del sitio vive fuera de audit/ (en local_path). Esta habilidad lo lee y nunca escribe en él. audit/ puede estar en una carpeta hermana o en su propia rama, por lo que los registros de auditoría nunca se mezclan con los commits del sitio.
Fase 0 — Intención (Puerta G0)
Si audit/intent.yaml falta o tiene campos requeridos vacíos, pregunte por los campos que faltan de forma conversacional, uno o dos a la vez. No capture, evalúe ni escriba nada hasta que cada campo requerido sea llenado por el usuario. Si el usuario aún no ha clonado el repositorio, dele el comando git clone exacto (para un proyecto de Vercel, el repositorio de GitHub del que se despliega) en su propio bloque de código y espere.
repo: "" # requerido: URL de GitHub (o proyecto de Vercel) del sitio
local_path: "" # requerido: ruta del clon local
commit: "" # requerido: SHA del commit al que se fija la auditoría
dev_command: "" # requerido: ej. "npm run dev"
dev_url: "http://localhost:3000"
routes: [] # requerido: rutas a auditar, ej. ["/", "/apply"]
ownership: "" # requerido: "repositorio propio", o quién otorgó permiso, y cuándo
implementer: "" # requerido: "claude-code" o "codex"
conformance_target: "WCAG 2.2 AA"
breakpoints: "derive" # "derive" del CSS del sitio, o una lista de anchos
house_rules: "" # ruta a tokens del sistema de diseño, o "none"
figma_file: "" # requerido para fases de Figma; en blanco = modo solo JSON
approvers: [] # requerido: nombres y roles
out_of_scope: []
Fase 1 — Esquema (Puerta G1)
Resuma el libro de reglas (conteo de reglas por nivel y modo) y los esquemas de registro. Pida al usuario que confirme o edite. Registre un evento schema.confirmed en el libro de decisiones con el nombre del usuario y la fecha. No continúe sin eso.
Sonda de capacidad en tiempo de ejecución
Antes de la Fase 2, escriba capabilities.json:
- Qué herramientas de Figma MCP están presentes (
use_figma,generate_figma_design,html_to_figma,get_metadata,get_screenshot,generate_diagram,upload_assets). - Resultado de
whoami: tipo de asiento en el plan que poseefigma_file. Si no son posibles las escrituras, establezcamode: json-onlyy omita las escrituras de Figma para la ejecución. Se espera que los estudiantes tengan acceso a un plan educativo; aún así, registre el asiento y el plan reales en lugar de asumir, y observe cualquier error de límite de velocidad. - Entorno local: versiones de Node y del gestor de paquetes, si
dev_commandse inicia y si el árbol de trabajo enlocal_pathestá limpio y encommit. - Cargue la habilidad
figma-usede Figma antes de cualquier llamadause_figma. - Lea el esquema de la herramienta
use_figmaen vivo y registre si acepta un parámetroskillNames. Una habilidad comparable de Figma (Throughline) pasaskillNames: "throughline"en cada llamada. Si el parámetro existe, paseskillNames: "figma-webdesigner"en cada llamadause_figma; si no, registreskillNames: unsupported. - Conocido desde la primera ejecución (2026-11-07, asiento de estudiante completo), vuelva a verificar en lugar de asumir:
setSharedPluginDatafunciona;addAnnotationCategoryAsyncynode.annotations(conlabelMarkdownycategoryId) funcionan;figma.saveVersionHistoryAsyncNO es compatible, por lo que el agente nunca puede crear la versión base;figma.root.nameNO se puede establecer, por lo que el archivo no se puede renombrar a través de la API. Si alguno de estos ahora falla, lleve los ID de decisión en los nombres de los marcos como⟦D-0007⟧más anotaciones, y registre el resultado. - Nombre el archivo de Figma para el sitio (por ejemplo
jobs.humanitarians.ai) al llamarcreate_new_file; no se puede renombrar después. Las páginas son etapas (00 Kit & Legend,01 As-Is Wireframes,02 To-Be Wireframes); los marcos sonpage / width / as-is|to-be / state.
Convenciones de script use_figma
Cada script que esta habilidad envía a través de use_figma debe seguir estas reglas:
- Los hermanos de misma altura necesitan
layoutSizingVertical = 'FILL'en cada hijo (ylayoutAlign = 'STRETCH'solo no es suficiente cuando el padre ajusta su altura). El texto en un concentrador o celda de tabla que debe ajustarse necesitatextAutoResize = 'HEIGHT'y un ancho. - Fuentes primero. Llame
figma.loadFontAsyncpara cada estilo de fuente que el script use (incluyendo Cursiva y Medium si se usan) en unPromise.allal principio, antes de crear o editar cualquier texto. - Establezca el tamaño después de la paternidad. Agregue cada nodo a su padre, luego establezca
layoutSizingHorizontalylayoutSizingVertical. Use solo nombres de propiedad documentados (cornerRadius, nocorner); una propiedad desconocida se ignora silenciosamente. - Devuelva un recibo de escritura. El script debe devolver un objeto con
createdNodeIdsymutatedNodeIds(ambos siempre llenos honestamente; matrices vacías solo cuando no ocurrió nada de ese tipo), másframeId,stamped(si se escribieron datos del plugin) ypageId. - Registre el recibo en el libro de decisiones. Después de cada llamada, agregue un evento
figma.writeque contenga el recibo, el ID de ejecución, los ID de decisión involucrados yversion_before. Las fases posteriores encuentran nodos propiedad de la habilidad a partir de estos ID, nunca de nombres o colores. - Estado anterior para mutaciones. Si el script cambia cualquier nodo existente (anotaciones en un nodo creado por la habilidad, texto, rellenos), devuelva los valores anteriores en el recibo para que el libro de decisiones pueda registrarlos. No se permite sobrescribir sin un estado anterior registrado.
- Falle en voz alta. Sin éxito silencioso. Si una búsqueda no encuentra nada, devuelva un error que enumere lo que se encontró; nunca informe éxito para una no operación.
Fase 2 — Captura
- Prepare el clon. Confirme que
local_pathestá encommitcon un árbol de trabajo limpio (si no, registredirty: truey deténgase para preguntar), instale dependencias, iniciedev_commandy confirme quedev_urlresponde. Registre el SHA del commit, el indicador sucio y la versión de Node enmanifest.json. No modifique ningún archivo fuente. Si el proyecto necesita variables de entorno o secretos que no están presentes, pregunte al usuario; nunca los invente. - Derive los puntos de quiebre de la propia configuración del repositorio (configuración de Tailwind, consultas de medios CSS personalizadas, tema del framework) y de las consultas de medios CSS calculadas del sitio (a menos que la intención enumere anchos). Capture a 320, en cada punto de quiebre menos uno y en el punto de quiebre, y en un ancho de escritorio grande.
- Por ancho: captura de pantalla de página completa, DOM, resultados de axe-core (etiquetas wcag2a, wcag2aa, wcag21aa, wcag22aa), verificación de desbordamiento, verificación de geometría de destino, esqueleto estructural (puntos de referencia, encabezados, clústeres interactivos con cuadros delimitadores).
- Registre el estado de la captura (banner de consentimiento, autenticación, variante) y SHA-256 de cada archivo en
manifest.json. - Agregue un evento
capture.completed.
Fase 3 — Medición
Ejecute verificaciones automatizadas y asistidas. Los resultados automatizados se convierten directamente en hallazgos. Los resultados asistidos se convierten en hallazgos con mode: assisted y triage: null; observe qué excepción (espaciado, en línea, equivalente, esencial, tabla de datos) podría aplicarse.
Mapeo de fuente. Para cada hallazgo, busque en el clon la fuente del elemento (su texto, nombres de clase, nombre de componente o atributos de datos) y registre source: {file, line, confidence}. Esto es de mejor esfuerzo: use confidence: low para una suposición y omita source en lugar de reclamar una ubicación que no encontró. Estas son pistas para el implementador, no instrucciones.
Fase 4 — Evaluación
Ejecute el pase heurístico. Para cada hallazgo registre:
rule_id, localizador, ruta de evidencia y hash- severidad 0–4 (Nielsen: frecuencia, impacto, persistencia)
- confianza (alta/media/baja)
scope: uno desingle-section,cross-section,component,interaction- una oración sobre lo que muestra la evidencia
Guía de alcance:
single-section: el problema está dentro de un bloque de una página.cross-section: el problema solo aparece a través de bloques, páginas o anchos (orden de prioridad versus orden visual, patrones inconsistentes, navegación que cambia entre páginas). Búsquelos deliberadamente; a menudo son los más trascendentales y son los más fáciles de pasar por alto al revisar una sección a la vez.component: un elemento reutilizable se comporta o se ve de manera inconsistente dondequiera que aparezca.interaction: el problema está en un estado, flujo o comportamiento en lugar de un diseño estático.
Para páginas largas, evalúe cada sección desde su propia captura de pantalla y observe las posiciones y; luego haga un pase separado para hallazgos entre secciones. Incluya solo reglas con evidencia visible suficiente; omita las reglas que no se pueden evaluar a partir de la captura en lugar de adivinar. Trátese como un evaluador; dígalo en el resumen de hallazgos.
Puerta G2 — Clasificación
Presente los hallazgos agrupados por severidad, luego por página, como una tabla: ID, regla, etiqueta, alcance, página/ancho, severidad, confianza, evidencia de una línea. Pida al usuario que acepte, rechace o re-puntúe. Registre cada llamada de clasificación como un evento del libro de decisiones atribuido al usuario. Solo los hallazgos aceptados avanzan.
Fase 5 — Línea base de Figma (Puerta G3)
- Capture pantallas actuales en la página
00 As-Isa través degenerate_figma_design(ohtml_to_figma), un marco por ancho capturado que muestre un cambio estructural. - Construya wireframes estructurales actuales en la página
01 As-Is Wireframesa partir deskeleton.json, usando el kit de wireframes del archivo sisearch_design_systemencuentra uno. - Entregue: pida al usuario que bloquee
00 As-Isy guarde una versión nombrada tituladabaseline R-…, luego déle su ID de versión. Usted no puede guardar versiones por sí mismo. - Registre el ID como
version_before. No más escrituras hasta que lo tenga.
Fase 6 — Proponer
- Agrupe los hallazgos aceptados en decisiones. Cada
D-NNNN.json: título, ID de hallazgos, contexto, propuesta, alternativas (si las hay), puntuación de impacto (1–3 por costo, riesgo y valor), estadoproposed, registro de quién y cuándo. - Por decisión, genere opciones de wireframe futuro en la página
02 To-Be Wireframes. Use una convención de nombres de marco que incluya el ancho y el ID de decisión. - Anote las diferencias en el archivo de Figma usando
addAnnotationCategoryAsynccon un ID de categoría que coincida con el prefijo de hallazgo. No use anotaciones por decisión; use una categoría de anotaciónfindingy etiquete con⟦D-0007⟧. - Registre cada llamada de
use_figmacon un recibo de escritura que incluya los ID de nodo creados o mutados. - Escriba un resumen de decisión en el libro de decisiones: la propuesta, cualquier alternativa y la puntuación de impacto.
Puerta G4 — Aprobación
- No negociable 1 aplica: nunca escriba archivos en
audit/approvals/. Esto es para la interacción humana directa. - Presente un resumen de las decisiones propuestas con puntuaciones de impacto. El humano ejecuta
fwd approve|reject|deferpor sí mismo. - Después de que el humano haya actuado, verifique que el archivo de aprobación coincida con el evento del libro de decisiones. Registre un evento
approval.verifiedcon el hash deapprovals/.
Fase 7 — Resumen de implementación
- Por decisión aprobada, genere
audit/handoff/D-NNNN.md:- Objetivo: la misma oración resumida de la decisión.
- Archivos fuente citados de los hallazgos.
- Estado actual (texto, diseño, estado) del DOM capturado.
- Cambio requerido: un cambio por breve; describa el comportamiento final deseado, no una receta de código.
- Condiciones de verificación: el implementador ejecuta
fwd recapturepara probar su trabajo contra su propia rama.
- Genere o actualice
audit/handoff/README.mdcon las reglas de estilo y accesibilidad del proyecto. - Escriba un resumen de la ejecución.
Resumen de puertas
- G0 —
intent.yamlcompleto y confirmado. - G1 — Reglas y esquemas confirmados.
- G2 — Hallazgos clasificados (aceptados/rechazados/re-puntuados).
- G3 — Versión base guardada por el humano.
- G4 — Decisiones aprobadas/rechazadas/diferidas.
- G5 — Resúmenes de implementación escritos.
Verificación del libro de decisiones
Después de que el humano ejecute fwd ledger verify, verifique la cadena de hash del libro de decisiones (audit/ledger.jsonl), confirme que cada archivo en audit/approvals/ esté referenciado por un evento human.approve en el libro de decisiones con un hash que coincida y que todos los eventos estén encadenados correctamente. Informe cualquier brecha sin detener el flujo.
Esquemas de registro
Hallazgo (schema/finding.json)
{
"$schema": "...",
"type": "object",
"properties": {
"id": {"type": "string", "pattern": "^F-[A-Z0-9-]+$"},
"rule_id": {"type": "string"},
"label": {"type": "string", "enum": ["failure", "concern", "deviation"]},
"severity": {"type": "integer", "minimum": 0, "maximum": 4},
"confidence": {"type": "string", "enum": ["high", "medium", "low"]},
"scope": {"type": "string", "enum": ["single-section", "cross-section", "component", "interaction"]},
"mode": {"type": "string", "enum": ["automated", "assisted", "manual"]},
"triage": {"type": ["string", "null"], "enum": ["accepted", "rejected", "rescored", null]},
"pages": {"type": "array", "items": {"type": "string"}},
"widths": {"type": "array", "items": {"type": "number"}},
"evidence": {
"type": "object",
"properties": {
"screenshot_path": {"type": "string"},
"dom_path": {"type": "string"},
"axe_path": {"type": "string"},
"hash": {"type": "string"}
},
"required": ["hash"]
},
"locator": {
"type": "object",
"properties": {
"css_selector": {"type": "string"},
"xpath": {"type": "string"},
"node_id": {"type": "integer"},
"label": {"type": "string"}
}
},
"source": {
"type": "object",
"properties": {
"file": {"type": "string"},
"line": {"type": "integer"},
"confidence": {"type": "string", "enum": ["high", "medium", "low"]}
}
},
"evidence_summary": {"type": "string"},
"notes": {"type": "string"}
},
"required": ["id", "rule_id", "label", "severity", "confidence", "scope", "mode", "evidence", "evidence_summary"]
}
Decisión (schema/decision.json)
{
"$schema": "...",
"type": "object",
"properties": {
"id": {"type": "string", "pattern": "^D-[0-9]{4}$"},
"title": {"type": "string"},
"finding_ids": {"type": "array", "items": {"type": "string"}},
"context": {"type": "string"},
"proposal": {
"type": "object",
"properties": {
"description": {"type": "string"},
"figma_node_ids": {"type": "array", "items": {"type": "string"}},
"rationale": {"type": "string"}
},
"required": ["description", "rationale"]
},
"alternatives": {
"type": "array",
"items": {
"type": "object",
"properties": {
"description": {"type": "string"},
"rationale": {"type": "string"}
}
}
},
"impact_score": {
"type": "object",
"properties": {
"cost": {"type": "integer", "minimum": 1, "maximum": 3},
"risk": {"type": "integer", "minimum": 1, "maximum": 3},
"value": {"type": "integer", "minimum": 1, "maximum": 3}
},
"required": ["cost", "risk", "value"]
},
"state": {"type": "string", "enum": ["proposed", "approved", "rejected", "deferred", "implemented"]},
"created_by": {"type": "string"},
"created_at": {"type": "string", "format": "date-time"}
},
"required": ["id", "title", "finding_ids", "context", "proposal", "impact_score", "state", "created_by", "created_at"]
}
Aprobación (schema/approval.json)
{
"$schema": "...",
"type": "object",
"properties": {
"id": {"type": "string", "pattern": "^A-[0-9]{4}$"},
"decision_id": {"type": "string", "pattern": "^D-[0-9]{4}$"},
"state": {"type": "string", "enum": ["approved", "rejected", "deferred"]},
"approved_by": {"type": "string"},
"approved_at": {"type": "string", "format": "date-time"},
"notes": {"type": "string"}
},
"required": ["id", "decision_id", "state", "approved_by", "approved_at"]
}
Evento del libro de decisiones (schema/ledger_event.json)
{
"$schema": "...",
"type": "object",
"properties": {
"event_id": {"type": "string"},
"type": {
"type": "string",
"enum": [
"schema.confirmed",
"capture.completed",
"finding.created",
"triage.recorded",
"decision.proposed",
"human.approve",
"approval.verified",
"figma.write",
"handoff.generated",
"run.summary"
]
},
"run_id": {"type": "string"},
"timestamp": {"type": "string", "format": "date-time"},
"actor": {"type": "string"},
"data": {"type": "object"},
"previous_hash": {"type": "string"},
"hash": {"type": "string"}
},
"required": ["event_id", "type", "run_id", "timestamp", "actor", "data", "previous_hash", "hash"]
}
Libro de reglas (audit/rulebook/rules.yaml)
Cada regla tiene:
id: único (ej.WCAG-1-1-1,H-CONSISTENCY-1,HOUSE-BUTTON-MD)tier:normative,heuristic,housesource: estándar (ej.WCAG 2.2,Nielsen,proyecto)title: nombre legible por humanosdescription: criterio completomode:automated,assisted,manualscope: alcance sugeridoexceptions: lista de excepciones aplicables (spacing,inline,equivalent,essential,data_table)examples: ejemplos de aprobado/fallo
Manejo del servidor local
- Para proyectos Vite, el servidor de desarrollo usa el puerto Vite del proyecto, no
fwd. - Si el proyecto necesita un
.envo secretos, pregunte al usuario o use el archivo de entorno auto-contenido del proyecto; nunca los invente. - No se requieren cambios en
package.json. Use la configuración dedev_command.
Manejo de errores en toda la habilidad
- Si un paso falla (servidor no se inicia, Figma devuelve un error, captura falla), registre el error en el libro de decisiones, informe al usuario y deténgase. No proceda a pasos dependientes.
- Si una llamada
use_figmadevuelve un error, vuelva a intentar hasta 2 veces con un retraso de 5 segundos. Si aún falla, registre el error, marquecapabilities.jsony continúe con el modo solo JSON. - Para proyectos no estándar (no Vite, no Next, no React), pregunte al usuario por el comando de desarrollo y la URL. No adivine.
Convenciones de nomenclatura de Figma
- Páginas:
00 Kit & Legend,01 As-Is Wireframes,02 To-Be Wireframes - Marcos en
01 As-Is Wireframes:{page} / {width}px / as-is - Marcos en
02 To-Be Wireframes:{page} / {width}px / to-be / {decision_id} - Leyenda: un marco que explica las anotaciones y convenciones de color.
Consideraciones de rendimiento
- Limite las capturas a un máximo de 6 anchos (320, punto de quiebre móvil, punto de quiebre tableta, escritorio, más dos derivados).
- Para páginas de más de 2000 nodos DOM, el DOM se trunca en el nodo de nivel superior más grande para evitar sobrecargar Figma.
- Las ejecuciones se limitan a 3 rutas por defecto. Solicite rutas adicionales al usuario.
Apéndice: Glosario
| Término | Definición |
|---|---|
| Hallazgo automático | Un hallazgo producido por una ejecución de axe-core o verificación de desbordamiento. |
| Hallazgo asistido | Un hallazgo donde el evaluador marcó una regla, pero el sistema ayudó con la localización. |
| Hallazgo manual | Un hallazgo donde el evaluador identificó y marcó todo de forma independiente (no utilizado en este flujo). |
| Decisión | Un grupo de hallazgos aceptados con una propuesta para abordarlos. |
| Resumen de implementación | Una especificación para que Claude Code/Codex implemente una sola decisión en el código fuente. |
| Punto de quiebre | Un ancho de ventana gráfica donde el diseño cambia debido a una consulta de medios. |