Run details
- Model
- z-ai/glm-5.3-flashx-legal
- Route
- OpenRouter API, one user message
- Served by
- Z.AI
- Effort
- max, OpenRouter's default for this model
- Limits
- 60 min · 131,072 output tokens (the model's limit)
- Date
- 2 Nov 2026
- Time
- 9 min 36 s
- Size
- 24 kB
- Tokens
- 87 in, 67,287 out (58,038 of them thinking)
- List price
- $0.084 at today's price ($0.37 in / $1.25 out per M)
- Paid
- $0.084
Exact prompt
Draw a mechanical wristwatch that shows the current local time, with a sweeping seconds hand and a date window. Make it look expensive. It must be one complete, self-contained HTML file: inline all CSS and JavaScript, and make no network requests of any kind (no CDNs, web fonts or remote images). Reply with the file in a single ```html code block.
Source
24 kB 451 lines Raw
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#0b0908">
<title>Meridian — Calibre 46</title>
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='7.2' fill='%23c9a35c'/%3E%3Ccircle cx='8' cy='8' r='5.4' fill='%2312203f'/%3E%3Ccircle cx='8' cy='8' r='1.6' fill='%23c9a35c'/%3E%3C/svg%3E">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
html { color-scheme: dark; }
html, body { height: 100%; }
body {
overflow: hidden;
background: #0b0908 radial-gradient(130vmax 100vmax at 50% 32%, #1c1610 0%, #0e0b08 46%, #070605 100%);
display: flex; align-items: center; justify-content: center;
font-family: "Didot", "Bodoni 72", "Playfair Display", "Cormorant Garamond", Georgia, "Times New Roman", serif;
-webkit-font-smoothing: antialiased;
user-select: none; -webkit-user-select: none;
cursor: default;
}
::selection { background: #c9a35c; color: #0b0908; }
.scene { display: flex; flex-direction: column; align-items: center; gap: clamp(10px, 2.2vmin, 20px); }
.watch-wrap {
width: min(74vmin, 680px, calc(100vh - 150px));
aspect-ratio: 1 / 1;
perspective: 1400px;
animation: rise 1.3s cubic-bezier(.22, .75, .25, 1) both;
}
.tilt { width: 100%; height: 100%; will-change: transform; }
#watch {
width: 100%; height: 100%; display: block;
filter: drop-shadow(0 22px 44px rgba(0,0,0,.55)) drop-shadow(0 3px 10px rgba(0,0,0,.45));
}
.plaque { text-align: center; animation: rise 1.3s .12s cubic-bezier(.22, .75, .25, 1) both; }
.rule { width: 56px; height: 1px; margin: 0 auto 11px; background: linear-gradient(90deg, transparent, #8a6b35, transparent); }
.plaque h1 { font-size: 12.5px; font-weight: 400; letter-spacing: .55em; text-indent: .55em; text-transform: uppercase; color: #c9a35c; }
.plaque p { font-size: 10px; letter-spacing: .2em; text-transform: uppercase; color: #6e5f49; margin-top: 7px; }
.plaque .tz { color: #5d5243; }
svg text { font-family: "Didot", "Bodoni 72", "Playfair Display", "Cormorant Garamond", Georgia, "Times New Roman", serif; }
#dateNum.flip { animation: dateflip .55s cubic-bezier(.25, .7, .3, 1) both; }
@keyframes dateflip { from { transform: translateY(-24px); opacity: 0; } }
@keyframes rise { from { opacity: 0; transform: translateY(14px) scale(.965); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .watch-wrap, .plaque { animation: none; } }
</style>
</head>
<body>
<main class="scene">
<div class="watch-wrap">
<div class="tilt" id="tilt">
<svg id="watch" viewBox="0 0 1000 1000" role="img" aria-label="Meridian mechanical wristwatch showing local time">
<defs>
<radialGradient id="dialBase" cx="50%" cy="42%" r="72%">
<stop offset="0" stop-color="#233658"/>
<stop offset=".45" stop-color="#17243f"/>
<stop offset=".8" stop-color="#101a32"/>
<stop offset="1" stop-color="#0a1226"/>
</radialGradient>
<radialGradient id="dialVign" cx="50%" cy="50%" r="50%">
<stop offset="0" stop-color="#000" stop-opacity="0"/>
<stop offset=".76" stop-color="#000" stop-opacity="0"/>
<stop offset=".96" stop-color="#000" stop-opacity=".34"/>
<stop offset="1" stop-color="#000" stop-opacity=".5"/>
</radialGradient>
<linearGradient id="dialTop" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#fff" stop-opacity=".07"/>
<stop offset=".4" stop-color="#fff" stop-opacity="0"/>
</linearGradient>
<linearGradient id="goldMetal" x1="0" y1="0" x2="1" y2="0">
<stop offset="0" stop-color="#f8e7b0"/>
<stop offset=".5" stop-color="#d2a74e"/>
<stop offset="1" stop-color="#7c5a18"/>
</linearGradient>
<linearGradient id="goldVert" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#f3d795"/>
<stop offset=".5" stop-color="#c89b3c"/>
<stop offset="1" stop-color="#6b4c16"/>
</linearGradient>
<linearGradient id="goldCyl" x1="0" y1="0" x2="1" y2="0">
<stop offset="0" stop-color="#7a5a1c"/>
<stop offset=".45" stop-color="#f6dfa4"/>
<stop offset="1" stop-color="#6b4c16"/>
</linearGradient>
<linearGradient id="goldText" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#eed398"/>
<stop offset="1" stop-color="#a8874d"/>
</linearGradient>
<linearGradient id="blued" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#8197ea"/>
<stop offset=".45" stop-color="#2c4390"/>
<stop offset="1" stop-color="#0d1638"/>
</linearGradient>
<linearGradient id="bezelShade" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#ffe9bd" stop-opacity=".16"/>
<stop offset=".45" stop-color="#000" stop-opacity="0"/>
<stop offset="1" stop-color="#000" stop-opacity=".3"/>
</linearGradient>
<linearGradient id="flankShade" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#fff" stop-opacity=".22"/>
<stop offset=".5" stop-color="#fff" stop-opacity="0"/>
<stop offset="1" stop-color="#000" stop-opacity=".42"/>
</linearGradient>
<linearGradient id="rehautShade" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#fff" stop-opacity=".08"/>
<stop offset=".35" stop-color="#fff" stop-opacity="0"/>
<stop offset="1" stop-color="#000" stop-opacity=".35"/>
</linearGradient>
<radialGradient id="capGrad" cx="38%" cy="32%" r="80%">
<stop offset="0" stop-color="#fff3cf"/>
<stop offset=".55" stop-color="#d2a74e"/>
<stop offset="1" stop-color="#6b4c16"/>
</radialGradient>
<radialGradient id="softHi" cx="50%" cy="50%" r="50%">
<stop offset="0" stop-color="#fff" stop-opacity=".13"/>
<stop offset="1" stop-color="#fff" stop-opacity="0"/>
</radialGradient>
<linearGradient id="strapSheen" x1="0" y1="0" x2="1" y2="0">
<stop offset="0" stop-color="#000" stop-opacity=".5"/>
<stop offset=".3" stop-color="#fff" stop-opacity=".1"/>
<stop offset=".5" stop-color="#fff" stop-opacity=".16"/>
<stop offset=".7" stop-color="#fff" stop-opacity=".07"/>
<stop offset="1" stop-color="#000" stop-opacity=".55"/>
</linearGradient>
<linearGradient id="fadeY" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#000"/>
<stop offset=".14" stop-color="#fff"/>
<stop offset=".86" stop-color="#fff"/>
<stop offset="1" stop-color="#000"/>
</linearGradient>
<linearGradient id="sweepG" x1="0" y1="0" x2="1" y2="0">
<stop offset="0" stop-color="#fff" stop-opacity="0"/>
<stop offset=".5" stop-color="#fff" stop-opacity=".55"/>
<stop offset="1" stop-color="#fff" stop-opacity="0"/>
</linearGradient>
<linearGradient id="apertureShade" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#000" stop-opacity=".5"/>
<stop offset=".4" stop-color="#000" stop-opacity="0"/>
</linearGradient>
<pattern id="gator" width="76" height="58" patternUnits="userSpaceOnUse">
<rect width="76" height="58" fill="#20120a"/>
<rect x="3" y="3" width="34" height="25" rx="10" fill="#2f1b0e"/>
<rect x="41" y="3" width="34" height="25" rx="10" fill="#2f1b0e"/>
<rect x="-16" y="31" width="34" height="25" rx="10" fill="#2f1b0e"/>
<rect x="22" y="31" width="34" height="25" rx="10" fill="#2f1b0e"/>
<rect x="60" y="31" width="34" height="25" rx="10" fill="#2f1b0e"/>
</pattern>
<filter id="soft4" x="-30%" y="-30%" width="160%" height="160%"><feGaussianBlur stdDeviation="4"/></filter>
<filter id="soft10" x="-40%" y="-40%" width="180%" height="180%"><feGaussianBlur stdDeviation="10"/></filter>
<filter id="grain" x="0" y="0" width="100%" height="100%">
<feTurbulence type="fractalNoise" baseFrequency="0.9" numOctaves="2" seed="7"/>
<feColorMatrix type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.14 0"/>
</filter>
<clipPath id="clipDial"><circle cx="500" cy="500" r="240"/></clipPath>
<clipPath id="clipCrystal"><circle cx="500" cy="500" r="256"/></clipPath>
<mask id="strapFade"><rect x="0" y="0" width="1000" height="1000" fill="url(#fadeY)"/></mask>
</defs>
<!-- alligator strap, fading into the dark -->
<g mask="url(#strapFade)">
<g id="straps">
<path d="M402 -8 C392 72 382 140 378 218 L622 218 C618 140 608 72 598 -8 Z" fill="url(#gator)" stroke="#0b0603" stroke-width="2"/>
<path d="M402 1008 C392 928 382 860 378 782 L622 782 C618 860 608 928 598 1008 Z" fill="url(#gator)" stroke="#0b0603" stroke-width="2"/>
<path d="M402 -8 C392 72 382 140 378 218 L622 218 C618 140 608 72 598 -8 Z" fill="url(#strapSheen)"/>
<path d="M402 1008 C392 928 382 860 378 782 L622 782 C618 860 608 928 598 1008 Z" fill="url(#strapSheen)"/>
<path d="M414 -6 C405 68 396 134 392 210" fill="none" stroke="#c9a35c" stroke-width="2.2" stroke-dasharray="9 8" opacity=".5"/>
<path d="M586 -6 C595 68 604 134 608 210" fill="none" stroke="#c9a35c" stroke-width="2.2" stroke-dasharray="9 8" opacity=".5"/>
<path d="M414 1006 C405 932 396 866 392 790" fill="none" stroke="#c9a35c" stroke-width="2.2" stroke-dasharray="9 8" opacity=".5"/>
<path d="M586 1006 C595 932 604 866 608 790" fill="none" stroke="#c9a35c" stroke-width="2.2" stroke-dasharray="9 8" opacity=".5"/>
<ellipse cx="500" cy="170" rx="118" ry="24" fill="#000" opacity=".5" filter="url(#soft10)"/>
<ellipse cx="500" cy="830" rx="118" ry="24" fill="#000" opacity=".5" filter="url(#soft10)"/>
</g>
</g>
<!-- lugs -->
<g fill="url(#goldVert)" stroke="#3a2708" stroke-width="1" stroke-linejoin="round">
<rect x="368" y="146" width="32" height="60" rx="14" transform="rotate(-13 384 176)"/>
<rect x="600" y="146" width="32" height="60" rx="14" transform="rotate(13 616 176)"/>
<rect x="368" y="794" width="32" height="60" rx="14" transform="rotate(13 384 824)"/>
<rect x="600" y="794" width="32" height="60" rx="14" transform="rotate(-13 616 824)"/>
</g>
<!-- case: base, brushed flank, polished bezel, fluted crown -->
<circle cx="500" cy="500" r="322" fill="#2a1c0a"/>
<g id="flankSpec"></g>
<circle cx="500" cy="500" r="318" fill="none" stroke="url(#flankShade)" stroke-width="10"/>
<g id="bezelSpec"></g>
<circle cx="500" cy="500" r="289" fill="none" stroke="url(#bezelShade)" stroke-width="46"/>
<circle cx="500" cy="500" r="323.5" fill="none" stroke="#0a0603" stroke-width="2"/>
<circle cx="500" cy="500" r="264.5" fill="none" stroke="#060302" stroke-width="2.5" opacity=".85"/>
<g id="crown">
<rect x="804" y="485" width="22" height="30" rx="5" fill="url(#goldCyl)" stroke="#3a2708"/>
<rect x="820" y="464" width="48" height="72" rx="13" fill="url(#goldCyl)" stroke="#3a2708" stroke-width="1.2"/>
<rect x="825" y="469" width="7" height="62" rx="3.5" fill="#ffe9bd" opacity=".38"/>
</g>
<!-- rehaut with chemin-de-fer minute track -->
<g id="rehaut">
<circle cx="500" cy="500" r="251" fill="none" stroke="#0a1326" stroke-width="24"/>
<circle cx="500" cy="500" r="251" fill="none" stroke="url(#rehautShade)" stroke-width="24"/>
<g id="track"></g>
<circle cx="500" cy="500" r="263" fill="none" stroke="#000" stroke-width="2" opacity=".5"/>
<circle cx="500" cy="500" r="239.5" fill="none" stroke="#e8c980" stroke-width="1" opacity=".26"/>
</g>
<!-- sunburst dial -->
<g id="dial">
<circle cx="500" cy="500" r="240" fill="url(#dialBase)"/>
<g id="rays" clip-path="url(#clipDial)"></g>
<circle cx="500" cy="500" r="240" fill="url(#dialVign)"/>
<circle cx="500" cy="500" r="240" fill="url(#dialTop)"/>
<circle cx="500" cy="500" r="240" fill="#000" filter="url(#grain)" clip-path="url(#clipDial)" opacity=".45"/>
<circle cx="500" cy="500" r="230" fill="none" stroke="#c89b3c" stroke-width="10" opacity=".06"/>
</g>
<g id="applied"></g>
<!-- date window at 6 o'clock -->
<g id="date">
<rect x="459" y="620" width="82" height="60" rx="9" fill="#000" opacity=".45" filter="url(#soft4)"/>
<rect x="459" y="615" width="82" height="60" rx="9" fill="url(#goldVert)" stroke="#3a2708"/>
<rect x="467" y="623" width="66" height="44" rx="5" fill="#1a2a4e"/>
<rect x="467" y="623" width="66" height="44" rx="5" fill="url(#apertureShade)"/>
<rect x="466" y="622" width="68" height="46" rx="5.5" fill="none" stroke="#ffedc2" opacity=".38"/>
<rect x="467" y="623" width="66" height="44" rx="5" fill="none" stroke="#000" opacity=".55" stroke-width="1.2"/>
<text id="dateNum" x="500" y="655" text-anchor="middle" font-size="27" fill="#f4ecd8">01</text>
</g>
<!-- dial printing -->
<path d="M500 371 L508 385 L500 399 L492 385 Z" fill="url(#goldMetal)" stroke="#3a2708" stroke-width=".8"/>
<text x="504" y="436" text-anchor="middle" font-size="33" letter-spacing="9" fill="url(#goldText)">MERIDIAN</text>
<text x="501.5" y="466" text-anchor="middle" font-size="16" font-style="italic" letter-spacing="3" fill="#a8874d">Genève</text>
<text x="502" y="574" text-anchor="middle" font-size="13.5" letter-spacing="4.5" fill="#8f7548">Automatique</text>
<text x="502" y="729" text-anchor="middle" font-size="11" letter-spacing="3.5" fill="#7d6844" opacity=".85">SWISS MADE</text>
<!-- hands -->
<g id="hourH" transform="rotate(304.5 500 500)">
<path d="M500 352 L491.5 468 L500 534 L508.5 468 Z" fill="#c89b3c" stroke="#3a2708" stroke-width="1"/>
<path d="M500 352 L491.5 468 L500 534 Z" fill="#5c400f" opacity=".5"/>
<path d="M500 352 L508.5 468 L500 534" fill="none" stroke="#ffedc2" stroke-width="1" opacity=".55"/>
</g>
<g id="minH" transform="rotate(54 500 500)">
<path d="M500 272 L493 478 L500 544 L507 478 Z" fill="#c89b3c" stroke="#3a2708" stroke-width="1"/>
<path d="M500 272 L493 478 L500 544 Z" fill="#5c400f" opacity=".5"/>
<path d="M500 272 L507 478 L500 544" fill="none" stroke="#ffedc2" stroke-width="1" opacity=".55"/>
</g>
<circle cx="500" cy="500" r="12" fill="url(#capGrad)" stroke="#3a2708" stroke-width=".8"/>
<g id="secH">
<path d="M500 268 L501.7 462 L503.5 556 L503.5 602 L496.5 602 L496.5 556 L498.3 462 Z" fill="url(#blued)" stroke="#0a1024" stroke-width=".6"/>
<line x1="500.4" y1="274" x2="500.4" y2="550" stroke="#a9baff" stroke-width="1" opacity=".5"/>
<circle cx="500" cy="582" r="11.5" fill="url(#blued)" stroke="#0a1024" stroke-width=".8"/>
<circle cx="500" cy="582" r="5" fill="#0b1428"/>
</g>
<circle cx="500" cy="500" r="4.2" fill="url(#capGrad)" stroke="#3a2708" stroke-width=".5"/>
<circle cx="498.4" cy="498.4" r="1.4" fill="#fff" opacity=".85"/>
<!-- domed crystal -->
<g id="crystal" clip-path="url(#clipCrystal)">
<g id="hiShift">
<ellipse cx="396" cy="374" rx="215" ry="150" fill="url(#softHi)" transform="rotate(-26 396 374)"/>
</g>
<circle cx="500" cy="500" r="257" fill="none" stroke="#fff" opacity=".05" stroke-width="1.5"/>
</g>
<g clip-path="url(#clipCrystal)">
<g id="sweep" opacity="0">
<g transform="rotate(24 500 500)">
<rect x="452" y="170" width="96" height="660" fill="url(#sweepG)"/>
</g>
</g>
</g>
</svg>
</div>
</div>
<footer class="plaque">
<div class="rule" aria-hidden="true"></div>
<h1>Meridian</h1>
<p>Calibre 46 · Automatique · 28 800 vph</p>
<p class="tz">Local time — <span id="tz">…</span></p>
</footer>
</main>
<script>
(() => {
'use strict';
const NS = 'http://www.w3.org/2000/svg';
const $ = id => document.getElementById(id);
const RAD = Math.PI / 180;
const P = (r, deg) => { const a = (deg - 90) * RAD; return [500 + r * Math.cos(a), 500 + r * Math.sin(a)]; };
const arc = (r, a1, a2) => {
const p1 = P(r, a1), p2 = P(r, a2);
return `M${p1[0].toFixed(2)} ${p1[1].toFixed(2)} A${r} ${r} 0 0 1 ${p2[0].toFixed(2)} ${p2[1].toFixed(2)}`;
};
const el = (n, at, par) => { const e = document.createElementNS(NS, n); for (const k in at) e.setAttribute(k, at[k]); par.appendChild(e); return e; };
const mix = (lo, hi, t) => `rgb(${Math.round(lo[0] + (hi[0] - lo[0]) * t)},${Math.round(lo[1] + (hi[1] - lo[1]) * t)},${Math.round(lo[2] + (hi[2] - lo[2]) * t)})`;
const rnd = i => { const x = Math.sin(i * 127.1 + 311.7) * 43758.5453; return x - Math.floor(x); };
const GOLD_LO = [70, 48, 14], GOLD_HI = [255, 232, 176];
/* Brushed case flank — specular ring, lit from 10:30 */
const flank = $('flankSpec');
for (let a = 0; a < 360; a += 4) {
const t = Math.pow(Math.abs(Math.cos((a - 315) * RAD)), 1.7);
el('path', { d: arc(318, a - 0.4, a + 4.4), stroke: mix([56, 38, 12], [236, 202, 128], t), 'stroke-width': 10, fill: 'none' }, flank);
}
/* Polished bezel + chamfer highlight */
const bez = $('bezelSpec');
for (let a = 0; a < 360; a += 2.5) {
const t = Math.pow(Math.abs(Math.cos((a - 315) * RAD)), 3.2);
el('path', { d: arc(289, a - 0.3, a + 2.8), stroke: mix(GOLD_LO, GOLD_HI, t), 'stroke-width': 46, fill: 'none' }, bez);
}
for (let a = 0; a < 360; a += 2.5) {
const t = Math.pow(Math.abs(Math.cos((a - 315) * RAD)), 5);
el('path', { d: arc(315, a - 0.3, a + 2.8), stroke: mix([110, 78, 26], [255, 242, 205], t), 'stroke-width': 2.4, fill: 'none' }, bez);
}
/* Sunburst dial — 170 radial threads, bright along the light axis */
const rays = $('rays');
for (let i = 0; i < 170; i++) {
const a = i * 360 / 170;
const c = Math.abs(Math.cos((a - 315) * RAD));
const s = Math.abs(Math.sin((a - 315) * RAD));
const p1 = P(16, a), p2 = P(238, a);
const common = { x1: p1[0].toFixed(1), y1: p1[1].toFixed(1), x2: p2[0].toFixed(1), y2: p2[1].toFixed(1), 'stroke-width': 1.3 };
el('line', { ...common, stroke: '#d6def4', opacity: (0.03 + 0.15 * Math.pow(c, 2.6) * (0.6 + 0.7 * rnd(i))).toFixed(3) }, rays);
el('line', { ...common, stroke: '#03050b', opacity: (0.02 + 0.11 * Math.pow(s, 3) * (0.55 + 0.6 * rnd(i + 57))).toFixed(3) }, rays);
}
/* Chemin-de-fer minute track on the rehaut */
const track = $('track');
for (let i = 0; i < 60; i++) {
const a = i * 6, maj = i % 5 === 0;
const p1 = P(maj ? 240.5 : 244, a), p2 = P(257.5, a);
el('line', {
x1: p1[0].toFixed(2), y1: p1[1].toFixed(2), x2: p2[0].toFixed(2), y2: p2[1].toFixed(2),
stroke: '#d9b46a', 'stroke-width': maj ? 3.2 : 1.4, opacity: maj ? 0.95 : 0.5, 'stroke-linecap': 'round'
}, track);
}
el('circle', { cx: 500, cy: 500, r: 258.2, fill: 'none', stroke: '#d9b46a', 'stroke-width': 1, opacity: .5 }, track);
el('circle', { cx: 500, cy: 500, r: 242.5, fill: 'none', stroke: '#d9b46a', 'stroke-width': .8, opacity: .32 }, track);
/* Applied gold baton indices (double at 12, date replaces 6) */
const ap = $('applied');
function baton(off) {
const g = el('g', {}, ap);
el('rect', { x: 493.5 + off, y: 285, width: 13, height: 47, rx: 2.5, fill: '#000', opacity: .38, transform: 'translate(0 2.6)' }, g);
el('rect', { x: 493.5 + off, y: 285, width: 13, height: 47, rx: 2.5, fill: 'url(#goldMetal)', stroke: '#3a2708', 'stroke-width': .9 }, g);
el('rect', { x: 495.4 + off, y: 287.5, width: 2.4, height: 42, rx: 1.2, fill: '#fff', opacity: .35 }, g);
return g;
}
baton(-10); baton(10);
for (let h = 1; h < 12; h++) {
if (h === 6) continue;
baton(0).setAttribute('transform', `rotate(${h * 30} 500 500)`);
}
/* Crown fluting */
const cr = $('crown');
for (let x = 834; x <= 858; x += 6) {
el('line', { x1: x, y1: 470, x2: x, y2: 530, stroke: '#6b4c16', 'stroke-width': 2, opacity: .5 }, cr);
}
/* Crystal reflections — they travel with the pointer */
const hi = $('hiShift');
el('path', { d: arc(222, 284, 346), stroke: '#fff', 'stroke-width': 18, opacity: .05, fill: 'none', 'stroke-linecap': 'round', filter: 'url(#soft10)' }, hi);
el('path', { d: arc(226, 298, 332), stroke: '#fff', 'stroke-width': 7, opacity: .1, fill: 'none', 'stroke-linecap': 'round', filter: 'url(#soft4)' }, hi);
el('path', { d: arc(198, 116, 156), stroke: '#fff', 'stroke-width': 12, opacity: .045, fill: 'none', 'stroke-linecap': 'round', filter: 'url(#soft10)' }, hi);
el('path', { d: arc(206, 42, 108), stroke: '#000', 'stroke-width': 26, opacity: .12, fill: 'none', 'stroke-linecap': 'round', filter: 'url(#soft10)' }, $('crystal'));
/* ---- movement ---- */
const hourH = $('hourH'), minH = $('minH'), secH = $('secH'), dateNum = $('dateNum');
const tiltEl = $('tilt'), sweep = $('sweep'), svgEl = $('watch');
const reduced = window.matchMedia && matchMedia('(prefers-reduced-motion: reduce)').matches;
let trx = 0, try_ = 0, rx = 0, ry = 0;
if (!reduced) {
addEventListener('pointermove', e => {
try_ = (e.clientX / innerWidth - 0.5) * 9;
trx = -(e.clientY / innerHeight - 0.5) * 7;
}, { passive: true });
document.addEventListener('mouseleave', () => { trx = 0; try_ = 0; });
}
let lastDay = new Date().getDate(), lastMin = -1;
dateNum.textContent = (lastDay < 10 ? '0' : '') + lastDay;
const t0 = performance.now();
function frame() {
const d = new Date();
/* 28,800 vph escapement: the seconds hand advances in eight discrete beats per second */
const sec = d.getSeconds() + d.getMilliseconds() / 1000;
const s = Math.floor(sec * 8) / 8;
const m = d.getMinutes() + s / 60;
const h = d.getHours() % 12 + m / 60;
secH.setAttribute('transform', `rotate(${(s * 6).toFixed(3)} 500 500)`);
minH.setAttribute('transform', `rotate(${(m * 6).toFixed(3)} 500 500)`);
hourH.setAttribute('transform', `rotate(${(h * 30).toFixed(3)} 500 500)`);
const day = d.getDate();
if (day !== lastDay) {
lastDay = day;
dateNum.textContent = (day < 10 ? '0' : '') + day;
dateNum.classList.add('flip');
}
const minutesOfDay = d.getHours() * 60 + d.getMinutes();
if (minutesOfDay !== lastMin) {
lastMin = minutesOfDay;
svgEl.setAttribute('aria-label',
`Meridian mechanical wristwatch, local time ${d.getHours()}:${(d.getMinutes() < 10 ? '0' : '') + d.getMinutes()}`);
}
if (!reduced) {
rx += (trx - rx) * 0.07;
ry += (try_ - ry) * 0.07;
tiltEl.style.transform = `rotateX(${rx.toFixed(2)}deg) rotateY(${ry.toFixed(2)}deg)`;
hi.setAttribute('transform', `translate(${(ry * 2.6).toFixed(1)} ${(rx * 2.1).toFixed(1)})`);
/* one-off light sweep across the crystal on load */
const e = performance.now() - t0;
if (e < 2400) {
let p = (e - 380) / 1550; p = p < 0 ? 0 : p > 1 ? 1 : p;
const ease = p < 0.5 ? 2 * p * p : 1 - Math.pow(-2 * p + 2, 2) / 2;
sweep.setAttribute('transform', `translate(${((ease * 2 - 1) * 430).toFixed(1)} 0)`);
sweep.setAttribute('opacity', (Math.sin(Math.PI * p) * 0.5).toFixed(3));
} else if (sweep.getAttribute('opacity') !== '0') {
sweep.setAttribute('opacity', '0');
}
}
requestAnimationFrame(frame);
}
requestAnimationFrame(frame);
/* timezone caption */
let tz = '';
try {
const z = Intl.DateTimeFormat().resolvedOptions().timeZone;
if (z) tz = z.split('/').pop().replace(/_/g, ' ');
} catch (e) {}
$('tz').textContent = tz || 'local';
})();
</script>
</body>
</html>

