/* Modal dialog - see the _Dialog partial. Replaces the browser's alert()/confirm(), which cannot be
   branded, cannot be styled, and on some browsers carries a "prevent this page from creating more
   dialogs" checkbox that lets a customer permanently silence a warning we need them to read.

   Its own file for the same reason busy-overlay.css is: BOTH layouts need it. The storefront loads
   site.css and the ops console loads admin.css, so anything defined in either one is invisible to
   the other half of the app - including .btn, which is why this file styles its own buttons instead
   of reusing the ones the storefront already has.

   Every colour is a token that resolves in BOTH scopes, using var() fallbacks where the two design
   systems disagree on the name:
     --panel  -> admin's surface; the storefront has no --panel, so it falls back to --surface
     --accent -> admin's blue;    the storefront has no --accent, so it falls back to --brand (coral)
   That is deliberate: the same dialog reads as FogMonkey on the storefront and as the neutral ops
   console in admin, without a second stylesheet or a wrapper class. */

.fm-dlg {
  width: min(92vw, 430px);
  padding: 0;
  border: none;
  border-radius: calc(var(--r-card, 16px) + 4px);
  background: var(--panel, var(--surface));
  color: var(--ink);
  font-family: var(--font-ui);
  box-shadow: 0 30px 70px -20px rgba(0, 0, 0, 0.45), 0 0 0 1px var(--line);
  overflow: hidden;
}

/* ::backdrop does NOT inherit custom properties from :root in every engine, so the scrim is a
   literal colour rather than a token. Kept neutral so it works over both the warm storefront and
   the slate console. */
.fm-dlg::backdrop {
  background: rgba(24, 20, 17, 0.5);
  backdrop-filter: blur(3px);
}

.fm-dlg-body {
  padding: 26px 26px 0;
  display: flex;
  gap: 15px;
}

/* Tone badge. The colour pair is set per tone below; only the geometry lives here. */
.fm-dlg-ic {
  flex: none;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
}
.fm-dlg-ic svg {
  width: 21px;
  height: 21px;
  stroke: currentColor;
  fill: none;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.fm-dlg-txt {
  min-width: 0;
}
.fm-dlg h2 {
  margin: 3px 0 7px;
  font-size: 17px;
  font-weight: 800;
  letter-spacing: -0.01em;
  line-height: 1.3;
}
.fm-dlg p {
  margin: 0;
  font-size: 14px;
  line-height: 1.55;
  color: var(--muted);
}

.fm-dlg-acts {
  display: flex;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: 9px;
  padding: 22px 26px 24px;
}

/* min-height 44px is not padding taste - it is the minimum touch target size (WCAG 2.5.5 AAA,
   and Apple's HIG). At 11px padding these measured 42px on a phone, which is the size at which
   people miss and hit the one next to it. inline-flex rather than inline-block so min-height
   actually centres the label, and so the <a> variant matches the <button> exactly. */
.fm-dlg-btn {
  border: 1.5px solid transparent;
  border-radius: 12px;
  padding: 11px 19px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  font: 700 13.5px var(--font-ui);
  cursor: pointer;
  background: var(--accent, var(--brand));
  color: #fff;
}
.fm-dlg-btn:hover {
  filter: brightness(0.93);
}
.fm-dlg-btn:focus-visible {
  outline: 2px solid var(--accent, var(--brand));
  outline-offset: 2px;
}
/* Secondary = the way out. Always present on a confirm, never on a notice. */
.fm-dlg-btn.sec {
  background: transparent;
  color: var(--ink);
  border-color: var(--line);
}
.fm-dlg-btn.sec:hover {
  background: var(--bg);
  filter: none;
}
/* Destructive primary. Outlined rather than a loud red fill: the point is to make the customer read
   it, not to make the button the most attractive thing on screen. */
.fm-dlg-btn.danger {
  background: var(--errbg);
  color: var(--err);
  border-color: var(--errline, var(--err));
}
.fm-dlg-btn.danger:hover {
  filter: none;
  background: var(--err);
  color: #fff;
}
/* A link rendered as a button - an escape hatch that goes somewhere useful ("View cart"). */
a.fm-dlg-btn {
  text-decoration: none;
}

/* ---------- tones ---------- */
.fm-dlg[data-tone="warn"] .fm-dlg-ic {
  background: var(--warnbg);
  color: var(--warn);
}
.fm-dlg[data-tone="error"] .fm-dlg-ic {
  background: var(--errbg);
  color: var(--err);
}
.fm-dlg[data-tone="success"] .fm-dlg-ic {
  background: var(--okbg);
  color: var(--ok);
}
.fm-dlg[data-tone="info"] .fm-dlg-ic {
  background: var(--accentbg, var(--brand2));
  color: var(--accent, var(--brandink));
}

/* ---------- entrance ---------- */
/* [open] rather than a class: the native dialog element sets it, so nothing has to be kept in sync. */
@keyframes fm-dlg-in {
  from {
    opacity: 0;
    transform: translateY(10px) scale(0.97);
  }
}
.fm-dlg[open] {
  animation: fm-dlg-in 0.16s ease-out;
}

@media (prefers-reduced-motion: reduce) {
  .fm-dlg[open] {
    animation: none;
  }
  .fm-dlg::backdrop {
    backdrop-filter: none;
  }
}

@media (max-width: 460px) {
  .fm-dlg-acts {
    /* Stacked and full-width on a phone, primary on top - thumb reach beats visual convention when
       the row would otherwise wrap into two ragged halves. */
    flex-direction: column-reverse;
  }
  .fm-dlg-acts .fm-dlg-btn {
    width: 100%;
  }
}

/* ── fm-modal: a full EDITOR in a dialog, as opposed to .fm-dlg above, which is a confirm prompt.
   Separate class rather than a variant of .fm-dlg because the two want opposite things: a confirm
   is a short fixed-size message that must not scroll, an editor is arbitrarily tall and must.
   Sharing one class would mean every rule carrying an exception for the other case.

   Used by Admin > Catalog's TLD editor, opened with showModal() so the backdrop, focus trap and
   Escape are the browser's rather than ours. */
.fm-modal {
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 0;
  background: var(--bg);
  color: var(--fg);
  /* min() not a bare vw/vh: on a short laptop window the editor is taller than the viewport, and a
     fixed height would put the Save button off-screen - which is the bug this modal exists to fix,
     reintroduced one layer in. */
  width: min(760px, calc(100vw - 32px));
  max-height: min(860px, calc(100vh - 48px));
  overflow: hidden;
  display: flex;
  flex-direction: column;
  box-shadow: 0 18px 50px rgba(0, 0, 0, .28);
}

.fm-modal::backdrop {
  /* Same reason as .fm-dlg::backdrop: ::backdrop does not inherit custom properties from :root in
     every engine, so the scrim is a literal. */
  background: rgba(15, 23, 42, .45);
}

.fm-modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 15px 24px;
  border-bottom: 1px solid var(--line);
  /* Sticky so the operator always knows which TLD they are editing and can always get out, however
     far down the form they have scrolled. */
  position: sticky;
  top: 0;
  background: var(--bg);
  z-index: 1;
}

.fm-modal-close {
  font-size: 22px;
  line-height: 1;
  text-decoration: none;
  color: var(--faint);
  padding: 2px 8px;
  border-radius: 8px;
}

.fm-modal-close:hover { color: var(--fg); background: var(--line2); }

.fm-modal-body {
  padding: 16px 24px 20px;
  overflow-y: auto;

  /* flex:1 AND min-height:0, and the second one is the whole bug this had.
     A flex child will not shrink below its content height without min-height:0, so overflow-y:auto
     never engages, the body stays as tall as its content, and the parent's overflow:hidden simply
     CLIPS the bottom off. The visible symptom is an editor whose Save button does not exist - which
     is the same complaint the modal was built to fix, one layer in. */
  flex: 1 1 auto;
  min-height: 0;
}

/* Sticky footer for the PRIMARY action.
   The editor is long and holds four independent forms; the price form is the one an operator came
   for, so its Save is pinned rather than left at whatever scroll position it lands on. The other
   three forms keep their own inline buttons next to the fields they submit - a footer button that
   saves "whichever section you were last looking at" would be worse than scrolling. */
.fm-modal-foot {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 24px;
  border-top: 1px solid var(--line);
  background: var(--bg);
  flex: 0 0 auto;
}

.fm-modal-foot .spacer { flex: 1; }

/* Section rhythm inside the editor. The four forms ran together as one grey wall; these give each
   one a headed band so the eye can find where a section starts and what its fields belong to. */
/* 36px of combined padding+margin between sections was most of the empty space in this dialog.
   22 reads as a clear break without the sections drifting apart. */
.fm-modal-body .fm-sec { padding-top: 14px; margin-top: 8px; border-top: 1px solid var(--line); }
.fm-modal-body .fm-sec:first-of-type { padding-top: 0; margin-top: 0; border-top: 0; }

.fm-modal-body .fm-sec-h {
  font: 800 11px var(--font-ui);
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--faint);
  margin: 0 0 10px;
}

/* The long explanations collapse. Native <details>, so no script, keyboard-operable, and the text
   is in the DOM whether open or shut. */
.fm-modal-body .fm-details > summary {
  cursor: pointer;
  list-style-position: outside;
  margin-bottom: 6px;
}

.fm-modal-body .fm-details[open] > summary { margin-bottom: 8px; }

/* The explanatory paragraphs are the bulk of this dialog and were set at the same weight as the
   controls. Narrowed and lightened so they read as notes beside the fields rather than as more
   form. */
.fm-modal-body .fm-note {
  font-size: 12px;
  color: var(--muted);
  line-height: 1.6;
  /* NO max-width. It was 62ch, a typographic measure borrowed from body copy, and inside a 760px
     dialog that wrapped every explanation at roughly 440px with the rest of the row empty - the
     text looked broken rather than comfortable. These paragraphs sit beside form controls that
     already span the full width, so matching them reads as deliberate where a narrow column
     reads as a mistake. */
  /* A note explains the controls that follow it, so it needs a gap or the field labels butt
     straight onto the last line of the paragraph and read as part of it. This was the visible
     crowding under the redemption explanation. */
  margin: 0 0 12px;
}

/* Prose, warnings and anything that should run the full width of the dialog. */
/* Read-only context, laid out as a line rather than as fields. Three facts each given their own
   label/control row made the read-only part of a section taller than the part you can actually
   change - the wrong emphasis, and pure height. */
.fm-modal-body .fm-summary {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 22px;
  margin: 0 0 14px;
  font-size: 13px;
}

.fm-modal-body .fm-summary .k {
  color: var(--muted);
  font-size: 12px;
  margin-right: 6px;
}

/* One column on a narrow window: a 140px label column beside a wrapped control is worse than a
   label sitting directly above it. */
@media (max-width: 560px) {
  .fm-modal {
    width: calc(100vw - 16px);
    max-height: calc(100vh - 24px);
  }
  .fm-modal-body { padding: 14px 16px 18px; }
}
