/* The envelope after a right call (sprint 28 item 3, roadmaps 63 and 64), in the one-bit art bible: ink and paper, the one gold on a
   gilded round only, Bayer dither, stepped motion at 15 fps (steps / step-end, never a smooth tween), no strobe: at most one 120 ms
   flash, on the big and gilded results. The sprites are drawn in client/mail-art.js and arrive as CSS variables (--m-*) on the tray
   and the stage. Every sprite is shown at a whole number of CSS px per art px (2 as laid out, 3 zoomed in), by background size and
   position in whole px: no transform ever scales the art, and no scale() here is anything but a whole number (test/mail-art.test.js),
   so nothing is resampled to grey. mail.js sets the data attributes listed at the top of mail-art.js and nothing else. Sentences in the
   sentence font, 16 px or more, thresholded to one bit by the page's filters (index.html): #onebit for regular words on paper, #bitb
   for bold words over the window's paper. */
#mail{position:fixed;z-index:6;left:0;right:0;top:0;pointer-events:none;color:#000;font:700 16px/24px "Atkinson Hyperlegible",Verdana,sans-serif}
#mail[hidden]{display:none}

/* ---------- the tray: the lamp (ten steps), the keyring (ten fragments), the shield, the last result ---------- */
.mail-tray{display:flex;flex-wrap:wrap;align-items:flex-start;gap:6px 6px;padding:48px 6px 0}
.mail-tray>span{position:relative;box-sizing:border-box;background:#fff;border:2px solid #000;box-shadow:2px 2px 0 #000;padding:0 8px 0 32px;filter:url(#onebit);white-space:nowrap}
.mail-tray>span:empty{display:none}
/* each icon is a 12 x 12 art tile, paper drawn on ink, set by mail-art.js (mirror) from the words mail.js writes */
.mail-tray>span::before{content:"";position:absolute;left:0;top:0;width:24px;height:24px;background:var(--m-icon) 0 0/24px 24px no-repeat;image-rendering:pixelated}
.mail-shield::before{background-image:var(--m-shield)!important}
.mail-tray>.mail-last{padding-left:8px;background:#000;color:#fff;box-shadow:2px 2px 0 #fff}
.mail-tray>.mail-last::before{content:none}
/* the free room's session score ("Session 340, 3 in a row"): a plain paper chip, no icon, so a phone sees it during play */
.mail-tray>.mail-session{padding-left:8px}
.mail-tray>.mail-session::before{content:none}
/* one streak face: the first lit lamp says what it multiplies ("Lamp x1.4: envelope points"); after that it is the lamp icon alone, its
   words kept for screen readers, so no bare "x" sits beside the door's chalked "x2" (mail-art.js lampLabeller) */
.mail-tray>.mail-lamp[data-label]::after{content:": " attr(data-label);font-weight:400}
.mail-tray>.mail-lamp[data-short="1"]{width:28px;height:28px;padding:0;overflow:hidden;color:transparent;border-color:#fff;box-shadow:0 0 0 2px #000,2px 2px 0 2px #000}
/* the lamp ticks to its new step as the envelope comes under the door: its tile rings once, three frames */
#mail[data-state="slide"] .mail-lamp::before{animation:mail-tick 400ms step-end both}
@keyframes mail-tick{0%{box-shadow:0 0 0 2px #fff,0 0 0 4px #000}33%{box-shadow:none}66%{box-shadow:0 0 0 2px #fff,0 0 0 4px #000}100%{box-shadow:none}}
#mail[data-state="slide"] .mail-lamp[data-short="1"]{overflow:visible}
/* a new shield clinks in beside the lamp at the result, not before */
#mail[data-tier="shield"][data-running="1"]:not([data-state="result"]) .mail-shield{visibility:hidden}
#mail[data-tier="shield"][data-state="result"] .mail-shield{animation:mail-clink 270ms step-end both}
@keyframes mail-clink{0%{transform:translateY(-12px)}25%{transform:translateY(-6px)}50%{transform:translateY(2px)}75%,100%{transform:none}}
/* the big or gilded mark, stamped on the keyring's corner while the result is up: drawn at 6, 4, then 2 px per art px */
.mail-mark{display:none;width:24px;height:24px;margin:-8px 0 0 -16px;background:var(--m-mark-big) 0 0/24px 24px no-repeat;image-rendering:pixelated}
#mail[data-state="result"][data-tier="big"] .mail-mark,#mail[data-state="result"][data-tier="jackpot"] .mail-mark{display:block;animation:mail-stamp 200ms step-end both}
#mail[data-state="result"][data-tier="jackpot"] .mail-mark{background-image:var(--m-mark-gold)}
@keyframes mail-stamp{0%{transform:scale(3)}33%{transform:scale(2)}66%,100%{transform:none}}

/* ---------- the window: a striped title bar, the scene under the door, the words over its foot ---------- */
/* 300 x 196 with its border, at a whole-px left (round() where the browser has it), so its 2x art never sits on a half pixel */
.mail-stage{display:none;position:absolute;left:calc(50% - 150px);left:round(down,calc(50% - 150px),1px);top:80px;top:var(--mail-top,80px);width:300px;background:#fff;border:2px solid #000;box-shadow:4px 4px 0 #000;text-align:center}
#mail[data-state="seep"] .mail-stage,#mail[data-state="slide"] .mail-stage,#mail[data-state="peephole"] .mail-stage,#mail[data-state="shake"] .mail-stage,
#mail[data-state="zoom"] .mail-stage,#mail[data-state="result"] .mail-stage{display:block}
#mail[data-running="1"] .mail-stage{pointer-events:auto;cursor:pointer}
/* the stripes are an SVG tile, not a gradient: a gradient's gold comes out a shade off */
.mail-title{position:relative;height:24px;border-bottom:2px solid #000;background:#fff}
.mail-title::before{content:"";position:absolute;left:4px;right:4px;top:4px;height:14px;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' shape-rendering='crispEdges'%3E%3Cpath d='M0 0h4v2h-4z'/%3E%3Cpath fill='%23fff' d='M0 2h4v2h-4z'/%3E%3C/svg%3E") 0 0/4px 4px}
.mail-title-t{position:relative;display:inline-block;padding:0 10px;background:#fff;font:700 18px/22px "Atkinson Hyperlegible",Verdana,sans-serif;filter:url(#onebit)}
/* a big one: the default-button ring (ink, a paper gap, ink) when it opens; gilded: gold in the ring and the stripes from the first beat */
#mail[data-tier="big"][data-state="result"] .mail-stage{box-shadow:0 0 0 2px #fff,0 0 0 6px #000,6px 6px 0 6px #000}
#mail[data-gold="1"] .mail-stage{box-shadow:0 0 0 2px #fff,0 0 0 6px #f2be48,0 0 0 8px #000,6px 6px 0 8px #000}
#mail[data-gold="1"] .mail-title::before{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' shape-rendering='crispEdges'%3E%3Cpath d='M0 0h4v2h-4z'/%3E%3Cpath fill='%23f2be48' d='M0 2h4v2h-4z'/%3E%3C/svg%3E")}

/* the scene: 148 x 84 art px at 2 px each (296 x 168). Zoomed in, every layer of the view shows at 3 px per art px: background size
   444 x 252 at a whole-px offset (mail-art.js ZOOM: -74, -96, which puts the opened envelope above the words). */
.mail-scene{position:relative;width:296px;height:168px;overflow:hidden;background:#000}
.mail-view{position:absolute;left:0;top:0;width:296px;height:168px;background:var(--m-scene) 0 0/296px 168px no-repeat;image-rendering:pixelated}
.mail-view>div{position:absolute;left:0;top:0;width:296px;height:168px;background-position:0 0;background-size:296px 168px;background-repeat:no-repeat}
#mail[data-state="zoom"] .mail-view,#mail[data-state="zoom"] .mail-view>div,#mail[data-state="result"] .mail-view,#mail[data-state="result"] .mail-view>div{background-position:-74px -96px;background-size:444px 252px}

/* gilded: gold light seeps under the door before anything else, then stays; it spreads out over the floor in five steps */
.mail-gold{display:none;background-image:var(--m-gold)}
#mail[data-gold="1"] .mail-gold{display:block}
#mail[data-state="seep"] .mail-gold{animation:mail-seep 800ms step-end both}
@keyframes mail-seep{0%{clip-path:inset(84px 0 78px 0)}20%{clip-path:inset(84px 0 62px 0)}40%{clip-path:inset(84px 0 44px 0)}60%{clip-path:inset(84px 0 24px 0)}80%,100%{clip-path:inset(0)}}

/* the envelope (mail-art.js ENV, 44 x 28 art px at 52, 45: a plain one in its bottom middle, a big or gilded one filling it): comes out
   from under the door in 8 stepped frames of 4 art rows, clipped at the gap so it is never seen above it */
.mail-paper{clip-path:inset(84px 0 0 0)}
.mail-paper::before{content:"";position:absolute;left:104px;top:90px;width:88px;height:56px;background:var(--m-env) 0 0/88px 56px no-repeat}
#mail[data-tier="big"] .mail-paper::before{background-image:var(--m-env-big)}
#mail[data-tier="jackpot"] .mail-paper::before{background-image:var(--m-env-gold)}
#mail[data-state="seep"] .mail-paper{visibility:hidden}
#mail[data-state="slide"] .mail-paper::before{animation:mail-slide 533ms steps(8,end) both}
@keyframes mail-slide{from{transform:translateY(-64px)}to{transform:none}}
#mail[data-state="zoom"] .mail-paper,#mail[data-state="result"] .mail-paper{clip-path:none}
#mail[data-state="zoom"] .mail-paper::before{left:82px;top:39px;width:132px;height:84px;background-size:132px 84px}
/* opened: the flap up, the seal cracked, the letter (or the shield) half out; OPEN (36 x 40 at 56, 33) at 3 px per art px */
#mail[data-state="result"] .mail-paper::before{left:94px;top:3px;width:108px;height:120px;background:var(--m-open) 0 0/108px 120px no-repeat}
#mail[data-state="result"][data-tier="shield"] .mail-paper::before{background-image:var(--m-open-shield)}
#mail[data-state="result"][data-tier="big"] .mail-paper::before{background-image:var(--m-open-big)}
#mail[data-state="result"][data-tier="jackpot"] .mail-paper::before{background-image:var(--m-open-gold)}
#mail[data-state="result"] .mail-paper::before{animation:mail-rise 270ms step-end both}
@keyframes mail-rise{0%{clip-path:inset(54px 0 0 0)}25%{clip-path:inset(36px 0 0 0)}50%{clip-path:inset(18px 0 0 0)}75%,100%{clip-path:none}}

/* the peephole: the room goes dark round a lens, held still. The iris closes in three drawn frames (each a wider lens, drawn, not
   scaled); the big and gilded envelopes get a wider lens */
.mail-hole{display:none;background-image:var(--m-hole)}
#mail[data-tier="big"] .mail-hole{background-image:var(--m-hole-big)}
#mail[data-gold="1"] .mail-hole{background-image:var(--m-hole-gold)}
#mail[data-state="peephole"] .mail-hole,#mail[data-state="shake"] .mail-hole,#mail[data-state="zoom"] .mail-hole{display:block}
#mail[data-state="peephole"] .mail-hole{animation:mail-iris 200ms step-end both}
#mail[data-state="peephole"][data-tier="big"] .mail-hole{animation-name:mail-iris-big}
#mail[data-state="peephole"][data-gold="1"] .mail-hole{animation-name:mail-iris-gold}
@keyframes mail-iris{0%{background-image:var(--m-iris-a)}33%{background-image:var(--m-iris-b)}66%{background-image:var(--m-iris-c)}100%{background-image:var(--m-hole)}}
@keyframes mail-iris-big{0%{background-image:var(--m-iris-big-a)}33%{background-image:var(--m-iris-big-b)}66%{background-image:var(--m-iris-big-c)}100%{background-image:var(--m-hole-big)}}
@keyframes mail-iris-gold{0%{background-image:var(--m-iris-gold-a)}33%{background-image:var(--m-iris-gold-b)}66%{background-image:var(--m-iris-gold-c)}100%{background-image:var(--m-hole-gold)}}

/* the zoom, 700 ms in ten stepped frames: Finder-style zoom rectangles open out from the lens to the scene's edge (five frames), then
   the view jumps to 3 px per art px about the lens and tilts down onto the envelope in two whole-px steps. Never a scale(). */
#mail[data-state="zoom"] .mail-view,#mail[data-state="zoom"] .mail-view>div{animation:mail-zoom 700ms step-end both}
@keyframes mail-zoom{0%,40%{background-position:0 0;background-size:296px 168px}50%{background-position:-74px -62px;background-size:444px 252px}
  70%{background-position:-74px -79px;background-size:444px 252px}85%,100%{background-position:-74px -96px;background-size:444px 252px}}
#mail[data-state="zoom"] .mail-paper::before{animation:mail-zoom-env 700ms step-end both}
@keyframes mail-zoom-env{0%,40%{left:104px;top:90px;width:88px;height:56px;background-size:88px 56px}50%{left:82px;top:73px;width:132px;height:84px;background-size:132px 84px}
  70%{left:82px;top:56px;width:132px;height:84px;background-size:132px 84px}85%,100%{left:82px;top:39px;width:132px;height:84px;background-size:132px 84px}}
.mail-zoomrect{display:none;position:absolute;border:2px solid #fff;box-shadow:0 0 0 2px #000,inset 0 0 0 2px #000;pointer-events:none}
#mail[data-state="zoom"] .mail-zoomrect{display:block;visibility:hidden;animation:mail-rects 700ms step-end both}
@keyframes mail-rects{0%{visibility:visible;left:82px;top:58px;width:132px;height:132px}10%{visibility:visible;left:62px;top:44px;width:172px;height:140px}
  20%{visibility:visible;left:42px;top:30px;width:212px;height:148px}30%{visibility:visible;left:22px;top:16px;width:252px;height:156px}
  40%{visibility:visible;left:2px;top:2px;width:292px;height:164px}50%,100%{visibility:hidden}}
/* big and gilded: the held beat shakes once and the light dips twice */
#mail[data-state="shake"] .mail-view{animation:mail-shake 400ms step-end both}
@keyframes mail-shake{0%{transform:translateX(-4px)}17%{transform:translateX(4px)}33%{transform:translateX(-4px)}50%{transform:translateX(2px)}67%,100%{transform:none}}
.mail-flicker{display:none;background:var(--m-dip) 0 0/16px 16px!important}
#mail[data-state="shake"] .mail-flicker{display:block;animation:mail-dip 600ms step-end both}
@keyframes mail-dip{0%{visibility:visible}11%{visibility:hidden}33%{visibility:visible}44%,100%{visibility:hidden}}
/* the result: through the lens and into the light. Points and shield: a pool of lamp light round the letter; big: a burst of rays;
   gilded: gold rays and sparkles */
.mail-rays{display:none}
#mail[data-state="result"] .mail-rays{display:block;background-image:var(--m-glow)}
#mail[data-state="result"][data-tier="big"] .mail-rays{background-image:var(--m-rays)}
#mail[data-state="result"][data-tier="jackpot"] .mail-rays{background-image:var(--m-rays-gold)}

/* the big and gilded results burst out of the window (mail-art.js BURST): behind it, opening out from its edges in three stepped zoom
   rectangles over the door glass. Gilded is the biggest. */
.mail-burst{display:none;position:absolute;z-index:-1;background-repeat:no-repeat;background-position:0 0;image-rendering:pixelated;pointer-events:none}
#mail[data-state="result"][data-tier="big"] .mail-burst{display:block;left:-42px;top:-26px;width:380px;height:228px;background-image:var(--m-burst-big);background-size:380px 228px;animation:mail-burst-big 200ms step-end both}
#mail[data-state="result"][data-tier="jackpot"] .mail-burst{display:block;left:-47px;top:-36px;width:390px;height:244px;background-image:var(--m-burst-gold);background-size:390px 244px;animation:mail-burst-gold 270ms step-end both}
@keyframes mail-burst-big{0%{clip-path:inset(24px 40px 8px 40px)}33%{clip-path:inset(12px 20px 4px 20px)}66%,100%{clip-path:none}}
@keyframes mail-burst-gold{0%{clip-path:inset(34px 45px 14px 45px)}25%{clip-path:inset(22px 30px 9px 30px)}50%{clip-path:inset(11px 15px 4px 15px)}75%,100%{clip-path:none}}

/* the room's one flash (big and gilded, 120 ms): a Bayer veil of paper behind the window. The veil is drawn at .85 and its layer
   cut to whole pixels (#bitb thresholds alpha), so it is paper or nothing: no grey. The disclaimer strip sits above it (onebit.css). */
.mail-flash{display:none;position:fixed;inset:0;z-index:-1;filter:url(#bitb)}
.mail-flash::before{content:"";position:absolute;inset:0;background:var(--m-flash) 0 0/16px 16px;opacity:.85}
#mail[data-flash="1"] .mail-flash{display:block}
/* desktop: the disclaimer is drawn in the canvas under the chat column (x 300 logical on), so the flash lights the room's column only */
html:not(.portrait) .mail-flash{right:auto;width:calc(var(--w,1280px) * 0.46)}

/* ---------- the words: over the foot of the scene, so the window stays short enough to leave the door's sum in view ---------- */
/* the plate is its own layer: #bitb cuts alpha, so the words must lie on nothing (transparent) to come out ink or paper */
.mail-plate{display:none;position:absolute;left:0;right:0;bottom:0;height:42px;border-top:2px solid #000;background:#fff}
.mail-result{display:none;position:absolute;left:0;right:0;bottom:0;height:40px;white-space:nowrap;
  font:700 24px/40px "Atkinson Hyperlegible",Verdana,sans-serif;filter:url(#bitb)}
#mail[data-state="result"] .mail-result,#mail[data-state="result"] .mail-plate{display:block}
#mail[data-tier="big"] .mail-result{font-size:28px}
#mail[data-tier="jackpot"] .mail-result{font-size:30px}
.mail-hint{position:absolute;right:4px;top:30px;padding:0 6px;border:2px solid #000;font:400 16px/22px "Atkinson Hyperlegible",Verdana,sans-serif;background:#fff;filter:url(#onebit)}
#mail[data-state="result"] .mail-hint{display:none}

/* desktop and landscape: the window sits low on the door (its centre is a quarter of the way across), over the floor it shows, clear
   of the reveal card and of the visitor's face on the glass */
html:not(.portrait) .mail-stage{left:calc(25vw - 150px);left:round(down,calc(25vw - 150px),1px);top:max(60px,min(calc(50vh + 40px),calc(100vh - 290px)));top:round(down,max(60px,min(calc(50vh + 40px),calc(100vh - 290px))),1px)}
/* sprint 29: with a sum chalked on the door, the window goes under it (or above it) instead, so the sum stays whole (phone.js
   mailFitDesk, set by scene-onebit.js as html.mail-desk and --mail-dtop in whole px) */
html.mail-desk:not(.portrait) .mail-stage{top:var(--mail-dtop)}
/* ---------- a short phone (Safari with its bars, 390 x 664; sprint 29 item 2) ----------
   phone.js mailFit places the window from the phone layout's own numbers (scene-onebit.js sets html.mail-short and --mail-top, -sh, -a,
   -b in whole px) so the door's sum and the chat's title bar stay whole: the tray waits while the window is up, the
   window starts under the menu bar, its rings lose their offset shadow, the words move into its title bar, and the scene is cropped to
   --mail-sh px (moved up --mail-a at 2 px per art px, --mail-b at 3): cropped, never scaled. */
/* sprint 31: the tray never covers the menu bar. On a short phone the window needs the room under it, so the chips wait (they are back when the window goes) */
html.mail-short #mail:is([data-state="seep"],[data-state="slide"],[data-state="peephole"],[data-state="shake"],[data-state="zoom"],[data-state="result"]) .mail-tray{visibility:hidden}
html.mail-short .mail-scene{height:var(--mail-sh)}
html.mail-short .mail-view{top:calc(0px - var(--mail-a))}
html.mail-short #mail[data-state="result"] .mail-view{top:calc(0px - var(--mail-b))}
html.mail-short #mail[data-state="zoom"] .mail-view{animation-name:mail-zoom-short}
@keyframes mail-zoom-short{0%,40%{top:calc(0px - var(--mail-a));background-position:0 0;background-size:296px 168px}
  50%{top:calc(0px - var(--mail-b));background-position:-74px -62px;background-size:444px 252px}
  70%{top:calc(0px - var(--mail-b));background-position:-74px -79px;background-size:444px 252px}
  85%,100%{top:calc(0px - var(--mail-b));background-position:-74px -96px;background-size:444px 252px}}
html.mail-short #mail[data-state="zoom"] .mail-zoomrect{animation-name:mail-rects-short}
@keyframes mail-rects-short{0%{visibility:visible;left:82px;top:max(2px,calc(58px - var(--mail-a)));width:132px;height:min(132px,calc(var(--mail-sh) - 4px))}
  10%{visibility:visible;left:62px;top:max(2px,calc(44px - var(--mail-a)));width:172px;height:min(140px,calc(var(--mail-sh) - 4px))}
  20%{visibility:visible;left:42px;top:2px;width:212px;height:calc(var(--mail-sh) - 4px)}
  30%{visibility:visible;left:22px;top:2px;width:252px;height:calc(var(--mail-sh) - 4px)}
  40%{visibility:visible;left:2px;top:2px;width:292px;height:calc(var(--mail-sh) - 4px)}50%,100%{visibility:hidden}}
html.mail-short #mail[data-tier="big"][data-state="result"] .mail-stage{box-shadow:0 0 0 2px #fff,0 0 0 6px #000}
html.mail-short #mail[data-gold="1"] .mail-stage{box-shadow:0 0 0 2px #fff,0 0 0 6px #f2be48,0 0 0 8px #000}
html.mail-short #mail[data-state="result"] .mail-plate{top:0;bottom:auto;height:24px;border-top:0;border-bottom:2px solid #000}
html.mail-short #mail[data-state="result"] .mail-result{top:0;bottom:auto;height:22px;font-size:20px;line-height:22px}
html.mail-short #mail[data-state="result"][data-tier="big"] .mail-burst{top:calc(-26px - var(--mail-b));height:calc(52px + var(--mail-sh) + var(--mail-b))}
html.mail-short #mail[data-state="result"][data-tier="jackpot"] .mail-burst{top:calc(-36px - var(--mail-b));height:calc(62px + var(--mail-sh) + var(--mail-b))}
/* a short phone: the window keeps to the width */
@media (max-width:319px){.mail-stage{left:0}}
/* reduced motion: no slide, no iris, no zoom, no shake, no flash; every state's last frame at once */
@media (prefers-reduced-motion:reduce){
  #mail *,#mail *::before{animation:none!important}
  #mail[data-flash="1"] .mail-flash{display:none}
}
