/* Typewriter (typewriter.js). The machine is a Blender sprite pair (img/o-typewriter, img/night/o-typewriter, shadow s-typewriter; layout in img/typewriter.json,
   made by src/typewriter.py + src/typewriter_pack.py). The page is live DOM: a sheet that rises out of the platen through a clipped window.
   Only transform and opacity animate. Day ink is near-black on cream paper; at night a dark veil (opacity crossfade) sits over the sheet like the other DOM paper. */
.obj.o-typewriter { cursor: grab; overflow: visible; --tw-ink: #2b2733; --tw-paper: #f6f1e5; --tw-ring: #7a5cc8; }
.obj.o-typewriter:active { cursor: grabbing; }
.obj.o-typewriter .cut.tw-n { opacity: 0; transition: opacity 1s ease-in-out; }
html.dark .obj.o-typewriter .cut.tw-n { opacity: 1; }
.obj.o-typewriter .tw-in {
  position: absolute; left: 50%; top: 50%; width: 2px; height: 2px; padding: 0; margin: 0; border: 0; resize: none; overflow: hidden;
  opacity: 0; font-size: 16px; /* 16px: iOS never zooms the page on focus */ pointer-events: none; caret-color: transparent; background: none; color: transparent;
}
.obj.o-typewriter:focus { outline: none; }

/* key-press jolt on the whole machine (translate only, ease-out, no overshoot) */
.obj.o-typewriter .lift.tw-jolt { animation: tw-jolt .09s cubic-bezier(.2, .8, .3, 1); }
@keyframes tw-jolt { 0% { transform: translateY(0); } 35% { transform: translateY(1.2px); } 100% { transform: translateY(0); } }
/* keyboard focus ring around the machine */
.obj.o-typewriter .lift::after {
  content: ""; position: absolute; inset: 14px 12px 0 12px; border-radius: 26px; pointer-events: none; opacity: 0;
  box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--tw-ring), 0 0 18px 3px rgba(122, 92, 200, .35);
  transition: opacity .2s cubic-bezier(.16, 1, .3, 1);
}
.obj.o-typewriter:focus-visible .lift::after { opacity: 1; }

/* the page window: sheet rises out of the platen centre line; padded 24px at the sides and top so the sheet shadow and the carriage shift stay visible */
.obj.o-typewriter .tw-win {
  position: absolute; overflow: hidden; pointer-events: none; transform-origin: var(--ox) var(--oy);
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 30px); mask-image: linear-gradient(to bottom, transparent 0, #000 30px);
}
.obj.o-typewriter .tw-car { position: absolute; left: 24px; top: 24px; width: 260px; height: 145px; transition: transform .14s cubic-bezier(.2, .9, .25, 1); will-change: transform; }
.obj.o-typewriter .tw-car.ret { transition-duration: .34s; }
.obj.o-typewriter .tw-sheet {
  position: absolute; left: 0; top: 0; width: 260px; height: 330px; pointer-events: auto; touch-action: none; border-radius: 2px 2px 0 0;
  background:
    linear-gradient(90deg, rgba(60, 40, 20, .06), rgba(60, 40, 20, 0) 5%, rgba(60, 40, 20, 0) 95%, rgba(60, 40, 20, .07)),
    linear-gradient(180deg, rgba(255, 255, 255, .5), rgba(255, 255, 255, 0) 22%),
    var(--tw-paper);
  box-shadow: 1px 2px 2px rgba(48, 36, 30, .20), 4px 8px 12px -2px rgba(48, 36, 30, .22);
  transition: transform .24s cubic-bezier(.2, .9, .25, 1); will-change: transform;
}
.obj.o-typewriter .tw-sheet.ghost { pointer-events: none; transition: none; }
/* darker band where the paper dives into the platen */
.obj.o-typewriter .tw-nip {
  position: absolute; left: 24px; top: 24px; width: 260px; height: 145px; pointer-events: none;
  background: linear-gradient(to top, rgba(30, 24, 30, .26), rgba(30, 24, 30, 0) 16px);
}
.obj.o-typewriter .tw-veil { position: absolute; inset: 0; background: rgba(8, 12, 28, .56); opacity: 0; pointer-events: none; transition: opacity 1s ease-in-out; }
html.dark .obj.o-typewriter .tw-veil { opacity: 1; }
html.dark .obj.o-typewriter .tw-sheet { box-shadow: 1px 2px 2px rgba(0, 0, 0, .35), 4px 8px 12px -2px rgba(0, 0, 0, .4); }

/* type */
.obj.o-typewriter .tw-ln {
  position: absolute; left: 22px; height: 15px; line-height: 15px; white-space: pre; user-select: none;
  font: 500 11.67px/15px 'JetBrains Mono', ui-monospace, 'Courier New', monospace; color: var(--tw-ink);
}
.obj.o-typewriter .tw-c {
  display: inline-block; width: 7px; text-align: center; opacity: var(--o, .9); transform: translateY(var(--dy, 0)) rotate(var(--r, 0deg));
  text-shadow: 0 0 .7px rgba(43, 39, 51, .55);
}
.obj.o-typewriter .tw-c.new { animation: tw-ink .12s cubic-bezier(.2, .8, .3, 1) both; }
@keyframes tw-ink {
  from { opacity: 0; transform: translateY(calc(var(--dy, 0px) - 2px)) scale(1.18) rotate(var(--r, 0deg)); }
  to { opacity: var(--o, .9); transform: translateY(var(--dy, 0)) rotate(var(--r, 0deg)); }
}


/* engaged: a soft glow lifts the page */
.obj.o-typewriter .tw-win { transition: filter .25s cubic-bezier(.16, 1, .3, 1); }
.obj.o-typewriter.tw-on .tw-win { filter: drop-shadow(0 0 8px rgba(122, 92, 200, .28)); }

html.dark .obj.o-typewriter { --tw-ring: #b49cf2; }

@media (prefers-reduced-motion: reduce) {
  .obj.o-typewriter .tw-car, .obj.o-typewriter .tw-sheet { transition-duration: .01s; }
  .obj.o-typewriter .tw-c.new, .obj.o-typewriter .lift.tw-jolt { animation: none; }
}

/* tear-off: while the sheet is held or flying the window stops clipping the top and sides (the platen line below still clips a held sheet) */
.obj.o-typewriter .tw-win.tw-free { overflow: visible; -webkit-mask-image: none; mask-image: none; clip-path: inset(-700px -700px 0 -700px); }
.obj.o-typewriter .tw-sheet.tw-lifted { box-shadow: 2px 6px 6px rgba(48, 36, 30, .20), 8px 18px 22px -4px rgba(48, 36, 30, .26); }
.obj.o-typewriter .tw-sheet.ghost { will-change: translate, rotate, opacity; }
