diff --git a/roles/serveur_keycloak/files/themes/alliance-boreale/account/resources/js/constellation.js b/roles/serveur_keycloak/files/themes/alliance-boreale/account/resources/js/constellation.js index 3cc80dc..cabb138 100644 --- a/roles/serveur_keycloak/files/themes/alliance-boreale/account/resources/js/constellation.js +++ b/roles/serveur_keycloak/files/themes/alliance-boreale/account/resources/js/constellation.js @@ -1,93 +1,97 @@ /* 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. */ + Vanilla JS, aucune dépendance. Crée son propre ciel en fond (le template Keycloak + n'a pas de ). Attend le DOM (le script est injecté dans ). + 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); + function init() { + if (!document.body || document.querySelector(".ab-sky")) return; - 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; + 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); - 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(); - } + 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 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 resize() { + w = canvas.clientWidth || window.innerWidth; + h = canvas.clientHeight || window.innerHeight; + canvas.width = w * dpr; + canvas.height = h * dpr; + ctx.setTransform(dpr, 0, 0, dpr, 0, 0); + seed(); } - } - 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(); + 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, dy = stars[i].y - stars[j].y; + var d = Math.sqrt(dx * dx + dy * dy); + if (d < LINK_DIST) { + ctx.strokeStyle = "rgba(120, 200, 255," + (1 - d / LINK_DIST) * 0.22 + ")"; + 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; + for (var k = 0; k < stars.length; k++) { + var s = stars[k]; + s.tw += 0.02; + ctx.beginPath(); + ctx.arc(s.x, s.y, s.r, 0, Math.PI * 2); + ctx.fillStyle = "rgba(255,255,255," + (0.6 + Math.sin(s.tw) * 0.4) + ")"; + 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); } - if (!reduce) requestAnimationFrame(draw); + + window.addEventListener("resize", resize); + resize(); + draw(); } - window.addEventListener("resize", resize); - resize(); - draw(); + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", init); + } else { + init(); + } })(); 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 daffa48..be877ed 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 @@ -22,7 +22,11 @@ html, body { height: 100%; font-family: var(--font); color: var(--ink); - background: #05060f !important; + /* Dégradé aurore en repli (visible même si le canvas ne se crée pas). */ + background: + radial-gradient(1200px 700px at 80% -10%, #131a44 0%, transparent 60%), + radial-gradient(900px 600px at 10% 0%, #0e1640 0%, transparent 55%), + linear-gradient(180deg, var(--bg-2) 0%, var(--bg) 70%) fixed !important; } .login-pf-page, body .login-pf-page { 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 index 3cc80dc..cabb138 100644 --- 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 @@ -1,93 +1,97 @@ /* 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. */ + Vanilla JS, aucune dépendance. Crée son propre ciel en fond (le template Keycloak + n'a pas de ). Attend le DOM (le script est injecté dans ). + 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); + function init() { + if (!document.body || document.querySelector(".ab-sky")) return; - 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; + 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); - 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(); - } + 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 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 resize() { + w = canvas.clientWidth || window.innerWidth; + h = canvas.clientHeight || window.innerHeight; + canvas.width = w * dpr; + canvas.height = h * dpr; + ctx.setTransform(dpr, 0, 0, dpr, 0, 0); + seed(); } - } - 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(); + 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, dy = stars[i].y - stars[j].y; + var d = Math.sqrt(dx * dx + dy * dy); + if (d < LINK_DIST) { + ctx.strokeStyle = "rgba(120, 200, 255," + (1 - d / LINK_DIST) * 0.22 + ")"; + 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; + for (var k = 0; k < stars.length; k++) { + var s = stars[k]; + s.tw += 0.02; + ctx.beginPath(); + ctx.arc(s.x, s.y, s.r, 0, Math.PI * 2); + ctx.fillStyle = "rgba(255,255,255," + (0.6 + Math.sin(s.tw) * 0.4) + ")"; + 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); } - if (!reduce) requestAnimationFrame(draw); + + window.addEventListener("resize", resize); + resize(); + draw(); } - window.addEventListener("resize", resize); - resize(); - draw(); + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", init); + } else { + init(); + } })();