# Experiment 01 · Settings page · with vs without ihumane

**Date:** 2026-11-06 · **Module:** `modules/ui-design` v0.1 · **Model:** same for both agents

## Setup

Two fresh agents got the identical task: build a settings page for "Tally", a
small-team task app (profile, notifications, team members, billing), plain
HTML/CSS/JS, "make it clean and modern", and no one available to answer
questions. The only difference: one was told to read and follow the ihumane UI
design module first.

- Without module: `baseline/`
- With module: `ihumane/`

## Result in one line

**On screen, both look good. Underneath, they're very different.** That's
exactly the problem ihumane is meant to solve.

## The inside (measured)

| | Without ihumane | With ihumane |
|---|---|---|
| Raw colours typed outside the token file | **41** | **0** |
| Different px values used outside tokens | **48** | **3** (all 1px/4px/16px with a reason) |
| Different font-size declarations | **15** | **5** |
| Inline styles | 5 | 0 |
| `!important` | 4 | 0 |
| Separate token file | no (tokens mixed in) | yes (`tokens.css`) |
| `DESIGN.md` for the next agent | no | yes |
| "Saving…" / loading states | none found | on every save |
| Undo instead of "Are you sure?" | remove only | remove, role change, revoke invite |
| Inputs without a label | 0 | 1 (hidden photo file input) |

## The surface (looked at)

- **Without:** a polished, typical SaaS look with an indigo/purple accent, a
  purple gradient, three side-by-side plan cards and colourful avatar
  circles. It looks good, but it's the default AI look the module warns
  about. It also added extras nobody asked for (member search, a password
  strength meter, quiet hours).
- **With:** quieter and more specific. One green accent, one primary action
  per section, borders instead of shadows, and copy that shows the maths
  ("$8.00 per member × 6 = $48.00 a month"). It also showed admin vs member
  views and an empty "new workspace" state.

## What the module did badly

- **Cost:** the module agent took about **2× the time** (13 min vs 6 min) and
  **~1.7× the tokens**. Reading 8 files and running every check adds up.
- **A missed label:** the hidden photo file input has no accessible label.
  The version without the module got this right.
- **A copy mismatch:** invoice buttons say "PDF" but download a plain-text
  file. The writer lens should have caught this.
- **Phone tabs:** at phone width, "Plan & billing" is cut off until you
  scroll the tab row. The agent reported this itself, which is good, but
  didn't fix it.

## Designer review (Aman)

| # | Found by the designer | Cause | Status |
|---|---|---|---|
| 1 | Members card: title cramped, touching the divider; top and bottom padding not equal | A spacing correction meant for normal cards (`.panel__title + * { margin-top: -12px }`) also applied to list cards and cancelled the 12px gap: 24px above the title, **0px** below | Fixed: list cards now have no padding of their own; header and rows each get 16px top and bottom (measured 18 / 17 around the text, the 1px is the font's own spacing) |
| 2 | Pending invites: same | Same rule | Fixed by the same change |
| 3 | Invoices: same | Same rule | Fixed by the same change (18 / 18) |
| 4 | "What can members and admins do?" looks like a link (accent colour, underline on hover), so the designer expected a dialog or side panel. It expanded inline instead and pushed the page down. "UI should not shift" unless it's a proper accordion. | The agent used the right element (`<details>`) but restyled it to "look clean": removed the arrow and made it look like a link | Fixed: now an accordion with a soft filled row, a chevron that turns, and the content opening inside the same box. Keyboard works. Spacing check passes (13 / 12). |
| 5 | After sending an invite, the confirmation text sat beside the button; with a long email it wrapped and pushed the button to a new line. Should be a toast (or a dialog with next steps), so nothing shifts. | Messages went in a `<p>` next to the button, in a footer allowed to wrap. Same pattern in Profile and Notifications. | Fixed in all three forms: successes are toasts (the invite toast has Undo); the footer never wraps, and errors wrap in their own column. Measured: the button stays in the same place through idle, loading, success and a long offline error, at 1280 and 375. |
| 6 | Loading only showed "Sending…" text; no visual sign of activity. Should have a spinner. | The busy state just swapped the label text, which also changed the button's width (it shrank 15px and shifted). | Fixed: spinner + short label stacked over the invisible original, so every button keeps its exact size (measured on all 4 busy buttons). Small buttons show the spinner alone. |
| 7 | Toast vs confirmation dialog: both are valid, so the agent should have asked the human which they wanted instead of picking silently. | The module told agents to put success in a toast, as if there were only one right answer. | Module now treats it as a "pattern fork": ask once with options and a recommendation, and record the answer in `DESIGN.md`. Asked: the designer chose **toast everywhere** (already built), now recorded. |
| 8 | "Back to tasks" sat at the right end of the global header. Back links belong on the page, on the left: "we are going back, not forward." | The agent filled empty header space on the right. | Fixed: back link top-left of the page, on its own row above both columns so "Settings" and "Team members" still line up (both at 162px); the arrow's stroke lines up with the title edge. Header now holds only logo and workspace. Checked desktop dark and phone light. |
| 9 | "Back to tasks" was underlined all the time. On this kind of link, the underline should only appear on hover. | One link style for everything, always underlined. The module's own rule said "a link: underline", which was too blunt. | Fixed: standalone links have no underline at rest, and underline on hover and keyboard focus. Links inside a sentence (the billing email) stay underlined, because colour alone isn't enough for colour-blind readers. |
| 10 | Plan & billing gave too little to decide with. The version **without** the module showed all plans side by side, seats used against the limit, and the next payment and date, and the designer preferred it. | The module itself: "show only needed choices" (Hick's law), "avoid three identical cards" and "remove what wasn't asked for" together pushed the agent to strip the screen to one upsell. | Rebuilt: an at-a-glance summary (current plan and maths; next payment, date and card; a seats bar "8 of 20" that turns amber near the limit and red when full, with words saying so) plus all three plans side by side, each priced **for this team** ("For your 6 people: $84.00 a month"), with one recommended button and plain reasons where a switch is blocked. Upgrades from any card. Checked desktop light, phone dark, new Free workspace, nearly full and full, and after upgrading. |

**Why the module missed it:** the agent did look at screenshots, but a 0px
gap is nearly invisible in one. The module told it to *look*; it needed to
tell it to *measure*.

**What changed in the module (v0.2):**
- New rule `2-system.md` §2.7: equal padding above and below, never closer
  than 8px to a line, no negative-margin corrections.
- New runnable check `checks/spacing.js`. Tested: on the old styles it flags
  all three cards; on the fixed styles it finds nothing in Profile, Team or
  Billing. One known false alarm: a Notifications table cell that is
  correctly top-aligned with a two-line label.
- Review lens updated: "measure, don't eyeball".
- New rules `3-humans.md` A5 "How a control looks is a promise about what
  it does" (a table of what each kind of control must look like) and A6
  "Don't move what people are looking at".
- New runnable check `checks/affordance.js`. Tested: on the old version it
  flags the roles link twice (underline on hover; no arrow); on the fixed
  version it finds nothing. It also finds nothing on the version built
  without the module.
- Spacing check tuned after running it on the version built without the
  module: it no longer flags compact pills, badges and buttons.
- Review lens updated: "predict, then click".
- New rules `3-humans.md` C2 (how a loading button must look) and C2b
  "Put feedback where it won't move anything" (a table of where each kind
  of message goes).
- New runnable check `checks/stability.js`: do an action, measure whether
  anything moved. Tested: on the old version it reports "Send invites"
  shrinking 15px while loading and jumping 54px down after; on the fixed
  version, "Nothing moved."
- Review lens updated: "act, then measure".
- New section `1-brief.md` Step 3b "Pattern choices: ask, don't pick": a
  table of common forks (toast vs dialog, undo vs confirm, autosave vs save
  button, tabs vs pages, one page vs steps, inline vs disclosure, error
  placement), when each option fits, and the rule to record answers in
  `DESIGN.md` so each fork is asked once per product.
- New rule `3-humans.md` B2b "Direction and place follow meaning": back
  left, forward right, Back before Next, page navigation in the page and
  not the global header, back link on a row above all columns.
- `checks/affordance.js` extended: flags back controls in the wrong half of
  the screen, in the global header, or after Next. Tested: flags both
  problems on the old version; nothing on the fixed version.
- `3-humans.md` A5 refined: standalone links underline on hover/focus only;
  links inside a sentence are always underlined.
- `checks/affordance.js` extended: flags standalone links underlined at rest
  and in-sentence links with no underline. Tested both ways (forced the
  billing email visible, then removed its underline: flagged). Fixed a false
  alarm on off-screen "skip to content" links.
- New rule `3-humans.md` B5 "Give people what they need to decide, on the
  screen where they decide": seven things every decision screen shows at a
  glance. B1 (Hick's law) and the cliché list now say explicitly that they
  don't apply to option comparisons. Review lens: "can they decide from this
  screen alone?"

**Note:** this is the first finding where the version without the module
did better, and the cause was the module over-correcting. Rules that
protect attention need a stated limit, or agents apply them where they hurt.

**Follow-up (human's choice):** added a monthly/annual toggle (assumed 20%
off annual). Every card shows the team's yearly total and the saving;
switching period takes effect at renewal, with a confirm dialog and Undo.
Built to the module's rules from the start: the toggle doesn't change
weight when selected (verified: it doesn't move), it works with arrow keys,
and the checks are clean.

**Lesson for ihumane:** the designer's eye found a problem in seconds that
the agent's process missed. Each finding like this becomes a rule and,
where possible, a check, so that no agent repeats it.

## Proposed module fixes (still open)

1. Add to `5-review.md` (writer lens): "A label must match what actually
   happens (a 'PDF' button must give a PDF)."
2. Add to `3-humans.md` (accessibility): hidden inputs triggered by a custom
   button still need a label.
3. Add a "fix, don't just report" rule: known layout problems found in
   review get fixed unless there's a reason not to.
4. Make a short **core** version (one file, about 150 lines) for small tasks,
   to cut the time and token cost. Keep the full set for bigger work.

## Caveats

One task, one run each. That shows a direction, not proof. The measurements
are simple pattern counts, and a designer's review of both results is the
real test.
