@charset "UTF-8";@font-face{font-display:swap;font-family:Archivo;font-style:normal;font-weight:300 700;src:url(../fonts/Archivo.woff2) format("woff2")}@font-face{font-display:swap;font-family:InterTight;font-style:normal;font-weight:200 600;src:url(../fonts/InterTight.woff2) format("woff2")}@font-face{font-display:swap;font-family:JetBrainsMono;font-style:normal;font-weight:400 500;src:url(../fonts/JetBrainsMono.woff2) format("woff2")}/* === inline.css === */h1,h2,h3,h4{font-family:Archivo,sans-serif;font-weight:400}.font__filter{display:none}h5{font-family:Archivo,sans-serif;font-size:3vw;font-weight:400;line-height:.95}@media screen and (max-width:600px){h5{font-size:10vw}}h1{font-size:6vw;line-height:.9}@media screen and (max-width:1300px){h1{font-size:62px}}@media screen and (max-width:600px){h1{font-size:40px}}h1 .line__inner{padding-bottom:.5vw;position:relative;top:.3vw}h1.lead{font-size:12vw;letter-spacing:-.1vw}@media screen and (max-width:600px){h1.lead{font-size:20vw}}h1.lead .line__inner{padding-bottom:1.5vw;position:relative;top:1vw}h1.medium{font-size:6.5vw;line-height:.1;margin-top:-2vw}@media screen and (max-width:600px){h1.medium{font-size:16vw;line-height:.4}}h1.medium .line{overflow:visible}h1.medium .line__inner{padding-bottom:5vw;position:relative;top:1vw}h2{font-size:12.5vw;letter-spacing:-.5vw;line-height:1}@media screen and (max-width:600px){h2{font-size:20vw}}h2.lead{font-size:14vw}@media screen and (max-width:600px){h2.lead{font-size:20vw}}h2 small{position:relative;top:4vw}h3{font-size:8vw;letter-spacing:-.1vw;line-height:.95}@media screen and (max-width:600px){h3{font-size:15vw}}h4{font-size:6vw;line-height:.85}@media screen and (max-width:600px){h4{font-size:10vw}}small{font-size:50%;letter-spacing:0}p.lead{font-family:Archivo,sans-serif;font-size:2.8vw;line-height:1;margin-bottom:4vw}@media screen and (max-width:600px){}@media screen and (max-width:600px){p.lead{font-size:30px;margin-bottom:30px}}p.lead.last{margin-bottom:8vw}@media screen and (max-width:600px){p.lead.last{margin-bottom:60px}}p.lead .line__inner{padding-bottom:.1vw;position:relative;top:.1vw}@media screen and (max-width:600px){p.lead .line__inner{padding-bottom:2px;top:2px}}.monospace{font-family:JetBrainsMono,monospace;font-size:50%;font-weight:400;letter-spacing:-.05vw;text-transform:uppercase}.monospace__p{font-size:70%;text-transform:none}.layout__third.monospace{padding-left:3vw;padding-top:.8vw;position:relative;white-space:pre-line}.layout__third.monospace.nobullet:before{content:""}@media screen and (max-width:600px){.layout__third.monospace{padding-left:0}.layout__third.monospace:before{content:""}}code{background-color:#000;border-radius:var(--radius);display:block;font-family:JetBrainsMono,monospace;font-size:70%;letter-spacing:-.01vw;margin:.2vw 0;padding:.5vw 1vw}@media screen and (max-width:600px){code{margin:.2vh 0;padding:.5vh 1vh}}article{padding:20vw 0}@media screen and (max-width:600px){article{padding:20vh 0 10vh}}article{letter-spacing:0}article a{text-decoration:underline}article ol,article p,article ul{font-size:90%}@media screen and (max-width:600px){article ol,article p,article ul{font-size:100%}}article hr{border:none;display:block;margin-top:2vw;padding-top:3vw;position:relative}article hr:before{border-top:1px solid hsla(0,0%,100%,.4);content:"";height:1px;left:0;position:absolute;top:0;width:20%}article blockquote{border-left:3px solid hsla(0,0%,100%,.3);margin-bottom:3vw;padding-left:2vw}@media screen and (max-width:600px){article blockquote{margin-bottom:5vh}}article blockquote p:last-child{padding-bottom:0}article h1{font-size:5vw;max-width:45vw;padding-bottom:5vw}@media screen and (max-width:600px){article h1{font-size:40px;max-width:85vw;padding-bottom:5vh}}article h5,article h6,article ol,article p,article ul{max-width:45vw;padding-bottom:3vw}@media screen and (max-width:600px){article h5,article h6,article ol,article p,article ul{max-width:85vw;padding-bottom:5vh}}article h2,article h3,article h4{max-width:45vw;padding:3vw 0}@media screen and (max-width:600px){article h2,article h3,article h4{max-width:80vw;padding:5vh 0}}article h2,article h3{font-size:5vw;font-weight:400;letter-spacing:-.1vw;line-height:.95}@media screen and (max-width:600px){article h2,article h3{font-size:15vw}}article h4{border-top:var(--border);font-size:250%}article h5{font-size:100%;font-weight:700}article h6{font-family:JetBrainsMono,monospace;font-size:55%;font-weight:400;letter-spacing:-.01vw;margin-top:-2%;padding-bottom:6vw;padding-right:10%;text-transform:uppercase}article ol,article ul{padding-left:0}@media screen and (max-width:600px){article ol,article ul{padding-left:0}}article ol li,article ul li{border-bottom:1px solid hsla(0,0%,100%,.4);list-style:none;margin-bottom:1vw;padding-bottom:1vw}article ol li:last-child,article ul li:last-child{border-bottom:none}@media screen and (max-width:600px){article ol li,article ul li{margin-bottom:2vh;padding-bottom:2vh}}*{margin:0;padding:0}*,body{box-sizing:border-box}body{-webkit-text-size-adjust:100%;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-display:swap;overflow-x:hidden}a{color:inherit;cursor:pointer;font-weight:inherit;outline:0;text-decoration:none}address{font-style:normal}figure{margin:0;padding:0}img,picture,video{display:block;height:100%;-o-object-fit:cover;object-fit:cover;-o-object-position:center top;object-position:center top;width:100%;will-change:transform}:root{--bgcolor:#1a1a1a;--primarycolor:#bababa;--red:#ff001a;--grey:#bababa;--black:#111;--lightblue:#9fe4f3;--blue:#03049c;--cream:#bab5a6;--green:#0f0;--pink:#a7849d;--lightgrey:#71737d;--columns:20;--bannerHeight:170vh;--radius:.5vw;--border:1px solid hsla(0,0%,100%,.7);--borderFade:1px solid hsla(0,0%,100%,.5)}@media screen and (max-width:600px){:root{--bannerHeight:100lvh;--radius:1vh}}.nuxt-loading-indicator{background:var(--primarycolor)!important;mix-blend-mode:difference}body{background-color:var(--bgcolor);color:var(--primarycolor);font-family:InterTight,sans-serif;font-size:1.7vw}@media screen and (max-width:1300px){body{font-size:20px}}main{min-height:100dvh;width:100vw}.opacity__50{opacity:.5}.topOverlay{background:linear-gradient(180deg,var(--background,var(--bgcolor)) 2%,transparent 100%);height:20vh;left:0;margin-bottom:-20vh;opacity:1;pointer-events:none;position:fixed;top:0;width:100%;z-index:2}.topOverlay__section{opacity:0;position:sticky;top:0;transition:opacity .3s ease}.topOverlay__section.is-visible{opacity:1}.cursor{height:100%;left:0;mix-blend-mode:difference;pointer-events:none;position:fixed;top:0;width:100%;z-index:99;--size:calc(100vw/var(--columns))}@media screen and (max-width:1300px){.cursor{display:none}}.cursor__inner{display:grid;grid-template-columns:repeat(var(--columns),var(--size))}.cursor__inner-box{background:#fff;border-radius:0;height:var(--size);opacity:0;width:var(--size)}.overlay{bottom:0;display:grid;grid-area:1/1/-1/-1;grid-template-columns:repeat(var(--columns),1fr);height:100vh;pointer-events:none;position:absolute;width:100vw;z-index:4}.overlay div{background:var(--color-bg-overlay);transform:scaleY(0)}.overlay__red{--color-bg-overlay:var(--red)}.overlay__cream{--color-bg-overlay:var(--cream)}.overlay__blue{--color-bg-overlay:var(--blue)}.overlay__grey{--color-bg-overlay:var(--bgcolor)}.overlay__lightgrey{--color-bg-overlay:var(--lightgrey)}.overlay__black{--color-bg-overlay:var(--black)}.buttons{display:flex;flex-wrap:wrap;justify-content:space-between}.button{--anim:0;color:var(--color);font-family:JetBrainsMono,monospace;font-size:70%;letter-spacing:-.05vw;position:relative}.button__big{border-bottom:1px solid var(--color);display:flex;justify-content:space-between;padding:1vw 0;width:100%}.button__big:first-child{border-top:1px solid var(--color)}@media screen and (max-width:600px){.button__big{padding:10px 0}}.button__half{border-bottom:1px solid var(--color);display:flex;justify-content:space-between;padding:.5vw 0;width:48%}@media screen and (max-width:600px){.button__half{width:100%}}.button__half:first-child,.button__half:nth-child(2){border-top:1px solid var(--color)}@media screen and (max-width:600px){.button__half:nth-child(2){border-top:none}}.button span{position:relative;transition:padding .3s ease}.button:before{background-color:var(--color);content:"";height:calc(100% + 3px);left:0;position:absolute;top:0;transform:scaleY(var(--anim));transform-origin:50% var(--button-origin,100%);width:100%;z-index:0}.button:hover{color:var(--bgcolor)}.button:hover>span{padding:0 1vw}.bg__red{background-color:var(--red)}.accordion{line-height:1.2;list-style-type:none;padding-bottom:3vw}@media screen and (max-width:600px){.accordion{font-size:90%;padding:20px 0 60px}}.accordion li{--anim:0;cursor:pointer;overflow:hidden;position:relative;transition:color .1s ease}.accordion li:before{background-color:var(--primarycolor);content:"";height:calc(100% + 3px);left:0;mix-blend-mode:difference;position:absolute;top:0;transform:scaleY(var(--anim));transform-origin:50% var(--accordion-origin,100%);width:100%;z-index:2}.accordion li>*{position:relative;z-index:1}@media screen and (max-width:600px){.accordion li{padding:.5vw 0}.accordion li .layout__third{display:none}}.accordion li:last-child{border-bottom:none}.accordion li h5{margin-top:0}.accordion li a{cursor:pointer;display:block;opacity:1;transition:opacity .5s ease}@media screen and (max-width:600px){.accordion li a{padding:10px 20px 10px 0}}.accordion li .more{font-size:4vw;font-weight:100;line-height:1;opacity:.3;position:absolute;right:3vw;top:-.7vw;transition:all .3s ease}@media screen and (max-width:600px){.accordion li .more{font-size:40px;top:4px;transform:translateY(0)}}.accordion li.selected{--anim:0!important}.accordion li.selected a{opacity:1}.accordion__content{height:0;overflow:hidden}.accordion__content p{line-height:1.4;max-width:70%;padding-bottom:5vw;padding-top:5vw}@media screen and (max-width:600px){.accordion__content p{font-size:90%;font-weight:400;margin-bottom:60px;margin-top:10px;max-width:100%}}.accordion__content p a{display:inline;padding:0}html.lenis{height:auto}html.lenis.lenis-smooth{scroll-behavior:auto}html.lenis.lenis-smooth [data-lenis-prevent]{overscroll-behavior:contain}html.lenis.lenis-stopped{overflow:hidden}@media screen and (max-width:600px){html.lenis.lenis-stopped{overflow:auto}}html.lenis.lenis-scrolling iframe{pointer-events:none}html.has-scroll-dragging{-webkit-user-select:none;-moz-user-select:none;user-select:none}.hover_effect,.splitting,[data-splitting]{opacity:0}.footer .hover_effect,.footer .splitting,.footer [data-splitting],header .hover_effect,header .splitting,header [data-splitting]{opacity:1}.line{display:block;overflow:hidden}.line__inner{display:block;transform-origin:left top}.splitting .char{position:relative}.splitting .char,.splitting .word{display:inline-block}.block{display:block}.menu__hover{counter-reset:menucounter}.menu__hover,.menu__hover .menu__item,.menu__hover .menu__item-text,.menu__hover .menu__item-textinner{position:relative}.menu__hover .hover-reveal{height:25vw;left:0;opacity:0;pointer-events:none;position:absolute;top:0;width:20vw;will-change:transform,filter;z-index:-1}@media screen and (max-width:600px){.menu__hover .hover-reveal{display:none}}.menu__hover .hover-reveal__inner{border-radius:var(--radius);overflow:hidden}.menu__hover .hover-reveal__img,.menu__hover .hover-reveal__inner{height:100%;position:relative;width:100%}.menu__hover .hover-reveal__img{background-position:50% 50%;background-size:cover}.layout{display:flex;flex-wrap:wrap;justify-content:space-between;padding:1.5vw 3vw;width:100vw}.layout__third{width:33%}@media screen and (max-width:600px){.layout__third{width:100%}.layout__third.monospace{padding-bottom:40px}}.layout__second{width:66%}@media screen and (max-width:600px){.layout__second{width:100%}}.layout__half{width:50%}@media screen and (max-width:600px){.layout__half{width:100%}.layout{display:block;padding:10px 20px}}.heading__text--subtitle,.heading__text--title{left:15vw;text-align:center;width:70vw;z-index:1}@media screen and (max-width:600px){.heading__text--subtitle,.heading__text--title{left:0;width:100vw}}.heading__text .line{display:inline-block;padding-right:.2vw}@media screen and (max-width:600px){.heading__text .line{margin-top:-30px}}.heading__text--title{position:absolute;top:41vh}@media screen and (max-width:600px){.heading__text--title{top:50svh}}.heading__text--title .line{margin-right:2vw}.heading__text--subtitle{bottom:2vw;letter-spacing:0;position:fixed}@media screen and (max-width:600px){.heading__text--subtitle{bottom:auto;top:61svh}}.heading__text--subtitle .line:first-child{margin-right:2vw}.heading__text--subtitle .line:last-child{margin-left:2vw}.heading__text--subtitle,.heading__text--title{align-items:center;display:flex;justify-content:center}.heading__text sup{font-size:90%;left:-1.7vw;position:relative;top:-5vw;width:2vw}@media screen and (max-width:600px){.heading__text sup{font-size:80%;top:-5svh}}.heading__text h4{font-size:100%;line-height:1.2}.heading__text h2,.heading__text h3{line-height:1.1}.section{padding:5vw 0 10vw;position:relative;--color:var(--primarycolor);background-color:var(--background);color:var(--color)}@media screen and (max-width:600px){.section{padding:30px 0 60px}}.section__header{padding:30vw 0 10vw}@media screen and (max-width:600px){.section__header{padding:50vh 0 10vh 20px}}.section .separator{border-top:1px solid var(--color);letter-spacing:0;padding-top:1.5vw;position:sticky;top:1vw;width:100%}@media screen and (max-width:600px){.section .separator{padding-bottom:40px;padding-top:10px}}.section__grey{--background:var(--bgcolor)}.section__lightgrey{--background:var(--lightgrey);--color:var(--black)}.section__lightgrey .button:hover{color:var(--grey)}.section__lightgrey .marqueeText:after,.section__lightgrey .marqueeText:before{border-color:var(--black)}.section__lightgrey .button{border-width:2px;font-weight:600}.section__red{--background:var(--red);--color:#000}.section__red .button:hover{color:var(--grey)}.section__cream{--background:var(--cream);--color:#000}.section__cream .button:hover{color:var(--grey)}.section__black{--background:var(--black);--color:var(--grey)}.section__blue{--background:var(--blue);--color:var(--grey)}.no__p{padding:0!important}.no__pb{padding-bottom:0!important}.no__pt{padding-top:.3vw!important}.large__pb{padding-bottom:20vw!important}@media screen and (max-width:600px){.large__pb{padding-bottom:40vh!important}}.large__pt{padding-top:20vw!important}@media screen and (max-width:600px){.large__pt{padding-top:20vh!important}.hide__mobile{display:none}}.wrapper{height:100%}.wrapper:after{animation:foreground .5s steps(1) infinite;background-image:url(../img/noise.png);background-position:50%;content:"";height:calc(100% + 20rem);left:-10rem;mix-blend-mode:overlay;opacity:.3;pointer-events:none;position:fixed;top:-10rem;width:calc(100% + 20rem);z-index:100}@media screen and (max-width:600px){.wrapper:after{display:none}}@keyframes foreground{0%{transform:translate3d(0,9rem,0)}10%{transform:translate3d(-1rem,-4rem,0)}20%{transform:translate3d(-8rem,2rem,0)}30%{transform:translate3d(9rem,-9rem,0)}40%{transform:translate3d(-2rem,7rem,0)}50%{transform:translate3d(-9rem,-4rem,0)}60%{transform:translate3d(2rem,6rem,0)}70%{transform:translate3d(7rem,-8rem,0)}80%{transform:translate3d(-9rem,1rem,0)}90%{transform:translate3d(6rem,-5rem,0)}to{transform:translate3d(-7rem,0,0)}}.gloom{overflow:hidden;z-index:23}.gloom,.gloom:before{height:100vh;left:0;pointer-events:none;position:fixed;top:0;width:100vw}.gloom:before{-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);content:"";opacity:.15}@media screen and (max-width:600px){.gloom:before{-webkit-backdrop-filter:blur(5px);backdrop-filter:blur(5px);opacity:.2}}.vignette{height:100dvh;overflow:hidden;width:100vw;z-index:100}.vignette,.vignette:before{left:0;pointer-events:none;position:fixed;top:0}.vignette:before{background-image:url(../img/crt.png);background-repeat:no-repeat;background-size:100% 100%;content:"";height:100%;opacity:.7;transform:scale(1.02);width:100%}.static__wrapper{padding-top:0}.errorScreen,.static__wrapper--inner{min-height:100vh}.errorScreen{align-items:center;display:flex;padding:0}.errorScreen__inner{display:flex;flex-direction:column;justify-content:center;padding:0 6vw;width:100%}.errorScreen__label{align-self:center;background:var(--grey);color:var(--blue);margin-bottom:2vw;padding:0 .6em}.errorScreen__copy{margin:0 auto;max-width:72ch}.errorScreen__copy p{margin:0 0 2vw}.errorScreen__continue{background:transparent;border:0;color:inherit;cursor:pointer;display:block;font:inherit;margin-top:.3em;padding:0;text-align:center;text-decoration:none;width:100%}@media screen and (max-width:600px){.errorScreen__inner{font-size:13px;padding:0 24px}.errorScreen__label{margin-bottom:28px}.errorScreen__copy{max-width:100%}}header{position:fixed;top:0;z-index:21}header:after{content:"";height:1px;left:3vw;position:absolute;right:3vw;top:5vw}@media screen and (max-width:600px){header:after{border-bottom:none}}header .nav{align-items:flex-start;font-family:InterTight,sans-serif;justify-content:flex-end}header .nav a{display:block;padding:.3vw .7vw}header .menu{background:transparent;border:0;color:inherit;cursor:pointer;display:block;font:inherit;padding:1.66vw 3vw;position:fixed;right:0;top:0;z-index:4}@media screen and (max-width:600px){header .menu{margin-top:30px;right:20px}}header .menu{display:none}@media screen and (max-width:600px){header .menu{display:block}}header .nav{display:flex}@media screen and (max-width:600px){header .nav{display:none}header .logo{padding:6px 20px}}header .logo svg{height:auto;margin-top:.3vw;width:10vw}@media screen and (max-width:1300px){header .logo svg{margin-top:6px;width:115px}}.nav__overlay{background:linear-gradient(180deg,#393939e6 3%,#39393900);display:none;height:60vh;opacity:1;z-index:3}.mobilenav,.nav__overlay{left:0;pointer-events:none;position:fixed;top:0;width:100vw}.mobilenav{background-color:var(--blue);clip-path:rect(0 100% 0 0);color:var(--grey);height:85svh;padding:20svh 0 0 10px;z-index:20}.mobilenav__backdrop{background-color:#000c;height:100lvh;left:0;opacity:0;pointer-events:none;position:fixed;top:0;transition:opacity .2s linear;width:100vw;z-index:3}.mobilenav__main a{display:block;font-family:Archivo,sans-serif;font-size:42px;line-height:1;padding:5px 10px}.mobilenav__main a .line__inner{padding-bottom:1px;position:relative;top:1px}.mobilenav__social{bottom:5vh;position:absolute}.mobilenav__social a{display:block;padding-left:10px}body.menu_open{overflow:hidden}body.menu_open .mobilenav{pointer-events:all}body.menu_open .mobilenav__backdrop{opacity:1}.logo3d{pointer-events:none;position:absolute;z-index:3}.logo3d--hero{bottom:auto;height:32vh;left:50vw;top:55vh;transform:translate(-50%,-50%);width:70vw}@media screen and (max-width:600px){.logo3d--hero{height:32vh;top:45vh;width:70vw}}.logo3d__canvas{height:100%;width:100%}.logo3d__canvas canvas{display:block;height:100%!important;width:100%!important}.home{--primarycolor:#D9DCDF}.home__wrapper{z-index:2}.homeHeroIntro,.home__wrapper{position:relative}.marqueeText{--marquee-line-scale:0;height:17vw;left:0;overflow:hidden;pointer-events:none;position:fixed;top:3.5vw;white-space:nowrap;width:100%;z-index:3}@media screen and (max-width:600px){.marqueeText{height:100px;top:80px}}.marqueeText:after,.marqueeText:before{border-bottom:var(--border);border-width:2px;content:"";height:1px;left:3vw;position:absolute;transform:scaleX(var(--marquee-line-scale));transform-origin:left top;width:94vw}.marqueeText:before{top:1.4vw}@media screen and (max-width:600px){.marqueeText:before{top:2px}}.marqueeText:after{bottom:4vw}.marqueeText__track{display:flex;left:0;position:absolute;top:0;white-space:nowrap;width:-moz-max-content;width:max-content;will-change:transform}.marqueeText__title{display:inline-flex;flex:0 0 auto;line-height:.96;margin-bottom:2vw;white-space:nowrap}@media screen and (max-width:600px){.marqueeText__title{margin-bottom:5vh}}.marqueeText .line{display:inline-block}.marqueeText__symbol{font-family:inherit;padding:0 2vw}section .marqueeText{position:static}.home-video-overlay-enter-active,.home-video-overlay-leave-active{transition:opacity .25s ease}.home-video-overlay-enter-from,.home-video-overlay-leave-to{opacity:0}section .banner__hero{background:linear-gradient(90deg,#003c6a 100%,#0eaebc 0);height:100vh;-o-object-fit:cover;object-fit:cover;opacity:0;overflow:hidden;position:relative;width:100vw}section .banner__hero--wrapper{height:100%;width:100%}section .banner__hero .splitting,section .banner__hero [data-splitting]{opacity:0}section .banner__hero p{bottom:3vw;color:#fff;position:absolute;right:3vw;width:32vw;z-index:3}@media screen and (max-width:600px){section .banner__hero p{bottom:50px;width:45vw}}section .banner__hero p span.line{display:inline-block}section .banner__hero p span.speed{cursor:pointer;margin-left:5px;text-decoration:underline}section .banner__hero p span.speed span.line__inner{background-color:var(--grey);color:var(--black)}section .banner__hero p span.speed span.line__inner:hover{background-color:var(--blue);color:var(--grey)}.home-cloud-canvas{opacity:0;pointer-events:none}.canvas{z-index:1}.canvas,.canvas__cover{height:100vh;left:0;margin:0;padding:0;position:fixed;top:0;width:100vw}.canvas__cover{background-color:#725b5b;mix-blend-mode:difference;opacity:0;pointer-events:none}section .intro h2{margin-top:10vw;padding-top:5vw;text-align:center;width:100%}@media screen and (max-width:600px){section .intro h2{margin-top:30vw}}section .intro h4{text-align:center;width:100%}section.homeworksSection{padding-top:0}section .small_print{justify-content:flex-start;margin-top:3vw}@media screen and (max-width:600px){section .small_print{margin-top:50px}}section .homeworks{margin-bottom:10vw}section .homeworks__showcaseHold{overflow:visible}@media screen and (max-width:600px){section .homeworks__showcaseHold{margin-top:20px}}section .homeworks__showcase{cursor:pointer;height:40vw;margin-top:5vw;max-height:72vh;min-height:320px;overflow:hidden;position:relative;touch-action:pan-y;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:100vw}@media screen and (max-width:600px){section .homeworks__showcase{height:72vw;max-height:none;min-height:260px}}section .homeworks__showcase:after,section .homeworks__showcase:before{content:"";height:100%;opacity:.3;pointer-events:none;position:absolute;top:0;width:6vw;z-index:2}section .homeworks__showcase:before{background:linear-gradient(90deg,var(--background,var(--bgcolor)) 0,transparent 100%);left:0}section .homeworks__showcase:after{background:linear-gradient(270deg,var(--background,var(--bgcolor)) 0,transparent 100%);right:0}section .homeworks__showcaseScale{left:0;position:absolute;top:0;transform-origin:50vw 50%}section .homeworks__showcaseLoop,section .homeworks__showcaseScale{height:100%;width:-moz-max-content;width:max-content;will-change:transform}section .homeworks__showcaseLoop{align-items:stretch;display:flex;gap:2.5vw;position:relative}@media screen and (max-width:600px){section .homeworks__showcaseLoop{gap:16px}}section .homeworks__showcaseItem{border-radius:12px;flex:0 0 auto;height:100%;margin:0;overflow:hidden;pointer-events:none}section .homeworks__showcaseItem img{display:block;height:100%;max-width:none;-o-object-fit:contain;object-fit:contain;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:auto;-webkit-user-drag:none}@media screen and (max-width:600px){section .homeworks__showcaseItem{border-radius:8px}}.homeworks__skimCursor{align-items:center;background-color:var(--primarycolor);border:var(--borderFade);border-radius:999px;color:var(--background,var(--bgcolor));display:inline-flex;justify-content:center;left:0;line-height:1;opacity:0;padding:clamp(6px,1vw,30px);pointer-events:none;position:fixed;text-transform:uppercase;top:0;white-space:nowrap;will-change:transform,opacity;z-index:21}@media screen and (max-width:600px){.homeworks__skimCursor{display:none}}section .benefits{padding-bottom:1vw;position:relative}section .benefits h4{padding-bottom:5vw;width:100%}@media screen and (max-width:600px){section .benefits h4{margin-bottom:20vw}}section .benefits__items--item{background-color:var(--bgcolor);border-top:var(--border);position:relative}section .benefits__items--item .layout{position:relative}@media screen and (max-width:600px){section .benefits__items--item .layout__third{display:none;position:absolute;right:20px;width:auto}}section .benefits__items--item .layout__second{display:flex;justify-content:space-between}section .benefits__items--image{border-radius:var(--radius);height:auto;overflow:hidden;width:35%}@media screen and (max-width:600px){section .benefits__items--image{position:absolute;right:10px;top:20px;width:35%}}section .benefits__items--text{padding-bottom:8vw;width:56%}@media screen and (max-width:600px){section .benefits__items--text{line-height:1.1;padding-bottom:80px;width:60%}}section .benefits__items--text p.lead{font-size:260%;line-height:.8;padding-right:0}@media screen and (max-width:600px){section .benefits__items--text p.lead{font-size:150%;margin-bottom:20px}}section .benefits__items--text p:not(.lead){width:70%}@media screen and (max-width:600px){section .benefits__items--text p:not(.lead){margin-top:0;width:100%}}section.section__blue .benefits__items--item{background-color:var(--blue);border-top:var(--border)}section.section__red .benefits__items--item{background-color:var(--red);border-top:1px solid #000}.section__pricing{transition:background .35s ease;--color:hsla(0,0%,100%,.7);color:#ffffffb3}.section__pricing .overlay{z-index:10}.section__pricing .topOverlay{position:sticky;z-index:10}.section .pricing{min-height:60vw;padding-bottom:20vw;position:relative}.section .pricing>.layout{position:relative}.section .pricing__content{z-index:9}.section .pricing__box{margin-bottom:2vw;padding-bottom:2vw;position:relative}@media screen and (max-width:600px){.section .pricing__box{--corner-size:28px;margin-bottom:40px;margin-top:20px;padding:40px 0}}.section .pricing__box .button{background-color:var(--grey)!important;color:var(--background)!important}.section .pricing__box .button:before{background:#fff}.section .pricing__box .button{background-color:#000;border-bottom-color:#000;margin-top:4vw;padding-left:1vw;padding-right:1vw}@media screen and (max-width:600px){.section .pricing__box .button{margin-top:80px;padding-left:10px;padding-right:10px}}.section .pricing__box--header{align-items:stretch;border-bottom:var(--border);border-top:var(--border);display:grid;grid-template-columns:1fr auto;margin-bottom:1vw}@media screen and (max-width:600px){.section .pricing__box--header{margin-bottom:20px}}.section .pricing__box--name,.section .pricing__box--price{align-items:center;display:flex;padding:1vw 0}@media screen and (max-width:600px){.section .pricing__box--name,.section .pricing__box--price{padding:14px 0}}.section .pricing__box--name{gap:.6vw}.section .pricing__box--badge{align-items:center;border:var(--border);border-radius:999px;display:inline-flex;font-family:JetBrainsMono,monospace;font-size:.75vw;letter-spacing:.02em;line-height:1;padding:.2vw .55vw;text-transform:uppercase}@media screen and (max-width:600px){.section .pricing__box--badge{font-size:10px;padding:4px 8px}}.section .pricing__box--price{border-left:var(--border);justify-content:flex-end;margin-left:1vw;padding-left:2vw;text-align:right;white-space:nowrap}.section .pricing__box--price s{opacity:.55}@media screen and (max-width:600px){.section .pricing__box--price{margin-left:14px;padding-left:14px}}.section .pricing__box p.lead{margin-bottom:0}@media screen and (max-width:600px){.section .pricing__box p.lead{font-size:120%}}.section .pricing__box p:not(.lead){letter-spacing:-.05vw;margin-bottom:3vw;max-width:30vw}@media screen and (max-width:600px){.section .pricing__box p:not(.lead){margin-bottom:30px;max-width:100%}}.section .pricing__box--items li{border-bottom:var(--border);list-style:none;padding:.5vw 0}.section .pricing__box--items li:last-child{border:none}@media screen and (max-width:600px){.section .pricing__box--items li{font-size:100%;padding:5px 0}}.section .pricing__box--items li:first-child{border-top:1px solid rgba(var(--color),.5)}.section .pricing__box.spotlight{--background:0,0,0;--color:255,255,255}.section .pricing p.longtext{padding:4vw 15vw;text-align:center;width:100vw}@media screen and (max-width:600px){.section .pricing p.longtext{padding:10vw 5vw 20vh}}.section .pricing .buttons{padding-bottom:3vw}@media screen and (max-width:600px){.section .pricing .buttons{padding-bottom:50px}}.section .pricing__package{background:transparent;height:100vh;left:0;opacity:0;pointer-events:none;position:fixed;top:0;width:100vw;z-index:9}.section .pricing__package canvas{background:transparent!important;display:block;height:100%!important;width:100%!important}@media screen and (max-width:600px){.section .pricing__package{display:none}.section .pricing{min-height:90vw}}section .branding__imageFrame{aspect-ratio:4/5;background-color:#000;border-radius:var(--radius);bottom:3vw;clip-path:inset(100% 0 0 0 round var(--radius));-webkit-clip-path:inset(100% 0 0 0 round var(--radius));left:3vw;overflow:hidden;pointer-events:none;position:fixed;width:20vw;will-change:clip-path;z-index:12}@media screen and (max-width:600px){section .branding__imageFrame{display:none}}section .branding__imageStack{height:100%;position:relative;width:100%}section .branding__imageStack:after{animation:foreground .5s steps(1) infinite;background-image:url(../img/noise.png);background-position:50%;content:"";height:calc(100% + 20rem);left:-10rem;mix-blend-mode:overlay;opacity:1;pointer-events:none;position:fixed;top:-10rem;width:calc(100% + 20rem);z-index:100}@media screen and (max-width:600px){section .branding__imageStack:after{display:none}}section .branding__image{background:var(--bgcolor);height:100%;inset:0;overflow:hidden;position:absolute;width:100%}section .branding__image img{display:block;height:100%;-o-object-fit:cover;object-fit:cover;width:100%}section .branding h4{padding-bottom:8vw}@media screen and (max-width:600px){section .branding h4{padding-bottom:50px}}section .branding p.lead.short{padding-right:10vw;position:sticky;top:8vw}section .branding .button{background-color:var(--black);border-bottom-color:var(--black);color:var(--grey);margin-top:5vw;padding-left:1vw;padding-right:1vw}section .branding .button:before{background-color:var(--lightgrey)}section .branding .button:hover{color:#000!important}@media screen and (max-width:600px){section .branding .button{margin-top:50px;padding-left:10px;padding-right:10px}}section .branding .pricing__box--items{display:flex;flex-wrap:wrap}section .branding .pricing__box--items li{width:50%}@media screen and (max-width:600px){section .branding .pricing__box--items li{width:100%}}.footer{min-height:calc(100vh - 5.1vw);overflow:hidden;position:relative;width:100vw}.footer__wrapper{height:100%;position:relative}.footer__logoStack{--trail-progress:0;color:var(--grey);isolation:isolate;opacity:.7;padding:3vw;position:relative}.footer__logo{display:block;height:auto;width:100%}.footer__logo path{fill:currentColor}.footer__logo--front{position:relative;z-index:5}.footer__logo--trail{background-color:var(--background,var(--bgcolor));clip-path:inset(0 0 calc(var(--trail-crop) + var(--trail-crop-offset, 0%)) 0);color:var(--grey);left:3vw;position:absolute;top:3vw;transform:translateY(calc(var(--trail-progress)*var(--trail-index)*-22%));width:calc(100% - 6vw);will-change:transform}
/* === entry.CQSbLAcy.css === */.wrapper{height:100%}.wrapper:after{animation:foreground .5s steps(1) infinite;background-image:url(../img/noise.png);background-position:50%;content:"";height:calc(100% + 20rem);left:-10rem;mix-blend-mode:overlay;opacity:.3;pointer-events:none;position:fixed;top:-10rem;width:calc(100% + 20rem);z-index:100}@media screen and (max-width:600px){.wrapper:after{display:none}}@keyframes foreground{0%{transform:translate3d(0,9rem,0)}10%{transform:translate3d(-1rem,-4rem,0)}20%{transform:translate3d(-8rem,2rem,0)}30%{transform:translate3d(9rem,-9rem,0)}40%{transform:translate3d(-2rem,7rem,0)}50%{transform:translate3d(-9rem,-4rem,0)}60%{transform:translate3d(2rem,6rem,0)}70%{transform:translate3d(7rem,-8rem,0)}80%{transform:translate3d(-9rem,1rem,0)}90%{transform:translate3d(6rem,-5rem,0)}to{transform:translate3d(-7rem,0,0)}}.gloom{overflow:hidden;z-index:23}.gloom,.gloom:before{height:100vh;left:0;pointer-events:none;position:fixed;top:0;width:100vw}.gloom:before{-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);content:"";opacity:.15}@media screen and (max-width:600px){.gloom:before{-webkit-backdrop-filter:blur(5px);backdrop-filter:blur(5px);opacity:.2}}.vignette{height:100dvh;overflow:hidden;width:100vw;z-index:100}.vignette,.vignette:before{left:0;pointer-events:none;position:fixed;top:0}.vignette:before{background-image:url(../img/crt.png);background-repeat:no-repeat;background-size:100% 100%;content:"";height:100%;opacity:.7;transform:scale(1.02);width:100%}.static__wrapper{padding-top:0}.errorScreen,.static__wrapper--inner{min-height:100vh}.errorScreen{align-items:center;display:flex;padding:0}.errorScreen__inner{display:flex;flex-direction:column;justify-content:center;padding:0 6vw;width:100%}.errorScreen__label{align-self:center;background:var(--grey);color:var(--blue);margin-bottom:2vw;padding:0 .6em}.errorScreen__copy{margin:0 auto;max-width:72ch}.errorScreen__copy p{margin:0 0 2vw}.errorScreen__continue{background:transparent;border:0;color:inherit;cursor:pointer;display:block;font:inherit;margin-top:.3em;padding:0;text-align:center;text-decoration:none;width:100%}@media screen and (max-width:600px){.errorScreen__inner{font-size:13px;padding:0 24px}.errorScreen__label{margin-bottom:28px}.errorScreen__copy{max-width:100%}}
/* === default.Z9wDiTTt.css === */header{position:fixed;top:0;z-index:21}header:after{content:"";height:1px;left:3vw;position:absolute;right:3vw;top:5vw}@media screen and (max-width:600px){header:after{border-bottom:none}}header .nav{align-items:flex-start;font-family:InterTight,sans-serif;justify-content:flex-end}header .nav a{display:block;padding:.3vw .7vw}header .menu{background:transparent;border:0;color:inherit;cursor:pointer;display:block;font:inherit;padding:1.66vw 3vw;position:fixed;right:0;top:0;z-index:4}@media screen and (max-width:600px){header .menu{margin-top:30px;right:20px}}header .menu{display:none}@media screen and (max-width:600px){header .menu{display:block}}header .nav{display:flex}@media screen and (max-width:600px){header .nav{display:none}header .logo{padding:6px 20px}}header .logo svg{height:auto;margin-top:.3vw;width:10vw}@media screen and (max-width:1300px){header .logo svg{margin-top:6px;width:115px}}.nav__overlay{background:linear-gradient(180deg,#393939e6 3%,#39393900);display:none;height:60vh;opacity:1;z-index:3}.mobilenav,.nav__overlay{left:0;pointer-events:none;position:fixed;top:0;width:100vw}.mobilenav{background-color:var(--blue);clip-path:rect(0 100% 0 0);color:var(--grey);height:85svh;padding:20svh 0 0 10px;z-index:20}.mobilenav__backdrop{background-color:#000c;height:100lvh;left:0;opacity:0;pointer-events:none;position:fixed;top:0;transition:opacity .2s linear;width:100vw;z-index:3}.mobilenav__main a{display:block;font-family:Archivo,sans-serif;font-size:42px;line-height:1;padding:5px 10px}.mobilenav__main a .line__inner{padding-bottom:1px;position:relative;top:1px}.mobilenav__social{bottom:5vh;position:absolute}.mobilenav__social a{display:block;padding-left:10px}body.menu_open{overflow:hidden}body.menu_open .mobilenav{pointer-events:all}body.menu_open .mobilenav__backdrop{opacity:1}
/* === MarqueeText.DeyW-Ysn.css === */.marqueeText{--marquee-line-scale:0;height:17vw;left:0;overflow:hidden;pointer-events:none;position:fixed;top:3.5vw;white-space:nowrap;width:100%;z-index:3}@media screen and (max-width:600px){.marqueeText{height:100px;top:80px}}.marqueeText:after,.marqueeText:before{border-bottom:var(--border);border-width:2px;content:"";height:1px;left:3vw;position:absolute;transform:scaleX(var(--marquee-line-scale));transform-origin:left top;width:94vw}.marqueeText:before{top:1.4vw}@media screen and (max-width:600px){.marqueeText:before{top:2px}}.marqueeText:after{bottom:4vw}.marqueeText__track{display:flex;left:0;position:absolute;top:0;white-space:nowrap;width:-moz-max-content;width:max-content;will-change:transform}.marqueeText__title{display:inline-flex;flex:0 0 auto;line-height:.96;margin-bottom:2vw;white-space:nowrap}@media screen and (max-width:600px){.marqueeText__title{margin-bottom:5vh}}.marqueeText .line{display:inline-block}.marqueeText__symbol{font-family:inherit;padding:0 2vw}section .marqueeText{position:static}
/* === Footer.MRJrKAf5.css === */.footer{min-height:calc(100vh - 5.1vw);overflow:hidden;position:relative;width:100vw}.footer__wrapper{height:100%;position:relative}.footer__logoStack{--trail-progress:0;color:var(--grey);isolation:isolate;opacity:.7;padding:3vw;position:relative}.footer__logo{display:block;height:auto;width:100%}.footer__logo path{fill:currentColor}.footer__logo--front{position:relative;z-index:5}.footer__logo--trail{background-color:var(--background,var(--bgcolor));clip-path:inset(0 0 calc(var(--trail-crop) + var(--trail-crop-offset, 0%)) 0);color:var(--grey);left:3vw;position:absolute;top:3vw;transform:translateY(calc(var(--trail-progress)*var(--trail-index)*-22%));width:calc(100% - 6vw);will-change:transform}
/* === index.CEnG83Iu.css === */.home-video-overlay-enter-active,.home-video-overlay-leave-active{transition:opacity .25s ease}.home-video-overlay-enter-from,.home-video-overlay-leave-to{opacity:0}.home-cloud-canvas{opacity:0;pointer-events:none}.canvas{z-index:1}.canvas,.canvas__cover{height:100vh;left:0;margin:0;padding:0;position:fixed;top:0;width:100vw}.canvas__cover{background-color:#725b5b;mix-blend-mode:difference;opacity:0;pointer-events:none}section .banner__hero{background:linear-gradient(90deg,#003c6a 100%,#0eaebc 0);height:100vh;-o-object-fit:cover;object-fit:cover;opacity:0;overflow:hidden;position:relative;width:100vw}section .banner__hero--wrapper{height:100%;width:100%}section .banner__hero .splitting,section .banner__hero [data-splitting]{opacity:0}section .banner__hero p{bottom:3vw;color:#fff;position:absolute;right:3vw;width:32vw;z-index:3}@media screen and (max-width:600px){section .banner__hero p{bottom:50px;width:45vw}}section .banner__hero p span.line{display:inline-block}section .banner__hero p span.speed{cursor:pointer;margin-left:5px;text-decoration:underline}section .banner__hero p span.speed span.line__inner{background-color:var(--grey);color:var(--black)}section .banner__hero p span.speed span.line__inner:hover{background-color:var(--blue);color:var(--grey)}section .intro h2{margin-top:10vw;padding-top:5vw;text-align:center;width:100%}@media screen and (max-width:600px){section .intro h2{margin-top:30vw}}section .intro h4{text-align:center;width:100%}section.homeworksSection{padding-top:0}section .small_print{justify-content:flex-start;margin-top:3vw}@media screen and (max-width:600px){section .small_print{margin-top:50px}}section .homeworks{margin-bottom:10vw}section .homeworks__showcaseHold{overflow:visible}@media screen and (max-width:600px){section .homeworks__showcaseHold{margin-top:20px}}section .homeworks__showcase{cursor:pointer;height:40vw;margin-top:5vw;max-height:72vh;min-height:320px;overflow:hidden;position:relative;touch-action:pan-y;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:100vw}@media screen and (max-width:600px){section .homeworks__showcase{height:72vw;max-height:none;min-height:260px}}section .homeworks__showcase:after,section .homeworks__showcase:before{content:"";height:100%;opacity:.3;pointer-events:none;position:absolute;top:0;width:6vw;z-index:2}section .homeworks__showcase:before{background:linear-gradient(90deg,var(--background,var(--bgcolor)) 0,transparent 100%);left:0}section .homeworks__showcase:after{background:linear-gradient(270deg,var(--background,var(--bgcolor)) 0,transparent 100%);right:0}section .homeworks__showcaseScale{left:0;position:absolute;top:0;transform-origin:50vw 50%}section .homeworks__showcaseLoop,section .homeworks__showcaseScale{height:100%;width:-moz-max-content;width:max-content;will-change:transform}section .homeworks__showcaseLoop{align-items:stretch;display:flex;gap:2.5vw;position:relative}@media screen and (max-width:600px){section .homeworks__showcaseLoop{gap:16px}}section .homeworks__showcaseItem{border-radius:12px;flex:0 0 auto;height:100%;margin:0;overflow:hidden;pointer-events:none}section .homeworks__showcaseItem img{display:block;height:100%;max-width:none;-o-object-fit:contain;object-fit:contain;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:auto;-webkit-user-drag:none}@media screen and (max-width:600px){section .homeworks__showcaseItem{border-radius:8px}}.homeworks__skimCursor{align-items:center;background-color:var(--primarycolor);border:var(--borderFade);border-radius:999px;color:var(--background,var(--bgcolor));display:inline-flex;justify-content:center;left:0;line-height:1;opacity:0;padding:clamp(6px,1vw,30px);pointer-events:none;position:fixed;text-transform:uppercase;top:0;white-space:nowrap;will-change:transform,opacity;z-index:21}@media screen and (max-width:600px){.homeworks__skimCursor{display:none}}.section__pricing{transition:background .35s ease;--color:hsla(0,0%,100%,.7);color:#ffffffb3}.section__pricing .overlay{z-index:10}.section__pricing .topOverlay{position:sticky;z-index:10}.section .pricing{min-height:60vw;padding-bottom:20vw;position:relative}.section .pricing>.layout{position:relative}.section .pricing__content{z-index:9}.section .pricing__box{margin-bottom:2vw;padding-bottom:2vw;position:relative}@media screen and (max-width:600px){.section .pricing__box{--corner-size:28px;margin-bottom:40px;margin-top:20px;padding:40px 0}}.section .pricing__box .button{background-color:var(--grey)!important;color:var(--background)!important}.section .pricing__box .button:before{background:#fff}.section .pricing__box .button{background-color:#000;border-bottom-color:#000;margin-top:4vw;padding-left:1vw;padding-right:1vw}@media screen and (max-width:600px){.section .pricing__box .button{margin-top:80px;padding-left:10px;padding-right:10px}}.section .pricing__box--header{align-items:stretch;border-bottom:var(--border);border-top:var(--border);display:grid;grid-template-columns:1fr auto;margin-bottom:1vw}@media screen and (max-width:600px){.section .pricing__box--header{margin-bottom:20px}}.section .pricing__box--name,.section .pricing__box--price{align-items:center;display:flex;padding:1vw 0}@media screen and (max-width:600px){.section .pricing__box--name,.section .pricing__box--price{padding:14px 0}}.section .pricing__box--name{gap:.6vw}.section .pricing__box--badge{align-items:center;border:var(--border);border-radius:999px;display:inline-flex;font-family:JetBrainsMono,monospace;font-size:.75vw;letter-spacing:.02em;line-height:1;padding:.2vw .55vw;text-transform:uppercase}@media screen and (max-width:600px){.section .pricing__box--badge{font-size:10px;padding:4px 8px}}.section .pricing__box--price{border-left:var(--border);justify-content:flex-end;margin-left:1vw;padding-left:2vw;text-align:right;white-space:nowrap}.section .pricing__box--price s{opacity:.55}@media screen and (max-width:600px){.section .pricing__box--price{margin-left:14px;padding-left:14px}}.section .pricing__box p.lead{margin-bottom:0}@media screen and (max-width:600px){.section .pricing__box p.lead{font-size:120%}}.section .pricing__box p:not(.lead){letter-spacing:-.05vw;margin-bottom:3vw;max-width:30vw}@media screen and (max-width:600px){.section .pricing__box p:not(.lead){margin-bottom:30px;max-width:100%}}.section .pricing__box--items li{border-bottom:var(--border);list-style:none;padding:.5vw 0}.section .pricing__box--items li:last-child{border:none}@media screen and (max-width:600px){.section .pricing__box--items li{font-size:100%;padding:5px 0}}.section .pricing__box--items li:first-child{border-top:1px solid rgba(var(--color),.5)}.section .pricing__box.spotlight{--background:0,0,0;--color:255,255,255}.section .pricing p.longtext{padding:4vw 15vw;text-align:center;width:100vw}@media screen and (max-width:600px){.section .pricing p.longtext{padding:10vw 5vw 20vh}}.section .pricing .buttons{padding-bottom:3vw}@media screen and (max-width:600px){.section .pricing .buttons{padding-bottom:50px}}.section .pricing__package{background:transparent;height:100vh;left:0;opacity:0;pointer-events:none;position:fixed;top:0;width:100vw;z-index:9}.section .pricing__package canvas{background:transparent!important;display:block;height:100%!important;width:100%!important}@media screen and (max-width:600px){.section .pricing__package{display:none}.section .pricing{min-height:90vw}}section .branding__imageFrame{aspect-ratio:4/5;background-color:#000;border-radius:var(--radius);bottom:3vw;clip-path:inset(100% 0 0 0 round var(--radius));-webkit-clip-path:inset(100% 0 0 0 round var(--radius));left:3vw;overflow:hidden;pointer-events:none;position:fixed;width:20vw;will-change:clip-path;z-index:12}@media screen and (max-width:600px){section .branding__imageFrame{display:none}}section .branding__imageStack{height:100%;position:relative;width:100%}section .branding__imageStack:after{animation:foreground .5s steps(1) infinite;background-image:url(../img/noise.png);background-position:50%;content:"";height:calc(100% + 20rem);left:-10rem;mix-blend-mode:overlay;opacity:1;pointer-events:none;position:fixed;top:-10rem;width:calc(100% + 20rem);z-index:100}@media screen and (max-width:600px){section .branding__imageStack:after{display:none}}section .branding__image{background:var(--bgcolor);height:100%;inset:0;overflow:hidden;position:absolute;width:100%}section .branding__image img{display:block;height:100%;-o-object-fit:cover;object-fit:cover;width:100%}section .branding h4{padding-bottom:8vw}@media screen and (max-width:600px){section .branding h4{padding-bottom:50px}}section .branding p.lead.short{padding-right:10vw;position:sticky;top:8vw}section .branding .button{background-color:var(--black);border-bottom-color:var(--black);color:var(--grey);margin-top:5vw;padding-left:1vw;padding-right:1vw}section .branding .button:before{background-color:var(--lightgrey)}section .branding .button:hover{color:#000!important}@media screen and (max-width:600px){section .branding .button{margin-top:50px;padding-left:10px;padding-right:10px}}section .branding .pricing__box--items{display:flex;flex-wrap:wrap}section .branding .pricing__box--items li{width:50%}@media screen and (max-width:600px){section .branding .pricing__box--items li{width:100%}}.home{--primarycolor:#D9DCDF}.home__wrapper{z-index:2}.homeHeroIntro,.home__wrapper{position:relative}
/* === Logo3D.CaV_7exR.css === */.logo3d{pointer-events:none;position:absolute;z-index:3}.logo3d--hero{bottom:auto;height:32vh;left:50vw;top:55vh;transform:translate(-50%,-50%);width:70vw}@media screen and (max-width:600px){.logo3d--hero{height:32vh;top:45vh;width:70vw}}.logo3d__canvas{height:100%;width:100%}.logo3d__canvas canvas{display:block;height:100%!important;width:100%!important}
/* === glasshouse: static-page additions (Vue handled these dynamically) === */

/* <=360px: the 1fr/auto package header cannot hold "Standard.PKG" + the nowrap "$4,000 $3,500/mo" price (2px horizontal overflow at 320px); let the price wrap onto two lines there */@media screen and (max-width:360px){.section .pricing__box--price{flex-wrap:wrap;white-space:normal}}

.banner__hero .banner__sky{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:0;pointer-events:none}.banner__hero.gl-fallback .home-cloud-canvas{display:none}

/* === INVENTORY COPY ADDITIONS === */.section .serviceTags{display:flex;flex-wrap:wrap;gap:0 1.4em;list-style:none;margin:.6em 0 0;padding:0}.section .serviceTags li{position:relative}.section .serviceTags li+li:before{content:"\00B7";position:absolute;left:-.85em;opacity:.5}.banner__hero .heroCopy{position:absolute;right:3vw;bottom:50px;width:45vw;z-index:3}.banner__hero .heroCopy p{position:static;width:100%;bottom:auto;right:auto}.banner__hero .heroButtons{margin-top:1.2em;display:flex;flex-wrap:wrap;gap:.6em}.section h2.lead.contact__number{margin:0 0 .4em}.section h2.lead.contact__number a{color:inherit;text-decoration:none}.footer .footer__copyright{margin-top:1.4em}.section .sectionEyebrow{font-size:16px;line-height:1.35}.section .homeworks .additionalServices__title{font-family:Archivo,sans-serif;font-size:2.8vw;line-height:1;margin:0}.section .homeworks .small_print p.lead.last{margin-bottom:1vw}@media screen and (max-width:600px){.section .homeworks .additionalServices__title{font-size:30px}.section .homeworks .small_print p.lead.last{margin-bottom:10px}
}.section .homeworks .additionalServices .layout__third:before{display:none}.logo3d--hero{transition:opacity .3s ease}

/* === PALETTE ADDITIONS === */:root{color-scheme:dark;scrollbar-color:var(--lightgrey) var(--bgcolor)}::selection{background:var(--green);color:var(--black)}::-moz-selection{background:var(--green);color:var(--black)}a:focus-visible,button:focus-visible{outline:2px solid var(--green);outline-offset:3px}
/* Top scrim: keeps the light nav text legible over the mid-grey Services section
   (was 1.76:1). It lives on body, not header, and sits at z-index 11 - above all
   section content (<=10) but BELOW the 3D mark (12 undocked / 20 docked) and below
   the header (21). So the mark renders in front of the gradient instead of being
   faded by it, in both its states, and the nav still reads on top of everything. */body:before{content:"";position:fixed;top:0;left:0;right:0;height:150px;pointer-events:none;z-index:11;background:linear-gradient(180deg,rgba(26,26,26,.92) 0%,rgba(26,26,26,.75) 35%,rgba(26,26,26,.35) 70%,rgba(26,26,26,0) 100%);background:linear-gradient(180deg,color-mix(in srgb,var(--bgcolor) 92%,transparent) 0%,color-mix(in srgb,var(--bgcolor) 75%,transparent) 35%,color-mix(in srgb,var(--bgcolor) 35%,transparent) 70%,color-mix(in srgb,var(--bgcolor) 0%,transparent) 100%)}

/* === SERVICE ROW BULLETS === */
/* Nothing left to do. The dot used to sit in the far-left .layout__third column, far
   from the row title, and was suppressed there via .nobullet and re-drawn hanging
   beside the title. The re-drawn dot is gone -- .nobullet still suppresses the original
   -- and all that survived here was the position:relative it was positioned against,
   which on its own changed nothing. See ADDITIONAL SERVICES GRID for the rows now. */


/* === LIQUID SECTION TRANSITION === */
/* Layers are stacked, not tiled: each fills the overlay and is separated in depth.
   No goo filter — the softness comes from per-layer blur, exactly like the footer
   wordmark's trail. */.overlay{overflow:hidden;display:block}.overlay div{position:absolute;inset:0;width:100%;height:100%;transform-origin:50% 100%;will-change:transform,opacity,filter}

/* === LIQUID FOOTER WORDMARK === */
/* Was: three hard-clipped copies fanning UPWARD (clip-path inset + translateY -22%),
   which read as window-shade slats. Now each copy hangs BELOW the wordmark,
   stretching and blurring with depth so the letters appear to melt downward. */.footer .footer__logo--trail{
  background-color:transparent;
  clip-path:none;
  transform-origin:50% 0%;
  transform:translateY(calc(var(--trail-progress) * var(--trail-index) * 7%))
            scaleY(calc(1 + var(--trail-progress) * var(--trail-index) * 0.22));
  opacity:calc((0.5 - var(--trail-index) * 0.11) * var(--trail-progress));
  filter:blur(calc(var(--trail-progress) * var(--trail-index) * 2.2px));
  will-change:transform,opacity,filter;
}

/* === FOOTER LAYOUT === */
/* .footer sets min-height, so the wrapper’s height:100% could not resolve and it
   collapsed to its content, leaving ~530px of dead space underneath. Make the
   section a flex column so the wrapper genuinely fills it and the contact row
   sits on the bottom edge. */.section.footer{display:flex}.footer .footer__wrapper{flex:1;display:flex;flex-direction:column;justify-content:space-between;height:auto}.footer .footer__wrapper > .layout.no__pt{margin-top:auto;padding-bottom:3vw}
/* Fan further down now that there is room for it to travel. */.footer .footer__logo--trail{
  transform:translateY(calc(var(--trail-progress) * var(--trail-index) * 17%))
            scaleY(calc(1 + var(--trail-progress) * var(--trail-index) * 0.60));
  opacity:calc((0.46 - var(--trail-index) * 0.055) * var(--trail-progress));
  filter:blur(calc(var(--trail-progress) * var(--trail-index) * 2px));
}

/* === HEADER WORDMARK SIZE === */
/* Up from 10vw / 115px. The docked GH mark measures this svg live (see
   headerLogoRight in logo3d.js) and keeps its own clearance, so it re-docks itself
   rather than needing a matching constant here. margin-top comes down to offset the
   extra height, so the wordmark stays optically centred in the header row. */header .logo svg{width:13vw;margin-top:.1vw}@media screen and (max-width:1300px){header .logo svg{width:150px;margin-top:3px}}

/* === HEADER EYEBROW BREAKPOINT === */
/* The nav links are a fixed 20px while the grid column holding them scales with the
   viewport, so the row runs out of width and wraps onto a second line. Measured:
   790px leaves 8px of slack, 780px leaves 3px, and at 770px it wraps. Switch to the
   mobile eyebrow -- wordmark plus Menu button -- well clear of that.

   Only the nav/menu swap moves up here. The mobile SPACING (the Menu button's 30px
   top margin, the logo's 20px side padding) stays at its own 600px breakpoint, where
   the header is genuinely phone-sized; at 800px the desktop spacing already lines the
   Menu button up with the wordmark. The docked GH mark needs no change either -- it
   measures the visible header controls live, so the Menu button simply becomes the
   obstacle the nav used to be. */@media screen and (max-width:860px){header .nav{display:none}header .menu{display:block}
}

/* === FOOTER WORDMARK CLEARANCE (MOBILE) === */
/* At the bottom of the page the footer fills the viewport, which puts the wordmark at
   y 47-95 on a 375x812 phone — entirely behind the fixed header, which runs 0-96.
   Push the stack down so it clears the eyebrow.

   margin, not padding: the trail copies are position:absolute at top:3vw inside the
   stack, so padding would move the front wordmark down and leave the whole fan behind
   it. Margin moves the stack and its absolutely-positioned children together.

   Safe to add because .footer__wrapper is a flex column with space-between and the
   contact row pinned by margin-top:auto, so this moves the wordmark only — the
   address and the contact buttons stay on the bottom edge where they are. */@media screen and (max-width:600px){.footer .footer__logoStack{margin-top:80px}
}

/* === FOOTER CONTACT ROW ALIGNMENT === */
/* The "Based in Canada" column is gone. .layout is flex with justify-content:
   space-between, which only held the contact block against the right edge because
   there were two children; with one child left, space-between places it at the
   start instead. Pin it explicitly. No effect on mobile, where .layout__second is
   already width:100%. */.footer .layout.no__pt > .layout__second{margin-left:auto}

/* === TYPOGRAPHY === */
/* Archivo replaces SemiSqueezed Medium, so the display sizes need a real weight:
   the originals all sat at 400, which in a variable grotesque reads far lighter than
   the Medium they were drawn against. This has to live at the END of the file --
   `h1,h2,h3,h4{font-weight:400}` is re-asserted by later, equally specific rules
   such as `h3{font-size:5vw;font-weight:400}`, which would otherwise win.
   Tracking is deliberately not set here: h2 and h3 already carry tuned vw values. */
h1,h2,h3,h4,h5,.mobilenav__main a,.section .homeworks .additionalServices__title{font-weight:600}
p.lead{font-weight:500}

/* Inter Tight sets about 15% wider than SemiSqueezed at the same size, which pushed
   the nav's single-line width from 484px to 556px and moved its wrap point from
   ~775px up to ~895px — above the 860px eyebrow breakpoint, so between 861 and 895
   the desktop nav reappeared and immediately wrapped onto two lines.

   Correcting it on the nav rather than by raising the breakpoint: shrinking the
   eyebrow to 0.9em and tightening the link padding restores roughly the original
   measure, and keeps the desktop nav usable down to 860px instead of retreating to
   the Menu button on every 13-inch laptop. Inter Tight's larger x-height means
   0.9em still reads at about the size SemiSqueezed did at 1em.
   The nav size cannot be set globally: the 20px it inherits comes from
   body{font-size:20px}, which drives the body copy too. */
header .nav{font-size:.9em}
header .nav a{padding:.3vw .55vw}


/* === FOOTER CALL-TO-ACTION === */
/* The Free Consultation button is gone, and so is the header that replaced it; the
   footer contact is now a single mailto: link. .buttons is flex with justify-content:space-between and .button__half
   is 48% wide, so the lone survivor would sit stranded in the left half of the
   row — :only-child gives it the full width without needing a marker class.
   The hero is in the same position now: its "Contact" header and its two links are one
   "Request a quote" button, so :only-child sizes that as well.

   .buttons__label went with them. It styled the header over each of those two groups,
   and there is no third one. */
.buttons .button__half:only-child{width:100%}


/* === LONG LINK TEXT === */
/* hello@glasshousedesignlab.com is one unbreakable token — 238px at 14px mono —
   inside a flex button that is usually narrower. Worst case is 700px wide, where
   .button__half is 48% of a 45vw hero column: a 151px button holding 233px of
   text. Flex items default to min-width:auto, so the span refuses to shrink below
   its content and spills past the button-s underline rather than wrapping.
   min-width:0 lets it shrink to the space available; overflow-wrap:anywhere gives
   the address a break opportunity so it wraps instead of overflowing. The arrows these buttons
   used to carry have been removed site-wide, so the :not(.arrow) below now excludes
   nothing. It is left in place deliberately: it contributes a class to the selector, and
   dropping it would lower the specificity of a rule that is still doing work. */
.button__half > span:not(.arrow),.button__big > span:not(.arrow){min-width:0;overflow-wrap:anywhere}


/* === MOBILE HERO COPY === */
/* The hero copy inherits `width:45vw` from the desktop layout, which on a 375px
   phone is 169px -- narrow enough that every line ran ragged and the email address
   broke mid-word across two lines. Widening it is what gives the hierarchy below
   room to exist, so it comes first.

   The block now runs between the page's own 20px gutters, about 335px on a 375px
   phone. It used to start clear of the vertical marquee rail that ran up the left
   side of the hero; that rail is gone, so the left edge is just the gutter.

   With the room, two tiers rather than one size doing all the work:
     - the description recedes to a 10px caption, opened up with line-height and
       tracking so small uppercase mono stays readable rather than going dimmer,
       which it cannot afford over the pale clouds it sits on;
     - the call to action sits under it at 14px with taller padding for a real tap
       target, and carries the block on its own.

   That 14px was min(14px,calc(4.7vw - 3px)) while the row held
   hello@glasshousedesignlab.com -- one 29-character unbreakable token at 17.0em of the
   row's own font size, which needed the clamp below about 362px. "Request a quote" is
   fifteen characters, roughly 9em, and clears the 280px column of a 320px phone with
   more than half of it to spare. The clamp had stopped protecting anything and was
   only shrinking the label on small phones -- 12.0px at 320px for a line that fits at
   14 -- so it is a flat 14px now. */
@media screen and (max-width:600px){
  .banner__hero .heroCopy{left:20px;right:20px;width:auto}
  .banner__hero .heroCopy>p.monospace{font-size:10px;line-height:1.55;letter-spacing:.05em}
  .banner__hero .heroButtons{margin-top:26px;gap:0}
  .heroButtons .button__half{padding:10px 0;font-size:14px}
}

/* === HERO LINK COLUMN === */
/* This column held a "Contact" header and two links -- a phone number and the email
   address -- and most of this block was about the second one. Between 600px and ~1120px
   the address broke across two or three lines, because the pair sat side by side at 48%
   of a 45vw column; a flex-basis of 253px let flex-wrap decide when to stack, rather than
   a breakpoint deciding it. A border-top repair went with that: the rules were written as
   :first-child and :nth-child(2) back when .buttons held exactly two links, and the header
   had shifted both of them along by one.

   All three elements are one "Request a quote" link now, and both problems left with them.
   A single item cannot wrap against a sibling, and there is no child left to count. What
   the row still needs is the width of the column and the rule above it, which closes the
   frame with .button__half's own border-bottom. Stated once rather than per breakpoint:
   with one link the stacked case and the side-by-side case are the same case.

   The bundle's own .button__half:first-child would in fact draw that top rule now, since
   the link is the only child of .buttons. It is stated here anyway so the row does not
   depend on being first -- that assumption is exactly what broke when the header arrived.

   flex-basis rather than width, because .button__half carries width:48% and a definite
   basis wins the main size of a flex item -- setting the width alone would not widen it. */
.heroButtons .button__half{border-top:1px solid var(--color);flex-basis:100%}

/* === HERO COPY LINE WRAP === */
/* rebuildSplitLines() locks each computed line into its own <span class="line"> and
   never runs again, so after a viewport change those spans still hold the wrapping of
   the width they were measured at. Widening is the damaging direction: the spans are
   `section .banner__hero p span.line{display:inline-block}` with NO whitespace text
   node between them, so once the column is wide enough two of them flow onto the same
   row. They butt together -- "...OTHER BRANDELEMENTS." -- and because overflow:hidden
   moves an inline-block's baseline to its bottom margin edge, two spans of unequal
   height sit at different offsets, which reads as one line overlapping another.
   Measured at 700px after loading at 340px: 3 lines on 2 rows, overlapping by 13px.

   Making them blocks means a locked line always owns its row, so neither the
   run-together nor the overlap can happen at any width. Stale breaks then degrade to
   nothing worse than a ragged right edge, and keepHeroCopyReflowing() in app.js clears
   even that once the resize settles -- this rule is what holds the line during the
   drag, before that debounce fires.

   The split target is a <span> and therefore inline; it is made a block too so the
   line blocks are not nested inside an inline box. */
.banner__hero .heroCopy p .splitting{display:block}
.banner__hero .heroCopy p span.line{display:block}

/* === HERO MARK CLEARANCE === */
/* The mark's box is positioned by viewport fraction while the hero copy is anchored to
   the bottom of the hero, so on short viewports the two converge and the mark prints
   over the text. constrainHeroMark() in logo3d.js measures the copy and writes these
   two properties; the fallbacks are the original values, so with no JS the mark sits
   exactly where it always did. setupSticky() re-measures from CSS on resize, so it
   picks the corrected position up on its own. */
.logo3d--hero{top:var(--hero-mark-top,55vh);height:var(--hero-mark-height,32vh)}
@media screen and (max-width:600px){.logo3d--hero{top:var(--hero-mark-top,45vh)}}

/* === SHORT VIEWPORT HERO COPY === */
/* The hero mark sits at a fixed 55vh with a fixed 32vh height, so its lower edge is
   pinned at 67.8vh. The copy is anchored to the BOTTOM of the hero instead, so its top
   is at 100vh - 50 - copyHeight -- a fraction that climbs as the viewport gets shorter
   until the two meet. Around 620px tall they collide.

   The mark is what stays fixed, because the interface panel behind it cuts a socket to
   exactly its size and a resizing mark would no longer fit its own hole. So the copy is
   what yields. Nothing is hidden and nothing is scaled: the block simply tightens --
   the caption loses its extra leading, the label sheds its margin, and the two contact
   rows lose the padding that was giving them a 44px tap target, which they can afford
   on a landscape phone where the pointer is usually a mouse anyway.

   These are height queries, so they do not touch a normal portrait phone: a 375x812
   device keeps the full spacing. They bite on a landscape phone and on a short desktop
   window, which is exactly where the collision was. */
@media screen and (max-height:700px){
  .banner__hero .heroCopy{bottom:34px}
  .banner__hero .heroCopy>p.monospace{line-height:1.4;margin-bottom:0}
  .banner__hero .heroButtons{margin-top:16px}
  .heroButtons .button__half{padding:7px 0}
}
@media screen and (max-height:560px){
  .banner__hero .heroCopy{bottom:24px}
  .banner__hero .heroCopy>p.monospace{font-size:10px;line-height:1.35}
  .banner__hero .heroButtons{margin-top:11px}
  .heroButtons .button__half{padding:5px 0}
}

/* === HERO BLACKOUT === */
/* The hero is the mark and nothing else: no cloud field, no interface panel, no canvas
   of any kind behind it. The bundled rule still paints the old sky gradient -- two
   identical copies of `section .banner__hero` inside the minified chunks -- so it is
   overridden here rather than edited in place, because those chunks are generated
   output and a hand-edit to them would not survive a rebuild.

   Flat #000 rather than var(--bgcolor). The mark is pale and matte and reads best
   against true black; --bgcolor is #1a1a1a, which sits close enough to the mark's own
   shadow side to soften the silhouette that is now the only thing in the frame. */
section .banner__hero{background:#000}

/* === GREEN PALETTE === */
/* --blue becomes #00fd01. It is redefined here rather than edited inside the minified
   chunk that declares it, so the original value stays readable in the source and the
   whole change reverts by deleting this one block.

   The swap is not just a hue change, it is a LUMINANCE INVERSION, and that is what the
   rest of this block is for. The old blue sat at relative luminance 0.025;
   the green sits at 0.703. Everything that was legible as something pale on a
   dark panel is now that same pale thing on a near-white-bright one:

     - --grey body text on the section background: 1.39:1, invisible
     - white on the same:                          1.40:1, invisible

   So the three .section__blue sections -- #process, #contact and the footer -- flip to
   dark type. --blue-ink is a very dark green rather than a neutral black, so the
   sections read as one colour family: 12.27:1 on the green.

   The individual overrides below are each a place where the inversion does NOT follow
   automatically from --color, because the rule hardcodes a palette token:

     .button:hover        paints the label --bgcolor (#1a1a1a) over a fill of --color.
                          With --color now dark ink that is dark on dark, so the label
                          takes the section's own green instead: 12.27:1.
     .mobilenav           is painted with --blue and hardcodes --grey text.
     .errorScreen__label  puts --blue text on a --grey chip, which as green-on-grey
                          would be 1.39:1; the ink gives 8.82:1. Note this selector,
                          and the .speed hover at the end of the block, match NOTHING
                          on index.html -- an error screen is a different state, and
                          the .speed span was never in this markup. They are kept so
                          the token stays consistent wherever they do render, not
                          because they fix anything visible here.
     footer wordmark      .footer__logoStack / .footer__logo--trail hardcode --grey, so
                          the flip never reached them. This one was previously asked to
                          stay WHITE, and on the old mid-tone green it could -- white
                          held 3.38:1 there. It cannot here: white on #00fd01 is
                          1.40:1, which is not a low-contrast choice, it is an
                          invisible one. It takes the ink.
     --border/--borderFade
                          are white at 70%/50% on :root and wash out completely on the
                          green, so they are restated as the ink at the same alphas. */
:root{--blue:#00fd01;--blue-ink:#04210a}
.section__blue{--color:var(--blue-ink);--border:1px solid rgba(4,33,10,.7);--borderFade:1px solid rgba(4,33,10,.5)}
.section__blue .button:hover{color:var(--blue)}
.mobilenav{color:var(--blue-ink)}
.errorScreen__label{color:var(--blue-ink)}
.footer .footer__logoStack,.footer .footer__logo--trail{color:var(--blue-ink)}
section .banner__hero p span.speed span.line__inner:hover{color:var(--blue-ink)}

/* === EYEBROW INK === */
/* The whole eyebrow crosses to black while a green section is behind it, in step with
   the 3D mark. logo3d.js owns the detection and toggles body.eyebrow-ink; everything
   below is just what that class repaints. The fade is 200ms, not something
   more leisurely, because it can only BEGIN at the instant green reaches the eyebrow:
   any earlier and a black eyebrow would be sitting on the dark page, invisible. So
   the whole duration is spent mid-grey over green, and short keeps that window brief.

   The colours are split out into their own custom properties rather than reusing
   --border. --border is a full shorthand string ("1px solid hsla(...)"), and a
   shorthand swap CANNOT be transitioned -- the 1px rules would snap to black while the
   text faded over 350ms. Splitting the colour out is what lets the wordmark, the nav
   links, the Menu button and both horizontal rules all arrive together on one curve.
   The list used to be longer -- a phone number and a Free Consultation divider sat in
   the header too -- and the rules that inked those came out with them.

   The wordmark needs its own line because its <path> carries fill="var(--primarycolor)"
   as a presentation attribute rather than fill="currentColor" (which the FOOTER
   wordmark does use), so a colour change on the header does not reach it. A CSS rule
   outranks a presentation attribute, so this re-inks it without touching the markup. */
body{--eyebrow-ink:var(--primarycolor);--eyebrow-rule:hsla(0,0%,100%,.7)}
body.eyebrow-ink{--eyebrow-ink:#000;--eyebrow-rule:rgba(0,0,0,.55)}
header{color:var(--eyebrow-ink);border-top:1px solid var(--eyebrow-rule);border-bottom:1px solid var(--eyebrow-rule);transition:color .2s ease,border-color .2s ease}
header .logo svg path{fill:var(--eyebrow-ink);transition:fill .2s ease}


/* === NO EYEBROW SCRIM === */
/* body:before was a 150px fixed band of --bgcolor (#1a1a1a) fading to nothing, sitting
   above everything at z-index 11 so it greyed the top of every section alike. It is
   dropped with content:none rather than display:none so no box is generated at all.

   What it was doing is already done better by .topOverlay__section, which is the same
   idea per section and in that section's OWN colour: a sticky 20vh gradient from the
   background down to transparent, faded in by ScrollTrigger. Content rising into the
   eyebrow dissolves into the panel it belongs to instead of into a grey that matched
   nothing -- on the black hero the scrim was actually LIGHTER than the page and left a
   visible haze around the mark.

   The cost is at the top of #services. That panel is #71737d, and the eyebrow's
   --primarycolor (#D9DCDF) on it is 3.74:1, where the scrim had been darkening the
   ground under the type. That contrast was already the weakest on the site before this
   change; the scrim was hiding it rather than fixing it. */
body:before{content:none}

/* === SECTION FIGURES === */
/* Three photographs placed in columns that were previously empty: the Why Glass House
   row's left half, the Free Consultation row's left half, and the space under the
   Services eyebrow. The Free Consultation figure shares the Why Glass House rules --
   same 50% column, same portrait crop, same section language -- rather than repeating
   them under its own name.

   They are sized in ch-independent terms off their column rather than given fixed
   dimensions, because both columns are percentage-width and collapse to 100% below
   600px -- where an unconstrained portrait 900px tall would push the heading it is
   meant to sit beside a full screen down the page. Hence the max-width in px on the
   narrow layout, which is a cap on the mobile case only.

   white-space is reset on the Services figure because .layout__third.monospace sets
   pre-line to keep its label's authored line breaks, and that would otherwise apply
   to the figure's own whitespace too. */
.sectionFigure{border-radius:var(--radius);margin:0;overflow:hidden;white-space:normal}
.sectionFigure img{display:block;height:auto;width:100%}
.sectionFigure--why,.sectionFigure--contact{margin-top:1vw;width:82%}
.sectionFigure--services{margin-top:3vw;width:100%}
@media screen and (max-width:600px){
.sectionFigure--why,.sectionFigure--contact{margin:0 0 30px;max-width:340px;width:100%}
.sectionFigure--services{margin:20px 0 10px;max-width:340px;width:100%}
}

/* === ADDITIONAL SERVICES HEADING === */
/* "Additional Services" is a section eyebrow now, set like the ones over Services and
   Process: JetBrains Mono 16px/400, uppercase, -.05vw tracking, 1.35 line-height. It
   had been Archivo at clamp(36px,5.2vw,76px)/600, which was the right answer while it
   was the only label the section had -- every item below it is Archivo too, so size was
   what separated a title from a list of names. As an eyebrow it separates by FAMILY
   instead, which is how the rest of the page marks a section opening, and it stops
   competing with the service names for the role of largest type in the section.

   The selector is the class, not the BEM name. .section .sectionEyebrow, where the 16px
   otherwise comes from, is two classes, and the bundle sizes this element from .section
   .homeworks .additionalServices__title -- three -- so the shared rule cannot reach it
   however late it appears. Four classes here beat that, and selecting on .sectionEyebrow
   means the class in the markup is doing real work rather than labelling. The values
   are restated because they cannot be inherited: .monospace supplies family, weight,
   tracking and uppercase to the other eyebrows through their parent, and this heading
   has no .monospace ancestor. If the eyebrow treatment moves, it has to move here too.

   No mobile size: the other eyebrows are 16px at every width, so this one is as well,
   and the 42px phone override went with the clamp.

   The rule beneath closes the group and the space below detaches it from the first item.
   Its column carried width:66% here, won for a 76px line that had six pixels of clearance
   at 50%. That has been dead since this section became a grid: ADDITIONAL SERVICES GRID
   sets the same four-class selector to 100% further down the file and takes it. Removed
   rather than left as a fallback, because a declaration that never applies is one more
   thing to reason about. The divider runs the full grid width, past the items' columns,
   which is the right shape for a rule under a heading. */
.section .homeworks .additionalServices{margin-bottom:2.5vw}
.section .homeworks .additionalServices .layout__half{border-bottom:var(--borderFade);padding-bottom:1.2vw}
.section .homeworks .additionalServices .sectionEyebrow{font-family:JetBrainsMono,monospace;font-size:16px;font-weight:400;letter-spacing:-.05vw;line-height:1.35;text-transform:uppercase}
@media screen and (max-width:600px){
.section .homeworks .additionalServices{margin-bottom:26px}
.section .homeworks .additionalServices .layout__half{padding-bottom:14px;width:100%}
}

/* === ADDITIONAL SERVICES GRID === */
/* Five services were five full-width rows that each used 47% of the width starting at
   34% -- the left third empty by design, the right fifth empty by accident -- and cost
   647px of section for about 250px of text.

   They are now one grid. .homeworks becomes the grid container and its existing rows
   become the cells, so the markup is untouched: each row keeps its empty .layout__third
   (hidden here) and its .layout__half (widened to fill the cell). The heading row spans
   every column.

   Columns are auto-fit rather than a count per breakpoint, because "as many as fit" is
   the actual intent -- 5, 4, 3, 2, and a single column on a phone, with the track floor
   doing the deciding. A ragged last row at the in-between widths is inherent to laying
   out six things in n columns; fixed counts would produce it too, minus the
   width-following.

   auto-fit does NOT save us at the wide end, though it reads as if it should. It
   collapses tracks that are EMPTY, and the heading spans grid-column 1/-1, so every
   track it opens contains an item and none can collapse -- past the width where a
   surplus track opens, the grid grows a dead column rather than holding still. That is
   measured, not theoretical: with five items it was seven 224.9px tracks at 1920 and
   584px of empty grid to the right of "Decks & print".

   So the count is pinned explicitly from the width where the last NEEDED track has just
   appeared. n tracks fit when n*220 + (n-1)*0.02W <= 0.94W - scrollbar, which puts the
   sixth at ~1590 and a seventh at ~1900; the media query starts at 1600. Below it
   auto-fit yields six or fewer on its own, above it the explicit six holds the seventh
   track shut, and the two agree across the whole overlap.

   That six is the only place in this block that knows how many services there are, and
   the 1600 is derived from it. A seventh would want both recomputed -- or the media
   query dropped, which puts the surplus item on its own row.

   .layout is width:100vw with its own gutters, which inside a grid cell would overflow
   the page, so the width and padding are handed to the container. The gutters stay 3vw
   so the grid lines up with every other section's left edge.

   Type: the names were 2.8vw (28px at 1024), sized for a 470px row and far too large
   for a 220px track -- "Ad & social creative" alone would have taken three lines. They
   scale on their own axis now, and the descriptions keep the site's 10px monospace with
   a line-height set explicitly, since 'normal' varies by family and these wrap to two
   lines in every column width above one. */
/* .no__pt drops this section's padding-top to .3vw !important, which is right for a
   section that opens with a 10px eyebrow but was not for the 76px heading this one used
   to open with, which started about 4px under the lightgrey panel's edge. The two greys
   are close in value, so with no gap the title read as the bottom of that panel rather
   than as the top of what follows. The heading is an eyebrow now and would survive the
   smaller padding, but the air is worth keeping: it is what sets this section's opening
   apart from the panel above rather than what rescues the heading from it.

   The padding goes on the grid container rather than on the section: it does not have
   to out-!important a utility class that way, and it stays inside the box the green
   overlay is bound to (see below), so the wipe geometry is unaffected. */
.section .homeworks{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));column-gap:2vw;row-gap:2vw;margin-bottom:3vw;padding:2.4vw 3vw 0;width:100%}
@media screen and (min-width:1600px){
.section .homeworks{grid-template-columns:repeat(6,1fr)}
}
.section .homeworks > .layout{margin:0;padding:0;width:auto}
.section .homeworks > .layout > .layout__third{display:none}
.section .homeworks > .layout > .layout__half{width:100%}
.section .homeworks > .additionalServices{grid-column:1/-1;margin-bottom:.6vw}
.section .homeworks .additionalServices .layout__half{width:100%}
.section .homeworks .small_print p.lead.last{font-size:clamp(17px,1.6vw,22px);line-height:1.05;margin-bottom:6px}
.section .homeworks .small_print p.monospace{line-height:1.35}
/* 10vw of padding under a section that is now a third of its old height reads as a
   dropout rather than as breathing room. */
section.homeworksSection{padding-bottom:4vw}
/* The liquid section transition assumes a section at least a screen tall. Its overlay is
   height:100vh pinned to the section's BOTTOM, so its top edge sits one viewport above
   that -- inside the section's own content when the section is tall, and 500px above the
   section entirely once this one shrank to ~256px. Since the wipe is triggered on the
   overlay's own top edge reaching the top of the viewport, it was starting before the
   Additional Services heading had even scrolled into view and covering the whole list in
   green while it was being read.

   height:100% binds the overlay to the section box instead (.section is the positioned
   ancestor, so the percentage resolves against it). The wipe cannot begin until the
   section's top reaches the top of the viewport, which is well after the list has been
   on screen, and it cannot reach up into the section above. What it costs is scale: the
   sweep is now the height of this section rather than a full screen. That is the trade
   for a short section -- for the bleed to run a full viewport BEFORE touching content,
   a section needs a viewport of clearance beneath its content, which is exactly the
   height this change was asked to remove. */
section.homeworksSection .overlay{height:100%}
@media screen and (max-width:600px){
.section .homeworks{column-gap:20px;row-gap:22px;margin-bottom:26px;padding:26px 20px 0}
.section .homeworks > .additionalServices{margin-bottom:2px}
.section .homeworks .small_print p.lead.last{font-size:19px;margin-bottom:5px}
section.homeworksSection{padding-bottom:34px}
}

/* === SCREEN CORNERS === */
/* The tube bulge is carried by crt.png on .vignette:before; this deepens the falloff
   where a curved screen actually loses the most light -- the corners, which sit furthest
   from the centre of the glass and turn away from the viewer hardest.

   Two layers rather than one. A single centred ellipse darkens the corners and the edge
   midpoints on the same curve, and an evenly darkened border reads as a frame, not as
   curvature. So the corner radials do the work and the centred one only adds a whisper
   of overall falloff behind them -- the corners land around thirty times darker than the
   middle of any edge.

   The corner pools carry FOUR stops, not two, because the depth at the corner and the
   reach into the screen are separate things and two stops tie them together: a two-stop
   pool decays linearly, so the only way to keep the corner dark is to drag a visible
   shadow a third of the way across the page with it. The extra stops bend the decay
   convex -- steep immediately, then tapering -- which holds the corner where it was and
   drops everything past it. Measured down the diagonal at 999x615, against the two-stop
   version it replaces:

     corner  .580 -> .584      80px  .353 -> .179
      40px   .471 -> .360     120px  .228 -> .061
                              160px  .095 -> .018

   The same retune roughly halves what the top corners take off the wordmark: at 1440
   wide, .375 -> .194 over it, so its contrast against the Services panel comes back from
   about 2.7:1 to about 3.3:1, against 3.74:1 with no vignette at all.

   The corner pools are CIRCLES in vmin, not percentages of the box. A percentage radius
   takes the box's aspect, so on a portrait phone each one stretches into a 325px-tall
   ellipse and the four of them merge into bands down the left and right edges -- side
   vignetting, not corner falloff. vmin keeps them round and keeps their reach in
   proportion to the smaller dimension at any aspect. The overall falloff behind them
   stays in percentages, because THAT one should follow the shape of the screen.

   No transform. .vignette:before is scaled 1.02 to hide the texture's own edges; this
   has no edges to hide and needs to hug the real ones, or the darkest part of it would
   be cropped away just outside the viewport.

   Note this sits at .vignette's z-index 100, above the header -- as the CRT texture
   already does, since a screen effect that stopped at the chrome would not read as a
   screen. The top corners therefore dim the wordmark and the nav links slightly. */
/* 100vw INCLUDES a classic scrollbar; .vignette is fixed, so its containing block is
   the initial containing block, which excludes one. On Windows and Linux that puts its
   right edge ~15px past the last visible pixel and carries both right-hand corner pools
   out with it -- their darkest point never renders, and the right of the screen ends up
   measurably lighter than the left. 100% resolves against the same box the page is
   actually painted into. */
.vignette{width:100%}
.vignette:after{background:radial-gradient(30vmin 30vmin at 0 0,rgba(0,0,0,.55) 0,rgba(0,0,0,.23) 30%,rgba(0,0,0,.06) 55%,rgba(0,0,0,0) 75%),radial-gradient(30vmin 30vmin at 100% 0,rgba(0,0,0,.55) 0,rgba(0,0,0,.23) 30%,rgba(0,0,0,.06) 55%,rgba(0,0,0,0) 75%),radial-gradient(30vmin 30vmin at 0 100%,rgba(0,0,0,.59) 0,rgba(0,0,0,.25) 30%,rgba(0,0,0,.07) 55%,rgba(0,0,0,0) 75%),radial-gradient(30vmin 30vmin at 100% 100%,rgba(0,0,0,.59) 0,rgba(0,0,0,.25) 30%,rgba(0,0,0,.07) 55%,rgba(0,0,0,0) 75%),radial-gradient(80% 80% at 50% 50%,rgba(0,0,0,0) 54%,rgba(0,0,0,.1) 100%);content:"";height:100%;left:0;pointer-events:none;position:absolute;top:0;width:100%}

/* === WIPE EDGE BLEED === */
/* The section wipe is four stacked layers; three of them are blurred, at 4px, 8px and
   12px, so that they lead the solid one as a soft smear. A Gaussian blur does not know
   which edge you meant -- it softens the layer's SIDES by exactly as much as its leading
   edge. The layers were inset:0, so their sides sat exactly on the screen's sides, and
   CSS blur(N) takes N as the standard deviation: at 12px the colour is still falling off
   ~36px in. Anywhere the crisp layer had not yet reached -- which is the whole leading
   band, the part you actually watch -- the green faded out before it got to the left and
   right edges and left a dark margin down both sides.

   So the layers are handed 64px of overhang on each side and .overlay's overflow:hidden
   (set in LIQUID SECTION TRANSITION above) crops it. The soft side edges now fall outside
   the visible box and every frame of the wipe reaches the screen edge at full strength.
   64 clears 3 standard deviations of the widest blur with room to spare.

   width:auto is not optional: the rule above sets width:100%, and a width plus both a
   left and a right over-constrains the box, so the used width would win and the right
   offset would simply be dropped -- the bleed would appear on the left only.

   Horizontal only. The layers scale from transform-origin 50% 100%, so stretching the
   box vertically would move that origin and change the wipe's geometry; stretching it
   sideways cannot, since 50% of a symmetrically widened box is the same centre line and
   scaleY does not touch x. The bottom edge needs nothing anyway: the crisp, unblurred
   layer is the last child, painted on top, and it covers from the overlay's bottom edge
   up, so the blurred bottoms are never the topmost thing on screen. */
.overlay div{inset:0 -64px;width:auto}

/* === FOOTER WORDMARK FAN (MOBILE) === */
/* The trail is sized in PERCENTAGES of the wordmark's own height, so the fan keeps its
   shape at every width -- and its absolute reach tracks the type. That is the problem on
   a phone: the wordmark is 49px tall there against 166px at 1280, so the same 17% and
   0.60 that melt 762px down a desktop footer travel 225px and stop less than a third of
   the way to the contact row. Measured at 375x812: the deepest copy ended at y 408 with
   291px of empty green under it.

   Steeper here. 30% and 1.06 per depth step put that copy at y 581 -- 398px below the
   wordmark, still 119px clear of the contact row, which matters because .footer__logoStack
   is positioned and the trail would otherwise paint over the contact type rather than
   behind it.

   The two numbers are scaled together, keeping the roughly 1:3.5 ratio the desktop pair
   has, so the character is unchanged: each copy still travels a little and stretches a
   lot. The blur and opacity ramps are deliberately untouched -- they are indexed on depth,
   not on distance, so the tail still fades and softens over the same six steps and simply
   does it across more screen. */
@media screen and (max-width:600px){
.footer .footer__logo--trail{transform:translateY(calc(var(--trail-progress) * var(--trail-index) * 30%)) scaleY(calc(1 + var(--trail-progress) * var(--trail-index) * 1.06))}
}

/* === WHY GLASS HOUSE DENSITY (MOBILE) === */
/* The three benefit rows keep their desktop spacing on a phone, and the spacing is most
   of what is there. Measured at 375x812: each row is 202px tall carrying 72px of content
   -- a 54px header and one 18px line of copy -- with 130px of padding and margin around
   it, and a further 40px of collapsed margin between rows. The three of them spanned
   704px of a 1603px section to say twelve words.

   Halved, roughly: 40px of vertical padding to 16, the 20/40 margins dropped entirely so
   the rows sit flush and their own padding does the separating, the header's 20px to 10,
   the title's 14px to 10, and the 30px under each line of copy to nothing since the row's
   bottom padding already provides it. Rows become 106/106/124 and the three span 336px,
   taking the section from 1603 to 1175 -- 428px, a little over a screen's worth on a
   phone, without touching a type size.

   The rules above and below each title are what separate the rows, so tightening the
   space around them reads as a denser list rather than a cramped one; it is the desktop
   layout that was carrying a gap the eye does not need at this width.

   Scoped to .section.section__pricing, which is the Why section and nothing else. The
   Services section uses .pricing__box too, for a single box beside a photograph, where
   the generous version still looks right -- and three classes beat the bundle's two, so
   this does not depend on file order. */
@media screen and (max-width:600px){
.section.section__pricing .pricing__box{margin:0;padding:16px 0}
.section.section__pricing .pricing__box--header{margin-bottom:10px}
.section.section__pricing .pricing__box--name{padding:10px 0}
.section.section__pricing .pricing__box p:not(.lead){margin-bottom:0}
}

/* === SECTION EYEBROW ABOVE FIGURE (MOBILE) === */
/* Why Glass House is built as a figure in the first .layout__half and the copy in the
   second, opening with the section's eyebrow. Below 600px the halves stop sitting side by
   side and stack, which drops the photograph in above the eyebrow that is supposed to
   announce the section. Put the eyebrow first.

   Free Consultation used to be here too, on the same selectors. Its eyebrow was removed
   when that section became the quote form, whose heading needs no help -- it is the first
   thing in the column either way. The contact half of each selector went with it, rather
   than being left to restructure a row for no reason.

   order cannot do that on its own: it only sorts siblings within one flex container, and
   the eyebrow is a child of the SECOND half while the figure is inside the FIRST. So the
   halves get display:contents, which removes their boxes and promotes the figure, the
   eyebrow, the heading and everything after it to children of the row itself -- then
   order:-1 on the eyebrow is enough. Nothing is lost with those boxes: at this width
   .layout__half carries width:100% and nothing else.

   flex-wrap and justify-content are reset explicitly. The bundle's desktop .layout rule
   sets wrap and space-between, and the mobile rule only overrides display to block, so
   turning display back to flex here quietly reinstates both. Today they compute to no
   difference -- the row's height is auto, so space-between has no free space to
   distribute -- but a min-height on either container later would spread the children
   apart, or wrap them into columns, for no visible reason.

   Mobile only, so the desktop two-column arrangement is untouched. */
@media screen and (max-width:600px){
#why .pricing__content{display:flex;flex-direction:column;flex-wrap:nowrap;justify-content:flex-start}
#why .pricing__content>.layout__half{display:contents}
#why .pricing__content .layout__half>.monospace{order:-1}
}

/* === LEAD DESCENDERS AND PANEL RULES === */
/* Two things about the rule that runs under a .lead heading.

   FIRST, it lands in the heading's descenders. .lead sets line-height 1, and a line box
   one em tall cannot hold Archivo, whose own ascent and descent come to 1.088em. The
   glyphs overflow the box by the difference, and since the box below it carries the rule
   on its border-top with nothing between them -- measured gap: 0 -- the rule is drawn
   straight through the tail of the g in "design".

   The overhang is a fixed fraction of the type, not of the viewport: 0.0162em, which is
   about 10% of the descender's depth at every width measured (1.7px at 768, 2.9px at
   1280, 4.0px at 1600). Small in pixels, but at this size it reads as a collision rather
   than as a near miss.

   So the margin is in em of the heading's own font size, which is what the overhang
   scales with -- .lead is sized in vw, so anything in px or vw would only hold at one
   width. 0.06em clears the 0.0162em and leaves roughly 0.04em of air under the tail.
   Applied to the two headings that are actually followed by a bordered box; the contact
   section's number is followed by a paragraph and is left alone. Why Glass House has no
   descender in its copy today, so it gains only the clearance, not a visible shift.

   SECOND, the rules are white on a panel whose text is near-black. --border and
   --borderFade are white at 70% and 50% on :root, which is right for every section that
   sets pale type on a dark ground -- the hero, Additional Services and Why all do. The
   green sections already restate them in their own ink. Services is the one panel that
   inverts to --black on --lightgrey and never restated them, so it draws white rules
   around #111 text. Same fix the green sections use, same two alphas, so the heavier and
   lighter weights stay distinguishable from each other. */
#services h2.lead,#why h2.lead{margin-bottom:.06em}
.section__lightgrey{--border:1px solid rgba(17,17,17,.7);--borderFade:1px solid rgba(17,17,17,.5)}

/* === SERVICES INTRO HEADING (MOBILE) === */
/* On a phone the Services photograph and the heading under it are 181px apart. Three
   rules stack up to that, and none of them is obviously the culprit on its own:

     10px   the figure's own bottom margin
     40px   .layout__third.monospace padding-bottom, a global mobile rule
    112.5   section .intro h2 margin-top -- 30vw, and the one that dominates
    18.75   that heading's padding-top, 5vw

   The 30vw is left over from when this column was empty. The eyebrow sat alone above the
   heading and needed the air; a 293px photograph was added to the column later, bringing
   its own margin and the column's padding with it, and the 30vw went on sitting on top of
   all of it.

   The right number is not a guess -- the page already answers this. Why Glass House and
   Free Consultation have the same shape on a phone, a photograph above a 75px .lead
   heading, and both run a measured 30px. So: drop the column padding and the heading's
   margin here, and let 10px of figure margin plus 20px of heading padding come to the
   same 30px. The margin collapses to the figure's 10 once the padding is gone, which is
   why the padding-top carries the rest rather than a margin that would collapse with it.

   Scoped to the Services intro and to phones. Desktop keeps 10vw + 5vw, where the column
   is beside the heading rather than above it and none of this arithmetic applies. The
   column padding is dropped only inside this intro -- the same rule spaces the accordion
   rows and the Additional Services rows, which are not affected. */
@media screen and (max-width:600px){
#services .intro .layout__third.monospace{padding-bottom:0}
#services .intro h2.lead{margin-top:0;padding-top:20px}
}

/* === MOBILE NAV CLIP === */
/* .mobilenav is a fixed, full-width, 85svh panel of #00fd01 at z-index 20 -- above every
   section, above both wipes, above everything on the page. The only thing keeping it off
   the screen is its clip-path. It is also pointer-events:none, so if it ever does paint it
   blocks nothing and swallows no taps: it would just be green.

   That clip-path was written in the rect() form. rect() in clip-path is CSS Shapes Level 2
   and only shipped in Chrome 133, Safari 18.4 and Firefox 137, all during 2025. A browser
   older than that does not fail gracefully here -- it drops the declaration as invalid,
   which leaves the panel unclipped.

   inset() is the same shape and has been supported since 2016. Not a redesign: rect(0 100%
   0 0) is top edge 0, right edge 100%, bottom edge 0, so zero height, and the browser
   already reports its computed value as inset(0px 0% 100% 0px) -- 100% inset from the
   bottom. This writes down what it was always computing, in a form every browser can read.
   The open and close tweens in app.js are converted to match, so the property is the same
   function throughout and GSAP interpolates it rather than snapping between two forms. */
.mobilenav{clip-path:inset(0 0% 100% 0)}

/* === SECTION SCRIM HANDOVER === */
/* Each section carries a .topOverlay scrim: a 20vh gradient, its own background colour at
   the top fading to transparent downward, stuck to the top of the viewport while that
   section owns the screen. A ScrollTrigger adds is-visible on entry and removes it at
   "bottom 20%" -- the moment the section's bottom edge reaches 20vh from the top.

   That is not an arbitrary number. The scrim is 20vh tall and pinned at top:0, so its own
   bottom edge is also at 20vh. The trigger drops it at exactly the frame it would start
   hanging past the end of its section. The geometry is deliberate and correct.

   The transition is what breaks it. opacity .3s means the scrim keeps painting for 300ms
   after the class is gone, and the page keeps moving underneath it. Measured at 1004x740:
   at section-bottom 160 it is lit and 11.7px inside its section; by 120 it hangs 28.3px
   past; from 80 down it hangs 47.6px past. It overshoots because margin-bottom:-20vh
   collapses its sticky margin box to nothing, so the constraint that should stop it at the
   section's end never bites.

   Below that boundary the wipe cannot help -- the wipe is clipped to its own section. So
   for 300ms a band of the OUTGOING section's colour paints over the INCOMING one, hard
   edged at the boundary because the wipe covers everything above it, fading downward
   because that is the tail of the gradient. Green over the black Why section coming out of
   Process; black over green going into Contact.

   The fix is to move the transition onto the visible state. Adding the class then fades in
   as before -- a transition is chosen from the after-change style, which now carries one --
   while removing it snaps, because the base rule no longer does. That makes the exposure
   provably zero rather than merely small: the scrim is only ever painted while the trigger
   says it is inside its section. Nothing is lost on the way out, either. At the frame it is
   dropped, the wipe already covers the viewport down past 20vh, so the scrim is behind it
   and the snap cannot be seen. */
.topOverlay__section{transition:none}
.topOverlay__section.is-visible{transition:opacity .3s ease}

/* === QUOTE FORM === */
/* The contact section led with the phone number set as a .lead, which on this page means
   14vw -- about 139px on a desktop and three stacked lines on a phone. A heading reading
   "Request a quote" cannot take that size: it is fifteen characters rather than twelve
   digits, and it is a label for what follows rather than the thing itself. So the title
   is on its own scale, clamped the way the Additional Services title is, prominent
   without setting the whole column.

   The fields borrow what the page already uses rather than inventing a control style:
   monospace labels like the other eyebrows, and a single bottom rule in var(--border),
   which the green section defines as rgba(4,33,10,.7) -- the same rule that separates
   the benefit rows. No boxes, no radius, nothing new.

   Focus and the invalid state both need to read against #00fd01, and the page-wide
   a:focus-visible rule uses var(--green) at #0f0, which on this ground is invisible. Both
   are drawn in the section ink instead. Neither changes the border WIDTH -- a second line
   is drawn with box-shadow, because growing a 1px border to 2px moves everything below it
   by a pixel as you tab through the form. The invalid state also brings its label to full
   opacity and reveals a message, so state is never carried by a line alone. A field that
   failed also takes a black asterisk before its label.

   The asterisk is a :before on the LABEL rather than a character in the markup, so it
   exists only while .is-invalid does -- there is no element to hide at rest and nothing
   for a screen reader to read out on a form that has not been submitted yet. It also
   inherits the label's opacity, which that rule has already taken to 1 by the time the
   asterisk exists, so the ink is full strength rather than the .6 the label sits at
   when everything is fine.

   Black rather than white, and it is not a close call on this section: #000 on #00fd01
   measures about 15:1, white on the same green about 1.4:1 -- the figure the GREEN
   PALETTE block above already records for exactly this reason. White needed a disc
   behind it to be legible at all; the ink does not, so the marker is one glyph again
   and the field keeps its original spacing.

   font-weight:700 is outside the face's own 400-500 range, so the variable axis clamps
   at 500 and the browser synthesises the rest. For one glyph that is the right trade:
   asking for 500 alone would be too close to the label beside it to read as a marker.

   The message sits BESIDE the label rather than under the input. The field is a wrapping
   flex row and the input carries flex-basis:100%, which forces it onto a line of its own
   and leaves the label and the message sharing the one above. In the markup the
   paragraph moved up between them; aria-describedby still points input at message, so
   what a screen reader announces is unchanged either way.

   The messages were shortened to suit the new position. "Please enter a cell number we
   can reach you on." is 46 characters, wider than the column at the phone label size, so
   it would have wrapped to its own line and landed exactly where it was being moved
   from. They are terser now and still say what is wrong.

   opacity .5 puts the message just under the label, which is .6 at rest -- and since an
   invalid field takes its label to full opacity, the pair reads as a strong field name
   with a quiet annotation next to it rather than two things competing.

   The title is pulled left by .058em, and that is an optical correction, not a layout
   one. Every box already lines up exactly -- title, form, labels and inputs all start at
   the same x. What does not line up is the INK: the R of Request carries 3px of left side
   bearing at the size it renders here, while the N of NAME in JetBrains Mono carries 0,
   so the heading reads as indented against the labels below it.

   In em because side bearing is a font metric and scales with the type, and this title is
   clamped between 34px and 64px -- measured, the bearing runs 2px at 34 and 4px at 64,
   which a fixed pixel value would only fix at one width. margin-left rather than
   text-indent so every line shifts, not just the first, should the heading ever wrap.
   Nothing else on the page is corrected this way: it only matters where a display face
   sits directly above monospace set at the same left edge. */
.quoteForm{margin-bottom:2vw}
.quoteForm__title{font-size:clamp(34px,5vw,64px);letter-spacing:-.02em;line-height:.95;margin-bottom:1.6vw;margin-left:-.058em}
.quoteForm__field{align-items:baseline;column-gap:.75em;display:flex;flex-wrap:wrap;margin-bottom:1.5vw}
.quoteForm__label{display:block;font-size:min(13px,calc(3.6vw - 1px));letter-spacing:.02em;margin-bottom:.4em;opacity:.6;transition:opacity .2s ease}
.quoteForm__optional{opacity:.55}
.quoteForm__input{-webkit-appearance:none;appearance:none;background:transparent;border:0;border-bottom:var(--border);border-radius:0;color:var(--color);display:block;font-family:JetBrainsMono,monospace;flex:1 0 100%;font-size:16px;padding:.6em 0;width:100%}
.quoteForm__input:focus{box-shadow:0 1px 0 0 var(--color);outline:0}
.quoteForm__input:focus-visible{outline:2px solid var(--color);outline-offset:4px}
.quoteForm__input--area{line-height:1.45;min-height:5.5em;resize:vertical}
.quoteForm__field.is-invalid .quoteForm__input{box-shadow:0 1px 0 0 var(--color)}
.quoteForm__field.is-invalid .quoteForm__label{opacity:1}
.quoteForm__field.is-invalid .quoteForm__label:before{color:#000;content:"*";font-weight:700;margin-right:.32em}
.quoteForm__error{font-size:min(12px,calc(3.4vw - 1px));margin:0;opacity:.5}
.quoteForm__status{font-size:min(13px,calc(3.6vw - 1px));margin-top:1em;min-height:1.4em;text-align:center}
@media screen and (max-width:600px){
.quoteForm{margin-bottom:26px}
.quoteForm__title{margin-bottom:18px}
.quoteForm__field{margin-bottom:18px}
}

/* === PILL BUTTON === */
/* The geometry is the theme's own: .pricing__box--badge is already a border + 999px
   radius + inline-flex pill in JetBrains Mono, sitting unused in the bundle. This is that
   shape at button size rather than a new one invented alongside it.

   width:auto is what makes it read as a pill rather than a rounded bar -- it hugs its
   label instead of spanning the column, which is why button__big came off both elements
   in the markup: undoing its width:100%, space-between and bottom rule from here would
   cost three more overrides than simply not asking for them. Nothing carries button__big
   now; its rules are left in the bundle with the rest of the theme surface this page does
   not use.

   The contact-block rules are the awkward part. section .branding .button paints it
   black with grey text and adds its own horizontal padding, section .branding
   .button:before fills it lightgrey, and section .branding .button:hover forces #000 with
   !important. That is two classes and an element, which a plain .button__pill cannot
   reach. These overrides used to carry #contact for the weight, but there are two pills
   now -- the form's submit and the Services CTA -- and only one of them is inside
   .branding, so an id naming one section is the wrong instrument.

   .buttons .button.button__pill is three classes. It outranks two-classes-and-an-element
   without naming a section, and both pills sit in a .buttons row, which is what makes
   the extra class available to spend. The hover colour still needs its own !important
   to answer theirs.

   Services has its own set. .section__lightgrey .button sets border-width:2px and
   font-weight:600 -- the theme asking for heavier buttons on that grey -- and
   .section__lightgrey .button:hover sets color:var(--grey). Two classes each, so the
   three-class override reaches them, but only for what it actually declares: measured
   before border-width and font-weight were added here, the Services pill came out at
   2px/600 against the submit's 1px/400, which is not the same button. A component that
   changes shape by section is not a component, so the pill states both. The section
   rule is left alone; it simply has nothing else to act on.

   Neither pill is told a colour. Both read --color and --background off the section they
   are in: blue-ink on green in the contact block, #111 on #71737d in Services. So the
   Services pill is ink-on-grey at rest and grey knocked out of ink on hover, and that
   inversion measures 4.0:1 -- the same ratio every other piece of text in that section
   already sits at, rather than a new floor introduced here.

   Hover keeps the house behaviour rather than inventing one: the pill floods with the
   ink colour and the label flips to the section's own ground, so it reads knocked out of
   the fill. HOW it floods is the FADE, NOT WIPE note below -- an earlier version did it
   with the theme's :before and that mechanism is gone.

   .button:hover>span adds 1vw of padding on hover across the site -- a nice effect on a
   full-width button, but on something that hugs its label it makes the pill itself jump
   wider. Neutralised here; the fill and the colour flip carry the hover on their own.

   FADE, NOT WIPE. The theme fill is transform:scaleY(var(--anim)) with the origin moved
   by script: in from the bottom on enter, and on leave it FINISHES filling before
   flipping the origin to the top and collapsing out. One continuous upward wipe, and the
   two phases are why simply pointing that same --anim at opacity would not do -- leave
   the button early and it would brighten to full before fading, a visible pop.

   So the fill is driven from :hover here rather than from --anim, and it is the button's
   OWN background-color rather than a pseudo-element. That second part matters. A :before
   is laid out against the padding box: measured here it came to 145.25 x 42 inside a
   147.25 x 44 border box, one pixel short on every side. Along the straight edges the
   border covers that, but the ends of a pill are a 22px curve, and two independently
   rasterised rounded shapes meeting on a curve leave an antialiased hairline -- the fill
   looked like it stopped just inside its own outline.

   A background has no such seam to leave. It paints to the BORDER box by default, so the
   fill runs out under the border itself, and since both are var(--color) the whole pill
   becomes one solid shape with no second edge to misalign. The pseudo-element is switched
   off with content:none rather than left invisible. Script still animates --anim on this
   element, harmlessly -- nothing reads it any more. Background and label transition over
   the same 0.22s so the ink and the green arrive together, and reduced motion collapses
   both to effectively instant. */
.button__pill{align-items:center;border:1px solid var(--color);border-radius:999px;display:inline-flex;gap:.7em;justify-content:center;position:relative;width:auto}
/* space-between is the site default for a .buttons row and reads as flush-left with a
   single child. The pill is the only thing in this row, so it is centred in the form
   column instead. One class beats the bundle rule on its own, but the #contact scope is
   kept for consistency with the rest of this block. */
#contact .quoteForm .buttons{justify-content:center}
.buttons .button.button__pill{background-color:transparent;border-color:var(--color);border-width:1px;color:var(--color);font-weight:400;min-height:44px;padding:.8em 1.8em;transition:background-color .22s ease,color .22s ease}
.buttons .button.button__pill:before{content:none}
@media (prefers-reduced-motion:reduce){
.buttons .button.button__pill{transition-duration:.01ms}
}
.buttons .button.button__pill:hover{background-color:var(--color);color:var(--background)!important}
.buttons .button.button__pill:hover>span{padding:0}
@media screen and (max-width:600px){
.buttons .button.button__pill{padding:.75em 1.6em}
}

/* === FOOTER EMAIL === */
/* The footer contact is hello@glasshousedesignlab.com rather than the phone number, and
   the address is one 29-character token with no break opportunity in it. Below 600px it
   has to share the row with the barcode, so the room it gets is not the page width: the
   grid above spends 75px on the mark and 16px on the column gap, and the page keeps 20px
   gutters, so the link has 100vw - 131px.

   At 14px that token measures 238px against a 244px column on a 375px phone. That looks
   like six pixels to spare and it is not, because the column is not all the label gets:
   .button:hover>span adds padding:0 1vw, and .button span transitions padding over .3s,
   so hovering the link grows it by 2vw -- 7.5px on a 375px phone -- while the animation
   runs. 238.2 + 7.5 is 245.7 against 244, and .button__half > span carries
   overflow-wrap:anywhere, so it breaks the address rather than overflow its underline.
   Measured at 375: at rest one line of 238.2px, hovered two lines of 230 and 8.2 -- the
   final "m" alone on the second -- and the button 23.8px tall becoming 41.8px.

   So the type shrinks to fit, the same answer the hero rows already give this token, and
   the hover padding is part of what it has to fit inside. The width is not simply
   proportional to the font size, because .button sets letter-spacing:-.05vw -- a viewport
   unit -- so 29 characters of JetBrains Mono come to 17.4F - 0.0145W at font size F on a
   viewport W, and the padding adds 0.02W on top. Solving
   17.4F - 0.0145W + 0.02W <= W - 131 - 4, keeping four pixels of slack, gives
   F <= 5.71vw - 7.8px.

   min() caps it at the 14px the button already computes to (70% of a 20px parent), so
   nothing moves at or above 382px, where the crossover now lands. Below that it tapers:
   13.6px at 375, 12.8px at 360 and 10.5px at 320, each leaving the same five pixels of
   slack hovered as at rest, by construction. It only ever shrinks the address and never
   lets it wrap.

   Shrinking the type rather than cancelling the padding is deliberate: the 2vw spread is
   the hover the rest of the site's buttons do, and this one is not special enough to opt
   out of it. The cost is that at 375 the footer address sets 0.4px smaller than the same
   address in the hero, which has a 335px row and never needed a clamp. */
@media screen and (max-width:600px){
.footer .layout.no__pt .buttons .button__half{font-size:min(14px,calc(5.71vw - 7.8px))}
}

/* === SCREEN MATTE === */
/* The CRT frame is height:100dvh, which is the whole point of it -- its bottom edge sits
   at the bottom of the VISIBLE area and follows Safari's toolbar as that collapses. The
   cost is that there is a strip below it, behind the toolbar, that the frame never covers:
   100lvh minus 100dvh, zero when the toolbar is away and a few dozen pixels when it is
   not. That strip is page, and at the foot of this page the page is #00fd01, so the area
   under the screen's bottom corners came up green and the effect stopped reading as a
   screen at all.

   iOS can take that colour by more than one route, so all of them are closed rather than
   the one that seemed likeliest:

     - theme-color, if Safari honours it, now says #000 rather than #1a1a1a;
     - the scroll canvas, which shows in the rubber-band overscroll, was propagating up
       from body (#1a1a1a) because <html> had no background of its own. It has one now,
       and a background on the root stops body's from propagating at all;
     - and the strip itself is covered by the matte below, in case Safari is sampling
       painted pixels rather than reading either of those.

   top:100dvh rather than bottom:0 is deliberate. A fixed element pinned to bottom:0 in
   Safari rides the VISUAL viewport, so it would sit above the toolbar and paint a black
   bar across the bottom of the page. Anchoring the top instead puts it exactly where the
   frame stops, and its height carries it to the bottom of the large viewport.

   The 160px floor is the point. calc(100lvh - 100dvh) alone is zero whenever the two
   viewports agree, which is most of the time on iOS and always on a desktop -- so for most
   of the session there was no backstop at all, and any state where dvh came back smaller
   than the area actually on screen showed page below the frame instead of black. That is
   what a fresh load and a scroll down was doing: frame ends partway up, page carries on to
   the bottom of the screen, and the toolbar floats over it. Scrolling up and down settled
   dvh and it looked right again, which is what made it seem intermittent.

   With a floor there is black under the frame in every state. When dvh is honest the whole
   160px is below the visible area and nothing is drawn; it is a fixed box, so it can never
   affect layout or add a scrollbar either way.

   The horizontal axis is closed by the bundle's body{overflow-x:hidden}, which the spec
   propagates to the viewport, and that is where it has to stay. An overflow-x:clip on the
   root looked like a harmless second lock and was not: html stops being visible, the
   propagation stops with it, body becomes the scrollport -- and because body's height is
   the content height it never scrolls, which silently disables every position:sticky on
   the page. Measured both ways: with it, the step cards ran straight past their sticky
   tops (99 -> -58 -> -158); without it they hold at 99, 154 and 209, and scrollX still
   refuses to leave zero.

   For the record: at 320, 375, 390 and 430 the document scrollWidth is exactly the client
   width and no unclipped element crosses the right edge. There is no horizontal overflow
   on this page to lock down twice. */
html{background-color:#000}
.screenMatte{background-color:#000;height:max(160px,calc(100lvh - 100dvh));left:0;pointer-events:none;position:fixed;right:0;top:100dvh;z-index:99}

/* === FIELD ZOOM === */
/* iOS Safari zooms the whole page in when you focus a field whose text is under 16px. It
   is not a preference and there is no flag for it -- Apple decided a smaller field is
   unreadable and fixes it by magnifying the document. The page never zooms back out.

   .quoteForm__input was min(15px,calc(4.2vw - 1px)): 15px at 375 and 12.4px at 320, under
   the threshold at every phone width. So tapping Name zoomed the page, and from then on it
   could be panned sideways and the fixed screen frame no longer lined up with what was on
   screen -- the frame is positioned against the LAYOUT viewport, which zooming does not
   move. Both symptoms, one cause.

   16px flat, at every width, is the whole fix -- an iPad or a phone held sideways is over
   600px and still iOS, so a phone-only override would have left those zooming. It is also just better: the value someone is typing
   should not be the smallest text in the row. It reads a little larger than the 13px label
   above it now, most visibly at 320 where the old clamp had pushed it to 12.4px.

   touch-action:manipulation removes the other way in, double-tap to zoom. It is set on the
   root because touch-action is not inherited -- the permitted behaviours are the
   intersection down the ancestor chain, so the root is where it reaches everything. Pinch
   to zoom still works, deliberately: it is ignored by Safari when you ask for it not to,
   and disabling it where it can be disabled only takes the page away from anyone who needs
   it. The showcase drag keeps its own stricter pan-y, which intersects to pan-y. */
html{touch-action:manipulation}

/* === MOBILE SCROLL COST === */
/* Two things were being paid for on every scrolled frame of the three-step stack, and the
   stack is the one part of this page whose position is computed in script rather than
   composited, so it is the part that shows it.

   .gloom:before is a fixed, full-viewport backdrop-filter:blur(5px) at opacity .2. A
   backdrop filter is not painted once -- it re-reads and re-blurs everything beneath it
   whenever that moves, which during a scroll is every frame, over the whole screen. What
   it buys at 20% opacity behind a CRT frame that is already softening the page is close
   to nothing: rendered with and without it at 375, the two are hard to tell apart. It
   stays on the desktop, where there is headroom for it and a pointer to appreciate it.

   The cards get will-change:transform because their y is rewritten every frame while the
   section is in view. Without it each write is a repaint of a card holding a photograph;
   with it they are composited layers the GPU can simply move. Three elements, so this is
   not the usual will-change mistake of promoting half the document.

   Neither of these changes what the stack does -- the y values it writes at every scroll
   offset are identical before and after, which is checked rather than assumed. */
.benefits__items--item{will-change:transform}
@media screen and (max-width:600px){
.gloom:before{-webkit-backdrop-filter:none;backdrop-filter:none}
}

/* === STEP STACK (TOUCH) === */
/* Only live when script has added .is-stacked, which it does on touch devices and nowhere
   else. That gate is deliberately NOT a media query: the decision belongs to whichever
   code path is positioning the cards, and that is chosen by device rather than by width.
   A desktop window dragged narrow keeps the handler, which is smooth there, and keeping
   the gate in one place means the two can never both think they are in charge.

   Each card sticks one reveal further down than the one before it, so as the page scrolls
   each comes to rest and the next slides over it, leaving its label showing. The cards
   already carry the section green and a top rule, so the one on top covers the one under
   it without anything else being added.

   --stackTop and --stackStep are published by the script: the height of the fixed header,
   and the reveal it would otherwise have staggered the transforms by. Three nth-child
   rules rather than a loop because there are three steps; a fourth would need a line here.

   The dwell is a generated box after the last card. Two simpler things were tried first
   and measured, and neither works:

     - padding on the container. A sticky box is constrained by its containing block's
       CONTENT box and padding is outside it. 324.8px of padding-bottom moved the trail by
       nothing at all.
     - a margin on the last card. A sticky box's constraint rect also excludes its OWN
       margins, so the card carries the margin down with it: cards one and two held at 99
       and 154 while the third sailed past to -406.

   What the third card needs is something AFTER it inside the container, and :after is
   exactly that -- a block box in normal flow that the card can be held against.

   It is not only about the dwell. fit() used to hand this section about 507px of trailing
   padding on a phone, and the section wipe that follows is timed off the section, so
   dropping that padding brought the wipe forward: measured, the black overlay was 61% of
   the way across before the third card had finished moving.

   The height is the dial for when that wipe starts, and it was turned down from 60svh to
   50svh by request -- 406px at 812 rather than 487. Measured at 375 wide, as offsets from
   the top of .benefits: the stack completes at 390 either way; the wipe began at 530 and
   now begins at 450. That leaves 60px of scroll with the stack whole and nothing over it,
   down from 140. The cards stay pinned through the wipe itself, so what was shortened is
   the pause before it starts, not the stack.

   transform:none because the desktop path may have left one on an element before a
   viewport change, and a transform makes a sticky element its own containing block, which
   would stop it sticking to the page. will-change goes back to auto for the same reason --
   it is there for elements whose transform is rewritten every frame, and here nothing is. */
.benefits__items.is-stacked .benefits__items--item{position:sticky;transform:none;will-change:auto}
.benefits__items.is-stacked:after{content:"";display:block;height:50svh}
.benefits__items.is-stacked .benefits__items--item:first-child{top:var(--stackTop,0px)}
.benefits__items.is-stacked .benefits__items--item:nth-child(2){top:calc(var(--stackTop,0px) + var(--stackStep,0px))}
.benefits__items.is-stacked .benefits__items--item:nth-child(3){top:calc(var(--stackTop,0px) + var(--stackStep,0px)*2)}

/* === FRAME BLEED === */
/* A strip of page shows under the bottom of the screen frame when you scroll down quickly.
   The frame is position:fixed, and iOS does not hold fixed layers perfectly still during a
   momentum scroll -- they are repositioned a frame or two late, which opens a gap at the
   trailing edge. Scrolling down, the trailing edge is the bottom, which is where the bar
   of green or grey was coming from.

   SCREEN MATTE below was supposed to be the backstop for this and cannot be, because its
   height is calc(100lvh - 100dvh): the moment the toolbar is hidden the two viewports are
   equal, the matte is zero pixels tall, and there is nothing under the frame at all. That
   is also exactly when the page fills the screen and the gap is most visible.

   A spread box-shadow is the whole fix. It paints outside the element's border box, so it
   sits beyond every edge of the frame at once rather than under one of them, and
   overflow:hidden does not touch it -- that clips the element's CONTENT, not its own
   shadow. It also lags with the frame, because it is part of the same layer: wherever the
   frame ends up, the black is already there. 64px is far more than the lag has ever
   measured and costs nothing, since it is off-screen whenever the frame is where it
   should be.

   It covers the top edge too, which the same lag would expose when flicking upward. That
   was not reported, but it is the same mechanism and the same declaration answers it. */
.vignette{box-shadow:0 0 0 64px #000}

/* === FOOTER BARCODE === */
/* Decoration for the empty left third of the footer's bottom row, which the contact
   block has never used -- .layout__second takes 66% and is pushed right by margin-left
   auto, leaving a 33% column with nothing in it.

   A real Code 39 symbol rather than a stripe pattern: real start/stop sentinels, a
   nine-elements-per-character grid, two wide bars and one wide space in every character,
   and a 3:1 wide-to-narrow ratio, encoding 6145580U53 -- the same string printed under it,
   as a barcode label does. The rhythm is the whole point: evenly random stripes read as
   a hatch fill, and a grid with real sentinels does not.

   The SHAPE is in the bars. Each bar keeps its own x and its own width -- which is the
   entire content of the symbol -- and only its top edge moves, riding a 20-unit gable
   that peaks at the centre of the 191-unit span, a pitch of about 12 degrees. The bars
   are cut as quadrilaterals rather than rectangles, so the roofline is a straight slope
   instead of a staircase of flat tops, and because the widths are untouched the symbol
   still decodes. Flat base, so it sits on the ground rather than floating.

   No plate behind it: the bars are the artwork, currentColor picks up --blue-ink from
   .section__blue -- the same near-black the address and the copyright are set in,
   12.27:1 on the green -- and the green shows through every gap.

   Type: 12 units against a 191-unit span, so at the 180px cap the digits render at about
   11px, comfortably under the address's 14px. They are tracked out to 120 units
   rather than to the full width of the bars: at this size a full-width stretch scatters
   ten glyphs instead of tracking them.

   Width is a percentage of the COLUMN, not of the viewport. A viewport unit cannot see
   how much room it is being given: at 601px -- one pixel above the breakpoint where the
   columns stop stacking -- the third is only ~186px wide. 52% cannot outgrow its
   container by construction, the 180px ceiling keeps it a mark rather than a feature,
   and the 140px floor stops the bars going too far sub-pixel in the one band where the
   percentage alone would shrink it further. */
.footer .footer__barcode{align-items:flex-end;display:flex}
.footer .footer__barcode svg{color:var(--color,#000);display:block;height:auto;width:clamp(140px,52%,180px)}
.footer .footer__barcode svg text{font-family:JetBrainsMono,monospace;font-weight:400;letter-spacing:normal}
/* Below 600px the bundle turns .layout into a block and gives both columns width 100%,
   which stacks them. This row becomes a grid instead, two columns by two rows, so the
   mark can sit on the address's line specifically rather than beside the contact block
   as a whole.

   That needs display:contents on .layout__second. The link is one of its children, and no
   flex or grid alignment can reach past a wrapper into one of its children -- align-self
   on the mark could only ever centre it against the whole stack, which straddles the
   address and the copyright. Dropping the wrapper's box promotes buttons and copyright
   to grid items of this row, and then the mark is simply placed in the same row as the
   buttons. Their own margins still apply and keep the vertical rhythm they had.

   Row 1 ends up as tall as the mark (75px wide, so 36px) rather than as tall as the
   button (24px), which centres the address in a row a few pixels taller than before.

   Half the desktop size on a phone, by request. Worth knowing what that costs: the symbol
   is 191 units across, so at 75px a narrow bar is 0.39 CSS px. On a 3x phone that is
   still about one device pixel and the bars stay separate; on a 1x screen -- a desktop
   browser narrowed past 600px, or a preview pane -- they blur together. The caption goes
   with it, to roughly 4.7px, which is below reading size and is there as texture rather
   than as something anyone parses. */
@media screen and (max-width:600px){
.footer .layout.no__pt{align-items:center;column-gap:16px;display:grid;grid-template-columns:auto minmax(0,1fr)}
.footer .layout.no__pt>.layout__second{display:contents}
.footer .footer__barcode{grid-area:1/1;margin-bottom:0;width:auto}
.footer .footer__barcode svg{width:75px}
.footer .layout.no__pt .buttons{grid-area:1/2}
.footer .layout.no__pt .footer__copyright{grid-area:2/2}
}
