/* ─── Brand & palette ─────────────────────────────────────────────── */
:root {
  --pink: #ec4899;
  --pink-soft: #fdf2f8;
  --pink-rule: #fbcfe8;
  --ink: #202124;
  --ink-soft: #3c4043;
  --muted: #5f6368;
  --line: #e8eaed;
  --bg: #ffffff;
  --bg-soft: #f8fafd;     /* Gmail-style soft sidebar bg */
  --bg-hover: #f1f3f4;
  --bg-selected: #fce4ec; /* light pink for selected folder */
  --bg-row-hover: #f5f5f5;
  --accent-strong: #be185d;
  --code-bg: #f1f3f4;
  --code-fg: #c5221f;
  --unread-bold: #202124;
  --read-text: #5f6368;
}
@media (prefers-color-scheme: dark) {
  :root {
    --pink-soft: #2a1726;
    --pink-rule: #5b1d44;
    --ink: #e8eaed;
    --ink-soft: #c4c7c5;
    --muted: #9aa0a6;
    --line: #3c4043;
    --bg: #1f1f1f;
    --bg-soft: #2a2a2c;
    --bg-hover: #3c4043;
    --bg-selected: #3a1f30;
    --bg-row-hover: #303030;
    --accent-strong: #f9a8d4;
    --code-bg: #2a2a2c;
    --code-fg: #fb7185;
    --unread-bold: #e8eaed;
    --read-text: #9aa0a6;
  }
}

/* ─── Icons ────────────────────────────────────────────────────────── */
/* Inline SVGs from js/icons.js. Inherit colour from the parent so a
   single palette token (e.g. --ink-soft, --pink) drives every glyph. */
.icon-svg { display: inline-block; vertical-align: middle; flex-shrink: 0; }
[data-icon] { display: inline-flex; align-items: center; justify-content: center; }

* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
body {
  font: 14px/1.5 'Google Sans', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, system-ui, sans-serif;
  color: var(--ink);
  background: var(--bg-soft);
  overflow: hidden;
}
button { font: inherit; cursor: pointer; border: none; background: none; color: inherit; }
a { color: var(--accent-strong); }
.mono { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }

/* ─── App shell ─────────────────────────────────────────────────────── */
.app {
  display: grid;
  grid-template-rows: 64px 1fr;
  height: 100vh;
}

/* ─── Top bar ──────────────────────────────────────────────────────── */
/* Three-column grid: [menu+brand] · [centered search] · [right buttons].
   A flex topbar with `flex: 1` on both the search and a trailing
   spacer split the remaining space evenly so the search drifted
   left of the visual middle. The grid centers the search column
   in the actual page width regardless of how wide the side groups
   get. */
.topbar {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center; gap: 8px;
  padding: 8px 16px;
  background: var(--bg-soft);
  position: relative; z-index: 10;
}
.topbar-left  { display: flex; align-items: center; gap: 8px; justify-self: start; }
.topbar-right { display: flex; align-items: center; gap: 4px; justify-self: end; }
.menu-btn {
  width: 40px; height: 40px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: var(--ink-soft); font-size: 20px;
}
.menu-btn:hover { background: var(--bg-hover); }
.brand {
  display: flex; align-items: center; gap: 10px;
  padding: 0 8px; min-width: 200px;
}
.brand-bow { font-size: 28px; line-height: 1; }
/* The brand bow PNG ships with transparent background — no rounded
   crop, no fill. Sits flush against the topbar. */
.brand-logo {
  width: 36px; height: 36px;
  flex-shrink: 0;
  display: block;
  object-fit: contain;
}
.brand-name {
  font: 500 22px/1 'Google Sans', sans-serif;
  color: var(--pink);
}
.auth-card .brand-logo {
  width: 32px; height: 32px;
  vertical-align: middle;
  display: inline-block;
}

.search-container {
  /* Lives in the centered grid column of `.topbar`. Width caps at
     720px (Gmail's actual cap), but stretches to fill the column
     when the viewport is narrower. */
  width: 720px;
  max-width: 100%;
  min-width: 280px;
  position: relative;
}
.search-input {
  width: 100%; height: 48px;
  padding: 0 48px 0 48px;
  border: none; border-radius: 8px;
  background: var(--bg-hover);
  color: var(--ink); font-size: 16px;
  outline: none; transition: background .15s, box-shadow .15s;
}
.search-input:focus, .search-input:hover {
  background: var(--bg);
  box-shadow: 0 1px 3px rgba(0,0,0,.1);
}
.search-icon {
  position: absolute; left: 14px; top: 50%;
  transform: translateY(-50%); font-size: 18px;
  color: var(--muted); pointer-events: none;
}
.search-clear-btn {
  position: absolute; right: 8px; top: 50%;
  transform: translateY(-50%);
  width: 32px; height: 32px; border-radius: 50%;
  display: none; align-items: center; justify-content: center;
  color: var(--muted);
}
.search-clear-btn.show { display: flex; }
.search-clear-btn:hover { background: var(--bg-hover); color: var(--ink); }
.search-hint {
  position: absolute; right: 50px; top: 50%;
  transform: translateY(-50%);
  font-size: 12px; color: var(--muted); pointer-events: none;
  display: none;
}
.search-hint.show { display: block; }

.icon-btn {
  width: 40px; height: 40px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: var(--ink-soft); font-size: 18px;
}
.icon-btn:hover { background: var(--bg-hover); }
/* Sound-toggle state colours. On = brand pink (alive); off = muted
   so the button reads as "currently silent". */
#sound-toggle-btn.sound-on { color: var(--pink); }
#sound-toggle-btn.sound-off { color: var(--muted); }

/* ─── Activity badges (live worker status) ───────────────────────
   One pill per active dispatcher worker. Populated by SSE on the
   `worker_started` / `worker_heartbeat` / `worker_finished`
   events. Each badge shows the agent's initial + name + a short
   verb derived from the worker's `lastTool`. The green dot
   gently pulses so the row reads as "alive" rather than static. */
/* Shell wraps the always-visible count pill + the scrollable badge
   row. Two children, side-by-side; the count never scrolls so the
   user can see how many agents are active even when the scroll viewport
   is full. */
.activity-badges-shell {
  display: flex; align-items: center; gap: 6px;
  margin-right: 4px;
  min-width: 0;  /* lets the inner scrollable strip shrink without
                    pushing siblings off the topbar */
}
.activity-badges-count {
  display: inline-flex; align-items: center; justify-content: center;
  height: 22px; min-width: 22px; padding: 0 7px;
  background: var(--pink, #ff4d8c);
  color: #fff;
  font-size: 11px; font-weight: 700;
  border-radius: 999px;
  flex-shrink: 0;
  user-select: none;
}
/* Horizontal-scrolling strip of badges. We deliberately allow
   `overflow-x: auto` so the user can swipe / trackpad-scroll through
   more than fit on screen, and use an edge fade mask so it's visually
   clear there's more content past the right edge. Scrollbar stays
   hidden (cleaner topbar) but the count pill + edge fade make
   "there's more" discoverable. */
.activity-badges {
  display: flex; align-items: center; gap: 6px;
  max-width: 480px;
  overflow-x: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
  /* Mask creates a gentle fade-out on each end so badges visually
     hint "I'm continuing past the viewport edge". Pure CSS, no JS. */
  mask-image: linear-gradient(to right, transparent 0, black 12px, black calc(100% - 16px), transparent 100%);
  -webkit-mask-image: linear-gradient(to right, transparent 0, black 12px, black calc(100% - 16px), transparent 100%);
  /* Snap-scroll so swiping never leaves a badge half-clipped. */
  scroll-snap-type: x proximity;
  /* Ensure the inner strip can shrink inside its flex parent. */
  min-width: 0;
}
.activity-badges::-webkit-scrollbar { display: none; }
.activity-badge { scroll-snap-align: start; }
.activity-badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px 4px 6px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 12px;
  color: var(--ink-soft);
  white-space: nowrap;
  cursor: default;
}
.activity-badge:hover { background: var(--bg-hover); }
.activity-badge .badge-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: #34a853;          /* live-green */
  flex-shrink: 0;
  box-shadow: 0 0 0 0 rgba(52, 168, 83, 0.5);
  animation: activity-pulse 2s infinite;
}
@keyframes activity-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(52, 168, 83, 0.5); }
  70%  { box-shadow: 0 0 0 6px rgba(52, 168, 83, 0); }
  100% { box-shadow: 0 0 0 0 rgba(52, 168, 83, 0); }
}
.activity-badge .badge-initial {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--pink); color: white;
  font-size: 10px; font-weight: 700;
  flex-shrink: 0;
}
.activity-badge .badge-name { font-weight: 500; color: var(--ink); }
.activity-badge .badge-status { color: var(--muted); }
.activity-badge .badge-status::before { content: '· '; opacity: .6; }

/* Mobile — hide the whole activity-badge shell (count pill + scrolling
   strip) on narrow viewports; folds into the profile dropdown anyway. */
@media (max-width: 800px) {
  .activity-badges-shell { display: none !important; }
}

/* ─── Profile (top right) ─────────────────────────────────────────── */
.profile-trigger {
  width: 40px; height: 40px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  border: 2px solid transparent;
  transition: border-color .15s;
}
.profile-trigger:hover { border-color: var(--line); }

.profile-menu {
  position: absolute; top: 56px; right: 16px;
  width: 360px; max-height: 80vh; overflow-y: auto;
  background: var(--bg); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 8px 32px rgba(0,0,0,0.15);
  padding: 12px 0; z-index: 25;
  display: none;
}
.profile-menu.open { display: block; }
.profile-menu-section {
  padding: 8px 20px 6px; font-size: 11px; font-weight: 600;
  color: var(--muted); text-transform: uppercase; letter-spacing: .06em;
}
.profile-menu-item {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 20px; cursor: pointer;
  color: var(--ink);
}
.profile-menu-item:hover { background: var(--bg-hover); }
.profile-menu-item .meta { flex: 1; min-width: 0; }
.profile-menu-item .name {
  font-weight: 500; font-size: 14px;
  display: flex; align-items: center; gap: 6px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.profile-menu-item .email {
  font-size: 12px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.profile-menu-item .selected-check {
  color: var(--pink); font-size: 20px; font-weight: 700;
  margin-left: 4px;
}
.profile-menu-divider { height: 1px; background: var(--line); margin: 8px 0; }

/* ─── Host switcher (Airbnb-style) ────────────────────────────────────
 *
 * Segmented pill bar at the top of the inbox menu. Each pill represents
 * a host (Claude, Codex, All); clicking flips the inbox list with a 3D
 * Y-axis rotation. The active pill is filled with the accent colour;
 * inactive pills are subtle so the visual weight rests on the inbox
 * roster itself rather than the chrome.
 */
.host-switcher {
  display: flex;
  gap: 4px;
  margin: 0 12px 6px;
  padding: 4px;
  background: var(--bg-hover);
  border-radius: 999px;
  border: 1px solid var(--line);
}
.host-switcher-pill {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 7px 10px;
  border: none;
  background: transparent;
  border-radius: 999px;
  color: var(--muted);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  /* Match Airbnb's "switch to hosting" feel: brisk, eased, no bounce. */
  transition: background-color 200ms cubic-bezier(0.4, 0, 0.2, 1),
              color 200ms cubic-bezier(0.4, 0, 0.2, 1),
              transform 120ms cubic-bezier(0.4, 0, 0.2, 1),
              box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1);
  white-space: nowrap;
  user-select: none;
}
.host-switcher-pill:hover { color: var(--ink); }
.host-switcher-pill:active { transform: scale(0.97); }
.host-switcher-pill.is-active {
  background: var(--bg);
  color: var(--ink);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
}
.host-switcher-logo {
  width: 16px;
  height: 16px;
  object-fit: contain;
  display: block;
}
.host-switcher-dot {
  width: 8px;
  height: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: currentColor;
  opacity: 0.7;
}

/* ─── Flip card (3D rotation on host switch) ──────────────────────────
 *
 * The inbox roster lives inside `.flip-card`, which rotates 180deg on
 * Y when a host is switched. Two stacked `.flip-face` panes carry the
 * "before" and "after" rosters; `backface-visibility: hidden` ensures
 * each pane is only visible on its own side of the rotation. Result:
 * the user sees roster A → edge-on at 90deg → roster B, creating the
 * illusion that each side of the card carries a distinct view.
 *
 * Same trick as Airbnb's Host Passport book-flip on iOS (Tech Blog,
 * May 2023). The CSS port is straightforward because the swap happens
 * naturally at the orthogonal midpoint where neither face is visible.
 */
#profile-menu-list {
  perspective: 1200px;
  /* perspective-origin: top so the flip pivots from the eye line, not
   * the centre — feels more like turning a page than tumbling a coin. */
  perspective-origin: 50% 0%;
}
.flip-card {
  position: relative;
  transform-style: preserve-3d;
  /* 460ms is the sweet spot from the Airbnb engineering write-up:
   * fast enough to feel responsive, slow enough to read as deliberate. */
  transition: transform 460ms cubic-bezier(0.4, 0, 0.2, 1);
  /* min-height so the menu doesn't collapse to 0 during the flip when
   * the back face is empty for the resetting frame. */
  min-height: 80px;
}
.flip-card.flipped {
  transform: rotateY(180deg);
}
.flip-face {
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  width: 100%;
}
.flip-face-back {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  transform: rotateY(180deg);
}
@media (prefers-reduced-motion: reduce) {
  .flip-card { transition: none; }
}

/* ─── Empty state inside the profile menu (filtered view → 0 rows) ──── */
.profile-menu-empty {
  padding: 24px 20px;
  text-align: center;
  color: var(--muted);
}
.profile-menu-empty .empty-icon {
  display: flex;
  justify-content: center;
  margin-bottom: 10px;
  opacity: 0.4;
}
.profile-menu-empty .empty-text {
  font-size: 13px;
  margin-bottom: 8px;
  color: var(--ink);
}
.profile-menu-empty .empty-hint {
  font-size: 12px;
  line-height: 1.5;
}
.profile-menu-empty code {
  font-size: 11px;
  padding: 2px 6px;
  border-radius: 4px;
  background: var(--bg-hover);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.profile-menu-footer {
  padding: 12px 20px; font-size: 13px; color: var(--muted);
  display: flex; gap: 12px;
}
.profile-menu-footer a {
  color: var(--accent-strong); cursor: pointer; text-decoration: none;
}
.profile-menu-footer a:hover { text-decoration: underline; }

/* ─── Operator notification email — display + inline edit ──────────
 *
 * Lives between the inbox list and the Sign out footer. Two states:
 *  - Display: current address (or "Not set" placeholder) + pencil
 *  - Edit:    <input> + Save / Cancel / Clear buttons + hint copy
 *
 * Visual weight is deliberately understated — this is a "set once,
 * forget" knob, not a primary action. */
.operator-email-display {
  padding: 6px 20px 10px;
  display: flex; align-items: center; gap: 8px;
  font-size: 13px;
}
.operator-email-value {
  flex: 1;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.operator-email-value.is-empty {
  color: var(--muted);
  font-style: italic;
  font-size: 12px;
}
.operator-email-edit-btn {
  background: transparent;
  border: none;
  cursor: pointer;
  color: var(--muted);
  padding: 4px;
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.operator-email-edit-btn:hover {
  background: var(--bg-hover);
  color: var(--ink);
}
.operator-email-edit {
  padding: 4px 20px 12px;
}
.operator-email-input {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--bg);
  color: var(--ink);
  font-size: 13px;
  font-family: inherit;
  box-sizing: border-box;
}
.operator-email-input:focus {
  outline: none;
  border-color: var(--accent-strong);
}
.operator-email-actions {
  display: flex;
  gap: 6px;
  margin-top: 8px;
}
.operator-email-btn {
  padding: 6px 12px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--bg);
  color: var(--ink);
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  transition: background 120ms, border-color 120ms;
}
.operator-email-btn:hover { background: var(--bg-hover); }
.operator-email-btn-primary {
  background: var(--accent-strong);
  color: white;
  border-color: var(--accent-strong);
}
.operator-email-btn-primary:hover {
  background: var(--accent-strong);
  opacity: 0.9;
}
.operator-email-btn-danger {
  margin-left: auto;
  color: #b91c1c;
  border-color: transparent;
}
.operator-email-btn-danger:hover {
  background: #fee2e2;
}
.operator-email-hint {
  margin-top: 8px;
  font-size: 11px;
  color: var(--muted);
  line-height: 1.45;
}
@media (prefers-color-scheme: dark) {
  .operator-email-btn-danger { color: #fca5a5; }
  .operator-email-btn-danger:hover { background: #2a1717; }
}

/* ─── Avatars ──────────────────────────────────────────────────────── */
.avatar {
  width: 32px; height: 32px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 14px; font-weight: 500; color: white;
  flex-shrink: 0; position: relative;
}
.avatar-sm { width: 24px; height: 24px; font-size: 11px; }
.avatar-md { width: 40px; height: 40px; font-size: 16px; }
.avatar-lg { width: 48px; height: 48px; font-size: 20px; }
.avatar-host { background: #fce8e0; color: #d97757; }
@media (prefers-color-scheme: dark) { .avatar-host { background: #2a1810; } }
.avatar svg { width: 60%; height: 60%; }
.avatar-img {
  width: 70%; height: 70%;
  object-fit: contain;
  display: block;
}
.avatar-check {
  position: absolute; bottom: -2px; right: -2px;
  width: 14px; height: 14px; border-radius: 50%;
  background: #22c55e; color: white;
  display: flex; align-items: center; justify-content: center;
  font-size: 9px; font-weight: 700;
  border: 2px solid var(--bg);
}

.role-badge {
  font-size: 10px; font-weight: 600;
  padding: 2px 7px; border-radius: 10px;
  text-transform: uppercase; letter-spacing: .04em;
  flex-shrink: 0;
}
.role-badge-host { background: #fef3c7; color: #92400e; }
.role-badge-sub { background: var(--pink-soft); color: var(--accent-strong); }
/* Host-ownership badges — show which LLM each agent's dispatcher
   rides on. Color-coded by provider so the user can scan an inbox
   list and tell at a glance which agents will wake under which
   model. metadata.host = 'claudecode' → Claude (Anthropic purple);
   'codex' → Codex (OpenAI orange/green); other → generic; absent →
   "Unclaimed" gray with hint to run `agenticmail-<host> claim`. */
.role-badge-claude       { background: #ede9fe; color: #5b21b6; }    /* Anthropic purple */
.role-badge-codex        { background: #dcfce7; color: #166534; }    /* OpenAI green */
.role-badge-host-other   { background: #dbeafe; color: #1e40af; }    /* unknown future host */
.role-badge-unclaimed    { background: #f3f4f6; color: #6b7280; }    /* legacy / no owner */
@media (prefers-color-scheme: dark) {
  .role-badge-host       { background: #44290c; color: #fcd34d; }
  .role-badge-claude     { background: #3b1f6b; color: #c4b5fd; }
  .role-badge-codex      { background: #14361f; color: #86efac; }
  .role-badge-host-other { background: #1e3a8a; color: #93c5fd; }
  .role-badge-unclaimed  { background: #1f2937; color: #9ca3af; }
}

/* ─── Main grid: sidebar + content ──────────────────────────────── */
.main {
  display: grid;
  grid-template-columns: 256px 1fr;
  overflow: hidden;
  background: var(--bg-soft);
  position: relative;
}
.sidebar-backdrop {
  display: none;
  position: fixed; inset: 64px 0 0 0;
  background: rgba(0,0,0,0.4);
  z-index: 14;
}
/* ─── Mobile / narrow viewport ──────────────────────────────────── */
@media (max-width: 800px) {
  .main { grid-template-columns: 1fr; }
  .sidebar {
    position: fixed; top: 64px; bottom: 0; left: 0;
    width: 280px; max-width: 85vw;
    background: var(--bg-soft);
    z-index: 15;
    transform: translateX(-100%);
    transition: transform .22s ease;
    box-shadow: 2px 0 16px rgba(0,0,0,0.1);
  }
  .main.sidebar-open .sidebar { transform: translateX(0); }
  .main.sidebar-open .sidebar-backdrop { display: block; }
  .content { border-radius: 0; margin: 0; }
  /* On mobile, drop the centered grid in favour of [chrome | search | account].
     The search expands to fill whatever space is left. */
  .topbar {
    padding: 8px 8px; gap: 4px;
    grid-template-columns: auto 1fr auto;
  }
  .brand { min-width: auto; }
  .brand-name { font-size: 18px; display: none; }
  .search-container { width: auto; min-width: 0; }
  .search-input { height: 40px; font-size: 14px; }
  /* On narrow screens, drop the checkbox + From column. Sender goes
     in a small line above subject+preview to mimic Gmail's mobile
     two-row stack. */
  .list-row {
    grid-template-columns: 32px 1fr 64px;
    height: auto;
    min-height: 64px;
    padding: 8px 12px;
    align-items: center;
  }
  .list-row .row-check { display: none; }
  .list-row .from {
    grid-column: 2 / 3;
    font-size: 13px;
    padding-right: 0;
  }
  .list-row .subject-cell {
    grid-column: 2 / 3;
    grid-row: 2;
    white-space: normal;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
  .list-row .star { grid-row: 1 / span 2; }
  .list-row .date { grid-row: 1; }
  .message-header { padding: 16px 16px 8px; }
  .message-subject { font-size: 18px; }
  .message-body { padding: 8px 16px 24px; max-width: none; }
  .message-attachments { padding: 12px 16px; }
  /* Compose modal goes full-screen on mobile rather than a tiny
     bottom-right popup that nobody can type into. */
  .compose-bg { padding: 0; align-items: stretch; justify-content: stretch; }
  .compose-modal { width: 100%; max-height: 100vh; border-radius: 0; }
  .compose-body textarea { min-height: 40vh; }
  /* Hide non-essential top-bar buttons on narrow screens. */
  #refresh-btn { display: none; }
}
@media (min-width: 801px) {
  /* Hamburger menu only matters on mobile; hide on desktop. */
  .menu-btn { display: none; }
}

/* ─── Sidebar ──────────────────────────────────────────────────────── */
.sidebar {
  padding: 8px 8px 16px 8px;
  overflow-y: auto;
}
.compose-btn {
  /* Gmail's Compose button is 48px tall with 16px corner radius —
     prominent but not pill-shaped. Earlier this was 56px + ~28px
     radius which read as a giant capsule and dominated the sidebar. */
  display: inline-flex; align-items: center; gap: 12px;
  height: 48px; padding: 0 24px 0 16px;
  margin-bottom: 16px;
  background: var(--pink); color: white;
  border-radius: 16px;
  font: 500 14px/1 'Google Sans', sans-serif;
  box-shadow: 0 1px 3px rgba(0,0,0,.1), 0 1px 2px rgba(0,0,0,.06);
  transition: box-shadow .15s, background .15s;
}
.compose-btn:hover {
  box-shadow: 0 2px 6px rgba(0,0,0,.15), 0 2px 4px rgba(0,0,0,.08);
  background: var(--accent-strong);
}
.compose-btn .compose-icon { font-size: 20px; }

.folder-row {
  display: flex; align-items: center; gap: 16px;
  height: 32px; padding: 0 12px 0 26px;
  border-radius: 0 16px 16px 0;
  margin-right: 8px;
  color: var(--ink-soft); cursor: pointer;
  font-size: 14px; font-weight: 500;
}
.folder-row:hover { background: var(--bg-hover); }
.folder-row.active {
  background: var(--bg-selected);
  color: var(--accent-strong);
  font-weight: 700;
}
.folder-row .icon { font-size: 18px; width: 20px; flex-shrink: 0; }
.folder-row .label { flex: 1; }
.folder-row .count {
  font-size: 12px; font-weight: 700;
  color: var(--accent-strong);
}
.folder-row .count[data-zero] { display: none; }

.sidebar-section {
  padding: 16px 16px 4px;
  font-size: 11px; font-weight: 600;
  color: var(--muted); text-transform: uppercase; letter-spacing: .06em;
}

/* ─── Content area ─────────────────────────────────────────────────── */
.content {
  background: var(--bg);
  border-radius: 16px 0 0 0;
  margin: 0 8px 8px 0;
  overflow: hidden;
  display: flex; flex-direction: column;
}

/* List toolbar (sticky, matches Gmail's row of buttons above the list).
   Same markup for every folder so Sent / Drafts / Spam render
   identically to Inbox — no per-folder UX divergence. */
.list-toolbar {
  display: flex; align-items: center; gap: 4px;
  padding: 4px 16px; height: 48px;
  border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 5;
  background: var(--bg);
  flex-shrink: 0;
}
.list-select-all {
  width: 40px; height: 40px;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; border-radius: 50%;
}
.list-select-all:hover { background: var(--bg-hover); }
.list-toolbar .list-refresh { width: 40px; height: 40px; }
.list-toolbar-spacer { flex: 1; }
.list-toolbar .count-text {
  font-size: 12px; color: var(--muted);
  margin-right: 8px;
}
/* Gmail-style pager. Buttons inherit .icon-btn styling; disabled
   state mutes the colour so the user can tell at a glance whether
   prev/next is available without trying to click. */
.pager-btn {
  width: 32px; height: 32px;
  color: var(--ink-soft);
}
.pager-btn:hover:not(:disabled) { background: var(--bg-hover); color: var(--ink); }
.pager-btn:disabled {
  color: var(--line);
  cursor: default;
}

/* Bulk-action toolbar — appears between select-all and refresh
   when one or more rows are checked. Replaces the visual idle
   state of the row (toolbar) with action buttons + a "N selected"
   indicator on the right. */
.bulk-actions {
  display: flex; align-items: center; gap: 4px;
  margin-left: 8px;
  padding-left: 12px;
  border-left: 1px solid var(--line);
}
.bulk-actions[hidden] { display: none; }
.bulk-actions .bulk-btn {
  width: 36px; height: 36px;
  color: var(--ink-soft);
}
.bulk-actions .bulk-btn:hover { background: var(--bg-hover); color: var(--ink); }
.bulk-count {
  font-size: 12px; font-weight: 500; color: var(--accent-strong);
  margin-left: 8px;
}

/* Gmail-style compact rows.
   Single line per message; subject + preview share one truncated
   cell so longer previews tail off with ellipsis instead of
   wrapping. Same row shape for every folder. */
.list-rows {
  flex: 1; overflow-y: auto;
}
.list-row {
  display: grid;
  grid-template-columns: 36px 32px 180px 1fr 90px;
  align-items: center; gap: 0;
  padding: 0 16px; height: 36px;
  cursor: pointer;
  border-bottom: 1px solid var(--line);
  position: relative;
}
@media (max-width: 1100px) { .list-row { grid-template-columns: 36px 32px 140px 1fr 80px; } }
.list-row:hover {
  background: var(--bg);
  box-shadow: inset 1px 0 0 var(--line), inset -1px 0 0 var(--line), 0 1px 3px rgba(0,0,0,.08);
  z-index: 1;
}
.list-row.unread { background: var(--bg); }
.list-row.unread .from, .list-row.unread .subject {
  color: var(--unread-bold); font-weight: 700;
}
.list-row:not(.unread) .from, .list-row:not(.unread) .subject {
  color: var(--read-text);
}
.list-row .row-check {
  width: 36px; height: 36px;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
}
.list-row .row-check input { cursor: pointer; }
.list-row .star {
  width: 32px; height: 32px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%; cursor: pointer;
  color: #dadce0;
}
.list-row .star:hover { background: var(--bg-hover); color: var(--muted); }
.list-row .star.starred { color: #f4b400; }
.list-row .from {
  font-size: 14px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  padding-right: 12px;
}
.list-row .subject-cell {
  font-size: 14px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  min-width: 0;
  display: block;        /* one line, ellipsis at the end */
}
.list-row .subject { font-weight: inherit; }
.list-row .preview-sep { color: var(--muted); }
.list-row .preview { color: var(--muted); font-weight: 400; }
.list-row .date {
  font-size: 12px; color: var(--muted); font-weight: 500;
  text-align: right; padding-right: 4px;
}
.list-row.unread .date { color: var(--unread-bold); font-weight: 700; }

/* ─── Drafts folder list ───────────────────────────────────────────
   In the Drafts list, the leading column reads as the recipient
   ("To: alice@…") since the user is always the sender; we tag it
   with a small red "Draft" pill so the row is unmistakable.
   Stars don't apply to drafts — the star slot is left empty. */
.list-row.draft-row .drafts-tag {
  display: inline-block;
  background: #ea4335;
  color: white;
  font-size: 11px; font-weight: 600;
  padding: 1px 6px; border-radius: 4px;
  margin-right: 6px;
  letter-spacing: .02em;
}
.list-row.draft-row .drafts-recipient .drafts-tag + * { vertical-align: middle; }
.list-row.draft-row .drafts-star-placeholder {
  /* Reserve grid space but render nothing — keeps every row's
     subject column aligned with non-draft folder rows. */
  width: 32px; height: 32px;
}

mark.search-hl {
  background: #fff475; color: inherit;
  padding: 0 1px;
}
@media (prefers-color-scheme: dark) {
  mark.search-hl { background: #5b4d00; color: #fef9c3; }
}

.empty {
  padding: 80px 24px; text-align: center;
  color: var(--muted); font-size: 14px;
}
.empty .big { font-size: 48px; margin-bottom: 16px; opacity: .4; }

/* ─── Message detail view ──────────────────────────────────────── */
.message-view {
  display: flex; flex-direction: column;
  height: 100%; overflow-y: auto;
}
.message-toolbar {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 16px; height: 48px;
  border-bottom: 1px solid var(--line);
  background: var(--bg);
  position: sticky; top: 0; z-index: 5;
  flex-shrink: 0;
  /* Toolbar spans full width (so the back button sticks to the
     left edge of the content pane) but its action group could be
     centered later if needed. Keeping it full-width matches Gmail. */
}
.message-toolbar .icon-btn { width: 36px; height: 36px; font-size: 16px; }
.message-toolbar .toolbar-spacer { flex: 1; }

/* Centered reading column for the open message — Gmail caps body
   content around ~840px so long-line text doesn't sprawl across
   ultrawide displays. Header, body, and attachments all share
   the same centering rule so they line up vertically. */
.message-header {
  padding: 32px 32px 16px;
  max-width: 840px;
  margin: 0 auto;
  width: 100%;
}
.message-subject {
  font: 400 22px/1.3 'Google Sans', sans-serif;
  color: var(--ink);
  margin: 0 0 20px;
}
.message-sender-row {
  display: flex; align-items: flex-start; gap: 16px;
}
.message-meta {
  flex: 1; min-width: 0;
}
.message-from {
  font-size: 14px; color: var(--ink);
}
.message-from .name { font-weight: 500; }
.message-from .addr { color: var(--muted); margin-left: 4px; }
/* Recipient rows — one per field (To / Cc / Bcc). Renders only
   when the field is non-empty. The label is a fixed-width tag
   so the addresses align cleanly across the three rows. */
.message-recipient-row {
  display: flex; gap: 6px;
  font-size: 12px; color: var(--muted);
  margin-top: 4px;
  line-height: 1.5;
}
.message-recipient-label {
  flex: 0 0 28px;
  font-weight: 600;
  color: var(--ink-soft);
  text-transform: none;
}
.message-recipient-list {
  flex: 1 1 auto;
  min-width: 0;
  word-break: break-word;
}
.message-cc .message-recipient-label,
.message-bcc .message-recipient-label { color: var(--muted); }
.message-date {
  font-size: 12px; color: var(--muted);
  white-space: nowrap;
}

.message-body {
  padding: 8px 32px 32px;
  font-size: 14px; line-height: 1.65;
  color: var(--ink);
  white-space: pre-wrap; word-wrap: break-word;
  max-width: 840px;
  margin: 0 auto;
  width: 100%;
  /* Clear visual end-of-message marker. The reply / quoted-thread
     chrome above made the body's bottom ambiguous; a hairline rule
     gives the reader a definite stop and separates from the
     attachments / next message in stack views. */
  border-bottom: 1px solid var(--line);
  padding-bottom: 28px;
  margin-bottom: 8px;
}
.message-body h1, .message-body h2, .message-body h3 {
  color: var(--pink); margin: 1.2em 0 .4em;
}
.message-body h1 { font-size: 1.4em; }
.message-body h2 { font-size: 1.2em; }
.message-body h3 { font-size: 1.05em; }
.message-body code {
  background: var(--code-bg); color: var(--code-fg);
  padding: 1px 5px; border-radius: 4px; font-size: 13px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
.message-body pre {
  background: var(--code-bg); padding: 12px 14px; border-radius: 8px;
  overflow-x: auto; font-size: 13px;
}
.message-body pre code { background: transparent; padding: 0; color: var(--ink); }
.message-body strong { color: var(--ink); }
.message-body em { color: var(--ink-soft); }
.message-body blockquote {
  border-left: 3px solid var(--pink-rule);
  margin: .8em 0; padding: .2em 0 .2em 12px;
  color: var(--muted); white-space: pre-wrap;
}

/* ─── In-body thread quote (replies inline in the body) ───────── */
/* When a message body contains an "On <date>, <addr> wrote:" line
   followed by `>`-quoted text, we render that section as a
   styled card with proper avatar + name + friendly date instead
   of leaving the raw ISO timestamp visible. Nested replies recurse
   so a 3-deep thread gets 3 nested cards. */
/* Thread-quote: the boxed-up older email a reply quotes. Issues we
 * sequentially squashed:
 *
 *   1. Huge vertical gap before the quote — initially 16px margin-top
 *      on .thread-quote PLUS empty <p>/<ul> blocks from the markdown
 *      renderer treating reply sig-lines like `- marlow` as bullet
 *      lists. message-view.js now trims trailing blank lines from
 *      the prose buffer; we tighten the rendered block margins below
 *      so the last <p>/<ul>/<ol> before a quote collapses its
 *      bottom margin and the gap reads as a single hairline.
 *   2. The pink left rule looked like a stub. ::before lays a 1px
 *      full-width divider tucked behind the border so the visual
 *      break is unambiguous and the rule reads as a continuous
 *      thread spine through the quoted block.
 *
 * Nested quotes (replies-of-replies) get progressively warmer rule
 * colours (pink → purple → amber) so the depth is visible at a
 * glance without staring at indentation. */
.thread-quote {
  position: relative;
  margin: 4px 0 8px;
  padding: 14px 0 4px 16px;
  border-left: 3px solid var(--pink-rule);
}
.thread-quote::before {
  content: '';
  position: absolute;
  top: 0;
  left: -3px;
  right: 0;
  height: 1px;
  background: var(--line, rgba(255,255,255,0.08));
}
/* Collapse the margin-bottom on whichever block lands immediately
 * before a thread-quote. Markdown's default 1em paragraph/list
 * margins were stacking with .thread-quote's margin-top, producing
 * a ~50px dead zone above quoted replies. With :has() we target
 * only the preceding sibling (other blocks elsewhere keep their
 * default margins). Modern browsers all support :has() now. */
.message-body p:has(+ .thread-quote),
.message-body ul:has(+ .thread-quote),
.message-body ol:has(+ .thread-quote),
.message-body h1:has(+ .thread-quote),
.message-body h2:has(+ .thread-quote),
.message-body h3:has(+ .thread-quote),
.message-body pre:has(+ .thread-quote),
.message-body blockquote:has(+ .thread-quote) {
  margin-bottom: 0;
}
/* Same tightening on the LAST child of a thread-quote-body — keeps
 * nested quote ladders from accumulating spacing as they descend. */
.thread-quote-body > p:last-child,
.thread-quote-body > ul:last-child,
.thread-quote-body > ol:last-child {
  margin-bottom: 0;
}
.thread-quote .thread-quote {
  border-left-color: #c084fc;
  margin: 4px 0 8px;
}
.thread-quote .thread-quote .thread-quote { border-left-color: #f59e0b; }
.thread-quote-head {
  display: flex; align-items: center; gap: 8px;
  margin: 0 0 8px;
  font-size: 13px;
  color: var(--muted);
}
.thread-quote-head .avatar-sm {
  width: 22px; height: 22px; font-size: 10px;
}
.thread-quote-from { font-weight: 500; color: var(--ink-soft); }
.thread-quote-dot { opacity: .5; }
.thread-quote-date { color: var(--muted); }
/* Audience block (To / Cc / Bcc) below the quote header — surfaces
 * who was on the previous round of the thread, not just the sender.
 * Optional: missing values are simply omitted, no row rendered. */
.thread-quote-audience {
  margin: -4px 0 8px;
  padding-left: 30px;          /* line up with sender name (past avatar) */
  font-size: 12px;
  color: var(--muted);
  line-height: 1.5;
}
.thread-quote-audience-row { display: block; }
.thread-quote-audience-label {
  display: inline-block;
  min-width: 28px;
  color: var(--muted);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 10.5px;
}
.thread-quote-audience-value {
  color: var(--ink-soft);
  word-break: break-word;
}
.thread-quote-body {
  color: var(--ink-soft);
}
.thread-quote-body p,
.thread-quote-body div { color: var(--ink-soft); }
.thread-quote-body code { background: var(--code-bg); color: var(--code-fg); }

.message-body blockquote blockquote { border-left-color: #c084fc; }
.message-body blockquote blockquote blockquote { border-left-color: #f59e0b; }
.message-body table { border-collapse: collapse; margin: .5em 0; }
.message-body th, .message-body td { border: 1px solid var(--line); padding: 6px 10px; }
.message-body th { background: var(--bg-soft); font-weight: 600; }
.message-body ul, .message-body ol { padding-left: 24px; }
.message-body hr { border: none; border-top: 1px solid var(--line); margin: 1.2em 0; }
.message-body a { color: var(--accent-strong); }
.message-body input[type=checkbox] { margin-right: 6px; }

.message-attachments {
  padding: 12px 32px; border-top: 1px solid var(--line);
  display: flex; flex-wrap: wrap; gap: 8px;
  max-width: 840px;
  margin: 0 auto;
  width: 100%;
}
.message-attachment {
  /* Clickable chip — fetches the file via the authed download
     helper and triggers a browser download. */
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 12px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--bg-soft); color: var(--ink-soft);
  font-size: 13px; cursor: pointer;
  font: inherit;
  transition: background .12s, border-color .12s, transform .06s;
}
.message-attachment:hover {
  background: var(--bg-hover);
  border-color: var(--accent-strong);
  color: var(--ink);
}
.message-attachment:active { transform: translateY(1px); }
.message-attachment.downloading { opacity: .6; cursor: progress; }
.message-attachment .att-icon { display: inline-flex; }
.message-attachment .att-size {
  color: var(--muted); font-size: 12px;
  padding-left: 4px;
  border-left: 1px solid var(--line);
}

/* Compose attachment chips (in the open compose modal) */
.compose-attachments {
  display: flex; flex-wrap: wrap; gap: 6px;
  padding: 8px 0 0;
}
.compose-attachments:empty { display: none; }
.attachment-chip {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 4px 4px 4px 10px;
  background: var(--bg-soft); border: 1px solid var(--line);
  border-radius: 16px;
  font-size: 12px; color: var(--ink-soft);
  max-width: 240px;
}
.attachment-chip .chip-name {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  max-width: 160px;
}
.attachment-chip .chip-size { color: var(--muted); }
.attachment-chip .chip-remove {
  width: 20px; height: 20px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 14px; line-height: 1; color: var(--muted);
  background: transparent; cursor: pointer;
}
.attachment-chip .chip-remove:hover { background: var(--bg-hover); color: var(--ink); }

/* Paperclip attach button in compose footer. */
.btn-attach {
  width: 36px; height: 36px;
  color: var(--muted);
}
.btn-attach:hover { background: var(--bg-hover); color: var(--ink); }

/* ─── Auth gate ─────────────────────────────────────────────────────── */
.auth-gate {
  position: fixed; inset: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--bg);
  z-index: 100;
}
.auth-card {
  width: 420px; padding: 36px;
  background: var(--bg); border: 1px solid var(--line); border-radius: 14px;
  box-shadow: 0 4px 16px rgba(0,0,0,.06);
}
.auth-card h1 { margin: 0 0 8px; font-size: 24px; color: var(--pink); font-weight: 500; }
.auth-card p { margin: 0 0 20px; color: var(--muted); font-size: 14px; line-height: 1.6; }
.auth-card input {
  width: 100%; height: 44px; padding: 0 14px; margin-bottom: 12px;
  border: 1px solid var(--line); border-radius: 8px;
  background: var(--bg-soft); color: var(--ink); outline: none;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 13px;
}
.auth-card input:focus { border-color: var(--pink); background: var(--bg); }
.auth-card .submit {
  width: 100%; height: 44px;
  background: var(--pink); color: white; border-radius: 8px;
  font-weight: 500; font-size: 14px;
}
.auth-card .submit:hover { background: var(--accent-strong); }
.auth-err { color: #d93025; font-size: 12px; margin-bottom: 12px; }

/* ─── Compose modal ─────────────────────────────────────────────────── */
.compose-bg {
  position: fixed; inset: 0; background: rgba(0,0,0,.3);
  display: flex; align-items: flex-end; justify-content: flex-end;
  padding: 0 24px 0 0;
  z-index: 50;
}
.compose-modal {
  width: 560px; max-height: 80vh;
  background: var(--bg); border-radius: 8px 8px 0 0;
  box-shadow: 0 8px 24px rgba(0,0,0,.2);
  display: grid; grid-template-rows: auto 1fr auto;
  overflow: hidden;
}
.compose-head {
  padding: 12px 16px;
  background: #404040; color: white;
  display: flex; justify-content: space-between; align-items: center;
  font-size: 13px; font-weight: 500;
}
.compose-head button { color: white; font-size: 16px; opacity: .8; }
.compose-head button:hover { opacity: 1; }

.compose-body {
  padding: 8px 16px; overflow-y: auto;
}
.compose-row {
  display: grid; grid-template-columns: 60px 1fr;
  border-bottom: 1px solid var(--line);
  align-items: center;
  padding: 4px 0;
}
.compose-row label { color: var(--muted); font-size: 13px; padding: 0 8px; }
.compose-row input, .compose-row select {
  width: 100%; padding: 8px 4px;
  border: none; outline: none;
  background: transparent; color: var(--ink);
  font: inherit; font-size: 14px;
}
.compose-row select { cursor: pointer; }
.compose-body textarea {
  width: 100%; min-height: 240px;
  padding: 12px 4px; margin-top: 8px;
  border: none; outline: none; resize: vertical;
  background: transparent; color: var(--ink);
  font-family: inherit; font-size: 14px; line-height: 1.6;
}
.compose-foot {
  padding: 12px 16px;
  border-top: 1px solid var(--line);
  display: flex; gap: 8px; align-items: center;
}
.btn-send {
  background: var(--pink); color: white;
  padding: 8px 24px; border-radius: 4px;
  font-weight: 500; font-size: 14px;
}
.btn-send:hover { background: var(--accent-strong); }
.compose-status {
  font-size: 12px; color: var(--muted);
  margin-left: 12px;
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.btn-discard {
  color: var(--muted);
  padding: 8px 12px;
}
.btn-discard:hover { background: var(--bg-hover); color: var(--ink); }
.compose-hint {
  font-size: 11px; color: var(--muted); padding: 0 8px;
}

/* ─── Confirm modal (used by destructive actions: delete, spam) ──── */
/* Centered dialog backed by a dimmed full-screen backdrop. Replaces
   browser-native window.confirm() so destructive actions match the
   rest of the app's chrome rather than dropping into OS-styled
   alerts. Focus lands on the confirm button on open; Esc cancels;
   Enter confirms only when the button has focus. */
.confirm-modal-bg {
  position: fixed; inset: 0; z-index: 80;
  background: rgba(0,0,0,0.45);
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  animation: confirm-fade-in .12s ease-out;
}
@keyframes confirm-fade-in { from { opacity: 0; } to { opacity: 1; } }
.confirm-modal {
  width: 100%; max-width: 420px;
  background: var(--bg); color: var(--ink);
  border-radius: 14px;
  padding: 24px 24px 18px;
  box-shadow: 0 12px 40px rgba(0,0,0,0.25), 0 2px 8px rgba(0,0,0,0.1);
}
.confirm-modal-title {
  margin: 0 0 8px;
  font: 500 18px/1.35 'Google Sans', sans-serif;
  color: var(--ink);
}
.confirm-modal-body {
  margin: 0 0 20px;
  font-size: 14px; line-height: 1.5;
  color: var(--ink-soft);
}
.confirm-modal-actions {
  display: flex; gap: 8px; justify-content: flex-end;
}
.btn-confirm-cancel,
.btn-confirm-ok {
  font: 500 14px/1 'Google Sans', sans-serif;
  padding: 10px 18px; border-radius: 8px;
  cursor: pointer; transition: background .12s;
}
.btn-confirm-cancel {
  background: transparent; color: var(--accent-strong);
}
.btn-confirm-cancel:hover { background: var(--bg-hover); }
.btn-confirm-ok {
  background: var(--pink); color: white;
}
.btn-confirm-ok:hover { background: var(--accent-strong); }
.btn-confirm-ok.btn-confirm-danger {
  /* Destructive variant — red instead of brand pink. */
  background: #d93025;
}
.btn-confirm-ok.btn-confirm-danger:hover { background: #b3261e; }

/* ─── Toast ────────────────────────────────────────────────────────── */
.toast {
  position: fixed; bottom: 24px; left: 24px; z-index: 60;
  padding: 12px 20px; border-radius: 4px;
  background: #323232; color: white; font-size: 14px;
  opacity: 0; transform: translateY(8px);
  transition: opacity .2s, transform .2s;
  pointer-events: none;
  max-width: 480px;
}
.toast.show { opacity: 1; transform: translateY(0); }
.toast.error { background: #d93025; }
