@import url('tokens.css');
*{box-sizing:border-box}html,body{margin:0;overflow-x:clip;letter-spacing:0}html{height:100%;background:var(--color-paper)}body{height:100dvh;overflow-y:hidden;color:var(--color-ink);font-family:var(--font-body);font-size:16px;display:flex;flex-direction:column}button,a{-webkit-tap-highlight-color:transparent}button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:pointer}a{color:inherit;text-decoration:none}img{display:block;max-width:100%;user-select:none}h1,h2,p,figure{margin:0}h1,h2{font-weight:400;letter-spacing:0}button,a{touch-action:manipulation}button:disabled{opacity:.25;cursor:default}[hidden]{display:none!important}svg{width:20px;height:20px;flex:none}button:focus-visible,a:focus-visible,[tabindex]:focus-visible{outline:2px solid var(--color-focus);outline-offset:5px}::selection{background:var(--color-accent);color:var(--color-paper)}
.sr-only,.skip-link:not(:focus){position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.skip-link:focus{position:fixed;z-index:100;top:10px;left:10px;padding:14px;background:var(--color-paper)}
.masthead{height:88px;flex:none;display:grid;grid-template-columns:1fr auto 1fr;align-items:center;padding:0 var(--gutter);z-index:5;background:var(--color-paper)}.header-link{min-height:44px;display:flex;align-items:center;font-size:15px;width:max-content}.header-link:last-child{justify-self:end}.header-link[aria-current=page]{text-decoration:underline;text-underline-offset:6px}.brand{display:flex;align-items:center;justify-content:center;min-height:44px;transition:opacity var(--dur-medium) var(--ease-out)}.brand img{width:74px;height:auto}body[data-view=home] .brand{visibility:hidden;opacity:0}.icon-button{display:grid;place-items:center;width:44px;height:44px;flex:none;border-radius:50%;transition:background var(--dur-short),opacity var(--dur-short)}
main{min-height:0;flex:1;outline:none}.view{height:100%;min-height:0}.view-heading{display:flex;align-items:center;justify-content:space-between;padding:12px var(--gutter) 32px;gap:24px}.view-heading h1,.chapter-heading h1{font:400 52px/1.05 var(--font-display)}.back-link{display:inline-flex;gap:12px;align-items:center;min-height:44px;font-size:14px;width:max-content}.home-view{display:grid;grid-template-rows:minmax(0,1fr) auto;gap:20px;padding-bottom:32px}.home-center{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:36px;min-height:0;padding:12px 24px 24px}.home-center h1{line-height:0;min-height:0}.hero-logo{width:min(380px,58vw);height:auto;max-height:28dvh}.project-link{display:flex;align-items:center;gap:32px;min-height:48px;border-bottom:1px solid var(--color-ink);font-size:14px;flex:none}.project-link svg{transition:transform var(--dur-medium) var(--ease-out)}
.rail-wrap{position:relative;min-width:0}.home-rail{width:100%;overflow-x:auto;overflow-y:hidden;scrollbar-width:none;overscroll-behavior:contain;touch-action:pan-x;outline-offset:-3px!important}.home-rail::-webkit-scrollbar{display:none}.rail-track{display:flex;width:max-content;gap:18px;align-items:center}.rail-cycle{display:flex;gap:18px;flex:none}.rail-photo{width:clamp(170px,23dvh,260px);height:clamp(170px,23dvh,260px);flex:none;display:grid;place-items:center;overflow:hidden;cursor:zoom-in}.rail-photo img{width:100%;height:100%;object-fit:contain}.rail-pause{position:absolute;right:var(--gutter);bottom:12px;background:var(--color-glass);backdrop-filter:blur(14px);border:1px solid var(--color-rule);z-index:2}
.rail-photo img{object-fit:cover}.rail-photo[data-id="074"] img,.rail-photo[data-id="178"] img{object-fit:contain}
.projects-view{display:grid;grid-template-rows:auto minmax(0,1fr) auto;padding-bottom:18px}.chapter-index{display:flex;gap:24px;padding:0 var(--gutter);min-height:0}.chapter-link{flex:1;min-width:0;display:flex;flex-direction:column;gap:16px;outline-offset:7px!important;user-select:none}.cover-media{position:relative;min-height:0;flex:1;overflow:hidden}.cover-media img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}.cover-media img.cover-next{opacity:0;transition:opacity 1400ms var(--ease-out)}.cover-media img.cover-next.is-visible{opacity:1}.cover-label{display:flex;align-items:center;justify-content:space-between;min-height:52px;border-top:1px solid var(--color-rule);padding-top:12px;font:400 36px/1 var(--font-display);flex:none}.cover-label svg{width:21px}.projects-back{margin:20px var(--gutter) 0}
.chapter-view{display:grid;grid-template-rows:auto minmax(0,1fr) auto}.chapter-heading{display:flex;align-items:center;justify-content:space-between;padding:12px var(--gutter) 32px;gap:24px}.chapter-nav{display:flex;gap:25px;font:400 22px var(--font-display)}.chapter-nav a{display:flex;align-items:center;min-height:44px;color:var(--color-muted)}.chapter-nav a[aria-current]{color:var(--color-ink);text-decoration:underline;text-underline-offset:7px}.gallery{display:flex;align-items:center;gap:100px;overflow-x:auto;overflow-y:hidden;height:100%;padding:8px var(--gutter);scrollbar-width:none;overscroll-behavior:contain;min-height:0}.gallery::-webkit-scrollbar{display:none}.gallery-group{display:flex;flex:none;align-items:center;gap:24px;height:100%}.photo-button{display:block;border:0;background:none;padding:0;cursor:zoom-in;flex:none;position:relative}.gallery .photo-button{width:calc(var(--gallery-height)*var(--ratio));height:var(--gallery-height);max-width:82vw;max-height:100%}.photo-button img{width:100%;height:100%;object-fit:contain}.gallery-group--pair .photo-button{height:calc(var(--gallery-height)*.78);width:calc(var(--gallery-height)*.78*var(--ratio));max-width:55vw}.gallery-footer{display:flex;align-items:center;justify-content:space-between;padding:18px var(--gutter) 20px}.gallery-arrows{display:flex;gap:8px}
.history-view{display:grid;grid-template-columns:140px minmax(0,1fr);grid-template-rows:auto minmax(0,1fr)}.history-heading{grid-column:1/-1;padding-bottom:24px}.history-modes{display:flex;gap:24px}.history-modes button{min-height:44px;font-size:14px;color:var(--color-muted)}.history-modes button[aria-pressed=true]{color:var(--color-ink);text-decoration:underline;text-underline-offset:7px}.history-years{display:flex;flex-direction:column;gap:8px;align-self:start;padding:24px 0 0 var(--gutter)}.history-years button{font:13px var(--font-mono);display:flex;align-items:center;gap:12px;min-height:44px;color:var(--color-muted);text-align:left}.history-years button::before{content:'';width:8px;height:1px;background:var(--color-rule);transition:width var(--dur-medium) var(--ease-out),background var(--dur-medium)}.history-years button[aria-current=true]{color:var(--color-ink)}.history-years button[aria-current=true]::before{width:24px;background:var(--color-accent)}.history-stream{overflow-y:auto;overscroll-behavior:contain;scrollbar-width:thin;scrollbar-color:var(--color-rule) transparent;padding:0 var(--gutter) 80px 28px;scroll-padding-top:24px}.history-year{display:grid;grid-template-columns:150px minmax(0,1fr);gap:32px;padding:32px 0 72px;border-top:1px solid var(--color-rule)}.history-year h2{font:16px var(--font-mono);position:sticky;top:24px;height:max-content;padding-top:5px}.year-photos{display:flex;flex-direction:column;align-items:center;gap:100px}.year-photos .photo-button{width:100%;height:min(66dvh,760px)}.history-stream[data-mode=grid] .history-year{grid-template-columns:80px minmax(0,1fr)}.history-stream[data-mode=grid] .year-photos{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:36px 28px;align-items:center}.history-stream[data-mode=grid] .photo-button{width:100%;height:180px}
.about-view{overflow-y:auto;overscroll-behavior:contain;padding-bottom:64px}.about-content{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:64px 100px;padding:24px var(--gutter) 0;max-width:1600px;margin:auto}.about-intro h2{font:48px/1.05 var(--font-display);margin-bottom:36px}.about-intro p{font-size:17px;line-height:1.8}.about-intro .ko{margin-top:20px;font-size:14px}.ko{color:var(--color-muted);font-family:var(--font-body);font-size:13px;line-height:1.8}.about-facts{margin:0}.about-facts>div{display:grid;grid-template-columns:100px minmax(0,1fr);gap:24px;border-top:1px solid var(--color-rule);padding:20px 0}.about-facts dt{font-size:13px;line-height:1.7}.about-facts dt .ko{display:block;font-size:12px}.about-facts dd{margin:0;font-size:14px;line-height:1.8}.about-facts dd .ko{margin-top:6px}.about-facts a{min-height:44px;display:inline-flex;gap:12px;align-items:center;overflow-wrap:anywhere}.mono{font-family:var(--font-mono);font-size:13px!important}.about-map{grid-column:1/-1}.about-map iframe{width:100%;height:360px;border:0;background:var(--color-surface);display:block}.about-map>a{display:flex;align-items:center;justify-content:flex-end;gap:16px;min-height:60px;font-size:14px}
.lightbox{position:fixed;inset:0;width:100%;max-width:none;height:100%;max-height:none;padding:0;border:0;background:transparent;overflow:hidden;color:var(--color-paper)}.lightbox::backdrop{background:var(--color-overlay)}.lightbox[open]{display:block}.zoom-stage{position:absolute;inset:60px 84px;display:flex;align-items:center;justify-content:center;pointer-events:none}.zoom-stage img{width:auto;height:auto;max-width:100%;max-height:100%;object-fit:contain;pointer-events:auto;cursor:zoom-out}.zoom-close,.zoom-prev,.zoom-next{position:absolute;background:var(--color-dark-glass);backdrop-filter:blur(14px);z-index:3}.zoom-close{top:20px;right:24px}.zoom-prev{left:20px;top:calc(50% - 22px)}.zoom-next{right:20px;top:calc(50% - 22px)}#zoom-retry{position:absolute;bottom:12px;pointer-events:auto;background:var(--color-dark-glass)}.zoom-source{opacity:0!important}.zoom-open{position:fixed;width:100%}
::view-transition{pointer-events:none}::view-transition-group(*){animation-duration:700ms;animation-timing-function:var(--ease-out)}::view-transition-old(root){animation:route-out 350ms ease both}::view-transition-new(root){animation:route-in 700ms var(--ease-out) both}@keyframes route-out{to{opacity:0}}@keyframes route-in{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
.lightbox[open]::backdrop{animation:dim-in 650ms var(--ease-out) both}.lightbox.is-closing::backdrop{animation:dim-out 500ms var(--ease-out) both}@keyframes dim-in{from{opacity:0}to{opacity:1}}@keyframes dim-out{from{opacity:1}to{opacity:0}}
@media(hover:hover) and (pointer:fine){.header-link:hover,.back-link:hover{color:var(--color-accent)}.icon-button:hover:not(:disabled){background:var(--color-surface);color:var(--color-ink)}.project-link:hover svg{transform:translate(3px,-3px)}.photo-button:hover,.rail-photo:hover{cursor:zoom-in}}
@media(min-width:1600px){.home-center{gap:48px}.hero-logo{width:460px}.chapter-index{gap:32px}.history-stream[data-mode=grid] .year-photos{grid-template-columns:repeat(5,minmax(0,1fr))}}
@media(max-width:900px){:root{--gutter:22px}.masthead{height:72px}.view-heading{padding-top:8px;padding-bottom:24px}.view-heading h1,.chapter-heading h1{font-size:42px}.home-view{padding-bottom:max(22px,env(safe-area-inset-bottom));gap:16px}.home-center{gap:32px}.hero-logo{width:min(380px,67vw);max-height:25dvh}.rail-photo{width:180px;height:180px}.rail-track,.rail-cycle{gap:14px}.chapter-index{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:22px 18px}.chapter-link{min-height:0;gap:9px}.cover-label{font-size:28px;min-height:40px;padding-top:8px}.cover-label svg{width:18px}.projects-view{padding-bottom:12px}.projects-back{margin-top:14px}.chapter-heading{padding:8px var(--gutter) 20px;flex-wrap:wrap;gap:8px}.chapter-nav{gap:20px;font-size:20px}.gallery{display:block;overflow-x:clip;overflow-y:auto;padding:10px var(--gutter) 48px;scrollbar-width:thin}.gallery-group{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));height:auto;gap:18px;margin-bottom:56px;align-items:center}.gallery-group:not(.gallery-group--pair){grid-template-columns:minmax(0,1fr)}.gallery .photo-button,.gallery-group--pair .photo-button{width:100%;height:auto;max-width:none;max-height:none}.gallery .photo-button img{height:auto;max-height:74dvh}.gallery-footer{padding:10px var(--gutter) 12px}.gallery-arrows{display:none}.history-view{grid-template-columns:minmax(0,1fr);grid-template-rows:auto auto minmax(0,1fr)}.history-heading{padding-bottom:12px}.history-years{flex-direction:row;gap:26px;padding:0 var(--gutter) 12px}.history-years button{gap:7px}.history-years button::before{display:none}.history-years button[aria-current=true]{text-decoration:underline;text-decoration-color:var(--color-accent);text-underline-offset:6px}.history-stream{padding:0 var(--gutter) 50px}.history-year{grid-template-columns:65px minmax(0,1fr);gap:16px;padding:24px 0 48px}.history-year h2{font-size:13px}.year-photos{gap:48px}.year-photos .photo-button{height:56dvh}.history-stream[data-mode=grid] .history-year{grid-template-columns:minmax(0,1fr);gap:20px}.history-stream[data-mode=grid] .history-year h2{position:static}.history-stream[data-mode=grid] .year-photos{grid-template-columns:repeat(3,minmax(0,1fr));gap:24px 18px}.history-stream[data-mode=grid] .photo-button{height:150px}.about-content{gap:40px}.about-intro h2{font-size:40px}.about-facts>div{grid-template-columns:80px minmax(0,1fr);gap:12px}.about-map iframe{height:320px}}
@media(max-width:600px){.masthead{height:64px}.header-link{font-size:14px}.brand img{width:62px}.home-center{gap:30px;padding-bottom:34px}.hero-logo{width:72vw;max-height:24dvh}.home-view{gap:0;padding-bottom:26px}.rail-photo{width:160px;height:160px}.rail-pause{right:16px;bottom:8px}.project-link{font-size:13px;gap:25px}.view-heading h1,.chapter-heading h1{font-size:38px}.view-heading{padding-bottom:20px}.chapter-nav{font-size:18px;gap:18px;justify-content:space-between;width:100%}.chapter-heading{gap:12px}.projects-view .view-heading{padding-bottom:18px}.cover-label{font-size:26px}.projects-back{margin-top:10px}.chapter-index{gap:22px 16px}.history-modes{gap:18px}.history-modes button{font-size:13px}.history-heading{padding-bottom:8px}.history-years{justify-content:space-between;gap:12px;padding-bottom:8px}.history-year{grid-template-columns:minmax(0,1fr);gap:20px}.history-year h2{position:static}.year-photos{gap:60px}.year-photos .photo-button{height:50dvh}.history-stream[data-mode=grid] .year-photos{grid-template-columns:repeat(2,minmax(0,1fr));gap:24px 18px}.history-stream[data-mode=grid] .photo-button{height:175px}.about-content{grid-template-columns:minmax(0,1fr);gap:40px;padding-top:16px}.about-intro h2{font-size:42px;margin-bottom:28px}.about-intro p{font-size:15px}.about-map iframe{height:300px}.zoom-stage{inset:70px 16px 86px}.zoom-close{right:12px;top:12px}.zoom-prev{left:calc(50% - 54px);top:auto;bottom:20px}.zoom-next{right:calc(50% - 54px);top:auto;bottom:20px}}
@media(max-height:600px){.masthead{height:60px}.home-center{flex-direction:row;gap:60px;padding:10px 24px 20px}.hero-logo{width:230px;max-height:24dvh}.home-view{padding-bottom:18px}.rail-photo{width:120px;height:120px}.projects-view .view-heading{padding-bottom:10px}.projects-view .view-heading h1{font-size:32px}.cover-label{font-size:24px;min-height:34px}.projects-back{margin-top:8px}.chapter-index{gap:12px}}
@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation-duration:.01ms!important;transition-duration:.01ms!important;scroll-behavior:auto!important}::view-transition-group(*),::view-transition-old(*),::view-transition-new(*){animation:none!important}}
@media(prefers-reduced-transparency:reduce){.rail-pause{background:var(--color-paper)}.zoom-close,.zoom-prev,.zoom-next{background:var(--color-ink)}}
@media(prefers-contrast:more){:root{--color-muted:#444;--color-rule:#777}.icon-button{border:1px solid currentColor}}

/* Continuous photo ribbon: equal height, original aspect ratios, no artificial crops. */
.home-view{padding-bottom:0;gap:0}
.hero-logo{width:min(190px,29vw);max-height:14dvh}
.rail-track,.rail-cycle{gap:0;align-items:stretch}
.rail-photo{height:clamp(210px,32dvh,360px);width:auto;aspect-ratio:var(--ratio);margin:0}
.rail-photo img{object-fit:cover;object-position:center}
.home-center{padding-bottom:24px}
.illustrated-map{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:end;gap:32px;border-top:1px solid var(--color-rule);padding-top:40px}
.illustrated-map img{width:100%;height:500px;object-fit:contain}
.illustrated-map figcaption{display:flex;flex-direction:column;gap:8px;padding-bottom:20px;font:32px var(--font-display)}
.about-map>a{justify-content:flex-end}
@media(min-width:1600px){.hero-logo{width:230px}}
@media(max-width:900px){.hero-logo{width:min(190px,33.5vw);max-height:12.5dvh}.rail-photo{height:clamp(180px,30dvh,300px)}.illustrated-map{gap:20px}.illustrated-map img{height:420px}}
@media(max-width:600px){.hero-logo{width:36vw;max-height:12dvh}.rail-photo{height:clamp(180px,31dvh,270px)}.home-center{padding-bottom:34px}.illustrated-map{grid-template-columns:minmax(0,1fr);gap:12px}.illustrated-map img{height:auto;max-height:440px}.illustrated-map figcaption{font-size:28px;padding-bottom:0}}
@media(max-height:600px){.hero-logo{width:115px;max-height:12dvh}.rail-photo{height:clamp(100px,33dvh,180px)}.home-center{padding-bottom:16px}}

/* History keeps the surrounding photographs in view, with a separate small index. */
.history-view{grid-template-columns:100px minmax(100px,.65fr) minmax(0,1.35fr);grid-template-rows:auto auto minmax(0,1fr);position:relative}
.history-heading{grid-column:1/-1;grid-row:1;padding-bottom:8px}
.history-years{grid-column:1/-1;grid-row:2;flex-direction:row;justify-content:center;gap:44px;padding:0 var(--gutter) 20px;align-self:stretch}
.history-years button{min-width:44px;justify-content:center;font-size:12px;text-align:center;position:relative}
.history-years button::before{display:none}
.history-years button[aria-current=true]{text-decoration:underline;text-decoration-color:var(--color-accent);text-underline-offset:8px}
.history-index{grid-column:1;grid-row:3;display:flex;flex-direction:column;min-height:0;align-items:center;padding:16px 0 16px var(--gutter);gap:16px}
#history-timeline{position:relative;overflow-y:auto;overflow-x:hidden;scrollbar-width:none;min-height:0;width:60px;padding:8px;flex:1;overscroll-behavior:contain}
#history-timeline button{position:relative;width:44px;height:48px;display:flex;align-items:center;justify-content:center;opacity:.35;transition:opacity 600ms var(--ease-out);flex:none}
#history-timeline button img{width:40px;height:32px;object-fit:cover}
#history-timeline button[aria-current=true]{opacity:1}
#history-timeline button[aria-current=true]::before{content:'';position:absolute;left:-7px;width:2px;height:24px;background:var(--color-accent)}
#history-timeline button:focus-visible{opacity:1;outline-offset:1px}
.history-current-year{grid-column:2;grid-row:3;align-self:center;justify-self:center;padding-bottom:40px;font:32px/1 var(--font-mono)}
.history-stream{grid-column:3;grid-row:3;position:relative;min-height:0;overflow-x:hidden;overflow-y:auto;padding:0;margin:0 var(--gutter) 0 0;scrollbar-width:none;scroll-padding:0;overscroll-behavior:contain}
.history-track{position:relative;will-change:transform}
.history-cycle{position:relative;display:flex;flex-direction:column;gap:52px;padding-bottom:52px}
.history-cycle .history-item{position:relative;display:flex;justify-content:center;align-items:center;padding:0 24px;perspective:1000px}
.history-cycle .photo-button{max-width:100%;transition:transform 800ms var(--ease-out);transform-origin:50% 50%}
.history-view[data-mode=grid]{grid-template-columns:minmax(0,1fr)}
.history-view[data-mode=grid] .history-index,.history-view[data-mode=grid] .history-current-year{display:none}
.history-view[data-mode=grid] .history-stream{grid-column:1;margin:0;padding:24px var(--gutter) 72px}
.history-grid{position:relative;display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:72px 48px;align-items:start}
.history-grid .history-item{position:relative;display:flex;flex-direction:column;align-items:center;gap:20px;transition:opacity 650ms var(--ease-out)}
.history-grid figcaption{font:11px var(--font-mono)}
.history-stream[data-mode=grid] .history-grid .photo-button{height:auto;aspect-ratio:var(--ratio);width:100%;max-height:240px;transition:transform 750ms var(--ease-out);transform-origin:center top}
.history-grid .photo-button img{max-height:240px}
@media(hover:hover) and (pointer:fine){
  .history-cycle .photo-button:hover{transform:rotateY(-4deg) rotate(-1.1deg) scale(1.025)}
  .history-grid:has(.photo-button:hover) .history-item:not(:has(.photo-button:hover)){opacity:.23}
  .history-grid .photo-button:hover{transform:scale(1.055) rotate(-.6deg);z-index:2}
  #history-timeline button:hover{opacity:1}
}
.history-grid:has(.photo-button:focus-visible) .history-item:not(:has(.photo-button:focus-visible)){opacity:.23}
@media(min-width:1600px){.history-grid{grid-template-columns:repeat(6,minmax(0,1fr));gap:88px 56px}.history-current-year{font-size:40px}}
@media(max-width:900px){
  .history-view{grid-template-columns:82px minmax(0,1fr);grid-template-rows:auto auto minmax(0,1fr)}
  .history-current-year{display:none}.history-index{padding-left:var(--gutter);gap:8px;padding-bottom:12px}
  .history-stream{grid-column:2;margin-right:var(--gutter)}.history-years{padding-bottom:12px;gap:32px}
  .history-cycle{gap:40px;padding-bottom:40px}.history-grid{grid-template-columns:repeat(4,minmax(0,1fr));gap:56px 28px}
}
@media(max-width:600px){
  .history-view{grid-template-columns:68px minmax(0,1fr)}.history-heading{padding-bottom:8px}
  .history-years{gap:24px;justify-content:center;padding:0 22px 8px}.history-years button{font-size:11px}
  .history-index{padding:8px 0 12px 8px}.history-stream{margin-right:8px}
  .history-cycle{gap:40px;padding-bottom:40px}.history-cycle .history-item{padding:0 24px}
  .history-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:44px 28px}.history-grid .history-item{gap:14px}
  .history-stream[data-mode=grid] .history-grid .photo-button,.history-grid .photo-button img{max-height:210px}
}
@media(prefers-reduced-motion:reduce){.history-cycle .photo-button:hover,.history-grid .photo-button:hover{transform:none}}

/* Minimal entry, continuous cropped panels, and a genuine image-loading state. */
.booting main{visibility:hidden}
body[data-input=pointer] h1:focus{outline:none}
.project-link{position:relative;gap:0;border:0;font:24px/1 var(--font-display);padding:0 4px;min-height:48px}
.project-link::after{content:'';position:absolute;left:0;right:0;bottom:5px;height:1px;background:currentColor;transform:scaleX(.78);transition:transform 900ms var(--ease-out),background 700ms var(--ease-out)}
.project-link span{transition:transform 900ms var(--ease-out),color 700ms var(--ease-out)}
@media(hover:hover) and (pointer:fine){.project-link:hover::after{transform:scaleX(1.12);background:var(--color-accent)}.project-link:hover span{transform:translateY(-3px);color:var(--color-accent)}}
.project-link:focus-visible::after{transform:scaleX(1.12)}
.page-loader{position:fixed;inset:0;z-index:50;display:grid;place-items:center;pointer-events:none;background:rgb(255 255 255 / .94);backdrop-filter:blur(6px);opacity:0;transition:opacity 450ms var(--ease-out)}
.page-loader.is-visible{opacity:1}
.page-loader img{width:160px;height:auto;animation:logo-float 1800ms ease-in-out infinite alternate}
/* The swing was +5 to -7, so the logo rested a pixel above centre and moved further
   up than down — which is what reads as "not quite centred" even though the box is.
   Even either side of nothing now. */
@keyframes logo-float{from{transform:translateY(6px);opacity:.72}to{transform:translateY(-6px);opacity:1}}
/* Cover panels stand on a shared baseline, each frame cut to its own photograph's ratio.
   Hover re-proportions the row; the pictures themselves are never cropped or zoomed. */
@media(min-width:901px){
  .chapter-index{display:block;position:relative;padding:0;margin:0 var(--gutter);column-gap:24px;--cover-label:76px;--panel-ease:760ms var(--ease-out)}
  .chapter-link{position:absolute;top:auto;bottom:0;left:0;display:block;min-width:0;overflow:visible;will-change:transform,width,height;transition:transform var(--panel-ease),width var(--panel-ease),height var(--panel-ease)}
  .cover-media{position:absolute;top:0;bottom:var(--cover-label);left:0;right:0;overflow:hidden}
  .cover-media img{max-width:none;transition:none}
  .cover-media img.cover-next{transition:opacity 900ms var(--ease-out)}
  .cover-label{position:absolute;bottom:0;left:0;width:100%;height:60px;display:block;line-height:1.15}
  .cover-label svg{position:absolute;right:0;top:20px;left:auto}
  .panels-instant .chapter-link{transition:none}
  .chapter-link:focus-visible .cover-media{outline:2px solid var(--color-focus);outline-offset:-3px}
}
/* Two columns on small screens, each cell cut to its photograph's ratio for the same reason. */
@media(max-width:900px){
  .chapter-index{align-items:end;overflow-y:auto;overscroll-behavior:contain}
  .cover-media{flex:none;height:auto;aspect-ratio:var(--ratio,.75)}
}
.gallery[data-mode=loop]{padding:8px 0;align-items:stretch;gap:0}
.gallery-track,.gallery-cycle{position:relative;display:flex;align-items:center;flex:none;gap:48px;height:100%;width:max-content}
.gallery-track{gap:0;will-change:transform}.gallery-cycle{padding-right:48px}
.gallery[data-mode=loop] .photo-button{max-width:none;max-height:none;flex:none}
.gallery[data-mode=vertical]{display:flex;flex-direction:column;gap:40px;align-items:center;padding:10px var(--gutter) 40px}
.gallery[data-mode=vertical] .photo-button{height:auto;width:100%;max-width:none;flex:none}
.gallery[data-mode=vertical] .photo-button img{height:auto;max-height:none}
.history-view{grid-template-rows:auto minmax(0,1fr)}
.history-heading{padding:10px var(--gutter) 18px;align-items:flex-start}
.history-modes{padding-top:0}
.history-years{grid-row:1;grid-column:1/-1;position:absolute;left:50%;top:10px;transform:translateX(-50%);padding:0;gap:32px;z-index:1}
.history-years button{font:24px/1 var(--font-display);min-height:44px;min-width:44px;padding-bottom:8px}
.history-index,.history-current-year,.history-stream{grid-row:2}
.history-current-year{font:52px/1 var(--font-display)}
.history-grid figcaption{font:18px/1 var(--font-display)}
.history-cycle{gap:36px;padding-bottom:36px}
.history-view[data-mode=grid] .history-years{grid-column:1}
.history-view[data-mode=grid] .history-stream{padding-top:8px}
.history-years,.history-current-year,.history-modes{user-select:none}
.about-view{display:grid;grid-template-rows:auto minmax(0,1fr);padding-bottom:28px;overflow:hidden}
.about-view>.view-heading{padding-bottom:24px}
.about-content{width:100%;max-width:none;margin:0;min-height:0;grid-template-columns:minmax(220px,.9fr) minmax(300px,1fr) minmax(280px,1.1fr);gap:44px;align-items:center;padding:0 var(--gutter)}
.about-logo{width:100%;max-width:290px;height:auto}
.about-intro h2{margin-bottom:42px;line-height:0}
.about-intro p{font-size:14px;line-height:1.7}
.about-intro .ko{font-size:12px;margin-top:16px}
.about-facts>div{grid-template-columns:74px minmax(0,1fr);gap:16px;padding:14px 0}
.about-facts dd{font-size:12px;line-height:1.75}.about-facts .ko{font-size:11px}
.about-map{grid-column:auto;min-width:0;min-height:0;align-self:center}
.illustrated-map{display:block;padding:0;border:0}
.map-viewport{aspect-ratio:1/1.1;position:relative;overflow:hidden;max-height:calc(100dvh - 290px)}
.map-drawing{position:relative;width:150%;left:-35%}
.map-drawing>img{width:100%;height:auto;max-height:none;max-width:none;object-fit:initial}
.map-pin{position:absolute;left:58.5%;top:27.8%;transform:translate(-50%,-100%);display:flex;align-items:center;flex-direction:column;min-width:98px;min-height:44px;padding:4px 8px 0;filter:drop-shadow(0 1px 8px white)}
.map-pin>img{width:98px;height:auto;padding:8px;background:var(--color-paper);transition:transform 700ms var(--ease-out)}
.map-pin-line{height:32px;width:1px;background:var(--color-accent)}
.map-pin-dot{width:9px;height:9px;flex:none;background:var(--color-accent);border:2px solid var(--color-paper);box-shadow:0 0 0 1px var(--color-accent);border-radius:50%}
.illustrated-map figcaption{padding:12px 0 0;font:28px/1 var(--font-display);gap:6px}
.illustrated-map figcaption .ko{font-size:11px}
.about-map>a{justify-content:flex-start;gap:12px;min-height:48px;font-size:12px}
@media(hover:hover) and (pointer:fine){.map-pin:hover>img{transform:translateY(-4px)}}
@media(min-width:1600px){.about-content{gap:80px;grid-template-columns:1fr 1fr 1.1fr}.about-logo{max-width:360px}.about-facts dd{font-size:14px}.about-intro p{font-size:16px}.map-viewport{max-height:580px}}
@media(max-width:1100px) and (min-width:901px){.about-content{gap:24px;grid-template-columns:.85fr 1.1fr 1fr}.about-facts>div{grid-template-columns:60px minmax(0,1fr);gap:10px}.about-intro p{font-size:13px}.about-logo{max-width:240px}}
@media(max-width:900px){
  .history-view{grid-template-rows:auto minmax(0,1fr)}.history-heading{padding-bottom:16px}.history-heading h1{font-size:38px}
  .history-years{grid-column:1/-1;left:50%;top:9px;gap:20px}.history-years button{font-size:22px;padding-bottom:6px}
  .history-cycle{gap:32px;padding-bottom:32px}
  .about-view{display:block;overflow-y:auto;padding-bottom:28px}.about-content{grid-template-columns:1fr 1fr;gap:32px;align-items:start}
  .about-intro{grid-column:1}.about-facts{grid-column:1;grid-row:2}.about-map{grid-column:2;grid-row:1/3;position:sticky;top:20px;align-self:start}
  .about-logo{max-width:230px}.about-intro h2{margin-bottom:24px}.map-viewport{max-height:none}
}
@media(max-width:600px){
  .history-heading{padding-bottom:48px}.history-heading h1{font-size:36px}
  .history-years{top:49px;gap:22px}.history-years button{font-size:21px;min-height:44px}
  .history-cycle{gap:28px;padding-bottom:28px}
  .about-content{grid-template-columns:minmax(0,1fr);gap:28px}.about-intro,.about-facts,.about-map{grid-column:1;grid-row:auto;position:static}
  .about-view>.view-heading{padding-bottom:24px}.about-logo{max-width:210px}.about-intro p{font-size:13px}.about-intro .ko{font-size:11px}
  .about-map{grid-row:2}.about-facts{grid-row:3}.map-viewport{aspect-ratio:1.35;max-height:270px}.map-drawing{width:130%;left:-25%;top:-25px}
  .illustrated-map figcaption{font-size:24px}.about-facts dd{font-size:13px}
}
@media(prefers-reduced-motion:reduce){.page-loader img{animation:none}.project-link:hover span,.map-pin:hover>img{transform:none}}
@media(max-height:650px) and (min-width:901px){.about-view{display:block;overflow-y:auto}.about-content{min-height:440px}.map-viewport{max-height:360px}}

/* Shared link feedback and a quiet, ink-like map annotation. */
.header-link{font:24px/1 var(--font-display)}
.ink-link{transition:color 700ms ease}
.link-label{display:inline-block;position:relative}
.link-label::after{content:'';position:absolute;left:0;right:0;bottom:-4px;height:1px;background:currentColor;transform:scaleX(0);transform-origin:left;transition:transform 800ms ease,opacity 800ms ease;opacity:0}
.header-link[aria-current=page],.chapter-nav a[aria-current],.history-modes button[aria-pressed=true],.history-years button[aria-current=true]{text-decoration:none}
.ink-link:is([aria-current=page],[aria-current=true],[aria-pressed=true],:focus-visible) .link-label::after{transform:scaleX(1);opacity:1}
@media(hover:hover) and (pointer:fine){.ink-link:hover .link-label::after{transform:scaleX(1);opacity:1}.ink-link:hover{color:var(--color-accent)}}
.history-grid .history-item{transition:opacity 1100ms ease-in-out}
.history-years button{font-size:23px}
.history-current-year{font-size:49px}
.history-grid figcaption{font-size:17px}
.mono{font-size:12px!important}
.about-facts>div{align-items:start}
.about-facts dt,.about-facts dd{line-height:1.75}
.about-facts a{display:inline-block;vertical-align:top;line-height:inherit;min-height:44px}
.about-facts a .link-label{vertical-align:top}
.about-intro p{max-width:310px}
.map-viewport{max-height:calc(100dvh - 345px)}
.map-pin{width:112px;height:115px;padding:0;filter:none;display:block;min-width:0}
.map-pin>img{position:absolute;left:-10px;top:4px;width:78px;padding:0;background:none;filter:drop-shadow(0 0 1px var(--color-paper)) drop-shadow(0 0 2px var(--color-paper));transform:rotate(-8deg);transition:transform 900ms ease}
.map-pin-line{position:absolute;left:33px;top:42px;width:28px;height:60px;background:none;border:0;border-left:1px solid var(--color-accent);border-bottom:1px solid var(--color-accent);border-radius:0 0 0 65%;transform:rotate(-10deg)}
.map-pin-dot{position:absolute;left:52px;bottom:0;width:6px;height:6px;background:var(--color-accent);border:0;box-shadow:none}
.map-pin-dot::before{content:'';position:absolute;width:24px;height:17px;border:1px solid var(--color-ink);border-radius:46% 54% 49% 51%;left:-9px;top:-6px;transform:rotate(-18deg);transition:transform 900ms ease}
.illustrated-map figcaption{gap:9px;padding-top:12px}
.map-address{font:12px/1.6 var(--font-body);color:var(--color-muted)}
.map-coordinates{display:block;font:12px/1.5 var(--font-mono);color:var(--color-muted)}
.about-map>a{min-height:44px;margin-top:5px}
#zoom-image{position:relative;z-index:2}
.zoom-stage .zoom-outgoing{position:fixed;max-width:none;max-height:none;object-fit:contain;pointer-events:none;z-index:1}
#zoom-retry{z-index:3}
@media(hover:hover) and (pointer:fine){.map-pin:hover>img{transform:rotate(-5deg) translateY(-3px)}.map-pin:hover .map-pin-dot::before{transform:rotate(-8deg) scale(1.1)}}
@media(max-width:900px){.header-link{font-size:23px}.history-years button{font-size:21px}.map-viewport{max-height:none}}
@media(max-width:600px){.header-link{font-size:22px}.history-years button{font-size:20px}.map-viewport{max-height:250px}.map-address,.map-coordinates{font-size:11px}.map-coordinates.mono{font-size:11px!important}}
@media(max-height:650px) and (min-width:901px){.map-viewport{max-height:320px}}
@media(prefers-reduced-motion:reduce){.map-pin:hover>img{transform:rotate(-8deg)}.map-pin:hover .map-pin-dot::before{transform:rotate(-18deg)}}

/* The date sits under the enlarged photograph, quiet enough to read only when looked for. */
.zoom-meta{position:absolute;left:0;right:0;bottom:26px;margin:0;text-align:center;font-size:12px!important;color:var(--color-muted);pointer-events:none;letter-spacing:.06em}
.lightbox.is-closing .zoom-meta{opacity:0;transition:opacity 220ms var(--ease-out)}
@media(max-width:600px){.zoom-meta{bottom:56px}}

/* Phones: the interface was competing with the photographs. The type scale comes down a
   step, the year rail goes away, and the bands stacked above each picture get shallower. */
@media(max-width:600px){
  .masthead{height:56px}
  .header-link{font-size:16px}
  .brand img{width:58px}
  .view-heading,.chapter-heading{padding-top:6px;padding-bottom:20px}
  .view-heading h1,.chapter-heading h1,.history-heading h1{font-size:27px}
  .chapter-nav{font-size:15px;gap:18px}
  .chapter-nav a{min-height:38px}
  .history-heading{padding-bottom:38px}
  .history-years{top:36px;gap:18px}
  .history-years button{font:15px/1 var(--font-display);min-height:38px;min-width:38px}
  .history-modes button{font-size:12px}
  /* A rail of 40x32 thumbnails is unreadable at this width and was taking 18% of it. */
  .history-view{grid-template-columns:minmax(0,1fr)}
  .history-index{display:none}
  .history-stream{grid-column:1;margin-right:0}
  /* Years in the grid are metadata beside a picture, not headings above one. */
  .history-grid figcaption{font:11px/1 var(--font-mono);color:var(--color-muted);letter-spacing:.04em}
  .history-grid{gap:34px 24px}
  .about-view>.view-heading{padding-bottom:18px}
  .cover-label{font-size:24px;min-height:36px}
}

/* Colophon: a reading page, so the measure stays short and the rhythm is vertical. */
.colophon-view{display:grid;grid-template-rows:auto minmax(0,1fr) auto}
.colophon-content{overflow-y:auto;overscroll-behavior:contain;padding:0 var(--gutter) 40px;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:0 80px;align-content:start;max-width:1180px}
.colophon-block{break-inside:avoid;margin-bottom:40px}
.colophon-block h2{font:400 26px/1.1 var(--font-display);margin-bottom:14px;padding-bottom:12px;border-top:1px solid var(--color-rule);padding-top:14px}
.colophon-block p{font-size:14px;line-height:1.85;max-width:44ch;margin-bottom:14px;color:var(--color-ink)}
.colophon-block p:last-child{margin-bottom:0}
.colophon-imprint{color:var(--color-muted);font-size:12px!important;letter-spacing:.04em}
.colophon-back{margin:16px var(--gutter) 22px}
.about-colophon-link{display:inline-flex;align-items:center;min-height:44px;margin:20px var(--gutter) 0;font-size:13px;color:var(--color-muted)}
@media(max-width:900px){.colophon-content{grid-template-columns:minmax(0,1fr);gap:0;padding-bottom:32px}.colophon-block{margin-bottom:32px}}
@media(max-width:600px){
  .colophon-content{padding-bottom:28px}
  .colophon-block h2{font-size:21px;margin-bottom:10px;padding-top:12px}
  .colophon-block p{font-size:13px;line-height:1.8}
  .colophon-block{margin-bottom:26px}
}

/* The line that closes the grid. Far enough below the last photograph to read as an end. */
.history-outro{display:block;text-align:center;padding:120px 0 40px;font:400 30px/1.3 var(--font-display);color:var(--color-ink)}
.history-outro .link-label::after{bottom:-7px}
@media(max-width:900px){.history-outro{padding:88px 0 32px;font-size:25px}}
@media(max-width:600px){.history-outro{padding:72px 0 24px;font-size:21px}}

/* History gave a single four-digit number 300px of the row and left the photographs 58%
   of the screen. The year column is now sized to the number, the rail is narrower, and
   the year tabs sit closer to the top, so the pictures get the width back. */
@media(min-width:901px){
  .history-view{grid-template-columns:96px minmax(104px,.56fr) minmax(0,1.44fr)}
  .history-heading{padding-top:4px;padding-bottom:8px}
  .history-years{top:4px;gap:34px}
  .history-years button{font-size:18px;min-height:38px;min-width:38px}
  .history-modes button{font-size:13px}
  #history-timeline button{width:38px}
  #history-timeline button img{width:34px;height:27px}
  /* The number is centred on the photograph beside it, so it carries no bottom padding. */
  .history-current-year{padding-bottom:0;font-size:42px}
}

/* A rotation is a slow reshape; a hover is a quick one. Same easing, different clock. */
@media(min-width:901px){
  .chapter-index.is-rotating .chapter-link{transition-duration:1600ms}
  .cover-media img.cover-next{transition-duration:1500ms}
  /* Emphasis comes from the others receding, so the size change can stay small. */
  .chapter-index:has(.chapter-link:hover) .chapter-link:not(:hover) .cover-media{opacity:.45}
  .cover-media{transition:opacity 700ms var(--ease-out)}
  .chapter-index:has(.chapter-link:hover) .chapter-link:not(:hover) .cover-label{opacity:.4;transition:opacity 700ms var(--ease-out)}
}
@media(prefers-reduced-motion:reduce){.chapter-index.is-rotating .chapter-link{transition-duration:.01ms}}

/* The pointer is a chicken foot, with the default arrow behind it if a browser refuses
   the image. Only on a real mouse: touch has no cursor and no trail to leave. */
@media(hover:hover) and (pointer:fine){
  html,body,a,button,.photo-button,.rail-photo,.chapter-link,.map-pin,.history-outro{
    cursor:image-set(url('assets/cursor-foot.png') 1x, url('assets/cursor-foot@2x.png') 2x) 12 2, auto;
  }
  .foot-trail{position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:90;pointer-events:none}  /* No overflow clip: the prints are placed inside the viewport already, and if this box
     ever measured short the clip would hide every one of them. */
  /* Painted through a mask so the ink colour is ours, not the drawing's: walking prints
     in the page's ink, a press in the one accent the site owns. */
  .foot-print{
    position:absolute;top:0;left:0;width:15px;height:15px;
    background-color:var(--color-ink);
    -webkit-mask:url('assets/chicken-foot.svg') center/contain no-repeat;
    mask:url('assets/chicken-foot.svg') center/contain no-repeat;
    opacity:.19;will-change:opacity,transform;
    transition:opacity 1000ms linear;
  }
  .foot-print.is-fading{opacity:0}
  .foot-print{transition-duration:1500ms}
}
@media(prefers-reduced-motion:reduce){.foot-trail{display:none}}

/* The four covers are drained of colour so the chapter names carry the page. Four
   photographs this unlike each other were competing with the words under them, and with
   each other. The colour is still there: it comes back the moment a chapter opens. */
#projects .cover-media img{filter:grayscale(1)}

/* Enlarged view, minimal: the controls keep a 44px target but lose the glass disc, so
   only the icon shows against a darker ground. */
.lightbox .icon-button{width:44px;height:44px;background:none!important;backdrop-filter:none!important;border:0!important;border-radius:0}
.lightbox .icon-button svg{width:15px;height:15px;stroke-width:1.5}
.lightbox .icon-button{opacity:.62;transition:opacity 320ms var(--ease-out)}
.lightbox .icon-button:disabled{opacity:.16}
@media(hover:hover) and (pointer:fine){.lightbox .icon-button:not(:disabled):hover{opacity:1}}
.lightbox .icon-button:focus-visible{opacity:1;outline-offset:-6px}
.zoom-close{top:14px;right:16px}
.zoom-prev{left:10px}
.zoom-next{right:10px}
@media(max-width:600px){.zoom-close{top:8px;right:8px}.zoom-prev{left:calc(50% - 48px)}.zoom-next{right:calc(50% - 48px)}}

/* Featured / Grid is a switch, not a name. Small, tracked and upper case reads as a
   control beside the serif years without competing with them. */
.history-modes button{font:500 11px/1 var(--font-body);letter-spacing:.14em;text-transform:uppercase}
.history-modes{gap:20px}
@media(max-width:600px){.history-modes button{font-size:10px;letter-spacing:.12em}}

/* The mark was black ink drawn on top of a black ink drawing, so it read as part of the
   street plan. Three moves separate it: the drawing steps back, the logo sits on its own
   patch of paper, and the spot itself is circled in the one accent the site owns. */
.map-drawing>img{opacity:.6;transition:opacity 700ms var(--ease-out)}
.map-pin{z-index:2}
.map-pin>img{
  width:84px;left:-14px;top:0;padding:7px 9px;
  background:var(--color-paper);filter:none;
  box-shadow:0 1px 0 var(--color-rule),0 0 0 1px var(--color-rule);
  transform:rotate(-3deg);
  animation:pin-float 5200ms ease-in-out infinite alternate;
  transition:transform 700ms var(--ease-out),box-shadow 700ms var(--ease-out);
}
@keyframes pin-float{from{translate:0 -2px}to{translate:0 3px}}
/* A hairline leader from the label down to the place it names. */
.map-pin-line{left:30px;top:44px;width:22px;height:50px;border-left:1px solid var(--color-accent);border-bottom:1px solid var(--color-accent);border-radius:0 0 0 70%;transform:rotate(-8deg)}
/* Circled by hand, the way you would mark a spot on a printed map. */
.map-pin-dot{left:50px;bottom:-2px;width:5px;height:5px}
.map-pin-dot::before{
  width:46px;height:33px;left:-20px;top:-14px;
  border:1.5px solid var(--color-accent);border-radius:47% 53% 44% 56%;
  transform:rotate(-14deg);transition:transform 800ms var(--ease-out),opacity 500ms
}
@media(hover:hover) and (pointer:fine){
  .map-pin:hover>img{transform:rotate(-1deg) scale(1.05);box-shadow:0 2px 0 var(--color-rule),0 0 0 1px var(--color-accent)}
  .map-pin:hover~* .map-drawing>img,.illustrated-map:has(.map-pin:hover) .map-drawing>img{opacity:.42}
  .map-pin:hover .map-pin-dot::before{transform:rotate(-6deg) scale(1.16)}
}
.map-pin:focus-visible>img{box-shadow:0 0 0 2px var(--color-focus)}
@media(prefers-reduced-motion:reduce){.map-pin>img{animation:none}}

/* Pressing tilts the foot. A cursor image cannot animate, but it can be swapped, and the
   swap on :active is enough to read as weight going onto it. */
@media(hover:hover) and (pointer:fine){
  html:active,body:active,a:active,button:active,.photo-button:active,.rail-photo:active,.chapter-link:active{
    cursor:image-set(url('assets/cursor-foot-press.png') 1x, url('assets/cursor-foot-press@2x.png') 2x) 12 2, auto;
  }
  /* The print left by a press: heavier ink, and it stays while several walking prints
     come and go around it. */
  .foot-print.is-press{
    width:26px;height:26px;opacity:.86;
    background-color:var(--color-accent);
    transition:opacity 3200ms cubic-bezier(.65,0,.9,.45);
    animation:foot-press 260ms var(--ease-out) both;
  }
  /* Lands slightly over-rotated and over-sized, then settles: weight arriving, not an
     element appearing. `rotate` composes on top of the transform's own angle. */
  @keyframes foot-press{from{scale:1.34;rotate:7deg}to{scale:1;rotate:0deg}}
}

/* Widening the row pushed the photographs left, because they are centred in it. The room
   asked for was vertical, so the stream keeps its width but the pictures hang from the
   right edge, the way they sat before, and take the height instead. */
@media(min-width:901px){
  /* Centred in a right-hand column, the way it sat before. Flushing it to the very edge
     read as pinned rather than placed. */
  .history-cycle .history-item{justify-content:center}
  /* Nothing capped the height, so a photograph only ever grew to its `sizes` width and
     left the bottom of the screen empty. */
  /* The size itself is set inline by measureHistory(), which knows the stream's real
     height; anything declared here would lose to it and only confuse the next reader. */
  /* A smaller heading is more room for the pictures underneath it. */
  .history-heading{padding-top:2px;padding-bottom:4px;align-items:flex-start}
  .history-heading h1{font-size:32px}
  .history-modes{padding-top:6px}
  .history-years{top:2px;gap:30px}
  .history-years button{font-size:15px;min-height:32px;min-width:32px}
  .history-current-year{font-size:36px}
}

/* The year stays put at the middle of the column; a number that chased the stream read
   as restless. */
.history-current-year{translate:none}

/* About already says About in the masthead; the page repeated it underneath. The heading
   stays for the section's accessible name and comes out of the picture. */
.about-view>.view-heading{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);padding:0;margin:-1px}
.about-view{grid-template-rows:minmax(0,1fr)}
@media(max-width:900px){.about-view{display:block}}

/* Loading: the mark alone, dead centre, breathing. A second element beside it pushed the
   logo off the middle and gave the eye two things to watch. */
.page-loader{grid-auto-flow:row;gap:0}
.page-loader::after{content:none}
.page-loader img{width:92px;animation:logo-float 1500ms ease-in-out infinite alternate}

/* The masthead pair read a step large against everything under it. Down to 20px, with the
   mark and the band itself brought in to match so the header keeps its proportions — and
   the eight pixels the band gives up go to the pictures. */
.masthead{height:80px}
.header-link{font-size:20px}
.brand img{width:66px}
@media(max-width:900px){
  .masthead{height:68px}
  .header-link{font-size:18px}
  .brand img{width:58px}
}
@media(max-width:600px){
  .masthead{height:58px}
  .header-link{font-size:15px}
  .brand img{width:54px}
}

/* The grid's dim was a slow fade in both directions, so pointing at one photograph took a
   beat to answer and letting go took another. Both halves are quicker now. */
.history-grid .history-item{transition:opacity 300ms var(--ease-out)}
.history-stream[data-mode=grid] .history-grid .photo-button{transition:transform 360ms var(--ease-out)}

/* The dim had gone from slow and heavy to quick and heavy. Halfway on the timing, and the
   photographs that step back keep more of themselves. */
.history-grid .history-item{transition:opacity 560ms var(--ease-out)}
.history-stream[data-mode=grid] .history-grid .photo-button{transition:transform 560ms var(--ease-out)}
@media(hover:hover) and (pointer:fine){
  .history-grid:has(.photo-button:hover) .history-item:not(:has(.photo-button:hover)){opacity:.4}
}
.history-grid:has(.photo-button:focus-visible) .history-item:not(:has(.photo-button:focus-visible)){opacity:.4}

/* Colophon as a specification page: the headings hang in a rail on the left and one column
   of text runs beside them. Two equal columns had left a long gap under the short block,
   because the blocks are nothing like the same length. */
@media(min-width:901px){
  /* Centred, so the page reads as a printed one. Left-aligned it put the text against the
     left edge with 746px of nothing beside it, and hung the scrollbar off in the middle. */
  .colophon-content{display:block;max-width:880px;margin-inline:auto;padding-left:0;padding-right:0}
  .colophon-block{
    display:grid;grid-template-columns:168px minmax(0,1fr);gap:0 48px;align-items:start;
    margin:0;padding:18px 0;border-top:1px solid var(--color-rule);
  }
  .colophon-block:first-child{border-top:0;padding-top:4px}
  /* The heading holds the rail; every paragraph stacks in the second column instead of
     flowing back into the first. */
  .colophon-block h2{grid-column:1;grid-row:1;font-size:21px;margin:0;padding:2px 0 0;border-top:0;line-height:1.15}
  .colophon-block p{grid-column:2;font-size:13px;line-height:1.85;max-width:62ch;margin-bottom:11px}
  .colophon-block p:last-child{margin-bottom:0}
  .colophon-imprint{padding-top:4px}
}
/* The cut at the fold, and the fade that lifts at the end of the text. */
.colophon-view{position:relative}
.colophon-view::after{
  content:'';position:absolute;left:0;right:0;bottom:62px;height:76px;pointer-events:none;
  background:linear-gradient(to bottom,rgb(255 255 255 / 0),rgb(255 255 255 / .72) 46%,var(--color-paper) 92%);
  opacity:1;transition:opacity 420ms var(--ease-out);
}
.colophon-view:has(.colophon-content.is-end)::after{opacity:0}
@media(max-width:600px){.colophon-view::after{bottom:52px;height:56px}}

/* ══════════════════════════════════════════════════════════════════════════
   The phone. One layer, and it comes last on purpose.

   Everything above grew a phone rule at a time over a long afternoon, and the
   rules began to argue: four heights for the hero logo, a dozen for the year
   buttons, a gallery told to be `block` that ended up `flex`. Rather than keep
   adding to that pile, this block is the single place the phone layout is
   decided, and being last it wins. What it does:

   1. Takes the controls away. Four pause buttons, a pair of gallery arrows and
      the timeline scrubber all exist so that a cursor has something to reach
      for. On a touch screen they are small targets floating over photographs,
      and app.js now holds the page still there, so they have nothing to pause.

   2. Lets the covers keep their own shape without cutting the labels off. Each
      cover panel is as tall as its photograph is, and a grid row used to stretch
      every panel to the tallest of the pair, which pushed the labels past the
      bottom of a short screen and sliced them in half. Now each panel stands on
      its own and the page scrolls if it must.

   3. Gives the small type back its size — the FEATURED / GRID pair was set at
      10px, which is a caption pretending to be a button.
   ══════════════════════════════════════════════════════════════════════════ */
@media(max-width:900px){
  /* 1. Controls that only make sense beside a cursor. */
  .rail-pause,#covers-pause,#history-pause,#gallery-pause,
  .gallery-arrows,.history-index,.history-current-year{display:none!important}
  /* The heading kept its space-between for a button that is no longer there. */
  .projects-view .view-heading{justify-content:flex-start}

  /* 2. Home: a mark you can read, and a ribbon that looks like a ribbon.
        A rail photo was coming out 377px wide on a 375px screen — one picture,
        edge to edge, indistinguishable from a hero image. */
  .hero-logo{width:min(250px,62vw);max-height:19dvh}
  .home-center{gap:26px;padding-bottom:20px}
  /* The one way into the archive, and it was set at 13px. */
  .project-link{font-size:20px;gap:18px}
  .rail-photo{height:clamp(140px,19dvh,200px);width:auto;aspect-ratio:var(--ratio)}
  .rail-track,.rail-cycle{gap:10px}

  /* 3. Projects: two columns, every panel its own height, nothing clipped. */
  /* The view was a three-row grid whose middle row was `1fr`, so on a short screen the
     four panels were handed a track smaller than they needed and spilled over the Home
     link underneath. Ordinary flow on a phone: each piece takes the height it asks for
     and the view scrolls. */
  .projects-view{display:block;overflow-y:auto;overscroll-behavior:contain;
    padding-bottom:max(14px,env(safe-area-inset-bottom))}
  .chapter-index{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
    align-items:start;gap:26px 16px;overflow:visible;padding:0 var(--gutter)}
  .chapter-link{position:static;display:flex;flex-direction:column;gap:10px;
    width:auto!important;height:auto!important;transform:none!important}
  .cover-media{position:static;flex:none;height:auto;aspect-ratio:var(--ratio,.8);overflow:hidden}
  .cover-media img{width:100%;height:100%;max-width:100%;object-fit:cover}
  .cover-label{position:static;display:flex;align-items:center;justify-content:space-between;
    width:auto;height:auto;min-height:34px;padding-top:9px;font-size:25px;line-height:1.1}
  .cover-label svg{position:static;width:17px}
  .projects-back{margin-top:16px}

  /* 4. History: the years used to be centred by absolute position, which set them
        down on top of the FEATURED / GRID pair. They get their own row instead. */
  .history-view{grid-template-columns:minmax(0,1fr);grid-template-rows:auto auto minmax(0,1fr)}
  .history-heading{grid-row:1;grid-column:1}
  .history-years{position:static;transform:none;grid-row:2;grid-column:1;
    flex-direction:row;justify-content:center;gap:22px;padding:0 var(--gutter) 12px}
  .history-years button{font:18px/1 var(--font-display);min-height:40px;min-width:40px}
  .history-stream{grid-row:3;grid-column:1}
  .history-modes button{font-size:12px;letter-spacing:.1em;min-height:44px;min-width:44px;
    display:flex;align-items:center;justify-content:center}

  /* 5. About: the drawing was being squeezed into 245px, which is a thumbnail of
        a map rather than a map. */
  .map-viewport{max-height:360px}

  /* 6. The colophon is the one page meant to be read rather than looked at, and it
        was still set at the 13px the desktop two-column layout needed. */
  .colophon-block p{font-size:15px;line-height:1.75;max-width:none}
  .colophon-block h2{font-size:22px}
}
@media(max-width:600px){
  .hero-logo{width:min(220px,58vw);max-height:17dvh}
  .project-link{font-size:18px;gap:16px}
  .rail-photo{height:clamp(130px,18dvh,180px)}
  .cover-label{font-size:22px;min-height:30px}
  .chapter-index{gap:22px 14px}
  .history-years{gap:18px}
  .history-years button{font-size:17px;min-height:38px;min-width:38px}
  .map-viewport{max-height:300px}

  /* The two arrows sat side by side under the middle of the picture, and the date sat
     on top of them. Sent to opposite corners, with the date in the gap between. */
  .zoom-prev{left:12px;right:auto;top:auto;bottom:16px}
  .zoom-next{right:12px;left:auto;top:auto;bottom:16px}
  .zoom-meta{bottom:29px}
}

/* ══════════════════════════════════════════════════════════════════════════
   Desk: the last word on the wide layout.

   Three things were out of true. The History view was a three-column grid —
   96px of thumbnail rail, a 376px column with nothing at all in it, and the
   photographs in what was left — so the picture sat 220px right of the middle
   of the window. Its heading started 10px higher than every other page's. And
   the Colophon's title stood at the gutter while the text it named began 340px
   further in.
   ══════════════════════════════════════════════════════════════════════════ */
@media(min-width:901px){
  /* One column, and the scale is lifted out of the flow and hung in the left
     margin instead of being given a column of its own. */
  .history-view{grid-template-columns:minmax(0,1fr);grid-template-rows:auto minmax(0,1fr)}
  .history-heading{grid-column:1;grid-row:1;padding:12px var(--gutter) 14px}
  .history-years{top:13px}
  .history-stream{grid-column:1;grid-row:2;margin:0;padding:0 var(--gutter)}
  .history-view[data-mode=grid] .history-stream{grid-row:2;padding:22px var(--gutter) 72px}
  /* The sheet is sized to land on one screen; 72px of padding under it was the only
     thing making the page scroll. */
  .history-view[data-mode=contact] .history-stream{grid-row:2;padding:20px var(--gutter) 14px}
  .history-index{grid-column:auto;grid-row:auto;position:absolute;left:var(--gutter);
    top:74px;bottom:24px;width:46px;z-index:2;
    display:flex;flex-direction:column;align-items:flex-start;padding:0;gap:16px}
  .history-view[data-mode=grid] .history-index,
  .history-view[data-mode=contact] .history-index{display:none}

  /* The running year was a grid item in a column of its own, 376px wide to hold two
     digits, which is what pushed the photographs 220px right of the middle. It is
     lifted out of the flow and set against the opposite margin from the scale, so
     the featured view reads as: scale, photograph, year. */
  .history-current-year{grid-column:auto;grid-row:auto;position:absolute;
    right:var(--gutter);bottom:26px;align-self:auto;justify-self:auto;padding:0;
    font:42px/1 var(--font-display);color:var(--color-muted);pointer-events:none;z-index:2}
  .history-view[data-mode=grid] .history-current-year,
  .history-view[data-mode=contact] .history-current-year{display:none}

  /* The title sits on the same left edge as the thing it names. Everywhere else
     that edge is the gutter; on the Colophon it is the measure. */
  .colophon-view{--measure:696px}
  .colophon-content{width:var(--measure);max-width:calc(100% - var(--gutter)*2);margin-inline:auto}
  .colophon-view>.view-heading{width:var(--measure);max-width:calc(100% - var(--gutter)*2);
    margin-inline:auto;justify-self:center;padding-left:0;padding-right:0}

  /* Three columns each centred on their own height meant no two of them started at
     the same line — the drawing began 230px above the text beside it. They start
     together now, a little below the masthead rather than hard against it, because
     this page's title is set as the logo and there is no heading to hold the gap. */
  .about-content{align-items:start;padding-top:26px}
  .about-map{align-self:start}
  /* Inline-flex that was being stretched to the full 1376px, so a one-word link had
     the whole width of the page as its hit area. */
  .about-colophon-link{width:fit-content}
}

/* ── The scale ─────────────────────────────────────────────────────────────
   One hairline per photograph, at the point it falls in the four years. The
   marks crowd through 2025 and 2026 because that is where the archive is thick,
   which makes the shape of four years readable at a glance — something 211
   identical thumbnails never managed. The accent bar is where you are.
   ───────────────────────────────────────────────────────────────────────── */
#history-timeline.scrubber{position:relative;width:46px;flex:1;min-height:0;overflow:visible;
  cursor:ns-resize;touch-action:none}
#history-timeline.scrubber::before{content:'';position:absolute;left:0;top:0;bottom:0;
  width:1px;background:var(--color-rule)}
.scrubber .tick{position:absolute;left:0;width:7px;height:1px;background:var(--color-ink);opacity:.2;
  transition:opacity 500ms var(--ease-out),width 500ms var(--ease-out)}
.scrubber .tick.is-current{width:12px;opacity:.8}
.scrubber .year-mark{position:absolute;left:0;transform:translateY(-50%);padding-left:23px;
  font:9px/1 var(--font-mono);letter-spacing:.08em;color:var(--color-muted);
  pointer-events:none;white-space:nowrap}
.scrubber .year-mark::before{content:'';position:absolute;left:0;top:50%;width:15px;height:1px;
  background:var(--color-ink);opacity:.45}
.scrub-cursor{position:absolute;left:0;top:var(--scrub,0%);width:16px;height:2px;margin-top:-1px;
  background:var(--color-accent);pointer-events:none;transition:top 560ms var(--ease-out)}
.scrubber.is-scrubbing .scrub-cursor{transition:none}
.scrubber:focus-visible{outline:2px solid var(--color-focus);outline-offset:3px}
@media(hover:hover) and (pointer:fine){.scrubber:hover .tick{opacity:.34}}
@media(prefers-reduced-motion:reduce){.scrub-cursor{transition:none}}

/* ── Contact ───────────────────────────────────────────────────────────────
   Every frame at once, small and even, read the way a contact sheet is read:
   not to look at any one of them but to see the shape of the whole four years.
   This is the one place in the archive a photograph is cropped — a sheet only
   works if the frames line up — and hovering gives the print back at size.
   ───────────────────────────────────────────────────────────────────────── */
.history-contact{display:grid;grid-template-columns:repeat(auto-fill,minmax(48px,1fr));
  gap:6px;align-items:start}
.history-contact .history-item{position:relative;display:block;padding:0;margin:0;
  transition:opacity 420ms var(--ease-out)}
/* A year starts its own row, so the four of them read as four blocks and you can see
   at a glance that 2023 is one line and 2026 is four. */
.history-contact .history-item[data-opens-year]{grid-column-start:1;margin-top:28px}
.history-contact .history-item:first-child{margin-top:0}
.history-contact figcaption{position:absolute;left:0;bottom:100%;padding-bottom:7px;
  font:9px/1 var(--font-mono);letter-spacing:.06em;color:var(--color-muted)}
/* The sheet is meant to land on one screen, so the closing line is a line, not a gap
   with a line at the bottom of it. */
.history-view[data-mode=contact] .history-outro{padding:42px 0 8px;font-size:23px}
.history-contact .photo-button{display:block;width:100%;height:auto;aspect-ratio:1;overflow:hidden;
  transition:transform 380ms var(--ease-out)}
.history-contact .photo-button img{width:100%;height:100%;max-height:none;object-fit:cover}
@media(hover:hover) and (pointer:fine){
  .history-contact:has(.photo-button:hover) .history-item:not(:has(.photo-button:hover)){opacity:.32}
  .history-contact .history-item:has(.photo-button:hover){z-index:3}
  .history-contact .photo-button:hover{transform:scale(1.85)}
}
@media(max-width:900px){
  /* The sheet was running edge to edge while every other thing on the page stood at
     the gutter, which is the one alignment a phone actually notices. */
  /* 26px on top so the first year's label, which hangs above its row, is not cut off. */
  .history-view[data-mode=contact] .history-stream{padding:26px var(--gutter) 44px}
  .history-contact{grid-template-columns:repeat(auto-fill,minmax(52px,1fr));gap:5px}
  .history-contact .history-item[data-opens-year]{margin-top:24px}
  .history-view[data-mode=contact] .history-outro{padding:34px 0 8px;font-size:20px}
  .history-modes{gap:14px}
}
@media(max-width:600px){
  .history-contact{grid-template-columns:repeat(auto-fill,minmax(46px,1fr));gap:4px}
  .history-modes{gap:11px}
  .history-modes button{min-width:0;padding:0 2px}
}

/* Dakbal Run sits beside About. The two share the left of the masthead; on a phone they
   go into the menu with the rest. The game is a red screen set into the paper like a
   photograph, as wide as the page and as tall as what is left under the masthead. Its
   name stands in the middle until the game has drawn itself over it. */
.header-group{display:flex;align-items:center;gap:32px}
@media(max-width:900px){.masthead .header-group{display:none}}
.run-view{display:flex;flex-direction:column;padding:0 var(--gutter) var(--gutter)}
.run-view>.view-heading{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);padding:0;margin:-1px}
.run-stage{position:relative;flex:1;min-height:0;background:#D42A20;overflow:hidden}
.run-placeholder{position:absolute;inset:0;display:grid;place-items:center;font:400 clamp(30px,4.2vw,46px)/1 var(--font-display);color:rgba(255,217,168,.78)}
.run-stage iframe{position:absolute;inset:0;width:100%;height:100%;border:0;display:block;background:transparent}
@media(max-width:600px){.run-view{padding:0 0 max(0px,env(safe-area-inset-bottom))}}

/* Film sits under History's modes. The animation is a dark picture set into the paper at
   16:9, as large as the page allows. It waits on its poster; Play (with sound) starts it,
   the picture itself pauses it, and leaving the page rewinds it. */
.history-film{min-height:44px;display:inline-flex;align-items:center;font-size:14px;color:var(--color-muted)}
.film-view{display:flex;flex-direction:column;padding:0 var(--gutter) var(--gutter)}
.film-view>.view-heading{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);padding:0;margin:-1px}
.film-stage{position:relative;flex:1;min-height:0;display:grid;place-items:center;container-type:size}
.film-frame{position:relative;width:min(100cqw,calc(100cqh * 16 / 9));aspect-ratio:16/9}
.film-stage video{display:block;width:100%;height:100%;background:#0b0908}
.film-play{position:absolute;inset:0;display:grid;place-content:end center;justify-items:center;gap:10px;padding-bottom:clamp(14px,6%,64px);color:var(--color-ink);cursor:pointer}
.film-play__word{font:400 clamp(34px,4.6vw,60px)/1 var(--font-display);background:rgba(251,250,247,.9);padding:.18em .5em .12em}
.film-play__time{font:12px var(--font-mono);color:var(--color-muted);background:rgba(251,250,247,.9);padding:4px 8px}
.film-stage[data-state=playing] .film-play>span,.film-stage[data-state=paused] .film-play__time{opacity:0}
.film-play>span{transition:opacity var(--dur-medium) var(--ease-out)}
.film-note{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)}
@media(max-width:900px){.history-film{font-size:13px}}
@media(max-width:600px){.film-view{padding:0 0 max(0px,env(safe-area-inset-bottom))}}
.film-stage video{outline:1px solid var(--color-rule);outline-offset:-1px}

/* The Index is the wall the shop kept: polaroids. Each frame is a print with the
   instant film's proportions (88 x 107: a square picture, a narrow margin on three sides
   and the deep strip below), warm white against the page's white so it reads as card,
   and turned a degree or two as if pinned by hand. Hovering straightens and lifts it.
   The slot under the picture is the unexposed film, so a picture still loading or
   still developing shows dark, not blank. */
.history-contact{--polaroid:#fbfaf6;grid-template-columns:repeat(auto-fill,minmax(42px,1fr));gap:7px 6px}
/* The first year's label hangs above its row and was cut by the top of the stream. */
@media(min-width:901px){.history-view[data-mode=contact] .history-stream{padding-top:20px}}
@media(max-width:900px){.history-contact{grid-template-columns:repeat(auto-fill,minmax(46px,1fr));gap:5px}}
@media(max-width:600px){.history-contact{grid-template-columns:repeat(auto-fill,minmax(40px,1fr));gap:4px}}
.history-contact .photo-button{aspect-ratio:auto;overflow:visible;padding:6% 5.5% 26%;
  background:linear-gradient(#37382f,#37382f) content-box no-repeat,var(--polaroid);
  box-shadow:0 0 0 .5px rgb(29 29 27 / .07),0 1px 1.5px rgb(29 29 27 / .12),0 5px 12px -6px rgb(29 29 27 / .3);
  rotate:var(--tilt,0deg)}
.history-contact .photo-button img{height:var(--print-img,auto);aspect-ratio:1;display:block;outline:.5px solid rgb(29 29 27 / .06);outline-offset:-.5px}
@media(hover:hover) and (pointer:fine){.history-contact .photo-button:hover{rotate:0deg}}
