The reference for the layout rework. Change this file first when a decision changes, then the code; the change log at the bottom says what moved and when. Jordan decides; Claude builds.
- Mockup (clickable, simplified numbers): https://claude.ai/artifact/SGVLW62wR3S1qxAzbumFJe
- Where to try it: the beta site, https://tacticalreroll-beta.pages.dev, with the Layout: New / Classic switch in the beta strip. The live site keeps the classic layout until Jordan promotes the new one.
- Cards: T-193 (calculator page), T-194 (each tool its own page, Army vs Army), T-195 (tidy-up).
1. Why
The site has one main job: "if my unit attacks that one, how many die, and how likely is each outcome?" Army vs Army, the winning lists and the rankings are research around that job.
Today all four tools share one long page, and the main job loses:
- On a phone the answer sits about 850px down, below the beta strip, the header, a five-line intro, two cards of dropdowns and statlines, and a modifiers card with two detachment pickers.
- The same things live in several places: lists (calculator dropdowns, Army vs Army sources, winning lists, saved lists), detachments (modifiers card and each list card), the answer (big number, pinned bar, table, funnel labels, classic charts), feedback (strip and footer), "switch" (calculator and Army vs Army), rankings (home page and the static faction pages).
- Seven overlays, each built its own way.
Two independent reviews (Claude's, and Fable's without seeing Claude's) agreed on nearly all of this; where they differed, Jordan chose (section 9).
2. Principles
- The answer first. On a phone the number and the funnel show without scrolling once a matchup is set.
- Three tiers.
- Always in view: both units and their model counts, the answer, the funnel, what fires, the modifiers that are on, Share.
- One tap away (a sheet or popout): the weapon table (Fire everything, profiles, Then fight), the modifier catalogue, leaders and support, detachments, the defender's options, the unit picker.
- Tucked (a fold inside those sheets): stat overrides, re-rolls, Carried by, the defender's weapon for switching roles, the volley animation switch, the table view, chart style.
- Overlays by one rule.
- Changes the answer → a sheet: a popout beside the answer on wide screens (the page stays live), a sheet from the bottom on phones with the live answer in its header. Closes with ✕, Done, Esc or a tap outside; nothing is lost.
- Explains the answer → a drawer that opens in place under it (the table, "More", each weapon's choices).
- Unrelated to the answer → a page or the menu (What's new, feedback, sign-in, language). No popup on a first visit.
- One of everything. One unit picker, one place per setting, one sheet style, one answer component reused on every page that shows a matchup.
3. The calculator (new layout)
Phone (up to 760px)
Top to bottom:
- Header: logo, BETA tag (beta only), theme. The five-line intro becomes one short line ("Warhammer 40k mathhammer calculator: pick any two units for the average and the odds."); the long copy stays in the page for search engines but lower down (stage 2 moves it to /mathhammer/).
- Two unit cards, stacked (Jordan: stacked is right for the calculator; the split card and its chips, Jordan 26 Sep). Each card, top to bottom:
⚔ [Termagants ▾] ⓘ − 20 +: the name, filled in its side's colour, opens the unit picker (T-346, Jordan 29 Sep: Change › is gone); the statline or the card itself opens that side's sheet (below); − / + sets the models. Long names shorten with "…" on phones.- Folding (T-346): on phones a card starts folded to its name and statline, its chips fading out under the statline with an arrow to open them; wider screens start open. The arrow folds or opens it, remembered per device (
hre.fold.v1); adding something in the sheet opens a folded card so it shows. - The full statline:
Tyranids · M6" · T3 · Sv 5+ · W1 · Ld 8+ · OC 2, with the invuln and the defender's FNP when there are any. - Weapons line (attacker): a chip per weapon the unit carries, tap to fire or stop. It follows Shoot / Fight / Shoot, then fight (guns, melee, or guns
then ⚔melee); the usual rules hold (something always fires; a model fires its pistol or its gun). Ends with Edit ›, opening the sheet at Weapons. - Buffs line, one line lower, both sides: 👑 joined characters, then the modifiers on in a few words (
RR wnd,+1 hit,Cover), × in the corner to drop one, then ⚡ rules in play (Sus 1): × switches one off and dims it, ↺ brings it back, and tapping it opens the sheet with the Detachments drawer open (Jordan). Ends with + Buff ›, opening the sheet at Modifiers. Tapping any chip opens its part of the sheet. - The two lines slide left and right on phones and wrap on desktop. On phones Edit › and + Buff › stay pinned at the right, and chips slide under them, fading out (Jordan). Since T-351 the weapons line wraps everywhere (a Hellblaster's Supercharge sat off the edge): names cut at about 14 letters, + Weapons last, and a weapon of several profiles is a two-part pill whose profile part switches it in place.
- − / + stop at the datasheet's model counts (T-197). A small ⇅ swap sits between the cards. The answer ends up about 100px lower on a phone than with one-line cards, still on the first screen.
- The answer: the big number, "of 10 Termagants slain", the range, the meter, and the shooting/fighting split when Then fight is on.
- The funnel, with the pixel squads either side and each weapon's part on hover or tap. Above it, in one row: ⚔️ ATTACK (was "Roll a volley"; the page's call to action, filled with the attacker-to-defender gradient), the animation switch, and Funnel / Classic (Jordan: the controls sit beside ATTACK, not in a drawer). View as table stays a drawer under it. With Then fight, ATTACK plays the shooting first, then the survivors are charged (T-192). Shoot / Fight / Shoot, then fight is a switch in that row too (Jordan, 26 Sep: it changes the answer, so it sits with it; the chosen one a thick outline, not a fill, so ATTACK stays the one filled button): between ATTACK and Funnel / Classic on desktop, on its own line above them on phones, and only for units that both shoot and fight. The answer carries it into an Army vs Army pairing, so the same switch works there. The weapons sheet keeps which weapons; its Then fight box goes.
- A small card: "The whole army? Compare two lists → Army vs Army."
- Footer.
Gone from this page in the new layout: the Modifiers card (its parts live in each side's sheet), the per-side lines under the funnel (replaced by the card's summary), the pinned result bar, the welcome popup.
A side's sheet
Everything about one side in one sheet, in sections, with a row of jump buttons pinned at the top. The header has the unit's name with its model count (− / + beside the name, Jordan) and the live answer.
- Detachments first, as a drawer (Jordan): folded, one line,
⚡ DETACHMENTS Talons + Vanguard 3/3 DP; open, every detachment of that army as a chip with its cost, tap on, tap off, and the ones that won't fit in the points left greyed out; then the options of any rule with a choice. Short names: one detachment shows its whole name; two or three show the first word of each, or the next word where two of the army's share a first word ("Saga of the Hunter" → Hunter). Set once per army, so two sides of the same army share them. - Attacker: Detachments, Weapons (the weapon chips and table), Leader & support (+ Leader, + Support, the joined characters' weapons and choices), Modifiers (the chips that are on, ✕ to drop, ⚡ rules to switch off, then the attacker's column of the modifier panel).
- Defender: Detachments, Modifiers (cover and the rest), Leader & support, Stats (T, Sv, Inv, W, FNP, and its weapon for when roles switch).
- A section with nothing in it (Leader & support for a unit no character can join) hides with its jump button.
Desktop (1100px and wider)
Two columns:
- Left (inputs): the attacker card, ⇅, the defender card, then "The whole army?".
- Right (result), sticky: the answer, then the funnel. It stays in view while you use the left column, so nothing needs a pinned bar.
- The sheets (each side's, the unit picker) open over the left column, so the answer and funnel stay visible and update live.
Between 761 and 1099px: one column, like the phone but with side-by-side units allowed where they fit.
The unit picker (sheet)
Rebuilt as a drill-down (T-347, Jordan 29 Sep; mockup https://claude.ai/artifact/SViy9qgADcVX2iMtEEeJ4c), docs/picker.js, one component with a mode ("unit" for a calculator side, "card" for 🔍; Matchup's "army" mode next). Opened from a side's name (T-346) or 🔍.
- Header: an Attacker | Defender switch with both units' names, ⇄ between, ✕. After a pick the other side comes up if it hasn't been picked this visit, with a one-line nudge ("✓ Attacker set. Now the defender?" · Done); a pick with both sides done closes it.
- Pinned: the search, then the drawers, one per choice made ("FROM · Lists", "FACTION · Tyranids"), the newest tinted; tapping one reopens its level. More than three fade at the top and scroll. Desktop: one breadcrumb line of pills.
- The tree: Where from? Lists · Pick unit · Random · Recent (Benchmarks for a new visitor). Lists: Current list (green, if loaded) · the opponent's list · My lists · Competitive · Supporters ⭐ · Benchmarks; a list's units come after "Use the whole list" (the list becomes that side's army in Army vs Army). Pick unit: Imperium · Chaos · Xenos → our trooper per faction (yours first) → every unit under the role headings, saved and recent first, Legends last. Random: a unit, one from your list, a winning list ⭐, a supporter's ⭐, then ↻ Roll again. ⭐ branches follow supporter.js (off on main until T-187).
- Behaviour: each side reopens where it left off (
hre.pick.v1); the attacker starts on your list, a returning visitor's side on its own army, a new visitor at the top. A level with one live option folds itself ("auto"). A squad of two sizes shows both (5 | 10) on its row. Search groups Jump to (a faction's units, your lists there), Units and Lists; once a faction is set, "in Tyranids | everywhere" (everywhere when the faction has no match). Typing anywhere searches; Backspace goes up a level. Empty branches say why and offer Upload a list or any unit of that side of the galaxy instead. One Plausible event a pick,Unit Pick(via, depth, root).
First visit
No popup. The default matchup shows as a working example, and the attacker card carries a small "Pick your army ›" prompt until the visitor changes a unit.
4. Army vs Army (new layout)
Retiring (Jordan, 29 Sep, consolidated brief): Matchup stops being a screen. A calculator side card holds a whole list; on phones each side gets a floating pill that opens the list, sorted by share slain, in the picker's sheet; on desktop the list grows under the side card. Three tabs: Calculator · My army · Meta (winning lists under Meta); /army/ and /matchup/ open the calculator with the picker in list mode. Cards T-352 to T-355. The screen below (T-348) stays live until T-355 ships (Jordan). Mockup: https://claude.ai/artifact/JhSkFzxVv1ugHeTAdg1JVJ, "View: Calculator page", "Fold into: Floating pills"; its Matchup-screen, drawers and rails views are the rejected paths. Built (T-352, T-353): a side holds a list (hre.sidelist.v1); the from-line under its statline; pills and the sorted sheet (#listPop) on phones, the list under the card on desktop; the ⇄ on the seam; list-level switches; "They shoot back" in the answer. Retired (T-355): three tabs; the Matchup screen is hidden (its columns still compute the lists' scores and the game plan). /matchup/ and #army open the calculator with the picker in list mode; /army/ stays My army (the brief's /army/ was Army vs Army's address before T-285). The picker's list mode holds Upload; the list sheet holds Split up / Join, the unmatched note and Game plan; the points notice is on My army. The tour's Matchup chapter became two calculator steps. Everything below is history.
Its own screen (Jordan, 26 Sep): in the new layout each tab (Calculator, Army vs Army, Lists, Rankings) shows only its own screen, with its own address: /, /army/, /lists/, /rankings/. It's still one app, switched in place: loaded lists stay, a pairing still shows the calculator's own answer, "Edit this matchup" flips to the calculator with it set, and the back button goes back a screen (leaving Army vs Army takes the pairing's answer home). For search engines each address is a real page with its own title, description and canonical link (copies of index.html written by tools/stamp_assets.js, with <base href="../">); old #army links land on the screen at its own address. Classic keeps the one long page (its tabs scroll; a screen's address scrolls to it). A shared matchup link always points at the calculator.
Folds since T-348 (Jordan, 29 Sep; mockup https://claude.ai/artifact/JhSkFzxVv1ugHeTAdg1JVJ): "whichever side you tap folds". Blue is yours, purple theirs, green the answer, everywhere.
- The band.
YOUR ARMY · Change ›⇄OPPONENT · Change ›; Change › opens the unit picker in army mode (T-347's picker, at its lists: current list, My lists with Upload or paste, Competitive, Supporters ⭐, Benchmarks (each faction's best of a unit type, or a whole faction), Random list), and choosing a list is the pick. Under the headings a card per side: list name, army · detachments · points, an amber dot naming unmatched units, ✕ on the opponent's (it clears and opens the picker). Then the options line (Cover · Stationary · Half range pills, ⚡ buffs ▾; its sheet holds the Colours switch). A one-line intro the first time. The four source tabs, Clear, "From My army" and the unmatched sentence are gone from view (the data paths stay). - Rest: both lists as plain rows under role headings (name, models, points; joined units as one 🔗 row), titled
YOURS · n/THEIRS · n. - One side picked: on phones that column folds into a drawer (
YOURS · Terminator Squad ×10, name and size) and the other takes the width, sorted: one number a row (points removed at best, "x of n slain" under it) with a bar scaled to the best, 🏆 best target on the first, and whatever it barely touches (under 0.3 slain) faded at the bottom under "No real effect". Their side first works the same way round: "Who deals with <unit>", models slain first. - Both picked: two drawers (first tapped on top, newest tinted), the pair card, then the rest of their units ("Other targets for <unit> · tap to switch"). A drawer unfolds its side and keeps the other; ↺ in the footer unfolds both.
- The pair card: "4.2 of 5 slain" (green) with ≈ points removed; Ranged and Melee with the weapon behind each; "They hit back: n of m fall to <weapon>"; the calculator's own battle strip and answer (funnel, pixel battle, This roll; no charts); "For this pair" chips (Cover, Stationary, Half range work the calculator's own switches for the loaded pair; ⚡ Buffs and 🛡 Target open the sides' sheets); Simulate › (plays in place), Keep attacking, Open in calculator › (Back returns to the same folds); a disclosure with the weapon choices and Split up / Join for the two picked units.
- Desktop (900px and up): both columns stay, the tapped row lights up (3px rule in its side's colour), the other column sorts the same way, and the pair card is a third column.
- Footer: ↺ (while folded), 📋 Game plan, 🔗 Share (the pair's own share menu, else a link to the screen). Plausible:
Matchup Pair(first: yours | theirs, via: fold | desktop).
The pinned bar never shows on this page in the new layout (the sheet or panel replaces it).
5. Header, menu, strip
- Beta strip (beta only): BETA, What's new, Feedback, and Layout: New / Classic.
- Stage 3 (T-195) moves What's new, Feedback, supporter sign-in, language and theme into one ⋯ menu, What's new becomes a page with a dot for unread, and the strip shrinks to a tag on phones. Not in this build.
6. The switch (how to flip between old and new)
hre.layoutin local storage:"new"or"classic".?layout=new/?layout=classicsets it. The page setsdata-layouton<html>before first paint.- Everywhere, live site included (Jordan, 26 Sep, promoted with the merge): the default is new, and the strip's switch offers Classic for a few weeks. T-200 then retires Classic (the switch, its CSS and code paths, its tests).
- Everything new is scoped under
html[data-layout="new"]in the CSS and checked withnewLayout()in scripts, so classic stays exactly as it is.
7. How it's built (for Claude; keep in step)
Reuse before rebuild. The new layout moves and restyles existing pieces; the dice engine, the weapon rules, the modifiers and detachment logic don't change.
| Piece | Today | New layout |
|---|---|---|
Unit selects #attArmy #attUnit #defArmy #defUnit | visible in the cards | hidden; the unit picker sets them and fires change |
| Unit cards | .setup-col with selects and statline | .unit-card (new): #attUnitBtn opens the picker (#unitPop), ⓘ the unit's sheet, the four heads the expander (T-429) |
What fires #attFiring | card | stays in the hidden classic card; the summary line reads S.attFire itself |
Edit weapons #attPop, Edit defender #defPop | popouts | their contents become the accordion's parts: sheet() in layout.js wraps them in .sh-sec sections in the card's expander, and the empty popouts are removed (T-439) |
Joins #attJoins #defJoins | card | in the sheet's Leader & support section |
Modifier chips #modsBar, #modPanel | one card, both sides + detachment pickers | the panel's two .mods-cols go into the sheets; each side's chips #attChips #defChips sit above them; detachment chips #attDets #defDets in the sheet's drawer (detDrawerHTML(), drawn by sheetFill(); setDets() keeps the 3 DP cap) |
Models #wf_squad #df_squad | card | hidden; the stepper in the sheet's header sets them and fires input |
Answer + funnel .main-layout | under the setup | phone: under the unit cards; desktop: right column; Army vs Army: moved into the pairing sheet/panel while it's open |
Pinned bar #pinBar | shows when scrolled | never |
Welcome welcome.js | first visit popup | skipped; prompt on the attacker card |
Army vs Army options #cmpBar | box above the lists | one line + sheet |
| Roster heads | tabs always | one line once loaded, tabs in a drawer |
Pairing detail #cmpDetail | its own breakdown | the calculator's answer and funnel, plus a weapon-choices drawer |
Tests: the classic layout's tests stay as they are; new-layout tests set hre.layout=new.
8. Not in this build
- Stage 2 (T-194 rest): a page per winning list (search traffic), rankings merged into the /factions/ pages, one "My lists" library. (Each tab as its own screen and address is done.)
- Stage 3 (T-195): the ⋯ menu, What's new as a page, one feedback door, shorter footer text.
- The charge animation for Then fight (T-192).
9. Decisions
| Date | Decision | By |
|---|---|---|
| 26 Sep | Home page becomes the calculator only; other tools become their own pages (stage 2) | Jordan, after both reviews |
| 26 Sep | Calculator units stacked, one line each, on phones | Jordan |
| 26 Sep | Army vs Army stays side by side on phones | Jordan |
| 26 Sep | Army vs Army pairings show the calculator's full answer and funnel, not a smaller copy | Jordan |
| 26 Sep | Build on beta behind a New / Classic switch, to compare and keep what works | Jordan |
| 26 Sep | Modifiers move onto each side's line; detachments into the unit picker | both reviews (replaced by the split card) |
| 26 Sep | Shoot / Fight / Shoot, then fight moves beside ATTACK; Fight to the death (rounds until one side is wiped out) is a new mode to come (T-196) | Jordan |
| 26 Sep | Promote: the new layout is the live default, the Classic switch kept for a few weeks (T-200 retires it) | Jordan |
| 26 Sep | Each tab its own screen and address (/army/, /lists/, /rankings/), one app switched in place; not separate reloading pages | Jordan |
| 26 Sep | Picker: factions under Imperium / Chaos / Xenos, units under role headings, A to Z | Jordan |
| 26 Sep | The volley fires in bursts from each gun in no set order, curving to its lane, not as a hose sweeping down | Jordan |
| 26 Sep | Mode switch outlined; Edit › and + Buff › pinned right; counts within the datasheet's (T-197) | Jordan |
| 26 Sep | Cards: full statline, − n + beside the name, the weapons and buffs as chips on sliding lines, Change › stays beside the name | Jordan |
| 26 Sep | ⚡ rules on the card: × dims one (↺ back on); tapping it opens the Detachments drawer | Jordan |
| 26 Sep | In a side's sheet: models beside the name; detachments first, as a drawer of tap-on chips with short names when folded | Jordan |
| 26 Sep | Split card: tapping the unit opens that side's whole sheet; Change › opens the unit picker; the lines under the funnel go | Jordan |
| 26 Sep | No first-visit popup; What's new a page (stage 3) | Fable's review, Jordan agreed to the merged plan |
| 27 Sep | Keep the "Tap to pick your army" prompt on a first visit; a guided tour for newcomers to consider (T-204) | Jordan |
| 27 Sep | Army vs Army on desktop: the pairing panel beside the lists (three columns) | Jordan |
| 27 Sep | Their units in list order by default; Best stays one tap away and is remembered | Jordan |
| 27 Sep | Army vs Army sides (T-205): four sources as tabs on each side (Winning list, My lists, Whole faction, Unit type); Clear with Undo; units under role headings, numbered 1 to N; Unit type by Imperium / Chaos / Xenos with the datasheets' own types | Jordan, from the mockup |
| 27 Sep | Stage 3: the GW disclaimer stays in full; What's new stays a pop-up card (T-184), not a page | Jordan |
| 26 Sep | Funnel / Classic and the animation switch sit beside the volley button, not in a drawer | Jordan |
| 26 Sep | "Roll a volley" becomes a prominent ⚔️ ATTACK button | Jordan (suggested SIMULATE or ATTACK) |
| 26 Sep | Shoot, then fight animates as shooting, then a charge | Jordan (bug report) |
| 29 Sep | Matchup retires into the calculator (lists on the side cards, floating pills, three tabs); T-348 stays until T-355 | Jordan |
| 29 Sep | Tier colours by medal: S gold, A green (T-356) | Jordan |
| 29 Sep | Matchup retired (T-355): /army/ stays My army's address, /matchup/ opens the calculator | the brief (its /army/ predates T-285) |
10. Open questions
None open. Settled by Jordan on 27 Sep (see the decisions table): keep the first-visit prompt; the pairing panel beside the lists on desktop; their units in list order by default.
Change log
- 28 Sep (T-283): the tabs are being rethought: Calculator · My army · Matchup · Meta, an in-app unit card, the sheets as tabs, Classic retired. Two proposals, the appraisal and Jordan's decisions are in
rethink/README.md; this brief is updated card by card as T-285 to T-291 land.
- 26 Sep: first version, from the mockup and Jordan's notes on the beta screenshots.
- 26 Sep: built on beta (sections 3, 4 and 6). What's in: the switch; the unit buttons and picker (search, Recent, From your lists, every unit of the army, models, detachments); each side's line (what fires, joins, modifier chips, + Modifier sheet showing that side's column); answer and funnel under the units on phones and in a sticky right column on desktop; More drawer (chart style, animation, table); no Modifiers card, pinned bar or welcome popup; a "Tap to pick your army" prompt for first visits. Army vs Army: options line + sheet, folding list headers, pinned titles ("⚔ Hive Tyrant attacking"), List / Best order, and the pairing sheet (phones, and up to 1099px) or panel (desktop) holding the calculator's own answer, a Shoot / Fight / Shoot, then fight switch, Edit this matchup, and the weapon choices drawer. Not yet: the stage 2 pages, the ⋯ menu, the ⇄ label change. Code:
docs/layout.js, the "streamlined layout" blocks at the end ofdocs/style.css, hooks in app.js (Layout.*,newLayout()). Tests:tests/browser/newlayout.test.js; other tests pin classic. - 26 Sep: Jordan's first notes. Funnel / Classic and the animation switch back beside the volley button (the More drawer is gone); the button is now ⚔️ ATTACK, filled and bigger, in both layouts; with Then fight it plays the shooting, then the charge (T-192, both layouts:
shootout.jsplans the two parts asV.shootandV.fight). - 26 Sep: bigger pixel figures (one step up per size, still shrunk to fit each side's share of the chart), and a leader joined to the attacking squad now stands behind it with a crown and charges with it. When squads and leaders crowd a phone's chart, the step names shorten.
- 26 Sep: the split card (Jordan). Each side's card: tap the unit for its whole sheet (weapons, leader, modifiers, models, detachments; the defender's stats), with a row of jumps at the top; Change › for the unit picker, now only a picker. The card's last line sums up the setup, and the per-side lines and the separate modifier sheet are gone. Also fixed: on phones the defender's sheet sat off to the side (both layouts).
- 26 Sep: Shoot / Fight / Shoot, then fight moved from the weapons sheet (and the pairing panel's header) to the answer, beside ATTACK:
#calcMode, built by layout.js inside.main-layout, so it travels into Army vs Army. Fight to the death is carded as T-196. - 26 Sep: from Jordan's phone test. The model count moved beside the unit's name in the sheet's header (the Models section is gone); detachments moved to the top as a drawer of chips (tap on, tap off, 3 DP cap, short names when folded) in place of the dropdowns; empty Leader & support sections hide; the BETA badge hides while a sheet is open.
- 26 Sep: the card's chips (Jordan). − n + beside the name; the full statline back; a weapons line (tap to fire, Edit ›) and a buffs line (short names, × in the corner, + Buff ›) that slide on phones and wrap on desktop, each chip opening its part of the sheet. Short names are our own words:
short.*in i18n.js, from the modifier (activeModifiers()now gives ashort) or from what a rule does (fxShort()in layout.js). The summary line is gone.weaponTap()in app.js is the one place a weapon chip's tap is handled. - 26 Sep: Jordan's next notes. The unit picker groups factions (Imperium / Chaos / Xenos) and units (role headings), A to Z; the volley's shots go in short bursts from each gun at random moments, down no set order of lanes, each curving from the gun at its own speed (
shootout.jsplan():t.sp,t.arc; a bullet still stops at the roll it fails); the mode switch is outlined; Edit › and + Buff › are pinned; model counts stay within the datasheet's (T-197,sizeRange()/squadFrom()in app.js, both layouts). - 26 Sep: squads of more than 10 are drawn in as many ranks (2 to 4) as give the biggest figures, not always 4 (Jordan: 20 Termagants were tiny). On a phone that's 2 tall ranks, twice the size; a joined leader scales with its squad; the size tiers keep their order.
- 26 Sep: each tab its own screen (Jordan). New layout:
showView()in app.js shows one.view(.view-on), sets the title and pushes the address;popstategoes back a screen;Layout.onView()closes a pairing when leaving Army vs Army. index.html has<base href="./">so relative fetches keep reaching the root after the address changes;stamp_assets.jswrites/army/,/lists/,/rankings/(in the sitemap, the offline shell). Classic: unchanged scrolling, and a screen's address scrolls to it.
The guided tour (T-204, 27 Sep night)
Jordan accepted the mockup's recommendations: the tour offers itself once on a first visit (never over a shared link) and stands in for the "Tap to pick your army" prompt; the Calculator chapter (16 steps, dynamic mode then classic) ends by offering the Army vs Army chapter (8 steps, which loads two winning lists if the page is empty). "Take the tour" in the footer replays it.
Classic below dynamic (T-263, 27 Sep night)
In the new layout both views are always on the page. Dynamic (the battle) leads, with the classic charts folded below it into one line of their averages that opens on a tap; ⟳ Classic swaps the order (charts on top and open, the battle below) and is remembered. Classic layout unchanged.
The unit card as one accordion (T-429, Jordan, 30 Sep)
Jordan approved the design session's mockup (https://claude.ai/artifact/X728KECZ2HJosSTMRQNuvk) after four rounds. It replaces the bottom unit sheet: each side's card is name (the picker), i, the size stepper; the statline; four heads on one line (Weapons, Leader, Detachment, Modifiers: what it carries, who is with it, which army rules, then the situation); one line of chips per category that has anything set, sliding sideways, never wrapping; and one expander at the card's foot that swaps content as heads are tapped. Attacker and defender are the same component, so the defender picks its weapons and leader too. A leader's squad-wide buffs show in the Modifiers line as gold crown chips, switchable per matchup. Cards start closed. SIMULATE folds both cards to one strip each on phones (tap one to reopen it). The modes become four: Shoot, Melee, Fight back (one fight phase, both sides' losses) and To the death. The fixed-height sheet (T-419) and the equal-height compact cards (T-424) are superseded.
Amended 30 Sep, 08:03Z to 08:10Z (mockup version 7, same link). SIMULATE on a phone turns the two cards into ONE row docked under the site header: two equal halves (attacker blue left, defender purple right: figure, name, ×N), ⇅ at the seam, sticky while the page scrolls to the funnel; a half opens that side's list sheet, or its card when it has no list. The floating list pills go. The modes are four TOGGLES, not four exclusive modes: Shoot and Melee are what our side does; Fight back, whether the target's survivors reply; To the death repeats it all up to 5 battle rounds until one side is gone. Fight back and To the death together are the fight to a finish as it was; one round of Fight back is To the death's first phase, to the same dice (deathOdds). Lists live on the cards: a list chip under the statline ("▤ Pick a list", or the list's name and its units, ✕ to clear); the MY ARMY strip and the Load a list door go; the doors are My army (reformatted, with Set as attacker / Set as defender) and Meta. The Simulate row is SIMULATE and "✨ Effects"; the charts/battle switch is a pill in the result panel's top-right corner.
Built 30 Sep (T-430 to T-438 on main; T-439 on the work branch, waiting for main): the docked row (#nlDock, two .dk-half and #dockSwap) replaces both cards below 900px while the battle plays, and a half's tap brings its card back (Layout.unstrip()); the four toggles are independent (S.attBack, S.attDeath; a share link's k is "b", "d" or "bd"); the list chip (.lchip, T-437) sits under the statline and the MY ARMY strip, #mineChips and the pills are gone; the Simulate row is #soReplay and #soFx, the 🎲 ×10 run and its tally (#soRuns) removed (T-438, T-439); the charts/battle switch is #chartSwap in .bd-corner, "📊 Charts" or "⚔ Battle".
Stratagems under the detachment (T-749, Jordan, 6 Oct)
Jordan approved the mockup (design/mockups/2026-10-06-calculator-stratagems.html) and the build on 6 Oct. A side's Detachment part gets a Stratagems · this unit block under its detachment chips and their choices (.st, drawn by docs/stratui.js from detDrawerHTML()): the unit's dice stratagems from the detachments picked (data/stratfx.json, written by tools/stratcalc.js from the catalogue, through DetFx.strats()), keywords checked, the rest a faint count ("1 more is for another kind of unit: SYNAPSE"). Grouped Shooting, Fight (melee), Defence (when it's attacked); a group that doesn't bear on the matchup is faint and says which toggle brings it in (the attacker's Defence with Fight back; the defender's Shooting or Fight when it shoots or fights back). Our words and the CP on each chip (.schip), never a name. Tapped, a stratagem is in use: the dice take it (detInPlay() adds its effects, strat: true, gated to ranged or melee by its phase) and it joins the Modifiers line as a teal ⚡ chip with its cost (.lc.strat, data-stratoff); tapped there or again in the block, it stops. Every one starts unused (S.attStrat/S.defStrat, not saved; they swap with the sides for the strike-back and the swap button). A stratagem allowed in shooting and in the fight is two chips, one use each; a round-long one is one use shown in each group ("same use"); one whose versions are true alternatives (Lethal Hits or Sustained Hits) is a chip per version, "or" between, one use. The core one-die re-roll sits last in Shooting and Fight, "any army". The heading's CP this matchup adds up the uses in play, a defence one once for each enemy phase it covers (shooting and melee both on: two), its tooltip saying how; nothing on the result card and no budget check. The flag: "strats" in data/flags.json ("beta": the beta site and local copies; ?strats=1 anywhere). Armies the catalogue doesn't cover yet have no block. The rankings and the points ledger don't read any of it.