/* ballaliens.com, kewin's site */

/* the fonts live on this server, not google's: nothing extra to fetch before the first paint,
   and one less company in the privacy page. both are open source (ofl), latin only */
@font-face { font-family: "Archivo"; font-style: normal; font-weight: 100 900; font-stretch: 62% 125%; font-display: swap; src: url("/assets/fonts/archivo-latin.woff2") format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "DM Mono"; font-style: normal; font-weight: 400; font-display: swap; src: url("/assets/fonts/dm-mono-400-latin.woff2") format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "DM Mono"; font-style: normal; font-weight: 500; font-display: swap; src: url("/assets/fonts/dm-mono-500-latin.woff2") format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }

:root {
  --ink: #141414;
  --paper: #fffaf0;
  --cream: #f3eee2;
  --mute: #6d685d;
  --sel: #1d5fe0;
  --sky-top: #2a7de4;
  --sky-mid: #5badf6;
  --haze: #d3ebff;
  --hz: 63vh;
  --dock-h: 64px;
  --sans: "Archivo", system-ui, sans-serif;
  --mono: "DM Mono", ui-monospace, monospace;
  --spring: cubic-bezier(.34, 1.4, .64, 1);
  --out: cubic-bezier(.22, 1, .36, 1);
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }
html, body { height: 100%; margin: 0; }
body {
  overflow: hidden;
  background: var(--haze);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
}
a { color: inherit; }
button { font: inherit; color: inherit; }
img, svg, canvas { display: block; }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
:focus-visible { outline: 3px solid var(--sel); outline-offset: 3px; }

/* ---------- the world ---------- */
.sky {
  position: fixed; inset: 0;
  background: linear-gradient(var(--sky-top), var(--sky-mid) calc(var(--hz) * .62), var(--haze) var(--hz));
}
.clouds { position: absolute; inset: 0 0 calc(100vh - var(--hz) - 2vh) 0; overflow: hidden; }
.cloud {
  position: absolute; left: 0; top: var(--y);
  width: var(--w); opacity: var(--o, 1);
  animation: drift var(--d) linear infinite;
  animation-delay: var(--delay);
  will-change: transform;
}
@keyframes drift {
  from { transform: translateX(-110%); }
  to { transform: translateX(calc(100vw + 10%)); }
}
.ground { position: fixed; left: 0; right: 0; bottom: 0; top: var(--hz); width: 100%; height: calc(100% - var(--hz)); }

@keyframes blink { 50% { opacity: .35; } }

/* ---------- desktop ---------- */
.desk {
  position: fixed; inset: 0; z-index: 2;
  display: flex; flex-direction: column; align-items: center;
  padding-top: max(7vh, 40px);
  pointer-events: none;
}
.desk > * { pointer-events: auto; }

.mark {
  margin: 0; color: var(--ink);
  font-weight: 200; font-stretch: 125%;
  font-size: clamp(54px, 11.5vw, 168px); line-height: 1;
  letter-spacing: .12em; margin-right: -.12em;
  user-select: none;
}
.mark-l { display: inline-flex; }
.mark-l span {
  display: inline-block;
  font-variation-settings: "wght" var(--w, 200), "wdth" var(--x, 125);
  transform: translateY(var(--lift, 0));
  transition: font-variation-settings .5s var(--out), transform .5s var(--spring);
}
/* intro: letters stretch out, icons fall in */
.mark-l span { animation: letter-in 1s var(--spring) backwards; animation-delay: calc(var(--n) * 80ms + 150ms); }
.mark-l span:nth-child(2) { --n: 1; } .mark-l span:nth-child(3) { --n: 2; } .mark-l span:nth-child(4) { --n: 3; } .mark-l span:nth-child(5) { --n: 4; }
.mark-l span:nth-child(1) { --n: 0; }
@keyframes letter-in {
  from { opacity: 0; transform: translateY(46px); font-variation-settings: "wght" 900, "wdth" 62; }
}
.tag { animation: pop-in .6s var(--spring) .7s backwards; }
.icon:nth-child(1) { --i: 0; } .icon:nth-child(2) { --i: 1; } .icon:nth-child(3) { --i: 2; } .icon:nth-child(4) { --i: 3; } .icon:nth-child(5) { --i: 4; }
.icon .art { animation: drop .9s linear backwards; animation-delay: calc(var(--i) * 90ms + 350ms); }
.icon .label { animation: pop-in .5s var(--spring) backwards; animation-delay: calc(var(--i) * 90ms + 900ms); }
@keyframes drop {
  0% { transform: translateY(-75vh) rotate(-8deg); animation-timing-function: cubic-bezier(.55, 0, 1, .45); }
  55% { transform: translateY(0) scale(1.14, .82); animation-timing-function: cubic-bezier(0, .55, .45, 1); }
  72% { transform: translateY(-16px) scale(.95, 1.06); animation-timing-function: cubic-bezier(.55, 0, 1, .45); }
  86% { transform: translateY(0) scale(1.04, .95); }
  100% { transform: none; }
}
@keyframes pop-in { from { opacity: 0; transform: scale(.6); } }
.dock { animation: rise .7s var(--spring) 1.1s backwards; }
.credit { animation: pop-in .6s var(--spring) 1.4s backwards; }
@keyframes rise { from { transform: translateY(120px); } }

.tag {
  margin: 1.2vh 0 0; padding: 3px 10px;
  background: #fff; border: 2px solid var(--ink);
  font-size: 13px; font-weight: 500; letter-spacing: .02em;
}

.icons {
  display: flex; gap: clamp(18px, 3vw, 44px);
  margin-top: auto; margin-bottom: calc(100vh - var(--hz) + 3vh);
}
.icon {
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  width: 104px; text-decoration: none;
  animation: bob 4.2s ease-in-out infinite;
  animation-delay: calc(var(--i, 0) * -.8s);
}
.icon:focus-visible { outline: none; }
@keyframes bob { 50% { transform: translateY(-6px); } }
.art { width: 84px; height: 84px; transition: transform .45s var(--spring); }
.art svg { width: 100%; height: 100%; overflow: visible; }
.label {
  padding: 2px 8px;
  background: #fff; border: 2px solid var(--ink);
  font-size: 13px; font-weight: 500; white-space: nowrap;
  transition: background .15s, color .15s;
}
.icon:hover .art, .icon:focus-visible .art { transform: translateY(-6px) rotate(-4deg) scale(1.06); }
.icon:hover .label, .icon:focus-visible .label, .icon.on .label { background: var(--sel); color: #fff; }
.icon:active .art { transform: scale(.92, .86) translateY(4px); transition-duration: .1s; }

/* each icon has its own little hover move */
.art.art-cat { position: relative; width: 150px; height: 150px; margin-top: -66px; }
.art-cat canvas { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; transition: opacity .5s; touch-action: pan-y; }
.art-cat svg { position: absolute; left: 33px; top: 66px; width: 84px; height: 84px; transition: opacity .3s; }
.cat-ready .art-cat canvas { opacity: 1; }
.cat-ready .art-cat svg { opacity: 0; }
.icon:hover .art-cat, .icon:focus-visible .art-cat { transform: translateY(-4px); }
.reel, .paper, .play, .disc { transform-box: fill-box; transform-origin: center; }
.i-poly { filter: drop-shadow(0 3px 4px rgba(10, 60, 120, .18)); }
.icon:hover .i-tape .reel, .icon.on .i-tape .reel { animation: spin 1.1s linear infinite; }
.paper { transition: transform .4s var(--spring); }
.icon:hover .paper, .icon.on .paper { transform: translateY(-7px) rotate(-4deg); }
.icon:hover .play, .icon.on .play { animation: pulse .7s ease-in-out infinite alternate; }
.icon:hover .rec, .icon.on .rec { animation: blink .8s steps(2) infinite; }
.icon:hover .rec polygon, .icon.on .rec polygon { fill: #ff2a1a; stroke: #ff2a1a; }
/* the record slides out of its sleeve */
.disc { transition: transform .45s var(--spring); }
.icon:hover .disc, .icon.on .disc { transform: translateX(5px) rotate(30deg); }
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes pulse { to { transform: scale(1.18); } }

/* ---------- windows ---------- */
.win {
  position: fixed; z-index: 20;
  left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: min(540px, calc(100vw - 32px));
  max-height: min(78vh, 760px);
  display: none; flex-direction: column;
  background: var(--paper);
  border: 2px solid var(--ink); border-radius: 12px;
  box-shadow: 0 2px 0 var(--ink), 0 26px 50px -18px rgba(8, 40, 95, .55);
  transition: rotate .45s var(--spring);
}
.win:focus { outline: none; }
.win.drag { transition: rotate .08s linear; }
html:not(.js) .win:target, .win.open { display: flex; }
.js .win { transform: none; }
.win.wide { width: min(760px, calc(100vw - 32px)); }

.bar {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 8px 8px 14px;
  background: var(--bar, #4aa8ff); color: var(--bar-ink, var(--ink));
  border-bottom: 2px solid var(--ink); border-radius: 10px 10px 0 0;
  cursor: grab; touch-action: none; user-select: none;
}
.win.drag .bar { cursor: grabbing; }
.bar h2 { margin: 0; font-size: 14px; font-weight: 700; font-stretch: 110%; letter-spacing: .01em; }
.meta { font-family: var(--mono); font-size: 12px; opacity: .75; }
.x {
  margin-left: auto; width: 28px; height: 28px; flex: none;
  display: grid; place-items: center;
  background: #fff; color: var(--ink); border: 2px solid var(--ink); border-radius: 8px;
  font-size: 18px; line-height: 1; text-decoration: none;
  transition: transform .2s var(--spring), background .15s;
}
.x:hover { background: #ffe14d; transform: rotate(90deg); }

.body { overflow: auto; padding: 20px 22px 24px; overscroll-behavior: contain; }
.body > :first-child { margin-top: 0; }
.lede { margin: 0 0 4px; font-size: 22px; font-weight: 700; font-stretch: 112%; line-height: 1.15; }
.small { margin: 0 0 12px; color: var(--mute); font-size: 14px; }
.tiny { margin: 10px 0 0; color: var(--mute); font-size: 12px; }
.sub { margin: 22px 0 8px; font-family: var(--mono); font-size: 12px; font-weight: 500; text-transform: uppercase; letter-spacing: .08em; color: var(--mute); }

.btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 14px; border: 2px solid var(--ink); border-radius: 999px;
  background: var(--ink); color: #fff;
  font-size: 14px; font-weight: 600; text-decoration: none; cursor: pointer;
  transition: transform .2s var(--spring);
}
.btn:hover { transform: translateY(-2px) rotate(-1.5deg); }
.btn.ghost { background: #fff; color: var(--ink); }
.p-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 14px 0 0; }

/* about */
.big-mark { font-size: 54px; font-weight: 200; font-stretch: 125%; letter-spacing: .14em; line-height: 1; }
.about p { margin: 0 0 12px; }
.chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 4px 0 0; padding: 0; list-style: none; }
.chips li { padding: 2px 10px; border: 2px solid var(--ink); border-radius: 999px; font-size: 13px; font-weight: 500; background: #fff; }
.embed { border-radius: 12px; overflow: hidden; min-height: 152px; background: var(--cream); display: grid; place-items: center; }
.embed iframe { width: 100%; height: 152px; border: 0; display: block; }
.mail-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.mail-row .mail { font-size: 18px; font-weight: 600; text-underline-offset: 4px; }
.copy { padding: 3px 10px; border: 2px solid var(--ink); border-radius: 999px; background: #fff; font-size: 12px; font-weight: 600; cursor: pointer; }

/* tutorials */
.intro { margin-bottom: 16px; }
.files { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 18px 14px; margin: 0; padding: 0; list-style: none; }
.file { display: flex; flex-direction: column; gap: 6px; text-decoration: none; }
.thumb {
  width: 100%; aspect-ratio: 1; height: auto; object-fit: cover;
  border: 2px solid var(--ink); border-radius: 8px; background: var(--cream);
  transition: transform .35s var(--spring);
}
.file:hover .thumb, .file:focus-visible .thumb { transform: translateY(-4px) rotate(-1.5deg); }
.file:focus-visible { outline: none; }
.file:focus-visible .fname { background: var(--sel); color: #fff; }
.fname { align-self: flex-start; font-size: 13px; font-weight: 600; padding: 0 4px; margin-left: -4px; word-break: break-all; }
.file:hover .fname { background: var(--sel); color: #fff; }
.fmeta { font-family: var(--mono); font-size: 11.5px; color: var(--mute); margin-top: -4px; }

/* preview player */
.player { display: grid; grid-template-columns: minmax(0, 240px) 1fr; gap: 22px; align-items: start; }
.stage { position: relative; }
.big { width: 100%; height: auto; max-height: 58vh; object-fit: contain; background: #141414; border: 2px solid var(--ink); border-radius: 10px; }
.p-nav { display: flex; align-items: center; justify-content: space-between; margin: 10px 0 0; }
.count { font-family: var(--mono); font-size: 13px; }
.p-title { margin: 0 0 6px; font-size: 26px; font-weight: 700; font-stretch: 112%; line-height: 1.1; }
.p-meta { margin: 0 0 8px; font-family: var(--mono); font-size: 12px; color: var(--mute); }
.p-note { margin: 0; color: var(--mute); }
.p-sites { margin: 12px 0 0; padding: 0; list-style: none; display: flex; flex-direction: column; align-items: flex-start; gap: 7px; }
.p-sites li { padding: 4px 11px; background: #fff; border: 2px solid var(--ink); border-radius: 8px; font-family: var(--mono); font-size: 13.5px; }
.p-sites li:nth-child(2) { margin-left: 12px; } .p-sites li:nth-child(3) { margin-left: 4px; }
.nav-btn { width: 38px; height: 38px; border: 2px solid var(--ink); border-radius: 50%; background: #fff; font-size: 16px; cursor: pointer; transition: transform .2s var(--spring); }
.nav-btn:hover { transform: scale(1.1); }

/* edits */
.side-a { display: flex; align-items: center; gap: 16px; margin-bottom: 16px; }
.spin { width: 74px; height: 74px; flex: none; animation: spin 3.2s linear infinite; }
.tracks { margin: 0; padding: 0; list-style: none; border-top: 2px solid var(--ink); }
.tracks a {
  display: grid; grid-template-columns: 30px 1fr auto; gap: 12px; align-items: baseline;
  padding: 9px 4px; border-bottom: 1.5px dashed rgba(20, 20, 20, .25);
  text-decoration: none; transition: background .12s, padding .25s var(--out);
}
.tracks a:hover, .tracks a:focus-visible { background: var(--sel); color: #fff; padding-left: 10px; outline: none; }
.no { font-family: var(--mono); font-size: 12px; opacity: .6; }
.tt { font-weight: 600; }
.ar { font-family: var(--mono); font-size: 12.5px; opacity: .7; text-align: right; }

/* work */
.pieces { margin: 0; padding: 0; list-style: none; }
.pieces li { padding: 12px 0 14px; border-bottom: 1.5px dashed rgba(20, 20, 20, .25); }
.pieces li:first-child { padding-top: 0; }
.p-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; text-decoration: none; }
.p-no { font-family: var(--mono); font-size: 12px; opacity: .6; }
.p-name { font-size: 19px; font-weight: 700; font-stretch: 110%; }
.p-kind { color: var(--mute); font-size: 14px; }
.p-head:hover .p-name { background: var(--sel); color: #fff; }
.p-text { margin: 6px 0 0 32px; font-size: 13.5px; color: var(--mute); }
.credits { margin: 6px 0 0 32px; font-size: 13.5px; }
.credits div { display: flex; align-items: baseline; gap: 8px; }
.credits div::after { content: ""; order: 1; flex: 1; border-bottom: 2px dotted rgba(20, 20, 20, .3); transform: translateY(-4px); }
.credits dt { order: 0; color: var(--mute); }
.credits dd { order: 2; margin: 0; font-weight: 600; }
.p-reels { display: flex; gap: 12px; margin: 10px 0 0 32px; }
.p-reel { width: 120px; display: flex; flex-direction: column; gap: 6px; text-decoration: none; }
.p-reel img { width: 100%; height: auto; aspect-ratio: 4 / 5; object-fit: cover; border: 2px solid var(--ink); border-radius: 8px; transition: transform .35s var(--spring); }
.p-reel:hover img, .p-reel:focus-visible img { transform: translateY(-4px) rotate(-1.5deg); }
.p-reel span { align-self: flex-start; font-size: 13px; font-weight: 600; padding: 0 4px; margin-left: -4px; }
.p-reel:hover span, .p-reel:focus-visible span { background: var(--sel); color: #fff; }
.p-reel:focus-visible { outline: none; }
.p-media { margin: 10px 0 0 32px; max-width: 340px; }
.cta { margin-top: 20px; padding: 16px 18px; background: #fff; border: 2px solid var(--ink); border-radius: 10px; transform: rotate(-1deg); }

/* flykewin */
.yt-list { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin: 14px 0 6px; }
.yt { position: relative; padding: 0; border: 0; background: none; text-align: left; cursor: pointer; }
.yt img { width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover; border: 2px solid var(--ink); border-radius: 8px; transition: transform .35s var(--spring); }
.yt:hover img { transform: rotate(-1.5deg) translateY(-3px); }
.yt-play { position: absolute; left: 0; top: 0; width: 100%; aspect-ratio: 16 / 9; display: grid; place-items: center; pointer-events: none; }
.yt-play::before { content: ""; grid-area: 1 / 1; width: 48px; height: 48px; border-radius: 50%; background: #ff5a4a; border: 2px solid var(--ink); transition: transform .3s var(--spring); }
.yt-play::after { content: ""; grid-area: 1 / 1; margin-left: 4px; border: 9px solid transparent; border-left: 14px solid #fff; border-right: 0; }
.yt:hover .yt-play::before { transform: scale(1.15); }
.yt-t { display: block; margin-top: 8px; font-size: 13.5px; font-weight: 600; line-height: 1.3; }
.yt-t em { display: block; font-style: normal; font-family: var(--mono); font-weight: 400; font-size: 12px; color: var(--mute); }
.yt-frame { width: 100%; aspect-ratio: 16 / 9; border: 2px solid var(--ink); border-radius: 8px; display: block; }

/* ---------- dock ---------- */
.dock-wrap {
  position: fixed; left: 0; right: 0; bottom: max(18px, env(safe-area-inset-bottom));
  z-index: 15; display: flex; justify-content: center; pointer-events: none;
}
.dock {
  pointer-events: auto;
  display: flex; align-items: center; gap: 8px;
  padding: 7px; background: #fff;
  border: 2px solid var(--ink); border-radius: 14px;
  box-shadow: 0 14px 30px -14px rgba(10, 60, 20, .5);
}
.app {
  width: 44px; height: 44px; display: grid; place-items: center;
  border: 2px solid var(--ink); border-radius: 10px; padding: 0;
  cursor: pointer; transition: transform .3s var(--spring);
}
.app svg { width: 24px; height: 24px; }
.app:hover { transform: translateY(-6px) scale(1.12) rotate(-4deg); }
.app:active { transform: scale(.9); transition-duration: .08s; }
.ig { background: #e1306c; }
.yt-app { background: #f2271c; }
.sp { background: #1ed760; }
.ml { background: #4aa8ff; }
.sep { width: 2px; align-self: stretch; margin: 4px 2px; background: var(--ink); opacity: .15; border-radius: 2px; }
.clock { padding: 0 8px 0 4px; font-family: var(--mono); font-size: 13px; font-weight: 500; white-space: nowrap; }
/* the mute speaker by the clock */
.mute { width: 30px; height: 30px; flex: none; display: grid; place-items: center; padding: 0; border: 0; border-radius: 8px; background: none; color: var(--ink); cursor: pointer; transition: background .15s, transform .2s var(--spring); }
.mute svg { width: 18px; height: 18px; }
.mute:hover { background: rgba(20, 20, 20, .08); }
.mute:active { transform: scale(.88); transition-duration: .08s; }
.mute:focus-visible { outline: 2px solid var(--sel); outline-offset: 1px; }
.mute .off, .mute[aria-pressed="true"] .on { display: none; }
.mute[aria-pressed="true"] .off { display: inline; }
.mute[aria-pressed="true"] { color: var(--mute); }

/* credit to studio.tue, on its own little cloud */
.credit {
  position: fixed; z-index: 15; right: 14px; top: max(8px, env(safe-area-inset-top));
  width: 176px; height: 84px; color: var(--ink); text-decoration: none;
}
.cc-cloud { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; transition: transform .4s var(--spring); }
.cc-in { position: absolute; left: 50%; top: 56%; transform: translate(-50%, -50%); display: flex; align-items: center; gap: 7px; white-space: nowrap; opacity: .5; transition: opacity .25s; }
.credit:hover .cc-in, .credit:focus-visible .cc-in { opacity: 1; }
.cc-t { font-size: 13px; font-weight: 600; letter-spacing: .01em; }
.credit-logo { width: 28px; height: 28px; flex: none; transition: transform .25s ease; }
.credit:hover .credit-logo, .credit:focus-visible .credit-logo { transform: rotate(5deg) scale(1.1); }
.credit:hover .cc-cloud { transform: scale(1.04); }
.credit:focus-visible { outline: none; }
.credit:focus-visible .cc-cloud { filter: drop-shadow(0 0 2px var(--sel)) drop-shadow(0 0 2px var(--sel)); }

/* toast for the copy button */
.toast {
  position: fixed; left: 50%; bottom: calc(var(--dock-h) + 40px); z-index: 1001;
  padding: 6px 14px; background: var(--ink); color: #fff; border-radius: 999px;
  font-size: 13px; font-weight: 600;
  transform: translate(-50%, 20px); opacity: 0;
  transition: transform .35s var(--spring), opacity .2s;
  pointer-events: none;
}
.toast.show { transform: translate(-50%, 0); opacity: 1; }

/* ---------- phones ---------- */
@media (max-width: 760px) {
  :root { --hz: 66vh; }
  .desk { padding-top: max(9vh, 56px); }
  .mark { font-size: clamp(44px, 15vw, 90px); }
  .icons { flex-wrap: wrap; justify-content: center; max-width: 330px; gap: 14px 10px; margin-bottom: calc(100vh - var(--hz) + 2.5vh); }
  .icon { width: 92px; gap: 7px; }
  .art.art-cat { width: 116px; height: 116px; margin-top: -48px; }
  .art-cat svg { left: 24px; top: 48px; width: 68px; height: 68px; }
  .art { width: 68px; height: 68px; }
  .label { font-size: 12.5px; }

  .win, .win.wide {
    left: 10px !important; right: 10px; top: max(64px, calc(env(safe-area-inset-top) + 54px)) !important;
    width: auto; max-height: none;
    bottom: calc(var(--dock-h) + 30px + env(safe-area-inset-bottom));
  }
  .bar { cursor: default; }
  .body { padding: 16px 16px 22px; }
  .files { grid-template-columns: repeat(2, 1fr); gap: 16px 12px; }
  .player { grid-template-columns: 1fr; }
  .stage { max-width: 300px; margin: 0 auto; width: 100%; }
  .yt-list { grid-template-columns: 1fr; }
  .big-mark { font-size: 40px; }

  .dock { gap: 6px; padding: 6px; }
  .app { width: 40px; height: 40px; }
  .clock { display: none; }
  .credit { right: 4px; width: 150px; height: 72px; }
  .cc-t { font-size: 12px; }
}
@media (max-height: 620px) and (min-width: 761px) {
  .mark { font-size: clamp(44px, 9vw, 110px); }
  .art { width: 64px; height: 64px; }
  .art.art-cat { width: 121px; height: 121px; margin-top: -57px; }
  .art-cat svg { left: 28px; top: 57px; width: 64px; height: 64px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
  .cloud { animation: none; transform: translateX(var(--rest, 0)); }
}

/* dims the world behind a window on phones */
.scrim { position: fixed; inset: 0; z-index: 18; background: rgba(12, 45, 95, .28); opacity: 0; pointer-events: none; transition: opacity .25s; }
@media (max-width: 760px) { .has-win .scrim { opacity: 1; pointer-events: auto; } }

/* ---------- his face, first in the dock ---------- */
.me { background: #3a9bf0; overflow: hidden; }
.me img { width: 100%; height: 100%; object-fit: cover; border-radius: 8px; }

/* ---------- mp3 player ---------- */
/* kewin.wav mp3 player. width follows its container: about 210px on desktop, 156px on phones.
   give the parent container-type: inline-size if it should size off a window instead of the viewport */
.mp3 { position: relative; width: clamp(156px, 15cqw + 60px, 210px); aspect-ratio: 200 / 320; user-select: none; -webkit-user-select: none; }
.mp3 svg { display: block; width: 100%; height: 100%; overflow: visible; filter: drop-shadow(0 3px 4px rgba(10, 60, 120, .18)); }
.mp3 .play, .mp3 .pause, .mp3 .prev, .mp3 .next, .mp3 .menu { transition: transform .08s, filter .12s; transform-box: fill-box; transform-origin: center; }
.mp3.playing .play, .mp3:not(.playing) .pause { display: none; }
.mp3 .down { transform: translateY(.9px) scale(.94); filter: brightness(.88); }
.mp3 .hot { filter: brightness(1.12); }
.mp3 .hit { position: absolute; transform: translate(-50%, -50%); width: 21%; height: 15%; padding: 0; border: 0; border-radius: 50%; background: none; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.mp3 .hit:focus-visible { outline: 3px solid var(--sel, #2f7ff0); outline-offset: 1px; }
.mp3 .seek { position: absolute; margin: 0; opacity: 0; cursor: pointer; }
.mp3:has(.seek:focus-visible) .bar-track { stroke: #ffd84a; stroke-width: .8; }
.mp3-scr text { font-family: var(--sans, "Archivo", system-ui, sans-serif); fill: #f3eee2; }
.mp3-scr .t-title { font-size: 10.5px; font-weight: 700; }
.mp3-scr .t-artist { font-size: 7.5px; font-weight: 500; fill: #9fb6e6; }
.mp3-scr .t-small { font-size: 6.5px; font-weight: 500; fill: #c9d6f2; font-variant-numeric: tabular-nums; }
/* MENU at the bottom of the wheel */
.mp3 .t-menu { font-family: var(--sans, "Archivo", system-ui, sans-serif); font-size: 8.6px; font-weight: 800; letter-spacing: .14em; fill: #2a2420; }
.mp3 .menu-hit { width: 26%; height: 9%; border-radius: 40%; }
.mp3.listing .scr-now, .mp3:not(.listing) .scr-list, .mp3:not(.listing) .row-hit, .mp3.listing .seek, .mp3.listing .vol { display: none; }
.mp3-scr .t-row { font-size: 7.4px; font-weight: 600; fill: #c9d6f2; }
.mp3-scr .row-on .t-row { fill: #fff8ea; }
.mp3-scr .row-bar { fill: #ee4611; }
.mp3-scr .row-now { fill: #9fb6e6; }
.mp3-scr .row-on .row-now { fill: #fff8ea; }
.mp3 .row-hit { position: absolute; padding: 0; margin: 0; border: 0; background: none; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.mp3 .row-hit:focus-visible { outline: 2px solid #ffd84a; outline-offset: -1px; border-radius: 2px; }
/* volume */
.mp3-scr .art-edge { fill: none; stroke: rgba(243, 238, 226, .3); stroke-width: .6; }
.mp3-scr .vol-ico { fill: #9fb6e6; }
.mp3-scr .vol-track { fill: #3a4c86; }
.mp3-scr .vol-fill { fill: #9fb6e6; }
.mp3-scr .vol-knob { fill: #f3eee2; }
.mp3 .vol { position: absolute; margin: 0; opacity: 0; cursor: pointer; }
.mp3:has(.vol:focus-visible) .vol-track { stroke: #ffd84a; stroke-width: .8; }
.mp3.no-vol .vol-row, .mp3.no-vol .vol { display: none; }
.mp3-scr .t-title.scroll { animation: mp3-marquee var(--dur, 6s) ease-in-out 1s infinite alternate; }
@keyframes mp3-marquee { from { transform: translateX(0); } to { transform: translateX(var(--dx, 0)); } }
@media (prefers-reduced-motion: reduce) { .mp3-scr .t-title.scroll { animation: none; } .mp3 .down { transform: none; } }
/* the one floating in the sky */
.sky-player, .sky-player * { -webkit-user-select: none; user-select: none; }
html.player-held, html.player-held * { -webkit-user-select: none !important; user-select: none !important; }
.sky-player { display: none; position: fixed; z-index: 14; right: 34px; bottom: 28px; animation: bob 5s ease-in-out infinite; animation-delay: -1.3s; touch-action: none; -webkit-touch-callout: none; }
.sky-player.on { display: block; }
.sky-player .mp3 { transition: transform .25s var(--spring); animation: pop-in .6s var(--spring) 1.5s backwards; }
.sky-player.dragging { z-index: 17; animation-play-state: paused; cursor: grabbing; }
.sky-player.dragging .mp3 { transform: scale(1.05) rotate(-2deg); }
.sky-player.dragging .mp3 svg { filter: drop-shadow(0 12px 14px rgba(10, 60, 120, .25)); }
@media (max-width: 760px) {
  .sky-player { right: 10px; bottom: calc(var(--dock-h) + 34px + env(safe-area-inset-bottom)); }
  .sky-player .mp3 { width: 124px; }
}

/* ---------- /kewin: a page just for the alien ---------- */
body.page-kewin { overflow: auto; height: auto; min-height: 100%; }
.k-stage { position: relative; z-index: 2; min-height: 100vh; min-height: 100svh; display: grid; grid-template-columns: minmax(0, 1fr) min(600px, 46vw); align-items: start; align-content: center; gap: 28px; max-width: 1240px; margin: 0 auto; padding: 72px 32px calc(var(--dock-h) + 56px); }
.k-cat { position: relative; width: min(100%, 560px); aspect-ratio: 1; justify-self: center; }
.k-cat canvas { position: absolute; top: -45cqh; left: 0; width: 100%; height: calc(100% + 125cqh); opacity: 0; transition: opacity .6s; touch-action: pan-y; }
.cat-ready .k-cat canvas { opacity: 1; }
.k-side { display: grid; gap: 16px; align-content: start; padding-top: 64px; }
/* his speech bubble */
.k-card { position: relative; z-index: 2; margin-left: -56px; background: #fff; border: 2px solid var(--ink); border-radius: 28px; box-shadow: 0 2px 0 var(--ink), 0 26px 50px -18px rgba(8, 40, 95, .55); }
.k-card::before { content: ""; position: absolute; left: -15px; bottom: 34px; width: 26px; height: 26px; background: #fff; border: solid var(--ink); border-width: 0 0 2px 2px; border-bottom-left-radius: 5px; transform: rotate(45deg); }
.k-card .body { padding: 24px 22px 14px; }
/* his name tag, animal crossing style */
.k-card .ac-name { position: absolute; top: -15px; left: 22px; margin: 0; padding: 4px 14px 5px; border: 2px solid var(--ink); border-radius: 999px; background: #ee4611; color: #fff; font: 700 14px/1.1 var(--sans); font-stretch: 112%; transform: rotate(-3deg); box-shadow: 0 2px 0 rgba(0, 0, 0, .18); }
.k-card .say { margin: 0 0 8px; font: 600 18px/1.34 var(--sans); min-height: 2.68em; text-wrap: pretty; }
.k-card .small { margin: 0; color: var(--mute); font-size: 13px; }

/* ---------- /kewin: his closet ----------
   a round tab per slot, tiles for what goes there, colors for what's on, saved fits. 65% white with a blur, the
   speech bubble stays solid. the blue fades in on each tab's own layer (gradients can't transition), tiles and
   swatches slide in staggered on a tab change, and the panel eases to its new height (closet.js) */
.closet { --white: #fff; --line: #e3e0d6; --sel-soft: #e4eeff; --shadow: rgba(20, 20, 20, .14);
  position: relative; z-index: 2; display: flex; flex-direction: column; gap: 10px; min-height: 0; width: min(100%, 410px); justify-self: end; padding: 12px 14px 11px;
  background: rgba(255, 255, 255, .65); -webkit-backdrop-filter: blur(12px) saturate(1.3); backdrop-filter: blur(12px) saturate(1.3);
  border: 2px solid var(--ink); border-radius: 24px; box-shadow: 0 6px 0 var(--shadow); }
.closet.sizing { overflow: hidden; }
.closet.measuring, .closet.measuring * { transition: none !important; animation: none !important; }
.closet header { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.closet h2 { margin: 0; }
.closet .fold { display: inline-flex; align-items: center; gap: 7px; margin: -4px -8px; padding: 4px 8px; border: 0; border-radius: 999px; background: none; color: var(--ink); font: 800 18px/1 var(--sans); letter-spacing: -.01em; cursor: pointer; transition: background .15s; }
.closet .fold:hover { background: rgba(29, 95, 224, .08); }
.closet .chev { width: 14px; height: 14px; transition: transform .25s var(--spring); }
.closet.shut { width: auto; align-self: start; padding: 10px 16px; }
.closet.shut .chev { transform: rotate(-90deg); }
.closet.shut > :not(header), .closet.shut .tools { display: none !important; }
.closet .tools { display: flex; gap: 8px; }
.closet .cpill { display: inline-flex; align-items: center; gap: 6px; padding: 6px; border: 2px solid var(--ink); border-radius: 999px; cursor: pointer; color: var(--ink); font: 600 13px/1 var(--sans);
  background: linear-gradient(rgba(255, 255, 255, .95), rgba(255, 255, 255, 0) 55%), linear-gradient(#fff, #dfeaf7); box-shadow: 0 2px 0 var(--shadow); transition: transform .15s var(--spring); }
.closet .cpill svg { width: 16px; height: 16px; }
.closet .cpill:hover { transform: translateY(-1px); }
.closet .cpill:active { transform: translateY(1px); box-shadow: none; }
.closet .tabs, .closet .items, .closet .swatches { display: flex; flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
.closet .tabs::-webkit-scrollbar, .closet .items::-webkit-scrollbar, .closet .swatches::-webkit-scrollbar { display: none; }
.closet .cpill span { display: none; }
.closet .tabs { gap: 5px; padding: 2px 2px 3px; }
.closet .tab { flex: 0 1 36px; display: flex; flex-direction: column; align-items: center; gap: 5px; min-width: 30px; padding: 0; border: 0; background: none; cursor: pointer; color: var(--mute); font: 500 10.5px/1 var(--mono); transition: color .25s var(--out); }
.closet .orb { position: relative; isolation: isolate; display: grid; place-items: center; width: 100%; aspect-ratio: 1; border: 2px solid var(--ink); border-radius: 50%; color: var(--ink);
  background: linear-gradient(rgba(255, 255, 255, .9), rgba(255, 255, 255, 0) 50%), radial-gradient(circle at 50% 75%, #cfe0f3, #f4f8fd 70%); box-shadow: 0 2px 0 var(--shadow);
  transition: transform .3s var(--spring), color .25s var(--out); }
.closet .orb::before { content: ""; position: absolute; inset: 0; z-index: -1; border-radius: 50%; opacity: 0; transition: opacity .25s var(--out);
  background: linear-gradient(rgba(255, 255, 255, .55), rgba(255, 255, 255, 0) 50%), radial-gradient(circle at 50% 80%, #6aa2ff, #1d5fe0 70%); }
.closet .tab svg { width: 18px; height: 18px; }
.closet .tab:hover .orb { transform: translateY(-2px); }
.closet .tab[aria-selected="true"] { color: var(--ink); }
.closet .tab[aria-selected="true"] .orb { color: var(--white); transform: scale(1.06); }
.closet .tab[aria-selected="true"] .orb::before { opacity: 1; }
.closet .worn { position: absolute; right: -4px; bottom: -3px; width: 13px; height: 13px; border: 2px solid var(--ink); border-radius: 50%; background: var(--c); transition: background .25s var(--out), transform .3s var(--spring); }
.closet .worn[hidden] { display: block !important; transform: scale(0); }
.closet .items { gap: 7px; margin-top: -6px; padding: 9px 9px 4px 2px; }
.closet .tile { position: relative; flex: none; width: 72px; display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 8px 4px 7px; border: 2px solid var(--ink); border-radius: 14px; cursor: pointer; color: var(--ink); font: 600 12px/1.1 var(--sans);
  background: linear-gradient(rgba(255, 255, 255, .85), rgba(241, 245, 250, .75)); box-shadow: 0 3px 0 var(--shadow); }
.closet .tile svg { width: 22px; height: 22px; }
.closet .tile:hover, .closet .sw:hover { transform: translateY(-2px); }
.closet .tile[aria-checked="true"] { border-color: var(--sel); color: var(--sel); background: linear-gradient(#f2f7ff, var(--sel-soft)); box-shadow: 0 0 0 3px rgba(29, 95, 224, .16), 0 3px 0 var(--shadow); }
.closet .tile[aria-checked="true"]::after { content: ""; position: absolute; top: -8px; right: -8px; width: 22px; height: 22px; border: 2px solid var(--white); border-radius: 50%;
  background: var(--sel) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7.5'/%3E%3C/svg%3E") center / 12px no-repeat; }
.closet .tile[role="switch"][aria-checked="false"] { color: var(--mute); }
.closet .chip { width: 26px; height: 7px; border: 1.5px solid var(--ink); border-radius: 4px; background: var(--c); }
.closet .tile, .closet .sw { transition: transform .15s var(--spring), background .25s var(--out), border-color .25s var(--out), color .25s var(--out), box-shadow .25s var(--out); }
.closet .in { animation: closet-in .38s var(--out) both; animation-delay: calc(var(--i, 0) * 28ms); }
@keyframes closet-in { from { opacity: 0; transform: translateY(8px) scale(.96); } }
.closet .colors { display: flex; flex-direction: column; gap: 6px; min-height: 47px; transition: opacity .2s var(--out); }
.closet .colors.none { opacity: 0; visibility: hidden; transition: opacity .2s var(--out), visibility 0s .2s; }
.closet .colors .c-label { margin: 0; color: var(--mute); font: 500 12px/1 var(--mono); }
.closet .colors .c-label b { color: var(--ink); font: 700 13px/1 var(--sans); }
.closet .swatches { gap: 8px; margin: -6px; padding: 6px; }
.closet .sw { position: relative; flex: none; width: 28px; height: 28px; padding: 0; border: 2px solid var(--ink); border-radius: 50%; cursor: pointer; box-shadow: 0 2px 0 var(--shadow);
  background: radial-gradient(circle at 34% 28%, rgba(255, 255, 255, .95) 0 11%, rgba(255, 255, 255, 0) 30%), radial-gradient(circle at 50% 62%, var(--c) 50%, color-mix(in srgb, var(--c), #000 28%) 100%); }
.closet .sw[aria-pressed="true"] { box-shadow: 0 0 0 3px var(--white), 0 0 0 5px var(--sel); }
.closet .sw.any { background: radial-gradient(circle at 34% 28%, rgba(255, 255, 255, .9) 0 11%, rgba(255, 255, 255, 0) 30%), conic-gradient(#ee4611, #f6c64f, #86dc7e, #4f8de0, #7b5cd6, #f49ac1, #ee4611); }
.closet .sw.any input { position: absolute; inset: 0; width: 100%; height: 100%; padding: 0; border: 0; opacity: 0; cursor: pointer; }
.closet .fits { display: flex; align-items: center; gap: 12px; padding-top: 8px; border-top: 2px dashed var(--line); }
.closet .fits p { margin: 0; color: var(--mute); font: 500 12px/1.2 var(--mono); }
.closet .slots { display: flex; gap: 8px; margin-left: auto; }
.closet .slot { position: relative; }
.closet .slot > button:first-child { display: flex; align-items: center; justify-content: center; gap: 3px; width: 48px; height: 28px; border: 2px dashed #8f8a7e; border-radius: 11px; background: rgba(255, 255, 255, .5); cursor: pointer; color: var(--mute); font: 600 18px/1 var(--sans); }
.closet .slot.full > button:first-child { border: 2px solid var(--ink); background: linear-gradient(#fff, #f1f5fa); box-shadow: 0 2px 0 var(--shadow); }
.closet .slot i { width: 12px; height: 12px; border: 1.5px solid var(--ink); border-radius: 50%; background: var(--c); }
.closet .clear { position: absolute; top: -8px; right: -8px; display: none; width: 20px; height: 20px; padding: 0; border: 2px solid var(--ink); border-radius: 50%; background: var(--white); cursor: pointer; font: 700 12px/1 var(--sans); }
.closet .slot.full:hover .clear, .closet .clear:focus-visible { display: grid; place-items: center; }
.closet button:focus-visible, .closet .sw:focus-within { outline: 3px solid var(--sel); outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) { .closet .in { animation: none; } .closet .tab, .closet .orb, .closet .orb::before, .closet .tile, .closet .sw, .closet .worn { transition: none; } }

/* stacked (him on top, the closet under him) only on tall screens. anything wider than it is tall keeps him on the
   left and the closet on the right, like a computer, so he never shrinks into a strip. a phone on
   its side is too short for that, so it keeps the stacked long scroll */
@media (max-width: 1000px) and (orientation: portrait), (max-width: 1000px) and (max-height: 499px) {
  /* stacked, he sits up top, so the grass comes up to meet him: the horizon lands at his waist
     (main.js keeps it there once it runs, this is the first guess) */
  .page-kewin { --hz: calc(64px + min(88vw, 460px) * .72); }
  .k-stage { grid-template-columns: 1fr; align-content: start; padding: 64px 16px calc(var(--dock-h) + 48px); }
  .k-cat { width: min(88vw, 460px); }
  .k-side { max-width: 600px; width: 100%; justify-self: center; padding-top: 0; }
  .k-card { margin-left: 0; }
  .k-card::before { left: 50%; bottom: auto; top: -15px; margin-left: -13px; transform: rotate(135deg); }
}

/* ---------- /kewin on phones ----------
   his words up top, him in the middle on the grass, the closet along the bottom. tabs, tiles and colors each
   scroll sideways in their own row, so nothing scrolls up and down and he never leaves the screen while you dress
   him. short screens keep the long scroll */
@media (max-width: 1000px) and (orientation: portrait) and (min-height: 600px) {
  body.page-kewin { overflow: hidden; height: 100%; }
  .k-stage { display: flex; flex-direction: column; gap: 10px; height: 100vh; height: 100svh; min-height: 0; max-width: 620px;
    padding: 90px 14px calc(max(18px, env(safe-area-inset-bottom)) + var(--dock-h) + 14px); }
  .k-side { display: contents; }
  .k-card { order: -1; flex: none; width: 100%; }
  .k-card::before { top: auto; bottom: -15px; transform: rotate(-45deg); }
  .k-card .body { padding: 18px 16px 9px; }
  .k-card .ac-name { top: -13px; left: 16px; font-size: 13px; }
  .k-card .say { margin-bottom: 4px; font-size: 15px; }
  .k-card .small { font-size: 12px; }
  .k-cat { flex: 1 1 0; min-height: 0; width: 100%; aspect-ratio: auto; }
  .closet { flex: none; width: 100%; border-radius: 20px; background: linear-gradient(rgba(240, 250, 236, .9), rgba(226, 244, 218, .9)); -webkit-backdrop-filter: none; backdrop-filter: none; }
  .closet.shut { width: auto; align-self: center; }
  .k-sign { display: none; }
}

/* ---------- /kewin: the scene ----------
   a tree behind him and a patch of grass by his feet (sized off his canvas's height, cqh, so they stay
   in scale with him at any size), a balloon drifting across, and his ufo, which main.js flies in now and then */
.k-cat { container-type: size; --him: 1; --near: 1.25; --fit-near: .2; }
.page-kewin { --voice-pitch: 540; --voice-speed: 15; }
.page-kewin .k-stage { overflow: clip; }
/* side by side, he fits the window: his size comes from its width and its height (--s, never so tall the page would
   scroll), and he stands low by the dock with the grass line behind his legs (main.js keeps --hz there, this is the
   first guess), so he's standing in his world at any window shape. the closet column sits on the same line, so
   opening it never moves him. its bubble keeps 64px over it to sit by his face, less on short screens so the open
   closet still fits */
@media (min-width: 1001px), (orientation: landscape) and (min-height: 500px) {
  body.page-kewin { --side: min(540px, 40vw); --s: min(620px, calc(min(1240px, 100vw) - 92px - var(--side)), calc(100svh - 72px - var(--dock-h) - 30px));
    --hz: calc(100svh - var(--dock-h) - 30px - .16 * var(--s)); }
  .k-stage { grid-template-columns: minmax(0, 1fr) var(--side); align-content: end; padding-bottom: calc(var(--dock-h) + 30px); }
  .k-cat { width: var(--s); align-self: end; }
  .k-side { grid-template-columns: minmax(0, 1fr); align-self: end; padding-top: clamp(0px, 100svh - 602px, 64px); }
  .k-cat canvas { width: calc(100% + 80cqh); }
}
.k-tree { position: absolute; height: calc(94cqh * var(--him)); width: auto; aspect-ratio: 140 / 200; left: max(-28px, calc(43% - 59cqh * var(--him))); bottom: calc(6cqh + 4cqh * var(--him)); }
.k-grass { position: absolute; width: calc(30cqh * var(--him)); height: auto; aspect-ratio: 100 / 48; left: calc(43% - 40cqh * var(--him)); bottom: calc(6cqh - 8cqh * var(--him)); pointer-events: none; }
.balloon { position: absolute; left: 0; top: 16%; width: clamp(40px, 4.4vw, 64px); animation: balloon-by 170s linear -70s infinite; will-change: transform; }
.balloon img { width: 100%; height: auto; animation: bob 7s ease-in-out infinite; }
@keyframes balloon-by { from { transform: translateX(-12vw); } to { transform: translateX(108vw); } }
.ufo { position: fixed; z-index: 3; left: 0; top: 0; width: clamp(84px, 8vw, 124px); visibility: hidden; pointer-events: none; will-change: transform; }
.ufo.on { visibility: visible; }
.ufo img { width: 100%; height: auto; }
.cloud > svg { transform-origin: 50% 85%; }
html.over-cloud body { cursor: pointer; }
/* more of his world: mushrooms at the tree's foot,
   rocks past his laptop and a signpost, all in step with his size like the tree */
.k-prop { position: absolute; height: auto; }
.k-mush { width: calc(19cqh * var(--him)); left: calc(43% - 38cqh * var(--him)); bottom: calc(6cqh + 2cqh * var(--him)); }
.k-rocks { width: calc(16cqh * var(--him)); left: calc(43% + 40cqh * var(--him)); bottom: calc(6cqh - 4cqh * var(--him)); }
.k-sign { width: calc(17cqh * var(--him)); left: calc(43% + 45cqh * var(--him)); bottom: calc(6cqh + 8cqh * var(--him)); }
/* little pines on the horizon */
.far { position: fixed; left: 0; right: 0; top: var(--hz); height: 0; }
.far .pine { position: absolute; bottom: -4px; width: auto; height: clamp(38px, 7vh, 76px); opacity: .9; filter: saturate(.8) brightness(1.06); }
.far .p1 { left: 2vw; } .far .p2 { left: 6.5vw; height: clamp(28px, 4.6vh, 52px); }
.far .p3 { right: 2.5vw; height: clamp(30px, 5vh, 56px); } .far .p4 { right: 6vw; }
/* the sky: planet, island, paper plane */
.planet { position: absolute; left: 31vw; top: 7vh; width: clamp(52px, 5.4vw, 84px); height: auto; animation: bob 9s ease-in-out infinite; }
.island { position: absolute; left: 0; top: 34%; width: clamp(56px, 5.6vw, 90px); animation: balloon-by 260s linear -160s infinite; will-change: transform; }
.island img, .plane img { width: 100%; height: auto; }
.island img { animation: bob 8s ease-in-out -2s infinite; }
.plane { position: absolute; left: 0; top: 24%; width: clamp(32px, 2.8vw, 46px); transform: translateX(-12vw); animation: plane-by 48s linear 9s infinite; will-change: transform; }
@keyframes plane-by {
  0% { transform: translate(-12vw, 0) rotate(-3deg); }
  9% { transform: translate(30vw, -4vh) rotate(4deg); }
  18% { transform: translate(70vw, -1vh) rotate(-4deg); }
  27%, 100% { transform: translate(112vw, -5vh) rotate(2deg); }
}
@media (prefers-reduced-motion: reduce) {
  .balloon { animation: none; transform: translateX(72vw); }
  .balloon img, .island img, .planet { animation: none; }
  .island { animation: none; transform: translateX(84vw); }
  .plane { display: none; }
}

/* ---------- /kewin: day and night ----------
   main.js sets the colors by the clock (dayNight). the sky clouds take its colors, his world (tree, props, far pines,
   things in the sky) dims, warms at sunset and cools at night, stars come out and fireflies drift by him. his 3d
   lights follow in cat.js. the credit cloud and the ui stay as they are */
.clouds .cloud svg g:first-of-type { fill: var(--cloud-shade, #b9dafb); }
.clouds .cloud svg g:last-of-type { fill: var(--cloud, #fff); }
.page-kewin :is(.k-tree, .k-prop, .k-grass, .far, .balloon, .island, .planet, .plane) { filter: brightness(var(--lit, 1)) saturate(var(--sat, 1)) sepia(calc(var(--warm, 0) * .5)); }
.stars { position: absolute; inset: 0 0 calc(100vh - var(--hz)) 0; opacity: var(--night, 0); pointer-events: none; }
.stars i { position: absolute; width: var(--z); height: var(--z); border-radius: 50%; background: #fff; box-shadow: 0 0 4px rgba(255, 255, 255, .8); animation: twinkle var(--t) ease-in-out infinite; }
@keyframes twinkle { 50% { opacity: .3; transform: scale(.7); } }
.flies { position: absolute; inset: 0; opacity: var(--night, 0); pointer-events: none; }
.flies i { position: absolute; width: max(3px, 1.1cqh); height: max(3px, 1.1cqh); border-radius: 50%; background: #f6ffa8; box-shadow: 0 0 1.6cqh .4cqh rgba(220, 255, 120, .7);
  animation: fly var(--t) ease-in-out infinite alternate, glow 2.6s ease-in-out infinite; }
@keyframes fly { to { transform: translate(var(--dx), var(--dy)); } }
@keyframes glow { 0%, 100% { opacity: .15; } 50% { opacity: 1; } }
html:not(.dark) :is(.stars, .flies) { display: none; }
@media (prefers-reduced-motion: reduce) { .stars i, .flies i { animation: none; } }

/* ---------- /kewin: his z's while he naps ---------- */
.zzz { position: fixed; left: 0; top: 0; z-index: 3; pointer-events: none; font: italic 800 22px/1 var(--sans); color: #fff; text-shadow: 0 2px 0 var(--ink), 0 0 2px var(--ink); }
.zzz:not(.on) { display: none; }
.zzz i { position: absolute; opacity: 0; animation: zfloat 3s ease-out infinite; }
.zzz i:nth-child(2) { animation-delay: 1s; font-size: .8em; }
.zzz i:nth-child(3) { animation-delay: 2s; font-size: .65em; }
@keyframes zfloat { 0% { opacity: 0; transform: translate(0, 0) scale(.6); } 20% { opacity: 1; } 100% { opacity: 0; transform: translate(22px, -54px) scale(1.15); } }
@media (prefers-reduced-motion: reduce) { .zzz i { animation: none; opacity: 1; } .zzz i:nth-child(2) { transform: translate(10px, -22px); } .zzz i:nth-child(3) { transform: translate(20px, -42px); } }

/* ---------- /kewin: his laptop's ping ---------- */
.ping-bang, .ping-note { position: fixed; left: 0; top: 0; z-index: 3; pointer-events: none; }
.ping-bang:not(.on), .ping-note:not(.on) { display: none; }
.ping-bang { width: 34px; height: 34px; margin: -44px 0 0 -17px; border: 2px solid var(--ink); border-radius: 50%; color: #fff; font: 900 22px/30px var(--sans); text-align: center; text-shadow: 0 1px 0 var(--ink);
  background: radial-gradient(circle at 34% 28%, rgba(255, 255, 255, .9) 0 10%, rgba(255, 255, 255, 0) 32%), radial-gradient(circle at 50% 62%, #ff7a3d 50%, #c9380c 100%);
  box-shadow: 0 3px 0 rgba(20, 20, 20, .25); animation: ping-pop .4s var(--spring) both, ping-bob .9s ease-in-out .4s infinite alternate; }
.ping-note { translate: -50% -100%; display: flex; gap: 8px; align-items: center; padding: 6px 11px 6px 6px; white-space: nowrap; color: var(--ink);
  background: linear-gradient(rgba(255, 255, 255, .98), rgba(255, 255, 255, .98) 45%, #eaf2fc); border: 2px solid var(--ink); border-radius: 13px;
  box-shadow: 0 3px 0 rgba(20, 20, 20, .16), 0 16px 30px -14px rgba(8, 40, 95, .55); animation: ping-pop .4s var(--spring) .12s both; }
.ping-ico { display: grid; place-items: center; width: 24px; height: 24px; flex: none; border: 2px solid var(--ink); border-radius: 8px;
  background: linear-gradient(rgba(255, 255, 255, .55), rgba(255, 255, 255, 0) 50%), linear-gradient(#ff8a4c, #ee4611); box-shadow: 0 2px 0 rgba(20, 20, 20, .18); }
.ping-ico svg { width: 12px; height: 12px; }
.ping-note b { display: block; font: 700 12px/1.15 var(--sans); }
.ping-note small { display: block; margin-top: 2px; color: var(--mute); font: 500 10px/1.1 var(--mono); }
@keyframes ping-pop { from { scale: 0; } }
@keyframes ping-bob { from { rotate: -8deg; translate: 0 0; } to { rotate: 6deg; translate: 0 -5px; } }
@media (prefers-reduced-motion: reduce) { .ping-bang, .ping-note { animation: none; } }

/* ---------- /kewin: the photo by the rocks ----------
   leans on the rocks, behind him (cat.js passes taps on it through unless he's in front). tap it and it comes up big */
.k-print { width: calc(10cqh * var(--him)); left: calc(43% + 53cqh * var(--him)); bottom: calc(6cqh - 5cqh * var(--him)); padding: calc(.45cqh * var(--him)) calc(.45cqh * var(--him)) calc(1.3cqh * var(--him)); border: 0; border-radius: 2px;
  background: #fff; rotate: -11deg; transform-origin: 0 100%; box-shadow: 0 0 0 1px rgba(20, 20, 20, .14), 0 .5cqh .9cqh rgba(10, 60, 40, .3);
  transition: rotate .4s var(--spring), translate .4s var(--spring); }
.k-print img { width: 100%; height: auto; }
.k-print.hot, .k-print:focus-visible { rotate: -4deg; translate: 0 -.8cqh; }
.k-print.out { visibility: hidden; }
/* on phones it leans on the mushrooms */
@media (max-width: 1000px) and (orientation: portrait), (max-width: 1000px) and (max-height: 499px) {
  .k-print { left: calc(43% - 21cqh * var(--him)); bottom: calc(6cqh - 1cqh * var(--him)); }
}
/* ---------- /kewin: his boombox ----------
   on the grass past the photo (on phones, in front of his laptop), behind his canvas too (cat.js passes taps on it through). it thumps on the beat
   while his music plays (cat.js sets --beat from the song) and puffs notes when you tap it */
.k-boombox { width: calc(13cqh * var(--him)); left: calc(43% + 66cqh * var(--him)); bottom: calc(6cqh - 4cqh * var(--him)); padding: 0; border: 0; background: none; cursor: pointer;
  transform-origin: 50% 100%; transition: translate .3s var(--spring); }
.k-boombox img { display: block; width: 100%; height: auto; }
.k-boombox.hot, .k-boombox:focus-visible { translate: 0 -.6cqh; }
.k-boombox:focus-visible { outline: 3px solid var(--ink); outline-offset: 4px; border-radius: 6px; }
.k-boombox.on { animation: thump var(--beat, .55s) cubic-bezier(.3, .7, .4, 1) infinite; }
@keyframes thump { 0% { scale: 1.08 .9; } 28% { scale: .96 1.06; } 60%, 100% { scale: 1; } }
.bb-note { position: absolute; width: calc(3.6cqh * var(--him)); pointer-events: none; animation: note-up 1.6s ease-out forwards; }
.bb-note svg { display: block; width: 100%; height: auto; }
@keyframes note-up { 0% { opacity: 0; transform: rotate(var(--r)) scale(.6); } 15% { opacity: 1; }
  100% { opacity: 0; transform: translate(calc(var(--dx) * 2.5cqh * var(--him)), calc(-14cqh * var(--him))) rotate(calc(var(--r) * -1)) scale(1); } }
@media (prefers-reduced-motion: reduce) { .k-boombox.on { animation: none; } }
@media (max-width: 1000px) and (orientation: portrait), (max-width: 1000px) and (max-height: 499px) {
  .k-boombox { left: calc(43% + 24cqh * var(--him)); bottom: calc(6cqh - 15cqh * var(--him)); }
}
.k-photo { position: fixed; z-index: 15; left: 0; top: 0; width: 400px; padding: 10px 10px 0; background: #fff; border: 2px solid var(--ink); border-radius: 4px;
  rotate: -2.5deg; box-shadow: 0 3px 0 var(--ink), 0 30px 60px -20px rgba(8, 40, 95, .6); }
.k-photo[hidden] { display: none; }
.k-photo:focus { outline: none; }
.k-photo img { width: 100%; height: auto; background: #dfe9f5 url(/assets/meme/awkward-world-sm.webp) center / cover; }
.k-photo .pick { display: flex; gap: 6px; padding: 9px 0 10px; }
.k-photo .pick button { padding: 3px 11px; border: 2px solid var(--ink); border-radius: 999px; background: #fff; color: var(--ink); font: 600 12px/1.2 var(--sans); cursor: pointer; }
.k-photo .pick [aria-pressed="true"] { background: var(--sel); color: #fff; }
.k-photo .x { position: absolute; right: -14px; top: -14px; margin: 0; cursor: pointer; }
