Repository navigation
re:builder - #162
Merged
Merged
re:builder#162
Conversation
…ership searches (#131) * Re:Builder: keep unique illustrations, fix collection and digital ownership searches - ac-card-art compares its source list by value: a unique whose card object is replaced once its printed effect arrives kept the same <img> src, so `load` never fired again and the art stayed hidden. - The collection / ownership searches send list filters as `key[]`: PHP kept the last value of a repeated `rarity=…`, so the default search asked for Exalted cards of one type and one set only. - collection-search.php forwards those lists to the collection API in its array form too (cacCollectionQuery, tested in tests/CollectionQueryTest.php). - The stack's ownership mock answers GET /api/collection with a few filtered cards, for the e2e test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Simplify: reset card art on its displayed src, share the owned query rationale - ac-card-art resets `loaded` when the displayed src changes rather than the source list. - ownedParams' doc carries the `key[]` rationale once; collection query loop without array_values. - e2e: the cards API answer waits for the shown illustration instead of a fixed delay; the digital collection test also runs on mobile (« Plus » menu); screenshots for the pull request. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * e2e: check the physical collection search too, against the stack's mock The stack's collection API (COLLECTION_API_URL) is the ownership mock, which also answers GET /api/collection with the collection API's filter names (cardType, cardSet): the real API only takes altered.re tokens. The collection test fails with the previous client or the previous proxy. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Stack: start the decks API with the latest Mercure The decks API image is built on the latest FrankenPHP base, whose Mercure now refuses publisher_jwt / subscriber_jwt outside compatibility mode: the container exited at startup and the e2e job failed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…a token or a hero (#132) * Re:Builder: number alt-art copies 1, 2, 3, one unnumbered marker for a token or a hero The markers showed `slotIndex + 1`: a token's single copy showed « 2 » in production (the ownership API's slot indexes most likely start at 1). They are now numbered by position; a family with one copy (token, hero) has one marker with a check and no number, and the first copy moves first, as on the site's widget. The stack's ownership mock gives tokens one copy, as the service does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Simplify the copy numbers of the alt-art markers Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Simplify: number the copies once, fewer marker assertions - alt-art-slots numbers the copies once per render instead of once per illustration; the pointer cursor is set on the button markers only. - e2e: the token markers are checked with two locator counts instead of two assertions a marker. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
… list (#133) * Re:Builder: check several effect values in a row, without reopening a list The effect editor's three criteria (Quand · déclencheur, Si · condition, Alors · effet) used a combobox that closed after each pick. They now use a checkbox list that stays open: - Window: the criteria as cards on the left (values one per line, « ou » on its own line), the checkbox list of the selected criterion on the right, at a fixed height so checking never moves the list. - Compact: each criterion shows its values and an « Ajouter un … » add button that opens the list as a step of the same sheet, over its whole height. - A list is narrowed again only when the two other criteria change (the server already leaves the narrowed criterion out), so checking values does not reshape the list being checked. New components: ac-check-list, ac-or-values, and the ac-ability-picker step. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Re:Builder: duplicate an effect from its summary A copy button between edit and delete on each effect summary puts a copy of the effect right after it, with its own id. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Re:Builder: share the list helpers of the effect editor - option-list.ts holds normalizeSearch and groupStarts, used by ac-combobox, ac-check-list and ac-select (which had its own copy of the search folding). - One _glyph.scss partial for the Altered Icons glyph of the three lists. - ac-check-list's search field uses the design system's ac-input-icon. - The effect editor builds its criteria from one text table, reads the picked values through one helper, and renders the intro and the load error from a single template each. - newEffectId() for the copy of a duplicated effect; ac-combobox drops its emptyPlaceholder input, unused since the effect editor stopped using it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
) Uniques are cards whose text is read. On a 2560 px window the results grid showed 8 of them per row, too small to read. The Uniques grid now caps at 7 columns: the cards only grow where 7 would be narrower than the usual 210 px, so 1920 px (5 per row) and 1440 px (3 per row) do not change, nor do the other tabs. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Re:Builder: the whole deck at a glance from 768 px, read and edit Deck bar above the deck page and the editor: hero art with a faction border, the name on two lines at most, format and legality, counts per type, cost curve (hand and reserve), terrain totals, and every action at hand. The editor's search and starting hand get a one-row version with a mini curve and a « ⋯ » menu. « Aperçu » is now a board of piles, one column group per type, like the deck image: every group has the same row count, the smallest that fits 12 card columns. In the editor each pile has a stepper on hover or focus; a card brought to 0 stays, faded, until the view is left. My own deck opens in the editor on « Aperçu »; « Terminer » goes back to the deck list. Someone else's deck opens on its read-only page. The deck panel keeps its card list only (summary and stats are in the bar) and starts hidden on « Aperçu ». Phones are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Re:Builder: deck board fills the window's width, copies of a pile further apart The number of card columns follows the board's measured width (150 px a column at least), so a wide window gets fewer rows; cards grow up to 260 px. Each copy behind the front one is 16 px lower, to count them at a glance. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Re:Builder: deck settings button stands out on any hero art Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Re:Builder: deck board cards stay readable, 150 px wide at least The column count now comes from the narrowest card allowed, counting each group's padding: a deck with Uniques takes more rows instead of shrinking its cards. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Re:Builder: editor deck panel as tall as its cards, the window at most Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Re:Builder: filters panel ends at the window's bottom under any header Its height left out a fixed 136 px, the old editor header; the deck bar is taller, so « Réinitialiser » and « Rechercher » were below the window. The panel now measures how far it sits below its sticky position. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Re:Builder: a click anywhere on an effect criterion opens it « Quand », « Si », « Alors »: only the title row was a button, the values below it (« Tous les déclencheurs »…) did nothing. The title's button now covers the whole card; the values' own buttons stay on top. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Re:Builder: more room around the deck bar's buttons Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Re:Builder: deck settings show the hero's illustration, not its card Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Re:Builder: disable the filters the Favoris tab cannot apply The site's favorites search filters its table by faction, set and rarity only: the name, cost, power, type and advanced fields did nothing there, with a chip as if they did. On Favoris they are now disabled and faded, under a note, and give no chip. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Re:Builder: a duplicated deck opens in the editor, on « Aperçu » From the deck page (someone else's deck or one's own) and from the editor's « Dupliquer en local », as « Dupliquer » in the editor already did. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Re:Builder: review fixes on the deck board and the filters panel - The board keeps at 0 only the cards removed with a pile's stepper (or the card zoom), not every reference it showed: a print swapped in the zoom or by Global alt-art mode no longer leaves a faded duplicate behind. - The filters panel measures its offset again each time it is shown from its tab, not only on scroll: reopened without scrolling, its buttons stayed below the window. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Re:Builder: simplify the deck bar, the board and the shared deck actions - The deck bar opens the hero zoom itself (no copy in each page) and renders its settings button once; overlines use the design system's .ac-text-overline. - deck-actions.ts holds the image source and the delete message, used by the deck page and the editor. - The board sorts its groups only when the cards change; a resize only recomputes the column count. Decklist order is one shared comparator. - Deck cards take a boolean for the editor link, not a route array built for every card on each change detection. - The filters panel is measured once a frame at most, and not on phones. - Split buttons share their menu positions with the editor's « ⋯ » menu. - Dead labels, translations, Sass variable and duplicate rules removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…ng a list (#136) The hand calculators (« Choisir… », A, B) and the subtype filter closed their list after each pick. ac-combobox gets a keepOpen mode, on for both: - Each option has a check box; a press checks or unchecks it and the list stays open. Checked values stay in the list, in bold. - Enter in the search field checks the first unchecked match and empties the field, as in the effect editor. - The chips go under the button, so checking never moves the button or the list under the pointer. - The listbox only gets the checked options it lists: the CDK listbox rejects a selected value it has no option for (one the search hides). Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…erminer », physical collection fixed (#137) * Re:Builder: « Mes decks » instead of « Terminer », hero settings in the search bar, collection search with several card types - The editor's « Terminer » goes: « ‹ Mes decks » of the deck bar leaves the editor (shown in the reduced bar too), the deck is saved on the way out as before. - The reduced deck bar (Recherche, Main de départ) keeps the settings button on the hero art: the hero can be changed without going back to « Aperçu ». - The collection API fails (HTTP 500) on several cardType[]: the proxy sends the card type only when there is one and filters several itself. Re:Builder sends four types by default, so its « Collection physique » tab always failed on preprod. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Re:Builder: Rares, Exalteds and Uniques against the format's caps in the deck bar Back from the deck panel's summary removed in #135, with the caps the site's builder shows: one badge per capped rarity (12/15), grey below the cap, green at it, red above. Under « Puissance totale » in the full bar, a column of its own in the reduced one; a rarity without a cap (Singleton, Sandbox) is left out. The reduced bar drops its mini curve from 1320 px, the terrain totals from 1060 px and the rarities from 900 px; the full bar keeps the rarities when the terrain totals go. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
… cardSet, HTTP 500 on several types) (#138) #137 filters several card types in the collection proxy, on the items' cardType. The mock answered with type / set instead, so the proxy dropped every card and the « Collection physique » e2e found 0. The mock now names the fields as the collection API does, and fails on several cardType[] like it: the e2e checks the proxy's own filtering. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…s app bar (#139) * Re:Builder: on phones too, « Mes decks » opens a deck in the editor; « ⋯ » in its app bar Like from 768 px, a deck of « Mes decks » opens in the editor on « Aperçu ». The deck page's actions (image, copy the list, duplicate, delete) were reached through « Terminer », gone in #137: the editor's app bar gets the deck bar's « ⋯ » menu. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Re:Builder: one element per app bar block, so « Partager » and « ⋯ » are both projected Content projection only takes a control-flow block with a single root: with both buttons in one @if, neither reached the app bar's actions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…nly @mobile tests (#140) The e2e job wrote its Docker layer cache from each pull request: a cache scoped to that PR, unreadable by the others, so every new PR rebuilt both images (~3-4 min), and the repository cache sat above its 10 GB limit. stack-images.yml now writes it on preprod (push, weekly, manual); pull requests only read it. On the CI, the mobile project runs only the tests tagged @mobile (bottom navigation, sheets, app bar, touch sizes): 56 tests instead of 88. Locally both projects still run everything, for pr-screenshots.mjs. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…n a slow network (#141) - SPA pages: a server-rendered placeholder (manifest `placeholder`) shown while the scripts load, kept by the host runtime until the plugin's first screen, replaced by an error notice if a module fails to load. Re:Builder's draws the screen of the URL (decks list, deck page, editor views) in its layout. - Design system: `ac-skeleton` (text, title, control, control-sm, circle, card, panel), `[acSkeleton]` directive. - DeckStore.opening: deck bar, panel, board, preview, list view, hand and deck page show skeletons in their own layout instead of « 0 cartes », « Deck vide », « Non légal ». owned() is unknown while the deck opens, so the actions stay in skeleton rather than « Modifier » appearing then disappearing. - Card search waits for configure() (the deck's faction and format) before its first request. - Decks list: skeletons at a deck card's size, « Chargement… » for the count. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Re:Builder: the hero portrait opens « Choisir un héros » (desktop deck bar and mobile summary) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Re:Builder: one portrait button in the deck bar, one hero picker config Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…app bar (#143) * Re:Builder: phones keep the hero and the rarity caps in the editor's app bar In « Recherche » and « Aperçu » on phones, the app bar of an editable deck shows the hero (it opens « Choisir un héros ») and, under the deck name, the Rares / Exaltées / Uniques against the format's caps, what the deck bar shows from 768 px. The bar stays on screen while scrolling; the condensed search head sticks below it. Its title opens « Résumé du deck »: hero, legality, a bar per capped rarity, counts per type. « Partager » moves to the « ⋯ » menu there. Also: ac-progress--success / --danger and ac-badge--dense in the design system, a [titles] slot on ac-app-bar, cached eager art (the hero after a tab change) shown without placeholder or fade, and shared helpers for the rarity labels (rarityLimitItems), the « Non légal » label and the hero art. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * e2e: read the created deck's id from the editor URL, not from the POST's body On the CI, Chrome had dropped the body of the deck creation response (the editor's images fill its buffer) by the time the test read it: « response.json: No data found for resource ». The status is still checked on the response. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
… 21 s on 3G, no layout shift) (#144) * Re:Builder: announce the page's modules in <head> (modulepreload), one round trip instead of five The build manifest lists, per page slug and language, the chunks a page imports before it can draw (esbuild metafile); the shell announces them with the entry modules and the shadow-root CSS. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Re:Builder: the page's data sooner on a slow network - Module preloads start once the page's stylesheets have loaded: the first paint keeps their bandwidth. - main.ts requests the deck of the deck page and of the editor while the modules download; the app takes that answer (prefetchInterceptor) instead of sending its own request. - Ownership check of the editor from papi/rebuilder/my-deck-ids (ids only, read server side) instead of downloading every deck of the account. - JSON of the API relay and of the plugin endpoints gzipped (Debian's mod_deflate leaves JSON out). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Re:Builder: no layout shift when the app replaces the skeleton, less art and code ahead on a slow network - Host runtime: the plugin's container and the server's placeholder share one grid cell until the first screen is drawn, so the placeholder is never pushed down (CLS ~1.0 -> ~0). - Decks list skeletons keyed by the list's length: decks arriving above them never move them. - Card art lookahead of half a screen on a 3G or slower connection (or data saver), instead of 2.5 screens. - Test hand, odds and calculators (with the CDK's drag and drop) in their own chunk, loaded with their view. - e2e: module preloads, one deck request, ownership from my-deck-ids, gzipped JSON, no layout shift. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Re:Builder: the prefetch reads its answer in full; skeleton e2e tests hold the scripts for real An unread error body kept the prefetched request open (no network idle on an unknown deck). The skeleton tests now turn the browser cache off, so the held main module is not served from the memory cache, and wait for the response only (a module script holds DOMContentLoaded). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Re:Builder: hashed build files cached for a year; A/B load-performance bench - plugins/rebuilder/.htaccess: Cache-Control immutable on main-, polyfills-, chunk-HASH.js and the hashed fonts (mod_headers): a repeat visit loads no module from the network. - tests/e2e/perf-ab.mjs: two versions of the site side by side on an emulated 3G / slow 4G phone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Re:Builder: request the modules right after the skeleton, not from <head> Started once the head's stylesheets had loaded, the module preloads took the bandwidth of the rest of the page and of the skeleton's stylesheet: the skeleton was painted ~0.3 s later than on preprod (screencast, 3G). The inline script now follows the placeholder, so it runs once the skeleton can be painted. e2e: the ownership test waits for the save before reloading. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * e2e: the held-scripts tests unregister the site's service worker first Installed by the first visit, it answered main.js itself, out of the routes' reach: the skeleton test failed one run in three. The ownership test waits for the app bar's hero on phones, where « Partager » moved to the « ⋯ » menu (#143). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…e » lists the Uniques (#145) * Re:Builder: a deck opens at the top of its page; Propriété numérique lists the Uniques Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Re:Builder: Propriété numérique keeps the Kickstarter set by default, steadier scroll e2e Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Re:Builder: one owner for the « légales » rule, page key from the active route Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…ones included (#146) * Re:Builder e2e: back from a deck puts the decks list where it was, phones included On phones the list did come back at its offset; the test scrolled the deck card under the sticky app bar, so Playwright's click scrolled the page back to the top before the deck opened, and the list rightly restored 0. The new test places the card just below the app bar and checks the exact offset on desktop and mobile. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Re:Builder e2e: one scroll below the app bar, URL checks through at() Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
… (focus, scrollIntoView and anchors no longer hidden) (#147) * Re:Builder e2e: back from a deck puts the decks list where it was, phones included On phones the list did come back at its offset; the test scrolled the deck card under the sticky app bar, so Playwright's click scrolled the page back to the top before the deck opened, and the list rightly restored 0. The new test places the card just below the app bar and checks the exact offset on desktop and mobile. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Re:Builder e2e: one scroll below the app bar, URL checks through at() Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Scroll offset under the sticky site header and the Re:Builder app bar <html> gets scroll-padding-top: --ac-page-top + --ac-scroll-top-offset, so keyboard focus, scrollIntoView, #anchors and find in page stop below the sticky bars instead of behind them (WCAG 2.2 SC 2.4.11). ac-app-bar raises --ac-scroll-top-offset on <html> while it sticks (shadow DOM: :has() cannot see it) and gets a sticky input that replaces the editor's .static override. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Re:Builder e2e: scrollIntoView puts the card below the sticky bars on its own Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ac-app-bar: offset only while a sticky bar is in the document The Decks list stays mounted, detached, while a deck is open (DecksListReuseStrategy): a lifecycle refcount kept its bar's offset after leaving the list (desktop after a resize, editor search view). The bars are now checked after every render, and only those in the document count. Position override through a host style binding; shorter docs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…fects; Collection physique lists its Uniques (#149) * Re:Builder: the account tabs show the Uniques with their stats and effects; Collection physique lists its Uniques - Propriété numérique and Collection physique: the APIs give a Unique's costs, not its effects (and the ownership API names its powers forest/mountain/ocean), so the Uniques showed 0 · 0 · 0 and no text. Their faces now come from the cards API batch, through one CardsApiService.uniqueFaces() shared with the editor and cached for the session. - Collection physique offers the Unique rarity (on by default) and the « légales » filter, like the other account tabs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Re:Builder e2e: the Unique of the account tabs is centered in its evidence Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…; a clear message when an alt art lacks copies (#150) - Card zoom: the card shrinks to leave room for the copies, the illustrations and « Accéder au détail », which always show whole; window heights in dvh instead of vh (phone browsers' bars). - Alt arts: picking an illustration once more than owned says « Vous n'avez pas assez d'exemplaires de cet art alternatif. » without calling the service; a 409 from the service says the same instead of the references and counts. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
#151) * SPA pages: the server's skeleton stays until the page draws, no empty frame in between The runtime overlays the placeholder and the plugin container in one grid cell and removes the placeholder once the container has some height. Grid items stretch to the cell, so the container was as tall as the placeholder as soon as it was mounted: the placeholder went before the app drew its page, and phones showed an empty frame between the two skeletons. The container now keeps its content's height (align-self: start) while they overlap. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * SPA pages: the first paint is the page's skeleton, not the site header over an empty page The site's hidden menus (mobile menu, account popover, sidebar: ~27 KB) come between the header and the mount point in the HTML, so the browser painted the header alone for 20-50 ms before it parsed the server's skeleton. <head> now names the mount point in <link rel="expect" blocking="render"> (spaMountId()): the first paint waits until the skeleton is parsed, at about the same time the skeleton used to show. Browsers without render-blocking `expect` (Safari, Firefox) ignore it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
… in Re:Builder The ownership service's « Global » mode rewrote every deck with the global preferences, on the site and on Board Game Arena (apply-to-deck), so a deck could not keep prints of its own. The settings page now sets default alt arts only, and a deck stores the prints it uses: - Settings (plugin ownership): one mode, « Arts alternatifs par défaut », for cards and tokens. - A player still in « Global » is switched to « par deck » on their next visit (includes/func.alt-arts.php); their decks wait for their default alt arts until Re:Builder opens them (table alt_art_pending_decks). - Re:Builder: a card added from the search takes the default alt art of its copy; « Arts alternatifs » in the search lists the alt arts the player owns after their card, added as shown; the brush of a card changes its prints for the deck; « Arts par défaut » applies the defaults to the deck; the token window shows each token large with its illustrations. Import, a copy of someone else's deck and a hero picked without « Alt arts » take the defaults. - Local stack: docker-compose.ownership.yml runs the real AlteredOwnership service, with owned alt arts, default alt arts and a deck to switch from « Global ». Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…on phones, and systematic loading checks (#152) * Re:Builder on phones: the deck's app bar goes from its skeleton to its final state; the app's styles before its first screen - Editor app bar (phones): while the deck opens and its owner is unknown, a skeleton in the final layout (back button, hero, name over the rarities, save status slot, « ⋯ ») instead of « Chargement du deck… » then a plain title. The server's skeleton (placeholder.php) draws the same bar, back chevron included. - Runtime: the plugin container stays hidden (in place) and the server's skeleton stays until the shadow root's stylesheets have loaded, so no frame shows the app unstyled (10 s fallback for a stalled request). - The server's skeleton keeps the site's font through the shadow root (`:host { all: initial }` used to turn it serif). - « Nouveau deck » on phones has an in-flow first screen, so its server skeleton goes away. - Design system: `--ac-badge-height` and `ac-skeleton--badge`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Re:Builder « Mon deck » on phones: nothing moves while the owner, the alt-art mode and the rarity icons arrive - « Choisir les arts des jetons » keeps its place in skeleton while the deck's owner or the alt-art mode is not known (EditorAltArts.tokensChoice: null), in the app and in the server's skeleton: it used to push the list down when it came. - Rarity icons carry their files' sizes (width / height): sized by their height only, they took no width until loaded, and the summary's rarity row wrapped late (+24 px). First visit on a phone (CPU 6×, 4G, empty cache): CLS 0.095 → 0.002. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Re:Builder editor: the quantity steppers from the start, not a read-only « ×1 » until the owner is known DeckStore.steppersShown: the editor's rows, tiles and piles draw their steppers unless the deck is known not to be the user's. A change still waits for editable() (setQuantity, and the board's own removed-cards list). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Loading checks for every Re:Builder screen: skeleton, styles, layout shifts, in the CI and as a timeline script - tests/e2e/loading.ts: a recorder installed before the page loads (empty frame, plugin shown unstyled, skeleton font, forbidden texts, CLS with the moved boxes), throttling profiles, empty cache. - plugins/rebuilder/e2e/loading.spec.ts: every screen (screens.ts), first and second visit, phone network, desktop and mobile; CLS budgets per screen (loading-budgets.json: 0.01, or today's value for a known shift, with its reason). - tests/e2e/loading-timeline.ts (npm run loading:timeline): frame-by-frame image and report of a screen, two stacks side by side with --compare (before / after). - First paint: <link rel="expect"> now names an element after the mount point (spaFirstPaintId()). Chromium paints once the expected element is inserted, and the parser could stop inside the placeholder: about 1 load in 25 showed the site header alone first; 0 in 90 since. - AGENTS.md § Checks, the plugin's AGENTS.md and README.md say when to run them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Loading budgets: the CI's values for the editor « Aperçu » (desktop) and « Nouveau deck » (mobile, second visit) The CI measures these known shifts above the local runs: the deck's owner and the page's footer come in another order there. #154 removes them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
#154) * Re:Builder on phones: the deck's app bar goes from its skeleton to its final state; the app's styles before its first screen - Editor app bar (phones): while the deck opens and its owner is unknown, a skeleton in the final layout (back button, hero, name over the rarities, save status slot, « ⋯ ») instead of « Chargement du deck… » then a plain title. The server's skeleton (placeholder.php) draws the same bar, back chevron included. - Runtime: the plugin container stays hidden (in place) and the server's skeleton stays until the shadow root's stylesheets have loaded, so no frame shows the app unstyled (10 s fallback for a stalled request). - The server's skeleton keeps the site's font through the shadow root (`:host { all: initial }` used to turn it serif). - « Nouveau deck » on phones has an in-flow first screen, so its server skeleton goes away. - Design system: `--ac-badge-height` and `ac-skeleton--badge`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Re:Builder « Mon deck » on phones: nothing moves while the owner, the alt-art mode and the rarity icons arrive - « Choisir les arts des jetons » keeps its place in skeleton while the deck's owner or the alt-art mode is not known (EditorAltArts.tokensChoice: null), in the app and in the server's skeleton: it used to push the list down when it came. - Rarity icons carry their files' sizes (width / height): sized by their height only, they took no width until loaded, and the summary's rarity row wrapped late (+24 px). First visit on a phone (CPU 6×, 4G, empty cache): CLS 0.095 → 0.002. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Re:Builder editor: the quantity steppers from the start, not a read-only « ×1 » until the owner is known DeckStore.steppersShown: the editor's rows, tiles and piles draw their steppers unless the deck is known not to be the user's. A change still waits for editable() (setQuantity, and the board's own removed-cards list). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Loading checks for every Re:Builder screen: skeleton, styles, layout shifts, in the CI and as a timeline script - tests/e2e/loading.ts: a recorder installed before the page loads (empty frame, plugin shown unstyled, skeleton font, forbidden texts, CLS with the moved boxes), throttling profiles, empty cache. - plugins/rebuilder/e2e/loading.spec.ts: every screen (screens.ts), first and second visit, phone network, desktop and mobile; CLS budgets per screen (loading-budgets.json: 0.01, or today's value for a known shift, with its reason). - tests/e2e/loading-timeline.ts (npm run loading:timeline): frame-by-frame image and report of a screen, two stacks side by side with --compare (before / after). - First paint: <link rel="expect"> now names an element after the mount point (spaFirstPaintId()). Chromium paints once the expected element is inserted, and the parser could stop inside the placeholder: about 1 load in 25 showed the site header alone first; 0 in 90 since. - AGENTS.md § Checks, the plugin's AGENTS.md and README.md say when to run them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Loading checks at seven screen sizes: a CLS table per screen and width, what moved named, 1280 and 1024 px in the CI - tests/e2e/loading-matrix.ts (npm run loading:matrix): every Re:Builder screen at 360, 390, 820, 1024, 1280, 1440 and 1920 px, first and second visit, in one table, with the shifts of each load. - The recorder names what moved: the element in the box that moved (a node of the plugin's shadow root, which the layout-shift entries leave out), with two ancestors. - loading-timeline.ts: --viewport for any of these sizes, --frames for the frames at full size. - loading.spec.ts: on the desktop project, a second visit at 1280 and 1024 px too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Re:Builder: no layout shift while a screen loads, at every screen size - Deck bar (deck page, editor): one height for every deck, from the server's skeleton to the deck. Each row of text on one line (the name whole in its tooltip), the actions' columns as wide in skeleton as the buttons, and the curve, terrain totals and rarities going at widths where the name keeps about 210 px (at 1280 px it was squeezed to 89 px and the bar 317 px high). The cost curve's legend goes under the chart, so that the curve stays down to 1250 px. - « Mes decks »: the count of the tab at the width of three digits while it loads; « Nouveau deck » after the list once it has loaded; the loading notice no longer wraps to a row of its own; the community deckbuilders' banner comes with the page (the server puts the list in the placeholder) instead of pushing the page down when it arrives. - « Nouveau deck »: the server's skeleton is the app's page and, where the app's window opens, the window. - Editor: the hint, the save state and « Arts des jetons » have their place while the owner is unknown, so that the modes row does not wrap later (tablets). - New deck form on phones: the heroes' row has one height for every faction and while the heroes load. - SPA pages: the server's skeleton fills the window, as the page does, so that the footer is not pushed down; the site logo has its size. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Loading budgets: the CI's values for the editor « Aperçu » (desktop) and « Nouveau deck » (mobile, second visit) The CI measures these known shifts above the local runs: the deck's owner and the page's footer come in another order there. #154 removes them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
The search no longer lists the owned alt arts after their card: a card's plain print stands for all its prints, and a copy added from the search takes its default alt art. The brush changes the prints in the deck. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…h or drag; a card at 0 leaves the deck board A copy left free shows its default alt art, faded, and takes it; a touched illustration goes on the first free copy, a dragged one on the copy it is dropped on; a touched copy goes back to its default (slotDefaults, slotChoices). The deck board no longer keeps a card brought to 0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ne pile of the deck board, copy 1 in front On by default, remembered in the browser. The brush's copy 1 is the deck's own choice: the prints the defaults do not explain come first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… is freed for the next illustration Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…o that saving moves nothing Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… a warning (#156) * CI: check only the plugins a pull request changes A pull request that only changes files under plugins/<id>/ runs only that plugin's PHP, Node, front-end and Playwright tests; any other change runs them all, as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * CI: pass plugin ids and spec folders through the environment, restricted to safe characters Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Loading checks: a CLS over budget is a warning with a screenshot, posted as a pull request comment The CLS of a screen varies from one CI run to the next and made pull requests red for shifts they did not cause. Over budget, the loading spec now attaches a screenshot of the settled page with the boxes that moved drawn on it; the CI job "CLS warnings" pushes the screenshots to the pr-screenshots branch and keeps one pull request comment up to date. The other loading problems (empty frame, unstyled, font, forbidden text) still fail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
… on a phone Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Without a type filter the mock only searched tokens, so the default alt arts page of the local stack showed no character, spell or permanent. It now reads the Common and Rare card groups (Uniques have no alt art) 200 at a time and counts skip / take in families, as AlteredOwnership's /api/alt-arts/search does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The fan of what decks take is larger, a token's or a hero's single card much larger, and the illustrations under the keys are 200 px wide. A card of the fan or an illustration opens in core-altered-cards' card lightbox, as on the cards pages (tilt, « Accéder au détail »), without its alt-art widget since the keys of the page already choose. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… and faded A key that was off and a disabled key looked alike (60 % and 30 % opacity). A key that can be pressed now has its text in --ac-color-text-2 and a darker bottom edge at full opacity; a disabled key loses its edge and fill, in --ac-color-text-disabled. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e right As in Re:Builder's brush (step 1 the illustrations, step 2 « Ce que le deck utilise »): the card's name on top, its illustrations and keys on the left, the fan of what decks take on a panel on the right (below the illustrations on a phone). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…decks take, centred As in Re:Builder's brush: the illustrations on a band ending in a chevron, which fits into the notch of the « what decks take » panel, its fan centred vertically; on a phone the panel goes under the band, the chevron pointing down. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s sideways A family with many prints (heroes have up to 5) made rows over 1000 px tall, the fan of what decks take far from the first keys. The illustrations now stay on one line that scrolls sideways, snapping to each print, with an arrow on each side while there is more that way; on a phone two prints and the edge of the next are in view. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
While a card's line of illustrations has more on one side, a mask fades the cut illustration out on that side (10 % of the line, 96 px at most). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GET /api/decks sends every deck whatever the page: an account of 1000 decks or more got the same list again and again, until the decks API ran out of memory and the switch to « par deck » failed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The service fills each line from the family's 1st card: a deck with the alt art on one line and the plain print on another (1st card alt art, 2nd and 3rd plain) got the alt art twice when leaving « Global », though only one copy is owned. The lines of a family are now sent as one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…he chevron The e2e reads the player's mode instead of expecting « par deck ». Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Five sections (how a game plays, the world and its art, ways to play, build your own deck, who runs Altered now) with a contents sidebar that highlights the section being read. - Texts live in one JSON file per language (pages/_discover/lang), English as the fallback; includes/page-lang.php loads them. - Section 2 draws two illustrations per faction from the cards API (a standard Hero, and a non-Hero, non-Token, non-Unique card), with the artist credit. - Section 4 has a formats picker with the same comparison table for each format. - Design system: new ac-toc contents component (navigation family). - Linked from nowhere yet: no menu entry, the page only answers on its URL. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Discover page: new /pages/discover, reachable by direct URL only
Prod moves to PHP 8.4.27 first while preprod keeps 7.4 until its own runtime switch, so the PHP job runs on both versions to catch code that would only break one of them. The ownership mock of the e2e stack moves to 8.4 for consistency. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Migrate to PHP 8.4.27 (preprod)
The PHP job ran on 7.4 and 8.4 while preprod kept PHP 7.4 after prod had switched. Both environments now run 8.4.27, so 7.4 no longer guards any runtime: the job goes back to a single 8.4 run, and the docs stop asking for 7.4-compatible code. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Re:Builder conflicts: the PR's alt-art editor and deck board kept, with preprod's loading states (DeckStore.steppersShown, skeletons while the deck's owner and the alt-art mode are not known, now for « Appliquer les arts par défaut » too). The e2e createServerDeck helper takes the copies. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ger keeps the player in « Global » Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A content creator filming the site leaked their address: the homepage newsletter field was filled with the account's e-mail. - Newsletter: the field is always empty; signed-in users get « Use my account address », which takes the address from the session. - Design system: ac-tooltip and ac-masked (tooltip.css), dsMaskEmail() and ac_masked_email(): c•••@gmail.com, the full address in a tooltip on hover or focus. - Account menu, account page and the hello-world demo page show the address masked. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…, no layout shift at 1024 px The switch and « Arts par défaut » come with the deck's owner: at 1024 px the row wrapped then, and the board moved 44 px down (CLS 0.043). Their skeletons, at their widths, make the row wrap before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Never show the signed-in user's e-mail address in full
CI: drop the PHP 7.4 lint now that preprod runs 8.4.27
Default alt arts: one setting for the defaults, each deck keeps its own prints (Re:Builder)
|
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


No description provided.