From 54303914ce48358cd87418ba532fe486fdc011e4 Mon Sep 17 00:00:00 2001 From: DrJfrost Date: Thu, 12 Mar 2026 18:52:18 -0500 Subject: [PATCH 01/55] =?UTF-8?q?Progress=20on=20home=20page=E2=80=94some?= =?UTF-8?q?=20components=20still=20need=20adjustment.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/urls.py | 6 + core/views.py | 147 +++++++++++++++++++++++ static/css/v3/components.css | 1 + static/css/v3/header.css | 2 + static/css/v3/heros.css | 1 + static/css/v3/v3-homepage.css | 151 ++++++++++++++++++++++++ templates/base.html | 8 +- templates/v3/homepage.html | 71 +++++++++++ templates/v3/includes/_event_cards.html | 15 ++- 9 files changed, 399 insertions(+), 3 deletions(-) create mode 100644 static/css/v3/v3-homepage.css create mode 100644 templates/v3/homepage.html diff --git a/config/urls.py b/config/urls.py index 498f31a0e..e01009b7d 100644 --- a/config/urls.py +++ b/config/urls.py @@ -31,6 +31,7 @@ TermsOfUseView, PrivacyPolicyView, V3ComponentDemoView, + V3HomepageView, ModernizedDocsView, RedirectToDocsView, RedirectToHTMLDocsView, @@ -250,6 +251,11 @@ staff_member_required(V3ComponentDemoView.as_view()), name="v3-demo-components", ), + path( + "v3/homepage/", + V3HomepageView.as_view(), + name="v3-homepage", + ), path("libraries/", LibraryListDispatcher.as_view(), name="libraries"), path( "libraries///", diff --git a/core/views.py b/core/views.py index a8fb08380..6edb094b3 100644 --- a/core/views.py +++ b/core/views.py @@ -1316,3 +1316,150 @@ def get_context_data(self, **kwargs): context["example_library_not_found"] = library_slug context["example_library_slug"] = library_slug return context + + +class V3HomepageView(TemplateView): + """Future v3 homepage at /v3/homepage/. Reuses v3 includes; does not replace current site homepage.""" + + template_name = "v3/homepage.html" + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["hero_image_url"] = f"{settings.STATIC_URL}img/v3/home-page/heros.png" + context["popular_terms"] = [ + {"label": "Networking"}, + {"label": "Math"}, + {"label": "Data processing"}, + {"label": "Concurrency"}, + {"label": "File systems"}, + {"label": "Testing"}, + ] + context["event_list"] = [ + { + "title": "Boost 1.90.0 closed for major changes", + "description": "Release closed for major code changes. Still open for serious problem fixes and docs changes without release manager review.", + "date": "29/10/25", + "datetime": "2025-10-29", + }, + { + "title": "Boost 1.90.0 closed for beta", + "description": "Release closed for all changes", + "date": "29/10/25", + "datetime": "2025-10-29", + }, + ] + context["event_primary_btn_text"] = "Download latest release" + context["event_primary_btn_url"] = reverse("releases-most-recent") + context["event_secondary_btn_text"] = "View events calendar" + context["event_secondary_btn_url"] = reverse("calendar") + from datetime import date + avatar_url = f"{settings.STATIC_URL}img/v3/demo_page/Avatar.png" + badge_url = f"{settings.STATIC_URL}img/v3/demo_page/Badge.svg" + context["homepage_posts"] = [ + { + "title": "Chaotic Attractors with Boost.OdeInt, a talk by Richard Thomson at the Utah C++ Programmers Group", + "url": "#", + "date": date(2025, 3, 3), + "category": "Issues", + "tag": "beast", + "author": {"name": "Christopher Kormanyos", "role": "Contributor", "avatar_url": avatar_url, "role_badge": badge_url, "show_badge": True}, + }, + { + "title": "A talk by Richard Thomson at the Utah C++ Programmers Group", + "url": "#", + "date": date(2025, 3, 3), + "category": "Issues", + "tag": "beast", + "author": {"name": "Dave Abrahams", "role": "Contributor", "avatar_url": avatar_url, "role_badge": badge_url, "show_badge": True}, + }, + ] + context["homepage_posts_view_all_url"] = reverse("news") + context["code_demo_hello"] = """#include +int main() { + std::cout << "Hello, Boost."; +}""" + context["community_cards"] = [ + { + "title": "Get help", + "description": "Tap into quick answers, networking, and chat with 24,000+ members.", + "icon_name": "info-box", + "cta_label": "Start here", + "cta_href": reverse("community"), + }, + { + "title": "Contribute", + "description": "Learn how to test or evaluate library submissions, or submit your own.", + "icon_name": "bullseye-arrow", + "cta_label": "Start here", + "cta_href": reverse("community"), + }, + { + "title": "Stay updated", + "description": "Get updates on the latest releases, fixes and announcements.", + "icon_name": "device-tv", + "cta_label": "Start here", + "cta_href": reverse("releases-most-recent"), + }, + { + "title": "Find work", + "description": "See who's looking for the C++ skills you've got.", + "icon_name": "human", + "cta_label": "Start here", + "cta_href": "#", + }, + ] + context["community_cta_url"] = reverse("community") + context["why_boost_cards"] = [ + {"title": "Performant", "description": "Optimized for production at any scale, Boost outperforms many standard benchmarks.", "icon_name": "bullseye-arrow"}, + {"title": "Peer-reviewed", "description": "Well tested by members of the C++ standards committee.", "icon_name": "get-help"}, + {"title": "Portable", "description": "Works across all platforms, compilers, and C++ standards.", "icon_name": "link"}, + {"title": "Innovative", "description": "Over 40 Boost libraries have become part of the C++ standard over the past 25 years.", "icon_name": "bullseye-arrow"}, + {"title": "Community-powered", "description": "Contributing to Boost builds credibility, sharpens skills, and advances careers.", "icon_name": "human"}, + {"title": "Known worldwide", "description": "Used in countless projects, you've probably encountered Boost without realizing it.", "icon_name": "link"}, + {"title": "Free", "description": "Open source now and always, thanks to the Boost Software License.", "icon_name": "check"}, + {"title": "Production-ready", "description": "Battle-tested in critical systems across industries around the globe.", "icon_name": "bullseye-arrow"}, + ] + context["stats_bars"] = [ + {"label": "1.70.0", "height_px": 78}, + {"label": "1.71.0", "height_px": 121}, + {"label": "1.72.0", "height_px": 74}, + {"label": "1.73.0", "height_px": 86}, + {"label": "1.74.0", "height_px": 100}, + {"label": "1.75.0", "height_px": 86}, + {"label": "1.76.0", "height_px": 36}, + {"label": "1.77.0", "height_px": 21}, + {"label": "1.78.0", "height_px": 98}, + {"label": "1.79.0", "height_px": 61}, + ] + context["testimonial_data"] = { + "heading": "What engineers are saying", + "testimonials": [ + { + "quote": "I use Boost daily. I absolutely love it. It's wonderful. I could not do my job w/o it. Much of it is in the new C++11 standard too.", + "author": { + "name": "Christopher Kormanyos", + "avatar_url": f"{settings.STATIC_URL}img/v3/demo_page/Avatar.png", + "role": "Author", + "role_badge": f"{settings.STATIC_URL}img/v3/demo_page/Badge.svg", + }, + }, + ], + } + context["library_intro"] = { + "library_name": "Boost.Core.", + "description": "Lightweight utilities that power dozens of other Boost libraries", + "authors": [ + {"name": "Vinnie Falco", "role": "Author", "avatar_url": f"{settings.STATIC_URL}img/v3/demo_page/Avatar.png", "badge_url": f"{settings.STATIC_URL}img/v3/demo_page/Badge.svg", "bio": "Big C++ fan. Not quite kidney-donation level, but close."}, + {"name": "Alex Wells", "role": "Contributor", "avatar_url": f"{settings.STATIC_URL}img/v3/demo_page/Avatar.png", "bio": "C++ enthusiast who has worked at Intel and Microsoft."}, + {"name": "Dave Abrahams", "role": "Maintainer", "avatar_url": f"{settings.STATIC_URL}img/v3/demo_page/Avatar.png", "badge_url": f"{settings.STATIC_URL}img/v3/demo_page/Badge.svg", "bio": "Contributor to Boost since 2009."}, + ], + "cta_url": reverse("library-detail", kwargs={"version_slug": "latest", "library_slug": "core"}), + } + context["build_anything_card"] = { + "title": "Build anything with boost", + "description": "Use, modify, and distribute Boost libraries freely. No binary attribution needed.", + "image_url": f"{settings.STATIC_URL}img/v3/solo-images/beaver-computer-blow-up.png", + "cta_label": "See license details", + "cta_url": "https://www.boost.org/users/license.html", + } + return context diff --git a/static/css/v3/components.css b/static/css/v3/components.css index f422d3acd..2844ddfe6 100644 --- a/static/css/v3/components.css +++ b/static/css/v3/components.css @@ -25,3 +25,4 @@ @import './learn-cards.css'; @import './terms-of-use.css'; @import './thread-archive-card.css'; +@import './v3-homepage.css'; diff --git a/static/css/v3/header.css b/static/css/v3/header.css index 877ae2f16..7282cfbe4 100644 --- a/static/css/v3/header.css +++ b/static/css/v3/header.css @@ -20,6 +20,8 @@ max-width: var(--header-width); margin: 0 auto; color: var(--color-text-primary, var(--text-color)); + position: absolute; + z-index: 10; } @media (min-width: 1440px) { diff --git a/static/css/v3/heros.css b/static/css/v3/heros.css index 4a8685d14..781ff7793 100644 --- a/static/css/v3/heros.css +++ b/static/css/v3/heros.css @@ -24,6 +24,7 @@ justify-content: space-between; align-items: center; background: var(--color-surface-weak-accent-yellow-homepage); + margin-bottom: var(--space-large, 16px); } .hero-home__block { diff --git a/static/css/v3/v3-homepage.css b/static/css/v3/v3-homepage.css new file mode 100644 index 000000000..c26460c26 --- /dev/null +++ b/static/css/v3/v3-homepage.css @@ -0,0 +1,151 @@ +/* + V3 Homepage layout – future replacement homepage at /v3/homepage/. + Composes existing v3 card components; this file only defines grid and spacing. +*/ + +.v3-homepage { + background: var(--color-bg-primary, #f7fdfe); + min-height: 50vh; +} + +.v3-homepage__content { + display: flex; + flex-direction: column; + gap: var(--space-xxl, 64px); + align-items: stretch; + max-width: 1440px; + margin: 0 auto; + padding: 0 var(--space-large, 16px); + box-sizing: border-box; +} + +.v3-homepage__row { + display: flex; + flex-direction: column; + gap: var(--space-xlarge, 24px); +} + +.v3-homepage__row--top { + display: grid; + grid-template-columns: 1fr 1fr 1fr; + gap: var(--space-large, 16px); + align-items: start; +} + +.v3-homepage__col { + min-width: 0; +} + +.v3-homepage__col--left { + display: flex; + flex-direction: column; + gap: var(--space-large, 16px); +} + +.v3-homepage__col--middle { + display: flex; + flex-direction: column; +} + +.v3-homepage__col--right { + display: flex; + flex-direction: column; + gap: var(--space-large, 16px); +} + +.v3-homepage__join-card { + background: var(--color-surface-weak-yellow, #fbeba9); + border-radius: var(--border-radius-xl, 12px); + border: 1px solid var(--color-stroke-weak, rgba(5, 8, 22, 0.1)); + padding: var(--space-large, 16px); + display: flex; + flex-direction: column; + gap: var(--space-large, 16px); +} + +.v3-homepage__community-cards { + display: flex; + flex-direction: column; + gap: var(--space-s, 4px); +} + +.v3-homepage__row--why { + width: 100%; +} + +.v3-homepage__row--stats { + display: grid; + grid-template-columns: 1fr 1fr; + gap: var(--space-large, 16px); + align-items: stretch; +} + +.v3-homepage__row--bottom { + display: grid; + grid-template-columns: minmax(0, 458px) minmax(0, 1fr); + gap: var(--space-large, 16px); + align-items: start; +} + +.v3-homepage__build-body { + display: flex; + flex-direction: row; + gap: var(--space-large, 16px); + align-items: flex-start; + padding: 0 var(--space-large, 16px); +} + +.v3-homepage__build-body .library-intro-card__description { + flex: 1; + margin: 0; +} + +.v3-homepage__build-img { + flex-shrink: 0; + width: 205px; + height: 205px; + border-radius: var(--border-radius-default, 8px); + object-fit: cover; +} + +.v3-homepage__build-card .library-intro-card__title { + padding: 0 var(--space-large, 16px); +} + +.v3-homepage__build-card .library-intro-card__divider { + margin: 0; +} + +.v3-homepage__build-card .post-cards__cta { + padding: var(--space-large, 16px); +} + +@media (max-width: 1024px) { + .v3-homepage__row--top { + grid-template-columns: 1fr 1fr; + } + + .v3-homepage__row--stats { + grid-template-columns: 1fr; + } + + .v3-homepage__row--bottom { + grid-template-columns: 1fr; + } +} + +@media (max-width: 768px) { + .v3-homepage__row--top { + grid-template-columns: 1fr; + } + + .v3-homepage__build-body { + flex-direction: column; + } + + .v3-homepage__build-img { + width: 100%; + height: auto; + max-height: 240px; + } +} diff --git a/templates/base.html b/templates/base.html index c1a4de8d2..e75f1a376 100644 --- a/templates/base.html +++ b/templates/base.html @@ -361,13 +361,15 @@ {% endflag %} {% flag "v3" %} {% include "v3/includes/_header_v3.html" %} - {% if request.resolver_match.url_name == 'v3-demo-components' %} + {% if request.resolver_match.url_name == 'v3-homepage' %} + {% include "v3/includes/_hero_home.html" with hero_image_url=hero_image_url %} + {% elif request.resolver_match.url_name == 'v3-demo-components' %} {% include "v3/includes/_hero_home.html" with hero_image_url=hero_image_url %}
{% include "v3/includes/_hero_library.html" with doc_url="#" source_url="#" slack_url="#" github_url="#" version_tag="C++ 03" added_text="Added in 1.66.0" hero_image_url=hero_image_url %} {% endif %} {% endflag %} - {% block main_content_wrapper %}
{% endblock %} + {% block main_content_wrapper %}
{% endblock %} {% block content_header %} {% flag "v3" %} {% else %} @@ -404,9 +406,11 @@ {% endblock %}
+ {% if request.resolver_match.url_name == 'v3-demo-components' %} {% flag "v3" %} {% include "v3/examples/_v3_example_section.html" %} {% endflag %} + {% endif %} {% if not hide_footer %} {% flag "v3" %} diff --git a/templates/v3/homepage.html b/templates/v3/homepage.html new file mode 100644 index 000000000..040fbd7f1 --- /dev/null +++ b/templates/v3/homepage.html @@ -0,0 +1,71 @@ +{% extends "base.html" %} +{% load waffle_tags %} + +{% block title %}Boost C++ Libraries{% endblock %} + +{% block content %} +{% flag "v3" %} +
+
+
+
+ {% include "v3/includes/_search_card.html" with heading="What are you trying to find?" action_url="/libraries/latest/browse/" popular_terms=popular_terms %} + {% include "v3/includes/_event_cards.html" with section_heading="Upcoming Events" event_list=event_list variant="white" primary_btn_text=event_primary_btn_text primary_btn_url=event_primary_btn_url secondary_btn_text=event_secondary_btn_text secondary_btn_url=event_secondary_btn_url %} +
+
+ {% include "v3/includes/_post_cards_v3.html" with heading="Posts from the Boost community" posts=homepage_posts view_all_url=homepage_posts_view_all_url view_all_label="View all posts" variant="default" theme="teal" %} +
+
+ {% include "v3/includes/_code_block_card.html" with heading="Get started with our libraries" code=code_demo_hello language="cpp" button_text="Explore examples" button_url="/libraries/latest/browse/" %} +
+

Join developers building the future of C++

+
+ {% for card in community_cards %} + {% include "v3/includes/_content_detail_card_item.html" with title=card.title description=card.description icon_name=card.icon_name cta_label=card.cta_label cta_href=card.cta_href %} + {% endfor %} +
+
+ Explore the community +
+
+
+
+ +
+ {% include "v3/includes/_why_boost_cards.html" with section_heading="Why Boost?" why_boost_cards=why_boost_cards %} +
+ +
+ {% include "v3/includes/_stats_in_numbers.html" with heading="Boost in numbers" description="Some detail about a graph in here" bars=stats_bars theme="default" primary_cta_label="Boost Org on GitHub" primary_cta_url="https://github.com/boostorg" %} + {% include "v3/includes/_testimonial_card.html" with heading=testimonial_data.heading testimonials=testimonial_data.testimonials %} +
+ +
+ {% if library_intro %} +
+ {% include "v3/includes/_library_intro_card.html" with library_name=library_intro.library_name description=library_intro.description authors=library_intro.authors cta_url=library_intro.cta_url %} +
+ {% endif %} + {% if build_anything_card %} +
+
+

{{ build_anything_card.title }}

+
+
+

{{ build_anything_card.description }}

+ {% if build_anything_card.image_url %} + + {% endif %} +
+
+
+ {{ build_anything_card.cta_label }} +
+
+
+ {% endif %} +
+
+
+{% endflag %} +{% endblock %} diff --git a/templates/v3/includes/_event_cards.html b/templates/v3/includes/_event_cards.html index d19c2cd57..9e848b421 100644 --- a/templates/v3/includes/_event_cards.html +++ b/templates/v3/includes/_event_cards.html @@ -18,7 +18,20 @@ {% include "v3/includes/_event_cards.html" %} {% endcomment %} {% if event_list and variant %} - {% include "v3/includes/_event_cards_section.html" with section_heading=section_heading event_list=event_list variant=variant primary_btn_text=primary_btn_text primary_btn_url=primary_btn_url secondary_btn_text=secondary_btn_text secondary_btn_url=secondary_btn_url %} + {% else %} {% comment %}Gallery: all 5 variants (white, grey, yellow, beige, teal) with sample content.{% endcomment %}
{% include "v3/includes/_code_block_card.html" with heading="Get started with our libraries" code=code_demo_hello language="cpp" button_text="Explore examples" button_url="/libraries/latest/browse/" %} -
-

Join developers building the future of C++

-
+
+

Join developers building the future of C++

+
+
Explore the community
-
+
@@ -46,24 +52,7 @@

Join developers building the future of C++

{% include "v3/includes/_library_intro_card.html" with library_name=library_intro.library_name description=library_intro.description authors=library_intro.authors cta_url=library_intro.cta_url %} {% endif %} - {% if build_anything_card %} -
-
-

{{ build_anything_card.title }}

-
-
-

{{ build_anything_card.description }}

- {% if build_anything_card.image_url %} - - {% endif %} -
-
-
- {{ build_anything_card.cta_label }} -
-
-
- {% endif %} + diff --git a/templates/v3/includes/_content_detail_card_item.html b/templates/v3/includes/_content_detail_card_item.html index ef65f5c68..f341aab15 100644 --- a/templates/v3/includes/_content_detail_card_item.html +++ b/templates/v3/includes/_content_detail_card_item.html @@ -6,8 +6,9 @@ icon_name (optional) — icon name for includes/icon.html (e.g. "bullseye-arrow"). If omitted, card is rendered without icon and modifier --has-icon is not applied. title_url (optional) — if set, title is wrapped in a link - cta_label (optional) — if set with cta_href, renders a CTA link below description + cta_label (optional) — if set with cta_href, renders a CTA link below description (or span if cta_as_span) cta_href (optional) — used with cta_label for the CTA link + cta_as_span (optional) — if truthy, CTA is rendered as (use when the whole card is wrapped in a link) Usage: {% include "v3/includes/_content_detail_card_item.html" with title="Get help" description="Tap into quick answers..." icon_name="bullseye-arrow" %} With CTA: {% include "v3/includes/_content_detail_card_item.html" with title="Get help" description="..." icon_name="info-box" cta_label="Start here" cta_href="#" %} @@ -22,7 +23,11 @@

{% if title_url %}{% endif %}{{ title }}{% if title_url %}{% endif %}

{{ description }}

- {% if cta_label and cta_href %} + {% if cta_label %} + {% if cta_as_span %} + {{ cta_label }} + {% elif cta_href %} {{ cta_label }} {% endif %} + {% endif %} From 82b595bd827107fee624f146258be7b68fa7cafc Mon Sep 17 00:00:00 2001 From: DrJfrost Date: Fri, 13 Mar 2026 08:58:01 -0500 Subject: [PATCH 03/55] fix color button heros and center navbar --- static/css/v3/header.css | 2 ++ static/css/v3/heros.css | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/static/css/v3/header.css b/static/css/v3/header.css index 7282cfbe4..4345460d1 100644 --- a/static/css/v3/header.css +++ b/static/css/v3/header.css @@ -22,6 +22,8 @@ color: var(--color-text-primary, var(--text-color)); position: absolute; z-index: 10; + left: 0; + right: 0; } @media (min-width: 1440px) { diff --git a/static/css/v3/heros.css b/static/css/v3/heros.css index 781ff7793..5a19e6f13 100644 --- a/static/css/v3/heros.css +++ b/static/css/v3/heros.css @@ -69,9 +69,9 @@ align-items: flex-start; } - .heros .btn.btn-hero.btn-secondary { + .btn.btn-hero.btn-secondary { background-color: var(--color-button-secondary); - border-color: var(--color-stroke-weak); + border-color: var(--color-stroke-strong); } .hero-home__actions .btn-icon { From 0bec3208224deda399eeede216eddb2dbc04fffc Mon Sep 17 00:00:00 2001 From: DrJfrost Date: Fri, 13 Mar 2026 14:45:08 -0500 Subject: [PATCH 04/55] Improving homepage styles. --- static/css/v3/content.css | 2 +- static/css/v3/event-cards.css | 2 +- static/css/v3/heros.css | 1 + static/css/v3/post-cards.css | 2 +- templates/v3/includes/_post_cards_v3.html | 8 +++++--- 5 files changed, 9 insertions(+), 6 deletions(-) diff --git a/static/css/v3/content.css b/static/css/v3/content.css index 018f8dabc..728de449b 100644 --- a/static/css/v3/content.css +++ b/static/css/v3/content.css @@ -9,7 +9,7 @@ color: var(--color-text-primary); margin: 0; padding: var(--space-card); - border-radius: var(--border-radius-xxl); + border-radius: var(--border-radius-l); background: var(--color-bg-secondary); border: 1px solid var(--color-border); display: flex; diff --git a/static/css/v3/event-cards.css b/static/css/v3/event-cards.css index a9118e400..8e2cb5aae 100644 --- a/static/css/v3/event-cards.css +++ b/static/css/v3/event-cards.css @@ -56,7 +56,7 @@ .event-card { background: var(--color-card-bg); - border-radius: var(--border-radius-xxl); + border-radius: var(--border-radius-l); margin: 0 var(--space-card); } diff --git a/static/css/v3/heros.css b/static/css/v3/heros.css index 5a19e6f13..e33d7a7aa 100644 --- a/static/css/v3/heros.css +++ b/static/css/v3/heros.css @@ -60,6 +60,7 @@ margin: 0; align-self: stretch; letter-spacing: -4px; + z-index: 1; } .hero-home__actions { diff --git a/static/css/v3/post-cards.css b/static/css/v3/post-cards.css index 95b98da13..2000af67d 100644 --- a/static/css/v3/post-cards.css +++ b/static/css/v3/post-cards.css @@ -368,7 +368,7 @@ } .post-cards--content-card .post-cards__list { - gap: var(--space-card); + gap: 4px; } .post-cards--content-card .content-detail-icon { diff --git a/templates/v3/includes/_post_cards_v3.html b/templates/v3/includes/_post_cards_v3.html index 6250e9773..a2fa6b9dc 100644 --- a/templates/v3/includes/_post_cards_v3.html +++ b/templates/v3/includes/_post_cards_v3.html @@ -5,7 +5,7 @@ No defaults for content; only output what is passed. {% endcomment %} {% if heading or posts or view_all_url or secondary_cta_url %} -
+
{% if heading %}

{% if heading_url %} @@ -19,7 +19,9 @@

    {% for item in posts %}
  • - {% include "v3/includes/_post_card_v3.html" with post=item %} +
    + {% include "v3/includes/_post_card_v3.html" with post=item %} +
  • {% endfor %}
@@ -27,7 +29,7 @@

{% if view_all_url or secondary_cta_url %}
{% if view_all_url %} - {{ view_all_label|default:"View all" }} + {{ view_all_label|default:"View all" }} {% endif %} {% if secondary_cta_url %} {{ secondary_cta_label }} From 0c060c408f76880fbd3741b9347a17120c79b129 Mon Sep 17 00:00:00 2001 From: DrJfrost Date: Fri, 13 Mar 2026 16:46:34 -0500 Subject: [PATCH 05/55] dark mode image integration --- core/views.py | 4 ++++ static/css/v3/content.css | 1 + static/css/v3/heros.css | 26 ++++++++++++++++++++++++ static/img/v3/home-page/heros_light.png | Bin 0 -> 35746 bytes 4 files changed, 31 insertions(+) create mode 100644 static/img/v3/home-page/heros_light.png diff --git a/core/views.py b/core/views.py index 6edb094b3..6a069fc5e 100644 --- a/core/views.py +++ b/core/views.py @@ -1137,6 +1137,8 @@ def get_context_data(self, **kwargs): f"{settings.STATIC_URL}img/checker.png" ) context["hero_image_url"] = f"{settings.STATIC_URL}img/v3/home-page/heros.png" + context["hero_image_url_light"] = f"{settings.STATIC_URL}img/v3/home-page/heros.png" + context["hero_image_url_dark"] = f"{settings.STATIC_URL}img/v3/home-page/heros_light.png" context["basic_card_data"] = { "title": "Found a Bug?", "text": "We rely on developers like you to keep Boost solid. Here's how to report issues that help the whole comm", @@ -1326,6 +1328,8 @@ class V3HomepageView(TemplateView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["hero_image_url"] = f"{settings.STATIC_URL}img/v3/home-page/heros.png" + context["hero_image_url_light"] = f"{settings.STATIC_URL}img/v3/home-page/heros.png" + context["hero_image_url_dark"] = f"{settings.STATIC_URL}img/v3/home-page/heros_light.png" context["popular_terms"] = [ {"label": "Networking"}, {"label": "Math"}, diff --git a/static/css/v3/content.css b/static/css/v3/content.css index 728de449b..a14d18336 100644 --- a/static/css/v3/content.css +++ b/static/css/v3/content.css @@ -19,6 +19,7 @@ box-sizing: border-box; align-self: start; transition: background-color 0.2s ease, border-color 0.2s ease; + height: 100%; } a:hover .content-detail-icon:not(.content-detail-icon--contained) { diff --git a/static/css/v3/heros.css b/static/css/v3/heros.css index e33d7a7aa..3819b9bf5 100644 --- a/static/css/v3/heros.css +++ b/static/css/v3/heros.css @@ -204,6 +204,19 @@ display: block; } + .hero-home__image--theme-aware .hero-home__img--light { + display: block; + } + .hero-home__image--theme-aware .hero-home__img--dark { + display: none; + } + .dark .hero-home__image--theme-aware .hero-home__img--light { + display: none; + } + .dark .hero-home__image--theme-aware .hero-home__img--dark { + display: block; + } + [data-theme="dark"] .hero-home__image .hero-home__img { mix-blend-mode: screen; } @@ -380,6 +393,19 @@ display: block; } + .hero-library__image--theme-aware .hero-library__img--light { + display: block; + } + .hero-library__image--theme-aware .hero-library__img--dark { + display: none; + } + .dark .hero-library__image--theme-aware .hero-library__img--light { + display: none; + } + .dark .hero-library__image--theme-aware .hero-library__img--dark { + display: block; + } + [data-theme="dark"] .hero-library__image .hero-library__img { mix-blend-mode: screen; } diff --git a/static/img/v3/home-page/heros_light.png b/static/img/v3/home-page/heros_light.png new file mode 100644 index 0000000000000000000000000000000000000000..458ac31a5bc3348134bddc59beb95457a5c8d44a GIT binary patch literal 35746 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 Date: Fri, 13 Mar 2026 16:52:25 -0500 Subject: [PATCH 06/55] format file --- core/views.py | 113 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 94 insertions(+), 19 deletions(-) diff --git a/core/views.py b/core/views.py index 6a069fc5e..4ebd264d1 100644 --- a/core/views.py +++ b/core/views.py @@ -1137,8 +1137,12 @@ def get_context_data(self, **kwargs): f"{settings.STATIC_URL}img/checker.png" ) context["hero_image_url"] = f"{settings.STATIC_URL}img/v3/home-page/heros.png" - context["hero_image_url_light"] = f"{settings.STATIC_URL}img/v3/home-page/heros.png" - context["hero_image_url_dark"] = f"{settings.STATIC_URL}img/v3/home-page/heros_light.png" + context["hero_image_url_light"] = ( + f"{settings.STATIC_URL}img/v3/home-page/heros.png" + ) + context["hero_image_url_dark"] = ( + f"{settings.STATIC_URL}img/v3/home-page/heros_light.png" + ) context["basic_card_data"] = { "title": "Found a Bug?", "text": "We rely on developers like you to keep Boost solid. Here's how to report issues that help the whole comm", @@ -1328,8 +1332,12 @@ class V3HomepageView(TemplateView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["hero_image_url"] = f"{settings.STATIC_URL}img/v3/home-page/heros.png" - context["hero_image_url_light"] = f"{settings.STATIC_URL}img/v3/home-page/heros.png" - context["hero_image_url_dark"] = f"{settings.STATIC_URL}img/v3/home-page/heros_light.png" + context["hero_image_url_light"] = ( + f"{settings.STATIC_URL}img/v3/home-page/heros.png" + ) + context["hero_image_url_dark"] = ( + f"{settings.STATIC_URL}img/v3/home-page/heros_light.png" + ) context["popular_terms"] = [ {"label": "Networking"}, {"label": "Math"}, @@ -1357,6 +1365,7 @@ def get_context_data(self, **kwargs): context["event_secondary_btn_text"] = "View events calendar" context["event_secondary_btn_url"] = reverse("calendar") from datetime import date + avatar_url = f"{settings.STATIC_URL}img/v3/demo_page/Avatar.png" badge_url = f"{settings.STATIC_URL}img/v3/demo_page/Badge.svg" context["homepage_posts"] = [ @@ -1366,7 +1375,13 @@ def get_context_data(self, **kwargs): "date": date(2025, 3, 3), "category": "Issues", "tag": "beast", - "author": {"name": "Christopher Kormanyos", "role": "Contributor", "avatar_url": avatar_url, "role_badge": badge_url, "show_badge": True}, + "author": { + "name": "Christopher Kormanyos", + "role": "Contributor", + "avatar_url": avatar_url, + "role_badge": badge_url, + "show_badge": True, + }, }, { "title": "A talk by Richard Thomson at the Utah C++ Programmers Group", @@ -1374,11 +1389,19 @@ def get_context_data(self, **kwargs): "date": date(2025, 3, 3), "category": "Issues", "tag": "beast", - "author": {"name": "Dave Abrahams", "role": "Contributor", "avatar_url": avatar_url, "role_badge": badge_url, "show_badge": True}, + "author": { + "name": "Dave Abrahams", + "role": "Contributor", + "avatar_url": avatar_url, + "role_badge": badge_url, + "show_badge": True, + }, }, ] context["homepage_posts_view_all_url"] = reverse("news") - context["code_demo_hello"] = """#include + context[ + "code_demo_hello" + ] = """#include int main() { std::cout << "Hello, Boost."; }""" @@ -1414,14 +1437,46 @@ def get_context_data(self, **kwargs): ] context["community_cta_url"] = reverse("community") context["why_boost_cards"] = [ - {"title": "Performant", "description": "Optimized for production at any scale, Boost outperforms many standard benchmarks.", "icon_name": "bullseye-arrow"}, - {"title": "Peer-reviewed", "description": "Well tested by members of the C++ standards committee.", "icon_name": "get-help"}, - {"title": "Portable", "description": "Works across all platforms, compilers, and C++ standards.", "icon_name": "link"}, - {"title": "Innovative", "description": "Over 40 Boost libraries have become part of the C++ standard over the past 25 years.", "icon_name": "bullseye-arrow"}, - {"title": "Community-powered", "description": "Contributing to Boost builds credibility, sharpens skills, and advances careers.", "icon_name": "human"}, - {"title": "Known worldwide", "description": "Used in countless projects, you've probably encountered Boost without realizing it.", "icon_name": "link"}, - {"title": "Free", "description": "Open source now and always, thanks to the Boost Software License.", "icon_name": "check"}, - {"title": "Production-ready", "description": "Battle-tested in critical systems across industries around the globe.", "icon_name": "bullseye-arrow"}, + { + "title": "Performant", + "description": "Optimized for production at any scale, Boost outperforms many standard benchmarks.", + "icon_name": "bullseye-arrow", + }, + { + "title": "Peer-reviewed", + "description": "Well tested by members of the C++ standards committee.", + "icon_name": "get-help", + }, + { + "title": "Portable", + "description": "Works across all platforms, compilers, and C++ standards.", + "icon_name": "link", + }, + { + "title": "Innovative", + "description": "Over 40 Boost libraries have become part of the C++ standard over the past 25 years.", + "icon_name": "bullseye-arrow", + }, + { + "title": "Community-powered", + "description": "Contributing to Boost builds credibility, sharpens skills, and advances careers.", + "icon_name": "human", + }, + { + "title": "Known worldwide", + "description": "Used in countless projects, you've probably encountered Boost without realizing it.", + "icon_name": "link", + }, + { + "title": "Free", + "description": "Open source now and always, thanks to the Boost Software License.", + "icon_name": "check", + }, + { + "title": "Production-ready", + "description": "Battle-tested in critical systems across industries around the globe.", + "icon_name": "bullseye-arrow", + }, ] context["stats_bars"] = [ {"label": "1.70.0", "height_px": 78}, @@ -1453,11 +1508,31 @@ def get_context_data(self, **kwargs): "library_name": "Boost.Core.", "description": "Lightweight utilities that power dozens of other Boost libraries", "authors": [ - {"name": "Vinnie Falco", "role": "Author", "avatar_url": f"{settings.STATIC_URL}img/v3/demo_page/Avatar.png", "badge_url": f"{settings.STATIC_URL}img/v3/demo_page/Badge.svg", "bio": "Big C++ fan. Not quite kidney-donation level, but close."}, - {"name": "Alex Wells", "role": "Contributor", "avatar_url": f"{settings.STATIC_URL}img/v3/demo_page/Avatar.png", "bio": "C++ enthusiast who has worked at Intel and Microsoft."}, - {"name": "Dave Abrahams", "role": "Maintainer", "avatar_url": f"{settings.STATIC_URL}img/v3/demo_page/Avatar.png", "badge_url": f"{settings.STATIC_URL}img/v3/demo_page/Badge.svg", "bio": "Contributor to Boost since 2009."}, + { + "name": "Vinnie Falco", + "role": "Author", + "avatar_url": f"{settings.STATIC_URL}img/v3/demo_page/Avatar.png", + "badge_url": f"{settings.STATIC_URL}img/v3/demo_page/Badge.svg", + "bio": "Big C++ fan. Not quite kidney-donation level, but close.", + }, + { + "name": "Alex Wells", + "role": "Contributor", + "avatar_url": f"{settings.STATIC_URL}img/v3/demo_page/Avatar.png", + "bio": "C++ enthusiast who has worked at Intel and Microsoft.", + }, + { + "name": "Dave Abrahams", + "role": "Maintainer", + "avatar_url": f"{settings.STATIC_URL}img/v3/demo_page/Avatar.png", + "badge_url": f"{settings.STATIC_URL}img/v3/demo_page/Badge.svg", + "bio": "Contributor to Boost since 2009.", + }, ], - "cta_url": reverse("library-detail", kwargs={"version_slug": "latest", "library_slug": "core"}), + "cta_url": reverse( + "library-detail", + kwargs={"version_slug": "latest", "library_slug": "core"}, + ), } context["build_anything_card"] = { "title": "Build anything with boost", From 40b0dfc90d25cdbb040a64e3e4d03bdb881a3133 Mon Sep 17 00:00:00 2001 From: DrJfrost Date: Mon, 16 Mar 2026 16:15:15 -0500 Subject: [PATCH 07/55] Fixing the homepage button positioning design --- templates/v3/homepage.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/v3/homepage.html b/templates/v3/homepage.html index 105dadd95..baf432dbe 100644 --- a/templates/v3/homepage.html +++ b/templates/v3/homepage.html @@ -30,7 +30,7 @@

Join developers bui {% endfor %} -
+

From 07330a4be054511f94c1812f28084a3cb90120cf Mon Sep 17 00:00:00 2001 From: DrJfrost Date: Mon, 16 Mar 2026 16:18:27 -0500 Subject: [PATCH 08/55] stlye hero padding top --- static/css/v3/heros.css | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/static/css/v3/heros.css b/static/css/v3/heros.css index 180049ddd..64240f14c 100644 --- a/static/css/v3/heros.css +++ b/static/css/v3/heros.css @@ -42,13 +42,14 @@ .hero-home__block { width: 100%; max-width: 1440px; - height: 480px; + min-height: 480px; position: relative; display: flex; align-items: center; flex-direction: row; padding: 20px; align-items: end; + padding-top: 60px; } .hero-home__content { @@ -321,7 +322,7 @@ .hero-library__block { width: 100%; max-width: 1440px; - height: 480px; + min-height: 480px; display: flex; align-items: center; justify-content: space-between; From 2babb39d5530ba2edfe7325d9dc02fe78c3536b2 Mon Sep 17 00:00:00 2001 From: DrJfrost Date: Mon, 16 Mar 2026 16:26:21 -0500 Subject: [PATCH 09/55] responsive styles v3 --- static/css/v3/v3-homepage.css | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/static/css/v3/v3-homepage.css b/static/css/v3/v3-homepage.css index 04da4b796..956d1083f 100644 --- a/static/css/v3/v3-homepage.css +++ b/static/css/v3/v3-homepage.css @@ -19,6 +19,12 @@ box-sizing: border-box; } +@media (max-width: 768px) { + .v3-homepage__content { + align-items: center; + } +} + .v3-homepage__row { display: flex; flex-direction: column; From 2907b3ebf7f39cdd88977c8dde5dc416cb5d1eca Mon Sep 17 00:00:00 2001 From: DrJfrost Date: Mon, 16 Mar 2026 16:30:32 -0500 Subject: [PATCH 10/55] post cards last changes view --- templates/v3/includes/_post_cards_v3.html | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/templates/v3/includes/_post_cards_v3.html b/templates/v3/includes/_post_cards_v3.html index 9c6682305..f9a4f2c70 100644 --- a/templates/v3/includes/_post_cards_v3.html +++ b/templates/v3/includes/_post_cards_v3.html @@ -27,19 +27,14 @@

{% endif %} {% if view_all_url or secondary_cta_url %} -
+
{% if view_all_url %} {{ view_all_label|default:"View all" }} {% endif %} - {% if view_all_url or secondary_cta_url %} -
- {% if view_all_url %} - {% include "v3/includes/_button.html" with label=view_all_label|default:"View all" url=view_all_url style="primary" only %} - {% endif %} - {% if secondary_cta_url %} - {% include "v3/includes/_button.html" with label=secondary_cta_label url=secondary_cta_url style="secondary" only %} - {% endif %} -
+ {% if secondary_cta_url %} + {{ secondary_cta_label }} {% endif %} -

-{% endif %} + + {% endif %} + +{% endif %} \ No newline at end of file From a157fc63cf48b57b74ac72d18ae6f68c625d1e43 Mon Sep 17 00:00:00 2001 From: DrJfrost Date: Mon, 16 Mar 2026 17:27:17 -0500 Subject: [PATCH 11/55] fix space format --- templates/v3/includes/_post_cards_v3.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/v3/includes/_post_cards_v3.html b/templates/v3/includes/_post_cards_v3.html index f9a4f2c70..2de340410 100644 --- a/templates/v3/includes/_post_cards_v3.html +++ b/templates/v3/includes/_post_cards_v3.html @@ -37,4 +37,4 @@

{% endif %} -{% endif %} \ No newline at end of file +{% endif %} From 39de457192164257357821426b8dbc53c8f6ce36 Mon Sep 17 00:00:00 2001 From: DrJfrost Date: Wed, 18 Mar 2026 13:01:06 -0500 Subject: [PATCH 12/55] update url heros in homepage --- core/views.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/core/views.py b/core/views.py index 9c46f05fe..0c3c3b0e9 100644 --- a/core/views.py +++ b/core/views.py @@ -1448,12 +1448,18 @@ class V3HomepageView(TemplateView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context["hero_image_url"] = f"{settings.STATIC_URL}img/v3/home-page/heros.png" + # Keep the hero background + centered image consistent with the v3 demos. + context["hero_background_image_url"] = ( + f"{settings.STATIC_URL}img/v3/home-page/home-page-background.png" + ) + context["hero_image_url"] = ( + f"{settings.STATIC_URL}img/v3/home-page/home-page-foreground.png" + ) context["hero_image_url_light"] = ( - f"{settings.STATIC_URL}img/v3/home-page/heros.png" + f"{settings.STATIC_URL}img/v3/home-page/home-page-foreground.png" ) context["hero_image_url_dark"] = ( - f"{settings.STATIC_URL}img/v3/home-page/heros_light.png" + f"{settings.STATIC_URL}img/v3/home-page/home-page-foreground.png" ) context["popular_terms"] = [ {"label": "Networking"}, From fbeefd0a5930ea3a2bbd4bdc17db77edb074bd1d Mon Sep 17 00:00:00 2001 From: DrJfrost Date: Fri, 20 Mar 2026 10:55:01 -0500 Subject: [PATCH 13/55] add info hero --- core/views.py | 28 ++++++++++++++++++++++++++++ templates/base.html | 8 ++++---- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/core/views.py b/core/views.py index f7bae0b59..35c0a2a7e 100644 --- a/core/views.py +++ b/core/views.py @@ -1515,6 +1515,34 @@ def get_context_data(self, **kwargs): context["hero_image_url_dark"] = ( f"{settings.STATIC_URL}img/v3/home-page/home-page-foreground.png" ) + + # Install card data (used by v3/includes/_hero_home.html -> _install_card.html) + context["install_card_title"] = ( + "Install Boost and get started in your terminal." + ) + context["install_card_pkg_managers"] = [ + {"label": "Conan", "value": "conan", "command": "conan install boost"}, + {"label": "Vcpkg", "value": "vcpkg", "command": "vcpkg install boost"}, + ] + context["install_card_system_install"] = [ + { + "label": "Ubuntu", + "value": "ubuntu", + "command": "sudo apt install libboost-all-dev", + }, + { + "label": "Fedora", + "value": "fedora", + "command": "sudo dnf install boost-devel", + }, + { + "label": "CentOS", + "value": "centos", + "command": "sudo yum install boost-devel", + }, + {"label": "Arch", "value": "arch", "command": "sudo pacman -S boost"}, + {"label": "Homebrew", "value": "homebrew", "command": "brew install boost"}, + ] context["popular_terms"] = [ {"label": "Networking"}, {"label": "Math"}, diff --git a/templates/base.html b/templates/base.html index d76603a4b..2c4788060 100644 --- a/templates/base.html +++ b/templates/base.html @@ -363,11 +363,11 @@ {% flag "v3" %} {% include "v3/includes/_header_v3.html" %} {% if request.resolver_match.url_name == 'v3-homepage' %} - {% include "v3/includes/_hero_home.html" with hero_image_url=hero_image_url hero_background_image_url=hero_background_image_url %} + {% include "v3/includes/_hero_home.html" with install_card_id="hero-home-1" hero_image_url=hero_image_url hero_background_image_url=hero_background_image_url %} {% elif request.resolver_match.url_name == 'v3-demo-components' %} - {% include "v3/includes/_hero_home.html" with hero_background_image_url="" hero_image_url_light=hero_legacy_image_url_light hero_image_url_dark=hero_legacy_image_url_dark %} - {% include "v3/includes/_hero_home.html" with hero_image_url=hero_image_url %} - {% include "v3/includes/_hero_home.html" with hero_image_url="" hero_image_url_light="" hero_image_url_dark="" %} + {% include "v3/includes/_hero_home.html" with hero_background_image_url="" install_card_id="hero-home-1" hero_image_url_light=hero_legacy_image_url_light hero_image_url_dark=hero_legacy_image_url_dark %} + {% include "v3/includes/_hero_home.html" with install_card_id="hero-home-2" hero_image_url=hero_image_url %} + {% include "v3/includes/_hero_home.html" with install_card_id="hero-home-3" hero_image_url="" hero_image_url_light="" hero_image_url_dark="" %}
{% include "v3/includes/_hero_library.html" with hero_background_image_url="" title="Boost.Beast" description="Portable HTTP, WebSocket, and network operations using only C++11 and Boost.Asio" doc_url="#" source_url="#" slack_url="#" github_url="#" version_tag="C++ 03" added_text="Added in 1.66.0" hero_image_url_light=hero_legacy_image_url_light hero_image_url_dark=hero_legacy_image_url_dark %}
From b3a778cbbb6cd6ba24265d92b80e72d5b7058f30 Mon Sep 17 00:00:00 2001 From: Julia Hoang Date: Thu, 2 Apr 2026 08:41:50 -0700 Subject: [PATCH 14/55] refactor: make a shared template for post_card and event_card --- core/views.py | 33 +++ static/css/v3/buttons.css | 17 +- static/css/v3/card-group.css | 149 +++++++++++ static/css/v3/components.css | 2 +- static/css/v3/event-cards.css | 114 --------- static/css/v3/post-cards.css | 241 +++++++----------- static/css/v3/v3-examples-section.css | 14 +- .../v3/examples/_v3_example_section.html | 114 +++------ templates/v3/includes/_card_group.html | 42 +++ .../v3/includes/_content_event_card_item.html | 36 --- templates/v3/includes/_event_card.html | 50 ++++ templates/v3/includes/_event_cards.html | 153 ----------- .../v3/includes/_event_cards_section.html | 31 --- templates/v3/includes/_post_card.html | 58 +++++ templates/v3/includes/_post_card_v3.html | 53 ---- templates/v3/includes/_post_cards_v3.html | 36 --- 16 files changed, 488 insertions(+), 655 deletions(-) create mode 100644 static/css/v3/card-group.css delete mode 100644 static/css/v3/event-cards.css create mode 100644 templates/v3/includes/_card_group.html delete mode 100644 templates/v3/includes/_content_event_card_item.html create mode 100644 templates/v3/includes/_event_card.html delete mode 100644 templates/v3/includes/_event_cards.html delete mode 100644 templates/v3/includes/_event_cards_section.html create mode 100644 templates/v3/includes/_post_card.html delete mode 100644 templates/v3/includes/_post_card_v3.html delete mode 100644 templates/v3/includes/_post_cards_v3.html diff --git a/core/views.py b/core/views.py index ba9a0c09e..f727e3c4c 100644 --- a/core/views.py +++ b/core/views.py @@ -1374,6 +1374,39 @@ def get_context_data(self, **kwargs): }, ] + context["demo_events"] = [ + { + "title": "Boost 1.90.0 closed for major changes", + "description": "Release closed for major code changes. " + "Still open for serious problem fixes.", + "date": "29/10/25", + "datetime": "2025-10-29", + }, + { + "title": "C++ Now 2025 call for submissions", + "description": "C++ Now conference is accepting talk proposals " + "until March 15.", + "date": "12/02/25", + "datetime": "2025-02-12", + }, + { + "title": "Boost 1.89.0 released", + "description": "Boost 1.89.0 is available with updates to Asio, " + "Beast, and several other libraries.", + "date": "15/01/25", + "datetime": "2025-01-15", + }, + ] + + context["demo_events_with_links"] = [ + { + **event, + "card_url": f"#event-{i}", + "card_aria_label": event["title"], + } + for i, event in enumerate(context["demo_events"]) + ] + context["create_account_card_preview_url"] = ( f"{settings.STATIC_URL}img/checker.png" ) diff --git a/static/css/v3/buttons.css b/static/css/v3/buttons.css index 46cab4b4a..0045c6d3f 100644 --- a/static/css/v3/buttons.css +++ b/static/css/v3/buttons.css @@ -69,8 +69,8 @@ .btn-secondary:hover, .btn-secondary[data-hover] { - border-color: var(--color-secondary-dark-blue); - color: var(--color-secondary-dark-blue); + border-color: var(--color-stroke-link-accent); + color: var(--color-text-link-accent); } .btn-green { @@ -239,3 +239,16 @@ html.dark .btn-icon-library:hover { width: 24px; height: 24px; } + +/* ── Dark Mode ──────────────────────────────────── */ +html.dark { + .btn-primary:hover, .btn-primary[data-hover], .btn-green:hover, .btn-green[data-hover], .btn-yellow:hover, .btn-yellow[data-hover], .btn-teal:hover, .btn-teal[data-hover] { + background-color: var(--color-secondary-dark-blue); + border-color: var(--color-stroke-weak); + color: var(--color-text-primary); + } + + .btn.btn-hero.btn-primary:hover,.btn.btn-hero.btn-primary[data-hover] { + color: var(--color-text-on-accent); + } +} diff --git a/static/css/v3/card-group.css b/static/css/v3/card-group.css new file mode 100644 index 000000000..b5008c4a7 --- /dev/null +++ b/static/css/v3/card-group.css @@ -0,0 +1,149 @@ +/* + Card Group + Shared themed container for groups of cards (posts, events, etc.). + Structure: heading + list of items + CTA section. + Dependencies: card.css (card__cta_section), tokens +*/ + +.card-group { + font-family: var(--font-sans); + color: var(--color-text-primary); + display: flex; + flex-direction: column; + gap: var(--space-card); + padding: var(--space-card) 0; + max-width: 458px; + flex-shrink: 0; + width: 100%; + min-width: 0; + box-sizing: border-box; + border-radius: var(--border-radius-xl); + border: 1px solid var(--color-stroke-weak); + background: var(--color-surface-weak); +} + +/* ── Theme variants ────────────────────────── */ + +.card-group--default { + background: var(--color-surface-weak); + border-color: var(--color-stroke-weak); +} + +.card-group--card.card-group--default { + background: var(--color-surface-mid); + border-color: var(--color-stroke-weak); +} + +.card-group--yellow { + background: var(--color-surface-weak-accent-yellow); + border-color: var(--color-accent-strong-yellow); +} + +.card-group--green { + background: var(--color-surface-weak-accent-green); + border-color: var(--color-accent-strong-green); +} + +.card-group--teal { + background: var(--color-surface-weak-accent-teal); + border-color: var(--color-accent-strong-teal); +} + +/* ── Heading ───────────────────────────────── */ + +.card-group__heading { + margin: 0; + padding: 0 var(--space-card); + font-family: var(--font-display); + font-size: var(--font-size-large); + font-weight: var(--font-weight-medium); + line-height: 1; + letter-spacing: -0.24px; + color: var(--color-text-primary); +} + +/* ── List ──────────────────────────────────── */ + +.card-group__list { + list-style: none; + margin: 0; + padding: 0; + display: flex; + flex-direction: column; +} + +/* ── Item ──────────────────────────────────── */ + +.card-group__item { + list-style: none; + border-top: 1px solid var(--color-stroke-weak); + min-width: 0; +} + +.card-group__item:last-child { + border-bottom: 1px solid var(--color-stroke-weak); +} + +.card-group__item:has(.card-group__item-link:hover) { + background-color: var(--color-surface-mid); +} + +/* ── Variant: card ─────────────────────────── */ + +.card-group--card .card-group__list { + gap: var(--space-s); + padding: 0 var(--space-card); +} + +.card-group--card .card-group__item { + border: none; + background: var(--color-surface-weak); + border-radius: var(--border-radius-l); +} + +.card-group--card .card-group__item:last-child { + border-bottom: none; +} + +/* ── Layout: horizontal ────────────────────── */ + +.card-group--horizontal { + max-width: 933px; +} + +.card-group--horizontal .card-group__list { + flex-direction: row; + flex-wrap: nowrap; + gap: var(--space-s); + min-width: 0; + +} + +.card-group--horizontal .card-group__item { + border: none; + flex: 1 1 0; + min-width: 0; +} + +.card-group--horizontal .card-group__item:last-child { + border-bottom: none; +} + +/* ── Responsive ─────────────────────────────── */ + +@media (max-width: 767px) { + .card-group--horizontal .card-group__list { + flex-direction: column; + } +} + +/* ── Dark mode ─────────────────────────────── */ +html.dark { + .card-group { + border-color: var(--color-stroke-weak); + } + + .card-group--default { + background: var(--color-primary-grey-850); + } +} diff --git a/static/css/v3/components.css b/static/css/v3/components.css index cf79bae80..dbc1c06df 100644 --- a/static/css/v3/components.css +++ b/static/css/v3/components.css @@ -15,7 +15,6 @@ @import "./inputs-page.css"; @import "./testimonial-card.css"; @import "./card.css"; -@import "./event-cards.css"; @import "./content.css"; @import "./why-boost-cards.css"; @import "./stats.css"; @@ -42,5 +41,6 @@ @import "./markdown-card.css"; @import "./user-profile.css"; @import "./user-card.css"; +@import "./card-group.css"; @import "./post-filter.css"; @import "./library-filter.css"; diff --git a/static/css/v3/event-cards.css b/static/css/v3/event-cards.css deleted file mode 100644 index 50480d1a8..000000000 --- a/static/css/v3/event-cards.css +++ /dev/null @@ -1,114 +0,0 @@ -.event-cards--white { - background: var(--color-bg-secondary); - border: 1px solid var(--color-border); -} - -.event-cards--grey { - background: var(--color-surface-mid); - border: 1px solid var(--color-border); -} - -.event-cards--yellow { - background: var(--color-surface-weak-accent-yellow); - border: 1px solid var(--color-accent-strong-yellow); -} - -.event-cards--green { - background: var(--color-surface-weak-accent-green); - border: 1px solid var(--color-accent-strong-green); -} - -.event-cards--teal { - background: var(--color-surface-weak-accent-teal); - border: 1px solid var(--color-accent-strong-teal); -} - -.event-cards__heading { - margin: 0 var(--space-card) var(--space-medium); - padding-bottom: var(--space-default); - font-size: var(--font-size-large); - font-weight: 500; - font-family: var(--font-display); -} - -.event-cards__list { - list-style: none; - margin: 0; - padding: 0; - display: flex; - flex-direction: column; - gap: var(--space-default); -} - -.event-cards--white .event-cards__list { - gap: 0; - border-top: 1px solid var(--color-border); -} - -.event-cards__item { - list-style: none; -} - -.event-cards--white .event-cards__item { - border-bottom: 1px solid var(--color-border); - padding-top: var(--space-medium); -} - -.event-card { - background: var(--color-card-bg); - border-radius: var(--card-radius); - margin: 0 var(--space-card); -} - -.event-cards__buttons { - display: flex; - gap: var(--button-gap); - margin: 0 var(--space-card); - padding-top: var(--space-xl); -} - -.event-cards__buttons .btn { - flex: 1 1 0; - min-width: 128px; - width: auto; - text-decoration: none; -} - -.event-cards__buttons .btn:hover { - text-decoration: none; -} - -.event-cards-gallery { - display: flex; - flex-wrap: wrap; - gap: var(--space-xl); - align-items: flex-start; - justify-content: center; -} - -.event-cards-gallery__item { - max-width: 458px; - width: 100%; - min-width: 0; - flex-shrink: 0; -} - -a:hover .content-card { - background: var(--color-primary-grey-100); -} - -a:hover .content-card { - background: var(--color-primary-grey-200); - border-color: var(--color-border); -} - -html.dark .event-cards--teal, -html.dark .event-cards--yellow, -html.dark .event-cards--beige { - background: var(--color-primary-grey-850); - border: 1px solid var(--color-primary-grey-850); -} - -html.dark .event-cards--grey { - background: var(--color-primary-grey-900); -} diff --git a/static/css/v3/post-cards.css b/static/css/v3/post-cards.css index 9a662df3d..59154a29e 100644 --- a/static/css/v3/post-cards.css +++ b/static/css/v3/post-cards.css @@ -1,29 +1,11 @@ -.post-cards a { - text-decoration: none; -} +/* + Post Cards & Content Cards + Individual card item styles (post-card, content-card) and + legacy container styles still used by carousel and testimonial components. + For themed card containers, use card-group.css instead. +*/ -.post-cards .content-detail-icon__cta, -.post-cards .content-card__cta { - text-decoration: underline; - text-decoration-skip-ink: none; -} - -.post-cards .content-detail-icon__cta:hover, -.post-cards .content-detail-icon__cta:focus, -.post-cards .content-detail-icon__cta:focus-visible, -.post-cards .content-card__cta:hover, -.post-cards .content-card__cta:focus, -.post-cards .content-card__cta:focus-visible { - text-decoration: underline; -} - -.post-cards .content-detail-icon__cta:focus-visible, -.post-cards .content-card__cta:focus-visible { - outline: none; - box-shadow: 0 0 0 2px var(--color-stroke-link-accent, #1F3044); - border-radius: 4px; - display: inline-block; -} +/* ── Legacy container (carousel + testimonial) ─ */ .post-cards { font-family: var(--font-sans); @@ -42,32 +24,6 @@ background: var(--color-surface-weak); } -.post-cards--default, -.post-cards--neutral { - background: var(--color-surface-weak); - border-color: var(--color-stroke-weak); -} - -.post-cards__heading { - margin: 0; - padding: 0 var(--space-card); - font-family: var(--font-display); - font-size: var(--font-size-large); - font-weight: var(--font-weight-medium); - line-height: 1; - letter-spacing: -0.24px; - color: var(--color-text-primary); -} - -.post-cards__heading-link { - color: inherit; - text-decoration: none; -} - -.post-cards__heading-link:hover { - text-decoration: none; -} - .post-cards__list { list-style: none; margin: 0; @@ -76,6 +32,11 @@ flex-direction: column; } +.post-cards__item { + list-style: none; + min-width: 0; +} + .post-cards--horizontal { max-width: 100%; min-width: 0; @@ -91,43 +52,73 @@ min-width: 0; } -.post-cards__item { - list-style: none; - border-top: 1px solid var(--color-stroke-weak); - min-width: 300px; -} - -.post-cards__item:last-child { - border-bottom: 1px solid var(--color-stroke-weak); -} - .post-cards--horizontal .post-cards__item { - border-top: none; - border-bottom: none; - border-right: 1px solid var(--color-stroke-weak); flex: 0 0 auto; - min-width: 368px; - max-width: 458px; -} - -.post-cards--horizontal .post-cards__item:last-child { - border-right: none; + min-width: 0; } -/* Carousel variant: horizontal scroll is intentional */ +/* Carousel variant */ .post-cards--horizontal.post-cards--carousel { overflow: visible; } + .post-cards--horizontal.post-cards--carousel .post-cards__list { overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch; } + .post-cards--horizontal.post-cards--carousel .post-cards__item { flex: 0 0 auto; flex-shrink: 0; } +.post-cards--content .post-cards__list { + gap: 0; +} + +.post-cards--content-list .post-cards__item { + border-top: 1px solid var(--color-stroke-weak); + border-bottom: none; + border-left: none; + border-right: none; +} + +.post-cards--content-list .post-cards__item:last-child { + border-bottom: 1px solid var(--color-stroke-weak); +} + +.post-cards--content-list .content-card { + background: transparent; + border-radius: 0; + border: none; +} + +.post-cards--content-card .post-cards__item { + border: none; + padding: 0; +} + +.post-cards--content-card .post-cards__list { + gap: var(--space-card); +} + +.post-cards--content-card .content-card { + background: var(--color-surface-weak); + border: 1px solid var(--color-stroke-weak); + border-radius: var(--border-radius-l); +} + +.post-cards--content-card .content-detail-icon { + min-width: 300px; +} + +.post-cards--content-card.post-cards--horizontal .post-cards__item { + border-right: none; +} + +/* ── Post card (individual item) ───────────── */ + .post-card { display: flex; flex-direction: column; @@ -169,52 +160,26 @@ color: var(--color-text-secondary); } -.post-card__meta-sep { +.post-card__meta > :not(:first-child)::before { + content: "•"; color: var(--color-text-secondary); user-select: none; + margin-right: 6px; } -.post-card__author { - display: flex; - align-items: center; - gap: var(--space-medium); -} - -.post-cards--content .post-cards__list { - gap: 0; -} - -.post-cards--content-list .post-cards__item { - border-top: 1px solid var(--color-stroke-weak); - border-bottom: none; - border-left: none; - border-right: none; -} - -.post-cards--content-list .post-cards__item:last-child { - border-bottom: 1px solid var(--color-stroke-weak); -} +/* ── Description (optional supporting copy) ── */ -.post-cards--content-list .content-card { - background: transparent; - border-radius: 0; - border: none; -} - -.post-cards--content-card .post-cards__item { - border: none; - padding: 0; -} - -.post-cards--content-card .post-cards__list { - gap: var(--space-card); +.post-card__description { + margin: 0; + font-family: var(--font-sans); + font-size: var(--font-size-small); + font-weight: var(--font-weight-regular); + line-height: var(--line-height-default); + letter-spacing: -0.14px; + color: var(--color-text-secondary); } -.post-cards--content-card .content-card { - background: var(--color-surface-weak); - border: 1px solid var(--color-stroke-weak); - border-radius: var(--border-radius-l); -} +/* ── Content card (event items, detail items) ─ */ .content-card { display: flex; @@ -318,40 +283,20 @@ text-decoration: underline; } -/* Content / detail cards (title + icon + description + optional CTA) */ -.post-cards--content .post-cards__list { - gap: 0; -} - -.post-cards--content-card .post-cards__item { - border: none; - padding: 0; -} - -.post-cards--content-card .post-cards__list { - gap: var(--space-card); -} - -.post-cards--content-card .content-detail-icon { - min-width: 300px; -} - -.post-cards--content-card.post-cards--horizontal .post-cards__item { - border-right: none; -} +/* ── Cards carousel ────────────────────────── */ .cards-carousel { display: flex; flex-direction: column; - gap: var(--space-large, 16px); - padding: var(--space-large, 16px) 0; + gap: var(--space-large); + padding: var(--space-large) 0; width: 100%; max-width: 100%; min-width: 0; box-sizing: border-box; - background: var(--color-surface-mid, #f7f7f8); - border: 1px solid var(--color-stroke-weak, rgba(5, 8, 22, 0.1)); - border-radius: var(--border-radius-l, 8px); + background: var(--color-surface-mid); + border: 1px solid var(--color-stroke-weak); + border-radius: var(--border-radius-l); overflow: hidden; } @@ -359,7 +304,7 @@ display: flex; align-items: center; justify-content: space-between; - padding: 0 var(--space-large, 16px); + padding: 0 var(--space-large); width: 100%; flex-shrink: 0; } @@ -367,11 +312,11 @@ .cards-carousel__heading { margin: 0; font-family: var(--font-display); - font-size: var(--font-size-large, 24px); - font-weight: var(--font-weight-medium, 500); + font-size: var(--font-size-large); + font-weight: var(--font-weight-medium); line-height: 1; letter-spacing: -0.24px; - color: var(--color-text-primary, #050816); + color: var(--color-text-primary); flex: 1 0 0; min-width: 0; } @@ -383,14 +328,14 @@ .cards-carousel__divider { margin: 0; border: none; - border-top: 1px solid var(--color-stroke-weak, rgba(5, 8, 22, 0.1)); + border-top: 1px solid var(--color-stroke-weak); width: 100%; height: 0; flex-shrink: 0; } .cards-carousel__track { - padding: 0 var(--space-large, 16px); + padding: 0 var(--space-large); width: 100%; min-width: 0; flex-shrink: 0; @@ -404,7 +349,7 @@ } .cards-carousel .post-cards--content-card .post-cards__list { - gap: var(--space-large, 16px); + gap: var(--space-large); align-items: stretch; } @@ -416,11 +361,11 @@ } .cards-carousel .content-detail-icon { - background: var(--color-surface-weak, #fff); - border: 1px solid var(--color-stroke-weak, rgba(5, 8, 22, 0.1)); - border-radius: var(--border-radius-l, 8px); - padding: var(--space-large, 16px); - gap: var(--space-large, 16px); + background: var(--color-surface-weak); + border: 1px solid var(--color-stroke-weak); + border-radius: var(--border-radius-l); + padding: var(--space-large); + gap: var(--space-large); width: 100%; min-width: 0; align-self: stretch; diff --git a/static/css/v3/v3-examples-section.css b/static/css/v3/v3-examples-section.css index ffe16b0cc..34c852a2b 100644 --- a/static/css/v3/v3-examples-section.css +++ b/static/css/v3/v3-examples-section.css @@ -153,14 +153,14 @@ html.dark .v3-examples-section__example-box { flex-shrink: 0; } -.v3-examples-section .post-cards--carousel .post-cards__list { +.v3-examples-section .post-cards--carousel .post-cards__list, +.v3-examples-section .card-group__list { scrollbar-width: none; -webkit-overflow-scrolling: touch; } -.v3-examples-section - .post-cards--carousel - .post-cards__list::-webkit-scrollbar { +.v3-examples-section .post-cards--carousel .post-cards__list::-webkit-scrollbar, +.v3-examples-section .card-group__list::-webkit-scrollbar { display: none; } @@ -283,6 +283,12 @@ html.dark .v3-examples-section__toc { text-decoration: underline; } +.v3-examples-section-horizontal-container { + display: flex; + gap: var(--space-xl); + overflow-x: auto; +} + /* ── Scroll offset for anchor links ────────────── */ .v3-examples-section__block[id] { diff --git a/templates/v3/examples/_v3_example_section.html b/templates/v3/examples/_v3_example_section.html index adc31c272..9e5f0503e 100644 --- a/templates/v3/examples/_v3_example_section.html +++ b/templates/v3/examples/_v3_example_section.html @@ -189,38 +189,6 @@

{{ section_title }}

{% endwith %} - {% with section_title="Post cards list" %} -
-

{{ section_title }}

-
-
-

- Posts from the Boost community -

-
    - {% for post in demo_posts %} -
  • - {% include "v3/includes/_post_card_v3.html" with post=post %} -
  • - {% endfor %} -
-
- {% include "v3/includes/_button.html" with label="View all posts" url="#" %} -
-
-
-
- {% endwith %} - - {% with section_title="Post Card" %} -
-

{{ section_title }}

-
- {% include "v3/includes/_post_card_v3.html" with post=demo_post %} -
-
- {% endwith %} - {% with section_title="Search Card" %}

{{ section_title }}

@@ -560,73 +528,65 @@

{{ section_title }}

{% endwith %} - {% with section_title="Event cards" %} + {% with section_title="Post Cards — list (this only have 1 theme)" %}

{{ section_title }}

-
{% include "v3/includes/_event_cards.html" %}
+
+ {% include "v3/includes/_post_card.html" with heading="Posts from the Boost community" items=demo_posts variant="list" primary_cta_label="View all posts" primary_cta_url="#" %} +
{% endwith %} - {% with section_title="Achievement cards" %} + {% with section_title="Post Cards — card variant with different themes - default, teal, yellow, green" %} +
+

{{ section_title }}

+
+ {% include "v3/includes/_post_card.html" with heading="Posts from the Boost community" items=demo_posts variant="card" primary_cta_label="View all posts" primary_cta_url="#" %} + {% include "v3/includes/_post_card.html" with heading="Posts from the Boost community" items=demo_posts variant="card" theme="teal" primary_cta_label="View all posts" primary_cta_url="#" %} + {% include "v3/includes/_post_card.html" with heading="Posts from the Boost community" items=demo_posts variant="card" theme="yellow" primary_cta_label="View all posts" primary_cta_url="#" %} + {% include "v3/includes/_post_card.html" with heading="Posts from the Boost community" items=demo_posts variant="card" theme="green" primary_cta_label="View all posts" primary_cta_url="#" %} +
+
+ {% endwith %} + + {% with section_title="Post Cards — card, teal, horizontal" %}

{{ section_title }}

-

Empty Card

- {% include "v3/includes/_achievement_card.html" %} -

Card with Achievements

- {% include "v3/includes/_achievement_card.html" with achievements=achievements_data.achievements primary_button_url="https://www.example.com" %} + {% include "v3/includes/_post_card.html" with heading="Posts from the Boost community" items=demo_posts variant="card" theme="teal" layout="horizontal" primary_cta_label="View all posts" primary_cta_url="#" %}
{% endwith %} - {% with section_title="Content event list" %} + {% with section_title="Event Cards — list (this only have 1 theme)" %}

{{ section_title }}

-
-

- Releases -

-
    -
  • - {% include "v3/includes/_content_event_card_item.html" with title="Boost 1.90.0 closed for major changes" description="Release closed for major code changes. Still open for serious problem fixes and docs changes without release manager review." date="29/10/25" datetime="29/10/25" card_url="#event-0" card_aria_label="Boost 1.90.0 closed for major changes" event_card_wrapper=False %} -
  • -
  • - {% include "v3/includes/_content_event_card_item.html" with title="C++ Now 2025 call for submissions" description="C++ Now conference is accepting talk proposals until March 15. Topics include modern C++, Boost libraries, and tooling." date="12/02/25" datetime="12/02/25" card_url="#event-1" card_aria_label="C++ Now 2025 call for submissions" event_card_wrapper=False %} -
  • -
  • - {% include "v3/includes/_content_event_card_item.html" with title="Boost 1.89.0 released" description="Boost 1.89.0 is available with updates to Asio, Beast, and several other libraries. See release notes for details." date="15/01/25" datetime="15/01/25" card_url="#event-2" card_aria_label="Boost 1.89.0 released" event_card_wrapper=False %} -
  • -
-
{% include "v3/includes/_button.html" with label="View all" url="#" %}
-
+ {% include "v3/includes/_event_card.html" with heading="Upcoming Events" items=demo_events_with_links variant="list" primary_cta_label="Download latest release" primary_cta_url="#" secondary_cta_label="View events calendar" secondary_cta_url="#" %}
{% endwith %} - {% with section_title="Content event card" %} + {% with section_title="Event Cards — card variants with different themes" %} +
+

{{ section_title }}

+
+ {% include "v3/includes/_event_card.html" with heading="Upcoming Events" items=demo_events_with_links variant="card" primary_cta_label="View events" primary_cta_url="#" secondary_cta_label="View calendar" secondary_cta_url="#" %} + {% include "v3/includes/_event_card.html" with heading="Upcoming Events" items=demo_events_with_links variant="card" theme="yellow" primary_cta_label="View events" primary_cta_url="#" secondary_cta_label="View calendar" secondary_cta_url="#" %} + {% include "v3/includes/_event_card.html" with heading="Upcoming Events" items=demo_events_with_links variant="card" theme="green" primary_cta_label="View events" primary_cta_url="#" secondary_cta_label="View calendar" secondary_cta_url="#" %} + {% include "v3/includes/_event_card.html" with heading="Upcoming Events" items=demo_events_with_links variant="card" theme="teal" primary_cta_label="View events" primary_cta_url="#" secondary_cta_label="View calendar" secondary_cta_url="#" %} +
+
+ {% endwith %} + + {% with section_title="Achievement cards" %}

{{ section_title }}

-
-

- Releases -

-
    -
  • - {% include "v3/includes/_content_event_card_item.html" with title="Boost 1.90.0 closed for major changes" description="Release closed for major code changes. Still open for serious problem fixes and docs changes without release manager review." date="29/10/25" datetime="29/10/25" card_url="#event-0" card_aria_label="Boost 1.90.0 closed for major changes" event_card_wrapper=True %} -
  • -
  • - {% include "v3/includes/_content_event_card_item.html" with title="C++ Now 2025 call for submissions" description="C++ Now conference is accepting talk proposals until March 15. Topics include modern C++, Boost libraries, and tooling." date="12/02/25" datetime="12/02/25" card_url="#event-1" card_aria_label="C++ Now 2025 call for submissions" event_card_wrapper=True %} -
  • -
  • - {% include "v3/includes/_content_event_card_item.html" with title="Boost 1.89.0 released" description="Boost 1.89.0 is available with updates to Asio, Beast, and several other libraries. See release notes for details." date="15/01/25" datetime="15/01/25" card_url="#event-2" card_aria_label="Boost 1.89.0 released" event_card_wrapper=True %} -
  • -
-
{% include "v3/includes/_button.html" with label="View all" url="#" %}
-
+

Empty Card

+ {% include "v3/includes/_achievement_card.html" %} +

Card with Achievements

+ {% include "v3/includes/_achievement_card.html" with achievements=achievements_data.achievements primary_button_url="https://www.example.com" %}
{% endwith %} diff --git a/templates/v3/includes/_card_group.html b/templates/v3/includes/_card_group.html new file mode 100644 index 000000000..6599ce5ac --- /dev/null +++ b/templates/v3/includes/_card_group.html @@ -0,0 +1,42 @@ +{% comment %} + Card Group — base template for themed card group containers. + Provides the shared shell (section, heading, CTAs). Consumers extend this + template and fill {% block card_list %} with their own item loop. + + Variables: + heading (string, required) — section heading text + heading_url (string, optional) — if set, heading becomes a link + items (list, required) — list of item objects + variant (string, optional) — "list" (border-separated) or "card" (bg + radius), defaults to "list" + theme (string, optional) — only applicable to variant "card"; + - 4 options are "default", "yellow", "green", "teal" + layout (string, optional) — "vertical" or "horizontal", defaults to "vertical" + primary_cta_label (string, optional) — primary CTA button label + primary_cta_url (string, optional) — primary CTA button URL + secondary_cta_label (string, optional) — secondary CTA button label + secondary_cta_url (string, optional) — secondary CTA button URL + + Usage: + Extend this template and override {% block card_list %} to render items. + See _event_card.html and _post_card.html for examples. +{% endcomment %} +{% if heading or items %} +
+ {% if heading %} +

{% if heading_url %}{{ heading }}{% else %}{{ heading }}{% endif %}

+ {% endif %} + {% block card_list %} + {# Consumers will fill this block with their item loop #} + {% endblock %} + {% if primary_cta_url or secondary_cta_url %} +
+ {% if primary_cta_url %} + {% include "v3/includes/_button.html" with label=primary_cta_label url=primary_cta_url style=theme|default:"primary" only %} + {% endif %} + {% if secondary_cta_url %} + {% include "v3/includes/_button.html" with label=secondary_cta_label url=secondary_cta_url style="secondary" only %} + {% endif %} +
+ {% endif %} +
+{% endif %} diff --git a/templates/v3/includes/_content_event_card_item.html b/templates/v3/includes/_content_event_card_item.html deleted file mode 100644 index ac2a58330..000000000 --- a/templates/v3/includes/_content_event_card_item.html +++ /dev/null @@ -1,36 +0,0 @@ -{% comment %} - V3 Content event card – single event item (title, description, date). - Uses content-card from static/css/v3/post-cards.css; event-card from event-cards.css when wrapped. - - Variables: - title (required) — event title - description (required) — event description - date (required) — human-readable date (e.g. "29/10/25") - datetime (optional) — value for