/* ══════════════════════════════════════════════════════════
   Admin · Leads CRM list view (/admin/leads).

   Glass Campus surfaces on the --adm-* tokens declared by
   .admin-layout: hairline borders, cool-blue shadows, no raw
   black, and NO brand gradient - this is a work surface, and
   the shell already spends the page's one gradient on the
   active nav bar (same rule the WhatsApp inbox follows).

   Semantic colour is untouched on purpose: status hex comes
   from the DB at runtime, paid-blue, untouched green #22C55E
   and the red/amber/green chip triads all keep their exact
   values. Only the surfaces around them were modernised.

   Layout: one DOM, two shapes. Above 1024px this is a wide
   table; at or below it every row is a compact card that
   opens on demand. The card machinery (flex rows, data-label
   pseudo-labels) comes from admin.css via .reg-table; the
   order scheme and everything card-only lives at the bottom
   of this file.
   ══════════════════════════════════════════════════════════ */

/* The page island must NOT be a scroll container.

   admin.css puts .leads-page in the RTL "own horizontal scroller" group so a
   wide RTL table can overflow leftward and still be reachable from the LTR
   .admin-main. The cost is invisible and total: an ancestor with a non-visible
   overflow becomes the scrollport for every `position: sticky` inside it, and
   this one never scrolls vertically - so the toolbar and the bulk bar would
   simply never stick. The horizontal scroll moves down to .leads-table-wrap,
   which is the only wide thing on the page. */
.leads-page {
  overflow: visible;
}

.leads-table-wrap {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
}

/* ── KPI band: total · pipeline funnel · overdue ───── */

.leads-kpis {
  display: flex;
  align-items: stretch;
  flex-wrap: wrap;
  gap: 0.75rem;
  padding: 0.7rem 1rem;
  margin-bottom: 0.85rem;
  background: var(--adm-glass);
  -webkit-backdrop-filter: var(--adm-glass-blur);
  backdrop-filter: var(--adm-glass-blur);
  border: 1px solid var(--adm-glass-border);
  border-radius: 14px;
  box-shadow: var(--adm-glass-shadow);
}

/* Tiles are separated by a hairline rather than boxed in their own cards -
   fewer edges, and the band reads as one instrument instead of four. The
   transparent border is load-bearing: the active states colour it, and a tile
   that grew a border on activation would nudge the whole band sideways. */
.leads-kpi {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.15rem;
  min-width: 96px;
  padding: 0.35rem 0.9rem;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 12px;
}

.leads-kpi:not(:first-child) {
  border-inline-start-color: var(--adm-line);
  border-start-start-radius: 0;
  border-end-start-radius: 0;
}

/* Solid ink, weight 600. The brand gradient is forbidden on numerals at this
   weight and unwelcome on a work surface at any weight. */
.leads-kpi-value {
  font-size: 1.35rem;
  font-weight: 600;
  line-height: 1.1;
  color: var(--adm-ink);
  font-variant-numeric: tabular-nums;
}

.leads-kpi-label {
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--adm-ink-3);
  white-space: nowrap;
}

/* The overdue and untouched tiles double as filter toggles. */
button.leads-kpi {
  cursor: pointer;
  transition: border-color 0.15s, background-color 0.15s;
}

button.leads-kpi:hover {
  background: rgba(0, 113, 227, 0.05);
}

.leads-kpi--alert .leads-kpi-value {
  color: #b91c1c;
}

.leads-kpi--active {
  background: #fef2f2;
  border-color: #fca5a5;
  box-shadow: 0 0 0 1px #fca5a5;
}

/* The untouched tile filters too, but it is not an alarm - 60% of the book
   being untouched is a normal Monday, and painting that red would teach staff
   to ignore the colour that means "overdue". Active state takes the green of
   the row highlight it names, so tile and rows read as one thing. */
.leads-kpi--untouched.leads-kpi--active {
  background: color-mix(in srgb, #22c55e 8%, #fff);
  border-color: rgba(34, 197, 94, 0.5);
  box-shadow: 0 0 0 1px rgba(34, 197, 94, 0.5);
}

/* The awaiting tile takes the amber of the rows it names, the same way the
   untouched tile takes their green - press it and the band and the list agree
   about which colour the answer is wearing.

   Its number goes dark amber whenever anybody is waiting, and that is a step
   below the overdue tile's red on purpose: a queue with people in it is not an
   alarm (a message that arrived four minutes ago is in this count), while an
   overdue follow-up is a promise already broken. Two reds would flatten that
   difference, which is how a panel teaches staff to stop reading colour. */
.leads-kpi--waiting .leads-kpi-value {
  color: #b45309;
}

.leads-kpi--awaiting.leads-kpi--active {
  background: color-mix(in srgb, #f59e0b 12%, #fff);
  border-color: rgba(180, 83, 9, 0.55);
  box-shadow: 0 0 0 1px rgba(180, 83, 9, 0.55);
}

/* Display option, not a filter - so it is deliberately quiet: no tile chrome,
   no border, just the control and its name, sitting beside the tile it acts
   on. */
.leads-kpi-toggle {
  display: inline-flex;
  align-items: center;
  align-self: center;
  gap: 0.45rem;
  padding: 0.35rem 0.2rem;
  color: var(--adm-ink-2);
  font-size: 0.78rem;
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
}

.leads-kpi-toggle:hover {
  color: var(--adm-ink);
}

.leads-kpi-toggle input[type="checkbox"] {
  width: 16px;
  height: 16px;
  accent-color: #22c55e;
  cursor: pointer;
}

.leads-funnel {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  gap: 0.35rem;
  min-width: 0;
  overflow-x: auto;
  padding: 0.15rem 0 0.15rem 0;
  padding-inline-start: 0.75rem;
  border-inline-start: 1px solid var(--adm-line);
}

.leads-funnel-seg {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.1rem;
  flex: 0 0 auto;
  min-width: 88px;
  padding: 0.4rem 0.75rem;
  background: #fff;
  border: 1px solid var(--adm-line);
  border-radius: 12px;
  cursor: pointer;
  transition: border-color 0.15s, background-color 0.15s;
}

.leads-funnel-seg:hover {
  background: #f7faff;
  border-color: rgba(0, 113, 227, 0.35);
}

.leads-funnel-seg--active {
  background: #eff6ff;
  border-color: #93c5fd;
  box-shadow: 0 0 0 1px #93c5fd;
}

.leads-funnel-count {
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--adm-ink);
  font-variant-numeric: tabular-nums;
}

.leads-funnel-label {
  font-size: 0.68rem;
  font-weight: 600;
  color: var(--adm-ink-2);
  white-space: nowrap;
}

.leads-funnel-sep {
  flex: 0 0 auto;
  font-size: 0.65rem;
  color: #cbd5e1;
}

/* ── Status pill strip ────────────────────────────────
   Lifted out of the filter bar: status is the dimension staff triage by, and
   it is the one filter that stays on screen at every width - including under
   the phone toolbar, where everything else hides in the sheet. */

.leads-statusbar {
  margin-bottom: 0.7rem;
}

/* Both edges fade so a pill cut off by the scroll is visibly cut off rather
   than simply absent. The gradient is mirror-symmetric, which is why a
   physical `to right` is RTL-safe here - flipping it would produce the same
   mask. */
.leads-statuspills,
.leads-funnel {
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 28px, #000 calc(100% - 28px), transparent 100%);
  mask-image: linear-gradient(to right, transparent 0, #000 28px, #000 calc(100% - 28px), transparent 100%);
}

.leads-statuspills {
  padding-bottom: 0.15rem;
}

.leads-statuspills .reg-date-pill {
  min-height: 2.1rem;
  border-color: var(--adm-line);
}

.lead-status-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}

.lead-status-dot {
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 50%;
  flex: 0 0 auto;
}

/* ── Filter bar (desktop) ─────────────────────────────
   Hidden below 1024px, where .leads-toolbar and the filter sheet take over. */

.leads-filter-bar {
  background: #fff;
  border: 1px solid var(--adm-line);
  border-radius: 14px;
  box-shadow: 0 1px 3px rgba(0, 60, 130, 0.05);
}

.leads-filter-bar .form-select,
.leads-filter-bar .form-input {
  min-height: 2.45rem;
  border-radius: 10px;
  border-color: var(--adm-line);
}

.leads-filter-bar .form-select:focus,
.leads-filter-bar .form-input:focus {
  border-color: var(--adm-accent);
  box-shadow: 0 0 0 3px rgba(0, 113, 227, 0.12);
}

.reg-filter-field--range {
  min-width: 220px;
}

/* The bulk-bar follow-up picker is the last native date input on this screen;
   the two filter ones were replaced by the range picker. */
.lead-date-input {
  width: auto;
}

/* ── Phone / tablet toolbar ───────────────────────────
   Sticky inside .admin-main, which is the panel's only scroller. Top offset is
   0 and not the mobile bar's height: .admin-mobile-bar is a flex SIBLING of
   .admin-main, so it never scrolls into this element's space. Full-bleed to
   the scroller's padding edge - exactly to it, never past it, or the LTR
   .admin-main grows a horizontal scrollbar. */

.leads-toolbar {
  display: none;
  align-items: center;
  gap: 0.5rem;
}

.leads-toolbar__search {
  flex: 1 1 auto;
  min-width: 0;
}

.leads-toolbar__search input {
  width: 100%;
  min-height: 44px;
  border-radius: 12px;
  border-color: var(--adm-line);
}

.leads-tool {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  flex: 0 0 auto;
  min-height: 44px;
  padding: 0 0.7rem;
  background: #fff;
  border: 1px solid var(--adm-line);
  border-radius: 12px;
  color: var(--adm-ink-2);
  font-family: inherit;
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
}

.leads-tool--square {
  min-width: 44px;
  justify-content: center;
  padding: 0;
  font-size: 1.05rem;
}

.leads-tool--on {
  background: var(--primary-light, rgba(0, 113, 227, 0.06));
  border-color: rgba(0, 113, 227, 0.4);
  color: var(--adm-accent-ink);
}

.leads-tool__label {
  max-width: 7.5rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.leads-tool__badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.15rem;
  height: 1.15rem;
  padding: 0 0.25rem;
  border-radius: 999px;
  background: var(--adm-accent);
  color: #fff;
  font-size: 0.68rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* ── Applied-filter chips (phone / tablet) ──────────── */

.leads-chips {
  display: none;
  align-items: center;
  gap: 0.4rem;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  padding: 0.55rem 0 0.15rem;
  scrollbar-width: none;
}

.leads-chips::-webkit-scrollbar {
  display: none;
}

.leads-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  flex: 0 0 auto;
  min-height: 36px;
  padding-inline: 0.65rem 0.15rem;
  background: #fff;
  border: 1px solid var(--adm-line);
  border-radius: 999px;
  font-size: 0.78rem;
  color: var(--adm-ink);
  white-space: nowrap;
}

.leads-chip__label {
  color: var(--adm-ink-3);
}

.leads-chip__value {
  font-weight: 600;
  max-width: 11rem;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 36px chip, 44px target: the button carries the extra height as padding and
   is pulled back with a negative block margin so the chip keeps its size. */
.leads-chip__x {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin-block: -4px;
  padding: 0;
  border: none;
  background: none;
  border-radius: 999px;
  color: var(--adm-ink-3);
  font-size: 0.8rem;
  cursor: pointer;
}

.leads-chip__x:hover {
  color: var(--adm-ink);
}

.leads-chip--clear {
  padding-inline: 0.85rem;
  font-weight: 600;
  color: var(--adm-accent-ink);
  border-color: rgba(0, 113, 227, 0.35);
  background: var(--primary-light, rgba(0, 113, 227, 0.06));
  font-family: inherit;
  cursor: pointer;
}

/* ── Filter + sort sheets (AdminSheet body content) ─── */

.leads-sheet {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  padding-top: 0.35rem;
}

.leads-sheet__field {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.leads-sheet__label {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--adm-ink-3);
}

.leads-sheet__field .form-select {
  min-height: 46px;
  border-radius: 12px;
  border-color: var(--adm-line);
  font-size: 0.92rem;
}

.leads-sheet__field .form-select:focus {
  border-color: var(--adm-accent);
  box-shadow: 0 0 0 3px rgba(0, 113, 227, 0.12);
}

/* The range picker's desktop shape is a 560px popover anchored to its trigger.
   Inside a sheet there is no room for it and the sheet body's scroller would
   clip it, so within a sheet the panel lays itself out at field width with the
   presets stacked over the calendar. Below 768px the picker's own rules
   already dock it to the bottom of the screen and none of this applies. */
.adm-sheet .adm-drp,
.adm-sheet .adm-drp__trigger {
  width: 100%;
}

.adm-sheet .adm-drp__trigger {
  min-height: 46px;
  border-radius: 12px;
}

.adm-sheet .adm-drp__panel {
  width: 100%;
}

.adm-sheet .adm-drp__cols {
  grid-template-columns: minmax(0, 1fr);
}

.adm-sheet .adm-drp__presets {
  border-inline-end: none;
  border-block-end: 1px solid var(--adm-line);
}

.leads-sortlist {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding-top: 0.25rem;
}

.leads-sortopt {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  min-height: 46px;
  padding: 0 0.75rem;
  border: none;
  background: none;
  border-radius: 12px;
  color: var(--adm-ink);
  font-family: inherit;
  font-size: 0.92rem;
  font-weight: 500;
  text-align: start;
  cursor: pointer;
}

.leads-sortopt:hover {
  background: rgba(0, 113, 227, 0.06);
}

.leads-sortopt--active {
  background: rgba(0, 113, 227, 0.1);
  color: var(--adm-accent-ink);
  font-weight: 600;
}

.leads-sortopt .fa-check {
  font-size: 0.78rem;
  color: var(--adm-accent);
}

/* ── Table ───────────────────────────────────────────── */

.leads-table {
  border-color: var(--adm-line);
  border-radius: 14px;
  box-shadow: 0 8px 32px rgba(0, 60, 130, 0.08);
}

/* Hebrew headers: uppercase and wide tracking do nothing for Hebrew glyphs,
   so the eyebrow treatment here is weight and colour only. */
.leads-table th {
  background: #f7faff;
  color: var(--adm-ink-3);
  border-bottom: 1px solid var(--adm-line);
  text-transform: none;
  letter-spacing: 0.01em;
}

.leads-table td {
  border-bottom-color: rgba(25, 26, 35, 0.05);
}

/* Fixed-width columns (desktop table layout only). */
.leads-table .lead-th-check   { width: 36px; }
.leads-table .lead-th-email   { width: 200px; }
.leads-table .lead-th-source  { width: 110px; }
.leads-table .lead-th-origin  { width: 180px; }
.leads-table .lead-th-status  { width: 170px; }
/* Wider than the 110px the read-only text needed: the cell holds an assign
   control now, and the longest username plus the select's caret gutter did not
   fit in the old width. */
.leads-table .lead-th-owner   { width: 150px; }
.leads-table .lead-th-created { width: 120px; }
/* Free Hebrew text, so it gets the widest column on the table - and it is still
   one clipped line (below), because a note runs to whatever length its author
   felt like and an unclamped cell would set the height of every row in the
   book. */
.leads-table .lead-th-comment { width: 240px; }

/* Same failure mode the email cell documents below, same fix: this cell holds
   arbitrary prose, and letting `table-layout: auto` measure its min-content
   width breaks a note over five lines and drags the row with it. One line,
   ellipsis, full text on the tooltip. */
.leads-table td.lead-cell--comment {
  max-width: 240px;
}

.lead-comment {
  display: flex;
  align-items: baseline;
  gap: 0.35rem;
  min-width: 0;
  color: var(--adm-ink-2);
}

.lead-comment-icon {
  flex: 0 0 auto;
  color: #94a3b8;
  font-size: 0.72rem;
}

.lead-comment-text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The email cell had exactly the failure the phone cell above documents, and
   for the same reason: `.reg-cell-email` carries `overflow-wrap: anywhere`,
   which tells `table-layout: auto` its min-content width is ONE CHARACTER. The
   auto layout duly handed the column 66px and broke
   "modzgvarashvili@gmail.com" over five lines, dragging the whole row to
   141px. One line, clipped with an ellipsis; the full address is on the link's
   tooltip and one tap away in the lead. */
.leads-table td.lead-cell--email {
  max-width: 200px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.leads-table td.lead-cell--email .reg-contact-link {
  word-break: normal;
}

.lead-row {
  cursor: pointer;
}

.lead-name-link {
  color: #2563eb;
  font-weight: 600;
}

.lead-row:hover .lead-name-link {
  text-decoration: underline;
}

/* ── Untouched leads ──────────────────────────────────
   A lead no staff member has ever acted on. Four signals: an 8% wash on the
   row, a 4px leading edge on the first cell, a weight bump on the name, and a
   written tag. The tag is what satisfies the doctrine .llc-node--terminal
   states in admin-lead-lifecycle.css - "a written flag plus a doubled edge, so
   the state is never carried by colour alone".

   Bright green, one value everywhere: #22C55E is the row wash, the leading
   edge and the tag's edge and icon, so the three read as one mark rather than
   three decorations. It is deliberately brighter than every green already in
   the status palette (#3f8f17 attended, #52a627 follow-up, #178e67 enrolled).

   WHICH STATUSES AN UNTOUCHED ROW CAN DISPLAY - re-derived 2026-08-08, because
   the answer changed. It used to be exactly two, `new` (#3D7CDF) and
   `registered_open_day` (#8258E4), on the argument that every other status is
   reached through a staff status change and a staff status change is what makes
   a lead NOT untouched. That argument no longer covers the whole taxonomy: the
   WhatsApp automation now writes three statuses of its own when a customer taps
   a button, and it authors them as `system`, which HUMAN_TOUCH_ACTIVITY in
   server/routes/leads.ts deliberately does not count. So the list is five:

     new                #3D7CDF   cool blue
     registered_open_day #8258E4  violet
     replied            #738616   olive
     requested_a_chat   #899C25   yellow-green
     requested_a_call   #5E6D0E   dark olive

   The three new ones are yellow-greens (hue 70) and the wash is a grass green
   (hue ~145), so they are closer to it than the two cool statuses were. They do
   not sit ON the wash: the status control is a chip carrying its own
   background - `statusChipStyle` in AdminLeads.vue paints `color + 1a` behind
   `color` - so what the wash actually costs is contrast, and it was measured
   rather than eyeballed. Vivid text over its own 10% tint, on white and then
   over this wash:

     new 3.62 -> 3.38 · registered_open_day 4.12 -> 3.84 · replied 3.63 -> 3.39
     requested_a_chat 2.78 -> 2.60 · requested_a_call 4.98 -> 4.67

   The wash costs about a quarter of a point and moves nothing across a
   threshold. `requested_a_chat` is under the 3:1 non-text floor either way, and
   that is a property of the CHIP, not of this rule: the taxonomy solves a
   separate darkened `ink` per status for exactly this job, `lead_statuses`
   stores only `color`, and `statusChipStyle` therefore has no darker value to
   reach for. Fixing it means shipping `ink` through GET /admin/statuses, which
   is a server change and not this file's to make.

   8% is measured against the house ladder, not picked by eye. It lands the row
   about as far off white as the selected row's #eff6ff, while selection still
   out-reads it because selection paints the CELLS. 4% was invisible at
   full-page scale, which is a highlight that does not highlight.

   The wash sits on the <tr>, not on the cells, on purpose: `.admin-table
   tr:hover td` and `.reg-row--selected td` both paint a td background, so
   hover feedback and selection keep working over it without a specificity
   fight.

   The :not() is not belt-and-braces, it is the only thing standing between a
   selected card and the wrong colour. On desktop `.reg-row--selected td` wins
   on !important, but in the <=1024px card layout the <tr> IS the card, and
   `.reg-table tbody tr.reg-row--selected` in admin.css carries identical
   specificity to this rule - admin-leads.css is linked second, so without the
   guard this line would win on source order and a selected untouched card
   would come out blue-ringed with a green body. */
.leads-table tbody tr.lead-row--untouched:not(.reg-row--selected) {
  background: color-mix(in srgb, #22c55e 8%, #fff);
}

/* Hover deepens the same hue instead of replacing it with the table's generic
   hover wash - the escalating-alpha ladder the WhatsApp inbox uses for unread
   (admin-whatsapp.css: 0.04 hover -> 0.08 active). Without this the state
   would blink off under the cursor, which is exactly when it is being read. */
.leads-table tbody tr.lead-row--untouched:hover td {
  background: color-mix(in srgb, #22c55e 11%, #fff);
}

/* Leading edge, on the first cell rather than the row: <tr> borders are
   unreliable under `border-collapse: collapse`. Logical property because
   .leads-page is an RTL island, so this lands on the right. Solid, not an
   alpha of the hue, so it is the exact colour the tag carries. */
.leads-table tbody tr.lead-row--untouched > td:first-child {
  border-inline-start: 4px solid #22c55e;
}

/* The non-colour signal. */
.leads-table tbody tr.lead-row--untouched .lead-name-link {
  font-weight: 700;
}

/* The written flag, on the name for the same reason the opt-out chip is: it is
   a fact about the person and it has to survive a fast scan. Same pill geometry
   as every other chip on this table.

   Edge and icon take the leading edge's #22C55E verbatim - that is the whole
   point, the tag names the bar. The LABEL steps down to #15803D: the same hue,
   dark enough to clear AA on the pill (measured 4.79:1, where #22C55E would
   sit at 2.18:1 and be decorative rather than readable). The icon keeps the
   bright green because it is aria-hidden and the label carries the meaning. */
.lead-untouched-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  margin-inline-start: 0.4rem;
  padding: 0.12rem 0.5rem;
  border: 1px solid #22c55e;
  border-radius: 999px;
  background: #f0fdf4;
  color: #15803d;
  font-size: 0.72rem;
  font-weight: 600;
  white-space: nowrap;
  vertical-align: middle;
}

.lead-untouched-chip i {
  font-size: 0.68rem;
  color: #22c55e;
}

/* ── Waiting for an answer ────────────────────────────
   The customer asked us for something and nobody has answered since. It is a
   DIFFERENT fact from "untouched" and it is a worse one - untouched says no
   colleague has picked the lead up, this says a real person is sitting at the
   other end of it - and the two are true together on most of the rows that
   carry either, because a customer tapping a button is not a staff touch.

   So this marking has to beat the green one, and colour alone cannot do it.
   Amber and green at the same 8-12% tint over white land at 1.10 and 1.07
   against white: identical brightness, separated only by hue, which is exactly
   the separation that disappears for a deuteranope and at a glance. The three
   signals below are therefore chosen for WEIGHT, not for hue:

     1. A FILLED chip. Every other chip on this table is an outlined pale pill;
        this is the only solid one, so it is the first thing the eye lands on
        whatever the row is doing. White on #B45309 is 5.02:1 (AA).
     2. A DARK leading edge. #B45309 sits at 5.02 against white where the
        untouched #22C55E sits at 2.28 - so the amber edge reads as darker, a
        luminance difference rather than a hue swap, and #B45309 against
        #22C55E is 2.20 on its own.
     3. The wash, which is the quietest of the three and is there so the whole
        row belongs to the marking rather than just its first 4 pixels.

   SPECIFICITY, NOT SOURCE ORDER. The untouched rules and these are otherwise
   identical in weight, and this file is long enough that "keep them below" is
   not a guarantee anybody can enforce. The `.leads-page` prefix buys one class,
   so a row that is both untouched and awaiting comes out amber no matter where
   these rules end up. `.leads-page` is the page root and always an ancestor of
   the table (`.leads-page > .leads-table-wrap > table`).

   The `:not(.reg-row--selected)` guard is copied verbatim from the untouched
   rule and is load-bearing for the same reason - see the paragraph above it. */
.leads-page .leads-table tbody tr.lead-row--awaiting:not(.reg-row--selected) {
  background: color-mix(in srgb, #f59e0b 12%, #fff);
}

.leads-page .leads-table tbody tr.lead-row--awaiting:hover td {
  background: color-mix(in srgb, #f59e0b 16%, #fff);
}

.leads-page .leads-table tbody tr.lead-row--awaiting > td:first-child {
  border-inline-start: 4px solid #b45309;
}

.leads-page .leads-table tbody tr.lead-row--awaiting .lead-name-link {
  font-weight: 700;
}

/* WHERE THE CUSTOMER-SIGNAL CHIP LIVES, AND WHY IT IS TWO PLACES.

   Desktop: inside the status cell, under the control, in this wrapper.
   Card (<=1024px): inside `.lead-flags` on the name line, as a second copy in
   the markup that this file switches on and off by breakpoint - the same
   arrangement `.lead-fu-chip` and `.lead-od-badge` already use in reverse.

   Every number below was measured in a real browser at 1500 / 1024 / 767 / 390,
   not estimated, because two plausible layouts were tried and both were wrong:

   1. Both chips in `.lead-flags`. The desktop name column settles around
      103-139px against thirteen competitors, and these pills are 64-98px wide
      and `white-space: nowrap` - so every chip there is its own LINE. The
      awaiting row went 53px (plain) -> 62px (one chip) -> 103px (three), on
      exactly the rows this feature is about: a lead who tapped a button has
      only ever been touched by the automation, so it is untouched AND waiting
      AND carries a preference, all three at once.
   2. Both chips here, side by side. The status column is 200px, 168px inside
      its padding, and the two pills are 98 + 80 plus the gap - so they wrapped
      and the row still came out at 99px.

   What ships is one merged pill ("ממתין לשיחה" rather than "ממתין לתשובה" +
   "ביקש שיחה"), 91px, one line, and the desktop row lands at a flat 73px
   whether the person is waiting, merely has a preference, or both.

   On the card the arithmetic reverses: the status control has 46% of line 1 and
   no room for anything, while `.lead-flags` is already a full-width wrapping
   line that most of these rows render anyway. Measured there too - the card is
   the same height at 1024, at 767 and at 390 with ZERO, one, two or THREE chips
   in the strip, so up to three the marking costs the phone nothing at all.

   THE FOURTH CHIP IS WHERE THAT STOPS, and it is worth stating rather than
   rounding off, because four is a shape this feature produces routinely: a call
   tap sets a follow-up, most of the taps on record came from open-day template
   recipients, and the bot authors as `system` so the lead stays untouched. Four
   chips measure ~401px against a 337px strip at 390px, so they take a second
   line and the card goes 381 -> 411px (1024 and 767 still fit four on one
   line). That is a taller card, not a broken one - the strip wraps, which is
   what `.lead-flags` is for - and it is the price of naming the state rather
   than only tinting it. If the flat height is ever worth more than the wording,
   the lever is shortening the open-day badge to its date below 768px, NOT
   dropping this chip: it is the only one of the four that says somebody is
   waiting on us.

   Not `display: none` on the wrapper alone: the chip classes are shared with the
   card copies, so the copies carry `.lead-chip--card` and this wrapper carries
   the desktop half. */
.lead-signals {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  margin-top: 0.3rem;
}

/* The chips carry a rail margin for the name cell they were designed against;
   here the wrapper's own gap does that job, and the margin would only indent
   the pill away from the control it belongs to. Same correction the card's
   `.lead-flags > *` rule makes for the same reason. */
.lead-signals > * {
  margin-inline-start: 0;
}

/* The card copies, hidden while the table is a table. Two class selectors deep
   for the same reason `.lead-row-caret` is: FontAwesome's own `.fas { display }`
   is appended AFTER the page stylesheets, so a single-class rule here would lose
   to it on the icon inside the chip and leave a stray glyph on every desktop
   row. */
.leads-table .lead-chip--card {
  display: none;
}

/* The one filled pill on the table. Sized exactly like its outlined
   neighbours - same padding, same radius, same 0.72rem - so it is heavier
   without being bigger, and the strip still lines up. */
.lead-awaiting-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  margin-inline-start: 0.4rem;
  padding: 0.12rem 0.5rem;
  border: 1px solid #b45309;
  border-radius: 999px;
  background: #b45309;
  color: #fff;
  font-size: 0.72rem;
  font-weight: 600;
  white-space: nowrap;
  vertical-align: middle;
  cursor: help;
}

.lead-awaiting-chip i {
  font-size: 0.68rem;
}

/* ── The contact preference the customer chose ────────
   Which button they tapped: call / chat / info. Deliberately the quietest chip
   in the strip, because it is a DURABLE preference and not an alarm - it stays
   on the row long after somebody has answered, so a loud treatment would keep
   crying wolf on every lead that has ever tapped anything.

   Indigo rather than the panel blue: #2563EB is already the lead NAME beside
   it, and a blue pill next to a blue link reads as a second link. #4338CA on
   #EEF2FF is 7.07:1, and the tint is far enough from both washes (1.02 against
   the amber row, 1.04 against the green) that the chip reads by its own border
   and ink on either. One chrome for all three intents on purpose: the icon and
   the words carry the difference, and a third colour system on this row would
   only make the two that mean "act now" easier to miss. */
.lead-intent-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  margin-inline-start: 0.4rem;
  padding: 0.12rem 0.5rem;
  border: 1px solid #c7d2fe;
  border-radius: 999px;
  background: #eef2ff;
  color: #4338ca;
  font-size: 0.72rem;
  font-weight: 600;
  white-space: nowrap;
  vertical-align: middle;
  cursor: help;
}

.lead-intent-chip i {
  font-size: 0.68rem;
  color: #6366f1;
}

/* Card-mode affordance only - the desktop table row has no room for it.
   Two classes deep so it outranks FontAwesome's own `.fas { display }`,
   which the admin shell appends after the page stylesheets. */
.leads-table .lead-row-caret {
  display: none;
}

/* Opt-out marker on the name. Same pill geometry as the open-day and
   enrollment chips, in the red of .lead-od-chip--noshow - a new visual
   language for one flag would only make it easier to miss. */
.lead-optout-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  margin-inline-start: 0.4rem;
  padding: 0.12rem 0.5rem;
  border: 1px solid #fecaca;
  border-radius: 999px;
  background: #fef2f2;
  color: #b91c1c;
  font-size: 0.72rem;
  font-weight: 600;
  white-space: nowrap;
  vertical-align: middle;
  cursor: help;
}

.lead-optout-chip i {
  font-size: 0.68rem;
}

/* Card-only follow-up chip. The desktop table has a follow-up COLUMN and this
   is what stands in for it. Quiet by default, because a date in the future is
   a plan rather than a problem; the overdue variant takes the opt-out chip's
   red, since both mean "this row needs a decision" and a second red would only
   imply a difference that is not there. */
.lead-fu-chip {
  display: none;
  align-items: center;
  gap: 0.3rem;
  padding: 0.12rem 0.5rem;
  border: 1px solid #dbe3ee;
  border-radius: 999px;
  background: #f8fafc;
  color: var(--adm-ink-2);
  font-size: 0.72rem;
  font-weight: 600;
  white-space: nowrap;
}

.lead-fu-chip i {
  font-size: 0.68rem;
  color: #94a3b8;
}

.lead-fu-chip--overdue {
  border-color: #fecaca;
  background: #fef2f2;
  color: #b91c1c;
}

.lead-fu-chip--overdue i {
  color: #dc2626;
}

/* Card-only open-day chip, standing in for the open-day column the same way.
   It borrows the column's own attendance colours (.lead-od-chip--*) rather
   than inventing a second green: it IS that chip, moved above the fold. */
.lead-od-badge {
  display: none;
  align-items: center;
  gap: 0.3rem;
  padding: 0.12rem 0.5rem;
  border: 1px solid transparent;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 600;
  white-space: nowrap;
}

.lead-od-badge i {
  font-size: 0.68rem;
}

/* ── A template blast, seen from the row it is passing over ────
   The only TRANSIENT chip on this table. It exists for the minutes a bulk
   WhatsApp template send takes - roughly one message every six seconds, so a
   133-person batch wears it for a quarter of an hour - and then it goes away on
   its own. Everything about it is shaped by that.

   OUTLINED, never filled: .lead-awaiting-chip is the one solid pill here and
   must stay the one solid pill, or a routine send starts shouting louder than a
   customer who has been waiting for an answer.

   Grey while it is working, because "in progress" is not news. It borrows
   .lead-fu-chip's muted values exactly rather than inventing a fifth neutral.

   The geometry is the family's, to the pixel - .12rem/.5rem, 999px, .72rem/600,
   icon at .68rem - for the usual reason plus one of its own: this chip appears
   and disappears while nobody is touching the page, and a row that changed
   height every six seconds would be unreadable. Nothing here may set a height,
   a margin-block or a line-height taller than its neighbours. */
.lead-blast-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  margin-inline-start: 0.4rem;
  padding: 0.12rem 0.5rem;
  border: 1px solid #dbe3ee;
  border-radius: 999px;
  background: #f8fafc;
  color: var(--adm-ink-2);
  font-size: 0.72rem;
  font-weight: 600;
  white-space: nowrap;
  vertical-align: middle;
  cursor: help;
}

.lead-blast-chip i {
  font-size: 0.68rem;
  color: #94a3b8;
}

/* A rotating glyph changes its advance width mid-turn, so without a fixed box
   the label beside it shuffles sideways twice a second - on 200 rows at once.
   `line-height: 1` is the other half: a glyph caught mid-rotation must never be
   the thing that sets the row's height. Same pair as .per-action--refresh in
   admin-person.css and .wai-composer__held-spinner in admin-whatsapp.css.

   Reduced motion needs nothing here: FontAwesome's own bundled guard freezes
   `fa-spin` at 0deg rather than hiding it, so the chip keeps its glyph, its
   colour and its words - which is the whole of its meaning. */
.lead-blast-chip__spin {
  display: inline-block;
  inline-size: 1em;
  line-height: 1;
  text-align: center;
}

/* Nobody reached this person. AMBER, never red, and that agrees on purpose with
   .wab-report__status--unknown in admin-wa-bulk.css - the same batch's own
   report paints an undetermined send amber precisely because a red mark is what
   makes somebody send a second paid message to a phone that may already have
   the first one. Red on this table is reserved for a stated refusal
   (.lead-optout-chip) and a missed commitment (.lead-fu-chip--overdue). */
.lead-blast-chip--missed {
  border-color: #fde68a;
  background: #fffbeb;
  color: #92400e;
}

.lead-blast-chip--missed i {
  color: #b45309;
}

/* Card-only call button - a full-width pill wrapping the number itself. */
.lead-tap {
  display: none;
}

/* Card-only cells: the two summary lines and the expander. The card used to
   carry a third - a labelled "open in WhatsApp Web" row, which existed only
   because the hand-off next to the number was an unlabelled glyph. The phone
   cell names all three destinations now, so the extra cell is gone. */
.lead-cell--meta,
.lead-cell--brief,
.lead-cell--more {
  display: none;
}

/* The phone cell holds a number plus the WhatsApp destination picker, and the
   table is `table-layout: auto`. `.reg-contact-link` carries
   `word-break: break-all`, which tells the auto layout this cell's min-content
   width is ONE CHARACTER - so the browser handed the column 67px and wrapped a
   ten-digit number over three lines with the controls stranded underneath.
   Pinning the cell to `nowrap` makes its real width the min-content width the
   layout has to honour. The table already scrolls horizontally, so the extra
   width costs nothing. */
.leads-table td.lead-cell--phone {
  white-space: nowrap;
}

.leads-table td.lead-cell--phone .reg-contact-link {
  word-break: normal;
}

/* The destination picker sits UNDER the number rather than beside it. `flex` is
   block-level, so it breaks the line inside the cell without a wrapper element,
   and `fit-content` keeps the column as narrow as the three short labels need -
   this is a table cell, and every pixel it takes is a pixel the columns beside
   it lose. */
.lead-wa-actions {
  display: flex;
  width: fit-content;
  margin-top: 0.3rem;
}

/* Source badge colors per lead source (base look from .reg-source-badge).
   Labels are verbose (form + surface), so allow a snug two-line wrap. */
.lead-source-badge {
  margin-left: 0;
  white-space: normal;
  line-height: 1.25;
}

.lead-source-badge--open_day {
  background: #f5f3ff;
  color: #6d28d9;
  border-color: #ddd6fe;
}

.lead-source-badge--contact_form {
  background: #eff6ff;
  color: #1d4ed8;
  border-color: #bfdbfe;
}

.lead-source-badge--whatsapp {
  background: #ecfdf5;
  color: #047857;
  border-color: #a7f3d0;
}

.lead-source-badge--manual {
  background: #f3f4f6;
  color: #6b7280;
  border-color: #e5e7eb;
}

.lead-source-badge--enrollment_page {
  background: #fff7ed;
  color: #b45309;
  border-color: #fed7aa;
}

/* Campaign context under the source badge: the channel verdict and the
   affiliate code chip, on ONE line beside each other. Wrapping was letting
   this cell stack four deep and set a 141px row height for the whole table -
   the origin is context, not the row's subject, and it must not out-size the
   name. Anything that does not fit is clipped; the tooltip carries the full
   verdict, and the lead page carries all of it. */
.lead-source-sub {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 0.25rem;
  margin-top: 0.25rem;
  min-width: 0;
  overflow: hidden;
}

/* Traffic-channel verdict badge in the sub-row. Tier swatches come from
   .reg-source-badge--* in admin.css; only the rail margin is reset here. */
.lead-channel-badge {
  margin-left: 0;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
}

.lead-channel-badge > span {
  overflow: hidden;
  text-overflow: ellipsis;
}

/* The resolved traffic-source bucket heading the "מקור" cell (Meta /
   Telegram / partner, partner name included). Neutral by default; the
   confirmed-paid variant borrows the affiliate chip's blue so a billed
   click reads distinct at a glance. */
.lead-origin-chip {
  margin-left: 0;
  max-width: 100%;
  background: #f8fafc;
  color: #334155;
  border-color: #e2e8f0;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 1.25;
}

.lead-origin-chip--paid {
  background: #eef4ff;
  color: #2456c4;
  border-color: #d5e3fb;
}

.lead-aff-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  background: #eef4ff;
  color: #2456c4;
  border: 1px solid #d5e3fb;
  border-radius: 5px;
  padding: 0 0.35rem;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.05em;
}

/* The affiliate's human name riding beside the code, so identifying the
   partner no longer requires the tooltip. */
.lead-aff-name {
  font-weight: 600;
  letter-spacing: 0;
  max-width: 120px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The ad campaign name is the fourth fact in a cell that only has room for
   two, and it is the least useful of them on a scanning pass. Off the desktop
   table entirely - it rides in the origin cell's tooltip instead - and back on
   the card below 1024px, where the cell has the full width. */
.lead-campaign {
  display: none;
  color: #8e8f9e;
  font-size: 0.68rem;
  max-width: 150px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Relative + absolute stacked pair for timestamp cells: the spelled-out
   distance ("לפני 4 שעות") over the dotted clock form ("31.7.26 18:23"). */
.lead-when {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  line-height: 1.3;
}

/* Each line stays whole - "לפני 49 דקות" must not break mid-phrase. */
.lead-when > span {
  white-space: nowrap;
}

.lead-when-abs {
  color: #8e8f9e;
  font-size: 0.68rem;
  font-weight: 400;
}

/* Status select is tinted inline from the status row's color. */
.lead-status-select {
  max-width: 100%;
}

.lead-status-select:disabled {
  cursor: not-allowed;
  opacity: 0.7;
}

.lead-owner {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.82rem;
  color: #334155;
  white-space: nowrap;
}

.lead-owner-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  background: #e0e7ff;
  color: #3730a3;
  font-size: 0.72rem;
  font-weight: 700;
  flex: 0 0 auto;
}

/* ── Inline assign ────────────────────────────────────
   Built on .reg-status-select, the same appearance-stripped pill the status
   cell beside it uses, so the two editable columns are visibly one idea rather
   than two. Only the colour is new: an owner has no palette of its own, so the
   control takes the slate the read-only text already had and lets the initial
   disc keep carrying the identity.

   The chrome is quiet until it is approached. A row of hard-bordered selects
   turns a table people READ into a form, and this column is scanned far more
   often than it is edited - so the border and fill arrive on hover and focus,
   and the resting state still reads as the text it replaced. */
.lead-owner-picker {
  gap: 0.15rem;
}

.lead-owner-select {
  min-width: 0;
  max-width: 100%;
  background-color: transparent;
  border-color: transparent;
  color: #334155;
}

.lead-owner-picker:hover .lead-owner-select,
.lead-owner-select:focus {
  background-color: #f8fafc;
  border-color: var(--adm-line);
}

/* Nobody owns this lead yet. The disc becomes the add glyph and the label keeps
   the muted weight of the "-" it replaced, so an unassigned row still reads as
   unassigned at a glance - it just has somewhere to go now. */
.lead-owner-select--empty {
  color: var(--adm-ink-3);
  font-weight: 500;
}

.lead-owner-avatar--empty {
  background: #eef2f7;
  color: #94a3b8;
  font-size: 0.62rem;
}

.lead-od-chips {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 0.25rem;
}

/* Enrollment cell = chips + inline "create contract" action. */
.lead-enroll-cell {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}

.lead-contract-btn {
  color: var(--primary-color, #0071E3);
  font-size: 0.82rem;
}

.lead-contract-btn:hover {
  color: var(--primary-hover, #0077ED);
}

.lead-od-chip,
.lead-enroll-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.12rem 0.5rem;
  border-radius: 999px;
  border: 1px solid transparent;
  font-size: 0.72rem;
  font-weight: 600;
  white-space: nowrap;
}

.lead-od-chip i {
  font-size: 0.7rem;
}

.lead-od-chip--attended {
  background: #ecfdf5;
  color: #047857;
  border-color: #a7f3d0;
}

.lead-od-chip--noshow {
  background: #fef2f2;
  color: #b91c1c;
  border-color: #fecaca;
}

.lead-od-chip--unset {
  background: #f3f4f6;
  color: #6b7280;
  border-color: #e5e7eb;
}

.lead-enroll-chip--paid {
  background: #ecfdf5;
  color: #047857;
  border-color: #a7f3d0;
}

.lead-enroll-chip--partial {
  background: #fffbeb;
  color: #92400e;
  border-color: #fde68a;
}

.lead-enroll-chip--unpaid {
  background: #f3f4f6;
  color: #6b7280;
  border-color: #e5e7eb;
}

/* One chip = one sale, and the chip opens that sale's own page. The paid /
   partial / unpaid coloring stays the chip's job, so the link affordance is
   carried by an underline and a lift on hover rather than by link blue, which
   would erase the payment state the chip exists to show. */
.lead-enroll-chip-link {
  text-decoration: none;
  transition: box-shadow 0.15s ease;
}

.lead-enroll-chip-link:hover {
  text-decoration: underline;
  box-shadow: 0 1px 4px rgba(0, 60, 130, 0.16);
}

.lead-enroll-chip-link:focus-visible {
  outline: 2px solid var(--primary-color, #0071E3);
  outline-offset: 2px;
}

.lead-activity {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.8rem;
  color: #475569;
  white-space: nowrap;
}

.lead-activity-icon {
  color: #94a3b8;
  font-size: 0.78rem;
}

/* WHAT the last action was, beside the glyph that only hints at it: "שיוך",
   "פולו-אפ", "סטטוס הרשמה". Absent on a genuinely machine-written row, where
   the tooltip's author line already reads "מערכת" and a chip would repeat it.
   Carries the weight because it is the answer this column is named after; the
   distance in time beside it is the qualifier, not the headline.

   The cap is a GUARD, not a clip on anything real - every label in
   ACTIVITY_KIND_LABEL fits inside it with room to spare. It is here because
   activityTypeLabel() falls back to the raw stored type for a type this build
   has never heard of, and this column declares no width of its own, so a
   single row from a newer server would otherwise widen it for the whole
   table. `nowrap` is inherited from .lead-activity. */
.lead-activity-label {
  min-width: 0;
  max-width: 8rem;
  overflow: hidden;
  text-overflow: ellipsis;
  font-weight: 600;
}

.lead-followup {
  display: inline-flex;
  align-items: baseline;
  gap: 0.3rem;
  font-size: 0.8rem;
  color: #334155;
  white-space: nowrap;
}

.lead-followup i {
  font-size: 0.7rem;
  color: #94a3b8;
}

.lead-followup--overdue,
.lead-followup--overdue i,
.lead-followup--overdue .reg-cell-sub {
  color: #b91c1c;
  font-weight: 600;
}

/* ── Bulk bar ─────────────────────────────────────────
   Desktop: sticks to the top of the scroller, so a selection made at row 180
   can still be acted on without scrolling back up. Phone/tablet: fixed to the
   bottom of the screen (see the responsive block). */

.leads-bulk-bar {
  position: sticky;
  top: 0;
  z-index: 20;
}

.lead-bulk-select {
  width: auto;
  padding: 0.32rem 1.6rem 0.32rem 0.6rem;
  font-size: 0.8rem;
}

.lead-bulk-followup {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}

.lead-bulk-followup .lead-date-input {
  padding: 0.32rem 0.5rem;
  font-size: 0.8rem;
}

/* ── Pagination ──────────────────────────────────────── */

.leads-pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.85rem 1rem;
  margin-top: 0.75rem;
  background: #fff;
  border: 1px solid var(--adm-line);
  border-radius: 12px;
  box-shadow: 0 1px 3px rgba(0, 60, 130, 0.05);
}

.leads-pagination-mid {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  justify-content: center;
}

.leads-pagination-info {
  font-size: 0.85rem;
  color: #475569;
  font-variant-numeric: tabular-nums;
}

/* Rows-per-page picker. Sits with the count it governs, not with the prev/next
   buttons - it changes how much of the list you see, not where you are in it. */
.leads-page-size {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.85rem;
  color: #475569;
}

.leads-page-size-label {
  white-space: nowrap;
}

.leads-page-size-select {
  padding: 0.28rem 0.5rem;
  border: 1px solid var(--adm-line);
  border-radius: 8px;
  background: #fff;
  font-family: inherit;
  font-size: 0.82rem;
  color: #1f2937;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  outline: none;
  transition: border-color 0.2s;
}

.leads-page-size-select:focus {
  border-color: var(--adm-accent);
}

.leads-pagination .btn[disabled] {
  opacity: 0.5;
  cursor: not-allowed;
}

/* ── Modals ──────────────────────────────────────────── */

.lead-duplicate-panel {
  padding: 0.75rem 0.9rem;
  margin-bottom: 0.9rem;
  background: #fffbeb;
  border: 1px solid #fde68a;
  border-radius: 12px;
}

.lead-duplicate-title {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0 0 0.35rem;
  font-size: 0.88rem;
  font-weight: 700;
  color: #92400e;
}

.lead-duplicate-info {
  margin: 0 0 0.6rem;
  font-size: 0.85rem;
  color: #475569;
}

.lead-duplicate-actions {
  display: flex;
  gap: 0.5rem;
}

/* Said out loud rather than left to be noticed: the force-create retry ships
   with the automatic WhatsApp approach turned OFF, because the server has just
   confirmed this phone already belongs to somebody. */
.lead-duplicate-note {
  margin: 0.6rem 0 0;
  font-size: 0.8rem;
  line-height: 1.6;
  color: #92400e;
}

/* Bulk-email opt-out warning. Same anatomy as .lead-duplicate-panel - the
   other 409 that stops a modal mid-flow - but red rather than amber: a
   duplicate row is an inconvenience, this is a person who asked us to stop. */
.lead-optout-warn {
  padding: 0.85rem 0.95rem;
  background: #fef2f2;
  border: 1px solid #fecaca;
  border-radius: 12px;
}

.lead-optout-warn-title {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  margin: 0 0 0.4rem;
  font-size: 0.92rem;
  font-weight: 700;
  color: #991b1b;
}

.lead-optout-warn-note {
  margin: 0 0 0.75rem;
  font-size: 0.83rem;
  line-height: 1.6;
  color: #7f1d1d;
}

/* Long selections scroll inside the panel so the footer decision stays put. */
.lead-optout-list {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  max-height: 260px;
  overflow-y: auto;
  margin: 0;
  padding: 0;
  list-style: none;
}

.lead-optout-item {
  padding: 0.5rem 0.6rem;
  background: #fff;
  border: 1px solid #fee2e2;
  border-radius: 10px;
}

.lead-optout-name {
  font-size: 0.85rem;
  font-weight: 700;
  color: #191a23;
}

/* The customer's own words, quoted verbatim - it is evidence, not a summary. */
.lead-optout-quote {
  display: block;
  margin-top: 0.15rem;
  font-size: 0.82rem;
  line-height: 1.5;
  color: #334155;
  overflow-wrap: anywhere;
}

.lead-optout-when {
  display: block;
  margin-top: 0.2rem;
  font-size: 0.72rem;
  color: #8e8f9e;
}

.lead-email-note {
  display: flex;
  align-items: baseline;
  gap: 0.45rem;
  padding: 0.6rem 0.75rem;
  margin: 0 0 0.9rem;
  background: #f0f9ff;
  border: 1px solid #bae6fd;
  border-radius: 10px;
  font-size: 0.82rem;
  color: #0c4a6e;
}

/* ── "Send the automatic approach" tick (New Lead modal) ──
   Every other field in that form writes a row in our database; this one puts a
   message on a stranger's phone, so it is separated from the run of optional
   fields by a hairline instead of sitting inside it, and it is the last thing
   read before the create button. Scoped to .leads-page: `.checkbox-label-admin`
   is shared with the curriculum and payment forms and must not be restyled
   from here. */
.leads-page .lead-approach-field {
  padding-top: 0.85rem;
  margin-top: 0.35rem;
  border-top: 1px solid var(--adm-line);
}

.leads-page .lead-approach-check {
  padding-bottom: 0;
  font-weight: 600;
  color: var(--adm-ink);
  cursor: pointer;
}

.leads-page .lead-approach-check i {
  margin-inline-end: 0.3rem;
  color: #117335;
}

/* No phone typed, so nothing can be sent. The control stays on screen and goes
   quiet rather than disappearing - a tick that vanishes leaves staff wondering
   whether a message went out. */
.leads-page .lead-approach-field--off .lead-approach-check {
  color: var(--adm-ink-3);
  cursor: default;
}

.leads-page .lead-approach-field--off .lead-approach-check i {
  color: var(--adm-ink-3);
}

.leads-page .lead-approach-note {
  margin-top: 0.3rem;
  padding-inline-start: 1.5rem;
  font-size: 0.78rem;
  line-height: 1.6;
  color: var(--adm-ink-2);
}

/* ══════════════════════════════════════════════════════════
   Responsive. The card collapse machinery (flex-card rows,
   data-label meta rows) comes from admin.css via .reg-table;
   the leads-specific order scheme and every card-only
   surface live here.
   ══════════════════════════════════════════════════════════ */

@media (max-width: 1024px) {
  /* The wide table is gone below this width, so the wrapper stops being a
     scroller - a scroll container here would clip the fixed bulk bar's
     stacking and re-break sticky for anything added inside it later. */
  .leads-table-wrap {
    overflow: visible;
  }

  .leads-kpi {
    min-width: 84px;
    flex: 1 1 auto;
  }

  .leads-funnel {
    flex: 1 1 100%;
    order: 2;
    padding-inline-start: 0;
    padding-top: 0.5rem;
    border-inline-start: none;
    border-top: 1px solid var(--adm-line);
  }

  /* The desktop filter bar hides; its controls live in the sheet. */
  .leads-filter-bar {
    display: none;
  }

  /* Sticky toolbar, full-bleed to the scroller's padding edge. The inline
     margins are exactly .admin-main's padding at this width: one pixel more
     and the LTR scroller grows a horizontal scrollbar it can never use. */
  .leads-toolbar {
    display: flex;
    position: sticky;
    top: 0;
    z-index: 12;
    margin-inline: -1.5rem;
    padding: 0.55rem 1.5rem;
    background: rgba(255, 255, 255, 0.92);
    -webkit-backdrop-filter: blur(18px) saturate(1.5);
    backdrop-filter: blur(18px) saturate(1.5);
    border-block-end: 1px solid var(--adm-line);
  }

  .leads-chips {
    display: flex;
  }

  /* ── Lead card ──────────────────────────────────────
     Five bands, in the order somebody working the list reads them:

       1. the name, with the status control at the end of the line
       2. any state chips - untouched, opt-out, follow-up, open day
       3. the call strip: the phone number, as the button that dials it
       4. owner · where the person came from · how old the lead is
       5. the last thing anybody did, and when

     Bands 2 and 5 disappear entirely when they have nothing to say, so a bare
     lead is three bands tall. Everything else waits behind "עוד".

     The hierarchy is carried by three things and not by colour alone: the name
     is the only full-size type on the card, the call strip is the only filled
     control, and bands 4-5 are one step down in size and two in contrast. That
     is what the four equal grey lines this replaced could not do.

     Ordered by class, not by label text, so copy edits cannot silently
     reshuffle the card. */

  /* The name cell hands its three children straight to the card's own flex
     box, which is the whole reason the chips can have a full-width line: the
     cell shares line 1 with the status control and is therefore about 160px
     wide on a phone - narrower than a single chip - so three chips inside it
     stacked into three lines. `display: contents` keeps inheritance (the
     cell's font-size reaches the name), and a browser that ignored it would
     fall back to the nested layout rather than break. */
  .leads-table td.reg-cell-name {
    display: contents;
  }

  /* Line 1. `flex: 1 1 0`, not a percentage: a flex container decides where to
     WRAP from the hypothetical (basis) size, before any shrinking, so at a 55%
     basis the name reserved 183px of a 332px card, the status pill wanted
     149px, and 332 was one gap short - the pill dropped to a full-width row of
     its own and the card grew 44px. With basis 0 the name contributes nothing
     to that decision and simply grows into whatever the pill leaves.

     `display: block` and a line-height, NOT a flex box: `text-overflow` only
     works on a block container, so as a flex box this clipped a long name
     mid-glyph with no ellipsis at all. */
  .leads-table .lead-name-link {
    order: 1;
    flex: 1 1 0;
    display: block;
    min-width: 0;
    line-height: 2.15rem;
    font-size: 1.02rem;
    font-weight: 700;
    color: var(--adm-ink);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .leads-table .lead-row-caret {
    order: 2;
    display: block;
    flex: 0 0 auto;
    align-self: center;
    color: #c3cad6;
    font-size: 0.78rem;
  }

  /* Status keeps the end of line 1 and drops its gutter label - the pill says
     what it is. It shrinks and the name does not, because the name is basis 0
     and has nothing to give: a very long status label eats its own width.

     The padding is zeroed, not just the top: this cell carries a data-label, so
     the shared labelled-row rule in admin.css was still holding 0.34rem under
     it and setting the height of line 1 five pixels taller than the control
     inside it. */
  .leads-table td.lead-cell--status {
    order: 3;
    flex: 0 1 auto;
    align-self: center;
    min-width: 0;
    max-width: 46%;
    margin-top: 0;
    padding: 0;
    border-top: none;
  }

  .leads-table td.lead-cell--status::before {
    display: none;
  }

  .leads-table td.lead-cell--status .lead-status-select {
    min-height: 2.15rem;
    max-width: 100%;
    font-size: 0.8rem;
  }

  /* Line 2 - the state chips, on a line of their own across the whole card.
     They are facts about the person and they have to survive a fast scan,
     which is the same reason two of them sit on the name in the desktop
     table. */
  .leads-table .lead-flags {
    order: 4;
    display: flex;
    flex: 1 1 100%;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.3rem;
    min-width: 0;
    margin-top: 0.3rem;
  }

  /* The chips carry a rail margin for the desktop name cell; here the strip's
     own gap does that job. `max-width` is the backstop for a chip whose text
     is longer than the card - none is today, and none may overflow tomorrow. */
  .leads-table .lead-flags > * {
    flex: 0 1 auto;
    max-width: 100%;
    margin-inline-start: 0;
    overflow: hidden;
  }

  .leads-table .lead-fu-chip,
  .leads-table .lead-od-badge,
  .leads-table .lead-chip--card {
    display: inline-flex;
  }

  /* ...and the desktop half of the same two facts goes away with the table it
     belonged to. Leaving it would put the chips inside line 1's 46%-wide
     status cell, which wraps them under the control and makes the name beside
     it two lines tall on every card that carries either. */
  .leads-table .lead-signals {
    display: none;
  }

  /* Line 3 - the call strip. On a card the number is not a labelled field to
     read, it is the thing being aimed at: it sits INSIDE the dial button, so
     the whole width is one 44px target instead of two lone glyphs against an
     empty band.

     `flex-basis: 100%` and not `auto`. A wrapping flex container decides its
     lines from the basis size, so an `auto` basis let this row fit alongside
     the name and the status pill on line 1 - which collapsed the name to 34px
     and stacked its text vertically. Any basis short of 100% only moves the
     failure: whether the row clears line 1 would depend on how wide the Hebrew
     status label happens to be, and that is not a thing to leave to the data. */
  .leads-table td.lead-cell--phone {
    order: 5;
    flex: 1 1 100%;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
    margin-top: 0.5rem;
    padding: 0.5rem 0 0;
    border-top: 1px solid var(--adm-line);
    white-space: normal;
  }

  /* The desktop cell's own gutter label and its plain text number: the strip
     below says both, and says them as a control. */
  .leads-table td.lead-cell--phone::before,
  .leads-table td.lead-cell--phone .lead-phone-text {
    display: none;
  }

  .leads-table td.lead-cell--phone .lead-tap {
    display: flex;
    flex: 1 1 auto;
    align-items: center;
    justify-content: flex-start;
    gap: 0.5rem;
    min-width: 0;
    height: 44px;
    margin: 0;
    padding-inline: 0.8rem;
    border: 1px solid #cfe0f7;
    border-radius: 12px;
    background: #f4f9ff;
    color: var(--adm-accent-ink);
    text-decoration: none;
  }

  .leads-table td.lead-cell--phone .lead-tap i {
    flex: 0 0 auto;
    font-size: 0.92rem;
    opacity: 0.75;
  }

  /* Tabular figures so a column of cards lines its digits up, and the same
     one-line clip every other run of text on this card gets - a stored value
     is not guaranteed to be ten digits. */
  .lead-tap-num {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 0.98rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.01em;
  }

  /* Its own line under the call strip, not beside it. Two 44px squares side by
     side is how a thumb aiming for the recorded conversation used to land on
     the unrecorded one; here each destination is a full-width labelled row and
     the mis-tap has nothing to hit. `flex-basis: 100%` is what breaks the line
     - see the note on the cell itself for why an `auto` basis is not enough. */
  .leads-table td.lead-cell--phone .lead-wa-actions {
    flex: 1 1 100%;
    width: auto;
    margin-top: 0;
  }

  /* Card mode starts at 1024px here, and every other control on the card is
     44px - the call strip directly above this one included. The segments match
     it rather than keeping the dense-table height, which on a touch tablet
     would put a 30px target between two 44px ones. */
  .leads-table td.lead-cell--phone .lead-wa-actions .wa-seg {
    min-height: 44px;
  }

  /* Card mode begins here, but the shared long-form swap only fires at 767px,
     so between the two the labels would still be trimmed inside a bar the full
     width of the card. The trimming exists for a table column that no longer
     exists at this width - print the destinations in full. */
  .leads-table td.lead-cell--phone .lead-wa-actions .wa-seg__long {
    display: inline;
  }

  .leads-table td.lead-cell--phone .lead-wa-actions .wa-seg__short {
    display: none;
  }

  /* ── Lines 4 and 5: the muted pair ──────────────────
     Owner, origin and age on one; the last action and its distance in time on
     the other. Between them they carry four of the fields that used to sit
     behind "עוד", because somebody scanning the list is asking whose lead this
     is, where the person came from and whether anyone has spoken to them yet -
     and opening every card to find out is the whole cost these two lines
     remove.

     Neither wraps. A note is free text and can be a paragraph, and a campaign
     name can be sixty characters; letting either wrap would hand the height of
     the card to whatever somebody happened to type, and the list stops being
     scannable at that point. Every run is clipped to one line with an
     ellipsis, and the full text is on the title and one tap away in the lead.

     `min-width: 0` on the cells is not decoration. A flex item defaults to
     `min-width: auto`, which resolves to its CONTENT-based minimum - and the
     content here is a nowrap run whose min-content width is the whole string.
     The cell was therefore sized to the text, grew past the card's edge, and
     took the ellipsis with it: `overflow: hidden` cannot clip a box that was
     never made narrow. The zero lets the box take the card's width and the
     clip finally has something to clip against. `overflow: hidden` on the cell
     itself is the backstop for anything added inside later. */
  .leads-table td.lead-cell--meta,
  .leads-table td.lead-cell--brief {
    display: flex;
    flex: 1 1 100%;
    align-items: center;
    gap: 0.3rem;
    min-width: 0;
    overflow: hidden;
    font-size: 0.78rem;
    line-height: 1.45;
    color: var(--adm-ink-3);
  }

  .leads-table td.lead-cell--meta {
    order: 6;
    margin-top: 0.45rem;
  }

  .leads-table td.lead-cell--brief {
    order: 7;
    margin-top: 0.15rem;
  }

  .lead-meta-dot,
  .lead-brief-dot {
    flex: 0 0 auto;
    color: #c3c9d4;
  }

  /* The owner keeps the initial disc the desktop column uses - same mark, so
     the two shapes of this screen do not name the same person two ways. It is
     sized down to the summary line rather than kept at the column's 1.5rem,
     which would out-weigh the name above it. */
  .lead-meta-owner {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    flex: 0 1 auto;
    min-width: 0;
    color: var(--adm-ink-2);
    font-weight: 600;
  }

  .lead-meta-avatar {
    width: 1.15rem;
    height: 1.15rem;
    font-size: 0.62rem;
  }

  /* Unassigned is a fact worth reading, not an empty slot - but it is not news
     either, so it drops to the muted weight the rest of the line carries. */
  .lead-meta-owner--none {
    color: var(--adm-ink-3);
    font-weight: 500;
  }

  .lead-meta-icon,
  .lead-brief-icon {
    flex: 0 0 auto;
    color: #94a3b8;
    font-size: 0.72rem;
  }

  .lead-meta-text,
  .lead-brief-text {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .lead-meta-origin {
    flex: 0 1 auto;
  }

  .lead-meta-when {
    flex: 0 0 auto;
    white-space: nowrap;
  }

  .lead-brief-act {
    display: flex;
    flex: 1 1 auto;
    align-items: center;
    gap: 0.3rem;
    min-width: 0;
  }

  /* `flex: 0 1 auto`, so it shrinks but never grows. Growing it pushed the
     timestamp against the far edge of the card, where "לפני 12 דקות" read as a
     detached label floating on its own instead of as the end of the sentence
     it belongs to. */
  .lead-brief-text {
    flex: 0 1 auto;
  }

  .lead-brief-when {
    flex: 0 0 auto;
    color: #9aa3b2;
    white-space: nowrap;
  }

  /* ── Expanded rows ──────────────────────────────────
     Hidden until the card is opened. Contact first, then where the lead
     stands, then the context it arrived with, then the audit stamp. */
  .leads-table tbody tr:not(.lead-row--expanded) td.lead-cell--detail {
    display: none;
  }

  /* The desktop clamp above is a TABLE fix and must not follow the email into
     the card, where this cell is a full-width labelled flex row: 200px minus a
     6rem gutter label leaves about 110px, and `text-overflow` is inert on a
     flex container's items, so the address came out hard-clipped mid-glyph with
     no ellipsis and no tooltip to fall back on from a touchscreen. Unclamped it
     wraps instead, via the `overflow-wrap: anywhere` it inherits from
     .reg-cell-email. */
  .leads-table td.lead-cell--email {
    order: 10;
    max-width: none;
    white-space: normal;
    overflow: visible;
  }
  .leads-table td.lead-cell--owner    { order: 12; }

  /* The card's ONE owner control, and it lives here rather than on the
     collapsed summary line above. That line prints the owner as text on
     purpose: a select up there would be the only tap target above the action
     row, on a card whose whole surface is a button that opens the lead, and a
     thumb aiming for the card would keep landing in a dropdown. Down here it
     sits with the other editable fields, a deliberate tap away.

     44px, unlike the 2.1rem status pill on line 1 - that one is squeezed
     alongside the name, and this one has the row to itself. */
  /* Centred, not baseline-aligned like the other labelled rows: the gutter
     label would otherwise sit on the text baseline inside a 44px control and
     ride high against it. */
  .leads-table td.lead-cell--owner {
    align-items: center;
  }

  .leads-table td.lead-cell--owner .lead-owner-picker {
    min-height: 44px;
  }

  .leads-table td.lead-cell--owner .lead-owner-select {
    min-height: 44px;
    font-size: 0.85rem;
    background-color: #f8fafc;
    border-color: var(--adm-line);
  }
  .leads-table td.lead-cell--activity { order: 13; }
  .leads-table td.lead-cell--comment  { order: 14; }
  .leads-table td.lead-cell--followup { order: 15; }
  .leads-table td.lead-cell--source   { order: 16; }
  .leads-table td.lead-cell--origin   { order: 17; }
  .leads-table td.lead-cell--openday  { order: 18; }
  .leads-table td.lead-cell--enroll   { order: 19; }
  .leads-table td.lead-cell--created  { order: 20; }

  /* The money chip is a LINK to its own sale, and it sits on a card whose own
     tap target opens the LEAD - a different page. At 0.72rem type inside
     0.12rem of padding it is a ~22px target, so a thumb that misses it by a
     couple of pixels does not miss harmlessly: it opens the wrong page.

     The card's answer to that is always the same and is stated on the WhatsApp
     segments above - "every other control on the card is 44px" - so the control
     itself carries the height rather than a pseudo-element faking a hit area,
     which on a wrapping row of chips would overlap the chip beside it. This
     lives in the 1024px block, not the 767px one, for the same reason those
     segments do: card mode BEGINS here, and a 22px target sitting between 44px
     ones on a touch tablet is the same mis-tap on a bigger screen.

     The link only. In selection mode the chip renders as a plain span, the row
     itself IS the checkbox, and fattening a read-out would only eat card
     height. The gap grows with it: 0.25rem between two 44px targets is not a
     gap, it is a shared edge. */
  .leads-table td.lead-cell--enroll .lead-od-chips {
    gap: 0.4rem;
  }

  .leads-table td.lead-cell--enroll .lead-enroll-chip-link {
    min-height: 44px;
    padding-inline: 0.8rem;
  }

  /* The desktop clamp is a TABLE fix and must not follow the note into the
     card, where this is a full-width labelled row with the space to wrap. A
     comment is the one field here whose words are the whole point of it, so it
     gets three lines rather than one clipped to an ellipsis a thumb cannot
     hover for the rest. */
  .leads-table td.lead-cell--comment {
    max-width: none;
  }

  .lead-comment-text {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    line-clamp: 3;
    overflow: hidden;
    text-overflow: unset;
    white-space: normal;
  }

  /* Same reasoning as the comment above, one step milder: the desktop cap on
     the activity chip is a TABLE guard, and a card row has the width to print
     an unfamiliar stored type in full. A word clipped to an ellipsis a thumb
     cannot hover for says strictly less than the raw string does. */
  .lead-activity-label {
    max-width: none;
  }

  /* Block breaks: pipeline state, context, audit. */
  .leads-table td.lead-cell--owner,
  .leads-table td.lead-cell--source,
  .leads-table td.lead-cell--created {
    margin-top: 0.3rem;
    padding-top: 0.55rem;
    border-top-color: #e2e8f2;
  }

  .leads-table td.lead-cell--created {
    font-size: 0.78rem;
  }

  /* The expander closes the card, and the whole line is the target - "עוד" is
     two words wide and a thumb is not. Order 8 keeps it under the collapsed
     bands and above the expanded fields, so it does not run away down the
     screen when the card opens. No second hairline: the call strip above
     already carries one, and two rules a few lines apart is fencing, not
     structure. */
  .leads-table td.lead-cell--more {
    order: 8;
    display: block;
    flex: 1 1 100%;
    margin-top: 0.1rem;
  }

  .lead-more-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    width: 100%;
    min-height: 44px;
    border: none;
    background: none;
    color: var(--adm-ink-3);
    font-family: inherit;
    font-size: 0.82rem;
    font-weight: 600;
    cursor: pointer;
  }

  .lead-more-btn i {
    font-size: 0.7rem;
  }

  /* A row with nothing in it is noise on a phone - drop it entirely. */
  .leads-table tbody td.lead-cell--empty {
    display: none;
  }

  /* Selection mode. The checkbox is out of the way until it is asked for; in
     the mode, the whole card is the target and the box is the read-out. */
  .leads-table tbody td.reg-cell-check {
    display: none;
  }

  .leads-table tbody tr.lead-row--picking td.reg-cell-check {
    order: 0;
    display: flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    padding-bottom: 0;
  }

  .leads-table tbody tr.lead-row--picking td.reg-cell-check input[type="checkbox"] {
    width: 22px;
    height: 22px;
  }

  /* The row IS the card here, so the untouched state moves off the cells and
     onto the card's own border and ring, and the desktop leading edge goes
     away with the table it belonged to. The wash itself comes from the base
     rule above, which carries the same :not() guard and for the same reason. */
  .leads-table tbody tr.lead-row--untouched:not(.reg-row--selected) {
    border-color: rgba(34, 197, 94, 0.55);
    box-shadow: 0 0 0 1px rgba(34, 197, 94, 0.55);
  }

  .leads-table tbody tr.lead-row--untouched > td:first-child {
    border-inline-start: none;
  }

  /* The desktop hover wash would punch cell-shaped holes in the card's own
     tint - the card carries the state here, so the cells stay clear. */
  .leads-table tbody tr.lead-row--untouched:hover td {
    background: transparent;
  }

  /* Same move for the awaiting card, and the same three reasons the desktop
     rules give: the ring is the DARK amber rather than the tint, so it reads
     heavier than the untouched card's bright-green ring instead of merely
     differently-hued, and the `.leads-page` prefix keeps it winning on a card
     that is both. The desktop leading edge goes away with the table, exactly
     as the green one does. */
  .leads-page .leads-table tbody tr.lead-row--awaiting:not(.reg-row--selected) {
    border-color: rgba(180, 83, 9, 0.6);
    box-shadow: 0 0 0 1px rgba(180, 83, 9, 0.6);
  }

  .leads-page .leads-table tbody tr.lead-row--awaiting > td:first-child {
    border-inline-start: none;
  }

  .leads-page .leads-table tbody tr.lead-row--awaiting:hover td {
    background: transparent;
  }

  /* The card box itself. The column gap only ever separates line 1's three
     items (name, caret, status) - every band below it is a full-width flex
     line - so it is tuned for that line and nothing else. */
  .leads-table tbody tr:not(.reg-row-detail) {
    align-items: flex-start;
    column-gap: 0.5rem;
    padding: 0.7rem 0.85rem 0.55rem;
    margin-bottom: 0.7rem;
    border-color: var(--adm-line);
    box-shadow: 0 4px 16px rgba(0, 60, 130, 0.06);
  }

  /* Hebrew labels: uppercase/tracking do nothing for them and the gutter
     has to fit "פעילות אחרונה". */
  .leads-table td[data-label]::before {
    flex-basis: 6rem;
    font-size: 0.72rem;
    text-transform: none;
    letter-spacing: 0;
  }

  /* Contact rows carry the primary actions - give them tap-sized targets. */
  .leads-table td.lead-cell--email .reg-contact-link {
    font-size: 0.9rem;
    font-weight: 600;
  }

  /* The campaign name has the full card width here, not a table column, so it
     comes back off the tooltip and onto the row. */
  .leads-table .lead-campaign {
    display: block;
    max-width: 100%;
  }

  .leads-table .lead-source-sub {
    flex-wrap: wrap;
    overflow: visible;
  }

  /* Bulk bar: fixed to the bottom of the screen. A selection made 40 cards
     down is acted on where the thumb already is, and the bar never scrolls
     away mid-decision. Buttons scroll sideways rather than stacking into a
     four-row slab that eats half the screen. */
  .leads-bulk-bar {
    position: fixed;
    inset-inline: 0;
    /* Both ends, explicitly. The desktop rule above is `position: sticky; top:
       0`, and that `top` does not stop applying when the position changes - a
       fixed box with top AND bottom pinned is stretched to the full viewport,
       which is how a bottom bar came out as a full-screen dark slab with its
       buttons floating mid-air. */
    inset-block-start: auto;
    inset-block-end: 0;
    z-index: 1015;
    height: auto;
    margin: 0;
    border-radius: 0;
    flex-wrap: nowrap;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    padding: 0.6rem 0.85rem calc(0.6rem + env(safe-area-inset-bottom, 0px));
    box-shadow: 0 -8px 28px rgba(0, 60, 130, 0.22);
  }

  .leads-bulk-bar .btn,
  .leads-bulk-bar .lead-bulk-select,
  .leads-bulk-bar .lead-date-input {
    flex: 0 0 auto;
    min-height: 44px;
  }

  .leads-bulk-bar .reg-bulk-count {
    flex: 0 0 auto;
  }

  /* The spacer's auto margin would push everything apart inside a horizontal
     scroller instead of pinning one button to the far side. */
  .leads-bulk-bar .reg-bulk-spacer {
    margin-inline: 0;
  }

  /* Clear the fixed bar so the last card is never under it. */
  .leads-page--bulk {
    padding-block-end: 5.5rem;
  }
}

/* Tablet only: two cards abreast. Each card is compact now, so a single
   column at 900px wastes half the screen. Cards are top-aligned so opening
   one does not stretch its neighbour to match. */
@media (min-width: 768px) and (max-width: 1024px) {
  .leads-table tbody {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.85rem;
    align-items: start;
  }

  .leads-table tbody tr:not(.reg-row-detail) {
    margin-bottom: 0;
  }
}

@media (max-width: 767px) {
  .leads-kpis {
    padding: 0.65rem 0.7rem;
    gap: 0.5rem;
  }

  .leads-funnel-seg {
    min-width: 74px;
    padding: 0.32rem 0.55rem;
  }

  .leads-kpi-value {
    font-size: 1.15rem;
  }

  .leads-toolbar {
    margin-inline: -0.75rem;
    padding-inline: 0.75rem;
  }

  /* No tab-bar offset here ON PURPOSE. While the bulk bar is up, selection
     mode REPLACES navigation: admin.css hides .adm-tabbar under
     .admin-layout:has(.leads-page--bulk) (the Material selection-mode
     convention), so this bar docks at the true bottom edge and owns the
     home-indicator inset via its own safe-area padding above. */

  .leads-table td[data-label]::before {
    flex-basis: 5.4rem;
  }

  /* Pagination: tap-sized and centred, with the count on its own line. */
  .leads-pagination {
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.6rem;
  }

  .leads-pagination .btn {
    min-height: 44px;
    padding-inline: 1rem;
  }

  .leads-pagination-mid {
    flex: 1 1 100%;
    order: -1;
  }

  .leads-page-size-select {
    min-height: 44px;
  }
}

/* ── Hebrew RTL island (.leads-page) mirrors ───────────
   Nothing left to mirror here. The WhatsApp controls this block used to flip
   were a pair of glyphs with a physical `margin-left`; they are now the shared
   `WaActionGroup`, which is built out of logical properties and needs no
   per-direction correction. Kept as a landmark for the next rule that does. */
