/* =============================================================================
   WhatsApp CRM — design system
   One accent, a neutral ramp, and generous vertical rhythm. Bengali glyphs sit
   taller than Latin ones, so line-height and paddings here are deliberately
   larger than a Latin-only UI would need — 3px of padding reads as zero in বাংলা.

   Three rules this file keeps:
     1. **Tokens, never literals.** A hex code in a component is a colour that
        will not follow the theme, and dark mode is where that shows up.
     2. **Both themes for every colour.** A token defined only under one of
        them is a white-on-white label waiting to happen.
     3. **The inbox layout block is load-bearing** — `minmax(0,1fr)` and the
        `min-height: 0`s are what make the thread scroll instead of the page.
        Read the comment there before touching any of it.
   ========================================================================== */

:root {
  /* brand: a deep WhatsApp-adjacent teal-green, calmer than the logo green */
  --brand-50:  #e8f7f4;
  --brand-100: #c6ece4;
  --brand-200: #9adfd1;
  --brand-300: #5cc9b6;
  --brand-400: #26b39c;
  --brand-500: #12a18c;
  --brand-600: #0e8375;
  --brand-700: #0b6b60;
  --brand-800: #085449;
  --brand-ink: #06413a;

  /* used once each, on purpose: a highlight that appears everywhere stops
     meaning "look here" */
  --accent:    #f59e0b;
  --accent-50: #fef4e2;

  --ok:    #16a34a;
  --warn:  #d97706;
  --danger:#dc2626;
  --info:  #2563eb;

  --bg:        #f4f6f6;
  --surface:   #ffffff;
  --surface-2: #fafcfb;
  --sunken:    #eef1f1;
  --border:    #e2e7e7;
  --border-strong: #cbd4d3;
  --glass:     rgba(255, 255, 255, .78);

  --text:   #101a19;
  --text-2: #55655f;
  --text-3: #8a9995;
  --ring:   rgba(18, 161, 140, .28);

  --bubble-out: #d9fdd3;
  --bubble-out-ink: #103a2c;
  --bubble-in: #ffffff;

  --radius:    14px;
  --radius-sm: 10px;
  --radius-lg: 20px;

  --shadow-sm: 0 1px 2px rgba(10, 30, 27, .05), 0 1px 1px rgba(10, 30, 27, .03);
  --shadow:    0 4px 14px rgba(10, 30, 27, .07), 0 1px 3px rgba(10, 30, 27, .05);
  --shadow-lg: 0 20px 46px rgba(10, 30, 27, .16), 0 4px 12px rgba(10, 30, 27, .07);
  --shadow-brand: 0 6px 18px rgba(14, 131, 117, .26);

  --sidebar-w: 248px;
  --topbar-h: 62px;

  --font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  --font-bn: 'Hind Siliguri', 'Noto Sans Bengali', var(--font);
  --mono: ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, monospace;

  color-scheme: light;
}

:root[data-theme="dark"] {
  --bg:        #0d1413;
  --surface:   #151d1c;
  --surface-2: #1a2321;
  --sunken:    #101816;
  --border:    #253130;
  --border-strong: #35443f;
  --glass:     rgba(21, 29, 28, .78);

  --text:   #e9f1ef;
  --text-2: #9db0ac;
  --text-3: #6d817d;
  --ring:   rgba(92, 201, 182, .30);

  --brand-50:  #0d2b27;
  --brand-100: #113b34;
  --brand-200: #16544a;
  --accent-50: #33260c;
  --bubble-out: #075e54;
  --bubble-out-ink: #e8efed;
  --bubble-in: #1f2a28;

  --shadow-sm: 0 1px 2px rgba(0,0,0,.4);
  --shadow:    0 4px 16px rgba(0,0,0,.45);
  --shadow-lg: 0 22px 50px rgba(0,0,0,.6);
  --shadow-brand: 0 6px 20px rgba(0, 0, 0, .5);

  color-scheme: dark;
}

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: 14.5px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

/* বাংলা needs the extra room; the whole app switches with one attribute. */
body[data-lang="bn"] { font-family: var(--font-bn); line-height: 1.75; }

h1, h2, h3, h4 { margin: 0; font-weight: 650; line-height: 1.35; letter-spacing: -.01em; }
h1 { font-size: 22px; }
h2 { font-size: 17px; }
h3 { font-size: 15px; }
p  { margin: 0 0 10px; }
a  { color: var(--brand-600); text-decoration: none; }
a:hover { text-decoration: underline; }

.muted    { color: var(--text-2); }
.dim      { color: var(--text-3); }
.small    { font-size: 12.5px; }
.mono     { font-family: var(--mono); font-size: 12.5px; }
.nowrap   { white-space: nowrap; }
.right    { text-align: right; }
.center   { text-align: center; }
.grow     { flex: 1; }
.hidden   { display: none !important; }
.row      { display: flex; align-items: center; gap: 10px; }
.row.wrap { flex-wrap: wrap; }
.col      { display: flex; flex-direction: column; gap: 10px; }
.between  { justify-content: space-between; }
.spacer   { flex: 1; }

/* ------------------------------------------------------------------ layout */
.app { display: grid; grid-template-columns: var(--sidebar-w) 1fr; min-height: 100vh; }

.sidebar {
  background: var(--surface);
  border-right: 1px solid var(--border);
  display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh; overflow-y: auto;
}

.brand {
  display: flex; align-items: center; gap: 10px;
  padding: 18px 18px 14px; font-weight: 700; font-size: 15.5px;
  letter-spacing: -.02em;
}
.brand-mark {
  width: 30px; height: 30px; border-radius: 9px; flex: 0 0 auto;
  background: linear-gradient(140deg, var(--brand-500), var(--brand-700));
  display: grid; place-items: center; color: #fff; font-size: 15px;
  box-shadow: var(--shadow-sm);
}

.nav { padding: 4px 10px 16px; display: flex; flex-direction: column; gap: 2px; }
.nav-label {
  font-size: 10.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .09em; color: var(--text-3);
  padding: 16px 10px 6px;
}
.nav-item {
  display: flex; align-items: center; gap: 11px;
  padding: 9px 11px; border-radius: var(--radius-sm);
  color: var(--text-2); font-weight: 500; font-size: 14px;
  cursor: pointer; border: none; background: none; width: 100%;
  text-align: start; font-family: inherit; line-height: 1.5;
  transition: background .12s, color .12s;
}
.nav-item:hover { background: var(--sunken); color: var(--text); text-decoration: none; }
.nav-item.active { background: var(--brand-50); color: var(--brand-700); font-weight: 600; }
:root[data-theme="dark"] .nav-item.active { color: var(--brand-300); }
.nav-item .ico { width: 18px; text-align: center; flex: 0 0 auto; font-size: 15px; }
.nav-item .pill {
  margin-inline-start: auto; background: var(--danger); color: #fff;
  font-size: 11px; font-weight: 700; padding: 1px 7px; border-radius: 999px;
}

.balance-card {
  margin: auto 12px 12px; padding: 14px;
  border-radius: var(--radius); border: 1px solid var(--border);
  background: linear-gradient(150deg, var(--brand-50), var(--surface));
}
.balance-card .n { font-size: 24px; font-weight: 700; letter-spacing: -.02em; line-height: 1.2; }

.main { min-width: 0; display: flex; flex-direction: column; }

.topbar {
  height: var(--topbar-h); flex: 0 0 auto;
  display: flex; align-items: center; gap: 12px;
  padding: 0 22px; background: var(--surface);
  border-bottom: 1px solid var(--border);
  position: sticky; top: 0; z-index: 30;
}
.page { padding: 22px; max-width: 1240px; width: 100%; }
.page-wide { max-width: none; }

/* ----------------------------------------------------------------- surfaces */
.card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow-sm);
}
.card-pad { padding: 18px; }
.card-head {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 18px; border-bottom: 1px solid var(--border);
}
.card-head h2 { flex: 1; }

.grid { display: grid; gap: 14px; }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

/* stat tile: one number, one label, no chartjunk */
.stat { padding: 16px 18px; }
.stat .label {
  font-size: 11.5px; font-weight: 650; text-transform: uppercase;
  letter-spacing: .07em; color: var(--text-3); margin-bottom: 6px;
}
.stat .value { font-size: 27px; font-weight: 700; letter-spacing: -.025em; line-height: 1.15; }
.stat .sub { font-size: 12.5px; color: var(--text-2); margin-top: 3px; }
.stat.accent { background: linear-gradient(150deg, var(--brand-50), var(--surface)); }

/* ------------------------------------------------------------------ inputs */
.field { display: flex; flex-direction: column; gap: 6px; }
.field > label { font-size: 12.5px; font-weight: 600; color: var(--text-2); }
.field .hint { font-size: 12px; color: var(--text-3); }

.input, .select, .textarea {
  width: 100%; padding: 10px 13px;
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--text);
  font: inherit; line-height: 1.6;
  transition: border-color .12s, box-shadow .12s;
}
.textarea { min-height: 110px; resize: vertical; }
.input:focus, .select:focus, .textarea:focus {
  outline: none; border-color: var(--brand-500);
  box-shadow: 0 0 0 3px var(--brand-50);
}
.input::placeholder, .textarea::placeholder { color: var(--text-3); }
.input:disabled, .select:disabled, .textarea:disabled {
  background: var(--sunken); color: var(--text-3); cursor: not-allowed;
}
.select { appearance: none; padding-inline-end: 34px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%238b9a98' d='M1 1l5 5 5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 12px center; }

.switch { position: relative; display: inline-block; width: 40px; height: 23px; flex: 0 0 auto; }
.switch input { opacity: 0; width: 0; height: 0; }
.switch .track {
  position: absolute; inset: 0; background: var(--border-strong);
  border-radius: 999px; transition: background .16s; cursor: pointer;
}
.switch .track::before {
  content: ''; position: absolute; height: 17px; width: 17px; left: 3px; top: 3px;
  background: #fff; border-radius: 50%; transition: transform .16s;
  box-shadow: var(--shadow-sm);
}
.switch input:checked + .track { background: var(--brand-500); }
.switch input:checked + .track::before { transform: translateX(17px); }

/* ----------------------------------------------------------------- buttons */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 10px 17px; border-radius: var(--radius-sm);
  border: 1px solid transparent; background: var(--brand-600); color: #fff;
  font: inherit; font-weight: 600; font-size: 14px; line-height: 1.5;
  cursor: pointer; white-space: nowrap;
  transition: background .12s, border-color .12s, transform .06s, opacity .12s;
}
.btn:hover { background: var(--brand-700); text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .5; cursor: not-allowed; transform: none; }
.btn.ghost { background: var(--surface); border-color: var(--border-strong); color: var(--text); }
.btn.ghost:hover { background: var(--sunken); }
.btn.subtle { background: var(--sunken); color: var(--text); }
.btn.subtle:hover { background: var(--border); }
.btn.danger { background: var(--danger); }
.btn.danger:hover { background: #b91c1c; }
.btn.sm { padding: 6px 12px; font-size: 13px; border-radius: 7px; }
.btn.lg { padding: 13px 24px; font-size: 15px; }
.btn.block { width: 100%; }
.btn.icon { padding: 8px; width: 34px; }

/* ------------------------------------------------------------------ badges */
.badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 10px; border-radius: 999px;
  font-size: 12px; font-weight: 600; line-height: 1.6;
  background: var(--sunken); color: var(--text-2);
}
.badge.ok     { background: #dcfce7; color: #15803d; }
.badge.warn   { background: #fef3c7; color: #b45309; }
.badge.danger { background: #fee2e2; color: #b91c1c; }
.badge.info   { background: #dbeafe; color: #1d4ed8; }
.badge.brand  { background: var(--brand-50); color: var(--brand-700); }
:root[data-theme="dark"] .badge.ok     { background: #14321f; color: #6ee7a8; }
:root[data-theme="dark"] .badge.warn   { background: #3a2a10; color: #fbbf24; }
:root[data-theme="dark"] .badge.danger { background: #3b1618; color: #fca5a5; }
:root[data-theme="dark"] .badge.info   { background: #16233f; color: #93b4fd; }
:root[data-theme="dark"] .badge.brand  { background: var(--brand-100); color: var(--brand-300); }

.dot { width: 8px; height: 8px; border-radius: 50%; background: var(--text-3); flex: 0 0 auto; }
.dot.ok { background: var(--ok); box-shadow: 0 0 0 3px rgba(22,163,74,.16); }
.dot.warn { background: var(--warn); }
.dot.danger { background: var(--danger); }

.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 9px; border-radius: 7px; background: var(--sunken);
  border: 1px solid var(--border); font-size: 12.5px; color: var(--text-2);
}
.chip button { border: none; background: none; cursor: pointer; color: var(--text-3); padding: 0; font-size: 14px; }
.chip.on { background: var(--brand-50); border-color: var(--brand-300); color: var(--brand-700); }

/* ------------------------------------------------------------------ tables */
.table-wrap { overflow-x: auto; }
table.table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.table th {
  text-align: start; font-size: 11.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .06em; color: var(--text-3);
  padding: 10px 14px; border-bottom: 1px solid var(--border); white-space: nowrap;
}
.table td { padding: 12px 14px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.table tr:last-child td { border-bottom: none; }
.table tbody tr:hover { background: var(--surface-2); }
.table td.num, .table th.num { text-align: end; font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------------- inbox */
/* 🔴 `grid-template-rows` and the `min-height: 0`s below are what make the
   thread scroll instead of the page. A grid row left implicit is `auto`, and an
   `auto` row is at least as tall as its content — for a 50-message thread that
   is nine thousand pixels, so the row grew, `.chat-pane`'s `height: 100%`
   grew with it, the pane never overflowed and so never scrolled, and the whole
   document got longer with the composer pushed off the bottom. Same trap as a
   grid item's `min-width: auto`, one axis over.
   `dvh` after `vh`: on a phone `100vh` is the viewport with the browser's own
   toolbars *hidden*, which hides the composer behind them. */
.inbox {
  display: grid; grid-template-columns: 320px 1fr; grid-template-rows: minmax(0, 1fr);
  height: calc(100vh - var(--topbar-h));
  height: calc(100dvh - var(--topbar-h));
  overflow: hidden;
}
.inbox-list {
  border-right: 1px solid var(--border); overflow-y: auto; background: var(--surface);
  min-height: 0; overscroll-behavior: contain;
}
.inbox-search { padding: 12px; border-bottom: 1px solid var(--border); position: sticky; top: 0; background: var(--surface); z-index: 2; }
.conv {
  display: flex; gap: 11px; padding: 12px 14px; cursor: pointer;
  border-bottom: 1px solid var(--border);
}
.conv:hover { background: var(--surface-2); }
.conv.active { background: var(--brand-50); }
:root[data-theme="dark"] .conv.active { background: var(--brand-100); }
.conv .avatar {
  width: 40px; height: 40px; border-radius: 50%; flex: 0 0 auto;
  background: linear-gradient(140deg, var(--brand-300), var(--brand-600));
  color: #fff; display: grid; place-items: center; font-weight: 650; font-size: 15px;
}
.conv .who { font-weight: 600; font-size: 14px; }
.conv .prev {
  color: var(--text-2); font-size: 13px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 200px;
}

.thread {
  flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch; padding: 20px 24px;
  background: var(--sunken);
  background-image: radial-gradient(var(--border) .5px, transparent .5px);
  background-size: 18px 18px;
}
.chat-pane { display: flex; flex-direction: column; min-width: 0; min-height: 0; height: 100%; }
.chat-head {
  display: flex; align-items: center; gap: 12px; padding: 12px 20px;
  border-bottom: 1px solid var(--border); background: var(--surface); flex: 0 0 auto;
}
.bubble {
  max-width: min(66%, 560px); padding: 9px 13px; border-radius: 14px;
  margin-bottom: 9px; font-size: 14px; line-height: 1.6;
  box-shadow: var(--shadow-sm); word-wrap: break-word; white-space: pre-wrap;
}
.bubble.in  { background: var(--bubble-in); border-bottom-left-radius: 4px; }
.bubble.out {
  background: var(--bubble-out); color: var(--bubble-out-ink);
  margin-inline-start: auto; border-bottom-right-radius: 4px;
}
.bubble .meta {
  font-size: 10.5px; color: var(--text-3); margin-top: 4px;
  display: flex; gap: 5px; justify-content: flex-end; align-items: center;
}
.bubble.out .meta { color: rgba(16,58,44,.55); }
:root[data-theme="dark"] .bubble.out .meta { color: rgba(232,239,237,.55); }
/* The "older messages" row sits above the first bubble, not over it: a sticky
   button would cover the message a reader scrolled up to find. */
.thread-top { display: flex; justify-content: center; padding: 2px 0 12px; }
/* Sticky inside the scroller, so it sits above the newest bubble whatever
   height the composer below it happens to have. */
.new-pill {
  position: sticky; bottom: 4px; display: block; margin: 6px auto 0;
  box-shadow: var(--shadow); border-radius: 999px;
}
.day-sep { text-align: center; margin: 14px 0; }
.day-sep span {
  background: var(--surface); border: 1px solid var(--border);
  padding: 3px 12px; border-radius: 999px; font-size: 11.5px; color: var(--text-2);
}
.composer {
  display: flex; gap: 10px; padding: 12px 16px; align-items: flex-end;
  border-top: 1px solid var(--border); background: var(--surface); flex: 0 0 auto;
}
.composer .textarea { min-height: 44px; max-height: 140px; }

/* ------------------------------------------------------------------ modals */
.modal-backdrop {
  position: fixed; inset: 0; background: rgba(9,20,18,.5);
  display: grid; place-items: center; z-index: 100; padding: 20px;
  backdrop-filter: blur(2px);
}
.modal {
  background: var(--surface); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg); width: 100%; max-width: 520px;
  max-height: 90vh; display: flex; flex-direction: column;
  animation: pop .16s ease-out;
}
.modal.wide { max-width: 780px; }
@keyframes pop { from { opacity: 0; transform: translateY(8px) scale(.99); } }
.modal-head { padding: 18px 20px 12px; display: flex; align-items: center; gap: 12px; }
.modal-body { padding: 0 20px 4px; overflow-y: auto; display: flex; flex-direction: column; gap: 14px; }
.modal-foot {
  padding: 16px 20px; display: flex; gap: 10px; justify-content: flex-end;
  border-top: 1px solid var(--border); margin-top: 14px;
}

/* ------------------------------------------------------------------ toasts */
.toasts {
  position: fixed; bottom: 20px; inset-inline-end: 20px;
  display: flex; flex-direction: column; gap: 10px; z-index: 200; max-width: 380px;
}
.toast {
  background: var(--surface); border: 1px solid var(--border);
  border-inline-start: 3px solid var(--brand-500);
  border-radius: var(--radius-sm); box-shadow: var(--shadow-lg);
  padding: 12px 15px; font-size: 13.5px; animation: slide .18s ease-out;
}
.toast.error { border-inline-start-color: var(--danger); }
.toast.ok    { border-inline-start-color: var(--ok); }
@keyframes slide { from { opacity: 0; transform: translateX(16px); } }

/* ------------------------------------------------------------------- misc */
.empty { padding: 48px 24px; text-align: center; color: var(--text-2); }
.empty .ico { font-size: 34px; opacity: .5; display: block; margin-bottom: 10px; }
.empty h3 { margin-bottom: 6px; color: var(--text); }

.skeleton {
  background: linear-gradient(90deg, var(--sunken) 25%, var(--border) 50%, var(--sunken) 75%);
  background-size: 200% 100%; animation: shimmer 1.3s infinite; border-radius: 6px;
}
@keyframes shimmer { to { background-position: -200% 0; } }

.progress { height: 7px; background: var(--sunken); border-radius: 999px; overflow: hidden; }
.progress > i { display: block; height: 100%; background: var(--brand-500); transition: width .3s; }

.tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border); }
.tab {
  padding: 9px 14px; border: none; background: none; cursor: pointer;
  font: inherit; font-weight: 600; font-size: 13.5px; color: var(--text-2);
  border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.tab.active { color: var(--brand-700); border-bottom-color: var(--brand-500); }
:root[data-theme="dark"] .tab.active { color: var(--brand-300); }

.qr-box {
  display: grid; place-items: center; gap: 14px; padding: 22px;
  background: var(--sunken); border-radius: var(--radius); text-align: center;
}
.qr-box img { width: 240px; height: 240px; border-radius: 10px; background: #fff; padding: 8px; }

pre.code {
  background: var(--sunken); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 14px; overflow-x: auto;
  font-family: var(--mono); font-size: 12.5px; line-height: 1.65; margin: 0;
}

/* bar chart, drawn with divs — no chart library for fourteen bars */
.bars { display: flex; align-items: flex-end; gap: 6px; height: 120px; }
.bars .bar { flex: 1; display: flex; flex-direction: column; justify-content: flex-end; gap: 2px; height: 100%; }
.bars .bar i { display: block; background: var(--brand-500); border-radius: 3px 3px 0 0; min-height: 2px; }
.bars .bar i.fail { background: var(--danger); border-radius: 0; }
.bars .bar span { font-size: 10px; color: var(--text-3); text-align: center; }

/* -------------------------------------------------------------- auth pages */
.auth { display: grid; grid-template-columns: 1fr 1fr; min-height: 100vh; }
.auth-hero {
  background: linear-gradient(155deg, var(--brand-700), var(--brand-ink));
  color: #fff; padding: 48px; display: flex; flex-direction: column; justify-content: center; gap: 20px;
}
.auth-hero h1 { font-size: 32px; line-height: 1.25; max-width: 15ch; }
.auth-hero ul { list-style: none; padding: 0; margin: 0; display: grid; gap: 12px; }
.auth-hero li { display: flex; gap: 11px; align-items: flex-start; opacity: .92; font-size: 14.5px; }
.auth-form { display: grid; place-items: center; padding: 40px 24px; }
.auth-form .inner { width: 100%; max-width: 372px; display: flex; flex-direction: column; gap: 14px; }

/* --------------------------------------------------------------- responsive */
.mobile-nav { display: none; }
.hamburger { display: none; }

@media (max-width: 1000px) {
  .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .auth { grid-template-columns: 1fr; }
  .auth-hero { display: none; }
}

@media (max-width: 820px) {
  .app { grid-template-columns: 1fr; }
  .sidebar {
    position: fixed; inset-block: 0; inset-inline-start: 0; width: 270px; z-index: 60;
    transform: translateX(-100%); transition: transform .2s; box-shadow: var(--shadow-lg);
  }
  body[data-drawer="open"] .sidebar { transform: none; }
  body[data-drawer="open"]::after {
    content: ''; position: fixed; inset: 0; background: rgba(9,20,18,.45); z-index: 50;
  }
  .hamburger { display: inline-flex; }
  .page { padding: 16px; padding-bottom: 86px; }
  .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }

  .inbox {
    grid-template-columns: 1fr;
    height: calc(100vh - var(--topbar-h) - 62px);
    height: calc(100dvh - var(--topbar-h) - 62px);
  }
  .inbox[data-pane="chat"] .inbox-list { display: none; }
  .inbox[data-pane="list"] .chat-pane { display: none; }

  .mobile-nav {
    display: flex; position: fixed; inset-inline: 0; bottom: 0; z-index: 40;
    background: var(--surface); border-top: 1px solid var(--border);
    padding: 6px 4px calc(6px + env(safe-area-inset-bottom));
  }
  .mobile-nav a {
    flex: 1; display: flex; flex-direction: column; align-items: center; gap: 2px;
    padding: 6px 2px; font-size: 10.5px; color: var(--text-3); font-weight: 600;
  }
  .mobile-nav a.active { color: var(--brand-600); }
  .mobile-nav a:hover { text-decoration: none; }
  .mobile-nav .ico { font-size: 18px; }
  .bubble { max-width: 84%; }
  .modal-foot { flex-direction: column-reverse; }
  .modal-foot .btn { width: 100%; }
}

@media print {
  .sidebar, .topbar, .mobile-nav, .btn { display: none !important; }
  .page { padding: 0; }
  /* browsers drop backgrounds when printing unless told otherwise */
  * { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}

/* A balance low enough to stop sending shortly should not look like good news. */
.balance-card.low { border-color: var(--danger); background: linear-gradient(150deg, #fff1f1, var(--surface)); }
:root[data-theme="dark"] .balance-card.low { background: linear-gradient(150deg, #2a1516, var(--surface)); }
.balance-card.low .n { color: var(--danger); }

/* Delivered is a different fact from accepted, so it is a different colour:
   the green segment is what WhatsApp confirmed, the brand segment is what we
   handed over and have not heard back about. One bar, three honest parts. */
.bars .bar i.ok { background: var(--ok); border-radius: 0; }

/* Label/value pairs in a detail panel. */
.kv { display: grid; grid-template-columns: max-content 1fr; gap: 6px 16px; font-size: 13.5px; }
.kv dt { color: var(--text-3); }
.kv dd { color: var(--text); word-break: break-word; }

/* A filter bar that wraps on a phone instead of pushing the page sideways. */
.filters { display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-end; }
.filters .field { flex: 1 1 150px; min-width: 0; }

/* The step-by-step of one message: queued -> sent -> delivered -> read. */
.steps { display: flex; flex-direction: column; gap: 0; }
.steps .step { display: flex; gap: 10px; align-items: flex-start; padding: 6px 0; }
.steps .step .dot { margin-top: 5px; flex: 0 0 auto; }
.steps .step.todo { opacity: .45; }

/* The conversation inside the message-detail modal. Same bubbles as the inbox,
   but boxed: a customer with 30 messages must not push the reply box off screen. */
.thread-mini {
  max-height: 300px; min-height: 120px; border: 1px solid var(--border);
  border-radius: 10px; padding: 12px 14px; flex: none;
}

/* ------------------------------------------------------------------- media
   Photos, videos and files: the attachment picker, the library sheet, and the
   way an attachment appears inside a chat bubble. Thumbnails are square and
   cropped so a portrait product photo and a landscape one line up in the grid
   instead of making the row jump. */
.media-icon {
  display: inline-grid; place-items: center;
  background: var(--sunken); border: 1px solid var(--border);
  border-radius: var(--radius-sm); color: var(--text-2);
  font-size: 18px; line-height: 1;
}

.attach { display: flex; flex-direction: column; gap: 8px; }
.attach .attached {
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface-2); padding: 8px 10px;
}

.media-grid {
  display: grid; gap: 10px;
  grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
}
.media-tile {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 8px; background: var(--surface); cursor: pointer;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  font: inherit; color: inherit; text-align: center; min-width: 0;
}
.media-tile:hover { border-color: var(--brand-500); }
.media-tile > span { max-width: 100%; }

/* Capped, not scaled to fit: a tall photo that filled the whole thread would
   push the message it is a caption for off the screen. */
.bubble-media {
  display: block; max-width: 100%; max-height: 260px;
  border-radius: var(--radius-sm); margin-bottom: 6px; object-fit: cover;
}
.bubble-file {
  display: flex; align-items: center; gap: 8px; margin-bottom: 6px;
  padding: 8px 10px; border-radius: var(--radius-sm);
  background: rgba(0, 0, 0, .05); color: inherit; text-decoration: none;
}
.bubble-file .media-icon { width: 32px; height: 32px; background: transparent; }
:root[data-theme="dark"] .bubble-file { background: rgba(255, 255, 255, .06); }

/* The composer keeps its own row; the picker sits above it so attaching a
   photo never squeezes the text box a person is typing in. */
.composer-wrap { flex: 0 0 auto; }
.composer-attach:not(:empty) {
  padding: 10px 16px 0; border-top: 1px solid var(--border); background: var(--surface);
}
.composer-attach + .composer { border-top: none; }

/* =============================================================================
   2.4 — the visual refresh
   Everything below is a *re-skin*: not one class name changed, so the eighteen
   views keep working untouched. Rules here deliberately come last so they win
   over the originals above without those needing to be picked apart.
   ========================================================================== */

/* ------------------------------------------------------------ focus & motion */
/* Focus is a keyboard user's cursor. `:focus-visible`, not `:focus`, so a mouse
   click on a button does not leave a ring behind it. */
:where(a, button, .btn, .tab, [tabindex]):focus-visible {
  outline: 2px solid var(--brand-500);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}
.input:focus, .select:focus, .textarea:focus {
  border-color: var(--brand-500);
  box-shadow: 0 0 0 3px var(--ring);
}

/* Everything that moves below is decoration. Somebody who has asked their
   operating system to stop things moving has usually asked for a reason. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important; scroll-behavior: auto !important;
  }
}

/* -------------------------------------------------------------- unsaved work */
/* The line that says a draft came back. It has to be impossible to miss and
   impossible to mistake for the form's own content — a form that silently
   fills itself in reads as stale data, and the person cannot tell which. */
.draft-note {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px; border-radius: var(--radius-sm);
  background: var(--accent-50); border: 1px solid var(--accent);
  font-size: 13px; color: var(--text);
}
:root[data-theme="dark"] .draft-note { border-color: #7c5c17; }

/* ------------------------------------------------------------------- chrome */
.brand-mark {
  border-radius: 10px;
  background: linear-gradient(145deg, var(--brand-400), var(--brand-700));
  box-shadow: var(--shadow-brand);
}
.sidebar { background: var(--surface); }

/* The active row gets a bar in the gutter as well as a tint: on a phone in
   sunlight the tint alone is not a difference anybody can see. */
.nav-item { position: relative; padding: 10px 12px; }
.nav-item.active::before {
  content: ''; position: absolute; inset-inline-start: 0; top: 50%;
  transform: translateY(-50%); width: 3px; height: 20px; border-radius: 0 3px 3px 0;
  background: var(--brand-500);
}
.nav-item .ico {
  display: inline-grid; place-items: center; width: 24px; height: 24px;
  border-radius: 7px; font-size: 13px; background: var(--sunken); color: var(--text-2);
  transition: background .12s, color .12s;
}
.nav-item.active .ico { background: var(--brand-500); color: #fff; }
.nav-item:hover .ico { background: var(--border); }
.nav-item.active:hover .ico { background: var(--brand-600); }

.topbar {
  background: var(--glass);
  backdrop-filter: saturate(1.6) blur(10px);
  -webkit-backdrop-filter: saturate(1.6) blur(10px);
}

.balance-card {
  background: linear-gradient(150deg, var(--brand-50), var(--surface) 70%);
  box-shadow: var(--shadow-sm); transition: box-shadow .14s, transform .14s;
}
.balance-card:hover { box-shadow: var(--shadow); transform: translateY(-1px); }

/* ----------------------------------------------------------------- surfaces */
.card { box-shadow: var(--shadow-sm); }
.card-head { padding: 15px 18px; }
.stat { position: relative; overflow: hidden; }
/* A single hairline of brand along the top of a tile: enough to group the row
   as "ours" without four coloured boxes shouting at each other. */
.stat::after {
  content: ''; position: absolute; inset-inline: 0; top: 0; height: 2px;
  background: linear-gradient(90deg, var(--brand-400), transparent 70%);
  opacity: .8;
}
.stat.accent::after { opacity: 1; }

/* ------------------------------------------------------------------ buttons */
.btn {
  background: linear-gradient(180deg, var(--brand-500), var(--brand-600));
  box-shadow: var(--shadow-brand);
  border-radius: 10px;
}
.btn:hover { background: linear-gradient(180deg, var(--brand-600), var(--brand-700)); }
.btn.ghost, .btn.subtle { box-shadow: var(--shadow-sm); }
.btn.ghost:hover { border-color: var(--border-strong); }
.btn.danger { background: linear-gradient(180deg, #ef4444, var(--danger)); box-shadow: none; }
.btn.danger:hover { background: linear-gradient(180deg, var(--danger), #b91c1c); }
.btn.lg { border-radius: 12px; padding: 13px 26px; }

/* ------------------------------------------------------------------- inputs */
.input, .select, .textarea { border-radius: 10px; border-color: var(--border-strong); }
.field > label { color: var(--text-2); letter-spacing: .005em; }

/* ------------------------------------------------------------------- tables */
.table th { background: var(--surface-2); }
.table tbody tr { transition: background .1s; }

/* ------------------------------------------------------------------- modals */
.modal-backdrop { background: rgba(6, 16, 15, .55); backdrop-filter: blur(3px); }
.modal { border: 1px solid var(--border); }
.modal-head { padding: 18px 20px 10px; }
.modal-head h2 { font-size: 18px; }

/* -------------------------------------------------------------------- empty */
.empty .ico {
  display: inline-grid; place-items: center; width: 56px; height: 56px;
  margin: 0 auto 12px; border-radius: 16px; opacity: 1;
  background: var(--sunken); color: var(--text-3); font-size: 24px;
}

/* ============================================================== landing page
   `views/home.js`. It owns the whole viewport — a logged-out session is given
   no sidebar and no topbar — so this section sets its own scale rather than
   inheriting the dashboard's.
   ========================================================================== */
.lp { --lp-max: 1160px; display: block; }
.lp-wrap { width: 100%; max-width: var(--lp-max); margin: 0 auto; padding: 0 24px; }

/* ---- header */
.lp-nav {
  position: sticky; top: 0; z-index: 50;
  background: var(--glass); backdrop-filter: saturate(1.6) blur(12px);
  -webkit-backdrop-filter: saturate(1.6) blur(12px);
  border-bottom: 1px solid transparent; transition: border-color .2s, box-shadow .2s;
}
.lp.scrolled .lp-nav { border-bottom-color: var(--border); box-shadow: var(--shadow-sm); }
.lp-nav-in { display: flex; align-items: center; gap: 18px; height: 66px; }
.lp-logo { display: inline-flex; align-items: center; gap: 10px; font-size: 15.5px; letter-spacing: -.02em; }
.lp-logo b { font-weight: 700; white-space: nowrap; }
.lp-logo-link, .lp-logo-link:hover { color: var(--text); text-decoration: none; }
.lp-mark {
  display: grid; place-items: center; border-radius: 10px; flex: none; color: #fff;
  background: linear-gradient(145deg, var(--brand-400), var(--brand-700));
  box-shadow: var(--shadow-brand);
}
.lp-links { display: flex; gap: 4px; margin-inline-start: auto; }
.lp-links a {
  padding: 8px 12px; border-radius: 9px; color: var(--text-2);
  font-weight: 550; font-size: 14px;
}
.lp-links a:hover { background: var(--sunken); color: var(--text); text-decoration: none; }
.lp-nav-actions { display: flex; align-items: center; gap: 8px; }

/* ---- hero */
.lp-hero { position: relative; overflow: hidden; padding: 56px 0 0; }
/* Light bleeding in from off-screen. Two soft radial pools rather than a flat
   gradient wash, so the top of the page has a direction to it. */
.lp-aurora { position: absolute; inset: -20% -10% auto; height: 720px; pointer-events: none; }
.lp-aurora::before, .lp-aurora::after {
  content: ''; position: absolute; border-radius: 50%; filter: blur(80px); opacity: .5;
}
.lp-aurora::before {
  width: 620px; height: 620px; top: 0; inset-inline-start: -80px;
  background: radial-gradient(circle, var(--brand-300), transparent 65%);
}
.lp-aurora::after {
  width: 520px; height: 520px; top: 60px; inset-inline-end: -60px;
  background: radial-gradient(circle, var(--brand-100), transparent 62%);
}
:root[data-theme="dark"] .lp-aurora::before,
:root[data-theme="dark"] .lp-aurora::after { opacity: .30; }

.lp-hero-in {
  position: relative; display: grid; gap: 48px; align-items: center;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
  padding-bottom: 74px;   /* room for the fact strip to hang into */
}
.lp-pill {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 13px 6px 10px; border-radius: 999px;
  background: var(--surface); border: 1px solid var(--border);
  box-shadow: var(--shadow-sm); font-size: 12.5px; font-weight: 600; color: var(--text-2);
}
.lp-pill svg { color: var(--brand-600); }
.lp-hero-copy h1 {
  font-size: clamp(31px, 5.2vw, 52px); line-height: 1.14; letter-spacing: -.03em;
  margin: 20px 0 16px; font-weight: 750;
}
body[data-lang="bn"] .lp-hero-copy h1 { line-height: 1.28; letter-spacing: -.01em; }
.lp-grad {
  background: linear-gradient(100deg, var(--brand-500), var(--brand-700));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
:root[data-theme="dark"] .lp-grad {
  background: linear-gradient(100deg, var(--brand-300), var(--brand-400));
  -webkit-background-clip: text; background-clip: text;
}
.lp-lead { font-size: 16.5px; line-height: 1.72; color: var(--text-2); max-width: 56ch; }
.lp-cta-row { display: flex; flex-wrap: wrap; gap: 12px; margin: 26px 0 18px; }
.lp-cta-row.center { justify-content: center; }
.lp-fine {
  display: flex; gap: 8px; align-items: flex-start;
  font-size: 12.5px; color: var(--text-3); max-width: 46ch; margin: 0;
}
.lp-fine svg { flex: none; margin-top: 2px; }

/* ---- the phone in the hero */
.lp-hero-art { position: relative; display: grid; place-items: center; min-height: 400px; }
.lp-phone {
  width: 292px; border-radius: 30px; background: var(--surface);
  border: 1px solid var(--border); box-shadow: var(--shadow-lg);
  overflow: hidden; transform: rotate(-1.4deg);
}
.lp-phone-top {
  display: flex; align-items: center; gap: 10px; padding: 14px 16px;
  background: linear-gradient(150deg, var(--brand-600), var(--brand-800)); color: #fff;
}
.lp-phone-top b { display: block; font-size: 13.5px; }
.lp-phone-top i { font-style: normal; font-size: 11px; opacity: .75; }
.lp-avatar {
  width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center;
  background: rgba(255, 255, 255, .22); font-weight: 700; font-size: 14px; flex: none;
}
.lp-phone-body {
  padding: 16px 14px; display: flex; flex-direction: column; gap: 8px;
  background: var(--sunken);
  background-image: radial-gradient(var(--border) .5px, transparent .5px);
  background-size: 16px 16px;
}
.lp-bub {
  max-width: 84%; padding: 8px 12px; border-radius: 14px; font-size: 12.8px;
  line-height: 1.55; box-shadow: var(--shadow-sm);
}
.lp-bub.in { background: var(--bubble-in); border-bottom-left-radius: 4px; }
.lp-bub.out {
  background: var(--bubble-out); color: var(--bubble-out-ink);
  align-self: flex-end; border-bottom-right-radius: 4px;
}
.lp-phone-bar {
  display: flex; align-items: center; gap: 10px; padding: 11px 14px;
  background: var(--surface); border-top: 1px solid var(--border); color: var(--brand-600);
}
.lp-phone-bar > span {
  flex: 1; height: 26px; border-radius: 999px; background: var(--sunken);
  border: 1px solid var(--border);
}

/* The two cards floating off the phone. Absolute, and hidden below the width
   where they would land on top of the conversation instead of beside it. */
.lp-float {
  position: absolute; display: flex; align-items: center; gap: 10px;
  padding: 11px 14px; border-radius: 14px;
  background: var(--surface); border: 1px solid var(--border); box-shadow: var(--shadow-lg);
  animation: lp-bob 6s ease-in-out infinite;
}
.lp-float b { display: block; font-size: 14px; line-height: 1.3; }
.lp-float i { font-style: normal; font-size: 11.5px; color: var(--text-3); }
.lp-float-ico {
  display: grid; place-items: center; width: 34px; height: 34px; border-radius: 10px;
  background: var(--brand-50); color: var(--brand-600); flex: none;
}
.lp-float-ico.ok { background: #dcfce7; color: #15803d; }
:root[data-theme="dark"] .lp-float-ico.ok { background: #14321f; color: #6ee7a8; }
.lp-float-a { top: 12%; inset-inline-start: 0; animation-delay: -2s; }
.lp-float-b { bottom: -6px; inset-inline-end: 0; }
@keyframes lp-bob { 50% { transform: translateY(-9px); } }

/* ---- the three-fact strip under the hero */
/* Its own element, outside `.lp-hero`: the hero clips (the aurora would widen
   the page otherwise) and this card is meant to sit across the hero's bottom
   edge. `z-index` because it overlaps in both directions — the hero above it
   and the section below it are both painted later than its own background. */
.lp-strip-wrap { position: relative; z-index: 2; margin-top: -38px; }
.lp-strip {
  position: relative; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0; border: 1px solid var(--border); border-radius: var(--radius-lg);
  background: var(--surface); box-shadow: var(--shadow); overflow: hidden;
}
.lp-strip-item { display: flex; align-items: center; gap: 12px; padding: 18px 20px; }
.lp-strip-item + .lp-strip-item { border-inline-start: 1px solid var(--border); }
.lp-strip-item b { display: block; font-size: 14.5px; }
.lp-strip-item i { font-style: normal; font-size: 12.5px; color: var(--text-2); }
.lp-strip-ico {
  display: grid; place-items: center; width: 40px; height: 40px; border-radius: 12px;
  background: var(--brand-50); color: var(--brand-600); flex: none;
}

/* ---- sections */
.lp-section { padding: 84px 0 0; }
.lp-section:first-of-type { padding-top: 96px; }
.lp-head { max-width: 62ch; margin-bottom: 34px; }
.lp-kicker {
  display: inline-block; font-size: 11.5px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--brand-600); margin-bottom: 10px;
}
:root[data-theme="dark"] .lp-kicker { color: var(--brand-300); }
.lp-section h2 {
  font-size: clamp(24px, 3.4vw, 34px); line-height: 1.22; letter-spacing: -.025em;
  margin-bottom: 12px; font-weight: 720;
}
body[data-lang="bn"] .lp-section h2 { line-height: 1.38; letter-spacing: -.005em; }

/* Sections arrive as they are scrolled to. `.reveal` is only ever added by JS,
   and only when there is an IntersectionObserver to take it off again — a
   browser without one must not be left with a page of invisible sections.
   Three more ways out, because "content that is invisible until something
   fires" is a bad bet to take with the only page a stranger ever sees:
     - reduced motion turns the whole effect off rather than making it quick;
     - printing shows everything, since paper does not scroll;
     - and a `.reveal` that never received `.in` fades itself in after two
       seconds anyway, so a wedged observer costs an animation, not the page. */
.lp .reveal {
  opacity: 0; transform: translateY(14px);
  transition: opacity .5s ease, transform .5s ease;
  animation: lp-failsafe 0s linear 2s forwards;
}
.lp .reveal.in { opacity: 1; transform: none; animation: none; }
@keyframes lp-failsafe { to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .lp .reveal { opacity: 1; transform: none; animation: none; }
}
@media print {
  .lp .reveal { opacity: 1 !important; transform: none !important; animation: none !important; }
}

/* ---- how it works */
.lp-steps {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: 18px; grid-template-columns: repeat(3, minmax(0, 1fr));
  counter-reset: step;
}
.lp-step {
  position: relative; padding: 26px 22px 24px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-sm);
}
.lp-step-n {
  position: absolute; top: -14px; inset-inline-start: 22px;
  width: 30px; height: 30px; border-radius: 10px; display: grid; place-items: center;
  background: linear-gradient(145deg, var(--brand-500), var(--brand-700));
  color: #fff; font-weight: 700; font-size: 14px; box-shadow: var(--shadow-brand);
}
.lp-step-ico {
  display: grid; place-items: center; width: 46px; height: 46px; border-radius: 14px;
  background: var(--brand-50); color: var(--brand-600); margin: 10px 0 14px;
}
:root[data-theme="dark"] .lp-step-ico { color: var(--brand-300); }
.lp-step h3 { font-size: 16.5px; margin-bottom: 8px; }
.lp-step p { color: var(--text-2); font-size: 14px; line-height: 1.7; margin: 0; }

/* ---- feature cards */
.lp-cards { display: grid; gap: 16px; grid-template-columns: repeat(4, minmax(0, 1fr)); }
.lp-card {
  padding: 22px 20px; background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-sm);
  transition: transform .16s, box-shadow .16s, border-color .16s;
}
.lp-card:hover { transform: translateY(-3px); box-shadow: var(--shadow); border-color: var(--brand-200); }
.lp-card-ico {
  display: grid; place-items: center; width: 42px; height: 42px; border-radius: 12px;
  background: var(--brand-50); color: var(--brand-600); margin-bottom: 14px;
}
:root[data-theme="dark"] .lp-card-ico { color: var(--brand-300); }
.lp-card h3 { font-size: 15.5px; margin-bottom: 7px; }
.lp-card p { color: var(--text-2); font-size: 13.5px; line-height: 1.68; margin: 0; }

/* ---- ban-safety */
.lp-safe { padding-top: 84px; }
.lp-safe-in {
  display: grid; gap: 40px; align-items: center;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr);
  padding: 44px; border-radius: 26px;
  background: linear-gradient(150deg, var(--brand-50), var(--surface) 65%);
  border: 1px solid var(--border);
}
:root[data-theme="dark"] .lp-safe-in {
  background: linear-gradient(150deg, var(--brand-50), var(--surface) 70%);
}
.lp-safe-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.lp-safe-list li {
  display: flex; align-items: center; gap: 11px;
  padding: 13px 16px; border-radius: 12px; font-weight: 550; font-size: 14px;
  background: var(--surface); border: 1px solid var(--border); box-shadow: var(--shadow-sm);
}
.lp-safe-list svg { color: var(--brand-600); flex: none; }
:root[data-theme="dark"] .lp-safe-list svg { color: var(--brand-300); }

/* ---- pricing */
.lp-prices { display: grid; gap: 16px; grid-template-columns: repeat(4, minmax(0, 1fr)); }
.lp-prices.one { grid-template-columns: minmax(0, 420px); }
.lp-price {
  display: flex; flex-direction: column; gap: 8px;
  padding: 24px 22px; background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm);
}
.lp-price h3 { font-size: 15.5px; }
.lp-price p { margin: 0; }
.lp-price .btn { margin-top: auto; }
.lp-price-n { font-size: 30px; font-weight: 750; letter-spacing: -.03em; line-height: 1.2; }
.lp-price-c { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 13.5px; color: var(--text-2); }
/* The free card is the one a stranger can act on today, so it is the one that
   is allowed to look different. */
.lp-price-free {
  background: linear-gradient(155deg, var(--brand-600), var(--brand-800));
  border-color: transparent; color: #fff; box-shadow: var(--shadow-lg);
}
.lp-price-free h3 { color: #fff; }
.lp-price-free p { color: rgba(255, 255, 255, .84); font-size: 13.5px; line-height: 1.68; }
.lp-price-free .lp-card-ico { background: rgba(255, 255, 255, .16); color: #fff; }
.lp-price-free .btn { background: #fff; color: var(--brand-700); box-shadow: none; }
.lp-price-free .btn:hover { background: #eef8f6; }
.lp-note { margin-top: 16px; font-size: 12.5px; color: var(--text-3); }

/* ---- FAQ */
.lp-faq { display: grid; gap: 10px; max-width: 820px; }
.lp-faq details {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow-sm); overflow: hidden;
}
.lp-faq summary {
  display: flex; align-items: center; gap: 14px; cursor: pointer;
  padding: 16px 18px; font-weight: 600; font-size: 15px; list-style: none;
}
.lp-faq summary::-webkit-details-marker { display: none; }
.lp-chev {
  margin-inline-start: auto; color: var(--brand-600); font-size: 20px; font-weight: 400;
  line-height: 1; transition: transform .18s; flex: none;
}
.lp-faq details[open] .lp-chev { transform: rotate(45deg); }
.lp-faq details p {
  margin: 0; padding: 0 18px 18px; color: var(--text-2); font-size: 14px; line-height: 1.75;
}

/* ---- closing band + footer */
.lp-final {
  margin-top: 92px; padding: 76px 0; text-align: center; color: #fff;
  background: linear-gradient(150deg, var(--brand-600), var(--brand-ink));
}
.lp-final h2 { font-size: clamp(24px, 3.6vw, 36px); letter-spacing: -.025em; margin-bottom: 12px; }
.lp-final p { color: rgba(255, 255, 255, .84); max-width: 52ch; margin: 0 auto 6px; font-size: 16px; }
.lp-final .btn.ghost {
  background: transparent; border-color: rgba(255, 255, 255, .45); color: #fff; box-shadow: none;
}
.lp-final .btn.ghost:hover { background: rgba(255, 255, 255, .12); }
.lp-final .btn:not(.ghost) { background: #fff; color: var(--brand-700); box-shadow: none; }
.lp-final .btn:not(.ghost):hover { background: #eef8f6; }

.lp-foot { background: var(--surface); border-top: 1px solid var(--border); padding: 28px 0; }
.lp-foot-in { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; }
.lp-foot p { flex: 1; margin: 0; color: var(--text-3); min-width: 220px; }
.lp-foot nav { display: flex; gap: 16px; }
.lp-foot nav a { color: var(--text-2); font-size: 13.5px; }

/* ---- responsive */
@media (max-width: 980px) {
  .lp-hero-in { grid-template-columns: 1fr; gap: 34px; }
  .lp-hero-art { order: -1; min-height: 0; }
  .lp-float { display: none; }        /* they would land on the conversation */
  .lp-phone { transform: none; }
  .lp-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .lp-prices { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .lp-safe-in { grid-template-columns: 1fr; padding: 30px; }
  .lp-steps { grid-template-columns: 1fr; gap: 26px; }
  .lp-links { display: none; }
}

@media (max-width: 620px) {
  .lp-wrap { padding: 0 16px; }
  .lp-hero { padding-top: 32px; }
  .lp-section { padding-top: 60px; }
  .lp-cards, .lp-prices { grid-template-columns: 1fr; }
  .lp-strip { grid-template-columns: 1fr; }
  .lp-strip-item + .lp-strip-item { border-inline-start: none; border-top: 1px solid var(--border); }
  .lp-hide-sm { display: none; }
  .lp-logo { font-size: 13.5px; }   /* two words, one line, at 320px too */
  .lp-nav-in { gap: 10px; }
  .lp-cta-row .btn { width: 100%; }
  .lp-final { margin-top: 64px; padding: 56px 0; }
}

/* ------------------------------------------------------- login & signup page
   The same light as the landing page, so arriving from it does not feel like
   arriving at a different company's website. */
.auth-hero {
  position: relative; overflow: hidden;
  background: linear-gradient(155deg, var(--brand-600), var(--brand-ink));
}
.auth-hero::after {
  content: ''; position: absolute; width: 460px; height: 460px; border-radius: 50%;
  top: -140px; inset-inline-end: -140px; filter: blur(70px); opacity: .38;
  background: radial-gradient(circle, var(--brand-300), transparent 66%);
}
.auth-hero > * { position: relative; }
.auth-hero li span:first-child { color: var(--brand-300); }
.auth-form .inner { max-width: 392px; }

/* ------------------------------------------- tags, filters and bulk picking
   Added with the tag rework (v2.5). The contact book and the campaign composer
   share these classes on purpose: the two screens describe the same audience,
   so they have to look like the same idea. */

.chip.sm { padding: 1px 7px; font-size: 11.5px; }
/* The count that turns "vip" into "vip 12" — the difference between a chip a
   vendor is willing to click and one they are guessing about. */
.chip-n {
  font-size: 10.5px; font-weight: 700; padding: 0 5px; border-radius: 5px;
  background: var(--border); color: var(--text-3);
}
.chip.on .chip-n { background: var(--brand-300); color: var(--brand-700); }
/* "No tag" is not a tag, so it does not look like one. */
.chip.alt { border-style: dashed; }
button.chip { cursor: pointer; font-family: inherit; }
button.chip:hover { border-color: var(--brand-300); }

.tag-box {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  min-height: 40px; padding: 6px 8px; cursor: text;
  border: 1px solid var(--border); border-radius: 9px; background: var(--surface);
}
.tag-box:focus-within { border-color: var(--brand-500); box-shadow: 0 0 0 3px var(--brand-50); }
.tag-entry {
  flex: 1 1 120px; min-width: 90px; border: none; outline: none;
  background: none; color: var(--text); font: inherit; font-size: 13px; padding: 2px;
}
.tag-suggest:empty { display: none; }

.filter-more { border-top: 1px solid var(--border); padding-top: 12px; }
.btn.ghost.active { background: var(--brand-50); color: var(--brand-700); border-color: var(--brand-300); }
.btn.danger, .btn.ghost.danger { color: var(--danger); }
.btn.ghost.danger:hover { background: rgba(220, 38, 38, .08); }

/* The bar that appears once somebody is ticked. It sticks because the ticking
   happens further down a long table than the actions do, and a vendor who has
   selected forty people should not have to scroll back up to act on them. */
.bulkbar {
  position: sticky; top: 0; z-index: 3;
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  padding: 10px 14px; background: var(--brand-50);
  border-block: 1px solid var(--brand-300);
}
tr.picked > td { background: var(--brand-50); }

/* The "pick people" list inside the campaign composer. Its own scroller, so a
   200-row list does not push the Send button off the modal. */
.picklist {
  max-height: 260px; overflow-y: auto; margin-top: 8px;
  border: 1px solid var(--border); border-radius: 9px; background: var(--surface);
}
.pickrow {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 10px; border-bottom: 1px solid var(--border); cursor: pointer;
}
.pickrow:last-child { border-bottom: none; }
.pickrow:hover { background: var(--sunken); }

/* Six audience tabs do not fit one phone-width row. */
.tabs.wrap { flex-wrap: wrap; }

/* =============================================================================
   Pricing — the price list, and the packs a vendor buys from
   -----------------------------------------------------------------------------
   Both sides of the same number. `.calc` is the live sum under the admin's
   price form; `.pkg` is the card the vendor picks from. They share the type
   scale on purpose: the per-message figure is the largest thing in each, because
   it is the only number in either screen that can be compared at a glance.
   ========================================================================== */

/* Two colours that were being written as inline hex in views. Tokens, so dark
   mode follows — rule 1 at the top of this file. */
.ok-text   { color: var(--ok); font-weight: 600; }
.warn-text { color: var(--warn); font-weight: 600; }
:root[data-theme="dark"] .ok-text   { color: #6ee7a8; }
:root[data-theme="dark"] .warn-text { color: #fbbf24; }

/* ---- the admin's live sum */
.calc {
  display: flex; flex-direction: column; gap: 8px;
  padding: 14px 16px; border-radius: var(--radius);
  background: var(--brand-50); border: 1px solid var(--brand-200);
}
.calc-head {
  font-size: 11.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .06em; color: var(--brand-700);
}
.calc-hero { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
/* Wide enough that "প্রতি বার্তার খরচ" stays on one line next to the figure it
   labels; below the wrap point it is the whole row anyway. */
.calc-hero > :first-child { min-width: 150px; }
.calc-label { font-size: 12.5px; color: var(--text-2); }
.calc-big {
  font-size: 30px; font-weight: 750; letter-spacing: -.03em;
  line-height: 1.2; color: var(--brand-700); font-variant-numeric: tabular-nums;
}
.calc-side { flex: 1; min-width: 190px; display: flex; flex-direction: column; gap: 2px; font-size: 13px; }
.calc-side .row { gap: 12px; }
.calc-warn {
  padding: 8px 10px; border-radius: 9px;
  background: var(--surface); border: 1px solid var(--warn); color: var(--text);
}
.calc-empty { padding: 4px 0; }
:root[data-theme="dark"] .calc-big { color: var(--brand-300); }
:root[data-theme="dark"] .calc-head { color: var(--brand-300); }

/* ---- the vendor's packs
   A four-across grid that drops to two and then one. The chosen-pack card is
   raised rather than recoloured: on a screen that is already brand-green, one
   more green block reads as "disabled", not "recommended". */
.pkg-grid {
  display: grid; gap: 14px;
  grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
  align-items: stretch;
}
.pkg {
  position: relative; display: flex; flex-direction: column; gap: 4px;
  padding: 20px 18px 18px; text-align: start; cursor: pointer;
  background: var(--surface); color: inherit; font: inherit;
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  transition: transform .14s ease, box-shadow .14s ease, border-color .14s ease;
}
.pkg:hover { transform: translateY(-3px); box-shadow: var(--shadow); border-color: var(--brand-300); }
.pkg:focus-visible { outline: 3px solid var(--ring); outline-offset: 2px; }
.pkg-best { border-color: var(--brand-400); box-shadow: var(--shadow-brand); }
.pkg-ribbon {
  position: absolute; inset-block-start: -10px; inset-inline-start: 16px;
  padding: 3px 10px; border-radius: 999px;
  background: var(--brand-600); color: #fff;
  font-size: 11px; font-weight: 700; letter-spacing: .02em;
  box-shadow: var(--shadow-sm);
}
.pkg-name { font-size: 14.5px; font-weight: 650; }
/* The headline. Everything else on the card exists to explain this line. */
.pkg-per {
  display: flex; align-items: baseline; gap: 5px; margin: 6px 0 2px;
  font-variant-numeric: tabular-nums;
}
.pkg-per b { font-size: 28px; font-weight: 750; letter-spacing: -.03em; line-height: 1.15; color: var(--brand-700); }
.pkg-per span { font-size: 12.5px; color: var(--text-2); }
.pkg-credits { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; font-size: 13px; color: var(--text-2); }
.pkg-total { font-size: 15px; font-weight: 650; color: var(--text); }
.pkg-rule { height: 1px; background: var(--border); margin: 12px 0 10px; }
.pkg-taka { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.pkg-taka b { font-size: 19px; font-weight: 700; letter-spacing: -.02em; }
.pkg .btn { margin-top: 12px; }
:root[data-theme="dark"] .pkg-per b { color: var(--brand-300); }

.pkg-note { margin-top: 12px; font-size: 12.5px; color: var(--text-3); }

@media (max-width: 620px) {
  .pkg-grid { grid-template-columns: 1fr; }
  .calc-hero { gap: 10px; }
  .calc-big { font-size: 26px; }
}

/* =============================================================================
   MESSAGE MANAGER (/messages)
   A log of a few hundred rows that a shop owner reads on a phone, standing up.
   A table cannot do that — seven columns become a sideways scroll and the one
   column that matters (did it arrive, did they answer) ends up off screen. So
   every message is a card, and the card puts the status where the thumb is.

   Three things carry the meaning here:
     1. **A colour per delivery state**, used in exactly three places — the rail
        down the side of the card, the pill, and the pulse bar at the top — so
        the same green means the same thing wherever the eye lands.
     2. **A read message is washed green over its whole card.** Read is the good
        outcome and the one being scanned for; a badge alone is too small to
        find at arm's length.
     3. **The pulse bar is the filter.** Its segments and the legend chips under
        it are the same numbers, and pressing one narrows the list — so the
        summary is not a decoration you read and then re-type into a form.
   ========================================================================== */

/* The state palette. It lives here rather than at the top of the file because
   these seven colours have exactly one consumer, but both themes are defined —
   a token with only a light value is a white-on-white label waiting to happen. */
:root {
  --st-queued:    #6f7f7a;  --st-queued-soft:    #eceff0;
  --st-sending:   #2563eb;  --st-sending-soft:   #dbeafe;
  --st-sent:      #a97516;  --st-sent-soft:      #fbf1de;
  --st-delivered: #2f74a0;  --st-delivered-soft: #e4eff6;
  --st-read:      #0e8375;  --st-read-soft:      #e0f4ef;
  --st-failed:    #c2382b;  --st-failed-soft:    #fbe8e5;
  --st-canceled:  #97a5a1;  --st-canceled-soft:  #eef1f1;
  --st-reply:     #7a4e8c;  --st-reply-soft:     #f3ecf7;
  --st-read-tint: #f1faf6;  --st-read-edge:      #c9e8dd;
}
:root[data-theme="dark"] {
  --st-queued:    #93a19c;  --st-queued-soft:    #1e2a27;
  --st-sending:   #7ea8f8;  --st-sending-soft:   #17243c;
  --st-sent:      #d8a848;  --st-sent-soft:      #2e2717;
  --st-delivered: #6fadd0;  --st-delivered-soft: #152a34;
  --st-read:      #40b899;  --st-read-soft:      #10312a;
  --st-failed:    #e07a6c;  --st-failed-soft:    #33201d;
  --st-canceled:  #7d8d89;  --st-canceled-soft:  #1b2422;
  --st-reply:     #bd97d1;  --st-reply-soft:     #261e2e;
  --st-read-tint: #11241f;  --st-read-edge:      #1d453a;
}

/* ---- the pulse: one number, one bar, one row of chips --------------------- */
.mm-summary { margin-bottom: 14px; }
.mm-srow { display: flex; align-items: flex-end; gap: 18px; flex-wrap: wrap; }
.mm-total { display: flex; align-items: baseline; gap: 10px; min-width: 0; }
.mm-total .n {
  font-size: 40px; font-weight: 750; line-height: 1; letter-spacing: -.03em;
  font-variant-numeric: tabular-nums;
}
.mm-total .lbl { font-size: 13.5px; color: var(--text-3); }

.mm-range {
  display: flex; gap: 2px; padding: 3px; margin-inline-start: auto;
  background: var(--surface); border: 1px solid var(--border); border-radius: 11px;
}
.mm-range button {
  padding: 6px 13px; border: none; border-radius: 8px; background: none;
  font: inherit; font-size: 13.5px; color: var(--text-2); cursor: pointer; white-space: nowrap;
}
.mm-range button:hover { color: var(--text); }
.mm-range button[aria-pressed="true"] { background: var(--brand-600); color: #fff; font-weight: 600; }

/* The bar is the same six numbers as the chips, drawn to width. flex-grow is
   the count itself, so a state with none of them simply is not there. */
.mm-pulse { display: flex; gap: 3px; height: 10px; margin: 14px 0 12px; }
.mm-pulse i { display: block; border-radius: 3px; transition: flex-grow .45s cubic-bezier(.4,0,.2,1); }
.mm-pulse i:first-child { border-radius: 999px 3px 3px 999px; }
.mm-pulse i:last-child  { border-radius: 3px 999px 999px 3px; }
.mm-pulse.blank { background: var(--sunken); border-radius: 999px; }

/* On a phone the chips scroll sideways rather than stacking into six rows and
   pushing the actual messages below the fold. */
.mm-legend {
  display: flex; gap: 8px; overflow-x: auto; scrollbar-width: none;
  margin: 0 -16px; padding: 2px 16px 6px;
}
.mm-legend::-webkit-scrollbar { display: none; }
@media (min-width: 760px) { .mm-legend { margin: 0; padding-inline: 0; flex-wrap: wrap; overflow: visible; } }

.mm-chip {
  display: inline-flex; align-items: center; gap: 8px; flex: 0 0 auto;
  padding: 8px 13px; border-radius: 11px; cursor: pointer;
  background: var(--surface); border: 1px solid var(--border);
  font: inherit; font-size: 13.5px; color: var(--text-2); white-space: nowrap;
  transition: border-color .12s, background .12s;
}
.mm-chip:hover { border-color: var(--border-strong); }
.mm-chip .dot { width: 8px; height: 8px; border-radius: 999px; background: var(--st); }
.mm-chip b { font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; }
.mm-chip[aria-pressed="true"] {
  background: var(--surface-2); border-color: var(--st);
  box-shadow: inset 0 0 0 1px var(--st);
}

/* ---- toolbar -------------------------------------------------------------- */
.mm-toolbar {
  position: sticky; top: var(--topbar-h); z-index: 20;
  padding: 10px 0; margin-bottom: 2px;
  background: var(--bg);
}
.mm-tbar { display: flex; gap: 9px; align-items: center; }
.mm-search { flex: 1; min-width: 0; position: relative; display: flex; align-items: center; }
.mm-search svg {
  position: absolute; inset-inline-start: 12px; width: 16px; height: 16px;
  color: var(--text-3); pointer-events: none;
}
.mm-search .input { padding-inline-start: 38px; }
.mm-tbar .btn { position: relative; }
.mm-tbar .btn .count {
  min-width: 18px; height: 18px; padding: 0 5px; border-radius: 999px;
  background: var(--brand-600); color: #fff; font-size: 11px; font-weight: 700;
  display: grid; place-items: center;
}
.mm-tbar .btn.ghost .count { background: var(--brand-600); color: #fff; }

.mm-active { display: flex; flex-wrap: wrap; gap: 7px; padding: 8px 0 2px; }
.mm-fchip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 7px 4px 11px; border-radius: 9px; font-size: 12.5px;
  background: var(--brand-50); color: var(--brand-700); border: 1px solid var(--brand-200);
}
:root[data-theme="dark"] .mm-fchip { color: var(--brand-300); }
.mm-fchip button {
  width: 18px; height: 18px; border: none; border-radius: 5px; background: none;
  color: inherit; opacity: .6; cursor: pointer; display: grid; place-items: center; font-size: 13px;
}
.mm-fchip button:hover { opacity: 1; background: var(--brand-100); }
.mm-clearall {
  border: none; background: none; cursor: pointer; font: inherit; font-size: 12.5px;
  color: var(--text-3); text-decoration: underline; text-underline-offset: 3px; padding: 4px;
}

/* ---- the list ------------------------------------------------------------- */
.mm-dayhead {
  display: flex; align-items: center; gap: 12px;
  padding: 16px 2px 8px; font-size: 12.5px; font-weight: 650; color: var(--text-3);
}
.mm-dayhead::after { content: ''; flex: 1; height: 1px; background: var(--border); }
.mm-list { display: flex; flex-direction: column; gap: 8px; }

.mm-row {
  display: grid; grid-template-columns: 3px 1fr; overflow: hidden;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); cursor: pointer;
  transition: border-color .12s, box-shadow .12s;
}
.mm-row:hover { border-color: var(--border-strong); box-shadow: var(--shadow-sm); }
.mm-rail { background: var(--st); }
.mm-body { padding: 13px 15px; min-width: 0; }
.mm-main { min-width: 0; }

/* Read is the outcome being scanned for, so it gets the whole card, not a badge. */
.mm-row[data-state="read"] { background: var(--st-read-tint); border-color: var(--st-read-edge); }
.mm-row[data-state="read"] .mm-tag { background: var(--surface); }

.mm-top { display: flex; align-items: center; gap: 9px; margin-bottom: 4px; }
.mm-name {
  border: none; background: none; padding: 0; font: inherit; cursor: pointer;
  font-weight: 650; font-size: 14.5px; color: var(--text); text-align: start;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%;
}
.mm-name:hover { text-decoration: underline; }
.mm-phone { font-size: 13px; color: var(--text-3); white-space: nowrap; font-family: var(--mono); }
.mm-time { font-size: 12.5px; color: var(--text-3); white-space: nowrap; }

/* Two lines, then an ellipsis. A campaign message runs to 400 characters and
   would otherwise be the only thing on the screen. */
.mm-text {
  margin: 0; font-size: 14.5px; color: var(--text-2); line-height: 1.5;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.mm-text .dim { color: var(--text-3); }

.mm-meta { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; margin-top: 9px; }
.mm-pill {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 9px; border-radius: 7px;
  background: var(--st-soft); color: var(--st);
  font-size: 12px; font-weight: 650; white-space: nowrap;
}
.mm-tag {
  font-size: 12px; color: var(--text-3); padding: 4px 8px;
  border-radius: 7px; background: var(--sunken); max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.mm-tag .mono { font-family: var(--mono); }

/* What the customer wrote back — the only line on the card that says a human
   did something, so it is the only one with a colour of its own. */
.mm-reply {
  margin-top: 10px; padding: 8px 12px; border-radius: 10px;
  background: var(--st-reply-soft); border-inline-start: 2.5px solid var(--st-reply);
  font-size: 13.5px; color: var(--text-2);
}
.mm-reply b { display: block; font-size: 11.5px; font-weight: 700; color: var(--st-reply); }
.mm-err {
  margin-top: 10px; padding: 8px 12px; border-radius: 10px;
  background: var(--st-failed-soft); border-inline-start: 2.5px solid var(--st-failed);
  font-size: 13.5px; color: var(--text-2);
}
.mm-err b { display: block; font-size: 11.5px; font-weight: 700; color: var(--st-failed); }
.mm-noreply { display: inline-block; margin-top: 8px; font-size: 12px; color: var(--text-3); }

.mm-side { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 10px; }
.mm-acts { display: flex; gap: 6px; margin-inline-start: auto; }

/* Wide enough for a column of its own: statuses line up down the right edge, so
   twenty cards can be read as one list instead of twenty separate boxes. */
@media (min-width: 940px) {
  .mm-body {
    display: grid; grid-template-columns: minmax(0, 1fr) 200px;
    column-gap: 22px; align-items: start; padding: 14px 18px;
  }
  .mm-side {
    flex-direction: column; align-items: flex-end; text-align: end;
    gap: 7px; margin-top: 0;
  }
  .mm-acts { margin-inline-start: 0; }
}

.mm-foot { text-align: center; padding: 18px 0 4px; }
.mm-note { text-align: center; color: var(--text-3); font-size: 12.5px; padding: 22px 0 8px; }

/* Below this the toolbar buttons keep their icon and drop their word, because
   three labelled buttons plus a search box is a two-line toolbar on a phone. */
@media (max-width: 620px) {
  .mm-tbar .hide-sm { display: none; }
  .mm-tbar .btn { padding-inline: 12px; }
}

@media (max-width: 560px) {
  .mm-phone { display: none; }
  .mm-total .n { font-size: 32px; }
  .mm-range { margin-inline-start: 0; }
}

/* ---- the detail drawer ---------------------------------------------------- */
.mm-bubble {
  background: var(--bubble-out); color: var(--bubble-out-ink);
  border-radius: 14px 14px 14px 4px; padding: 12px 15px;
  font-size: 14.5px; line-height: 1.6; margin: 0 0 14px; white-space: pre-wrap;
}
.mm-dl { display: flex; justify-content: space-between; gap: 16px; padding: 8px 0; border-bottom: 1px solid var(--border); font-size: 13.5px; }
.mm-dl:last-child { border-bottom: none; }
.mm-dl dt { color: var(--text-3); margin: 0; }
.mm-dl dd { margin: 0; text-align: end; font-weight: 500; word-break: break-word; }
