/* DCP Keys — page styling. Scoped to #dcp-keys-wrap. Mirrors the
   palette and section/card patterns of dcp_inspector.css so the two
   pages feel like siblings. Phase 1 covers the Identity section
   only; placeholder shells for DKDMs and Issue KDM appear in later
   phases. */

#dcp-keys-wrap {
  --bg: #0f0f10;
  --surface: #1a1a1a;
  --surface2: #1e1e1e;
  --surface3: #262626;
  --border: rgba(255,255,255,0.14);
  --border-light: rgba(255,255,255,0.2);
  --text: #e9e9e9;
  --text-muted: #aaaaaa;
  --text-dim: #888;
  --accent: #d8d8d8;
  --accent-dim: rgba(255,255,255,0.06);
  --ok:   #34d399;
  --warn: #facc15;
  --bad:  #f87171;
  --info: #60a5fa;
  background: var(--bg);
  color: var(--text);
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 12px;
  line-height: 1.5;
}
#dcp-keys-wrap *, #dcp-keys-wrap *::before, #dcp-keys-wrap *::after { box-sizing: border-box; }
/* Page-wide rule: never render italics anywhere under /dcp_keys. Some
   of the site-level / Bootstrap base styles slip italic into otherwise-
   unstyled <em>, <i>, <cite>, etc., and at this body font size italics
   read as visual noise rather than emphasis. We use bold + colour for
   emphasis throughout the page instead. The single * selector is fine
   here — it's scoped to #dcp-keys-wrap so it doesn't bleed into other
   pages. */
#dcp-keys-wrap, #dcp-keys-wrap * { font-style: normal !important; }
/* Strip the Bootstrap-derived `label { margin-bottom: 0.5rem }` that
   ships from the site-level base template. Every list row in this
   page renders as a <label> (so the whole row is a click target for
   the inner checkbox), and Bootstrap's default was adding 8px of
   phantom space below every row — making list rhythm look uneven
   regardless of whatever padding we set. Each row class can still
   set its own explicit margin if it needs one. */
#dcp-keys-wrap label { margin-bottom: 0; }

/* Per-section drop highlight. The whole DKDMs / Recipients section
   gets an info-coloured border + tint while a file is being dragged
   over it, so it's obvious which kind of file the section accepts. */
#dcp-keys-wrap .dck-drop-section { transition: background-color 0.15s; }
#dcp-keys-wrap .dck-drop-section.dck-section-drag-active .chart-card {
  border-color: var(--info);
  background: rgba(96, 165, 250, 0.06);
  box-shadow: 0 0 0 2px rgba(96, 165, 250, 0.25);
}

/* Inline drop banner replacing the old big-square dropzone — small
   click-to-browse affordance + reminder that the whole section is a
   drop target. */
#dcp-keys-wrap .dck-section-drop-banner {
  border: 1px dashed var(--border-light);
  background: var(--surface2);
  padding: 10px 14px;
  margin-bottom: 12px;
  font-size: 11px;
  color: var(--text-muted);
  display: flex;
  /* baseline keeps the 13px label and the smaller link sitting on
     the same text baseline; align-items:center would line up their
     box centers and the link would float visually higher. */
  align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
}

#dcp-keys-wrap #dck-app {
  padding: 24px 28px;
  max-width: 1100px;
  width: 100%;
  margin: 0 auto;
}

/* ─── Header ────────────────────────────────────── */
#dcp-keys-wrap #dck-app-header {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  margin-bottom: 24px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--border);
  gap: 12px;
}
#dcp-keys-wrap #dck-app-header .title-group {
  display: flex; align-items: center; gap: 12px; flex-shrink: 0;
}
#dcp-keys-wrap #dck-title {
  font-size: 18px;
  font-weight: 600;
  letter-spacing: -0.3px;
}
/* "How this works" button — small, low-key, sits next to the title. */
#dcp-keys-wrap .dck-how-btn {
  font-size: 11px;
  font-family: inherit;
  color: var(--info);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 3px 9px;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}
#dcp-keys-wrap .dck-how-btn:hover {
  background: rgba(255,255,255,0.06);
  border-color: var(--info);
}

/* Modal overlay + card. position:fixed so it floats above sticky nav. */
#dcp-keys-wrap .dck-how-overlay {
  position: fixed;
  inset: 0;
  z-index: 1050;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 80px 16px 32px;
  background: rgba(0,0,0,0.65);
  overflow-y: auto;
  animation: dck-how-fade 0.18s ease-out;
}
@keyframes dck-how-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}
#dcp-keys-wrap .dck-how-modal {
  background: var(--surface2);
  border: 1px solid var(--border);
  border-radius: 6px;
  width: 100%;
  max-width: 720px;
  box-shadow: 0 12px 40px rgba(0,0,0,0.5);
  animation: dck-how-pop 0.18s ease-out;
}
@keyframes dck-how-pop {
  from { transform: translateY(-8px); opacity: 0; }
  to   { transform: translateY(0);    opacity: 1; }
}
#dcp-keys-wrap .dck-how-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 18px;
  border-bottom: 1px solid var(--border);
}
#dcp-keys-wrap .dck-how-header h3 {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.2px;
}
#dcp-keys-wrap .dck-how-close {
  background: transparent;
  border: none;
  color: var(--text-dim);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  padding: 0 6px;
  border-radius: 3px;
  transition: color 0.15s, background 0.15s;
}
#dcp-keys-wrap .dck-how-close:hover {
  color: var(--text);
  background: rgba(255,255,255,0.08);
}
#dcp-keys-wrap .dck-how-body {
  padding: 16px 18px 18px;
  font-size: 12px;
  line-height: 1.55;
  color: var(--text);
}
#dcp-keys-wrap .dck-how-intro {
  margin: 0 0 14px;
  color: var(--text-muted);
}

/* Three-actor legend pills at the top of the flowchart. */
#dcp-keys-wrap .dck-how-legend {
  display: flex;
  gap: 8px;
  margin-bottom: 16px;
  flex-wrap: wrap;
}
#dcp-keys-wrap .dck-actor {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  padding: 2px 8px;
  border-radius: 10px;
  white-space: nowrap;
}
#dcp-keys-wrap .dck-actor-you    { background: rgba(81, 162, 255, 0.18); color: var(--info); }
#dcp-keys-wrap .dck-actor-house  { background: rgba(255, 184, 76, 0.18); color: #ffb84c; }
#dcp-keys-wrap .dck-actor-cinema { background: rgba(108, 219, 130, 0.18); color: #6cdb82; }

/* The flow chart itself — a numbered vertical list. Each <li> shows the
   actor doing the work, an optional arrow to a recipient actor, and the
   step description. The CSS counter renders the step number in a
   circular badge on the left, and the <li> draws a vertical connecting
   line down to the next step. */
#dcp-keys-wrap .dck-how-steps {
  list-style: none;
  counter-reset: dck-step;
  padding: 0;
  margin: 0 0 14px;
}
#dcp-keys-wrap .dck-how-steps li {
  counter-increment: dck-step;
  position: relative;
  padding: 10px 0 10px 38px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 8px;
}
#dcp-keys-wrap .dck-how-steps li::before {
  content: counter(dck-step);
  position: absolute;
  left: 0;
  top: 10px;
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--surface3);
  border: 1px solid var(--border);
  font-size: 11px;
  font-weight: 600;
  color: var(--text-muted);
}
#dcp-keys-wrap .dck-how-steps li:not(:last-child)::after {
  content: '';
  position: absolute;
  left: 11px;        /* center of the 24-wide number badge */
  top: 34px;         /* bottom of badge */
  width: 1px;
  bottom: -4px;
  background: var(--border);
}
#dcp-keys-wrap .dck-how-steps .dck-step-arrow {
  color: var(--text-dim);
  font-size: 12px;
  margin: 0 2px;
}
#dcp-keys-wrap .dck-how-steps .dck-step-body {
  flex: 1 1 100%;
  margin-left: 0;
  margin-top: 2px;
  color: var(--text);
}
#dcp-keys-wrap .dck-how-steps li em {
  color: var(--info);
}
#dcp-keys-wrap .dck-how-footer {
  margin: 14px 0 0;
  padding-top: 14px;
  border-top: 1px solid var(--border);
  color: var(--text-muted);
  font-size: 11px;
  line-height: 1.55;
}
#dcp-keys-wrap #dck-app-header .header-row-2 {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  font-size: 11px;
  color: var(--text-muted);
}
/* Floating notification banner. `position: fixed` (not `sticky`) so it
   stays glued to the viewport regardless of scroll position — sticky
   only works inside the parent's scroll context, and would fall out of
   view once the user scrolled past long sections. The site-wide navbar
   is itself sticky at top:0, height ~55px, z-index 1030, so we park
   below it (top: 55px) and out-rank its z-index so any intermediate
   stacking context can't slip in front of us. */
#dcp-keys-wrap #dck-status {
  position: fixed;
  top: 64px;
  left: 50%;
  transform: translateX(-50%);
  width: calc(100% - 32px);
  max-width: 720px;
  z-index: 1040;
  font-size: 12px;
  padding: 10px 36px 10px 14px;   /* extra right padding for the × button */
  background: var(--surface3);
  border: 1px solid var(--border);
  border-left: 3px solid var(--info);
  border-radius: 4px;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.35);
  /* Soft fade/slide-in. The [hidden] attribute disables display
     entirely, so the animation only runs on the show path. */
  animation: dck-status-in 0.18s ease-out;
}
#dcp-keys-wrap #dck-status[data-tone="error"] {
  border-left-color: var(--bad);
}
#dcp-keys-wrap #dck-status .dck-status-close {
  position: absolute;
  top: 6px;
  right: 8px;
  width: 20px;
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  color: var(--text-dim);
  cursor: pointer;
  font-size: 16px;
  line-height: 1;
  padding: 0;
  border-radius: 3px;
  transition: color 0.15s, background 0.15s;
}
#dcp-keys-wrap #dck-status .dck-status-close:hover {
  color: var(--text);
  background: rgba(255, 255, 255, 0.08);
}
@keyframes dck-status-in {
  from { opacity: 0; transform: translate(-50%, -8px); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}

/* ─── Section heading + chart card (mirror inspector) ──── */
#dcp-keys-wrap .section-heading {
  display: flex; align-items: center; gap: 10px; margin-bottom: 12px;
  cursor: pointer; user-select: none;
}
#dcp-keys-wrap .section-heading h2 {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  text-transform: uppercase;
  letter-spacing: 0.6px;
  margin: 0;
}
/* Chevron — flips when the section collapses, mirrors the Inspector
   pattern so the two pages feel consistent. */
#dcp-keys-wrap .section-heading h2::before {
  content: '▾';
  display: inline-block;
  margin-right: 6px;
  color: var(--text-dim);
  font-size: 10px;
  width: 10px;
  text-align: center;
  transition: transform 0.15s ease;
}
#dcp-keys-wrap .dck-section.collapsed .section-heading h2::before {
  transform: rotate(-90deg);
}
#dcp-keys-wrap .dck-section.collapsed > .chart-card { display: none; }
#dcp-keys-wrap .dck-section.collapsed { margin-bottom: 12px; }
#dcp-keys-wrap .section-heading .heading-line {
  flex: 1;
  height: 1px;
  background: var(--border);
}
#dcp-keys-wrap .dck-section { margin-bottom: 28px; }
#dcp-keys-wrap .chart-card {
  background: var(--surface);
  border: 1px solid var(--border);
  /* Asymmetric vertical padding — same rationale as the list-row
     padding: keep the top generous so headings and descriptions
     don't crowd the top border, but tighten the bottom so sections
     with little content (e.g. an unexpanded Recipients section)
     don't leave a deep gutter below their last child. */
  padding: 18px 20px 10px;
}
#dcp-keys-wrap .cat-sub {
  font-size: 11px;
  color: var(--text-muted);
  margin-bottom: 14px;
  line-height: 1.5;
}

/* ─── Banners ───────────────────────────────────── */
#dcp-keys-wrap .dck-banner {
  font-size: 11px;
  line-height: 1.5;
  padding: 10px 14px;
  margin-bottom: 18px;
  border-left: 3px solid;
  background: var(--surface3);
}
#dcp-keys-wrap .dck-banner strong { color: var(--text); font-weight: 600; }
#dcp-keys-wrap .dck-banner-warn {
  border-left-color: var(--warn);
  background: rgba(250, 204, 21, 0.08);
}
#dcp-keys-wrap .dck-banner-warn strong { color: var(--warn); }
#dcp-keys-wrap .dck-banner ul { margin: 6px 0 0 18px; padding: 0; }
#dcp-keys-wrap .dck-banner li { margin-top: 2px; }

/* ─── Identity empty / form / details ───────────── */
#dcp-keys-wrap .dck-empty {
  margin-bottom: 18px;
  font-size: 11px;
  color: var(--text-muted);
  line-height: 1.6;
}
#dcp-keys-wrap .dck-empty-line { margin: 0 0 8px; }
#dcp-keys-wrap .dck-empty-line strong { color: var(--warn); }

#dcp-keys-wrap .dck-legacy-warning {
  border: 1px solid var(--bad, #c62828);
  background: rgba(198, 40, 40, 0.08);
  padding: 10px 12px;
  margin: 0 0 14px;
  font-size: 11px;
  line-height: 1.55;
  border-radius: 3px;
  color: var(--text);
}
#dcp-keys-wrap .dck-legacy-warning strong { color: var(--bad, #c62828); display: block; margin-bottom: 4px; }

#dcp-keys-wrap .dck-form { display: flex; flex-direction: column; gap: 12px; }
#dcp-keys-wrap .dck-form-row {
  display: grid;
  grid-template-columns: 140px 1fr;
  align-items: center;
  gap: 8px 14px;
}
#dcp-keys-wrap .dck-form-row label {
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.7px;
  color: var(--text-muted);
}
#dcp-keys-wrap .dck-form-row input {
  background: var(--surface2);
  color: var(--text);
  border: 1px solid var(--border);
  padding: 6px 9px;
  font-size: 12px;
  font-family: inherit;
  width: 100%;
}
#dcp-keys-wrap .dck-form-row input:focus {
  outline: none;
  border-color: var(--info);
  box-shadow: 0 0 0 1px var(--info);
}
#dcp-keys-wrap .dck-form-row .dck-hint {
  grid-column: 2;
  font-size: 10px;
  color: var(--text-dim);
  margin-top: -2px;
}
/* Live normalization preview shown beneath the cert-chain identifier
   input when the typed value differs from what will be saved (e.g. the
   user typed spaces and they'll become dashes). Inherits font-size from
   .dck-hint above but uses the accent colour so it reads as a system
   message rather than static help text. */
#dcp-keys-wrap .dck-form-row .dck-preview {
  grid-column: 2;
  font-size: 10px;
  color: var(--info);
  margin-top: -2px;
}
/* Form row variant where the input is a checkbox: aligns the box and
   its inline label into the value column without the small-caps label
   on the left, then the hint sits below as usual. */
#dcp-keys-wrap .dck-form-row.dck-form-row-checkbox {
  grid-template-columns: 1fr;     /* one column — checkbox + label inline */
}
#dcp-keys-wrap .dck-form-row.dck-form-row-checkbox .dck-hint {
  grid-column: 1;
}
#dcp-keys-wrap .dck-checkbox-label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  font-weight: 600;
  color: var(--text);
  cursor: pointer;
  text-transform: none;            /* override .dck-form-row label uppercase */
  letter-spacing: normal;
}
#dcp-keys-wrap .dck-checkbox-label input[type="checkbox"] {
  width: auto;
  flex: 0 0 auto;
  margin: 0;
  cursor: pointer;
}

/* "Restore from backup…" row above the gen form. Mirrors the action
   button styling of the empty-state form but sits as its own block. */
#dcp-keys-wrap .dck-restore-row {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  margin-bottom: 14px;
  padding: 12px 14px;
  border: 1px dashed var(--border-light);
  background: var(--surface2);
}
#dcp-keys-wrap .dck-restore-row .dck-form-hint {
  text-transform: none;
  letter-spacing: normal;
  font-size: 11px;
  color: var(--text-muted);
  flex: 1 1 200px;
  min-width: 0;
}

#dcp-keys-wrap .dck-form-row .dck-preview code {
  font-family: 'Menlo','Consolas',monospace;
  font-size: 10px;
  color: var(--info);
  background: rgba(0, 0, 0, 0.15);
  padding: 0 4px;
  border-radius: 2px;
}

#dcp-keys-wrap .dck-primary-btn,
#dcp-keys-wrap .dck-danger-btn {
  background: var(--surface2);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 7px 14px;
  cursor: pointer;
  font-size: 11px;
  font-family: inherit;
  letter-spacing: 0.4px;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
}
#dcp-keys-wrap .dck-primary-btn:hover { border-color: var(--border-light); }
#dcp-keys-wrap .dck-primary-btn:disabled {
  color: var(--text-dim); cursor: default; opacity: 0.6;
}
#dcp-keys-wrap .dck-danger-btn { color: var(--bad); }
#dcp-keys-wrap .dck-danger-btn:hover {
  border-color: rgba(248,113,113,0.4);
  background: rgba(248,113,113,0.08);
}

#dcp-keys-wrap .dck-progress {
  margin-top: 8px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
#dcp-keys-wrap .dck-progress-stage {
  font-size: 10px;
  color: var(--text-muted);
  font-family: 'Menlo','Consolas',monospace;
}
#dcp-keys-wrap .dck-progress-bar {
  height: 4px;
  background: var(--surface3);
  border: 1px solid var(--border);
  overflow: hidden;
}
#dcp-keys-wrap .dck-progress-fill {
  width: 0%;
  height: 100%;
  background: var(--info);
  transition: width 120ms linear;
}

/* ─── Identity — collapsed (compact) mode ──────── */
/* Single-row summary shown after every page load. Click anywhere on
   the row to expand to the full identity card. Visually low-key — a
   subtle hover highlight signals it's interactive without competing
   with the action buttons in other sections. */
#dcp-keys-wrap .dck-identity-collapsed {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 10px 14px;
  background: var(--surface2);
  border: 1px solid var(--border);
  border-radius: 4px;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
  font-size: 12px;
}
#dcp-keys-wrap .dck-identity-collapsed:hover {
  background: var(--surface3);
  border-color: var(--info);
}
#dcp-keys-wrap .dck-collapsed-main {
  display: flex;
  align-items: center;
  gap: 14px;
  min-width: 0;
  flex: 1;
}
#dcp-keys-wrap .dck-collapsed-cn {
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
}
#dcp-keys-wrap .dck-collapsed-thumb {
  font-size: 11px;
  color: var(--text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
#dcp-keys-wrap .dck-collapsed-meta {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-shrink: 0;
}
#dcp-keys-wrap .dck-collapsed-expiry {
  font-size: 11px;
  color: var(--text-muted);
}
#dcp-keys-wrap .dck-collapsed-expiry.dck-expired {
  color: var(--bad);
  font-weight: 600;
}
#dcp-keys-wrap .dck-collapsed-chevron {
  font-size: 13px;
  color: var(--text-dim);
}

/* ─── Identity details ─────────────────────────── */
/* Wrapper around the expanded identity content. The Collapse button
   is pinned to the upper-right of this box via absolute positioning,
   keeping it out of the action-row that lives at the bottom. The
   wrapper also reserves a bit of right padding so long-running values
   in the grid (cert fingerprints) don't bump into the button. */
#dcp-keys-wrap .dck-identity-expanded-wrap {
  position: relative;
  padding-right: 100px;
}
#dcp-keys-wrap .dck-identity-collapse-btn {
  position: absolute;
  top: 0;
  right: 0;
  font-family: inherit;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  padding: 4px 12px;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-dim);
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
}
#dcp-keys-wrap .dck-identity-collapse-btn:hover {
  color: var(--info);
  border-color: var(--info);
  background: rgba(96, 165, 250, 0.06);
}
/* On narrow viewports the absolute button can crowd the grid — drop
   the reserved padding below a tight breakpoint and let the button
   float to the top of the panel above the content instead. */
@media (max-width: 560px) {
  #dcp-keys-wrap .dck-identity-expanded-wrap {
    padding-right: 0;
    padding-top: 36px;
  }
}

#dcp-keys-wrap .dck-identity-grid {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 6px 14px;
  font-size: 12px;
  margin-bottom: 16px;
}
#dcp-keys-wrap .dck-lbl {
  color: var(--text-muted);
  text-transform: uppercase;
  font-size: 9px;
  letter-spacing: 0.7px;
  align-self: center;
}
#dcp-keys-wrap .dck-val { color: var(--text); word-break: break-all; }
#dcp-keys-wrap .dck-val.mono { font-family: 'Menlo','Consolas',monospace; }
#dcp-keys-wrap .dck-val.dck-expired { color: var(--bad); font-weight: 600; }
#dcp-keys-wrap .dck-thumbprint {
  background: var(--surface2);
  padding: 3px 6px;
  border: 1px solid var(--border);
  font-size: 11px;
}

#dcp-keys-wrap .dck-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 18px;
}

#dcp-keys-wrap .dck-details {
  margin-top: 8px;
  border: 1px solid var(--border);
}
#dcp-keys-wrap .dck-details summary {
  cursor: pointer;
  padding: 6px 10px;
  font-size: 10px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.6px;
  list-style: none;
  background: var(--surface2);
}
#dcp-keys-wrap .dck-details summary::-webkit-details-marker { display: none; }
#dcp-keys-wrap .dck-details summary::before { content: '▸ '; color: var(--text-dim); }
#dcp-keys-wrap .dck-details[open] summary::before { content: '▾ '; }
#dcp-keys-wrap .dck-pem {
  margin: 0;
  padding: 10px 12px;
  font-family: 'Menlo','Consolas',monospace;
  font-size: 11px;
  color: var(--text);
  background: var(--bg);
  white-space: pre-wrap;
  word-break: break-all;
}

/* ─── Placeholder cards for Phase 2/5 sections ─── */
#dcp-keys-wrap .dck-placeholder {
  font-size: 11px;
  color: var(--text-dim);
  padding: 16px 0;
}

/* ─── DKDM section ─────────────────────────────── */
#dcp-keys-wrap .dck-dropzone {
  border: 1.5px dashed var(--border-light);
  background: var(--surface2);
  padding: 28px 20px;
  text-align: center;
  margin-bottom: 16px;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}
#dcp-keys-wrap .dck-dropzone:hover,
#dcp-keys-wrap .dck-dropzone.dck-dropzone-active {
  border-color: var(--info);
  background: rgba(96, 165, 250, 0.05);
}
#dcp-keys-wrap .dck-dropzone-label {
  font-size: 13px;
  color: var(--text);
  margin-bottom: 4px;
}
#dcp-keys-wrap .dck-dropzone-hint {
  font-size: 11px;
  color: var(--text-muted);
}
#dcp-keys-wrap .dck-link {
  color: var(--info);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
#dcp-keys-wrap .dck-dkdm-card {
  border: 1px solid var(--border);
  background: var(--surface2);
  padding: 12px 14px;
  margin-top: 10px;
}
#dcp-keys-wrap .dck-dkdm-card-head {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin-bottom: 8px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--border);
}
#dcp-keys-wrap .dck-dkdm-card-title {
  flex: 1;
  font-size: 12px;
  font-weight: 600;
  color: var(--text);
  word-break: break-all;
}
#dcp-keys-wrap .dck-card-remove {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-dim);
  padding: 2px 8px;
  cursor: pointer;
  font-size: 11px;
  font-family: inherit;
}
#dcp-keys-wrap .dck-card-remove:hover {
  color: var(--bad);
  border-color: rgba(248, 113, 113, 0.4);
  background: rgba(248, 113, 113, 0.08);
}
#dcp-keys-wrap .dck-dkdm-card-grid {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 6px 16px;          /* roomier than the previous 4×12 */
  font-size: 11px;
  font-style: normal;     /* defeat any inherited italics from site.css / Bootstrap */
  margin-top: 12px;       /* breathing room between summary row and detail grid */
  padding-top: 10px;
  border-top: 1px dashed var(--border);
}
/* Values inside the detail grid must render upright even if a parent
   container slipped into italic somewhere (the previous screenshot
   showed slanted CPL IDs and dates — this kills that). */
#dcp-keys-wrap .dck-dkdm-card-grid .dck-val,
#dcp-keys-wrap .dck-dkdm-card-grid .dck-lbl {
  font-style: normal;
}
#dcp-keys-wrap .dck-validity-ok   { color: var(--text); }
#dcp-keys-wrap .dck-validity-warn { color: var(--warn); }
#dcp-keys-wrap .dck-validity-bad  { color: var(--bad); }
#dcp-keys-wrap .dck-validity-note {
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  margin-left: 6px;
}
#dcp-keys-wrap .dck-keytype-badge {
  display: inline-block;
  font-family: 'Menlo','Consolas',monospace;
  font-size: 10px;
  padding: 1px 5px;
  background: var(--surface3);
  border: 1px solid var(--border);
  margin-left: 4px;
}

/* ─── Recipients section (Phase 5) ────────────── */
/* Scrollable container around the recipient cards. Caps the section
   height so the page stays compact once the user has accumulated
   many recipients; cards beyond the cap scroll within. */
#dcp-keys-wrap .dck-recipient-list {
  max-height: 360px;
  overflow-y: auto;
  border: 1px solid var(--border);
  background: var(--bg);
}
#dcp-keys-wrap .dck-recipient-card {
  border-bottom: 1px solid var(--border);
  background: var(--surface2);
}
#dcp-keys-wrap .dck-recipient-card:last-child { border-bottom: none; }
/* Unified row spacing across all three list components (CPL picker,
   Generate-KDM recipient picker, Recipients management list).
   Symmetric vertical padding + tight line-height + per-row border
   gives every list the same visual rhythm. The card-expanded variant
   keeps the same outer padding — the .dck-recipient-detail block
   inside handles its own top margin / divider, so the row's bottom
   padding stays consistent whether expanded or not. */
#dcp-keys-wrap .dck-recipient-card-collapsed { padding: 8px 12px; line-height: 1.2; }
#dcp-keys-wrap .dck-recipient-card-expanded  { padding: 8px 12px; line-height: 1.2; }
#dcp-keys-wrap .dck-recipient-card-editing {
  border-color: var(--info);
  background: rgba(96, 165, 250, 0.04);
  padding: 12px 14px;
}

/* Organization groups in the Recipients section. Whole group is a
   collapsible folder so a chain with many screens reads as one row
   in the default view. Inside, member recipient cards render as
   normal (their own per-card chevron still works). */
#dcp-keys-wrap .dck-recipient-groups {
  display: flex;
  flex-direction: column;
  /* No outer padding or gap — each group carries its own
     border-bottom so the stack reads as one flush list, matching
     the other two pickers (CPL list / Generate-KDM recipient list).
     Eliminates the inconsistent 4px gutter / 4px gaps that made
     this list feel different from the other two. */
  border: 1px solid var(--border);
  background: var(--surface2);
}
#dcp-keys-wrap .dck-recipient-groups > .dck-recipient-group + .dck-recipient-group {
  border-top: 1px solid var(--border);
}
#dcp-keys-wrap .dck-recipient-group {
  background: var(--surface2);
  overflow: hidden;
}
#dcp-keys-wrap .dck-recipient-group-expanded {
  background: var(--bg);
}
#dcp-keys-wrap .dck-recipient-group-header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  cursor: pointer;
  font-size: 12px;
  /* Explicit tight line-height — without this the header inherits
     the wrapper's 1.5 line-height, which makes the row substantially
     taller than its content needs (the 12px text gets an 18px line
     box, so the box appears half-empty when collapsed). */
  line-height: 1.2;
  transition: background 0.12s;
}
#dcp-keys-wrap .dck-recipient-group-header:hover {
  background: var(--surface3);
}
#dcp-keys-wrap .dck-recipient-group .dck-group-name {
  font-weight: 600;
  color: var(--text);
  flex: 1 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
#dcp-keys-wrap .dck-recipient-group .dck-group-count {
  font-size: 10px;
  color: var(--text-dim);
  background: var(--surface3);
  border-radius: 10px;
  padding: 1px 7px;
  flex: 0 0 auto;
}
#dcp-keys-wrap .dck-recipient-group .dck-group-expired {
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--bad);
  border: 1px solid rgba(248, 113, 113, 0.4);
  padding: 1px 6px;
  border-radius: 3px;
  flex: 0 0 auto;
}
/* Group body — the cards inside an expanded group. No internal
   padding; each card has its own symmetric 8px/12px padding +
   border-bottom, so the list reads as a flush stack. The first
   card sits directly below the group header's border-bottom, and
   the last card's border is dropped via :last-child elsewhere. */
#dcp-keys-wrap .dck-recipient-group-expanded .dck-recipient-list {
  display: flex;
  flex-direction: column;
  border-top: 1px solid var(--border);
  /* Indent the cards 16px from the group header's left edge so the
     hierarchy reads. */
  padding-left: 0;
}
#dcp-keys-wrap .dck-recipient-group-expanded .dck-recipient-card {
  padding-left: 28px;
}

/* Single-line summary row: friendly name · notes · pem-name + actions
   on the right. Long values truncate so the row stays one line tall.
   Shared with `.dck-dkdm-summary` — same flex layout, same chevron,
   different inner content. */
#dcp-keys-wrap .dck-recipient-summary,
#dcp-keys-wrap .dck-dkdm-summary {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  min-height: 28px;
}
/* The DKDM summary is whole-row clickable (the recipient one isn't —
   it has edit-able sub-elements). Hover hint helps signal that. */
#dcp-keys-wrap .dck-dkdm-summary {
  cursor: pointer;
  border-radius: 3px;
  margin: -4px -6px;
  padding: 4px 6px;
  transition: background 0.12s;
  font-style: normal;       /* defeat any inherited italics */
}
#dcp-keys-wrap .dck-dkdm-summary:hover { background: rgba(255,255,255,0.04); }
/* DKDM titles are usually longer than recipient names — let them
   take up more of the row before truncating. Recipient summaries
   keep their tighter 30% cap so the notes/file columns get airtime.
   Force upright text — earlier renders showed slanted titles on
   some font fallbacks; this guarantees a normal weight rendering. */
#dcp-keys-wrap .dck-dkdm-summary .dck-summary-name {
  max-width: 55%;
  font-style: normal;
}
#dcp-keys-wrap .dck-dkdm-summary .dck-summary-days,
#dcp-keys-wrap .dck-dkdm-summary .dck-status-pill {
  font-style: normal;
}

/* Status pill — coloured "VALID" / "EXPIRED" / "NOT YET" badge that
   sits next to the title in DKDM and (future) other lists. Mirrors
   the actor-pill vocabulary in the "How this works" modal so the
   page uses one consistent colour code for state. */
#dcp-keys-wrap .dck-status-pill {
  display: inline-flex;
  align-items: center;
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  padding: 2px 7px;
  border-radius: 10px;
  flex: 0 0 auto;
}
#dcp-keys-wrap .dck-status-pill-ok      { background: rgba(108, 219, 130, 0.18); color: #6cdb82; }
#dcp-keys-wrap .dck-status-pill-warn    { background: rgba(255, 184, 76, 0.18); color: #ffb84c; }
#dcp-keys-wrap .dck-status-pill-bad     { background: rgba(248, 113, 113, 0.18); color: var(--bad); }
#dcp-keys-wrap .dck-status-pill-unknown { background: rgba(255,255,255,0.06); color: var(--text-dim); }

/* "12 days left" / "expired 3 days ago" — sits next to the status pill,
   takes the remaining horizontal space, dims out so the pill is the
   loud element. */
#dcp-keys-wrap .dck-summary-days {
  font-size: 11px;
  color: var(--text-muted);
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

#dcp-keys-wrap .dck-summary-name {
  font-weight: 600;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 30%;
}
#dcp-keys-wrap .dck-summary-sep {
  color: var(--text-dim);
  flex: 0 0 auto;
}
#dcp-keys-wrap .dck-summary-notes {
  color: var(--text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1 1 auto;
  min-width: 0;
}
#dcp-keys-wrap .dck-summary-file {
  color: var(--text-dim);
  font-size: 11px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 25%;
}
#dcp-keys-wrap .dck-summary-empty { opacity: 0.6; }
#dcp-keys-wrap .dck-summary-expired {
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--bad);
  border: 1px solid rgba(248, 113, 113, 0.4);
  padding: 1px 5px;
  flex: 0 0 auto;
}
#dcp-keys-wrap .dck-summary-actions {
  display: inline-flex;
  gap: 4px;
  margin-left: auto;          /* anchor to the right edge of the row */
  padding-left: 16px;         /* visual separation from content cluster */
  flex: 0 0 auto;
  justify-content: flex-end;
}

/* Expand/collapse triangle — sized down to feel like an inline glyph
   rather than a button. No padding, no hover background, just colour
   tint on hover. */
#dcp-keys-wrap .dck-card-toggle {
  background: transparent;
  border: none;
  color: var(--text-dim);
  cursor: pointer;
  font-size: 9px;
  font-family: inherit;
  padding: 0;
  width: 12px;
  height: 12px;
  line-height: 12px;
  flex: 0 0 12px;
  text-align: center;
  opacity: 0.7;
}
#dcp-keys-wrap .dck-card-toggle:hover { color: var(--info); opacity: 1; }

/* Detail grid (rendered only when expanded) — slightly indented and
   visually separated from the summary row. */
#dcp-keys-wrap .dck-recipient-detail {
  margin-top: 10px;
  padding-top: 8px;
  padding-left: 22px;
  border-top: 1px dashed var(--border);
}

/* Edit button — same shape / size as remove button, sits next to it */
#dcp-keys-wrap .dck-card-edit {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-dim);
  padding: 2px 8px;
  cursor: pointer;
  font-size: 11px;
  font-family: inherit;
}
#dcp-keys-wrap .dck-card-edit:hover {
  color: var(--info);
  border-color: rgba(96, 165, 250, 0.4);
  background: rgba(96, 165, 250, 0.08);
}
/* Inline edit form layout */
#dcp-keys-wrap .dck-recipient-edit-grid {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
#dcp-keys-wrap .dck-recipient-edit-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
#dcp-keys-wrap .dck-add-recipient {
  margin-top: 6px;
  border: 1px dashed var(--border-light);
  background: var(--surface2);
  padding: 0;
}
#dcp-keys-wrap .dck-add-recipient summary {
  cursor: pointer;
  padding: 10px 14px;
  font-size: 11px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.6px;
  list-style: none;
}
#dcp-keys-wrap .dck-add-recipient summary::-webkit-details-marker { display: none; }
#dcp-keys-wrap .dck-add-recipient summary::before { content: '▸ '; color: var(--text-dim); }
#dcp-keys-wrap .dck-add-recipient[open] summary::before { content: '▾ '; }
#dcp-keys-wrap .dck-add-recipient-body {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 0 14px 14px;
}
#dcp-keys-wrap .dck-add-recipient-row {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

/* Form bits used by Recipients + Issue KDM */
#dcp-keys-wrap .dck-form-label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 11px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}
#dcp-keys-wrap .dck-form-label > input,
#dcp-keys-wrap .dck-form-label > select,
#dcp-keys-wrap .dck-form-label > textarea {
  font-family: 'Menlo','Consolas',monospace;
  font-size: 12px;
  padding: 8px 10px;
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--text);
  text-transform: none;
  letter-spacing: normal;
}
#dcp-keys-wrap .dck-form-label > input:focus,
#dcp-keys-wrap .dck-form-label > select:focus,
#dcp-keys-wrap .dck-form-label > textarea:focus {
  outline: none;
  border-color: var(--info);
}
#dcp-keys-wrap .dck-form-label > textarea { resize: vertical; min-height: 96px; }
#dcp-keys-wrap .dck-form-hint {
  text-transform: none;
  letter-spacing: normal;
  color: var(--text-dim);
  font-size: 10px;
}
#dcp-keys-wrap .dck-btn {
  font-family: inherit;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  padding: 8px 16px;
  background: var(--surface2);
  border: 1px solid var(--border);
  color: var(--text);
  cursor: pointer;
}
#dcp-keys-wrap .dck-btn:hover { border-color: var(--border-light); }
#dcp-keys-wrap .dck-btn-primary {
  background: var(--info);
  color: var(--bg);
  border-color: var(--info);
}
#dcp-keys-wrap .dck-btn-primary:hover { background: var(--info); opacity: 0.9; }
/* Disabled state: greyed out, no hover lift, not-allowed cursor.
   Applies to any .dck-btn — primary or otherwise. */
#dcp-keys-wrap .dck-btn:disabled,
#dcp-keys-wrap .dck-btn-primary:disabled {
  background: var(--surface2);
  color: var(--text-dim);
  border-color: var(--border);
  cursor: not-allowed;
  opacity: 0.6;
}
#dcp-keys-wrap .dck-btn:disabled:hover,
#dcp-keys-wrap .dck-btn-primary:disabled:hover {
  background: var(--surface2);
  border-color: var(--border);
  opacity: 0.6;
}
/* Hint text shown next to the Generate button switches to a warn
   tint when surfacing a blocker reason instead of the default copy. */
#dcp-keys-wrap .dck-form-hint-warn {
  color: var(--warn);
  font-style: normal;
}

/* ─── Issue KDM form ──────────────────────────── */
#dcp-keys-wrap .dck-issue-form {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
/* When a form-label wraps one of the bordered list boxes (CPL picker
   or recipient checklist), give the box a bit of breathing room from
   the label text above. Symmetric with the 14px gap between sections
   below so the box reads as a self-contained card with balanced
   margins, not as a tight extension of the label text. */
#dcp-keys-wrap .dck-form-label > .dck-cpl-picker,
#dcp-keys-wrap .dck-form-label > .dck-recipient-checklist {
  margin-top: 8px;
}
/* Multi-select recipient checklist for batch KDM issuance. The
   container is height-capped + scrolls when the list grows. */
#dcp-keys-wrap .dck-recipient-checklist {
  border: 1px solid var(--border);
  background: var(--bg);
  display: flex;
  flex-direction: column;
}
#dcp-keys-wrap .dck-checklist-controls {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 10px;
  background: var(--surface2);
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
}
#dcp-keys-wrap .dck-checklist-btn {
  font-family: inherit;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  padding: 3px 10px;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-muted);
  cursor: pointer;
}
#dcp-keys-wrap .dck-checklist-btn:hover { color: var(--text); border-color: var(--border-light); }
#dcp-keys-wrap .dck-checklist-count {
  margin-left: auto;
  font-size: 11px;
  color: var(--text-muted);
  font-family: 'Menlo','Consolas',monospace;
}
#dcp-keys-wrap .dck-checklist-items {
  max-height: 320px;
  overflow-y: auto;
}
/* Search row sits above the Select-all controls. Live filter; ×
   button clears the field. */
#dcp-keys-wrap .dck-checklist-search {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  background: var(--surface2);
  border-bottom: 1px solid var(--border);
}
#dcp-keys-wrap .dck-checklist-search input {
  flex: 1 1 auto;
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 4px 8px;
  font-size: 11px;
  font-family: inherit;
  border-radius: 2px;
}
#dcp-keys-wrap .dck-checklist-search input:focus {
  outline: none;
  border-color: var(--info);
  box-shadow: 0 0 0 1px var(--info);
}
/* Organization grouping inside the checklist. Each org gets a
   header row with its own checkbox (toggles every member in the
   group) and a tinted background so groups read as folders. */
#dcp-keys-wrap .dck-issue-group {
  border-bottom: 1px solid var(--border);
}
#dcp-keys-wrap .dck-issue-group:last-child { border-bottom: none; }
#dcp-keys-wrap .dck-issue-group-header {
  background: var(--surface2);
  /* Symmetric vertical padding matching every other list-row /
     list-header pair in the page (CPL picker, Recipients management
     list). 8px / 12px with line-height: 1.2 is the unified pattern. */
  padding: 8px 12px;
  line-height: 1.2;
  border-bottom: 1px solid var(--border);
}
#dcp-keys-wrap .dck-issue-group-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  font-size: 11px;
  /* Bootstrap-margin kill — this is a <label> too. */
  margin: 0;
  text-transform: none;
  letter-spacing: normal;
}
#dcp-keys-wrap .dck-issue-group-toggle .dck-group-name {
  font-weight: 600;
  color: var(--text);
  flex: 1 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
#dcp-keys-wrap .dck-issue-group-toggle .dck-group-count {
  font-size: 10px;
  color: var(--text-dim);
  background: var(--surface3);
  border-radius: 10px;
  padding: 1px 7px;
}
/* Recipient rows inside a group indent slightly so the hierarchy
   reads at a glance. */
#dcp-keys-wrap .dck-issue-group-body .dck-recipient-checkbox-row {
  padding-left: 28px;
}

/* CPL picker — same outer chrome as the recipient checklist (border,
   stacked search → controls → list), but rows are radio-selectable
   single-select instead of multi-select checkboxes. */
#dcp-keys-wrap .dck-cpl-picker {
  border: 1px solid var(--border);
  background: var(--bg);
  display: flex;
  flex-direction: column;
}
#dcp-keys-wrap .dck-cpl-items {
  max-height: 260px;
  overflow-y: auto;
}
#dcp-keys-wrap .dck-cpl-row {
  display: flex;
  align-items: center;
  gap: 10px;
  /* Symmetric vertical padding + tight line-height, matching the
     other two list components (Generate-KDM recipient checklist
     and Recipients management list). All three lists now read with
     the same rhythm. */
  padding: 8px 12px;
  /* Kill the global Bootstrap-derived `label { margin-bottom: 0.5rem }`
     that ships from the base template. Without this override, every
     <label class="dck-cpl-row"> was getting an extra 8px below it,
     making rows look "weird" — a perceived asymmetric gap that's
     actually a phantom margin sitting between rows. */
  margin: 0;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  font-size: 12px;
  line-height: 1.2;
  text-transform: none;
  letter-spacing: normal;
  transition: background 0.12s;
}
#dcp-keys-wrap .dck-cpl-row:last-child { border-bottom: none; }
#dcp-keys-wrap .dck-cpl-row:hover { background: var(--surface2); }
#dcp-keys-wrap .dck-cpl-row-selected {
  background: rgba(81, 162, 255, 0.10);
  border-left: 2px solid var(--info);
  padding-left: 10px;        /* compensate the 2px border so row text doesn't shift */
}
#dcp-keys-wrap .dck-cpl-row-selected:hover {
  background: rgba(81, 162, 255, 0.15);
}
#dcp-keys-wrap .dck-cpl-row-main {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
#dcp-keys-wrap .dck-cpl-title {
  color: var(--text);
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  line-height: 1.3;
}
/* CPL UUID + meta row sits under the title. The UUID is shown in
   full so a user can copy/paste it; it's allowed to wrap on narrow
   viewports rather than truncating with an ellipsis, since you
   genuinely need the whole string to match it against an external
   reference. Title above still ellipsises if too long. */
#dcp-keys-wrap .dck-cpl-meta {
  color: var(--text-dim);
  font-size: 11px;
  word-break: break-all;
  line-height: 1.3;
}
#dcp-keys-wrap .dck-cpl-meta .mono {
  font-family: 'Menlo','Consolas',monospace;
  color: var(--text-muted);
}

/* Shown in place of the "Loading…" placeholder when JS bootstrap
   fails. The status banner at the top of the page carries the full
   error; this is the inline equivalent so the empty section panels
   don't read as "perpetually loading". */
#dcp-keys-wrap .dck-bootstrap-error {
  padding: 14px 16px;
  border-left: 3px solid var(--bad);
  background: rgba(248, 113, 113, 0.06);
  color: var(--text);
  font-size: 12px;
  line-height: 1.5;
}
#dcp-keys-wrap .dck-bootstrap-error-detail {
  display: block;
  margin-top: 4px;
  color: var(--text-muted);
  font-size: 11px;
}

/* Drop-import review modal. Reuses the .dck-how-overlay / .dck-how-modal
   chrome from the How-this-works modal — same backdrop, animation, and
   close-button. Inside, a cert preview block (read-only) sits above the
   editable form, with action buttons pinned at the bottom. */
#dcp-keys-wrap .dck-import-modal {
  max-width: 560px;
}
#dcp-keys-wrap .dck-import-progress {
  font-size: 11px;
  color: var(--text-muted);
  margin-bottom: 12px;
  padding: 6px 10px;
  background: var(--surface3);
  border-left: 2px solid var(--info);
  border-radius: 2px;
}
#dcp-keys-wrap .dck-import-progress[hidden] { display: none; }
#dcp-keys-wrap .dck-import-cert-preview {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 6px 14px;
  padding: 12px 14px;
  margin-bottom: 14px;
  background: var(--surface3);
  border: 1px solid var(--border);
  border-radius: 3px;
  font-size: 11px;
}
#dcp-keys-wrap .dck-import-cert-row {
  display: contents;     /* let the spans land directly in the grid */
}
#dcp-keys-wrap .dck-import-cert-preview .dck-lbl {
  font-size: 9px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.7px;
  align-self: center;
}
#dcp-keys-wrap .dck-import-cert-preview .dck-val {
  color: var(--text);
  font-style: normal;
  word-break: break-all;
}
#dcp-keys-wrap .dck-import-cert-preview .dck-val.mono {
  font-family: 'Menlo','Consolas',monospace;
}
#dcp-keys-wrap .dck-import-actions {
  display: flex;
  gap: 10px;
  justify-content: flex-end;
  margin-top: 16px;
}
#dcp-keys-wrap .dck-recipient-checkbox-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  /* Kill the inherited Bootstrap `label { margin-bottom: 0.5rem }`
     that would otherwise add 8px of phantom space below every
     row. See .dck-cpl-row for the same fix. */
  margin: 0;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  font-size: 12px;
  line-height: 1.2;
  text-transform: none;
  letter-spacing: normal;
}
#dcp-keys-wrap .dck-recipient-checkbox-row:last-child { border-bottom: none; }
#dcp-keys-wrap .dck-recipient-checkbox-row:hover { background: var(--surface2); }
#dcp-keys-wrap .dck-recipient-checkbox-name {
  color: var(--text);
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1 1 auto;
  min-width: 0;
}
#dcp-keys-wrap .dck-recipient-checkbox-meta {
  color: var(--text-dim);
  font-size: 10px;
  flex: 0 0 auto;
}
#dcp-keys-wrap .dck-recipient-checkbox-flag {
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--bad);
  border: 1px solid rgba(248, 113, 113, 0.4);
  padding: 1px 5px;
  flex: 0 0 auto;
}
#dcp-keys-wrap .dck-recipient-checkbox-expired .dck-recipient-checkbox-name { color: var(--text-dim); }
#dcp-keys-wrap .dck-issue-tz {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 10px 12px;
  background: var(--surface2);
  border: 1px solid var(--border);
}
#dcp-keys-wrap .dck-tz-status {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  font-size: 11px;
}
#dcp-keys-wrap .dck-tz-current {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  font-family: 'Menlo','Consolas',monospace;
  color: var(--text);
}
/* Live wall-clock at the selected venue. Slightly louder than the
   surrounding muted text so the eye lands on it — this is the thing
   the user actually wants to see when picking a timezone for KDM
   delivery. */
#dcp-keys-wrap .dck-tz-clock {
  color: var(--text);
  font-weight: 600;
}
#dcp-keys-wrap .dck-tz-offset {
  color: var(--info);
  font-weight: 600;
}
#dcp-keys-wrap .dck-tz-revert {
  color: var(--text-dim);
}
#dcp-keys-wrap .dck-tz-revert .dck-link {
  color: var(--info);
  font-family: inherit;
}
#dcp-keys-wrap .dck-issue-validity {
  display: grid;
  /* Three columns: Valid-from (date+time), Valid-until (date+time),
     and Window-length. The date-pair columns are equal-width and
     flexible; the duration column is fixed-narrow since it only
     ever holds a short string like "30 days". */
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) 130px;
  gap: 14px;
  align-items: end;
}
@media (max-width: 720px) {
  #dcp-keys-wrap .dck-issue-validity {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }
  #dcp-keys-wrap .dck-issue-validity .dck-form-label-duration {
    grid-column: 1 / -1;
  }
}
@media (max-width: 480px) {
  #dcp-keys-wrap .dck-issue-validity { grid-template-columns: 1fr; }
}
/* The split date+time pair inside each validity field. Date input
   stretches; time input is fixed-width and tabular-numeric so HH:MM
   reads as a clock. Used instead of <input type="datetime-local"> to
   bypass Safari's locale-dependent 12-hour rendering — see comment
   on dckIsoLocalInTz in dcp_keys.js. */
#dcp-keys-wrap .dck-datetime-pair {
  display: flex;
  gap: 6px;
  align-items: stretch;
  min-width: 0;
}
#dcp-keys-wrap .dck-datetime-pair input[type="date"] {
  flex: 1 1 auto;
  min-width: 0;
}
#dcp-keys-wrap .dck-datetime-pair input[type="text"] {
  flex: 0 0 68px;
  text-align: center;
  font-variant-numeric: tabular-nums;
  font-family: 'Menlo','Consolas',monospace;
  padding-left: 4px;
  padding-right: 4px;
}
#dcp-keys-wrap .dck-datetime-pair input[type="text"]:invalid {
  border-color: var(--bad);
  box-shadow: 0 0 0 1px var(--bad);
}
/* Duration column. Plain text input — auto-formats on blur via
   dckParseDuration + dckFormatDuration. */
#dcp-keys-wrap .dck-form-label-duration input {
  width: 100%;
  text-align: left;
}
/* FM-flags box — was a <fieldset> originally, but those have browser
   defaults (margin-block-end, min-block-size: min-content, weird
   legend baseline alignment in Safari) that rendered extra empty
   space at the bottom. Plain div with a heading row is cleaner. */
#dcp-keys-wrap .dck-fm-flags {
  border: 1px solid var(--border);
  background: var(--surface2);
  padding: 10px 14px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 12px;
  color: var(--text);
}
#dcp-keys-wrap .dck-fm-flags-legend {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--text-muted);
  margin-bottom: 2px;
}
#dcp-keys-wrap .dck-fm-flags label {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: 'Menlo','Consolas',monospace;
  font-size: 11px;
}
#dcp-keys-wrap .dck-issue-actions {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}

/* ─── History pane ────────────────────────────────── */
/* The History section lists every KDM the user has issued via this
   browser (sourced from dcpCrypto.listIssuedKdms / STORE_KDM_LOG).
   Layout = a search box on top, then a table with one row per audit
   record. Validity dates are status-coloured so the user can scan
   the list and spot which KDMs are currently valid vs expired. */
#dcp-keys-wrap .dck-history-toolbar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-bottom: 12px;
}
#dcp-keys-wrap .dck-history-search {
  flex: 1;
  min-width: 200px;
  background: var(--surface2);
  border: 1px solid var(--border);
  color: var(--text);
  font: inherit;
  padding: 6px 10px;
}
#dcp-keys-wrap .dck-history-search:focus {
  outline: none;
  border-color: var(--info);
}
#dcp-keys-wrap .dck-history-count {
  font-size: 11px;
  color: var(--text-dim);
  font-family: 'Menlo','Consolas',monospace;
  white-space: nowrap;
  /* Reserve a stable slot so filter changes that swap "3 of 3
     records" for "12 of 12 records" don't tug at the flex-1 search
     input's width. */
  min-width: 110px;
  text-align: right;
}
/* Validity-status filter pills in the toolbar. Three pills, one per
   status (Valid / Expired / Future). Each pill is "active" (tinted to
   its status colour) by default; clicking toggles to "muted" (faint
   neutral grey) so the user can hide records of that status. */
#dcp-keys-wrap .dck-history-status-filter {
  display: inline-flex;
  gap: 4px;
  align-items: center;
}
#dcp-keys-wrap .dck-history-status-pill {
  font-family: 'Menlo','Consolas',monospace;
  font-size: 10px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  padding: 4px 9px;
  /* Lock each pill to a fixed width regardless of its label so the
     toolbar doesn't reshape on toggle. Without this, sub-pixel glyph
     rendering of "Valid" / "Expired" / "Future" at different
     foreground colours can drift the pill width by a fraction of a
     pixel, which the flex-1 search input then absorbs visibly. */
  min-width: 64px;
  text-align: center;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-dim);
  cursor: pointer;
  border-radius: 2px;
  /* Suppress the UA focus ring — the pill's active/muted styling is
     the focus / state affordance. The default ring (an outline that
     sits OUTSIDE the box but ABOVE neighbouring content) is what
     made the toolbar appear to shift on click. */
  outline: none;
  transition: background 0.12s, color 0.12s, border-color 0.12s, opacity 0.12s;
}
#dcp-keys-wrap .dck-history-status-pill:hover {
  border-color: var(--border-light);
}
#dcp-keys-wrap .dck-history-status-pill:focus-visible {
  /* Keyboard navigation still needs a focus indicator. Use a tight
     box-shadow that sits ON TOP of the pill rather than outside it,
     so it doesn't push neighbours. */
  box-shadow: 0 0 0 2px rgba(96, 165, 250, 0.6);
}
/* Muted state — the pill is "off"; records of this status are hidden. */
#dcp-keys-wrap .dck-history-status-pill.is-muted {
  opacity: 0.45;
}
/* Active state — tint the pill to match the row colour used inside
   the table so the connection is obvious. */
#dcp-keys-wrap .dck-history-status-pill.dck-history-status-valid.is-active {
  background: rgba(52, 211, 153, 0.14);
  border-color: var(--ok);
  color: var(--ok);
}
#dcp-keys-wrap .dck-history-status-pill.dck-history-status-expired.is-active {
  background: rgba(248, 113, 113, 0.14);
  border-color: var(--bad);
  color: var(--bad);
}
#dcp-keys-wrap .dck-history-status-pill.dck-history-status-future.is-active {
  background: rgba(255, 255, 255, 0.06);
  border-color: var(--border-light);
  color: var(--text);
}
/* Scroll wrapper around the table — fixed at ~10 rows tall so the
   pane keeps a stable footprint regardless of how many records the
   user has. Sticky header keeps the column titles visible as the
   user scrolls through long histories. The exact row count assumes
   ~38px per row plus ~30px header; tweak if row padding changes.
   Switched from max-height to a fixed height so the pane doesn't
   collapse to a tiny strip when the cache is empty / filtered to
   zero rows — the consistent footprint stops the page below from
   jumping around as history changes. */
#dcp-keys-wrap .dck-history-scroll {
  height: 410px;
  overflow-y: auto;
  border: 1px solid var(--border);
  background: var(--surface);
}
/* Centered placeholder for the empty-state (no records at all). Used
   in lieu of the table; takes the full scroll-container height and
   centers a bold grey title vertically + horizontally. */
#dcp-keys-wrap .dck-history-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  font-size: 18px;
  font-weight: 700;
  color: var(--text-dim);
  letter-spacing: 0.5px;
  text-transform: uppercase;
  user-select: none;
}
#dcp-keys-wrap .dck-history-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
  table-layout: fixed;          /* makes column widths predictable */
}
/* Column widths: CPL takes the largest slice, Target middle, the
   Re-issue button column is narrow + content-sized. fixed layout
   means the browser respects these rather than negotiating from
   content. */
#dcp-keys-wrap .dck-history-table .dck-h-th-cpl    { width: 55%; }
#dcp-keys-wrap .dck-history-table .dck-h-th-target { width: 30%; }
#dcp-keys-wrap .dck-history-table .dck-h-th-action { width: 15%; }
#dcp-keys-wrap .dck-history-scroll .dck-history-table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  /* Re-paint the background here because <table> backgrounds
     don't naturally stay opaque when their cells go sticky. */
  background: var(--surface2);
}
#dcp-keys-wrap .dck-history-table th,
#dcp-keys-wrap .dck-history-table td {
  text-align: left;
  padding: 8px 10px;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}
/* Pair the two tr rows belonging to one record: drop the bottom
   border on the main row and the top spacing on the meta row so they
   read as one block, then keep the meta row's bottom border to
   separate records. */
#dcp-keys-wrap .dck-history-table tr.dck-h-main > td {
  border-bottom: none;
  padding-bottom: 2px;
}
#dcp-keys-wrap .dck-history-table tr.dck-h-meta > td {
  padding-top: 2px;
  padding-bottom: 10px;
  font-size: 11px;
  color: var(--text-dim);
  font-family: 'Menlo','Consolas',monospace;
}
#dcp-keys-wrap .dck-history-table tr.dck-h-meta .dck-h-meta-label {
  text-transform: uppercase;
  letter-spacing: 0.5px;
  font-size: 9px;
  color: var(--text-muted);
  margin-right: 4px;
}
#dcp-keys-wrap .dck-history-table tr.dck-h-meta .dck-h-meta-value {
  margin-right: 8px;
}
#dcp-keys-wrap .dck-history-table tr.dck-h-meta .dck-h-meta-sep {
  color: var(--border-light);
  margin-right: 6px;
}
/* Status tag inline next to the validity range — small badge so the
   colour reads even on the dim meta row. */
#dcp-keys-wrap .dck-history-table tr.dck-h-meta .dck-h-meta-tag {
  display: inline-block;
  font-size: 9px;
  letter-spacing: 0.6px;
  padding: 1px 6px;
  border-radius: 2px;
  margin-left: 6px;
  background: rgba(255,255,255,0.05);
}
#dcp-keys-wrap .dck-history-table tr.dck-h-meta .dck-h-meta-tag.dck-h-valid    { color: var(--ok);   background: rgba(52, 211, 153, 0.12); }
#dcp-keys-wrap .dck-history-table tr.dck-h-meta .dck-h-meta-tag.dck-h-expired  { color: var(--bad);  background: rgba(248, 113, 113, 0.12); }
#dcp-keys-wrap .dck-history-table tr.dck-h-meta .dck-h-meta-tag.dck-h-future   { color: var(--text-dim); background: rgba(255,255,255,0.05); }
/* The Re-issue action cell rowspans both rows; vertically centre it
   between the main and meta lines for a tidy look. */
#dcp-keys-wrap .dck-history-table td.dck-h-action {
  vertical-align: middle;
  text-align: right;
  white-space: nowrap;
}
#dcp-keys-wrap .dck-history-table th {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--text-muted);
  font-weight: 600;
  background: var(--surface2);
  border-bottom: 1px solid var(--border);
}
/* Hover highlight, applied to BOTH rows of a record at once. Each
   record is a pair of <tr>s (.dck-h-main + .dck-h-meta) — a bare
   `tr:hover` would only light up whichever row the cursor is over,
   making the two halves of one record look like two separate hover
   targets.
   Baseline rule (works in every browser):
     1) main hovered            → main is lit
     2) main hovered + adjacent → meta below it is lit
     3) meta hovered            → meta is lit */
#dcp-keys-wrap .dck-history-table tr.dck-h-main:hover,
#dcp-keys-wrap .dck-history-table tr.dck-h-main:hover + tr.dck-h-meta,
#dcp-keys-wrap .dck-history-table tr.dck-h-meta:hover {
  background: rgba(255, 255, 255, 0.02);
}
/* :has() rule kept separate so browsers that don't understand it
   still apply the three baseline selectors above. Adds the
   "hover the meta row → light up the main above" case via
   previous-sibling-by-:has. Chrome 105+, Safari 15.4+, FF 121+. */
#dcp-keys-wrap .dck-history-table tr.dck-h-main:has(+ tr.dck-h-meta:hover) {
  background: rgba(255, 255, 255, 0.02);
}
#dcp-keys-wrap .dck-history-table .dck-h-cpl {
  font-weight: 600;
  color: var(--text);
}
#dcp-keys-wrap .dck-history-table .dck-h-cpluuid {
  font-family: 'Menlo','Consolas',monospace;
  font-size: 9px;
  color: var(--text-dim);
  display: block;
  margin-top: 2px;
}
#dcp-keys-wrap .dck-history-table .dck-h-recipient {
  color: var(--text);
}
#dcp-keys-wrap .dck-history-table .dck-h-tp {
  font-family: 'Menlo','Consolas',monospace;
  font-size: 9px;
  color: var(--text-dim);
  display: block;
  margin-top: 2px;
}
#dcp-keys-wrap .dck-history-table .dck-h-issued {
  font-family: 'Menlo','Consolas',monospace;
  font-size: 11px;
  color: var(--text-dim);
  white-space: nowrap;
}
#dcp-keys-wrap .dck-history-table .dck-h-date {
  font-family: 'Menlo','Consolas',monospace;
  font-size: 11px;
  white-space: nowrap;
}
/* Validity status colouring — applied to the cell containing the
   Valid-From → Valid-Until range. Tone classes:
     dck-h-valid    → currently within the window (green)
     dck-h-expired  → past the end (red)
     dck-h-future   → start hasn't arrived yet (grey)
*/
#dcp-keys-wrap .dck-history-table .dck-h-valid {
  color: var(--ok, #4caf50);
}
#dcp-keys-wrap .dck-history-table .dck-h-expired {
  color: var(--bad, #e64a3a);
}
#dcp-keys-wrap .dck-history-table .dck-h-future {
  color: var(--text-dim);
}
#dcp-keys-wrap .dck-history-table .dck-h-action {
  text-align: right;
  white-space: nowrap;
}
#dcp-keys-wrap .dck-history-empty {
  padding: 20px 12px;
  color: var(--text-dim);
  font-size: 12px;
  text-align: center;
  background: var(--surface2);
  border: 1px dashed var(--border);
}
