/* Infinite Ascent site.
   No framework: every byte here is on the critical path.

   The look is the game's look, not a template's: everything is drawn with a fat black
   marker, nothing is blurred, shadows are hard offsets because that is how you shade a
   doodle, and cards sit at a slight angle like sketches taped to a page. If a rule here
   makes the site feel more like a product page and less like a notebook, delete it. */

:root{
  /* Committed to light. The game is a bright sky with no dark mode, and without this
     declaration Chrome's auto-dark inverts the whole page - cream paper goes olive, the
     sky goes teal, the gold button goes brown. Do not add a dark palette here; add it to
     the game first if it ever needs one. */
  color-scheme: light;

  /* pulled off the actual sprites, not a palette generator */
  --sky:#ade4f3; --sky-2:#8fd4ea; --sky-3:#cfeefa;
  --ink:#12212a; --ink-2:#3c5361; --ink-3:#6b8290;
  --paper:#ffffff; --card:#fff; --rule:#12212a;
  --red:#d8443c; --green:#8cc63f; --gold:#e0a92e; --blue:#3a7bbf; --pink:#ff5fa2;
  --accent:#3a7bbf; --accent-ink:#26608f; --play:#8cc63f;
  --max:1120px; --col:66ch;
  --shadow:4px 4px 0 var(--ink);
  --shadow-sm:3px 3px 0 var(--ink);
  --hand:"Fredoka","Baloo 2",Nunito,"Trebuchet MS","Segoe UI",system-ui,sans-serif;
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
  margin:0; color:var(--ink); background:var(--paper);
  font:16px/1.65 "Trebuchet MS","Segoe UI",system-ui,-apple-system,sans-serif;
  -webkit-font-smoothing:antialiased;
}
/* faint sketchbook dot grid, drawn not downloaded */
body::before{
  content:""; position:fixed; inset:0; z-index:-1; pointer-events:none;
  background:radial-gradient(var(--ink-3) 1px, transparent 1px) 0 0/23px 23px;
  opacity:.13;
}

h1,h2,h3{font-family:var(--hand); line-height:1.1; margin:0 0 .4em; text-wrap:balance;
         letter-spacing:-.01em; font-weight:700}
h1{font-size:clamp(34px,6vw,58px)}
h2{font-size:clamp(23px,3.2vw,32px); margin-top:1.8em; position:relative; display:inline-block}
/* hand-drawn marker underline: one squiggle, no image request */
h2::after{
  content:""; display:block; height:7px; margin-top:1px;
  background:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='120' height='7' viewBox='0 0 120 7'><path d='M2 5C22 1 38 6 58 3s40 4 60 0' fill='none' stroke='%23e0a92e' stroke-width='5' stroke-linecap='round'/></svg>") repeat-x left bottom;
  background-size:auto 7px;
}
h3{font-size:19px}
p{margin:0 0 1.05em}
a{color:var(--accent-ink); text-underline-offset:3px; text-decoration-thickness:2px}
kbd{font:700 13px/1 var(--hand),ui-monospace,monospace; background:var(--card);
    border:2px solid var(--ink); border-radius:6px; padding:3px 7px;
    box-shadow:2px 2px 0 var(--ink); display:inline-block; margin:0 1px; color:var(--ink)}

.skip{position:absolute; left:-999px}
.skip:focus{left:12px; top:12px; background:var(--card); padding:10px 14px; z-index:99;
            border:3px solid var(--ink); border-radius:10px}

/* ---------------------------------------------------------------- chrome */
.top{
  max-width:var(--max); margin:0 auto; padding:16px 20px;
  display:flex; align-items:center; justify-content:space-between; gap:16px; flex-wrap:wrap;
}
.brand{display:flex; align-items:center; gap:10px; font-family:var(--hand); font-weight:700;
       font-size:21px; color:var(--ink); text-decoration:none}
.brand:hover .mark{transform:rotate(-8deg) scale(1.08)}
.mark{width:34px; height:34px; border:2.5px solid var(--ink); border-radius:9px;
      box-shadow:var(--shadow-sm); transition:transform .15s ease}
.top nav{display:flex; gap:6px; flex-wrap:wrap; font-family:var(--hand); font-size:15px;
         font-weight:600}
.top nav a{color:var(--ink); text-decoration:none; padding:5px 11px; border-radius:9px;
           border:2px solid transparent}
.top nav a:hover{border-color:var(--ink); background:var(--sky-3)}
.top nav a[aria-current]{border-color:var(--ink); background:var(--sky);
                         box-shadow:2px 2px 0 var(--ink)}

/* ---------------------------------------------------------------- layout */
.col,.narrow{max-width:var(--col); margin-inline:auto; padding-inline:20px}
.narrow{text-align:center; padding-top:26px}
.dek{font-size:18.5px; color:var(--ink-2); max-width:58ch; margin-inline:auto}

.hero{
  max-width:var(--max); margin:8px auto 30px; padding:30px 22px; position:relative;
  overflow:hidden; background:linear-gradient(var(--sky) 0%, var(--sky-3) 100%);
  border:3px solid var(--ink); border-radius:22px; box-shadow:6px 6px 0 var(--ink);
  display:grid; gap:26px; grid-template-columns:1fr; justify-items:center; text-align:center;
}
@media (min-width:880px){
  .hero{grid-template-columns:1fr 300px; align-items:center; text-align:left;
        justify-items:start; padding:34px 34px 34px 38px; gap:38px}
  .hero .stores{justify-content:flex-start}
  .hero .dek{margin-inline:0}
}
/* doodle clouds, same fat outline as every sprite. One path, no image request. */
.hero::before,.hero::after{
  content:""; position:absolute; pointer-events:none; background-repeat:no-repeat;
  background-size:100% 100%;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 124 58'><path d='M26 54h72c13 0 20-8 20-17 0-10-8-17-18-17-3-11-13-18-24-18-9 0-17 4-22 12-3-2-7-3-11-3-10 0-18 7-19 17-9 1-16 9-16 17 0 5 4 9 9 9z' fill='white' stroke='%2312212a' stroke-width='4.5' stroke-linejoin='round'/></svg>");
}
.hero::before{width:112px; height:52px; left:18px; top:16px; transform:rotate(-3deg)}
.hero::after{width:84px; height:39px; right:330px; bottom:22px; transform:rotate(4deg)}
@media (max-width:980px){ .hero::before,.hero::after{display:none} }

.hero-copy{position:relative; max-width:52ch}
.or{font-family:var(--hand); font-weight:600; font-size:15.5px; color:#1d5063;
    margin:14px 0 0}
@media (max-width:879px){ .or{display:none} }
.hero h1{color:var(--ink); margin-bottom:.25em}
.hero .dek{color:#173f4d; font-size:17.5px}

/* the card is the button: the whole thing is the click target */
.hero-card{position:relative; display:block; width:min(300px,82vw); flex:none;
           border:4px solid var(--ink); border-radius:18px; overflow:hidden;
           box-shadow:6px 6px 0 var(--ink); background:#c9eefb; text-decoration:none;
           transition:transform .1s ease, box-shadow .1s ease}
.hero-card img{display:block; width:100%; height:auto}
.hero-card-cta{position:absolute; left:50%; bottom:16px; transform:translateX(-50%);
               font-family:var(--hand); font-weight:700; font-size:19px; color:var(--ink);
               background:#9db4f0; border:4px solid var(--ink); border-radius:14px;
               padding:10px 26px; box-shadow:4px 4px 0 var(--ink); white-space:nowrap}
.hero-card:hover{transform:translate(-2px,-2px); box-shadow:8px 8px 0 var(--ink)}
.hero-card:active{transform:translate(2px,2px); box-shadow:2px 2px 0 var(--ink)}

.sky-art{position:absolute; pointer-events:none; user-select:none}
.sky-art.chaser{width:58px; height:58px; left:24px; bottom:18px; transform:rotate(-7deg)}
@media (max-width:980px){ .sky-art{display:none} }

/* ---------------------------------------------------------------- buttons */
.stores{display:flex; gap:14px; justify-content:center; flex-wrap:wrap; margin:22px 0 6px}
.stores.small{margin:14px 0 0; justify-content:flex-start}
.btn{
  display:inline-flex; align-items:center; gap:9px;
  font-family:var(--hand); font-weight:700; font-size:16px; text-decoration:none;
  color:var(--ink); background:var(--card);
  border:3px solid var(--ink); border-radius:13px; padding:12px 20px;
  box-shadow:var(--shadow); transition:transform .08s ease, box-shadow .08s ease;
}
.btn.ios{background:var(--sky)}
.btn.play{background:var(--green)}
/* the shape and colour of the restart button in-game, not a web call-to-action */
.btn.go{background:#9db4f0; font-size:21px; padding:15px 36px; border-width:4px;
        border-radius:15px; box-shadow:5px 5px 0 var(--ink)}
.stores.small .btn{padding:9px 14px; font-size:14px; box-shadow:var(--shadow-sm)}
.btn:hover{transform:translate(-1px,-1px); box-shadow:5px 5px 0 var(--ink)}
.btn:active{transform:translate(3px,3px); box-shadow:1px 1px 0 var(--ink)}
.btn img{width:22px; height:22px; border:0; border-radius:0; padding:0; background:none;
         box-shadow:none; flex:none}

/* ---------------------------------------------------------------- the game */
.game{position:relative; max-width:430px; margin:0 auto 14px; aspect-ratio:9/16;
      border:4px solid var(--ink); border-radius:20px; overflow:hidden; background:var(--sky);
      box-shadow:7px 7px 0 var(--ink)}
.game iframe{width:100%; height:100%; border:0; display:block}

/* The poster is the opening card the game itself shows, straight out of the build. */
.poster{position:absolute; inset:0; background:#c9eefb; overflow:hidden}
.card-art{position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
          object-position:top center; display:block}
/* the button always lands on a clean field, whatever the card crop puts behind it */
.poster-in{position:absolute; left:0; right:0; bottom:0; padding:14% 8% 6%;
           display:flex; flex-direction:column; align-items:center; text-align:center;
           background:linear-gradient(rgba(201,238,251,0) 0%, rgba(208,240,252,.82) 42%,
                                      rgba(212,241,252,.96) 100%)}
.poster .hint{font-size:14px; color:#15414f; margin:11px 0 0; font-weight:600;
              text-shadow:0 1px 0 rgba(255,255,255,.75)}

.game{container-type:inline-size}

/* ---------------------------------------------------------------- art */
/* Every sprite is a flat fill inside a fat black outline, so it vanishes on a dark card.
   They all sit on a fixed light sky plate - the background they have in the game. */
.ico,.pad img,.controls img,.inline-art{
  background:linear-gradient(var(--sky-3),#f2fbfe); border:2.5px solid var(--ink);
  border-radius:12px; padding:5px; object-fit:contain; box-shadow:var(--shadow-sm);
}
.ico{width:46px; height:46px; flex:none}
.ico.sm{width:28px; height:28px; padding:3px; border-width:2px; border-radius:8px;
        box-shadow:2px 2px 0 var(--ink)}
.inline-art{float:right; width:96px; height:96px; margin:4px 0 12px 18px; transform:rotate(4deg)}

.pads{display:grid; gap:18px; margin:22px 0 8px;
      grid-template-columns:repeat(auto-fit,minmax(230px,1fr))}
.pad{margin:0; background:var(--card); border:3px solid var(--ink); border-radius:14px;
     padding:15px 17px; display:grid; gap:11px; justify-items:start; box-shadow:var(--shadow)}
.pad:nth-child(odd){transform:rotate(-.8deg)}
.pad:nth-child(even){transform:rotate(.7deg)}
.pad img{width:138px; height:56px}
.pad figcaption{font-size:14.5px; color:var(--ink-2)}
.pad b{font-family:var(--hand); font-size:17px; color:var(--ink); display:block}

.controls{display:flex; gap:18px; align-items:center; margin:22px 0;
          background:var(--card); border:3px solid var(--ink); border-radius:14px;
          padding:17px; box-shadow:var(--shadow)}
.controls img{width:88px; height:88px; flex:none}
.controls p{margin:0 0 .5em; font-size:15.5px; color:var(--ink-2)}
.controls p:last-child{margin-bottom:0}

/* ---------------------------------------------------------------- zones */
.zlist{list-style:none; padding:0; margin:20px 0 8px; display:grid; gap:10px}
.zlist li{display:flex; gap:11px; align-items:baseline; color:var(--ink-2)}
.zlist b{color:var(--ink)}
.dot{width:15px; height:15px; border-radius:50%; background:var(--c,#ccc);
     border:2.5px solid var(--ink); flex:none; box-shadow:2px 2px 0 var(--ink)}
.zones{display:grid; gap:18px; margin:24px 0}
.zone{background:var(--card); border:3px solid var(--ink); border-radius:14px;
      padding:17px 20px; box-shadow:var(--shadow)}
.zone:nth-child(odd){transform:rotate(-.5deg)}
.zone:nth-child(even){transform:rotate(.45deg)}
.zone h2{margin:0 0 .3em; font-size:21px; display:flex; align-items:center; gap:11px}
.zone h2::after{display:none}
.zone p{margin:0; color:var(--ink-2); font-size:15.5px}

/* ---------------------------------------------------------------- tables */
.tbl{overflow-x:auto; border:3px solid var(--ink); border-radius:14px; background:var(--card);
     margin:22px 0; box-shadow:var(--shadow)}
table{border-collapse:collapse; width:100%; font-size:15.5px; min-width:460px}
th,td{text-align:left; padding:13px 16px; border-bottom:2px solid var(--sky-3);
      vertical-align:middle}
tbody tr:last-child th,tbody tr:last-child td{border-bottom:0}
thead th{background:var(--sky); font-family:var(--hand); font-size:14px; letter-spacing:.03em;
         text-transform:uppercase; border-bottom:3px solid var(--ink)}
tbody th{font-family:var(--hand); font-size:17px; font-weight:700; white-space:nowrap; width:1%;
         display:flex; align-items:center; gap:12px}
td{color:var(--ink-2)}

/* ---------------------------------------------------------------- faq */
.faq details{border:3px solid var(--ink); border-radius:13px; padding:13px 17px;
             margin-bottom:11px; background:var(--card); box-shadow:var(--shadow-sm)}
.faq summary{cursor:pointer; font-family:var(--hand); font-size:17.5px; font-weight:600}
.faq summary::marker{color:var(--gold)}
.faq details[open]{background:var(--sky-3)}
.faq p{margin:.75em 0 0; color:var(--ink-2)}

/* ---------------------------------------------------------------- boards */
/* Three across, stated outright. auto-fit inside the 66ch reading column lands on 2+1
   at desktop widths, and a lone third card under two others reads as a bug. */
.boards{display:grid; gap:14px; grid-template-columns:repeat(3,1fr); margin:22px 0}
@media (max-width:620px){ .boards{grid-template-columns:1fr} }
.board{background:var(--card); border:3px solid var(--ink); border-radius:14px;
       padding:15px 19px; box-shadow:var(--shadow)}
.board:nth-child(1){transform:rotate(-.9deg)}
.board:nth-child(3){transform:rotate(.8deg)}
.board h2{margin:0 0 .5em; font-size:19px; display:flex; align-items:center; gap:10px}
.board h2::after{display:none}
.board ol{margin:0; padding-left:1.35em; font-size:15.5px; color:var(--ink-2)}
.board li{padding:3px 0}
.board li::marker{font-family:var(--hand); font-weight:700; color:var(--ink)}
.board li b{color:var(--ink)}
.board li{display:flex; justify-content:space-between; gap:12px; align-items:baseline}
.board .sc{font-family:var(--hand); font-weight:700; color:var(--ink)}
.board .ph{display:list-item; list-style:none; margin-left:-1.35em; color:var(--ink-3);
           font-size:14.5px; line-height:1.5}

/* ---------------------------------------------------------------- ad rails */
.rail{display:none}
@media (min-width:1400px){
  .rail{display:block; position:fixed; top:96px; width:160px; min-height:600px}
  .rail-l{left:max(12px,calc(50vw - 720px))}
  .rail-r{right:max(12px,calc(50vw - 720px))}
}

/* ---------------------------------------------------------------- footer */
.foot{margin-top:52px; border-top:4px solid var(--ink); background:var(--sky-3)}
.cols{max-width:var(--max); margin:0 auto; padding:30px 20px 8px; display:grid; gap:26px;
      grid-template-columns:repeat(auto-fit,minmax(215px,1fr))}
.cols strong{display:block; margin-bottom:10px; font-family:var(--hand); font-size:17px}
.cols a{display:block; color:var(--ink-2); text-decoration:none; padding:3px 0}
.cols a:hover{color:var(--accent-ink); text-decoration:underline}
.cols p{color:var(--ink-2); font-size:14.5px}
.fine{max-width:var(--max); margin:0 auto; padding:12px 20px 28px; color:var(--ink-3);
      font-size:13px}

@media (max-width:560px){
  .controls{flex-direction:column; align-items:flex-start}
  .inline-art{width:70px; height:70px; margin-left:14px}
  .hero{border-radius:18px; box-shadow:5px 5px 0 var(--ink)}
}
@media (prefers-reduced-motion:reduce){
  *{transition:none !important; animation:none !important}
  .pad,.zone,.board,.poster-icon,.inline-art{transform:none !important}
}

/* ---------------------------------------------------------------- the chase
   Somebody's climber bounding across the foot of the page with Jerry after them, in two skins
   picked at random per visit from the shop's own art. Background decoration: never interactive,
   never over the copy, and built by site.js after load so the first paint pays nothing for it.

   Only transforms and opacity animate, so it composites on the GPU and never reflows. The outer
   element carries the crossing and the inner one the hop; stacking them that way is what lets a
   steady run hold a bouncing arc without the two fighting each other. */
.chase{position:fixed; left:0; right:0; bottom:clamp(6px,3vh,40px); height:150px;
       z-index:-1; pointer-events:none; overflow:hidden; opacity:.55}
.chase .lane{position:absolute; bottom:0; left:0; width:96px; height:110px;
             animation:chase-cross var(--cross,17s) linear var(--delay,0s) both}
.chase .lane.jerry{--delay:.5s; opacity:.92}
.chase .bob{position:absolute; bottom:0; width:100%; height:100%;
            animation:chase-hop var(--hop,.78s) cubic-bezier(.3,0,.5,1) infinite}
.chase .lane.jerry .bob{animation-name:chase-trudge; animation-duration:calc(var(--hop,.78s) * 1.15)}
.chase img{position:absolute; bottom:0; left:20px; width:56px; height:56px; display:block;
           transform:scaleX(var(--face,1))}
/* Speed streaks: three marker dashes that stretch and fade behind, drawn not downloaded. */
.chase i{position:absolute; left:0; height:3px; border-radius:3px; background:var(--ink-3);
         opacity:0; transform-origin:right center; animation:chase-dash .5s ease-out infinite}
.chase i:nth-child(1){bottom:34px; width:26px}
.chase i:nth-child(2){bottom:22px; width:18px; animation-delay:.12s}
.chase i:nth-child(3){bottom:46px; width:14px; animation-delay:.24s}
@keyframes chase-cross{
  from{transform:translateX(var(--from,-22vw))}
  to{transform:translateX(var(--to,122vw))}
}
@keyframes chase-hop{
  0%,100%{transform:translateY(0) scale(1,.94)}
  12%{transform:translateY(-6px) scale(.97,1.05)}
  50%{transform:translateY(-38px) scale(1.02,1.02)}
  88%{transform:translateY(-6px) scale(1.04,.96)}
}
@keyframes chase-trudge{
  0%,100%{transform:translateY(0) rotate(-3deg)}
  50%{transform:translateY(-14px) rotate(3deg)}
}
@keyframes chase-dash{
  0%{opacity:0; transform:scaleX(.2)}
  30%{opacity:.5; transform:scaleX(1)}
  100%{opacity:0; transform:scaleX(.1)}
}
/* No room for it beside the copy on a phone, and no reason to spend the frame budget there. */
@media (max-width:820px){ .chase{display:none} }
@media (prefers-reduced-motion:reduce){ .chase{display:none} }
