/* ============================================================================
   Capture — Inbox composed-flow components ("Tactile Chips" redesign)
   Momentum bar · Next card · System lane strip.

   Class-namespaced (mom-* / next-* / lane-*) so it never collides with the
   legacy .momentum-* / .next-card rules in components.css (those go inert for
   the inbox flow, like .item-card did when .card replaced it; .item-card has
   since been pruned).

   theme.css variables ONLY — no hardcoded hex/oklch. The design_handoff canvas
   authored these in inline oklch; every value below maps to a --token.
   Load AFTER card.css so it is authoritative (add the <link> to index.html).
   Maps canvas #3a (desktop) / #3b (phone) / #2b (system resting shape).
   ========================================================================== */

/* =========================================================================
   0. TOP COMMAND STRIP  (momentum + Next on ONE row)

   Persistent chrome wrapper in index.html: .topstrip > #momentum + #next-slot.
   Next LEADS on the left (the one decision that matters now — order:-1); the
   momentum bar + search sit on the right, search flush to the true edge. Only
   the inbox mounts Next, so #next-slot is empty on every other view → :empty
   collapses it and momentum spans the full width, exactly as before the merge.
   Below the strip breakpoint the two stack (momentum on top, as it was).
   ========================================================================= */
.topstrip {
  display: flex;
  align-items: stretch;                /* equal heights → cohesive strip */
  gap: var(--gap-col);
  margin-bottom: 18px;                 /* the spacing .mom-bar used to own */
}
.topstrip > #momentum  { flex: 2.6 1 0; min-width: 0; display: flex; }
.topstrip > #next-slot { flex: 1 1 0;   min-width: 0; display: flex; order: -1; }
.topstrip > #next-slot:empty { display: none; }   /* non-inbox → momentum full width */

/* the two inner cards fill their flex cell (equal heights, no stray margins).
   The momentum bar is shorter than the Next card; matching heights leaves slack,
   so centre its (possibly wrapped) rows vertically instead of letting align-content
   spread them to the edges — one line reads centred, a wrapped search stays a tidy
   pair rather than a gap. */
.topstrip > #momentum > .mom-bar { flex: 1; margin-bottom: 0; align-content: center; }
.topstrip > #next-slot > .next-focus { flex: 1; max-width: none; margin-bottom: 0; }

/* Stack below ~860px: the momentum bar wants the full width to lay out its
   stats + search without wrapping, so side-by-side is a wide-screen affordance. */
@media (max-width: 860px) {
  .topstrip { flex-wrap: wrap; }
  .topstrip > #momentum,
  .topstrip > #next-slot { flex-basis: 100%; }
  .topstrip > #next-slot { order: 0; }            /* stacked: momentum back on top */
}

/* =========================================================================
   1. MOMENTUM BAR  (persistent chrome — #momentum, shown on every view)
   ========================================================================= */
.mom-bar {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  padding: 11px 22px;
  margin-bottom: 18px;
  background: var(--strip-bg);
  border: 1px solid var(--hairline);
  border-radius: var(--r-compact);
  box-shadow: var(--inset-top-hairline);
}

/* ── streak cluster ── */
.mom-streak { display: inline-flex; align-items: center; gap: 8px; }
.mom-flame { font-size: 16px; line-height: 1; }
.mom-streak-label {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text-body);
  white-space: nowrap;
}

.mom-divider {
  width: 1px;
  height: 16px;
  background: var(--border-strong);
  flex-shrink: 0;
}

/* ── today's counts (mono) ── */
.mom-counts {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--dim);
  white-space: nowrap;
}
.mom-c { color: var(--dim); }
.mom-added   { color: var(--text-body); }
.mom-closed  { color: var(--green); }
.mom-triaged { color: var(--dim); }

/* ── gradient progress bar (green → pink = momentum %) ── */
.mom-progress {
  flex: 1;
  min-width: 80px;
  height: 5px;
  border-radius: 3px;
  background: var(--border);
  position: relative;
  overflow: hidden;
}
.mom-progress-fill {
  position: absolute;
  left: 0; top: 0; bottom: 0;
  border-radius: 3px;
  background: linear-gradient(90deg, var(--green), var(--pink));
  transition: width .5s ease;
}
/* Escalation is carried as data-level for future tinting; kept calm (never
   alarm-red) per the non-guilt tone — a hairline outline at critical only. */
.mom-progress[data-level="critical"] { box-shadow: inset 0 0 0 1px var(--pink-dim); }

/* ── freshness ── */
.mom-fresh {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--dim);
  white-space: nowrap;
  cursor: pointer;
  border-radius: var(--r-pill);
}
.mom-fresh:hover { color: var(--text-body); }
.mom-fresh:focus-visible { outline: 2px solid var(--pink); outline-offset: 2px; }
.mom-fresh.mom-muted { cursor: default; color: var(--dimmer); }
.mom-muted:hover { color: var(--dimmer); }

/* ── system-only shortcut ── */
.mom-system {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  border-radius: var(--r-pill);
  border: 1px solid var(--border-strong);
  background: var(--chip-bg);
  color: var(--text-body);
  font-family: var(--font-mono);
  font-size: 11px;
  line-height: 1;
  white-space: nowrap;
  text-decoration: none;
  transition: border-color .16s ease, color .16s ease, filter .16s ease;
}
.mom-system:hover { border-color: var(--pink-dim); color: var(--pink-tint-text); filter: brightness(1.08); }
.mom-system:focus-visible { outline: 2px solid var(--pink); outline-offset: 2px; }

/* ── search pill (far right) — keeps the real #global-search input ── */
.mom-search {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  border-radius: var(--r-pill);
  background: var(--inset);
  border: 1px solid var(--border-strong);
  transition: border-color .16s ease;
}
.mom-search:focus-within { border-color: var(--pink); }
.mom-search-ico { font-size: 12px; color: var(--dim); }
.mom-search input {
  border: none;
  background: transparent;
  color: var(--text);
  font-family: var(--font-body);
  font-size: 12px;
  width: 120px;
  padding: 0;
}
.mom-search input::placeholder { color: var(--dim); }
.mom-search input:focus { outline: none; }
.mom-kbd {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--dimmer);
  border: 1px solid var(--border-strong);
  border-radius: 4px;
  padding: 0 4px;
  line-height: 1.5;
}

/* =========================================================================
   2. NEXT CARD  (#next-slot — leads the inbox flow)
   ========================================================================= */
/* One decision, one column. Full-bleed made the Next card a pink slab that ate the
   first screen; it's a single card's worth of content, so it gets a single masonry
   column's worth of width (the pile is column-count:2 / column-gap:--gap-col).
   Phone keeps it full width — there's only one column there anyway. */
.next-focus {
  position: relative;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  height: 140px;
  max-width: calc((100% - var(--gap-col)) / 2);
  background: linear-gradient(150deg, var(--pink-tint-bg), var(--card));
  border: 1px solid var(--pink-dim);
  border-radius: var(--r-card);
  padding: 13px 15px;
  margin-bottom: var(--gap-col);
  box-shadow: var(--glow-next), var(--inset-top-hairline);
}
.next-focus.next-expanded {
  height: auto;
  min-height: 140px;
}

.next-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 9px;
}

.next-spark {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--pink-tint-text);
  margin-right: auto;
}
.next-sparkle {
  display: inline-block;
  will-change: transform, opacity;
  animation: sparkleTwinkle 2.6s ease-in-out infinite;
}

.next-line {
  flex: 1;
  min-height: 0;
  font-size: 16px;
  line-height: 1.5;
  font-weight: 600;
  color: var(--text);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.next-focus:not(.next-expanded) .next-line {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}

.next-expand {
  flex: none;
  border: 0;
  padding: 3px 0;
  background: transparent;
  color: var(--pink-tint-text);
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 700;
  cursor: pointer;
}
.next-expand[hidden] { display: none; }
.next-expand:hover { color: var(--text); }
.next-expand:focus-visible { outline: 2px solid var(--pink); outline-offset: 2px; }

.next-gestures { display: flex; gap: var(--gap-chip); margin-top: 11px; }
.next-gesture {
  flex: 0 1 auto;              /* sized to their label, not stretched edge-to-edge */
  font-size: 13px;
  font-weight: 600;
  padding: 8px 18px;
  border: none;
  border-radius: var(--r-pill);
  cursor: pointer;
  transition: filter .14s ease, transform .05s ease, background .16s ease;
}
.next-gesture:hover { filter: brightness(1.08); }
.next-gesture:active { transform: translateY(1px); }
.next-done { background: var(--pink); color: var(--bg); font-weight: 700; }
.next-done:hover { background: var(--pink-hover); filter: none; }
.next-skip { background: var(--chip-bg); color: var(--text-body); }

/* empty / clear */
.next-blank { background: var(--card); box-shadow: var(--inset-top-hairline); }
.next-clear { font-size: 15px; color: var(--dim); }

/* error */
.next-fail {
  background: var(--card);
  border: 1px solid var(--pink-dim);
  border-radius: var(--r-card);
  padding: 14px 16px;
  margin-bottom: var(--gap-col);
  color: var(--importance-vital);
  box-shadow: none;
}

@keyframes sparkleTwinkle {
  0%, 100% { opacity: 0.25; transform: scale(0.7) rotate(0deg); }
  50%      { opacity: 1;    transform: scale(1)   rotate(90deg); }
}

/* =========================================================================
   3. SYSTEM LANE STRIP  (quarantined — one hatched/dashed slate strip)
   ========================================================================= */
.lane-strip {
  background: repeating-linear-gradient(
    135deg,
    var(--system-hatch-a),
    var(--system-hatch-a) 9px,
    var(--system-hatch-b) 9px,
    var(--system-hatch-b) 18px
  );
  border: 1px dashed var(--system-border);
  border-radius: var(--r-compact);
  padding: 11px 13px;
  margin-bottom: var(--gap-col);
}
.lane-head { display: flex; align-items: center; gap: 8px; }
.lane-bell { font-size: 13px; line-height: 1; }
.lane-tag {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  padding: 2px 6px;
  border-radius: 5px;
  background: var(--system-tag-bg);
  color: var(--system-tag-text);
}
.lane-count {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--dim);
}
.lane-line {
  font-size: 12.5px;
  color: var(--text-body);
  margin-top: 8px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.lane-line + .lane-line { color: var(--dim); margin-top: 4px; }
.lane-review {
  display: inline-block;
  margin-top: 9px;
  font-size: 11px;
  padding: 4px 10px;
  border: 1px solid var(--system-border);
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--system-tag-text);
  text-decoration: none;
  cursor: pointer;
}
.lane-review:hover { color: var(--text); border-color: var(--dim); }

/* System messages folded INTO the card flow at their age position — never a stack
   above the pile (that turned every inbox visit into a review checkpoint).
   Stacked layout (head / name / ack), because these now live in a narrow masonry
   column beside the cards. Same hatched/dashed slate so noise still reads as
   noise — both kinds: `signals` rows AND category='system' items. */
.sys-row {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 7px;
  padding: 11px 13px;
  border-radius: var(--r-compact);
  border: 1px dashed var(--system-border);
  background: repeating-linear-gradient(135deg,
    var(--system-hatch-a), var(--system-hatch-a) 9px,
    var(--system-hatch-b) 9px, var(--system-hatch-b) 18px);
}
/* masonry citizenship: don't split across columns, own the same rhythm as .card */
.card-masonry > .sys-row { break-inside: avoid; margin-bottom: var(--gap-col); }

.sys-head { display: flex; align-items: center; gap: 7px; width: 100%; }
.sys-bell { flex-shrink: 0; font-size: 13px; line-height: 1; }
.sys-tag {
  flex-shrink: 0; font-family: var(--font-mono); font-size: 10px; font-weight: 700;
  letter-spacing: 0.08em; padding: 2px 6px; border-radius: 5px;
  background: var(--system-tag-bg); color: var(--system-tag-text);
}
.sys-age {
  margin-left: auto; flex-shrink: 0;
  font-family: var(--font-mono); font-size: 11px; color: var(--dimmer);
}
.sys-name {
  width: 100%; min-width: 0;
  font-size: 12.5px; line-height: 1.45; color: var(--text-body);
  overflow-wrap: anywhere;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3;
  overflow: hidden;
}
.sys-ack {
  align-self: flex-start; flex-shrink: 0;
  font-size: 11px; padding: 4px 10px; cursor: pointer;
  border: 1px solid var(--system-border); border-radius: var(--r-pill);
  background: transparent; color: var(--system-tag-text);
}
.sys-ack:hover { color: var(--text); border-color: var(--dim); }

/* settled — a completed system item ("Show done"); it offers Undone, not Done */
.sys-row.done { opacity: 0.55; }
.sys-row.done .sys-name { text-decoration: line-through; color: var(--dimmer); }

/* =========================================================================
   3b. INBOX TOOLBAR  (one row — categories · #tags · sort · show-done)

   Was four stacked rows (category pills, two wrapped rows of tag pills, a sort
   row), which pushed the actual captures below the fold. Categories keep their
   counts on ONE horizontally-scrollable row (that's the main filter); the long
   tag tail hides behind the #tags disclosure; sort + show-done ride along.
   ========================================================================= */
.ibx-toolbar {
  display: flex;
  align-items: center;
  gap: var(--gap-chip);
  margin-bottom: 10px;
}
/* the pills scroll sideways instead of wrapping into extra rows */
.ibx-cats {
  flex: 1 1 auto;
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: none;                       /* the pills ARE the affordance */
  -webkit-overflow-scrolling: touch;
  mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent);
}
.ibx-cats::-webkit-scrollbar { display: none; }
.ibx-cats .pills { flex-wrap: nowrap; }        /* override the wrapping default */
.ibx-cats .pill { flex-shrink: 0; }

.ibx-tools { display: flex; align-items: center; gap: var(--gap-chip); flex-shrink: 0; }
.ibx-tagtoggle {
  font-size: 0.75rem;
  padding: 0.3rem 0.65rem;
  cursor: pointer;
  white-space: nowrap;
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  background: var(--card);
  color: var(--dim);
  transition: color .16s ease, border-color .16s ease, background .16s ease;
}
.ibx-tagtoggle:hover { color: var(--text); border-color: var(--pink-dim); background: var(--card-hover); }
.ibx-tagtoggle.open { color: var(--text); border-color: var(--pink-dim); background: var(--card-hover); }

/* Select toggle — same pill grammar as #tags; solid pink when active. */
.ibx-select-btn {
  font-size: 0.75rem;
  padding: 0.3rem 0.65rem;
  cursor: pointer;
  white-space: nowrap;
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  background: var(--card);
  color: var(--dim);
  transition: color .16s ease, border-color .16s ease, background .16s ease;
}
.ibx-select-btn:hover { color: var(--text); border-color: var(--pink-dim); background: var(--card-hover); }
.ibx-select-btn.active {
  background: var(--pink); border-color: var(--pink); color: var(--bg); font-weight: 600;
}

/* =========================================================================
   3c. SELECT MODE + BULK ACTION BAR  (owner-only multi-select triage)

   In select mode the whole card is one tap target: children get
   pointer-events:none so every tap lands on .card → app.js __cardClick routes
   it to the selection toggle. Selected cards wear a pink ring + tint (the
   tactile-chip idiom — a state, not a bolted-on checkbox).
   ========================================================================= */
.ibx-selecting .card { cursor: pointer; }
.ibx-selecting .card * { pointer-events: none; }        /* whole card = select target */
.card.ibx-selected {
  outline: 2px solid var(--pink);
  outline-offset: 1px;
  background: var(--pink-tint-bg);
  box-shadow: 0 0 0 4px var(--nav-active-bg), var(--shadow-card);
}

/* Sticky bulk bar — floats above the footer, centred, wraps on a phone. */
.ibx-bulkbar {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: 18px;
  z-index: 60;
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  max-width: min(760px, calc(100vw - 24px));
  padding: 10px 16px;
  background: var(--card-hover);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-card);
  box-shadow: 0 16px 40px -14px oklch(0 0 0 / 0.7), var(--inset-top-hairline);
}
.ibx-bulk-count {
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 700;
  color: var(--pink-tint-text);
  white-space: nowrap;
}
.ibx-bulk-group { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.ibx-bulk-label {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--dim);
}
.ibx-bulk-aud {
  font-size: 12px;
  padding: 6px 12px;
  border: none;
  border-radius: var(--r-pill);
  background: var(--chip-bg);
  color: var(--text-body);
  cursor: pointer;
  transition: filter .14s ease;
}
.ibx-bulk-aud:hover { filter: brightness(1.14); color: var(--pink-tint-text); }
.ibx-bulk-proj { max-width: 160px; }
.ibx-bulk-cancel { margin-left: auto; }

@media (max-width: 640px) {
  .ibx-bulkbar {
    left: 12px; right: 12px; transform: none;
    max-width: none; gap: 8px 12px; bottom: 12px;
  }
  .ibx-bulk-cancel { margin-left: 0; }
}

/* =========================================================================
   4. RESPONSIVE  (phone — canvas #3b: momentum compacts, search goes full width)
   ========================================================================= */

/* Below the masonry breakpoint the pile is a single column, so Next takes the
   full width again and its gestures go back to thumb-sized halves. */
@media (max-width: 700px) {
  .next-focus { max-width: none; }
  .next-gesture { flex: 1; padding: 10px 0; }
}

@media (max-width: 640px) {
  /* sort/show-done drop below the (still scrollable) category row on a phone */
  .ibx-toolbar { flex-wrap: wrap; }
  .ibx-cats { flex-basis: 100%; }
  .mom-bar { gap: 8px 12px; padding: 9px 14px; }
  .mom-divider { display: none; }
  .mom-counts { font-size: 11px; }
  /* let the bar breathe, then drop search to its own full-width row */
  .mom-progress { flex-basis: 100%; order: 5; }
  .mom-fresh { order: 6; }
  .mom-system { order: 7; }
  .mom-search { order: 8; margin-left: 0; flex: 1 1 100%; }
  .mom-search input { width: 100%; flex: 1; }
  .next-line { font-size: 14.5px; }
}

/* =========================================================================
   5. REDUCED MOTION  (still the sparkle + progress; theme.css already caps
      animation-duration, this also neutralises the width transition)
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {
  .next-sparkle { animation: none; opacity: 0.85; }
  .mom-progress-fill { transition: none; }
  .next-gesture { transition: none; }
}
