/* Penguin Arcade — hub shell. Same dusk-ice palette as Peakling. */
* { margin: 0; padding: 0; box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
/* NOTE: no `touch-action: none` here. It used to sit on the root, which killed
   panning inside every overflow:auto scroller — on a phone the Shop's BUY row,
   the badge grid and most of the newspaper were physically unreachable. The
   canvas stays locked by #hub's own touch-action plus the {passive:false}
   preventDefault handlers in js/hub.js. overscroll-behavior kills rubber-band. */
html, body { height: 100%; overflow: hidden; background: #0b1026; overscroll-behavior: none; }

/* every scrollable surface must be able to pan vertically on touch */
.panel, .pet-panel, .ev-pop, #newsRoot, #quickChat, #boardRows, #itemGrid, #ledgerRows, #mapRooms {
  touch-action: pan-y; -webkit-overflow-scrolling: touch; overscroll-behavior: contain;
}
#trayItems { touch-action: pan-x; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; }
body { font-family: -apple-system, "Avenir Next", "Segoe UI", system-ui, sans-serif; color: #eaf4ff; }

#stage { position: fixed; inset: 0; }
#hub { position: absolute; inset: 0; width: 100%; height: 100%; display: block; touch-action: none; }

/* The real room painting is decoded before its HUD/chat chrome is revealed.
   This avoids a first-frame flash of the retired procedural town with a fully
   interactive-looking chat bar on top of it. */
body.scene-loading #hud,
body.scene-loading #dock,
body.scene-loading #quickChat,
body.scene-loading #emoteWheel,
body.scene-loading #toast,
body.scene-loading #buildTag { visibility: hidden; pointer-events: none; }

.hidden { display: none !important; }

/* ------- HUD ------- */
#hud {
  position: absolute; top: max(10px, env(safe-area-inset-top));
  /* horizontal insets too: in landscape the notch/rounded corner eats the ends
     of this row, and the buttons live at the right end */
  left: max(10px, env(safe-area-inset-left)); right: max(10px, env(safe-area-inset-right));
  display: flex; justify-content: space-between; align-items: center; pointer-events: none; gap: 6px;
}
#hudLeft, #hudRight { display: flex; gap: 6px; align-items: center; pointer-events: auto; min-width: 0; }
#nameTag {
  height: 38px; display: flex; align-items: center;
  background: rgba(8, 13, 32, .62); border: 1px solid rgba(150, 200, 255, .22);
  padding: 0 14px; border-radius: 999px; font-weight: 700; font-size: 13px; letter-spacing: .4px;
  cursor: pointer; backdrop-filter: blur(14px); box-shadow: 0 4px 14px rgba(0, 0, 0, .30);
  /* the name absorbs all the shrinking — buttons and balance stay whole */
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 25vw;
  flex-shrink: 1; min-width: 0;
}
#coins {
  height: 38px; display: flex; align-items: center;
  background: rgba(8, 13, 32, .62); border: 1px solid rgba(150, 200, 255, .22);
  padding: 0 13px; border-radius: 999px; font-weight: 800; font-size: 13px; color: #bfe9ff;
  backdrop-filter: blur(14px); box-shadow: 0 4px 14px rgba(0, 0, 0, .30); white-space: nowrap;
  cursor: pointer;
  /* compact (see UI.refreshCoins) so it never shoves the button pill off-screen,
     but it does NOT shrink — a truncated balance is worse than a truncated name */
  max-width: 26vw; overflow: hidden; text-overflow: ellipsis; flex-shrink: 0;
}
/* the buttons are the one thing that must always stay reachable */
#hudBtns { flex-shrink: 0; }
#hudRight { display: flex; align-items: center; gap: 8px; min-width: 0; }
#hudBtns {
  display: flex; gap: 2px; padding: 3px; border-radius: 999px;
  background: rgba(8, 13, 32, .62); border: 1px solid rgba(150, 200, 255, .22);
  backdrop-filter: blur(14px); box-shadow: 0 4px 14px rgba(0, 0, 0, .30);
}
.hudbtn {
  min-width: 36px; height: 44px; border-radius: 999px; border: none;
  background: transparent; color: #eaf4ff; font-size: 10px; font-weight: 800;
  letter-spacing: 0.3px; cursor: pointer; padding: 0 6px;
  display: flex; align-items: center; justify-content: center; line-height: 1;
}
.hudbtn:active { background: rgba(120, 170, 255, .25); transform: scale(.92); }
/* Narrow phones: with five buttons in the pill, name + balance + buttons no
   longer fit at full size, and because both the balance and the pill are
   flex-shrink:0 the overflow went somewhere unrecoverable — straight off the
   right edge, clipping the settings gear. Tighten the row instead of letting
   it spill. Height stays 44px, so touch targets are unaffected. */
@media (max-width: 430px) {
  #hudRight { gap: 6px; }
  #hudBtns { gap: 0; padding: 3px 2px; }
  .hudbtn { min-width: 32px; padding: 0 3px; }
  #nameTag { max-width: 20vw; padding: 0 11px; }
  #coins { padding: 0 10px; }
}
.hud-icon { width: 20px; height: 20px; object-fit: contain; vertical-align: middle; margin-right: 2px; pointer-events: none; }
/* The 2px right margin exists to separate the coin icon from the balance text
   beside it. On an icon-ONLY button there is no text, so it just shoves the
   glyph 1px off-centre in the circle — visible once every dock button is an
   icon and they sit in a row. */
.dockbtn .hud-icon, .hudbtn .hud-icon { margin-right: 0; }
/* Dock buttons are 44px but were drawing these painterly icons at 20px, which
   muddies them — they carry real shading and outlines, unlike a flat glyph. */
.dockbtn .hud-icon { width: 26px; height: 26px; }
.hud-icon-exit { width: 18px; height: 18px; object-fit: contain; vertical-align: middle; margin-right: 4px; pointer-events: none; }
.dockbtn {
  min-width: 44px; height: 44px; border-radius: 999px; border: none; flex-shrink: 0;
  background: rgba(120, 170, 255, .10); color: #eaf4ff; font-size: 10px; font-weight: 800;
  letter-spacing: 0.5px; cursor: pointer; padding: 0 8px;
  display: flex; align-items: center; justify-content: center; line-height: 1;
}
.dockbtn:active { transform: scale(.92); background: rgba(120, 170, 255, .25); }
.dockbtn.armed { background: #2d6cdf; box-shadow: 0 0 14px rgba(90,170,255,.8); }

/* ------- chat dock ------- */
#dock {
  position: absolute; left: 50%; transform: translateX(-50%);
  bottom: max(12px, env(safe-area-inset-bottom));
  display: flex; gap: 5px; align-items: center; width: min(520px, calc(100% - 20px));
  background: rgba(8, 13, 32, .62); border: 1px solid rgba(150, 200, 255, .22);
  padding: 6px; border-radius: 999px; backdrop-filter: blur(14px);
  box-shadow: 0 6px 20px rgba(0, 0, 0, .35);
}
#chatForm { flex: 1; min-width: 0; }
#chatInput {
  width: 100%; padding: 10px 15px; border-radius: 999px; font-size: 15px;
  border: none; outline: none;
  background: rgba(120, 170, 255, .10); color: #eaf4ff;
}
#chatInput::placeholder { color: #7f95c2; }
#chatInput:focus { background: rgba(120, 170, 255, .16); box-shadow: inset 0 0 0 1.5px rgba(127, 184, 255, .55); }

#emoteWheel {
  position: absolute; left: 50%; transform: translateX(-50%);
  bottom: calc(max(12px, env(safe-area-inset-bottom)) + 62px);
  display: flex; gap: 8px; background: rgba(8, 13, 32, .78); padding: 8px 10px;
  border-radius: 999px; border: 1px solid rgba(150, 200, 255, .25); backdrop-filter: blur(14px);
  box-shadow: 0 6px 20px rgba(0, 0, 0, .35);
}
#emoteWheel button {
  min-width: 46px; height: 46px; border-radius: 999px; font-size: 11px; font-weight: 800;
  letter-spacing: 0.5px; border: none; padding: 0 10px; color: #eaf4ff;
  background: rgba(120, 170, 255, .12); cursor: pointer;
}
#emoteWheel button:hover { background: rgba(120, 170, 255, .3); }
#emoteWheel button:active { transform: scale(.9); }

/* ------- panels ------- */
#panelScrim { position: absolute; inset: 0; background: rgba(4, 8, 22, .55); backdrop-filter: blur(3px); }
.panel {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: min(620px, calc(100% - 28px)); max-height: min(560px, calc(100% - 40px));
  background: linear-gradient(180deg, #131b3d, #0d1330); border: 1px solid rgba(140, 190, 255, .45);
  border-radius: 18px; padding: 16px 18px; overflow: auto; box-shadow: 0 18px 60px rgba(0,0,0,.6);
}
.panelHead { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; }
.panelHead h2 { font-size: 18px; letter-spacing: 2px; color: #cfe7ff; }
.closeX {
  width: 44px; height: 44px; border-radius: 50%; border: 1px solid rgba(140,190,255,.4);
  background: transparent; color: #cfe7ff; font-size: 15px; cursor: pointer;
}

/* style panel */
.styleBody { display: flex; gap: 16px; }
.previewCol { display: flex; flex-direction: column; gap: 8px; align-items: center; }
#previewCanvas {
  background: radial-gradient(circle at 50% 30%, #1c2a5c, #0d1330 75%);
  border: 1px solid rgba(140,190,255,.35); border-radius: 14px;
}
#nameInput {
  width: 100%; padding: 8px 10px; border-radius: 10px; text-align: center; font-weight: 700;
  border: 1px solid rgba(140,190,255,.4); background: rgba(10,16,40,.7); color: #eaf4ff; outline: none;
}
#styleCoins { font-weight: 800; color: #bfe9ff; }
.itemsCol { flex: 1; min-width: 0; display: flex; flex-direction: column; }
#styleTabs, #boardTabs { display: flex; gap: 6px; margin-bottom: 10px; flex-wrap: wrap; }
#styleTabs button, #boardTabs button {
  padding: 7px 13px; border-radius: 999px; border: 1px solid rgba(140,190,255,.35);
  background: transparent; color: #9fb8e6; font-weight: 700; font-size: 12px; letter-spacing: 1px; cursor: pointer;
}
#styleTabs button.sel, #boardTabs button.sel { background: #2d6cdf; color: #fff; border-color: #9fd0ff; }
#itemGrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(74px, 1fr)); gap: 8px; }
.item {
  position: relative; border-radius: 12px; border: 2px solid rgba(140,190,255,.25);
  background: rgba(120,170,255,.08); height: 74px; cursor: pointer;
  display: flex; align-items: center; justify-content: center; overflow: hidden;
}
.item.sel { border-color: #7fd0ff; box-shadow: 0 0 10px rgba(90,180,255,.5); }
.item.equipped::after {
  content: "✓"; position: absolute; top: 3px; right: 6px; color: #8affc0; font-weight: 900;
}
.item .swatch { width: 40px; height: 40px; border-radius: 50%; border: 2px solid rgba(255,255,255,.5); }
.item img { max-width: 56px; max-height: 52px; image-rendering: auto; }
/* painted swatches (wallpaper/flooring, vector items) — soften the hard square */
.item img.swatchImg { border-radius: 8px; }
.item .scarfFileThumb {
  width: 56px; height: 52px; display: block;
  background: var(--scarf-color);
  -webkit-mask: var(--scarf-mask) center / contain no-repeat;
  mask: var(--scarf-mask) center / contain no-repeat;
  filter: drop-shadow(0 1px 1px rgba(7, 14, 38, .55));
}
/* Local-file product cards cannot read a PNG back out of a canvas, so these
   retain the item’s real colour and unmistakable garment silhouette without a
   tainted-canvas text fallback.  The hosted shop continues to use its actual
   rendered penguin crop. */
.item .capeFileThumb {
  position: relative; width: 43px; height: 50px; display: block;
  background: linear-gradient(90deg, rgba(255,255,255,.16), transparent 38%), var(--cape-color);
  border: 2px solid rgba(246,249,255,.68); border-radius: 18px 18px 25px 25px;
  clip-path: polygon(18% 0, 82% 0, 100% 20%, 82% 100%, 50% 88%, 18% 100%, 0 20%);
  box-shadow: inset 0 0 0 1px rgba(13,24,61,.38), 0 1px 2px rgba(7,14,38,.55);
}
.item .capeFileThumb::after {
  content: ''; position: absolute; left: 50%; top: 0; width: 7px; height: 7px;
  transform: translateX(-50%); border-radius: 0 0 7px 7px; background: #f5d477;
}
.item .vestFileThumb {
  position: relative; width: 45px; height: 48px; display: block;
  background: var(--vest-color); border: 2px solid rgba(246,249,255,.72);
  border-radius: 14px 14px 11px 11px;
  clip-path: polygon(15% 0, 35% 0, 50% 17%, 65% 0, 85% 0, 100% 19%, 92% 100%, 8% 100%, 0 19%);
  box-shadow: inset 0 0 0 1px rgba(13,24,61,.35), 0 1px 2px rgba(7,14,38,.55);
}
.item .vestFileThumb i,
.item .vestFileThumb::before,
.item .vestFileThumb::after { content: ''; position: absolute; display: block; }
.item .vestFileThumb i { left: 50%; top: 7px; width: 2px; height: 39px; transform: translateX(-50%); background: rgba(246,249,255,.75); }
.item .vestFileThumb.puffer::before { left: 5px; right: 5px; top: 14px; height: 2px; background: rgba(246,249,255,.6); box-shadow: 0 10px rgba(246,249,255,.6), 0 20px rgba(246,249,255,.6); }
.item .vestFileThumb.sailor::before { left: 50%; top: 3px; width: 22px; height: 13px; transform: translateX(-50%); border-bottom: 3px solid #f6f9ff; clip-path: polygon(0 0, 100% 0, 50% 100%); }
.item .vestFileThumb.ranger::before { left: 6px; bottom: 8px; width: 9px; height: 7px; border: 1px solid rgba(246,249,255,.8); border-radius: 2px; box-shadow: 21px 0 0 -1px var(--vest-color), 21px 0 0 0 rgba(246,249,255,.8); }
.item .vestFileThumb.tux { background: #20212b; }
.item .vestFileThumb.tux::before { left: 50%; top: 8px; width: 17px; height: 16px; transform: translateX(-50%); background: #f6f9ff; clip-path: polygon(0 0, 50% 100%, 100% 0, 78% 0, 50% 40%, 22% 0); }
.item .vestFileThumb.summit::before { left: 6px; right: 6px; bottom: 9px; height: 6px; border-radius: 6px; background: rgba(222,249,255,.75); }
.item .vestFileThumb.varsity::before { left: 6px; right: 6px; top: 5px; height: 5px; border-radius: 4px; background: #f5d477; }
.item .price {
  position: absolute; bottom: 2px; left: 0; right: 0; text-align: center;
  font-size: 11px; font-weight: 800; color: #ffd98a; text-shadow: 0 1px 2px #000;
}
.item .eyeLabel { font-size: 22px; }
#buyRow { display: flex; align-items: center; justify-content: space-between; margin-top: 10px; }
#buyLabel { font-weight: 700; color: #ffd98a; }
#buyBtn {
  padding: 9px 22px; border-radius: 999px; border: none; background: #ffb742; color: #241505;
  font-weight: 900; letter-spacing: 1px; cursor: pointer;
}
#buyBtn:disabled { opacity: .45; }

/* leaderboard */
#boardRows { display: flex; flex-direction: column; gap: 6px; }
.brow {
  display: flex; justify-content: space-between; padding: 9px 13px; border-radius: 10px;
  background: rgba(120,170,255,.08); font-weight: 700; font-size: 14px;
}
.brow.you { background: rgba(60,130,255,.28); border: 1px solid rgba(140,200,255,.5); }
.brow .rank { color: #9fb8e6; margin-right: 10px; }
.brow .val { color: #bfe9ff; }

/* game launch panel */
#gamePanel p { color: #b9cdf0; font-size: 14px; margin-bottom: 12px; }
#gameModes { display: flex; flex-direction: column; gap: 8px; }
button.big {
  padding: 13px 18px; border-radius: 14px; border: none; font-size: 16px; font-weight: 900;
  letter-spacing: 1.5px; background: linear-gradient(180deg, #4a9dff, #2d6cdf); color: #fff; cursor: pointer;
}
button.big.ghost { background: transparent; border: 1.5px dashed rgba(140,190,255,.4); color: #7f95c2; }
button.big:disabled { opacity: .48; cursor: default; }
.mut { color: #7f95c2 !important; font-size: 12px !important; margin-top: 10px; }
.partyPanel { z-index: 47; max-width: 460px; }
.partySetup, .partyMembers { display: flex; flex-direction: column; gap: 8px; }
.partyJoinRow { display: flex; gap: 8px; margin-top: 2px; }
.partyJoinRow input {
  min-width: 0; flex: 1; height: 46px; padding: 0 12px; border-radius: 12px;
  border: 1px solid rgba(140,190,255,.38); background: rgba(8,14,36,.68);
  color: #eaf4ff; text-align: center; letter-spacing: .14em; font: 900 15px system-ui;
}
.smallBtn {
  min-height: 42px; padding: 0 13px; border-radius: 11px; border: 1px solid rgba(140,190,255,.42);
  background: rgba(88,145,255,.18); color: #dff0ff; font: 800 12px system-ui; letter-spacing: .06em; cursor: pointer;
}
.partyTip { text-align: center; margin-bottom: 0; }
.partyCodeCard {
  display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 6px 10px; padding: 12px;
  border-radius: 13px; border: 1px solid rgba(123,218,255,.36); background: rgba(62,130,220,.14);
}
.partyCodeCard span { color: #9ab6df; font: 800 10px system-ui; letter-spacing: .12em; }
.partyCodeCard strong { color: #f7e5a3; font: 900 23px system-ui; letter-spacing: .16em; }
.partyCodeCard .smallBtn { grid-row: span 2; grid-column: 2; }
.partyMembers { margin: 12px 0; }
.partyMember {
  display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 10px 12px;
  border-radius: 10px; background: rgba(120,170,255,.09); color: #dcecff; font: 700 14px system-ui;
}
.partyMember.you { border: 1px solid rgba(136,218,255,.45); background: rgba(75,145,255,.22); }
.partyMember b { color: #9cdeb9; font-size: 10px; letter-spacing: .09em; }
.partyLeave { display: block; margin: 12px auto 0; border: 0; background: transparent; color: #9fb8e6; font: 800 12px system-ui; cursor: pointer; }
#upgradeBenefits { display: flex; flex-wrap: wrap; gap: 7px; margin: 14px 0 4px; }
#upgradeBenefits span {
  padding: 6px 9px; border-radius: 999px; color: #bfe9ff; font-size: 10px; font-weight: 900;
  letter-spacing: .06em; background: rgba(75,208,160,.12); border: 1px solid rgba(100,225,185,.28);
}
#upgradeBalance { color: #ffd98a !important; font-weight: 800; }
#upgradeBtn:disabled { opacity: .65; cursor: default; }

/* game overlay */
#gameOverlay { position: absolute; inset: 0; background: #000; z-index: 50; }
#gameFrame { width: 100%; height: 100%; border: none; }
#backToHub {
  position: absolute; top: max(10px, env(safe-area-inset-top)); left: 12px;
  padding: 9px 16px; border-radius: 999px; border: 1px solid rgba(140,190,255,.5);
  background: rgba(10, 16, 40, .8); color: #eaf4ff; font-weight: 800; cursor: pointer;
}

/* toast */
#toast {
  position: absolute; left: 50%; transform: translateX(-50%);
  /* clear the HUD and the event banner, and wrap instead of running off both
     edges (the beachbash toast measured -66 -> 441 on a 375px viewport) */
  top: calc(max(10px, env(safe-area-inset-top)) + 52px);
  max-width: calc(100% - 32px); z-index: 60;
  background: rgba(16, 26, 60, .92); border: 1px solid rgba(140,210,255,.5);
  padding: 9px 18px; border-radius: 18px; font-weight: 800; font-size: 14px; color: #cfe9ff;
  animation: toastIn .25s ease-out; pointer-events: none;
  white-space: normal; text-align: center; line-height: 1.35;
}
@keyframes toastIn { from { opacity: 0; transform: translate(-50%, -8px); } to { opacity: 1; transform: translate(-50%, 0); } }

/* ------- quick chat ------- */
#quickChat {
  position: absolute; left: 50%; transform: translateX(-50%);
  bottom: calc(max(12px, env(safe-area-inset-bottom)) + 62px);
  display: flex; flex-wrap: wrap; gap: 6px; justify-content: center;
  width: min(520px, calc(100% - 20px));
  background: rgba(8, 13, 32, .82); padding: 10px; border-radius: 16px;
  border: 1px solid rgba(150, 200, 255, .25); backdrop-filter: blur(14px);
  box-shadow: 0 6px 20px rgba(0, 0, 0, .35);
}
#quickChat button {
  padding: 7px 12px; border-radius: 999px; border: 1px solid rgba(140,190,255,.35);
  background: rgba(120,170,255,.12); color: #dceafe; font-size: 13px; font-weight: 700; cursor: pointer;
}
#quickChat button:active { transform: scale(.94); }

/* ------- igloo tray ------- */
#iglooTray {
  position: absolute; left: 50%; transform: translateX(-50%);
  bottom: calc(max(12px, env(safe-area-inset-bottom)) + 62px);
  display: grid; grid-template-columns: minmax(116px, 174px) minmax(0, 1fr) auto; gap: 9px; align-items: center;
  background: rgba(10, 16, 40, .9); padding: 8px 10px; border-radius: 16px;
  border: 1px solid rgba(140, 190, 255, .45); backdrop-filter: blur(8px);
  width: min(760px, calc(100% - 20px));
}
#trayMeta { min-width: 0; }
#trayLabel {
  font-size: 11px; font-weight: 900; letter-spacing: .08em; color: #9dffdc; white-space: nowrap;
}
#trayHelp { margin-top: 4px; color: #b7cbe9; font-size: 11px; line-height: 1.25; }
#trayItems { display: flex; gap: 6px; overflow-x: auto; min-width: 0; }
/* thumbnails, not text: twelve "Ice Couch x1" labels squeezed to 62px and bled
   over each other on a 375px screen. Fixed square tiles never shrink. */
#trayItems button {
  position: relative; flex: 0 0 auto; width: 56px; height: 56px; padding: 4px;
  border-radius: 12px; border: 1px solid rgba(140,190,255,.35);
  background: rgba(120,170,255,.12); color: #dceafe; font-size: 12px; font-weight: 700; cursor: pointer;
  white-space: nowrap;
}
#trayItems button.trayHint {
  width: auto; height: 56px; padding: 6px 14px; font-size: 12px; opacity: .8;
}
#trayItems button img { width: 100%; height: 100%; object-fit: contain; display: block; }
#trayItems button .eyeLabel { font-size: 13px; line-height: 48px; }
#trayItems button .trayN {
  position: absolute; right: 2px; bottom: 1px; min-width: 15px; padding: 0 3px;
  border-radius: 8px; background: rgba(8,13,32,.9); border: 1px solid rgba(140,190,255,.4);
  font-size: 10px; font-weight: 900; color: #cfe9ff;
}
#trayItems button:active { transform: scale(.94); }
#trayItems button.sel { background: #2d6cdf; border-color: #9fd0ff; box-shadow: 0 0 0 2px rgba(159,208,255,.5); }
#trayActions { display: flex; flex-direction: column; gap: 5px; }
#trayDone, #trayCancel {
  padding: 9px 14px; border-radius: 999px; border: none; background: #4fd0a0;
  color: #06281c; font-weight: 900; cursor: pointer; white-space: nowrap;
}
#trayCancel { background: rgba(255,255,255,.12); color: #dceafe; border: 1px solid rgba(180,210,255,.28); }
#trayDone:active, #trayCancel:active { transform: scale(.95); }

@media (max-width: 560px) {
  #iglooTray { grid-template-columns: 78px minmax(0, 1fr) auto; gap: 6px; padding: 7px 8px; }
  #trayLabel { font-size: 10px; white-space: normal; line-height: 1.15; }
  #trayHelp { display: none; }
  #trayItems button { width: 52px; height: 52px; }
  #trayItems button .eyeLabel { line-height: 44px; }
  #trayDone, #trayCancel { padding: 8px 10px; font-size: 11px; }
}

/* ------- style panel extras ------- */
#limitedBanner {
  margin-bottom: 8px; padding: 6px 12px; border-radius: 10px; font-size: 12px; font-weight: 800;
  background: rgba(255,183,66,.15); border: 1px solid rgba(255,183,66,.5); color: #ffd98a;
}
.item .lock {
  position: absolute; top: 3px; left: 6px; font-size: 12px;
}
.item .newTag {
  position: absolute; top: 2px; left: 2px; font-size: 9px; font-weight: 900;
  background: #e04747; color: #fff; padding: 2px 5px; border-radius: 6px; letter-spacing: .5px;
}
.item .wish {
  position: absolute; top: 1px; right: 4px; font-size: 13px; color: #ff8aa8; cursor: pointer;
}
.item .furnN {
  position: absolute; top: 2px; right: 6px; font-size: 11px; font-weight: 900; color: #8affc0;
}
#wishBtn {
  width: 38px; height: 38px; border-radius: 50%; border: 1px solid rgba(255,138,168,.6);
  background: transparent; color: #ff8aa8; font-size: 17px; cursor: pointer; margin-right: 8px;
}
#wishBtn.on { background: rgba(255,138,168,.25); }
#memberRow {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin-top: 12px; padding: 9px 12px; border-radius: 12px; font-size: 12px; font-weight: 700;
  background: rgba(255,217,138,.08); border: 1px dashed rgba(255,217,138,.45); color: #ffd98a;
}
#memberRow button {
  padding: 7px 14px; border-radius: 999px; border: none; background: #ffb742; color: #241505;
  font-weight: 900; cursor: pointer; white-space: nowrap;
}

/* ------- map ------- */
#mapRooms { display: flex; flex-direction: column; gap: 8px; }
#mapRooms .mapRoomRow { display: flex; align-items: stretch; gap: 8px; }
#mapRooms .mapRoom {
  flex: 1 1 auto; min-width: 0;
  display: flex; justify-content: space-between; align-items: center;
  padding: 13px 16px; border-radius: 14px; border: 1px solid rgba(140,190,255,.35);
  background: rgba(120,170,255,.08); color: #eaf4ff; font-size: 15px; font-weight: 800; cursor: pointer;
}
#mapRooms .mapRoom.here { border-color: #7fd0ff; background: rgba(60,130,255,.25); }
#mapRooms .sub { font-size: 12px; color: #9fb8e6; font-weight: 600; }
#mapRooms .mapGift {
  flex: 0 0 auto; min-width: 60px; border: 1px solid rgba(255,217,138,.42);
  border-radius: 14px; padding: 0 10px; background: rgba(255,217,138,.14);
  color: #ffe3a0; font: 900 11px system-ui; letter-spacing: .05em; cursor: pointer;
}
#mapRooms .mapGift:active { background: rgba(255,217,138,.28); transform: scale(.97); }

/* ------- profile ------- */
#profTop { display: flex; gap: 14px; align-items: center; }
#profCanvas {
  background: radial-gradient(circle at 50% 30%, #1c2a5c, #0d1330 75%);
  border: 1px solid rgba(140,190,255,.35); border-radius: 14px; flex-shrink: 0;
}
#profInfo { flex: 1; min-width: 0; }
#profName { font-size: 20px; font-weight: 900; margin-bottom: 6px; }
#profLevelRow { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
#profLevel { font-weight: 900; color: #ffd98a; white-space: nowrap; }
#xpBar { flex: 1; height: 10px; border-radius: 999px; background: rgba(120,170,255,.15); overflow: hidden; }
#xpFill { height: 100%; border-radius: 999px; background: linear-gradient(90deg, #4a9dff, #7fd0ff); }
#profStats { font-size: 12px; color: #9fb8e6; line-height: 1.7; }
.secTitle { margin: 14px 0 8px; font-size: 13px; letter-spacing: 2px; color: #7fa8d8; }
#badgeGrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 8px; }
.badge {
  padding: 8px; border-radius: 12px; text-align: center; font-size: 11px; font-weight: 700;
  background: rgba(120,170,255,.08); border: 1px solid rgba(140,190,255,.25); color: #9fb8e6;
}
.badge.earned { background: rgba(255,217,138,.12); border-color: rgba(255,217,138,.5); color: #ffe9bd; }
.badge .bemoji { font-size: 22px; display: block; margin-bottom: 3px; }
#ledgerRows { font-size: 12px; color: #9fb8e6; display: flex; flex-direction: column; gap: 4px; }
#ledgerRows .lrow { display: flex; justify-content: space-between; }
#ledgerRows .pos { color: #8affc0; font-weight: 800; }
#ledgerRows .neg { color: #ff9a8a; font-weight: 800; }

/* ------- goldfish ------- */
#goldBundles { display: flex; flex-direction: column; gap: 8px; margin: 10px 0; }
.goldBundle {
  padding: 12px 16px; border-radius: 14px; border: 1px solid rgba(255,217,138,.5);
  background: rgba(255,183,66,.12); color: #ffe9bd; font-size: 15px; font-weight: 900; cursor: pointer;
}

/* ------- art panel ------- */
#artPanel p { color: #b9cdf0; font-size: 14px; margin-bottom: 10px; }
#voteBtn.voted { background: #4fd0a0; color: #06281c; }

/* ------- custom UI icons (text-only until full set is generated) ------- */
.ui-icon { width: 24px; height: 24px; vertical-align: middle; image-rendering: auto; display: none; }
.ui-icon-lg { width: 32px; height: 32px; display: none; }
.emote-icon { width: 36px; height: 36px; display: none; }
.ic { font-weight: 800; font-size: 11px; color: #9fb8e6; }

@media (max-width: 560px) {
  .styleBody { flex-direction: column; align-items: center; }
  .itemsCol { width: 100%; }
  #profTop { flex-direction: column; }
}

/* Safe Chat stand-in: fills the dock slot the hidden text box leaves behind,
   so the bar never reads as broken. Same pill shape as #chatInput. */
#safeChatSub {
  flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: flex-start;
  justify-content: center; gap: 1px; padding: 6px 15px; border-radius: 999px;
  border: none; cursor: pointer; text-align: left; min-height: 44px;
  background: rgba(120, 170, 255, .10); color: #eaf4ff;
}
#safeChatSub:active { background: rgba(120, 170, 255, .2); }
#safeChatSub span { font: 700 14px system-ui; }
#safeChatSub small { font: 500 10.5px system-ui; color: #7f95c2; }

/* emote wheel: real icons instead of ASCII labels */
#emoteWheel button img { width: 34px; height: 34px; object-fit: contain; display: block; margin: 0 auto; }
#emoteWheel .emoteCap { display: block; font: 700 9.5px system-ui; letter-spacing: .04em; margin-top: 2px; }

/* ===================================================================
   SHOP SHEET  (portrait-first)
   Structure discipline: ONE flex column, exactly ONE overflow-y:auto
   descendant, no position:sticky, no drag surface. That is the whole
   reason this is safe in WKWebView.
   =================================================================== */
#stylePanel.sheet {
  left: 0; right: 0; bottom: 0; top: max(10px, env(safe-area-inset-top));
  /* MUST: .panel sets transform: translate(-50%,-50%). Without this reset the
     sheet renders half its width left and half its height up, mostly
     off-screen. */
  transform: none;
  width: 100%; max-width: none; max-height: none;
  border-radius: 22px 22px 0 0; padding: 0; overflow: hidden;
  display: flex; flex-direction: column;
  /* MUST: .panel is in the shared `touch-action: pan-y` list at the top of
     this file, and touch-action INTERSECTS down the ancestor chain — so a
     pan-x child of a pan-y parent resolves to no panning at all. #deptStrip
     scrolls horizontally, so the panel itself must stop declaring pan-y.
     (#trayItems gets away with pan-x only because #iglooTray sits outside
     every panel.) The real vertical scroller re-declares pan-y below. */
  touch-action: manipulation;
}
.sheetGrab { width: 40px; height: 4px; border-radius: 2px; margin: 7px auto 0;
             background: rgba(160, 200, 255, .35); flex: 0 0 auto; }
#stylePanel.sheet .panelHead { flex: 0 0 44px; padding: 0 12px; margin: 0;
                               gap: 8px; align-items: center; }
#stylePanel.sheet .panelHead h2 { flex: 1; min-width: 0; font-size: 15px; }

#shopStage {
  flex: 0 0 190px; position: relative; overflow: hidden;
  background: radial-gradient(circle at 50% 34%, #1c2a5c, #0d1330 78%);
  border-top: 1px solid rgba(140, 190, 255, .18);
  border-bottom: 1px solid rgba(140, 190, 255, .18);
  transition: flex-basis 200ms cubic-bezier(.2, .8, .2, 1);
}
#stylePanel.tall #shopStage { flex-basis: 320px; }
#stylePanel.sheet #previewCanvas {
  position: absolute; left: 50%; bottom: 0; transform: translateX(-50%);
  background: none; border: none; cursor: grab; touch-action: none;
  -webkit-tap-highlight-color: transparent;
}
#stylePanel.sheet #previewCanvas.turning { cursor: grabbing; }
#turnHint {
  position: absolute; left: 12px; bottom: 9px; z-index: 1; pointer-events: none;
  display: flex; align-items: center; gap: 5px; padding: 5px 8px; border-radius: 999px;
  color: rgba(207, 231, 255, .78); background: rgba(8, 13, 32, .58);
  border: 1px solid rgba(150, 200, 255, .18); font: 800 9px/1 system-ui;
  letter-spacing: .45px;
}
#turnHint .turnIcon { color: #8fd5ff; font-size: 13px; line-height: 8px; }
#turnLabel { color: #fff1ba; min-width: 34px; text-align: center; }
#stylePanel.sheet #styleCoins {
  position: absolute; top: 8px; right: 10px; display: flex; gap: 6px;
  font: 900 13px system-ui; color: #eaf4ff; background: none; padding: 0;
}
#styleCoins .cur { display: flex; align-items: center; gap: 3px;
  padding: 4px 9px; border-radius: 999px; background: rgba(8, 13, 32, .66);
  border: 1px solid rgba(150, 200, 255, .22); }
#styleCoins .cur img { width: 13px; height: 13px; object-fit: contain; }
#styleCoins .snow { color: #bfe9ff; }
#styleCoins .gold { color: #ffb0d8; }
#stageToggle { min-width: 40px; }

#deptStrip {
  flex: 0 0 52px; display: flex; gap: 6px; align-items: center;
  padding: 0 12px; overflow-x: auto; overflow-y: hidden;
  touch-action: pan-x; -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain; scrollbar-width: none;
  border-bottom: 1px solid rgba(140, 190, 255, .16);
}
#deptStrip::-webkit-scrollbar { display: none; }
#deptStrip button {
  flex: 0 0 auto; height: 44px; padding: 0 14px; border-radius: 999px;
  border: 1px solid rgba(140, 190, 255, .25); background: rgba(120, 170, 255, .10);
  color: #cfe7ff; font: 800 12px system-ui; cursor: pointer; white-space: nowrap;
}
#deptStrip button.sel { background: #2d6cdf; color: #fff; border-color: #9fd0ff; }
#deptStrip button[data-tab="event"] { border-color: rgba(181, 143, 255, .58); color: #eadfff; }

#shopScroll {
  flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 10px 14px 14px;
  touch-action: pan-y; -webkit-overflow-scrolling: touch; overscroll-behavior: contain;
}
#stylePanel.sheet #itemGrid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px;
  max-height: none; overflow: visible; touch-action: auto;
}
#deptNote {
  font: 600 11.5px/1.35 system-ui; color: #9fb8e6; margin-bottom: 9px;
  padding: 8px 10px; border-radius: 10px; background: rgba(120, 170, 255, .07);
  border: 1px solid rgba(140, 190, 255, .16);
}
#eventCollectionBanner {
  display: grid; gap: 2px; margin-bottom: 9px; padding: 10px 12px; border-radius: 12px;
  background: linear-gradient(115deg, rgba(111, 84, 211, .33), rgba(53, 199, 204, .18));
  border: 1px solid rgba(184, 157, 255, .58); box-shadow: inset 0 1px rgba(255,255,255,.12);
}
#eventCollectionBanner .eventEyebrow { font: 900 9px/1 system-ui; letter-spacing: 1.2px; color: #d6c4ff; }
#eventCollectionBanner strong { font: 900 15px/1.15 system-ui; color: #f0eaff; }
#eventCollectionBanner > span:last-child { font: 600 10.5px/1.3 system-ui; color: #c7dff5; }
#gridEmpty { font: 600 13px system-ui; color: #9fb8e6; text-align: center; padding: 26px 10px; }

/* cells are <button>s now — a <div> with a title is an invisible tooltip on iOS */
#stylePanel.sheet .item {
  position: relative; height: 124px; border-radius: 14px; overflow: hidden;
  border: 2px solid rgba(140, 190, 255, .25); background: rgba(120, 170, 255, .08);
  display: grid; grid-template-rows: 78px 24px 20px; padding: 0; margin: 0;
  color: inherit; font: inherit; text-align: center; cursor: pointer; width: 100%;
}
.item .art { display: flex; align-items: center; justify-content: center; min-height: 0; }
.item .art img, .item .art canvas { max-width: 72px; max-height: 74px; }
.item .art .swatch { width: 52px; height: 52px; border-radius: 50%;
                     border: 2px solid rgba(255, 255, 255, .35); }
.item .nm { font: 700 11px/12px system-ui; color: #cfe7ff; padding: 0 4px;
            display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
            overflow: hidden; }
.item .foot { font: 900 11px system-ui; display: flex; align-items: center;
              justify-content: center; gap: 3px; }
.item .foot img { width: 12px; height: 12px; object-fit: contain; }
.item .foot.snow { color: #bfe9ff; }
.item .foot.gold { color: #ffb0d8; }
.item .foot.own { color: #8affc0; }
.item .foot.event { color: #d7c2ff; font-size: 9px; letter-spacing: .35px; }
.item.wearing { border-color: #7fd0ff; box-shadow: 0 0 12px rgba(90, 180, 255, .5); }
.item.owned { border-color: rgba(138, 255, 192, .55); }
.item.tryon { border-style: dashed; border-color: #ffd98a; }
.item.eventItem { border-color: rgba(183, 145, 255, .56); background: linear-gradient(145deg, rgba(112, 78, 202, .20), rgba(79, 208, 192, .10)); }
/* vh_santa carries BOTH isNew and limited, so these stacked on top of each
   other — three separate corners instead */
#stylePanel.sheet .item .newTag { top: 3px; left: 3px; right: auto; }
#stylePanel.sheet .item .lock   { top: 3px; right: 3px; left: auto; }
#stylePanel.sheet .item .furnN  { bottom: 24px; right: 4px; top: auto; left: auto; }
#stylePanel.sheet .item .eventTag {
  position: absolute; top: 3px; right: 3px; z-index: 1; padding: 2px 5px; border-radius: 6px;
  border: 1px solid rgba(220, 197, 255, .50); background: rgba(26, 14, 62, .82);
  color: #e5d5ff; font: 900 8px/1 system-ui; letter-spacing: .55px;
}

#nameRow { display: flex; align-items: center; gap: 10px; margin-top: 14px;
           padding-top: 12px; border-top: 1px solid rgba(140, 190, 255, .16); }
#nameRow label { font: 700 12px system-ui; color: #9fb8e6; flex: 0 0 auto; }
#nameRow input { flex: 1; min-width: 0; height: 44px; }
#stylePanel.sheet #memberRow { margin-top: 12px; }

/* permanent — never hidden, so it can never reflow the grid under a finger */
#stylePanel.sheet #buyRow {
  flex: 0 0 auto; display: flex; align-items: center; gap: 10px;
  padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
  border-top: 1px solid rgba(140, 190, 255, .22);
  background: linear-gradient(180deg, #131b40, #0b1029);
  /* lifts the bar off the grid so it reads as a fixed action strip rather
     than the last row of items */
  box-shadow: 0 -10px 24px rgba(4, 8, 24, .55);
}
/* picture of the selected item, so the verb and the thing it acts on are
   next to each other instead of a thumb's width apart */
#buyThumb {
  flex: 0 0 auto; width: 46px; height: 46px; border-radius: 12px;
  display: grid; place-items: center; overflow: hidden;
  background: rgba(120, 165, 235, .10);
  border: 1px solid rgba(140, 190, 255, .22);
}
/* With nothing selected there is no picture to show, and an empty bordered
   square reads as a thumbnail that failed to load. Collapse it instead, which
   also gives the "Tap anything to try it on" hint the width it needs. */
#buyThumb.empty { display: none; }
#buyThumb img, #buyThumb canvas { width: 100%; height: 100%; object-fit: contain; }
#buyThumb .swatch { width: 30px; height: 30px; border-radius: 50%; }
#buyText { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
#buyLabel { font: 800 15px system-ui; color: #f2f8ff; letter-spacing: .2px;
            white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#buySub { font: 600 11.5px system-ui; color: #9fb8e6;
          white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

#stylePanel.sheet #wishBtn {
  width: 46px; height: 46px; flex: 0 0 auto; font-size: 20px;
  border-radius: 14px; border: 1px solid rgba(255, 138, 168, .45);
  background: rgba(255, 138, 168, .08); color: #ff9dba;
  transition: transform .12s ease, background .15s ease;
}
#stylePanel.sheet #wishBtn:active { transform: scale(.94); }
#stylePanel.sheet #wishBtn.on { background: rgba(255, 138, 168, .28); color: #ffd3df;
                                border-color: rgba(255, 138, 168, .8); }
#stylePanel.sheet #wishBtn:disabled { opacity: .3; }

/* One button, five states. Each gets its own fill instead of dimming one gold
   pill, because a 45%-opacity gold on navy lands on a muddy olive that looks
   like a rendering fault rather than a disabled control. */
#stylePanel.sheet #buyBtn {
  flex: 0 0 auto; min-width: 116px; height: 50px; padding: 0 18px;
  border-radius: 14px; border: 1px solid transparent;
  font: 900 15px/1 system-ui; letter-spacing: .6px;
  transition: transform .12s ease, filter .15s ease;
}
#stylePanel.sheet #buyBtn:active:not(:disabled) { transform: scale(.96); }
#stylePanel.sheet #buyBtn.is-buy {
  background: linear-gradient(180deg, #ffd27a, #f5a623); color: #2a1804;
  box-shadow: 0 4px 14px rgba(245, 166, 35, .35);
}
#stylePanel.sheet #buyBtn.is-wear {
  background: linear-gradient(180deg, #7fd8a6, #33a86d); color: #04240f;
  box-shadow: 0 4px 14px rgba(51, 168, 109, .32);
}
#stylePanel.sheet #buyBtn.is-event {
  background: linear-gradient(180deg, #d6c4ff, #8f69df); color: #170a39;
  box-shadow: 0 4px 14px rgba(143, 105, 223, .35);
}
#stylePanel.sheet #buyBtn.is-goal {
  background: rgba(120, 165, 235, .14); color: #cfe3ff;
  border-color: rgba(140, 190, 255, .45);
}
/* the two genuinely unavailable states: flat, quiet, unmistakably inert */
#stylePanel.sheet #buyBtn.is-worn,
#stylePanel.sheet #buyBtn.is-locked {
  background: rgba(140, 190, 255, .10); color: #8fa8cc;
  border-color: rgba(140, 190, 255, .20); box-shadow: none;
}
#stylePanel.sheet #buyBtn:disabled { opacity: 1; cursor: default; }

@media (min-width: 700px) {
  #stylePanel.sheet { left: 50%; right: auto; transform: translateX(-50%);
    top: 4vh; bottom: 4vh; width: min(680px, 92vw); border-radius: 20px; }
  #stylePanel.sheet #itemGrid { grid-template-columns: repeat(4, 1fr); }
}

/* Hub's floating buttons must not sit on top of an open panel — see
   UI.openPanel. They are fixed at z-index 58 on <body>, outside #stage. */
body.panelOpen #newsBtn,
body.panelOpen #petsBtn,
body.panelOpen #evBanner { display: none !important; }

/* CLUB/LTD had no chip behind them while NEW did, so they read as loose text
   sitting on top of the item art. Same treatment, opposite corner. */
#stylePanel.sheet .item .lock {
  font: 900 9px system-ui; letter-spacing: .5px; padding: 2px 5px;
  border-radius: 6px; background: rgba(8, 13, 32, .82); color: #ffd98a;
  border: 1px solid rgba(255, 217, 138, .45);
}

/* emote wheel: the painted penguin plus a small symbol badge.
   Selector must out-specify `#emoteWheel button img` (34px) above — an id
   selector beats a bare class, which sized the badge as a second icon. */
#emoteWheel button { position: relative; }
#emoteWheel button img.emoBadge {
  position: absolute; right: 0; bottom: 13px; width: 16px; height: 16px;
  margin: 0; object-fit: contain; pointer-events: none;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .65));
}

/* ---- HUD row geometry -------------------------------------------------
   The button pill measured 52px tall against 38px for the name and balance
   beside it — visibly taller and heavier than the rest of the row. Everything
   in the row is now the same 44px height, and the pill's own padding is gone
   so it does not add to it. Touch targets stay 44px. */
#nameTag, #coins { height: 44px; }
#hudBtns { padding: 0 2px; }
.hudbtn { height: 44px; }
.hudbtn .hud-icon { width: 22px; height: 22px; }
/* MAP / ME / LB are icons now, so the name can have the width it needs —
   "Penguin559" wanted 103px and was being clipped to 73px at 20vw. */
@media (max-width: 430px) {
  #nameTag { max-width: 40vw; }
}

/* ---- identity pill: level badge + name (+ club star) ------------------- */
#nameTag { gap: 6px; padding: 0 11px 0 4px; }
.lvChip {
  flex: 0 0 auto; min-width: 24px; height: 26px; padding: 0 5px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 999px; background: rgba(120, 170, 255, .22);
  border: 1px solid rgba(150, 200, 255, .35);
  font: 900 12px system-ui; color: #cfe7ff; letter-spacing: 0;
}
.lvChip.club { background: rgba(255, 205, 110, .22); border-color: rgba(255, 205, 110, .5); color: #ffd98a; }
#nameTag .nmText { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#nameTag .clubStar { flex: 0 0 auto; color: #ffd98a; font-size: 12px; }

/* four HUD buttons now fit at the full 44px touch width on a 390px phone */
@media (max-width: 430px) {
  .hudbtn { min-width: 44px; padding: 0 2px; }
}
.hudbtn .hud-icon { width: 24px; height: 24px; }

/* leaderboards, rehoused in the profile panel */
.profBoard { display: flex; align-items: center; justify-content: center; gap: 8px; margin: 12px 0 4px; }
.profBoard .hud-icon { width: 20px; height: 20px; }

/* The row's shrink policy, stated explicitly. #coins and #hudBtns are both
   flex-shrink:0, so if the LEFT side is not the flexible one the row simply
   overflows the viewport — which it did (19px past the right edge at 375px).
   The name is the only thing here that can lose width gracefully. */
#hudLeft  { flex: 1 1 auto; min-width: 0; }
#hudRight { flex: 0 0 auto; }

#profActions { display: flex; flex-direction: column; gap: 8px; margin: 14px 0 4px; }
#profActions .profBoard { margin: 0; }

/* ---- HUD: three real columns ------------------------------------------
   Was a two-part space-between row, which parked the balance hard against
   the button pill with a ~107px void beside the name — it read as "not
   centred" because it wasn't. A 1fr / auto / 1fr grid gives the balance its
   own centre column, so it sits mid-screen whatever the name and buttons do.
   The equal side columns also bound the name, so the vw caps below are gone:
   they were tuned for a 375px phone and left a 440px one worse off — the base
   25vw cap gave the name 63px for 81px of text and truncated it with an
   ellipsis on the WIDER device. */
#hud {
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 8px;
}
#hudLeft   { justify-self: start;  min-width: 0; }
#hudCenter { justify-self: center; min-width: 0; display: flex; align-items: center; }
#hudRight  { justify-self: end;    min-width: 0; }
/* the grid column is the constraint now, not a viewport fraction */
#nameTag { max-width: 100%; }
@media (max-width: 430px) { #nameTag { max-width: 100%; } }

/* ------- illustrated island map (mapPanel) ------- */
#islandMap {
  container-type: inline-size;   /* .mapSpot labels size off THIS, see below */
  position: relative; border-radius: 14px; overflow: hidden;
  border: 1px solid rgba(150, 200, 255, .25);
  box-shadow: 0 6px 22px rgba(0, 0, 0, .35);
  background: #0a1230;
}
#islandMap img { display: block; width: 100%; height: auto; pointer-events: none; }
.mapSpot {
  position: absolute; transform: translate(-50%, -50%);
  background: rgba(9, 15, 38, .78); color: #dff1ff;
  border: 1.5px solid rgba(140, 210, 255, .55); border-radius: 999px;
  /* Pins are pinned in PERCENTAGES of the painting, so their labels have to
     shrink with it too — sized against the map's own width (not the
     viewport), five fixed-size pills on a narrow phone map overlapped into
     an unreadable pile. em padding keeps the pill shape at every size. */
  padding: .42em .82em; letter-spacing: .05em; white-space: nowrap;
  font: 800 clamp(7px, 3.1cqw, 13px)/1 system-ui;
  cursor: pointer;
  transition: transform .15s ease, background .15s ease;
}
.mapSpot:hover { transform: translate(-50%, -50%) scale(1.08); background: rgba(30, 60, 130, .85); }
.mapSpot.here {
  border-color: #ffe9a8; color: #ffe9a8; background: rgba(60, 45, 10, .8);
  cursor: default;
}
.mapSpot.here::after {
  content: ''; position: absolute; inset: -7px; border-radius: 999px;
  border: 2px solid rgba(255, 233, 168, .7); animation: mapPulse 1.6s ease-out infinite;
  pointer-events: none;
}
@keyframes mapPulse {
  0% { transform: scale(.9); opacity: .9; }
  100% { transform: scale(1.35); opacity: 0; }
}

/* eye-colour swatch: a big iris disc — sclera ring, coloured iris, pupil,
   sparkle — so four colours read apart instantly at thumbnail size */
.irisChip {
  width: 56px; height: 56px; border-radius: 50%;
  background:
    radial-gradient(circle at 38% 34%, rgba(255,255,255,.95) 0 12%, transparent 13%),
    radial-gradient(circle at 50% 52%, #10142a 0 17%, transparent 18%),
    radial-gradient(circle at 50% 52%, var(--iris) 0 40%, transparent 41%),
    #f4f9ff;
  border: 2px solid #1a2036; box-shadow: inset 0 -3px 6px rgba(20,30,60,.18);
}

/* an undiscovered secret room: a nameless shimmer out on the map's water */
.mapSpot.secret {
  /* scales with the map like the labels do, and never shrinks below a
     comfortable tap target */
  padding: 0; border-radius: 50%;
  width: clamp(20px, 5cqw, 30px); height: clamp(20px, 5cqw, 30px);
  background: rgba(190, 235, 255, .16);
  border: 1.5px solid rgba(200, 240, 255, .34);
  box-shadow: 0 0 10px rgba(160, 220, 255, .35);
  animation: secretShimmer 3.4s ease-in-out infinite;
}
.mapSpot.secret:hover {
  background: rgba(210, 245, 255, .34);
  border-color: rgba(225, 250, 255, .7);
}
@keyframes secretShimmer {
  0%, 100% { opacity: .35; }
  50%      { opacity: .8; }
}
