diff --git a/website/_site/about/index.html b/website/_site/about/index.html
index bedce41..d3d8731 100644
--- a/website/_site/about/index.html
+++ b/website/_site/about/index.html
@@ -17,7 +17,7 @@
-
+
diff --git a/website/_site/assets/css/main.css b/website/_site/assets/css/main.css
index bf93ea2..2031449 100644
--- a/website/_site/assets/css/main.css
+++ b/website/_site/assets/css/main.css
@@ -7,9 +7,9 @@
--text: #f8fafc;
--muted: #aab6ca;
--soft: #64748b;
- /*--accent: #38bdf8;*/
- /*--accent2: #a855f7;*/
- /*--accent3: #22c55e;*/
+ --accent: #38bdf8;
+ --accent2: #a855f7;
+ --accent3: #22c55e;
--shadow: 0 24px 80px rgba(0, 0, 0, 0.45);
--accent: #54d63d;
@@ -39,37 +39,12 @@ body {
min-height: 100vh;
background:
- radial-gradient(
- circle at 14% 12%,
- rgba(52, 165, 57, 0.20),
- transparent 30%
- ),
- radial-gradient(
- circle at 82% 16%,
- rgba(95, 218, 82, 0.14),
- transparent 32%
- ),
- radial-gradient(
- circle at 50% 85%,
- rgba(32, 126, 55, 0.12),
- transparent 36%
- ),
- linear-gradient(
- 180deg,
- #070b09 0%,
- #0b1410 100%
- );
-
+ radial-gradient(circle at 14% 12%, rgba(168, 85, 247, 0.30), transparent 28%),
+ radial-gradient(circle at 82% 16%, rgba(56, 189, 248, 0.24), transparent 30%),
+ radial-gradient(circle at 50% 85%, rgba(34, 197, 94, 0.11), transparent 35%),
+ linear-gradient(180deg, #050816 0%, #07111f 100%);
color: var(--text);
- font-family:
- Inter,
- ui-sans-serif,
- system-ui,
- -apple-system,
- BlinkMacSystemFont,
- "Segoe UI",
- sans-serif;
-
+ font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
line-height: 1.65;
overflow-x: hidden;
}
@@ -602,153 +577,50 @@ a:hover {
}
/*
- * Interactive radio / aircraft-scatter hero layer
+ * Full-width, full-height home hero
*/
-.hero-radio-fx {
- position: absolute;
- inset: 0;
- z-index: 0;
+main {
width: 100%;
- height: 100%;
- pointer-events: none;
- opacity: 0.76;
}
-.hero-fx-vignette {
- position: absolute;
- inset: 0;
- z-index: 1;
- pointer-events: none;
-
- background:
- linear-gradient(
- 90deg,
- rgba(7, 11, 9, 0.92) 0%,
- rgba(7, 11, 9, 0.68) 34%,
- rgba(7, 11, 9, 0.16) 64%,
- rgba(7, 11, 9, 0.42) 100%
- ),
- linear-gradient(
- 180deg,
- rgba(7, 11, 9, 0.10),
- rgba(7, 11, 9, 0.58)
- );
+.hero.hero-split {
+ width: 100%;
+ max-width: none;
+ min-height: calc(100vh - 77px);
+ padding:
+ clamp(56px, 7vh, 100px)
+ clamp(28px, 6vw, 110px);
+ align-content: center;
+ overflow: hidden;
}
-.hero-split > *:not(.hero-radio-fx):not(.hero-fx-vignette) {
- position: relative;
- z-index: 2;
+.hero.hero-split > div:first-of-type {
+ max-width: 760px;
}
-/*
- * Operator-console badge styling
- */
-
-.badge,
-.eyebrow {
- color: #caffc0;
- background: rgba(52, 165, 57, 0.12);
- border-color: rgba(105, 232, 88, 0.32);
- box-shadow: 0 0 22px rgba(82, 255, 101, 0.08);
+.hero.hero-split .hero-panel {
+ width: min(100%, 700px);
+ justify-self: center;
}
-/*
- * Light-mode identity:
- * white/grey UI with red contest accents
- */
+@media (min-width: 1600px) {
+ .hero.hero-split {
+ grid-template-columns:
+ minmax(520px, 0.85fr)
+ minmax(600px, 1.15fr);
+ gap: clamp(50px, 6vw, 130px);
+ }
-html[data-theme="light"] {
- --bg: #f4f4f2;
- --bg2: #ffffff;
- --panel: rgba(255, 255, 255, 0.88);
- --panel2: rgba(242, 242, 239, 0.92);
- --border: rgba(91, 91, 86, 0.20);
- --text: #252522;
- --muted: #656560;
- --soft: #888881;
-
- --accent: #d33732;
- --accent2: #f25a51;
- --accent3: #ae2727;
-
- --fx-plane: #df3732;
- --fx-plane-muted: rgba(211, 55, 50, 0.38);
- --fx-beam: #ef4039;
- --fx-beam-glow: rgba(239, 64, 57, 0.22);
- --fx-reflection: #ff8d84;
- --fx-trail: rgba(211, 55, 50, 0.15);
- --fx-grid: rgba(185, 47, 43, 0.045);
-}
-
-html[data-theme="light"] body {
- background:
- radial-gradient(
- circle at 14% 12%,
- rgba(211, 55, 50, 0.12),
- transparent 30%
- ),
- radial-gradient(
- circle at 82% 16%,
- rgba(242, 90, 81, 0.09),
- transparent 32%
- ),
- linear-gradient(
- 180deg,
- #ffffff 0%,
- #f0f0ed 100%
- );
-}
-
-html[data-theme="light"] .hero-fx-vignette {
- background:
- linear-gradient(
- 90deg,
- rgba(255, 255, 255, 0.95) 0%,
- rgba(255, 255, 255, 0.76) 34%,
- rgba(255, 255, 255, 0.18) 66%,
- rgba(255, 255, 255, 0.48) 100%
- ),
- linear-gradient(
- 180deg,
- rgba(255, 255, 255, 0.06),
- rgba(240, 240, 237, 0.62)
- );
-}
-
-html[data-theme="light"] .badge,
-html[data-theme="light"] .eyebrow {
- color: #962a27;
- background: rgba(211, 55, 50, 0.08);
- border-color: rgba(211, 55, 50, 0.24);
+ .hero.hero-split .hero-panel {
+ width: min(100%, 780px);
+ }
}
@media (max-width: 900px) {
- .hero-radio-fx {
- opacity: 0.48;
- }
-
- .hero-fx-vignette {
- background:
- linear-gradient(
- 180deg,
- rgba(7, 11, 9, 0.82),
- rgba(7, 11, 9, 0.34)
- );
- }
-
- html[data-theme="light"] .hero-fx-vignette {
- background:
- linear-gradient(
- 180deg,
- rgba(255, 255, 255, 0.90),
- rgba(255, 255, 255, 0.42)
- );
- }
-}
-
-@media (prefers-reduced-motion: reduce) {
- .hero-radio-fx {
- opacity: 0.28;
+ .hero.hero-split {
+ min-height: auto;
+ padding-top: 60px;
+ padding-bottom: 60px;
}
}
\ No newline at end of file
diff --git a/website/_site/assets/js/hero-radio-fx.js b/website/_site/assets/js/hero-radio-fx.js
index b83644f..7c4a292 100644
--- a/website/_site/assets/js/hero-radio-fx.js
+++ b/website/_site/assets/js/hero-radio-fx.js
@@ -270,40 +270,91 @@
];
}
- function createBeam(target) {
- const leftStation = {
- x: state.width * 0.12,
- y: state.height * 0.82
+ function getRadioStations() {
+ const centerX = state.width * 0.54;
+ const centerY = state.height * 0.43;
+
+ const left = {
+ x: state.width * 0.075,
+ y: state.height * 0.82,
+ label: "JN49EM"
};
- const rightStation = {
- x: state.width * 0.88,
- y: state.height * 0.78
+ const right = {
+ x: state.width * 0.925,
+ y: state.height * 0.80,
+ label: "JO66MD"
};
- const source =
- Math.abs(target.x - leftStation.x) <
- Math.abs(target.x - rightStation.x)
- ? leftStation
- : rightStation;
+ left.angle = Math.atan2(
+ centerY - left.y,
+ centerX - left.x
+ );
+
+ right.angle = Math.atan2(
+ centerY - right.y,
+ centerX - right.x
+ );
+
+ return [left, right];
+ }
+
+ function createBeam(target) {function createBeam(target) {
+ const stations = getRadioStations();
+
+ const source = stations
+ .map((station) => ({
+ station,
+ distance: Math.hypot(
+ target.x - station.x,
+ target.y - station.y
+ )
+ }))
+ .sort((a, b) => a.distance - b.distance)[0].station;
+
+ const beamAngle = Math.atan2(
+ target.y - source.y,
+ target.x - source.x
+ );
+
+ /*
+ * Der Strahl beginnt nicht im Antennenmast,
+ * sondern etwas vor der Yagi.
+ */
+ const antennaTipDistance = 45;
+
+ const startX =
+ source.x +
+ Math.cos(beamAngle) * antennaTipDistance;
+
+ const startY =
+ source.y +
+ Math.sin(beamAngle) * antennaTipDistance;
state.beams.push({
- startX: source.x,
- startY: source.y,
+ startX,
+ startY,
endX: target.x,
endY: target.y,
age: 0,
- maximumAge: 0.62
+ maximumAge: 0.72
});
target.hit = 1;
+ const probabilities = [50, 75, 100];
+ const probability =
+ probabilities[
+ Math.floor(Math.random() * probabilities.length)
+ ];
+
state.reflections.push({
x: target.x,
y: target.y,
age: 0,
- maximumAge: 0.9,
- radius: randomBetween(8, 15)
+ maximumAge: 1.25,
+ radius: randomBetween(8, 13),
+ probability
});
}
@@ -394,6 +445,126 @@
context.restore();
}
+ function drawYagi(station, palette) {
+ context.save();
+
+ context.translate(station.x, station.y);
+ context.rotate(station.angle);
+
+ context.strokeStyle = palette.plane;
+ context.fillStyle = palette.plane;
+ context.lineCap = "round";
+ context.lineWidth = 1.5;
+
+ context.shadowColor = palette.beamGlow;
+ context.shadowBlur = 9;
+
+ /*
+ * Mast
+ */
+ context.beginPath();
+ context.moveTo(-30, 26);
+ context.lineTo(-30, -5);
+ context.stroke();
+
+ /*
+ * Ausleger / Boom
+ */
+ context.beginPath();
+ context.moveTo(-32, 0);
+ context.lineTo(43, 0);
+ context.stroke();
+
+ /*
+ * Reflektor
+ */
+ context.beginPath();
+ context.moveTo(-27, -17);
+ context.lineTo(-27, 17);
+ context.stroke();
+
+ /*
+ * Dipol
+ */
+ context.beginPath();
+ context.moveTo(-12, -14);
+ context.lineTo(-12, 14);
+ context.stroke();
+
+ /*
+ * Direktoren
+ */
+ const directors = [
+ { x: 2, length: 22 },
+ { x: 14, length: 19 },
+ { x: 25, length: 16 },
+ { x: 35, length: 13 }
+ ];
+
+ for (const director of directors) {
+ context.beginPath();
+ context.moveTo(
+ director.x,
+ -director.length / 2
+ );
+ context.lineTo(
+ director.x,
+ director.length / 2
+ );
+ context.stroke();
+ }
+
+ /*
+ * Einspeisepunkt
+ */
+ context.beginPath();
+ context.arc(-12, 0, 3.2, 0, Math.PI * 2);
+ context.fill();
+
+ context.restore();
+
+ /*
+ * Locator bleibt waagerecht lesbar.
+ */
+ context.save();
+
+ context.font =
+ '700 11px Inter, system-ui, sans-serif';
+
+ const labelWidth =
+ context.measureText(station.label).width + 14;
+
+ const labelX = station.x - labelWidth / 2;
+ const labelY = station.y + 32;
+
+ context.fillStyle = "rgba(6, 18, 10, 0.86)";
+ context.strokeStyle = palette.planeMuted;
+ context.lineWidth = 1;
+
+ context.beginPath();
+ context.roundRect(
+ labelX,
+ labelY,
+ labelWidth,
+ 23,
+ 6
+ );
+ context.fill();
+ context.stroke();
+
+ context.fillStyle = palette.plane;
+ context.textAlign = "center";
+ context.textBaseline = "middle";
+
+ context.fillText(
+ station.label,
+ station.x,
+ labelY + 11.5
+ );
+
+ context.restore();
+ }
+
function drawPlane(plane, palette) {
context.save();
@@ -465,17 +636,20 @@
context.globalAlpha = alpha;
context.strokeStyle = palette.beamGlow;
- context.lineWidth = 6;
+ context.lineWidth = 8;
context.shadowColor = palette.beam;
context.shadowBlur = 15;
+ context.setLineDash([10, 6]);
+ context.lineDashOffset = -progress * 36;
+
context.beginPath();
context.moveTo(beam.startX, beam.startY);
context.lineTo(beam.endX, beam.endY);
context.stroke();
context.strokeStyle = palette.beam;
- context.lineWidth = 1.4;
+ context.lineWidth = 1.8;
context.shadowBlur = 5;
context.beginPath();
@@ -483,34 +657,145 @@
context.lineTo(beam.endX, beam.endY);
context.stroke();
- context.restore();
- }
-
- function drawReflection(reflection, palette) {
- const progress =
- reflection.age / reflection.maximumAge;
-
- context.save();
-
- context.globalAlpha = 1 - progress;
- context.strokeStyle = palette.reflection;
- context.lineWidth = 1.5;
- context.shadowColor = palette.beam;
- context.shadowBlur = 12;
-
- context.beginPath();
- context.arc(
- reflection.x,
- reflection.y,
- reflection.radius,
- 0,
- Math.PI * 2
- );
- context.stroke();
+ context.setLineDash([]);
context.restore();
}
+ function drawReflection(reflection, palette) {
+ const progress =
+ reflection.age / reflection.maximumAge;
+
+ const alpha = 1 - progress;
+
+ context.save();
+
+ context.translate(
+ reflection.x,
+ reflection.y
+ );
+
+ context.globalAlpha = alpha;
+
+ /*
+ * Äußerer Reflexionsring
+ */
+ context.strokeStyle = palette.reflection;
+ context.lineWidth = 1.6;
+ context.shadowColor = palette.beam;
+ context.shadowBlur = 18;
+
+ context.beginPath();
+ context.arc(
+ 0,
+ 0,
+ reflection.radius,
+ 0,
+ Math.PI * 2
+ );
+ context.stroke();
+
+ /*
+ * Zweiter Ring
+ */
+ context.globalAlpha = alpha * 0.55;
+
+ context.beginPath();
+ context.arc(
+ 0,
+ 0,
+ reflection.radius * 1.65,
+ 0,
+ Math.PI * 2
+ );
+ context.stroke();
+
+ /*
+ * Reflexionskreuz
+ */
+ context.globalAlpha = alpha * 0.8;
+ context.lineWidth = 1;
+
+ const crossSize =
+ reflection.radius * 1.25;
+
+ context.beginPath();
+ context.moveTo(-crossSize, 0);
+ context.lineTo(crossSize, 0);
+ context.moveTo(0, -crossSize);
+ context.lineTo(0, crossSize);
+ context.stroke();
+
+ /*
+ * Heller Reflexionspunkt
+ */
+ context.globalAlpha = alpha;
+ context.fillStyle = palette.reflection;
+ context.shadowBlur = 24;
+
+ context.beginPath();
+ context.arc(0, 0, 3.8, 0, Math.PI * 2);
+ context.fill();
+
+ context.restore();
+
+ /*
+ * AP-Prozentwert
+ */
+ context.save();
+
+ const label = `${reflection.probability}%`;
+
+ context.font =
+ '800 12px Inter, system-ui, sans-serif';
+
+ const textWidth =
+ context.measureText(label).width;
+
+ const boxWidth = textWidth + 16;
+ const boxHeight = 25;
+
+ const boxX =
+ reflection.x + reflection.radius + 12;
+
+ const boxY =
+ reflection.y - reflection.radius - 17;
+
+ context.globalAlpha =
+ clamp(alpha * 1.25, 0, 1);
+
+ context.fillStyle = "rgba(6, 18, 10, 0.91)";
+ context.strokeStyle = palette.plane;
+ context.lineWidth = 1;
+
+ context.shadowColor = palette.beamGlow;
+ context.shadowBlur = 10;
+
+ context.beginPath();
+ context.roundRect(
+ boxX,
+ boxY,
+ boxWidth,
+ boxHeight,
+ 6
+ );
+ context.fill();
+ context.stroke();
+
+ context.shadowBlur = 0;
+ context.fillStyle = palette.reflection;
+ context.textAlign = "center";
+ context.textBaseline = "middle";
+
+ context.fillText(
+ label,
+ boxX + boxWidth / 2,
+ boxY + boxHeight / 2
+ );
+
+ context.restore();
+ }
+
function drawStaticScene() {
const palette = getPalette();
@@ -523,6 +808,10 @@
drawGrid(palette);
drawRadarTarget(palette);
+
+ for (const station of getRadioStations()) {
+ drawYagi(station, palette);
+ }
}
function drawScene() {
@@ -538,6 +827,10 @@
drawGrid(palette);
drawRadarTarget(palette);
+ for (const station of getRadioStations()) {
+ drawYagi(station, palette);
+ }
+
for (const plane of state.planes) {
drawPlane(plane, palette);
}
diff --git a/website/_site/contact/index.html b/website/_site/contact/index.html
index c13f44e..e07d3d4 100644
--- a/website/_site/contact/index.html
+++ b/website/_site/contact/index.html
@@ -17,7 +17,7 @@
-
+
diff --git a/website/_site/download/index.html b/website/_site/download/index.html
index 972a8d1..2e11ce1 100644
--- a/website/_site/download/index.html
+++ b/website/_site/download/index.html
@@ -17,7 +17,7 @@
-
+
diff --git a/website/_site/faq/index.html b/website/_site/faq/index.html
index c57844f..a8ca646 100644
--- a/website/_site/faq/index.html
+++ b/website/_site/faq/index.html
@@ -17,7 +17,7 @@
-
+
diff --git a/website/_site/features/airscout/index.html b/website/_site/features/airscout/index.html
index 380605b..e2f5df1 100644
--- a/website/_site/features/airscout/index.html
+++ b/website/_site/features/airscout/index.html
@@ -17,7 +17,7 @@
-
+
diff --git a/website/_site/features/dual-chat/index.html b/website/_site/features/dual-chat/index.html
index f858c9a..0fa3ea8 100644
--- a/website/_site/features/dual-chat/index.html
+++ b/website/_site/features/dual-chat/index.html
@@ -17,7 +17,7 @@
-
+
diff --git a/website/_site/features/dx-cluster/index.html b/website/_site/features/dx-cluster/index.html
index 17fcb4f..d3890e5 100644
--- a/website/_site/features/dx-cluster/index.html
+++ b/website/_site/features/dx-cluster/index.html
@@ -17,7 +17,7 @@
-
+
diff --git a/website/_site/features/index.html b/website/_site/features/index.html
index 9bab3cb..febe429 100644
--- a/website/_site/features/index.html
+++ b/website/_site/features/index.html
@@ -17,7 +17,7 @@
-
+
diff --git a/website/_site/features/log-sync/index.html b/website/_site/features/log-sync/index.html
index 0c76230..75851c5 100644
--- a/website/_site/features/log-sync/index.html
+++ b/website/_site/features/log-sync/index.html
@@ -17,7 +17,7 @@
-
+
diff --git a/website/_site/features/macros/index.html b/website/_site/features/macros/index.html
index a104e9f..939281d 100644
--- a/website/_site/features/macros/index.html
+++ b/website/_site/features/macros/index.html
@@ -17,7 +17,7 @@
-
+
diff --git a/website/_site/features/priority-score/index.html b/website/_site/features/priority-score/index.html
index 8412805..e7cbe5a 100644
--- a/website/_site/features/priority-score/index.html
+++ b/website/_site/features/priority-score/index.html
@@ -17,7 +17,7 @@
-
+
diff --git a/website/_site/features/sked-reminder/index.html b/website/_site/features/sked-reminder/index.html
index 43a8627..51a7bde 100644
--- a/website/_site/features/sked-reminder/index.html
+++ b/website/_site/features/sked-reminder/index.html
@@ -17,7 +17,7 @@
-
+
diff --git a/website/_site/features/timeline/index.html b/website/_site/features/timeline/index.html
index c174a14..0e09da8 100644
--- a/website/_site/features/timeline/index.html
+++ b/website/_site/features/timeline/index.html
@@ -17,7 +17,7 @@
-
+
diff --git a/website/_site/index.html b/website/_site/index.html
index 79c069e..d355c52 100644
--- a/website/_site/index.html
+++ b/website/_site/index.html
@@ -17,7 +17,7 @@
-
+
@@ -298,7 +298,7 @@
-
+