La brecha que el dossier le apuntaba a este block: la cita única es la variante modal de todas las referencias y el grid la minoría, dos de ocho en Tailwind Plus. Entra como disposición, no como hermano. La anatomía no cambia —cita, autor, avatar—, sólo cómo se colocan, y el precedente es el fondo del hero, que también redefine lo que hacen sus partes. El hermano se reabre sólo si algún día pide rotación o carrusel, que es otro componente. Viaja por contexto de configuración, el patrón del align de feature-grid y team, no la coordinación de pricing. Y viaja porque el spotlight no es una piel sobre las mismas cajas: la rejilla deja de serlo y de estampar el ritmo estructural —que es para una FILA, no para una cita—, el ítem pierde la tarjeta, la cita sube de tamaño y se centra, y el autor pasa debajo, donde ya no hay una hilera de caras que alinear. Pedirle a la app que repita esa decisión en cinco partes es el agujero que A-84 cerró en feature-grid. Enmarcar una cita sola la hace parecer un ítem de una lista que no está ahí, así que ahí no hay tarjeta y el tipo lo dice, en vez de aceptar una superficie que luego descarta. La cita se centra con un párrafo de verdad: sobre una caja en línea el centrado no aplica, y sería mentira. Slot nuevo para la marca de quien firma, en las dos disposiciones: es lo que hace que una cita se lea como evidencia y no como una opinión, y es la pieza que ponen todas las referencias. Medido: en grid, cinco tarjetas, veinte píxeles, medida de mil veinticuatro y ritmo escalonado; en spotlight, cero tarjetas, una cita de veintiocho centrada en párrafo, medida de setecientos sesenta y ocho, autor centrado y sin escalonado; a 375 la cita cae a veinticuatro. El grid queda idéntico a antes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>alpha-0.1-background
parent
b92dc3bdb2
commit
f3bfcf2dd9
@ -0,0 +1,32 @@
|
|||||||
|
import { getContext, setContext } from 'svelte';
|
||||||
|
import type { TestimonialsLayout } from './types';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* What `Testimonials` shares with its parts: the section's ARRANGEMENT.
|
||||||
|
*
|
||||||
|
* Configuration, not state — the same shape `feature-grid` and `team` use for
|
||||||
|
* their `align`. It travels because `spotlight` is not a different skin over the
|
||||||
|
* same boxes: the row of cards becomes ONE quote, so `Items` stops being a grid,
|
||||||
|
* `Item` drops the card that framed it, the quote steps up in size and the author
|
||||||
|
* moves under it. Asking the app to repeat that decision on five parts is exactly
|
||||||
|
* the hole A-84 closed on `feature-grid`.
|
||||||
|
*/
|
||||||
|
export interface TestimonialsContext {
|
||||||
|
/** `grid` (the default) or `spotlight`. A getter, so reads track the source. */
|
||||||
|
readonly layout: TestimonialsLayout;
|
||||||
|
}
|
||||||
|
|
||||||
|
const KEY = Symbol('uix.testimonials');
|
||||||
|
|
||||||
|
export function setTestimonialsContext(ctx: TestimonialsContext): void {
|
||||||
|
setContext(KEY, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getTestimonialsContext(): TestimonialsContext | undefined {
|
||||||
|
return getContext<TestimonialsContext | undefined>(KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The arrangement a part should assume when it is used outside the block. */
|
||||||
|
export function testimonialsLayout(): TestimonialsLayout {
|
||||||
|
return getTestimonialsContext()?.layout ?? 'grid';
|
||||||
|
}
|
||||||
@ -1,11 +1,24 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
/** Testimonials.Quote — the quotation. The app supplies the words. */
|
/** Testimonials.Quote — the quotation. The app supplies the words. */
|
||||||
import { Text } from '$uix/eidos/components/text';
|
import { Text } from '$uix/eidos/components/text';
|
||||||
|
import { testimonialsLayout } from './context';
|
||||||
import type { TestimonialsQuoteProps } from './types';
|
import type { TestimonialsQuoteProps } from './types';
|
||||||
|
|
||||||
let { children, ...rest }: TestimonialsQuoteProps = $props();
|
let { children, ...rest }: TestimonialsQuoteProps = $props();
|
||||||
|
|
||||||
|
const layout = $derived(testimonialsLayout());
|
||||||
|
// The spotlight quote carries the section on its own, so it steps up one size
|
||||||
|
// and centres. `as="p"` because `text-align` is inert on an inline box (F17) —
|
||||||
|
// a `span` would keep the lines flush start and the centring would be a lie.
|
||||||
|
const spotlight = $derived(layout === 'spotlight');
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Text size="lg" wrap="pretty" {...rest}>
|
<Text
|
||||||
|
as={spotlight ? 'p' : undefined}
|
||||||
|
size={spotlight ? 'xl' : 'lg'}
|
||||||
|
align={spotlight ? 'center' : undefined}
|
||||||
|
wrap="pretty"
|
||||||
|
{...rest}
|
||||||
|
>
|
||||||
{@render children?.()}
|
{@render children?.()}
|
||||||
</Text>
|
</Text>
|
||||||
|
|||||||
Loading…
Reference in new issue