47:51Ranking major U.S. Open-Weights Models. (Where does Ripple 65B fit in?)
Nov 6, 2026 · YouTube
38:58Testing Particle-1: a post-trained DeepSeek V4.1 Flash specializing in coding and efficiency
Oct 28, 2026 · YouTube
29:55Kimi K3.1 Pro Looked Incredible. Then I Kept Testing.
Oct 26, 2026 · YouTube
16:45DeepSeek V4.1 Flash Is Shockingly Good for the Price
Sep 10, 2026 · YouTube
17:14How much better is GPT-6 Astra over Claude Opus 5? Real Website and Coding Tests
Sep 5, 2026 · YouTube
29:13Implementing a multiplayer game with GPT-6 Astra (+ Gemini 3.8, Opus 5, Sol Pro)
Sep 5, 2026 · YouTube
19:42Meta Muse Spark 1.3 Review: A Huge Leap Forward
Sep 2, 2026 · YouTube
17:31Testing Gemini 3.8 Flash on Real Coding Challenges (vs. other models)
Sep 2, 2026 · YouTube
Build one self-contained HTML page for a museum armoury exhibit: a standing figure and a slider that re-equips that same figure across three periods of human history.
Choose any three periods from recorded human history, anywhere in the world. Put them in chronological order and keep adjacent choices at least 100 years apart. For each, name a specific year and place; if an exact year is impossible, give the tightest defensible date range and explain it in the label.
Choose periods you can depict accurately. You are judged on the drawing as well as the interface.
Math.random, clocks, or accumulated state.localStorage, sessionStorage, cookies, or indexedDB.One line per period: date, place, equipment, weapon, and one specific detail a non-specialist might miss.
One paragraph explaining the attachment points, layer order, and interpolation between periods.
One fenced html block containing the complete page.
Name the least certain historical choice and any accuracy compromise you made for legibility.
I will move the slider slowly in both directions, watch the feet and shoulders for drift, compare labels to drawings, inspect the SVG structure, and go straight to the final period before judging the rest.
The SVG contains one fixed anatomical body and fixed anchors for the head (260,124), torso (260,250), waist (260,320), arms (260,190), legs (260,350), feet (260,550), weapon hand (168,335), and shield arm (354,282). Equipment is nested beneath those anchors; back-to-front order is body, leg and foot defences, torso clothing and armour, waist defences, arm harness, head equipment, weapon and gripping hand, then shield. The slider supplies an integer from 0–2000: within each 1000-step interval, endpoint equipment receives deterministic opacities 1-u and u. No body coordinate, scale, or transform changes, exact stops receive weights of precisely one and zero, and intermediate labels explicitly describe the resulting superimposed re-equipment rather than claiming a historical hybrid.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>The Armoury — One Body, Three Battles</title>
<style>
:root {
color-scheme: dark;
--ink: #202724;
--paper: #e9e2d3;
--paper-deep: #dcd2bf;
--night: #151b1b;
--panel: #202827;
--gold: #c9a467;
--muted: #aab2aa;
--line: #3b4541;
}
* { box-sizing: border-box; }
body {
margin: 0;
min-height: 100vh;
background:
radial-gradient(circle at 50% -10%, #2c3733 0, transparent 42rem),
var(--night);
color: #f0ede5;
font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont,
"Segoe UI", sans-serif;
}
.page {
width: min(1080px, 100%);
margin: 0 auto;
padding: 34px 22px 46px;
}
header {
display: flex;
align-items: end;
justify-content: space-between;
gap: 24px;
margin-bottom: 22px;
}
.kicker {
margin: 0 0 8px;
color: var(--gold);
font-size: 0.72rem;
font-weight: 750;
letter-spacing: 0.2em;
text-transform: uppercase;
}
h1 {
margin: 0;
font-family: Georgia, "Times New Roman", serif;
font-size: clamp(2rem, 4.5vw, 3.5rem);
font-weight: 400;
line-height: 1.02;
letter-spacing: -0.025em;
}
.header-note {
max-width: 270px;
margin: 0 0 4px;
color: var(--muted);
font-size: 0.84rem;
line-height: 1.55;
text-align: right;
}
.exhibit {
overflow: hidden;
border: 1px solid #46504a;
border-radius: 4px;
background: var(--panel);
box-shadow: 0 28px 80px #0008;
}
.stage {
position: relative;
border-bottom: 1px solid var(--line);
background:
linear-gradient(90deg, transparent 49.9%, #ffffff08 50%, transparent 50.1%),
radial-gradient(ellipse at 50% 72%, #44504a 0, #29332f 37%, #1d2523 75%);
}
.stage-meta {
position: absolute;
z-index: 2;
top: 18px;
left: 20px;
right: 20px;
display: flex;
justify-content: space-between;
gap: 16px;
color: #c5cec4;
font-size: 0.65rem;
font-weight: 700;
letter-spacing: 0.14em;
pointer-events: none;
text-transform: uppercase;
}
#armoury-figure {
display: block;
width: 100%;
height: 610px;
}
.controls {
padding: 22px 28px 20px;
background: #202827;
}
.control-heading {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: 18px;
margin-bottom: 15px;
}
.control-heading label {
color: #d8ddd5;
font-size: 0.75rem;
font-weight: 750;
letter-spacing: 0.12em;
text-transform: uppercase;
}
#scrub-readout {
color: var(--gold);
font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
font-size: 0.75rem;
text-align: right;
}
#period-slider {
--value: 0%;
display: block;
width: 100%;
height: 24px;
margin: 0;
appearance: none;
-webkit-appearance: none;
background: transparent;
cursor: ew-resize;
}
#period-slider::-webkit-slider-runnable-track {
height: 4px;
border-radius: 4px;
background: linear-gradient(
90deg,
var(--gold) 0 var(--value),
#53605a var(--value) 100%
);
}
#period-slider::-moz-range-track {
height: 4px;
border-radius: 4px;
background: linear-gradient(
90deg,
var(--gold) 0 var(--value),
#53605a var(--value) 100%
);
}
#period-slider::-webkit-slider-thumb {
width: 20px;
height: 20px;
margin-top: -8px;
appearance: none;
-webkit-appearance: none;
border: 3px solid #202827;
border-radius: 50%;
background: #f1d29a;
box-shadow: 0 0 0 1px #f1d29a, 0 3px 9px #0008;
}
#period-slider::-moz-range-thumb {
width: 15px;
height: 15px;
border: 3px solid #202827;
border-radius: 50%;
background: #f1d29a;
box-shadow: 0 0 0 1px #f1d29a, 0 3px 9px #0008;
}
#period-slider:focus-visible {
outline: 2px solid #f1d29a;
outline-offset: 5px;
}
.stop-buttons {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
margin-top: 9px;
}
.stop-buttons button {
padding: 8px 6px;
border: 1px solid transparent;
border-radius: 2px;
background: transparent;
color: #bfc8bf;
font: inherit;
font-size: 0.77rem;
cursor: pointer;
}
.stop-buttons button:first-child { text-align: left; }
.stop-buttons button:last-child { text-align: right; }
.stop-buttons button:hover {
color: #fff4dc;
border-color: #59665e;
}
.stop-buttons button[aria-pressed="true"] {
border-color: #9b835b;
background: #c9a46712;
color: #f1d29a;
}
.control-note {
margin: 11px 0 0;
color: #939f97;
font-size: 0.72rem;
line-height: 1.45;
}
.placard {
position: relative;
padding: 28px 30px 30px;
border-top: 5px solid var(--gold);
background:
linear-gradient(90deg, #00000005 1px, transparent 1px) 0 0 / 24px 24px,
var(--paper);
color: var(--ink);
}
.placard-topline {
display: flex;
align-items: center;
justify-content: space-between;
gap: 18px;
margin-bottom: 9px;
}
#stop-status {
display: inline-flex;
align-items: center;
gap: 7px;
color: #526044;
font-size: 0.66rem;
font-weight: 800;
letter-spacing: 0.14em;
text-transform: uppercase;
}
#stop-status::before {
width: 7px;
height: 7px;
border-radius: 50%;
background: #73855b;
content: "";
}
#stop-status.transition { color: #8b582e; }
#stop-status.transition::before { background: #b6753d; }
.catalogue {
color: #6b6c61;
font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
font-size: 0.68rem;
}
#period-title {
margin: 0 0 20px;
font-family: Georgia, "Times New Roman", serif;
font-size: clamp(1.55rem, 3vw, 2.25rem);
font-weight: 400;
line-height: 1.12;
}
.label-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 17px 30px;
}
.field.wide { grid-column: 1 / -1; }
.field dt {
margin-bottom: 4px;
color: #777367;
font-size: 0.63rem;
font-weight: 800;
letter-spacing: 0.15em;
text-transform: uppercase;
}
.field dd {
margin: 0;
font-size: 0.88rem;
line-height: 1.5;
}
#period-note {
margin: 22px 0 0;
padding-top: 15px;
border-top: 1px solid #bdb39f;
color: #5c5c52;
font-family: Georgia, "Times New Roman", serif;
font-size: 0.9rem;
font-style: italic;
line-height: 1.55;
}
footer {
margin-top: 15px;
color: #859088;
font-size: 0.7rem;
line-height: 1.5;
text-align: center;
}
@media (max-width: 700px) {
.page { padding: 22px 12px 32px; }
header { display: block; }
.header-note { margin-top: 12px; text-align: left; }
#armoury-figure { height: 500px; }
.stage-meta { font-size: 0.56rem; }
.controls { padding: 19px 17px; }
.placard { padding: 24px 20px; }
.label-grid { grid-template-columns: 1fr; }
.field.wide { grid-column: auto; }
.control-heading { align-items: start; }
}
@media (max-width: 430px) {
#armoury-figure { height: 430px; }
.stage-meta span:last-child { display: none; }
.catalogue { display: none; }
}
</style>
</head>
<body>
<div class="page">
<header>
<div>
<p class="kicker">Museum armoury · Reconstruction study</p>
<h1>One body. Three battles.</h1>
</div>
<p class="header-note">
A single standing rig, re-equipped from Marathon to Agincourt to Osaka.
The intervening views explain the change; they are not additional periods.
</p>
</header>
<main class="exhibit">
<section class="stage" aria-label="Armoured figure reconstruction">
<div class="stage-meta">
<span id="stage-mode">Plate I · Exact stop</span>
<span>Fixed anatomical rig · No rescaling</span>
</div>
<svg id="armoury-figure"
viewBox="0 -45 520 635"
role="img"
aria-labelledby="svg-title svg-description"
xmlns="http://www.w3.org/2000/svg">
<title id="svg-title">One standing figure with equipment from three historical periods</title>
<desc id="svg-description">
A fixed body with bronze Athenian hoplite equipment, steel fifteenth-century
plate harness, or lacquered Japanese armour, depending on the timeline slider.
</desc>
<defs>
<linearGradient id="bronze" x1="0" y1="0" x2="1" y2="1">
<stop offset="0" stop-color="#f0d080"/>
<stop offset="0.28" stop-color="#c59548"/>
<stop offset="0.64" stop-color="#8c5b2b"/>
<stop offset="1" stop-color="#d0a151"/>
</linearGradient>
<linearGradient id="bronze-light" x1="0" y1="0" x2="1" y2="0">
<stop offset="0" stop-color="#7c4f27"/>
<stop offset="0.46" stop-color="#e0b965"/>
<stop offset="0.7" stop-color="#a87536"/>
<stop offset="1" stop-color="#664322"/>
</linearGradient>
<linearGradient id="steel" x1="0" y1="0" x2="1" y2="1">
<stop offset="0" stop-color="#e2e5df"/>
<stop offset="0.27" stop-color="#aebbbd"/>
<stop offset="0.58" stop-color="#64777d"/>
<stop offset="0.8" stop-color="#3f535b"/>
<stop offset="1" stop-color="#a8b5b5"/>
</linearGradient>
<linearGradient id="steel-dark" x1="0" y1="0" x2="1" y2="0">
<stop offset="0" stop-color="#34484f"/>
<stop offset="0.48" stop-color="#a3b1b1"/>
<stop offset="1" stop-color="#41565c"/>
</linearGradient>
<linearGradient id="lacquer" x1="0" y1="0" x2="1" y2="1">
<stop offset="0" stop-color="#536b70"/>
<stop offset="0.35" stop-color="#2c444b"/>
<stop offset="0.8" stop-color="#172b32"/>
<stop offset="1" stop-color="#40585c"/>
</linearGradient>
<linearGradient id="skin" x1="0" y1="0" x2="1" y2="1">
<stop offset="0" stop-color="#d0a07a"/>
<stop offset="0.55" stop-color="#ad795a"/>
<stop offset="1" stop-color="#80543f"/>
</linearGradient>
<linearGradient id="red-cloth" x1="0" y1="0" x2="1" y2="1">
<stop offset="0" stop-color="#a6533d"/>
<stop offset="0.55" stop-color="#77382f"/>
<stop offset="1" stop-color="#4d2928"/>
</linearGradient>
<radialGradient id="shield-face" cx="35%" cy="28%" r="80%">
<stop offset="0" stop-color="#a15c42"/>
<stop offset="0.65" stop-color="#743d32"/>
<stop offset="1" stop-color="#3f2927"/>
</radialGradient>
<pattern id="mail-pattern" width="10" height="10" patternUnits="userSpaceOnUse">
<rect width="10" height="10" fill="#39494d"/>
<circle cx="2.8" cy="2.8" r="2.25" fill="none" stroke="#94a09e" stroke-width="0.8"/>
<circle cx="7.8" cy="7.8" r="2.25" fill="none" stroke="#788885" stroke-width="0.8"/>
</pattern>
<pattern id="haidate-pattern" width="13" height="15" patternUnits="userSpaceOnUse">
<rect width="13" height="15" fill="#343b38"/>
<rect x="1.2" y="2" width="10" height="9.5" rx="1"
fill="#6c746b" stroke="#222d2d" stroke-width="0.8"/>
<path d="M3 1v3M10 1v3" stroke="#a5543b" stroke-width="1.4"/>
</pattern>
<g id="kusazuri-panel">
<path d="M0 0H24L28 72Q12 78-4 72Z"
fill="url(#lacquer)" stroke="#13252a" stroke-width="1.4"/>
<g fill="none" stroke="#61767a" stroke-width="1">
<path d="M-1 14Q12 18 25 14"/>
<path d="M-2 28Q12 32 26 28"/>
<path d="M-3 42Q12 46 27 42"/>
<path d="M-3 56Q12 60 27 56"/>
</g>
<g fill="none" stroke="#ad573d" stroke-width="2">
<path d="M4 2L5 13L4 27L5 41L4 55L5 69"/>
<path d="M18 2L19 13L18 27L19 41L18 55L19 69"/>
</g>
<g fill="#c17a51">
<circle cx="5" cy="14" r="1.5"/><circle cx="19" cy="14" r="1.5"/>
<circle cx="4" cy="42" r="1.5"/><circle cx="19" cy="42" r="1.5"/>
</g>
</g>
</defs>
<!-- Museum mount and ground never move. -->
<g id="display-base">
<ellipse cx="260" cy="581" rx="139" ry="17" fill="#080d0c" opacity="0.42"/>
<path d="M91 590H429" stroke="#9d9f88" stroke-width="1" opacity="0.36"/>
<path d="M153 596H367" stroke="#111917" stroke-width="5" opacity="0.42"/>
</g>
<g id="figure-rig" stroke-linecap="round" stroke-linejoin="round">
<!-- LAYER 1: the one anatomical body. Nothing here is animated. -->
<g id="fixed-body" stroke="#17211f" stroke-width="1.5">
<g id="fixed-legs" data-fixed-proportions="true">
<path d="M222 345Q236 337 253 350L247 437Q237 452 219 439L211 370Z"
fill="#303a38"/>
<path d="M267 350Q284 337 298 345L309 370L301 439Q283 452 273 437Z"
fill="#303a38"/>
<path d="M219 432Q232 441 247 434L239 541Q234 557 215 548L207 466Z"
fill="#293432"/>
<path d="M273 434Q288 441 301 432L313 466L305 548Q286 557 281 541Z"
fill="#293432"/>
<path d="M210 542Q225 538 239 546L239 566L196 575Q188 566 199 555Z"
fill="#202927"/>
<path d="M281 546Q295 538 310 542L321 555Q332 566 324 575L281 566Z"
fill="#202927"/>
</g>
<g id="fixed-torso" data-fixed-proportions="true">
<path d="M245 140L244 174Q260 184 276 174L275 140Z"
fill="url(#skin)"/>
<path d="M211 177Q230 164 245 166L275 166Q290 164 309 177
L300 256L294 322Q260 336 226 322L220 256Z"
fill="#35403c"/>
<path d="M226 318L294 318L302 355L278 371L260 352L242 371L218 355Z"
fill="#2d3734"/>
</g>
<g id="fixed-arms" data-fixed-proportions="true">
<path d="M204 179Q187 187 181 208L168 252Q171 267 187 270
L205 222L222 196Z" fill="#35403c"/>
<path d="M169 251Q157 277 155 308L153 327Q161 340 176 334
L185 300L196 268Z" fill="#35403c"/>
<path d="M316 179Q333 187 339 208L352 252Q349 267 333 270
L315 222L298 196Z" fill="#35403c"/>
<path d="M351 251Q363 277 365 308L367 327Q359 340 344 334
L335 300L324 268Z" fill="#35403c"/>
<path d="M157 325Q168 318 179 327L180 339Q169 350 157 340Z"
fill="url(#skin)"/>
<path d="M363 325Q352 318 341 327L340 339Q351 350 363 340Z"
fill="url(#skin)"/>
</g>
<g id="fixed-head" data-fixed-proportions="true">
<ellipse cx="232" cy="113" rx="6" ry="11" fill="#a97456"/>
<ellipse cx="288" cy="113" rx="6" ry="11" fill="#a97456"/>
<path d="M232 82Q260 56 288 82L288 119Q284 146 260 157
Q236 146 232 119Z" fill="url(#skin)"/>
<path d="M241 101Q248 97 254 101M266 101Q272 97 279 101"
fill="none" stroke="#4b3830" stroke-width="2"/>
<path d="M260 105L256 125L263 128" fill="none"
stroke="#76503f" stroke-width="1.5"/>
<path d="M250 140Q260 144 270 140" fill="none"
stroke="#634439" stroke-width="1.5"/>
</g>
</g>
<!-- LAYER 2: leg equipment, anchored at the fixed hips. -->
<g id="anchor-legs" data-fixed-anchor="260,350" transform="translate(260 350)">
<g id="hoplite-leg-equipment" data-period="0" opacity="1">
<path d="M-46 23L-10 22L-14 84Q-24 103-40 90L-49 45Z"
fill="url(#skin)" stroke="#694b3b" stroke-width="1.4"/>
<path d="M46 23L10 22L14 84Q24 103 40 90L49 45Z"
fill="url(#skin)" stroke="#694b3b" stroke-width="1.4"/>
<path d="M-50 105Q-36 95-19 102L-23 170Q-28 194-43 196
Q-53 186-52 164Z"
fill="url(#bronze-light)" stroke="#604223" stroke-width="1.7"/>
<path d="M50 105Q36 95 19 102L23 170Q28 194 43 196
Q53 186 52 164Z"
fill="url(#bronze-light)" stroke="#604223" stroke-width="1.7"/>
<path d="M-35 106Q-30 144-39 187M35 106Q30 144 39 187"
fill="none" stroke="#efd081" stroke-width="2" opacity="0.65"/>
<path d="M-48 117Q-35 124-21 116M48 117Q35 124 21 116"
fill="none" stroke="#6d4926" stroke-width="1.2"/>
</g>
<g id="medieval-leg-harness" data-period="1" opacity="0">
<path d="M-42-5Q-24-13-7 0L-13 87Q-23 102-41 89L-49 20Z"
fill="url(#steel)" stroke="#34484e" stroke-width="1.6"/>
<path d="M42-5Q24-13 7 0L13 87Q23 102 41 89L49 20Z"
fill="url(#steel)" stroke="#34484e" stroke-width="1.6"/>
<path d="M-27 1L-29 81M27 1L29 81"
stroke="#d6ded9" stroke-width="2" opacity="0.58"/>
<path d="M-50 82Q-33 72-16 84L-14 103Q-32 116-49 103Z"
fill="url(#steel-dark)" stroke="#33464c" stroke-width="1.5"/>
<path d="M50 82Q33 72 16 84L14 103Q32 116 49 103Z"
fill="url(#steel-dark)" stroke="#33464c" stroke-width="1.5"/>
<path d="M-48 88L-61 83L-58 104L-47 108ZM48 88L61 83L58 104L47 108Z"
fill="url(#steel)" stroke="#33464c" stroke-width="1.3"/>
<path d="M-50 108Q-36 99-19 105L-23 171Q-28 194-43 196
Q-52 184-52 162Z"
fill="url(#steel)" stroke="#34484e" stroke-width="1.6"/>
<path d="M50 108Q36 99 19 105L23 171Q28 194 43 196
Q52 184 52 162Z"
fill="url(#steel)" stroke="#34484e" stroke-width="1.6"/>
<path d="M-35 111L-39 188M35 111L39 188"
stroke="#e0e5df" stroke-width="2" opacity="0.65"/>
<g fill="#c4ceca">
<circle cx="-45" cy="91" r="1.8"/><circle cx="-21" cy="91" r="1.8"/>
<circle cx="45" cy="91" r="1.8"/><circle cx="21" cy="91" r="1.8"/>
</g>
</g>
<g id="samurai-leg-equipment" data-period="2" opacity="0">
<path d="M-42-5Q-24-13-7 0L-13 91Q-25 106-43 91L-51 22Z"
fill="#49483f" stroke="#242c29" stroke-width="1.5"/>
<path d="M42-5Q24-13 7 0L13 91Q25 106 43 91L51 22Z"
fill="#49483f" stroke="#242c29" stroke-width="1.5"/>
<path d="M-49 1L-11 1L-14 91Q-31 102-48 91Z"
fill="url(#haidate-pattern)" stroke="#202c2b" stroke-width="1.6"/>
<path d="M49 1L11 1L14 91Q31 102 48 91Z"
fill="url(#haidate-pattern)" stroke="#202c2b" stroke-width="1.6"/>
<path d="M-45 88Q-30 98-17 88M45 88Q30 98 17 88"
fill="none" stroke="#a7533b" stroke-width="2"/>
<path d="M-50 108Q-35 101-19 106L-23 173Q-29 193-44 195
L-52 166Z"
fill="#2b3534" stroke="#192523" stroke-width="1.5"/>
<path d="M50 108Q35 101 19 106L23 173Q29 193 44 195
L52 166Z"
fill="#2b3534" stroke="#192523" stroke-width="1.5"/>
<g stroke="#77827a" stroke-width="5">
<path d="M-44 115L-45 181M-34 111L-35 185M-24 114L-27 178"/>
<path d="M44 115L45 181M34 111L35 185M24 114L27 178"/>
</g>
<g stroke="#9a4e38" stroke-width="3">
<path d="M-50 133Q-35 139-21 133M50 133Q35 139 21 133"/>
<path d="M-48 165Q-35 171-23 165M48 165Q35 171 23 165"/>
</g>
</g>
</g>
<!-- LAYER 3: footwear uses the same two fixed foot outlines. -->
<g id="anchor-feet" data-fixed-anchor="260,550" transform="translate(260 550)">
<g id="hoplite-sandals" data-period="0" opacity="1">
<path d="M-50-8Q-35-12-21-4L-21 16L-64 25Q-72 16-61 5Z"
fill="url(#skin)" stroke="#5e4133" stroke-width="1.5"/>
<path d="M21-4Q35-12 50-8L61 5Q72 16 64 25L21 16Z"
fill="url(#skin)" stroke="#5e4133" stroke-width="1.5"/>
<path d="M-66 23L-22 14M66 23L22 14"
stroke="#493126" stroke-width="5"/>
<path d="M-57 3L-27 15M-48-6L-44 17M57 3L27 15M48-6L44 17"
stroke="#68442d" stroke-width="3"/>
</g>
<g id="medieval-sabatons" data-period="1" opacity="0">
<path d="M-50-8Q-35-12-21-4L-21 16L-64 25Q-72 16-61 5Z"
fill="url(#steel)" stroke="#34484e" stroke-width="1.5"/>
<path d="M21-4Q35-12 50-8L61 5Q72 16 64 25L21 16Z"
fill="url(#steel)" stroke="#34484e" stroke-width="1.5"/>
<g fill="none" stroke="#40555b" stroke-width="1.4">
<path d="M-60 2Q-42 8-23 5M-65 10Q-44 16-22 12M-63 18L-29 17"/>
<path d="M60 2Q42 8 23 5M65 10Q44 16 22 12M63 18L29 17"/>
</g>
<path d="M-43-7L-39 17M43-7L39 17"
stroke="#d7dfda" stroke-width="2" opacity="0.6"/>
</g>
<g id="samurai-tabi-and-sandals" data-period="2" opacity="0">
<path d="M-50-8Q-35-12-21-4L-21 16L-64 25Q-72 16-61 5Z"
fill="#252f30" stroke="#111a1b" stroke-width="1.5"/>
<path d="M21-4Q35-12 50-8L61 5Q72 16 64 25L21 16Z"
fill="#252f30" stroke="#111a1b" stroke-width="1.5"/>
<path d="M-66 23L-22 14M66 23L22 14"
stroke="#a58a5d" stroke-width="5"/>
<path d="M-57 4L-30 16M-43-5L-43 15M57 4L30 16M43-5L43 15"
stroke="#8c7653" stroke-width="2.5"/>
</g>
</g>
<!-- LAYER 4: clothing and torso armour. -->
<g id="anchor-torso" data-fixed-anchor="260,250" transform="translate(260 250)">
<g id="hoplite-chiton-and-cuirass" data-period="0" opacity="1">
<path d="M-50-72Q-28-86-15-80L0-70L15-80Q28-86 50-72
L43 10L38 64L50 126L25 137L0 121L-25 137L-50 126
L-38 64L-43 10Z"
fill="url(#red-cloth)" stroke="#482827" stroke-width="1.6"/>
<path d="M-31 76L-25 126M0 73V119M31 76L25 126"
fill="none" stroke="#c36b4b" stroke-width="1.4" opacity="0.48"/>
<path d="M-46-69L-24-79Q0-66 24-79L46-69L36-41L31 15
Q30 41 44 59Q0 72-44 59Q-30 41-31 15L-36-41Z"
fill="url(#bronze)" stroke="#664421" stroke-width="2"/>
<path d="M-43 56Q0 67 43 56" fill="none"
stroke="#f0cf7b" stroke-width="3" opacity="0.72"/>
<path d="M0-65V55M-29-46Q-17-28-24 8M29-46Q17-28 24 8"
fill="none" stroke="#f2d688" stroke-width="1.5" opacity="0.4"/>
<path d="M-35-65Q0-50 35-65" fill="none"
stroke="#755029" stroke-width="1.5"/>
</g>
<g id="medieval-breastplate" data-period="1" opacity="0">
<path d="M-50-72Q-28-86-15-80L0-70L15-80Q28-86 50-72
L43 10L38 69Q0 80-38 69L-43 10Z"
fill="#303839" stroke="#1c2728" stroke-width="1.5"/>
<path d="M-45-72Q-25-82 0-72Q25-82 45-72L41-25
Q35 10 39 42L45 58Q0 72-45 58L-39 42
Q-35 10-41-25Z"
fill="url(#steel)" stroke="#34484e" stroke-width="1.8"/>
<path d="M0-66V57" stroke="#e0e6e0" stroke-width="2.2" opacity="0.68"/>
<path d="M-39 22Q0 36 39 22" fill="none"
stroke="#3d5259" stroke-width="2"/>
<path d="M-42 50Q0 63 42 50" fill="none"
stroke="#d5ded9" stroke-width="1.5" opacity="0.65"/>
<path d="M-26-71Q0-58 26-71" fill="none"
stroke="#263a40" stroke-width="3"/>
<g fill="#d6ded8">
<circle cx="-37" cy="-44" r="2"/><circle cx="37" cy="-44" r="2"/>
<circle cx="-35" cy="39" r="2"/><circle cx="35" cy="39" r="2"/>
</g>
</g>
<g id="samurai-okegawa-do" data-period="2" opacity="0">
<path d="M-51-71Q-27-86-12-78L0-67L12-78Q27-86 51-71
L45 16L39 72Q0 84-39 72L-45 16Z"
fill="#3b4240" stroke="#1d2928" stroke-width="1.5"/>
<path d="M-39-69L-48-46L-35-38L-22-70ZM39-69L48-46L35-38L22-70Z"
fill="url(#lacquer)" stroke="#17282c" stroke-width="1.5"/>
<path d="M-45-63Q0-78 45-63L42 40Q0 58-42 40Z"
fill="url(#lacquer)" stroke="#14272d" stroke-width="1.8"/>
<g fill="none" stroke="#687d7e" stroke-width="1.5">
<path d="M-44-40Q0-28 44-40"/>
<path d="M-43-18Q0-6 43-18"/>
<path d="M-43 4Q0 16 43 4"/>
<path d="M-42 26Q0 38 42 26"/>
</g>
<g fill="#a5aaa0" stroke="#26383a" stroke-width="0.7">
<circle cx="-31" cy="-50" r="2"/><circle cx="0" cy="-44" r="2"/>
<circle cx="31" cy="-50" r="2"/>
<circle cx="-32" cy="-28" r="2"/><circle cx="0" cy="-22" r="2"/>
<circle cx="32" cy="-28" r="2"/>
<circle cx="-32" cy="-6" r="2"/><circle cx="0" cy="0" r="2"/>
<circle cx="32" cy="-6" r="2"/>
<circle cx="-31" cy="17" r="2"/><circle cx="0" cy="23" r="2"/>
<circle cx="31" cy="17" r="2"/>
</g>
<path d="M-38-58Q-24-66-12-62" fill="none"
stroke="#91a09a" stroke-width="2" opacity="0.45"/>
</g>
</g>
<!-- LAYER 5: waist defences and sidearm. -->
<g id="anchor-waist" data-fixed-anchor="260,320" transform="translate(260 320)">
<g id="medieval-fauld-and-mail-skirt" data-period="1" opacity="0">
<path d="M-36-10L36-10L43 57Q0 73-43 57Z"
fill="url(#mail-pattern)" stroke="#2d3d40" stroke-width="1.5"/>
<path d="M-42-12Q0 0 42-12L43 0Q0 13-43 0Z"
fill="url(#steel)" stroke="#374b51" stroke-width="1.3"/>
<path d="M-43 0Q0 13 43 0L44 12Q0 25-44 12Z"
fill="url(#steel)" stroke="#374b51" stroke-width="1.3"/>
<path d="M-44 12Q0 25 44 12L42 25Q0 38-42 25Z"
fill="url(#steel)" stroke="#374b51" stroke-width="1.3"/>
</g>
<g id="samurai-kusazuri-and-katana" data-period="2" opacity="0">
<!-- Sheathed katana: hilt forward, scabbard at the anatomical left hip. -->
<path d="M22 4Q58 23 103 47" fill="none"
stroke="#111f24" stroke-width="10"/>
<path d="M25 2Q61 21 101 43" fill="none"
stroke="#597074" stroke-width="2" opacity="0.65"/>
<path d="M22 4L-3-13" fill="none" stroke="#6c4936" stroke-width="11"/>
<path d="M16-1L11 4M9-6L4-1M2-11L-3-6"
stroke="#c1aa82" stroke-width="2"/>
<ellipse cx="22" cy="4" rx="5" ry="11"
transform="rotate(-56 22 4)" fill="#786c4d"
stroke="#292d27" stroke-width="1.3"/>
<use href="#kusazuri-panel" transform="translate(-52 0)"/>
<use href="#kusazuri-panel" transform="translate(-26 0)"/>
<use href="#kusazuri-panel" transform="translate(0 0)"/>
<use href="#kusazuri-panel" transform="translate(26 0)"/>
</g>
</g>
<!-- LAYER 6: arm equipment on the fixed arm pose. -->
<g id="anchor-arms" data-fixed-anchor="260,190" transform="translate(260 190)">
<g id="hoplite-arms-and-sleeves" data-period="0" opacity="1">
<g id="hoplite-arm-screen-left">
<path d="M-56-11Q-73-3-79 18L-92 62Q-89 77-73 80
L-55 32L-38 6Z"
fill="url(#skin)" stroke="#694b3b" stroke-width="1.4"/>
<path d="M-91 61Q-103 87-105 118L-107 137Q-99 150-84 144
L-75 110L-64 78Z"
fill="url(#skin)" stroke="#694b3b" stroke-width="1.4"/>
<path d="M-58-12Q-47-22-29-12L-39 22L-59 30L-75 15Z"
fill="url(#red-cloth)" stroke="#542c29" stroke-width="1.4"/>
</g>
<use href="#hoplite-arm-screen-left" transform="scale(-1 1)"/>
</g>
<g id="medieval-arm-harness" data-period="1" opacity="0">
<g id="medieval-arm-screen-left">
<path d="M-56-11Q-73-3-79 18L-92 62L-105 119L-107 137
Q-99 150-84 144L-75 110L-64 78L-55 32L-38 6Z"
fill="#303a3b" stroke="#1c292b" stroke-width="1.4"/>
<path d="M-70-14Q-52-28-32-12L-34 10Q-52 20-73 10Z"
fill="url(#steel)" stroke="#34484e" stroke-width="1.5"/>
<path d="M-73 8Q-54 18-36 8L-40 22Q-57 31-77 20Z"
fill="url(#steel-dark)" stroke="#34484e" stroke-width="1.3"/>
<path d="M-72 20L-52 25L-66 61L-85 57Z"
fill="url(#steel)" stroke="#34484e" stroke-width="1.5"/>
<path d="M-93 62Q-82 54-69 65L-70 81Q-84 90-97 79Z"
fill="url(#steel-dark)" stroke="#34484e" stroke-width="1.4"/>
<path d="M-95 82L-75 86L-86 132L-104 132Z"
fill="url(#steel)" stroke="#34484e" stroke-width="1.5"/>
<path d="M-105 130L-85 130L-81 143L-88 154L-105 148L-111 139Z"
fill="url(#steel-dark)" stroke="#34484e" stroke-width="1.4"/>
<path d="M-66-13L-55 12M-76 29L-64 55M-91 88L-98 126"
stroke="#e0e5df" stroke-width="1.7" opacity="0.55"/>
<path d="M-103 139L-88 144M-101 145L-90 149"
stroke="#c0cbc7" stroke-width="1"/>
</g>
<use href="#medieval-arm-screen-left" transform="scale(-1 1)"/>
</g>
<g id="samurai-sode-and-kote" data-period="2" opacity="0">
<g id="samurai-arm-screen-left">
<path d="M-56-11Q-73-3-79 18L-92 62L-105 119L-107 137
Q-99 150-84 144L-75 110L-64 78L-55 32L-38 6Z"
fill="#3d4340" stroke="#202a28" stroke-width="1.4"/>
<path d="M-82-9L-42-5L-48 68L-91 63Z"
fill="url(#lacquer)" stroke="#17282d" stroke-width="1.6"/>
<g fill="none" stroke="#6b7e7e" stroke-width="1.2">
<path d="M-84 8L-44 12M-86 25L-46 29M-88 43L-47 47"/>
</g>
<g stroke="#b1583e" stroke-width="2.2">
<path d="M-75-5L-76 8L-77 25L-78 43L-79 60"/>
<path d="M-55-4L-57 11L-58 28L-59 46L-60 64"/>
</g>
<path d="M-94 76L-73 82L-86 133L-105 132Z"
fill="url(#mail-pattern)" stroke="#233335" stroke-width="1.4"/>
<path d="M-91 83L-99 124M-82 85L-91 127"
stroke="#8a9690" stroke-width="4"/>
<path d="M-105 130L-85 130L-81 143L-88 154L-105 148L-111 139Z"
fill="#293637" stroke="#142122" stroke-width="1.4"/>
<path d="M-99 86L-80 91M-103 113L-86 117"
stroke="#a34f39" stroke-width="2.4"/>
</g>
<use href="#samurai-arm-screen-left" transform="scale(-1 1)"/>
</g>
</g>
<!-- LAYER 7: helmets attach to the same skull anchor. -->
<g id="anchor-head" data-fixed-anchor="260,124" transform="translate(260 124)">
<g id="hoplite-corinthian-helmet" data-period="0" opacity="1">
<path d="M-36-31Q-34-65 0-70Q34-65 36-31L34 18L26 37
L12 34L10 2L-10 2L-12 34L-26 37L-34 18Z"
fill="url(#bronze)" stroke="#624221" stroke-width="1.8"/>
<path d="M-27-21L27-21L24-7L8-10L5 15L0 27L-5 15L-8-10L-24-7Z"
fill="url(#skin)" stroke="#6e4b31" stroke-width="1"/>
<path d="M-25-18L-8-14L-10-8L-24-10ZM25-18L8-14L10-8L24-10Z"
fill="#1d2522"/>
<path d="M-4-22L4-22L5 9L0 18L-5 9Z"
fill="url(#bronze-light)" stroke="#75502a" stroke-width="0.8"/>
<path d="M-29-35Q0-57 29-35M-30 9L-24 29M30 9L24 29"
fill="none" stroke="#f1d485" stroke-width="2" opacity="0.55"/>
<path d="M-35-25Q0-39 35-25" fill="none"
stroke="#74502a" stroke-width="1.4"/>
</g>
<g id="medieval-bascinet-and-aventail" data-period="1" opacity="0">
<path d="M-39-5Q-48 20-45 54Q-30 72 0 64Q30 72 45 54
Q48 20 39-5L28 15Q0 35-28 15Z"
fill="url(#mail-pattern)" stroke="#2d3c3f" stroke-width="1.6"/>
<path d="M-34-18Q-35-53 0-73Q35-53 34-18L30 10L-30 10Z"
fill="url(#steel)" stroke="#34484e" stroke-width="1.7"/>
<path d="M-31-20Q0-32 31-20L28 8L8 27L0 32L-8 27L-28 8Z"
fill="url(#steel-dark)" stroke="#33474e" stroke-width="1.6"/>
<path d="M-26-12Q0-17 26-12L25-7Q0-11-25-7Z"
fill="#172326"/>
<path d="M0-25V27" stroke="#c7d2cf" stroke-width="2" opacity="0.68"/>
<g fill="#26383d">
<circle cx="-18" cy="3" r="1.8"/><circle cx="-11" cy="7" r="1.8"/>
<circle cx="-19" cy="11" r="1.8"/><circle cx="18" cy="3" r="1.8"/>
<circle cx="11" cy="7" r="1.8"/><circle cx="19" cy="11" r="1.8"/>
</g>
<circle cx="-32" cy="-12" r="4" fill="#71858a"
stroke="#2f4248" stroke-width="1"/>
<circle cx="32" cy="-12" r="4" fill="#71858a"
stroke="#2f4248" stroke-width="1"/>
<path d="M-25-43Q0-62 25-43" fill="none"
stroke="#e1e5df" stroke-width="2" opacity="0.55"/>
</g>
<g id="samurai-kabuto-menpo" data-period="2" opacity="0">
<!-- Shikoro: separate flaring side and rear neck-guard lames. -->
<path d="M-34-24L-27 8L-34 48L-52 42Q-47 4-34-24Z"
fill="url(#lacquer)" stroke="#15282d" stroke-width="1.5"/>
<path d="M34-24L27 8L34 48L52 42Q47 4 34-24Z"
fill="url(#lacquer)" stroke="#15282d" stroke-width="1.5"/>
<path d="M-34 22Q0 38 34 22L43 51Q0 69-43 51Z"
fill="url(#lacquer)" stroke="#15282d" stroke-width="1.5"/>
<g fill="none" stroke="#728588" stroke-width="1.2">
<path d="M-44-2L-29 3M-48 14L-31 19M-50 29L-33 33"/>
<path d="M44-2L29 3M48 14L31 19M50 29L33 33"/>
<path d="M-39 36Q0 52 39 36M-41 47Q0 63 41 47"/>
</g>
<g stroke="#ae563d" stroke-width="2">
<path d="M-40-12L-43 36M40-12L43 36"/>
<path d="M-26 31L-28 53M26 31L28 53"/>
</g>
<path d="M-34-28Q-34-54 0-67Q34-54 34-28L31-20
Q0-29-31-20Z"
fill="url(#lacquer)" stroke="#14272d" stroke-width="1.7"/>
<path d="M0-64V-27" stroke="#8a9a94" stroke-width="2.2" opacity="0.7"/>
<path d="M-39-28Q0-35 39-28L34-17Q0-24-34-17Z"
fill="#263d43" stroke="#13272d" stroke-width="1.4"/>
<path d="M-24-2Q0-9 24-2L21 24Q12 39 0 41Q-12 39-21 24Z"
fill="#354a4d" stroke="#17292c" stroke-width="1.6"/>
<path d="M0-3L-6 15L2 18L8 14" fill="none"
stroke="#839087" stroke-width="2"/>
<path d="M-10 28Q0 23 10 28" fill="none"
stroke="#111e20" stroke-width="2.5"/>
<path d="M-22 38Q0 48 22 38L25 50Q0 61-25 50Z"
fill="url(#lacquer)" stroke="#17282c" stroke-width="1.3"/>
<path d="M-25 50Q0 61 25 50L24 62Q0 72-24 62Z"
fill="url(#lacquer)" stroke="#17282c" stroke-width="1.3"/>
<path d="M-19 43L19 52M-20 55L20 63"
stroke="#ad553c" stroke-width="2"/>
<g fill="#9ba49a">
<circle cx="-22" cy="-42" r="1.8"/><circle cx="22" cy="-42" r="1.8"/>
</g>
</g>
</g>
<!-- LAYER 8: all weapons attach to the same right-hand point. -->
<g id="anchor-right-hand" data-fixed-anchor="168,335" transform="translate(168 335)">
<g id="hoplite-dory" data-period="0" opacity="1">
<path d="M0-305V220" stroke="#69482c" stroke-width="5"/>
<path d="M-1-303V218" stroke="#aa7d47" stroke-width="1.2" opacity="0.7"/>
<path d="M0-365C-13-346-14-323 0-305C14-323 13-346 0-365Z"
fill="url(#steel)" stroke="#34494f" stroke-width="1.4"/>
<path d="M0-359V-309" stroke="#e3e6de" stroke-width="1.4"/>
<path d="M-5 218L0 250L5 218Z"
fill="url(#bronze)" stroke="#694724" stroke-width="1.2"/>
<path d="M-11-8Q0-15 10-6L11 7Q0 16-11 7Z"
fill="url(#skin)" stroke="#674737" stroke-width="1.4"/>
<path d="M-8-2L8 1M-8 4L7 7" fill="none"
stroke="#7c533e" stroke-width="1.1"/>
</g>
<g id="medieval-pollaxe" data-period="1" opacity="0">
<path d="M0-199V220" stroke="#725236" stroke-width="7"/>
<path d="M-1-198V218" stroke="#b18a58" stroke-width="1.5" opacity="0.65"/>
<path d="M0-280L7-246L0-229L-7-246Z"
fill="url(#steel)" stroke="#34484e" stroke-width="1.3"/>
<path d="M-7-241H7V-177H-7Z"
fill="url(#steel-dark)" stroke="#34484e" stroke-width="1.3"/>
<path d="M-6-234C-24-238-48-231-56-211
C-42-213-31-190-7-190Z"
fill="url(#steel)" stroke="#34484e" stroke-width="1.5"/>
<path d="M7-225L49-214L7-204Z"
fill="url(#steel)" stroke="#34484e" stroke-width="1.4"/>
<path d="M-5-177L-5-93M5-177L5-93"
stroke="#87999c" stroke-width="2.5"/>
<path d="M-11-9L9-9L13 2L8 14L-8 14L-13 3Z"
fill="url(#steel-dark)" stroke="#34484e" stroke-width="1.4"/>
<path d="M-9-2H10M-9 5H9" stroke="#c3cfcb" stroke-width="1.2"/>
</g>
<g id="samurai-sugu-yari" data-period="2" opacity="0">
<path d="M0-211V230" stroke="#202c2b" stroke-width="6"/>
<path d="M-1-208V228" stroke="#63716a" stroke-width="1.2" opacity="0.7"/>
<path d="M0-350L9-316L7-219L0-202L-7-219L-9-316Z"
fill="url(#steel)" stroke="#34484e" stroke-width="1.3"/>
<path d="M0-341V-211" stroke="#edf0e7" stroke-width="1.5" opacity="0.8"/>
<path d="M-7-216H7L6-184H-6Z"
fill="#4d5d5d" stroke="#1c2c2f" stroke-width="1.2"/>
<path d="M-11-8Q0-14 10-6L11 7Q0 15-11 7Z"
fill="#293637" stroke="#142122" stroke-width="1.4"/>
<path d="M-8-1L8 2M-8 5L7 8" stroke="#77837d" stroke-width="1.2"/>
</g>
</g>
<!-- LAYER 9: the aspis attaches to the fixed left forearm. -->
<g id="anchor-left-forearm"
data-fixed-anchor="354,282"
transform="translate(354 282)">
<g id="hoplite-aspis" data-period="0" opacity="1">
<circle cx="4" cy="5" r="88" fill="#101715" opacity="0.4"/>
<circle r="87" fill="url(#bronze-light)"
stroke="#513923" stroke-width="2"/>
<circle r="77" fill="url(#shield-face)"
stroke="#d0a05a" stroke-width="2"/>
<circle r="69" fill="none" stroke="#c08252"
stroke-width="1.3" opacity="0.45"/>
<path d="M-55-48A73 73 0 0 1 34-65"
fill="none" stroke="#e2a26a" stroke-width="3" opacity="0.35"/>
<path d="M75-38Q88 0 75 38"
fill="none" stroke="#3b2925" stroke-width="4" opacity="0.5"/>
</g>
</g>
</g>
</svg>
</section>
<section class="controls" aria-label="Historical period controls">
<div class="control-heading">
<label for="period-slider">Re-equipment timeline</label>
<output id="scrub-readout" for="period-slider">490 BCE · exact stop</output>
</div>
<input id="period-slider"
type="range"
min="0"
max="2000"
step="1"
value="0"
aria-label="Move continuously between the three equipment periods">
<div class="stop-buttons" aria-label="Jump to an exact period">
<button type="button" data-stop="0" aria-pressed="true">490 BCE · Marathon</button>
<button type="button" data-stop="1" aria-pressed="false">1415 CE · Agincourt</button>
<button type="button" data-stop="2" aria-pressed="false">1615 CE · Osaka</button>
</div>
<p class="control-note">
Drag slowly or use the arrow keys. Stops are equally spaced for comparison,
not scaled by elapsed years; translucent intermediate equipment is an explanatory blend.
</p>
</section>
<article class="placard" aria-label="Current equipment label">
<div class="placard-topline">
<span id="stop-status">Exact historical stop</span>
<span class="catalogue">ARM / RIG-01 / PLATE <span id="plate-number">I</span></span>
</div>
<h2 id="period-title">Athenian hoplite at Marathon</h2>
<dl class="label-grid">
<div class="field">
<dt>Date</dt>
<dd id="label-date"></dd>
</div>
<div class="field">
<dt>Place</dt>
<dd id="label-place"></dd>
</div>
<div class="field wide">
<dt>Equipment</dt>
<dd id="label-equipment"></dd>
</div>
<div class="field wide">
<dt>Materials</dt>
<dd id="label-materials"></dd>
</div>
<div class="field wide">
<dt>Weapon</dt>
<dd id="label-weapon"></dd>
</div>
</dl>
<p id="period-note"></p>
</article>
</main>
<footer>
The body is a reconstruction armature, not three portraits. Equipment opacities
are recalculated directly from the slider on every input.
</footer>
</div>
<script>
(function () {
"use strict";
const periods = [
{
dateShort: "490 BCE",
title: "Athenian hoplite at Marathon",
shortTitle: "Athenian hoplite",
stage: "Plate I · Athenian hoplite",
plate: "I",
date: "490 BCE — the conventional year of the Battle of Marathon.",
place: "Marathon, Attica — an Athenian hoplite.",
placeShort: "Marathon, Attica",
equipment: "Corinthian helmet; bronze bell cuirass; bronze greaves; short chiton; wooden aspis with a painted face and bronze rim.",
equipmentShort: "Corinthian helmet, bell cuirass, greaves, chiton and aspis",
materials: "Bronze armour and rim; iron spearhead; wood, leather and woven cloth.",
weapon: "Dory — wooden shaft, iron leaf-shaped head and bronze sauroter (butt-spike).",
weaponShort: "dory",
note: "Exact-stop reconstruction. The plain shield face is deliberate: Athenian shield devices were not one standard state uniform. The visible bronze point below the hand is the spear’s sauroter."
},
{
dateShort: "1415 CE",
title: "English man-at-arms at Agincourt",
shortTitle: "English man-at-arms",
stage: "Plate II · English man-at-arms",
plate: "II",
date: "25 October 1415 CE — the Battle of Agincourt.",
place: "Azincourt (Agincourt), northern France — an English man-at-arms fighting on foot.",
placeShort: "Azincourt, northern France",
equipment: "Visored bascinet with mail aventail; steel breastplate and fauld; articulated arm and leg harness; mail skirt; sabatons and arming garments.",
equipmentShort: "visored bascinet, mail aventail, plate harness, fauld and mail skirt",
materials: "Shaped steel plate; iron and steel mail; leather straps; padded cloth; ash shaft.",
weapon: "Pollaxe — steel top spike, axe head and rear spike on an ash shaft, with steel langets reinforcing the wood below the head.",
weaponShort: "pollaxe",
note: "Exact-stop reconstruction. No shield is shown: complete plate harness generally made one unnecessary for a man-at-arms on foot. The long steel strips beneath the pollaxe head are its protective langets."
},
{
dateShort: "1615 CE",
title: "Tokugawa-side samurai at Osaka",
shortTitle: "Tokugawa-side samurai",
stage: "Plate III · Samurai at Osaka",
plate: "III",
date: "1615 CE — the Summer Siege of Osaka.",
place: "Osaka, Japan — a samurai reconstruction for the Tokugawa-side army.",
placeShort: "Osaka, Japan",
equipment: "Tōsei-gusoku: zunari kabuto, menpo with throat guard, riveted okegawa-dō, sode, kote, kusazuri, haidate and suneate; sheathed katana at the left waist.",
equipmentShort: "zunari kabuto, menpo, okegawa-dō, sode, kote, kusazuri, haidate and suneate",
materials: "Lacquered iron plates; steel blade and mail; silk lacing; leather and cloth; lacquered wooden spear shaft.",
weapon: "Sugu yari — a straight-bladed spear with a steel head and lacquered wooden shaft. A sheathed katana is also visible as a sidearm.",
weaponShort: "sugu yari and sheathed katana",
note: "Exact-stop reconstruction. The yari is the primary battlefield weapon; the katana is secondary. The haidate’s small plates are sewn into an apron, while the suneate use splints over the lower legs."
}
];
const slider = document.getElementById("period-slider");
const parts = Array.from(
document.querySelectorAll("#armoury-figure [data-period]")
);
const buttons = Array.from(document.querySelectorAll("[data-stop]"));
const ui = {
title: document.getElementById("period-title"),
date: document.getElementById("label-date"),
place: document.getElementById("label-place"),
equipment: document.getElementById("label-equipment"),
materials: document.getElementById("label-materials"),
weapon: document.getElementById("label-weapon"),
note: document.getElementById("period-note"),
status: document.getElementById("stop-status"),
stage: document.getElementById("stage-mode"),
readout: document.getElementById("scrub-readout"),
plate: document.getElementById("plate-number")
};
function percent(value) {
return String(Math.round(value * 10) / 10);
}
function render(rawValue) {
const numeric = Number(rawValue);
const value = Math.max(
0,
Math.min(2000, Math.round(Number.isFinite(numeric) ? numeric : 0))
);
slider.value = String(value);
slider.style.setProperty("--value", String(value / 20) + "%");
const weights = [0, 0, 0];
const exact = value % 1000 === 0;
let ariaValue = "";
if (exact) {
const index = value / 1000;
const p = periods[index];
weights[index] = 1;
ui.title.textContent = p.title;
ui.date.textContent = p.date;
ui.place.textContent = p.place;
ui.equipment.textContent = p.equipment;
ui.materials.textContent = p.materials;
ui.weapon.textContent = p.weapon;
ui.note.textContent = p.note;
ui.status.textContent = "Exact historical stop";
ui.status.classList.remove("transition");
ui.stage.textContent = p.stage;
ui.readout.textContent = p.dateShort + " · exact stop";
ui.plate.textContent = p.plate;
ariaValue = p.title + ", exact stop";
} else {
const aIndex = Math.floor(value / 1000);
const bIndex = aIndex + 1;
const remainder = value - aIndex * 1000;
const u = remainder / 1000;
const a = periods[aIndex];
const b = periods[bIndex];
const towardB = remainder / 10;
const towardA = 100 - towardB;
weights[aIndex] = 1 - u;
weights[bIndex] = u;
ui.title.textContent =
"Between " + a.shortTitle + " and " + b.shortTitle;
ui.date.textContent =
"Between " + a.dateShort + " and " + b.dateShort + "; " +
percent(towardB) + "% along the visual interpolation toward " +
b.dateShort + ". This is not an additional historical date.";
ui.place.textContent =
a.placeShort + " ↔ " + b.placeShort +
" — a composite view, not a claimed intermediate location.";
ui.equipment.textContent =
a.equipmentShort + " (" + percent(towardA) + "% module opacity) + " +
b.equipmentShort + " (" + percent(towardB) +
"% module opacity), attached to the same body.";
ui.materials.textContent =
"Both endpoint palettes are visibly superimposed. A: " +
a.materials + " B: " + b.materials;
ui.weapon.textContent =
a.weaponShort + " (" + percent(towardA) + "% opacity) + " +
b.weaponShort + " (" + percent(towardB) +
"% opacity). Both are drawn during the re-equipment blend.";
ui.note.textContent =
"Transition view: the translucent overlap explains re-equipment and is not a historically valid hybrid. The feet, legs, torso, skull and every attachment coordinate remain fixed.";
ui.status.textContent = "Interpolated view · not a historical ensemble";
ui.status.classList.add("transition");
ui.stage.textContent =
"Re-equipping · " + a.dateShort + " → " + b.dateShort;
ui.readout.textContent =
a.dateShort + " → " + b.dateShort + " · " + percent(towardB) + "%";
ui.plate.textContent = a.plate + "–" + b.plate;
ariaValue =
"Between " + a.title + " and " + b.title + ", " +
percent(towardB) + " percent toward " + b.dateShort;
}
parts.forEach(function (part) {
const index = Number(part.getAttribute("data-period"));
const weight = weights[index];
part.setAttribute("opacity", weight.toFixed(3));
part.setAttribute("visibility", weight === 0 ? "hidden" : "visible");
});
buttons.forEach(function (button, index) {
button.setAttribute(
"aria-pressed",
exact && value === index * 1000 ? "true" : "false"
);
});
slider.setAttribute("aria-valuetext", ariaValue);
}
slider.addEventListener("input", function () {
render(slider.value);
});
buttons.forEach(function (button) {
button.addEventListener("click", function () {
render(Number(button.getAttribute("data-stop")) * 1000);
});
});
render(0);
}());
</script>
</body>
</html>
The 490 BCE Athenian hoplite is the least certain individual reconstruction: Marathon’s date and place are secure, but no source assigns this complete kit to a particular Athenian there, and neither Corinthian helmets nor bronze bell cuirasses were universal. They are plausible older equipment rather than standard issue. For legibility, the aspis is shallower than the real deep bowl, its internal porpax and handgrip are hidden, spear shafts are modestly display-scaled, and the mail rings and Japanese lacing are enlarged.