import { type ComponentPropsWithoutRef, type ReactNode } from 'react'; export interface PracticeProfileHeroBadge { /** Display key — i18n is up to the consumer. */ key: string; /** Display label. */ label: string; /** Badge variant — falls back to `neutral`. */ variant?: 'neutral' | 'info' | 'success' | 'warning' | 'error'; } export interface PracticeProfileHeroRating { /** Mean rating, 0–5. */ value: number; /** Total number of reviews. */ count: number; } export interface PracticeProfileHeroHandle { getName: () => string; /** Structural flag — whether a cover strip is rendered. No PHI. */ getHasCover: () => boolean; } export interface PracticeProfileHeroProps extends Omit, 'aria-label' | 'children'> { /** Practice display name. Rendered as the H1 heading. */ name: string; /** Slogan / tagline subtitle (e.g. "15 anni di esperienza nel cuore di Brera"). */ tagline?: string; /** * Optional practice photo / logo URL. The kit always renders an * `` — when `imageUrl` is missing the avatar falls back to * initials. */ imageUrl?: string; /** * Text alternative for the photo's ``, for image search and crawlers. * Pass the practice name. Leave it out and the photo stays decorative * (`alt=""`), as before. Added in 1.91.0. */ imageAlt?: string; /** * Optional cover image painted as a full-width strip above the body. * The strip renders ONLY when this is set — a practice without a cover * image gets no strip (and no empty gradient band). While the image * loads, the brand gradient shows in the strip. If it fails to load * (404, 401, not an image), the strip goes, as if no cover had been * passed, and `data-has-cover` reads `"false"`. A different URL tries * again. */ coverImageUrl?: string; /** Rating summary — when present, renders a Rating + numeric breakdown line. */ rating?: PracticeProfileHeroRating; /** * Optional badge row beneath the rating. Use sparingly — 1–3 chips * suit the hero's density; longer lists belong in ``. */ badges?: PracticeProfileHeroBadge[]; /** * Rendered at the inline-end of the heading row (right side on LTR) * from `sm` up. The heading row wraps, so on a phone the action drops * onto its own line, starts flush with the practice name, and is free * to shrink into the column rather than overflow it. * * Use for a "Book an appointment" `