/* Mii Plaza + Mii editor. A deliberate change of voice from the chat: a bright Wii plaza floor,
   rounded type, white pill buttons, red for "you" and selection (the red and white theme). See DESIGN.md. */
@font-face { font-family: "M PLUS Rounded 1c"; font-weight: 500; font-style: normal; font-display: swap; src: url(/fonts/MPLUSRounded1c-500.woff2) format("woff2"); }
@font-face { font-family: "M PLUS Rounded 1c"; font-weight: 800; font-style: normal; font-display: swap; src: url(/fonts/MPLUSRounded1c-800.woff2) format("woff2"); }

/* .pz-vars carries the plaza tokens outside the plaza too (the game screens in games.css). */
.plaza, .pz-vars {
  --pz-world: #000000;    /* the pitch black beyond the Black Lodge's curtains (Ethan: no more brown), in light and dark mode */
  --pz-sky: #fde3e4;
  --pz-floor: #fcf6f6;
  --pz-grid: #f3e3e4;
  --pz-chrome: #ffffff;
  --pz-ink: #45282c;
  --pz-ink-2: #8e6d71;
  --pz-line: #eccfd1;
  --pz-blue: #e0202a;      /* your marker, selection rings (red now; the name stays) */
  --pz-bar: #c3121b;       /* the top bar and the main button (white text reads on it) */
  --pz-rounded: "M PLUS Rounded 1c", "Hiragino Maru Gothic ProN", var(--font);
  --mw: 62px;
}
.plaza {
  position: fixed; left: 0; right: 0; top: var(--app-top, 0px); height: var(--app-h); z-index: 25;
  display: flex; flex-direction: column; max-width: 1100px; margin: 0 auto;
  background: var(--pz-floor); color: var(--pz-ink); font-family: var(--pz-rounded); font-weight: 500;
  opacity: 0; transform: scale(.985); transition: opacity .2s, transform .2s;
}
.plaza.in { opacity: 1; transform: none; }
/* typing in the Lobby (member request): the keyboard slides over the floor instead of shrinking it (app.js fitViewport) */
html.kb-over .plaza { height: var(--app-full, var(--app-h)); }
html.kb-over body.tabs-on .plaza { height: calc(var(--app-full, var(--app-h)) - var(--tabs-y, 0px)); }
@media (prefers-color-scheme: dark) {
  .plaza, .pz-vars {
    --pz-sky: #1c1c1c; --pz-floor: #000000; --pz-grid: #141414; --pz-chrome: #000000;
    --pz-ink: #ffffff; --pz-ink-2: #a8a8a8; --pz-line: #333333; --pz-blue: #ff4b53; --pz-bar: #a10f18;
  }
}
/* Themes (member request, Ethan: "change the theme of the bii lobby back to the clean white Bii lobby ... add a personalize
   option so users can pick the basic themes for their version"): #plaza[data-theme] (plaza.js THEMES) sets the lobby's own
   chrome (bars, hint, cards, bubbles, My Biis, the editor) to match its world, in light and dark mode alike.
   --pz-lift: how much of a member's colour to keep in names; the dark themes mix the rest toward white so deep ones read. */
.plaza { --pz-lift: 100%; }
.plaza[data-theme="white"] {
  --pz-world: #ffffff; --pz-sky: #fde3e4; --pz-floor: #fcf6f6; --pz-grid: #f3e3e4; --pz-chrome: #ffffff;
  --pz-ink: #45282c; --pz-ink-2: #8e6d71; --pz-line: #eccfd1; --pz-blue: #e0202a; --pz-bar: #c3121b;
}
/* the Black Lodge: pitch black with white ink (Ethan: "replace the ugly brown ... with pitch black") */
.plaza[data-theme="lodge"] {
  --pz-world: #000000; --pz-sky: #1c1c1c; --pz-floor: #000000; --pz-grid: #141414; --pz-chrome: #000000;
  --pz-ink: #ffffff; --pz-ink-2: #a8a8a8; --pz-line: #333333; --pz-blue: #ff4b53; --pz-bar: #c3121b; --pz-lift: 55%;
}
.plaza[data-theme="night"] {
  --pz-world: #0a1230; --pz-sky: #1a2552; --pz-floor: #0a1230; --pz-grid: #131d45; --pz-chrome: #0d1638;
  --pz-ink: #f1f3ff; --pz-ink-2: #9ba5cf; --pz-line: #27336a; --pz-blue: #ff4b53; --pz-bar: #c3121b; --pz-lift: 55%;
}
.plaza[data-theme="meadow"] {
  --pz-world: #cdeaf8; --pz-sky: #dff1d2; --pz-floor: #f5faef; --pz-grid: #e3efd8; --pz-chrome: #ffffff;
  --pz-ink: #22341b; --pz-ink-2: #5f7955; --pz-line: #cfe2c1; --pz-blue: #e0202a; --pz-bar: #c3121b;
}
.plaza[data-theme="bubblegum"] {
  --pz-world: #ffe4f0; --pz-sky: #ffe0ee; --pz-floor: #fff4f9; --pz-grid: #fbe3ee; --pz-chrome: #ffffff;
  --pz-ink: #4c2139; --pz-ink-2: #9b6a86; --pz-line: #f7c9dd; --pz-blue: #e0202a; --pz-bar: #c3121b;
}
body.in-plaza { background: var(--felt); }
@media (min-width: 1101px) { .plaza { box-shadow: 0 0 0 1px var(--rule); } }

/* top bar */
.pz-top { flex: none; display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: center; gap: 10px;
  padding: calc(10px + env(safe-area-inset-top)) 12px 10px; background: var(--pz-bar); color: #fff; }
.pz-top > :first-child { justify-self: start; }
.pz-top > :last-child { justify-self: end; }
.pz-title { margin: 0; font: 800 21px/1.1 var(--pz-rounded); letter-spacing: .01em; white-space: nowrap; }
.pz-spacer { width: 1px; }

.pz-btn { min-height: 44px; padding: 9px 17px; border-radius: 99px; border: 2px solid var(--pz-line); background: var(--pz-chrome); color: var(--pz-ink);
  font: 800 15px/1 var(--pz-rounded); box-shadow: inset 0 -3px 0 #0000000f; white-space: nowrap; }
.pz-btn:active { transform: translateY(1px); box-shadow: inset 0 -1px 0 #0000000f; }
.pz-btn:disabled { opacity: .55; }
.pz-top .pz-btn { border-color: #ffffff; }
.pz-btn.blue { background: var(--pz-bar); border-color: var(--pz-bar); color: #fff; }
.pz-top .pz-btn.blue { background: #fff; color: var(--pz-bar); }
@media (prefers-color-scheme: dark) { .pz-top .pz-btn { border-color: #ffffff40; } .pz-top .pz-btn.blue { background: #fff; color: #a10f18; } }
.pz-btn.small { min-height: 40px; padding: 7px 14px; font-size: 14.5px; }
.pz-link { background: none; border: 0; padding: 8px 4px; min-height: 40px; color: var(--pz-blue); font: 800 14px/1.2 var(--pz-rounded); text-decoration: underline; text-underline-offset: 3px; }
.pz-link.danger { color: var(--danger); }
.plaza :focus-visible { outline: 3px solid var(--pz-blue); outline-offset: 2px; }

/* the floor */
.pz-floor { position: relative; flex: 1; overflow: hidden; touch-action: none; cursor: grab; user-select: none; -webkit-user-select: none;
  background: var(--pz-world);
}
/* bug fix (Ethan): the floor is its own layer, so nothing drawn on it (bubbles, placards, markers) climbs over the text bar */
.pz-floor { isolation: isolate; }
/* The dock (member requests, Ethan): a strip across the Lobby's head, right under the Chat / Change / Lobby bar, over the
   floor. #pzCam is the row in it: your own tools (tamagotchi, sparkle), then the places (arcade, paint, blocks, movies,
   events: plaza.js PLACES); their menus and trays drop down from it over the floor.
   Cells share the width on a phone and stop growing at 60px on a wide screen; the frame colour shows through the 2px
   gaps as the dividers, the same between every pair of cells (member request, Ethan). */
.pz-dock { flex: none; position: relative; z-index: 3500; background: var(--pz-chrome);
  border-bottom: 2px solid var(--pz-line); cursor: default; }
.pz-cam { position: relative; display: flex; gap: 2px; max-width: calc(11 * 62px); margin: 0 auto; background: var(--pz-line); }
.pz-cam-b { flex: 1 1 0; min-width: 0; height: 48px; padding: 0; margin: 0; display: grid; place-items: center; background: var(--pz-chrome); color: var(--pz-ink);
  border: 0; border-radius: 0; -webkit-tap-highlight-color: transparent; cursor: pointer; }
.pz-cam-b svg { width: 22px; height: 22px; fill: currentColor; }
.pz-cam-b:active { transform: translateY(1px); }
/* Pixel icons (member request, Ethan): 12 x 12 one-bit sprites at 2px a pixel, a tamagotchi monster first and the rest
   drawn to match. The monster's face is your Bii's mood, no meter (member request, Ethan): a smile, a flat mouth once
   a meter is under half (.meh), a frown once one runs low (.hungry), blinking now and then. */
.pz-cam-b svg.px { width: 24px; height: 24px; shape-rendering: crispEdges; }
/* Group cells (member request, Ethan): the arcade (arcade + high scores). Open, it goes header red and its rows drop
   down under it like the moves menu. */
.pz-cam-b.group[aria-pressed="true"] { background: var(--pz-bar); color: #fff; }
.pz-group { transform-origin: 30px 0; }
.pz-group .pz-act { width: auto; min-width: 118px; }
.pz-cam-b.tama .tm { opacity: 0; }
.pz-cam-b.tama .tm-ok, .pz-cam-b.tama.meh .tm-meh, .pz-cam-b.tama.hungry .tm-sad { opacity: 1; animation: pz-blink1 4.3s steps(1) infinite; }
.pz-cam-b.tama .tm-blink, .pz-cam-b.tama.meh .tm-mehblink, .pz-cam-b.tama.hungry .tm-sadblink { animation: pz-blink2 4.3s steps(1) infinite; }
@keyframes pz-blink1 { 94% { opacity: 0; } 97% { opacity: 1; } }
@keyframes pz-blink2 { 94% { opacity: 1; } 97% { opacity: 0; } }
.pz-cam-b.tama:is(.meh, .hungry) :is(.tm-ok, .tm-blink) { opacity: 0; animation: none; }
@media (prefers-reduced-motion: reduce) { .pz-cam-b.tama .tm { animation: none !important; } }
.pz-ripple { position: absolute; width: 34px; height: 14px; margin: -7px 0 0 -17px; border-radius: 50%; border: 2.5px solid var(--pz-blue); pointer-events: none; animation: pz-ripple .55s ease-out forwards; z-index: 1; }
@keyframes pz-ripple { from { transform: scale(.3); opacity: 1; } to { transform: scale(1.5); opacity: 0; } }

/* the 3D floor (mii3d.js draws it) and the overlays that ride on each Mii: name tag at the feet,
   "you" marker, "!" and speech bubble above the head. --hh is the head height in px. */
.pz-canvas { position: absolute; inset: 0; display: block; }
.pm { position: absolute; left: 0; top: 0; width: 0; height: 0; pointer-events: none; will-change: transform; --hh: 120px; }
.pm-me { position: absolute; left: -8px; bottom: calc(var(--hh) + 6px); width: 0; height: 0; pointer-events: none;
  border: 8px solid transparent; border-top: 11px solid var(--pz-blue); border-bottom: 0; animation: pz-marker 1.2s ease-in-out infinite alternate; }
@keyframes pz-marker { to { transform: translateY(-5px); } }
.pm.talking { z-index: 4000 !important; }
.pm.offering { z-index: 4500 !important; }
.pm.offering .pm-bubble { display: none; }
/* Tap a Bii: its card pops up over its head, one solid red block in the section bar's style (member request, Ethan:
   "cleaner, solid red like the top bar"): the bar's #d3121c, white Libre Franklin caps, square corners, no icons. The
   name leads in those caps behind a small hard square in the member's colour; a status line in white under it; then
   the buttons as the bar's cells, split by its faint white hairlines. Gary's card stays Geek Squad black, the hot
   dog's keeps its poem paper. */
.pm-challenge { --pm-red: #d3121c; position: absolute; left: 0; bottom: calc(var(--hh) + 12px); transform: translateX(-50%); pointer-events: auto;
  display: grid; grid-template-columns: repeat(var(--n, 1), minmax(max-content, 1fr)); width: max-content; max-width: calc(100vw - 24px); margin-left: var(--dx, 0px); background: var(--pm-red); color: #fff; white-space: nowrap;
  animation: pz-pop .22s cubic-bezier(.3, 1.6, .5, 1); }
.pm-challenge::after { content: ""; position: absolute; left: clamp(18px, calc(50% - var(--dx, 0px)), calc(100% - 18px)); bottom: -6px; width: 12px; height: 12px;
  margin-left: -6px; background: var(--pm-red); transform: rotate(45deg); }
.pm-challenge.below { bottom: auto; top: 12px; }
.pm-challenge.below::after { bottom: auto; top: -6px; }
.pm-challenge > :not(button) { grid-column: 1 / -1; min-width: 0; }
.pm-challenge button { position: relative; z-index: 1; display: flex; align-items: center; justify-content: center; gap: 6px;
  min-height: 44px; margin: 0; padding: 0 16px; border: 0; background: none; color: #fff; cursor: pointer; -webkit-tap-highlight-color: transparent;
  font: 800 13px/1 "Libre Franklin", "Helvetica Neue", Arial, sans-serif; letter-spacing: .1em; text-transform: uppercase; text-rendering: geometricPrecision; }
.pm-gb { --n: 2; }
.pm-challenge button + button::before { content: ""; position: absolute; left: 0; top: 12px; bottom: 12px; width: 1px; background: rgba(255, 255, 255, .45); }
.pm-challenge button:active { filter: brightness(.94); }
.pm-challenge button:focus-visible { outline: 3px solid #fff; outline-offset: -5px; }
/* the card's top: name, status, what they're up to (stars live on the profile, member request); a faint white hairline (inset like the bar's) over the buttons */
.pm-who { position: relative; display: grid; gap: 4px; padding: 11px 16px 11px; text-align: left; color: #fff; }
.pm-challenge:not(.bare) .pm-who::after { content: ""; position: absolute; left: 12px; right: 12px; bottom: 0; height: 1px; background: rgba(255, 255, 255, .45); }
.pm-who-n { display: block; min-width: 0; overflow: hidden; text-overflow: ellipsis; font: 800 16px/1.1 "Libre Franklin", "Helvetica Neue", Arial, sans-serif;
  letter-spacing: .1em; text-transform: uppercase; color: #fff; text-rendering: geometricPrecision; }
/* the dot by the name: green when they're here, red when they're away (member request, Ethan) */
.pm-who-n::before { content: ""; display: inline-block; width: 10px; height: 10px; margin: 0 9px 0 2px; vertical-align: .05em; border-radius: 50%; background: #ff5a62; box-shadow: 0 0 0 1.5px #fff; }
.pm-who-n.on::before { background: #2fd16c; }
.pm-who-s { display: flex; align-items: center; font: 700 13px/1.2 var(--pz-rounded); color: rgba(255, 255, 255, .82); }
/* what they're up to (member request, Ethan): a live white dot, then the line in white */
.pm-doing { display: flex; align-items: baseline; gap: 7px; width: max-content; max-width: min(260px, calc(100vw - 72px)); margin-top: 1px; white-space: normal; font: 700 14px/1.25 var(--pz-rounded); color: #fff; }
.pm-doing::before { content: ''; flex: none; width: 8px; height: 8px; transform: translateY(-1px); background: #fff; box-shadow: 0 0 0 0 rgba(255, 255, 255, .6); animation: pm-doing 1.8s ease-out infinite; }
@keyframes pm-doing { 0% { box-shadow: 0 0 0 0 rgba(255, 255, 255, .6); } 100% { box-shadow: 0 0 0 7px rgba(255, 255, 255, 0); } }
@media (prefers-reduced-motion: reduce) { .pm-doing::before { animation: none; } }
/* Agent Gary's card: one black "Show me how" bar with a Geek Squad orange underline */
.pm-gs .pm-gs-go { padding: 9px 18px 10px; background: #000; box-shadow: inset 0 -3px 0 #ff6c0c; }
.pm-gs .pm-gs-go::before { display: none; }
.pm-gs .pm-gs-go svg { width: 19px; height: 19px; flex: none; color: #ff6c0c; }
/* the hot dog's poem (member request, Zoe): his card opens on a hot dog stand's paper liner, a red-and-white gingham
   edge over plain napkin paper, and the poem's lines set in one by one as it arrives; "Another poem" underneath */
.pm-poem { white-space: normal; width: min(320px, calc(100vw - 24px)); }
.pm-poem .pm-who-s { font-size: 14px; color: #fff; }
.pm-poem-page { display: grid; min-height: 58px; padding: 24px 16px 14px; color: #45282c; background-color: #fffdf8;
  background-image: repeating-conic-gradient(#d3121c 0 25%, #fff 0 50%); background-size: 12px 12px; background-repeat: repeat-x;
  font: 500 16px/1.5 var(--pz-rounded); text-align: left; }
.pm-poem-page span { display: block; padding-left: 1.1em; text-indent: -1.1em; text-wrap: pretty; animation: pz-line .45s ease-out both; animation-delay: calc(var(--i) * .32s); }
.pm-poem.waiting .pm-poem-page span { opacity: .35; animation: none; }
.pm-poem.waiting .pm-who-s { color: rgba(255, 255, 255, .7); }
.pm-poem .pm-poem-more { padding: 9px 18px 10px; }
@keyframes pz-line { from { opacity: 0; transform: translateY(4px); } }
@media (prefers-reduced-motion: reduce) { .pm-poem-page span { animation: none; } }
.pm.offering .pm-me { display: none; }
.pm.talking .pm-me { display: none; }
.pm-bubble { position: absolute; left: 0; bottom: calc(var(--hh) + 10px); transform: translateX(-50%); width: max-content; max-width: 168px; pointer-events: none;
  padding: 7px 11px 8px; border-radius: 14px; background: var(--pz-chrome); color: var(--pz-ink); border: 2px solid var(--pz-line);
  font: 500 14px/1.3 var(--pz-rounded); overflow-wrap: anywhere; animation: pz-pop .22s cubic-bezier(.3, 1.6, .5, 1); }
.pm-bubble::after { content: ""; position: absolute; left: 50%; bottom: -8px; width: 12px; height: 12px; margin-left: -6px; background: inherit;
  border: solid var(--pz-line); border-width: 0 2px 2px 0; transform: rotate(45deg); }
.pm-bubble .blood { font-style: normal; }
.pm-bubble .grawlix { font-family: "Comic Sans MS", "Comic Neue", "Chalkboard SE", "Comic Sans", cursive; font-weight: 700; font-style: normal; white-space: nowrap; }
@keyframes pz-pop { from { transform: translateX(-50%) scale(.6); opacity: 0; } }
.pm-bang { position: absolute; left: 14px; bottom: calc(var(--hh) - 4px); font: 800 28px/1 var(--pz-rounded); color: #f0532d; opacity: 0; pointer-events: none; }
.pm.emo-poked .pm-bang { animation: pz-bang 1.1s ease-out; }
@keyframes pz-bang { 0% { opacity: 0; transform: translateY(6px) scale(.5); } 15% { opacity: 1; transform: none; } 75% { opacity: 1; } 100% { opacity: 0; transform: translateY(-6px); } }
/* sleepers lie on the floor: z's drift up off the head (which lies toward --side * -1) */
.pm-zzz { display: none; position: absolute; left: calc(var(--side, 1) * var(--hh) * -.55); bottom: calc(var(--hh) - 6px); width: 0; height: 0; pointer-events: none; }
.pm.sleeping .pm-zzz { display: block; }
.pm-zzz i { position: absolute; left: 0; bottom: 0; font: 800 15px/1 var(--pz-rounded); font-style: normal; color: var(--pz-ink-2); opacity: 0;
  animation: pz-zzz-r 3.6s ease-out infinite; will-change: transform, opacity; }
.pm-zzz.flip i { animation-name: pz-zzz-l; }
.pm-zzz i:nth-child(2) { font-size: 19px; animation-delay: 1.2s; }
.pm-zzz i:nth-child(3) { font-size: 24px; animation-delay: 2.4s; }
/* Bug fix (Ethan: the z's didn't move): iOS Safari doesn't animate var() inside @keyframes, so each side gets its own
   keyframes (plaza.js mkEl adds .flip for side -1), and they keep drifting under Reduce Motion (a slow, small float). */
@keyframes pz-zzz-r {
  0% { opacity: 0; transform: translate(0, 0) rotate(-8deg) scale(.6); }
  15% { opacity: .9; }
  45% { transform: translate(-8px, -20px) rotate(4deg) scale(.82); }
  70% { opacity: .7; }
  100% { opacity: 0; transform: translate(-26px, -46px) rotate(8deg) scale(1); }
}
@keyframes pz-zzz-l {
  0% { opacity: 0; transform: translate(0, 0) rotate(8deg) scale(.6); }
  15% { opacity: .9; }
  45% { transform: translate(8px, -20px) rotate(-4deg) scale(.82); }
  70% { opacity: .7; }
  100% { opacity: 0; transform: translate(26px, -46px) rotate(-8deg) scale(1); }
}
.pm.sleeping .pm-bang { left: calc(var(--side, 1) * var(--hh) * -.55); }
@media (prefers-reduced-motion: reduce) {
  .pm-me { animation: none; }
  .pm-zzz i { animation-duration: 4.8s !important; animation-iteration-count: infinite !important; }
  .pm-zzz i:nth-child(2) { animation-delay: 1.6s; }
  .pm-zzz i:nth-child(3) { animation-delay: 3.2s; }
}


/* bottom bar (Personalize's looks, Fire): the Lobby's foot now the dock is up top, so it holds the bottom safe area */
.pz-bottom { flex: none; grid-template-columns: minmax(0, 1fr); background: var(--pz-chrome); border-top: 2px solid var(--pz-line); padding: 8px 12px calc(10px + var(--sab)); display: grid; gap: 8px; }
.pz-emotes { display: flex; gap: 8px; }
/* with nothing to show (no look or Fire), the bar goes and the floor runs down to the screen's bottom edge */
.kb-open .pz-bottom { padding-bottom: 10px; }
.plaza:not(:has(> .pz-bottom > :not(.pz-emotes):not([hidden]), > .pz-bottom > .pz-emotes > :not([hidden]))) > .pz-bottom { display: none; }
/* who's here (member request, Ethan: "add the active bii bar back"): the chat's row of flat 2D Bii heads (style.css .here-*)
   at the Lobby's foot, in the theme's chrome. It holds the bottom safe area, so the bar above drops its own; names keep
   the member's colour, lifted toward white on the dark themes (--pz-lift). Gone while the keyboard is up, like the chat's. */
.pz-here { flex: none; display: flex; gap: 4px; padding: 6px 10px calc(4px + var(--sab)); overflow-x: auto; background: var(--pz-chrome);
  overscroll-behavior-x: contain; scrollbar-width: none; -webkit-overflow-scrolling: touch; border-top: 2px solid var(--pz-line); }
.pz-here::-webkit-scrollbar { display: none; }
.plaza > .pz-bottom:has(+ .pz-here) { padding-bottom: 8px; }
.kb-open .pz-here { display: none; }
.kb-open .plaza > .pz-bottom:has(+ .pz-here) { padding-bottom: 10px; }
.pz-here .here-p { color: color-mix(in srgb, var(--c, var(--pz-ink)) var(--pz-lift), #fff); font: 800 12px/1.2 var(--pz-rounded); }
.pz-here .here-note { color: var(--pz-ink-2); font-family: var(--pz-rounded); }

/* Talking (member request, Ethan: no say bar; a speech bubble button, and the text box is the bubble over your Bii).
   #pzDraft is the pz-bubble you're writing: your red "you" line while the keyboard is up, dashed and faded once you tap
   away with it unsent, the plain bubble line the moment it's sent (then the real bubble takes over). The red square
   holds a one-bit up arrow, like the column. plaza.js placeDraft sets its spot and --tail. */
.pz-draft { position: absolute; left: 0; top: 0; z-index: 4800; display: flex; align-items: flex-end; gap: 6px; width: max-content;
  max-width: min(272px, calc(100% - 16px)); padding: 4px 4px 4px 12px; border-radius: 14px; background: var(--pz-chrome);
  border: 2px solid var(--pz-blue); color: var(--pz-ink); pointer-events: auto; cursor: text; touch-action: manipulation;
  animation: pz-draft .2s cubic-bezier(.3, 1.6, .5, 1); transform-origin: var(--tail, 50%) 100%; }
.pz-draft[hidden] { display: none; }
.pz-draft::after { content: ""; position: absolute; left: var(--tail, 50%); bottom: -8px; width: 12px; height: 12px; margin-left: -6px;
  background: inherit; border: inherit; border-width: 0 2px 2px 0; transform: rotate(45deg); }
.pz-draft.untailed::after { display: none; }
@keyframes pz-draft { from { opacity: 0; scale: .7; } }
.pz-draft-in { display: grid; flex: 1; min-width: 7.5em; padding: 6px 0 5px; }
.pz-draft-in::after { content: attr(data-v) " "; visibility: hidden; white-space: pre-wrap; overflow-wrap: anywhere; }
.pz-draft-in::after, .pz-draft textarea { grid-area: 1 / 1; max-height: 6.5em; overflow: hidden; font: 500 17px/1.3 var(--pz-rounded); } /* five lines, then it scrolls */
.pz-draft textarea { width: 0; min-width: 100%; margin: 0; padding: 0; border: 0; border-radius: 0; background: none; color: inherit;
  resize: none; overflow-y: auto; outline: none; caret-color: var(--pz-blue); overflow-wrap: anywhere; -webkit-appearance: none; appearance: none; }
.pz-draft textarea:focus-visible { outline: none; } /* the bubble's red line is the focus */
.pz-draft textarea::placeholder { color: var(--pz-ink-2); opacity: 1; }
.pz-draft-go { flex: none; width: 36px; height: 36px; margin: 0; padding: 0; display: grid; place-items: center; border: 0;
  background: var(--pz-bar); color: #fff; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.pz-draft-go svg.px { width: 24px; height: 24px; fill: currentColor; shape-rendering: crispEdges; }
.pz-draft.idle { border-style: dashed; color: var(--pz-ink-2); }
.pz-draft.idle .pz-draft-go { display: none; }
.pz-draft.idle { padding-right: 12px; }
.pz-draft.sending { border-color: var(--pz-line); }
.pz-draft.sending .pz-draft-go { visibility: hidden; }
.plaza.talk .pm-me, .plaza.talk .pz-floor > .pm:has(.pm-me) .pm-bubble { display: none; }
.plaza.look .pz-draft { display: none; }
@media (prefers-reduced-motion: reduce) { .pz-draft { animation: none; } }

/* panels (My Miis, editor) slide over the floor */
.pz-panel { position: absolute; inset: 0; z-index: 5000; display: flex; flex-direction: column; background: var(--pz-floor);
  opacity: 0; transform: translateY(14px); transition: opacity .2s, transform .22s cubic-bezier(.2, .8, .2, 1); }
.pz-panel.in { opacity: 1; transform: none; }
.pz-scroll { flex: 1; overflow-y: auto; padding: 16px 14px calc(24px + var(--sab)); overscroll-behavior: contain; }
.pz-lede { margin: 0 0 16px; color: var(--pz-ink-2); font-size: 15.5px; line-height: 1.45; max-width: 52ch; }

.mc-grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); gap: 12px; }
.mc { display: flex; flex-direction: column; align-items: center; gap: 4px; }
.mc-pick { width: 100%; display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 12px 8px 10px; border-radius: 18px;
  border: 2px solid var(--pz-line); background: var(--pz-chrome); color: var(--pz-ink); font-family: var(--pz-rounded); }
.mc-pick .mc-fig { width: 76px; height: 129px; opacity: 0; transition: opacity .15s; }
.mc-pick .mc-fig.in { opacity: 1; }
.mc-pick .mc-cutout { object-fit: contain; }
.mc.main .mc-pick { border-color: var(--pz-blue); box-shadow: inset 0 0 0 1.5px var(--pz-blue); }
.mc-name { font-weight: 800; font-size: 15px; }
.mc-flag { min-height: 40px; display: grid; place-items: center; font-weight: 800; font-size: 14px; color: var(--pz-blue); }
.mc-new { justify-content: center; min-height: 185px; border-style: dashed; }
.mc-new .plus { font: 800 44px/1 var(--pz-rounded); color: var(--pz-blue); }

/* editor */
.ed-stage { position: relative; flex: none; height: clamp(190px, 34vh, 340px); padding: 0; background: var(--pz-sky); border-bottom: 2px solid var(--pz-line); display: flex; justify-content: center; overflow: hidden; }
.ed-mii { width: 100%; height: 100%; }
.ed-canvas { display: block; width: 100%; height: 100%; touch-action: none; cursor: grab; }
.ed-mii > .mii { display: block; height: 100%; width: auto; margin: 0 auto; aspect-ratio: 100 / 170; overflow: visible; }
.ed-shuffle { position: absolute; right: 12px; bottom: 12px; }
.ed-name { flex: none; display: flex; align-items: center; gap: 10px; padding: 10px 14px; background: var(--pz-chrome); border-bottom: 2px solid var(--pz-line); font-weight: 800; font-size: 15px; }
.ed-name input { flex: 1; min-width: 0; min-height: 42px; padding: 8px 14px; border-radius: 12px; border: 2px solid var(--pz-line); background: var(--pz-floor); color: var(--pz-ink); font: 800 17px/1.2 var(--pz-rounded); outline: none; }
.ed-name input:focus { border-color: var(--pz-blue); }
.ed-tabs { flex: none; display: flex; gap: 6px; overflow-x: auto; padding: 10px 12px; scrollbar-width: none; background: var(--pz-chrome); border-bottom: 2px solid var(--pz-line); }
.ed-tabs::-webkit-scrollbar { display: none; }
.ed-tabs button { flex: none; min-height: 40px; padding: 7px 14px; border-radius: 99px; border: 2px solid var(--pz-line); background: var(--pz-floor); color: var(--pz-ink-2); font: 800 14.5px/1 var(--pz-rounded); }
.ed-tabs button[aria-selected="true"] { border-color: var(--pz-blue); background: var(--pz-chrome); color: var(--pz-ink); box-shadow: inset 0 0 0 1.5px var(--pz-blue); }
.ed-pane { flex: 1; overflow-y: auto; padding: 14px 12px calc(20px + var(--sab)); overscroll-behavior: contain; }
.ed-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(74px, 1fr)); gap: 8px; }
.opt { aspect-ratio: 1; padding: 4px; border-radius: 16px; border: 2px solid var(--pz-line); background: var(--pz-chrome); display: grid; place-items: center; }
.opt .mii-face, .opt img { width: 100%; height: 100%; display: block; }
.opt img { opacity: 0; transition: opacity .15s; }
.opt img.in { opacity: 1; }
.opt.on { border-color: var(--pz-blue); box-shadow: inset 0 0 0 2px var(--pz-blue); background: var(--pz-sky); }
.ed-swatches { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 16px; }
.sw { width: 42px; height: 42px; border-radius: 50%; background: var(--sw); border: 2px solid #00000024; }
.sw.on { box-shadow: 0 0 0 3px var(--pz-floor), 0 0 0 6px var(--pz-blue); }
.ed-sub { margin: 20px 0 0; font-weight: 800; font-size: 15px; }
.ed-slider { display: grid; grid-template-columns: 64px 1fr; align-items: center; gap: 12px; min-height: 48px; font-weight: 800; font-size: 15px; }
.ed-slider input { width: 100%; accent-color: var(--pz-bar); height: 32px; }
.ed-del { display: block; margin: 22px auto 0; }
/* Pokémon tab (member request, Ethan: hide your follower): a Poké Ball that pops open while it's out, two big choices. */
.ed-pet-ball { flex: none; position: relative; width: 64px; height: 64px; border-radius: 50%; border: 3px solid var(--pz-ink);
  background: linear-gradient(var(--pz-bar) 0 calc(50% - 2px), var(--pz-ink) 0 calc(50% + 2px), #fff 0); transition: transform .25s; }
.ed-pet-ball::after { content: ""; position: absolute; left: 50%; top: 50%; width: 16px; height: 16px; margin: -11px 0 0 -11px; border-radius: 50%; border: 3px solid var(--pz-ink); background: #fff; }
.ed-pet-ball.out { transform: rotate(-18deg); background: linear-gradient(var(--pz-bar) 0 calc(42% - 2px), var(--pz-ink) 0 calc(42% + 2px), #fff 0); }
.ed-pet-pick { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 16px; }
.ed-pet-opt { aspect-ratio: auto; min-height: 56px; color: var(--pz-ink); font: 800 16px/1.2 var(--pz-rounded); }
@media (prefers-reduced-motion: reduce) { .ed-pet-ball { transition: none; } }
/* Drawn face, mix and match (member request, Ethan): each part Drawn or Ready-made. The Face tab's grid shows them all;
   a part's own tab has the two big choices (.ed-keep-pick) over its list. */
.ed-keep { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 8px; margin: 4px 0 16px; }
.ed-keep-b { display: grid; gap: 3px; min-height: 52px; padding: 7px 10px; border-radius: 14px; border: 2px dashed color-mix(in srgb, var(--pz-ink-2) 55%, transparent); background: var(--pz-floor);
  color: var(--pz-ink); text-align: left; font: 800 15px/1.15 var(--pz-rounded); }
.ed-keep-b span { font-weight: 700; font-size: 12.5px; color: var(--pz-ink-2); }
.ed-keep-b.on { border-style: solid; border-color: var(--pz-blue); background: var(--pz-sky); box-shadow: inset 0 0 0 1.5px var(--pz-blue); }
.ed-keep-b.on span { color: var(--pz-blue); }
.ed-keep-pick { margin: 0 0 12px; }

/* the chat header's door to the plaza: your own Mii's face */

/* The mech and henry's centipede: the owner's red "Fire"/"Bite" pill, the "!" when a laser or bite hits, and the floor shaking on impact. */
.pz-btn.fire { margin-left: auto; background: var(--pz-bar); border-color: var(--pz-bar); color: #fff; }
.pz-btn[hidden] { display: none; }
.pm.emo-zapped .pm-bang { animation: pz-bang 1.3s ease-out; }
.pz-floor.shake { animation: pz-shake .34s linear; }
@keyframes pz-shake { 0%, 100% { transform: none; } 20% { transform: translate(-5px, 2px); } 40% { transform: translate(4px, -3px); } 60% { transform: translate(-3px, 1px); } 80% { transform: translate(2px, -1px); } }
@media (prefers-reduced-motion: reduce) { .pz-floor.shake { animation: none; } }


/* Personalize (member request, Ethan: pick the Lobby's theme, just for you): the sparkle button fills red
   while open; the chat bar gives way to a row of theme tiles, each a tiny window onto that floor with your own Bii
   standing on it. Picking one repaints the Lobby behind at once; the picked tile gets the "you" ring. */
.pz-cam-b.look[aria-pressed="true"] { background: var(--pz-bar); color: #fff; }
.plaza.look .pz-emotes { display: none; }
.pz-look { display: grid; gap: 10px; }
.pz-look[hidden] { display: none; }
.pz-look-top { display: flex; align-items: center; gap: 8px; }
.pz-look-say { flex: 1; min-width: 0; margin: 0; font: 800 16px/1.25 var(--pz-rounded); color: var(--pz-ink); }
.pz-themes { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: clamp(5px, 1.8vw, 8px); max-width: 460px; }
.pz-theme { display: flex; flex-direction: column; align-items: stretch; gap: 6px; min-width: 0; margin: 0; padding: 0; border: 0; background: none;
  color: var(--pz-ink-2); font: 800 clamp(10.5px, 3vw, 12px)/1.15 var(--pz-rounded); letter-spacing: -.01em; text-align: center; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.pz-theme[aria-checked="true"] { color: var(--pz-ink); }
.pz-theme-n { min-height: 2.3em; }
.pz-theme-pic { position: relative; display: block; aspect-ratio: 1 / 1.08; overflow: hidden; background: var(--t-sky); outline: 1.5px solid var(--pz-line); outline-offset: -1.5px; }
.pz-theme[aria-checked="true"] .pz-theme-pic { outline: 3px solid var(--pz-blue); outline-offset: 2px; }
.pz-theme:active .pz-theme-pic { transform: translateY(1px); }
.pz-theme-floor { position: absolute; left: 0; right: 0; bottom: 0; height: 50%; background: var(--t-floor); }
.pz-theme-floor::after { content: ""; position: absolute; left: 22%; right: 22%; top: 30%; height: 16%; border-radius: 50%; background: radial-gradient(closest-side, #0000004d, #0000); }
.pz-theme-bii { position: absolute; left: 50%; bottom: 29%; width: 62%; transform: translateX(-50%); }
.pz-theme-bii .mface, .pz-theme-bii img, .pz-theme-bii svg { display: block; width: 100%; height: auto; }
.pz-theme[data-theme="white"] { --t-sky: #ffffff; --t-floor: #ffffff; }
.pz-theme[data-theme="lodge"] { --t-sky: repeating-linear-gradient(90deg, #6e0912 0 2px, #b0101d 2px 6px, #8e0c16 6px 8px);
  --t-floor: linear-gradient(135deg, #e4dccd 25%, #0000 25%) -5px 0 / 10px 10px, linear-gradient(225deg, #e4dccd 25%, #0000 25%) -5px 0 / 10px 10px,
    linear-gradient(315deg, #e4dccd 25%, #0000 25%) 0 0 / 10px 10px, linear-gradient(45deg, #e4dccd 25%, #0000 25%) 0 0 / 10px 10px, #000; }
.pz-theme[data-theme="night"] { --t-sky: radial-gradient(1px 1px at 18% 22%, #fff 99%, #0000), radial-gradient(1px 1px at 72% 14%, #fff 99%, #0000),
    radial-gradient(1.5px 1.5px at 44% 34%, #dfe6ff 99%, #0000), radial-gradient(1px 1px at 86% 38%, #fff 99%, #0000), #0a1230; --t-floor: #131d45; }
.pz-theme[data-theme="meadow"] { --t-sky: #cdeaf8; --t-floor: repeating-linear-gradient(90deg, #b3dc93 0 9px, #a9d487 9px 18px); }
.pz-theme[data-theme="bubblegum"] { --t-sky: #ffe4f0; --t-floor: #ffe4f0; }
.pz-theme[data-theme="night"] .pz-theme-floor::after, .pz-theme[data-theme="lodge"] .pz-theme-floor::after { background: radial-gradient(closest-side, #000a, #0000); }
.pm[data-key="jesus"] .pm-bubble { max-width: 220px; } /* his verses run long (plaza.js plaza-say) */

/* Hunger (member request, Ethan: a feed button next to dance). A 4px strip along Feed's foot is your Bii's belly,
   emptying over three days, in the header red on a frame-colour track (the dock's palette, member request); it blinks
   once it's hungry. An empty meter never kills the Bii (member request). */
.pz-feed { position: relative; overflow: hidden; }
.pz-feed-l { display: inline-flex; align-items: center; gap: 5px; }
.pz-belly { position: absolute; left: 0; right: 0; bottom: 0; height: 4px; background: var(--pz-line); pointer-events: none; }
.pz-belly b { display: block; height: 100%; width: calc(var(--belly, 1) * 100%); background: var(--pz-bar); transition: width .4s; }
.pz-feed.hungry .pz-belly b { animation: pz-belly 1.1s ease-in-out infinite alternate; }
@keyframes pz-belly { to { opacity: .45; } }
@media (prefers-reduced-motion: reduce) { .pz-feed.hungry .pz-belly b { animation: none; } }
/* The moves menu (member request, Ethan: Wave, Jump, Dance and Feed moved off the bottom bar into a tamagotchi at the
   first cell of the dock). Open, the tamagotchi goes header red like every open dock cell (member request) and a
   column of moves drops down under it, lined up
   with the dock's left edge. Each row leads with a 12 x 12 one-bit icon in the button row's own style and ink
   (member request, Ethan), flipping between two frames once a second like the toy does. Shut, the
   tamagotchi's face shows the mood. */
.pz-cam-b.tama[aria-pressed="true"] { background: var(--pz-bar); color: #fff; }
.pz-tama { position: absolute; left: 0; top: calc(100% + 10px); display: flex; flex-direction: column;
  border: 2px solid var(--pz-line); background: var(--pz-line); transform-origin: 22px 0; animation: pz-tama .16s ease-out; }
.pz-tama[hidden] { display: none; }
@keyframes pz-tama { from { opacity: 0; transform: translateY(-10px) scale(.96); } }
.pz-act { display: flex; align-items: center; gap: 10px; width: 118px; height: 44px; margin: 0; padding: 0 12px 0 10px; border: 0;
  background: var(--pz-chrome); color: var(--pz-ink); font: 800 15.5px/1 var(--pz-rounded); text-align: left; white-space: nowrap;
  -webkit-tap-highlight-color: transparent; cursor: pointer; }
.pz-tama > :not(:first-child) { border-top: 2px solid var(--pz-line); }
.pz-act:active { transform: translateY(1px); }
.pz-act:disabled { opacity: .45; cursor: default; }
.pz-ico { flex: none; display: block; width: 24px; height: 24px; fill: currentColor; shape-rendering: crispEdges; }
.pz-ico .f2 { opacity: 0; }
.plaza.tama .pz-act:not(:disabled) .pz-ico .f1 { animation: pz-ico1 1.1s steps(1) infinite; }
.plaza.tama .pz-act:not(:disabled) .pz-ico .f2 { animation: pz-ico2 1.1s steps(1) infinite; }
@keyframes pz-ico1 { 50% { opacity: 0; } }
@keyframes pz-ico2 { 50% { opacity: 1; } }
/* Play (member request, Ethan: a play meter that only games fill). Same strip as Feed; tapped, it opens the arcade. */
/* The moves bar (member request, Ethan: Feed, Play, Clean and Dance in a row across the top, under the section bar
   and the dock, in the dock's palette). Upright, #pzTama hangs flush from the dock's foot across its full width like
   the Blocks tray: four equal chrome cells with the dock's 2px frame-colour dividers, icon then label; the meters run
   along each cell's foot in the header red on a frame-colour track. Under 360px the label drops under the icon.
   Landscape keeps the column beside the dock (below). */
@media not all and (orientation: landscape) and (pointer: coarse) {
  #pzTama { left: 0; right: 0; top: 100%; flex-direction: row; gap: 2px; border: 0; border-top: 2px solid var(--pz-line);
    border-bottom: 2px solid var(--pz-line); transform-origin: 50% 0; }
  #pzTama > :not(:first-child) { border-top: 0; }
  #pzTama .pz-act { flex: 1 1 0; width: auto; min-width: 0; height: 48px; justify-content: center; gap: 7px; padding: 0 4px; }
  #pzTama .pz-feed-l { gap: 3px; }
  @media (max-width: 359px) { #pzTama .pz-act { flex-direction: column; gap: 3px; height: 58px; font-size: 13.5px; } }
}
@media (prefers-reduced-motion: reduce) {
  .pz-tama { animation: none; }
  .plaza.tama .pz-act .pz-ico :is(.f1, .f2) { animation: none !important; }
}
.pz-emotes:not(:has(> :not([hidden]))) { display: none; }
@media (max-width: 380px) { .pz-emotes .pz-btn.small { padding-left: 11px; padding-right: 11px; } }
/* The meal: dropped into its hands at the mouth, gone in three chomps, crumbs flying off each one. */
.pm-food { position: absolute; left: 0; bottom: calc(var(--hh) * .52); width: 0; height: 0; pointer-events: none; }
.pm-food span { position: absolute; left: -14px; bottom: 0; font-size: 28px; line-height: 1; transform-origin: 50% 80%;
  animation: pz-food 2s cubic-bezier(.3, .7, .4, 1) both; }
.pm-food i { position: absolute; left: 0; bottom: 8px; width: 5px; height: 5px; background: #f3d9a4; opacity: 0; }
.pm-food i:nth-child(2) { animation: pz-crumb-l .5s ease-out .55s both; }
.pm-food i:nth-child(3) { animation: pz-crumb-r .5s ease-out .95s both; background: #e0a060; }
.pm-food i:nth-child(4) { animation: pz-crumb-l .5s ease-out 1.35s both; }
@keyframes pz-food {
  0% { transform: translateY(-70px) scale(.7); opacity: 0; }
  18% { transform: translateY(0) scale(1); opacity: 1; }
  27% { transform: scale(1); opacity: 1; } 30% { transform: scale(.78) rotate(-6deg); opacity: 1; }
  47% { transform: scale(.78) rotate(-6deg); opacity: 1; } 50% { transform: scale(.52) rotate(5deg); opacity: 1; }
  67% { transform: scale(.52) rotate(5deg); opacity: 1; } 70%, 100% { transform: scale(0); opacity: 0; }
}
/* iOS doesn't animate var() in keyframes, so each side gets its own crumb flight */
@keyframes pz-crumb-l { 0% { opacity: 1; transform: none; } 100% { opacity: 0; transform: translate(-20px, 22px) rotate(90deg); } }
@keyframes pz-crumb-r { 0% { opacity: 1; transform: none; } 100% { opacity: 0; transform: translate(18px, 24px) rotate(-90deg); } }
@media (prefers-reduced-motion: reduce) { .pm-food span { animation-duration: 2.2s; } }
/* A new hot dog lands from the sky (plaza.js dropAir): five dust puffs burst out low from his feet, the floor gives a little thud. */
.pm-poof { position: absolute; left: 0; bottom: 0; width: 0; height: 0; pointer-events: none; }
.pm-poof i { position: absolute; left: -9px; bottom: -6px; width: 18px; height: 12px; border-radius: 50%; background: #fff;
  box-shadow: 0 1px 0 rgba(120, 100, 80, .35); opacity: 0; }
.pm-poof i:nth-child(1) { animation: pz-poof-1 .7s cubic-bezier(.2, .8, .3, 1) both; }
.pm-poof i:nth-child(2) { animation: pz-poof-2 .7s cubic-bezier(.2, .8, .3, 1) both; }
.pm-poof i:nth-child(3) { animation: pz-poof-3 .75s cubic-bezier(.2, .8, .3, 1) both; }
.pm-poof i:nth-child(4) { animation: pz-poof-4 .75s cubic-bezier(.2, .8, .3, 1) both; }
.pm-poof i:nth-child(5) { animation: pz-poof-5 .65s cubic-bezier(.2, .8, .3, 1) both; }
/* one flight per puff (iOS doesn't animate var() in keyframes) */
@keyframes pz-poof-1 { 0% { opacity: .95; transform: scale(.4); } 100% { opacity: 0; transform: translate(-40px, 2px) scale(1.5); } }
@keyframes pz-poof-2 { 0% { opacity: .95; transform: scale(.4); } 100% { opacity: 0; transform: translate(40px, 2px) scale(1.5); } }
@keyframes pz-poof-3 { 0% { opacity: .9; transform: scale(.4); } 100% { opacity: 0; transform: translate(-24px, -14px) scale(1.2); } }
@keyframes pz-poof-4 { 0% { opacity: .9; transform: scale(.4); } 100% { opacity: 0; transform: translate(24px, -14px) scale(1.2); } }
@keyframes pz-poof-5 { 0% { opacity: .9; transform: scale(.5); } 100% { opacity: 0; transform: translate(0, -22px) scale(1.1); } }
.pz-floor.thud { animation: pz-thud .28s ease-out; }
@keyframes pz-thud { 0%, 100% { transform: none; } 30% { transform: translateY(3px); } 65% { transform: translateY(-1px); } }
@media (prefers-reduced-motion: reduce) { .pm-poof { display: none; } .pz-floor.thud { animation: none; } }

.pm-challenge.pm-gs, .pm-challenge.pm-gs::after { border-color: #000; background: #000; }

/* Gloom (member request, Ethan: "as that meter falls, your bii should get increasingly sad"): a Bii crying from
   boredom gets a little grey cloud over its head (.gloom-3); when the play meter is nearly gone it rains (.gloom-4). */
.pm-cloud { display: none; position: absolute; left: 0; bottom: calc(var(--hh) + 10px); width: 40px; height: 22px; margin-left: -20px; pointer-events: none;
  animation: pz-cloud 4.2s ease-in-out infinite; }
.pm.gloom-3 .pm-cloud, .pm.gloom-4 .pm-cloud { display: block; }
.pm.sleeping .pm-cloud { display: none; }
.pm-cloud svg { width: 100%; height: 100%; display: block; overflow: visible; }
.pm-cloud path { fill: #9aa3ad; stroke: #5d6670; stroke-width: 1.4; stroke-linejoin: round; }
.pm.gloom-4 .pm-cloud path { fill: #6f7882; stroke: #424a53; }
.pm-cloud i { display: none; position: absolute; top: 18px; width: 2px; height: 7px; border-radius: 1px; background: #5aa7e0; opacity: 0;
  animation: pz-rain .7s linear infinite; }
.pm.gloom-4 .pm-cloud i { display: block; }
.pm-cloud i:nth-of-type(1) { left: 9px; }
.pm-cloud i:nth-of-type(2) { left: 16px; animation-delay: .35s; }
.pm-cloud i:nth-of-type(3) { left: 23px; animation-delay: .18s; }
.pm-cloud i:nth-of-type(4) { left: 30px; animation-delay: .52s; }
@keyframes pz-cloud { 0%, 100% { transform: translateX(-3px); } 50% { transform: translateX(3px); } }
@keyframes pz-rain { 0% { opacity: 0; transform: translateY(0); } 15% { opacity: .9; } 100% { opacity: 0; transform: translateY(22px); } }
@media (prefers-reduced-motion: reduce) { .pm-cloud { animation: none; } .pm-cloud i { animation-duration: 1.6s; } }
.pm-bubble:not([hidden]) ~ .pm-cloud { display: none !important; }
/* Stink (member request, Ethan: "as the cleanliness meter drops, your bii will become increasingly stinky"): cartoon
   stink lines, olive green, curling up off the body and fading as they rise. .stink-1 a single faint whiff, .stink-2
   three of them, .stink-3 thick and dark with three flies buzzing round its head. plaza.js stinkOf. */
.pm-stink { display: none; position: absolute; left: 0; bottom: calc(var(--hh) * .28); width: calc(var(--hh) * .95); height: calc(var(--hh) * .85);
  margin-left: calc(var(--hh) * -.475); pointer-events: none; }
.pm.stink-1 .pm-stink, .pm.stink-2 .pm-stink, .pm.stink-3 .pm-stink { display: block; }
.pm.sleeping .pm-stink { display: none !important; }
.pm-stink svg { width: 100%; height: 100%; display: block; overflow: visible; }
.pm-stink path { fill: none; stroke: #7c9a2e; stroke-width: 3; stroke-linecap: round; opacity: 0; animation: pz-stink 2.6s ease-in-out infinite; }
.pm-stink path:nth-child(2) { animation-delay: .85s; }
.pm-stink path:nth-child(3) { animation-delay: 1.7s; }
.pm.stink-1 .pm-stink path:not(:nth-child(2)) { display: none; }
.pm.stink-1 .pm-stink path { stroke-width: 2; }
.pm.stink-3 .pm-stink path { stroke: #5d7a1c; stroke-width: 3.4; }
@keyframes pz-stink { 0% { opacity: 0; transform: translateY(10px); } 35% { opacity: .85; } 100% { opacity: 0; transform: translateY(-14px); } }
.pm-stink b { display: none; position: absolute; left: 50%; top: 18%; width: 0; height: 0; }
.pm.stink-3 .pm-stink b { display: block; animation: pz-fly 1.9s linear infinite; }
.pm-stink b:nth-of-type(2) { animation-duration: 2.4s !important; animation-direction: reverse !important; top: 4%; }
.pm-stink b:nth-of-type(3) { animation-duration: 1.5s !important; animation-delay: -.6s !important; top: 30%; }
.pm-stink b::before { content: ""; position: absolute; left: calc(var(--hh) * .32); top: -2px; width: 4px; height: 4px; border-radius: 50%; background: #1d1d1d;
  box-shadow: -2px -3px 0 -.5px #dbe9f2cc, 2px -3px 0 -.5px #dbe9f2cc; animation: pz-buzz .12s steps(2) infinite; }
@keyframes pz-fly { to { transform: rotate(360deg); } }
@keyframes pz-buzz { 50% { transform: translate(1px, -1px); } }
@media (prefers-reduced-motion: reduce) { .pm-stink path { animation-duration: 5s; } .pm.stink-3 .pm-stink b { animation-duration: 6s !important; } .pm-stink b::before { animation: none; } }
/* Out of the bath: drops flung off in every direction as it shakes itself dry, then a few sparkles. */
.pm-fresh { position: absolute; left: 0; bottom: calc(var(--hh) * .55); width: 0; height: 0; pointer-events: none; }
.pm-fresh i { position: absolute; left: 0; top: 0; width: 0; height: 0; }
.pm-fresh i::after { content: ""; position: absolute; left: -3px; top: -4px; width: 6px; height: 8px; border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%;
  background: #6fb8ea; opacity: 0; animation: pz-shake-drop .6s ease-out both; }
.pm-fresh i:nth-child(1) { transform: rotate(-80deg); } .pm-fresh i:nth-child(2) { transform: rotate(-35deg); }
.pm-fresh i:nth-child(3) { transform: rotate(10deg); } .pm-fresh i:nth-child(4) { transform: rotate(100deg); }
.pm-fresh i:nth-child(5) { transform: rotate(145deg); } .pm-fresh i:nth-child(6) { transform: rotate(190deg); }
.pm-fresh i:nth-child(odd)::after { animation-delay: .25s; } .pm-fresh i:nth-child(even)::after { animation-delay: .6s; }
.pm-fresh i:nth-child(3n)::after { animation-delay: .95s; }
@keyframes pz-shake-drop { 0% { opacity: 1; transform: translateY(0); } 100% { opacity: 0; transform: translateY(-46px); } }
.pm-fresh b { position: absolute; font: 400 18px/1 sans-serif; color: #fff; text-shadow: 0 0 2px #6fb8ea, 0 0 6px #b6e0ff; opacity: 0;
  animation: pz-twinkle .7s ease-out both; }
.pm-fresh b:nth-of-type(1) { left: -30px; top: -40px; animation-delay: 1.5s; }
.pm-fresh b:nth-of-type(2) { left: 16px; top: -58px; animation-delay: 1.7s; font-size: 14px; }
.pm-fresh b:nth-of-type(3) { left: 22px; top: -8px; animation-delay: 1.9s; }
@keyframes pz-twinkle { 0% { opacity: 0; transform: scale(.2) rotate(-40deg); } 40% { opacity: 1; transform: scale(1.1); } 100% { opacity: 0; transform: scale(.6) rotate(30deg); } }
@media (prefers-reduced-motion: reduce) { .pm-fresh i { display: none; } }
/* The verse chiron (member request; plaza.js "verse chiron"): tap Jesus and his verse drops in along the top of
   the floor as a news-ticker strip (style.css .chiron): his head and the reference on the white slant tab
   (a long book name sits over its chapter and verse), the verse crawling past, a small felt cross between repeats. It slides
   down on arrival and rolls back up; a tap sends it away. */
.pz-verse { position: absolute; left: 0; right: 0; top: 0; z-index: 4600; cursor: pointer; box-shadow: 0 3px 0 rgba(46, 11, 15, .18);
  transform: translateY(-100%); transition: transform .24s cubic-bezier(.2, .8, .3, 1); }
.pz-verse.in { transform: none; }
.pz-verse.out { transform: translateY(-100%); transition-duration: .2s; transition-timing-function: ease-in; }
.pz-verse .chiron-tag { max-width: 60%; gap: 8px; padding-right: 22px; }
.pz-verse-ref { font-size: 21px; white-space: nowrap; }
.pz-verse-ref.two { display: flex; flex-direction: column; gap: 2px; font-size: 16px; letter-spacing: .08em; line-height: 1; }
.pz-verse .chiron-item { font-family: var(--font); }
.pz-verse .chiron-item::after { width: 7px; height: 11px; margin-bottom: 1px; background: linear-gradient(var(--felt), var(--felt)) center / 7px 2.5px no-repeat, linear-gradient(var(--felt), var(--felt)) center / 2.5px 11px no-repeat;
  background-position: center 3px, center; }
@media (prefers-reduced-motion: reduce) { .pz-verse, .pz-verse.out { transition: none; } }

/* Blocks + Paint trays (member request, Ethan: "the same style as the tamagotchi button bars"; plaza.js "blocks", "paint").
   The cube or brush cell goes header red while its tray is up; the tray hangs from the dock's bottom edge across its
   full width (edge to edge, no side frame): cells in the dock's chrome with 2px frame-colour dividers, like the moves
   menu. Each colour fills its whole cell, seven to a row (fourteen on a wide screen); the picked one wears a red frame
   with a white line inside (::before, buttons.css drops button shadows). Tools are moves-menu rows (one-bit icon + bold
   rounded label); on = header red with white, like the open cell (member request: keep the red theme); waiting =
   dimmed with the time left. Paint's tools line up under the colour columns: three
   brush-size squares in the picked colour (hollow for the eraser, which rubs square), Eraser and Undo two columns
   each. The hint is the last row in ink-2. Remove fades the swatches (they don't apply). The floor takes a crosshair
   while painting. */
.pz-cam-b.place[aria-pressed="true"] { background: var(--pz-bar); color: #fff; }
.pz-tama.pz-blocks { --cols: 7; --pdab: 14px; left: 0; right: 0; top: calc(100% + 2px); gap: 0; border: 0; border-bottom: 2px solid var(--pz-line);
  transform-origin: 50% 0; }
@media (min-width: 700px) { .pz-tama.pz-blocks { --cols: 14; } }
.pz-tama.pz-blocks > :not(:first-child) { border-top: 0; }
.pz-sws, .pz-ptools { display: grid; grid-template-columns: repeat(var(--cols), minmax(0, 1fr)); gap: 2px; }
.pz-sw { position: relative; height: 46px; min-width: 0; margin: 0; padding: 0; border: 0; display: grid; place-items: center;
  background: var(--pz-chrome); color: var(--pz-ink); cursor: pointer; -webkit-tap-highlight-color: transparent; }
.pz-sws .pz-sw { color: var(--pz-bar); }
.pz-sws .pz-sw > i { position: absolute; inset: 0; background: var(--c); }
.pz-sws .pz-sw:active > i { filter: brightness(.88); }
.pz-sws .pz-sw[aria-pressed="true"]::before { content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  border: 3px solid var(--pz-bar); box-shadow: inset 0 0 0 2px #fff; }
.pz-blocks.erase .pz-sws .pz-sw > i { opacity: .35; }
.pz-btools { display: grid; grid-template-columns: 1fr 1fr; gap: 2px; }
.pz-bt { display: flex; align-items: center; justify-content: center; gap: 8px; height: 46px; min-width: 0; margin: 0; padding: 0 8px;
  border: 0; background: var(--pz-chrome); color: var(--pz-ink); font: 800 15.5px/1 var(--pz-rounded); white-space: nowrap;
  -webkit-tap-highlight-color: transparent; cursor: pointer; }
.pz-bt:active > * { transform: translateY(1px); }
.pz-bt[aria-pressed="true"] { background: var(--pz-bar); color: #fff; }
.pz-bhint { margin: 0; padding: 10px 12px 11px; background: var(--pz-chrome); color: var(--pz-ink-2); font: 600 13.5px/1.35 var(--pz-rounded); }
.pz-ptools .pz-bt { grid-column: span 2; }
@media (min-width: 700px) { .pz-ptools .pz-bt { grid-column: span 4; } .pz-ptools .pz-size { grid-column: span 2; } }
@media (max-width: 370px) { .pz-ptools .pz-bt { gap: 5px; padding: 0 4px; font-size: 14px; } }
.pz-size > i { display: block; width: var(--d); height: var(--d); background: var(--dab, var(--pz-ink)); }
.pz-sw.pz-size:active > i { transform: translateY(1px); }
.pz-sw.pz-size[aria-pressed="true"] { background: var(--pz-bar); color: #fff; }
.pz-sw.pz-size[aria-pressed="true"] > i { box-shadow: 0 0 0 2px #fff; }
.pz-paint.erase .pz-size > i { background: transparent; box-shadow: inset 0 0 0 2px currentColor; }
/* Folding (member requests): once its picks are made (Blocks: a colour or Remove; Paint: a colour and a size) or it's
   used on the floor, the Blocks or Paint tray slides up into one strip so the floor is free: a square of what you'll do
   (the block colour / the brush size in the colour; hollow for Remove and the eraser), its name, a pixel chevron, then
   the quick tools (Blocks: Build and Remove icons with their countdowns; Paint: Undo). Tapping the strip slides the
   full tray back down. */
.pz-pfold { display: grid; grid-template-rows: 1fr; transition: grid-template-rows .22s cubic-bezier(.3, .7, .2, 1); }
.pz-pfull { display: flex; flex-direction: column; gap: 2px; min-height: 0; overflow: hidden; }
.pz-blocks.folded .pz-pfold { grid-template-rows: 0fr; }
.pz-pstrip { display: none; gap: 2px; animation: pz-tama .16s ease-out; }
.pz-blocks.folded .pz-pstrip { display: flex; }
.pz-pstrip .pz-bt { flex: 0 0 auto; height: 42px; padding: 0 14px; }
.pz-pshow { flex: 1 1 auto; display: flex; align-items: center; gap: 10px; min-width: 0; height: 42px; margin: 0; padding: 0 12px;
  border: 0; background: var(--pz-chrome); color: var(--pz-ink); font: 800 15.5px/1 var(--pz-rounded); text-align: left;
  white-space: nowrap; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.pz-pshow > span { flex: 0 1 auto; overflow: hidden; text-overflow: ellipsis; }
.pz-pshow:active > * { transform: translateY(1px); }
.pz-pdab { flex: none; display: grid; place-items: center; width: 22px; height: 22px; }
.pz-pdab::before { content: ""; width: var(--pdab, 10px); height: var(--pdab, 10px); background: var(--dab, var(--pz-ink));
  box-shadow: 0 0 0 1.5px var(--pz-line); }
.pz-blocks.erase .pz-pdab::before { background: transparent; box-shadow: inset 0 0 0 2px currentColor; }
.pz-pchev { width: 18px; height: 18px; margin-left: -2px; }
@media (prefers-reduced-motion: reduce) { .pz-pfold { transition: none; } .pz-pstrip { animation: none; } }
.plaza.painting .pz-floor { cursor: crosshair; }

/* Landscape (member request, Ethan): held sideways on a phone or tablet, the dock stands up as a column on the right
   edge, the floor fills the rest, and the side safe area (notch, home bar) is the dock's own chrome. Cells keep the
   2px frame-colour dividers and stop growing at 64px tall. Menus open leftward beside their button (plaza.js setGroup
   lines the arcade's up with it); the block and paint trays hang from the dock's left edge, seven colours to a row. */
@media (orientation: landscape) and (pointer: coarse) {
  .plaza { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: minmax(0, 1fr) auto; }
  .plaza > .pz-floor { grid-column: 1; grid-row: 1; }
  .plaza > .pz-bottom { grid-column: 1; grid-row: 2; padding-left: max(12px, env(safe-area-inset-left)); }
  .plaza { grid-template-rows: minmax(0, 1fr) auto auto; }
  .plaza > .pz-here { grid-column: 1; grid-row: 3; padding-left: max(10px, env(safe-area-inset-left)); }
  .plaza > .pz-dock { grid-column: 2; grid-row: 1 / -1; min-height: 0; border-bottom: 0; border-left: 2px solid var(--pz-line);
    padding: 0 env(safe-area-inset-right) var(--sab) 0; }
  .pz-cam { flex-direction: column; width: 58px; max-width: none; max-height: 100%; margin: 0; }
  .pz-cam-b { flex: 0 1 64px; width: 100%; height: auto; min-height: 0; }
  .pz-tama { left: auto; right: calc(100% + 12px); top: 0; transform-origin: 100% 22px; }
  @keyframes pz-tama-side { from { opacity: 0; transform: translateX(10px) scale(.96); } }
  .pz-tama { animation-name: pz-tama-side; }
  .pz-group { left: auto !important; }
  .pz-tama.pz-blocks { --cols: 7; left: auto; right: 100%; top: 0; width: min(378px, calc(100vw - 120px)); max-height: 100%; overflow-y: auto;
    overscroll-behavior: contain; border-left: 2px solid var(--pz-line); transform-origin: 100% 0; }
  .pz-ptools .pz-bt { grid-column: span 2; }
  .pz-ptools .pz-size { grid-column: auto; }
}

/* Weather (plaza.js "weather"): a lightning strike whites the floor out for a blink, twice, like a real flash. */
.pz-flash { position: absolute; inset: 0; z-index: 3000; pointer-events: none; background: #fff; opacity: 0; }
.pz-flash.on { animation: pz-flash .5s linear; }
@keyframes pz-flash { 0% { opacity: 0; } 8% { opacity: .7; } 22% { opacity: .05; } 34% { opacity: .45; } 100% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .pz-flash.on { animation: none; } }
