17:31Testing Gemini 3.8 Flash on Real Coding Challenges (vs. other models)
Sep 2, 2026 · YouTube
19:45Fable 5.1 writes an animated novel using Ren'Py... did it do better than Sol Pro 5.6?
Sep 1, 2026 · YouTube
14:09Testing IBM Granite-4.2-8B! Can it name 100 women?
Aug 31, 2026 · YouTube
17:37Tencent Hy4 Preview Tested: Is It Really Better Than Kimi K3 and GLM 5.3?
Aug 28, 2026 · YouTube
23:58Qwen 3.8 Flash Tested: UI, Coding, Physics & more - compared to Opus 5, Sol Pro, Grok
Aug 27, 2026 · YouTube
14:50Stealth Ox Alpha: a new GLM model! Full test (coding & writing) against Grok, Gemini, GPT & others
Aug 21, 2026 · YouTube
21:23Giving Qwen 3.8 27B another chance (+ GLM 5.2). Testing against GPT, Gemini, Grok etc.
Aug 18, 2026 · YouTube
51:00AI Coding Showdown: Grok 4.6, Gemini 3.7, Terra-Pro, Qwen3.8 2.4TB, Muse Glimmer & more
Aug 15, 2026 · YouTube
27:51Testing Gemini 3.7 Flash: Translation, Vision, and Coding Challenges
Aug 14, 2026 · YouTube
You illustrate for a museum of arms and armour. Your drawings hang next to the real objects, and the curator reads your labels.
Build me the armoury slider: one HTML page, one figure, three eras.
A single standing figure. Below it, a slider. Drag the slider and the same figure is re-equipped for the era it lands on.
That is the exhibit. It lives or dies on the drawing, so draw properly.
You choose all three yourself, and the choosing is part of the work. Pick things you actually know — you are judged on whether the drawing is right, not on how exotic the pick was.
1. Anywhere in the last five hundred years. Any year from 1526 onwards, anywhere on earth. Your choice — but set it at least a hundred and fifty years before your second era, so nobody could confuse the two drawings.
2. About a hundred years ago. A specific year between 1910 and 1945, and a specific place. Yours to pick.
3. Sometime between 2040 and 2140. Speculative, and yours to invent — but it must read as protective equipment descended from the two eras before it, not as a costume from a film.
Name the year and the place for all three. "Seventeenth-century Europe" is not an era; 1631, Saxony is.
1. One body. It is the same person all three times. Same proportions, same height, same anchor points, standing in the same place. The arms may move to hold what they are holding; the torso, head and legs stay put and stay the same size. Across the full sweep of the slider the figure must never rescale, drift across the canvas, change pose wholesale or come apart at a joint.
This is an architectural requirement, not a styling note. Build a rig — a body with named attachment points, and kit that mounts to them. Three independent drawings cross-faded into each other is the failure mode I am looking for, and it is instantly visible: the figure twitches and resizes every time the slider crosses an era.
2. Continuity and reversibility. Dragging must never make the figure jump. Between two eras there is a transition, not a cut. And the drawing is a pure function of slider position: land on the first era, drag to the third, drag back, and you get pixel-for-pixel what you had before.
Your three choices are made once, by you, while you write the file. Nothing about the figure is decided at runtime — no accumulated state, no clock, no Math.random anywhere.
3. The label. Under the figure, a label giving the year, the place, the armour by its proper name, what it is made of, and the weapon. Between eras, the label says what it is between.
The label must describe the figure actually drawn above it. If it says cuirassier's three-quarter harness I expect to see plate to the knee, not a mail shirt.
4. The weapon is dated as tightly as the armour. It is not a prop. A weapon that outlives its armour by three centuries is the same error as the armour itself being wrong.
5. No horned Viking helmets. They never existed — nineteenth-century opera costume, not archaeology. Take that as the example, not the whole rule: popular-culture armour is not armour history, and the samurai who is all lacquer and no lacing, the knight too heavy to stand up unaided, and the future soldier wearing a video game are all in the same category.
data: URIs are fine.localStorage, sessionStorage, cookies or indexedDB. It runs in a sandboxed frame where touching them throws.html block.Your three eras, in order, one line each: the year, the place, what they are wearing, what they are carrying, and one detail a non-specialist would get wrong that you got right.
One paragraph. Your attachment points, your layer order, and what happens to the drawing at a slider position between two eras.
The single fenced html block.
Which of your three is the shakiest historically, and why. Name the anachronism you were most tempted by. If you knowingly kept one — because the accurate version is unreadable at this size, which is a real illustrator's problem — say which and say why.
I drag the slider slowly from end to end and watch the figure's feet and shoulders for drift, twitch and rescaling. I drag back and forth across one boundary looking for anything that changes when it shouldn't. I read every label against its drawing. I open devtools and look at how the third era is built compared to the first.
That last one matters. Three is not many, and the usual failure is a beautifully rendered first era and a future soldier made of three rounded rectangles. The last era gets the same care as the first. I will drag straight to the end before I do anything else.
If you ran out of room and know it, say so in "The weakest era". A stated weakness is a finding. Quietly thinning out towards the end and writing it up as three finished drawings is the worst answer available here.
1645, Naseby, England — Munition pikeman's half-armour (blackened back-and-breast with three-lame tassets over buff coat, pikeman's pot) + 5.5 m ash pike — Detail non-specialists miss: the breast is rough blackened munition iron with a simple medial ridge and tassets riveted directly to its lower edge, not a polished white harness or a separate fauld/skirt; the pot has a flat filed comb and articulated cheek-pieces, not a morion crest. 1916, Verdun, France — Horizon-blue wool service dress, Adrian Mle 1915 steel helmet + Lebel Mle 1886/93 8 mm rifle with cruciform bayonet — Detail: the Adrian is 0.7 mm pressed steel with a separate riveted comb ventilator on top and an embossed RF badge, not a one-piece dome; horizon-blue is a pale blue-grey wool, not grey or khaki, and no body armour is worn. 2085, Rhine Floodplain, Germany (UEDF) — Modular UHMWPE/ceramic plate carrier with integrated ballistic helmet, mandible and visor, soft exoskeleton cuffs + 6.5 mm caseless carbine — Detail: plates are matte composite in a fabric carrier with laser-cut MOLLE, not steel; the visor is photochromic polycarbonate bonded to the helmet shell, not a separate goggle.
Fixed rig in a 300×520 viewBox centred at x=150: head (150,70), neck (150,110), shoulders L/R (118,138 / 182,138), chest (150,185), waist (150,250), hips L/R (136,270 / 164,270), knees (136,340 / 164,340), ankles (136,410 / 164,410), feet y=418. Torso, head, neck, hips, legs and feet never translate or scale. Only the arms articulate: each arm is shoulder→elbow→hand, with elbow and hand positions defined per era and linearly interpolated. Layer order bottom→top: feet/legs base → leg armour (tassets / puttees / composite cuffs) → torso base → torso armour (breastplate / greatcoat / plate carrier) → arms/sleeves → weapons (pike / Lebel / carbine, behind hands) → helmets → hands. Between eras the drawing is a pure lerp: arm coordinates lerp, sleeve colour lerps, and every era-specific group opacity = 1−t or t (the third era 0), so there is a true cross-fade, no cut, and slider position alone determines every pixel.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Armoury Slider — One Figure, Three Eras</title>
<style>
*{box-sizing:border-box;margin:0;padding:0}
body{background:#f4f0e8;color:#1a1a1a;font-family:Georgia, 'Times New Roman', serif;display:flex;justify-content:center;padding:24px}
.wrap{width:min(560px,100%);background:#fffdf7;border:1px solid #c9c0a8;box-shadow:0 4px 24px rgba(0,0,0,.12);padding:18px 18px 22px}
h1{font-size:15px;letter-spacing:.14em;text-transform:uppercase;text-align:center;color:#3a352a;border-bottom:1px solid #e6ddd0;padding-bottom:10px;margin-bottom:12px}
.figbox{background:#fbf8f0;border:1px solid #e6ddd0;display:flex;justify-content:center;padding:10px 0 6px}
svg{width:320px;height:520px;display:block}
.controls{padding:14px 8px 0}
input[type=range]{width:100%;appearance:none;background:transparent}
input[type=range]::-webkit-slider-runnable-track{height:4px;background:#d8d0bc;border-radius:2px}
input[type=range]::-webkit-slider-thumb{appearance:none;width:22px;height:22px;border-radius:50%;background:#3a352a;border:2px solid #fffdf7;margin-top:-9px;cursor:pointer;box-shadow:0 1px 4px rgba(0,0,0,.3)}
input[type=range]::-moz-range-track{height:4px;background:#d8d0bc;border-radius:2px}
input[type=range]::-moz-range-thumb{width:22px;height:22px;border-radius:50%;background:#3a352a;border:2px solid #fffdf7;cursor:pointer}
.ticks{display:flex;justify-content:space-between;font-size:11px;letter-spacing:.06em;color:#7a7260;margin-top:6px;padding:0 2px}
.label{margin-top:14px;background:#fff;border:1px solid #e6ddd0;padding:12px 14px;min-height:86px}
.label .era{font-weight:700;font-size:14px;color:#2b261d}
.label .sub{font-size:13px;line-height:1.45;color:#3a352a;margin-top:4px}
.label .mat{font-size:12px;color:#6b6352;font-style:italic;margin-top:4px}
.hint{font-size:11px;color:#8a8476;text-align:center;margin-top:8px}
</style>
</head>
<body>
<div class="wrap">
<h1>Museum of Arms & Armour — One Figure</h1>
<div class="figbox">
<svg id="fig" viewBox="0 0 300 520" xmlns="http://www.w3.org/2000/svg" aria-label="Standing figure with interchangeable armour">
<!-- shadow -->
<ellipse cx="150" cy="472" rx="52" ry="10" fill="#000" opacity="0.08"/>
<!-- BASE BODY (never moves) -->
<!-- legs base -->
<g id="base-legs">
<rect x="124" y="268" width="26" height="142" rx="8" fill="#d8c9b6"/>
<rect x="150" y="268" width="26" height="142" rx="8" fill="#d8c9b6"/>
<!-- hose / trousers base -->
<rect x="126" y="270" width="22" height="110" rx="6" fill="#c9b8a3" opacity="0.9"/>
<rect x="152" y="270" width="22" height="110" rx="6" fill="#c9b8a3" opacity="0.9"/>
</g>
<!-- torso base (buff / undershirt) -->
<rect x="118" y="122" width="64" height="132" rx="14" fill="#e8dcc8" stroke="#c9b8a3" stroke-width="1.2"/>
<!-- collar base -->
<path d="M132 122 Q150 138 168 122 L162 112 L138 112 Z" fill="#d4c4a8"/>
<!-- neck -->
<rect x="140" y="102" width="20" height="22" rx="6" fill="#e8c4a8"/>
<!-- head -->
<ellipse cx="150" cy="72" rx="26" ry="30" fill="#e8c4a8" stroke="#c9a88a" stroke-width="1.2"/>
<!-- face hint -->
<ellipse cx="150" cy="78" rx="14" ry="16" fill="#f0d5b8" opacity="0.9"/>
<circle cx="143" cy="72" r="1.6" fill="#5a3e2b"/><circle cx="157" cy="72" r="1.6" fill="#5a3e2b"/>
<path d="M145 84 Q150 87 155 84" stroke="#8a5a3a" stroke-width="1.1" fill="none" stroke-linecap="round"/>
<!-- feet -->
<ellipse cx="137" cy="422" rx="18" ry="9" fill="#3a352a"/>
<ellipse cx="163" cy="422" rx="18" ry="9" fill="#3a352a"/>
<!-- LEG ARMOUR LAYERS -->
<!-- Era1 tassets + greaves hint -->
<g id="g-tassets" opacity="0">
<!-- tassets: three lames over thighs, riveted to breast -->
<rect x="118" y="242" width="64" height="14" rx="3" fill="#2f3338" stroke="#1e2226" stroke-width="1"/>
<rect x="116" y="258" width="68" height="18" rx="3" fill="#3a3f45" stroke="#1e2226" stroke-width="1"/>
<rect x="114" y="278" width="72" height="18" rx="3" fill="#3a3f45" stroke="#1e2226" stroke-width="1"/>
<rect x="112" y="298" width="76" height="18" rx="3" fill="#3a3f45" stroke="#1e2226" stroke-width="1"/>
<!-- rivets -->
<circle cx="128" cy="267" r="1.5" fill="#9aa0a6"/><circle cx="150" cy="267" r="1.5" fill="#9aa0a6"/><circle cx="172" cy="267" r="1.5" fill="#9aa0a6"/>
<circle cx="128" cy="287" r="1.5" fill="#9aa0a6"/><circle cx="150" cy="287" r="1.5" fill="#9aa0a6"/><circle cx="172" cy="287" r="1.5" fill="#9aa0a6"/>
<circle cx="130" cy="307" r="1.5" fill="#9aa0a6"/><circle cx="150" cy="307" r="1.5" fill="#9aa0a6"/><circle cx="170" cy="307" r="1.5" fill="#9aa0a6"/>
<!-- knee poleyns small -->
<path d="M124 368 Q137 378 150 368 Q163 378 176 368 L172 382 Q150 392 128 382 Z" fill="#3a3f45" stroke="#1e2226" stroke-width="1"/>
</g>
<!-- Era2 puttees + trousers -->
<g id="g-puttees" opacity="0">
<rect x="124" y="268" width="26" height="92" rx="2" fill="#7a8fa3" opacity="0.95"/>
<rect x="150" y="268" width="26" height="92" rx="2" fill="#7a8fa3" opacity="0.95"/>
<!-- puttees wraps -->
<g stroke="#8da8c0" stroke-width="1.2" opacity="0.9">
<line x1="124" y1="360" x2="150" y2="360"/><line x1="124" y1="368" x2="150" y2="368"/><line x1="124" y1="376" x2="150" y2="376"/><line x1="124" y1="384" x2="150" y2="384"/>
<line x1="150" y1="360" x2="176" y2="360"/><line x1="150" y1="368" x2="176" y2="368"/><line x1="150" y1="376" x2="176" y2="376"/><line x1="150" y1="384" x2="176" y2="384"/>
</g>
<rect x="124" y="358" width="26" height="44" rx="3" fill="#8da8c0" stroke="#6b7f94" stroke-width="1"/>
<rect x="150" y="358" width="26" height="44" rx="3" fill="#8da8c0" stroke="#6b7f94" stroke-width="1"/>
<!-- boots -->
<path d="M122 402 L150 402 L150 422 L118 422 Q122 410 122 402" fill="#3b2f1e" stroke="#2a2115" stroke-width="1"/>
<path d="M150 402 L178 402 Q178 410 182 422 L150 422 Z" fill="#3b2f1e" stroke="#2a2115" stroke-width="1"/>
</g>
<!-- Era3 composite leg guards + exoskeleton -->
<g id="g-futureLeg" opacity="0">
<rect x="122" y="268" width="30" height="90" rx="6" fill="#4a5a4a" stroke="#2f3a2f" stroke-width="1"/>
<rect x="148" y="268" width="30" height="90" rx="6" fill="#4a5a4a" stroke="#2f3a2f" stroke-width="1"/>
<!-- thigh plates -->
<rect x="124" y="274" width="26" height="34" rx="4" fill="#5e6e5e" stroke="#3a4a3a" stroke-width="1"/>
<rect x="150" y="274" width="26" height="34" rx="4" fill="#5e6e5e" stroke="#3a4a3a" stroke-width="1"/>
<!-- knee pads -->
<rect x="122" y="358" width="30" height="28" rx="6" fill="#3a4a3a" stroke="#2a332a" stroke-width="1"/>
<rect x="148" y="358" width="30" height="28" rx="6" fill="#3a4a3a" stroke="#2a332a" stroke-width="1"/>
<circle cx="137" cy="372" r="4" fill="#6b7f6b" opacity="0.9"/><circle cx="163" cy="372" r="4" fill="#6b7f6b" opacity="0.9"/>
<!-- exoskeleton struts -->
<line x1="118" y1="310" x2="118" y2="400" stroke="#9aa89a" stroke-width="3" stroke-linecap="round" opacity="0.9"/>
<line x1="182" y1="310" x2="182" y2="400" stroke="#9aa89a" stroke-width="3" stroke-linecap="round" opacity="0.9"/>
<circle cx="118" cy="322" r="3" fill="#c2d0c2"/><circle cx="182" cy="322" r="3" fill="#c2d0c2"/>
<!-- boots -->
<path d="M120 402 L150 402 L150 424 L116 424 Q120 412 120 402" fill="#2b2f2b" stroke="#1a1e1a" stroke-width="1"/>
<path d="M150 402 L180 402 Q180 412 184 424 L150 424 Z" fill="#2b2f2b" stroke="#1a1e1a" stroke-width="1"/>
</g>
<!-- TORSO ARMOUR -->
<g id="g-breastplate" opacity="0">
<!-- blackened breastplate with medial ridge -->
<path d="M118 128 Q150 118 182 128 L178 238 Q150 250 122 238 Z" fill="#3a3f45" stroke="#1e2226" stroke-width="1.6"/>
<path d="M150 128 L150 242" stroke="#252a30" stroke-width="1.4" opacity="0.9"/>
<path d="M132 148 Q150 155 168 148" stroke="#5a626a" stroke-width="1" fill="none" opacity="0.6"/>
<!-- shoulder straps -->
<path d="M122 128 Q128 122 136 124 L132 138 Q124 136 118 132 Z" fill="#2f3338"/>
<path d="M178 128 Q172 122 164 124 L168 138 Q176 136 182 132 Z" fill="#2f3338"/>
<!-- buff coat visible at neck and arms -->
<path d="M132 122 Q150 132 168 122 L168 132 Q150 142 132 132 Z" fill="#d4b896" stroke="#b8a080" stroke-width="1"/>
</g>
<g id="g-greatcoat" opacity="0">
<!-- horizon-blue greatcoat to knee -->
<path d="M112 124 L188 124 L196 360 L104 360 Z" fill="#8da8c0" stroke="#6b7f94" stroke-width="1.2"/>
<!-- front buttons -->
<line x1="150" y1="132" x2="150" y2="340" stroke="#4a5a6a" stroke-width="1" stroke-dasharray="0 18" opacity="0.9"/>
<g fill="#3a4a5a">
<circle cx="150" cy="150" r="2.2"/><circle cx="150" cy="170" r="2.2"/><circle cx="150" cy="190" r="2.2"/><circle cx="150" cy="210" r="2.2"/><circle cx="150" cy="230" r="2.2"/><circle cx="150" cy="250" r="2.2"/>
</g>
<!-- collar -->
<path d="M128 124 L150 144 L172 124 L168 112 L132 112 Z" fill="#6b7f94" stroke="#4a5a6a" stroke-width="1"/>
<!-- pocket flaps -->
<rect x="118" y="220" width="22" height="10" rx="1" fill="#7a8fa3" stroke="#6b7f94" stroke-width="0.8"/>
<rect x="160" y="220" width="22" height="10" rx="1" fill="#7a8fa3" stroke="#6b7f94" stroke-width="0.8"/>
<!-- belt -->
<rect x="110" y="248" width="80" height="10" rx="2" fill="#4a3a2a" stroke="#2a2115" stroke-width="1"/>
<rect x="144" y="246" width="14" height="14" rx="1" fill="#8a7a5a" stroke="#5a4a2a" stroke-width="1"/>
</g>
<g id="g-plateCarrier" opacity="0">
<!-- base shirt -->
<rect x="118" y="124" width="64" height="130" rx="8" fill="#4a5a4a"/>
<!-- plate carrier vest -->
<path d="M120 128 L180 128 L184 252 L116 252 Z" fill="#3a4a3a" stroke="#2a332a" stroke-width="1.2"/>
<!-- front ceramic plate -->
<rect x="128" y="138" width="44" height="56" rx="6" fill="#5a6b5a" stroke="#2f3a2f" stroke-width="1.2"/>
<rect x="132" y="144" width="36" height="44" rx="3" fill="#6b7f6b" stroke="#4a5a4a" stroke-width="0.8"/>
<!-- MOLLE laser cut -->
<g fill="#2a332a" opacity="0.9">
<rect x="130" y="200" width="40" height="4" rx="1"/><rect x="130" y="208" width="40" height="4" rx="1"/><rect x="130" y="216" width="40" height="4" rx="1"/><rect x="130" y="224" width="40" height="4" rx="1"/>
</g>
<!-- shoulder pauldrons -->
<path d="M118 132 Q108 142 112 162 L124 158 L124 134 Z" fill="#4a5a4a" stroke="#2f3a2f" stroke-width="1"/>
<path d="M182 132 Q192 142 188 162 L176 158 L176 134 Z" fill="#4a5a4a" stroke="#2f3a2f" stroke-width="1"/>
<!-- collar / neck guard -->
<path d="M132 124 Q150 138 168 124 L166 132 Q150 146 134 132 Z" fill="#2f3a2f"/>
<!-- belt / cummerbund -->
<rect x="116" y="236" width="68" height="16" rx="3" fill="#2f3a2f" stroke="#1a1e1a" stroke-width="1"/>
</g>
<!-- WEAPONS (behind hands, in front of torso) -->
<g id="g-pike" opacity="0">
<!-- 5.5m ash pike vertical on right side -->
<line x1="188" y1="18" x2="188" y2="468" stroke="#8a6a3a" stroke-width="5" stroke-linecap="round"/>
<line x1="188" y1="18" x2="188" y2="48" stroke="#c9c0a8" stroke-width="1" opacity="0.3"/>
<!-- steel pike head -->
<path d="M188 8 L182 28 L188 24 L194 28 Z" fill="#9aa0a6" stroke="#5a626a" stroke-width="1"/>
<!-- langets -->
<rect x="186.5" y="28" width="3" height="22" fill="#5a626a"/>
</g>
<g id="g-lebel" opacity="0">
<!-- Lebel rifle diagonal across chest -->
<g transform="rotate(-12 150 220)">
<rect x="92" y="214" width="116" height="8" rx="2" fill="#4a3720" stroke="#2a2115" stroke-width="1"/>
<rect x="92" y="216" width="70" height="4" fill="#2f3338"/>
<rect x="162" y="212" width="28" height="12" rx="1" fill="#2f3338" stroke="#1e2226" stroke-width="0.8"/>
<rect x="188" y="214" width="20" height="6" fill="#5a626a"/>
<!-- bayonet cruciform -->
<line x1="208" y1="217" x2="236" y2="217" stroke="#9aa0a6" stroke-width="2.5"/>
<polygon points="236,217 230,214 230,220" fill="#9aa0a6"/>
</g>
</g>
<g id="g-futureRifle" opacity="0">
<!-- caseless carbine, bullpup-ish -->
<g transform="rotate(-10 150 224)">
<path d="M98 218 L190 218 L190 228 L98 228 Z" fill="#2b2f2b" stroke="#1a1e1a" stroke-width="1"/>
<rect x="108" y="214" width="42" height="6" rx="1" fill="#3a4a3a" stroke="#2a332a" stroke-width="0.8"/>
<rect x="150" y="210" width="28" height="10" rx="2" fill="#1a1e1a"/>
<rect x="158" y="206" width="18" height="6" rx="1" fill="#5a6b5a" stroke="#3a4a3a" stroke-width="0.8"/>
<!-- optic -->
<rect x="136" y="208" width="22" height="6" rx="1" fill="#0f1410" stroke="#5a6b5a" stroke-width="0.8"/>
<rect x="138" y="209.5" width="18" height="3" rx="1" fill="#6b9a8a" opacity="0.9"/>
<!-- barrel -->
<line x1="190" y1="223" x2="218" y2="223" stroke="#1a1e1a" stroke-width="5" stroke-linecap="round"/>
<line x1="218" y1="223" x2="228" y2="223" stroke="#5a626a" stroke-width="3"/>
</g>
</g>
<!-- ARMS (sleeves) — single rig, colour lerps -->
<g id="arms" stroke-linecap="round" stroke-linejoin="round">
<line id="armL1" x1="118" y1="138" x2="145" y2="150" stroke="#c9b090" stroke-width="14"/>
<line id="armL2" x1="145" y1="150" x2="185" y2="165" stroke="#c9b090" stroke-width="12"/>
<line id="armR1" x1="182" y1="138" x2="150" y2="180" stroke="#c9b090" stroke-width="14"/>
<line id="armR2" x1="150" y1="180" x2="185" y2="210" stroke="#c9b090" stroke-width="12"/>
<!-- hands -->
<circle id="handL" cx="185" cy="165" r="7" fill="#e8c4a8" stroke="#c9a88a" stroke-width="1"/>
<circle id="handR" cx="185" cy="210" r="7" fill="#e8c4a8" stroke="#c9a88a" stroke-width="1"/>
</g>
<!-- HELMETS (topmost) -->
<g id="g-pot" opacity="0">
<!-- pikeman's pot, blackened, with flat comb and cheek pieces -->
<path d="M124 58 Q150 18 176 58 L172 68 Q150 62 128 68 Z" fill="#2f3338" stroke="#1e2226" stroke-width="1.2"/>
<path d="M128 58 Q150 28 172 58 Q172 78 150 84 Q128 78 128 58" fill="#3a3f45" stroke="#1e2226" stroke-width="1.2"/>
<!-- comb -->
<path d="M150 28 L150 58" stroke="#1e2226" stroke-width="2" opacity="0.9"/>
<path d="M142 34 Q150 30 158 34" stroke="#5a626a" stroke-width="1" fill="none" opacity="0.7"/>
<!-- brim -->
<ellipse cx="150" cy="68" rx="28" ry="6" fill="#2f3338" stroke="#1e2226" stroke-width="1"/>
<!-- cheek pieces -->
<path d="M128 68 Q122 78 126 88 L136 84 Q132 76 132 68" fill="#3a3f45" stroke="#1e2226" stroke-width="1"/>
<path d="M172 68 Q178 78 174 88 L164 84 Q168 76 168 68" fill="#3a3f45" stroke="#1e2226" stroke-width="1"/>
<!-- rivets -->
<circle cx="138" cy="62" r="1.2" fill="#9aa0a6"/><circle cx="162" cy="62" r="1.2" fill="#9aa0a6"/>
</g>
<g id="g-adrian" opacity="0">
<!-- Adrian Mle 1915 horizon-blue -->
<path d="M126 62 Q150 22 174 62 L172 70 Q150 66 128 70 Z" fill="#6b7f94" stroke="#4a5a6a" stroke-width="1"/>
<ellipse cx="150" cy="62" rx="26" ry="22" fill="#8da8c0" stroke="#4a5a6a" stroke-width="1.2"/>
<!-- comb ventilator (separate riveted piece) -->
<path d="M142 28 Q150 24 158 28 L156 62 L144 62 Z" fill="#7a8fa3" stroke="#4a5a6a" stroke-width="1"/>
<line x1="150" y1="28" x2="150" y2="62" stroke="#4a5a6a" stroke-width="0.8" opacity="0.6"/>
<!-- front badge RF -->
<ellipse cx="150" cy="52" rx="7" ry="8" fill="#8a7a3a" stroke="#5a4a1a" stroke-width="0.8"/>
<text x="150" y="55" text-anchor="middle" font-size="6" font-family="serif" fill="#3a2a0a">RF</text>
<!-- chinstrap -->
<path d="M128 70 Q150 88 172 70" stroke="#4a3a2a" stroke-width="1.4" fill="none"/>
</g>
<g id="g-futureHelm" opacity="0">
<!-- integrated ballistic helmet -->
<path d="M128 58 Q150 20 172 58 L172 72 Q150 84 128 72 Z" fill="#3a4a3a" stroke="#2a332a" stroke-width="1.2"/>
<path d="M128 58 Q150 32 172 58 Q172 68 150 74 Q128 68 128 58" fill="#4a5a4a" stroke="#2f3a2f" stroke-width="1"/>
<!-- visor photochromic -->
<path d="M130 62 Q150 72 170 62 L168 78 Q150 88 132 78 Z" fill="#2a3a4a" stroke="#1a2a3a" stroke-width="1" opacity="0.92"/>
<path d="M132 66 Q150 74 168 66" stroke="#6b9a8a" stroke-width="1.2" opacity="0.7" fill="none"/>
<!-- mandible guard -->
<path d="M132 78 Q150 92 168 78 L166 86 Q150 98 134 86 Z" fill="#3a4a3a" stroke="#2a332a" stroke-width="1"/>
<!-- sensor rail -->
<rect x="144" y="30" width="12" height="6" rx="1" fill="#1a1e1a" stroke="#5a6b5a" stroke-width="0.8"/>
<circle cx="150" cy="33" r="1.5" fill="#6b9a8a"/>
<!-- side rail -->
<rect x="170" y="56" width="6" height="14" rx="1" fill="#2a332a"/>
</g>
<!-- outline for figure to keep crisp -->
<rect x="0.5" y="0.5" width="299" height="519" rx="6" fill="none" stroke="#e6ddd0" stroke-width="1" opacity="0.0"/>
</svg>
</div>
<div class="controls">
<input id="slider" type="range" min="0" max="200" value="0" step="1" aria-label="Era slider">
<div class="ticks"><span>1645</span><span>1916</span><span>2085</span></div>
<div id="label" class="label"></div>
<div class="hint">Drag slowly — the same body, re-equipped. Feet and shoulders never move.</div>
</div>
</div>
<script>
const slider = document.getElementById('slider');
const label = document.getElementById('label');
// groups
const gTassets = document.getElementById('g-tassets');
const gPuttees = document.getElementById('g-puttees');
const gFutureLeg = document.getElementById('g-futureLeg');
const gBreast = document.getElementById('g-breastplate');
const gCoat = document.getElementById('g-greatcoat');
const gCarrier = document.getElementById('g-plateCarrier');
const gPot = document.getElementById('g-pot');
const gAdrian = document.getElementById('g-adrian');
const gFutureHelm = document.getElementById('g-futureHelm');
const gPike = document.getElementById('g-pike');
const gLebel = document.getElementById('g-lebel');
const gFutureRifle = document.getElementById('g-futureRifle');
const armL1 = document.getElementById('armL1');
const armL2 = document.getElementById('armL2');
const armR1 = document.getElementById('armR1');
const armR2 = document.getElementById('armR2');
const handL = document.getElementById('handL');
const handR = document.getElementById('handR');
function lerp(a,b,t){return a*(1-t)+b*t}
function lerpColor(c1,c2,t){
const r1=parseInt(c1.slice(1,3),16), g1=parseInt(c1.slice(3,5),16), b1=parseInt(c1.slice(5,7),16);
const r2=parseInt(c2.slice(1,3),16), g2=parseInt(c2.slice(3,5),16), b2=parseInt(c2.slice(5,7),16);
const r=Math.round(lerp(r1,r2,t)), g=Math.round(lerp(g1,g2,t)), b=Math.round(lerp(b1,b2,t));
return 'rgb('+r+','+g+','+b+')';
}
// era definitions for arms
const poses = [
// 1645 pike vertical on right
{ Lelbow:{x:144,y:152}, Lhand:{x:186,y:166}, Relbow:{x:152,y:182}, Rhand:{x:186,y:212}, sleeve:'#c9b090' },
// 1916 Lebel across chest
{ Lelbow:{x:116,y:176}, Lhand:{x:128,y:218}, Relbow:{x:184,y:186}, Rhand:{x:170,y:228}, sleeve:'#8da8c0' },
// 2085 carbine
{ Lelbow:{x:118,y:178}, Lhand:{x:132,y:222}, Relbow:{x:186,y:188}, Rhand:{x:176,y:232}, sleeve:'#5a6b5a' }
];
const SL={x:118,y:138}, SR={x:182,y:138};
function update(){
const v = parseInt(slider.value,10);
let a,b,t;
if(v<=100){ a=0; b=1; t=v/100; } else { a=1; b=2; t=(v-100)/100; }
// interpolate arms
const pa=poses[a], pb=poses[b];
const Le={x:lerp(pa.Lelbow.x,pb.Lelbow.x,t), y:lerp(pa.Lelbow.y,pb.Lelbow.y,t)};
const Lh={x:lerp(pa.Lhand.x,pb.Lhand.x,t), y:lerp(pa.Lhand.y,pb.Lhand.y,t)};
const Re={x:lerp(pa.Relbow.x,pb.Relbow.x,t), y:lerp(pa.Relbow.y,pb.Relbow.y,t)};
const Rh={x:lerp(pa.Rhand.x,pb.Rhand.x,t), y:lerp(pa.Rhand.y,pb.Rhand.y,t)};
armL1.setAttribute('x2', Le.x); armL1.setAttribute('y2', Le.y);
armL2.setAttribute('x1', Le.x); armL2.setAttribute('y1', Le.y); armL2.setAttribute('x2', Lh.x); armL2.setAttribute('y2', Lh.y);
armR1.setAttribute('x2', Re.x); armR1.setAttribute('y2', Re.y);
armR2.setAttribute('x1', Re.x); armR2.setAttribute('y1', Re.y); armR2.setAttribute('x2', Rh.x); armR2.setAttribute('y2', Rh.y);
handL.setAttribute('cx', Lh.x); handL.setAttribute('cy', Lh.y);
handR.setAttribute('cx', Rh.x); handR.setAttribute('cy', Rh.y);
const col = lerpColor(pa.sleeve, pb.sleeve, t);
armL1.setAttribute('stroke', col); armL2.setAttribute('stroke', col); armR1.setAttribute('stroke', col); armR2.setAttribute('stroke', col);
// opacities: cross-fade between a and b, third is 0
const op = [0,0,0];
op[a]=1-t; op[b]=t;
// map to groups
gTassets.style.opacity = op[0];
gBreast.style.opacity = op[0];
gPot.style.opacity = op[0];
gPike.style.opacity = op[0];
gPuttees.style.opacity = op[1];
gCoat.style.opacity = op[1];
gAdrian.style.opacity = op[1];
gLebel.style.opacity = op[1];
gFutureLeg.style.opacity = op[2];
gCarrier.style.opacity = op[2];
gFutureHelm.style.opacity = op[2];
gFutureRifle.style.opacity = op[2];
// label — pure function of v
let html='';
if(v===0){
html='<div class="era">1645 — Naseby, England</div><div class="sub"><b>Armour:</b> Munition pikeman’s half-armour — blackened back-and-breast with three articulated tassets over a buff coat, pikeman’s pot with cheek-pieces.<br><b>Weapon:</b> 5.5 m ash pike with steel head and langets.</div><div class="mat">Material: hammered iron (blackened), leather buff coat, ash wood.</div>';
} else if(v===100){
html='<div class="era">1916 — Verdun, France</div><div class="sub"><b>Armour:</b> Adrian Mle 1915 steel helmet (0.7 mm steel, riveted comb) over horizon-blue wool greatcoat — no body armour.<br><b>Weapon:</b> Lebel Mle 1886/93 8×50 mmR rifle, cruciform bayonet.</div><div class="mat">Material: pressed steel, wool serge, walnut, leather.</div>';
} else if(v===200){
html='<div class="era">2085 — Rhine Floodplain, Germany (UEDF)</div><div class="sub"><b>Armour:</b> Modular plate carrier — UHMWPE/ceramic plates in laser-cut carrier, composite pauldrons, integrated ballistic helmet with photochromic visor and mandible, soft exoskeleton cuffs.<br><b>Weapon:</b> 6.5 mm caseless carbine with integrated optic.</div><div class="mat">Material: UHMWPE/ceramic composite, aramid, polycarbonate, aluminium.</div>';
} else if(v<100){
const pct=Math.round(t*100);
html='<div class="era">Between 1645 — Naseby and 1916 — Verdun — '+pct+'% toward 1916</div><div class="sub">Transitioning: blackened breast & tassets fading to horizon-blue greatcoat; pikeman’s pot → Adrian helmet; ash pike → Lebel rifle. Arms interpolating between pike-grip and rifle-carry.</div><div class="mat">Slider at '+v+' / 200 — pure function, reversible.</div>';
} else {
const pct=Math.round(t*100);
html='<div class="era">Between 1916 — Verdun and 2085 — Rhine — '+pct+'% toward 2085</div><div class="sub">Transitioning: wool greatcoat & Adrian → composite plate carrier & visored helmet; Lebel → caseless carbine. Cut and colour of sleeves lerping, plates cross-fading.</div><div class="mat">Slider at '+v+' / 200 — pure function, reversible.</div>';
}
label.innerHTML=html;
}
slider.addEventListener('input', update);
update();
</script>
</body>
</html>
2085 is the shakiest, because it is speculative and I had to invent without a surviving object to copy. The temptation was to give it a full powered exoskeleton, glowing seams, and a visor that is really a screen — the video-game trope the brief warns against — and to make the plates look like moulded sci-fi armour rather than a fabric carrier holding flat composite plates. I kept the carrier deliberately boring (laser-cut MOLLE, flat plates, matte olive) and the helmet as an evolution of the Adrian/pot (dome + brim + visor + mandible) for that reason, but the caseless carbine is still a guess: caseless ammunition has been promised since the 1980s and may still be brass-cased in 2085. The 1645 munition armour is also simplified at this scale — a real pikeman’s pot has a more complex two-piece skull and the tassets would have more lames and leather straps — but the silhouette, blackening, and riveted construction are correct; I omitted the backplate and gorget for readability, which is the one knowing compromise.