Compare commits

...
Author SHA1 Message Date
bruno f3b507b8d9 Merge pull request '[Theme] Nouveau theme Spark (dark/light, identique a la Console Spark) et defaut = Spark dark' (#28) from feat/theme-spark into main
CI / security (push) Failing after 0s
CI / lint (push) Successful in 3m6s
CI / test (push) Failing after 0s
CI / build (push) Skipped
CI / e2e (push) Skipped
2026-10-27 23:25:10 -04:00
bruno c01c7e862d Merge pull request '[fix] Mypy Coffre Secrets (3 erreurs) + version 2.80.2' (#27) from fix/mypy-coffre-2.80.2 into main
CI / lint (push) Failing after 0s
CI / security (push) Failing after 0s
CI / test (push) Skipped
CI / build (push) Skipped
CI / e2e (push) Skipped
2026-10-27 23:24:44 -04:00
bruno 99cd765997 [fix] CHANGELOG 2.80.2 : bouton Nouveau secret + plancher msgpack
CI / lint (pull_request) Failing after 0s
CI / security (pull_request) Failing after 0s
CI / test (pull_request) Skipped
CI / build (pull_request) Skipped
CI / e2e (pull_request) Skipped
2026-10-27 23:20:41 -04:00
bruno 5266506b56 [fix] Securite : plancher msgpack>=1.2.3 (CVE-2026-114613, pip-audit bloquant)
CI / lint (pull_request) Failing after 1s
CI / test (pull_request) Skipped
CI / build (pull_request) Skipped
CI / e2e (pull_request) Skipped
CI / security (pull_request) Successful in 1m56s
2026-10-27 23:20:35 -04:00
bruno 682a5030d3 [fix] Coffre Secrets : valeurField attache l'oeil a wrap avant insertBefore (NotFoundError bouton Nouveau secret)
CI / security (pull_request) Failing after 0s
CI / lint (pull_request) Successful in 3m19s
CI / test (pull_request) Failing after 1m47s
CI / build (pull_request) Skipped
CI / e2e (pull_request) Skipped
2026-10-27 23:20:30 -04:00
bruno fc3d847d85 [fix] mypy Coffre + bump 2.80.2 : CHANGELOG.md
CI / security (pull_request) Failing after 2m29s
CI / lint (pull_request) Successful in 2m55s
CI / test (pull_request) Failing after 5m10s
CI / build (pull_request) Skipped
CI / e2e (pull_request) Skipped
2026-10-27 23:10:51 -04:00
bruno 82756030c6 [fix] mypy Coffre + bump 2.80.2 : docs/ROADMAP.md 2026-10-27 23:10:48 -04:00
bruno 0352451ead [fix] mypy Coffre + bump 2.80.2 : README.fr.md 2026-10-27 23:10:44 -04:00
bruno 593cf492c3 [fix] mypy Coffre + bump 2.80.2 : README.md 2026-10-27 23:10:41 -04:00
bruno 0b8ad8b0f3 [fix] mypy Coffre + bump 2.80.2 : desktop/Cargo.lock 2026-10-27 23:10:39 -04:00
bruno 111d927ece [fix] mypy Coffre + bump 2.80.2 : desktop/Cargo.toml 2026-10-27 23:10:36 -04:00
bruno 2dae023ee3 [fix] mypy Coffre + bump 2.80.2 : desktop/tauri.conf.json 2026-10-27 23:10:34 -04:00
bruno b12122f78a [fix] mypy Coffre + bump 2.80.2 : package.json 2026-10-27 23:10:31 -04:00
bruno 0c7b3162c8 [fix] mypy Coffre + bump 2.80.2 : VERSION 2026-10-27 23:10:29 -04:00
bruno d4d050297b [fix] mypy Coffre + bump 2.80.2 : backend/coffre_store.py 2026-10-27 23:10:27 -04:00
bruno 8d768bf9d5 [fix] mypy Coffre + bump 2.80.2 : backend/coffre_crypto.py 2026-10-27 23:10:24 -04:00
bruno 47ac8bf6c0 Merge pull request '[fix] Version 2.80.1 synchronisee + corrections ruff (60 erreurs CI)' (#26) from fix/version-2.80.1-ruff into main
CI / security (push) Failing after 1s
CI / lint (push) Failing after 2m10s
CI / test (push) Skipped
CI / build (push) Skipped
CI / e2e (push) Skipped
2026-10-27 23:00:13 -04:00
bruno 070add4e7b [Thème Spark] Anti-FOUC admin aligné sur fond/texte Spark
CI / security (pull_request) Failing after 0s
CI / lint (pull_request) Successful in 3m10s
CI / test (pull_request) Failing after 5m22s
CI / build (pull_request) Skipped
CI / e2e (pull_request) Skipped
2026-10-27 22:10:14 -04:00
bruno 847b3225b2 [Thème Spark] Splash et meta theme-color alignés sur Spark dark 2026-10-27 22:10:11 -04:00
bruno 3ae5c7efac [Thème Spark] Bloc :root de secours aligné sur la palette dark Spark 2026-10-27 22:10:07 -04:00
bruno 4966c27548 [Thème Spark] Ajout du thème 'spark' (dark/light, 39 variables) et défaut spark/dark 2026-10-27 22:10:04 -04:00
17 changed files with 167 additions and 72 deletions
+12 -1
View File
@@ -6,7 +6,7 @@ Format basé sur [Keep a Changelog](https://keepachangelog.com/fr/1.1.0/),
et [Semantic Versioning](https://semver.org/spec/v2.0.0.html). et [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
> **En cours de développement** : les changements à venir sont listés dans la section > **En cours de développement** : les changements à venir sont listés dans la section
> [Unreleased](#unreleased). La dernière version livrée est **2.80.1**. > [Unreleased](#unreleased). La dernière version livrée est **2.80.2**.
--- ---
@@ -14,6 +14,17 @@ et [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
--- ---
## [2.80.2] — 2026-10-27
### Corrigé
- **CI lint (mypy)** — 3 erreurs dans le Coffre Secrets : annotation explicite `type[Any] | None` pour `AESGCM` dans `coffre_crypto.py` (le repli sans `cryptography` reste `None`, et `_require_aesgcm()` retourne désormais la classe pour un narrowing propre) ; annotation `dict[str, Any]` du coffre dans `create_coffre` (`coffre_store.py`), qui inférait ses valeurs en `str | None` et refusait le dict de `wrap_dek` ainsi que `coffre["id"]` en argument. Aucun `type: ignore` aveugle ajouté, aucun changement de comportement.
- **Bouton Nouveau secret inoperant (console NotFoundError)** — `valeurField` appelait `wrap.insertBefore(input, eyeBtn)` alors que le bouton oeil n'avait jamais ete rattache a `wrap` : l'oeil est desormais ajoute a `wrap` avant le premier `build`, la modale de creation (et celle de rotation) s'ouvre.
- **CI security (pip-audit)** — plancher `msgpack>=1.2.3` : la version transitive 1.2.1 etait signalee pour CVE-2026-114613 (correctif 1.2.3).
---
## [2.80.1] — 2026-10-27 ## [2.80.1] — 2026-10-27
### Ajouté ### Ajouté
+3 -3
View File
@@ -4,7 +4,7 @@
**Porte d'entrée web ultra-léger pour vos vaults Obsidian** — Accédez, naviguez et recherchez dans toutes vos notes Obsidian depuis n'importe quel appareil via une interface web moderne et responsive. **Porte d'entrée web ultra-léger pour vos vaults Obsidian** — Accédez, naviguez et recherchez dans toutes vos notes Obsidian depuis n'importe quel appareil via une interface web moderne et responsive.
[![Version](https://img.shields.io/badge/Version-2.80.1-blue.svg)]() [![Version](https://img.shields.io/badge/Version-2.80.2-blue.svg)]()
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Docker](https://img.shields.io/badge/Docker-Ready-blue.svg)](https://www.docker.com/) [![Docker](https://img.shields.io/badge/Docker-Ready-blue.svg)](https://www.docker.com/)
[![Python](https://img.shields.io/badge/Python-3.11+-green.svg)](https://www.python.org/) [![Python](https://img.shields.io/badge/Python-3.11+-green.svg)](https://www.python.org/)
@@ -977,8 +977,8 @@ Ce projet est sous licence **MIT** — voir le fichier [LICENSE](LICENSE) pour l
## 📝 Changelog ## 📝 Changelog
Consultez le [CHANGELOG.md](./CHANGELOG.md) pour l'historique complet de toutes les versions (v1.0.0 → v2.80.1). Consultez le [CHANGELOG.md](./CHANGELOG.md) pour l'historique complet de toutes les versions (v1.0.0 → v2.80.2).
--- ---
*Projet : ObsiGate | Version : 2.80.1 | Dernière mise à jour : Septembre 2026* *Projet : ObsiGate | Version : 2.80.2 | Dernière mise à jour : Septembre 2026*
+3 -3
View File
@@ -2,7 +2,7 @@
**Ultra-light web gateway for your Obsidian vaults** — Access, browse, and search all your Obsidian notes from any device via a modern, responsive web interface. **Ultra-light web gateway for your Obsidian vaults** — Access, browse, and search all your Obsidian notes from any device via a modern, responsive web interface.
[![Version](https://img.shields.io/badge/Version-2.80.1-blue.svg)]() [![Version](https://img.shields.io/badge/Version-2.80.2-blue.svg)]()
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Docker](https://img.shields.io/badge/Docker-Ready-blue.svg)](https://www.docker.com/) [![Docker](https://img.shields.io/badge/Docker-Ready-blue.svg)](https://www.docker.com/)
[![Python](https://img.shields.io/badge/Python-3.11+-green.svg)](https://www.python.org/) [![Python](https://img.shields.io/badge/Python-3.11+-green.svg)](https://www.python.org/)
@@ -1152,8 +1152,8 @@ This project is licensed under the **MIT License** - see the [LICENSE](LICENSE)
## 📝 Changelog ## 📝 Changelog
See [CHANGELOG.md](./CHANGELOG.md) for the complete version history (v1.0.0 → v2.80.1). See [CHANGELOG.md](./CHANGELOG.md) for the complete version history (v1.0.0 → v2.80.2).
--- ---
*Project: ObsiGate | Version: 2.80.1 | Last updated: September 2026* *Project: ObsiGate | Version: 2.80.2 | Last updated: September 2026*
+1 -1
View File
@@ -1 +1 @@
2.80.1 2.80.2
+17 -6
View File
@@ -24,14 +24,19 @@ import logging
import os import os
import stat import stat
from pathlib import Path from pathlib import Path
from typing import Any
logger = logging.getLogger("obsigate.coffre_crypto") logger = logging.getLogger("obsigate.coffre_crypto")
# Annotation explicite : sans elle, mypy refuse l'assignation de deux types
# (la classe AESGCM importée, puis None dans le repli sans cryptography)
# et le commentaire `type: ignore[assignment]` ne couvre pas ce code [misc].
AESGCM: type[Any] | None
try: # cryptography est une dépendance de la Phase 1a (requirements.txt) try: # cryptography est une dépendance de la Phase 1a (requirements.txt)
from cryptography.exceptions import InvalidTag from cryptography.exceptions import InvalidTag
from cryptography.hazmat.primitives.ciphers.aead import AESGCM from cryptography.hazmat.primitives.ciphers.aead import AESGCM
except Exception: # pragma: no cover - environnement sans cryptography except Exception: # pragma: no cover - environnement sans cryptography
AESGCM = None # type: ignore[assignment] AESGCM = None
InvalidTag = Exception # type: ignore[assignment,misc] InvalidTag = Exception # type: ignore[assignment,misc]
@@ -55,11 +60,17 @@ class CryptoIndisponibleError(CoffreCryptoError):
"""La bibliothèque ``cryptography`` n'est pas installée.""" """La bibliothèque ``cryptography`` n'est pas installée."""
def _require_aesgcm() -> None: def _require_aesgcm() -> type[Any]:
"""Retourne la classe AESGCM, ou lève si cryptography est absent.
Retourner la classe (plutôt qu'un simple garde) permet à mypy de
savoir que l'appelant détient bien un constructible, et non None.
"""
if AESGCM is None: if AESGCM is None:
raise CryptoIndisponibleError( raise CryptoIndisponibleError(
"cryptography n'est pas installé (dépendance Phase 1a)" "cryptography n'est pas installé (dépendance Phase 1a)"
) )
return AESGCM
def parse_kek(raw: str) -> bytes: def parse_kek(raw: str) -> bytes:
@@ -146,17 +157,17 @@ def _unb64(value: str) -> bytes:
def encrypt_with_key(key: bytes, plaintext: bytes, aad: bytes) -> dict: def encrypt_with_key(key: bytes, plaintext: bytes, aad: bytes) -> dict:
"""Chiffre avec AES-256-GCM. Retourne {nonce, ciphertext} en base64.""" """Chiffre avec AES-256-GCM. Retourne {nonce, ciphertext} en base64."""
_require_aesgcm() aesgcm = _require_aesgcm()
nonce = os.urandom(12) nonce = os.urandom(12)
ciphertext = AESGCM(key).encrypt(nonce, plaintext, aad) ciphertext = aesgcm(key).encrypt(nonce, plaintext, aad)
return {"nonce": _b64(nonce), "ciphertext": _b64(ciphertext)} return {"nonce": _b64(nonce), "ciphertext": _b64(ciphertext)}
def decrypt_with_key(key: bytes, nonce_b64: str, ciphertext_b64: str, aad: bytes) -> bytes: def decrypt_with_key(key: bytes, nonce_b64: str, ciphertext_b64: str, aad: bytes) -> bytes:
"""Déchiffre avec AES-256-GCM. Tag invalide -> TagInvalideError.""" """Déchiffre avec AES-256-GCM. Tag invalide -> TagInvalideError."""
_require_aesgcm() aesgcm = _require_aesgcm()
try: try:
return AESGCM(key).decrypt(_unb64(nonce_b64), _unb64(ciphertext_b64), aad) return aesgcm(key).decrypt(_unb64(nonce_b64), _unb64(ciphertext_b64), aad)
except InvalidTag as exc: except InvalidTag as exc:
raise TagInvalideError("Tag GCM invalide : données altérées ou mauvaise clé") from exc raise TagInvalideError("Tag GCM invalide : données altérées ou mauvaise clé") from exc
except (binascii.Error, ValueError) as exc: except (binascii.Error, ValueError) as exc:
+2 -1
View File
@@ -42,6 +42,7 @@ import threading
import uuid import uuid
from datetime import UTC, datetime, timedelta from datetime import UTC, datetime, timedelta
from pathlib import Path from pathlib import Path
from typing import Any
from backend.coffre_crypto import ( from backend.coffre_crypto import (
decrypt_secret_value, decrypt_secret_value,
@@ -306,7 +307,7 @@ def create_coffre(
data = _load_coffres(base) data = _load_coffres(base)
if any(c["slug"] == slug for c in data["coffres"]): if any(c["slug"] == slug for c in data["coffres"]):
raise CoffreExisteError(f"Coffre déjà existant : {slug}") raise CoffreExisteError(f"Coffre déjà existant : {slug}")
coffre = { coffre: dict[str, Any] = {
"id": str(uuid.uuid4()), "id": str(uuid.uuid4()),
"slug": slug, "slug": slug,
"nom": nom, "nom": nom,
+4
View File
@@ -75,3 +75,7 @@ filelock>=4.2.1
opentelemetry-api>=1.45.1 opentelemetry-api>=1.45.1
# Coffre Secrets (Phase 1a) : chiffrement par enveloppe AES-256-GCM. # Coffre Secrets (Phase 1a) : chiffrement par enveloppe AES-256-GCM.
cryptography>=44.0 cryptography>=44.0
# Plancher de securite : msgpack est transitif, version 1.2.1 relevee par le job
# security (pip-audit, bloquant) — CVE-2026-114613, corrigee en 1.2.3.
msgpack>=1.2.3
+1 -1
View File
@@ -2626,7 +2626,7 @@ dependencies = [
[[package]] [[package]]
name = "obsigate-desktop" name = "obsigate-desktop"
version = "2.80.1" version = "2.80.2"
dependencies = [ dependencies = [
"chrono", "chrono",
"env_logger", "env_logger",
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "obsigate-desktop" name = "obsigate-desktop"
version = "2.80.1" version = "2.80.2"
description = "ObsiGate Desktop — Porte d'entrée native pour vos vaults Obsidian" description = "ObsiGate Desktop — Porte d'entrée native pour vos vaults Obsidian"
authors = ["Bruno Charest"] authors = ["Bruno Charest"]
edition = "2021" edition = "2021"
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"$schema": "https://raw.githubusercontent.com/nicedoc/obsigate/main/desktop/tauri.conf.schema.json", "$schema": "https://raw.githubusercontent.com/nicedoc/obsigate/main/desktop/tauri.conf.schema.json",
"productName": "ObsiGate", "productName": "ObsiGate",
"version": "2.80.1", "version": "2.80.2",
"identifier": "com.obsigate.desktop", "identifier": "com.obsigate.desktop",
"build": { "build": {
"frontendDist": "../frontend", "frontendDist": "../frontend",
+1 -1
View File
@@ -1,6 +1,6 @@
# ObsiGate — Roadmap # ObsiGate — Roadmap
> **Version :** 2.80.1 | **Dernière mise à jour :** 2026-10-27 > **Version :** 2.80.2 | **Dernière mise à jour :** 2026-10-27
> **Ce fichier ne contient que le travail à venir** (🔵 En cours + ⚪ Backlog) et un index compact > **Ce fichier ne contient que le travail à venir** (🔵 En cours + ⚪ Backlog) et un index compact
> vers les fonctionnalités livrées. > vers les fonctionnalités livrées.
> - **Méthode de livraison à appliquer pour toute tâche : [DELIVERY_WORKFLOW.md](./DELIVERY_WORKFLOW.md)** > - **Méthode de livraison à appliquer pour toute tâche : [DELIVERY_WORKFLOW.md](./DELIVERY_WORKFLOW.md)**
+4 -4
View File
@@ -19,8 +19,8 @@
var mode = localStorage.getItem("obsigate-theme-mode") || "dark"; var mode = localStorage.getItem("obsigate-theme-mode") || "dark";
root.setAttribute("data-theme", mode); root.setAttribute("data-theme", mode);
var light = mode === "light" || mode === "sepia"; var light = mode === "light" || mode === "sepia";
root.style.setProperty("--bg-primary", light ? "#ffffff" : "#0f1117"); root.style.setProperty("--bg-primary", light ? "#fbfbfa" : "#17181a");
root.style.setProperty("--text-primary", light ? "#1a1a1a" : "#e6edf3"); root.style.setProperty("--text-primary", light ? "#242624" : "#eceeeb");
} catch (e) { root.setAttribute("data-theme", "dark"); } } catch (e) { root.setAttribute("data-theme", "dark"); }
})(); })();
</script> </script>
@@ -41,8 +41,8 @@
min-height: 100vh; min-height: 100vh;
overflow: auto; /* override SPA style.css: body{overflow:hidden} */ overflow: auto; /* override SPA style.css: body{overflow:hidden} */
height: auto; /* override SPA style.css: body{height:100vh} */ height: auto; /* override SPA style.css: body{height:100vh} */
background: var(--bg-primary, #0f1117); background: var(--bg-primary, #17181a);
color: var(--text-primary, #e6edf3); color: var(--text-primary, #eceeeb);
font-family: "Segoe UI", system-ui, -apple-system, sans-serif; font-family: "Segoe UI", system-ui, -apple-system, sans-serif;
} }
+4 -4
View File
@@ -10,7 +10,7 @@
name="description" name="description"
content="Porte d'entrée web pour vos vaults Obsidian - Accédez, naviguez et recherchez dans toutes vos notes" content="Porte d'entrée web pour vos vaults Obsidian - Accédez, naviguez et recherchez dans toutes vos notes"
/> />
<meta name="theme-color" content="#2563eb" /> <meta name="theme-color" content="#7c5cd6" />
<meta name="mobile-web-app-capable" content="yes" /> <meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-capable" content="yes" />
<meta <meta
@@ -54,14 +54,14 @@
#boot-splash { #boot-splash {
position: fixed; inset: 0; z-index: 2147483647; position: fixed; inset: 0; z-index: 2147483647;
display: flex; align-items: center; justify-content: center; display: flex; align-items: center; justify-content: center;
background: radial-gradient(1200px 600px at 50% -10%, #1b2030 0%, #0e1117 60%); background: radial-gradient(1200px 600px at 50% -10%, #26272b 0%, #17181a 60%);
color: #e6e8ee; font-family: "Segoe UI", system-ui, -apple-system, sans-serif; color: #eceeeb; font-family: "Segoe UI", system-ui, -apple-system, sans-serif;
} }
body.app-booted #boot-splash { display: none; } body.app-booted #boot-splash { display: none; }
.bs-card { display: flex; flex-direction: column; align-items: center; gap: 14px; } .bs-card { display: flex; flex-direction: column; align-items: center; gap: 14px; }
.bs-logo { .bs-logo {
width: 72px; height: 72px; display: flex; align-items: center; justify-content: center; width: 72px; height: 72px; display: flex; align-items: center; justify-content: center;
font-size: 38px; background: #171c26; border: 1px solid #2a3242; border-radius: 18px; font-size: 38px; background: #1f2023; border: 1px solid #33353a; border-radius: 18px;
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.45); box-shadow: 0 8px 30px rgba(0, 0, 0, 0.45);
} }
.bs-title { font-size: 22px; font-weight: 600; letter-spacing: 0.3px; } .bs-title { font-size: 22px; font-weight: 600; letter-spacing: 0.3px; }
+3
View File
@@ -292,6 +292,9 @@ function valeurField(initialType) {
else if (input) input.type = 'password'; else if (input) input.type = 'password';
}); });
eyeBtn.title = t('coffres.show_before_save'); eyeBtn.title = t('coffres.show_before_save');
// L'oeil doit etre enfant de wrap AVANT le premier build : insertBefore(input, eyeBtn)
// leve sinon NotFoundError et la modale ne s'ouvre jamais (bug bouton Nouveau secret).
wrap.appendChild(eyeBtn);
build(initialType); build(initialType);
return { return {
wrap, wrap,
+67 -2
View File
@@ -1,5 +1,5 @@
/* ObsiGate — Theme System /* ObsiGate — Theme System
* 15 themes x 2 modes (dark/light) * 16 themes x 2 modes (dark/light)
* Persisted in localStorage as 'obsigate-theme' * Persisted in localStorage as 'obsigate-theme'
* Usage: import { initThemes, applyTheme, getCurrentTheme, THEMES } from './themes.js' * Usage: import { initThemes, applyTheme, getCurrentTheme, THEMES } from './themes.js'
*/ */
@@ -45,6 +45,71 @@ var THEMES = {
} }
}, },
// ── Thème Spark ──────────────────────────────────────────────────────
// Palette source : console Spark (agent.dracodev.net), app/console/console.css
// (variables --p-*). Mapping Spark -> ObsiGate, identique en structure pour
// dark et light ; seules les valeurs changent (sauf accent/ok/warn/err).
// Fidèle (valeur Spark directe) :
// fond -> --bg-primary, --surface2 ; surface -> --surface ;
// chip -> --bg-secondary, --tag-bg ; chip-survol -> --bg-hover ;
// bord -> --border ; chip-bord -> --border-md, --scrollbar, --resize-handle ;
// texte -> --text-primary, --text ; doux -> --text-secondary, --text-2 ;
// faint -> --text-muted, --text-3 ; champ -> --search-bg ;
// code -> --code-bg ; accent -> --accent, --accent-card, --purple, --ai ;
// lien -> --accent-text (variante lisible de l'accent sur fond teinté) ;
// ok -> --accent-green, --success, --green ;
// danger -> --danger ; danger-fond -> --danger-bg ;
// pastilles ok (fond) -> --success-bg, --green-bg ;
// pastilles ok (texte) -> --ok ; ambre -> --warn ; rouge -> --err.
// Approximations documentées (ObsiGate a plus de variables que Spark,
// ce ne sont PAS des valeurs Spark) :
// --bg-sidebar <- fond (Spark n'a pas de token sidebar dédié) ;
// --accent-bg <- agent (surface teintée de Spark, pas de teinte lavande) ;
// --surface3 <- agent ; --purple-bg <- appro-fond (fond teinté le plus
// proche, la palette Spark n'a pas de teinte lavande) ;
// --overlay-bg <- convention ObsiGate (rgba noir 0.3 clair / 0.5 sombre,
// aucun token voile dans la palette Spark).
// Non reportés (aucune variable ObsiGate correspondante dans les 39) :
// bulle utilisateur/envoi #2f6fed, titres approbation #9a6a1c / #e8bc7a.
// Une seule entrée 'spark' : dark et light sont ses deux modes, jamais
// deux thèmes séparés. Modes high-contrast/sepia générés comme pour les
// autres thèmes (à partir de dark/light).
'spark': {
name: 'Spark', desc: 'Palette de la console Spark',
modes: {
dark: {
'--bg-primary': '#17181a', '--bg-secondary': '#26272b', '--bg-sidebar': '#17181a',
'--bg-hover': '#2e3036', '--border': '#33353a', '--text-primary': '#eceeeb',
'--text-secondary': '#a6aba0', '--text-muted': '#83887e', '--accent': '#7c5cd6',
'--accent-green': '#2ea36b', '--tag-bg': '#26272b', '--tag-text': '#7c5cd6',
'--code-bg': '#2c2e33', '--search-bg': '#1f2023', '--scrollbar': '#3a3c41',
'--resize-handle': '#3a3c41', '--overlay-bg': 'rgba(0,0,0,0.5)', '--danger': '#e8a08d',
'--danger-bg': '#40241f', '--success': '#2ea36b', '--success-bg': '#173d29',
'--accent-card': '#7c5cd6', '--accent-bg': '#26272b', '--accent-text': '#b39df5',
'--green': '#2ea36b', '--green-bg': '#173d29', '--purple': '#7c5cd6',
'--purple-bg': '#2a2118', '--surface': '#1f2023', '--surface2': '#17181a',
'--surface3': '#26272b', '--border-md': '#3a3c41', '--text': '#eceeeb',
'--text-2': '#a6aba0', '--text-3': '#83887e', '--ok': '#7fd6a8',
'--warn': '#e8a13c', '--ai': '#7c5cd6', '--err': '#cf4b32'
},
light: {
'--bg-primary': '#fbfbfa', '--bg-secondary': '#f4f5f1', '--bg-sidebar': '#fbfbfa',
'--bg-hover': '#e9ebe4', '--border': '#e4e5e0', '--text-primary': '#242624',
'--text-secondary': '#6c7268', '--text-muted': '#8a8f84', '--accent': '#7c5cd6',
'--accent-green': '#2ea36b', '--tag-bg': '#f4f5f1', '--tag-text': '#7c5cd6',
'--code-bg': '#e8eae3', '--search-bg': '#ffffff', '--scrollbar': '#d6d8d1',
'--resize-handle': '#d6d8d1', '--overlay-bg': 'rgba(0,0,0,0.3)', '--danger': '#a03a28',
'--danger-bg': '#f6e3de', '--success': '#2ea36b', '--success-bg': '#dff2e7',
'--accent-card': '#7c5cd6', '--accent-bg': '#eef0ea', '--accent-text': '#5b3df0',
'--green': '#2ea36b', '--green-bg': '#dff2e7', '--purple': '#7c5cd6',
'--purple-bg': '#fdf6ec', '--surface': '#ffffff', '--surface2': '#fbfbfa',
'--surface3': '#eef0ea', '--border-md': '#d6d8d1', '--text': '#242624',
'--text-2': '#6c7268', '--text-3': '#8a8f84', '--ok': '#1d7a4c',
'--warn': '#e8a13c', '--ai': '#7c5cd6', '--err': '#cf4b32'
}
}
},
'github': { 'github': {
name: 'GitHub', desc: 'Contraste doux', name: 'GitHub', desc: 'Contraste doux',
modes: { modes: {
@@ -523,7 +588,7 @@ var THEMES = {
}; };
// ── Theme Engine ───────────────────────────────────────────────────── // ── Theme Engine ─────────────────────────────────────────────────────
var _currentTheme = 'defaut-obsigate'; var _currentTheme = 'spark';
var _currentMode = 'dark'; var _currentMode = 'dark';
var AVAILABLE_MODES = ['dark', 'light', 'high-contrast', 'sepia']; var AVAILABLE_MODES = ['dark', 'light', 'high-contrast', 'sepia'];
+42 -42
View File
@@ -11,58 +11,58 @@
/* ── Editor save dot state colors ── */ /* ── Editor save dot state colors ── */
:root { :root {
--ok: #34d399; --ok: #7fd6a8;
--warn: #fbbf24; --warn: #e8a13c;
--ai: #8b5cf6; --ai: #7c5cd6;
--err: #f87171; --err: #cf4b32;
} }
/* ===== THEME — DARK (fallback default, no data-theme) ===== */ /* ===== THEME — DARK (fallback default, no data-theme) ===== */
:root { :root {
--bg-primary: #0f1117; --bg-primary: #17181a;
--bg-secondary: #161b22; --bg-secondary: #26272b;
--bg-sidebar: #13161d; --bg-sidebar: #17181a;
--bg-hover: #1f2430; --bg-hover: #2e3036;
--border: #21262d; --border: #33353a;
--text-primary: #e6edf3; --text-primary: #eceeeb;
--text-secondary: #8b949e; --text-secondary: #a6aba0;
--text-muted: #484f58; --text-muted: #83887e;
--accent: #58a6ff; --accent: #7c5cd6;
--accent-green: #3fb950; --accent-green: #2ea36b;
--tag-bg: #1f2a3a; --tag-bg: #26272b;
--tag-text: #79c0ff; --tag-text: #7c5cd6;
--code-bg: #161b22; --code-bg: #2c2e33;
--search-bg: #21262d; --search-bg: #1f2023;
--scrollbar: #30363d; --scrollbar: #3a3c41;
--resize-handle: #30363d; --resize-handle: #3a3c41;
--overlay-bg: rgba(0, 0, 0, 0.5); --overlay-bg: rgba(0, 0, 0, 0.5);
--danger: #ff7b72; --danger: #e8a08d;
--danger-bg: #3d1a18; --danger-bg: #40241f;
--success: #3fb950; --success: #2ea36b;
--success-bg: #1a3d1f; --success-bg: #173d29;
--accent-card: #58a6ff; --accent-card: #7c5cd6;
--accent-bg: #1f2a3a; --accent-bg: #26272b;
--accent-text: #79c0ff; --accent-text: #b39df5;
--green: #3fb950; --green: #2ea36b;
--green-bg: #1a3d1f; --green-bg: #173d29;
--purple: #a371f7; --purple: #7c5cd6;
--purple-bg: #2d1b4e; --purple-bg: #2a2118;
--surface: #161b22; --surface: #1f2023;
--surface2: #0f1117; --surface2: #17181a;
--surface3: #0d0f14; --surface3: #26272b;
--border-md: #30363d; --border-md: #3a3c41;
--text: #e6edf3; --text: #eceeeb;
--text-2: #8b949e; --text-2: #a6aba0;
--text-3: #484f58; --text-3: #83887e;
--mono: "JetBrains Mono", monospace; --mono: "JetBrains Mono", monospace;
--radius: 6px; --radius: 6px;
--radius-lg: 10px; --radius-lg: 10px;
/* #154-A1 — data-grid tokens: the sheet reads slightly lighter than the /* #154-A1 — data-grid tokens: the sheet reads slightly lighter than the
chrome (toolbar/panels), headers are clearly distinct from cells. */ chrome (toolbar/panels), headers are clearly distinct from cells. */
--grid-bg: #161b22; --grid-bg: #1f2023;
--grid-header-bg: #1f2430; --grid-header-bg: #2e3036;
--grid-header-text: #e6edf3; --grid-header-text: #eceeeb;
--grid-border: #3d444d; --grid-border: #33353a;
--grid-zebra: rgba(255, 255, 255, 0.025); --grid-zebra: rgba(255, 255, 255, 0.025);
} }
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "obsigate", "name": "obsigate",
"version": "2.80.1", "version": "2.80.2",
"description": "**Porte d'entrée web ultra-léger pour vos vaults Obsidian** — Accédez, naviguez et recherchez dans toutes vos notes Obsidian depuis n'importe quel appareil via une interface web moderne et responsive.", "description": "**Porte d'entrée web ultra-léger pour vos vaults Obsidian** — Accédez, naviguez et recherchez dans toutes vos notes Obsidian depuis n'importe quel appareil via une interface web moderne et responsive.",
"main": "patch.js", "main": "patch.js",
"directories": { "directories": {