:root {
  --bg: #1b2733;
  --panel: #243645;
  --panel-2: #2c4252;
  --line: #3b566a;
  --text: #dfe6ee;
  --muted: #93a6b8;
  --accent: #ffd65a;
  --shaman: #98e2eb;
  --good: #2ecf73;
  --bad: #e2687a;
  --game: #6a7495;
  color-scheme: dark;
}

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 13px/1.4 Verdana, "Segoe UI", sans-serif;
}

#app {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 230px;
  grid-template-rows: auto auto minmax(160px, 1fr);
  grid-template-areas: "hud hud" "stage side" "chat side";
  gap: 8px;
  height: 100%;
  max-width: 1280px;
  margin: 0 auto;
  padding: 8px 16px 12px;
}

#hud {
  grid-area: hud;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 18px;
  padding: 8px 12px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 8px;
}
.brand { font-size: 15px; color: var(--accent); margin-right: 6px; }
.brand span { color: var(--muted); font-weight: normal; font-size: 12px; }
.stat { display: flex; flex-direction: column; min-width: 0; }
.stat.wide { flex: 1 1 200px; }
.stat .label { font-size: 10px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); }
.stat span:last-child { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.stat.me span:last-child { color: var(--accent); }
#menuBar { display: flex; gap: 6px; margin-left: auto; }
#menuBar button {
  padding: 6px 12px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--panel-2);
  color: var(--text);
  font: 12px Verdana, sans-serif;
  cursor: pointer;
}
#menuBar button:hover { border-color: var(--accent); color: var(--accent); }
#timer { font-variant-numeric: tabular-nums; }

#stage {
  grid-area: stage;
  position: relative;
  aspect-ratio: 2 / 1;
  width: 100%;
  background: var(--game);
  border: 1px solid var(--line);
  border-radius: 8px;
  overflow: hidden;
}
#game { position: absolute; inset: 0; }
#game canvas { display: block; }
#overlay { position: absolute; transform-origin: 0 0; pointer-events: none; }
.line.markup a { color: inherit; text-decoration: underline; cursor: pointer; }

#sidebar {
  grid-area: side;
  display: flex;
  flex-direction: column;
  min-height: 0;
  padding: 10px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 8px;
}
#sidebar h2 { margin: 0 0 6px; font-size: 12px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); }
#playerList { list-style: none; margin: 0; padding: 0; overflow-y: auto; flex: 1; }
#playerList li {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas: "name score";
  padding: 5px 6px;
  border-radius: 6px;
}
#playerList li:nth-child(odd) { background: rgba(255, 255, 255, 0.03); }
#playerList .name { grid-area: name; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#playerList .score { grid-area: score; align-self: center; font-variant-numeric: tabular-nums; color: var(--muted); }
#playerList li.me .name { color: var(--accent); }
.help { margin-top: 8px; border-top: 1px solid var(--line); padding-top: 8px; color: var(--muted); }
.help summary { cursor: pointer; color: var(--text); }
.help dl { display: grid; grid-template-columns: auto 1fr; gap: 3px 8px; margin: 8px 0 0; font-size: 11px; }
.help dt { color: var(--text); }
.help dd { margin: 0; }

#chat {
  grid-area: chat;
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 8px;
  overflow: hidden;
}
#chatBody { flex: 1; display: flex; min-height: 0; }
#chatLog {
  flex: 1; min-width: 0; overflow-y: auto; padding: 8px 10px;
  font-family: var(--chat-font, inherit); /* /font (js/chattabs.js) */
}
.line { padding: 1px 0; word-wrap: break-word; }
/* Players' lines carry the latest client's tag colours themselves (LINE_FORMS in main.js); these are the rest: the
   server's lines with no tag in its #6C77C1, and this client's own notes. Links as its stylesheet has them (m87). */
.line .who { color: #009d9d; }
.line.system, .line.markup { color: #6c77c1; }
.line.event { color: #a4cf9e; }
.line.whisper, .line.whisper .who { color: #ed67ea; }
.line a:hover { color: #2ecf73; }
.line a:active { color: #e9e654; }
/* The chat's bar (js/chattabs.js, main.js setupChatBar): its pictures in a row with the box, as the latest client's. */
#chatBar { position: relative; display: flex; align-items: center; gap: 2px; }
.chat-icon {
  flex: none; display: grid; place-items: center; width: 20px; height: 20px; padding: 0;
  border: 0; background: none; box-shadow: none; line-height: 0; cursor: pointer;
}
.chat-icon[hidden] { display: none; }
.chat-icon img { width: calc(var(--w, 18) * var(--u, 1px)); height: calc(var(--h, 18) * var(--u, 1px)); pointer-events: none; }
/* "To the last line" is greyed (its colours times 0.55) while the last line is in sight, and glows #93D329 every
   other half second while new lines wait below (n2892, n10272). */
#chatNew.dim { cursor: default; }
#chatNew.dim img { filter: brightness(0.55); }
#chatNew.glow img { filter: drop-shadow(0 0 1px #93d329) drop-shadow(0 0 1px #93d329) drop-shadow(0 0 1px #93d329); }
/* The box: the interface's brown (#3E2C1D) at 0.6 of its light and 0.8 seen, with the corners of 3 and the edge sunk
   by one pixel (black above and to the left, white at half below and to the right: its BevelFilter); the target's
   name before what is typed, in the target's colour (n6983), the words in #C2C2DA. */
#chatField {
  flex: 1; min-width: 0; display: flex; align-items: center; cursor: text;
  background: rgba(37, 26, 17, 0.8); border-radius: 3px;
  box-shadow: inset 1px 1px 0 #000, inset -1px -1px 0 rgba(255, 255, 255, 0.5);
}
#chatPrefix { flex: none; white-space: pre; padding: 0 2px 0 3px; }
#chatInput { flex: 1; min-width: 0; border: 0; background: transparent; color: #c2c2da; padding: 2px 3px; font: inherit; outline: none; }
html.guest #chatFriends, html.guest #chatTribe { display: none; }
/* The shown tabs' names (n3797): a column at the left of the lines from two of them on, 17 a row, as wide as the
   widest name and 90 at most, the lines 10 past it; the tab in the log in #009D9D, one with lines unread in #ED67EA
   after its count in #BABD2F, the others in the chat's #C2C2DA (n2095.n8451; the colours are set by chattabs.js). */
#chatTabs { display: none; }
#chat.tabbed #chatTabs {
  display: flex; flex: none; flex-direction: column; align-self: flex-start; max-height: calc(100% - 10px);
  overflow-y: auto; scrollbar-width: none; padding-left: 2px;
}
#chat.tabbed #chatTabs::-webkit-scrollbar { display: none; }
#chat.tabbed #chatLog { margin-left: 8px; }
.chat-tab {
  display: block; height: 17px; max-width: 90px; padding: 0; border: 0; background: none; box-shadow: none;
  font: 12px/17px Verdana, sans-serif; color: #c2c2da; white-space: pre; overflow: hidden; text-align: left; cursor: pointer;
}
.chat-tab .count { color: #babd2f; }
/* The chat grown over the play (n2861): 350 more upwards, on the interface's brown at 0.95 with its top corners
   rounded by 10. */
#chat.big { background: rgba(62, 44, 29, 0.95); }
#emoteMenu {
  position: absolute;
  right: 6px;
  bottom: calc(100% + 6px);
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 6px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 8px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.35);
  z-index: 5;
}
#emoteMenu[hidden] { display: none; }
#emoteMenu button {
  padding: 2px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--panel-2);
  color: var(--text);
  line-height: 0;
  cursor: pointer;
}
#emoteMenu button:hover { border-color: var(--accent); }

#shamanBar, #transformBar { display: flex; gap: 6px; padding: 6px 8px; border-bottom: 1px solid var(--line); background: var(--panel-2); overflow-x: auto; }
#shamanBar[hidden], #transformBar[hidden] { display: none; }
#shamanBar button, #transformBar button {
  position: relative;
  display: grid;
  place-items: center;
  width: 54px;
  height: 46px;
  flex: none;
  background: #1f2f3c;
  border: 1px solid var(--line);
  border-radius: 6px;
  cursor: pointer;
}
#shamanBar button img, #transformBar button img { max-width: 44px; max-height: 34px; }
#shamanBar button span, #transformBar button span { position: absolute; top: 1px; left: 4px; font-size: 10px; color: var(--muted); }
#shamanBar button.active, #transformBar button.active { border-color: var(--shaman); box-shadow: 0 0 0 1px var(--shaman); }

.modal {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 16px;
  background: rgba(10, 16, 22, 0.72);
  z-index: 10;
}
.modal[hidden] { display: none; }
.card {
  width: min(360px, 100%);
  padding: 22px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.4);
}
.card h1 { margin: 0; color: var(--accent); font-size: 24px; }
.card .sub { margin: 2px 0 16px; color: var(--muted); }
.card label, .card .label { display: block; margin-top: 10px; color: var(--muted); font-size: 12px; }
.card input {
  display: block;
  width: 100%;
  margin-top: 4px;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--panel-2);
  color: var(--text);
  font: inherit;
}
.card input:focus { outline: 2px solid var(--accent); outline-offset: 0; }
#loginTabs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; padding: 3px; background: var(--bg); border-radius: 8px; }
#loginTabs button { padding: 6px; border: 0; border-radius: 6px; background: transparent; color: var(--muted); font: inherit; cursor: pointer; }
#loginTabs button[aria-selected="true"] { background: var(--panel-2); color: var(--text); }
.captcha { display: flex; gap: 6px; align-items: center; margin-top: 4px; }
.captcha canvas { height: 34px; width: auto; image-rendering: pixelated; background: #fff; border-radius: 4px; }
.captcha button { width: 34px; height: 34px; border: 1px solid var(--line); border-radius: 6px; background: var(--panel-2); color: var(--text); cursor: pointer; }
button.primary {
  width: 100%;
  margin-top: 16px;
  padding: 10px;
  border: 0;
  border-radius: 8px;
  background: var(--accent);
  color: #1b2733;
  font: bold 14px Verdana, sans-serif;
  cursor: pointer;
}
#loginForm.busy button.primary { opacity: 0.55; pointer-events: none; }
#loginStatus { min-height: 1.4em; margin: 10px 0 0; color: var(--bad); }
#loginStatus.good { color: var(--good); }
#loginPassword.refused { color: #ff0000; } /* a refused login's words, as the latest client writes them there (m7367) */
.dialog { width: min(560px, 100%); max-height: 80vh; overflow: auto; }

.panel { width: min(560px, 100%); max-height: 86vh; display: flex; flex-direction: column; padding: 16px 18px; }
.panel-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.panel-head h2 { margin: 0; font-size: 17px; color: var(--accent); }
.close { width: 30px; height: 30px; border: 1px solid var(--line); border-radius: 6px; background: var(--panel-2); color: var(--text); font-size: 18px; line-height: 1; cursor: pointer; }
.close:hover { border-color: var(--accent); }
.tabs { display: flex; flex-wrap: wrap; gap: 4px; padding: 3px; background: var(--bg); border-radius: 8px; }
.tabs button { padding: 6px 10px; border: 0; border-radius: 6px; background: transparent; color: var(--muted); font: 12px Verdana, sans-serif; cursor: pointer; }
.tabs button[aria-selected="true"] { background: var(--panel-2); color: var(--text); }
/* The latest's room window (n2148, 670 by 340): the rooms on the left, 330 wide; the modes' pictures, the chosen
   mode's words and the two buttons on the right. On a narrow screen the right side goes on top. */
.panel.rooms { width: min(690px, 100%); height: min(430px, 86vh); }
.rooms-body { display: flex; gap: 16px; flex: 1; min-height: 0; }
.rooms-left { flex: 1 1 330px; display: flex; flex-direction: column; min-height: 0; min-width: 0; }
.rooms-right { flex: 0 0 276px; display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.rooms-right .primary-action { padding: 6px 10px; font-size: 13px; }
.rooms-right #roomCreateOpen { margin-top: auto; }
.rooms-right #roomCreateOpen[hidden] + .primary-action { margin-top: auto; }
.room-head { display: flex; justify-content: space-between; padding: 0 22px 0 30px; color: #60608f; font: 12px Verdana, sans-serif; }
.room-list { list-style: none; margin: 4px 0 6px; padding: 0; overflow-y: auto; min-height: 60px; flex: 1; }
.room-list .empty { padding: 10px; color: var(--muted); }
.room-list .room {
  display: flex; align-items: center; gap: 4px; width: 100%; height: 22px; padding: 0 2px;
  background: none; border: 0; border-radius: 0; box-shadow: none; font: 12px Verdana, sans-serif; cursor: pointer; text-align: left;
}
/* A row under the pointer: the latest's #314E57 (m3289, n5263). */
.room-list .room:hover { background: #314e57; }
.room-flag { width: 24px; height: 16px; object-fit: contain; flex: none; }
.room-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.room.quick .room-name { color: #babd2f; }
.room.funcorp .room-name { color: #ff8547; }
.room.own .room-name { color: #ffd991; }
.room.other .room-name { color: #6c77c0; }
.room-count { flex: 0 0 60px; text-align: center; color: #60608f; font-variant-numeric: tabular-nums; }
.room-stars { display: block; width: 20px; height: 20px; flex: none; }
.room-stars img { display: block; width: 20px; height: 20px; object-fit: contain; }
html.mobile .room-stars { width: 34px; height: 34px; padding: 7px; box-sizing: border-box; margin-right: -7px; }
.room-search input { width: 100%; box-sizing: border-box; padding: 4px 8px; font: 12px Verdana, sans-serif; }
.room-modes { display: flex; flex-wrap: wrap; gap: 10px; }
.room-modes.waiting { pointer-events: none; }
.mode-tile {
  position: relative; width: 70px; height: 70px; padding: 0; border: 0; border-radius: 0; background: #000; cursor: pointer; flex: none;
  box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.5), inset -1px -1px 0 rgba(0, 0, 0, 0.8);
}
.mode-tile img { display: block; width: 70px; height: 70px; }
.mode-tile span {
  position: absolute; left: 0; right: 0; bottom: 0; height: 20px; line-height: 20px; background: rgba(0, 0, 0, 0.8);
  color: #6c77c0; font: 12px Verdana, sans-serif; text-align: center; white-space: nowrap; overflow: hidden;
}
.mode-tile[data-mode="1"] span { font-size: 9px; }
.mode-tile[data-mode="16"] span { color: #009d9d; }
/* The chosen one: a fifth darker, its edge pressed in, its name yellow, and no click (m3418). */
.mode-tile[aria-selected="true"] { cursor: default; box-shadow: inset 2px 2px 0 rgba(0, 0, 0, 0.9), inset -2px -2px 0 rgba(255, 255, 255, 0.5); }
.mode-tile[aria-selected="true"] img { filter: brightness(0.8); }
.mode-tile[aria-selected="true"] span { color: #babd2f; }
.room-mode-info { margin: 0; color: #c2c2da; font: 12px/1.35 Verdana, sans-serif; }
.room-mode-info strong { display: block; color: #2ecf73; font-size: 14px; font-weight: normal; }
.room-tip {
  position: absolute; z-index: 5; max-width: 260px; padding: 3px 6px; background: #222233; border: 2px solid #000;
  color: #009d9d; font: 11px Verdana, sans-serif; pointer-events: none; white-space: nowrap;
}
.room-tip[hidden] { display: none; }
@media (max-width: 720px) {
  .panel.rooms { height: 92vh; height: 92dvh; }
  .rooms-body { flex-direction: column-reverse; gap: 8px; }
  .rooms-left { flex: 1 1 auto; }
  .rooms-right { flex: none; width: auto; }
  .room-modes { flex-wrap: nowrap; overflow-x: auto; gap: 8px; padding-bottom: 2px; }
  .rooms-right #roomCreateOpen, .rooms-right #roomCreateOpen[hidden] + .primary-action { margin-top: 0; }
  .rooms-right { display: grid; grid-template-columns: 1fr 1fr; }
  .rooms-right .room-modes, .rooms-right .room-mode-info { grid-column: 1 / -1; }
  .rooms-right #roomCreateOpen[hidden] + .primary-action { grid-column: 1 / -1; }
}
/* A short screen (a phone held sideways): the modes' pictures in one row that scrolls, the buttons side by side. */
@media (max-height: 520px) and (min-width: 721px) {
  .panel.rooms { height: 96vh; height: 96dvh; }
  .room-modes { flex-wrap: nowrap; overflow-x: auto; gap: 8px; flex: none; padding-bottom: 2px; }
  .rooms-right { display: grid; grid-template-columns: 1fr 1fr; align-content: start; overflow-y: auto; }
  .rooms-right .room-modes, .rooms-right .room-mode-info { grid-column: 1 / -1; }
  .rooms-right #roomCreateOpen, .rooms-right #roomCreateOpen[hidden] + .primary-action { margin-top: 0; }
  .rooms-right #roomCreateOpen[hidden] + .primary-action { grid-column: 1 / -1; }
}
html.mobile .room-list .room { height: 34px; font-size: 14px; }
html.mobile .room-search input { padding: 8px 10px; font-size: 16px; }
/* The "Create a room" window (m10708, 320 by 355): a row for each setting. */
.panel.room-create { width: min(360px, 100%); }
.room-create-form { display: flex; flex-direction: column; gap: 5px; overflow-y: auto; min-height: 0; font: 12px Verdana, sans-serif; }
.room-create-form .create-row { display: flex; align-items: center; gap: 6px; margin: 0; color: #c2c2da; font-size: 12px; }
.room-create-form .create-label { flex: none; }
.room-create-form .create-row input, .room-create-form .create-row select { flex: 1; min-width: 0; padding: 3px 6px; font: 12px Verdana, sans-serif; }
.room-create-form .create-number { flex: 0 0 60px !important; margin-left: auto; text-align: right; }
.room-create-form .create-prefix { color: #ffd991; white-space: pre; flex: none; }
.room-create-form .create-check { display: flex; align-items: center; gap: 6px; margin: 0; color: #c2c2da; font-size: 12px; cursor: pointer; }
.room-create-form button[type="submit"] { margin-top: 6px; padding: 6px 10px; }
html.mobile .room-create-form .create-row input, html.mobile .room-create-form .create-row select { font-size: 16px; padding: 6px 8px; }
html.mobile .room-create-form .create-check { min-height: 30px; font-size: 14px; }

#profileBody { overflow-y: auto; }
/* One's own titles are links in the text's colour, as the latest client's stylesheet has links (m87). */
#profileBody a { color: inherit; text-decoration: none; }
#profileBody a:hover { color: #2ecf73; }
#profileBody a:active { color: #e9e654; }
#profileBody .title-search { display: block; margin: 4px 0 6px; width: min(220px, 100%); font: 12px Verdana, sans-serif; }
.profile-head { display: flex; gap: 14px; align-items: center; }
.profile-head h2 { margin: 0 0 4px; color: var(--accent); font-size: 20px; }
.portrait { flex: none; display: grid; place-items: center; width: 110px; height: 110px; border-radius: 10px; background: var(--game); }
.portrait canvas { max-width: 100%; max-height: 100%; }
#profileBody h3 { margin: 14px 0 6px; font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); }
.muted { margin: 2px 0; color: var(--muted); }
.small { font-size: 11px; margin-top: 12px; }
.stats { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 6px; margin: 0; }
.stat-row { padding: 6px 8px; background: var(--panel-2); border-radius: 6px; }
.stat-row dt { font-size: 10px; color: var(--muted); }
.stat-row dd { margin: 2px 0 0; font-size: 15px; font-variant-numeric: tabular-nums; }
#playerList .name { cursor: pointer; }
#playerList .name:hover { text-decoration: underline; }
#dialogBody { color: #c2c2da; }

@media (max-width: 760px) {
  #app {
    grid-template-columns: 1fr;
    grid-template-rows: auto auto minmax(180px, 1fr) auto;
    grid-template-areas: "hud" "stage" "chat" "side";
    height: auto;
    min-height: 100%;
  }
  #sidebar { max-height: 240px; }
  .stat.wide { flex-basis: 100%; }
}

/* Shop */
.panel.shop { width: min(980px, 100%); height: min(640px, 90vh); }
.wallet { display: flex; gap: 14px; margin-left: auto; margin-right: 12px; }
.price { display: inline-flex; align-items: center; gap: 4px; font-variant-numeric: tabular-nums; }
.price img { height: 14px; width: auto; }
.shop-body { display: grid; grid-template-columns: 210px minmax(0, 1fr); gap: 12px; margin-top: 10px; min-height: 0; flex: 1; }
#shopSide { display: flex; flex-direction: column; gap: 10px; min-height: 0; overflow-y: auto; }
.shop-preview { display: grid; place-items: center; min-height: 170px; border-radius: 10px; background: var(--game); }
.shop-preview canvas { max-width: 100%; }
.shop-info h3 { margin: 0 0 6px; font-size: 14px; color: var(--accent); }
.shop-actions, .colors { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.shop-actions button, .colors button, .outfit button {
  display: inline-flex; align-items: center; justify-content: center; gap: 4px; padding: 8px 10px;
  border: 1px solid var(--line); border-radius: 6px; background: var(--panel-2); color: var(--text); font: 12px Verdana, sans-serif; cursor: pointer;
}
.shop-actions button:hover:not(:disabled), .colors button:hover:not(:disabled), .outfit button:hover:not(:disabled) { border-color: var(--accent); }
.shop button:disabled { opacity: 0.45; cursor: not-allowed; }
button.primary-action { background: var(--accent); color: #1b2733; border-color: var(--accent); font-weight: bold; }
.color-row { display: flex; flex-wrap: wrap; gap: 6px; }
.color-row input { width: 34px; height: 30px; padding: 0; border: 1px solid var(--line); border-radius: 6px; background: var(--panel-2); cursor: pointer; }
.shop-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(92px, 1fr)); grid-auto-rows: min-content; gap: 8px; overflow-y: auto; min-height: 0; padding: 2px; align-content: start; }
.tile {
  position: relative; display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 6px;
  border: 1px solid var(--line); border-radius: 8px; background: var(--panel-2); color: var(--text); font: 11px Verdana, sans-serif; cursor: pointer;
}
.tile:hover { border-color: var(--accent); }
.tile.selected { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.tile.wearing { background: #2f4a3b; }
.tile-art { display: grid; place-items: center; width: 72px; height: 62px; }
.tile-art canvas { max-width: 72px; max-height: 62px; }
.no-art { color: var(--muted); font-size: 10px; }
.tile-foot { color: var(--muted); }
.tile.owned .tile-foot { color: var(--good); }
.badge { position: absolute; top: 4px; right: 4px; padding: 1px 5px; border-radius: 999px; background: var(--bad); color: #fff; font-size: 9px; }
.shop-grid.outfits { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
.outfit { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 10px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel-2); }
.outfit .tile-art { width: 110px; height: 90px; }
.outfit .tile-art canvas { max-width: 110px; max-height: 90px; }
.outfit button { width: 100%; }
#giftBody h2 { margin: 0 0 8px; color: var(--accent); font-size: 17px; }

@media (max-width: 760px) {
  .shop-body { grid-template-columns: 1fr; grid-template-rows: auto minmax(0, 1fr); }
  .shop-preview { min-height: 120px; }
  .panel.shop { height: 92vh; }
}

/* Friends and tribe */
.panel.wide { width: min(760px, 100%); }
.people { max-height: 46vh; }
.people.short { min-height: 0; max-height: 18vh; flex: none; }
.person { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; padding: 7px 10px; border: 1px solid var(--line); border-radius: 6px; background: var(--panel-2); }
.person.online .person-name::before { content: ""; display: inline-block; width: 8px; height: 8px; margin-right: 6px; border-radius: 50%; background: var(--good); }
.person-name { font-weight: bold; }
.person-status { color: var(--muted); flex: 1; min-width: 120px; }
.row-actions, .button-row { display: flex; flex-wrap: wrap; gap: 4px; }
.button-row { margin-top: 8px; }
.row-actions button, .row-actions select, .button-row button, .options button, .options select, .people > li > button {
  padding: 5px 9px; border: 1px solid var(--line); border-radius: 6px; background: var(--panel); color: var(--text); font: 11px Verdana, sans-serif; cursor: pointer;
}
.row-actions button:hover, .button-row button:hover, .options button:hover { border-color: var(--accent); }
.section { margin: 10px 0 4px; font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); }
.options { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line); color: var(--muted); font-size: 12px; }
.tribe-head p { margin: 0 0 4px; }
#tribeBody { display: flex; flex-direction: column; gap: 8px; min-height: 0; overflow-y: auto; }
#tribeBody .tabs { flex: none; }
.person.rank { align-items: flex-start; }
.perms { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 2px 10px; flex: 1 1 100%; color: var(--muted); font-size: 11px; }
#confirmBody h2 { margin: 0 0 8px; color: var(--accent); font-size: 17px; }
.card input[type="checkbox"] { display: inline-block; width: auto; margin: 0; padding: 0; accent-color: var(--accent); }
.perms label, .options label { display: inline-flex; align-items: center; gap: 5px; margin: 0; }
.button-row button.primary-action, .row-actions button.primary-action { background: var(--accent); color: #1b2733; border-color: var(--accent); }

/* Map editor */
#editor { grid-area: chat; display: flex; flex-direction: column; gap: 6px; min-height: 0; overflow-y: auto; padding: 8px 10px; background: var(--panel); border: 1px solid var(--line); border-radius: 8px; }
#editor[hidden], #chat[hidden] { display: none; }
html:not(.mobile) #editor .touch-only { display: none; }
.editor-row { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; }
.editor-row button, .editor-row select, .editor-xml button {
  padding: 5px 9px; border: 1px solid var(--line); border-radius: 6px; background: var(--panel-2); color: var(--text); font: 11px Verdana, sans-serif; cursor: pointer;
}
.editor-row button:hover { border-color: var(--accent); }
.editor-row button.active { border-color: var(--accent); color: var(--accent); }
.editor-row.fields { gap: 4px 10px; padding: 6px 8px; background: var(--panel-2); border-radius: 6px; font-size: 11px; color: var(--muted); }
.editor-row.fields label { display: inline-flex; align-items: center; gap: 4px; }
.editor-row.fields input[type="number"] { width: 62px; padding: 3px 5px; border: 1px solid var(--line); border-radius: 4px; background: var(--panel); color: var(--text); font: inherit; }
.editor-row.fields input[type="color"] { width: 30px; height: 22px; padding: 0; border: 1px solid var(--line); background: none; }
.editor-row.fields select { padding: 3px 5px; }
.editor-row.fields strong { color: var(--accent); }
.editor-row.fields strong.good { color: var(--good); }
.editor-row.fields strong.bad { color: var(--bad); }
.editor-row.fields input.wide { flex: 1 1 180px; min-width: 140px; padding: 4px 6px; border: 1px solid var(--line); border-radius: 4px; background: var(--panel); color: var(--text); font: inherit; }
.editor-row.fields input:disabled { opacity: 0.4; }
.editor-row.fields button:disabled { opacity: 0.45; cursor: default; }
#editorTabs button[aria-selected="true"] { border-color: var(--accent); color: var(--accent); background: var(--panel); }
#editorScroll { flex: 1; min-width: 120px; }
.editor-xml summary { cursor: pointer; color: var(--muted); font-size: 11px; }
.editor-xml textarea { display: block; width: 100%; height: 90px; margin: 6px 0; padding: 6px; border: 1px solid var(--line); border-radius: 6px; background: var(--bg); color: var(--text); font: 11px ui-monospace, Menlo, monospace; }
#menuBar button.primary-action { background: var(--accent); color: #1b2733; border-color: var(--accent); font-weight: bold; }

/* Friends: the latest client's "Friendlist" (ComposantAmis), 400 wide inside its frame: two tabs, then a list 280
   high with a box under it. Its row's buttons are the client's own pictures (remove, whisper, join), of which only the
   round close is here; whisper and join are words. */
.panel.friends { width: min(423px, 100%); }
.friend-tabs { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.friend-tabs button { height: 20px; padding: 0; border: 1px solid var(--line); border-radius: 4px; background: var(--panel-2); color: var(--text); font: 11px Verdana, sans-serif; cursor: pointer; }
.friend-tabs button[aria-selected="true"] { background: rgba(0, 0, 0, 0.3); color: #c2c2da; cursor: default; }
.friend-pane { display: flex; flex-direction: column; gap: 4px; margin-top: 5px; }
.friend-pane[hidden] { display: none; }
.friend-scroll { height: min(280px, 50vh); overflow-y: auto; }
.friend-none { margin: 0; color: #c2c2da; font: 12px Verdana, sans-serif; }
.friend-none[hidden] { display: none; }
.friend-list { margin: 0; padding: 0; list-style: none; }
.friend { display: flex; align-items: center; gap: 2px; min-height: 20px; font: 12px Verdana, sans-serif; }
.friend-remove { flex: none; width: 15px; height: 15px; padding: 0; border: 0; border-radius: 50%; background: url('/assets/web/x_transformice/x_interface/x_fermer.svg') center / contain no-repeat #8a2d2d; cursor: pointer; }
.friend-place { flex: none; position: relative; width: 36px; height: 20px; }
.friend-place .game { position: absolute; left: 0; top: 2px; width: 16px; height: 16px; }
.friend-place .flag { position: absolute; left: 20px; top: 3px; width: 18px; height: 14px; }
.friend-text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #c2c2da; }
.friend-text .female { color: #feb1fc; }
.friend-text .male { color: #98e2eb; }
.friend-name { text-decoration: none; }
.friend-name.on { color: #babd2f; }
.friend-name.one-way { color: #6c77c1; }
.friend-text .off, .friend-name.off { color: #60608f; }
.friend-text .when { font-size: 10px; }
.friend-text .friend-room { color: #009d9d; font-size: 11px; }
.friend-actions { flex: none; display: flex; gap: 2px; }
.friend-actions button, .friend-add button { padding: 1px 6px; border: 1px solid var(--line); border-radius: 4px; background: var(--panel-2); color: var(--text); font: 10px Verdana, sans-serif; cursor: pointer; }
.friend-add { display: flex; gap: 4px; }
.friend-add input { flex: 0 1 145px; width: auto; min-width: 0; height: 20px; margin: 0; padding: 0 4px; font: 12px Verdana, sans-serif; }
#ignoreForm input { flex-basis: 265px; }
.friend-add button { flex: 0 1 120px; height: 20px; font-size: 11px; }
.friend-options { display: flex; flex-wrap: wrap; gap: 4px 12px; color: #c2c2da; font: 11px Verdana, sans-serif; }
.friend-options label { display: inline-flex; align-items: center; gap: 3px; margin: 0; color: #c2c2da; font-size: 11px; }

/* Café: the latest client's window (n2046), 760 by 320 inside its frame: the topics in a column on the left (40%,
   a list 290 high and "Create a new topic" under it) and, 10 px over, what is opened from them. Avatars are fetched
   from the official avatar server, which this game has no copy of, so they are one flat colour. In the touch view,
   and in a window too narrow for both, the columns take turns (.reading: what was opened, with the arrow back). */
.panel.cafe { width: min(783px, 100%); } /* (760 inside: the frame is 71 across, its contents reach 24 out over it each side) */
.cafe .panel-head { gap: 6px; }
.cafe .panel-head h2 { flex: 1; }
#cafeBack:not([hidden]) { width: 26px; height: 22px; margin-left: 18px; padding: 0; border: 0; background: none; color: #f4e3b5; font-size: 18px; line-height: 1; cursor: pointer; }
#cafeBack:not([hidden]) + h2 { padding-left: 4px; }
.cafe-refresh { width: 20px; height: 20px; padding: 0; border: 0; background: none; color: #f4e3b5; font-size: 17px; line-height: 1; cursor: pointer; }
.cafe-refresh[hidden] { display: none; }
.cafe-columns { display: grid; grid-template-columns: 40% minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); gap: 10px; height: min(320px, 70vh); min-height: 0; }
.cafe-topics { display: flex; flex-direction: column; gap: 6px; min-height: 0; }
.cafe-list { flex: 1; min-height: 0; margin: 0; padding: 0; list-style: none; overflow-y: auto; background: rgba(0, 0, 0, 0.18); }
.cafe-topic { display: grid; grid-template-columns: 50px minmax(0, 1fr); grid-template-rows: auto auto; align-content: start; column-gap: 5px; width: 100%; min-height: 50px; padding: 0; border: 0; background: none; color: var(--text); font: 12px Verdana, sans-serif; text-align: left; cursor: pointer; }
.cafe-topic:hover { background: rgba(255, 255, 255, 0.05); }
.cafe-topic.on { background: rgba(0, 0, 0, 0.2); opacity: 0.8; }
.cafe-topic.red .cafe-topic-title { color: #cb546b; }
.cafe-topic .cafe-avatar { grid-row: 1 / 3; border-right: 3px solid #122529; }
.cafe-topic-title { align-self: end; padding-top: 3px; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; line-height: 14px; word-break: break-word; }
.cafe-topic-line { color: #6c77c1; font-size: 11px; }
.cafe-topic-line .count { color: #ffd991; }
.cafe-topic-line .mine { color: #60608f; }
.cafe-list li + li { border-top: 1px solid rgba(0, 0, 0, 0.25); }
.cafe-avatar { display: block; width: 50px; height: 50px; padding: 0; border: 0; background: #122529; }
.cafe-new { flex: none; align-self: center; padding: 5px 12px; border: 1px solid var(--line); border-radius: 6px; background: var(--panel-2); color: var(--text); font: 11px Verdana, sans-serif; cursor: pointer; }
.cafe-new[hidden] { display: none; }
.cafe-new:hover { border-color: var(--accent); }
.cafe-posts { position: relative; min-height: 0; overflow-y: auto; }
.cafe-mark { margin: 0; height: 100%; display: grid; place-items: center; color: #22464d; font: 100px Verdana, sans-serif; line-height: 1; overflow: hidden; user-select: none; }
.cafe-post { display: grid; grid-template-columns: 50px minmax(0, 1fr) auto; column-gap: 2px; min-height: 50px; padding-bottom: 2px; font: 12px Verdana, sans-serif; }
.cafe-post + .cafe-post { margin-top: 4px; }
.cafe-post .cafe-avatar { border-radius: 10px; cursor: pointer; }
.cafe-post.marked { outline: 2px solid #cb546b; outline-offset: -2px; }
.cafe-post.gone { opacity: 0.5; }
.cafe-post.red .cafe-words { color: #cb546b; }
.cafe-body { padding-left: 2px; min-width: 0; }
.cafe-author .name { font-weight: bold; }
.cafe-author .up { color: #2ecf73; }
.cafe-author .down, .cafe-words .down { color: #cb546b; }
.cafe-words { display: block; color: #c2c2da; white-space: normal; overflow-wrap: anywhere; }
.cafe-quote { display: block; margin: 0 20px; color: #6c77c0; font-size: 10px; }
.cafe-item { display: list-item; margin-left: 16px; list-style: disc; }
.cafe-when { color: #60608f; font-size: 11px; white-space: nowrap; }
.cafe-when .tag { color: #9fb4c0; }
.cafe-form { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.cafe-form[hidden] { display: none; }
.cafe-form .cafe-title, .cafe-form .cafe-message { display: block; width: 100%; margin: 0; padding: 6px 8px; font: 12px Verdana, sans-serif; }
.cafe-form .cafe-title::placeholder { color: #babd2f; }
.cafe-form .cafe-message::placeholder { color: #6c77c0; }
.cafe-form .cafe-title.refused { outline: 2px solid #cb546b; }
.cafe-form .cafe-title.refused::placeholder { color: #cb546b; }
.cafe-form .cafe-message { min-height: 60px; resize: none; overflow: hidden; }
.cafe-submit { align-self: center; padding: 5px 16px; border: 1px solid var(--line); border-radius: 6px; background: var(--panel-2); color: var(--text); font: 11px Verdana, sans-serif; cursor: pointer; }
.cafe-submit:hover { border-color: var(--accent); }
.cafe-menu { position: absolute; z-index: 2; display: flex; flex-direction: column; min-width: 90px; padding: 3px; background: var(--panel); border: 1px solid var(--line); box-shadow: 0 8px 20px rgba(0, 0, 0, 0.45); }
.cafe-menu button { padding: 5px 10px; border: 0; background: none; color: var(--text); font: 12px Verdana, sans-serif; text-align: left; cursor: pointer; }
.cafe-menu button:hover:not(:disabled) { background: var(--panel-2); }
.cafe-menu button:disabled { color: #60608f; cursor: default; }
.panel.cafe { position: relative; }
html.mobile .cafe-columns, html.mobile .cafe.reading .cafe-columns { grid-template-columns: minmax(0, 1fr); height: min(520px, calc(100dvh - 140px)); }
html.mobile #cafe.reading .cafe-topics, html.mobile #cafe:not(.reading) .cafe-posts { display: none; }
/* (The arrow back is only for the columns taking turns.) */
@media (min-width: 621px) { html:not(.mobile) #cafeBack { display: none; } }
@media (max-width: 620px) {
  .cafe-columns { grid-template-columns: minmax(0, 1fr); height: min(520px, calc(100dvh - 140px)); }
  #cafe.reading .cafe-topics, #cafe:not(.reading) .cafe-posts { display: none; }
}
#nailState { align-self: center; margin-left: 6px; color: var(--muted); font-size: 11px; white-space: nowrap; }
#vote {
  position: absolute; left: 50%; bottom: 14px; transform: translateX(-50%); z-index: 4;
  display: flex; align-items: center; gap: 8px; padding: 8px 12px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 8px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.35);
  color: var(--text); font: 12px Verdana, sans-serif;
}
#vote[hidden] { display: none; }
/* The tutorial's box (the latest's clip cI on map 900: its text typed in, its "Quit the tutorial" button under it).
   Where the clip stands on the map is still to be read from it; until then the box is at the top, in the middle, in
   one flat colour. */
#tutorial {
  position: absolute; z-index: 4; left: 50%; top: calc(36 * var(--u, 1px)); transform: translateX(-50%); width: min(470px, calc(100% - 24px));
  display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 10px 14px; box-sizing: border-box;
  background: rgba(38, 54, 63, 0.9); border-radius: 8px; color: #c2c2da; font: 13px/1.4 Verdana, sans-serif; text-align: center;
}
#tutorial[hidden] { display: none; }
#tutorial p { margin: 0; min-height: 2.8em; }
#tutorial button { padding: 4px 12px; border: 1px solid var(--line); border-radius: 6px; background: var(--panel-2); color: var(--text); font: 12px Verdana, sans-serif; cursor: pointer; }
html.desk #tutorial { width: calc(470 * var(--u)); padding: calc(8 * var(--u)) calc(12 * var(--u)); gap: calc(6 * var(--u)); font-size: calc(12 * var(--u)); border-radius: calc(6 * var(--u)); }
html.desk #tutorial button { font-size: calc(11 * var(--u)); padding: calc(3 * var(--u)) calc(10 * var(--u)); }
html.mobile #tutorial { top: calc(env(safe-area-inset-top, 0px) + 46px); }
html.backdrop #tutorial, html.watching #tutorial { display: none !important; }
/* The latest client's help bubbles over the page (its class n1556): a 2 px white line with a yellow glow around what
   they point at, its help arrow ($FlecheAide, placed by its point: main.js) 2 px under that and pointing up, and the
   words 25 px under the arrow, Verdana 13 in cream with a black glow, on a dark plate reaching 2 px over them, 4 to
   their left and 2 to their right. --k is one of the original's pixels. The late-join notice frames the left 500 px of
   the top bar (its 'fin_partie', 500 by 23 at 2, 2); the touch view's bar is measured (--hud-bottom). */
.help-note { position: absolute; z-index: 7; pointer-events: none; --k: 1px; }
.help-note[hidden] { display: none; }
.help-ring {
  position: absolute; inset: calc(-1 * var(--k)); border: calc(2 * var(--k)) solid #fff;
  box-shadow: 0 0 calc(3 * var(--k)) #ffd859, 0 0 calc(3 * var(--k)) #ffd859, inset 0 0 calc(3 * var(--k)) #ffd859;
}
.help-arrow { position: absolute; left: calc(50% + var(--ax, 0) * var(--k)); top: calc(100% + (2 + var(--ay, 0)) * var(--k)); width: calc(var(--aw, 0) * var(--k)); }
.help-arrow[hidden] { display: none; }
.help-words {
  position: absolute; left: calc(50% - var(--k)); top: calc(100% + 27 * var(--k)); transform: translateX(-50%);
  width: max-content; max-width: calc(196 * var(--k)); padding: calc(2 * var(--k)) calc(2 * var(--k)) 0 calc(4 * var(--k));
  border-radius: calc(5 * var(--k)); background: rgba(0, 0, 0, 0.5); color: #ffddc2; text-align: center;
  font: calc(13 * var(--k)) / 1.25 Verdana, sans-serif; text-shadow: 0 0 calc(2 * var(--k)) #000, 0 0 calc(2 * var(--k)) #000, 0 0 var(--k) #000;
}
html.desk #waitNotice { --k: var(--u); left: calc(2 * var(--u)); top: calc(2 * var(--u)); width: calc(500 * var(--u)); height: calc(23 * var(--u)); }
html.mobile #waitNotice {
  position: fixed; left: calc(2px + env(safe-area-inset-left, 0px)); top: calc(2px + env(safe-area-inset-top, 0px));
  width: min(500px, calc(100% - 4px - env(safe-area-inset-left, 0px) - env(safe-area-inset-right, 0px)));
  height: calc(var(--hud-bottom, 40px) - env(safe-area-inset-top, 0px) - 4px);
}
html.backdrop .help-note, html.watching .help-note { display: none !important; }
#vote button { padding: 4px 12px; border: 1px solid var(--line); border-radius: 6px; background: var(--panel-2); color: var(--text); font: inherit; cursor: pointer; }
#vote button:hover { border-color: var(--accent); }
.shaman-own { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 6px; }
.shaman-own progress { flex: 1 1 160px; height: 10px; accent-color: var(--accent); }
.shaman-own select { padding: 4px 8px; border: 1px solid var(--line); border-radius: 6px; background: var(--panel-2); color: var(--text); font: 12px Verdana, sans-serif; }
#transformBar button span { position: static; font: 11px Verdana, sans-serif; color: var(--text); padding: 0 6px; }

/* ------------------------------------------------------------------ touch screens
   The game fills the whole screen as a crop that follows the mouse, with the menus folded away. */
.mobile-only { display: none; }
html.mobile, html.mobile body { height: 100dvh; overflow: hidden; overscroll-behavior: none; }
html.mobile body { position: fixed; inset: 0; -webkit-text-size-adjust: 100%; }
html.mobile #app { display: block; height: 100dvh; max-width: none; padding: 0; }
html.mobile #stage {
  position: fixed; inset: 0; width: auto; aspect-ratio: auto; border: 0; border-radius: 0;
  touch-action: none; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none;
}
html.mobile #game canvas { touch-action: none; }
html.mobile .help { display: none; }

html.mobile #hud {
  position: fixed; top: 0; left: 0; right: 0; z-index: 6;
  flex-wrap: nowrap; gap: 14px;
  padding: calc(5px + env(safe-area-inset-top)) calc(8px + env(safe-area-inset-right)) 5px calc(8px + env(safe-area-inset-left));
  background: rgba(27, 39, 51, 0.6); border: 0; border-radius: 0;
}
html.mobile .brand, html.mobile #hud > .stat.wide, html.mobile #hud > .stat.me, html.mobile #hud > .stat:nth-of-type(1) { display: none; }
/* A narrow screen (a small phone, a frame beside something else): the bar keeps what there is room for. A text that
   does not fit is cut short, not laid over its neighbour; under 340 px the shaman's name goes (it is marked in the game). */
html.mobile #hud > .stat { min-width: 0; }
html.mobile #hud > .stat > span { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 340px) {
  html.mobile #hud { gap: 8px; }
  html.mobile #hud > .stat:nth-of-type(4) { display: none; }
}
html.mobile #mobileButtons { display: flex; gap: 6px; margin-left: auto; flex: none; }
html.mobile #mobileButtons button, html.mobile #buildBar button {
  min-height: 34px; padding: 6px 12px; border: 1px solid var(--line); border-radius: 8px;
  background: rgba(44, 66, 82, 0.9); color: var(--text); font: 12px Verdana, sans-serif;
}
html.mobile #mobileButtons button[aria-expanded="true"] { border-color: var(--accent); color: var(--accent); }

/* Menu drawer: the panels, then the player list. */
html.mobile #menuBar, html.mobile #sidebar { display: none; }
html.mobile.menu-open #menuBar {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; margin: 0;
  position: fixed; z-index: 7; top: calc(52px + env(safe-area-inset-top)); left: 8px; right: 8px;
  padding: 8px; background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
}
html.mobile.menu-open #menuBar button { min-height: 40px; }
html.mobile.menu-open #sidebar {
  display: flex; position: fixed; z-index: 7; left: 8px; right: 8px;
  top: calc(160px + env(safe-area-inset-top)); max-height: calc(100dvh - 180px - env(safe-area-inset-top));
}
html.mobile .touch-help { display: block; margin: 8px 0 0; padding-top: 8px; border-top: 1px solid var(--line); color: var(--muted); font-size: 12px; }

/* Chat sheet, and the newest lines shown over the game while it is closed. */
html.mobile #chat { display: none; }
html.mobile.chat-open #chat {
  display: flex; position: fixed; z-index: 7; left: 0; right: 0; bottom: 0; height: 46dvh;
  border-radius: 12px 12px 0 0; padding-bottom: env(safe-area-inset-bottom);
}
html.mobile #chatInput, html.mobile #chatPrefix { font-size: 16px; } /* smaller text makes iOS zoom the page on focus */
/* The touch view's bar: the same pictures, a finger's size apart; its lines are scrolled by the finger, so the two
   arrows that scroll them are not there. The grown chat takes the screen under the top bar. */
html.mobile #chatLog { font-size: calc(var(--chat-size, 13) * 1px); }
html.mobile #chatBar { gap: 4px; padding: 6px 8px; }
html.mobile .chat-icon { width: 36px; height: 36px; }
html.mobile .chat-icon img { width: 24px; height: 24px; object-fit: contain; }
html.mobile #chatUp, html.mobile #chatDown { display: none; }
html.mobile #chatField { min-height: 36px; border-radius: 6px; }
html.mobile #chatInput { padding: 6px 6px; }
html.mobile #chatPrefix { padding-left: 8px; }
html.mobile.chat-open #chat.big { height: calc(100dvh - 52px - env(safe-area-inset-top)); }
/* The tabs' column: the same names and colours, in rows a finger can pick. */
html.mobile #chat.tabbed #chatTabs { padding: 4px 0 0 6px; }
html.mobile .chat-tab { height: 32px; max-width: 110px; font-size: 13px; line-height: 32px; }
html.mobile #chatToast {
  display: block; position: absolute; z-index: 4; pointer-events: none;
  left: calc(8px + env(safe-area-inset-left)); top: calc(50px + env(safe-area-inset-top)); max-width: min(76%, 420px);
}
html.mobile.chat-open #chatToast { display: none; }
#chatToast .line { display: table; margin-bottom: 2px; padding: 2px 8px; border-radius: 8px; background: rgba(27, 39, 51, 0.7); font-size: 12px; animation: toast 5s forwards; }
@keyframes toast { 0%, 80% { opacity: 1; } 100% { opacity: 0; } }

/* Shaman objects and transformations sit under the top bar. */
html.mobile #shamanBar, html.mobile #transformBar {
  position: absolute; z-index: 5; left: 0; right: 0; top: calc(46px + env(safe-area-inset-top));
  border: 0; background: rgba(27, 39, 51, 0.6); touch-action: pan-x;
}
html.mobile #nailState { display: none; }
html.mobile #buildBar { display: flex; gap: 6px; position: absolute; z-index: 5; left: 50%; transform: translateX(-50%); top: calc(104px + env(safe-area-inset-top)); }
html.mobile #buildBar[hidden] { display: none; }

/* Run by holding a side; swipe up or use a jump button with either thumb. */
html.mobile #touchControls { display: block; }
/* The ring under a steering finger: where it rested, and the knob for how far it has slid. On a wall it turns. */
#pad { position: absolute; left: 0; top: 0; box-sizing: border-box; border-radius: 50%; pointer-events: none;
  border: 2px solid rgba(255, 226, 163, 0.5); background: rgba(50, 70, 80, 0.22); }
#pad[hidden] { display: none; }
#pad i { position: absolute; left: 30%; top: 30%; width: 40%; height: 40%; border-radius: 50%; background: rgba(255, 226, 163, 0.7); }
#pad.wall { border-style: dashed; animation: pad-turn 1.6s linear infinite; }
#pad.wall i { left: 38%; top: -8%; width: 24%; height: 24%; }
@keyframes pad-turn { to { rotate: -360deg; } }
.pad { position: absolute; z-index: 5; bottom: calc(16px + env(safe-area-inset-bottom)); display: flex; flex-direction: column; gap: 12px; }
.pad.left { left: calc(14px + env(safe-area-inset-left)); }
.pad.right { right: calc(14px + env(safe-area-inset-right)); }
.pad button {
  width: 68px; height: 68px; border-radius: 50%; border: 2px solid rgba(255, 255, 255, 0.6);
  background: rgba(27, 39, 51, 0.5); color: #fff; font: bold 12px Verdana, sans-serif; letter-spacing: 0.03em;
  touch-action: none; user-select: none; -webkit-user-select: none; -webkit-tap-highlight-color: transparent;
}
.pad button.on { background: rgba(255, 214, 90, 0.75); border-color: #fff; color: #1b2733; }
html.mobile #buildBar #bRotateLeft, html.mobile #buildBar #bRotateRight { font-size: 20px; line-height: 1; padding: 4px 12px; }
html.mobile #buildBar button { white-space: nowrap; }
html.mobile #vote { bottom: calc(100px + env(safe-area-inset-bottom)); }

/* ------------------------------------------------------------------ the Flash client's look
   Everything from here down dresses the page like the original client. Colours and frames come from its own
   interface art (assets/client158/x_TransformiceFLA/sprites): slate panels (#324650), buttons and fields (#3c5064),
   wooden window frames with brass corners ($FenetreBase), square icon buttons ($Menu_*), the login scene. */
:root {
  --bg: #6a7495;
  --panel: #324650;
  --panel-2: #3c5064;
  --well: #26363f;
  --line: #212f36;
  --text: #c2c2da;
  --muted: #8d9ab6;
  --accent: #efce8f;
  --game: #6a7495;
  --wood: linear-gradient(#b98a55, #94693f 48%, #794436);
  --title: "Soopafresh", "Arial Rounded MT Bold", "Trebuchet MS", Verdana, sans-serif;
}
body { background: linear-gradient(#6a7495, #59627f); background-attachment: fixed; }

/* Panels: the slate boxes of the chat and the lists. */
#hud, #sidebar, #chat, #editor {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.09), 0 3px 0 rgba(0, 0, 0, 0.22);
}
.brand { font: 20px/1 var(--title); color: var(--accent); text-shadow: 0 2px 0 rgba(0, 0, 0, 0.35); letter-spacing: 0.02em; }
.stat .label { color: #7f8fb0; }
.stat span:last-child { color: var(--text); }
.stat.me span:last-child { color: var(--accent); }

/* Buttons: slate with a lit top edge; the main action of a form is a wooden plank. (Not ".room": the room list's rows
   have their own look, and a room's chat line has that class too, which drew every line as a slate button.) */
#menuBar button, .room-join button, .captcha button, #vote button, #emoteMenu button, .row-actions button,
.button-row button, .editor-row button, #editorXmlApply, .shop-side button, .tool, .outfit button {
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 7px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14), 0 1px 0 rgba(0, 0, 0, 0.25);
  color: var(--text);
}
#menuBar button:hover, .room-join button:hover, #emoteMenu button:hover, .row-actions button:hover,
.button-row button:hover, .editor-row button:hover { background: #4a6079; border-color: var(--line); color: #fff; }
/* A button the player's rank has no right to (the tribe window) is there but off, and looks it. */
.button-row button:disabled, .row-actions button:disabled { opacity: 0.45; cursor: default; background: var(--panel-2); border-color: var(--line); color: var(--text); }
button.primary, .primary-action, .room-join button[type="submit"], #menuBar button.primary-action {
  background: var(--wood);
  border: 1px solid #4b2a1b;
  border-radius: 8px;
  box-shadow: inset 0 1px 0 rgba(255, 236, 190, 0.45), 0 2px 0 rgba(0, 0, 0, 0.3);
  color: #fff4d8;
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.45);
  font-weight: bold;
}
button.primary:hover, .primary-action:hover, .room-join button[type="submit"]:hover { filter: brightness(1.1); }

/* The menus are the client's own square icon buttons, with a caption under each. */
#menuBar { gap: 4px; align-items: stretch; }
#menuBar button { display: flex; flex-direction: column; align-items: center; gap: 2px; min-width: 54px; padding: 4px 6px 3px; font-size: 10px; background: transparent; border-color: transparent; box-shadow: none; }
#menuBar button img { width: 30px; height: 30px; filter: drop-shadow(0 2px 0 rgba(0, 0, 0, 0.3)); transition: transform 0.08s; }
#menuBar button:hover { background: rgba(255, 255, 255, 0.07); border-color: transparent; }
#menuBar button:hover img { transform: translateY(-2px) scale(1.06); }
#menuBar button.primary-action { flex-direction: row; padding: 6px 12px; font-size: 12px; }

/* The game sits in the wooden frame the client draws around its stage. */
html:not(.mobile) #stage {
  box-sizing: content-box;
  width: calc(100% - 18px);
  border: 9px solid #794436;
  border-image: url('/assets/client158/x_TransformiceFLA/sprites/%24CadreLogin_1027.svg') 12 / 9px stretch;
  border-radius: 0;
  box-shadow: 0 4px 0 rgba(0, 0, 0, 0.25);
}

/* Lists and chat. */
#sidebar h2 { font: 15px/1.2 var(--title); letter-spacing: 0.03em; color: var(--accent); text-transform: none; }
#playerList li:nth-child(odd) { background: rgba(0, 0, 0, 0.14); }
#shamanBar, #transformBar { background: var(--well); }
#shamanBar button, #transformBar button { background: var(--panel-2); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12); }
#emoteMenu, #vote { background: var(--panel); border: 1px solid var(--line); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.09), 0 10px 30px rgba(0, 0, 0, 0.4); }

/* Windows: the wooden frame with brass corners, over its dark teal board. The frame art is 174x131 with 27 px
   corners, so it is cut into nine pieces there. */
.modal { background: rgba(28, 34, 52, 0.62); }
.card {
  padding: 2px 4px;
  background: none;
  border: 27px solid transparent;
  border-image: url('/assets/client158/x_TransformiceFLA/sprites/%24FenetreBase_1128.svg') 27 fill / 27px stretch;
  border-radius: 0;
  box-shadow: none;
  filter: drop-shadow(0 14px 22px rgba(0, 0, 0, 0.5));
  color: var(--text);
}
.panel { padding: 0 2px; }
.card h1, .panel-head h2, .profile-head h2, #giftBody h2, #confirmBody h2, #askBody h2 {
  font-family: var(--title); font-weight: normal; letter-spacing: 0.03em; color: var(--accent); text-shadow: 0 2px 0 rgba(0, 0, 0, 0.4);
}
.card h1 { font-size: 30px; }
.panel-head h2 { font-size: 22px; }
.card .sub, .muted { color: #9fb4c0; }
.card label, .card .label { color: #a9c0c8; }
.card input, .card textarea, .card select, .room-join input, #editor input, #editor select, #editor textarea {
  background: #14282c; border: 1px solid #0b181b; border-radius: 6px; color: var(--text);
  box-shadow: inset 0 2px 3px rgba(0, 0, 0, 0.35);
}
.card input:focus, .card textarea:focus, .room-join input:focus { outline: 2px solid var(--accent); }
.tabs, #loginTabs { background: rgba(0, 0, 0, 0.3); border: 1px solid rgba(0, 0, 0, 0.35); }
.tabs button, #loginTabs button { color: #9fb4c0; }
.tabs button[aria-selected="true"], #loginTabs button[aria-selected="true"] { background: var(--panel-2); color: var(--accent); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14); }
.stat-row, .portrait { background: rgba(0, 0, 0, 0.25); border: 1px solid rgba(0, 0, 0, 0.3); }
.portrait { background: var(--game); }
#profileBody h3, .section { color: #9fb4c0; }
/* The close button is the client's red cross. */
.close:not(#cafeBack) {
  width: 30px; height: 30px; border: 0; padding: 0; color: transparent; font-size: 0; cursor: pointer;
  background: url('/assets/client158/x_Ressources_Class/sprites/%24Fermer_1075.svg') center / contain no-repeat;
}
.close:not(#cafeBack):hover { filter: brightness(1.15); transform: scale(1.06); }

/* Logging in happens under the sky of the tutorial map, the first one a new player sees. */
#login.modal {
  background: #6a7495 url('/assets/client158/x_Ressources_Class/sprites/%24F_0_276.svg') center / cover no-repeat; /* the sky of the tutorial map */
}
#login .card { width: min(380px, 100%); }

/* Touch screens: the same dress, fitted to the phone. */
html.mobile #hud { background: rgba(50, 70, 80, 0.86); border: 0; border-bottom: 1px solid var(--line); border-radius: 0; box-shadow: 0 2px 0 rgba(0, 0, 0, 0.2); }
html.mobile #mobileButtons button { min-height: 0; width: 40px; height: 40px; padding: 0; border: 0; background: none; }
html.mobile #mobileButtons button img { width: 36px; height: 36px; filter: drop-shadow(0 2px 0 rgba(0, 0, 0, 0.3)); }
html.mobile #mobileButtons button[aria-expanded="true"] img { filter: drop-shadow(0 0 5px var(--accent)); }
html.mobile.menu-open #menuBar { background: var(--panel); border: 1px solid var(--line); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.09), 0 8px 20px rgba(0, 0, 0, 0.4); grid-template-columns: repeat(4, 1fr); gap: 2px; padding: 6px 4px; }
html.mobile.menu-open #menuBar button { min-width: 0; padding: 4px 0 3px; }
/* The list of players opens under the menu, however many rows the menu's buttons take on this screen: `--menu-bottom`
   is where the menu ends, measured when it opens (main.js). The numbers after it are for before that is known. */
html.mobile.menu-open #sidebar { top: calc(var(--menu-bottom, calc(238px + env(safe-area-inset-top))) + 8px); max-height: calc(100dvh - var(--menu-bottom, calc(238px + env(safe-area-inset-top))) - 24px); }
@media (orientation: landscape) {
  html.mobile.menu-open #menuBar { grid-template-columns: repeat(8, 1fr); }
  html.mobile.menu-open #sidebar { top: calc(var(--menu-bottom, calc(178px + env(safe-area-inset-top))) + 8px); max-height: calc(100dvh - var(--menu-bottom, calc(178px + env(safe-area-inset-top))) - 16px); }
}
html.mobile.menu-open #menuBar button { min-height: 58px; font-size: 11px; }
html.mobile.menu-open #menuBar button img { width: 34px; height: 34px; }
html.mobile #buildBar button { background: var(--panel-2); border: 1px solid var(--line); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14); color: var(--text); }
html.mobile #shamanBar, html.mobile #transformBar { background: rgba(38, 54, 63, 0.86); }
html.mobile .card { border-width: 20px; border-image-width: 20px; }
html.mobile.chat-open #chat { border-radius: 12px 12px 0 0; }
#chatToast .line { background: rgba(38, 54, 63, 0.82); border: 1px solid rgba(0, 0, 0, 0.3); }
#menuBar button[hidden] { display: none; }
/* Headings drawn from the client's display face (see titlefont.js). */
.title-font { height: 1.2em; width: auto; max-width: 100%; vertical-align: -0.28em; fill: currentColor; filter: drop-shadow(0 2px 0 rgba(0, 0, 0, 0.4)); overflow: visible; }
.brand img { height: 26px; display: block; filter: drop-shadow(0 2px 0 rgba(0, 0, 0, 0.3)); }
.brand { display: flex; align-items: center; gap: 6px; }
#login .card .emblem { width: 92px; display: block; margin: -6px auto 0; filter: drop-shadow(0 3px 0 rgba(0, 0, 0, 0.35)); }
#login .card h1, #login .card .sub { text-align: center; }
.brand .brand-name { color: var(--accent); font-size: 21px; }
.brand span#localTag { font: 11px Verdana, sans-serif; color: var(--muted); align-self: flex-end; }

/* The map editor on a touch screen: its tools are a panel over the bottom of the map; drag the map to slide it. */
html.mobile #editor {
  position: fixed; z-index: 7; left: 0; right: 0; bottom: 0; max-height: 46dvh; overflow-y: auto;
  border-radius: 12px 12px 0 0; padding: 8px 8px calc(8px + env(safe-area-inset-bottom));
}
html.mobile #editor[hidden] { display: none; }
html.mobile #editorTabs, html.mobile #editorActions { flex-wrap: nowrap; overflow-x: auto; padding-bottom: 2px; }
html.mobile #editor .editor-row button, html.mobile #editor .editor-row select { flex: none; min-height: 36px; padding: 6px 10px; }
html.mobile #editor .editor-row.fields input[type="number"] { width: 70px; min-height: 32px; font-size: 16px; }
html.mobile.editor-folded #editor > :not(#editorActions) { display: none; }
html.mobile #editorScroll { display: none; }
html.mobile.editing #pad, html.mobile.editing #chatToast { display: none; }
html.mobile #editorBack:not([hidden]) {
  display: block; position: absolute; z-index: 5; left: 50%; transform: translateX(-50%);
  top: calc(54px + env(safe-area-inset-top)); padding: 8px 14px; font: bold 12px Verdana, sans-serif;
}
#drawToggle { display: none; }
html.mobile #drawToggle:not([hidden]) {
  display: block; position: absolute; z-index: 5; left: calc(8px + env(safe-area-inset-left)); top: calc(108px + env(safe-area-inset-top));
  min-height: 36px; padding: 6px 14px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel-2); color: var(--text);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14); font: 12px Verdana, sans-serif;
}
html.mobile #drawToggle.on { background: var(--wood); color: #fff4d8; border-color: #4b2a1b; }
/* The room where a totem is made: the original's three buttons along the bottom left (Reset, Save, Cancel). */
#totemBar:not([hidden]) { display: flex; gap: 8px; position: absolute; z-index: 5; left: calc(8px + env(safe-area-inset-left)); bottom: calc(10px + env(safe-area-inset-bottom)); }
/* (The count also stands on the map itself, where the original has it; on a phone that corner is often out of view.) */
#totemCount { align-self: center; padding: 0 6px; color: var(--text); font: 12px Verdana, sans-serif; text-shadow: 0 1px 2px #000; }
#totemBar button {
  min-width: 100px; min-height: 36px; padding: 6px 14px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel-2); color: var(--text);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14); font: 12px Verdana, sans-serif;
}
/* The Meep! button, opposite it: live once the bar over the mouse has filled. */
#meepButton { display: none; }
html.mobile #meepButton:not([hidden]) {
  display: block; position: absolute; z-index: 5; right: calc(8px + env(safe-area-inset-right)); top: calc(108px + env(safe-area-inset-top));
  min-height: 36px; padding: 6px 14px; border: 1px solid #4b2a1b; border-radius: 8px; background: var(--wood); color: #fff4d8;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14); font: bold 12px Verdana, sans-serif;
}
html.mobile #meepButton:disabled { opacity: 0.45; }
html.mobile.editing #shamanBar, html.mobile.editing #transformBar, html.mobile.editing #buildBar, html.mobile.editing #drawToggle, html.mobile.editing #meepButton { display: none; }

/* A phone held sideways has little height: the shaman's objects take a slimmer strip. */
@media (orientation: landscape) and (max-height: 520px) {
  html.mobile #shamanBar, html.mobile #transformBar { padding: 3px 8px; gap: 4px; }
  html.mobile #shamanBar button, html.mobile #transformBar button { width: 46px; height: 34px; }
  html.mobile #shamanBar button img, html.mobile #transformBar button img { max-width: 36px; max-height: 26px; }
  html.mobile #buildBar { top: calc(88px + env(safe-area-inset-top)); }
  html.mobile #drawToggle:not([hidden]), html.mobile #meepButton:not([hidden]) { top: calc(88px + env(safe-area-inset-top)); }
}
#loginTabs[hidden], .card label[hidden], #passwordRow[hidden], #captchaRow[hidden] { display: none; }

/* ------------------------------------------------------------------ options
   The options window as the latest client has it (its n5663, 580 by 310): one of the framed windows, titled "Options"
   with a close cross, its two volume rows (a switch, −, the number, +) and then the switches one under the other. The
   shaman window beside it is framed too. */
#options .card { width: min(580px, 100%); }
#optionsBody .option.volume { align-items: center; cursor: default; }
#optionsBody .volume label { display: flex; flex: 1; align-items: center; gap: 10px; margin: 0; color: var(--text); font-size: 13px; cursor: pointer; }
#optionsBody .volume input[type="text"] { flex: none; width: 44px; height: 26px; padding: 0 4px; text-align: center; }
#optionsBody .volume button { flex: none; width: 28px; height: 26px; padding: 0; }
#optionsBody, #shamanBody { display: flex; flex-direction: column; gap: 10px; overflow-y: auto; }
.option-list { display: grid; gap: 2px; }
#optionsBody .option, #shamanBody .option { display: flex; align-items: flex-start; gap: 10px; margin: 0; padding: 6px 2px; cursor: pointer; font-size: 13px; color: var(--text); }
#optionsBody .option > span, #shamanBody .option > span { flex: 1; }
#optionsBody .option input, #shamanBody .option input { flex: none; width: 20px; height: 20px; margin: 0; padding: 0; accent-color: var(--accent); }
#optionsBody .option small { display: block; margin-top: 2px; color: var(--muted); font-size: 11px; }
#optionsBody > button, #shamanBody > button { align-self: stretch; }
#shamanBody .shaman-top { display: flex; align-items: center; gap: 14px; }
/* The latest's mode tiles (n423.n5072): the name over a 60 px picture. */
#shamanBody .shaman-modes { display: flex; justify-content: center; gap: 10px; }
#shamanBody .shaman-mode {
  display: flex; flex-direction: column; align-items: center; gap: 4px; flex: 0 1 100px; min-width: 0; padding: 2px;
  background: none; border: 0; color: var(--text); font: 12px Verdana, sans-serif; cursor: pointer; position: relative;
}
#shamanBody .shaman-mode img { width: 60px; height: 60px; background: #000; }
/* (The latest marks the chosen one with its radio sprite, which this client lacks: here its name in yellow, and the
   others' pictures dimmed.) */
#shamanBody .shaman-mode[aria-checked="false"] img { filter: brightness(0.7); }
#shamanBody .shaman-mode[aria-checked="true"] span { color: #babd2f; }
#shamanBody .shaman-mode:disabled { opacity: 0.45; cursor: default; }
#shamanBody .shaman-top .option-colour { flex: 1; }
#shamanBody .shaman-portrait { flex: none; display: grid; place-items: center; width: 110px; min-height: 96px; }
#shamanBody .option-colour { display: flex; align-items: center; gap: 10px; margin: 0; padding: 5px 2px; font-size: 13px; color: var(--text); }
#shamanBody .option-colour span { flex: 1; }
#shamanBody .option-colour input.hex { flex: none; width: 84px; text-transform: uppercase; font-family: ui-monospace, Menlo, monospace; }
#shamanBody > button:disabled { opacity: 0.45; cursor: default; }
#shamanBody .option-colour input[type="color"] { flex: none; width: 44px; height: 26px; padding: 0; border: 1px solid var(--line); border-radius: 6px; background: none; }

/* ------------------------------------------------------------------ the note in the bottom right corner
   What a bot is testing on this page, or else what is being worked on and is not on the server yet (js/note.js),
   in one of the game's own window frames. It is not there when there is nothing to say. */
#testNote {
  /* As wide as its top line, which stays one line; the text under it wraps to that width. */
  position: fixed; right: 10px; bottom: 10px; z-index: 9998; width: max-content; min-width: min(330px, 44vw); max-width: calc(100vw - 20px); pointer-events: none;
  padding: 0 4px 2px;
  border: 20px solid transparent;
  border-image: url('/assets/client158/x_TransformiceFLA/sprites/%24FenetreBase_1128.svg') 27 fill / 20px stretch;
  filter: drop-shadow(0 8px 14px rgba(0, 0, 0, 0.5));
  color: var(--text);
  animation: testNoteIn 0.35s ease-out;
}
#testNote[hidden], #testNote.shot { display: none; }
/* What is being tested, on the training's page (js/note.js): a frame in the margin to the left of the stage, in the
   same window frame as the note, with a line over it that says what it is. */
#showFrame {
  position: fixed; left: 10px; top: 112px; bottom: 64px; z-index: 9997; display: flex; flex-direction: column; gap: 4px; padding: 0 2px 2px;
  border: 16px solid transparent;
  border-image: url('/assets/client158/x_TransformiceFLA/sprites/%24FenetreBase_1128.svg') 27 fill / 16px stretch;
  filter: drop-shadow(0 8px 14px rgba(0, 0, 0, 0.5));
}
#showFrame .what { margin: 0; font-size: 11px; line-height: 1.3; color: var(--accent); text-shadow: 0 1px 0 rgba(0, 0, 0, 0.4); }
#showFrame iframe { flex: 1; width: 100%; min-height: 0; border: 0; border-radius: 6px; background: #6a7495; }
/* On a phone the screen is the game's: the note is its headline and no more, and it is gone while a panel, the menu
   or the chat is open (it lay over the room panel's buttons). The login screen keeps it. */
html.mobile #testNote { min-width: 0; max-width: min(240px, 60vw); right: 6px; bottom: 6px; border-width: 14px; border-image-width: 14px; }
html.mobile #testNote .about, html.mobile #testNote .log, html.mobile #testNote .step, html.mobile #testNote .threads, html.mobile #testNote .fresh:not(.stale) { display: none; }
html.mobile #testNote h3 { font-size: 12px; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; }
html.mobile #testNote .usage { font-size: 9px; }
html.mobile body:has(.modal:not([hidden]):not(#login)) #testNote, html.mobile.menu-open #testNote, html.mobile.chat-open #testNote { display: none; }
/* (On a desktop the note stays out of a window's way too: it lay over the corner of the Shaman window's skill trees.) */
body:has(.modal:not([hidden]):not(#login)) #testNote { display: none; }
#testNote > :not(.eyebrow) { width: 0; min-width: 100%; }
#testNote .eyebrow { white-space: nowrap; display: flex; align-items: center; gap: 6px; font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--shaman); }
#testNote .eyebrow .when { margin-left: auto; padding-left: 8px; letter-spacing: 0; text-transform: none; white-space: nowrap; color: var(--muted); }
#testNote .eyebrow::before { content: ''; flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--good); animation: testNotePulse 1.4s ease-in-out infinite; }
#testNote[data-kind="next"] .eyebrow { color: var(--muted); }
#testNote[data-kind="next"] .eyebrow::before { background: var(--accent); }
#testNote h3 { margin: 3px 0 4px; font-size: 14px; line-height: 1.25; color: var(--accent); text-shadow: 0 1px 0 rgba(0, 0, 0, 0.4); }
#testNote p { margin: 0; font-size: 11.5px; line-height: 1.4; }
#testNote .step { margin-top: 5px; padding-top: 5px; border-top: 1px solid rgba(255, 255, 255, 0.14); color: var(--muted); }
#testNote .log:empty { display: none; }
#testNote .log p { margin: 5px 0 0; padding-top: 5px; border-top: 1px solid rgba(255, 255, 255, 0.14); font-size: 11px; line-height: 1.35; color: var(--text); }
#testNote .log time { color: var(--shaman); font-size: 10px; white-space: nowrap; }
#testNote .usage { margin-top: 6px; padding-top: 5px; border-top: 1px solid rgba(255, 255, 255, 0.14); font-size: 10px; letter-spacing: 0.03em; color: var(--muted); }
#testNote[data-kind="paused"] .eyebrow { color: var(--accent); }
#testNote[data-kind="paused"] .eyebrow::before { background: var(--bad); }
#testNote[data-kind="paused"] h3 { font-size: 17px; font-variant-numeric: tabular-nums; }
#testNote p:empty { display: none; }
#testNote[data-kind="deployed"] .eyebrow, #testNote[data-kind="tested"] .eyebrow { color: var(--good); }
#testNote[data-kind="deployed"] .eyebrow::before, #testNote[data-kind="tested"] .eyebrow::before { animation: none; }
#testNote[data-kind="tested"] .eyebrow::before { content: '✓'; width: auto; height: auto; background: none; border-radius: 0; font-size: 11px; line-height: 1; }
/* The threads' rows (js/note.js): what each thread of the work is at, two lines at most each, those that wait on the
   owner first, in full and in the accent colour; the reports under them are whose they say; and the line that says
   the note is being kept, or in the colour of a warning that it is not. */
/* With rows the note has a width of its own: in Safari a note "as wide as its top line" came out as wide as its
   longest row, the whole window across (2026-10-12). And it never stands taller than the window (js/note.js, fit):
   first the rows take a line each and the headline loses its sentence, then the reports go. */
#testNote.rows { width: min(400px, calc(100vw - 20px)); min-width: 0; }
#testNote.rows .eyebrow .more { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
#testNote.rows .eyebrow .when { flex: none; }
#testNote .threads:empty, #testNote .fresh:empty { display: none; }
#testNote .threads { margin-top: 6px; padding-top: 3px; border-top: 1px solid rgba(255, 255, 255, 0.14); }
#testNote .threads p { display: grid; grid-template-columns: 7px minmax(0, 1fr) auto; gap: 0 6px; align-items: start; margin: 3px 0 0; font-size: 11px; line-height: 1.3; }
#testNote .threads p::before { content: ''; width: 6px; height: 6px; margin-top: 4px; border-radius: 50%; background: var(--good); }
#testNote .threads span { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; color: var(--text); }
#testNote .threads b, #testNote .log b { font-weight: 600; color: var(--shaman); }
#testNote .threads time { font-size: 10px; color: var(--muted); white-space: nowrap; }
#testNote .threads p[data-state="waiting"]::before { background: var(--accent); animation: testNotePulse 1.4s ease-in-out infinite; }
#testNote .threads p[data-state="waiting"] span { -webkit-line-clamp: 6; color: var(--accent); }
#testNote .threads p[data-state="waiting"] b { color: var(--accent); }
#testNote .threads p[data-state="done"]::before, #testNote .threads p[data-state="idle"]::before, #testNote .threads p[data-state="more"]::before { background: var(--muted); }
#testNote .threads p[data-state="done"] span, #testNote .threads p[data-state="idle"] span, #testNote .threads p[data-state="more"] span { color: var(--muted); }
#testNote.rows .about { max-height: 2.8em; overflow: hidden; }
#testNote.rows .log p { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }
#testNote .fresh { margin-top: 6px; padding-top: 5px; border-top: 1px solid rgba(255, 255, 255, 0.14); font-size: 10px; letter-spacing: 0.03em; color: var(--muted); }
#testNote .fresh.stale { font-size: 11.5px; font-weight: 600; letter-spacing: 0; color: var(--bad); }
#testNote .fresh:not(:empty) + .usage { margin-top: 2px; padding-top: 0; border-top: 0; }
#testNote.tight .about { display: none; }
#testNote.tight .threads span { -webkit-line-clamp: 1; }
#testNote.tight .threads p[data-state="waiting"] span { -webkit-line-clamp: 3; }
#testNote.tight .log p { -webkit-line-clamp: 1; }
#testNote.tighter .log { display: none; }
/* On a phone the game needs its screen: what is in the works is a title only there. */
@media (max-width: 720px), (max-height: 480px) {
  #testNote:not([data-kind="test"]) { min-width: 0; border-width: 13px; border-image-width: 13px; }
  #testNote:not([data-kind="test"]) .more { display: none; }
  #testNote:not([data-kind="test"]) .log, #testNote:not([data-kind="test"]) .threads, #testNote:not([data-kind="test"]) .fresh:not(.stale) { display: none; }
  #testNote:not([data-kind="test"]) .about { display: none; }
  #testNote:not([data-kind="test"]) h3 { margin: 2px 0 0; font-size: 12px; }
  #testNote:not([data-kind="test"]) .eyebrow { font-size: 8.5px; }
}
@keyframes testNoteIn { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
@keyframes testNotePulse { 50% { opacity: 0.35; } }
@media (prefers-reduced-motion: reduce) { #testNote, #testNote .eyebrow::before { animation: none; } }

/* The shaman window's title as the original writes it: teal, in the middle; the window closes by its button. */
/* A page that only watches a room (`?watch=`): nothing to type or to steer with, and no chat at all (the lines
   that pop up over the play, the panel and its button): the owner watches it in a small frame on his own site. */
html.watching #chatInput, html.watching #pad, html.watching #drawToggle,
html.watching #chat, html.watching #chatToast, html.watching #mChat,
html.watching #buildBar, html.watching #wheel, html.watching #mEmote, html.watching #shamanBar, html.watching #transformBar { display: none !important; }
/* The shaman's skill trees in the Shaman window (js/skills.js): five side by side where there is room for them,
   one under the other on a narrow window or a phone. A skill with no point in it is dim. */
#shaman .panel:has(.skill-set) { width: min(940px, 100%); max-height: 94vh; }
#shamanBody .skill-set h3 { margin: 6px 0; font-size: 13px; color: var(--text); }
#shamanBody .skill-none { margin: 0; font-size: 12px; opacity: 0.75; }
#shamanBody .skill-trees { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 8px; }
#shamanBody .skill-tree { min-width: 0; padding: 6px; border: 1px solid color-mix(in srgb, var(--tree) 45%, transparent); border-radius: 8px; background: rgba(0, 0, 0, 0.18); }
#shamanBody .skill-tree h4 { margin: 0 0 6px; font-size: 12px; text-align: center; color: var(--tree); }
#shamanBody .skill-row { display: flex; justify-content: center; gap: 4px; margin-bottom: 4px; }
#shamanBody .skill { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 3px 2px; border-radius: 6px; background: rgba(255, 255, 255, 0.05); opacity: 0.45; font-size: 10px; line-height: 1.15; text-align: center; }
#shamanBody .skill.has { opacity: 1; background: color-mix(in srgb, var(--tree) 24%, transparent); }
#shamanBody .skill b { font-weight: 600; overflow-wrap: anywhere; }
#shamanBody .skill i { font-style: normal; opacity: 0.8; }
@media (max-width: 760px) { #shamanBody .skill-trees { grid-template-columns: 1fr; } #shamanBody .skill { font-size: 11px; padding: 4px 3px; } }
html.mobile #shamanBody .skill-trees { grid-template-columns: 1fr; }
html.mobile #shamanBody .skill { font-size: 11px; padding: 4px 3px; }
#shaman .panel-head { justify-content: center; }
#shaman .panel-head h2 { color: #009d9d; }
#shaman .panel-head .close { display: none; }

/* ------------------------------------------------------------------ the login screen's background (js/backdrop.js)
   A room of the game seen through a blur, behind the login card; or, just after a deploy, one of the skies. The page
   inside the frame is the game with everything but the game taken away. */
#backdrop { position: fixed; z-index: 9; left: -3%; top: -3%; width: 106%; height: 106%; border: 0; pointer-events: none; filter: blur(7px) brightness(0.92); }
#login.modal.live { background: rgba(20, 28, 44, 0.18); }
#login.modal.still { background-size: cover; background-position: center; }
html.backdrop #hud, html.backdrop #sidebar, html.backdrop #chat, html.backdrop #editor, html.backdrop #login, html.backdrop #vote,
html.backdrop #touchControls, html.backdrop #buildBar, html.backdrop #chatToast, html.backdrop #drawToggle, html.backdrop #meepButton, html.backdrop #overlay,
html.backdrop #shamanBar, html.backdrop #transformBar, html.backdrop #testNote, html.backdrop #botLabel, html.backdrop #pad, html.backdrop .modal { display: none !important; }

/* The shaman's wheel (wheel.js): the original's nail cells, flying out to a circle around the shaman. */
#wheel { position: absolute; left: 0; top: 0; width: 0; height: 0; z-index: 6; pointer-events: none; }
#wheel.shut { visibility: hidden; }
#wheel.shut button { transition: none; pointer-events: none; }
#wheel button {
  position: absolute; left: -22px; top: -22px; width: 44px; height: 44px; padding: 0; border: 0; border-radius: 9px; cursor: pointer;
  display: grid; place-items: center; pointer-events: auto; color: #ffe2a3;
  background: url("/assets/client158/x_Ressources_Class/sprites/%24FondClou_1145.svg") center / 100% 100% no-repeat;
  translate: 0 0; scale: 0.3; opacity: 0;
  transition-property: translate, scale, opacity; transition-timing-function: cubic-bezier(0.2, 0.8, 0.25, 1);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4); will-change: translate, scale, opacity;
}
#wheel.open button { translate: var(--x) var(--y); scale: 1; opacity: 1; }
#wheel button img { max-width: 30px; max-height: 26px; pointer-events: none; }
#wheel button b { font: 700 20px/1 Verdana, sans-serif; }
#wheel button span { position: absolute; right: 4px; bottom: 1px; font: 10px/1.1 Verdana, sans-serif; color: #ffe2a3; text-shadow: 0 1px 1px #1d120b; }
#wheel button i { position: absolute; left: 4px; bottom: 1px; font: normal 10px/1.1 Verdana, sans-serif; color: #fff; text-shadow: 0 1px 1px #1d120b; }
#wheel button.spent { cursor: default; }
#wheel button.spent img { filter: brightness(0.2); opacity: 0.5; } /* the latest client's ColorTransform(0.2, 0.2, 0.2, 0.5) */
#wheel button.active { box-shadow: 0 0 0 2px #ffcd2c, 0 0 8px #ffcd2c; }
#wheel button:hover, #wheel button:focus-visible { box-shadow: 0 0 0 1px #ffe2a3, 0 2px 4px rgba(0, 0, 0, 0.4); outline: none; }
@media (prefers-reduced-motion: reduce) { #wheel button { transition-duration: 0ms !important; transition-delay: 0ms !important; } }
/* How to go on with a held object. */
#aimHint {
  position: absolute; z-index: 5; left: 50%; translate: -50% 0; bottom: calc(10px + env(safe-area-inset-bottom)); max-width: calc(100% - 24px);
  padding: 4px 10px; border-radius: 8px; background: rgba(38, 54, 63, 0.86); border: 1px solid #212f36; color: #c2c2da;
  font: 12px/1.3 Verdana, sans-serif; text-align: center; pointer-events: none;
}
#aimHint[hidden] { display: none; }
html.backdrop #wheel, html.backdrop #aimHint, html.mobile.editing #wheel, html.mobile.editing #aimHint { display: none !important; }

/* ------------------------------------------------------------------------------------------------ The desktop view
   The original's stage, 800 by 600, scaled to the window: the game in the top 400, the slate bar across its top and
   the slate panel under it (the two shapes of the original's interface clip, #324650), the chat where the original
   puts its chat (5, 402; 470 wide), the list of mice where it puts its list (496, 435; 149 by 162, rows of 19) and
   the help where it keeps its log of the round. `--u` is one of the original's pixels. */
html.desk { --u: min(100vw / 800, 100dvh / 600); }
html.desk body { margin: 0; height: 100dvh; overflow: hidden; display: grid; place-items: center; place-content: center; }
html.desk #app {
  position: relative; display: block; width: calc(800 * var(--u)); height: calc(600 * var(--u)); max-width: none;
  margin: 0; padding: 0; font-size: calc(11 * var(--u)); line-height: 1.35;
}
html.desk #app::before {
  content: ""; position: absolute; left: 0; top: calc(400 * var(--u)); width: 100%; height: calc(200 * var(--u));
  background: #324650; border-radius: calc(10 * var(--u));
}
html.desk #stage {
  position: absolute; left: 0; top: 0; width: calc(800 * var(--u)); height: calc(400 * var(--u)); aspect-ratio: auto;
  box-sizing: border-box; border: 0; border-image: none; border-radius: 0; box-shadow: none;
}
html.desk #hud {
  position: absolute; z-index: 6; left: 0; top: 0; width: 100%; height: calc(23 * var(--u)); box-sizing: border-box;
  flex-wrap: nowrap; gap: calc(10 * var(--u)); padding: 0 calc(8 * var(--u)); overflow: hidden;
  background: #324650; border: 0; border-radius: calc(6 * var(--u)); box-shadow: none;
}
html.desk .brand { display: none; }
html.desk .stat { flex: 0 0 auto; flex-direction: row; align-items: baseline; gap: calc(3 * var(--u)); font-size: calc(10 * var(--u)); line-height: 1; white-space: nowrap; }
html.desk .stat.wide { flex: 0 1 auto; min-width: 0; }
html.desk .stat .label { font-size: calc(8 * var(--u)); letter-spacing: 0; }
html.desk .stat.me { display: none; } /* the list of mice marks the player */
html.desk #menuBar { height: 100%; margin-left: auto; gap: calc(1 * var(--u)); align-items: center; flex: none; }
html.desk #menuBar button { min-width: 0; height: 100%; padding: 0 calc(3 * var(--u)); flex-direction: row; font-size: calc(10 * var(--u)); border: 0; border-radius: calc(4 * var(--u)); }
html.desk #menuBar button img { width: calc(17 * var(--u)); height: calc(17 * var(--u)); }
html.desk #menuBar button span { display: none; } /* icons in a row, as the original's; the name shows on hovering */
html.desk #menuBar button.primary-action { padding: 0 calc(8 * var(--u)); height: calc(18 * var(--u)); }
html.desk #menuBar button.primary-action span { display: inline; }
html.desk #chat {
  position: absolute; z-index: 1; left: calc(5 * var(--u)); top: calc(402 * var(--u)); width: calc(470 * var(--u)); height: calc(195 * var(--u));
  border: 0; border-radius: calc(6 * var(--u)); background: transparent; box-shadow: none;
}
html.desk #sidebar {
  position: absolute; z-index: 1; left: calc(496 * var(--u)); top: calc(402 * var(--u)); width: calc(149 * var(--u)); height: calc(195 * var(--u));
  display: block; padding: 0; border: 0; background: transparent; box-shadow: none; overflow: visible;
}
html.desk #sidebar h2 { height: calc(33 * var(--u)); margin: 0; display: flex; align-items: center; font-size: calc(15 * var(--u)); }
html.desk #playerList { height: calc(162 * var(--u)); background: #26363f; border-radius: calc(5 * var(--u)); }
html.desk #playerList li { min-height: calc(19 * var(--u)); padding: 0 calc(5 * var(--u)); font-size: calc(11 * var(--u)); align-items: center; }
html.desk .help {
  position: absolute; left: calc(154 * var(--u)); top: calc(2 * var(--u)); width: calc(145 * var(--u)); height: calc(192 * var(--u)); box-sizing: border-box;
  margin: 0; padding: calc(4 * var(--u)) calc(6 * var(--u)); border: 0; overflow-y: auto; background: #26363f; border-radius: calc(5 * var(--u));
}
html.desk .help summary { font: calc(13 * var(--u)) / 1.2 var(--title); color: var(--accent); list-style: none; cursor: default; }
html.desk .help dl { display: block; font-size: calc(9 * var(--u)); margin: calc(3 * var(--u)) 0 0; }
html.desk .help dt { margin-top: calc(3 * var(--u)); color: #c2c2da; font-weight: bold; }
html.desk .help dd { color: #8d9ab6; }
html.desk #editor {
  position: absolute; z-index: 2; left: 0; top: calc(400 * var(--u)); width: 100%; height: calc(200 * var(--u)); box-sizing: border-box;
  border: 0; border-radius: calc(10 * var(--u)); box-shadow: none;
}
/* The vote at the bottom right of the play, its two buttons where the latest's are (684 and 744 across, 376 down, 30
   wide: its _Vote clip). */
html.desk #vote {
  left: auto; right: calc(20 * var(--u)); bottom: calc(2 * var(--u)); transform: none;
  flex-wrap: wrap; justify-content: flex-end; gap: calc(4 * var(--u)) calc(30 * var(--u)); width: calc(162 * var(--u)); box-sizing: border-box;
  padding: calc(4 * var(--u)) calc(6 * var(--u)); font-size: calc(11 * var(--u)); border-radius: calc(6 * var(--u));
}
html.desk #vote > span { flex: 1 0 100%; text-align: center; }
html.desk #vote button { width: calc(30 * var(--u)); padding: calc(2 * var(--u)) 0; font-size: calc(10 * var(--u)); border-radius: calc(4 * var(--u)); }
html.desk .mobile-only { display: none !important; }

/* The latest build's wooden interface, the pictures its own server gives the client (fetched 2026-10-11 from
   www.transformice.com/images/x_transformice/x_interface/, wrapped as SVG by tools/wrap_bitmaps.py): 1 is the top bar,
   4 the band under the stage (planks for the chat at its left, a parchment sheet, five planks for the players at its
   right). First application: the top bar on 1, the chat on the left planks of 4. */
#hud { background: url('/assets/web/x_transformice/x_interface/1.svg') center / 100% 100% no-repeat #3b2418; border: 0; border-image: none; }
#chat { background: url('/assets/web/x_transformice/x_interface/4.svg') left top / 165% 100% no-repeat #2b1a11; border: 0; border-image: none; border-radius: 0; }
/* In the desktop layout the stage is the original's 800 by 600: its top bar and the 800 by 200 band under the stage
   are those two pictures, whole, in place of the flat slate they were painted. */
html.desk #hud { background: url('/assets/web/x_transformice/x_interface/1.svg') center / 100% 100% no-repeat #3b2418; border-radius: 0; }
html.desk #app::before { background: url('/assets/web/x_transformice/x_interface/4.svg') center / 100% 100% no-repeat #2b1a11; border-radius: 0; }
/* The phone layout's top bar is the same wooden strip. */
html.mobile #hud { background: url('/assets/web/x_transformice/x_interface/1.svg') center / 100% 100% no-repeat #3b2418; border: 0; border-image: none; }
/* On the band's wood and parchment (desktop): the list of mice is written on the sheet in the ink a sheet takes, and the
   panels that lay on the old slate have no ground of their own. */
html.desk #sidebar, html.desk .help { background: none; }
html.desk #sidebar li, html.desk #sidebar li .name { color: #3f2a14; }
html.desk .help dt { color: #ecdcb4; }
html.desk .help dd { color: #cdb98c; }
/* The latest client keeps its menu in the band, a row of buttons over the parchment, and the top bar for words alone.
   (Desktop layout. The list of mice begins under that row, on the sheet.) */
html.desk #hud { overflow: visible; }
html.desk #menuBar {
  position: absolute; left: calc(493 * var(--u)); top: calc(447 * var(--u)); width: calc(150 * var(--u)); height: calc(23 * var(--u));
  margin: 0; gap: 0; justify-content: space-between; align-items: center;
}
html.desk #menuBar button { padding: 0; height: auto; }
html.desk #menuBar button img { width: calc(15.5 * var(--u)); height: calc(15.5 * var(--u)); }
html.desk #menuBar button.primary-action { position: absolute; right: 0; top: calc(-447 * var(--u)); height: calc(18 * var(--u)); margin-top: calc(2 * var(--u)); }
html.desk #sidebar h2 { margin-bottom: calc(38 * var(--u)); }

/* The band's middle as the latest client has it: the player's own mouse in the square, the smileys on the hanging
   sign, the menu row under them, and the list of mice straight on the parchment (no heading, no panel of its own). */
#myPortrait, #signFaces { display: none; }
html.desk #myPortrait {
  display: grid; place-items: center; position: absolute; left: calc(1 * var(--u)); top: calc(3 * var(--u));
  width: calc(38 * var(--u)); height: calc(38 * var(--u)); overflow: hidden; pointer-events: none;
}
html.desk #myPortrait canvas { max-width: 130%; max-height: 130%; }
html.desk #signFaces {
  display: grid; grid-template-columns: repeat(5, 1fr); gap: 0; position: absolute; left: calc(47 * var(--u)); top: calc(5 * var(--u));
  width: calc(88 * var(--u)); height: calc(33 * var(--u)); align-items: center; justify-items: center;
}
html.desk #signFaces button { padding: 0; border: 0; background: none; box-shadow: none; line-height: 0; min-width: 0; cursor: pointer; }
html.desk #signFaces button img { width: calc(15 * var(--u)); height: auto; }
html.desk #signFaces button:hover img { filter: brightness(1.2); }
html.desk #sidebar h2 { visibility: hidden; height: calc(33 * var(--u)); margin: 0 0 calc(38 * var(--u)); }
html.desk #playerList { height: calc(122 * var(--u)); background: none; border-radius: 0; padding: 0 calc(4 * var(--u)); }
html.desk #playerList li { background: none; color: #3f2a14; border: 0; }
html.desk #playerList li:nth-child(odd) { background: rgba(90, 58, 22, 0.09); }
html.desk #playerList .name { color: #2f6d70; }
html.desk #playerList .score { color: #5b3f1e; }
html.desk #playerList li.me .name { color: #8a4a0c; }

/* Windows as the latest client draws them: its own window sprite ($FenetreBaseFn: a plank along the top with leaves
   at its corners, over the dark teal board), cut into nine by the sprite's own grid (tools/ui_art.py: 28.35 from the
   top, 35 from the right, 28.75 from the bottom, 35.85 from the left). The grid's corners are much wider than the
   frame is thick, so what a window holds reaches back out over them; its heading lies on the plank. */
.card, #options .card {
  padding: 0;
  background: none;
  border-style: solid; border-color: transparent; border-width: 28.35px 35px 28.75px 35.85px;
  border-image: url('/assets/ui/window.svg') 28.35 35 28.75 35.85 fill / 28.35px 35px 28.75px 35.85px stretch;
  border-radius: 0;
  box-shadow: none;
  filter: drop-shadow(0 14px 22px rgba(0, 0, 0, 0.5));
}
.card > *, #options .card > * { margin-left: -24px; margin-right: -24px; }
.card > :first-child { margin-top: 6px; }
.card > :last-child { margin-bottom: -14px; }
.card > .panel-head, .card > header.panel-head {
  margin-top: -26px; margin-bottom: 8px; min-height: 24px; align-items: center;
}
.card > .panel-head h2 { font-size: 18px; line-height: 24px; color: #f4e3b5; text-shadow: 0 1px 0 #2a1708, 0 2px 2px rgba(0, 0, 0, 0.45); padding-left: 22px; }
/* The close button: the round red one the latest client fetches (x_interface/x_fermer). */
.close:not(#cafeBack) {
  width: 22px; height: 22px; padding: 0; border: 0; border-radius: 50%; color: transparent; font-size: 0;
  background: url('/assets/web/x_transformice/x_interface/x_fermer.svg') center / contain no-repeat; box-shadow: none;
}
.card > .panel-head .close { margin-right: 20px; }
/* (The latest client keeps the band's right-hand planks bare; the list of controls that stands there is this
   client's own, kept to be looked at and judged: plain text on the planks, no panel.) */
/* On a phone the window keeps the sprite's own cuts too (an older rule made its frame thinner, for the old frame). */
html.mobile .card, html.mobile #options .card { border-width: 28.35px 35px 28.75px 35.85px; border-image-width: 28.35px 35px 28.75px 35.85px; }

/* The small panels that were slate boxes (the phone's menu and players panels, the emote menu, the vote box) lie on
   the latest client's own wood: the dark planks of its band (x_interface/4). */
html.mobile.menu-open #menuBar, html.mobile.menu-open #sidebar, #emoteMenu, html.mobile #emoteMenu, #vote {
  background: url('/assets/web/x_transformice/x_interface/4.svg') left top / 170% 100% no-repeat #2b1a11;
  border: 0; border-radius: 0; box-shadow: 0 8px 20px rgba(0, 0, 0, 0.45);
}
html.mobile.menu-open #menuBar button, html.mobile.menu-open #sidebar, html.mobile.menu-open #sidebar li, html.mobile.menu-open #sidebar .touch-help { color: #ecdcb4; }
html.mobile.menu-open #playerList li:nth-child(odd) { background: rgba(0, 0, 0, 0.18); }
#emoteMenu button, #vote button { background: rgba(20, 12, 7, 0.55); border-color: #5b3d22; color: #ecdcb4; }

/* The top bar as the latest client writes it (desktop, its n1475.n2159): the map (the maker or number in its <J>,
   " - @code" in its <BL>), then "Time left :", "Mice :" and the last field ("Shaman :" or "Round:", not shown while
   empty), each after a stroke in its <G> with three spaces either side; at the far end the room, with its
   community's flag. Labels in its <N>, values in its <V>, the shaman or round in its <CH>; Verdana 12. */
html.desk #hud .stat { order: 5; color: #c2c2da; align-items: center; font-size: calc(12 * var(--u)); gap: calc(4 * var(--u)); }
html.desk #hud .stat .label { font-size: inherit; letter-spacing: 0; text-transform: none; color: #c2c2da; }
html.desk #hud .stat.wide { order: 1; padding-left: calc(4 * var(--u)); }
html.desk #hud .stat.wide .label { display: none; }
html.desk #hud #mapName { color: #babd2f; }
html.desk #hud #mapName .map-number { color: #6c77c1; }
html.desk #hud .stat.clock { order: 2; }
html.desk #hud .stat:has(#miceCount) { order: 3; }
html.desk #hud .stat:has(#shamanName) { order: 4; }
html.desk #hud .stat.clock::before, html.desk #hud .stat:has(#miceCount)::before, html.desk #hud .stat:has(#shamanName)::before {
  content: '|'; color: #60608f; margin: 0 calc(9 * var(--u)) 0 calc(3 * var(--u));
}
html.desk #hud .stat.wide:has(#mapName:empty) { display: none; } /* (no map yet: no map part, nor its stroke) */
html.desk #hud .stat.wide:has(#mapName:empty) ~ .stat.clock::before { content: none; }
html.desk #hud #timer, html.desk #hud #miceCount { color: #009d9d; }
html.desk #hud #shamanName { color: #98e2eb; }
html.desk #hud .stat:has(#roomName) { order: 9; margin-left: auto; padding-right: calc(6 * var(--u)); gap: calc(4 * var(--u)); }
html.desk #hud .stat:has(#roomName) .label { display: none; }
html.desk #hud .stat:has(#roomName)::before {
  content: ''; width: calc(16 * var(--u)); height: calc(16 * var(--u)); flex: none;
  background: var(--room-flag, url('/assets/web/drapeaux/16/INT.svg')) center / contain no-repeat;
}
html.desk #hud #roomName { color: #53c9a6; } /* the latest's room name: green, or its <J> yellow for a '*' room */
html.desk #hud #roomName.starred { color: #babd2f; }

/* The band's buttons as the latest client places them (desktop): the menu row over the parchment keeps the shop,
   the rooms, the menu's other windows and full screen; friends, tribe and café are the chat bar's own three
   pictures there (#chatFriends…), so the menu's are not shown. The list of mice gives a name in teal and its score
   right after it. */
html.desk #menuBar button img { width: calc(18 * var(--u)); height: calc(18 * var(--u)); }
html.desk #menuFriends, html.desk #menuTribe, html.desk #menuCafe { display: none; }
html.desk #playerList li { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
html.desk #playerList .name { font-weight: bold; color: #0f9aa0; display: inline; }
html.desk #playerList .score { display: inline; margin-left: calc(4 * var(--u)); color: #6d74c4; font-weight: bold; }
html.desk #hud #mapName .map-kind { width: calc(15 * var(--u)); height: calc(15 * var(--u)); vertical-align: middle; margin-right: calc(4 * var(--u)); }
/* The square holds the mouse's head, large, as the latest client shows it. */
html.desk #myPortrait canvas { max-width: none; max-height: none; height: 215%; width: auto; transform: translate(-4%, 20%); }
/* The menu row in the latest client's order: the house, the list, the shop, the cup; then what it has not. */
html.desk #menuRooms { order: 1; }
html.desk #menuOptions { order: 2; }
html.desk #menuShop { order: 3; }
html.desk #menuProfile { order: 4; }
html.desk #menuEditor { order: 5; }
html.desk #menuShaman { order: 6; }
html.desk #menuFull { order: 7; }
html.desk #myPortrait { display: block; }
html.desk #myPortrait canvas { position: absolute; left: 50%; top: -4%; height: 170%; width: auto; max-width: none; max-height: none; transform: translateX(-54%); }

/* The chat as the latest client lays it out (desktop, its n479 at 5, 402: 470 by 200): the lines in Verdana 12 (or
   what /font and /fontsize chose), the bar 175 down, 20 high: friends, tribe and café (accounts only for the first
   two), the box (316 wide for an account, 360 for a guest), the plus, "to the last line" and the two arrows, 2
   apart; the cross before the box takes 22 of it (n8752). The scroll bar is the bar's arrows: the lines have none. */
html.desk #chatLog {
  padding: calc(2 * var(--u)); font-size: calc(var(--chat-size, 12) * var(--u)); font-family: var(--chat-font, Verdana, sans-serif);
  line-height: 1.17; scrollbar-width: none;
}
html.desk #chatLog::-webkit-scrollbar { display: none; }
html.desk #chatBar { flex: none; height: calc(20 * var(--u)); gap: calc(2 * var(--u)); margin: 0; padding: 0; border: 0; background: none; }
html.desk .chat-icon { width: calc(20 * var(--u)); height: calc(20 * var(--u)); }
html.desk #chatField {
  height: calc(21 * var(--u)); border-radius: calc(3 * var(--u)); font-size: calc(12 * var(--u));
  box-shadow: inset var(--u) var(--u) 0 #000, inset calc(-1 * var(--u)) calc(-1 * var(--u)) 0 rgba(255, 255, 255, 0.5);
}
html.desk #chatPrefix { padding: 0 calc(2 * var(--u)) 0 calc(3 * var(--u)); }
html.desk #chatInput { padding: 0 calc(3 * var(--u)); font-size: calc(12 * var(--u)); }
html.desk #chat.tabbed #chatTabs { padding-left: calc(2 * var(--u)); max-height: calc(100% - 10 * var(--u)); }
html.desk #chat.tabbed #chatLog { margin-left: calc(8 * var(--u)); }
html.desk .chat-tab { height: calc(17 * var(--u)); max-width: calc(90 * var(--u)); font-size: calc(12 * var(--u)); line-height: calc(17 * var(--u)); }
html.desk #chat.big {
  z-index: 5; left: calc(3 * var(--u)); top: calc(52 * var(--u)); width: calc(472 * var(--u)); height: calc(545 * var(--u));
  padding-left: calc(2 * var(--u)); border-radius: calc(10 * var(--u)) calc(10 * var(--u)) 0 0; background: rgba(62, 44, 29, 0.95);
}

/* The phone's bar with the desktop's words and colours (they stay stacked, for room), the clock first as there. */
html.mobile #hud .stat .label { color: #c2c2da; text-transform: none; letter-spacing: 0; }
html.mobile #hud #timer, html.mobile #hud #miceCount { color: #009d9d; }
html.mobile #hud #shamanName { color: #98e2eb; }
html.mobile #hud > .stat.clock { order: -1; }
html.desk #hud #timer.late, html.mobile #hud #timer.late { color: #cb546b; } /* the last ten seconds, in the game's <R> */
#shamanName .second-shaman { color: #feb1fc; } /* the second shaman, as the latest client colours it */
#hud > .stat[hidden] { display: none; }

/* The 3, 2, 1, go of a round's hold (js/countdown.js), its pictures at 400, 210 of the play, each grown about that
   point; in the touch view the same spot of the screen, in screen pixels. */
#countdown { position: absolute; z-index: 5; left: 50%; top: 52.5%; width: 0; height: 0; pointer-events: none; }
html.desk #countdown { left: calc(400 * var(--u)); top: calc(210 * var(--u)); }
#countdown img {
  position: absolute; max-width: none;
  left: calc(var(--x) * var(--u, 1px)); top: calc(var(--y) * var(--u, 1px)); width: calc(var(--w, 0) * var(--u, 1px));
  transform-origin: calc(var(--x) * -1 * var(--u, 1px)) calc(var(--y) * -1 * var(--u, 1px));
}
#countdown img[hidden] { display: none; }

/* (The English client writes "Time left : 00:56" and "Mice : 2", with a space before the colon: seen in a picture of it.) */

/* The list of mice as the latest client writes it (m3024, its row n1931): a row is "Name score" in Verdana 13 bold,
   the name in #604331 (the player's own in <V>, #009D9D) and the score in <BL> (#6C77C1), with a line of #D5CD9F under
   it from 5 to 140; rows lie 1 over each other (their spacing is -1), about 19.5 apart, with no ground of their own.
   The touch view writes the same words in the same order, a finger's height apart, on its own wood. */
html.desk #playerList li {
  min-height: 0; height: calc(19.5 * var(--u)); padding: 0 0 0 calc(2 * var(--u)); font: bold calc(13 * var(--u)) / calc(19.5 * var(--u)) Verdana, sans-serif;
  background: linear-gradient(#d5cd9f, #d5cd9f) left calc(5 * var(--u)) bottom / calc(135 * var(--u)) calc(1 * var(--u)) no-repeat;
}
html.desk #playerList li:nth-child(odd) { background: linear-gradient(#d5cd9f, #d5cd9f) left calc(5 * var(--u)) bottom / calc(135 * var(--u)) calc(1 * var(--u)) no-repeat; }
html.desk #playerList li .name { color: #604331; font-weight: bold; }
html.desk #playerList li.me .name { color: #009d9d; }
html.desk #playerList .score { color: #6c77c1; font-weight: bold; margin-left: 0; }
html.mobile #playerList li.me .name { color: #009d9d; }
html.mobile #playerList .score { color: #6c77c1; font-weight: bold; }

/* The two thin strips of the latest client's interface (desktop): one right under the top bar (x_interface/2, at 22),
   one along the top of the band (x_interface/3, at 390), each across the whole width, as that client places them. */
html.desk #app::after {
  content: ""; position: absolute; left: 0; top: 0; width: 100%; height: calc(400 * var(--u)); pointer-events: none; z-index: 1;
  background:
    url('/assets/web/x_transformice/x_interface/2.svg') left calc(22 * var(--u)) / 100% calc(8 * var(--u)) no-repeat,
    url('/assets/web/x_transformice/x_interface/3.svg') left calc(390 * var(--u)) / 100% calc(10 * var(--u)) no-repeat;
}

/* The last small slate boxes lie on the game's wood too: the phone's chat lines that pop up over the game. */
#chatToast .line { background: rgba(43, 26, 17, 0.82); color: #ecdcb4; }

/* The hanging sign's ten buttons (desktop): the latest client's own emote pictures, a face for the smileys, its plus. */
html.desk #signFaces button img { width: calc(15 * var(--u)); height: calc(15 * var(--u)); object-fit: contain; }

/* The bag: its button sits on the corner of the player's portrait, as in the latest client (desktop); its window is a
   grid of the things carried, each a picture of the game's server and a count. */
html.desk #menuBag { position: absolute; left: calc(-3 * var(--u)); top: calc(-21 * var(--u)); z-index: 2; }
html.desk #menuBag img { width: calc(17 * var(--u)); height: calc(17 * var(--u)); }
.bag-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(58px, 1fr)); gap: 6px; margin-bottom: 8px; }
.bag-tile { position: relative; aspect-ratio: 1; padding: 4px; border: 0; border-radius: 8px; background: #324650; cursor: pointer; }
.bag-tile:hover { filter: brightness(1.15); }
.bag-art { display: grid; place-items: center; width: 100%; height: 100%; }
.bag-art img { width: 40px; height: 40px; border-radius: 4px; }
.bag-count { position: absolute; right: 4px; bottom: 2px; font: bold 12px Verdana, sans-serif; color: #f4e3b5; text-shadow: 0 1px 1px #000; }

/* The daily quests. Their round button sits where the latest client puts it: at the same point of the portrait's
   square as the bag (which is drawn about that point at nine tenths), drawn down and right from it at eight tenths.
   A mission is a box as that client draws it (its row class): 200 wide, the dark rounded ground, what it pays in a
   30-wide square at the left with the number at its corner, the words beside it, and under both a bar 14 high, its
   two halves a shade apart, with "done/asked" in the middle. Gold for cheese, pink for the strawberry bonus. */
html.desk #menuQuests { position: absolute; left: calc(4.5 * var(--u)); top: calc(-14 * var(--u)); z-index: 3; }
html.desk #menuQuests img { width: calc(18.5 * var(--u)); height: calc(18.5 * var(--u)); }
/* Only its round picture takes a click, as Flash finds a click on what is drawn: a square box over the bag took the
   clicks meant for the bag's middle and opened the quests. (The button's corners are cut; the picture is not.) */
html.desk #menuBar #menuQuests { border-radius: 50%; }
html.desk #menuBar #menuQuests img { pointer-events: none; }
.quest-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 5px; margin-bottom: 4px; }
.quest-row { --bar: #d19f4d; --ink: #ffeac9; display: grid; grid-template-columns: 30px minmax(0, 1fr); gap: 5px; align-items: center; padding: 5px; border-radius: 6px; background: #102325; color: #c2c2da; font-size: 12px; line-height: 1.3; text-align: left; }
.quest-row.berries { --bar: #d14d6e; --ink: #ffc9d7; }
.quest-row.can-change { cursor: pointer; }
.quest-row.can-change:hover, .quest-row.can-change:focus-visible { filter: brightness(1.25); outline: 0; }
.quest-pay { position: relative; width: 30px; height: 30px; }
.quest-pay img { width: 100%; height: 100%; object-fit: contain; display: block; }
.quest-pay i { position: absolute; right: 0; bottom: 0; font: bold 11px/1 Verdana, sans-serif; font-style: normal; color: #fff; text-shadow: 0 0 2px #000, 0 0 2px #000, 0 0 3px #000; }
.quest-text b { color: #ef7a00; font-weight: normal; }
.quest-bar { grid-column: 1 / -1; position: relative; height: 14px; border-radius: 3px; background: #071213; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.12); overflow: hidden; }
.quest-fill { position: absolute; left: 2px; top: 2px; bottom: 2px; max-width: calc(100% - 4px); background: linear-gradient(to bottom, color-mix(in srgb, var(--bar) 80%, #fff) 50%, var(--bar) 50%); }
.quest-count { position: absolute; inset: 0; text-align: center; font: 11px/14px Verdana, sans-serif; color: var(--ink); text-shadow: 0 0 2px #000, 0 0 2px #000, 0 0 3px #000; }
.quest-ask { text-align: center; padding: 10px 0 4px; }
.quest-ask-buttons { display: flex; gap: 8px; justify-content: center; margin-top: 10px; }
#questToast { position: absolute; left: 50%; top: calc(25 * var(--u, 1px)); z-index: 40; width: min(230px, 86vw); pointer-events: none; opacity: 0; transform: translate(-50%, -18px); transition: opacity 0.25s, transform 0.25s; }
#questToast[hidden] { display: none; }
#questToast.in { opacity: 1; transform: translate(-50%, 0); }
#questToast.going { opacity: 0; }
#questToast .quest-row { box-shadow: 0 4px 12px rgba(0, 0, 0, 0.45); }
html.mobile #questToast { top: calc(env(safe-area-inset-top, 0px) + 46px); }
@media (max-width: 480px) { .quest-grid { grid-template-columns: minmax(0, 1fr); } }

/* The corner note, and the frame beside the training, are windows of the game like any other: the latest client's
   wooden window (the same sprite and cuts as .card), the note's top line lying on its plank as a window's heading
   does, the rest on the dark board. On a phone the same window at six tenths of its size. */
#testNote, #showFrame {
  padding: 0;
  border-style: solid; border-color: transparent; border-width: 28.35px 35px 28.75px 35.85px;
  border-image: url('/assets/ui/window.svg') 28.35 35 28.75 35.85 fill / 28.35px 35px 28.75px 35.85px stretch;
  filter: drop-shadow(0 14px 22px rgba(0, 0, 0, 0.5));
}
#testNote > * { margin-left: -22px; margin-right: -22px; }
#testNote > :not(.eyebrow) { min-width: calc(100% + 44px); }
#testNote .eyebrow { margin-top: -25px; margin-bottom: 10px; min-height: 22px; padding: 0 14px; color: #f4e3b5; text-shadow: 0 1px 0 #2a1708, 0 2px 2px rgba(0, 0, 0, 0.45); }
#testNote[data-kind="next"] .eyebrow { color: #f4e3b5; }
#testNote .eyebrow .when { color: #ecdcb4; }
#testNote > :last-child { margin-bottom: -12px; }
#testNote .usage { margin-top: 6px; padding-top: 5px; border-top: 1px solid rgba(255, 255, 255, 0.14); color: var(--muted); font-size: 10.5px; }
#testNote .usage:empty { display: none; }
#showFrame > * { margin-left: -24px; margin-right: -24px; }
#showFrame .what { margin-top: -24px; margin-bottom: 8px; min-height: 22px; padding: 0 14px; color: #f4e3b5; text-shadow: 0 1px 0 #2a1708; }
#showFrame > :last-child { margin-bottom: -14px; }
html.mobile #testNote { border-width: 17px 21px 17.25px 21.5px; border-image-width: 17px 21px 17.25px 21.5px; }
html.mobile #testNote > * { margin-left: -13px; margin-right: -13px; }
html.mobile #testNote > :not(.eyebrow) { min-width: calc(100% + 26px); }
html.mobile #testNote .eyebrow { margin-top: -15px; margin-bottom: 6px; min-height: 13px; padding: 0 8px; font-size: 8.5px; }
html.mobile #testNote > :last-child { margin-bottom: -7px; }

/* A profile's badges: the game server's own pictures, 40 by 40 as the latest client shows them, in a row that wraps. */
.badge-row { display: flex; flex-wrap: wrap; gap: 4px; margin: 2px 0 8px; }
.badge { position: relative; width: 40px; height: 40px; }
.badge img { display: block; width: 40px; height: 40px; }
.badge i { position: absolute; right: 0; bottom: 0; font: bold 10px/1 Verdana, sans-serif; font-style: normal; color: #fff; text-shadow: 0 0 2px #000, 0 0 2px #000, 0 0 3px #000; }

/* ---------------------------------------------------------------- a module's interface (js/modules.js)
   The screen layer (#overlay) is the original's stage, 800 by 400 of it shown, over the world and under every piece of
   the interface; the map layer (#moduleMap) moves with the world. Neither shows before the server's first [29,1].
   Texts are the latest client's text fields: Verdana 11 in #C2C2DA with Flash's 2 px gutter, their links the game's
   #2ECF73 under the pointer and #E9E654 pressed. */
#overlay { overflow: hidden; }
#moduleMap { position: absolute; left: 0; top: 0; width: 0; height: 0; transform-origin: 0 0; pointer-events: none; }
html:not(.modules) #overlay, html:not(.modules) #moduleMap, html.modules-buried #moduleMap { visibility: hidden; }
html.watching #overlay { display: none; }
.mod-layer { position: absolute; inset: 0; pointer-events: none; }
.mod-area, .mod-popup, .mod-picker { position: absolute; pointer-events: auto; font: 11px Verdana, sans-serif; color: #c2c2da; text-align: left; }
.mod-area-fill { position: absolute; inset: -4px; border-radius: 5px; }
.mod-area-line { position: absolute; inset: -5px; border: 2px solid; border-radius: 6px; }
.mod-text {
  position: relative; box-sizing: border-box; padding: 2px; font: 11px Verdana, sans-serif; line-height: normal; color: #c2c2da;
  white-space: pre-wrap; overflow-wrap: break-word; overflow: hidden; user-select: none; -webkit-user-select: none;
}
.mod-text.single { white-space: pre; width: max-content; }
.mod-text.single br { display: none; }
.mod-text.single div { display: inline; }
.mod-text a { color: inherit; text-decoration: none; cursor: pointer; }
.mod-text a:hover, .mod-text a:hover * { color: #2ecf73; }
.mod-text a:active, .mod-text a:active * { color: #e9e654; }
.mod-text img { max-width: none; }
.mod-image { position: absolute; left: 0; top: 0; transform-origin: 0 0; pointer-events: none; max-width: none; }
/* A popup: #324650 with the original's raised edge (light top-left, black bottom-right); its field sunk in #212E35. */
.mod-popup-back { position: absolute; border-radius: 5px; background: #324650; box-shadow: inset 1px 1px 1px #79acc6, inset -1px -1px 1px #000; }
.mod-popup-text { position: absolute; left: 0; top: 0; }
.mod-popup-field-back { position: absolute; height: 20px; border-radius: 3px; background: #212e35; box-shadow: inset 1px 1px 1px #000, inset -1px -1px 1px #79acc6; }
.mod-popup-field {
  position: absolute; box-sizing: border-box; height: 20px; margin: 0; padding: 2px; border: 0; outline: 0; background: transparent;
  font: 11px Verdana, sans-serif; color: #00cccc;
}
/* Its buttons are the game's $Btn, a cap of 10 at each end of the stretched middle; until the picture is there (or
   where it is not), one flat colour. */
.mod-btn { position: absolute; box-sizing: border-box; height: 20px; cursor: pointer; text-align: center; white-space: nowrap; background: var(--panel-2); }
.mod-btn.art {
  background: none; border-style: solid; border-width: 0 10px;
  border-image: url('/assets/client158/x_TransformiceFLA/sprites/%24Btn_692.svg') 0 10 fill / 0 10px stretch;
}
.mod-btn-label { position: relative; top: 2px; font: 11px Verdana, sans-serif; color: #c2c2da; }
.mod-btn.down .mod-btn-label { top: 3px; }
/* The colour picker: 365 wide in the frame of the latest client's windows, its rows at 4 from its side. */
.mod-picker { width: 365px; }
.mod-picker-frame { position: absolute; left: -10px; top: -10px; width: 385px; height: calc(100% + 20px); box-sizing: border-box; }
.mod-picker-title { position: absolute; left: 4px; top: 4px; width: 357px; min-height: 20px; font: 12px Verdana, sans-serif; text-align: center; overflow-wrap: break-word; }
.mod-editor { position: absolute; left: 4px; width: 356px; height: 256px; }
.mod-editor-square { position: absolute; left: 0; top: 0; width: 256px; height: 256px; cursor: crosshair; touch-action: none; }
.mod-editor-marker {
  position: absolute; width: 12px; height: 12px; margin: -6px 0 0 -6px; box-sizing: border-box; border: 2px solid #fff; border-radius: 50%;
  box-shadow: 0 0 1px 1px #000; pointer-events: none;
}
.mod-editor-hues { position: absolute; left: 266px; top: 0; width: 20px; height: 256px; cursor: pointer; touch-action: none; }
.mod-editor-arrow { position: absolute; left: 259px; width: 34px; height: 10px; margin-top: -5px; pointer-events: none; }
.mod-editor-arrow svg { display: block; }
.mod-editor-last { position: absolute; left: 306px; top: 0; width: 50px; height: 128px; }
.mod-editor-live { position: absolute; left: 306px; top: 128px; width: 50px; height: 128px; }
.mod-picker-row { position: absolute; left: 4px; width: 357px; height: 22px; display: flex; align-items: center; gap: 5px; font: 12px Verdana, sans-serif; white-space: nowrap; }
.mod-swatch { display: inline-block; flex: none; width: 18px; height: 18px; margin-top: -2px; cursor: pointer; }
.mod-swatch-text {
  flex: none; width: 65px; height: 18px; box-sizing: border-box; margin: -2px 11px 0 0; padding: 1px 2px; border: 0; outline: 0;
  background: transparent; font: 12px Verdana, sans-serif; color: #c2c2da; text-transform: uppercase;
}
.mod-recents { display: inline-flex; gap: 2px; }
.mod-picker-buttons { position: absolute; left: 4px; width: 357px; height: 22px; display: flex; gap: 16px; }
.mod-picker-button {
  flex: none; width: 170.5px; height: 22px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; cursor: pointer;
  font: 12px Verdana, sans-serif; color: #c2c2da; box-shadow: inset 1px 1px 1px rgba(255, 255, 255, 0.5), inset -1px -1px 1px #000;
}

/* The selfie's photo (js/selfie.js): the latest client's 400 by 320 window, its picture 400 by 270 over two
   buttons. It is made smaller to fit a small screen, never larger. */
#selfie { background: none; pointer-events: none; }
#selfie .selfie-card { pointer-events: auto; width: min(400px, 100%); padding: 0 2px; }
#selfie .selfie-frame { position: relative; width: 100%; aspect-ratio: 400 / 270; }
#selfie .selfie-photo { display: block; width: 100%; height: 100%; }
#selfie .selfie-flash { position: absolute; inset: 0; background: #ffffff; pointer-events: none; }
#selfie .selfie-buttons { display: grid; gap: 4px; margin-top: 4px; }
html.desk #selfie .selfie-card { width: calc(400 * var(--u)); }
html.desk #selfie .selfie-buttons button { font-size: calc(11 * var(--u)); }

/* The emotes and smileys as the latest client offers them (js/main.js, buildEmoteMenu): pictures alone. Every emote
   and the faces in one box where the touch view's button (and for now the chat bar's) opens it; from the band's sign
   the smileys' picker, a 210 by 200 box of 35 px faces on black at four tenths, its foot on the band (its n4647), and
   the plus's menu of the other seven, 20 px cells four to a row in a 100 wide box framed 10 px all round (n5449). */
#emoteMenu .emotes { display: grid; grid-template-columns: repeat(5, auto); gap: 4px; justify-content: start; }
#emoteMenu .emotes img { width: 28px; height: 28px; object-fit: contain; }
#emoteMenu .faces { display: flex; flex-wrap: wrap; gap: 2px; padding-top: 4px; border-top: 1px solid #5b3d22; }
#emoteMenu .faces button { border-color: transparent; background: none; }
#emoteMenu .faces img { width: 29px; height: 29px; }
html #emoteMenu.placed { position: fixed; right: auto; bottom: auto; z-index: 30; }
html #emoteMenu[data-mode="faces"] {
  display: block; box-sizing: border-box; width: 210px; height: 200px; padding: 0; overflow-y: auto;
  background: rgba(0, 0, 0, 0.4); border: 0; border-radius: 0; box-shadow: none;
}
html #emoteMenu[data-mode="faces"] .faces { gap: 0; padding: 0; border: 0; }
html #emoteMenu[data-mode="faces"] .faces button { padding: 0; border: 0; border-radius: 0; box-shadow: none; }
html #emoteMenu[data-mode="faces"] .faces img { width: 35px; height: 35px; }
html #emoteMenu[data-mode="more"] {
  display: block; width: 100px; padding: 0; background: none; box-shadow: none; border-radius: 0;
  border: 10px solid transparent; border-image: url('/assets/client158/x_TransformiceFLA/sprites/%24FenetreBase_1128.svg') 27 fill / 10px stretch;
  filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.45));
}
html #emoteMenu[data-mode="more"] .emotes { grid-template-columns: repeat(4, 20px); gap: 4px; }
html #emoteMenu[data-mode="more"] .emotes button { width: 20px; height: 20px; padding: 0; border: 0; border-radius: 0; background: none; box-shadow: none; display: grid; place-items: center; }
html #emoteMenu[data-mode="more"] .emotes img { width: 17px; height: 17px; }
html #emoteMenu[data-mode="more"] .emotes button:hover img, html #emoteMenu[data-mode="faces"] .faces button:hover img { filter: brightness(1.2); }
/* (After the modes' own rules, which would otherwise show it: what a mode leaves out, and the menu while shut.) */
html #emoteMenu[data-mode="faces"] .emotes, html #emoteMenu[data-mode="more"] .faces, html #emoteMenu[data-mode="more"] .emotes button.on-sign,
html #emoteMenu[hidden] { display: none; }
/* In the desktop view in the stage's own pixels. */
html.desk #emoteMenu[data-mode="faces"] { width: calc(210 * var(--u)); height: calc(200 * var(--u)); }
html.desk #emoteMenu[data-mode="faces"] .faces img { width: calc(35 * var(--u)); height: calc(35 * var(--u)); }
html.desk #emoteMenu[data-mode="more"] { width: calc(100 * var(--u)); border-width: calc(10 * var(--u)); border-image-width: calc(10 * var(--u)); }
html.desk #emoteMenu[data-mode="more"] .emotes { grid-template-columns: repeat(4, calc(20 * var(--u))); gap: calc(4 * var(--u)); }
html.desk #emoteMenu[data-mode="more"] .emotes button { width: calc(20 * var(--u)); height: calc(20 * var(--u)); }
html.desk #emoteMenu[data-mode="more"] .emotes img { width: calc(17 * var(--u)); height: calc(17 * var(--u)); }
/* The touch view's box lies under the top bar across the screen, its cells large enough for a finger. */
html.mobile #emoteMenu { position: fixed; z-index: 8; right: 8px; left: 8px; bottom: auto; top: calc(52px + env(safe-area-inset-top)); }
html.mobile #emoteMenu .emotes { grid-template-columns: repeat(auto-fill, minmax(44px, 1fr)); }
html.mobile #emoteMenu .emotes button { min-height: 44px; display: grid; place-items: center; }
html.mobile #emoteMenu .emotes img { width: 32px; height: 32px; }
html.mobile #emoteMenu .faces { justify-content: center; }
html.mobile #emoteMenu .faces img { width: 35px; height: 35px; }

/* A ban (main.js showBanned): nothing on the page but the latest client's window of 250 by 175 (its n1293), the words
   in its middle, the window at the middle across and seven tenths of the way down. */
html.banned #app { display: none; }
#banned.modal { display: block; background: none; }
#banned.modal[hidden] { display: none; }
#banned .card { position: absolute; box-sizing: border-box; width: 250px; height: 175px; left: calc((100% - 250px) / 2); top: calc((100% - 175px) * 0.7); display: grid; place-items: center; }
#bannedText { margin: 0; text-align: center; color: #c2c2da; }
