diff options
| author | Dawid Rycerz <dawid@rycerz.xyz> | 2025-07-22 18:47:32 +0300 |
|---|---|---|
| committer | Dawid Rycerz <dawid@rycerz.xyz> | 2025-07-22 18:47:32 +0300 |
| commit | c949098e81248cd05da48d6ec6ccc033bd1d0011 (patch) | |
| tree | b4ea59db61b38ee2934f05b478c5eff39905f4d9 /src/components/widgets | |
| parent | d0eb8e6a0f85759a34114596976ef4c1eb4f0258 (diff) | |
Full size hero
Diffstat (limited to 'src/components/widgets')
| -rw-r--r-- | src/components/widgets/HeroBackground.astro | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/src/components/widgets/HeroBackground.astro b/src/components/widgets/HeroBackground.astro new file mode 100644 index 0000000..b5ea748 --- /dev/null +++ b/src/components/widgets/HeroBackground.astro @@ -0,0 +1,128 @@ +--- +import Image from '~/components/common/Image.astro'; +import Button from '~/components/ui/Button.astro'; + +import type { Hero as Props } from '~/types'; + +const { + title = await Astro.slots.render('title'), + subtitle = await Astro.slots.render('subtitle'), + tagline, + + content = await Astro.slots.render('content'), + actions = await Astro.slots.render('actions'), + image = await Astro.slots.render('image'), + + id, + bg = await Astro.slots.render('bg'), + logoPath = '~/assets/images/customworks-logo.png', +} = Astro.props; +--- + +<section class="relative md:-mt-[76px] not-prose min-h-screen flex items-center" {...id ? { id } : {}}> + <!-- Background Image --> + <div class="absolute inset-0 pointer-events-none" aria-hidden="true"> + { + image && ( + <div class="absolute inset-0"> + {typeof image === 'string' ? ( + <Fragment set:html={image} /> + ) : ( + <Image + class="w-full h-full object-cover" + widths={[400, 768, 1024, 2040]} + sizes="100vw" + loading="eager" + width={1920} + height={1080} + aspectRatio="16:9" + {...image} + /> + )} + </div> + ) + } + <!-- Dark overlay for better text readability --> + <div class="absolute inset-0 bg-black bg-opacity-50"></div> + <slot name="bg"> + {bg ? <Fragment set:html={bg} /> : null} + </slot> + </div> + + <!-- Content --> + <div class="relative max-w-7xl mx-auto px-4 sm:px-6 w-full"> + <div class="pt-0 md:pt-[76px] pointer-events-none"></div> + <div class="py-12 md:py-20 lg:py-0 text-center"> + <div class="max-w-4xl mx-auto"> + <!-- Logo --> + { + logoPath && ( + <div class="mb-8 intersect-once motion-safe:md:intersect:animate-fade motion-safe:md:opacity-0 intersect-quarter"> + <Image + src={logoPath} + alt="CustomWorks Logo" + class="mx-auto max-h-20 md:max-h-24 lg:max-h-28 w-auto object-contain" + widths={[200, 300, 400]} + sizes="(max-width: 767px) 200px, (max-width: 1023px) 300px, 400px" + loading="eager" + width={400} + height={200} + /> + </div> + ) + } + + { + tagline && ( + <p + class="text-base text-white font-bold tracking-wide uppercase intersect-once motion-safe:md:intersect:animate-fade motion-safe:md:opacity-0 intersect-quarter mb-4" + set:html={tagline} + /> + ) + } + + { + title && ( + <h1 + class="text-5xl md:text-6xl lg:text-7xl font-bold leading-tighter tracking-tighter mb-6 font-heading text-white intersect-once motion-safe:md:intersect:animate-fade motion-safe:md:opacity-0 intersect-quarter" + set:html={title} + /> + ) + } + + { + subtitle && ( + <p + class="text-xl md:text-2xl text-white/90 mb-8 dark:text-white/90 intersect-once motion-safe:md:intersect:animate-fade motion-safe:md:opacity-0 intersect-quarter max-w-3xl mx-auto" + set:html={subtitle} + /> + ) + } + + { + actions && ( + <div class="max-w-xs sm:max-w-md m-auto flex flex-nowrap flex-col sm:flex-row sm:justify-center gap-4 lg:justify-center lg:m-0 lg:max-w-7xl intersect-once motion-safe:md:intersect:animate-fade motion-safe:md:opacity-0 intersect-quarter"> + {Array.isArray(actions) ? ( + actions.map((action) => ( + <div class="flex w-full sm:w-auto"> + <Button {...(action || {})} class="w-full sm:mb-0" /> + </div> + )) + ) : ( + <Fragment set:html={actions} /> + )} + </div> + ) + } + + { + content && ( + <div class="mt-8 intersect-once motion-safe:md:intersect:animate-fade motion-safe:md:opacity-0 intersect-quarter"> + <Fragment set:html={content} /> + </div> + ) + } + </div> + </div> + </div> +</section> |
