diff --git a/workspace/assets/css/heim.css b/workspace/assets/css/heim.css
index 96c20fd5..5c888546 100644
--- a/workspace/assets/css/heim.css
+++ b/workspace/assets/css/heim.css
@@ -1659,3 +1659,77 @@
weniger Reiz. Die Bahnen bleiben in voller Farbe stehen. */
.uhr__sekunde, .uhr__minute, .uhr__stunde { filter: none; }
}
+
+/* ===================================================================
+ DER KOMETENSCHWEIF (08.09.2026)
+
+ Filipe: "auch die lichter von sekunden, minuten und stunden perfekt
+ anpassen, wie die läuft und aussieht soll wirklich mega perfekt sein
+ ... überrasch mich."
+
+ WAS ER LEISTET: Ein Bogen in gleichmaessiger Farbe zeigt einen
+ STAND. Ein Bogen, der zur Spitze hin heller wird, zeigt eine
+ RICHTUNG -- man sieht ohne Nachdenken, wo "jetzt" ist und wohin es
+ laeuft. Bei drei Ringen uebereinander ist das der Unterschied
+ zwischen Ablesen und Erkennen.
+
+ WARUM ZWEI LAGEN UND KEIN VERLAUF: Ein Farbverlauf ENTLANG einer
+ Kreisbahn geht in SVG nicht -- `linearGradient` folgt einer Geraden,
+ `radialGradient` einem Radius, keiner einer Bahn. Der ehrliche Weg
+ ist ein zweites, kuerzeres Segment ueber dem ersten. Es liegt vor
+ der Oberkante, damit die helle Kante auch auf dem Schweif sitzt.
+
+ `stroke-linecap: round` nur hier, nicht am Hauptbogen: Die runde
+ Kappe markiert die Spitze. Am Hauptbogen wuerde sie auch den ANFANG
+ runden -- und der liegt bei zwoelf Uhr, wo eine runde Kappe wie ein
+ Fehler aussieht.
+
+ AUGENSCHONEND: Der Schweif ist heller als der Bogen, aber nicht
+ greller -- er bleibt in derselben Farbfamilie und wird nicht
+ animiert. Was hier leuchtet, leuchtet ruhig. */
+/* KEINE EIGENE DREHUNG (Korrektur nach dem Bildschirmfoto).
+
+ Ich hatte hier `transform: rotate(-90deg)` gesetzt, damit der
+ Schweif wie die Bahnen bei zwoelf Uhr beginnt. Das war doppelt: Das
+ ganze SVG `.uhr__ring` ist bereits um -90 Grad gedreht (siehe dort,
+ "Bei Null soll der Ring OBEN beginnen"). Die Schweife standen
+ dadurch exakt eine Vierteldrehung neben ihren Boegen -- im Bild oben
+ links, waehrend die Boegen oben rechts endeten. Die Rechnung war
+ richtig, die Drehung eine zu viel. */
+.uhr__spur-bahn {
+ fill: none;
+ stroke-linecap: round;
+ opacity: .95;
+}
+.uhr__spur-bahn[data-spur="sekunde"] {
+ stroke: #ffd2d6; stroke-width: 3;
+ filter: drop-shadow(0 0 3px rgba(255, 120, 134, .85));
+}
+.uhr__spur-bahn[data-spur="minute"] {
+ stroke: #d8efff; stroke-width: 3.4;
+ filter: drop-shadow(0 0 3px rgba(130, 205, 255, .8));
+}
+.uhr__spur-bahn[data-spur="stunde"] {
+ stroke: #ffe9c9; stroke-width: 4;
+ filter: drop-shadow(0 0 3px rgba(233, 190, 130, .75));
+}
+
+/* DIE KOEPFE GLEITEN, STATT ZU SPRINGEN.
+
+ Die Anzeige selbst rechnet weiterhin nur EINMAL je Sekunde -- das
+ war eine bewusste Entscheidung (sechzig Bildberechnungen je Sekunde
+ halten auf einer stundenlang offenen Seite den Rechner warm). Die
+ Bewegung dazwischen uebernimmt der Browser: eine Ueberblendung von
+ knapp einer Sekunde, die genau bis zum naechsten Takt laeuft.
+
+ Damit sieht die Perle aus wie ein gleitender Zeiger und kostet
+ trotzdem nichts. Voraussetzung ist, dass der Winkel WEITERZAEHLT
+ statt bei 360 Grad zurueckzuspringen -- sonst liefe die Ueberblendung
+ einmal je Minute rueckwaerts durch das ganze Zifferblatt. Genau das
+ macht start.js jetzt (fortlaufende Sekunden statt sk % 60). */
+.uhr__perle {
+ transition: transform .92s cubic-bezier(.33, 0, .2, 1);
+}
+@media (prefers-reduced-motion: reduce) {
+ .uhr__perle { transition: none; }
+}
diff --git a/workspace/assets/js/start.js b/workspace/assets/js/start.js
index 5ae45711..c2b4e7da 100644
--- a/workspace/assets/js/start.js
+++ b/workspace/assets/js/start.js
@@ -379,11 +379,42 @@
for (const welcher of ['sekunde', 'minute', 'stunde']) {
lagen[welcher] = [...document.querySelectorAll(`[data-ring="${welcher}"]`)];
}
+ /* DER SCHWEIF (08.09.2026): die letzten Grad vor der Spitze, heller.
+
+ Gerechnet, nicht geschaetzt. Ein Kreis mit Umfang U, Fortschritt
+ a (0..1) und Schweiflaenge s soll ein Segment von (a*U - s) bis
+ a*U zeigen. Mit `dasharray: s, U-s` beginnt das sichtbare Stueck
+ bei (U - offset), also gilt
+
+ U - offset = a*U - s -> offset = U*(1-a) + s
+
+ Die Laenge wird bei kurzen Boegen mitgekuerzt: Am Anfang einer
+ Minute ist der Bogen selbst noch kuerzer als der Schweif, und ein
+ Schweif ohne Bogen darunter haenge sonst am Ende des Kreises --
+ sichtbar als heller Strich bei zwoelf Uhr, wo nichts sein darf. */
+ const SCHWEIF = { sekunde: 30, minute: 26, stunde: 22 }; // Bogenlaenge
+ const spuren = {};
+ for (const welcher of ['sekunde', 'minute', 'stunde']) {
+ spuren[welcher] = document.querySelector(`[data-spur="${welcher}"]`);
+ }
+
const setze = (welcher, anteil) => {
- const wert = String(UMFANG[welcher] * (1 - anteil));
+ const U = UMFANG[welcher];
+ const wert = String(U * (1 - anteil));
for (const el of lagen[welcher]) el.style.strokeDashoffset = wert;
+
+ const spur = spuren[welcher];
+ if (!spur) return;
+ const s = Math.min(SCHWEIF[welcher], U * anteil);
+ if (s <= 0.5) { spur.style.opacity = '0'; return; } /* nichts zu zeigen */
+ spur.style.opacity = '';
+ spur.style.strokeDasharray = `${s} ${U - s}`;
+ spur.style.strokeDashoffset = String(U * (1 - anteil) + s);
};
+ /* Der Nullpunkt der eigenen Uhr -- siehe unten bei den Koepfen. */
+ let nullpunkt = null, startWinkel = 0, minStart = 0, stdStart = 0, sekStart = 0;
+
const takt = () => {
const j = new Date();
const std = j.getHours(), min = j.getMinutes(), sk = j.getSeconds();
@@ -409,16 +440,58 @@
sechzig. Auf einer Seite, die stundenlang offen steht, ist das
der Unterschied zwischen einem warmen und einem kalten
Rechner. */
+ /* DIE KOEPFE ZAEHLEN WEITER, STATT ZURUECKZUSPRINGEN.
+
+ Sie gleiten jetzt (Ueberblendung in heim.css) statt zu
+ springen. Damit das funktioniert, darf der Winkel bei 59 -> 0
+ Sekunden NICHT von 354 auf 0 fallen -- die Ueberblendung liefe
+ sonst einmal je Minute rueckwaerts durch das ganze
+ Zifferblatt. Gerechnet wird deshalb mit der fortlaufenden Zeit:
+ Der Winkel waechst immer weiter, und 366 Grad sieht genauso aus
+ wie 6, nur dass der Weg dorthin vorwaerts fuehrt.
+
+ Die Anzeige selbst rechnet weiterhin nur einmal je Sekunde --
+ die Bewegung dazwischen macht der Browser, nicht das Skript. */
+ /* SEIT DEM ERSTEN TAKT, NICHT SEIT 1970.
+
+ Der erste Versuch rechnete mit der vollen Unixzeit. Ergebnis im
+ Bildschirmfoto: `rotate(1.07333e+10deg)` -- eine Zahl in
+ Exponentialschreibweise, bei der die Nachkommastellen laengst
+ weg sind. Die Perlen standen sichtbar NEBEN dem Ende ihrer
+ Boegen, die rote sogar auf der anderen Seite des Zifferblatts.
+ Gerechnet war es richtig, darstellbar nicht.
+
+ Jetzt zaehlt eine eigene Uhr ab dem ersten Takt: Startwinkel ist
+ der echte Stand beim Laden, danach kommen 6 Grad je Sekunde
+ dazu. Die Zahl bleibt klein (ein Tag sind 518 400 Grad), waechst
+ aber weiter -- und nur das braucht die Ueberblendung, damit sie
+ nie rueckwaerts laeuft. */
+ if (nullpunkt === null) {
+ nullpunkt = Math.floor(j.getTime() / 1000);
+ startWinkel = sk * 6;
+ minStart = min; stdStart = std; sekStart = sk;
+ }
+ const seit = Math.floor(j.getTime() / 1000) - nullpunkt;
+ const winkelSek = startWinkel + seit * 6;
const perle = $('uhr-perle');
- if (perle) perle.style.transform = `rotate(${sk * 6}deg)`;
+ if (perle) perle.style.transform = `rotate(${winkelSek.toFixed(2)}deg)`;
/* Die beiden anderen Koepfe laufen mit IHREN Ringen -- die Minute
nimmt die Sekunden anteilig mit, die Stunde die Minuten. Sonst
staende der Kopf neben dem Ende seines Bogens, und genau das
sieht man sofort. */
+ /* Minute und Stunde ebenso: Startstand plus das, was seither
+ vergangen ist. Sie tragen die kleineren Einheiten anteilig mit,
+ damit ihr Kopf nie neben dem Ende ihres Bogens steht. */
const perleMin = $('uhr-perle-minute');
- if (perleMin) perleMin.style.transform = `rotate(${(min + sk / 60) * 6}deg)`;
+ if (perleMin) {
+ const start = (minStart + sekStart / 60) * 6;
+ perleMin.style.transform = `rotate(${(start + seit * 0.1).toFixed(3)}deg)`;
+ }
const perleStd = $('uhr-perle-stunde');
- if (perleStd) perleStd.style.transform = `rotate(${((std % 12) + min / 60) * 30}deg)`;
+ if (perleStd) {
+ const start = ((stdStart % 12) + minStart / 60) * 30;
+ perleStd.style.transform = `rotate(${(start + seit / 120).toFixed(4)}deg)`;
+ }
setze('minute', (min + sk / 60) / 60);
setze('stunde', ((std % 12) + min / 60) / 12);
diff --git a/workspace/start.html b/workspace/start.html
index 426ea780..1149014f 100644
--- a/workspace/start.html
+++ b/workspace/start.html
@@ -286,6 +286,34 @@
+
+
+
+
+
+
+