AbiirSkincare/Hydrogen/web/app/components/AbiirHomeHero_old.tsx

260 lines
9.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import {AbiirEyebrow} from '~/components/AbiirEyebrow';
import type {AbiirHomeHeroCms} from '~/lib/homeHero';
import {ABIIR_WIDE_INNER_FRAME_CLASS} from '~/lib/springGlowBanner';
import heroOption04Src from '~/assets/Hero_option04.jpg';
/** Figma hero band height + marquee. */
const FIGMA_HERO_H = 978;
const FIGMA_MARQUEE_H = 68;
function toHeroImageData(
input:
| {
id?: string | null;
url: string;
altText?: string | null;
width?: number | null;
height?: number | null;
}
| null
| undefined,
) {
if (!input?.url) return null;
return {
id: input.id ?? undefined,
url: input.url,
altText: input.altText ?? '',
width: input.width ?? undefined,
height: input.height ?? undefined,
};
}
const HERO_IMAGE_STATIC = toHeroImageData({
id: 'hero-option-04',
url: heroOption04Src,
altText: 'ABiiR skincare — hero',
width: 855,
height: FIGMA_HERO_H,
});
function pickHeroImageData(cms: AbiirHomeHeroCms) {
if (cms.image?.url) {
return toHeroImageData({
id: cms.image.id,
url: cms.image.url,
altText: cms.image.alt,
width: cms.image.width,
height: cms.image.height,
});
}
return HERO_IMAGE_STATIC;
}
function isExternalHref(href: string) {
return /^https?:\/\//i.test(href);
}
function HeroCtaLink({
href,
className,
style,
children,
}: {
href: string;
className?: string;
style?: React.CSSProperties;
children: React.ReactNode;
}) {
return (
<a
href={href}
className={className}
style={style}
rel={isExternalHref(href) ? 'noreferrer' : undefined}
>
{children}
</a>
);
}
/** Figma icon564:2080 — 15×15 */
function HeroCtaArrowIcon({className}: {className?: string}) {
return (
<svg
className={className}
width={15}
height={15}
viewBox="0 0 15 15"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-hidden
>
<path
d="M1 7.5h11M8.5 1L14 7.5 8.5 14"
stroke="currentColor"
strokeWidth={1.5}
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
}
export type AbiirHomeHeroProps = {
cms: AbiirHomeHeroCms;
};
/**
* Hero: Figma `633:2179` — 1710×978 frame, image `absolute inset-0 object-cover`, copy
* `left: 206px`, `width: 637px`, vertically centered on `lg` (unpadded 1710 rail).
* Viewport gutters extend `gradientStart` / `gradientEnd` past the frame.
*/
export function AbiirHomeHero({cms}: AbiirHomeHeroProps) {
const heroBurgundy = cms.accentBurgundy;
const imageData = pickHeroImageData(cms);
const edgeLeft = cms.gradientStart;
const edgeRight = cms.gradientEnd;
/** Space outside the centered 1710px shell (matches Spring Glow full-bleed gutters). */
const viewportGutterWidth = 'max(0px, calc((100vw - min(100vw, 1710px)) / 2))';
return (
<section data-abiir-hero className="abiir-home-hero relative w-full overflow-hidden !py-0">
<div
className="relative w-full overflow-hidden lg:h-[978px]"
style={{
minHeight: `min(100svh, ${FIGMA_HERO_H}px)`,
}}
>
{/* Viewport → shell: edge colors (desktop only; mobile uses column gradient below) */}
<div
aria-hidden
className="pointer-events-none absolute inset-y-0 left-0 z-0 hidden lg:block"
style={{width: viewportGutterWidth, backgroundColor: edgeLeft}}
/>
<div
aria-hidden
className="pointer-events-none absolute inset-y-0 right-0 z-0 hidden lg:block"
style={{width: viewportGutterWidth, backgroundColor: edgeRight}}
/>
<div className={`relative z-[1] ${ABIIR_WIDE_INNER_FRAME_CLASS}`}>
{/* Full-bleed within 1710px frame (Figma has no side padding on this artboard) */}
<div
className="relative min-h-[min(100svh,978px)] w-full overflow-hidden bg-gradient-to-r from-[var(--abiir-hero-edge-l)] to-[var(--abiir-hero-edge-r)] lg:h-[978px] lg:min-h-[978px] lg:bg-transparent"
style={
{
'--abiir-hero-edge-l': edgeLeft,
'--abiir-hero-edge-r': edgeRight,
} as React.CSSProperties
}
>
{imageData ? (
<img
src={imageData.url}
alt={imageData.altText || 'ABiiR hero'}
width={imageData.width ?? 855}
height={imageData.height ?? FIGMA_HERO_H}
loading="eager"
decoding="async"
className="absolute inset-0 size-full object-cover object-center"
sizes="(min-width: 1024px) 1710px, 100vw"
/>
) : null}
</div>
{/* Readability: scrim over the left half of the shell */}
<div
aria-hidden
className="pointer-events-none absolute inset-0 z-[5] bg-gradient-to-r from-[rgba(60,6,23,0.48)] via-[rgba(60,6,23,0.12)] to-transparent sm:from-[rgba(60,6,23,0.4)] sm:via-[rgba(60,6,23,0.08)] lg:max-w-[50%]"
/>
{/* Copy — lg+: left 206px, w 637px; vertically centered in 978px frame */}
<div className="pointer-events-none absolute inset-0 z-10">
<div className="pointer-events-auto relative px-6 pb-12 pt-10 sm:px-10 lg:absolute lg:left-[206px] lg:top-1/2 lg:w-[637px] lg:max-w-[637px] lg:-translate-y-1/2 lg:px-0 lg:pb-0 lg:pt-0">
<div className="flex flex-col gap-6">
<AbiirEyebrow surface="light" className="!text-left">
{cms.eyebrow}
</AbiirEyebrow>
<h1
className="m-0 font-['Cormorant_Garamond',serif] font-light tracking-[-0.969px] text-white not-italic"
style={{
fontSize: 'clamp(2.5rem, 5.5vw, 64.6px)',
lineHeight: 1.12,
fontWeight: 300,
}}
>
<span className="block w-full">
<span className="font-light">{cms.headlineLine1Prefix}</span>
<span className="font-['Cormorant_Garamond',serif] font-light italic">
{cms.headlineLine1Italic}
</span>
</span>
<span className="block w-full">
<span className="font-light">{cms.headlineLine2Prefix}</span>
<span className="font-light not-italic" style={{color: heroBurgundy}}>
{cms.headlineLine2Accent}
</span>
</span>
</h1>
<p className="m-0 font-['Raleway',sans-serif] text-[clamp(1rem,1.29vw+0.65rem,22px)] font-medium leading-[34px] text-[rgba(250,248,243,0.8)] lg:text-[22px]">
{cms.body}
</p>
<div className="flex flex-wrap items-start gap-[21.25px]">
<HeroCtaLink
href={cms.primaryCtaHref}
className="group relative inline-flex h-[52.883px] w-full max-w-[257.586px] shrink-0 items-center justify-between pl-[36px] pr-[18px] no-underline transition-opacity duration-300 hover:opacity-[0.92]"
style={{background: heroBurgundy, color: '#fff'}}
>
<span className="font-['Raleway',sans-serif] text-[14px] font-bold uppercase leading-[19.89px] tracking-[2.3868px]">
{cms.primaryCtaLabel}
</span>
<HeroCtaArrowIcon className="shrink-0 text-white transition-transform group-hover:translate-x-0.5" />
</HeroCtaLink>
<HeroCtaLink
href={cms.secondaryCtaHref}
className="inline-flex h-[52.883px] min-w-0 shrink-0 cursor-pointer items-center justify-center border-0 border-b border-solid border-white bg-transparent pb-[17px] pt-4 no-underline transition-opacity duration-300 hover:opacity-80 lg:min-w-[96.328px]"
>
<span className="whitespace-nowrap text-left font-['Raleway',sans-serif] text-[14px] font-medium uppercase leading-[19.89px] tracking-[2.3868px] text-white">
{cms.secondaryCtaLabel}
</span>
</HeroCtaLink>
</div>
</div>
</div>
</div>
</div>
</div>
{/* Marquee — full width */}
<div
className="relative z-10 w-full overflow-hidden pt-[21.25px]"
style={{background: heroBurgundy, minHeight: FIGMA_MARQUEE_H}}
>
<div className="flex h-[26px] w-full items-center overflow-hidden">
<div className="h-full min-h-0 w-full overflow-hidden opacity-75">
<div
className="animate-[hero-marquee_32s_linear_infinite] flex w-max items-center gap-[200px] whitespace-nowrap font-['Cormorant_Garamond',serif] text-[rgba(250,248,243,0.8)] font-semibold italic tracking-[1.02px]"
style={{
fontSize: 'clamp(1.4rem, calc(1.974vw + 0.7rem), 33.6px)',
lineHeight: '26px',
}}
>
{[0, 1].map((i) => (
<p key={i} className="m-0 shrink-0" aria-hidden={i === 1}>
{cms.marqueeText}
</p>
))}
</div>
</div>
</div>
</div>
</section>
);
}
export type {AbiirHomeHeroCms} from '~/lib/homeHero';