/* dialog.css — the app's confirm / prompt dialog (S1-15).
 *
 * Replaces `window.confirm` and `window.prompt`, which htmx (`hx-confirm`,
 * `hx-prompt`) and two plain forms were calling directly. The native ones are a
 * grey OS strip: no title, no product voice, an "OK" that never names the action,
 * and on a phone they render as a system sheet that looks like a browser warning
 * rather than a step of the app. Everything asked here is irreversible-ish
 * (закрыть заказ, аннулировать накладную, удалить строку), so the question
 * deserves to be read.
 *
 * Hand-written CSS, not Tailwind, and on purpose: the Tailwind build scans
 * *.html and *.go only (knowledge/06 gotcha 6, tailwind.config.js), so class
 * names that only ever appear in dialog.js would have no styles. Everything here
 * is driven from JS (tone, hidden field), so it must live outside that build —
 * the same call `.file-drop-over` makes inline in layout.html and `.toast` /
 * `.hl` make in feedback.css (ADL0075), just too big to keep inline.
 *
 * The element is a real <dialog> + showModal(): the focus trap, Esc, the inert
 * background and the top-layer stacking are the platform's, not ours. Nothing to
 * maintain, and it cannot be covered by the nav's z-index.
 */

/* ---- shell -------------------------------------------------------------- */

#app-dialog {
  /* preflight already zeroes the UA border and padding (dialog{padding:0}) */
  width: min(30rem, calc(100vw - 2rem));
  /* max-width, explicitly: the UA sheet caps a dialog at calc(100% - 6px - 2em),
     which on a 390 px phone wins over the width above and leaves the card 18 px
     narrower than intended (measured). Own the number instead of subtracting the
     UA's. */
  max-width: none;
  /* A long question must scroll INSIDE the card, never push the buttons off
     screen (conv. 17, applied to a dialog). */
  max-height: calc(100vh - 1.5rem);
  max-height: calc(100dvh - 1.5rem);
  overflow: auto;
  margin: auto;
  border-radius: 1rem;
  background: #fff;
  color: #0f172a; /* slate-900 */
  box-shadow: 0 25px 50px -12px rgb(15 23 42 / 0.45);
}

#app-dialog::backdrop {
  background: rgb(15 23 42 / 0.55);
  backdrop-filter: blur(2px);
}

/* On a phone the dialog docks to the bottom: this UI is designed at 390 px and
   the two buttons should sit where the thumb already is, not in the middle of
   the screen. */
@media (max-width: 480px) {
  #app-dialog {
    width: calc(100vw - 1.25rem);
    margin: auto auto 0.625rem;
  }
  /* …except when it asks for text (dialog.js sets data-prompting). The layout
     viewport does not shrink for the on-screen keyboard on iOS Safari or on
     default-config Chrome Android, so a bottom-docked card with a focused input
     renders underneath it. */
  #app-dialog[data-prompting] { margin: auto; }
}

/* ---- motion ------------------------------------------------------------- */

@keyframes dlg-in {
  from { opacity: 0; transform: translateY(12px) scale(0.97); }
  to   { opacity: 1; transform: none; }
}
@keyframes dlg-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes dlg-out {
  from { opacity: 1; transform: none; }
  to   { opacity: 0; transform: translateY(8px) scale(0.98); }
}
@keyframes dlg-unfade {
  from { opacity: 1; }
  to   { opacity: 0; }
}

#app-dialog[open]           { animation: dlg-in 0.18s cubic-bezier(0.2, 0.8, 0.3, 1); }
#app-dialog[open]::backdrop { animation: dlg-fade 0.18s ease; }

/* dialog.js sets data-closing, waits for the animation, then calls close() — so
   "Отмена" does not just blink out of existence. These are their own KEYFRAME
   NAMES on purpose: `dlg-in … reverse` looks equivalent and is not. An animation
   is identified by its name, so changing only the duration/direction updates the
   running one instead of restarting it — it is already past its new active
   duration by the time the user answers, so nothing moves and `animationend`
   never fires (found in review; the close was landing on fadeOut's 250 ms
   timeout, leaving the page inert and fully visible until then). */
#app-dialog[data-closing]           { animation: dlg-out 0.12s ease forwards; }
#app-dialog[data-closing]::backdrop { animation: dlg-unfade 0.12s ease forwards; }

@media (prefers-reduced-motion: reduce) {
  #app-dialog[open], #app-dialog[open]::backdrop,
  #app-dialog[data-closing], #app-dialog[data-closing]::backdrop {
    animation-duration: 0.01s;
  }
}

/* L5: the hint is a live region, so it is EMPTY until dialog.js fills it from the
   field's own data-hint. Empty = gone. */
.dlg-hint:empty { display: none; }

/* ---- body --------------------------------------------------------------- */

.dlg-form { padding: 1.25rem 1.25rem 0; }

.dlg-head {
  display: flex;
  gap: 0.875rem;
  align-items: flex-start;
}

/* The glyph is CSS, not a JS-written string: the tone is the only thing dialog.js
   sets, and no user-facing text should be born in a .js file (knowledge/06 §5). */
.dlg-icon {
  flex: 0 0 auto;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 9999px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.125rem;
  font-weight: 700;
  line-height: 1;
  background: #f1f5f9; /* slate-100 */
  color: #475569;      /* slate-600 */
}
.dlg-icon::before { content: "?"; }

.dlg-copy { min-width: 0; } /* conv. 23: this column prints a название the user typed */

.dlg-title {
  margin: 0.125rem 0 0;
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.35;
  overflow-wrap: anywhere;
}

.dlg-text {
  margin: 0.375rem 0 0;
  font-size: 0.875rem;
  line-height: 1.5;
  color: #475569; /* slate-600 */
  overflow-wrap: anywhere;
}
.dlg-text:empty { display: none; }

/* ---- prompt field ------------------------------------------------------- */

.dlg-field {
  display: block;
  margin-top: 1rem;
}
.dlg-field[hidden] { display: none; }

.dlg-label {
  display: block;
  font-size: 0.75rem;
  font-weight: 600;
  color: #64748b; /* slate-500 */
  overflow-wrap: anywhere;
}

.dlg-input {
  margin-top: 0.375rem;
  width: 100%;
  border: 1px solid #cbd5e1; /* slate-300 */
  border-radius: 0.5rem;
  padding: 0.5rem 0.75rem;
  font: inherit;
  font-size: 1rem; /* ≥16px: anything smaller makes iOS Safari zoom on focus */
  color: inherit;
  background: #fff;
}
.dlg-input:focus {
  outline: none;
  border-color: #0f172a;
  box-shadow: 0 0 0 3px rgb(15 23 42 / 0.08);
}

/* Written only after an empty submit — an error before the first attempt is
   noise, and an empty live region is what makes the message ANNOUNCE when it
   finally arrives. */
.dlg-hint {
  margin: 0.375rem 0 0;
  font-size: 0.75rem;
  color: #e11d48; /* rose-600 */
}
.dlg-field[data-invalid] .dlg-input { border-color: #fda4af; }

/* ---- actions ------------------------------------------------------------ */

/* Sticky, and spanning the card's full width via the negative margin: the scroll
   container is #app-dialog itself, so without this a long question scrolls the
   buttons out of reach and the answer to "must scroll INSIDE the card" would only
   be half true. */
.dlg-actions {
  position: sticky;
  bottom: 0;
  z-index: 1;
  margin: 0 -1.25rem;
  padding: 1.25rem;
  background: #fff;
  display: flex;
  gap: 0.5rem;
  justify-content: flex-end;
}

.dlg-btn {
  border-radius: 0.5rem;
  padding: 0.5rem 0.875rem;
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 1.25rem;
  cursor: pointer;
  overflow-wrap: anywhere;
}
.dlg-btn:focus-visible {
  outline: 2px solid #0f172a;
  outline-offset: 2px;
}

.dlg-cancel {
  background: #fff;
  color: #475569;
  border: 1px solid #cbd5e1;
}
.dlg-cancel:hover { background: #f1f5f9; }

.dlg-ok {
  background: #0f172a; /* slate-900, the page's primary */
  color: #fff;
  border: 1px solid #0f172a;
}
.dlg-ok:hover { background: #334155; }

/* Tones. The dialog wears the colour of the button that opened it, so "Удалить"
   does not open the same neutral box as "Выписать". */
#app-dialog[data-tone="danger"] .dlg-icon   { background: #ffe4e6; color: #e11d48; }
#app-dialog[data-tone="danger"] .dlg-icon::before { content: "!"; }
#app-dialog[data-tone="danger"] .dlg-ok     { background: #e11d48; border-color: #e11d48; }
#app-dialog[data-tone="danger"] .dlg-ok:hover { background: #be123c; }

#app-dialog[data-tone="success"] .dlg-icon  { background: #d1fae5; color: #047857; }
#app-dialog[data-tone="success"] .dlg-icon::before { content: "✓"; }
#app-dialog[data-tone="success"] .dlg-ok    { background: #059669; border-color: #059669; }
#app-dialog[data-tone="success"] .dlg-ok:hover { background: #047857; }

/* Phones: full-width stacked buttons, primary on top — one thumb, no aiming. */
@media (max-width: 480px) {
  .dlg-actions { flex-direction: column-reverse; }
  .dlg-btn { width: 100%; padding: 0.625rem 0.875rem; }
}
