--- /** * CardCarousel — scroll-snap card strip with prev/next arrows and dots, driven by ./carousel.ts. * * Callers place each card as a direct child of the default slot, carrying `snap-start shrink-0` and a fixed * responsive width, e.g. `…`. * * The header always renders so the arrows exist even under a caller's own heading; the view-all link shows at every * width, so a capped carousel always offers an onward path (SLA-2368). The active dot takes `--carousel-dot` when the * site defines it (default: the primary role). */ import Icon from '../primitives/Icon.astro'; import { deterministicId } from '@sarimarcus/content-sites-core/dom'; interface Props { /** Section heading rendered above the track. */ heading?: string; headingTag?: 'h2' | 'h3'; /** * Full replacement for the heading's classes (not appended — a merged list * would keep the default `sm:text-3xl` winning at that breakpoint). Use when * a caller needs a quieter heading than the default section scale, e.g. a * subordinate related-content block sitting under a page `h2`. */ headingClass?: string; description?: string; /** Anchor id for in-page jump links / scroll-spy. */ id?: string; /** Optional "view all" link shown next to the arrows. */ viewAllHref?: string; viewAllLabel?: string; /** Accessible label for the scroll region (falls back to the heading). */ ariaLabel?: string; class?: string; } const { heading, headingTag = 'h2', headingClass, description, id, viewAllHref, viewAllLabel = 'View all', ariaLabel, class: className, } = Astro.props; const HeadingTag = headingTag; // Ids must be unique per page AND stable across builds. const containerId = deterministicId('cc', Astro.url.pathname, id, ariaLabel ?? heading); const trackId = `${containerId}-t`; ---
{heading && ( {heading} )} {description && (

{description}

)}
{viewAllHref && ( {viewAllLabel} )}