:root {
  /* Tell the browser the app is dark-themed so native widgets (form
   * controls, scrollbars, text-selection highlights, browser chrome)
   * render dark by default. Without this, Chrome/Android Safari paint
   * these in light mode even on a dark app, which can flash light when
   * inputs focus or the keyboard appears. */
  color-scheme: dark;

  /* Background */
  --color-bg: #060d10;
  --color-bg-chat: #0a1014;
  --color-bg-elevated: #141e26;

  /* Text */
  --color-text-primary: #f0f4f8;

  /* Accent */
  --color-accent: #00e5a0;
  --color-accent-dark: #00b87e;
  --color-accent-hover: #33f0ba;
  --color-accent-sky: #38bdf8;

  /* Semantic */
  --color-danger: #f43f5e;
  --color-danger-dark: #d4293e;
  --color-warning: #fbbf24;
  --color-warning-dark: #d97706;

  /* Neutrals */
  --color-white: #FFFFFF;
  --color-black: #000000;

  /* UI */
  --color-nav-inactive: #C6C6C6;
  --color-border: #DEDEDE;
  --color-row-alt: #EFEFEF;
  --color-badge: #ff0000;
  --color-dev: #818cf8;
  --color-night: #818cf8;

  /* Message time backgrounds */
  --color-msg-time-right: #092a25;
  --color-msg-time-left: #11191f;

  /* Toast */
  --color-toast-error: #ffd8df;
  --color-toast-warn: #ffeed1;
  --color-toast-info: #d9fff0;
}

* {
  scrollbar-width: none;
  -ms-overflow-style: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
  font-family: 'Montserrat', sans-serif;
  touch-action: pan-y;
}
*:focus {
  outline: none;
}
*::-webkit-scrollbar {
  display: none;
}

html, body {
  margin: 0px;
  padding: 0px;
  border: 0px;
  box-sizing: border-box;

  position: relative;
  vertical-align:top;
  font-family: 'Montserrat', sans-serif;
  overflow:hidden;
  background-color: var(--color-bg);

  -webkit-overscroll-behavior: none;
  overscroll-behavior: none;
  touch-action: none;
  -webkit-overflow-scrolling: touch;

  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
    -webkit-user-select: none;
     -khtml-user-select: none;
       -moz-user-select: none;
        -ms-user-select: none;
            user-select: none;
}

html {
  height: 100%;
  width: 100%;
}

body {
  position:absolute;
  top:env(safe-area-inset-top, 0);
  left:0px;

  width:100%;
  height:100%;
  height:calc(100% - env(safe-area-inset-bottom, 0));
}

/* ===== Safe-area fill ================================================
 * <body> is offset by env(safe-area-inset-top/bottom) so the page
 * gradient doesn't spill into the notch / home-indicator zones on
 * iPhone. The zones themselves then fall through to <html>'s solid
 * background. On iOS Safari PWA that can still visually leak (WebKit
 * paints body's gradient slightly outside its box around transitions /
 * translucent status bar).
 *
 * Paint opaque strips directly over both safe-area zones so nothing
 * leaks regardless of platform. On devices with no safe-area insets
 * (most Androids, desktop PWA) env() resolves to 0 and the strips
 * collapse to zero height — inert.
 *
 * Base colour is --color-bg (#060d10) which matches the near-opaque
 * rgba(6,13,16,0.97) used by the top bar / bottom nav on every page,
 * and the rgba(6,13,16,0.9) composer bar on the chat page. */
body::before,
body::after {
  content: '';
  position: fixed;
  left: 0;
  right: 0;
  background: var(--color-bg);
  pointer-events: none;
  /* Above the top bar (z:10) / bottom nav (z:9) so even if a
     background ever bleeds into the strip, this still covers it.
     Below the loading bar (z:999999) and modals so overlays remain
     on top. */
  z-index: 100;
}
body::before {
  top: 0;
  height: env(safe-area-inset-top, 0);
}
body::after {
  bottom: 0;
  height: env(safe-area-inset-bottom, 0);
}

a {
  text-decoration:none;
  color:inherit;
}
pre {
  margin:0px;
  padding:0px;
  white-space: pre-wrap;
  white-space: -moz-pre-wrap;
  white-space: -pre-wrap;
  white-space: -o-pre-wrap;
  word-wrap: break-word;
}

img {
    -webkit-transition: opacity 342ms ease;
    transition: opacity 342ms ease;
}
img[data-src] {
    opacity: 0;
    pointer-events: none;

    min-width: 1px;
    min-height: 1px;
}
img.img_loaded {
    opacity: 1;
    pointer-events: auto !important;
}

.pending_invites_cont {
    margin-bottom:20px !important;
}

.hb_button {
    color: var(--color-bg);
    font-size: 16px;
    width: 30px;
    height: 30px;
    border-radius: 10px;
    background-color: var(--color-white);
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    margin: 0px;
    padding: 0px;
    border: 0px;
}

.hbbm_cont {
  display:flex;
}
.hb_button_multi {
    color: var(--color-bg);
    font-size: 16px;
    width: 30px;
    height: 30px;
    border-radius: 10px;
    background-color: var(--color-white);

    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;

    margin: 0px;
    padding: 0px;
    border: 0px;
}

#mop_wrap {
  position:absolute;
  top:0px;
  left:0px;
  width:100%;
  height:100%;

  display:none;
  z-index:999;
}
#message_options_popup {
  position:absolute;
  top:50%;
  left:50%;
  transform:translate(-50%, -50%);
  padding:20px;
  width:60%;
  height:auto;
  background-color:var(--color-bg-elevated);
  color:var(--color-text-primary);
  border-radius:20px;
  display:none;

  z-index:9999;

  align-items: center;
  justify-content: center;
  text-align: center;
  flex-direction: column;
}
.mop_title {
  font-size:20px;
  text-align:center;
  font-weight:bold;
}

#attachments_wrap {
    position:absolute;
    top:0px;
    left:0px;
    width:100%;
    height:100%;


    display:none;
    z-index:999;
}
#attachments_popup {
    position:absolute;
    top:50%;
    left:50%;
    transform:translate(-50%, -50%);
    padding:20px;
    width:60%;
    height:auto;
    background-color:var(--color-bg-elevated);
    color:var(--color-text-primary);
    border-radius:20px;
    display:none;

    align-items: center;
    justify-content: center;
    text-align: center;
    flex-direction: column;
    z-index:9999;
  }

#mop_message {
  border:0px;
  background-color:var(--color-bg-elevated);
  color:var(--color-bg);
  width:100%;
  margin:0px;
  padding:0px;
  opacity:0;
  height:20px;
}
.mop_button {
  border-radius:10px;
  border:0px;
  background-color:var(--color-white);
  color:var(--color-bg);
  width:100px;
  margin:0px;
  padding:10px 10px;
  font-weight:bold;
  font-size:14px;
}
.mop_buttons_cont {
  display:flex;
  justify-content: center;
  text-align: center;
  align-items: center;
}
#delete_message {
  margin-left:30px;
}
#chats_list_cont,
#getContacts_API {
  contain: layout style;
}
.cm_finder {
  contain: layout style paint;
}

.chat_cont {
  display:flex;
  align-items: center;
  position:relative;
  margin-bottom:20px;
  padding-top:20px;
  border-top:1px solid var(--color-border);
  content-visibility: auto;
  contain-intrinsic-size: auto 80px;
}
.chat_cont_first {
  border-top:0px;
  padding-top:0px;
}

.chat_cont_picture {
  width:60px;
  height:60px;
}
.chat_cont_picture img {
  object-fit:cover;
  object-position: center;
  border-radius: 14px;
  width:100%;
  height:100%;
}

.contact_pic {
  width:150px;
  height:150px;
  margin-left:auto;
  margin-right:auto;
  margin-bottom:20px;
}
.contact_pic img {
  width:100%;
  height:100%;
  border-radius: 14px;
  object-fit:cover;
  object-position: center;
}
.contact_name {
  text-align:center;
  font-size:24px;
  font-weight:bold;
  width:100%;
  height:auto;
}
.fr_list_title {
  font-weight:bold;
}
.fr_list_cont {
  margin-top:20px;
  margin-bottom:20px;
}

.pending_fr_banner {
  background-color:var(--color-bg-elevated);
  color:var(--color-text-primary);
  display:flex;
  justify-content: space-between;
  align-items: center;
  height:auto;
  border-radius:14px;
  font-weight:bold;
  padding:10px 20px;
  margin-bottom:20px;
}

.contact_options {
  display:flex;
  justify-content: center;
  align-items: center;
  text-align: center;
  margin-top:30px;
  margin-bottom:20px;
  width:100%;
  gap:40px;
}
.contact_option_indv {
  text-align: center;
  background-color:var(--color-bg-elevated);
  color:var(--color-text-primary);
  padding:10px 20px;
  border-radius:14px;
  border:0px;

  height:100px;
  width:100px;

  display:flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  justify-content: center;
}
.option_icon {
  font-size:30px;
  text-align: center;
}
.single_co {
  margin-right:0px !important;
}
.option_title {
  font-size:12px;
  text-align: center;
  font-weight:bold;
  margin-top:10px;
}

.chat_name_sub {
  font-size:12px;
  width:100%;
  font-weight:normal;
  margin: 0px;
  padding: 0px;

  word-wrap: break-word;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;

  overflow: hidden;
  text-overflow: ellipsis;
}
.chat_cont_name {
  margin-left:20px;
  width: calc(100% - 154px);
}
.chat_name_title {
  font-size:16px;
  font-weight:bold;
  width:100%;
}
.chat_unread_messages {
  border-radius:50%;
  background-color:var(--color-bg-elevated);
  width:25px;
  height:25px;
  display:flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  color:var(--color-white);
  font-weight:bold;
  margin-top:5px;
  float:right;
}
.chat_right_info {
  position:absolute;
  right:0px;
  top:50%;
  transform: translateY(-50%);
  font-size:12px;
  text-align:right;
}
.chat_right_dt {
  color:var(--color-black);
}

.bottom_message {
  position:relative;
  bottom:0px;
  left:0px;
  min-height:30px;
  height:auto;
  padding:20px;
  width:calc(100% - 40px);
  background-color:var(--color-bg-elevated);
  display: flex;
  align-items: center;

  overflow-y:visible;
  overflow-x:visible;
  overscroll-behavior: none;

  touch-action: pan-y;
  z-index:8;
}

.message_process {
  position:absolute;
  top:0px;
  left:0px;
  width:100%;
  height:100%;
  display:flex;
  text-align: center;
  justify-content: center;
  align-items: center;
  z-index:1000000000;
  font-weight:bold;
  font-size:20px;
  color:var(--color-white);
  background-color:var(--color-bg-elevated);
  display:none;
}

.bottom_nav {
  height:70px;
  justify-content: center;
  font-weight:bold;
  background-color: var(--color-bg-elevated);
  color:var(--color-white);
  padding:0px;
  margin:0px;
  width:100% !important;
  z-index:9;
}
.bnm_inner {
  width:100%;
  height:100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  text-align: center;
  background-color: var(--color-bg-elevated);
}

.bnm_item {
  font-size:32px;
  width:100%;
  height:100%;
  display:flex;
  align-items: center;
  text-align: center;
  justify-content: center;

  background-color:var(--color-bg-elevated);
  color:var(--color-nav-inactive);
}
.bnm_item a {
  display:flex;
  align-items: center;
  text-align: center;
  justify-content: center;
  line-height: 1;

  position: relative;
}
.bnm_selected {
  color:var(--color-white);
}

.bottom_message #user_message {
  display: block;
  max-height:100px;
  overflow-x: hidden;
  overflow-y: hidden;
  width:calc(100% - 110px);
  resize:none;
  min-height: 20px;
  line-height: 20px;
  background-color:var(--color-white);
  color:var(--color-black);
  margin:0px;
  padding:5px;
  font-size:14px;
  height:20px;
  border:0px;
  border-radius:10px;
  margin-left:50px;

  /* NO overscroll-behavior — textarea has overflow:hidden so wheel events
     should bubble to the parent chat scroll container. Setting
     overscroll-behavior:none here captured wheels over the input strip
     and dropped them on the floor. */
  touch-action: manipulation;
  -webkit-overflow-scrolling: touch;
}

.bottom_message button {
  position:absolute;
  bottom:20px;
  margin:0px;
  padding:0px;
  border:0px;
  height:30px;
  width:30px;
  background-color:var(--color-white);
  border-radius: 10px;
  color:var(--color-bg);
  font-size:16px;
  display:flex;
  align-items: center;
  justify-content: center;
  text-align: center;
}
.bottom_message #attach_message {
  left:20px;
}
.bottom_message #send_message {
  right:20px;
  font-size:24px;
}

.indv_message {
  border-radius:12px;
  margin-bottom:20px;
  padding:10px;
  padding-right:46px;
  width:auto;
  max-width:80%;
  position:relative;

  display:flex;
  flex-direction: column;

  clear:both;
  text-align:left;
  color:var(--color-white);
  overflow:hidden;
  font-size:14px;
}
.indv_message pre a {
  text-decoration: underline;
}

.indv_message_name {
  font-weight:bold;
  margin-bottom:5px;
}

.indv_message_hidden_st {
  display:none;
}

.date_line {
  height:auto;
  width:50%;
  text-align:center;
  padding:10px;
  font-size:14px;
  font-weight:bold;
  clear:both;
  margin-bottom:20px;
  background-color:var(--color-bg-elevated);
  color:var(--color-text-primary);
  border-radius:10px;
  margin-left:auto;
  margin-right:auto;
}
.system_line {
  width:80%;
}

.indv_message_info_cont {
  width:26px;
  height: calc(100% - 20px);
  position:absolute;
  top:10px;
  right:10px;
  text-align:right;
}

.indv_message_info {
  position:absolute;
  font-size:10px;
  text-align:right;
  bottom:0px;
  right:0px;
  z-index:2;
  min-height:20px;
  width:100%;

  display:flex;
  align-items: flex-end;
  justify-content: flex-end;
}

.indv_message_moreinfo {
  position:absolute;
  font-size:14px;
  font-weight:900;
  letter-spacing: 1.5px;
  line-height: 10px;
  text-align:right;
  top:0px;
  right:0px;
  z-index:1;
  width:100%;

  display:flex;
  align-items: flex-start;
  justify-content: flex-end;
}

.message_right {
  float:right;
  background-color:var(--color-bg-elevated);
}
.message_left {
  float:left;
  background-color:rgba(18, 26, 32, 0.92);
}

.chat_top_info {
  position:relative;
  top:0px;
  left:0px;
  height:24px;
  width:calc(100% - 40px);
  padding:20px;
  background-color:var(--color-bg-elevated);

  font-weight:bold;
  font-size:24px;
  z-index:10;

  display: flex;
  align-items: center;

  /* NO overflow / overscroll-behavior here — if we set overflow:hidden,
     browsers (Chromium especially) treat the header as a scroll container
     and capture wheel events over the top 60px strip. Combined with
     overscroll-behavior:none, wheel events die there instead of
     propagating to .chats_cont. Content fits by design (fixed 24px height
     + 20px padding), so overflow isn't needed. */

  touch-action: pan-y;
}

.cti_cont {
  justify-content: space-between;
}
.cti_left {
  display:flex;
  align-items: center;
  flex: 1;
  min-width: 0;
  gap: 12px;
}
.cti_right {
  color: var(--color-bg);
  font-size:16px;
  width:30px;
  height:30px;
  border-radius: 10px;
  background-color: var(--color-white);

  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;

  margin: 0px;
  padding: 0px;
  border: 0px;
}
.cti_right a {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
}

.header_top {
  justify-content: space-between;
  color:var(--color-white);
}

.header_text {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.header_button {
  flex-shrink: 0;
}

.chat_other_name {
  color: var(--color-white);
  font-size: 17px;
  font-weight: 600;
  line-height: 1.25;
  max-width: 100%;
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
}

/* Live presence: muted by default (last seen / offline). The poll's onlineStatus()
   toggles is-online / is-away; "Online" lights up mint plus a tiny mint
   rounded-square — a pixel of aurora light, not a round dot. Typing never
   renders here: the in-flow typing bubble is the sole typing indicator. */
#chat_online_status {
  font-size: 12px;
  font-weight: 500;
  line-height: 16px;
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--color-text-primary);
  opacity: 0.5;
}
/* Empty (no presence yet / hidden) => zero height so the name sits centered next
   to the avatar; it only stacks above the status once the poll fills a value. */
#chat_online_status:empty {
  display: none;
}
#chat_online_status.is-online {
  color: var(--color-accent);
  opacity: 1;
}
#chat_online_status.is-online::before {
  content: "";
  display: inline-block;
  width: 5px;
  height: 5px;
  border-radius: 2px;
  margin-right: 6px;
  vertical-align: middle;
  background: var(--color-accent);
}
.chat_back_button {
  color: var(--color-bg);
  font-size:24px;
  width:30px;
  height:30px;
  border-radius: 10px;
  background-color: var(--color-white);

  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;

  margin: 0px;
  padding: 0px;
  border: 0px;
}
.chat_back_button a {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
}

/* Header identity: avatar + name/presence stack, links to /info (the WhatsApp-style
   header tap). flex:1;min-width:0 down the chain lets the name ellipsis-truncate. */
.cti_identity {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 11px;
  text-decoration: none;
  color: inherit;
}
.cti_avatar {
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  border-radius: 14px;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.06);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.08);
}
.cti_avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  border-radius: 14px;
}
.cti_nameblock {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.cti_nameblock .my_top_display {
  font-size: 12px;
  font-weight: 500;
  line-height: 16px;
  min-height: 16px;
}

/* Tap-down feedback on the header controls before a hard cross-document nav. */
.chat_back_button,
.cti_right,
.cti_identity {
  transition: transform 0.1s ease;
}
.chat_back_button:active,
.cti_right:active,
a.cti_identity:active {
  transform: scale(0.94);
}
@media (prefers-reduced-motion: reduce) {
  .chat_back_button:active,
  .cti_right:active,
  a.cti_identity:active { transform: none; }
}

.chats_cont {
  position:relative;
  background-color: var(--color-white);

  padding:20px;
  width:calc(100% - 40px);

  overflow-y: scroll;
  overflow-x: hidden;
  overscroll-behavior: none;
  -webkit-overflow-scrolling: touch;
  transform: translateZ(0);

  padding-top: 40px;
  padding-bottom: 40px;
  height: calc(100% - 214px);
  font-size: 18px;
}

.chat_page {
  padding-bottom:20px;
  height: calc(100% - 194px);
}

.settings_page {
  padding:20px;
  padding-top:40px;
  padding-bottom:40px;
  height:calc(100% - 214px);
  font-size:18px;
}

.contacts_page {
  padding-bottom:20px;
  height: calc(100% - 194px);
}

.settings_returnMessage {
  background-color:var(--color-bg-elevated);
  border-radius:14px;
  padding:20px;
  color:var(--color-text-primary);
  text-align:center;
  margin-bottom:20px;
  font-weight:bold;
}
.settings_item {
  margin-bottom:20px;
}
.settings_item form {
  display:flex;
}
.settings_item input {
  font-size:17px;
  margin:0px;
  padding:15px;
  width:calc(100% - 122px);
  margin-right:10px;
  border-radius:12px;
  border:1px solid rgba(255, 255, 255, 0.1);
}
.settings_item button {
  font-size:17px;
  font-weight:bold;
  padding:15px;
  text-align:center;
  height:auto;
  margin:0px;
  border:0px;
  border-radius:12px;
  background-color:var(--color-bg-elevated);
  border:1px solid rgba(255, 255, 255, 0.1);
  color:var(--color-text-primary);
  width:100px;
}

.uds_table {
    font-size:12px;
    border-radius:14px;
    border:1px solid rgba(255, 255, 255, 0.1);
}
.uds_table_row {
    text-align:left;
    padding:10px;
    border-bottom:1px solid rgba(255, 255, 255, 0.06);
    display:flex;
    justify-content: space-between;
    align-items:center;
}
.uds_table_row:last-child {
    border-bottom:0px;
}
.udstr_right {
    font-size:24px;
    margin-left:20px;
}
.udstr_right button {
    color: var(--color-text-primary);
    font-size:18px;
    width:32px;
    height:32px;
    border-radius: 10px;
    background-color: var(--color-bg-elevated);

    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;

    margin: 0px;
    padding: 0px;
    border: 0px;
}
.ld_buttons {
  display:block !important;
  text-align:center;
  margin-top:10px;
}
.ld_buttons button {
  width:100%;
  display:block;
}

.settings_item_title {
  font-weight:bold;
  margin-bottom:10px;
  font-size:20px;
  line-height:0.9;
}
.ap_inner {
  display:flex;
  align-items: center;
}
.ap_inner button {
  margin-left:10px;
}
.ap_inner img {
  border-radius: 12px;
  object-fit:cover;
  height:53px;
  width:53px;
}
.ap_choose_file {
  margin-bottom:0px;
}
.ap_choose_file .settings_item_title {
  margin-bottom:20px;
}
.ap_choose_file form {
  display:block;
}
.ap_choose_file input {
  display:block;
  border:0px;
  margin:0px;
  padding:0px;
  border-radius:0px;
}
.ap_choose_file button {
  display:block;
  margin-top:20px;
  width:100%;
}

.change_number form {
  display:block;
}
.change_number input {
  margin-top:5px;
  margin-right:0px;
  width:calc(100% - 12px);
  margin-bottom:20px;
}
.change_number button {
  width:100%;
}
.cn_subtext {
  font-size:14px;
  margin-bottom:20px;
}

#new_messages_button {
    position:absolute;
    top:-60px;
    right:20px;
    background-color:var(--color-bg-elevated);
    color:var(--color-text-primary);
    height:40px;
    width:40px;
    border-radius:10px;
    display: flex;
    align-items: center;
    text-align:center;
    justify-content: center;
}
#new_messages_button i {
    font-size:30px;
    line-height:1;
}

#chatbox {
  position:relative;

  padding:20px;
  padding-bottom:0px;

  width:calc(100% - 40px);
  height:calc(100% - 160px);

  min-height:calc(100% - 240px);
  max-height:calc(100% - 160px);

  overflow-y: scroll;
  overflow-x: hidden;
  overscroll-behavior: none;

  background-color:var(--color-white);
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;
}
.chatbox_long {
  height:calc(100% - 84px) !important;
  min-height:calc(100% - 84px) !important;
  max-height:calc(100% - 84px) !important;
}

.chatbox_loading {
  position:fixed;
  inset:0;
  top:env(safe-area-inset-top, 0);

  text-align: center;
  display:flex;
  vertical-align:middle;
  justify-content: center;
  align-items: center;

  background-color: var(--color-bg);
  z-index:9;

  font-size:24px;
  font-weight:bold;
  color:var(--color-white);
}
.chatbox_loading_inner {
  display:flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  vertical-align: middle;
  text-align: center;
}
.cli_spin {
  display:flex;
  justify-content: center;
  align-items: center;
  vertical-align: middle;
  text-align: center;

  font-size:48px;
}
.cli_text {
  display:flex;
  justify-content: center;
  align-items: center;
  vertical-align: middle;
  text-align: center;

  margin-top:20px;
}

.chat_info_cont {
  position:relative;
  background-color: var(--color-white);

  padding:40px;
  padding-left:20px;
  padding-right:20px;
  width:calc(100% - 40px);
  height:calc(100% - 144px);
  overflow-y: scroll;
  overflow-x: hidden;
  overscroll-behavior: none;
}

/* ===== AUTH PAGE ===== */
.moo-auth {
  position: fixed;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior: none;
  background: var(--color-bg);
  z-index: 1;
}
.moo-auth::before,
.moo-auth::after {
  content: '';
  flex: 1 0 24px;
}

.moo-auth__bg {
  position: fixed;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
}

.moo-auth__orb {
  position: absolute;
  border-radius: 50%;
  will-change: transform;
}
.moo-auth__orb--1 {
  width: 500px;
  height: 500px;
  background: radial-gradient(circle, rgba(14, 165, 233, 0.5) 0%, transparent 70%);
  top: -10%;
  right: -5%;
  animation: mooOrb1 20s ease-in-out infinite;
}
.moo-auth__orb--2 {
  width: 600px;
  height: 600px;
  background: radial-gradient(circle, rgba(99, 102, 241, 0.45) 0%, transparent 70%);
  bottom: -15%;
  left: -10%;
  animation: mooOrb2 25s ease-in-out infinite;
}
.moo-auth__orb--3 {
  width: 400px;
  height: 400px;
  background: radial-gradient(circle, rgba(244, 63, 94, 0.35) 0%, transparent 70%);
  top: 40%;
  left: 50%;
  margin-left: -200px;
  animation: mooOrb3 30s ease-in-out infinite;
}

@keyframes mooOrb1 {
  0%, 100% { transform: translate(0, 0) scale(1); }
  25% { transform: translate(80px, -120px) scale(1.1); }
  50% { transform: translate(-40px, -60px) scale(0.9); }
  75% { transform: translate(60px, 40px) scale(1.05); }
}
@keyframes mooOrb2 {
  0%, 100% { transform: translate(0, 0) scale(1); }
  33% { transform: translate(-100px, 80px) scale(1.15); }
  66% { transform: translate(60px, -100px) scale(0.95); }
}
@keyframes mooOrb3 {
  0%, 100% { transform: translate(0, 0) scale(1); }
  20% { transform: translate(100px, 50px) scale(0.9); }
  40% { transform: translate(-60px, 120px) scale(1.1); }
  60% { transform: translate(-120px, -40px) scale(1.05); }
  80% { transform: translate(40px, -80px) scale(0.95); }
}

.moo-auth__noise {
  position: absolute;
  inset: 0;
  opacity: 0.035;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-repeat: repeat;
  background-size: 256px 256px;
}

/* Glass card */
.moo-auth__card {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: 420px;
  flex-shrink: 0;
  padding: 48px 40px;
  box-sizing: border-box;
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 24px;
  box-shadow:
    0 0 0 1px rgba(255, 255, 255, 0.03),
    0 24px 80px rgba(0, 0, 0, 0.4);
  animation: mooCardIn 0.6s ease-out forwards;
}

@keyframes mooCardIn {
  from {
    opacity: 0;
    transform: translateY(24px) scale(0.98);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

/* Staggered entrance */
.moo-auth__card > * {
  opacity: 0;
  animation: mooFadeUp 0.5s ease-out forwards;
}
.moo-auth__card > *:nth-child(1) { animation-delay: 0.08s; }
.moo-auth__card > *:nth-child(2) { animation-delay: 0.14s; }
.moo-auth__card > *:nth-child(3) { animation-delay: 0.2s; }
.moo-auth__card > *:nth-child(4) { animation-delay: 0.26s; }
.moo-auth__card > *:nth-child(5) { animation-delay: 0.32s; }
.moo-auth__card > *:nth-child(6) { animation-delay: 0.38s; }
.moo-auth__card > *:nth-child(7) { animation-delay: 0.44s; }

@keyframes mooFadeUp {
  from {
    opacity: 0;
    transform: translateY(14px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Logo */
.moo-auth__logo {
  text-align: center;
  margin-bottom: 32px;
}
.moo-auth__logo a {
  display: inline-block;
  text-decoration: none;
  transition: transform 0.3s ease;
}
.moo-auth__logo a:hover {
  transform: scale(1.05);
}
.moo-auth__logo img {
  width: 88px;
  height: 88px;
  border-radius: 22px;
  box-shadow: 0 0 40px rgba(0, 229, 160, 0.15), 0 0 0 1px rgba(255, 255, 255, 0.08);
}
.moo-auth__tagline {
  margin-top: 16px;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 2.5px;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.4);
  white-space: nowrap;
}
/* Fixed-size flex items so the collapse/converge animation can drive each
   word's width precisely without flexbox grow/shrink fighting it. */
.moo-auth__tagline > * { flex: 0 0 auto; }
.moo-auth__tagline .mat-word {
  display: inline-block;
  overflow: hidden;
  white-space: nowrap;
  /* LOAD-BEARING: the auth card centres text; centred text inside the
     animated-width boxes over-measures the .COM reveal (scrollWidth of a
     centred 0-width clip) and strands dead space left of the period —
     "SAYVELLO .COM". Left-pin so collapse/reveal clip from the right. */
  text-align: left;
}
/* Inter-word spacing as a collapsible right margin (not a flex gap) so it can
   animate to 0 as the middle words drop out and SAY/VELLO converge. */
.moo-auth__tagline .mat-say,
.moo-auth__tagline .mat-hello,
.moo-auth__tagline .mat-on { margin-right: 0.42em; }
.moo-auth__tagline .mat-say {
  color: var(--color-text-primary);
}
.moo-auth__tagline .mat-vello {
  color: var(--color-accent);
  font-weight: 700;
}
/* The TLD: hidden by default — this IS the no-JS / reduced-motion resting
   state (line reads "SAY HELLO ON VELLO"). JS reveals it as the final beat. */
.moo-auth__tagline .mat-tld {
  display: inline-block;
  overflow: hidden;
  white-space: nowrap;
  text-align: left;
  text-transform: uppercase;
  /* No font-weight/letter-spacing overrides: inherit the container's 600 +
     tracking so .COM matches SAY exactly and shares the wordmark's rhythm
     (a tighter .COM made the VELLO→.COM joint read as a gap). The negative
     margin optically kerns the period's left side-bearing. */
  margin-left: -0.06em;
  color: rgba(255, 255, 255, 0.4);
  width: 0;
  opacity: 0;
}

/* Title + Subtitle */
.moo-auth__title {
  font-size: 28px;
  font-weight: 800;
  color: var(--color-text-primary);
  margin: 0 0 8px;
  letter-spacing: -0.5px;
}
.moo-auth__subtitle {
  font-size: 15px;
  font-weight: 400;
  color: rgba(255, 255, 255, 0.45);
  margin: 0 0 32px;
  line-height: 1.5;
}

/* Form fields */
.moo-auth__field {
  position: relative;
  margin-bottom: 24px;
}
.moo-auth__field-icon {
  position: absolute;
  left: 0;
  bottom: 13px;
  color: rgba(255, 255, 255, 0.25);
  font-size: 15px;
  width: 20px;
  text-align: center;
  transition: color 0.3s;
  pointer-events: none;
}
.moo-auth__field input {
  width: 100%;
  background: transparent;
  border: none;
  border-bottom: 2px solid rgba(255, 255, 255, 0.1);
  color: var(--color-text-primary);
  padding: 22px 0 10px 32px;
  font-size: 16px;
  font-weight: 500;
  font-family: 'Montserrat', sans-serif;
  transition: border-color 0.3s;
  box-sizing: border-box;
  border-radius: 0;
  -webkit-appearance: none;
  user-select: text;
  -webkit-user-select: text;
  touch-action: manipulation;
}
.moo-auth__field input:focus {
  border-bottom-color: var(--color-accent);
}
.moo-auth__field label {
  position: absolute;
  left: 32px;
  top: 18px;
  color: rgba(255, 255, 255, 0.35);
  font-size: 16px;
  font-weight: 500;
  pointer-events: none;
  transition: top 0.25s cubic-bezier(0.4, 0, 0.2, 1), font-size 0.25s cubic-bezier(0.4, 0, 0.2, 1), color 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}
.moo-auth__field input:focus + label,
.moo-auth__field input:not(:placeholder-shown) + label {
  top: 2px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--color-accent);
}
.moo-auth__field:has(input:focus) .moo-auth__field-icon {
  color: var(--color-accent);
}
.moo-auth__field:has(input:not(:placeholder-shown)) .moo-auth__field-icon {
  color: rgba(255, 255, 255, 0.45);
}

/* Submit button */
.moo-auth__btn {
  width: 100%;
  padding: 16px 24px;
  margin-top: 8px;
  background: linear-gradient(135deg, var(--color-accent), var(--color-accent-dark));
  border: none;
  border-radius: 14px;
  color: var(--color-bg);
  font-weight: 700;
  font-size: 16px;
  font-family: 'Montserrat', sans-serif;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  transition: opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1), transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  position: relative;
  overflow: hidden;
  touch-action: manipulation;
}
.moo-auth__btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 32px rgba(0, 229, 160, 0.25);
}
.moo-auth__btn:active {
  transform: translateY(0) scale(0.98);
}
.moo-auth__btn i {
  font-size: 14px;
  transition: transform 0.3s;
}
.moo-auth__btn:hover i {
  transform: translateX(3px);
}
.moo-auth__btn::before {
  content: '';
  position: absolute;
  top: 0;
  left: -100%;
  width: 100%;
  height: 100%;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
  transition: left 0.6s ease;
}
.moo-auth__btn:hover::before {
  left: 100%;
}
.moo-auth__btn:disabled {
  opacity: 0.7;
  cursor: default;
}
.moo-auth__btn:disabled:hover {
  transform: none;
  box-shadow: none;
}
.moo-auth__btn:disabled::before {
  display: none;
}

/* Switch link (login <-> register) */
.moo-auth__switch {
  margin-top: 28px;
  text-align: center;
  font-size: 14px;
  color: rgba(255, 255, 255, 0.4);
  font-weight: 500;
}
.moo-auth__switch a {
  color: var(--color-accent);
  font-weight: 700;
  margin-left: 4px;
  transition: color 0.2s;
  text-decoration: none;
}
.moo-auth__switch a:hover {
  color: var(--color-accent-hover);
}

/* Account deleted banner */
.moo-auth__deleted-banner {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 18px;
  border-radius: 14px;
  background: rgba(244, 63, 94, 0.08);
  border: 1px solid rgba(244, 63, 94, 0.15);
  color: rgba(244, 63, 94, 0.85);
  font-size: 14px;
  font-weight: 600;
  margin-bottom: 24px;
}
.moo-auth__deleted-banner i {
  font-size: 16px;
  flex-shrink: 0;
}

/* Password + recovery key save-prove ritual (register, recover, settings modals) */
.moo-rk-step {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 2.5px;
  text-transform: uppercase;
  color: rgba(0, 229, 160, 0.55);
  margin-bottom: 8px;
}
.moo-rk-warn {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 14px 16px;
  border-radius: 14px;
  background: rgba(251, 191, 36, 0.07);
  border: 1px solid rgba(251, 191, 36, 0.18);
  margin-bottom: 16px;
  text-align: left;
}
.moo-rk-warn i {
  color: var(--color-warning);
  font-size: 15px;
  flex-shrink: 0;
  margin-top: 2px;
}
.moo-rk-warn div {
  font-size: 13px;
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.6);
  font-weight: 500;
}
.moo-rk-warn strong {
  color: var(--color-warning);
  font-weight: 700;
}
.moo-rk-confirm__input {
  width: 100%;
  box-sizing: border-box;
  display: block;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 14px;
  padding: 14px 16px;
  color: var(--color-accent);
  font-family: 'Courier New', Courier, monospace;
  font-size: 14px;
  font-weight: 700;
  line-height: 1.7;
  letter-spacing: 1px;
  text-align: center;
  word-break: break-all;
  resize: none;
  outline: none;
  transition: border-color 160ms ease;
}
.moo-rk-confirm__input::placeholder {
  color: rgba(255, 255, 255, 0.25);
  font-family: 'Montserrat', sans-serif;
  font-weight: 500;
  letter-spacing: 0;
}
.moo-rk-confirm__input:focus { border-color: rgba(0, 229, 160, 0.35); }
.moo-rk-confirm__input--err,
.moo-rk-confirm__input--err:focus { border-color: rgba(244, 63, 94, 0.55); }
.moo-rk-confirm__input--ok,
.moo-rk-confirm__input--ok:focus { border-color: rgba(0, 229, 160, 0.6); }
.moo-rk-confirm__status {
  margin: 8px 2px 0;
  font-size: 12px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.35);
  text-align: center;
  min-height: 16px;
}
.moo-rk-confirm__status--err { color: var(--color-danger); }
.moo-rk-confirm__status--ok { color: var(--color-accent); }
.moo-auth__btn.moo-auth__btn--locked,
.moo-auth__btn.moo-auth__btn--locked:hover {
  opacity: 0.4;
  cursor: default;
  transform: none;
  box-shadow: none;
}
.moo-auth__btn.moo-auth__btn--locked::before { display: none; }
.moo-auth__btn.moo-auth__btn--locked:hover i { transform: none; }

/* Invite-only notice */
.moo-auth__invite-note {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 16px 18px;
  border-radius: 14px;
  background: rgba(14, 22, 28, 0.90);
  border: 1px solid rgba(255, 255, 255, 0.06);
  margin-top: 24px;
}
.moo-auth__invite-note > i {
  color: rgba(255, 255, 255, 0.25);
  font-size: 14px;
  margin-top: 2px;
  flex-shrink: 0;
}
.moo-auth__invite-note strong {
  display: block;
  color: rgba(255, 255, 255, 0.7);
  font-size: 13px;
  font-weight: 700;
  margin-bottom: 4px;
}
.moo-auth__invite-note p {
  margin: 0;
  color: rgba(255, 255, 255, 0.35);
  font-size: 13px;
  line-height: 1.5;
}

/* Auth mobile responsive */
@media (max-width: 480px) {
  .moo-auth::before,
  .moo-auth::after {
    flex: 1 0 16px;
  }
  .moo-auth__card {
    padding: 32px 24px;
    border-radius: 20px;
    max-width: calc(100% - 32px);
  }
  .moo-auth__title {
    font-size: 24px;
  }
  .moo-auth__field input {
    font-size: 15px;
  }
  .moo-auth__orb--1 { width: 300px; height: 300px; }
  .moo-auth__orb--2 { width: 350px; height: 350px; }
  .moo-auth__orb--3 { width: 250px; height: 250px; margin-left: -125px; }
}

/* ===== CONTACTS PAGE OVERHAUL ===== */

/* Page background — aurora gradient on body when contacts page is active */
html:has(.contacts_page) {
  background: var(--color-bg);
}
body:has(.contacts_page) {
  background:
    radial-gradient(ellipse at 75% 15%, rgba(14, 165, 233, 0.14) 0%, transparent 50%),
    radial-gradient(ellipse at 25% 85%, rgba(99, 102, 241, 0.11) 0%, transparent 50%),
    radial-gradient(ellipse at 55% 55%, rgba(244, 63, 94, 0.07) 0%, transparent 40%),
    var(--color-bg);
}

/* Header — dark glass */
body:has(.contacts_page) .chat_top_info.header_top {
  background: rgba(6, 13, 16, 0.97);
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
body:has(.contacts_page) .hb_button {
  background: rgba(24, 32, 40, 0.92);
  color: var(--color-text-primary);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 10px;
  transition: opacity 0.2s, background-color 0.2s, color 0.2s, border-color 0.2s;
}
body:has(.contacts_page) .hb_button:hover {
  background: rgba(0, 229, 160, 0.15);
  border-color: rgba(0, 229, 160, 0.3);
  color: var(--color-accent);
}

/* Bottom nav — dark glass */
body:has(.contacts_page) .bottom_nav {
  background: rgba(6, 13, 16, 0.97);
  border-top: 1px solid rgba(255, 255, 255, 0.06);
}
body:has(.contacts_page) .bnm_inner,
body:has(.contacts_page) .bnm_item {
  background: rgba(6, 13, 16, 0.85);
}
body:has(.contacts_page) .bnm_item {
  color: rgba(255, 255, 255, 0.3);
}
body:has(.contacts_page) .bnm_selected {
  color: var(--color-accent);
}

/* Content area — transparent so aurora shows through */
.contacts_page {
  background: transparent !important;
  color: var(--color-text-primary);
  padding-top: 20px !important;
  padding-bottom: 20px !important;
  height: calc(100% - 174px) !important;
}

/* Contact list items — glass cards */
.contacts_page .chat_cont {
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.06) !important;
  border-radius: 16px;
  padding: 16px !important;
  margin-bottom: 12px !important;
  transition: background 0.25s, border-color 0.25s;
}
.contacts_page .chat_cont:active {
  background: rgba(24, 32, 40, 0.92);
}
.contacts_page #getContacts_API > a:last-child .chat_cont,
.contacts_page .fr_list_cont > a:last-child .chat_cont {
  margin-bottom: 0 !important;
}
.contacts_page .chat_cont_first {
  border: 1px solid rgba(255, 255, 255, 0.06) !important;
  padding-top: 16px !important;
}
.contacts_page .chat_cont_picture img {
  border-radius: 14px;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.06);
}
.contacts_page .chat_cont_name {
  width: calc(100% - 80px);
}
.contacts_page .chat_name_title {
  color: var(--color-text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* "No contacts" empty state */
.contacts_page #getContacts_API:empty,
.contacts_page #getContacts_API:not(:has(.chat_cont)) {
  color: rgba(255, 255, 255, 0.35);
  text-align: center;
  padding: 60px 0;
  font-size: 15px;
}

/* Pending friend requests banner — accent glass */
.contacts_page .pending_fr_banner {
  background: rgba(0, 229, 160, 0.08);
  border: 1px solid rgba(0, 229, 160, 0.15);
  border-radius: 16px;
  color: var(--color-text-primary);
  padding: 16px 20px;
  transition: background 0.25s;
}
.contacts_page .pending_fr_banner:active {
  background: rgba(0, 229, 160, 0.14);
}
.contacts_page .pending_fr_banner .pfr_number {
  background: var(--color-accent);
  color: var(--color-bg);
  width: 28px;
  height: 28px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  font-weight: 800;
}

/* Friend request list titles */
.contacts_page .fr_list_title {
  color: rgba(255, 255, 255, 0.5);
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1px;
  margin-bottom: 12px;
}

/* ---- Profile card (individual contact) ---- */
.moo-profile-card {
  position: relative;
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 24px;
  padding: 32px;
  text-align: center;
  margin-bottom: 8px;
}
.contacts_page .contact_pic {
  width: 110px;
  height: 110px;
  margin: 0 auto 20px;
}
.contacts_page .contact_pic img {
  border-radius: 24px;
  box-shadow:
    0 0 40px rgba(0, 229, 160, 0.1),
    0 0 0 1px rgba(255, 255, 255, 0.08);
}
.contacts_page .contact_name {
  color: var(--color-text-primary);
  font-size: 24px;
}
.contacts_page .contact_mn_display {
  color: rgba(255, 255, 255, 0.4);
  font-size: 15px;
  margin-top: 4px;
}
.contacts_page .contact_real_name {
  font-size: 14px;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.35);
  margin-top: 2px;
}
.contacts_page .contact_last_online {
  color: rgba(255, 255, 255, 0.45);
  font-size: 13px;
  margin-top: 12px;
}
.contacts_page .contact_last_online b {
  color: rgba(255, 255, 255, 0.6);
}
.contacts_page .contact_timezone {
  color: rgba(255, 255, 255, 0.35);
  font-size: 13px;
}
.contacts_page .contact_timezone b {
  color: rgba(255, 255, 255, 0.5);
}
/* Contact action buttons */
.contacts_page .contact_options {
  gap: 12px;
  margin-top: 16px;
  margin-bottom: 0;
}
.contacts_page .contact_option_indv {
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 18px;
  color: var(--color-text-primary);
  width: 110px;
  height: 100px;
  cursor: pointer;
  transition: opacity 0.25s cubic-bezier(0.4, 0, 0.2, 1), background-color 0.25s cubic-bezier(0.4, 0, 0.2, 1), border-color 0.25s cubic-bezier(0.4, 0, 0.2, 1), transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}
.contacts_page .contact_option_indv:hover {
  background: rgba(0, 229, 160, 0.08);
  border-color: rgba(0, 229, 160, 0.2);
  transform: translateY(-3px);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
}
.contacts_page .contact_option_indv:active {
  transform: translateY(0);
}
.contacts_page .option_icon {
  font-size: 24px;
  color: var(--color-accent);
}
.contacts_page .option_title {
  color: rgba(255, 255, 255, 0.6);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.3px;
}
.contacts_page .moo-btn-danger:hover {
  background: rgba(244, 63, 94, 0.1) !important;
  border-color: rgba(244, 63, 94, 0.25) !important;
}
.contacts_page .moo-btn-danger .option_icon {
  color: var(--color-danger);
}
.contacts_page .moo-btn-success:hover {
  background: rgba(0, 229, 160, 0.12) !important;
  border-color: rgba(0, 229, 160, 0.25) !important;
}
.contacts_page .co_contact_form {
  gap: 12px;
}

/* ---- Form cards (add contact, create/join group) ---- */
.contacts_page .moo-form-card {
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 24px;
  padding: 36px 32px;
}
.contacts_page .moo-form-icon {
  font-size: 32px;
  color: var(--color-accent);
  margin-bottom: 16px;
}
.contacts_page .moo-form-card .settings_item_title {
  color: var(--color-text-primary);
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -0.3px;
  line-height: 1.2;
}
.contacts_page .moo-form-card .cn_subtext {
  color: rgba(255, 255, 255, 0.4);
  font-size: 14px;
  line-height: 1.6;
  margin-bottom: 28px;
}
.contacts_page .moo-form-card .cn_input_title {
  color: rgba(255, 255, 255, 0.4);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1px;
  margin-bottom: 8px;
}
.contacts_page .moo-form-card form {
  display: block;
}
.contacts_page .moo-form-card input {
  background: transparent !important;
  border: none !important;
  border-bottom: 2px solid rgba(255, 255, 255, 0.1) !important;
  color: var(--color-text-primary) !important;
  padding: 14px 0 !important;
  font-size: 16px !important;
  font-weight: 500;
  font-family: 'Montserrat', sans-serif;
  width: 100% !important;
  margin: 0 0 24px 0 !important;
  border-radius: 0 !important;
  -webkit-appearance: none;
  transition: border-color 0.3s;
  user-select: text;
  -webkit-user-select: text;
  touch-action: manipulation;
}
.contacts_page .moo-form-card input:focus {
  border-bottom-color: var(--color-accent) !important;
}
.contacts_page .moo-form-card input[readonly] {
  color: rgba(255, 255, 255, 0.4) !important;
  border-bottom-color: rgba(255, 255, 255, 0.05) !important;
}
.contacts_page .moo-form-card button[type="submit"] {
  background: linear-gradient(135deg, var(--color-accent), var(--color-accent-dark)) !important;
  color: var(--color-bg) !important;
  border: none !important;
  border-radius: 14px !important;
  padding: 16px 24px !important;
  font-weight: 700 !important;
  font-size: 16px !important;
  font-family: 'Montserrat', sans-serif;
  width: 100% !important;
  cursor: pointer;
  transition: opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1), transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  position: relative;
  overflow: hidden;
}
.contacts_page .moo-form-card button[type="submit"]:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 32px rgba(0, 229, 160, 0.25);
}
.contacts_page .moo-form-card button[type="submit"]:active {
  transform: translateY(0) scale(0.98);
}
.contacts_page .moo-form-card button[type="submit"] i {
  font-size: 14px;
}

/* Return/status messages */
.contacts_page .settings_returnMessage {
  background: rgba(0, 229, 160, 0.08);
  border: 1px solid rgba(0, 229, 160, 0.15);
  border-radius: 16px;
  color: var(--color-text-primary);
  padding: 18px 24px;
  font-size: 15px;
  font-weight: 600;
  text-align: left;
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 20px;
}
.contacts_page .settings_returnMessage i {
  color: var(--color-accent);
  font-size: 18px;
  flex-shrink: 0;
}

/* Pending invites table */
.contacts_page .uds_table {
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 16px;
  overflow: hidden;
  margin-top: 16px;
}
.contacts_page .uds_table_row {
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  padding: 14px 16px;
  color: rgba(255, 255, 255, 0.6);
}
.contacts_page .uds_table_row b {
  color: rgba(255, 255, 255, 0.4);
}
.contacts_page .udstr_right button {
  background: rgba(244, 63, 94, 0.1) !important;
  border: 1px solid rgba(244, 63, 94, 0.2) !important;
  color: var(--color-danger) !important;
  border-radius: 10px !important;
  width: 32px !important;
  height: 32px !important;
  padding: 0 !important;
  font-size: 18px !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  transition: opacity 0.2s, background-color 0.2s;
}
.contacts_page .udstr_right button:hover {
  background: rgba(244, 63, 94, 0.2);
}

/* ---- Modal — frosted glass ---- */
body:has(.contacts_page) #chats_popup_wrap {
  background: rgba(6, 13, 16, 0.6);
  animation: mooOverlayIn 0.2s ease-out;
}
body:has(.contacts_page) #chats_popup {
  background: rgba(20, 30, 38, 0.85);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 24px;
  padding: 32px;
  width: min(320px, 80%);
  color: var(--color-text-primary);
  animation: mooModalIn 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
@keyframes mooOverlayIn {
  from { opacity: 0; }
  to { opacity: 1; }
}
@keyframes mooModalIn {
  from { opacity: 0; transform: translate(-50%, -48%) scale(0.95); }
  to { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  @keyframes mooOverlayIn { from, to { opacity: 1; } }
  @keyframes mooModalIn { from, to { opacity: 1; transform: translate(-50%, -50%) scale(1); } }
  #moo_img_viewer { animation: none; } /* media viewer opens without the scale-in */
}
.moo-modal__title {
  font-size: 18px;
  font-weight: 800;
  text-align: center;
  margin-bottom: 20px;
  color: var(--color-text-primary);
  letter-spacing: -0.3px;
}
.moo-modal__options {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 100%;
}
.moo-modal__option {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 18px;
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 14px;
  color: var(--color-text-primary);
  font-size: 15px;
  font-weight: 600;
  text-decoration: none;
  transition: opacity 0.2s, background-color 0.2s, border-color 0.2s;
}
.moo-modal__option:hover {
  background: rgba(0, 229, 160, 0.08);
  border-color: rgba(0, 229, 160, 0.2);
}
.moo-modal__option:active {
  background: rgba(0, 229, 160, 0.14);
}
.moo-modal__option i {
  color: var(--color-accent);
  font-size: 16px;
  width: 24px;
  text-align: center;
  flex-shrink: 0;
}

/* Nickname form on contact page */
.contacts_page .moo-settings-card {
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 20px;
  padding: 24px;
}
.contacts_page .moo-settings-card__header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
}
.contacts_page .moo-settings-card__icon {
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: rgba(0, 229, 160, 0.1);
  border: 1px solid rgba(0, 229, 160, 0.15);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-accent);
  font-size: 14px;
  flex-shrink: 0;
}
.contacts_page .moo-settings-card .settings_item_title {
  color: var(--color-text-primary);
  font-size: 17px;
  font-weight: 700;
  margin-bottom: 0;
  line-height: 1;
}
.moo-nickname-form {
  display: flex;
  gap: 8px;
}
.moo-nickname-form input[type="text"] {
  flex: 1;
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  color: var(--color-text-primary);
  padding: 12px 16px;
  font-size: 15px;
  font-weight: 500;
  font-family: 'Montserrat', sans-serif;
  width: auto;
  margin: 0;
  -webkit-appearance: none;
  user-select: text;
  -webkit-user-select: text;
  touch-action: manipulation;
}
.moo-nickname-form input[type="text"]:focus {
  border-color: rgba(0, 229, 160, 0.4);
}
.moo-nickname-form input[type="text"]::placeholder {
  color: rgba(255, 255, 255, 0.25);
}
.moo-nickname-form button {
  background: rgba(18, 26, 32, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  color: var(--color-text-primary);
  padding: 12px 16px;
  font-size: 14px;
  font-weight: 700;
  font-family: 'Montserrat', sans-serif;
  cursor: pointer;
  transition: opacity 0.2s, background-color 0.2s, color 0.2s, border-color 0.2s;
  white-space: nowrap;
}
.moo-nickname-form button:hover {
  background: rgba(0, 229, 160, 0.1);
  border-color: rgba(0, 229, 160, 0.25);
  color: var(--color-accent);
}
.moo-nickname-form .moo-btn-danger-outline {
  background: transparent;
  border: 1px solid rgba(244, 63, 94, 0.3);
  color: var(--color-danger);
}
.moo-nickname-form .moo-btn-danger-outline:hover {
  background: rgba(244, 63, 94, 0.1);
  border-color: rgba(244, 63, 94, 0.4);
}

/* Contacts page responsive */
@media (max-width: 480px) {
  .moo-profile-card {
    padding: 24px;
    border-radius: 20px;
  }
  .contacts_page .moo-form-card {
    padding: 28px 24px;
    border-radius: 20px;
  }
  .contacts_page .contact_option_indv {
    width: 90px;
    height: 90px;
  }
  .contacts_page .moo-settings-card {
    padding: 20px;
    border-radius: 16px;
  }
  .moo-nickname-form {
    flex-direction: column;
  }
}

/* ===== SETTINGS PAGE OVERHAUL ===== */

/* Page background */
html:has(.moo-settings) {
  background: var(--color-bg);
}
body:has(.moo-settings) {
  background:
    radial-gradient(ellipse at 70% 20%, rgba(14, 165, 233, 0.12) 0%, transparent 50%),
    radial-gradient(ellipse at 30% 80%, rgba(99, 102, 241, 0.1) 0%, transparent 50%),
    radial-gradient(ellipse at 50% 50%, rgba(244, 63, 94, 0.06) 0%, transparent 40%),
    var(--color-bg);
}

/* Header — dark glass */
body:has(.moo-settings) .chat_top_info.header_top {
  background: rgba(6, 13, 16, 0.97);
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
body:has(.moo-settings) .hb_button {
  background: rgba(24, 32, 40, 0.92);
  color: var(--color-text-primary);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 10px;
  transition: opacity 0.2s, background-color 0.2s, color 0.2s, border-color 0.2s;
}
body:has(.moo-settings) .hb_button:hover {
  background: rgba(0, 229, 160, 0.15);
  border-color: rgba(0, 229, 160, 0.3);
  color: var(--color-accent);
}

/* Bottom nav — dark glass */
body:has(.moo-settings) .bottom_nav {
  background: rgba(6, 13, 16, 0.97);
  border-top: 1px solid rgba(255, 255, 255, 0.06);
}
body:has(.moo-settings) .bnm_inner,
body:has(.moo-settings) .bnm_item {
  background: rgba(6, 13, 16, 0.85);
}
body:has(.moo-settings) .bnm_item {
  color: rgba(255, 255, 255, 0.3);
}
body:has(.moo-settings) .bnm_selected {
  color: var(--color-accent);
}

/* Section headers */
.moo-settings__section {
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: rgba(255, 255, 255, 0.3);
  padding: 0 4px;
  margin-bottom: 12px;
}
.moo-settings__section:not(:first-of-type) {
  margin-top: 28px;
}

/* Content area */
.moo-settings {
  background: transparent !important;
  color: var(--color-text-primary);
  padding-top: 20px !important;
  padding-bottom: 20px !important;
  height: calc(100% - 174px) !important;
}

/* Settings cards */
.moo-settings .moo-settings-card {
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 20px;
  padding: 24px;
  margin-bottom: 16px;
}
.moo-settings .moo-settings-card:last-child,
.moo-settings .moo-settings-card:last-of-type,
.moo-settings .moo-form-card:last-child,
.moo-settings .moo-form-card:last-of-type,
.moo-settings .settings_item_last {
  margin-bottom: 0;
}
.moo-settings-card__header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
}
.moo-settings-card__icon {
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: rgba(0, 229, 160, 0.1);
  border: 1px solid rgba(0, 229, 160, 0.15);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-accent);
  font-size: 14px;
  flex-shrink: 0;
}
.moo-settings .moo-settings-card .settings_item_title {
  color: var(--color-text-primary);
  font-size: 17px;
  font-weight: 700;
  margin-bottom: 0;
  line-height: 1;
}

/* Settings card forms (Name, Mobile Number) */
.moo-settings .moo-settings-card form:not(.ap_inner):not(.ld_buttons) {
  display: flex;
  gap: 10px;
}
.moo-settings .moo-settings-card input[type="text"],
.moo-settings .moo-settings-card input[type="tel"] {
  flex: 1;
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  color: var(--color-text-primary);
  padding: 12px 16px;
  font-size: 15px;
  font-weight: 500;
  font-family: 'Montserrat', sans-serif;
  width: auto;
  margin: 0;
  transition: border-color 0.3s;
  -webkit-appearance: none;
  user-select: text;
  -webkit-user-select: text;
  touch-action: manipulation;
}
.moo-settings .moo-settings-card input[type="text"]:focus,
.moo-settings .moo-settings-card input[type="tel"]:focus {
  border-color: rgba(0, 229, 160, 0.4);
}
.moo-settings .moo-settings-card input[readonly] {
  color: rgba(255, 255, 255, 0.4);
  border-color: rgba(255, 255, 255, 0.05);
}
.moo-settings .moo-settings-card button[type="submit"] {
  background: rgba(18, 26, 32, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  color: var(--color-text-primary);
  padding: 12px 20px;
  font-size: 14px;
  font-weight: 700;
  font-family: 'Montserrat', sans-serif;
  cursor: pointer;
  transition: opacity 0.2s, background-color 0.2s, color 0.2s, border-color 0.2s;
  white-space: nowrap;
  width: auto;
  height: auto;
  margin: 0;
}
.moo-settings .moo-settings-card button[type="submit"]:hover {
  background: rgba(0, 229, 160, 0.1);
  border-color: rgba(0, 229, 160, 0.25);
  color: var(--color-accent);
}

/* Account picture */
.moo-settings .moo-settings-card .ap_inner {
  display: flex;
  align-items: center;
  gap: 16px;
}
.moo-settings .moo-settings-card .ap_inner img {
  width: 56px;
  height: 56px;
  border-radius: 14px;
  object-fit: cover;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.08);
  flex-shrink: 0;
}
.moo-settings .moo-ap-buttons {
  display: flex;
  gap: 8px;
  height: 56px;
}
.moo-settings .moo-ap-buttons button {
  margin-left: 0;
  height: 100% !important;
}

/* Danger outline button */
.moo-settings .moo-btn-danger-outline {
  background: transparent !important;
  border: 1px solid rgba(244, 63, 94, 0.3) !important;
  color: var(--color-danger) !important;
}
.moo-settings .moo-btn-danger-outline:hover {
  background: rgba(244, 63, 94, 0.1) !important;
  border-color: rgba(244, 63, 94, 0.4) !important;
}

/* Push notifications */
.moo-settings .push_box {
  margin-top: 0;
}
.moo-pn-status {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  border-radius: 12px;
  font-size: 14px;
  font-weight: 600;
  margin-bottom: 14px;
}
.moo-pn-enabled {
  background: rgba(0, 229, 160, 0.08);
  border: 1px solid rgba(0, 229, 160, 0.15);
  color: var(--color-accent);
}
.moo-pn-disabled {
  background: rgba(14, 22, 28, 0.90);
  border: 1px solid rgba(255, 255, 255, 0.06);
  color: rgba(255, 255, 255, 0.4);
}
.moo-settings .push_button {
  display: flex;
  gap: 8px;
}
.moo-settings .push_button button {
  flex: 1;
  background: rgba(18, 26, 32, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  color: var(--color-text-primary);
  padding: 12px 20px;
  font-size: 14px;
  font-weight: 700;
  font-family: 'Montserrat', sans-serif;
  cursor: pointer;
  transition: opacity 0.2s, background-color 0.2s, color 0.2s, border-color 0.2s;
  width: auto;
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.moo-settings .push_button button:hover {
  background: rgba(0, 229, 160, 0.1);
  border-color: rgba(0, 229, 160, 0.25);
  color: var(--color-accent);
}
.moo-settings .push_button .moo-btn-danger-outline {
  background: transparent !important;
  border: 1px solid rgba(244, 63, 94, 0.3) !important;
  color: var(--color-danger) !important;
}
.moo-settings .push_button .moo-btn-danger-outline:hover {
  background: rgba(244, 63, 94, 0.1) !important;
  border-color: rgba(244, 63, 94, 0.4) !important;
  color: var(--color-danger) !important;
}

/* Account devices table */
.moo-settings .uds_table {
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 14px;
  overflow: hidden;
}
.moo-settings .uds_table_row {
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  padding: 14px 16px;
  color: rgba(255, 255, 255, 0.6);
  font-size: 12px;
}
.moo-settings .uds_table_row:last-child {
  border-bottom: 0;
}
.moo-settings .uds_table_row b {
  color: rgba(255, 255, 255, 0.8);
}
.moo-settings .udstr_right button {
  background: rgba(244, 63, 94, 0.1) !important;
  border: 1px solid rgba(244, 63, 94, 0.2) !important;
  color: var(--color-danger) !important;
  border-radius: 10px !important;
  width: 32px !important;
  height: 32px !important;
  padding: 0 !important;
  font-size: 16px !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  transition: opacity 0.2s, background-color 0.2s;
  cursor: pointer;
}
.moo-settings .udstr_right button:hover {
  background: rgba(244, 63, 94, 0.2) !important;
}

/* Log out everywhere button */
.moo-settings .ld_buttons {
  display: block !important;
  margin-top: 14px;
}
.moo-settings .ld_buttons button {
  width: 100% !important;
  background: rgba(244, 63, 94, 0.08) !important;
  border: 1px solid rgba(244, 63, 94, 0.2) !important;
  border-radius: 12px !important;
  color: var(--color-danger) !important;
  padding: 14px 20px !important;
  font-size: 14px !important;
  font-weight: 700 !important;
  font-family: 'Montserrat', sans-serif;
  cursor: pointer;
  transition: opacity 0.2s, background-color 0.2s;
  display: flex !important;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.moo-settings .ld_buttons button:hover {
  background: rgba(244, 63, 94, 0.15) !important;
}

/* Return messages */
.moo-settings .settings_returnMessage {
  background: rgba(0, 229, 160, 0.08);
  border: 1px solid rgba(0, 229, 160, 0.15);
  border-radius: 16px;
  color: var(--color-text-primary);
  padding: 18px 24px;
  font-size: 15px;
  font-weight: 600;
  text-align: left;
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
}
.moo-settings .settings_returnMessage i {
  color: var(--color-accent);
  font-size: 18px;
  flex-shrink: 0;
}

/* Privacy toggles */
.moo-privacy-toggles {
  display: flex;
  flex-direction: column;
  gap: 0;
}
.moo-privacy-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}
.moo-privacy-toggle:last-child {
  border-bottom: none;
  padding-bottom: 0;
}
.moo-privacy-toggle:first-child {
  padding-top: 0;
}
.moo-privacy-toggle__text {
  flex: 1;
  min-width: 0;
}
.moo-privacy-toggle__label {
  font-size: 14px;
  font-weight: 600;
  color: var(--color-text-primary);
}
.moo-privacy-toggle__desc {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.3);
  margin-top: 2px;
}
/* Toggle switch */
.moo-toggle {
  position: relative;
  display: inline-block;
  width: 44px;
  height: 26px;
  flex-shrink: 0;
  cursor: pointer;
}
.moo-toggle input {
  opacity: 0;
  width: 0;
  height: 0;
  position: absolute;
}
.moo-toggle__track {
  position: absolute;
  inset: 0;
  background: rgba(28, 36, 44, 0.92);
  border-radius: 13px;
  transition: background 0.25s;
}
.moo-toggle__track::after {
  content: '';
  position: absolute;
  top: 3px;
  left: 3px;
  width: 20px;
  height: 20px;
  background: rgba(255, 255, 255, 0.5);
  border-radius: 50%;
  transition: transform 0.25s, background 0.25s;
}
.moo-toggle input:checked + .moo-toggle__track {
  background: var(--color-accent);
}
.moo-toggle input:checked + .moo-toggle__track::after {
  transform: translateX(18px);
  background: var(--color-bg);
}
.moo-toggle input:disabled + .moo-toggle__track {
  opacity: 0.35;
  cursor: not-allowed;
}
.moo-toggle:has(input:disabled) {
  cursor: not-allowed;
}

/* Sub-pages (change picture, verify number) — reuse moo-form-card from contacts */
.moo-settings .moo-form-card {
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 24px;
  padding: 36px 32px;
}
.moo-settings .moo-form-icon {
  font-size: 32px;
  color: var(--color-accent);
  margin-bottom: 16px;
}
.moo-settings .moo-form-card .settings_item_title {
  font-size: 22px;
  font-weight: 800;
  color: var(--color-text-primary);
  letter-spacing: -0.3px;
  line-height: 1.2;
  margin-bottom: 10px;
}
.moo-settings .moo-form-card .cn_subtext {
  color: rgba(255, 255, 255, 0.4);
  font-size: 14px;
  line-height: 1.6;
  margin-bottom: 28px;
}
.moo-settings .moo-form-card .cn_input_title {
  color: rgba(255, 255, 255, 0.4);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1px;
  margin-bottom: 8px;
}
.moo-settings .moo-form-card form {
  display: block;
}
.moo-settings .moo-form-card input[type="text"],
.moo-settings .moo-form-card input[type="tel"] {
  background: transparent !important;
  border: none !important;
  border-bottom: 2px solid rgba(255, 255, 255, 0.1) !important;
  border-radius: 0 !important;
  color: var(--color-text-primary) !important;
  padding: 14px 0 !important;
  font-size: 16px !important;
  font-weight: 500;
  font-family: 'Montserrat', sans-serif;
  width: 100% !important;
  margin: 0 0 24px 0 !important;
  -webkit-appearance: none;
  transition: border-color 0.3s;
  user-select: text;
  -webkit-user-select: text;
  touch-action: manipulation;
}
.moo-settings .moo-form-card input[type="text"]:focus,
.moo-settings .moo-form-card input[type="tel"]:focus {
  border-bottom-color: var(--color-accent) !important;
}
.moo-settings .moo-form-card input[readonly] {
  color: rgba(255, 255, 255, 0.4) !important;
  border-bottom-color: rgba(255, 255, 255, 0.05) !important;
}
.moo-settings .moo-form-card input[type="file"] {
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  color: rgba(255, 255, 255, 0.6);
  padding: 14px;
  font-size: 14px;
  font-family: 'Montserrat', sans-serif;
  width: calc(100% - 30px);
  margin-bottom: 24px;
  cursor: pointer;
}
.moo-settings .moo-form-card button[type="submit"] {
  background: linear-gradient(135deg, var(--color-accent), var(--color-accent-dark)) !important;
  color: var(--color-bg) !important;
  border: none !important;
  border-radius: 14px !important;
  padding: 16px 24px !important;
  font-weight: 700 !important;
  font-size: 16px !important;
  font-family: 'Montserrat', sans-serif;
  width: 100% !important;
  cursor: pointer;
  transition: opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1), transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.moo-settings .moo-form-card button[type="submit"]:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 32px rgba(0, 229, 160, 0.25);
}
.moo-settings .moo-form-card button[type="submit"]:active {
  transform: translateY(0) scale(0.98);
}

/* Bug report modal — frosted glass */
body:has(.moo-settings) #br_popup_wrap {
  background: rgba(6, 13, 16, 0.6);
  animation: mooOverlayIn 0.2s ease-out;
}
body:has(.moo-settings) #br_popup {
  background: rgba(20, 30, 38, 0.85);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 24px;
  padding: 32px;
  width: min(360px, 80%);
  color: var(--color-text-primary);
  animation: mooModalIn 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
body:has(.moo-settings) .br_popup_title {
  color: var(--color-text-primary);
  font-size: 18px;
  font-weight: 800;
  letter-spacing: -0.3px;
  margin-bottom: 20px;
}
body:has(.moo-settings) .br_form {
  gap: 12px;
}
body:has(.moo-settings) .br_selectbox {
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  color: var(--color-text-primary);
  padding: 14px 16px;
  font-size: 15px;
  font-weight: 500;
  font-family: 'Montserrat', sans-serif;
}
body:has(.moo-settings) .br_selectbox option {
  background: var(--color-bg-elevated);
  color: var(--color-text-primary);
}
body:has(.moo-settings) .br_textarea {
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  color: var(--color-text-primary);
  padding: 14px 16px;
  font-size: 15px;
  font-weight: 500;
  font-family: 'Montserrat', sans-serif;
  min-height: 100px;
  user-select: text;
  -webkit-user-select: text;
  touch-action: manipulation;
}
body:has(.moo-settings) .br_textarea::placeholder {
  color: rgba(255, 255, 255, 0.3);
  font-weight: 400;
}
body:has(.moo-settings) .br_submit_button {
  background: linear-gradient(135deg, var(--color-accent), var(--color-accent-dark)) !important;
  color: var(--color-bg) !important;
  border: none !important;
  border-radius: 14px !important;
  padding: 16px 24px !important;
  font-weight: 700 !important;
  font-size: 16px !important;
  font-family: 'Montserrat', sans-serif;
  width: 100% !important;
  cursor: pointer;
  transition: opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1), transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
body:has(.moo-settings) .br_submit_button:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 32px rgba(0, 229, 160, 0.25);
}

/* Styled file picker (replaces native file input) */
.moo-file-input {
  position: absolute;
  width: 0;
  height: 0;
  opacity: 0;
  pointer-events: none;
  overflow: hidden;
}
.moo-file-picker {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 20px;
  background: rgba(14, 22, 28, 0.90);
  border: 2px dashed rgba(255, 255, 255, 0.1);
  border-radius: 16px;
  cursor: pointer;
  transition: opacity 0.2s, background-color 0.2s, border-color 0.2s;
  margin-bottom: 0;
}
.moo-file-picker:hover {
  background: rgba(0, 229, 160, 0.04);
  border-color: rgba(0, 229, 160, 0.2);
}
.moo-file-picker:active {
  background: rgba(0, 229, 160, 0.08);
}
.moo-file-picker__icon {
  width: 44px;
  height: 44px;
  border-radius: 12px;
  background: rgba(0, 229, 160, 0.1);
  border: 1px solid rgba(0, 229, 160, 0.15);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-accent);
  font-size: 18px;
  flex-shrink: 0;
}
.moo-file-picker__text {
  flex: 1;
  min-width: 0;
}
.moo-file-picker__label {
  font-size: 15px;
  font-weight: 600;
  color: var(--color-text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.moo-file-picker__hint {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.3);
  margin-top: 2px;
}

/* ===== IMAGE CROP MODAL ===== */
#moo_crop_wrap {
  position: fixed;
  inset: 0;
  background: rgba(6, 13, 16, 0.8);
  z-index: 100000;
  animation: mooOverlayIn 0.2s ease-out;
}
#moo_crop_modal {
  position: absolute;
  inset: 0;
  display: none;
  flex-direction: column;
  background: var(--color-bg);
  color: var(--color-text-primary);
}
.moo-crop__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  padding-top: calc(16px + env(safe-area-inset-top, 0));
  flex-shrink: 0;
}
.moo-crop__title {
  font-size: 18px;
  font-weight: 800;
  letter-spacing: -0.3px;
}
#moo_crop_cancel {
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: rgba(18, 26, 32, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
  color: rgba(255, 255, 255, 0.5);
  font-size: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 0;
  margin: 0;
}
.moo-crop__stage {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 0;
  overflow: hidden;
  position: relative;
  touch-action: none;
}
.moo-crop__img-area {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
#moo_crop_img {
  position: absolute;
  user-select: none;
  -webkit-user-select: none;
  pointer-events: none;
  will-change: transform;
  opacity: 1 !important;
}
.moo-crop__frame {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  border: 2px solid rgba(255, 255, 255, 0.6);
  border-radius: 4px;
  box-shadow: 0 0 0 9999px rgba(6, 13, 16, 0.65);
  z-index: 2;
  pointer-events: none;
}
.moo-crop__corner {
  position: absolute;
  width: 20px;
  height: 20px;
  border-color: var(--color-accent);
  border-style: solid;
  border-width: 0;
}
.moo-crop__corner--tl { top: -2px; left: -2px; border-top-width: 3px; border-left-width: 3px; border-radius: 2px 0 0 0; }
.moo-crop__corner--tr { top: -2px; right: -2px; border-top-width: 3px; border-right-width: 3px; border-radius: 0 2px 0 0; }
.moo-crop__corner--bl { bottom: -2px; left: -2px; border-bottom-width: 3px; border-left-width: 3px; border-radius: 0 0 0 2px; }
.moo-crop__corner--br { bottom: -2px; right: -2px; border-bottom-width: 3px; border-right-width: 3px; border-radius: 0 0 2px 0; }

.moo-crop__controls {
  padding: 12px 24px;
  flex-shrink: 0;
}
.moo-crop__zoom {
  display: flex;
  align-items: center;
  gap: 14px;
}
.moo-crop__zoom button {
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: rgba(18, 26, 32, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
  color: var(--color-text-primary);
  font-size: 13px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 0;
  flex-shrink: 0;
  transition: opacity 0.2s, background-color 0.2s, color 0.2s, border-color 0.2s;
}
.moo-crop__zoom button:active {
  background: rgba(0, 229, 160, 0.15);
  border-color: rgba(0, 229, 160, 0.3);
  color: var(--color-accent);
}
.moo-crop__zoom-track {
  flex: 1;
  height: 4px;
  background: rgba(24, 32, 40, 0.92);
  border-radius: 2px;
  overflow: hidden;
}
.moo-crop__zoom-fill {
  height: 100%;
  width: 0%;
  background: var(--color-accent);
  border-radius: 2px;
  transition: width 0.15s ease;
}

.moo-crop__actions {
  display: flex;
  gap: 10px;
  padding: 16px 20px;
  padding-bottom: calc(16px + env(safe-area-inset-bottom, 0));
  flex-shrink: 0;
}
.moo-crop__btn-secondary {
  flex: 0.8;
  padding: 16px;
  background: rgba(18, 26, 32, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 14px;
  color: rgba(255, 255, 255, 0.6);
  font-weight: 600;
  font-size: 15px;
  font-family: 'Montserrat', sans-serif;
  cursor: pointer;
}
.moo-crop__btn-primary {
  flex: 1.2;
  padding: 16px;
  background: linear-gradient(135deg, var(--color-accent), var(--color-accent-dark));
  border: none;
  border-radius: 14px;
  color: var(--color-bg);
  font-weight: 700;
  font-size: 15px;
  font-family: 'Montserrat', sans-serif;
  cursor: pointer;
  transition: opacity 0.2s, transform 0.2s, box-shadow 0.2s;
}
.moo-crop__btn-primary:disabled {
  opacity: 0.7;
  cursor: default;
}

/* Upload progress overlay */
#moo_crop_uploading {
  position: absolute;
  inset: 0;
  background: rgba(6, 13, 16, 0.8);
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  z-index: 5;
}
.moo-crop__upload-spinner {
  font-size: 36px;
  color: var(--color-accent);
}
.moo-crop__upload-text {
  font-size: 16px;
  font-weight: 600;
  color: var(--color-text-primary);
}

/* Crop upload error state — inline retry panel (no more alerts). Sits over
 * the crop stage exactly like #moo_crop_uploading but with danger-themed icon
 * and a retry button that reuses the already-cropped blob. */
.moo-crop__error {
  position: absolute;
  inset: 0;
  background: rgba(6, 13, 16, 0.88);
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 32px 28px;
  z-index: 6;
  text-align: center;
}
.moo-crop__error-icon {
  width: 64px;
  height: 64px;
  border-radius: 18px;
  background: rgba(244, 63, 94, 0.12);
  border: 1px solid rgba(244, 63, 94, 0.3);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 26px;
  color: var(--color-danger);
  box-shadow: 0 10px 28px rgba(244, 63, 94, 0.15);
}
.moo-crop__error-text {
  font-family: 'Montserrat', sans-serif;
  font-size: 14px;
  font-weight: 600;
  color: var(--color-text-primary);
  max-width: 300px;
  line-height: 1.4;
}
.moo-crop__error-retry {
  margin-top: 4px;
  padding: 11px 22px;
  height: 42px;
  border-radius: 12px;
  border: none;
  background: linear-gradient(135deg, var(--color-accent), var(--color-accent-dark));
  color: var(--color-bg);
  font-family: 'Montserrat', sans-serif;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  letter-spacing: 0.02em;
  box-shadow: 0 8px 24px rgba(0, 229, 160, 0.25);
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}
.moo-crop__error-retry:hover {
  transform: translateY(-1px);
  box-shadow: 0 12px 30px rgba(0, 229, 160, 0.35);
}
.moo-crop__error-retry:active { transform: translateY(0); }

/* Settings responsive */
@media (max-width: 480px) {
  .moo-settings .moo-settings-card {
    padding: 20px;
    border-radius: 16px;
  }
  .moo-settings .moo-form-card {
    padding: 28px 24px;
    border-radius: 20px;
  }
  .moo-settings-card__icon {
    width: 32px;
    height: 32px;
    font-size: 13px;
  }
}

/* ===== TOOLS PAGE OVERHAUL ===== */

/* Page background */
html:has(.moo-tools) {
  background: var(--color-bg);
}
body:has(.moo-tools) {
  background:
    radial-gradient(ellipse at 65% 25%, rgba(14, 165, 233, 0.12) 0%, transparent 50%),
    radial-gradient(ellipse at 35% 75%, rgba(99, 102, 241, 0.1) 0%, transparent 50%),
    radial-gradient(ellipse at 50% 50%, rgba(244, 63, 94, 0.06) 0%, transparent 40%),
    var(--color-bg);
}

/* Header — dark glass */
body:has(.moo-tools) .chat_top_info.header_top {
  background: rgba(6, 13, 16, 0.97);
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
body:has(.moo-tools) .hb_button {
  background: rgba(24, 32, 40, 0.92);
  color: var(--color-text-primary);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 10px;
  transition: opacity 0.2s, background-color 0.2s, color 0.2s, border-color 0.2s;
}
body:has(.moo-tools) .hb_button:hover {
  background: rgba(0, 229, 160, 0.15);
  border-color: rgba(0, 229, 160, 0.3);
  color: var(--color-accent);
}
body:has(.moo-tools) .hb_button_multi {
  background: rgba(24, 32, 40, 0.92);
  color: var(--color-text-primary);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 10px;
  transition: opacity 0.2s, background-color 0.2s, color 0.2s, border-color 0.2s;
}
body:has(.moo-tools) .hb_button_multi:hover {
  background: rgba(0, 229, 160, 0.15);
  border-color: rgba(0, 229, 160, 0.3);
  color: var(--color-accent);
}

/* Bottom nav — dark glass */
body:has(.moo-tools) .bottom_nav {
  background: rgba(6, 13, 16, 0.97);
  border-top: 1px solid rgba(255, 255, 255, 0.06);
}
body:has(.moo-tools) .bnm_inner,
body:has(.moo-tools) .bnm_item {
  background: rgba(6, 13, 16, 0.85);
}
body:has(.moo-tools) .bnm_item {
  color: rgba(255, 255, 255, 0.3);
}
body:has(.moo-tools) .bnm_selected {
  color: var(--color-accent);
}

/* Content area */
.moo-tools {
  background: transparent !important;
  color: var(--color-text-primary);
  padding-top: 20px !important;
  padding-bottom: 20px !important;
  height: calc(100% - 174px) !important;
}

/* ---- Tools list items (main page) ---- */
.moo-tools__item {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 20px;
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 18px;
  color: var(--color-text-primary);
  text-decoration: none;
  margin-bottom: 12px;
  transition: opacity 0.25s cubic-bezier(0.4, 0, 0.2, 1), background-color 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}
.moo-tools__item:last-child,
.moo-tools__item:last-of-type {
  margin-bottom: 0;
}
.moo-tools__item:active {
  background: rgba(24, 32, 40, 0.92);
}
.moo-tools__item-icon {
  width: 44px;
  height: 44px;
  border-radius: 14px;
  background: rgba(0, 229, 160, 0.1);
  border: 1px solid rgba(0, 229, 160, 0.15);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-accent);
  font-size: 18px;
  flex-shrink: 0;
}
.moo-tools__item-icon--dev {
  background: rgba(99, 102, 241, 0.1);
  border-color: rgba(99, 102, 241, 0.2);
  color: var(--color-dev);
}
.moo-tools__item-info {
  flex: 1;
  min-width: 0;
}
.moo-tools__item-name {
  font-size: 17px;
  font-weight: 700;
  color: var(--color-text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.moo-tools__item-desc {
  font-size: 13px;
  color: rgba(255, 255, 255, 0.35);
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.moo-tools__item-arrow {
  color: rgba(255, 255, 255, 0.15);
  font-size: 14px;
  flex-shrink: 0;
}
.moo-tools__empty {
  color: rgba(255, 255, 255, 0.35);
  text-align: center;
  padding: 60px 0;
  font-size: 15px;
}

/* ---- Medication list items ---- */
.moo-tools__med-item {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 18px 20px;
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 16px;
  color: var(--color-text-primary);
  text-decoration: none;
  margin-bottom: 10px;
  transition: opacity 0.25s, background-color 0.25s, border-color 0.25s;
}
.moo-tools__med-item:last-child,
.moo-tools__med-item:last-of-type {
  margin-bottom: 0;
}
.moo-tools__med-item:active {
  background: rgba(24, 32, 40, 0.92);
}
.moo-tools__med-item.moo-med-due {
  border-color: rgba(0, 229, 160, 0.2);
  background: rgba(0, 229, 160, 0.04);
}
.moo-tools__med-info {
  flex: 1;
  min-width: 0;
}
.moo-tools__med-name {
  font-size: 17px;
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.moo-med-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 6px;
}
.moo-med-due-badge {
  font-size: 11px;
  font-weight: 700;
  padding: 3px 8px;
  border-radius: 6px;
  background: var(--color-accent);
  color: var(--color-bg);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}
.moo-tools__med-detail {
  font-size: 14px;
  color: rgba(255, 255, 255, 0.4);
  margin-top: 3px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Medication taken banner */
.moo-med-taken-banner {
  margin-bottom: 16px;
}
.moo-med-taken-banner button {
  width: 100%;
  padding: 16px 24px;
  background: linear-gradient(135deg, var(--color-accent), var(--color-accent-dark));
  border: none;
  border-radius: 14px;
  color: var(--color-bg);
  font-weight: 700;
  font-size: 16px;
  font-family: 'Montserrat', sans-serif;
  cursor: pointer;
  transition: opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1), transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.moo-med-taken-banner button:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 32px rgba(0, 229, 160, 0.25);
}
.moo-med-taken-banner button:active {
  transform: translateY(0) scale(0.98);
}

/* Medication reorder banner */
.moo-med-reorder-banner {
  margin-bottom: 16px;
  background: rgba(251, 191, 36, 0.06);
  border: 1px solid rgba(251, 191, 36, 0.15);
  border-radius: 14px;
  padding: 16px 20px;
}
.moo-med-reorder-banner__label {
  color: var(--color-warning);
  font-size: 14px;
  font-weight: 700;
  margin-bottom: 12px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.moo-med-reorder-banner button {
  width: 100%;
  padding: 12px 24px;
  background: rgba(251, 191, 36, 0.12);
  border: 1px solid rgba(251, 191, 36, 0.25);
  border-radius: 10px;
  color: var(--color-warning);
  font-weight: 700;
  font-size: 15px;
  font-family: 'Montserrat', sans-serif;
  cursor: pointer;
  transition: opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1), transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.moo-med-reorder-banner button:active {
  transform: scale(0.98);
}

/* Medication reorder list badges */
.moo-med-reorder-badge,
.moo-med-reorder-badge--overdue {
  font-size: 11px;
  font-weight: 700;
  padding: 3px 8px;
  border-radius: 6px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  display: inline-block;
}
.moo-med-reorder-badge {
  background: rgba(251, 191, 36, 0.15);
  color: var(--color-warning);
}
.moo-med-reorder-badge--overdue {
  background: rgba(244, 63, 94, 0.15);
  color: var(--color-danger);
}
.moo-tools__med-item.moo-med-reorder-due {
  border-color: rgba(251, 191, 36, 0.2);
  background: rgba(251, 191, 36, 0.04);
}

/* Medication date input */
.moo-tools .moo-settings-card input[type="date"],
.moo-tools .moo-form-card input[type="date"] {
  color-scheme: dark;
}

/* Medication custom date picker */
.moo-med-datepicker {
  margin-top: 12px;
  background: rgba(14, 22, 28, 0.90);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 14px;
  padding: 12px;
  animation: mooCalIn 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  overflow: hidden;
  box-sizing: border-box;
}
@keyframes mooCalIn {
  from { opacity: 0; transform: translateY(-8px); }
  to { opacity: 1; transform: translateY(0); }
}
.moo-med-datepicker__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 14px;
}
.moo-med-datepicker__nav {
  width: 38px;
  height: 38px;
  border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, 0.08);
  background: rgba(14, 22, 28, 0.92);
  color: var(--color-text-primary);
  font-size: 13px;
  font-family: 'Montserrat', sans-serif;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: opacity 0.2s, background-color 0.2s, border-color 0.2s, transform 0.2s;
  padding: 0;
  -webkit-tap-highlight-color: transparent;
}
.moo-med-datepicker__nav:active {
  background: rgba(0, 229, 160, 0.12);
  border-color: rgba(0, 229, 160, 0.25);
  transform: scale(0.92);
}
.moo-med-datepicker__nav--disabled {
  opacity: 0.15;
  pointer-events: none;
}
.moo-med-datepicker__title {
  font-size: 15px;
  font-weight: 700;
  color: var(--color-text-primary);
}
.moo-med-datepicker__weekdays {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  margin-bottom: 4px;
}
.moo-med-datepicker__weekday {
  text-align: center;
  font-size: 11px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.25);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  padding: 4px 0;
}
.moo-med-datepicker__days {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  grid-gap: 4px;
  gap: 4px;
}
.moo-med-datepicker__day {
  height: 36px;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  font-weight: 500;
  color: var(--color-text-primary);
  border-radius: 10px;
  cursor: pointer;
  transition: opacity 0.15s, background-color 0.15s, color 0.15s, border-color 0.15s, transform 0.15s;
  border: 1px solid transparent;
  background: none;
  padding: 0;
  font-family: 'Montserrat', sans-serif;
  -webkit-tap-highlight-color: transparent;
}
.moo-med-datepicker__day:active:not(.moo-med-datepicker__day--past):not(.moo-med-datepicker__day--empty) {
  transform: scale(0.88);
  background: rgba(0, 229, 160, 0.15);
}
.moo-med-datepicker__day--empty {
  cursor: default;
}
.moo-med-datepicker__day--past {
  color: rgba(255, 255, 255, 0.12);
  cursor: default;
}
.moo-med-datepicker__day--today {
  background: rgba(0, 229, 160, 0.1);
  border-color: rgba(0, 229, 160, 0.25);
  color: var(--color-accent);
  font-weight: 700;
}
.moo-med-datepicker__day--selected {
  background: linear-gradient(135deg, var(--color-accent), var(--color-accent-dark));
  color: var(--color-bg);
  font-weight: 700;
  border-color: transparent;
}
/* Override generic button styles on datepicker day cells */
.moo-med-datepicker__day {
  padding: 0 !important;
  margin: 3px !important;
  height: 36px !important;
}

/* Medication detail cards — reuse settings card styles */
.moo-tools .moo-settings-card {
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 20px;
  padding: 24px;
  margin-bottom: 16px;
}
.moo-tools .moo-settings-card:last-child,
.moo-tools .moo-settings-card:last-of-type,
.moo-tools .moo-form-card:last-child,
.moo-tools .moo-form-card:last-of-type {
  margin-bottom: 0;
}
.moo-tools .moo-settings-card__header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
}
.moo-tools .moo-settings-card__icon {
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: rgba(0, 229, 160, 0.1);
  border: 1px solid rgba(0, 229, 160, 0.15);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-accent);
  font-size: 14px;
  flex-shrink: 0;
}
.moo-tools .moo-settings-card .settings_item_title {
  color: var(--color-text-primary);
  font-size: 17px;
  font-weight: 700;
  margin-bottom: 0;
  line-height: 1;
}
.moo-tools .moo-settings-card__value {
  color: rgba(255, 255, 255, 0.5);
  font-size: 15px;
}
.moo-tools .moo-settings-card form {
  display: flex;
  gap: 10px;
}
.moo-tools .moo-settings-card input[type="text"],
.moo-tools .moo-settings-card input[type="tel"],
.moo-tools .moo-settings-card input[type="time"],
.moo-tools .moo-settings-card input[type="date"] {
  flex: 1;
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  color: var(--color-text-primary);
  padding: 12px 16px;
  font-size: 15px;
  font-weight: 500;
  font-family: 'Montserrat', sans-serif;
  width: auto;
  height: auto;
  margin: 0;
  transition: border-color 0.3s;
  -webkit-appearance: none;
  user-select: text;
  -webkit-user-select: text;
  touch-action: manipulation;
}
.moo-tools .moo-settings-card input:focus {
  border-color: rgba(0, 229, 160, 0.4);
}
.moo-tools .moo-settings-card select {
  flex: 1;
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  color: var(--color-text-primary);
  padding: 12px 16px;
  font-size: 15px;
  font-weight: 500;
  font-family: 'Montserrat', sans-serif;
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  width: auto;
  margin: 0;
}
.moo-tools .moo-settings-card select option {
  background: var(--color-bg-elevated);
  color: var(--color-text-primary);
}
.moo-tools .moo-settings-card button[type="submit"],
.moo-tools .moo-settings-card button[type="button"] {
  background: rgba(18, 26, 32, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  color: var(--color-text-primary);
  padding: 12px 20px;
  font-size: 14px;
  font-weight: 700;
  font-family: 'Montserrat', sans-serif;
  cursor: pointer;
  transition: opacity 0.2s, background-color 0.2s, color 0.2s, border-color 0.2s;
  white-space: nowrap;
  width: auto;
  height: auto;
  margin: 0;
}
.moo-tools .moo-settings-card button[type="submit"]:hover,
.moo-tools .moo-settings-card button[type="button"]:hover {
  background: rgba(0, 229, 160, 0.1);
  border-color: rgba(0, 229, 160, 0.25);
  color: var(--color-accent);
}

/* Form cards (new medication) — reuse pattern */
.moo-tools .moo-form-card {
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 24px;
  padding: 36px 32px;
}
.moo-tools .moo-form-icon {
  font-size: 32px;
  color: var(--color-accent);
  margin-bottom: 16px;
}
.moo-tools .moo-form-card .settings_item_title {
  color: var(--color-text-primary);
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -0.3px;
  line-height: 1.2;
}
.moo-tools .moo-form-card .cn_subtext {
  color: rgba(255, 255, 255, 0.4);
  font-size: 14px;
  line-height: 1.6;
  margin-bottom: 28px;
}
/* ALM-061(d): generic tool-wide subtext helper, relocated here from the alarm
   block where it was mis-filed. Applies to ALL tools (not alarm-specific). */
.moo-tools .cn_subtext {
  color: rgba(255, 255, 255, 0.50);
  font: 500 12px/1.45 'Montserrat', sans-serif;
  margin-top: 12px;
}
.moo-tools .moo-form-card .cn_input_title {
  color: rgba(255, 255, 255, 0.4);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1px;
  margin-bottom: 8px;
  margin-top: 20px;
}
.moo-tools .moo-form-card .cn_input_title:first-of-type {
  margin-top: 0;
}
.moo-tools .moo-form-card form {
  display: block;
}
.moo-tools .moo-form-card input[type="text"],
.moo-tools .moo-form-card input[type="time"],
.moo-tools .moo-form-card input[type="date"] {
  background: transparent !important;
  border: none !important;
  border-bottom: 2px solid rgba(255, 255, 255, 0.1) !important;
  border-radius: 0 !important;
  color: var(--color-text-primary) !important;
  padding: 14px 0 !important;
  font-size: 16px !important;
  font-weight: 500;
  font-family: 'Montserrat', sans-serif;
  width: 100% !important;
  height: auto !important;
  margin: 0 0 4px 0 !important;
  -webkit-appearance: none;
  transition: border-color 0.3s;
  user-select: text;
  -webkit-user-select: text;
  touch-action: manipulation;
}
.moo-tools .moo-form-card input[type="text"]:focus,
.moo-tools .moo-form-card input[type="time"]:focus,
.moo-tools .moo-form-card input[type="date"]:focus {
  border-bottom-color: var(--color-accent) !important;
}
.moo-tools .moo-form-card input::placeholder {
  color: rgba(255, 255, 255, 0.2);
}
.moo-tools .moo-form-card select {
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  color: var(--color-text-primary);
  padding: 14px 16px;
  font-size: 15px;
  font-weight: 500;
  font-family: 'Montserrat', sans-serif;
  width: 100%;
  margin-bottom: 4px;
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
}
.moo-tools .moo-form-card select option {
  background: var(--color-bg-elevated);
  color: var(--color-text-primary);
}
.moo-tools .moo-form-card button[type="submit"] {
  background: linear-gradient(135deg, var(--color-accent), var(--color-accent-dark)) !important;
  color: var(--color-bg) !important;
  border: none !important;
  border-radius: 14px !important;
  padding: 16px 24px !important;
  font-weight: 700 !important;
  font-size: 16px !important;
  font-family: 'Montserrat', sans-serif;
  width: 100% !important;
  margin-top: 24px !important;
  cursor: pointer;
  transition: opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1), transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.moo-tools .moo-form-card button[type="submit"]:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 32px rgba(0, 229, 160, 0.25);
}

/* ---- Monthly Bills tool ---- */
.moo-bill-section {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1.2px;
  color: rgba(255, 255, 255, 0.35);
  padding: 4px 4px 12px;
  margin-top: 18px;
}
.moo-bill-section:first-child { margin-top: 0; }

.moo-bill-item {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 18px 20px;
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 16px;
  color: var(--color-text-primary);
  text-decoration: none;
  margin-bottom: 10px;
  transition: opacity 0.25s, background-color 0.25s, border-color 0.25s, transform 0.25s;
}
.moo-bill-item:last-child,
.moo-bill-item:last-of-type { margin-bottom: 0; }
.moo-bill-item:active {
  background: rgba(24, 32, 40, 0.92);
  transform: scale(0.99);
}
.moo-bill-item--next {
  border-color: rgba(0, 229, 160, 0.22);
  background:
    linear-gradient(135deg, rgba(0, 229, 160, 0.06), transparent 55%),
    rgba(14, 22, 28, 0.92);
}
.moo-bill-item--past .moo-bill-item__name,
.moo-bill-item--past .moo-bill-item__amount { color: rgba(255, 255, 255, 0.45); }
.moo-bill-item--past .moo-bill-item__due { color: rgba(255, 255, 255, 0.28); }
.moo-bill-item--past .moo-bill-item__chevron { color: rgba(255, 255, 255, 0.18); }
.moo-bill-item__info { flex: 1; min-width: 0; }
.moo-bill-item__name {
  font-size: 16px;
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  letter-spacing: -0.1px;
}
.moo-bill-item__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 6px;
  align-items: center;
}
.moo-bill-item__due {
  font-size: 12px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.4);
  letter-spacing: 0.2px;
}
.moo-bill-item__shared {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  padding: 3px 8px 3px 7px;
  border-radius: 6px;
  background: rgba(56, 189, 248, 0.12);
  color: var(--color-accent-sky);
  border: 1px solid rgba(56, 189, 248, 0.18);
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
.moo-bill-item__shared i { font-size: 9px; }
.moo-bill-item__amount {
  font-variant-numeric: tabular-nums;
  font-size: 18px;
  font-weight: 800;
  color: var(--color-text-primary);
  letter-spacing: -0.4px;
  flex-shrink: 0;
}
.moo-bill-item__chevron {
  color: rgba(255, 255, 255, 0.25);
  font-size: 12px;
  flex-shrink: 0;
}

.moo-bill-amount-wrap { position: relative; }
.moo-bill-amount-wrap::before {
  content: '£';
  position: absolute;
  left: 0;
  top: 14px;
  font-size: 16px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.45);
  pointer-events: none;
  z-index: 1;
}
.moo-tools .moo-form-card .moo-bill-amount-wrap input { padding-left: 14px !important; }
.moo-tools .moo-settings-card .moo-bill-amount-wrap { flex: 1; display: flex; }
.moo-tools .moo-settings-card .moo-bill-amount-wrap::before {
  left: 14px;
  top: 50%;
  transform: translateY(-50%);
}
.moo-tools .moo-settings-card .moo-bill-amount-wrap input { padding-left: 28px !important; }

.moo-bill-share-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 14px 16px;
  background: rgba(14, 22, 28, 0.6);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 14px;
  margin-top: 8px;
  cursor: pointer;
}
.moo-bill-share-row__text { flex: 1; min-width: 0; }
.moo-bill-share-row__label {
  display: block;
  font-size: 14px;
  font-weight: 700;
  color: var(--color-text-primary);
}
.moo-bill-share-row__desc {
  display: block;
  font-size: 12px;
  color: rgba(255, 255, 255, 0.4);
  margin-top: 3px;
  line-height: 1.4;
}

/* Shared card on edit page — row inside settings card */
.moo-bill-shared-card__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  width: 100%;
}
.moo-bill-shared-card__desc {
  flex: 1;
  font-size: 13px;
  color: rgba(255, 255, 255, 0.5);
  line-height: 1.4;
}
/* Override the .moo-tools .moo-settings-card form { display: flex; gap: 10px } so the
   shared toggle row stretches naturally; we only have one child here. */
.moo-tools .moo-bill-shared-card form {
  display: block;
}

/* Empty state — vertically centered hero with CTA */
.moo-bill-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 0 24px;
  min-height: 100%;
  box-sizing: border-box;
}
.moo-bill-empty::before,
.moo-bill-empty::after {
  content: '';
  flex: 1 0 24px;
}
.moo-bill-empty__icon {
  width: 72px;
  min-width: 72px;
  height: 72px;
  min-height: 72px;
  flex-shrink: 0;
  border-radius: 22px;
  background: rgba(0, 229, 160, 0.08);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 28px;
  color: var(--color-accent);
  margin-bottom: 20px;
  box-shadow: 0 0 40px rgba(0, 229, 160, 0.08);
}
.moo-bill-empty__title {
  font-size: 20px;
  font-weight: 800;
  color: var(--color-text-primary);
  margin-bottom: 8px;
  letter-spacing: -0.3px;
}
.moo-bill-empty__subtitle {
  font-size: 13px;
  color: rgba(255, 255, 255, 0.4);
  line-height: 1.5;
  max-width: 280px;
  margin-bottom: 28px;
}
.moo-bill-empty__cta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 14px 24px;
  background: linear-gradient(135deg, var(--color-accent), var(--color-accent-dark));
  color: var(--color-bg);
  border-radius: 14px;
  font-weight: 700;
  font-size: 15px;
  font-family: 'Montserrat', sans-serif;
  text-decoration: none;
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.moo-bill-empty__cta:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 32px rgba(0, 229, 160, 0.25);
}
.moo-bill-empty__cta:active { transform: scale(0.98); }

#bills_sum_wrap {
  position: absolute;
  inset: 0;
  background: rgba(6, 13, 16, 0.6);
  z-index: 999;
  animation: mooOverlayIn 0.2s ease-out;
}
#bills_sum_modal {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: none;
  flex-direction: column;
  background: rgba(20, 30, 38, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 24px;
  width: min(420px, calc(100% - 48px));
  max-height: calc(100vh - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px) - 48px);
  max-height: calc(100dvh - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px) - 48px);
  z-index: 9999;
  color: var(--color-text-primary);
  animation: mooModalIn 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  overflow: hidden;
}

.moo-bill-sum__hero {
  position: relative;
  border-radius: 24px 24px 0 0;
  overflow: hidden;
  -webkit-mask-image: -webkit-radial-gradient(white, black);
  clip-path: inset(0 round 24px 24px 0 0);
  padding: 38px 24px 26px;
  text-align: center;
  background: linear-gradient(180deg, rgba(0, 229, 160, 0.05), transparent 80%);
}
.moo-bill-sum__hero::before {
  content: '';
  position: absolute;
  width: 320px;
  height: 320px;
  top: -110px;
  left: 50%;
  transform: translateX(-50%);
  background: radial-gradient(circle, rgba(0, 229, 160, 0.22), transparent 60%);
  filter: blur(44px);
  pointer-events: none;
  z-index: 0;
}
.moo-bill-sum__hero > * { position: relative; z-index: 1; }
.moo-bill-sum__eyebrow {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 2px;
  color: rgba(255, 255, 255, 0.45);
  margin-bottom: 12px;
}
.moo-bill-sum__total {
  font-size: 44px;
  font-weight: 800;
  letter-spacing: -1.4px;
  font-variant-numeric: tabular-nums;
  color: var(--color-text-primary);
  line-height: 1;
}
.moo-bill-sum__total-label {
  font-size: 13px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.4);
  margin-top: 10px;
}

.moo-bill-sum__breakdown {
  padding: 8px 24px 16px;
}
.moo-bill-sum-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 4px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}
.moo-bill-sum-row:last-child { border-bottom: none; }
.moo-bill-sum-row__icon {
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.08);
  display: flex;
  align-items: center;
  justify-content: center;
  color: rgba(255, 255, 255, 0.55);
  font-size: 14px;
  flex-shrink: 0;
}
.moo-bill-sum-row--shared .moo-bill-sum-row__icon {
  background: rgba(56, 189, 248, 0.1);
  border-color: rgba(56, 189, 248, 0.18);
  color: var(--color-accent-sky);
}
.moo-bill-sum-row--week .moo-bill-sum-row__icon {
  background: rgba(0, 229, 160, 0.12);
  border-color: rgba(0, 229, 160, 0.22);
  color: var(--color-accent);
}
.moo-bill-sum-row__text { flex: 1; min-width: 0; }
.moo-bill-sum-row__label {
  font-size: 14px;
  font-weight: 700;
  color: var(--color-text-primary);
}
.moo-bill-sum-row__sub {
  font-size: 11px;
  color: rgba(255, 255, 255, 0.4);
  margin-top: 3px;
}
.moo-bill-sum-row__value {
  font-variant-numeric: tabular-nums;
  font-size: 17px;
  font-weight: 800;
  letter-spacing: -0.4px;
  color: var(--color-text-primary);
  flex-shrink: 0;
  text-align: right;
  min-width: 92px;
}
.moo-bill-sum-row--week .moo-bill-sum-row__value { color: var(--color-accent); }

.moo-bill-sum__close {
  box-sizing: border-box;
  margin: 0 24px 24px;
  padding: 14px 20px;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.1);
  color: var(--color-text-primary);
  font-size: 14px;
  font-weight: 700;
  font-family: 'Montserrat', sans-serif;
  cursor: pointer;
  transition: background-color 0.2s, border-color 0.2s, color 0.2s;
}
.moo-bill-sum__close:hover {
  background: rgba(255, 255, 255, 0.1);
  border-color: rgba(255, 255, 255, 0.15);
}
.moo-bill-sum__close:active {
  background: rgba(255, 255, 255, 0.14);
}

/* Delete confirm modal — reuses .moo-nc-modal__ shell */
#bill_del_wrap {
  position: absolute;
  inset: 0;
  background: rgba(6, 13, 16, 0.6);
  z-index: 999;
  animation: mooOverlayIn 0.2s ease-out;
}
#bill_del_modal {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: none;
  flex-direction: column;
  background: rgba(20, 30, 38, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 24px;
  width: min(380px, calc(100% - 48px));
  max-height: calc(100vh - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px) - 48px);
  max-height: calc(100dvh - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px) - 48px);
  z-index: 9999;
  color: var(--color-text-primary);
  animation: mooModalIn 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  overflow: hidden;
}
.moo-bill-del__msg {
  font-size: 14px;
  color: rgba(255, 255, 255, 0.55);
  line-height: 1.55;
  text-align: center;
}
.moo-bill-del__msg strong {
  color: var(--color-text-primary);
  font-weight: 700;
  word-break: break-word;
}
#bill_del_modal .moo-da-modal__actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
}



/* Note lock screen */
.moo-note-lock {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  height: 100%;
  min-height: 0;
  padding: 40px 24px;
}
.moo-note-lock__icon {
  width: 72px;
  height: 72px;
  border-radius: 22px;
  background: rgba(0, 229, 160, 0.06);
  border: 1px solid rgba(0, 229, 160, 0.12);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 28px;
  color: var(--color-accent);
  margin-bottom: 20px;
  box-shadow: 0 0 40px rgba(0, 229, 160, 0.08);
}
.moo-note-lock__title {
  font-size: 20px;
  font-weight: 800;
  color: var(--color-text-primary);
  letter-spacing: -0.3px;
  margin-bottom: 6px;
  max-width: 280px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.moo-note-lock__subtitle {
  font-size: 13px;
  color: rgba(255, 255, 255, 0.3);
  margin-bottom: 28px;
}
.moo-note-lock__form {
  width: 100%;
  max-width: 280px;
}
.moo-pw-mask {
  -webkit-text-security: disc;
  text-security: disc;
}
.moo-note-lock__input {
  width: calc(100% - 36px);
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 14px;
  color: var(--color-text-primary);
  padding: 16px 18px;
  font-size: 16px;
  font-weight: 500;
  font-family: 'Montserrat', sans-serif;
  outline: none;
  text-align: center;
  letter-spacing: 2px;
  -webkit-appearance: none;
  transition: border-color 0.2s;
}
.moo-note-lock__input:focus {
  border-color: rgba(0, 229, 160, 0.4);
}
.moo-note-lock__input::placeholder {
  color: rgba(255, 255, 255, 0.2);
  letter-spacing: 0;
}
.moo-note-lock__error {
  font-size: 12px;
  color: var(--color-danger);
  font-weight: 600;
  margin-top: 8px;
}
.moo-note-lock__error:empty {
  display: none;
}
.moo-note-lock__btn {
  width: 100%;
  padding: 16px;
  background: linear-gradient(135deg, var(--color-accent), var(--color-accent-dark));
  border: none;
  border-radius: 14px;
  color: var(--color-bg);
  font-size: 15px;
  font-weight: 700;
  font-family: 'Montserrat', sans-serif;
  cursor: pointer;
  transition: opacity 0.2s, transform 0.2s;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 12px;
}
.moo-note-lock__btn:active {
  transform: scale(0.97);
}

/* ===== CHAT PASSWORD ENCRYPTION ===== */

/* Chat lock screen — fills chat content area below header */
.moo-chat-lock {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 40px 24px;
  height: calc(100% - 84px);
  min-height: 0;
  box-sizing: border-box;
}
.moo-chat-lock .moo-note-lock__icon {
  flex-shrink: 0;
  min-width: 72px;
  min-height: 72px;
  box-shadow: 0 0 60px rgba(0, 229, 160, 0.1);
}

/* Pending-access banner — sits above the composer when a send is rejected
   because our share is still pending (stale cached DEK after a re-invite).
   Neutral surface, not mint: this is a calm waiting state, not a CTA or an
   error. Hourglass mirrors the full-screen pending lock so both surfaces read
   as one thing. */
.moo-chat-access-banner {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 10px 12px 0;
  padding: 12px 14px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: 14px;
  z-index: 5;
}
.moo-chat-access-banner__icon {
  width: 36px;
  height: 36px;
  min-width: 36px;
  border-radius: 10px;
  background: rgba(0, 229, 160, 0.12);
  color: var(--color-accent);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
}
.moo-chat-access-banner__text {
  flex: 1;
  min-width: 0;
}
.moo-chat-access-banner__title {
  font-family: 'Montserrat', sans-serif;
  font-size: 13px;
  font-weight: 700;
  color: var(--color-text-primary);
  letter-spacing: -0.01em;
}
.moo-chat-access-banner__desc {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.45);
  margin-top: 2px;
  line-height: 1.4;
}
.moo-chat-access-banner__btn {
  flex-shrink: 0;
  padding: 8px 14px;
  border: none;
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.10);
  color: var(--color-text-primary);
  font-family: 'Montserrat', sans-serif;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: transform 0.15s ease, background 0.15s ease;
}
.moo-chat-access-banner__btn:hover {
  background: rgba(255, 255, 255, 0.16);
}
.moo-chat-access-banner__btn:active {
  transform: scale(0.94);
}

/* Composer dimmed + inert while access is pending (draft stays readable). */
#moo_chat_input_row.moo-input-locked {
  opacity: 0.5;
  pointer-events: none;
}

/* Chat migration overlay — shown while a legacy chat is being upgraded to E2EE.
   Same vertical rhythm as the lock screen, but with a pulsing shield halo to
   signal activity + a rotating status line that updates as phases complete. */
.moo-chat-migrate {
  position: absolute;
  inset: 0;
  background: var(--color-bg);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 40px 24px;
  z-index: 20;
  box-sizing: border-box;
  gap: 6px;
}
.moo-chat-migrate__halo {
  position: relative;
  width: 96px;
  height: 96px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 22px;
}
.moo-chat-migrate__ring {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 1.5px solid rgba(0, 229, 160, 0.35);
  animation: moo-chat-migrate-pulse 1.8s cubic-bezier(0.25, 0.8, 0.4, 1) infinite;
}
.moo-chat-migrate__ring--delay {
  animation-delay: 0.6s;
}
.moo-chat-migrate__icon {
  position: relative;
  width: 72px;
  height: 72px;
  border-radius: 50%;
  background: rgba(0, 229, 160, 0.1);
  border: 1px solid rgba(0, 229, 160, 0.25);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-accent);
  font-size: 28px;
  box-shadow: 0 0 40px rgba(0, 229, 160, 0.15);
}
@keyframes moo-chat-migrate-pulse {
  0%   { transform: scale(1);   opacity: 0.85; }
  100% { transform: scale(1.6); opacity: 0; }
}
.moo-chat-migrate__title {
  font-family: 'Montserrat', sans-serif;
  font-size: 17px;
  font-weight: 700;
  color: var(--color-text-primary);
  letter-spacing: -0.01em;
}
.moo-chat-migrate__subtitle {
  font-size: 13px;
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.42);
  max-width: 280px;
  margin-top: 4px;
}
.moo-chat-migrate__status {
  margin-top: 14px;
  padding: 8px 14px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.08);
  font-size: 12px;
  color: rgba(255, 255, 255, 0.55);
  font-weight: 500;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.moo-chat-migrate__status i {
  color: var(--color-accent);
  font-size: 10px;
}

/* Chat info — encryption status */
.moo-enc-e2ee-desc {
  font-size: 13px;
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.4);
}
.moo-enc-lock-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
}
.moo-enc-lock-row__title {
  font-size: 14px;
  color: var(--color-text-primary);
  font-weight: 600;
}
.moo-enc-lock-row__desc {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.3);
  margin-top: 3px;
}

/* Enable encryption button */
.moo-enc-enable-btn {
  width: 100%;
  padding: 14px 20px;
  background: linear-gradient(135deg, var(--color-accent), var(--color-accent-dark));
  border: none;
  border-radius: 12px;
  color: var(--color-bg);
  font-size: 15px;
  font-weight: 700;
  font-family: 'Montserrat', sans-serif;
  cursor: pointer;
  transition: opacity 0.2s, transform 0.2s, box-shadow 0.2s;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.moo-enc-enable-btn:active {
  transform: scale(0.97);
}



/* Invite code modal */
#ic_wrap {
  position: absolute;
  inset: 0;
  background: rgba(6, 13, 16, 0.6);
  z-index: 999;
  animation: mooOverlayIn 0.2s ease-out;
}
#ic_modal {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: none;
  flex-direction: column;
  background: rgba(20, 30, 38, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 24px;
  width: min(380px, calc(100% - 48px));
  max-height: calc(100vh - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px) - 48px);
  max-height: calc(100dvh - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px) - 48px);
  z-index: 9999;
  color: var(--color-text-primary);
  animation: mooModalIn 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  overflow: hidden;
}

/* Settings account modals (username, password, recovery key) */
#cu_wrap, #cp_wrap, #rk_wrap, #tf_wrap, #tfd_wrap {
  position: absolute;
  inset: 0;
  background: rgba(6, 13, 16, 0.6);
  z-index: 999;
  animation: mooOverlayIn 0.2s ease-out;
}
#cu_modal, #cp_modal, #rk_modal, #tf_modal, #tfd_modal {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: none;
  flex-direction: column;
  background: rgba(20, 30, 38, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 24px;
  width: min(380px, calc(100% - 48px));
  max-height: calc(100vh - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px) - 48px);
  max-height: calc(100dvh - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px) - 48px);
  z-index: 9999;
  color: var(--color-text-primary);
  animation: mooModalIn 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  overflow: hidden;
}


.moo-nc-modal__header {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 28px 24px 0;
  flex-shrink: 0;
}
.moo-nc-modal__icon {
  width: 48px;
  height: 48px;
  border-radius: 14px;
  background: rgba(0, 229, 160, 0.1);
  border: 1px solid rgba(0, 229, 160, 0.15);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  color: var(--color-accent);
}
.moo-nc-modal__title {
  font-size: 18px;
  font-weight: 700;
  text-align: center;
}
.moo-nc-modal__body {
  padding: 20px 24px;
  overflow-y: auto;
  overscroll-behavior: none;
}
.moo-nc-modal__input {
  width: 100%;
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 14px;
  color: var(--color-text-primary);
  padding: 16px 18px;
  font-size: 16px;
  font-weight: 600;
  font-family: 'Montserrat', sans-serif;
  outline: none;
  -webkit-appearance: none;
  transition: border-color 0.2s;
  box-sizing: border-box;
  user-select: text;
  -webkit-user-select: text;
}
.moo-nc-modal__input:focus {
  border-color: rgba(0, 229, 160, 0.4);
}
.moo-nc-modal__input::placeholder {
  color: rgba(255, 255, 255, 0.2);
  font-weight: 400;
}
.moo-nc-modal__actions {
  display: flex;
  gap: 10px;
  padding: 0 24px 24px;
}
.moo-nc-modal__create {
  flex: 1;
  padding: 14px 20px;
  border-radius: 12px;
  background: linear-gradient(135deg, var(--color-accent), var(--color-accent-dark));
  border: none;
  color: var(--color-bg);
  font-size: 14px;
  font-weight: 700;
  font-family: 'Montserrat', sans-serif;
  cursor: pointer;
  transition: opacity 0.2s, box-shadow 0.2s;
  white-space: nowrap;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}
.moo-nc-modal__create:hover:not(:disabled) {
  box-shadow: 0 8px 24px rgba(0, 229, 160, 0.25);
}
.moo-nc-modal__create:disabled {
  cursor: not-allowed;
}


.moo-note-share__btn {
  padding: 8px 14px;
  border-radius: 10px;
  background: rgba(18, 26, 32, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
  color: var(--color-text-primary);
  font-size: 12px;
  font-weight: 600;
  font-family: 'Montserrat', sans-serif;
  cursor: pointer;
  transition: opacity 0.2s, background-color 0.2s, color 0.2s, border-color 0.2s;
  white-space: nowrap;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 5px;
}
.moo-note-share__btn--active {
  background: rgba(0, 229, 160, 0.1);
  border-color: rgba(0, 229, 160, 0.25);
  color: var(--color-accent);
}
.moo-note-share__btn--cancel {
  background: rgba(244, 63, 94, 0.1);
  border-color: rgba(244, 63, 94, 0.25);
  color: var(--color-danger);
}
.moo-note-share__btn--pending {
  background: rgba(251, 191, 36, 0.08);
  border-color: rgba(251, 191, 36, 0.22);
  color: var(--color-warning);
}
.moo-note-share__btn[disabled] {
  opacity: 0.45;
  cursor: not-allowed;
}

/* ---- Cloud Drive Tool ---- */
.moo-cd-page {
  display: flex !important;
  flex-direction: column !important;
  height: calc(100% - 134px) !important;
  width: 100% !important;
  overflow-y: auto !important;
  overflow-x: hidden !important;
  overscroll-behavior: none !important;
  padding: 0 !important;
  background: transparent !important;
  font-size: 14px !important;
}

/* Setup screen — matches .moo-note-lock pattern */
.moo-cd-setup {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 0 24px;
  min-height: 100%;
  box-sizing: border-box;
}
.moo-cd-setup::before,
.moo-cd-setup::after {
  content: '';
  flex: 1 0 24px;
}
.moo-cd-setup__icon {
  width: 72px;
  min-width: 72px;
  height: 72px;
  min-height: 72px;
  flex-shrink: 0;
  border-radius: 22px;
  background: rgba(0, 229, 160, 0.08);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 28px;
  color: var(--color-accent);
  margin-bottom: 20px;
  box-shadow: 0 0 40px rgba(0, 229, 160, 0.08);
}
.moo-cd-setup__title {
  font-size: 20px;
  font-weight: 800;
  color: var(--color-text-primary);
  margin-bottom: 6px;
}
.moo-cd-setup__subtitle {
  font-size: 13px;
  color: rgba(255, 255, 255, 0.3);
  line-height: 1.5;
  max-width: 300px;
  margin-bottom: 8px;
}
.moo-cd-setup__form {
  width: 100%;
  max-width: 280px;
  padding-bottom: 24px;
}
.moo-cd-setup__input {
  width: calc(100% - 36px);
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 14px;
  color: var(--color-text-primary);
  font-family: 'Montserrat', sans-serif;
  font-size: 16px;
  font-weight: 500;
  padding: 16px 18px;
  outline: none;
  -webkit-appearance: none;
  transition: border-color 0.2s;
  margin-bottom: 10px;
}
.moo-cd-setup__input:focus {
  border-color: rgba(0, 229, 160, 0.4);
}
.moo-cd-setup__input::placeholder {
  color: rgba(255, 255, 255, 0.2);
}
.moo-cd-setup__error {
  font-size: 12px;
  color: var(--color-danger);
  font-weight: 600;
  margin-top: 8px;
}
.moo-cd-setup__error:empty {
  display: none;
}
.moo-cd-setup__btn {
  width: 100%;
  padding: 16px !important;
  background: linear-gradient(135deg, var(--color-accent), var(--color-accent-dark)) !important;
  border: none !important;
  border-radius: 14px !important;
  color: var(--color-bg) !important;
  font-family: 'Montserrat', sans-serif !important;
  font-size: 15px !important;
  font-weight: 700 !important;
  cursor: pointer;
  display: flex !important;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 12px;
}
.moo-cd-setup__btn:active {
  transform: scale(0.97);
}

/* Lock screen — matches .moo-note-lock pattern */
.moo-cd-lock {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 0 24px;
  min-height: 100%;
  box-sizing: border-box;
}
.moo-cd-lock::before,
.moo-cd-lock::after {
  content: '';
  flex: 1 0 24px;
}
.moo-cd-lock__icon {
  width: 72px;
  min-width: 72px;
  height: 72px;
  min-height: 72px;
  flex-shrink: 0;
  border-radius: 22px;
  background: rgba(0, 229, 160, 0.08);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 28px;
  color: var(--color-accent);
  margin-bottom: 20px;
  box-shadow: 0 0 40px rgba(0, 229, 160, 0.08);
}
.moo-cd-lock__title {
  font-size: 20px;
  font-weight: 800;
  color: var(--color-text-primary);
}
.moo-cd-lock__subtitle {
  font-size: 13px;
  color: rgba(255, 255, 255, 0.3);
  margin-bottom: 20px;
}
.moo-cd-lock__form {
  width: 100%;
  max-width: 280px;
  padding-bottom: 24px;
}
.moo-cd-lock__input {
  width: calc(100% - 36px);
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 14px;
  color: var(--color-text-primary);
  font-family: 'Montserrat', sans-serif;
  font-size: 16px;
  font-weight: 500;
  padding: 16px 18px;
  outline: none;
  -webkit-appearance: none;
  transition: border-color 0.2s;
}
.moo-cd-lock__input:focus {
  border-color: rgba(0, 229, 160, 0.4);
}
.moo-cd-lock__input::placeholder {
  color: rgba(255, 255, 255, 0.2);
}
.moo-cd-lock__error {
  font-size: 12px;
  color: var(--color-danger);
  font-weight: 600;
  margin-top: 8px;
}
.moo-cd-lock__error:empty {
  display: none;
}
.moo-cd-lock__btn {
  width: 100%;
  padding: 16px !important;
  background: linear-gradient(135deg, var(--color-accent), var(--color-accent-dark)) !important;
  border: none !important;
  border-radius: 14px !important;
  color: var(--color-bg) !important;
  font-family: 'Montserrat', sans-serif !important;
  font-size: 15px !important;
  font-weight: 700 !important;
  cursor: pointer;
  display: flex !important;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 12px;
}
.moo-cd-lock__btn:active {
  transform: scale(0.97);
}

/* ===== Hidden Folder Unlock Modal (admin-only) =====
   Triggered by a silent 5-second long-press on the Cloud Drive settings gear.
   Piggybacks on .moo-nc-modal__ shell; this block only overrides the icon
   treatment, subtitle, and the Unlock CTA so the modal reads as "secured /
   admin-only" without drifting from the rest of Cloud Drive's aurora theme. */
.moo-cd-hf__icon {
  background: rgba(0, 229, 160, 0.12) !important;
  border: 1px solid rgba(0, 229, 160, 0.3);
  box-shadow: 0 0 24px rgba(0, 229, 160, 0.2);
  color: var(--color-accent) !important;
}
/* Wraps the title + subtitle inside the modal header so they sit as a single
   block (tight vertical rhythm) instead of being pulled apart by the header's
   flex gap. */
.moo-cd-hf__heading {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
.moo-cd-hf__subtitle {
  font-size: 13px;
  color: rgba(255, 255, 255, 0.5);
  text-align: center;
  margin: 0;
  letter-spacing: 0.01em;
}
.moo-cd-hf__btn {
  background: linear-gradient(135deg, var(--color-accent), var(--color-accent-dark)) !important;
  color: var(--color-bg) !important;
  font-weight: 700 !important;
}

/* Browser */
.moo-cd-browser {
  display: flex !important;
  flex-direction: column !important;
  flex: 1 !important;
  min-height: 0 !important;
  overflow-y: auto;
  overscroll-behavior: none;
  height: 100% !important;
}

/* Crumb bar — breadcrumbs + the list/grid view toggle. The toggle sits
 * OUTSIDE .moo-cd-breadcrumbs so it never wraps or scrolls away when a
 * deep path fills the crumbs' own max-height scroll region. The bar (not
 * the crumbs) carries the vertical padding so `align-items: center` puts
 * a single crumb line and the button on the SAME axis — no per-child
 * offset compensation. */
.moo-cd-crumbbar {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  padding: 14px 14px 10px 0;
}

/* Breadcrumbs */
.moo-cd-breadcrumbs {
  display: flex;
  gap: 6px;
  align-items: center;
  padding: 0 16px;
  font-size: 13px;
  color: rgba(255, 255, 255, 0.35);
  flex-wrap: wrap;
  flex: 1;
  min-width: 0;
  max-height: 48px;
  overflow-y: auto;
  overscroll-behavior: none;
}

/* List/grid switcher. Quiet rounded-square icon button (brand radius for
 * small buttons); the icon always shows the view a click switches TO.
 * padding/line-height are reset because there is no global button reset —
 * UA button defaults would nudge the glyph off-centre. */
.moo-cd-viewtoggle {
  flex-shrink: 0;
  box-sizing: border-box;
  width: 32px;
  height: 32px;
  margin: 0 0 0 8px;
  padding: 0;
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.07);
  color: rgba(240, 244, 248, 0.6);
  font-size: 13px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background-color 0.15s, color 0.15s, border-color 0.15s;
}
.moo-cd-viewtoggle > i {
  display: block;
  line-height: 1;
}
.moo-cd-viewtoggle:hover {
  background: rgba(255, 255, 255, 0.06);
  color: rgba(240, 244, 248, 0.85);
  border-color: rgba(255, 255, 255, 0.12);
}
.moo-cd-viewtoggle:active {
  background: rgba(18, 26, 32, 0.92);
}
.moo-cd-breadcrumb {
  cursor: pointer;
  transition: color 0.15s;
}
.moo-cd-breadcrumb:active {
  color: var(--color-accent);
}
.moo-cd-breadcrumb--active {
  color: var(--color-text-primary);
  font-weight: 600;
  cursor: default;
}
.moo-cd-breadcrumb-sep {
  font-size: 8px;
  color: rgba(255, 255, 255, 0.15);
}

/* Item rows */
.moo-cd-list {
  flex: 1;
  min-height: 0;
}
.moo-cd-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.04);
  cursor: pointer;
  transition: background 0.15s;
  -webkit-user-select: none;
  user-select: none;
}
/* Strip the trailing divider from the last row so the list ends cleanly
 * instead of with an orphan line. The first row already has no top border
 * (rule above is bottom-only), so the pattern is row-divider, not full-
 * underline-each-row. */
.moo-cd-item:last-child {
  border-bottom: 0;
}
.moo-cd-item:active {
  background: rgba(14, 22, 28, 0.90);
}
.moo-cd-item__icon {
  width: 42px;
  height: 42px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 229, 160, 0.06);
  font-size: 16px;
  color: var(--color-accent);
  flex-shrink: 0;
}
.moo-cd-item__icon--folder {
  background: rgba(251, 191, 36, 0.08);
  color: var(--color-warning);
}
.moo-cd-item__info {
  flex: 1;
  min-width: 0;
}
.moo-cd-item__name {
  font-size: 14px;
  font-weight: 600;
  color: var(--color-text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.moo-cd-item__meta {
  font-size: 11px;
  color: rgba(255, 255, 255, 0.3);
  margin-top: 2px;
}
/* Extension badge. Lives at row level (sibling of __info in list rows,
 * sibling of __name in video tile rows) so it centres against the full
 * row via the row's flex `align-items:center` instead of just the name
 * text. Inline-flex + line-height:1 keeps the glyph centred inside its
 * own explicit-height box regardless of font metrics. */
.moo-cd-ext-badge {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 20px;
  padding: 0 7px;
  background: rgba(0, 229, 160, 0.12);
  border: 1px solid rgba(0, 229, 160, 0.28);
  color: var(--color-accent);
  border-radius: 6px;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  line-height: 1;
  font-family: 'Montserrat', sans-serif;
  box-sizing: border-box;
  user-select: none;
  -webkit-user-select: none;
  /* Decorative — clicks pass through to the row's open-file handler so
   * a tap that lands on the badge doesn't get swallowed. */
  pointer-events: none;
  max-width: 110px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.moo-cd-item__more {
  background: none !important;
  border: none !important;
  color: rgba(255, 255, 255, 0.3) !important;
  font-size: 16px !important;
  padding: 8px !important;
  cursor: pointer;
  flex-shrink: 0;
  border-radius: 8px !important;
  transition: background-color 0.15s, color 0.15s !important;
}
.moo-cd-item__more:hover {
  background: rgba(255, 255, 255, 0.06) !important;
  color: rgba(255, 255, 255, 0.7) !important;
}
.moo-cd-item__more:active {
  background: rgba(18, 26, 32, 0.92) !important;
}

/* ==========================================================================
 * MEDIA GRID — auto-triggered when a folder (no subfolders) contains at
 * least one image or video. All tile kinds share the same card chrome
 * (media box + title/kebab row): videos render their sprite poster with
 * the canonical mint play overlay and a hover/long-press slideshow of
 * timeline-spread frames; images paint the decrypted photo itself as a
 * cover background; every other file type is a static icon tile.
 * ======================================================================== */

/* When the list container is in grid mode it doesn't have the row-style
 * border-bottom + per-row padding — the grid manages its own spacing.
 * The .moo-cd-vtile rule below resets the per-tile look so it doesn't
 * inherit the row layout from .moo-cd-item. */
/* Applied to #cd_list itself (not an inner wrapper). The override on flex +
 * min-height is critical: #cd_list has `.moo-cd-list { flex: 1; min-height: 0 }`
 * which would otherwise lock #cd_list to the flex remainder height of
 * .moo-cd-browser, leaving the grid's overflow as visual ink only — the
 * parent's overflow:auto can't scroll content that doesn't push its own
 * box bounds. With flex: 0 0 auto, #cd_list sizes to its natural grid
 * content height, and .moo-cd-browser's scroll engages naturally as soon
 * as breadcrumbs + grid total height exceeds the viewport. */
.moo-cd-list--grid {
  flex: 0 0 auto !important;
  min-height: auto !important;
  padding: 18px;
  display: grid;
  /* Larger tiles for video — fewer per row, more visible thumbnail real estate.
   * Minmax floor is the smallest a tile shrinks to before wrapping. */
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 20px 18px;
  align-content: start;
}
@media (max-width: 900px) {
  .moo-cd-list--grid {
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  }
}
@media (max-width: 600px) {
  .moo-cd-list--grid {
    /* 1fr at this width = single column, video fills full width */
    grid-template-columns: 1fr;
    gap: 14px;
    padding: 12px;
  }
}

/* Reset .moo-cd-item row-look for grid tiles (we still keep the data-* + click
 * delegation by reusing the .moo-cd-item--file class, so existing handlers in
 * cdLoadFolder fire on tile click for play + on .moo-cd-item__more for kebab). */
.moo-cd-vtile.moo-cd-item {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0;
  padding: 0;
  border-bottom: none;
  border-radius: 14px;
  background: rgba(14, 22, 28, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.05);
  overflow: hidden;
  transition: transform 0.18s cubic-bezier(0.4, 0, 0.2, 1),
              border-color 0.18s,
              box-shadow 0.18s;
  -webkit-touch-callout: none;
}
.moo-cd-vtile.moo-cd-item:hover {
  transform: translateY(-2px);
  border-color: rgba(0, 229, 160, 0.22);
  box-shadow: 0 12px 28px rgba(0, 0, 0, 0.35);
}
.moo-cd-vtile.moo-cd-item:active {
  transform: translateY(0);
  background: rgba(14, 22, 28, 0.55);
}

.moo-cd-vtile__media {
  position: relative;
  aspect-ratio: 16 / 9;
  background: #060d10;
  overflow: hidden;
  border-radius: 14px 14px 0 0;
}
/* Poster applied — the .__media element shows either a single cell of the
 * encrypted video sprite (cdApplySpriteCell) or the decrypted photo itself
 * (cdApplyImageTilePhoto). Hides whichever fallback glyph sat underneath. */
.moo-cd-vtile--sprite-poster .moo-cd-vtile__play,
.moo-cd-vtile--sprite-poster .moo-cd-vtile__glyph {
  display: none;
}

/* Mint play overlay — same translucent green as Video.js big-play, scaled down
 * to fit the tile thumbnail and centered. Always visible (signals "this is a
 * video" before any hover). Slight lift on tile hover. */
.moo-cd-vtile__play {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 52px;
  height: 52px;
  margin: -26px 0 0 -26px;
  border-radius: 50%;
  background: rgba(0, 229, 160, 0.15);
  border: 2px solid rgba(0, 229, 160, 0.4);
  color: var(--color-accent);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  pointer-events: none;
  transition: transform 0.18s cubic-bezier(0.4, 0, 0.2, 1),
              background-color 0.18s,
              border-color 0.18s;
}
.moo-cd-vtile__play > i {
  margin-left: 3px; /* optical centering for the play triangle */
}
.moo-cd-vtile.moo-cd-item:hover .moo-cd-vtile__play {
  transform: scale(1.08);
  background: rgba(0, 229, 160, 0.22);
  border-color: rgba(0, 229, 160, 0.55);
}

/* Quiet glyph for image + doc tiles — a rounded-square chip (brand rule:
 * rounded squares, not circles; mint stays reserved for the play
 * affordance). On image tiles it's a placeholder that disappears once the
 * decrypted photo paints (and the permanent face if the browser can't
 * decode the format, e.g. HEIC outside Safari); on doc tiles it's the
 * permanent file-type face. Deliberately static — no hover response. */
.moo-cd-vtile__glyph {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 52px;
  height: 52px;
  margin: -26px 0 0 -26px;
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.08);
  color: rgba(240, 244, 248, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  pointer-events: none;
}
/* Folder tiles (user-pinned grid view) keep the list's amber folder
 * identity so folders read at a glance among media thumbs. */
.moo-cd-vtile__glyph--folder {
  background: rgba(251, 191, 36, 0.08);
  border-color: rgba(251, 191, 36, 0.16);
  color: var(--color-warning);
}

/* Title + kebab row underneath the media. */
.moo-cd-vtile__row {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 10px 10px 10px 14px;
  min-width: 0;
}
.moo-cd-vtile__name {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--color-text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  letter-spacing: 0.1px;
}
/* Video tile is tighter than the list row, so dial the badge down
 * slightly so it doesn't dominate the title. Selector targets the row
 * (badge is a sibling of __name now, not a child). */
.moo-cd-vtile__row .moo-cd-ext-badge {
  height: 18px;
  padding: 0 6px;
  font-size: 9px;
  border-radius: 5px;
}
.moo-cd-vtile .moo-cd-item__more {
  padding: 6px !important;
  font-size: 14px !important;
  margin-right: -2px;
}

/* Context menu */
.moo-cd-ctx {
  position: fixed;
  z-index: 99999;
  background: rgba(20, 30, 38, 0.95);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 14px;
  padding: 8px 0;
  min-width: 170px;
}
.moo-cd-ctx__item {
  padding: 12px 20px;
  font-size: 14px;
  font-weight: 500;
  color: var(--color-text-primary);
  display: flex;
  align-items: center;
  gap: 12px;
  cursor: pointer;
  transition: background 0.12s;
}
/* Fixed-width icon column so labels line up flush across rows even when
 * the icons have different intrinsic widths (e.g. fa-file 10px wide vs
 * fa-folder-plus 18px wide). Icon is centered within the 18px slot; the
 * <span> label then starts at the same x for every row. */
.moo-cd-ctx__item > i {
  display: inline-flex;
  justify-content: center;
  width: 18px;
  flex-shrink: 0;
  font-size: 14px;
}
.moo-cd-ctx__item:active {
  background: rgba(18, 26, 32, 0.92);
}
.moo-cd-ctx__item--danger {
  color: var(--color-danger);
}

/* Empty state */
.moo-cd-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  flex: 1;
  min-height: 0;
  color: rgba(255, 255, 255, 0.2);
  gap: 10px;
  font-size: 14px;
  padding: 24px;
}
.moo-cd-empty i {
  font-size: 36px;
}
.moo-cd-empty__btn {
  margin-top: 6px;
  padding: 10px 20px !important;
  background: rgba(0, 229, 160, 0.08) !important;
  border: 1px solid rgba(0, 229, 160, 0.15) !important;
  border-radius: 10px !important;
  color: var(--color-accent) !important;
  font-family: 'Montserrat', sans-serif !important;
  font-size: 13px !important;
  font-weight: 600 !important;
  cursor: pointer;
  display: flex !important;
  align-items: center;
  justify-content: center;
  gap: 6px;
}
.moo-cd-empty__btn:active {
  background: rgba(0, 229, 160, 0.14) !important;
}
.moo-cd-empty__btn i {
  font-size: 13px;
}

/* Loading */
.moo-cd-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 1;
  min-height: 0;
  font-size: 20px;
  color: rgba(255, 255, 255, 0.2);
}

/* Drag & drop zone */
.moo-cd-dropzone {
  position: absolute;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(6, 13, 16, 0.8);
}
.moo-cd-dropzone__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 40px;
  border: 2px dashed rgba(0, 229, 160, 0.3);
  border-radius: 20px;
  color: var(--color-accent);
  font-size: 15px;
  font-weight: 600;
}
.moo-cd-dropzone__inner i {
  font-size: 36px;
}

/* ===== Upload queue modal (Cloud Drive) =====
 * Queue-based upload UI — shows one row per file with live state
 * (pending / encrypting / uploading / done / failed / skipped), inline
 * retry buttons, and an overall progress ring. */
#cd_upload_overlay {
  position: fixed;
  inset: 0;
  background: rgba(6, 13, 16, 0.82);
  z-index: 100000;
  animation: mooOverlayIn 0.25s ease-out;
}
#cd_upload_modal {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(560px, calc(100% - 32px));
  max-height: min(720px, calc(100dvh - 48px));
  max-height: min(720px, calc(100vh - 48px));
  display: flex;
  flex-direction: column;
  background: rgba(20, 30, 38, 0.96);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 22px;
  box-shadow: 0 32px 90px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(0, 229, 160, 0.04);
  z-index: 100001;
  overflow: hidden;
  animation: mooModalIn 0.3s cubic-bezier(0.2, 0.9, 0.3, 1);
}
.moo-cdu__header {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 20px 22px 16px 22px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  flex-shrink: 0;
}
.moo-cdu__header-main {
  flex: 1;
  min-width: 0;
}
.moo-cdu__title {
  font-family: 'Montserrat', sans-serif;
  font-size: 16px;
  font-weight: 700;
  color: var(--color-text-primary);
  letter-spacing: -0.01em;
  line-height: 1.25;
}
.moo-cdu__subtitle {
  font-size: 12px;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.5);
  margin-top: 4px;
  letter-spacing: 0.01em;
}
.moo-cdu__close {
  width: 34px;
  height: 34px;
  border-radius: 11px;
  background: rgba(16, 24, 30, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.08);
  color: rgba(255, 255, 255, 0.6);
  font-size: 14px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  transition: opacity 0.18s ease, background-color 0.18s ease, color 0.18s ease, border-color 0.18s ease;
  flex-shrink: 0;
}
.moo-cdu__close:hover {
  background: rgba(244, 63, 94, 0.12);
  border-color: rgba(244, 63, 94, 0.3);
  color: var(--color-danger);
}

/* Summary: big ring + stat pills */
.moo-cdu__summary {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 18px 22px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
  flex-shrink: 0;
  background:
    radial-gradient(circle at 0% 0%, rgba(0, 229, 160, 0.06), transparent 60%),
    radial-gradient(circle at 100% 100%, rgba(6, 13, 16, 0.4), transparent 60%);
}
.moo-cdu__ring-wrap {
  position: relative;
  width: 72px;
  height: 72px;
  flex-shrink: 0;
}
.moo-cdu__ring {
  width: 72px;
  height: 72px;
}
.moo-cdu__ring-bg {
  fill: none;
  stroke: rgba(255, 255, 255, 0.08);
  stroke-width: 5;
}
.moo-cdu__ring-fg {
  fill: none;
  stroke: var(--color-accent);
  stroke-width: 5;
  stroke-linecap: round;
  stroke-dasharray: 226.2;
  stroke-dashoffset: 226.2;
  transform: rotate(-90deg);
  transform-origin: center;
  transition: stroke-dashoffset 0.35s cubic-bezier(0.4, 0, 0.2, 1);
  filter: drop-shadow(0 0 8px rgba(0, 229, 160, 0.35));
}
.moo-cdu__ring-pct {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'Montserrat', sans-serif;
  font-size: 14px;
  font-weight: 700;
  color: var(--color-text-primary);
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}
.moo-cdu__stats {
  flex: 1;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 10px;
  min-width: 0;
}
.moo-cdu__stat {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  border: 1px solid transparent;
  white-space: nowrap;
  letter-spacing: 0.02em;
}
.moo-cdu__stat i { font-size: 10px; }
.moo-cdu__stat--done {
  background: rgba(0, 229, 160, 0.1);
  border-color: rgba(0, 229, 160, 0.22);
  color: var(--color-accent);
}
.moo-cdu__stat--active {
  background: rgba(0, 229, 160, 0.06);
  border-color: rgba(0, 229, 160, 0.15);
  color: rgba(0, 229, 160, 0.85);
}
.moo-cdu__stat--pending {
  background: rgba(14, 22, 28, 0.92);
  border-color: rgba(255, 255, 255, 0.08);
  color: rgba(255, 255, 255, 0.5);
}
.moo-cdu__stat--failed {
  background: rgba(244, 63, 94, 0.1);
  border-color: rgba(244, 63, 94, 0.24);
  color: var(--color-danger);
}

/* Scrollable file list. No bottom padding on the wrapper — the last item's
 * own internal padding + the footer's top border/padding already provide
 * visual separation. Adding wrapper padding-bottom caused "double padding"
 * below the last row. */
.moo-cdu__list-wrap {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: none;
  /* Balanced top/bottom padding so the first and last rows have breathing room
     against the summary above and the footer below. */
  padding: 14px 16px 16px 16px;
}
.moo-cdu__list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.moo-cdu__item {
  display: grid;
  grid-template-columns: 38px 1fr auto auto;
  align-items: center;
  gap: 12px;
  padding: 11px 13px;
  /* Solid enough to read as a real card even in "pending" state — a fainter
     alpha makes pending/done rows look washed-out / disabled next to the
     vivid active row. */
  background: rgba(22, 30, 36, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.13);
  border-left: 3px solid rgba(255, 255, 255, 0.22);
  border-radius: 12px;
  transition: background 0.2s ease, border-color 0.2s ease, box-shadow 0.25s ease, transform 0.2s ease;
  animation: mooCduItemIn 0.25s ease-out;
}
@keyframes mooCduItemIn {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: translateY(0); }
}
/* Active upload: clearly highlighted so the user can see which file is
   currently being processed (a faint green reads as "grayed out" alongside
   idle rows). */
.moo-cdu__item--active {
  background: rgba(0, 229, 160, 0.11);
  border-color: rgba(0, 229, 160, 0.32);
  border-left-color: var(--color-accent);
  box-shadow: 0 0 0 1px rgba(0, 229, 160, 0.08), 0 4px 18px -6px rgba(0, 229, 160, 0.35);
}
.moo-cdu__item--done {
  background: rgba(0, 229, 160, 0.045);
  border-color: rgba(0, 229, 160, 0.18);
  border-left-color: var(--color-accent);
}
/* Done rows stay at full opacity — the green left border + state badge is
   the completion cue (fading the icon read as "washed out" once several rows
   were done). */
.moo-cdu__item--failed {
  background: rgba(244, 63, 94, 0.06);
  border-color: rgba(244, 63, 94, 0.2);
  border-left-color: var(--color-danger);
}
.moo-cdu__item--skipped {
  background: rgba(251, 191, 36, 0.05);
  border-color: rgba(251, 191, 36, 0.18);
  border-left-color: var(--color-warning);
}
.moo-cdu__icon {
  width: 38px;
  height: 38px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  border: 1px solid rgba(255, 255, 255, 0.06);
  flex-shrink: 0;
}
.moo-cdu__icon--mint   { background: rgba(0, 229, 160, 0.1);  color: var(--color-accent); border-color: rgba(0, 229, 160, 0.22); }
.moo-cdu__icon--sky    { background: rgba(96, 165, 250, 0.1); color: #60a5fa; border-color: rgba(96, 165, 250, 0.22); }
.moo-cdu__icon--amber  { background: rgba(251, 191, 36, 0.1); color: var(--color-warning); border-color: rgba(251, 191, 36, 0.22); }
.moo-cdu__icon--rose   { background: rgba(244, 63, 94, 0.1);  color: var(--color-danger); border-color: rgba(244, 63, 94, 0.22); }
.moo-cdu__icon--muted  { background: rgba(16, 24, 30, 0.92); color: rgba(255, 255, 255, 0.5); border-color: rgba(255, 255, 255, 0.08); }
.moo-cdu__info {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.moo-cdu__name {
  font-family: 'Montserrat', sans-serif;
  font-size: 13px;
  font-weight: 600;
  color: var(--color-text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 1.3;
}
.moo-cdu__meta {
  font-size: 11px;
  color: rgba(255, 255, 255, 0.45);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  letter-spacing: 0.01em;
}
.moo-cdu__err {
  color: var(--color-danger);
  font-weight: 600;
}
.moo-cdu__item--skipped .moo-cdu__err {
  color: var(--color-warning);
}
/* Thin inline progress bar — only rendered during active upload */
.moo-cdu__bar {
  margin-top: 4px;
  height: 3px;
  border-radius: 3px;
  background: rgba(24, 32, 40, 0.92);
  overflow: hidden;
}
.moo-cdu__bar-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--color-accent), var(--color-accent-dark));
  border-radius: 3px;
  transition: width 0.25s ease;
  box-shadow: 0 0 8px rgba(0, 229, 160, 0.4);
}
.moo-cdu__state {
  width: 28px;
  height: 28px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  flex-shrink: 0;
}
.moo-cdu__state--done    { background: rgba(0, 229, 160, 0.12); color: var(--color-accent); }
.moo-cdu__state--active  { background: rgba(0, 229, 160, 0.08); color: var(--color-accent); }
.moo-cdu__state--pending { background: rgba(14, 22, 28, 0.92); color: rgba(255, 255, 255, 0.35); }
.moo-cdu__state--failed  { background: rgba(244, 63, 94, 0.14); color: var(--color-danger); }
.moo-cdu__state--skipped { background: rgba(251, 191, 36, 0.12); color: var(--color-warning); }
.moo-cdu__item-retry {
  width: 28px;
  height: 28px;
  border-radius: 8px;
  background: rgba(0, 229, 160, 0.12);
  border: 1px solid rgba(0, 229, 160, 0.24);
  color: var(--color-accent);
  font-size: 11px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  transition: opacity 0.18s ease, background-color 0.18s ease, border-color 0.18s ease;
  flex-shrink: 0;
}
.moo-cdu__item-retry:hover {
  background: rgba(0, 229, 160, 0.2);
  border-color: rgba(0, 229, 160, 0.4);
}

/* Footer actions */
.moo-cdu__actions {
  display: flex;
  gap: 10px;
  padding: 14px 22px 20px 22px;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  flex-shrink: 0;
  background: rgba(6, 13, 16, 0.3);
}
.moo-cdu__btn {
  flex: 1;
  height: 42px;
  border-radius: 12px;
  border: none;
  font-family: 'Montserrat', sans-serif;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  transition: opacity 0.18s ease, background-color 0.18s ease, color 0.18s ease, border-color 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease;
  letter-spacing: 0.02em;
}
.moo-cdu__btn--primary {
  background: linear-gradient(135deg, var(--color-accent), var(--color-accent-dark));
  color: var(--color-bg);
  box-shadow: 0 6px 20px rgba(0, 229, 160, 0.25);
}
.moo-cdu__btn--primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 10px 26px rgba(0, 229, 160, 0.35);
}
.moo-cdu__btn--primary:active {
  transform: translateY(0);
}
.moo-cdu__btn--secondary {
  background: rgba(16, 24, 30, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
  color: var(--color-text-primary);
}
.moo-cdu__btn--secondary:hover {
  background: rgba(26, 34, 42, 0.92);
  border-color: rgba(255, 255, 255, 0.16);
}

/* Cloud Drive toast — non-blocking replacement for alert() */
.moo-cd-toast {
  position: fixed;
  bottom: calc(24px + env(safe-area-inset-bottom, 0));
  left: 50%;
  transform: translateX(-50%) translateY(12px);
  max-width: calc(100% - 32px);
  padding: 13px 18px;
  border-radius: 14px;
  font-family: 'Montserrat', sans-serif;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.01em;
  z-index: 100005;
  display: flex;
  align-items: center;
  gap: 10px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5);
  opacity: 0;
  transition: transform 0.3s cubic-bezier(0.2, 0.9, 0.3, 1), opacity 0.3s ease;
  pointer-events: none;
}
.moo-cd-toast--visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
.moo-cd-toast i { font-size: 14px; flex-shrink: 0; }
.moo-cd-toast--error {
  background: rgba(32, 12, 18, 0.92);
  border: 1px solid rgba(244, 63, 94, 0.3);
  color: var(--color-toast-error);
}
.moo-cd-toast--error i { color: var(--color-danger); }
.moo-cd-toast--warn {
  background: rgba(32, 26, 12, 0.92);
  border: 1px solid rgba(251, 191, 36, 0.3);
  color: var(--color-toast-warn);
}
.moo-cd-toast--warn i { color: var(--color-warning); }
.moo-cd-toast--info {
  background: rgba(12, 26, 22, 0.92);
  border: 1px solid rgba(0, 229, 160, 0.28);
  color: var(--color-toast-info);
}
.moo-cd-toast--info i { color: var(--color-accent); }

/* ===== GLOBAL TOAST (mooToast) =====
   Page-agnostic sibling of .moo-cd-toast — same glass-morphism, vars + radii.
   Used by the alarm evidence viewer (and any caller of window.mooToast) so a
   transient message renders as an in-page notice instead of a blocking
   native alert(). Mirrors .moo-cd-toast tone variants 1:1. */
.moo-toast {
  position: fixed;
  bottom: calc(24px + env(safe-area-inset-bottom, 0));
  left: 50%;
  transform: translateX(-50%) translateY(12px);
  max-width: calc(100% - 32px);
  padding: 13px 18px;
  border-radius: 14px;
  font-family: 'Montserrat', sans-serif;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.01em;
  z-index: 100005;
  display: flex;
  align-items: center;
  gap: 10px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5);
  opacity: 0;
  transition: transform 0.3s cubic-bezier(0.2, 0.9, 0.3, 1), opacity 0.3s ease;
  pointer-events: none;
}
.moo-toast--visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
.moo-toast i { font-size: 14px; flex-shrink: 0; }
.moo-toast--error {
  background: rgba(32, 12, 18, 0.92);
  border: 1px solid rgba(244, 63, 94, 0.3);
  color: var(--color-toast-error);
}
.moo-toast--error i { color: var(--color-danger); }
.moo-toast--warn {
  background: rgba(32, 26, 12, 0.92);
  border: 1px solid rgba(251, 191, 36, 0.3);
  color: var(--color-toast-warn);
}
.moo-toast--warn i { color: var(--color-warning); }
.moo-toast--info {
  background: rgba(12, 26, 22, 0.92);
  border: 1px solid rgba(0, 229, 160, 0.28);
  color: var(--color-toast-info);
}
.moo-toast--info i { color: var(--color-accent); }

/* ===== CLOUD DRIVE DOWNLOAD PROGRESS MODAL ===== */
/* Shown while a file is being fetched + decrypted. Mirrors the visual
   language of the upload queue modal so both flows feel consistent.
   Single vertical column around a big progress ring — no flex-row
   fragility on narrow viewports. Cancel button is absolutely positioned
   top-right so it never competes with content for horizontal space. */
#cd_dl_overlay {
  position: fixed;
  inset: 0;
  background:
    radial-gradient(ellipse 600px 300px at 50% 20%, rgba(0, 229, 160, 0.07), transparent 70%),
    rgba(6, 13, 16, 0.85);
  z-index: 100002;
  animation: mooOverlayIn 0.25s ease-out;
}
#cd_dl_modal {
  position: absolute !important;
  top: 50% !important;
  left: 50% !important;
  transform: translate(-50%, -50%) !important;
  width: calc(100% - 32px) !important;
  max-width: 380px !important;
  background:
    radial-gradient(ellipse 380px 180px at 50% 0%, rgba(0, 229, 160, 0.08), transparent 70%),
    rgba(14, 22, 28, 0.96) !important;
  border: 1px solid rgba(255, 255, 255, 0.08) !important;
  border-radius: 22px !important;
  box-shadow:
    0 40px 100px rgba(0, 0, 0, 0.6),
    0 0 0 1px rgba(0, 229, 160, 0.04) inset !important;
  z-index: 100003 !important;
  animation: mooModalIn 0.25s ease-out;
  overflow: hidden !important;
  padding: 36px 28px 32px 28px !important;
  text-align: center !important;
  box-sizing: border-box !important;
  /* Force flex column so all children stack vertically and centre regardless
     of any generic #cd_dl_modal selectors elsewhere in the cascade. Note
     `display` is deliberately NOT set here — the inline HTML style starts it
     hidden and the JS `.css('display', 'flex')` toggles it on. Setting display
     with !important here would block the JS show/hide. */
  flex-direction: column !important;
  align-items: center !important;
  justify-content: flex-start !important;
}
/* All download-modal children use ID+class selectors so their specificity
   beats `#cd_dl_modal > *`-style and bare-class rules elsewhere — immune to
   cascade surprises from future generic rules. */

/* Close button — absolute-positioned in corner, doesn't participate in flow. */
#cd_dl_modal > .moo-cddl__close {
  position: absolute !important;
  top: 14px !important;
  right: 14px !important;
  left: auto !important;
  width: 34px !important;
  height: 34px !important;
  max-width: 34px !important;
  background: rgba(18, 26, 32, 0.92) !important;
  border: 1px solid rgba(255, 255, 255, 0.08) !important;
  color: rgba(255, 255, 255, 0.7) !important;
  border-radius: 50% !important;
  cursor: pointer !important;
  font-size: 13px !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
  padding: 0 !important;
  z-index: 2 !important;
  margin: 0 !important;
  box-sizing: border-box !important;
}
#cd_dl_modal > .moo-cddl__close:hover {
  background: rgba(244, 63, 94, 0.18) !important;
  color: var(--color-danger) !important;
  border-color: rgba(244, 63, 94, 0.35) !important;
}

/* Ring wrapper — fixed 120px square, auto-centred horizontally by margin. */
#cd_dl_modal > .moo-cddl__ring-wrap {
  position: relative !important;
  width: 120px !important;
  height: 120px !important;
  min-width: 0 !important;
  max-width: 120px !important;
  margin: 0 auto 22px auto !important;
  padding: 0 !important;
  display: block !important;
  flex-shrink: 0 !important;
  box-sizing: border-box !important;
}
#cd_dl_modal .moo-cddl__ring {
  width: 120px !important;
  height: 120px !important;
  display: block !important;
  overflow: visible;
}
#cd_dl_modal .moo-cddl__ring-bg {
  fill: none;
  stroke: rgba(255, 255, 255, 0.06);
  stroke-width: 7;
}
#cd_dl_modal .moo-cddl__ring-fg {
  fill: none;
  stroke: var(--color-accent);
  stroke-width: 7;
  stroke-linecap: round;
  transition: stroke-dashoffset 0.3s ease-out;
  filter: drop-shadow(0 0 10px rgba(0, 229, 160, 0.55));
}
#cd_dl_modal .moo-cddl__ring-pct {
  position: absolute !important;
  top: 0 !important;
  left: 0 !important;
  right: 0 !important;
  bottom: 0 !important;
  width: auto !important;
  height: auto !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  font-size: 22px !important;
  font-weight: 800 !important;
  color: var(--color-accent) !important;
  font-variant-numeric: tabular-nums !important;
  letter-spacing: -0.02em;
  margin: 0 !important;
  padding: 0 !important;
}

/* Text rows — block-level, full width, centred by text-align + flexbox parent.
   min-width: 0 is CRITICAL so long filenames trigger text-overflow: ellipsis
   instead of forcing the flex item wider than the modal. */
#cd_dl_modal > .moo-cddl__title,
#cd_dl_modal > .moo-cddl__filename,
#cd_dl_modal > .moo-cddl__phase,
#cd_dl_modal > .moo-cddl__bytes {
  display: block !important;
  width: 100% !important;
  max-width: 100% !important;
  min-width: 0 !important;
  text-align: center !important;
  flex-shrink: 0 !important;
  box-sizing: border-box !important;
  padding: 0 !important;
}
#cd_dl_modal > .moo-cddl__title {
  font-size: 16px !important;
  font-weight: 700 !important;
  color: var(--color-text-primary) !important;
  letter-spacing: 0.01em;
  margin: 0 0 6px 0 !important;
}
#cd_dl_modal > .moo-cddl__filename {
  font-size: 12px !important;
  color: rgba(255, 255, 255, 0.48) !important;
  white-space: nowrap !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
  margin: 0 0 20px 0 !important;
  font-weight: 500 !important;
}
#cd_dl_modal > .moo-cddl__phase {
  font-size: 13px !important;
  font-weight: 600 !important;
  color: rgba(0, 229, 160, 0.9) !important;
  letter-spacing: 0.02em;
  text-transform: uppercase !important;
  margin: 0 0 6px 0 !important;
}
#cd_dl_modal > .moo-cddl__bytes {
  font-size: 12px !important;
  color: rgba(255, 255, 255, 0.5) !important;
  font-variant-numeric: tabular-nums !important;
  font-family: 'SF Mono', 'JetBrains Mono', ui-monospace, Menlo, Consolas, monospace !important;
  min-height: 1em !important;
  margin: 0 !important;
}

/* Tight layout on narrow screens */
@media (max-width: 520px) {
  .moo-cdu__summary {
    flex-direction: column;
    align-items: flex-start;
    gap: 14px;
  }
  .moo-cdu__ring-wrap { align-self: center; }
  .moo-cdu__stats { width: 100%; justify-content: center; }
  .moo-cdu__item {
    grid-template-columns: 34px 1fr auto;
    gap: 10px;
    padding: 9px 10px;
  }
  .moo-cdu__icon { width: 34px; height: 34px; font-size: 14px; }
  .moo-cdu__name { font-size: 12.5px; }
  .moo-cdu__meta { font-size: 10.5px; }
  .moo-cdu__item-retry { grid-column: 3; grid-row: 1; }
  /* On mobile, failed items show the retry button in column 3 instead of the
     state indicator — hide the state icon to prevent overlap. Using a direct
     class selector instead of :has() for older Firefox compatibility. */
  .moo-cdu__item--failed .moo-cdu__state { display: none; }
}

/* Cloud Drive Modals — all use position: absolute for keyboard awareness */
#cdf_wrap, #cdr_wrap, #cdm_wrap, #cdi_wrap, #cdd_wrap, #cds_wrap, #cda_wrap, #cdhf_wrap {
  position: absolute;
  inset: 0;
  background: rgba(6, 13, 16, 0.7);
  z-index: 999;
  animation: mooOverlayIn 0.2s ease-out;
}
#cdf_modal, #cdr_modal, #cdm_modal, #cdi_modal, #cdd_modal, #cds_modal, #cda_modal, #cdhf_modal {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  flex-direction: column;
  background: rgba(20, 30, 38, 0.95);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 24px;
  width: min(380px, calc(100% - 48px));
  max-height: calc(100vh - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px) - 48px);
  max-height: calc(100dvh - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px) - 48px);
  z-index: 9999;
  color: var(--color-text-primary);
  animation: mooModalIn 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  overflow: hidden;
}
.moo-cd-modal__error {
  font-size: 12px;
  color: var(--color-danger);
  font-weight: 600;
  text-align: center;
  margin-top: 8px;
}
.moo-cd-modal__error:empty {
  display: none;
}
.moo-cd-modal__error--padded {
  padding: 0 24px;
}

/* Rename modal: input + extension-suffix pill. The pill carries the full
 * extension (".pdf", ".tar.gz" via lastIndexOf — see cdSplitExt) and is
 * non-editable so renames can't accidentally drop or change the type.
 * Hidden via :empty for folders / extension-less files so the input can
 * span the full row.
 *
 * Padding/font/line-height mirror .moo-nc-modal__input (16px vertical
 * padding, 16px font, 1.2 line-height) so the pill renders at the same
 * height as the input without flex-stretch — flex-stretch + a flex
 * container breaks text-overflow:ellipsis, and the inputs already have
 * stable padding so the mirror is robust enough. */
.moo-cd-rename__row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.moo-cd-rename__row .moo-nc-modal__input {
  flex: 1;
  min-width: 0;
}
.moo-cd-rename__ext {
  flex: 0 0 auto;
  max-width: 45%;
  padding: 16px 14px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 14px;
  color: rgba(255, 255, 255, 0.55);
  font-size: 16px;
  font-weight: 600;
  font-family: 'Montserrat', sans-serif;
  line-height: 1.2;
  box-sizing: border-box;
  user-select: none;
  -webkit-user-select: none;
  pointer-events: none;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.moo-cd-rename__ext:empty {
  display: none;
}

/* Move modal list — margin above + below separates the scrollable list from
   the modal header ("Move To" title) and the actions footer ("Move Here"
   button) so items never visually touch either when scrolled. Subtle top +
   bottom borders reinforce the separation. */
.moo-cd-move__list {
  max-height: 250px;
  overflow-y: auto;
  overscroll-behavior: none;
  padding: 8px 0;
  margin: 12px 0;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
.moo-cd-move__item {
  padding: 12px 24px;
  font-size: 14px;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.6);
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 12px;
  transition: background 0.12s;
  border-bottom: 1px solid rgba(255, 255, 255, 0.04);
}
.moo-cd-move__item:last-child {
  border-bottom: none;
}
.moo-cd-move__item:active {
  background: rgba(14, 22, 28, 0.92);
}
.moo-cd-move__item--selected {
  background: rgba(0, 229, 160, 0.08);
  color: var(--color-accent);
  font-weight: 600;
}

/* File info modal */
.moo-cd-info__body {
  padding: 16px 24px;
}
.moo-cd-info__row {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  padding: 12px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.04);
  gap: 16px;
}
.moo-cd-info__row:last-child {
  border-bottom: none;
}
.moo-cd-info__label {
  font-size: 13px;
  color: rgba(255, 255, 255, 0.35);
  font-weight: 500;
  flex-shrink: 0;
}
.moo-cd-info__value {
  font-size: 14px;
  color: var(--color-text-primary);
  font-weight: 500;
  text-align: right;
  word-break: break-all;
}

/* Delete modals — match .moo-da-modal pattern */
#cdd_modal .moo-nc-modal__body,
#cda_modal .moo-nc-modal__body {
  padding: 16px 24px;
}
#cdd_modal .moo-nc-modal__actions,
#cda_modal .moo-nc-modal__actions {
  padding: 0 24px 20px;
}
.moo-cd-delete__msg {
  font-size: 14px;
  color: rgba(255, 255, 255, 0.5);
  line-height: 1.5;
}
.moo-cd-delete__cancel {
  flex: 1;
  padding: 14px 20px !important;
  background: rgba(16, 24, 30, 0.92) !important;
  border: 1px solid rgba(255, 255, 255, 0.1) !important;
  border-radius: 12px !important;
  color: rgba(255, 255, 255, 0.5) !important;
  font-weight: 700 !important;
  font-size: 14px !important;
  font-family: 'Montserrat', sans-serif !important;
  cursor: pointer;
}
.moo-cd-delete__cancel:active {
  background: rgba(28, 36, 44, 0.92) !important;
}
.moo-cd-delete__confirm {
  flex: 1;
  padding: 14px 20px !important;
  white-space: nowrap;
  background: linear-gradient(135deg, var(--color-danger), var(--color-danger-dark)) !important;
  border: none !important;
  border-radius: 12px !important;
  color: var(--color-white) !important;
  font-weight: 700 !important;
  font-size: 14px !important;
  font-family: 'Montserrat', sans-serif !important;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}
.moo-cd-delete__confirm:active {
  opacity: 0.85;
}

/* Cloud Drive Settings Modal */
.moo-cd-settings__section {
  padding: 20px 24px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
.moo-cd-settings__section:last-child {
  border-bottom: none;
}
.moo-cd-settings__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.moo-cd-settings__label {
  flex: 1;
  min-width: 0;
}
.moo-cd-settings__label-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--color-text-primary);
}
.moo-cd-settings__label-desc {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.4);
  margin-top: 4px;
  line-height: 1.4;
}
.moo-cd-settings__section--danger {
  padding: 16px 24px;
}
.moo-cd-settings__danger-btn {
  width: 100%;
  padding: 14px 20px !important;
  background: rgba(244, 63, 94, 0.1) !important;
  border: 1px solid rgba(244, 63, 94, 0.2) !important;
  border-radius: 12px !important;
  color: var(--color-danger) !important;
  font-weight: 700 !important;
  font-size: 14px !important;
  font-family: 'Montserrat', sans-serif !important;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}
.moo-cd-settings__danger-btn:active {
  background: rgba(244, 63, 94, 0.2) !important;
}
#cds_modal .moo-nc-modal__actions {
  padding: 0 24px 20px;
}
.moo-nc-modal__create:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}


/* ---- Gang Rota ---- */
.moo-gr-holiday {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px 20px;
  background: rgba(245, 158, 11, 0.08);
  border: 1px solid rgba(245, 158, 11, 0.15);
  border-radius: 16px;
  color: var(--color-warning);
  font-size: 14px;
  font-weight: 600;
  margin-bottom: 24px;
}
.moo-gr-holiday i {
  font-size: 18px;
  flex-shrink: 0;
}
.moo-gr-section-label {
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: rgba(255, 255, 255, 0.4);
  margin-bottom: 12px;
  margin-top: 24px;
}
.moo-gr-section-label:first-child,
.moo-gr-holiday + .moo-gr-section-label {
  margin-top: 0;
}
.moo-gr-card {
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 18px 20px;
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 20px;
  max-width: 500px;
}
.moo-gr-card--active {
  background: rgba(0, 229, 160, 0.06);
  border-color: rgba(0, 229, 160, 0.2);
}
.moo-gr-card__photo {
  width: 30%;
  max-width: 100px;
  overflow: hidden;
  flex-shrink: 0;
}
.moo-gr-card__photo img {
  width: 100%;
  height: auto;
  border-radius: 12px;
}
.moo-gr-card__name {
  font-size: 18px;
  font-weight: 700;
  color: var(--color-text-primary);
}
.moo-gr-card__detail {
  font-size: 14px;
  color: rgba(255, 255, 255, 0.4);
  margin-top: 4px;
}
.moo-gr-card--active .moo-gr-card__name {
  color: var(--color-accent);
}
.moo-gr-card--active .moo-gr-card__detail {
  color: rgba(255, 255, 255, 0.6);
}
.moo-gr-upcoming {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* ---- Admin / Developer tables ---- */
.moo-tools .table_cont {
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 20px;
  overflow: hidden;
}
.moo-tools .table_header {
  background: rgba(14, 22, 28, 0.92);
  padding: 16px 20px;
  color: var(--color-text-primary);
  font-weight: 700;
  font-size: 16px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  display: flex;
  align-items: center;
  gap: 10px;
}
.moo-tools .table_header i {
  color: var(--color-accent);
  font-size: 14px;
}
.moo-tools .table_content {
  background: transparent;
}
.moo-tools .table_headers {
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: rgba(255, 255, 255, 0.4);
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
.moo-tools .table_row {
  font-size: 13px;
  color: rgba(255, 255, 255, 0.6);
}
.moo-tools .table_row_content {
  border-bottom: 1px solid rgba(255, 255, 255, 0.04);
}
.moo-tools .table_row_content:last-child {
  border-bottom: 0;
}
.moo-tools .table_row_content:nth-child(odd) {
  background: rgba(14, 22, 28, 0.88);
}
.moo-tools .table_row_content b {
  color: rgba(255, 255, 255, 0.8);
}
.moo-tools .table_column {
  padding: 14px 16px;
  font-size: 13px;
}
.moo-tools .table_buttons button {
  background: rgba(244, 63, 94, 0.1) !important;
  border: 1px solid rgba(244, 63, 94, 0.2) !important;
  color: var(--color-danger) !important;
  border-radius: 8px !important;
  width: 28px !important;
  height: 28px !important;
  padding: 0 !important;
  cursor: pointer;
  transition: opacity 0.2s, background-color 0.2s;
}
.moo-tools .table_buttons button:hover {
  background: rgba(244, 63, 94, 0.2) !important;
}
.moo-tools .fa_eye_slash_button {
  background: rgba(245, 158, 11, 0.1) !important;
  border: 1px solid rgba(245, 158, 11, 0.2) !important;
  color: var(--color-warning) !important;
}
.moo-tools .fa_eye_slash_button:hover {
  background: rgba(245, 158, 11, 0.2) !important;
}
.moo-tools .table_open_content_button {
  background: rgba(0, 229, 160, 0.1);
  border: 1px solid rgba(0, 229, 160, 0.15);
  color: var(--color-accent);
  border-radius: 8px;
  font-size: 12px;
  font-weight: 700;
  padding: 0 12px;
  height: 28px;
}
.moo-tools .table_norows {
  padding: 20px;
  color: rgba(255, 255, 255, 0.3);
  font-size: 14px;
  text-align: left;
}
.moo-tools .tc_margintop {
  margin-top: 16px;
}

/* Content dialog modal (admin) */
body:has(.moo-tools) #content_dialog_wrap {
  background: rgba(6, 13, 16, 0.6);
  animation: mooOverlayIn 0.2s ease-out;
}
body:has(.moo-tools) #cd_popup {
  background: rgba(20, 30, 38, 0.9);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 20px;
  padding: 24px;
  width: 80%;
  max-height: 80%;
  color: rgba(255, 255, 255, 0.7);
  animation: mooModalIn 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
body:has(.moo-tools) .content_dialog_text {
  font-size: 14px;
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.6);
}

/* Beehive logo */
.moo-tools .hli_cont {
  margin-bottom: 12px;
}
.moo-tools .hive_logo_img {
  border-radius: 16px;
}

/* Tools responsive */
@media (max-width: 480px) {
  .moo-tools .moo-settings-card {
    padding: 20px;
    border-radius: 16px;
  }
  .moo-tools .moo-form-card {
    padding: 28px 24px;
    border-radius: 20px;
  }
  .moo-tools__item {
    padding: 16px;
    border-radius: 16px;
  }
  .moo-tools__item-icon {
    width: 38px;
    height: 38px;
    font-size: 16px;
  }
  .moo-tools .table_column {
    padding: 10px 12px;
    font-size: 12px;
  }
}

/* ===== CHATS LIST PAGE OVERHAUL ===== */

/* Page background */
html:has(.moo-chats) {
  background: var(--color-bg);
}
body:has(.moo-chats) {
  background:
    radial-gradient(ellipse at 60% 20%, rgba(14, 165, 233, 0.12) 0%, transparent 50%),
    radial-gradient(ellipse at 40% 80%, rgba(99, 102, 241, 0.1) 0%, transparent 50%),
    radial-gradient(ellipse at 50% 50%, rgba(244, 63, 94, 0.06) 0%, transparent 40%),
    var(--color-bg);
}

/* Header — dark glass */
body:has(.moo-chats) .chat_top_info.header_top {
  background: rgba(6, 13, 16, 0.97);
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
body:has(.moo-chats) .hb_button {
  background: rgba(24, 32, 40, 0.92);
  color: var(--color-text-primary);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 10px;
  transition: opacity 0.2s, background-color 0.2s, color 0.2s, border-color 0.2s;
}
body:has(.moo-chats) .hb_button:hover {
  background: rgba(0, 229, 160, 0.15);
  border-color: rgba(0, 229, 160, 0.3);
  color: var(--color-accent);
}

/* Bottom nav — dark glass */
body:has(.moo-chats) .bottom_nav {
  background: rgba(6, 13, 16, 0.97);
  border-top: 1px solid rgba(255, 255, 255, 0.06);
}
body:has(.moo-chats) .bnm_inner,
body:has(.moo-chats) .bnm_item {
  background: rgba(6, 13, 16, 0.85);
}
body:has(.moo-chats) .bnm_item {
  color: rgba(255, 255, 255, 0.3);
}
body:has(.moo-chats) .bnm_selected {
  color: var(--color-accent);
}

/* Content area */
.moo-chats {
  background: transparent !important;
  color: var(--color-text-primary);
  padding-top: 20px !important;
  padding-bottom: 0px !important;
  height: calc(100% - 154px) !important;
}

/* Loading screen */
body:has(.moo-chats) .chatbox_loading {
  position: absolute !important;
  inset: 64px 0 67px 0 !important;
  background:
    radial-gradient(ellipse at 60% 20%, rgba(14, 165, 233, 0.12) 0%, transparent 50%),
    radial-gradient(ellipse at 40% 80%, rgba(99, 102, 241, 0.1) 0%, transparent 50%),
    var(--color-bg);
  color: var(--color-text-primary);
}
body:has(.moo-chats) .cli_spin {
  color: var(--color-accent);
  font-size: 36px;
}
body:has(.moo-chats) .cli_text {
  color: rgba(255, 255, 255, 0.5);
  font-size: 16px;
  font-weight: 600;
  margin-top: 16px;
}

/* Chat list items — glass cards */
.moo-chats .chat_cont {
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.06) !important;
  border-radius: 16px;
  padding: 16px !important;
  margin-bottom: 10px !important;
  transition: background 0.25s;
}
.moo-chats .chat_cont:active {
  background: rgba(24, 32, 40, 0.92);
}
.moo-chats .chat_cont_first {
  border: 1px solid rgba(255, 255, 255, 0.06) !important;
  padding-top: 16px !important;
}
.moo-chats .chat_cont_picture img {
  border-radius: 14px;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.06);
  /* Placeholder tint so an avatar that hasn't decoded yet reads as an intentional
     rounded tile (the list now paints before avatars finish loading). The loaded
     image (object-fit:cover) covers it. */
  background: rgba(255, 255, 255, 0.04);
}
.moo-chats .chat_name_title {
  color: var(--color-text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.moo-chats .chat_name_sub {
  color: rgba(255, 255, 255, 0.4);
}
.moo-chats .chat_cont_name {
  color: var(--color-text-primary);
  width: calc(100% - 170px);
}

/* Date/time info */
.moo-chats .chat_right_info {
  right: 16px;
}
.moo-chats .chat_right_dt {
  color: rgba(255, 255, 255, 0.35);
}

/* Muted chat icon */
.chat_muted_icon {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.25);
  margin-top: 4px;
  text-align: right;
}

/* Unread messages badge — circle at one digit, grows into a pill for 2+.
   Count is server-capped at 99+ (raw 3-digit counts overflowed the old fixed
   22px circle). */
.moo-chats .chat_unread_messages {
  background-color: var(--color-accent);
  color: var(--color-bg);
  font-size: 11px;
  width: auto;
  min-width: 22px;
  height: 22px;
  padding: 0 6px;
  box-sizing: border-box;
  border-radius: 11px;
}

/* Chat rows are block-level so the FLIP reorder transform applies (anchors
   are inline by default, and transforms don't render on inline boxes). The
   animation itself is Web Animations API in loadChats — no transition class
   here; reduced motion is gated in JS (_mooReducedMotion). */
.moo-chats .cli_finder {
  display: block;
}

/* No chats empty state — an invitation to act, not a dead end */
.moo-chats .chats_list_none {
  text-align: center;
  padding: 56px 24px;
}
.moo-chats .cln_icon {
  width: 56px;
  height: 56px;
  margin: 0 auto;
  border-radius: 14px;
  background: rgba(0, 229, 160, 0.08);
  border: 1px solid rgba(0, 229, 160, 0.14);
  color: var(--color-accent);
  font-size: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.moo-chats .cln_title {
  margin-top: 16px;
  font-size: 16px;
  font-weight: 700;
  color: var(--color-text-primary);
}
.moo-chats .cln_text {
  margin-top: 6px;
  margin-left: auto;
  margin-right: auto;
  max-width: 280px;
  font-size: 13px;
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.45);
}
.moo-chats .cln_button {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 18px;
  padding: 11px 18px;
  border: none;
  border-radius: 12px;
  background: linear-gradient(135deg, var(--color-accent), var(--color-accent-dark));
  color: var(--color-bg);
  font-family: 'Montserrat', sans-serif;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform 0.18s ease, filter 0.18s ease;
}
.moo-chats .cln_button:hover {
  filter: brightness(1.06);
}
.moo-chats .cln_button:active {
  transform: scale(0.97);
}

/* Connection-failure notice (mooChatsPollFailed shows it after 3 misses) */
.moo-chats .chats_list_error {
  display: none;
  text-align: center;
  padding: 56px 24px;
  font-size: 14px;
  color: rgba(255, 255, 255, 0.45);
}

/* Last chat item — bottom spacing via margin to work around WebKit ignoring padding-bottom on scroll containers */
.moo-chats > a:last-of-type .chat_cont {
  margin-bottom: 0 !important;
}
.moo-chats::after {
  content: '';
  display: block;
  height: 20px;
}

/* ---- Modal — frosted glass ---- */
body:has(.moo-chats) #chats_popup_wrap {
  background: rgba(6, 13, 16, 0.6);
  animation: mooOverlayIn 0.2s ease-out;
}
body:has(.moo-chats) #chats_popup {
  background: rgba(20, 30, 38, 0.85);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 24px;
  padding: 32px;
  width: min(320px, 80%);
  color: var(--color-text-primary);
  animation: mooModalIn 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

/* Message Yourself form button — styled like moo-modal__option */
.moo-modal__option--form {
  padding: 0;
  background: none;
  border: none;
}
.moo-modal__option--form form {
  width: 100%;
}
.moo-modal__option--form button {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 18px;
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 14px;
  color: var(--color-text-primary);
  font-size: 15px;
  font-weight: 600;
  font-family: 'Montserrat', sans-serif;
  text-decoration: none;
  transition: opacity 0.2s, background-color 0.2s, border-color 0.2s;
  width: 100%;
  cursor: pointer;
  text-align: left;
}
.moo-modal__option--form button:hover {
  background: rgba(0, 229, 160, 0.08);
  border-color: rgba(0, 229, 160, 0.2);
}
.moo-modal__option--form button:active {
  background: rgba(0, 229, 160, 0.14);
}
.moo-modal__option--form button i {
  color: var(--color-accent);
  font-size: 16px;
  width: 24px;
  text-align: center;
  flex-shrink: 0;
}

/* ===== CHAT INFO PAGE OVERHAUL ===== */

/* Page background */
/* These page-level rules style the STANDALONE /info page. The :not(:has(.moo-info-panel))
   guard keeps them from firing when .moo-chatinfo is an injected slide-over fragment
   inside the chat (.moo-info-panel) — otherwise they re-tint the live chat header and
   dim a peer's mint presence while the panel is open. */
html:has(.moo-chatinfo):not(:has(.moo-info-panel)) {
  background: var(--color-bg);
}
body:has(.moo-chatinfo):not(:has(.moo-info-panel)) {
  background:
    radial-gradient(ellipse at 60% 20%, rgba(14, 165, 233, 0.12) 0%, transparent 50%),
    radial-gradient(ellipse at 40% 80%, rgba(99, 102, 241, 0.1) 0%, transparent 50%),
    radial-gradient(ellipse at 50% 50%, rgba(244, 63, 94, 0.06) 0%, transparent 40%),
    var(--color-bg);
}

/* Header — dark glass */
body:has(.moo-chatinfo):not(:has(.moo-info-panel)) .chat_top_info {
  background: rgba(6, 13, 16, 0.97);
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
body:has(.moo-chatinfo):not(:has(.moo-info-panel)) .chat_back_button {
  background: rgba(24, 32, 40, 0.92);
  color: var(--color-text-primary);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 10px;
}
body:has(.moo-chatinfo):not(:has(.moo-info-panel)) .chat_other_name {
  color: var(--color-text-primary);
}
body:has(.moo-chatinfo):not(:has(.moo-info-panel)) #chat_online_status {
  color: rgba(255, 255, 255, 0.4);
}
body:has(.moo-chatinfo):not(:has(.moo-info-panel)) .my_top_display {
  color: rgba(255, 255, 255, 0.4);
}

/* Content area */
.moo-chatinfo {
  background: transparent !important;
  color: var(--color-text-primary);
  padding: 20px !important;
  height: calc(100% - 104px) !important;
  width: calc(100% - 40px) !important;
}

/* F14: /info slide-over panel — fetched .moo-chatinfo fragment slides in over
   the chat view (no full-page reload, DEK reused). Right-anchored; full-width on
   phones, a side sheet on desktop. */
.moo-info-panel {
  position: fixed;
  top: 0; /* JS sets this to the chat top-bar's bottom on open */
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 10000;
  display: flex;
  flex-direction: column;
  background: var(--color-bg);
  transform: translateX(100%);
  transition: transform 0.28s cubic-bezier(0.4, 0, 0.2, 1);
}
.moo-info-panel.is-open { transform: translateX(0); }
.moo-info-panel__body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: none;
  padding-bottom: env(safe-area-inset-bottom);
}
/* The injected fragment keeps its .chat_info_cont class (overflow:scroll +
   overscroll-behavior:none). With auto height it can't scroll yet TRAPS the
   desktop wheel — force it to a plain flow block so the panel body is the single
   scroller (touch already worked; this restores wheel scrolling). */
.moo-info-panel .moo-chatinfo { height: auto !important; overflow: visible !important; }
@media (prefers-reduced-motion: reduce) {
  .moo-info-panel {
    transition: opacity 0.2s ease;
    transform: none;
    opacity: 0;
    pointer-events: none;
  }
  .moo-info-panel.is-open { opacity: 1; pointer-events: auto; }
}

/* Settings cards — reuse pattern */
.moo-chatinfo .moo-settings-card {
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 20px;
  padding: 24px;
  margin-bottom: 16px;
}
.moo-chatinfo .moo-settings-card:last-child,
.moo-chatinfo .moo-settings-card:last-of-type,
.moo-chatinfo .moo-form-card:last-child,
.moo-chatinfo .moo-form-card:last-of-type {
  margin-bottom: 0;
}
.moo-chatinfo .moo-settings-card__header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
}
.moo-chatinfo .moo-settings-card__icon {
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: rgba(0, 229, 160, 0.1);
  border: 1px solid rgba(0, 229, 160, 0.15);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-accent);
  font-size: 14px;
  flex-shrink: 0;
}
/* F5: muted notifications icon (warning tint), toggled by the inline mute JS. */
.moo-chatinfo .moo-settings-card__icon.is-muted {
  background: rgba(245, 158, 11, 0.1);
  border-color: rgba(245, 158, 11, 0.15);
  color: var(--color-warning);
}
.moo-chatinfo .moo-settings-card .settings_item_title {
  color: var(--color-text-primary);
  font-size: 17px;
  font-weight: 700;
  margin-bottom: 0;
  line-height: 1;
}

/* Card inline forms (Group Name) */
.moo-chatinfo .moo-settings-card form:not(.ap_inner) {
  display: flex;
  gap: 10px;
}
.moo-chatinfo .moo-settings-card input[type="text"],
.moo-chatinfo .moo-settings-card input[type="tel"] {
  flex: 1;
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  color: var(--color-text-primary);
  padding: 12px 16px;
  font-size: 15px;
  font-weight: 500;
  font-family: 'Montserrat', sans-serif;
  width: auto;
  margin: 0;
  transition: border-color 0.3s;
  -webkit-appearance: none;
  user-select: text;
  -webkit-user-select: text;
  touch-action: manipulation;
}
.moo-chatinfo .moo-settings-card input:focus {
  border-color: rgba(0, 229, 160, 0.4);
}
.moo-chatinfo .moo-settings-card input[readonly] {
  color: rgba(255, 255, 255, 0.5);
  border-color: rgba(255, 255, 255, 0.06);
  cursor: default;
}
.moo-chatinfo .moo-settings-card button[type="submit"],
.moo-chatinfo .moo-settings-card button[type="button"]:not(.moo-enc-enable-btn):not(.moo-chat-media__show-all):not(.moo-member-btn) {
  background: rgba(18, 26, 32, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  color: var(--color-text-primary);
  padding: 12px 20px;
  font-size: 14px;
  font-weight: 700;
  font-family: 'Montserrat', sans-serif;
  cursor: pointer;
  transition: opacity 0.2s, background-color 0.2s, color 0.2s, border-color 0.2s;
  white-space: nowrap;
  width: auto;
  height: auto;
  margin: 0;
}
.moo-chatinfo .moo-settings-card button[type="submit"]:hover,
.moo-chatinfo .moo-settings-card button[type="button"]:not(.moo-enc-enable-btn):not(.moo-chat-media__show-all):not(.moo-member-btn):hover {
  background: rgba(0, 229, 160, 0.1);
  border-color: rgba(0, 229, 160, 0.25);
  color: var(--color-accent);
}

/* Group picture */
.moo-chatinfo .moo-settings-card .ap_inner {
  display: flex;
  align-items: center;
  gap: 16px;
}
.moo-chatinfo .moo-settings-card .ap_inner img {
  width: 56px;
  height: 56px;
  border-radius: 14px;
  object-fit: cover;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.08);
  flex-shrink: 0;
}
.moo-chatinfo .moo-ap-buttons {
  display: flex;
  gap: 8px;
  height: 56px;
}
.moo-chatinfo .moo-ap-buttons button {
  height: 100% !important;
}
.moo-chatinfo .moo-btn-danger-outline {
  background: transparent !important;
  border: 1px solid rgba(244, 63, 94, 0.3) !important;
  color: var(--color-danger) !important;
}
.moo-chatinfo .moo-btn-danger-outline:hover {
  background: rgba(244, 63, 94, 0.1) !important;
  border-color: rgba(244, 63, 94, 0.4) !important;
}

/* Chat participants list */
.moo-chatinfo .chat_participants {
  margin-top: 8px;
}
.moo-chatinfo .chat_cont {
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.06) !important;
  border-radius: 14px;
  padding: 14px !important;
  margin-bottom: 8px !important;
  transition: background 0.25s;
}
.moo-chatinfo .chat_cont:active {
  background: rgba(24, 32, 40, 0.92);
}
.moo-chatinfo .chat_cont_first {
  border: 1px solid rgba(255, 255, 255, 0.06) !important;
  padding-top: 14px !important;
}
.moo-chatinfo .chat_cont_picture img {
  border-radius: 12px;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.06);
}
.moo-chatinfo .chat_cont_name {
  width: calc(100% - 80px);
}
.moo-chatinfo .chat_name_title {
  color: var(--color-text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.moo-chatinfo .chat_participants > a:last-child .chat_cont,
.moo-chatinfo .chat_participants > .chat_cont:last-child {
  margin-bottom: 0 !important;
}

/* Return messages */
.moo-chatinfo .settings_returnMessage {
  background: rgba(0, 229, 160, 0.08);
  border: 1px solid rgba(0, 229, 160, 0.15);
  border-radius: 16px;
  color: var(--color-text-primary);
  padding: 18px 24px;
  font-size: 15px;
  font-weight: 600;
  text-align: left;
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
}
.moo-chatinfo .settings_returnMessage i {
  color: var(--color-accent);
  font-size: 18px;
  flex-shrink: 0;
}

/* Leave chat button */
.moo-chatinfo__leave {
  margin-top: 16px;
}
.moo-chatinfo__leave button {
  width: 100%;
  padding: 16px 24px;
  background: rgba(244, 63, 94, 0.08);
  border: 1px solid rgba(244, 63, 94, 0.2);
  border-radius: 14px;
  color: var(--color-danger);
  font-weight: 700;
  font-size: 15px;
  font-family: 'Montserrat', sans-serif;
  cursor: pointer;
  transition: opacity 0.2s, background-color 0.2s;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.moo-chatinfo__leave button:hover {
  background: rgba(244, 63, 94, 0.15);
}

/* Leave chat confirmation dialog */
.moo-chatinfo__confirm {
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 20px;
  padding: 32px;
  text-align: center;
  margin-bottom: 16px;
}
.moo-chatinfo__confirm-icon {
  font-size: 28px;
  color: var(--color-danger);
  margin-bottom: 16px;
}
.moo-chatinfo__confirm-text {
  color: rgba(255, 255, 255, 0.7);
  font-size: 16px;
  font-weight: 600;
  line-height: 1.5;
  margin-bottom: 24px;
}
.moo-chatinfo__confirm form {
  display: flex;
  gap: 10px;
}
.moo-chatinfo__confirm-btn--secondary {
  flex: 1;
  padding: 14px !important;
  width: auto !important;
  height: auto !important;
  background: rgba(18, 26, 32, 0.92) !important;
  border: 1px solid rgba(255, 255, 255, 0.1) !important;
  border-radius: 14px !important;
  color: rgba(255, 255, 255, 0.6) !important;
  font-weight: 600 !important;
  font-size: 15px !important;
  font-family: 'Montserrat', sans-serif;
  cursor: pointer;
  transition: opacity 0.2s, background-color 0.2s;
}
.moo-chatinfo__confirm-btn--secondary:hover {
  background: rgba(28, 36, 44, 0.92) !important;
}
.moo-chatinfo__confirm-btn--danger {
  flex: 1;
  padding: 14px !important;
  width: auto !important;
  height: auto !important;
  background: rgba(244, 63, 94, 0.15) !important;
  border: 1px solid rgba(244, 63, 94, 0.25) !important;
  border-radius: 14px !important;
  color: var(--color-danger) !important;
  font-weight: 700 !important;
  font-size: 15px !important;
  font-family: 'Montserrat', sans-serif;
  cursor: pointer;
  transition: opacity 0.2s, background-color 0.2s;
}
.moo-chatinfo__confirm-btn--danger:hover {
  background: rgba(244, 63, 94, 0.25) !important;
}

/* ===== GROUP ADMIN ROLES ===== */

/* Member badges row */
.moo-member-badges {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 3px;
}

/* Admin badge pill */
.moo-admin-badge {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  background: rgba(0, 229, 160, 0.1);
  border: 1px solid rgba(0, 229, 160, 0.18);
  color: var(--color-accent);
  font-size: 9px;
  font-weight: 800;
  padding: 2px 7px;
  border-radius: 6px;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  line-height: 1.4;
}
.moo-admin-badge i {
  font-size: 7px;
}

/* You badge */
.moo-you-badge {
  color: rgba(255, 255, 255, 0.3);
  font-size: 11px;
  font-weight: 600;
}

/* Pending badge — E2EE chats, member waiting on DEK wrap completion */
.moo-pending-badge {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  background: rgba(251, 191, 36, 0.1);
  border: 1px solid rgba(251, 191, 36, 0.2);
  color: var(--color-warning);
  font-size: 9px;
  font-weight: 800;
  padding: 2px 7px;
  border-radius: 6px;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  line-height: 1.4;
}
.moo-pending-badge i {
  font-size: 7px;
}

/* Member row with action buttons (admin view) */
.moo-chatinfo .moo-member-row {
  display: flex;
  align-items: center;
}
.moo-chatinfo .moo-member-link {
  display: flex;
  align-items: center;
  flex: 1;
  min-width: 0;
  color: inherit;
  text-decoration: none;
}
.moo-chatinfo .moo-member-row .chat_cont_name {
  width: auto;
  flex: 1;
  min-width: 0;
}
.moo-chatinfo .moo-member-actions {
  display: flex;
  gap: 6px;
  flex-shrink: 0;
  margin-left: 8px;
}
.moo-chatinfo .moo-member-btn {
  width: 28px;
  height: 28px;
  border-radius: 8px;
  border: 1px solid rgba(255, 255, 255, 0.08);
  background: rgba(14, 22, 28, 0.92);
  color: rgba(255, 255, 255, 0.35);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: 11px;
  transition: opacity 0.2s, background-color 0.2s, color 0.2s, border-color 0.2s;
  padding: 0;
}
.moo-chatinfo .moo-member-btn:hover {
  background: rgba(0, 229, 160, 0.1);
  border-color: rgba(0, 229, 160, 0.25);
  color: var(--color-accent);
}
.moo-chatinfo .moo-member-btn--active {
  background: rgba(0, 229, 160, 0.1);
  border-color: rgba(0, 229, 160, 0.2);
  color: var(--color-accent);
}
.moo-chatinfo .moo-member-btn--danger:hover {
  background: rgba(244, 63, 94, 0.1) !important;
  border-color: rgba(244, 63, 94, 0.25) !important;
  color: var(--color-danger) !important;
}

/* Remove member modal */
#grm_wrap {
  position: absolute;
  inset: 0;
  background: rgba(6, 13, 16, 0.7);
  z-index: 100000; /* above the F14 /info slide-over panel (10000) */
  animation: mooOverlayIn 0.2s ease-out;
}
#grm_modal {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 100001;
  background: rgba(20, 30, 38, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 20px;
  padding: 28px;
  width: min(340px, calc(100% - 48px));
  text-align: center;
  animation: mooModalIn 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.moo-grm__icon {
  width: 48px;
  height: 48px;
  border-radius: 14px;
  background: rgba(244, 63, 94, 0.1);
  border: 1px solid rgba(244, 63, 94, 0.15);
  color: var(--color-danger);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  margin: 0 auto 16px;
}
.moo-grm__title {
  font-size: 18px;
  font-weight: 800;
  color: var(--color-text-primary);
  margin-bottom: 8px;
}
.moo-grm__text {
  font-size: 14px;
  color: rgba(255, 255, 255, 0.5);
  line-height: 1.5;
  margin-bottom: 24px;
}
.moo-grm__text strong {
  color: var(--color-text-primary);
  font-weight: 700;
}
.moo-grm__buttons {
  display: flex;
  gap: 10px;
}
.moo-grm__btn {
  flex: 1;
  padding: 13px 16px;
  border-radius: 12px;
  font-size: 14px;
  font-weight: 700;
  font-family: 'Montserrat', sans-serif;
  cursor: pointer;
  transition: opacity 0.2s, background-color 0.2s, color 0.2s, border-color 0.2s;
  border: none;
}
.moo-grm__btn--cancel {
  background: rgba(18, 26, 32, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
  color: var(--color-text-primary);
}
.moo-grm__btn--cancel:hover {
  background: rgba(28, 36, 44, 0.92);
}
.moo-grm__btn--remove {
  background: rgba(244, 63, 94, 0.15);
  border: 1px solid rgba(244, 63, 94, 0.25);
  color: var(--color-danger);
}
.moo-grm__btn--remove:hover {
  background: rgba(244, 63, 94, 0.25);
}

/* Upload picture sub-page (form card) */
.moo-chatinfo .moo-form-card {
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 24px;
  padding: 36px 32px;
}
.moo-chatinfo .moo-form-icon {
  font-size: 32px;
  color: var(--color-accent);
  margin-bottom: 16px;
}
.moo-chatinfo .moo-form-card .settings_item_title {
  color: var(--color-text-primary);
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -0.3px;
  line-height: 1.2;
  margin-bottom: 10px;
}
.moo-chatinfo .moo-form-card .cn_subtext {
  color: rgba(255, 255, 255, 0.4);
  font-size: 14px;
  line-height: 1.6;
  margin-bottom: 28px;
}
.moo-chatinfo .moo-form-card form {
  display: block;
}
.moo-chatinfo .moo-form-card input[type="file"] {
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  color: rgba(255, 255, 255, 0.6);
  padding: 14px;
  font-size: 14px;
  font-family: 'Montserrat', sans-serif;
  width: calc(100% - 30px);
  margin-bottom: 24px;
  cursor: pointer;
}
.moo-chatinfo .moo-form-card button[type="submit"] {
  background: linear-gradient(135deg, var(--color-accent), var(--color-accent-dark)) !important;
  color: var(--color-bg) !important;
  border: none !important;
  border-radius: 14px !important;
  padding: 16px 24px !important;
  font-weight: 700 !important;
  font-size: 16px !important;
  font-family: 'Montserrat', sans-serif;
  width: 100% !important;
  cursor: pointer;
  transition: opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1), transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.moo-chatinfo .moo-form-card button[type="submit"]:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 32px rgba(0, 229, 160, 0.25);
}

/* Mute chat */
.moo-mute-status {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  border-radius: 12px;
  font-size: 14px;
  font-weight: 600;
  margin-bottom: 14px;
  background: rgba(245, 158, 11, 0.08);
  border: 1px solid rgba(245, 158, 11, 0.15);
  color: var(--color-warning);
}
.moo-mute-status i {
  flex-shrink: 0;
}
.moo-mute-form {
  display: flex;
  gap: 10px;
}
.moo-mute-select {
  flex: 1;
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  color: var(--color-text-primary);
  padding: 12px 16px;
  padding-right: 36px;
  font-size: 14px;
  font-weight: 500;
  font-family: 'Montserrat', sans-serif;
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='rgba(255,255,255,0.4)' stroke-width='2' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
}
.moo-mute-select option {
  background: var(--color-bg-elevated);
  color: var(--color-text-primary);
}
.moo-mute-form button {
  background: rgba(245, 158, 11, 0.1) !important;
  border: 1px solid rgba(245, 158, 11, 0.2) !important;
  border-radius: 12px !important;
  color: var(--color-warning) !important;
  padding: 12px 20px !important;
  font-size: 14px !important;
  font-weight: 700 !important;
  font-family: 'Montserrat', sans-serif;
  cursor: pointer;
  transition: opacity 0.2s, background-color 0.2s;
  white-space: nowrap;
  width: auto !important;
  height: auto !important;
  display: flex;
  align-items: center;
  gap: 8px;
}
.moo-mute-form button:hover {
  background: rgba(245, 158, 11, 0.18) !important;
}
.moo-unmute-btn {
  width: 100%;
  background: rgba(18, 26, 32, 0.92) !important;
  border: 1px solid rgba(255, 255, 255, 0.1) !important;
  border-radius: 12px !important;
  color: var(--color-text-primary) !important;
  padding: 14px 20px !important;
  font-size: 14px !important;
  font-weight: 700 !important;
  font-family: 'Montserrat', sans-serif;
  cursor: pointer;
  transition: opacity 0.2s, background-color 0.2s, color 0.2s, border-color 0.2s;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: auto !important;
}
.moo-unmute-btn:hover {
  background: rgba(0, 229, 160, 0.1) !important;
  border-color: rgba(0, 229, 160, 0.25) !important;
  color: var(--color-accent) !important;
}

/* Chat info responsive */
@media (max-width: 480px) {
  .moo-chatinfo .moo-settings-card {
    padding: 20px;
    border-radius: 16px;
  }
  .moo-chatinfo .moo-form-card {
    padding: 28px 24px;
    border-radius: 20px;
  }
  .moo-chatinfo .moo-settings-card__icon {
    width: 32px;
    height: 32px;
    font-size: 13px;
  }
  .moo-mute-form {
    flex-direction: column;
  }
}

/* ===== GLOBAL IMAGE VIEWER ===== */
#moo_img_viewer {
  position: fixed;
  inset: 0;
  z-index: 100000;
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 20px;
  padding-top: calc(20px + env(safe-area-inset-top, 0));
  padding-bottom: calc(20px + env(safe-area-inset-bottom, 0));
  animation: mooImgViewerIn 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
#moo_img_viewer_bg {
  position: absolute;
  inset: 0;
  background: rgba(6, 13, 16, 0.92);
  z-index: -1;
}
@keyframes mooImgViewerIn {
  from { opacity: 0; transform: scale(0.92); }
  to { opacity: 1; transform: scale(1); }
}
#moo_img_close {
  position: absolute;
  top: calc(16px + env(safe-area-inset-top, 0));
  right: calc(16px + env(safe-area-inset-right, 0));
  width: 44px;
  height: 44px;
  border-radius: 14px;
  background: rgba(24, 32, 40, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
  color: var(--color-text-primary);
  font-size: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: opacity 0.2s, background-color 0.2s, color 0.2s, border-color 0.2s;
  z-index: 2;
  padding: 0;
  margin: 0;
}
#moo_img_close:hover {
  background: rgba(244, 63, 94, 0.15);
  border-color: rgba(244, 63, 94, 0.3);
  color: var(--color-danger);
}
#moo_img_container {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 0;
  width: 100%;
  margin-top: 60px;
  pointer-events: none;
}
#moo_img_preview {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: 12px;
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.5);
  pointer-events: auto;
  /* The gesture handler owns all directions (pan / double-tap zoom / swipe-down
     dismiss), so opt out of the global touch-action: pan-y. */
  touch-action: none;
  transform-origin: center center;
}

/* Video.js player wrapper */
#moo_vid_wrap {
  position: relative;
  width: 100%;
  height: 100%;
  pointer-events: auto;
  /* Square corners on the open video player — keep the box-shadow for depth
   * but no rounding on the visible video frame or the title bar above it. */
  border-radius: 0;
  overflow: hidden;
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.5);
  /* Flex column so the title bar can sit ABOVE the player at full width
   * (instead of being a partial-width overlay), and the player flexes to
   * fill the remaining height. Without this layout the video would still
   * fill 100% height and push the title under it. */
  display: flex;
  flex-direction: column;
  background: #060d10;
}
#moo_vid_wrap > #moo_vid_preview,
#moo_vid_wrap > .video-js {
  flex: 1 1 auto;
  min-height: 0;
}

/* Video.js dark theme overrides */
#moo_vid_wrap .video-js {
  background-color: transparent;
  font-family: 'Montserrat', sans-serif;
}
#moo_vid_wrap .video-js .vjs-tech {
  border-radius: 0;
}
#moo_vid_wrap .vjs-big-play-button {
  background: rgba(0, 229, 160, 0.15);
  border: 2px solid rgba(0, 229, 160, 0.4);
  border-radius: 50%;
  width: 70px;
  height: 70px;
  line-height: 70px;
  font-size: 30px;
  top: 50%;
  left: 50%;
  margin-top: -35px;
  margin-left: -35px;
  transition: opacity 0.2s, background-color 0.2s, border-color 0.2s;
}
#moo_vid_wrap .vjs-big-play-button .vjs-icon-placeholder::before {
  display: flex;
  align-items: center;
  justify-content: center;
}
#moo_vid_wrap .vjs-big-play-button:hover,
#moo_vid_wrap .vjs-big-play-button:focus {
  background: rgba(0, 229, 160, 0.25);
  border-color: rgba(0, 229, 160, 0.6);
}
/* Hide the big play button while Video.js is buffering — otherwise both the
 * loading spinner AND the big play button render on top of each other during
 * the cold-start of CD video streaming (autoplay is firing in the background
 * but the first chunks aren't decrypted yet). The user only needs the spinner
 * during this window. After playback starts, vjs-has-started replaces vjs-
 * waiting and the button stays hidden naturally. If autoplay was blocked,
 * the player exits vjs-waiting without becoming vjs-has-started → big play
 * shows again so the user can manually start. */
#moo_vid_wrap .vjs-waiting:not(.vjs-has-started) .vjs-big-play-button,
#moo_vid_wrap .video-js.vjs-seeking .vjs-big-play-button,
/* During the explicit loading/recovery windows we manage via JS, NEVER show
 * the big play button or the static "paused" poster. The user clicked a file
 * (or we're auto-recovering after a stall) — they don't need a manual play
 * affordance, they need a spinner that shows we're working. The cd-loading
 * class is set in moo_open_video and cleared on `playing`; cd-recovering
 * is set in attemptRecovery and cleared on `playing`. Both layered with
 * !important to defeat Video.js's own state-class rules. */
#moo_vid_wrap.cd-loading .vjs-big-play-button,
#moo_vid_wrap.cd-loading .vjs-poster,
#moo_vid_wrap.cd-recovering .vjs-big-play-button,
#moo_vid_wrap.cd-recovering .vjs-poster {
  display: none !important;
}
/* cd-force-play: the inverse — FORCE the existing big center mint play button
 * visible when iOS blocked the unmuted autoplay of a downloaded blob (set in
 * moo_open_video on the play() rejection or the 4s backstop; removed on
 * `playing`). The 4-class second selector beats the 3-class vjs-waiting hide
 * above, so the obvious center CTA shows instead of only the small control-bar
 * play. Reuses the existing .vjs-big-play-button styling — no new button. */
#moo_vid_wrap.cd-force-play .vjs-big-play-button,
#moo_vid_wrap.cd-force-play .vjs-waiting:not(.vjs-has-started) .vjs-big-play-button {
  display: block !important;
}
/* ...and while that CTA button is up, HIDE Video.js's own loading spinner.
 * A blocked autoplay can leave the player in vjs-waiting, which renders the
 * native spinner — the user must see ONLY the button, never a spinner behind
 * it. (cd-loading is already removed when cd-force-play is set, so this only
 * suppresses Video.js's native vjs-waiting/seeking spinner.) */
#moo_vid_wrap.cd-force-play .vjs-loading-spinner {
  display: none !important;
}
/* Force the spinner visible during cd-loading + cd-recovering. Video.js may
 * exit vjs-waiting briefly during src() reset of recovery — that flash should
 * still be a spinner, not a play button. visibility: visible bypasses the
 * 300ms grace (vjs-spinner-show animation) so our managed states show the
 * spinner instantly — these states are entered explicitly and the user
 * deserves immediate feedback. */
#moo_vid_wrap.cd-loading .vjs-loading-spinner,
#moo_vid_wrap.cd-recovering .vjs-loading-spinner {
  display: block !important;
  opacity: 1 !important;
  visibility: visible !important;
}
/* During mid-stream recovery, attemptRecovery rebuilds the player by
 * calling player.src(...). Setting a new src forces HTMLVideoElement
 * currentTime back to 0 — there's no API to set currentTime before the
 * new media has reached HAVE_METADATA. We only restore resumeAt inside
 * the loadedmetadata callback, so for the ~50-300 ms between src reset
 * and metadata arriving the progress bar visibly bounces to 0:00 and
 * then snaps back to where the user actually was. Hide the time + scrub
 * UI during BOTH cd-loading and cd-recovering so the user sees only the
 * spinner during ANY load state, full stop. The bar reappears with the
 * correct currentTime as soon as `playing` clears the class. Includes
 * cd-loading so initial-open and post-seek loading states match
 * recovery's UI exactly — flickering between visible-then-hidden as
 * the video transitions through cd-loading → cd-recovering → playing
 * was the source of the "timeline jumps to start" complaint. Volume +
 * fullscreen + play/pause stay visible so the user can still interact
 * with the chrome they expect. */
#moo_vid_wrap.cd-loading .vjs-progress-control,
#moo_vid_wrap.cd-loading .vjs-current-time,
#moo_vid_wrap.cd-loading .vjs-time-divider,
#moo_vid_wrap.cd-loading .vjs-duration,
#moo_vid_wrap.cd-loading .vjs-remaining-time,
#moo_vid_wrap.cd-recovering .vjs-progress-control,
#moo_vid_wrap.cd-recovering .vjs-current-time,
#moo_vid_wrap.cd-recovering .vjs-time-divider,
#moo_vid_wrap.cd-recovering .vjs-duration,
#moo_vid_wrap.cd-recovering .vjs-remaining-time {
  visibility: hidden !important;
}
#moo_vid_wrap .vjs-control-bar {
  background: rgba(6, 13, 16, 0.85);
  border-radius: 0;
  font-family: 'Montserrat', sans-serif;
}

/* Video viewer title bar — refined caption that sits ABOVE the player at
 * full container width. Lives as a flex row at the top of #moo_vid_wrap
 * (which is now display:flex column), so it spans exactly the player's
 * width with no offset. Aurora glass-morphism dark, mint accent icon,
 * ellipsis truncation. We do NOT overlay the player — Video.js's own
 * controls (big play button, loading spinner) need an unobstructed
 * surface so the user sees the canonical engine UI, not our redundant
 * surfaces on top of it. */
.moo-vid-title {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 10px 14px;
  background: rgba(20, 30, 38, 0.92);
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  font-family: 'Montserrat', sans-serif;
  animation: mooVidTitleIn 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}
.moo-vid-title > i {
  font-size: 12px;
  color: var(--color-accent);
  opacity: 0.85;
  flex-shrink: 0;
}
.moo-vid-title__name {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.1px;
  color: rgba(255, 255, 255, 0.85);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Alarm evidence multi-camera switcher — pills in the video viewer title
   bar (only shown when an incident recorded >1 camera). Glass-morphism to
   match the alarm aesthetic; active pill takes the viewer's accent. Sits
   right of the (truncating) title name; stays inert + hidden for Cloud
   Drive video + single-camera incidents. */
.moo-evid-switcher {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 6px;
}
.moo-evid-switcher[hidden] { display: none; }
.moo-evid-switcher__pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  border-radius: 9px;
  border: 1px solid var(--alarm-border, rgba(255, 255, 255, 0.07));
  background: var(--alarm-glass-1, rgba(255, 255, 255, 0.035));
  color: var(--alarm-text-secondary, rgba(255, 255, 255, 0.62));
  font: 600 11px/1 'Montserrat', sans-serif;
  letter-spacing: 0.02em;
  cursor: pointer;
  white-space: nowrap;
  appearance: none;
  -webkit-appearance: none;
  font-family: inherit;
  transition: background-color 140ms ease, border-color 140ms ease, color 140ms ease, transform 80ms ease;
}
.moo-evid-switcher__pill > i { font-size: 10px; opacity: 0.8; }
.moo-evid-switcher__pill:active { transform: translateY(1px); }
.moo-evid-switcher__pill:hover:not(.is-active):not(.is-disabled) {
  background: var(--alarm-glass-2, rgba(255, 255, 255, 0.062));
  color: var(--alarm-text-primary, rgba(255, 255, 255, 0.95));
}
.moo-evid-switcher__pill.is-active {
  background: color-mix(in srgb, var(--color-accent) 20%, transparent);
  border-color: color-mix(in srgb, var(--color-accent) 55%, transparent);
  color: var(--color-accent);
  cursor: default;
}
.moo-evid-switcher__pill.is-disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.moo-evid-switcher__unavail {
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  opacity: 0.75;
  padding-left: 2px;
}
@media (max-width: 480px) {
  .moo-evid-switcher__pill > span:not(.moo-evid-switcher__unavail) {
    max-width: 80px;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}
@keyframes mooVidTitleIn {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ==========================================================================
 * SCRUBBER PREVIEW — YouTube-style thumbnail tooltip on the progress bar.
 * Positioned absolutely inside #moo_vid_wrap, with `left` set by JS to
 * follow the cursor. `bottom` parks it just above the Video.js control bar.
 * Mint border matches the design language; downward arrow points at the
 * cursor on the slider beneath.
 * ======================================================================== */

#moo_vid_wrap .moo-scrub-preview {
  position: absolute;
  bottom: 56px;            /* above Video.js's ~30px control bar with breathing room */
  left: 0;                 /* JS overrides this on every move */
  width: 160px;
  z-index: 5;
  pointer-events: none;
  user-select: none;
  -webkit-user-select: none;
  filter: drop-shadow(0 6px 18px rgba(0, 0, 0, 0.55));
  animation: mooScrubPreviewIn 0.12s cubic-bezier(0.4, 0, 0.2, 1);
}
#moo_vid_wrap .moo-scrub-preview[hidden] {
  display: none;
}
#moo_vid_wrap .moo-scrub-preview__frame {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: #060d10;
  border: 1px solid rgba(0, 229, 160, 0.45);
  border-radius: 8px;
  overflow: hidden;
}
/* Sprite-mode scrub: the frame element IS the canvas — background-image is
 * the decrypted sprite blob, background-position slides to the cell mapped
 * from cursor time. Set up by mooScrubSetSprite + mooScrubShowPreview. */
#moo_vid_wrap .moo-scrub-preview--sprite .moo-scrub-preview__frame {
  background-repeat: no-repeat;
  /* bg-image, bg-size, bg-position set inline by mooScrubShowPreview */
}
/* Downward triangle pointing at the slider beneath the preview. */
#moo_vid_wrap .moo-scrub-preview__frame::after {
  content: '';
  position: absolute;
  left: 50%;
  bottom: -7px;
  transform: translateX(-50%);
  width: 0;
  height: 0;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  border-top: 7px solid rgba(0, 229, 160, 0.45);
}
#moo_vid_wrap .moo-scrub-preview__time {
  margin-top: 6px;
  text-align: center;
  font-family: 'Montserrat', sans-serif;
  font-size: 11px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.85);
  letter-spacing: 0.4px;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.7);
}
@keyframes mooScrubPreviewIn {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Hide Video.js's built-in mouse-time tooltip — our preview shows the time
 * as part of the thumbnail card, no need for the redundant text overlay
 * floating above the slider track. */
#moo_vid_wrap .vjs-mouse-display,
#moo_vid_wrap .vjs-time-tooltip {
  display: none !important;
}

#moo_vid_wrap .vjs-play-progress,
#moo_vid_wrap .vjs-volume-level {
  background: var(--color-accent) !important;
}
#moo_vid_wrap .vjs-play-progress::before {
  color: var(--color-accent) !important;
}
#moo_vid_wrap .vjs-slider {
  background: rgba(28, 36, 44, 0.92);
}
#moo_vid_wrap .vjs-load-progress,
#moo_vid_wrap .vjs-load-progress div {
  background: rgba(255, 255, 255, 0.15);
}
#moo_vid_wrap .vjs-time-control {
  font-size: 12px;
  font-weight: 500;
}
#moo_vid_wrap .vjs-menu-content {
  background: rgba(6, 13, 16, 0.92);
  border-radius: 8px;
  font-family: 'Montserrat', sans-serif;
}
#moo_vid_wrap .vjs-menu li.vjs-selected,
#moo_vid_wrap .vjs-menu li.vjs-selected:hover {
  background: var(--color-accent);
  color: var(--color-bg);
}
#moo_vid_wrap .vjs-menu li:hover,
#moo_vid_wrap .vjs-menu li:focus {
  background: rgba(28, 36, 44, 0.92);
}
#moo_vid_wrap .video-js .vjs-poster {
  background-color: var(--color-bg);
}
/* Spinner — clean single-arc design.
 *
 * Video.js ships a dual-arc spinner: ::before and ::after each rotate, and a
 * `vjs-spinner-fade` keyframe animation cycles border-top-color through #fff
 * (35% keyframe) and back to gray. A static border-top-color override gets
 * defeated by the running animation, so the arcs flash white. The visual
 * effect: a green outer ring with two white arcs chasing each other —
 * reads as a "double spinner". Fix: hide the dual pseudo-elements entirely
 * and animate the spinner element itself with one solid green top arc.
 *
 * NOTE: a custom keyframe is required (not Video.js's `vjs-spinner-spin`)
 * because the spinner element relies on `transform: translate(-50%, -50%)`
 * for centering — Video.js's keyframe rotates with no translate, so applying
 * it to the outer element would clobber the translate and the spinner would
 * render in the top-left corner. This keyframe preserves the translate. */
@keyframes moo-spinner-spin-centered {
  0%   { transform: translate(-50%, -50%) rotate(0deg); }
  100% { transform: translate(-50%, -50%) rotate(360deg); }
}
#moo_vid_wrap .vjs-loading-spinner {
  border: 0.42em solid rgba(0, 229, 160, 0.18);
  border-top-color: var(--color-accent);
  width: 4em;
  height: 4em;
  /* Two animations combined: our rotation (continuous) + Video.js's own
   * `vjs-spinner-show` (a 0s/0.3s/forwards animation that flips the
   * spinner's `visibility` from hidden→visible). Video.js's base rule sets
   * the spinner to `visibility: hidden` and relies on the spinner-show
   * keyframe to reveal it after a 300ms grace; if we replace the animation
   * shorthand entirely the spinner is permanently invisible. Combining
   * keeps the natural buffering grace (fast loads don't flash) while
   * giving us the rotation. The cd-loading + cd-recovering rules below
   * force visibility immediately for our managed states. */
  animation:
    moo-spinner-spin-centered 0.85s linear infinite,
    vjs-spinner-show 0s linear 0.3s forwards !important;
}
/* Kill the dual-arc system entirely — would otherwise still flash white via
 * Video.js's vjs-spinner-fade keyframe. The element-level rotation above
 * gives us a single, on-brand, jank-free spinner. */
#moo_vid_wrap .vjs-loading-spinner::before,
#moo_vid_wrap .vjs-loading-spinner::after {
  display: none !important;
}
#moo_vid_wrap .vjs-error-display {
  background: rgba(6, 13, 16, 0.85);
  font-family: 'Montserrat', sans-serif;
}
#moo_vid_wrap .vjs-error-display .vjs-modal-dialog-content {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  color: var(--color-danger);
  padding: 20px;
}
#moo_vid_wrap .vjs-time-tooltip {
  background: rgba(6, 13, 16, 0.92);
  color: var(--color-text-primary);
  font-family: 'Montserrat', sans-serif;
  font-size: 11px;
  font-weight: 600;
  border-radius: 6px;
  padding: 4px 8px;
}
#moo_vid_wrap .vjs-remaining-time {
  color: rgba(255, 255, 255, 0.6);
  font-size: 12px;
}
#moo_vid_wrap .vjs-button > .vjs-icon-placeholder::before {
  font-size: 18px;
}
/* ===== GLOBAL FILE VIEWER (PDF / text / unsupported) ===== */
#moo_pdf_frame {
  width: 100%;
  height: 100%;
  max-width: 1000px;
  border: none;
  border-radius: 12px;
  background: #1a1a1a;
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.5);
  pointer-events: auto;
}
/* Canvas-based PDF viewer for iOS (see index.php moo_render_pdf_canvases).
 * Scrollable column of canvases, one per page, each CSS-sized to wrap width
 * so the user just scrolls to read through the whole document. */
#moo_pdf_canvas_wrap {
  width: 100%;
  height: 100%;
  max-width: 1000px;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: none;
  background: #1a1a1a;
  border-radius: 12px;
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.5);
  padding: 12px;
  box-sizing: border-box;
  pointer-events: auto;
}
#moo_pdf_canvas_wrap canvas {
  display: block;
  margin: 0 auto 12px auto;
  background: white;
  border-radius: 4px;
  max-width: 100%;
}
#moo_pdf_canvas_wrap canvas:last-child { margin-bottom: 0; }
.moo-pdf__loading,
.moo-pdf__error {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 60px;
  padding: 20px;
  color: rgba(255, 255, 255, 0.5);
  font-size: 14px;
  gap: 10px;
}
.moo-pdf__loading i { font-size: 20px; color: var(--color-accent); }
#moo_text_wrap {
  width: 100%;
  max-width: 900px;
  max-height: 100%;
  flex-direction: column;
  pointer-events: auto;
  border-radius: 14px;
  overflow: hidden;
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.5);
  background: rgba(20, 30, 38, 0.95);
  border: 1px solid rgba(255, 255, 255, 0.08);
}
#moo_text_content {
  margin: 0;
  padding: 20px 24px;
  font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
  font-size: 13px;
  line-height: 1.55;
  color: var(--color-text-primary);
  white-space: pre-wrap;
  word-break: break-word;
  overflow-y: auto;
  overscroll-behavior: none;
  max-height: 100%;
  tab-size: 2;
  -moz-tab-size: 2;
  flex: 1 1 auto;
  min-height: 0;
}

/* DOCX preview (mammoth.js HTML output) — reuses the text-wrap glass card
   but renders proper HTML instead of monospace pre. */
#moo_docx_wrap {
  width: 100%;
  max-width: 900px;
  max-height: 100%;
  flex-direction: column;
  pointer-events: auto;
  border-radius: 14px;
  overflow: hidden;
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.5);
  /* DOCX files are authored for a white page — mammoth's converted HTML
     assumes black-on-white with coloured runs/highlights/tables that become
     unreadable on the app's dark theme. Force a true white page background
     + dark text so the document looks like a real Word preview. */
  background: #ffffff;
  border: 1px solid rgba(0, 0, 0, 0.08);
}
#moo_docx_content {
  padding: 28px 32px;
  font-family: 'Montserrat', sans-serif;
  font-size: 14px;
  line-height: 1.65;
  color: #1a1a1a;
  overflow-y: auto;
  overscroll-behavior: none;
  max-height: 100%;
  flex: 1 1 auto;
  min-height: 0;
  word-wrap: break-word;
}
#moo_docx_content h1 { font-size: 22px; font-weight: 700; margin: 18px 0 10px; color: #111; }
#moo_docx_content h2 { font-size: 19px; font-weight: 700; margin: 16px 0 8px; color: #111; }
#moo_docx_content h3 { font-size: 16px; font-weight: 700; margin: 14px 0 6px; color: #111; }
#moo_docx_content h4, #moo_docx_content h5, #moo_docx_content h6 { font-size: 14px; font-weight: 700; margin: 12px 0 4px; color: #111; }
#moo_docx_content p { margin: 0 0 12px 0; }
#moo_docx_content ul, #moo_docx_content ol { margin: 0 0 12px 0; padding-left: 24px; }
#moo_docx_content li { margin-bottom: 4px; }
#moo_docx_content a { color: #0a66c2; text-decoration: underline; }
#moo_docx_content strong, #moo_docx_content b { font-weight: 700; }
#moo_docx_content em, #moo_docx_content i { font-style: italic; }
#moo_docx_content img { max-width: 100%; height: auto; border-radius: 4px; margin: 8px 0; }
#moo_docx_content table { border-collapse: collapse; width: 100%; margin: 12px 0; font-size: 13px; }
#moo_docx_content th, #moo_docx_content td {
  border: 1px solid rgba(0, 0, 0, 0.2);
  padding: 8px 12px;
  text-align: left;
  vertical-align: top;
}
#moo_docx_content th { background: rgba(0, 0, 0, 0.05); font-weight: 700; }
#moo_docx_content hr { border: none; border-top: 1px solid rgba(0, 0, 0, 0.15); margin: 16px 0; }
#moo_docx_content blockquote {
  margin: 12px 0;
  padding: 8px 16px;
  border-left: 3px solid #0a66c2;
  background: rgba(10, 102, 194, 0.06);
  border-radius: 0 4px 4px 0;
  color: #333;
}

/* ==============================================================
   XLSX PREVIEW — "ledger sheet" aesthetic
   ==============================================================
   Crisp white paper for the data, a dark-glass tab bar at the
   bottom for sheet switching. This sits INSIDE the global file
   viewer, so the dark overlay provides atmosphere and the white
   paper reads as a proper document — same treatment as DOCX for
   cohesion, but with data-density instead of flowing text.
   Typography: a monospaced stack inside the cells gives numeric
   data that refined "ledger" feel. The Montserrat display face
   stays on the tab labels and everywhere else the app uses it.
*/
#moo_xlsx_wrap {
  width: 100%;
  max-width: 1200px;
  max-height: 100%;
  flex-direction: column;
  pointer-events: auto;
  border-radius: 14px;
  overflow: hidden;
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.5);
  background: #ffffff;
  border: 1px solid rgba(0, 0, 0, 0.08);
}
#moo_xlsx_scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
  overscroll-behavior: none;
  background:
    linear-gradient(#ffffff, #ffffff),
    /* Very faint drafting-paper grid so empty area isn't a dead white void */
    repeating-linear-gradient(0deg, transparent 0, transparent 23px, rgba(0,0,0,0.025) 23px, rgba(0,0,0,0.025) 24px);
  background-attachment: local, local;
}
#moo_xlsx_content {
  padding: 0;
  min-width: fit-content;
}
.moo-xlsx__sheet {
  /* SheetJS's sheet_to_html emits one <table id="sjs-..."> per sheet.
     We target it via descendant selectors so we don't need to rewrite
     the HTML — just style what SheetJS hands us. */
  padding: 20px 24px 24px 24px;
}
.moo-xlsx__sheet table {
  border-collapse: collapse;
  font-family: 'SF Mono', 'JetBrains Mono', 'Fira Code', ui-monospace, Menlo, Consolas, monospace;
  font-size: 12.5px;
  color: #1a1a1a;
  background: #ffffff;
  /* Each sheet sits on the paper with a whisper of shadow so the
     eye has an edge to grab — very subtle, not a drop-shadow card. */
  box-shadow: 0 0 0 1px rgba(0,0,0,0.04);
  border-radius: 2px;
  table-layout: auto;
  min-width: 100%;
}
.moo-xlsx__sheet table td,
.moo-xlsx__sheet table th {
  padding: 7px 12px;
  border-right: 1px solid rgba(0,0,0,0.06);
  border-bottom: 1px solid rgba(0,0,0,0.06);
  text-align: left;
  vertical-align: top;
  white-space: nowrap;
  max-width: 420px;
  overflow: hidden;
  text-overflow: ellipsis;
  /* Tabular figures so digit columns align perfectly even inside a
     monospaced font — matters for long numeric columns. */
  font-variant-numeric: tabular-nums;
}
.moo-xlsx__sheet table tr:first-child td,
.moo-xlsx__sheet table tr:first-child th {
  /* First row styled as a header — slightly bolder, faint mint wash
     so the app's accent colour shows up in this "documents" context
     without fighting the white paper. */
  background: linear-gradient(180deg, rgba(0, 229, 160, 0.08), rgba(0, 229, 160, 0.02));
  font-weight: 700;
  color: #0d2e22;
  border-bottom: 2px solid rgba(0, 229, 160, 0.3);
  position: sticky;
  top: 0;
  z-index: 1;
}
.moo-xlsx__sheet table tr:hover td {
  background: rgba(0, 229, 160, 0.05);
}
.moo-xlsx__sheet table tr:first-child:hover td {
  /* Don't clobber the header row's gradient on hover. */
  background: linear-gradient(180deg, rgba(0, 229, 160, 0.12), rgba(0, 229, 160, 0.04));
}

/* Sheet tab bar — dark glass contrasts against the white paper.
   Same visual language as the app's bottom nav. */
#moo_xlsx_tabs {
  flex-shrink: 0;
  display: flex;
  gap: 4px;
  padding: 10px 14px;
  background: linear-gradient(180deg, rgba(10, 16, 20, 0.92), rgba(6, 13, 16, 0.96));
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  overflow-x: auto;
  overflow-y: hidden;
  /* Scope to X axis: these tabs scroll horizontally only, so vertical wheel
     events need to propagate to the outer XLSX viewer scroll container
     (was 'overscroll-behavior: none' which trapped vertical wheels). */
  overscroll-behavior-x: none;
  white-space: nowrap;
}
.moo-xlsx__tab {
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.08);
  color: rgba(255, 255, 255, 0.65);
  font-family: 'Montserrat', sans-serif;
  font-size: 12px;
  font-weight: 600;
  padding: 7px 14px;
  border-radius: 8px;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
  flex-shrink: 0;
  letter-spacing: 0.01em;
}
.moo-xlsx__tab:hover {
  background: rgba(24, 32, 40, 0.92);
  color: rgba(255, 255, 255, 0.9);
  border-color: rgba(255, 255, 255, 0.14);
}
.moo-xlsx__tab--active {
  background: linear-gradient(180deg, rgba(0, 229, 160, 0.22), rgba(0, 184, 126, 0.18));
  color: var(--color-toast-info);
  border-color: rgba(0, 229, 160, 0.5);
  box-shadow: 0 0 0 1px rgba(0, 229, 160, 0.18), 0 6px 20px -8px rgba(0, 229, 160, 0.5);
}
.moo-xlsx__tab--active:hover {
  background: linear-gradient(180deg, rgba(0, 229, 160, 0.28), rgba(0, 184, 126, 0.24));
  color: #ffffff;
}

/* ==============================================================
   PPTX PREVIEW — "proof sheet" aesthetic
   ==============================================================
   Vertical stack of 16:9 slide cards. Each slide is a piece of
   printed paper with generous padding, a mint slide-number badge
   in the top-left corner, bold display title, body lines, and any
   embedded images at the bottom. Dashed hair-rules between slides
   evoke a photo-lab contact sheet. Deliberately NOT a carousel —
   scrolling through slides like reviewing a printed handout is
   faster and more legible than prev/next buttons.
*/
#moo_pptx_wrap {
  width: 100%;
  max-width: 960px;
  max-height: 100%;
  flex-direction: column;
  pointer-events: auto;
  border-radius: 14px;
  overflow: hidden;
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.5);
  /* Warm off-white paper background that the white slide cards sit on
     — gives the proof-sheet concept a second layer of paper depth. */
  background: #f7f6f2;
  border: 1px solid rgba(0, 0, 0, 0.08);
}
#moo_pptx_content {
  overflow-y: auto;
  overscroll-behavior: none;
  max-height: 100%;
  padding: 32px 28px 48px 28px;
  flex: 1 1 auto;
  min-height: 0;
}
.moo-pptx__slide {
  position: relative;
  background: #ffffff;
  border-radius: 6px;
  padding: 48px 56px 40px 56px;
  margin-bottom: 36px;
  /* Layered shadow: a crisp hairline + a soft cast — makes each slide
     feel like it's lifted slightly off the proof sheet, not flat. */
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, 0.06),
    0 1px 3px rgba(0, 0, 0, 0.04),
    0 20px 40px -24px rgba(0, 0, 0, 0.18);
  /* 16:9 minimum height feels like a real slide even when the slide
     content is sparse; tall content pushes it past the minimum. */
  min-height: 0;
}
.moo-pptx__slide::before {
  /* The mint "staple" — a thin vertical accent mark running down the
     left edge that ties the slide back to the app's accent colour
     without fighting the white-paper readability. */
  content: '';
  position: absolute;
  left: 0;
  top: 48px;
  bottom: 40px;
  width: 3px;
  background: linear-gradient(180deg, #00e5a0 0%, #00b87e 100%);
  border-radius: 0 2px 2px 0;
  box-shadow: 0 0 12px rgba(0, 229, 160, 0.3);
}
.moo-pptx__slide:last-child {
  margin-bottom: 0;
}
/* Dashed hair-rule separators between slides — "contact sheet" cue.
   Drawn as a pseudo element so it sits on the paper, not the card. */
.moo-pptx__slide:not(:last-child)::after {
  content: '';
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  bottom: -23px;
  width: 40%;
  height: 1px;
  background-image: repeating-linear-gradient(90deg, rgba(0,0,0,0.22) 0 6px, transparent 6px 12px);
}
.moo-pptx__num {
  position: absolute;
  top: 20px;
  right: 24px;
  font-family: 'Montserrat', sans-serif;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.18em;
  color: rgba(0, 184, 126, 0.85);
  text-transform: uppercase;
  /* Ties the number into the mint staple without being a badge — feels
     like a stamp from a copy shop rather than a UI chip. */
}
.moo-pptx__num::before {
  content: 'SLIDE ';
  color: rgba(0, 0, 0, 0.35);
  font-weight: 600;
}
.moo-pptx__body {
  font-family: 'Montserrat', sans-serif;
  color: #1a1a1a;
}
.moo-pptx__title {
  font-size: 26px;
  font-weight: 800;
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: #0d0d0d;
  margin-bottom: 16px;
  /* Subtle mint underline on the title — echoes the staple accent. */
  padding-bottom: 10px;
  border-bottom: 2px solid rgba(0, 229, 160, 0.25);
}
.moo-pptx__line {
  font-size: 14px;
  line-height: 1.6;
  color: #2d2d2d;
  margin-bottom: 8px;
  position: relative;
  padding-left: 18px;
}
.moo-pptx__line::before {
  /* Bullet as a mint diamond — small, refined, contextual. */
  content: '';
  position: absolute;
  left: 2px;
  top: 9px;
  width: 6px;
  height: 6px;
  background: #00b87e;
  transform: rotate(45deg);
  border-radius: 1px;
}
.moo-pptx__images {
  margin-top: 20px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 14px;
  padding-top: 18px;
  border-top: 1px dashed rgba(0, 0, 0, 0.12);
}
.moo-pptx__images img {
  width: 100%;
  height: auto;
  max-height: 280px;
  object-fit: contain;
  background: #f4f4f4;
  border-radius: 4px;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.06);
}

/* Tight layout for narrow viewports — reduce paper padding, shrink
   title slightly, keep everything legible at phone widths. */
@media (max-width: 600px) {
  .moo-xlsx__sheet { padding: 14px 16px 18px 16px; }
  .moo-xlsx__sheet table td,
  .moo-xlsx__sheet table th { padding: 6px 9px; font-size: 11.5px; }
  #moo_pptx_content { padding: 20px 14px 32px 14px; }
  .moo-pptx__slide { padding: 32px 24px 28px 32px; margin-bottom: 28px; }
  .moo-pptx__title { font-size: 20px; }
  .moo-pptx__num { top: 14px; right: 16px; }
  .moo-pptx__slide::before { top: 32px; bottom: 28px; }
}

#moo_fv_unsupported {
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  text-align: center;
  pointer-events: auto;
  padding: 36px 32px;
  max-width: 420px;
  width: calc(100% - 40px);
  background: rgba(20, 30, 38, 0.95);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 20px;
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.5);
}
#moo_fv_unsupported .moo-fv__icon {
  width: 64px;
  height: 64px;
  border-radius: 16px;
  background: rgba(16, 24, 30, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.08);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 28px;
  color: rgba(255, 255, 255, 0.45);
  margin-bottom: 4px;
}
#moo_fv_unsupported .moo-fv__name {
  font-size: 14px;
  font-weight: 600;
  color: var(--color-text-primary);
  word-break: break-all;
  line-height: 1.4;
}
#moo_fv_unsupported .moo-fv__reason {
  font-size: 13px;
  color: rgba(255, 255, 255, 0.5);
  line-height: 1.45;
}
#moo_fv_unsupported .moo-fv__hint {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.35);
  margin-top: 4px;
}

#moo_img_actions {
  display: flex;
  gap: 10px;
  margin-top: 20px;
  flex-shrink: 0;
}
.moo_img_action_btn {
  background: rgba(18, 26, 32, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 14px;
  color: var(--color-text-primary);
  padding: 14px 22px;
  font-size: 14px;
  font-weight: 600;
  font-family: 'Montserrat', sans-serif;
  cursor: pointer;
  transition: opacity 0.2s, background-color 0.2s, color 0.2s, border-color 0.2s;
  display: flex;
  align-items: center;
  gap: 8px;
  white-space: nowrap;
}
.moo_img_action_btn:hover {
  background: rgba(0, 229, 160, 0.1);
  border-color: rgba(0, 229, 160, 0.25);
  color: var(--color-accent);
}
@media (max-width: 480px) {
  #moo_img_actions {
    flex-direction: column;
    width: 100%;
  }
  .moo_img_action_btn {
    width: 100%;
    justify-content: center;
    box-sizing: border-box;
  }
}

/* ===== CHAT PAGE OVERHAUL ===== */

/* Page background */
html:has(.moo-chat) {
  background: var(--color-bg);
}
body:has(.moo-chat) {
  background: var(--color-bg);
}

/* Header — dark glass */
body:has(.moo-chat) .chat_top_info {
  background: rgba(6, 13, 16, 0.97);
}
body:has(.moo-chat) .chat_back_button {
  background: rgba(24, 32, 40, 0.92);
  color: var(--color-text-primary);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 10px;
}
body:has(.moo-chat) .chat_other_name {
  color: var(--color-text-primary);
}
body:has(.moo-chat) #chat_online_status {
  color: rgba(255, 255, 255, 0.4);
}
body:has(.moo-chat) .my_top_display {
  color: rgba(255, 255, 255, 0.4);
}
body:has(.moo-chat) .cti_right {
  background: rgba(24, 32, 40, 0.92);
  color: var(--color-text-primary);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 10px;
}

/* Chatbox — dark with subtle texture */
.moo-chat {
  background-color: var(--color-bg-chat) !important;
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cdefs%3E%3Cstyle%3E.i%7Bfill:rgba(255,255,255,0.025);%7D%3C/style%3E%3C/defs%3E%3Ccircle class='i' cx='20' cy='20' r='3'/%3E%3Ccircle class='i' cx='120' cy='90' r='2.5'/%3E%3Ccircle class='i' cx='60' cy='160' r='2'/%3E%3Ccircle class='i' cx='170' cy='40' r='2'/%3E%3Ccircle class='i' cx='140' cy='170' r='3'/%3E%3Cpath class='i' d='M90 15c0-3.3 2.7-6 6-6h8c3.3 0 6 2.7 6 6v6c0 3.3-2.7 6-6 6h-5l-4 4v-4h-1c-2.2 0-4-1.8-4-4v-8z'/%3E%3Cpath class='i' d='M30 100c0-3.3 2.7-6 6-6h8c3.3 0 6 2.7 6 6v6c0 3.3-2.7 6-6 6h-5l-4 4v-4h-1c-2.2 0-4-1.8-4-4v-8z'/%3E%3Cpath class='i' d='M155 120c0-3.3 2.7-6 6-6h8c3.3 0 6 2.7 6 6v6c0 3.3-2.7 6-6 6h-5l-4 4v-4h-1c-2.2 0-4-1.8-4-4v-8z'/%3E%3Cpath class='i' d='M75 70l3-5.2 3 5.2-3 1.8z'/%3E%3Cpath class='i' d='M180 140l3-5.2 3 5.2-3 1.8z'/%3E%3Crect class='i' x='100' y='130' width='10' height='8' rx='2'/%3E%3Crect class='i' x='10' y='60' width='8' height='6' rx='1.5'/%3E%3Cpath class='i' d='M50 45a4 4 0 11-8 0 4 4 0 018 0zm-4-2v3m0 1v.5'/%3E%3Cpath class='i' d='M130 55a4 4 0 11-8 0 4 4 0 018 0zm-4-2v3m0 1v.5'/%3E%3Cpath class='i' d='M80 185a3 3 0 100-6 3 3 0 000 6zm-1.5-3h3m-1.5-1.5v3'/%3E%3Cpath class='i' d='M185 85a3 3 0 100-6 3 3 0 000 6zm-1.5-3h3m-1.5-1.5v3'/%3E%3C/svg%3E") !important;
  background-repeat: repeat !important;
  background-size: 200px 200px !important;
}

/* Loading screen */
body:has(.moo-chat) .chatbox_loading {
  position: absolute !important;
  inset: 64px 0 0 0 !important;
  background:
    radial-gradient(ellipse at 60% 20%, rgba(14, 165, 233, 0.12) 0%, transparent 50%),
    radial-gradient(ellipse at 40% 80%, rgba(99, 102, 241, 0.1) 0%, transparent 50%),
    var(--color-bg);
  color: var(--color-text-primary);
}
body:has(.moo-chat) .cli_spin {
  color: var(--color-accent);
  font-size: 36px;
}
body:has(.moo-chat) .cli_text {
  color: rgba(255, 255, 255, 0.5);
  font-size: 16px;
  font-weight: 600;
  margin-top: 16px;
}

/* Loading more chat banner */
body:has(.moo-chat) .loading_more_chat {
  background: rgba(6, 13, 16, 0.85);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 14px;
  color: var(--color-text-primary);
  font-size: 15px;
}
body:has(.moo-chat) .loading_more_chat i {
  color: var(--color-accent);
}

/* Encryption banner */
.moo-chat .messages_encrypted {
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 12px;
  color: rgba(255, 255, 255, 0.4);
  font-size: 13px;
  padding: 10px 16px;
  cursor: pointer;
  transition: background 0.2s;
}
.moo-chat .messages_encrypted:active {
  background: rgba(24, 32, 40, 0.92);
}
.moo-chat .messages_encrypted i {
  margin-right: 6px;
  color: var(--color-accent);
}
.moo-chat .messages_encrypted b {
  color: var(--color-accent);
}

/* Scroll-to-message loading toast */
#scroll_to_toast {
  position: fixed;
  bottom: 100px;
  left: 50%;
  transform: translateX(-50%);
  display: none;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 12px 24px;
  white-space: nowrap;
  background: rgba(6, 13, 16, 0.9);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 14px;
  color: var(--color-text-primary);
  font-size: 14px;
  font-weight: 600;
  z-index: 100;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
}
#scroll_to_toast i {
  color: var(--color-accent);
}

/* Date and system lines */
.moo-chat .date_line,
.moo-chat .system_line {
  background: rgba(18, 26, 32, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 10px;
  color: rgba(255, 255, 255, 0.45);
  font-size: 12px;
  font-weight: 600;
  padding: 8px 16px;
  width: fit-content;
}

/* Message bubbles */
.moo-chat .indv_message.message_right {
  background: rgba(0, 229, 160, 0.12);
  border: 1px solid rgba(0, 229, 160, 0.1);
}
.moo-chat .indv_message.message_left {
  background: rgba(18, 26, 32, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.06);
}
.moo-chat .indv_message_info.message_right {
  background: var(--color-msg-time-right);
  border: none;
  padding: 2px 4px;
  border-radius: 4px;
}
.moo-chat .indv_message_info.message_left {
  background: var(--color-msg-time-left);
  border: none;
  padding: 2px 4px;
  border-radius: 4px;
}
.moo-chat .indv_message {
  border-radius: 14px;
  color: var(--color-text-primary);
  font-size: 14px;
  padding-right: 52px;
  display: inline-flex;
}
/* Same-sender run: tighten this bubble's gap to the next one (base is a 20px
   margin-bottom) so a burst reads as one calm block. margin-bottom (not a
   negative margin-top) because the bubbles are floated + clear:both, where a
   negative top margin is swallowed by clearance. The repeated name is dropped
   server-side. */
.moo-chat .indv_message--run {
  margin-bottom: 3px;
}
/* In-flow typing bubble: an incoming-style glass pill with three bouncing dots,
   appended at the bottom of #chatbox while the peer is typing. Matches
   .indv_message.message_left (bg/border/radius); floated + clear:both like the
   real bubbles, no time-badge gutter. */
.moo-chat .moo-typing-bubble {
  float: left;
  clear: both;
  margin: 0 0 20px 0;
  padding: 14px 16px;
  border-radius: 14px;
  background: rgba(18, 26, 32, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.06);
  max-width: 80%;
}
.moo-typing-dots {
  display: flex;
  align-items: center;
  gap: 5px;
}
.moo-typing-dots span {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--color-text-primary);
  opacity: 0.45;
  animation: mooTypingDot 1.3s infinite ease-in-out;
}
.moo-typing-dots span:nth-child(2) { animation-delay: 0.18s; }
.moo-typing-dots span:nth-child(3) { animation-delay: 0.36s; }
@keyframes mooTypingDot {
  0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }
  30% { transform: translateY(-4px); opacity: 0.85; }
}
@media (prefers-reduced-motion: reduce) {
  .moo-typing-dots span { animation: none; opacity: 0.6; }
}
/* Swipe-to-reply: during the drag the bubble follows the finger (no transition);
   overflow goes visible so the reply arrow shows in the revealed space, and text
   selection is suppressed. On release .swipe-return adds the spring-back. */
.moo-chat .indv_message.swiping {
  overflow: visible;
  user-select: none;
  -webkit-user-select: none;
}
.moo-chat .indv_message.swipe-return {
  transition: transform 0.22s cubic-bezier(0.22, 0.61, 0.36, 1);
}
.moo-swipe-arrow {
  position: absolute;
  left: -34px;
  top: 50%;
  transform: translateY(-50%) scale(0.7);
  color: var(--color-accent);
  font-size: 15px;
  opacity: 0;
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  .moo-chat .indv_message.swipe-return { transition: transform 0.01s linear; }
}
/* Long-press feedback: a quiet dip while held (added after ~140ms so taps and
   scroll-starts never flash it), released on menu-open/cancel. */
.moo-chat .indv_message.pressing {
  transform: scale(0.97);
  filter: brightness(0.92);
  transition: transform 0.12s ease-out, filter 0.12s ease-out;
}
/* Touch devices: long-press opens the options menu, so suppress the native iOS
   callout + text selection (Copy lives in the menu). Desktop keeps selection. */
@media (pointer: coarse) {
  .moo-chat .indv_message {
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    user-select: none;
  }
}
@media (prefers-reduced-motion: reduce) {
  .moo-chat .indv_message.pressing { transform: none; transition: filter 0.1s ease; }
}
.moo-chat .indv_message_info_cont {
  width: 26px;
  right: 10px;
  top: 10px;
  height: calc(100% - 20px);
}
.moo-chat .indv_message_info {
  color: rgba(255, 255, 255, 0.3);
  white-space: nowrap;
  width: auto;
}
/* A freshly-sent (optimistic) bubble rises a few px as it appears — one quiet
   motion, no bounce. The class is removed once adopted so it never replays on
   reflow. */
@keyframes mooMsgRise {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}
.moo-chat .indv_message--optimistic-enter,
.moo-chat .indv_message--enter { animation: mooMsgRise 0.18s ease-out; }
/* M6: failed send — the bubble stays, tappable to retry. A danger exclamation by
   the time + a faint danger ring; retrying dims it. Restrained, no heavy tint. */
.moo-chat .indv_message--failed {
  cursor: pointer;
  box-shadow: inset 0 0 0 1px rgba(244, 63, 94, 0.3);
}
.moo-chat .indv_message--failed .indv_message_info::before {
  content: '\f06a';
  font-family: 'Font Awesome 6 Free';
  font-weight: 900;
  color: var(--color-danger);
  margin-right: 5px;
  font-size: 11px;
}
.moo-chat .indv_message--retrying {
  opacity: 0.55;
  transition: opacity 0.2s ease;
}
/* The mirror of the entrance: a deleted bubble fades + settles, then its real
   (JS-measured) height collapses so the thread slides up smoothly at any size,
   before it's detached. The JS sets max-height to the measured height then to 0
   so the collapse is linear (a fixed CSS ceiling would clip tall messages and
   back-load the collapse). Reversible — the JS clears the inline styles + class
   on a failed delete. Specific properties only, never transition: all. */
.moo-chat .indv_message--leaving {
  overflow: hidden;
  pointer-events: none;
  transition: opacity 0.15s ease-in,
              transform 0.15s ease-in,
              max-height 0.24s ease-in,
              margin-top 0.24s ease-in,
              margin-bottom 0.24s ease-in,
              padding-top 0.24s ease-in,
              padding-bottom 0.24s ease-in;
}
@media (prefers-reduced-motion: reduce) {
  @keyframes mooMsgRise { from, to { opacity: 1; transform: none; } }
  /* Still collapse the space (so there's no ghost gap), just fast and without
     the transform/settle. */
  .moo-chat .indv_message--leaving {
    transition: opacity 0.1s ease, max-height 0.1s ease,
                margin-top 0.1s ease, margin-bottom 0.1s ease,
                padding-top 0.1s ease, padding-bottom 0.1s ease;
  }
}
.moo-chat .indv_message_moreinfo {
  color: rgba(255, 255, 255, 0.25);
}
.moo-chat .indv_message pre a {
  color: var(--color-accent);
}
.moo-chat .indv_message_name {
  color: var(--color-accent);
  font-size: 13px;
}
/* Grouped (same sender as the bubble above, within the run window): the name node
   is still emitted so the client re-stitch can toggle it both ways, but hidden. */
.moo-chat .indv_message_name--grouped {
  display: none;
}

/* GIF images in messages */
.moo-chat .GIF_IMG {
  border-radius: 10px;
}

/* New messages scroll button */
body:has(.moo-chat) #new_messages_button {
  background: rgba(0, 229, 160, 0.15);
  border: 1px solid rgba(0, 229, 160, 0.2);
  color: var(--color-accent);
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
}
body:has(.moo-chat) #new_messages_button i {
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
}
/* Unread count above the jump-to-bottom pill. Dark glass with mint text +
   hairline mint border — mint stays the light source, not a painted fill. */
body:has(.moo-chat) #new_messages_button .moo-new-msg-count {
  position: absolute;
  top: -9px;
  left: 50%;
  transform: translateX(-50%);
  min-width: 20px;
  height: 18px;
  padding: 0 6px;
  box-sizing: border-box;
  border-radius: 9px;
  background: rgba(6, 13, 16, 0.95);
  border: 1px solid rgba(0, 229, 160, 0.35);
  color: var(--color-accent);
  font-size: 11px;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
  white-space: nowrap;
  pointer-events: none;
}

/* ---- Message input bar ---- */
.moo-chat-bar {
  background: rgba(6, 13, 16, 0.9) !important;
  padding: 20px !important;
  width: calc(100% - 40px) !important;
  min-height: 30px !important;
  display: flex !important;
  flex-direction: column !important;
  align-items: stretch !important;
}
.moo-chat-bar #user_message {
  background: rgba(18, 26, 32, 0.92) !important;
  border: 1px solid rgba(255, 255, 255, 0.1) !important;
  border-radius: 14px !important;
  color: var(--color-text-primary) !important;
  padding: 7px 14px !important;
  font-size: 15px;
  font-family: 'Montserrat', sans-serif;
  margin-left: 0 !important;
  flex: 1 1 0 !important;
  width: auto !important;
  min-width: 0 !important;
  min-height: 20px;
  height: 20px;
  line-height: 20px;
  user-select: text;
  -webkit-user-select: text;
  touch-action: manipulation;
}
.moo-chat-bar button {
  position: relative !important;
  bottom: auto !important;
  left: auto !important;
  right: auto !important;
  background: rgba(24, 32, 40, 0.92) !important;
  border: 1px solid rgba(255, 255, 255, 0.1) !important;
  border-radius: 10px !important;
  color: var(--color-text-primary) !important;
  width: 34px !important;
  height: 34px !important;
  min-width: 34px;
  flex-shrink: 0;
  transition: opacity 0.2s, background-color 0.2s, color 0.2s, border-color 0.2s;
}
.moo-chat-bar #send_message {
  background: linear-gradient(135deg, var(--color-accent), var(--color-accent-dark)) !important;
  border: none !important;
  color: var(--color-bg) !important;
  font-size: 16px !important;
}
.moo-chat-bar .message_process {
  background: rgba(6, 13, 16, 0.95) !important;
  color: rgba(255, 255, 255, 0.6) !important;
  font-size: 15px;
}

/* ---- Message options popup ---- */
body:has(.moo-chat) #mop_wrap {
  background: rgba(6, 13, 16, 0.6);
  animation: mooOverlayIn 0.2s ease-out;
}
body:has(.moo-chat) #message_options_popup {
  background: rgba(20, 30, 38, 0.85);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 20px;
  padding: 28px;
  width: min(320px, 80%);
  height: auto !important;
  color: var(--color-text-primary);
  animation: mooModalIn 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
body:has(.moo-chat) .mop_title {
  font-size: 18px;
  font-weight: 800;
  letter-spacing: -0.3px;
  margin-bottom: 16px;
}
body:has(.moo-chat) #mop_message {
  position: absolute;
  left: -9999px;
  opacity: 0;
  height: 1px;
  width: 1px;
  padding: 0;
  margin: 0;
  border: 0;
}
body:has(.moo-chat) .mop_buttons_cont {
  display: flex;
  gap: 10px;
  width: 100%;
  box-sizing: border-box;
}
body:has(.moo-chat) .mop_button {
  flex: 1;
  background: rgba(18, 26, 32, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 14px;
  color: var(--color-text-primary);
  padding: 14px;
  font-size: 14px;
  font-weight: 600;
  font-family: 'Montserrat', sans-serif;
  width: auto;
  cursor: pointer;
  transition: opacity 0.2s, background-color 0.2s, color 0.2s, border-color 0.2s;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
/* hover: hover only — on touch, the synthetic hover from a long-press opening
   the options menu under the finger sticks and looks like the button is armed. */
@media (hover: hover) {
  body:has(.moo-chat) .mop_button:hover {
    background: rgba(0, 229, 160, 0.08);
    border-color: rgba(0, 229, 160, 0.2);
    color: var(--color-accent);
  }
}
body:has(.moo-chat) .mop_button_delete {
  background: rgba(244, 63, 94, 0.08);
  border-color: rgba(244, 63, 94, 0.15);
  color: var(--color-danger);
}
@media (hover: hover) {
  body:has(.moo-chat) .mop_button_delete:hover {
    background: rgba(244, 63, 94, 0.15);
    border-color: rgba(244, 63, 94, 0.25);
    color: var(--color-danger);
  }
}
body:has(.moo-chat) #delete_message {
  margin-left: 0;
}

/* ---- Attachments popup ---- */
body:has(.moo-chat) #attachments_wrap {
  background: rgba(6, 13, 16, 0.6);
  animation: mooOverlayIn 0.2s ease-out;
}
body:has(.moo-chat) #attachments_popup {
  background: rgba(20, 30, 38, 0.85);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 24px;
  padding: 32px;
  width: min(320px, 80%);
  color: var(--color-text-primary);
  animation: mooModalIn 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
/* F10: tap-to-close fade for the attachments sheet (the JS drops display:none
   after the 180ms timeout). Named prop, reduced-motion safe. */
#attachments_wrap.moo-sheet-closing,
#attachments_popup.moo-sheet-closing {
  opacity: 0;
  transition: opacity 0.18s ease;
}
@media (prefers-reduced-motion: reduce) {
  #attachments_wrap.moo-sheet-closing,
  #attachments_popup.moo-sheet-closing { transition: none; }
}
/* Attachment option buttons — reset button defaults for .moo-modal__option */
body:has(.moo-chat) #attachments_popup .moo-modal__option {
  cursor: pointer;
  font-family: 'Montserrat', sans-serif;
  text-align: left;
  width: 100%;
  box-sizing: border-box;
}

/* ---- KLIPY/GIF popup ---- */
body:has(.moo-chat) #klipy_wrap {
  background: rgba(6, 13, 16, 0.6);
  animation: mooOverlayIn 0.2s ease-out;
}
body:has(.moo-chat) #klipy_popup {
  background: rgba(20, 30, 38, 0.9);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 24px;
  color: var(--color-text-primary);
}
body:has(.moo-chat) .klipy_title {
  color: var(--color-text-primary);
}
body:has(.moo-chat) .klipy_title_sub {
  color: rgba(255, 255, 255, 0.35);
}
body:has(.moo-chat) #klipy_search {
  background: rgba(18, 26, 32, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  color: var(--color-text-primary);
  padding-left: 36px;
}
body:has(.moo-chat) .klipy_search_icon {
  color: rgba(255, 255, 255, 0.3);
}
body:has(.moo-chat) .klipy_indv img {
  border-radius: 10px;
}
body:has(.moo-chat) .gifs_loading {
  background: rgba(20, 30, 38, 0.9);
  color: var(--color-text-primary);
  font-size: 16px;
}
body:has(.moo-chat) .gifs_loading .cli_spin {
  color: var(--color-accent);
  font-size: 28px;
}
body:has(.moo-chat) .gifs_loading .cli_text {
  color: rgba(255, 255, 255, 0.5);
  font-size: 14px;
}

/* ---- Encryption info popup ---- */
body:has(.moo-chat) #ms_popup_wrap {
  background: rgba(6, 13, 16, 0.6);
  animation: mooOverlayIn 0.2s ease-out;
}
body:has(.moo-chat) #ms_popup {
  background: rgba(20, 30, 38, 0.85);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 24px;
  padding: 32px;
  width: min(360px, 80%);
  color: var(--color-text-primary);
  animation: mooModalIn 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
body:has(.moo-chat) .ms_popup_title {
  font-size: 18px;
  font-weight: 800;
  color: var(--color-text-primary);
  letter-spacing: -0.3px;
}
body:has(.moo-chat) .ms_popup_message {
  color: rgba(255, 255, 255, 0.5);
  font-size: 14px;
  line-height: 1.7;
}
body:has(.moo-chat) .ms_popup_message b {
  color: rgba(255, 255, 255, 0.7);
}

/* Reply reference card (inside message bubbles) */
.reply_reference {
  background: rgba(18, 26, 32, 0.92);
  border-left: 3px solid var(--color-accent);
  border-radius: 0 8px 8px 0;
  padding: 8px 12px;
  margin-bottom: 8px;
  cursor: pointer;
  transition: background 0.2s;
  max-width: 100%;
  overflow: hidden;
}
.reply_reference:active {
  background: rgba(28, 36, 44, 0.92);
}
.reply_ref_name {
  font-size: 12px;
  font-weight: 700;
  color: var(--color-accent);
  margin-bottom: 2px;
}
.reply_ref_text {
  font-size: 13px;
  color: rgba(255, 255, 255, 0.5);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Forwarded label */
.forwarded_label {
  font-size: 11px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.35);
  margin-bottom: 4px;
  font-style: italic;
}
.forwarded_label i {
  margin-right: 4px;
}

/* Message highlight animation (scroll to reply target) */
.message_highlight {
  animation: mooMsgHighlight 2s ease-out;
}
@keyframes mooMsgHighlight {
  0%, 20% { outline: 2px solid var(--color-accent); outline-offset: 2px; }
  100% { outline: 2px solid transparent; outline-offset: 2px; }
}

/* Reply preview bar (above message input) */
#reply_preview {
  display: none;
  align-items: center;
  gap: 10px;
  padding: 10px 16px;
  background: rgba(14, 22, 28, 0.92);
  border-left: 3px solid var(--color-accent);
  border-radius: 0 10px 10px 0;
  margin-bottom: 10px;
  width: calc(100% - 19px);
}
#reply_preview_inner {
  flex: 1;
  min-width: 0;
}
#reply_preview_name {
  font-size: 12px;
  font-weight: 700;
  color: var(--color-accent);
}
#reply_preview_text {
  font-size: 13px;
  color: rgba(255, 255, 255, 0.45);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
#reply_cancel {
  background: rgba(18, 26, 32, 0.92) !important;
  border: 1px solid rgba(255, 255, 255, 0.1) !important;
  border-radius: 8px !important;
  color: rgba(255, 255, 255, 0.5) !important;
  width: 28px !important;
  height: 28px !important;
  min-width: 28px;
  font-size: 12px !important;
  cursor: pointer;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  flex-shrink: 0;
  position: relative !important;
  bottom: auto !important;
  left: auto !important;
  right: auto !important;
}

/* Input row wrapper */
#moo_chat_input_row {
  display: flex;
  align-items: flex-end;
  gap: 10px;
  width: 100%;
}

/* Message options - accent button (reply) */
body:has(.moo-chat) .mop_button_accent {
  background: rgba(0, 229, 160, 0.08);
  border-color: rgba(0, 229, 160, 0.15);
  color: var(--color-accent);
}
@media (hover: hover) {
  body:has(.moo-chat) .mop_button_accent:hover {
    background: rgba(0, 229, 160, 0.15);
    border-color: rgba(0, 229, 160, 0.25);
  }
}

/* Message options button grid */
body:has(.moo-chat) .mop_buttons_grid {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  width: 100%;
}
body:has(.moo-chat) .mop_buttons_grid .mop_button {
  flex: 1 1 calc(50% - 4px);
  min-width: calc(50% - 4px);
  box-sizing: border-box;
}
body:has(.moo-chat) .mop_buttons_grid .mop_button:last-child:nth-child(odd) {
  flex: 1 1 100%;
  min-width: 100%;
}

/* Forward picker modal */
body:has(.moo-chat) #forward_wrap {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(6, 13, 16, 0.6);
  display: none;
  z-index: 999;
  animation: mooOverlayIn 0.2s ease-out;
}
body:has(.moo-chat) #forward_popup {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: rgba(20, 30, 38, 0.9);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 24px;
  padding: 28px;
  width: min(360px, 85%);
  max-height: 70%;
  color: var(--color-text-primary);
  display: none;
  flex-direction: column;
  z-index: 9999;
  animation: mooModalIn 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
#forward_list {
  overflow-y: auto;
  overscroll-behavior: none;
  flex: 1;
  min-height: 0;
  margin-bottom: 16px;
}
.forward_section_title {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: rgba(255, 255, 255, 0.35);
  margin-bottom: 8px;
  margin-top: 16px;
}
.forward_section_title:first-child {
  margin-top: 0;
}
.forward_item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  border-radius: 12px;
  cursor: pointer;
  transition: background 0.15s;
  margin-bottom: 4px;
}
.forward_item:hover {
  background: rgba(14, 22, 28, 0.92);
}
.forward_item:active {
  background: rgba(24, 32, 40, 0.92);
}
.forward_item img {
  width: 38px;
  height: 38px;
  border-radius: 10px;
  object-fit: cover;
  flex-shrink: 0;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.06);
}
.forward_item span {
  flex: 1;
  font-size: 15px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.forward_check {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.15);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: opacity 0.15s, background-color 0.15s, color 0.15s, border-color 0.15s;
  font-size: 11px;
  color: transparent;
}
.forward_selected .forward_check {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-bg);
}
.forward_selected {
  background: rgba(0, 229, 160, 0.06);
}
#forward_send {
  width: 100%;
  padding: 14px;
  background: linear-gradient(135deg, var(--color-accent), var(--color-accent-dark));
  border: none;
  border-radius: 14px;
  color: var(--color-bg);
  font-weight: 700;
  font-size: 15px;
  font-family: 'Montserrat', sans-serif;
  cursor: pointer;
  transition: opacity 0.2s, transform 0.2s, box-shadow 0.2s;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  flex-shrink: 0;
}
#forward_send:hover {
  transform: translateY(-1px);
  box-shadow: 0 6px 24px rgba(0, 229, 160, 0.25);
}

/* ===== ATTACHMENTS ===== */

/* ---- Location Card ---- */
.moo-location-card {
  display: block;
  width: 260px;
  max-width: 100%;
  border-radius: 12px;
  overflow: hidden;
  color: var(--color-text-primary);
  background: rgba(0, 0, 0, 0.2);
  border: 1px solid rgba(255, 255, 255, 0.06);
}
/* CSS-only abstract "map" — renders with NO external requests (no map tiles, no
   third-party imagery). A faint street grid + roads over a dark aurora wash,
   with the pin floating at centre. Coordinates stay private until the user
   explicitly taps "Open". */
.moo-location-card__map {
  width: 100%;
  height: 112px;
  overflow: hidden;
  position: relative;
  background:
    radial-gradient(130% 100% at 50% 125%, rgba(0, 229, 160, 0.12), transparent 60%),
    rgba(14, 22, 28, 0.92);
}
.moo-location-card__grid {
  position: absolute;
  inset: -1px;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.05) 1px, transparent 1px);
  background-size: 26px 26px;
  background-position: center;
  -webkit-mask-image: radial-gradient(82% 82% at 50% 44%, #000 52%, transparent 100%);
  mask-image: radial-gradient(82% 82% at 50% 44%, #000 52%, transparent 100%);
}
.moo-location-card__map::after {
  content: '';
  position: absolute;
  inset: 0;
  background:
    linear-gradient(116deg, transparent 46.5%, rgba(255, 255, 255, 0.07) 47%, rgba(255, 255, 255, 0.07) 48.6%, transparent 49.1%),
    linear-gradient(31deg, transparent 61.5%, rgba(0, 229, 160, 0.10) 62%, transparent 63%);
  pointer-events: none;
}
.moo-location-card__pin {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -60%);
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  border-radius: 12px;
  background: rgba(0, 229, 160, 0.16);
  border: 1px solid rgba(0, 229, 160, 0.38);
  color: var(--color-accent);
  font-size: 15px;
  z-index: 1;
}
.moo-location-card__pin::after {
  content: '';
  position: absolute;
  bottom: -9px;
  left: 50%;
  transform: translateX(-50%);
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgba(0, 229, 160, 0.5);
}
.moo-location-card__info {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
}
.moo-location-card__meta {
  min-width: 0;
  flex: 1;
}
.moo-location-card__label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  font-weight: 600;
  color: var(--color-text-primary);
}
.moo-location-card__label i {
  color: var(--color-accent);
  font-size: 12px;
}
.moo-location-card__coords {
  margin-top: 2px;
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  color: rgba(255, 255, 255, 0.5);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.moo-location-card__open {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 10px;
  border-radius: 10px;
  font-size: 12px;
  font-weight: 600;
  color: var(--color-accent);
  background: rgba(0, 229, 160, 0.10);
  border: 1px solid rgba(0, 229, 160, 0.22);
  text-decoration: none;
  transition: background-color 0.15s ease, border-color 0.15s ease;
}
.moo-location-card__open:active {
  background: rgba(0, 229, 160, 0.18);
}

/* ---- Media Grid ---- */
.moo-media-grid {
  display: grid;
  gap: 3px;
  border-radius: 10px;
  overflow: hidden;
  max-width: 280px;
}
.moo-media-grid--single {
  grid-template-columns: auto;
}
.moo-media-grid--two {
  grid-template-columns: 1fr 1fr;
}
.moo-media-grid--three {
  grid-template-columns: 1fr 1fr;
  grid-template-rows: auto auto;
}
.moo-media-grid--three .moo-media-grid__item:first-child {
  grid-column: 1 / -1;
}
.moo-media-grid--multi {
  grid-template-columns: 1fr 1fr;
  grid-template-rows: auto auto;
}
/* Album cap (> 4): square 2x2; tiles 5+ are hidden and a "+N" overlay sits on
   the 4th cell. The grid is the offset parent; the square tiles guarantee equal
   rows so the 50%/50% overlay lines up. Tapping +N removes --capped to reveal
   the rest in place. */
.moo-media-grid--capped {
  position: relative;
}
.moo-media-grid--capped .moo-media-grid__item {
  aspect-ratio: 1;
}
.moo-media-grid--capped .moo-media-grid__item:nth-child(n+5) {
  display: none;
}
.moo-media-grid__more {
  display: none;
}
.moo-media-grid--capped .moo-media-grid__more {
  display: flex;
  position: absolute;
  right: 0;
  bottom: 0;
  width: calc(50% - 1.5px);
  height: calc(50% - 1.5px);
  align-items: center;
  justify-content: center;
  background: rgba(6, 13, 16, 0.62);
  color: var(--color-text-primary);
  font-size: 24px;
  font-weight: 700;
  cursor: pointer;
  z-index: 3;
}
.moo-media-grid__item {
  position: relative;
  overflow: hidden;
  background: rgba(14, 22, 28, 0.90);
  min-height: 80px;
}
.moo-media-grid--single .moo-media-grid__item {
  min-height: 0;
  max-height: 320px;
}
.moo-media-grid__item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  min-height: 80px;
}
.moo-media-grid--single .moo-media-grid__item img {
  min-height: 0;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 320px;
  object-fit: contain;
}
/* ---- Reply preview inside media bubbles ----
   The media grid owns the bubble width: the reply chip contributes ZERO
   intrinsic width (width: 0) then stretches back to the grid's width
   (min-width: 100%). Without this a wide reply sets the bubble width and the
   narrower media sits left-aligned with its right corners un-rounded (the
   grid's radius clips at the grid box, which spanned the full bubble). */
.indv_message:has(.moo-media-grid) .reply_reference {
  width: 0;
  min-width: 100%;
  box-sizing: border-box;
}
.indv_message:has(.moo-media-grid) .reply_ref_name {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Group sender names get the same treatment — a long name above a narrow GIF
   would re-widen the bubble and un-round the media's right corners. */
.indv_message:has(.moo-media-grid) .indv_message_name {
  width: 0;
  min-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Floor for tiny media: don't let a small GIF/photo crush the reply chip into
   an unreadable sliver — widen the single tile instead. Its image fills the
   box (GIFs cover-crop; photos letterbox on the dark card at worst). */
.indv_message:has(.reply_reference) .moo-media-grid--single .moo-media-grid__item {
  min-width: 200px;
}
.indv_message:has(.reply_reference) .moo-media-grid--single .moo-media-grid__item img {
  width: 100%;
}
.moo-media-grid__video-ph {
  width: 100%;
  height: 100%;
  min-height: 80px;
  position: relative;
  overflow: hidden;
  background: linear-gradient(145deg, #0d2420 0%, #091a16 100%);
}
.moo-media-grid__video-ph i {
  display: none;
}
.moo-media-grid--single .moo-media-grid__video-ph {
  min-height: 120px;
  aspect-ratio: 16 / 9;
  max-height: 320px;
}
.moo-media-grid__play {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 50px;
  height: 50px;
  border-radius: 50%;
  background: rgba(0, 229, 160, 0.13);
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  z-index: 2;
}
.moo-media-grid__play i {
  color: var(--color-accent);
  font-size: 18px;
  margin-left: 3px;
}

/* ---- File Card ---- */
.moo-file-attachments {
  display: flex;
  flex-direction: column;
  gap: 6px;
  max-width: min(280px, 100%);
}
.moo-file-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 10px;
  text-decoration: none;
  color: var(--color-text-primary);
  transition: background 0.15s, border-color 0.15s;
  min-width: 0;
}
.moo-file-card:active {
  background: rgba(24, 32, 40, 0.92);
  border-color: rgba(255, 255, 255, 0.1);
}
.moo-file-card__icon {
  width: 38px;
  height: 38px;
  border-radius: 10px;
  background: linear-gradient(135deg, rgba(0, 229, 160, 0.15), rgba(0, 229, 160, 0.05));
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.moo-file-card__icon i {
  color: var(--color-accent);
  font-size: 16px;
}
.moo-file-card__info {
  flex: 1;
  min-width: 0;
}
.moo-file-card__name {
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.moo-file-card__size {
  font-size: 11px;
  color: rgba(255, 255, 255, 0.35);
  margin-top: 2px;
}
.moo-file-card__download {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: rgba(14, 22, 28, 0.92);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.moo-file-card__download i {
  color: rgba(255, 255, 255, 0.35);
  font-size: 13px;
}

/* ---- Upload Overlay ---- */
/* ---- Non-blocking upload pill (above the composer input row) ---- */
.moo-upload-pill {
  display: none;
  align-items: center;
  gap: 10px;
  padding: 9px 12px 11px;
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 12px;
  margin-bottom: 10px;
  position: relative;
  overflow: hidden;
  animation: mooUploadPillIn 0.2s ease-out;
}
@keyframes mooUploadPillIn {
  from { opacity: 0; }
  to { opacity: 1; }
}
.moo-upload-pill .moo-upload__status {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--color-text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.moo-upload-pill.is-error .moo-upload__status {
  color: var(--color-danger);
}
.moo-upload-pill__right {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}
.moo-upload-pill .moo-upload__percent {
  font-size: 13px;
  font-weight: 600;
  color: var(--color-accent);
  font-variant-numeric: tabular-nums;
}
.moo-upload-pill__retry {
  font-size: 12px;
  font-weight: 700;
  color: var(--color-accent);
  background: rgba(0, 229, 160, 0.1);
  border: 0;
  border-radius: 8px;
  padding: 5px 10px;
  cursor: pointer;
  transition: transform 0.1s ease;
}
.moo-upload-pill__cancel {
  width: 26px;
  height: 26px;
  border-radius: 8px;
  border: 0;
  background: rgba(255, 255, 255, 0.06);
  color: var(--color-text-primary);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: 13px;
  flex-shrink: 0;
  transition: transform 0.1s ease;
}
.moo-upload-pill__retry:active,
.moo-upload-pill__cancel:active {
  transform: scale(0.92);
}
/* The generic `.moo-chat-bar button` rule forces a 34px square (!important) on
   every button in the composer — it clips the Retry label and oversizes Cancel.
   Restore the pill buttons' own sizing/look (higher specificity beats it). */
.moo-chat-bar .moo-upload-pill__retry {
  width: auto !important;
  height: auto !important;
  min-width: 0 !important;
  padding: 5px 10px !important;
  background: rgba(0, 229, 160, 0.1) !important;
  border: 0 !important;
  border-radius: 8px !important;
  color: var(--color-accent) !important;
  transition: transform 0.12s ease !important; /* beat the generic .moo-chat-bar button transition so the :active press eases */
}
.moo-chat-bar .moo-upload-pill__cancel {
  width: 26px !important;
  height: 26px !important;
  min-width: 26px !important;
  background: rgba(255, 255, 255, 0.06) !important;
  border: 0 !important;
  border-radius: 8px !important;
  transition: transform 0.12s ease !important;
}
/* F16: wax-seal progress disc (replaces the bottom-edge fill). A 2px mint ring
   traces the rim as it fills; a dark recessed "wax" centre reads as a pressed
   seal. One subtle press + a mint check on completion. Mint stays light-on-rim. */
.moo-seal {
  position: relative;
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.moo-seal__svg { width: 24px; height: 24px; display: block; }
.moo-seal__track { fill: none; stroke: rgba(255, 255, 255, 0.07); stroke-width: 3; }
.moo-seal__ring {
  fill: none;
  stroke: var(--color-accent);
  stroke-width: 3;
  stroke-linecap: round;
  stroke-dasharray: 106.8;
  stroke-dashoffset: 106.8;
  transition: stroke-dashoffset 0.3s ease, stroke 0.3s ease;
}
.moo-upload-pill.is-error .moo-seal__ring { stroke: rgba(255, 255, 255, 0.18); }
.moo-seal__check {
  position: absolute;
  font-size: 9px;
  line-height: 1;
  color: var(--color-accent);
  opacity: 0;
  transition: opacity 0.2s ease;
}
.moo-upload-pill.is-done .moo-seal__check { opacity: 1; }
.moo-upload-pill.is-done .moo-seal { animation: mooSealPress 0.32s cubic-bezier(0.34, 1.56, 0.64, 1); }
@keyframes mooSealPress {
  0% { transform: scale(0.88); }
  55% { transform: scale(1.04); }
  100% { transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .moo-upload-pill { animation: none; }
  .moo-seal__ring { transition: none; }
  .moo-upload-pill.is-done .moo-seal { animation: none; }
  .moo-upload-pill__retry:active,
  .moo-upload-pill__cancel:active { transform: none; }
}

/* ---- Upload Preview Modal ---- */
#moo_upload_wrap {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(6, 13, 16, 0.6);
  display: none;
  z-index: 999;
  animation: mooOverlayIn 0.2s ease-out;
}
#moo_upload_preview {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: none;
  flex-direction: column;
  gap: 14px;
  padding: 28px;
  background: rgba(20, 30, 38, 0.9);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 24px;
  width: min(360px, 85%);
  max-height: 70%;
  z-index: 9999;
  color: var(--color-text-primary);
  animation: mooModalIn 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  overflow-y: auto;
  overscroll-behavior: none;
}
.moo-upload-preview__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.moo-upload-preview__count {
  font-size: 12px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.5);
}
.moo-upload-preview__close {
  background: rgba(18, 26, 32, 0.92) !important;
  border: 1px solid rgba(255, 255, 255, 0.1) !important;
  border-radius: 8px !important;
  color: rgba(255, 255, 255, 0.5) !important;
  width: 28px !important;
  height: 28px !important;
  min-width: 28px;
  font-size: 12px !important;
  cursor: pointer;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  flex-shrink: 0;
  position: relative !important;
  bottom: auto !important;
  left: auto !important;
  right: auto !important;
}
.moo-upload-preview__items {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  overflow-y: auto;
  overscroll-behavior: none;
  max-height: 40vh;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 4px;
  scrollbar-width: none;
}
.moo-upload-preview__items::-webkit-scrollbar {
  display: none;
}
.moo-upload-preview__thumb {
  width: 64px;
  height: 64px;
  border-radius: 10px;
  overflow: hidden;
  flex-shrink: 0;
  position: relative;
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.06);
}
.moo-upload-preview__thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.moo-upload-preview__thumb-remove {
  position: absolute;
  top: 3px;
  right: 3px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: rgba(6, 13, 16, 0.8);
  border: 1px solid rgba(255, 255, 255, 0.1);
  color: rgba(255, 255, 255, 0.6);
  font-size: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  line-height: 1;
  flex-shrink: 0;
}
.moo-upload-preview__file-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  background: rgba(14, 22, 28, 0.90);
  border: 1px solid rgba(255, 255, 255, 0.05);
  border-radius: 10px;
  width: 100%;
  box-sizing: border-box;
}
.moo-upload-preview__file-icon {
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: rgba(0, 229, 160, 0.08);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.moo-upload-preview__file-icon i {
  color: var(--color-accent);
  font-size: 15px;
}
.moo-upload-preview__file-details {
  flex: 1;
  min-width: 0;
  overflow: hidden;
}
.moo-upload-preview__file-remove {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: rgba(244, 63, 94, 0.06);
  border: 1px solid rgba(244, 63, 94, 0.1);
  color: rgba(244, 63, 94, 0.5);
  font-size: 13px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: opacity 0.15s, background-color 0.15s, color 0.15s, border-color 0.15s;
}
.moo-upload-preview__file-remove:active {
  background: rgba(244, 63, 94, 0.15);
  border-color: rgba(244, 63, 94, 0.3);
  color: var(--color-danger);
}
.moo-upload-preview__file-name {
  font-size: 12px;
  font-weight: 600;
  color: var(--color-text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
  min-width: 0;
}
.moo-upload-preview__file-size {
  font-size: 10px;
  color: rgba(255, 255, 255, 0.3);
}
.moo-upload-preview__send {
  background: linear-gradient(135deg, var(--color-accent), var(--color-accent-dark)) !important;
  border: none !important;
  border-radius: 12px !important;
  color: var(--color-bg) !important;
  font-weight: 700 !important;
  font-size: 14px !important;
  font-family: 'Montserrat', sans-serif !important;
  padding: 12px !important;
  cursor: pointer;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 8px;
  transition: transform 0.15s, box-shadow 0.15s;
  width: 100%;
  box-sizing: border-box;
  position: relative !important;
  bottom: auto !important;
  left: auto !important;
  right: auto !important;
}
.moo-upload-preview__send:active {
  transform: scale(0.98);
}

/* ---- Upload Encryption Toggle ---- */
.moo-upload-preview__encrypt {
  padding: 12px 0 0;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  margin-top: 4px;
}
.moo-upload-preview__encrypt-toggle {
  display: flex;
  align-items: center;
  gap: 10px;
}
.moo-upload-preview__encrypt-label {
  font-size: 12px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.5);
}
.moo-upload-preview__encrypt-label i {
  color: var(--color-accent);
  margin-right: 4px;
  font-size: 11px;
}
.moo-upload-preview__encrypt-note {
  font-size: 10px;
  color: rgba(255, 255, 255, 0.25);
  margin-top: 6px;
}
.moo-toggle--sm {
  width: 36px;
  height: 20px;
}
.moo-toggle--sm .moo-toggle__track::after {
  width: 14px;
  height: 14px;
  left: 3px;
  top: 3px;
}
.moo-toggle--sm input:checked + .moo-toggle__track::after {
  transform: translateX(16px);
}

/* ---- Encrypted Media ----
   Post-E2EE-default, every chat message's media is encrypted. Rather than
   badge every thumbnail with a padlock, we render the same visual as an
   unencrypted image/video and let main_js's auto-decrypt loop populate the
   <img src> with a blob URL of the decrypted bytes. .moo-media-enc-img is
   the empty <img> the auto-decrypt loop fills. The subtle background tint
   is a loading placeholder — visible until the blob URL is set, then the
   image itself covers it. */
.moo-media-grid__item--encrypted {
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.moo-media-enc-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  background: rgba(255, 255, 255, 0.03);
  min-height: 80px;
}
/* F13: a mint skeleton sweep while the encrypted image is still src-less (i.e.
   fetching + decrypting). The decrypt loop sets [src] the moment it has bytes,
   which drops this selector and reveals the image. Reduced-motion => flat tint. */
.moo-media-enc-img:not([src]) {
  background-image: linear-gradient(100deg, transparent 20%, rgba(0, 229, 160, 0.10) 50%, transparent 80%);
  background-size: 200% 100%;
  background-repeat: no-repeat;
  animation: mooEncSkeleton 1.5s ease-in-out infinite;
}
@keyframes mooEncSkeleton {
  0% { background-position: 180% 0; }
  100% { background-position: -80% 0; }
}
@media (prefers-reduced-motion: reduce) {
  .moo-media-enc-img:not([src]) { animation: none; background-image: none; }
}
/* When an LQIP blur is painted on the item (E2EE attachment-metadata), drop the
   skeleton sweep + the img's faint tint so the real preview shows through cleanly
   until the decrypted blob paints over it. */
.moo-media-grid__item--encrypted[data-lqip-set] .moo-media-enc-img:not([src]) {
  background: transparent;
  animation: none;
}
.moo-media-grid--single .moo-media-enc-img {
  min-height: 100px;
}
/* Reserve a default box for single encrypted images BEFORE decrypt so the row
   isn't 0-height and snapping to natural size on load. The auto-decrypt loop
   reads the real dimensions from the decrypted bytes and sets the exact px box
   on the item (E2EE → the server can't read pixels to render dims up front), so
   the only residual movement is a small default->exact adjustment, not 0->full.
   The image always fills the reserved box (contain), so a wrong default just
   letterboxes briefly rather than overflowing. */
.moo-media-grid--single .moo-media-grid__item--encrypted {
  width: 240px;
  max-width: 100%;
  /* aspect-ratio (not an explicit height) so that when max-width:100% clamps the
     width on a narrow screen, the height tracks it and the ratio is preserved.
     The decrypt loop overrides --enc-ar inline with the image's real ratio. */
  aspect-ratio: var(--enc-ar, 4 / 3);
}
.moo-media-grid--single .moo-media-grid__item--encrypted .moo-media-enc-img {
  width: 100%;
  height: 100%;
  min-height: 0;
  object-fit: contain;
}
/* GIFs crop-fill the box (cover) instead of contain, so the KLIPY watermark
   never floats over an empty letterbox bar if the exact box wasn't set (e.g. a
   createImageBitmap failure leaves the default ratio). With the exact box,
   cover == contain. Must follow the rule above (equal specificity). */
.moo-media-grid--single .moo-media-grid__item--gif .moo-media-enc-img {
  object-fit: cover;
}

/* ---- Encrypted File Card ----
   Visually identical to an unencrypted file card now that every E2EE chat's
   files are encrypted by default. The only difference is the click handler
   (routes to mooDecryptAndView for in-browser decrypt). */
.moo-file-card--encrypted {
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* ---- Encrypted Items in Chat Info Grid ----
   Same principle as the in-message encrypted media: images get auto-decrypted
   inline (cmAutoDecryptEncImages), videos/files keep their existing visual
   (video icon / file icon) minus the padlock badge. */
.moo-chat-media__item--encrypted {
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.moo-chat-media-enc-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  background: rgba(255, 255, 255, 0.03);
}


/* Hidden file inputs for upload */
#moo_file_input_media,
#moo_file_input_files {
  display: none !important;
}

/* Shared modal component — used by group invite list */
.moo-fm-modal__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px 24px 16px;
  flex-shrink: 0;
}
.moo-fm-modal__title {
  font-size: 17px;
  font-weight: 700;
}
.moo-fm-modal__header button {
  width: 32px;
  height: 32px;
  border-radius: 10px;
  background: rgba(18, 26, 32, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.08);
  color: rgba(255, 255, 255, 0.4);
  font-size: 14px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s;
}
.moo-fm-modal__header button:active {
  background: rgba(28, 36, 44, 0.92);
}
.moo-fm-modal__list {
  overflow-y: auto;
  flex: 1;
  min-height: 0;
  padding: 0 24px 24px;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: none;
}
.moo-fm-modal__loading,
.moo-fm-modal__empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 48px 0;
  color: rgba(255, 255, 255, 0.25);
  font-size: 14px;
}
.moo-fm-modal__loading i,
.moo-fm-modal__empty i {
  font-size: 28px;
  color: rgba(255, 255, 255, 0.15);
}

/* Generic row component — used by group invite list */
.moo-fm-file {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.04);
  transition: opacity 0.2s;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.moo-fm-file:last-child {
  border-bottom: none;
}
.moo-fm-file__icon {
  width: 38px;
  height: 38px;
  border-radius: 10px;
  background: rgba(0, 229, 160, 0.08);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.moo-fm-file__icon i {
  color: var(--color-accent);
  font-size: 15px;
}
.moo-fm-file__info {
  flex: 1;
  min-width: 0;
}
.moo-fm-file__type {
  font-size: 13px;
  font-weight: 600;
  color: var(--color-text-primary);
}

/* ---- Danger-confirm modal pattern (.moo-da-modal__*) ----
   Shared by bills delete, time-tracker, and the note conflict modal. */
.moo-da-modal__header {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 28px 24px 0;
  flex-shrink: 0;
}
.moo-da-modal__icon {
  width: 48px;
  height: 48px;
  border-radius: 14px;
  background: rgba(244, 63, 94, 0.1);
  border: 1px solid rgba(244, 63, 94, 0.15);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  color: var(--color-danger);
}
.moo-da-modal__title {
  font-size: 18px;
  font-weight: 700;
  text-align: center;
}
.moo-da-modal__body {
  padding: 16px 24px;
  font-size: 14px;
  color: rgba(255, 255, 255, 0.5);
  line-height: 1.6;
}
.moo-da-modal__body p {
  margin: 0 0 8px;
}
.moo-da-modal__body ul {
  margin: 0 0 12px;
  padding-left: 20px;
}
.moo-da-modal__body li {
  margin-bottom: 4px;
}
.moo-da-modal__warn {
  color: var(--color-danger);
  font-weight: 600;
  font-size: 13px;
}
.moo-da-modal__actions {
  display: flex;
  gap: 10px;
  padding: 0 24px 20px;
}
.moo-da-modal__actions form {
  flex: 1;
  margin: 0;
}
.moo-da-modal__cancel {
  flex: 1;
  padding: 14px 20px;
  border-radius: 12px;
  background: rgba(18, 26, 32, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
  color: var(--color-text-primary);
  font-size: 14px;
  font-weight: 700;
  font-family: 'Montserrat', sans-serif;
  cursor: pointer;
  transition: opacity 0.2s, background-color 0.2s;
  white-space: nowrap;
}
.moo-da-modal__cancel:hover {
  background: rgba(28, 36, 44, 0.92);
}
.moo-da-modal__confirm {
  flex: 1;
  width: 100%;
  padding: 14px 20px;
  border-radius: 12px;
  white-space: nowrap;
  background: rgba(244, 63, 94, 0.15);
  border: 1px solid rgba(244, 63, 94, 0.3);
  color: var(--color-danger);
  font-size: 14px;
  font-weight: 700;
  font-family: 'Montserrat', sans-serif;
  cursor: pointer;
  transition: opacity 0.2s, background-color 0.2s, border-color 0.2s;
}
.moo-da-modal__confirm:hover:not(:disabled) {
  background: rgba(244, 63, 94, 0.25);
  border-color: rgba(244, 63, 94, 0.5);
}
.moo-da-modal__confirm:disabled {
  cursor: not-allowed;
}
.moo-da-modal__countdown {
  text-align: center;
  padding: 0 24px 20px;
  font-size: 12px;
  color: rgba(255, 255, 255, 0.25);
  font-weight: 500;
}
.moo-da-modal__countdown span {
  color: var(--color-danger);
  font-weight: 700;
}

/* Note concurrent-edit conflict modal — reuses the .moo-da-modal structure but
   with neutral chrome (a version fork is a choice, not a destructive action).
   Mint icon + primary button match the brand's "light source" accent. */
#ncf_wrap {
  position: absolute;
  inset: 0;
  background: rgba(6, 13, 16, 0.6);
  z-index: 999;
  animation: mooOverlayIn 0.2s ease-out;
}
#ncf_modal {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: none;
  flex-direction: column;
  background: rgba(20, 30, 38, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 24px;
  width: min(380px, calc(100% - 48px));
  z-index: 9999;
  color: var(--color-text-primary);
  animation: mooModalIn 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  overflow: hidden;
}
.moo-cf-modal__icon {
  width: 48px;
  height: 48px;
  border-radius: 14px;
  background: rgba(0, 229, 160, 0.1);
  border: 1px solid rgba(0, 229, 160, 0.18);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  color: var(--color-accent);
}
.moo-cf-modal__primary {
  flex: 1;
  padding: 14px 20px;
  border-radius: 12px;
  white-space: nowrap;
  background: rgba(0, 229, 160, 0.14);
  border: 1px solid rgba(0, 229, 160, 0.3);
  color: var(--color-accent);
  font-size: 14px;
  font-weight: 700;
  font-family: 'Montserrat', sans-serif;
  cursor: pointer;
  transition: background-color 0.2s, border-color 0.2s;
}
.moo-cf-modal__primary:hover {
  background: rgba(0, 229, 160, 0.2);
  border-color: rgba(0, 229, 160, 0.5);
}

/* Pinned messages list (chat info page) */
.moo-pinned-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.moo-pinned-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  background: rgba(14, 22, 28, 0.90);
  border: 1px solid rgba(255, 255, 255, 0.05);
  border-radius: 14px;
}
/* Pinned-message popup (tap a pin to read it in place). Above the /info panel. */
#pinned_view_wrap {
  position: absolute;
  inset: 0;
  background: rgba(6, 13, 16, 0.7);
  z-index: 100000;
  animation: mooOverlayIn 0.2s ease-out;
}
#pinned_view_modal {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 100001;
  width: min(420px, 80%);
  max-height: calc(100dvh - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px) - 48px);
  display: flex;
  flex-direction: column;
  background: rgba(20, 30, 38, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 24px;
  padding: 24px;
  color: var(--color-text-primary);
  animation: mooModalIn 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.moo-pinview__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}
.moo-pinview__sender {
  font-size: 16px;
  font-weight: 700;
  color: var(--color-accent);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.moo-pinview__close {
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  border: none;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--color-text-primary);
  cursor: pointer;
}
.moo-pinview__body {
  font-size: 15px;
  line-height: 1.5;
  color: var(--color-text-primary);
  overflow-y: auto;
  overscroll-behavior: none;
  word-break: break-word;
  overflow-wrap: anywhere;
}
.moo-pinview__gifwrap {
  position: relative;
  display: inline-block;
  max-width: 100%;
  line-height: 0;
}
.moo-pinview__gif {
  max-width: 100%;
  max-height: 50vh;
  border-radius: 12px;
  display: block;
}
.moo-pinview__coords {
  margin-top: 8px;
  font-size: 13px;
  color: rgba(255, 255, 255, 0.5);
}
.moo-pinview__maps {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 10px;
  color: var(--color-accent);
  text-decoration: none;
  font-size: 14px;
}
.moo-pinview__time {
  margin-top: 16px;
  font-size: 12px;
  color: rgba(255, 255, 255, 0.45);
}
.moo-pinned-item__content {
  flex: 1;
  min-width: 0;
}
.moo-pinned-item__sender {
  font-size: 13px;
  font-weight: 700;
  color: var(--color-accent);
  margin-bottom: 3px;
}
.moo-pinned-item__text {
  font-size: 14px;
  color: rgba(255, 255, 255, 0.6);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.moo-pinned-item__text i {
  margin-right: 4px;
}
.moo-pinned-item__time {
  font-size: 11px;
  color: rgba(255, 255, 255, 0.25);
  margin-top: 4px;
}
.moo-pinned-item__unpin {
  flex-shrink: 0;
}
.moo-pinned-item__unpin button {
  background: rgba(244, 63, 94, 0.1) !important;
  border: 1px solid rgba(244, 63, 94, 0.2) !important;
  border-radius: 10px !important;
  color: var(--color-danger) !important;
  width: 32px !important;
  height: 32px !important;
  padding: 0 !important;
  font-size: 14px !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  cursor: pointer;
  transition: opacity 0.2s, background-color 0.2s;
  margin: 0;
}
.moo-pinned-item__unpin button:hover {
  background: rgba(244, 63, 94, 0.2) !important;
}

/* ===== CHAT INFO — FILES & MEDIA ===== */
.moo-chat-media__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
  contain: layout style paint;
  /* Reserve one row so the auto-load (F18) doesn't collapse-then-jump the card. */
  min-height: 104px;
}
/* Failed/empty media states render as DIVs, never <button> (the settings-card
   button override at .moo-chatinfo ... button[type=button] would force odd sizing). */
.moo-chat-media__state {
  grid-column: 1 / -1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 104px;
  padding: 16px;
  text-align: center;
  color: var(--color-text-primary);
  opacity: 0.6;
  font-size: 14px;
}
.moo-chat-media__state i { font-size: 20px; }
.moo-chat-media__state--failed { cursor: pointer; opacity: 0.75; }
.moo-chat-media__item {
  border-radius: 12px;
  overflow: hidden;
  aspect-ratio: 1;
  cursor: pointer;
  position: relative;
  background: rgba(14, 22, 28, 0.92);
  -webkit-tap-highlight-color: transparent;
  content-visibility: auto;
  contain-intrinsic-size: auto 100px;
}
.moo-chat-media__item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.moo-chat-media__item .moo-media-grid__video-ph {
  min-height: 0;
  aspect-ratio: 1;
}
/* Play badge: a small corner rounded-square glass tile (8px chip radius, brand
   scale) instead of a centred 50% circle that obscured the thumbnail. */
.moo-chat-media__item--video::after {
  content: '\f04b';
  font-family: 'Font Awesome 6 Free';
  font-weight: 900;
  position: absolute;
  bottom: 6px;
  left: 6px;
  width: 26px;
  height: 26px;
  background: rgba(6, 13, 16, 0.5);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-accent);
  font-size: 12px;
  padding-left: 2px;
  pointer-events: none;
  z-index: 2;
}
/* Recoverable decrypt states for /info media tiles. --failed shows a tappable
   refresh glyph (the grid click handler re-queues the decrypt); --missing is a
   quiet dimmed 'unavailable' tile. Pure ::after overlay, no <button>/<div> child
   so it dodges the settings-card button override. */
.moo-chat-media__item--failed::after {
  content: '\f021';
  font-family: 'Font Awesome 6 Free';
  font-weight: 900;
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  color: var(--color-accent);
  background: rgba(6, 13, 16, 0.5);
  z-index: 2;
}
.moo-chat-media__item--missing {
  opacity: 0.5;
}
.moo-chat-media__item--missing::after {
  content: '\f127';
  font-family: 'Font Awesome 6 Free';
  font-weight: 900;
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  color: var(--color-text-primary);
  background: rgba(6, 13, 16, 0.45);
  z-index: 2;
}
.moo-chat-media__item--file {
  aspect-ratio: 1;
}
.moo-chat-media__file-cover {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  background: rgba(14, 22, 28, 0.90);
}
.moo-chat-media__file-cover i {
  font-size: 28px;
  color: var(--color-accent);
  opacity: 0.5;
}
.moo-chat-media__file-label {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: rgba(255, 255, 255, 0.3);
}
.moo-chat-media__grid:not(:empty) + .moo-chat-media__show-all {
  margin-top: 12px;
}
.moo-chat-media__show-all {
  width: 100%;
  padding: 12px;
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 12px;
  color: var(--color-text-primary);
  font-size: 13px;
  font-weight: 600;
  font-family: 'Montserrat', sans-serif;
  cursor: pointer;
  transition: opacity 0.2s, background-color 0.2s, color 0.2s, border-color 0.2s, transform 0.2s;
  -webkit-tap-highlight-color: transparent;
}
.moo-chat-media__show-all:hover {
  background: rgba(0, 229, 160, 0.1);
  border-color: rgba(0, 229, 160, 0.25);
  color: var(--color-accent);
}
.moo-chat-media__show-all:active {
  transform: scale(0.98);
  background: rgba(0, 229, 160, 0.08);
}

/* ===== GROUP INVITE CARDS (chats page) ===== */
.moo-gi-card {
  display: flex;
  align-items: center;
  gap: 12px;
  background: rgba(0, 229, 160, 0.06);
  border: 1px solid rgba(0, 229, 160, 0.12);
  border-radius: 16px;
  padding: 14px 16px;
  margin-bottom: 10px;
  transition: opacity 0.2s;
}
.moo-gi-card:last-child {
  margin-bottom: 0;
}
.moo-gi-card__icon {
  width: 40px;
  height: 40px;
  border-radius: 12px;
  background: rgba(0, 229, 160, 0.1);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  color: var(--color-accent);
  font-size: 16px;
}
.moo-gi-card__info {
  flex: 1;
  min-width: 0;
}
.moo-gi-card__title {
  font-size: 14px;
  font-weight: 700;
  color: var(--color-text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.moo-gi-card__sub {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.4);
  margin-top: 2px;
}
.moo-gi-card__actions {
  display: flex;
  gap: 8px;
  flex-shrink: 0;
}
.moo-gi-card__accept {
  width: 40px;
  height: 40px;
  border-radius: 10px;
  border: none;
  background: linear-gradient(135deg, var(--color-accent), var(--color-accent-dark));
  color: var(--color-bg);
  font-size: 14px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: opacity 0.2s, transform 0.2s;
  -webkit-tap-highlight-color: transparent;
}
.moo-gi-card__accept:active {
  transform: scale(0.9);
}
.moo-gi-card__decline {
  width: 40px;
  height: 40px;
  border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  background: rgba(18, 26, 32, 0.92);
  color: rgba(255, 255, 255, 0.5);
  font-size: 14px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: opacity 0.2s, background-color 0.2s, color 0.2s, border-color 0.2s, transform 0.2s;
  -webkit-tap-highlight-color: transparent;
}
.moo-gi-card__decline:active {
  transform: scale(0.9);
  background: rgba(244, 63, 94, 0.1);
  border-color: rgba(244, 63, 94, 0.2);
  color: var(--color-danger);
}

/* ===== RECOVERY-KEY BACKFILL NUDGE (chats page) =====
   One-time security prompt shown only to accounts whose recovery key can't yet
   unlock their encrypted data. Shares the glass-card language of the invite
   cards; the labeled primary action marks it as an account-security task rather
   than a routine notification. Mint is the light source — no glow/halo. */
.moo-rk-nudge {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 13px;
  background: rgba(0, 229, 160, 0.06);
  border: 1px solid rgba(0, 229, 160, 0.16);
  border-radius: 16px;
  padding: 16px;
  margin-bottom: 16px;
}
.moo-rk-nudge__icon {
  width: 44px;
  height: 44px;
  border-radius: 14px;
  background: rgba(0, 229, 160, 0.12);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  color: var(--color-accent);
  font-size: 18px;
}
.moo-rk-nudge__body {
  flex: 1;
  min-width: 0;
  padding-right: 22px; /* clear the dismiss control */
}
.moo-rk-nudge__title {
  font-size: 14.5px;
  font-weight: 700;
  color: var(--color-text-primary);
  letter-spacing: -0.01em;
}
.moo-rk-nudge__text {
  font-size: 12.5px;
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.55);
  margin-top: 4px;
}
.moo-rk-nudge__cta {
  display: inline-flex;
  align-items: center;
  margin-top: 13px;
  padding: 10px 16px;
  border-radius: 11px;
  border: none;
  background: linear-gradient(135deg, var(--color-accent), var(--color-accent-dark));
  color: var(--color-bg);
  font-family: 'Montserrat', sans-serif;
  font-size: 13px;
  font-weight: 700;
  text-decoration: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform 0.18s ease, filter 0.18s ease;
}
.moo-rk-nudge__cta:hover {
  filter: brightness(1.06);
}
.moo-rk-nudge__cta:active {
  transform: scale(0.97);
}
.moo-rk-nudge__dismiss {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 26px;
  height: 26px;
  border-radius: 8px;
  border: none;
  background: transparent;
  color: rgba(255, 255, 255, 0.4);
  font-size: 13px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  -webkit-tap-highlight-color: transparent;
  transition: background-color 0.18s ease, color 0.18s ease;
}
.moo-rk-nudge__dismiss:hover {
  background: rgba(255, 255, 255, 0.06);
  color: var(--color-text-primary);
}

/* Group invite modal */
#gi_wrap {
  position: absolute;
  inset: 0;
  background: rgba(6, 13, 16, 0.6);
  z-index: 100000; /* above the F14 /info slide-over panel (10000) */
  animation: mooOverlayIn 0.2s ease-out;
}
#gi_modal {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: none;
  flex-direction: column;
  background: rgba(20, 30, 38, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 24px;
  width: min(400px, calc(100% - 48px));
  max-height: calc(100vh - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px) - 48px);
  max-height: calc(100dvh - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px) - 48px);
  z-index: 100001;
  color: var(--color-text-primary);
  animation: mooModalIn 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  overflow: hidden;
}

/* Clickable pinned items */
.moo-pinned-item__content {
  cursor: pointer;
  transition: opacity 0.2s;
}
.moo-pinned-item__content:active {
  opacity: 0.7;
}

#delete_chat_button {
  width:100%;
}
.chat_participants {
  margin-top:20px;
}

.klipy_indv {
    width: 100%;
    aspect-ratio: 16 / 9;
}
.klipy_indv img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    border-radius: 12px;
}

/* KLIPY attribution watermark — subtle dark-glass chip on the sent GIF message
   card. Mint as atmosphere (the light source), not paint. Anchored to the
   position:relative .moo-media-grid__item card. */
.klipy_wm {
    position: absolute;
    right: 8px;
    bottom: 8px;
    z-index: 2;
    pointer-events: none;
    padding: 4px;
    border-radius: 4px;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.06em;
    line-height: 1;
    color: rgba(255, 255, 255, 0.82);
    background: rgba(6, 13, 16, 0.55);
    border: 1px solid rgba(0, 229, 160, 0.22);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.45);
}

.gifs_loading {
  position:absolute;
  top:68px;
  left:0px;

  opacity: 0;
  transition: opacity 250ms ease;

  display:none;
  text-align: center;
  vertical-align:middle;
  justify-content: center;
  align-items: center;

  width:100%;
  height:calc(100% - 68px);
  background-color: var(--color-bg-elevated);
  z-index:9;

  font-size:24px;
  font-weight:bold;
  color:var(--color-white);
}

#klipy_results {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 6px;

    width: 100%;
    height: calc(100% - 108px);

    overflow-y: scroll;
    overflow-x: hidden;
    overscroll-behavior: none;
    position: relative;

    margin-top: 20px;
    border-radius: 12px;
    padding: 0;
    box-sizing: border-box;
}

#klipy_search {
    width:calc(100% - 35px);
    min-height: 20px;
    line-height: 20px;
    background-color: var(--color-white);
    color: var(--color-black);
    margin: 0px;
    padding: 5px;
    padding-left:30px;
    font-size: 14px;
    height: 20px;
    border: 0px;
    border-radius: 12px;
}
#klipy_popup {
    overflow:hidden;
    position:absolute;
    top:50%;
    left:50%;
    transform:translate(-50%, -50%);
    padding:20px;
    width:80%;
    height:80%;
    background-color:var(--color-bg-elevated);
    color:var(--color-text-primary);
    border-radius:20px;
    display:none;
    z-index:9999;
}
#klipy_wrap {
    position:absolute;
    top:0px;
    left:0px;
    width:100%;
    height:100%;

    display:none;
    z-index:999;
}
.klipy_title {
    margin-bottom:20px;
    font-weight:bold;
    height:38px;
    font-size:20px;
    text-align:center;
    line-height:1.2;
}
.klipy_title_sub {
  width:100%;
  font-weight: normal;
  font-size:12px;
  text-align: center;
}

.GIF_IMG {
    width:auto !important;
    height:auto !important;

    min-width: 200px;
    max-width: 50vw;

    border-radius: 12px;
    overflow:hidden;
    display:flex;
}
.klipy_search_cont {
    position:relative;
}
.klipy_search_icon {
    position:absolute;
    top:0px;
    left:0px;

    display:flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    line-height:1;

    width:30px;
    height:30px;

    color:var(--color-black);
}

.push_button button {
  width:100%;
  margin-top:10px;
}
.push_button {
  display:flex;
  justify-content: center;
  align-items: center;
  gap:10px;
}

.unread_badge {
  position:absolute;
  top:-5px;
  right:-5px;

  background-color: var(--color-badge);
  color:var(--color-white);

  border-radius: 50%;

  width:20px;
  height:20px;
  overflow:hidden;

  font-weight:bold;
  font-size:12px;

  display:none;
  justify-content: center;
  text-align: center;
  align-items: center;
}

.input_time {
  background-color: var(--color-white);
  height:23px;
  text-align: left;
}

#pn_asked_wrap {
    position: absolute;
    top: 0px;
    left: 0px;
    width: 100%;
    height: 100%;
    background: rgba(6, 13, 16, 0.6);
    display: block;
    z-index: 999;
    animation: mooOverlayIn 0.2s ease-out;
}
#pn_asked_popup {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    padding: 32px;
    width: min(320px, 80%);
    height: auto;
    background: rgba(20, 30, 38, 0.85);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 24px;
    color: var(--color-text-primary);
    display: block;
    text-align: center;
    z-index: 9999;
    animation: mooModalIn 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.moo-pn-asked-icon {
    width: 56px;
    height: 56px;
    border-radius: 16px;
    background: rgba(0, 229, 160, 0.1);
    border: 1px solid rgba(0, 229, 160, 0.15);
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 auto 20px;
    font-size: 22px;
    color: var(--color-accent);
}
#pn_asked_popup .pn_popup_title {
    font-size: 18px;
    font-weight: 800;
    color: var(--color-text-primary);
    letter-spacing: -0.3px;
    margin-bottom: 8px;
}
#pn_asked_popup .pn_popup_message {
    font-size: 14px;
    color: rgba(255, 255, 255, 0.45);
    line-height: 1.6;
    margin-bottom: 24px;
}
#pn_asked_popup .mop_buttons_cont {
    display: flex;
    gap: 10px;
}
#pn_asked_popup .pn_button_no {
    flex: 1;
    margin-left: 0;
    padding: 14px;
    background: rgba(18, 26, 32, 0.92);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 14px;
    color: rgba(255, 255, 255, 0.6);
    font-weight: 600;
    font-size: 14px;
    font-family: 'Montserrat', sans-serif;
    cursor: pointer;
    transition: opacity 0.2s, background-color 0.2s;
    width: auto;
}
#pn_asked_popup .pn_button_no:hover {
    background: rgba(28, 36, 44, 0.92);
}
#pn_asked_popup .mop_button_yes {
    flex: 1;
    padding: 14px;
    background: linear-gradient(135deg, var(--color-accent), var(--color-accent-dark));
    border: none;
    border-radius: 14px;
    color: var(--color-bg);
    font-weight: 700;
    font-size: 14px;
    font-family: 'Montserrat', sans-serif;
    cursor: pointer;
    transition: opacity 0.2s, transform 0.2s, box-shadow 0.2s;
    width: auto;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
}
#pn_asked_popup .mop_button_yes:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 24px rgba(0, 229, 160, 0.25);
}

/* ===== Push-notification recovery banner =====
 * Surfaces the localStorage 'vocyl_pn_recovery_needed' flag set by
 * pwa_pn.js when the subscription dies silently. NON-modal (a banner,
 * not an interrupt) since the recovery state is "you should fix this"
 * not "you must fix this immediately". Amber-warning aurora glass to
 * differentiate from the accent-green primary actions — same visual
 * vocabulary as #pn_asked_popup (icon chip + title + button) but a
 * banner geometry that doesn't block the viewport.
 *
 * Hidden by default; JS toggles display:flex when the flag is set or
 * the 'vocyl-pn-needs-attention' custom event fires. */
#pn_recovery_banner {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 990;
    margin: env(safe-area-inset-top) auto 0;
    padding: 12px 14px;
    max-width: 540px;
    align-items: center;
    gap: 12px;
    background: linear-gradient(180deg, rgba(36, 28, 12, 0.96), rgba(20, 30, 38, 0.96));
    border-bottom: 1px solid rgba(251, 191, 36, 0.28);
    box-shadow: 0 12px 28px -16px rgba(0, 0, 0, 0.85);
    animation: mooPnBannerIn 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    color: var(--color-text-primary);
    font-family: 'Montserrat', sans-serif;
}
@media (min-width: 600px) {
    #pn_recovery_banner {
        margin-top: calc(env(safe-area-inset-top) + 12px);
        border: 1px solid rgba(251, 191, 36, 0.28);
        border-radius: 14px;
    }
}
@keyframes mooPnBannerIn {
    from { opacity: 0; transform: translateY(-8px); }
    to   { opacity: 1; transform: translateY(0);    }
}
.moo-pn-banner__icon {
    width: 36px;
    height: 36px;
    border-radius: 10px;
    background: rgba(251, 191, 36, 0.14);
    border: 1px solid rgba(251, 191, 36, 0.3);
    display: flex;
    align-items: center;
    justify-content: center;
    color: #fbbf24;
    font-size: 14px;
    flex-shrink: 0;
}
.moo-pn-banner__body {
    flex: 1;
    min-width: 0;
}
.moo-pn-banner__title {
    font-size: 13px;
    font-weight: 700;
    color: rgba(255, 255, 255, 0.92);
    letter-spacing: -0.1px;
}
.moo-pn-banner__msg {
    font-size: 11.5px;
    color: rgba(255, 255, 255, 0.55);
    line-height: 1.4;
    margin-top: 1px;
}
.moo-pn-banner__action {
    flex-shrink: 0;
    padding: 8px 14px;
    background: rgba(251, 191, 36, 0.16);
    border: 1px solid rgba(251, 191, 36, 0.4);
    border-radius: 9px;
    color: #fbbf24;
    font-size: 12px;
    font-weight: 700;
    cursor: pointer;
    font-family: 'Montserrat', sans-serif;
    transition: background-color 0.15s, border-color 0.15s, opacity 0.15s;
}
.moo-pn-banner__action:hover {
    background: rgba(251, 191, 36, 0.24);
    border-color: rgba(251, 191, 36, 0.55);
}
.moo-pn-banner__action:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}
.moo-pn-banner__close {
    flex-shrink: 0;
    width: 28px;
    height: 28px;
    background: transparent;
    border: 0;
    border-radius: 8px;
    color: rgba(255, 255, 255, 0.4);
    font-size: 14px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background-color 0.15s, color 0.15s;
}
.moo-pn-banner__close:hover {
    background: rgba(255, 255, 255, 0.06);
    color: rgba(255, 255, 255, 0.9);
}

#chats_popup_wrap {
    position:absolute;
    top:0px;
    left:0px;
    width:100%;
    height:100%;

    display:none;
    z-index:999;
}
#chats_popup {
    position:absolute;
    top:50%;
    left:50%;
    transform:translate(-50%, -50%);
    padding:20px;
    width:60%;
    height:auto;
    background-color:var(--color-bg-elevated);
    color:var(--color-text-primary);
    border-radius:20px;
    display:none;

    align-items: center;
    justify-content: center;
    text-align: center;
    flex-direction: column;
    z-index:9999;
}

.co_contact_form {
  display:flex;
  justify-content: center;
  text-align: center;
  align-items: center;
  gap:40px;
}
.contact_mn_display {
  font-size:16px;
  font-weight:normal;
}

.contact_last_online {
  font-size:14px;
  font-weight:normal;

  margin-top:10px;
}
.contact_timezone {
  font-size:14px;
  font-weight:normal;
}

.my_top_display {
  font-size:12px;
  font-weight:normal;
}

.loading_bar {
    position: fixed;
    top: 0px;
    left: 0px;

    width: calc(100% - 40px);
    height: 24px;

    color: var(--color-text-primary);
    background: var(--color-bg);
    border: none;
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);

    border-radius: 0px;
    padding: 20px;
    padding-top: calc(20px + env(safe-area-inset-top, 0));
    overflow: hidden;

    display: none;
    justify-content: flex-start;
    align-items: center;
    text-align: left;

    z-index: 999999;
}
.lb_left {
  font-size: 20px;
  color: var(--color-accent);

  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
}
.lb_right {
  display: flex;
  justify-content: center;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
  margin-left: 14px;
}
.lbr_line1 {
  font-weight: 700;
  font-size: 15px;
  color: var(--color-text-primary);

  display: flex;
  justify-content: flex-start;
  align-items: center;
  text-align: left;
  line-height: 1;
}
.lbr_line2 {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.4);

  display: flex;
  justify-content: flex-start;
  align-items: center;
  text-align: left;
  line-height: 1;
  margin-top: 2px;
}

#br_popup_wrap {
    position:absolute;
    top:0px;
    left:0px;
    width:100%;
    height:100%;

    display:none;
    z-index:999;
}
#br_popup {
    position:absolute;
    top:50%;
    left:50%;
    transform:translate(-50%, -50%);
    padding:20px;

    width:80%;
    max-width:300px;

    height:auto;
    max-height:80%;

    overflow-x:hidden;
    overflow-y:auto;
    overscroll-behavior: none;

    background-color:var(--color-white);
    border: 1px solid rgba(255, 255, 255, 0.08);
    color:var(--color-black);
    border-radius:20px;

    display:none;
    align-items: center;
    justify-content: center;
    text-align: center;
    flex-direction: column;

    z-index:9999;
}
.br_popup_title {
  font-size:18px;
  text-align:center;
  font-weight:bold;
  margin-bottom:20px;
}
.br_form {
  display:flex;
  flex-direction: column;
  gap:10px;
  width:100%;
}
.br_submit_button {
  font-size: 17px;
  font-weight: bold;
  padding: 15px;
  text-align: center;
  height: auto;
  margin: 0px;
  border: 0px;
  border-radius: 12px;
  background-color: var(--color-bg-elevated);
  border: 1px solid rgba(255, 255, 255, 0.1);
  color: var(--color-text-primary);
  width: 100%;
}
.br_selectbox {
  -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;

  font-size: 17px;
  margin: 0px;
  padding: 15px;
  width:100%;
  margin-right: 10px;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  background-color: var(--color-white);
  color:var(--color-black);
}
.br_textarea {
  -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;

  font-size: 17px;
  margin: 0px;
  padding: 15px;
  width:calc(100% - 32px);
  height:140px;
  margin-right: 10px;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  color:var(--color-black);

  overflow-x:hidden;
  overflow-y:auto;
  overscroll-behavior: none;

  resize:none;
}
.br_textarea::placeholder {
  font-weight: normal;
  opacity: 1;
  color: var(--color-black);
}

#ms_popup_wrap {
    position:absolute;
    top:0px;
    left:0px;
    width:100%;
    height:100%;

    display:none;
    z-index:999;
}
#ms_popup {
    position:absolute;
    top:50%;
    left:50%;
    transform:translate(-50%, -50%);
    padding:20px;
    width:80%;
    height:auto;
    max-height:80%;

    overflow-x:hidden;
    overflow-y:auto;
    overscroll-behavior: none;

    background-color:var(--color-bg-elevated);
    border:0px;
    color:var(--color-text-primary);
    border-radius:20px;
    display:none;

    align-items: center;
    justify-content: center;
    text-align: center;
    flex-direction: column;

    z-index:9999;
}
.ms_popup_title {
  font-size:18px;
  text-align:center;
  font-weight:bold;
  margin-bottom:20px;
}

.messages_encrypted {
  height:auto;
  width:fit-content;
  text-align:center;
  padding:10px;
  font-size:14px;
  font-weight:normal;
  clear:both;
  margin-bottom:20px;
  background-color:var(--color-bg-elevated);
  color:var(--color-text-primary);
  border-radius:10px;
  margin-left:auto;
  margin-right:auto;
}

.input_select {
  font-size: 18px;
  margin: 0px;
  padding: 5px;
  width: calc(100% - 12px);
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.1);
}

.loading_more_chat {
  position:absolute;
  top:20px;
  left:20px;
  width:calc(100% - 80px);
  height:auto;

  padding: 20px;
  font-size: 20px;
  font-weight: bold;

  background-color: var(--color-bg-elevated);
  color: var(--color-text-primary);
  border-radius: 12px;

  opacity: 0;
  transition: opacity 200ms ease;

  display:none;
  justify-content: center;
  align-items: center;
  text-align: center;
}
.lmc_text {
  margin-left:10px;
}

.table_cont {
  border:1px solid rgba(255, 255, 255, 0.1);
  border-radius:14px;

  display:flex;
  flex-direction: column;
  overflow:hidden;
}
.table_header {
  background-color: var(--color-bg-elevated);
  padding:20px;
  color:var(--color-white);
  font-weight:bold;
  font-size:20px;
}
.table_content {
  display:flex;
  flex-direction: column;
  overflow:hidden;
}
.table_headers {
  font-weight:bold;
  font-size:18px;
  border-bottom:1px solid rgba(255, 255, 255, 0.1);
}
.table_row {
  font-size:16px;
  display:flex;
  justify-content: space-between;
  align-items: center;
  overflow:hidden;
}
.table_column {
  display:flex;
  padding:20px;

  overflow-x:scroll;
  overscroll-behavior-x: none;

  white-space: nowrap;

  touch-action: pan-x pan-y;
  -webkit-overflow-scrolling: touch;
}
.tc_splitbutton {
  justify-content: space-between;
  align-items: center;
  gap:20px;
}
.table_buttons {
  display:flex;
  align-items: center;
  gap:10px;
  justify-content: flex-start;

  touch-action: pan-x pan-y;
  -webkit-overflow-scrolling: touch;
}
.table_buttons button {
  color: var(--color-text-primary);
  font-size:16px;
  width:28px;
  height:28px;
  border-radius: 10px;
  background-color: var(--color-bg-elevated);
  cursor: pointer;

  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;

  margin: 0px;
  padding: 0px;
  border: 0px;

  touch-action: pan-x pan-y;
  -webkit-overflow-scrolling: touch;
}
.fa_eye_slash_button {
  font-size:13px !important;
}
.table_content_hidden {
  display:none;
}
.table_open_content_button {
  border-radius:10px;
  cursor: pointer;

  font-size:14px;
  font-weight:bold;

  padding:0px 10px;
  height:28px;

  background-color: var(--color-accent);
  color:var(--color-bg);

  touch-action: pan-x pan-y;
  -webkit-overflow-scrolling: touch;

  display:flex;
  text-align: center;
  align-items: center;
  justify-content: center;
}

.table_row_content:nth-child(odd) {
  background-color: var(--color-row-alt);
}
.sv_trc1 {
  width:50%;
}
.sv_trc2 {
  width:50%;
}
.tc_margintop {
  margin-top:20px;
}
.table_norows {
  padding:20px;
}
.report_trc1 {
  width:20%;
}
.report_trc2 {
  width:30%;
}
.report_trc3 {
  width:50%;
}

.content_dialog_text {
  display:flex;
  overflow-wrap: break-word;
  word-wrap: break-word;
  word-break: break-all;
}
#content_dialog_wrap {
    position:absolute;
    top:0px;
    left:0px;
    width:100%;
    height:100%;

    display:none;
    z-index:999;
}
#cd_popup {
    position:absolute;
    top:50%;
    left:50%;
    transform:translate(-50%, -50%);
    padding:20px;

    width:80%;
    height:auto;
    max-height:80%;

    overflow-x:hidden;
    overflow-y:auto;
    overscroll-behavior: none;

    background-color:var(--color-white);
    border: 1px solid rgba(255, 255, 255, 0.08);
    color:var(--color-black);
    border-radius:20px;

    display:none;
    align-items: center;
    justify-content: center;
    text-align: center;
    flex-direction: column;

    z-index:9999;
}

.chats_list_none {
  display:none;
}

.hli_cont {
  display:flex;
  justify-content: center;
  align-items: center;
  text-align: center;
}
.hive_logo_img {
  width:70%;
  max-width:300px;
}

.settings_item_last {
  margin-bottom:0px;
}

/* =====================================================================
   ALARM TOOL — Mission-control visual system.
   State-as-color is the primary semantic. Hero state is the centerpiece.
   Quiet most of the time; loud on trigger. Scoped under
   so it never bleeds.
   ===================================================================== */

:root {
  /* Semantic state hues — solid colours used for borders, text, glows. */
  --alarm-c-disarmed:    hsl(158, 64%, 50%);
  --alarm-c-arming:      hsl(40, 92%, 58%);
  --alarm-c-armed-away:  hsl(355, 82%, 60%);
  --alarm-c-armed-home:  hsl(22, 90%, 58%);
  --alarm-c-pending:     hsl(354, 88%, 62%);
  --alarm-c-triggered:   hsl(0, 95%, 62%);

  /* Glass surface scale */
  --alarm-glass-1: rgba(255,255,255,0.035);
  --alarm-glass-2: rgba(255,255,255,0.062);
  --alarm-glass-3: rgba(255,255,255,0.095);
  --alarm-border:        rgba(255,255,255,0.07);
  --alarm-border-strong: rgba(255,255,255,0.14);

  /* Text scale */
  --alarm-text-primary:   rgba(255,255,255,0.95);
  --alarm-text-secondary: rgba(255,255,255,0.62);
  --alarm-text-muted:     rgba(255,255,255,0.40);

  /* Shadows */
  --alarm-shadow-card: 0 4px 24px rgba(0,0,0,0.32), 0 1px 0 rgba(255,255,255,0.04) inset;

  /* Online-dot scale */
  --alarm-c-online:      hsl(150, 70%, 50%);
  --alarm-c-online-warn: hsl(40, 90%, 55%);
  --alarm-c-offline:     hsl(0, 70%, 55%);

  /* Battery */
  --alarm-c-battery-ok:   hsl(150, 60%, 50%);
  --alarm-c-battery-low:  hsl(40, 90%, 55%);
  --alarm-c-battery-crit: hsl(0, 80%, 58%);
}

/* ===== Page wrapper =====
   No custom wrapper rules — inherit fully from .chats_cont + .moo-tools so
   sizing matches every other Vello tool. Content elements have their own
   spacing/gaps; the wrapper stays vanilla block-layout. */

/* ===== Generic buttons ===== */
.moo-alarm__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 12px 16px;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  background: rgba(24, 32, 40, 0.92);
  color: var(--alarm-text-primary);
  font: 600 13px/1 'Montserrat', sans-serif;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: background-color 160ms ease, border-color 160ms ease, transform 80ms ease;
  white-space: nowrap;
  text-decoration: none;
  appearance: none;
  -webkit-appearance: none;
  box-sizing: border-box;
  font-family: inherit;
}
.moo-alarm__btn:hover { background: var(--alarm-glass-3); }
.moo-alarm__btn:active { transform: translateY(1px); }
.moo-alarm__btn[disabled] {
  opacity: 0.42;
  cursor: not-allowed;
  pointer-events: none;
}

.moo-alarm__btn--primary {
  background: color-mix(in srgb, var(--alarm-c-disarmed) 18%, var(--alarm-glass-2));
  border-color: color-mix(in srgb, var(--alarm-c-disarmed) 50%, transparent);
  color: var(--alarm-c-disarmed);
}
.moo-alarm__btn--primary:hover {
  background: color-mix(in srgb, var(--alarm-c-disarmed) 26%, var(--alarm-glass-2));
}

.moo-alarm__btn--danger {
  background: color-mix(in srgb, var(--alarm-c-triggered) 18%, var(--alarm-glass-2));
  border-color: color-mix(in srgb, var(--alarm-c-triggered) 55%, transparent);
  color: var(--alarm-c-triggered);
}
.moo-alarm__btn--danger:hover {
  background: color-mix(in srgb, var(--alarm-c-triggered) 26%, var(--alarm-glass-2));
}

.moo-alarm__btn--ghost {
  background: transparent;
  border-color: var(--alarm-border);
  color: var(--alarm-text-secondary);
}

.moo-alarm__btn--block { width: 100%; }

.moo-alarm__btn--sm {
  padding: 8px 12px;
  font-size: 12px;
  border-radius: 10px;
  gap: 6px;
}

/* Utility layout helpers for alarm — replaces scattered inline `style=""` */
.moo-alarm__check-row { display: flex; gap: 14px; flex-wrap: wrap; }
.moo-alarm__pin-actions { display: flex; gap: 6px; flex-shrink: 0; }
.moo-alarm__placeholder--ghost { background: transparent; border: 0; padding: 32px 16px; }
.moo-alarm__heading--gap { margin-top: 18px; }
/* Wraps {label, control, optional hint} as one tight unit. Inside an
   expand-inner the parent's child-spacing rule treats the whole block as
   a single child, so the internals stay close together (label margin-bottom
   8 to control, optional 6px hint below) instead of inheriting a 14px sibling
   gap that would visually break the label from its control. */
.moo-alarm__field-block { display: block; }
/* Helper hint sitting tight below a control (input / readonly-field).
   6px is the "tight pair" distance — close enough to read as belonging to
   the control above, far enough to register as secondary text. Replaces
   scattered inline `style="margin-top: 6px"` on .moo-alarm__field-row-desc. */
.moo-alarm__field-row-desc--hint { margin-top: 6px; }

.moo-alarm__btn-row {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

/* Active header-nav button — green accent matching .moo-tools__item-icon highlight.
   ALM-061(b): route the brand accent through the --color-accent :root token
   (#00e5a0 == rgb(0,229,160)) instead of hardcoding the literal, so a brand
   retune in :root stays in sync with the rest of the accent-coloured UI. */
body:has(.moo-tools) .hb_button_multi.is-active {
  background: color-mix(in srgb, var(--color-accent) 18%, transparent);
  border-color: color-mix(in srgb, var(--color-accent) 45%, transparent);
  color: var(--color-accent);
}

/* ===== Form controls ===== */
.moo-alarm__input {
  width: 100%;
  padding: 12px 16px;
  border-radius: 12px;
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
  color: var(--alarm-text-primary);
  font: 500 15px/1.3 'Montserrat', sans-serif;
  transition: border-color 160ms ease, background-color 160ms ease;
  appearance: none;
  -webkit-appearance: none;
  box-sizing: border-box;
}
.moo-alarm__input:focus {
  outline: none;
  border-color: rgba(255, 255, 255, 0.16);
  background: rgba(24, 32, 40, 0.92);
}
.moo-alarm__input::placeholder { color: var(--alarm-text-muted); }
.moo-alarm__input option { background: #0e161c; color: var(--alarm-text-primary); }

select.moo-alarm__input {
  padding-right: 40px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='rgba%28255%2C 255%2C 255%2C 0.62%29' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 16px center;
  background-size: 16px;
  cursor: pointer;
  -moz-appearance: none;
}
select.moo-alarm__input::-ms-expand {
  display: none;
}

.moo-alarm__check input:focus-visible + .moo-alarm__check-box {
  outline: 2px solid var(--alarm-c-disarmed);
  outline-offset: 2px;
}
/* ALM-061(a): scope the alarm-green focus ring to alarm toggles only.
   `.moo-toggle`/`.moo-toggle__track` is a SHARED component (Bills, Cloud Drive,
   Settings, Chat — Bills & CD even share the .moo-tools wrapper), so this rule
   was unscoped and leaked --alarm-c-disarmed onto every toggle in the app.
   `.moo-alarm__field-row-control` is the alarm-only ancestor of every alarm
   toggle (devices.php / users.php) and never appears outside the alarm subsystem. */
.moo-alarm__field-row-control .moo-toggle input:focus-visible + .moo-toggle__track {
  outline: 2px solid var(--alarm-c-disarmed);
  outline-offset: 2px;
}

/* Direct-child spacing inside expand-inner. Block layout (set below) makes
   spacing margin-driven — keeps a wrapper (form, .moo-alarm__field-block)
   tight inside while putting consistent breathing room between siblings.
   The `--gap` modifier on a heading promotes it to a section break (24px). */
.moo-alarm__list-card-expand-inner > * + * { margin-top: 14px; }
.moo-alarm__list-card-expand-inner > .moo-alarm__heading--gap,
.moo-alarm__list-card-expand-inner > .moo-alarm__form--gap-top { margin-top: 24px; }

/* Label baseline for alarm forms. Existing Vocyl `.cn_input_title` is only
   styled inside `.moo-form-card`; alarm forms aren't wrapped in that. Apply
   the same look + consistent stacking margins. Scoped with body:has() NOT a
   `.moo-tools` descendant: the modals are relocated to <body> (outside
   `.moo-tools`) on load, so a descendant selector would leave their labels
   unstyled — the bug behind "modal font sizes are wrong". */
body:has(.moo-tools) .cn_input_title {
  display: block;
  color: rgba(255, 255, 255, 0.40);
  font: 700 11px/1 'Montserrat', sans-serif;
  text-transform: uppercase;
  letter-spacing: 1px;
  margin: 20px 0 8px;
}
.moo-tools .cn_input_title:first-child,
.moo-tools form .cn_input_title:first-child,
.moo-tools .moo-alarm__list-card-expand .cn_input_title:first-of-type,
body:has(.moo-tools) .moo-alarm__modal .cn_input_title:first-of-type {
  margin-top: 0;
}
/* ALM-061(d): `.moo-tools .cn_subtext` (a generic, tool-wide helper rule) was
   relocated OUT of this alarm block to the shared tools section (search
   ".moo-tools .moo-form-card .cn_subtext") so a future "delete the alarm CSS"
   refactor can't accidentally drop a style every tool relies on. */
/* Inline helper hint inside an uppercase label (e.g. the parentheticals in the
   Add Camera form): reset the inherited bold UPPERCASE tracking so it reads as
   soft, normal-case text rather than shouting at label size. */
body:has(.moo-tools) .cn_input_title .moo-alarm__muted {
  text-transform: none;
  letter-spacing: 0;
  font-weight: 500;
}
/* Form-level layout: alarm forms inside list-card-expand / section / modal
   use BLOCK layout (default). Children manage their own margins so each
   label / input / row gets identical top spacing. */
.moo-tools .moo-alarm__list-card-expand form {
  display: block;
}
/* Modal forms are the flex column that fills the modal: a scrollable
   .moo-alarm__modal-body sits above a pinned .moo-alarm__modal-actions footer. */
body:has(.moo-tools) .moo-alarm__modal form {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
}
/* Field-row toggles inside a form get generous breathing above (matches label
   margin-top). They are standalone control groups, not paired to a preceding
   label. */
.moo-tools .moo-alarm__list-card-expand form .moo-alarm__field-row,
body:has(.moo-tools) .moo-alarm__modal form .moo-alarm__field-row {
  margin-top: 20px;
}
/* Check-rows are paired to the cn_input_title directly above them — they
   are the "input" for that label. Sit them close (only the label's own
   margin-bottom applies). */
.moo-tools .moo-alarm__list-card-expand form .moo-alarm__check-row,
body:has(.moo-tools) .moo-alarm__modal form .moo-alarm__check-row {
  margin-top: 0;
}
/* Submit row sits below the last form group with generous breathing room.
   (Modal footers are pinned via padding in the modal block below, not margin.) */
.moo-tools .moo-alarm__list-card-expand form > button[type="submit"],
.moo-tools .moo-alarm__list-card-expand form > .moo-alarm__btn-row {
  margin-top: 24px;
}

/* Toggle: use existing .moo-toggle / .moo-toggle__track from bills (pure CSS). */

/* Checkbox (square) */
.moo-alarm__check {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  user-select: none;
}
.moo-alarm__check input {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.moo-alarm__check-box {
  width: 20px;
  height: 20px;
  border-radius: 6px;
  border: 1px solid var(--alarm-border-strong);
  background: var(--alarm-glass-1);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background-color 160ms ease, border-color 160ms ease;
  flex-shrink: 0;
}
.moo-alarm__check-box::after {
  content: '';
  width: 10px;
  height: 10px;
  border-radius: 3px;
  background: var(--alarm-c-disarmed);
  transform: scale(0);
  transition: transform 160ms cubic-bezier(0.4, 0, 0.2, 1);
}
.moo-alarm__check input:checked + .moo-alarm__check-box {
  border-color: color-mix(in srgb, var(--alarm-c-disarmed) 55%, transparent);
  background: color-mix(in srgb, var(--alarm-c-disarmed) 14%, var(--alarm-glass-2));
}
.moo-alarm__check input:checked + .moo-alarm__check-box::after {
  transform: scale(1);
}
.moo-alarm__check-label {
  font: 500 14px/1.3 'Montserrat', sans-serif;
  color: var(--alarm-text-primary);
}

/* ===== Section card (used in Settings, etc) ===== */
.moo-alarm__section {
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 16px;
  padding: 22px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}
.moo-alarm__section-title {
  font: 700 11px/1 'Montserrat', sans-serif;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: rgba(255, 255, 255, 0.45);
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
}
.moo-alarm__section-title > i { font-size: 11px; }
.moo-alarm__section + .moo-alarm__section { margin-top: 16px; }

.moo-alarm__field-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 0;
}
/* Subtle divider between adjacent field-rows inside a section. The
   .moo-alarm__section parent supplies a 20px flex gap; we add 20px padding
   ABOVE the border so the line has matching breathing room top and bottom. */
.moo-alarm__section .moo-alarm__field-row + .moo-alarm__field-row {
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  padding-top: 20px;
}
.moo-alarm__field-row-info {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.moo-alarm__field-row-info .moo-alarm__field-row-desc { margin-top: 0; }
.moo-alarm__field-row-title {
  font: 700 14px/1.25 'Montserrat', sans-serif;
  color: var(--alarm-text-primary);
}
.moo-alarm__field-row-desc {
  font: 500 12px/1.4 'Montserrat', sans-serif;
  color: rgba(255, 255, 255, 0.55);
}
.moo-alarm__field-row-control {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

/* ===== Dashboard: Hero card ===== */
.moo-alarm__hero {
  position: relative;
  border-radius: 18px;
  padding: 26px 22px 22px;
  margin-bottom: 20px;
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.07);
  display: flex;
  flex-direction: column;
  gap: 10px;
  height: auto;
  overflow: hidden;
  isolation: isolate;
  box-shadow: var(--alarm-shadow-card);
  transition: border-color 280ms ease, background-color 280ms ease;
}
.moo-alarm__hero::before {
  content: '';
  position: absolute;
  inset: -40%;
  background: radial-gradient(circle at 20% 20%, var(--_alarm-hero-glow, transparent), transparent 60%);
  opacity: 0.55;
  z-index: -1;
  transition: background 280ms ease, opacity 280ms ease;
  pointer-events: none;
}
/* Hero type hierarchy — PRIMARY (state) > SECONDARY (countdown) >
   SUPPORTING (detail) > CAPTION (meta). The state label IS the headline;
   the countdown sits beneath as urgent-but-secondary numeric data. */
.moo-alarm__hero-state {
  font: 700 46px/1.02 'Montserrat', sans-serif;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--_alarm-hero-fg, var(--alarm-text-primary));
  transition: color 280ms ease;
  word-break: break-word;
  /* Two-layer dark drop shadow — the close 1/2px layer crisps the edge
     against the hero's radial-gradient backdrop, the wider 3/12px layer
     adds soft depth below. Was a colored glow (matched the state's fg
     color at 22%/28px blur) which read as harsh "lit up from inside";
     dark shadow drops the text into the panel instead. Uses plain black
     rather than `var(--color-bg)` so the shadow is the same on every
     state without picking up the panel's bg tint. */
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.55), 0 3px 12px rgba(0, 0, 0, 0.35);
}
.moo-alarm__hero-meta {
  font: 600 11px/1.4 'Montserrat', sans-serif;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  /* Override `--alarm-text-muted` (0.4 alpha) for this one element — the
     hero's "since 14:32" meta line was disappearing into the panel against
     the new dark text-shadow on the state above it. 0.8 reads as clearly
     legible supporting copy without overpowering the headline. */
  color: rgba(255, 255, 255, 0.8);
  font-variant-numeric: tabular-nums;
}
.moo-alarm__hero-countdown {
  font: 800 38px/1 'Montserrat', sans-serif;
  color: var(--_alarm-hero-fg, var(--alarm-text-primary));
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.015em;
  margin-top: 2px;
}
.moo-alarm__hero-detail {
  font: 500 15px/1.45 'Montserrat', sans-serif;
  color: var(--alarm-text-primary);
  letter-spacing: 0.005em;
}
/* Hero body wrapper — purely a JS-patch handle. display:contents keeps the
   meta/detail/countdown direct-child flex behaviour of the hero. */
[data-alarm-hero-body] { display: contents; }

/* Hero state palette swaps */
.moo-alarm__hero--disarmed {
  --_alarm-hero-fg: var(--alarm-c-disarmed);
  --_alarm-hero-glow: color-mix(in srgb, var(--alarm-c-disarmed) 35%, transparent);
  border-color: color-mix(in srgb, var(--alarm-c-disarmed) 24%, transparent);
}
.moo-alarm__hero--arming_away,
.moo-alarm__hero--arming_home {
  --_alarm-hero-fg: var(--alarm-c-arming);
  --_alarm-hero-glow: color-mix(in srgb, var(--alarm-c-arming) 35%, transparent);
  border-color: color-mix(in srgb, var(--alarm-c-arming) 30%, transparent);
  animation: alarmPulseSoft 1.6s ease-in-out infinite;
}
.moo-alarm__hero--armed_away {
  --_alarm-hero-fg: var(--alarm-c-armed-away);
  --_alarm-hero-glow: color-mix(in srgb, var(--alarm-c-armed-away) 38%, transparent);
  border-color: color-mix(in srgb, var(--alarm-c-armed-away) 30%, transparent);
}
.moo-alarm__hero--armed_home {
  --_alarm-hero-fg: var(--alarm-c-armed-home);
  --_alarm-hero-glow: color-mix(in srgb, var(--alarm-c-armed-home) 38%, transparent);
  border-color: color-mix(in srgb, var(--alarm-c-armed-home) 30%, transparent);
}
.moo-alarm__hero--pending {
  --_alarm-hero-fg: var(--alarm-c-pending);
  --_alarm-hero-glow: color-mix(in srgb, var(--alarm-c-pending) 45%, transparent);
  border-color: color-mix(in srgb, var(--alarm-c-pending) 50%, transparent);
  animation: alarmPulseSoft 1.0s ease-in-out infinite;
}
.moo-alarm__hero--triggered {
  --_alarm-hero-fg: #fff;
  --_alarm-hero-glow: color-mix(in srgb, var(--alarm-c-triggered) 55%, transparent);
  background: color-mix(in srgb, var(--alarm-c-triggered) 22%, var(--alarm-glass-2));
  border-color: var(--alarm-c-triggered);
  animation: alarmFlash 0.55s steps(2) infinite;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--alarm-c-triggered) 65%, transparent),
              0 16px 48px color-mix(in srgb, var(--alarm-c-triggered) 35%, transparent),
              0 1px 0 rgba(255,255,255,0.06) inset;
}

/* ===== Dashboard: section titles ===== */
/* ===== Arm/disarm command buttons — embedded in the hero card.
   margin-top mirrors the hero's outer padding so the gap above the buttons
   equals the padding on every other side (6px hero gap + 16px margin = 22px). */
.moo-alarm__commands {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
  margin-top: 16px;
  margin-bottom: 0;
}
.moo-alarm__cmd-status {
  display: flex;
  justify-content: center;
  margin-top: 16px;
  padding-top: 2px;
}
.moo-alarm__cmd-status[hidden] { display: none; }
.moo-alarm__cmd-status-pill {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 11px;
  border-radius: 9px;
  border: 1px solid rgba(255, 255, 255, 0.05);
  background: rgba(255, 255, 255, 0.03);
  color: var(--alarm-text-secondary);
  font: 600 11px/1.3 'Montserrat', sans-serif;
  letter-spacing: 0.02em;
}
.moo-alarm__cmd-status-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  flex: 0 0 auto;
  background: var(--color-accent);
}
.moo-alarm__cmd-status-pill--pending .moo-alarm__cmd-status-dot {
  background: var(--color-accent);
  animation: moo-alarm-cmd-pulse 1.2s ease-in-out infinite;
}
/* "Command didn't apply" — use the alarm-scoped triggered token (red) since
   the command genuinely failed; the global --color-warning is hue-adjacent
   to the arming/armed_home hero glow and washed out against those states. */
.moo-alarm__cmd-status-pill--failed {
  color: var(--alarm-text-primary);
}
.moo-alarm__cmd-status-pill--failed .moo-alarm__cmd-status-dot {
  background: var(--alarm-c-triggered);
}
@keyframes moo-alarm-cmd-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.35; transform: scale(0.7); }
}
@media (prefers-reduced-motion: reduce) {
  .moo-alarm__cmd-status-pill--pending .moo-alarm__cmd-status-dot { animation: none; }
}

/* ===== Dashboard: Agent-silent banner =====
   Sits above the hero card when the Pi agent hasn't been heard from recently
   (alarm_agent_last_sync stale). Two severities: --warn (2-10min, transient,
   yellow) and --off (>10min or never-seen, real outage, red). Hidden when
   agent is in 'ok' state. Glass-morphism strip with a left-edge severity stripe
   + radial glow matching the hero's aesthetic.

   Severity → banner mapping mirrors alarm_get_base_station_status's online_cls
   ('warn' = warn banner, 'off' = off banner). The patcher in dashboard.php
   toggles the modifier class + the `hidden` attribute. */
.moo-alarm__agent-banner {
  position: relative;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 13px 18px;
  margin-bottom: 14px;
  border-radius: 14px;
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid var(--alarm-border);
  border-left-width: 3px;
  border-left-color: var(--_alarm-agent-accent, var(--alarm-border-strong));
  box-shadow: var(--alarm-shadow-card);
  overflow: hidden;
  isolation: isolate;
  transition: border-color 240ms ease, background-color 240ms ease;
}
.moo-alarm__agent-banner[hidden] { display: none; }
.moo-alarm__agent-banner::before {
  content: '';
  position: absolute;
  inset: -60% -40% -60% -40%;
  background: radial-gradient(circle at 0% 50%, var(--_alarm-agent-glow, transparent), transparent 55%);
  opacity: 0.5;
  z-index: -1;
  pointer-events: none;
  transition: background 240ms ease, opacity 240ms ease;
}
.moo-alarm__agent-banner--warn {
  --_alarm-agent-accent: var(--alarm-c-online-warn);
  --_alarm-agent-glow: color-mix(in srgb, var(--alarm-c-online-warn) 40%, transparent);
}
.moo-alarm__agent-banner--off {
  --_alarm-agent-accent: var(--alarm-c-offline);
  --_alarm-agent-glow: color-mix(in srgb, var(--alarm-c-offline) 55%, transparent);
  animation: moo-alarm-agent-banner-ring 2.4s ease-in-out infinite;
}
@keyframes moo-alarm-agent-banner-ring {
  0%, 100% { box-shadow: var(--alarm-shadow-card), 0 0 0 0 color-mix(in srgb, var(--alarm-c-offline) 35%, transparent); }
  50%      { box-shadow: var(--alarm-shadow-card), 0 0 0 4px color-mix(in srgb, var(--alarm-c-offline) 10%, transparent); }
}
.moo-alarm__agent-banner-icon {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  flex: 0 0 auto;
  border-radius: 10px;
  background: color-mix(in srgb, var(--_alarm-agent-accent) 14%, transparent);
  color: var(--_alarm-agent-accent);
  font-size: 16px;
}
.moo-alarm__agent-banner-icon-dot {
  position: absolute;
  top: 5px;
  right: 5px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--_alarm-agent-accent);
  box-shadow: 0 0 0 2px rgba(14, 22, 28, 0.92);
  animation: moo-alarm-agent-icon-pulse 1.4s ease-in-out infinite;
}
@keyframes moo-alarm-agent-icon-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.35; transform: scale(0.7); }
}
.moo-alarm__agent-banner-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  flex: 1 1 auto;
}
.moo-alarm__agent-banner-label {
  font: 700 11px/1.4 'Montserrat', sans-serif;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--_alarm-agent-accent);
}
.moo-alarm__agent-banner-text {
  font: 500 14px/1.4 'Montserrat', sans-serif;
  color: var(--alarm-text-primary);
  letter-spacing: 0.002em;
}
@media (prefers-reduced-motion: reduce) {
  .moo-alarm__agent-banner--off       { animation: none; }
  .moo-alarm__agent-banner-icon-dot   { animation: none; }
}

.moo-alarm__cmd {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 14px 10px;
  min-height: 78px;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.08);
  background: rgba(0, 0, 0, 0.25);
  color: var(--alarm-text-secondary);
  font: 700 12px/1 'Montserrat', sans-serif;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background-color 160ms ease, border-color 160ms ease, color 160ms ease, transform 80ms ease;
  appearance: none;
  -webkit-appearance: none;
  box-sizing: border-box;
  font-family: inherit;
}
.moo-alarm__cmd > i { font-size: 18px; }
.moo-alarm__cmd:hover { background: rgba(0, 0, 0, 0.4); color: var(--alarm-text-primary); }
.moo-alarm__cmd:active { transform: translateY(1px); }

.moo-alarm__cmd--away.is-active {
  background: color-mix(in srgb, var(--alarm-c-armed-away) 22%, var(--alarm-glass-2));
  border-color: color-mix(in srgb, var(--alarm-c-armed-away) 55%, transparent);
  color: var(--alarm-c-armed-away);
}
.moo-alarm__cmd--away:hover { color: var(--alarm-c-armed-away); border-color: color-mix(in srgb, var(--alarm-c-armed-away) 35%, transparent); }

.moo-alarm__cmd--home.is-active {
  background: color-mix(in srgb, var(--alarm-c-armed-home) 22%, var(--alarm-glass-2));
  border-color: color-mix(in srgb, var(--alarm-c-armed-home) 55%, transparent);
  color: var(--alarm-c-armed-home);
}
.moo-alarm__cmd--home:hover { color: var(--alarm-c-armed-home); border-color: color-mix(in srgb, var(--alarm-c-armed-home) 35%, transparent); }

.moo-alarm__cmd--off.is-active {
  background: color-mix(in srgb, var(--alarm-c-disarmed) 22%, var(--alarm-glass-2));
  border-color: color-mix(in srgb, var(--alarm-c-disarmed) 55%, transparent);
  color: var(--alarm-c-disarmed);
}
.moo-alarm__cmd--off:hover { color: var(--alarm-c-disarmed); border-color: color-mix(in srgb, var(--alarm-c-disarmed) 35%, transparent); }

/* Disabled arm/disarm — engaged when the Pi agent is >10min silent (the same
   threshold that flips the agent-silent banner to red). Buttons stay visible
   so the user can see what's there, but interactivity is suppressed:
   pointer-events off, cursor not-allowed, no hover/active feedback, fade +
   subtle grayscale. `[disabled]` is the native HTML attr (already non-clickable
   for <button type="submit"> — the visual state is what we're adding here).
   `.is-disabled` mirrors it for the patcher path (JS toggles both). */
.moo-alarm__cmd[disabled],
.moo-alarm__cmd.is-disabled {
  cursor: not-allowed;
  pointer-events: none;
  opacity: 0.42;
  filter: saturate(0.5);
  transform: none;
}
/* Win-over the per-state .is-active highlight when disabled — a disabled
   armed_away button should still LOOK disabled, not solid red. */
.moo-alarm__cmd[disabled].is-active,
.moo-alarm__cmd.is-disabled.is-active {
  background: rgba(0, 0, 0, 0.25);
  border-color: rgba(255, 255, 255, 0.08);
  color: var(--alarm-text-muted);
}
.moo-alarm__cmd[disabled]:hover,
.moo-alarm__cmd.is-disabled:hover {
  background: rgba(0, 0, 0, 0.25);
  color: var(--alarm-text-secondary);
  border-color: rgba(255, 255, 255, 0.08);
}

/* ===== Dashboard: SOS hold-to-trigger bar — embedded in the hero card below
   the arm grid. Deliberately NOT a fourth tile in the 3-grid (muscle-memory
   adjacency risk): the one wide, red-outlined control on the card. The hold
   progress is the left-to-right fill sweep — transition-driven, duration set
   by JS via --moo-sos-hold so CSS and the JS timer can't drift apart. No glow,
   no pulse (brand: mint is atmosphere, red is reserved for genuine danger).
   touch-action:none overrides the global `pan-y` so a hold can't be stolen by
   a scroll; the fill layer clips via overflow+inherited radius. */
.moo-alarm__sos {
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  margin-top: 12px;
  padding: 11px 14px;
  min-height: 56px;
  border-radius: 12px;
  border: 1px solid color-mix(in srgb, var(--alarm-c-triggered) 38%, transparent);
  background: rgba(0, 0, 0, 0.25);
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  box-sizing: border-box;
  font-family: inherit;
  text-align: left;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
  transition: border-color 160ms ease, background-color 160ms ease;
}
.moo-alarm__sos[hidden] { display: none; }
.moo-alarm__sos-fill {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: color-mix(in srgb, var(--alarm-c-triggered) 30%, transparent);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 160ms ease;
  pointer-events: none;
}
.moo-alarm__sos.is-holding { border-color: color-mix(in srgb, var(--alarm-c-triggered) 70%, transparent); }
.moo-alarm__sos.is-holding .moo-alarm__sos-fill {
  transform: scaleX(1);
  /* Functional motion (progress feedback), intentionally NOT disabled under
     prefers-reduced-motion — without it a hold gives no progress signal. */
  transition: transform var(--moo-sos-hold, 5000ms) linear;
}
.moo-alarm__sos-icon {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  flex: 0 0 auto;
  border-radius: 10px;
  background: color-mix(in srgb, var(--alarm-c-triggered) 16%, transparent);
  color: var(--alarm-c-triggered);
  font-size: 15px;
}
.moo-alarm__sos-text {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}
.moo-alarm__sos-label {
  font: 700 13px/1 'Montserrat', sans-serif;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--alarm-c-triggered);
}
.moo-alarm__sos-sub {
  font: 500 12px/1.35 'Montserrat', sans-serif;
  color: var(--alarm-text-secondary);
}
.moo-alarm__sos.is-holding .moo-alarm__sos-sub { color: var(--alarm-text-primary); }
.moo-alarm__sos.is-sent {
  border-color: var(--alarm-c-triggered);
  background: color-mix(in srgb, var(--alarm-c-triggered) 22%, var(--alarm-glass-2));
}
.moo-alarm__sos.is-sent .moo-alarm__sos-sub { color: var(--alarm-text-primary); }
.moo-alarm__sos.is-error { border-color: color-mix(in srgb, var(--alarm-c-triggered) 70%, transparent); }
.moo-alarm__sos.is-error .moo-alarm__sos-sub { color: var(--alarm-c-triggered); }
.moo-alarm__sos[disabled],
.moo-alarm__sos.is-disabled {
  cursor: not-allowed;
  pointer-events: none;
  opacity: 0.42;
  filter: saturate(0.5);
}

.moo-alarm__heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin: 0 0 10px;
}
.moo-alarm__heading-title {
  font: 700 11px/1 'Montserrat', sans-serif;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: rgba(255, 255, 255, 0.45);
}
/* ===== Dashboard: Sensor grid ===== */
.moo-alarm__sensor-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 10px;
  margin-bottom: 20px;
}
.moo-alarm__sensor-card {
  position: relative;
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 16px;
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  transition: border-color 160ms ease, background-color 160ms ease;
  min-height: 124px;
}
.moo-alarm__sensor-card .moo-alarm__sensor-card-top { margin-bottom: 4px; }
.moo-alarm__sensor-card .moo-alarm__sensor-bottom { margin-top: auto; padding-top: 6px; }
/* Hover is a clickable affordance — only camera cards drill into Live View
   on click, so only camera cards get the hover-lift. Other sensor/keypad
   cards are display-only on the dashboard (admin via Devices page). */
.moo-alarm__sensor-card[data-type="camera"] { cursor: pointer; }
.moo-alarm__sensor-card[data-type="camera"]:hover { background: rgba(24, 32, 40, 0.92); }
/* F63: the camera tile is keyboard-focusable (role=button, tabindex=0); the
   global *:focus{outline:none} hides focus, so restore a visible ring matching
   the sibling .moo-alarm__history-row:focus-visible pattern. */
.moo-alarm__sensor-card[data-type="camera"]:focus-visible {
  outline: 2px solid var(--alarm-c-disarmed);
  outline-offset: -2px;
  background: rgba(24, 32, 40, 0.92);
}
.moo-alarm__sensor-card-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.moo-alarm__sensor-icon {
  width: 34px;
  height: 34px;
  border-radius: 9px;
  background: var(--alarm-glass-3);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--alarm-text-primary);
  font-size: 15px;
  border: 1px solid var(--alarm-border);
}
.moo-alarm__sensor-card[data-type="smoke"] .moo-alarm__sensor-icon {
  color: var(--alarm-c-armed-home);
  background: color-mix(in srgb, var(--alarm-c-armed-home) 10%, var(--alarm-glass-3));
}
.moo-alarm__sensor-card[data-type="entry"] .moo-alarm__sensor-icon {
  color: var(--alarm-c-arming);
  background: color-mix(in srgb, var(--alarm-c-arming) 10%, var(--alarm-glass-3));
}
.moo-alarm__sensor-card[data-type="motion"] .moo-alarm__sensor-icon {
  color: var(--alarm-c-disarmed);
  background: color-mix(in srgb, var(--alarm-c-disarmed) 10%, var(--alarm-glass-3));
}
.moo-alarm__sensor-card[data-type="keypad"] .moo-alarm__sensor-icon {
  color: var(--alarm-text-secondary);
}

.moo-alarm__online-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--alarm-c-online);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--alarm-c-online) 18%, transparent);
}
.moo-alarm__online-dot--warn {
  background: var(--alarm-c-online-warn);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--alarm-c-online-warn) 18%, transparent);
}
.moo-alarm__online-dot--off {
  background: var(--alarm-c-offline);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--alarm-c-offline) 18%, transparent);
}

.moo-alarm__sensor-name {
  font: 700 15px/1.25 'Montserrat', sans-serif;
  color: var(--alarm-text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.moo-alarm__sensor-loc {
  font: 500 12px/1.3 'Montserrat', sans-serif;
  color: rgba(255, 255, 255, 0.55);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Door open/closed chip on entry-sensor cards. Sits between location and
   the battery/last-seen bottom row. Two visual variants share the same
   pill geometry — only the colour tokens differ — so the chip reads as one
   semantic element with state, not two separate UI components.
   --open uses the alarming/amber tone (matches the rest of the status-row
   `--warn` palette) for "needs attention". --closed uses the green
   disarmed accent for "ok / at rest". */
.moo-alarm__sensor-door {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  align-self: flex-start;
  margin-top: 4px;
  padding: 4px 9px;
  border-radius: 8px;
  font: 600 11px/1 'Montserrat', sans-serif;
  letter-spacing: 0.02em;
  border: 1px solid transparent;
  background: var(--alarm-glass-2);
}
.moo-alarm__sensor-door > i { font-size: 11px; }
.moo-alarm__sensor-door--open {
  color: var(--alarm-c-arming);
  background: color-mix(in srgb, var(--alarm-c-arming) 14%, transparent);
  border-color: color-mix(in srgb, var(--alarm-c-arming) 38%, transparent);
}
.moo-alarm__sensor-door--closed {
  color: var(--alarm-c-disarmed);
  background: color-mix(in srgb, var(--alarm-c-disarmed) 10%, transparent);
  border-color: color-mix(in srgb, var(--alarm-c-disarmed) 28%, transparent);
}
.moo-alarm__sensor-door--hidden { display: none; }
.moo-alarm__sensor-bottom {
  margin-top: auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
  row-gap: 4px;
  min-width: 0;
  font: 500 11px/1 'Montserrat', sans-serif;
  color: var(--alarm-text-secondary);
  font-variant-numeric: tabular-nums;
}
.moo-alarm__sensor-battery {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--alarm-c-battery-ok);
}
.moo-alarm__sensor-battery--low     { color: var(--alarm-c-battery-low); }
.moo-alarm__sensor-battery--crit    { color: var(--alarm-c-battery-crit); }
.moo-alarm__sensor-battery--unknown { color: var(--alarm-text-muted); }

/* Battery + temperature live together on the LEFT of the sensor-bottom row, so
   the existing space-between layout still pushes the "last seen" timestamp to
   the RIGHT. Without this wrapper, adding a third child would scatter the
   middle item to the centre and break the cadence. Inline flex keeps both
   readings inline with the timestamp baseline. */
.moo-alarm__sensor-stats {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}
/* Ambient temperature reading. Muted by design — this is passive context, not
   a health signal. Battery already owns the colour-coded health channel; if
   temperature ever needs its own urgency tier (e.g. freeze warning), introduce
   a `--warn`/`--crit` modifier mirroring the battery variants. */
.moo-alarm__sensor-temp {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--alarm-text-muted);
}

/* Compact sensor-card warning indicator — surfaces fault / tamper between the
   device icon and the online dot. Colour-only, no background — mirrors the
   battery chip's restraint so the card stays quiet at rest. Amber = fault
   (maintenance grade); red = tamper (security grade). Reuses the battery
   colour scale rather than introducing new tokens. The fixed 18×18 keeps it
   from collapsing on the flex row when its sibling is the dot. */
.moo-alarm__sensor-warn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  font-size: 13px;
  line-height: 1;
  color: var(--alarm-c-battery-low);
  flex: 0 0 auto;
}
.moo-alarm__sensor-warn--crit { color: var(--alarm-c-battery-crit); }

/* Right-side group inside .moo-alarm__sensor-card-top — keeps the warning
   chip adjacent to the online dot. Without this wrapper, the parent's
   justify-content:space-between would scatter a third child to the centre. */
.moo-alarm__sensor-card-actions {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

/* ===== Dashboard: Events feed ===== */
.moo-alarm__events {
  display: flex;
  flex-direction: column;
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 16px;
  overflow: hidden;
}
.moo-alarm__event {
  display: grid;
  grid-template-columns: 60px 28px 1fr auto;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  border-top: 1px solid rgba(255, 255, 255, 0.05);
  font: 500 13px/1.3 'Montserrat', sans-serif;
  color: var(--alarm-text-primary);
  transition: background-color 120ms ease;
}
.moo-alarm__event:first-child { border-top: 0; }
.moo-alarm__event:hover { background: var(--alarm-glass-2); }
.moo-alarm__event-time {
  font: 700 11px/1 'Montserrat', sans-serif;
  font-variant-numeric: tabular-nums;
  color: rgba(255, 255, 255, 0.45);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.moo-alarm__event-icon {
  width: 24px;
  height: 24px;
  border-radius: 8px;
  background: var(--alarm-glass-3);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  color: var(--alarm-text-primary);
  flex-shrink: 0;
}
.moo-alarm__event--alarm_triggered .moo-alarm__event-icon,
.moo-alarm__event--test_fire .moo-alarm__event-icon {
  background: color-mix(in srgb, var(--alarm-c-triggered) 24%, transparent);
  color: var(--alarm-c-triggered);
}
.moo-alarm__event--low_battery .moo-alarm__event-icon {
  background: color-mix(in srgb, var(--alarm-c-arming) 22%, transparent);
  color: var(--alarm-c-arming);
}
.moo-alarm__event--sensor_offline .moo-alarm__event-icon {
  background: color-mix(in srgb, var(--alarm-c-offline) 22%, transparent);
  color: var(--alarm-c-offline);
}
.moo-alarm__event--state_change .moo-alarm__event-icon {
  background: color-mix(in srgb, var(--alarm-c-armed-away) 22%, transparent);
  color: var(--alarm-c-armed-away);
}
.moo-alarm__event-body {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.moo-alarm__event-summary {
  font: 600 13px/1.3 'Montserrat', sans-serif;
  color: var(--alarm-text-primary);
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
}
.moo-alarm__event-sub {
  font: 500 12px/1.3 'Montserrat', sans-serif;
  color: rgba(255, 255, 255, 0.55);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.moo-alarm__event-chips {
  display: flex;
  gap: 5px;
  flex-shrink: 0;
}
.moo-alarm__event-mini-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 7px;
  border-radius: 6px;
  background: var(--alarm-glass-2);
  font: 600 10px/1 'Montserrat', sans-serif;
  color: var(--alarm-text-secondary);
  letter-spacing: 0.03em;
  text-transform: uppercase;
}
.moo-alarm__event-new {
  animation: alarmSlideIn 360ms ease-out both;
}

/* ===== Sensors / Users / History list rows ===== */
.moo-alarm__list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.moo-alarm__list-card {
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 20px;
  padding: 16px 18px;
  display: flex;
  flex-direction: column;
  /* `gap: 0` is load-bearing for the grid-rows accordion: even when
     `.moo-alarm__list-card-expand` collapses to 0 height it's still a flex
     child (display:grid, not display:none), so any parent gap would leak as
     dead space below the button. The open-state inner picks up the spacing
     via margin-top + border-top + padding-top below. */
  gap: 0;
  transition: border-color 160ms ease, background-color 160ms ease;
}
.moo-alarm__list-card-top {
  /* button-element reset so the inner text isn't centered by user-agent default */
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  border: 0;
  margin: 0;
  padding: 0;
  color: inherit;
  font: inherit;
  text-align: left;
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  cursor: pointer;
  user-select: none;
}
.moo-alarm__list-card-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.moo-alarm__list-card-title {
  font: 700 15px/1.25 'Montserrat', sans-serif;
  color: var(--alarm-text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.moo-alarm__list-card-sub {
  font: 500 12px/1.3 'Montserrat', sans-serif;
  color: rgba(255, 255, 255, 0.55);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.moo-alarm__list-card-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
}
/* Accordion expand: animate grid-template-rows 0fr → 1fr for a real height
   transition without JS-measured pixel heights. Inner wrapper carries ALL
   open-state padding / margin / border so the collapsed state has ZERO
   spacing leaking — adding any padding to the base inner class would push
   the closed card taller (padding overflows past a 0fr-clipped content
   area). Visibility uses a discrete-step transition delayed by the height
   animation so children are pulled out of tab order once the collapse
   completes (a11y). */
.moo-alarm__list-card-expand {
  display: grid;
  grid-template-rows: 0fr;
  overflow: hidden;
  visibility: hidden;
  transition: grid-template-rows 240ms cubic-bezier(0.22, 0.61, 0.36, 1),
              visibility 0s linear 240ms;
}
.moo-alarm__list-card-expand-inner {
  /* Block layout (was flex column + gap). Spacing handled by the
     `> * + *` margin-top rule near the top of this file, which means a
     wrapping <div class="moo-alarm__field-block"> can group {label,
     control, hint} as one tight unit without inheriting a parent flex
     gap that double-counts with its children's own margin-top. */
  display: block;
  min-height: 0;
  overflow: hidden;
}
.moo-alarm__list-card.is-open .moo-alarm__list-card-expand {
  grid-template-rows: 1fr;
  visibility: visible;
  transition: grid-template-rows 240ms cubic-bezier(0.22, 0.61, 0.36, 1),
              visibility 0s linear 0s;
}
.moo-alarm__list-card.is-open .moo-alarm__list-card-expand-inner {
  /* margin-top compensates for the removed parent flex gap (parent
     has gap:0); total spacing between button + form content stays ≈
     pre-grid-rows. NO padding-bottom — it would survive into the
     collapsed state if ever moved out of `.is-open`. */
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid rgba(255, 255, 255, 0.07);
}
@media (prefers-reduced-motion: reduce) {
  .moo-alarm__list-card-expand { transition: none; }
}
.moo-alarm__list-card-chevron {
  font-size: 11px;
  color: var(--alarm-text-muted);
  transition: transform 200ms ease;
}
.moo-alarm__list-card.is-open .moo-alarm__list-card-chevron {
  transform: rotate(90deg);
}
/* Invisible chevron used on non-expandable cards (e.g. the Vocyl Alarm
   Agent base station) so the online dot stays in the same column as the
   dots on the expandable cards above. Visibility (not display:none) keeps
   the box in flow so the dot's position is unchanged. */
.moo-alarm__list-card-chevron--spacer { visibility: hidden; }

/* Role / status badges */
.moo-alarm__badge {
  display: inline-flex;
  padding: 3px 8px;
  border-radius: 6px;
  background: var(--alarm-glass-3);
  border: 1px solid var(--alarm-border);
  font: 700 10px/1 'Montserrat', sans-serif;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--alarm-text-secondary);
}
/* ===== Devices tab sections (Sensors / Cameras / Base Station) ===== */
body:has(.moo-tools) .moo-alarm__section {
  display: block;
  margin: 0 0 22px;
  background: none;
  border: none;
  border-radius: 0;
  padding: 0;
}
body:has(.moo-tools) .moo-alarm__section:last-of-type {
  margin-bottom: 0;
}
body:has(.moo-tools) .moo-alarm__section-header {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 12px;
  padding: 0;
}
body:has(.moo-tools) .moo-alarm__section-title {
  margin: 0;
  font: 700 11px/1 'Montserrat', sans-serif;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--alarm-text-secondary);
  flex-shrink: 0;
}
body:has(.moo-tools) .moo-alarm__section-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  height: 20px;
  padding: 0 7px;
  border-radius: 6px;
  background: var(--alarm-glass-2);
  border: 1px solid var(--alarm-border, rgba(255,255,255,0.08));
  font: 700 11px/1 'Montserrat', sans-serif;
  color: var(--alarm-text-secondary);
  flex-shrink: 0;
}
body:has(.moo-tools) .moo-alarm__section-rule {
  flex: 1;
  height: 1px;
  background: linear-gradient(
    to right,
    rgba(255,255,255,0.10),
    rgba(255,255,255,0.0)
  );
  margin-left: 4px;
}

/* Empty-state block inside a section */
body:has(.moo-tools) .moo-alarm__empty {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 18px 18px;
  background: rgba(14, 22, 28, 0.55);
  border: 1px dashed rgba(255,255,255,0.10);
  border-radius: 16px;
}
body:has(.moo-tools) .moo-alarm__empty-icon {
  font-size: 18px;
  color: var(--alarm-text-muted);
  flex-shrink: 0;
}
body:has(.moo-tools) .moo-alarm__empty-text {
  font: 500 12.5px/1.45 'Montserrat', sans-serif;
  color: var(--alarm-text-secondary);
}

/* "+ Add Camera" CTA card — sits at the bottom of the Cameras section.
   Looks like a list-card but with primary-action accent + dashed border. */
body:has(.moo-tools) .moo-alarm__add-card {
  appearance: none;
  -webkit-appearance: none;
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  margin: 10px 0 0;
  padding: 16px 18px;
  background: color-mix(in srgb, var(--alarm-c-disarmed) 6%, rgba(14, 22, 28, 0.55));
  border: 1px dashed color-mix(in srgb, var(--alarm-c-disarmed) 40%, transparent);
  border-radius: 20px;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background-color 160ms ease, border-color 160ms ease, transform 120ms ease;
}
body:has(.moo-tools) .moo-alarm__add-card:hover {
  background: color-mix(in srgb, var(--alarm-c-disarmed) 12%, rgba(14, 22, 28, 0.65));
  border-color: color-mix(in srgb, var(--alarm-c-disarmed) 60%, transparent);
}
body:has(.moo-tools) .moo-alarm__add-card:active {
  transform: translateY(1px);
}
body:has(.moo-tools) .moo-alarm__add-card-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: color-mix(in srgb, var(--alarm-c-disarmed) 18%, transparent);
  border: 1px solid color-mix(in srgb, var(--alarm-c-disarmed) 40%, transparent);
  color: var(--alarm-c-disarmed);
  font-size: 14px;
  flex-shrink: 0;
}
body:has(.moo-tools) .moo-alarm__add-card-label {
  display: flex;
  flex-direction: column;
  gap: 3px;
  flex: 1;
  min-width: 0;
}
body:has(.moo-tools) .moo-alarm__add-card-title {
  font: 700 14px/1.2 'Montserrat', sans-serif;
  color: var(--alarm-text-primary);
}
body:has(.moo-tools) .moo-alarm__add-card-sub {
  font: 500 11.5px/1.3 'Montserrat', sans-serif;
  color: var(--alarm-text-secondary);
}
body:has(.moo-tools) .moo-alarm__add-card-chevron {
  font-size: 11px;
  color: var(--alarm-text-muted);
  flex-shrink: 0;
}

body:has(.moo-tools) .moo-alarm__muted {
  color: var(--alarm-text-muted);
}

/* ===== Live View modal (Dashboard + Devices both summon it) ===== */
/* Full-screen on phones, centered on desktop. Sits at z-index above
   nav/modals — designed to be a focused single-purpose overlay. */
.moo-alarm__liveview-wrap {
  position: fixed;
  inset: 0;
  /* Above the existing moo-alarm__modal-wrap (9000) so Live View opened from
     a card-edit form sits over the Add/Delete modals if both are visible. */
  z-index: 9500;
  display: flex;
  align-items: stretch;
  justify-content: stretch;
  background: rgba(2, 6, 10, 0.94);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  animation: alarmLvFade 220ms ease-out;
}
.moo-alarm__liveview-wrap[hidden] { display: none !important; }
@keyframes alarmLvFade {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.moo-alarm__liveview {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  width: 100%;
  max-width: 100%;
  margin: 0;
  padding: env(safe-area-inset-top, 0) 0 env(safe-area-inset-bottom, 0);
  background: transparent;
}
@media (min-width: 720px) {
  .moo-alarm__liveview-wrap {
    align-items: center;
    justify-content: center;
    padding: 24px;
  }
  .moo-alarm__liveview {
    flex: 0 1 auto;
    width: min(960px, 92vw);
    max-height: calc(100vh - 48px);
    border-radius: 22px;
    overflow: hidden;
    /* iOS Safari leaks blur/box-shadow halos past border-radius on rounded
       containers — belt-and-braces clip via mask + clip-path so the video
       feed (and any child backdrop-filter / box-shadow) never bleeds past
       the rounded corners. */
    -webkit-mask-image: -webkit-radial-gradient(white, black);
    clip-path: inset(0 round 22px);
    background: linear-gradient(180deg, rgba(20, 28, 34, 0.96), rgba(10, 14, 18, 0.96));
    border: 1px solid rgba(255, 255, 255, 0.08);
    box-shadow: 0 30px 80px rgba(0, 0, 0, 0.6);
  }
  /* Give the stage a definite 16:9 height. On mobile it's `flex: 1` and fills
     the full-screen overlay; but in the desktop/tablet centered box the parent
     is content-sized (flex: 0 1 auto), so a `flex: 1` child has no free space to
     grow into and collapses to 0 height — that's why the feed was invisible on
     desktop until the window narrowed back to the full-screen layout. aspect-ratio
     derives a real height from the box width; the inherited min-height:0 lets it
     shrink so the controls stay visible on short windows. */
  .moo-alarm__liveview-stage {
    flex: 0 1 auto;
    width: 100%;
    aspect-ratio: 16 / 9;
  }
}

.moo-alarm__liveview-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 18px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  flex-shrink: 0;
}
.moo-alarm__liveview-title {
  display: flex;
  align-items: center;
  gap: 10px;
  font: 700 14px/1.2 'Montserrat', sans-serif;
  letter-spacing: 0.02em;
  color: var(--alarm-text-primary);
}
.moo-alarm__liveview-title > i {
  color: var(--alarm-c-armed-home);
  font-size: 13px;
}
.moo-alarm__liveview-close {
  appearance: none;
  -webkit-appearance: none;
  width: 36px;
  height: 36px;
  border: 1px solid rgba(255, 255, 255, 0.08);
  background: rgba(255, 255, 255, 0.04);
  border-radius: 12px;
  color: rgba(255, 255, 255, 0.55);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  padding: 0;
  transition: background 0.15s ease-out, border-color 0.15s ease-out, color 0.15s ease-out;
}
.moo-alarm__liveview-close:hover {
  /* ALM-061(c): the same block already uses var(--color-danger) for `color`;
     route the background/border literals (#f43f5e == rgb(244,63,94)) through
     the same token so a danger retune can't split the hover into two reds. */
  background: color-mix(in srgb, var(--color-danger) 12%, transparent);
  color: var(--color-danger);
  border-color: color-mix(in srgb, var(--color-danger) 30%, transparent);
}

/* Video stage — 16:9 aspect on mobile, fills available height on desktop */
.moo-alarm__liveview-stage {
  position: relative;
  flex: 1;
  min-height: 0;
  background: #000;
  overflow: hidden;
  /* Disable native browser gestures inside the stage so the JS gesture
     handler owns pinch/pan: without this iOS Safari does its own page-
     zoom on a two-finger pinch and Chrome would try to scroll. */
  touch-action: none;
}
.moo-alarm__liveview-stage.is-zoomed {
  /* Drag-to-pan affordance — only when actually zoomed in, since at 1x
     there's nowhere to pan to. */
  cursor: grab;
}
.moo-alarm__liveview-stage.is-zoomed.is-panning {
  cursor: grabbing;
}
.moo-alarm__liveview-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  transform-origin: center center;
  transition: transform 220ms cubic-bezier(0.22, 0.61, 0.36, 1);
  /* Hint the compositor to keep the video on its own GPU layer during
     zoom/pan so the transform updates don't trigger layout-paint cycles. */
  will-change: transform;
  /* CRITICAL: override the global `* { touch-action: pan-y }` rule
     (CLAUDE.md design rules) so iOS Safari doesn't intercept the
     pinch/pan gesture on the video itself. Without this the pinch
     would appear to "bounce back" on release because the browser was
     running its own (cancelled) pan logic in parallel with our JS
     gesture handler — when the user lifted, the browser's interpretation
     would briefly reset the visual state before our transform reasserted.
     `none` allows clicks (we don't actually use them here) but blocks
     all browser-managed touch gestures, leaving the stage's pointer-
     event listeners as the sole driver of pan/zoom. */
  touch-action: none;
}
/* During an active pinch / drag / wheel-burst the transform updates
   on every frame, so the 220ms ease would lag behind the finger. Kill
   the transition while `.is-panning` is set; the JS toggles it on
   pointerdown/wheel and removes it on pointerup or wheel-burst-end. */
.moo-alarm__liveview-stage.is-panning .moo-alarm__liveview-video {
  transition: none;
}
.moo-alarm__liveview-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 12px;
  color: var(--alarm-text-secondary);
  font: 600 13.5px/1.4 'Montserrat', sans-serif;
  pointer-events: none;
  background: rgba(0, 0, 0, 0.4);
}
.moo-alarm__liveview-overlay > i { font-size: 26px; color: var(--alarm-c-armed-home); }

/* "Tap for sound" badge — shown over the video while muted. Tapping it
   unmutes audio (works because the click counts as a user gesture, which
   browsers require to enable autoplay-with-sound). */
.moo-alarm__liveview-unmute-badge {
  position: absolute;
  bottom: 14px;
  left: 50%;
  transform: translateX(-50%);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px 16px;
  background: rgba(0, 0, 0, 0.72);
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 999px;
  color: #fff;
  font: 600 12.5px/1 'Montserrat', sans-serif;
  letter-spacing: 0.02em;
  cursor: pointer;
  z-index: 5;
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  transition: background-color 160ms ease, transform 160ms ease;
  animation: alarmLvBadgePop 360ms ease-out both;
}
.moo-alarm__liveview-unmute-badge:hover {
  background: rgba(0, 0, 0, 0.85);
}
.moo-alarm__liveview-unmute-badge:active {
  transform: translateX(-50%) scale(0.96);
}
.moo-alarm__liveview-unmute-badge > i { font-size: 12px; }
.moo-alarm__liveview-unmute-badge[hidden] { display: none; }
@keyframes alarmLvBadgePop {
  from { opacity: 0; transform: translate(-50%, 8px); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}

/* Controls — d-pad on left, side-stack (zoom/mute) on right */
.moo-alarm__liveview-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 28px;
  padding: 20px 18px calc(20px + env(safe-area-inset-bottom, 0));
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  flex-shrink: 0;
}

.moo-alarm__liveview-dpad {
  display: grid;
  grid-template-columns: 48px 48px 48px;
  grid-template-rows:    48px 48px 48px;
  grid-template-areas:
    ".    up   ."
    "left .    right"
    ".    down .";
  gap: 6px;
}
.moo-alarm__liveview-dpad-up    { grid-area: up; }
.moo-alarm__liveview-dpad-left  { grid-area: left; }
.moo-alarm__liveview-dpad-right { grid-area: right; }
.moo-alarm__liveview-dpad-down  { grid-area: down; }
.moo-alarm__liveview-dpad-center {
  grid-area: 2 / 2 / 3 / 3;
  width: 24px;
  height: 24px;
  align-self: center;
  justify-self: center;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.10);
}
.moo-alarm__liveview-dpad-btn {
  appearance: none;
  -webkit-appearance: none;
  width: 48px;
  height: 48px;
  border: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.04);
  position: relative;
  cursor: pointer;
  transition: background-color 100ms ease, transform 80ms ease, border-color 120ms ease;
  -webkit-tap-highlight-color: transparent;
}
.moo-alarm__liveview-dpad-btn:hover {
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.16);
}
.moo-alarm__liveview-dpad-btn:active {
  background: color-mix(in srgb, var(--alarm-c-armed-home) 16%, rgba(255, 255, 255, 0.08));
  border-color: color-mix(in srgb, var(--alarm-c-armed-home) 35%, transparent);
  transform: scale(0.96);
}
/* Triangle arrows drawn with ::before */
.moo-alarm__liveview-dpad-btn::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 0;
  height: 0;
  transform: translate(-50%, -50%);
  border-style: solid;
}
.moo-alarm__liveview-dpad-up::before {
  border-width: 0 8px 11px 8px;
  border-color: transparent transparent var(--alarm-text-primary) transparent;
}
.moo-alarm__liveview-dpad-down::before {
  border-width: 11px 8px 0 8px;
  border-color: var(--alarm-text-primary) transparent transparent transparent;
}
.moo-alarm__liveview-dpad-left::before {
  border-width: 8px 11px 8px 0;
  border-color: transparent var(--alarm-text-primary) transparent transparent;
}
.moo-alarm__liveview-dpad-right::before {
  border-width: 8px 0 8px 11px;
  border-color: transparent transparent transparent var(--alarm-text-primary);
}

.moo-alarm__liveview-side {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.moo-alarm__liveview-icon-btn {
  appearance: none;
  -webkit-appearance: none;
  width: 44px;
  height: 44px;
  border-radius: 11px;
  border: 1px solid rgba(255, 255, 255, 0.10);
  background: rgba(255, 255, 255, 0.04);
  color: var(--alarm-text-primary);
  font-size: 14px;
  cursor: pointer;
  transition: background-color 100ms ease, border-color 120ms ease, transform 80ms ease;
  -webkit-tap-highlight-color: transparent;
}
.moo-alarm__liveview-icon-btn:hover {
  background: rgba(255, 255, 255, 0.08);
}
.moo-alarm__liveview-icon-btn:active {
  transform: scale(0.95);
}
.moo-alarm__liveview-icon-btn--muted {
  color: var(--alarm-text-muted);
}
/* Confirmation flash for the Set Home button — tinted green + checkmark
   for ~1.2s after a successful tap. Uses the disarmed accent (same green
   the rest of the alarm UI uses for "ok / committed"). The icon swap is
   pure CSS (::before overlay) so the JS doesn't need to rewrite the
   <i> element on every flash. transition: color smooths the fade-out
   when the JS removes the class. */
.moo-alarm__liveview-icon-btn--success {
  color: var(--alarm-c-disarmed);
  background: color-mix(in srgb, var(--alarm-c-disarmed) 18%, rgba(255, 255, 255, 0.04));
  border-color: color-mix(in srgb, var(--alarm-c-disarmed) 45%, transparent);
  transition: background-color 200ms ease, border-color 200ms ease, color 200ms ease;
}
.moo-alarm__liveview-icon-btn--success > i {
  /* Swap the house icon to a checkmark via a CSS-only icon replacement.
     `display:none` the original FA glyph and project a check in its place
     using the same FA font + the FA check unicode (\f00c). Keeps the
     button geometry identical — no layout shift on the flash. */
  visibility: hidden;
  position: relative;
}
.moo-alarm__liveview-icon-btn--success > i::after {
  visibility: visible;
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  content: '\f00c'; /* fa-check */
  font-family: 'Font Awesome 6 Free';
  font-weight: 900;
  font-size: 14px;
}

/* Lock body scroll while Live View is open */
body.is-liveview-open {
  overflow: hidden;
}

/* Dashboard camera tile should look tappable */
body:has(.moo-tools) .moo-alarm__sensor-card[data-type="camera"] {
  cursor: pointer;
}
body:has(.moo-tools) .moo-alarm__sensor-card[data-type="camera"]:hover {
  border-color: color-mix(in srgb, var(--alarm-c-armed-home) 30%, transparent);
}

/* Error pill — bubbles up post-redirect cam_err parameter under the Add card. */
body:has(.moo-tools) .moo-alarm__error-pill {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 10px 0 0;
  padding: 12px 14px;
  background: color-mix(in srgb, var(--alarm-c-armed-away) 12%, rgba(14, 22, 28, 0.55));
  border: 1px solid color-mix(in srgb, var(--alarm-c-armed-away) 45%, transparent);
  border-radius: 12px;
  font: 600 12.5px/1.4 'Montserrat', sans-serif;
  color: var(--alarm-c-armed-away);
}
body:has(.moo-tools) .moo-alarm__error-pill > i {
  font-size: 14px;
  flex-shrink: 0;
}

/* Read-only field — visually echoes .moo-alarm__input but dimmed/muted to
   communicate "you can't change this here". Used for sensor Type. */
body:has(.moo-tools) .moo-alarm__readonly-field {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 41px;
  padding: 11px 16px;
  border-radius: 12px;
  background: rgba(0, 0, 0, 0.18);
  border: 1px solid rgba(255, 255, 255, 0.05);
  font: 500 15px/1.2 'Montserrat', sans-serif;
  color: var(--alarm-text-secondary);
  letter-spacing: 0.01em;
  box-sizing: border-box;
}
/* Consolidated Status row: Health + Tamper + Temperature inline */
body:has(.moo-tools) .moo-alarm__status-row {
  flex-wrap: wrap;
  height: auto;
  min-height: 41px;
  padding: 9px 16px;
  row-gap: 6px;
  column-gap: 10px;
  line-height: 1.3;
}
body:has(.moo-tools) .moo-alarm__status-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--alarm-text-secondary);
}
body:has(.moo-tools) .moo-alarm__status-item--ok   { color: var(--alarm-c-battery-ok); }
body:has(.moo-tools) .moo-alarm__status-item--warn { color: var(--alarm-c-battery-low); }
body:has(.moo-tools) .moo-alarm__status-item--crit { color: var(--alarm-c-battery-crit); }
body:has(.moo-tools) .moo-alarm__status-sep {
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.22);
  flex-shrink: 0;
}
body:has(.moo-tools) .moo-alarm__badge--connecting {
  color: var(--alarm-c-arming);
  background: color-mix(in srgb, var(--alarm-c-arming) 14%, transparent);
  border-color: color-mix(in srgb, var(--alarm-c-arming) 35%, transparent);
  animation: alarmConnectingPulse 2s ease-in-out infinite;
}
@keyframes alarmConnectingPulse {
  0%, 100% { opacity: 0.78; }
  50%      { opacity: 1.0; }
}

/* Base-station card uses a faint tint to differentiate from sensors */
body:has(.moo-tools) .moo-alarm__list-card--basestation {
  background: linear-gradient(
    180deg,
    rgba(14, 22, 28, 0.92),
    color-mix(in srgb, var(--alarm-c-disarmed) 3%, rgba(14, 22, 28, 0.92))
  );
}

/* Non-expandable cards (base station). No hover cursor, no chevron, no toggle. */
body:has(.moo-tools) .moo-alarm__list-card--static {
  cursor: default;
}
body:has(.moo-tools) .moo-alarm__list-card-top--static {
  cursor: default;
  user-select: text;
}

/* Nested PIN sub-list inside a user card */
.moo-alarm__pin-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 12px 14px;
  background: rgba(24, 32, 40, 0.92);
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.07);
}
.moo-alarm__pin-info {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.moo-alarm__pin-mask {
  font: 800 18px/1 'Montserrat', sans-serif;
  color: var(--alarm-text-secondary);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.18em;
}
.moo-alarm__pin-label {
  font: 500 12px/1.3 'Montserrat', sans-serif;
  color: rgba(255, 255, 255, 0.55);
}

/* ===== Evidence Clip — inline pill on history-feed rows =====
   Glass-morphism red pill with a pulsing REC dot. Lives in the existing
   event-chips grid cell so the row layout doesn't shift. Triggers the
   evidence playback modal via the event-delegation listener installed
   below in alarm.php. */
.moo-alarm__event-clip-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px 5px 8px;
  border-radius: 8px;
  background: linear-gradient(135deg,
      color-mix(in srgb, var(--alarm-c-triggered) 18%, transparent),
      color-mix(in srgb, var(--alarm-c-triggered)  9%, transparent));
  border: 1px solid color-mix(in srgb, var(--alarm-c-triggered) 40%, transparent);
  color: var(--alarm-c-triggered);
  font: 700 10px/1 'Montserrat', sans-serif;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  font-family: inherit;
  white-space: nowrap;
  transition: transform 120ms ease, background-color 160ms ease, border-color 160ms ease, box-shadow 160ms ease;
}
.moo-alarm__event-clip-btn:hover {
  transform: translateY(-1px);
  background: linear-gradient(135deg,
      color-mix(in srgb, var(--alarm-c-triggered) 28%, transparent),
      color-mix(in srgb, var(--alarm-c-triggered) 16%, transparent));
  border-color: color-mix(in srgb, var(--alarm-c-triggered) 60%, transparent);
  box-shadow: 0 4px 14px color-mix(in srgb, var(--alarm-c-triggered) 25%, transparent);
}
.moo-alarm__event-clip-btn:active { transform: translateY(0); }
.moo-alarm__event-clip-btn > i { font-size: 9px; }
.moo-alarm__event-clip-btn-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--alarm-c-triggered);
  box-shadow: 0 0 8px color-mix(in srgb, var(--alarm-c-triggered) 80%, transparent);
  animation: alarm-evid-dot-pulse 1.4s ease-in-out infinite;
  flex-shrink: 0;
}
@keyframes alarm-evid-dot-pulse {
  0%, 100% { opacity: 1;   transform: scale(1); }
  50%      { opacity: 0.45; transform: scale(0.85); }
}

@media (prefers-reduced-motion: reduce) {
  .moo-alarm__event-clip-btn-dot { animation: none; }
}

/* ===== History tab: filter bar + pager =====
   Filter chips are a flex-wrap row of rounded-rect pills (12px radius —
   matches the rest of the alarm "control" radius — NOT pure pills, per
   the Vello design language). Inactive chips read as muted ghost
   surfaces; the active chip flips to the green disarmed accent so the
   current state is unambiguous at a glance. */
.moo-alarm__filter-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 0 16px;
}
/* Each chip on a row is EQUAL width — not proportional to content.
   `flex: 1 1 0` (basis 0) means every chip starts at 0 width and grows
   equally to share the row's free space, so two chips with different
   content widths end up the same final size. The lone-chip-on-row-2
   case stretches to 100% since it has no row-mates to share with.
   4 on row → 25% each; 3+1 → 33% × 3 then 100%; 2+2 → 50% each.
   `min-width: min-content` keeps the chip from shrinking below its
   intrinsic content width (so text + count badge never clip): when
   the row can't fit all chips at min-content + gaps, one wraps to
   the next row instead. */
.moo-alarm__filter-bar > .moo-alarm__filter-chip {
  flex: 1 1 0;
  min-width: min-content;
  justify-content: center;
}
.moo-alarm__filter-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px 14px;
  border-radius: 12px;
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.08);
  font: 600 12.5px/1 'Montserrat', sans-serif;
  letter-spacing: 0.02em;
  color: var(--alarm-text-secondary);
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 160ms ease, border-color 160ms ease, color 160ms ease;
}
.moo-alarm__filter-chip:hover {
  background: rgba(24, 32, 40, 0.92);
  border-color: rgba(255, 255, 255, 0.14);
  color: var(--alarm-text-primary);
}
.moo-alarm__filter-chip > i {
  font-size: 11px;
  opacity: 0.85;
}
.moo-alarm__filter-chip-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  height: 18px;
  padding: 0 6px;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.06);
  font: 700 10.5px/1 'Montserrat', sans-serif;
  color: var(--alarm-text-muted);
  font-variant-numeric: tabular-nums;
}
.moo-alarm__filter-chip.is-active {
  background: color-mix(in srgb, var(--alarm-c-disarmed) 14%, rgba(14, 22, 28, 0.92));
  border-color: color-mix(in srgb, var(--alarm-c-disarmed) 50%, transparent);
  color: var(--alarm-c-disarmed);
}
.moo-alarm__filter-chip.is-active > i {
  opacity: 1;
}
.moo-alarm__filter-chip.is-active .moo-alarm__filter-chip-count {
  background: color-mix(in srgb, var(--alarm-c-disarmed) 22%, transparent);
  color: var(--alarm-c-disarmed);
}

/* Pager cluster: prev/next chevron buttons flanking a centered row of
   numbered page pills. Disabled arrows stay in place (dimmed) so the
   cluster doesn't shift horizontally between first / middle / last page.
   Summary line ("Page X of Y · N events") sits below as a muted caption. */
.moo-alarm__pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  margin: 22px 0 8px;
  /* MUST stay on a single line — combined with the tightened page-set
     logic (ellipsis kicks in at 8+ pages, max ~6 pills + 2 ellipses)
     and the no-shrink pills below, the cluster fits a 320px viewport. */
  flex-wrap: nowrap;
}
.moo-alarm__pager-arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 10px;
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.08);
  color: var(--alarm-text-secondary);
  font-size: 11px;
  text-decoration: none;
  cursor: pointer;
  flex-shrink: 0;
  transition: background-color 160ms ease, border-color 160ms ease, color 160ms ease;
}
.moo-alarm__pager-arrow:hover {
  background: rgba(24, 32, 40, 0.92);
  border-color: rgba(255, 255, 255, 0.14);
  color: var(--alarm-text-primary);
}
.moo-alarm__pager-arrow.is-disabled {
  opacity: 0.32;
  cursor: not-allowed;
  pointer-events: none;
}
.moo-alarm__pager-pages {
  display: flex;
  align-items: center;
  gap: 3px;
  /* Constrain to its own intrinsic size so the surrounding arrows stay
     pinned to the cluster's edges and the pills shrink-share remaining
     space if needed. min-width:0 lets flex-shrink work on overflow. */
  min-width: 0;
  flex-shrink: 1;
}
.moo-alarm__pager-page {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 30px;
  height: 30px;
  padding: 0 6px;
  border-radius: 8px;
  background: transparent;
  border: 1px solid transparent;
  font: 600 12.5px/1 'Montserrat', sans-serif;
  font-variant-numeric: tabular-nums;
  color: var(--alarm-text-secondary);
  text-decoration: none;
  cursor: pointer;
  flex-shrink: 0;
  transition: background-color 160ms ease, border-color 160ms ease, color 160ms ease;
}
.moo-alarm__pager-page:hover {
  background: rgba(24, 32, 40, 0.92);
  color: var(--alarm-text-primary);
}
.moo-alarm__pager-page.is-active {
  background: color-mix(in srgb, var(--alarm-c-disarmed) 16%, transparent);
  border-color: color-mix(in srgb, var(--alarm-c-disarmed) 50%, transparent);
  color: var(--alarm-c-disarmed);
  cursor: default;
}
.moo-alarm__pager-ellipsis {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 30px;
  color: var(--alarm-text-muted);
  font: 700 13px/1 'Montserrat', sans-serif;
  letter-spacing: 0.04em;
  user-select: none;
  flex-shrink: 0;
}
.moo-alarm__pager-summary {
  text-align: center;
  margin: 0 0 8px;
  font: 600 12px/1.3 'Montserrat', sans-serif;
  font-variant-numeric: tabular-nums;
  color: var(--alarm-text-muted);
}
.moo-alarm__pager-summary--alone {
  margin: 18px 0 0;
}

/* Narrow-viewport pager: hide the non-active page pills + ellipses so the
   cluster fits on a single line even at 320px. The active pill stays as a
   "current page" badge between the prev/next arrows, and the summary line
   below ("Page X of Y · N events") gives the full context. Loses jump-
   to-page on mobile — acceptable trade-off for not overflowing the
   viewport edge (which was the previous behaviour at ≤ 360px). */
@media (max-width: 479px) {
  .moo-alarm__pager-pages > .moo-alarm__pager-page:not(.is-active),
  .moo-alarm__pager-pages > .moo-alarm__pager-ellipsis {
    display: none;
  }
}
.moo-alarm__history-row {
  display: grid;
  grid-template-columns: 88px 32px 1fr auto 16px;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  border-top: 1px solid rgba(255, 255, 255, 0.05);
  cursor: pointer;
  transition: background-color 120ms ease;
}
.moo-alarm__history-row:first-of-type { border-top: 0; }
.moo-alarm__history-row:hover { background: rgba(24, 32, 40, 0.92); }
.moo-alarm__history-row:focus-visible {
  outline: 2px solid var(--alarm-c-disarmed);
  outline-offset: -2px;
  background: rgba(24, 32, 40, 0.92);
}
.moo-alarm__history-row-chevron {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  color: var(--alarm-text-muted);
  transition: transform 200ms ease;
}
.moo-alarm__history-row.is-open .moo-alarm__history-row-chevron {
  transform: rotate(90deg);
}
.moo-alarm__history-row-payload {
  display: none;
  padding: 14px 16px;
  font: 500 11px/1.5 ui-monospace, 'SFMono-Regular', Menlo, monospace;
  color: var(--alarm-text-secondary);
  background: var(--alarm-glass-1);
  white-space: pre-wrap;
  word-break: break-all;
}
.moo-alarm__history-row.is-open + .moo-alarm__history-row-payload {
  display: block;
}

/* ===== Modal pattern =====
   Overlay uses position:absolute (NOT fixed) so it tracks viewport.js's
   html/body resize when the iOS keyboard opens — every form modal here has a
   text input. Each wrap is relocated to <body> on load (see each page's footer
   script) so it sizes against the keyboard-aware body box.
   The modal itself is a three-zone column — fixed header, scrollable body,
   pinned footer — so the title + actions stay put while the content scrolls
   when it outgrows the viewport. All five alarm modals share this skeleton. */
.moo-alarm__modal-wrap {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.62);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  z-index: 9000;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 16px;
}
.moo-alarm__modal-wrap.is-open {
  display: flex;
  animation: mooOverlayIn 0.2s ease-out;
}
/* Body-scroll lock while any alarm modal is open. Stops the page behind the
   backdrop from scrolling on iOS (would otherwise scroll-shift the entire
   viewport during keyboard interactions inside the modal). Released only when
   no .moo-alarm__modal-wrap.is-open remains — handled in the page-level JS. */
body.moo-alarm-modal-open { overflow: hidden; }
/* Alarm header nav row — replaces the previous inline gap:6px. Scopes the gap
   to this nav so other tools' .hbbm_cont uses (currently none) aren't affected. */
.moo-alarm__nav { gap: 6px; }
/* Modal title's auxiliary text ("for Erin", etc.) — used to be inline-styled. */
body:has(.moo-tools) .moo-alarm__modal-title-aux {
  font-weight: 400;
  opacity: 0.7;
}
/* Form spacing helpers — replace inline style="margin-top:N" calls. */
body:has(.moo-tools) .moo-alarm__form--gap-top { margin-top: 14px; }
body:has(.moo-tools) .moo-alarm__input--stacked { margin-top: 8px; }
.moo-alarm__modal {
  position: relative;
  width: min(420px, 100%);
  max-height: 100%;
  background: rgba(18, 22, 26, 0.96);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 24px;
  box-shadow: 0 14px 44px rgba(0,0,0,0.55), 0 1px 0 rgba(255,255,255,0.06) inset;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  animation: alarmModalIn 0.26s cubic-bezier(0.4, 0, 0.2, 1);
}
/* Header — fixed at the top */
.moo-alarm__modal-title {
  flex-shrink: 0;
  padding: 22px 24px 0;
  font: 800 18px/1.25 'Montserrat', sans-serif;
  color: var(--alarm-text-primary);
  letter-spacing: -0.01em;
}
.moo-alarm__modal-desc {
  flex-shrink: 0;
  padding: 7px 24px 0;
  font: 500 13px/1.5 'Montserrat', sans-serif;
  color: var(--alarm-text-secondary);
}
/* Body — the only zone that scrolls once the modal hits max-height */
.moo-alarm__modal-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: 18px 24px;
  scrollbar-width: none;
}
.moo-alarm__modal-body::-webkit-scrollbar { display: none; }
/* Footer — pinned at the bottom, always reachable above the keyboard */
.moo-alarm__modal-actions {
  flex-shrink: 0;
  display: flex;
  gap: 10px;
  justify-content: flex-end;
  padding: 18px 24px 22px;
}
/* When a scrollable body sits above the footer, add a hairline + opaque backing
   so content reads as sliding beneath the pinned actions. Confirm-only modals
   (title + desc + actions, no body) intentionally skip it. */
.moo-alarm__modal-body + .moo-alarm__modal-actions {
  border-top: 1px solid rgba(255, 255, 255, 0.07);
  background: rgba(18, 22, 26, 0.96);
}
@keyframes alarmModalIn {
  from { opacity: 0; transform: translateY(10px) scale(0.985); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .moo-alarm__modal-wrap.is-open,
  .moo-alarm__modal { animation: none; }
}

/* Big PIN entry input */
.moo-alarm__pin-input {
  display: block;
  width: 100%;
  box-sizing: border-box;
  text-align: center;
  font: 800 30px/1 'Montserrat', sans-serif;
  letter-spacing: 0.36em;
  padding: 16px 16px 16px 28px;
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: 12px;
  color: var(--alarm-text-primary);
  font-variant-numeric: tabular-nums;
  caret-color: var(--alarm-c-disarmed);
  appearance: none;
  -webkit-appearance: none;
}
.moo-alarm__pin-input:focus {
  outline: none;
  border-color: var(--alarm-c-disarmed);
  background: rgba(24, 32, 40, 0.92);
}

/* ===== Empty / placeholder ===== */
.moo-alarm__placeholder {
  text-align: center;
  padding: 40px 24px;
  color: var(--alarm-text-secondary);
  background: rgba(14, 22, 28, 0.92);
  border: 1px dashed rgba(255, 255, 255, 0.10);
  border-radius: 16px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  font: 600 13px/1.4 'Montserrat', sans-serif;
}
.moo-alarm__placeholder > i {
  font-size: 28px;
  color: var(--alarm-text-secondary);
}
.moo-alarm__placeholder p { margin: 0; }

/* ===== Animations ===== */
@keyframes alarmPulseSoft {
  0%, 100% { box-shadow: 0 14px 44px rgba(0,0,0,0.55), 0 1px 0 rgba(255,255,255,0.06) inset, 0 0 0 0px transparent; }
  50%      { box-shadow: 0 14px 44px rgba(0,0,0,0.55), 0 1px 0 rgba(255,255,255,0.06) inset, 0 0 24px var(--_alarm-hero-glow, transparent); }
}
@keyframes alarmFlash {
  0%   { opacity: 1;    }
  100% { opacity: 0.55; }
}
@keyframes alarmSlideIn {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ===== Mobile tweaks ===== */
@media (max-width: 480px) {
  .moo-alarm__hero { padding: 22px 18px; min-height: 140px; }
  .moo-alarm__hero-state { font-size: 36px; letter-spacing: 0.03em; }
  .moo-alarm__hero-countdown { font-size: 32px; }
  .moo-alarm__hero-detail { font-size: 14px; }
  .moo-alarm__sensor-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* Keep the chips column (auto) on mobile so the View Clip pill stays
     visible in History — same inline treatment as the dashboard's Recent
     Activity rows. Previously the whole chips cell was display:none here,
     which hid the pill on phones (the primary platform) and is why clips
     appeared in Recent Activity but not History. The summary already
     ellipsises (white-space:nowrap), so the narrower body cell is fine. */
  .moo-alarm__history-row { grid-template-columns: 70px 28px 1fr auto 16px; }
  /* Drop only the secondary sensor mini-chip on mobile — the row summary
     already names the sensor inline, so it's redundant; the actionable
     View Clip pill is kept. When a row has no clip the auto column
     collapses to 0, so non-clip rows are visually unchanged. */
  .moo-alarm__history-row .moo-alarm__event-mini-chip { display: none; }
}

/* Honour reduce-motion */
@media (prefers-reduced-motion: reduce) {
  .moo-alarm__hero--triggered,
  .moo-alarm__hero--pending,
  .moo-alarm__hero--arming_away,
  .moo-alarm__hero--arming_home {
    animation: none;
  }
  .moo-alarm__event-new { animation: none; }
}

/* ============================================================
   Time Tracker Tool (.moo-tt-*)
   ============================================================ */
.moo-tt-page { padding-bottom: 40px; }

/* Week navigation */
.moo-tt-weeknav {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 4px 0 18px;
}
.moo-tt-weeknav__btn {
  width: 40px;
  height: 40px;
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 12px;
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.08);
  color: var(--color-text-primary);
  text-decoration: none;
  transition: background-color 0.2s, border-color 0.2s;
}
.moo-tt-weeknav__btn:hover { border-color: rgba(255, 255, 255, 0.18); }
.moo-tt-weeknav__btn:active { background: rgba(24, 32, 40, 0.92); }
.moo-tt-weeknav__center { flex: 1 1 auto; text-align: center; min-width: 0; }
.moo-tt-weeknav__title {
  font-size: 17px;
  font-weight: 700;
  color: var(--color-text-primary);
  line-height: 1.2;
}
.moo-tt-weeknav__range {
  font-size: 12px;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.45);
  font-variant-numeric: tabular-nums;
  margin-top: 3px;
}

/* Week summary hero */
.moo-tt-sum {
  position: relative;
  overflow: hidden;
  border-radius: 20px;
  padding: 26px 24px 22px;
  text-align: center;
  margin-bottom: 22px;
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.08);
}
.moo-tt-sum--over {
  background: linear-gradient(135deg, rgba(0, 229, 160, 0.10), transparent 55%), rgba(14, 22, 28, 0.92);
  border-color: rgba(0, 229, 160, 0.18);
}
.moo-tt-sum__eyebrow {
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.8px;
  color: rgba(255, 255, 255, 0.4);
  margin-bottom: 10px;
}
.moo-tt-sum__headline {
  font-size: 42px;
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.5px;
  font-variant-numeric: tabular-nums;
  color: var(--color-text-primary);
}
.moo-tt-sum--over .moo-tt-sum__headline { color: var(--color-accent); }
.moo-tt-sum__headline--empty { font-size: 23px; font-weight: 700; letter-spacing: 0; }
.moo-tt-sum__money {
  font-size: 15px;
  font-weight: 600;
  margin-top: 9px;
  color: rgba(255, 255, 255, 0.6);
  font-variant-numeric: tabular-nums;
}
.moo-tt-sum--over .moo-tt-sum__money { color: var(--color-accent); }
.moo-tt-sum__sub { font-size: 14px; color: rgba(255, 255, 255, 0.5); margin-top: 8px; }

/* Contract-line meter (signature element) */
.moo-tt-meter {
  position: relative;
  height: 8px;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.08);
  margin: 18px 2px 16px;
  overflow: hidden;
}
.moo-tt-meter__fill {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  background: rgba(255, 255, 255, 0.28);
  border-radius: 6px;
}
.moo-tt-meter__over {
  position: absolute;
  top: 0;
  bottom: 0;
  background: var(--color-accent);
  border-radius: 0 6px 6px 0;
}
.moo-tt-meter__tick {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 2px;
  background: rgba(255, 255, 255, 0.55);
}

/* Summary breakdown rows */
.moo-tt-sum__breakdown { margin-top: 2px; }
.moo-tt-sum-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 9px 0;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  font-size: 13px;
}
.moo-tt-sum-row__label { color: rgba(255, 255, 255, 0.55); font-weight: 500; }
.moo-tt-sum-row__value {
  color: var(--color-text-primary);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* Day rows */
.moo-tt-days { display: flex; flex-direction: column; gap: 8px; }
.moo-tt-day {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  box-sizing: border-box;
  text-align: left;
  margin: 0;
  padding: 14px 16px;
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 14px;
  color: var(--color-text-primary);
  font-family: 'Montserrat', sans-serif;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  transition: background-color 0.2s, border-color 0.2s, transform 0.15s;
}
.moo-tt-day:hover { border-color: rgba(255, 255, 255, 0.16); }
.moo-tt-day:active { background: rgba(24, 32, 40, 0.92); transform: scale(0.99); }
.moo-tt-day--empty {
  background: rgba(12, 18, 23, 0.55);
  border-style: dashed;
  border-color: rgba(255, 255, 255, 0.1);
}
.moo-tt-day--today { border-color: rgba(0, 229, 160, 0.3); }
.moo-tt-day__head { flex: 0 0 52px; }
.moo-tt-day__dow { font-size: 14px; font-weight: 700; white-space: nowrap; }
.moo-tt-day--today .moo-tt-day__dow { color: var(--color-accent); }
.moo-tt-day__date {
  font-size: 11px;
  color: rgba(255, 255, 255, 0.42);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  margin-top: 1px;
}
.moo-tt-day__mid { flex: 1 1 auto; min-width: 0; }
.moo-tt-day__shift {
  display: flex;
  align-items: center;
  gap: 7px;
  flex-wrap: wrap;
  font-size: 15px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.moo-tt-day__shift i { font-size: 11px; color: rgba(255, 255, 255, 0.35); }
.moo-tt-day__next {
  font-size: 10px;
  font-weight: 700;
  line-height: 1;
  padding: 3px 6px;
  border-radius: 6px;
  background: rgba(0, 229, 160, 0.12);
  color: var(--color-accent);
}
.moo-tt-day__chips { display: flex; gap: 6px; margin-top: 6px; flex-wrap: wrap; }
.moo-tt-chip {
  font-size: 11px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  padding: 3px 8px;
  border-radius: 7px;
  background: rgba(255, 255, 255, 0.06);
  color: rgba(255, 255, 255, 0.6);
}
.moo-tt-chip--break { color: rgba(255, 255, 255, 0.42); }
.moo-tt-day__net { flex: 0 0 auto; text-align: right; }
.moo-tt-day__net-val { font-size: 18px; font-weight: 800; font-variant-numeric: tabular-nums; }
.moo-tt-day__net-lbl {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: rgba(255, 255, 255, 0.38);
  margin-top: 1px;
}
.moo-tt-day__add {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.5);
}
.moo-tt-day__add i { font-size: 12px; color: var(--color-accent); }

/* Entry + settings modals (overlay + centered; absolute because they hold inputs) */
#tt_entry_wrap, #tt_settings_wrap {
  position: absolute;
  inset: 0;
  background: rgba(6, 13, 16, 0.6);
  z-index: 9998;
  animation: mooOverlayIn 0.25s ease;
}
#tt_entry_modal, #tt_settings_modal {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: none;
  flex-direction: column;
  width: min(400px, calc(100% - 40px));
  max-height: calc(100vh - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px) - 40px);
  max-height: calc(100dvh - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px) - 40px);
  overflow-y: auto;
  overscroll-behavior: contain;
  background: rgba(20, 30, 38, 0.96);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 24px;
  z-index: 9999;
  color: var(--color-text-primary);
  animation: mooModalIn 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

#tt_entry_modal .moo-da-modal__icon,
#tt_settings_modal .moo-da-modal__icon {
  background: rgba(0, 229, 160, 0.1);
  border-color: rgba(0, 229, 160, 0.18);
  color: var(--color-accent);
}

#tt_entry_modal form, #tt_settings_modal form { margin: 0; }

/* Entry modal fields */
.moo-tt-entry-date {
  font-size: 13px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.55);
  text-align: center;
  margin-bottom: 16px;
}
.moo-tt-times { display: flex; gap: 12px; }
.moo-tt-field { flex: 1; display: flex; flex-direction: column; gap: 7px; }
.moo-tt-field__lbl {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.8px;
  color: rgba(255, 255, 255, 0.4);
}
.moo-tt-field input[type="time"] {
  width: 100%;
  box-sizing: border-box;
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  color: var(--color-text-primary);
  padding: 12px 14px;
  font-size: 16px;
  font-weight: 600;
  font-family: 'Montserrat', sans-serif;
  font-variant-numeric: tabular-nums;
  -webkit-appearance: none;
  appearance: none;
  transition: border-color 0.25s;
}
.moo-tt-field input[type="time"]:focus { border-color: rgba(0, 229, 160, 0.45); outline: none; }

/* Live preview */
.moo-tt-preview {
  margin-top: 16px;
  padding: 14px 16px;
  background: rgba(0, 229, 160, 0.05);
  border: 1px solid rgba(0, 229, 160, 0.12);
  border-radius: 12px;
}
.moo-tt-preview__empty { font-size: 13px; line-height: 1.4; color: rgba(255, 255, 255, 0.45); }
.moo-tt-preview__row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 3px 0;
  font-size: 14px;
  color: rgba(255, 255, 255, 0.6);
}
.moo-tt-preview__row strong {
  color: var(--color-text-primary);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.moo-tt-preview__row--net {
  margin-top: 4px;
  padding-top: 8px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}
.moo-tt-preview__row--net span { color: rgba(255, 255, 255, 0.8); font-weight: 600; }
.moo-tt-preview__row--net strong { color: var(--color-accent); font-size: 16px; }
.moo-tt-preview__note {
  margin-top: 8px;
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: rgba(0, 229, 160, 0.85);
}

/* Settings modal rows */
.moo-tt-set { display: flex; flex-direction: column; }
.moo-tt-set__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 13px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
.moo-tt-set__row:last-child { border-bottom: none; }
.moo-tt-set__lbl {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: 14px;
  font-weight: 600;
  color: var(--color-text-primary);
}
.moo-tt-set__hint { font-size: 11px; font-weight: 500; color: rgba(255, 255, 255, 0.4); }
/* Fixed-width control so every input box lines up in one vertical column. */
.moo-tt-set__control { position: relative; flex: 0 0 112px; width: 112px; }
.moo-tt-set__control input[type="number"] {
  width: 100%;
  box-sizing: border-box;
  text-align: right;
  background: rgba(14, 22, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 10px;
  color: var(--color-text-primary);
  padding: 10px 48px 10px 14px; /* right room for the unit suffix + clear gap */
  font-size: 15px;
  font-weight: 600;
  font-family: 'Montserrat', sans-serif;
  font-variant-numeric: tabular-nums;
  -webkit-appearance: none;
  -moz-appearance: textfield;
  appearance: none;
}
.moo-tt-set__control--money input[type="number"] { padding: 10px 14px 10px 28px; } /* left room for the £ */
.moo-tt-set__control input[type="number"]:focus { border-color: rgba(0, 229, 160, 0.45); outline: none; }
.moo-tt-set__unit {
  position: absolute;
  right: 14px;
  top: 50%;
  transform: translateY(-50%);
  pointer-events: none;
  font-size: 13px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.45);
}
.moo-tt-set__pre {
  position: absolute;
  left: 14px;
  top: 50%;
  transform: translateY(-50%);
  pointer-events: none;
  font-size: 13px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.45);
}
.moo-tt-set__static {
  font-size: 14px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.55);
}

/* Modal action buttons */
.moo-tt-save {
  flex: 1;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 14px 20px;
  border-radius: 12px;
  background: linear-gradient(135deg, var(--color-accent), var(--color-accent-dark));
  border: none;
  color: var(--color-bg);
  font-size: 14px;
  font-weight: 700;
  font-family: 'Montserrat', sans-serif;
  cursor: pointer;
  transition: box-shadow 0.2s, opacity 0.2s;
}
.moo-tt-save:hover { box-shadow: 0 8px 24px rgba(0, 229, 160, 0.25); }
.moo-tt-save:disabled { opacity: 0.6; cursor: not-allowed; box-shadow: none; }
.moo-tt-del {
  width: 100%;
  box-sizing: border-box;
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 13px 20px;
  border-radius: 12px;
  background: rgba(244, 63, 94, 0.12);
  border: 1px solid rgba(244, 63, 94, 0.28);
  color: var(--color-danger);
  font-size: 13px;
  font-weight: 700;
  font-family: 'Montserrat', sans-serif;
  cursor: pointer;
  transition: background-color 0.2s, border-color 0.2s;
}
.moo-tt-del:hover { background: rgba(244, 63, 94, 0.2); border-color: rgba(244, 63, 94, 0.45); }
#tt_entry_delform { padding: 14px 24px 22px; border-top: 1px solid rgba(255, 255, 255, 0.06); }

/* Day-type segmented control (entry modal) */
.moo-tt-typesel {
  display: flex;
  gap: 4px;
  padding: 4px;
  margin-bottom: 16px;
  background: rgba(8, 14, 18, 0.6);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 12px;
}
.moo-tt-typesel__opt {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 9px 4px;
  border-radius: 9px;
  font-size: 12.5px;
  font-weight: 600;
  white-space: nowrap;
  color: rgba(255, 255, 255, 0.5);
  cursor: pointer;
  transition: background-color 0.2s, color 0.2s;
}
.moo-tt-typesel__opt input { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }
.moo-tt-typesel__opt:has(input:checked) { background: rgba(0, 229, 160, 0.14); color: var(--color-accent); }

/* Holiday / Off-sick info panel (entry modal) */
.moo-tt-typeinfo {
  margin-top: 4px;
  padding: 16px;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.08);
  font-size: 14px;
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.6);
  align-items: center;
  gap: 9px;
}
.moo-tt-typeinfo i { color: rgba(255, 255, 255, 0.4); font-size: 15px; flex: 0 0 auto; }
.moo-tt-typeinfo strong { color: var(--color-text-primary); font-weight: 700; }

/* Holiday / Off-sick day-row tags */
.moo-tt-day__tag {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 11px;
  border-radius: 9px;
  font-size: 13px;
  font-weight: 600;
}
.moo-tt-day__tag i { font-size: 12px; }
.moo-tt-day__tag--holiday { background: rgba(56, 189, 248, 0.12); color: var(--color-accent-sky); }
.moo-tt-day__tag--sick { background: rgba(255, 255, 255, 0.06); color: rgba(255, 255, 255, 0.55); }
.moo-tt-day__tag--dayoff { background: rgba(255, 255, 255, 0.06); color: rgba(255, 255, 255, 0.55); }
.moo-tt-day__net-val--none { color: rgba(255, 255, 255, 0.3); }