/* =========================================================
   Canonical modal shell — THE one modal system (D49).
   Loaded globally from base.html (after layout.css).
   Emitted by the `modal` macro in templates/macros/ui.html;
   behavior (Escape / focus trap / restore / backdrop dismiss)
   in static/js/ui_modal.js.
   Base geometry moved verbatim from restore_result.css (the
   pre-D49 BEM copy, also duplicated in dashboard.css and
   allowlist_modal.css); only z-index moved onto the --z scale.
   ========================================================= */

.modal[hidden] { display: none; }
.modal {
  position: fixed; inset: 0; z-index: var(--z-modal);
  display: flex; align-items: center; justify-content: center;
}
.modal__backdrop {
  position: absolute; inset: 0;
  background: var(--scrim);
  backdrop-filter: blur(2px);
}
.modal__panel {
  position: relative;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: var(--sp-6);
  max-width: 520px;
  width: calc(100% - var(--sp-6));
  box-shadow: 0 20px 50px rgba(var(--ink-rgb), 0.30);
  display: flex; flex-direction: column; gap: var(--sp-3);
}
.modal__panel h2 { font-size: var(--fs-xl); margin: 0; color: var(--fg); }
.modal__panel p  { margin: 0; font-size: var(--fs-sm); color: var(--fg-2); }
.modal__panel ul { margin: 0; padding-left: var(--sp-5); }
.modal__panel li { font-size: var(--fs-sm); color: var(--fg-2); margin: var(--sp-1) 0; }
/* Two-signal inline error (pattern study F3, D52): hue + a leading glyph so
   the message isn't carried by color alone. The icon is a CSS mask painted
   with currentColor, so every existing `.modal__error` consumer inherits it
   (feature JS fills these nodes via textContent — real inline SVG children
   would be wiped) and it stays out of the accessibility tree. */
.modal__error {
  font-size: var(--fs-sm); color: var(--danger-muted);
  display: flex; align-items: flex-start; gap: var(--sp-2);
}
.modal__error[hidden] { display: none; }
.modal__error::before {
  content: "";
  width: 14px; height: 14px; flex: none;
  margin-top: 2px;  /* optical alignment with the first text line */
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M12 8v4'/%3E%3Cpath d='M12 16h.01'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M12 8v4'/%3E%3Cpath d='M12 16h.01'/%3E%3C/svg%3E") center / contain no-repeat;
}
.modal__error:empty::before { display: none; }
.modal__actions  { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--sp-2); margin-top: var(--sp-3); }
/* Two-CTA "split" row (D49 modifier) — equal-width buttons that wrap to a
   full-width stack once each can't hold ~150px (e.g. two long labels at 360px).
   Used by the onboarding welcome card's "one card, two doors" (spec 2026-07-23). */
.modal__actions--split { justify-content: stretch; }
.modal__actions--split > .btn { flex: 1 1 150px; }

/* ----- Parts (absorbed from report-modal / the 2026-07-11 mockups) ----- */
.modal__head {
  display: flex; align-items: flex-start; gap: var(--sp-3);
}
.modal__head > h2, .modal__head > h3 { flex: 1; }
.modal__ico {
  width: 34px; height: 34px; flex: none;
  border-radius: var(--r-full);
  display: grid; place-items: center;
  background: var(--accent-soft-bg);
  color: var(--accent-soft-fg);
}
.modal__close {
  flex: none;
  /* Always trails to the head's far edge. No-op when a flex:1 title already
     fills the head (its free space is zero), so heads with a title h2/h3 are
     unchanged; heads that lead with an eyebrow (welcome card) get it right. */
  margin-inline-start: auto;
  width: 30px; height: 30px;
  display: grid; place-items: center;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--r-md);
  color: var(--fg-3);
  font-size: var(--fs-lg);
  line-height: 1;
  cursor: pointer;
}
.modal__close:hover { background: var(--surface-muted); color: var(--fg); }
.modal__close:focus-visible { outline: none; box-shadow: var(--sh-focus); }
.modal__eyebrow {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--fg-3);
}
.modal__body { min-height: 0; }
.modal__callout {
  border-left: var(--bw-3) solid var(--accent);
  background: var(--accent-soft-bg);
  border-radius: 0 var(--r-md) var(--r-md) 0;
  padding: var(--sp-3) var(--sp-4);
  display: flex; flex-direction: column; gap: var(--sp-1);
}
.modal__callout .modal__eyebrow { color: var(--accent-soft-fg); }
/* Left slot in the actions row (e.g. "0 of 4 resolved" progress meta) */
.modal__actions .modal__actions-meta {
  flex: 1;
  align-self: center;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--fg-3);
}

/* Danger-tinted callout modifier (e.g. the unreviewed warn band). */
.modal__callout--warn {
  border-left-color: var(--danger);
  background: var(--danger-soft-bg);
}
.modal__callout--warn .modal__eyebrow { color: var(--danger-muted); }

/* ----- Document list + acknowledgement (bulk-download confirm, spec 3) -----
   Selectors are `.modal__panel`-qualified so they win over the generic
   `.modal__panel ul/li/p` defaults above without !important. */
.modal__panel .modal__doclist {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  max-height: 34vh;
  overflow-y: auto;
}
.modal__panel .modal__doc {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  margin: 0;
  padding: var(--sp-1) var(--sp-2);
  border-radius: var(--r-md);
  font-size: var(--fs-sm);
  color: var(--fg-2);
}
.modal__doc:hover { background: var(--surface-muted); }
.modal__doc-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--fg);
}
a.modal__doc-name { text-decoration: none; color: var(--fg); }
a.modal__doc-name:hover { text-decoration: underline; }
a.modal__doc-name:focus-visible {
  outline: none;
  box-shadow: var(--sh-focus);
  border-radius: var(--r-sm);
}
.modal__doc .pill { flex: none; }

.modal__ack {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-2);
  margin-top: var(--sp-2);
  cursor: pointer;
  font-size: var(--fs-sm);
  color: var(--fg);
}
.modal__ack input[type="checkbox"] {
  flex: none;
  margin: 2px 0 0;
  accent-color: var(--brand);
  cursor: pointer;
}
.modal__ack:focus-within { border-radius: var(--r-sm); box-shadow: var(--sh-focus); }

.modal__panel .modal__fineprint {
  font-size: var(--fs-xs);
  color: var(--fg-3);
  line-height: var(--lh-relaxed);
}
.modal__fineprint[hidden] { display: none; }

.modal__panel .modal__status {
  font-size: var(--fs-sm);
  color: var(--accent-soft-fg);
}
.modal__status[hidden] { display: none; }

/* ----- Size modifiers ----- */
.modal--sm .modal__panel { max-width: 420px; }
.modal--lg .modal__panel {
  max-width: none;
  width: min(720px, calc(100% - var(--sp-6)));
  max-height: 85vh;
  overflow: hidden;
}
.modal--lg .modal__body { overflow-y: auto; }

/* Settings shell (/account, 2026-07-16): two-pane popup — icon rail +
   scrolling content pane. Fixed height so section switches don't resize
   the panel. Pane composition (rail/nav/sections) lives in account.css. */
.modal--settings .modal__panel {
  display: grid;
  grid-template-columns: 232px minmax(0, 1fr);
  gap: 0;
  padding: 0;
  max-width: none;
  width: min(880px, calc(100% - var(--sp-6)));
  height: min(620px, calc(100dvh - var(--sp-12)));
  overflow: hidden;
}
@media (max-width: 880px) {
  .modal--settings .modal__panel {
    /* minmax(0,1fr), not 1fr: a bare 1fr track min-sizes to the rail's
       min-content (the horizontal nav strip), widening the whole panel
       past the viewport — values then clip under overflow:hidden. */
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr);
    width: 100%;
    height: 100dvh;
    border-radius: 0;
    border: 0;
  }
}

/* ----- Behavior/appearance modifiers ----- */
/* Blocking (reprompt re-auth): heavier scrim, gold seam, above page modals.
   ui_modal.js skips Escape/trap-exit/backdrop for [data-modal-blocking]. */
.modal--blocking { z-index: calc(var(--z-modal) + 100); }
.modal--blocking .modal__backdrop {
  background: var(--scrim-heavy);
  backdrop-filter: blur(3px);
}
.modal--blocking .modal__panel {
  border-top: var(--bw-3) solid var(--accent);
}
/* Edge-to-edge panel (report modal head/foot own their padding) */
.modal--flush .modal__panel { padding: 0; gap: 0; }
.modal--flush .modal__actions { margin-top: 0; }

/* ----- Generic modal form fields (moved from dashboard.css; used by the
   folder/rename modals — now available to every modal) ----- */
.modal .field {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
}
.modal .field label {
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  color: var(--fg-2);
}
.modal .field input[type="text"],
.modal .field select {
  padding: var(--sp-2) var(--sp-3);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  color: var(--fg);
  font-family: var(--font-sans);
  font-size: 14px;
  transition: border-color 120ms ease, box-shadow 120ms ease;
}
/* Focus border stays --navy-800 (not --border-focus) for Tier-A parity;
   switching to the dark-aware token is a Tier-B normalization. */
.modal .field input[type="text"]:focus,
.modal .field select:focus {
  outline: none;
  border-color: var(--navy-800);
  box-shadow: var(--sh-focus);
}
.modal .field__hint {
  margin: 0;
  font-size: var(--fs-sm);
  color: var(--fg-3);
}
