/* Joel's garage. Design values from "6b · The Garage v2". */
html,body{margin:0;height:100%}
body{font-family:'Instrument Sans',sans-serif;background:#2e4a3f;overflow:hidden}
.viewport{position:fixed;inset:0;display:flex;overflow:hidden}
.frame{position:relative;flex:none;margin:auto;overflow:hidden}
.stage{position:absolute;left:0;top:0;width:1440px;height:900px;overflow:hidden;background:#2e4a3f;color:#1d1b24;transform-origin:0 0}
.loop{position:absolute;left:0;top:0;width:1440px;height:900px;pointer-events:none}
.fx{position:absolute;left:0;top:0;width:0;height:0;pointer-events:none}
.hot:focus-visible,.lnk:focus-visible,.card-close:focus-visible{outline:3px solid #ffd166;outline-offset:3px}
.ring{position:absolute;border:4px dashed #ffd166;border-radius:16px;box-sizing:border-box;pointer-events:none}
.ring[hidden],.card[hidden]{display:none}
.card{position:absolute;width:340px;box-sizing:border-box;padding:20px;border-radius:18px;background:#fffaf0;border:3px solid #1d1b24;box-shadow:6px 6px 0 #1d1b24;display:flex;flex-direction:column;gap:14px;z-index:5}
.card-head{display:flex;justify-content:space-between;align-items:flex-start;gap:12px}
.card-heading{display:flex;flex-direction:column;gap:2px}
.card-kicker{font-size:12px;font-weight:700;letter-spacing:2px;color:#5a4f47}
.card-title{font-family:'Fraunces',serif;font-weight:900;font-size:30px;line-height:1.05}
.card-close{width:44px;height:44px;flex-shrink:0;border-radius:50%;border:2px solid #1d1b24;background:#fffaf0;display:flex;align-items:center;justify-content:center;cursor:pointer;padding:0}
.card-body{font-size:15px;line-height:1.45;font-weight:500}
.card-links{display:flex;flex-direction:column;gap:8px}
.lnk-note{font-weight:500;color:#5a4f47}
.title{position:absolute;left:56px;bottom:52px;display:flex;flex-direction:column;gap:10px;color:#fffaf0}
.title h1{margin:0;font-family:'Fraunces',serif;font-weight:900;font-size:60px;line-height:.95}
.title p{margin:0;font-size:15px;color:#d6e4dc}

/* Design animations, verbatim */
a{color:#1d1b24}a:hover{color:#c8553d}
@keyframes walk{0%{transform:translate(0,0) scaleX(1)}46%{transform:translate(219px,126px) scaleX(1)}50%{transform:translate(219px,126px) scaleX(-1)}96%{transform:translate(0,0) scaleX(-1)}100%{transform:translate(0,0) scaleX(1)}}
@keyframes legA{0%,100%{transform:rotate(18deg)}50%{transform:rotate(-18deg)}}
@keyframes legB{0%,100%{transform:rotate(-18deg)}50%{transform:rotate(18deg)}}
@keyframes wag{0%,100%{transform:rotate(-14deg)}50%{transform:rotate(16deg)}}
@keyframes bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-2px)}}
@keyframes type{0%,100%{transform:translateY(0)}50%{transform:translateY(-3px)}}
@keyframes glow{0%,100%{opacity:.85}50%{opacity:1}}
.dog{animation:walk 14s ease-in-out infinite;transform-origin:38px 56px}
.legA{transform-box:fill-box;transform-origin:50% 0;animation:legA .45s ease-in-out infinite}
.legB{transform-box:fill-box;transform-origin:50% 0;animation:legB .45s ease-in-out infinite}
.wag{transform-box:fill-box;transform-origin:100% 100%;animation:wag .35s ease-in-out infinite}
.bob{animation:bob .45s ease-in-out infinite}
.type{animation:type .3s ease-in-out infinite}
.glow{animation:glow 2.5s ease-in-out infinite}
@keyframes chan{0%{opacity:1}12%{opacity:1}12.5%{opacity:0}99.5%{opacity:0}100%{opacity:1}}
.ch{opacity:0;animation:chan 80s linear infinite}
@keyframes roll{0%{transform:translate(0,0) scale(1)}85%{transform:translate(0,-58px) scale(.45)}100%{transform:translate(0,-58px) scale(.45)}}
.roll{transform-box:fill-box;transform-origin:center;animation:roll 2.5s ease-in infinite}
@keyframes fall{from{transform:translateY(-30px)}to{transform:translateY(110px)}}
.fall{animation:fall 2.2s linear infinite}
.rain{animation:fall .7s linear infinite}
@keyframes zap{from{transform:translateX(-40px)}to{transform:translateX(180px)}}
.zap{animation:zap 1.1s linear infinite}
@keyframes ping{0%{transform:scale(.2);opacity:1}100%{transform:scale(1.4);opacity:0}}
.ping{transform-box:fill-box;transform-origin:center;animation:ping 1.6s ease-out infinite}
@keyframes surf{0%,100%{transform:translate(0,0) rotate(-4deg)}50%{transform:translate(26px,-6px) rotate(6deg)}}
.surf{transform-box:fill-box;transform-origin:center;animation:surf 3s ease-in-out infinite}
@keyframes arc{0%{transform:translate(0,0)}50%{transform:translate(60px,-50px)}100%{transform:translate(120px,-10px)}}
.arc{animation:arc 2.6s ease-out infinite}
@keyframes pass{0%{transform:translate(0,0) rotate(-20deg)}100%{transform:translate(140px,-20px) rotate(-20deg)}}
.pass{transform-box:fill-box;transform-origin:center;animation:pass 1.8s ease-in-out infinite}
@keyframes eyes{0%,100%{opacity:1}50%{opacity:.4}}
.eyes{animation:eyes .6s ease-in-out infinite}
@keyframes step{0%,100%{transform:translateY(0)}50%{transform:translateY(-4px)}}
.step{animation:step .35s ease-in-out infinite}
@keyframes robot{0%{opacity:0;transform:translate(0px,0px) scaleX(1)}0.952%{opacity:0;transform:translate(0px,0px) scaleX(1)}1%{opacity:1;transform:translate(0px,0px) scaleX(1)}3.81%{opacity:1;transform:translate(-87.6px,50.5px) scaleX(1)}5.238%{opacity:1;transform:translate(-87.6px,50.5px) scaleX(1)}7.619%{opacity:1;transform:translate(0px,0px) scaleX(1)}8.095%{opacity:0;transform:translate(0px,0px) scaleX(1)}100%{opacity:0;transform:translate(0px,0px) scaleX(1)}}
.robot{animation:robot 105s linear infinite;transform-origin:48px 176px;opacity:0}
@keyframes jPush{0%{opacity:0;transform:translate(0px,0px) scaleX(1)}1.143%{opacity:0;transform:translate(0px,0px) scaleX(1)}1.19%{opacity:1;transform:translate(0px,0px) scaleX(1)}4.286%{opacity:1;transform:translate(-193.2px,-93.1px) scaleX(1)}5.238%{opacity:1;transform:translate(-193.2px,-93.1px) scaleX(1)}7.619%{opacity:1;transform:translate(-105.5px,-143.7px) scaleX(1)}7.905%{opacity:1;transform:translate(-105.5px,-143.7px) scaleX(-1)}10.476%{opacity:1;transform:translate(0px,0px) scaleX(-1)}10.762%{opacity:0;transform:translate(0px,0px) scaleX(-1)}100%{opacity:0;transform:translate(0px,0px) scaleX(1)}}
.jPush{animation:jPush 105s linear infinite;transform-origin:40px 160px;opacity:0}
@keyframes bR{0%{opacity:0}1.381%{opacity:0}1.429%{opacity:1}4.762%{opacity:1}4.81%{opacity:0}100%{opacity:0}}
.bR{animation:bR 105s linear infinite;opacity:0}
@keyframes bJ1{0%{opacity:0}5.19%{opacity:0}5.238%{opacity:1}8.095%{opacity:1}8.143%{opacity:0}100%{opacity:0}}
.bJ1{animation:bJ1 105s linear infinite;opacity:0}
@keyframes sonFive{0%{opacity:0;transform:translate(0px,0px) scaleX(1)}15.238%{opacity:0;transform:translate(0px,0px) scaleX(1)}15.286%{opacity:1;transform:translate(0px,0px) scaleX(1)}18.095%{opacity:1;transform:translate(-87.6px,50.5px) scaleX(1)}18.286%{opacity:1;transform:translate(-87.6px,50.5px) scaleX(-1)}20.952%{opacity:1;transform:translate(-87.6px,50.5px) scaleX(-1)}23.81%{opacity:1;transform:translate(0px,0px) scaleX(-1)}24.095%{opacity:0;transform:translate(0px,0px) scaleX(-1)}100%{opacity:0;transform:translate(0px,0px) scaleX(1)}}
.sonFive{animation:sonFive 105s linear infinite;transform-origin:40px 176px;opacity:0}
@keyframes jFive{0%{opacity:0;transform:translate(0px,0px) scaleX(1)}15.429%{opacity:0;transform:translate(0px,0px) scaleX(1)}15.476%{opacity:1;transform:translate(0px,0px) scaleX(1)}18.571%{opacity:1;transform:translate(-151.3px,-78.2px) scaleX(1)}21.429%{opacity:1;transform:translate(-151.3px,-78.2px) scaleX(1)}21.714%{opacity:1;transform:translate(-151.3px,-78.2px) scaleX(-1)}24.286%{opacity:1;transform:translate(0px,0px) scaleX(-1)}24.571%{opacity:0;transform:translate(0px,0px) scaleX(-1)}100%{opacity:0;transform:translate(0px,0px) scaleX(1)}}
.jFive{animation:jFive 105s linear infinite;transform-origin:40px 160px;opacity:0}
@keyframes bS1{0%{opacity:0}18.238%{opacity:0}18.286%{opacity:1}19.619%{opacity:1}19.667%{opacity:0}100%{opacity:0}}
.bS1{animation:bS1 105s linear infinite;opacity:0}
@keyframes bJ2{0%{opacity:0}19.19%{opacity:0}19.238%{opacity:1}20.952%{opacity:1}21%{opacity:0}100%{opacity:0}}
.bJ2{animation:bJ2 105s linear infinite;opacity:0}
@keyframes burst{0%{opacity:0}19.571%{opacity:0}19.619%{opacity:1}20.571%{opacity:1}20.619%{opacity:0}100%{opacity:0}}
.burst{animation:burst 105s linear infinite;opacity:0}
@keyframes jGtrGo{0%{opacity:0;transform:translate(0px,0px) scaleX(1)}29.714%{opacity:0;transform:translate(0px,0px) scaleX(1)}29.762%{opacity:1;transform:translate(0px,0px) scaleX(1)}32.381%{opacity:1;transform:translate(-286.8px,128.8px) scaleX(1)}34.286%{opacity:1;transform:translate(-617.5px,-29.9px) scaleX(1)}34.333%{opacity:0;transform:translate(-617.5px,-29.9px) scaleX(1)}100%{opacity:0;transform:translate(-617.5px,-29.9px) scaleX(1)}}
.jGtrGo{animation:jGtrGo 105s linear infinite;transform-origin:40px 160px;opacity:0}
@keyframes jGtr{0%{opacity:0;transform:translate(0px,0px) scaleX(1)}34.286%{opacity:0;transform:translate(0px,0px) scaleX(1)}34.333%{opacity:1;transform:translate(0px,0px) scaleX(1)}38.571%{opacity:1;transform:translate(0px,0px) scaleX(1)}38.619%{opacity:0;transform:translate(0px,0px) scaleX(1)}100%{opacity:0;transform:translate(0px,0px) scaleX(1)}}
.jGtr{animation:jGtr 105s linear infinite;transform-origin:40px 160px;opacity:0}
@keyframes jGtrBack{0%{opacity:0;transform:translate(0px,0px) scaleX(-1)}38.571%{opacity:0;transform:translate(0px,0px) scaleX(-1)}38.619%{opacity:1;transform:translate(0px,0px) scaleX(-1)}40.571%{opacity:1;transform:translate(330.7px,158.7px) scaleX(-1)}42.286%{opacity:1;transform:translate(617.5px,29.9px) scaleX(-1)}42.381%{opacity:0;transform:translate(617.5px,29.9px) scaleX(-1)}100%{opacity:0;transform:translate(617.5px,29.9px) scaleX(1)}}
.jGtrBack{animation:jGtrBack 105s linear infinite;transform-origin:40px 160px;opacity:0}
@keyframes n1{0%{opacity:0}34.619%{opacity:0}34.667%{opacity:1}38.381%{opacity:1}38.429%{opacity:0}100%{opacity:0}}
.n1{animation:n1 105s linear infinite;opacity:0}
@keyframes wife{0%{opacity:0;transform:translate(0px,0px) scaleX(1)}43.81%{opacity:0;transform:translate(0px,0px) scaleX(1)}43.857%{opacity:1;transform:translate(0px,0px) scaleX(1)}46.667%{opacity:1;transform:translate(-87.6px,50.5px) scaleX(1)}46.857%{opacity:1;transform:translate(-87.6px,50.5px) scaleX(-1)}50.476%{opacity:1;transform:translate(-87.6px,50.5px) scaleX(-1)}52.857%{opacity:1;transform:translate(0px,0px) scaleX(-1)}53.143%{opacity:0;transform:translate(0px,0px) scaleX(-1)}100%{opacity:0;transform:translate(0px,0px) scaleX(1)}}
.wife{animation:wife 105s linear infinite;transform-origin:36px 144px;opacity:0}
@keyframes kid{0%{opacity:0;transform:translate(0px,0px) scaleX(1)}44.476%{opacity:0;transform:translate(0px,0px) scaleX(1)}44.524%{opacity:1;transform:translate(0px,0px) scaleX(1)}47.333%{opacity:1;transform:translate(-117.5px,37.9px) scaleX(1)}47.524%{opacity:1;transform:translate(-117.5px,37.9px) scaleX(-1)}50.762%{opacity:1;transform:translate(-117.5px,37.9px) scaleX(-1)}53.333%{opacity:1;transform:translate(0px,0px) scaleX(-1)}53.619%{opacity:0;transform:translate(0px,0px) scaleX(-1)}100%{opacity:0;transform:translate(0px,0px) scaleX(1)}}
.kid{animation:kid 105s linear infinite;transform-origin:33px 132px;opacity:0}
@keyframes jHug{0%{opacity:0;transform:translate(0px,0px) scaleX(1)}44%{opacity:0;transform:translate(0px,0px) scaleX(1)}44.048%{opacity:1;transform:translate(0px,0px) scaleX(1)}47.429%{opacity:1;transform:translate(-151.3px,-78.2px) scaleX(1)}48.095%{opacity:1;transform:translate(-155.3px,-94.3px) scaleX(1)}50.286%{opacity:1;transform:translate(-155.3px,-94.3px) scaleX(1)}50.476%{opacity:1;transform:translate(-155.3px,-94.3px) scaleX(-1)}53.81%{opacity:1;transform:translate(0px,0px) scaleX(-1)}54.095%{opacity:0;transform:translate(0px,0px) scaleX(-1)}100%{opacity:0;transform:translate(0px,0px) scaleX(1)}}
.jHug{animation:jHug 105s linear infinite;transform-origin:40px 160px;opacity:0}
@keyframes bJ3{0%{opacity:0}47.095%{opacity:0}47.143%{opacity:1}48.571%{opacity:1}48.619%{opacity:0}100%{opacity:0}}
.bJ3{animation:bJ3 105s linear infinite;opacity:0}
@keyframes bW{0%{opacity:0}48.619%{opacity:0}48.667%{opacity:1}50.476%{opacity:1}50.524%{opacity:0}100%{opacity:0}}
.bW{animation:bW 105s linear infinite;opacity:0}
@keyframes hearts{0%{opacity:0}48.143%{opacity:0}48.19%{opacity:1}50.095%{opacity:1}50.143%{opacity:0}100%{opacity:0}}
.hearts{animation:hearts 105s linear infinite;opacity:0}
@keyframes jCouchGo{0%{opacity:0;transform:translate(0px,0px) scaleX(1)}58.286%{opacity:0;transform:translate(0px,0px) scaleX(1)}58.333%{opacity:1;transform:translate(0px,0px) scaleX(1)}60.476%{opacity:1;transform:translate(-143.4px,-55.2px) scaleX(1)}60.524%{opacity:0;transform:translate(-143.4px,-55.2px) scaleX(1)}100%{opacity:0;transform:translate(-143.4px,-55.2px) scaleX(1)}}
.jCouchGo{animation:jCouchGo 105s linear infinite;transform-origin:40px 160px;opacity:0}
@keyframes jCouch{0%{opacity:0}60.524%{opacity:0}60.571%{opacity:1}66.667%{opacity:1}66.714%{opacity:0}100%{opacity:0}}
.jCouch{animation:jCouch 105s linear infinite;opacity:0}
@keyframes jCouchBack{0%{opacity:0;transform:translate(0px,0px) scaleX(-1)}66.667%{opacity:0;transform:translate(0px,0px) scaleX(-1)}66.714%{opacity:1;transform:translate(0px,0px) scaleX(-1)}68.857%{opacity:1;transform:translate(143.4px,55.2px) scaleX(-1)}69.048%{opacity:0;transform:translate(143.4px,55.2px) scaleX(-1)}100%{opacity:0;transform:translate(143.4px,55.2px) scaleX(1)}}
.jCouchBack{animation:jCouchBack 105s linear infinite;transform-origin:40px 160px;opacity:0}
@keyframes bJ4{0%{opacity:0}61.857%{opacity:0}61.905%{opacity:1}65.238%{opacity:1}65.286%{opacity:0}100%{opacity:0}}
.bJ4{animation:bJ4 105s linear infinite;opacity:0}
@keyframes sonChess{0%{opacity:0;transform:translate(0px,0px) scaleX(1)}72.381%{opacity:0;transform:translate(0px,0px) scaleX(1)}72.429%{opacity:1;transform:translate(0px,0px) scaleX(1)}74.762%{opacity:1;transform:translate(-87.6px,50.5px) scaleX(1)}74.857%{opacity:1;transform:translate(-87.6px,50.5px) scaleX(-1)}77.143%{opacity:1;transform:translate(-17.9px,169px) scaleX(-1)}77.238%{opacity:1;transform:translate(-17.9px,169px) scaleX(1)}79.048%{opacity:1;transform:translate(-125.5px,226.5px) scaleX(1)}81.524%{opacity:1;transform:translate(-125.5px,226.5px) scaleX(1)}81.619%{opacity:1;transform:translate(-125.5px,226.5px) scaleX(-1)}82.857%{opacity:1;transform:translate(-17.9px,169px) scaleX(-1)}82.952%{opacity:1;transform:translate(-17.9px,169px) scaleX(1)}84.095%{opacity:1;transform:translate(-87.6px,50.5px) scaleX(1)}85.048%{opacity:1;transform:translate(0px,0px) scaleX(1)}85.238%{opacity:0;transform:translate(0px,0px) scaleX(1)}100%{opacity:0;transform:translate(0px,0px) scaleX(1)}}
.sonChess{animation:sonChess 105s linear infinite;transform-origin:40px 176px;opacity:0}
@keyframes jChess{0%{opacity:0;transform:translate(0px,0px) scaleX(1)}72.571%{opacity:0;transform:translate(0px,0px) scaleX(1)}72.619%{opacity:1;transform:translate(0px,0px) scaleX(1)}75.714%{opacity:1;transform:translate(-215.1px,-13.8px) scaleX(1)}81.524%{opacity:1;transform:translate(-215.1px,-13.8px) scaleX(1)}81.619%{opacity:1;transform:translate(-215.1px,-13.8px) scaleX(-1)}83.81%{opacity:1;transform:translate(0px,0px) scaleX(-1)}84%{opacity:0;transform:translate(0px,0px) scaleX(-1)}100%{opacity:0;transform:translate(0px,0px) scaleX(1)}}
.jChess{animation:jChess 105s linear infinite;transform-origin:40px 160px;opacity:0}
@keyframes bS2{0%{opacity:0}79.19%{opacity:0}79.238%{opacity:1}80.381%{opacity:1}80.429%{opacity:0}100%{opacity:0}}
.bS2{animation:bS2 105s linear infinite;opacity:0}
@keyframes bJ5{0%{opacity:0}80.429%{opacity:0}80.476%{opacity:1}81.524%{opacity:1}81.571%{opacity:0}100%{opacity:0}}
.bJ5{animation:bJ5 105s linear infinite;opacity:0}
@keyframes jKeyGo{0%{opacity:0;transform:translate(0px,0px) scaleX(1)}86.857%{opacity:0;transform:translate(0px,0px) scaleX(1)}86.905%{opacity:1;transform:translate(0px,0px) scaleX(1)}89.524%{opacity:1;transform:translate(-286.8px,128.8px) scaleX(1)}91.619%{opacity:1;transform:translate(-673.2px,2.3px) scaleX(1)}91.667%{opacity:0;transform:translate(-673.2px,2.3px) scaleX(1)}100%{opacity:0;transform:translate(-673.2px,2.3px) scaleX(1)}}
.jKeyGo{animation:jKeyGo 105s linear infinite;transform-origin:40px 160px;opacity:0}
@keyframes jKey{0%{opacity:0;transform:translate(0px,0px) scaleX(1)}91.619%{opacity:0;transform:translate(0px,0px) scaleX(1)}91.667%{opacity:1;transform:translate(0px,0px) scaleX(1)}95.714%{opacity:1;transform:translate(0px,0px) scaleX(1)}95.762%{opacity:0;transform:translate(0px,0px) scaleX(1)}100%{opacity:0;transform:translate(0px,0px) scaleX(1)}}
.jKey{animation:jKey 105s linear infinite;transform-origin:40px 160px;opacity:0}
@keyframes jKeyBack{0%{opacity:0;transform:translate(0px,0px) scaleX(-1)}95.714%{opacity:0;transform:translate(0px,0px) scaleX(-1)}95.762%{opacity:1;transform:translate(0px,0px) scaleX(-1)}97.714%{opacity:1;transform:translate(386.4px,126.5px) scaleX(-1)}99.429%{opacity:1;transform:translate(673.2px,-2.3px) scaleX(-1)}99.524%{opacity:0;transform:translate(673.2px,-2.3px) scaleX(-1)}100%{opacity:0;transform:translate(673.2px,-2.3px) scaleX(1)}}
.jKeyBack{animation:jKeyBack 105s linear infinite;transform-origin:40px 160px;opacity:0}
@keyframes n2{0%{opacity:0}91.952%{opacity:0}92%{opacity:1}95.524%{opacity:1}95.571%{opacity:0}100%{opacity:0}}
.n2{animation:n2 105s linear infinite;opacity:0}
@keyframes seated{0%{opacity:1}1.095%{opacity:1}1.143%{opacity:0}10.762%{opacity:0}10.81%{opacity:1}15.381%{opacity:1}15.429%{opacity:0}24.571%{opacity:0}24.619%{opacity:1}29.667%{opacity:1}29.714%{opacity:0}42.381%{opacity:0}42.429%{opacity:1}43.952%{opacity:1}44%{opacity:0}54.095%{opacity:0}54.143%{opacity:1}58.238%{opacity:1}58.286%{opacity:0}69.048%{opacity:0}69.095%{opacity:1}72.524%{opacity:1}72.571%{opacity:0}84%{opacity:0}84.048%{opacity:1}86.81%{opacity:1}86.857%{opacity:0}99.524%{opacity:0}99.571%{opacity:1}100%{opacity:1}}
.seated{animation:seated 105s linear infinite}
@keyframes gtr{0%{opacity:1}34.238%{opacity:1}34.286%{opacity:0}38.571%{opacity:0}38.619%{opacity:1}100%{opacity:1}}
.gtr{animation:gtr 105s linear infinite}
@keyframes notesUp{0%{transform:translateY(10px);opacity:0}30%{opacity:1}100%{transform:translateY(-30px);opacity:0}}
.notes{animation:notesUp 1.2s ease-out infinite}
.seatedOff{opacity:0}
@keyframes bwalk{0%{opacity:1;transform:translate(0,0)}96%{opacity:1;transform:translate(-298.8px,-200.1px)}100%{opacity:0;transform:translate(-298.8px,-200.1px)}}
.bWalk{animation:bwalk 2.2s linear 1 forwards}
@keyframes brun{0%,47%{opacity:0;transform:translate(0,0) scaleX(-1)}48%{opacity:1;transform:translate(0,0) scaleX(-1)}75%{opacity:1;transform:translate(141.5px,86.2px) scaleX(-1)}96%{opacity:1;transform:translate(229.1px,35.7px) scaleX(-1)}100%{opacity:0;transform:translate(229.1px,35.7px) scaleX(-1)}}
.bRun{opacity:0;animation:brun 4.6s linear 1 forwards;transform-origin:40px 160px}
@keyframes tilt{0%,100%{transform:rotate(0)}30%{transform:rotate(9deg)}60%{transform:rotate(-4deg)}80%{transform:rotate(2deg)}}
.tilt{transform-box:fill-box;transform-origin:50% 0;animation:tilt 1.6s ease-in-out 2.2s 2}
@keyframes gwalk{0%{opacity:1;transform:translate(0,0)}45%{opacity:1;transform:translate(-286.8px,128.8px)}97%{opacity:1;transform:translate(-617.5px,-29.9px)}100%{opacity:0;transform:translate(-617.5px,-29.9px)}}
.gWalk{animation:gwalk 3s linear 1 forwards}
@keyframes gshow{0%,97%{opacity:0}100%{opacity:1}}
.gPlay{opacity:0;animation:gshow 3s linear 1 forwards}
@keyframes ghide{0%,97%{opacity:1}100%{opacity:0}}
.gtrOff{animation:ghide 3s linear 1 forwards}
@keyframes pop{0%{transform:scale(.85);opacity:0}100%{transform:scale(1);opacity:1}}
.card{animation:pop .18s ease-out 1}
@keyframes ring{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.45;transform:scale(1.04)}}
.ring{animation:ring 1.1s ease-in-out infinite}
.hot{position:absolute;background:transparent;border:0;padding:0;cursor:pointer;border-radius:12px}
.lnk{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:11px 14px;border-radius:10px;border:2px solid #1d1b24;background:#ffd166;color:#1d1b24;font-weight:700;font-size:14px;text-decoration:none}
.lnk:hover{background:#ffc233;color:#1d1b24}

/* Click scenes: Joel walks over and uses the thing. Paths start at the desk (966.8, 434.4). */
@keyframes appear{to{opacity:1}}
@keyframes vanish{to{opacity:0}}
.show{opacity:0;animation:appear .12s linear 1 forwards}
.hide{animation:vanish .12s linear 1 forwards}
.blink{opacity:0;animation:appear .12s linear 1 forwards,vanish .12s linear 1 forwards}
@keyframes fwalk{0%{opacity:1;transform:translate(0,0)}96%{opacity:1;transform:translate(-278.8px,-202.4px)}100%{opacity:0;transform:translate(-278.8px,-202.4px)}}
.fWalk{animation:fwalk 2.2s linear 1 forwards}
@keyframes sipA{0%,40%{opacity:1}42%,88%{opacity:0}90%,100%{opacity:1}}
@keyframes sipB{0%,40%{opacity:0}42%,88%{opacity:1}90%,100%{opacity:0}}
.sipA{animation:sipA 2.4s linear 3.4s infinite}
.sipB{opacity:0;animation:sipB 2.4s linear 3.4s infinite}
@keyframes kwalk{0%{opacity:1;transform:translate(0,0)}45%{opacity:1;transform:translate(-286.8px,128.8px)}97%{opacity:1;transform:translate(-673.2px,2.3px)}100%{opacity:0;transform:translate(-673.2px,2.3px)}}
.kWalk{animation:kwalk 3s linear 1 forwards}
@keyframes bkwalk{0%{opacity:1;transform:translate(0,0)}45%{opacity:1;transform:translate(-286.8px,128.8px)}97%{opacity:1;transform:translate(-605.5px,-50.6px)}100%{opacity:0;transform:translate(-605.5px,-50.6px)}}
.bkWalk{animation:bkwalk 3s linear 1 forwards}
.bikeOff{animation:ghide 3s linear 1 forwards}
@keyframes ride{0%,50%{opacity:0;transform:translate(0,0) scaleX(-1)}50.5%{opacity:1;transform:translate(0,0) scaleX(-1)}94%{opacity:1;transform:translate(518.1px,-108.1px) scaleX(-1)}97%,100%{opacity:0;transform:translate(518.1px,-108.1px) scaleX(-1)}}
.ride{opacity:0;animation:ride 6s linear 1 forwards;transform-origin:40px 160px}
@keyframes spin{to{transform:rotate(-360deg)}}
.spin{transform-box:fill-box;transform-origin:center;animation:spin .5s linear infinite}
@keyframes cwalk{0%{opacity:1;transform:translate(0,0)}96%{opacity:1;transform:translate(-143.4px,-55.2px)}100%{opacity:0;transform:translate(-143.4px,-55.2px)}}
.cWalk{animation:cwalk 2s linear 1 forwards}
@keyframes dwalk{0%{opacity:1;transform:translate(0,0)}45%{opacity:1;transform:translate(-227px,131.1px)}97%{opacity:1;transform:translate(calc(var(--dx) - 469.2px),calc(var(--dy) + 30.8px))}100%{opacity:0;transform:translate(calc(var(--dx) - 469.2px),calc(var(--dy) + 30.8px))}}
.dWalk{animation:dwalk 3s linear 1 forwards}
.dog.held{animation-play-state:paused;visibility:hidden}
.happy .wag{animation-duration:.18s}
@keyframes pat{0%,100%{transform:rotate(0)}50%{transform:rotate(14deg)}}
.pat{transform-origin:16px 58px;animation:pat .5s ease-in-out infinite}
@keyframes chwalk{0%{opacity:1;transform:translate(0,0)}96%{opacity:1;transform:translate(-215.1px,-13.8px)}100%{opacity:0;transform:translate(-215.1px,-13.8px)}}
.chWalk{animation:chwalk 3.2s linear 1 forwards}
@keyframes sowalk{0%{opacity:1;transform:translate(0,0) scaleX(1)}35%{transform:translate(-87.6px,50.5px) scaleX(1)}36%{transform:translate(-87.6px,50.5px) scaleX(-1)}70%{transform:translate(-17.9px,169px) scaleX(-1)}71%{transform:translate(-17.9px,169px) scaleX(1)}97%{opacity:1;transform:translate(-125.5px,226.5px) scaleX(1)}100%{opacity:0;transform:translate(-125.5px,226.5px) scaleX(1)}}
.soWalk{animation:sowalk 7s linear 1 forwards;transform-origin:40px 176px}
@keyframes bdwalk{0%{opacity:1;transform:translate(0,0)}94%{opacity:1;transform:translate(-67.7px,-75.9px)}100%{opacity:0;transform:translate(-67.7px,-75.9px)}}
.bdWalk{animation:bdwalk 1.2s linear 1 forwards}
@keyframes swing{0%,100%{transform:rotate(50deg)}45%,60%{transform:rotate(-4deg)}}
.swing{transform-origin:16px 38px;animation:swing .6s ease-in infinite}
@keyframes spark{0%,44%{opacity:0}46%,62%{opacity:1}64%,100%{opacity:0}}
.spark{opacity:0;animation:spark .6s linear infinite}
@keyframes hiwalk{0%{opacity:1;transform:translate(0,0)}96%{opacity:1;transform:translate(-95.6px,-151.8px)}100%{opacity:0;transform:translate(-95.6px,-151.8px)}}
.hiWalk{animation:hiwalk 1.8s linear 1 forwards}
@keyframes wave{0%,100%{transform:rotate(-12deg)}50%{transform:rotate(14deg)}}
.waveArm{transform-origin:16px 36px;animation:wave .6s ease-in-out infinite}
.seatedOn .type{animation-duration:.12s}
@keyframes code{0%{transform:scaleX(0)}15%,100%{transform:scaleX(1)}}
.code{transform-box:fill-box;transform-origin:0 50%;transform:scaleX(0);animation:code 2.8s steps(6) infinite}

/* Clickable hints: halos flash in turn (delays set in garage.js) and light up on hover, with a name tip. */
@keyframes halo{0%,100%{opacity:0}5%{opacity:1}13%{opacity:1}20%{opacity:0}}
.halo{opacity:0;animation:halo 12.6s ease-in-out infinite}
.halo.on{animation:none;opacity:1}
.halo *{stroke-width:calc(var(--hw,12) * 1px)}
@keyframes intro{0%,100%{opacity:0}25%,70%{opacity:1}}
.intro .halo{animation:intro 3s ease-in-out 1 both !important}
.busy .halo:not(.on){animation:none;opacity:0}
@keyframes dogglow{0%,100%{filter:drop-shadow(0 0 0 rgba(255,209,102,0)) drop-shadow(0 0 0 rgba(255,209,102,0))}5%,13%{filter:drop-shadow(0 0 4px #ffd166) drop-shadow(0 0 4px #ffd166)}20%{filter:drop-shadow(0 0 0 rgba(255,209,102,0)) drop-shadow(0 0 0 rgba(255,209,102,0))}}
.intro .dog>svg{animation:dogglow 3s ease-in-out 1 both !important}
.dog>svg{animation:dogglow 12.6s ease-in-out 11.7s infinite}
.dog.on>svg{animation:none;filter:drop-shadow(0 0 3px #ffd166) drop-shadow(0 0 3px #ffd166)}
.busy .dog:not(.on)>svg{animation:none}
@keyframes tip{from{opacity:0;transform:translate(-50%,-90%) scale(.9)}to{opacity:1;transform:translate(-50%,-100%)}}
.tip{position:absolute;transform:translate(-50%,-100%);padding:7px 12px;border-radius:99px;background:#fffaf0;border:2px solid #1d1b24;box-shadow:3px 3px 0 #1d1b24;font-size:13px;font-weight:700;white-space:nowrap;pointer-events:none;z-index:4;animation:tip .14s ease-out}
.tip[hidden]{display:none}

/* Small screens (body.compact / body.portrait, set in fit()): room fills the width, header on top, cards as a sheet. */
.mhead{display:none}
.portrait .viewport{flex-direction:column}
.portrait .frame{margin:12px auto auto} /* room under the header, leaving the lower screen for the card */
.portrait .mhead{display:block;flex:none;padding:calc(16px + env(safe-area-inset-top)) 20px 4px;color:#fffaf0}
.mhead h1{margin:0;font-family:'Fraunces',serif;font-weight:900;font-size:34px;line-height:1}
.mhead p{margin:6px 0 0;font-size:14px;color:#d6e4dc}
.compact .title{display:none}
.compact .hot::before{content:"";position:absolute;inset:-14px} /* bigger tap targets */
.compact .hot[data-open=surf]::before,.compact .hot[data-open=snow]::before{inset:-3px} /* the two boards sit close together */
@keyframes sheet{from{transform:translateY(24px);opacity:0}to{transform:none;opacity:1}}
.compact .card{position:fixed;left:12px !important;right:12px;top:auto !important;bottom:calc(12px + env(safe-area-inset-bottom));width:auto;max-height:52vh;overflow-y:auto;z-index:20;animation:sheet .2s ease-out}
.compact:not(.portrait) .card{left:auto !important;top:12px !important;bottom:auto;width:min(340px,46vw);max-height:calc(100vh - 24px)}
.compact .card-title{font-size:24px}

/* Chess game (assets/js/chessgame.js) */
.lnk{font-family:inherit;cursor:pointer;text-align:left}
.lnk.alt{background:#fffaf0}
.lnk.alt:hover{background:#f2ead8}
.game{position:fixed;inset:0;z-index:50;display:flex;align-items:center;justify-content:center;padding:12px;background:rgba(29,27,36,.72);overflow:auto}
.game[hidden]{display:none}
.game-box{position:relative;width:min(560px,100%);box-sizing:border-box;padding:18px;border-radius:18px;background:#fffaf0;border:3px solid #1d1b24;box-shadow:6px 6px 0 #1d1b24;display:flex;flex-direction:column;gap:12px;animation:pop .18s ease-out 1;color:#1d1b24;font-family:'Instrument Sans',sans-serif}
.game-head{display:flex;justify-content:space-between;align-items:flex-start;gap:12px}
.game-warn{margin:0;padding:8px 12px;border-radius:10px;background:#ffd166;border:2px solid #1d1b24;font-size:13px;font-weight:700;line-height:1.35}
.game-main{display:flex;flex-direction:column;gap:12px}
.board{display:grid;grid-template-columns:repeat(8,1fr);width:100%;aspect-ratio:1;border:3px solid #1d1b24;border-radius:6px;overflow:hidden;touch-action:manipulation}
.board.over{opacity:.55;pointer-events:none}
.sq{position:relative;display:flex;align-items:center;justify-content:center;margin:0;padding:0;border:0;border-radius:0;cursor:pointer;font-size:clamp(22px,8.2vw,56px);line-height:1;-webkit-tap-highlight-color:transparent}
.sq.light{background:#f0e3c4}
.sq.dark{background:#b98e58}
.sq.last{background:#e6d36a}
.sq.sel{background:#8fd18a}
.sq.check{background:#ef7a6a}
.sq.dot::after{content:"";position:absolute;width:30%;height:30%;border-radius:50%;background:rgba(29,27,36,.35)}
.sq.cap::after{content:"";position:absolute;inset:6%;border-radius:50%;border:4px solid rgba(29,27,36,.4)}
.pc{pointer-events:none;font-family:'Segoe UI Symbol','Apple Symbols','DejaVu Sans',sans-serif}
.pc.w{color:#fffaf0;-webkit-text-stroke:1.5px #1d1b24;text-shadow:0 1px 0 #1d1b24}
.pc.b{color:#1d1b24}
.game-side{display:flex;align-items:center;justify-content:space-between;gap:12px}
.game-status{font-size:15px;font-weight:700;min-height:1.4em}
.game-quit{flex:none}
.game-result{position:absolute;inset:0;z-index:2;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;padding:24px;text-align:center;border-radius:15px;background:#fffaf0}
.game-result[hidden]{display:none}
.result-title{font-family:'Fraunces',serif;font-weight:900;font-size:36px;line-height:1.05}
.game-result p{margin:0;font-size:16px;font-weight:500;line-height:1.4;max-width:30ch}
.game-result.won .result-title{color:#2f6f4a}
.result-actions{display:flex;gap:10px;flex-wrap:wrap;justify-content:center}
.game button:focus-visible{outline:3px solid #ffd166;outline-offset:3px}
.playing{overflow:hidden}
@media (orientation:landscape) and (max-height:560px){
  .game-box{width:min(920px,100%);flex-direction:row;flex-wrap:wrap;align-items:flex-start;gap:8px 16px;padding:12px}
  .game-head{flex:1 1 100%}
  .game-warn{flex:1 1 100%;padding:5px 10px}
  .game-main{flex-direction:row;flex:1 1 100%;align-items:flex-start}
  .board{width:min(calc(100vh - 150px),60vw);flex:none}
  .game-side{flex-direction:column;align-items:flex-start;flex:1}
  .game-head .card-close{width:36px;height:36px}
  .sq{font-size:clamp(16px,calc((100vh - 150px) / 8 * .75),44px)}
}

/* Shred Free (assets/js/skigame.js) */
.ski{position:fixed;inset:0;z-index:60;background:#f7f9fb;overflow:hidden;outline:none;touch-action:none;-webkit-user-select:none;user-select:none;font-family:'Instrument Sans',sans-serif;color:#1d1b24}
.ski[hidden]{display:none}
.ski canvas{position:absolute;inset:0;width:100%;height:100%;touch-action:none}
.ski-hud{position:absolute;left:calc(12px + env(safe-area-inset-left));top:calc(12px + env(safe-area-inset-top));display:flex;gap:6px;flex-wrap:wrap;pointer-events:none}
.ski-hud span{padding:6px 10px;border-radius:99px;background:#fffaf0;border:2px solid #1d1b24;box-shadow:2px 2px 0 #1d1b24;font-size:13px;font-weight:700;font-variant-numeric:tabular-nums}
.ski-top{position:absolute;right:calc(12px + env(safe-area-inset-right));top:calc(12px + env(safe-area-inset-top));display:flex;gap:8px}
.ski-touch{position:absolute;left:0;right:0;bottom:calc(16px + env(safe-area-inset-bottom));display:none;justify-content:space-between;padding:0 16px;pointer-events:none}
.ski-pad{pointer-events:auto;width:84px;height:84px;border-radius:50%;border:3px solid #1d1b24;background:#ffd166;box-shadow:3px 3px 0 #1d1b24;font:700 15px 'Instrument Sans',sans-serif;color:#1d1b24;touch-action:none}
.ski-pad:active{transform:translate(2px,2px);box-shadow:1px 1px 0 #1d1b24}
#ski-turbo{background:#7fd1c7}
@media (pointer:coarse){.ski-touch{display:flex}}
.ski-panel{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;padding:16px;background:rgba(29,27,36,.45)}
.ski-panel[hidden]{display:none}
.ski-card{width:min(440px,100%);box-sizing:border-box;padding:22px;border-radius:18px;background:#fffaf0;border:3px solid #1d1b24;box-shadow:6px 6px 0 #1d1b24;display:flex;flex-direction:column;gap:10px;text-align:center;animation:pop .18s ease-out 1}
.ski-card p{margin:0;font-size:15px;line-height:1.45}
.ski-keys{margin:0;padding:10px 12px;list-style:none;border-radius:10px;background:#eef2f6;font-size:13px;line-height:1.7}
.ski-keys[hidden]{display:none}
.k-touch{display:none}
@media (pointer:coarse){.k-keys{display:none}.k-touch{display:list-item}}
.ski button:focus-visible{outline:3px solid #ffd166;outline-offset:3px}

/* Surf Mondo's (assets/js/surfgame.js) reuses the Shred Free overlay styles */
.surfgame{background:#2f6f8f}
.hearts-hud{color:#e4572e;letter-spacing:2px}
.surf-touch{justify-content:flex-end}
