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/testimonials/TestimonialsSite.svelte

109 lines
3.6 KiB

<script lang="ts">
/**
* The testimonials mini-page: a grid of quotes with avatar fallbacks, plus a
* page floor.
*/
import { Testimonials } from '$blocks/testimonials';
import { Avatar } from '$uix/eidos/components/avatar';
import { Section } from '$uix/eidos/components/section';
import { Container } from '$uix/eidos/components/container';
import { Stack } from '$uix/eidos/components/stack';
import { Wrap } from '$uix/eidos/components/wrap';
import { Heading } from '$uix/eidos/components/heading';
import { Text } from '$uix/eidos/components/text';
let { layout = 'grid' as 'grid' | 'spotlight' }: { layout?: 'grid' | 'spotlight' } = $props();
type Quote = { quote: string; name: string; role: string; initials: string; color: string };
const quotes: Quote[] = [
{
quote: 'Migramos en una tarde y los números por fin cuadran con nuestra base de datos.',
name: 'Ana Ruiz',
role: 'CTO en Northwind',
initials: 'AR',
color: 'indigo'
},
{
quote: 'Las cohortes que antes tardaban un día ahora salen al instante, sin reprocesar.',
name: 'Marco Vidal',
role: 'Head of Growth en Umbra',
initials: 'MV',
color: 'teal'
},
{
quote: 'Configuramos una alerta y cazamos una fuga de conversión el mismo día.',
name: 'Lucía Peña',
role: 'Product Manager en Kessel',
initials: 'LP',
color: 'orange'
},
{
quote: 'Sin coste por asiento: por fin invité a todo el equipo al panel.',
name: 'Diego Sáez',
role: 'Fundador en Volta',
initials: 'DS',
color: 'green'
},
{
quote: 'El SSO y la auditoría pasaron la revisión de seguridad sin una sola fricción.',
name: 'Sofía Marín',
role: 'Engineering Lead en Marisol',
initials: 'SM',
color: 'plum'
}
];
// El spotlight lleva UNA cita — la que el equipo quiera destacar.
const shown = $derived(layout === 'spotlight' ? [quotes[1]] : quotes);
</script>
<Testimonials {layout}>
<Testimonials.Header>
<Heading level={2} align="center">Equipos de producto que ya no vuelan a ciegas</Heading>
<Text size="lg" color="muted" align="center">
Lo que cambia cuando los eventos entran crudos y salen en cohortes.
</Text>
</Testimonials.Header>
<Testimonials.Items>
<!-- El spotlight es UNA cita: la app decide cuál, el block sólo la coloca. -->
{#each shown as q (q.name)}
<Testimonials.Item>
{#snippet logo()}
<!-- La marca de quien firma la cita: lo que hace que se lea como
evidencia y no como una opinión. Aquí es una palabra compuesta con
el canon; una app real pondría su `Image`. -->
<Text size="lg" weight="semibold" color="muted">{q.role.split(' en ')[1] ?? ''}</Text>
{/snippet}
<Testimonials.Quote>«{q.quote}»</Testimonials.Quote>
<Testimonials.Author>
{#snippet avatar()}
<Avatar variant="solid" color={q.color}>
<Avatar.Fallback>{q.initials}</Avatar.Fallback>
</Avatar>
{/snippet}
<Testimonials.AuthorName>{q.name}</Testimonials.AuthorName>
<Testimonials.AuthorRole>{q.role}</Testimonials.AuthorRole>
</Testimonials.Author>
</Testimonials.Item>
{/each}
</Testimonials.Items>
</Testimonials>
<!-- A floor so the page reads as a page. -->
<Section size="lg">
<Container size="lg">
<Stack gap={4} align="center">
<Text size="sm" weight="medium" color="muted" align="center">
Con la confianza de equipos de producto en
</Text>
<Wrap gap={8} justify="center">
{#each ['Northwind', 'Umbra', 'Kessel', 'Volta', 'Marisol'] as brand (brand)}
<Text size="lg" weight="semibold" color="muted">{brand}</Text>
{/each}
</Wrap>
</Stack>
</Container>
</Section>

Powered by TurnKey Linux.