Criteria
Turns several loose questions into a one-file HTML form with a progress bar and a button that copies every answer at once.
Cuándo se usa
When you need to decide several different things at once and would rather fill in a form than answer them one by one.
SKILL.md
# Criteria
For when several different kinds of questions need asking at once (not just "pick option 2"),
and whoever is answering would rather fill them in with a keyboard and mouse and hand back
**the whole block in one go**, instead of answering each question one at a time in the chat.
It does not replace other ways of asking, it completes them:
- A back-and-forth **in the chat**, question by question, is still better when each answer
needs reasoning through before the next question can even be written.
- A **Markdown** questionnaire is still better for a third party (a client, a collaborator)
who has no coding agent installed and can only read plain text.
- **Criteria** is a form in the **browser**, for whoever already has a coding agent in front
of them, when the questions can all be asked at once and dictating or typing them one by one
is what is left over.
## Process
### 1. Gather the questions
Whatever the decision needs. For each one, pick its type:
- `texto` (text) - a short line (a name, a number).
- `parrafo` (paragraph) - several lines (an explanation, some context).
- `opcion` (single choice) - pick one from a list. The "Other:" free-text option is always
added on its own, nothing needs to ask for it.
- `multiple` (multiple choice) - pick several from a list. Same always-on "Other:".
- `escala` (scale) - rate on a range (0-10, 1-5), with labels at the ends if they help.
One question per decision: if a question carries two things inside it, that is two questions.
**Before treating the list as final, run every question through two filters, no exceptions:**
- **Is it actually needed?** If the answer would not change anything done afterward, the
question does not belong. Do not ask to pad out the form or "just in case": every extra
question wastes the time of whoever has to answer it.
- **Does it read clearly the first time?** A short sentence, one single idea, no jargon the
person answering has no reason to know. If a question needs context to make sense, that
context goes in `ayuda` (see below), never crammed into the title until it turns long or
technical.
Go through the whole list with these two filters before moving to step 2: drop every question
that would not change anything, and rewrite every question that needs a second read to figure
out what it is even asking. A forty-question form where half a dozen are noise is not more
thorough than a thirty-four-question one, it is just longer and more tiring to fill in.
Each option of `opcion` or `multiple` can be plain text, or carry more: `{ texto, ayuda?,
nota? }`, where `ayuda` is a short line underneath (why that option matters) and `nota` is a
short badge next to it (for example `"recommended"`). The whole list does not need one format:
a question can mix plain options with others that carry help text or a badge.
If the questionnaire is long and its questions fall into clear groups (like "the pricing ladder",
"mobile", "money"), any question accepts an optional `seccion: "Group title"`. As soon as it
changes from one question to the next, a header with an automatic letter (A, B, C...) is inserted
on its own before that card. It is purely visual grouping: the P1, P2... numbering and the answer
format do not change.
**How to tell `opcion` from `multiple` apart, without guessing:** ask whether two of the
answers could be true at once. "How much does it cost a month?" is `opcion`, because one price
rules out the rest. "What justifies paying for this?" or "what should the app do?" are almost
always `multiple`, because several reasons or several features can be true at the same time. By
default, when in doubt, `multiple` costs less than forcing a single answer onto something that
is not one: it errs on letting people pick too much, not too little.
**This is not negotiable, not even when the questionnaire needs more design than the template
ships with.** The title, the help text and the badge above already cover the most common case of
"I need to explain each option and mark the recommended one". If something still genuinely does
not fit (a full comparison table, a large warning banner), a richer design can be hand-built, but
the behaviour does not get negotiated away: every single-choice question carries its free-text
"Other:", and every question where two answers could both be true uses checkboxes, not radios.
A hand-built questionnaire without this is not a simplified version of Criteria, it is a broken
questionnaire that looks like one.
### 2. Match the palette to the project you are working in
This is not optional: the questionnaire **does not always look the same**, it looks like the
conversation it was asked in. Before generating the file, check whether the active project has
its own design system (an `App.css`, a `globals.css`, Tailwind tokens, theme variables already
defined) and find its colors, its border radii and its typeface. If it has one, replace the
values in the block marked `PALETA` (the `--bg`, `--text`, `--accent`, `--ok`, `--warn`,
`--bad`, `--radio`, `font-family`...) with its own. The `ESTRUCTURA` block below is never
touched: it always uses `var(--something)`, so it inherits the skin change on its own. If the
project has no identifiable design system of its own (a task with no website, or a repo with no
frontend), the template's neutral default palette is kept, already checked for WCAG 2.1
contrast.
### 3. Generate the file, without reading the whole template
`references/plantilla.html` never changes between one questionnaire and the next except in
three spots, so there is no need to load it into context to touch them: copy the file as-is
(`cp` / `Copy-Item`, never inside the project's own code, it is a working file) to
`criteria-<topic>.html` in a temporary session folder, and substitute the three placeholders
with a single-pass command that reads and writes the file without its content ever passing
through the model:
```bash
python3 - "<path-to-copy>" <<'EOF'
import json, sys
p = sys.argv[1]
html = open(p, encoding="utf-8").read()
html = html.replace("__TITULO__", "...") # what is being decided, in four words
html = html.replace("__SUBTITULO__", "...") # one sentence: what this is for and what happens when it's done
html = html.replace("__PREGUNTAS_JSON__", json.dumps([
# ...the questions, using the shapes from step 1...
], ensure_ascii=False))
open(p, "w", encoding="utf-8").write(html)
EOF
```
In PowerShell, the same thing with `-replace` over `Get-Content -Raw` and
`Set-Content -Encoding utf8`. If step 2 calls for a different palette, those same commands add
more `-replace`/`.replace()` calls over the `PALETA` block's values; the `ESTRUCTURA` block is
never touched. The read-and-edit-file tools are not used on `plantilla.html` or on the copy:
there is no need to, and loading a hundreds-of-lines HTML file into context just to change three
values is spending tokens for nothing.
### 4. Open it yourself
Open the file in the browser on your own (on Windows, `Start-Process` on the path; on macOS,
`open`; on Linux, `xdg-open`), without asking permission and without just leaving the path
written down for someone else to open by hand. In the chat, one line: what is being asked and
that the block should be pasted back once it is done. Never repeat the question list in the
terminal: whoever has to read and answer it already has it in front of them, in the form.
### 5. When the pasted block comes back
It arrives in the shape `P1. <question>\n→ <answer>`. The ones saying `(no answer)` are the
ones left blank: they are not made up, they get asked again in the chat if the decision needs
them to close, or set aside if they are not blocking. With the rest, build the prompt or make
the decision the questionnaire was for.
## What the template already has, and why it stays untouched
- **Zero CDN, one file.** It has to look the same with no internet connection.
- **System theme, no toggle.** `prefers-color-scheme` decides light or dark on its own: this is
not a catalog that needs checking in both themes at once, it is a single-use form.
- **The default palette** (`--bg`, `--panel`, `--accent`...) is the one used in step 2 when the
project has none of its own, with contrast already measured against WCAG 2.1. If a hex value
is ever touched, it gets measured again, never adjusted by eye.
- **A progress bar up top**, always visible while scrolling (`position: sticky`), with the
answered count next to it. Not just a number lost at the bottom of the page.
- **"Other:" always present** on every single- or multiple-choice question, with its free-text
slot. It is built into the template, not something to remember to ask for. Typing there marks
it on its own, no need to click its checkbox first, and the pick survives a page reload just
like the rest of the answers.
- **Real multi-select, and it says so.** `multiple` uses checkboxes, not radios: more than one
can be picked at once, the final block joins them with commas, and the question carries its
own "pick one or several" badge so it is never mistaken for single choice.
- **Options with help text and a badge**, for when the plain list is not enough: any option can
carry a short explanation underneath and a short badge next to it (like "recommended"), with
no hand-written HTML and no need to leave the template.
- **Sections with an automatic letter**, for long questionnaires: grouping questions under a
`seccion` does not change their numbering or the answer format, it just adds a visual divider.
- **Nothing is required.** A form where everything is mandatory does not get filled in quickly
by anyone; the button still copies with blank questions, marked as such.
- **Copying with a safety net.** It tries `navigator.clipboard`, and if the browser blocks it
(which happens sometimes on a local `file://` page), it leaves the text selected in a visible
box so a manual Ctrl+C still works.
- **Autosaved to `localStorage`.** If the tab gets closed by accident halfway through, whatever
was already typed is still there when the same file is reopened.
## When NOT to use this
If there is only one thing to decide, or if the questions depend on each other (the second one
cannot be written until the first is answered), that is a back-and-forth in the chat, not
Criteria: here every question gets asked at once, in a single pass.