{% set g = module.style %}
{% set a = module.advanced %}
{# Prepare data source - manual cards or HubDB #}
{% set card_items = [] %}
{% set hubdb_error = none %}
{% if module.data_source == 'hubdb' %}
{# HubDB data source #}
{% if module.hubdb_config.table_id %}
{% set table = hubdb_table(module.hubdb_config.table_id) %}
{% if table %}
{% set query_params = {} %}
{% if module.hubdb_config.filter_column and module.hubdb_config.filter_value %}
{% do query_params.update({module.hubdb_config.filter_column: module.hubdb_config.filter_value}) %}
{% endif %}
{# limit must be a query param — hubdb_table_rows() has no 3rd positional arg. #}
{% do query_params.update({"limit": module.hubdb_config.limit|default(9)}) %}
{% set card_items = hubdb_table_rows(table.id, query_params) %}
{% else %}
{% set hubdb_error = "HubDB table not found. Please check the table ID in module settings." %}
{% endif %}
{% else %}
{% set hubdb_error = "HubDB table not selected. Please select a table in module settings." %}
{% endif %}
{% else %}
{# Manual cards data source #}
{% set card_items = module.cards %}
{% endif %}
{# Mobile-first: Determine visible cards on mobile viewport #}
{% set mobile_visible_count = g.cols_mobile == '1' ? 2 : 4 %}
{% set tablet_visible_count = g.cols_tablet|int * 2 %}
{# No preload here: it fetched the FULL-SIZE original while the first renders a
resized srcset candidate (double download), and fired even for the 'no-image'
variant. The first card image is already loading="eager" + fetchpriority="high". #}
{# Main grid section #}
{# Optional section header #}
{% if a.section_title or a.section_subtitle %}
{% if a.section_title %}
Please configure the HubDB settings in the module editor or switch to Manual Cards.
{% endif %}
{# Cards grid container #}
{# Responsive column widths — constant per module instance, computed once #}
{% set mobile_width = g.cols_mobile == '1' ? 350 : 263 %}
{% set tablet_width = (768 / g.cols_tablet|int)|round %}
{% set desktop_width = (1200 / g.cols_desktop|int)|round %}
{% for item in card_items %}
{% set card_index = loop.index %}
{# Mobile-first priority: Only first visible cards on mobile get high priority #}
{% set is_mobile_priority = (g.cols_mobile == '1' and card_index == 1) or (g.cols_mobile == '2' and card_index <= 2) %}
{% set is_priority = is_mobile_priority %}
{# Corner-flag label if present #}
{% if item.badge %}
{{ item.badge|escape }}
{% endif %}
{# Image - not shown for no-image variant #}
{# Handle both manual and HubDB image sources #}
{% if module.data_source == 'hubdb' %}
{# HubDB: image may be URL string or object with .url property #}
{% set image_url = item.image.url if item.image.url else (item.image if item.image is string else '') %}
{% set img_width = item.image.width if item.image.width else null %}
{% set img_height = item.image.height if item.image.height else null %}
{% set img_size_known = img_width and img_height %}
{% else %}
{# Manual: standard module image field - check for valid src string #}
{% set image_url = item.image.src if item.image.src else (item.image.url if item.image.url else (item.image if item.image is string else '')) %}
{% set img_width = item.image.width if item.image.width else null %}
{% set img_height = item.image.height if item.image.height else null %}
{% set img_size_known = img_width and img_height %}
{% endif %}
{# Only render image if we have a valid URL string #}
{% if g.card_variant != 'no-image' and image_url and image_url is string and image_url != '' %}
{% set loading = is_priority ? 'eager' : (a.lazy_load ? 'lazy' : (item.image.loading|default('lazy'))) %}
{% set fetchpriority = is_priority ? 'high' : 'auto' %}
{# Check if image is HubSpot-hosted (resize_image_url only works with HubSpot URLs) #}
{% set is_hubspot_image = image_url is string_containing 'hubspot' or image_url is string_containing 'hubspotusercontent' or image_url is string_containing 'f.hubspotusercontent' %}
{# Generate properly sized URLs — only when native dimensions are known to avoid upscaling #}
{% if is_hubspot_image and img_size_known %}
{% set img_mobile = resize_image_url(image_url, mobile_width) %}
{% set img_tablet = resize_image_url(image_url, tablet_width) %}
{% set img_desktop = resize_image_url(image_url, desktop_width) %}
{% set img_desktop_2x = resize_image_url(image_url, desktop_width * 2) %}
{% endif %}
{% endif %}
{# Card body content #}
{% if item.eyebrow %}
{{ item.eyebrow|escape }}
{% endif %}
{{ item.title|escape }}
{% if item.content and g.card_variant != 'compact' %}
{{ item.content|sanitize_html }}
{% endif %}
{# CTA button or link.
Manual cards: cta_url is a url-field dict (use .href).
HubDB rows: cta_url is a plain string. Support both. #}
{% if (item.cta_url.href or item.cta_url is string) and item.cta_text %}
{% set cta_href = item.cta_url.href|default(item.cta_url, true) %}
{% set target_attrs = item.new_tab ? 'target="_blank" rel="noopener noreferrer"' : '' %}
{% set aria_label = item.cta_aria_label ? 'aria-label="' ~ item.cta_aria_label|escape ~ '"' : '' %}
{% if item.cta_as_button %}
{{ item.cta_text|escape }}
{% else %}
{{ item.cta_text|escape }}
→
{% endif %}
{% endif %}
{% endfor %}
{# Mobile performance monitoring and adaptive loading #}
{% if a.mobile_optimization == 'adaptive' %}
{% endif %}
{# Mobile-first critical CSS - only load what mobile needs #}
{% require_css %}
{% end_require_css %}