Compare commits

...

5 Commits

Author SHA1 Message Date
e94b841b2a Merge pull request 'feat: Giga Rice 2026 — violet-chaton v2 + Ghost Shell AGS v3' (#1) from features/giga-rice-2026 into dev
Reviewed-on: #1
2026-03-26 08:14:28 +00:00
51b725e1f7 fix(ags-v3): nice-to-have — portabilité, perf, réactivité
- Prompt.tsx: GLib.get_user_name() au lieu de hardcode "tetardtek"
- ghost-shell.desktop: $HOME au lieu de chemin absolu
- SystemStats.tsx: lecture /proc/stat + /proc/meminfo (zero fork, économie batterie)
- Battery.tsx: createDerivedBinding percentage+charging — réactif sur branchement
2026-03-26 09:13:36 +01:00
da22b6446d fix(ags-v3): audit fixes — portable brain path, reactive volume, SCSS dedup
- brain.ts: BRAIN_ROOT résolu via $BRAIN_ROOT env / ~/.config/brain-path / fallback ~/Dev/Brain
- Volume.tsx: bindings volume + mute séparés et réactifs
- style.scss: importe _bar.scss et _heartbeat.scss via @use, supprime 199 lignes dupliquées
2026-03-26 08:58:33 +01:00
Tetardtek-Cortex
932b174c36 feat: Ghost Shell v2 — AGS v3 statusbar + violet-chaton v2 palette
- AGS v3.1.0 (Astal/GTK3) Ghost Shell avec ghost mode (heartbeat + hover reveal)
- Modules : clock, battery, volume (interactif), network, MPRIS, CPU/RAM, systray
- Brain Power panel (Super + B) — lecture live focus/todos/session
- tetardtek_ prompt avec curseur clignotant
- Palette violet-chaton v2 documentée (Mitsuri Kanroji gradient magenta → green)
- Autostart COSMIC via .desktop
- Archive AGS v1 conservée pour référence
2026-03-26 06:54:17 +01:00
Tetardtek-Cortex
7e9d12e640 feat: violet-chaton v2 — palette originale, kitty, AGS, Maple Mono NF
Refonte complete du rice. Palette 100% originale (Mitsuri Kanroji inspired),
zero emprunt Dracula/Catppuccin. 50 fichiers, 3200+ lignes.

Palette v2:
- palette.sh source de verite unique (dark + light)
- 5 accents (magenta, lilac, mitsuri, lavande, champagne)
- 4 semantiques derivees, 4 niveaux texte, 6 fonds
- Gradient signature: magenta → lilac → lavande → mitsuri
- Variante Light: fonds lavande, accents assombris WCAG

Terminal:
- kitty (remplace COSMIC Term comme principal)
- Maple Mono NF (cursive italics, ligatures)
- Cursor trail magenta, splits/layouts tiling, undercurl
- Vi-mode zsh avec cursor shape adaptatif

Shell:
- starship 3 lignes (palette nommee, brain_name, battery, sudo)
- zshrc v2 (nouveaux outils, fzf pimp, shell functions, vi-mode)
- Commandes custom: proj, glog, fkill, colors, hotkeys, weather, y

Desktop:
- AGS config (bar 3-pills, OSD gradient, launcher, notifications)
- COSMIC Dark + Light v2 (7 fichiers RON chacun)
- COSMIC Term v2 (color schemes dark/light, Maple Mono NF)
- GTK3/GTK4 dark + light css
- Vivaldi theme v2

Outils:
- +kitty +dust +procs +tokei +sd +hyperfine +gping +Maple Mono NF
- Propagation palette sur: bat, btop, cava, yazi, lazygit, rofi,
  delta, fastfetch, atuin, ls-colors, vivaldi
- Claude Code statusline brain-aware

Docs:
- README v2 complet (palette, structure, raccourcis, commandes)
- help.md v2 (reference exhaustive)
2026-03-26 03:57:18 +01:00
80 changed files with 5717 additions and 1633 deletions

View File

@@ -0,0 +1,34 @@
// ── violet-chaton v2 — AGS config ───────────────────────────────────────────
// Barre + OSD + Launcher + Notifications
// Modulaire : Hyprland = full, COSMIC = bar + OSD + launcher + notifs
import { Bar } from "./widgets/Bar.js";
import { OSD } from "./widgets/OSD.js";
import { Launcher } from "./widgets/Launcher.js";
import { Notifications } from "./widgets/Notifications.js";
// ── Compositor detection ────────────────────────────────────────────────────
const compositor = (() => {
const session = Utils.exec("echo $XDG_CURRENT_DESKTOP").trim();
if (session.includes("Hyprland")) return "hyprland";
if (session.includes("COSMIC")) return "cosmic";
return "unknown";
})();
print(`[violet-chaton] compositor: ${compositor}`);
// ── Windows ─────────────────────────────────────────────────────────────────
const windows = (monitor) => {
const wins = [
Bar(monitor, compositor),
OSD(monitor),
Launcher(monitor),
Notifications(monitor),
];
return wins;
};
export default {
style: `${App.configDir}/css/style.css`,
windows: windows(0).flat(),
};

View File

@@ -0,0 +1,385 @@
/* ── violet-chaton v2 — AGS stylesheet ────────────────────────────────────────
*
* Palette :
* crust #1a0e27
* base #261537
* mantle #341c4a
* surface0 #3d2454
* surface1 #493161
* surface2 #5a3875
* magenta #ff4da6 accent primaire
* lilac #c9a0ff accent secondaire
* mitsuri #9adba8 vert pastel
* lavande #a4b4ff bleu-violet
* champagne #e8c87a or chaud
* danger #f25c7a
* text #f0eaf8
* subtext1 #c4b8d4
* subtext0 #9a8fad
* muted #716686
*
* ─────────────────────────────────────────────────────────────────────────── */
/* ── Reset ───────────────────────────────────────────────────────────────── */
* {
font-family: "Maple Mono NF", "MapleMono Nerd Font", monospace;
font-size: 13px;
font-weight: bold;
}
/* ══════════════════════════════════════════════════════════════════════════
* BAR — 3 pills glassmorphism (island floating)
* ══════════════════════════════════════════════════════════════════════════ */
.bar {
background: transparent;
}
.bar .modules-left,
.bar .modules-center,
.bar .modules-right {
background: alpha(#261537, 0.88);
border-radius: 14px;
border: 3px solid alpha(#ff4da6, 0.60);
margin: 8px 4px;
padding: 0 4px;
}
.bar .modules-left:hover,
.bar .modules-center:hover,
.bar .modules-right:hover {
border-color: #ff4da6;
box-shadow: 0 4px 28px alpha(#c9a0ff, 0.18);
}
/* ── Launcher button ─────────────────────────────────────────────────────── */
.bar .launcher-btn {
color: #ff4da6;
font-size: 19px;
padding: 0 14px 0 18px;
min-width: 0;
min-height: 0;
}
.bar .launcher-btn:hover {
color: #c9a0ff;
}
/* ── Separator ───────────────────────────────────────────────────────────── */
.bar .separator {
color: alpha(#f0eaf8, 0.12);
font-size: 11px;
padding: 0 4px;
font-weight: normal;
}
/* ── Clock ───────────────────────────────────────────────────────────────── */
.bar .clock {
color: #ff4da6;
font-weight: 900;
font-size: 14px;
letter-spacing: 0.04em;
padding: 0 10px;
}
.bar .clock:hover {
color: #c9a0ff;
}
/* ── Date ────────────────────────────────────────────────────────────────── */
.bar .date {
color: #a4b4ff;
font-size: 12px;
font-weight: normal;
padding: 0 10px 0 2px;
}
/* ── System modules ──────────────────────────────────────────────────────── */
.bar .cpu { color: #a4b4ff; }
.bar .cpu.warning { color: #e8c87a; }
.bar .cpu.critical { color: #f25c7a; }
.bar .ram { color: #ff4da6; }
.bar .ram.warning { color: #e8c87a; }
.bar .ram.critical { color: #f25c7a; }
.bar .temp {
color: alpha(#a4b4ff, 0.60);
font-size: 11px;
font-weight: normal;
}
.bar .temp.warning { color: #e8c87a; }
.bar .temp.critical { color: #f25c7a; }
/* ── Network ─────────────────────────────────────────────────────────────── */
.bar .network {
color: #a4b4ff;
font-size: 11px;
font-weight: normal;
}
.bar .network.disconnected { color: #f25c7a; }
.bar .network.wifi { color: alpha(#a4b4ff, 0.80); }
/* ── Volume ──────────────────────────────────────────────────────────────── */
.bar .volume { color: #ff4da6; }
.bar .volume.muted { color: alpha(#ff4da6, 0.30); }
/* ── Battery ─────────────────────────────────────────────────────────────── */
.bar .battery { color: #ff4da6; }
.bar .battery.charging { color: #9adba8; }
.bar .battery.low { color: #f25c7a; }
.bar .battery.warning { color: #e8c87a; }
/* ── Media (MPRIS) ───────────────────────────────────────────────────────── */
.bar .media {
color: #c9a0ff;
font-size: 12px;
font-weight: normal;
padding: 0 10px;
}
.bar .media.paused {
color: alpha(#c9a0ff, 0.50);
font-style: italic;
}
/* ── Systray ─────────────────────────────────────────────────────────────── */
.bar .systray { padding: 0 8px; }
.bar .systray .passive { opacity: 0.5; }
/* ── Workspaces (Hyprland only) ──────────────────────────────────────────── */
.bar .workspaces button {
background: transparent;
color: #716686;
min-width: 24px;
min-height: 24px;
border-radius: 8px;
margin: 2px;
padding: 0;
}
.bar .workspaces button.active {
background: alpha(#ff4da6, 0.20);
color: #ff4da6;
border: 1px solid alpha(#ff4da6, 0.40);
}
.bar .workspaces button.occupied {
color: #c9a0ff;
}
.bar .workspaces button:hover {
background: alpha(#c9a0ff, 0.12);
color: #c9a0ff;
}
/* ── Power button ────────────────────────────────────────────────────────── */
.bar .power-btn {
color: #f25c7a;
font-size: 15px;
padding: 0 14px 0 8px;
min-width: 0;
min-height: 0;
}
.bar .power-btn:hover { color: #ff4da6; }
/* ── Hover global modules ────────────────────────────────────────────────── */
.bar .cpu:hover,
.bar .ram:hover,
.bar .temp:hover,
.bar .network:hover,
.bar .volume:hover,
.bar .battery:hover {
color: #c9a0ff;
}
/* ══════════════════════════════════════════════════════════════════════════
* OSD — volume / brightness overlay
* ══════════════════════════════════════════════════════════════════════════ */
.osd {
background: alpha(#261537, 0.92);
border-radius: 14px;
border: 2px solid alpha(#ff4da6, 0.40);
padding: 12px 20px;
margin: 0 0 40px 0;
}
.osd .icon {
color: #ff4da6;
font-size: 24px;
margin-right: 12px;
}
.osd progressbar trough {
background: #3d2454;
border-radius: 8px;
min-height: 8px;
min-width: 200px;
}
.osd progressbar progress {
border-radius: 8px;
min-height: 8px;
background: linear-gradient(to right, #ff4da6, #c9a0ff, #a4b4ff, #9adba8);
}
.osd .label {
color: #f0eaf8;
font-size: 12px;
margin-left: 8px;
}
/* ══════════════════════════════════════════════════════════════════════════
* LAUNCHER — app search
* ══════════════════════════════════════════════════════════════════════════ */
.launcher {
background: alpha(#1a0e27, 0.94);
border-radius: 14px;
border: 2px solid alpha(#ff4da6, 0.38);
padding: 10px;
min-width: 500px;
}
.launcher .search {
background: alpha(#261537, 0.75);
border-radius: 12px;
border: 1px solid alpha(#5a3875, 0.50);
padding: 9px 14px;
color: #f0eaf8;
caret-color: #ff4da6;
font-size: 14px;
}
.launcher .search:focus {
border-color: alpha(#ff4da6, 0.60);
}
.launcher .app-item {
background: transparent;
border-radius: 8px;
padding: 7px 10px;
color: #f0eaf8;
}
.launcher .app-item:hover,
.launcher .app-item:focus {
background: alpha(#ff4da6, 0.16);
border: 1px solid alpha(#ff4da6, 0.32);
}
.launcher .app-item:hover label,
.launcher .app-item:focus label {
color: #ff4da6;
}
.launcher .app-item image {
margin-right: 10px;
}
.launcher .no-results {
color: #716686;
padding: 20px;
}
/* ══════════════════════════════════════════════════════════════════════════
* NOTIFICATIONS
* ══════════════════════════════════════════════════════════════════════════ */
.notification {
background: alpha(#261537, 0.94);
border-radius: 14px;
border: 2px solid alpha(#c9a0ff, 0.30);
padding: 12px;
margin: 8px;
min-width: 350px;
}
.notification .title {
color: #ff4da6;
font-weight: bold;
font-size: 13px;
}
.notification .body {
color: #c4b8d4;
font-weight: normal;
font-size: 12px;
}
.notification .app-name {
color: #716686;
font-size: 11px;
}
.notification .time {
color: #716686;
font-size: 10px;
}
.notification .close-btn {
color: #716686;
font-size: 14px;
min-width: 0;
min-height: 0;
padding: 2px 6px;
border-radius: 6px;
}
.notification .close-btn:hover {
color: #f25c7a;
background: alpha(#f25c7a, 0.12);
}
.notification .actions button {
background: alpha(#5a3875, 0.50);
color: #c9a0ff;
border-radius: 8px;
padding: 4px 12px;
margin: 4px 4px 0 0;
}
.notification .actions button:hover {
background: alpha(#ff4da6, 0.20);
color: #ff4da6;
}
/* ── Urgency levels ──────────────────────────────────────────────────────── */
.notification.critical {
border-color: alpha(#f25c7a, 0.60);
}
.notification.critical .title {
color: #f25c7a;
}
/* ══════════════════════════════════════════════════════════════════════════
* TOOLTIP — shared
* ══════════════════════════════════════════════════════════════════════════ */
tooltip {
background: alpha(#1a0e27, 0.96);
border: 1px solid alpha(#ff4da6, 0.30);
border-radius: 10px;
color: #f0eaf8;
padding: 6px 10px;
}

View File

@@ -0,0 +1,228 @@
// ── violet-chaton v2 — Bar widget ───────────────────────────────────────────
// 3 pills glassmorphism — modulaire selon compositor
const audio = await Service.import("audio");
const battery = await Service.import("battery");
const network = await Service.import("network");
const systemtray = await Service.import("systemtray");
const mpris = await Service.import("mpris");
// ── Helpers ─────────────────────────────────────────────────────────────────
const Separator = () => Widget.Label({ className: "separator", label: "│" });
const Clock = () => Widget.Label({
className: "clock",
connections: [[1000, (self) => {
self.label = Utils.exec("date +%H:%M");
}]],
});
const DateWidget = () => Widget.Label({
className: "date",
connections: [[60000, (self) => {
self.label = Utils.exec("date '+%a %d %b'");
}]],
});
// ── System ──────────────────────────────────────────────────────────────────
const CPU = () => Widget.Label({
className: "cpu",
connections: [[2000, (self) => {
const usage = Math.round(
Number(Utils.exec(`bash -c "top -bn1 | awk '/^%Cpu/ {print 100-$8}'"`)
));
self.label = `󰻠 ${usage}%`;
self.toggleClassName("warning", usage > 70);
self.toggleClassName("critical", usage > 90);
}]],
});
const RAM = () => Widget.Label({
className: "ram",
connections: [[2000, (self) => {
const used = Utils.exec(`bash -c "free -m | awk '/^Mem:/ {printf \"%.1f\", $3/1024}'"`)
const total = Utils.exec(`bash -c "free -m | awk '/^Mem:/ {printf \"%.1f\", $2/1024}'"`)
const pct = Math.round((parseFloat(used) / parseFloat(total)) * 100);
self.label = `󰑭 ${used}G`;
self.toggleClassName("warning", pct > 70);
self.toggleClassName("critical", pct > 90);
}]],
});
// ── Network ─────────────────────────────────────────────────────────────────
const Network = () => Widget.Label({
className: "network",
connections: [[network, (self) => {
if (network.primary === "wifi") {
const wifi = network.wifi;
self.label = `󰤨 ${wifi?.ssid || ""}`;
self.toggleClassName("wifi", true);
self.toggleClassName("disconnected", false);
} else if (network.primary === "wired") {
self.label = "󰈀 Eth";
self.toggleClassName("wifi", false);
self.toggleClassName("disconnected", false);
} else {
self.label = "󰤮 ";
self.toggleClassName("disconnected", true);
}
}]],
});
// ── Volume ──────────────────────────────────────────────────────────────────
const Volume = () => Widget.Button({
className: "volume",
onClicked: () => { audio.speaker.isMuted = !audio.speaker.isMuted; },
child: Widget.Label({
connections: [[audio, (self) => {
const vol = Math.round((audio.speaker?.volume || 0) * 100);
const muted = audio.speaker?.isMuted;
const icon = muted ? "󰝟" : vol > 66 ? "󰕾" : vol > 33 ? "󰖀" : "󰕿";
self.label = `${icon} ${vol}%`;
self.parent?.toggleClassName("muted", muted);
}, "speaker-changed"]],
}),
});
// ── Battery ─────────────────────────────────────────────────────────────────
const Battery = () => Widget.Label({
className: "battery",
visible: battery.bind("available"),
connections: [[battery, (self) => {
const pct = battery.percent;
const charging = battery.charging;
const icon = charging ? "󰂄" : pct > 80 ? "󰁹" : pct > 60 ? "󰂀" :
pct > 40 ? "󰁾" : pct > 20 ? "󰁻" : "󰂎";
self.label = `${icon} ${pct}%`;
self.toggleClassName("charging", charging);
self.toggleClassName("low", pct <= 20 && !charging);
self.toggleClassName("warning", pct <= 30 && !charging);
}]],
});
// ── Media ───────────────────────────────────────────────────────────────────
const Media = () => Widget.Label({
className: "media",
connections: [[mpris, (self) => {
const player = mpris.players[0];
if (!player) {
self.visible = false;
return;
}
self.visible = true;
const artist = player.trackArtists?.join(", ") || "";
const title = player.trackTitle || "";
const icon = player.playBackStatus === "Playing" ? " " : " ";
self.label = `${icon}${artist ? artist + " — " : ""}${title}`.slice(0, 50);
self.toggleClassName("paused", player.playBackStatus !== "Playing");
}]],
});
// ── Systray ─────────────────────────────────────────────────────────────────
const SysTray = () => Widget.Box({
className: "systray",
children: systemtray.bind("items").transform((items) =>
items.map((item) =>
Widget.Button({
child: Widget.Icon({ icon: item.bind("icon"), size: 16 }),
tooltipMarkup: item.bind("tooltip-markup"),
onPrimaryClick: (_, event) => item.activate(event),
onSecondaryClick: (_, event) => item.openMenu(event),
})
)
),
});
// ── Launcher button ─────────────────────────────────────────────────────────
const LauncherBtn = () => Widget.Button({
className: "launcher-btn",
label: "󱄅",
onClicked: () => App.toggleWindow("launcher"),
});
// ── Power button ────────────────────────────────────────────────────────────
const PowerBtn = () => Widget.Button({
className: "power-btn",
label: "⏻",
onClicked: () => Utils.exec("bash -c 'systemctl poweroff'"),
});
// ── Workspaces (Hyprland only) ──────────────────────────────────────────────
const Workspaces = (compositor) => {
if (compositor !== "hyprland") return Widget.Box({});
const hyprland = await Service.import("hyprland");
return Widget.Box({
className: "workspaces",
children: hyprland.bind("workspaces").transform((ws) =>
ws.sort((a, b) => a.id - b.id)
.filter((w) => w.id > 0)
.map((w) =>
Widget.Button({
onClicked: () => hyprland.messageAsync(`dispatch workspace ${w.id}`),
child: Widget.Label({ label: `${w.id}` }),
className: hyprland.active.workspace.bind("id").transform(
(id) => id === w.id ? "active" : w.windows > 0 ? "occupied" : ""
),
})
)
),
});
};
// ── Bar assembly ────────────────────────────────────────────────────────────
export const Bar = (monitor, compositor) => Widget.Window({
name: `bar-${monitor}`,
monitor,
anchor: ["top", "left", "right"],
exclusivity: "exclusive",
className: "bar",
child: Widget.CenterBox({
startWidget: Widget.Box({
className: "modules-left",
children: [
LauncherBtn(),
Separator(),
Workspaces(compositor),
Separator(),
CPU(),
RAM(),
],
}),
centerWidget: Widget.Box({
className: "modules-center",
children: [
Media(),
],
}),
endWidget: Widget.Box({
className: "modules-right",
hpack: "end",
children: [
Network(),
Separator(),
Volume(),
Separator(),
Battery(),
Separator(),
DateWidget(),
Clock(),
Separator(),
SysTray(),
Separator(),
PowerBtn(),
],
}),
}),
});

View File

@@ -0,0 +1,99 @@
// ── violet-chaton v2 — Launcher widget ──────────────────────────────────────
// App launcher avec recherche fuzzy
const applications = await Service.import("applications");
const AppItem = (app) => Widget.Button({
className: "app-item",
onClicked: () => {
app.launch();
App.closeWindow("launcher");
},
child: Widget.Box({
children: [
Widget.Icon({ icon: app.iconName || "application-x-executable", size: 24 }),
Widget.Box({
vertical: true,
children: [
Widget.Label({
label: app.name,
xalign: 0,
truncate: "end",
}),
Widget.Label({
label: app.description || "",
xalign: 0,
truncate: "end",
className: "description",
css: "color: #716686; font-size: 11px; font-weight: normal;",
}),
],
}),
],
}),
});
export const Launcher = (monitor) => {
let apps = applications.list;
const list = Widget.Box({
vertical: true,
spacing: 2,
});
const entry = Widget.Entry({
className: "search",
placeholderText: "Rechercher...",
onAccept: () => {
const first = apps[0];
if (first) {
first.launch();
App.closeWindow("launcher");
}
},
onChange: ({ text }) => {
apps = applications.query(text || "");
list.children = apps.slice(0, 12).map(AppItem);
if (apps.length === 0) {
list.children = [Widget.Label({
className: "no-results",
label: "Aucun resultat",
})];
}
},
});
return Widget.Window({
name: "launcher",
monitor,
anchor: ["top"],
layer: "overlay",
visible: false,
keymode: "exclusive",
setup: (self) => {
self.keybind("Escape", () => App.closeWindow("launcher"));
self.hook(App, (_, name, visible) => {
if (name === "launcher" && visible) {
entry.text = "";
apps = applications.list;
list.children = apps.slice(0, 12).map(AppItem);
entry.grab_focus();
}
});
},
child: Widget.Box({
className: "launcher",
vertical: true,
children: [
Widget.Scrollable({
hscroll: "never",
vscroll: "automatic",
css: "min-height: 400px;",
child: list,
}),
entry,
],
}),
});
};

View File

@@ -0,0 +1,105 @@
// ── violet-chaton v2 — Notifications widget ─────────────────────────────────
// Popup notifications stylees — urgency-aware
const notifications = await Service.import("notifications");
// Ne pas déranger
notifications.popupTimeout = 5000;
notifications.cacheActions = true;
const NotificationIcon = (notif) => {
if (notif.image) {
return Widget.Box({
css: `
min-width: 48px; min-height: 48px;
background-image: url("${notif.image}");
background-size: cover;
background-position: center;
border-radius: 8px;
margin-right: 10px;
`,
});
}
return Widget.Icon({
icon: notif.appIcon || notif.appEntry || "dialog-information",
size: 36,
css: "margin-right: 10px;",
});
};
const Notification = (notif) => Widget.Box({
className: `notification ${notif.urgency}`,
vertical: true,
children: [
Widget.Box({
children: [
NotificationIcon(notif),
Widget.Box({
vertical: true,
hexpand: true,
children: [
Widget.Box({
children: [
Widget.Label({
className: "title",
label: notif.summary,
xalign: 0,
hexpand: true,
truncate: "end",
}),
Widget.Label({
className: "time",
label: new Date(notif.time * 1000)
.toLocaleTimeString("fr-FR", {
hour: "2-digit",
minute: "2-digit",
}),
}),
Widget.Button({
className: "close-btn",
label: "✕",
onClicked: () => notif.close(),
}),
],
}),
Widget.Label({
className: "app-name",
label: notif.appName || "",
xalign: 0,
}),
],
}),
],
}),
...(notif.body ? [Widget.Label({
className: "body",
label: notif.body,
xalign: 0,
wrap: true,
useMarkup: true,
})] : []),
...(notif.actions.length > 0 ? [Widget.Box({
className: "actions",
children: notif.actions.map((action) =>
Widget.Button({
label: action.label,
onClicked: () => notif.invoke(action.id),
})
),
})] : []),
],
});
export const Notifications = (monitor) => Widget.Window({
name: `notifications-${monitor}`,
monitor,
anchor: ["top", "right"],
layer: "overlay",
child: Widget.Box({
vertical: true,
css: "min-width: 350px;",
children: notifications.bind("popups").transform((popups) =>
popups.map(Notification)
),
}),
});

View File

@@ -0,0 +1,95 @@
// ── violet-chaton v2 — OSD widget ───────────────────────────────────────────
// Overlay volume / brightness avec gradient Mitsuri
const audio = await Service.import("audio");
// ── OSD reveal timer ────────────────────────────────────────────────────────
let osdTimeout = null;
const showOSD = (window) => {
window.visible = true;
if (osdTimeout) clearTimeout(osdTimeout);
osdTimeout = setTimeout(() => {
window.visible = false;
}, 1500);
};
// ── Volume OSD ──────────────────────────────────────────────────────────────
const VolumeOSD = () => {
const icon = Widget.Label({ className: "icon" });
const progress = Widget.ProgressBar();
const label = Widget.Label({ className: "label" });
const box = Widget.Box({
className: "osd",
children: [icon, progress, label],
connections: [[audio, (self) => {
const vol = audio.speaker?.volume || 0;
const muted = audio.speaker?.isMuted;
icon.label = muted ? "󰝟" : vol > 0.66 ? "󰕾" : vol > 0.33 ? "󰖀" : "󰕿";
progress.value = vol;
label.label = `${Math.round(vol * 100)}%`;
}, "speaker-changed"]],
});
return box;
};
// ── Brightness OSD ──────────────────────────────────────────────────────────
const BrightnessOSD = () => {
const icon = Widget.Label({ className: "icon", label: "󰃞" });
const progress = Widget.ProgressBar();
const label = Widget.Label({ className: "label" });
const getBrightness = () => {
try {
const max = Number(Utils.exec("brightnessctl max"));
const cur = Number(Utils.exec("brightnessctl get"));
return max > 0 ? cur / max : 0;
} catch {
return 0;
}
};
const box = Widget.Box({
className: "osd",
children: [icon, progress, label],
connections: [[500, (self) => {
const val = getBrightness();
progress.value = val;
label.label = `${Math.round(val * 100)}%`;
}]],
});
return box;
};
// ── OSD windows ─────────────────────────────────────────────────────────────
export const OSD = (monitor) => {
const volumeWin = Widget.Window({
name: `osd-volume-${monitor}`,
monitor,
anchor: ["bottom"],
layer: "overlay",
visible: false,
child: VolumeOSD(),
});
const brightnessWin = Widget.Window({
name: `osd-brightness-${monitor}`,
monitor,
anchor: ["bottom"],
layer: "overlay",
visible: false,
child: BrightnessOSD(),
});
// Auto-show on volume change
Utils.merge([audio.speaker?.bind("volume")], () => showOSD(volumeWin));
return [volumeWin, brightnessWin];
};

View File

@@ -1,376 +1,19 @@
## ── violet-chaton config ────────────────────────────────────────────────────── ## ── violet-chaton v2 — atuin config ──────────────────────────────────────────
dialect = "uk" # format de date européen dialect = "uk"
timezone = "local" timezone = "local"
search_mode = "fuzzy" # recherche floue comme fzf search_mode = "fuzzy"
filter_mode = "global" # cherche dans tout l'historique filter_mode = "global"
style = "full" # interface complète style = "full"
inline_height = 40 # occupe 40% du terminal inline_height = 40
invert = true # barre de recherche en haut invert = true
show_preview = true # aperçu de la commande sélectionnée show_preview = true
enter_accept = true # Entrée accepte directement enter_accept = true
[theme] [theme]
name = "violet-chaton" name = "violet-chaton"
## ── fin config violet-chaton ──────────────────────────────────────────────────
## Base directory for Atuin data files (databases, keys, session, etc.)
## All data file paths default to being relative to this directory.
## linux/mac: ~/.local/share/atuin (or XDG_DATA_HOME/atuin)
## windows: %USERPROFILE%/.local/share/atuin
# data_dir = "~/.local/share/atuin"
## where to store your database, default is your system data directory
## linux/mac: ~/.local/share/atuin/history.db
## windows: %USERPROFILE%/.local/share/atuin/history.db
# db_path = "~/.history.db"
## where to store your encryption key, default is your system data directory
## linux/mac: ~/.local/share/atuin/key
## windows: %USERPROFILE%/.local/share/atuin/key
# key_path = "~/.key"
## where to store your auth session token, default is your system data directory
## linux/mac: ~/.local/share/atuin/session
## windows: %USERPROFILE%/.local/share/atuin/session
# session_path = "~/.session"
## date format used, either "us" or "uk"
# dialect = "us"
## default timezone to use when displaying time
## either "l", "local" to use the system's current local timezone, or an offset
## from UTC in the format of "<+|->H[H][:M[M][:S[S]]]"
## for example: "+9", "-05", "+03:30", "-01:23:45", etc.
# timezone = "local"
## enable or disable automatic sync
# auto_sync = true
## enable or disable automatic update checks
# update_check = true
## address of the sync server
# sync_address = "https://api.atuin.sh"
## how often to sync history. note that this is only triggered when a command
## is ran, so sync intervals may well be longer
## set it to 0 to sync after every command
# sync_frequency = "10m"
## which search mode to use
## possible values: prefix, fulltext, fuzzy, skim
# search_mode = "fuzzy"
## which filter mode to use by default
## possible values: "global", "host", "session", "session-preload", "directory", "workspace"
## consider using search.filters to customize the enablement and order of filter modes
# filter_mode = "global"
## With workspace filtering enabled, Atuin will filter for commands executed
## in any directory within a git repository tree (default: false).
##
## To use workspace mode by default when available, set this to true and
## set filter_mode to "workspace" or leave it unspecified and
## set search.filters to include "workspace" before other filter modes.
# workspaces = false
## which filter mode to use when atuin is invoked from a shell up-key binding
## the accepted values are identical to those of "filter_mode"
## leave unspecified to use same mode set in "filter_mode"
# filter_mode_shell_up_key_binding = "global"
## which search mode to use when atuin is invoked from a shell up-key binding
## the accepted values are identical to those of "search_mode"
## leave unspecified to use same mode set in "search_mode"
# search_mode_shell_up_key_binding = "fuzzy"
## which style to use
## possible values: auto, full, compact
# style = "auto"
## the maximum number of lines the interface should take up
## set it to 0 to always go full screen
# inline_height = 0
## the maximum number of lines the interface should take up
## when atuin is invoked from a shell up-key binding
## the accepted values are identical to those of "inline_height"
# inline_height_shell_up_key_binding = 0
## Invert the UI - put the search bar at the top , Default to `false`
# invert = false
## enable or disable showing a preview of the selected command
## useful when the command is longer than the terminal width and is cut off
# show_preview = true
## what to do when the escape key is pressed when searching
## possible values: return-original, return-query
# exit_mode = "return-original"
## possible values: emacs, subl
# word_jump_mode = "emacs"
## characters that count as a part of a word
# word_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
## number of context lines to show when scrolling by pages
# scroll_context_lines = 1
## use ctrl instead of alt as the shortcut modifier key for numerical UI shortcuts
## alt-0 .. alt-9
# ctrl_n_shortcuts = false
## Show numeric shortcuts (1..9) beside list items in the TUI
## set to false to hide the moving numbers if you find them distracting
# show_numeric_shortcuts = true
## default history list format - can also be specified with the --format arg
# history_format = "{time}\t{command}\t{duration}"
## prevent commands matching any of these regexes from being written to history.
## Note that these regular expressions are unanchored, i.e. if they don't start
## with ^ or end with $, they'll match anywhere in the command.
## For details on the supported regular expression syntax, see
## https://docs.rs/regex/latest/regex/#syntax
# history_filter = [
# "^secret-cmd",
# "^innocuous-cmd .*--secret=.+",
# ]
## prevent commands run with cwd matching any of these regexes from being written
## to history. Note that these regular expressions are unanchored, i.e. if they don't
## start with ^ or end with $, they'll match anywhere in CWD.
## For details on the supported regular expression syntax, see
## https://docs.rs/regex/latest/regex/#syntax
# cwd_filter = [
# "^/very/secret/area",
# ]
## Configure the maximum height of the preview to show.
## Useful when you have long scripts in your history that you want to distinguish
## by more than the first few lines.
# max_preview_height = 4
## Configure whether or not to show the help row, which includes the current Atuin
## version (and whether an update is available), a keymap hint, and the total
## amount of commands in your history.
# show_help = true
## Configure whether or not to show tabs for search and inspect
# show_tabs = true
## Configure whether or not the tabs row may be auto-hidden, which includes the current Atuin
## tab, such as Search or Inspector, and other tabs you may wish to see. This will
## only be hidden if there are fewer than this count of lines available, and does not affect the use
## of keyboard shortcuts to switch tab. 0 to never auto-hide, default is 8 (lines).
## This is ignored except in `compact` mode.
# auto_hide_height = 8
## Defaults to true. This matches history against a set of default regex, and will not save it if we get a match. Defaults include
## 1. AWS key id
## 2. Github pat (old and new)
## 3. Slack oauth tokens (bot, user)
## 4. Slack webhooks
## 5. Stripe live/test keys
# secrets_filter = true
## Defaults to true. If enabled, upon hitting enter Atuin will immediately execute the command,
## whereas tab will put the command in the prompt for editing.
## If set to false, both enter and tab will place the command in the prompt for editing.
## This applies for new installs. Old installs will keep the old behaviour unless configured otherwise.
enter_accept = true
## Defaults to false. If enabled, when triggered after &&, || or |, Atuin will complete commands to chain rather than replace the current line.
# command_chaining = false
## Defaults to "emacs". This specifies the keymap on the startup of `atuin
## search`. If this is set to "auto", the startup keymap mode in the Atuin
## search is automatically selected based on the shell's keymap where the
## keybinding is defined. If this is set to "emacs", "vim-insert", or
## "vim-normal", the startup keymap mode in the Atuin search is forced to be
## the specified one.
# keymap_mode = "auto"
## Cursor style in each keymap mode. If specified, the cursor style is changed
## in entering the cursor shape. Available values are "default" and
## "{blink,steady}-{block,underline,bar}".
# keymap_cursor = { emacs = "blink-block", vim_insert = "blink-block", vim_normal = "steady-block" }
# network_connect_timeout = 5
# network_timeout = 5
## Timeout (in seconds) for acquiring a local database connection (sqlite)
# local_timeout = 5
## Set this to true and Atuin will minimize motion in the UI - timers will not update live, etc.
## Alternatively, set env NO_MOTION=true
# prefers_reduced_motion = false
[stats]
## Set commands where we should consider the subcommand for statistics. Eg, kubectl get vs just kubectl
# common_subcommands = [
# "apt",
# "cargo",
# "composer",
# "dnf",
# "docker",
# "dotnet",
# "git",
# "go",
# "ip",
# "jj",
# "kubectl",
# "nix",
# "nmcli",
# "npm",
# "pecl",
# "pnpm",
# "podman",
# "port",
# "systemctl",
# "tmux",
# "yarn",
# ]
## Set commands that should be totally stripped and ignored from stats
# common_prefix = ["sudo"]
## Set commands that will be completely ignored from stats
# ignored_commands = [
# "cd",
# "ls",
# "vi"
# ]
[keys]
# Defaults to true. If disabled, using the up/down key won't exit the TUI when scrolled past the first/last entry.
# scroll_exits = true
# Defaults to true. The left arrow key will exit the TUI when scrolling before the first character
# exit_past_line_start = true
# Defaults to true. The right arrow key performs the same functionality as Tab and copies the selected line to the command line to be modified.
# accept_past_line_end = true
# Defaults to false. The left arrow key performs the same functionality as Tab and copies the selected line to the command line to be modified.
# accept_past_line_start = false
# Defaults to false. The backspace key performs the same functionality as Tab and copies the selected line to the command line to be modified when at the start of the line.
# accept_with_backspace = false
[sync] [sync]
# Enable sync v2 by default
# This ensures that sync v2 is enabled for new installs only
# In a later release it will become the default across the board
records = true records = true
[preview]
## which preview strategy to use to calculate the preview height (respects max_preview_height).
## possible values: auto, static
## auto: length of the selected command.
## static: length of the longest command stored in the history.
## fixed: use max_preview_height as fixed height.
# strategy = "auto"
[daemon]
## Enables using the daemon to sync. Requires the daemon to be running in the background. Start it with `atuin daemon`
# enabled = false
## How often the daemon should sync in seconds
# sync_frequency = 300
## The path to the unix socket used by the daemon (on unix systems)
## linux/mac: ~/.local/share/atuin/atuin.sock
## windows: Not Supported
# socket_path = "~/.local/share/atuin/atuin.sock"
## Use systemd socket activation rather than opening the given path (the path must still be correct for the client)
## linux: false
## mac/windows: Not Supported
# systemd_socket = false
## The port that should be used for TCP on non unix systems
# tcp_port = 8889
# [theme]
## Color theme to use for rendering in the terminal.
## There are some built-in themes, including the base theme ("default"),
## "autumn" and "marine". You can add your own themes to the "./themes" subdirectory of your
## Atuin config (or ATUIN_THEME_DIR, if provided) as TOML files whose keys should be one or
## more of AlertInfo, AlertWarn, AlertError, Annotation, Base, Guidance, Important, and
## the string values as lowercase entries from this list:
## https://ogeon.github.io/docs/palette/master/palette/named/index.html
## If you provide a custom theme file, it should be called "NAME.toml" and the theme below
## should be the stem, i.e. `theme = "NAME"` for your chosen NAME.
# name = "autumn"
## Whether the theme manager should output normal or extra information to help fix themes.
## Boolean, true or false. If unset, left up to the theme manager.
# debug = true
[search]
## The list of enabled filter modes, in order of priority.
## The "workspace" mode is skipped when not in a workspace or workspaces = false.
## Default filter mode can be overridden with the filter_mode setting.
# filters = [ "global", "host", "session", "session-preload", "workspace", "directory" ]
[tmux]
## Enable using atuin with tmux popup (requires tmux >= 3.2)
## When enabled and running inside tmux, Atuin will use a popup window for interactive search.
## Set to false to disable the popup.
## This can also be controlled with the ATUIN_TMUX_POPUP environment variable.
## Note: The tmux popup is currently supported in zsh, bash, and fish shells. This currently doesn't work with iTerm native tmux integration.
# enabled = false
## Width of the tmux popup window
## Can be a percentage, or integer (e.g. "100" means 100 characters wide)
# width = "80%"
## Height of the tmux popup window
## Can be a percentage, or integer (e.g. "100" means 100 lines tall)
# height = "60%"
[ui] [ui]
columns = ["exit", "duration", "time", "command"] columns = ["exit", "duration", "time", "command"]
## Columns to display in the interactive search, from left to right.
## The selection indicator (" > ") is always shown first implicitly.
##
## Each column can be specified as a simple string (uses default width)
## or as an object with type, width, and expand:
## { type = "directory", width = 30, expand = true }
##
## Available column types (with default widths):
## duration (5) - Command execution duration (e.g., "123ms")
## time (8) - Relative time since execution (e.g., "59m ago")
## datetime (16) - Absolute timestamp (e.g., "2025-01-22 14:35")
## directory (20) - Working directory (truncated if too long)
## host (15) - Hostname where command was run
## user (10) - Username
## exit (3) - Exit code (colored by success/failure)
## command (*) - The command itself (expands by default)
##
## The "expand" option (default: true for command, false for others) makes a
## column fill remaining space. Only one column should have expand = true.
##
## Default:
# columns = ["duration", "time", "command"]
##
## Examples:
##
## Minimal - more space for commands:
# columns = ["duration", "command"]
##
## With wider directory column:
# columns = ["duration", { type = "directory", width = 30 }, "command"]
##
## Show host for multi-machine sync users:
# columns = ["duration", "time", "host", "command"]
##
## Show exit codes prominently:
# columns = ["exit", "duration", "command"]
##
## Make directory expand instead of command:
# columns = ["duration", "time", { type = "directory", expand = true }, { type = "command", expand = false }]

View File

@@ -4,58 +4,74 @@
"type": "none" "type": "none"
}, },
"display": { "display": {
"separator": " ", "separator": " ",
"color": { "color": {
"keys": "magenta", "keys": "#ff4da6",
"title": "cyan" "title": "#c9a0ff",
"separator": "#5a3875"
} }
}, },
"modules": [ "modules": [
"title", {
"separator", "type": "title",
"format": "{user-name}@{host-name}",
{"type": "os", "key": "󰣚 Système ", "keyColor": "magenta"}, "keyColor": "#ff4da6"
{"type": "kernel", "key": " Kernel ", "keyColor": "magenta"}, },
{"type": "shell", "key": " Shell ", "keyColor": "magenta"}, {
{"type": "terminal", "key": " Terminal ", "keyColor": "magenta"}, "type": "custom",
{"type": "wm", "key": " Bureau ", "keyColor": "magenta"}, "format": "───────────────────────────────────",
{"type": "packages", "key": "󰏖 Paquets ", "keyColor": "magenta"}, "outputColor": "#3d2454"
},
"break", "break",
{"type": "cpu", "key": "󰻠 CPU ", "keyColor": "magenta"}, {"type": "os", "key": " sys", "keyColor": "#ff4da6"},
{"type": "kernel", "key": " ker", "keyColor": "#c9a0ff"},
{"type": "shell", "key": " sh ", "keyColor": "#a4b4ff"},
{"type": "terminal", "key": " trm", "keyColor": "#9adba8"},
{"type": "wm", "key": " wm ", "keyColor": "#c9a0ff"},
{"type": "packages", "key": " pkg", "keyColor": "#e8c87a"},
"break",
{"type": "cpu", "key": " cpu", "keyColor": "#ff4da6"},
{ {
"type": "gpu", "type": "gpu",
"key": "󰍛 GPU ", "key": " gpu",
"keyColor": "magenta", "keyColor": "#c9a0ff",
"hideTypes": ["Integrated"] "hideTypes": ["Integrated"]
}, },
{ {
"type": "display", "type": "display",
"key": "󰹆 Écran ", "key": " dsp",
"keyColor": "magenta", "keyColor": "#a4b4ff",
"format": "{width}x{height} @ {refresh-rate}Hz" "format": "{width}x{height} @ {refresh-rate}Hz"
}, },
{"type": "memory", "key": "󰑭 Mémoire ", "keyColor": "magenta"}, {"type": "memory", "key": " mem", "keyColor": "#ff4da6"},
{ {
"type": "disk", "type": "disk",
"key": "󰋊 Disque ", "key": " dsk",
"keyColor": "magenta", "keyColor": "#e8c87a",
"folders": "/" "folders": "/"
}, },
{"type": "processes", "key": "󰙲 Processus", "keyColor": "magenta"}, {"type": "uptime", "key": " up ", "keyColor": "#716686"},
{"type": "uptime", "key": "󰅐 Uptime ", "keyColor": "magenta"},
"break", "break",
{ {
"type": "media", "type": "media",
"key": " Musique ", "key": " now",
"keyColor": "magenta", "keyColor": "#ff4da6",
"format": "{artist} — {title}" "format": "{artist} — {title}"
}, },
"break", "break",
{
"type": "custom",
"format": "───────────────────────────────────",
"outputColor": "#3d2454"
},
"colors" "colors"
] ]
} }

View File

@@ -18,38 +18,38 @@
navigate = true navigate = true
hyperlinks = true hyperlinks = true
# Lignes supprimées : fond rose sombre # Lignes supprimees : fond magenta sombre
minus-style = syntax "#3d1a2e" minus-style = syntax "#3a1230"
minus-emph-style = syntax "#5a1a38" minus-emph-style = syntax "#5a1848"
# Lignes ajoutées : fond cyan sombre # Lignes ajoutees : fond mitsuri sombre
plus-style = syntax "#0d2a35" plus-style = syntax "#1a3025"
plus-emph-style = syntax "#0d3a48" plus-emph-style = syntax "#1a4530"
# Numéros de ligne # Numeros de ligne
line-numbers-minus-style = "#ff79c6" line-numbers-minus-style = "#ff4da6"
line-numbers-plus-style = "#8be9fd" line-numbers-plus-style = "#9adba8"
line-numbers-zero-style = "#6c7086" line-numbers-zero-style = "#716686"
line-numbers-left-format = " {nm} │" line-numbers-left-format = " {nm} │"
line-numbers-right-format = " {np} │" line-numbers-right-format = " {np} │"
# En-tête de fichier # En-tete de fichier
file-style = "bold #e79cfe" file-style = "bold #c9a0ff"
file-decoration-style = "#3d2454 box" file-decoration-style = "#3d2454 box"
file-added-label = "[+]" file-added-label = "[+]"
file-removed-label = "[-]" file-removed-label = "[-]"
file-modified-label = "[~]" file-modified-label = "[~]"
file-renamed-label = "[»]" file-renamed-label = "[»]"
# En-tête de hunk # En-tete de hunk
hunk-header-style = "syntax #261537" hunk-header-style = "syntax #261537"
hunk-header-decoration-style = "#6c7086 box" hunk-header-decoration-style = "#716686 box"
hunk-header-file-style = "bold #e79cfe" hunk-header-file-style = "bold #c9a0ff"
hunk-header-line-number-style = "#7f849c" hunk-header-line-number-style = "#9a8fad"
# Commit # Commit
commit-decoration-style = "bold #ff79c6 box" commit-decoration-style = "bold #ff4da6 box"
commit-style = "bold #f8f8f2" commit-style = "bold #f0eaf8"
[merge] [merge]
conflictstyle = diff3 conflictstyle = diff3

182
INSTALL/configs/kitty.conf Normal file
View File

@@ -0,0 +1,182 @@
# ── violet-chaton v2 — kitty terminal ────────────────────────────────────────
# Font : Maple Mono NF — cursive italics + ligatures
# Palette : violet-chaton v2 (source : themes/palette.sh)
# ── Font ─────────────────────────────────────────────────────────────────────
font_family Maple Mono NF
bold_font Maple Mono NF Bold
italic_font Maple Mono NF Italic
bold_italic_font Maple Mono NF Bold Italic
font_size 13.0
# Ligatures et font features (cursive italics pour commentaires)
disable_ligatures never
font_features MapleMono-NF-Regular +cv01 +ss01 +ss02 +ss03 +ss05
font_features MapleMono-NF-Italic +cv01 +ss01 +ss02 +ss03 +ss05
font_features MapleMono-NF-Bold +cv01 +ss01 +ss02 +ss03 +ss05
font_features MapleMono-NF-BoldItalic +cv01 +ss01 +ss02 +ss03 +ss05
# ── Cursor + trail effect ────────────────────────────────────────────────────
cursor #ff4da6
cursor_text_color #1a0e27
cursor_shape beam
cursor_beam_thickness 1.8
cursor_blink_interval 0.4
# Undercurl style — vagues violettes pour les erreurs/warnings
undercurl_style thin-sparse
# Couleurs undercurl (utilisees par les apps qui supportent les colored underlines)
# Les terminaux modernes + neovim/bat utilisent ces couleurs automatiquement
# Trail — trainee lumineuse magenta derriere le curseur
cursor_trail 15
cursor_trail_decay 0.05 0.3
cursor_trail_start_threshold 0
# ── Scrollback ───────────────────────────────────────────────────────────────
scrollback_lines 10000
wheel_scroll_multiplier 3
# ── Mouse ────────────────────────────────────────────────────────────────────
mouse_hide_wait 2.0
url_color #a4b4ff
url_style curly
open_url_with default
detect_urls yes
# ── Bell ─────────────────────────────────────────────────────────────────────
enable_audio_bell no
visual_bell_duration 0.0
# ── Window ───────────────────────────────────────────────────────────────────
window_padding_width 8 12
background_opacity 0.92
dynamic_background_opacity yes
dim_opacity 0.75
# Blur (compositor dependent — works on KWin, Hyprland, COSMIC)
# background_blur 24
confirm_os_window_close 0
initial_window_width 120c
initial_window_height 35c
# ── Tab bar ──────────────────────────────────────────────────────────────────
tab_bar_edge top
tab_bar_style powerline
tab_powerline_style slanted
tab_bar_min_tabs 2
active_tab_foreground #1a0e27
active_tab_background #ff4da6
active_tab_font_style bold
inactive_tab_foreground #c4b8d4
inactive_tab_background #3d2454
inactive_tab_font_style normal
tab_bar_background #1a0e27
# ── Palette violet-chaton v2 ─────────────────────────────────────────────────
# Fond
foreground #f0eaf8
background #261537
selection_foreground #1a0e27
selection_background #c9a0ff
# Noir (fonds)
color0 #261537
color8 #5a3875
# Rouge (danger)
color1 #f25c7a
color9 #ff7a96
# Vert (mitsuri)
color2 #9adba8
color10 #b5e8c0
# Jaune (champagne)
color3 #e8c87a
color11 #f0d99a
# Bleu (lavande)
color4 #a4b4ff
color12 #bcc8ff
# Magenta
color5 #ff4da6
color13 #c9a0ff
# Cyan (lilac — pas de vrai cyan, on reste violet)
color6 #c9a0ff
color14 #dfc0ff
# Blanc (texte)
color7 #c4b8d4
color15 #f0eaf8
# ── Marks ────────────────────────────────────────────────────────────────────
mark1_foreground #1a0e27
mark1_background #ff4da6
mark2_foreground #1a0e27
mark2_background #c9a0ff
mark3_foreground #1a0e27
mark3_background #a4b4ff
# ── Keyboard shortcuts ──────────────────────────────────────────────────────
# Clipboard
map ctrl+v paste_from_clipboard
map ctrl+c copy_or_interrupt
# Tabs
map ctrl+shift+t new_tab_with_cwd
map ctrl+shift+l next_tab
map ctrl+shift+h previous_tab
map ctrl+shift+w close_tab
map ctrl+shift+, set_tab_title
# Splits / Windows — tiling dans le terminal
map ctrl+shift+enter new_window_with_cwd
map ctrl+shift+\ launch --cwd=current --location=vsplit
map ctrl+shift+- launch --cwd=current --location=hsplit
map ctrl+shift+z toggle_layout stack
map ctrl+shift+r start_resizing_window
# Navigation entre splits
map ctrl+shift+left neighboring_window left
map ctrl+shift+right neighboring_window right
map ctrl+shift+up neighboring_window up
map ctrl+shift+down neighboring_window down
# Swap splits
map ctrl+shift+f move_window_forward
map ctrl+shift+b move_window_backward
# Zoom
map ctrl+shift+equal change_font_size all +1.0
map ctrl+shift+minus change_font_size all -1.0
map ctrl+shift+0 change_font_size all 0
# Reload
map ctrl+shift+f5 load_config_file
# Quick layouts
map ctrl+shift+1 goto_layout tall
map ctrl+shift+2 goto_layout fat
map ctrl+shift+3 goto_layout grid
map ctrl+shift+4 goto_layout horizontal
map ctrl+shift+5 goto_layout vertical
# ── Layouts ──────────────────────────────────────────────────────────────────
enabled_layouts tall,fat,grid,horizontal,vertical,stack
# ── Splits styling ──────────────────────────────────────────────────────────
active_border_color #ff4da6
inactive_border_color #3d2454
bell_border_color #f25c7a
window_border_width 1.5pt
window_margin_width 2
single_window_margin_width 0
draw_minimal_borders yes
inactive_text_alpha 0.7

View File

@@ -0,0 +1,37 @@
// violet-chaton v2 — subtle glow shader for kitty
// Adds a soft bloom/glow around bright text characters
// Usage: kitty --override 'background_shader=~/.config/kitty/violet-chaton-glow.glsl'
void main() {
// Sample the original pixel
vec4 color = texture(image, texCoord);
// Only glow on non-background pixels (bright enough)
float brightness = dot(color.rgb, vec3(0.299, 0.587, 0.114));
if (brightness > 0.15) {
// Sample surrounding pixels for bloom
vec2 pixel = 1.0 / textureSize(image, 0);
vec4 glow = vec4(0.0);
float total = 0.0;
for (int x = -2; x <= 2; x++) {
for (int y = -2; y <= 2; y++) {
float weight = 1.0 / (1.0 + float(x*x + y*y));
glow += texture(image, texCoord + vec2(float(x), float(y)) * pixel) * weight;
total += weight;
}
}
glow /= total;
// Blend glow with original — subtle violet tint
float glowBrightness = dot(glow.rgb, vec3(0.299, 0.587, 0.114));
vec3 violetTint = vec3(0.85, 0.55, 1.0); // lilac-ish
vec3 glowColor = glow.rgb * violetTint;
// Mix: 85% original + 15% glow, only where text is
color.rgb = mix(color.rgb, color.rgb + glowColor * 0.12, smoothstep(0.1, 0.4, glowBrightness));
}
gl_FragColor = color;
}

View File

@@ -1,15 +1,15 @@
gui: gui:
theme: theme:
activeBorderColor: ['#ff79c6', 'bold'] # pink — fenêtre active activeBorderColor: ['#ff4da6', 'bold']
inactiveBorderColor: ['#6c7086'] # muted — fenêtre inactive inactiveBorderColor: ['#716686']
optionsTextColor: ['#e79cfe'] # purple optionsTextColor: ['#c9a0ff']
selectedLineBgColor: ['#3d2454'] # bg-high selectedLineBgColor: ['#5a3875']
selectedRangeBgColor: ['#3d2454'] selectedRangeBgColor: ['#5a3875']
cherryPickedCommitBgColor: ['#3d2454'] cherryPickedCommitBgColor: ['#3d2454']
cherryPickedCommitFgColor: ['#8be9fd'] # cyan cherryPickedCommitFgColor: ['#a4b4ff']
unstagedChangesColor: ['#f38ba8'] # danger unstagedChangesColor: ['#f25c7a']
defaultFgColor: ['#f8f8f2'] # text defaultFgColor: ['#f0eaf8']
searchingActiveBorderColor: ['#8be9fd', 'bold'] # cyan searchingActiveBorderColor: ['#a4b4ff', 'bold']
nerdFontsVersion: '3' nerdFontsVersion: '3'
border: rounded border: rounded
git: git:

View File

@@ -2,21 +2,53 @@
command_timeout = 1000 command_timeout = 1000
add_newline = true add_newline = true
# ── Format ──────────────────────────────────────────────────────────────────── # ── violet-chaton v2 — palette reference ─────────────────────────────────────
# Ligne 1 : infos → durée | mémoire | heure # magenta #ff4da6 accent primaire
# Ligne 2 : # lilac #c9a0ff accent secondaire
format = """ # mitsuri #9adba8 vert pastel (success, fresh)
$os $username$hostname$directory$git_branch$git_status$git_state$git_commit\ # lavande #a4b4ff bleu-violet (info, fonctions)
$python$nodejs$rust$golang$java$docker_context$package\ # champagne #e8c87a or chaud (warning, langages)
$fill\ # danger #f25c7a rouge vif
$cmd_duration$memory_usage$time # text #f0eaf8 texte principal
$status$character""" # subtext1 #c4b8d4 texte secondaire
# subtext0 #9a8fad labels
# muted #716686 desactive
# surface2 #5a3875 selection
# ── Système ─────────────────────────────────────────────────────────────────── # ── Format — 3 lignes ───────────────────────────────────────────────────────
# Ligne 1 : separateur
# Ligne 2 : os | dir | git | langages | ... fill ... | duree | batterie | heure
# Ligne 3 : prompt caractere
format = """
[┌──](bold #5a3875) $os$sudo$username$hostname\
$directory$git_branch$git_status$git_state$git_commit\
$python$nodejs$rust$golang$java$docker_context$package$env_var\
$fill\
$cmd_duration$battery$time
[└─](bold #5a3875) $status$character"""
# ── Palette Starship ─────────────────────────────────────────────────────────
palette = "violet-chaton"
[palettes.violet-chaton]
magenta = "#ff4da6"
lilac = "#c9a0ff"
mitsuri = "#9adba8"
lavande = "#a4b4ff"
champagne = "#e8c87a"
danger = "#f25c7a"
text = "#f0eaf8"
subtext1 = "#c4b8d4"
subtext0 = "#9a8fad"
muted = "#716686"
surface2 = "#5a3875"
crust = "#1a0e27"
# ── Systeme ──────────────────────────────────────────────────────────────────
[os] [os]
disabled = false disabled = false
style = "bold #ff79c6" style = "bold magenta"
format = "[$symbol]($style)" format = "[$symbol]($style)"
[os.symbols] [os.symbols]
@@ -43,38 +75,44 @@ Macos = " "
Windows = "󰍲 " Windows = "󰍲 "
Unknown = " " Unknown = " "
[sudo]
disabled = false
style = "bold danger"
symbol = "󰞀 "
format = "[$symbol]($style)"
[username] [username]
style_user = "#9399b2" style_user = "subtext0"
style_root = "bold #f38ba8" style_root = "bold danger"
format = "[$user]($style)" format = "[$user]($style)"
show_always = true show_always = false
[hostname] [hostname]
style = "#7f849c" style = "muted"
format = "[@$hostname ]($style)" format = "[@$hostname ]($style)"
ssh_only = false ssh_only = true
ssh_symbol = "󰣀 " ssh_symbol = "󰣀 "
# ── Navigation ─────────────────────────────────────────────────────────────── # ── Navigation ───────────────────────────────────────────────────────────────
[directory] [directory]
style = "bold #e79cfe" style = "bold lilac"
read_only = " 󰌾" read_only = " 󰌾"
read_only_style = "#f38ba8" read_only_style = "danger"
truncate_to_repo = false truncate_to_repo = false
truncation_length = 4 truncation_length = 4
truncation_symbol = "…/" truncation_symbol = "…/"
format = "[ $path]($style)[$read_only]($read_only_style) " format = "[ $path]($style)[$read_only]($read_only_style) "
# ── Git ────────────────────────────────────────────────────────────────────── # ── Git ──────────────────────────────────────────────────────────────────────
[git_branch] [git_branch]
symbol = " " symbol = " "
style = "bold #ff79c6" style = "bold magenta"
format = "[$symbol$branch]($style) " format = "[$symbol$branch]($style) "
[git_status] [git_status]
style = "#8be9fd" style = "mitsuri"
format = "([$all_status$ahead_behind]($style) )" format = "([$all_status$ahead_behind]($style) )"
ahead = "⇡$count" ahead = "⇡$count"
behind = "⇣$count" behind = "⇣$count"
@@ -88,85 +126,98 @@ deleted = "✘$count"
conflicted = "=$count" conflicted = "=$count"
[git_state] [git_state]
style = "#f9e2af" style = "champagne"
format = '\([$state( $progress_current/$progress_total)]($style)\) ' format = '\([$state( $progress_current/$progress_total)]($style)\) '
[git_commit] [git_commit]
style = "#6c7086" style = "muted"
format = '[\($hash$tag\)]($style) ' format = '[\($hash$tag\)]($style) '
tag_symbol = " 󰓼 " tag_symbol = " 󰓼 "
only_detached = true only_detached = true
# ── Langages ───────────────────────────────────────────────────────────────── # ── Langages ─────────────────────────────────────────────────────────────────
[python] [python]
symbol = " " symbol = " "
style = "#f9e2af" style = "champagne"
format = "[$symbol$version]($style) " format = "[$symbol$version]($style) "
[nodejs] [nodejs]
symbol = " " symbol = " "
style = "#a6e3a1" style = "mitsuri"
format = "[$symbol$version]($style) " format = "[$symbol$version]($style) "
[rust] [rust]
symbol = " " symbol = " "
style = "#ff79c6" style = "magenta"
format = "[$symbol$version]($style) " format = "[$symbol$version]($style) "
[golang] [golang]
symbol = " " symbol = " "
style = "#8be9fd" style = "lavande"
format = "[$symbol$version]($style) " format = "[$symbol$version]($style) "
[java] [java]
symbol = " " symbol = " "
style = "#f38ba8" style = "danger"
format = "[$symbol$version]($style) " format = "[$symbol$version]($style) "
[docker_context] [docker_context]
symbol = " " symbol = " "
style = "#8be9fd" style = "lavande"
format = "[$symbol$context]($style) " format = "[$symbol$context]($style) "
only_with_files = true only_with_files = true
[package] [package]
symbol = "󰏗 " symbol = "󰏗 "
style = "#e79cfe" style = "lilac"
format = "[$symbol$version]($style) " format = "[$symbol$version]($style) "
display_private = false display_private = false
# ── Droite (après $fill) ───────────────────────────────────────────────────── # ── Env var custom — brain_name ──────────────────────────────────────────────
[env_var.brain_name]
variable = "brain_name"
style = "italic muted"
symbol = "󰧑 "
format = "[$symbol$env_value]($style) "
# ── Droite (apres $fill) ────────────────────────────────────────────────────
[fill] [fill]
symbol = " " symbol = ""
style = "#3d2454"
[cmd_duration] [cmd_duration]
format = "[󱎫 $duration]($style) " format = "[󱎫 $duration]($style) "
style = "#7f849c" style = "subtext0"
min_time = 2000 min_time = 2000
[memory_usage] [battery]
disabled = false disabled = false
threshold = 0 format = "[$symbol$percentage]($style) "
symbol = "󰑭 "
style = "#9399b2" [[battery.display]]
format = "[$symbol$ram]($style) " threshold = 30
style = "bold danger"
[[battery.display]]
threshold = 70
style = "champagne"
[time] [time]
disabled = false disabled = false
style = "bold #6c7086" style = "bold muted"
format = "[ $time]($style)" format = "[ $time]($style)"
time_format = "%H:%M" time_format = "%H:%M"
# ── Ligne 2 ─────────────────────────────────────────────────────────────────── # ── Ligne 3 — le prompt ─────────────────────────────────────────────────────
[status] [status]
disabled = false disabled = false
style = "#ff79c6" style = "danger"
format = "[$symbol$status ]($style)" format = "[$symbol$status ]($style)"
symbol = "✘ " symbol = "✘ "
[character] [character]
success_symbol = "[](bold #8be9fd)" success_symbol = "[](bold mitsuri)"
error_symbol = "[](bold #ff79c6)" error_symbol = "[](bold magenta)"

View File

@@ -12,10 +12,35 @@ max_width = 600
max_height = 900 max_height = 900
[opener] [opener]
edit = [{ run = 'nano "$@"', block = true }] edit = [
{ run = '${EDITOR:-nano} "$@"', block = true },
]
open = [
{ run = 'xdg-open "$@"', orphan = true },
]
reveal = [
{ run = 'xdg-open "$(dirname "$1")"', orphan = true },
]
[open] [open]
rules = [ rules = [
{ mime = "text/*", use = "edit" }, { mime = "text/*", use = "edit" },
{ mime = "image/*", use = "open" }, { mime = "image/*", use = "open" },
{ mime = "video/*", use = "open" },
{ mime = "audio/*", use = "open" },
{ mime = "application/pdf", use = "open" },
{ mime = "application/json", use = "edit" },
{ mime = "*/xml", use = "edit" },
{ name = "*.md", use = "edit" },
{ name = "*.yml", use = "edit" },
{ name = "*.yaml", use = "edit" },
{ name = "*.toml", use = "edit" },
{ name = "*.conf", use = "edit" },
{ name = "*.sh", use = "edit" },
]
[plugin]
prepend_previewers = [
# Image preview via kitty protocol (native dans kitty)
{ mime = "image/*", run = "image" },
] ]

View File

@@ -17,19 +17,22 @@ zinit light zsh-users/zsh-completions
export PATH="/usr/local/bin:$HOME/.local/bin:/usr/bin:$HOME/.atuin/bin:$PATH" export PATH="/usr/local/bin:$HOME/.local/bin:/usr/bin:$HOME/.atuin/bin:$PATH"
# ── Historique ──────────────────────────────────────────────────────────────── # ── Historique ────────────────────────────────────────────────────────────────
HISTSIZE=10000 HISTSIZE=50000
HISTFILESIZE=20000 HISTFILESIZE=100000
HISTFILE=~/.zsh_history HISTFILE=~/.zsh_history
setopt HIST_IGNORE_DUPS setopt HIST_IGNORE_DUPS
setopt HIST_IGNORE_SPACE setopt HIST_IGNORE_SPACE
setopt HIST_FIND_NO_DUPS
setopt SHARE_HISTORY setopt SHARE_HISTORY
setopt APPEND_HISTORY setopt APPEND_HISTORY
setopt EXTENDED_HISTORY
# ── Options zsh ─────────────────────────────────────────────────────────────── # ── Options zsh ───────────────────────────────────────────────────────────────
setopt AUTO_CD # cd en tapant juste le nom du dossier setopt AUTO_CD # cd en tapant juste le nom du dossier
setopt CORRECT # correction de typos setopt CORRECT # correction de typos
setopt GLOB_DOTS # inclure fichiers cachés dans les globs setopt GLOB_DOTS # inclure fichiers caches dans les globs
setopt NO_BEEP # silence setopt NO_BEEP # silence
setopt INTERACTIVE_COMMENTS # commentaires en mode interactif
# ── Completion ──────────────────────────────────────────────────────────────── # ── Completion ────────────────────────────────────────────────────────────────
autoload -Uz compinit && compinit autoload -Uz compinit && compinit
@@ -37,44 +40,46 @@ zstyle ':completion:*' menu select
zstyle ':completion:*' list-colors "${(s.:.)LS_COLORS}" zstyle ':completion:*' list-colors "${(s.:.)LS_COLORS}"
zstyle ':completion:*' matcher-list 'm:{a-z}={A-Za-z}' zstyle ':completion:*' matcher-list 'm:{a-z}={A-Za-z}'
zstyle ':completion:*' group-name '' zstyle ':completion:*' group-name ''
zstyle ':completion:*:descriptions' format '%F{#e79cfe}── %d ──%f' zstyle ':completion:*:descriptions' format '%F{#c9a0ff}── %d ──%f'
# ── Couleurs grep ───────────────────────────────────────────────────────────── # ── Couleurs grep ─────────────────────────────────────────────────────────────
alias grep='grep --color=auto' alias grep='grep --color=auto'
alias fgrep='fgrep --color=auto' alias fgrep='fgrep --color=auto'
alias egrep='egrep --color=auto' alias egrep='egrep --color=auto'
# ── eza (remplace ls) ──────────────────────────────────────────────────────── # ── eza (remplace ls) ────────────────────────────────────────────────────────
alias ls='eza --icons --color=always --group-directories-first' alias ls='eza --icons --color=always --group-directories-first'
alias ll='eza -l --icons --git --group-directories-first' alias ll='eza -l --icons --git --group-directories-first'
alias lt='eza --tree --icons' alias la='eza -la --icons --git --group-directories-first'
alias lt='eza --tree --icons --level=3'
export LS_COLORS="$(bash ~/.local/share/violet-chaton/violet-chaton-ls-colors.sh)" export LS_COLORS="$(bash ~/.local/share/violet-chaton/violet-chaton-ls-colors.sh)"
# ── bat (remplace cat) ─────────────────────────────────────────────────────── # ── bat (remplace cat) ───────────────────────────────────────────────────────
alias bat='batcat' alias bat='batcat'
alias cat='batcat --paging=never' alias cat='batcat --paging=never'
export MANPAGER="sh -c 'col -bx | batcat -l man -p'" export MANPAGER="sh -c 'col -bx | batcat -l man -p'"
# ── fd (remplace find) ─────────────────────────────────────────────────────── # ── fd (remplace find) ───────────────────────────────────────────────────────
alias fd='fdfind' alias fd='fdfind'
# ── Nouveaux outils ─────────────────────────────────────────────────────────── # ── Outils modernes ──────────────────────────────────────────────────────────
alias lg='lazygit' # git TUI alias lg='lazygit'
alias rg='rg --color=always' # ripgrep avec couleurs alias rg='rg --color=always'
alias disk='ncdu' # analyse disque alias disk='dust' # analyse disque (remplace ncdu)
alias man='tldr' # man pages simplifiées alias tl='tldr' # man pages simplifiees (man reste intact)
alias pipes='pipes.sh' # animation pipes alias pipes='pipes.sh'
fuck() { eval "$(thefuck --alias 2>/dev/null)"; fuck "$@"; } # init paresseux alias top='btop'
fuck() { eval "$(thefuck --alias 2>/dev/null)"; fuck "$@"; }
# ── fzf ────────────────────────────────────────────────────────────────────── # ── fzf ──────────────────────────────────────────────────────────────────────
[ -f /usr/share/doc/fzf/examples/key-bindings.zsh ] && source /usr/share/doc/fzf/examples/key-bindings.zsh [ -f /usr/share/doc/fzf/examples/key-bindings.zsh ] && source /usr/share/doc/fzf/examples/key-bindings.zsh
[ -f /usr/share/doc/fzf/examples/completion.zsh ] && source /usr/share/doc/fzf/examples/completion.zsh [ -f /usr/share/doc/fzf/examples/completion.zsh ] && source /usr/share/doc/fzf/examples/completion.zsh
# Raccourcis fzf personnalisés # Raccourcis fzf
bindkey -r '^T' # libère Ctrl+T bindkey -r '^T'
bindkey -r '\ec' # libère Alt+C bindkey -r '\ec'
bindkey '^G' fzf-file-widget # Ctrl+G → chercher un fichier bindkey '^G' fzf-file-widget
bindkey '^F' fzf-cd-widget # Ctrl+F → chercher un dossier bindkey '^F' fzf-cd-widget
export FZF_DEFAULT_COMMAND='fdfind --type f --hidden --follow --exclude .git --exclude .cache --search-path $HOME' export FZF_DEFAULT_COMMAND='fdfind --type f --hidden --follow --exclude .git --exclude .cache --search-path $HOME'
export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND" export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"
export FZF_ALT_C_COMMAND='fdfind --type d --hidden --follow --exclude .git --exclude .cache --search-path $HOME' export FZF_ALT_C_COMMAND='fdfind --type d --hidden --follow --exclude .git --exclude .cache --search-path $HOME'
@@ -82,39 +87,188 @@ export FZF_DEFAULT_OPTS="
--height 40% --layout=reverse --border rounded --info=hidden --height 40% --layout=reverse --border rounded --info=hidden
--preview 'batcat --color=always --style=plain --line-range=:80 {}' --preview 'batcat --color=always --style=plain --line-range=:80 {}'
--preview-window 'right:50%:wrap' --preview-window 'right:50%:wrap'
--color=bg+:#3d2454,bg:#341c4a,spinner:#ff79c6,hl:#8be9fd --color=bg+:#5a3875,bg:#261537,spinner:#ff4da6,hl:#a4b4ff
--color=fg:#f8f8f2,header:#ff79c6,info:#e79cfe,pointer:#ff79c6 --color=fg:#f0eaf8,header:#ff4da6,info:#c9a0ff,pointer:#ff4da6
--color=marker:#a6e3a1,fg+:#f8f8f2,prompt:#e79cfe,hl+:#8be9fd" --color=marker:#9adba8,fg+:#f0eaf8,prompt:#c9a0ff,hl+:#a4b4ff"
# ── zoxide (remplace cd) ────────────────────────────────────────────────────── # ── zoxide (remplace cd) ────────────────────────────────────────────────────
eval "$(zoxide init zsh --cmd cd)" eval "$(zoxide init zsh --cmd cd)"
# ── Fastfetch ───────────────────────────────────────────────────────────────── # ── direnv (charge .envrc automatiquement) ───────────────────────────────────
alias fetch='fastfetch --config ~/.config/fastfetch/config.jsonc --raw <(chafa --size 44x22 --symbols vhalf --color-space rgb "$HOME/.config/fastfetch/violet-chaton-logo.png") --logo-width 52' command -v direnv &>/dev/null && eval "$(direnv hook zsh)"
fetch
# ── zsh-autosuggestions ─────────────────────────────────────────────────────── # ── fnm (Node.js version manager — lazy load) ───────────────────────────────
ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE="fg=#6c7086" if [ -d "$HOME/.local/share/fnm" ]; then
export PATH="$HOME/.local/share/fnm:$PATH"
eval "$(fnm env --use-on-cd --shell zsh)"
fi
# ── Fastfetch ────────────────────────────────────────────────────────────────
alias fetch='fastfetch --config ~/.config/fastfetch/config.jsonc --raw <(chafa --size 44x22 --symbols vhalf --color-space rgb "$HOME/.config/fastfetch/violet-chaton-logo.png") --logo-width 52'
[[ -z "$TMUX" && -z "$INSIDE_EMACS" && -z "$VSCODE_INJECTION" ]] && fetch
# ── zsh-autosuggestions ──────────────────────────────────────────────────────
ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE="fg=#716686"
ZSH_AUTOSUGGEST_STRATEGY=(history completion) ZSH_AUTOSUGGEST_STRATEGY=(history completion)
ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE=20 ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE=20
bindkey '^ ' autosuggest-accept # Ctrl+Space pour accepter la suggestion bindkey '^ ' autosuggest-accept
# ── zsh-syntax-highlighting (couleurs violet-chaton) ───────────────────────── # ── zsh-syntax-highlighting (couleurs violet-chaton v2) ──────────────────────
ZSH_HIGHLIGHT_STYLES[command]='fg=#8be9fd' ZSH_HIGHLIGHT_STYLES[command]='fg=#a4b4ff'
ZSH_HIGHLIGHT_STYLES[builtin]='fg=#ff79c6' ZSH_HIGHLIGHT_STYLES[builtin]='fg=#ff4da6'
ZSH_HIGHLIGHT_STYLES[alias]='fg=#e79cfe' ZSH_HIGHLIGHT_STYLES[alias]='fg=#c9a0ff'
ZSH_HIGHLIGHT_STYLES[function]='fg=#8be9fd' ZSH_HIGHLIGHT_STYLES[function]='fg=#a4b4ff'
ZSH_HIGHLIGHT_STYLES[string]='fg=#e79cfe' ZSH_HIGHLIGHT_STYLES[string]='fg=#9adba8'
ZSH_HIGHLIGHT_STYLES[path]='fg=#f8f8f2,underline' ZSH_HIGHLIGHT_STYLES[path]='fg=#f0eaf8,underline'
ZSH_HIGHLIGHT_STYLES[unknown-token]='fg=#f38ba8,bold' ZSH_HIGHLIGHT_STYLES[unknown-token]='fg=#f25c7a,bold,standout'
ZSH_HIGHLIGHT_STYLES[reserved-word]='fg=#ff79c6' ZSH_HIGHLIGHT_STYLES[reserved-word]='fg=#ff4da6'
ZSH_HIGHLIGHT_STYLES[comment]='fg=#6c7086,italic' ZSH_HIGHLIGHT_STYLES[single-hyphen-option]='fg=#e8c87a'
ZSH_HIGHLIGHT_STYLES[globbing]='fg=#f9e2af' ZSH_HIGHLIGHT_STYLES[double-hyphen-option]='fg=#e8c87a'
ZSH_HIGHLIGHT_STYLES[history-expansion]='fg=#f9e2af' ZSH_HIGHLIGHT_STYLES[back-quoted-argument]='fg=#c9a0ff'
ZSH_HIGHLIGHT_STYLES[dollar-quoted-argument]='fg=#9adba8'
ZSH_HIGHLIGHT_STYLES[assign]='fg=#f0eaf8'
ZSH_HIGHLIGHT_STYLES[redirection]='fg=#ff4da6,bold'
ZSH_HIGHLIGHT_STYLES[commandseparator]='fg=#ff4da6'
# ── atuin (remplace Ctrl+R) ─────────────────────────────────────────────────── # ── Vi-mode — cursor shape adaptatif ────────────────────────────────────────
bindkey -v
export KEYTIMEOUT=1
# Beam en insert, block en normal
zle-keymap-select() {
case $KEYMAP in
vicmd) echo -ne '\e[1 q' ;; # block clignotant
viins|main) echo -ne '\e[5 q' ;; # beam clignotant
esac
}
zle -N zle-keymap-select
# Reset beam au demarrage de chaque prompt
zle-line-init() { echo -ne '\e[5 q' }
zle -N zle-line-init
# Garder les keybindings essentiels en mode insert
bindkey '^A' beginning-of-line
bindkey '^E' end-of-line
bindkey '^K' kill-line
bindkey '^U' backward-kill-line
bindkey '^W' backward-kill-word
bindkey '^Y' yank
bindkey '^R' history-incremental-search-backward
bindkey '^P' up-line-or-history
bindkey '^N' down-line-or-history
bindkey '^?' backward-delete-char
bindkey '^H' backward-delete-char
ZSH_HIGHLIGHT_STYLES[comment]='fg=#716686,italic'
ZSH_HIGHLIGHT_STYLES[globbing]='fg=#e8c87a'
ZSH_HIGHLIGHT_STYLES[history-expansion]='fg=#e8c87a'
# ── fzf pimped — git log picker, process killer ─────────────────────────────
# Git log browser — Ctrl+L en mode normal
fzf-git-log() {
git log --oneline --color=always --decorate --graph 2>/dev/null |
fzf --ansi --no-sort --reverse --preview \
'git show --color=always $(echo {} | grep -oP "[a-f0-9]{7,}" | head -1)' \
--preview-window='right:60%:wrap' \
--bind='enter:execute(echo {} | grep -oP "[a-f0-9]{7,}" | head -1 | tr -d "\n" | xclip -selection clipboard)+abort'
}
alias glog='fzf-git-log'
# Process killer — fzf powered
fkill() {
local pid
pid=$(procs --color=always 2>/dev/null || ps aux) |
fzf --ansi --header="Select process to kill" \
--preview-window='hidden' |
awk '{print $1}'
[ -n "$pid" ] && kill -9 "$pid" && echo "Killed $pid"
}
# ── Shell functions — violet-chaton toolkit ──────────────────────────────────
# mkcd — creer un dossier et y aller
mkcd() { mkdir -p "$1" && cd "$1" }
# Project switcher — fzf dans ~/Dev
proj() {
local dir
dir=$(find ~/Dev -maxdepth 3 -name ".git" -type d 2>/dev/null | sed 's|/.git$||' |
fzf --preview 'eza -la --icons --color=always --group-directories-first {}' \
--preview-window='right:50%')
[ -n "$dir" ] && cd "$dir"
}
# Palette preview — affiche violet-chaton v2 dans le terminal
colors() {
echo ""
echo -e " \033[1mviolet-chaton v2\033[0m"
echo ""
echo -e " \033[38;2;255;77;166m████\033[0m magenta #ff4da6"
echo -e " \033[38;2;201;160;255m████\033[0m lilac #c9a0ff"
echo -e " \033[38;2;154;219;168m████\033[0m mitsuri #9adba8"
echo -e " \033[38;2;164;180;255m████\033[0m lavande #a4b4ff"
echo -e " \033[38;2;232;200;122m████\033[0m champagne #e8c87a"
echo ""
echo -e " \033[38;2;242;92;122m████\033[0m danger #f25c7a"
echo -e " \033[38;2;232;200;122m████\033[0m warning #e8c87a"
echo -e " \033[38;2;154;219;168m████\033[0m success #9adba8"
echo -e " \033[38;2;164;180;255m████\033[0m info #a4b4ff"
echo ""
echo -e " \033[38;2;240;234;248m████\033[0m text #f0eaf8"
echo -e " \033[38;2;196;184;212m████\033[0m subtext1 #c4b8d4"
echo -e " \033[38;2;154;143;173m████\033[0m subtext0 #9a8fad"
echo -e " \033[38;2;113;102;134m████\033[0m muted #716686"
echo ""
echo -e " Gradient: \033[38;2;255;77;166m██\033[38;2;226;118;212m██\033[38;2;201;160;255m██\033[38;2;182;168;255m██\033[38;2;164;180;255m██\033[38;2;159;200;212m██\033[38;2;154;219;168m██\033[38;2;130;232;160m██\033[0m"
echo ""
}
# Yazi — wrapper qui cd dans le dernier dossier visite
y() {
local tmp="$(mktemp -t "yazi-cwd.XXXXXX")"
yazi "$@" --cwd-file="$tmp"
if cwd="$(cat -- "$tmp")" && [ -n "$cwd" ] && [ "$cwd" != "$PWD" ]; then
cd "$cwd"
fi
rm -f "$tmp"
}
# Weather — meteo rapide
weather() { curl -s "wttr.in/${1:-Paris}?format=3" }
# Cheatsheet — raccourcis violet-chaton
hotkeys() {
echo ""
echo -e " \033[38;2;255;77;166m\033[1m── kitty ──\033[0m"
echo -e " \033[38;2;201;160;255mCtrl+Shift+\\\033[0m split vertical"
echo -e " \033[38;2;201;160;255mCtrl+Shift+-\033[0m split horizontal"
echo -e " \033[38;2;201;160;255mCtrl+Shift+Z\033[0m zoom (stack toggle)"
echo -e " \033[38;2;201;160;255mCtrl+Shift+←→↑↓\033[0m naviguer splits"
echo -e " \033[38;2;201;160;255mCtrl+Shift+1-5\033[0m layouts (tall/fat/grid/h/v)"
echo -e " \033[38;2;201;160;255mCtrl+Shift+T\033[0m nouvel onglet"
echo ""
echo -e " \033[38;2;255;77;166m\033[1m── zsh ──\033[0m"
echo -e " \033[38;2;154;219;168mEsc\033[0m vi normal mode (hjkl, w, b)"
echo -e " \033[38;2;154;219;168mi\033[0m retour insert"
echo -e " \033[38;2;154;219;168mCtrl+G\033[0m fzf fichier"
echo -e " \033[38;2;154;219;168mCtrl+F\033[0m fzf dossier"
echo -e " \033[38;2;154;219;168mCtrl+Space\033[0m accepter suggestion"
echo ""
echo -e " \033[38;2;255;77;166m\033[1m── commandes ──\033[0m"
echo -e " \033[38;2;164;180;255mproj\033[0m project switcher fzf"
echo -e " \033[38;2;164;180;255mglog\033[0m git log fzf"
echo -e " \033[38;2;164;180;255mfkill\033[0m process killer fzf"
echo -e " \033[38;2;164;180;255my\033[0m yazi (cd au dossier visite)"
echo -e " \033[38;2;164;180;255mcolors\033[0m palette violet-chaton v2"
echo -e " \033[38;2;164;180;255mweather [ville]\033[0m meteo rapide"
echo -e " \033[38;2;164;180;255mhotkeys\033[0m cette aide"
echo ""
}
# ── atuin (remplace Ctrl+R) ──────────────────────────────────────────────────
[[ -f ~/.atuin/bin/env ]] && source ~/.atuin/bin/env [[ -f ~/.atuin/bin/env ]] && source ~/.atuin/bin/env
command -v atuin &>/dev/null && eval "$(atuin init zsh --disable-up-arrow)" command -v atuin &>/dev/null && eval "$(atuin init zsh --disable-up-arrow)"
# ── starship ───────────────────────────────────────────────────────────────── # ── starship ─────────────────────────────────────────────────────────────────
command -v starship &>/dev/null && eval "$(starship init zsh)" command -v starship &>/dev/null && eval "$(starship init zsh)"

View File

@@ -27,18 +27,19 @@ PACKAGES=(
btop btop
# atuin → installé via son propre script (voir 02-packages-manual.sh) # atuin → installé via son propre script (voir 02-packages-manual.sh)
# starship → installé via son propre script (voir 02-packages-manual.sh) # starship → installé via son propre script (voir 02-packages-manual.sh)
# ── Waybar + launcher + dépendances ────────────────────────────────────── # ── AGS + deps (remplace waybar/wob/wofi) ─────────────────────────────────
waybar
wob
wofi
brightnessctl brightnessctl
playerctl playerctl
wireplumber wireplumber
python3-gi
gir1.2-gtk-3.0 gir1.2-gtk-3.0
gir1.2-gtklayershell-0.1 gir1.2-gtklayershell-0.1
gir1.2-gdkpixbuf-2.0 gir1.2-gdkpixbuf-2.0
gir1.2-pango-1.0 gir1.2-pango-1.0
libgtk-layer-shell-dev
libpulse-dev
libdbusmenu-gtk3-dev
# Rofi reste en backup launcher (AGS launcher = principal)
rofi
# ── Fun & utils ────────────────────────────────────────────────────────── # ── Fun & utils ──────────────────────────────────────────────────────────
cmatrix cmatrix
toilet toilet

View File

@@ -131,6 +131,135 @@ else
chmod +x "$BIN/pipes.sh" && ok "pipes.sh" || fail "pipes.sh" chmod +x "$BIN/pipes.sh" && ok "pipes.sh" || fail "pipes.sh"
fi fi
# dust (remplace ncdu/du)
if has_cmd dust; then
ok "dust (déjà installé)"
else
DUST_VER=$(github_latest_tag "bootandy/dust")
if [ -z "$DUST_VER" ]; then
fail "dust — version introuvable"
else
install_binary "dust" \
"https://github.com/bootandy/dust/releases/download/${DUST_VER}/dust-${DUST_VER}-x86_64-unknown-linux-musl.tar.gz" \
"tar:dust"
fi
fi
# procs (remplace ps)
if has_cmd procs; then
ok "procs (déjà installé)"
else
PROCS_VER=$(github_latest_tag "dalance/procs")
if [ -z "$PROCS_VER" ]; then
fail "procs — version introuvable"
else
install_binary "procs" \
"https://github.com/dalance/procs/releases/download/${PROCS_VER}/procs-${PROCS_VER}-x86_64-linux.zip" \
"zip:procs"
fi
fi
# tokei (stats code par langage) — v12 car v13+ n'a plus de binaires pre-compiles
if has_cmd tokei; then
ok "tokei (déjà installé)"
else
install_binary "tokei" \
"https://github.com/XAMPPRocky/tokei/releases/download/v12.1.2/tokei-x86_64-unknown-linux-musl.tar.gz" \
"tar:tokei"
fi
# sd (remplace sed simplifié)
if has_cmd sd; then
ok "sd (déjà installé)"
else
SD_VER=$(github_latest_tag "chmln/sd")
if [ -z "$SD_VER" ]; then
fail "sd — version introuvable"
else
install_binary "sd" \
"https://github.com/chmln/sd/releases/download/${SD_VER}/sd-${SD_VER}-x86_64-unknown-linux-musl.tar.gz" \
"tar:sd"
fi
fi
# hyperfine (benchmarks CLI)
if has_cmd hyperfine; then
ok "hyperfine (déjà installé)"
else
HF_VER=$(github_latest_tag "sharkdp/hyperfine")
if [ -z "$HF_VER" ]; then
fail "hyperfine — version introuvable"
else
install_binary "hyperfine" \
"https://github.com/sharkdp/hyperfine/releases/download/${HF_VER}/hyperfine-${HF_VER}-x86_64-unknown-linux-musl.tar.gz" \
"tar:hyperfine"
fi
fi
# gping (ping avec graphe)
if has_cmd gping; then
ok "gping (déjà installé)"
else
GPING_VER=$(github_latest_tag "orf/gping")
if [ -z "$GPING_VER" ]; then
fail "gping — version introuvable"
else
install_binary "gping" \
"https://github.com/orf/gping/releases/download/${GPING_VER}/gping-Linux-musl-x86_64.tar.gz" \
"tar:gping"
fi
fi
section "AGS (Aylur's GTK Shell — barre + OSD + launcher + notifs)"
if has_cmd ags; then
ok "ags (deja installe)"
else
step "Installation de AGS depuis source..."
tmp=$(mktemp -d)
AGS_VER=$(github_latest_tag "Aylur/ags")
if [ -z "$AGS_VER" ]; then
warn "ags — version introuvable — a installer manuellement"
else
if git clone --depth 1 --branch "$AGS_VER" https://github.com/Aylur/ags.git "$tmp/ags" &>/dev/null; then
if cd "$tmp/ags" && npm install &>/dev/null && npm run build &>/dev/null; then
cp "$tmp/ags/ags" "$BIN/ags" 2>/dev/null && chmod +x "$BIN/ags" 2>/dev/null
if [ -x "$BIN/ags" ]; then
ok "ags"
else
warn "ags — build OK mais binaire non trouve. Install manuelle recommandee :"
info " git clone https://github.com/Aylur/ags && cd ags && npm i && npm run build"
fi
else
warn "ags — build echoue. Install manuelle recommandee :"
info " git clone https://github.com/Aylur/ags && cd ags && npm i && npm run build"
fi
cd - &>/dev/null
else
warn "ags — clone echoue"
fi
fi
rm -rf "$tmp"
fi
section "kitty (terminal GPU-accelerated)"
if has_cmd kitty; then
ok "kitty (deja installe)"
else
step "Installation de kitty..."
if curl -L https://sw.kovidgoyal.net/kitty/installer.sh | sh /dev/stdin launch=n &>/dev/null; then
ln -sf "$HOME/.local/kitty.app/bin/kitty" "$HOME/.local/bin/kitty"
ln -sf "$HOME/.local/kitty.app/bin/kitten" "$HOME/.local/bin/kitten"
# Desktop file pour le launcher
cp "$HOME/.local/kitty.app/share/applications/kitty.desktop" \
"$HOME/.local/share/applications/" 2>/dev/null
sed -i "s|Icon=kitty|Icon=$HOME/.local/kitty.app/share/icons/hicolor/256x256/apps/kitty.png|g" \
"$HOME/.local/share/applications/kitty.desktop" 2>/dev/null
ok "kitty"
else
fail "kitty"
fi
fi
section "starship (prompt)" section "starship (prompt)"
if has_cmd starship; then if has_cmd starship; then
ok "starship (déjà installé)" ok "starship (déjà installé)"
@@ -188,7 +317,7 @@ else
fi fi
# ── Nerd Fonts ───────────────────────────────────────────────────────────────── # ── Nerd Fonts ─────────────────────────────────────────────────────────────────
section "Nerd Fonts (JetBrainsMono NL + 0xProto)" section "Nerd Fonts (Maple Mono NF + JetBrainsMono NL + 0xProto)"
FONTS_DIR="$HOME/.local/share/fonts/NerdFonts" FONTS_DIR="$HOME/.local/share/fonts/NerdFonts"
ensure_dir "$FONTS_DIR" ensure_dir "$FONTS_DIR"
@@ -213,6 +342,9 @@ install_font() {
rm -rf "$tmp" rm -rf "$tmp"
} }
install_font "Maple Mono NF" \
"https://github.com/subframe7536/maple-font/releases/latest/download/MapleMono-NF.zip" \
"MapleMono-NF-Regular.ttf"
install_font "JetBrainsMono NL" \ install_font "JetBrainsMono NL" \
"https://github.com/ryanoasis/nerd-fonts/releases/latest/download/JetBrainsMono.zip" \ "https://github.com/ryanoasis/nerd-fonts/releases/latest/download/JetBrainsMono.zip" \
"JetBrainsMonoNLNerdFont-Regular.ttf" "JetBrainsMonoNLNerdFont-Regular.ttf"

View File

@@ -51,6 +51,10 @@ fi
# ── Configs outils ───────────────────────────────────────────────────────────── # ── Configs outils ─────────────────────────────────────────────────────────────
section "Configs outils" section "Configs outils"
deploy_file "$CONFIGS/starship.toml" "$HOME/.config/starship.toml" deploy_file "$CONFIGS/starship.toml" "$HOME/.config/starship.toml"
deploy_file "$CONFIGS/kitty.conf" "$HOME/.config/kitty/kitty.conf"
if [ -f "$CONFIGS/kitty/violet-chaton-glow.glsl" ]; then
deploy_file "$CONFIGS/kitty/violet-chaton-glow.glsl" "$HOME/.config/kitty/violet-chaton-glow.glsl"
fi
deploy_file "$CONFIGS/bat.conf" "$HOME/.config/bat/config" deploy_file "$CONFIGS/bat.conf" "$HOME/.config/bat/config"
deploy_file "$CONFIGS/btop.conf" "$HOME/.config/btop/btop.conf" deploy_file "$CONFIGS/btop.conf" "$HOME/.config/btop/btop.conf"
deploy_file "$CONFIGS/fastfetch.jsonc" "$HOME/.config/fastfetch/config.jsonc" deploy_file "$CONFIGS/fastfetch.jsonc" "$HOME/.config/fastfetch/config.jsonc"
@@ -128,14 +132,20 @@ fi
# ── GTK3 / GTK4 — thème violet-chaton ───────────────────────────────────── # ── GTK3 / GTK4 — thème violet-chaton ─────────────────────────────────────
section "GTK — thème violet-chaton" section "GTK — thème violet-chaton"
step "Thème GTK3 (adw-gtk3-dark + couleurs violet-chaton)..." step "Thème GTK3 dark (adw-gtk3-dark + couleurs violet-chaton)..."
ensure_dir "$HOME/.config/gtk-3.0" ensure_dir "$HOME/.config/gtk-3.0"
deploy_file "$THEMES/violet-chaton-gtk.css" "$HOME/.config/gtk-3.0/gtk.css" deploy_file "$THEMES/violet-chaton-gtk.css" "$HOME/.config/gtk-3.0/gtk.css"
step "Thème GTK4 / libadwaita (couleurs violet-chaton)..." step "Thème GTK3 light..."
deploy_file "$THEMES/violet-chaton-gtk-light.css" "$HOME/.config/gtk-3.0/gtk-light.css"
step "Thème GTK4 / libadwaita dark..."
ensure_dir "$HOME/.config/gtk-4.0" ensure_dir "$HOME/.config/gtk-4.0"
deploy_file "$THEMES/violet-chaton-gtk.css" "$HOME/.config/gtk-4.0/gtk.css" deploy_file "$THEMES/violet-chaton-gtk.css" "$HOME/.config/gtk-4.0/gtk.css"
step "Thème GTK4 / libadwaita light..."
deploy_file "$THEMES/violet-chaton-gtk-light.css" "$HOME/.config/gtk-4.0/gtk-light.css"
step "Activation adw-gtk3-dark + dark mode (gsettings)..." step "Activation adw-gtk3-dark + dark mode (gsettings)..."
if has_cmd gsettings; then if has_cmd gsettings; then
gsettings set org.gnome.desktop.interface gtk-theme 'adw-gtk3-dark' 2>/dev/null && \ gsettings set org.gnome.desktop.interface gtk-theme 'adw-gtk3-dark' 2>/dev/null && \
@@ -246,105 +256,59 @@ PYEOF
fi fi
fi fi
# ── Waybar ───────────────────────────────────────────────────────────────────── # ── AGS (remplace waybar + wob + wofi) ─────────────────────────────────────────
section "Waybar — island floating 3 pills" section "AGS — violet-chaton shell"
deploy_file "$CONFIGS/waybar/config" "$HOME/.config/waybar/config" ensure_dir "$HOME/.config/ags/css"
deploy_file "$THEMES/violet-chaton-waybar.css" "$HOME/.config/waybar/style.css" ensure_dir "$HOME/.config/ags/widgets"
deploy_file "$CONFIGS/waybar/cava-waybar.cfg" "$HOME/.config/waybar/cava-waybar.cfg" deploy_file "$CONFIGS/ags/config.js" "$HOME/.config/ags/config.js"
deploy_file "$CONFIGS/ags/css/style.css" "$HOME/.config/ags/css/style.css"
deploy_file "$CONFIGS/ags/widgets/Bar.js" "$HOME/.config/ags/widgets/Bar.js"
deploy_file "$CONFIGS/ags/widgets/OSD.js" "$HOME/.config/ags/widgets/OSD.js"
deploy_file "$CONFIGS/ags/widgets/Launcher.js" "$HOME/.config/ags/widgets/Launcher.js"
deploy_file "$CONFIGS/ags/widgets/Notifications.js" "$HOME/.config/ags/widgets/Notifications.js"
step "Scripts waybar..." # ── Autostart — AGS ────────────────────────────────────────────────────────────
ensure_dir "$HOME/.config/waybar/scripts" section "Autostart — AGS"
for script in "$CONFIGS/waybar/scripts/"*.sh; do
dst="$HOME/.config/waybar/scripts/$(basename "$script")"
cp "$script" "$dst" && chmod +x "$dst"
done
for script in "$CONFIGS/waybar/scripts/"*.py; do
dst="$HOME/.config/waybar/scripts/$(basename "$script")"
cp "$script" "$dst" && chmod +x "$dst"
done
ok "Scripts waybar"
# ── Autostart ───────────────────────────────────────────────────────────────────
section "Autostart — waybar + wob"
ensure_dir "$HOME/.config/autostart" ensure_dir "$HOME/.config/autostart"
deploy_file "$CONFIGS/autostart/waybar.desktop" "$HOME/.config/autostart/waybar.desktop"
deploy_file "$CONFIGS/autostart/wob.desktop" "$HOME/.config/autostart/wob.desktop" cat > /tmp/ags-vc.desktop << 'DESKTOP'
[Desktop Entry]
Type=Application
Name=AGS violet-chaton
Exec=ags
X-GNOME-Autostart-enabled=true
DESKTOP
deploy_file "/tmp/ags-vc.desktop" "$HOME/.config/autostart/ags.desktop"
rm -f /tmp/ags-vc.desktop
# Cleanup ancien waybar/wob autostart si present
[ -f "$HOME/.config/autostart/waybar.desktop" ] && rm -f "$HOME/.config/autostart/waybar.desktop" && ok "waybar autostart retire"
[ -f "$HOME/.config/autostart/wob.desktop" ] && rm -f "$HOME/.config/autostart/wob.desktop" && ok "wob autostart retire"
# ── Règle sudoers — profil énergie ────────────────────────────────────────────── # ── Règle sudoers — profil énergie ──────────────────────────────────────────────
section "Sudoers — profil énergie ACPI" section "Sudoers — profil énergie ACPI"
SUDOERS_FILE="/etc/sudoers.d/waybar-power-profile" SUDOERS_FILE="/etc/sudoers.d/vc-power-profile"
SUDOERS_RULE="$USER ALL=(ALL) NOPASSWD: /usr/bin/tee /sys/firmware/acpi/platform_profile" SUDOERS_RULE="$USER ALL=(ALL) NOPASSWD: /usr/bin/tee /sys/firmware/acpi/platform_profile"
if [ -f "$SUDOERS_FILE" ]; then if [ -f "$SUDOERS_FILE" ] || [ -f "/etc/sudoers.d/waybar-power-profile" ]; then
ok "Règle sudoers déjà présente" ok "Règle sudoers déjà présente"
else else
step "Création de la règle sudoers (mot de passe sudo requis)..." step "Création de la règle sudoers (mot de passe sudo requis)..."
echo "$SUDOERS_RULE" > /tmp/waybar-pp-sudoers echo "$SUDOERS_RULE" > /tmp/vc-pp-sudoers
if sudo cp /tmp/waybar-pp-sudoers "$SUDOERS_FILE" && sudo chmod 440 "$SUDOERS_FILE"; then if sudo cp /tmp/vc-pp-sudoers "$SUDOERS_FILE" && sudo chmod 440 "$SUDOERS_FILE"; then
rm -f /tmp/waybar-pp-sudoers rm -f /tmp/vc-pp-sudoers
ok "Règle sudoers créée" ok "Règle sudoers créée"
else else
rm -f /tmp/waybar-pp-sudoers rm -f /tmp/vc-pp-sudoers
warn "Échec sudoers — changement de profil énergie nécessitera sudo" warn "Échec sudoers — changement de profil énergie nécessitera sudo"
fi fi
fi fi
# ── Règle udev — permissions platform_profile ──────────────────────────────── # ── Rofi — backup launcher (AGS launcher = principal) ──────────────────────────
section "udev — platform_profile accessible au groupe video" section "Rofi — thème violet-chaton (backup launcher)"
UDEV_FILE="/etc/udev/rules.d/90-platform-profile.rules"
if [ -f "$UDEV_FILE" ]; then
ok "Règle udev déjà présente"
else
step "Création de la règle udev (mot de passe sudo requis)..."
echo 'ACTION=="add|change", KERNEL=="platform_profile", SUBSYSTEM=="acpi", RUN+="/bin/chmod g+w /sys/firmware/acpi/platform_profile", RUN+="/bin/chgrp video /sys/firmware/acpi/platform_profile"' \
> /tmp/90-platform-profile.rules
if sudo cp /tmp/90-platform-profile.rules "$UDEV_FILE" && sudo chmod 644 "$UDEV_FILE"; then
rm -f /tmp/90-platform-profile.rules
sudo chmod g+w /sys/firmware/acpi/platform_profile 2>/dev/null
sudo chgrp video /sys/firmware/acpi/platform_profile 2>/dev/null
ok "Règle udev créée"
else
rm -f /tmp/90-platform-profile.rules
warn "Échec udev — redémarrage requis pour les permissions platform_profile"
fi
fi
# ── Wofi — launcher + power menu ────────────────────────────────────────────────
section "Wofi — launcher violet-chaton"
ensure_dir "$HOME/.config/wofi"
deploy_file "$CONFIGS/wofi/config" "$HOME/.config/wofi/config"
deploy_file "$THEMES/violet-chaton-wofi.css" "$HOME/.config/wofi/style.css"
deploy_file "$THEMES/violet-chaton-wofi-power.css" "$HOME/.config/wofi/power-style.css"
# ── Rofi ────────────────────────────────────────────────────────────────────────
section "Rofi — thème violet-chaton"
ensure_dir "$HOME/.config/rofi" ensure_dir "$HOME/.config/rofi"
deploy_file "$CONFIGS/rofi/config.rasi" "$HOME/.config/rofi/config.rasi" deploy_file "$CONFIGS/rofi/config.rasi" "$HOME/.config/rofi/config.rasi"
deploy_file "$THEMES/violet-chaton-rofi.rasi" "$HOME/.config/rofi/violet-chaton.rasi" deploy_file "$THEMES/violet-chaton-rofi.rasi" "$HOME/.config/rofi/violet-chaton.rasi"
# ── wob ─────────────────────────────────────────────────────────────────────────
section "wob — overlay volume/luminosité"
deploy_file "$CONFIGS/wob/wob.ini" "$HOME/.config/wob.ini"
# ── Désactiver cosmic-osd (remplacé par wob) ─────────────────────────────────
section "cosmic-osd — désactivation (wob le remplace)"
if [ -f /usr/bin/cosmic-osd.real ]; then
ok "cosmic-osd déjà désactivé via dpkg-divert"
elif [ -f /usr/bin/cosmic-osd ]; then
step "Divert de cosmic-osd (mot de passe sudo requis)..."
if sudo dpkg-divert --add --rename --divert /usr/bin/cosmic-osd.real /usr/bin/cosmic-osd; then
printf '#!/usr/bin/env bash\nexec sleep infinity\n' > /tmp/cosmic-osd-fake
chmod +x /tmp/cosmic-osd-fake
sudo cp /tmp/cosmic-osd-fake /usr/bin/cosmic-osd
rm -f /tmp/cosmic-osd-fake
pkill -x cosmic-osd 2>/dev/null
ok "cosmic-osd désactivé — wob gère les overlays"
else
warn "dpkg-divert échoué — cosmic-osd reste actif"
fi
else
warn "cosmic-osd introuvable — rien à faire"
fi
# ── Logo fastfetch ───────────────────────────────────────────────────────────── # ── Logo fastfetch ─────────────────────────────────────────────────────────────
section "Logo fastfetch" section "Logo fastfetch"
if [ -f "$SCRIPT_DIR/assets/violet-chaton-logo.png" ]; then if [ -f "$SCRIPT_DIR/assets/violet-chaton-logo.png" ]; then

View File

@@ -1,16 +1,23 @@
#!/bin/bash #!/bin/bash
# ── violet-chaton : fonctions partagées ─────────────────────────────────────── # ── violet-chaton : fonctions partagées ───────────────────────────────────────
PINK='\033[38;2;255;121;198m' # ── Palette violet-chaton v2 (source de verite : themes/palette.sh) ──────────
PURPLE='\033[38;2;231;156;254m' _LIB_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CYAN='\033[38;2;139;233;253m' _PALETTE="$_LIB_DIR/../themes/palette.sh"
GREEN='\033[38;2;166;227;161m' if [ -f "$_PALETTE" ]; then
YELLOW='\033[38;2;249;226;175m' source "$_PALETTE"
RED='\033[38;2;243;139;168m' fi
MUTED='\033[38;2;108;112;134m'
TEXT='\033[38;2;248;248;242m' PINK="${VC_ANSI_MAGENTA:-\033[38;2;255;77;166m}"
BOLD='\033[1m' PURPLE="${VC_ANSI_LILAC:-\033[38;2;201;160;255m}"
RESET='\033[0m' CYAN="${VC_ANSI_LAVANDE:-\033[38;2;164;180;255m}"
GREEN="${VC_ANSI_MITSURI:-\033[38;2;154;219;168m}"
YELLOW="${VC_ANSI_CHAMPAGNE:-\033[38;2;232;200;122m}"
RED="${VC_ANSI_DANGER:-\033[38;2;242;92;122m}"
MUTED="${VC_ANSI_MUTED:-\033[38;2;113;102;134m}"
TEXT="${VC_ANSI_TEXT:-\033[38;2;240;234;248m}"
BOLD="${VC_ANSI_BOLD:-\033[1m}"
RESET="${VC_ANSI_RESET:-\033[0m}"
# ── Log ──────────────────────────────────────────────────────────────────────── # ── Log ────────────────────────────────────────────────────────────────────────
# INSTALL_LOG peut être pré-exporté par install.sh pour que tous les sous-scripts # INSTALL_LOG peut être pré-exporté par install.sh pour que tous les sous-scripts

View File

@@ -1,40 +1,40 @@
{ {
0: ( 0: (
name: "violet-chaton", name: "violet-chaton",
foreground: "#F8F8F2", foreground: "#F0EAF8",
background: "#261537", background: "#261537",
cursor: "#FF79C6", cursor: "#FF4DA6",
bright_foreground: "#F8F8F2", bright_foreground: "#F0EAF8",
dim_foreground: "#6C7086", dim_foreground: "#716686",
normal: ( normal: (
black: "#261537", black: "#261537",
red: "#F38BA8", red: "#F25C7A",
green: "#A6E3A1", green: "#9ADBA8",
yellow: "#F9E2AF", yellow: "#E8C87A",
blue: "#3D2454", blue: "#A4B4FF",
magenta: "#FF79C6", magenta: "#FF4DA6",
cyan: "#8BE9FD", cyan: "#C9A0FF",
white: "#F8F8F2", white: "#C4B8D4",
), ),
bright: ( bright: (
black: "#6C7086", black: "#5A3875",
red: "#FF79C6", red: "#FF7A96",
green: "#8BE9FD", green: "#B5E8C0",
yellow: "#E79CFE", yellow: "#F0D99A",
blue: "#E79CFE", blue: "#BCC8FF",
magenta: "#E79CFE", magenta: "#C9A0FF",
cyan: "#8BE9FD", cyan: "#DFC0FF",
white: "#F8F8F2", white: "#F0EAF8",
), ),
dim: ( dim: (
black: "#261537", black: "#1A0E27",
red: "#F38BA8", red: "#C93A5A",
green: "#A6E3A1", green: "#6EBE80",
yellow: "#F9E2AF", yellow: "#B89840",
blue: "#3D2454", blue: "#7A8ACC",
magenta: "#FF79C6", magenta: "#D4348A",
cyan: "#8BE9FD", cyan: "#8A5CB8",
white: "#6C7086", white: "#716686",
), ),
), ),
} }

View File

@@ -1,40 +1,40 @@
{ {
0: ( 0: (
name: "violet-chaton", name: "violet-chaton-light",
foreground: "#F8F8F2", foreground: "#261537",
background: "#261537", background: "#F3EDF8",
cursor: "#FF79C6", cursor: "#D4348A",
bright_foreground: "#F8F8F2", bright_foreground: "#261537",
dim_foreground: "#6C7086", dim_foreground: "#8A7BA0",
normal: ( normal: (
black: "#261537", black: "#F3EDF8",
red: "#F38BA8", red: "#C93A5A",
green: "#A6E3A1", green: "#3D9E68",
yellow: "#F9E2AF", yellow: "#B89840",
blue: "#3D2454", blue: "#5A6AD0",
magenta: "#FF79C6", magenta: "#D4348A",
cyan: "#8BE9FD", cyan: "#8A5CB8",
white: "#F8F8F2", white: "#3D2454",
), ),
bright: ( bright: (
black: "#6C7086", black: "#C4B8D4",
red: "#FF79C6", red: "#E04A6A",
green: "#8BE9FD", green: "#4DAE78",
yellow: "#E79CFE", yellow: "#C8A850",
blue: "#E79CFE", blue: "#6A7AE0",
magenta: "#E79CFE", magenta: "#8A5CB8",
cyan: "#8BE9FD", cyan: "#A070D0",
white: "#F8F8F2", white: "#261537",
), ),
dim: ( dim: (
black: "#261537", black: "#EBE4F2",
red: "#F38BA8", red: "#A02840",
green: "#A6E3A1", green: "#2D7E50",
yellow: "#F9E2AF", yellow: "#987830",
blue: "#3D2454", blue: "#4A5AB0",
magenta: "#FF79C6", magenta: "#B42870",
cyan: "#8BE9FD", cyan: "#704898",
white: "#6C7086", white: "#5A3875",
), ),
), ),
} }

View File

@@ -1 +1 @@
"JetBrains Mono NL" "Maple Mono NF"

View File

@@ -1,74 +1,74 @@
( (
base: ( base: (
red: 0.90588236, red: 0.788,
green: 0.6117647, green: 0.627,
blue: 0.99607843, blue: 1.0,
alpha: 1.0, alpha: 1.0,
), ),
hover: ( hover: (
red: 0.8103273, red: 0.708,
green: 0.558776, green: 0.564,
blue: 0.90052974, blue: 0.900,
alpha: 1.0, alpha: 1.0,
), ),
pressed: ( pressed: (
red: 0.51201665, red: 0.469,
green: 0.32542938, green: 0.355,
blue: 0.59074855, blue: 0.608,
alpha: 1.0, alpha: 1.0,
), ),
selected: ( selected: (
red: 0.8103273, red: 0.708,
green: 0.558776, green: 0.564,
blue: 0.90052974, blue: 0.900,
alpha: 1.0, alpha: 1.0,
), ),
selected_text: ( selected_text: (
red: 0.90588236, red: 0.788,
green: 0.6117647, green: 0.627,
blue: 0.99607843, blue: 1.0,
alpha: 1.0, alpha: 1.0,
), ),
focus: ( focus: (
red: 0.90588236, red: 0.788,
green: 0.6117647, green: 0.627,
blue: 0.99607843, blue: 1.0,
alpha: 1.0, alpha: 1.0,
), ),
divider: ( divider: (
red: 0.0, red: 0.102,
green: 0.0, green: 0.055,
blue: 0.000000000000000000000000000000000000000000055, blue: 0.153,
alpha: 1.0, alpha: 1.0,
), ),
on: ( on: (
red: 0.0, red: 0.102,
green: 0.0, green: 0.055,
blue: 0.000000000000000000000000000000000000000000055, blue: 0.153,
alpha: 1.0, alpha: 1.0,
), ),
disabled: ( disabled: (
red: 0.90588236, red: 0.788,
green: 0.6117647, green: 0.627,
blue: 0.99607843, blue: 1.0,
alpha: 1.0, alpha: 0.5,
), ),
on_disabled: ( on_disabled: (
red: 0.45294118, red: 0.445,
green: 0.30588236, green: 0.341,
blue: 0.49803922, blue: 0.577,
alpha: 1.0, alpha: 1.0,
), ),
border: ( border: (
red: 0.90588236, red: 0.788,
green: 0.6117647, green: 0.627,
blue: 0.99607843, blue: 1.0,
alpha: 1.0, alpha: 1.0,
), ),
disabled_border: ( disabled_border: (
red: 0.90588236, red: 0.788,
green: 0.6117647, green: 0.627,
blue: 0.99607843, blue: 1.0,
alpha: 0.5, alpha: 0.5,
), ),
) )

View File

@@ -1,100 +1,100 @@
( (
base: ( base: (
red: 0.20392156, red: 0.149,
green: 0.109803915, green: 0.082,
blue: 0.2901961, blue: 0.216,
alpha: 1.0, alpha: 1.0,
), ),
component: ( component: (
base: ( base: (
red: 0.28618598, red: 0.239,
green: 0.19189146, green: 0.141,
blue: 0.3797182, blue: 0.329,
alpha: 1.0, alpha: 1.0,
), ),
hover: ( hover: (
red: 0.35756737, red: 0.286,
green: 0.27269349, green: 0.192,
blue: 0.44174638, blue: 0.380,
alpha: 1.0, alpha: 1.0,
), ),
pressed: ( pressed: (
red: 0.4289488, red: 0.353,
green: 0.35349554, green: 0.220,
blue: 0.5037746, blue: 0.459,
alpha: 1.0, alpha: 1.0,
), ),
selected: ( selected: (
red: 0.35756737, red: 0.286,
green: 0.27269349, green: 0.192,
blue: 0.44174638, blue: 0.380,
alpha: 1.0, alpha: 1.0,
), ),
selected_text: ( selected_text: (
red: 0.90588236, red: 0.788,
green: 0.6117647, green: 0.627,
blue: 0.99607843, blue: 1.0,
alpha: 1.0, alpha: 1.0,
), ),
focus: ( focus: (
red: 0.90588236, red: 0.788,
green: 0.6117647, green: 0.627,
blue: 0.99607843, blue: 1.0,
alpha: 1.0, alpha: 1.0,
), ),
divider: ( divider: (
red: 0.8318802, red: 0.769,
green: 0.8318715, green: 0.722,
blue: 0.8090188, blue: 0.831,
alpha: 0.2, alpha: 0.2,
), ),
on: ( on: (
red: 0.8318802, red: 0.941,
green: 0.8318715, green: 0.918,
blue: 0.8090188, blue: 0.973,
alpha: 1.0, alpha: 1.0,
), ),
disabled: ( disabled: (
red: 0.28618598, red: 0.239,
green: 0.19189146, green: 0.141,
blue: 0.3797182, blue: 0.329,
alpha: 0.5, alpha: 0.5,
), ),
on_disabled: ( on_disabled: (
red: 0.8318802, red: 0.941,
green: 0.8318715, green: 0.918,
blue: 0.8090188, blue: 0.973,
alpha: 0.65, alpha: 0.65,
), ),
border: ( border: (
red: 0.7874787, red: 0.353,
green: 0.6994349, green: 0.220,
blue: 0.8914889, blue: 0.459,
alpha: 1.0, alpha: 1.0,
), ),
disabled_border: ( disabled_border: (
red: 0.7874787, red: 0.353,
green: 0.6994349, green: 0.220,
blue: 0.8914889, blue: 0.459,
alpha: 0.5, alpha: 0.5,
), ),
), ),
divider: ( divider: (
red: 0.36091125, red: 0.204,
green: 0.28561735, green: 0.110,
blue: 0.42521048, blue: 0.290,
alpha: 1.0, alpha: 1.0,
), ),
on: ( on: (
red: 0.9888701, red: 0.941,
green: 0.98887116, green: 0.918,
blue: 0.9652681, blue: 0.973,
alpha: 1.0, alpha: 1.0,
), ),
small_widget: ( small_widget: (
red: 0.21216959, red: 0.443,
green: 0.20068932, green: 0.400,
blue: 0.22159976, blue: 0.525,
alpha: 0.25, alpha: 0.25,
), ),
) )

View File

@@ -1,74 +1,74 @@
( (
base: ( base: (
red: 0.9529412, red: 0.949,
green: 0.54509807, green: 0.361,
blue: 0.65882355, blue: 0.478,
alpha: 1.0, alpha: 1.0,
), ),
hover: ( hover: (
red: 0.84797436, red: 0.854,
green: 0.5054427, green: 0.325,
blue: 0.6307258, blue: 0.430,
alpha: 1.0, alpha: 1.0,
), ),
pressed: ( pressed: (
red: 0.53554606, red: 0.526,
green: 0.29209605, green: 0.208,
blue: 0.42212114, blue: 0.347,
alpha: 1.0, alpha: 1.0,
), ),
selected: ( selected: (
red: 0.84797436, red: 0.854,
green: 0.5054427, green: 0.325,
blue: 0.6307258, blue: 0.430,
alpha: 1.0, alpha: 1.0,
), ),
selected_text: ( selected_text: (
red: 0.90588236, red: 0.949,
green: 0.6117647, green: 0.361,
blue: 0.99607843, blue: 0.478,
alpha: 1.0, alpha: 1.0,
), ),
focus: ( focus: (
red: 0.90588236, red: 0.949,
green: 0.6117647, green: 0.361,
blue: 0.99607843, blue: 0.478,
alpha: 1.0, alpha: 1.0,
), ),
divider: ( divider: (
red: 0.0, red: 0.102,
green: 0.0, green: 0.055,
blue: 0.000000000000000000000000000000000000000000055, blue: 0.153,
alpha: 1.0, alpha: 1.0,
), ),
on: ( on: (
red: 0.0, red: 0.102,
green: 0.0, green: 0.055,
blue: 0.000000000000000000000000000000000000000000055, blue: 0.153,
alpha: 1.0, alpha: 1.0,
), ),
disabled: ( disabled: (
red: 0.9529412, red: 0.949,
green: 0.54509807, green: 0.361,
blue: 0.65882355, blue: 0.478,
alpha: 1.0, alpha: 0.5,
), ),
on_disabled: ( on_disabled: (
red: 0.4764706, red: 0.526,
green: 0.27254903, green: 0.208,
blue: 0.32941177, blue: 0.316,
alpha: 1.0, alpha: 1.0,
), ),
border: ( border: (
red: 0.9529412, red: 0.949,
green: 0.54509807, green: 0.361,
blue: 0.65882355, blue: 0.478,
alpha: 1.0, alpha: 1.0,
), ),
disabled_border: ( disabled_border: (
red: 0.9529412, red: 0.949,
green: 0.54509807, green: 0.361,
blue: 0.65882355, blue: 0.478,
alpha: 0.5, alpha: 0.5,
), ),
) )

View File

@@ -1 +1 @@
"Violet-chaton" "Violet-Chaton Dark"

View File

@@ -1,100 +1,100 @@
( (
base: ( base: (
red: 0.21960787, red: 0.204,
green: 0.13725492, green: 0.110,
blue: 0.29411766, blue: 0.290,
alpha: 1.0, alpha: 1.0,
), ),
component: ( component: (
base: ( base: (
red: 0.28282174, red: 0.239,
green: 0.19933021, green: 0.141,
blue: 0.36183798, blue: 0.329,
alpha: 1.0, alpha: 1.0,
), ),
hover: ( hover: (
red: 0.35453954, red: 0.286,
green: 0.27938837, green: 0.192,
blue: 0.42565417, blue: 0.380,
alpha: 1.0, alpha: 1.0,
), ),
pressed: ( pressed: (
red: 0.4262574, red: 0.353,
green: 0.35944653, green: 0.220,
blue: 0.48947042, blue: 0.459,
alpha: 1.0, alpha: 1.0,
), ),
selected: ( selected: (
red: 0.35453954, red: 0.286,
green: 0.27938837, green: 0.192,
blue: 0.42565417, blue: 0.380,
alpha: 1.0, alpha: 1.0,
), ),
selected_text: ( selected_text: (
red: 0.90588236, red: 0.788,
green: 0.6117647, green: 0.627,
blue: 0.99607843, blue: 1.0,
alpha: 1.0, alpha: 1.0,
), ),
focus: ( focus: (
red: 0.90588236, red: 0.788,
green: 0.6117647, green: 0.627,
blue: 0.99607843, blue: 1.0,
alpha: 1.0, alpha: 1.0,
), ),
divider: ( divider: (
red: 0.8318802, red: 0.769,
green: 0.8318715, green: 0.722,
blue: 0.8090188, blue: 0.831,
alpha: 0.2, alpha: 0.2,
), ),
on: ( on: (
red: 0.8318802, red: 0.941,
green: 0.8318715, green: 0.918,
blue: 0.8090188, blue: 0.973,
alpha: 1.0, alpha: 1.0,
), ),
disabled: ( disabled: (
red: 0.28282174, red: 0.239,
green: 0.19933021, green: 0.141,
blue: 0.36183798, blue: 0.329,
alpha: 0.5, alpha: 0.5,
), ),
on_disabled: ( on_disabled: (
red: 0.8318802, red: 0.941,
green: 0.8318715, green: 0.918,
blue: 0.8090188, blue: 0.973,
alpha: 0.65, alpha: 0.65,
), ),
border: ( border: (
red: 0.7874787, red: 0.353,
green: 0.6994349, green: 0.220,
blue: 0.8914889, blue: 0.459,
alpha: 1.0, alpha: 1.0,
), ),
disabled_border: ( disabled_border: (
red: 0.7874787, red: 0.353,
green: 0.6994349, green: 0.220,
blue: 0.8914889, blue: 0.459,
alpha: 0.5, alpha: 0.5,
), ),
), ),
divider: ( divider: (
red: 0.32676017, red: 0.149,
green: 0.2608749, green: 0.082,
blue: 0.38187551, blue: 0.216,
alpha: 1.0, alpha: 1.0,
), ),
on: ( on: (
red: 0.75536937, red: 0.941,
green: 0.7553548, green: 0.918,
blue: 0.73290694, blue: 0.973,
alpha: 1.0, alpha: 1.0,
), ),
small_widget: ( small_widget: (
red: 0.23257035, red: 0.443,
green: 0.22102591, green: 0.400,
blue: 0.24228081, blue: 0.525,
alpha: 0.25, alpha: 0.25,
), ),
) )

View File

@@ -1,74 +1,74 @@
( (
base: ( base: (
red: 0.6509804, red: 0.604,
green: 0.8901961, green: 0.859,
blue: 0.6313726, blue: 0.659,
alpha: 1.0, alpha: 1.0,
), ),
hover: ( hover: (
red: 0.60640574, red: 0.544,
green: 0.7815211, green: 0.773,
blue: 0.608765, blue: 0.593,
alpha: 1.0, alpha: 1.0,
), ),
pressed: ( pressed: (
red: 0.38456568, red: 0.353,
green: 0.46464506, green: 0.457,
blue: 0.40839565, blue: 0.406,
alpha: 1.0, alpha: 1.0,
), ),
selected: ( selected: (
red: 0.60640574, red: 0.544,
green: 0.7815211, green: 0.773,
blue: 0.608765, blue: 0.593,
alpha: 1.0, alpha: 1.0,
), ),
selected_text: ( selected_text: (
red: 0.90588236, red: 0.604,
green: 0.6117647, green: 0.859,
blue: 0.99607843, blue: 0.659,
alpha: 1.0, alpha: 1.0,
), ),
focus: ( focus: (
red: 0.90588236, red: 0.604,
green: 0.6117647, green: 0.859,
blue: 0.99607843, blue: 0.659,
alpha: 1.0, alpha: 1.0,
), ),
divider: ( divider: (
red: 0.0, red: 0.102,
green: 0.0, green: 0.055,
blue: 0.000000000000000000000000000000000000000000055, blue: 0.153,
alpha: 1.0, alpha: 1.0,
), ),
on: ( on: (
red: 0.0, red: 0.102,
green: 0.0, green: 0.055,
blue: 0.000000000000000000000000000000000000000000055, blue: 0.153,
alpha: 1.0, alpha: 1.0,
), ),
disabled: ( disabled: (
red: 0.6509804, red: 0.604,
green: 0.8901961, green: 0.859,
blue: 0.6313726, blue: 0.659,
alpha: 1.0, alpha: 0.5,
), ),
on_disabled: ( on_disabled: (
red: 0.3254902, red: 0.353,
green: 0.44509804, green: 0.457,
blue: 0.3156863, blue: 0.406,
alpha: 1.0, alpha: 1.0,
), ),
border: ( border: (
red: 0.6509804, red: 0.604,
green: 0.8901961, green: 0.859,
blue: 0.6313726, blue: 0.659,
alpha: 1.0, alpha: 1.0,
), ),
disabled_border: ( disabled_border: (
red: 0.6509804, red: 0.604,
green: 0.8901961, green: 0.859,
blue: 0.6313726, blue: 0.659,
alpha: 0.5, alpha: 0.5,
), ),
) )

View File

@@ -1,74 +1,74 @@
( (
base: ( base: (
red: 0.9764706, red: 0.910,
green: 0.8862745, green: 0.784,
blue: 0.6862745, blue: 0.478,
alpha: 1.0, alpha: 1.0,
), ),
hover: ( hover: (
red: 0.8667979, red: 0.819,
green: 0.7783838, green: 0.706,
blue: 0.6526866, blue: 0.430,
alpha: 1.0, alpha: 1.0,
), ),
pressed: ( pressed: (
red: 0.54731077, red: 0.506,
green: 0.46268427, green: 0.420,
blue: 0.43584663, blue: 0.316,
alpha: 1.0, alpha: 1.0,
), ),
selected: ( selected: (
red: 0.8667979, red: 0.819,
green: 0.7783838, green: 0.706,
blue: 0.6526866, blue: 0.430,
alpha: 1.0, alpha: 1.0,
), ),
selected_text: ( selected_text: (
red: 0.90588236, red: 0.910,
green: 0.6117647, green: 0.784,
blue: 0.99607843, blue: 0.478,
alpha: 1.0, alpha: 1.0,
), ),
focus: ( focus: (
red: 0.90588236, red: 0.910,
green: 0.6117647, green: 0.784,
blue: 0.99607843, blue: 0.478,
alpha: 1.0, alpha: 1.0,
), ),
divider: ( divider: (
red: 0.0, red: 0.102,
green: 0.0, green: 0.055,
blue: 0.000000000000000000000000000000000000000000055, blue: 0.153,
alpha: 1.0, alpha: 1.0,
), ),
on: ( on: (
red: 0.0, red: 0.102,
green: 0.0, green: 0.055,
blue: 0.000000000000000000000000000000000000000000055, blue: 0.153,
alpha: 1.0, alpha: 1.0,
), ),
disabled: ( disabled: (
red: 0.9764706, red: 0.910,
green: 0.8862745, green: 0.784,
blue: 0.6862745, blue: 0.478,
alpha: 1.0, alpha: 0.5,
), ),
on_disabled: ( on_disabled: (
red: 0.4882353, red: 0.506,
green: 0.44313726, green: 0.420,
blue: 0.34313726, blue: 0.316,
alpha: 1.0, alpha: 1.0,
), ),
border: ( border: (
red: 0.9764706, red: 0.910,
green: 0.8862745, green: 0.784,
blue: 0.6862745, blue: 0.478,
alpha: 1.0, alpha: 1.0,
), ),
disabled_border: ( disabled_border: (
red: 0.9764706, red: 0.910,
green: 0.8862745, green: 0.784,
blue: 0.6862745, blue: 0.478,
alpha: 0.5, alpha: 0.5,
), ),
) )

View File

@@ -1,74 +1,74 @@
( (
base: ( base: (
red: 0.9058823, red: 0.541,
green: 0.6117647, green: 0.361,
blue: 0.99607843, blue: 0.722,
alpha: 1.0, alpha: 1.0,
), ),
hover: ( hover: (
red: 0.7988549, red: 0.461,
green: 0.5659659, green: 0.301,
blue: 0.8900906, blue: 0.642,
alpha: 1.0, alpha: 1.0,
), ),
pressed: ( pressed: (
red: 0.81436175, red: 0.381,
green: 0.6745583, green: 0.241,
blue: 0.91372323, blue: 0.562,
alpha: 1.0, alpha: 1.0,
), ),
selected: ( selected: (
red: 0.7988549, red: 0.461,
green: 0.5659659, green: 0.301,
blue: 0.8900906, blue: 0.642,
alpha: 1.0, alpha: 1.0,
), ),
selected_text: ( selected_text: (
red: 0.9058823, red: 0.541,
green: 0.6117647, green: 0.361,
blue: 0.99607843, blue: 0.722,
alpha: 1.0, alpha: 1.0,
), ),
focus: ( focus: (
red: 0.9058823, red: 0.541,
green: 0.6117647, green: 0.361,
blue: 0.99607843, blue: 0.722,
alpha: 1.0, alpha: 1.0,
), ),
divider: ( divider: (
red: 0.9999203, red: 0.953,
green: 0.99998146, green: 0.929,
blue: 1.0, blue: 0.973,
alpha: 1.0, alpha: 1.0,
), ),
on: ( on: (
red: 0.9999203, red: 0.953,
green: 0.99998146, green: 0.929,
blue: 1.0, blue: 0.973,
alpha: 1.0, alpha: 1.0,
), ),
disabled: ( disabled: (
red: 0.9058823, red: 0.541,
green: 0.6117647, green: 0.361,
blue: 0.99607843, blue: 0.722,
alpha: 1.0, alpha: 1.0,
), ),
on_disabled: ( on_disabled: (
red: 0.9529013, red: 0.271,
green: 0.8058731, green: 0.181,
blue: 0.99803925, blue: 0.361,
alpha: 1.0, alpha: 1.0,
), ),
border: ( border: (
red: 0.9058823, red: 0.541,
green: 0.6117647, green: 0.361,
blue: 0.99607843, blue: 0.722,
alpha: 1.0, alpha: 1.0,
), ),
disabled_border: ( disabled_border: (
red: 0.9058823, red: 0.541,
green: 0.6117647, green: 0.361,
blue: 0.99607843, blue: 0.722,
alpha: 0.5, alpha: 0.5,
), ),
) )

View File

@@ -1,100 +1,100 @@
( (
base: ( base: (
red: 0.20392156, red: 0.953,
green: 0.109803915, green: 0.929,
blue: 0.2901961, blue: 0.973,
alpha: 1.0, alpha: 1.0,
), ),
component: ( component: (
base: ( base: (
red: 0.28618598, red: 0.867,
green: 0.19189146, green: 0.831,
blue: 0.3797182, blue: 0.910,
alpha: 1.0, alpha: 1.0,
), ),
hover: ( hover: (
red: 0.25756738, red: 0.816,
green: 0.17270231, green: 0.776,
blue: 0.3417464, blue: 0.871,
alpha: 1.0, alpha: 1.0,
), ),
pressed: ( pressed: (
red: 0.22894879, red: 0.769,
green: 0.15351318, green: 0.722,
blue: 0.30377457, blue: 0.831,
alpha: 1.0, alpha: 1.0,
), ),
selected: ( selected: (
red: 0.25756738, red: 0.816,
green: 0.17270231, green: 0.776,
blue: 0.3417464, blue: 0.871,
alpha: 1.0, alpha: 1.0,
), ),
selected_text: ( selected_text: (
red: 0.9058823, red: 0.541,
green: 0.6117647, green: 0.361,
blue: 0.99607843, blue: 0.722,
alpha: 1.0, alpha: 1.0,
), ),
focus: ( focus: (
red: 0.9058823, red: 0.541,
green: 0.6117647, green: 0.361,
blue: 0.99607843, blue: 0.722,
alpha: 1.0, alpha: 1.0,
), ),
divider: ( divider: (
red: 0.8318751, red: 0.149,
green: 0.8318648, green: 0.082,
blue: 0.80908096, blue: 0.216,
alpha: 0.2, alpha: 0.2,
), ),
on: ( on: (
red: 0.8318751, red: 0.149,
green: 0.8318648, green: 0.082,
blue: 0.80908096, blue: 0.216,
alpha: 1.0, alpha: 1.0,
), ),
disabled: ( disabled: (
red: 0.28618598, red: 0.867,
green: 0.19189146, green: 0.831,
blue: 0.3797182, blue: 0.910,
alpha: 0.5, alpha: 0.5,
), ),
on_disabled: ( on_disabled: (
red: 0.8318751, red: 0.149,
green: 0.8318648, green: 0.082,
blue: 0.80908096, blue: 0.216,
alpha: 0.65, alpha: 0.65,
), ),
border: ( border: (
red: 0.072988935, red: 0.541,
green: 0.079405405, green: 0.482,
blue: 0.14595589, blue: 0.627,
alpha: 1.0, alpha: 1.0,
), ),
disabled_border: ( disabled_border: (
red: 0.072988935, red: 0.541,
green: 0.079405405, green: 0.482,
blue: 0.14595589, blue: 0.627,
alpha: 0.5, alpha: 0.5,
), ),
), ),
divider: ( divider: (
red: 0.3609102, red: 0.769,
green: 0.285616, green: 0.722,
blue: 0.42522332, blue: 0.831,
alpha: 1.0, alpha: 1.0,
), ),
on: ( on: (
red: 0.98886484, red: 0.149,
green: 0.98886436, green: 0.082,
blue: 0.9653322, blue: 0.216,
alpha: 1.0, alpha: 1.0,
), ),
small_widget: ( small_widget: (
red: 0.20783836, red: 0.541,
green: 0.20930338, green: 0.482,
blue: 0.23179808, blue: 0.627,
alpha: 0.25, alpha: 0.25,
), ),
) )

View File

@@ -1,74 +1,74 @@
( (
base: ( base: (
red: 0.47058824, red: 0.788,
green: 0.16078432, green: 0.227,
blue: 0.18039216, blue: 0.353,
alpha: 1.0, alpha: 1.0,
), ),
hover: ( hover: (
red: 0.45061958, red: 0.698,
green: 0.20518154, green: 0.187,
blue: 0.23754153, blue: 0.303,
alpha: 1.0, alpha: 1.0,
), ),
pressed: ( pressed: (
red: 0.59671474, red: 0.588,
green: 0.44906804, green: 0.147,
blue: 0.5058801, blue: 0.253,
alpha: 1.0, alpha: 1.0,
), ),
selected: ( selected: (
red: 0.45061958, red: 0.698,
green: 0.20518154, green: 0.187,
blue: 0.23754153, blue: 0.303,
alpha: 1.0, alpha: 1.0,
), ),
selected_text: ( selected_text: (
red: 0.9058823, red: 0.541,
green: 0.6117647, green: 0.361,
blue: 0.99607843, blue: 0.722,
alpha: 1.0, alpha: 1.0,
), ),
focus: ( focus: (
red: 0.9058823, red: 0.541,
green: 0.6117647, green: 0.361,
blue: 0.99607843, blue: 0.722,
alpha: 1.0, alpha: 1.0,
), ),
divider: ( divider: (
red: 0.9999203, red: 0.953,
green: 0.99998146, green: 0.929,
blue: 1.0, blue: 0.973,
alpha: 1.0, alpha: 1.0,
), ),
on: ( on: (
red: 0.9999203, red: 0.953,
green: 0.99998146, green: 0.929,
blue: 1.0, blue: 0.973,
alpha: 1.0, alpha: 1.0,
), ),
disabled: ( disabled: (
red: 0.47058824, red: 0.788,
green: 0.16078432, green: 0.227,
blue: 0.18039216, blue: 0.353,
alpha: 1.0, alpha: 1.0,
), ),
on_disabled: ( on_disabled: (
red: 0.7352543, red: 0.394,
green: 0.5803829, green: 0.114,
blue: 0.5901961, blue: 0.177,
alpha: 1.0, alpha: 1.0,
), ),
border: ( border: (
red: 0.47058824, red: 0.788,
green: 0.16078432, green: 0.227,
blue: 0.18039216, blue: 0.353,
alpha: 1.0, alpha: 1.0,
), ),
disabled_border: ( disabled_border: (
red: 0.47058824, red: 0.788,
green: 0.16078432, green: 0.227,
blue: 0.18039216, blue: 0.353,
alpha: 0.5, alpha: 0.5,
), ),
) )

View File

@@ -1 +1 @@
"Violet-chaton" "Violet-Chaton Light"

View File

@@ -1,100 +1,100 @@
( (
base: ( base: (
red: 0.21960787, red: 0.922,
green: 0.13725492, green: 0.894,
blue: 0.29411766, blue: 0.949,
alpha: 1.0, alpha: 1.0,
), ),
component: ( component: (
base: ( base: (
red: 0.28282174, red: 0.867,
green: 0.19933021, green: 0.831,
blue: 0.36183798, blue: 0.910,
alpha: 1.0, alpha: 1.0,
), ),
hover: ( hover: (
red: 0.25453955, red: 0.816,
green: 0.17939718, green: 0.776,
blue: 0.32565418, blue: 0.871,
alpha: 1.0, alpha: 1.0,
), ),
pressed: ( pressed: (
red: 0.2262574, red: 0.769,
green: 0.15946417, green: 0.722,
blue: 0.2894704, blue: 0.831,
alpha: 1.0, alpha: 1.0,
), ),
selected: ( selected: (
red: 0.25453955, red: 0.816,
green: 0.17939718, green: 0.776,
blue: 0.32565418, blue: 0.871,
alpha: 1.0, alpha: 1.0,
), ),
selected_text: ( selected_text: (
red: 0.9058823, red: 0.541,
green: 0.6117647, green: 0.361,
blue: 0.99607843, blue: 0.722,
alpha: 1.0, alpha: 1.0,
), ),
focus: ( focus: (
red: 0.9058823, red: 0.541,
green: 0.6117647, green: 0.361,
blue: 0.99607843, blue: 0.722,
alpha: 1.0, alpha: 1.0,
), ),
divider: ( divider: (
red: 0.8318751, red: 0.149,
green: 0.8318648, green: 0.082,
blue: 0.80908096, blue: 0.216,
alpha: 0.2, alpha: 0.2,
), ),
on: ( on: (
red: 0.8318751, red: 0.149,
green: 0.8318648, green: 0.082,
blue: 0.80908096, blue: 0.216,
alpha: 1.0, alpha: 1.0,
), ),
disabled: ( disabled: (
red: 0.28282174, red: 0.867,
green: 0.19933021, green: 0.831,
blue: 0.36183798, blue: 0.910,
alpha: 0.5, alpha: 0.5,
), ),
on_disabled: ( on_disabled: (
red: 0.8318751, red: 0.149,
green: 0.8318648, green: 0.082,
blue: 0.80908096, blue: 0.216,
alpha: 0.65, alpha: 0.65,
), ),
border: ( border: (
red: 0.072988935, red: 0.541,
green: 0.079405405, green: 0.482,
blue: 0.14595589, blue: 0.627,
alpha: 1.0, alpha: 1.0,
), ),
disabled_border: ( disabled_border: (
red: 0.072988935, red: 0.541,
green: 0.079405405, green: 0.482,
blue: 0.14595589, blue: 0.627,
alpha: 0.5, alpha: 0.5,
), ),
), ),
divider: ( divider: (
red: 0.32675916, red: 0.769,
green: 0.26087362, green: 0.722,
blue: 0.38188773, blue: 0.831,
alpha: 1.0, alpha: 1.0,
), ),
on: ( on: (
red: 0.7553642, red: 0.239,
green: 0.7553483, green: 0.141,
blue: 0.732968, blue: 0.329,
alpha: 1.0, alpha: 1.0,
), ),
small_widget: ( small_widget: (
red: 0.22808892, red: 0.541,
green: 0.22971416, green: 0.482,
blue: 0.25254303, blue: 0.627,
alpha: 0.25, alpha: 0.25,
), ),
) )

View File

@@ -1,74 +1,74 @@
( (
base: ( base: (
red: 0.09411765, red: 0.239,
green: 0.33333334, green: 0.620,
blue: 0.16078432, blue: 0.408,
alpha: 1.0, alpha: 1.0,
), ),
hover: ( hover: (
red: 0.14944312, red: 0.199,
green: 0.34322074, green: 0.540,
blue: 0.22185525, blue: 0.348,
alpha: 1.0, alpha: 1.0,
), ),
pressed: ( pressed: (
red: 0.40847942, red: 0.159,
green: 0.5353426, green: 0.440,
blue: 0.4960762, blue: 0.288,
alpha: 1.0, alpha: 1.0,
), ),
selected: ( selected: (
red: 0.14944312, red: 0.199,
green: 0.34322074, green: 0.540,
blue: 0.22185525, blue: 0.348,
alpha: 1.0, alpha: 1.0,
), ),
selected_text: ( selected_text: (
red: 0.9058823, red: 0.541,
green: 0.6117647, green: 0.361,
blue: 0.99607843, blue: 0.722,
alpha: 1.0, alpha: 1.0,
), ),
focus: ( focus: (
red: 0.9058823, red: 0.541,
green: 0.6117647, green: 0.361,
blue: 0.99607843, blue: 0.722,
alpha: 1.0, alpha: 1.0,
), ),
divider: ( divider: (
red: 0.9999203, red: 0.953,
green: 0.99998146, green: 0.929,
blue: 1.0, blue: 0.973,
alpha: 1.0, alpha: 1.0,
), ),
on: ( on: (
red: 0.9999203, red: 0.953,
green: 0.99998146, green: 0.929,
blue: 1.0, blue: 0.973,
alpha: 1.0, alpha: 1.0,
), ),
disabled: ( disabled: (
red: 0.09411765, red: 0.239,
green: 0.33333334, green: 0.620,
blue: 0.16078432, blue: 0.408,
alpha: 1.0, alpha: 1.0,
), ),
on_disabled: ( on_disabled: (
red: 0.547019, red: 0.120,
green: 0.6666574, green: 0.310,
blue: 0.5803922, blue: 0.204,
alpha: 1.0, alpha: 1.0,
), ),
border: ( border: (
red: 0.09411765, red: 0.239,
green: 0.33333334, green: 0.620,
blue: 0.16078432, blue: 0.408,
alpha: 1.0, alpha: 1.0,
), ),
disabled_border: ( disabled_border: (
red: 0.09411765, red: 0.239,
green: 0.33333334, green: 0.620,
blue: 0.16078432, blue: 0.408,
alpha: 0.5, alpha: 0.5,
), ),
) )

View File

@@ -1,74 +1,74 @@
( (
base: ( base: (
red: 0.3254902, red: 0.722,
green: 0.28235295, green: 0.596,
blue: 0.0, blue: 0.251,
alpha: 1.0, alpha: 1.0,
), ),
hover: ( hover: (
red: 0.33454114, red: 0.642,
green: 0.30243644, green: 0.526,
blue: 0.093227796, blue: 0.211,
alpha: 1.0, alpha: 1.0,
), ),
pressed: ( pressed: (
red: 0.5241657, red: 0.542,
green: 0.50985235, green: 0.436,
blue: 0.41568404, blue: 0.171,
alpha: 1.0, alpha: 1.0,
), ),
selected: ( selected: (
red: 0.33454114, red: 0.642,
green: 0.30243644, green: 0.526,
blue: 0.093227796, blue: 0.211,
alpha: 1.0, alpha: 1.0,
), ),
selected_text: ( selected_text: (
red: 0.9058823, red: 0.541,
green: 0.6117647, green: 0.361,
blue: 0.99607843, blue: 0.722,
alpha: 1.0, alpha: 1.0,
), ),
focus: ( focus: (
red: 0.9058823, red: 0.541,
green: 0.6117647, green: 0.361,
blue: 0.99607843, blue: 0.722,
alpha: 1.0, alpha: 1.0,
), ),
divider: ( divider: (
red: 0.9999203, red: 0.149,
green: 0.99998146, green: 0.082,
blue: 1.0, blue: 0.216,
alpha: 1.0, alpha: 1.0,
), ),
on: ( on: (
red: 0.9999203, red: 0.149,
green: 0.99998146, green: 0.082,
blue: 1.0, blue: 0.216,
alpha: 1.0, alpha: 1.0,
), ),
disabled: ( disabled: (
red: 0.3254902, red: 0.722,
green: 0.28235295, green: 0.596,
blue: 0.0, blue: 0.251,
alpha: 1.0, alpha: 1.0,
), ),
on_disabled: ( on_disabled: (
red: 0.66270524, red: 0.361,
green: 0.6411672, green: 0.298,
blue: 0.5, blue: 0.126,
alpha: 1.0, alpha: 1.0,
), ),
border: ( border: (
red: 0.3254902, red: 0.722,
green: 0.28235295, green: 0.596,
blue: 0.0, blue: 0.251,
alpha: 1.0, alpha: 1.0,
), ),
disabled_border: ( disabled_border: (
red: 0.3254902, red: 0.722,
green: 0.28235295, green: 0.596,
blue: 0.0, blue: 0.251,
alpha: 0.5, alpha: 0.5,
), ),
) )

137
INSTALL/themes/palette.sh Normal file
View File

@@ -0,0 +1,137 @@
#!/usr/bin/env bash
# ══════════════════════════════════════════════════════════════════════════════
# violet-chaton v2 — palette source de verite
#
# Inspiration : Mitsuri Kanroji — gradient rose → vert pastel
# Identite : univers violet profond, accents chauds/frais, zero emprunt
#
# Usage :
# source palette.sh
# echo "$VC_MAGENTA" → #ff4da6
# echo "${VC_RGB_MAGENTA}" → 255;77;166
# echo "${VC_ANSI_MAGENTA}" → \033[38;2;255;77;166m
# ══════════════════════════════════════════════════════════════════════════════
# ── Fond (signature violet-chaton) ───────────────────────────────────────────
VC_CRUST="#1a0e27" # le plus profond — borders, shadows
VC_BASE="#261537" # fond principal
VC_MANTLE="#341c4a" # fond secondaire
VC_SURFACE0="#3d2454" # elements poses
VC_SURFACE1="#493161" # elements hover
VC_SURFACE2="#5a3875" # selection, highlight
# ── Texte (teinte violet — pas du blanc pur) ─────────────────────────────────
VC_TEXT="#f0eaf8" # texte principal
VC_SUBTEXT1="#c4b8d4" # texte secondaire
VC_SUBTEXT0="#9a8fad" # labels, placeholders
VC_MUTED="#716686" # desactive, commentaires
# ── Accents ──────────────────────────────────────────────────────────────────
VC_MAGENTA="#ff4da6" # accent primaire — chaud, vif
VC_LILAC="#c9a0ff" # accent secondaire — doux, aerien
VC_MITSURI="#9adba8" # vert pastel — frais, unique
VC_LAVANDE="#a4b4ff" # bleu-violet — info, fonctions
VC_CHAMPAGNE="#e8c87a" # or chaud — casse le bicolore
# ── Semantiques (derivees des accents) ───────────────────────────────────────
VC_DANGER="#f25c7a" # rouge vif, teinte violet
VC_WARNING="#e8c87a" # = champagne
VC_SUCCESS="#9adba8" # = mitsuri green
VC_INFO="#a4b4ff" # = lavande
# ── Gradient signature (cava, barres, transitions) ───────────────────────────
# magenta → lilac → lavande → mitsuri
VC_GRADIENT_1="$VC_MAGENTA"
VC_GRADIENT_2="#e276d4" # magenta → lilac mid
VC_GRADIENT_3="$VC_LILAC"
VC_GRADIENT_4="#b6a8ff" # lilac → lavande mid
VC_GRADIENT_5="$VC_LAVANDE"
VC_GRADIENT_6="#9fc8d4" # lavande → mitsuri mid
VC_GRADIENT_7="#9adba8" # = mitsuri
VC_GRADIENT_8="#82e8a0" # mitsuri bright tip
# ══════════════════════════════════════════════════════════════════════════════
# LIGHT — meme univers violet, fonds lavande clairs
# Les accents sont legerement assombris pour le contraste sur fond clair
# ══════════════════════════════════════════════════════════════════════════════
# ── Fond light (lavande — identite violet conservee) ────────────────────────
VCL_CRUST="#f8f4fc" # le plus clair — presque blanc violet
VCL_BASE="#f3edf8" # fond principal
VCL_MANTLE="#ebe4f2" # fond secondaire
VCL_SURFACE0="#ddd4e8" # elements poses
VCL_SURFACE1="#d0c6de" # elements hover
VCL_SURFACE2="#c4b8d4" # selection, highlight
# ── Texte light (violet fonce — inversion du dark) ──────────────────────────
VCL_TEXT="#261537" # texte principal (= base dark)
VCL_SUBTEXT1="#3d2454" # texte secondaire
VCL_SUBTEXT0="#5a3875" # labels
VCL_MUTED="#8a7ba0" # desactive, commentaires
# ── Accents light (assombris pour contraste WCAG AA sur fond clair) ─────────
VCL_MAGENTA="#d4348a" # accent primaire
VCL_LILAC="#8a5cb8" # accent secondaire
VCL_MITSURI="#3d9e68" # vert mitsuri assombri
VCL_LAVANDE="#5a6ad0" # bleu-violet assombri
VCL_CHAMPAGNE="#b89840" # or chaud assombri
# ── Semantiques light ──────────────────────────────────────────────────────
VCL_DANGER="#c93a5a"
VCL_WARNING="#b89840"
VCL_SUCCESS="#3d9e68"
VCL_INFO="#5a6ad0"
# ── Font ─────────────────────────────────────────────────────────────────────
VC_FONT="Maple Mono NF"
VC_FONT_FALLBACK="MapleMono Nerd Font"
VC_FONT_SIZE=13
# ── RGB (pour les contextes qui n'acceptent pas le hex) ──────────────────────
_hex2rgb() { printf '%d;%d;%d' "0x${1:1:2}" "0x${1:3:2}" "0x${1:5:2}"; }
VC_RGB_CRUST=$(_hex2rgb "$VC_CRUST")
VC_RGB_BASE=$(_hex2rgb "$VC_BASE")
VC_RGB_MANTLE=$(_hex2rgb "$VC_MANTLE")
VC_RGB_SURFACE0=$(_hex2rgb "$VC_SURFACE0")
VC_RGB_SURFACE1=$(_hex2rgb "$VC_SURFACE1")
VC_RGB_SURFACE2=$(_hex2rgb "$VC_SURFACE2")
VC_RGB_TEXT=$(_hex2rgb "$VC_TEXT")
VC_RGB_SUBTEXT1=$(_hex2rgb "$VC_SUBTEXT1")
VC_RGB_SUBTEXT0=$(_hex2rgb "$VC_SUBTEXT0")
VC_RGB_MUTED=$(_hex2rgb "$VC_MUTED")
VC_RGB_MAGENTA=$(_hex2rgb "$VC_MAGENTA")
VC_RGB_LILAC=$(_hex2rgb "$VC_LILAC")
VC_RGB_MITSURI=$(_hex2rgb "$VC_MITSURI")
VC_RGB_LAVANDE=$(_hex2rgb "$VC_LAVANDE")
VC_RGB_CHAMPAGNE=$(_hex2rgb "$VC_CHAMPAGNE")
VC_RGB_DANGER=$(_hex2rgb "$VC_DANGER")
VC_RGB_WARNING=$(_hex2rgb "$VC_WARNING")
VC_RGB_SUCCESS=$(_hex2rgb "$VC_SUCCESS")
VC_RGB_INFO=$(_hex2rgb "$VC_INFO")
# ── ANSI (pour echo -e dans les scripts) ─────────────────────────────────────
_hex2ansi() { echo "\033[38;2;$(_hex2rgb "$1")m"; }
VC_ANSI_CRUST=$(_hex2ansi "$VC_CRUST")
VC_ANSI_BASE=$(_hex2ansi "$VC_BASE")
VC_ANSI_MANTLE=$(_hex2ansi "$VC_MANTLE")
VC_ANSI_SURFACE0=$(_hex2ansi "$VC_SURFACE0")
VC_ANSI_SURFACE1=$(_hex2ansi "$VC_SURFACE1")
VC_ANSI_SURFACE2=$(_hex2ansi "$VC_SURFACE2")
VC_ANSI_TEXT=$(_hex2ansi "$VC_TEXT")
VC_ANSI_SUBTEXT1=$(_hex2ansi "$VC_SUBTEXT1")
VC_ANSI_SUBTEXT0=$(_hex2ansi "$VC_SUBTEXT0")
VC_ANSI_MUTED=$(_hex2ansi "$VC_MUTED")
VC_ANSI_MAGENTA=$(_hex2ansi "$VC_MAGENTA")
VC_ANSI_LILAC=$(_hex2ansi "$VC_LILAC")
VC_ANSI_MITSURI=$(_hex2ansi "$VC_MITSURI")
VC_ANSI_LAVANDE=$(_hex2ansi "$VC_LAVANDE")
VC_ANSI_CHAMPAGNE=$(_hex2ansi "$VC_CHAMPAGNE")
VC_ANSI_DANGER=$(_hex2ansi "$VC_DANGER")
VC_ANSI_WARNING=$(_hex2ansi "$VC_WARNING")
VC_ANSI_SUCCESS=$(_hex2ansi "$VC_SUCCESS")
VC_ANSI_INFO=$(_hex2ansi "$VC_INFO")
VC_ANSI_RESET='\033[0m'
VC_ANSI_BOLD='\033[1m'
VC_ANSI_ITALIC='\033[3m'

View File

@@ -1,10 +1,10 @@
# violet-chaton — thème atuin # violet-chaton v2 — theme atuin
# Les valeurs sont des noms de couleurs CSS (palette crate) # Les valeurs sont des noms de couleurs CSS (palette crate)
Base = "white" # texte principal #f8f8f2 Base = "lavender_blush" # texte principal #f0eaf8
Important = "hot_pink" # éléments importants #ff79c6 Important = "hot_pink" # accent primaire #ff4da6
Guidance = "slate_gray" # texte d'aide/muted #7f849c Guidance = "medium_purple" # texte aide/muted #716686
Annotation = "orchid" # labels/annotations #e79cfe Annotation = "plum" # labels/annotations #c9a0ff
AlertInfo = "light_cyan" # info #8be9fd AlertInfo = "light_steel_blue" # info #a4b4ff
AlertWarn = "pale_goldenrod" # avertissement #f9e2af AlertWarn = "goldenrod" # warning #e8c87a
AlertError = "light_pink" # erreur #f38ba8 AlertError = "pale_violet_red" # danger #f25c7a

View File

@@ -11,12 +11,12 @@
<dict> <dict>
<key>settings</key> <key>settings</key>
<dict> <dict>
<key>background</key> <string>#341c4a</string> <key>background</key> <string>#261537</string>
<key>foreground</key> <string>#f8f8f2</string> <key>foreground</key> <string>#f0eaf8</string>
<key>caret</key> <string>#ff79c6</string> <key>caret</key> <string>#ff4da6</string>
<key>lineHighlight</key><string>#3d2454</string> <key>lineHighlight</key><string>#3d2454</string>
<key>selection</key> <string>#3d245480</string> <key>selection</key> <string>#5a387580</string>
<key>invisibles</key> <string>#6c7086</string> <key>invisibles</key> <string>#716686</string>
</dict> </dict>
</dict> </dict>
@@ -26,17 +26,17 @@
<key>scope</key><string>comment, punctuation.definition.comment</string> <key>scope</key><string>comment, punctuation.definition.comment</string>
<key>settings</key> <key>settings</key>
<dict> <dict>
<key>foreground</key><string>#7f849c</string> <key>foreground</key><string>#9a8fad</string>
<key>fontStyle</key><string>italic</string> <key>fontStyle</key><string>italic</string>
</dict> </dict>
</dict> </dict>
<!-- Chaînes --> <!-- Chaines -->
<dict> <dict>
<key>name</key><string>String</string> <key>name</key><string>String</string>
<key>scope</key><string>string, string.quoted, string.template</string> <key>scope</key><string>string, string.quoted, string.template</string>
<key>settings</key> <key>settings</key>
<dict><key>foreground</key><string>#e79cfe</string></dict> <dict><key>foreground</key><string>#9adba8</string></dict>
</dict> </dict>
<!-- Nombres --> <!-- Nombres -->
@@ -44,23 +44,23 @@
<key>name</key><string>Number</string> <key>name</key><string>Number</string>
<key>scope</key><string>constant.numeric</string> <key>scope</key><string>constant.numeric</string>
<key>settings</key> <key>settings</key>
<dict><key>foreground</key><string>#a6e3a1</string></dict> <dict><key>foreground</key><string>#e8c87a</string></dict>
</dict> </dict>
<!-- Mots-clés --> <!-- Mots-cles -->
<dict> <dict>
<key>name</key><string>Keyword</string> <key>name</key><string>Keyword</string>
<key>scope</key><string>keyword, keyword.control, storage, storage.type, storage.modifier</string> <key>scope</key><string>keyword, keyword.control, storage, storage.type, storage.modifier</string>
<key>settings</key> <key>settings</key>
<dict><key>foreground</key><string>#ff79c6</string></dict> <dict><key>foreground</key><string>#ff4da6</string></dict>
</dict> </dict>
<!-- Opérateurs --> <!-- Operateurs -->
<dict> <dict>
<key>name</key><string>Operator</string> <key>name</key><string>Operator</string>
<key>scope</key><string>keyword.operator</string> <key>scope</key><string>keyword.operator</string>
<key>settings</key> <key>settings</key>
<dict><key>foreground</key><string>#ff79c6</string></dict> <dict><key>foreground</key><string>#ff4da6</string></dict>
</dict> </dict>
<!-- Fonctions --> <!-- Fonctions -->
@@ -68,7 +68,7 @@
<key>name</key><string>Function</string> <key>name</key><string>Function</string>
<key>scope</key><string>entity.name.function, meta.function-call, support.function</string> <key>scope</key><string>entity.name.function, meta.function-call, support.function</string>
<key>settings</key> <key>settings</key>
<dict><key>foreground</key><string>#8be9fd</string></dict> <dict><key>foreground</key><string>#a4b4ff</string></dict>
</dict> </dict>
<!-- Types / Classes --> <!-- Types / Classes -->
@@ -76,15 +76,15 @@
<key>name</key><string>Type</string> <key>name</key><string>Type</string>
<key>scope</key><string>entity.name.class, entity.name.type, support.class, support.type</string> <key>scope</key><string>entity.name.class, entity.name.type, support.class, support.type</string>
<key>settings</key> <key>settings</key>
<dict><key>foreground</key><string>#e79cfe</string></dict> <dict><key>foreground</key><string>#c9a0ff</string></dict>
</dict> </dict>
<!-- Constantes / Booléens --> <!-- Constantes / Booleens -->
<dict> <dict>
<key>name</key><string>Constant</string> <key>name</key><string>Constant</string>
<key>scope</key><string>constant, constant.language, variable.language</string> <key>scope</key><string>constant, constant.language, variable.language</string>
<key>settings</key> <key>settings</key>
<dict><key>foreground</key><string>#8be9fd</string></dict> <dict><key>foreground</key><string>#a4b4ff</string></dict>
</dict> </dict>
<!-- Variables --> <!-- Variables -->
@@ -92,7 +92,7 @@
<key>name</key><string>Variable</string> <key>name</key><string>Variable</string>
<key>scope</key><string>variable, variable.other</string> <key>scope</key><string>variable, variable.other</string>
<key>settings</key> <key>settings</key>
<dict><key>foreground</key><string>#f8f8f2</string></dict> <dict><key>foreground</key><string>#f0eaf8</string></dict>
</dict> </dict>
<!-- Tags HTML/XML --> <!-- Tags HTML/XML -->
@@ -100,7 +100,7 @@
<key>name</key><string>Tag</string> <key>name</key><string>Tag</string>
<key>scope</key><string>entity.name.tag</string> <key>scope</key><string>entity.name.tag</string>
<key>settings</key> <key>settings</key>
<dict><key>foreground</key><string>#ff79c6</string></dict> <dict><key>foreground</key><string>#ff4da6</string></dict>
</dict> </dict>
<!-- Attributs --> <!-- Attributs -->
@@ -108,7 +108,10 @@
<key>name</key><string>Attribute</string> <key>name</key><string>Attribute</string>
<key>scope</key><string>entity.other.attribute-name</string> <key>scope</key><string>entity.other.attribute-name</string>
<key>settings</key> <key>settings</key>
<dict><key>foreground</key><string>#8be9fd</string></dict> <dict>
<key>foreground</key><string>#a4b4ff</string>
<key>fontStyle</key><string>italic</string>
</dict>
</dict> </dict>
<!-- Ponctuation --> <!-- Ponctuation -->
@@ -116,15 +119,15 @@
<key>name</key><string>Punctuation</string> <key>name</key><string>Punctuation</string>
<key>scope</key><string>punctuation</string> <key>scope</key><string>punctuation</string>
<key>settings</key> <key>settings</key>
<dict><key>foreground</key><string>#9399b2</string></dict> <dict><key>foreground</key><string>#9a8fad</string></dict>
</dict> </dict>
<!-- CSS propriétés --> <!-- CSS proprietes -->
<dict> <dict>
<key>name</key><string>CSS Property</string> <key>name</key><string>CSS Property</string>
<key>scope</key><string>support.type.property-name.css, support.type.property-name.scss</string> <key>scope</key><string>support.type.property-name.css, support.type.property-name.scss</string>
<key>settings</key> <key>settings</key>
<dict><key>foreground</key><string>#8be9fd</string></dict> <dict><key>foreground</key><string>#a4b4ff</string></dict>
</dict> </dict>
<!-- CSS valeurs --> <!-- CSS valeurs -->
@@ -132,7 +135,7 @@
<key>name</key><string>CSS Value</string> <key>name</key><string>CSS Value</string>
<key>scope</key><string>support.constant.property-value.css</string> <key>scope</key><string>support.constant.property-value.css</string>
<key>settings</key> <key>settings</key>
<dict><key>foreground</key><string>#e79cfe</string></dict> <dict><key>foreground</key><string>#c9a0ff</string></dict>
</dict> </dict>
<!-- SCSS variables --> <!-- SCSS variables -->
@@ -140,7 +143,56 @@
<key>name</key><string>SCSS Variable</string> <key>name</key><string>SCSS Variable</string>
<key>scope</key><string>variable.scss, variable.sass</string> <key>scope</key><string>variable.scss, variable.sass</string>
<key>settings</key> <key>settings</key>
<dict><key>foreground</key><string>#8be9fd</string></dict> <dict><key>foreground</key><string>#a4b4ff</string></dict>
</dict>
<!-- Regex -->
<dict>
<key>name</key><string>Regex</string>
<key>scope</key><string>string.regexp</string>
<key>settings</key>
<dict><key>foreground</key><string>#e8c87a</string></dict>
</dict>
<!-- Markdown heading -->
<dict>
<key>name</key><string>Markdown Heading</string>
<key>scope</key><string>markup.heading, entity.name.section</string>
<key>settings</key>
<dict>
<key>foreground</key><string>#ff4da6</string>
<key>fontStyle</key><string>bold</string>
</dict>
</dict>
<!-- Markdown bold -->
<dict>
<key>name</key><string>Markdown Bold</string>
<key>scope</key><string>markup.bold</string>
<key>settings</key>
<dict><key>fontStyle</key><string>bold</string></dict>
</dict>
<!-- Markdown italic -->
<dict>
<key>name</key><string>Markdown Italic</string>
<key>scope</key><string>markup.italic</string>
<key>settings</key>
<dict>
<key>foreground</key><string>#c9a0ff</string>
<key>fontStyle</key><string>italic</string>
</dict>
</dict>
<!-- Markdown link -->
<dict>
<key>name</key><string>Markdown Link</string>
<key>scope</key><string>markup.underline.link</string>
<key>settings</key>
<dict>
<key>foreground</key><string>#a4b4ff</string>
<key>fontStyle</key><string>underline</string>
</dict>
</dict> </dict>
<!-- Invalide --> <!-- Invalide -->
@@ -149,7 +201,7 @@
<key>scope</key><string>invalid</string> <key>scope</key><string>invalid</string>
<key>settings</key> <key>settings</key>
<dict> <dict>
<key>foreground</key><string>#f38ba8</string> <key>foreground</key><string>#f25c7a</string>
<key>fontStyle</key><string>bold</string> <key>fontStyle</key><string>bold</string>
</dict> </dict>
</dict> </dict>

View File

@@ -1,75 +1,75 @@
# violet-chaton btop theme # violet-chaton v2 btop theme
# Palette : ~/Documents/config/violet-chaton-discord-theme/src/modules/_variables.scss # Palette : themes/palette.sh — zero emprunt
# Main background # Main background
theme[main_bg]="#261537" theme[main_bg]="#261537"
# Main text color # Main text color
theme[main_fg]="#f8f8f2" theme[main_fg]="#f0eaf8"
# Title color for boxes # Title color for boxes
theme[title]="#e79cfe" theme[title]="#c9a0ff"
# Highlight color for keyboard shortcuts # Highlight color for keyboard shortcuts
theme[hi_fg]="#ff79c6" theme[hi_fg]="#ff4da6"
# Background color of selected item in processes box # Background color of selected item in processes box
theme[selected_bg]="#3d2454" theme[selected_bg]="#5a3875"
# Foreground color of selected item in processes box # Foreground color of selected item in processes box
theme[selected_fg]="#f8f8f2" theme[selected_fg]="#f0eaf8"
# Color of inactive/disabled text # Color of inactive/disabled text
theme[inactive_fg]="#6c7086" theme[inactive_fg]="#716686"
# Misc colors for processes box (mini cpu graphs, details, status) # Misc colors for processes box (mini cpu graphs, details, status)
theme[proc_misc]="#8be9fd" theme[proc_misc]="#a4b4ff"
# Box outline colors # Box outline colors
theme[cpu_box]="#38234b" theme[cpu_box]="#3d2454"
theme[mem_box]="#38234b" theme[mem_box]="#3d2454"
theme[net_box]="#38234b" theme[net_box]="#3d2454"
theme[proc_box]="#38234b" theme[proc_box]="#3d2454"
# Box divider line # Box divider line
theme[div_line]="#341c4a" theme[div_line]="#341c4a"
# Temperature graph : cyan (froid) → warning (chaud) → danger (critique) # Temperature graph : lavande (froid) → champagne (chaud) → danger (critique)
theme[temp_start]="#8be9fd" theme[temp_start]="#a4b4ff"
theme[temp_mid]="#f9e2af" theme[temp_mid]="#e8c87a"
theme[temp_end]="#f38ba8" theme[temp_end]="#f25c7a"
# CPU graph : purple → pink → danger # CPU graph : lilac → magenta → danger
theme[cpu_start]="#e79cfe" theme[cpu_start]="#c9a0ff"
theme[cpu_mid]="#ff79c6" theme[cpu_mid]="#ff4da6"
theme[cpu_end]="#f38ba8" theme[cpu_end]="#f25c7a"
# Mem/Disk free meter : green → cyan → purple # Mem/Disk free meter : mitsuri → lavande → lilac
theme[free_start]="#a6e3a1" theme[free_start]="#9adba8"
theme[free_mid]="#8be9fd" theme[free_mid]="#a4b4ff"
theme[free_end]="#e79cfe" theme[free_end]="#c9a0ff"
# Mem/Disk cached meter : purple subtil # Mem/Disk cached meter : surface subtil → lilac
theme[cached_start]="#3d2454" theme[cached_start]="#3d2454"
theme[cached_mid]="#e79cfe" theme[cached_mid]="#c9a0ff"
theme[cached_end]="#e79cfe" theme[cached_end]="#c9a0ff"
# Mem/Disk available meter : cyan → purple # Mem/Disk available meter : lavande → lilac → magenta
theme[available_start]="#8be9fd" theme[available_start]="#a4b4ff"
theme[available_mid]="#e79cfe" theme[available_mid]="#c9a0ff"
theme[available_end]="#ff79c6" theme[available_end]="#ff4da6"
# Mem/Disk used meter : purple → pink → danger # Mem/Disk used meter : lilac → magenta → danger
theme[used_start]="#e79cfe" theme[used_start]="#c9a0ff"
theme[used_mid]="#ff79c6" theme[used_mid]="#ff4da6"
theme[used_end]="#f38ba8" theme[used_end]="#f25c7a"
# Download graph : cyan → purple # Download graph : lavande → lilac → magenta
theme[download_start]="#8be9fd" theme[download_start]="#a4b4ff"
theme[download_mid]="#e79cfe" theme[download_mid]="#c9a0ff"
theme[download_end]="#ff79c6" theme[download_end]="#ff4da6"
# Upload graph : pink → danger # Upload graph : magenta → danger → champagne
theme[upload_start]="#ff79c6" theme[upload_start]="#ff4da6"
theme[upload_mid]="#f38ba8" theme[upload_mid]="#f25c7a"
theme[upload_end]="#f9e2af" theme[upload_end]="#e8c87a"

View File

@@ -17,16 +17,16 @@ mono_option = average
reverse = 0 reverse = 0
[color] [color]
# background commenté = transparent # background commente = transparent
gradient = 1 gradient = 1
gradient_color_1 = '#ff79c6' gradient_color_1 = '#ff4da6'
gradient_color_2 = '#f079d8' gradient_color_2 = '#e276d4'
gradient_color_3 = '#e079ea' gradient_color_3 = '#c9a0ff'
gradient_color_4 = '#e79cfe' gradient_color_4 = '#b6a8ff'
gradient_color_5 = '#c0b0fe' gradient_color_5 = '#a4b4ff'
gradient_color_6 = '#99c4fe' gradient_color_6 = '#9fc8d4'
gradient_color_7 = '#8bd4fe' gradient_color_7 = '#9adba8'
gradient_color_8 = '#8be9fd' gradient_color_8 = '#82e8a0'
[smoothing] [smoothing]
monstercat = 1 monstercat = 1

View File

@@ -0,0 +1,128 @@
/* ── violet-chaton v2 GTK Light theme (adw-gtk3 compatible) ──────────────────
* Palette : themes/palette.sh — section LIGHT
* Meme univers violet, fonds lavande clairs
* ─────────────────────────────────────────────────────────────────────────── */
@define-color window_bg_color rgba(243, 237, 248, 1.00);
@define-color window_fg_color rgba(38, 21, 55, 1.00);
@define-color view_bg_color rgba(248, 244, 252, 1.00);
@define-color view_fg_color rgba(61, 36, 84, 1.00);
@define-color headerbar_bg_color rgba(235, 228, 242, 1.00);
@define-color headerbar_fg_color rgba(38, 21, 55, 1.00);
@define-color headerbar_border_color_color rgba(196, 184, 212, 1.00);
@define-color headerbar_backdrop_color rgba(243, 237, 248, 1.00);
@define-color sidebar_bg_color rgba(235, 228, 242, 1.00);
@define-color sidebar_fg_color rgba(61, 36, 84, 1.00);
@define-color sidebar_shade_color rgba(0, 0, 0, 0.06);
@define-color sidebar_backdrop_color rgba(221, 212, 232, 1.00);
@define-color secondary_sidebar_bg_color rgba(221, 212, 232, 1.00);
@define-color secondary_sidebar_fg_color rgba(61, 36, 84, 1.00);
@define-color secondary_sidebar_shade_color rgba(0, 0, 0, 0.06);
@define-color secondary_sidebar_backdrop_color rgba(208, 198, 222, 1.00);
@define-color card_bg_color rgba(248, 244, 252, 1.00);
@define-color card_fg_color rgba(61, 36, 84, 1.00);
@define-color thumbnail_bg_color rgba(248, 244, 252, 1.00);
@define-color thumbnail_fg_color rgba(61, 36, 84, 1.00);
@define-color dialog_bg_color rgba(243, 237, 248, 1.00);
@define-color dialog_fg_color rgba(38, 21, 55, 1.00);
@define-color popover_bg_color rgba(248, 244, 252, 1.00);
@define-color popover_fg_color rgba(61, 36, 84, 1.00);
@define-color shade_color rgba(0, 0, 0, 0.12);
@define-color scrollbar_outline_color rgba(196, 184, 212, 0.50);
/* Accent = lilac assombri */
@define-color accent_color rgba(138, 92, 184, 1.00);
@define-color accent_bg_color rgba(138, 92, 184, 1.00);
@define-color accent_fg_color rgba(248, 244, 252, 1.00);
/* Destructive = danger */
@define-color destructive_color rgba(201, 58, 90, 1.00);
@define-color destructive_bg_color rgba(201, 58, 90, 1.00);
@define-color destructive_fg_color rgba(248, 244, 252, 1.00);
/* Warning = champagne */
@define-color warning_color rgba(184, 152, 64, 1.00);
@define-color warning_bg_color rgba(184, 152, 64, 1.00);
@define-color warning_fg_color rgba(38, 21, 55, 1.00);
/* Success = mitsuri */
@define-color success_color rgba(61, 158, 104, 1.00);
@define-color success_bg_color rgba(61, 158, 104, 1.00);
@define-color success_fg_color rgba(248, 244, 252, 1.00);
/* Error = danger */
@define-color error_color rgba(201, 58, 90, 1.00);
@define-color error_bg_color rgba(201, 58, 90, 1.00);
@define-color error_fg_color rgba(248, 244, 252, 1.00);
/* Bleu = lavande assombri */
@define-color blue_1 rgba(110, 130, 224, 1.00);
@define-color blue_2 rgba(100, 120, 216, 1.00);
@define-color blue_3 rgba(90, 106, 208, 1.00);
@define-color blue_4 rgba(72, 86, 180, 1.00);
@define-color blue_5 rgba(54, 66, 152, 1.00);
/* Vert = mitsuri assombri */
@define-color green_1 rgba(80, 176, 124, 1.00);
@define-color green_2 rgba(70, 168, 114, 1.00);
@define-color green_3 rgba(61, 158, 104, 1.00);
@define-color green_4 rgba(48, 132, 84, 1.00);
@define-color green_5 rgba(36, 106, 66, 1.00);
/* Jaune = champagne assombri */
@define-color yellow_1 rgba(200, 170, 86, 1.00);
@define-color yellow_2 rgba(192, 162, 76, 1.00);
@define-color yellow_3 rgba(184, 152, 64, 1.00);
@define-color yellow_4 rgba(158, 128, 44, 1.00);
@define-color yellow_5 rgba(132, 104, 26, 1.00);
/* Rouge = danger assombri */
@define-color red_1 rgba(218, 82, 114, 1.00);
@define-color red_2 rgba(210, 70, 102, 1.00);
@define-color red_3 rgba(201, 58, 90, 1.00);
@define-color red_4 rgba(174, 42, 72, 1.00);
@define-color red_5 rgba(148, 28, 56, 1.00);
/* Orange */
@define-color orange_1 rgba(210, 154, 100, 1.00);
@define-color orange_2 rgba(202, 144, 88, 1.00);
@define-color orange_3 rgba(192, 132, 76, 1.00);
@define-color orange_4 rgba(164, 108, 56, 1.00);
@define-color orange_5 rgba(136, 84, 38, 1.00);
/* Purple = lilac → magenta assombris */
@define-color purple_1 rgba(156, 116, 200, 1.00);
@define-color purple_2 rgba(148, 104, 192, 1.00);
@define-color purple_3 rgba(138, 92, 184, 1.00);
@define-color purple_4 rgba(114, 72, 160, 1.00);
@define-color purple_5 rgba(92, 54, 136, 1.00);
/* Echelle monochrome lavande */
@define-color light_0 rgba(248, 244, 252, 1.00);
@define-color light_1 rgba(243, 237, 248, 1.00);
@define-color light_2 rgba(235, 228, 242, 1.00);
@define-color light_3 rgba(221, 212, 232, 1.00);
@define-color light_4 rgba(208, 198, 222, 1.00);
@define-color dark_0 rgba(196, 184, 212, 1.00);
@define-color dark_1 rgba(138, 123, 160, 1.00);
@define-color dark_2 rgba(90, 56, 117, 1.00);
@define-color dark_3 rgba(61, 36, 84, 1.00);
@define-color dark_4 rgba(38, 21, 55, 1.00);
/* ── Variables GTK3 classiques (compat apps legacy) ─────────────────────── */
@define-color theme_bg_color rgba(243, 237, 248, 1.00);
@define-color theme_fg_color rgba(38, 21, 55, 1.00);
@define-color theme_base_color rgba(248, 244, 252, 1.00);
@define-color theme_selected_bg_color rgba(138, 92, 184, 1.00);
@define-color theme_selected_fg_color rgba(248, 244, 252, 1.00);
@define-color theme_text_color rgba(38, 21, 55, 1.00);
@define-color borders rgba(196, 184, 212, 1.00);

View File

@@ -1,122 +1,127 @@
/* ── violet-chaton GTK theme (adw-gtk3-dark compatible) ─────────────────── /* ── violet-chaton v2 GTK theme (adw-gtk3-dark compatible) ───────────────────
* * Palette : themes/palette.sh — source de verite unique
* Contenu identique au dark.css généré par COSMIC pour le thème violet-chaton.
* adw-gtk3-dark et libadwaita lisent ces variables @define-color.
* Sur le PC principal, COSMIC gère ce fichier via symlink — ce fichier
* sert de fallback lors de la première installation.
* ─────────────────────────────────────────────────────────────────────────── */ * ─────────────────────────────────────────────────────────────────────────── */
@define-color window_bg_color rgba(52, 28, 74, 1.00); @define-color window_bg_color rgba(38, 21, 55, 1.00);
@define-color window_fg_color rgba(252, 252, 246, 1.00); @define-color window_fg_color rgba(240, 234, 248, 1.00);
@define-color view_bg_color rgba(56, 35, 75, 1.00); @define-color view_bg_color rgba(52, 28, 74, 1.00);
@define-color view_fg_color rgba(193, 193, 187, 1.00); @define-color view_fg_color rgba(196, 184, 212, 1.00);
@define-color headerbar_bg_color rgba(52, 28, 74, 1.00); @define-color headerbar_bg_color rgba(38, 21, 55, 1.00);
@define-color headerbar_fg_color rgba(252, 252, 246, 1.00); @define-color headerbar_fg_color rgba(240, 234, 248, 1.00);
@define-color headerbar_border_color_color rgba(92, 73, 108, 1.00); @define-color headerbar_border_color_color rgba(90, 56, 117, 1.00);
@define-color headerbar_backdrop_color rgba(52, 28, 74, 1.00); @define-color headerbar_backdrop_color rgba(38, 21, 55, 1.00);
@define-color sidebar_bg_color rgba(56, 35, 75, 1.00); @define-color sidebar_bg_color rgba(52, 28, 74, 1.00);
@define-color sidebar_fg_color rgba(193, 193, 187, 1.00); @define-color sidebar_fg_color rgba(196, 184, 212, 1.00);
@define-color sidebar_shade_color rgba(0, 0, 0, 0.08); @define-color sidebar_shade_color rgba(0, 0, 0, 0.08);
@define-color sidebar_backdrop_color rgba(72, 53, 89, 1.00); @define-color sidebar_backdrop_color rgba(61, 36, 84, 1.00);
@define-color secondary_sidebar_bg_color rgba(69, 71, 90, 1.00); @define-color secondary_sidebar_bg_color rgba(61, 36, 84, 1.00);
@define-color secondary_sidebar_fg_color rgba(225, 225, 219, 1.00); @define-color secondary_sidebar_fg_color rgba(196, 184, 212, 1.00);
@define-color secondary_sidebar_shade_color rgba(0, 0, 0, 0.08); @define-color secondary_sidebar_shade_color rgba(0, 0, 0, 0.08);
@define-color secondary_sidebar_backdrop_color rgba(84, 86, 103, 1.00); @define-color secondary_sidebar_backdrop_color rgba(73, 49, 97, 1.00);
@define-color card_bg_color rgba(73, 49, 97, 1.00); @define-color card_bg_color rgba(61, 36, 84, 1.00);
@define-color card_fg_color rgba(212, 212, 206, 1.00); @define-color card_fg_color rgba(196, 184, 212, 1.00);
@define-color thumbnail_bg_color rgba(73, 49, 97, 1.00); @define-color thumbnail_bg_color rgba(61, 36, 84, 1.00);
@define-color thumbnail_fg_color rgba(212, 212, 206, 1.00); @define-color thumbnail_fg_color rgba(196, 184, 212, 1.00);
@define-color dialog_bg_color rgba(56, 35, 75, 1.00); @define-color dialog_bg_color rgba(52, 28, 74, 1.00);
@define-color dialog_fg_color rgba(193, 193, 187, 1.00); @define-color dialog_fg_color rgba(196, 184, 212, 1.00);
@define-color popover_bg_color rgba(73, 49, 97, 1.00); @define-color popover_bg_color rgba(61, 36, 84, 1.00);
@define-color popover_fg_color rgba(212, 212, 206, 1.00); @define-color popover_fg_color rgba(196, 184, 212, 1.00);
@define-color shade_color rgba(0, 0, 0, 0.32); @define-color shade_color rgba(0, 0, 0, 0.32);
@define-color scrollbar_outline_color rgba(52, 28, 74, 0.50); @define-color scrollbar_outline_color rgba(38, 21, 55, 0.50);
@define-color accent_color rgba(231, 156, 254, 1.00); /* Accent = lilac (v2) */
@define-color accent_bg_color rgba(231, 156, 254, 1.00); @define-color accent_color rgba(201, 160, 255, 1.00);
@define-color accent_fg_color rgba(0, 0, 0, 1.00); @define-color accent_bg_color rgba(201, 160, 255, 1.00);
@define-color accent_fg_color rgba(26, 14, 39, 1.00);
@define-color destructive_color rgba(243, 139, 168, 1.00); /* Destructive = danger */
@define-color destructive_bg_color rgba(243, 139, 168, 1.00); @define-color destructive_color rgba(242, 92, 122, 1.00);
@define-color destructive_fg_color rgba(0, 0, 0, 1.00); @define-color destructive_bg_color rgba(242, 92, 122, 1.00);
@define-color destructive_fg_color rgba(26, 14, 39, 1.00);
@define-color warning_color rgba(249, 226, 175, 1.00); /* Warning = champagne */
@define-color warning_bg_color rgba(249, 226, 175, 1.00); @define-color warning_color rgba(232, 200, 122, 1.00);
@define-color warning_fg_color rgba(0, 0, 0, 1.00); @define-color warning_bg_color rgba(232, 200, 122, 1.00);
@define-color warning_fg_color rgba(26, 14, 39, 1.00);
@define-color success_color rgba(166, 227, 161, 1.00); /* Success = mitsuri */
@define-color success_bg_color rgba(166, 227, 161, 1.00); @define-color success_color rgba(154, 219, 168, 1.00);
@define-color success_fg_color rgba(0, 0, 0, 1.00); @define-color success_bg_color rgba(154, 219, 168, 1.00);
@define-color success_fg_color rgba(26, 14, 39, 1.00);
@define-color accent_color rgba(231, 156, 254, 1.00); /* Error = danger */
@define-color accent_bg_color rgba(231, 156, 254, 1.00); @define-color error_color rgba(242, 92, 122, 1.00);
@define-color accent_fg_color rgba(0, 0, 0, 1.00); @define-color error_bg_color rgba(242, 92, 122, 1.00);
@define-color error_fg_color rgba(26, 14, 39, 1.00);
@define-color error_color rgba(243, 139, 168, 1.00); /* Bleu = lavande */
@define-color error_bg_color rgba(243, 139, 168, 1.00); @define-color blue_1 rgba(180, 196, 255, 1.00);
@define-color error_fg_color rgba(0, 0, 0, 1.00); @define-color blue_2 rgba(172, 188, 255, 1.00);
@define-color blue_3 rgba(164, 180, 255, 1.00);
@define-color blue_4 rgba(138, 154, 228, 1.00);
@define-color blue_5 rgba(112, 128, 200, 1.00);
@define-color blue_1 rgba(151, 195, 255, 1.00); /* Vert = mitsuri */
@define-color blue_2 rgba(144, 187, 255, 1.00); @define-color green_1 rgba(170, 230, 182, 1.00);
@define-color blue_3 rgba(137, 180, 250, 1.00); @define-color green_2 rgba(162, 226, 175, 1.00);
@define-color blue_4 rgba(114, 156, 224, 1.00); @define-color green_3 rgba(154, 219, 168, 1.00);
@define-color blue_5 rgba(91, 132, 199, 1.00); @define-color green_4 rgba(128, 192, 142, 1.00);
@define-color green_5 rgba(102, 166, 116, 1.00);
@define-color green_1 rgba(175, 236, 170, 1.00); /* Jaune = champagne */
@define-color green_2 rgba(171, 232, 165, 1.00); @define-color yellow_1 rgba(242, 212, 140, 1.00);
@define-color green_3 rgba(166, 227, 161, 1.00); @define-color yellow_2 rgba(238, 206, 132, 1.00);
@define-color green_4 rgba(139, 199, 134, 1.00); @define-color yellow_3 rgba(232, 200, 122, 1.00);
@define-color green_5 rgba(113, 171, 108, 1.00); @define-color yellow_4 rgba(204, 174, 98, 1.00);
@define-color yellow_5 rgba(176, 148, 74, 1.00);
@define-color yellow_1 rgba(254, 231, 180, 1.00); /* Rouge = danger */
@define-color yellow_2 rgba(252, 229, 178, 1.00); @define-color red_1 rgba(254, 116, 146, 1.00);
@define-color yellow_3 rgba(249, 226, 175, 1.00); @define-color red_2 rgba(248, 104, 134, 1.00);
@define-color yellow_4 rgba(219, 196, 146, 1.00); @define-color red_3 rgba(242, 92, 122, 1.00);
@define-color yellow_5 rgba(189, 167, 118, 1.00); @define-color red_4 rgba(216, 70, 100, 1.00);
@define-color red_5 rgba(190, 48, 78, 1.00);
@define-color red_1 rgba(255, 154, 183, 1.00); /* Orange (derive du champagne chaud) */
@define-color red_2 rgba(252, 147, 176, 1.00); @define-color orange_1 rgba(248, 186, 140, 1.00);
@define-color red_3 rgba(243, 139, 168, 1.00); @define-color orange_2 rgba(244, 178, 130, 1.00);
@define-color red_4 rgba(217, 116, 145, 1.00); @define-color orange_3 rgba(238, 168, 118, 1.00);
@define-color red_5 rgba(191, 93, 122, 1.00); @define-color orange_4 rgba(210, 142, 94, 1.00);
@define-color orange_5 rgba(182, 116, 70, 1.00);
@define-color orange_1 rgba(255, 190, 146, 1.00); /* Purple = lilac → magenta */
@define-color orange_2 rgba(255, 185, 140, 1.00); @define-color purple_1 rgba(216, 180, 255, 1.00);
@define-color orange_3 rgba(250, 179, 135, 1.00); @define-color purple_2 rgba(208, 170, 255, 1.00);
@define-color orange_4 rgba(222, 153, 110, 1.00); @define-color purple_3 rgba(201, 160, 255, 1.00);
@define-color orange_5 rgba(195, 128, 85, 1.00); @define-color purple_4 rgba(174, 136, 228, 1.00);
@define-color purple_5 rgba(148, 112, 200, 1.00);
@define-color purple_1 rgba(192, 202, 255, 1.00); /* Echelle monochrome violet */
@define-color purple_2 rgba(186, 196, 255, 1.00);
@define-color purple_3 rgba(180, 190, 254, 1.00);
@define-color purple_4 rgba(155, 164, 226, 1.00);
@define-color purple_5 rgba(130, 139, 200, 1.00);
@define-color light_0 rgba(0, 0, 0, 1.00); @define-color light_0 rgba(0, 0, 0, 1.00);
@define-color light_1 rgba(3, 3, 16, 1.00); @define-color light_1 rgba(10, 5, 16, 1.00);
@define-color light_2 rgba(24, 25, 43, 1.00); @define-color light_2 rgba(26, 14, 39, 1.00);
@define-color light_3 rgba(50, 53, 72, 1.00); @define-color light_3 rgba(52, 28, 74, 1.00);
@define-color light_4 rgba(79, 82, 103, 1.00); @define-color light_4 rgba(73, 49, 97, 1.00);
@define-color dark_0 rgba(110, 114, 135, 1.00); @define-color dark_0 rgba(113, 102, 134, 1.00);
@define-color dark_1 rgba(143, 147, 169, 1.00); @define-color dark_1 rgba(154, 143, 173, 1.00);
@define-color dark_2 rgba(177, 181, 205, 1.00); @define-color dark_2 rgba(196, 184, 212, 1.00);
@define-color dark_3 rgba(213, 217, 241, 1.00); @define-color dark_3 rgba(240, 234, 248, 1.00);
@define-color dark_4 rgba(255, 255, 255, 1.00); @define-color dark_4 rgba(255, 255, 255, 1.00);
/* ── Variables GTK3 classiques (compat apps legacy) ─────────────────────── */ /* ── Variables GTK3 classiques (compat apps legacy) ─────────────────────── */
@define-color theme_bg_color rgba(52, 28, 74, 1.00); @define-color theme_bg_color rgba(38, 21, 55, 1.00);
@define-color theme_fg_color rgba(252, 252, 246, 1.00); @define-color theme_fg_color rgba(240, 234, 248, 1.00);
@define-color theme_base_color rgba(73, 49, 97, 1.00); @define-color theme_base_color rgba(61, 36, 84, 1.00);
@define-color theme_selected_bg_color rgba(231, 156, 254, 1.00); @define-color theme_selected_bg_color rgba(201, 160, 255, 1.00);
@define-color theme_selected_fg_color rgba(52, 28, 74, 1.00); @define-color theme_selected_fg_color rgba(26, 14, 39, 1.00);
@define-color theme_text_color rgba(252, 252, 246, 1.00); @define-color theme_text_color rgba(240, 234, 248, 1.00);
@define-color borders rgba(92, 73, 108, 1.00); @define-color borders rgba(90, 56, 117, 1.00);

View File

@@ -1,23 +1,19 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Génère les LS_COLORS violet-chaton depuis catppuccin-mocha # ── violet-chaton v2 — LS_COLORS ────────────────────────────────────────────
# Genere les LS_COLORS depuis la palette v2 sans dependance a catppuccin
# Usage : export LS_COLORS="$(bash violet-chaton-ls-colors.sh)" # Usage : export LS_COLORS="$(bash violet-chaton-ls-colors.sh)"
#
# Palette v2 :
# magenta #ff4da6 executables
# lilac #c9a0ff dossiers
# mitsuri #9adba8 fichiers texte/code
# lavande #a4b4ff liens symboliques
# champagne #e8c87a archives/comprimes
# danger #f25c7a fichiers speciaux (devices, sockets)
# text #f0eaf8 fichiers normaux
# muted #716686 fichiers caches/backup
# subtext0 #9a8fad metadata
vivid generate catppuccin-mocha | \ cat << 'LSCOLORS'
sed \ no=0:fi=0:rs=0:di=1;38;2;201;160;255:ln=38;2;164;180;255:mh=0:pi=38;2;232;200;122;48;2;38;21;55:so=1;38;2;242;92;122:do=1;38;2;242;92;122:bd=38;2;232;200;122;48;2;61;36;84:cd=38;2;232;200;122;48;2;38;21;55:or=1;38;2;242;92;122;48;2;38;21;55:su=38;2;240;234;248;48;2;242;92;122:sg=38;2;240;234;248;48;2;232;200;122:ca=0:tw=38;2;240;234;248;48;2;61;158;104:ow=38;2;201;160;255;48;2;61;36;84:st=38;2;240;234;248;48;2;164;180;255:ex=1;38;2;255;77;166:mi=1;38;2;242;92;122;48;2;38;21;55:*.tar=38;2;232;200;122:*.tgz=38;2;232;200;122:*.arc=38;2;232;200;122:*.arj=38;2;232;200;122:*.taz=38;2;232;200;122:*.lha=38;2;232;200;122:*.lz4=38;2;232;200;122:*.lzh=38;2;232;200;122:*.lzma=38;2;232;200;122:*.tlz=38;2;232;200;122:*.txz=38;2;232;200;122:*.tzo=38;2;232;200;122:*.t7z=38;2;232;200;122:*.zip=38;2;232;200;122:*.z=38;2;232;200;122:*.dz=38;2;232;200;122:*.gz=38;2;232;200;122:*.lrz=38;2;232;200;122:*.lz=38;2;232;200;122:*.lzo=38;2;232;200;122:*.xz=38;2;232;200;122:*.zst=38;2;232;200;122:*.tzst=38;2;232;200;122:*.bz2=38;2;232;200;122:*.bz=38;2;232;200;122:*.tbz=38;2;232;200;122:*.tbz2=38;2;232;200;122:*.tz=38;2;232;200;122:*.deb=38;2;232;200;122:*.rpm=38;2;232;200;122:*.jar=38;2;232;200;122:*.war=38;2;232;200;122:*.ear=38;2;232;200;122:*.sar=38;2;232;200;122:*.rar=38;2;232;200;122:*.alz=38;2;232;200;122:*.ace=38;2;232;200;122:*.zoo=38;2;232;200;122:*.cpio=38;2;232;200;122:*.7z=38;2;232;200;122:*.rz=38;2;232;200;122:*.cab=38;2;232;200;122:*.wim=38;2;232;200;122:*.swm=38;2;232;200;122:*.dwm=38;2;232;200;122:*.esd=38;2;232;200;122:*.apk=38;2;232;200;122:*.jpg=38;2;255;77;166:*.jpeg=38;2;255;77;166:*.mjpg=38;2;255;77;166:*.mjpeg=38;2;255;77;166:*.gif=38;2;255;77;166:*.bmp=38;2;255;77;166:*.pbm=38;2;255;77;166:*.pgm=38;2;255;77;166:*.ppm=38;2;255;77;166:*.tga=38;2;255;77;166:*.xbm=38;2;255;77;166:*.xpm=38;2;255;77;166:*.tif=38;2;255;77;166:*.tiff=38;2;255;77;166:*.png=38;2;255;77;166:*.svg=38;2;255;77;166:*.svgz=38;2;255;77;166:*.mng=38;2;255;77;166:*.pcx=38;2;255;77;166:*.webp=38;2;255;77;166:*.avif=38;2;255;77;166:*.ico=38;2;255;77;166:*.mov=38;2;201;160;255:*.mpg=38;2;201;160;255:*.mpeg=38;2;201;160;255:*.m2v=38;2;201;160;255:*.mkv=38;2;201;160;255:*.webm=38;2;201;160;255:*.ogm=38;2;201;160;255:*.mp4=38;2;201;160;255:*.m4v=38;2;201;160;255:*.mp4v=38;2;201;160;255:*.vob=38;2;201;160;255:*.qt=38;2;201;160;255:*.nuv=38;2;201;160;255:*.wmv=38;2;201;160;255:*.asf=38;2;201;160;255:*.rm=38;2;201;160;255:*.rmvb=38;2;201;160;255:*.flc=38;2;201;160;255:*.avi=38;2;201;160;255:*.fli=38;2;201;160;255:*.flv=38;2;201;160;255:*.gl=38;2;201;160;255:*.dl=38;2;201;160;255:*.xcf=38;2;201;160;255:*.xwd=38;2;201;160;255:*.yuv=38;2;201;160;255:*.cgm=38;2;201;160;255:*.emf=38;2;201;160;255:*.ogv=38;2;201;160;255:*.aac=38;2;164;180;255:*.au=38;2;164;180;255:*.flac=38;2;164;180;255:*.m4a=38;2;164;180;255:*.mid=38;2;164;180;255:*.midi=38;2;164;180;255:*.mka=38;2;164;180;255:*.mp3=38;2;164;180;255:*.mpc=38;2;164;180;255:*.ogg=38;2;164;180;255:*.ra=38;2;164;180;255:*.wav=38;2;164;180;255:*.oga=38;2;164;180;255:*.opus=38;2;164;180;255:*.spx=38;2;164;180;255:*.xspf=38;2;164;180;255:*.pdf=38;2;242;92;122:*.doc=38;2;154;219;168:*.docx=38;2;154;219;168:*.xls=38;2;154;219;168:*.xlsx=38;2;154;219;168:*.ppt=38;2;154;219;168:*.pptx=38;2;154;219;168:*.odt=38;2;154;219;168:*.ods=38;2;154;219;168:*.odp=38;2;154;219;168:*.md=38;2;154;219;168:*.json=38;2;154;219;168:*.yaml=38;2;154;219;168:*.yml=38;2;154;219;168:*.toml=38;2;154;219;168:*.xml=38;2;154;219;168:*.csv=38;2;154;219;168:*.js=38;2;154;219;168:*.ts=38;2;154;219;168:*.py=38;2;154;219;168:*.rs=38;2;154;219;168:*.go=38;2;154;219;168:*.sh=38;2;154;219;168:*.bash=38;2;154;219;168:*.zsh=38;2;154;219;168:*.fish=38;2;154;219;168:*.c=38;2;154;219;168:*.cpp=38;2;154;219;168:*.h=38;2;154;219;168:*.hpp=38;2;154;219;168:*.java=38;2;154;219;168:*.css=38;2;154;219;168:*.scss=38;2;154;219;168:*.html=38;2;154;219;168:*.vue=38;2;154;219;168:*.svelte=38;2;154;219;168:*.tsx=38;2;154;219;168:*.jsx=38;2;154;219;168:*.sql=38;2;154;219;168:*.lua=38;2;154;219;168:*.rb=38;2;154;219;168:*.php=38;2;154;219;168:*.swift=38;2;154;219;168:*.kt=38;2;154;219;168:*.bak=38;2;113;102;134:*.old=38;2;113;102;134:*.orig=38;2;113;102;134:*.swp=38;2;113;102;134:*~=38;2;113;102;134:*.tmp=38;2;113;102;134:*.log=38;2;113;102;134:*.lock=38;2;154;143;173:*.env=38;2;232;200;122:*.env.example=38;2;154;143;173:*.gitignore=38;2;154;143;173:*.dockerignore=38;2;154;143;173:*.editorconfig=38;2;154;143;173
-e 's/38;2;137;180;250/38;2;231;156;254/g' \ LSCOLORS
-e 's/48;2;137;180;250/48;2;231;156;254/g' \
-e 's/38;2;245;194;231/38;2;255;121;198/g' \
-e 's/48;2;245;194;231/48;2;255;121;198/g' \
-e 's/38;2;116;199;236/38;2;139;233;253/g' \
-e 's/48;2;116;199;236/48;2;139;233;253/g' \
-e 's/38;2;88;91;112/38;2;127;132;156/g' \
-e 's/48;2;88;91;112/48;2;127;132;156/g' \
-e 's/38;2;30;30;46/38;2;52;28;74/g' \
-e 's/48;2;30;30;46/48;2;52;28;74/g' \
-e 's/38;2;49;50;68/38;2;61;36;84/g' \
-e 's/48;2;49;50;68/48;2;61;36;84/g' \
-e 's/38;2;203;166;247/38;2;231;156;254/g' \
-e 's/48;2;203;166;247/48;2;231;156;254/g' \
-e 's/38;2;205;214;244/38;2;248;248;242/g' \
-e 's/38;2;180;190;254/38;2;231;156;254/g' \
-e 's/38;2;148;226;213/38;2;139;233;253/g'

View File

@@ -1,32 +1,32 @@
/* ── violet-chaton rofi theme ─────────────────────────────────────────────── */ /* ── violet-chaton v2 rofi theme ──────────────────────────────────────────── */
* { * {
bg0: #261537; bg0: #1a0e27;
bg1: #341c4a; bg1: #261537;
surface: #493161; surface: #493161;
pink: #ff79c6; magenta: #ff4da6;
purple: #e79cfe; lilac: #c9a0ff;
cyan: #8be9fd; lavande: #a4b4ff;
text: #f8f8f2; text: #f0eaf8;
muted: #6c7086; muted: #716686;
overlay: #9399b2; subtext0: #9a8fad;
background-color: transparent; background-color: transparent;
text-color: @text; text-color: @text;
} }
/* ── Fenêtre — positionnée sous les pills ─────────────────────────────────── */ /* ── Fenetre ─────────────────────────────────────────────────────────────── */
window { window {
background-color: rgba(38, 21, 55, 0.94); background-color: rgba(26, 14, 39, 0.94);
border: 2px; border: 2px;
border-color: rgba(255, 121, 198, 0.38); border-color: rgba(255, 77, 166, 0.38);
border-radius: 14px; border-radius: 14px;
width: 500px; width: 500px;
padding: 0px; padding: 0px;
} }
/* ── Layout — résultats en haut, recherche en bas ────────────────────────── */ /* ── Layout — resultats en haut, recherche en bas ────────────────────────── */
mainbox { mainbox {
background-color: transparent; background-color: transparent;
@@ -35,7 +35,7 @@ mainbox {
children: [ listview, inputbar ]; children: [ listview, inputbar ];
} }
/* ── Liste des résultats ─────────────────────────────────────────────────── */ /* ── Liste des resultats ─────────────────────────────────────────────────── */
listview { listview {
background-color: transparent; background-color: transparent;
@@ -56,15 +56,15 @@ element {
} }
element selected { element selected {
background-color: rgba(255, 121, 198, 0.16); background-color: rgba(255, 77, 166, 0.16);
border: 1px; border: 1px;
border-color: rgba(255, 121, 198, 0.32); border-color: rgba(255, 77, 166, 0.32);
} }
element hover { element hover {
background-color: rgba(255, 121, 198, 0.16); background-color: rgba(255, 77, 166, 0.16);
border: 1px; border: 1px;
border-color: rgba(255, 121, 198, 0.32); border-color: rgba(255, 77, 166, 0.32);
} }
element-icon { element-icon {
@@ -80,20 +80,20 @@ element-text {
} }
element-text selected { element-text selected {
text-color: @pink; text-color: @magenta;
} }
element-text hover { element-text hover {
text-color: @pink; text-color: @magenta;
} }
/* ── Séparateur visuel avant la recherche ─────────────────────────────────── */ /* ── Barre de recherche ──────────────────────────────────────────────────── */
inputbar { inputbar {
background-color: rgba(52, 28, 74, 0.75); background-color: rgba(38, 21, 55, 0.75);
border-radius: 0 0 12px 12px; border-radius: 0 0 12px 12px;
border: 1px; border: 1px;
border-color: rgba(92, 73, 108, 0.50); border-color: rgba(90, 56, 117, 0.50);
padding: 9px 14px; padding: 9px 14px;
spacing: 8px; spacing: 8px;
children: [ prompt, entry ]; children: [ prompt, entry ];
@@ -101,30 +101,30 @@ inputbar {
prompt { prompt {
background-color: transparent; background-color: transparent;
text-color: @pink; text-color: @magenta;
font: "JetBrainsMono Nerd Font Bold 14"; font: "Maple Mono NF Bold 14";
vertical-align: 0.5; vertical-align: 0.5;
} }
entry { entry {
background-color: transparent; background-color: transparent;
text-color: @text; text-color: @text;
placeholder: "Rechercher une application..."; placeholder: "Rechercher...";
placeholder-color: @muted; placeholder-color: @muted;
vertical-align: 0.5; vertical-align: 0.5;
} }
/* ── Scrollbar ───────────────────────────────────────────────────────────── */ /* ── Scrollbar ───────────────────────────────────────────────────────────── */
scrollbar { scrollbar {
background-color: rgba(92, 73, 108, 0.30); background-color: rgba(90, 56, 117, 0.30);
handle-color: rgba(255, 121, 198, 0.40); handle-color: rgba(255, 77, 166, 0.40);
handle-width: 4px; handle-width: 4px;
border-radius: 2px; border-radius: 2px;
padding: 0; padding: 0;
} }
/* ── Messages ────────────────────────────────────────────────────────────── */ /* ── Messages ────────────────────────────────────────────────────────────── */
message { message {
background-color: transparent; background-color: transparent;
@@ -132,6 +132,6 @@ message {
} }
textbox { textbox {
text-color: @overlay; text-color: @subtext0;
background-color: transparent; background-color: transparent;
} }

View File

@@ -4,20 +4,20 @@
"accentOnWindow": true, "accentOnWindow": true,
"accentSaturationLimit": 1, "accentSaturationLimit": 1,
"alpha": 1, "alpha": 1,
"backgroundImage": "/resources/bg_pawel-czerwinski-Xk7ktUfyaNI-unsplash.webp", "backgroundImage": "",
"backgroundPosition": "stretch", "backgroundPosition": "stretch",
"backgroundSource": "", "backgroundSource": "",
"blur": 0, "blur": 0,
"colorAccentBg": "#2c183e", "colorAccentBg": "#1a0e27",
"colorBg": "#341c4a", "colorBg": "#261537",
"colorFg": "#d3d9e3", "colorFg": "#f0eaf8",
"colorHighlightBg": "#b68fdc", "colorHighlightBg": "#c9a0ff",
"colorWindowBg": "#1D1E21", "colorWindowBg": "#1a0e27",
"contrast": 0, "contrast": 0,
"dimBlurred": false, "dimBlurred": false,
"engineVersion": 1, "engineVersion": 1,
"id": "11455bed-3b48-4de5-9a03-a83a1b4be775", "id": "11455bed-3b48-4de5-9a03-a83a1b4be775",
"name": "Rice Violet-Chaton", "name": "Violet-Chaton v2",
"preferSystemAccent": false, "preferSystemAccent": false,
"radius": 14, "radius": 14,
"simpleScrollbar": true, "simpleScrollbar": true,

View File

@@ -1,96 +1,96 @@
# violet-chaton — thème yazi # violet-chaton v2 — theme yazi
[mgr] [mgr]
cwd = { fg = "#e79cfe" } # purple — dossier courant cwd = { fg = "#c9a0ff" }
find_keyword = { fg = "#f9e2af", bold = true, italic = true, underline = true } find_keyword = { fg = "#e8c87a", bold = true, italic = true, underline = true }
find_position = { fg = "#ff79c6", bg = "reset", bold = true, italic = true } find_position = { fg = "#ff4da6", bg = "reset", bold = true, italic = true }
marker_copied = { fg = "#8be9fd", bg = "#8be9fd" } # cyan marker_copied = { fg = "#a4b4ff", bg = "#a4b4ff" }
marker_cut = { fg = "#f38ba8", bg = "#f38ba8" } # danger marker_cut = { fg = "#f25c7a", bg = "#f25c7a" }
marker_marked = { fg = "#e79cfe", bg = "#e79cfe" } # purple marker_marked = { fg = "#c9a0ff", bg = "#c9a0ff" }
marker_selected = { fg = "#ff79c6", bg = "#ff79c6" } # pink marker_selected = { fg = "#ff4da6", bg = "#ff4da6" }
count_copied = { fg = "#261537", bg = "#8be9fd" } count_copied = { fg = "#261537", bg = "#a4b4ff" }
count_cut = { fg = "#261537", bg = "#f38ba8" } count_cut = { fg = "#261537", bg = "#f25c7a" }
count_selected = { fg = "#261537", bg = "#ff79c6" } count_selected = { fg = "#261537", bg = "#ff4da6" }
border_symbol = "│" border_symbol = "│"
border_style = { fg = "#6c7086" } border_style = { fg = "#716686" }
[tabs] [tabs]
active = { fg = "#261537", bg = "#ff79c6", bold = true } active = { fg = "#261537", bg = "#ff4da6", bold = true }
inactive = { fg = "#ff79c6", bg = "#3d2454" } inactive = { fg = "#ff4da6", bg = "#3d2454" }
[mode] [mode]
normal_main = { fg = "#261537", bg = "#ff79c6", bold = true } normal_main = { fg = "#261537", bg = "#ff4da6", bold = true }
normal_alt = { fg = "#ff79c6", bg = "#3d2454" } normal_alt = { fg = "#ff4da6", bg = "#3d2454" }
select_main = { fg = "#261537", bg = "#8be9fd", bold = true } select_main = { fg = "#261537", bg = "#a4b4ff", bold = true }
select_alt = { fg = "#8be9fd", bg = "#3d2454" } select_alt = { fg = "#a4b4ff", bg = "#3d2454" }
unset_main = { fg = "#261537", bg = "#e79cfe", bold = true } unset_main = { fg = "#261537", bg = "#c9a0ff", bold = true }
unset_alt = { fg = "#e79cfe", bg = "#3d2454" } unset_alt = { fg = "#c9a0ff", bg = "#3d2454" }
[status] [status]
perm_sep = { fg = "#6c7086" } perm_sep = { fg = "#716686" }
perm_type = { fg = "#e79cfe" } # purple perm_type = { fg = "#c9a0ff" }
perm_read = { fg = "#8be9fd" } # cyan perm_read = { fg = "#a4b4ff" }
perm_write = { fg = "#ff79c6" } # pink perm_write = { fg = "#ff4da6" }
perm_exec = { fg = "#a6e3a1" } # green perm_exec = { fg = "#9adba8" }
progress_label = { fg = "#f8f8f2", bold = true } progress_label = { fg = "#f0eaf8", bold = true }
progress_normal = { fg = "#8be9fd", bg = "#3d2454" } progress_normal = { fg = "#a4b4ff", bg = "#3d2454" }
progress_error = { fg = "#f38ba8", bg = "#3d2454" } progress_error = { fg = "#f25c7a", bg = "#3d2454" }
[pick] [pick]
border = { fg = "#ff79c6" } border = { fg = "#ff4da6" }
active = { fg = "#e79cfe", bold = true } active = { fg = "#c9a0ff", bold = true }
inactive = {} inactive = {}
[input] [input]
border = { fg = "#ff79c6" } border = { fg = "#ff4da6" }
title = { fg = "#e79cfe" } title = { fg = "#c9a0ff" }
value = { fg = "#f8f8f2" } value = { fg = "#f0eaf8" }
selected = { reversed = true } selected = { reversed = true }
[completion] [completion]
border = { fg = "#8be9fd" } border = { fg = "#a4b4ff" }
active = { fg = "#ff79c6", bold = true } active = { fg = "#ff4da6", bold = true }
inactive = { fg = "#6c7086" } inactive = { fg = "#716686" }
[tasks] [tasks]
border = { fg = "#ff79c6" } border = { fg = "#ff4da6" }
title = { fg = "#e79cfe" } title = { fg = "#c9a0ff" }
hovered = { fg = "#ff79c6", underline = true } hovered = { fg = "#ff4da6", underline = true }
[which] [which]
mask = { bg = "#261537" } mask = { bg = "#261537" }
cands = { fg = "#8be9fd" } cands = { fg = "#a4b4ff" }
rest = { fg = "#6c7086" } rest = { fg = "#716686" }
desc = { fg = "#e79cfe" } desc = { fg = "#c9a0ff" }
separator = " " separator = " "
separator_style = { fg = "#6c7086" } separator_style = { fg = "#716686" }
[help] [help]
on = { fg = "#ff79c6" } on = { fg = "#ff4da6" }
run = { fg = "#8be9fd" } run = { fg = "#a4b4ff" }
desc = { fg = "#f8f8f2" } desc = { fg = "#f0eaf8" }
hovered = { bg = "#3d2454", bold = true } hovered = { bg = "#3d2454", bold = true }
footer = { fg = "#261537", bg = "#e79cfe" } footer = { fg = "#261537", bg = "#c9a0ff" }
[notify] [notify]
title_info = { fg = "#8be9fd" } title_info = { fg = "#a4b4ff" }
title_warn = { fg = "#f9e2af" } title_warn = { fg = "#e8c87a" }
title_error = { fg = "#f38ba8" } title_error = { fg = "#f25c7a" }
[filetype] [filetype]
rules = [ rules = [
{ mime = "image/*", style = { fg = "#ff79c6" } }, { mime = "image/*", style = { fg = "#ff4da6" } },
{ mime = "video/*", style = { fg = "#e79cfe" } }, { mime = "video/*", style = { fg = "#c9a0ff" } },
{ mime = "audio/*", style = { fg = "#8be9fd" } }, { mime = "audio/*", style = { fg = "#a4b4ff" } },
{ mime = "application/zip", style = { fg = "#f9e2af" } }, { mime = "application/zip", style = { fg = "#e8c87a" } },
{ mime = "application/x-tar", style = { fg = "#f9e2af" } }, { mime = "application/x-tar", style = { fg = "#e8c87a" } },
{ mime = "application/pdf", style = { fg = "#f38ba8" } }, { mime = "application/pdf", style = { fg = "#f25c7a" } },
{ mime = "text/*", style = { fg = "#f8f8f2" } }, { mime = "text/*", style = { fg = "#f0eaf8" } },
] ]

221
README.md
View File

@@ -1,8 +1,17 @@
# violet-chaton # violet-chaton v2
> Rice Pop!_OS complet aux couleurs violet-chaton — compatible **COSMIC** et **Hyprland** > Rice Pop!\_OS complet — palette originale, zero emprunt.
> Compatible **COSMIC** et **Hyprland**.
![preview](assets/preview.png) ![preview](INSTALL/assets/violet-chaton-logo.png)
---
## Philosophie
Palette 100% originale inspiree du gradient de **Mitsuri Kanroji** (rose → vert pastel).
Fond violet profond signature, 5 accents uniques, variantes dark + light.
Source de verite unique : `INSTALL/themes/palette.sh`
--- ---
@@ -14,73 +23,179 @@ cd dotfiles-violet-chaton
bash INSTALL/install.sh bash INSTALL/install.sh
``` ```
Choisir **1** (complète) ou **4** (configs uniquement si les outils sont déjà là). Choisir **1** (complete) ou **4** (configs uniquement si les outils sont deja la).
Prérequis : `sudo apt install -y curl git unzip`
Prerequis : `sudo apt install -y curl git unzip`
--- ---
## Ce que tu obtiens ## Ce que tu obtiens
**Shell** — zsh · starship · atuin · zinit · autosuggestions · syntax-highlighting ### Terminal
**CLI**eza · bat · fd · fzf · zoxide · ripgrep · lazygit · delta · yazi · btop - **kitty** — GPU-accelerated, ligatures, cursor trail magenta, splits tiling, GLSL shader glow
**Terminal**fastfetch avec sprite Pokémon via chafa · LS_COLORS patché depuis catppuccin-mocha via vivid · cava · pipes.sh - **Maple Mono NF** — italiques cursives, ligatures, fine et niche
**Desktop** — Waybar 3-pills glassmorphism · Wofi · Rofi · wob (OSD volume/luminosité)
**Polices** — JetBrainsMono NL + 0xProto Nerd Fonts · icônes candy-icons ### Shell
**Apps** — Vivaldi (thème injecté auto) · Vesktop/Discord · Nemo · GTK3/GTK4 - **zsh** + zinit + autosuggestions + syntax-highlighting (palette v2)
- **starship** 3 lignes — separateur style, prompt signature, brain\_name env var
- **vi-mode** — beam/block cursor adaptatif, keybindings emacs preserves
- **atuin** — historique shell fuzzy
### Outils CLI
| Outil | Remplace | Description |
|-------|----------|-------------|
| `eza` | ls | Listing colore avec icones |
| `bat` | cat | Coloration syntaxique + theme v2 |
| `fd` | find | Recherche de fichiers |
| `fzf` | — | Fuzzy finder (fichiers, dossiers, git log, process killer) |
| `zoxide` | cd | Navigation intelligente |
| `ripgrep` | grep | Recherche dans les fichiers |
| `lazygit` | — | Git TUI avec couleurs v2 |
| `delta` | diff | Diffs colores side-by-side |
| `yazi` | — | Explorateur fichiers TUI + preview images kitty |
| `btop` | top | Monitoring systeme avec theme v2 |
| `dust` | du/ncdu | Analyse disque |
| `procs` | ps | Process viewer |
| `tokei` | — | Stats code par langage |
| `sd` | sed | Remplacement simplifie |
| `hyperfine` | time | Benchmarks CLI |
| `gping` | ping | Ping avec graphe |
### Desktop
- **AGS** (Aylur's GTK Shell) — barre 3-pills glassmorphism, OSD gradient Mitsuri, launcher, notifications
- **Rofi** — backup launcher avec theme v2
- Detection auto compositor (Hyprland = workspaces, COSMIC = mode compatible)
### Theming
- **COSMIC** Dark + Light — palette v2 complete (accent, background, primary, semantiques)
- **COSMIC Term** — Maple Mono NF + color schemes dark/light
- **GTK3/GTK4** — dark + light css
- **Vivaldi** — theme injecte automatiquement
- **Vesktop/Discord** — theme css
- Candy-icons
--- ---
## COSMIC ## Palette v2
Déploiement automatique complet : ### Dark
- Thème COSMIC Dark/Light — palette violet-chaton | | Hex | Role |
- CosmicTerm — police, couleurs, profil
- CosmicTk — polices UI + icônes candy-icons
- `cosmic-osd` désactivé, remplacé par `wob`
- Waybar + autostart configurés
---
## Hyprland
Les configs shell, waybar, wofi, rofi, kitty et zsh fonctionnent **tels quels** sous Hyprland.
Ce qui reste à câbler côté Hyprland :
```
hyprland.conf — keybinds, moniteurs, règles fenêtres
hyprpaper / swww — fond d'écran
hyprlock — écran de verrouillage
mako — notifications
```
> Ces configs ne sont pas (encore) dans le repo — les contributions sont les bienvenues.
---
## Palette
| | Hex | Rôle |
|-|-----|------| |-|-----|------|
| ![#261537](https://placehold.co/12x12/261537/261537.png) | `#261537` | Background | | ![#261537](https://placehold.co/12x12/261537/261537.png) | `#261537` | base — fond principal |
| ![#341c4a](https://placehold.co/12x12/341c4a/341c4a.png) | `#341c4a` | BG medium | | ![#341c4a](https://placehold.co/12x12/341c4a/341c4a.png) | `#341c4a` | mantle |
| ![#3d2454](https://placehold.co/12x12/3d2454/3d2454.png) | `#3d2454` | BG high · sélection | | ![#3d2454](https://placehold.co/12x12/3d2454/3d2454.png) | `#3d2454` | surface0 |
| ![#ff79c6](https://placehold.co/12x12/ff79c6/ff79c6.png) | `#ff79c6` | Pink — accents · bordures | | ![#5a3875](https://placehold.co/12x12/5a3875/5a3875.png) | `#5a3875` | surface2 — selection |
| ![#e79cfe](https://placehold.co/12x12/e79cfe/e79cfe.png) | `#e79cfe` | Purple — accents secondaires | | ![#ff4da6](https://placehold.co/12x12/ff4da6/ff4da6.png) | `#ff4da6` | magenta — accent primaire |
| ![#8be9fd](https://placehold.co/12x12/8be9fd/8be9fd.png) | `#8be9fd` | Cyan — commandes · highlights | | ![#c9a0ff](https://placehold.co/12x12/c9a0ff/c9a0ff.png) | `#c9a0ff` | lilac — accent secondaire |
| ![#f8f8f2](https://placehold.co/12x12/f8f8f2/f8f8f2.png) | `#f8f8f2` | Text | | ![#9adba8](https://placehold.co/12x12/9adba8/9adba8.png) | `#9adba8` | mitsuri — vert pastel / success |
| ![#a4b4ff](https://placehold.co/12x12/a4b4ff/a4b4ff.png) | `#a4b4ff` | lavande — bleu-violet / info |
| ![#e8c87a](https://placehold.co/12x12/e8c87a/e8c87a.png) | `#e8c87a` | champagne — or chaud / warning |
| ![#f25c7a](https://placehold.co/12x12/f25c7a/f25c7a.png) | `#f25c7a` | danger |
| ![#f0eaf8](https://placehold.co/12x12/f0eaf8/f0eaf8.png) | `#f0eaf8` | text |
| ![#716686](https://placehold.co/12x12/716686/716686.png) | `#716686` | muted |
### Gradient signature
```
magenta → lilac → lavande → mitsuri
#ff4da6 → #c9a0ff → #a4b4ff → #9adba8
```
### Light
Fonds lavande clairs (`#f3edf8`), accents assombris pour contraste WCAG.
Meme identite violet, meme gradient. Voir `palette.sh` section LIGHT.
--- ---
## Raccourcis ## Raccourcis kitty
| Touche | Action | | Touche | Action |
|--------|--------| |--------|--------|
| `Ctrl+R` | Historique atuin | | `Ctrl+Shift+\` | Split vertical |
| `Ctrl+G` | Fichier (fzf) | | `Ctrl+Shift+-` | Split horizontal |
| `Ctrl+F` | Dossier (fzf) | | `Ctrl+Shift+Z` | Zoom (stack toggle) |
| `Ctrl+Shift+←→↑↓` | Naviguer entre splits |
| `Ctrl+Shift+1-5` | Layouts (tall/fat/grid/h/v) |
| `Ctrl+Shift+T` | Nouvel onglet |
| `Ctrl+Shift+W` | Fermer onglet |
| `Ctrl+Shift+R` | Redimensionner split |
| `Ctrl+V` | Coller |
| `Ctrl+C` | Copier / interrompre |
## Raccourcis shell
| Touche | Action |
|--------|--------|
| `Ctrl+G` | fzf fichier |
| `Ctrl+F` | fzf dossier |
| `Ctrl+R` | Historique (atuin) |
| `Ctrl+Space` | Accepter suggestion | | `Ctrl+Space` | Accepter suggestion |
| `Escape` | Vi normal mode |
| `i` | Retour insert |
## Alias clés ## Commandes custom
`ls` → eza · `cat` → bat · `fd` → fdfind · `man` → tldr · `lg` → lazygit · `disk` → ncdu · `fetch` → fastfetch+chafa | Commande | Description |
|----------|-------------|
| `colors` | Affiche la palette v2 |
| `hotkeys` | Cheatsheet raccourcis |
| `proj` | Project switcher fzf dans ~/Dev |
| `glog` | Git log fzf avec preview |
| `fkill` | Process killer fzf |
| `y` | Yazi (cd au dossier visite) |
| `weather [ville]` | Meteo rapide |
## Alias
| Alias | Commande reelle |
|-------|-----------------|
| `ls` | eza --icons |
| `ll` | eza -l --icons --git |
| `la` | eza -la --icons --git |
| `lt` | eza --tree --level=3 |
| `cat` | bat (sans pager) |
| `bat` | batcat |
| `fd` | fdfind |
| `lg` | lazygit |
| `tl` | tldr |
| `disk` | dust |
| `top` | btop |
| `fetch` | fastfetch + chafa logo |
---
## Structure
```
INSTALL/
install.sh — point d'entree (menu interactif)
scripts/
lib.sh — fonctions partagees (couleurs palette v2)
01-packages-apt.sh — paquets apt
02-packages-manual.sh — binaires GitHub + fonts + kitty + AGS
03-deploy-configs.sh — deploy configs + themes + COSMIC + GTK
configs/
zshrc — shell config
starship.toml — prompt 3 lignes
kitty.conf — terminal + cursor trail + splits
kitty/violet-chaton-glow.glsl — shader glow optionnel
ags/ — AGS bar + OSD + launcher + notifications
...
themes/
palette.sh — SOURCE DE VERITE UNIQUE
violet-chaton-*.{css,toml,theme,rasi,json,sh,tmTheme}
cosmic/ — COSMIC Dark + Light + Term + Tk
assets/
violet-chaton-logo.png
```
---
## Credits
- Palette : originale, inspiree Mitsuri Kanroji (Demon Slayer)
- Font : [Maple Mono NF](https://github.com/subframe7536/maple-font)
- Icones : [candy-icons](https://github.com/EliverLara/candy-icons)
- Shell : [AGS](https://github.com/Aylur/ags) · [starship](https://starship.rs) · [kitty](https://sw.kovidgoyal.net/kitty/)

461
ags-v1/config.js Normal file
View File

@@ -0,0 +1,461 @@
// ── violet-chaton v2 — AGS config ───────────────────────────────────────────
// Barre + OSD + Launcher + Notifications
// API: AGS v1.8.2 (.hook/.bind/.poll — no connections)
const audio = await Service.import("audio");
const battery = await Service.import("battery");
const network = await Service.import("network");
const systemtray = await Service.import("systemtray");
const mpris = await Service.import("mpris");
const notifications = await Service.import("notifications");
const applications = await Service.import("applications");
// ── Compositor detection ────────────────────────────────────────────────────
const compositor = (() => {
const session = Utils.exec("bash -c 'echo $XDG_CURRENT_DESKTOP'").trim();
if (session.includes("Hyprland")) return "hyprland";
if (session.includes("COSMIC")) return "cosmic";
return "unknown";
})();
print(`[violet-chaton] compositor: ${compositor}`);
// ══════════════════════════════════════════════════════════════════════════════
// BAR
// ══════════════════════════════════════════════════════════════════════════════
const Separator = () => Widget.Label({ className: "separator", label: "│" });
const Clock = () => Widget.Label({ className: "clock" })
.poll(1000, (self) => { self.label = Utils.exec("date +%H:%M"); });
const DateWidget = () => Widget.Label({ className: "date" })
.poll(60000, (self) => { self.label = Utils.exec("date '+%a %d %b'"); });
const CPU = () => Widget.Label({ className: "cpu" })
.poll(2000, (self) => {
const usage = Math.round(
Number(Utils.exec(['bash', '-c', "top -bn1 | awk '/^%Cpu/ {print 100-$8}'"]))
);
self.label = `󰻠 ${usage}%`;
self.toggleClassName("warning", usage > 70);
self.toggleClassName("critical", usage > 90);
});
const RAM = () => Widget.Label({ className: "ram" })
.poll(2000, (self) => {
const used = Utils.exec(['bash', '-c', "free -m | awk '/^Mem:/ {printf \"%.1f\", $3/1024}'"]);
const total = Utils.exec(['bash', '-c', "free -m | awk '/^Mem:/ {printf \"%.1f\", $2/1024}'"]);
const pct = Math.round((parseFloat(used) / parseFloat(total)) * 100);
self.label = `󰑭 ${used}G`;
self.toggleClassName("warning", pct > 70);
self.toggleClassName("critical", pct > 90);
});
const Network = () => Widget.Label({ className: "network" })
.hook(network, (self) => {
if (network.primary === "wifi") {
const wifi = network.wifi;
self.label = `󰤨 ${wifi?.ssid || ""}`;
self.toggleClassName("wifi", true);
self.toggleClassName("disconnected", false);
} else if (network.primary === "wired") {
self.label = "󰈀 Eth";
self.toggleClassName("wifi", false);
self.toggleClassName("disconnected", false);
} else {
self.label = "󰤮 ";
self.toggleClassName("disconnected", true);
}
});
const Volume = () => Widget.Button({
className: "volume",
onClicked: () => { audio.speaker.isMuted = !audio.speaker.isMuted; },
child: Widget.Label()
.hook(audio, (self) => {
const vol = Math.round((audio.speaker?.volume || 0) * 100);
const muted = audio.speaker?.isMuted;
const icon = muted ? "󰝟" : vol > 66 ? "󰕾" : vol > 33 ? "󰖀" : "󰕿";
self.label = `${icon} ${vol}%`;
self.parent?.toggleClassName("muted", muted);
}, "speaker-changed"),
});
const Battery = () => Widget.Label({
className: "battery",
visible: battery.bind("available"),
}).hook(battery, (self) => {
const pct = battery.percent;
const charging = battery.charging;
const icon = charging ? "󰂄" : pct > 80 ? "󰁹" : pct > 60 ? "󰂀" :
pct > 40 ? "󰁾" : pct > 20 ? "󰁻" : "󰂎";
self.label = `${icon} ${pct}%`;
self.toggleClassName("charging", charging);
self.toggleClassName("low", pct <= 20 && !charging);
self.toggleClassName("warning", pct <= 30 && !charging);
});
const Media = () => Widget.Label({ className: "media" })
.hook(mpris, (self) => {
const player = mpris.players[0];
if (!player) {
self.visible = false;
return;
}
self.visible = true;
const artist = player.trackArtists?.join(", ") || "";
const title = player.trackTitle || "";
const icon = player.playBackStatus === "Playing" ? " " : " ";
self.label = `${icon}${artist ? artist + " — " : ""}${title}`.slice(0, 50);
self.toggleClassName("paused", player.playBackStatus !== "Playing");
});
const SysTray = () => Widget.Box({
className: "systray",
children: systemtray.bind("items").as((items) =>
items.map((item) =>
Widget.Button({
child: Widget.Icon({ icon: item.bind("icon"), size: 16 }),
tooltipMarkup: item.bind("tooltip-markup"),
onPrimaryClick: (_, event) => item.activate(event),
onSecondaryClick: (_, event) => item.openMenu(event),
})
)
),
});
const LauncherBtn = () => Widget.Button({
className: "launcher-btn",
label: "󱄅",
onClicked: () => App.toggleWindow("launcher"),
});
const PowerBtn = () => Widget.Button({
className: "power-btn",
label: "⏻",
onClicked: () => Utils.exec("bash -c 'systemctl poweroff'"),
});
const Workspaces = () => {
if (compositor !== "hyprland") return Widget.Box({});
// Hyprland not running — return empty
return Widget.Box({});
};
const Bar = (monitor) => Widget.Window({
name: `bar-${monitor}`,
monitor,
anchor: ["top", "left", "right"],
exclusivity: "exclusive",
className: "bar",
child: Widget.CenterBox({
startWidget: Widget.Box({
className: "modules-left",
children: [
LauncherBtn(),
Separator(),
Workspaces(),
CPU(),
RAM(),
],
}),
centerWidget: Widget.Box({
className: "modules-center",
children: [
Media(),
],
}),
endWidget: Widget.Box({
className: "modules-right",
hpack: "end",
children: [
Network(),
Separator(),
Volume(),
Separator(),
Battery(),
Separator(),
DateWidget(),
Clock(),
Separator(),
SysTray(),
Separator(),
PowerBtn(),
],
}),
}),
});
// ══════════════════════════════════════════════════════════════════════════════
// OSD
// ══════════════════════════════════════════════════════════════════════════════
const VolumeOSD = () => {
const icon = Widget.Label({ className: "icon" });
const progress = Widget.ProgressBar();
const label = Widget.Label({ className: "label" });
return Widget.Box({
className: "osd",
children: [icon, progress, label],
}).hook(audio, (self) => {
const vol = audio.speaker?.volume || 0;
const muted = audio.speaker?.isMuted;
icon.label = muted ? "󰝟" : vol > 0.66 ? "󰕾" : vol > 0.33 ? "󰖀" : "󰕿";
progress.value = vol;
label.label = `${Math.round(vol * 100)}%`;
}, "speaker-changed");
};
const BrightnessOSD = () => {
const icon = Widget.Label({ className: "icon", label: "󰃞" });
const progress = Widget.ProgressBar();
const label = Widget.Label({ className: "label" });
const getBrightness = () => {
try {
const max = Number(Utils.exec("brightnessctl max"));
const cur = Number(Utils.exec("brightnessctl get"));
return max > 0 ? cur / max : 0;
} catch {
return 0;
}
};
return Widget.Box({
className: "osd",
children: [icon, progress, label],
}).poll(500, (self) => {
const val = getBrightness();
progress.value = val;
label.label = `${Math.round(val * 100)}%`;
});
};
const OSD = (monitor) => [
Widget.Window({
name: `osd-volume-${monitor}`,
monitor,
anchor: ["bottom"],
layer: "overlay",
visible: false,
child: VolumeOSD(),
}),
Widget.Window({
name: `osd-brightness-${monitor}`,
monitor,
anchor: ["bottom"],
layer: "overlay",
visible: false,
child: BrightnessOSD(),
}),
];
// ══════════════════════════════════════════════════════════════════════════════
// LAUNCHER
// ══════════════════════════════════════════════════════════════════════════════
const AppItem = (app) => Widget.Button({
className: "app-item",
onClicked: () => {
app.launch();
App.closeWindow("launcher");
},
child: Widget.Box({
children: [
Widget.Icon({ icon: app.iconName || "application-x-executable", size: 24 }),
Widget.Box({
vertical: true,
children: [
Widget.Label({ label: app.name, xalign: 0, truncate: "end" }),
Widget.Label({
label: app.description || "",
xalign: 0,
truncate: "end",
css: "color: #716686; font-size: 11px; font-weight: normal;",
}),
],
}),
],
}),
});
const Launcher = (monitor) => {
let apps = applications.list;
const list = Widget.Box({ vertical: true, spacing: 2 });
const entry = Widget.Entry({
className: "search",
placeholderText: "Rechercher...",
onAccept: () => {
const first = apps[0];
if (first) {
first.launch();
App.closeWindow("launcher");
}
},
onChange: ({ text }) => {
apps = applications.query(text || "");
list.children = apps.slice(0, 12).map(AppItem);
if (apps.length === 0) {
list.children = [Widget.Label({
className: "no-results",
label: "Aucun resultat",
})];
}
},
});
return Widget.Window({
name: "launcher",
monitor,
anchor: ["top"],
layer: "overlay",
visible: false,
keymode: "exclusive",
setup: (self) => {
self.keybind("Escape", () => App.closeWindow("launcher"));
self.hook(App, (_, name, visible) => {
if (name === "launcher" && visible) {
entry.text = "";
apps = applications.list;
list.children = apps.slice(0, 12).map(AppItem);
entry.grab_focus();
}
});
},
child: Widget.Box({
className: "launcher",
vertical: true,
children: [
Widget.Scrollable({
hscroll: "never",
vscroll: "automatic",
css: "min-height: 400px;",
child: list,
}),
entry,
],
}),
});
};
// ══════════════════════════════════════════════════════════════════════════════
// NOTIFICATIONS
// ══════════════════════════════════════════════════════════════════════════════
notifications.popupTimeout = 5000;
notifications.cacheActions = true;
const NotificationIcon = (notif) => {
if (notif.image) {
return Widget.Box({
css: `
min-width: 48px; min-height: 48px;
background-image: url("${notif.image}");
background-size: cover;
background-position: center;
border-radius: 8px;
margin-right: 10px;
`,
});
}
return Widget.Icon({
icon: notif.appIcon || notif.appEntry || "dialog-information",
size: 36,
css: "margin-right: 10px;",
});
};
const Notification = (notif) => Widget.Box({
className: `notification ${notif.urgency}`,
vertical: true,
children: [
Widget.Box({
children: [
NotificationIcon(notif),
Widget.Box({
vertical: true,
hexpand: true,
children: [
Widget.Box({
children: [
Widget.Label({
className: "title",
label: notif.summary,
xalign: 0,
hexpand: true,
truncate: "end",
}),
Widget.Label({
className: "time",
label: new Date(notif.time * 1000)
.toLocaleTimeString("fr-FR", {
hour: "2-digit",
minute: "2-digit",
}),
}),
Widget.Button({
className: "close-btn",
label: "✕",
onClicked: () => notif.close(),
}),
],
}),
Widget.Label({
className: "app-name",
label: notif.appName || "",
xalign: 0,
}),
],
}),
],
}),
...(notif.body ? [Widget.Label({
className: "body",
label: notif.body,
xalign: 0,
wrap: true,
useMarkup: true,
})] : []),
...(notif.actions.length > 0 ? [Widget.Box({
className: "actions",
children: notif.actions.map((action) =>
Widget.Button({
label: action.label,
onClicked: () => notif.invoke(action.id),
})
),
})] : []),
],
});
const Notifications = (monitor) => Widget.Window({
name: `notifications-${monitor}`,
monitor,
anchor: ["top", "right"],
layer: "overlay",
child: Widget.Box({
vertical: true,
css: "min-width: 350px;",
children: notifications.bind("popups").as((popups) =>
popups.map(Notification)
),
}),
});
// ══════════════════════════════════════════════════════════════════════════════
// EXPORT
// ══════════════════════════════════════════════════════════════════════════════
export default {
style: `${App.configDir}/css/style.css`,
windows: [
Bar(0),
...OSD(0),
Launcher(0),
Notifications(0),
],
};

385
ags-v1/css/style.css Normal file
View File

@@ -0,0 +1,385 @@
/* ── violet-chaton v2 — AGS stylesheet ────────────────────────────────────────
*
* Palette :
* crust #1a0e27
* base #261537
* mantle #341c4a
* surface0 #3d2454
* surface1 #493161
* surface2 #5a3875
* magenta #ff4da6 accent primaire
* lilac #c9a0ff accent secondaire
* mitsuri #9adba8 vert pastel
* lavande #a4b4ff bleu-violet
* champagne #e8c87a or chaud
* danger #f25c7a
* text #f0eaf8
* subtext1 #c4b8d4
* subtext0 #9a8fad
* muted #716686
*
* ─────────────────────────────────────────────────────────────────────────── */
/* ── Reset ───────────────────────────────────────────────────────────────── */
* {
font-family: "Maple Mono NF", "MapleMono Nerd Font", monospace;
font-size: 13px;
font-weight: bold;
}
/* ══════════════════════════════════════════════════════════════════════════
* BAR — 3 pills glassmorphism (island floating)
* ══════════════════════════════════════════════════════════════════════════ */
.bar {
background: transparent;
}
.bar .modules-left,
.bar .modules-center,
.bar .modules-right {
background: alpha(#261537, 0.88);
border-radius: 14px;
border: 3px solid alpha(#ff4da6, 0.60);
margin: 8px 4px;
padding: 0 4px;
}
.bar .modules-left:hover,
.bar .modules-center:hover,
.bar .modules-right:hover {
border-color: #ff4da6;
box-shadow: 0 4px 28px alpha(#c9a0ff, 0.18);
}
/* ── Launcher button ─────────────────────────────────────────────────────── */
.bar .launcher-btn {
color: #ff4da6;
font-size: 19px;
padding: 0 14px 0 18px;
min-width: 0;
min-height: 0;
}
.bar .launcher-btn:hover {
color: #c9a0ff;
}
/* ── Separator ───────────────────────────────────────────────────────────── */
.bar .separator {
color: alpha(#f0eaf8, 0.12);
font-size: 11px;
padding: 0 4px;
font-weight: normal;
}
/* ── Clock ───────────────────────────────────────────────────────────────── */
.bar .clock {
color: #ff4da6;
font-weight: 900;
font-size: 14px;
letter-spacing: 0.04em;
padding: 0 10px;
}
.bar .clock:hover {
color: #c9a0ff;
}
/* ── Date ────────────────────────────────────────────────────────────────── */
.bar .date {
color: #a4b4ff;
font-size: 12px;
font-weight: normal;
padding: 0 10px 0 2px;
}
/* ── System modules ──────────────────────────────────────────────────────── */
.bar .cpu { color: #a4b4ff; }
.bar .cpu.warning { color: #e8c87a; }
.bar .cpu.critical { color: #f25c7a; }
.bar .ram { color: #ff4da6; }
.bar .ram.warning { color: #e8c87a; }
.bar .ram.critical { color: #f25c7a; }
.bar .temp {
color: alpha(#a4b4ff, 0.60);
font-size: 11px;
font-weight: normal;
}
.bar .temp.warning { color: #e8c87a; }
.bar .temp.critical { color: #f25c7a; }
/* ── Network ─────────────────────────────────────────────────────────────── */
.bar .network {
color: #a4b4ff;
font-size: 11px;
font-weight: normal;
}
.bar .network.disconnected { color: #f25c7a; }
.bar .network.wifi { color: alpha(#a4b4ff, 0.80); }
/* ── Volume ──────────────────────────────────────────────────────────────── */
.bar .volume { color: #ff4da6; }
.bar .volume.muted { color: alpha(#ff4da6, 0.30); }
/* ── Battery ─────────────────────────────────────────────────────────────── */
.bar .battery { color: #ff4da6; }
.bar .battery.charging { color: #9adba8; }
.bar .battery.low { color: #f25c7a; }
.bar .battery.warning { color: #e8c87a; }
/* ── Media (MPRIS) ───────────────────────────────────────────────────────── */
.bar .media {
color: #c9a0ff;
font-size: 12px;
font-weight: normal;
padding: 0 10px;
}
.bar .media.paused {
color: alpha(#c9a0ff, 0.50);
font-style: italic;
}
/* ── Systray ─────────────────────────────────────────────────────────────── */
.bar .systray { padding: 0 8px; }
.bar .systray .passive { opacity: 0.5; }
/* ── Workspaces (Hyprland only) ──────────────────────────────────────────── */
.bar .workspaces button {
background: transparent;
color: #716686;
min-width: 24px;
min-height: 24px;
border-radius: 8px;
margin: 2px;
padding: 0;
}
.bar .workspaces button.active {
background: alpha(#ff4da6, 0.20);
color: #ff4da6;
border: 1px solid alpha(#ff4da6, 0.40);
}
.bar .workspaces button.occupied {
color: #c9a0ff;
}
.bar .workspaces button:hover {
background: alpha(#c9a0ff, 0.12);
color: #c9a0ff;
}
/* ── Power button ────────────────────────────────────────────────────────── */
.bar .power-btn {
color: #f25c7a;
font-size: 15px;
padding: 0 14px 0 8px;
min-width: 0;
min-height: 0;
}
.bar .power-btn:hover { color: #ff4da6; }
/* ── Hover global modules ────────────────────────────────────────────────── */
.bar .cpu:hover,
.bar .ram:hover,
.bar .temp:hover,
.bar .network:hover,
.bar .volume:hover,
.bar .battery:hover {
color: #c9a0ff;
}
/* ══════════════════════════════════════════════════════════════════════════
* OSD — volume / brightness overlay
* ══════════════════════════════════════════════════════════════════════════ */
.osd {
background: alpha(#261537, 0.92);
border-radius: 14px;
border: 2px solid alpha(#ff4da6, 0.40);
padding: 12px 20px;
margin: 0 0 40px 0;
}
.osd .icon {
color: #ff4da6;
font-size: 24px;
margin-right: 12px;
}
.osd progressbar trough {
background: #3d2454;
border-radius: 8px;
min-height: 8px;
min-width: 200px;
}
.osd progressbar progress {
border-radius: 8px;
min-height: 8px;
background: linear-gradient(to right, #ff4da6, #c9a0ff, #a4b4ff, #9adba8);
}
.osd .label {
color: #f0eaf8;
font-size: 12px;
margin-left: 8px;
}
/* ══════════════════════════════════════════════════════════════════════════
* LAUNCHER — app search
* ══════════════════════════════════════════════════════════════════════════ */
.launcher {
background: alpha(#1a0e27, 0.94);
border-radius: 14px;
border: 2px solid alpha(#ff4da6, 0.38);
padding: 10px;
min-width: 500px;
}
.launcher .search {
background: alpha(#261537, 0.75);
border-radius: 12px;
border: 1px solid alpha(#5a3875, 0.50);
padding: 9px 14px;
color: #f0eaf8;
caret-color: #ff4da6;
font-size: 14px;
}
.launcher .search:focus {
border-color: alpha(#ff4da6, 0.60);
}
.launcher .app-item {
background: transparent;
border-radius: 8px;
padding: 7px 10px;
color: #f0eaf8;
}
.launcher .app-item:hover,
.launcher .app-item:focus {
background: alpha(#ff4da6, 0.16);
border: 1px solid alpha(#ff4da6, 0.32);
}
.launcher .app-item:hover label,
.launcher .app-item:focus label {
color: #ff4da6;
}
.launcher .app-item image {
margin-right: 10px;
}
.launcher .no-results {
color: #716686;
padding: 20px;
}
/* ══════════════════════════════════════════════════════════════════════════
* NOTIFICATIONS
* ══════════════════════════════════════════════════════════════════════════ */
.notification {
background: alpha(#261537, 0.94);
border-radius: 14px;
border: 2px solid alpha(#c9a0ff, 0.30);
padding: 12px;
margin: 8px;
min-width: 350px;
}
.notification .title {
color: #ff4da6;
font-weight: bold;
font-size: 13px;
}
.notification .body {
color: #c4b8d4;
font-weight: normal;
font-size: 12px;
}
.notification .app-name {
color: #716686;
font-size: 11px;
}
.notification .time {
color: #716686;
font-size: 10px;
}
.notification .close-btn {
color: #716686;
font-size: 14px;
min-width: 0;
min-height: 0;
padding: 2px 6px;
border-radius: 6px;
}
.notification .close-btn:hover {
color: #f25c7a;
background: alpha(#f25c7a, 0.12);
}
.notification .actions button {
background: alpha(#5a3875, 0.50);
color: #c9a0ff;
border-radius: 8px;
padding: 4px 12px;
margin: 4px 4px 0 0;
}
.notification .actions button:hover {
background: alpha(#ff4da6, 0.20);
color: #ff4da6;
}
/* ── Urgency levels ──────────────────────────────────────────────────────── */
.notification.critical {
border-color: alpha(#f25c7a, 0.60);
}
.notification.critical .title {
color: #f25c7a;
}
/* ══════════════════════════════════════════════════════════════════════════
* TOOLTIP — shared
* ══════════════════════════════════════════════════════════════════════════ */
tooltip {
background: alpha(#1a0e27, 0.96);
border: 1px solid alpha(#ff4da6, 0.30);
border-radius: 10px;
color: #f0eaf8;
padding: 6px 10px;
}

228
ags-v1/widgets/Bar.js Normal file
View File

@@ -0,0 +1,228 @@
// ── violet-chaton v2 — Bar widget ───────────────────────────────────────────
// 3 pills glassmorphism — modulaire selon compositor
const audio = Service.import("audio");
const battery = Service.import("battery");
const network = Service.import("network");
const systemtray = Service.import("systemtray");
const mpris = Service.import("mpris");
// ── Helpers ─────────────────────────────────────────────────────────────────
const Separator = () => Widget.Label({ className: "separator", label: "│" });
const Clock = () => Widget.Label({
className: "clock",
connections: [[1000, (self) => {
self.label = Utils.exec("date +%H:%M");
}]],
});
const DateWidget = () => Widget.Label({
className: "date",
connections: [[60000, (self) => {
self.label = Utils.exec("date '+%a %d %b'");
}]],
});
// ── System ──────────────────────────────────────────────────────────────────
const CPU = () => Widget.Label({
className: "cpu",
connections: [[2000, (self) => {
const usage = Math.round(
Number(Utils.exec(`bash -c "top -bn1 | awk '/^%Cpu/ {print 100-$8}'"`)
));
self.label = `󰻠 ${usage}%`;
self.toggleClassName("warning", usage > 70);
self.toggleClassName("critical", usage > 90);
}]],
});
const RAM = () => Widget.Label({
className: "ram",
connections: [[2000, (self) => {
const used = Utils.exec(`bash -c "free -m | awk '/^Mem:/ {printf \"%.1f\", $3/1024}'"`)
const total = Utils.exec(`bash -c "free -m | awk '/^Mem:/ {printf \"%.1f\", $2/1024}'"`)
const pct = Math.round((parseFloat(used) / parseFloat(total)) * 100);
self.label = `󰑭 ${used}G`;
self.toggleClassName("warning", pct > 70);
self.toggleClassName("critical", pct > 90);
}]],
});
// ── Network ─────────────────────────────────────────────────────────────────
const Network = () => Widget.Label({
className: "network",
connections: [[network, (self) => {
if (network.primary === "wifi") {
const wifi = network.wifi;
self.label = `󰤨 ${wifi?.ssid || ""}`;
self.toggleClassName("wifi", true);
self.toggleClassName("disconnected", false);
} else if (network.primary === "wired") {
self.label = "󰈀 Eth";
self.toggleClassName("wifi", false);
self.toggleClassName("disconnected", false);
} else {
self.label = "󰤮 ";
self.toggleClassName("disconnected", true);
}
}]],
});
// ── Volume ──────────────────────────────────────────────────────────────────
const Volume = () => Widget.Button({
className: "volume",
onClicked: () => { audio.speaker.isMuted = !audio.speaker.isMuted; },
child: Widget.Label({
connections: [[audio, (self) => {
const vol = Math.round((audio.speaker?.volume || 0) * 100);
const muted = audio.speaker?.isMuted;
const icon = muted ? "󰝟" : vol > 66 ? "󰕾" : vol > 33 ? "󰖀" : "󰕿";
self.label = `${icon} ${vol}%`;
self.parent?.toggleClassName("muted", muted);
}, "speaker-changed"]],
}),
});
// ── Battery ─────────────────────────────────────────────────────────────────
const Battery = () => Widget.Label({
className: "battery",
visible: battery.bind("available"),
connections: [[battery, (self) => {
const pct = battery.percent;
const charging = battery.charging;
const icon = charging ? "󰂄" : pct > 80 ? "󰁹" : pct > 60 ? "󰂀" :
pct > 40 ? "󰁾" : pct > 20 ? "󰁻" : "󰂎";
self.label = `${icon} ${pct}%`;
self.toggleClassName("charging", charging);
self.toggleClassName("low", pct <= 20 && !charging);
self.toggleClassName("warning", pct <= 30 && !charging);
}]],
});
// ── Media ───────────────────────────────────────────────────────────────────
const Media = () => Widget.Label({
className: "media",
connections: [[mpris, (self) => {
const player = mpris.players[0];
if (!player) {
self.visible = false;
return;
}
self.visible = true;
const artist = player.trackArtists?.join(", ") || "";
const title = player.trackTitle || "";
const icon = player.playBackStatus === "Playing" ? " " : " ";
self.label = `${icon}${artist ? artist + " — " : ""}${title}`.slice(0, 50);
self.toggleClassName("paused", player.playBackStatus !== "Playing");
}]],
});
// ── Systray ─────────────────────────────────────────────────────────────────
const SysTray = () => Widget.Box({
className: "systray",
children: systemtray.bind("items").transform((items) =>
items.map((item) =>
Widget.Button({
child: Widget.Icon({ icon: item.bind("icon"), size: 16 }),
tooltipMarkup: item.bind("tooltip-markup"),
onPrimaryClick: (_, event) => item.activate(event),
onSecondaryClick: (_, event) => item.openMenu(event),
})
)
),
});
// ── Launcher button ─────────────────────────────────────────────────────────
const LauncherBtn = () => Widget.Button({
className: "launcher-btn",
label: "󱄅",
onClicked: () => App.toggleWindow("launcher"),
});
// ── Power button ────────────────────────────────────────────────────────────
const PowerBtn = () => Widget.Button({
className: "power-btn",
label: "⏻",
onClicked: () => Utils.exec("bash -c 'systemctl poweroff'"),
});
// ── Workspaces (Hyprland only) ──────────────────────────────────────────────
const Workspaces = (compositor) => {
if (compositor !== "hyprland") return Widget.Box({});
const hyprland = Service.import("hyprland");
return Widget.Box({
className: "workspaces",
children: hyprland.bind("workspaces").transform((ws) =>
ws.sort((a, b) => a.id - b.id)
.filter((w) => w.id > 0)
.map((w) =>
Widget.Button({
onClicked: () => hyprland.messageAsync(`dispatch workspace ${w.id}`),
child: Widget.Label({ label: `${w.id}` }),
className: hyprland.active.workspace.bind("id").transform(
(id) => id === w.id ? "active" : w.windows > 0 ? "occupied" : ""
),
})
)
),
});
};
// ── Bar assembly ────────────────────────────────────────────────────────────
export const Bar = (monitor, compositor) => Widget.Window({
name: `bar-${monitor}`,
monitor,
anchor: ["top", "left", "right"],
exclusivity: "exclusive",
className: "bar",
child: Widget.CenterBox({
startWidget: Widget.Box({
className: "modules-left",
children: [
LauncherBtn(),
Separator(),
Workspaces(compositor),
Separator(),
CPU(),
RAM(),
],
}),
centerWidget: Widget.Box({
className: "modules-center",
children: [
Media(),
],
}),
endWidget: Widget.Box({
className: "modules-right",
hpack: "end",
children: [
Network(),
Separator(),
Volume(),
Separator(),
Battery(),
Separator(),
DateWidget(),
Clock(),
Separator(),
SysTray(),
Separator(),
PowerBtn(),
],
}),
}),
});

View File

@@ -0,0 +1,99 @@
// ── violet-chaton v2 — Launcher widget ──────────────────────────────────────
// App launcher avec recherche fuzzy
const applications = Service.import("applications");
const AppItem = (app) => Widget.Button({
className: "app-item",
onClicked: () => {
app.launch();
App.closeWindow("launcher");
},
child: Widget.Box({
children: [
Widget.Icon({ icon: app.iconName || "application-x-executable", size: 24 }),
Widget.Box({
vertical: true,
children: [
Widget.Label({
label: app.name,
xalign: 0,
truncate: "end",
}),
Widget.Label({
label: app.description || "",
xalign: 0,
truncate: "end",
className: "description",
css: "color: #716686; font-size: 11px; font-weight: normal;",
}),
],
}),
],
}),
});
export const Launcher = (monitor) => {
let apps = applications.list;
const list = Widget.Box({
vertical: true,
spacing: 2,
});
const entry = Widget.Entry({
className: "search",
placeholderText: "Rechercher...",
onAccept: () => {
const first = apps[0];
if (first) {
first.launch();
App.closeWindow("launcher");
}
},
onChange: ({ text }) => {
apps = applications.query(text || "");
list.children = apps.slice(0, 12).map(AppItem);
if (apps.length === 0) {
list.children = [Widget.Label({
className: "no-results",
label: "Aucun resultat",
})];
}
},
});
return Widget.Window({
name: "launcher",
monitor,
anchor: ["top"],
layer: "overlay",
visible: false,
keymode: "exclusive",
setup: (self) => {
self.keybind("Escape", () => App.closeWindow("launcher"));
self.hook(App, (_, name, visible) => {
if (name === "launcher" && visible) {
entry.text = "";
apps = applications.list;
list.children = apps.slice(0, 12).map(AppItem);
entry.grab_focus();
}
});
},
child: Widget.Box({
className: "launcher",
vertical: true,
children: [
Widget.Scrollable({
hscroll: "never",
vscroll: "automatic",
css: "min-height: 400px;",
child: list,
}),
entry,
],
}),
});
};

View File

@@ -0,0 +1,105 @@
// ── violet-chaton v2 — Notifications widget ─────────────────────────────────
// Popup notifications stylees — urgency-aware
const notifications = Service.import("notifications");
// Ne pas déranger
notifications.popupTimeout = 5000;
notifications.cacheActions = true;
const NotificationIcon = (notif) => {
if (notif.image) {
return Widget.Box({
css: `
min-width: 48px; min-height: 48px;
background-image: url("${notif.image}");
background-size: cover;
background-position: center;
border-radius: 8px;
margin-right: 10px;
`,
});
}
return Widget.Icon({
icon: notif.appIcon || notif.appEntry || "dialog-information",
size: 36,
css: "margin-right: 10px;",
});
};
const Notification = (notif) => Widget.Box({
className: `notification ${notif.urgency}`,
vertical: true,
children: [
Widget.Box({
children: [
NotificationIcon(notif),
Widget.Box({
vertical: true,
hexpand: true,
children: [
Widget.Box({
children: [
Widget.Label({
className: "title",
label: notif.summary,
xalign: 0,
hexpand: true,
truncate: "end",
}),
Widget.Label({
className: "time",
label: new Date(notif.time * 1000)
.toLocaleTimeString("fr-FR", {
hour: "2-digit",
minute: "2-digit",
}),
}),
Widget.Button({
className: "close-btn",
label: "✕",
onClicked: () => notif.close(),
}),
],
}),
Widget.Label({
className: "app-name",
label: notif.appName || "",
xalign: 0,
}),
],
}),
],
}),
...(notif.body ? [Widget.Label({
className: "body",
label: notif.body,
xalign: 0,
wrap: true,
useMarkup: true,
})] : []),
...(notif.actions.length > 0 ? [Widget.Box({
className: "actions",
children: notif.actions.map((action) =>
Widget.Button({
label: action.label,
onClicked: () => notif.invoke(action.id),
})
),
})] : []),
],
});
export const Notifications = (monitor) => Widget.Window({
name: `notifications-${monitor}`,
monitor,
anchor: ["top", "right"],
layer: "overlay",
child: Widget.Box({
vertical: true,
css: "min-width: 350px;",
children: notifications.bind("popups").transform((popups) =>
popups.map(Notification)
),
}),
});

95
ags-v1/widgets/OSD.js Normal file
View File

@@ -0,0 +1,95 @@
// ── violet-chaton v2 — OSD widget ───────────────────────────────────────────
// Overlay volume / brightness avec gradient Mitsuri
const audio = Service.import("audio");
// ── OSD reveal timer ────────────────────────────────────────────────────────
let osdTimeout = null;
const showOSD = (window) => {
window.visible = true;
if (osdTimeout) clearTimeout(osdTimeout);
osdTimeout = setTimeout(() => {
window.visible = false;
}, 1500);
};
// ── Volume OSD ──────────────────────────────────────────────────────────────
const VolumeOSD = () => {
const icon = Widget.Label({ className: "icon" });
const progress = Widget.ProgressBar();
const label = Widget.Label({ className: "label" });
const box = Widget.Box({
className: "osd",
children: [icon, progress, label],
connections: [[audio, (self) => {
const vol = audio.speaker?.volume || 0;
const muted = audio.speaker?.isMuted;
icon.label = muted ? "󰝟" : vol > 0.66 ? "󰕾" : vol > 0.33 ? "󰖀" : "󰕿";
progress.value = vol;
label.label = `${Math.round(vol * 100)}%`;
}, "speaker-changed"]],
});
return box;
};
// ── Brightness OSD ──────────────────────────────────────────────────────────
const BrightnessOSD = () => {
const icon = Widget.Label({ className: "icon", label: "󰃞" });
const progress = Widget.ProgressBar();
const label = Widget.Label({ className: "label" });
const getBrightness = () => {
try {
const max = Number(Utils.exec("brightnessctl max"));
const cur = Number(Utils.exec("brightnessctl get"));
return max > 0 ? cur / max : 0;
} catch {
return 0;
}
};
const box = Widget.Box({
className: "osd",
children: [icon, progress, label],
connections: [[500, (self) => {
const val = getBrightness();
progress.value = val;
label.label = `${Math.round(val * 100)}%`;
}]],
});
return box;
};
// ── OSD windows ─────────────────────────────────────────────────────────────
export const OSD = (monitor) => {
const volumeWin = Widget.Window({
name: `osd-volume-${monitor}`,
monitor,
anchor: ["bottom"],
layer: "overlay",
visible: false,
child: VolumeOSD(),
});
const brightnessWin = Widget.Window({
name: `osd-brightness-${monitor}`,
monitor,
anchor: ["bottom"],
layer: "overlay",
visible: false,
child: BrightnessOSD(),
});
// Auto-show on volume change
Utils.merge([audio.speaker?.bind("volume")], () => showOSD(volumeWin));
return [volumeWin, brightnessWin];
};

2
ags-v3/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
node_modules/
@girs/

30
ags-v3/app.ts Normal file
View File

@@ -0,0 +1,30 @@
import app from "ags/gtk3/app"
import style from "./style.scss"
import Heartbeat from "./widget/Heartbeat"
import Bar from "./widget/Bar"
import BrainPower from "./widget/panels/BrainPower"
app.start({
css: style,
main() {
for (const monitor of app.get_monitors()) {
Heartbeat(monitor)
Bar(monitor)
BrainPower(monitor)
}
},
requestHandler(request: any, res: (response: any) => void) {
const cmd = String(request)
if (cmd.includes("toggle-brain")) {
const win = app.get_window("brain-power")
if (win) {
win.visible = !win.visible
res("toggled")
} else {
res("window not found")
}
} else {
res(`unknown: '${cmd}'`)
}
},
})

21
ags-v3/env.d.ts vendored Normal file
View File

@@ -0,0 +1,21 @@
declare const SRC: string
declare module "inline:*" {
const content: string
export default content
}
declare module "*.scss" {
const content: string
export default content
}
declare module "*.blp" {
const content: string
export default content
}
declare module "*.css" {
const content: string
export default content
}

75
ags-v3/lib/brain.ts Normal file
View File

@@ -0,0 +1,75 @@
import GLib from "gi://GLib"
const BRAIN_ROOT = GLib.getenv("BRAIN_ROOT")
|| readFile(GLib.get_home_dir() + "/.config/brain-path")?.trim()
|| GLib.get_home_dir() + "/Dev/Brain"
export interface BrainState {
focus: string
todos: { open: number; done: number; top3: string[] }
session: string | null
}
function readFile(path: string): string | null {
try {
const [ok, contents] = GLib.file_get_contents(path)
if (ok && contents) {
return new TextDecoder().decode(contents)
}
} catch {}
return null
}
export function getFocus(): string {
const content = readFile(`${BRAIN_ROOT}/focus.md`)
if (!content) return "no focus"
// skip header lines, get the meat
const lines = content.split("\n").filter(
(l) => !l.startsWith("#") && !l.startsWith(">") && l.trim() !== "" && !l.startsWith("---")
)
return lines[0]?.trim() || "no focus"
}
export function getTodos(): { open: number; done: number; top3: string[] } {
const content = readFile(`${BRAIN_ROOT}/todo/README.md`)
if (!content) return { open: 0, done: 0, top3: [] }
const lines = content.split("\n")
const open: string[] = []
let done = 0
for (const line of lines) {
const trimmed = line.trim()
if (trimmed.startsWith("- [ ]") || trimmed.startsWith("⬜")) {
open.push(trimmed.replace(/^- \[ \] /, "").replace(/^⬜ ?/, ""))
} else if (trimmed.startsWith("- [x]") || trimmed.startsWith("✅")) {
done++
}
}
return {
open: open.length,
done,
top3: open.slice(0, 3),
}
}
export function getSession(): string | null {
try {
const [ok, contents] = GLib.file_get_contents(
GLib.get_home_dir() + "/.claude/session-role"
)
if (ok && contents) {
return new TextDecoder().decode(contents).trim()
}
} catch {}
return null
}
export function getBrainState(): BrainState {
return {
focus: getFocus(),
todos: getTodos(),
session: getSession(),
}
}

10
ags-v3/package.json Normal file
View File

@@ -0,0 +1,10 @@
{
"dependencies": {
"ags": "*",
"gnim": "*"
},
"prettier": {
"semi": false,
"tabWidth": 2
}
}

105
ags-v3/style.scss Normal file
View File

@@ -0,0 +1,105 @@
@use "styles/palette" as *;
@use "styles/heartbeat";
@use "styles/bar";
* {
font-family: $font;
font-size: 13px;
font-weight: bold;
}
// ── Layer 3 — Brain Power Panel ──
window.BrainPower {
background: transparent;
.brain-panel {
background: rgba(26, 14, 39, 0.94); // $crust heavy glass
border-radius: 0 $radius $radius 0;
border: 2px solid rgba(201, 160, 255, 0.40); // $lilac border
border-left: none;
min-width: 380px;
padding: 16px;
}
.brain-header {
padding: 0 0 12px 0;
}
.brain-title {
color: $magenta;
font-size: 16px;
font-weight: 900;
letter-spacing: 0.08em;
}
.brain-close {
background: transparent;
border: none;
min-width: 0;
min-height: 0;
padding: 2px 8px;
label {
color: $muted;
font-size: 14px;
}
&:hover label {
color: $danger;
}
}
.brain-content {
padding: 0 4px;
}
.brain-section {
padding: 8px 0 4px 0;
}
.brain-section-title {
color: $lilac;
font-size: 11px;
font-weight: 900;
letter-spacing: 0.12em;
}
.brain-divider {
background: rgba(90, 56, 117, 0.30); // $surface2
min-height: 1px;
margin: 8px 0;
}
.brain-focus {
color: $text;
font-size: 13px;
padding: 4px 0 4px 16px;
}
.brain-session {
color: $champagne;
font-size: 12px;
font-weight: normal;
padding: 4px 0 4px 16px;
}
.brain-todos-count {
color: $muted;
font-size: 11px;
font-weight: normal;
}
.brain-todos-list {
color: $subtext1;
font-size: 12px;
font-weight: normal;
padding: 4px 0 4px 16px;
}
.brain-terminal-placeholder {
color: $muted;
font-size: 11px;
font-style: italic;
padding: 8px 0 4px 16px;
}
}

192
ags-v3/styles/_bar.scss Normal file
View File

@@ -0,0 +1,192 @@
@use "palette" as *;
// Layer 1 — Ghost bar (hover reveal)
window.Bar {
background: transparent;
> centerbox {
background: rgba(38, 21, 55, 0.88); // $base @ 0.88
border-radius: $radius;
border: 3px solid rgba(255, 77, 166, 0.60); // $magenta @ 0.60
margin: 6px 8px;
padding: 0 8px;
min-height: 38px;
}
.modules-left,
.modules-center,
.modules-right {
padding: 0 4px;
}
.module {
padding: 0 8px;
color: $text;
}
.prompt-name {
color: $magenta;
font-size: 14px;
padding: 0 0 0 10px;
}
.prompt-cursor {
color: $lilac;
font-size: 14px;
font-weight: 900;
}
.separator {
color: rgba(240, 234, 248, 0.12); // $text @ 0.12
font-size: 11px;
padding: 0 4px;
font-weight: normal;
}
// ── clock ──
.clock {
color: $magenta;
font-weight: 900;
font-size: 14px;
letter-spacing: 0.04em;
padding: 0 10px;
}
.date {
color: $lavande;
font-size: 12px;
font-weight: normal;
padding: 0 10px 0 2px;
}
// ── system stats ──
.cpu { color: $lavande; }
.ram { color: $magenta; }
.temp {
color: rgba(164, 180, 255, 0.60); // $lavande @ 0.60
font-size: 11px;
font-weight: normal;
}
.cpu, .ram, .temp {
&.warning { color: $champagne; }
&.critical { color: $danger; }
}
// ── network ──
.network {
color: $lavande;
font-size: 12px;
padding: 0 8px;
&.disconnected { color: $danger; }
}
// ── volume ──
button.volume,
button.muted {
background: transparent;
border: none;
padding: 0 8px;
min-width: 0;
min-height: 0;
label { color: $magenta; }
&.muted label { color: rgba(255, 77, 166, 0.30); }
&:hover label { color: $lilac; }
}
// ── battery ──
.battery {
color: $magenta;
padding: 0 8px;
&.charging { color: $mitsuri; }
&.low { color: $danger; }
&.warning { color: $champagne; }
}
// ── media ──
.media-module {
padding: 0 4px;
}
.media {
padding: 0 4px;
&.paused .media-text {
color: rgba(201, 160, 255, 0.50); // $lilac @ 0.50
font-style: italic;
}
}
.media-text {
color: $lilac;
font-size: 12px;
font-weight: normal;
padding: 0 6px;
}
.media-prev,
.media-play,
.media-next {
background: transparent;
border: none;
padding: 0 3px;
min-width: 0;
min-height: 0;
label { color: $lilac; font-size: 13px; }
&:hover label { color: $magenta; }
}
// ── systray ──
.systray {
padding: 0 4px;
}
.systray-item {
background: transparent;
border: none;
padding: 0 3px;
min-width: 0;
min-height: 0;
&:hover {
background: rgba(201, 160, 255, 0.12);
border-radius: $radius-sm;
}
}
// ── hover effects ──
.module:hover,
.clock:hover,
.cpu:hover,
.ram:hover,
.network:hover,
.battery:hover {
color: $lilac;
}
// ── workspaces ──
.workspaces button {
background: transparent;
color: $muted;
min-width: 22px;
min-height: 22px;
border-radius: $radius-sm;
margin: 2px;
padding: 0;
&.active {
background: rgba(255, 77, 166, 0.20);
color: $magenta;
border: 1px solid rgba(255, 77, 166, 0.40);
}
&.occupied { color: $lilac; }
&:hover {
background: rgba(201, 160, 255, 0.12);
color: $lilac;
}
}
}

View File

@@ -0,0 +1,21 @@
@use "palette" as *;
// Layer 0 — heartbeat line
// Fin trait magenta en haut de l'écran — "le système est vivant"
window.Heartbeat {
background: transparent;
> box {
// gradient uses rgba() which SCSS understands natively
background: linear-gradient(
to right,
rgba(255, 77, 166, 0.0),
rgba(255, 77, 166, 0.6),
rgba(201, 160, 255, 0.8),
rgba(255, 77, 166, 0.6),
rgba(255, 77, 166, 0.0)
);
min-height: 2px;
}
}

View File

@@ -0,0 +1,35 @@
// ── violet-chaton v2 ──────────────────────────────────────────────────────
// Mitsuri Kanroji inspired — gradient magenta → green
// Ghost Shell edition
// backgrounds
$crust: #1a0e27;
$base: #261537;
$mantle: #341c4a;
$surface0: #3d2454;
$surface1: #493161;
$surface2: #5a3875;
// accents
$magenta: #ff4da6;
$lilac: #c9a0ff;
$mitsuri: #9adba8;
$lavande: #a4b4ff;
$champagne: #e8c87a;
$danger: #f25c7a;
// text
$text: #f0eaf8;
$subtext1: #c4b8d4;
$subtext0: #9a8fad;
$muted: #716686;
// shared
$font: "Maple Mono NF", "MapleMono Nerd Font", monospace;
$radius: 14px;
$radius-sm: 8px;
$transition: 300ms ease-out;
// Note: alpha() is a GTK CSS function, not SCSS.
// Use it raw in GTK CSS values, not in SCSS variables.
// For SCSS variables that need transparency, use rgba().

3
ags-v3/toggle-brain.sh Executable file
View File

@@ -0,0 +1,3 @@
#!/bin/bash
# Toggle Brain Power panel via AGS IPC
ags request "toggle-brain" 2>/dev/null

14
ags-v3/tsconfig.json Normal file
View File

@@ -0,0 +1,14 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"strict": true,
"module": "ES2022",
"target": "ES2020",
"lib": ["ES2023"],
"moduleResolution": "Bundler",
// "checkJs": true,
// "allowJs": true,
"jsx": "react-jsx",
"jsxImportSource": "ags/gtk3"
}
}

74
ags-v3/widget/Bar.tsx Normal file
View File

@@ -0,0 +1,74 @@
import app from "ags/gtk3/app"
import { Astal, Gtk, Gdk } from "ags/gtk3"
import Clock from "./modules/Clock"
import Battery from "./modules/Battery"
import Volume from "./modules/Volume"
import Network from "./modules/Network"
import SystemStats from "./modules/SystemStats"
import Media from "./modules/Media"
import SysTray from "./modules/SysTray"
import Prompt from "./modules/Prompt"
export default function Bar(gdkmonitor: Gdk.Monitor) {
const { TOP, LEFT, RIGHT } = Astal.WindowAnchor
let hideTimeout: number | null = null
function scheduleHide(win: Astal.Window) {
if (hideTimeout) clearTimeout(hideTimeout)
hideTimeout = setTimeout(() => {
win.visible = false
hideTimeout = null
}, 800)
}
function cancelHide() {
if (hideTimeout) {
clearTimeout(hideTimeout)
hideTimeout = null
}
}
return (
<window
class="Bar"
name="bar"
visible={false}
gdkmonitor={gdkmonitor}
exclusivity={Astal.Exclusivity.EXCLUSIVE}
anchor={TOP | LEFT | RIGHT}
application={app}
layer={Astal.Layer.TOP}
>
<eventbox
onHover={() => cancelHide()}
onHoverLost={(self) => {
const win = self.get_toplevel() as Astal.Window
scheduleHide(win)
}}
>
<centerbox>
<box $type="start" class="modules-left" halign={Gtk.Align.START}>
<Prompt />
<label class="separator" label="│" />
<SystemStats />
<label class="separator" label="│" />
<Media />
</box>
<box $type="center" class="modules-center">
<Clock />
</box>
<box $type="end" class="modules-right" halign={Gtk.Align.END}>
<SysTray />
<label class="separator" label="│" />
<Network />
<label class="separator" label="│" />
<Volume />
<label class="separator" label="│" />
<Battery />
</box>
</centerbox>
</eventbox>
</window>
)
}

View File

@@ -0,0 +1,27 @@
import app from "ags/gtk3/app"
import { Astal, Gtk, Gdk } from "ags/gtk3"
export default function Heartbeat(gdkmonitor: Gdk.Monitor) {
const { TOP, LEFT, RIGHT } = Astal.WindowAnchor
return (
<window
class="Heartbeat"
gdkmonitor={gdkmonitor}
exclusivity={Astal.Exclusivity.NONE}
anchor={TOP | LEFT | RIGHT}
application={app}
layer={Astal.Layer.OVERLAY}
>
<eventbox
onHover={() => {
// reveal the bar
const bar = app.get_window("bar")
if (bar) bar.visible = true
}}
>
<box class="heartbeat-line" />
</eventbox>
</window>
)
}

View File

@@ -0,0 +1,38 @@
import AstalBattery from "gi://AstalBattery"
import { createBinding, createDerivedBinding } from "ags"
export default function Battery() {
const bat = AstalBattery.get_default()
const percentage = createBinding(bat, "percentage")
const charging = createBinding(bat, "charging")
const text = createDerivedBinding(
[percentage, charging],
(p: number, isCharging: boolean) => {
const pct = Math.round(p * 100)
let icon = ""
if (isCharging) icon = "󰂄"
else if (pct > 90) icon = "󰁹"
else if (pct > 70) icon = "󰂁"
else if (pct > 50) icon = "󰁿"
else if (pct > 30) icon = "󰁽"
else if (pct > 10) icon = "󰁻"
else icon = "󰂃"
return `${icon} ${pct}%`
},
)
const cls = createDerivedBinding(
[percentage, charging],
(p: number, isCharging: boolean) => {
const pct = Math.round(p * 100)
if (isCharging) return "battery charging"
if (pct <= 10) return "battery low"
if (pct <= 20) return "battery warning"
return "battery"
},
)
return <label class={cls} label={text} />
}

View File

@@ -0,0 +1,32 @@
import { createPoll } from "ags/time"
function formatTime(): string {
const now = new Date()
return now.toLocaleTimeString("fr-FR", {
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
})
}
function formatDate(): string {
const now = new Date()
return now.toLocaleDateString("fr-FR", {
weekday: "short",
day: "numeric",
month: "short",
})
}
export default function Clock() {
const time = createPoll("", 1000, () => formatTime())
const date = createPoll("", 60000, () => formatDate())
return (
<box>
<label class="clock" label={time} />
<label class="separator" label="│" />
<label class="date" label={date} />
</box>
)
}

View File

@@ -0,0 +1,60 @@
import AstalMpris from "gi://AstalMpris"
import { createBinding, For } from "ags"
export default function Media() {
const mpris = AstalMpris.get_default()
const players = createBinding(mpris, "players")
return (
<box class="media-module">
<For each={players}>
{(player) => {
const title = createBinding(player, "title")
const artist = createBinding(player, "artist")
const status = createBinding(player, "playbackStatus")
const icon = status((s: AstalMpris.PlaybackStatus) =>
s === AstalMpris.PlaybackStatus.PLAYING ? "󰐊" : "󰏤"
)
const label = title((t: string) => {
const a = player.artist
const display = a ? `${a}${t}` : t
// truncate long titles
return display.length > 40
? display.substring(0, 37) + "..."
: display
})
const cls = status((s: AstalMpris.PlaybackStatus) =>
s === AstalMpris.PlaybackStatus.PLAYING ? "media" : "media paused"
)
return (
<box class={cls}>
<button
class="media-prev"
onClicked={() => player.previous()}
>
<label label="󰒮" />
</button>
<button
class="media-play"
onClicked={() => player.play_pause()}
>
<label label={icon} />
</button>
<button
class="media-next"
onClicked={() => player.next()}
>
<label label="󰒭" />
</button>
<label class="media-text" label={label} />
</box>
)
}}
</For>
</box>
)
}

View File

@@ -0,0 +1,31 @@
import AstalNetwork from "gi://AstalNetwork"
import { createBinding } from "ags"
export default function Network() {
const net = AstalNetwork.get_default()
const text = createBinding(net, "primary")((type: AstalNetwork.Primary) => {
if (type === AstalNetwork.Primary.WIFI) {
const wifi = net.wifi
if (!wifi) return "󰤮 offline"
const ssid = wifi.ssid || "wifi"
const strength = wifi.strength
let icon = "󰤯"
if (strength > 80) icon = "󰤨"
else if (strength > 60) icon = "󰤥"
else if (strength > 40) icon = "󰤢"
else if (strength > 20) icon = "󰤟"
return `${icon} ${ssid}`
}
if (type === AstalNetwork.Primary.WIRED) return "󰈀 eth"
return "󰤮 offline"
})
const cls = createBinding(net, "primary")((type: AstalNetwork.Primary) => {
if (type === AstalNetwork.Primary.WIFI) return "network wifi"
if (type === AstalNetwork.Primary.WIRED) return "network wired"
return "network disconnected"
})
return <label class={cls} label={text} />
}

View File

@@ -0,0 +1,18 @@
import GLib from "gi://GLib"
import { createPoll } from "ags/time"
export default function Prompt() {
const username = GLib.get_user_name() || "user"
const cursor = createPoll("_", 600, () => {
// alternate between _ and empty to create blink
return Date.now() % 1200 < 600 ? "_" : " "
})
return (
<box>
<label class="prompt-name" label={username} />
<label class="prompt-cursor" label={cursor} />
</box>
)
}

View File

@@ -0,0 +1,24 @@
import AstalTray from "gi://AstalTray"
import Gtk from "gi://Gtk?version=3.0"
import { createBinding, For } from "ags"
export default function SysTray() {
const tray = AstalTray.get_default()
const items = createBinding(tray, "items")
return (
<box class="systray">
<For each={items}>
{(item) => (
<button
class="systray-item"
tooltipText={createBinding(item, "tooltipMarkup")}
onClicked={() => item.activate(0, 0)}
>
<icon pixelSize={16} gicon={createBinding(item, "gicon")} />
</button>
)}
</For>
</box>
)
}

View File

@@ -0,0 +1,60 @@
import GLib from "gi://GLib"
import { createPoll } from "ags/time"
function readProc(path: string): string | null {
try {
const [ok, contents] = GLib.file_get_contents(path)
if (ok && contents) return new TextDecoder().decode(contents)
} catch {}
return null
}
let prevIdle = 0
let prevTotal = 0
function getCpuUsage(): string {
const content = readProc("/proc/stat")
if (!content) return "?"
const line = content.split("\n")[0] // "cpu user nice system idle ..."
const parts = line.split(/\s+/).slice(1).map(Number)
const idle = parts[3] + parts[4] // idle + iowait
const total = parts.reduce((a, b) => a + b, 0)
const dIdle = idle - prevIdle
const dTotal = total - prevTotal
prevIdle = idle
prevTotal = total
if (dTotal === 0) return "0"
return `${Math.round(((dTotal - dIdle) / dTotal) * 100)}`
}
function getRamUsage(): string {
const content = readProc("/proc/meminfo")
if (!content) return "?"
const lines = content.split("\n")
let total = 0, available = 0
for (const line of lines) {
if (line.startsWith("MemTotal:")) total = parseInt(line.split(/\s+/)[1])
if (line.startsWith("MemAvailable:")) available = parseInt(line.split(/\s+/)[1])
if (total && available) break
}
if (!total) return "?"
return `${Math.round(((total - available) / total) * 100)}`
}
export default function SystemStats() {
const cpu = createPoll("0", 3000, () => getCpuUsage())
const ram = createPoll("0", 5000, () => getRamUsage())
return (
<box>
<label class="cpu module" label={cpu((v: string) => ` ${v}%`)} />
<label class="ram module" label={ram((v: string) => `󰍛 ${v}%`)} />
</box>
)
}

View File

@@ -0,0 +1,44 @@
import AstalWp from "gi://AstalWp"
import { createBinding } from "ags"
export default function Volume() {
const speaker = AstalWp.get_default()!.defaultSpeaker!
const volume = createBinding(speaker, "volume")
const mute = createBinding(speaker, "mute")
const text = volume((v: number) => {
const pct = Math.round(v * 100)
const muted = speaker.mute
let icon = "󰕾"
if (muted) icon = "󰝟"
else if (v > 0.66) icon = "󰕾"
else if (v > 0.33) icon = "󰖀"
else if (v > 0) icon = "󰕿"
else icon = "󰝟"
return `${icon} ${pct}%`
})
const cls = mute((m: boolean) =>
m ? "volume muted" : "volume"
)
return (
<button
class={cls}
onClicked={() => {
speaker.mute = !speaker.mute
}}
onScroll={(_self: any, event: any) => {
const delta = event.delta_y
if (delta < 0) {
speaker.volume = Math.min(speaker.volume + 0.05, 1.0)
} else {
speaker.volume = Math.max(speaker.volume - 0.05, 0.0)
}
}}
>
<label label={text} />
</button>
)
}

View File

@@ -0,0 +1,104 @@
import app from "ags/gtk3/app"
import { Astal, Gtk, Gdk } from "ags/gtk3"
import { createPoll } from "ags/time"
import { getBrainState } from "../../lib/brain"
function BrainContent() {
const state = createPoll("", 10000, () => JSON.stringify(getBrainState()))
const focus = state((s: string) => {
try { return JSON.parse(s).focus } catch { return "..." }
})
const todosLabel = state((s: string) => {
try {
const t = JSON.parse(s).todos
return `${t.open} ouverts / ${t.done} faits`
} catch { return "..." }
})
const todosList = state((s: string) => {
try {
const t = JSON.parse(s).todos.top3
return t.map((item: string) => `${item}`).join("\n") || " rien"
} catch { return "..." }
})
const session = state((s: string) => {
try {
const sess = JSON.parse(s).session
return sess || "aucune"
} catch { return "..." }
})
return (
<box orientation={Gtk.Orientation.VERTICAL} class="brain-content">
<box class="brain-section">
<label class="brain-section-title" label=" FOCUS" xalign={0} />
</box>
<label class="brain-focus" label={focus} xalign={0} wrap />
<box class="brain-divider" />
<box class="brain-section">
<label class="brain-section-title" label=" SESSION" xalign={0} />
</box>
<label class="brain-session" label={session} xalign={0} />
<box class="brain-divider" />
<box class="brain-section">
<label class="brain-section-title" label="󰄲 TODOS" xalign={0} />
<label class="brain-todos-count" label={todosLabel} xalign={1} hexpand />
</box>
<label class="brain-todos-list" label={todosList} xalign={0} />
<box class="brain-divider" />
<box class="brain-section">
<label class="brain-section-title" label=" TERMINAL" xalign={0} />
</box>
<label class="brain-terminal-placeholder" label=" bientôt — agent brain-hud" xalign={0} />
</box>
)
}
export default function BrainPower(gdkmonitor: Gdk.Monitor) {
const { TOP, LEFT, BOTTOM } = Astal.WindowAnchor
return (
<window
class="BrainPower"
name="brain-power"
visible={false}
gdkmonitor={gdkmonitor}
exclusivity={Astal.Exclusivity.NONE}
anchor={TOP | LEFT | BOTTOM}
application={app}
layer={Astal.Layer.OVERLAY}
>
<eventbox
onHoverLost={() => {
const win = app.get_window("brain-power")
if (win) win.visible = false
}}
>
<box orientation={Gtk.Orientation.VERTICAL} class="brain-panel">
<box class="brain-header">
<label class="brain-title" label=" BRAIN POWER" hexpand xalign={0} />
<button
class="brain-close"
onClicked={() => {
const win = app.get_window("brain-power")
if (win) win.visible = false
}}
>
<label label="✕" />
</button>
</box>
<BrainContent />
</box>
</eventbox>
</window>
)
}

View File

@@ -0,0 +1,6 @@
[Desktop Entry]
Type=Application
Name=Ghost Shell
Comment=violet-chaton v2 AGS statusbar
Exec=sh -c "ags run -d $HOME/.config/ags-v3 -g 3"
X-GNOME-Autostart-enabled=true

270
help.md
View File

@@ -1,4 +1,6 @@
# violet-chaton — référence des commandes # violet-chaton v2 — reference des commandes
> Tape `hotkeys` dans le terminal pour un rappel rapide.
--- ---
@@ -6,28 +8,33 @@
| Commande | Alias | Description | | Commande | Alias | Description |
|---|---|---| |---|---|---|
| `ls` | `eza --icons --git` | Listing coloré avec icônes | | `ls` | eza --icons | Listing colore avec icones |
| `ll` | `eza -l --git` | Listing long avec infos git | | `ll` | eza -l --git | Listing long avec infos git |
| `lt` | `eza --tree` | Arborescence en arbre | | `la` | eza -la --git | Listing complet (fichiers caches inclus) |
| `cd <dossier>` | zoxide | Navigation intelligente (mémorise les dossiers visités) | | `lt` | eza --tree | Arborescence en arbre (3 niveaux) |
| `cd <partiel>` | zoxide | Saute vers le dossier le plus probable — ex: `cd doc``~/Documents` | | `cd <dossier>` | zoxide | Navigation intelligente (memorise les dossiers visites) |
| `cd <partiel>` | zoxide | Saute vers le dossier le plus probable |
| `<nom_dossier>` | AUTO_CD | Entrer dans un dossier sans taper `cd` | | `<nom_dossier>` | AUTO_CD | Entrer dans un dossier sans taper `cd` |
| `yazi` | — | Explorateur de fichiers TUI (clavier) | | `y` | yazi + cd | Explorateur fichiers TUI — cd au dossier visite en quittant |
| `proj` | fzf ~/Dev | Project switcher — navigue dans tous les projets |
| `nemo` | — | Explorateur de fichiers GUI | | `nemo` | — | Explorateur de fichiers GUI |
| `fd <pattern>` | fdfind | Recherche de fichiers (remplace `find`) | | `fd <pattern>` | fdfind | Recherche de fichiers (remplace `find`) |
| `mkcd <nom>` | mkdir + cd | Creer un dossier et y entrer |
### yazi — raccourcis principaux ### yazi — raccourcis principaux
| Touche | Action | | Touche | Action |
|---|---| |---|---|
| `h/j/k/l` ou flèches | Navigation | | `h/j/k/l` ou fleches | Navigation |
| `Entrée` | Ouvrir / entrer dans le dossier | | `Entree` | Ouvrir / entrer dans le dossier |
| `Espace` | Sélectionner | | `Espace` | Selectionner |
| `y` | Copier | | `y` | Copier |
| `d` | Couper | | `d` | Couper |
| `p` | Coller | | `p` | Coller |
| `r` | Renommer | | `r` | Renommer |
| `D` | Supprimer | | `D` | Supprimer |
| `q` | Quitter | | `q` | Quitter (retour au dossier visite) |
> yazi utilise le protocole image kitty — les images s'affichent en preview native.
--- ---
@@ -35,12 +42,13 @@
| Commande | Alias | Description | | Commande | Alias | Description |
|---|---|---| |---|---|---|
| `cat <fichier>` | batcat | Affichage avec coloration syntaxique, sans pager | | `cat <fichier>` | batcat | Affichage avec coloration syntaxique (theme violet-chaton) |
| `bat <fichier>` | batcat | Comme cat avec numéros de lignes et pager | | `bat <fichier>` | batcat | Comme cat avec numeros de lignes et pager |
| `glow <fichier.md>` | — | Rendu Markdown dans le terminal | | `glow <fichier.md>` | — | Rendu Markdown dans le terminal |
| `man <commande>` | tldr | Pages de manuel simplifiées (remplace man) | | `tl <commande>` | tldr | Pages de manuel simplifiees avec exemples |
| `tldr <commande>` | — | Exemples pratiques d'une commande | | `man <commande>` | — | Pages de manuel completes (man reste intact) |
| `fetch` | — | Affiche les infos système avec le logo violet-chaton | | `fetch` | — | Infos systeme avec le logo violet-chaton |
| `colors` | — | Affiche la palette violet-chaton v2 complete |
--- ---
@@ -48,58 +56,120 @@
| Commande | Description | | Commande | Description |
|---|---| |---|---|
| `grep <pattern> <fichier>` | Recherche dans un fichier (--color=auto actif par défaut) | | `rg <pattern>` | Recherche dans les fichiers (ripgrep) |
| `rg <pattern>` | Recherche dans les fichiers (ripgrep, remplace grep) | | `fd <pattern>` | Recherche de fichiers |
| `fd <pattern>` | Recherche de fichiers (remplace find) | | `fzf` | Fuzzy finder interactif |
| `fzf` | Fuzzy finder interactif (pipe ou seul) |
### fzf — raccourcis clavier ### fzf — raccourcis clavier
| Touche | Action | | Touche | Action |
|---|---| |---|---|
| `Ctrl+G` | Recherche fuzzy d'un **fichier** dans `$HOME` (aperçu batcat) | | `Ctrl+G` | Recherche fuzzy d'un **fichier** (apercu bat) |
| `Ctrl+F` | Recherche fuzzy d'un **dossier** dans `$HOME` | | `Ctrl+F` | Recherche fuzzy d'un **dossier** |
| `Ctrl+R` | Recherche dans l'**historique** (via atuin) | | `Ctrl+R` | Recherche dans l'**historique** (via atuin) |
### fzf — commandes avancees
| Commande | Description |
|---|---|
| `glog` | Git log interactif — preview du commit, copie hash au presse-papier |
| `fkill` | Process killer — selectionne et tue un process |
--- ---
## Git ## Git
| Commande | Alias | Description | | Commande | Alias | Description |
|---|---|---| |---|---|---|
| `lg` | lazygit | Interface TUI complète pour git | | `lg` | lazygit | Interface TUI complete pour git (theme violet-chaton v2) |
| `git diff` | — | Affichage amélioré par git-delta (couleurs, side-by-side) | | `glog` | — | Git log fzf avec preview des commits |
| `gh pr create` | — | Créer une pull request depuis le terminal | | `git diff` | — | Diffs colores par delta (side-by-side, violet-chaton) |
| `gh issue list` | — | Lister les issues du dépôt courant |
| `gh auth login` | — | S'authentifier sur GitHub |
### lazygit — raccourcis principaux ### lazygit — raccourcis principaux
| Touche | Action | | Touche | Action |
|---|---| |---|---|
| `1/2/3/4/5` | Changer de panneau (status/branches/commits/stash/reflog) | | `1/2/3/4/5` | Changer de panneau |
| `Espace` | Stage / unstage un fichier | | `Espace` | Stage / unstage |
| `c` | Commit | | `c` | Commit |
| `p` | Push | | `p` | Push |
| `P` | Pull | | `P` | Pull |
| `b` | Gérer les branches |
| `z` | Undo |
| `q` | Quitter | | `q` | Quitter |
### git-delta — navigation dans les diffs ### git-delta — navigation
| Touche | Action | | Touche | Action |
|---|---| |---|---|
| `n` | Hunk suivant | | `n` | Hunk suivant |
| `N` | Hunk précédent | | `N` | Hunk precedent |
| `q` | Quitter | | `q` | Quitter |
--- ---
## Monitoring & système ## Terminal kitty — splits & layouts
| Touche | Action |
|---|---|
| `Ctrl+Shift+\` | Split vertical |
| `Ctrl+Shift+-` | Split horizontal |
| `Ctrl+Shift+Z` | Zoom — stack toggle (fullscreen le split actif) |
| `Ctrl+Shift+←→↑↓` | Naviguer entre splits |
| `Ctrl+Shift+F` | Deplacer split en avant |
| `Ctrl+Shift+B` | Deplacer split en arriere |
| `Ctrl+Shift+R` | Redimensionner split |
| `Ctrl+Shift+1` | Layout tall |
| `Ctrl+Shift+2` | Layout fat |
| `Ctrl+Shift+3` | Layout grid |
| `Ctrl+Shift+4` | Layout horizontal |
| `Ctrl+Shift+5` | Layout vertical |
| `Ctrl+Shift+T` | Nouvel onglet |
| `Ctrl+Shift+W` | Fermer onglet |
| `Ctrl+Shift+H/L` | Onglet precedent/suivant |
| `Ctrl+Shift+,` | Renommer onglet |
| `Ctrl+V` | Coller |
| `Ctrl+C` | Copier / interrompre |
| `Ctrl+Shift++/-/0` | Zoom police |
| `Ctrl+Shift+F5` | Recharger la config |
---
## Vi-mode zsh
Le shell demarre en **mode insert** (beam cursor). `Escape` passe en **mode normal** (block cursor).
### Mode normal (Escape)
| Touche | Action |
|---|---|
| `h/j/k/l` | Deplacement gauche/bas/haut/droite |
| `w` / `b` | Mot suivant / precedent |
| `0` / `$` | Debut / fin de ligne |
| `x` | Supprimer caractere |
| `dd` | Supprimer la ligne |
| `yy` | Copier la ligne |
| `p` | Coller |
| `i` | Retour mode insert |
| `a` | Insert apres le curseur |
| `A` | Insert en fin de ligne |
### Mode insert (keybindings preserves)
| Touche | Action |
|---|---|
| `Ctrl+A` | Debut de ligne |
| `Ctrl+E` | Fin de ligne |
| `Ctrl+W` | Supprimer mot precedent |
| `Ctrl+U` | Supprimer jusqu'au debut |
| `Ctrl+K` | Supprimer jusqu'a la fin |
| `Ctrl+Y` | Coller (yank) |
| `Ctrl+Space` | Accepter suggestion auto |
---
## Monitoring & systeme
| Commande | Alias | Description | | Commande | Alias | Description |
|---|---|---| |---|---|---|
| `btop` | — | Moniteur système interactif (CPU, RAM, réseau, disque) | | `btop` / `top` | — | Moniteur systeme (theme violet-chaton v2) |
| `disk` | ncdu | Analyse de l'espace disque interactif | | `disk` / `dust` | — | Analyse de l'espace disque |
| `ncdu` | — | Idem (nom original) | | `procs` | — | Process viewer moderne |
| `tokei` | — | Stats code par langage |
| `hyperfine <cmd>` | — | Benchmark d'une commande |
| `gping <host>` | — | Ping avec graphe temps reel |
--- ---
@@ -107,14 +177,9 @@
| Commande / Touche | Description | | Commande / Touche | Description |
|---|---| |---|---|
| `Ctrl+R` | Recherche dans l'historique avec atuin (fuzzy, filtré par dossier/host) | | `Ctrl+R` | Recherche fuzzy dans l'historique |
| `atuin search <terme>` | Recherche dans l'historique en ligne de commande | | `atuin stats` | Statistiques commandes |
| `atuin stats` | Statistiques sur les commandes les plus utilisées | | `atuin sync` | Synchroniser entre machines |
| `atuin sync` | Synchroniser l'historique entre machines (compte requis) |
| `atuin register` | Créer un compte atuin pour la synchronisation |
> L'interface atuin affiche : code de sortie | durée | timestamp | commande.
> L'historique est partagé entre sessions et machines si atuin est configuré avec un compte.
--- ---
@@ -122,12 +187,10 @@
| Commande / Touche | Description | | Commande / Touche | Description |
|---|---| |---|---|
| `fuck` | Corrige la dernière commande ratée (thefuck) | | `fuck` | Corrige la derniere commande ratee (thefuck) |
| `Ctrl+Space` | Accepte la suggestion automatique complète | | `Ctrl+Space` | Accepte la suggestion complete |
| `→` (flèche droite) | Accepte partiellement la suggestion (mot par mot) | | `→` (fleche droite) | Accepte partiellement (mot par mot) |
| `Tab` | Autocomplétion avec menu interactif | | `Tab` | Autocompletion avec menu interactif |
> zsh corrige aussi automatiquement les petites typos de commandes (option `CORRECT`).
--- ---
@@ -135,15 +198,13 @@
| Commande | Description | | Commande | Description |
|---|---| |---|---|
| `cava` | Visualiseur audio dans le terminal | | `cava` | Visualiseur audio (gradient Mitsuri) |
| `pipes` | Animation de tuyaux colorés | | `pipes` | Animation de tuyaux colores |
| `cbonsai` | Bonsaï animé dans le terminal | | `cbonsai` | Bonsai anime |
| `chafa <image>` | Affiche une image dans le terminal | | `chafa <image>` | Affiche une image dans le terminal |
| `lolcat` | Colorie la sortie d'une commande en arc-en-ciel (ex: `ls \| lolcat`) | | `lolcat` | Colorie en arc-en-ciel (ex: `ls \| lolcat`) |
| `cmatrix` | Pluie de caractères style Matrix | | `cmatrix` | Pluie de caracteres Matrix |
| `toilet -f big <texte>` | Affiche du texte en gros ASCII art coloré | | `toilet -f big <texte>` | Texte en gros ASCII art |
| `jp2a <image.jpg>` | Convertit une image en ASCII art dans le terminal |
| `w3m <url>` | Navigue sur le web en mode texte depuis le terminal |
--- ---
@@ -151,76 +212,41 @@
| Commande | Description | | Commande | Description |
|---|---| |---|---|
| `qalc` | Calculatrice interactive (unités, conversions, ex: `150 EUR to USD`) | | `sd <ancien> <nouveau>` | Remplacement simplifie (remplace sed) |
| `jq <filtre> <fichier.json>` | Traite et formate du JSON en ligne de commande | | `qalc` | Calculatrice interactive (unites, conversions) |
| `uv` | Gestionnaire de paquets Python ultra-rapide (remplace pip/venv) | | `jq` | Traite et formate du JSON |
| `uvx <outil>` | Exécute un outil Python dans un environnement isolé temporaire | | `weather [ville]` | Meteo rapide |
| `uv` / `uvx` | Gestionnaire Python ultra-rapide |
--- ---
## Cheat sheets interactifs ## Coloration syntaxique zsh
| Commande | Description |
|---|---|
| `navi` | Interface interactive de cheat sheets (chercher des exemples de commandes) |
| `tldr <commande>` | Résumé rapide d'une commande avec exemples |
---
## Prompt (starship)
Le prompt affiche automatiquement sur **2 lignes** :
**Ligne 1 :** OS | User@Host | Dossier courant | Branche git + état | Langage détecté + version | Durée dernière commande (si >2s) | RAM | Heure
**Ligne 2 :** Code de retour si erreur | Caractère `` (bleu ok / rouge erreur)
**État git affiché :**
| Symbole | Signification |
|---|---|
| `⇡N` | N commits en avance sur le remote |
| `⇣N` | N commits en retard |
| `?N` | N fichiers non trackés |
| `!N` | N fichiers modifiés |
| `+N` | N fichiers stagés |
| `✘N` | Conflits |
---
## Plugins zsh actifs
| Plugin | Effet |
|---|---|
| `zsh-autosuggestions` | Suggestions grises basées sur l'historique |
| `zsh-syntax-highlighting` | Coloration de la commande en cours de frappe |
| `zsh-completions` | Complétions supplémentaires pour de nombreux outils |
| `zinit` | Gestionnaire de plugins (chargement automatique au démarrage) |
---
## Coloration syntaxique du terminal
| Type | Couleur | | Type | Couleur |
|---|---| |---|---|
| Commandes | Cyan | | Commandes | Lavande `#a4b4ff` |
| Alias | Violet | | Alias | Lilac `#c9a0ff` |
| Builtins zsh | Rose | | Builtins | Magenta `#ff4da6` |
| Chaînes | Violet | | Chaines | Mitsuri `#9adba8` |
| Chemins | Blanc souligné | | Options `--flag` | Champagne `#e8c87a` |
| Erreurs / inconnu | Rouge gras | | Chemins | Text souligne |
| Commentaires | Gris italique | | Erreurs / inconnu | Danger `#f25c7a` bold |
| Globs (`*`, `?`) | Jaune | | Commentaires | Muted `#716686` italic |
| Redirections `> \|` | Magenta bold |
| Globs `* ?` | Champagne |
--- ---
## Options zsh actives ## Prompt starship (3 lignes)
| Option | Effet | ```
|---|---| ┌── [OS] [dossier] [git branch] [git status] [langages] ─── [duree] [batterie] [heure]
| `AUTO_CD` | Entrer dans un dossier sans taper `cd` | └─ [status]
| `CORRECT` | Correction automatique des typos | ```
| `GLOB_DOTS` | Les fichiers cachés `.xxx` inclus dans les globs |
| `SHARE_HISTORY` | Historique partagé entre toutes les sessions zsh | - **Ligne 1** : separateur + infos (remplissage pointille entre gauche/droite)
| `HIST_IGNORE_DUPS` | Ne pas enregistrer les doublons dans l'historique | - **Ligne 2** : prompt `` — vert mitsuri si OK, magenta si erreur
| `HIST_IGNORE_SPACE` | Les commandes précédées d'un espace ne sont pas enregistrées | - **username@host** : cache en local, apparait en SSH
| `NO_BEEP` | Silence — pas de bip | - **sudo** : indicateur discret quand actif
- **battery** : visible sous 70%, rouge sous 30%
- **brain\_name** : affiche en italic quand la variable est definie

View File

@@ -0,0 +1,68 @@
# violet-chaton v2 — Palette Reference
> Mitsuri Kanroji inspired gradient magenta → green
> Created by Tetardtek — 2026
## Colors
### Backgrounds
| Name | Hex | Usage |
|------|-----|-------|
| crust | `#1a0e27` | Deepest background, panels heavy glass |
| base | `#261537` | Primary background, bar glass |
| mantle | `#341c4a` | Elevated surfaces |
| surface0 | `#3d2454` | Input backgrounds, troughs |
| surface1 | `#493161` | Hover states, subtle borders |
| surface2 | `#5a3875` | Active states, dividers |
### Accents
| Name | Hex | Usage |
|------|-----|-------|
| magenta | `#ff4da6` | Primary accent — clock, battery, volume, borders, heartbeat |
| lilac | `#c9a0ff` | Secondary accent — hover states, media, brain panel |
| mitsuri | `#9adba8` | Green pastel — charging state, success, health good |
| lavande | `#a4b4ff` | Blue-violet — date, CPU, network, info states |
| champagne | `#e8c87a` | Warm gold — warnings, session info |
| danger | `#f25c7a` | Red-pink — errors, low battery, disconnected |
### Text
| Name | Hex | Usage |
|------|-----|-------|
| text | `#f0eaf8` | Primary text |
| subtext1 | `#c4b8d4` | Secondary text, todo items |
| subtext0 | `#9a8fad` | Tertiary text |
| muted | `#716686` | Disabled, placeholders, empty states |
## Font
- **Primary**: Maple Mono NF (cursive italics)
- **Size**: 13px bold (bar), 14px 900 (clock, prompt)
- **Icons**: Nerd Font glyphs from Maple Mono NF
## Signature Visual Elements
- Glassmorphism: `rgba(38, 21, 55, 0.88)` (base @ 88%)
- Heavy glass: `rgba(26, 14, 39, 0.94)` (crust @ 94%)
- Border accent: `3px solid rgba(255, 77, 166, 0.60)` (magenta @ 60%)
- Hover glow: `box-shadow: 0 4px 28px rgba(201, 160, 255, 0.18)` (lilac @ 18%)
- Gradient progress: `linear-gradient(to right, magenta, lilac, lavande, mitsuri)`
- Heartbeat: gradient `magenta 0% → magenta 60% → lilac 80% → magenta 60% → magenta 0%`
- Border radius: 14px (pills), 8px (buttons)
## SCSS Variables
```scss
$crust: #1a0e27;
$base: #261537;
$mantle: #341c4a;
$surface0: #3d2454;
$surface1: #493161;
$surface2: #5a3875;
$magenta: #ff4da6;
$lilac: #c9a0ff;
$mitsuri: #9adba8;
$lavande: #a4b4ff;
$champagne: #e8c87a;
$danger: #f25c7a;
$text: #f0eaf8;
$subtext1: #c4b8d4;
$subtext0: #9a8fad;
$muted: #716686;
```