Run details
- Model
- z-ai/glm-5.3-flash
- Route
- OpenRouter API, one user message
- Served by
- OpenInference
- Effort
- max, OpenRouter's default for this model
- Limits
- 60 min · 131,072 output tokens (the model's limit)
- Date
- 31 Oct 2026
- Time
- 17 min 21 s
- Size
- 32 kB
- Tokens
- 102 in, 68,740 out (56,544 of them thinking)
- List price
- $0.010 at today's price ($0.016 in / $0.148 out per M)
- Paid
- $0.002
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
32 kB 607 lines Raw
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="color-scheme" content="dark">
<title>Aubert Genève · Ref. 2147</title>
<style>
*{margin:0;padding:0;box-sizing:border-box}
html,body{height:100%}
body{
background:radial-gradient(130% 100% at 50% 36%, #29231a 0%, #1b1712 46%, #0e0c09 100%);
font-family:Georgia,'Times New Roman',serif;
color:#8f826b; overflow:hidden; touch-action:manipulation;
display:flex; flex-direction:column;
-webkit-user-select:none; user-select:none;
}
body::after{ /* soft photographic vignette */
content:""; position:fixed; inset:0; pointer-events:none;
background:radial-gradient(140% 140% at 50% 40%, transparent 55%, rgba(0,0,0,.45) 100%);
}
header{
position:fixed; top:0; left:0; right:0; z-index:5; pointer-events:none;
display:flex; justify-content:space-between; align-items:center;
padding:20px 30px; font-size:11px; letter-spacing:.32em; color:#5f5544;
}
header .brand{color:#a99878; letter-spacing:.46em; font-size:12px}
#clockDigits{color:#a09173; font-variant-numeric:tabular-nums; letter-spacing:.2em}
.stage{
flex:1; min-height:100vh;
display:flex; flex-direction:column; align-items:center; justify-content:center;
padding:60px 16px 16px;
}
.tilt-pivot{perspective:1500px}
#tiltWrap{transform-style:preserve-3d; will-change:transform}
svg{display:block; height:min(80svh,780px); height:min(80vh,780px); width:auto; max-width:94vw}
@media (max-aspect-ratio:4/5){ svg{height:auto; width:min(92vw,640px)} }
footer{text-align:center; padding:8px 16px 20px; z-index:5}
.specs{font-size:10.5px; letter-spacing:.3em; color:#57503f; margin-bottom:8px}
.status{font-size:11.5px; letter-spacing:.18em; color:#93866f; min-height:15px; transition:opacity .18s ease}
.status.alert{color:#c89a5e}
.status.fade{opacity:0}
.hint{font-size:10px; letter-spacing:.26em; color:#4a4234; margin-top:8px}
#crown{cursor:pointer}
#crownBody{transition:filter .25s ease}
#crown:hover #crownBody{filter:brightness(1.13)}
#crownHit:focus-visible{outline:none; stroke:#c89a5e; stroke-width:1.5; stroke-dasharray:5 5}
@media (max-height:620px){ .hint,.specs{display:none} }
.grain{ /* self-contained film grain */
position:fixed; inset:0; pointer-events:none; opacity:.05; mix-blend-mode:overlay;
background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
}
</style>
</head>
<body>
<header>
<div>REF. 2147 · ATELIER SERIES</div>
<div class="brand">AUBERT GENÈVE</div>
<div>LOCAL <span id="clockDigits">--:--:--</span></div>
</header>
<main class="stage">
<div class="tilt-pivot"><div id="tiltWrap">
<svg id="watch" viewBox="0 0 900 1120" xmlns="http://www.w3.org/2000/svg" role="img"
aria-label="Aubert Genève mechanical wristwatch showing the current local time, with a date window and a beating balance wheel">
<defs>
<radialGradient id="dialBase" cx="0.455" cy="0.40" r="0.78">
<stop offset="0" stop-color="#fbf7ee"/><stop offset="0.42" stop-color="#f3ecdc"/>
<stop offset="0.72" stop-color="#e6dcc6"/><stop offset="1" stop-color="#cfc2a4"/>
</radialGradient>
<radialGradient id="dialSheen" gradientUnits="userSpaceOnUse" cx="390" cy="420" r="430">
<stop offset="0" stop-color="#fff8e8" stop-opacity="0.15"/>
<stop offset="0.45" stop-color="#fff8e8" stop-opacity="0.05"/>
<stop offset="0.75" stop-color="#fff8e8" stop-opacity="0"/>
</radialGradient>
<radialGradient id="dialVign" gradientUnits="userSpaceOnUse" cx="450" cy="540" r="264">
<stop offset="0.62" stop-color="#3a2c14" stop-opacity="0"/>
<stop offset="0.88" stop-color="#3a2c14" stop-opacity="0.10"/>
<stop offset="1" stop-color="#33260f" stop-opacity="0.30"/>
</radialGradient>
<linearGradient id="bezelMetal" gradientUnits="userSpaceOnUse" x1="168" y1="540" x2="732" y2="540">
<stop offset="0" stop-color="#ffe9cb"/><stop offset="0.16" stop-color="#f4d8ab"/>
<stop offset="0.34" stop-color="#d9ab74"/><stop offset="0.5" stop-color="#a4713c"/>
<stop offset="0.62" stop-color="#7c4e22"/><stop offset="0.78" stop-color="#b98a4e"/>
<stop offset="1" stop-color="#f6e2bd"/>
</linearGradient>
<linearGradient id="lugMetal" gradientUnits="userSpaceOnUse" x1="336" y1="210" x2="440" y2="330">
<stop offset="0" stop-color="#f6dfb6"/><stop offset="0.5" stop-color="#cfa06a"/><stop offset="1" stop-color="#7c4c20"/>
</linearGradient>
<linearGradient id="lugMetalR" gradientUnits="userSpaceOnUse" x1="564" y1="210" x2="460" y2="330">
<stop offset="0" stop-color="#f6dfb6"/><stop offset="0.5" stop-color="#cfa06a"/><stop offset="1" stop-color="#7c4c20"/>
</linearGradient>
<linearGradient id="lugMetalB" gradientUnits="userSpaceOnUse" x1="336" y1="750" x2="440" y2="870">
<stop offset="0" stop-color="#f6dfb6"/><stop offset="0.5" stop-color="#cfa06a"/><stop offset="1" stop-color="#7c4c20"/>
</linearGradient>
<linearGradient id="lugMetalBR" gradientUnits="userSpaceOnUse" x1="564" y1="750" x2="460" y2="870">
<stop offset="0" stop-color="#f6dfb6"/><stop offset="0.5" stop-color="#cfa06a"/><stop offset="1" stop-color="#7c4c20"/>
</linearGradient>
<linearGradient id="crownMetal" gradientUnits="userSpaceOnUse" x1="0" y1="510" x2="0" y2="570">
<stop offset="0" stop-color="#ffeacb"/><stop offset="0.45" stop-color="#d3a269"/>
<stop offset="0.8" stop-color="#8a5a28"/><stop offset="1" stop-color="#6b4018"/>
</linearGradient>
<linearGradient id="strapLeather" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#352515"/><stop offset="0.5" stop-color="#241a10"/><stop offset="1" stop-color="#1a120b"/>
</linearGradient>
<radialGradient id="movePlate" cx="0.5" cy="0.45" r="0.7">
<stop offset="0" stop-color="#2e2619"/><stop offset="0.7" stop-color="#221b12"/><stop offset="1" stop-color="#120d08"/>
</radialGradient>
<radialGradient id="brass" cx="0.4" cy="0.35" r="0.8">
<stop offset="0" stop-color="#e8c47c"/><stop offset="0.6" stop-color="#c39a52"/><stop offset="1" stop-color="#8a6128"/>
</radialGradient>
<linearGradient id="gradBlued" gradientUnits="userSpaceOnUse" x1="0" y1="-250" x2="0" y2="40">
<stop offset="0" stop-color="#6f95d8"/><stop offset="0.35" stop-color="#274a86"/>
<stop offset="0.75" stop-color="#142a52"/><stop offset="1" stop-color="#0d1c3a"/>
</linearGradient>
<radialGradient id="goldCap" cx="0.35" cy="0.35" r="0.85">
<stop offset="0" stop-color="#f9e7c3"/><stop offset="0.55" stop-color="#d9ab74"/><stop offset="1" stop-color="#8a5a2c"/>
</radialGradient>
<linearGradient id="dateDisc" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#fbf8ee"/><stop offset="1" stop-color="#efe8d5"/>
</linearGradient>
<radialGradient id="glassTint" gradientUnits="userSpaceOnUse" cx="450" cy="540" r="264">
<stop offset="0" stop-color="#ffffff" stop-opacity="0"/>
<stop offset="0.8" stop-color="#ffffff" stop-opacity="0.02"/>
<stop offset="0.97" stop-color="#bcd2f0" stop-opacity="0.05"/>
<stop offset="1" stop-color="#9db8dd" stop-opacity="0.13"/>
</radialGradient>
<radialGradient id="winRecess">
<stop offset="0" stop-color="#000" stop-opacity="0"/>
<stop offset="0.68" stop-color="#000" stop-opacity="0"/>
<stop offset="0.9" stop-color="#000" stop-opacity="0.28"/>
<stop offset="1" stop-color="#000" stop-opacity="0.55"/>
</radialGradient>
<linearGradient id="fadeGTop" gradientUnits="userSpaceOnUse" x1="0" y1="330" x2="0" y2="100">
<stop offset="0" stop-color="#fff"/><stop offset="0.5" stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity="0"/>
</linearGradient>
<linearGradient id="fadeGBot" gradientUnits="userSpaceOnUse" x1="0" y1="750" x2="0" y2="1010">
<stop offset="0" stop-color="#fff"/><stop offset="0.35" stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity="0"/>
</linearGradient>
<mask id="fadeTop" maskUnits="userSpaceOnUse" x="350" y="50" width="200" height="290">
<rect x="350" y="50" width="200" height="290" fill="url(#fadeGTop)"/>
</mask>
<mask id="fadeBot" maskUnits="userSpaceOnUse" x="350" y="740" width="200" height="300">
<rect x="350" y="740" width="200" height="300" fill="url(#fadeGBot)"/>
</mask>
<clipPath id="dialClip"><circle cx="450" cy="540" r="264"/></clipPath>
<clipPath id="winClip"><circle cx="315" cy="540" r="58"/></clipPath>
<filter id="b1" filterUnits="userSpaceOnUse" x="0" y="0" width="900" height="1120"><feGaussianBlur stdDeviation="1.2"/></filter>
<filter id="b2" filterUnits="userSpaceOnUse" x="0" y="0" width="900" height="1120"><feGaussianBlur stdDeviation="2.2"/></filter>
<filter id="b3" filterUnits="userSpaceOnUse" x="0" y="0" width="900" height="1120"><feGaussianBlur stdDeviation="3.2"/></filter>
<filter id="b6" filterUnits="userSpaceOnUse" x="0" y="0" width="900" height="1120"><feGaussianBlur stdDeviation="6"/></filter>
<filter id="b10" filterUnits="userSpaceOnUse" x="0" y="0" width="900" height="1120"><feGaussianBlur stdDeviation="10"/></filter>
<filter id="b14" filterUnits="userSpaceOnUse" x="0" y="0" width="900" height="1120"><feGaussianBlur stdDeviation="14"/></filter>
<filter id="handShadow" filterUnits="userSpaceOnUse" x="120" y="240" width="680" height="680">
<feDropShadow dx="9" dy="13" stdDeviation="7" flood-color="#1f1204" flood-opacity="0.32"/>
</filter>
<filter id="idxShadow" filterUnits="userSpaceOnUse" x="180" y="270" width="560" height="560">
<feDropShadow dx="3" dy="5" stdDeviation="2.4" flood-color="#2a1704" flood-opacity="0.4"/>
</filter>
<path id="lugShape" d="M 432 332 C 400 314, 368 290, 354 266 C 346 252, 344 236, 352 226 C 360 216, 374 220, 384 234 L 442 306 Z"/>
<path id="smArc" d="M 399.5 777.7 A 243 243 0 0 0 500.5 777.7"/>
</defs>
<!-- ground shadows -->
<ellipse cx="450" cy="888" rx="255" ry="22" fill="#000" opacity="0.5" filter="url(#b6)"/>
<ellipse cx="450" cy="890" rx="310" ry="34" fill="#000" opacity="0.3" filter="url(#b14)"/>
<!-- strap, top -->
<g mask="url(#fadeTop)">
<rect x="365" y="50" width="170" height="290" fill="url(#strapLeather)"/>
<path d="M 366.5 50 V 340" stroke="rgba(255,214,160,.14)" stroke-width="1.6"/>
<path d="M 533.5 50 V 340" stroke="rgba(255,214,160,.14)" stroke-width="1.6"/>
<path d="M 450 50 V 340" stroke="rgba(0,0,0,.28)" stroke-width="1.3"/>
<path d="M 381 50 V 340" stroke="#b98d54" stroke-width="1.5" stroke-dasharray="7 6" opacity=".5"/>
<path d="M 519 50 V 340" stroke="#b98d54" stroke-width="1.5" stroke-dasharray="7 6" opacity=".5"/>
</g>
<!-- strap, bottom -->
<g mask="url(#fadeBot)">
<rect x="365" y="740" width="170" height="300" fill="url(#strapLeather)"/>
<path d="M 366.5 740 V 1040" stroke="rgba(255,214,160,.14)" stroke-width="1.6"/>
<path d="M 533.5 740 V 1040" stroke="rgba(255,214,160,.14)" stroke-width="1.6"/>
<path d="M 450 740 V 1040" stroke="rgba(0,0,0,.28)" stroke-width="1.3"/>
<path d="M 381 740 V 1040" stroke="#b98d54" stroke-width="1.5" stroke-dasharray="7 6" opacity=".5"/>
<path d="M 519 740 V 1040" stroke="#b98d54" stroke-width="1.5" stroke-dasharray="7 6" opacity=".5"/>
</g>
<!-- lugs -->
<use href="#lugShape" fill="url(#lugMetal)" stroke="#3a1d06" stroke-opacity=".5"/>
<use href="#lugShape" transform="translate(900 0) scale(-1 1)" fill="url(#lugMetalR)" stroke="#3a1d06" stroke-opacity=".5"/>
<use href="#lugShape" transform="translate(0 1080) scale(1 -1)" fill="url(#lugMetalB)" stroke="#3a1d06" stroke-opacity=".5"/>
<use href="#lugShape" transform="translate(900 1080) scale(-1 -1)" fill="url(#lugMetalBR)" stroke="#3a1d06" stroke-opacity=".5"/>
<!-- crown stem (revealed when the crown is pulled) -->
<g id="stem">
<rect x="740" y="536" width="36" height="8" fill="#4a2c10"/>
<rect x="740" y="537.6" width="36" height="1.6" fill="rgba(255,220,170,.35)"/>
</g>
<!-- case -->
<circle cx="450" cy="540" r="303" fill="#1a1108"/>
<circle cx="450" cy="540" r="300" fill="url(#bezelMetal)"/>
<circle cx="450" cy="540" r="300" fill="none" stroke="#3a220c" stroke-width="1.6" opacity=".85"/>
<circle cx="450" cy="540" r="296.8" fill="none" stroke="#ffedcf" stroke-width="1" opacity=".28"/>
<path id="aBezTop" fill="none" stroke="#fff6e4" stroke-opacity=".5" stroke-width="7" filter="url(#b3)"/>
<path id="aBezDark" fill="none" stroke="#2e1a06" stroke-opacity=".35" stroke-width="6" filter="url(#b3)"/>
<path id="aBezGlint" fill="none" stroke="#fffbf0" stroke-opacity=".8" stroke-width="2" filter="url(#b1)"/>
<path id="aBezGlint2" fill="none" stroke="#ffe9cd" stroke-opacity=".22" stroke-width="3.5" filter="url(#b2)"/>
<circle cx="450" cy="540" r="266" fill="none" stroke="rgba(28,13,2,.55)" stroke-width="5"/>
<!-- dial -->
<circle cx="450" cy="540" r="264" fill="url(#dialBase)"/>
<circle cx="450" cy="540" r="263.2" fill="none" stroke="rgba(255,242,220,.25)" stroke-width="1.2"/>
<g id="rays" clip-path="url(#dialClip)"></g>
<circle cx="450" cy="540" r="264" fill="url(#dialSheen)"/>
<circle cx="450" cy="540" r="264" fill="url(#dialVign)"/>
<g id="track">
<circle cx="450" cy="540" r="252" fill="none" stroke="#7c7054" stroke-width="0.9" opacity=".85"/>
<circle cx="450" cy="540" r="238" fill="none" stroke="#7c7054" stroke-width="0.9" opacity=".85"/>
</g>
<g id="indices"></g>
<!-- open-heart aperture at 9 o'clock -->
<g id="aperture">
<circle cx="315" cy="540" r="64" fill="none" stroke="url(#bezelMetal)" stroke-width="7"/>
<circle cx="315" cy="540" r="60.5" fill="url(#movePlate)"/>
<g clip-path="url(#winClip)">
<g id="perlage"></g>
<g transform="translate(284 571)">
<g id="fourthRot">
<path id="fourthGear" fill="url(#brass)" stroke="rgba(50,26,6,.55)" stroke-width="0.7"/>
<circle r="2.4" fill="#151009"/>
<circle cx="5.6" cy="0" r="1.9" fill="#191309"/>
<circle cx="-2.8" cy="4.9" r="1.9" fill="#191309"/>
<circle cx="-2.8" cy="-4.9" r="1.9" fill="#191309"/>
</g>
</g>
<g transform="translate(349 562)">
<g id="escRot">
<path id="escGear" fill="url(#brass)" stroke="rgba(50,26,6,.55)" stroke-width="0.7"/>
<circle r="3.1" fill="#d9ab74" stroke="rgba(50,26,6,.6)" stroke-width="0.6"/>
</g>
</g>
<path id="springD" fill="none" stroke="#44659c" stroke-width="1.1" opacity=".9"/>
<g id="balance">
<circle cx="315" cy="540" r="44" fill="none" stroke="rgba(15,8,0,.45)" stroke-width="1.6"/>
<path d="M 275 540 L 355 540" stroke="#d2a25a" stroke-width="6.5"/>
<path d="M 315 500 L 315 580" stroke="#d2a25a" stroke-width="6.5"/>
<path d="M 276 538.4 L 354 538.4" stroke="rgba(255,240,214,.5)" stroke-width="1.2"/>
<circle cx="315" cy="540" r="40.5" fill="none" stroke="#d2a25a" stroke-width="6"/>
<circle cx="315" cy="540" r="37.4" fill="none" stroke="rgba(255,240,214,.45)" stroke-width="1"/>
<circle cx="343.6" cy="511.4" r="2.7" fill="#ecd090" stroke="#6b4014" stroke-width=".7"/>
<circle cx="343.6" cy="568.6" r="2.7" fill="#ecd090" stroke="#6b4014" stroke-width=".7"/>
<circle cx="286.4" cy="568.6" r="2.7" fill="#ecd090" stroke="#6b4014" stroke-width=".7"/>
<circle cx="286.4" cy="511.4" r="2.7" fill="#ecd090" stroke="#6b4014" stroke-width=".7"/>
</g>
<path d="M 256 531 C 274 524, 296 524, 312 533 L 316 549 C 298 540, 276 540, 258 547 Z"
fill="#c79c5e" stroke="rgba(60,30,5,.5)" stroke-width=".8"/>
<circle cx="261" cy="539.5" r="3.6" fill="#d9b269" stroke="#5f3a12" stroke-width=".7"/>
<path d="M 258.4 537.6 L 263.8 541.4" stroke="#5f3a12" stroke-width="1"/>
<circle cx="315" cy="540" r="6.8" fill="#dccfa9" stroke="rgba(55,28,6,.55)" stroke-width="0.8"/>
<circle cx="315" cy="540" r="4" fill="#a41336"/>
<circle cx="313.7" cy="538.7" r="1.2" fill="rgba(255,205,195,.9)"/>
<circle cx="315" cy="540" r="59.5" fill="url(#winRecess)"/>
</g>
</g>
<!-- date window at 3 o'clock -->
<g id="dateWin">
<rect x="585" y="517.5" width="60" height="45" rx="7" fill="url(#bezelMetal)" filter="url(#idxShadow)"/>
<rect x="589" y="521.5" width="52" height="37" rx="4" fill="#2a1704"/>
<rect x="591.5" y="524" width="47" height="32" rx="2.5" fill="url(#dateDisc)"/>
<path d="M 592.5 555 L 592.5 525.2 L 637.5 525.2" fill="none" stroke="rgba(20,8,0,.42)" stroke-width="1.4"/>
<path d="M 637.5 525.2 L 637.5 555 L 592.5 555" fill="none" stroke="rgba(255,252,238,.5)" stroke-width="1.1"/>
<text id="dateText" x="615" y="549" text-anchor="middle" font-size="25" fill="#33291a"
font-family="Georgia,'Times New Roman',serif">1</text>
</g>
<g font-family="Georgia,'Times New Roman',serif">
<text x="446.5" y="404" text-anchor="middle" font-size="30" letter-spacing="7" fill="#3a3122">AUBERT</text>
<text x="447.3" y="427" text-anchor="middle" font-size="11" letter-spacing="5.5" fill="#8a7d63">GENÈVE</text>
<text x="449" y="656" text-anchor="middle" font-size="12.5" font-style="italic" letter-spacing="2" fill="#7d7157">AUTOMATIQUE</text>
<text font-size="9.5" letter-spacing="3.5" fill="#8d8168">
<textPath href="#smArc" startOffset="50%" text-anchor="middle">SWISS  MADE</textPath>
</text>
</g>
<!-- hands -->
<g id="hands" filter="url(#handShadow)">
<g id="hourH" transform="translate(450 540)">
<path d="M 0 26 L -9.5 -16 L 0 -160 Z" fill="#f2d8ac"/>
<path d="M 0 26 L 9.5 -16 L 0 -160 Z" fill="#c6905a"/>
<path d="M 0 26 L -9.5 -16 L 0 -160 L 9.5 -16 Z" fill="none" stroke="rgba(70,38,8,.45)" stroke-width="0.8"/>
<path d="M 0 23 L 0 -156" stroke="rgba(255,248,230,.8)" stroke-width="0.9"/>
</g>
<g id="minH" transform="translate(450 540)">
<path d="M 0 28 L -6.5 -14 L 0 -238 Z" fill="#f2d8ac"/>
<path d="M 0 28 L 6.5 -14 L 0 -238 Z" fill="#c6905a"/>
<path d="M 0 28 L -6.5 -14 L 0 -238 L 6.5 -14 Z" fill="none" stroke="rgba(70,38,8,.45)" stroke-width="0.7"/>
<path d="M 0 25 L 0 -234" stroke="rgba(255,248,230,.8)" stroke-width="0.8"/>
</g>
<g id="secH" transform="translate(450 540)">
<path d="M -1.4 34 L -0.55 -248 L 0.55 -248 L 1.4 34 Z" fill="url(#gradBlued)"/>
<path d="M -0.4 30 L -0.4 -243" stroke="rgba(200,220,255,.55)" stroke-width="0.6"/>
<circle cy="30" r="8.5" fill="none" stroke="url(#gradBlued)" stroke-width="4"/>
</g>
<g id="capG">
<circle cx="450" cy="540" r="10" fill="url(#goldCap)" stroke="rgba(60,30,5,.55)" stroke-width="0.9"/>
<circle cx="450" cy="540" r="3.4" fill="#7a4e22"/>
<circle cx="447" cy="536.5" r="1.6" fill="rgba(255,250,235,.7)"/>
</g>
</g>
<!-- sapphire crystal -->
<g id="crystal">
<circle cx="450" cy="540" r="263" fill="none" stroke="rgba(30,15,0,.28)" stroke-width="2"/>
<circle cx="450" cy="540" r="264" fill="url(#glassTint)"/>
<g id="glare">
<ellipse cx="352" cy="426" rx="150" ry="56" fill="#ffffff" opacity="0.08" transform="rotate(-33 352 426)" filter="url(#b14)"/>
<ellipse cx="566" cy="650" rx="92" ry="24" fill="#ffffff" opacity="0.055" transform="rotate(-33 566 650)" filter="url(#b10)"/>
<path id="aGlassTop" fill="none" stroke="#ffffff" stroke-opacity=".3" stroke-width="2" filter="url(#b1)"/>
<path id="aGlassBot" fill="none" stroke="#a9c1e8" stroke-opacity=".14" stroke-width="3" filter="url(#b2)"/>
</g>
</g>
<!-- fluted crown -->
<g id="crown">
<g id="crownBody">
<rect x="756" y="510" width="45" height="60" rx="13" fill="url(#crownMetal)" stroke="rgba(48,24,6,.55)" stroke-width="1"/>
<path d="M763 513V567 M769.6 513V567 M776.2 513V567 M782.8 513V567 M789.4 513V567"
stroke="rgba(70,36,8,.45)" stroke-width="2.2"/>
<path d="M765 513V567 M771.6 513V567 M778.2 513V567 M784.8 513V567 M791.4 513V567"
stroke="rgba(255,236,200,.3)" stroke-width="1"/>
<ellipse cx="797.5" cy="540" rx="6" ry="26.5" fill="#e2bc82" stroke="rgba(48,24,6,.5)" stroke-width="0.8"/>
<ellipse cx="797.5" cy="540" rx="2.6" ry="13" fill="rgba(110,60,15,.45)"/>
<rect x="758" y="513" width="38" height="3" rx="1.5" fill="rgba(255,246,226,.45)"/>
</g>
<rect id="crownHit" x="728" y="494" width="92" height="92" fill="transparent" tabindex="0" role="button"
aria-label="Crown: click to stop or restart the movement"/>
</g>
</svg>
</div></div>
<footer>
<div class="specs">CALIBRE AB-21 · 28,800 VPH · 5N ROSE GOLD · SAPPHIRE</div>
<div class="status" id="status">MOVEMENT RUNNING — CLICK THE CROWN TO STOP THE BALANCE</div>
<div class="hint">MOVE YOUR CURSOR — THE SUNBURST DIAL CATCHES THE LIGHT</div>
</footer>
</main>
<div class="grain"></div>
<script>
(function(){
'use strict';
const NS='http://www.w3.org/2000/svg';
const $=id=>document.getElementById(id);
const el=(tag,attrs,parent)=>{
const n=document.createElementNS(NS,tag);
for(const k in attrs) n.setAttribute(k,attrs[k]);
if(parent) parent.appendChild(n);
return n;
};
// polar helper: compass angle (0 = 12 o'clock, clockwise), around dial centre
const CX=450, CY=540;
const P=(r,a)=>[CX+r*Math.sin(a), CY-r*Math.cos(a)];
const arcD=(r,a1,a2)=>{
const [x1,y1]=P(r,a1*Math.PI/180),[x2,y2]=P(r,a2*Math.PI/180);
const large=((a2-a1)%360+360)%360>180?1:0;
return `M ${x1.toFixed(2)} ${y1.toFixed(2)} A ${r} ${r} 0 ${large} 1 ${x2.toFixed(2)} ${y2.toFixed(2)}`;
};
const reduced=matchMedia('(prefers-reduced-motion: reduce)').matches;
/* ---------- generated geometry ---------- */
// sunray brushing: 144 fine radial lines, opacity driven live by light direction
const raysG=$('rays'), rays=[];
for(let i=0;i<144;i++){
const a=i*2.5*Math.PI/180;
const [x1,y1]=P(26,a),[x2,y2]=P(262,a);
const L=el('line',{x1:x1.toFixed(1),y1:y1.toFixed(1),x2:x2.toFixed(1),y2:y2.toFixed(1),
stroke:'#fffdf2','stroke-width':1.15,'stroke-opacity':0.08},raysG);
rays.push({el:L,a,j:0.85+Math.random()*0.35});
}
// chemin-de-fer minute track
const track=$('track');
for(let i=0;i<60;i++){
const a=i*6*Math.PI/180, maj=i%5===0;
const [x1,y1]=P(maj?232:240.5,a),[x2,y2]=P(maj?252:250,a);
el('line',{x1:x1.toFixed(1),y1:y1.toFixed(1),x2:x2.toFixed(1),y2:y2.toFixed(1),
stroke:maj?'#3f3624':'#5c523d','stroke-width':maj?2.4:1.1,'stroke-opacity':.9},track);
}
// applied faceted baton indices (3 and 9 make way for the date window / aperture)
const idx=$('indices');
const baton=(g,bx)=>{
const t='translate(450 540)';
el('path',{d:`M ${bx-5.5} -192 L ${bx-5.5} -230.5 L ${bx} -232.5 L ${bx} -190.5 Z`,fill:'#f4dbb0',transform:t},g);
el('path',{d:`M ${bx} -190.5 L ${bx} -232.5 L ${bx+5.5} -230.5 L ${bx+5.5} -192 Z`,fill:'#b07c42',transform:t},g);
el('path',{d:`M ${bx-5.5} -192 L ${bx-5.5} -230.5 L ${bx} -232.5 L ${bx+5.5} -230.5 L ${bx+5.5} -192 Z`,
fill:'none',stroke:'rgba(70,36,8,.5)','stroke-width':0.8,transform:t},g);
el('path',{d:`M ${bx} -231 L ${bx} -191.5`,stroke:'rgba(255,246,228,.85)','stroke-width':0.9,transform:t},g);
};
for(let h=0;h<12;h++){
if(h===3||h===9) continue;
const g=el('g',{transform:`rotate(${h*30} 450 540)`,filter:'url(#idxShadow)'},idx);
if(h===0){baton(g,-9.5);baton(g,9.5);} else baton(g,0);
}
// perlage decoration inside the movement window
const pg=$('perlage');
for(let j=0;j<9;j++){
const y=496+j*11, off=(j%2)*5.5;
for(let i=0;i<12;i++)
el('circle',{cx:(251+i*12+off).toFixed(1),cy:y,r:8,fill:'none',
stroke:'rgba(255,228,190,.06)','stroke-width':2.4},pg);
}
// blued hairspring: Archimedean spiral
let sd='M 315 543';
for(let k=1;k<=120;k++){
const th=k/120*4.75*2*Math.PI, r=3+23*(k/120);
sd+=` L ${(315+Math.cos(th)*r).toFixed(2)} ${(540+Math.sin(th)*r).toFixed(2)}`;
}
$('springD').setAttribute('d',sd);
// gear teeth generator
const gearPath=(r,n,depth)=>{
const step=Math.PI*2/n, pts=[];
for(let i=0;i<n;i++){
const a=i*step;
pts.push([a+step*0.08,r-depth],[a+step*0.30,r],[a+step*0.55,r],[a+step*0.80,r-depth]);
}
return 'M '+pts.map(p=>(Math.cos(p[0])*p[1]).toFixed(2)+' '+(Math.sin(p[0])*p[1]).toFixed(2)).join(' L ')+' Z';
};
$('escGear').setAttribute('d',gearPath(15,15,3));
$('fourthGear').setAttribute('d',gearPath(12.5,12,2.7));
// fixed studio reflection arcs
$('aBezTop').setAttribute('d',arcD(287,326,54));
$('aBezDark').setAttribute('d',arcD(287,126,234));
$('aBezGlint').setAttribute('d',arcD(281,346,24));
$('aBezGlint2').setAttribute('d',arcD(284,146,166));
$('aGlassTop').setAttribute('d',arcD(256,333,27));
$('aGlassBot').setAttribute('d',arcD(259,137,223));
/* ---------- state ---------- */
const hourH=$('hourH'),minH=$('minH'),secH=$('secH'),balance=$('balance'),
spring=$('springD'),escRot=$('escRot'),fourthRot=$('fourthRot'),
crownBody=$('crownBody'),bezelGrad=$('bezelMetal'),sheenGrad=$('dialSheen'),
glare=$('glare'),tiltWrap=$('tiltWrap'),statusEl=$('status'),
dateText=$('dateText'),clockDigits=$('clockDigits');
const DEFAULT_STATUS='MOVEMENT RUNNING — CLICK THE CROWN TO STOP THE BALANCE';
let mode='run'; // run | hacked | settle
let frozenT=0, fromA=null, pullWall=0, pushWall=0, settleStart=0;
let crownTarget=0, cx=0, cxv=0;
let tpx=0, tpy=0, px=0, py=0, lastPhi=-999;
let shownDay=-1, lastClock='', revertTimer=null;
// display angles from a timestamp; seconds quantised to 1/8 s (28,800 vph sweep)
function displayAngles(t){
const d=new Date(t);
const s=d.getSeconds()+d.getMilliseconds()/1000;
const sq=Math.floor(s*8)/8;
return {
sec:sq*6,
min:(d.getMinutes()+s/60)*6,
hour:((d.getHours()%12)+d.getMinutes()/60+s/3600)*30,
sRaw:s
};
}
function setHands(a){
hourH.setAttribute('transform',`translate(450 540) rotate(${a.hour.toFixed(3)})`);
minH.setAttribute('transform',`translate(450 540) rotate(${a.min.toFixed(3)})`);
secH.setAttribute('transform',`translate(450 540) rotate(${a.sec.toFixed(3)})`);
}
function setStatus(text,alert){
statusEl.classList.add('fade');
setTimeout(()=>{
statusEl.textContent=text;
statusEl.classList.toggle('alert',!!alert);
statusEl.classList.remove('fade');
},180);
}
function updateLight(phi,lx,ly){
const rad=phi*Math.PI/180;
for(const r of rays){
const o=0.05+0.34*Math.pow(Math.abs(Math.cos(r.a-rad)),9);
r.el.setAttribute('stroke-opacity',(o*r.j).toFixed(3));
}
bezelGrad.setAttribute('gradientTransform',`rotate(${(phi+90).toFixed(1)} 450 540)`);
sheenGrad.setAttribute('cx',(450+lx*250).toFixed(1));
sheenGrad.setAttribute('cy',(540+ly*250).toFixed(1));
glare.setAttribute('transform',`translate(${(lx*34).toFixed(1)} ${(ly*26).toFixed(1)})`);
}
/* ---------- sound (tiny mechanical click, synthesised locally) ---------- */
let AC=null;
function tick(freq,dur,vol,type){
try{
AC=AC||new (window.AudioContext||window.webkitAudioContext)();
if(AC.state==='suspended') AC.resume();
const o=AC.createOscillator(), g=AC.createGain(), t=AC.currentTime;
o.type=type||'square';
o.frequency.setValueAtTime(freq,t);
o.frequency.exponentialRampToValueAtTime(Math.max(60,freq*0.6),t+dur);
g.gain.setValueAtTime(vol,t);
g.gain.exponentialRampToValueAtTime(0.0001,t+dur);
o.connect(g); g.connect(AC.destination);
o.start(t); o.stop(t+dur+0.02);
}catch(e){}
}
/* ---------- crown: hacking seconds ---------- */
function toggleCrown(){
if(mode!=='hacked'){
frozenT=Date.now();
fromA=displayAngles(frozenT);
mode='hacked'; pullWall=performance.now(); crownTarget=17;
tick(1450,.045,.05); tick(500,.08,.035);
setStatus('MOVEMENT HALTED — PUSH THE CROWN HOME TO RESUME',true);
}else{
pushWall=settleStart=performance.now();
mode='settle'; crownTarget=0;
tick(950,.05,.05); tick(300,.1,.05,'triangle');
setStatus('BALANCE RESTARTED — HANDS SYNCED TO LOCAL TIME',false);
clearTimeout(revertTimer);
revertTimer=setTimeout(()=>setStatus(DEFAULT_STATUS,false),4200);
}
}
$('crownHit').addEventListener('click',toggleCrown);
$('crownHit').addEventListener('keydown',e=>{
if(e.key==='Enter'||e.key===' '){e.preventDefault();toggleCrown();}
});
/* ---------- pointer / tilt ---------- */
addEventListener('pointermove',e=>{
tpx=Math.max(-1,Math.min(1,(e.clientX/innerWidth-0.5)*2));
tpy=Math.max(-1,Math.min(1,(e.clientY/innerHeight-0.5)*2));
});
document.addEventListener('pointerleave',()=>{tpx=0;tpy=0;});
addEventListener('blur',()=>{tpx=0;tpy=0;});
/* ---------- main loop ---------- */
const pad2=n=>String(n).padStart(2,'0');
function loop(now){
requestAnimationFrame(loop);
// gentle parallax tilt, eased
px+=(tpx-px)*0.06; py+=(tpy-py)*0.06;
if(!reduced) tiltWrap.style.transform=`rotateX(${(-py*8).toFixed(2)}deg) rotateY(${(px*8).toFixed(2)}deg)`;
// light direction: cursor position + a slow autonomous drift so the sunburst shimmers on its own
const lx=reduced?0:Math.max(-1,Math.min(1,px+0.22*Math.sin(now/8600)));
const ly=reduced?0:Math.max(-1,Math.min(1,py+0.18*Math.cos(now/11300)));
const phi=Math.atan2(lx,-ly)*180/Math.PI;
if(Math.abs(phi-lastPhi)>0.2){updateLight(phi,lx,ly);lastPhi=phi;}
// hands
let angles;
if(mode==='hacked'){
angles=displayAngles(frozenT);
}else if(mode==='settle'){
const live=displayAngles(Date.now());
const p=Math.min(1,(now-settleStart)/950);
const e1=1-Math.pow(1-p,3), e2=1-Math.pow(1-p,2.6);
const dH=((live.hour-fromA.hour+540)%360)-180;
const dM=((live.min-fromA.min+540)%360)-180;
const dS=((live.sec-fromA.sec)%360+360)%360;
const wob=Math.sin(p*Math.PI*2.2)*Math.pow(1-p,1.6)*4.5;
angles={hour:fromA.hour+dH*e1, min:fromA.min+dM*e1, sec:fromA.sec+dS*e2+wob, sRaw:live.sRaw};
if(p>=1) mode='run';
}else{
angles=displayAngles(Date.now());
}
setHands(angles);
// balance wheel: ±250° at 4 Hz; winds down when hacked, spins up on restart
let amp=250;
if(mode==='hacked') amp=250*Math.pow(Math.max(0,1-(now-pullWall)/1500),1.5);
else if(mode==='settle') amp=250*Math.pow(Math.min(1,(now-pushWall)/900),0.8);
const ph=now/1000*Math.PI*2*4;
const th=amp*Math.sin(ph);
balance.setAttribute('transform',`rotate(${th.toFixed(2)} 315 540)`);
const sc=1+0.05*(amp/250)*Math.sin(2*ph);
spring.setAttribute('transform',
`translate(315 540) rotate(${(th*0.14).toFixed(2)}) scale(${sc.toFixed(4)}) translate(-315 -540)`);
// escape wheel steps 8 times per second, in sync with the seconds hand
const step=Math.floor(angles.sRaw*8);
escRot.setAttribute('transform',`rotate(${(-(step*12)%360).toFixed(2)})`);
fourthRot.setAttribute('transform',`rotate(${(-angles.sRaw*6).toFixed(2)})`);
// crown slide with a slight mechanical overshoot
cxv+=(crownTarget-cx)*0.16-cxv*0.30; cx+=cxv;
crownBody.setAttribute('transform',`translate(${cx.toFixed(2)} 0)`);
// header clock (always real local time) + date window (follows the movement)
const rd=new Date();
const ck=`${pad2(rd.getHours())}:${pad2(rd.getMinutes())}:${pad2(rd.getSeconds())}`;
if(ck!==lastClock){clockDigits.textContent=ck;lastClock=ck;
document.title=`${pad2(rd.getHours())}:${pad2(rd.getMinutes())} — Aubert Genève`;}
const dd=new Date(mode==='hacked'?frozenT:Date.now());
if(dd.getDate()!==shownDay){shownDay=dd.getDate();dateText.textContent=String(shownDay);}
}
requestAnimationFrame(loop);
})();
</script>
</body>
</html>

