/* ==========================================================================
   LINE AND LIGHT: components
   One gesture at four scales: a drawn outline whose openings fill with moving
   light, then widen. Loader, service bands, project switch, chapter change.
   ========================================================================== */

/* ---------- 1 · The loading ceremony ------------------------------------ */
/* Without a script there is no ceremony and nothing to dismiss, so the
   loader is never drawn at all. */
.load{display:none}
html.js .load{position:fixed;inset:0;z-index:900;background:var(--ink);
  display:grid;place-items:center;overflow:hidden}
html.js .load[hidden]{display:none}
.load__stage{position:relative;width:min(78vw,900px);aspect-ratio:16/9;
  transition:width .78s var(--ease-draw),height .78s var(--ease-draw)}
/* the frame itself opens, so the film grows to full bleed in one move rather
   than sitting in a box and then cutting */
.load.is-open .load__stage{width:100vw;height:100svh;aspect-ratio:auto}

/* the datum: struck at 120ms, then never moved again on the whole page */
.load__datum{position:absolute;left:0;right:0;top:50%;height:2px;
  background:var(--orange);transform:scaleX(0);transform-origin:left center}
.load.is-run .load__datum{transform:scaleX(1);transition:transform .72s var(--ease-draw) .1s}

/* the elevation draws itself */
.load__draw{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
.load__draw path,.load__draw line,.load__draw rect{
  fill:none;stroke:var(--paper);stroke-width:1.25;vector-effect:non-scaling-stroke;
  stroke-dasharray:var(--len,1200);stroke-dashoffset:var(--len,1200)}
.load.is-run .load__draw path,
.load.is-run .load__draw line,
.load.is-run .load__draw rect{
  stroke-dashoffset:0;transition:stroke-dashoffset 1.05s var(--ease-draw) .34s}

/* the drawn openings fill with the hero film */
.load__fill{position:absolute;inset:0;opacity:0;
  clip-path:polygon(28% 42%,43% 42%,43% 70%,28% 70%, 28% 42%, 57% 42%,72% 42%,72% 70%,57% 70%,57% 42%)}
/* A film and its poster are two children of the same box. Left in flow the
   film lands a whole frame below the poster and is clipped away: it plays,
   invisibly, and the visitor only ever sees the still. Every film is pinned
   over its poster. */
.load__fill video{position:absolute;inset:0}
.load__fill video,.load__fill img{width:100%;height:100%;object-fit:cover;
  filter:grayscale(1) contrast(1.06)}
.load.is-fill .load__fill{opacity:1;transition:opacity .45s linear}
.load.is-open .load__fill{clip-path:polygon(-20% -20%,120% -20%,120% 120%,-20% 120%, -20% -20%, -20% -20%,-20% -20%,-20% -20%,-20% -20%,-20% -20%);
  transition:clip-path .78s var(--ease-draw)}
.load.is-open .load__draw{opacity:0;transition:opacity .42s linear .1s}
.load.is-open .load__mark{opacity:0;transition:opacity .34s linear .22s}

.load__mark{position:absolute;left:0;top:calc(50% + 26px);display:grid;gap:6px;opacity:0}
.load.is-name .load__mark{opacity:1;transition:opacity .4s linear}
.load__mark img{height:22px;width:auto;filter:invert(1)}
.load__mark span{color:var(--grey-mid)}
.load__skip{position:fixed;right:var(--gut);bottom:26px;z-index:901;
  color:var(--grey-mid);letter-spacing:.16em;text-transform:uppercase;font-size:var(--t-note)}
.load__skip:hover{color:var(--paper)}

/* ---------- 2 · Header -------------------------------------------------- */
.top{position:fixed;inset:0 0 auto 0;z-index:300;display:flex;align-items:center;
  justify-content:space-between;padding:20px var(--gut);
  background:transparent;border-bottom:1px solid transparent;
  transition:background .3s linear,border-color .3s linear}
/* Past the hero the bar takes the ground it is standing on, the way a title
   block sits at the head of a sheet. Nothing then scrolls under open type. */
html.is-scrolled[data-topmode="paper"] .top,
html.is-scrolled[data-topmode="light"] .top{background:var(--paper);
  border-bottom-color:rgba(0,0,0,.14)}
html.is-scrolled[data-topmode="dark"] .top{background:rgba(0,0,0,.94);
  border-bottom-color:rgba(255,255,255,.14)}
html.is-scrolled .top::before{opacity:0}
html.menu-open .top{background:transparent;border-bottom-color:transparent}
html.menu-open .top::before{opacity:0}
html.menu-open .top a.lk,
html.menu-open .top__scale,
html.menu-open .top__menu{color:#fff}
html.menu-open .top__brand img{filter:invert(1)}
/* A blend mode made the header vanish over mid grey photography. The header
   carries its own light instead: a short scrim, and a theme read from whatever
   section is under the header band. */
.top::before{content:"";position:absolute;inset:0 0 auto 0;height:124px;
  z-index:-1;pointer-events:none;transition:opacity .4s linear;
  background:linear-gradient(180deg,rgba(0,0,0,.58) 0%,rgba(0,0,0,.22) 48%,rgba(0,0,0,0) 100%)}
html[data-topmode="light"] .top::before,
html[data-topmode="paper"] .top::before{opacity:0}
.top__brand img{height:20px;width:auto;filter:invert(1);transition:filter .3s linear}
html[data-topmode="light"] .top__brand img,
html[data-topmode="paper"] .top__brand img{filter:none}
.top__nav{display:none;gap:clamp(16px,2vw,34px)}
@media (min-width:860px){ .top__nav{display:flex} }
.top a.lk{color:#fff;font-size:var(--t-note);letter-spacing:.16em;
  text-transform:uppercase;font-weight:500}
.top__scale{color:#fff;font-size:var(--t-note);letter-spacing:.16em;font-weight:500;
  font-variant-numeric:tabular-nums}
.top a.lk,.top__scale{transition:color .3s linear}
html[data-topmode="light"] .top a.lk,
html[data-topmode="light"] .top__scale,
html[data-topmode="light"] .top__menu,
html[data-topmode="paper"] .top a.lk,
html[data-topmode="paper"] .top__scale,
html[data-topmode="paper"] .top__menu{color:var(--ink)}

/* ---------- 2b · The menu on a phone -------------------------------------
   Below the width that fits three links in the bar, they move into a panel.
   Without JavaScript the links stay in the bar instead, so navigation never
   depends on a script. */
.top__menu{display:none;color:#fff;transition:color .3s linear}
.menu{display:none}
@media (max-width:859px){
  html.js .top__menu{display:block}
  html.js .menu{position:fixed;inset:0;z-index:280;background:var(--ink);
    display:grid;align-content:center;gap:clamp(18px,4vh,34px);
    padding:0 var(--gut);opacity:0;visibility:hidden;
    transform:translateY(-10px);
    transition:opacity .34s var(--ease),transform .4s var(--ease),visibility .34s}
  html.js .menu.is-open{opacity:1;visibility:visible;transform:none}
  html:not(.js) .top__nav{display:flex;gap:clamp(10px,3vw,18px)}
  .top__scale{margin-left:auto;margin-right:clamp(14px,4vw,22px)}
}
.menu__datum{position:absolute;left:0;right:0;top:var(--datum);height:2px;
  background:var(--orange)}
.menu__nav{display:grid;gap:clamp(6px,1.4vh,14px)}
.menu__nav a{font-family:var(--display);font-weight:600;letter-spacing:-.03em;
  line-height:1.04;font-size:clamp(2.6rem,13vw,4.2rem);color:#fff}
.menu__mail{color:var(--grey-cool);margin-top:clamp(8px,2vh,18px)}
html.menu-open,html.menu-open body{overflow:hidden}

/* ---------- 3 · Hero ---------------------------------------------------- */
/* The content box starts below the datum, so the orange line can never strike
   through the first line of the headline. */
.hero{position:relative;min-height:100svh;overflow:hidden;background:#070707;
  display:flex;align-items:flex-end;padding-top:calc(var(--datum) + 2vh)}
.hero__film{position:absolute;inset:0}
.hero__film video,.hero__film img{width:100%;height:100%;object-fit:cover;
  filter:grayscale(1) contrast(1.07)}
.hero__film video{position:absolute;inset:0;opacity:0;transition:opacity .7s linear}
.hero__film video.is-ready{opacity:1}
.hero::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(183deg,rgba(0,0,0,.52) 0%,rgba(0,0,0,.05) 34%,rgba(0,0,0,.82) 100%)}
/* the datum, held at the same screen position the loader struck it */
.hero__datum{position:absolute;left:0;right:0;top:var(--datum);height:2px;
  background:var(--orange);z-index:2;opacity:.9}
.hero__in{position:relative;z-index:3;width:100%;padding-bottom:clamp(28px,5vh,66px)}
.hero h1{color:#fff;font-size:min(clamp(2.5rem,8.4vw,7.8rem),12.4vh);max-width:13ch}
.hero h1 .ln{display:block;overflow:hidden;padding-block:.06em .12em;margin-block:-.06em}
.hero h1 .ln>span{display:block}
html.js .hero h1 .ln>span[data-in]:not(.is-in){transform:translateY(104%);opacity:1}
.hero__lead{margin-top:clamp(16px,2.4vh,26px);font-size:var(--t-lead);
  font-weight:500;color:#fff;max-width:46ch}
.hero__acts{margin-top:clamp(18px,2.6vh,30px);display:flex;flex-wrap:wrap;gap:10px}

.btn{display:inline-flex;align-items:center;gap:12px;padding:14px 24px;
  font-size:var(--t-note);letter-spacing:.16em;text-transform:uppercase;font-weight:600;
  border:1px solid rgba(255,255,255,.52);color:#fff;
  transition:background .3s var(--ease),color .3s var(--ease),border-color .3s var(--ease)}
.btn--fill{background:var(--orange);border-color:var(--orange);color:#000}
.btn:hover{background:#fff;border-color:#fff;color:#000}

/* ---------- 4 · Service bands ------------------------------------------- */
.svc{background:var(--ink)}
.band{position:relative;border-top:1px solid rgba(255,255,255,.14)}
.band__in{display:grid;gap:clamp(20px,3vw,48px);
  padding-block:clamp(48px,8vh,110px)}
.band__num{color:var(--orange);font-family:var(--display);font-weight:600;
  font-size:clamp(2.4rem,5vw,4rem);line-height:.9}
.band h3{color:#fff;font-size:clamp(1.7rem,3.4vw,2.9rem);margin-top:8px}
.band p{color:var(--grey-cool);max-width:44ch;margin-top:14px}
.band__list{margin-top:20px;display:grid;gap:9px}
.band__list li{color:#fff;font-size:var(--t-body);display:flex;align-items:baseline;gap:12px}
.band__list li::before{content:"";width:16px;height:1px;background:var(--orange);flex:none;
  transform:translateY(-4px)}
.band__fig{position:relative;overflow:hidden;background:#111}
/* The service bands describe how a building happens, so they are read as
   grey. Colour is kept for the projects and for the studio itself. */
.band__fig img{width:100%;height:100%;object-fit:cover;filter:grayscale(1) contrast(1.06)}
/* the line work drawn over the photograph, in register with it */
.band__over{position:absolute;inset:0;width:100%;height:100%;pointer-events:none}
.band__over path,.band__over line,.band__over rect,.band__over circle{
  fill:none;stroke:rgba(255,255,255,.85);stroke-width:1;vector-effect:non-scaling-stroke;
  stroke-dasharray:var(--len,900);stroke-dashoffset:var(--len,900)}
.band__over--ink path,.band__over--ink line,
.band__over--ink rect,.band__over--ink circle{stroke:rgba(0,0,0,.62)}
.band__over .mark,.band__over--ink .mark{stroke:var(--orange)}
.band.is-in .band__over path,.band.is-in .band__over line,
.band.is-in .band__over rect,.band.is-in .band__over circle{
  stroke-dashoffset:0;transition:stroke-dashoffset .95s var(--ease-draw)}

@media (min-width:900px){
  .band--a .band__in{grid-template-columns:minmax(0,1.3fr) minmax(0,1fr);align-items:center}
  .band--b .band__in{grid-template-columns:1fr;padding-block:0}
  .band--c .band__in{grid-template-columns:minmax(0,1fr) minmax(0,1.15fr);align-items:center}
  .band--c .band__fig{order:2}
}
/* band B is the loud one: full bleed with the copy over it */
.band--b{position:relative}
.band--b .band__fig{position:absolute;inset:0;height:100%}
.band--b .band__in{position:relative;z-index:2;min-height:78svh;display:flex;
  align-items:flex-end;padding-block:clamp(40px,7vh,90px)}
.band--b::after{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(180deg,rgba(0,0,0,.42) 0%,rgba(0,0,0,.1) 40%,rgba(0,0,0,.8) 100%)}
.band--c{background:var(--paper)}
.band--c h3,.band--c .band__list li{color:var(--ink)}
.band--c p{color:#3a3a3a}

.svc__head{padding-block:clamp(54px,9vh,120px) clamp(26px,4vh,54px);display:grid;gap:18px}
@media (min-width:980px){
  .svc__head{grid-template-columns:minmax(0,1fr) minmax(0,27rem);align-items:end;
    gap:clamp(24px,4vw,70px)}
}
.svc__head h2{color:#fff;font-size:clamp(2.2rem,5.4vw,4.6rem);text-wrap:balance}
/* the authored line breaks are for the wide layout; on a phone they leave a
   one word line, so the sentence is allowed to find its own breaks */
@media (max-width:700px){ .svc__head h2 br{display:none} }
.svc__head p{color:var(--grey-cool)}

/* ---------- 5 · The project gallery ------------------------------------- */
.work{background:var(--paper);color:var(--ink);padding-block:clamp(54px,9vh,120px)}
.work__head{display:grid;gap:18px;padding-bottom:clamp(26px,4vh,52px)}
@media (min-width:980px){
  .work__head{grid-template-columns:minmax(0,1fr) minmax(0,27rem);align-items:end;
    gap:clamp(24px,4vw,70px)}
}
.work__head h2{font-size:clamp(2.2rem,5.4vw,4.6rem);text-wrap:balance}
.work__head p{color:#3a3a3a}

.gal{position:relative;margin-top:clamp(20px,3vh,36px)}
.gal__track{display:flex;gap:var(--gut);overflow-x:auto;overflow-y:hidden;
  scroll-snap-type:x mandatory;scroll-padding-inline:var(--gut);
  padding-inline:var(--gut);padding-bottom:18px;scrollbar-width:none;
  -webkit-overflow-scrolling:touch;
  -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 var(--fade-l),
    #000 calc(100% - var(--fade-r)),transparent 100%);
  mask-image:linear-gradient(90deg,transparent 0,#000 var(--fade-l),
    #000 calc(100% - var(--fade-r)),transparent 100%)}
/* the card running off the edge dissolves rather than being guillotined */
.gal{--fade-l:0px;--fade-r:clamp(64px,16vw,260px)}
.gal.is-mid{--fade-l:clamp(18px,3vw,46px)}
.gal.is-end{--fade-l:clamp(64px,16vw,260px);--fade-r:0px}
/* On a phone the next card shows as a deliberate edge rather than a sliver,
   and no fade is allowed to reach the card being read. */
@media (max-width:700px){
  /* exactly the width left over beside a card, so the fade covers the peeking
     card and never touches the one being read */
  .gal{--fade-l:0px;--fade-r:calc(16vw - var(--gut))}
  .gal.is-mid{--fade-l:var(--gut)}
  .gal.is-end{--fade-l:calc(16vw - var(--gut));--fade-r:0px}
  .slide{width:84vw}
}
.gal__track::-webkit-scrollbar{display:none}
.gal__track:focus{outline:none}
.gal__track:focus-visible{outline:2px solid var(--orange);outline-offset:6px}
.slide{flex:0 0 auto;width:min(88vw,620px);scroll-snap-align:start;position:relative}
@media (min-width:1000px){ .slide{width:min(62vw,880px)} }

/* The numeral is the sheet number, set above the frame where it is always
   legible. Multiplying it over a dark photograph turned it almost black. */
.slide__num{display:block;color:var(--orange);font-family:var(--display);
  font-weight:600;line-height:.82;letter-spacing:-.04em;
  font-size:clamp(2.6rem,6vw,5rem);margin-bottom:.14em}
.slide__frame{position:relative;overflow:hidden;background:#111;aspect-ratio:16/10}
.slide__sheet{position:absolute;inset:0;opacity:0;visibility:hidden}
.slide__sheet.on{opacity:1;visibility:visible}
.slide__sheet img,.slide__sheet video{width:100%;height:100%;object-fit:cover}
.slide__sheet video{position:absolute;inset:0}
/* The sheets. One convention across all eight drawings: cut work in poche,
   fabric at full weight, everything seen beyond it thinner, annotation small,
   and orange reserved for dimensions, levels and the route. */
.slide__sheet--draw{background:var(--ink);display:grid;place-items:center;padding:2.6%}
.slide__sheet--draw svg{width:100%;height:100%}
.slide__sheet--draw path,.slide__sheet--draw line,.slide__sheet--draw rect,
.slide__sheet--draw circle,.slide__sheet--draw polyline,.slide__sheet--draw polygon{
  fill:none;stroke:rgba(255,255,255,.74);stroke-width:1;vector-effect:non-scaling-stroke}
.slide__sheet--draw .w{stroke:#fff;stroke-width:2.2}
.slide__sheet--draw .t{stroke:rgba(255,255,255,.46);stroke-width:.85}
.slide__sheet--draw .g{stroke:rgba(255,255,255,.2);stroke-width:.85}
.slide__sheet--draw .poche{fill:rgba(255,255,255,.92);stroke:none}
.slide__sheet--draw .fillt{fill:rgba(255,255,255,.055);stroke:none}
.slide__sheet--draw .mark{stroke:var(--orange);stroke-width:1}
.slide__sheet--draw text{fill:rgba(255,255,255,.6);stroke:none;font-family:var(--text);
  font-size:13px;font-weight:500;letter-spacing:.14em}
.slide__sheet--draw .ttl{fill:#fff;font-size:15px;letter-spacing:.17em}
.slide__sheet--draw .dim{fill:var(--orange);letter-spacing:.1em}
/* on a phone the sheet reads as line work; the words are on the card below */
@media (max-width:760px){ .slide__sheet--draw text{display:none} }

/* the iris: same gesture as the loader, at frame scale */
.slide__frame.is-iris .slide__sheet{clip-path:inset(42% 44% 42% 44%)}
.slide__frame .slide__sheet{clip-path:inset(0% 0% 0% 0%);
  transition:clip-path .3s var(--ease-draw),opacity .25s linear}

.slide__bar{display:flex;flex-wrap:wrap;gap:10px 18px;align-items:center;
  margin-top:16px}
.sheets{display:flex;flex-wrap:wrap;border:1px solid rgba(0,0,0,.3)}
@media (max-width:400px){
  .sheets button{padding-inline:10px;letter-spacing:.08em}
}
.sheets button{padding:9px 15px;font-size:var(--t-note);letter-spacing:.14em;
  text-transform:uppercase;font-weight:600;color:#555;
  transition:background .25s var(--ease),color .25s var(--ease)}
.sheets button + button{border-left:1px solid rgba(0,0,0,.3)}
.sheets button[aria-checked="true"]{background:var(--ink);color:#fff}
.sheets button:hover{color:var(--ink)}
.sheets button[aria-checked="true"]:hover{color:#fff}
.slide__status{margin-left:auto;display:inline-flex;align-items:center;gap:9px;
  color:#555;font-size:var(--t-note);letter-spacing:.12em;text-transform:uppercase}
.slide__status::before{content:"";width:8px;height:8px;background:var(--orange);flex:none}
@media (max-width:620px){ .slide__status{margin-left:0} }

.slide__body{margin-top:16px;display:grid;gap:10px}
.slide__body h3{font-size:clamp(1.8rem,3.6vw,3rem)}
.slide__meta{color:#555;font-size:var(--t-note);letter-spacing:.1em;text-transform:uppercase}
.slide__note{color:#3a3a3a;max-width:50ch}

.gal__bar{display:flex;align-items:center;justify-content:space-between;
  gap:var(--gut);margin-top:clamp(18px,3vh,30px)}
.dots{display:flex;gap:9px;align-items:center}
.dot{width:36px;height:12px;padding:5px 0;position:relative}
.dot::after{content:"";position:absolute;left:0;right:0;top:5px;height:2px;
  background:rgba(0,0,0,.26);transition:background .25s linear,height .25s linear}
.dot[aria-current="true"]::after{background:var(--orange);height:3px;top:4px}
.dot:hover::after{background:rgba(0,0,0,.6)}
.gal__nav{display:flex;gap:10px}
.gal__btn{width:46px;height:46px;border:1px solid rgba(0,0,0,.3);display:grid;
  place-items:center;transition:border-color .25s,color .25s,background .25s}
.gal__btn svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.8}
.gal__btn:hover:not(:disabled){background:var(--ink);border-color:var(--ink);color:#fff}
.gal__btn:disabled{opacity:.28;cursor:default}
/* Without a script the carousel controls are not there to be pressed, and the
   three sheets simply stack, captioned, wherever a project frame appears. The
   carousel and the sheet switch are separate now, so each has its own flag. */
html:not(.js-gal) .gal__nav,html:not(.js-gal) .dots{display:none}
html:not(.js-sheets) .slide__sheet{position:relative;opacity:1;visibility:visible}
html:not(.js-sheets) .slide__frame{aspect-ratio:auto}
html:not(.js-sheets) .sheets{display:none}

/* ---------- 6 · The chapter change -------------------------------------- */
.chapter{position:relative;background:var(--ink);overflow:hidden}
.chapter__wipe{position:absolute;left:0;right:0;top:0;height:0;background:var(--ink);
  z-index:2;pointer-events:none}
.chapter__film{position:relative;min-height:84svh;overflow:hidden;background:#070707}
.chapter__film video,.chapter__film img{position:absolute;inset:0;
  width:100%;height:100%;object-fit:cover}
.chapter__film video{opacity:0;transition:opacity .7s linear}
.chapter__film video.is-ready{opacity:1}
.chapter::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:1;
  background:linear-gradient(180deg,rgba(0,0,0,.72) 0%,rgba(0,0,0,.18) 42%,rgba(0,0,0,.86) 100%)}
.chapter__in{position:absolute;inset:auto 0 0 0;z-index:3;
  padding-bottom:clamp(30px,6vh,70px)}
.chapter h2{color:#fff;font-size:clamp(2.2rem,5.6vw,4.8rem);max-width:15ch}
.chapter p{color:var(--grey-cool);margin-top:16px;max-width:46ch;font-size:var(--t-lead)}
.chapter__datum{position:absolute;left:0;right:0;top:var(--datum);height:2px;
  background:var(--orange);z-index:3;opacity:.9}

/* the colophon moved into the shared footer; see pages.css */
