Files
librodrome/app/components/home/BookSection.vue
T
YvvandClaude Opus 5.5 201cfbbb50 design : accueil console seul, vrai §, curseurs animés, statuts, lecteur
- accueil : la console devient l'accueil unique (variantes B/C, sélecteur
  et ancien accueil retirés) ; curseurs qui montent de l'asservissement et
  dérivent seuls, un axe mis en avant à tour de rôle, arrêt au clic,
  immobiles en prefers-reduced-motion ; « AUTONOMIE » devant chaque axe,
  leviers mis en valeur, ligne des trois autonomies en couleurs
- logo : § de Playfair Display (SIL OFL) vectorisé, composant partagé
  UiSectionSign (en-tête, page événement) + favicon.svg
- UiStatusBadge (production / développement / gestation) sur l'accueil,
  les pages d'axe et les pages projet
- liens libreDecision / SejeteralO fixés sur la prod (plus de repli localhost)
- logiciel libre : bouton v1 dans la carte projet en tête de page
- couverture du livre : recadrage corrigé (BookSection)
- texte courant en Public Sans (zéros non barrés)
- lecteur : la pastille persistante ne masque plus la navigation du
  BookPlayer ; lecture directe du MP3 (les .ogg n'existent pas : 404)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 05:59:33 +02:00

127 lines
3.6 KiB
Vue

<template>
<section :class="compact ? 'section-book-compact' : 'section-padding'">
<div class="container-content">
<div :class="['grid items-center', compact ? 'gap-5 md:grid-cols-[auto_1fr]' : 'gap-12 md:grid-cols-2']">
<!-- Book cover -->
<UiScrollReveal>
<div class="book-cover-wrapper relative">
<div
:class="['book-cover-3d', compact && 'book-cover-3d--compact']"
:style="{ backgroundImage: `url(${content?.book.coverImage})` }"
role="img"
:aria-label="content?.book.coverAlt"
/>
</div>
</UiScrollReveal>
<!-- Content + CTAs -->
<div>
<UiScrollReveal>
<p :class="['font-mono tracking-widest text-accent uppercase', compact ? 'text-xs mb-1' : 'text-sm mb-2']">
{{ content?.book.kicker }}
</p>
<h2 :class="['book-heading font-display font-bold tracking-tight text-white', compact && 'book-heading--compact']">
<template v-if="compact">
<span class="block">{{ titleLine1 }}</span>
<span class="block" style="color: hsl(var(--color-text) / 0.55)">{{ titleLine2 }}</span>
</template>
<template v-else>{{ content?.book.title }}</template>
</h2>
</UiScrollReveal>
<UiScrollReveal :delay="100">
<p :class="['leading-relaxed', compact ? 'mt-2 text-sm' : 'mt-4 text-lg text-white/60']"
:style="compact ? 'color: hsl(var(--color-text-muted)); font-size: 0.85rem' : ''">
{{ content?.book.description }}
</p>
</UiScrollReveal>
<UiScrollReveal :delay="200">
<BookActions
:show-chapters="showChapters"
@open-player="$emit('open-player')"
@open-pdf="$emit('open-pdf')"
/>
</UiScrollReveal>
</div>
</div>
</div>
</section>
</template>
<script setup lang="ts">
withDefaults(defineProps<{
showChapters?: boolean
compact?: boolean
}>(), {
showChapters: true,
compact: false,
})
defineEmits<{
'open-player': []
'open-pdf': []
}>()
const { data: content } = await usePageContent('home')
const titleParts = computed(() => {
const title = content.value?.book.title ?? ''
const idx = title.indexOf('—')
if (idx === -1) return [title, '']
return [title.slice(0, idx).trim(), '— ' + title.slice(idx + 1).trim()]
})
const titleLine1 = computed(() => titleParts.value[0])
const titleLine2 = computed(() => titleParts.value[1])
</script>
<style scoped>
.section-book-compact {
padding: 0;
}
.book-cover-wrapper {
perspective: 800px;
display: flex;
justify-content: center;
}
.book-cover-3d {
width: 100%;
max-width: 360px;
aspect-ratio: 1756 / 2480;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
border-radius: 0.75rem;
overflow: hidden;
border: 1px solid hsl(var(--color-text) / 0.1);
box-shadow:
0 12px 40px hsl(var(--color-text) / 0.15),
0 0 0 1px hsl(var(--color-text) / 0.08);
transition: transform 0.5s cubic-bezier(0.645, 0.045, 0.355, 1),
box-shadow 0.5s ease;
}
.book-cover-3d--compact {
max-width: 120px;
}
.book-cover-3d:hover {
transform: rotateY(-8deg) rotateX(3deg) scale(1.02);
box-shadow:
12px 16px 48px hsl(var(--color-text) / 0.2),
0 0 0 1px hsl(var(--color-primary) / 0.2);
}
.book-heading {
font-size: clamp(1.625rem, 4vw, 2.125rem);
}
.book-heading--compact {
font-size: clamp(0.95rem, 2.5vw, 1.15rem);
line-height: 1.35;
}
</style>