Refonte UI complète : palettes saisonnières, typo moderne, paroles nettoyées, Shadoks
- Nettoyage paroles : suppression instructions Suno AI, corrections prononciation (11 fichiers) - 4 palettes saisonnières (Automne/Hiver dark, Printemps/Été light) avec sélecteur - Typographie modernisée : Outfit (display) + Inter (sans) remplacent Syne + Space Grotesk - Styles adaptatifs : CSS vars pour couleurs, overrides light mode complets - Mini-player : bouton Next ajouté, flèche expand plus visible - BookPlayer : fix scroll mode paginé, croix de fermeture visible - Illustrations Shadoks inline SVG dans 11 composants/pages - Suppression soulignés navigation, reset boutons, bordures propres Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -20,7 +20,7 @@ export default defineAppConfig({
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
gratewizard: {
|
gratewizard: {
|
||||||
url: 'https://gratewizard.ml',
|
url: import.meta.dev ? 'http://localhost:3009' : 'https://gratewizard.ml',
|
||||||
popup: {
|
popup: {
|
||||||
width: 420,
|
width: 420,
|
||||||
height: 720,
|
height: 720,
|
||||||
|
|||||||
@@ -14,6 +14,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
const paletteStore = usePaletteStore()
|
||||||
|
onMounted(() => paletteStore.applyToDOM())
|
||||||
|
|
||||||
useHead({
|
useHead({
|
||||||
titleTemplate: (title) => {
|
titleTemplate: (title) => {
|
||||||
return title ? `${title} — Le Librodrome` : 'Le librodrome'
|
return title ? `${title} — Le Librodrome` : 'Le librodrome'
|
||||||
|
|||||||
@@ -60,10 +60,10 @@
|
|||||||
|
|
||||||
@keyframes glow-pulse {
|
@keyframes glow-pulse {
|
||||||
0%, 100% {
|
0%, 100% {
|
||||||
box-shadow: 0 0 8px hsl(12 76% 48% / 0.3);
|
box-shadow: 0 0 8px hsl(var(--color-primary) / 0.3);
|
||||||
}
|
}
|
||||||
50% {
|
50% {
|
||||||
box-shadow: 0 0 24px hsl(12 76% 48% / 0.6);
|
box-shadow: 0 0 24px hsl(var(--color-primary) / 0.6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
/* This file provides fallback and utility classes */
|
/* This file provides fallback and utility classes */
|
||||||
|
|
||||||
.font-display {
|
.font-display {
|
||||||
font-family: 'Syne', system-ui, sans-serif;
|
font-family: 'Outfit', system-ui, sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
.font-sans {
|
.font-sans {
|
||||||
font-family: 'Space Grotesk', system-ui, sans-serif;
|
font-family: 'Inter', system-ui, sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
.font-mono {
|
.font-mono {
|
||||||
|
|||||||
@@ -3,20 +3,20 @@
|
|||||||
@import './typography.css';
|
@import './typography.css';
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--color-primary: 12 76% 48%;
|
--color-primary: 18 80% 45%;
|
||||||
--color-accent: 36 80% 52%;
|
--color-accent: 32 85% 50%;
|
||||||
--color-bg: 20 8% 3.5%;
|
--color-bg: 16 12% 4%;
|
||||||
--color-surface: 20 8% 8%;
|
--color-surface: 16 12% 9%;
|
||||||
--color-surface-light: 20 8% 13%;
|
--color-surface-light: 16 10% 14%;
|
||||||
--color-text: 0 0% 100%;
|
--color-text: 0 0% 100%;
|
||||||
--color-text-muted: 0 0% 100% / 0.6;
|
--color-text-muted: 0 0% 60%;
|
||||||
|
|
||||||
--header-height: 4rem;
|
--header-height: 4rem;
|
||||||
--player-height: 0rem;
|
--player-height: 0rem;
|
||||||
--sidebar-width: 280px;
|
--sidebar-width: 280px;
|
||||||
|
|
||||||
--font-display: 'Syne', sans-serif;
|
--font-display: 'Outfit', sans-serif;
|
||||||
--font-sans: 'Space Grotesk', sans-serif;
|
--font-sans: 'Inter', sans-serif;
|
||||||
--font-mono: 'JetBrains Mono', monospace;
|
--font-mono: 'JetBrains Mono', monospace;
|
||||||
|
|
||||||
--ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
|
--ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
|
||||||
@@ -43,9 +43,22 @@ body {
|
|||||||
min-height: 100dvh;
|
min-height: 100dvh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
border: none;
|
||||||
|
background: none;
|
||||||
|
cursor: pointer;
|
||||||
|
font: inherit;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
::selection {
|
::selection {
|
||||||
background-color: hsl(var(--color-primary) / 0.3);
|
background-color: hsl(var(--color-primary) / 0.3);
|
||||||
color: white;
|
color: hsl(var(--color-text));
|
||||||
}
|
}
|
||||||
|
|
||||||
:focus-visible {
|
:focus-visible {
|
||||||
@@ -72,6 +85,78 @@ body {
|
|||||||
background: hsl(var(--color-text) / 0.25);
|
background: hsl(var(--color-text) / 0.25);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ═══ Light mode overrides ═══ */
|
||||||
|
.palette-light {
|
||||||
|
color-scheme: light;
|
||||||
|
}
|
||||||
|
|
||||||
|
.palette-light,
|
||||||
|
.palette-light .text-white {
|
||||||
|
color: hsl(var(--color-text));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* white with opacity → dark text with same opacity */
|
||||||
|
.palette-light .text-white\/20 { color: hsl(var(--color-text) / 0.2); }
|
||||||
|
.palette-light .text-white\/30 { color: hsl(var(--color-text) / 0.3); }
|
||||||
|
.palette-light .text-white\/40 { color: hsl(var(--color-text) / 0.4); }
|
||||||
|
.palette-light .text-white\/45 { color: hsl(var(--color-text) / 0.45); }
|
||||||
|
.palette-light .text-white\/50 { color: hsl(var(--color-text) / 0.5); }
|
||||||
|
.palette-light .text-white\/60 { color: hsl(var(--color-text) / 0.6); }
|
||||||
|
.palette-light .text-white\/70 { color: hsl(var(--color-text) / 0.7); }
|
||||||
|
.palette-light .text-white\/80 { color: hsl(var(--color-text) / 0.8); }
|
||||||
|
.palette-light .text-white\/85 { color: hsl(var(--color-text) / 0.85); }
|
||||||
|
|
||||||
|
/* white backgrounds → surface tones */
|
||||||
|
.palette-light .bg-white\/5 { background-color: hsl(var(--color-text) / 0.04); }
|
||||||
|
.palette-light .bg-white\/8 { background-color: hsl(var(--color-text) / 0.06); }
|
||||||
|
.palette-light .bg-white\/10 { background-color: hsl(var(--color-text) / 0.07); }
|
||||||
|
|
||||||
|
/* borders */
|
||||||
|
.palette-light .border-white\/8 { border-color: hsl(var(--color-text) / 0.1); }
|
||||||
|
|
||||||
|
/* hover overrides */
|
||||||
|
.palette-light .hover\:text-white:hover,
|
||||||
|
.palette-light .hover\:text-white\/70:hover,
|
||||||
|
.palette-light .hover\:text-white\/80:hover {
|
||||||
|
color: hsl(var(--color-text));
|
||||||
|
}
|
||||||
|
.palette-light .hover\:text-white\/60:hover {
|
||||||
|
color: hsl(var(--color-text) / 0.6);
|
||||||
|
}
|
||||||
|
.palette-light .hover\:bg-white\/5:hover {
|
||||||
|
background-color: hsl(var(--color-text) / 0.04);
|
||||||
|
}
|
||||||
|
.palette-light .hover\:bg-white\/10:hover {
|
||||||
|
background-color: hsl(var(--color-text) / 0.07);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* placeholder overrides */
|
||||||
|
.palette-light .placeholder\:text-white\/30::placeholder {
|
||||||
|
color: hsl(var(--color-text) / 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prose/content in light mode */
|
||||||
|
.palette-light .prose { color: hsl(var(--color-text)); }
|
||||||
|
.palette-light .prose :where(h1,h2,h3,h4,h5,h6) { color: hsl(var(--color-text)); }
|
||||||
|
|
||||||
|
/* Active states */
|
||||||
|
.palette-light .text-white\! { color: hsl(var(--color-text)) !important; }
|
||||||
|
.palette-light .active-class .text-white\! { color: hsl(var(--color-text)) !important; }
|
||||||
|
|
||||||
|
/* text-gradient in light mode */
|
||||||
|
.palette-light .text-gradient {
|
||||||
|
background-image: linear-gradient(to right, hsl(var(--color-primary)), hsl(var(--color-accent)));
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* card surfaces */
|
||||||
|
.palette-light .card-surface {
|
||||||
|
background: hsl(var(--color-surface));
|
||||||
|
border-color: hsl(var(--color-text) / 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
/* Page transitions */
|
/* Page transitions */
|
||||||
.page-enter-active,
|
.page-enter-active,
|
||||||
.page-leave-active {
|
.page-leave-active {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
font-family: var(--font-sans);
|
font-family: var(--font-sans);
|
||||||
font-size: 1.125rem;
|
font-size: 1.125rem;
|
||||||
line-height: 1.8;
|
line-height: 1.8;
|
||||||
color: hsl(0 0% 100% / 0.90);
|
color: hsl(var(--color-text) / 0.90);
|
||||||
max-width: 65ch;
|
max-width: 65ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -13,11 +13,11 @@
|
|||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
line-height: 1.25;
|
line-height: 1.25;
|
||||||
letter-spacing: -0.02em;
|
letter-spacing: -0.02em;
|
||||||
color: white;
|
color: hsl(var(--color-text));
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
margin-bottom: 1.5rem;
|
margin-bottom: 1.5rem;
|
||||||
padding-bottom: 0.75rem;
|
padding-bottom: 0.75rem;
|
||||||
border-bottom: 2px solid hsl(12 76% 48% / 0.4);
|
border-bottom: 2px solid hsl(var(--color-primary) / 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
.prose h2 {
|
.prose h2 {
|
||||||
@@ -26,11 +26,11 @@
|
|||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
line-height: 1.3;
|
line-height: 1.3;
|
||||||
letter-spacing: -0.01em;
|
letter-spacing: -0.01em;
|
||||||
color: white;
|
color: hsl(var(--color-text));
|
||||||
margin-top: 3.5rem;
|
margin-top: 3.5rem;
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
padding-left: 0.75rem;
|
padding-left: 0.75rem;
|
||||||
border-left: 3px solid hsl(12 76% 48% / 0.5);
|
border-left: 3px solid hsl(var(--color-primary) / 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
.prose h3 {
|
.prose h3 {
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
font-size: clamp(1.25rem, 3vw, 1.625rem);
|
font-size: clamp(1.25rem, 3vw, 1.625rem);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
color: hsl(0 0% 100% / 0.92);
|
color: hsl(var(--color-text) / 0.92);
|
||||||
margin-top: 3rem;
|
margin-top: 3rem;
|
||||||
margin-bottom: 0.75rem;
|
margin-bottom: 0.75rem;
|
||||||
}
|
}
|
||||||
@@ -49,7 +49,7 @@
|
|||||||
width: 0.5rem;
|
width: 0.5rem;
|
||||||
height: 0.5rem;
|
height: 0.5rem;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: hsl(36 80% 52%);
|
background: hsl(var(--color-accent));
|
||||||
margin-right: 0.625rem;
|
margin-right: 0.625rem;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
position: relative;
|
position: relative;
|
||||||
@@ -61,7 +61,7 @@
|
|||||||
font-size: clamp(1.065rem, 2.5vw, 1.25rem);
|
font-size: clamp(1.065rem, 2.5vw, 1.25rem);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
line-height: 1.45;
|
line-height: 1.45;
|
||||||
color: hsl(0 0% 100% / 0.85);
|
color: hsl(var(--color-text) / 0.85);
|
||||||
margin-top: 2.5rem;
|
margin-top: 2.5rem;
|
||||||
margin-bottom: 0.625rem;
|
margin-bottom: 0.625rem;
|
||||||
}
|
}
|
||||||
@@ -69,7 +69,7 @@
|
|||||||
.prose h4::before {
|
.prose h4::before {
|
||||||
content: '//';
|
content: '//';
|
||||||
font-family: var(--font-mono);
|
font-family: var(--font-mono);
|
||||||
color: hsl(36 80% 52%);
|
color: hsl(var(--color-accent));
|
||||||
margin-right: 0.5rem;
|
margin-right: 0.5rem;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
@@ -78,7 +78,7 @@
|
|||||||
.prose h2 + p,
|
.prose h2 + p,
|
||||||
.prose h3 + p {
|
.prose h3 + p {
|
||||||
font-size: 1.175rem;
|
font-size: 1.175rem;
|
||||||
color: hsl(0 0% 100% / 0.75);
|
color: hsl(var(--color-text) / 0.75);
|
||||||
line-height: 1.85;
|
line-height: 1.85;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,25 +88,25 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.prose a {
|
.prose a {
|
||||||
color: hsl(12 76% 68%);
|
color: hsl(var(--color-primary) / 0.85);
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
text-decoration-color: hsl(12 76% 58% / 0.3);
|
text-decoration-color: hsl(var(--color-primary) / 0.3);
|
||||||
text-underline-offset: 3px;
|
text-underline-offset: 3px;
|
||||||
transition: text-decoration-color 0.2s;
|
transition: text-decoration-color 0.2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.prose a:hover {
|
.prose a:hover {
|
||||||
text-decoration-color: hsl(12 76% 58%);
|
text-decoration-color: hsl(var(--color-primary));
|
||||||
}
|
}
|
||||||
|
|
||||||
.prose blockquote {
|
.prose blockquote {
|
||||||
margin: 2rem 0;
|
margin: 2rem 0;
|
||||||
padding: 1rem 1.5rem;
|
padding: 1rem 1.5rem;
|
||||||
border-left: 3px solid hsl(12 76% 58%);
|
border-left: 3px solid hsl(var(--color-primary));
|
||||||
background: hsl(240 10% 8%);
|
background: hsl(var(--color-surface));
|
||||||
border-radius: 0 0.5rem 0.5rem 0;
|
border-radius: 0 0.5rem 0.5rem 0;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
color: hsl(0 0% 100% / 0.75);
|
color: hsl(var(--color-text) / 0.75);
|
||||||
}
|
}
|
||||||
|
|
||||||
.prose blockquote p:last-child {
|
.prose blockquote p:last-child {
|
||||||
@@ -116,17 +116,17 @@
|
|||||||
.prose code {
|
.prose code {
|
||||||
font-family: var(--font-mono);
|
font-family: var(--font-mono);
|
||||||
font-size: 0.875em;
|
font-size: 0.875em;
|
||||||
background: hsl(240 10% 12%);
|
background: hsl(var(--color-surface-light));
|
||||||
padding: 0.2em 0.4em;
|
padding: 0.2em 0.4em;
|
||||||
border-radius: 0.25rem;
|
border-radius: 0.25rem;
|
||||||
color: hsl(31 97% 66%);
|
color: hsl(var(--color-accent));
|
||||||
}
|
}
|
||||||
|
|
||||||
.prose pre {
|
.prose pre {
|
||||||
margin: 2rem 0;
|
margin: 2rem 0;
|
||||||
padding: 1.5rem;
|
padding: 1.5rem;
|
||||||
background: hsl(240 10% 6%);
|
background: hsl(var(--color-bg));
|
||||||
border: 1px solid hsl(0 0% 100% / 0.08);
|
border: 1px solid hsl(var(--color-text) / 0.08);
|
||||||
border-radius: 0.75rem;
|
border-radius: 0.75rem;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
}
|
}
|
||||||
@@ -134,7 +134,7 @@
|
|||||||
.prose pre code {
|
.prose pre code {
|
||||||
background: none;
|
background: none;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
color: hsl(0 0% 100% / 0.87);
|
color: hsl(var(--color-text) / 0.87);
|
||||||
}
|
}
|
||||||
|
|
||||||
.prose ul,
|
.prose ul,
|
||||||
@@ -149,22 +149,22 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.prose li::marker {
|
.prose li::marker {
|
||||||
color: hsl(12 76% 58%);
|
color: hsl(var(--color-primary));
|
||||||
}
|
}
|
||||||
|
|
||||||
.prose hr {
|
.prose hr {
|
||||||
margin: 3rem 0;
|
margin: 3rem 0;
|
||||||
border: none;
|
border: none;
|
||||||
border-top: 1px solid hsl(0 0% 100% / 0.1);
|
border-top: 1px solid hsl(var(--color-text) / 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.prose strong {
|
.prose strong {
|
||||||
color: white;
|
color: hsl(var(--color-text));
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
.prose em {
|
.prose em {
|
||||||
color: hsl(0 0% 100% / 0.9);
|
color: hsl(var(--color-text) / 0.9);
|
||||||
}
|
}
|
||||||
|
|
||||||
.prose img {
|
.prose img {
|
||||||
|
|||||||
@@ -50,7 +50,7 @@
|
|||||||
<template v-if="isScrollMode">{{ scrollPercent }}%</template>
|
<template v-if="isScrollMode">{{ scrollPercent }}%</template>
|
||||||
<template v-else>{{ currentPage + 1 }}<span class="op-40">/</span>{{ totalPages }}</template>
|
<template v-else>{{ currentPage + 1 }}<span class="op-40">/</span>{{ totalPages }}</template>
|
||||||
</span>
|
</span>
|
||||||
<button class="reader-bar-btn" @click="close" aria-label="Fermer">
|
<button class="reader-bar-btn reader-bar-close" @click="close" aria-label="Fermer">
|
||||||
<div class="i-lucide-x h-5 w-5" />
|
<div class="i-lucide-x h-5 w-5" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -633,6 +633,14 @@ onUnmounted(() => {
|
|||||||
color: white;
|
color: white;
|
||||||
background: hsl(0 0% 100% / 0.06);
|
background: hsl(0 0% 100% / 0.06);
|
||||||
}
|
}
|
||||||
|
.reader-bar-close {
|
||||||
|
color: hsl(0 0% 100% / 0.7);
|
||||||
|
background: hsl(0 0% 100% / 0.08);
|
||||||
|
}
|
||||||
|
.reader-bar-close:hover {
|
||||||
|
color: white;
|
||||||
|
background: hsl(0 70% 55% / 0.3);
|
||||||
|
}
|
||||||
.reader-bar-title {
|
.reader-bar-title {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
font-family: var(--font-display, 'Syne', sans-serif);
|
font-family: var(--font-display, 'Syne', sans-serif);
|
||||||
@@ -744,7 +752,7 @@ onUnmounted(() => {
|
|||||||
position: relative;
|
position: relative;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden auto;
|
||||||
border-radius: 0.75rem;
|
border-radius: 0.75rem;
|
||||||
background: hsl(20 8% 5% / 0.4);
|
background: hsl(20 8% 5% / 0.4);
|
||||||
backdrop-filter: blur(16px);
|
backdrop-filter: blur(16px);
|
||||||
@@ -796,12 +804,16 @@ onUnmounted(() => {
|
|||||||
.reader-columns :deep(h3) {
|
.reader-columns :deep(h3) {
|
||||||
break-after: avoid;
|
break-after: avoid;
|
||||||
}
|
}
|
||||||
.reader-columns :deep(p),
|
|
||||||
.reader-columns :deep(blockquote),
|
.reader-columns :deep(blockquote),
|
||||||
.reader-columns :deep(ul),
|
.reader-columns :deep(ul),
|
||||||
.reader-columns :deep(ol) {
|
.reader-columns :deep(ol) {
|
||||||
break-inside: avoid;
|
break-inside: avoid;
|
||||||
}
|
}
|
||||||
|
/* p with pre-line (lyrics) can be taller than a column — allow break */
|
||||||
|
.reader-columns :deep(p) {
|
||||||
|
break-inside: auto;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
/* Page-turn shadow overlay */
|
/* Page-turn shadow overlay */
|
||||||
.reader-shadow {
|
.reader-shadow {
|
||||||
|
|||||||
@@ -57,6 +57,6 @@ function playSong(song: Song) {
|
|||||||
.chapter-title {
|
.chapter-title {
|
||||||
font-size: clamp(2rem, 5vw, 2.75rem);
|
font-size: clamp(2rem, 5vw, 2.75rem);
|
||||||
padding-bottom: 0.75rem;
|
padding-bottom: 0.75rem;
|
||||||
border-bottom: 2px solid hsl(12 76% 48% / 0.4);
|
border-bottom: 2px solid hsl(var(--color-primary) / 0.4);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,5 +1,34 @@
|
|||||||
<template>
|
<template>
|
||||||
<section class="section-padding">
|
<section class="relative overflow-hidden section-padding">
|
||||||
|
<!-- Shadok thinker: ovoid character sitting, hand on chin, thinking bubble -->
|
||||||
|
<svg class="shadok-thinker" viewBox="0 0 220 280" fill="none" aria-hidden="true">
|
||||||
|
<!-- Body (seated, leaning forward) -->
|
||||||
|
<ellipse cx="100" cy="160" rx="42" ry="50" fill="currentColor" opacity="0.85"/>
|
||||||
|
<!-- Head (tilted) -->
|
||||||
|
<ellipse cx="110" cy="95" rx="25" ry="24" fill="currentColor" opacity="0.8"/>
|
||||||
|
<!-- Neck -->
|
||||||
|
<path d="M100 118 Q105 110 108 105" stroke="currentColor" stroke-width="6" stroke-linecap="round" opacity="0.6" fill="none"/>
|
||||||
|
<!-- Eyes (contemplative) -->
|
||||||
|
<circle cx="103" cy="90" r="4.5" fill="currentColor" opacity="0.2"/>
|
||||||
|
<circle cx="120" cy="90" r="4.5" fill="currentColor" opacity="0.2"/>
|
||||||
|
<circle cx="104" cy="89" r="1.8" fill="currentColor" opacity="0.5"/>
|
||||||
|
<circle cx="121" cy="89" r="1.8" fill="currentColor" opacity="0.5"/>
|
||||||
|
<!-- Arm to chin -->
|
||||||
|
<line x1="140" y1="145" x2="130" y2="108" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||||
|
<!-- Hand on chin -->
|
||||||
|
<circle cx="130" cy="105" r="5" fill="currentColor" opacity="0.45"/>
|
||||||
|
<!-- Seated legs (crossed/bent) -->
|
||||||
|
<path d="M75 205 Q60 230 50 240" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6" fill="none"/>
|
||||||
|
<path d="M120 205 Q140 220 145 240" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6" fill="none"/>
|
||||||
|
<!-- Feet -->
|
||||||
|
<path d="M50 240 L38 243 M50 240 L45 246" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" opacity="0.5"/>
|
||||||
|
<path d="M145 240 L133 243 M145 240 L140 246" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" opacity="0.5"/>
|
||||||
|
<!-- Thinking bubbles -->
|
||||||
|
<circle cx="150" cy="78" r="5" fill="currentColor" opacity="0.3"/>
|
||||||
|
<circle cx="165" cy="62" r="8" fill="currentColor" opacity="0.25"/>
|
||||||
|
<circle cx="185" cy="42" r="12" fill="currentColor" opacity="0.2"/>
|
||||||
|
</svg>
|
||||||
|
|
||||||
<div class="container-content">
|
<div class="container-content">
|
||||||
<div class="grid items-center gap-12 md:grid-cols-2">
|
<div class="grid items-center gap-12 md:grid-cols-2">
|
||||||
<!-- Book cover -->
|
<!-- Book cover -->
|
||||||
@@ -63,10 +92,10 @@ const { data: content } = await usePageContent('home')
|
|||||||
aspect-ratio: 3 / 4;
|
aspect-ratio: 3 / 4;
|
||||||
border-radius: 0.75rem;
|
border-radius: 0.75rem;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border: 1px solid hsl(20 8% 18%);
|
border: 1px solid hsl(var(--color-text) / 0.1);
|
||||||
box-shadow:
|
box-shadow:
|
||||||
0 12px 40px hsl(0 0% 0% / 0.5),
|
0 12px 40px hsl(var(--color-text) / 0.15),
|
||||||
0 0 0 1px hsl(20 8% 15%);
|
0 0 0 1px hsl(var(--color-text) / 0.08);
|
||||||
transition: transform 0.5s cubic-bezier(0.645, 0.045, 0.355, 1),
|
transition: transform 0.5s cubic-bezier(0.645, 0.045, 0.355, 1),
|
||||||
box-shadow 0.5s ease;
|
box-shadow 0.5s ease;
|
||||||
max-width: 360px;
|
max-width: 360px;
|
||||||
@@ -75,8 +104,8 @@ const { data: content } = await usePageContent('home')
|
|||||||
.book-cover-3d:hover {
|
.book-cover-3d:hover {
|
||||||
transform: rotateY(-8deg) rotateX(3deg) scale(1.02);
|
transform: rotateY(-8deg) rotateX(3deg) scale(1.02);
|
||||||
box-shadow:
|
box-shadow:
|
||||||
12px 16px 48px hsl(0 0% 0% / 0.6),
|
12px 16px 48px hsl(var(--color-text) / 0.2),
|
||||||
0 0 0 1px hsl(12 76% 48% / 0.2);
|
0 0 0 1px hsl(var(--color-primary) / 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.book-cover-img {
|
.book-cover-img {
|
||||||
@@ -89,4 +118,24 @@ const { data: content } = await usePageContent('home')
|
|||||||
.heading-section {
|
.heading-section {
|
||||||
font-size: clamp(1.625rem, 4vw, 2.125rem);
|
font-size: clamp(1.625rem, 4vw, 2.125rem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.shadok-thinker {
|
||||||
|
position: absolute;
|
||||||
|
right: 3%;
|
||||||
|
bottom: 8%;
|
||||||
|
width: clamp(90px, 12vw, 170px);
|
||||||
|
opacity: 0.1;
|
||||||
|
pointer-events: none;
|
||||||
|
color: hsl(var(--color-accent));
|
||||||
|
animation: shadok-float-thinker 10s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes shadok-float-thinker {
|
||||||
|
0%, 100% { transform: translateY(0); }
|
||||||
|
50% { transform: translateY(-8px); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.shadok-thinker { display: none; }
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -4,7 +4,24 @@
|
|||||||
<div class="grid items-center gap-12 md:grid-cols-2">
|
<div class="grid items-center gap-12 md:grid-cols-2">
|
||||||
<!-- Book cover -->
|
<!-- Book cover -->
|
||||||
<UiScrollReveal>
|
<UiScrollReveal>
|
||||||
<div class="book-cover-wrapper">
|
<div class="book-cover-wrapper relative">
|
||||||
|
<!-- Shadok pumper -->
|
||||||
|
<svg class="shadok-pumper" viewBox="0 0 200 240" fill="none" aria-hidden="true">
|
||||||
|
<ellipse cx="100" cy="130" rx="55" ry="65" fill="currentColor" opacity="0.9"/>
|
||||||
|
<ellipse cx="100" cy="60" rx="30" ry="28" fill="currentColor" opacity="0.85"/>
|
||||||
|
<circle cx="88" cy="54" r="6" fill="currentColor" opacity="0.2"/>
|
||||||
|
<circle cx="112" cy="54" r="6" fill="currentColor" opacity="0.2"/>
|
||||||
|
<circle cx="90" cy="53" r="2.5" fill="currentColor" opacity="0.5"/>
|
||||||
|
<circle cx="114" cy="53" r="2.5" fill="currentColor" opacity="0.5"/>
|
||||||
|
<polygon points="100,68 115,78 85,78" fill="currentColor" opacity="0.6"/>
|
||||||
|
<line x1="80" y1="192" x2="70" y2="230" stroke="currentColor" stroke-width="4" stroke-linecap="round" opacity="0.7"/>
|
||||||
|
<line x1="120" y1="192" x2="130" y2="230" stroke="currentColor" stroke-width="4" stroke-linecap="round" opacity="0.7"/>
|
||||||
|
<line x1="70" y1="230" x2="55" y2="232" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.5"/>
|
||||||
|
<line x1="130" y1="230" x2="145" y2="232" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.5"/>
|
||||||
|
<line x1="155" y1="110" x2="190" y2="90" stroke="currentColor" stroke-width="4" stroke-linecap="round" opacity="0.6"/>
|
||||||
|
<line x1="190" y1="90" x2="190" y2="120" stroke="currentColor" stroke-width="4" stroke-linecap="round" opacity="0.6"/>
|
||||||
|
<rect x="180" y="118" width="18" height="40" rx="3" fill="currentColor" opacity="0.4"/>
|
||||||
|
</svg>
|
||||||
<div class="book-cover-3d">
|
<div class="book-cover-3d">
|
||||||
<img
|
<img
|
||||||
:src="content?.book.coverImage"
|
:src="content?.book.coverImage"
|
||||||
@@ -68,10 +85,10 @@ const { data: content } = await usePageContent('home')
|
|||||||
aspect-ratio: 3 / 4;
|
aspect-ratio: 3 / 4;
|
||||||
border-radius: 0.75rem;
|
border-radius: 0.75rem;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border: 1px solid hsl(20 8% 18%);
|
border: 1px solid hsl(var(--color-text) / 0.1);
|
||||||
box-shadow:
|
box-shadow:
|
||||||
0 12px 40px hsl(0 0% 0% / 0.5),
|
0 12px 40px hsl(var(--color-text) / 0.15),
|
||||||
0 0 0 1px hsl(20 8% 15%);
|
0 0 0 1px hsl(var(--color-text) / 0.08);
|
||||||
transition: transform 0.5s cubic-bezier(0.645, 0.045, 0.355, 1),
|
transition: transform 0.5s cubic-bezier(0.645, 0.045, 0.355, 1),
|
||||||
box-shadow 0.5s ease;
|
box-shadow 0.5s ease;
|
||||||
max-width: 360px;
|
max-width: 360px;
|
||||||
@@ -80,8 +97,8 @@ const { data: content } = await usePageContent('home')
|
|||||||
.book-cover-3d:hover {
|
.book-cover-3d:hover {
|
||||||
transform: rotateY(-8deg) rotateX(3deg) scale(1.02);
|
transform: rotateY(-8deg) rotateX(3deg) scale(1.02);
|
||||||
box-shadow:
|
box-shadow:
|
||||||
12px 16px 48px hsl(0 0% 0% / 0.6),
|
12px 16px 48px hsl(var(--color-text) / 0.2),
|
||||||
0 0 0 1px hsl(12 76% 48% / 0.2);
|
0 0 0 1px hsl(var(--color-primary) / 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.book-cover-img {
|
.book-cover-img {
|
||||||
@@ -94,4 +111,25 @@ const { data: content } = await usePageContent('home')
|
|||||||
.heading-section {
|
.heading-section {
|
||||||
font-size: clamp(1.625rem, 4vw, 2.125rem);
|
font-size: clamp(1.625rem, 4vw, 2.125rem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.shadok-pumper {
|
||||||
|
position: absolute;
|
||||||
|
right: -15%;
|
||||||
|
bottom: 5%;
|
||||||
|
width: clamp(60px, 10vw, 120px);
|
||||||
|
opacity: 0.12;
|
||||||
|
pointer-events: none;
|
||||||
|
color: hsl(var(--color-primary));
|
||||||
|
animation: shadok-float 10s ease-in-out infinite;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes shadok-float {
|
||||||
|
0%, 100% { transform: translateY(0); }
|
||||||
|
50% { transform: translateY(-10px); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.shadok-pumper { display: none; }
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,5 +1,37 @@
|
|||||||
<template>
|
<template>
|
||||||
<section class="section-padding">
|
<section class="relative overflow-hidden section-padding">
|
||||||
|
<!-- Shadok scale: balance with absurd objects -->
|
||||||
|
<svg class="shadok-scale" viewBox="0 0 260 280" fill="none" aria-hidden="true">
|
||||||
|
<!-- Vertical pole -->
|
||||||
|
<line x1="130" y1="40" x2="130" y2="240" stroke="currentColor" stroke-width="4" stroke-linecap="round" opacity="0.8"/>
|
||||||
|
<!-- Base triangle -->
|
||||||
|
<polygon points="100,240 160,240 130,220" fill="currentColor" opacity="0.5"/>
|
||||||
|
<!-- Horizontal beam -->
|
||||||
|
<line x1="40" y1="80" x2="220" y2="60" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.7"/>
|
||||||
|
<!-- Pivot circle -->
|
||||||
|
<circle cx="130" cy="70" r="8" fill="currentColor" opacity="0.6"/>
|
||||||
|
<!-- Left pan (chain lines) -->
|
||||||
|
<line x1="40" y1="80" x2="30" y2="120" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity="0.5"/>
|
||||||
|
<line x1="40" y1="80" x2="70" y2="120" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity="0.5"/>
|
||||||
|
<!-- Left pan dish -->
|
||||||
|
<path d="M20 120 Q50 135 80 120" stroke="currentColor" stroke-width="2.5" fill="currentColor" opacity="0.35"/>
|
||||||
|
<!-- Absurd object on left: a snail -->
|
||||||
|
<ellipse cx="50" cy="112" rx="14" ry="8" fill="currentColor" opacity="0.5"/>
|
||||||
|
<path d="M60 108 Q68 95 58 92 Q48 90 52 100" stroke="currentColor" stroke-width="2" fill="none" opacity="0.4"/>
|
||||||
|
<!-- Right pan (chain lines) -->
|
||||||
|
<line x1="220" y1="60" x2="210" y2="100" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity="0.5"/>
|
||||||
|
<line x1="220" y1="60" x2="250" y2="100" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity="0.5"/>
|
||||||
|
<!-- Right pan dish -->
|
||||||
|
<path d="M200 100 Q230 115 260 100" stroke="currentColor" stroke-width="2.5" fill="currentColor" opacity="0.35"/>
|
||||||
|
<!-- Absurd object on right: a star/coin -->
|
||||||
|
<circle cx="230" cy="92" r="10" fill="currentColor" opacity="0.4"/>
|
||||||
|
<circle cx="230" cy="92" r="5" fill="currentColor" opacity="0.2"/>
|
||||||
|
<!-- Tiny Shadok perched on top -->
|
||||||
|
<ellipse cx="130" cy="35" rx="12" ry="10" fill="currentColor" opacity="0.6"/>
|
||||||
|
<circle cx="130" cy="22" r="7" fill="currentColor" opacity="0.55"/>
|
||||||
|
<circle cx="133" cy="20" r="2" fill="currentColor" opacity="0.3"/>
|
||||||
|
</svg>
|
||||||
|
|
||||||
<div class="container-content">
|
<div class="container-content">
|
||||||
<div class="mx-auto max-w-3xl text-center">
|
<div class="mx-auto max-w-3xl text-center">
|
||||||
<UiScrollReveal>
|
<UiScrollReveal>
|
||||||
@@ -41,4 +73,24 @@ const { data: content } = await usePageContent('home')
|
|||||||
.heading-section {
|
.heading-section {
|
||||||
font-size: clamp(1.625rem, 4vw, 2.125rem);
|
font-size: clamp(1.625rem, 4vw, 2.125rem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.shadok-scale {
|
||||||
|
position: absolute;
|
||||||
|
left: 2%;
|
||||||
|
top: 10%;
|
||||||
|
width: clamp(100px, 14vw, 200px);
|
||||||
|
opacity: 0.1;
|
||||||
|
pointer-events: none;
|
||||||
|
color: hsl(var(--color-primary));
|
||||||
|
animation: shadok-float-scale 9s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes shadok-float-scale {
|
||||||
|
0%, 100% { transform: translateY(0) rotate(0deg); }
|
||||||
|
50% { transform: translateY(-10px) rotate(2deg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.shadok-scale { display: none; }
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -2,8 +2,20 @@
|
|||||||
<section class="section-padding">
|
<section class="section-padding">
|
||||||
<div class="container-content">
|
<div class="container-content">
|
||||||
<UiScrollReveal>
|
<UiScrollReveal>
|
||||||
<div class="gw-card">
|
<div class="gw-card relative overflow-hidden">
|
||||||
<div class="flex flex-col items-center text-center gap-4 md:flex-row md:text-left md:gap-8">
|
<!-- Shadok blob -->
|
||||||
|
<svg class="shadok-blob" viewBox="0 0 200 180" fill="none" aria-hidden="true">
|
||||||
|
<path d="M60 90 Q30 50 70 30 Q110 10 140 40 Q180 60 170 100 Q165 140 130 155 Q90 170 55 145 Q25 125 60 90Z" fill="currentColor" opacity="0.12"/>
|
||||||
|
<path d="M60 90 Q30 50 70 30 Q110 10 140 40 Q180 60 170 100 Q165 140 130 155 Q90 170 55 145 Q25 125 60 90Z" stroke="currentColor" stroke-width="1.5" opacity="0.2"/>
|
||||||
|
<circle cx="100" cy="80" r="8" fill="currentColor" opacity="0.08"/>
|
||||||
|
<circle cx="120" cy="110" r="6" fill="currentColor" opacity="0.06"/>
|
||||||
|
<circle cx="80" cy="105" r="5" fill="currentColor" opacity="0.07"/>
|
||||||
|
<circle cx="95" cy="72" r="3" fill="currentColor" opacity="0.3"/>
|
||||||
|
<circle cx="108" cy="70" r="3" fill="currentColor" opacity="0.3"/>
|
||||||
|
<circle cx="96" cy="71" r="1.2" fill="currentColor" opacity="0.5"/>
|
||||||
|
<circle cx="109" cy="69" r="1.2" fill="currentColor" opacity="0.5"/>
|
||||||
|
</svg>
|
||||||
|
<div class="flex flex-col items-center text-center gap-4 md:flex-row md:text-left md:gap-8 relative z-1">
|
||||||
<!-- Icon -->
|
<!-- Icon -->
|
||||||
<div class="gw-icon-wrapper">
|
<div class="gw-icon-wrapper">
|
||||||
<div class="i-lucide-sparkles h-8 w-8 text-amber-400" />
|
<div class="i-lucide-sparkles h-8 w-8 text-amber-400" />
|
||||||
@@ -75,4 +87,24 @@ const { data: content } = await usePageContent('home')
|
|||||||
border: 1px solid hsl(40 80% 50% / 0.15);
|
border: 1px solid hsl(40 80% 50% / 0.15);
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.shadok-blob {
|
||||||
|
position: absolute;
|
||||||
|
right: -2%;
|
||||||
|
top: -20%;
|
||||||
|
width: clamp(100px, 15vw, 180px);
|
||||||
|
opacity: 0.15;
|
||||||
|
pointer-events: none;
|
||||||
|
color: hsl(var(--color-accent));
|
||||||
|
animation: shadok-drift 12s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes shadok-drift {
|
||||||
|
0%, 100% { transform: translateY(0) rotate(0deg); }
|
||||||
|
50% { transform: translateY(-8px) rotate(3deg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.shadok-blob { display: none; }
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -4,6 +4,25 @@
|
|||||||
<div class="absolute inset-0 bg-gradient-to-b from-primary/10 via-transparent to-surface-bg" />
|
<div class="absolute inset-0 bg-gradient-to-b from-primary/10 via-transparent to-surface-bg" />
|
||||||
<div class="absolute inset-0 bg-[radial-gradient(ellipse_at_top,hsl(12_76%_48%/0.15),transparent_70%)]" />
|
<div class="absolute inset-0 bg-[radial-gradient(ellipse_at_top,hsl(12_76%_48%/0.15),transparent_70%)]" />
|
||||||
|
|
||||||
|
<!-- Shadok bird decoration -->
|
||||||
|
<svg class="shadok-bird" viewBox="0 0 180 260" fill="none" aria-hidden="true">
|
||||||
|
<ellipse cx="90" cy="100" rx="45" ry="40" fill="currentColor" opacity="0.85"/>
|
||||||
|
<circle cx="130" cy="60" r="22" fill="currentColor" opacity="0.8"/>
|
||||||
|
<path d="M110 85 Q125 70 128 63" stroke="currentColor" stroke-width="8" stroke-linecap="round" opacity="0.7" fill="none"/>
|
||||||
|
<circle cx="136" cy="55" r="5" fill="currentColor" opacity="0.3"/>
|
||||||
|
<circle cx="137" cy="54" r="2" fill="currentColor" opacity="0.6"/>
|
||||||
|
<polygon points="150,58 175,50 152,65" fill="currentColor" opacity="0.6"/>
|
||||||
|
<line x1="75" y1="138" x2="60" y2="230" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||||
|
<line x1="105" y1="138" x2="115" y2="230" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||||
|
<circle cx="66" cy="190" r="4" fill="currentColor" opacity="0.4"/>
|
||||||
|
<circle cx="111" cy="190" r="4" fill="currentColor" opacity="0.4"/>
|
||||||
|
<path d="M60 230 L45 233 M60 230 L55 236 M60 230 L65 235" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" opacity="0.5"/>
|
||||||
|
<path d="M115 230 L100 233 M115 230 L110 236 M115 230 L120 235" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" opacity="0.5"/>
|
||||||
|
<path d="M48 95 Q20 80 15 65" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.5" fill="none"/>
|
||||||
|
<path d="M48 100 Q22 92 10 85" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4" fill="none"/>
|
||||||
|
<path d="M48 105 Q25 102 12 100" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.3" fill="none"/>
|
||||||
|
</svg>
|
||||||
|
|
||||||
<!-- Content -->
|
<!-- Content -->
|
||||||
<div class="container-content relative z-10 px-4">
|
<div class="container-content relative z-10 px-4">
|
||||||
<div class="mx-auto max-w-3xl text-center">
|
<div class="mx-auto max-w-3xl text-center">
|
||||||
@@ -54,4 +73,25 @@ const { data: content } = await usePageContent('home')
|
|||||||
.hero-title {
|
.hero-title {
|
||||||
font-size: clamp(2.25rem, 7vw, 4rem);
|
font-size: clamp(2.25rem, 7vw, 4rem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.shadok-bird {
|
||||||
|
position: absolute;
|
||||||
|
right: 5%;
|
||||||
|
top: 15%;
|
||||||
|
width: clamp(80px, 12vw, 160px);
|
||||||
|
opacity: 0.12;
|
||||||
|
pointer-events: none;
|
||||||
|
color: hsl(var(--color-primary));
|
||||||
|
animation: shadok-float 8s ease-in-out infinite;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes shadok-float {
|
||||||
|
0%, 100% { transform: translateY(0); }
|
||||||
|
50% { transform: translateY(-12px); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.shadok-bird { display: none; }
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -106,8 +106,8 @@ function formatDate(iso: string) {
|
|||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.message-form-card {
|
.message-form-card {
|
||||||
background: hsl(20 8% 6%);
|
background: hsl(var(--color-surface));
|
||||||
border: 1px solid hsl(20 8% 14%);
|
border: 1px solid hsl(var(--color-text) / 0.1);
|
||||||
border-radius: 0.75rem;
|
border-radius: 0.75rem;
|
||||||
padding: 1.5rem;
|
padding: 1.5rem;
|
||||||
}
|
}
|
||||||
@@ -116,25 +116,25 @@ function formatDate(iso: string) {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 0.5rem 0.75rem;
|
padding: 0.5rem 0.75rem;
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
border: 1px solid hsl(20 8% 18%);
|
border: 1px solid hsl(var(--color-text) / 0.12);
|
||||||
background: hsl(20 8% 4%);
|
background: hsl(var(--color-bg));
|
||||||
color: white;
|
color: hsl(var(--color-text));
|
||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
transition: border-color 0.2s;
|
transition: border-color 0.2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.msg-input::placeholder {
|
.msg-input::placeholder {
|
||||||
color: hsl(20 8% 40%);
|
color: hsl(var(--color-text) / 0.35);
|
||||||
}
|
}
|
||||||
|
|
||||||
.msg-input:focus {
|
.msg-input:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
border-color: hsl(12 76% 48% / 0.5);
|
border-color: hsl(var(--color-primary) / 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
.message-card {
|
.message-card {
|
||||||
background: hsl(20 8% 6%);
|
background: hsl(var(--color-surface));
|
||||||
border: 1px solid hsl(20 8% 14%);
|
border: 1px solid hsl(var(--color-text) / 0.1);
|
||||||
border-radius: 0.75rem;
|
border-radius: 0.75rem;
|
||||||
padding: 1rem 1.25rem;
|
padding: 1rem 1.25rem;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,37 @@
|
|||||||
<template>
|
<template>
|
||||||
<section class="section-padding bg-surface-600/50">
|
<section class="relative overflow-hidden section-padding bg-surface-600/50">
|
||||||
|
<!-- Shadok musician: round character playing a trumpet -->
|
||||||
|
<svg class="shadok-musician" viewBox="0 0 220 280" fill="none" aria-hidden="true">
|
||||||
|
<!-- Body (ovoid) -->
|
||||||
|
<ellipse cx="100" cy="150" rx="45" ry="55" fill="currentColor" opacity="0.85"/>
|
||||||
|
<!-- Head -->
|
||||||
|
<circle cx="100" cy="80" r="28" fill="currentColor" opacity="0.8"/>
|
||||||
|
<!-- Eyes -->
|
||||||
|
<circle cx="90" cy="74" r="5" fill="currentColor" opacity="0.2"/>
|
||||||
|
<circle cx="110" cy="74" r="5" fill="currentColor" opacity="0.2"/>
|
||||||
|
<circle cx="91" cy="73" r="2" fill="currentColor" opacity="0.5"/>
|
||||||
|
<circle cx="111" cy="73" r="2" fill="currentColor" opacity="0.5"/>
|
||||||
|
<!-- Mouth (blowing) -->
|
||||||
|
<circle cx="125" cy="86" r="4" fill="currentColor" opacity="0.3"/>
|
||||||
|
<!-- Trumpet -->
|
||||||
|
<line x1="128" y1="86" x2="185" y2="78" stroke="currentColor" stroke-width="5" stroke-linecap="round" opacity="0.7"/>
|
||||||
|
<path d="M185 68 Q200 78 185 88" stroke="currentColor" stroke-width="3" fill="currentColor" opacity="0.45"/>
|
||||||
|
<!-- Trumpet valves -->
|
||||||
|
<circle cx="155" cy="80" r="3" fill="currentColor" opacity="0.3"/>
|
||||||
|
<circle cx="165" cy="79" r="3" fill="currentColor" opacity="0.3"/>
|
||||||
|
<!-- Music notes floating -->
|
||||||
|
<circle cx="205" cy="60" r="4" fill="currentColor" opacity="0.4"/>
|
||||||
|
<line x1="209" y1="60" x2="209" y2="42" stroke="currentColor" stroke-width="1.5" opacity="0.4"/>
|
||||||
|
<circle cx="195" cy="45" r="3" fill="currentColor" opacity="0.3"/>
|
||||||
|
<line x1="198" y1="45" x2="198" y2="30" stroke="currentColor" stroke-width="1.5" opacity="0.3"/>
|
||||||
|
<!-- Legs -->
|
||||||
|
<line x1="82" y1="202" x2="72" y2="255" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||||
|
<line x1="118" y1="202" x2="128" y2="255" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||||
|
<!-- Feet -->
|
||||||
|
<path d="M72 255 L58 258 M72 255 L66 261" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" opacity="0.5"/>
|
||||||
|
<path d="M128 255 L114 258 M128 255 L122 261" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" opacity="0.5"/>
|
||||||
|
</svg>
|
||||||
|
|
||||||
<div class="container-content">
|
<div class="container-content">
|
||||||
<UiScrollReveal>
|
<UiScrollReveal>
|
||||||
<div class="text-center mb-12">
|
<div class="text-center mb-12">
|
||||||
@@ -48,4 +80,24 @@ const featuredSongs = computed(() => bookData.getSongs().slice(0, 6))
|
|||||||
.heading-section {
|
.heading-section {
|
||||||
font-size: clamp(1.625rem, 4vw, 2.125rem);
|
font-size: clamp(1.625rem, 4vw, 2.125rem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.shadok-musician {
|
||||||
|
position: absolute;
|
||||||
|
right: 3%;
|
||||||
|
top: 5%;
|
||||||
|
width: clamp(90px, 12vw, 170px);
|
||||||
|
opacity: 0.1;
|
||||||
|
pointer-events: none;
|
||||||
|
color: hsl(var(--color-primary));
|
||||||
|
animation: shadok-float-musician 8s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes shadok-float-musician {
|
||||||
|
0%, 100% { transform: translateY(0); }
|
||||||
|
50% { transform: translateY(-10px); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.shadok-musician { display: none; }
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,6 +1,45 @@
|
|||||||
<template>
|
<template>
|
||||||
<footer class="border-t border-white/8 bg-surface-600">
|
<footer class="footer-wrap border-t border-white/8 bg-surface-600">
|
||||||
<div class="container-content px-4 py-8">
|
<!-- Shadok pattern -->
|
||||||
|
<svg class="footer-shadok-pattern" viewBox="0 0 400 80" fill="none" aria-hidden="true">
|
||||||
|
<g transform="translate(20,10)">
|
||||||
|
<ellipse cx="15" cy="25" rx="12" ry="14" fill="currentColor" opacity="0.08"/>
|
||||||
|
<circle cx="15" cy="10" r="7" fill="currentColor" opacity="0.06"/>
|
||||||
|
<line x1="10" y1="38" x2="8" y2="55" stroke="currentColor" stroke-width="1.5" opacity="0.06"/>
|
||||||
|
<line x1="20" y1="38" x2="22" y2="55" stroke="currentColor" stroke-width="1.5" opacity="0.06"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(80,15)">
|
||||||
|
<ellipse cx="15" cy="22" rx="10" ry="12" fill="currentColor" opacity="0.06"/>
|
||||||
|
<circle cx="15" cy="8" r="6" fill="currentColor" opacity="0.05"/>
|
||||||
|
<line x1="10" y1="33" x2="8" y2="48" stroke="currentColor" stroke-width="1.5" opacity="0.05"/>
|
||||||
|
<line x1="20" y1="33" x2="22" y2="48" stroke="currentColor" stroke-width="1.5" opacity="0.05"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(140,8)">
|
||||||
|
<ellipse cx="15" cy="25" rx="11" ry="13" fill="currentColor" opacity="0.07"/>
|
||||||
|
<circle cx="15" cy="10" r="6.5" fill="currentColor" opacity="0.06"/>
|
||||||
|
<line x1="10" y1="37" x2="7" y2="54" stroke="currentColor" stroke-width="1.5" opacity="0.06"/>
|
||||||
|
<line x1="20" y1="37" x2="23" y2="54" stroke="currentColor" stroke-width="1.5" opacity="0.06"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(210,18)">
|
||||||
|
<ellipse cx="15" cy="20" rx="10" ry="11" fill="currentColor" opacity="0.05"/>
|
||||||
|
<circle cx="15" cy="7" r="5.5" fill="currentColor" opacity="0.04"/>
|
||||||
|
<line x1="10" y1="30" x2="9" y2="44" stroke="currentColor" stroke-width="1.5" opacity="0.04"/>
|
||||||
|
<line x1="20" y1="30" x2="21" y2="44" stroke="currentColor" stroke-width="1.5" opacity="0.04"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(270,12)">
|
||||||
|
<ellipse cx="15" cy="24" rx="12" ry="14" fill="currentColor" opacity="0.07"/>
|
||||||
|
<circle cx="15" cy="9" r="7" fill="currentColor" opacity="0.06"/>
|
||||||
|
<line x1="10" y1="37" x2="7" y2="55" stroke="currentColor" stroke-width="1.5" opacity="0.06"/>
|
||||||
|
<line x1="20" y1="37" x2="23" y2="55" stroke="currentColor" stroke-width="1.5" opacity="0.06"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(340,16)">
|
||||||
|
<ellipse cx="15" cy="22" rx="10" ry="12" fill="currentColor" opacity="0.06"/>
|
||||||
|
<circle cx="15" cy="8" r="6" fill="currentColor" opacity="0.05"/>
|
||||||
|
<line x1="10" y1="33" x2="8" y2="48" stroke="currentColor" stroke-width="1.5" opacity="0.05"/>
|
||||||
|
<line x1="20" y1="33" x2="22" y2="48" stroke="currentColor" stroke-width="1.5" opacity="0.05"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
<div class="container-content px-4 py-8 relative z-1">
|
||||||
<div class="flex flex-col items-center gap-4 md:flex-row md:justify-between">
|
<div class="flex flex-col items-center gap-4 md:flex-row md:justify-between">
|
||||||
<!-- Credits -->
|
<!-- Credits -->
|
||||||
<p class="text-sm text-white/40">
|
<p class="text-sm text-white/40">
|
||||||
@@ -26,3 +65,21 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const { data: site } = await useSiteContent()
|
const { data: site } = await useSiteContent()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.footer-wrap {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-shadok-pattern {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
opacity: 0.6;
|
||||||
|
pointer-events: none;
|
||||||
|
color: hsl(var(--color-primary));
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
<header class="sticky top-0 z-40 border-b border-white/8 bg-surface-bg/80 backdrop-blur-xl">
|
<header class="sticky top-0 z-40 border-b border-white/8 bg-surface-bg/80 backdrop-blur-xl">
|
||||||
<div class="container-content flex h-[var(--header-height)] items-center justify-between px-4">
|
<div class="container-content flex h-[var(--header-height)] items-center justify-between px-4">
|
||||||
<!-- Logo -->
|
<!-- Logo -->
|
||||||
<NuxtLink to="/" class="flex items-center gap-2 font-display text-lg font-bold tracking-tight">
|
<NuxtLink to="/" class="flex items-center gap-2 text-lg tracking-tight">
|
||||||
<div class="i-lucide-book-open h-6 w-6 text-primary" />
|
<div class="i-lucide-book-open h-6 w-6 text-primary" />
|
||||||
<span class="text-gradient">{{ site?.identity.name }}</span>
|
<span class="font-calligraphy font-bold text-gradient text-xl italic">{{ site?.identity.name }}</span>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
|
|
||||||
<!-- Desktop navigation -->
|
<!-- Desktop navigation -->
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
>
|
>
|
||||||
{{ item.label }}
|
{{ item.label }}
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
|
<UiPaletteSelector />
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<!-- Mobile menu button -->
|
<!-- Mobile menu button -->
|
||||||
|
|||||||
@@ -99,13 +99,18 @@
|
|||||||
<div :class="store.isPlaying ? 'i-lucide-pause' : 'i-lucide-play'" class="h-4 w-4" />
|
<div :class="store.isPlaying ? 'i-lucide-pause' : 'i-lucide-play'" class="h-4 w-4" />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
<!-- Next -->
|
||||||
|
<button class="pill-next" aria-label="Suivant" @click.stop="playNext" :disabled="!store.hasNext">
|
||||||
|
<div class="i-lucide-skip-forward h-3.5 w-3.5" />
|
||||||
|
</button>
|
||||||
|
|
||||||
<!-- Expand -->
|
<!-- Expand -->
|
||||||
<button
|
<button
|
||||||
class="pill-expand"
|
class="pill-expand"
|
||||||
:aria-label="isExpanded ? 'Réduire' : 'Développer'"
|
:aria-label="isExpanded ? 'Réduire' : 'Développer'"
|
||||||
@click.stop="toggleExpanded"
|
@click.stop="toggleExpanded"
|
||||||
>
|
>
|
||||||
<div :class="isExpanded ? 'i-lucide-chevron-down' : 'i-lucide-chevron-up'" class="h-3.5 w-3.5" />
|
<div :class="isExpanded ? 'i-lucide-chevron-down' : 'i-lucide-chevron-up'" class="h-4 w-4" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -116,7 +121,7 @@
|
|||||||
import { onClickOutside } from '@vueuse/core'
|
import { onClickOutside } from '@vueuse/core'
|
||||||
|
|
||||||
const store = usePlayerStore()
|
const store = usePlayerStore()
|
||||||
const { setVolume, togglePlayPause } = useAudioPlayer()
|
const { setVolume, togglePlayPause, playNext } = useAudioPlayer()
|
||||||
|
|
||||||
useMediaSession()
|
useMediaSession()
|
||||||
|
|
||||||
@@ -235,22 +240,40 @@ onClickOutside(widgetRef, () => {
|
|||||||
.pill-play:hover { transform: scale(1.08); }
|
.pill-play:hover { transform: scale(1.08); }
|
||||||
.pill-play:active { transform: scale(0.94); }
|
.pill-play:active { transform: scale(0.94); }
|
||||||
|
|
||||||
|
/* Next */
|
||||||
|
.pill-next {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 1.5rem;
|
||||||
|
height: 1.5rem;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
color: hsl(0 0% 100% / 0.6);
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.15s;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.pill-next:hover { color: white; }
|
||||||
|
.pill-next:disabled { opacity: 0.3; cursor: default; }
|
||||||
|
|
||||||
/* Expand chevron */
|
/* Expand chevron */
|
||||||
.pill-expand {
|
.pill-expand {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 1.25rem;
|
width: 1.75rem;
|
||||||
height: 1.25rem;
|
height: 1.75rem;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: transparent;
|
background: hsl(0 0% 100% / 0.08);
|
||||||
border: none;
|
border: none;
|
||||||
color: hsl(0 0% 100% / 0.3);
|
color: hsl(0 0% 100% / 0.5);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: color 0.2s;
|
transition: all 0.2s;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
.pill-expand:hover { color: hsl(0 0% 100% / 0.7); }
|
.pill-expand:hover { color: hsl(0 0% 100% / 0.9); background: hsl(0 0% 100% / 0.15); }
|
||||||
|
|
||||||
/* ═══════════════════════════════════════
|
/* ═══════════════════════════════════════
|
||||||
PANEL
|
PANEL
|
||||||
|
|||||||
261
app/components/ui/PaletteSelector.vue
Normal file
261
app/components/ui/PaletteSelector.vue
Normal file
@@ -0,0 +1,261 @@
|
|||||||
|
<template>
|
||||||
|
<div class="settings-selector" ref="selectorRef">
|
||||||
|
<button
|
||||||
|
class="settings-trigger"
|
||||||
|
aria-label="Réglages d'affichage"
|
||||||
|
@click="isOpen = !isOpen"
|
||||||
|
>
|
||||||
|
<div class="i-lucide-settings h-5 w-5" />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<Transition name="settings-dropdown">
|
||||||
|
<div v-if="isOpen" class="settings-dropdown">
|
||||||
|
<h4 class="settings-title">Affichage</h4>
|
||||||
|
|
||||||
|
<!-- Palette grid : 4 saisons -->
|
||||||
|
<div class="settings-section">
|
||||||
|
<span class="settings-label">Ambiance</span>
|
||||||
|
<div class="settings-palette-grid">
|
||||||
|
<button
|
||||||
|
v-for="name in paletteNames"
|
||||||
|
:key="name"
|
||||||
|
class="settings-palette-btn"
|
||||||
|
:class="{
|
||||||
|
'settings-palette-btn--active': paletteStore.currentPalette === name,
|
||||||
|
'settings-palette-btn--light': paletteStore.palettes[name].isLight,
|
||||||
|
}"
|
||||||
|
:title="paletteStore.palettes[name].label"
|
||||||
|
@click="paletteStore.setPalette(name)"
|
||||||
|
>
|
||||||
|
<span class="settings-palette-preview">
|
||||||
|
<span class="settings-palette-dot" :style="{ background: `hsl(${paletteStore.palettes[name].primary})` }" />
|
||||||
|
<span class="settings-palette-dot" :style="{ background: `hsl(${paletteStore.palettes[name].accent})` }" />
|
||||||
|
</span>
|
||||||
|
<span class="settings-palette-info">
|
||||||
|
<span class="settings-palette-name">{{ paletteStore.palettes[name].label }}</span>
|
||||||
|
<span class="settings-palette-mode">{{ paletteStore.palettes[name].isLight ? 'Clair' : 'Sombre' }}</span>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Font size -->
|
||||||
|
<div class="settings-section">
|
||||||
|
<span class="settings-label">Taille texte</span>
|
||||||
|
<div class="settings-toggle-group">
|
||||||
|
<button
|
||||||
|
v-for="size in fontSizes"
|
||||||
|
:key="size.value"
|
||||||
|
class="settings-toggle"
|
||||||
|
:class="{ 'settings-toggle--active': currentFontSize === size.value }"
|
||||||
|
@click="setFontSize(size.value)"
|
||||||
|
>
|
||||||
|
{{ size.label }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Transition>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onClickOutside } from '@vueuse/core'
|
||||||
|
import type { PaletteName } from '~/stores/palette'
|
||||||
|
|
||||||
|
const paletteStore = usePaletteStore()
|
||||||
|
const selectorRef = ref<HTMLElement>()
|
||||||
|
const isOpen = ref(false)
|
||||||
|
|
||||||
|
const paletteNames: PaletteName[] = ['automne', 'hiver', 'printemps', 'ete']
|
||||||
|
|
||||||
|
const currentFontSize = ref(
|
||||||
|
(import.meta.client && localStorage.getItem('fontSize')) || 'normal',
|
||||||
|
)
|
||||||
|
|
||||||
|
const fontSizes = [
|
||||||
|
{ label: 'A-', value: 'small' },
|
||||||
|
{ label: 'A', value: 'normal' },
|
||||||
|
{ label: 'A+', value: 'large' },
|
||||||
|
]
|
||||||
|
|
||||||
|
function setFontSize(size: string) {
|
||||||
|
currentFontSize.value = size
|
||||||
|
if (import.meta.client) {
|
||||||
|
localStorage.setItem('fontSize', size)
|
||||||
|
const root = document.documentElement
|
||||||
|
const map: Record<string, string> = { small: '14px', normal: '16px', large: '18px' }
|
||||||
|
root.style.fontSize = map[size] || '16px'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply font size on mount
|
||||||
|
onMounted(() => {
|
||||||
|
const saved = localStorage.getItem('fontSize')
|
||||||
|
if (saved) setFontSize(saved)
|
||||||
|
})
|
||||||
|
|
||||||
|
onClickOutside(selectorRef, () => { isOpen.value = false })
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.settings-selector {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-trigger {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 2.25rem;
|
||||||
|
height: 2.25rem;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
color: hsl(var(--color-text) / 0.7);
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
.settings-trigger:hover {
|
||||||
|
color: hsl(var(--color-text));
|
||||||
|
background: hsl(var(--color-text) / 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-dropdown {
|
||||||
|
position: absolute;
|
||||||
|
top: calc(100% + 0.5rem);
|
||||||
|
right: 0;
|
||||||
|
width: 260px;
|
||||||
|
padding: 0.75rem;
|
||||||
|
border-radius: 0.75rem;
|
||||||
|
background: hsl(var(--color-surface));
|
||||||
|
backdrop-filter: blur(16px);
|
||||||
|
border: 1px solid hsl(var(--color-text) / 0.08);
|
||||||
|
box-shadow: 0 8px 32px hsl(0 0% 0% / 0.3);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.75rem;
|
||||||
|
z-index: 50;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-title {
|
||||||
|
font-family: var(--font-display);
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 700;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
color: hsl(var(--color-text) / 0.4);
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-section {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.375rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-label {
|
||||||
|
font-size: 0.7rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: hsl(var(--color-text) / 0.5);
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-toggle-group {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.25rem;
|
||||||
|
background: hsl(var(--color-text) / 0.04);
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
padding: 0.125rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-toggle {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.375rem;
|
||||||
|
padding: 0.375rem 0.5rem;
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 500;
|
||||||
|
color: hsl(var(--color-text) / 0.5);
|
||||||
|
transition: all 0.15s;
|
||||||
|
}
|
||||||
|
.settings-toggle:hover {
|
||||||
|
color: hsl(var(--color-text) / 0.8);
|
||||||
|
}
|
||||||
|
.settings-toggle--active {
|
||||||
|
background: hsl(var(--color-primary));
|
||||||
|
color: white;
|
||||||
|
box-shadow: 0 1px 4px hsl(var(--color-primary) / 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-palette-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
gap: 0.375rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-palette-btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
padding: 0.5rem;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
transition: all 0.2s;
|
||||||
|
color: hsl(var(--color-text) / 0.6);
|
||||||
|
background: hsl(var(--color-text) / 0.02);
|
||||||
|
}
|
||||||
|
.settings-palette-btn:hover {
|
||||||
|
background: hsl(var(--color-text) / 0.06);
|
||||||
|
color: hsl(var(--color-text) / 0.9);
|
||||||
|
}
|
||||||
|
.settings-palette-btn--active {
|
||||||
|
background: hsl(var(--color-text) / 0.1);
|
||||||
|
color: hsl(var(--color-text));
|
||||||
|
box-shadow: inset 0 0 0 1.5px hsl(var(--color-primary) / 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-palette-preview {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.125rem;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-palette-dot {
|
||||||
|
width: 0.75rem;
|
||||||
|
height: 0.75rem;
|
||||||
|
border-radius: 50%;
|
||||||
|
box-shadow: 0 1px 3px hsl(0 0% 0% / 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-palette-info {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-palette-name {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-palette-mode {
|
||||||
|
font-size: 0.6rem;
|
||||||
|
opacity: 0.5;
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-dropdown-enter-active {
|
||||||
|
transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
|
||||||
|
}
|
||||||
|
.settings-dropdown-leave-active {
|
||||||
|
transition: all 0.15s ease;
|
||||||
|
}
|
||||||
|
.settings-dropdown-enter-from,
|
||||||
|
.settings-dropdown-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-4px) scale(0.96);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
top: var(--header-height);
|
top: var(--header-height);
|
||||||
height: calc(100dvh - var(--header-height));
|
height: calc(100dvh - var(--header-height));
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
border-right: 1px solid hsl(0 0% 100% / 0.08);
|
border-right: 1px solid hsl(var(--color-text) / 0.08);
|
||||||
padding: 1.5rem;
|
padding: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,34 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="section-padding">
|
<div class="relative overflow-hidden section-padding">
|
||||||
|
<!-- Shadok philosopher: character sitting cross-legged, floating -->
|
||||||
|
<svg class="shadok-philosopher" viewBox="0 0 220 280" fill="none" aria-hidden="true">
|
||||||
|
<!-- Body (round, serene) -->
|
||||||
|
<ellipse cx="110" cy="150" rx="48" ry="55" fill="currentColor" opacity="0.85"/>
|
||||||
|
<!-- Head -->
|
||||||
|
<ellipse cx="110" cy="82" rx="26" ry="25" fill="currentColor" opacity="0.8"/>
|
||||||
|
<!-- Closed eyes (meditating) -->
|
||||||
|
<path d="M96 80 Q100 84 105 80" stroke="currentColor" stroke-width="2" stroke-linecap="round" fill="none" opacity="0.4"/>
|
||||||
|
<path d="M115 80 Q119 84 124 80" stroke="currentColor" stroke-width="2" stroke-linecap="round" fill="none" opacity="0.4"/>
|
||||||
|
<!-- Serene smile -->
|
||||||
|
<path d="M102 93 Q110 98 118 93" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" fill="none" opacity="0.3"/>
|
||||||
|
<!-- Arms resting on knees -->
|
||||||
|
<path d="M64 155 Q55 180 70 200" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" fill="none" opacity="0.6"/>
|
||||||
|
<path d="M156 155 Q165 180 150 200" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" fill="none" opacity="0.6"/>
|
||||||
|
<!-- Hands on knees -->
|
||||||
|
<circle cx="70" cy="200" r="5" fill="currentColor" opacity="0.4"/>
|
||||||
|
<circle cx="150" cy="200" r="5" fill="currentColor" opacity="0.4"/>
|
||||||
|
<!-- Crossed legs -->
|
||||||
|
<path d="M80 205 Q90 230 120 235" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" fill="none" opacity="0.6"/>
|
||||||
|
<path d="M140 205 Q130 230 100 235" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" fill="none" opacity="0.6"/>
|
||||||
|
<!-- Floating aura lines -->
|
||||||
|
<path d="M50 245 Q110 260 170 245" stroke="currentColor" stroke-width="1.5" stroke-dasharray="4 4" fill="none" opacity="0.25"/>
|
||||||
|
<path d="M60 255 Q110 268 160 255" stroke="currentColor" stroke-width="1" stroke-dasharray="3 5" fill="none" opacity="0.18"/>
|
||||||
|
<!-- Small sparkles around -->
|
||||||
|
<circle cx="55" cy="110" r="2.5" fill="currentColor" opacity="0.2"/>
|
||||||
|
<circle cx="170" cy="95" r="2" fill="currentColor" opacity="0.18"/>
|
||||||
|
<circle cx="160" cy="130" r="3" fill="currentColor" opacity="0.15"/>
|
||||||
|
</svg>
|
||||||
|
|
||||||
<div class="container-content mx-auto max-w-3xl">
|
<div class="container-content mx-auto max-w-3xl">
|
||||||
<ContentRenderer v-if="page" :value="page" class="prose" />
|
<ContentRenderer v-if="page" :value="page" class="prose" />
|
||||||
</div>
|
</div>
|
||||||
@@ -19,3 +48,25 @@ const { data: page } = await useAsyncData('about', () =>
|
|||||||
queryCollection('pages').path('/pages/about').first(),
|
queryCollection('pages').path('/pages/about').first(),
|
||||||
)
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.shadok-philosopher {
|
||||||
|
position: absolute;
|
||||||
|
right: 3%;
|
||||||
|
bottom: 8%;
|
||||||
|
width: clamp(90px, 13vw, 180px);
|
||||||
|
opacity: 0.1;
|
||||||
|
pointer-events: none;
|
||||||
|
color: hsl(var(--color-primary));
|
||||||
|
animation: shadok-float-philosopher 11s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes shadok-float-philosopher {
|
||||||
|
0%, 100% { transform: translateY(0); }
|
||||||
|
50% { transform: translateY(-12px); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.shadok-philosopher { display: none; }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,5 +1,41 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="section-padding">
|
<div class="relative overflow-hidden section-padding">
|
||||||
|
<!-- Shadok DJ: character with headphones behind a turntable -->
|
||||||
|
<svg class="shadok-dj" viewBox="0 0 260 300" fill="none" aria-hidden="true">
|
||||||
|
<!-- Body -->
|
||||||
|
<ellipse cx="130" cy="155" rx="42" ry="50" fill="currentColor" opacity="0.85"/>
|
||||||
|
<!-- Head -->
|
||||||
|
<circle cx="130" cy="88" r="26" fill="currentColor" opacity="0.8"/>
|
||||||
|
<!-- Headphones band -->
|
||||||
|
<path d="M104 78 Q130 55 156 78" stroke="currentColor" stroke-width="4" stroke-linecap="round" fill="none" opacity="0.6"/>
|
||||||
|
<!-- Headphone ear pads -->
|
||||||
|
<ellipse cx="102" cy="85" rx="8" ry="12" fill="currentColor" opacity="0.5"/>
|
||||||
|
<ellipse cx="158" cy="85" rx="8" ry="12" fill="currentColor" opacity="0.5"/>
|
||||||
|
<!-- Eyes (cool, half-lidded) -->
|
||||||
|
<ellipse cx="120" cy="85" rx="5" ry="3" fill="currentColor" opacity="0.25"/>
|
||||||
|
<ellipse cx="140" cy="85" rx="5" ry="3" fill="currentColor" opacity="0.25"/>
|
||||||
|
<circle cx="121" cy="86" r="1.8" fill="currentColor" opacity="0.5"/>
|
||||||
|
<circle cx="141" cy="86" r="1.8" fill="currentColor" opacity="0.5"/>
|
||||||
|
<!-- Mouth (grin) -->
|
||||||
|
<path d="M122 98 Q130 104 138 98" stroke="currentColor" stroke-width="2" stroke-linecap="round" fill="none" opacity="0.35"/>
|
||||||
|
<!-- Arms reaching to turntable -->
|
||||||
|
<line x1="90" y1="150" x2="55" y2="195" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||||
|
<line x1="170" y1="150" x2="205" y2="195" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||||
|
<!-- Turntable body -->
|
||||||
|
<rect x="30" y="200" width="200" height="18" rx="4" fill="currentColor" opacity="0.4"/>
|
||||||
|
<!-- Turntable platter (ellipse for perspective) -->
|
||||||
|
<ellipse cx="130" cy="200" rx="55" ry="15" fill="currentColor" opacity="0.25"/>
|
||||||
|
<ellipse cx="130" cy="200" rx="55" ry="15" stroke="currentColor" stroke-width="1.5" fill="none" opacity="0.35"/>
|
||||||
|
<!-- Record center -->
|
||||||
|
<circle cx="130" cy="200" r="5" fill="currentColor" opacity="0.4"/>
|
||||||
|
<!-- Tone arm -->
|
||||||
|
<line x1="195" y1="188" x2="150" y2="195" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity="0.5"/>
|
||||||
|
<circle cx="195" cy="188" r="3" fill="currentColor" opacity="0.35"/>
|
||||||
|
<!-- Legs -->
|
||||||
|
<line x1="115" y1="202" x2="105" y2="260" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||||
|
<line x1="145" y1="202" x2="155" y2="260" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||||
|
</svg>
|
||||||
|
|
||||||
<div class="container-content">
|
<div class="container-content">
|
||||||
<header class="mb-12 text-center">
|
<header class="mb-12 text-center">
|
||||||
<p class="mb-2 font-mono text-sm tracking-widest text-accent uppercase">{{ content?.kicker }}</p>
|
<p class="mb-2 font-mono text-sm tracking-widest text-accent uppercase">{{ content?.kicker }}</p>
|
||||||
@@ -107,4 +143,24 @@ const filteredSongs = computed(() => {
|
|||||||
.page-title {
|
.page-title {
|
||||||
font-size: clamp(2rem, 5vw, 2.75rem);
|
font-size: clamp(2rem, 5vw, 2.75rem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.shadok-dj {
|
||||||
|
position: absolute;
|
||||||
|
right: 2%;
|
||||||
|
top: 3%;
|
||||||
|
width: clamp(100px, 14vw, 190px);
|
||||||
|
opacity: 0.1;
|
||||||
|
pointer-events: none;
|
||||||
|
color: hsl(var(--color-accent));
|
||||||
|
animation: shadok-float-dj 8s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes shadok-float-dj {
|
||||||
|
0%, 100% { transform: translateY(0); }
|
||||||
|
50% { transform: translateY(-10px); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.shadok-dj { display: none; }
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,6 +1,48 @@
|
|||||||
<template>
|
<template>
|
||||||
<NuxtLayout>
|
<NuxtLayout>
|
||||||
<div class="section-padding">
|
<div class="relative overflow-hidden section-padding">
|
||||||
|
<!-- Shadok alchemist: character stirring a cauldron with sparkles -->
|
||||||
|
<svg class="shadok-alchemist" viewBox="0 0 240 320" fill="none" aria-hidden="true">
|
||||||
|
<!-- Body -->
|
||||||
|
<ellipse cx="120" cy="145" rx="40" ry="48" fill="currentColor" opacity="0.85"/>
|
||||||
|
<!-- Head -->
|
||||||
|
<circle cx="120" cy="82" r="24" fill="currentColor" opacity="0.8"/>
|
||||||
|
<!-- Wizard hat -->
|
||||||
|
<polygon points="120,30 100,80 140,80" fill="currentColor" opacity="0.5"/>
|
||||||
|
<line x1="100" y1="80" x2="140" y2="80" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.45"/>
|
||||||
|
<!-- Hat star -->
|
||||||
|
<circle cx="118" cy="55" r="3" fill="currentColor" opacity="0.25"/>
|
||||||
|
<!-- Eyes (mischievous) -->
|
||||||
|
<circle cx="111" cy="78" r="4.5" fill="currentColor" opacity="0.2"/>
|
||||||
|
<circle cx="129" cy="78" r="4.5" fill="currentColor" opacity="0.2"/>
|
||||||
|
<circle cx="112" cy="77" r="2" fill="currentColor" opacity="0.5"/>
|
||||||
|
<circle cx="130" cy="77" r="2" fill="currentColor" opacity="0.5"/>
|
||||||
|
<!-- Grin -->
|
||||||
|
<path d="M112 92 Q120 98 128 92" stroke="currentColor" stroke-width="2" stroke-linecap="round" fill="none" opacity="0.35"/>
|
||||||
|
<!-- Arm holding spoon/stick -->
|
||||||
|
<line x1="158" y1="140" x2="175" y2="210" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||||
|
<!-- Other arm -->
|
||||||
|
<path d="M82 145 Q65 165 70 185" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" fill="none" opacity="0.6"/>
|
||||||
|
<!-- Cauldron -->
|
||||||
|
<path d="M60 220 Q60 260 120 260 Q180 260 180 220" fill="currentColor" opacity="0.4"/>
|
||||||
|
<ellipse cx="120" cy="220" rx="60" ry="15" fill="currentColor" opacity="0.3"/>
|
||||||
|
<ellipse cx="120" cy="220" rx="60" ry="15" stroke="currentColor" stroke-width="2" fill="none" opacity="0.4"/>
|
||||||
|
<!-- Cauldron legs -->
|
||||||
|
<line x1="80" y1="258" x2="75" y2="280" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.5"/>
|
||||||
|
<line x1="160" y1="258" x2="165" y2="280" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.5"/>
|
||||||
|
<!-- Bubbles from cauldron -->
|
||||||
|
<circle cx="100" cy="210" r="5" fill="currentColor" opacity="0.2"/>
|
||||||
|
<circle cx="135" cy="205" r="4" fill="currentColor" opacity="0.18"/>
|
||||||
|
<circle cx="115" cy="198" r="3" fill="currentColor" opacity="0.15"/>
|
||||||
|
<!-- Sparkles -->
|
||||||
|
<circle cx="90" cy="190" r="2" fill="currentColor" opacity="0.25"/>
|
||||||
|
<circle cx="150" cy="195" r="2.5" fill="currentColor" opacity="0.2"/>
|
||||||
|
<circle cx="105" cy="185" r="1.5" fill="currentColor" opacity="0.2"/>
|
||||||
|
<!-- Character legs -->
|
||||||
|
<line x1="105" y1="190" x2="95" y2="225" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.5"/>
|
||||||
|
<line x1="135" y1="190" x2="145" y2="225" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.5"/>
|
||||||
|
</svg>
|
||||||
|
|
||||||
<div class="container-content max-w-3xl mx-auto">
|
<div class="container-content max-w-3xl mx-auto">
|
||||||
<!-- Back link -->
|
<!-- Back link -->
|
||||||
<UiScrollReveal>
|
<UiScrollReveal>
|
||||||
@@ -77,14 +119,14 @@ const { url, launch } = useGrateWizard()
|
|||||||
.gw-feature-card {
|
.gw-feature-card {
|
||||||
padding: 1.5rem;
|
padding: 1.5rem;
|
||||||
border-radius: 0.75rem;
|
border-radius: 0.75rem;
|
||||||
border: 1px solid hsl(20 8% 18%);
|
border: 1px solid hsl(var(--color-text) / 0.1);
|
||||||
background: hsl(20 8% 8% / 0.5);
|
background: hsl(var(--color-surface) / 0.5);
|
||||||
transition: border-color 0.3s ease, background 0.3s ease;
|
transition: border-color 0.3s ease, background 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gw-feature-card:hover {
|
.gw-feature-card:hover {
|
||||||
border-color: hsl(40 80% 50% / 0.25);
|
border-color: hsl(40 80% 50% / 0.25);
|
||||||
background: hsl(20 8% 10% / 0.5);
|
background: hsl(var(--color-surface-light) / 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
code {
|
code {
|
||||||
@@ -94,4 +136,24 @@ code {
|
|||||||
border-radius: 0.25em;
|
border-radius: 0.25em;
|
||||||
background: hsl(40 80% 50% / 0.1);
|
background: hsl(40 80% 50% / 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.shadok-alchemist {
|
||||||
|
position: absolute;
|
||||||
|
right: 2%;
|
||||||
|
top: 15%;
|
||||||
|
width: clamp(100px, 14vw, 190px);
|
||||||
|
opacity: 0.1;
|
||||||
|
pointer-events: none;
|
||||||
|
color: hsl(var(--color-accent));
|
||||||
|
animation: shadok-float-alchemist 10s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes shadok-float-alchemist {
|
||||||
|
0%, 100% { transform: translateY(0) rotate(0deg); }
|
||||||
|
50% { transform: translateY(-10px) rotate(1deg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.shadok-alchemist { display: none; }
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,5 +1,54 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="section-padding">
|
<div class="relative overflow-hidden section-padding">
|
||||||
|
<!-- Shadok reader: character with big glasses reading a book -->
|
||||||
|
<svg class="shadok-reader" viewBox="0 0 240 300" fill="none" aria-hidden="true">
|
||||||
|
<!-- Body -->
|
||||||
|
<ellipse cx="120" cy="170" rx="45" ry="55" fill="currentColor" opacity="0.85"/>
|
||||||
|
<!-- Head -->
|
||||||
|
<circle cx="120" cy="100" r="28" fill="currentColor" opacity="0.8"/>
|
||||||
|
<!-- Big round glasses -->
|
||||||
|
<circle cx="107" cy="94" r="11" stroke="currentColor" stroke-width="2.5" fill="none" opacity="0.5"/>
|
||||||
|
<circle cx="133" cy="94" r="11" stroke="currentColor" stroke-width="2.5" fill="none" opacity="0.5"/>
|
||||||
|
<line x1="118" y1="94" x2="122" y2="94" stroke="currentColor" stroke-width="2" opacity="0.5"/>
|
||||||
|
<!-- Eyes behind glasses -->
|
||||||
|
<circle cx="108" cy="93" r="2.5" fill="currentColor" opacity="0.5"/>
|
||||||
|
<circle cx="134" cy="93" r="2.5" fill="currentColor" opacity="0.5"/>
|
||||||
|
<!-- Arms holding book -->
|
||||||
|
<line x1="78" y1="155" x2="60" y2="180" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||||
|
<line x1="162" y1="155" x2="180" y2="180" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||||
|
<!-- Book (open) -->
|
||||||
|
<rect x="55" y="175" width="55" height="40" rx="2" fill="currentColor" opacity="0.35"/>
|
||||||
|
<rect x="110" y="175" width="55" height="40" rx="2" fill="currentColor" opacity="0.3"/>
|
||||||
|
<line x1="110" y1="175" x2="110" y2="215" stroke="currentColor" stroke-width="2" opacity="0.5"/>
|
||||||
|
<!-- Book lines (text) -->
|
||||||
|
<line x1="65" y1="188" x2="100" y2="188" stroke="currentColor" stroke-width="1" opacity="0.2"/>
|
||||||
|
<line x1="65" y1="195" x2="95" y2="195" stroke="currentColor" stroke-width="1" opacity="0.2"/>
|
||||||
|
<line x1="65" y1="202" x2="98" y2="202" stroke="currentColor" stroke-width="1" opacity="0.2"/>
|
||||||
|
<!-- Legs -->
|
||||||
|
<line x1="105" y1="222" x2="95" y2="270" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||||
|
<line x1="135" y1="222" x2="145" y2="270" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
<!-- Shadok stack: pile of books tilting -->
|
||||||
|
<svg class="shadok-stack" viewBox="0 0 160 220" fill="none" aria-hidden="true">
|
||||||
|
<!-- Bottom book -->
|
||||||
|
<rect x="20" y="170" width="120" height="22" rx="3" fill="currentColor" opacity="0.5" transform="rotate(-2 80 181)"/>
|
||||||
|
<!-- Second book -->
|
||||||
|
<rect x="30" y="145" width="100" height="20" rx="3" fill="currentColor" opacity="0.45" transform="rotate(3 80 155)"/>
|
||||||
|
<!-- Third book -->
|
||||||
|
<rect x="25" y="120" width="110" height="18" rx="3" fill="currentColor" opacity="0.4" transform="rotate(-4 80 129)"/>
|
||||||
|
<!-- Fourth book -->
|
||||||
|
<rect x="35" y="97" width="90" height="18" rx="3" fill="currentColor" opacity="0.35" transform="rotate(5 80 106)"/>
|
||||||
|
<!-- Fifth book (tilting more) -->
|
||||||
|
<rect x="40" y="74" width="80" height="17" rx="3" fill="currentColor" opacity="0.3" transform="rotate(-7 80 82)"/>
|
||||||
|
<!-- Top book (really tilting) -->
|
||||||
|
<rect x="45" y="52" width="70" height="16" rx="3" fill="currentColor" opacity="0.25" transform="rotate(10 80 60)"/>
|
||||||
|
<!-- Tiny Shadok sitting on top -->
|
||||||
|
<ellipse cx="85" cy="42" rx="10" ry="8" fill="currentColor" opacity="0.5"/>
|
||||||
|
<circle cx="85" cy="30" r="6" fill="currentColor" opacity="0.45"/>
|
||||||
|
<circle cx="87" cy="29" r="1.5" fill="currentColor" opacity="0.3"/>
|
||||||
|
</svg>
|
||||||
|
|
||||||
<div class="container-content">
|
<div class="container-content">
|
||||||
<header class="mb-12 text-center">
|
<header class="mb-12 text-center">
|
||||||
<p class="mb-2 font-mono text-sm tracking-widest text-primary uppercase">{{ content?.kicker }}</p>
|
<p class="mb-2 font-mono text-sm tracking-widest text-primary uppercase">{{ content?.kicker }}</p>
|
||||||
@@ -68,4 +117,41 @@ const { data: chapters } = await useAsyncData('book-toc', () =>
|
|||||||
.page-title {
|
.page-title {
|
||||||
font-size: clamp(2rem, 5vw, 2.75rem);
|
font-size: clamp(2rem, 5vw, 2.75rem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.shadok-reader {
|
||||||
|
position: absolute;
|
||||||
|
right: 2%;
|
||||||
|
top: 5%;
|
||||||
|
width: clamp(90px, 13vw, 180px);
|
||||||
|
opacity: 0.1;
|
||||||
|
pointer-events: none;
|
||||||
|
color: hsl(var(--color-primary));
|
||||||
|
animation: shadok-float-reader 9s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shadok-stack {
|
||||||
|
position: absolute;
|
||||||
|
left: 2%;
|
||||||
|
bottom: 5%;
|
||||||
|
width: clamp(80px, 11vw, 150px);
|
||||||
|
opacity: 0.1;
|
||||||
|
pointer-events: none;
|
||||||
|
color: hsl(var(--color-accent));
|
||||||
|
animation: shadok-float-stack 11s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes shadok-float-reader {
|
||||||
|
0%, 100% { transform: translateY(0); }
|
||||||
|
50% { transform: translateY(-10px); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes shadok-float-stack {
|
||||||
|
0%, 100% { transform: translateY(0) rotate(0deg); }
|
||||||
|
50% { transform: translateY(-8px) rotate(-2deg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.shadok-reader { display: none; }
|
||||||
|
.shadok-stack { display: none; }
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -42,8 +42,8 @@ function formatDate(iso: string) {
|
|||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.message-card {
|
.message-card {
|
||||||
background: hsl(20 8% 6%);
|
background: hsl(var(--color-surface));
|
||||||
border: 1px solid hsl(20 8% 14%);
|
border: 1px solid hsl(var(--color-text) / 0.1);
|
||||||
border-radius: 0.75rem;
|
border-radius: 0.75rem;
|
||||||
padding: 1.25rem 1.5rem;
|
padding: 1.25rem 1.5rem;
|
||||||
}
|
}
|
||||||
|
|||||||
118
app/stores/palette.ts
Normal file
118
app/stores/palette.ts
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
export type PaletteName = 'automne' | 'hiver' | 'printemps' | 'ete'
|
||||||
|
|
||||||
|
interface PaletteColors {
|
||||||
|
primary: string
|
||||||
|
accent: string
|
||||||
|
surface: string
|
||||||
|
bg: string
|
||||||
|
surfaceLight: string
|
||||||
|
text: string
|
||||||
|
textMuted: string
|
||||||
|
isLight: boolean
|
||||||
|
label: string
|
||||||
|
icon: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const palettes: Record<PaletteName, PaletteColors> = {
|
||||||
|
// ══════ DARK THEMES ══════
|
||||||
|
|
||||||
|
// Automne : cuivre chaud, feuilles mortes, terre brûlée
|
||||||
|
automne: {
|
||||||
|
primary: '18 80% 45%', // cuivre profond
|
||||||
|
accent: '32 85% 50%', // ambre doré
|
||||||
|
surface: '16 12% 9%', // écorce sombre
|
||||||
|
bg: '16 12% 4%', // terre noire
|
||||||
|
surfaceLight: '16 10% 14%', // bois fumé
|
||||||
|
text: '0 0% 100%',
|
||||||
|
textMuted: '0 0% 60%',
|
||||||
|
isLight: false,
|
||||||
|
label: 'Automne',
|
||||||
|
icon: 'i-lucide-leaf',
|
||||||
|
},
|
||||||
|
|
||||||
|
// Hiver : bleu nuit, givre, argent lunaire
|
||||||
|
hiver: {
|
||||||
|
primary: '215 55% 52%', // bleu nuit étoilé
|
||||||
|
accent: '195 40% 65%', // givre argenté
|
||||||
|
surface: '220 15% 10%', // ciel de minuit
|
||||||
|
bg: '225 18% 5%', // nuit polaire
|
||||||
|
surfaceLight: '220 12% 15%', // brume nocturne
|
||||||
|
text: '0 0% 100%',
|
||||||
|
textMuted: '210 10% 60%',
|
||||||
|
isLight: false,
|
||||||
|
label: 'Hiver',
|
||||||
|
icon: 'i-lucide-snowflake',
|
||||||
|
},
|
||||||
|
|
||||||
|
// ══════ LIGHT THEMES ══════
|
||||||
|
|
||||||
|
// Printemps : vert tendre, rose cerisier, lumière fraîche
|
||||||
|
printemps: {
|
||||||
|
primary: '145 50% 38%', // vert bourgeon
|
||||||
|
accent: '340 65% 55%', // rose cerisier
|
||||||
|
surface: '120 12% 93%', // rosée du matin
|
||||||
|
bg: '100 15% 96%', // clarté verte
|
||||||
|
surfaceLight: '120 8% 87%', // feuille pâle
|
||||||
|
text: '150 15% 12%', // vert profond
|
||||||
|
textMuted: '140 8% 42%', // mousse
|
||||||
|
isLight: true,
|
||||||
|
label: 'Printemps',
|
||||||
|
icon: 'i-lucide-flower-2',
|
||||||
|
},
|
||||||
|
|
||||||
|
// Été : doré solaire, turquoise mer, lumineux chaleureux
|
||||||
|
ete: {
|
||||||
|
primary: '25 85% 52%', // soleil couchant
|
||||||
|
accent: '175 55% 42%', // turquoise marin
|
||||||
|
surface: '40 25% 92%', // sable clair
|
||||||
|
bg: '42 30% 96%', // lumière dorée
|
||||||
|
surfaceLight: '38 18% 86%', // dune
|
||||||
|
text: '30 20% 12%', // terre chaude
|
||||||
|
textMuted: '30 10% 40%', // ombre estivale
|
||||||
|
isLight: true,
|
||||||
|
label: 'Été',
|
||||||
|
icon: 'i-lucide-sun',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
export const usePaletteStore = defineStore('palette', () => {
|
||||||
|
const currentPalette = ref<PaletteName>(
|
||||||
|
(import.meta.client && localStorage.getItem('palette') as PaletteName) || 'automne',
|
||||||
|
)
|
||||||
|
|
||||||
|
const colors = computed(() => palettes[currentPalette.value])
|
||||||
|
const isLight = computed(() => colors.value.isLight)
|
||||||
|
|
||||||
|
function applyToDOM() {
|
||||||
|
if (!import.meta.client) return
|
||||||
|
const c = colors.value
|
||||||
|
const root = document.documentElement
|
||||||
|
const s = root.style
|
||||||
|
s.setProperty('--color-primary', c.primary)
|
||||||
|
s.setProperty('--color-accent', c.accent)
|
||||||
|
s.setProperty('--color-surface', c.surface)
|
||||||
|
s.setProperty('--color-bg', c.bg)
|
||||||
|
s.setProperty('--color-surface-light', c.surfaceLight)
|
||||||
|
s.setProperty('--color-text', c.text)
|
||||||
|
s.setProperty('--color-text-muted', c.textMuted)
|
||||||
|
// Toggle light/dark class for CSS overrides
|
||||||
|
root.classList.toggle('palette-light', c.isLight)
|
||||||
|
root.classList.toggle('palette-dark', !c.isLight)
|
||||||
|
s.setProperty('color-scheme', c.isLight ? 'light' : 'dark')
|
||||||
|
}
|
||||||
|
|
||||||
|
function setPalette(name: PaletteName) {
|
||||||
|
currentPalette.value = name
|
||||||
|
if (import.meta.client) localStorage.setItem('palette', name)
|
||||||
|
applyToDOM()
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
currentPalette,
|
||||||
|
colors,
|
||||||
|
palettes,
|
||||||
|
isLight,
|
||||||
|
setPalette,
|
||||||
|
applyToDOM,
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -7,18 +7,16 @@ readingTime: "25 min"
|
|||||||
|
|
||||||
Coder un rêve
|
Coder un rêve
|
||||||
|
|
||||||
\[Verse\]
|
|
||||||
Dans l'ombre des géants big tek
|
Dans l'ombre des géants big tek
|
||||||
Des lignes poussent discrètes
|
Des lignes poussent discrètes
|
||||||
Tourné vers la grande ourse
|
Tourné vers la grande ourse
|
||||||
Je coule open source
|
Je coule open source
|
||||||
|
|
||||||
\[Prechorus\]
|
Balance ton Json
|
||||||
Balance ton Jiz Onne
|
|
||||||
mon shell résonne
|
mon shell résonne
|
||||||
Coup de dés Py - thon Runtime Upgrade, ninja blayde
|
Coup de dés Python Runtime Upgrade, ninja blade
|
||||||
Ça bilt, Docker compose. Devant l'écran je pose. Ca biilt.
|
Ça build, Docker compose. Devant l'écran je pose. Ça build.
|
||||||
shhhhhhh... it com paille ...llss,
|
shhhhhhh... it compiles ...llss,
|
||||||
tapis dans une typo sans serif, je check les certif
|
tapis dans une typo sans serif, je check les certif
|
||||||
merde ça lag,
|
merde ça lag,
|
||||||
mate mes log,
|
mate mes log,
|
||||||
@@ -26,14 +24,13 @@ j'ai la langue qui bog.
|
|||||||
Mon café est tout froid
|
Mon café est tout froid
|
||||||
Je ne perds pas la foi.
|
Je ne perds pas la foi.
|
||||||
|
|
||||||
\[Chorus\]
|
Codeurs de rêve
|
||||||
Codeurs de rêv
|
|
||||||
Rime pour les dèvs
|
Rime pour les dèvs
|
||||||
dans les réseaux, où que j'aille
|
dans les réseaux, où que j'aille
|
||||||
vous êtes mes sudo,
|
vous êtes mes sudo,
|
||||||
mes samouraï
|
mes samouraï
|
||||||
Hackers, Admin,
|
Hackers, Admin,
|
||||||
Dèvop, développ
|
Devop, develop
|
||||||
Vous décentralisez
|
Vous décentralisez
|
||||||
Vous open sourcez
|
Vous open sourcez
|
||||||
Un monde moins obscur
|
Un monde moins obscur
|
||||||
@@ -41,7 +38,6 @@ Duniterre bien sûr.
|
|||||||
Notre toil fiduciaire
|
Notre toil fiduciaire
|
||||||
Nous pouvez être fiers
|
Nous pouvez être fiers
|
||||||
|
|
||||||
\[Verse 2\]
|
|
||||||
Appel aux ressources
|
Appel aux ressources
|
||||||
Donner vie au code source
|
Donner vie au code source
|
||||||
Léger besoin de finance
|
Léger besoin de finance
|
||||||
@@ -53,7 +49,6 @@ Du fuel pour les applis
|
|||||||
tous vos dons ... les mettent à l'abri
|
tous vos dons ... les mettent à l'abri
|
||||||
Merci
|
Merci
|
||||||
|
|
||||||
\[Bridge\]
|
|
||||||
Crash à minuit
|
Crash à minuit
|
||||||
Je reste éveillé
|
Je reste éveillé
|
||||||
Le bug fatal
|
Le bug fatal
|
||||||
@@ -63,14 +58,13 @@ Je vais le basher
|
|||||||
Le café est-il prêt ?
|
Le café est-il prêt ?
|
||||||
C'est bientôt aujourd'hui
|
C'est bientôt aujourd'hui
|
||||||
|
|
||||||
\[Chorus\]
|
Codeurs de rêve
|
||||||
Codeurs de rêv
|
|
||||||
Rime pour les dèvs
|
Rime pour les dèvs
|
||||||
dans les réseaux, où que j'aille
|
dans les réseaux, où que j'aille
|
||||||
vous êtes mes sudo,
|
vous êtes mes sudo,
|
||||||
mes samouraï
|
mes samouraï
|
||||||
Hackers, Admin,
|
Hackers, Admin,
|
||||||
Dèvop, développ
|
Devop, develop
|
||||||
Vous décentralisez
|
Vous décentralisez
|
||||||
Vous open sourcez
|
Vous open sourcez
|
||||||
Un monde moins obscur
|
Un monde moins obscur
|
||||||
|
|||||||
@@ -7,12 +7,6 @@ readingTime: "15 min"
|
|||||||
|
|
||||||
Inverser les flux
|
Inverser les flux
|
||||||
|
|
||||||
\[Intro\]
|
|
||||||
\[Guitar vibraphone : Accords riches et harmoniques\]
|
|
||||||
\[Basse : Une ligne très ronde qui glisse\]
|
|
||||||
\[Cut Brass swell\]
|
|
||||||
\[Articulte, french\]
|
|
||||||
|
|
||||||
Tu choisis ... ta monnaie,
|
Tu choisis ... ta monnaie,
|
||||||
son économie,
|
son économie,
|
||||||
Tu passes de l'une à l'autre
|
Tu passes de l'une à l'autre
|
||||||
@@ -23,22 +17,18 @@ Tu peux aussi ne plus l'appeler monnaie du tout.
|
|||||||
Changer de lunettes, (mais pas les rose)
|
Changer de lunettes, (mais pas les rose)
|
||||||
c'est un ruban-mètre, posé sur la planète.
|
c'est un ruban-mètre, posé sur la planète.
|
||||||
|
|
||||||
\[Chorus\]
|
|
||||||
(Groove s'intensifie, la batterie claque)
|
|
||||||
Le D.U, c'est une mesure.
|
Le D.U, c'est une mesure.
|
||||||
(Choir: La mesure...)
|
(Choir: La mesure...)
|
||||||
Pour ne plus obliger. Pour ne plus devoir.
|
Pour ne plus obliger. Pour ne plus devoir.
|
||||||
Je donne à mon économie, j'alimente le réservoir.
|
Je donne à mon économie, j'alimente le réservoir.
|
||||||
\[break\]
|
|
||||||
Si je t'aime, j'y mets mon affect.
|
Si je t'aime, j'y mets mon affect.
|
||||||
Si je ne t'aime pas, du moins je te respecte.
|
Si je ne t'aime pas, du moins je te respecte.
|
||||||
Je compte sur les autres, sur mon économie,
|
Je compte sur les autres, sur mon économie,
|
||||||
Pour y trouver ma pleine mesure.
|
Pour y trouver ma pleine mesure.
|
||||||
La solidarité organique, pas de paniK
|
La solidarité organique, pas de panique
|
||||||
Elle franchit les limites.
|
Elle franchit les limites.
|
||||||
(Choir: Organique...)
|
(Choir: Organique...)
|
||||||
|
|
||||||
\[Verse 1\]
|
|
||||||
"Je ne veux rien en retour", c'est ce que tu dis.
|
"Je ne veux rien en retour", c'est ce que tu dis.
|
||||||
Mais tu m'obliges.
|
Mais tu m'obliges.
|
||||||
Tu crées une dette non dite,
|
Tu crées une dette non dite,
|
||||||
@@ -47,7 +37,6 @@ La solidarité mécanique est complexe
|
|||||||
Elle a ses limites.
|
Elle a ses limites.
|
||||||
(Whisper: C'est horrible pour les mites)
|
(Whisper: C'est horrible pour les mites)
|
||||||
|
|
||||||
\[Le rythme devient plus sec, plus percussif. Flow rapide\]
|
|
||||||
Alors j'opère un retournement.
|
Alors j'opère un retournement.
|
||||||
Je choisis mes mots, c'est un glissement.
|
Je choisis mes mots, c'est un glissement.
|
||||||
(...)
|
(...)
|
||||||
@@ -65,10 +54,9 @@ La "dépossession monétaire" n'a plus lieu d'être.
|
|||||||
Ce n'est plus mortifère, ni délétère.
|
Ce n'est plus mortifère, ni délétère.
|
||||||
(...)
|
(...)
|
||||||
Je rentre du marché, nouveau vocabulaire :
|
Je rentre du marché, nouveau vocabulaire :
|
||||||
\[Male\]- "Hey - j'ai reçu une semaine de cour-ss."
|
(Male) - "Hey - j'ai reçu une semaine de cours."
|
||||||
\[Female\]- "Wow, t'as mis gratitude max à la source ?"
|
(Female) - "Wow, t'as mis gratitude max à la source ?"
|
||||||
|
|
||||||
\[Bridge - Duet Call & Response\]
|
|
||||||
(Male) Je ne paye plus.
|
(Male) Je ne paye plus.
|
||||||
(Female) Je mesure. J'estime...
|
(Female) Je mesure. J'estime...
|
||||||
(Male) Je négocie détendu. (c'est un virage)
|
(Male) Je négocie détendu. (c'est un virage)
|
||||||
@@ -77,16 +65,13 @@ Je rentre du marché, nouveau vocabulaire :
|
|||||||
(Female) De la masse.
|
(Female) De la masse.
|
||||||
(Both) Ou une température.
|
(Both) Ou une température.
|
||||||
L'économie, c'est de l'énergie, de la chaleur c'est sûr.
|
L'économie, c'est de l'énergie, de la chaleur c'est sûr.
|
||||||
\[break\] Je grave ma gratitude dans la chaîne.
|
Je grave ma gratitude dans la chaîne.
|
||||||
C'est une trans-action. Au sens noble du terme.
|
C'est une trans-action. Au sens noble du terme.
|
||||||
|
|
||||||
\[Chorus - Ensemble\]
|
|
||||||
(Groove s'intensifie, la batterie claque)
|
|
||||||
Le D.U, c'est une mesure.
|
Le D.U, c'est une mesure.
|
||||||
(Choir: La mesure...)
|
(Choir: La mesure...)
|
||||||
Pour ne plus obliger. Pour ne plus devoir.
|
Pour ne plus obliger. Pour ne plus devoir.
|
||||||
Je donne à mon économie, j'alimente le réservoir.
|
Je donne à mon économie, j'alimente le réservoir.
|
||||||
\[break\]
|
|
||||||
Si je t'aime, j'y mets mon affect.
|
Si je t'aime, j'y mets mon affect.
|
||||||
Si je ne t'aime pas, du moins je te respecte.
|
Si je ne t'aime pas, du moins je te respecte.
|
||||||
Je compte sur les autres, sur mon économie,
|
Je compte sur les autres, sur mon économie,
|
||||||
@@ -95,8 +80,6 @@ La solidarité organique, pas de panique
|
|||||||
Elle franchit les limites.
|
Elle franchit les limites.
|
||||||
(Choir: Organique...)
|
(Choir: Organique...)
|
||||||
|
|
||||||
\[Verse 3 - Male Lead\]
|
|
||||||
\[Musique s'épure, Basse et Claquements de doigts. Question tone\]
|
|
||||||
Dis,... et quand c'est la course ? Si c'est une buvette ?
|
Dis,... et quand c'est la course ? Si c'est une buvette ?
|
||||||
Pas le temps des discours, philosopher sur la canette ?
|
Pas le temps des discours, philosopher sur la canette ?
|
||||||
(Female : Faut qu'ça dépote !)
|
(Female : Faut qu'ça dépote !)
|
||||||
@@ -107,21 +90,14 @@ Ils ont posé leurs références.
|
|||||||
Tu prends ou pas, tu vois si c'est bon,
|
Tu prends ou pas, tu vois si c'est bon,
|
||||||
tu entres dans la danse.
|
tu entres dans la danse.
|
||||||
Tu peux gratifier plus, si le cœur t'en dit.
|
Tu peux gratifier plus, si le cœur t'en dit.
|
||||||
Plaider un co-eff. relatif aussi...
|
Plaider un coeff. relatif aussi...
|
||||||
Mais la mesure est là, autour d'un bel invariant, on sait où on va.
|
Mais la mesure est là, autour d'un bel invariant, on sait où on va.
|
||||||
(...)
|
(...)
|
||||||
Au delà d'un simple théorème
|
Au delà d'un simple théorème
|
||||||
C'est le cadeau de la T.R.M.
|
C'est le cadeau de la T.R.M.
|
||||||
|
|
||||||
\[Outro\]
|
|
||||||
(Female ad-libs: Équilibre... Invariant...)
|
|
||||||
\[Rhodes solo, jazzy and improvised\]
|
|
||||||
\[Male spoken sexy\]
|
|
||||||
On frotte nos échelles.
|
On frotte nos échelles.
|
||||||
On construit avec les autres.
|
On construit avec les autres.
|
||||||
(Fade out on the warm bass line)
|
|
||||||
\[Female sexy\]
|
|
||||||
Construction culturelle.
|
Construction culturelle.
|
||||||
\[break smooth\]
|
|
||||||
J'évalue mon degré de gratitude
|
J'évalue mon degré de gratitude
|
||||||
Pour que ça devienne une habitude.
|
Pour que ça devienne une habitude.
|
||||||
|
|||||||
@@ -7,12 +7,6 @@ readingTime: "25 min"
|
|||||||
|
|
||||||
Inverser les flux
|
Inverser les flux
|
||||||
|
|
||||||
\[Intro\]
|
|
||||||
\[Guitar vibraphone : Accords riches et harmoniques\]
|
|
||||||
\[Basse : Une ligne très ronde qui glisse\]
|
|
||||||
\[Cut Brass swell\]
|
|
||||||
\[Articulte, french\]
|
|
||||||
|
|
||||||
Tu choisis ... ta monnaie,
|
Tu choisis ... ta monnaie,
|
||||||
son économie,
|
son économie,
|
||||||
Tu passes de l'une à l'autre
|
Tu passes de l'une à l'autre
|
||||||
@@ -23,22 +17,18 @@ Tu peux aussi ne plus l'appeler monnaie du tout.
|
|||||||
Changer de lunettes, (mais pas les rose)
|
Changer de lunettes, (mais pas les rose)
|
||||||
c'est un ruban-mètre, posé sur la planète.
|
c'est un ruban-mètre, posé sur la planète.
|
||||||
|
|
||||||
\[Chorus\]
|
|
||||||
(Groove s'intensifie, la batterie claque)
|
|
||||||
Le D.U, c'est une mesure.
|
Le D.U, c'est une mesure.
|
||||||
(Choir: La mesure...)
|
(Choir: La mesure...)
|
||||||
Pour ne plus obliger. Pour ne plus devoir.
|
Pour ne plus obliger. Pour ne plus devoir.
|
||||||
Je donne à mon économie, j'alimente le réservoir.
|
Je donne à mon économie, j'alimente le réservoir.
|
||||||
\[break\]
|
|
||||||
Si je t'aime, j'y mets mon affect.
|
Si je t'aime, j'y mets mon affect.
|
||||||
Si je ne t'aime pas, du moins je te respecte.
|
Si je ne t'aime pas, du moins je te respecte.
|
||||||
Je compte sur les autres, sur mon économie,
|
Je compte sur les autres, sur mon économie,
|
||||||
Pour y trouver ma pleine mesure.
|
Pour y trouver ma pleine mesure.
|
||||||
La solidarité organique, pas de paniK
|
La solidarité organique, pas de panique
|
||||||
Elle franchit les limites.
|
Elle franchit les limites.
|
||||||
(Choir: Organique...)
|
(Choir: Organique...)
|
||||||
|
|
||||||
\[Verse 1\]
|
|
||||||
"Je ne veux rien en retour", c'est ce que tu dis.
|
"Je ne veux rien en retour", c'est ce que tu dis.
|
||||||
Mais tu m'obliges.
|
Mais tu m'obliges.
|
||||||
Tu crées une dette non dite,
|
Tu crées une dette non dite,
|
||||||
@@ -47,7 +37,6 @@ La solidarité mécanique est complexe
|
|||||||
Elle a ses limites.
|
Elle a ses limites.
|
||||||
(Whisper: C'est horrible pour les mites)
|
(Whisper: C'est horrible pour les mites)
|
||||||
|
|
||||||
\[Le rythme devient plus sec, plus percussif. Flow rapide\]
|
|
||||||
Alors j'opère un retournement.
|
Alors j'opère un retournement.
|
||||||
Je choisis mes mots, c'est un glissement.
|
Je choisis mes mots, c'est un glissement.
|
||||||
(...)
|
(...)
|
||||||
@@ -65,10 +54,9 @@ La "dépossession monétaire" n'a plus lieu d'être.
|
|||||||
Ce n'est plus mortifère, ni délétère.
|
Ce n'est plus mortifère, ni délétère.
|
||||||
(...)
|
(...)
|
||||||
Je rentre du marché, nouveau vocabulaire :
|
Je rentre du marché, nouveau vocabulaire :
|
||||||
\[Male\]- "Hey - j'ai reçu une semaine de cour-ss."
|
(Male) - "Hey - j'ai reçu une semaine de cours."
|
||||||
\[Female\]- "Wow, t'as mis gratitude max à la source ?"
|
(Female) - "Wow, t'as mis gratitude max à la source ?"
|
||||||
|
|
||||||
\[Bridge - Duet Call & Response\]
|
|
||||||
(Male) Je ne paye plus.
|
(Male) Je ne paye plus.
|
||||||
(Female) Je mesure. J'estime...
|
(Female) Je mesure. J'estime...
|
||||||
(Male) Je négocie détendu. (c'est un virage)
|
(Male) Je négocie détendu. (c'est un virage)
|
||||||
@@ -77,16 +65,13 @@ Je rentre du marché, nouveau vocabulaire :
|
|||||||
(Female) De la masse.
|
(Female) De la masse.
|
||||||
(Both) Ou une température.
|
(Both) Ou une température.
|
||||||
L'économie, c'est de l'énergie, de la chaleur c'est sûr.
|
L'économie, c'est de l'énergie, de la chaleur c'est sûr.
|
||||||
\[break\] Je grave ma gratitude dans la chaîne.
|
Je grave ma gratitude dans la chaîne.
|
||||||
C'est une trans-action. Au sens noble du terme.
|
C'est une trans-action. Au sens noble du terme.
|
||||||
|
|
||||||
\[Chorus - Ensemble\]
|
|
||||||
(Groove s'intensifie, la batterie claque)
|
|
||||||
Le D.U, c'est une mesure.
|
Le D.U, c'est une mesure.
|
||||||
(Choir: La mesure...)
|
(Choir: La mesure...)
|
||||||
Pour ne plus obliger. Pour ne plus devoir.
|
Pour ne plus obliger. Pour ne plus devoir.
|
||||||
Je donne à mon économie, j'alimente le réservoir.
|
Je donne à mon économie, j'alimente le réservoir.
|
||||||
\[break\]
|
|
||||||
Si je t'aime, j'y mets mon affect.
|
Si je t'aime, j'y mets mon affect.
|
||||||
Si je ne t'aime pas, du moins je te respecte.
|
Si je ne t'aime pas, du moins je te respecte.
|
||||||
Je compte sur les autres, sur mon économie,
|
Je compte sur les autres, sur mon économie,
|
||||||
@@ -95,8 +80,6 @@ La solidarité organique, pas de panique
|
|||||||
Elle franchit les limites.
|
Elle franchit les limites.
|
||||||
(Choir: Organique...)
|
(Choir: Organique...)
|
||||||
|
|
||||||
\[Verse 3 - Male Lead\]
|
|
||||||
\[Musique s'épure, Basse et Claquements de doigts. Question tone\]
|
|
||||||
Dis,... et quand c'est la course ? Si c'est une buvette ?
|
Dis,... et quand c'est la course ? Si c'est une buvette ?
|
||||||
Pas le temps des discours, philosopher sur la canette ?
|
Pas le temps des discours, philosopher sur la canette ?
|
||||||
(Female : Faut qu'ça dépote !)
|
(Female : Faut qu'ça dépote !)
|
||||||
@@ -107,21 +90,14 @@ Ils ont posé leurs références.
|
|||||||
Tu prends ou pas, tu vois si c'est bon,
|
Tu prends ou pas, tu vois si c'est bon,
|
||||||
tu entres dans la danse.
|
tu entres dans la danse.
|
||||||
Tu peux gratifier plus, si le cœur t'en dit.
|
Tu peux gratifier plus, si le cœur t'en dit.
|
||||||
Plaider un co-eff. relatif aussi...
|
Plaider un coeff. relatif aussi...
|
||||||
Mais la mesure est là, autour d'un bel invariant, on sait où on va.
|
Mais la mesure est là, autour d'un bel invariant, on sait où on va.
|
||||||
(...)
|
(...)
|
||||||
Au delà d'un simple théorème
|
Au delà d'un simple théorème
|
||||||
C'est le cadeau de la T.R.M.
|
C'est le cadeau de la T.R.M.
|
||||||
|
|
||||||
\[Outro\]
|
|
||||||
(Female ad-libs: Équilibre... Invariant...)
|
|
||||||
\[Rhodes solo, jazzy and improvised\]
|
|
||||||
\[Male spoken sexy\]
|
|
||||||
On frotte nos échelles.
|
On frotte nos échelles.
|
||||||
On construit avec les autres.
|
On construit avec les autres.
|
||||||
(Fade out on the warm bass line)
|
|
||||||
\[Female sexy\]
|
|
||||||
Construction culturelle.
|
Construction culturelle.
|
||||||
\[break smooth\]
|
|
||||||
J'évalue mon degré de gratitude
|
J'évalue mon degré de gratitude
|
||||||
Pour que ça devienne une habitude.
|
Pour que ça devienne une habitude.
|
||||||
|
|||||||
@@ -7,9 +7,6 @@ readingTime: "20 min"
|
|||||||
|
|
||||||
Les asymétries
|
Les asymétries
|
||||||
|
|
||||||
\[Intro\]
|
|
||||||
(Cello and Bowed Bass: low, scraping texture)
|
|
||||||
(Piano: Single discordant note repeated)
|
|
||||||
(Male: Voix très posée, grave, proche)
|
(Male: Voix très posée, grave, proche)
|
||||||
Entre soi... Connivence fait loi.
|
Entre soi... Connivence fait loi.
|
||||||
On est entre nous On se rassure.
|
On est entre nous On se rassure.
|
||||||
@@ -19,12 +16,10 @@ Nous sommes trop convaincus.
|
|||||||
Cela nous endort. Ce que je crois peut-être à tord ... tue.
|
Cela nous endort. Ce que je crois peut-être à tord ... tue.
|
||||||
(Females: Pseudo-isolés... Pseudo-isolés...)
|
(Females: Pseudo-isolés... Pseudo-isolés...)
|
||||||
|
|
||||||
\[Verse 1\]
|
J'ai vu des collectifs, plus ou moins disruptifs.
|
||||||
(Drums enter: intricate brushwork, soft but fast)
|
Parfois prônant le don, par exemple Solaris.
|
||||||
J'ai vu des collectifs, plus ou moins dissruptifs.
|
|
||||||
Parfois prônant le don, par exemple Solariss.
|
|
||||||
J'y ai vu de l'usure, le sentiment d'abus.
|
J'y ai vu de l'usure, le sentiment d'abus.
|
||||||
Des abandons moribons, ...
|
Des abandons moribonds, ...
|
||||||
Ha bon ?
|
Ha bon ?
|
||||||
|
|
||||||
Malgré quelques notifs, et les esprits attentifs
|
Malgré quelques notifs, et les esprits attentifs
|
||||||
@@ -32,8 +27,6 @@ Parfois nous le savons, dans les violons on pisse
|
|||||||
J'ai vu aussi bien sûr, quelques trous du cul
|
J'ai vu aussi bien sûr, quelques trous du cul
|
||||||
Mais ! Est-ce là une bonne raison ?
|
Mais ! Est-ce là une bonne raison ?
|
||||||
|
|
||||||
\[Bridge 1\]
|
|
||||||
(Rhythm becomes jagged, syncopated stops)
|
|
||||||
Rien n'est symétrique, ce n'est pas magique.
|
Rien n'est symétrique, ce n'est pas magique.
|
||||||
(Females: ) Rien.
|
(Females: ) Rien.
|
||||||
Une pomme aujourd'hui, n'est pas la même demain.
|
Une pomme aujourd'hui, n'est pas la même demain.
|
||||||
@@ -42,10 +35,7 @@ Et s'il y a une cagette, ce n'est pas cinq palettes.
|
|||||||
Six heures assis à parler bien à l'aise...
|
Six heures assis à parler bien à l'aise...
|
||||||
Six heures à genoux sur un toit...ho ! balaise
|
Six heures à genoux sur un toit...ho ! balaise
|
||||||
(Females:) Est-ce le même geste, ou une ascèse ? mmmhh.
|
(Females:) Est-ce le même geste, ou une ascèse ? mmmhh.
|
||||||
(Silence - 1 second)
|
|
||||||
|
|
||||||
\[Chorus\]
|
|
||||||
(Music swells slightly, singing questions)
|
|
||||||
Alors que faire ? On désespère, on baisse les bras ?
|
Alors que faire ? On désespère, on baisse les bras ?
|
||||||
on légifère ? On écrit des lois ?
|
on légifère ? On écrit des lois ?
|
||||||
On réglemente, on décide de l'issue ?
|
On réglemente, on décide de l'issue ?
|
||||||
@@ -54,8 +44,6 @@ Mieux vaut peut-être un protocole avec quelques bémol.
|
|||||||
Une façon de traiter, d'éviter de juger, préfigurer.
|
Une façon de traiter, d'éviter de juger, préfigurer.
|
||||||
(suspension) Ne pas tranchez les sorts, à leur insu.
|
(suspension) Ne pas tranchez les sorts, à leur insu.
|
||||||
|
|
||||||
\[Verse 2\]
|
|
||||||
(Bass is now plucked, heavy groove)
|
|
||||||
Pour limiter le ressentiment,
|
Pour limiter le ressentiment,
|
||||||
la lassitude, l'envenime-ment.
|
la lassitude, l'envenime-ment.
|
||||||
Il suffit d'une mesure.
|
Il suffit d'une mesure.
|
||||||
@@ -68,7 +56,6 @@ Qui célèbre le mérite ? - Dans l'ombre du monde ;
|
|||||||
Pas celui des héritages ? - Ce s'rait possible ça ?
|
Pas celui des héritages ? - Ce s'rait possible ça ?
|
||||||
Qui réellement, récompense et compense ? sans dépense ni dispense ?
|
Qui réellement, récompense et compense ? sans dépense ni dispense ?
|
||||||
|
|
||||||
\[Bridge 2\]
|
|
||||||
Une communauté ne peut pas tout écrire.
|
Une communauté ne peut pas tout écrire.
|
||||||
La loi, ne peut pas tout régler.
|
La loi, ne peut pas tout régler.
|
||||||
même si c'est toi qui la fait
|
même si c'est toi qui la fait
|
||||||
@@ -77,8 +64,6 @@ Une belle et grande morale ? - c'est bancal :
|
|||||||
Il est utile de prévenir, se souvenir, ...
|
Il est utile de prévenir, se souvenir, ...
|
||||||
C'est le pire.
|
C'est le pire.
|
||||||
|
|
||||||
\[Chorus\]
|
|
||||||
(Music swells slightly)
|
|
||||||
Alors que faire ? On désespère, on baisse les bras ?
|
Alors que faire ? On désespère, on baisse les bras ?
|
||||||
on légifère ? On écrit des lois ?
|
on légifère ? On écrit des lois ?
|
||||||
On réglemente, on décide de l'issue ?
|
On réglemente, on décide de l'issue ?
|
||||||
@@ -88,23 +73,18 @@ Une façon de traiter, d'éviter de juger, préfigurer.
|
|||||||
(suspension) Ne pas tranchez les sorts, à leur insu.
|
(suspension) Ne pas tranchez les sorts, à leur insu.
|
||||||
(suspension) Ne tranchez pas mon sort, à mon insu.
|
(suspension) Ne tranchez pas mon sort, à mon insu.
|
||||||
|
|
||||||
\[Bridge 1\]
|
|
||||||
(Rhythm becomes jagged, syncopated stops)
|
|
||||||
Rien n'est symétrique. Ce n'est pas magique.
|
Rien n'est symétrique. Ce n'est pas magique.
|
||||||
(Females:) Rien.
|
(Females:) Rien.
|
||||||
Pour se rétablir, retomber sur nos pieds
|
Pour se rétablir, retomber sur nos pieds
|
||||||
Il existe un outil qui s'appelle, ... "la monnaie".
|
Il existe un outil qui s'appelle, ... "la monnaie".
|
||||||
|
|
||||||
\[Verse 3\]
|
|
||||||
C'est elle en permanence qui résout le "schmilblick".
|
C'est elle en permanence qui résout le "schmilblick".
|
||||||
Même sans qu'on y pense, faut avouer, c'est pratique
|
Même sans qu'on y pense, faut avouer, c'est pratique
|
||||||
C'est elle qui compense, récompense ou dispense
|
C'est elle qui compense, récompense ou dispense
|
||||||
Mais attention, délit de pleine flagrance ! (drum, suspension)
|
Mais attention, délit de pleine flagrance !
|
||||||
Chaque monnaie programme sa propre engence.
|
Chaque monnaie programme sa propre engence.
|
||||||
Ne t'y méprends pas, son pouvoir est immense.
|
Ne t'y méprends pas, son pouvoir est immense.
|
||||||
|
|
||||||
\[Outro\]
|
|
||||||
(Piano flowing arpeggios, fading)
|
|
||||||
Résoudre le problème des asymétries.
|
Résoudre le problème des asymétries.
|
||||||
Réduire le besoin de légiférer.
|
Réduire le besoin de légiférer.
|
||||||
Pour une simple coloc... ou pour un monde entier.
|
Pour une simple coloc... ou pour un monde entier.
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ readingTime: "18 min"
|
|||||||
|
|
||||||
Désir des arts
|
Désir des arts
|
||||||
|
|
||||||
\[Intro\]
|
|
||||||
La matière est peu docile
|
La matière est peu docile
|
||||||
L'esprit est agile
|
L'esprit est agile
|
||||||
Il désire l'art
|
Il désire l'art
|
||||||
@@ -15,19 +14,16 @@ Les mains sont habiles
|
|||||||
précieuses et volubiles
|
précieuses et volubiles
|
||||||
Elles façonnent des amarres
|
Elles façonnent des amarres
|
||||||
|
|
||||||
\[Pont\]
|
|
||||||
C'est reparti pour un tour
|
C'est reparti pour un tour
|
||||||
Pour le désir des arts
|
Pour le désir des arts
|
||||||
Nous voilà de retour
|
Nous voilà de retour
|
||||||
Vous nous avez manqué
|
Vous nous avez manqué
|
||||||
|
|
||||||
\[Refrain\]
|
|
||||||
Les mains habiles
|
Les mains habiles
|
||||||
L'esprit agile
|
L'esprit agile
|
||||||
La matière plus docile
|
La matière plus docile
|
||||||
Sous le geste de l'émotion
|
Sous le geste de l'émotion
|
||||||
|
|
||||||
\[Couplet 1\]
|
|
||||||
Les structures sont solides
|
Les structures sont solides
|
||||||
Les intentions fluides
|
Les intentions fluides
|
||||||
Notre équipe est unie
|
Notre équipe est unie
|
||||||
@@ -35,13 +31,11 @@ Prête pour l'inédit
|
|||||||
Nous serons à vos côtés
|
Nous serons à vos côtés
|
||||||
En ce lieu de toute beauté
|
En ce lieu de toute beauté
|
||||||
|
|
||||||
\[Refrain\]
|
|
||||||
Les mains habiles
|
Les mains habiles
|
||||||
L'esprit agile
|
L'esprit agile
|
||||||
La matière plus docile
|
La matière plus docile
|
||||||
Sous le geste de l'émotion
|
Sous le geste de l'émotion
|
||||||
|
|
||||||
\[Couplet 2\]
|
|
||||||
Qu'ils soient cent
|
Qu'ils soient cent
|
||||||
Qu'ils soient mille
|
Qu'ils soient mille
|
||||||
Curieux ou passionnés
|
Curieux ou passionnés
|
||||||
@@ -51,13 +45,11 @@ Partout est l'attrait
|
|||||||
Touchez sans les gants
|
Touchez sans les gants
|
||||||
Ici le désir vrille
|
Ici le désir vrille
|
||||||
|
|
||||||
\[Refrain\]
|
|
||||||
Les mains habiles
|
Les mains habiles
|
||||||
L'esprit agile
|
L'esprit agile
|
||||||
La matière plus docile
|
La matière plus docile
|
||||||
Sous le geste de l'émotion
|
Sous le geste de l'émotion
|
||||||
|
|
||||||
\[Outro\]
|
|
||||||
L'Art est de retour
|
L'Art est de retour
|
||||||
Il célèbre l'amour
|
Il célèbre l'amour
|
||||||
Demain un autre jour
|
Demain un autre jour
|
||||||
|
|||||||
@@ -7,14 +7,9 @@ readingTime: "8 min"
|
|||||||
|
|
||||||
Ainsi soit-il
|
Ainsi soit-il
|
||||||
|
|
||||||
\[Intro\]
|
|
||||||
\[Vinyl Crackle Sound\]
|
|
||||||
\[Minimalist Piano Loop\]
|
|
||||||
Fiat...
|
Fiat...
|
||||||
Fiat Lux… Fiat Euro.
|
Fiat Lux… Fiat Euro.
|
||||||
|
|
||||||
\[Verse 1\]
|
|
||||||
\[Spoken Word, Calm and Clear\]
|
|
||||||
Fiat. Ce n'est pas une marque.
|
Fiat. Ce n'est pas une marque.
|
||||||
C'est du latin.
|
C'est du latin.
|
||||||
Ça veut dire : "Que cela soit".
|
Ça veut dire : "Que cela soit".
|
||||||
@@ -25,15 +20,11 @@ Un monopole déclaré.
|
|||||||
Une clé de voûte qui tient tout l'édifice.
|
Une clé de voûte qui tient tout l'édifice.
|
||||||
Si la clé casse... tout s'écroule.
|
Si la clé casse... tout s'écroule.
|
||||||
|
|
||||||
\[Chorus\]
|
|
||||||
\[Melodic Hook, Softly Sung\]
|
|
||||||
Mais la monnaie n'est pas la richesse.
|
Mais la monnaie n'est pas la richesse.
|
||||||
C'est juste le mètre... pas le tissu.
|
C'est juste le mètre... pas le tissu.
|
||||||
C'est le baromètre... pas le climat.
|
C'est le baromètre... pas le climat.
|
||||||
Ne confondons pas la carte et le territoire.
|
Ne confondons pas la carte et le territoire.
|
||||||
|
|
||||||
\[Verse 2\]
|
|
||||||
\[Rhythmic Spoken, Slightly Faster\]
|
|
||||||
Message aux pionniers :
|
Message aux pionniers :
|
||||||
Faire tourner la monnaie en rond, ce n'est pas créer.
|
Faire tourner la monnaie en rond, ce n'est pas créer.
|
||||||
Se faire des virements autour d'une table...
|
Se faire des virements autour d'une table...
|
||||||
@@ -45,19 +36,12 @@ L'économie, c'est "passer la seconde".
|
|||||||
C'est produire. Transformer.
|
C'est produire. Transformer.
|
||||||
Le reste ? C'est de la comptabilité.
|
Le reste ? C'est de la comptabilité.
|
||||||
|
|
||||||
\[Bridge\]
|
|
||||||
\[Bass Line Drops\]
|
|
||||||
\[Pause\]
|
|
||||||
Notre monnaie-dette a un code génétique.
|
Notre monnaie-dette a un code génétique.
|
||||||
Elle programme le manque. Elle programme la course.
|
Elle programme le manque. Elle programme la course.
|
||||||
Mais le DU...
|
Mais le DU...
|
||||||
Le DU change le code source.
|
Le DU change le code source.
|
||||||
|
|
||||||
\[Outro\]
|
|
||||||
\[Fading Music\]
|
|
||||||
\[Whispered\]
|
|
||||||
Même accès pour tous.
|
Même accès pour tous.
|
||||||
Même pouvoir de création.
|
Même pouvoir de création.
|
||||||
Ce n'est plus "Que la dette soit".
|
Ce n'est plus "Que la dette soit".
|
||||||
C'est "Que l'équilibre soit".
|
C'est "Que l'équilibre soit".
|
||||||
\[Silence\]
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ order: 1
|
|||||||
readingTime: "15 min"
|
readingTime: "15 min"
|
||||||
---
|
---
|
||||||
|
|
||||||
\[Intro\]
|
|
||||||
Ce livre est un essai.
|
Ce livre est un essai.
|
||||||
Une proposition.
|
Une proposition.
|
||||||
Une intention.
|
Une intention.
|
||||||
@@ -13,16 +12,14 @@ Une invitation.
|
|||||||
(...)
|
(...)
|
||||||
Une façon.
|
Une façon.
|
||||||
|
|
||||||
\[bridge\]
|
Deux mille vingt-quatre j'écris tout l'été, ...
|
||||||
Deux mille vingt'-quatre j'écris tout l'été, ...
|
Deux mille vingt-cinq je mûris toute l'année, ...
|
||||||
Deux mille vingt'-cinq je mûris toute l'année, ...
|
Deux mille vingt-six la sortie... mmmmhh,
|
||||||
Deux mille vingt'-siss la sortie... mmmmhh,
|
|
||||||
Le temps pass
|
Le temps pass
|
||||||
Est-ce une menace ?
|
Est-ce une menace ?
|
||||||
|
|
||||||
\[Verse 1\]
|
|
||||||
Pour éviter tout quiproquo :
|
Pour éviter tout quiproquo :
|
||||||
Pour mieux zaimer le propos
|
Pour mieux aimer le propos
|
||||||
Ce n'est pas une théorie.
|
Ce n'est pas une théorie.
|
||||||
Pas d'u-niversalité.
|
Pas d'u-niversalité.
|
||||||
Loin s'en faut.
|
Loin s'en faut.
|
||||||
@@ -34,20 +31,17 @@ Civile et artistique
|
|||||||
Mais si ça reste à ton échelle... c'est symbolique.
|
Mais si ça reste à ton échelle... c'est symbolique.
|
||||||
Viser mon bassin de vie ? ça se complique.
|
Viser mon bassin de vie ? ça se complique.
|
||||||
|
|
||||||
\[Chorus\]
|
Ce livre n'est pas un guide,
|
||||||
Ce livre n'est pas un guiDe,
|
|
||||||
davantage un guit'.
|
davantage un guit'.
|
||||||
Ce n'est pas un Kit.
|
Ce n'est pas un kit.
|
||||||
Ça ne dit pas quoi faire lundi.
|
Ça ne dit pas quoi faire lundi.
|
||||||
|
|
||||||
\[Bridge\]
|
|
||||||
Tu veux une baguette magique ?
|
Tu veux une baguette magique ?
|
||||||
Supprimer la pression, l'oppression ? - Ce s'rait pas con...
|
Supprimer la pression, l'oppression ? - Ce s'rait pas con...
|
||||||
Si je ne résous pas mes problèmes d'aujourd'hui... à quoi bon ?
|
Si je ne résous pas mes problèmes d'aujourd'hui... à quoi bon ?
|
||||||
Naviguer dans le ciel des idées...
|
Naviguer dans le ciel des idées...
|
||||||
C'est fini !
|
C'est fini !
|
||||||
|
|
||||||
\[Verse 2\]
|
|
||||||
Créer une économie ?
|
Créer une économie ?
|
||||||
On en a déjà une. Tu veux décrocher la lune ?
|
On en a déjà une. Tu veux décrocher la lune ?
|
||||||
Elle couvre mes besoins vitaux. De facto.
|
Elle couvre mes besoins vitaux. De facto.
|
||||||
@@ -62,33 +56,29 @@ restez là sans mot dire,
|
|||||||
"restez des enfants !"...
|
"restez des enfants !"...
|
||||||
mmh, suspect et sans avenir.
|
mmh, suspect et sans avenir.
|
||||||
|
|
||||||
\[Bridge\]
|
|
||||||
Deux mille vingt-six. L'année des défis.
|
Deux mille vingt-six. L'année des défis.
|
||||||
Ne plus subir les agendas. Créer les nôtr'.
|
Ne plus subir les agendas. Créer les nôtr'.
|
||||||
On manque de repères ?... Entre autres, ...
|
On manque de repères ?... Entre autres, ...
|
||||||
Faut les trouver,...
|
Faut les trouver,...
|
||||||
En produisant, les inventer.
|
En produisant, les inventer.
|
||||||
|
|
||||||
\[Chorus\]
|
Ce livre n'est pas un guide,
|
||||||
Ce livre n'est pas un guiDe,
|
|
||||||
davantage un guit'.
|
davantage un guit'.
|
||||||
Ce n'est pas un Kit.
|
Ce n'est pas un kit.
|
||||||
Ça ne dit pas quoi faire lundi.
|
Ça ne dit pas quoi faire lundi.
|
||||||
|
|
||||||
\[Bridge 2\]
|
|
||||||
C'est un os à ronger.
|
C'est un os à ronger.
|
||||||
Une cartographie. Quelques boussoles.
|
Une cartographie. Quelques boussoles.
|
||||||
Dans une jungle à défricher.
|
Dans une jungle à défricher.
|
||||||
Ce n'est pas encore l'heure...
|
Ce n'est pas encore l'heure...
|
||||||
Du prêtà-porter.
|
Du prêt-à-porter.
|
||||||
A nous de tailler.
|
A nous de tailler.
|
||||||
|
|
||||||
\[outro\]
|
|
||||||
On tourne une page pour voir ?
|
On tourne une page pour voir ?
|
||||||
Décline le rôle de la bonne poire...
|
Décline le rôle de la bonne poire...
|
||||||
Je n'ai pas que l'espoir
|
Je n'ai pas que l'espoir
|
||||||
J'ai un pouvoir
|
J'ai un pouvoir
|
||||||
Tu as bien mieux que l'espoir,
|
Tu as bien mieux que l'espoir,
|
||||||
Nous - zavons un grand pouvoir.
|
Nous avons un grand pouvoir.
|
||||||
|
|
||||||
(whisper :) hey, on tourne une page ?
|
(whisper :) hey, on tourne une page ?
|
||||||
|
|||||||
@@ -5,17 +5,12 @@ order: 3
|
|||||||
readingTime: "8 min"
|
readingTime: "8 min"
|
||||||
---
|
---
|
||||||
|
|
||||||
\[Intro\]
|
|
||||||
(Piano Rhodes : accords jazzy)
|
|
||||||
(Basse : Ligne ronde et enveloppante)
|
|
||||||
|
|
||||||
Une économie du don ?
|
Une économie du don ?
|
||||||
Mais de quel don nous parlons ?
|
Mais de quel don nous parlons ?
|
||||||
Ce mariage fait peur. Il claque.
|
Ce mariage fait peur. Il claque.
|
||||||
Un oxymore, on l'apprend juste après l'bac.
|
Un oxymore, on l'apprend juste après l'bac.
|
||||||
Une contradiction pour l'esprit.
|
Une contradiction pour l'esprit.
|
||||||
|
|
||||||
\[Verse 1\]
|
|
||||||
On évacue tout de suite le spirituel.
|
On évacue tout de suite le spirituel.
|
||||||
Désolé pour le karma, désolé pour le ciel.
|
Désolé pour le karma, désolé pour le ciel.
|
||||||
Je ne parle pas du "centuple divin".
|
Je ne parle pas du "centuple divin".
|
||||||
@@ -25,7 +20,6 @@ Ici, c'est un geste. Juste un geste.
|
|||||||
Qui sert de base, qui sert de fondation,
|
Qui sert de base, qui sert de fondation,
|
||||||
À une autre forme de construction.
|
À une autre forme de construction.
|
||||||
|
|
||||||
\[Chorus\]
|
|
||||||
Ce n'est pas l'image d'Épinal, le don gratuit, le don idéal.
|
Ce n'est pas l'image d'Épinal, le don gratuit, le don idéal.
|
||||||
Marcel Mauss nous l'a dit, dans son essai radical.
|
Marcel Mauss nous l'a dit, dans son essai radical.
|
||||||
Ce n'est pas un cadeau, c'est un cycle vital.
|
Ce n'est pas un cadeau, c'est un cycle vital.
|
||||||
@@ -35,7 +29,6 @@ C'est un pacte, une tension, parfois même un combat.
|
|||||||
Si tu ne redonnes pas, si tu enfreins le protocole...
|
Si tu ne redonnes pas, si tu enfreins le protocole...
|
||||||
Ça ne pardonne pas.
|
Ça ne pardonne pas.
|
||||||
|
|
||||||
\[Verse 2\]
|
|
||||||
J'entends les rêves de brûler la monnaie.
|
J'entends les rêves de brûler la monnaie.
|
||||||
"Le troc", "la gratuité", "Mocica", le grand projet.
|
"Le troc", "la gratuité", "Mocica", le grand projet.
|
||||||
La monnaie serait le vice, la corruption mentale.
|
La monnaie serait le vice, la corruption mentale.
|
||||||
@@ -46,8 +39,6 @@ La monnaie-dette, celle qui nous tient, celle qui nous guette.
|
|||||||
Mais si la monnaie est libre ? Elle permet les équilibres.
|
Mais si la monnaie est libre ? Elle permet les équilibres.
|
||||||
Si elle devient notre outil ? Elle change le récit.
|
Si elle devient notre outil ? Elle change le récit.
|
||||||
|
|
||||||
\[Bridge\]
|
|
||||||
(Music strips down. Just Bass and Snare rimshots)
|
|
||||||
Le don qui se mesure, donne la mesure.
|
Le don qui se mesure, donne la mesure.
|
||||||
C'est quand tu donnes ton temps, ton énergie, ta sueur,
|
C'est quand tu donnes ton temps, ton énergie, ta sueur,
|
||||||
Que tu crées ton propre étalon de valeur.
|
Que tu crées ton propre étalon de valeur.
|
||||||
@@ -56,7 +47,6 @@ Puis silence. Le geste pose un nouveau décor.
|
|||||||
Le don — c'est pas une perte.
|
Le don — c'est pas une perte.
|
||||||
Le don — c'est le début d'un accord.
|
Le don — c'est le début d'un accord.
|
||||||
|
|
||||||
\[Chorus 2\]
|
|
||||||
Ce n'est pas l'image d'Épinal, le don gratuit, le don idéal.
|
Ce n'est pas l'image d'Épinal, le don gratuit, le don idéal.
|
||||||
Marcel Mauss nous l'a dit, dans son essai radical.
|
Marcel Mauss nous l'a dit, dans son essai radical.
|
||||||
Ce n'est pas un cadeau, c'est un cycle vital.
|
Ce n'est pas un cadeau, c'est un cycle vital.
|
||||||
@@ -64,7 +54,6 @@ Ce n'est pas un cadeau, c'est un cycle vital.
|
|||||||
Le don qui se mesure, donne la mesure.
|
Le don qui se mesure, donne la mesure.
|
||||||
Le don qui se mesure, donne la mesure.
|
Le don qui se mesure, donne la mesure.
|
||||||
|
|
||||||
\[Outro\]
|
|
||||||
De quel don nous parlons ?
|
De quel don nous parlons ?
|
||||||
...Celui qui construit.
|
...Celui qui construit.
|
||||||
Celui qui nous relie.
|
Celui qui nous relie.
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ readingTime: "35 min"
|
|||||||
|
|
||||||
Hymne à la monnaie libre
|
Hymne à la monnaie libre
|
||||||
|
|
||||||
\[Verse\]
|
|
||||||
Des cercles qui se croisent
|
Des cercles qui se croisent
|
||||||
Sans les regards qui toisent
|
Sans les regards qui toisent
|
||||||
Des poings qui se détendent
|
Des poings qui se détendent
|
||||||
@@ -18,7 +17,6 @@ Un futur qui s'écrit
|
|||||||
Un souffle tout petit
|
Un souffle tout petit
|
||||||
Pas de chaînes pour les pensées
|
Pas de chaînes pour les pensées
|
||||||
|
|
||||||
\[Chorus\]
|
|
||||||
Construire des vies
|
Construire des vies
|
||||||
Nos cœurs qui grossissent
|
Nos cœurs qui grossissent
|
||||||
Couvrir nos besoins
|
Couvrir nos besoins
|
||||||
@@ -34,7 +32,6 @@ Y consacrer nos vies
|
|||||||
Si tu en as la fibre
|
Si tu en as la fibre
|
||||||
C'est l'hymne à la monnaie libre
|
C'est l'hymne à la monnaie libre
|
||||||
|
|
||||||
\[Verse 2\]
|
|
||||||
Les jours se lèvent sur des rêves partagés
|
Les jours se lèvent sur des rêves partagés
|
||||||
Quelques champs pour les possibles
|
Quelques champs pour les possibles
|
||||||
Des ponts à imaginer
|
Des ponts à imaginer
|
||||||
@@ -43,7 +40,6 @@ Pas de trône
|
|||||||
Juste l'humanité
|
Juste l'humanité
|
||||||
Est-elle si pénible ?
|
Est-elle si pénible ?
|
||||||
|
|
||||||
\[Bridge\]
|
|
||||||
Ni maîtres ni esclaves
|
Ni maîtres ni esclaves
|
||||||
Juste un écho
|
Juste un écho
|
||||||
Des esprits qui dansent
|
Des esprits qui dansent
|
||||||
@@ -51,7 +47,6 @@ Dans des corps qui pensent
|
|||||||
Un chant nouveau
|
Un chant nouveau
|
||||||
Surmontent les entraves
|
Surmontent les entraves
|
||||||
|
|
||||||
\[Chorus\]
|
|
||||||
Construire des vies
|
Construire des vies
|
||||||
Nos cœurs qui grossissent
|
Nos cœurs qui grossissent
|
||||||
Couvrir nos besoins
|
Couvrir nos besoins
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ readingTime: "30 min"
|
|||||||
|
|
||||||
Hymne à la monnaie libre
|
Hymne à la monnaie libre
|
||||||
|
|
||||||
\[Verse\]
|
|
||||||
Des cercles qui se croisent
|
Des cercles qui se croisent
|
||||||
Sans les regards qui toisent
|
Sans les regards qui toisent
|
||||||
Des poings qui se détendent
|
Des poings qui se détendent
|
||||||
@@ -18,7 +17,6 @@ Un futur qui s'écrit
|
|||||||
Un souffle tout petit
|
Un souffle tout petit
|
||||||
Pas de chaînes pour les pensées
|
Pas de chaînes pour les pensées
|
||||||
|
|
||||||
\[Chorus\]
|
|
||||||
Construire des vies
|
Construire des vies
|
||||||
Nos cœurs qui grossissent
|
Nos cœurs qui grossissent
|
||||||
Couvrir nos besoins
|
Couvrir nos besoins
|
||||||
@@ -34,7 +32,6 @@ Y consacrer nos vies
|
|||||||
Si tu en as la fibre
|
Si tu en as la fibre
|
||||||
C'est l'hymne à la monnaie libre
|
C'est l'hymne à la monnaie libre
|
||||||
|
|
||||||
\[Verse 2\]
|
|
||||||
Les jours se lèvent sur des rêves partagés
|
Les jours se lèvent sur des rêves partagés
|
||||||
Quelques champs pour les possibles
|
Quelques champs pour les possibles
|
||||||
Des ponts à imaginer
|
Des ponts à imaginer
|
||||||
@@ -43,7 +40,6 @@ Pas de trône
|
|||||||
Juste l'humanité
|
Juste l'humanité
|
||||||
Est-elle si pénible ?
|
Est-elle si pénible ?
|
||||||
|
|
||||||
\[Bridge\]
|
|
||||||
Ni maîtres ni esclaves
|
Ni maîtres ni esclaves
|
||||||
Juste un écho
|
Juste un écho
|
||||||
Des esprits qui dansent
|
Des esprits qui dansent
|
||||||
@@ -51,7 +47,6 @@ Dans des corps qui pensent
|
|||||||
Un chant nouveau
|
Un chant nouveau
|
||||||
Surmontent les entraves
|
Surmontent les entraves
|
||||||
|
|
||||||
\[Chorus\]
|
|
||||||
Construire des vies
|
Construire des vies
|
||||||
Nos cœurs qui grossissent
|
Nos cœurs qui grossissent
|
||||||
Couvrir nos besoins
|
Couvrir nos besoins
|
||||||
|
|||||||
@@ -7,14 +7,9 @@ readingTime: "20 min"
|
|||||||
|
|
||||||
Ainsi soit-il
|
Ainsi soit-il
|
||||||
|
|
||||||
\[Intro\]
|
|
||||||
\[Vinyl Crackle Sound\]
|
|
||||||
\[Minimalist Piano Loop\]
|
|
||||||
Fiat...
|
Fiat...
|
||||||
Fiat Lux… Fiat Euro.
|
Fiat Lux… Fiat Euro.
|
||||||
|
|
||||||
\[Verse 1\]
|
|
||||||
\[Spoken Word, Calm and Clear\]
|
|
||||||
Fiat. Ce n'est pas une marque.
|
Fiat. Ce n'est pas une marque.
|
||||||
C'est du latin.
|
C'est du latin.
|
||||||
Ça veut dire : "Que cela soit".
|
Ça veut dire : "Que cela soit".
|
||||||
@@ -25,15 +20,11 @@ Un monopole déclaré.
|
|||||||
Une clé de voûte qui tient tout l'édifice.
|
Une clé de voûte qui tient tout l'édifice.
|
||||||
Si la clé casse... tout s'écroule.
|
Si la clé casse... tout s'écroule.
|
||||||
|
|
||||||
\[Chorus\]
|
|
||||||
\[Melodic Hook, Softly Sung\]
|
|
||||||
Mais la monnaie n'est pas la richesse.
|
Mais la monnaie n'est pas la richesse.
|
||||||
C'est juste le mètre... pas le tissu.
|
C'est juste le mètre... pas le tissu.
|
||||||
C'est le baromètre... pas le climat.
|
C'est le baromètre... pas le climat.
|
||||||
Ne confondons pas la carte et le territoire.
|
Ne confondons pas la carte et le territoire.
|
||||||
|
|
||||||
\[Verse 2\]
|
|
||||||
\[Rhythmic Spoken, Slightly Faster\]
|
|
||||||
Message aux pionniers :
|
Message aux pionniers :
|
||||||
Faire tourner la monnaie en rond, ce n'est pas créer.
|
Faire tourner la monnaie en rond, ce n'est pas créer.
|
||||||
Se faire des virements autour d'une table...
|
Se faire des virements autour d'une table...
|
||||||
@@ -45,19 +36,12 @@ L'économie, c'est "passer la seconde".
|
|||||||
C'est produire. Transformer.
|
C'est produire. Transformer.
|
||||||
Le reste ? C'est de la comptabilité.
|
Le reste ? C'est de la comptabilité.
|
||||||
|
|
||||||
\[Bridge\]
|
|
||||||
\[Bass Line Drops\]
|
|
||||||
\[Pause\]
|
|
||||||
Notre monnaie-dette a un code génétique.
|
Notre monnaie-dette a un code génétique.
|
||||||
Elle programme le manque. Elle programme la course.
|
Elle programme le manque. Elle programme la course.
|
||||||
Mais le DU...
|
Mais le DU...
|
||||||
Le DU change le code source.
|
Le DU change le code source.
|
||||||
|
|
||||||
\[Outro\]
|
|
||||||
\[Fading Music\]
|
|
||||||
\[Whispered\]
|
|
||||||
Même accès pour tous.
|
Même accès pour tous.
|
||||||
Même pouvoir de création.
|
Même pouvoir de création.
|
||||||
Ce n'est plus "Que la dette soit".
|
Ce n'est plus "Que la dette soit".
|
||||||
C'est "Que l'équilibre soit".
|
C'est "Que l'équilibre soit".
|
||||||
\[Silence\]
|
|
||||||
|
|||||||
26
public/images/shadoks/shadok-bird.svg
Normal file
26
public/images/shadoks/shadok-bird.svg
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 180 260" fill="none">
|
||||||
|
<!-- Body: round absurd bird -->
|
||||||
|
<ellipse cx="90" cy="100" rx="45" ry="40" fill="currentColor" opacity="0.85"/>
|
||||||
|
<!-- Head: tilted -->
|
||||||
|
<circle cx="130" cy="60" r="22" fill="currentColor" opacity="0.8"/>
|
||||||
|
<!-- Neck -->
|
||||||
|
<path d="M110 85 Q125 70 128 63" stroke="currentColor" stroke-width="8" stroke-linecap="round" opacity="0.7" fill="none"/>
|
||||||
|
<!-- Eye -->
|
||||||
|
<circle cx="136" cy="55" r="5" fill="currentColor" opacity="0.2"/>
|
||||||
|
<circle cx="137" cy="54" r="2" fill="currentColor" opacity="0.5"/>
|
||||||
|
<!-- Beak: long, absurd -->
|
||||||
|
<polygon points="150,58 175,50 152,65" fill="currentColor" opacity="0.6"/>
|
||||||
|
<!-- Long legs -->
|
||||||
|
<line x1="75" y1="138" x2="60" y2="230" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||||
|
<line x1="105" y1="138" x2="115" y2="230" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||||
|
<!-- Knees (knobby) -->
|
||||||
|
<circle cx="66" cy="190" r="4" fill="currentColor" opacity="0.4"/>
|
||||||
|
<circle cx="111" cy="190" r="4" fill="currentColor" opacity="0.4"/>
|
||||||
|
<!-- Feet -->
|
||||||
|
<path d="M60 230 L45 233 M60 230 L55 236 M60 230 L65 235" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" opacity="0.5"/>
|
||||||
|
<path d="M115 230 L100 233 M115 230 L110 236 M115 230 L120 235" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" opacity="0.5"/>
|
||||||
|
<!-- Tail feathers -->
|
||||||
|
<path d="M48 95 Q20 80 15 65" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.5" fill="none"/>
|
||||||
|
<path d="M48 100 Q22 92 10 85" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4" fill="none"/>
|
||||||
|
<path d="M48 105 Q25 102 12 100" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.3" fill="none"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.8 KiB |
14
public/images/shadoks/shadok-blob.svg
Normal file
14
public/images/shadoks/shadok-blob.svg
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 180" fill="none">
|
||||||
|
<!-- Amorphous blob shape -->
|
||||||
|
<path d="M60 90 Q30 50 70 30 Q110 10 140 40 Q180 60 170 100 Q165 140 130 155 Q90 170 55 145 Q25 125 60 90Z" fill="currentColor" opacity="0.12"/>
|
||||||
|
<path d="M60 90 Q30 50 70 30 Q110 10 140 40 Q180 60 170 100 Q165 140 130 155 Q90 170 55 145 Q25 125 60 90Z" stroke="currentColor" stroke-width="1.5" opacity="0.2"/>
|
||||||
|
<!-- Inner texture -->
|
||||||
|
<circle cx="100" cy="80" r="8" fill="currentColor" opacity="0.08"/>
|
||||||
|
<circle cx="120" cy="110" r="6" fill="currentColor" opacity="0.06"/>
|
||||||
|
<circle cx="80" cy="105" r="5" fill="currentColor" opacity="0.07"/>
|
||||||
|
<!-- Tiny eyes (personality) -->
|
||||||
|
<circle cx="95" cy="72" r="3" fill="currentColor" opacity="0.3"/>
|
||||||
|
<circle cx="108" cy="70" r="3" fill="currentColor" opacity="0.3"/>
|
||||||
|
<circle cx="96" cy="71" r="1.2" fill="currentColor" opacity="0.5"/>
|
||||||
|
<circle cx="109" cy="69" r="1.2" fill="currentColor" opacity="0.5"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 977 B |
45
public/images/shadoks/shadok-pattern.svg
Normal file
45
public/images/shadoks/shadok-pattern.svg
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 80" fill="none">
|
||||||
|
<!-- Repeating mini-shadok pattern -->
|
||||||
|
<!-- Shadok 1 -->
|
||||||
|
<g transform="translate(20,10)">
|
||||||
|
<ellipse cx="15" cy="25" rx="12" ry="14" fill="currentColor" opacity="0.08"/>
|
||||||
|
<circle cx="15" cy="10" r="7" fill="currentColor" opacity="0.06"/>
|
||||||
|
<line x1="10" y1="38" x2="8" y2="55" stroke="currentColor" stroke-width="1.5" opacity="0.06"/>
|
||||||
|
<line x1="20" y1="38" x2="22" y2="55" stroke="currentColor" stroke-width="1.5" opacity="0.06"/>
|
||||||
|
</g>
|
||||||
|
<!-- Shadok 2 -->
|
||||||
|
<g transform="translate(80,15)">
|
||||||
|
<ellipse cx="15" cy="22" rx="10" ry="12" fill="currentColor" opacity="0.06"/>
|
||||||
|
<circle cx="15" cy="8" r="6" fill="currentColor" opacity="0.05"/>
|
||||||
|
<line x1="10" y1="33" x2="8" y2="48" stroke="currentColor" stroke-width="1.5" opacity="0.05"/>
|
||||||
|
<line x1="20" y1="33" x2="22" y2="48" stroke="currentColor" stroke-width="1.5" opacity="0.05"/>
|
||||||
|
</g>
|
||||||
|
<!-- Shadok 3 -->
|
||||||
|
<g transform="translate(140,8)">
|
||||||
|
<ellipse cx="15" cy="25" rx="11" ry="13" fill="currentColor" opacity="0.07"/>
|
||||||
|
<circle cx="15" cy="10" r="6.5" fill="currentColor" opacity="0.06"/>
|
||||||
|
<line x1="10" y1="37" x2="7" y2="54" stroke="currentColor" stroke-width="1.5" opacity="0.06"/>
|
||||||
|
<line x1="20" y1="37" x2="23" y2="54" stroke="currentColor" stroke-width="1.5" opacity="0.06"/>
|
||||||
|
</g>
|
||||||
|
<!-- Shadok 4 -->
|
||||||
|
<g transform="translate(210,18)">
|
||||||
|
<ellipse cx="15" cy="20" rx="10" ry="11" fill="currentColor" opacity="0.05"/>
|
||||||
|
<circle cx="15" cy="7" r="5.5" fill="currentColor" opacity="0.04"/>
|
||||||
|
<line x1="10" y1="30" x2="9" y2="44" stroke="currentColor" stroke-width="1.5" opacity="0.04"/>
|
||||||
|
<line x1="20" y1="30" x2="21" y2="44" stroke="currentColor" stroke-width="1.5" opacity="0.04"/>
|
||||||
|
</g>
|
||||||
|
<!-- Shadok 5 -->
|
||||||
|
<g transform="translate(270,12)">
|
||||||
|
<ellipse cx="15" cy="24" rx="12" ry="14" fill="currentColor" opacity="0.07"/>
|
||||||
|
<circle cx="15" cy="9" r="7" fill="currentColor" opacity="0.06"/>
|
||||||
|
<line x1="10" y1="37" x2="7" y2="55" stroke="currentColor" stroke-width="1.5" opacity="0.06"/>
|
||||||
|
<line x1="20" y1="37" x2="23" y2="55" stroke="currentColor" stroke-width="1.5" opacity="0.06"/>
|
||||||
|
</g>
|
||||||
|
<!-- Shadok 6 -->
|
||||||
|
<g transform="translate(340,16)">
|
||||||
|
<ellipse cx="15" cy="22" rx="10" ry="12" fill="currentColor" opacity="0.06"/>
|
||||||
|
<circle cx="15" cy="8" r="6" fill="currentColor" opacity="0.05"/>
|
||||||
|
<line x1="10" y1="33" x2="8" y2="48" stroke="currentColor" stroke-width="1.5" opacity="0.05"/>
|
||||||
|
<line x1="20" y1="33" x2="22" y2="48" stroke="currentColor" stroke-width="1.5" opacity="0.05"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.5 KiB |
17
public/images/shadoks/shadok-planet.svg
Normal file
17
public/images/shadoks/shadok-planet.svg
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" fill="none">
|
||||||
|
<!-- Planet body -->
|
||||||
|
<circle cx="100" cy="100" r="70" fill="currentColor" opacity="0.15"/>
|
||||||
|
<circle cx="100" cy="100" r="70" stroke="currentColor" stroke-width="2" opacity="0.3"/>
|
||||||
|
<!-- Craters -->
|
||||||
|
<circle cx="80" cy="75" r="15" fill="currentColor" opacity="0.08"/>
|
||||||
|
<circle cx="120" cy="110" r="20" fill="currentColor" opacity="0.06"/>
|
||||||
|
<circle cx="90" cy="130" r="10" fill="currentColor" opacity="0.1"/>
|
||||||
|
<!-- Ring / orbit -->
|
||||||
|
<ellipse cx="100" cy="100" rx="95" ry="25" stroke="currentColor" stroke-width="1.5" opacity="0.2" transform="rotate(-20 100 100)"/>
|
||||||
|
<!-- Small moons -->
|
||||||
|
<circle cx="30" cy="50" r="8" fill="currentColor" opacity="0.25"/>
|
||||||
|
<circle cx="175" cy="140" r="5" fill="currentColor" opacity="0.2"/>
|
||||||
|
<!-- Surface features -->
|
||||||
|
<path d="M65 90 Q75 85 85 90" stroke="currentColor" stroke-width="1.5" opacity="0.15" fill="none"/>
|
||||||
|
<path d="M105 120 Q115 115 125 118" stroke="currentColor" stroke-width="1.5" opacity="0.12" fill="none"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.0 KiB |
24
public/images/shadoks/shadok-pumper.svg
Normal file
24
public/images/shadoks/shadok-pumper.svg
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 240" fill="none">
|
||||||
|
<!-- Body: ovoid shape -->
|
||||||
|
<ellipse cx="100" cy="130" rx="55" ry="65" fill="currentColor" opacity="0.9"/>
|
||||||
|
<!-- Head: smaller oval on top -->
|
||||||
|
<ellipse cx="100" cy="60" rx="30" ry="28" fill="currentColor" opacity="0.85"/>
|
||||||
|
<!-- Eyes -->
|
||||||
|
<circle cx="88" cy="54" r="6" fill="currentColor" opacity="0.2"/>
|
||||||
|
<circle cx="112" cy="54" r="6" fill="currentColor" opacity="0.2"/>
|
||||||
|
<circle cx="90" cy="53" r="2.5" fill="currentColor" opacity="0.5"/>
|
||||||
|
<circle cx="114" cy="53" r="2.5" fill="currentColor" opacity="0.5"/>
|
||||||
|
<!-- Beak -->
|
||||||
|
<polygon points="100,68 115,78 85,78" fill="currentColor" opacity="0.6"/>
|
||||||
|
<!-- Legs -->
|
||||||
|
<line x1="80" y1="192" x2="70" y2="230" stroke="currentColor" stroke-width="4" stroke-linecap="round" opacity="0.7"/>
|
||||||
|
<line x1="120" y1="192" x2="130" y2="230" stroke="currentColor" stroke-width="4" stroke-linecap="round" opacity="0.7"/>
|
||||||
|
<!-- Feet -->
|
||||||
|
<line x1="70" y1="230" x2="55" y2="232" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.5"/>
|
||||||
|
<line x1="130" y1="230" x2="145" y2="232" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.5"/>
|
||||||
|
<!-- Pump handle -->
|
||||||
|
<line x1="155" y1="110" x2="190" y2="90" stroke="currentColor" stroke-width="4" stroke-linecap="round" opacity="0.6"/>
|
||||||
|
<line x1="190" y1="90" x2="190" y2="120" stroke="currentColor" stroke-width="4" stroke-linecap="round" opacity="0.6"/>
|
||||||
|
<!-- Pump body -->
|
||||||
|
<rect x="180" y="118" width="18" height="40" rx="3" fill="currentColor" opacity="0.4"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.6 KiB |
@@ -20,9 +20,10 @@ export default defineConfig({
|
|||||||
presetWebFonts({
|
presetWebFonts({
|
||||||
provider: 'bunny',
|
provider: 'bunny',
|
||||||
fonts: {
|
fonts: {
|
||||||
display: 'Syne:400,500,600,700,800',
|
display: 'Outfit:400,500,600,700,800',
|
||||||
sans: 'Space Grotesk:300,400,500,600,700',
|
sans: 'Inter:300,400,500,600,700',
|
||||||
mono: 'JetBrains Mono:400,500,700',
|
mono: 'JetBrains Mono:400,500,700',
|
||||||
|
calligraphy: 'Playfair Display:400,700',
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
@@ -33,47 +34,47 @@ export default defineConfig({
|
|||||||
theme: {
|
theme: {
|
||||||
colors: {
|
colors: {
|
||||||
primary: {
|
primary: {
|
||||||
DEFAULT: 'hsl(12, 76%, 48%)',
|
DEFAULT: 'hsl(var(--color-primary))',
|
||||||
50: 'hsl(12, 76%, 95%)',
|
50: 'hsl(18, 80%, 95%)',
|
||||||
100: 'hsl(12, 76%, 88%)',
|
100: 'hsl(18, 80%, 88%)',
|
||||||
200: 'hsl(12, 76%, 76%)',
|
200: 'hsl(18, 80%, 76%)',
|
||||||
300: 'hsl(12, 76%, 64%)',
|
300: 'hsl(18, 80%, 64%)',
|
||||||
400: 'hsl(12, 76%, 56%)',
|
400: 'hsl(18, 80%, 56%)',
|
||||||
500: 'hsl(12, 76%, 48%)',
|
500: 'hsl(var(--color-primary))',
|
||||||
600: 'hsl(12, 76%, 40%)',
|
600: 'hsl(18, 80%, 38%)',
|
||||||
700: 'hsl(12, 76%, 33%)',
|
700: 'hsl(18, 80%, 30%)',
|
||||||
800: 'hsl(12, 76%, 26%)',
|
800: 'hsl(18, 80%, 24%)',
|
||||||
900: 'hsl(12, 76%, 18%)',
|
900: 'hsl(18, 80%, 16%)',
|
||||||
},
|
},
|
||||||
accent: {
|
accent: {
|
||||||
DEFAULT: 'hsl(36, 80%, 52%)',
|
DEFAULT: 'hsl(var(--color-accent))',
|
||||||
50: 'hsl(36, 80%, 95%)',
|
50: 'hsl(32, 85%, 95%)',
|
||||||
100: 'hsl(36, 80%, 88%)',
|
100: 'hsl(32, 85%, 88%)',
|
||||||
200: 'hsl(36, 80%, 76%)',
|
200: 'hsl(32, 85%, 76%)',
|
||||||
300: 'hsl(36, 80%, 66%)',
|
300: 'hsl(32, 85%, 66%)',
|
||||||
400: 'hsl(36, 80%, 58%)',
|
400: 'hsl(32, 85%, 58%)',
|
||||||
500: 'hsl(36, 80%, 52%)',
|
500: 'hsl(var(--color-accent))',
|
||||||
600: 'hsl(36, 80%, 44%)',
|
600: 'hsl(32, 85%, 42%)',
|
||||||
700: 'hsl(36, 80%, 36%)',
|
700: 'hsl(32, 85%, 34%)',
|
||||||
800: 'hsl(36, 80%, 28%)',
|
800: 'hsl(32, 85%, 26%)',
|
||||||
900: 'hsl(36, 80%, 20%)',
|
900: 'hsl(32, 85%, 18%)',
|
||||||
},
|
},
|
||||||
surface: {
|
surface: {
|
||||||
DEFAULT: 'hsl(20, 8%, 8%)',
|
DEFAULT: 'hsl(var(--color-surface))',
|
||||||
50: 'hsl(20, 8%, 22%)',
|
50: 'hsl(16, 12%, 22%)',
|
||||||
100: 'hsl(20, 8%, 18%)',
|
100: 'hsl(16, 12%, 18%)',
|
||||||
200: 'hsl(20, 8%, 13%)',
|
200: 'hsl(16, 12%, 13%)',
|
||||||
300: 'hsl(20, 8%, 10%)',
|
300: 'hsl(16, 12%, 10%)',
|
||||||
400: 'hsl(20, 8%, 8%)',
|
400: 'hsl(var(--color-surface))',
|
||||||
500: 'hsl(20, 8%, 6%)',
|
500: 'hsl(16, 12%, 6%)',
|
||||||
600: 'hsl(20, 8%, 4%)',
|
600: 'hsl(16, 12%, 4%)',
|
||||||
bg: 'hsl(20, 8%, 3.5%)',
|
bg: 'hsl(var(--color-bg))',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
shortcuts: {
|
shortcuts: {
|
||||||
'btn-primary': 'inline-flex items-center justify-center px-6 py-3 rounded-lg bg-primary text-white font-display font-semibold tracking-wide transition-all duration-200 hover:bg-primary-600 hover:scale-105 active:scale-95',
|
'btn-primary': 'inline-flex items-center justify-center px-6 py-3 rounded-lg bg-primary text-white font-display font-semibold tracking-wide border-none transition-all duration-200 hover:bg-primary-600 hover:scale-105 active:scale-95',
|
||||||
'btn-accent': 'inline-flex items-center justify-center px-6 py-3 rounded-lg bg-accent text-surface-bg font-display font-semibold tracking-wide transition-all duration-200 hover:bg-accent-600 hover:scale-105 active:scale-95',
|
'btn-accent': 'inline-flex items-center justify-center px-6 py-3 rounded-lg bg-accent text-surface-bg font-display font-semibold tracking-wide border-none transition-all duration-200 hover:bg-accent-600 hover:scale-105 active:scale-95',
|
||||||
'btn-ghost': 'inline-flex items-center justify-center px-4 py-2 rounded-lg border-none text-white/70 font-sans transition-all duration-200 hover:bg-white/10 hover:text-white',
|
'btn-ghost': 'inline-flex items-center justify-center px-4 py-2 rounded-lg border-none text-white/70 font-sans transition-all duration-200 hover:bg-white/10 hover:text-white',
|
||||||
'card-surface': 'rounded-xl bg-surface border border-white/8 p-6 transition-all duration-300 hover:border-primary/30 hover:shadow-lg hover:shadow-primary/5',
|
'card-surface': 'rounded-xl bg-surface border border-white/8 p-6 transition-all duration-300 hover:border-primary/30 hover:shadow-lg hover:shadow-primary/5',
|
||||||
'text-gradient': 'bg-gradient-to-r from-primary-300 to-accent bg-clip-text text-transparent',
|
'text-gradient': 'bg-gradient-to-r from-primary-300 to-accent bg-clip-text text-transparent',
|
||||||
|
|||||||
Reference in New Issue
Block a user