* {
  box-sizing: border-box;
}

[hidden] {
  display: none !important;
}

:root {
  --win-gray: #c0c0c0;
  --win-light: #ffffff;
  --win-mid: #dcdcdc;
  --win-dark: #808080;
  --win-black: #000000;
  --win-blue: #000080;
  --win-blue-light: #1084d0;
  --desktop-teal: #008080;
  --terminal-green: #00ff66;
}

html {
  min-height: 100%;
}

body {
  margin: 0;
  min-height: 100vh;
  background:
    radial-gradient(circle at 18px 18px, rgba(255, 255, 255, 0.08) 1px, transparent 1px),
    var(--desktop-teal);
  background-size: 24px 24px;
  font-family: Tahoma, Verdana, Arial, sans-serif;
  color: var(--win-black);
  padding: 14px;
}

.desktop {
  /* Fill the browser by default (desktop = full screen). On phones the viewport
     is already narrower than the classic window, so this changes nothing there.
     The □ titlebar button toggles the retro 540px floating window (.windowed). */
  width: 100%;
  margin: 0 auto;
}
.desktop.windowed {
  max-width: 540px;
}
.app-shell {
  position: relative;
  display: flex;
  flex-direction: column;
  height: calc(100vh - 28px);
  overflow: hidden;
}

.window {
  background: var(--win-gray);
  border: 2px solid var(--win-black);
  box-shadow:
    inset 2px 2px var(--win-light),
    inset -2px -2px var(--win-dark),
    7px 7px 0 rgba(0, 0, 0, 0.35);
}

.title-bar {
  height: 31px;
  background: linear-gradient(90deg, var(--win-blue), var(--win-blue-light));
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 4px 6px;
  font-weight: bold;
  font-size: 13px;
  user-select: none;
}

.title-left {
  display: flex;
  align-items: center;
  gap: 7px;
}

.gn-icon {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  object-fit: cover;
  display: inline-block;
  flex: 0 0 auto;
  box-shadow: 0 0 4px rgba(80, 170, 255, 0.7);
}

.window-buttons,
.button-row,
.chat-actions {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

.window-buttons {
  gap: 3px;
}

.win-btn {
  width: 20px;
  height: 20px;
  background: var(--win-gray);
  color: var(--win-black);
  border: 1px solid var(--win-black);
  box-shadow: inset 1px 1px var(--win-light), inset -1px -1px var(--win-dark);
  text-align: center;
  line-height: 17px;
  font-size: 12px;
}

.menu-bar {
  background: var(--win-gray);
  padding: 3px 6px;
  border-bottom: 1px solid var(--win-dark);
  font-size: 13px;
  display: flex;
  gap: 2px;
  flex-wrap: wrap;
  flex: 0 0 auto;
  z-index: 20;
}

.menu-item {
  padding: 2px 8px;
  min-height: 20px;
}

.menu-item:hover {
  background: var(--win-blue);
  color: #fff;
}

.menu-label::first-letter {
  text-decoration: underline;
}

.main-layout {
  display: grid;
  grid-template-columns: 265px minmax(0, 1fr);
  gap: 8px;
  padding: 8px;
}

.panel {
  background: var(--win-mid);
  border: 2px solid var(--win-dark);
  box-shadow: inset 1px 1px var(--win-light), inset -1px -1px #404040;
  padding: 8px;
}

.brand-box {
  display: flex;
  align-items: center;
  gap: 10px;
  background: #000;
  color: var(--terminal-green);
  border: 2px inset var(--win-dark);
  padding: 6px 12px;
  margin-bottom: 8px;
  font-family: "Courier New", monospace;
  text-shadow: 0 0 3px rgba(0, 255, 102, 0.65);
}

/* Compact top bar: the brand sits on one slim row instead of a tall hero,
   so Home leads with content. The logo is fixed-height (its wordmark + globe
   scale together) and the subtitle is pushed to the right edge. */
.brand-logo {
  display: block;
  width: auto;
  height: 38px;
  margin: 0;
}

.brand-title {
  font-size: 22px;
  font-weight: bold;
  letter-spacing: 1px;
}

.brand-subtitle,
.preview-mood,
.room-meta,
.room-status,
.room-note,
.hint-text {
  font-size: 12px;
}

.brand-subtitle {
  margin: 0 0 0 auto;
  color: #aaffcc;
}

.section-title {
  font-weight: bold;
  margin: 10px 0 5px;
}

.status-light,
.buddy {
  display: flex;
  align-items: center;
  gap: 6px;
}

.status-light {
  font-weight: bold;
  color: #006600;
  margin: 8px 0;
  flex-wrap: wrap;
}
.device-info,
.server-wipe,
.server-users {
  font-weight: normal;
  font-size: 11px;
  color: #5a5f6b;
  white-space: nowrap;
}
body.dark .device-info,
body.dark .server-wipe,
body.dark .server-users {
  color: #8aa0c4;
}

/* Identity header: the screen name + presence now sit inside the black brand
   box, immediately right of the orb logo, with the "Messenger 98" tagline
   tucked beneath. Text is forced onto the terminal palette so it stays legible
   on the always-black header in both themes. */
.brand-head {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1 1 auto;
  min-width: 0;
}
.brand-box .status-light {
  margin: 0;
  color: var(--terminal-green);
  text-shadow: 0 0 3px rgba(0, 255, 102, 0.55);
}
/* The presence stays on a single compact line beside the orb: the dot and
   "· Online" are fixed, and a long screen name ellipsizes rather than wrapping
   the dot onto its own line. */
.brand-presence {
  flex-wrap: nowrap;
  font-size: 13px;
}
.brand-presence .home-username {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.brand-presence #onlineStatus {
  flex: 0 0 auto;
  white-space: nowrap;
}
/* Keep the name/status separator attached to the status word — it leads
   "Online" rather than trailing the name. */
.brand-presence .home-username:not(:empty)::after {
  content: none;
}
.brand-presence #onlineStatus:not(:empty)::before {
  content: "\00b7";
  margin-right: 6px;
  color: #9fe7c2;
}
.brand-box .brand-subtitle {
  margin: 0;
}

/* Secondary system strip under the brand: server count · device · sound. Its
   texts no longer lead with a separator (they used to trail the name on one
   line), so a middot is inserted only between them when both are present. */
.home-meta {
  margin-top: 0;
  font-weight: normal;
}
.home-meta .server-users:not(:empty) + .device-info:not(:empty)::before {
  content: "\00b7";
  margin: 0 5px;
  color: #5a5f6b;
}
body.dark .home-meta .server-users:not(:empty) + .device-info:not(:empty)::before {
  color: #8aa0c4;
}
.home-meta .device-info:not(:empty) + .server-wipe:not(:empty)::before {
  content: "\00b7";
  margin: 0 5px;
  color: #5a5f6b;
}
body.dark .home-meta .device-info:not(:empty) + .server-wipe:not(:empty)::before {
  color: #8aa0c4;
}

/* Online indicator: the GreyNOC orb globe. Online = glowing blue globe;
   offline (.dot-off) = a dimmed, desaturated globe. Used everywhere a
   presence dot appears (status light, buddy rows, room users, channels). */
.dot {
  width: 12px;
  height: 12px;
  background: #04060c url("/icons/orb-256.png") center / cover no-repeat;
  border-radius: 50%;
  flex: 0 0 auto;
  box-shadow: 0 0 5px rgba(80, 170, 255, 0.75);
  animation: globe-pulse 2.4s ease-in-out infinite;
}
@keyframes globe-pulse {
  0%, 100% { box-shadow: 0 0 4px rgba(80, 170, 255, 0.55); }
  50% { box-shadow: 0 0 7px rgba(80, 170, 255, 0.95); }
}
@media (prefers-reduced-motion: reduce) {
  .dot { animation: none; }
}

label {
  display: block;
  font-weight: bold;
  margin: 8px 0 3px;
  font-size: 12px;
}

input,
textarea,
select {
  width: 100%;
  font-family: Tahoma, Verdana, Arial, sans-serif;
  font-size: 13px;
  border: 2px inset var(--win-dark);
  background: #fff;
  color: var(--win-black);
  padding: 5px;
  outline: none;
}

input:focus,
textarea:focus,
select:focus {
  background: #ffffe8;
}

textarea {
  resize: vertical;
  min-height: 56px;
}

.color-row {
  display: grid;
  grid-template-columns: 48px minmax(0, 1fr);
  gap: 6px;
  align-items: center;
}

input[type="color"] {
  height: 30px;
  padding: 0;
}

.button-row,
.chat-actions {
  margin-top: 8px;
}

button {
  font-family: Tahoma, Verdana, Arial, sans-serif;
  font-size: 13px;
  background: var(--win-gray);
  color: var(--win-black);
  border: 2px solid var(--win-black);
  box-shadow: inset 2px 2px var(--win-light), inset -2px -2px var(--win-dark);
  padding: 6px 10px;
  cursor: pointer;
  min-height: 30px;
}

button:hover {
  background: #d8d8d8;
}

button:active {
  box-shadow: inset 2px 2px var(--win-dark), inset -2px -2px var(--win-light);
  transform: translate(1px, 1px);
}

button:focus-visible {
  outline: 1px dotted var(--win-black);
  outline-offset: -5px;
}

.profile-preview,
.buddy-list,
.room-box,
.msg-pane,
.compose-box,
.chat-header {
  background: #fff;
  border: 2px inset var(--win-dark);
  padding: 8px;
}

.profile-preview {
  min-height: 100px;
  margin-top: 8px;
  word-break: break-word;
}

.preview-name {
  font-weight: bold;
  margin-bottom: 4px;
}

.preview-mood {
  color: #006600;
  margin-bottom: 6px;
}

/* Profile editor: text + background color side by side. */
.profile-colors {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 10px;
}
.color-field label {
  margin-top: 0;
}
.profile-help code {
  background: rgba(0, 0, 0, 0.08);
  border: 1px solid var(--win-dark);
  border-radius: 2px;
  padding: 0 3px;
  font-family: "Courier New", monospace;
  font-size: 11px;
  white-space: nowrap;
}
body.dark .profile-help code {
  background: rgba(255, 255, 255, 0.1);
}
.inline-btn {
  min-height: 0;
  padding: 2px 10px;
  font-size: 11px;
}

/* Rendered profile markup (preview card + Buddy Info). */
.profile-preview {
  border: 2px inset var(--win-dark);
  padding: 8px;
  border-radius: 2px;
}
.pc-empty {
  color: #777;
  font-style: italic;
}
.pc-marquee {
  display: block;
  overflow: hidden;
  white-space: nowrap;
  width: 100%;
}
.pc-marquee-inner {
  display: inline-block;
  padding-left: 100%;
  animation: pc-scroll 11s linear infinite;
}
@keyframes pc-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(-100%); }
}
@media (prefers-reduced-motion: reduce) {
  .pc-marquee-inner { animation: none; padding-left: 0; }
}

/* ---- Buddy Info window (AIM-style) ------------------------------------ */
.buddy-info { font-size: 12px; }
.bi-namefield { margin-bottom: 10px; }
/* Earned feed badges, shown only in Buddy Info. */
.bi-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 10px;
}
.bi-badges:empty {
  display: none;
}
.bi-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 9px;
  border-radius: 12px;
  font-size: 11px;
  font-weight: bold;
}
.bi-badge.best {
  background: linear-gradient(180deg, #ffe79a, #e0a400);
  border: 1px solid #b07d00;
  color: #4a3500;
}
.bi-badge.worst {
  /* "big red badge" for most dislikes. */
  background: #c0392b;
  border: 1px solid #7d1f15;
  color: #fff;
  font-size: 13px;
  padding: 4px 11px;
  letter-spacing: 0.04em;
  box-shadow: 0 0 6px rgba(192, 57, 43, 0.6);
}
.bi-namefield-label {
  font-size: 11px;
  color: #444;
  margin-bottom: 3px;
}
body.dark .bi-namefield-label { color: #9fb3d6; }
.bi-name-input {
  width: 100%;
  font-weight: bold;
}
.bi-row {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  padding: 3px 0;
  border-bottom: 1px dotted var(--win-dark);
}
.bi-label { color: #555; }
body.dark .bi-label { color: #9fb3d6; }
.bi-val {
  font-weight: bold;
  text-align: right;
  word-break: break-word;
}
.bi-on { color: #0a7d2c; }
.bi-away { color: #a86400; }
.bi-off { color: #888; }
.bi-key {
  font-family: "Courier New", monospace;
  font-weight: normal;
  font-size: 11px;
}
.bi-head {
  margin: 10px 0 4px;
  font-weight: bold;
  border-bottom: 1px solid var(--win-dark);
  padding-bottom: 3px;
}
.bi-profile {
  border: 2px inset var(--win-dark);
  background: #000;
  color: #dcdcdc;
  padding: 8px;
  min-height: 70px;
  max-height: 240px;
  overflow: auto;
  word-break: break-word;
  white-space: pre-wrap;
}
/* ⓘ Buddy-Info button on buddy rows. */
.buddy-info-btn {
  min-height: 0;
  padding: 0 5px;
  font-size: 12px;
  line-height: 1.5;
  margin-left: 2px;
}

/* ---- Live feed (X-style timeline) ------------------------------------- */
/* Lives in the center pane of the Home dashboard. The composer is pinned and
   the timeline below scrolls on its own (on desktop; on phones the page scrolls). */
.home-feed {
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.feed-composer {
  position: relative; /* anchor for the @-mention picker */
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  gap: 6px;
  background: var(--win-mid);
  border: 2px inset var(--win-dark);
  padding: 8px;
  margin-bottom: 10px;
}
/* Buddy @-mention picker (feed composer only). */
.mention-pop {
  position: absolute;
  left: 8px;
  right: 8px;
  top: calc(100% - 6px);
  z-index: 70;
  max-height: 168px;
  overflow: auto;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 3px;
  background: var(--win-gray);
  border: 2px solid var(--win-light);
  border-right-color: var(--win-dark);
  border-bottom-color: var(--win-dark);
  box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.4);
}
.mention-pop[hidden] {
  display: none;
}
.mention-row {
  width: 100%;
  padding: 4px 7px;
  text-align: left;
  font-size: 12px;
  font-weight: bold;
  color: var(--win-black);
  background: var(--win-gray);
  border: 1px solid transparent;
  cursor: pointer;
}
.mention-row:hover,
.mention-row.active {
  background: linear-gradient(90deg, var(--win-blue), var(--win-blue-light));
  color: #fff;
}
/* @mention highlight inside a rendered feed post. */
.feed-mention {
  color: #1f6fd6;
  font-weight: bold;
}
body.dark .feed-mention {
  color: #6fb4ff;
}
.feed-mention-you {
  padding: 0 3px;
  border-radius: 3px;
  color: #fff;
  background: #1f9d55;
}
.feed-composer textarea {
  width: 100%;
  resize: vertical;
  min-height: 38px;
  max-height: 96px; /* keep the "post something" box compact on phones */
}
.feed-composer-row {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
}
.feed-count {
  font-family: "Courier New", monospace;
  font-size: 11px;
  color: #5a5f6b;
}
.feed-count.low {
  color: #c00000;
  font-weight: bold;
}
body.dark .feed-count {
  color: #8aa0c4;
}
.feed-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 0 2px;
  /* Locked-size scroll viewport: the timeline scrolls INSIDE this box instead of
     growing the page, so you can scroll endlessly as posts arrive. Desktop swaps
     the fixed height for a flex-fill of the center pane (see the media query). */
  height: 60vh;
  min-height: 300px;
  overflow-y: auto;
  border: 2px inset var(--win-dark);
  background: var(--win-mid);
}
/* 12h docking: the winner sticks to the TOP of the viewport and the loser to the
   BOTTOM (see the sticky rules below); the timeline scrolls between them. */
.feed-post.feed-winner { order: -1; }
.feed-post.feed-loser { order: 2; }
.feed-empty {
  color: #777;
  font-style: italic;
  padding: 12px 4px;
}
.feed-post {
  background: #fff;
  border: 2px solid var(--win-dark);
  box-shadow: inset 1px 1px var(--win-light), inset -1px -1px #808080;
  padding: 6px 9px;
  animation: feed-in 0.18s ease-out;
}
body.dark .feed-post {
  background: #161b26;
}
@keyframes feed-in {
  from { opacity: 0; transform: translateY(-4px); }
  to { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .feed-post { animation: none; }
}
.feed-post-head {
  display: flex;
  align-items: baseline;
  gap: 6px;
  margin-bottom: 2px;
}
.feed-post-name {
  font-weight: bold;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 60%;
}
/* GreyNOC globe beside a bot's name (e.g. BB) in the feed. */
.feed-bot-badge {
  flex: 0 0 auto;
  align-self: center;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  object-fit: cover;
  filter: drop-shadow(0 0 3px rgba(79, 184, 255, 0.6));
}
.feed-post-time {
  margin-left: auto;
  flex: 0 0 auto;
  font-size: 11px;
  color: #5a5f6b;
}
body.dark .feed-post-time {
  color: #9fb3d6;
}
.feed-post-body {
  white-space: pre-wrap;
  word-break: break-word;
  line-height: 1.4;
}
/* Collapse long posts to 3 lines (the … is the click-to-expand cue); the JS
   only marks a body .feed-truncated when it actually overflows. */
.feed-post-body.feed-clamped {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.feed-post-body.feed-truncated {
  cursor: pointer;
}
.feed-post-body.feed-clamped.feed-expanded {
  display: block;
  -webkit-line-clamp: none;
  overflow: visible;
}
.feed-post-actions {
  margin-top: 5px;
  display: flex;
  gap: 8px;
}
.feed-vote {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-height: 0;
  padding: 2px 9px;
  font-size: 12px;
}
.feed-vote-icon {
  color: #888;
  line-height: 1;
}
.feed-vote-count {
  font-size: 11px;
  min-width: 8px;
}
/* 👍 / 👎 are emoji (their glyph color is fixed), so the active state is shown
   with a tinted border + background instead of recoloring the icon. */
.feed-like.on {
  border-color: #1a8a3c;
  background: rgba(26, 138, 60, 0.14);
}
.feed-dislike.on {
  border-color: #c0392b;
  background: rgba(192, 57, 43, 0.14);
}
.feed-hidden {
  display: none !important;
}
/* Phone view: pack the live feed tighter so more posts fit per screen — trims
   per-post padding, line height, action row, and the composer without changing
   any feature. */
@media (max-width: 600px) {
  .feed-list { gap: 4px; }
  .feed-post { padding: 4px 7px; }
  .feed-post-head { margin-bottom: 1px; gap: 5px; }
  .feed-post-name { font-size: 12px; max-width: 55%; }
  .feed-post-time { font-size: 10px; }
  .feed-post-body { line-height: 1.3; font-size: 13px; }
  .feed-post-actions { margin-top: 3px; gap: 6px; }
  .feed-vote { padding: 1px 7px; font-size: 11px; }
  .feed-vote-count { font-size: 10px; }
  .feed-composer { padding: 6px; margin-bottom: 6px; gap: 4px; }
  .feed-composer textarea { min-height: 32px; max-height: 80px; }
  .feed-bot-badge { width: 13px; height: 13px; }
}
.feed-count.slow {
  color: #9a6a00;
  font-weight: bold;
}
body.dark .feed-count.slow {
  color: #ffd54a;
}
.feed-friends-toggle {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-right: auto; /* push count + Post button to the right */
  font-size: 11px;
  cursor: pointer;
}
.feed-friends-toggle input {
  width: auto;
  margin: 0;
}
/* 12h dock badges + highlight. */
.feed-pin-badge {
  display: inline-block;
  margin: 0 0 6px;
  padding: 2px 7px;
  border-radius: 3px;
  font-size: 11px;
  font-weight: bold;
}
.feed-pin-badge.win {
  background: rgba(217, 164, 0, 0.18);
  border: 1px solid #d9a400;
  color: #8a6500;
}
.feed-pin-badge.lose {
  background: rgba(91, 127, 255, 0.16);
  border: 1px solid #5b7fff;
  color: #3a4fb0;
}
body.dark .feed-pin-badge.win {
  color: #ffd54a;
}
body.dark .feed-pin-badge.lose {
  color: #9fb3ff;
}
.feed-post.feed-winner {
  position: sticky;
  top: 0;
  z-index: 3;
  border-color: #d9a400;
  box-shadow: inset 0 0 0 1px #d9a400, 0 4px 9px rgba(0, 0, 0, 0.32);
}
.feed-post.feed-loser {
  position: sticky;
  bottom: 0;
  z-index: 3;
  border-color: #5b7fff;
  box-shadow: inset 0 0 0 1px #5b7fff, 0 -4px 9px rgba(0, 0, 0, 0.32);
}

.buddy-list {
  min-height: 120px;
  margin-top: 5px;
}

.home-social .buddy-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  overflow: hidden;
}

.home-buddy-section {
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.home-buddy-section[data-buddy-section="friends"],
.home-buddy-section[data-buddy-section="online"] {
  flex: 1 1 118px;
}

.home-buddy-section.buddy-section-collapsed {
  flex: 0 0 auto;
}

.buddy-section-body {
  min-height: 0;
  max-height: 160px;
  overflow-y: auto;
  padding: 2px 0;
}

.home-buddy-section[data-buddy-section="friends"] .buddy-section-body,
.home-buddy-section[data-buddy-section="online"] .buddy-section-body {
  flex: 1 1 auto;
}

.buddy-section-collapsed .buddy-section-body {
  display: none;
}

.buddy {
  padding: 3px;
  font-size: 13px;
}

.buddy:hover {
  background: var(--win-blue);
  color: #fff;
}

.buddy:hover .dot {
  border-color: #fff;
}

.room-box {
  margin-top: 5px;
  background: #efefef;
}

.room-box input,
.room-box button {
  margin-bottom: 6px;
}

.room-status {
  border: 1px inset var(--win-dark);
  background: #fff;
  color: #333;
  padding: 5px;
  margin: 4px 0 6px;
  line-height: 1.35;
}

.room-note {
  color: #333;
  line-height: 1.35;
}

#roomCode {
  text-transform: uppercase;
  font-family: "Courier New", monospace;
  font-weight: bold;
  letter-spacing: 1px;
}

#leaveRoomButton {
  width: auto;
}

.chat-panel {
  display: flex;
  flex-direction: column;
  min-height: 650px;
}

.chat-header {
  background: #efefef;
  margin-bottom: 8px;
}

.room-title {
  font-weight: bold;
  font-size: 17px;
}

.room-meta {
  margin-top: 3px;
  color: #333;
}

.msg-pane {
  flex: 1;
  overflow-y: auto;
  min-height: 410px;
  font-size: 13px;
  line-height: 1.35;
  background:
    linear-gradient(#ffffff, #ffffff),
    repeating-linear-gradient(0deg, transparent, transparent 22px, rgba(0, 0, 128, 0.05) 22px, rgba(0, 0, 128, 0.05) 23px);
}

.system-message {
  color: #666;
  font-style: italic;
  margin-bottom: 8px;
}

.message {
  margin-bottom: 9px;
  padding: 2px 0 4px;
}

.message-meta {
  color: #555;
  font-size: 12px;
}

.message-user {
  font-weight: bold;
  cursor: help;
}

.message-user:hover {
  text-decoration: underline;
}

.message-mood {
  color: #666;
  margin-left: 5px;
}

.message-text {
  margin-left: 12px;
  white-space: pre-wrap;
  word-break: break-word;
}

.compose-box {
  margin-top: 8px;
  background: var(--win-mid);
}
.compose-box.compose-disabled {
  opacity: 0.82;
}

.compose-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 86px;
  gap: 8px;
}

#text {
  min-height: 62px;
}
textarea:disabled,
button:disabled {
  cursor: not-allowed;
}
textarea:disabled {
  background: #ececec;
  color: #555;
}
button:disabled {
  opacity: 0.62;
}
button:disabled:hover {
  background: var(--win-gray);
}

/* Persistent bottom status bar (lives in .app-shell, shown on every view).
   Plain Win98 text boxes by default; becomes a router-LED panel in chat. */
.footer {
  flex: 0 0 auto;
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
  padding: 6px 8px;
  border-top: 1px solid var(--win-dark);
  background: var(--win-gray);
  font-size: 12px;
}

.status-box {
  flex: 1 1 150px;
  border: 1px inset var(--win-dark);
  background: var(--win-mid);
  padding: 3px 8px;
  min-width: 120px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---- Router-LED status bar (chat view) -------------------------------- */
/* In the rooms view the status bar morphs into a metered router panel: each
   item collapses to a short label + a blinking LED, each glowing at its own
   rate so it reads like a router's front-panel activity lights. */
.app-shell[data-view="rooms"] .footer {
  gap: 8px;
  padding: 5px 10px;
  justify-content: flex-start;
  align-items: center;
  background: linear-gradient(180deg, #161b26 0%, #0a0d14 100%);
  border-top: 1px solid #05070b;
}
.app-shell[data-view="rooms"] .status-box {
  flex: 0 0 auto;
  min-width: 0;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 9px;
  border: 1px solid #2a3344;
  border-radius: 3px;
  background: #0a0d14;
  box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.6);
  font-size: 0; /* hide the verbose value text; label comes from ::after */
  overflow: visible;
}
.app-shell[data-view="rooms"] .status-box::before {
  content: "";
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #18c464;
  box-shadow: 0 0 6px #18c464, inset 0 -1px 1px rgba(0, 0, 0, 0.4), inset 0 1px 1px rgba(255, 255, 255, 0.5);
  flex: 0 0 auto;
  animation: led-meter 1.6s ease-in-out infinite;
}
.app-shell[data-view="rooms"] .status-box::after {
  content: attr(data-led);
  font: 700 10px/1 "Courier New", monospace;
  letter-spacing: 0.1em;
  color: #9fb1cc;
}
/* Independent blink rates = router activity feel. */
.app-shell[data-view="rooms"] .status-box[data-led="NET"]::before { animation-duration: 1.9s; }
.app-shell[data-view="rooms"] .status-box[data-led="RELAY"]::before { animation-duration: 2.7s; animation-delay: 0.3s; }
.app-shell[data-view="rooms"] .status-box[data-led="PM2"]::before { animation-duration: 0.6s; } /* fast = activity */
.app-shell[data-view="rooms"] .status-box[data-led="UP"]::before { animation-duration: 3.3s; animation-delay: 0.15s; }
/* WAN down: the NET led turns red while the socket is dropped. */
.app-shell[data-view="rooms"] .footer.net-down .status-box[data-led="NET"]::before {
  background: #e84545;
  box-shadow: 0 0 7px #e84545;
  animation-duration: 0.4s;
}
@keyframes led-meter {
  0%, 100% { opacity: 0.4; }
  50% { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .app-shell[data-view="rooms"] .status-box::before { animation: none; opacity: 1; }
}

/* ===========================================================================
 * Retro chrome additions: sound toggle, working menus, modals, nudge, buzz,
 * saved profiles, and window-button states.
 * ========================================================================= */

/* Window chrome buttons are now real <button>s - keep the retro 90s look. */
.win-btn {
  cursor: pointer;
  padding: 0;
  font-family: Tahoma, Verdana, Arial, sans-serif;
}
.win-btn:active {
  box-shadow: inset 1px 1px var(--win-dark), inset -1px -1px var(--win-light);
}

/* Minimize = roll the window up to just its title bar. Maximize = full width. */
.window.rolled {
  height: auto;
}
.window.rolled .views,
.window.rolled .menu-bar,
.window.rolled .nav-drawer,
.window.rolled .nav-scrim {
  display: none;
}

/* Sound on/off toggle, parked next to the status light. */
.sound-toggle {
  margin-left: auto;
  min-height: 0;
  padding: 1px 7px;
  font-size: 11px;
  font-weight: bold;
  letter-spacing: 1px;
  line-height: 16px;
}
.sound-toggle.muted {
  color: #a00000;
}

/* ---------------------------------------------------------------------------
 * Friends quick-button: a Win98 button beside SND with a blinking presence LED
 * and an overlapping pop-down of your first 3 friends. The full Friends list
 * still lives under the live feed; this is the at-a-glance shortcut.
 * The LED blinks green when friends are online (once per online friend), and
 * a single blue blink when none are — driven by JS (see updateFriendsQuick).
 * ------------------------------------------------------------------------- */
.status-light .sound-toggle {
  margin-left: auto; /* SND rides the right edge of the status row */
}
.home-control-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 6px;
  margin-top: 10px;
}
.home-control-grid > * {
  min-width: 0;
}
/* Control popovers (Friends / Display / Away) OVERLAP the content below instead of
   expanding inline and reflowing the grid. The panel is the positioning context;
   its open controls float as an absolute pop-down (see .friends-pop for the
   sibling pattern). Mutual exclusion + outside-click/Escape are wired in app.js. */
.home-control-grid > details {
  position: relative;
}
.home-control-grid > details[open] {
  grid-column: auto; /* stay in the cell — the open controls are absolute, not inline */
  z-index: 61; /* lift the open tile so its pop-down sits above neighboring tiles */
}
.home-control-grid > details > .theme-controls,
.home-control-grid > details > .away-status-controls,
.home-control-grid > details > .chat-controls {
  position: absolute;
  top: calc(100% + 3px);
  left: 0;
  right: auto;
  z-index: 61;
  min-width: 200px;
  max-width: min(248px, calc(100vw - 24px));
  padding: 6px;
  background: var(--win-gray);
  color: var(--win-black);
  border: 2px solid var(--win-light);
  border-right-color: var(--win-dark);
  border-bottom-color: var(--win-dark);
  box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.4);
}
/* Chat dropdown: the Chat tile is a <details>; its summary keeps the orb look, so
   hide the native disclosure triangle. The options stack inside the pop-down. */
.chat-jump-btn {
  list-style: none;
}
.chat-jump-btn::-webkit-details-marker {
  display: none;
}
.home-control-grid > details > .chat-controls {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
/* On narrow screens the right-column control tiles (Display = 2nd child, Chat =
   4th child) would push their left-anchored pop-down past the right edge — anchor
   those to the right so they open leftward and stay on screen. */
@media (max-width: 480px) {
  .home-control-grid > details:nth-child(2) > .theme-controls,
  .home-control-grid > details:nth-child(4) > .chat-controls {
    left: auto;
    right: 0;
  }
}
.chat-option {
  width: 100%;
  padding: 5px 8px;
  text-align: left;
  font-size: 12px;
  font-weight: bold;
  cursor: pointer;
  background: var(--win-gray);
  border: 2px solid var(--win-black);
  box-shadow: inset 1px 1px var(--win-light), inset -1px -1px var(--win-dark);
}
.chat-option:hover,
.chat-option:focus-visible {
  background: linear-gradient(90deg, var(--win-blue), var(--win-blue-light));
  color: #fff;
  outline: none;
}
.chat-option:active {
  box-shadow: inset 1px 1px var(--win-dark), inset -1px -1px var(--win-light);
}
/* Friends now reads as its own foldable bar, mirroring the Display / Away rows. */
.friends-quick {
  position: relative;
  display: block;
}
.friends-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  min-height: 26px;
  padding: 3px 6px;
  font-size: 12px;
  text-align: left;
  cursor: pointer;
  background: var(--win-gray);
  border: 2px solid var(--win-black);
  box-shadow: inset 2px 2px var(--win-light), inset -2px -2px var(--win-dark);
}
.friends-btn::before {
  content: "+";
  display: inline-grid;
  place-items: center;
  width: 14px;
  height: 14px;
  flex: 0 0 auto;
  border: 1px solid var(--win-black);
  background: #fff;
  font-weight: bold;
  line-height: 1;
}
.friends-btn[aria-expanded="true"]::before {
  content: "-";
}
.friends-btn-label {
  font-weight: bold;
  white-space: nowrap;
}
.friends-btn-value {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 1 1 auto;
  min-width: 0;
  color: #5a5f6b;
}
.friends-btn-edit {
  flex: 0 0 auto;
  font-weight: bold;
  text-decoration: underline;
}
body.dark .friends-btn::before {
  background: #101622;
}
body.dark .friends-btn-value {
  color: #8aa0c4;
}
.friend-led {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  flex: 0 0 auto;
  background: #123048;
  box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.6);
}
.friend-led.led-blue {
  background: #123048;
}
.friend-led.led-green {
  background: #123a23;
}
.friend-led.led-blue.on {
  background: #4fb8ff;
  box-shadow: 0 0 6px 1px rgba(79, 184, 255, 0.95);
}
.friend-led.led-green.on {
  background: #39ff8a;
  box-shadow: 0 0 6px 1px rgba(57, 255, 138, 0.95);
}
@media (prefers-reduced-motion: reduce) {
  /* Steady (no blink) for reduced-motion users — JS leaves it lit. */
  .friend-led.on {
    box-shadow: none;
  }
}
.friends-btn-count {
  background: #0a5a0a;
  color: #fff;
  border-radius: 7px;
  padding: 0 5px;
  font-size: 10px;
  font-weight: bold;
  min-width: 13px;
  text-align: center;
  line-height: 14px;
}
.friends-btn-count.none {
  background: var(--win-dark);
}
.friends-pop {
  position: absolute;
  top: calc(100% + 3px);
  /* Anchor to the LEFT edge of the Friends cell so the dropdown opens rightward
     into the 290px console column. (Right-anchoring spilled it off the window's
     left edge once Friends became a narrow grid cell, clipping every name.) */
  left: 0;
  right: auto;
  z-index: 60;
  min-width: 214px;
  max-width: min(214px, calc(100vw - 24px));
  background: var(--win-gray);
  color: var(--win-black);
  border: 2px solid var(--win-light);
  border-right-color: var(--win-dark);
  border-bottom-color: var(--win-dark);
  box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.4);
  padding: 4px;
}
.friends-pop[hidden] {
  display: none;
}
.friends-pop-head {
  font-weight: bold;
  font-size: 11px;
  padding: 2px 4px 4px;
  border-bottom: 1px solid var(--win-dark);
  margin-bottom: 3px;
}
.friends-pop-row {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  background: transparent;
  border: 0;
  padding: 4px 5px;
  text-align: left;
  cursor: pointer;
  font-size: 12px;
  color: inherit;
}
.friends-pop-row:hover,
.friends-pop-row:focus-visible {
  background: var(--win-blue);
  color: #fff;
  outline: none;
}
.friends-pop-name {
  flex: 1 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.friends-pop-st {
  font-size: 10px;
  color: var(--win-dark);
}
.friends-pop-row:hover .friends-pop-st,
.friends-pop-row:focus-visible .friends-pop-st {
  color: #cdd9ff;
}
.friends-pop-row.buddy-off {
  opacity: 0.62;
}
.friends-pop-all {
  width: 100%;
  margin-top: 3px;
  font-size: 11px;
  min-height: 0;
  padding: 2px 6px;
  line-height: 16px;
}
.friends-pop .buddy-empty {
  padding: 8px 6px;
  font-size: 12px;
}

/* Script-kiddie roast toast: a terminal line that slides up from the bottom when
   someone drops an injection payload into a compose box (see roastHacker). */
.hack-toast {
  position: fixed;
  left: 50%;
  bottom: 18px;
  transform: translateX(-50%) translateY(14px);
  z-index: 9999;
  max-width: min(92vw, 560px);
  padding: 9px 14px;
  background: #000;
  color: #39ff8a;
  border: 1px solid #1f9b59;
  box-shadow: 0 0 12px rgba(57, 255, 138, 0.45);
  font: 12px/1.45 "Courier New", monospace;
  text-shadow: 0 0 4px rgba(57, 255, 138, 0.7);
  white-space: pre-wrap;
  word-break: break-word;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s ease, transform 0.18s ease;
}
.hack-toast.show {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
@media (prefers-reduced-motion: reduce) {
  .hack-toast {
    transition: opacity 0.18s ease;
    transform: translateX(-50%);
  }
}

/* Working menu bar dropdowns. */
.menu-item {
  position: relative;
  cursor: default;
  user-select: none;
}
.menu-item.open {
  background: var(--win-blue);
  color: #fff;
}
.menu-dropdown {
  position: absolute;
  top: 100%;
  left: 0;
  min-width: 188px;
  background: var(--win-gray);
  border: 2px solid var(--win-black);
  box-shadow: inset 1px 1px var(--win-light), inset -1px -1px var(--win-dark), 3px 3px 0 rgba(0, 0, 0, 0.35);
  padding: 2px;
  z-index: 60;
  color: var(--win-black);
  font-weight: normal;
}
.menu-dropdown-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  padding: 4px 18px 4px 12px;
  font-size: 13px;
  cursor: pointer;
  white-space: nowrap;
}
.menu-dropdown-item:hover {
  background: var(--win-blue);
  color: #fff;
}
.menu-dropdown-item.disabled {
  color: var(--win-dark);
  cursor: default;
}
.menu-dropdown-item.disabled:hover {
  background: transparent;
  color: var(--win-dark);
}
.menu-accel {
  font-size: 11px;
  opacity: 0.8;
}
.menu-sep {
  height: 2px;
  margin: 3px 2px;
  border-top: 1px solid var(--win-dark);
  border-bottom: 1px solid var(--win-light);
}

/* Modal dialogs (about, prompts, sound test, confirms). */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 64, 0.35);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100;
  padding: 16px;
}
.modal {
  width: 100%;
  background: var(--win-gray);
  border: 2px solid var(--win-black);
  box-shadow: inset 2px 2px var(--win-light), inset -2px -2px var(--win-dark), 7px 7px 0 rgba(0, 0, 0, 0.4);
  animation: gn-pop 0.12s ease-out;
}
@keyframes gn-pop {
  from { transform: scale(0.94); opacity: 0.4; }
  to { transform: scale(1); opacity: 1; }
}
.modal-title-bar {
  height: 28px;
  background: linear-gradient(90deg, var(--win-blue), var(--win-blue-light));
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 4px 4px 4px 8px;
  font-weight: bold;
  font-size: 13px;
}
.modal-close {
  width: 20px;
  height: 20px;
  min-height: 0;
  padding: 0;
  line-height: 16px;
  font-size: 13px;
}
.modal-body {
  padding: 14px 14px 6px;
  font-size: 13px;
  line-height: 1.45;
  max-height: 65vh;
  overflow-y: auto;
}
.modal-line {
  min-height: 6px;
  word-break: break-word;
  white-space: pre-wrap;
}
.modal-body label {
  margin-top: 4px;
}
.modal-buttons {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  padding: 8px 14px 14px;
}
.modal-buttons button.primary {
  font-weight: bold;
}
.sound-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 8px;
}
.sound-grid button {
  min-height: 26px;
  padding: 4px 8px;
  font-size: 12px;
}

/* App-wide toast feedback. */
.toast-container {
  position: fixed;
  right: 18px;
  bottom: 18px;
  z-index: 120;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 6px;
  pointer-events: none;
}
.app-toast {
  max-width: min(340px, calc(100vw - 36px));
  padding: 7px 10px;
  background: var(--win-gray);
  color: var(--win-black);
  border: 2px solid var(--win-black);
  box-shadow: inset 1px 1px var(--win-light), inset -1px -1px var(--win-dark), 3px 3px 0 rgba(0, 0, 0, 0.35);
  font-size: 12px;
  line-height: 1.35;
  animation: app-toast-in 0.16s ease-out;
}
.app-toast.ok {
  border-color: #0f6e2f;
}
.app-toast.warn {
  border-color: #9a6a00;
}
.app-toast.error {
  border-color: #a00000;
}
.app-toast-out {
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.25s, transform 0.25s;
}
@keyframes app-toast-in {
  from {
    transform: translateY(8px);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}
@media (prefers-reduced-motion: reduce) {
  .app-toast {
    animation: none;
  }
  .app-toast-out {
    transition: none;
  }
}

/* Saved profile vault list. */
.saved-profiles {
  background: #fff;
  border: 2px inset var(--win-dark);
  padding: 5px;
  margin-top: 5px;
  min-height: 44px;
  max-height: 140px;
  overflow-y: auto;
}

/* Profile -> Rank Friends: a compact reorderable list with up/down controls. */
.friend-rank-list {
  background: #fff;
  border: 2px inset var(--win-dark);
  padding: 4px;
  margin-top: 5px;
  max-height: 200px;
  overflow-y: auto;
}
body.dark .friend-rank-list {
  background: #0e1320;
}
.friend-rank-row {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 3px 4px;
}
.friend-rank-pos {
  font-family: "Courier New", monospace;
  font-size: 11px;
  color: #5a5f6b;
  min-width: 26px;
}
body.dark .friend-rank-pos {
  color: #8aa0c4;
}
.friend-rank-name {
  flex: 1 1 auto;
  font-size: 13px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.friend-rank-btn {
  flex: 0 0 auto;
  width: 30px;
  height: 26px;
  min-height: 0;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  line-height: 1;
}
.friend-rank-btn:disabled {
  opacity: 0.4;
  cursor: default;
}

.saved-empty {
  color: #666;
  font-size: 12px;
  font-style: italic;
  padding: 3px;
}
.saved-row {
  display: flex;
  align-items: stretch;
  gap: 4px;
  margin-bottom: 3px;
}
.saved-load {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 6px;
  text-align: left;
  min-height: 0;
  padding: 3px 6px;
  font-size: 12px;
  overflow: hidden;
}
.saved-swatch {
  width: 11px;
  height: 11px;
  flex: 0 0 auto;
  border: 1px solid var(--win-black);
  border-radius: 2px;
}
.saved-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.saved-del {
  min-height: 0;
  padding: 3px 7px;
  font-size: 11px;
  color: #a00000;
  font-weight: bold;
}

/* BUZZ!!! nudge - shake the whole window, flash the message. */
@keyframes gn-shake {
  10%, 90% { transform: translate(-2px, 1px); }
  20%, 80% { transform: translate(4px, -2px); }
  30%, 50%, 70% { transform: translate(-6px, 2px); }
  40%, 60% { transform: translate(6px, -1px); }
}
.window.nudge {
  animation: gn-shake 0.5s ease-in-out;
}
.buzz-msg .message-text {
  color: #cc0000;
  font-weight: bold;
  font-family: "Courier New", monospace;
}
.buzz-msg {
  animation: gn-flash 0.4s steps(1) 2;
}
@keyframes gn-flash {
  50% { background: #ffe0e0; }
}

@media (prefers-reduced-motion: reduce) {
  .window.nudge,
  .buzz-msg,
  .pub-dot.active,
  .pub-dot.unread,
  .modal {
    animation: none;
  }
}

/* Lobby / Room conversation tabs. */
.chat-tabs {
  display: flex;
  gap: 4px;
  padding: 0 2px;
  margin-bottom: -2px;
}
.chat-tab {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  column-gap: 5px;
  border: 2px solid var(--win-black);
  border-bottom: none;
  background: var(--win-gray);
  box-shadow: inset 1px 1px var(--win-light);
  padding: 5px 14px;
  font-size: 12px;
  font-weight: bold;
  min-height: 0;
  border-radius: 4px 4px 0 0;
  color: #444;
}
.tab-main {
  display: flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tab-lock {
  flex: 0 0 auto;
  font-size: 11px;
}
.tab-tier {
  grid-column: 1 / span 2;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 10px;
  font-weight: normal;
  line-height: 1.1;
  color: #5a5f6b;
}
.chat-tab:hover {
  background: #d8d8d8;
}
.chat-tab.active {
  background: var(--win-mid);
  color: var(--win-black);
  z-index: 2;
  padding-bottom: 7px;
}
.chat-tab.in-room::before {
  content: none;
}
.chat-tab.in-room .tab-main::after {
  content: "";
  flex: 0 0 auto;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #00cc00;
  border: 1px solid #006600;
}
.tab-badge[hidden] {
  display: none;
}
.tab-badge {
  display: inline-block;
  grid-column: 2;
  grid-row: 1;
  min-width: 16px;
  margin-left: 4px;
  padding: 0 4px;
  font-size: 11px;
  line-height: 15px;
  text-align: center;
  color: #fff;
  background: #c00000;
  border: 1px solid #600000;
  border-radius: 8px;
}

.security-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  align-items: center;
  padding: 0 2px;
  margin: -3px 0 1px;
  color: #5a5f6b;
  font-size: 11px;
}
.security-legend span {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 1px 5px;
  background: var(--win-mid);
  border: 1px solid var(--win-dark);
}
.security-legend b {
  font-family: "Courier New", monospace;
}

.room-invite-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 8px;
  align-items: center;
  padding: 7px 8px;
  background: #f6fff5;
  border: 2px inset var(--win-dark);
  font-size: 12px;
}
.room-invite-main {
  min-width: 0;
}
.room-invite-title {
  font-weight: bold;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.room-invite-code strong {
  font-family: "Courier New", monospace;
  letter-spacing: 1px;
}
.room-invite-note {
  margin-top: 2px;
  color: #4a4a4a;
}
.room-invite-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 5px;
}
.room-invite-actions button {
  min-height: 0;
  padding: 3px 8px;
  font-size: 11px;
}

/* Live Buddy List. */
.buddy-count {
  font-weight: normal;
  font-size: 11px;
  color: #006600;
}
.buddy-group {
  font-size: 11px;
  font-weight: bold;
  color: var(--win-dark);
  text-transform: uppercase;
  letter-spacing: 1px;
  margin: 5px 0 2px;
}
.buddy-group-toggle {
  width: 100%;
  min-height: 0;
  display: flex;
  align-items: center;
  gap: 5px;
  margin: 0;
  padding: 4px 6px;
  text-align: left;
  background: var(--win-mid);
  border: 1px solid var(--win-dark);
  box-shadow: inset 1px 1px var(--win-light), inset -1px -1px var(--win-dark);
}
.buddy-group-toggle:hover {
  background: #d8d8d8;
}
.buddy-group-toggle:active {
  transform: none;
}
.buddy-caret {
  width: 12px;
  flex: 0 0 auto;
  font-family: "Courier New", monospace;
  font-size: 12px;
  line-height: 1;
}
.buddy-group-count {
  margin-left: auto;
  color: #006600;
  font-size: 11px;
  font-weight: normal;
  letter-spacing: 0;
  text-transform: none;
}
.buddy-empty {
  font-size: 12px;
  font-style: italic;
  color: #777;
  padding: 3px;
}
.buddy-online {
  cursor: pointer;
}
.buddy-online,
.buddy-friend {
  display: flex;
  align-items: center;
  gap: 6px;
}
.buddy-friend .buddy-name {
  flex: 0 1 auto;
}
.friend-add,
.friend-del {
  margin-left: auto;
  min-height: 0;
  width: 20px;
  padding: 0;
  font-size: 16px;
  font-weight: bold;
  line-height: 16px;
  text-align: center;
  box-shadow: none;
  border: 1px solid var(--win-dark);
}
.friend-add {
  color: #0a7d1a; /* green — add */
}
.friend-del {
  color: #a00000; /* red — remove */
}
body.dark .friend-add {
  color: #5dca6e;
}
body.dark .friend-del {
  color: #ff8a8a;
}
/* Word-label variants of the friend control (request handshake states). Unlike
   the square "+" they size to their text. */
.friend-add.friend-pending,
.friend-add.friend-accept,
.friend-add.friend-decline {
  width: auto;
  padding: 0 7px;
  font-size: 11px;
  line-height: 18px;
  letter-spacing: 0.3px;
}
.friend-add.friend-pending {
  color: var(--win-dark);
  font-weight: normal;
  font-style: italic;
}
.friend-add.friend-accept {
  color: #0a7d1a;
}
.friend-add.friend-decline {
  color: #a00000;
  margin-left: 4px;
}
body.dark .friend-add.friend-pending {
  color: #8aa0c4;
}
body.dark .friend-add.friend-accept {
  color: #5dca6e;
}
body.dark .friend-add.friend-decline {
  color: #ff8a8a;
}
/* Friend Requests section — incoming asks awaiting accept/decline. */
.buddy-group-static {
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 4px 6px;
  margin: 0;
  font-size: 11px;
  font-weight: bold;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--win-dark);
  background: var(--win-mid);
  border: 1px solid var(--win-dark);
  box-shadow: inset 1px 1px var(--win-light), inset -1px -1px var(--win-dark);
}
.friend-req-row {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 2px 3px;
}
.friend-req-row .buddy-name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.friend-req-row .friend-add {
  margin-left: 0;
}
.dot-req {
  filter: hue-rotate(40deg) saturate(1.4);
}
.buddy-off {
  opacity: 0.6;
}
.dot-off {
  filter: grayscale(1) brightness(0.7);
  box-shadow: none;
  animation: none;
}
.buddy-name {
  font-weight: bold;
}
.buddy-mood {
  color: #666;
  font-size: 12px;
}
.buddy-online:hover .buddy-mood {
  color: #fff;
}

/* Fighter-jet "Night Ops" toggle: a guarded cockpit switch. */
.display-switch {
  display: grid;
  grid-template-columns: auto auto auto;
  align-items: center;
  justify-content: center;
  gap: 7px;
  margin: 8px 0 2px;
  padding: 7px 6px 5px;
  background: #15171c;
  border: 2px inset var(--win-dark);
}
.ds-label {
  font-size: 10px;
  font-weight: bold;
  letter-spacing: 1px;
  color: #8a8f99;
}
.ds-night {
  color: #6ad0ff;
}
.ds-wipe {
  color: #ff6b6b;
}

/* Two guarded switches side by side: Day/Night + Wipe. */
.switch-bank {
  display: flex;
  justify-content: center;
  gap: 12px;
  margin: 8px 0 2px;
  padding: 7px 6px 5px;
  background: #15171c;
  border: 2px inset var(--win-dark);
}
.switch-unit {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
}
.switch-row {
  display: flex;
  align-items: center;
  gap: 6px;
}
.ds-caption {
  grid-column: 1 / -1;
  text-align: center;
  font-size: 10px;
  letter-spacing: 2px;
  margin-top: 3px;
  color: #d2a533;
  font-family: "Courier New", monospace;
}
.jet-switch {
  position: relative;
  width: 46px;
  height: 54px;
  padding: 0;
  min-height: 0;
  border: 2px solid #0a0c10;
  border-radius: 6px;
  background: linear-gradient(#3b414c, #1c2027);
  box-shadow: inset 0 1px 0 #5b6270, inset 0 -3px 5px rgba(0, 0, 0, 0.6);
  perspective: 240px;
  cursor: pointer;
}
.jet-slot {
  position: absolute;
  left: 50%;
  top: 9px;
  transform: translateX(-50%);
  width: 16px;
  height: 36px;
  background: #08090d;
  border-radius: 4px;
  box-shadow: inset 0 0 5px #000;
}
.jet-lever {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  bottom: 9px;
  width: 18px;
  height: 20px;
  background: linear-gradient(#d6d9df, #80848d);
  border: 1px solid #2c2f36;
  border-radius: 4px;
  box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.5);
  transition: top 0.15s ease, bottom 0.15s ease, background 0.15s ease;
}
.jet-switch.on .jet-lever {
  bottom: auto;
  top: 9px;
  background: linear-gradient(#ffd76b, #e09a18);
}
.jet-guard {
  position: absolute;
  left: -2px;
  right: -2px;
  top: -3px;
  height: 46px;
  background: repeating-linear-gradient(45deg, #d23b32 0 6px, #a92a23 6px 12px);
  border: 2px solid #5a120e;
  border-radius: 6px 6px 3px 3px;
  transform-origin: top center;
  transform: rotateX(0deg);
  transition: transform 0.22s ease;
  box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.25);
}
.jet-switch.armed .jet-guard {
  transform: rotateX(-128deg);
}
.jet-switch.armed {
  box-shadow: inset 0 1px 0 #5b6270, inset 0 -3px 5px rgba(0, 0, 0, 0.6), 0 0 8px rgba(106, 208, 255, 0.7);
}
.jet-switch:focus-visible {
  outline: 2px dotted #6ad0ff;
  outline-offset: 2px;
}

/* ===========================================================================
 * Night Ops (dark theme). Flip the variables, then patch the surfaces that
 * use literal colors. Activated by `body.dark`.
 * ========================================================================= */
body.dark {
  --win-gray: #2a2f3b;
  --win-light: #454c5e;
  --win-mid: #20242e;
  --win-dark: #0c0f16;
  --win-black: #cdd9ec;
  --desktop-teal: #070b14;
  /* Recolor native UI (scrollbars, <select> option popups, etc.) to match. */
  color-scheme: dark;
}
body.dark {
  background:
    radial-gradient(circle at 18px 18px, rgba(120, 170, 255, 0.07) 1px, transparent 1px),
    var(--desktop-teal);
  background-size: 24px 24px;
}
body.dark input,
body.dark textarea,
body.dark select {
  background: #0d1119;
  color: #d6e6ff;
}
body.dark input:focus,
body.dark textarea:focus,
body.dark select:focus {
  background: #141b27;
}
body.dark .profile-preview,
body.dark .buddy-list,
body.dark .compose-box,
body.dark .saved-profiles,
body.dark .room-invite-card {
  background: #161b26;
}
body.dark .room-box {
  background: #11151f;
}
body.dark .chat-header {
  background: #1a2030;
}
body.dark .room-status {
  background: #0d1119;
  color: #9fb3d6;
}
body.dark .room-note {
  color: #9fb3d6;
}
body.dark .msg-pane {
  color: #d6e6ff;
  background:
    linear-gradient(#10141d, #10141d),
    repeating-linear-gradient(0deg, transparent, transparent 22px, rgba(120, 170, 255, 0.06) 22px, rgba(120, 170, 255, 0.06) 23px);
}
body.dark .system-message {
  color: #8aa0c4;
}
body.dark .message-meta {
  color: #9fb0cc;
}
body.dark .message-mood,
body.dark .buddy-mood {
  color: #8294b4;
}
body.dark .room-meta {
  color: #9fb3d6;
}
body.dark textarea:disabled {
  background: #171b25;
  color: #8294b4;
}
body.dark .security-legend {
  color: #8aa0c4;
}
body.dark .room-invite-note {
  color: #9fb3d6;
}
body.dark button:hover,
body.dark .chat-tab:hover {
  background: #3a4150;
}
body.dark .chat-tab {
  color: #aebbd2;
}
body.dark .tab-tier {
  color: #8aa0c4;
}
body.dark .saved-empty,
body.dark .buddy-empty {
  color: #8090aa;
}

/* ---- framed empty states: turn barren areas (feed, buddy/online lists, public
   rooms, rank list, blocked list) into inviting retro panels — glyph + guidance.
   Scoped to those containers so the compact friends-pop dropdown is untouched. */
.feed-empty,
#friendList .buddy-empty,
#onlineBuddies .buddy-empty,
#pubRoomList .buddy-empty,
#friendRankList .buddy-empty,
#blockedList .buddy-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 18px 12px;
  text-align: center;
  font-style: normal;
  font-size: 12px;
  color: #5a5f6b;
}
.feed-empty {
  min-height: 150px;
}
.feed-empty::before,
#friendList .buddy-empty::before,
#onlineBuddies .buddy-empty::before,
#pubRoomList .buddy-empty::before,
#friendRankList .buddy-empty::before,
#blockedList .buddy-empty::before {
  display: inline-grid;
  place-items: center;
  width: 42px;
  height: 42px;
  font-size: 22px;
  line-height: 1;
  border: 2px solid #0a3a6e;
  background: #dde8f5;
  content: "\1F4AC"; /* speech balloon — feed / rooms */
}
#friendList .buddy-empty::before,
#onlineBuddies .buddy-empty::before,
#friendRankList .buddy-empty::before {
  content: "\1F465"; /* people — friends / online / rank */
}
#blockedList .buddy-empty::before {
  content: "\1F6AB"; /* no entry — blocked */
}
body.dark .feed-empty,
body.dark #friendList .buddy-empty,
body.dark #onlineBuddies .buddy-empty,
body.dark #pubRoomList .buddy-empty,
body.dark #friendRankList .buddy-empty,
body.dark #blockedList .buddy-empty {
  color: #8aa0c4;
}
body.dark .feed-empty::before,
body.dark #friendList .buddy-empty::before,
body.dark #onlineBuddies .buddy-empty::before,
body.dark #pubRoomList .buddy-empty::before,
body.dark #friendRankList .buddy-empty::before,
body.dark #blockedList .buddy-empty::before {
  border-color: #2c7a4a;
  background: #0c1a14;
}
body.dark .preview-mood,
body.dark .status-light {
  color: #5fe39a;
}
body.dark .status-box {
  color: #cdd9ec;
}

/* Cryptographic-identity badges on messages + the fingerprint readout. */
.msg-badge {
  display: inline-block;
  margin-left: 4px;
  font-size: 11px;
  font-weight: bold;
  cursor: help;
}
.msg-badge.id-self,
.msg-badge.id-verified {
  color: #0a8a0a;
}
.msg-badge.id-known,
.msg-badge.id-new {
  color: #1060c0;
}
.msg-badge.id-conflict,
.msg-badge.id-changed,
.msg-badge.id-invalid {
  color: #cc0000;
}
body.dark .msg-badge.id-self,
body.dark .msg-badge.id-verified {
  color: #5fe39a;
}
body.dark .msg-badge.id-known,
body.dark .msg-badge.id-new {
  color: #6ad0ff;
}
.id-fingerprint {
  font-family: "Courier New", monospace;
  font-size: 17px;
  font-weight: bold;
  letter-spacing: 2px;
  text-align: center;
  padding: 9px;
  margin: 6px 0;
  background: #f0f0f0;
  border: 2px inset var(--win-dark);
  word-break: break-all;
}
body.dark .id-fingerprint {
  background: #11151f;
  color: #6ad0ff;
}

/* Encrypted file messages. */
.file-message .file-body {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.file-name {
  font-weight: bold;
}
a.file-download {
  display: inline-block;
  padding: 1px 8px;
  font-size: 12px;
  background: var(--win-gray);
  border: 2px solid var(--win-black);
  box-shadow: inset 1px 1px var(--win-light), inset -1px -1px var(--win-dark);
  color: var(--win-black);
  text-decoration: none;
}
a.file-download:active {
  box-shadow: inset 1px 1px var(--win-dark), inset -1px -1px var(--win-light);
}
#attachButton {
  font-size: 12px;
}

/* Message reactions. */
.react-wrap {
  position: relative;
  display: inline-block;
  margin-left: 4px;
}
.react-btn {
  min-height: 0;
  padding: 0 5px;
  font-size: 11px;
  line-height: 15px;
  box-shadow: none;
  border: 1px solid var(--win-dark);
}
.react-palette {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 40;
  display: flex;
  gap: 2px;
  padding: 3px;
  background: var(--win-gray);
  border: 2px solid var(--win-black);
  box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.35);
}
/* The class' explicit display would otherwise override the UA [hidden] rule,
   leaving the emoji palette permanently open. Re-hide it when toggled closed. */
.react-palette[hidden] {
  display: none;
}
.react-emoji {
  min-height: 0;
  padding: 1px 3px;
  font-size: 15px;
  border: 1px solid transparent;
  background: transparent;
  box-shadow: none;
}
.react-emoji:hover {
  background: var(--win-blue);
}
.reactions {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin: 3px 0 0 12px;
}
.react-pill {
  font-size: 12px;
  padding: 0 6px;
  line-height: 18px;
  background: #e8e8e8;
  border: 1px solid var(--win-dark);
  border-radius: 9px;
  cursor: pointer;
}
.react-pill.mine {
  background: #cfe0ff;
  border-color: #1060c0;
}
body.dark .react-pill {
  background: #2a2f3b;
  color: #cdd9ec;
}
body.dark .react-pill.mine {
  background: #1a3050;
  border-color: #6ad0ff;
}

/* Typing indicator + disappearing-message controls. */
.typing-indicator {
  padding: 2px 8px 3px;
  font-size: 12px;
  font-style: italic;
  color: #555;
  min-height: 15px;
}
body.dark .typing-indicator {
  color: #8aa0c4;
}
.disappear-control {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  margin: 0;
  font-size: 11px;
  font-weight: normal;
}
.disappear-control select {
  width: auto;
  min-width: 54px;
  padding: 2px 4px;
  font-size: 11px;
}
.ephemeral-badge {
  margin-left: 4px;
  font-size: 11px;
  cursor: help;
  opacity: 0.8;
}
.message.vanishing {
  animation: gn-vanish 0.45s ease forwards;
  overflow: hidden;
}
@keyframes gn-vanish {
  to {
    opacity: 0;
    transform: translateX(14px);
    max-height: 0;
    margin-bottom: 0;
    padding: 0;
  }
}
@media (prefers-reduced-motion: reduce) {
  .message.vanishing {
    animation: none;
  }
}

/* ===========================================================================
 * Buddy List pop-out window (buddylist.html)
 * ========================================================================= */
.section-title:has(.popout-btn) {
  display: flex;
  align-items: center;
  gap: 6px;
}
.popout-btn {
  margin-left: auto;
  min-height: 0;
  padding: 1px 8px;
  font-size: 10px;
  line-height: 16px;
}

body.buddy-popout {
  padding: 0;
  min-height: 100vh;
  overflow: hidden;
}
.bl-window {
  display: flex;
  flex-direction: column;
  height: 100vh;
  border-width: 0;
  box-shadow: none;
}
.bl-window .title-bar,
.bl-me,
.bl-toolbar,
.bl-footer {
  flex: 0 0 auto;
}
.bl-window .sound-toggle.muted {
  opacity: 0.55;
  text-decoration: line-through;
}

.bl-me {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 9px;
  background: var(--win-gray);
  border-bottom: 1px solid var(--win-dark);
}
.bl-logo {
  width: 34px;
  height: 34px;
  flex: 0 0 auto;
}
.bl-me-text {
  flex: 1;
  min-width: 0;
}
.bl-me-name {
  font-weight: bold;
  font-size: 13px;
  color: #0a6b2e;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
body.dark .bl-me-name {
  color: var(--terminal-green);
}
.bl-me-key {
  font-size: 10px;
  color: #5a5f6b;
  font-family: "Courier New", monospace;
}
.bl-sync {
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--win-dark);
  flex: 0 0 auto;
}
.bl-sync.on {
  background: #21d07a;
  box-shadow: 0 0 6px #21d07a;
}
.bl-sync.off {
  background: #c9603f;
}

.bl-toolbar {
  padding: 6px 8px;
  background: var(--win-mid);
  border-bottom: 1px solid var(--win-dark);
  display: flex;
  flex-direction: column;
  gap: 5px;
}
.bl-search {
  width: 100%;
}
.bl-toolrow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font-size: 11px;
}
.bl-sort,
.bl-offline {
  display: flex;
  align-items: center;
  gap: 4px;
  cursor: pointer;
}
.bl-sort select {
  font-size: 11px;
  min-height: 0;
  padding: 1px 2px;
  width: auto;
}

.bl-list,
.bl-detail {
  flex: 1 1 auto;
  overflow-y: auto;
  background: #ffffff;
}
body.dark .bl-list,
body.dark .bl-detail {
  background: #11151f;
}
.bl-list {
  padding: 3px 0;
}

.bl-group {
  border-bottom: 1px solid rgba(128, 128, 128, 0.22);
}
.bl-group-head {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 6px;
  text-align: left;
  padding: 5px 8px;
  background: transparent;
  border: 0;
  box-shadow: none;
  font-weight: bold;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--win-blue);
  cursor: pointer;
  min-height: 0;
}
.bl-group-head:hover {
  background: rgba(16, 132, 208, 0.12);
}
body.dark .bl-group-head {
  color: #7fb2ff;
}
.bl-caret {
  width: 10px;
  font-size: 10px;
}
.bl-group-label {
  flex: 1;
}
.bl-group-count {
  font-weight: normal;
  background: var(--win-dark);
  color: #fff;
  border-radius: 8px;
  padding: 0 6px;
  font-size: 10px;
}
.bl-group-body {
  padding: 1px 0 4px;
}

.bl-row {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 4px 9px;
  cursor: pointer;
}
.bl-row:hover {
  background: rgba(16, 132, 208, 0.18);
}
.bl-row .dot {
  flex: 0 0 auto;
}
.bl-row-main {
  flex: 1;
  min-width: 0;
}
.bl-row-name {
  display: flex;
  align-items: center;
  gap: 4px;
}
.bl-star {
  color: #e8b007;
  font-size: 11px;
}
.bl-name {
  font-size: 13px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bl-row-sub {
  font-size: 10px;
  color: #5a5f6b;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
body.dark .bl-row-sub {
  color: #8aa0c4;
}
.bl-row-off .bl-name {
  color: #6b7079;
}
body.dark .bl-row-off .bl-name {
  color: #74808f;
}
.bl-row-actions {
  display: flex;
  gap: 3px;
  opacity: 0;
  transition: opacity 0.1s;
  flex: 0 0 auto;
}
.bl-row:hover .bl-row-actions,
.bl-row:focus-within .bl-row-actions {
  opacity: 1;
}
.bl-act {
  min-height: 0;
  padding: 0 5px;
  font-size: 12px;
  line-height: 17px;
  box-shadow: none;
  border: 1px solid var(--win-dark);
}
.bl-act.on {
  color: #e8b007;
}
.bl-add {
  color: #1a7f37;
  font-weight: bold;
}
.bl-del {
  color: #c0392b;
  font-weight: bold;
}
body.dark .bl-add {
  color: #5dca6e;
}
body.dark .bl-del {
  color: #ff8a8a;
}
.bl-empty {
  padding: 16px 14px;
  text-align: center;
  color: #5a5f6b;
  font-size: 12px;
}
body.dark .bl-empty {
  color: #8aa0c4;
}
.bl-empty-sub {
  margin-top: 6px;
  font-size: 11px;
  font-style: italic;
}
.bl-hidden-hint {
  padding: 5px 10px;
  font-size: 10px;
  font-style: italic;
  color: #5a5f6b;
}

.bl-detail-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  background: var(--win-mid);
  border-bottom: 1px solid var(--win-dark);
  position: sticky;
  top: 0;
}
.bl-detail-title {
  font-weight: bold;
  font-size: 13px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bl-back {
  min-height: 0;
  padding: 1px 8px;
  font-size: 11px;
}
.bl-detail-card {
  padding: 10px;
  display: flex;
  flex-direction: column;
  gap: 9px;
}
.bl-detail-status {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 12px;
}
.bl-field {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.bl-field-label {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #5a5f6b;
}
body.dark .bl-field-label,
body.dark .bl-hidden-hint,
body.dark .bl-footer {
  color: #8aa0c4;
}
.bl-field-value {
  font-family: "Courier New", monospace;
  font-size: 12px;
  word-break: break-all;
  background: rgba(0, 0, 0, 0.05);
  padding: 3px 5px;
  border: 1px solid var(--win-dark);
}
body.dark .bl-field-value {
  background: rgba(255, 255, 255, 0.05);
}
.bl-field-hint {
  font-size: 10px;
  font-style: italic;
  color: #5a5f6b;
}
.bl-input {
  width: 100%;
}
.bl-note {
  min-height: 54px;
  resize: vertical;
}
.bl-detail-btns {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 2px;
}
.bl-btn {
  min-height: 0;
  padding: 3px 9px;
  font-size: 11px;
}
.bl-btn.primary {
  font-weight: bold;
}
.bl-btn.on {
  color: #e8b007;
}
.bl-btn.danger {
  color: #b00020;
}
body.dark .bl-btn.danger {
  color: #ff8a9c;
}

.bl-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 4px 9px;
  font-size: 10px;
  background: var(--win-gray);
  border-top: 1px solid var(--win-dark);
  color: #5a5f6b;
}
.bl-open-main {
  min-height: 0;
  padding: 1px 7px;
  font-size: 10px;
  flex: 0 0 auto;
}

.bl-toasts {
  position: fixed;
  left: 8px;
  right: 8px;
  bottom: 8px;
  display: flex;
  flex-direction: column;
  gap: 5px;
  pointer-events: none;
  z-index: 999;
}
.bl-toast {
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--win-blue);
  color: #fff;
  border: 1px solid var(--win-black);
  box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.4);
  padding: 6px 9px;
  font-size: 11px;
  animation: bl-toast-in 0.18s ease-out;
}
.bl-toast-on {
  background: #14622f;
}
.bl-toast-off {
  background: #5a5f6b;
}
.bl-toast-text {
  flex: 1;
}
.bl-toast-action {
  min-height: 0;
  padding: 0 7px;
  font-size: 10px;
}
.bl-toast-out {
  opacity: 0;
  transition: opacity 0.35s;
}
@keyframes bl-toast-in {
  from {
    transform: translateY(8px);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}
@media (prefers-reduced-motion: reduce) {
  .bl-toast {
    animation: none;
  }
}

@media (max-width: 780px) {
  body {
    padding: 6px;
  }

  .desktop {
    max-width: none;
  }

  .main-layout {
    grid-template-columns: 1fr;
  }

  .chat-panel {
    min-height: 520px;
  }

  .msg-pane {
    min-height: 300px;
  }

  .compose-grid {
    grid-template-columns: 1fr;
  }
}

/* ===========================================================================
 * Status & privacy controls (sidebar) + profile-limit chooser (modal)
 * ========================================================================= */
.custom-status {
  margin-top: 4px;
}
.home-control-grid .away-status-panel,
.home-control-grid .chat-jump-btn,
.home-control-grid .theme-panel {
  margin-top: 0;
}
.away-status-panel,
.chat-jump-btn {
  margin-top: 10px;
}
.away-status-bar,
.buddy-panel-bar,
.chat-jump-btn,
.theme-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 26px;
  padding: 3px 6px;
  list-style: none;
  cursor: pointer;
  font-size: 12px;
  background: var(--win-gray);
  border: 2px solid var(--win-black);
  box-shadow: inset 2px 2px var(--win-light), inset -2px -2px var(--win-dark);
}
.away-status-bar::-webkit-details-marker,
.buddy-panel-bar::-webkit-details-marker,
.theme-bar::-webkit-details-marker {
  display: none;
}
.away-status-bar::before,
.buddy-panel-bar::before,
.chat-jump-btn::before,
.theme-bar::before {
  content: "+";
  display: inline-grid;
  place-items: center;
  width: 14px;
  height: 14px;
  flex: 0 0 auto;
  border: 1px solid var(--win-black);
  background: #fff;
  font-weight: bold;
  line-height: 1;
}
.away-status-panel[open] .away-status-bar::before,
.buddy-panel[open] .buddy-panel-bar::before,
.theme-panel[open] .theme-bar::before {
  content: "-";
}
.away-status-label,
.buddy-panel-label,
.chat-jump-label,
.theme-bar-label {
  font-weight: bold;
  white-space: nowrap;
}
.away-status-value,
.buddy-panel-value,
.chat-jump-value,
.theme-bar-value {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: #5a5f6b;
}
.away-status-edit,
.chat-jump-edit,
.theme-bar-edit {
  flex: 0 0 auto;
  font-weight: bold;
  text-decoration: underline;
}
.chat-jump-btn {
  width: 100%;
  text-align: left;
}
.chat-jump-btn:hover,
.chat-jump-btn:focus-visible {
  outline: 1px dotted var(--win-black);
  outline-offset: -5px;
}
.away-status-controls {
  padding: 7px 0 0;
}
.theme-panel {
  margin-top: 10px;
}
.theme-controls {
  padding: 7px 0 0;
}
.theme-toggle {
  width: 100%;
}
.home-control-grid .friends-btn,
.home-control-grid .away-status-bar,
.home-control-grid .chat-jump-btn,
.home-control-grid .theme-bar {
  position: relative;
  display: grid;
  grid-template-columns: 16px minmax(0, 1fr) auto;
  grid-template-rows: auto auto;
  align-items: center;
  column-gap: 5px;
  row-gap: 0;
  min-height: 34px;
  padding: 2px 5px;
  font-size: 11px;
  line-height: 1.15;
}
.home-control-grid .friends-btn::before,
.home-control-grid .away-status-bar::before,
.home-control-grid .chat-jump-btn::before,
.home-control-grid .theme-bar::before {
  grid-column: 1;
  grid-row: 1 / 3;
  width: 13px;
  height: 13px;
}
body.dark .home-control-grid .theme-bar::after {
  content: "";
  position: absolute;
  left: 24px;
  right: 8px;
  bottom: 3px;
  height: 2px;
  background: linear-gradient(90deg, transparent, #ff1e1e 45%, #fff 50%, #ff1e1e 55%, transparent);
  filter: drop-shadow(0 0 5px #ff1e1e);
  transform: translateX(-38%) scaleX(0.32);
  transform-origin: center;
  animation: theme-laser-scan 1.45s ease-in-out infinite alternate;
  pointer-events: none;
}
.home-control-grid .friends-btn-label,
.home-control-grid .away-status-label,
.home-control-grid .chat-jump-label,
.home-control-grid .theme-bar-label {
  grid-column: 2 / 4;
  grid-row: 1;
  overflow: hidden;
  text-overflow: ellipsis;
}
.home-control-grid .away-status-label::after {
  content: " \1F44B";
  display: inline-block;
  transform-origin: 72% 76%;
  animation: away-wave 1.6s ease-in-out infinite;
}
.home-control-grid .friends-btn-value,
.home-control-grid .away-status-value,
.home-control-grid .chat-jump-value,
.home-control-grid .theme-bar-value {
  grid-column: 2;
  grid-row: 2;
}
.home-control-grid .friends-btn-edit,
.home-control-grid .away-status-edit,
.home-control-grid .chat-jump-edit,
.home-control-grid .theme-bar-edit {
  grid-column: 3;
  grid-row: 2;
}
.home-control-grid details[open] .away-status-bar,
.home-control-grid details[open] .theme-bar {
  min-height: 26px;
}
.home-control-grid details[open] .away-status-controls,
.home-control-grid details[open] .theme-controls {
  padding-top: 6px;
}
.home-control-grid .chat-jump-btn {
  grid-template-columns: 22px minmax(0, 1fr) auto;
}
.home-control-grid .chat-jump-btn::before {
  display: none;
}
/* The orb is a fixed circular "porthole": its outline never changes, so the ball
   can never read as a tilting coin. The image inside is oversized and clipped to
   this circle, so when it turns ONLY the wireframe surface moves while the
   silhouette stays perfectly round — that's what fixes the wonky look. The wrapper
   also carries the breathing red halo. */
.chat-jump-orb {
  grid-column: 1;
  grid-row: 1 / 3;
  align-self: center;
  justify-self: center;
  position: relative;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  overflow: hidden;
  background: radial-gradient(circle at 50% 45%, #2a0606, #050202);
  filter: drop-shadow(0 0 5px rgba(168, 12, 12, 0.85));
  animation: globe-omen 4.6s ease-in-out infinite;
}
/* Lit-sphere shading over the turning wireframe: a soft specular highlight up and
   to the left, darkening toward the lower-right limb. This volume cue is what
   sells "3D ball" more than the rotation alone does. */
.chat-jump-orb::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  pointer-events: none;
  background:
    radial-gradient(circle at 34% 30%, rgba(255, 214, 214, 0.5), rgba(255, 150, 150, 0) 42%),
    radial-gradient(circle at 50% 50%, rgba(0, 0, 0, 0) 52%, rgba(40, 0, 0, 0.72) 100%);
}
.chat-jump-globe {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 165%;
  height: 165%;
  object-fit: cover;
  /* Recolor the electric-blue orb to a brooding blood-red; its brightness
     "breathes" like a dormant ember (globe-ember), in step with the halo. The
     translate centers the oversized image and is also the reduced-motion resting
     transform (the turn keyframes re-state it). */
  filter: hue-rotate(150deg) saturate(1.5) brightness(0.72);
  transform: translate(-50%, -50%);
  animation: globe-turn 10s ease-in-out infinite,
             globe-ember 4.6s ease-in-out infinite;
}
@keyframes theme-laser-scan {
  from {
    transform: translateX(-38%) scaleX(0.32);
    opacity: 0.72;
  }
  to {
    transform: translateX(38%) scaleX(0.32);
    opacity: 1;
  }
}
@keyframes away-wave {
  0%, 100% { transform: rotate(0deg); }
  15% { transform: rotate(18deg); }
  30% { transform: rotate(-8deg); }
  45% { transform: rotate(15deg); }
  60% { transform: rotate(-4deg); }
}
/* The slow surface turn — the wireframe rocks +/-48deg on a vertical axis. The
   image is oversized (165%), so even at the extreme it still full-bleeds the
   circular porthole (no gap opens at the sides). Because the porthole clips it,
   the silhouette never distorts; easing makes it linger at each turn. */
@keyframes globe-turn {
  0% {
    transform: translate(-50%, -50%) perspective(200px) rotateY(-48deg);
  }
  50% {
    transform: translate(-50%, -50%) perspective(200px) rotateY(48deg);
  }
  100% {
    transform: translate(-50%, -50%) perspective(200px) rotateY(-48deg);
  }
}
/* Ember body breath — the orb glows hotter then cools (on the image). */
@keyframes globe-ember {
  0%,
  100% {
    filter: hue-rotate(150deg) saturate(1.4) brightness(0.6);
  }
  50% {
    filter: hue-rotate(166deg) saturate(2) brightness(1.02);
  }
}
/* Halo breath — the red glow swells and dims with the ember (on the wrapper). */
@keyframes globe-omen {
  0%,
  100% {
    filter: drop-shadow(0 0 4px rgba(148, 10, 10, 0.7));
  }
  50% {
    filter: drop-shadow(0 0 13px rgba(255, 26, 26, 0.95));
  }
}
@media (prefers-reduced-motion: reduce) {
  .home-control-grid .theme-bar::after,
  .home-control-grid .away-status-label::after,
  .chat-jump-orb,
  .chat-jump-globe {
    animation: none;
  }
}

/* "Code" — a full-width Pro shortcut to the Code Lab, sitting below the 2x2 grid
   so the control panel stays symmetric. Mirrors the chat tile's icon/label/value
   layout, just stretched across both columns. */
.home-control-grid .code-jump-btn {
  grid-column: auto; /* Code + GreyMESH each take one cell so they share a row */
  position: relative;
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr) auto;
  grid-template-rows: auto auto;
  align-items: center;
  column-gap: 5px;
  row-gap: 0;
  min-height: 34px;
  padding: 2px 8px;
  font-size: 11px;
  line-height: 1.15;
  text-align: left;
  cursor: pointer;
  background: var(--win-gray);
  border: 2px solid var(--win-black);
  box-shadow: inset 2px 2px var(--win-light), inset -2px -2px var(--win-dark);
}
.code-jump-btn:hover,
.code-jump-btn:focus-visible {
  outline: 1px dotted var(--win-black);
  outline-offset: -5px;
}
.code-jump-ico {
  grid-column: 1;
  grid-row: 1 / 3;
  justify-self: center;
  align-self: center;
  font: bold 12px "Courier New", monospace;
  color: #2d6a9f;
  filter: drop-shadow(0 0 3px rgba(79, 184, 255, 0.55));
}
.code-jump-label {
  grid-column: 2 / 4;
  grid-row: 1;
  font-weight: bold;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.code-jump-value {
  grid-column: 2;
  grid-row: 2;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: #5a5f6b;
}
.code-jump-edit {
  grid-column: 3;
  grid-row: 2;
  font-weight: bold;
  text-decoration: underline;
}
/* Self-contained PRO badge (independent of the Code Lab feature's own CSS). */
.ctrl-pro-tag {
  display: inline-block;
  margin-left: 5px;
  padding: 0 4px;
  font-size: 9px;
  font-weight: bold;
  letter-spacing: 0.5px;
  vertical-align: 1px;
  color: #3a2a00;
  background: linear-gradient(180deg, #ffe082, #f2b32e);
  border: 1px solid #b9851a;
  border-radius: 3px;
}
body.dark .code-jump-ico {
  color: #7fc1ff;
}
body.dark .code-jump-value {
  color: #8aa0c4;
}
/* Free-trial upsell banner shown atop the slop report after the one free scan. */
.slop-trial-banner {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
  padding: 6px 8px;
  font-size: 11px;
  color: #3a2a00;
  background: linear-gradient(180deg, #ffe9a8, #f6c244);
  border: 1px solid #b9851a;
}
.slop-trial-text {
  flex: 1 1 auto;
}
.slop-trial-go {
  flex: 0 0 auto;
  min-height: 0;
  padding: 2px 8px;
  font-weight: bold;
  cursor: pointer;
}
/* Live-collaboration bar in the Code Lab (host/join an encrypted code session). */
.codelab-collab {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-top: 8px;
  padding: 6px 8px;
  font-size: 11px;
  background: var(--win-gray);
  border: 1px solid var(--win-dark);
}
.codelab-collab-label {
  font-weight: bold;
}
.codelab-collab-enc {
  margin-left: 4px;
  padding: 0 4px;
  font-size: 9px;
  font-weight: bold;
  letter-spacing: 0.3px;
  color: #0a3a1a;
  background: #7dffb0;
  border: 1px solid #2c7a4a;
  border-radius: 3px;
}
.codelab-join-code {
  width: 84px;
  text-transform: uppercase;
}
.codelab-collab-status {
  flex: 1 1 100%;
  color: #5a5f6b;
}
body.dark .codelab-collab-status {
  color: #8aa0c4;
}
/* "Back" button on the Pro page — returns to the view an upsell interrupted. */
.pro-back-btn {
  margin: 0 0 8px;
  padding: 3px 10px;
  font-size: 12px;
  font-weight: bold;
  cursor: pointer;
}
/* Find-in-code bar (local literal search over the editor). */
.codelab-search {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-top: 8px;
}
.codelab-search-input {
  flex: 1 1 auto;
  min-width: 0;
}
.codelab-search-count {
  flex: 0 0 auto;
  min-width: 50px;
  font-size: 11px;
  color: #5a5f6b;
  text-align: right;
}
/* Compact, consistent prev / next / match-case buttons. */
.codelab-search-btn {
  flex: 0 0 auto;
  min-width: 28px;
  min-height: 0;
  height: 26px;
  padding: 0 7px;
  font-size: 12px;
  font-weight: bold;
  line-height: 1;
}
.codelab-case-btn {
  font-family: "Courier New", monospace;
}
/* Pressed = match-case ON: sunken Win98 look + a clear active highlight. */
.codelab-case-btn[aria-pressed="true"] {
  box-shadow: inset 2px 2px var(--win-dark), inset -2px -2px var(--win-light);
  background: var(--win-blue);
  color: #fff;
}
body.dark .codelab-search-count {
  color: #8aa0c4;
}
body.dark .away-status-bar::before,
body.dark .buddy-panel-bar::before,
body.dark .chat-jump-btn::before,
body.dark .theme-bar::before {
  background: #101622;
}
body.dark .away-status-value,
body.dark .buddy-panel-value,
body.dark .chat-jump-value,
body.dark .theme-bar-value {
  color: #8aa0c4;
}

/* Foldable Friends panel (mirrors the Away-message bar). */
.buddy-panel-controls {
  padding-top: 7px;
}
.buddy-panel-actions {
  display: flex;
  justify-content: flex-end;
  margin-bottom: 6px;
}

/* Home status line: your screen name shown next to the online status. */
.home-username {
  font-weight: bold;
}
.home-username:not(:empty)::after {
  content: "\00b7";
  margin-left: 6px;
  color: #5a5f6b;
  font-weight: normal;
}
body.dark .home-username:not(:empty)::after {
  color: #8aa0c4;
}
.setting-check {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 5px;
  margin: 6px 0 0;
  font-size: 12px;
  font-weight: normal;
  cursor: pointer;
}
.setting-check input[type="checkbox"] {
  width: auto;
  margin: 0;
  flex: 0 0 auto;
}
.danger-title {
  color: #8a0000;
}
.danger-zone {
  border: 1px solid #8a0000;
  background: rgba(176, 0, 32, 0.06);
  padding: 8px;
  margin-top: 4px;
}
.danger-switch {
  margin-top: 8px;
}
body.dark .danger-title {
  color: #ff8a9b;
}
body.dark .danger-zone {
  border-color: #ff8a9b;
  background: rgba(255, 138, 155, 0.08);
}
.inline-mins {
  width: auto;
  min-width: 64px;
  padding: 1px 3px;
  font-size: 11px;
}
.setting-hint {
  color: #5a5f6b;
  font-size: 11px;
}
body.dark .setting-hint {
  color: #8aa0c4;
}
.privacy-box {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 6px 8px;
  border: 1px solid var(--win-dark);
  background: rgba(0, 0, 0, 0.03);
}
body.dark .privacy-box {
  background: #161b26;
}
/* Settings "Save" row: the button with an inline "Saved" confirmation beside it. */
.settings-save-row {
  align-items: center;
}
.settings-saved-hint {
  color: #1a7a3a;
  font-weight: bold;
}
body.dark .settings-saved-hint {
  color: #5fe39a;
}

.profile-chooser {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 8px;
}
.profile-chooser-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 100%;
  text-align: left;
  padding: 6px 9px;
  font-size: 12px;
}
.profile-chooser-name {
  font-weight: bold;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.profile-chooser-act {
  color: #b00020;
  font-size: 11px;
  flex: 0 0 auto;
}
body.dark .profile-chooser-act {
  color: #ff8a9c;
}

/* ===========================================================================
 * App shell: hamburger nav drawer + section views
 * ========================================================================= */
.title-right {
  display: flex;
  align-items: center;
  gap: 8px;
}
.nav-toggle {
  min-height: 0;
  padding: 1px 9px;
  font-size: 16px;
  line-height: 20px;
  color: #fff;
  background: rgba(255, 255, 255, 0.12);
  border: 1px solid rgba(255, 255, 255, 0.55);
  box-shadow: none;
}
.nav-toggle:hover {
  background: rgba(255, 255, 255, 0.25);
  color: #fff;
}

/* Notification bell + unread badge (title bar) */
.notif-bell {
  position: relative;
  min-height: 0;
  padding: 1px 8px;
  font-size: 15px;
  line-height: 20px;
  color: #fff;
  background: rgba(255, 255, 255, 0.12);
  border: 1px solid rgba(255, 255, 255, 0.55);
  box-shadow: none;
}
.notif-bell:hover {
  background: rgba(255, 255, 255, 0.25);
  color: #fff;
}
.notif-bell.has-unread {
  animation: notif-bell-wiggle 1.4s ease-in-out 2;
}
@keyframes notif-bell-wiggle {
  0%, 100% { transform: rotate(0); }
  20% { transform: rotate(-12deg); }
  40% { transform: rotate(10deg); }
  60% { transform: rotate(-6deg); }
  80% { transform: rotate(4deg); }
}
.notif-count {
  position: absolute;
  top: -6px;
  right: -6px;
  min-width: 15px;
  height: 15px;
  padding: 0 3px;
  border-radius: 8px;
  background: #ff3030;
  border: 1px solid #fff;
  color: #fff;
  font-size: 9px;
  font-weight: bold;
  line-height: 13px;
  text-align: center;
  box-shadow: 0 0 5px rgba(255, 48, 48, 0.8);
}

/* Notification dropdown panel */
.notif-panel {
  position: absolute;
  top: 58px;
  right: 0;
  z-index: 62;
  width: 300px;
  max-width: 90%;
  max-height: 60%;
  display: flex;
  flex-direction: column;
  background: var(--win-gray);
  border: 2px solid var(--win-black);
  border-top: none;
  box-shadow: -4px 6px 14px rgba(0, 0, 0, 0.45);
}
.notif-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 5px 8px;
  background: var(--win-blue);
  color: #fff;
  border-bottom: 1px solid var(--win-black);
}
.notif-title {
  font-weight: bold;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.notif-head-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}
.notif-alerts {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  color: #fff;
  cursor: pointer;
}
.notif-alerts input {
  margin: 0;
}
.notif-clear {
  min-height: 0;
  padding: 1px 8px;
  font-size: 11px;
}
.notif-list {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 4px;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.notif-empty {
  padding: 16px 8px;
  text-align: center;
  font-size: 12px;
  color: var(--win-dark);
}
body.dark .notif-empty {
  color: #8aa0c4;
}
.notif-item {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  text-align: left;
  min-height: 0;
  padding: 7px 8px;
  font-size: 12px;
  background: var(--win-mid);
}
.notif-item.unread {
  background: #fffbe6;
  border-left: 3px solid var(--win-blue);
}
body.dark .notif-item.unread {
  background: #2a3550;
}
.notif-ico {
  flex: 0 0 auto;
  font-size: 14px;
}
.notif-text {
  flex: 1 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.notif-time {
  flex: 0 0 auto;
  font-size: 10px;
  color: var(--win-dark);
}
body.dark .notif-time {
  color: #8aa0c4;
}

.nav-drawer {
  position: absolute;
  top: 58px;
  right: 0;
  bottom: 0;
  width: 215px;
  max-width: 82%;
  z-index: 60;
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 6px;
  background: var(--win-gray);
  border-left: 2px solid var(--win-black);
  box-shadow: -5px 0 14px rgba(0, 0, 0, 0.45);
  transform: translateX(100%);
  transition: transform 0.18s ease;
  overflow-y: auto;
}
.nav-drawer.open {
  transform: translateX(0);
}
.nav-drawer-head {
  padding: 4px 6px 6px;
  margin-bottom: 3px;
  border-bottom: 1px solid var(--win-dark);
  font-weight: bold;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--win-dark);
}
body.dark .nav-drawer-head {
  color: #8aa0c4;
}
.nav-link {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  text-align: left;
  min-height: 0;
  padding: 9px 10px;
  font-size: 14px;
  background: var(--win-mid);
}
.nav-link.active {
  background: var(--win-blue);
  color: #fff;
  font-weight: bold;
}
.nav-ico {
  width: 18px;
  text-align: center;
  flex: 0 0 auto;
}
.nav-unread {
  width: 9px;
  height: 9px;
  margin-left: auto;
  border-radius: 50%;
  background: #ff5252;
  box-shadow: 0 0 5px #ff5252;
  display: none;
}
.nav-unread.on {
  display: inline-block;
}
.nav-scrim {
  position: absolute;
  top: 58px;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 55;
  background: rgba(0, 0, 0, 0.35);
}

/* Views — one visible at a time. Document-style views scroll on their own;
   the Rooms view is a flex column so the message pane scrolls and the composer
   stays pinned. */
.views {
  position: relative;
  flex: 1 1 auto;
  overflow: hidden;
}
.view {
  height: 100%;
  overflow-y: auto;
  padding: 10px;
}
.view[hidden] {
  display: none;
}
.view .section-title:first-child {
  margin-top: 0;
}
.view-rooms {
  display: flex;
  flex-direction: column;
  gap: 6px;
  overflow: hidden;
  padding: 8px;
}
.view-rooms .msg-pane {
  flex: 1 1 auto;
  min-height: 0;
}
.view-rooms .chat-tabs,
.view-rooms .chat-header,
.view-rooms .security-legend,
.view-rooms .room-invite-card,
.view-rooms .typing-indicator,
.view-rooms .compose-box,
.view-rooms .room-users-wrap {
  flex: 0 0 auto;
}
.view-rooms #roomBrowser,
.view-rooms #pubBrowser {
  flex: 1 1 auto;
  min-height: 0;
}
.view-rooms #roomChatBar,
.view-rooms #pubChatBar {
  flex: 0 0 auto;
}

.private-browser {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  gap: 8px;
  padding: 8px;
  overflow-y: auto;
}
.private-room-box {
  border: 1px solid var(--win-dark);
  box-shadow: inset 1px 1px #fff, inset -1px -1px #808080;
  padding: 9px;
}
.private-room-columns {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  align-items: start;
}
.private-room-column {
  min-width: 0;
}
.private-room-column label {
  margin-top: 0;
}

@media (prefers-reduced-motion: reduce) {
  .nav-drawer {
    transition: none;
  }
}
@media (max-width: 780px) {
  .app-shell {
    height: calc(100vh - 12px);
  }
  .menu-bar {
    display: none;
  }
  .nav-drawer,
  .nav-scrim {
    top: 31px;
  }
  /* Bigger touch targets for the public-rooms directory on small screens. */
  .pub-room {
    min-height: 44px;
    padding: 10px 12px;
    font-size: 14px;
  }
  .pub-create,
  .pub-find,
  .room-invite-card,
  .private-room-columns {
    grid-template-columns: 1fr;
  }
  .room-invite-actions {
    justify-content: flex-start;
  }
  .pub-create #pubRoomCreate,
  .pub-sort {
    width: 100%;
  }
}

/* ===========================================================================
 * Direct-message window (dm.html) + ✉ buttons
 * ========================================================================= */
body.dm-popout {
  padding: 0;
  min-height: 100vh;
  min-height: 100dvh;
  overflow: hidden;
}
.dm-window {
  display: flex;
  flex-direction: column;
  height: 100vh; /* fallback for old browsers */
  height: 100dvh; /* fit the VISIBLE viewport on mobile so the composer + Buzz/Video row aren't pushed under the browser toolbar */
  border-width: 0;
  box-shadow: none;
}
.dm-window .title-bar,
.dm-bar,
.dm-verify,
.dm-incoming,
.dm-video,
.dm-window .typing-indicator,
.dm-window .compose-box {
  flex: 0 0 auto;
}
.dm-window .sound-toggle.muted {
  opacity: 0.55;
  text-decoration: line-through;
}
.dm-bar {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 5px 9px;
  background: var(--win-mid);
  border-bottom: 1px solid var(--win-dark);
  font-size: 12px;
}
.dm-lock {
  font-size: 13px;
  flex: 0 0 auto;
}
.dm-status {
  color: #444;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
body.dark .dm-status {
  color: #b8c7e0;
}
.dm-verify {
  padding: 4px 9px;
  background: rgba(0, 128, 0, 0.08);
  border-bottom: 1px solid var(--win-dark);
}
body.dark .dm-verify {
  background: rgba(80, 209, 138, 0.08);
}
.dm-verify-line {
  font-size: 11px;
  font-weight: bold;
}
.dm-verify-line.ok {
  color: #0a6b2e;
}
.dm-verify-line.info {
  color: #245c9c;
}
.dm-verify-line.warn {
  color: #b00020;
}
body.dark .dm-verify-line.ok {
  color: #4fd18a;
}
body.dark .dm-verify-line.info {
  color: #6ad0ff;
}
body.dark .dm-verify-line.warn {
  color: #ff8a9c;
}
.dm-verify-sn {
  font-family: "Courier New", monospace;
  font-size: 10px;
  color: #555;
  word-break: break-all;
}
body.dark .dm-verify-sn {
  color: #8aa0c4;
}
.dm-verify-pqoff {
  color: #9a6a00;
  font-weight: bold;
}
body.dark .dm-verify-pqoff {
  color: #f0b542;
}
.dm-verify-btn {
  margin-top: 4px;
  font-size: 11px;
}
.dm-messages {
  flex: 1 1 auto;
  min-height: 0;
}
.dm-window.dm-ended {
  opacity: 0.7;
}

/* ---------------------------------------------------------------------------
 * 2000s-style 480p video calling in the DM window. Retro CRT vibe: a 4:3 stage,
 * scanline overlay, chunky Win98 controls, mirrored self-view.
 * ------------------------------------------------------------------------- */
.dm-incoming {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 7px 10px;
  background: #11223a;
  border-bottom: 2px solid var(--win-dark);
  color: #cdd9ec;
  font-size: 13px;
  animation: dm-ring-blink 1s steps(1, end) infinite;
}
@keyframes dm-ring-blink {
  50% { background: #1c3a63; }
}
.dm-incoming-actions {
  display: flex;
  gap: 6px;
  flex: 0 0 auto;
}
.dm-accept { color: #0a6b2a; font-weight: bold; }
.dm-decline { color: #a00000; font-weight: bold; }

.dm-video {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 8px;
  background: #000;
  border-bottom: 2px solid var(--win-dark);
}
.dm-video-stage {
  position: relative;
  width: 100%;
  max-width: 480px;
  max-height: 50dvh; /* never let the video crowd out the call controls on phones */
  margin: 0 auto;
  aspect-ratio: 4 / 3;
  background: #04060c;
  border: 2px inset var(--win-dark);
  overflow: hidden;
}
.dm-remote-video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  background: #04060c;
  filter: saturate(1.1) contrast(1.05);
}
.dm-local-video {
  position: absolute;
  right: 6px;
  bottom: 6px;
  width: 30%;
  max-width: 120px;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  background: #04060c;
  border: 1px solid #5a5f6b;
  /* Mirror is now driven by .mediafx-mirror (toggle in the A/V settings). */
}
.dm-video-stage::after { /* CRT scanlines */
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: repeating-linear-gradient(to bottom, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 2px, rgba(0, 0, 0, 0.16) 3px);
}
.dm-video-status {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  text-align: center;
  color: #9fe7c2;
  font-family: "Courier New", monospace;
  font-size: 12px;
  text-shadow: 0 0 4px rgba(0, 255, 102, 0.5);
  pointer-events: none;
}
.dm-video-controls {
  display: flex;
  gap: 6px;
  justify-content: center;
}
.dm-vc-btn.vc-off { color: #a00000; text-decoration: line-through; }
.dm-hangup { color: #a00000; font-weight: bold; }

.buddy-dm {
  margin-left: auto;
  min-height: 0;
  padding: 0 5px;
  font-size: 11px;
  line-height: 15px;
  box-shadow: none;
  border: 1px solid var(--win-dark);
  color: #2a6fb0;
}
body.dark .buddy-dm {
  color: #7fb2ff;
}
/* When the ✉ button is present it owns the right-push; keep the next button snug. */
.buddy-dm + .friend-add,
.buddy-dm + .friend-del {
  margin-left: 4px;
}
.bl-msg {
  color: #2a6fb0;
}
body.dark .bl-msg {
  color: #7fb2ff;
}

/* ===========================================================================
 * Age verification gate
 * ========================================================================= */
.age-gate {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: rgba(0, 0, 0, 0.82);
}
.age-panel {
  width: 100%;
  max-width: 360px;
  padding: 20px 18px;
  text-align: center;
  background: var(--win-gray);
  border: 2px solid var(--win-black);
  box-shadow:
    inset 2px 2px var(--win-light),
    inset -2px -2px var(--win-dark),
    6px 6px 0 rgba(0, 0, 0, 0.45);
}
.age-logo {
  display: block;
  width: 88px;
  height: 88px;
  margin: 0 auto 10px;
}
.age-title {
  font-size: 16px;
  font-weight: bold;
  margin-bottom: 8px;
}
.age-body {
  font-size: 13px;
  line-height: 1.45;
  margin-bottom: 16px;
}
.age-btns {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.age-enter {
  font-weight: bold;
  padding: 8px;
}
.age-leave {
  padding: 6px;
}

/* ===========================================================================
 * In-chat user list + public name-blur privacy
 * ========================================================================= */
.room-users-wrap {
  border: 1px solid var(--win-dark);
  background: var(--win-mid);
}
.room-users-wrap > summary {
  cursor: pointer;
  list-style: none;
  padding: 6px 9px;
  font-weight: bold;
  font-size: 12px;
}
.room-users-wrap > summary::-webkit-details-marker {
  display: none;
}
.room-users-wrap > summary::before {
  content: "\25B8 ";
  color: var(--win-dark);
}
.room-users-wrap[open] > summary::before {
  content: "\25BE ";
}
.room-users {
  max-height: 132px;
  overflow-y: auto;
  padding: 3px 8px 6px;
  background: #ffffff;
}
body.dark .room-users {
  background: #11151f;
}
.room-user {
  padding: 2px 0;
  cursor: default;
}

/* Public rooms directory (browse / search / create) */
.pub-browser {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 8px;
  min-height: 0;
}
.pub-create {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 6px;
  align-items: center;
}
.pub-create #pubRoomCreate {
  width: auto;
  white-space: nowrap;
  padding-left: 14px;
  padding-right: 14px;
}
.pub-find {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 6px;
  align-items: center;
}
.pub-search {
  width: 100%;
}
.pub-sort {
  width: auto;
  flex: 0 0 auto;
}
.pub-note {
  font-size: 11px;
  color: #b00020;
  padding: 1px 2px;
}
body.dark .pub-note {
  color: #ff8a9b;
}

.pub-empty-cta {
  border: 2px inset var(--win-mid);
  background: #f7f7f7;
  color: #333;
  padding: 9px 10px;
  font-size: 12px;
  line-height: 1.35;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.pub-empty-cta strong {
  font-size: 12px;
}
.pub-empty-cta.loading strong::before {
  content: "\25D4 ";
  color: #1084d0;
}
.pub-empty-cta.empty strong::before {
  content: "\2191 ";
  color: #1084d0;
}
.pub-empty-cta.error strong::before {
  content: "! ";
  color: #b00020;
}
body.dark .pub-empty-cta {
  background: #11151f;
  color: #cbd8ee;
}

/* Activity dot on each directory row: green pulse when a room is live. */
.pub-dot {
  flex: 0 0 auto;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #9a9a9a;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.35);
}
.pub-dot.active {
  background: #2ecc40;
  animation: pubPulse 1.6s ease-in-out infinite;
}
.pub-dot.unread {
  background: #ff2d2d;
  box-shadow: 0 0 6px rgba(255, 45, 45, 0.9), inset 0 0 0 1px #7a0000;
  animation: pubUnreadBlink 0.8s steps(1) infinite;
}
.pub-room.unread {
  outline: 1px dotted #b00020;
  outline-offset: -3px;
}
@keyframes pubPulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.45; }
}
@keyframes pubUnreadBlink {
  50% {
    background: #ffff66;
    box-shadow: 0 0 6px rgba(255, 255, 102, 0.9), inset 0 0 0 1px #8a7a00;
  }
}
.pub-new-chip {
  flex: 0 0 auto;
  font-size: 10px;
  font-weight: bold;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  padding: 1px 5px;
  color: #0c447c;
  background: #b5d4f4;
  border: 1px solid #378add;
}
body.dark .pub-new-chip {
  color: #e6f1fb;
  background: #0c447c;
  border-color: #378add;
}

.pub-room-list {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.pub-room {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  text-align: left;
  padding: 7px 10px;
  font-size: 13px;
}
.pub-room-name {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: bold;
}
.pub-room-count {
  flex: 0 0 auto;
  color: #5a5f6b;
  font-size: 11px;
}
body.dark .pub-room-count {
  color: #8aa0c4;
}
.pub-room-go {
  flex: 0 0 auto;
  font-size: 11px;
  font-weight: bold;
  color: #1084d0;
}
body.dark .pub-room-go {
  color: #5aa9ff;
}

/* Bar shown while inside a public room */
.pub-chat-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 5px 8px;
  font-size: 11px;
  color: #5a5f6b;
  border-bottom: 1px solid rgba(0, 0, 0, 0.25);
}
body.dark .pub-chat-bar {
  color: #8aa0c4;
  border-bottom-color: rgba(255, 255, 255, 0.12);
}
.pub-back {
  flex: 0 0 auto;
  width: auto;
  min-height: 0;
  padding: 2px 10px;
  font-size: 12px;
}

/* A name set "private" in public chat: an unreadable smudge in its own color. */
.name-blur {
  filter: blur(4.5px);
  -webkit-user-select: none;
  user-select: none;
  cursor: default;
}

/* ===========================================================================
 * GreyNOC Pro (Stripe) — pricing card, nav badge, gated affordances
 * ========================================================================= */
.nav-pro {
  font-weight: bold;
}
.nav-pro-dot {
  margin-left: 6px;
  font-size: 10px;
  font-weight: bold;
  letter-spacing: 0.5px;
  padding: 1px 5px;
  color: #412402;
  background: #fac775;
  border: 1px solid #ba7517;
}

.pro-card {
  border: 2px solid var(--win-dark, #808080);
  background: var(--win-mid, #c0c0c0);
  padding: 14px;
  margin-top: 6px;
}
body.dark .pro-card {
  background: #1a2233;
  border-color: #3a4a66;
}
.pro-head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 10px;
}
.pro-star {
  font-size: 30px;
  line-height: 1;
  color: #e0a915;
}
.pro-title {
  font-size: 16px;
  font-weight: bold;
}
.pro-price {
  font-size: 13px;
  color: #1084d0;
  font-weight: bold;
}
body.dark .pro-price {
  color: #5aa9ff;
}
.pro-perks {
  list-style: none;
  margin: 0 0 12px;
  padding: 0;
}
.pro-perks li {
  padding: 5px 0 5px 22px;
  position: relative;
  font-size: 13px;
  border-bottom: 1px dotted rgba(0, 0, 0, 0.2);
}
body.dark .pro-perks li {
  border-bottom-color: rgba(255, 255, 255, 0.12);
}
.pro-perks li::before {
  content: "\2714";
  position: absolute;
  left: 2px;
  color: #1d9e75;
  font-weight: bold;
}
.pro-was {
  color: #5a5f6b;
  font-size: 11px;
}
body.dark .pro-was {
  color: #8aa0c4;
}
.pro-note {
  font-size: 12px;
  color: #b00020;
  margin: 4px 0;
  padding: 6px 8px;
  border: 1px solid #b00020;
  background: rgba(176, 0, 32, 0.07);
}
.pro-note.ok {
  color: #0f6e56;
  border-color: #0f6e56;
  background: rgba(29, 158, 117, 0.1);
}
body.dark .pro-note {
  color: #ff8a9b;
  border-color: #ff8a9b;
}
body.dark .pro-note.ok {
  color: #5dcaa5;
  border-color: #5dcaa5;
}
.pro-go {
  width: 100%;
  font-weight: bold;
  padding: 8px;
  font-size: 14px;
}
.pro-current {
  margin-top: 8px;
  font-size: 13px;
  font-weight: bold;
  color: #0f6e56;
  text-align: center;
}
body.dark .pro-current {
  color: #5dcaa5;
}
.pro-code-output {
  margin-top: 8px;
  padding: 7px 8px;
  font-family: "Courier New", monospace;
  font-size: 12px;
  line-height: 1.35;
  overflow-wrap: anywhere;
  border: 1px inset #ffffff;
  background: #ffffff;
  color: #111111;
}
body.dark .pro-code-output {
  border-color: #3a4a66;
  background: #101622;
  color: #d8e4ff;
}
.pro-restore {
  margin-top: 10px;
  font-size: 12px;
  color: #5a5f6b;
}
body.dark .pro-restore {
  color: #8aa0c4;
}
.linklike {
  width: auto;
  min-height: 0;
  padding: 0;
  border: 0;
  background: none;
  box-shadow: none;
  color: #1084d0;
  text-decoration: underline;
  cursor: pointer;
  font-size: 12px;
}
body.dark .linklike {
  color: #5aa9ff;
}
.pro-restore-box {
  margin-top: 8px;
}
.pro-restore-box label {
  display: block;
  font-size: 11px;
  margin-bottom: 3px;
}
.pro-fineprint {
  margin-top: 12px;
}
/* Free members: the File button reads as locked. */
body:not(.is-pro) #attachButton {
  opacity: 0.6;
}

/* ===========================================================================
 * Blocking — per-row block button + the Settings management list
 * ========================================================================= */
.room-user {
  position: relative;
}
.user-block {
  margin-left: auto;
  flex: 0 0 auto;
  width: auto;
  min-height: 0;
  padding: 0 4px;
  font-size: 11px;
  line-height: 1.4;
  opacity: 0.55;
}
.user-block:hover {
  opacity: 1;
}
.blocked-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 6px 0;
}
.blocked-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 8px;
  border: 1px solid var(--win-dark, #808080);
  background: var(--win-light, #fff);
  font-size: 13px;
}
body.dark .blocked-row {
  background: #16203022;
  border-color: #3a4a66;
}
.blocked-name {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.blocked-fp {
  flex: 0 0 auto;
  font-family: var(--mono, monospace);
  font-size: 11px;
  color: #5a5f6b;
}
body.dark .blocked-fp {
  color: #8aa0c4;
}
.blocked-unblock {
  flex: 0 0 auto;
  width: auto;
  min-height: 0;
  padding: 2px 10px;
  font-size: 11px;
}

/* ===========================================================================
 * Home dashboard rework — a Win98 control console (left) + buddy list (right).
 * One column on phones; two panes on desktop so nothing stretches awkwardly
 * across the now full-width window. Footer pins to the bottom.
 * ========================================================================= */
#view-home {
  padding: 14px;
}
.home-grid {
  display: grid;
  gap: 12px;
}
.home-console > *:first-child {
  margin-top: 0;
}

/* Tidy section headers on Home: a clear Win98 group label. */
#view-home .section-title {
  font-size: 13px;
  margin: 14px 0 7px;
  padding-bottom: 4px;
  border-bottom: 1px solid var(--win-dark);
}

/* Brand box: keep the compact strip on desktop too, just a touch taller. */
.brand-box {
  padding: 8px 14px;
}
.brand-logo {
  height: 42px;
}
.brand-subtitle {
  font-size: 13px;
  letter-spacing: 1px;
}

/* Friend rows: roomier + easier to read/tap. */
#view-home .buddy {
  padding: 5px 6px;
  font-size: 13px;
}
.home-social .buddy-list {
  min-height: 280px;
}

@media (min-width: 821px) {
  /* Fill the window height so the footer pins to the bottom (no teal void). */
  #view-home {
    max-width: 1400px;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
  }
  /* Three panes: status console (left), the live feed front-and-center, and the
     buddy list (right). The feed is the widest, flexible column. */
  .home-grid {
    flex: 1 1 auto;
    min-height: 0;
    grid-template-columns: 290px minmax(0, 1fr) 320px;
    grid-template-rows: 1fr;
    grid-template-areas: "console feed social";
    gap: 16px;
    align-items: stretch;
  }
  .home-console {
    grid-area: console;
    align-self: start; /* control panel sizes to its content */
  }
  .home-feed {
    grid-area: feed;
    min-height: 0;
  }
  /* The timeline fills the center pane and scrolls; the composer stays pinned. */
  .home-feed .feed-list {
    flex: 1 1 auto;
    height: auto; /* fill the pane rather than the fixed mobile height */
    min-height: 0;
    overflow-y: auto;
  }
  .home-social {
    grid-area: social;
    display: flex;
    flex-direction: column;
    min-height: 0;
  }
  /* The foldable Friends panel fills the right pane when open so the buddy list
     can scroll; when folded it shrinks and the feed reclaims the column. */
  .home-social .buddy-panel {
    display: flex;
    flex-direction: column;
    min-height: 0;
  }
  .home-social .buddy-panel[open] {
    flex: 1 1 auto;
  }
  .home-social .buddy-panel-controls {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
  }
  /* The buddy list fills the taller right pane; each expanded group scrolls. */
  .home-social .buddy-list {
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden;
  }
  .home-social .buddy-section-body {
    max-height: none;
  }
  .home-grid:has(#buddyPanel:not([open])) {
    grid-template-columns: 290px minmax(0, 1fr) max-content;
  }
}

/* ===========================================================================
 * Consistent view widths on desktop — center every view at a comfortable max
 * so nothing stretches edge-to-edge on the full-width window (matches Home).
 * Phones keep the full width (this only kicks in above the mobile breakpoint).
 * ========================================================================= */
@media (min-width: 821px) {
  /* Primary view matches the Home dashboard width. */
  #view-rooms {
    max-width: 1080px;
    margin: 0 auto;
  }
  /* Forms + reading views sit in a narrower, more legible centered column. */
  #view-profile,
  #view-settings,
  #view-pro,
  #view-help {
    max-width: 720px;
    margin: 0 auto;
  }
}

/* ===========================================================================
 * Custom "420" emojis (joint / leaf / bong / puffco / cloud) + composer picker
 * ========================================================================= */
.cmoji {
  width: 1.3em;
  height: 1.3em;
  vertical-align: -0.28em;
  margin: 0 1px;
}
.emoji-wrap {
  position: relative;
  display: inline-flex;
}
.emoji-btn {
  min-height: 30px;
  padding: 5px 9px;
  line-height: 1;
}
.emoji-palette {
  position: absolute;
  bottom: calc(100% + 4px);
  right: 0;
  z-index: 30;
  width: 290px;
  max-width: calc(100vw - 24px);
  max-height: 300px;
  overflow-y: auto;
  padding: 5px 6px;
  background: var(--win-gray);
  border: 2px solid var(--win-black);
  box-shadow: inset 2px 2px var(--win-light), inset -2px -2px var(--win-dark), 3px 3px 0 rgba(0, 0, 0, 0.35);
}
.emoji-cat {
  font-size: 10px;
  font-weight: bold;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--win-dark);
  margin: 7px 2px 3px;
}
.emoji-cat:first-child {
  margin-top: 1px;
}
.emoji-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 1px;
}
.emoji-opt {
  min-height: 0;
  padding: 2px;
  font-size: 18px;
  line-height: 1.15;
  background: transparent;
  border: 1px solid transparent;
  box-shadow: none;
}
.emoji-opt:hover {
  background: var(--win-blue);
  border-color: var(--win-black);
}
.emoji-opt:active {
  transform: none;
  box-shadow: none;
}
.emoji-opt .cmoji {
  width: 20px;
  height: 20px;
  vertical-align: middle;
  margin: 0;
}

/* ===========================================================================
 * Code Lab + GN Slop Detector (Pro). An intentionally dark "terminal" surface
 * that reads as an IDE in both day and night themes. No inline styles: the
 * score meter colors itself from a stylesheet-set --lvl custom property.
 * ========================================================================= */
.codelab-pro-tag,
.nav-pro-static {
  display: inline-block;
  background: linear-gradient(180deg, #ffe082, #f2b32e);
  color: #3a2a00;
  font-size: 10px;
  font-weight: bold;
  letter-spacing: 0.5px;
  padding: 1px 5px;
  border-radius: 3px;
  border: 1px solid #b9851a;
  vertical-align: middle;
}
.codelab-pro-tag {
  margin-left: 6px;
}

.codelab {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 8px;
}

/* The toolbar, collaborate box, and find bar. Stacked on mobile; on desktop they
   flow onto one wrapping row (below) to save vertical space. */
.codelab-controls {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.codelab-controls > * {
  margin-top: 0; /* the container gap owns the spacing now */
}
@media (min-width: 1500px) {
  /* One row: nowrap forces the toolbar, collaborate box, and find bar to share a
     line and shrink to fit (their status text truncates) instead of wrapping.
     Below 1500px there isn't room for all of it plus a usable find box, so the
     controls stay stacked. */
  .codelab-controls {
    flex-direction: row;
    flex-wrap: nowrap;
    align-items: center;
    column-gap: 8px;
  }
  /* Each control bar stays single-line and shrinks via its status text. */
  .codelab-controls .codelab-toolbar,
  .codelab-controls .codelab-collab {
    flex: 0 1 auto;
    flex-wrap: nowrap;
    min-width: 0;
  }
  .codelab-controls .codelab-search {
    flex: 1 1 170px;
    min-width: 150px;
  }
  /* Compact Lang select (override the global width:100%) + inline label. */
  .codelab-controls .codelab-lang {
    width: auto;
  }
  .codelab-controls .codelab-lang-label {
    margin: 0;
  }
  /* Status lines ride the row but truncate rather than shove the find bar off it. */
  .codelab-controls .codelab-stat,
  .codelab-controls .codelab-collab-status {
    flex: 0 1 auto;
    min-width: 0;
    max-width: 120px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .codelab-controls .codelab-stat {
    margin-left: 6px;
  }
}

/* Phones: roomier, touch-friendly Code Lab controls instead of desktop-density
   rows. Each control bar's items get ~42px tall targets and breathe; the lang
   select, stat line, collab label, and status take their own full-width rows. */
@media (max-width: 600px) {
  .codelab-controls {
    gap: 12px;
  }
  .codelab-controls .codelab-toolbar {
    gap: 8px;
  }
  .codelab-controls .codelab-lang {
    flex: 1 1 100%;
    min-height: 40px;
  }
  .codelab-controls .codelab-analyze,
  .codelab-controls .codelab-toolbar .inline-btn {
    flex: 1 1 auto;
    min-height: 42px;
    padding: 8px 12px;
    font-size: 13px;
  }
  .codelab-controls .codelab-stat {
    flex: 1 1 100%;
    margin-left: 0;
    font-size: 12px;
  }
  .codelab-controls .codelab-collab {
    gap: 8px;
    padding: 10px;
  }
  .codelab-controls .codelab-collab-label {
    flex: 1 1 100%;
  }
  .codelab-controls .codelab-collab .inline-btn {
    flex: 1 1 40%;
    min-height: 42px;
    padding: 8px 12px;
    font-size: 13px;
  }
  .codelab-controls .codelab-join-code {
    flex: 1 1 40%;
    width: auto;
    min-height: 42px;
    font-size: 13px;
    text-align: center;
  }
  .codelab-controls .codelab-collab-status {
    flex: 1 1 100%;
  }
  .codelab-controls .codelab-search {
    gap: 6px;
  }
  .codelab-controls .codelab-search-input {
    min-height: 42px;
    font-size: 13px;
  }
  .codelab-controls .codelab-search-btn {
    min-width: 44px;
    height: 42px;
    font-size: 16px;
  }
  .codelab-controls .codelab-search-count {
    font-size: 12px;
  }
}

.codelab-toolbar {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}
.codelab-lang-label {
  font-weight: bold;
  font-size: 12px;
}
.codelab-lang {
  font-size: 12px;
}
.codelab-analyze {
  font-weight: bold;
}
.codelab-stat {
  font-size: 11px;
  color: var(--win-dark);
  margin-left: auto;
}
body.dark .codelab-stat {
  color: #9fb3d6;
}

/* ---- multi-party video: collaborator picker + the in-Code-Lab stream grid -- */
.codelab-video-picker {
  margin-top: 8px;
  padding: 8px;
  background: var(--win-gray);
  border: 2px solid var(--win-black);
  box-shadow: inset 2px 2px var(--win-light), inset -2px -2px var(--win-dark);
}
.cv-picker-head {
  font-weight: bold;
  font-size: 12px;
  margin-bottom: 6px;
}
.cv-picker-row {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  padding: 2px 0;
}
.cv-picker-row input {
  width: auto;
}
.cv-picker-actions {
  display: flex;
  gap: 6px;
  margin-top: 8px;
}
.codelab-video {
  margin-top: 8px;
  border: 2px inset var(--win-dark);
  background: #0b0f14;
  padding: 6px;
}
.codelab-video-bar {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 6px;
  font-size: 11px;
  color: #cdd9e5;
}
.codelab-video-title {
  font-weight: bold;
}
.codelab-video-count {
  color: #9fb3d6;
}
.codelab-video-bar .inline-btn {
  margin-left: 0;
}
.codelab-video-bar .inline-btn:last-child {
  margin-left: auto;
}
/* A tight, auto-filling grid of participant tiles. */
.codelab-video-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 6px;
}
.cv-tile {
  position: relative;
  aspect-ratio: 4 / 3;
  background: #05080c;
  border: 1px solid #1e2730;
  overflow: hidden;
}
.cv-tile video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  background: #05080c;
}
/* .cv-local mirror is driven by .mediafx-mirror (A/V settings toggle). */
/* Mirror the self-preview (display only; the transmitted canvas is never flipped).
   Default-on via prefs; toggled in the A/V settings panel. */
.mediafx-mirror {
  transform: scaleX(-1) !important;
}
.cv-name {
  position: absolute;
  left: 4px;
  bottom: 4px;
  padding: 1px 5px;
  font-size: 10px;
  color: #fff;
  background: rgba(0, 0, 0, 0.6);
  border-radius: 2px;
}

/* ===== Human gate — first-entry "prove you're human" checkpoint ============== */
.humangate {
  position: fixed;
  inset: 0;
  z-index: 100000; /* above everything, incl. onboarding dialogs */
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: rgba(2, 6, 12, 0.86);
}
.humangate-done {
  opacity: 0;
  transition: opacity 0.2s ease;
}
.humangate-panel {
  width: min(320px, calc(100vw - 24px));
  padding: 14px;
  text-align: center;
  background: var(--win-gray);
  color: var(--win-black);
  border: 2px solid var(--win-light);
  border-right-color: var(--win-dark);
  border-bottom-color: var(--win-dark);
  box-shadow: 4px 4px 0 rgba(0, 0, 0, 0.5);
}
.humangate-title {
  font-weight: bold;
  font-size: 14px;
  margin-bottom: 4px;
}
.humangate-sub {
  font-size: 12px;
  color: #4a4f5b;
  margin-bottom: 10px;
}
body.dark .humangate-sub {
  color: #9fb2d0;
}
.humangate-canvas {
  width: 220px;
  max-width: 100%;
  height: 70px;
  image-rendering: pixelated;
  border: 2px inset var(--win-dark);
  background: #0b0f14;
}
.humangate-math {
  margin: 6px 0;
  font-size: 18px;
  font-weight: bold;
}
.humangate-prompt {
  display: block;
  margin: 8px 0 4px;
  font-size: 12px;
  font-weight: bold;
}
.humangate-input {
  width: 100%;
  text-align: center;
  font-size: 16px;
  letter-spacing: 2px;
  text-transform: uppercase;
}
.humangate-msg {
  min-height: 16px;
  margin: 6px 0;
  font-size: 12px;
  font-weight: bold;
  color: #b00000;
}
body.dark .humangate-msg {
  color: #ff8a8a;
}
.humangate-row {
  display: flex;
  gap: 6px;
}
.humangate-btn {
  flex: 1 1 auto;
  padding: 5px;
  font-weight: bold;
  cursor: pointer;
}
.humangate-go {
  flex: 2 1 auto;
}
.humangate-alt {
  margin-top: 10px;
  padding: 2px;
  width: 100%;
  font-size: 11px;
  text-decoration: underline;
  color: #1f6fd6;
  background: none;
  border: 0;
  cursor: pointer;
}
body.dark .humangate-alt {
  color: #6fb4ff;
}
.humangate-shake {
  animation: humangate-shake 0.3s ease;
}
@keyframes humangate-shake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-7px); }
  40% { transform: translateX(7px); }
  60% { transform: translateX(-5px); }
  80% { transform: translateX(5px); }
}
@media (prefers-reduced-motion: reduce) {
  .humangate-shake { animation: none; }
}

/* ===== Media FX — A/V settings + fun-overlay picker (shared: DM + Code Lab) ==== */
.mediafx-modal {
  position: fixed;
  inset: 0;
  z-index: 9000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 12px;
  background: rgba(0, 0, 0, 0.5);
}
.mediafx-modal[hidden] {
  display: none;
}
.mediafx-panel {
  width: min(340px, calc(100vw - 24px));
  max-height: calc(100vh - 24px);
  overflow: auto;
  padding: 10px;
  background: var(--win-gray);
  color: var(--win-black);
  border: 2px solid var(--win-light);
  border-right-color: var(--win-dark);
  border-bottom-color: var(--win-dark);
  box-shadow: 3px 3px 0 rgba(0, 0, 0, 0.45);
}
.mediafx-title {
  margin-bottom: 8px;
  padding-bottom: 4px;
  font-weight: bold;
  font-size: 13px;
  border-bottom: 1px solid var(--win-dark);
}
.mediafx-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
  font-size: 12px;
}
.mediafx-row > span {
  flex: 0 0 78px;
  font-weight: bold;
}
.mediafx-select {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 12px;
}
.mediafx-note {
  margin: 2px 0 8px;
  font-size: 10px;
  color: #5a5f6b;
}
body.dark .mediafx-note {
  color: #8aa0c4;
}
.mediafx-check {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 10px;
  font-size: 12px;
  cursor: pointer;
}
.mediafx-subhead {
  margin: 4px 0 6px;
  font-weight: bold;
  font-size: 12px;
}
.mediafx-fx-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
  margin-bottom: 10px;
}
.mediafx-fx-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 6px 2px;
  font-size: 10px;
  cursor: pointer;
  background: var(--win-gray);
  border: 2px solid var(--win-black);
  box-shadow: inset 1px 1px var(--win-light), inset -1px -1px var(--win-dark);
}
.mediafx-fx-btn.on {
  background: #d7e3ff;
  box-shadow: inset 1px 1px var(--win-dark), inset -1px -1px var(--win-light);
}
body.dark .mediafx-fx-btn.on {
  background: #2a3650;
}
.mediafx-fx-emoji {
  font-size: 20px;
  line-height: 1;
}
.mediafx-fx-label {
  font-weight: bold;
}
.mediafx-close {
  width: 100%;
  padding: 5px;
  font-weight: bold;
}

/* Editor: line-number gutter + textarea, kept metric-identical so rows align. */
.codelab-editor {
  display: flex;
  height: clamp(240px, 44vh, 560px);
  border: 2px inset var(--win-dark);
  background: #0b0f14;
  overflow: hidden;
}
.code-gutter {
  flex: 0 0 auto;
  width: 44px;
  padding: 6px 6px 6px 0;
  overflow: hidden;
  text-align: right;
  background: #11161d;
  border-right: 1px solid #1e2730;
  color: #56697d;
  font: 13px/18px "Consolas", "Courier New", monospace;
  user-select: none;
}
.code-gutter-cell {
  height: 18px;
  line-height: 18px;
}
.code-gutter-cell.has-finding {
  color: #ffcf5a;
  font-weight: bold;
}
.code-gutter-cell.has-finding::before {
  content: "\25B8"; /* ▸ marker */
  margin-right: 3px;
}
/* Find-in-code: highlight every line number whose line holds a match (cyan,
   distinct from the amber scan-finding marker). */
.code-gutter-cell.search-line {
  background: rgba(79, 209, 255, 0.28);
  color: #d6f2ff;
  font-weight: bold;
}
.code-area {
  flex: 1 1 auto;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 6px 8px;
  border: 0;
  resize: none;
  background: #0b0f14;
  color: #c8e8d0;
  caret-color: var(--terminal-green);
  font: 13px/18px "Consolas", "Courier New", monospace;
  white-space: pre;
  overflow: auto;
  tab-size: 2;
}
.code-area::placeholder {
  color: #4d6175;
}
/* Keep the editor dark on focus in BOTH themes — the global input/textarea
   focus rule flips fields to pale cream (#ffffe8) in light theme, which would
   leave the light-green code unreadable. The IDE is always a dark surface. */
.code-area:focus {
  outline: none;
  background: #0b0f14;
}
body.dark .code-area:focus {
  background: #0b0f14;
}

/* Report: score gauge + diagnostics list. */
.codelab-report {
  border: 2px inset var(--win-dark);
  background: #0e1319;
  color: #cdd9e5;
  padding: 8px;
}

/* ===== Drag + resize: movable/resizable result boxes & canvases ============== */
.dr-enabled {
  position: relative;
  padding-top: 20px !important; /* room for the drag strip above existing content */
}
.dr-enabled::before {
  content: "\2823 drag \00B7 \2198 resize"; /* ⠣ drag · ↘ resize */
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 18px;
  padding: 0 6px;
  font: 10px/18px "Consolas", "Courier New", monospace;
  color: #8aa0c4;
  background: rgba(127, 170, 255, 0.14);
  border-bottom: 1px solid rgba(127, 170, 255, 0.2);
  white-space: nowrap;
  overflow: hidden;
  pointer-events: none; /* visual cue only — JS handles the drag on the element */
  cursor: move;
}
.dr-enabled.dr-dragging {
  user-select: none;
  opacity: 0.97;
}

/* Full-width bottom-edge resize handle (dragresize edgeResize). A grab strip that
   spans the whole bottom of a docked panel — drag anywhere along it to size up/down,
   double-click to reset — instead of hunting for a tiny corner. It's a sibling of
   the panel, so it auto-hides whenever that panel is [hidden]. */
.dr-edge {
  height: 12px;
  margin-top: -1px; /* hug the panel above */
  display: flex;
  align-items: center;
  justify-content: center;
  background: #11161d;
  border: 1px solid #1e2730;
  border-top: 0;
  cursor: ns-resize;
  touch-action: none; /* pointer drag, not scroll, on touch */
}
.dr-edge::before {
  content: "";
  width: 46px;
  height: 4px;
  border-top: 2px solid #3a4756;
  border-bottom: 2px solid #3a4756;
}
.dr-edge:hover { background: #18202b; }
.dr-edge.dr-edge-active { background: #1d2735; }
.dr-edge:hover::before,
.dr-edge.dr-edge-active::before { border-color: #4fb8ff; }
[hidden] + .dr-edge { display: none !important; } /* hide when the panel above is hidden */

/* BB live hint — appears under the editor ONLY when the code would break / fail CI. */
.bb-hint {
  display: flex;
  align-items: center;
  gap: 7px;
  margin-top: 6px;
  padding: 5px 8px;
  font: 12px/1.4 "Consolas", "Courier New", monospace;
  color: #ffd9a8;
  background: #1a1206;
  border: 1px solid #5a3d12;
  border-left: 3px solid #ffcf5a;
  cursor: pointer;
}
.bb-hint[hidden] {
  display: none;
}
.bb-hint:hover {
  background: #241a0a;
}
.bb-hint-globe {
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  object-fit: cover;
}
.bb-hint-text {
  flex: 1 1 auto;
  min-width: 0;
}

/* ===== BB — the CI bot's pipeline report (terminal vibe; always dark) ======== */
.bb-report {
  margin-top: 6px;
  padding: 8px;
  background: #0b0f14;
  color: #cdd9e5;
  border: 2px inset var(--win-dark);
  font: 12px/1.5 "Consolas", "Courier New", monospace;
}
.bb-report[hidden] {
  display: none;
}
.bb-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
  padding-bottom: 6px;
  border-bottom: 1px solid #1e2730;
}
.bb-avatar {
  width: 24px;
  height: 24px;
  flex: 0 0 auto;
  border-radius: 50%;
  object-fit: cover;
  vertical-align: -6px;
  filter: drop-shadow(0 0 4px rgba(79, 184, 255, 0.6));
}
.bb-btn-globe {
  width: 15px;
  height: 15px;
  border-radius: 50%;
  object-fit: cover;
  vertical-align: -3px;
  margin-right: 2px;
}
.bb-title {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}
.bb-name {
  font-weight: bold;
  letter-spacing: 0.5px;
  color: #aef9c6;
}
.bb-verdict {
  color: #8aa0c4;
}
.bb-report.bb-failed .bb-verdict {
  color: #ff8a8a;
}
.bb-stage {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 2px 0;
}
.bb-stage-idx {
  flex: 0 0 auto;
  color: #56697d;
}
.bb-stage-name {
  flex: 0 0 auto;
  min-width: 92px;
}
.bb-stage-icon {
  flex: 0 0 auto;
  font-weight: bold;
}
.bb-stage-note {
  flex: 1 1 auto;
  min-width: 0;
  color: #8aa0c4;
}
.bb-pass .bb-stage-icon { color: #39ff8a; }
.bb-warn .bb-stage-icon { color: #ffcf5a; }
.bb-fail .bb-stage-icon { color: #ff5a5a; }
.bb-fail .bb-stage-name { color: #ff9a9a; }
.bb-find {
  display: flex;
  gap: 8px;
  width: calc(100% - 18px);
  margin: 1px 0 1px 18px;
  padding: 2px 6px;
  text-align: left;
  color: #cdd9e5;
  background: rgba(255, 255, 255, 0.03);
  border: 0;
  border-left: 3px solid #56697d;
  font: inherit;
  cursor: pointer;
}
.bb-find:hover,
.bb-find:focus-visible {
  background: rgba(79, 209, 255, 0.14);
  outline: none;
}
.bb-sev-high { border-left-color: #ff5a5a; }
.bb-sev-med { border-left-color: #ffcf5a; }
.bb-sev-low { border-left-color: #56697d; }
.bb-find-line {
  flex: 0 0 auto;
  color: #56697d;
  font-weight: bold;
}
.bb-find-msg {
  flex: 1 1 auto;
  min-width: 0;
}
/* BB live scan: the "● live" badge, the slop summary row, and the free upsell. */
.bb-live {
  margin-left: auto;
  flex: 0 0 auto;
  color: #39ff8a;
  font-size: 11px;
  letter-spacing: 0.5px;
  animation: bb-live-pulse 1.6s ease-in-out infinite;
}
@keyframes bb-live-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } }
@media (prefers-reduced-motion: reduce) { .bb-live { animation: none; } }
.bb-slop {
  --lvl: #8a98a6;
  margin-top: 4px;
  padding-top: 6px;
  border-top: 1px solid #1e2730;
}
.bb-slop.lvl-clean { --lvl: #35d07f; }
.bb-slop.lvl-low { --lvl: #8bd450; }
.bb-slop.lvl-med { --lvl: #ffb454; }
.bb-slop.lvl-high { --lvl: #ff8a3d; }
.bb-slop.lvl-heavy { --lvl: #ff5c5c; }
.bb-slop .bb-stage-name { color: var(--lvl); }
.bb-slop-score {
  flex: 0 0 auto;
  font-weight: bold;
  color: var(--lvl);
}
.bb-upsell {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
  padding: 6px 9px;
  background: rgba(255, 207, 90, 0.08);
  border: 1px solid #5a4a12;
  border-left: 3px solid #ffcf5a;
}
.bb-upsell-text {
  flex: 1 1 auto;
  min-width: 0;
  color: #ffe1b0;
}
.bb-upsell-go {
  flex: 0 0 auto;
  padding: 2px 10px;
  background: linear-gradient(#ffcf5a, #e0a92e);
  color: #1a1206;
  font-weight: bold;
  border: 1px solid #b9881f;
  border-radius: 3px;
  cursor: pointer;
}
.bb-upsell-go:hover { background: linear-gradient(#ffd97a, #eab63c); }

/* ===== GreyIQ fix suggestions — inline 💡 + a click-to-swap card =============
   BB flags a line; GreyIQ (greyiq.js) suggests the swap. A lightbulb sits at the
   flagged line inside the editor; clicking it opens a card with before→after
   diffs (the diff view is reused from GreyNOC/GreyIQ) you can apply in one click.
   The editor is the positioning context; bulbs/card are placed via CSSOM .style
   (allowed under the strict CSP — only string-parsed styles are blocked). */
.codelab-editor { position: relative; }
.bb-fix-layer {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none; /* clicks fall through to the textarea… */
  z-index: 4;
}
.bb-fix-layer > * { pointer-events: auto; } /* …except the bulbs and the card */
.bb-fix-bulb {
  position: absolute;
  width: 20px;
  height: 18px;
  padding: 0;
  font-size: 12px;
  line-height: 18px;
  text-align: center;
  background: transparent;
  border: 0;
  cursor: pointer;
  opacity: 0.6;
  filter: grayscale(0.5);
}
.bb-fix-bulb:hover { opacity: 1; filter: none; transform: scale(1.15); }
.bb-fix-bulb.has-swap {
  opacity: 0.95;
  filter: none;
  animation: bb-bulb-pulse 1.8s ease-in-out infinite;
}
@keyframes bb-bulb-pulse { 0%, 100% { opacity: 0.95; } 50% { opacity: 0.45; } }
@media (prefers-reduced-motion: reduce) { .bb-fix-bulb.has-swap { animation: none; } }
.bb-hidden { display: none !important; }
.bb-fix-card {
  position: absolute;
  left: 50px;
  right: 10px;
  max-height: 70%;
  overflow: auto;
  padding: 8px;
  background: #0d141c;
  border: 1px solid #2a3947;
  border-left: 3px solid #4fb8ff;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.55);
  font: 12px/1.5 "Consolas", "Courier New", monospace;
  color: #cdd9e5;
}
.bb-fix-head {
  display: flex;
  align-items: center;
  gap: 7px;
  margin-bottom: 6px;
  padding-bottom: 5px;
  border-bottom: 1px solid #1e2730;
}
.bb-fix-orb {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  object-fit: cover;
  flex: 0 0 auto;
  filter: drop-shadow(0 0 3px rgba(79, 184, 255, 0.6));
}
.bb-fix-head-text { flex: 1 1 auto; font-weight: bold; color: #aef9c6; letter-spacing: 0.4px; }
.bb-fix-close {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  padding: 0;
  color: #8aa0c4;
  background: transparent;
  border: 0;
  cursor: pointer;
}
.bb-fix-close:hover { color: #fff; }
.bb-fix-opt {
  margin: 6px 0;
  padding: 6px 7px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid #1e2730;
  border-left: 3px solid #56697d;
}
.bb-fix-opt.bb-conf-high { border-left-color: #39ff8a; }
.bb-fix-opt.bb-conf-medium { border-left-color: #ffcf5a; }
.bb-fix-opt.bb-conf-low { border-left-color: #ff8a3d; }
.bb-fix-opt.bb-fix-advice { border-left-color: #56697d; background: rgba(255, 255, 255, 0.015); }
.bb-fix-opt-top { display: flex; align-items: baseline; gap: 8px; }
.bb-fix-opt-title { flex: 1 1 auto; font-weight: bold; color: #e6f0fb; }
.bb-fix-conf {
  flex: 0 0 auto;
  padding: 0 6px;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: #0b0f14;
  background: #56697d;
  border-radius: 8px;
}
.bb-conf-high .bb-fix-conf { background: #39ff8a; }
.bb-conf-medium .bb-fix-conf { background: #ffcf5a; }
.bb-conf-low .bb-fix-conf { background: #ff8a3d; }
.bb-fix-why { margin: 4px 0; color: #9fb2c6; }
.bb-diff {
  display: flex;
  flex-direction: column;
  margin: 5px 0;
  padding: 4px 6px;
  max-height: 11rem;
  overflow: auto;
  background: #070c11;
  border: 1px solid #16202a;
}
.bb-diff-line { white-space: pre-wrap; word-break: break-word; padding: 0 2px; }
.bb-diff-add { background: rgba(57, 255, 138, 0.12); color: #aef9c6; }
.bb-diff-del { background: rgba(255, 90, 90, 0.12); color: #ff9a9a; }
.bb-diff-ctx { color: #6f8398; }
.bb-fix-apply {
  margin-top: 4px;
  padding: 3px 12px;
  font: bold 12px "Consolas", "Courier New", monospace;
  color: #06140c;
  background: linear-gradient(#39ff8a, #16c46a);
  border: 1px solid #0f9b50;
  border-radius: 3px;
  cursor: pointer;
}
.bb-fix-apply:hover { background: linear-gradient(#62ffa3, #21d479); }
.bb-fix-apply:active { transform: translateY(1px); }

.slop-gauge {
  --lvl: #8a98a6;
  display: flex;
  align-items: center;
  gap: 12px;
  padding-bottom: 8px;
  border-bottom: 1px solid #1e2730;
}
.slop-gauge.lvl-clean { --lvl: #35d07f; }
.slop-gauge.lvl-low   { --lvl: #8bd450; }
.slop-gauge.lvl-med   { --lvl: #ffb454; }
.slop-gauge.lvl-high  { --lvl: #ff8a3d; }
.slop-gauge.lvl-heavy { --lvl: #ff5c5c; }
.slop-score {
  font: bold 30px/1 "Consolas", "Courier New", monospace;
  color: var(--lvl);
  min-width: 48px;
  text-align: center;
}
.slop-gauge-body {
  display: flex;
  flex-direction: column;
  gap: 5px;
  flex: 1 1 auto;
}
.slop-meter {
  display: flex;
  gap: 2px;
}
.slop-seg {
  flex: 1 1 0;
  height: 12px;
  background: #1e2730;
  border-radius: 1px;
}
.slop-seg.on {
  background: var(--lvl);
  box-shadow: 0 0 4px var(--lvl);
}
.slop-verdict {
  font-weight: bold;
  font-size: 13px;
  color: var(--lvl);
}

.slop-findings {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 8px;
  max-height: 240px;
  overflow: auto;
}
.slop-empty {
  color: #35d07f;
  font-size: 13px;
  padding: 6px 2px;
}
.slop-finding {
  display: flex;
  align-items: baseline;
  gap: 8px;
  width: 100%;
  text-align: left;
  background: #131a22;
  border: 1px solid #1e2730;
  border-left-width: 3px;
  border-radius: 2px;
  padding: 5px 8px;
  color: #cdd9e5;
  font-size: 12px;
  cursor: pointer;
}
.slop-finding:hover {
  background: #18212c;
}
.slop-finding.sev-high { border-left-color: #ff5c5c; }
.slop-finding.sev-med { border-left-color: #ffb454; }
.slop-finding.sev-low { border-left-color: #6fb3ff; }
.slop-sev {
  flex: 0 0 auto;
  font-weight: bold;
  font-size: 10px;
  letter-spacing: 0.5px;
}
.sev-high .slop-sev { color: #ff5c5c; }
.sev-med .slop-sev { color: #ffb454; }
.sev-low .slop-sev { color: #6fb3ff; }
.slop-line {
  flex: 0 0 auto;
  font-family: "Consolas", "Courier New", monospace;
  color: #7d8b99;
}
.slop-msg {
  flex: 1 1 auto;
}

/* ===== BB Academy — the /HelpmeBB learning canvas (BB's terminal palette) ==== */
.bb-academy {
  position: relative;
  margin-top: 8px;
  display: flex;
  flex-direction: column;
  height: clamp(220px, 48vh, 600px); /* a docked, resizable panel (see dragresize) */
  overflow: hidden;                  /* the body scrolls; container height adjusts */
  background: #0b0f14;
  color: #cdd9e5;
  border: 2px inset var(--win-dark);
  font: 13px/1.55 "Consolas", "Courier New", monospace;
}
.bb-academy[hidden] { display: none; }
.bb-academy-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 9px;
  background: #11161d;
  border-bottom: 1px solid #1e2730;
}
.bb-academy-bar .bb-avatar { width: 26px; height: 26px; }
.bb-academy-titles { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }
.bb-academy-name { font-weight: bold; letter-spacing: 0.5px; color: #aef9c6; }
.bb-academy-sub { color: #8aa0c4; font-size: 11px; }
.bb-academy-sub code { color: #ffcf5a; background: rgba(255, 207, 90, 0.1); padding: 0 3px; border-radius: 2px; }
.bb-academy-xp {
  flex: 0 0 auto;
  color: #ffd479;
  font-weight: bold;
  padding: 2px 8px;
  border: 1px solid #5a4a12;
  background: rgba(255, 207, 90, 0.08);
  border-radius: 10px;
}
.bb-academy-xp:empty { display: none; }
.bb-academy-close { flex: 0 0 auto; padding: 1px 7px; }
.bb-academy-body {
  flex: 1 1 auto;
  min-height: 0; /* let the body shrink + scroll inside the flex column */
  padding: 11px 12px 14px;
  overflow-y: auto;
}

/* shared text + buttons */
.bba-h { margin: 12px 0 4px; color: #aef9c6; font-size: 13px; letter-spacing: 0.4px; }
.bba-p { margin: 7px 0; color: #d4deea; }
.bba-prompt {
  margin: 8px 0;
  padding: 9px 11px;
  background: rgba(79, 209, 255, 0.07);
  border-left: 3px solid #4fd1ff;
  color: #e6eef8;
}
.bba-flow { margin: 4px 0 12px; color: #8aa0c4; font-size: 11.5px; }
.bba-hint-sm { margin: 8px 0; color: #8aa0c4; font-size: 11.5px; font-style: italic; }
.bba-actions { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0 4px; }
.bba-primary {
  background: linear-gradient(#1f6f47, #155434);
  color: #d8ffe9 !important;
  border: 1px solid #39ff8a;
  font-weight: bold;
}
.bba-primary:hover { background: linear-gradient(#247f51, #19623d); }
.bba-link {
  background: none;
  border: 0;
  color: #6fd3ff;
  cursor: pointer;
  padding: 4px 2px;
  font: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.bba-link:hover { color: #a9e6ff; }
.bba-resume { display: inline-block; margin-top: 10px; }
.bba-tip {
  display: flex;
  gap: 7px;
  margin: 9px 0;
  padding: 6px 9px;
  background: #1a1206;
  border: 1px solid #5a3d12;
  border-left: 3px solid #ffcf5a;
  color: #ffe1b0;
}
.bba-tip-i { flex: 0 0 auto; }
.bba-tip-x { flex: 1 1 auto; min-width: 0; }
.bba-list { margin: 7px 0; padding-left: 20px; color: #d4deea; }
.bba-list li { margin: 3px 0; }
.bba-code {
  position: relative;
  margin: 9px 0;
  padding: 10px 11px;
  background: #06090d;
  border: 1px solid #1e2730;
  border-radius: 3px;
  overflow-x: auto;
  white-space: pre;
  color: #d6f5e3;
}
.bba-code code { font: 12px/1.5 "Consolas", "Courier New", monospace; color: inherit; white-space: pre; }
.bba-code-lang {
  position: absolute;
  top: 0;
  right: 0;
  padding: 1px 7px;
  font-size: 10px;
  color: #56697d;
  background: #11161d;
  border-bottom-left-radius: 3px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

/* welcome / level select */
.bba-speech {
  padding: 10px 12px;
  background: rgba(79, 209, 255, 0.06);
  border-left: 3px solid #4fd1ff;
  margin-bottom: 14px;
}
.bba-speech p { margin: 4px 0; }
.bba-speech-strong { font-weight: bold; color: #aef9c6; font-size: 15px; }
.bba-speech-q { color: #ffd479; font-weight: bold; margin-top: 8px !important; }
.bba-choices { display: flex; flex-wrap: wrap; gap: 12px; }
.bba-choice {
  flex: 1 1 220px;
  display: flex;
  align-items: flex-start;
  gap: 11px;
  text-align: left;
  padding: 14px;
  background: #11161d;
  border: 1px solid #283341;
  border-radius: 5px;
  color: #cdd9e5;
  cursor: pointer;
  font: inherit;
  transition: border-color 0.12s, background 0.12s;
}
.bba-choice:hover { border-color: #39ff8a; background: #141b24; }
.bba-choice-ic { font-size: 30px; line-height: 1; flex: 0 0 auto; }
.bba-choice-tt { display: flex; flex-direction: column; gap: 3px; }
.bba-choice-title { font-weight: bold; color: #aef9c6; font-size: 15px; }
.bba-choice-desc { color: #8aa0c4; font-size: 12px; }

/* course map */
.bba-maptop { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 10px; }
.bba-levelpill {
  padding: 3px 11px;
  background: rgba(57, 255, 138, 0.1);
  border: 1px solid #2c7a52;
  border-radius: 12px;
  color: #aef9c6;
  font-weight: bold;
}
.bba-lang {
  margin: 10px 0;
  padding: 11px 12px;
  background: #0e131a;
  border: 1px solid #283341;
  border-radius: 5px;
}
.bba-lang.complete { border-color: #2c7a52; box-shadow: inset 0 0 0 1px rgba(57, 255, 138, 0.25); }
.bba-lang-head { display: flex; align-items: center; gap: 10px; }
.bba-lang-ic { font-size: 24px; }
.bba-lang-tt { display: flex; align-items: baseline; gap: 10px; flex: 1 1 auto; }
.bba-lang-name { font-weight: bold; color: #e6eef8; font-size: 15px; }
.bba-lang-count { color: #8aa0c4; font-size: 11.5px; }
.bba-lang-blurb { margin: 5px 0 8px; color: #8aa0c4; font-size: 11.5px; }
.bba-bar { display: flex; gap: 3px; margin: 8px 0; }
.bba-seg { flex: 1 1 auto; height: 7px; background: #1c2531; border-radius: 2px; }
.bba-seg.on { background: linear-gradient(#39ff8a, #20c46a); }
.bba-modlist { display: flex; flex-direction: column; gap: 4px; margin-top: 9px; }
.bba-mod {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  text-align: left;
  padding: 7px 9px;
  background: #11161d;
  border: 1px solid #232e3b;
  border-left: 3px solid #56697d;
  border-radius: 3px;
  color: #cdd9e5;
  cursor: pointer;
  font: inherit;
}
.bba-mod:hover { background: #16202b; border-left-color: #4fd1ff; }
.bba-mod.done { border-left-color: #39ff8a; }
.bba-mod.wip { border-left-color: #ffcf5a; }
.bba-mod-ic { flex: 0 0 auto; width: 16px; text-align: center; font-weight: bold; }
.bba-mod.done .bba-mod-ic { color: #39ff8a; }
.bba-mod.wip .bba-mod-ic { color: #ffcf5a; }
.bba-mod.todo .bba-mod-ic { color: #56697d; }
.bba-mod-t { flex: 1 1 auto; min-width: 0; }
.bba-mod-min { flex: 0 0 auto; color: #56697d; font-size: 11px; }
.bba-mod-start { flex: 0 0 auto; color: #0b0f14; background: #ffcf5a; font-weight: bold; font-size: 10.5px; padding: 1px 7px; border-radius: 9px; }

/* lesson */
.bba-crumb { margin-bottom: 6px; }
.bba-lessonhead { display: flex; align-items: baseline; gap: 10px; }
.bba-title { margin: 4px 0 2px; color: #aef9c6; font-size: 16px; }
.bba-mins { color: #56697d; font-size: 11.5px; }
.bba-concept { margin: 6px 0; }

/* quiz */
.bba-quiz { display: flex; flex-direction: column; gap: 11px; margin: 10px 0; }
.bba-q { border: 1px solid #283341; border-radius: 4px; padding: 9px 11px; background: #0e131a; }
.bba-q-legend { padding: 0 5px; color: #e6eef8; font-weight: bold; }
.bba-opt { display: flex; align-items: flex-start; gap: 8px; padding: 5px 4px; cursor: pointer; border-radius: 3px; }
.bba-opt:hover { background: rgba(79, 209, 255, 0.08); }
.bba-opt input { margin-top: 3px; flex: 0 0 auto; accent-color: #39ff8a; }
.bba-opt-t { flex: 1 1 auto; }
.bba-quiz-result:empty { display: none; }
.bba-score { margin: 10px 0; padding: 8px 11px; font-weight: bold; border-radius: 4px; }
.bba-score.pass { color: #d8ffe9; background: rgba(57, 255, 138, 0.12); border: 1px solid #2c7a52; }
.bba-score.fail { color: #ffd9d9; background: rgba(255, 90, 90, 0.1); border: 1px solid #7a2c2c; }
.bba-qa { display: flex; gap: 8px; padding: 7px 0; border-bottom: 1px solid #161e27; }
.bba-qa-i { flex: 0 0 auto; width: 16px; text-align: center; font-weight: bold; }
.bba-qa.ok .bba-qa-i { color: #39ff8a; }
.bba-qa.no .bba-qa-i { color: #ff5a5a; }
.bba-qa-body { flex: 1 1 auto; min-width: 0; }
.bba-qa-q { color: #d4deea; }
.bba-qa-a { color: #aef9c6; font-size: 12px; margin-top: 2px; }
.bba-qa-e { color: #8aa0c4; font-size: 11.5px; margin-top: 2px; }

/* challenge result */
.bba-chk-result:empty { display: none; }
.bba-checks { display: flex; flex-direction: column; gap: 5px; margin: 10px 0; }
.bba-check { display: flex; gap: 8px; padding: 6px 9px; background: rgba(255, 255, 255, 0.03); border-left: 3px solid #56697d; border-radius: 3px; }
.bba-check.ok { border-left-color: #39ff8a; }
.bba-check.no { border-left-color: #ff5a5a; }
.bba-check-i { flex: 0 0 auto; font-weight: bold; }
.bba-check.ok .bba-check-i { color: #39ff8a; }
.bba-check.no .bba-check-i { color: #ff5a5a; }
.bba-check-body { flex: 1 1 auto; min-width: 0; }
.bba-check-name { color: #d4deea; }
.bba-check-hint { color: #ffc98a; font-size: 11.5px; margin-top: 2px; }
.bba-ci { margin: 10px 0; padding: 8px 10px; background: #06090d; border: 1px solid #1e2730; border-radius: 3px; }
.bba-ci-fail { border-color: #7a2c2c; }
.bba-ci-head { display: flex; align-items: center; gap: 7px; margin-bottom: 6px; }
.bba-ci-globe { width: 15px; height: 15px; border-radius: 50%; }
.bba-ci-verdict { color: #aef9c6; font-size: 12px; }
.bba-ci-fail .bba-ci-verdict { color: #ff9a9a; }
.bba-ci-stages { display: flex; flex-wrap: wrap; gap: 6px; }
.bba-ci-stage { padding: 2px 8px; border-radius: 10px; background: #11161d; border: 1px solid #232e3b; font-size: 11px; }
.bba-ci-stage .bba-ci-ic { font-weight: bold; }
.bba-ci-stage.bb-pass .bba-ci-ic { color: #39ff8a; }
.bba-ci-stage.bb-warn .bba-ci-ic { color: #ffcf5a; }
.bba-ci-stage.bb-fail .bba-ci-ic { color: #ff5a5a; }
.bba-pass { margin-top: 10px; padding: 11px 12px; background: rgba(57, 255, 138, 0.1); border: 1px solid #2c7a52; border-radius: 5px; }
.bba-pass-h { font-weight: bold; color: #aef9c6; font-size: 15px; }
.bba-pass-x { color: #b7e8cb; font-size: 12px; margin-top: 3px; }
.bba-fail { margin-top: 10px; padding: 10px 12px; background: rgba(255, 90, 90, 0.08); border: 1px solid #6a2a2a; border-radius: 5px; }
.bba-fail-h { font-weight: bold; color: #ffb3b3; }
.bba-fail-x { color: #d8b6b6; font-size: 12px; margin-top: 3px; }
.bba-done { margin-top: 8px; color: #aef9c6; font-size: 12px; }

/* badges */
.bba-badgestrip { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin: 4px 0 12px; padding: 8px 10px; background: #0e131a; border: 1px solid #232e3b; border-radius: 5px; }
.bba-badgestrip-label { color: #8aa0c4; font-size: 11.5px; }
.bba-badgestrip-row { display: flex; flex-wrap: wrap; gap: 5px; flex: 1 1 auto; }
.bba-badge { font-size: 18px; line-height: 1; filter: grayscale(1) opacity(0.35); cursor: help; }
.bba-badge.earned { filter: none; }
.bba-badgegrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; margin-top: 10px; }
.bba-badgecard { padding: 12px; text-align: center; background: #0e131a; border: 1px solid #232e3b; border-radius: 6px; }
.bba-badgecard.earned { border-color: #2c7a52; background: rgba(57, 255, 138, 0.06); }
.bba-badgecard.locked { opacity: 0.55; }
.bba-badgecard-i { font-size: 30px; line-height: 1; }
.bba-badgecard.locked .bba-badgecard-i { filter: grayscale(1); }
.bba-badgecard-n { font-weight: bold; color: #e6eef8; margin-top: 6px; }
.bba-badgecard-d { color: #8aa0c4; font-size: 11px; margin-top: 4px; }
.bba-badgecard-s { margin-top: 7px; font-size: 11px; font-weight: bold; color: #56697d; }
.bba-badgecard.earned .bba-badgecard-s { color: #39ff8a; }

/* ===================== Meshtastic NetMap / GreyMESH ===================== */
.netmap-note {
  margin: 6px 0 10px;
  padding: 8px 10px;
  background: #fff8d6;
  border: 1px solid #c9b458;
  color: #5c4d00;
  font-size: 12px;
}
.netmap-toolbar {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 10px;
}
.netmap-connect { font-weight: bold; }
.netmap-status { font-size: 12px; color: var(--win-dark); }
.netmap-status[data-kind="ok"] { color: #1a6e2e; }
.netmap-status[data-kind="busy"] { color: #7a5a00; }
.netmap-status[data-kind="err"] { color: #a11; }
body.dark .netmap-status { color: #9fb3d6; }
body.dark .netmap-status[data-kind="ok"] { color: #39ff8a; }
.netmap-count-wrap { margin-left: auto; font-size: 12px; }
.netmap-count { font-weight: bold; }

.netmap-grid {
  display: grid;
  grid-template-columns: minmax(260px, 360px) 1fr;
  gap: 12px;
  align-items: start;
}
@media (max-width: 640px) {
  .netmap-grid { grid-template-columns: 1fr; }
}
.netmap-radar {
  border: 2px inset var(--win-dark);
  background: #04120a;
  line-height: 0;
}
.netmap-svg { display: block; width: 100%; height: auto; }
.nm-bg { fill: #04120a; }
.nm-ring { fill: none; stroke: #1f5e3a; stroke-width: 1; }
.nm-cross { stroke: #14422a; stroke-width: 1; }
.nm-link { stroke: #2c9c63; stroke-width: 1; opacity: 0.5; }
.nm-node { fill: #39ff8a; stroke: #04120a; stroke-width: 1; }
.nm-node.nm-self { fill: #7fd0ff; }
.nm-node.nm-stale { fill: #5b7a68; }
.nm-label { fill: #8fe7b6; font: 9px "Courier New", monospace; }
.nm-range { fill: #5fbf8b; font: 10px "Courier New", monospace; text-anchor: middle; }
.nm-empty { fill: #3f7a59; font: 11px "Courier New", monospace; text-anchor: middle; }

.netmap-side, .netmap-chat { margin-top: 0; }
.netmap-side-title { font-weight: bold; font-size: 12px; margin-bottom: 6px; }
.netmap-chan { font-weight: normal; color: var(--win-dark); font-size: 11px; }
.netmap-node-list {
  border: 2px inset var(--win-dark);
  background: var(--win-light);
  max-height: 320px;
  overflow: auto;
  padding: 4px;
}
body.dark .netmap-node-list { background: #0e131a; }
.mesh-node-row {
  display: grid;
  grid-template-columns: 12px 1fr auto;
  gap: 6px;
  align-items: center;
  padding: 4px 6px;
  font-size: 12px;
  border-bottom: 1px dotted var(--win-dark);
}
.mesh-node-row:last-child { border-bottom: none; }
.mesh-node-led {
  width: 8px; height: 8px; border-radius: 50%;
  background: #39c46a; box-shadow: 0 0 4px #39c46a;
}
.mesh-node-led.stale { background: #8a8a8a; box-shadow: none; }
.mesh-node-name { font-weight: bold; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mesh-node-meta { color: var(--win-dark); font: 11px "Courier New", monospace; }
body.dark .mesh-node-meta { color: #8aa0c4; }

.netmap-chat { margin-top: 14px; }
.netmap-messages { height: 180px; overflow: auto; }
.mesh-msg { font-size: 13px; padding: 2px 4px; word-wrap: break-word; }
.mesh-msg-sys { color: var(--win-dark); font-style: italic; }
body.dark .mesh-msg-sys { color: #8aa0c4; }
.mesh-msg-from { font-weight: bold; }
.mesh-msg-mine .mesh-msg-from { color: #1a6e2e; }
body.dark .mesh-msg-mine .mesh-msg-from { color: #39ff8a; }
.netmap-compose { display: flex; gap: 8px; margin-top: 8px; }
.netmap-compose input { flex: 1; }

/* GreyMESH home-grid button: same Win98 layout as Code, green antenna accent. */
.mesh-jump-ico {
  color: #1f7a45;
  filter: drop-shadow(0 0 3px rgba(57, 255, 138, 0.55));
}
body.dark .mesh-jump-ico { color: #39ff8a; }

/* Phase 3: identity binding + RF presence */
.netmap-bind {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin: 4px 0 6px;
  font-size: 12px;
}
.netmap-bind-label { font-weight: bold; }
.netmap-bind input { width: 150px; font: 12px "Courier New", monospace; }
.netmap-bind-status { color: var(--win-dark); }
body.dark .netmap-bind-status { color: #9fb3d6; }
.netmap-bind-hint { margin-top: 0; }
.nm-node.nm-friend { fill: #ffd84a; stroke: #04120a; stroke-width: 1.5; }
.nm-label-friend { fill: #ffe98a; font-weight: bold; }
.buddy-rf {
  margin-left: 4px;
  font-size: 11px;
  line-height: 1;
  filter: drop-shadow(0 0 3px rgba(57, 255, 138, 0.7));
}