Simplification de l'aventure
This commit is contained in:
54
config.ts
54
config.ts
@@ -1,54 +0,0 @@
|
|||||||
import { defineCollection, z } from "astro:content";
|
|
||||||
|
|
||||||
// Collection pour le Journal de bord de la campagne JDR
|
|
||||||
const journalCollection = defineCollection({
|
|
||||||
type: "content",
|
|
||||||
schema: z.object({
|
|
||||||
title: z.string(),
|
|
||||||
author: z.string(),
|
|
||||||
publishDate: z.date(),
|
|
||||||
tags: z.array(z.string()),
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
// Collection pour les logs de développement et de réflexion
|
|
||||||
const logsCollection = defineCollection({
|
|
||||||
type: "content",
|
|
||||||
schema: z.object({
|
|
||||||
title: z.string(),
|
|
||||||
publishDate: z.date(),
|
|
||||||
tags: z.array(z.string()),
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
// Collection pour le "Codex de la Substance" (apprentissage)
|
|
||||||
const codexCollection = defineCollection({
|
|
||||||
type: "content",
|
|
||||||
schema: z.object({
|
|
||||||
title: z.string(),
|
|
||||||
subtitle: z.string(),
|
|
||||||
publishDate: z.date(),
|
|
||||||
tags: z.array(z.string()),
|
|
||||||
concept2D: z.string(),
|
|
||||||
mecanique: z.string(),
|
|
||||||
vision3D: z.string(),
|
|
||||||
status: z.enum(["Acquis", "En cours", "À explorer"]),
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
const bujoCollection = defineCollection({
|
|
||||||
type: 'content',
|
|
||||||
schema: z.object({
|
|
||||||
title: z.string(),
|
|
||||||
publishDate: z.date(),
|
|
||||||
tags: z.array(z.string()),
|
|
||||||
period: z.string().optional(),
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const collections = {
|
|
||||||
journal: journalCollection,
|
|
||||||
logs: logsCollection,
|
|
||||||
codex: codexCollection,
|
|
||||||
bujo: bujoCollection,
|
|
||||||
};
|
|
||||||
8
package-lock.json
generated
8
package-lock.json
generated
@@ -10,7 +10,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/mdx": "^4.3.13",
|
"@astrojs/mdx": "^4.3.13",
|
||||||
"@tailwindcss/vite": "^4.1.18",
|
"@tailwindcss/vite": "^4.1.18",
|
||||||
"astro": "^5.16.15",
|
"astro": "^5.17.1",
|
||||||
"tailwindcss": "^4.1.18"
|
"tailwindcss": "^4.1.18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -2057,9 +2057,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/astro": {
|
"node_modules/astro": {
|
||||||
"version": "5.16.15",
|
"version": "5.17.1",
|
||||||
"resolved": "https://registry.npmjs.org/astro/-/astro-5.16.15.tgz",
|
"resolved": "https://registry.npmjs.org/astro/-/astro-5.17.1.tgz",
|
||||||
"integrity": "sha512-+X1Z0NTi2pa5a0Te6h77Dgc44fYj63j1yx6+39Nvg05lExajxSq7b1Uj/gtY45zoum8fD0+h0nak+DnHighs3A==",
|
"integrity": "sha512-oD3tlxTaVWGq/Wfbqk6gxzVRz98xa/rYlpe+gU2jXJMSD01k6sEDL01ZlT8mVSYB/rMgnvIOfiQQ3BbLdN237A==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/compiler": "^2.13.0",
|
"@astrojs/compiler": "^2.13.0",
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/mdx": "^4.3.13",
|
"@astrojs/mdx": "^4.3.13",
|
||||||
"@tailwindcss/vite": "^4.1.18",
|
"@tailwindcss/vite": "^4.1.18",
|
||||||
"astro": "^5.16.15",
|
"astro": "^5.17.1",
|
||||||
"tailwindcss": "^4.1.18"
|
"tailwindcss": "^4.1.18"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,202 +1,190 @@
|
|||||||
---
|
---
|
||||||
import type { CollectionEntry } from 'astro:content';
|
import type { CollectionEntry } from "astro:content";
|
||||||
import GoldButton from './ui/GoldButton.astro';
|
import GoldButton from "./ui/GoldButton.astro";
|
||||||
import CodexCard from './ui/CodexCard.astro';
|
import CodexCard from "./ui/CodexCard.astro";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
posts: CollectionEntry<'journal' | 'logs' | 'codex'>[];
|
posts: CollectionEntry<"journal" | "logs" | "codex">[];
|
||||||
tags: string[];
|
tags: string[];
|
||||||
basePath: 'journal' | 'logs' | 'codex';
|
basePath: "journal" | "logs" | "codex";
|
||||||
}
|
}
|
||||||
|
|
||||||
const { posts, tags, basePath } = Astro.props;
|
const { posts, tags, basePath } = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<div id="content-search-component">
|
<div id="content-search-component">
|
||||||
<div class="search-wrapper">
|
<div class="search-wrapper">
|
||||||
<input type="search" id="search-input" placeholder="Rechercher..." />
|
<input
|
||||||
</div>
|
type="search"
|
||||||
|
id="search-input"
|
||||||
|
placeholder="Rechercher dans le grimoire..."
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="tag-filters" class="tags-container">
|
<div id="tag-filters" class="tags-container">
|
||||||
<button class="tag-btn active" data-tag="all">Toutes</button>
|
<button class="tag-btn active" data-tag="all">Toutes</button>
|
||||||
{
|
{
|
||||||
tags.map((tag) => (
|
tags.map((tag) => (
|
||||||
<button class="tag-btn" data-tag={tag}>{tag}</button>
|
<button class="tag-btn" data-tag={tag}>
|
||||||
))
|
{tag}
|
||||||
}
|
</button>
|
||||||
</div>
|
))
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="search-results" class="card-grid">
|
<div id="search-results" class="card-grid">
|
||||||
{basePath === 'codex' ? (
|
{
|
||||||
posts.map((post) => (
|
basePath === "codex"
|
||||||
<CodexCard entry={post as CollectionEntry<'codex'>} />
|
? posts.map((post) => (
|
||||||
))
|
<CodexCard entry={post as CollectionEntry<"codex">} />
|
||||||
) : (
|
))
|
||||||
posts.map((post) => (
|
: posts.map((post) => (
|
||||||
<GoldButton
|
<GoldButton
|
||||||
href={`/${basePath}/${post.slug}/`}
|
href={`/${basePath}/${post.id}/`}
|
||||||
title={post.data.title}
|
title={post.data.title}
|
||||||
body={`Publié le ${new Date(post.data.publishDate).toLocaleDateString('fr-FR')}`}
|
body={`Publié le ${new Date(post.data.publishDate).toLocaleDateString("fr-FR")}`}
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
)
|
}
|
||||||
}
|
</div>
|
||||||
</div>
|
|
||||||
<p id="no-results" class="no-results-message" style="display: none;">
|
<p id="no-results" class="no-results-message" style="display: none;">
|
||||||
Aucun document ne correspond à votre recherche.
|
Aucun parchemin ne correspond à votre recherche.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<div
|
||||||
|
id="search-data-bridge"
|
||||||
|
data-posts={JSON.stringify(posts)}
|
||||||
|
data-basepath={basePath}
|
||||||
|
style="display: none;"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script define:vars={{ posts, tags, basePath }}>
|
<script>
|
||||||
const searchInput = document.getElementById('search-input');
|
// On récupère les données via le DOM pour que l'éditeur reste coloré
|
||||||
const resultsContainer = document.getElementById('search-results');
|
const bridge = document.getElementById("search-data-bridge");
|
||||||
const noResultsMessage = document.getElementById('no-results');
|
const posts = JSON.parse(bridge.dataset.posts);
|
||||||
const tagFiltersContainer = document.getElementById('tag-filters');
|
const basePath = bridge.dataset.basepath;
|
||||||
|
|
||||||
let currentQuery = '';
|
const searchInput = document.body.querySelector("#search-input");
|
||||||
let activeTag = 'all';
|
const resultsContainer = document.body.querySelector("#search-results");
|
||||||
|
const noResultsMessage = document.body.querySelector("#no-results");
|
||||||
|
const tagFiltersContainer = document.body.querySelector("#tag-filters");
|
||||||
|
|
||||||
// --- Fonctions Utilitaires ---
|
let currentQuery = "";
|
||||||
// Fonction pour normaliser le texte (enlever les accents, mettre en minuscule)
|
let activeTag = "all";
|
||||||
function normalizeText(text) {
|
|
||||||
return text
|
|
||||||
.toLowerCase()
|
|
||||||
.normalize('NFD')
|
|
||||||
.replace(/[\u0300-\u036f]/g, '');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fonction pour créer le HTML d'une carte Codex
|
function normalizeText(text) {
|
||||||
function createCodexCardHTML(post) {
|
if (!text) return "";
|
||||||
const statusClass = post.data.status.toLowerCase().replace(' ', '-');
|
return text
|
||||||
return `
|
.toLowerCase()
|
||||||
<a href="/codex/${post.slug}" class="codex-card">
|
.normalize("NFD")
|
||||||
<div class="card-header">
|
.replace(/[\u0300-\u036f]/g, "");
|
||||||
<div class="card-title">${post.data.title}</div>
|
}
|
||||||
<div class="card-subtitle">${post.data.subtitle}</div>
|
|
||||||
<span class="status status-${statusClass}">${post.data.status}</span>
|
|
||||||
</div>
|
|
||||||
<div class="skill-section">
|
|
||||||
<div class="skill-header">Compétence</div>
|
|
||||||
<p class="skill-content">${post.data.mecanique}</p>
|
|
||||||
<div class="skill-header">Application Concrète</div>
|
|
||||||
<p class="skill-content">${post.data.vision3D}</p>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fonction pour créer le HTML d'un GoldButton
|
function createCodexCardHTML(post) {
|
||||||
function createGoldButtonHTML(post) {
|
const statusClass = (post.data.status || "draft")
|
||||||
return `
|
.toLowerCase()
|
||||||
<a href="/${basePath}/${post.slug}/" class="gold-button">
|
.replace(" ", "-");
|
||||||
<div class="title">${post.data.title}</div>
|
return `
|
||||||
<p class="body">Publié le ${new Date(post.data.publishDate).toLocaleDateString('fr-FR')}</p>
|
<a href="/codex/${post.id}" class="codex-card">
|
||||||
</a>
|
<div class="card-header">
|
||||||
`;
|
<div class="card-title">${post.data.title}</div>
|
||||||
}
|
<div class="card-subtitle">${post.data.subtitle || ""}</div>
|
||||||
|
<span class="status status-${statusClass}">${post.data.status || "Inconnu"}</span>
|
||||||
|
</div>
|
||||||
|
<div class="skill-section">
|
||||||
|
<div class="skill-header">Compétence</div>
|
||||||
|
<p class="skill-content">${post.data.mecanique || "En cours..."}</p>
|
||||||
|
<div class="skill-header">Application</div>
|
||||||
|
<p class="skill-content">${post.data.vision3D || "À venir..."}</p>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
// Fonction pour mettre à jour l'affichage
|
function createGoldButtonHTML(post) {
|
||||||
function renderResults() {
|
const dateStr = new Date(post.data.publishDate).toLocaleDateString(
|
||||||
let filteredPosts = posts;
|
"fr-FR",
|
||||||
|
);
|
||||||
// 1. Filtrer par balise active
|
return `
|
||||||
if (activeTag !== 'all') {
|
<a href="/${basePath}/${post.id}/" class="gold-button">
|
||||||
// Pour le codex, on filtre par 'domain', sinon par 'tags'
|
<div class="title">${post.data.title}</div>
|
||||||
const filterKey = basePath === 'codex' ? 'domain' : 'tags';
|
<p class="body">Publié le ${dateStr}</p>
|
||||||
filteredPosts = filteredPosts.filter(post => {
|
</a>
|
||||||
const values = post.data[filterKey];
|
`;
|
||||||
if (Array.isArray(values)) {
|
}
|
||||||
return values.includes(activeTag);
|
|
||||||
}
|
|
||||||
return values === activeTag; // Gère le cas où 'domain' est une simple chaîne
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. Filtrer par recherche textuelle
|
|
||||||
if (currentQuery) {
|
|
||||||
filteredPosts = filteredPosts.filter(post => normalizeText(post.data.title).includes(currentQuery));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Mettre à jour le DOM
|
|
||||||
noResultsMessage.style.display = filteredPosts.length === 0 ? 'block' : 'none';
|
|
||||||
|
|
||||||
const resultsHTML = filteredPosts.map(post =>
|
|
||||||
basePath === 'codex' ? createCodexCardHTML(post) : createGoldButtonHTML(post)
|
|
||||||
).join('');
|
|
||||||
resultsContainer.innerHTML = resultsHTML;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- Écouteurs d'événements ---
|
|
||||||
searchInput.addEventListener('input', (e) => {
|
|
||||||
currentQuery = normalizeText(e.target.value);
|
|
||||||
renderResults();
|
|
||||||
});
|
|
||||||
|
|
||||||
tagFiltersContainer.addEventListener('click', (e) => {
|
|
||||||
if (!e.target.matches('.tag-btn')) return;
|
|
||||||
|
|
||||||
// Mettre à jour le style du bouton actif
|
|
||||||
tagFiltersContainer.querySelector('.active').classList.remove('active');
|
|
||||||
e.target.classList.add('active');
|
|
||||||
|
|
||||||
activeTag = e.target.dataset.tag;
|
|
||||||
renderResults();
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
/* Styles pour les filtres de balises */
|
/* Conteneur des tags : centrage et espacement */
|
||||||
.tags-container {
|
.tags-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: 0.75rem;
|
gap: 0.6rem;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
margin-bottom: 3rem;
|
margin-bottom: 3rem;
|
||||||
}
|
width: 100%;
|
||||||
.search-wrapper {
|
}
|
||||||
margin-bottom: 3rem;
|
|
||||||
text-align: center;
|
/* Le bouton de tag : on force les styles pour contrer Tailwind */
|
||||||
}
|
.tag-btn {
|
||||||
#search-input {
|
all: unset; /* On réinitialise les styles par défaut du navigateur */
|
||||||
width: 100%;
|
display: inline-block;
|
||||||
max-width: 400px;
|
cursor: pointer;
|
||||||
padding: 0.75rem 1rem;
|
background-color: #f3ece0;
|
||||||
font-size: 1.1rem;
|
color: #4a4130;
|
||||||
font-family: 'EB Garamond', serif;
|
padding: 0.4rem 1.2rem;
|
||||||
border: 2px solid #dcd0b9;
|
border-radius: 9999px; /* Forme pilule parfaite */
|
||||||
border-radius: 8px;
|
font-family: "Cinzel", serif;
|
||||||
background-color: rgba(253, 246, 232, 0.8);
|
font-size: 0.85rem;
|
||||||
color: #4a4130;
|
border: 1px solid #dcd0b9;
|
||||||
}
|
transition: all 0.2s ease-in-out;
|
||||||
#search-input:focus {
|
text-align: center;
|
||||||
outline: none;
|
}
|
||||||
border-color: #c89b3c;
|
|
||||||
box-shadow: 0 0 10px rgba(200, 155, 60, 0.4);
|
/* État survolé */
|
||||||
}
|
.tag-btn:hover {
|
||||||
.no-results-message {
|
background-color: #fdf6e8;
|
||||||
text-align: center;
|
border-color: #c89b3c;
|
||||||
font-style: italic;
|
color: #c89b3c;
|
||||||
font-size: 1.2rem;
|
transform: translateY(-1px);
|
||||||
color: #4a4130;
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
||||||
}
|
}
|
||||||
.tag-btn {
|
|
||||||
background-color: transparent;
|
/* État actif (celui qui est doré sur ton image 2) */
|
||||||
color: #b8860b;
|
.tag-btn.active {
|
||||||
padding: 0.4rem 1rem;
|
background-color: #c89b3c !important;
|
||||||
border-radius: 15px;
|
color: #ffffff !important;
|
||||||
font-size: 0.9rem;
|
border-color: #b8860b !important;
|
||||||
font-family: 'Cinzel', serif;
|
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.2);
|
||||||
border: 1px solid rgba(200, 155, 60, 0.5);
|
}
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.2s ease;
|
/* Centrage de la barre de recherche */
|
||||||
}
|
.search-wrapper {
|
||||||
.tag-btn:hover {
|
display: flex;
|
||||||
background-color: rgba(200, 155, 60, 0.2);
|
justify-content: center;
|
||||||
border-color: #c89b3c;
|
margin-bottom: 2.5rem;
|
||||||
}
|
width: 100%;
|
||||||
.tag-btn.active {
|
}
|
||||||
background-color: #c89b3c;
|
|
||||||
color: #2c2a24;
|
#search-input {
|
||||||
border-color: #c89b3c;
|
width: 100%;
|
||||||
}
|
max-width: 450px;
|
||||||
</style>
|
padding: 0.75rem 1.2rem;
|
||||||
|
border: 1px solid #dcd0b9;
|
||||||
|
border-radius: 8px;
|
||||||
|
background-color: rgba(253, 246, 232, 0.9);
|
||||||
|
font-family: "EB Garamond", serif;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
color: #4a4130;
|
||||||
|
outline: none;
|
||||||
|
transition: border-color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
#search-input:focus {
|
||||||
|
border-color: #c89b3c;
|
||||||
|
box-shadow: 0 0 0 2px rgba(200, 155, 60, 0.1);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
---
|
|
||||||
import { getCollection } from 'astro:content';
|
|
||||||
|
|
||||||
const months = [
|
|
||||||
"Janvier", "Février", "Mars", "Avril", "Mai", "Juin",
|
|
||||||
"Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"
|
|
||||||
];
|
|
||||||
|
|
||||||
// 1. Récupérer tous les événements futurs
|
|
||||||
const futureEvents = await getCollection('bujo', ({ id }) => {
|
|
||||||
return id.startsWith('future/');
|
|
||||||
});
|
|
||||||
|
|
||||||
// 2. Grouper les événements par mois
|
|
||||||
const eventsByMonth = {};
|
|
||||||
futureEvents.forEach(event => {
|
|
||||||
const monthIndex = event.data.publishDate.getMonth(); // 0 = Janvier, 1 = Février, etc.
|
|
||||||
if (!eventsByMonth[monthIndex]) {
|
|
||||||
eventsByMonth[monthIndex] = [];
|
|
||||||
}
|
|
||||||
eventsByMonth[monthIndex].push(event);
|
|
||||||
});
|
|
||||||
---
|
|
||||||
|
|
||||||
<h1 class="text-3xl font-bold mb-2">Future Log</h1>
|
|
||||||
<p class="text-slate-500 mb-8">La vue d'ensemble de l'année à venir. Les grands rendez-vous, les voyages, les jalons importants.</p>
|
|
||||||
|
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
||||||
{months.map((monthName, index) => (
|
|
||||||
<div class="bg-white p-4 rounded-lg border border-slate-200 shadow-sm">
|
|
||||||
<h3 class="font-bold text-lg mb-3 text-slate-800">{monthName} 2026</h3>
|
|
||||||
<div class="space-y-2">
|
|
||||||
{eventsByMonth[index] ? eventsByMonth[index].map(event => (
|
|
||||||
<div class="text-sm p-2 bg-blue-50 rounded text-blue-800">{event.data.publishDate.getDate()} - {event.data.title}</div>
|
|
||||||
)) : (
|
|
||||||
<div class="h-6 bg-slate-100 rounded opacity-50"></div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
---
|
|
||||||
const { months } = Astro.props;
|
|
||||||
---
|
|
||||||
<h1 class="text-3xl font-bold mb-6 border-b pb-4">Index du Journal</h1>
|
|
||||||
|
|
||||||
<section class="mb-8">
|
|
||||||
<h2 class="text-2xl font-semibold mb-4 text-slate-700">Fondations</h2>
|
|
||||||
<ul class="list-disc list-inside space-y-2">
|
|
||||||
<li><a href="/bujo/keys" class="text-blue-600 hover:underline">Clés (Keys) - Notre langage de symboles</a></li>
|
|
||||||
<li><a href="/bujo/future-log" class="text-blue-600 hover:underline">Future Log - Le planning annuel</a></li>
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="mb-8">
|
|
||||||
<h2 class="text-2xl font-semibold mb-4 text-slate-700">Logs Temporels</h2>
|
|
||||||
<p class="text-slate-600 mb-4">Le cœur du journal, où le temps est cartographié mois par mois.</p>
|
|
||||||
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
|
|
||||||
{months.map(monthPath => {
|
|
||||||
const [year, month] = monthPath.split('/');
|
|
||||||
const monthName = new Date(parseInt(year), parseInt(month) - 1).toLocaleString('fr-FR', { month: 'long' });
|
|
||||||
return (
|
|
||||||
<a href={`/bujo/${monthPath}`} class="bg-slate-100 p-4 rounded-lg text-center font-semibold hover:bg-blue-100 transition-colors">
|
|
||||||
{monthName.charAt(0).toUpperCase() + monthName.slice(1)} {year}
|
|
||||||
</a>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<h2 class="text-2xl font-semibold mb-4 text-slate-700">Collections</h2>
|
|
||||||
<p class="text-slate-600 mb-4">Les pages thématiques qui rassemblent idées, suivis et inspirations.</p>
|
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
||||||
<div class="bg-slate-50 p-4 rounded-lg">
|
|
||||||
<h3 class="font-semibold text-slate-800 mb-2">Organisation & Suivi</h3>
|
|
||||||
<ul class="list-disc list-inside space-y-2 text-sm">
|
|
||||||
<li><a href="/bujo/collections/trackers-mensuels" class="text-blue-600 hover:underline">Trackers d'Habitudes</a></li>
|
|
||||||
<li><a href="/bujo/collections/objectifs-du-mois" class="text-blue-600 hover:underline">Objectifs du Mois</a></li>
|
|
||||||
<li><a href="/bujo/collections/suivi-depenses" class="text-blue-600 hover:underline">Suivi des Dépenses</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="bg-slate-50 p-4 rounded-lg">
|
|
||||||
<h3 class="font-semibold text-slate-800 mb-2">Inspiration & Bien-être</h3>
|
|
||||||
<ul class="list-disc list-inside space-y-2 text-sm">
|
|
||||||
<li><a href="/bujo/collections/gratitude" class="text-blue-600 hover:underline">Journal de Gratitude</a></li>
|
|
||||||
<li><a href="/bujo/collections/brain-dump" class="text-blue-600 hover:underline">Brain Dump (Vide-esprit)</a></li>
|
|
||||||
<li><a href="/bujo/collections/bucket-list" class="text-blue-600 hover:underline">Bucket List</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="bg-slate-50 p-4 rounded-lg">
|
|
||||||
<h3 class="font-semibold text-slate-800 mb-2">Créativité & Culture</h3>
|
|
||||||
<ul class="list-disc list-inside space-y-2 text-sm">
|
|
||||||
<li><a href="/bujo/collections/livres-a-lire" class="text-blue-600 hover:underline">Livres à lire</a></li>
|
|
||||||
<li><a href="/bujo/collections/films-a-voir" class="text-blue-600 hover:underline">Films & Séries à voir</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
---
|
|
||||||
---
|
|
||||||
<h1 class="text-3xl font-bold mb-6 border-b pb-4">Les Clés</h1>
|
|
||||||
<p class="mb-6">Ceci est notre langage pour capturer les pensées rapidement. Chaque symbole a une intention.</p>
|
|
||||||
|
|
||||||
<div class="space-y-8">
|
|
||||||
<section>
|
|
||||||
<h2 class="text-xl font-bold text-slate-700 border-b pb-2 mb-4">Symboles de Base</h2>
|
|
||||||
<ul class="space-y-4 text-lg">
|
|
||||||
<li class="flex items-center"><span class="w-8 text-center font-mono text-xl">•</span><span>Tâche à faire</span></li>
|
|
||||||
<li class="flex items-center"><span class="w-8 text-center font-mono text-xl text-green-600">X</span><span>Tâche terminée</span></li>
|
|
||||||
<li class="flex items-center"><span class="w-8 text-center font-mono text-xl text-blue-600">></span><span>Tâche reportée (migrée)</span></li>
|
|
||||||
<li class="flex items-center"><span class="w-8 text-center font-mono text-xl text-orange-600"><</span><span>Tâche planifiée (calendrier)</span></li>
|
|
||||||
<li class="flex items-center"><span class="w-8 text-center font-mono text-xl">○</span><span>Événement</span></li>
|
|
||||||
<li class="flex items-center"><span class="w-8 text-center font-mono text-xl">–</span><span>Note / Idée</span></li>
|
|
||||||
<li class="flex items-center"><span class="w-8 text-center font-mono text-xl text-slate-400"><s>•</s></span><span>Tâche annulée</span></li>
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<h2 class="text-xl font-bold text-slate-700 border-b pb-2 mb-4">Signifiants de Priorité (Préfixes)</h2>
|
|
||||||
<p class="text-sm text-slate-500 mb-4">Placés à gauche du symbole de base pour ajouter du contexte.</p>
|
|
||||||
<ul class="space-y-4 text-lg">
|
|
||||||
<li class="flex items-center"><span class="w-8 text-center font-mono text-xl text-red-500">*</span><span>Priorité absolue</span></li>
|
|
||||||
<li class="flex items-center"><span class="w-8 text-center font-mono text-xl text-yellow-500">!</span><span>Inspiration, Eurêka !</span></li>
|
|
||||||
<li class="flex items-center"><span class="w-8 text-center font-mono text-xl text-green-700">$</span><span>Aspect financier</span></li>
|
|
||||||
<li class="flex items-center"><span class="w-8 text-center font-mono text-xl">👁️</span><span>À explorer / Rechercher</span></li>
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<h2 class="text-xl font-bold text-slate-700 border-b pb-2 mb-4">Souffle de Vie (Bien-être & Réflexion)</h2>
|
|
||||||
<ul class="space-y-4 text-lg">
|
|
||||||
<li class="flex items-center"><span class="w-8 text-center font-mono text-xl">△</span><span>Leçon apprise, réflexion</span></li>
|
|
||||||
<li class="flex items-center"><span class="w-8 text-center font-mono text-xl text-pink-500">♡</span><span>Moment de gratitude</span></li>
|
|
||||||
<li class="flex items-center"><span class="w-8 text-center font-mono text-xl">⭘</span><span>En attente (dépend de qqn d'autre)</span></li>
|
|
||||||
<li class="flex items-center"><span class="w-8 text-center font-mono text-xl">⚓</span><span>Rituel, habitude ancrée</span></li>
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="mt-12 pt-6 border-t">
|
|
||||||
<h3 class="text-lg font-semibold mb-2">Exemple d'utilisation :</h3>
|
|
||||||
<div class="p-4 bg-slate-50 rounded-lg text-slate-700 font-mono">
|
|
||||||
<p>* • Finaliser le projet A</p>
|
|
||||||
<p>$ – Penser à renouveler l'abonnement</p>
|
|
||||||
<p>! △ La patience est la forme la plus douce du courage.</p>
|
|
||||||
<p>○ Passer faire coucou à Sofia en métropole</p>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
---
|
|
||||||
// Exemple de données. Plus tard, cela pourrait venir de fichiers de contenu.
|
|
||||||
const books = [
|
|
||||||
{ title: "Vers la beauté", author: "David Foenkinos", status: "En cours" },
|
|
||||||
{ title: "La huitième couleur", author: "Terry Pratchett", status: "À acheter" },
|
|
||||||
];
|
|
||||||
|
|
||||||
const booksByStatus = {
|
|
||||||
'En cours': books.filter(b => b.status === 'En cours'),
|
|
||||||
'À lire': books.filter(b => b.status === 'À lire'),
|
|
||||||
'À acheter': books.filter(b => b.status === 'À acheter'),
|
|
||||||
'Lu': books.filter(b => b.status === 'Lu'),
|
|
||||||
};
|
|
||||||
|
|
||||||
const statusStyles = {
|
|
||||||
'En cours': 'bg-blue-100 text-blue-800',
|
|
||||||
'À lire': 'bg-yellow-100 text-yellow-800',
|
|
||||||
'Lu': 'bg-green-100 text-green-800',
|
|
||||||
};
|
|
||||||
---
|
|
||||||
|
|
||||||
<h1 class="text-3xl font-bold mb-2">Collection : Livres à lire</h1>
|
|
||||||
<p class="text-slate-500 mb-8">La pile de savoir et d'évasion qui attend d'être explorée.</p>
|
|
||||||
|
|
||||||
{Object.entries(booksByStatus).map(([status, bookList]) => (
|
|
||||||
<section class="mb-8">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700 border-b pb-2 mb-4">{status}</h2>
|
|
||||||
<ul class="space-y-3">
|
|
||||||
{bookList.map(book => (
|
|
||||||
<li class="p-4 bg-white rounded-md shadow-sm border border-slate-200 flex justify-between items-center">
|
|
||||||
<div>
|
|
||||||
<p class="font-semibold">{book.title}</p>
|
|
||||||
<p class="text-sm text-slate-500">{book.author}</p>
|
|
||||||
</div>
|
|
||||||
<span class={`text-xs font-semibold px-2 py-1 rounded-full ${statusStyles[status]}`}>{book.status}</span>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
))}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
---
|
|
||||||
// Example data.
|
|
||||||
const items = [
|
|
||||||
{ title: "Demon Slayer : La forteresse infinie", type: "Film", status: "Vu" },
|
|
||||||
];
|
|
||||||
|
|
||||||
const itemsByStatus = {
|
|
||||||
'En cours': items.filter(b => b.status === 'En cours'),
|
|
||||||
'À voir': items.filter(b => b.status === 'À voir'),
|
|
||||||
'Vu': items.filter(b => b.status === 'Vu'),
|
|
||||||
};
|
|
||||||
|
|
||||||
const statusStyles = {
|
|
||||||
'En cours': 'bg-blue-100 text-blue-800',
|
|
||||||
'À voir': 'bg-yellow-100 text-yellow-800',
|
|
||||||
'Vu': 'bg-green-100 text-green-800',
|
|
||||||
};
|
|
||||||
---
|
|
||||||
|
|
||||||
<h1 class="text-3xl font-bold mb-2">Collection : Films & Séries à voir</h1>
|
|
||||||
<p class="text-slate-500 mb-8">Pour ne jamais être à court d'idées lors d'une soirée cinéma.</p>
|
|
||||||
|
|
||||||
{Object.entries(itemsByStatus).map(([status, itemList]) => (
|
|
||||||
<section class="mb-8">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700 border-b pb-2 mb-4">{status}</h2>
|
|
||||||
<ul class="space-y-3">
|
|
||||||
{itemList.map(item => (
|
|
||||||
<li class="p-4 bg-white rounded-md shadow-sm border border-slate-200 flex justify-between items-center">
|
|
||||||
<div>
|
|
||||||
<p class="font-semibold">{item.title}</p>
|
|
||||||
<p class="text-sm text-slate-500">{item.type}</p>
|
|
||||||
</div>
|
|
||||||
<span class={`text-xs font-semibold px-2 py-1 rounded-full ${statusStyles[status]}`}>{item.status}</span>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
))}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
---
|
|
||||||
// Example data. This could later come from content files.
|
|
||||||
const objectives = [
|
|
||||||
{
|
|
||||||
title: "Finaliser le pivot structurel du site",
|
|
||||||
steps: [
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Lancer la section 'Journal de Bord'",
|
|
||||||
steps: [
|
|
||||||
{ text: "Créer l'architecture du Bujo", done: true },
|
|
||||||
{ text: "Remplir les collections de base", done: true },
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Améliorer ma pratique d'Obsidian",
|
|
||||||
steps: [
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Améliorer ma pratique d'Astro",
|
|
||||||
steps: [
|
|
||||||
]
|
|
||||||
}
|
|
||||||
];
|
|
||||||
---
|
|
||||||
|
|
||||||
<h1 class="text-3xl font-bold mb-2">Collection : Objectifs du Mois</h1>
|
|
||||||
<p class="text-slate-500 mb-8">Découper les grandes ambitions en étapes réalisables pour rester motivé.</p>
|
|
||||||
|
|
||||||
<div class="space-y-6">
|
|
||||||
{objectives.map(obj => (
|
|
||||||
<div class="bg-white p-4 rounded-lg border border-slate-200 shadow-sm">
|
|
||||||
<h3 class="font-semibold text-lg text-slate-800 mb-3">{obj.title}</h3>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
{obj.steps.map(step => (
|
|
||||||
<li class="flex items-center text-sm">
|
|
||||||
<input type="checkbox" checked={step.done} class="h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500 mr-3" />
|
|
||||||
<span class:list={[{ "line-through text-slate-400": step.done }]}>{step.text}</span>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
---
|
|
||||||
const { collectionTitle } = Astro.props;
|
|
||||||
const capitalizedTitle = collectionTitle ? collectionTitle.charAt(0).toUpperCase() + collectionTitle.slice(1) : "Collection";
|
|
||||||
---
|
|
||||||
<h1 class="text-3xl font-bold mb-2">Collection : {capitalizedTitle}</h1>
|
|
||||||
<p class="text-slate-500 mb-8">Cette collection est en cours de construction.</p>
|
|
||||||
|
|
||||||
<div class="p-8 text-center bg-slate-50 rounded-lg border-2 border-dashed border-slate-300">
|
|
||||||
<p class="text-slate-500 italic">Contenu à venir...</p>
|
|
||||||
</div>
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
---
|
|
||||||
// Exemple de données. Plus tard, cela pourrait venir de fichiers de contenu.
|
|
||||||
const habits = [
|
|
||||||
"Sport (3x/sem)",
|
|
||||||
"Lecture",
|
|
||||||
"Écriture (Log/Journal)",
|
|
||||||
"Pratique du code",
|
|
||||||
"Budget respecté",
|
|
||||||
"Coucher avant 23h"
|
|
||||||
];
|
|
||||||
|
|
||||||
const daysInMonth = 31; // Pour Janvier, à rendre dynamique plus tard
|
|
||||||
|
|
||||||
// C'est ici que vous contrôlez l'état du tracker.
|
|
||||||
// Pour chaque habitude, listez les jours où elle a été complétée.
|
|
||||||
const completedHabits = {
|
|
||||||
"Sport (3x/sem)": [19],
|
|
||||||
"Lecture": [19],
|
|
||||||
"Écriture (Log/Journal)": [17,18,19],
|
|
||||||
"Pratique du code": [17,18,19],
|
|
||||||
"Budget respecté": [19],
|
|
||||||
"Coucher avant 23h": [],
|
|
||||||
};
|
|
||||||
---
|
|
||||||
|
|
||||||
<h1 class="text-3xl font-bold mb-2">Collection : Trackers Mensuels</h1>
|
|
||||||
<p class="text-slate-500 mb-8">Une vue d'ensemble pour cultiver la discipline et observer les schémas qui se dessinent.</p>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<h2 class="text-2xl font-semibold mb-4 text-slate-800">Janvier 2026</h2>
|
|
||||||
<div class="overflow-x-auto rounded-lg border border-slate-200">
|
|
||||||
<table class="min-w-full text-sm text-left">
|
|
||||||
<thead class="bg-slate-50 text-slate-600">
|
|
||||||
<tr>
|
|
||||||
<th class="p-2 font-semibold">Habitude</th>
|
|
||||||
{Array.from({ length: daysInMonth }, (_, i) => (
|
|
||||||
<th class="w-10 h-10 p-1 text-center font-mono font-normal">{i + 1}</th>
|
|
||||||
))}
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody class="bg-white">
|
|
||||||
{habits.map(habit => (
|
|
||||||
<tr class="border-t border-slate-200 align-middle">
|
|
||||||
<td class="p-2 font-semibold">{habit}</td>
|
|
||||||
{Array.from({ length: daysInMonth }, (_, i) => {
|
|
||||||
const day = i + 1;
|
|
||||||
const isCompleted = completedHabits[habit]?.includes(day);
|
|
||||||
const cellClass = isCompleted ? 'bg-green-400' : 'bg-white';
|
|
||||||
return (
|
|
||||||
<td class="p-1 text-center">
|
|
||||||
<div class={`w-6 h-6 border border-slate-300 rounded-sm mx-auto ${cellClass}`}></div>
|
|
||||||
</td>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<p class="text-xs text-slate-400 mt-2">Astuce : Sur mobile, la grille peut être scrollée horizontalement.</p>
|
|
||||||
</section>
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
---
|
|
||||||
const { symbol } = Astro.props;
|
|
||||||
|
|
||||||
const keyMap = {
|
|
||||||
'•': { style: '' },
|
|
||||||
'X': { style: 'text-green-600' },
|
|
||||||
'>': { style: 'text-blue-600' },
|
|
||||||
'<': { style: 'text-orange-600' },
|
|
||||||
'○': { style: '' },
|
|
||||||
'–': { style: '' },
|
|
||||||
's': { style: 'text-slate-400', symbol: '<s>•</s>' }, // Cas spécial pour la tâche annulée
|
|
||||||
'*': { style: 'text-red-500' },
|
|
||||||
'!': { style: 'text-yellow-500' },
|
|
||||||
'$': { style: 'text-green-700' },
|
|
||||||
'👁️': { style: '' },
|
|
||||||
'△': { style: '' },
|
|
||||||
'♡': { style: 'text-pink-500' },
|
|
||||||
'⭘': { style: '' },
|
|
||||||
'⚓': { style: '' },
|
|
||||||
};
|
|
||||||
|
|
||||||
const currentKey = keyMap[symbol] || { style: '', symbol: symbol };
|
|
||||||
---
|
|
||||||
<span class:list={["w-8 inline-block text-center font-mono text-xl", currentKey.style]} set:html={currentKey.symbol || symbol} />
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
---
|
|
||||||
const { logs, year, month } = Astro.props;
|
|
||||||
|
|
||||||
const yearNum = parseInt(year);
|
|
||||||
const monthNum = parseInt(month);
|
|
||||||
|
|
||||||
const monthName = new Date(yearNum, monthNum - 1).toLocaleString('fr-FR', { month: 'long' });
|
|
||||||
const capitalizedMonthName = monthName.charAt(0).toUpperCase() + monthName.slice(1);
|
|
||||||
|
|
||||||
// --- Logique du Calendrier ---
|
|
||||||
const daysInMonth = new Date(yearNum, monthNum, 0).getDate();
|
|
||||||
const firstDayOfMonth = new Date(yearNum, monthNum - 1, 1).getDay(); // 0=Dim, 1=Lun, ...
|
|
||||||
const startOffset = firstDayOfMonth === 0 ? 6 : firstDayOfMonth - 1;
|
|
||||||
const weekDays = ['Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam', 'Dim'];
|
|
||||||
|
|
||||||
const logsByDay = new Map(logs.map(log => {
|
|
||||||
const day = log.data.publishDate.getDate();
|
|
||||||
return [day, log];
|
|
||||||
}));
|
|
||||||
---
|
|
||||||
|
|
||||||
<h1 class="text-3xl font-bold mb-2">Monthly Log</h1>
|
|
||||||
<p class="text-slate-500 mb-8">{capitalizedMonthName} {year}</p>
|
|
||||||
|
|
||||||
<!-- Vue Calendrier -->
|
|
||||||
<div class="grid grid-cols-7 gap-1 text-center mb-12">
|
|
||||||
<!-- Jours de la semaine -->
|
|
||||||
{weekDays.map(day => <div class="font-bold text-sm text-slate-500 py-2">{day}</div>)}
|
|
||||||
|
|
||||||
<!-- Jours vides avant le début du mois -->
|
|
||||||
{Array.from({ length: startOffset }).map(() => <div />)}
|
|
||||||
|
|
||||||
<!-- Jours du mois -->
|
|
||||||
{Array.from({ length: daysInMonth }, (_, i) => i + 1).map(day => {
|
|
||||||
const log = logsByDay.get(day);
|
|
||||||
const currentDate = new Date(yearNum, monthNum - 1, day);
|
|
||||||
const isToday = new Date().toDateString() === currentDate.toDateString();
|
|
||||||
const dayOfWeek = currentDate.getDay();
|
|
||||||
const isWeekend = dayOfWeek === 0 || dayOfWeek === 6;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<a href={log ? `/bujo/${log.slug}` : '#'} class:list={[
|
|
||||||
"h-12 w-12 flex items-center justify-center rounded-full transition-colors",
|
|
||||||
{ "bg-slate-50 text-slate-500": isWeekend && !log },
|
|
||||||
{ "bg-blue-500 text-white font-bold": isToday && log },
|
|
||||||
{ "border-2 border-blue-500": isToday && !log },
|
|
||||||
{ "bg-blue-100 hover:bg-blue-200 font-semibold": log && !isToday },
|
|
||||||
{ "pointer-events-none": !log }
|
|
||||||
]}>{day}</a>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Liste des entrées -->
|
|
||||||
<h2 class="text-2xl font-semibold mb-4 border-t pt-8">Toutes les entrées du mois</h2>
|
|
||||||
<ul class="space-y-4">
|
|
||||||
{logs.map(log => (
|
|
||||||
<li class="border-b border-slate-200 pb-3">
|
|
||||||
<a href={`/bujo/${log.slug}`} class="text-lg font-semibold text-blue-600 hover:underline">{log.data.title}</a>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
@@ -2,103 +2,117 @@
|
|||||||
import type { CollectionEntry } from "astro:content";
|
import type { CollectionEntry } from "astro:content";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
entry: CollectionEntry<"codex">;
|
entry: CollectionEntry<"codex">;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { entry } = Astro.props;
|
const { entry } = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<a href={`/codex/${entry.slug}`} class="codex-card">
|
<a href={`/codex/${entry.slug}`} class="codex-card">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<div class="card-title">{entry.data.title}</div>
|
<div class="card-title">{entry.data.title}</div>
|
||||||
<div class="card-subtitle">{entry.data.subtitle}</div>
|
<div class="card-subtitle">{entry.data.subtitle}</div>
|
||||||
<span class={`status status-${entry.data.status.toLowerCase().replace(' ', '-')}`}>
|
<span
|
||||||
{entry.data.status}
|
class={`status status-${entry.data.status.toLowerCase().replace(" ", "-")}`}
|
||||||
</span>
|
>
|
||||||
</div>
|
{entry.data.status}
|
||||||
<div class="skill-section">
|
</span>
|
||||||
<div class="skill-header">Compétence</div>
|
</div>
|
||||||
<p class="skill-content">{entry.data.mecanique}</p>
|
<div class="skill-section">
|
||||||
<div class="skill-header">Application Concrète</div>
|
<div class="skill-header">Compétence</div>
|
||||||
<p class="skill-content">{entry.data.vision3D}</p>
|
<p class="skill-content">{entry.data.mecanique}</p>
|
||||||
|
<div class="skill-header">Application Concrète</div>
|
||||||
|
<p class="skill-content">{entry.data.vision3D}</p>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.codex-card {
|
.codex-card {
|
||||||
display: block;
|
display: block;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
background: linear-gradient(145deg, #fefbf3, #f8f1e4);
|
background: linear-gradient(145deg, #fefbf3, #f8f1e4);
|
||||||
border: 2px solid #dcd0b9;
|
border: 2px solid #dcd0b9;
|
||||||
border-radius: 15px;
|
border-radius: 15px;
|
||||||
padding: 1.5rem;
|
padding: 1.5rem;
|
||||||
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05);
|
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05);
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 450px; /* Largeur max pour une carte */
|
max-width: 450px; /* Largeur max pour une carte */
|
||||||
}
|
}
|
||||||
|
|
||||||
.codex-card:hover {
|
.codex-card:hover {
|
||||||
transform: translateY(-5px) scale(1.02);
|
transform: translateY(-5px) scale(1.02);
|
||||||
border-color: #c89b3c;
|
border-color: #c89b3c;
|
||||||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-header {
|
.card-header {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-title {
|
.card-title {
|
||||||
font-family: 'Cinzel', serif;
|
font-family: "Cinzel", serif;
|
||||||
font-size: 1.3rem;
|
font-size: 1.3rem;
|
||||||
color: #b8860b;
|
color: #b8860b;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-subtitle {
|
.card-subtitle {
|
||||||
font-family: 'EB Garamond', serif;
|
font-family: "EB Garamond", serif;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
.status {
|
.status {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: -5px;
|
top: -5px;
|
||||||
right: -5px;
|
right: -5px;
|
||||||
font-family: 'Cinzel', serif;
|
font-family: "Cinzel", serif;
|
||||||
font-size: 0.7rem;
|
font-size: 0.7rem;
|
||||||
padding: 0.2rem 0.5rem;
|
padding: 0.2rem 0.5rem;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
border: 1px solid;
|
border: 1px solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-acquis { background-color: rgba(60, 150, 60, 0.1); border-color: rgba(60, 150, 60, 0.4); color: #3c963c; }
|
.status-acquis {
|
||||||
.status-en-cours { background-color: rgba(200, 155, 60, 0.15); border-color: rgba(200, 155, 60, 0.4); color: #b8860b; }
|
background-color: rgba(60, 150, 60, 0.1);
|
||||||
.status-à-explorer { background-color: rgba(100, 100, 100, 0.1); border-color: rgba(100, 100, 100, 0.3); color: #646464; }
|
border-color: rgba(60, 150, 60, 0.4);
|
||||||
|
color: #3c963c;
|
||||||
|
}
|
||||||
|
.status-en-cours {
|
||||||
|
background-color: rgba(200, 155, 60, 0.15);
|
||||||
|
border-color: rgba(200, 155, 60, 0.4);
|
||||||
|
color: #b8860b;
|
||||||
|
}
|
||||||
|
.status-à-explorer {
|
||||||
|
background-color: rgba(100, 100, 100, 0.1);
|
||||||
|
border-color: rgba(100, 100, 100, 0.3);
|
||||||
|
color: #646464;
|
||||||
|
}
|
||||||
|
|
||||||
.skill-section {
|
.skill-section {
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
background-color: rgba(253, 246, 232, 0.5);
|
background-color: rgba(253, 246, 232, 0.5);
|
||||||
border: 1px solid #dcd0b9;
|
border: 1px solid #dcd0b9;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
padding: 0.75rem 1rem;
|
padding: 0.75rem 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.skill-header {
|
.skill-header {
|
||||||
font-family: 'Cinzel', serif;
|
font-family: "Cinzel", serif;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #4a4130;
|
color: #4a4130;
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
margin-bottom: 0.25rem;
|
margin-bottom: 0.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.skill-content {
|
.skill-content {
|
||||||
margin: 0 0 0.75rem 0;
|
margin: 0 0 0.75rem 0;
|
||||||
padding-left: 0.5rem;
|
padding-left: 0.5rem;
|
||||||
border-left: 2px solid rgba(200, 155, 60, 0.3);
|
border-left: 2px solid rgba(200, 155, 60, 0.3);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,88 +0,0 @@
|
|||||||
---
|
|
||||||
const { pathname } = Astro.url;
|
|
||||||
|
|
||||||
// Dans une application réelle, ces liens pourraient provenir d'un fichier de configuration.
|
|
||||||
const navItems = [
|
|
||||||
{ href: '/', label: 'Accueil' },
|
|
||||||
{ href: '/codex', label: 'Codex' },
|
|
||||||
{ href: '/atelier', label: 'Atelier' },
|
|
||||||
{ href: '/observatoire', label: 'Observatoire' },
|
|
||||||
{ href: '/boussole', label: 'Boussole' },
|
|
||||||
{ href: '/journal', label: 'Journal' },
|
|
||||||
{ href: '/auteur', label: 'Auteur' },
|
|
||||||
{ href: '/logs', label: 'Logs' },
|
|
||||||
];
|
|
||||||
---
|
|
||||||
|
|
||||||
<nav class="game-nav">
|
|
||||||
<div id="nav-container" class="nav-container">
|
|
||||||
{
|
|
||||||
navItems.map((item) => {
|
|
||||||
// Met en surbrillance si le chemin commence par l'URL du lien (ex: /journal/2 commence par /journal)
|
|
||||||
const isActive = item.href === '/' ? pathname === '/' : pathname.startsWith(item.href) && item.href.length > 1;
|
|
||||||
return (
|
|
||||||
<a href={item.href} class:list={['nav-item', { active: isActive }]} title={item.label}>
|
|
||||||
{item.label}
|
|
||||||
</a>
|
|
||||||
);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
/* --- Styles de la barre de navigation --- */
|
|
||||||
.game-nav {
|
|
||||||
position: fixed;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
height: auto; /* La hauteur s'adapte au contenu */
|
|
||||||
background: rgba(253, 246, 232, 0.85); /* Fond parchemin semi-transparent */
|
|
||||||
border-top: 2px solid #c89b3c; /* Bordure dorée */
|
|
||||||
box-shadow: 0 -5px 20px rgba(0, 0, 0, 0.15);
|
|
||||||
backdrop-filter: blur(8px);
|
|
||||||
z-index: 1000;
|
|
||||||
padding: 0.5rem 1rem; /* Un peu d'espace intérieur */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --- Styles du conteneur des liens --- */
|
|
||||||
.nav-container {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap; /* Permet aux éléments de passer à la ligne */
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
height: inherit;
|
|
||||||
gap: 0.5rem 1.5rem; /* Espace vertical et horizontal entre les liens */
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-item {
|
|
||||||
text-decoration: none;
|
|
||||||
color: #4a4130; /* Couleur texte sombre pour le contraste */
|
|
||||||
font-family: 'Cinzel', serif;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
transition: all 0.2s ease-in-out;
|
|
||||||
padding: 0.25rem 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-item.active {
|
|
||||||
color: #b8860b; /* Couleur dorée pour l'élément actif */
|
|
||||||
transform: scale(1.05);
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-item:hover {
|
|
||||||
color: #b8860b; /* Couleur dorée au survol */
|
|
||||||
transform: scale(1.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --- Styles pour les écrans larges (Desktop) --- */
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
.game-nav {
|
|
||||||
height: 55px; /* Hauteur fixe pour le bureau */
|
|
||||||
padding: 0 1rem;
|
|
||||||
}
|
|
||||||
.nav-container {
|
|
||||||
flex-wrap: nowrap; /* Empêche le retour à la ligne sur les grands écrans */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,17 +1,14 @@
|
|||||||
---
|
---
|
||||||
interface Props {
|
interface Props {
|
||||||
href: string;
|
href: string;
|
||||||
title: string;
|
title: string;
|
||||||
body: string;
|
body: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { href, title, body } = Astro.props;
|
const { href, title, body } = Astro.props;
|
||||||
---
|
---
|
||||||
<style>
|
|
||||||
/* Les styles ont été déplacés dans GameLayout.astro pour être globaux */
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<a href={href} class="gold-button">
|
<a href={href} class="gold-button">
|
||||||
<div class="title">{title}</div>
|
<div class="title">{title}</div>
|
||||||
<p class="body">{body}</p>
|
<p class="body">{body}</p>
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
---
|
|
||||||
// Ce composant est un simple conteneur stylisé.
|
|
||||||
// Il n'a pas besoin de props, il affiche simplement le contenu passé à l'intérieur.
|
|
||||||
---
|
|
||||||
|
|
||||||
<div class="parchment-card">
|
|
||||||
<slot />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.parchment-card {
|
|
||||||
background-color: rgba(253, 246, 232, 0.8); /* Fond parchemin légèrement transparent */
|
|
||||||
border: 1px solid #dcd0b9;
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 2rem;
|
|
||||||
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.15);
|
|
||||||
backdrop-filter: blur(4px); /* Effet de verre dépoli pour voir la texture du fond */
|
|
||||||
margin-bottom: 2rem;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,36 +1,24 @@
|
|||||||
import { defineCollection, z } from 'astro:content';
|
import { defineCollection, z } from "astro:content";
|
||||||
import { glob } from 'astro/loaders';
|
import { glob } from "astro/loaders";
|
||||||
|
|
||||||
const bujo = defineCollection({
|
// Petit helper pour éviter la répétition du loader
|
||||||
loader: glob({ pattern: '**/[^_]*.{md,mdx}', base: "./src/content/bujo" }),
|
const obsidianLoader = (path: string) =>
|
||||||
schema: z.object({
|
glob({
|
||||||
title: z.string(),
|
pattern: "**/[^_]*.{md,mdx}",
|
||||||
publishDate: z.date(),
|
base: `./src/content/${path}`,
|
||||||
}).passthrough(),
|
});
|
||||||
});
|
|
||||||
|
|
||||||
const codex = defineCollection({
|
|
||||||
loader: glob({ pattern: '**/[^_]*.{md,mdx}', base: "./src/content/codex" }),
|
|
||||||
schema: z.object({}).passthrough(), // TODO: Définir un schéma plus strict
|
|
||||||
});
|
|
||||||
|
|
||||||
const journal = defineCollection({
|
const journal = defineCollection({
|
||||||
loader: glob({ pattern: '**/[^_]*.{md,mdx}', base: "./src/content/journal" }),
|
loader: obsidianLoader("journal"),
|
||||||
schema: z.object({
|
schema: z
|
||||||
title: z.string(),
|
.object({
|
||||||
author: z.string(),
|
title: z.string(),
|
||||||
publishDate: z.date(),
|
// On rend la date plus flexible car Obsidian peut parfois envoyer des strings
|
||||||
tags: z.array(z.string()),
|
publishDate: z.coerce.date(),
|
||||||
}).passthrough(),
|
tags: z.array(z.string()).default([]),
|
||||||
|
author: z.string().default("Artisan"),
|
||||||
|
})
|
||||||
|
.passthrough(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const logs = defineCollection({
|
export const collections = { journal }; // Simplifié pour test
|
||||||
loader: glob({ pattern: '**/[^_]*.{md,mdx}', base: "./src/content/logs" }),
|
|
||||||
schema: z.object({
|
|
||||||
title: z.string(),
|
|
||||||
publishDate: z.date(),
|
|
||||||
tags: z.array(z.string()),
|
|
||||||
}).passthrough(),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const collections = { bujo, codex, journal, logs };
|
|
||||||
|
|||||||
@@ -1,71 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Daily Log - 18 Janvier 2026"
|
|
||||||
publishDate: 2026-01-18
|
|
||||||
tags: ["Daily", "Pivot", "Organisation"]
|
|
||||||
---
|
|
||||||
import Key from '~/components/bujo/Key.astro';
|
|
||||||
|
|
||||||
<div class="mb-8 p-4 bg-blue-50 border-l-4 border-blue-400">
|
|
||||||
<h2 class="text-xl font-bold text-slate-800 mb-2"><Key symbol="⚓" /> Ancrage & Bien-être</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Routine du matin (douche, dents...)</li>
|
|
||||||
<li><Key symbol="X" /> Activité physique</li>
|
|
||||||
<li><Key symbol="–" /> Qualité du sommeil (1-5) : 3</li>
|
|
||||||
<li><Key symbol="–" /> Humeur du jour (1-5) : 4</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="*" /> Objectifs du Dimanche</h2>
|
|
||||||
<p class="text-sm text-slate-500 mb-3">Une ou deux choses pour profiter de la journée et se sentir bien.</p>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="X" /> [Objectif principal]</li>
|
|
||||||
<li><Key symbol="X" /> [Autre petite tâche]</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="$" /> Organisation & Budget</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="X" /> Planifier les repas de la semaine à venir</li>
|
|
||||||
<li><Key symbol="X" /> Chercher une activité gratuite ou un bon plan</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="•" /> Foyer & Préparation de la semaine</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="X" /> Session de rangement (15 min)</li>
|
|
||||||
<li><Key symbol="X" /> Préparer les vêtements pour lundi</li>
|
|
||||||
<li><Key symbol="X" /> Tâche ménagère au choix (lessive, vaisselle...)</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="♡" /> Loisirs & Note du jour</h2>
|
|
||||||
<p class="text-slate-600 mt-2">Un moment pour soi, une pensée, une petite victoire :</p>
|
|
||||||
<p class="mt-4 p-3 bg-amber-50 text-amber-900 border-l-4 border-amber-400 rounded-r-lg italic">Ce matin après la séance d'hier c'était très compliqué de pouvoir tenir la routine du jour. Je me suis réveillé vers 13h30, je suis sorti du lit vers 14h 14h30... Mais je me sens reposé, je n'ai pas le cou qui tire aujourd'hui, ou encore de migraine particulière. Deux objectifs principales aujourd'hui. La première était de faire le résumé de la session de JDR d'hier. La seconde de commencer à créer mon bullet Journal, ce n'est que le début mais c'est déjà ça.. J'ai réussi à faire les deux et j'ai fait ma lessive, j'ai tendu mon ligne. J'ai rangé un peu mes affaires. J’ai créé mon bullet journal aujourd’hui je suis trop content.. Il y a tellement de chose à faire encore mais franchement, ça fait plaisir !</p>
|
|
||||||
<textarea id="daily-note" class="w-full mt-2 p-2 border rounded bg-slate-50" rows="2" placeholder="..."></textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script is:inline>
|
|
||||||
{`
|
|
||||||
// On s'assure que le script s'exécute une fois la page chargée
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
|
||||||
const textarea = document.getElementById('daily-note');
|
|
||||||
// Clé unique pour cette entrée de journal, basée sur la date
|
|
||||||
const storageKey = 'note-' + new URL(window.location.href).pathname;
|
|
||||||
|
|
||||||
// 1. Charger la note sauvegardée au chargement de la page
|
|
||||||
const savedNote = localStorage.getItem(storageKey);
|
|
||||||
if (savedNote) {
|
|
||||||
textarea.value = savedNote;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. Sauvegarder la note à chaque fois que l'on écrit dedans
|
|
||||||
textarea.addEventListener('input', () => {
|
|
||||||
localStorage.setItem(storageKey, textarea.value);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
`}
|
|
||||||
</script>
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Daily Log - 19 Janvier 2026"
|
|
||||||
publishDate: 2026-01-19
|
|
||||||
tags: ["Daily", "Work", "Organisation"]
|
|
||||||
---
|
|
||||||
import Key from '~/components/bujo/Key.astro';
|
|
||||||
|
|
||||||
<div class="mb-8 p-4 bg-blue-50 border-l-4 border-blue-400">
|
|
||||||
<h2 class="text-xl font-bold text-slate-800 mb-2"><Key symbol="⚓" /> Ancrage & Bien-être</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="X" /> Routine du matin (douche, dents...)</li>
|
|
||||||
<li><Key symbol="X" /> Activité physique douce (étirements, marche...)</li>
|
|
||||||
<li><Key symbol="–" /> Qualité du sommeil (1-5) : 4</li>
|
|
||||||
<li><Key symbol="–" /> Humeur du jour (1-5) : 5</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="*" /> Priorités du Jour (Pro & Perso)</h2>
|
|
||||||
<p class="text-sm text-slate-500 mb-3">Se concentrer sur 1 à 3 tâches essentielles pour avancer.</p>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="X" /> [Tâche pro n°1]</li>
|
|
||||||
<li><Key symbol=">" /> [Tâche pro n°2]</li>
|
|
||||||
<li><Key symbol=">" /> [Tâche perso importante]</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="$" /> Organisation & Budget</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="X" /> Planifier le repas du soir</li>
|
|
||||||
<li><Key symbol="<" /> Point rapide sur les comptes</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="•" /> Foyer & Routine du soir</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="X" /> Remplir mon carnet à dessin et projets</li>
|
|
||||||
<li><Key symbol=">" /> Ranger l'espace de travail (5 min)</li>
|
|
||||||
<li><Key symbol="X" /> Préparer les affaires pour demain</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="♡" /> Loisirs & Note du jour</h2>
|
|
||||||
<p class="text-slate-600 mt-2">Un moment pour soi, une pensée, une petite victoire :</p>
|
|
||||||
<p class="mt-4 p-3 bg-amber-50 text-amber-900 border-l-4 border-amber-400 rounded-r-lg italic">Ce matin réveil à l'heure, j'étais trop bien dans mon lit... Je sentait que ma nuit a était reposante. J'avais pas trop de douleur, ça tirait un peu, juste assez pour que je me rende compte que ça ne me faisait pas mal. je suis partie de chez moi à vélo, en forme et avec un moral d'acier fort d'avoir réalisé ce bel outil hier... De samedi j'ai eu un appel concernant LEO qui demandait à mettre un article au tarif défini, le problème c'est que c'est la 5ème fois qu'il m’appelle pour ce type d'article. Alors je me suis investi d'une mission aujourd'hui, mettre en lumière l'erreur et faire en sorte de structurer un tableur avec toute les corrections à mettre en place. Ce qui a était fait bon j'ai fini un peu plus tard que d'habitude mais ça en valait la peine. Peut-être diront-il demain que ça ne sert à rien. En tout cas moi je sais que ça sert à quelque chose. Ce soir j'ai commencé à remplir mon BUJO. Mais je dois surtout organiser des tâches dans un véritable carnet et noter ce qui doit être améliorer ou modifier pour rendre ce travail loin d'être fastidieux. Ce soir ce sera simple au niveau du repas, rien de folichon, juste de quoi sustenter mon estomac. Il faudrait que je pense à la section recette. Pour les comptes, idem il faudrait que j'y penses également. Et aussi à améliorer chaque point de ce Bujo. Je dois aussi structurer mes routines pour l'entretien de ma maison. Il faudrait aussi peut-être que je penses à un petit espace de notification... Enfin à voir c'est pas le plus urgent. En attendant ce soir une fois que j'ai finaliser de remplir toute les sections on s'attarde dans un vrai carnet de note avec des crayons ^^</p>
|
|
||||||
<textarea id="daily-note-19" class="w-full mt-2 p-2 border rounded bg-slate-50" rows="2" placeholder="..."></textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script is:inline>
|
|
||||||
{`
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
|
||||||
const textarea = document.getElementById('daily-note-19');
|
|
||||||
const storageKey = 'note-/bujo/2026/01/19';
|
|
||||||
const savedNote = localStorage.getItem(storageKey);
|
|
||||||
if (savedNote) textarea.value = savedNote;
|
|
||||||
textarea.addEventListener('input', () => localStorage.setItem(storageKey, textarea.value));
|
|
||||||
});
|
|
||||||
`}
|
|
||||||
</script>
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Daily Log - 20 Janvier 2026"
|
|
||||||
publishDate: 2026-01-20
|
|
||||||
tags: ["Daily", "Work", "Organisation"]
|
|
||||||
---
|
|
||||||
import Key from '~/components/bujo/Key.astro';
|
|
||||||
|
|
||||||
<div class="mb-8 p-4 bg-blue-50 border-l-4 border-blue-400">
|
|
||||||
<h2 class="text-xl font-bold text-slate-800 mb-2"><Key symbol="⚓" /> Ancrage & Bien-être</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Routine du matin (douche, dents...)</li>
|
|
||||||
<li><Key symbol="•" /> Activité physique douce (étirements, marche...)</li>
|
|
||||||
<li><Key symbol="–" /> Qualité du sommeil (1-5) : __</li>
|
|
||||||
<li><Key symbol="–" /> Humeur du jour (1-5) : __</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="*" /> Priorités du Jour (Pro & Perso)</h2>
|
|
||||||
<p class="text-sm text-slate-500 mb-3">Se concentrer sur 1 à 3 tâches essentielles pour avancer.</p>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> [Tâche pro n°2 d'hier]</li>
|
|
||||||
<li><Key symbol="•" /> [Tâche pro n°1]</li>
|
|
||||||
<li><Key symbol="•" /> [Tâche pro n°2]</li>
|
|
||||||
<li><Key symbol="•" /> [Tâche perso importante d'hier]</li>
|
|
||||||
<li><Key symbol="•" /> [Tâche perso importante]</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="$" /> Organisation & Budget</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Planifier le repas du soir</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="•" /> Foyer & Routine du soir</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Ranger l'espace de travail (10 min)</li>
|
|
||||||
<li><Key symbol="•" /> Préparer les affaires pour demain</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="♡" /> Loisirs & Note du jour</h2>
|
|
||||||
<p class="text-slate-600 mt-2">Un moment pour soi, une pensée, une petite victoire :</p>
|
|
||||||
<textarea id="daily-note-20" class="w-full mt-2 p-2 border rounded bg-slate-50" rows="2" placeholder="..."></textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script is:inline>
|
|
||||||
{`
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
|
||||||
const textarea = document.getElementById('daily-note-20');
|
|
||||||
const storageKey = 'note-/bujo/2026/01/20';
|
|
||||||
const savedNote = localStorage.getItem(storageKey);
|
|
||||||
if (savedNote) textarea.value = savedNote;
|
|
||||||
textarea.addEventListener('input', () => localStorage.setItem(storageKey, textarea.value));
|
|
||||||
});
|
|
||||||
`}
|
|
||||||
</script>
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Fin des frais d'agence"
|
|
||||||
publishDate: 2026-08-01
|
|
||||||
tags: ["future-log", "pro"]
|
|
||||||
---
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Publier la dernière mouture du site"
|
|
||||||
publishDate: 2026-02-01
|
|
||||||
tags: ["future-log", "pro"]
|
|
||||||
---
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Négocier contrat Cirrus"
|
|
||||||
publishDate: 2026-04-01
|
|
||||||
tags: ["future-log", "pro"]
|
|
||||||
---
|
|
||||||
|
|
||||||
*• Préparer la renégociation du contrat.
|
|
||||||
– Deux ans d'ancienneté, c'est un pivot stratégique. Le moment est venu d'aligner le contrat avec la valeur apportée.
|
|
||||||
|
|
||||||
### A. Bilan des Réalisations (Le Factuel)
|
|
||||||
|
|
||||||
• Lister les réalisations concrètes :
|
|
||||||
- $ Chiffres clés (hausse CA, gain de temps, économies).
|
|
||||||
- • Projets complexes menés de A à Z.
|
|
||||||
- • Tâches et responsabilités acquises hors contrat initial (Argument n°1).
|
|
||||||
|
|
||||||
### B. Étude du Marché
|
|
||||||
|
|
||||||
👁️ Rechercher ma valeur sur le marché actuel :
|
|
||||||
- • Consulter les simulateurs de salaire (Apec, Glassdoor).
|
|
||||||
- • Analyser les offres d'emploi pour des postes similaires.
|
|
||||||
– L'objectif n'est pas de menacer, mais de démontrer une connaissance de ma valeur.
|
|
||||||
|
|
||||||
### C. Préparer le "Panier de Négociation"
|
|
||||||
|
|
||||||
• Définir les demandes au-delà du salaire :
|
|
||||||
- $ Rémunération : Salaire de base, primes.
|
|
||||||
- ♡ Qualité de vie : Télétravail, aménagement d'horaires.
|
|
||||||
- • Évolution : Formation certifiante, changement de poste.
|
|
||||||
|
|
||||||
### D. L'Entretien
|
|
||||||
|
|
||||||
< ○ Demander un entretien spécifique pour discuter de mon évolution.
|
|
||||||
– Pendant l'entretien : rester positif, être précis dans les demandes, et préparer une réponse au "non" ("Que dois-je accomplir dans les 6 prochains mois ?").
|
|
||||||
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Plannifier mon mois de février"
|
|
||||||
publishDate: 2026-01-20
|
|
||||||
tags: ["future-log", "pro", "perso"]
|
|
||||||
---
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Repas d'entreprise pour la cohésion d'équipe"
|
|
||||||
publishDate: 2026-02-15
|
|
||||||
tags: ["future-log", "pro"]
|
|
||||||
---
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Vacances, rencontres et affaires"
|
|
||||||
publishDate: 2026-09-15
|
|
||||||
tags: ["future-log", "perso"]
|
|
||||||
---
|
|
||||||
Préparer le voyage pour la métropole et réserver les billets.
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
---
|
|
||||||
title: "L'Anatomie du Mouvement"
|
|
||||||
subtitle: "Animer pour le Web"
|
|
||||||
publishDate: 2026-01-14
|
|
||||||
tags: ["Blender", "Pipeline", "Animation", "Rigging"]
|
|
||||||
domain: "3D"
|
|
||||||
concept2D: "Créer un GIF animé à partir d'une séquence d'images."
|
|
||||||
mecanique: "Stocker plusieurs animations dans l'Éditeur d'actions non linéaires (NLA) pour les exporter en une seule fois."
|
|
||||||
vision3D: "Une statue qui bouge n'est pas vivante. Une créature vivante exprime une intention dans chaque mouvement. Le NLA Editor est le grimoire où l'on écrit les différents 'états d'âme' de l'avatar (marche, course, attente) pour pouvoir les invoquer à volonté dans le code."
|
|
||||||
status: "À explorer"
|
|
||||||
---
|
|
||||||
|
|
||||||
Le mouvement est la manifestation la plus pure du souffle de vie. Pour qu'il s'exprime dans Three.js, il doit être correctement catalogué dans Blender.
|
|
||||||
|
|
||||||
### La Check-list de l'Animateur
|
|
||||||
|
|
||||||
1. **Une Armature, Un Corps :**
|
|
||||||
* **Mécanique :** Le maillage de votre personnage (`Mesh`) doit être parenté à un seul objet `Armature`. Évitez les armatures multiples.
|
|
||||||
* **Vision :** Le squelette est unique. Il est le conduit par lequel le souffle se propage dans tout le corps.
|
|
||||||
|
|
||||||
2. **Le Grimoire des Actions (NLA Editor) :**
|
|
||||||
* **Mécanique :** Ne laissez pas vos animations en vrac. Pour chaque animation (ex: `marche`, `course`), allez dans l'éditeur d'actions, créez une nouvelle action, puis cliquez sur le bouton "Stocker l'action" (Push Down). Cela l'ajoute comme une "piste" dans l'éditeur NLA.
|
|
||||||
* **Vision :** Chaque piste est un chapitre de la vie de votre personnage. En les nommant correctement, vous pourrez dire à votre code : "Maintenant, lis le chapitre de la course" ou "Joue l'incantation de l'attente".
|
|
||||||
|
|
||||||
3. **Exporter les Actions :**
|
|
||||||
* **Mécanique :** Dans les paramètres d'export GLB, sous l'onglet `Animation`, assurez-vous que "Animer les actions" est coché et que "Exporter les actions NLA" l'est aussi.
|
|
||||||
* **Vision :** C'est le sceau final qui lie tous les chapitres de votre grimoire d'animations au cristal `.glb` avant son grand voyage.
|
|
||||||
|
|
||||||
En suivant ces préceptes, vous pourrez, dans Three.js, charger votre modèle et accéder à un tableau de toutes ses animations par leur nom, prêt à insuffler le véritable Hebel à votre création.
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Le Sceau de Transmutation"
|
|
||||||
subtitle: "Exporter en GLB/GLTF pour le Web"
|
|
||||||
publishDate: 2026-01-14
|
|
||||||
tags: ["Blender", "Pipeline", "GLTF", "Export"]
|
|
||||||
domain: "3D"
|
|
||||||
concept2D: "Enregistrer un fichier en 'JPEG pour le Web' avec les bons réglages de compression."
|
|
||||||
mecanique: "Configurer les paramètres de l'exportateur GLTF 2.0 pour optimiser la taille et la compatibilité."
|
|
||||||
vision3D: "L'export n'est pas une simple sauvegarde. C'est un rituel qui enferme l'essence du modèle dans un cristal (le fichier .glb) pour son voyage vers le monde du navigateur. Un rituel mal exécuté peut briser le cristal ou en altérer le contenu."
|
|
||||||
status: "À explorer"
|
|
||||||
---
|
|
||||||
|
|
||||||
Le format `.glb` (GLTF Binaire) est le vaisseau qui transportera votre création. Le configurer correctement, c'est s'assurer que le voyage se fasse sans perte et que le modèle arrive intact et léger.
|
|
||||||
|
|
||||||
### La Check-list du Rituel d'Exportation (`Fichier > Exporter > gLTF 2.0`)
|
|
||||||
|
|
||||||
1. **Format :**
|
|
||||||
* Choisissez **`gLTF Binaire (.glb)`**. Il contient tout (modèle, textures, animations) en un seul fichier, plus simple à gérer dans le code.
|
|
||||||
|
|
||||||
2. **Onglet `Inclure` :**
|
|
||||||
* **`Objets sélectionnés` :** Cochez **toujours** cette case. Vous ne voulez exporter que votre personnage, pas les lumières ou caméras de votre scène de travail.
|
|
||||||
* **`Propriétés personnalisées` :** Utile pour passer des données de Blender au code.
|
|
||||||
* **`Caméras` / `Lumières directionnelles` :** Décochez-les. La lumière et la caméra doivent être gérées par Three.js pour un contrôle total.
|
|
||||||
|
|
||||||
3. **Onglet `Transformation` :**
|
|
||||||
* **`+Y vers le Haut` :** Toujours coché. C'est la convention de Three.js.
|
|
||||||
|
|
||||||
4. **Onglet `Géométrie` :**
|
|
||||||
* **`Appliquer les modificateurs` :** Cochez cette case, sauf si vous utilisez des Shape Keys (morphings) pour la déformation.
|
|
||||||
* **`Compression` :** **Activez-la !** C'est le secret pour des modèles légers qui se chargent vite. L'algorithme Draco de Google est extrêmement efficace.
|
|
||||||
|
|
||||||
5. **Onglet `Animation` :**
|
|
||||||
* **`Animer les actions` :** Cochez cette case.
|
|
||||||
* **`Élaguer les animations` :** Cochez pour enlever les images-clés inutiles qui alourdissent le fichier.
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
---
|
|
||||||
title: "La Discipline de la Forme"
|
|
||||||
subtitle: "Préparer le Modèle pour le Souffle"
|
|
||||||
publishDate: 2026-01-14
|
|
||||||
tags: ["Blender", "Pipeline", "Optimisation"]
|
|
||||||
domain: "3D"
|
|
||||||
concept2D: "Nettoyer un fichier SVG avant de l'importer"
|
|
||||||
mecanique: "Appliquer les transformations, vérifier l'orientation et nettoyer la géométrie d'un modèle 3D."
|
|
||||||
vision3D: "Le corps de l'avatar n'est pas qu'une forme, c'est un réceptacle. S'il est impur ou mal orienté, le souffle de vie (l'animation) sera corrompu ou s'exprimera de travers. C'est l'art de préparer un golem parfait avant le rituel d'animation."
|
|
||||||
status: "À explorer"
|
|
||||||
---
|
|
||||||
|
|
||||||
Avant même de murmurer la formule d'exportation, le pèlerin doit s'assurer que son réceptacle est pur. Un modèle mal préparé dans Blender se manifestera dans Three.js comme une entité tordue, décalée ou gigantesque.
|
|
||||||
|
|
||||||
### La Check-list des Fondations
|
|
||||||
|
|
||||||
1. **Le Centre du Monde :**
|
|
||||||
* **Mécanique :** Assurez-vous que votre personnage est au centre de la scène (Origine du Monde : 0, 0, 0). Son origine (le petit point orange) doit être idéalement entre ses pieds.
|
|
||||||
* **Vision :** L'avatar doit être ancré dans la réalité de votre monde. S'il naît décalé, il sera toujours un étranger.
|
|
||||||
|
|
||||||
2. **L'Échelle de la Réalité :**
|
|
||||||
* **Mécanique :** Appliquez toutes les transformations avec `Ctrl + A` > `Toutes les transformations`. L'échelle de votre objet doit être de `(1, 1, 1)`.
|
|
||||||
* **Vision :** Un avatar dont l'échelle n'est pas appliquée peut apparaître 100 fois trop grand ou trop petit dans la scène Three.js. C'est la différence entre un dieu et un insecte.
|
|
||||||
|
|
||||||
3. **Le Regard vers l'Avant :**
|
|
||||||
* **Mécanique :** Votre modèle doit faire face à l'axe **-Y** (Avant). C'est la convention pour que la commande `lookAt()` de Three.js fonctionne intuitivement.
|
|
||||||
* **Vision :** Le regard de votre création doit être aligné avec son intention. S'il regarde de côté, il avancera en crabe, son corps trahissant son âme.
|
|
||||||
|
|
||||||
4. **La Pureté de la Géométrie :**
|
|
||||||
* **Mécanique :** En mode `Édition`, sélectionnez tout (`A`) et utilisez `M` > `Par distance` pour fusionner les sommets en double. Recalculez les normales avec `Shift + N`.
|
|
||||||
* **Vision :** Les sommets dupliqués sont des fractures dans l'âme du modèle. Les normales inversées sont des morceaux de peau retournés. Ces impuretés créent des artefacts visuels, des cicatrices sombres là où la lumière devrait être.
|
|
||||||
|
|
||||||
5. **Nommer, c'est Invoquer :**
|
|
||||||
* **Mécanique :** Donnez des noms clairs à vos objets (`Corps`, `Yeux`, `Armature`) et à vos matériaux.
|
|
||||||
* **Vision :** Un nom est une incantation. Il vous permettra, dans le code, d'invoquer une partie précise du corps pour la modifier, comme si vous appeliez son véritable nom.
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
---
|
|
||||||
title: "L'Alignement des Souffles"
|
|
||||||
subtitle: "CSS Flexbox"
|
|
||||||
publishDate: 2026-01-14
|
|
||||||
tags: ["CSS", "Layout", "Flexbox"]
|
|
||||||
domain: "Web Dev"
|
|
||||||
concept2D: "Centrer un texte verticalement dans un bloc, avec des astuces."
|
|
||||||
mecanique: "Un modèle de boîte unidimensionnel qui permet de distribuer l'espace et d'aligner des éléments le long d'un axe principal (horizontal ou vertical)."
|
|
||||||
vision3D: "Imaginez des âmes (des objets) flottant en ligne. Flexbox est le vent qui les pousse pour les regrouper, les espacer ou les centrer. C'est un souffle directionnel, parfait pour organiser des éléments qui se suivent, comme une barre de navigation ou une liste d'attributs."
|
|
||||||
status: "Acquis"
|
|
||||||
---
|
|
||||||
|
|
||||||
Flexbox (Flexible Box Layout) a été une révolution pour les développeurs web. Il a rendu simple ce qui était auparavant complexe : l'alignement et la distribution d'éléments dans un conteneur.
|
|
||||||
|
|
||||||
### La Philosophie de l'Axe
|
|
||||||
|
|
||||||
Flexbox est **unidimensionnel**. Il ne raisonne que sur un seul axe à la fois :
|
|
||||||
* **L'axe principal (`justify-content`) :** Comment les éléments se répartissent-ils le long de la direction principale (par défaut, de gauche à droite) ? Sont-ils au début, à la fin, au centre, ou avec un espace égal entre eux ?
|
|
||||||
* **L'axe secondaire (`align-items`) :** Comment les éléments s'alignent-ils sur l'axe perpendiculaire ? Sont-ils en haut, en bas, au centre, ou étirés pour remplir l'espace ?
|
|
||||||
|
|
||||||
C'est l'outil idéal pour les composants d'interface : barres de navigation, en-têtes de cartes, listes... partout où des éléments doivent être organisés en ligne ou en colonne.
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
---
|
|
||||||
title: "La Trame du Monde"
|
|
||||||
subtitle: "CSS Grid"
|
|
||||||
publishDate: 2026-01-14
|
|
||||||
tags: ["CSS", "Layout", "Grid"]
|
|
||||||
domain: "Web Dev"
|
|
||||||
concept2D: "Utiliser des `<table>` pour la mise en page (l'ancienne méthode, rigide)."
|
|
||||||
mecanique: "Un modèle de boîte bidimensionnel qui permet de créer des mises en page complexes en définissant des lignes et des colonnes explicites."
|
|
||||||
vision3D: "Si Flexbox est un souffle, Grid est la main de l'architecte qui dessine la trame invisible du monde. On ne pousse pas les objets, on leur assigne une place précise dans une structure. C'est le pouvoir de dire : 'Toi, tu iras ici, de cette colonne à celle-ci', créant des espaces complexes et asymétriques."
|
|
||||||
status: "Acquis"
|
|
||||||
---
|
|
||||||
|
|
||||||
CSS Grid a complété Flexbox en offrant un contrôle sur les deux dimensions simultanément. C'est l'outil de choix pour la mise en page globale d'une page ou d'un composant complexe.
|
|
||||||
|
|
||||||
### La Philosophie de la Grille
|
|
||||||
|
|
||||||
Grid est **bidimensionnel**. Il raisonne en termes de grille, avec des lignes et des colonnes :
|
|
||||||
* **Définition de la trame (`grid-template-columns` / `rows`) :** Vous définissez la structure de votre grille à l'avance. Combien de colonnes ? De quelle taille ?
|
|
||||||
* **Placement des éléments (`grid-column` / `grid-row`) :** Vous pouvez ensuite placer chaque élément précisément à l'intérieur de cette grille, en lui disant de s'étendre sur une ou plusieurs cellules.
|
|
||||||
|
|
||||||
C'est l'outil parfait pour les mises en page de magazines, les tableaux de bord, et toute interface où les éléments ne se suivent pas simplement mais occupent des zones spécifiques de l'écran.
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Le Portail Diégétique"
|
|
||||||
subtitle: "La Question du Menu de Création"
|
|
||||||
publishDate: 2026-01-14
|
|
||||||
tags: ["UI", "UX", "Game Design", "Interface"]
|
|
||||||
domain: "Game Design"
|
|
||||||
concept2D: "Un formulaire web bien désigné."
|
|
||||||
mecanique: "L'Interface Utilisateur (UI) qui permet au joueur de faire des choix pour personnaliser son avatar."
|
|
||||||
vision3D: "Le menu est la membrane entre le monde du joueur et le monde du jeu. S'il est une simple liste de boutons, il est une barrière à l'immersion. S'il est intégré à l'univers (un miroir, un rêve, une table d'alchimiste), il devient le premier rituel, le premier acte de création magique."
|
|
||||||
status: "À explorer"
|
|
||||||
---
|
|
||||||
|
|
||||||
Le mot "menu" peut sembler froid et technique, mais il représente un défi de design crucial : comment donner au joueur les outils de la création sans briser l'illusion ?
|
|
||||||
|
|
||||||
### Les Approches du Menu de Création
|
|
||||||
|
|
||||||
1. **Le Menu "Catalogue" (Classique) :** Une série de listes et de curseurs. Efficace, précis, mais souvent peu immersif. C'est la boîte à outils posée à côté de la sculpture.
|
|
||||||
|
|
||||||
2. **Le Menu "Diégétique" (Moderne) :** L'interface fait partie du monde du jeu.
|
|
||||||
* **Exemple :** Le personnage se regarde dans un miroir magique et le joueur modifie son reflet (*Dragon's Dogma 2*).
|
|
||||||
* **Exemple :** Le joueur manipule des orbes d'énergie ou des fragments de cristal qui flottent autour de l'avatar pour en changer les aspects.
|
|
||||||
|
|
||||||
Dans un projet Low Poly novateur, le menu lui-même peut devenir une expérience artistique. Puisque le personnage est simple, l'interface peut être riche et animée, utilisant des formes géométriques et des effets de lumière qui répondent en temps réel aux choix du joueur, transformant un formulaire en un véritable acte de magie.
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Le Regard et le Toucher"
|
|
||||||
subtitle: "Raycasting"
|
|
||||||
publishDate: 2026-01-15
|
|
||||||
tags: ["Physique du Sable", "Interaction"]
|
|
||||||
domain: "3D"
|
|
||||||
concept2D: "États :hover et :active des boutons"
|
|
||||||
mecanique: "Lancer un rayon depuis la caméra pour détecter les intersections avec les objets de la scène."
|
|
||||||
vision3D: "Le regard qui devient une main. Le simple fait de poser les yeux sur un objet peut altérer sa matière (changement de shader), déclencher un son, ou le faire léviter. C'est le premier pas vers une interaction sans interface visible."
|
|
||||||
status: "Acquis"
|
|
||||||
---
|
|
||||||
|
|
||||||
### La Dissection du Grain
|
|
||||||
|
|
||||||
Le Raycasting est le pont entre le monde 2D de l'écran et l'espace 3D de la scène. En projetant un rayon invisible depuis la position de la souris (ou du centre de la caméra), nous pouvons lister tous les objets qu'il traverse.
|
|
||||||
|
|
||||||
C'est le mécanisme fondamental qui nous permet de répondre à la question : "Qu'est-ce que le visiteur est en train de regarder ?". Il remplace la logique du DOM où l'on attache des `event listeners` à des boîtes HTML. Ici, l'événement est attaché à la direction du regard lui-même. C'est la mécanique derrière le "regard" ou la "main" du visiteur dans notre univers.
|
|
||||||
|
|
||||||
### Le Journal de Transmutation
|
|
||||||
|
|
||||||
Le passage du `:hover` CSS au Raycasting est un saut paradigmatique. On ne décore plus une boîte, on interroge l'espace. Le feedback n'est plus un simple changement de couleur, mais peut devenir une réaction physique de l'objet lui-même, lui donnant l'illusion d'être conscient de notre présence.
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
---
|
|
||||||
title: "La Pureté Géométrique"
|
|
||||||
subtitle: "Le Style Low Poly & Voxel"
|
|
||||||
publishDate: 2026-01-14
|
|
||||||
tags: ["Low Poly", "Voxel", "Direction Artistique", "Style"]
|
|
||||||
domain: "Game Design"
|
|
||||||
concept2D: "Le Pixel Art, où chaque carré compte."
|
|
||||||
mecanique: "Utiliser un nombre minimal de polygones (Low Poly) ou de cubes (Voxel) pour représenter des formes, en se concentrant sur la silhouette, la couleur et la lumière plutôt que sur le détail réaliste."
|
|
||||||
vision3D: "Le 'souffle de vie' n'a pas besoin des pores de la peau pour exister. En réduisant la forme à son essence, on laisse plus de place à l'imagination et à l'énergie pure. Le personnage n'est plus une imitation du réel, mais un symbole, une idée en mouvement."
|
|
||||||
status: "À explorer"
|
|
||||||
---
|
|
||||||
|
|
||||||
Choisir le Low Poly en 2026 n'est plus une contrainte technique, mais un choix esthétique radical. C'est l'art de la **"Modernité Simple"**. On utilise la puissance des moteurs modernes non pas pour imiter le réel, mais pour sublimer la simplicité.
|
|
||||||
|
|
||||||
### Le Low Poly "Haute-Fidélité"
|
|
||||||
|
|
||||||
Pour qu'un style simple ne paraisse pas "vieux jeu", on le marie à des technologies de pointe :
|
|
||||||
|
|
||||||
* **La Lumière sur la Forme :** On applique des éclairages et des ombres ultra-réalistes (calculés par des shaders complexes) sur des formes géométriques pures. Le contraste entre la simplicité du modèle et la complexité de la lumière crée un rendu unique, à la fois lisible et magnifique. C'est le style de jeux comme *Tunic* ou *Sable*.
|
|
||||||
|
|
||||||
* **La Matière avant la Texture :** Au lieu de peindre des détails, on simule des matériaux. Le personnage peut ressembler à une figurine en plastique brillant, en verre dépoli ou en métal brossé. La lumière interagit avec ces matériaux de façon crédible, donnant au modèle un aspect "premium" et tangible.
|
|
||||||
|
|
||||||
* **L'Animation comme Âme :** La fluidité du mouvement devient primordiale. Un personnage en 100 polygones peut sembler plus vivant qu'un modèle photoréaliste s'il bouge avec une grâce et une intention parfaites. Le "Hebel" se déplace du détail de la surface vers la pureté du mouvement.
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
---
|
|
||||||
title: "L'Architecture de l'Âme"
|
|
||||||
subtitle: "L'Arbre de Talents"
|
|
||||||
publishDate: 2026-01-14
|
|
||||||
tags: ["Game Design", "Systèmes", "RPG", "Progression"]
|
|
||||||
domain: "Game Design"
|
|
||||||
concept2D: "Un organigramme ou une carte mentale."
|
|
||||||
mecanique: "Un système de progression visuel où le joueur dépense des points pour débloquer des compétences et des bonus interconnectés, créant un 'build' (une construction) unique."
|
|
||||||
vision3D: "Le 'Hebel' n'est pas que visuel. C'est aussi la structure invisible de la puissance du personnage. L'arbre de talents est la constellation de son âme guerrière, où chaque choix est une étoile qui définit qui il est au combat, bien plus que la couleur de ses yeux."
|
|
||||||
status: "À explorer"
|
|
||||||
---
|
|
||||||
|
|
||||||
La personnalisation n'est pas qu'une affaire d'apparence. Un arbre de talents est une forme de création de personnage tout aussi profonde, mais qui se joue au niveau des systèmes.
|
|
||||||
|
|
||||||
### La Personnalisation Systémique
|
|
||||||
|
|
||||||
* **L'Expression par le Gameplay :** Dans des jeux comme *Path of Exile* ou *Divinity: Original Sin*, l'identité du personnage se définit par ses actions : la manière dont il combine ses sorts, la vitesse de ses attaques, sa capacité à survivre. L'arbre de talents est le lieu où ces choix sont architecturés.
|
|
||||||
|
|
||||||
* **Le Plaisir Cérébral :** "Jouer dans les menus" est une forme de plaisir à part entière. Le joueur devient un théoricien, un architecte de builds, cherchant la synergie parfaite entre des dizaines de compétences.
|
|
||||||
|
|
||||||
* **Une Constellation de Pouvoirs :** Visuellement, un arbre de talents peut lui-même devenir une œuvre d'art. Une carte céleste où chaque compétence est une étoile, et les liens entre elles forment les constellations du pouvoir que le joueur dessine pour son avatar.
|
|
||||||
@@ -33,7 +33,7 @@ A l'intérieur, l'obscurité y était totale, une gueule noire dévorant la lumi
|
|||||||
|
|
||||||
C’est ainsi que **Gurdil**, désormais baptisé **"Cul Brillant"**, est devenu notre phare, notre cap, que dis-je notre firmament. Et c'est guidés par son postérieur rayonnant que nous nous sommes enfoncés dans les entrailles de la terre, prêts à affronter l'obscurité.
|
C’est ainsi que **Gurdil**, désormais baptisé **"Cul Brillant"**, est devenu notre phare, notre cap, que dis-je notre firmament. Et c'est guidés par son postérieur rayonnant que nous nous sommes enfoncés dans les entrailles de la terre, prêts à affronter l'obscurité.
|
||||||
|
|
||||||
---
|
|
||||||
### Aventuriers
|
### Aventuriers
|
||||||
|
|
||||||
| **Nom** | **Race** | **Notes particulières** |
|
| **Nom** | **Race** | **Notes particulières** |
|
||||||
@@ -43,6 +43,7 @@ C’est ainsi que **Gurdil**, désormais baptisé **"Cul Brillant"**, est devenu
|
|||||||
| **Bulle** | Fée | A lancé _Lumière_ sur le caleçon de Gurdil pour explorer la mine. |
|
| **Bulle** | Fée | A lancé _Lumière_ sur le caleçon de Gurdil pour explorer la mine. |
|
||||||
| **Gurdil** | Nain | Désormais surnommé "Cul Brillant" à cause du sort de Bulle. |
|
| **Gurdil** | Nain | Désormais surnommé "Cul Brillant" à cause du sort de Bulle. |
|
||||||
| **Jinn** | Genasi | Musicien du groupe ; a payé sa chambre d'auberge en jouant. |
|
| **Jinn** | Genasi | Musicien du groupe ; a payé sa chambre d'auberge en jouant. |
|
||||||
|
|
||||||
### Personnages
|
### Personnages
|
||||||
|
|
||||||
| **Nom** | **Race / Rôle** | **Relation / Détails** |
|
| **Nom** | **Race / Rôle** | **Relation / Détails** |
|
||||||
@@ -63,17 +64,12 @@ C’est ainsi que **Gurdil**, désormais baptisé **"Cul Brillant"**, est devenu
|
|||||||
| **Ran & Zas** | Gobelins | Enfants de Tritte et Iben. |
|
| **Ran & Zas** | Gobelins | Enfants de Tritte et Iben. |
|
||||||
| **Alvin** | Gnome | Enfant du village. |
|
| **Alvin** | Gnome | Enfant du village. |
|
||||||
|
|
||||||
---
|
|
||||||
### Les légendes de Kwel le Sang-dragon
|
### Les légendes de Kwel le Sang-dragon
|
||||||
|
|
||||||
Kwel semble être une source d'informations aussi riche qu'incertaine. Voici les détails de ses récits :
|
Kwel semble être une source d'informations aussi riche qu'incertaine. Voici les détails de ses récits :
|
||||||
|
|
||||||
**Le Dragon de la Mine :** Il affirme qu'un "Dragon Infernal" vit dans la mine. Il raconte cette histoire de deux façons : dans l'une, il était enfant quand cela s'est produit, dans l'autre, il y travaillait.
|
- **Le Dragon de la Mine :** Il affirme qu'un "Dragon Infernal" vit dans la mine. Il raconte cette histoire de deux façons : dans l'une, il était enfant quand cela s'est produit, dans l'autre, il y travaillait.
|
||||||
|
- **La Fondation de l'Auberge :** Il prétend avoir bâti l'auberge lui-même avec l'aide d'un groupe d'aventuriers. Bien qu'il soit originaire du village, il loge à l'auberge.
|
||||||
**La Fondation de l'Auberge :** Il prétend avoir bâti l'auberge lui-même avec l'aide d'un groupe d'aventuriers. Bien qu'il soit originaire du village, il loge à l'auberge.
|
- **La Bataille du Grand Arbre :** Il y a plus de 1000 ans, des ogres ont attaqué la forêt. L'arbre millénaire devait être détruit, mais il a été sauvé par un groupe d'aventuriers dont Kwel prétend avoir fait partie.
|
||||||
|
- **Paradoxe Temporel :** Il affirme avoir fait partie d'aventuriers il y a un millénaire, tout en disant qu'il a lui-même moins de 1000 ans (alors que le village, lui, dépasse cet âge).
|
||||||
**La Bataille du Grand Arbre :** Il y a plus de 1000 ans, des ogres ont attaqué la forêt. L'arbre millénaire devait être détruit, mais il a été sauvé par un groupe d'aventuriers dont Kwel prétend avoir fait partie.
|
- **Connaissance des Grungs :** Il a mentionné avoir déjà croisé des membres de votre espèce (Grung) au cours de sa vie.
|
||||||
|
|
||||||
**Paradoxe Temporel :** Il affirme avoir fait partie d'aventuriers il y a un millénaire, tout en disant qu'il a lui-même moins de 1000 ans (alors que le village, lui, dépasse cet âge).
|
|
||||||
|
|
||||||
**Connaissance des Grungs :** Il a mentionné avoir déjà croisé des membres de votre espèce (Grung) au cours de sa vie.
|
|
||||||
|
|||||||
@@ -21,8 +21,6 @@ Le groupe réagit alors avec une coordination héroïque. **Gurdil** pulvérisa
|
|||||||
|
|
||||||
Le calme revenu, nous avons secouru **Jinn**. Stabilisé par Bulle et soigné par Maielan, le Génasi reprit connaissance. Nyrae se contenta d'un simple "Mouais..." laconique en croisant son regard, soulignant le poids de l'épreuve. Après s'être lui même soigné, Jinn retrouva assez de forces pour continuer. Nous avons repris la marche jusqu'au bout du couloir. Là, un **mur maçonné**, étrangement propre et hors de place, nous barrait la route. Une partie de son centre est effondrée. C'est de l'autre côté, dans ce vide inconnu, que nous entendons enfin les voix des enfants. Qu'est-ce qui a bien pu être enfermé ici ?
|
Le calme revenu, nous avons secouru **Jinn**. Stabilisé par Bulle et soigné par Maielan, le Génasi reprit connaissance. Nyrae se contenta d'un simple "Mouais..." laconique en croisant son regard, soulignant le poids de l'épreuve. Après s'être lui même soigné, Jinn retrouva assez de forces pour continuer. Nous avons repris la marche jusqu'au bout du couloir. Là, un **mur maçonné**, étrangement propre et hors de place, nous barrait la route. Une partie de son centre est effondrée. C'est de l'autre côté, dans ce vide inconnu, que nous entendons enfin les voix des enfants. Qu'est-ce qui a bien pu être enfermé ici ?
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### État du Groupe
|
### État du Groupe
|
||||||
|
|
||||||
- **Jinn :** Affaibli mais conscient (récupération en cours).
|
- **Jinn :** Affaibli mais conscient (récupération en cours).
|
||||||
|
|||||||
69
src/content/journal/sang.md
Normal file
69
src/content/journal/sang.md
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
---
|
||||||
|
title: "Le printemps sanglant"
|
||||||
|
author: "G'Mas"
|
||||||
|
publishDate: 2026-02-08
|
||||||
|
tags: ["Vampire","Enfant perdu", "Maçonnerie"]
|
||||||
|
---
|
||||||
|
|
||||||
|
## L'Ombre de Constancia
|
||||||
|
|
||||||
|
Après avoir terrassé les Krutiks, nous nous sommes enfoncés dans un conduit étroit serpentant vers le nord-est. Au bout de ce cul-de-sac de briques, un spectacle troublant nous attendait : un mur maçonné effondré, dont la facture humaine, médiocre et grossière, rappelait étrangement celle du manoir noble du village. L'expertise de **Gurdil** fut à couper le souffle ; avec le dédain propre à son peuple, il nous décrivit la pauvreté de cette construction comparée à la finesse de l'architecture naine.
|
||||||
|
|
||||||
|
Pendant ce temps, la lumière projetée par le caleçon de Gurdil étayait les parois, transformant la roche brute en véritables enluminures pour mes yeux de Grung. N'ayant jamais parcouru de tels espaces, la noirceur des cavités me révélait un monde mystérieux et fabuleux dès qu'une source de "lumière étoilée" y était introduite.
|
||||||
|
|
||||||
|
Au centre de la pièce, derrière la section effondrée, une **Eladrin** (elfe des plans féeriques) dont l'humeur reflétait la rigueur de l'hiver semblait prisonnière d'un **pentacle tracé à la poudre blanche**. Autour d'elle, les enfants disparus gisaient au sol ou erraient, proies de magies d'illusion. Pendant que l'Elfe subissait l'emprise d'une magie d'abjuration, le jeune Arengon, **Zajic**, paraissait totalement hypnotisé, selon l'analyse magique de **Bulle**.
|
||||||
|
|
||||||
|
L'Eladrin nous supplia de la libérer, prétendant être la victime d'un savant fou qui l'utilisait pour drainer ses pouvoirs héréditaires. J'essayai d'expliquer au groupe qu'il était impératif de l'endormir avant toute chose, tant l'étrangeté de la situation m'alertait.
|
||||||
|
|
||||||
|
Malgré mes doutes et ma tentative de neutraliser la menace à distance, la tension monta. Gurdil, pressé par l'urgence du sauvetage, céda aux appels insistants de la créature. En dépit de mes avertissements, fidèle à sa nature directe, asséna une gifle monumentale à un enfant pour le réveiller, provoquant l'ire immédiate de la bourgmestre. Las de mes palabres qu'il jugeait inutiles, le nain brisa d'un geste le cercle de poudre blanche au sol. Instantanément, la tristesse hivernale de l'elfe fit place à une joie printanière malveillante... et l'illusion tomba.
|
||||||
|
|
||||||
|
Une fois libérée, l'elfe révéla sa véritable nature : une **Vampire** n'ayant pas bu de sang depuis 70 ans. Le combat s'engagea immédiatement, acharné. Mon poison resta inefficace, mais **Nyrae** parvint à l'entraver avec son fouet sylvestre et un sort d'_Enchevêtrement_. **Bulle** déchaîna la foudre, un éclair foudroyant qui brûla les parures de la créature, révélant une régénération terrifiante.
|
||||||
|
|
||||||
|
Malgré son manque d'énergie apparent, la vampire fit preuve d'une expérience qui lui permettait de résister indéfiniment à nos assauts. Dans le chaos, elle utilisa son charme sur moi ; soudain, ma perception changea et je ne vis plus en elle qu'une amie à secourir, m'obligeant à baisser ma sarbacane. Le drame survint lorsqu'elle planta ses crocs dans le cou de **Nyrae** pour recouvrer sa puissance. Elle révéla alors sa véritable identité : **Constancia Denney, Chevalier de la Couronne d'Argent**.
|
||||||
|
|
||||||
|
Un portail s'ouvrit derrière elle, nous laissant quelques instants pour échanger. Une fois le charme dissipé, je revins sur la défensive et l'interrogeai sur son apparence féerique et ses liens éventuels avec l'Arbre Millénaire. Elle répondit avec dédain qu'il ne s'agissait que d'une image parmi d'autres, avant de prendre les traits de **Jean-Laurent**, le frère d'un de mes amis d'enfance. J'empêchai le groupe de la poursuivre dans le portail, affirmant avoir le pouvoir d'aller à sa rencontre par mes rêves. Elle finit par s'évanouir dans les profondeurs de sa dimension alors que le portail se refermait.
|
||||||
|
|
||||||
|
J'ai tenu à présenter mes excuses à la bourgmestre pour mes soupçons concernant une complicité du village. Elle nous assura que les villageois n'en sauraient rien ; le secret resterait entre nous, la bourgmestre et les enfants encore sous le choc.
|
||||||
|
|
||||||
|
Nous sommes sortis de la mine en héros, accueillis par le village entier. Les enfants ont rejoint les bras de leurs parents, sains et saufs, bien qu'incapables d'expliquer leurs légères blessures. À l'instant où nous avons retrouvé l'air libre, le sort de _Lumière_ s'est dissipé : le caleçon de Gurdil a cessé de briller, marquant la fin de l'ère du "Cul Brillant" (Pour l'instant).
|
||||||
|
|
||||||
|
Le village a célébré notre victoire par un festin, mais le repos fut de courte durée. Tandis que Gurdil se noyait dans la bière et que **Kwel** s'appropriait nos exploits à l'auberge, le sommeil loin d'être léger m'accueilli en son ceint pour me délivrer un message nocturne en rêve. La fée du **Grand Chêne** m'a appelé à l'aide : Ce souffle de vie si cher à mon cœur, est menacé. Dans cette vision, Nyrae et Bulle apparaissaient comme les messagères les plus aptes à communiquer avec cette force ancienne.
|
||||||
|
|
||||||
|
### 🧛 L'Entité : Constancia Denney
|
||||||
|
|
||||||
|
- **Identité :** Vampire et Chevalier de la Couronne d'Argent.
|
||||||
|
- **Métamorphose :** Elle utilise des apparences saisonnières liées à son état (Eladrin hivernale lors de son emprisonnement, joie printanière à sa libération). Elle peut également copier les traits de proches, comme Jean-Laurent.
|
||||||
|
- **Capacités :** * **Régénération :** Capacité de soin exceptionnelle, même après avoir subi la foudre de Bulle.
|
||||||
|
- **Charme :** Peut transformer un adversaire en "ami dévoué", neutralisant ainsi toute hostilité (testé sur G'mas).
|
||||||
|
- **Drain de vie :** Recouvre sa puissance en s'abreuvant de sang frais (victime : Nyrae).
|
||||||
|
- **Statut :** En fuite via un portail dimensionnel.
|
||||||
|
|
||||||
|
|
||||||
|
### 🕸️ Mécanismes & Mystères
|
||||||
|
|
||||||
|
- **Le Pentacle :** Un cercle de poudre blanche combinant des magies d'abjuration (confinement) et d'illusion (dissimulation de la véritable forme).
|
||||||
|
- **L'Incident Diplomatique :** Gurdil a rompu l'hypnose de Zajic par une gifle monumentale, créant une tension avec la Bourgmestre Maielan.
|
||||||
|
- **Le Paradoxe :** Bien que Constancia prétende que son apparence féerique était fortuite, l'appel de détresse du **Grand Chêne** a suivi immédiatement sa libération.
|
||||||
|
|
||||||
|
|
||||||
|
### 🌌 Le Souffle de Vie
|
||||||
|
|
||||||
|
- **Localisation :** Le cœur du Grand Chêne, l'arbre millénaire du village.
|
||||||
|
- **État :** Menacé par une force obscure. La fée protectrice de l'arbre a envoyé un appel au secours onirique.
|
||||||
|
- **Émissaires :** Nyrae et Bulle sont identifiées comme les vecteurs de communication prioritaires avec l'essence de l'Arbre.
|
||||||
|
|
||||||
|
### 🟢 Évolution des Aventuriers (Niveau 2)
|
||||||
|
|
||||||
|
|**Nom**|**Action Marquante**|**État**|
|
||||||
|
|---|---|---|
|
||||||
|
|**G'mas**|A tenté la diplomatie ; charmé par la vampire.|Troublé, en quête de réponses oniriques.|
|
||||||
|
|**Nyrae**|A immobilisé la vampire (Enchevêtrement) ; a subi la morsure.|Lien renforcé avec le Grand Chêne.|
|
||||||
|
|**Gurdil**|A brisé le sceau de poudre blanche.|Victorieux, en pleine gueule de bois.|
|
||||||
|
|**Bulle**|Diagnostic magique et éclair dévastateur.|Prête pour la mission féerique.|
|
||||||
|
|**Jinn**|Soutien au combat malgré la régénération de l'ennemi.|Prêt pour la suite.|
|
||||||
|
|
||||||
|
### 📋 Métadonnées
|
||||||
|
|
||||||
|
- **Lieu :** Conduit Nord-Est, Secteur Maçonné (facture humaine médiocre).
|
||||||
|
- **Atmosphère :** Noirceur totale révélée par la source lumineuse "stellaire" de Gurdil.
|
||||||
|
- **Concept-clé :** #SouffleDeVie #Niveau2 #CouronneDArgent.
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Acquis et Paradigmes d'Astro"
|
|
||||||
publishDate: 2026-01-13
|
|
||||||
tags: ["Astro", "Architecture", "Paradigmes", "Composants", "Routage", "Contenu"]
|
|
||||||
---
|
|
||||||
|
|
||||||
Ce log est une halte. Un moment pour observer le chemin parcouru, non pas comme une liste de compétences acquises, mais comme la compréhension des fondations sur lesquelles nous nous tenons. Cette version du site est une étape nécessaire : l'apprentissage des langages et des structures du web "plat", pour mieux en déceler les limites et préparer le véritable saut dans l'immersion.
|
|
||||||
|
|
||||||
### 1. L'Apprentissage du Langage des Bâtisseurs
|
|
||||||
|
|
||||||
Avant de pouvoir façonner le sable en mondes, il fallait apprendre à tailler la pierre. L'architecture actuelle repose sur les paradigmes d'Astro, qui sont ceux des bâtisseurs de la toile moderne.
|
|
||||||
|
|
||||||
* **L'Art de la Brique (`Composants Astro`)** : Nous avons appris à créer des "briques" réutilisables (`GoldButton`, `ParchmentCard`). C'est un art de l'efficacité, de la modularité. Chaque brique est autonome, avec ses propres styles. C'est puissant, mais cela nous enferme dans une logique de "boîtes" empilées les unes sur les autres.
|
|
||||||
|
|
||||||
* **Le Grimoire Ordonné (`Content Collections`)** : Nous avons appris à cataloguer nos récits et nos logs. Chaque parchemin est validé, chaque métadonnée est à sa place. C'est la sagesse de l'archiviste, qui assure l'ordre et la cohérence. Mais un livre, même magique, reste une succession de pages linéaires.
|
|
||||||
|
|
||||||
* **Les Sentiers Tracés (`Routage Dynamique`)** : Nous avons appris à tracer les chemins qui relient nos pages. De l'index du journal à un article, d'un article à sa balise. Ces chemins sont clairs, rapides, générés à l'avance. Mais ce sont des sentiers balisés sur une carte en deux dimensions, pas une exploration libre dans un monde vivant.
|
|
||||||
|
|
||||||
### 2. La Conscience des Murs Invisibles
|
|
||||||
|
|
||||||
Cette architecture modulaire, si prisée, est aussi une cage dorée. Elle nous a permis de construire vite et bien, mais elle nous a aussi forcés à penser en "pages", en "blocs", en "liens". L'immersion que permet Three.js ne peut se contenter de cela.
|
|
||||||
|
|
||||||
Le paradigme actuel est celui du **document**. On navigue d'un document à l'autre. L'ambition est de passer au paradigme de l'**espace**. Un monde unique et persistant dans lequel le contenu n'est pas une page que l'on charge, mais un objet avec lequel on interagit.
|
|
||||||
|
|
||||||
C'est ici que des logiques ont été abandonnées, non par erreur, mais par nécessité. Le menu hamburger, par exemple, est une convention du web 2D. Dans un monde 3D, la navigation pourrait être un objet dans la scène, une carte que l'on déplie, un chemin de lumière que l'on suit.
|
|
||||||
|
|
||||||
### 3. Le Prochain Pas : Façonner le Sable
|
|
||||||
|
|
||||||
Cette fondation n'est pas vaine. Elle est le sol stable sur lequel nous allons maintenant ériger un sanctuaire en trois dimensions. La prochaine grande étape n'est pas d'ajouter une fonctionnalité, mais de changer de regard.
|
|
||||||
|
|
||||||
* **Comprendre chaque grain** : Il s'agira de déconstruire. Comment une scène Three.js peut-elle devenir le "layout" principal ? Comment faire en sorte que le routage d'Astro ne recharge pas une page, mais déclenche une animation dans la scène 3D ?
|
|
||||||
|
|
||||||
* **Construire avec intention** : Chaque choix devra être conscient. Nous n'appliquerons pas des solutions toutes faites, mais nous chercherons à comprendre les principes fondamentaux de la 3D sur le web pour créer une expérience qui a du sens. Le but n'est pas de "faire" un site 3D, mais de **comprendre** comment le faire naître.
|
|
||||||
|
|
||||||
Cette étape est terminée. Le pèlerin a appris les cartes du vieux monde. Il est temps, maintenant, de les brûler pour dessiner la sienne.
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Initialisation du projet"
|
|
||||||
publishDate: 2026-01-09
|
|
||||||
tags: ["Setup", "Infrastructure", "Docker", "Raspberry Pi", "Astro"]
|
|
||||||
---
|
|
||||||
|
|
||||||
Le projet a été initialisé avec Astro. La structure de base est en place.
|
|
||||||
|
|
||||||
Le déploiement est géré par Docker et Docker Compose, ce qui permet de lancer le site sur le Raspberry Pi avec une seule commande.
|
|
||||||
### Matériel
|
|
||||||
|
|
||||||
* **Serveur** : Raspberry Pi 4 (4Go de RAM)
|
|
||||||
* **Stockage** : Disque dur externe de 2To
|
|
||||||
|
|
||||||
### Environnement Serveur
|
|
||||||
|
|
||||||
* **Système d'exploitation** : Debian
|
|
||||||
* **Conteneurisation** : Docker & Docker Compose
|
|
||||||
|
|
||||||
### Environnement de Développement
|
|
||||||
|
|
||||||
* **Système d'exploitation local** : Ubuntu
|
|
||||||
* **Framework** : Astro
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Ajout de la matière du passé"
|
|
||||||
publishDate: 2026-01-12
|
|
||||||
tags: ["Contenu", "Design", "Narratif", "Composants"]
|
|
||||||
---
|
|
||||||
|
|
||||||
Le site a été enrichi avec le contenu principal, donnant vie à l'univers narratif du projet. L'ensemble du site adopte désormais la voix et la perspective de G'Mas, le pèlerin Grung.
|
|
||||||
|
|
||||||
### Nouvelles Sections
|
|
||||||
|
|
||||||
* **Le Sanctuaire des Grains (`/atelier`)** : Présente l'arsenal technique (Three.js, Blender, Raspberry Pi) à travers la métaphore du "Kit du Pèlerin".
|
|
||||||
|
|
||||||
* **L'Observatoire des Songes (`/observatoire`)** : Partage les inspirations du projet, des œuvres de Miyazaki aux histoires des compagnons d'aventure du jeu de rôle.
|
|
||||||
|
|
||||||
* **La Boussole Éthique (`/boussole`)** : Expose la philosophie du projet, en distinguant les modèles de création vertueux (Open Source) des approches jugées néfastes.
|
|
||||||
|
|
||||||
* **Page Auteur (`/auteur`)** : Crée un pont entre le personnage (G'Mas), l'alter-ego artistique (Hatjan Krâpo) et le créateur (Nicolas Latchimy), en listant ses différents travaux et contacts.
|
|
||||||
|
|
||||||
La page d'accueil a également été mise à jour pour refléter ces ajouts via un système de cartes de présentation.
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Déconstruction pour un Nouveau Souffle"
|
|
||||||
publishDate: 2026-01-18
|
|
||||||
tags: ["Architecture", "Pivot", "Blueprint", "GSAP", "State Management"]
|
|
||||||
---
|
|
||||||
|
|
||||||
**Log de Construction #04**
|
|
||||||
|
|
||||||
**Statut :** Pivot structurel / Phase de Blueprint
|
|
||||||
|
|
||||||
**Sujet :** Abandon du modèle actuel pour la Voie du "Slide Navigator"
|
|
||||||
|
|
||||||
### 1. Le Constat du Mécanicien
|
|
||||||
|
|
||||||
Après avoir testé l'architecture actuelle, le verdict tombe : les pièces s'emboîtent, mais le moteur ne tourne pas rond. L'expérience manque de fluidité, le "souffle de vie" (Hebel) s'éparpille dans une structure trop complexe qui ne rend pas hommage à l'esthétique *Storybook* que je vise.
|
|
||||||
|
|
||||||
Vouloir construire la carrosserie avant d'avoir stabilisé le châssis est une erreur de débutant que je choisis de corriger aujourd'hui.
|
|
||||||
|
|
||||||
### 2. La Voie du "Slide Navigator"
|
|
||||||
|
|
||||||
Je décide de revenir à l'essentiel : **la narration séquentielle**. Plutôt qu'un site web classique, je vais structurer l'expérience comme une galerie interactive, un "PowerPoint 3D" où chaque vue est une étape clé de mon pèlerinage.
|
|
||||||
|
|
||||||
Ce choix s'impose pour plusieurs raisons :
|
|
||||||
* **Contrôle du Flux :** Chaque "slide" devient une scène Three.js maîtrisée (position caméra, éclairage, UI spécifique).
|
|
||||||
* **Clarté Narrative :** On ne se perd plus dans le site ; on tourne les pages d'un grimoire numérique.
|
|
||||||
* **Prototypage Rapide :** Cela me permet de valider le passage de l'écran titre au menu "Hebel", puis à la Timeline, avec la précision d'un mécanicien qui règle ses soupapes.
|
|
||||||
|
|
||||||
### 3. Prochaines Étapes (Le Blueprint)
|
|
||||||
|
|
||||||
Le chantier se concentre désormais sur le **"State Controller"**. Il s'agira de définir un tableau d'objets contenant les coordonnées de chaque scène, puis d'utiliser **GSAP** pour créer des transitions fluides entre ces "slides", simulant un voyage cinématographique. Les calques d'interface HTML resteront superposés au canvas pour garantir une accessibilité totale.
|
|
||||||
|
|
||||||
*Le grain de sable ne s'arrête pas, il change de trajectoire pour mieux dessiner l'oasis.*
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
---
|
|
||||||
title: "L'Harmonie du Souffle et du Silicium"
|
|
||||||
publishDate: 2026-01-14
|
|
||||||
tags: ["IA", "Création", "Philosophie", "Codex"]
|
|
||||||
---
|
|
||||||
|
|
||||||
J'ai d'abord vu cette chose comme un piège. Dans ma quête pour bâtir le "Codex de la Substance", je l'ai effleuré quelques fois, et le résultat m'avait glacé : un savoir sans âme, un corps sans "Hebel", ce souffle de vie qui naît de l'effort et de la découverte. Ma conclusion fut simple, presque réactionnaire : rejeter l'outil pour préserver le chemin.
|
|
||||||
|
|
||||||
Aujourd'hui, je regarde cette posture avec une nouvelle perspective. Les événements qui secouent un de ces mondes que je ne voient qu'en rêve me servent de miroir. Là-bas, la société se fracture entre les adeptes d'une production de masse sans âme et les artisans d'un rejet total, une guerre culturelle où chacun semble avoir perdu de vue l'essentiel. Ce n'est pas l'outil le problème, mais notre relation à lui.
|
|
||||||
|
|
||||||
Le rejet pur et simple est une impasse. C'est se priver d'un partenaire de danse d'une puissance inouïe. L'adoption aveugle en est une autre, menant à une uniformisation stérile.
|
|
||||||
|
|
||||||
### Forger une Troisième Voie
|
|
||||||
|
|
||||||
La véritable voie est celle de l'harmonie. L'IA ne doit pas être une usine qui remplace le créateur, ni un simple outil que l'on brandit. Elle doit devenir une extension de notre intention, un instrument accordé à notre propre souffle.
|
|
||||||
|
|
||||||
Mon rôle n'est pas de tout écrire à la main par principe, mais de devenir le chef d'orchestre. Je fournis l'intention, la "Vision", la question fondamentale. L'IA, elle, explore les possibles, génère la "Mécanique", propose des formes et des structures à une vitesse surhumaine. Mon travail se déplace : de celui qui taille chaque pierre à celui qui dessine le plan de la cathédrale et insuffle son âme dans l'édifice.
|
|
||||||
|
|
||||||
Le Codex ne sera donc pas le journal d'un ermite, mais le témoignage d'une collaboration. Chaque carte sera le fruit d'un dialogue entre le souffle et le silicium. Le chemin sera différent, ni plus court, ni plus long. Il sera simplement plus riche, car il explorera des territoires que je n'aurais jamais pu arpenter seul.
|
|
||||||
|
|
||||||
Il ne s'agit plus de se méfier de la machine, mais d'apprendre à créer *avec* elle, en harmonie.
|
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
---
|
---
|
||||||
import { ClientRouter } from 'astro:transitions';
|
import { ClientRouter } from "astro:transitions";
|
||||||
import GameNav from '../components/ui/GameNav.astro';
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
title: string;
|
title: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { title } = Astro.props;
|
const { title } = Astro.props;
|
||||||
@@ -11,271 +10,303 @@ const { title } = Astro.props;
|
|||||||
|
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="fr">
|
<html lang="fr">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="description" content="Clone de AFK Journey avec Astro et Three.js" />
|
<meta
|
||||||
<meta name="viewport" content="width=device-width" initial-scale=1 />
|
name="description"
|
||||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
content="Clone de AFK Journey avec Astro et Three.js"
|
||||||
<meta name="generator" content={Astro.generator} />
|
/>
|
||||||
<title>{title}</title>
|
<meta name="viewport" content="width=device-width" initial-scale="1" />
|
||||||
<ClientRouter />
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||||
</head>
|
<meta name="generator" content={Astro.generator} />
|
||||||
<body>
|
<title>{title}</title>
|
||||||
<main>
|
<ClientRouter />
|
||||||
<slot />
|
</head>
|
||||||
</main>
|
<body>
|
||||||
<GameNav />
|
<main>
|
||||||
</body>
|
<slot />
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
<style is:global>
|
<style is:global>
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Cinzel:wght@700&family=EB+Garamond&display=swap');
|
@import url("https://fonts.googleapis.com/css2?family=Cinzel:wght@700&family=EB+Garamond&display=swap");
|
||||||
|
|
||||||
html {
|
html {
|
||||||
background-color: #fdf6e8; /* Ton crème/parchemin */
|
background-color: #fdf6e8; /* Ton crème/parchemin */
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
/* La couleur de fond est maintenant sur l'élément HTML */
|
/* La couleur de fond est maintenant sur l'élément HTML */
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
color: #4a4a4a;
|
color: #4a4a4a;
|
||||||
font-family: 'EB Garamond', serif;
|
font-family: "EB Garamond", serif;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
/* Ajout d'un padding en bas pour ne pas que la nav masque le contenu */
|
/* Ajout d'un padding en bas pour ne pas que la nav masque le contenu */
|
||||||
padding: 2rem 2rem 100px 2rem;
|
padding: 2rem 2rem 100px 2rem;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Applique une texture de grain de papier en arrière-plan */
|
/* Applique une texture de grain de papier en arrière-plan */
|
||||||
body::before {
|
body::before {
|
||||||
content: '';
|
content: "";
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0; left: 0;
|
top: 0;
|
||||||
width: 100%; height: 100%;
|
left: 0;
|
||||||
/* Assurez-vous d'avoir une image de texture dans public/textures/ */
|
width: 100%;
|
||||||
background-image: url('/textures/paper-grain.png');
|
height: 100%;
|
||||||
opacity: 0.5; /* J'augmente l'opacité pour qu'elle soit bien visible */
|
/* Assurez-vous d'avoir une image de texture dans public/textures/ */
|
||||||
|
background-image: url("/textures/paper-grain.png");
|
||||||
|
opacity: 0.5; /* J'augmente l'opacité pour qu'elle soit bien visible */
|
||||||
|
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --- Styles des Titres --- */
|
/* --- Styles des Titres --- */
|
||||||
h1, h2 {
|
h1,
|
||||||
font-family: 'Cinzel', serif;
|
h2 {
|
||||||
text-align: center;
|
font-family: "Cinzel", serif;
|
||||||
color: #3a352a; /* Une couleur de texte sombre pour un bon contraste */
|
text-align: center;
|
||||||
margin-bottom: 2rem; /* Espace après l'ornement */
|
color: #3a352a; /* Une couleur de texte sombre pour un bon contraste */
|
||||||
}
|
margin-bottom: 2rem; /* Espace après l'ornement */
|
||||||
|
}
|
||||||
|
|
||||||
/* Ajoute un ornement doré sous les titres */
|
/* Ajoute un ornement doré sous les titres */
|
||||||
h1::after, h2::after {
|
h1::after,
|
||||||
content: '';
|
h2::after {
|
||||||
display: block;
|
content: "";
|
||||||
width: 100px; /* Largeur de l'ornement */
|
display: block;
|
||||||
height: 2px;
|
width: 100px; /* Largeur de l'ornement */
|
||||||
background: linear-gradient(90deg, transparent, #c89b3c, transparent); /* Dégradé doré */
|
height: 2px;
|
||||||
margin: 0.75rem auto 0; /* Espace entre le texte et l'ornement */
|
background: linear-gradient(
|
||||||
opacity: 0.8;
|
90deg,
|
||||||
/* Animation pour "dessiner" la ligne */
|
transparent,
|
||||||
transform: scaleX(0);
|
#c89b3c,
|
||||||
animation: drawLine 1s cubic-bezier(0.22, 1, 0.36, 1) 0.3s forwards;
|
transparent
|
||||||
}
|
); /* Dégradé doré */
|
||||||
|
margin: 0.75rem auto 0; /* Espace entre le texte et l'ornement */
|
||||||
|
opacity: 0.8;
|
||||||
|
/* Animation pour "dessiner" la ligne */
|
||||||
|
transform: scaleX(0);
|
||||||
|
animation: drawLine 1s cubic-bezier(0.22, 1, 0.36, 1) 0.3s forwards;
|
||||||
|
}
|
||||||
|
|
||||||
/* On peut différencier légèrement le h2 */
|
/* On peut différencier légèrement le h2 */
|
||||||
h2 {
|
h2 {
|
||||||
font-size: 1.8rem;
|
font-size: 1.8rem;
|
||||||
color: #4a4130;
|
color: #4a4130;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --- Styles pour le contenu Markdown (.prose) --- */
|
/* --- Styles pour le contenu Markdown (.prose) --- */
|
||||||
.prose h3 {
|
.prose h3 {
|
||||||
font-family: 'Cinzel', serif;
|
font-family: "Cinzel", serif;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
border-bottom: 1px solid #dcd0b9;
|
border-bottom: 1px solid #dcd0b9;
|
||||||
padding-bottom: 0.5rem;
|
padding-bottom: 0.5rem;
|
||||||
margin-top: 2.5rem;
|
margin-top: 2.5rem;
|
||||||
}
|
}
|
||||||
/* On retire l'ornement pour les h3 */
|
/* On retire l'ornement pour les h3 */
|
||||||
.prose h3::after {
|
.prose h3::after {
|
||||||
content: none;
|
content: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.prose p {
|
.prose p {
|
||||||
line-height: 1.7;
|
line-height: 1.7;
|
||||||
font-size: 1.1rem;
|
font-size: 1.1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.parchment-card a {
|
.parchment-card a {
|
||||||
color: #c89b3c; /* Or vif */
|
color: #c89b3c; /* Or vif */
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
transition: color 0.2s;
|
transition: color 0.2s;
|
||||||
}
|
}
|
||||||
.parchment-card a:hover {
|
.parchment-card a:hover {
|
||||||
filter: brightness(1.2);
|
filter: brightness(1.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.prose ul {
|
.prose ul {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
padding-left: 1rem;
|
padding-left: 1rem;
|
||||||
}
|
}
|
||||||
.prose ul li::before {
|
.prose ul li::before {
|
||||||
content: '•';
|
content: "•";
|
||||||
color: #c89b3c;
|
color: #c89b3c;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 1em;
|
width: 1em;
|
||||||
margin-left: -1em;
|
margin-left: -1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.prose hr {
|
.prose hr {
|
||||||
border: 0;
|
border: 0;
|
||||||
height: 2px;
|
height: 2px;
|
||||||
background: linear-gradient(90deg, transparent, #c89b3c, transparent);
|
background: linear-gradient(90deg, transparent, #c89b3c, transparent);
|
||||||
margin: 3rem 0;
|
margin: 3rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.prose table {
|
.prose table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
margin: 2rem 0;
|
margin: 2rem 0;
|
||||||
}
|
}
|
||||||
.prose th, .prose td {
|
.prose th,
|
||||||
padding: 0.75rem;
|
.prose td {
|
||||||
text-align: left;
|
padding: 0.75rem;
|
||||||
border-bottom: 1px solid #dcd0b9; /* Ligne de séparation parchemin */
|
text-align: left;
|
||||||
}
|
border-bottom: 1px solid #dcd0b9; /* Ligne de séparation parchemin */
|
||||||
.prose th {
|
}
|
||||||
font-family: 'Cinzel', serif;
|
.prose th {
|
||||||
background-color: rgba(253, 246, 232, 0.5); /* Fond de cellule plus clair */
|
font-family: "Cinzel", serif;
|
||||||
}
|
background-color: rgba(
|
||||||
|
253,
|
||||||
|
246,
|
||||||
|
232,
|
||||||
|
0.5
|
||||||
|
); /* Fond de cellule plus clair */
|
||||||
|
}
|
||||||
|
|
||||||
/* --- Styles pour GoldButton --- */
|
/* --- Styles pour GoldButton --- */
|
||||||
.gold-button {
|
.gold-button {
|
||||||
background: linear-gradient(145deg, #fefbf3, #f8f1e4); /* Dégradé parchemin clair */
|
background: linear-gradient(
|
||||||
border: 2px solid #c89b3c;
|
145deg,
|
||||||
border-radius: 15px;
|
#fefbf3,
|
||||||
color: #4a4130; /* Texte sombre pour le contraste */
|
#f8f1e4
|
||||||
padding: 1.5rem;
|
); /* Dégradé parchemin clair */
|
||||||
text-align: center;
|
border: 2px solid #c89b3c;
|
||||||
text-decoration: none;
|
border-radius: 15px;
|
||||||
transition: all 0.3s ease;
|
color: #4a4130; /* Texte sombre pour le contraste */
|
||||||
display: block;
|
padding: 1.5rem;
|
||||||
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1), inset 0 0 5px rgba(200, 155, 60, 0.1);
|
text-align: center;
|
||||||
}
|
text-decoration: none;
|
||||||
.gold-button:hover {
|
transition: all 0.3s ease;
|
||||||
transform: translateY(-5px);
|
display: block;
|
||||||
filter: brightness(1.05);
|
box-shadow:
|
||||||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15), inset 0 0 10px rgba(200, 155, 60, 0.2);
|
0 4px 15px rgba(0, 0, 0, 0.1),
|
||||||
border-color: #f0e6d2;
|
inset 0 0 5px rgba(200, 155, 60, 0.1);
|
||||||
}
|
}
|
||||||
.gold-button .title { /* Ciblage plus spécifique */
|
.gold-button:hover {
|
||||||
font-family: 'Cinzel', serif;
|
transform: translateY(-5px);
|
||||||
font-size: 1.5rem;
|
filter: brightness(1.05);
|
||||||
color: #b8860b; /* Titre en couleur or */
|
box-shadow:
|
||||||
margin-bottom: 0.5rem;
|
0 8px 25px rgba(0, 0, 0, 0.15),
|
||||||
}
|
inset 0 0 10px rgba(200, 155, 60, 0.2);
|
||||||
.gold-button .body { /* Ciblage plus spécifique */
|
border-color: #f0e6d2;
|
||||||
font-family: 'EB Garamond', serif;
|
}
|
||||||
font-size: 1rem;
|
.gold-button .title {
|
||||||
color: #4a4130; /* Texte sombre pour le contraste */
|
/* Ciblage plus spécifique */
|
||||||
}
|
font-family: "Cinzel", serif;
|
||||||
.card-grid {
|
font-size: 1.5rem;
|
||||||
display: flex;
|
color: #b8860b; /* Titre en couleur or */
|
||||||
flex-wrap: wrap;
|
margin-bottom: 0.5rem;
|
||||||
justify-content: center;
|
}
|
||||||
gap: 2rem;
|
.gold-button .body {
|
||||||
padding: 0;
|
/* Ciblage plus spécifique */
|
||||||
margin: 0;
|
font-family: "EB Garamond", serif;
|
||||||
}
|
font-size: 1rem;
|
||||||
|
color: #4a4130; /* Texte sombre pour le contraste */
|
||||||
|
}
|
||||||
|
.card-grid {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 2rem;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* --- Styles pour les Tags --- */
|
/* --- Styles pour les Tags --- */
|
||||||
.tags-container {
|
.tags-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
margin-bottom: 2rem;
|
margin-bottom: 2rem;
|
||||||
}
|
}
|
||||||
.tag {
|
.tag {
|
||||||
background-color: rgba(200, 155, 60, 0.2);
|
background-color: rgba(200, 155, 60, 0.2);
|
||||||
color: #b8860b;
|
color: #b8860b;
|
||||||
padding: 0.25rem 0.75rem;
|
padding: 0.25rem 0.75rem;
|
||||||
border-radius: 15px;
|
border-radius: 15px;
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
font-family: 'Cinzel', serif;
|
font-family: "Cinzel", serif;
|
||||||
border: 1px solid rgba(200, 155, 60, 0.3);
|
border: 1px solid rgba(200, 155, 60, 0.3);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
}
|
}
|
||||||
.tag:hover {
|
.tag:hover {
|
||||||
background-color: #c89b3c;
|
background-color: #c89b3c;
|
||||||
color: #2c2a24;
|
color: #2c2a24;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Keyframes pour l'animation de l'ornement */
|
/* Keyframes pour l'animation de l'ornement */
|
||||||
@keyframes drawLine {
|
@keyframes drawLine {
|
||||||
from {
|
from {
|
||||||
transform: scaleX(0);
|
transform: scaleX(0);
|
||||||
}
|
}
|
||||||
to {
|
to {
|
||||||
transform: scaleX(1);
|
transform: scaleX(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Animation pour la nouvelle page (le "pop-up") */
|
/* Animation pour la nouvelle page (le "pop-up") */
|
||||||
@keyframes slide-in {
|
@keyframes slide-in {
|
||||||
from {
|
from {
|
||||||
transform: translateY(15%) scale(0.95);
|
transform: translateY(15%) scale(0.95);
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
to {
|
to {
|
||||||
transform: translateY(0) scale(1);
|
transform: translateY(0) scale(1);
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Animation pour l'ancienne page qui disparaît */
|
/* Animation pour l'ancienne page qui disparaît */
|
||||||
@keyframes fade-out {
|
@keyframes fade-out {
|
||||||
from { opacity: 1; }
|
from {
|
||||||
to { opacity: 0; }
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
to {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* On applique nos animations aux pseudo-éléments de View Transitions */
|
/* On applique nos animations aux pseudo-éléments de View Transitions */
|
||||||
::view-transition-new(root) {
|
::view-transition-new(root) {
|
||||||
animation: 0.4s cubic-bezier(0.22, 1, 0.36, 1) 0s 1 normal both running slide-in;
|
animation: 0.4s cubic-bezier(0.22, 1, 0.36, 1) 0s 1 normal both running
|
||||||
}
|
slide-in;
|
||||||
|
}
|
||||||
|
|
||||||
::view-transition-old(root) {
|
::view-transition-old(root) {
|
||||||
animation: 0.2s ease-out 0s 1 normal both running fade-out;
|
animation: 0.2s ease-out 0s 1 normal both running fade-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --- Ajustements pour les écrans mobiles --- */
|
/* --- Ajustements pour les écrans mobiles --- */
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
body {
|
body {
|
||||||
padding: 1.5rem 1rem 100px 1rem; /* Réduction du padding latéral */
|
padding: 1.5rem 1rem 100px 1rem; /* Réduction du padding latéral */
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 2rem; /* Réduction de la taille des titres principaux */
|
font-size: 2rem; /* Réduction de la taille des titres principaux */
|
||||||
}
|
}
|
||||||
|
|
||||||
.parchment-card {
|
.parchment-card {
|
||||||
padding: 1.5rem; /* Moins de padding dans les cartes */
|
padding: 1.5rem; /* Moins de padding dans les cartes */
|
||||||
}
|
}
|
||||||
|
|
||||||
.gold-button {
|
.gold-button {
|
||||||
padding: 1rem; /* Boutons moins hauts */
|
padding: 1rem; /* Boutons moins hauts */
|
||||||
}
|
}
|
||||||
|
|
||||||
.gold-button .title {
|
.gold-button .title {
|
||||||
font-size: 1.2rem; /* Titres des boutons plus petits */
|
font-size: 1.2rem; /* Titres des boutons plus petits */
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-grid {
|
.card-grid {
|
||||||
gap: 1rem; /* Moins d'espace entre les cartes */
|
gap: 1rem; /* Moins d'espace entre les cartes */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,39 +0,0 @@
|
|||||||
---
|
|
||||||
import {ClientRouter} from 'astro:transitions';
|
|
||||||
import '../styles/global.css';
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
title: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { title } = Astro.props;
|
|
||||||
---
|
|
||||||
|
|
||||||
<!doctype html>
|
|
||||||
<html lang="fr">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta name="description" content="Le journal de bord de l'artisan." />
|
|
||||||
<meta name="viewport" content="width=device-width" />
|
|
||||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
||||||
<meta name="generator" content={Astro.generator} />
|
|
||||||
<title>{title}</title>
|
|
||||||
<ClientRouter />
|
|
||||||
</head>
|
|
||||||
<body class="bg-slate-100 text-slate-800 font-sans">
|
|
||||||
<main class="max-w-3xl mx-auto p-4 sm:p-8">
|
|
||||||
<header class="mb-8 text-center">
|
|
||||||
<a href="/bujo" class="text-2xl font-bold text-slate-900 hover:text-blue-700 transition-colors duration-300">
|
|
||||||
Journal de Bord
|
|
||||||
</a>
|
|
||||||
<p class="text-slate-500">Le codex de la vie de l'artisan.</p>
|
|
||||||
</header>
|
|
||||||
<div class="bg-white rounded-lg shadow-md p-6 sm:p-8">
|
|
||||||
<slot />
|
|
||||||
</div>
|
|
||||||
<footer class="text-center mt-12 text-sm text-slate-400">
|
|
||||||
<a href="/auteur" class="hover:text-slate-600">Retour à la page Auteur</a>
|
|
||||||
</footer>
|
|
||||||
</main>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Daily Log - 21 Janvier 2026"
|
|
||||||
publishDate: 2026-01-21
|
|
||||||
tags: ["Daily", "Work", "Organisation"]
|
|
||||||
---
|
|
||||||
import Key from '~/components/bujo/Key.astro';
|
|
||||||
|
|
||||||
<div class="mb-8 p-4 bg-blue-50 border-l-4 border-blue-400">
|
|
||||||
<h2 class="text-xl font-bold text-slate-800 mb-2"><Key symbol="⚓" /> Ancrage & Bien-être</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Routine du matin (douche, dents...)</li>
|
|
||||||
<li><Key symbol="•" /> Activité physique douce (étirements, marche...)</li>
|
|
||||||
<li><Key symbol="–" /> Qualité du sommeil (1-5) : __</li>
|
|
||||||
<li><Key symbol="–" /> Humeur du jour (1-5) : __</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="*" /> Priorités du Jour (Pro & Perso)</h2>
|
|
||||||
<p class="text-sm text-slate-500 mb-3">Se concentrer sur 1 à 3 tâches essentielles pour avancer.</p>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> [Tâche pro n°1]</li>
|
|
||||||
<li><Key symbol="•" /> [Tâche pro n°2]</li>
|
|
||||||
<li><Key symbol="•" /> [Tâche perso importante]</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="$" /> Organisation & Budget</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Planifier le repas du soir</li>
|
|
||||||
<li><Key symbol="👁️" /> Point rapide sur les comptes</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="•" /> Foyer & Routine du soir</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Ranger l'espace de travail (5 min)</li>
|
|
||||||
<li><Key symbol="•" /> Préparer les affaires pour demain</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="♡" /> Loisirs & Note du jour</h2>
|
|
||||||
<p class="text-slate-600 mt-2">Un moment pour soi, une pensée, une petite victoire :</p>
|
|
||||||
<textarea id="daily-note-21" class="w-full mt-2 p-2 border rounded bg-slate-50" rows="2" placeholder="..."></textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script is:inline>
|
|
||||||
{`
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
|
||||||
const textarea = document.getElementById('daily-note-21');
|
|
||||||
const storageKey = 'note-/bujo/2026/01/21';
|
|
||||||
const savedNote = localStorage.getItem(storageKey);
|
|
||||||
if (savedNote) textarea.value = savedNote;
|
|
||||||
textarea.addEventListener('input', () => localStorage.setItem(storageKey, textarea.value));
|
|
||||||
});
|
|
||||||
`}
|
|
||||||
</script>
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Daily Log - 22 Janvier 2026"
|
|
||||||
publishDate: 2026-01-22
|
|
||||||
tags: ["Daily", "Work", "Organisation"]
|
|
||||||
---
|
|
||||||
import Key from '~/components/bujo/Key.astro';
|
|
||||||
|
|
||||||
<div class="mb-8 p-4 bg-blue-50 border-l-4 border-blue-400">
|
|
||||||
<h2 class="text-xl font-bold text-slate-800 mb-2"><Key symbol="⚓" /> Ancrage & Bien-être</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Routine du matin (douche, dents...)</li>
|
|
||||||
<li><Key symbol="•" /> Activité physique douce (étirements, marche...)</li>
|
|
||||||
<li><Key symbol="–" /> Qualité du sommeil (1-5) : __</li>
|
|
||||||
<li><Key symbol="–" /> Humeur du jour (1-5) : __</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="*" /> Priorités du Jour (Pro & Perso)</h2>
|
|
||||||
<p class="text-sm text-slate-500 mb-3">Se concentrer sur 1 à 3 tâches essentielles pour avancer.</p>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> [Tâche pro n°1]</li>
|
|
||||||
<li><Key symbol="•" /> [Tâche pro n°2]</li>
|
|
||||||
<li><Key symbol="•" /> [Tâche perso importante]</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="$" /> Organisation & Budget</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Planifier le repas du soir</li>
|
|
||||||
<li><Key symbol="👁️" /> Point rapide sur les comptes</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="•" /> Foyer & Routine du soir</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Ranger l'espace de travail (5 min)</li>
|
|
||||||
<li><Key symbol="•" /> Préparer les affaires pour demain</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="♡" /> Loisirs & Note du jour</h2>
|
|
||||||
<p class="text-slate-600 mt-2">Un moment pour soi, une pensée, une petite victoire :</p>
|
|
||||||
<textarea id="daily-note-22" class="w-full mt-2 p-2 border rounded bg-slate-50" rows="2" placeholder="..."></textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script is:inline>
|
|
||||||
{`
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
|
||||||
const textarea = document.getElementById('daily-note-22');
|
|
||||||
const storageKey = 'note-/bujo/2026/01/22';
|
|
||||||
const savedNote = localStorage.getItem(storageKey);
|
|
||||||
if (savedNote) textarea.value = savedNote;
|
|
||||||
textarea.addEventListener('input', () => localStorage.setItem(storageKey, textarea.value));
|
|
||||||
});
|
|
||||||
`}
|
|
||||||
</script>
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Daily Log - 23 Janvier 2026"
|
|
||||||
publishDate: 2026-01-23
|
|
||||||
tags: ["Daily", "Work", "Organisation"]
|
|
||||||
---
|
|
||||||
import Key from '~/components/bujo/Key.astro';
|
|
||||||
|
|
||||||
<div class="mb-8 p-4 bg-blue-50 border-l-4 border-blue-400">
|
|
||||||
<h2 class="text-xl font-bold text-slate-800 mb-2"><Key symbol="⚓" /> Ancrage & Bien-être</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Routine du matin (douche, dents...)</li>
|
|
||||||
<li><Key symbol="•" /> Activité physique douce (étirements, marche...)</li>
|
|
||||||
<li><Key symbol="–" /> Qualité du sommeil (1-5) : __</li>
|
|
||||||
<li><Key symbol="–" /> Humeur du jour (1-5) : __</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="*" /> Priorités du Jour (Pro & Perso)</h2>
|
|
||||||
<p class="text-sm text-slate-500 mb-3">Se concentrer sur 1 à 3 tâches essentielles pour avancer.</p>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> [Tâche pro n°1]</li>
|
|
||||||
<li><Key symbol="•" /> [Tâche pro n°2]</li>
|
|
||||||
<li><Key symbol="•" /> [Tâche perso importante]</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="$" /> Organisation & Budget</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Planifier le repas du soir</li>
|
|
||||||
<li><Key symbol="👁️" /> Point rapide sur les comptes</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="•" /> Foyer & Routine du soir</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Ranger l'espace de travail (5 min)</li>
|
|
||||||
<li><Key symbol="•" /> Préparer les affaires pour demain</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="♡" /> Loisirs & Note du jour</h2>
|
|
||||||
<p class="text-slate-600 mt-2">Un moment pour soi, une pensée, une petite victoire :</p>
|
|
||||||
<textarea id="daily-note-23" class="w-full mt-2 p-2 border rounded bg-slate-50" rows="2" placeholder="..."></textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script is:inline>
|
|
||||||
{`
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
|
||||||
const textarea = document.getElementById('daily-note-23');
|
|
||||||
const storageKey = 'note-/bujo/2026/01/23';
|
|
||||||
const savedNote = localStorage.getItem(storageKey);
|
|
||||||
if (savedNote) textarea.value = savedNote;
|
|
||||||
textarea.addEventListener('input', () => localStorage.setItem(storageKey, textarea.value));
|
|
||||||
});
|
|
||||||
`}
|
|
||||||
</script>
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Daily Log - 24 Janvier 2026"
|
|
||||||
publishDate: 2026-01-24
|
|
||||||
tags: ["Daily", "Weekend", "Organisation"]
|
|
||||||
---
|
|
||||||
import Key from '~/components/bujo/Key.astro';
|
|
||||||
|
|
||||||
<div class="mb-8 p-4 bg-blue-50 border-l-4 border-blue-400">
|
|
||||||
<h2 class="text-xl font-bold text-slate-800 mb-2"><Key symbol="⚓" /> Ancrage & Bien-être</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Routine du matin (douche, dents...)</li>
|
|
||||||
<li><Key symbol="•" /> Activité physique douce (étirements, marche...)</li>
|
|
||||||
<li><Key symbol="–" /> Qualité du sommeil (1-5) : __</li>
|
|
||||||
<li><Key symbol="–" /> Humeur du jour (1-5) : __</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="*" /> Objectifs du Samedi</h2>
|
|
||||||
<p class="text-sm text-slate-500 mb-3">Une ou deux choses pour profiter de la journée et se sentir bien.</p>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> [Objectif principal]</li>
|
|
||||||
<li><Key symbol="•" /> [Autre petite tâche]</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="•" /> Foyer & Organisation</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Session de rangement (15 min)</li>
|
|
||||||
<li><Key symbol="•" /> Tâche ménagère au choix (lessive, vaisselle...)</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="♡" /> Loisirs & Note du jour</h2>
|
|
||||||
<p class="text-slate-600 mt-2">Un moment pour soi, une pensée, une petite victoire :</p>
|
|
||||||
<textarea id="daily-note-24" class="w-full mt-2 p-2 border rounded bg-slate-50" rows="2" placeholder="..."></textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script is:inline>
|
|
||||||
{`
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
|
||||||
const textarea = document.getElementById('daily-note-24');
|
|
||||||
const storageKey = 'note-/bujo/2026/01/24';
|
|
||||||
const savedNote = localStorage.getItem(storageKey);
|
|
||||||
if (savedNote) textarea.value = savedNote;
|
|
||||||
textarea.addEventListener('input', () => localStorage.setItem(storageKey, textarea.value));
|
|
||||||
});
|
|
||||||
`}
|
|
||||||
</script>
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Daily Log - 25 Janvier 2026"
|
|
||||||
publishDate: 2026-01-25
|
|
||||||
tags: ["Daily", "Weekend", "Organisation"]
|
|
||||||
---
|
|
||||||
import Key from '~/components/bujo/Key.astro';
|
|
||||||
|
|
||||||
<div class="mb-8 p-4 bg-blue-50 border-l-4 border-blue-400">
|
|
||||||
<h2 class="text-xl font-bold text-slate-800 mb-2"><Key symbol="⚓" /> Ancrage & Bien-être</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Routine du matin (douche, dents...)</li>
|
|
||||||
<li><Key symbol="•" /> Activité physique douce (étirements, marche...)</li>
|
|
||||||
<li><Key symbol="–" /> Qualité du sommeil (1-5) : __</li>
|
|
||||||
<li><Key symbol="–" /> Humeur du jour (1-5) : __</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="*" /> Objectifs du Dimanche</h2>
|
|
||||||
<p class="text-sm text-slate-500 mb-3">Une ou deux choses pour profiter de la journée et se sentir bien.</p>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> [Objectif principal]</li>
|
|
||||||
<li><Key symbol="•" /> [Autre petite tâche]</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="$" /> Organisation & Budget</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Planifier les repas de la semaine à venir</li>
|
|
||||||
<li><Key symbol="👁️" /> Chercher une activité gratuite ou un bon plan</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="•" /> Foyer & Préparation de la semaine</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Session de rangement (15 min)</li>
|
|
||||||
<li><Key symbol="•" /> Préparer les vêtements pour lundi</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="♡" /> Loisirs & Note du jour</h2>
|
|
||||||
<p class="text-slate-600 mt-2">Un moment pour soi, une pensée, une petite victoire :</p>
|
|
||||||
<textarea id="daily-note-25" class="w-full mt-2 p-2 border rounded bg-slate-50" rows="2" placeholder="..."></textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script is:inline>
|
|
||||||
{`
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
|
||||||
const textarea = document.getElementById('daily-note-25');
|
|
||||||
const storageKey = 'note-/bujo/2026/01/25';
|
|
||||||
const savedNote = localStorage.getItem(storageKey);
|
|
||||||
if (savedNote) textarea.value = savedNote;
|
|
||||||
textarea.addEventListener('input', () => localStorage.setItem(storageKey, textarea.value));
|
|
||||||
});
|
|
||||||
`}
|
|
||||||
</script>
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Daily Log - 25 Janvier 2026"
|
|
||||||
publishDate: 2026-01-25
|
|
||||||
tags: ["Daily", "Weekend", "Organisation"]
|
|
||||||
---
|
|
||||||
import Key from '~/components/bujo/Key.astro';
|
|
||||||
|
|
||||||
<div class="mb-8 p-4 bg-blue-50 border-l-4 border-blue-400">
|
|
||||||
<h2 class="text-xl font-bold text-slate-800 mb-2"><Key symbol="⚓" /> Ancrage & Bien-être</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Routine du matin (douche, dents...)</li>
|
|
||||||
<li><Key symbol="•" /> Activité physique douce (étirements, marche...)</li>
|
|
||||||
<li><Key symbol="–" /> Qualité du sommeil (1-5) : __</li>
|
|
||||||
<li><Key symbol="–" /> Humeur du jour (1-5) : __</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="*" /> Objectifs du Dimanche</h2>
|
|
||||||
<p class="text-sm text-slate-500 mb-3">Une ou deux choses pour profiter de la journée et se sentir bien.</p>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> [Objectif principal]</li>
|
|
||||||
<li><Key symbol="•" /> [Autre petite tâche]</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="$" /> Organisation & Budget</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Planifier les repas de la semaine à venir</li>
|
|
||||||
<li><Key symbol="👁️" /> Chercher une activité gratuite ou un bon plan</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="•" /> Foyer & Préparation de la semaine</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Session de rangement (15 min)</li>
|
|
||||||
<li><Key symbol="•" /> Préparer les vêtements pour lundi</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="♡" /> Loisirs & Note du jour</h2>
|
|
||||||
<p class="text-slate-600 mt-2">Un moment pour soi, une pensée, une petite victoire :</p>
|
|
||||||
<textarea id="daily-note-25" class="w-full mt-2 p-2 border rounded bg-slate-50" rows="2" placeholder="..."></textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script is:inline>
|
|
||||||
{`
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
|
||||||
const textarea = document.getElementById('daily-note-25');
|
|
||||||
const storageKey = 'note-/bujo/2026/01/25';
|
|
||||||
const savedNote = localStorage.getItem(storageKey);
|
|
||||||
if (savedNote) textarea.value = savedNote;
|
|
||||||
textarea.addEventListener('input', () => localStorage.setItem(storageKey, textarea.value));
|
|
||||||
});
|
|
||||||
`}
|
|
||||||
</script>
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Daily Log - 22 Janvier 2026"
|
|
||||||
publishDate: 2026-01-22
|
|
||||||
tags: ["Daily", "Work", "Organisation"]
|
|
||||||
---
|
|
||||||
import Key from '~/components/bujo/Key.astro';
|
|
||||||
|
|
||||||
<div class="mb-8 p-4 bg-blue-50 border-l-4 border-blue-400">
|
|
||||||
<h2 class="text-xl font-bold text-slate-800 mb-2"><Key symbol="⚓" /> Ancrage & Bien-être</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Routine du matin (douche, dents...)</li>
|
|
||||||
<li><Key symbol="•" /> Activité physique douce (étirements, marche...)</li>
|
|
||||||
<li><Key symbol="–" /> Qualité du sommeil (1-5) : __</li>
|
|
||||||
<li><Key symbol="–" /> Humeur du jour (1-5) : __</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="*" /> Priorités du Jour (Pro & Perso)</h2>
|
|
||||||
<p class="text-sm text-slate-500 mb-3">Se concentrer sur 1 à 3 tâches essentielles pour avancer.</p>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> [Tâche pro n°1]</li>
|
|
||||||
<li><Key symbol="•" /> [Tâche pro n°2]</li>
|
|
||||||
<li><Key symbol="•" /> [Tâche perso importante]</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="$" /> Organisation & Budget</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Planifier le repas du soir</li>
|
|
||||||
<li><Key symbol="👁️" /> Point rapide sur les comptes</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="•" /> Foyer & Routine du soir</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Ranger l'espace de travail (5 min)</li>
|
|
||||||
<li><Key symbol="•" /> Préparer les affaires pour demain</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="♡" /> Loisirs & Note du jour</h2>
|
|
||||||
<p class="text-slate-600 mt-2">Un moment pour soi, une pensée, une petite victoire :</p>
|
|
||||||
<textarea id="daily-note-22" class="w-full mt-2 p-2 border rounded bg-slate-50" rows="2" placeholder="..."></textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script is:inline>
|
|
||||||
{`
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
|
||||||
const textarea = document.getElementById('daily-note-22');
|
|
||||||
const storageKey = 'note-/bujo/2026/01/22';
|
|
||||||
const savedNote = localStorage.getItem(storageKey);
|
|
||||||
if (savedNote) textarea.value = savedNote;
|
|
||||||
textarea.addEventListener('input', () => localStorage.setItem(storageKey, textarea.value));
|
|
||||||
});
|
|
||||||
`}
|
|
||||||
</script>
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Daily Log - 19 Janvier 2026"
|
|
||||||
publishDate: 2026-01-19
|
|
||||||
tags: ["Daily", "Work", "Organisation"]
|
|
||||||
---
|
|
||||||
import Key from '~/components/bujo/Key.astro';
|
|
||||||
|
|
||||||
<div class="mb-8 p-4 bg-blue-50 border-l-4 border-blue-400">
|
|
||||||
<h2 class="text-xl font-bold text-slate-800 mb-2"><Key symbol="⚓" /> Ancrage & Bien-être</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Routine du matin (douche, dents...)</li>
|
|
||||||
<li><Key symbol="•" /> Activité physique douce (étirements, marche...)</li>
|
|
||||||
<li><Key symbol="–" /> Qualité du sommeil (1-5) : __</li>
|
|
||||||
<li><Key symbol="–" /> Humeur du jour (1-5) : __</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="*" /> Priorités du Jour (Pro & Perso)</h2>
|
|
||||||
<p class="text-sm text-slate-500 mb-3">Se concentrer sur 1 à 3 tâches essentielles pour avancer.</p>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> [Tâche pro n°1]</li>
|
|
||||||
<li><Key symbol="•" /> [Tâche pro n°2]</li>
|
|
||||||
<li><Key symbol="•" /> [Tâche perso importante]</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="$" /> Organisation & Budget</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Planifier le repas du soir</li>
|
|
||||||
<li><Key symbol="👁️" /> Point rapide sur les comptes</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="•" /> Foyer & Routine du soir</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Ranger l'espace de travail (5 min)</li>
|
|
||||||
<li><Key symbol="•" /> Préparer les affaires pour demain</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="♡" /> Loisirs & Note du jour</h2>
|
|
||||||
<p class="text-slate-600 mt-2">Un moment pour soi, une pensée, une petite victoire :</p>
|
|
||||||
<textarea id="daily-note-19" class="w-full mt-2 p-2 border rounded bg-slate-50" rows="2" placeholder="..."></textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script is:inline>
|
|
||||||
{`
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
|
||||||
const textarea = document.getElementById('daily-note-19');
|
|
||||||
const storageKey = 'note-/bujo/2026/01/19';
|
|
||||||
const savedNote = localStorage.getItem(storageKey);
|
|
||||||
if (savedNote) textarea.value = savedNote;
|
|
||||||
textarea.addEventListener('input', () => localStorage.setItem(storageKey, textarea.value));
|
|
||||||
});
|
|
||||||
`}
|
|
||||||
</script>
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Daily Log - 20 Janvier 2026"
|
|
||||||
publishDate: 2026-01-20
|
|
||||||
tags: ["Daily", "Work", "Organisation"]
|
|
||||||
---
|
|
||||||
import Key from '~/components/bujo/Key.astro';
|
|
||||||
|
|
||||||
<div class="mb-8 p-4 bg-blue-50 border-l-4 border-blue-400">
|
|
||||||
<h2 class="text-xl font-bold text-slate-800 mb-2"><Key symbol="⚓" /> Ancrage & Bien-être</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Routine du matin (douche, dents...)</li>
|
|
||||||
<li><Key symbol="•" /> Activité physique douce (étirements, marche...)</li>
|
|
||||||
<li><Key symbol="–" /> Qualité du sommeil (1-5) : __</li>
|
|
||||||
<li><Key symbol="–" /> Humeur du jour (1-5) : __</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="*" /> Priorités du Jour (Pro & Perso)</h2>
|
|
||||||
<p class="text-sm text-slate-500 mb-3">Se concentrer sur 1 à 3 tâches essentielles pour avancer.</p>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> [Tâche pro n°1]</li>
|
|
||||||
<li><Key symbol="•" /> [Tâche pro n°2]</li>
|
|
||||||
<li><Key symbol="•" /> [Tâche perso importante]</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="$" /> Organisation & Budget</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Planifier le repas du soir</li>
|
|
||||||
<li><Key symbol="👁️" /> Point rapide sur les comptes</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="•" /> Foyer & Routine du soir</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Ranger l'espace de travail (5 min)</li>
|
|
||||||
<li><Key symbol="•" /> Préparer les affaires pour demain</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="♡" /> Loisirs & Note du jour</h2>
|
|
||||||
<p class="text-slate-600 mt-2">Un moment pour soi, une pensée, une petite victoire :</p>
|
|
||||||
<textarea id="daily-note-20" class="w-full mt-2 p-2 border rounded bg-slate-50" rows="2" placeholder="..."></textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script is:inline>
|
|
||||||
{`
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
|
||||||
const textarea = document.getElementById('daily-note-20');
|
|
||||||
const storageKey = 'note-/bujo/2026/01/20';
|
|
||||||
const savedNote = localStorage.getItem(storageKey);
|
|
||||||
if (savedNote) textarea.value = savedNote;
|
|
||||||
textarea.addEventListener('input', () => localStorage.setItem(storageKey, textarea.value));
|
|
||||||
});
|
|
||||||
`}
|
|
||||||
</script>
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Daily Log - 21 Janvier 2026"
|
|
||||||
publishDate: 2026-01-21
|
|
||||||
tags: ["Daily", "Work", "Organisation"]
|
|
||||||
---
|
|
||||||
import Key from '~/components/bujo/Key.astro';
|
|
||||||
|
|
||||||
<div class="mb-8 p-4 bg-blue-50 border-l-4 border-blue-400">
|
|
||||||
<h2 class="text-xl font-bold text-slate-800 mb-2"><Key symbol="⚓" /> Ancrage & Bien-être</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Routine du matin (douche, dents...)</li>
|
|
||||||
<li><Key symbol="•" /> Activité physique douce (étirements, marche...)</li>
|
|
||||||
<li><Key symbol="–" /> Qualité du sommeil (1-5) : __</li>
|
|
||||||
<li><Key symbol="–" /> Humeur du jour (1-5) : __</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="*" /> Priorités du Jour (Pro & Perso)</h2>
|
|
||||||
<p class="text-sm text-slate-500 mb-3">Se concentrer sur 1 à 3 tâches essentielles pour avancer.</p>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> [Tâche pro n°1]</li>
|
|
||||||
<li><Key symbol="•" /> [Tâche pro n°2]</li>
|
|
||||||
<li><Key symbol="•" /> [Tâche perso importante]</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="$" /> Organisation & Budget</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Planifier le repas du soir</li>
|
|
||||||
<li><Key symbol="👁️" /> Point rapide sur les comptes</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="•" /> Foyer & Routine du soir</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Ranger l'espace de travail (5 min)</li>
|
|
||||||
<li><Key symbol="•" /> Préparer les affaires pour demain</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="♡" /> Loisirs & Note du jour</h2>
|
|
||||||
<p class="text-slate-600 mt-2">Un moment pour soi, une pensée, une petite victoire :</p>
|
|
||||||
<textarea id="daily-note-21" class="w-full mt-2 p-2 border rounded bg-slate-50" rows="2" placeholder="..."></textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script is:inline>
|
|
||||||
{`
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
|
||||||
const textarea = document.getElementById('daily-note-21');
|
|
||||||
const storageKey = 'note-/bujo/2026/01/21';
|
|
||||||
const savedNote = localStorage.getItem(storageKey);
|
|
||||||
if (savedNote) textarea.value = savedNote;
|
|
||||||
textarea.addEventListener('input', () => localStorage.setItem(storageKey, textarea.value));
|
|
||||||
});
|
|
||||||
`}
|
|
||||||
</script>
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Daily Log - 24 Janvier 2026"
|
|
||||||
publishDate: 2026-01-24
|
|
||||||
tags: ["Daily", "Weekend", "Organisation"]
|
|
||||||
---
|
|
||||||
import Key from '~/components/bujo/Key.astro';
|
|
||||||
|
|
||||||
<div class="mb-8 p-4 bg-blue-50 border-l-4 border-blue-400">
|
|
||||||
<h2 class="text-xl font-bold text-slate-800 mb-2"><Key symbol="⚓" /> Ancrage & Bien-être</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Routine du matin (douche, dents...)</li>
|
|
||||||
<li><Key symbol="•" /> Activité physique douce (étirements, marche...)</li>
|
|
||||||
<li><Key symbol="–" /> Qualité du sommeil (1-5) : __</li>
|
|
||||||
<li><Key symbol="–" /> Humeur du jour (1-5) : __</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="*" /> Objectifs du Samedi</h2>
|
|
||||||
<p class="text-sm text-slate-500 mb-3">Une ou deux choses pour profiter de la journée et se sentir bien.</p>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> [Objectif principal]</li>
|
|
||||||
<li><Key symbol="•" /> [Autre petite tâche]</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="•" /> Foyer & Organisation</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Session de rangement (15 min)</li>
|
|
||||||
<li><Key symbol="•" /> Tâche ménagère au choix (lessive, vaisselle...)</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="♡" /> Loisirs & Note du jour</h2>
|
|
||||||
<p class="text-slate-600 mt-2">Un moment pour soi, une pensée, une petite victoire :</p>
|
|
||||||
<textarea id="daily-note-24" class="w-full mt-2 p-2 border rounded bg-slate-50" rows="2" placeholder="..."></textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script is:inline>
|
|
||||||
{`
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
|
||||||
const textarea = document.getElementById('daily-note-24');
|
|
||||||
const storageKey = 'note-/bujo/2026/01/24';
|
|
||||||
const savedNote = localStorage.getItem(storageKey);
|
|
||||||
if (savedNote) textarea.value = savedNote;
|
|
||||||
textarea.addEventListener('input', () => localStorage.setItem(storageKey, textarea.value));
|
|
||||||
});
|
|
||||||
`}
|
|
||||||
</script>
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Daily Log - 23 Janvier 2026"
|
|
||||||
publishDate: 2026-01-23
|
|
||||||
tags: ["Daily", "Work", "Organisation"]
|
|
||||||
---
|
|
||||||
import Key from '~/components/bujo/Key.astro';
|
|
||||||
|
|
||||||
<div class="mb-8 p-4 bg-blue-50 border-l-4 border-blue-400">
|
|
||||||
<h2 class="text-xl font-bold text-slate-800 mb-2"><Key symbol="⚓" /> Ancrage & Bien-être</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Routine du matin (douche, dents...)</li>
|
|
||||||
<li><Key symbol="•" /> Activité physique douce (étirements, marche...)</li>
|
|
||||||
<li><Key symbol="–" /> Qualité du sommeil (1-5) : __</li>
|
|
||||||
<li><Key symbol="–" /> Humeur du jour (1-5) : __</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="*" /> Priorités du Jour (Pro & Perso)</h2>
|
|
||||||
<p class="text-sm text-slate-500 mb-3">Se concentrer sur 1 à 3 tâches essentielles pour avancer.</p>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> [Tâche pro n°1]</li>
|
|
||||||
<li><Key symbol="•" /> [Tâche pro n°2]</li>
|
|
||||||
<li><Key symbol="•" /> [Tâche perso importante]</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="$" /> Organisation & Budget</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Planifier le repas du soir</li>
|
|
||||||
<li><Key symbol="👁️" /> Point rapide sur les comptes</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="•" /> Foyer & Routine du soir</h2>
|
|
||||||
<ul class="space-y-2">
|
|
||||||
<li><Key symbol="•" /> Ranger l'espace de travail (5 min)</li>
|
|
||||||
<li><Key symbol="•" /> Préparer les affaires pour demain</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6">
|
|
||||||
<h2 class="text-xl font-bold text-slate-700"><Key symbol="♡" /> Loisirs & Note du jour</h2>
|
|
||||||
<p class="text-slate-600 mt-2">Un moment pour soi, une pensée, une petite victoire :</p>
|
|
||||||
<textarea id="daily-note-23" class="w-full mt-2 p-2 border rounded bg-slate-50" rows="2" placeholder="..."></textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script is:inline>
|
|
||||||
{`
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
|
||||||
const textarea = document.getElementById('daily-note-23');
|
|
||||||
const storageKey = 'note-/bujo/2026/01/23';
|
|
||||||
const savedNote = localStorage.getItem(storageKey);
|
|
||||||
if (savedNote) textarea.value = savedNote;
|
|
||||||
textarea.addEventListener('input', () => localStorage.setItem(storageKey, textarea.value));
|
|
||||||
});
|
|
||||||
`}
|
|
||||||
</script>
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
---
|
|
||||||
import GameLayout from '../layouts/GameLayout.astro';
|
|
||||||
import ParchmentCard from '../components/ui/ParchmentCard.astro';
|
|
||||||
---
|
|
||||||
<GameLayout title="Le Sanctuaire des Grains - Sweet Journey">
|
|
||||||
<ParchmentCard>
|
|
||||||
<h1>🏜️ Le Sanctuaire des Grains</h1>
|
|
||||||
<p>
|
|
||||||
Entrez dans mon lieu de méditation. D'où je viens, la création n'est pas une affaire de métal et de feu, mais de patience, de concentration et de sable. Chaque grain est une possibilité, chaque ligne de code un chemin tracé dans les dunes de l'esprit. Cette section dévoile les arts que j'emploie pour donner forme à ce monde.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Le Façonnage du Sable : Les Arts Techniques</h2>
|
|
||||||
<p>
|
|
||||||
Au lieu d'une forge, mon art s'exprime par le façonnage. Les idées brutes sont comme du sable sauvage ; il faut le canaliser, le modeler avec discipline pour qu'il devienne une histoire, une expérience. Pour invoquer un monde 3D dans le navigateur, le choix des arts est aussi crucial que le choix du sable.
|
|
||||||
</p>
|
|
||||||
<h3>Pourquoi Three.js ?</h3>
|
|
||||||
<p><strong>Three.js</strong> est mon art martial numérique. C'est un ensemble de katas (fonctions) en JavaScript qui me permet de maîtriser le flux de la 3D dans le navigateur. Chaque mouvement est précis : je peux dicter la course de la lumière, orchestrer la danse des objets et appliquer les textures comme on applique un pigment. C'est le ki qui donne vie à la matière inerte.</p>
|
|
||||||
<h3>Pourquoi Blender ?</h3>
|
|
||||||
<p>Si Three.js est l'art du mouvement, <strong>Blender</strong> est l'art de la méditation. C'est dans ce monde intérieur que je voyage pour façonner les personnages, les paysages et les rêves de mon peuple. C'est un outil open source qui me permet de donner une forme tangible à mes visions, avant de leur insuffler le souffle de vie sur le web.</p>
|
|
||||||
|
|
||||||
<h2>Le Kit du Pèlerin : Outils de Prédilection</h2>
|
|
||||||
<p>Tout pèlerin transporte avec lui des outils essentiels. Les miens ne sont pas faits de bois ou de métal, mais ils sont tout aussi vitaux pour mon voyage.</p>
|
|
||||||
<dl>
|
|
||||||
<dt><strong>Visual Studio Code : Mon Grimoire de Rituels</strong></dt>
|
|
||||||
<dd>C'est ici que je calligraphie les incantations (le code) qui donnent leurs instructions au sable. Chaque fonction est un mantra, chaque variable un grain choisi avec soin pour construire le monde.</dd>
|
|
||||||
|
|
||||||
<dt><strong>Lenovo Yoga 530 (Ubuntu) : Ma Pierre de Méditation</strong></dt>
|
|
||||||
<dd>C'est sur cette surface que je m'installe pour me concentrer. Sa flexibilité me permet de trouver la posture juste, et son cœur (Ubuntu) bat au rythme du partage et de la liberté, des valeurs chères à tout pèlerin.</dd>
|
|
||||||
|
|
||||||
<dt><strong>Wacom One, GIMP & Krita : Ma Toile de Sable et mes Pigments de Songe</strong></dt>
|
|
||||||
<dd>La tablette est une étendue de sable fin sur laquelle je dessine les premières formes de mes visions. GIMP et Krita m'offre les pigments extraits des rêves pour leur donner couleur et vie.</dd>
|
|
||||||
|
|
||||||
<dt><strong>Obsidian & Carnet à dessin : Ma Carte des Étoiles et mon Journal de Piste</strong></dt>
|
|
||||||
<dd>Le carnet recueille les croquis bruts de mon voyage. Obsidian, lui, est ma carte du ciel intérieure ; il me permet de relier chaque idée, chaque souvenir et chaque rêve en une constellation de savoir qui guide ma quête.</dd>
|
|
||||||
|
|
||||||
<dt><strong>Raspberry Pi : Mon Foyer de Pèlerin</strong></dt>
|
|
||||||
<dd>Ce petit autel est le cœur de mon campement numérique. C'est un serveur humble mais résilient, d'où je publie mes récits et partage mes créations avec le monde. Il bat au rythme de plusieurs esprits bienveillants :</dd>
|
|
||||||
<dd>
|
|
||||||
<ul>
|
|
||||||
<li><strong>Docker :</strong> L'art de créer des bocaux à songes. Chaque service est contenu dans son propre terrarium magique, parfait et isolé, pour s'assurer que les rêves ne se mélangent pas.</li>
|
|
||||||
<li><strong>Nginx Proxy Manager :</strong> Le gardien des carrefours, qui guide les visiteurs égarés vers la bonne histoire, le bon outil.</li>
|
|
||||||
<li><strong>Nextcloud & Wallabag :</strong> Ma besace sans fond et mon filet à murmures. L'un stocke mes trouvailles et mes grains de sable précieux, l'autre capture les histoires du vent pour une lecture future.</li>
|
|
||||||
<li><strong>Dolibarr & Superset :</strong> Mon grand livre de marchand et ma lentille d'analyse. Ils m'aident à tenir les comptes de mes échanges de rêves et à scruter la nature profonde de chaque grain de sable (donnée) que je collecte.</li>
|
|
||||||
</ul>
|
|
||||||
</dd>
|
|
||||||
</dl>
|
|
||||||
</ParchmentCard>
|
|
||||||
</GameLayout>
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
---
|
|
||||||
import GameLayout from '../layouts/GameLayout.astro';
|
|
||||||
import ParchmentCard from '../components/ui/ParchmentCard.astro';
|
|
||||||
---
|
|
||||||
|
|
||||||
<GameLayout title="L'Artisan des Rêves - Nicolas Latchimy">
|
|
||||||
<ParchmentCard>
|
|
||||||
<h1>🐸 L'Artisan derrière le Pèlerin</h1>
|
|
||||||
<p>
|
|
||||||
Je suis G'Mas, un pèlerin fait de sable et de songes. Mais qui est l'artisan qui me rêve ? Qui est celui dont les mains façonnent mon voyage ? Laissez-moi vous parler de lui, car son histoire est la source de la mienne.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Il se nomme <strong>Nicolas Latchimy</strong>. Artiste, développeur, un esprit ubiquiste qui, depuis l'âge de trois ans, utilise le dessin pour donner une forme à ses émotions. Son parcours est un long pèlerinage entre deux mondes : celui de l'Art, étudié à Paris et à La Réunion, et celui du Code, appris plus tard pour construire de nouvelles formes de récits.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Hatjan Krâpo, le Cousin du grung</h2>
|
|
||||||
<p>
|
|
||||||
Avant que je n'existe, un autre batracien est né de son crayon : <strong>Hatjan Krâpo</strong>. Mon lointain cousin de papier. Si je suis un pèlerin des sables, Hatjan est un symbole du rejet, du dégoût, mais aussi d'une humanité cinglante. À travers lui, Nicolas explore les thèmes qui le hantent : l'exclusion, les discriminations, le harcèlement. C'est un cri silencieux contre les écarts qui fracturent nos sociétés.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Mosaic Chantilly, l'Armateur d'Art</h2>
|
|
||||||
<p>
|
|
||||||
Le 14 septembre 2024, un autre chemin s'est ouvert. Sous le nom de <strong>Mosaic Chantilly</strong>, il est devenu un "armateur d'art à corps perdu". Sa mission : déconstruire l'art comme une mosaïque pour en révéler l'essence. C'est une quête de dix ans qui commence, un nouveau voyage dans la matière et la forme.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Du Pinceau au Code</h2>
|
|
||||||
<p>
|
|
||||||
Après des années à questionner le monde à travers l'art, il s'est tourné vers le développement web. Non pas pour abandonner le dessin, mais pour lui offrir un nouveau terrain de jeu. Il voit le code comme un autre langage pour raconter des histoires, pour créer des ponts. Ce site en est la preuve : un lieu où la 3D, la narration et la technique se rencontrent.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Retrouver l'Artisan</h2>
|
|
||||||
<p>Pour suivre ses autres pérégrinations, qu'elles soient dessinées ou codées :</p>
|
|
||||||
<ul>
|
|
||||||
<li><strong>Portfolio Artistique :</strong> <a href="https://www.pinterest.com/imazmaronrstones/errances-cr%C3%A9atives/" target="_blank" rel="noopener noreferrer">Errances Créatives sur Pinterest</a></li>
|
|
||||||
<li><strong>Page Auteur :</strong> <a href="https://www.la-reunion-des-livres.re/auteur/latchimy-nicolas/" target="_blank" rel="noopener noreferrer">La Réunion des Livres</a></li>
|
|
||||||
<li><strong>Forum Dessiné :</strong> <a href="https://www.forum-dessine.fr/auteurs/krapo" target="_blank" rel="noopener noreferrer">Profil de Krâpo</a></li>
|
|
||||||
<li><strong>23h de la BD (2019) :</strong> <a href="https://23hbd.com/participants/2019/krapo/" target="_blank" rel="noopener noreferrer">Participation 2019</a></li>
|
|
||||||
<li><strong>23h de la BD (2020) :</strong> <a href="https://23hbd.com/participants/2020/krapo/" target="_blank" rel="noopener noreferrer">Participation 2020</a></li>
|
|
||||||
<li><strong>Webtoon (Liestral) :</strong> <a href="https://www.webtoons.com/fr/canvas/liestral/list?title_no=1049110" target="_blank" rel="noopener noreferrer">Découvrir son webtoon</a></li>
|
|
||||||
<li><strong>Instagram :</strong> <a href="https://www.instagram.com/mosaic_chantilly/" target="_blank" rel="noopener noreferrer">@mosaic_chantilly</a></li>
|
|
||||||
<li><strong>CV en ligne :</strong> <a href="https://nohay.github.io/" target="_blank" rel="noopener noreferrer">Découvrir son parcours</a></li>
|
|
||||||
</ul>
|
|
||||||
</ParchmentCard>
|
|
||||||
|
|
||||||
<ParchmentCard>
|
|
||||||
<h2>📖 Le Journal de Bord de l'Artisan</h2>
|
|
||||||
<p>
|
|
||||||
Au-delà des chroniques et des lignes de code, il y a le quotidien. Une quête d'équilibre entre la vie, la passion et la discipline. Ce journal de bord est une tentative de cartographier ce voyage intérieur.
|
|
||||||
</p>
|
|
||||||
<div class="text-center mt-4">
|
|
||||||
<a href="/bujo" class="bg-stone-700 text-white font-bold py-2 px-4 rounded hover:bg-stone-800 transition-colors duration-300">Accéder au Journal de Bord</a>
|
|
||||||
</div>
|
|
||||||
</ParchmentCard>
|
|
||||||
</GameLayout>
|
|
||||||
|
|
||||||
</Layout>
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
---
|
|
||||||
import GameLayout from '../layouts/GameLayout.astro';
|
|
||||||
import ParchmentCard from '../components/ui/ParchmentCard.astro';
|
|
||||||
---
|
|
||||||
|
|
||||||
<GameLayout title="La Boussole Éthique - Sweet Journey">
|
|
||||||
<ParchmentCard>
|
|
||||||
<h1>⚖️ La Boussole Éthique</h1>
|
|
||||||
<p>
|
|
||||||
Mon voyage a commencé à cause d'un fléau : un sable sombre, dépourvu de vie, qui corrompt mes terres et empoisonne les rêves de mon peuple. Cette quête m'a enseigné à distinguer le sable pur du sable vicié. Il en va de même pour les créations des mortels. Certaines sont conçues pour apporter un repos réparateur, d'autres sont des pièges, aussi subtils que le poison sur ma peau.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Les Sables de Vie : Les Chemins à Suivre</h2>
|
|
||||||
<p>Ce sont les modèles basés sur le respect et la valeur. L'**Open Source**, par exemple, est comme une oasis où chaque pèlerin peut puiser de l'eau, mais aussi y ajouter une goutte pour le suivant. C'est un cycle de don où la connaissance n'est pas un trésor gardé, mais une source qui abreuve la communauté. Ma conviction est que l'on peut bâtir de grandes choses avec des matériaux que d'autres jugent obsolètes, en laissant une empreinte légère. L'autonomie est possible sans dévaster le monde ; c'est une question de culture. Se souvenir de la naissance de la grande toile (le web) et voir où elle en est aujourd'hui doit nous inspirer à créer en harmonie avec l'ensemble.</p>
|
|
||||||
|
|
||||||
<h2>Les Marécages de Sable Noir : Les Chemins à Éviter</h2>
|
|
||||||
<p>Ici se trouvent les sables mouvants. Je perçois dans le monde une tendance à la démesure, une soif de pouvoir qui oublie l'équilibre. On y cherche à dominer plutôt qu'à harmoniser, à prendre plutôt qu'à partager. Cette philosophie ressemble au sable noir : elle crée des systèmes où quelques-uns s'enrichissent en asséchant les rêves de la multitude. Mon art se refuse à emprunter cette voie.</p>
|
|
||||||
</ParchmentCard>
|
|
||||||
</GameLayout>
|
|
||||||
@@ -1,132 +0,0 @@
|
|||||||
---
|
|
||||||
import { getCollection, render } from 'astro:content';
|
|
||||||
import LifeLayout from '../../layouts/LifeLayout.astro';
|
|
||||||
|
|
||||||
// Import des composants de page pour les garder modulaires
|
|
||||||
import BujoIndex from '../../components/bujo/BujoIndex.astro';
|
|
||||||
import BujoKeys from '../../components/bujo/BujoKeys.astro';
|
|
||||||
import MonthlyLog from '../../components/bujo/MonthlyLog.astro';
|
|
||||||
import BujoFutureLog from '../../components/bujo/BujoFutureLog.astro';
|
|
||||||
import CollectionTracker from '../../components/bujo/CollectionTracker.astro';
|
|
||||||
import CollectionObjectifs from '../../components/bujo/CollectionObjectifs.astro';
|
|
||||||
import CollectionBooks from '../../components/bujo/CollectionBooks.astro';
|
|
||||||
import CollectionPlaceholder from '../../components/bujo/CollectionPlaceholder.astro';
|
|
||||||
import CollectionFilms from '../../components/bujo/CollectionFilms.astro';
|
|
||||||
|
|
||||||
export async function getStaticPaths() {
|
|
||||||
const bujoEntries = await getCollection('bujo');
|
|
||||||
const paths = bujoEntries.map(entry => {
|
|
||||||
const slug = entry.id.replace(/\.(md|mdx)$/, '');
|
|
||||||
return { params: { slug } };
|
|
||||||
});
|
|
||||||
// Ajouter les routes statiques/virtuelles
|
|
||||||
paths.push({ params: { slug: undefined } }); // Index
|
|
||||||
paths.push({ params: { slug: 'keys' } });
|
|
||||||
paths.push({ params: { slug: 'future-log' } });
|
|
||||||
paths.push({ params: { slug: 'collections/livres-a-lire' } });
|
|
||||||
paths.push({ params: { slug: 'collections/trackers-mensuels' } });
|
|
||||||
paths.push({ params: { slug: 'collections/objectifs-du-mois' } });
|
|
||||||
paths.push({ params: { slug: 'collections/suivi-depenses' } });
|
|
||||||
paths.push({ params: { slug: 'collections/gratitude' } });
|
|
||||||
paths.push({ params: { slug: 'collections/brain-dump' } });
|
|
||||||
paths.push({ params: { slug: 'collections/bucket-list' } });
|
|
||||||
paths.push({ params: { slug: 'collections/films-a-voir' } });
|
|
||||||
|
|
||||||
// Ajouter les routes pour les mois
|
|
||||||
const uniqueMonths = new Set<string>();
|
|
||||||
bujoEntries.forEach(log => {
|
|
||||||
const [year, month] = log.id.split('/');
|
|
||||||
if (year && month && !isNaN(parseInt(year)) && !isNaN(parseInt(month))) {
|
|
||||||
uniqueMonths.add(`${year}/${month}`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
uniqueMonths.forEach(monthPath => {
|
|
||||||
paths.push({ params: { slug: monthPath } });
|
|
||||||
});
|
|
||||||
|
|
||||||
return paths;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { slug } = Astro.params;
|
|
||||||
|
|
||||||
// 1. Gérer la page d'index (/bujo)
|
|
||||||
if (slug === undefined) {
|
|
||||||
const allLogs = await getCollection('bujo');
|
|
||||||
const uniqueMonths = new Set<string>();
|
|
||||||
allLogs.forEach(log => {
|
|
||||||
const [year, month] = log.id.split('/');
|
|
||||||
if (year && month && !isNaN(parseInt(year)) && !isNaN(parseInt(month))) {
|
|
||||||
uniqueMonths.add(`${year}/${month}`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Astro.props.page = 'index';
|
|
||||||
Astro.props.months = Array.from(uniqueMonths);
|
|
||||||
}
|
|
||||||
// 2. Gérer les pages statiques (clés, etc.)
|
|
||||||
else if (slug === 'keys') {
|
|
||||||
Astro.props.page = 'keys';
|
|
||||||
}
|
|
||||||
else if (slug === 'future-log') {
|
|
||||||
Astro.props.page = 'bujo-future-log';
|
|
||||||
}
|
|
||||||
// 3. Gérer les collections
|
|
||||||
else if (slug.startsWith('collections/')) {
|
|
||||||
if (slug === 'collections/trackers-mensuels') {
|
|
||||||
Astro.props.page = 'collection-tracker';
|
|
||||||
} else if (slug === 'collections/livres-a-lire') {
|
|
||||||
Astro.props.page = 'collection-books';
|
|
||||||
} else if (slug === 'collections/objectifs-du-mois') {
|
|
||||||
Astro.props.page = 'collection-objectifs';
|
|
||||||
} else if (slug === 'collections/films-a-voir') {
|
|
||||||
Astro.props.page = 'collection-films';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Astro.props.page = 'collection-placeholder';
|
|
||||||
Astro.props.collectionTitle = slug.split('/')[1].replace(/-/g, ' ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 4. Gérer les logs mensuels (ex: /bujo/2026/01)
|
|
||||||
else if (slug.match(/^\d{4}\/\d{2}$/)) {
|
|
||||||
const [year, month] = slug.split('/');
|
|
||||||
const monthlyLogs = await getCollection('bujo', ({ id }) => id.startsWith(slug));
|
|
||||||
Astro.props.page = 'monthly-log';
|
|
||||||
Astro.props.logs = monthlyLogs;
|
|
||||||
Astro.props.year = year;
|
|
||||||
Astro.props.month = month;
|
|
||||||
}
|
|
||||||
// 5. Gérer les entrées de contenu (Daily Logs)
|
|
||||||
else {
|
|
||||||
const bujoEntries = await getCollection('bujo');
|
|
||||||
const entry = bujoEntries.find(e => e.id.replace(/\.(md|mdx)$/, '') === slug);
|
|
||||||
if (entry) {
|
|
||||||
const { Content } = await render(entry);
|
|
||||||
Astro.props.page = 'entry';
|
|
||||||
Astro.props.entry = entry;
|
|
||||||
Astro.props.Content = Content;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const { page, entry, Content, months, logs, year, month, collectionTitle } = Astro.props;
|
|
||||||
const title = page === 'index' ? 'Journal de Bord' : (entry ? entry.data.title : collectionTitle || 'Journal');
|
|
||||||
---
|
|
||||||
|
|
||||||
<LifeLayout title={title}>
|
|
||||||
{page === 'index' && <BujoIndex months={months} />}
|
|
||||||
{page === 'keys' && <BujoKeys />}
|
|
||||||
{page === 'bujo-future-log' && <BujoFutureLog />}
|
|
||||||
|
|
||||||
{page === 'collection-tracker' && <CollectionTracker />}
|
|
||||||
{page === 'collection-objectifs' && <CollectionObjectifs />}
|
|
||||||
{page === 'collection-books' && <CollectionBooks />}
|
|
||||||
{page === 'collection-films' && <CollectionFilms />}
|
|
||||||
{page === 'collection-placeholder' && <CollectionPlaceholder collectionTitle={collectionTitle} />}
|
|
||||||
|
|
||||||
{page === 'monthly-log' && <MonthlyLog logs={logs} year={year} month={month} />}
|
|
||||||
|
|
||||||
{page === 'entry' && Content && (
|
|
||||||
<article class="prose prose-slate lg:prose-xl max-w-none">
|
|
||||||
<h1 class="text-3xl font-bold mb-2">{entry.data.title}</h1>
|
|
||||||
<Content />
|
|
||||||
</article>
|
|
||||||
)}
|
|
||||||
</LifeLayout>
|
|
||||||
@@ -1,152 +0,0 @@
|
|||||||
---
|
|
||||||
import { getCollection, type CollectionEntry } from "astro:content";
|
|
||||||
import GameLayout from "../../layouts/GameLayout.astro";
|
|
||||||
|
|
||||||
export async function getStaticPaths() {
|
|
||||||
const codexEntries = await getCollection("codex");
|
|
||||||
return codexEntries.map((entry) => ({
|
|
||||||
params: { slug: entry.slug },
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
const { slug } = Astro.params;
|
|
||||||
const codexEntries = await getCollection("codex");
|
|
||||||
|
|
||||||
const entry = codexEntries.find((entry) => entry.slug === slug);
|
|
||||||
|
|
||||||
if (!entry) {
|
|
||||||
return Astro.redirect("/404");
|
|
||||||
}
|
|
||||||
|
|
||||||
const { Content } = await entry.render();
|
|
||||||
---
|
|
||||||
|
|
||||||
<GameLayout title={entry.data.title}>
|
|
||||||
<main class="codex-entry-container">
|
|
||||||
<article class="parchment-card">
|
|
||||||
<div class="header">
|
|
||||||
<h1>{entry.data.title}</h1>
|
|
||||||
<h2>{entry.data.subtitle}</h2>
|
|
||||||
<p class="publish-date">
|
|
||||||
Savoir acquis le : {
|
|
||||||
entry.data.publishDate.toLocaleDateString("fr-FR", {
|
|
||||||
year: "numeric",
|
|
||||||
month: "long",
|
|
||||||
day: "numeric",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="transmutation-table">
|
|
||||||
<div class="table-row header">
|
|
||||||
<div class="col-title">Ancien Monde (2D)</div>
|
|
||||||
<div class="col-title">Mécanique</div>
|
|
||||||
<div class="col-title">Monde de Demain (3D)</div>
|
|
||||||
</div>
|
|
||||||
<div class="table-row">
|
|
||||||
<div>{entry.data.concept2D}</div>
|
|
||||||
<div>{entry.data.mecanique}</div>
|
|
||||||
<div>{entry.data.vision3D}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{entry.data.tags && (
|
|
||||||
<div class="tags-container">
|
|
||||||
{entry.data.tags.map((tag) => (
|
|
||||||
<a href={`/codex/tags/${tag.toLowerCase()}`} class="tag">{tag}</a>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<div class="prose">
|
|
||||||
<Content />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<a href="/codex" class="back-link"> ← Retourner au Codex </a>
|
|
||||||
</article>
|
|
||||||
</main>
|
|
||||||
</GameLayout>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.codex-entry-container {
|
|
||||||
max-width: 900px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 2rem 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.parchment-card {
|
|
||||||
background: linear-gradient(145deg, #fefbf3, #f8f1e4);
|
|
||||||
border: 2px solid #dcd0b9;
|
|
||||||
border-radius: 15px;
|
|
||||||
padding: 2rem 3rem;
|
|
||||||
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05);
|
|
||||||
}
|
|
||||||
|
|
||||||
.header {
|
|
||||||
text-align: center;
|
|
||||||
margin-bottom: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header h1 {
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
}
|
|
||||||
.header h2 {
|
|
||||||
font-family: "EB Garamond", serif;
|
|
||||||
font-style: italic;
|
|
||||||
font-size: 1.4rem;
|
|
||||||
color: #4a4130;
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
/* On retire l'ornement pour le h2 de la carte */
|
|
||||||
.header h2::after {
|
|
||||||
content: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.publish-date {
|
|
||||||
font-style: italic;
|
|
||||||
opacity: 0.7;
|
|
||||||
}
|
|
||||||
|
|
||||||
.transmutation-table {
|
|
||||||
margin: 2rem 0;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
background-color: rgba(253, 246, 232, 0.5);
|
|
||||||
border: 1px solid #dcd0b9;
|
|
||||||
border-radius: 8px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-row {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr 1.5fr 1.5fr;
|
|
||||||
gap: 1rem;
|
|
||||||
padding: 0.75rem 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-row.header {
|
|
||||||
background-color: rgba(220, 208, 185, 0.4);
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-row:not(.header) {
|
|
||||||
border-top: 1px solid #dcd0b9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-title {
|
|
||||||
font-family: "Cinzel", serif;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #4a4130;
|
|
||||||
}
|
|
||||||
|
|
||||||
.back-link {
|
|
||||||
display: inline-block;
|
|
||||||
margin-top: 3rem;
|
|
||||||
font-family: "Cinzel", serif;
|
|
||||||
color: #b8860b;
|
|
||||||
text-decoration: none;
|
|
||||||
transition: all 0.2s ease;
|
|
||||||
}
|
|
||||||
.back-link:hover {
|
|
||||||
transform: translateX(-5px);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
---
|
|
||||||
import { getCollection } from "astro:content";
|
|
||||||
import GameLayout from "../../layouts/GameLayout.astro";
|
|
||||||
import ContentSearch from "../../components/ContentSearch.astro";
|
|
||||||
|
|
||||||
// 1. Récupérer toutes les entrées du codex
|
|
||||||
const codexEntries = await getCollection("codex");
|
|
||||||
|
|
||||||
// 2. Trier les entrées par date de publication
|
|
||||||
const sortedEntries = codexEntries.sort(
|
|
||||||
(a, b) => b.data.publishDate.valueOf() - a.data.publishDate.valueOf()
|
|
||||||
);
|
|
||||||
|
|
||||||
// 3. Extraire tous les domaines uniques pour les catégories
|
|
||||||
const allDomains = [...new Set(codexEntries.map(entry => entry.data.domain))];
|
|
||||||
---
|
|
||||||
|
|
||||||
<GameLayout title="Codex de la Substance">
|
|
||||||
<h1>Le Codex de la Substance</h1>
|
|
||||||
<p style="text-align: center; margin-bottom: 3rem;">
|
|
||||||
Le laboratoire où le pèlerin dissèque les mécanismes du réel (le code)
|
|
||||||
pour insuffler le "souffle de vie" (Hebel) à ses créations.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<!-- On passe les entrées, les domaines (en tant que tags) et le chemin de base au composant de recherche -->
|
|
||||||
<ContentSearch posts={sortedEntries} tags={allDomains} basePath="codex" />
|
|
||||||
|
|
||||||
</GameLayout>
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
---
|
|
||||||
import { getCollection } from "astro:content";
|
|
||||||
import GameLayout from "../../../layouts/GameLayout.astro";
|
|
||||||
import CodexCard from "../../../components/ui/CodexCard.astro";
|
|
||||||
|
|
||||||
export async function getStaticPaths() {
|
|
||||||
const allCodexEntries = await getCollection("codex");
|
|
||||||
const allTags = allCodexEntries.flatMap((entry) => entry.data.tags);
|
|
||||||
const uniqueTags = [...new Set(allTags)];
|
|
||||||
|
|
||||||
return uniqueTags.map((tag) => {
|
|
||||||
return {
|
|
||||||
params: { tag: tag.toLowerCase() },
|
|
||||||
props: { tag },
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const { tag } = Astro.props;
|
|
||||||
|
|
||||||
const allCodexEntries = await getCollection("codex");
|
|
||||||
|
|
||||||
const filteredEntries = allCodexEntries.filter((entry) =>
|
|
||||||
entry.data.tags.map(t => t.toLowerCase()).includes(Astro.params.tag)
|
|
||||||
);
|
|
||||||
---
|
|
||||||
|
|
||||||
<GameLayout title={`Domaine : ${tag}`}>
|
|
||||||
<main class="codex-container">
|
|
||||||
<h1>Domaine : {tag}</h1>
|
|
||||||
<p>
|
|
||||||
Liste de tous les savoirs et mécaniques liés au domaine "{tag}".
|
|
||||||
</p>
|
|
||||||
<div class="card-grid">
|
|
||||||
{filteredEntries.map((entry) => <CodexCard entry={entry} />)}
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
</GameLayout>
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
---
|
|
||||||
import GameLayout from "../layouts/GameLayout.astro";
|
|
||||||
import GoldButton from "../components/ui/GoldButton.astro";
|
|
||||||
---
|
|
||||||
|
|
||||||
<GameLayout title="Bienvenue sur JDRSweetJourney">
|
|
||||||
<h1>Bienvenue sur le projet JDR Sweet Journey !</h1>
|
|
||||||
<h2>L'Ambition</h2>
|
|
||||||
<p>
|
|
||||||
L'objectif est de créer un clone entièrement web de l'application mobile <strong
|
|
||||||
>AFK Journey</strong
|
|
||||||
>. Ce projet sera une vitrine technologique utilisant :
|
|
||||||
</p>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
La modélisation 3D et l'animation (2D et 3D) réalisées avec <strong
|
|
||||||
>Blender</strong
|
|
||||||
>.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
La retranscription de ces éléments dans le navigateur grâce à <strong
|
|
||||||
>Three.js</strong
|
|
||||||
>.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<ul class="card-grid">
|
|
||||||
<GoldButton
|
|
||||||
href="https://threejs-journey.com"
|
|
||||||
title="🎓 Formation : Three.js Journey"
|
|
||||||
body="Ce projet s'appuie sur les enseignements de Three.js Journey pour garantir une base technique solide."
|
|
||||||
/>
|
|
||||||
</ul>
|
|
||||||
<p>
|
|
||||||
Si en plus, cette plateforme peut servir de point de repère pour nos
|
|
||||||
aventures de jeu de rôle, c'est une pierre deux coups !
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Le Voyage</h2>
|
|
||||||
<p>
|
|
||||||
Ce site est aussi un levier pour maîtriser les paradigmes technologiques
|
|
||||||
de demain. Explorez le <strong>journal d'aventure</strong> pour suivre la
|
|
||||||
quête, ou consultez les <strong>logs de construction</strong> pour voir les
|
|
||||||
coulisses techniques.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<ul class="card-grid">
|
|
||||||
<GoldButton
|
|
||||||
href="/atelier"
|
|
||||||
title="🏜️ Le Sanctuaire des Grains"
|
|
||||||
body="Découvrez les arts et les outils du pèlerin pour façonner le sable et les rêves."
|
|
||||||
/>
|
|
||||||
<GoldButton
|
|
||||||
href="/observatoire"
|
|
||||||
title="🎨 L'Observatoire"
|
|
||||||
body="Explorez les sources d'inspiration : artistes, développeurs, podcasts et jeux qui nourrissent ce projet."
|
|
||||||
/>
|
|
||||||
<GoldButton
|
|
||||||
href="/boussole"
|
|
||||||
title="⚖️ La Boussole Éthique"
|
|
||||||
body="Une réflexion sur les modèles économiques vertueux et ceux à éviter dans le monde du jeu vidéo."
|
|
||||||
/>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<p>Quelle ambition, jeune batracien...</p>
|
|
||||||
</GameLayout>
|
|
||||||
@@ -1,45 +1,147 @@
|
|||||||
---
|
---
|
||||||
import { getCollection } from 'astro:content';
|
// 1. Ajoute "render" dans ton import
|
||||||
import GameLayout from '../../layouts/GameLayout.astro';
|
import { getCollection, render } from "astro:content";
|
||||||
import ParchmentCard from '../../components/ui/ParchmentCard.astro';
|
import GameLayout from "../../layouts/GameLayout.astro";
|
||||||
|
|
||||||
// 1. Génère une page statique pour chaque article de la collection
|
|
||||||
export async function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
const posts = await getCollection('journal');
|
const journalEntries = await getCollection("journal");
|
||||||
return posts.map((post) => ({
|
return journalEntries.map((entry) => ({
|
||||||
params: { slug: post.slug },
|
params: { slug: entry.id },
|
||||||
props: post,
|
props: { entry },
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Récupère les props de l'article correspondant
|
const { entry } = Astro.props;
|
||||||
const post = Astro.props;
|
|
||||||
const { Content } = await post.render();
|
if (!entry) {
|
||||||
|
return Astro.redirect("/404");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Utilise la fonction render(entry) au lieu de entry.render()
|
||||||
|
const { Content } = await render(entry);
|
||||||
---
|
---
|
||||||
|
|
||||||
<GameLayout title={post.data.title}>
|
<GameLayout title={entry.data.title}>
|
||||||
<ParchmentCard>
|
<main class="codex-entry-container">
|
||||||
<h1>{post.data.title}</h1>
|
<article class="parchment-card">
|
||||||
<div class="meta">
|
<div class="header">
|
||||||
Par {post.data.author} • Le {post.data.publishDate.toLocaleDateString('fr-FR')}
|
<h1>{entry.data.title}</h1>
|
||||||
</div>
|
<p class="publish-date">
|
||||||
{post.data.tags && (
|
Savoir acquis le : {
|
||||||
<div class="tags-container">
|
entry.data.publishDate.toLocaleDateString("fr-FR", {
|
||||||
{post.data.tags.map((tag) => (
|
year: "numeric",
|
||||||
<a href={`/journal/tags/${tag}`} class="tag">{tag}</a>
|
month: "long",
|
||||||
))}
|
day: "numeric",
|
||||||
</div>
|
})
|
||||||
)}
|
}
|
||||||
<article class="prose">
|
</p>
|
||||||
<Content />
|
</div>
|
||||||
</article>
|
|
||||||
</ParchmentCard>
|
{
|
||||||
|
entry.data.tags && (
|
||||||
|
<div class="tags-container">
|
||||||
|
{entry.data.tags.map((tag) => (
|
||||||
|
<a
|
||||||
|
href={`/journal/tags/${tag.toLowerCase()}`}
|
||||||
|
class="tag"
|
||||||
|
>
|
||||||
|
{tag}
|
||||||
|
</a>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
<div class="prose">
|
||||||
|
<Content />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a href="/journal" class="back-link">
|
||||||
|
← Retourner au Journal
|
||||||
|
</a>
|
||||||
|
</article>
|
||||||
|
</main>
|
||||||
</GameLayout>
|
</GameLayout>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.meta {
|
.codex-entry-container {
|
||||||
text-align: center;
|
max-width: 900px;
|
||||||
font-style: italic;
|
margin: 0 auto;
|
||||||
margin-bottom: 2rem;
|
padding: 2rem 1rem;
|
||||||
}
|
}
|
||||||
</style>
|
|
||||||
|
.parchment-card {
|
||||||
|
background: linear-gradient(145deg, #fefbf3, #f8f1e4);
|
||||||
|
border: 2px solid #dcd0b9;
|
||||||
|
border-radius: 15px;
|
||||||
|
padding: 2rem 3rem;
|
||||||
|
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header h1 {
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
.header h2 {
|
||||||
|
font-family: "EB Garamond", serif;
|
||||||
|
font-style: italic;
|
||||||
|
font-size: 1.4rem;
|
||||||
|
color: #4a4130;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
/* On retire l'ornement pour le h2 de la carte */
|
||||||
|
.header h2::after {
|
||||||
|
content: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.publish-date {
|
||||||
|
font-style: italic;
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.transmutation-table {
|
||||||
|
margin: 2rem 0;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
background-color: rgba(253, 246, 232, 0.5);
|
||||||
|
border: 1px solid #dcd0b9;
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-row {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1.5fr 1.5fr;
|
||||||
|
gap: 1rem;
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-row.header {
|
||||||
|
background-color: rgba(220, 208, 185, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-row:not(.header) {
|
||||||
|
border-top: 1px solid #dcd0b9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-title {
|
||||||
|
font-family: "Cinzel", serif;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #4a4130;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-link {
|
||||||
|
display: inline-block;
|
||||||
|
margin-top: 3rem;
|
||||||
|
font-family: "Cinzel", serif;
|
||||||
|
color: #b8860b;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
.back-link:hover {
|
||||||
|
transform: translateX(-5px);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,19 +1,23 @@
|
|||||||
---
|
---
|
||||||
import { getCollection } from 'astro:content';
|
import { getCollection } from "astro:content";
|
||||||
import GameLayout from '../../../layouts/GameLayout.astro';
|
import GameLayout from "../../../layouts/GameLayout.astro";
|
||||||
import GoldButton from '../../../components/ui/GoldButton.astro';
|
import GoldButton from "../../../components/ui/GoldButton.astro";
|
||||||
|
|
||||||
export async function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
const allPosts = await getCollection('journal');
|
const allPosts = await getCollection("journal");
|
||||||
const allTags = [...new Set(allPosts.flatMap((post) => post.data.tags || []))];
|
const allTags = [
|
||||||
|
...new Set(allPosts.flatMap((post) => post.data.tags || [])),
|
||||||
|
];
|
||||||
|
|
||||||
return allTags.map((tag) => {
|
return allTags.map((tag) => {
|
||||||
const filteredPosts = allPosts.filter((post) => post.data.tags?.includes(tag));
|
const filteredPosts = allPosts.filter((post) =>
|
||||||
return {
|
post.data.tags?.includes(tag),
|
||||||
params: { tag },
|
);
|
||||||
props: { posts: filteredPosts },
|
return {
|
||||||
};
|
params: { tag },
|
||||||
});
|
props: { posts: filteredPosts },
|
||||||
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const { tag } = Astro.params;
|
const { tag } = Astro.params;
|
||||||
@@ -21,19 +25,23 @@ const { posts } = Astro.props;
|
|||||||
---
|
---
|
||||||
|
|
||||||
<GameLayout title={`Récits: ${tag}`}>
|
<GameLayout title={`Récits: ${tag}`}>
|
||||||
<h1>Récits avec la balise : <span class="tag-title">{tag}</span></h1>
|
<h1>Récits avec la balise : <span class="tag-title">{tag}</span></h1>
|
||||||
|
|
||||||
<div class="card-grid">
|
<div class="card-grid">
|
||||||
{
|
{
|
||||||
posts.map((post) => (
|
posts.map((post) => (
|
||||||
<GoldButton href={`/journal/${post.slug}/`} title={post.data.title} body={`Publié le ${post.data.publishDate.toLocaleDateString('fr-FR')}`} />
|
<GoldButton
|
||||||
))
|
href={`/journal/${post.id}/`}
|
||||||
}
|
title={post.data.title}
|
||||||
</div>
|
body={`Publié le ${post.data.publishDate.toLocaleDateString("fr-FR")}`}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</div>
|
||||||
</GameLayout>
|
</GameLayout>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.tag-title {
|
.tag-title {
|
||||||
color: #c89b3c;
|
color: #c89b3c;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
---
|
|
||||||
import { getCollection } from 'astro:content';
|
|
||||||
import GameLayout from '../../layouts/GameLayout.astro';
|
|
||||||
import ParchmentCard from '../../components/ui/ParchmentCard.astro';
|
|
||||||
|
|
||||||
// 1. Génère une page pour chaque entrée de la collection 'logs'
|
|
||||||
export async function getStaticPaths() {
|
|
||||||
const logEntries = await getCollection('logs');
|
|
||||||
return logEntries.map((entry) => ({
|
|
||||||
params: { slug: entry.slug },
|
|
||||||
props: entry,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. Récupère les props pour la page actuelle
|
|
||||||
const post = Astro.props;
|
|
||||||
const { Content } = await post.render();
|
|
||||||
---
|
|
||||||
|
|
||||||
<GameLayout title={post.data.title}>
|
|
||||||
<ParchmentCard>
|
|
||||||
<h1>{post.data.title}</h1>
|
|
||||||
<div class="meta">
|
|
||||||
Publié le {post.data.publishDate.toLocaleDateString('fr-FR')}
|
|
||||||
</div>
|
|
||||||
{post.data.tags && (
|
|
||||||
<div class="tags-container">
|
|
||||||
{post.data.tags.map((tag) => (
|
|
||||||
<a href={`/logs/tags/${tag}`} class="tag">{tag}</a>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<article class="prose">
|
|
||||||
<Content />
|
|
||||||
</article>
|
|
||||||
</ParchmentCard>
|
|
||||||
</GameLayout>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
/* Les styles des tags sont maintenant globaux dans GameLayout.astro */
|
|
||||||
|
|
||||||
.meta {
|
|
||||||
text-align: center;
|
|
||||||
font-style: italic;
|
|
||||||
margin-bottom: 2rem;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
---
|
|
||||||
import { getCollection } from 'astro:content';
|
|
||||||
import GameLayout from '../../layouts/GameLayout.astro';
|
|
||||||
import ContentSearch from '../../components/ContentSearch.astro';
|
|
||||||
|
|
||||||
// 1. Récupère TOUS les logs et les trie.
|
|
||||||
const allPosts = await getCollection('logs');
|
|
||||||
const sortedPosts = allPosts.sort(
|
|
||||||
(a, b) => b.data.publishDate.valueOf() - a.data.publishDate.valueOf()
|
|
||||||
);
|
|
||||||
|
|
||||||
// 2. Extrait toutes les balises uniques
|
|
||||||
const allTags = [...new Set(allPosts.flatMap(post => post.data.tags || []))];
|
|
||||||
---
|
|
||||||
|
|
||||||
<GameLayout title="Logs de Construction">
|
|
||||||
<h1>⚙️ Logs de Construction</h1>
|
|
||||||
<p style="text-align: center; margin-bottom: 3rem;">
|
|
||||||
Les coulisses techniques du projet. Utilisez la barre de recherche pour trouver un log.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<!-- 3. On utilise le composant de recherche pour les logs -->
|
|
||||||
<ContentSearch posts={sortedPosts} tags={allTags} basePath="logs" />
|
|
||||||
|
|
||||||
</GameLayout>
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
---
|
|
||||||
import { getCollection } from 'astro:content';
|
|
||||||
import GameLayout from '../../../layouts/GameLayout.astro';
|
|
||||||
import GoldButton from '../../../components/ui/GoldButton.astro';
|
|
||||||
|
|
||||||
export async function getStaticPaths() {
|
|
||||||
const allPosts = await getCollection('logs');
|
|
||||||
const allTags = [...new Set(allPosts.flatMap((post) => post.data.tags || []))];
|
|
||||||
|
|
||||||
return allTags.map((tag) => {
|
|
||||||
const filteredPosts = allPosts.filter((post) => post.data.tags?.includes(tag));
|
|
||||||
return {
|
|
||||||
params: { tag },
|
|
||||||
props: { posts: filteredPosts },
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const { tag } = Astro.params;
|
|
||||||
const { posts } = Astro.props;
|
|
||||||
---
|
|
||||||
|
|
||||||
<GameLayout title={`Logs: ${tag}`}>
|
|
||||||
<h1>Logs avec la balise : <span class="tag-title">{tag}</span></h1>
|
|
||||||
|
|
||||||
<div class="card-grid">
|
|
||||||
{
|
|
||||||
posts.map((post) => (
|
|
||||||
<GoldButton href={`/logs/${post.slug}/`} title={post.data.title} body={`Publié le ${post.data.publishDate.toLocaleDateString('fr-FR')}`} />
|
|
||||||
))
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</GameLayout>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.tag-title {
|
|
||||||
color: #c89b3c;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
---
|
|
||||||
import GameLayout from '../layouts/GameLayout.astro';
|
|
||||||
import ParchmentCard from '../components/ui/ParchmentCard.astro';
|
|
||||||
---
|
|
||||||
|
|
||||||
<GameLayout title="L'Observatoire des Songes - Sweet Journey">
|
|
||||||
<ParchmentCard>
|
|
||||||
<h1>🔭 L'Observatoire des Songes</h1>
|
|
||||||
<p>
|
|
||||||
Un pèlerin, même dans les mers de sable, doit lever les yeux vers les constellations pour ne pas perdre son chemin. Mon voyage n'est pas solitaire ; il est guidé par les échos d'autres mondes, les murmures d'autres créateurs. Cet observatoire est ma carte du ciel, où chaque étoile est une âme dont la lumière m'inspire.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Les Tisseurs de Rêves : Artistes & Développeurs</h2>
|
|
||||||
<p>Certains artisans, comme le maître Hayao Miyazaki, créent des mondes où le vent, les arbres et les esprits ont une voix. Leurs récits sont des leçons d'harmonie, un rappel que même la plus petite créature a sa place dans le grand cycle. J'étudie leurs œuvres comme un ancien grimoire, y cherchant la maîtrise de la forme et du mouvement.</p>
|
|
||||||
|
|
||||||
<h2>Mes Compagnons de Quête</h2>
|
|
||||||
<p>Mon pèlerinage serait vain sans ceux qui marchent à mes côtés. Chacun est une étoile dans ma nuit, une source de force et de récits inattendus. Leur courage et leurs bizarreries nourrissent mon voyage autant que le sable :</p>
|
|
||||||
<ul>
|
|
||||||
<li><strong>Orson, le Gardien du Froid :</strong> Notre Maître de Jeu, un être aussi énigmatique et froid que sa patrie gelée. Il tisse les fils de notre destinée tout en suivant la sienne : une quête de vengeance pour sa sœur disparue, marquée au fer rouge par un symbole arcanique. Il est le vent glacial qui nous pousse en avant.</li>
|
|
||||||
<li><strong>Gurdill "Cul Brillant" :</strong> Un prince nain en exil, dont le surnom lumineux cache une profonde connaissance de la forge. Banni par les siens, il cherche à prouver sa valeur, son marteau elfique à la main. Sa quête de rédemption est aussi flamboyante que son fameux caleçon.</li>
|
|
||||||
<li><strong>Bulle aux Mains d’Or :</strong> Une fée guérisseuse, exilée volontaire de son royaume pour comprendre la souffrance du monde matériel. Sa lumière est un baume pour nos blessures, et sa naïveté un rappel constant de la pureté que nous cherchons à protéger.</li>
|
|
||||||
<li><strong>Jinn le Mélodiste :</strong> Un barde Genasi au sang de feu, dont la musique est aussi ardente que son tempérament. Sa quête pour retrouver l'épée de ses ancêtres est un chant d'honneur qui rythme nos pas et enflamme nos cœurs.</li>
|
|
||||||
<li><strong>Nyrae la Guérisseuse :</strong> Une Tabaxi dont les pas silencieux la guident loin de sa forêt natale. Son instinct et sa connaissance des onguents sont un réconfort précieux, une présence sauvage et apaisante dans notre groupe hétéroclite.</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h2>Les Murmures du Vent</h2>
|
|
||||||
|
|
||||||
<h2>Les Chroniques d'Autres Mondes</h2>
|
|
||||||
</ParchmentCard>
|
|
||||||
</GameLayout>
|
|
||||||
|
|
||||||
</Layout>
|
|
||||||
Reference in New Issue
Block a user