/* ==========================================================================
   Willy Web · leewilly.com
   Greyscale Platinum / Magic Cap / Palm. Only photos get colour.
   ========================================================================== */

/* Titles, menus, clock: Jersey 10 (OFL). One weight; size-adjust matches the old Pixelify cap height, so sizes stay put. */
@font-face { font-family: "Jersey 10"; src: url("../assets/fonts/jersey-10.woff2") format("woff2"); font-weight: 400; font-display: swap; size-adjust: 130%; 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: "Jersey 10"; src: url("../assets/fonts/jersey-10-ext.woff2") format("woff2"); font-weight: 400; font-display: swap; size-adjust: 130%; unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "Silkscreen"; src: url("../assets/fonts/silkscreen-400.woff2") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Silkscreen"; src: url("../assets/fonts/silkscreen-700.woff2") format("woff2"); font-weight: 700; font-display: swap; }
@font-face { font-family: "VT323"; src: url("../assets/fonts/vt323.woff2") format("woff2"); font-weight: 400; font-display: swap; }

:root {
  --ink: #101010;
  --ink-2: #3a3a3a;
  --face: #dedede;
  --face-2: #cecece;
  --hi: #ffffff;
  --lo: #8c8c8c;
  --lo-2: #5a5a5a;
  --desk: #a5a5a5;
  --floor: #b5b5b5;     /* the room's floor (tools/make_room.py FLOOR); the page below the desk carries on in it */
  --lcd: #c5c5c5;
  --lcd-ink: #191919;
  --body-shell: #6b6b6b;
  --menu-h: 39px;

  --font-ui: "Jersey 10", "Chicago", "Charcoal", "Geneva", system-ui, sans-serif;
  --font-px: "Silkscreen", "Jersey 10", monospace;
  --font-lcd: "VT323", "Monaco", ui-monospace, monospace;
  --font-body: "Geneva", "Verdana", "Tahoma", system-ui, sans-serif;

  --drop: 2px 2px 0 rgba(0, 0, 0, .14);
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; font-synthesis-weight: none; scroll-padding-top: calc(var(--menu-h) + 12px); }
body {
  margin: 0;
  min-height: 100vh;
  color: var(--ink);
  font: 15px/1.5 var(--font-body);
  background: #efefef;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}
img { display: block; }
a { color: inherit; }
h1, h2, h3, p { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
button { font: inherit; color: inherit; }

.sr-only {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Focus: chunky 1-bit ring that reads on every grey */
:focus { outline: none; }
:focus-visible {
  outline: 3px solid var(--ink);
  outline-offset: 2px;
  box-shadow: 0 0 0 6px var(--hi);
  border-radius: 4px;
}

.skip-link {
  position: fixed; left: 8px; top: -60px; z-index: 1000;
  padding: 8px 14px; background: var(--ink); color: var(--hi);
  font: 16px var(--font-ui); text-decoration: none; border-radius: 4px;
}
.skip-link:focus { top: calc(var(--menu-h) + 8px); }

/* ------------------------------------------------------------------ Boot */
.boot { display: none; }
.booting .boot {
  position: fixed; inset: 0; z-index: 900;
  display: grid; place-items: center;
  background: #e6e6e6;
  animation: boot-failsafe 0s 4s forwards; /* never block the page even if JS dies */
}
.boot.is-done { opacity: 0; transform: scale(1.04); transition: opacity .35s ease, transform .35s ease; pointer-events: none; }
.boot__card {
  width: min(300px, 84vw);
  padding: 26px 24px 22px;
  text-align: center;
  background: #f7f7f7;
  border: 1.5px solid var(--ink);
  border-radius: 6px;
  animation: boot-pop .45s cubic-bezier(.2, 1.6, .4, 1) both;
}
.boot__logo { width: 64px; height: 64px; margin: 0 auto 12px; animation: boot-bob 1.2s steps(2) infinite; }
.boot__name { font: 700 22px/1 var(--font-ui); }
.boot__msg { margin: 10px 0 12px; font: 18px/1 var(--font-lcd); min-height: 18px; }
.progress {
  height: 14px; border: 1px solid var(--ink); background: var(--hi);
  box-shadow: inset 1px 1px 0 var(--lo); overflow: hidden;
}
.progress__bar {
  display: block; height: 100%; width: 0;
  background: repeating-linear-gradient(-45deg, #313131 0 5px, #737373 5px 10px);
  animation: boot-fill 1.5s cubic-bezier(.6, .05, .3, 1) forwards;
}
@keyframes boot-fill { to { width: 100%; } }
@keyframes boot-pop { from { transform: scale(.6); opacity: 0; } }
@keyframes boot-bob { 50% { transform: translateY(-3px); } }
@keyframes boot-failsafe { to { visibility: hidden; opacity: 0; pointer-events: none; } }

/* --------------------------------------------------------------- Menubar */
.menubar {
  position: sticky; top: 0; z-index: 500;
  display: flex; align-items: center; justify-content: space-between;
  height: var(--menu-h); padding: 0 15px;
  background: #f7f7f7;
  border-bottom: 1px solid var(--ink);
  font: 600 22.5px/1 var(--font-ui);
  user-select: none;
}
.menubar__left, .menubar__right, .menus { display: flex; align-items: center; height: 100%; }
.menubar__logo { display: grid; place-items: center; width: 45px; height: 100%; border-radius: 0; }
.menubar__logo img { width: 24px; height: 24px; image-rendering: pixelated; }   /* the hand-drawn 24px WW, 1:1 */
.menu__trigger.menubar__name { padding: 0 15px 0 9px; font-weight: 700; white-space: nowrap; }
.menubar__short { display: none; }
.menu { position: relative; height: 100%; }
.menu__trigger {
  height: 100%; padding: 0 15px; border: 0; background: none; cursor: default;
  font: 600 22.5px/1 var(--font-ui);
}
.menu__trigger[aria-expanded="true"], .menu__trigger:hover { background: var(--ink); color: var(--hi); }
.menu__list {
  position: absolute; top: 100%; left: 0; min-width: 315px; padding: 4.5px 0;
  background: var(--face); border: 1px solid var(--ink);
  box-shadow: var(--drop);
}
.menu__list a, .menu__list button {
  display: flex; justify-content: space-between; gap: 24px; width: 100%;
  padding: 7.5px 24px; border: 0; background: none; text-align: left; text-decoration: none;
  font: 500 22.5px/1.2 var(--font-ui); cursor: default;
}
.menu__list a:hover, .menu__list button:hover, .menu__list a:focus-visible, .menu__list button:focus-visible {
  background: var(--ink); color: var(--hi); outline: none; box-shadow: none; border-radius: 0;
}
.menu__list kbd { font: 22.5px var(--font-lcd); opacity: .7; }
/* Apps menu: each app's pixel icon before its name (WW for Home); white on the black hover row */
.menu__list a.menu__app { display: flex; justify-content: flex-start; align-items: center; gap: 12px; padding-left: 18px; }
.menu__ic { flex: none; width: 24px; height: 24px; image-rendering: pixelated; }
.menu__list a.menu__app:hover .menu__ic, .menu__list a.menu__app:focus-visible .menu__ic { filter: invert(1); }
.menu__sep { height: 1px; margin: 6px 1px; background: var(--lo); box-shadow: 0 1px 0 var(--hi); }
.clock { font-weight: 600; white-space: nowrap; font-variant-numeric: tabular-nums; }

/* ---------------------------------------------------------------- Window */
.window {
  position: relative;
  background: #f7f7f7;
  border: 1px solid var(--ink);
  border-radius: 2px;
  box-shadow: var(--drop);
}
.titlebar {
  display: flex; align-items: center; gap: 6px;
  height: 22px; padding: 0 5px;
  border-bottom: 1px solid var(--ink);
  background: var(--face);
}
.titlebar__rule {
  flex: 1; height: 11px;
  height: 7px;
  background: repeating-linear-gradient(to bottom, #b5b5b5 0 1px, transparent 1px 3px);
}
.titlebar__title { padding: 0 6px; font: 700 15px/1 var(--font-ui); white-space: nowrap; }
.titlebar__box {
  width: 13px; height: 13px; flex: none;
  border: 1px solid var(--ink); background: #f7f7f7;
}
.titlebar__box--zoom { background: linear-gradient(var(--ink), var(--ink)) 2px 2px / 6px 6px no-repeat, var(--face); }
.titlebar__box--shade { background: linear-gradient(var(--ink), var(--ink)) 2px 3px / 7px 1px no-repeat, linear-gradient(var(--ink), var(--ink)) 2px 6px / 7px 1px no-repeat, var(--face); }
.statusbar {
  display: flex; justify-content: space-between; gap: 12px;
  padding: 4px 10px; border-top: 1px solid #b5b5b5;
  font: 17px/1 var(--font-lcd); color: var(--ink-2);
}

/* ----------------------------------------------------------- Push buttons */
.push[hidden] { display: none; }   /* an app with no extra button (RUIND Garage) shows OK only */
.push {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 36px; padding: 6px 18px;
  font: 600 16px/1 var(--font-ui); text-decoration: none; color: var(--ink);
  background: #f7f7f7;
  border: 1.5px solid var(--ink); border-radius: 7px;
  cursor: pointer;
  transition: transform .12s;
}
.push:hover { background: #fff; }
.push:active { background: var(--ink); color: var(--hi); }
.push--default { box-shadow: 0 0 0 2px #e6e6e6, 0 0 0 3.5px var(--ink); }
.push--default:focus-visible { box-shadow: 0 0 0 2px #e6e6e6, 0 0 0 3.5px var(--ink), 0 0 0 7px var(--hi); }

/* ------------------------------------------------------------- Home stage */
.stage {
  position: relative;
  padding: 0;
  text-align: center;
  background: var(--floor);
  overflow: hidden;
}
.stage__head { position: relative; z-index: 3; }
/* The desk: pixel art (assets/desk/), edge to edge. The room picture is 1200 x 456; its middle 234 columns are the
   phone view (SVG x 0..400). The box is as tall as the phone view at full width, or the screen, whichever is less,
   and the SVG slices the wide picture to fill it, so wide screens see more wall and floor. Never shorter than the whole
   picture at full width (2051 x 779 SVG units, 0.38), so a short wide screen (a phone on its side) keeps the top of the
   room and scrolls a little instead. */
.room {
  position: relative; z-index: 2;
  width: 100%;
  height: max(min(calc(100vw * 1.9487), calc(100vh - var(--menu-h))), calc(100vw * .38));
  height: max(min(calc(100vw * 1.9487), calc(100svh - var(--menu-h))), calc(100vw * .38));
  background: var(--floor);
}
.desk-svg { display: block; width: 100%; height: 100%; overflow: visible; touch-action: pan-y;
  -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
.desk-svg image { image-rendering: pixelated; image-rendering: crisp-edges; image-rendering: pixelated; }
.leash__link { cursor: pointer; outline: none; -webkit-tap-highlight-color: transparent; }   /* Willy Workout's leash under the desk */
.leash.is-off { display: none; }
.leash__art { image-rendering: pixelated; transform-box: fill-box; transform-origin: 50% 100%; transition: transform .18s steps(3); }
.leash__line { image-rendering: pixelated; pointer-events: none; }
.leash__link:hover .leash__art, .leash__link:focus-visible .leash__art { transform: rotate(-3deg); }
.poster { cursor: pointer; outline: none; -webkit-tap-highlight-color: transparent; }
.poster__art { transform-box: fill-box; transform-origin: 50% 0; transition: transform .18s steps(3); }
.poster:hover .poster__art, .poster:focus-visible .poster__art { transform: rotate(-2deg); }
.lamp { cursor: pointer; outline: none; -webkit-tap-highlight-color: transparent; }
.lamp__off, .lamp-off .lamp__on, .lamp-off .lamp-light { display: none; }
.lamp-off .lamp__off { display: inline; }
.desk-svg { transition: filter .25s steps(3); }
.desk-svg.lamp-off { filter: url(#lamp-dim); }   /* lights out: index.html steps each grey down the ramp, per pixel, so the pixels stay crisp */
html.lights-out { --floor: #6b6b6b; }   /* the floor and page around the room match the dimmed picture (#b5b5b5 through #lamp-dim) */
html.lights-out body, html.lights-out .launch, html.lights-out .foot { background: #6b6b6b; }
html.lights-out .foot, html.lights-out .foot__link { color: #212121; }
.desk-svg, .desk-svg *, .launch__tile img { -webkit-user-drag: none; }
.obj__shadow { fill: #000; opacity: .07; transform-box: fill-box; transform-origin: 50% 50%; pointer-events: none; }   /* a shadow left on top of another object must not eat its taps */
.obj__art, .obj__tray { transform-box: fill-box; transform-origin: 50% 100%; }
.obj__tray { transform: scaleY(0); }
.obj__link { cursor: grab; outline: none; -webkit-tap-highlight-color: transparent; }
.obj--drawer .obj__link { cursor: pointer; }
.js .obj:not(.obj--drawer), .js .obj:not(.obj--drawer) * { touch-action: none; -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
.obj.is-dragging .obj__link { cursor: grabbing; }
.obj__link:focus { outline: none; }
.obj--drawer.is-off .obj__tray { display: none; }
.obj--drawer.is-off .obj__link { pointer-events: none; cursor: default; }
[data-app-item].is-app-off { display: none !important; }   /* Site settings > Show app: off */
.focus-ants {
  fill: none; stroke: #101010; stroke-width: 2; stroke-dasharray: 5 4; pointer-events: none;
  animation: ants .6s linear infinite;
}
@keyframes ants { to { stroke-dashoffset: -9; } }
.no-js-focus .obj__link:focus-visible .obj__art { outline: 3px solid #101010; }

/* Balloon Help-style label */
.balloon {
  position: absolute; z-index: 10; left: 0; top: 0;
  padding: 7px 12px 8px; min-width: 120px;
  background: #fff; color: var(--ink);
  border: 1.5px solid var(--ink); border-radius: 12px;
  font: 700 16px/1.1 var(--font-ui); white-space: nowrap; text-align: center;
  transform: translate(-50%, calc(-100% - 14px));
  pointer-events: none;
  animation: balloon-in .28s cubic-bezier(.2, 1.7, .4, 1);
}
.balloon::after {
  content: ""; position: absolute; left: 50%; bottom: -10px; width: 14px; height: 14px; margin-left: -7px;
  background: #fff; border-right: 1.5px solid var(--ink); border-bottom: 1.5px solid var(--ink);
  transform: rotate(45deg) skew(8deg, 8deg);
}
.balloon__soon:empty { display: none; }
.balloon__soon { display: block; margin-top: 3px; font: 16px/1 var(--font-lcd); color: #525252; text-transform: uppercase; letter-spacing: .04em; }
@keyframes balloon-in { from { opacity: 0; transform: translate(-50%, calc(-100% - 4px)) scale(.8); } }

/* ----------------------------------------------------------------- Floor */
.floor {
  padding: 28px 18px 44px;
  text-align: center;
  background: var(--floor);
}
.thesis {
  max-width: 15ch; margin: 0 auto;
  font: 700 clamp(30px, 8.6vw, 52px)/1.06 var(--font-ui);
  letter-spacing: -.01em;
  text-wrap: balance;
}
.thesis mark {
  color: var(--hi); background: var(--ink);
  padding: 0 .14em; margin: 0 -.02em;
  box-decoration-break: clone; -webkit-box-decoration-break: clone;
}
/* ------------------------------------------------- All apps (launcher) */
.launch { padding: 28px 16px 48px; background: #efefef; border-top: 1.5px solid #313131; }
.launch__title { max-width: 640px; margin: 0 auto 18px; font: 700 26px/1 var(--font-ui); }
.launch__grid {
  max-width: 640px; margin: 0 auto;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px;   /* two columns at most */
}
.launch__item { --r: 1; }
.launch__link {
  position: relative;
  display: grid; grid-template-columns: 56px 1fr; grid-template-rows: 1fr 1fr; align-items: center; column-gap: 14px; row-gap: 4px;
  min-height: 76px; padding: 10px 14px;
  text-decoration: none; color: var(--ink);
  background: #fff; border: 1.5px solid #313131; border-radius: 12px;
  opacity: var(--r);
  transform: translateY(calc((1 - var(--r)) * 34px)) scale(calc(.94 + var(--r) * .06));
  transition: border-color .15s, background-color .15s, box-shadow .15s;
}
.launch__tile {
  grid-row: 1 / 3;
  position: relative; isolation: isolate; display: grid; place-items: center;
  width: 56px; height: 56px; border: 1.5px solid #313131; border-radius: 14px; background: #efefef;
  transform: rotate(calc((1 - var(--r)) * -14deg));
  transition: transform .35s cubic-bezier(.3, 1.8, .5, 1);
}
.launch__tile img { width: 32px; height: 32px; image-rendering: pixelated; }
.launch__text { grid-column: 2; grid-row: 1 / 3; align-self: center; display: grid; gap: 3px; min-width: 0; }
.launch__name { font: 700 18px/1.1 var(--font-ui); }
.launch__link:hover, .launch__link:focus-visible { box-shadow: 3px 3px 0 #313131; }
.launch__link:hover .launch__tile, .launch__link:focus-visible .launch__tile { transform: rotate(-6deg) scale(1.08); }
.launch__link:active { transform: scale(.98); }
.launch__link:focus-visible { outline-offset: 3px; border-radius: 12px; }

/* ------------------------------------------------------------- Read Me */

/* ----------------------------------------------------------------- Alert */
.alert {
  width: min(460px, calc(100vw - 28px)); padding: 0;
  color: var(--ink); background: #f7f7f7;
  border: 1.5px solid var(--ink); border-radius: 6px;
  box-shadow: 4px 4px 0 rgba(0,0,0,.2);
}
.alert::backdrop { background: rgba(58, 58, 58,.35); backdrop-filter: grayscale(1); }
.alert[open] { animation: alert-in .38s cubic-bezier(.2, 1.5, .4, 1); }
@keyframes alert-in { from { transform: scale(.7) translateY(30px); opacity: 0; } }
.alert__inner { display: grid; grid-template-columns: 56px 1fr; gap: 14px 16px; padding: 20px 20px 18px; }
.alert__icon img { width: 48px; height: 48px; image-rendering: pixelated; }
.alert__text h2 { font: 700 20px/1.1 var(--font-ui); }
.alert__quote { margin-top: 8px; font: 600 18px/1.25 var(--font-ui); }
.alert__quote:empty { display: none; }
#soon-body { margin-top: 8px; font-size: 14px; color: var(--ink-2); }
#soon-body p + p { margin-top: 6px; }
.alert__status { margin-top: 12px; font: 17px/1.2 var(--font-lcd); }
.stamp {
  display: inline-block; margin-right: 6px; padding: 2px 7px 1px;
  font: 700 11px/1.3 var(--font-px); text-transform: uppercase;
  border: 2px solid var(--ink); border-radius: 3px; transform: rotate(-3deg);
}
.lie { margin-top: 8px; padding: 6px 10px; background: var(--ink); color: var(--hi); font: 18px/1.2 var(--font-lcd); }
.hearts { margin-top: 8px; font: 22px/1.1 var(--font-lcd); }
.alert__buttons { grid-column: 1 / -1; display: flex; justify-content: flex-end; flex-wrap: wrap; gap: 14px; padding-right: 4px; }
.alert__buttons .push { min-width: 92px; }


/* ------------------------------------------------------------ Responsive */
@media (min-width: 900px) {
  .floor { padding-top: 22px; }
  .thesis { max-width: 23ch; font-size: clamp(34px, 3.6vw, 46px); }
}
@media (max-width: 560px) {
  :root { --menu-h: 42px; }
  .menubar { padding: 0 9px; }
  .menu__trigger, .menu__trigger.menubar__name { padding: 0 12px; }
  .menu { position: static; }                       /* both menus drop from the logo's edge, so the right one stays on screen */
  .menu__list { left: 54px; min-width: 0; width: calc(100vw - 62px); max-width: 315px; }
  .floor { padding: 26px 16px 44px; }
      .launch { padding: 20px 10px 36px; }
  .launch__grid { grid-template-columns: 1fr 1fr; gap: 8px; }
  .launch__link { grid-template-columns: 44px 1fr; min-height: 64px; padding: 8px 10px; column-gap: 10px; }
  .launch__tile { width: 44px; height: 44px; border-radius: 11px; }
  .launch__tile img { width: 28px; height: 28px; }
  .launch__name { font-size: 15px; }
}

@media (max-width: 420px) {
  .menubar__long { display: none; }
  .menubar__short { display: inline; }
}

/* ----------------------------------------------------- Reduced motion */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; scroll-behavior: auto !important; }
  .boot { display: none !important; }
}
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}
@media (prefers-reduced-motion: reduce) {
  .js .obj:not(.obj--drawer), .js .obj:not(.obj--drawer) * { touch-action: auto; }
  .js .obj:not(.obj--drawer) .obj__link { cursor: pointer; }
  .focus-ants { animation: none; }
}


/* Footer: css/foot.css */
