/* ============================================================
   CCD Design System v2 — MODAL
   Ground-up rebuild 2026-07-01, from tokens.css + type.css.
   Built on native <dialog>: focus trap, ESC-to-close, and the
   backdrop come for free (no JS lib, escapes any stacking context).
   Open with el.showModal(). Floats → gets --shadow-modal + --r-large.

   WHEN: the task interrupts, is bounded (≤ ~5 fields), is safe to
   discard, and does not need the page behind it. Creating a thing,
   confirming a consequence.
   NOT: a form that IS the page's content, or one you fill in
   repeatedly (add a task, edit a row) — those stay inline, where
   the surrounding rows are the context.
   Never hand-roll this as an absolutely-positioned panel: you lose
   the focus trap, ESC, and the backdrop, and you inherit whatever
   stacking context you were dropped into.
   ============================================================ */

.modal {
  padding: 0;
  border: none;
  border-radius: var(--r-large);
  background: var(--float);
  color: var(--ink);
  box-shadow: var(--shadow-modal);
  width: calc(100% - var(--s-7));
  max-width: 460px;
  /* native <dialog> centers itself via margin:auto */

  /* entrance — quick ease-out; discrete props let it animate open/close */
  opacity: 0;
  transform: translateY(8px) scale(.98);
  transition:
    opacity .18s ease-out,
    transform .18s ease-out,
    overlay .18s ease-out allow-discrete,
    display .18s ease-out allow-discrete;
}
/* Grows DOWN, never sideways: a long form gets a scrolling body between a pinned
   head and foot, so the title and the confirm button never leave the screen.
   `display: flex` must stay on [open] -- a bare one here would beat the UA's
   `dialog:not([open]) { display: none }` and every modal would render on load.
   flex-direction must NOT: it is inert while display:none, and on [open] it
   snapped back to `row` the instant the dialog closed while display:flex was
   still transitioning out for .18s -- head/body/foot re-laid out as three
   columns mid-fade (measured 451->92px head, 66->415px foot). That was the
   close "blip". Keep the axis on the bare rule so it survives the close. */
.modal { max-height: min(84vh, 720px); flex-direction: column; }
.modal[open] { display: flex; opacity: 1; transform: none; }
.modal__head, .modal__foot { flex: 0 0 auto; }
.modal__body { flex: 1 1 auto; overflow-y: auto; overscroll-behavior: contain; }
@starting-style { .modal[open] { opacity: 0; transform: translateY(8px) scale(.98); } }

.modal::backdrop {
  background: var(--scrim);
  opacity: 0;
  transition: opacity .18s ease-out, overlay .18s ease-out allow-discrete, display .18s ease-out allow-discrete;
}
.modal[open]::backdrop { opacity: 1; }
@starting-style { .modal[open]::backdrop { opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  .modal, .modal::backdrop { transition: none; }
  .modal { transform: none; }
}

/* Regions ----------------------------------------------------- */
.modal__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s-3);
  padding: var(--card-pad);              /* even 16 all round */
  border-bottom: 1px solid var(--divider);
}
/* Kill the UA <h2> margin — that was the "floating" gap inside the header. */
.modal__title { margin: 0; }
.modal__body { padding: var(--card-pad); }
.modal__body > :first-child { margin-top: 0; }
.modal__body > :last-child  { margin-bottom: 0; }

.modal__foot {
  display: flex;
  justify-content: flex-end;
  gap: var(--s-2);
  padding: var(--card-pad);
  border-top: 1px solid var(--divider);
}

/* Close (×) — ghost icon, muted → ink on hover. */
.modal__close {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; margin: -2px -4px 0 0;
  border: none; border-radius: var(--r-base);
  background: transparent; color: var(--muted);
  cursor: pointer;
  transition: background-color .12s ease, color .12s ease;
}
.modal__close:hover { background: var(--ctl-raise-hover); color: var(--ink); }
.modal__close:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
