/* Bulk Actions — hub, multi-file config, progress, results, and the cross-file
   redaction review. Reuses the app's design tokens (auto dark-mode) and the shared
   .kp-enter entrance; all motion is the house rise curve. No @keyframes here on
   purpose — entrances ride .kp-enter (app.css); the rest are cheap transitions. */

/* ── Dashboard banner ─────────────────────────────────────────────────────── */
.dash-bulk-banner {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px 18px;
  /* 28px above clears the Start-here spotlight (matches the .dash-section + .dash-section
     rhythm) — the banner sits between two sections so that adjacency rule can't fire,
     and margin-top:0 left it flush against the tiles, reading as an overlap. */
  margin: 28px 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-elev);
  box-shadow: var(--shadow-sm);
  text-decoration: none;
  color: var(--text);
  transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
}
.dash-bulk-banner:hover { border-color: var(--primary); box-shadow: var(--shadow); transform: translateY(-2px); }
.dash-bulk-banner:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.dash-bulk-icon {
  flex: none; display: block;
  width: 52px; height: 52px; border-radius: 13px; object-fit: cover;
  box-shadow: 0 4px 14px -4px rgba(0, 0, 0, 0.18), 0 1px 2px rgba(0, 0, 0, 0.08);
}
[data-theme="dark"] .dash-bulk-icon { box-shadow: 0 4px 18px -4px rgba(0, 0, 0, 0.55), 0 1px 2px rgba(0, 0, 0, 0.4); }
.dash-bulk-text { display: flex; flex-direction: column; gap: 2px; flex: 1 1 auto; }
.dash-bulk-text strong { font-size: 1.02rem; }
.dash-bulk-text span { color: var(--text-soft); font-size: .9rem; }
.dash-bulk-arrow { flex: none; color: var(--text-mute); transition: transform .15s ease, color .15s ease; }
.dash-bulk-banner:hover .dash-bulk-arrow { color: var(--primary); transform: translateX(3px); }

/* ── Hub grid ─────────────────────────────────────────────────────────────── */
.bulk-hub-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 14px;
}
.bulk-hub-card {
  display: flex; gap: 13px; align-items: flex-start;
  padding: 18px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-elev);
  text-decoration: none; color: var(--text);
  box-shadow: var(--shadow-sm);
  transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
}
.bulk-hub-card:hover { border-color: var(--primary); box-shadow: var(--shadow); transform: translateY(-2px); }
.bulk-hub-card:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.bulk-hub-card.is-featured { grid-column: span 2; border-color: var(--border-strong); background: linear-gradient(180deg, var(--primary-soft), var(--bg-elev) 60%); }
.bulk-hub-icon {
  flex: none; display: block; width: 52px; height: 52px;
  border-radius: 13px; object-fit: cover;
  box-shadow: 0 4px 14px -4px rgba(0, 0, 0, 0.18), 0 1px 2px rgba(0, 0, 0, 0.08);
}
[data-theme="dark"] .bulk-hub-icon { box-shadow: 0 4px 18px -4px rgba(0, 0, 0, 0.55), 0 1px 2px rgba(0, 0, 0, 0.4); }
.bulk-hub-card.is-featured .bulk-hub-icon { width: 58px; height: 58px; }
.bulk-hub-body { display: flex; flex-direction: column; gap: 4px; }
.bulk-hub-body strong { font-size: 1.04rem; }
.bulk-hub-desc { color: var(--text-soft); font-size: .9rem; line-height: 1.45; }
@media (max-width: 640px) { .bulk-hub-card.is-featured { grid-column: span 1; } }

/* ── Config screen ────────────────────────────────────────────────────────── */
.bulk-config { display: flex; flex-direction: column; gap: 16px; }
.bulk-dir-row { margin-top: -6px; }
.bulk-dir-row .btn { display: inline-flex; align-items: center; gap: 7px; }
.bulk-queue-host { display: flex; flex-direction: column; gap: 12px; }
.bulk-queue { display: flex; flex-direction: column; gap: 8px; }
.bulk-queue-row { border-radius: var(--radius); transition: opacity .15s ease; }
.bulk-queue-row.is-locked { opacity: .58; }
.bulk-queue-row .file-item { margin: 0; }
.bulk-queue-idx {
  flex: none; display: grid; place-items: center;
  width: 22px; height: 22px; margin-right: 4px;
  border-radius: 50%; background: var(--bg-soft); color: var(--text-soft);
  font-size: .76rem; font-weight: 600;
}
.bulk-queue-lock {
  align-self: center; margin-right: 6px;
  padding: 2px 7px; border-radius: 999px;
  background: var(--primary-soft); color: var(--primary);
  font-size: .68rem; font-weight: 700; letter-spacing: .03em;
}

/* Options blocks */
.bulk-opts { display: flex; flex-direction: column; gap: 12px; padding-top: 4px; border-top: 1px solid var(--border); }
.bulk-opts-title { font-weight: 600; font-size: .95rem; }
.bulk-opt-field { display: flex; flex-direction: column; gap: 6px; font-size: .9rem; color: var(--text-soft); }
.bulk-opt-field.is-check { flex-direction: row; align-items: center; gap: 9px; }
.bulk-opt-label { font-weight: 500; color: var(--text); }
.bulk-opt-select, .bulk-opt-input {
  padding: 9px 11px; border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  background: var(--bg); color: var(--text); font: inherit; max-width: 420px;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.bulk-opt-select:focus, .bulk-opt-input:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--primary-soft); }
.bulk-opt-range { width: 220px; accent-color: var(--primary); }
.bulk-opt-check { width: 17px; height: 17px; accent-color: var(--primary); }
.bulk-opt-note { font-size: .82rem; margin: 0; }

/* Process All vs Review Each */
.bulk-mode-toggle { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.bulk-mode-btn {
  display: flex; flex-direction: column; gap: 3px; text-align: left;
  padding: 12px 14px; border: 1.5px solid var(--border); border-radius: var(--radius);
  background: var(--bg); color: var(--text); cursor: pointer;
  transition: border-color .15s ease, box-shadow .15s ease, background-color .15s ease;
}
.bulk-mode-btn strong { font-size: .95rem; }
.bulk-mode-btn span { font-size: .82rem; color: var(--text-soft); }
.bulk-mode-btn:hover { border-color: var(--border-strong); }
.bulk-mode-btn.is-active { border-color: var(--primary); background: var(--primary-soft); }
.bulk-mode-btn:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
@media (max-width: 560px) { .bulk-mode-toggle { grid-template-columns: 1fr; } }

/* Sticky action footer — the primary action (Scan / Read / Run / Merge) stays
   pinned to the bottom of the viewport while a long file queue scrolls underneath,
   so the button is always reachable without scrolling past the whole list. It
   settles flush at the card's bottom edge once you've scrolled to the end. The
   bg + top border mask the rows sliding behind it; the -24px side/bottom margins
   cancel the card's 24px padding so the bar spans the full card width.
   Shared by every multi-file batch tool (bulk-*, bulk-redact, rename) and opted
   into by Merge via `.action-bar.is-sticky-foot` (other .action-bar tools, which
   often have content below the bar, are deliberately left alone). */
.bulk-config-foot,
.action-bar.is-sticky-foot {
  position: sticky;
  bottom: 0;
  /* Sticky makes its own stacking context, but z-index:auto paints at level 0 —
     below the page-thumbnail's positioned children (redaction marks z:1, badges
     z:2), so those black boxes bled OVER this bar as a marked thumb scrolled
     behind it. Lift the bar above both so its opaque bg masks everything under. */
  z-index: 3;
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin: 0 -24px -24px;
  padding: 14px 24px;
  background: var(--bg-elev);
  border-top: 1px solid var(--border);
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}
.btn.btn-lg { padding: 12px 22px; font-size: 1rem; }

/* ── Lock notice + warnings ───────────────────────────────────────────────── */
.bulk-lock-notice {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 14px 16px; border: 1px solid var(--primary); border-radius: var(--radius);
  background: var(--primary-soft);
}
.bulk-lock-text { display: flex; flex-direction: column; gap: 3px; flex: 1 1 240px; }
.bulk-lock-text strong { color: var(--text); }
.bulk-lock-text span { font-size: .86rem; color: var(--text-soft); }

.bulk-warnings { display: flex; flex-direction: column; gap: 8px; }
.bulk-warn {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 11px 13px; border-radius: var(--radius); font-size: .86rem; line-height: 1.45;
  border: 1px solid var(--border);
}
.bulk-warn svg { flex: none; margin-top: 1px; }
.bulk-warn-soft { background: var(--bg-soft); color: var(--text-soft); }
.bulk-warn-soft svg { color: var(--text-mute); }
.bulk-warn-hard { background: color-mix(in srgb, var(--danger) 8%, var(--bg-elev)); border-color: color-mix(in srgb, var(--danger) 35%, var(--border)); color: var(--text); }
.bulk-warn-hard svg { color: var(--danger); }

/* ── Progress ─────────────────────────────────────────────────────────────── */
.bulk-progress { display: flex; flex-direction: column; gap: 12px; max-width: 620px; margin: 0 auto; }
.bulk-progress-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.bulk-progress-head h3 { margin: 0; font-size: 1.05rem; }
.bulk-progress-eta { font-size: .85rem; white-space: nowrap; }
.bulk-bar { height: 9px; border-radius: 999px; background: var(--bg-soft); overflow: hidden; }
.bulk-bar-fill {
  height: 100%; width: 100%; transform-origin: left center; transform: scaleX(0);
  background: var(--grad); border-radius: 999px;
  transition: transform .3s cubic-bezier(.2, .7, .3, 1);
}
.bulk-progress.is-paused .bulk-bar-fill { opacity: .55; }
.bulk-progress-status { display: flex; justify-content: space-between; gap: 12px; font-size: .88rem; color: var(--text-soft); }
.bulk-progress-tally { color: var(--text-mute); }
.bulk-current { font-size: .85rem; color: var(--text-soft); min-height: 1.2em; }
.bulk-current-name { display: inline-block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; }
.bulk-progress-actions { display: flex; gap: 8px; }
.bulk-progress-hint { font-size: .8rem; margin: 0; }

/* ── Results ──────────────────────────────────────────────────────────────── */
.bulk-results { display: flex; flex-direction: column; gap: 16px; }
.bulk-results-head { display: flex; align-items: center; gap: 14px; }
.bulk-results-seal { flex: none; display: grid; place-items: center; width: 46px; height: 46px; border-radius: 50%; background: color-mix(in srgb, var(--success) 14%, var(--bg-elev)); color: var(--success); }
.bulk-results-head.has-errors .bulk-results-seal { background: color-mix(in srgb, var(--danger) 14%, var(--bg-elev)); color: var(--danger); }
/* Diagnostic caution (Privacy X-ray found exposure): amber, not the green all-clear.
   Matches the standalone tool's --xray-amber so screen + batch read identically. */
.bulk-results-head.has-exposure .bulk-results-seal { background: color-mix(in srgb, #d97706 16%, var(--bg-elev)); color: #b45309; }
html[data-theme="dark"] .bulk-results-head.has-exposure .bulk-results-seal { color: #fbbf24; }
.bulk-results-headline h3 { margin: 0 0 2px; }
.bulk-results-headline p { margin: 0; font-size: .88rem; }
.bulk-results-actions { display: flex; flex-wrap: wrap; gap: 10px; }
.bulk-artifact-btn { display: inline-flex; align-items: center; gap: 8px; }
.bulk-artifact-btn.is-locked { opacity: .9; }
.bulk-results-list { display: flex; flex-direction: column; gap: 6px; }
.bulk-result-row {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--bg-elev);
  transition: border-color .15s ease;
}
.bulk-result-row.is-err { border-color: color-mix(in srgb, var(--danger) 40%, var(--border)); }
.bulk-result-row.is-caution { border-color: color-mix(in srgb, #d97706 38%, var(--border)); }
.bulk-result-status { flex: none; display: grid; place-items: center; width: 22px; color: var(--success); }
.bulk-result-row.is-err .bulk-result-status { color: var(--danger); }
.bulk-result-row.is-caution .bulk-result-status { color: #b45309; }
html[data-theme="dark"] .bulk-result-row.is-caution .bulk-result-status { color: #fbbf24; }
.bulk-result-name { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: .9rem; }
.bulk-result-meta { flex: none; font-size: .82rem; max-width: 45%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bulk-result-act { flex: none; }
.bulk-results-foot { display: flex; justify-content: center; }

/* ── Portfolio dashboard (Privacy X-ray batch) ─────────────────────────────── */
/* The firm-wide gasp moment. Rises with .bulk-results (.kp-enter), so no local
   animation; nothing here is interactive, so no hover/focus states needed. */
.bulk-portfolio { display: flex; flex-direction: column; gap: 14px; }
.bulk-portfolio-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
.bulk-portfolio-stat { border: 1px solid var(--border); border-radius: var(--radius); padding: 12px 10px; text-align: center; background: var(--bg-elev); }
.bulk-portfolio-stat .n { display: block; font-size: 1.5rem; font-weight: 800; line-height: 1.1; color: var(--text); }
.bulk-portfolio-stat.is-flag .n { color: #b45309; }
html[data-theme="dark"] .bulk-portfolio-stat.is-flag .n { color: #fbbf24; }
.bulk-portfolio-stat .l { display: block; font-size: .72rem; color: var(--text-soft); margin-top: 4px; line-height: 1.3; }
.bulk-portfolio-cats { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.bulk-portfolio-lab { font-size: .78rem; font-weight: 700; color: var(--text-soft); }
.bulk-portfolio-cat { font-size: .78rem; padding: 3px 9px; border-radius: 999px; background: var(--bg-elev); border: 1px solid var(--border); color: var(--text); }
.bulk-portfolio-exposed ul { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-direction: column; }
.bulk-portfolio-exposed li { display: flex; justify-content: space-between; gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--border); font-size: .85rem; }
.bulk-portfolio-exposed li:last-child { border-bottom: 0; }
.bulk-portfolio-file { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bulk-portfolio-verdict { flex: 0 0 auto; text-align: right; color: #b45309; font-weight: 600; }
html[data-theme="dark"] .bulk-portfolio-verdict { color: #fbbf24; }
@media (max-width: 560px) { .bulk-portfolio-stats { grid-template-columns: repeat(2, 1fr); } }

/* ── Redact review ────────────────────────────────────────────────────────── */
.bulk-review-bar {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  position: sticky; top: 8px; z-index: 5;
}
.bulk-review-summary { font-size: .92rem; color: var(--text-soft); flex: 1 1 200px; }
.bulk-review-summary strong { color: var(--text); }
.bulk-uncertain-count { color: #b45309; font-weight: 600; }
.bulk-review-sens select { margin-left: 6px; }
.bulk-review-cats { display: flex; flex-wrap: wrap; gap: 6px; flex: 1 1 100%; order: 3; }
.bulk-cat-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px; border: 1px solid var(--border-strong); border-radius: 999px;
  background: var(--bg); color: var(--text); font-size: .8rem; cursor: pointer;
  transition: border-color .15s ease, opacity .15s ease, background-color .15s ease;
}
.bulk-cat-chip:hover { border-color: var(--primary); }
.bulk-cat-chip:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.bulk-cat-chip.is-off { opacity: .42; text-decoration: line-through; }
.bulk-cat-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--hl, var(--primary)); }
.bulk-cat-n { color: var(--text-mute); font-variant-numeric: tabular-nums; }
.bulk-review-actions { display: flex; gap: 8px; margin-left: auto; }

.bulk-review-files { display: flex; flex-direction: column; gap: 12px; margin-top: 14px; }
.bulk-review-file { padding: 0; overflow: hidden; transition: opacity .15s ease; }
.bulk-review-file.is-excluded { opacity: .5; }
.bulk-review-file-head { display: flex; align-items: center; gap: 12px; padding: 13px 16px; }
.bulk-review-include { display: flex; align-items: center; gap: 10px; flex: 1 1 auto; cursor: pointer; min-width: 0; }
.bulk-review-include input { width: 17px; height: 17px; accent-color: var(--primary); flex: none; }
.bulk-review-fname { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; }
.bulk-review-fmeta { flex: none; font-size: .84rem; color: var(--text-soft); }
.bulk-review-err { color: var(--danger); }
.bulk-review-file-body { padding: 4px 16px 16px; display: flex; flex-direction: column; gap: 14px; border-top: 1px solid var(--border); }
.bulk-pg-loading { padding: 18px 0; text-align: center; font-size: .88rem; }

.bulk-pg { position: relative; max-width: 520px; margin: 0 auto; width: 100%; }
.bulk-pg canvas { display: block; width: 100%; border: 1px solid var(--border); border-radius: var(--radius-sm); }
.bulk-pg-overlay { position: absolute; inset: 0; }
.bulk-pg-num { position: absolute; top: 6px; left: 6px; padding: 2px 7px; border-radius: 999px; background: rgba(15,23,42,.66); color: #fff; font-size: .7rem; }
.bulk-hl {
  position: absolute; box-sizing: border-box; padding: 0; margin: 0;
  border: 2px solid var(--hl); background: transparent; border-radius: 2px; cursor: pointer;
  transition: box-shadow .15s ease;
}
.bulk-hl::before { content: ''; position: absolute; inset: 0; background: var(--hl); opacity: 0; transition: opacity .15s ease; border-radius: 1px; }
.bulk-hl.is-on::before { opacity: .4; }
.bulk-hl.is-uncertain { border-style: dashed; border-color: #f59e0b; }
.bulk-hl.is-uncertain::before { background: #f59e0b; }
.bulk-hl.cat-hidden { display: none; }
.bulk-hl:hover, .bulk-hl:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--bg-elev), 0 0 0 4px var(--hl); z-index: 2; }

/* ── Subject access (DSAR) ───────────────────────────────────────────────────
   One requester per batch — their findings are preserved (dashed slate, off by
   default) in every file. Slate, never --danger: kept means NOT redacted. */
.bulk-subject { display: flex; flex-direction: column; gap: 8px; padding-top: 12px; border-top: 1px solid var(--border); }
.bulk-subject-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.bulk-subject-head { display: inline-flex; align-items: baseline; gap: 8px; }
.bulk-subject-name { font-weight: 600; font-size: .95rem; color: var(--text); }
.bulk-subject-opt { font-weight: 400; font-size: .82rem; }
/* Requester summary chips — populated after the config modal closes. */
.bulk-subject-summary { display: flex; flex-wrap: wrap; gap: 6px; }
.bulk-subject-chip {
  display: inline-flex; align-items: center; max-width: 100%;
  font-size: 12.5px; padding: 3px 9px; border: 1px solid var(--border);
  border-radius: 999px; background: var(--bg); color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* Review screen: the requester's preserved finds */
.bulk-subjectkept-count { color: #64748b; font-weight: 600; }
.bulk-hl.is-subject-kept { border-style: dashed; border-color: #64748b; opacity: .55; transition: box-shadow .15s ease, opacity .15s ease; }
.bulk-hl.is-subject-kept::before { background: #64748b; }
.bulk-hl.is-subject-kept:hover, .bulk-hl.is-subject-kept:focus-visible { opacity: .9; }
