Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
6bd5eee
feat(tooling): add reveal-season preview-card parser
claude Jun 23, 2026
668114c
feat(reveals): switch reveal season to Set 13 (Attack of the Vine!)
claude Jun 23, 2026
305439a
feat(reveals): add Set 12/13 names + abbreviations to theme
claude Jun 23, 2026
a366ead
Merge Set 13 art assets from master into claude/upbeat-thompson-pmvknv
claude Jun 23, 2026
763a092
Merge master into claude/upbeat-thompson-pmvknv
claude Jun 23, 2026
97b0ba8
fix(tooling): capture mixed-content ability text + card number in parser
claude Jun 24, 2026
b13d740
feat(tooling): make preview-card parser paste-to-download in devtools
claude Jun 24, 2026
3f707bd
feat(tooling): extract keyword abilities in preview parser
claude Jun 24, 2026
e5d047c
fix(engine): treat Temporary Shift as standard (same-name) shift
claude Jun 24, 2026
6dec36a
fix(tooling,engine): address PR #388 review
claude Jun 24, 2026
92e1789
refactor(tooling): flatten parser to clear CodeScene gate (#388)
claude Jun 24, 2026
4b19f00
docs(tooling): move preview-card parser out of scripts into a doc (#388)
claude Jun 24, 2026
77f5bd9
feat(reveals): populate Set 13 preview cards (51 cards) (#388)
claude Jun 25, 2026
bbf0372
docs: address CodeRabbit review on parser docs (#388)
claude Jun 25, 2026
d78e1fb
feat(reveals): add 25 more Set 13 preview cards (76 total) (#388)
claude Jun 25, 2026
d16b01f
feat(engine): decompose Team compound names for Shift targeting
claude Jun 25, 2026
5942e19
feat(engine): re-export getShiftBaseNames from public API barrel
claude Jun 25, 2026
8307bf9
docs(engine): tag getShiftBaseNames example fence as text (MD040)
claude Jun 25, 2026
c627f6b
feat(engine): classify named Shift variants (Combo/Duo team, multi-wo…
claude Jun 25, 2026
1f8062b
feat(reveals): add 5 more Set 13 preview cards (81 total) (#388)
claude Jun 25, 2026
ff12db5
test(engine): tighten shift-variant tests + fix MD038 in shift docs
claude Jun 25, 2026
1d2ef57
feat(reveals): add 8 more Set 13 preview cards (89 total) (#388)
claude Jun 25, 2026
3380dcb
feat(reveals): add Set 13 preview card images (89 cards) (#388)
Doberjohn Jun 26, 2026
a44e536
refactor(scripts): extract downloadCards from downloader main() to cl…
Doberjohn Jun 26, 2026
e814f9e
test(e2e): widen mobile-safari lightbox open/close timeouts to 15s to…
Doberjohn Jun 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ See `packages/synergy-engine/REMOVED_RULES.md` for archived rules (Evasive, Trib

Shift cards find same-named base characters; base characters find Shift cards. Both directions use the same scoring. Scores 3-10 based on curve gap, inkwell flexibility, free Shift cost tiers, and condition activation.

**Variants** (`getShiftType` in `utils/cardHelpers.ts`): `Shift N` and `Temporary Shift N` target same-named characters (standard); `X Shift N` (e.g. `Puppy Shift`, `Madrigal Shift`, `Temporary Red Panda Shift`) targets characters with classification `X` — the prefix may be multiple words, and a leading `Temporary` modifier is stripped before classifying; `Universal Shift N` targets any character. **Team** cards print a compound name ("Belle & Beast", "Sulley & Boo") and shift onto a character named either half, whatever the keyword's flavor label (`Shift`, `Combo Shift`, `Duo Shift`). The `&` in the name is the team signal — checked before the classification branch so `Combo`/`Duo` aren't misread as classifications; `standard` matching routes through `getShiftBaseNames`, which splits the base name on `&` so each component is a valid target (atomic names with no `&` pass through unchanged).

**Full documentation**: See [`packages/synergy-engine/SHIFT_TARGET_RULE.md`](packages/synergy-engine/SHIFT_TARGET_RULE.md) for detailed score tables, examples, condition matchers, and design rationale.

### Rule 2: Named Companions (direct, forward-only matching)
Expand Down
6 changes: 3 additions & 3 deletions apps/web/e2e/E2E_TESTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,10 +196,10 @@ Regression guard for issue #268 (skeleton-loading UI). Each test intercepts `/da

| Test | What it verifies |
|---|---|
| renders hero and franchise tiers at /reveals | All 4 tier headings (Toy Story, Incredibles, Brave, Returning) render |
| renders hero and franchise tiers at /reveals | All 4 tier headings (Monsters, Inc., Up, Turning Red, Returning) render |
| desktop nav shows Reveals entry with NEW badge | `/` has a Reveals link with a "NEW" badge child |
| mobile nav shows Reveals tab | On mobile, `/browse`'s bottom nav has a "Set 12 reveals" link |
| promo modal appears on landing page and not on /reveals | `role="complementary" name=/Set 12 reveals/` visible on `/`, absent on `/reveals` |
| mobile nav shows Reveals tab | On mobile, `/browse`'s bottom nav has a "Set 13 reveals" link |
| promo modal appears on landing page and not on /reveals | `role="complementary" name=/Set 13 reveals/` visible on `/`, absent on `/reveals` |
| tier card click opens the card overview modal | Clicking a card tile on `/reveals` opens the modal; URL stays `/reveals` |

## Patterns
Expand Down
17 changes: 11 additions & 6 deletions apps/web/e2e/tests/reveals-page.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ test.describe('Reveals page (flag on)', () => {

await page.goto('/reveals');

await expect(page.getByRole('heading', {name: /Toy Story/i})).toBeVisible();
await expect(page.getByRole('heading', {name: /The Incredibles/i})).toBeVisible();
await expect(page.getByRole('heading', {name: /Brave/i})).toBeVisible();
await expect(page.getByRole('heading', {name: 'Monsters, Inc.', exact: true})).toBeVisible();
await expect(page.getByRole('heading', {name: 'Up', exact: true})).toBeVisible();
await expect(page.getByRole('heading', {name: 'Turning Red', exact: true})).toBeVisible();
await expect(page.getByRole('heading', {name: /Returning franchises/i})).toBeVisible();
});

Expand All @@ -64,7 +64,7 @@ test.describe('Reveals page (flag on)', () => {
await page.goto('/browse');
const mobileNav = page.getByRole('navigation', {name: 'Mobile navigation'});
// aria-label is the descriptive form after the Option B accessible-name refactor.
const revealsLink = mobileNav.getByRole('link', {name: 'Set 12 reveals', exact: true});
const revealsLink = mobileNav.getByRole('link', {name: 'Set 13 reveals', exact: true});
await expect(revealsLink).toBeVisible();
});

Expand All @@ -73,19 +73,24 @@ test.describe('Reveals page (flag on)', () => {

await page.goto('/');
await expect(
page.getByRole('complementary', {name: /Set 12 reveals/i}),
page.getByRole('complementary', {name: /Set 13 reveals/i}),
).toBeVisible();

await page.goto('/reveals');
await expect(
page.getByRole('complementary', {name: /Set 12 reveals/i}),
page.getByRole('complementary', {name: /Set 13 reveals/i}),
).toHaveCount(0);
});

test('tier card click opens the card overview modal', async ({page}, testInfo) => {
if (testInfo.project.name.startsWith('mobile-')) test.skip();

await page.goto('/reveals');
// Early reveal season: previewCards.json may still have cards: [] (no tiles to
// click). Skip until at least one Set 13 card is curated, mirroring the
// season-ended skip in beforeEach so the suite stays green across the lifecycle.
const tileCount = await page.getByTestId('card-tile').count();
test.skip(tileCount === 0, 'No reveal cards curated yet (previewCards.json cards: []).');
const firstTile = page.getByTestId('card-tile').first();
await expect(firstTile).toBeVisible();
await firstTile.click();
Expand Down
6 changes: 4 additions & 2 deletions apps/web/e2e/tests/synergy-detail-modal.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,10 +155,12 @@ test.describe('Synergy comparison — Mobile', () => {
// queried on `page`, not scoped to the modal.
await appPage.cardOverviewModal.getByRole('button', {name: /^Enlarge /}).first().click();
const lightbox = page.getByRole('dialog', {name: /enlarged/i});
await expect(lightbox).toBeVisible({timeout: 3000});
// The mobile-safari binary runs the lightbox open/close transition slower than the
// 3s default; widen both assertions to 15s for determinism (same fix as #376's modal).
await expect(lightbox).toBeVisible({timeout: 15000});

await lightbox.getByRole('button', {name: /close enlarged card/i}).click();
await expect(lightbox).toHaveCount(0, {timeout: 3000});
await expect(lightbox).toHaveCount(0, {timeout: 15000});
});

test('should exit comparison mode via BACK on mobile', async ({appPage}) => {
Expand Down
Binary file added apps/web/public/card-images-preview/13002-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13002.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13005-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13005.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13006-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13006.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13007-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13007.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13009-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13009.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13017-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13017.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13018-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13018.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13021-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13021.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13024-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13024.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13026-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13026.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13028-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13028.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13029-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13029.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13030-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13030.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13031-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13031.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13033-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13033.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13034-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13034.avif
Binary file not shown.
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13037.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13038-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13038.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13040-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13040.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13044-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13044.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13049-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13049.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13051-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13051.avif
Binary file not shown.
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13052.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13058-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13058.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13059-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13059.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13060-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13060.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13061-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13061.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13065-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13065.avif
Binary file not shown.
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13067.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13068-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13068.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13074-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13074.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13075-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13075.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13079-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13079.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13082-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13082.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13083-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13083.avif
Binary file not shown.
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13088.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13093-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13093.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13095-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13095.avif
Binary file not shown.
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13098.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13099-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13099.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13100-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13100.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13102-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13102.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13103-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13103.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13108-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13108.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13113-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13113.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13115-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13115.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13119-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13119.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13122-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13122.avif
Binary file not shown.
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13123.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13125-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13125.avif
Binary file not shown.
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13126.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13127-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13127.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13128-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13128.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13129-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13129.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13131-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13131.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13132-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13132.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13136-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13136.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13139-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13139.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13140-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13140.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13142-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13142.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13150-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13150.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13153-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13153.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13155-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13155.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13156-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13156.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13160-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13160.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13161-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13161.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13162-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13162.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13165-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13165.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13166-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13166.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13169-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13169.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13172-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13172.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13174-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13174.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13178-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13178.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13187-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13187.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13190-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13190.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13197-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13197.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13199-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13199.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13200-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13200.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13201-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13201.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13900-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13900.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13912-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13912.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13914-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13914.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13920-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13920.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13926-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13926.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13933-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13933.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13948-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13948.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13952-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13952.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13975-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13975.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13977-sm.avif
Binary file not shown.
Binary file added apps/web/public/card-images-preview/13977.avif
Binary file not shown.
Loading
Loading