Skip to content

WT-1193: Cards refactor#1371

Draft
lucianoratamero wants to merge 20 commits into
mainfrom
WT-1193-cards-refactor
Draft

WT-1193: Cards refactor#1371
lucianoratamero wants to merge 20 commits into
mainfrom
WT-1193-cards-refactor

Conversation

@lucianoratamero

@lucianoratamero lucianoratamero commented May 20, 2026

Copy link
Copy Markdown
Collaborator

One-line summary

This PR adds the Filled Card variant and refactors the cards to consolidate similar cards into a shared template.
This is based on the landing page follow-ups PR, so I'll wait for that one to be merged before this one.

Significant changes and points to review

Since I used the illustration card as base for the new generic card block/component, I also needed to search for all the places that were statically using the outline and illustration cards. I think I found them all, but I could've missed something.

Issue / Bugzilla link

https://mozilla-hub.atlassian.net/browse/WT-1193

Testing

Take a look at the new filled card in the pattern library, run the BE and visual regression tests, and check for possible places I could've forgotten to apply the new block/component.

@lucianoratamero lucianoratamero changed the base branch from main to WT-1174-landing-page-follow-up May 20, 2026 22:36
@codecov

codecov Bot commented May 20, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 79.39%. Comparing base (aa94c2e) to head (b2971d6).

Additional details and impacted files
@@                       Coverage Diff                       @@
##           WT-1174-landing-page-follow-up    #1371   +/-   ##
===============================================================
  Coverage                           79.38%   79.39%           
===============================================================
  Files                                 152      152           
  Lines                               10337    10341    +4     
===============================================================
+ Hits                                 8206     8210    +4     
  Misses                               2131     2131           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new “Filled” card variant and refactors Flare 2026 card usage by consolidating multiple card types into a shared card-2026 template/component, updating CMS blocks, templates, pattern-library examples, CSS, and visual regression coverage accordingly.

Changes:

  • Added Filled card pattern-library example + Playwright visual regression coverage.
  • Refactored templates/CMS blocks to use card-2026 in place of older card include patterns.
  • Updated Flare 2026 card CSS + tests to match the new markup/classes.

Review note: I reviewed this using the repository’s Copilot custom instructions and AGENTS.md.

Reviewed changes

Copilot reviewed 27 out of 31 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
tests/playwright/specs/visual-regression/illustration-card-variants.spec.js Updates Pattern Library URL path for the illustration card variants visual test.
tests/playwright/specs/visual-regression/cards-list-filled.spec.js Adds visual regression coverage for the new filled cards list (light/dark).
springfield/firefox/templates/firefox/landing/year-in-review-2025-flare26.html Migrates highlight cards to card-2026.
springfield/firefox/templates/firefox/landing/get-new.html Migrates “favorite browser” cards to card-2026.
springfield/firefox/templates/firefox/enterprise/index.html Migrates enterprise icon/sticker cards to card-2026 and moves sticker content into content:media.
springfield/firefox/templates/firefox/developer/index-flare26.html Migrates developer page card grids to card-2026.
springfield/firefox/templates/firefox/default/landing.html Migrates default-landing icon cards to card-2026.
springfield/firefox/templates/firefox/browsers/mobile/index.html Migrates mobile download cards to card-2026.
springfield/firefox/templates/firefox/browsers/desktop/base.html Migrates desktop download platform cards to card-2026.
springfield/cms/tests/test_blocks.py Updates CMS rendering tests to reflect new card markup/class structure.
springfield/cms/templates/pattern-library/components/flare-26/cards-list/illustration-card_variants.yaml Updates illustration-card variant data to use media_type.
springfield/cms/templates/pattern-library/components/flare-26/cards-list/illustration-card_variants.html Updates pattern-library illustration card variants to render via card-2026.
springfield/cms/templates/pattern-library/components/flare-26/cards-list/cards-list_outlined.html Updates outlined cards list example to use card-2026 with variant="outlined" + media slot.
springfield/cms/templates/pattern-library/components/flare-26/cards-list/cards-list_filled.yaml Adds pattern-library context data for filled cards list.
springfield/cms/templates/pattern-library/components/flare-26/cards-list/cards-list_filled.html Adds pattern-library template for filled cards list using card-2026 with variant="filled".
springfield/cms/templates/components/card-2026.html Refactors card-2026 into a shared card template with variant + media_type logic and updated classes.
springfield/cms/templates/cms/blog_index_page.html Migrates blog index cards to card-2026.
springfield/cms/templates/cms/blocks/related-article-card.html Migrates related article card block to card-2026.
springfield/cms/templates/cms/blocks/icon-card-2026.html Migrates icon card block to card-2026 with media_type="icon".
springfield/cms/templates/cms/blocks/card-2026.html Consolidates multiple CMS card styles into a unified card-2026 block template and computes variant/media_type.
springfield/cms/templates/cms/blocks/article-cards-list.html Migrates article cards list block to card-2026 with explicit media_type.
springfield/cms/templates/cms/article_index_page.html Migrates article index cards to card-2026, adding explicit outlined variant for outline-card mode.
springfield/cms/blocks.py Introduces a variant setting on card settings and replaces the old outlined card block factory with a generalized CardBlock.
media/css/cms/variables/flare26-light-theme.css Adds a new theme variable for filled card background color (light theme).
media/css/cms/variables/flare26-dark-theme.css Adds a new theme variable for filled card background color (dark theme).
media/css/cms/pages/flare26-developer-edition.css Removes developer page overrides tied to old sticker/illustration-card structure.
media/css/cms/components/flare26-card.css Refactors card styling to be variant-driven (.fl-card-outlined / .fl-card-filled) and updates illustration-card layout hooks.
Comments suppressed due to low confidence (6)

springfield/cms/templates/components/card-2026.html:31

  • fix (blocking): card-2026 can currently emit invalid/unstyled class combinations for media cards. When contents.media is present and variant is empty, the template does not add fl-card-outlined/fl-card-filled, but .fl-card no longer supplies padding/background/hover styles (those are now on the variant classes), so illustration/icon/sticker cards can render without core card styling. Also, when media_type is ''/None, the template generates fl-illustration--card / fl-illustration-None-card. Consider defaulting media cards to an explicit card variant (e.g. outlined) and treating falsy media_type as the default ("media") so the generated classes stay valid.
    springfield/cms/templates/cms/blocks/card-2026.html:25
  • fix (blocking): media_type is set to None when there is no media/icon/sticker, which will typically render as the string "None" in the include attribute and can lead to fl-illustration-None-card if media is later present. Use an empty string or omit the attribute when unset, and ensure the default illustration-card case passes/normalizes to media_type="media" (rather than "").
    springfield/firefox/templates/firefox/developer/index-flare26.html:66
  • fix (blocking): The media cards in this list omit media_type, which can produce fl-illustration--card and/or omit the card theme variant class. Pass media_type="media" (or normalize to it) so default illustration-card styling is applied consistently.
        <include:cards-list cards_per_row="2">
          <include:card-2026 expand_link>
            <content:media>
              <img src="{{ static('img/firefox/developer/hero-inactive-css.png') }}"
                srcset="{{ static('img/firefox/developer/hero-inactive-css-high-res.png') }} 2x"
                alt="{{ ftl('firefox-developer-inactive-css') }}"
                loading="lazy" width="560" height="280" />
            </content:media>
            <content:heading>

springfield/cms/templates/cms/blocks/related-article-card.html:15

  • fix (blocking): This block includes media but doesn’t pass media_type, which can generate an invalid fl-illustration--card class and miss the card theme variant styling. Pass/normalize media_type="media" here (or update the component to default correctly when media is present).
<include:card-2026 expand_link="true">
  <content:media>
    {% set img = value.get_sticker() %}
    {% if img %}
      {{ image(img, "width-400") }}
    {% else %}
      <img src="/media/img/logos/firefox/firefox-logo.svg" alt="" />
    {% endif %}
  </content:media>

springfield/cms/templates/pattern-library/components/flare-26/cards-list/illustration-card_variants.yaml:8

  • fix: For the "Default" illustration-card example, media_type is set to an empty string. With the current card-2026 class logic, this will produce an invalid fl-illustration--card class. Use media_type: "media" (or omit and let the component normalize to the default) to keep the generated CSS class valid.
    springfield/cms/tests/test_blocks.py:2724
  • fix: find_all(..., class_=[...]) matches elements with any of the classes, not all of them. If the page layout changes, this could pick up non-icon illustration cards too. Prefer querying for fl-illustration-icon-card specifically (or require both classes via a CSS selector) to keep the test precise.
    icon_section = sections[1]
    icon_card_articles = icon_section.find_all("article", class_=["fl-illustration-card", "fl-illustration-icon-card"])

Comment on lines +64 to 65
<include:card-2026 variant="sticker">
<content:media>
Comment on lines +343 to 346
<include:card-2026>
<content:media>
<img src="/media/img/firefox/landing/get/kit-with-google.png" srcset="/media/img/firefox/landing/get/kit-with-google-high-res.png 2x" width="340" height="400" alt="" aria-hidden />
</content:media>
Comment on lines +39 to 42
<include:card-2026 variant="icon">
<content:media>
<img src="{{ static('protocol/img/icons/brand/violet/no-eye.svg') }}" width="48" height="48" alt="" loading="lazy">
</content:media>
Comment on lines 125 to 129
<include:cards-list>
<include:illustration-card-2026 variant="sticker">
<include:card-2026 variant="sticker">
<content:media>
<img src="/media/{{ card1_image_url }}" aria-hidden="true" />
</content:media>
Comment on lines +152 to 153
<include:card-2026 variant="sticker" media_type="sticker" expand_link>
<content:media>
<include:cards-list container_width="fill">
{% for block in page.featured_articles[4:] %}
<include:illustration-card-2026 expand_link="true">
<include:card-2026 expand_link="true">
Comment thread springfield/cms/blocks.py
Comment on lines +2002 to 2011
def CardBlock(allow_uitour=False, *args, **kwargs):
"""Factory function to create OutlinedCardBlock with appropriate button types.

Args:
allow_uitour: If True, allows both regular buttons and UI Tour buttons.
If False, only allows regular buttons.
"""

class _OutlinedCardBlock(blocks.StructBlock):
class _CardBlock(blocks.StructBlock):
settings = BaseCardSettings()

assert icon_card_section.find(class_="fl-card-grid")
icon_card_articles = icon_card_section.find_all("article", class_="fl-illustration-card fl-illustration-icon-card")
icon_card_articles = icon_card_section.find_all("article", class_=["fl-illustration-card", "fl-illustration-icon-card"])
Base automatically changed from WT-1174-landing-page-follow-up to main May 26, 2026 19:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants