Compare commits

...
17 Commits
Author SHA1 Message Date
bruno 7cf2a3fc25 Merge pull request 'Identité Kanbante : sidebar charbon, accent vert, icônes ligne, bouton thème en Administration (#54, #55)' (#56) from identite-verte-54-55 into main
CI / test (push) Successful in 4m0s
2026-10-28 23:13:34 -04:00
bruno 6602a070be Page Projets : copie URL dans le menu ⋯ + refonte thème barre Fusion/Spark (#44, #45)
CI / test (push) Failing after 0s
CI / test (pull_request) Failing after 0s
2026-10-28 23:12:56 -04:00
bruno 9e1ff33698 Page Projets : copie URL dans le menu ⋯ + refonte thème barre Fusion/Spark (#44, #45)
CI / test (push) Failing after 0s
2026-10-28 23:12:54 -04:00
bruno 47dd9c06a1 Page Projets : copie URL dans le menu ⋯ + refonte thème barre Fusion/Spark (#44, #45)
CI / test (push) Failing after 0s
2026-10-28 23:12:52 -04:00
bruno 90b9189169 Page Projets : copie URL dans le menu ⋯ + refonte thème barre Fusion/Spark (#44, #45)
CI / test (push) Failing after 1s
2026-10-28 23:12:50 -04:00
bruno 91ddfcd3b3 Page Projets : copie URL dans le menu ⋯ + refonte thème barre Fusion/Spark (#44, #45)
CI / test (push) Failing after 0s
2026-10-28 23:12:48 -04:00
bruno 2c10040046 Page Projets : copie URL dans le menu ⋯ + refonte thème barre Fusion/Spark (#44, #45)
CI / test (push) Failing after 0s
2026-10-28 23:12:46 -04:00
bruno 32fbe1d137 Page Projets : copie URL dans le menu ⋯ + refonte thème barre Fusion/Spark (#44, #45)
CI / test (push) Failing after 0s
2026-10-28 23:12:44 -04:00
bruno 4d1757e3d2 Page Projets : copie URL dans le menu ⋯ + refonte thème barre Fusion/Spark (#44, #45)
CI / test (push) Failing after 4m8s
2026-10-28 23:12:41 -04:00
bruno 9dc62885b0 Merge pull request 'Navigation : accordéon Administration + bouton Dark/Light (#51, #52)' (#53) from nav-theme-51-52 into main
CI / test (push) Successful in 3m42s
2026-10-28 23:00:16 -04:00
bruno cc007dfa04 Page Projets : copie URL dans le menu ⋯ + refonte thème barre Fusion/Spark (#44, #45)
CI / test (push) Failing after 0s
CI / test (pull_request) Failing after 0s
2026-10-28 22:59:13 -04:00
bruno f0ca8b9ec6 Page Projets : copie URL dans le menu ⋯ + refonte thème barre Fusion/Spark (#44, #45)
CI / test (push) Successful in 4m24s
2026-10-28 22:59:11 -04:00
bruno 6a938cf778 Page Projets : copie URL dans le menu ⋯ + refonte thème barre Fusion/Spark (#44, #45)
CI / test (push) Failing after 0s
2026-10-28 22:59:09 -04:00
bruno c60694bf23 Page Projets : copie URL dans le menu ⋯ + refonte thème barre Fusion/Spark (#44, #45)
CI / test (push) Failing after 0s
2026-10-28 22:59:07 -04:00
bruno a08fa53bab Page Projets : copie URL dans le menu ⋯ + refonte thème barre Fusion/Spark (#44, #45)
CI / test (push) Failing after 0s
2026-10-28 22:59:05 -04:00
bruno 1c81259e0d Page Projets : copie URL dans le menu ⋯ + refonte thème barre Fusion/Spark (#44, #45)
CI / test (push) Failing after 0s
2026-10-28 22:59:03 -04:00
bruno 5749b1c718 Merge pull request 'Thème du site : look agent-dev / barre Fusion, fin du bleu/mauve (#49)' (#50) from theme-agent-49 into main
CI / test (push) Successful in 4m50s
2026-10-28 22:48:45 -04:00
8 changed files with 255 additions and 66 deletions
+12
View File
@@ -1,3 +1,15 @@
## 0.41.0 — 2026-10-28 — Identité Kanbante : sidebar charbon, accent vert, icônes ligne, bouton thème en Administration (#54, #55)
- **Sidebar (#54)** : fond charbon draco (`rgba(26, 28, 26, 0.96)`) à la place du bleu-noir `rgba(13, 16, 24)` oublié par le re-thème 0.39.0 — la barre latérale a désormais la même teinte que le reste du site, en sombre comme en clair (clair déjà blanc).
- **Accent vert (#54)** : le rose Spark cède la place au vert Kanbante — `--accent: #0d9488`, second ton `#14b8a6` (clair : `#0f766e`), anneaux, focus, dégradés et replis associés. La barre Fusion partagée n'est pas touchée (Spark rose, marques des autres apps).
- **Icônes (#54)** : les emoji de la barre latérale sont remplacés par des SVG fins en trait (stroke currentColor), style rail Spark, pour chaque entrée de navigation ; le logo Kanbante devient des colonnes kanban blanches sur fond vert sarcelle.
- **Bouton Dark/Light (#55)** : déplacé de l'en-tête applicatif vers la section Administration de la barre latérale (icône seule en rail replié, libellé explicite sinon). Comportement inchangé (bascule + choix mémorisé). Conséquence : seuls les administrateurs le voient, la section Administration leur étant réservée.
## 0.40.0 — 2026-10-28 — Navigation : section Administration + bouton Dark/Light (#51, #52)
- **Accordéon (#51)** : la section Administration ne fermait jamais — le JS posait `nav-closed-admin`, mais `style.css` ne définissait les règles de fermeture que pour les 4 autres sections. Les règles admin sont ajoutées (fermeture et rotation du chevron) : l'accordéon redevient exclusif.
- **Bouton Dark/Light (#52)** : bouton « ☀️ Mode clair / 🌙 Mode sombre » dans l'en-tête applicatif, qui bascule `data-theme` sur `<html>` et mémorise le choix (localStorage, appliqué avant le rendu par l'amorce de `_header.html`). Thème clair sur les jetons draco (fond #f2f2f0, surfaces blanches/grises, accent rose conservé, second ton assombri pour les liens), barre Fusion et panneau Spark qui suivent. Défaut inchangé : sombre. `nav.js` est désormais versionné (`?v=`), comme dashboard.js depuis la 0.38.1.
## 0.39.0 — 2026-10-28 — Thème du site : look agent-dev / barre Fusion (#49)
- **Re-thème complet** : `style.css` passe sur les jetons draco-barre (Console v7.2) — fond #101211, surfaces #1a1c1a / #242624 / #20221f, bordure #2e302c, textes #eceee9 / #a6aba2 / #8b9089, accent rose Spark #c2437e (second ton #e078a8). Fond plat, plus de halos ni de dégradés violet→bleu, y compris les valeurs de repli et l'écran de connexion.
+1 -1
View File
@@ -177,7 +177,7 @@ from urllib.parse import urlparse
BASE_DIR = Path(__file__).resolve().parent.parent
APP_VERSION = "0.39.0"
APP_VERSION = "0.41.0"
def _env_bool(name: str, default: bool) -> bool:
+28 -4
View File
@@ -1,3 +1,15 @@
<script>
/* Thème (#52) : appliqué avant le rendu de la barre, pour
éviter le flash sombre quand l'utilisateur a choisi le
clair. Défaut = sombre (les gabarits portent
data-theme="dark") ; seul un choix mémorisé bascule. */
try {
var _t = localStorage.getItem('kanbante-theme');
if (_t === 'light' || _t === 'dark') {
document.documentElement.setAttribute('data-theme', _t);
}
} catch (e) { /* mode privé : le thème ne survit qu'à la page */ }
</script>
{% include "_draco_bar.html" %}
{# ── Cadre applicatif partagé (issue #16, refonte 0.16.0) ─────────
Barre latérale unique pour TOUTES les pages applicatives :
@@ -78,10 +90,10 @@
<aside class="sidebar" id="sidebar" aria-label="Navigation principale">
<div class="side-head">
<a href="/" class="side-logo" aria-label="Kanbante — accueil">
<span class="logo-mark">📋</span>
<span class="logo-mark"><svg viewBox="0 0 24 24" fill="#fff" aria-hidden="true"><rect x="3" y="4" width="5" height="16" rx="1"/><rect x="9.5" y="4" width="5" height="10" rx="1"/><rect x="16" y="4" width="5" height="13" rx="1"/></svg></span>
<span class="side-label gradient-text">Kanbante</span>
</a>
<button type="button" class="side-search palette-trigger" title="Recherche & commandes (Ctrl+K)" aria-label="Recherche et commandes (Ctrl+K)">🔍</button>
<button type="button" class="side-search palette-trigger" title="Recherche & commandes (Ctrl+K)" aria-label="Recherche et commandes (Ctrl+K)"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" aria-hidden="true"><circle cx="11" cy="11" r="7"/><path d="M20 20l-4-4"/></svg></button>
<button type="button" class="side-collapse" id="side-collapse" title="Replier ou déplier le menu" aria-label="Replier ou déplier le menu"><span class="side-collapse-ico">«</span></button>
</div>
{% if current_workspace and user_workspaces and user_workspaces|length > 1 %}
@@ -95,6 +107,9 @@
</select>
</form>
{% endif %}
{# Icônes de navigation (#54) : SVG fins en trait, style rail
Spark — monochromes (currentColor), pas d'emoji. #}
{% macro nav_icon(key) %}<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">{% if key == 'home' %}<path d="M3 11l9-8 9 8"/><path d="M5 10v11h14V10"/><path d="M10 21v-6h4v6"/>{% elif key == 'focus' %}<circle cx="12" cy="12" r="9"/><circle cx="12" cy="12" r="5"/><circle cx="12" cy="12" r="1" fill="currentColor"/>{% elif key == 'today' %}<path d="M7 18a5 5 0 0 1 10 0"/><path d="M3 18h18"/><path d="M12 9V6"/><path d="M5.5 11l1.5 1.5"/><path d="M18.5 11l-1.5 1.5"/>{% elif key == 'my' %}<circle cx="12" cy="8" r="3.5"/><path d="M4 20c0-3.5 3.5-5.5 8-5.5s8 2 8 5.5"/>{% elif key == 'briefing' %}<path d="M4 20V11"/><path d="M10 20V4"/><path d="M16 20v-8"/><path d="M3 20h18"/>{% elif key == 'standup' %}<path d="M4 5h16v11h-7l-4 4v-4H4z"/>{% elif key == 'digest' %}<path d="M6 3h12v18H6z"/><path d="M9 8h6"/><path d="M9 12h6"/><path d="M9 16h4"/>{% elif key == 'inflight' %}<path d="M3 12l19-9-7 18-4-6z"/><path d="M11 15L22 3"/>{% elif key == 'forecast' %}<path d="M3 18l5-6 4 3 9-9"/><path d="M16 6h5v5"/>{% elif key == 'health' %}<path d="M12 20C7 16 3 13 3 9a4.5 4.5 0 0 1 8-2.5A4.5 4.5 0 0 1 21 9c0 4-4 7-9 11z"/>{% elif key == 'rules' %}<path d="M6 3h12v18H6z"/><path d="M9 12l2 2 4-4"/>{% elif key == 'activity' %}<path d="M4 4h16v16H4z"/><path d="M7 8h10"/><path d="M7 12h10"/><path d="M7 16h6"/>{% elif key == 'search' %}<circle cx="11" cy="11" r="7"/><path d="M20 20l-4-4"/>{% elif key == 'capture' %}<path d="M13 2L4 14h6l-1 8 10-13h-6z"/>{% elif key == 'archives' %}<path d="M3 8h18"/><path d="M5 8v12h14V8"/><path d="M9 8v5h6V8"/>{% elif key == 'wall' %}<path d="M3 5h18v11H3z"/><path d="M9 21h6"/><path d="M12 16v5"/>{% elif key == 'admin' %}<path d="M4 4h7v7H4z"/><path d="M13 4h7v7h-7z"/><path d="M4 13h7v7H4z"/><path d="M13 13h7v7h-7z"/>{% elif key == 'admin_connections' %}<path d="M9 3v5"/><path d="M15 3v5"/><path d="M7 8h10v5a5 5 0 0 1-10 0z"/><path d="M12 18v3"/>{% elif key == 'admin_workspaces' %}<circle cx="12" cy="12" r="9"/><path d="M15 9l-2 4-4 2 2-4z"/>{% elif key == 'admin_columns' %}<path d="M4 4h4v16H4z"/><path d="M10 4h4v16h-4z"/><path d="M16 4h4v16h-4z"/>{% elif key == 'admin_settings' %}<circle cx="12" cy="12" r="3"/><path d="M12 2v3"/><path d="M12 19v3"/><path d="M2 12h3"/><path d="M19 12h3"/><path d="M4.5 4.5l2 2"/><path d="M17.5 17.5l2 2"/><path d="M19.5 4.5l-2 2"/><path d="M6.5 17.5l-2 2"/>{% else %}<circle cx="12" cy="12" r="9"/>{% endif %}</svg>{% endmacro %}
<nav class="side-nav">
{% for gkey, group, links in nav_groups %}
<div class="side-section" data-group="{{ gkey }}">
@@ -106,10 +121,16 @@
<div class="side-acc-inner">
{% for key, href, icon, label in links %}
<a href="{{ href }}" class="side-link{% if active_nav == key %} active{% endif %}" title="{{ label }}">
<span class="side-ico">{{ icon }}</span>
<span class="side-ico">{{ nav_icon(key) }}</span>
<span class="side-label">{{ label }}</span>
</a>
{% endfor %}
{% if gkey == 'admin' %}
<button type="button" class="side-link theme-toggle-link" id="theme-toggle" title="Basculer entre thème sombre et clair" aria-label="Basculer entre thème sombre et clair">
<span class="side-ico" data-theme-ico>☀️</span>
<span class="side-label" data-theme-label>Mode clair</span>
</button>
{% endif %}
</div>
</div>
</div>
@@ -123,6 +144,9 @@
<a href="/profile" class="side-logout" title="Mon profil">👤<span class="side-label"> {{ current_user.display_name or current_user.username }}</span></a>
{% endif %}
<span class="side-version side-label">v{{ version }}</span>
{% if not is_admin %}
<button type="button" class="theme-toggle-foot" id="theme-toggle" title="Basculer entre thème sombre et clair" aria-label="Basculer entre thème sombre et clair"><span data-theme-ico>☀️</span></button>
{% endif %}
{% if auth_enabled %}
<a href="/logout" class="side-logout" title="Se déconnecter">⏻<span class="side-label"> Sortir</span></a>
{% endif %}
@@ -142,5 +166,5 @@
{% endif %}
<button type="button" class="nav-pill palette-trigger topbar-search" title="Recherche et commandes (Ctrl+K)">🔍</button>
</div>
<script src="/static/js/nav.js" defer></script>
<script src="/static/js/nav.js?v={{ version }}" defer></script>
</header>
+103 -56
View File
@@ -17,8 +17,8 @@
--text: #eceee9;
--text-2: #a6aba2;
--text-3: #8b9089;
--accent: #c2437e;
--accent-2: #e078a8;
--accent: #0d9488;
--accent-2: #14b8a6;
--green: #10b981;
--yellow: #f59e0b;
--red: #ef4444;
@@ -26,7 +26,7 @@
--radius-sm: 10px;
--shadow: 0 8px 28px rgba(0, 0, 0, 0.38);
--shadow-sm: 0 2px 10px rgba(0, 0, 0, 0.25);
--ring: 0 0 0 3px rgba(194, 67, 126, 0.35);
--ring: 0 0 0 3px rgba(13, 148, 136, 0.35);
}
* { margin: 0; padding: 0; box-sizing: border-box; }
@@ -48,7 +48,7 @@ body {
line-height: 1.45;
}
::selection { background: rgba(194, 67, 126, 0.45); }
::selection { background: rgba(13, 148, 136, 0.45); }
a { color: var(--accent-2); text-decoration: none; }
a:hover { text-decoration: underline; }
@@ -79,7 +79,7 @@ button, input, select, textarea { font: inherit; }
padding: 8px 10px;
}
:where(input, textarea, select):focus-visible {
outline: 2px solid rgba(194, 67, 126, 0.55);
outline: 2px solid rgba(13, 148, 136, 0.55);
outline-offset: 0;
}
@@ -121,7 +121,7 @@ button, input, select, textarea { font: inherit; }
font-size: 1rem;
}
.gradient-text {
background: linear-gradient(120deg, #c2437e, #e078a8);
background: linear-gradient(120deg, #0d9488, #14b8a6);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
@@ -145,7 +145,7 @@ header h1 { font-size: 1.2rem; font-weight: 600; }
.nav-pill:hover { color: var(--text); background: var(--surface-2); text-decoration: none; }
.nav-pill.active {
color: #fff;
background: linear-gradient(135deg, rgba(194,67,126,.85), rgba(224,120,168,.85));
background: linear-gradient(135deg, rgba(13,148,136,.85), rgba(20,184,166,.85));
border-color: rgba(255,255,255,0.12);
}
@@ -155,7 +155,7 @@ header h1 { font-size: 1.2rem; font-weight: 600; }
font-size: 0.78rem;
font-weight: 600;
background: color-mix(in srgb, var(--accent) 18%, transparent);
color: #d99ab5;
color: #7dd3c8;
}
.badge.secondary { background: var(--surface-2); color: var(--text-2); }
@@ -281,13 +281,13 @@ a.kpi:hover { background: var(--surface-2); text-decoration: none; }
font-size: 0.68rem;
text-transform: uppercase;
letter-spacing: 0.6px;
color: #d99ab5;
color: #7dd3c8;
font-weight: 700;
}
.date { font-size: 0.75rem; color: var(--text-3); }
.project-card h3 { font-size: 1.08rem; margin-bottom: 6px; letter-spacing: -0.01em; }
.project-card h3 a { color: var(--text); }
.project-card h3 a:hover { color: #e078a8; text-decoration: none; }
.project-card h3 a:hover { color: #14b8a6; text-decoration: none; }
.desc {
font-size: 0.85rem;
color: var(--text-2);
@@ -363,7 +363,7 @@ a.kpi:hover { background: var(--surface-2); text-decoration: none; }
.milestone-chip:hover { color: var(--text); text-decoration: none; border-color: var(--border-strong); }
.milestone-chip.active {
color: #fff;
background: linear-gradient(135deg, rgba(194,67,126,.9), rgba(224,120,168,.9));
background: linear-gradient(135deg, rgba(13,148,136,.9), rgba(20,184,166,.9));
border-color: transparent;
}
.milestone-banner {
@@ -372,8 +372,8 @@ a.kpi:hover { background: var(--surface-2); text-decoration: none; }
gap: 16px;
margin: 14px 24px 0;
padding: 14px 18px;
background: linear-gradient(120deg, rgba(194,67,126,.14), rgba(224,120,168,.10));
border: 1px solid rgba(194,67,126,.35);
background: linear-gradient(120deg, rgba(13,148,136,.14), rgba(20,184,166,.10));
border: 1px solid rgba(13,148,136,.35);
border-radius: var(--radius);
flex-wrap: wrap;
}
@@ -490,7 +490,7 @@ a.kpi:hover { background: var(--surface-2); text-decoration: none; }
.kanban-card.dragging { opacity: 0.55; transform: rotate(2deg) scale(1.02); box-shadow: var(--shadow); }
.card-id {
font-size: 0.7rem;
color: #d99ab5;
color: #7dd3c8;
font-weight: 700;
margin-bottom: 4px;
display: flex;
@@ -641,7 +641,7 @@ footer {
.focus-group { margin-bottom: 30px; }
.focus-group h2 { font-size: 1.06rem; margin-bottom: 12px; display: flex; gap: 10px; align-items: center; }
.focus-group h2 a { color: var(--text); }
.focus-group h2 a:hover { color: #e078a8; text-decoration: none; }
.focus-group h2 a:hover { color: #14b8a6; text-decoration: none; }
.focus-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 12px; }
.focus-card { margin-bottom: 0; cursor: default; }
@@ -772,7 +772,7 @@ footer {
}
.issue-row:hover { border-color: var(--border-strong); }
.issue-main { color: var(--text); flex: 1; min-width: 220px; }
.issue-main:hover { color: #e078a8; text-decoration: none; }
.issue-main:hover { color: #14b8a6; text-decoration: none; }
.col-chip {
padding: 2px 10px;
border-radius: 999px;
@@ -818,7 +818,7 @@ footer {
cursor: col-resize;
z-index: 5;
}
.notes-resize:hover { background: rgba(194, 67, 126, 0.35); }
.notes-resize:hover { background: rgba(13, 148, 136, 0.35); }
.notes-foot { display: flex; justify-content: space-between; align-items: center; gap: 10px; margin-top: 10px; }
.notes-foot .btn-save { margin-top: 0; }
.notes-status { font-size: 0.76rem; color: var(--text-3); }
@@ -1092,7 +1092,7 @@ footer {
border-radius: 16px; padding: 26px 28px; min-height: 220px;
}
.triage-card-top { display: flex; gap: 14px; align-items: baseline; color: var(--text-3); font-size: 0.88rem; }
.triage-card-num { font-weight: 700; color: var(--accent, #c2437e); }
.triage-card-num { font-weight: 700; color: var(--accent, #0d9488); }
.triage-card-link { margin-left: auto; color: var(--text-3); text-decoration: none; }
.triage-card-title { margin: 10px 0 8px; font-size: 1.5rem; line-height: 1.3; }
.triage-card-labels { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 10px; }
@@ -1104,7 +1104,7 @@ footer {
border: 1px solid var(--border, #2e302c); border-radius: 10px;
padding: 9px 13px; font: inherit; font-size: 0.9rem; cursor: pointer;
}
.triage-keys button:hover { border-color: var(--accent, #c2437e); }
.triage-keys button:hover { border-color: var(--accent, #0d9488); }
.triage-keys kbd {
background: var(--surface-3, #20221f); border: 1px solid var(--border-strong, #3f4340);
border-radius: 5px; padding: 1px 6px; font-size: 0.78rem; margin-right: 4px;
@@ -1130,7 +1130,7 @@ footer {
background: var(--surface-1, #1a1c1a); border: 1px solid var(--border, #2e302c);
border-radius: 12px; padding: 16px 20px; color: var(--text-1); text-decoration: none;
}
.triage-project:hover { border-color: var(--accent, #c2437e); }
.triage-project:hover { border-color: var(--accent, #0d9488); }
.triage-project-count { color: var(--text-3); }
/* ── Wallboard : navigation manuelle (0.11.0) ── */
@@ -1144,14 +1144,14 @@ footer {
border: 1px solid rgba(143, 163, 191, 0.45);
font-size: 1.15rem; cursor: pointer; backdrop-filter: blur(4px);
}
.wall-nav-btn:hover { border-color: #c2437e; color: #fff; }
.wall-nav-btn:hover { border-color: #0d9488; color: #fff; }
.wall-dots { display: flex; gap: 8px; }
.wall-dot {
width: 13px; height: 13px; border-radius: 50%; padding: 0;
background: rgba(143, 163, 191, 0.35); border: 1px solid rgba(143, 163, 191, 0.5);
cursor: pointer;
}
.wall-dot.on { background: #c2437e; border-color: #c2437e; }
.wall-dot.on { background: #0d9488; border-color: #0d9488; }
.wall-paused {
position: fixed; top: 18px; left: 50%; transform: translateX(-50%);
background: rgba(19, 26, 41, 0.85); color: #f0b429;
@@ -1171,13 +1171,13 @@ footer {
.today-picks { display: grid; gap: 14px; margin-bottom: 20px; }
.today-card {
background: var(--surface-1, #1a1c1a); border: 1px solid var(--border-strong, #3f4340);
border-left: 5px solid var(--accent, #c2437e); border-radius: 14px; padding: 20px 24px;
border-left: 5px solid var(--accent, #0d9488); border-radius: 14px; padding: 20px 24px;
}
.today-card.done { border-left-color: var(--good, #3fb950); opacity: 0.85; }
.today-card-top { display: flex; justify-content: space-between; color: var(--text-3); font-size: 0.85rem; }
.today-card h2 { margin: 8px 0 12px; font-size: 1.3rem; line-height: 1.35; }
.today-card-actions { display: flex; gap: 16px; align-items: center; }
.today-card-actions a { color: var(--accent, #c2437e); text-decoration: none; font-size: 0.9rem; }
.today-card-actions a { color: var(--accent, #0d9488); text-decoration: none; font-size: 0.9rem; }
.today-list { list-style: none; padding: 0; margin: 0; display: grid; gap: 10px; }
.today-list li { display: flex; justify-content: space-between; gap: 12px; align-items: center; }
.today-list em { color: var(--text-3); font-style: normal; font-size: 0.85rem; }
@@ -1185,23 +1185,23 @@ footer {
/* ── Prévisions + Récit (0.12.0, #7 #4) ── */
.forecast-flex { display: flex; gap: 22px; align-items: center; flex-wrap: wrap; }
.sparkline { width: 168px; height: 48px; }
.sparkline rect { fill: var(--accent, #c2437e); opacity: 0.85; }
.sparkline rect { fill: var(--accent, #0d9488); opacity: 0.85; }
.forecast-nums p { margin: 4px 0; }
.forecast-milestones { margin: 12px 0 0; padding-left: 18px; line-height: 1.8; }
.forecast-line { color: var(--accent, #c2437e); }
.milestone-forecast { color: var(--accent, #c2437e); font-weight: 600; }
.forecast-line { color: var(--accent, #0d9488); }
.milestone-forecast { color: var(--accent, #0d9488); font-weight: 600; }
.milestone-sprint { color: var(--text-1); text-decoration: none; border: 1px solid var(--border, #2e302c); border-radius: 8px; padding: 2px 10px; }
.milestone-sprint:hover { border-color: var(--accent, #c2437e); }
.milestone-sprint:hover { border-color: var(--accent, #0d9488); }
.sprint-render { line-height: 1.65; }
.sprint-render h1 { font-size: 1.5rem; }
.sprint-render h2 { font-size: 1.15rem; margin-top: 22px; }
.sprint-render a { color: var(--accent, #c2437e); }
.sprint-render a { color: var(--accent, #0d9488); }
/* ── Code lié (0.13.0, #1) ── */
.card-code { font-size: 0.78rem; color: var(--accent, #c2437e); margin-top: 5px; }
.card-code { font-size: 0.78rem; color: var(--accent, #0d9488); margin-top: 5px; }
.detail-code { margin: 10px 0; }
.code-line { padding: 3px 0; font-size: 0.9rem; color: var(--text-2, #a6aba2); }
.code-line a { color: var(--accent, #c2437e); text-decoration: none; }
.code-line a { color: var(--accent, #0d9488); text-decoration: none; }
.code-line code { background: var(--surface-3, #20221f); border-radius: 4px; padding: 0 5px; }
/* ── Branche depuis la carte (0.14.0, #3) ── */
@@ -1246,7 +1246,7 @@ body.with-sidebar.sidebar-collapsed { padding-left: 68px; }
width: 238px; box-sizing: border-box;
display: flex; flex-direction: column; gap: 6px;
padding: 16px 12px 12px; overflow-y: auto; overflow-x: hidden;
background: rgba(13, 16, 24, 0.96);
background: rgba(26, 28, 26, 0.96);
border-right: 1px solid var(--border);
transition: width 0.26s cubic-bezier(0.4, 0, 0.2, 1), transform 0.26s cubic-bezier(0.4, 0, 0.2, 1);
}
@@ -1267,7 +1267,7 @@ body.sidebar-collapsed .sidebar { width: 68px; }
transition: border-color 0.15s, color 0.15s, transform 0.15s;
}
.side-search:hover {
color: var(--text); border-color: var(--accent, #c2437e);
color: var(--text); border-color: var(--accent, #0d9488);
transform: translateY(-1px);
}
body.sidebar-collapsed .side-head { flex-direction: column; padding-left: 0; padding-right: 0; }
@@ -1298,11 +1298,13 @@ body.sidebar-collapsed .side-search { margin-left: 0; }
body.nav-closed-principal [data-group="principal"] .side-acc,
body.nav-closed-rituels [data-group="rituels"] .side-acc,
body.nav-closed-pilotage [data-group="pilotage"] .side-acc,
body.nav-closed-outils [data-group="outils"] .side-acc { grid-template-rows: 0fr; }
body.nav-closed-outils [data-group="outils"] .side-acc,
body.nav-closed-admin [data-group="admin"] .side-acc { grid-template-rows: 0fr; }
body.nav-closed-principal [data-group="principal"] .side-chevron,
body.nav-closed-rituels [data-group="rituels"] .side-chevron,
body.nav-closed-pilotage [data-group="pilotage"] .side-chevron,
body.nav-closed-outils [data-group="outils"] .side-chevron { transform: rotate(-90deg); }
body.nav-closed-outils [data-group="outils"] .side-chevron,
body.nav-closed-admin [data-group="admin"] .side-chevron { transform: rotate(-90deg); }
@media (min-width: 901px) {
/* Rail replié : pas d'accordéon, toutes les icônes visibles. */
body.sidebar-collapsed .side-acc { grid-template-rows: 1fr !important; }
@@ -1317,10 +1319,22 @@ body.nav-closed-outils [data-group="outils"] .side-chevron { transform: rotate(-
}
.side-link:hover { background: var(--surface-2); color: var(--text); text-decoration: none; }
.side-link.active {
color: #fff; border-left-color: #c2437e;
background: linear-gradient(90deg, rgba(194,67,126,.32), rgba(224,120,168,.14));
color: #fff; border-left-color: #0d9488;
background: linear-gradient(90deg, rgba(13,148,136,.32), rgba(20,184,166,.14));
}
.side-ico { font-size: 1.05rem; width: 22px; text-align: center; flex-shrink: 0; }
.side-ico { font-size: 1.05rem; width: 22px; text-align: center; flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; }
.side-ico svg { width: 20px; height: 20px; display: block; }
.logo-mark svg { width: 20px; height: 20px; display: block; }
.side-search svg { width: 19px; height: 19px; display: block; }
/* Bouton thème dans la section Administration (#55) : même
gabarit qu'un lien de navigation, mais c'est un <button>. */
.theme-toggle-link { background: transparent; border: none; cursor: pointer; font: inherit; width: 100%; text-align: left; }
.theme-toggle-link:hover { background: var(--surface-2); color: var(--text); text-decoration: none; }
/* Repli non-admin (#55) : bouton thème dans le pied de la barre,
icône seule — la section Administration n'existe que pour les
administrateurs, les autres utilisateurs gardent un accès. */
.theme-toggle-foot { background: transparent; border: none; cursor: pointer; font-size: 1rem; padding: 2px; color: var(--text-3); }
.theme-toggle-foot:hover { color: var(--text); }
.side-foot {
margin-top: auto; padding-top: 12px;
display: flex; align-items: center; justify-content: space-between; gap: 8px;
@@ -1336,7 +1350,7 @@ body.nav-closed-outils [data-group="outils"] .side-chevron { transform: rotate(-
transition: border-color 0.15s, color 0.15s, transform 0.15s;
}
.side-collapse:hover {
color: var(--text); border-color: var(--accent, #c2437e);
color: var(--text); border-color: var(--accent, #0d9488);
transform: translateY(-1px);
}
.side-fresh { color: var(--text-3); font-size: 0.76rem; white-space: nowrap; }
@@ -1402,10 +1416,10 @@ body.sidebar-collapsed .side-foot { justify-content: center; }
padding: 7px 14px; color: var(--text); background: var(--surface-1);
font-size: 0.88rem; font-weight: 600;
}
.health-chip:hover { text-decoration: none; border-color: var(--accent, #c2437e); }
.health-chip:hover { text-decoration: none; border-color: var(--accent, #0d9488); }
.proj-actions { display: flex; gap: 8px; flex-wrap: wrap; margin: 18px 0 22px; }
.proj-actions .nav-pill { border: 1px solid var(--border); }
.proj-primary { background: linear-gradient(135deg, rgba(194,67,126,.85), rgba(224,120,168,.85)); color: #fff !important; }
.proj-primary { background: linear-gradient(135deg, rgba(13,148,136,.85), rgba(20,184,166,.85)); color: #fff !important; }
.proj-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 16px; }
.proj-panel {
background: var(--surface-1); border: 1px solid var(--border);
@@ -1452,7 +1466,7 @@ body.sidebar-collapsed .side-foot { justify-content: center; }
background: rgba(255, 255, 255, 0.08); color: var(--text-2);
border-radius: 999px; padding: 1px 7px;
}
.seg-tabs button.active .seg-count { background: rgba(194, 67, 126, 0.22); color: var(--text); }
.seg-tabs button.active .seg-count { background: rgba(13, 148, 136, 0.22); color: var(--text); }
.dash-toolbar .toolbar-search { padding: 0; flex: 1 1 200px; }
.dash-toolbar .toolbar-search input { max-width: none; background: var(--surface-2); }
.dash-tool { display: inline-flex; align-items: center; gap: 8px; font-size: 0.88rem; color: var(--text-2); white-space: nowrap; }
@@ -1461,7 +1475,7 @@ body.sidebar-collapsed .side-foot { justify-content: center; }
border: 1px solid var(--border); border-radius: 8px; padding: 6px 8px;
min-height: 36px;
}
.dash-tool-check input { width: 17px; height: 17px; accent-color: #c2437e; }
.dash-tool-check input { width: 17px; height: 17px; accent-color: #0d9488; }
.dash-view-toggle { margin-left: auto; display: inline-flex; border: 1px solid var(--border); border-radius: 9px; overflow: hidden; }
.dash-view-toggle button {
background: var(--surface-1); color: var(--text-2); border: none;
@@ -1476,7 +1490,7 @@ body.sidebar-collapsed .side-foot { justify-content: center; }
border: 1px solid var(--border); border-radius: 10px;
font-size: 0.95rem; font-weight: 700;
}
.owner-head:hover { border-color: var(--accent, #c2437e); }
.owner-head:hover { border-color: var(--accent, #0d9488); }
.owner-head .owner-chevron { transition: transform 0.2s ease; font-size: 0.7rem; }
.owner-head[aria-expanded="false"] .owner-chevron { transform: rotate(-90deg); }
.owner-grid { padding: 0 !important; }
@@ -1497,7 +1511,7 @@ body.sidebar-collapsed .side-foot { justify-content: center; }
donc aucun fond — le menu était transparent et illisible. */
.card-menu {
--menu-bg: #ffffff; --menu-bg-2: #e9eae6; --menu-ink: #1b1d1a;
--menu-ink-2: #5c615a; --menu-line: #dedfd9; --menu-agent: #c2437e;
--menu-ink-2: #5c615a; --menu-line: #dedfd9; --menu-agent: #0d9488;
position: absolute; right: 0; top: calc(100% + 6px); z-index: 60;
min-width: 248px; display: flex; flex-direction: column; gap: 2px;
background: var(--menu-bg); border: 1px solid var(--menu-line);
@@ -1627,8 +1641,8 @@ a.ms-title:hover { text-decoration: underline; }
min-height: 100dvh; margin: 0;
display: flex; align-items: center; justify-content: center;
background:
radial-gradient(640px 420px at 18% 12%, rgba(194, 67, 126, 0.20), transparent 62%),
radial-gradient(560px 380px at 84% 88%, rgba(224, 120, 168, 0.16), transparent 60%),
radial-gradient(640px 420px at 18% 12%, rgba(13, 148, 136, 0.20), transparent 62%),
radial-gradient(560px 380px at 84% 88%, rgba(20, 184, 166, 0.16), transparent 60%),
var(--bg, #101211);
padding: 24px 16px;
}
@@ -1644,12 +1658,12 @@ a.ms-title:hover { text-decoration: underline; }
.login-mark {
display: inline-flex; align-items: center; justify-content: center;
width: 56px; height: 56px; border-radius: 16px; font-size: 1.7rem;
background: linear-gradient(135deg, rgba(194,67,126,.35), rgba(224,120,168,.25));
background: linear-gradient(135deg, rgba(13,148,136,.35), rgba(20,184,166,.25));
border: 1px solid var(--border);
}
.login-brand h1 {
margin: 12px 0 4px; font-size: 1.55rem; font-weight: 700;
background: linear-gradient(120deg, #c2437e, #e078a8);
background: linear-gradient(120deg, #0d9488, #14b8a6);
-webkit-background-clip: text; background-clip: text;
-webkit-text-fill-color: transparent;
}
@@ -1666,10 +1680,10 @@ a.ms-title:hover { text-decoration: underline; }
background: var(--bg-2, #101211); color: var(--text-1, #eceee9);
font: inherit; font-weight: 400;
}
.login-form input:focus { outline: 2px solid rgba(194, 67, 126, 0.55); outline-offset: 0; border-color: transparent; }
.login-form input:focus { outline: 2px solid rgba(13, 148, 136, 0.55); outline-offset: 0; border-color: transparent; }
.login-submit {
margin-top: 4px; padding: 12px 18px; cursor: pointer;
background: linear-gradient(135deg, var(--accent, #c2437e), var(--accent-2, #e078a8));
background: linear-gradient(135deg, var(--accent, #0d9488), var(--accent-2, #14b8a6));
color: #fff; border: none; border-radius: 10px;
font: inherit; font-weight: 600; font-size: 1rem;
transition: filter 0.15s, transform 0.1s;
@@ -1715,7 +1729,7 @@ body.sidebar-collapsed .ws-switch { display: none; }
.btn-mini { padding: 4px 10px; font-size: 0.85em; border-radius: 8px;
border: 1px solid var(--border, #2e302c); background: var(--surface-2, #242624);
color: inherit; cursor: pointer; }
.btn-mini:hover { border-color: var(--accent, #c2437e); }
.btn-mini:hover { border-color: var(--accent, #0d9488); }
.btn-mini:disabled { opacity: 0.45; cursor: not-allowed; }
.btn-danger:hover { border-color: #e5534b; color: #e5534b; }
.chip-ok { display: inline-block; padding: 4px 10px; border-radius: 999px;
@@ -1745,7 +1759,7 @@ body.sidebar-collapsed .ws-switch { display: none; }
.composer-target { color: var(--muted, #a6aba2); font-size: 0.82rem; }
.composer-main { display: flex; gap: 8px; }
.composer-main input[type="text"] { flex: 1; background: var(--surface-2); border: 1px solid var(--border); border-radius: 8px; padding: 9px 12px; color: inherit; font-size: 0.95rem; }
.composer-main input[type="text"]:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(194, 67, 126, 0.25); }
.composer-main input[type="text"]:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(13, 148, 136, 0.25); }
.composer-desc { margin-top: 10px; }
.composer-desc summary { list-style: none; cursor: pointer; display: inline-flex; align-items: center; gap: 6px; font-size: 0.88rem; color: var(--accent-2); padding: 4px 2px; user-select: none; }
.composer-desc summary::-webkit-details-marker { display: none; }
@@ -1753,7 +1767,7 @@ body.sidebar-collapsed .ws-switch { display: none; }
.composer-chevron { transition: transform 0.15s ease; font-size: 0.75rem; }
.composer-desc[open ] .composer-chevron { transform: rotate(180deg); }
.composer-desc textarea { width: 100%; margin-top: 8px; background: var(--surface-2); border: 1px solid var(--border); border-radius: 8px; padding: 10px 12px; color: inherit; font-family: inherit; resize: vertical; }
.composer-desc textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(194, 67, 126, 0.25); }
.composer-desc textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(13, 148, 136, 0.25); }
.composer-hint { color: var(--muted, #a6aba2); font-size: 0.78rem; margin: 6px 0 0; }
/* ── Mes issues : barre de filtres (0.33.0) ── */
@@ -1763,13 +1777,13 @@ body.sidebar-collapsed .ws-switch { display: none; }
.my-search-wrap { position: relative; flex: 1 1 280px; }
.my-search-icon { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); opacity: 0.65; pointer-events: none; }
.my-search-wrap input[type="search"] { width: 100%; background: var(--surface-2); border: 1px solid var(--border); border-radius: 999px; padding: 9px 14px 9px 38px; color: inherit; font-size: 0.92rem; }
.my-search-wrap input[type="search"]:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(194, 67, 126, 0.25); }
.my-search-wrap input[type="search"]:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(13, 148, 136, 0.25); }
.my-filters select { background: var(--surface-2); border: 1px solid var(--border); border-radius: 8px; padding: 9px 10px; color: inherit; font-size: 0.9rem; }
.my-filters select:focus { outline: none; border-color: var(--accent); }
.my-col-chips { display: flex; gap: 6px; flex-wrap: wrap; margin-right: auto; }
.filter-chip { display: inline-flex; align-items: center; gap: 6px; background: var(--surface-2); border: 1px solid var(--border); color: inherit; border-radius: 999px; padding: 5px 12px; font-size: 0.85rem; cursor: pointer; transition: border-color 0.15s, background 0.15s; }
.filter-chip:hover { border-color: var(--border-strong); }
.filter-chip.on { background: rgba(194, 67, 126, 0.18); border-color: var(--accent); font-weight: 600; }
.filter-chip.on { background: rgba(13, 148, 136, 0.18); border-color: var(--accent); font-weight: 600; }
.filter-chip-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
.filter-chip-count { opacity: 0.7; font-size: 0.78rem; }
.my-count { color: var(--muted, #a6aba2); font-size: 0.88rem; white-space: nowrap; }
@@ -1791,3 +1805,36 @@ body.sidebar-collapsed .ws-switch { display: none; }
.ms-form input:focus, .ms-form textarea:focus { outline: none; border-color: var(--accent); }
.ms-hint { color: var(--muted, #a6aba2); font-size: 0.78rem; }
.ms-form-actions { display: flex; gap: 8px; }
/* ── Thème clair (#52) : jetons draco-barre (clair par défaut).
html[data-theme="light"] prime sur le :root sombre et sur le
prefers-color-scheme de la barre Fusion. Le sombre reste le
défaut (les gabarits portent data-theme="dark", le JS du
thème ne bascule que sur choix mémorisé). */
html[data-theme="light"] {
--bg: #f2f2f0; --surface: #ffffff; --surface-2: #e9eae6; --surface-3: #f6f6f3;
--border: #dedfd9; --border-strong: #c9cbc2;
--text: #1b1d1a; --text-2: #5c615a; --text-3: #787d75;
--accent: #0d9488; --accent-2: #0f766e;
--shadow: 0 8px 28px rgba(0, 0, 0, 0.12);
--shadow-sm: 0 2px 10px rgba(0, 0, 0, 0.08);
color-scheme: light;
}
html[data-theme="light"] .sidebar { background: rgba(255, 255, 255, 0.96); }
html[data-theme="light"] .app-header { background: rgba(255, 255, 255, 0.85); }
/* Lien actif de la barre latérale : fond vert translucide sur
fond clair — le texte blanc du thème sombre y serait illisible. */
html[data-theme="light"] .side-link.active { color: #1b1d1a; }
/* Menu ⋯ des tuiles : jetons clairs explicites, pour primer sur
le prefers-color-scheme sombre du système. */
html[data-theme="light"] .card-menu {
--menu-bg: #ffffff; --menu-bg-2: #e9eae6; --menu-ink: #1b1d1a;
--menu-ink-2: #5c615a; --menu-line: #dedfd9;
}
/* Barre Fusion : jetons clairs explicites, pour primer sur son
@media (prefers-color-scheme: dark). Le panneau Spark suit
via son MutationObserver sur data-theme (draco-panneau.js). */
html[data-theme="light"] .draco-bar {
--bg: #f2f2f0; --surface: #ffffff; --surface-2: #e9eae6; --surface-3: #f6f6f3;
--ink: #1b1d1a; --ink-2: #5c615a; --ink-3: #787d75; --line: #dedfd9;
}
+29
View File
@@ -34,6 +34,35 @@
if (window.innerWidth > 900) closeDrawer();
});
/* Bascule Dark/Light (#52) : le choix est mémorisé et
l'amorce de _header.html l'a déjà appliqué avant le rendu.
Ici, on ne fait que synchroniser le libellé et le clic. */
var themeBtn = document.getElementById('theme-toggle');
function syncThemeBtn(theme) {
if (!themeBtn) return;
var light = theme === 'light';
/* Bouton dans la section Administration (#55) : icône et
libellé sont des <span> séparés ; l'ancien bouton de
l'en-tête, lui, n'avait qu'un texte. */
var ico = themeBtn.querySelector('[data-theme-ico]');
var lbl = themeBtn.querySelector('[data-theme-label]');
if (ico) ico.textContent = light ? '🌙' : '☀️';
if (lbl) lbl.textContent = light ? 'Mode sombre' : 'Mode clair';
if (!ico && !lbl) {
themeBtn.textContent = light ? '🌙 Mode sombre' : '☀️ Mode clair';
}
themeBtn.setAttribute('aria-pressed', light ? 'true' : 'false');
}
if (themeBtn) {
syncThemeBtn(document.documentElement.getAttribute('data-theme') || 'dark');
themeBtn.addEventListener('click', function () {
var next = document.documentElement.getAttribute('data-theme') === 'light' ? 'dark' : 'light';
document.documentElement.setAttribute('data-theme', next);
try { localStorage.setItem('kanbante-theme', next); } catch (e) { /* non-fatal */ }
syncThemeBtn(next);
});
}
if (collapseBtn) {
collapseBtn.addEventListener('click', function () {
var collapsed = document.body.classList.toggle('sidebar-collapsed');
+35
View File
@@ -0,0 +1,35 @@
"""Identité Kanbante (#54, #55) : sidebar charbon (pas bleutée),
accent vert Kanbante (pas rose Spark), icônes de navigation en
trait (pas d'emoji), bouton Dark/Light dans la section
Administration (pas dans l'en-tête).
"""
def test_sidebar_charbon_et_accent_vert(client, fake_gitea):
css = client.get("/static/css/style.css").text
assert "rgba(26, 28, 26, 0.96)" in css
assert "rgba(13, 16, 24" not in css
assert "--accent: #0d9488;" in css
assert "#c2437e" not in css
def test_nav_icons_sont_des_svg(client, fake_gitea):
page = client.get("/")
assert 'class="side-ico"><svg' in page.text
# Le logo Kanbante est aussi un SVG (colonnes blanches).
assert 'class="logo-mark"><svg' in page.text
def test_theme_toggle_dans_admin_pas_dans_en_tete(client, fake_gitea):
page = client.get("/")
assert 'id="theme-toggle"' in page.text
head = page.text.split("header-actions", 1)[1].split("</header>", 1)[0]
assert 'id="theme-toggle"' not in head
# Placement administrateur : le bouton est dans le bloc de la
# section Administration du gabarit (les non-admins, eux, le
# voient dans le pied de la barre, la section n'existant pas
# pour eux — sans quoi ils perdraient le basculeur).
tpl = open("app/templates/_header.html", encoding="utf-8").read()
admin_block = tpl.split("gkey == 'admin'", 1)[1]
assert 'id="theme-toggle"' in admin_block
assert "data-theme-label" in admin_block
+39
View File
@@ -0,0 +1,39 @@
"""Navigation (#51) et bascule Dark/Light (#52).
L'accordéon de la barre latérale omettait la section admin :
le JS posait nav-closed-admin, mais aucun style ne la suivait.
Le thème clair, lui, doit être atteignable par un bouton et
mémorisé, avec les jetons draco clairs.
"""
def test_admin_accordion_closes(client, fake_gitea):
css = client.get("/static/css/style.css").text
assert 'body.nav-closed-admin [data-group="admin"] .side-acc' in css
assert 'body.nav-closed-admin [data-group="admin"] .side-chevron' in css
def test_theme_toggle_present_and_versioned(client, fake_gitea):
page = client.get("/")
assert 'id="theme-toggle"' in page.text
assert "/static/js/nav.js?v=" in page.text
# #55 : le bouton n'est plus dans l'en-tête applicatif.
head = page.text.split("header-actions", 1)[1].split("</header>", 1)[0]
assert 'id="theme-toggle"' not in head
def test_theme_js_contract(client, fake_gitea):
js = client.get("/static/js/nav.js").text
assert "kanbante-theme" in js
assert "theme-toggle" in js
assert "data-theme" in js
def test_light_theme_tokens(client, fake_gitea):
css = client.get("/static/css/style.css").text
assert 'html[data-theme="light"]' in css
assert "--bg: #f2f2f0;" in css
assert "--surface: #ffffff;" in css
assert "--accent-2: #0f766e;" in css
assert 'html[data-theme="light"] .draco-bar' in css
assert 'html[data-theme="light"] .card-menu' in css
+8 -5
View File
@@ -1,7 +1,8 @@
"""Thème du site (#49) : Kanbante doit ressembler à la console
"""Thème du site (#49, #54) : Kanbante doit ressembler à la console
agent / barre Fusion (draco-barre, Console v7.2), pas au bleu/mauve
historique. Le test fige les jetons et interdit le retour des
littéraux violet/bleu de thème dans style.css.
historique — et l'accent est désormais le vert Kanbante, pas le
rose Spark. Le test fige les jetons et interdit le retour des
littéraux rose/violet/bleu de thème dans style.css.
"""
@@ -13,8 +14,8 @@ def test_theme_agent_tokens(client, fake_gitea):
assert "--surface-3: #20221f;" in css
assert "--border: #2e302c;" in css
assert "--text: #eceee9;" in css
assert "--accent: #c2437e;" in css
assert "--accent-2: #e078a8;" in css
assert "--accent: #0d9488;" in css
assert "--accent-2: #14b8a6;" in css
def test_no_blue_purple_theme_literals(client, fake_gitea):
@@ -24,5 +25,7 @@ def test_no_blue_purple_theme_literals(client, fake_gitea):
"#c4b5fd", "#a5c4fd", "#0b0e14", "#141822", "#1b202e",
"#232939", "124, 92, 252", "124,92,252",
"91, 138, 247", "91,138,247",
"#c2437e", "#e078a8", "194, 67, 126", "194,67,126",
"224, 120, 168", "224,120,168",
):
assert banned not in css, banned