From 53acf1e209f73150528f8e356d7da4a34f116236 Mon Sep 17 00:00:00 2001 From: Daniel Allaire Date: Fri, 3 Jul 2026 23:47:44 -0400 Subject: [PATCH] =?UTF-8?q?Th=C3=A8me=20Keycloak=20:=20constellation=20ani?= =?UTF-8?q?m=C3=A9e=20en=20fond=20du=20login?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Le JS (scripts=js/constellation.js) crée son propre ciel (canvas + aurore, le template Keycloak n'en ayant pas) : champ d'étoiles scintillantes qui dérivent, liens de constellation cyan, blob d'aurore ondulant. Respecte prefers-reduced-motion. Reprend l'animation du site de l'Alliance. Prouvé : constellation.js référencé + servi (200). Co-Authored-By: Claude Opus 4.8 --- CHANGELOG.md | 4 + .../login/resources/css/alliance.css | 38 +++++++- .../login/resources/js/constellation.js | 93 +++++++++++++++++++ .../alliance-boreale/login/theme.properties | 1 + 4 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 roles/serveur_keycloak/files/themes/alliance-boreale/login/resources/js/constellation.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 5458f70..b0b4bf2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,10 @@ `kcadm ... -s loginTheme` (var `serveur_keycloak_login_theme`, idempotent), Keycloak rechargé (`flush_handlers` avant la config realm). **Prouvé** : la page de login charge `alliance.css` (HTTP 200) + le `logo.svg` (200), `loginTheme=alliance-boreale` actif sur `chezlepro`. + **Constellation animée en fond** (`scripts=js/constellation.js`) : le JS crée son propre ciel + (canvas + aurore, le template n'en ayant pas) — étoiles scintillantes qui dérivent, liens de + constellation cyan, blob d'aurore ondulant ; respecte `prefers-reduced-motion`. Prouvé : + `constellation.js` référencé + servi (200). - **Soumission courriel `:587` interne (authentifiée) — la boucle souveraine est bouclée.** Postfix (`edge-mta`) sert la **soumission `:587`** (bloc `master.cf` : STARTTLS requis, `SMTP AUTH`, seuls les authentifiés relaient) ; l'auth SASL est **déléguée à Dovecot** (`infra-mail`, passdb LDAP diff --git a/roles/serveur_keycloak/files/themes/alliance-boreale/login/resources/css/alliance.css b/roles/serveur_keycloak/files/themes/alliance-boreale/login/resources/css/alliance.css index 6719d43..7e92b53 100644 --- a/roles/serveur_keycloak/files/themes/alliance-boreale/login/resources/css/alliance.css +++ b/roles/serveur_keycloak/files/themes/alliance-boreale/login/resources/css/alliance.css @@ -29,7 +29,43 @@ body { radial-gradient(900px 600px at 10% 0%, #0e1640 0%, transparent 55%), linear-gradient(180deg, var(--bg-2) 0%, var(--bg) 70%) fixed; } -.login-pf-page { padding-top: 40px; } +.login-pf-page { padding-top: 40px; background: transparent; } +#kc-container, #kc-container-wrapper, .login-pf-page .card-pf { position: relative; } + +/* ---------- Ciel animé : constellation + aurore (injecté par constellation.js) ---------- */ +.ab-sky { + position: fixed; + inset: 0; + z-index: -1; + overflow: hidden; + pointer-events: none; +} +.ab-sky canvas { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + display: block; +} +.ab-aurora { + position: absolute; + inset: -20% -10% auto -10%; + height: 70vh; + filter: blur(60px) saturate(140%); + opacity: 0.5; + background: + radial-gradient(40% 60% at 20% 30%, var(--aurora-teal) 0%, transparent 70%), + radial-gradient(45% 70% at 55% 20%, var(--aurora-cyan) 0%, transparent 70%), + radial-gradient(40% 65% at 80% 35%, var(--aurora-violet) 0%, transparent 70%); + animation: aurora-drift 22s ease-in-out infinite alternate; +} +@keyframes aurora-drift { + from { transform: translateX(-3%) translateY(0) scale(1); } + to { transform: translateX(3%) translateY(2%) scale(1.08); } +} +@media (prefers-reduced-motion: reduce) { + .ab-aurora { animation: none; } +} /* ---------- En-tête + logo étoile aurore ---------- */ #kc-header, diff --git a/roles/serveur_keycloak/files/themes/alliance-boreale/login/resources/js/constellation.js b/roles/serveur_keycloak/files/themes/alliance-boreale/login/resources/js/constellation.js new file mode 100644 index 0000000..3cc80dc --- /dev/null +++ b/roles/serveur_keycloak/files/themes/alliance-boreale/login/resources/js/constellation.js @@ -0,0 +1,93 @@ +/* Alliance Boréale — champ d'étoiles + constellation, adapté au login Keycloak. + Vanilla JS, aucune dépendance. Crée son propre ciel en fond (le template + Keycloak n'a pas de ). Respecte prefers-reduced-motion. + Métaphore : chaque artisan est une étoile ; reliés, ils forment la constellation. */ +(function () { + "use strict"; + if (document.querySelector(".ab-sky")) return; + + var sky = document.createElement("div"); + sky.className = "ab-sky"; + sky.setAttribute("aria-hidden", "true"); + var canvas = document.createElement("canvas"); + canvas.id = "ab-constellation"; + var aurora = document.createElement("div"); + aurora.className = "ab-aurora"; + sky.appendChild(canvas); + sky.appendChild(aurora); + document.body.insertBefore(sky, document.body.firstChild); + + var reduce = window.matchMedia("(prefers-reduced-motion: reduce)").matches; + var ctx = canvas.getContext("2d"); + var stars = []; + var w = 0, h = 0, dpr = Math.min(window.devicePixelRatio || 1, 2); + var LINK_DIST = 130; + + function resize() { + w = canvas.clientWidth; + h = canvas.clientHeight; + canvas.width = w * dpr; + canvas.height = h * dpr; + ctx.setTransform(dpr, 0, 0, dpr, 0, 0); + seed(); + } + + function seed() { + var count = Math.round((w * h) / 14000); + count = Math.max(40, Math.min(160, count)); + stars = []; + for (var i = 0; i < count; i++) { + stars.push({ + x: Math.random() * w, + y: Math.random() * h, + r: Math.random() * 1.3 + 0.4, + vx: (Math.random() - 0.5) * 0.12, + vy: (Math.random() - 0.5) * 0.12, + tw: Math.random() * Math.PI * 2 + }); + } + } + + function draw() { + ctx.clearRect(0, 0, w, h); + for (var i = 0; i < stars.length; i++) { + for (var j = i + 1; j < stars.length; j++) { + var dx = stars[i].x - stars[j].x; + var dy = stars[i].y - stars[j].y; + var d = Math.sqrt(dx * dx + dy * dy); + if (d < LINK_DIST) { + var a = (1 - d / LINK_DIST) * 0.22; + ctx.strokeStyle = "rgba(120, 200, 255," + a + ")"; + ctx.lineWidth = 1; + ctx.beginPath(); + ctx.moveTo(stars[i].x, stars[i].y); + ctx.lineTo(stars[j].x, stars[j].y); + ctx.stroke(); + } + } + } + for (var k = 0; k < stars.length; k++) { + var s = stars[k]; + s.tw += 0.02; + var glow = 0.6 + Math.sin(s.tw) * 0.4; + ctx.beginPath(); + ctx.arc(s.x, s.y, s.r, 0, Math.PI * 2); + ctx.fillStyle = "rgba(255,255,255," + glow + ")"; + ctx.shadowColor = "rgba(160,220,255,0.9)"; + ctx.shadowBlur = 6; + ctx.fill(); + ctx.shadowBlur = 0; + if (!reduce) { + s.x += s.vx; + s.y += s.vy; + if (s.x < 0 || s.x > w) s.vx *= -1; + if (s.y < 0 || s.y > h) s.vy *= -1; + } + } + if (!reduce) requestAnimationFrame(draw); + } + + window.addEventListener("resize", resize); + resize(); + draw(); +})(); diff --git a/roles/serveur_keycloak/files/themes/alliance-boreale/login/theme.properties b/roles/serveur_keycloak/files/themes/alliance-boreale/login/theme.properties index eb8f547..fc2aded 100644 --- a/roles/serveur_keycloak/files/themes/alliance-boreale/login/theme.properties +++ b/roles/serveur_keycloak/files/themes/alliance-boreale/login/theme.properties @@ -1,3 +1,4 @@ parent=keycloak import=common/keycloak styles=css/login.css css/alliance.css +scripts=js/constellation.js