You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/web/routes/blocks/hero/HeroSite.svelte

175 lines
6.6 KiB

<script lang="ts">
/**
* The hero mini-page: the block with a page worth of product content, so the
* demo can render it FULL-BLEED (the hero at the real top of a real page) and
* the `preview` route can serve the same thing as a standalone document for
* the device-width frame.
*
* The media is a framed screenshot placeholder composed from canon components
* — no external asset, no raw CSS — so it reads as a product shot in every
* theme.
*/
import { Hero } from '$blocks/hero';
import { Section } from '$uix/eidos/components/section';
import { Container } from '$uix/eidos/components/container';
import { Stack } from '$uix/eidos/components/stack';
import { Group } from '$uix/eidos/components/group';
import { Grid } from '$uix/eidos/components/grid';
import { Box } from '$uix/eidos/components/box';
import { Wrap } from '$uix/eidos/components/wrap';
import { Surface } from '$uix/eidos/components/surface';
import { Mockup } from '$uix/eidos/components/mockup';
import { MediaPlayer } from '$uix/eidos/components/media-player';
import { Heading } from '$uix/eidos/components/heading';
import { Text } from '$uix/eidos/components/text';
import { Badge } from '$uix/eidos/components/badge';
import { Button } from '$uix/eidos/components/button';
import { Link } from '$uix/eidos/components/link';
import * as Icon from '$uix/eidos/components/icon';
type ContainerSize = 'sm' | 'md' | 'lg' | 'xl' | 'full';
type SectionSize = 'sm' | 'md' | 'lg' | 'xl';
type Layout = 'center' | 'split' | 'background';
type Decor = 'glow' | 'mesh' | 'grid' | 'dots' | 'none';
type MediaKind = 'dashboard' | 'video';
let {
layout = 'split' as Layout,
level = 1,
container = 'lg' as ContainerSize,
size = 'xl' as SectionSize,
withMedia = true,
withEyebrow = true,
mediaKind = 'dashboard' as MediaKind,
decor = 'glow' as Decor
}: {
layout?: Layout;
level?: 1 | 2 | 3 | 4 | 5 | 6;
container?: ContainerSize;
size?: SectionSize;
withMedia?: boolean;
withEyebrow?: boolean;
mediaKind?: MediaKind;
decor?: Decor;
} = $props();
// Faux chart bars for the screenshot placeholder — fixed heights in rem so
// the card is exactly as tall as its content, no empty frame.
const bars = ['3rem', '5rem', '3.6rem', '6.4rem', '4.4rem', '7.4rem', '5.6rem'];
const centered = $derived(layout !== 'split');
</script>
<Hero {layout} {level} containerSize={container} sectionSize={size} {decor}>
{#snippet backdrop()}
<!-- The backdrop is a real Surface with the aurora gradient finish: the
identity's `primary` solid painted by `--gradient-aurora` (derived from
the theme's own colour roles). No hand-picked colour — swap the palette
and the backdrop follows. -->
<Surface variant="solid" color="primary" gradient width="100%" height="100%" />
{/snippet}
{#snippet eyebrow()}
{#if withEyebrow}
<Badge size="sm" variant="soft" color="primary">Beta pública</Badge>
{/if}
{/snippet}
{#snippet title()}
Analítica de producto sin sorpresas en la factura
{/snippet}
{#snippet description()}
Eventos crudos, cohortes al día y automatizaciones que reaccionan solas. Sin muestreo, sin
reprocesar y sin un contrato que crece con cada pico de tráfico.
{/snippet}
{#snippet actions()}
<!-- `intent="fulfill"`: the page's completion, carried as ANTICIPATORY
WEIGHT (colour and form). It does NOT load the Button's
`contact-activate` with intent — the morfo says so explicitly — so it
produces no sound or haptic by itself; the evaluative consequence is
the `commit` the app emits when the outcome lands (see PricingSite). -->
<Button variant="solid" size="lg" intent="fulfill">
{#snippet endIcon()}<Icon.ArrowRight size="xs" />{/snippet}
{#snippet child({ props, content })}
<a href="#pricing" {...props}>{@render content()}</a>
{/snippet}
Empezar gratis
</Button>
<!-- No ink override here: the block sets it for the whole copy cluster under
`background`. This used to pass `--color-content-on-solid` by hand, which
was inert anyway (`subtle` resolves to `color: inherit`). -->
<Link href="#docs" variant="subtle" size="lg">Ver la documentación</Link>
{/snippet}
{#snippet media()}
{#if withMedia && mediaKind === 'video'}
<!-- A hero with VIDEO: the canon `MediaPlayer` inside the same `Mockup`
chrome. Nothing bespoke — the block's `media` slot takes whatever the
app composes. -->
<Mockup chrome="browser" url="acme.app/demo">
<MediaPlayer media="video">
<MediaPlayer.Media
src="https://test-videos.co.uk/vids/bigbuckbunny/mp4/h264/720/Big_Buck_Bunny_720_10s_1MB.mp4"
loop
muted
autoplay
playsinline
/>
<MediaPlayer.DefaultControls />
</MediaPlayer>
</Mockup>
{:else if withMedia}
<!-- Dogfoods the canon `Mockup`: the browser chrome (dots + URL) is the
primitive's, so the faux dashboard inside is just the content. -->
<Mockup chrome="browser" url="acme.app/analytics">
<Box padding={4}>
<Stack gap={5}>
<Group gap={2} align="center" justify="end">
<Badge size="xs" variant="soft" color="primary">en vivo</Badge>
</Group>
<!-- Grid gives each bar an equal 1fr track — no reliance on flex-grow. -->
<Grid columns={7} gap={3} align="end">
{#each bars as h, i (i)}
<Surface
variant="solid"
color={i === 5 ? 'primary' : 'neutral'}
rounded
height={h}
/>
{/each}
</Grid>
<Grid templateColumns="1fr 20%" gap={3} align="center">
<Surface variant="solid" color="neutral" rounded height="0.5rem" />
<Surface variant="solid" color="neutral" rounded height="0.5rem" />
</Grid>
</Stack>
</Box>
</Mockup>
{/if}
{/snippet}
</Hero>
<!-- A floor so the page reads as a page, not a lone band. -->
<Section size="lg">
<Container size={container}>
<Stack gap={6}>
<Text size="sm" weight="medium" color="muted" align={centered ? 'center' : 'start'}>
Con la confianza de equipos de producto en
</Text>
<Wrap gap={8} justify={centered ? 'center' : 'start'}>
{#each ['Northwind', 'Umbra', 'Kessel', 'Volta', 'Marisol'] as brand (brand)}
<Text size="lg" weight="semibold" color="muted">{brand}</Text>
{/each}
</Wrap>
<Heading level={level === 1 ? 2 : 3}>
Del evento crudo a la decisión, sin escala intermedia
</Heading>
<Text color="muted" measure="wide">
Los eventos llegan tal cual y salen en cohortes: quién hizo qué, cuándo dejó de hacerlo y
qué cambió la semana en que lanzaste. Consulta cualquier ventana sin reprocesar.
</Text>
</Stack>
</Container>
</Section>

Powered by TurnKey Linux.