/* ═══════════════════════════════════════════════════════════
   BOUNCE GUARD — additions to the shared cb-admin design system.
   cb-admin.css is VENDORED from the Shopify apps and must stay
   byte-identical to theirs, so anything specific to this panel
   lives here instead of being edited into it.
   ═══════════════════════════════════════════════════════════ */

/* ─── Brand mark (the apps ship a logo file; this panel draws one) ─── */
.cb-brand-mark {
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: linear-gradient(135deg, var(--cb-accent-blue), var(--cb-accent-purple));
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 17px;
  flex-shrink: 0;
  box-shadow: var(--cb-glow-blue);
}

/* ─── Exit-criteria checklist ────────────────────────────────
   Phase 0 has two conditions that decide whether it is finished.
   Prose gets skimmed; a list that is red until it is green does not. */
.cb-check {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 13px 0;
  border-bottom: 1px solid var(--cb-border);
}
.cb-check:last-child { border-bottom: none; }

.cb-check-mark {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 800;
  flex-shrink: 0;
  margin-top: 1px;
}
.cb-check-mark.pass { background: rgba(16, 185, 129, 0.15); color: var(--cb-accent-emerald); }
.cb-check-mark.fail { background: rgba(245, 158, 11, 0.15); color: var(--cb-accent-amber); }

.cb-check-body p {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--cb-text-primary);
  line-height: 1.4;
  /* The title line carries badges beside the text, not stacked under it. */
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
/* Direct child only. Without the `>` this also hits every .cb-badge nested in the
   title line and turns a pill into a full-width bar. */
.cb-check-body > span {
  display: block;
  font-size: 12.5px;
  color: var(--cb-text-muted);
  line-height: 1.55;
  margin-top: 3px;
}

/* ─── Monospace cells: ids, hashes, agent keys ─── */
.cb-mono {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 11.5px;
  color: var(--cb-text-secondary);
}

/* ─── Copy-to-clipboard row ─── */
.cb-copy-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.cb-copy-row .cb-codeblock {
  flex: 1;
  min-width: 0;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* ─── Coverage bar (client-ref coverage per app) ─── */
.cb-bar {
  height: 6px;
  border-radius: 3px;
  background: var(--cb-bg-input);
  overflow: hidden;
  min-width: 90px;
}
.cb-bar-fill {
  height: 100%;
  border-radius: 3px;
  transition: width var(--cb-transition);
}
.cb-bar-fill.good { background: linear-gradient(90deg, #10b981, #34d399); }
.cb-bar-fill.warn { background: linear-gradient(90deg, #f59e0b, #fbbf24); }
.cb-bar-fill.bad  { background: linear-gradient(90deg, #ef4444, #f87171); }

/* ─── Wide modal, for the register form and the raw payload viewer ─── */
.cb-modal.wide { max-width: 620px; }
.cb-modal.xwide { max-width: 860px; }

.cb-modal-scroll {
  max-height: 60vh;
  overflow: auto;
  margin: 0 -4px;
  padding: 0 4px;
}

/* ─── Toast ─── */
.cb-toast {
  position: fixed;
  right: 20px;
  bottom: 20px;
  z-index: 300;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  border-radius: var(--cb-radius);
  background: var(--cb-bg-card);
  border: 1px solid var(--cb-border);
  box-shadow: var(--cb-shadow-lg);
  font-size: 13px;
  font-weight: 500;
  color: var(--cb-text-primary);
  animation: cb-scale-in 0.18s ease;
  max-width: 420px;
}
.cb-toast.ok { border-color: var(--cb-accent-emerald); }
.cb-toast.err { border-color: var(--cb-accent-red); }

/* ─── Inline filter row above a table ─── */
.cb-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
}
.cb-filters .cb-select,
.cb-filters .cb-input { width: auto; min-width: 150px; }

/* ─── Sidebar collapses away on small screens ─── */
@media (max-width: 900px) {
  .cb-sidebar { transform: translateX(-100%); transition: transform var(--cb-transition); }
  .cb-sidebar.open { transform: none; }
  .cb-main { margin-left: 0; }
}

/* ═══════════════════════════════════════════════════════════
   RULES & DECISIONS
   ═══════════════════════════════════════════════════════════ */

/* Exactly two across, never three. There are four rules, and 2x2 reads as four
   deliberate choices where 3+1 reads as a list that ran out. auto-fit would pick
   three on a wide screen and leave the fourth card stranded beside a gap. */
.cb-rule-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
}

@media (max-width: 1080px) {
  .cb-rule-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

.cb-rule-card {
  border: 1px solid var(--cb-border);
  border-radius: var(--cb-radius);
  background: var(--cb-bg-input);
  padding: 18px;
  transition: opacity var(--cb-transition), border-color var(--cb-transition);
}

/* A disabled rule stays legible — it is still a number someone may want to
   read — but stops competing for attention with the ones that are counting. */
.cb-rule-card.off {
  opacity: 0.55;
}

.cb-rule-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 14px;
  margin-bottom: 10px;
}

.cb-rule-head h4 {
  font-size: 14px;
  font-weight: 600;
  color: var(--cb-text-primary);
}

.cb-rule-head .cb-mono {
  font-size: 11px;
  color: var(--cb-text-muted);
}

.cb-rule-doc {
  font-size: 12.5px;
  line-height: 1.65;
  color: var(--cb-text-secondary);
  margin-bottom: 16px;
}

.cb-rule-inputs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

/* The sentence is the part of the card that is meant to be read out loud —
   "block a shop after 10 hard bounces in 10 minutes" is a claim someone can
   agree or disagree with, in a way that two numbers in two boxes are not. */
.cb-rule-sentence {
  margin-top: 16px;
  padding: 11px 13px;
  border-radius: 8px;
  background: var(--cb-bg-secondary);
  border-left: 3px solid var(--cb-accent-blue);
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--cb-text-secondary);
}

.cb-rule-sentence b {
  color: var(--cb-text-primary);
  font-weight: 600;
}

/* Sticks to the bottom of the viewport so the Save button is reachable without
   scrolling back up past four rule cards and an allowlist.
   `bottom: 12px` rather than 0 so it reads as a floating bar rather than one
   welded to the window edge, and the shadow has somewhere to fall. */
.cb-save-bar {
  position: sticky;
  bottom: 12px;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin: 20px 0;
  padding: 14px 18px;
  border: 1px solid var(--cb-border);
  border-radius: var(--cb-radius);
  background: var(--cb-bg-card);
  box-shadow: 0 -6px 24px rgba(0, 0, 0, 0.28);
}

/* An enforced block that has not lapsed is the one row on the Decisions screen
   that is costing a merchant something right now. */
.cb-row-hot td {
  background: rgba(239, 68, 68, 0.05);
}

@media (max-width: 720px) {
  .cb-rule-inputs {
    grid-template-columns: 1fr;
  }
  .cb-save-bar {
    flex-direction: column;
    align-items: stretch;
  }
}

/* Links inside an alert inherit the muted body colour and vanish against the
   tinted background — and these are the links that matter most, because every
   one of them is the next thing the reader is supposed to do. */
.cb-alert-body a,
.cb-rule-doc a,
.cb-table-empty a {
  color: var(--cb-accent-blue);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.cb-alert-body a:hover,
.cb-rule-doc a:hover,
.cb-table-empty a:hover {
  color: var(--cb-text-primary);
}

/* ═══════════════════════════════════════════════════════════
   NARROW SCREENS
   ═══════════════════════════════════════════════════════════ */

/* `.cb-main` is a flex item, and a flex item's default `min-width: auto` means
   it refuses to shrink below its content. One wide table therefore stretched the
   whole page instead of scrolling inside its own wrapper: at 420px the layout
   measured 1040px and the entire panel scrolled sideways, topbar and all.
   `min-width: 0` is the standard release valve.

   Fixed here rather than in cb-admin.css, which is vendored verbatim from the
   Notifylyst app and has to stay byte-identical to it. */
.cb-main {
  min-width: 0;
}

.cb-table-wrap {
  max-width: 100%;
}

/* A table may scroll inside its wrapper; the PAGE may not. Below this width the
   columns cannot all fit honestly, so let the table keep its natural width and
   scroll, rather than crushing timestamps and shop ids into two-character
   columns. */
@media (max-width: 900px) {
  .cb-table {
    min-width: 720px;
  }
}

/* ═══════════════════════════════════════════════════════════
   BOUNCE ACTIVITY — events and decisions, one screen
   ═══════════════════════════════════════════════════════════ */

/* The tab strip is defined in cb-admin.css for a full-bleed sub-nav under a
   topbar. Here it sits inside the content padding, so it needs its own edges. */
.cb-activity-tabs {
  padding: 0;
  margin: -4px 0 20px;
  background: transparent;
}

.cb-tab-count {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 7px;
  border-radius: 10px;
  background: var(--cb-bg-input);
  border: 1px solid var(--cb-border);
  font-size: 11px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.cb-tab.active .cb-tab-count {
  border-color: var(--cb-accent-blue);
  color: var(--cb-accent-blue);
}

/* A shop id in a table cell that narrows the view when clicked. It has to read
   as clickable without becoming a button-shaped thing in every row. */
.cb-linkish {
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  color: var(--cb-accent-blue);
  font: inherit;
  text-align: left;
  border-bottom: 1px dashed transparent;
}

.cb-linkish:hover {
  border-bottom-color: var(--cb-accent-blue);
}

/* Says what the view is currently narrowed to, and how to get out. Without it a
   filtered explorer looks identical to an empty one. */
.cb-scope-chip {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 12px;
  padding: 8px 12px;
  border-radius: 8px;
  background: var(--cb-bg-secondary);
  border: 1px solid var(--cb-border);
  border-left: 3px solid var(--cb-accent-blue);
}
