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.
1526, Wittenberg, Saxony — A cuirassier's three-quarter harness of hardened leather (buff coat) over a mail shirt, with a single steel breastplate, a morion helmet with a single comb and cheek-pieces, and a straight-bladed estoc (a thrusting sword) hung from a baldric. Detail a non-specialist gets wrong: the breastplate is a single piece, not a two-piece "front and back" — the back is a separate skirt of mail and leather, not a matching plate.
1916, Somme, France — A Brodie helmet (Mark I) with a canvas cover, a wool tunic, puttees, and a Webley Mk VI revolver in a leather holster on the right hip, with a trench club hanging from the belt. Detail a non-specialist gets wrong: the Brodie helmet is not a "tin hat" — it has a pronounced brim and a fixed crest, and the canvas cover is tied under the chin, not just draped.
2089, Lanzarote, Canary Islands — A modular plate-weave exosuit: a ceramic-composite chest plate with a flexible Kevlar-nomex underlayer, a ballistic helmet with a visor slit and a rear-mounted comms node, articulated knee and elbow guards of the same ceramic composite, and a pulse carbine (a directed-energy small arm) slung across the back, with a sidearm holster on the left hip. Detail a non-specialist gets wrong: the helmet is not a "space helmet" — it has a fixed brim and a visor that is a single piece of transparent armour, not a bubble; the suit is not a "mech" — it is worn, not piloted, and the articulation is at the joints, not the torso.
The figure is a single SVG with a fixed viewBox and a standing pose: feet planted, shoulders level, head upright, arms hanging. The body is drawn once as a set of anchor points — shoulders (two), chest (one), waist (one), hips (two), knees (two), shins (two), feet (two), neck (one), head (one) — and each era's armour is a set of SVG elements that mount to those anchors by absolute coordinates computed from the anchors, not by eyeballing. The layer order is: body (skin, always visible) → underlayer (mail or fabric, era-dependent) → plate (breastplate, helmet, limb guards, era-dependent) → weapon (era-dependent) → label (HTML, below the SVG). At a slider position between two eras, the armour layers cross-fade by opacity interpolated linearly against the slider value, but the anchor points never move, the body never rescales, and the weapons fade in/out without shifting the figure's silhouette. The transition is a pure function of the slider: same slider value always yields the same drawing, and dragging back yields pixel-for-pixel the same drawing.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Armoury Slider — Three Eras, One Figure</title>
<style>
:root {
--bg: #1a1a1a;
--panel: #2a2a2a;
--text: #d4d4d4;
--accent: #c9a227;
--label-bg: #222;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
html, body {
background: var(--bg);
color: var(--text);
font-family: "Palatino Linotype", "Book Antiqua", Palatino, Georgia, serif;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
padding: 1.5rem 1rem;
}
h1 {
font-size: 1.1rem;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--accent);
margin-bottom: 0.25rem;
font-weight: 400;
}
.subtitle {
font-size: 0.8rem;
color: #888;
margin-bottom: 1.2rem;
font-style: italic;
}
.exhibit {
width: 100%;
max-width: 720px;
background: var(--panel);
border: 1px solid #3a3a3a;
padding: 1.2rem;
border-radius: 2px;
}
.figure-wrap {
position: relative;
width: 100%;
aspect-ratio: 3 / 4;
background: #111;
border: 1px solid #333;
margin-bottom: 1rem;
overflow: hidden;
}
.figure-wrap svg {
display: block;
width: 100%;
height: 100%;
}
.slider-row {
display: flex;
align-items: center;
gap: 0.6rem;
margin-bottom: 0.8rem;
}
.era-tag {
font-size: 0.7rem;
text-transform: uppercase;
letter-spacing: 0.1em;
color: #666;
min-width: 4.2rem;
text-align: right;
}
.era-tag.active { color: var(--accent); }
input[type="range"] {
-webkit-appearance: none;
appearance: none;
flex: 1;
height: 4px;
background: #444;
border-radius: 2px;
outline: none;
cursor: pointer;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 18px;
height: 18px;
background: var(--accent);
border-radius: 50%;
border: 2px solid #1a1a1a;
cursor: pointer;
box-shadow: 0 0 0 1px #c9a227;
}
input[type="range"]::-moz-range-thumb {
width: 18px;
height: 18px;
background: var(--accent);
border-radius: 50%;
border: 2px solid #1a1a1a;
cursor: pointer;
}
.era-marks {
display: flex;
justify-content: space-between;
padding: 0 0.2rem;
margin-bottom: 0.6rem;
font-size: 0.6rem;
color: #555;
text-transform: uppercase;
letter-spacing: 0.08em;
}
.label {
background: var(--label-bg);
border-left: 3px solid var(--accent);
padding: 0.7rem 0.9rem;
font-size: 0.85rem;
line-height: 1.5;
min-height: 5rem;
}
.label .year {
font-size: 1.1rem;
font-weight: 700;
color: var(--accent);
display: block;
margin-bottom: 0.15rem;
}
.label .place {
font-style: italic;
color: #aaa;
display: block;
margin-bottom: 0.4rem;
}
.label .body-text {
color: #ccc;
}
.label .body-text strong {
color: #e0e0e0;
font-weight: 600;
}
.label .transition {
color: #888;
font-style: italic;
}
.footnote {
margin-top: 0.8rem;
font-size: 0.7rem;
color: #555;
text-align: center;
max-width: 720px;
line-height: 1.4;
}
</style>
</head>
<body>
<h1>Armoury Slider</h1>
<p class="subtitle">One figure, three eras. Drag to re-equip.</p>
<div class="exhibit">
<div class="figure-wrap" id="figureWrap">
<svg id="figure" viewBox="0 0 300 400" preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg">
<!-- ===== BODY (fixed, never changes) ===== -->
<g id="body">
<!-- legs -->
<path d="M128 280 L124 340 L122 380 L132 380 L134 340 L140 280 Z" fill="#c9a88b" stroke="#8a6a4a" stroke-width="0.8"/>
<path d="M160 280 L164 340 L166 380 L176 380 L174 340 L168 280 Z" fill="#c9a88b" stroke="#8a6a4a" stroke-width="0.8"/>
<!-- feet -->
<path d="M120 378 L122 384 L134 384 L136 378 Z" fill="#3a2a1a" stroke="#1a1a1a" stroke-width="0.6"/>
<path d="M164 378 L166 384 L178 384 L180 378 Z" fill="#3a2a1a" stroke="#1a1a1a" stroke-width="0.6"/>
<!-- torso -->
<path d="M120 180 L118 240 L120 280 L180 280 L182 240 L180 180 Z" fill="#c9a88b" stroke="#8a6a4a" stroke-width="0.8"/>
<!-- shoulders -->
<path d="M108 178 L118 180 L118 196 L108 194 Z" fill="#c9a88b" stroke="#8a6a4a" stroke-width="0.8"/>
<path d="M192 178 L182 180 L182 196 L192 194 Z" fill="#c9a88b" stroke="#8a6a4a" stroke-width="0.8"/>
<!-- arms -->
<path d="M112 190 L108 230 L106 260 L114 260 L116 230 L120 192 Z" fill="#c9a88b" stroke="#8a6a4a" stroke-width="0.8"/>
<path d="M188 190 L192 230 L194 260 L186 260 L184 230 L180 192 Z" fill="#c9a88b" stroke="#8a6a4a" stroke-width="0.8"/>
<!-- hands -->
<ellipse cx="110" cy="262" rx="5" ry="6" fill="#c9a88b" stroke="#8a6a4a" stroke-width="0.6"/>
<ellipse cx="190" cy="262" rx="5" ry="6" fill="#c9a88b" stroke="#8a6a4a" stroke-width="0.6"/>
<!-- neck -->
<path d="M138 170 L138 180 L162 180 L162 170 Z" fill="#c9a88b" stroke="#8a6a4a" stroke-width="0.6"/>
<!-- head -->
<ellipse cx="150" cy="155" rx="18" ry="22" fill="#c9a88b" stroke="#8a6a4a" stroke-width="0.8"/>
<!-- face hint -->
<path d="M142 150 Q150 148 158 150" fill="none" stroke="#8a6a4a" stroke-width="0.6"/>
<circle cx="145" cy="152" r="1" fill="#5a3a2a"/>
<circle cx="155" cy="152" r="1" fill="#5a3a2a"/>
</g>
<!-- ===== UNDERLAYER (cross-fades) ===== -->
<g id="underlayer">
<!-- Era 1: mail shirt + buff coat hint -->
<g id="under-era1" opacity="0">
<path d="M118 196 L116 240 L118 280 L182 280 L184 240 L182 196 Z" fill="#6a6a6a" stroke="#3a3a3a" stroke-width="0.5"/>
<!-- mail texture: small rings suggestion -->
<g fill="none" stroke="#4a4a4a" stroke-width="0.4">
<circle cx="130" cy="210" r="2"/>
<circle cx="140" cy="210" r="2"/>
<circle cx="150" cy="210" r="2"/>
<circle cx="160" cy="210" r="2"/>
<circle cx="130" cy="220" r="2"/>
<circle cx="140" cy="220" r="2"/>
<circle cx="150" cy="220" r="2"/>
<circle cx="160" cy="220" r="2"/>
<circle cx="130" cy="230" r="2"/>
<circle cx="140" cy="230" r="2"/>
<circle cx="150" cy="230" r="2"/>
<circle cx="160" cy="230" r="2"/>
<circle cx="130" cy="240" r="2"/>
<circle cx="140" cy="240" r="2"/>
<circle cx="150" cy="240" r="2"/>
<circle cx="160" cy="240" r="2"/>
<circle cx="130" cy="250" r="2"/>
<circle cx="140" cy="250" r="2"/>
<circle cx="150" cy="250" r="2"/>
<circle cx="160" cy="250" r="2"/>
<circle cx="130" cy="260" r="2"/>
<circle cx="140" cy="260" r="2"/>
<circle cx="150" cy="260" r="2"/>
<circle cx="160" cy="260" r="2"/>
<circle cx="130" cy="270" r="2"/>
<circle cx="140" cy="270" r="2"/>
<circle cx="150" cy="270" r="2"/>
<circle cx="160" cy="270" r="2"/>
</g>
<!-- buff coat over mail, sleeves -->
<path d="M112 192 L108 230 L106 260 L114 260 L116 230 L120 192 Z" fill="#8a6a3a" stroke="#5a4a2a" stroke-width="0.5" opacity="0.7"/>
<path d="M188 192 L192 230 L194 260 L186 260 L184 230 L180 192 Z" fill="#8a6a3a" stroke="#5a4a2a" stroke-width="0.5" opacity="0.7"/>
</g>
<!-- Era 2: wool tunic, puttees -->
<g id="under-era2" opacity="0">
<path d="M118 196 L116 240 L118 280 L182 280 L184 240 L182 196 Z" fill="#4a3a2a" stroke="#2a1a0a" stroke-width="0.5"/>
<!-- tunic collar -->
<path d="M138 196 L150 200 L162 196 L162 192 L150 196 L138 192 Z" fill="#3a2a1a" stroke="#2a1a0a" stroke-width="0.4"/>
<!-- puttees on legs -->
<path d="M124 320 L122 340 L122 360 L132 360 L134 340 L136 320 Z" fill="#5a4a3a" stroke="#3a2a1a" stroke-width="0.5"/>
<path d="M164 320 L166 340 L166 360 L176 360 L174 340 L172 320 Z" fill="#5a4a3a" stroke="#3a2a1a" stroke-width="0.5"/>
<!-- puttee wrap lines -->
<g stroke="#3a2a1a" stroke-width="0.3" fill="none">
<path d="M124 325 L136 325"/>
<path d="M124 332 L136 332"/>
<path d="M124 339 L136 339"/>
<path d="M124 346 L136 346"/>
<path d="M124 353 L136 353"/>
<path d="M164 325 L176 325"/>
<path d="M164 332 L176 332"/>
<path d="M164 339 L176 339"/>
<path d="M164 346 L176 346"/>
<path d="M164 353 L176 353"/>
</g>
<!-- tunic sleeves -->
<path d="M112 192 L108 230 L106 260 L114 260 L116 230 L120 192 Z" fill="#4a3a2a" stroke="#2a1a0a" stroke-width="0.5"/>
<path d="M188 192 L192 230 L194 260 L186 260 L184 230 L180 192 Z" fill="#4a3a2a" stroke="#2a1a0a" stroke-width="0.5"/>
</g>
<!-- Era 3: Kevlar-nomex underlayer, flexible -->
<g id="under-era3" opacity="0">
<path d="M118 196 L116 240 L118 280 L182 280 L184 240 L182 196 Z" fill="#2a2a2a" stroke="#1a1a1a" stroke-width="0.5"/>
<!-- subtle weave texture -->
<g stroke="#3a3a3a" stroke-width="0.3" fill="none" opacity="0.6">
<path d="M120 200 L180 200"/>
<path d="M120 210 L180 210"/>
<path d="M120 220 L180 220"/>
<path d="M120 230 L180 230"/>
<path d="M120 240 L180 240"/>
<path d="M120 250 L180 250"/>
<path d="M120 260 L180 260"/>
<path d="M120 270 L180 270"/>
<path d="M120 280 L180 280"/>
</g>
<!-- sleeve underlayer -->
<path d="M112 192 L108 230 L106 260 L114 260 L116 230 L120 192 Z" fill="#2a2a2a" stroke="#1a1a1a" stroke-width="0.5"/>
<path d="M188 192 L192 230 L194 260 L186 260 L184 230 L180 192 Z" fill="#2a2a2a" stroke="#1a1a1a" stroke-width="0.5"/>
<!-- leg underlayer -->
<path d="M124 300 L122 340 L122 360 L132 360 L134 340 L136 300 Z" fill="#2a2a2a" stroke="#1a1a1a" stroke-width="0.5"/>
<path d="M164 300 L166 340 L166 360 L176 360 L174 340 L172 300 Z" fill="#2a2a2a" stroke="#1a1a1a" stroke-width="0.5"/>
</g>
</g>
<!-- ===== PLATE (cross-fades) ===== -->
<g id="plate">
<!-- Era 1: breastplate, morion, limb plates -->
<g id="plate-era1" opacity="0">
<!-- breastplate (single piece, cuirass) -->
<path d="M122 196 L120 210 L118 230 L118 250 L122 265 L130 272 L150 275 L170 272 L178 265 L182 250 L182 230 L180 210 L178 196 Z" fill="#6a6a6a" stroke="#3a3a3a" stroke-width="1"/>
<!-- breastplate centre ridge -->
<path d="M150 196 L150 275" fill="none" stroke="#4a4a4a" stroke-width="0.8"/>
<!-- breastplate fluting -->
<g stroke="#5a5a5a" stroke-width="0.4" fill="none">
<path d="M130 200 L130 270"/>
<path d="M140 200 L140 270"/>
<path d="M160 200 L160 270"/>
<path d="M170 200 L170 270"/>
</g>
<!-- fauld (waist skirt of plate) -->
<path d="M118 265 L122 272 L130 275 L150 278 L170 275 L178 272 L182 265 L182 275 L178 280 L170 282 L150 284 L130 282 L122 280 L118 275 Z" fill="#6a6a6a" stroke="#3a3a3a" stroke-width="0.8"/>
<!-- morion helmet -->
<path d="M132 150 L132 130 L140 118 L150 112 L160 118 L168 130 L168 150 L160 155 L150 158 L140 155 Z" fill="#6a6a6a" stroke="#3a3a3a" stroke-width="1"/>
<!-- comb -->
<path d="M150 112 L150 130 L148 140 L152 140 L150 130" fill="#5a5a5a" stroke="#3a3a3a" stroke-width="0.6"/>
<!-- cheek pieces -->
<path d="M132 150 L130 158 L132 162 L138 160 L138 152 Z" fill="#6a6a6a" stroke="#3a3a3a" stroke-width="0.6"/>
<path d="M168 150 L170 158 L168 162 L162 160 L162 152 Z" fill="#6a6a6a" stroke="#3a3a3a" stroke-width="0.6"/>
<!-- visor slit -->
<path d="M140 148 L160 148" fill="none" stroke="#2a2a2a" stroke-width="1.2"/>
<!-- limb plates: couters (elbow) and poleyns (knee) -->
<!-- left couter -->
<path d="M108 232 L104 238 L104 248 L110 250 L114 246 L114 236 Z" fill="#6a6a6a" stroke="#3a3a3a" stroke-width="0.8"/>
<!-- right couter -->
<path d="M192 232 L196 238 L196 248 L190 250 L186 246 L186 236 Z" fill="#6a6a6a" stroke="#3a3a3a" stroke-width="0.8"/>
<!-- left poleyn -->
<path d="M124 300 L120 306 L120 316 L126 320 L132 316 L132 306 Z" fill="#6a6a6a" stroke="#3a3a3a" stroke-width="0.8"/>
<!-- right poleyn -->
<path d="M176 300 L180 306 L180 316 L174 320 L168 316 L168 306 Z" fill="#6a6a6a" stroke="#3a3a3a" stroke-width="0.8"/>
<!-- greave hints (lower leg plate) -->
<path d="M122 320 L120 340 L120 360 L132 360 L134 340 L136 320 Z" fill="#6a6a6a" stroke="#3a3a3a" stroke-width="0.6" opacity="0.6"/>
<path d="M178 320 L180 340 L180 360 L168 360 L166 340 L164 320 Z" fill="#6a6a6a" stroke="#3a3a3a" stroke-width="0.6" opacity="0.6"/>
</g>
<!-- Era 2: Brodie helmet, no plate -->
<g id="plate-era2" opacity="0">
<!-- Brodie helmet Mark I -->
<path d="M132 150 L130 138 L134 124 L142 116 L150 112 L158 116 L166 124 L170 138 L168 150 L162 155 L150 158 L138 155 Z" fill="#7a7a7a" stroke="#4a4a4a" stroke-width="1"/>
<!-- helmet brim -->
<path d="M130 150 L132 152 L168 152 L170 150 L168 155 L150 158 L132 155 Z" fill="#6a6a6a" stroke="#4a4a4a" stroke-width="0.6"/>
<!-- crest (fixed, raised ridge) -->
<path d="M150 112 L150 130 L148 138 L152 138 L150 130" fill="#6a6a6a" stroke="#4a4a4a" stroke-width="0.6"/>
<!-- canvas cover (tied under chin) -->
<path d="M134 150 L132 156 L134 162 L140 164 L150 165 L160 164 L166 162 L168 156 L166 150 L160 152 L150 153 L140 152 Z" fill="#5a5a4a" stroke="#3a3a2a" stroke-width="0.5" opacity="0.8"/>
<!-- chin tie -->
<path d="M140 164 L142 168 L148 168 L150 165" fill="none" stroke="#3a3a2a" stroke-width="0.5"/>
<path d="M160 164 L158 168 L152 168 L150 165" fill="none" stroke="#3a3a2a" stroke-width="0.5"/>
<!-- helmet badge hint (crown) -->
<circle cx="150" cy="135" r="3" fill="none" stroke="#4a4a4a" stroke-width="0.5"/>
</g>
<!-- Era 3: ceramic composite plate, helmet with visor -->
<g id="plate-era3" opacity="0">
<!-- chest plate (ceramic composite, modular) -->
<path d="M120 196 L118 210 L116 230 L116 250 L120 265 L128 272 L150 275 L172 272 L180 265 L184 250 L184 230 L182 210 L180 196 Z" fill="#4a4a4a" stroke="#2a2a2a" stroke-width="1"/>
<!-- plate segmentation lines (modular) -->
<g stroke="#3a3a3a" stroke-width="0.5" fill="none">
<path d="M120 210 L180 210"/>
<path d="M118 230 L182 230"/>
<path d="M118 250 L182 250"/>
</g>
<!-- ceramic texture (subtle speckle) -->
<g fill="#5a5a5a" opacity="0.4">
<circle cx="135" cy="215" r="0.8"/>
<circle cx="145" cy="220" r="0.8"/>
<circle cx="155" cy="215" r="0.8"/>
<circle cx="165" cy="220" r="0.8"/>
<circle cx="135" cy="235" r="0.8"/>
<circle cx="145" cy="240" r="0.8"/>
<circle cx="155" cy="235" r="0.8"/>
<circle cx="165" cy="240" r="0.8"/>
<circle cx="135" cy="255" r="0.8"/>
<circle cx="145" cy="260" r="0.8"/>
<circle cx="155" cy="255" r="0.8"/>
<circle cx="165" cy="260" r="0.8"/>
</g>
<!-- shoulder guards (modular, articulated) -->
<path d="M108 178 L118 180 L118 196 L108 194 Z" fill="#4a4a4a" stroke="#2a2a2a" stroke-width="0.8"/>
<path d="M192 178 L182 180 L182 196 L192 194 Z" fill="#4a4a4a" stroke="#2a2a2a" stroke-width="0.8"/>
<!-- elbow guards -->
<path d="M108 232 L104 238 L104 248 L110 250 L114 246 L114 236 Z" fill="#4a4a4a" stroke="#2a2a2a" stroke-width="0.8"/>
<path d="M192 232 L196 238 L196 248 L190 250 L186 246 L186 236 Z" fill="#4a4a4a" stroke="#2a2a2a" stroke-width="0.8"/>
<!-- knee guards -->
<path d="M124 300 L120 306 L120 316 L126 320 L132 316 L132 306 Z" fill="#4a4a4a" stroke="#2a2a2a" stroke-width="0.8"/>
<path d="M176 300 L180 306 L180 316 L174 320 L168 316 L168 306 Z" fill="#4a4a4a" stroke="#2a2a2a" stroke-width="0.8"/>
<!-- shin guards -->
<path d="M122 320 L120 340 L120 360 L132 360 L134 340 L136 320 Z" fill="#4a4a4a" stroke="#2a2a2a" stroke-width="0.6"/>
<path d="M178 320 L180 340 L180 360 L168 360 L166 340 L164 320 Z" fill="#4a4a4a" stroke="#2a2a2a" stroke-width="0.6"/>
<!-- helmet (ballistic, with visor slit and comms node) -->
<path d="M132 150 L130 138 L134 124 L142 116 L150 112 L158 116 L166 124 L170 138 L168 150 L162 155 L150 158 L138 155 Z" fill="#3a3a3a" stroke="#1a1a1a" stroke-width="1"/>
<!-- visor slit (single piece transparent armour) -->
<path d="M138 148 L162 148 L162 152 L138 152 Z" fill="#1a1a1a" stroke="#0a0a0a" stroke-width="0.6"/>
<!-- visor reflection hint -->
<path d="M142 149 L148 149" fill="none" stroke="#4a4a4a" stroke-width="0.4"/>
<!-- comms node (rear-mounted, shown as a small box at back of helmet) -->
<rect x="166" y="138" width="4" height="6" fill="#2a2a2a" stroke="#1a1a1a" stroke-width="0.5"/>
<!-- helmet brim -->
<path d="M130 150 L132 152 L168 152 L170 150 L168 155 L150 158 L132 155 Z" fill="#2a2a2a" stroke="#1a1a1a" stroke-width="0.6"/>
<!-- helmet crest (aerodynamic ridge) -->
<path d="M150 112 L150 130 L148 138 L152 138 L150 130" fill="#3a3a3a" stroke="#1a1a1a" stroke-width="0.6"/>
</g>
</g>
<!-- ===== WEAPON (cross-fades) ===== -->
<g id="weapon">
<!-- Era 1: estoc (thrusting sword) on baldric -->
<g id="weapon-era1" opacity="0">
<!-- baldric across chest -->
<path d="M110 196 L120 200 L150 205 L180 200 L190 196" fill="none" stroke="#3a2a1a" stroke-width="1.5"/>
<!-- sword hilt at right hip -->
<rect x="180" y="250" width="6" height="4" fill="#3a2a1a" stroke="#1a1a1a" stroke-width="0.5"/>
<!-- sword blade (straight, thrusting) -->
<path d="M183 254 L183 200 L185 200 L185 254 Z" fill="#8a8a8a" stroke="#4a4a4a" stroke-width="0.5"/>
<!-- blade fuller hint -->
<path d="M184 250 L184 205" fill="none" stroke="#6a6a6a" stroke-width="0.3"/>
<!-- pommel -->
<circle cx="183" cy="256" r="2" fill="#3a2a1a" stroke="#1a1a1a" stroke-width="0.4"/>
</g>
<!-- Era 2: Webley Mk VI revolver + trench club -->
<g id="weapon-era2" opacity="0">
<!-- holster on right hip -->
<path d="M178 252 L182 252 L184 262 L180 264 L176 262 Z" fill="#3a2a1a" stroke="#1a1a1a" stroke-width="0.6"/>
<!-- revolver grip -->
<path d="M180 252 L182 252 L183 248 L181 246 Z" fill="#2a2a2a" stroke="#1a1a1a" stroke-width="0.5"/>
<!-- revolver barrel -->
<path d="M181 248 L181 240 L183 240 L183 248 Z" fill="#3a3a3a" stroke="#1a1a1a" stroke-width="0.5"/>
<!-- revolver cylinder hint -->
<circle cx="182" cy="244" r="2" fill="none" stroke="#1a1a1a" stroke-width="0.4"/>
<!-- trench club hanging from belt -->
<path d="M160 262 L158 270 L156 280 L160 282 L164 280 L162 270 L164 262 Z" fill="#3a2a1a" stroke="#1a1a1a" stroke-width="0.6"/>
<!-- club nails -->
<circle cx="158" cy="272" r="0.6" fill="#6a6a6a"/>
<circle cx="162" cy="274" r="0.6" fill="#6a6a6a"/>
<circle cx="160" cy="278" r="0.6" fill="#6a6a6a"/>
</g>
<!-- Era 3: pulse carbine slung + sidearm holster -->
<g id="weapon-era3" opacity="0">
<!-- carbine slung across back (shown as a shape over the shoulder) -->
<path d="M110 190 L115 195 L120 200 L130 205 L140 208 L150 210 L160 208 L170 205 L180 200 L185 195 L190 190" fill="none" stroke="#2a2a2a" stroke-width="2"/>
<!-- carbine body (barrel pointing down at right) -->
<path d="M185 195 L187 200 L189 210 L191 220 L193 230 L195 240 L197 250 L195 252 L193 250 L191 240 L189 230 L187 220 L185 210 L183 200 L181 195 Z" fill="#2a2a2a" stroke="#1a1a1a" stroke-width="0.6"/>
<!-- carbine energy cell hint -->
<rect x="188" y="215" width="6" height="3" fill="#3a3a3a" stroke="#1a1a1a" stroke-width="0.4"/>
<!-- sidearm holster on left hip -->
<path d="M118 252 L122 252 L124 262 L120 264 L116 262 Z" fill="#2a2a2a" stroke="#1a1a1a" stroke-width="0.6"/>
<!-- sidearm grip -->
<path d="M120 252 L122 252 L123 248 L121 246 Z" fill="#1a1a1a" stroke="#0a0a0a" stroke-width="0.5"/>
<!-- sidearm barrel -->
<path d="M121 248 L121 240 L123 240 L123 248 Z" fill="#2a2a2a" stroke="#1a1a1a" stroke-width="0.5"/>
</g>
</g>
</svg>
</div>
<div class="slider-row">
<span class="era-tag" id="tagLeft">1526</span>
<input type="range" id="slider" min="0" max="200" value="0" step="1" aria-label="Era slider">
<span class="era-tag" id="tagRight">2089</span>
</div>
<div class="era-marks">
<span>1526 · Wittenberg</span>
<span>1916 · Somme</span>
<span>2089 · Lanzarote</span>
</div>
<div class="label" id="label">
<span class="year" id="labelYear">1526</span>
<span class="place" id="labelPlace">Wittenberg, Saxony</span>
<span class="body-text" id="labelBody"></span>
</div>
</div>
<p class="footnote">Drag the slider. The figure is the same person in the same place; only the equipment changes. Between eras the drawing interpolates — no cut, no jump.</p>
<script>
(function () {
"use strict";
var slider = document.getElementById("slider");
var labelYear = document.getElementById("labelYear");
var labelPlace = document.getElementById("labelPlace");
var labelBody = document.getElementById("labelBody");
var tagLeft = document.getElementById("tagLeft");
var tagRight = document.getElementById("tagRight");
// Era data — fixed at author time, no runtime randomness.
var eras = [
{
year: "1526",
place: "Wittenberg, Saxony",
armour: "cuirassier's three-quarter harness",
material: "hardened leather (buff) over a mail shirt, with a single-piece steel breastplate, morion helmet with comb and cheek-pieces, and limb plates (couters, poleyns, greaves)",
weapon: "estoc — a straight-bladed thrusting sword hung from a baldric",
detail: "the breastplate is a single cuirass, not a two-piece front-and-back; the back is a mail-and-leather skirt, not a matching plate."
},
{
year: "1916",
place: "Somme, France",
armour: "Brodie helmet (Mark I) with canvas cover, wool tunic, puttees",
material: "steel helmet with a pronounced brim and fixed crest, canvas cover tied under the chin, wool and cotton clothing",
weapon: "Webley Mk VI revolver in a leather holster on the right hip, with a trench club hanging from the belt",
detail: "the Brodie is not a 'tin hat' — it has a fixed crest and a brim, and the canvas cover is tied, not draped."
},
{
year: "2089",
place: "Lanzarote, Canary Islands",
armour: "modular plate-weave exosuit — ceramic-composite chest plate with Kevlar-Nomex underlayer, ballistic helmet with visor slit and rear comms node, articulated knee and elbow guards",
material: "ceramic composite over a flexible ballistic underlayer, with articulated joint guards",
weapon: "pulse carbine (directed-energy small arm) slung across the back, with a sidearm holster on the left hip",
detail: "the helmet is not a 'space helmet' — it has a fixed brim and a single-piece visor of transparent armour, and the suit is worn, not piloted."
}
];
// Interpolation segments: 0..100 = era1→era2, 100..200 = era2→era3.
// At exactly 0, 100, 200 we are at an era. Between, we cross-fade.
function setOpacityForValue(v) {
// v in [0, 200]
var gUnder = document.getElementById("underlayer");
var gPlate = document.getElementById("plate");
var gWeapon = document.getElementById("weapon");
var e1u = document.getElementById("under-era1");
var e2u = document.getElementById("under-era2");
var e3u = document.getElementById("under-era3");
var e1p = document.getElementById("plate-era1");
var e2p = document.getElementById("plate-era2");
var e3p = document.getElementById("plate-era3");
var e1w = document.getElementById("weapon-era1");
var e2w = document.getElementById("weapon-era2");
var e3w = document.getElementById("weapon-era3");
// Reset
e1u.setAttribute("opacity", "0");
e2u.setAttribute("opacity", "0");
e3u.setAttribute("opacity", "0");
e1p.setAttribute("opacity", "0");
e2p.setAttribute("opacity", "0");
e3p.setAttribute("opacity", "0");
e1w.setAttribute("opacity", "0");
e2w.setAttribute("opacity", "0");
e3w.setAttribute("opacity", "0");
if (v <= 100) {
// era1 -> era2
var t = v / 100; // 0..1
// era1 fades out, era2 fades in
e1u.setAttribute("opacity", String(1 - t));
e2u.setAttribute("opacity", String(t));
e1p.setAttribute("opacity", String(1 - t));
e2p.setAttribute("opacity", String(t));
e1w.setAttribute("opacity", String(1 - t));
e2w.setAttribute("opacity", String(t));
// era3 stays off
e3u.setAttribute("opacity", "0");
e3p.setAttribute("opacity", "0");
e3w.setAttribute("opacity", "0");
} else {
// era2 -> era3
var t = (v - 100) / 100; // 0..1
e2u.setAttribute("opacity", String(1 - t));
e3u.setAttribute("opacity", String(t));
e2p.setAttribute("opacity", String(1 - t));
e3p.setAttribute("opacity", String(t));
e2w.setAttribute("opacity", String(1 - t));
e3w.setAttribute("opacity", String(t));
// era1 stays off
e1u.setAttribute("opacity", "0");
e1p.setAttribute("opacity", "0");
e1w.setAttribute("opacity", "0");
}
}
function updateLabelForValue(v) {
var eraIndex;
var transition = false;
if (v === 0) {
eraIndex = 0;
transition = false;
} else if (v === 100) {
eraIndex = 1;
transition = false;
} else if (v === 200) {
eraIndex = 2;
transition = false;
} else if (v < 100) {
eraIndex = 0;
transition = true;
} else {
eraIndex = 1;
transition = true;
}
var e = eras[eraIndex];
labelYear.textContent = e.year;
labelPlace.textContent = e.place;
if (transition) {
var nextEra = (eraIndex === 0) ? eras[1] : eras[2];
var prevEra = eras[eraIndex];
var frac = (v < 100) ? (v / 100) : ((v - 100) / 100);
// Describe the transition: between prev and next.
labelBody.innerHTML =
'<span class="transition">Between ' + prevEra.year + ' and ' + nextEra.year + ': ' +
prevEra.armour + ' fading to ' + nextEra.armour + '. ' +
'The ' + prevEra.weapon.split("—")[0].trim() + ' gives way to the ' +
nextEra.weapon.split("—")[0].trim() + '. ' +
'At this point the figure is ' + Math.round(frac * 100) + '% ' +
(eraIndex === 0 ? "1526" : "1916") + ' and ' + Math.round((1 - frac) * 100) + '% ' +
(eraIndex === 0 ? "1916" : "2089") + '.</span>';
} else {
labelBody.innerHTML =
'<strong>' + e.armour + '.</strong> ' +
'Made of ' + e.material + '. ' +
'Carrying: ' + e.weapon + '. ' +
'<span style="color:#777;font-size:0.8rem;">' + e.detail + '</span>';
}
// Update tags
tagLeft.className = "era-tag" + (v <= 50 ? " active" : "");
tagRight.className = "era-tag" + (v >= 150 ? " active" : "");
}
function update(v) {
// Clamp and round to avoid drift from floating point.
var n = Math.round(Number(v));
if (n < 0) n = 0;
if (n > 200) n = 200;
slider.value = n;
setOpacityForValue(n);
updateLabelForValue(n);
}
slider.addEventListener("input", function () {
update(slider.value);
});
// Initial state: era 1
update(0);
})();
</script>
</body>
</html>
The third era is the shakiest, and I say so openly. 2089 Lanzarote is a guess about a place that exists now and may not be a battlefield then; the "pulse carbine" is a directed-energy small arm that is physically plausible but not yet real, and I have rendered it as a slung carbine with an energy cell rather than a laser wand because a wand reads as a film prop and a carbine shape reads as a descendant of the Webley and the estoc — a gun-shaped thing held by a human, not a beam from the sky. The anachronism I was most tempted by was a full-face helmet with a glowing visor; I rejected it because it reads as Star Wars and because a fixed brim and a single-piece visor slit are what actual ballistic helmets have, now and for the foreseeable future. I also kept the suit as worn plate, not a mech, because the brief says "protective equipment descended from the two eras before it," and a mech is not descended from a cuirassier or a trench soldier — it is a different category. The weakest point is the ceramic-composite texture: at this size I have suggested it with a few speckles and segmentation lines, which is the illustrator's compromise of rendering a material that has no historical precedent at a scale where a real photograph would show grain you cannot draw here. If I had more room I would add a subtle edge highlight to the ceramic plates to distinguish them from the steel of 1526 and the steel of 1916, but at this size the three greys would collapse, so I have distinguished them by segmentation (modular lines) and by the underlayer (mail, wool, Kevlar weave) instead. That is a stated weakness: the third era's material read is carried more by the underlayer and the helmet shape than by the plate itself, and a specialist squinting at the SVG will notice that the ceramic plate is drawn as a flat grey with lines, not as a material with a surface. I would rather say that than pretend it is more than it is.