Skip to content

Commit 17e4c93

Browse files
Update CSS
1 parent cfec17d commit 17e4c93

2 files changed

Lines changed: 103 additions & 26 deletions

File tree

app.js

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2446,9 +2446,10 @@
24462446
const total = Math.max(remaining.length, 1);
24472447
const angle = (Math.PI * 2 * index) / total - Math.PI / 2;
24482448
const nodeClass = constellationClassForType(node.type);
2449-
const ring = nodeClass === "node--movement" ? 30 : (nodeClass === "node--artist" ? 24 : 18);
2450-
const x = 50 + Math.cos(angle) * ring;
2451-
const y = 50 + Math.sin(angle) * (ring * 0.78);
2449+
const ring = nodeClass === "node--movement" ? 34 : (nodeClass === "node--artist" ? 26 : 18);
2450+
const jitter = ((index % 2 === 0 ? 1 : -1) * 0.9) + ((index % 3) - 1) * 0.4;
2451+
const x = 50 + Math.cos(angle) * ring + Math.sin(angle) * (ring * 0.08) * jitter;
2452+
const y = 50 + Math.sin(angle) * ring * 0.92 + Math.cos(angle) * (ring * 0.06) * jitter;
24522453
positions.set(node.id, {
24532454
x: Math.max(12, Math.min(88, x)),
24542455
y: Math.max(14, Math.min(84, y))
@@ -2478,6 +2479,46 @@
24782479
const seenRelations = new Set();
24792480
const visibleNodeIds = new Set(nodes.map((node) => node.id));
24802481

2482+
function updateHoverState(activeNodeId) {
2483+
const nodeEls = constellationNodesEl.querySelectorAll(".node");
2484+
const linkEls = constellationLinksEl.querySelectorAll(".link");
2485+
const connectedIds = new Set();
2486+
2487+
linkEls.forEach((linkEl) => {
2488+
const sourceId = linkEl.dataset.source;
2489+
const targetId = linkEl.dataset.target;
2490+
if (sourceId === activeNodeId || targetId === activeNodeId) {
2491+
linkEl.classList.add("is-connected");
2492+
connectedIds.add(sourceId);
2493+
connectedIds.add(targetId);
2494+
} else {
2495+
linkEl.classList.remove("is-connected");
2496+
}
2497+
});
2498+
2499+
nodeEls.forEach((nodeEl2) => {
2500+
const id = nodeEl2.dataset.nodeId;
2501+
if (id === activeNodeId) {
2502+
nodeEl2.classList.add("is-hovered");
2503+
nodeEl2.classList.remove("is-connected");
2504+
} else if (connectedIds.has(id)) {
2505+
nodeEl2.classList.add("is-connected");
2506+
nodeEl2.classList.remove("is-hovered");
2507+
} else {
2508+
nodeEl2.classList.remove("is-connected", "is-hovered");
2509+
}
2510+
});
2511+
}
2512+
2513+
function resetHoverState() {
2514+
constellationLinksEl.querySelectorAll(".link").forEach((linkEl) => {
2515+
linkEl.classList.remove("is-connected");
2516+
});
2517+
constellationNodesEl.querySelectorAll(".node").forEach((nodeEl2) => {
2518+
nodeEl2.classList.remove("is-connected", "is-hovered");
2519+
});
2520+
}
2521+
24812522
((((snapshot.graphe || {}).relations) || [])).forEach((relation) => {
24822523
const key = [relation.source, relation.target, relation.type].join("|");
24832524
if (seenRelations.has(key)) {
@@ -2503,6 +2544,8 @@
25032544
const link = document.createElement("div");
25042545
const isMutedTemporally = temporalFocus && (!temporalFocus.activeIds.has(relation.source) || !temporalFocus.activeIds.has(relation.target));
25052546
link.className = "link" + (isMutedTemporally ? " is-muted-temporal" : "");
2547+
link.dataset.source = relation.source;
2548+
link.dataset.target = relation.target;
25062549
link.style.left = source.x + "%";
25072550
link.style.top = source.y + "%";
25082551
link.style.width = length + "%";
@@ -2517,6 +2560,7 @@
25172560
const isFilterFocus = nodeMatchesShellFilter(node, snapshot);
25182561
const nodeEl = document.createElement("button");
25192562
nodeEl.type = "button";
2563+
nodeEl.dataset.nodeId = node.id;
25202564
nodeEl.className = "node " + constellationClassForType(node.type) + (node.id === selectedId ? " is-selected" : "") + (snapshot.affichage_chargement && node.id === runtimeState.lastRequestedEntityId ? " is-loading" : "") + (isTemporalFocus ? " is-temporal-focus" : "") + (isMutedTemporally ? " is-muted-temporal" : "") + (runtimeState.shellFilter && runtimeState.shellFilter.effectiveLens && isFilterFocus ? " is-filter-focus" : "");
25212565
nodeEl.style.left = position.x + "%";
25222566
nodeEl.style.top = position.y + "%";
@@ -2527,6 +2571,11 @@
25272571
label.textContent = node.etiquette || node.id;
25282572
nodeEl.appendChild(label);
25292573

2574+
nodeEl.addEventListener("mouseenter", () => updateHoverState(node.id));
2575+
nodeEl.addEventListener("focus", () => updateHoverState(node.id));
2576+
nodeEl.addEventListener("mouseleave", resetHoverState);
2577+
nodeEl.addEventListener("blur", resetHoverState);
2578+
25302579
nodeEl.addEventListener("click", async () => {
25312580
try {
25322581
await loadEntityByNode(node);

styles.css

Lines changed: 51 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,29 +1081,37 @@
10811081
.constellation-grid {
10821082
z-index: 0;
10831083
background-image:
1084+
radial-gradient(circle at 18% 18%, rgba(110, 243, 255, 0.05), transparent 0 2.8%),
1085+
radial-gradient(circle at 72% 28%, rgba(219, 178, 97, 0.04), transparent 0 2.5%),
10841086
linear-gradient(rgba(255, 255, 255, 0.03) 1px, transparent 1px),
10851087
linear-gradient(90deg, rgba(255, 255, 255, 0.03) 1px, transparent 1px);
10861088
background-size: 88px 88px;
1089+
background-blend-mode: screen;
10871090
-webkit-mask-image: radial-gradient(circle at center, black 28%, transparent 85%);
10881091
mask-image: radial-gradient(circle at center, black 28%, transparent 85%);
10891092
}
10901093

10911094
@media (prefers-color-scheme: light) {
10921095
html:not(.theme-dark) .constellation-grid {
10931096
background-image:
1097+
radial-gradient(circle at 18% 18%, rgba(43, 143, 134, 0.05), transparent 0 2.8%),
1098+
radial-gradient(circle at 72% 28%, rgba(184, 134, 11, 0.03), transparent 0 2.5%),
10941099
linear-gradient(rgba(0, 0, 0, 0.02) 1px, transparent 1px),
10951100
linear-gradient(90deg, rgba(0, 0, 0, 0.02) 1px, transparent 1px);
10961101
}
10971102
}
10981103

10991104
html.theme-light .constellation-grid {
11001105
background-image:
1106+
radial-gradient(circle at 18% 18%, rgba(43, 143, 134, 0.05), transparent 0 2.8%),
1107+
radial-gradient(circle at 72% 28%, rgba(184, 134, 11, 0.03), transparent 0 2.5%),
11011108
linear-gradient(rgba(0, 0, 0, 0.02) 1px, transparent 1px),
11021109
linear-gradient(90deg, rgba(0, 0, 0, 0.02) 1px, transparent 1px);
11031110
}
11041111

11051112
.constellation-links {
11061113
z-index: 1;
1114+
pointer-events: none;
11071115
}
11081116

11091117
.constellation-nodes {
@@ -1113,10 +1121,17 @@
11131121
.link {
11141122
position: absolute;
11151123
height: 1px;
1116-
background: linear-gradient(90deg, transparent, rgba(139, 233, 253, 0.5), transparent);
1124+
border-radius: 999px;
1125+
background: linear-gradient(90deg, transparent 0%, rgba(110, 243, 255, 0.18) 20%, rgba(214, 164, 88, 0.42) 50%, rgba(110, 243, 255, 0.18) 80%, transparent 100%);
1126+
box-shadow: 0 0 16px rgba(110, 243, 255, 0.12), inset 0 0 8px rgba(255, 255, 255, 0.1);
11171127
transform-origin: left center;
1118-
opacity: 0.7;
1119-
transition: opacity 160ms ease, filter 160ms ease;
1128+
opacity: 0.62;
1129+
transition: opacity 180ms ease, filter 180ms ease, background 180ms ease;
1130+
}
1131+
1132+
.link.is-connected {
1133+
opacity: 1;
1134+
filter: saturate(1.15) drop-shadow(0 0 8px rgba(110, 243, 255, 0.22));
11201135
}
11211136

11221137
.node {
@@ -1125,37 +1140,41 @@
11251140
place-items: center;
11261141
border-radius: 50%;
11271142
border: 2px solid rgba(255, 255, 255, 0.22);
1128-
-webkit-backdrop-filter: blur(6px);
1129-
backdrop-filter: blur(6px);
1130-
box-shadow: 0 0 24px rgba(110, 243, 255, 0.15);
1143+
background-clip: padding-box;
1144+
-webkit-backdrop-filter: blur(8px);
1145+
backdrop-filter: blur(8px);
1146+
box-shadow: 0 0 32px rgba(110, 243, 255, 0.12);
11311147
cursor: pointer;
11321148
transform: translate(-50%, -50%);
11331149
-webkit-appearance: none;
11341150
appearance: none;
11351151
padding: 0;
11361152
margin: 0;
11371153
animation: nodeAppear 260ms ease;
1138-
transition: transform var(--transition-normal), box-shadow var(--transition-normal), border-color var(--transition-normal), opacity var(--transition-normal), filter var(--transition-normal);
1154+
transition: transform var(--transition-normal), box-shadow var(--transition-normal), border-color var(--transition-normal), opacity var(--transition-normal), filter var(--transition-normal), background var(--transition-normal);
11391155
}
11401156

11411157
.node:hover,
1142-
.node:focus-visible {
1143-
transform: translate(-50%, -50%) scale(1.08);
1144-
border-color: rgba(255, 255, 255, 0.48);
1145-
box-shadow: 0 0 32px rgba(110, 243, 255, 0.28);
1158+
.node:focus-visible,
1159+
.node.is-connected,
1160+
.node.is-hovered {
1161+
transform: translate(-50%, -50%) scale(1.1);
1162+
border-color: rgba(255, 255, 255, 0.52);
1163+
box-shadow: 0 0 32px rgba(110, 243, 255, 0.3), 0 0 6px rgba(255, 255, 255, 0.08);
1164+
z-index: 4;
11461165
}
11471166

11481167
.node.is-selected {
1149-
border-color: rgba(214, 164, 88, 0.58);
1150-
box-shadow: 0 0 34px rgba(214, 164, 88, 0.24);
1168+
border-color: rgba(214, 164, 88, 0.72);
1169+
box-shadow: 0 0 42px rgba(214, 164, 88, 0.3), 0 0 18px rgba(110, 243, 255, 0.12);
11511170
}
11521171

11531172
.node.is-selected.node--work {
1154-
width: 58px;
1155-
height: 58px;
1173+
width: 62px;
1174+
height: 62px;
11561175
z-index: 5;
1157-
background: radial-gradient(circle, rgba(238, 161, 200, 0.56), rgba(238, 161, 200, 0.12));
1158-
box-shadow: 0 0 42px rgba(238, 161, 200, 0.3), 0 0 20px rgba(214, 164, 88, 0.18);
1176+
background: radial-gradient(circle, rgba(238, 161, 200, 0.68), rgba(238, 161, 200, 0.14));
1177+
box-shadow: 0 0 44px rgba(238, 161, 200, 0.34), 0 0 20px rgba(214, 164, 88, 0.2);
11591178
}
11601179

11611180
.node.is-loading {
@@ -1166,12 +1185,12 @@
11661185

11671186
.node.is-muted-temporal,
11681187
.link.is-muted-temporal {
1169-
opacity: 0.2;
1188+
opacity: 0.22;
11701189
filter: saturate(0.75);
11711190
}
11721191

11731192
.node.is-temporal-focus {
1174-
box-shadow: 0 0 30px rgba(77, 182, 172, 0.28);
1193+
box-shadow: 0 0 34px rgba(77, 182, 172, 0.32);
11751194
}
11761195

11771196
.node.is-filter-muted,
@@ -1181,7 +1200,7 @@
11811200
}
11821201

11831202
.node.is-filter-focus {
1184-
box-shadow: 0 0 28px rgba(214, 164, 88, 0.18);
1203+
box-shadow: 0 0 30px rgba(214, 164, 88, 0.18);
11851204
}
11861205

11871206
.node--movement {
@@ -1204,19 +1223,28 @@
12041223

12051224
.node-label {
12061225
position: absolute;
1207-
top: calc(100% + 10px);
1226+
top: calc(100% + 8px);
12081227
left: 50%;
1209-
transform: translateX(-50%);
1228+
transform: translateX(-50%) translateY(0);
12101229
white-space: nowrap;
12111230
font-family: Arial, Helvetica, sans-serif;
1212-
font-size: 0.77rem;
1231+
font-size: 0.78rem;
12131232
letter-spacing: 0.04em;
12141233
color: var(--text-soft);
12151234
pointer-events: none;
1235+
opacity: 0.86;
1236+
transition: opacity 180ms ease, transform 180ms ease, color 180ms ease;
12161237
}
12171238

1239+
.node:hover .node-label,
1240+
.node:focus-visible .node-label,
12181241
.node.is-selected .node-label {
1242+
opacity: 1;
1243+
transform: translateX(-50%) translateY(0);
12191244
color: var(--text-main);
1245+
}
1246+
1247+
.node.is-selected .node-label {
12201248
font-weight: 600;
12211249
font-size: 0.84rem;
12221250
text-shadow: 0 0 14px rgba(255, 255, 255, 0.12);

0 commit comments

Comments
 (0)