diff --git a/src/main/java/kst4contest/view/map/MapHtmlResources.java b/src/main/java/kst4contest/view/map/MapHtmlResources.java
index ab6223b..490208a 100644
--- a/src/main/java/kst4contest/view/map/MapHtmlResources.java
+++ b/src/main/java/kst4contest/view/map/MapHtmlResources.java
@@ -13,8 +13,12 @@ import java.nio.charset.StandardCharsets;
* - inspectPoint(x,y) returns what is under the cursor
* - zoomIn()/zoomOut() are callable from Java
* - grid / beam / connection use non-interactive panes
- * - JavaScript logs are forwarded to Java through javaMapBridge
+ * - JavaScript errors are forwarded to Java through javaMapBridge
* - setTheme(light|dark) aligns the map with the JavaFX application theme
+ *
+ * Important:
+ * This version intentionally uses integer Leaflet zoom levels again.
+ * Fractional zoom in JavaFX WebView caused unreliable marker positioning.
*/
public final class MapHtmlResources {
@@ -184,6 +188,111 @@ public final class MapHtmlResources {
font-weight: 800;
}
+ .station-cluster-wrapper {
+ background: transparent;
+ border: none;
+ box-shadow: none;
+ }
+
+ .station-cluster-root {
+ position: relative;
+ width: 1px;
+ height: 1px;
+ pointer-events: auto;
+ cursor: pointer;
+ user-select: none;
+ }
+
+ /*
+ * Cluster design aligned with normal KST4Contest station markers:
+ * - dark center like station-dot
+ * - blue border for normal clustered stations
+ * - yellow border when the cluster contains worked stations
+ * - orange hover border similar to selected station state
+ */
+ .station-cluster-bubble {
+ position: absolute;
+ left: -16px;
+ top: -16px;
+ min-width: 32px;
+ height: 32px;
+ padding: 0 7px;
+ border-radius: 18px;
+ background: #1d1d1d;
+ color: #f4f7fa;
+ border: 2px solid #4da6ff;
+ box-shadow:
+ 0 0 0 1px rgba(0, 0, 0, 0.35),
+ 0 2px 7px rgba(0, 0, 0, 0.42);
+ box-sizing: border-box;
+ font-size: 13px;
+ font-weight: 800;
+ line-height: 28px;
+ text-align: center;
+ white-space: nowrap;
+ }
+
+ .station-cluster-bubble.medium {
+ left: -18px;
+ top: -18px;
+ min-width: 36px;
+ height: 36px;
+ border-radius: 20px;
+ font-size: 14px;
+ line-height: 32px;
+ }
+
+ .station-cluster-bubble.large {
+ left: -21px;
+ top: -21px;
+ min-width: 42px;
+ height: 42px;
+ border-radius: 23px;
+ font-size: 15px;
+ line-height: 38px;
+ }
+
+ .station-cluster-bubble.worked {
+ border-color: #ffd24d;
+ }
+
+ .station-cluster-bubble.warning {
+ border-color: #00ff66;
+ color: #00ff66;
+ }
+
+ .station-cluster-root:hover .station-cluster-bubble {
+ border-color: #ff9900;
+ box-shadow:
+ 0 0 0 2px rgba(255, 153, 0, 0.28),
+ 0 2px 9px rgba(0, 0, 0, 0.48);
+ }
+
+ body.kst-theme-dark .station-cluster-bubble {
+ background: #202428;
+ color: #f1f3f5;
+ border-color: #4da6ff;
+ box-shadow:
+ 0 0 0 1px rgba(255, 255, 255, 0.12),
+ 0 2px 8px rgba(0, 0, 0, 0.58);
+ }
+
+ body.kst-theme-dark .station-cluster-bubble.worked {
+ border-color: #ffd24d;
+ }
+
+ body.kst-theme-dark .station-cluster-bubble.warning {
+ border-color: #00ff66;
+ color: #00ff66;
+ }
+
+ body.kst-theme-dark .station-cluster-root:hover .station-cluster-bubble {
+ border-color: #ff9900;
+ box-shadow:
+ 0 0 0 2px rgba(255, 153, 0, 0.32),
+ 0 2px 10px rgba(0, 0, 0, 0.65);
+ }
+
.maidenhead-grid-label-wrapper {
background: transparent;
border: none;
@@ -225,9 +334,6 @@ public final class MapHtmlResources {