# Bar-Model Solution Authoring (Singapore Method)

How to author solution HTML for word problems. Every word-problem
solution draws the model FIRST, then derives the working FROM the model.
Never present bare arithmetic for a problem a bar model can represent.

## 0. Model-first policy (non-negotiable)

- The **model is the FIRST and primary method for any problem that has a model
  structure** (comparison, part–whole, ratio, before–after).
- **P1–P2 may have no model-worthy questions** — most are simple one- or two-step
  arithmetic with no bar model. **Don't force a model** where the question doesn't
  warrant one; plain stepwise working is correct there. Bar models become standard
  from **P3** onwards.
- **P1–P4: model only (where a model applies).** No algebra, no `x`, no
  guess-and-check — ever.
- **P5–P6:** after the *complete* model solution (including the check line),
  an **optional** second section headed **"Alternative method (algebra)"** may
  show the algebraic route. It must:
  - arrive at the **same answer**,
  - be **visibly secondary** — placed *after* the check line and clearly
    separated (own heading),
  - **never** appear for a P1–P4 question.
- The model solution must remain **complete and self-sufficient without** the
  algebra section — the algebra is an addendum, never a dependency.

## 1. Choose the model type

| Problem pattern | Model | Structure |
|---|---|---|
| Total split into parts ("altogether", "in all") | Part–whole | One bar divided into parts; whole bracketed |
| "More than / fewer than / difference" | Comparison | Two left-aligned bars; difference bracketed |
| Two scenarios sharing a common item (this doc's example) | Comparison (elimination) | Two bars, identical segments aligned; subtract |
| "3 times as many" | Equal units | One bar = 1 unit; other = n identical units |
| "Gave away / received / transferred" | Before–after | Two bars, same subject, before and after states |
| Ratio / fraction of a quantity | Units | Bar cut into equal units; label units, not values |

## 2. Drawing rules

- Two bars comparing quantities are ALWAYS left-aligned at x=20.
- Identical items get identical segment widths across both bars
  (an apple in bar 1 = same width as an apple in bar 2).
- Equal units within a bar are EQUAL width — non-negotiable; the visual
  equality IS the mathematics.
- Schematic, not to scale, EXCEPT unit equality above.
- A shared/common segment (the eliminated item) is drawn first, leftmost.
- The difference region gets: a dashed vertical alignment line (#4A6488,
  1.5px, dasharray 5 5) at the shorter bar's end, plus a square bracket
  under the bars with the subtraction written on it.
- Unknowns are labelled with "?" inside the segment.
- Totals sit to the RIGHT of each bar, never on top of segments.

## 3. Visual style (AGS Math Graphics Library v2.0)

Palette is closed: Crimson #960000, Gold #BF9237, Lime #88C808,
Steel Blue #4A6488, Dusty Rose #D0ACAC, Ink #2A2A2A (outlines + text only).
**No other colours, ever — including white.**

- **Segment fills:** Lime, Dusty Rose, Gold only (all take Ink text legibly).
  One colour per item type.
- **Crimson:** emphasis only — final answers, key values in working.
  Never a segment fill (Ink text fails on it).
- **Steel Blue:** annotation only — dashed alignment lines, brackets, check line.
- **All segment text and outlines:** Ink #2A2A2A.
- Outlines: 2px. Fills: flat brand colours only, NO gradients.
- Container: 2px Dusty Rose #D0ACAC border, border-radius 8px, 14px padding.
- SVG: width="100%", viewBox 640 wide, height fits content + 20px.
  Segments 44px tall, rx=4. Text 15px/600 in segments, 14px annotations.
  Every segment label uses text-anchor="middle" dominant-baseline="central".
- Include role="img" and aria-label describing the model.

## 4. Working format (after the model)

1. One sentence stating what the model shows ("Both bars have the same
   watermelon, so the difference is 3 apples.").
2. Steps in unitary form, one transformation per line:
   "3 units → 0.60 kg", "1 unit → 0.60 ÷ 3 = 0.2 kg".
   Use the arrow (→) convention, not equals, when mapping units to values.
3. Answer in bold WITH units (Crimson emphasis).
4. Check line in Steel Blue: substitute back into the original statement.

## 5. Language rules

- "unit(s)" is the canonical word once the model abstracts items.
- Never introduce algebra (x, simultaneous equations) in P1–P4 solutions —
  the model replaces it. For P5–P6 it is allowed ONLY as the optional,
  clearly-separated secondary section defined in §0 (after the model + check).
- Each working line must be readable off the diagram; if a step can't be
  pointed to in the model, redraw the model.

## 6b. Given vs derived (non-negotiable)

Every numeric label in the model is one of two kinds, and the reader must be
able to tell them apart at a glance:

- **Given** — a value stated in the problem (e.g. "Tim has $56.90",
  "$7.45 more"). Render **plain**.
- **Derived** — a value you worked out (e.g. Kelly's $49.45, the total
  $106.35). Render **italic with a steel-blue dotted underline**.

Rules:
- Show the givens *as drawn quantities*, not just in the working. If the
  problem gives a total, draw that total (don't replace it with a derived
  breakdown). Example: for "Tim has $56.90, $7.45 more than Kelly", Tim's
  bar is one segment labelled $56.90 (given); Kelly's bar is the derived
  $49.45; the $7.45 gap is given; the total bracket is the derived answer.
- Unit-count labels ("1", "2", "3"…) and "?" are structural, not values —
  leave them plain.
- The final answer is still Crimson emphasis in the working; in the diagram
  it is a derived value (italic + dotted underline).
- Every solution carries a one-line legend (auto-added by `bm_html`)
  stating "plain = given · italic underlined = worked out".

In code (`_work_barmodels/lib.php`): pass `$derived = true` as the last
argument to `seg`, `vbrace`, or `hbrace` to mark a label as worked-out.

## 7. Fractions and entity encoding (non-negotiable)

A vulgar-fraction **glyph** exists for only a handful of fractions (½ ⅓ ⅔ ¼ ¾
⅕ ⅖ ⅗ ⅘ ⅙ ⅛ …). For every other fraction — 7/9, 2/11, 3/5, 7/10 — there is
**no glyph**, and writing one anyway (as unicode `⅘`, numeric ref `&#8536;`,
or named entity `&frac45;`) silently renders the **wrong value**. This passed
a numeric answer-key check while teaching a child "⅘ of 66 = 12" — the worst
class of bug. It is **banned**:

- NEVER write a fraction as a glyph, `&#85xx;` numeric ref, or `&fracNN;`
  entity. (`&frac45;` etc. are real entities → wrong glyph; `&frac49;` isn't
  an entity at all → renders literally.)
- In **HTML** (intro, working, check): use `frac($a,$b)` →
  `<sup>a</sup>&frasl;<sub>b</sub>`. Works for any a/b.
- In an **SVG `<text>`** label: use `sfrac($a,$b)` → plain `a/b` (sup/sub do
  not render inside SVG text).
- After authoring, grep the output for vulgar-fraction glyphs / `&#85` /
  `&frac` and confirm zero hits.

Other entities: `&minus; &times; &divide; &rarr; &rArr; &mdash;` are standard
and render under flutter_html — use them freely and consistently. The single
fraction convention above is what must not drift between authors.

## 8. Solid = quantity, dashed = gap (non-negotiable)

A filled segment means "this much of the quantity exists." A **gap/difference**
between two bars is NOT part of either quantity and must NOT be drawn as a solid
filled segment — a child reads a solid `[ $20 ]` on Ken's bar as Ken owning a
separate $20 part.

- **Quantity** (the bar, or a piece that genuinely belongs to it, e.g. "last
  year = this year + 3 more books"): solid fill — `seg()`.
- **Gap / difference / "how much more"** (the distance between two left-aligned
  bars): dashed outline, no fill — `gapseg()` — or show it with a brace
  (`hbrace`) / dashed alignment line (`dline`) instead. Never a solid segment.

Test: if the number is the size of the space *between* two bars, it is a gap →
`gapseg`/brace. If it is part of one bar's own total, it is a quantity → `seg`.

## 9. Delivery format (string + PNG)

The app does NOT render HTML/SVG in the solution field (it uses LaTeX +
`[[model:…]]` + plain text — see `flutter_demo` `MathTextUtils.renderSolution`).
So a solution is authored as an SVG (for the drawn model) but **shipped as**:
a text body (`bm_html` → unicode operators, `\(\frac{a}{b}\)` for fractions,
`<br>` line breaks) with a `[[model:p<g>/solutions/q<id>.png]]` marker; the SVG
is rasterised to that PNG (`bm_insert` → headless Chrome) and served from
`/media` (= `storage/app/public`). Given/derived styling is baked into the PNG.

## 6. Reference implementation

See the watermelon/apples question (W + 4A = 4.05, W + A = 3.45) for the
canonical comparison-elimination solution. Reuse its HTML structure;
change segments, totals, bracket label, and working.

Don't redraw or restyle existing solution artwork — this guide extends the
library, consistent with the never-redraw-sprites rule.
