Palettes harmoniques, logo g breve (Decision), Protocoles promu

- Moods: palettes multi-teintes (secondary, tertiary par mood)
  Peps: corail/ocre/bleu electrique ; Zen: sauge/lavande/terre cuite
  Chagrine: violet/cyan/magenta/or ; Grave: ambre/cuivre/bleu acier
- Logo: gavel + g(Decision) — incompletude de Godel
- Dashboard: 4 cartes d'entree (Documents, Decisions, Protocoles, Mandats)
  chacune avec sa couleur propre
- Protocoles promu au meme rang que les autres sections
  (boite a outils de vote + workflows n8n via MCP)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Yvv
2026-02-28 19:39:25 +01:00
parent 61a414d214
commit 9b6388a600
5 changed files with 169 additions and 133 deletions

View File

@@ -90,8 +90,8 @@ function isActive(to: string) {
<UIcon name="i-lucide-menu" class="text-lg" /> <UIcon name="i-lucide-menu" class="text-lg" />
</button> </button>
<NuxtLink to="/" class="app-header__logo"> <NuxtLink to="/" class="app-header__logo">
<span class="app-header__logo-mark">G</span> <UIcon name="i-lucide-gavel" class="app-header__logo-icon" />
<span class="app-header__logo-text">libredecision</span> <span class="app-header__logo-g">ğ</span><span class="app-header__logo-paren">(</span><span class="app-header__logo-word">Decision</span><span class="app-header__logo-paren">)</span>
</NuxtLink> </NuxtLink>
</div> </div>
@@ -207,7 +207,7 @@ function isActive(to: string) {
<!-- Footer --> <!-- Footer -->
<footer class="app-footer"> <footer class="app-footer">
<span>Glibredecision v0.1.0</span> <span>ğ(Decision) v0.1.0</span>
<span class="app-footer__sep">·</span> <span class="app-footer__sep">·</span>
<span>Licence libre</span> <span>Licence libre</span>
</footer> </footer>
@@ -268,18 +268,31 @@ function isActive(to: string) {
.app-header__logo { .app-header__logo {
text-decoration: none; text-decoration: none;
display: flex; display: flex;
align-items: baseline; align-items: center;
gap: 0; gap: 0.375rem;
} }
.app-header__logo-mark { .app-header__logo-icon {
font-size: 1.125rem;
color: var(--mood-accent);
}
.app-header__logo-g {
font-size: 1.25rem; font-size: 1.25rem;
font-weight: 800; font-weight: 800;
color: var(--mood-accent); color: var(--mood-accent);
line-height: 1; line-height: 1;
font-style: italic;
} }
.app-header__logo-text { .app-header__logo-paren {
font-size: 0.9375rem;
font-weight: 300;
color: var(--mood-text-muted);
letter-spacing: -0.02em;
}
.app-header__logo-word {
font-size: 0.9375rem; font-size: 0.9375rem;
font-weight: 600; font-weight: 600;
color: var(--mood-text); color: var(--mood-text);

View File

@@ -1,140 +1,150 @@
/* ========================================================================== /* ==========================================================================
Glibredecision — Mood / Ambiance System ğ(Decision) — Mood / Ambiance System
4 moods: Peps (light), Zen (light), Chagrine (dark), Grave (dark) Palettes harmoniques variees, colores en lite, lumineux en dark.
Design: saturated, modern, zero pastels.
========================================================================== */ ========================================================================== */
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
Peps — Energique, vif, franc (Light) Peps — Chaud, colore, tonique (Light)
Palette: corail / ocre / bleu electrique / vert vif
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
.mood-peps { .mood-peps {
--mood-bg: #fafafa; --mood-bg: #faf9f6;
--mood-surface: #ffffff; --mood-surface: #ffffff;
--mood-surface-hover: #f5f0ec; --mood-surface-hover: #fdf2ec;
--mood-text: #18120e; --mood-text: #1e1410;
--mood-text-muted: #6e5f52; --mood-text-muted: #7a5e48;
--mood-accent: #d44a10; --mood-accent: #d44a10;
--mood-accent-soft: rgba(212, 74, 16, 0.08); --mood-accent-soft: rgba(212, 74, 16, 0.08);
--mood-accent-text: #ffffff; --mood-accent-text: #ffffff;
--mood-border: #e0d5cb; --mood-border: #e8d8c8;
--mood-success: #18843b; --mood-secondary: #2874a6;
--mood-warning: #c27e07; --mood-tertiary: #c4841d;
--mood-error: #c42b2b; --mood-success: #1a8c3e;
--mood-gradient: linear-gradient(160deg, #faf8f5 0%, #ffffff 50%, #faf7f4 100%); --mood-warning: #c47d0a;
--mood-shadow: rgba(120, 60, 10, 0.06); --mood-error: #c23028;
--mood-gradient: linear-gradient(145deg, #fdf8f0 0%, #ffffff 40%, #f0f6fb 100%);
--mood-shadow: rgba(180, 80, 20, 0.07);
--mood-input-bg: #ffffff; --mood-input-bg: #ffffff;
--mood-input-border: #c9bdb0; --mood-input-border: #d4c0aa;
--mood-input-focus: #d44a10; --mood-input-focus: #d44a10;
--mood-status-prepa: #b35c0a; --mood-status-prepa: #b8600e;
--mood-status-prepa-bg: rgba(179, 92, 10, 0.12); --mood-status-prepa-bg: rgba(184, 96, 14, 0.12);
--mood-status-vote: #1856a8; --mood-status-vote: #2874a6;
--mood-status-vote-bg: rgba(24, 86, 168, 0.10); --mood-status-vote-bg: rgba(40, 116, 166, 0.10);
--mood-status-vigueur: #18843b; --mood-status-vigueur: #1a8c3e;
--mood-status-vigueur-bg: rgba(24, 132, 59, 0.10); --mood-status-vigueur-bg: rgba(26, 140, 62, 0.10);
--mood-status-clos: #5c5c5c; --mood-status-clos: #6e5844;
--mood-status-clos-bg: rgba(92, 92, 92, 0.08); --mood-status-clos-bg: rgba(110, 88, 68, 0.08);
} }
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
Zen — Ancre, equilibre, sobre (Light) Zen — Frais, vegetal, vivant (Light)
Palette: sauge / lavande / terre cuite / bleu ciel
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
.mood-zen { .mood-zen {
--mood-bg: #f7f9f7; --mood-bg: #f6f9f5;
--mood-surface: #ffffff; --mood-surface: #ffffff;
--mood-surface-hover: #edf3ee; --mood-surface-hover: #ecf4e8;
--mood-text: #141e14; --mood-text: #172014;
--mood-text-muted: #4a6650; --mood-text-muted: #4e6d48;
--mood-accent: #2d7a4a; --mood-accent: #2e8250;
--mood-accent-soft: rgba(45, 122, 74, 0.07); --mood-accent-soft: rgba(46, 130, 80, 0.07);
--mood-accent-text: #ffffff; --mood-accent-text: #ffffff;
--mood-border: #c2d4c6; --mood-border: #bdd4b8;
--mood-success: #1d8a42; --mood-secondary: #7868a6;
--mood-warning: #b07309; --mood-tertiary: #b86830;
--mood-error: #be3232; --mood-success: #1d9048;
--mood-gradient: linear-gradient(160deg, #f4f8f4 0%, #ffffff 50%, #f5f8f5 100%); --mood-warning: #a87020;
--mood-shadow: rgba(30, 80, 50, 0.05); --mood-error: #b83838;
--mood-gradient: linear-gradient(145deg, #f2f8ef 0%, #ffffff 40%, #f4f0f8 100%);
--mood-shadow: rgba(40, 100, 60, 0.06);
--mood-input-bg: #ffffff; --mood-input-bg: #ffffff;
--mood-input-border: #a8c0ad; --mood-input-border: #a4c4a0;
--mood-input-focus: #2d7a4a; --mood-input-focus: #2e8250;
--mood-status-prepa: #9e6b0a; --mood-status-prepa: #a87020;
--mood-status-prepa-bg: rgba(158, 107, 10, 0.10); --mood-status-prepa-bg: rgba(168, 112, 32, 0.10);
--mood-status-vote: #1565a5; --mood-status-vote: #6858a0;
--mood-status-vote-bg: rgba(21, 101, 165, 0.10); --mood-status-vote-bg: rgba(104, 88, 160, 0.10);
--mood-status-vigueur: #1d8a42; --mood-status-vigueur: #1d9048;
--mood-status-vigueur-bg: rgba(29, 138, 66, 0.10); --mood-status-vigueur-bg: rgba(29, 144, 72, 0.10);
--mood-status-clos: #606060; --mood-status-clos: #607858;
--mood-status-clos-bg: rgba(96, 96, 96, 0.08); --mood-status-clos-bg: rgba(96, 120, 88, 0.08);
} }
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
Chagrine — Dense, veloute, introspectif (Dark) Chagrine — Lumineux, electrique, profond (Dark)
Palette: violet vif / cyan / magenta / or
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
.mood-chagrine { .mood-chagrine {
--mood-bg: #16121e; --mood-bg: #14101e;
--mood-surface: #1e1828; --mood-surface: #1c1628;
--mood-surface-hover: #281f36; --mood-surface-hover: #261e38;
--mood-text: #e0d8ec; --mood-text: #e4daf0;
--mood-text-muted: #8e80a8; --mood-text-muted: #9888b8;
--mood-accent: #8b6cc4; --mood-accent: #9470d8;
--mood-accent-soft: rgba(139, 108, 196, 0.12); --mood-accent-soft: rgba(148, 112, 216, 0.12);
--mood-accent-text: #ffffff; --mood-accent-text: #ffffff;
--mood-border: #2e2540; --mood-border: #302448;
--mood-success: #48c278; --mood-secondary: #38c8c8;
--mood-warning: #d4a030; --mood-tertiary: #e07090;
--mood-error: #e06060; --mood-success: #40d888;
--mood-gradient: linear-gradient(160deg, #16121e 0%, #1e1828 50%, #1a1524 100%); --mood-warning: #e0b040;
--mood-shadow: rgba(100, 60, 180, 0.10); --mood-error: #e86060;
--mood-input-bg: #1e1828; --mood-gradient: linear-gradient(145deg, #14101e 0%, #1c1628 40%, #101820 100%);
--mood-input-border: #3a2e52; --mood-shadow: rgba(120, 80, 200, 0.12);
--mood-input-focus: #8b6cc4; --mood-input-bg: #1c1628;
--mood-input-border: #3c2c58;
--mood-input-focus: #9470d8;
--mood-status-prepa: #c4a050; --mood-status-prepa: #e0b040;
--mood-status-prepa-bg: rgba(196, 160, 80, 0.14); --mood-status-prepa-bg: rgba(224, 176, 64, 0.15);
--mood-status-vote: #7090d0; --mood-status-vote: #38c8c8;
--mood-status-vote-bg: rgba(112, 144, 208, 0.14); --mood-status-vote-bg: rgba(56, 200, 200, 0.14);
--mood-status-vigueur: #48c278; --mood-status-vigueur: #40d888;
--mood-status-vigueur-bg: rgba(72, 194, 120, 0.14); --mood-status-vigueur-bg: rgba(64, 216, 136, 0.14);
--mood-status-clos: #706080; --mood-status-clos: #7868a0;
--mood-status-clos-bg: rgba(112, 96, 128, 0.12); --mood-status-clos-bg: rgba(120, 104, 160, 0.12);
} }
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
Grave — Mineral, solennel, net (Dark) Grave — Chaud, mineral, lumineux (Dark)
Palette: ambre / cuivre / bleu acier / vert oxyde
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
.mood-grave { .mood-grave {
--mood-bg: #111214; --mood-bg: #12110e;
--mood-surface: #191a1e; --mood-surface: #1a1814;
--mood-surface-hover: #22201c; --mood-surface-hover: #24201a;
--mood-text: #e2e0d8; --mood-text: #e8e0d0;
--mood-text-muted: #8a877e; --mood-text-muted: #a09880;
--mood-accent: #c49530; --mood-accent: #d09828;
--mood-accent-soft: rgba(196, 149, 48, 0.10); --mood-accent-soft: rgba(208, 152, 40, 0.10);
--mood-accent-text: #111214; --mood-accent-text: #12110e;
--mood-border: #2a2a2e; --mood-border: #302c24;
--mood-success: #4ac070; --mood-secondary: #5898c8;
--mood-warning: #d4a530; --mood-tertiary: #c87848;
--mood-error: #d85050; --mood-success: #48c870;
--mood-gradient: linear-gradient(160deg, #111214 0%, #191a1e 50%, #141518 100%); --mood-warning: #d0a030;
--mood-shadow: rgba(160, 120, 30, 0.08); --mood-error: #d05050;
--mood-input-bg: #191a1e; --mood-gradient: linear-gradient(145deg, #12110e 0%, #1a1814 40%, #141618 100%);
--mood-input-border: #38362e; --mood-shadow: rgba(180, 130, 40, 0.10);
--mood-input-focus: #c49530; --mood-input-bg: #1a1814;
--mood-input-border: #3a3428;
--mood-input-focus: #d09828;
--mood-status-prepa: #c49530; --mood-status-prepa: #c87848;
--mood-status-prepa-bg: rgba(196, 149, 48, 0.14); --mood-status-prepa-bg: rgba(200, 120, 72, 0.15);
--mood-status-vote: #5a90c8; --mood-status-vote: #5898c8;
--mood-status-vote-bg: rgba(90, 144, 200, 0.14); --mood-status-vote-bg: rgba(88, 152, 200, 0.14);
--mood-status-vigueur: #4ac070; --mood-status-vigueur: #48c870;
--mood-status-vigueur-bg: rgba(74, 192, 112, 0.14); --mood-status-vigueur-bg: rgba(72, 200, 112, 0.14);
--mood-status-clos: #686860; --mood-status-clos: #787060;
--mood-status-clos-bg: rgba(104, 104, 96, 0.12); --mood-status-clos-bg: rgba(120, 112, 96, 0.12);
} }
/* ========================================================================== /* ==========================================================================
Global design tokens — modern, refined, thin Global design tokens
========================================================================== */ ========================================================================== */
body { body {
@@ -143,7 +153,7 @@ body {
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
/* --- Status pills — compact, saturated, NO pastels --- */ /* --- Status pills --- */
.status-pill { .status-pill {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
@@ -183,25 +193,14 @@ body {
} }
/* ========================================================================== /* ==========================================================================
Global overrides — Nuxt UI refinements Nuxt UI overrides
========================================================================== */ ========================================================================== */
/* Inputs: thin, clean, mood-aware */
:root .mood-peps, :root .mood-peps,
:root .mood-zen, :root .mood-zen,
:root .mood-chagrine, :root .mood-chagrine,
:root .mood-grave { :root .mood-grave {
/* UInput / UTextarea */
--ui-border: var(--mood-input-border); --ui-border: var(--mood-input-border);
--ui-bg: var(--mood-input-bg); --ui-bg: var(--mood-input-bg);
--ui-text-highlighted: var(--mood-accent); --ui-text-highlighted: var(--mood-accent);
} }
/* UButton refinements */
:root .mood-peps button[class*="UButton"],
:root .mood-zen button[class*="UButton"],
:root .mood-chagrine button[class*="UButton"],
:root .mood-grave button[class*="UButton"] {
font-weight: 500;
letter-spacing: 0.01em;
}

View File

@@ -12,10 +12,10 @@ export interface Mood {
const STORAGE_KEY = 'glibredecision_mood' const STORAGE_KEY = 'glibredecision_mood'
const moods: Mood[] = [ const moods: Mood[] = [
{ id: 'peps', label: 'Peps', description: 'Energique et franc', icon: 'i-lucide-sun', color: '#d44a10', isDark: false }, { id: 'peps', label: 'Peps', description: 'Chaud et tonique', icon: 'i-lucide-sun', color: '#d44a10', isDark: false },
{ id: 'zen', label: 'Zen', description: 'Ancre et sobre', icon: 'i-lucide-leaf', color: '#2d7a4a', isDark: false }, { id: 'zen', label: 'Zen', description: 'Frais et vegetal', icon: 'i-lucide-leaf', color: '#2e8250', isDark: false },
{ id: 'chagrine', label: 'Chagrine', description: 'Dense et veloute', icon: 'i-lucide-moon', color: '#8b6cc4', isDark: true }, { id: 'chagrine', label: 'Chagrine', description: 'Electrique et profond', icon: 'i-lucide-moon', color: '#9470d8', isDark: true },
{ id: 'grave', label: 'Grave', description: 'Mineral et solennel', icon: 'i-lucide-shield', color: '#c49530', isDark: true }, { id: 'grave', label: 'Grave', description: 'Mineral et lumineux', icon: 'i-lucide-shield', color: '#d09828', isDark: true },
] ]
const currentMood: Ref<string> = ref('peps') const currentMood: Ref<string> = ref('peps')

View File

@@ -26,7 +26,7 @@ onMounted(async () => {
} }
}) })
/** Entry cards — the 3 main doors. */ /** Entry cards — the 4 main doors. */
const entryCards = computed(() => [ const entryCards = computed(() => [
{ {
key: 'documents', key: 'documents',
@@ -37,6 +37,7 @@ const entryCards = computed(() => [
countLabel: `${documents.activeDocuments.length} actif${documents.activeDocuments.length > 1 ? 's' : ''}`, countLabel: `${documents.activeDocuments.length} actif${documents.activeDocuments.length > 1 ? 's' : ''}`,
totalLabel: `${documents.list.length} au total`, totalLabel: `${documents.list.length} au total`,
description: 'Textes fondateurs sous vote permanent', description: 'Textes fondateurs sous vote permanent',
color: 'var(--mood-accent)',
}, },
{ {
key: 'decisions', key: 'decisions',
@@ -47,6 +48,18 @@ const entryCards = computed(() => [
countLabel: `${decisions.activeDecisions.length} en cours`, countLabel: `${decisions.activeDecisions.length} en cours`,
totalLabel: `${decisions.list.length} au total`, totalLabel: `${decisions.list.length} au total`,
description: 'Processus de decision collectifs', description: 'Processus de decision collectifs',
color: 'var(--mood-secondary, var(--mood-accent))',
},
{
key: 'protocoles',
title: 'Protocoles',
icon: 'i-lucide-settings',
to: '/protocols',
count: protocols.protocols.length,
countLabel: `${protocols.protocols.length} modalite${protocols.protocols.length > 1 ? 's' : ''}`,
totalLabel: 'Boite a outils de vote + workflows',
description: 'Modalites de vote, formules, workflows n8n',
color: 'var(--mood-tertiary, var(--mood-accent))',
}, },
{ {
key: 'mandats', key: 'mandats',
@@ -57,6 +70,7 @@ const entryCards = computed(() => [
countLabel: null, countLabel: null,
totalLabel: null, totalLabel: null,
description: 'Un contexte, un objectif, une duree, une ou plusieurs nominations ; par defaut : nomination d\'un binome.', description: 'Un contexte, un objectif, une duree, une ou plusieurs nominations ; par defaut : nomination d\'un binome.',
color: 'var(--mood-success)',
}, },
]) ])
@@ -91,7 +105,7 @@ function formatDate(dateStr: string): string {
<div class="dash"> <div class="dash">
<!-- Welcome --> <!-- Welcome -->
<div class="dash__welcome"> <div class="dash__welcome">
<h1 class="dash__title">Glibredecision</h1> <h1 class="dash__title"><span class="dash__title-g">ğ</span><span class="dash__title-paren">(</span>Decision<span class="dash__title-paren">)</span></h1>
<p class="dash__subtitle"> <p class="dash__subtitle">
Decisions collectives pour la communaute Duniter / G1 Decisions collectives pour la communaute Duniter / G1
</p> </p>
@@ -100,7 +114,7 @@ function formatDate(dateStr: string): string {
<!-- Entry cards --> <!-- Entry cards -->
<div class="dash__entries"> <div class="dash__entries">
<template v-if="loading"> <template v-if="loading">
<LoadingSkeleton v-for="i in 3" :key="i" :lines="3" card /> <LoadingSkeleton v-for="i in 4" :key="i" :lines="3" card />
</template> </template>
<template v-else> <template v-else>
<NuxtLink <NuxtLink
@@ -108,6 +122,7 @@ function formatDate(dateStr: string): string {
:key="card.key" :key="card.key"
:to="card.to" :to="card.to"
class="entry-card" class="entry-card"
:style="{ '--card-color': card.color }"
> >
<div class="entry-card__icon"> <div class="entry-card__icon">
<UIcon :name="card.icon" class="text-xl" /> <UIcon :name="card.icon" class="text-xl" />
@@ -253,6 +268,13 @@ function formatDate(dateStr: string): string {
color: var(--mood-accent); color: var(--mood-accent);
letter-spacing: -0.02em; letter-spacing: -0.02em;
} }
.dash__title-g {
font-style: italic;
}
.dash__title-paren {
font-weight: 300;
color: var(--mood-text-muted);
}
.dash__subtitle { .dash__subtitle {
margin-top: 0.25rem; margin-top: 0.25rem;
font-size: 0.875rem; font-size: 0.875rem;
@@ -280,7 +302,7 @@ function formatDate(dateStr: string): string {
transition: border-color 0.15s ease, box-shadow 0.15s ease; transition: border-color 0.15s ease, box-shadow 0.15s ease;
} }
.entry-card:hover { .entry-card:hover {
border-color: var(--mood-accent); border-color: var(--card-color, var(--mood-accent));
box-shadow: 0 2px 8px var(--mood-shadow); box-shadow: 0 2px 8px var(--mood-shadow);
} }
@@ -291,8 +313,8 @@ function formatDate(dateStr: string): string {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
border-radius: 6px; border-radius: 6px;
background: var(--mood-accent-soft); background: color-mix(in srgb, var(--card-color, var(--mood-accent)) 10%, transparent);
color: var(--mood-accent); color: var(--card-color, var(--mood-accent));
margin-bottom: 0.25rem; margin-bottom: 0.25rem;
} }
@@ -306,7 +328,7 @@ function formatDate(dateStr: string): string {
.entry-card__count { .entry-card__count {
font-size: 1.25rem; font-size: 1.25rem;
font-weight: 800; font-weight: 800;
color: var(--mood-accent); color: var(--card-color, var(--mood-accent));
line-height: 1; line-height: 1;
} }
@@ -331,7 +353,7 @@ function formatDate(dateStr: string): string {
} }
.entry-card:hover .entry-card__arrow { .entry-card:hover .entry-card__arrow {
opacity: 1; opacity: 1;
color: var(--mood-accent); color: var(--card-color, var(--mood-accent));
} }
/* --- Connect banner --- */ /* --- Connect banner --- */

View File

@@ -57,9 +57,11 @@ onMounted(() => {
<div class="login-card"> <div class="login-card">
<!-- Logo --> <!-- Logo -->
<div class="login-card__header"> <div class="login-card__header">
<span class="login-card__logo">G</span> <div class="login-card__logo">
<UIcon name="i-lucide-gavel" class="text-xl" />
</div>
<h1 class="login-card__title">Connexion</h1> <h1 class="login-card__title">Connexion</h1>
<p class="login-card__subtitle">Identite Duniter V2 · Ed25519</p> <p class="login-card__subtitle">ğ(Decision) · Duniter V2 · Ed25519</p>
</div> </div>
<!-- Steps indicator --> <!-- Steps indicator -->