/* ============================================================
   Zallixor — broadcasts.css
   Banner + sheet for in-app announcements (js/broadcasts.js).

   Uses the colour tokens the app already defines (--card, --text,
   --muted, --line, --brand) with a hard fallback after each one, so
   this sheet renders correctly in the main app AND in both chat
   builds even though their token sets are not identical.

   Load AFTER style.css and ui.css so the tokens exist by the time
   these rules are read.
   ============================================================ */

#zb-banner {
  position: fixed;
  left: 0;
  right: 0;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 74px); /* clears the bottom nav */
  z-index: 140;                  /* above content, below modals (which sit at 200+) */
  display: none;
  padding: 0 12px;
  pointer-events: none;          /* the container never blocks taps */
}
#zb-banner.zb-open { display: block; }

/* On a desktop shell there is no bottom nav to clear. */
html.zx-desktop #zb-banner,
html[data-site="desktop"] #zb-banner {
  bottom: 24px;
  left: auto;
  right: 24px;
  max-width: 400px;
  padding: 0;
}

.zb-card {
  pointer-events: auto;
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 10px;
  max-width: 560px;
  margin: 0 auto;
  padding: 12px 40px 12px 12px;
  border-radius: 14px;
  border: 1px solid var(--line, rgba(255, 255, 255, .12));
  background: var(--card, #14161d);
  color: var(--text, #eef1f6);
  box-shadow: 0 10px 30px rgba(0, 0, 0, .35);
  animation: zb-rise .28s ease both;
}

@keyframes zb-rise {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

/* Respect the user's motion setting — the app already honours this
   elsewhere, so an announcement must not be the one thing that ignores it. */
@media (prefers-reduced-motion: reduce) {
  .zb-card { animation: none; }
}

.zb-icon {
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  border-radius: 8px;
  background: rgba(255, 255, 255, .06);
}
.zb-icon svg { width: 16px; height: 16px; }

.zb-text { min-width: 0; flex: 1 1 auto; }

.zb-title {
  font-weight: 600;
  font-size: 14px;
  line-height: 1.3;
  margin-bottom: 2px;
}

.zb-body {
  font-size: 13px;
  line-height: 1.45;
  color: var(--muted, #9aa3b2);
  /* Two lines in the banner; the full text is in the sheet. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.zb-actions {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  gap: 6px;
  align-self: center;
}

.zb-action,
.zb-more {
  border: 0;
  cursor: pointer;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  padding: 7px 12px;
  border-radius: 999px;
  white-space: nowrap;
}
.zb-action {
  background: var(--brand, #5b7cfa);
  color: #fff;
}
.zb-more {
  background: rgba(255, 255, 255, .08);
  color: var(--text, #eef1f6);
}

.zb-close {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 8px;
  cursor: pointer;
  background: transparent;
  color: var(--muted, #9aa3b2);
}
.zb-close:hover { background: rgba(255, 255, 255, .08); }
.zb-close svg { width: 15px; height: 15px; }

/* ── Kinds ──
   A coloured left edge rather than a fully tinted card: readable in
   both themes without needing a light and dark variant of each. */
.zb-card.zb-info      { border-left: 3px solid var(--brand, #5b7cfa); }
.zb-card.zb-update    { border-left: 3px solid #3fb950; }
.zb-card.zb-warning   { border-left: 3px solid #e3a008; }
.zb-card.zb-celebrate { border-left: 3px solid #d18bff; }

.zb-card.zb-warning .zb-icon   { background: rgba(227, 160, 8, .16); color: #e3a008; }
.zb-card.zb-update .zb-icon    { background: rgba(63, 185, 80, .16); color: #3fb950; }
.zb-card.zb-celebrate .zb-icon { background: rgba(209, 139, 255, .16); color: #d18bff; }

/* ── Full announcement sheet ── */

.zb-overlay {
  position: fixed;
  inset: 0;
  z-index: 220;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(0, 0, 0, .55);
}

.zb-sheet {
  width: 100%;
  max-width: 440px;
  border-radius: 18px;
  border: 1px solid var(--line, rgba(255, 255, 255, .12));
  background: var(--card, #14161d);
  color: var(--text, #eef1f6);
  padding: 18px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, .5);
}

.zb-sheet-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
}
.zb-sheet-head h3 {
  flex: 1 1 auto;
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  line-height: 1.3;
}
.zb-sheet-head .zb-close { position: static; }

.zb-sheet-body {
  margin: 0 0 16px;
  font-size: 14px;
  line-height: 1.6;
  color: var(--text, #eef1f6);
  white-space: pre-wrap;   /* keeps the admin's line breaks */
  word-break: break-word;
}

.zb-sheet-foot {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
}
.zb-sheet-foot .zb-action,
.zb-sheet-foot .zb-more { font-size: 13px; padding: 9px 16px; }

/* Small phones: stack the buttons under the text instead of beside it,
   so a long title never squeezes them into a single character wide. */
@media (max-width: 380px) {
  .zb-card { flex-wrap: wrap; }
  .zb-actions { flex-direction: row; width: 100%; margin-top: 4px; }
}

/* When an announcement banner is open, lift the toast above it instead of
   letting the two share the same strip of screen. The banner sits at
   bottom:74px and is ~80px tall; the toast sat at bottom:88px - wholly
   inside it, and 40 z-index layers below. They now stack: banner below,
   toast above.

   Scoped to the MOBILE shell only. On a desktop shell the banner is
   bottom-RIGHT and 400px wide while the toast is centred, so they never
   overlap - and --nav-h does not exist there, so this offset would push
   the toast into the middle of the screen for no reason. */
html:not(.zx-desktop):not([data-site="desktop"]) body.zb-has-banner #toast-host {
  bottom: calc(var(--nav-h, 72px) + var(--safe-bottom, 0px) + 104px);
}
