Skip to content
Merged
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Svelte 5 + TypeScript + Vite. Public repository.
| Game data with sources | `src/data/` (decision 004) |
| Owned properties and upgrades | `data/properties.ts`, `lib/properties.ts` (011) |
| Business production (stock, supplies, value) | `data/production.ts`, `lib/production.ts` (012) |
| Business card order (drag, keys) | `lib/order.ts`, `ui/Panel` `move` (decision 014) |
| Theme tokens | `src/app.css` (decision 009) |
| CI, templates | `.github/` |
| Skills: `handoff`, `finish-pr`; agent: `scout` | `.claude/` |
Expand Down
13 changes: 12 additions & 1 deletion docs/decisions/010-resync.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,21 @@
delivery that arrives while nobody looks still counts. The wait is 10 minutes for every
business and runs on real time for now; which clock the game uses is not confirmed. A raid
also cancels a delivery on its way.
- **Segmented bars, drag to resync** (issue #32): stock and supplies bars are split into five
segments like in game (`BAR_SEGMENTS` in `src/data/business-events.ts`), in the resync
controls only; collapsed cards keep a plain bar to stay clean. Each segment is its own box
with an edge (`--track-edge`, 3.4:1 on the panel), so empty segments are easy to see.
In `BusinessBars` each bar is also a slider (`Meter` with `onset`): drag its handle with mouse,
pen or touch, or use the keys (arrows step 1% to the next whole percent, Page Up/Down jump to
the next segment edge, Home/End to 0/100%). A drag rounds to whole percent and snaps to a
segment edge from up to 1.5% away (`dragValue`/`keyValue` in `src/lib/ui.ts`), so 19% and 21%
are reached by key or typing. It commits once, on release, and shows the level under the
pointer as the value while dragging. Typing stays for exact values.
- What each event does, and the delivery, are game data in `src/data/business-events.ts`
(decision 004).
- **Undo takes back the last edit or preset** of that value; in `BusinessBars` one Undo covers
the last change to either bar, events included. It subtracts what the edit changed
the last change to either bar, events included. Dragging and key steps on one bar in a row
are one change (`recordEdit`), so Undo takes back the whole adjustment, not the last 1%. It subtracts what the edit changed
rather than restoring the old number, so progress counted since is kept: a cooldown mistyped
as 1:30 instead of 2:00 and undone ten minutes later shows 1:50. The undo lives in the
component for the session and is not saved.
Expand Down
6 changes: 4 additions & 2 deletions docs/decisions/011-owned-properties.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
no upgrades. Unchecking "owned" keeps the upgrades, so owning it again restores them. Entries
for ids the catalog does not list are kept; a saved value that no longer fits its upgrade
reads as the default. Logic: `src/lib/properties.ts`.
- **UI:** Settings has a Properties panel with every catalog entry (owned checkbox; upgrades
appear once owned). The Businesses tab shows only owned properties, each panel with a gear
- **UI:** Settings has a Properties panel with every catalog entry: the name as the row label and
a toggle button next to it, "Owned" (accent, filled) or "Not owned" (muted, outlined), with
`aria-pressed` and the name as its accessible label, so the state reads at a glance (issue
#31; it replaced an "Own <name>" checkbox). Upgrades appear once owned. The Businesses tab shows only owned properties, each panel with a gear
button that opens the same settings in place; closed, it summarises the bought upgrades.
Both components take the catalog as a prop, so `#/kit` previews them with sample entries.

Expand Down
31 changes: 31 additions & 0 deletions docs/decisions/014-card-order.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# 014: Business cards in the user's order

2026-10-14, issue #30. Builds on decisions 006 and 009.

## Decision

- **The title bar is the handle.** `Panel` takes an optional `move` prop: its title bar (with the
dot grips of the in-game cards) becomes a focusable handle with a grab cursor. The Businesses
tab passes it for every card; other panels stay fixed.
- **Pointer drag** (mouse, pen and touch alike, through pointer events), like moving apps on a
phone: pressing the handle lifts the card, which then sticks to the pointer while its slot
stays outlined. Over another card, the two swap: that card slides into the empty slot and
nothing else moves (`swapAt`; issue #30 review: shifting every card in between made them race
along the rows like one long list). A swap needs the pointer in the middle of the other
card (20% in from each side, `cardAt`), measured where cards end up rather than mid-slide, so
a pointer resting on a border does not flick the cards back and forth. Releasing saves the
order and the card glides into its slot; a cancelled pointer leaves the order as it was. The handle has `touch-action: none`, so
a touch that starts on a title bar drags instead of scrolling.
- **Keyboard:** with the handle focused, arrow keys move the card one place back or forward
(reading order, since the grid wraps), Home/End to the first or last place. A polite live
region says where it went, and focus stays on the handle.
- **Saved state** (version 5): `businessOrder`, a list of property ids. Shown cards follow it;
owned businesses it does not list (e.g. bought later) come after in catalog order. Ids of
businesses not owned now are kept at the end, so owning one again does not lose it.
Logic: `src/lib/order.ts`.

## Why

Not everyone cares about every business equally, and the in-game card titles already look like
drag handles. Pointer events cover touch without a second code path, unlike HTML drag and drop.
Saving ids rather than positions keeps the order stable when businesses are bought or sold.
3 changes: 2 additions & 1 deletion docs/decisions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ free number, add one line below. **Replacing one:** write a new decision, then m
- [007](007-state-store.md) State store: unreadable data blocks saving like a newer version; import overrides
- [008](008-clock-details.md) Clock details: session play time, opens paused (setting), throttled ticks counted, long gaps asked about
- [009](009-terminal-design.md) Terminal look: tokens in `app.css`, self-hosted Oswald (OFL), browser-style tabs, base components in `src/components/ui/`
- [010](010-resync.md) Resync: `EditableValue` for every tracked value, `BusinessBars` with Sold/Raided/Full and supply deliveries, undo keeps progress since
- [010](010-resync.md) Resync: `EditableValue` for every tracked value, `BusinessBars` with Sold/Raided/Full and supply deliveries, undo keeps progress since, five-segment bars you can drag
- [011](011-owned-properties.md) Owned properties and upgrades: catalog in `src/data/properties.ts`, toggle/choice upgrades, Settings panel and Businesses gear
- [012](012-business-production.md) Business production: rate per exact upgrade combination in `src/data/production.ts`, continuous on play time, unknown rates do not run
- [013](013-marked-estimates.md) Missing game values may be estimated by a stated rule from sourced ones, marked "(est.)" wherever shown
- [014](014-card-order.md) Business cards: drag a title bar to lift a card and swap it with another, or move it with arrow keys; order saved as property ids
2 changes: 2 additions & 0 deletions src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@
now={clocks.now}
onresync={(id, bars) =>
(store.state.businesses = { ...store.state.businesses, [id]: bars })}
order={store.state.businessOrder}
onorder={(order) => (store.state.businessOrder = order)}
/>
{:else if active === 'settings'}
<Settings />
Expand Down
2 changes: 2 additions & 0 deletions src/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
--supplies: #3f6db8;
--supplies-text: #8fb2ee;
--track: #2b343e;
/* Edge of an empty bar segment: 3.4:1 on --panel, so the segments read before they fill. */
--track-edge: #6b7a88;
--warn: #f0b450;
--danger: #ef7a6e;
--focus: #ffd75e;
Expand Down
Loading
Loading