ci/woodpecker/push/woodpecker Pipeline was successful
Descendue de 20 px sous la première ligne du chapeau, la lectrice ne montrait plus que sa bulle. Elle ne peut pas non plus sortir par le côté de la carte, à cause de la marge de page et de la gouttière, et l'accordéoniste occupe le seul dessus libre. DA, 03/11 après 19h : « Je ne veux pas d'un oiseau réduit à un morceau ». Elle reste visible à 1440 px sur la page commande, où elle se tient en marge droite : les 61 oiseaux restent visibles. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
373 lines
9.1 KiB
Vue
373 lines
9.1 KiB
Vue
<template>
|
|
<div class="format">
|
|
<header v-if="format && showHeader" class="format-head">
|
|
<!-- The accordion player at the end of the title, on its baseline: on the event card it stood
|
|
at the height of the reader, and its ground line touched the card's link (rules c, h).
|
|
S and from 1200 px: the band above leaves 125 px, and a perched bird keeps a void of its
|
|
own height above it (rule f); 8 px under the baseline, within the 12 px of rule e -->
|
|
<h2 class="format-title">{{ format.title }}<UiOiseauPose nom="accordeoniste" pose="perche" bout left="16px" bottom="-8px" :w="72" retourne ton="accent" :seuil="1200" /></h2>
|
|
<p class="format-text">{{ format.text }}</p>
|
|
</header>
|
|
|
|
<div class="format-grid">
|
|
<!-- Éditorial : le livre et les chansons -->
|
|
<article v-if="book" class="format-card format-card--book">
|
|
<!-- No bird behind the book card (DA, 03/11 after 19h): lowered under the header's first
|
|
line, the reader only showed her bubble; the page margin and the gutter leave her no
|
|
side to come out by, and the free top of the card holds the accordion player. She
|
|
stands on the order page -->
|
|
<div
|
|
class="format-cover"
|
|
role="img"
|
|
:aria-label="book.coverAlt"
|
|
:style="{ backgroundImage: `url(${book.coverImage})` }"
|
|
/>
|
|
<div class="format-body">
|
|
<p class="format-kicker">{{ book.kicker }}</p>
|
|
<h3 class="format-card-title">{{ book.title }}</h3>
|
|
<p class="format-desc">{{ book.description }}</p>
|
|
<div class="format-actions">
|
|
<button type="button" class="fbtn fbtn--main" @click="$emit('open-player')">
|
|
<span class="i-lucide-play h-4 w-4" aria-hidden="true" />
|
|
{{ book.cta?.player }}
|
|
</button>
|
|
<button type="button" class="fbtn" @click="$emit('open-pdf')">
|
|
<span class="i-lucide-book-open h-4 w-4" aria-hidden="true" />
|
|
{{ book.cta?.pdf }}
|
|
</button>
|
|
<NuxtLink to="/economique/modele-eco" class="fbtn fbtn--quiet">
|
|
<span class="i-lucide-list h-4 w-4" aria-hidden="true" />
|
|
Présentation des chapitres
|
|
</NuxtLink>
|
|
<NuxtLink to="/economique/commande" class="fbtn fbtn--quiet">
|
|
<span class="i-lucide-shopping-bag h-4 w-4" aria-hidden="true" />
|
|
Commandez le livre
|
|
</NuxtLink>
|
|
</div>
|
|
</div>
|
|
</article>
|
|
|
|
<!-- Événementiel -->
|
|
<NuxtLink v-if="evenement" :to="evenement.to" class="format-card format-card--event">
|
|
<p class="format-kicker">
|
|
{{ evenement.teaser }}
|
|
<span v-if="evenement.gestation" class="format-state">en gestation</span>
|
|
</p>
|
|
<h3 class="format-card-title format-card-title--event">{{ evenement.subtitle }}</h3>
|
|
<p v-if="evenement.tagline" class="format-tagline">{{ evenement.tagline }}</p>
|
|
<ul v-if="evenement.config.length" class="format-config">
|
|
<li v-for="c in evenement.config" :key="c.label">
|
|
<span :class="`i-lucide-${c.icon}`" class="h-4 w-4" aria-hidden="true" />
|
|
<span>{{ c.label }}</span>
|
|
</li>
|
|
</ul>
|
|
<span class="format-more">
|
|
Voir l'événement
|
|
<span class="i-lucide-arrow-right h-4 w-4" aria-hidden="true" />
|
|
</span>
|
|
</NuxtLink>
|
|
</div>
|
|
|
|
<!-- Reproduction + à qui l'on s'adresse -->
|
|
<div v-if="evenement?.reproduction || hero?.addressees?.length" class="format-repro">
|
|
<p v-if="evenement?.reproduction" class="format-repro-line">
|
|
<span class="format-basins" aria-hidden="true"><i v-for="n in 5" :key="n" /></span>
|
|
{{ evenement.reproduction }}
|
|
</p>
|
|
<div v-if="hero?.addressees?.length" class="format-audience">
|
|
<p class="format-audience-label">{{ hero.audience }}</p>
|
|
<ul>
|
|
<li v-for="a in hero.addressees" :key="a.label">
|
|
<strong>{{ a.label }}</strong> {{ a.value }}
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
withDefaults(defineProps<{
|
|
format?: { title: string, text: string }
|
|
book?: any
|
|
evenement?: any
|
|
hero?: any
|
|
showHeader?: boolean
|
|
}>(), {
|
|
showHeader: true,
|
|
})
|
|
|
|
defineEmits<{
|
|
'open-player': []
|
|
'open-pdf': []
|
|
}>()
|
|
</script>
|
|
|
|
<style scoped>
|
|
.format {
|
|
display: grid;
|
|
gap: 1.5rem;
|
|
}
|
|
|
|
.format-head {
|
|
max-width: 44rem;
|
|
}
|
|
|
|
.format-title {
|
|
margin: 0;
|
|
font-family: var(--font-display);
|
|
font-weight: 800;
|
|
font-size: clamp(1.75rem, 4.2vw, 2.75rem);
|
|
letter-spacing: -0.03em;
|
|
line-height: 1.05;
|
|
color: hsl(var(--color-text));
|
|
}
|
|
|
|
.format-text {
|
|
margin: 0.75rem 0 0;
|
|
font-size: 1.1rem;
|
|
line-height: 1.5;
|
|
color: hsl(var(--color-text) / 0.72);
|
|
}
|
|
|
|
.format-grid {
|
|
isolation: isolate;
|
|
display: grid;
|
|
gap: 1.25rem;
|
|
}
|
|
|
|
@media (min-width: 1024px) {
|
|
.format-grid { grid-template-columns: 1.35fr 1fr; }
|
|
}
|
|
|
|
.format-card {
|
|
position: relative;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.5rem;
|
|
padding: 1.5rem;
|
|
border-radius: 16px;
|
|
background: hsl(var(--color-surface));
|
|
}
|
|
|
|
.format-card--book {
|
|
flex-direction: row;
|
|
gap: 1.5rem;
|
|
}
|
|
|
|
.format-cover {
|
|
flex-shrink: 0;
|
|
width: clamp(6.5rem, 16vw, 10rem);
|
|
aspect-ratio: 1756 / 2480;
|
|
border-radius: 6px;
|
|
background-size: cover;
|
|
background-position: center;
|
|
box-shadow: 0 16px 30px -18px hsl(var(--color-text) / 0.6);
|
|
}
|
|
|
|
.format-body {
|
|
min-width: 0;
|
|
}
|
|
|
|
.format-kicker {
|
|
margin: 0;
|
|
font-family: var(--font-mono);
|
|
font-size: 0.72rem;
|
|
color: hsl(var(--axis-eco));
|
|
}
|
|
|
|
.format-card--event .format-kicker {
|
|
color: hsl(var(--axis-cit));
|
|
}
|
|
|
|
.format-state {
|
|
margin-left: 0.35rem;
|
|
color: hsl(var(--color-text) / 0.5);
|
|
}
|
|
|
|
.format-state::before {
|
|
content: '◌ ';
|
|
}
|
|
|
|
.format-card-title {
|
|
margin: 0.3rem 0 0;
|
|
font-family: var(--font-display);
|
|
font-weight: 800;
|
|
font-size: clamp(1.3rem, 2.4vw, 1.6rem);
|
|
letter-spacing: -0.02em;
|
|
line-height: 1.12;
|
|
color: hsl(var(--color-text));
|
|
}
|
|
|
|
.format-card-title--event {
|
|
font-weight: 700;
|
|
}
|
|
|
|
.format-desc {
|
|
margin: 0.5rem 0 0;
|
|
font-size: 0.95rem;
|
|
line-height: 1.5;
|
|
color: hsl(var(--color-text) / 0.72);
|
|
}
|
|
|
|
.format-actions {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 0.4rem;
|
|
margin-top: 1rem;
|
|
}
|
|
|
|
.fbtn {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 0.4rem;
|
|
min-height: 2.5rem;
|
|
padding: 0.45rem 1rem;
|
|
border-radius: 20px;
|
|
font-size: 0.86rem;
|
|
font-weight: 700;
|
|
color: hsl(var(--color-text) / 0.85);
|
|
background: hsl(var(--color-text) / 0.07);
|
|
transition: transform 0.1s ease, background 0.2s ease;
|
|
}
|
|
|
|
.fbtn:hover { transform: translateY(-1px); background: hsl(var(--axis-eco) / 0.14); }
|
|
.fbtn:active { transform: translateY(0); }
|
|
|
|
.fbtn--main {
|
|
color: hsl(var(--color-bg));
|
|
background: hsl(var(--axis-eco));
|
|
}
|
|
|
|
.fbtn--main:hover { background: hsl(var(--axis-eco) / 0.88); }
|
|
|
|
.fbtn--quiet {
|
|
font-weight: 400;
|
|
background: transparent;
|
|
}
|
|
|
|
.format-card--event {
|
|
color: hsl(var(--color-text));
|
|
transition: transform 0.12s ease;
|
|
}
|
|
|
|
.format-card--event:hover {
|
|
transform: translateY(-3px);
|
|
}
|
|
|
|
.format-tagline {
|
|
margin: 0.2rem 0 0;
|
|
font-family: var(--font-display);
|
|
font-size: 1.05rem;
|
|
color: hsl(var(--color-text) / 0.7);
|
|
}
|
|
|
|
.format-config {
|
|
list-style: none;
|
|
margin: 0.75rem 0 0;
|
|
padding: 0;
|
|
display: grid;
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
gap: 0.5rem;
|
|
font-size: 0.85rem;
|
|
color: hsl(var(--color-text) / 0.78);
|
|
}
|
|
|
|
.format-config li {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.45rem;
|
|
}
|
|
|
|
.format-config li > span:first-child {
|
|
color: hsl(var(--axis-cit));
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.format-more {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 0.35rem;
|
|
margin-top: auto;
|
|
padding-top: 1rem;
|
|
font-family: var(--font-display);
|
|
font-weight: 700;
|
|
color: hsl(var(--axis-cit));
|
|
}
|
|
|
|
/* Reproduction */
|
|
.format-repro {
|
|
display: grid;
|
|
gap: 1.25rem;
|
|
padding: 1.25rem 0 0;
|
|
}
|
|
|
|
@media (min-width: 768px) {
|
|
.format-repro {
|
|
grid-template-columns: 1fr 1fr;
|
|
align-items: start;
|
|
}
|
|
}
|
|
|
|
.format-repro-line {
|
|
margin: 0;
|
|
font-family: var(--font-display);
|
|
font-weight: 700;
|
|
font-size: clamp(1.15rem, 2.2vw, 1.4rem);
|
|
line-height: 1.25;
|
|
letter-spacing: -0.015em;
|
|
color: hsl(var(--color-text));
|
|
}
|
|
|
|
/* One basin, then its copies */
|
|
.format-basins {
|
|
display: flex;
|
|
gap: 0.35rem;
|
|
margin-bottom: 0.6rem;
|
|
}
|
|
|
|
.format-basins i {
|
|
display: block;
|
|
width: 0.8rem;
|
|
height: 0.8rem;
|
|
border-radius: 50%;
|
|
box-shadow: inset 0 0 0 1.5px hsl(var(--axis-cit) / 0.6);
|
|
}
|
|
|
|
.format-basins i:first-child {
|
|
background: hsl(var(--axis-cit));
|
|
box-shadow: none;
|
|
}
|
|
|
|
.format-audience-label {
|
|
margin: 0 0 0.5rem;
|
|
font-family: var(--font-mono);
|
|
font-size: 0.72rem;
|
|
color: hsl(var(--color-text) / 0.5);
|
|
}
|
|
|
|
.format-audience ul {
|
|
list-style: none;
|
|
margin: 0;
|
|
padding: 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.3rem;
|
|
font-size: 0.95rem;
|
|
color: hsl(var(--color-text) / 0.7);
|
|
}
|
|
|
|
.format-audience strong {
|
|
color: hsl(var(--color-text));
|
|
}
|
|
|
|
@media (max-width: 640px) {
|
|
.format-card--book { flex-direction: column; }
|
|
.format-config { grid-template-columns: 1fr; }
|
|
}
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.fbtn, .format-card--event { transition: none; }
|
|
}
|
|
</style>
|