:root{--ink:#283f31;--muted:#718268;--paper:#f1f2e4;--line:#c8d4b9;--sea:#4f8587;--hub-shadow:0 1px 3px #0009,0 0 12px #0005}
*{box-sizing:border-box}
html,body{max-width:100%;overflow:hidden}
body{margin:0;background:var(--sea);color:var(--ink);font:13px/1.65 system-ui,sans-serif}
a{color:inherit;text-underline-offset:4px}
button,input{font:inherit;color:inherit;border:1px solid #b9caad;border-radius:5px;background:#f6f6e9e8;padding:8px 11px}
button{cursor:pointer}
button:hover{background:#e6edd9}
button:disabled{opacity:.3;cursor:default}
button:focus-visible,input:focus-visible,a:focus-visible{outline:3px solid #b47b43;outline-offset:4px}
[hidden]{display:none!important}
.visually-hidden{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
/* The canvas owns every gesture: pinch and drag must not scroll the page. */
#world{position:fixed;inset:0}
#world canvas{width:100%;height:100%;display:block;touch-action:none;cursor:grab}
#world canvas:active{cursor:grabbing}
/* Scoped to the page header: card-panel.js builds its own card head as a <header> element, and
   a bare element selector pinned that card's Pin and Close buttons to the top of the viewport. */
body>header{position:fixed;z-index:8;inset:0 0 auto;height:76px;display:flex;align-items:center;justify-content:space-between;gap:25px;padding:0 33px;background:linear-gradient(#f1f2e4df,#f1f2e480,transparent);pointer-events:none}
body>header>*{pointer-events:auto}
.brand{font-size:18px;letter-spacing:.14em;text-decoration:none;font-weight:700;white-space:nowrap}
body>header>span{font-size:9px;letter-spacing:.16em;color:#728265}
body>header>a:last-child{font-size:11px;text-decoration:none;white-space:nowrap}
.intro{position:fixed;z-index:3;top:108px;left:35px;width:270px;pointer-events:none}
.intro a{pointer-events:auto}
.eyebrow{font-size:9px;letter-spacing:.14em;text-transform:uppercase;color:#e9f0e4;text-shadow:var(--hub-shadow)}
h1{font:normal 43px/1.06 Georgia,serif;letter-spacing:-.045em;margin:13px 0 17px;color:#f7f8ee;text-shadow:var(--hub-shadow)}
h1 em{font-weight:400;color:#d9e5c6}
.intro>p{font-size:11px;color:#eef2e6;line-height:1.75;max-width:255px;text-shadow:var(--hub-shadow)}

/* Sector labels ride the sector centroid. Only a small name tag is always on; the full card with
   the per-class model chips is hover, focus, or tap only, so seven cards do not cover the map. */
#sector-labels,#island-labels{position:fixed;inset:0;z-index:2;pointer-events:none}
.sector-label{position:absolute;transform:translate(-50%,-50%);pointer-events:auto;opacity:1;transition:opacity 620ms ease;background:none;border:0;padding:0;margin:0;font:inherit;color:#526b42;text-align:center;line-height:1.3;cursor:pointer}
.sector-tag{display:block;font-size:11px;font-weight:650;letter-spacing:.01em;white-space:nowrap;color:var(--sector-tag-ink,#4a6340);text-shadow:0 1px 2px #eff2dfe0,0 0 7px #eff2dfcc;transition:opacity 120ms ease}
.sector-label:focus-visible{outline:2px solid #7f9853;outline-offset:3px;border-radius:4px}
.sector-card{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);z-index:1;opacity:0;visibility:hidden;transition:opacity 120ms ease,visibility 0s linear 120ms;background:#eff2dfd6;border:1px solid #c3d1b094;border-radius:5px;padding:5px 8px;min-width:64px;max-width:150px;box-shadow:0 3px 14px #43593409}
.sector-label.is-open .sector-card{opacity:1;visibility:visible;transition:opacity 120ms ease}
.sector-label.is-open .sector-tag{opacity:0}
.sector-card b{display:block;font-size:9px;font-weight:650}
.sector-card small{display:block;font-size:6.5px;line-height:1.4;color:#7b8b6c;margin-top:1px}
.sector-card .chips{display:flex;gap:3px;justify-content:center;flex-wrap:wrap;margin-top:4px}
.chip{display:inline-block;font-style:normal;font-size:6px;line-height:1.2;padding:2px 4px;border-radius:8px;border:1px solid var(--sector-accent,#9fb08c);background:#f7f8ec;color:#4a6340;max-width:60px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.chip[data-empty=true]{border-style:dashed;color:#9aa78d;background:transparent}
.sector-label[aria-pressed=true] .sector-tag{color:var(--sector-tag-ink,#3d5533);text-decoration:underline;text-underline-offset:3px}
.sector-label[aria-pressed=true] .sector-card{background:#e6ebd5;border-color:var(--sector-accent,#799361);box-shadow:0 0 0 2px #7f985344}
.sector-label[data-fogged=true] .sector-tag,.sector-label[data-fogged=true] .sector-card{color:#829276}
.sector-label[data-fogged=true] .sector-card{border-style:dashed}
.sector-label[data-fogged=true] .chip{border-style:dashed}
@media(prefers-reduced-motion:reduce){.sector-tag,.sector-card,.sector-label.is-open .sector-card{transition-duration:0s}}
.island-label{position:absolute;transform:translate(-50%,-140%);font-size:7px;letter-spacing:.06em;color:#33422c;background:#f4f7ebe8;border:1px solid #3f5236;border-radius:4px;padding:2px 5px;text-shadow:none;max-width:120px;overflow:hidden;box-sizing:border-box}
.island-label b{display:block;font-weight:600;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.island-metric{display:block;font-size:5.5px;font-weight:400;letter-spacing:.08em;opacity:.78}
.island-label[data-kind=moat]{color:#6b3f22;border-color:#7a4b2a;background:#fdf0e4e8}
.island-label[data-revealed=false]{color:#5d6a63;border-color:#63736b;background:#eceff0e0;font-style:italic;letter-spacing:.12em;text-transform:uppercase}
.island-metric{display:block;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* The rules panel steps aside once the map is the subject; this button is the way back. */
.intro{transition:opacity .25s ease}
#rules-toggle{position:fixed;z-index:4;top:108px;left:35px;pointer-events:auto;font:inherit;font-size:9px;letter-spacing:.1em;text-transform:uppercase;color:#3f5236;background:#eff2dfd6;border:1px solid #7a8f66;border-radius:5px;padding:5px 10px;cursor:pointer}
#rules-toggle:hover{background:#f2f5e7}
#rules-toggle[aria-pressed=true]{background:#e6ebd5;border-color:#799361}

/* The scrubber sits on a bottom-centre bar so it never covers the centre island. White with a
   soft shadow rather than a paper card, because it floats over the sea. */
#time-hub{position:fixed;z-index:6;left:50%;bottom:24px;transform:translateX(-50%);display:flex;flex-direction:column-reverse;align-items:center;gap:6px;color:#fff;text-shadow:var(--hub-shadow);pointer-events:none}
#time-hub>*{pointer-events:auto}
.hub-row{display:flex;align-items:center;gap:6px;border:1.5px solid #fff;border-radius:999px;padding:4px 6px;background:transparent;box-shadow:var(--hub-shadow),inset 0 0 0 1px #0002}
#time-hub button{background:transparent;border:1px solid #fff;color:#fff;border-radius:50%;width:30px;height:30px;padding:0;font-size:15px;line-height:1;text-shadow:var(--hub-shadow);box-shadow:0 1px 3px #0006}
#time-hub button:hover{background:#ffffff26}
#time-hub button:disabled{opacity:.35}
#play{font-size:11px;margin-left:2px}
#play[aria-pressed=true]{background:#ffffff33}
#date{background:transparent;border:0;color:#fff;font:12px/1 ui-monospace,monospace;padding:6px 4px;min-width:128px;text-align:center;color-scheme:dark}
#date::-webkit-calendar-picker-indicator{filter:invert(1);opacity:.85;cursor:pointer}
#milestone-label{font-size:10px;letter-spacing:.04em;max-width:280px;text-align:center;line-height:1.4;color:#fff;background:#0000;padding:0 8px}

#view-toggle{position:fixed;z-index:7;right:28px;bottom:24px;display:flex;gap:0;border:1px solid #c3d1b0;border-radius:999px;background:#eff2dfe0;padding:3px;backdrop-filter:blur(6px)}
#view-toggle button{border:0;background:transparent;border-radius:999px;padding:7px 14px;font-size:10px;letter-spacing:.06em;text-transform:uppercase;color:#5d7350}
#view-toggle button[aria-pressed=true]{background:#48633c;color:#fff}

#error{position:fixed;z-index:15;top:36%;left:34%;right:20%;background:var(--paper);padding:25px;border:1px solid var(--line);border-radius:6px;font-size:12px}

@media(max-height:850px) and (min-width:721px){.intro{top:92px}#rules-toggle{top:92px}.intro h1{font-size:37px}.intro>p{font-size:10px}}
@media(max-width:1100px){body>header>span{display:none}.intro{left:24px;width:220px}#rules-toggle{left:24px}.intro h1{font-size:36px}.intro>p{font-size:10px;max-width:215px}.sector-card{min-width:56px;padding:4px 6px}.sector-tag{font-size:10px}.sector-card b{font-size:8px}.chip{max-width:48px}#view-toggle{right:20px;bottom:20px}}
@media(max-width:720px){#rules-toggle{top:74px;left:16px;font-size:8px;padding:4px 8px}.island-label{max-width:96px}body>header{height:58px;padding:0 17px}.brand{font-size:15px}body>header>a:last-child{font-size:9px}.intro{top:74px;left:16px;width:200px}.intro>.eyebrow{font-size:7px}.intro h1{font-size:28px;margin:8px 0}.intro h1 br{display:none}.intro>p{display:none}.sector-card{min-width:46px;padding:3px 5px;max-width:92px}.sector-tag{font-size:9px}.sector-card b{font-size:7px}.sector-card small{font-size:6px;margin-top:0}.chip{font-size:5.5px;max-width:34px;padding:1px 3px}.hub-row{padding:3px 4px;gap:4px}#time-hub button{width:26px;height:26px;font-size:13px}#date{font-size:11px;min-width:112px}#milestone-label{font-size:9px;max-width:220px}#time-hub{bottom:64px}#view-toggle{right:12px;bottom:14px}#view-toggle button{padding:6px 11px;font-size:9px}#error{left:8%;right:8%;top:38%}}
@media(prefers-reduced-motion:reduce){*{scroll-behavior:auto!important}}

/* Cinematic opening. The vignette is one fixed radial sheet: during the title it is a tight dark
   ring that leaves only the AlexNet island at the centre lit, and after the lift it stays on as a
   soft edge darkening that deepens at street zoom, where the frame is close and needs a border. */
#vignette{position:fixed;inset:0;z-index:5;pointer-events:none;opacity:0;
 background:radial-gradient(circle at 50% 50%,#0000 0%,#0000 30%,#03110f59 64%,#020c0b8c 100%);
 transition:opacity .5s ease,background-position .5s ease}
#vignette.is-intro{background:radial-gradient(circle at 50% 48%,#0000 0%,#00000000 7%,#031110d9 34%,#010908fa 72%)}
body.is-intro header,body.is-intro .intro,body.is-intro #view-toggle,body.is-intro #time-hub,body.is-intro #rules-toggle{opacity:0;transition:opacity .6s ease}
/* The chapters and the showcase run on after the opening lifts. The hero copy and the rules
   button sit over the map, so they stay down for the whole cinematic run, not just the title. */
body.is-cinematic .intro,body.is-cinematic #rules-toggle{opacity:0;transition:opacity .6s ease}
#title-card{position:fixed;z-index:9;left:50%;top:50%;transform:translate(-50%,-50%);width:min(560px,86vw);text-align:center;
 color:#f4f6ea;pointer-events:none;opacity:0;transition:opacity .8s ease}
#title-card.is-on{opacity:1}
#title-card h2{font:normal 54px/1 Georgia,serif;letter-spacing:.22em;margin:0 0 18px;text-indent:.22em;text-shadow:0 2px 24px #000c}
#title-card .title-sub{font:italic 17px/1.5 Georgia,serif;letter-spacing:.04em;margin:0 0 26px;color:#dfe7d2;text-shadow:0 1px 12px #000a}
#title-card .title-line{font:normal 13px/1.6 Georgia,serif;letter-spacing:.16em;text-transform:uppercase;margin:0;color:#bfcdb4;text-shadow:0 1px 10px #000a}
/* Chapter cards sit in the lower third so the map keeps the frame; small serif on a paper chip. */
#chapter-card{position:fixed;z-index:9;left:50%;bottom:21%;transform:translate(-50%,8px);width:min(360px,74vw);
 background:#f1f2e4ec;border:1px solid #b9caad;border-radius:5px;padding:13px 17px 11px;text-align:center;pointer-events:none;
 box-shadow:0 6px 28px #0a1a1855;opacity:0;transition:opacity .55s ease,transform .55s ease}
#chapter-card.is-on{opacity:1;transform:translate(-50%,0)}
#chapter-card .chapter-line{font:normal 17px/1.35 Georgia,serif;color:#283f31;margin:0 0 7px}
#chapter-card .chapter-source{display:block;font:normal 8px/1 Georgia,serif;letter-spacing:.18em;text-transform:uppercase;color:#7c8c6d}
@media(max-width:720px){#title-card h2{font-size:34px}#title-card .title-sub{font-size:14px}#chapter-card{bottom:26%}#chapter-card .chapter-line{font-size:15px}}
@media(prefers-reduced-motion:reduce){#vignette,#title-card,#chapter-card{transition-duration:0s}}

/* Card panel host. A fixed inset layer keeps the panel's own absolute left/top in client
   pixels, which is the coordinate space card-panel.js computes anchors in. */
#card-root{position:fixed;inset:0;z-index:6;pointer-events:none}
#card-root .cp-panel{pointer-events:auto}

/* Showcase captions ride the chapter card slot but carry no source domain, because a beat is
   a camera move rather than a dated claim. */
#chapter-card.is-showcase .chapter-source{display:none}
/* A card taller than the viewport scrolls inside itself rather than pushing its chart off screen. */
/* A sector under terra incognita carries no tag; it fades in on the month it is revealed. */
.sector-label[data-fogged=true]{opacity:0;pointer-events:none}
@media(prefers-reduced-motion:reduce){.sector-label{transition-duration:0s}}

#card-root .cp-panel{max-height:calc(100vh - 16px);overflow-y:auto}
/* The selection ring on the open sector card is the accent, so a fogged sector reads muted
   while the one under the pointer reads in its own culture colour. */
.sector-label.is-open .sector-card{border-color:var(--sector-accent,#c3d1b094)}

/* Card panel layout overrides for the atlas page. card-panel.js owns the DOM order, so the
   legend is moved to the footer with flex order rather than by rebuilding the panel. */
#card-root .cp-panel{display:flex;flex-direction:column;gap:0;min-height:0}
#card-root .cp-head{order:1;flex:0 0 auto}
#card-root .cp-body{order:2;flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain}
#card-root .cp-chart{order:3;flex:0 0 auto}
/* Once per session, one line under the card rather than a second box stacked over it. */
#card-root .cp-legend{order:4;flex:0 0 auto;margin:8px 0 0;padding:6px 0 0;background:none;
 border:0;border-top:1px solid var(--cp-line);border-radius:0;display:flex;flex-wrap:wrap;
 align-items:baseline;gap:4px 8px;font-size:11px;line-height:1.35}
#card-root .cp-legend-line{display:inline;margin:0;color:var(--cp-ink-muted)}
#card-root .cp-legend-line:last-of-type{margin:0;color:var(--cp-ink-muted)}
#card-root .cp-legend-dismiss{margin-left:auto;flex:0 0 auto}

/* The chart needs real height to carry two axes, and its captions name what the ticks measure. */
#card-root .cp-chart-figure{margin:0;position:relative;padding:14px 0 2px}
#card-root .cp-chart-figure svg{display:block;width:100%;height:auto;min-height:200px}
#card-root .cp-axis{position:absolute;font-size:9px;letter-spacing:.02em;color:var(--cp-ink-secondary)}
#card-root .cp-axis-left{top:0;left:0}
#card-root .cp-axis-right{top:0;right:0}
#card-root .cp-axis-x{position:static;display:block;text-align:center;margin-top:2px}

/* One channel per line: the Basis value is a joined list, not a sentence. */
#card-root .mc-line-stacked{flex-wrap:wrap}
#card-root .mc-basis-channel{display:block;text-align:right}

/* The mute toggle keeps its own slot under the header instead of crowding the scrubber. */
#mute-slot{position:fixed;z-index:7;top:88px;right:28px;pointer-events:auto;display:flex;gap:8px}
#mute-slot button{width:32px;height:32px;border-radius:999px;border:1px solid #c3d1b0;
 background:#eff2dfe0;backdrop-filter:blur(6px);font-size:14px;line-height:1;cursor:pointer;
 display:flex;align-items:center;justify-content:center}
/* The cycle toggle sits beside the mute control; pressed means the moon holds the date. */
#mute-slot #cycle[aria-pressed="true"]{background:#26333fe0;border-color:#9fb4d6}
@media(max-width:720px){#mute-slot{top:66px;right:12px;gap:6px}}

/* The grab handle only exists in sheet mode; on a pointer device the card has a close button. */
.cp-handle{display:none}

/* Portrait: the card opens as a peek at 30 percent and expands to 55 percent. The peek leaves the
   map above it tappable, which is what lets a second tap on the same target reach the map. */
@media(max-width:480px){
 #card-root .cp-panel,#card-root .cp-panel.cp-sheet{height:30vh;max-height:30vh;padding-top:0}
 #card-root .cp-panel.is-expanded{height:55vh;max-height:55vh}
 #card-root .cp-chart-figure svg{min-height:170px}
 .cp-handle{display:block;order:0;flex:0 0 auto;width:100%;background:none;border:0;
  padding:8px 0 6px;margin:0;cursor:pointer;touch-action:none}
 .cp-handle-grip{display:block;width:36px;height:4px;margin:0 auto;border-radius:999px;
  background:var(--cp-line)}
 .cp-handle:focus-visible{outline:2px solid var(--cp-accent);outline-offset:2px;border-radius:6px}
 /* At the peek the card is an identity plus its two headline numbers, nothing more. */
 #card-root .cp-panel.cp-sheet:not(.is-expanded) .mc-line[data-peek="0"],
 #card-root .cp-panel.cp-sheet:not(.is-expanded) .mc-note,
 #card-root .cp-panel.cp-sheet:not(.is-expanded) .mc-sources,
 #card-root .cp-panel.cp-sheet:not(.is-expanded) .cp-chart,
 #card-root .cp-panel.cp-sheet:not(.is-expanded) .cp-legend{display:none}
}

/* With the sheet open the bottom controls sit above whichever height it is showing. */
@media(max-width:480px){
 body.has-card-sheet #time-hub{bottom:calc(30vh + 54px)}
 body.has-card-sheet #view-toggle{bottom:calc(30vh + 12px)}
 body.has-card-expanded #time-hub{bottom:calc(55vh + 54px)}
 body.has-card-expanded #view-toggle{bottom:calc(55vh + 12px)}
}
