Repository navigation
feat(layout): show the unofficial-content notice and source attribution on every page - #67
Merged
Merged
Conversation
Issue #34. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fable, Mode A: needs revision, nothing blocking. The scanner policy is compared by directives (its nonce differs per request), the footer sits directly after short content, a type supplies its lines in display order, and ADR 0018's consequence is updated with the card page. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Maintainer's rulings of 2026-10-11, relayed by the coordinator: 'Fan Content Policy' links to Wizards' policy page and 'Scryfall' to scryfall.com, so a notice line carries link data; README.md is left out of this PR. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fable, Mode A, second pass: nothing blocking. A phrase matches once and exactly, an address is an absolute https URI, identical lines are defined, and a footer link is a brand link with no target. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Approved by the maintainer on 2026-10-11, relayed by the coordinator. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rendered from the per-phase commits of the local 018-plan-phases branch, where each phase's specs and RuboCop were green. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fable, read-only: ready to execute, nothing blocking. The phone test frame is shorter, a stale CSS comment goes, link phrases marked html_safe stay plain text, and the scanner link case is listed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The maintainer approved the plan with one change: the shell is marked c-shell--footed where the plan used a :has() selector. Phases 2 and 3 were re-proved red then green on the scratch branch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Plan 018, Phase 0: The contract and its collector. A source may supply its footer lines through an optional .content_notice hook; a line is plain text with the phrases of it that link out. Ruling: executed in the session from the plan's tested phase commit, not by a subagent - the brief allows reusing the scratch commits - costs a re-run through subagents if that is wanted. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Plan 018, Phase 1: The Magic catalog's notice. The policy's wording with Collector as the title, then the attribution, each with its link. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Plan 018, Phase 2: The footer on every page. The layout reads the registered sources' lines once, marks the shell c-shell--footed when there are any and renders one footer after the main content. The card page's own attribution line and its rule go. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Plan 018, Phase 3: Presentation and the design-system pattern. Small print under a divider on the page gutter, with brand links. Below 640px the footer takes the tab bar's clearance from c-main through the shell's c-shell--footed class, so its last line stops above the bar. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Plan 018, Phase 4: Records. The card page's attribution is no longer a core exception, and the footer's core spec is a second guard. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Plan 018, Phase 5: Integration Verification. bin/ci passed on 134ce3e with 1178 examples, 0 failures, 1 pending. Three checks that need a real phone are listed as owed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fable, Mode B: spec-aligned, nothing blocking. One count corrected. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A layout-set class over :has() (maintainer's choice), one subagent per phase even for a small plan (maintainer's feedback), how the prototype branch was built, and three narrow-frame facts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Spec 018: four faults only a whole-suite run or a broken rule showed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
What changed
Every page now ends with a footer carrying Wizards of the Coast's Fan Content Policy notice and the Scryfall attribution. Until now the app had no unofficial-content notice anywhere, and its only attribution was one line on the card page, while the collection, search results and the scanner showed card images with none. Research 016 lists both as gaps for any instance, and ruling 28 asked for this footer.
.content_notice;MTG::Scryfall::Sourcesupplies the policy's notice (word for word, with "Collector" as the title) and "Card data and images provided by Scryfall." The core (Catalog::ContentNotice, the layout, thelayouts/footerpartial) names no collectible, source or rights holder, andspec/footer_core_spec.rbguards that (ADR 0018, updated here).httpsaddress on a phrase that occurs exactly once. The footer holds text and links only.Turbo-Framerequest, a Turbo Stream, the health check) carry none.c-shell--footedand the footer takes the bar's clearance fromc-main, so there is no empty band before it.Footerpattern: its own block at the end ofcollector/additions.css,docs/design-system/components/Footer.md, and a README line.Documents
:has()selector)Verification
bin/cipasses: RuboCop, Brakeman, bundler-audit, importmap audit and RSpec with 1178 examples, 0 failures, 1 pending (the art-agreement check, which needs a local cache and is unrelated). Every acceptance criterion (AC-1.1 to AC-4.4) is met by a passing example; the table is in the verification document. A read-only implementation review found the code spec-aligned and identical to the plan.Not covered by an example: a Turbo morph refresh, touch targets, and following a footer link from the scanner mid-sitting. The "runs no query" example counts queries at the model, not around a page render.
Owed from the maintainer
On a real phone, since headless Firefox has no safe-area inset and no touch:
/scannerand come back: the camera starts again and the sitting still lists the card.Expected conflicts with the spec 019 PR (issue #35, uncropped card images)
Both branches add adjacent lines in the same places. Keep both sides in each:
app/assets/stylesheets/collector/additions.css(each appends its own block);docs/design-system/README.md, after the spec 015 "App additions" line;spec/design_system_files_spec.rb;RSpec/DescribeClasslist in.rubocop.yml.This PR removes one line inside the card page's block of
additions.css(.c-attribution) and one line ofcatalog/entries/show.html.erb; it touches no image rule.Screenshots
From test data, so the cards show their names on blank cards. Phone shots are a 390 × 844 frame scrolled to the end of the page.
Closes #34
🤖 Generated with Claude Code