/* ═══════════════════════════════════════════════════════════
   CŒUR ASTRAL - MODALE + SHEET (ALS-1054)
   ═══════════════════════════════════════════════════════════

   Look of the <dialog> modal engine (js/v2/modal.js). The engine wraps
   each legacy `.modal` root in a runtime <dialog class="ca-modal">, so the
   panel styled here is the unchanged `.modal` element.

   Scope: every selector starts with `.ui-v2 ` or `body.ui-v2`. Legacy
   parts (.modal, .modal-content,
   .modal-footer) are restyled only inside dialog.ca-modal.

   !important: the declarations marked with it only beat the !important
   rules of modal-system.css and of the Materialize .modal layer
   (materialize.min.css, materialize-override.css) on the panel, and in
   MODERATION MODALS the per-modal rules of materialize-override.css, each
   named in a comment. They go away with those stylesheets. */

/* ─────────────────────────────────────────────────────────────
   DIALOG - Full-viewport frame that centres the panel
   ───────────────────────────────────────────────────────────── */
.ui-v2 dialog.ca-modal {
  --ca-modal-w: 560px;
  position: fixed;
  inset: 0;
  width: auto;
  height: auto;
  max-width: none;
  max-height: none;
  margin: 0;
  padding: var(--sp-16);
  border: 0;
  background: transparent;
  color: inherit;
  overflow: hidden;
}

.ui-v2 dialog.ca-modal[data-size="sm"] {
  --ca-modal-w: 400px;
}

.ui-v2 dialog.ca-modal[data-size="lg"] {
  --ca-modal-w: 800px;
}

.ui-v2 dialog.ca-modal[open] {
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Scrim. The var() fallbacks cover browsers whose ::backdrop does not
   inherit custom properties yet. */
.ui-v2 dialog.ca-modal::backdrop {
  background: var(--scrim, rgb(6 9 18 / 0.72));
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}

@media (prefers-reduced-transparency: reduce) {
  .ui-v2 dialog.ca-modal::backdrop {
    background: var(--scrim-strong, rgb(6 9 18 / 0.92));
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .ui-v2 dialog.ca-modal::backdrop {
    background: var(--scrim-strong, rgb(6 9 18 / 0.92));
  }
}

/* ─────────────────────────────────────────────────────────────
   PANEL - The legacy `.modal` root, level-3 elevation
   Materialize hides and fixes it; modal-system.css sizes it, layers it
   and colours it with !important; materialize-override.css moves it to
   top: 5vh !important under 480px.
   ───────────────────────────────────────────────────────────── */
.ui-v2 dialog.ca-modal > .modal {
  display: block;
  position: relative !important;
  top: auto !important;
  right: auto;
  bottom: auto;
  left: auto;
  z-index: auto !important;
  width: min(var(--ca-modal-w), 92vw) !important;
  max-width: 92vw !important;
  max-height: 85dvh !important;
  margin: 0;
  padding: 0;
  overflow-y: auto;
  background: var(--surface-2) !important;
  border: 1px solid var(--rule-dialog);
  border-radius: var(--r-lg) !important;
  box-shadow: var(--shadow-dialog);
  opacity: 1;
  transform: none;
  color: var(--ivory-300);
  font: 400 15px/24px var(--font-ui);
  animation: ca-modal-in var(--dur-3) var(--ease-out);
}

@keyframes ca-modal-in {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
}

.ui-v2 dialog.ca-modal .modal-content {
  padding: var(--sp-24);
}

/* Keeps the first line of content clear of the 44px close button. */
.ui-v2 dialog.ca-modal:not([data-kind="blocking"]) .modal-content > :first-child {
  padding-inline-end: var(--sp-48);
}

.ui-v2 dialog.ca-modal .modal-footer {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-items: center;
  gap: var(--sp-12);
  height: auto;
  padding: var(--sp-16) var(--sp-24);
  border-top: 1px solid var(--rule-soft);
  background: transparent;
}

/* Optional v2 heading: eyebrow then Cormorant title (spec 28/34). The
   title restates family and weight with !important because
   materialize-override.css forces h1-h6 to Montserrat 600 !important. */
.ui-v2 dialog.ca-modal .ca-modal__eyebrow {
  margin: 0 0 var(--sp-8);
  font-family: var(--font-ui);
  font-size: var(--fs-eyebrow);
  line-height: var(--lh-eyebrow);
  font-weight: 600;
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--gold-400);
}

.ui-v2 dialog.ca-modal .ca-modal__title {
  margin: 0;
  font-family: var(--font-display) !important;
  font-size: 28px;
  line-height: 34px;
  font-weight: 500 !important;
  letter-spacing: var(--ls-display);
  color: var(--ivory-100);
}

/* Body copy under the title (blocked profile, profile nudge). Restates
   font and margin over style.css p rules. */
.ui-v2 dialog.ca-modal .ca-modal__text {
  margin: var(--sp-8) 0 0;
  font: 400 15px/24px var(--font-ui);
  color: var(--ivory-300);
}

/* ─────────────────────────────────────────────────────────────
   CLOSE BUTTON - Injected by modal.js, 44px touch target
   Materialize gives button:focus a teal background, so :focus restates
   the transparent one.
   ───────────────────────────────────────────────────────────── */
.ui-v2 dialog.ca-modal .ca-modal__close,
.ui-v2 dialog.ca-modal .ca-modal__close:focus {
  background-color: transparent;
}

.ui-v2 dialog.ca-modal .ca-modal__close {
  position: absolute;
  top: var(--sp-8);
  right: var(--sp-8);
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: var(--r-pill);
  color: var(--ivory-300);
  line-height: 0;
  cursor: pointer;
  transition:
    background-color var(--dur-1) var(--ease-out),
    color var(--dur-1) var(--ease-out);
}

.ui-v2 dialog.ca-modal .ca-modal__close:hover {
  background-color: var(--surface-3);
  color: var(--ivory-100);
}

/* Legacy header crosses: the injected close button replaces them. */
.ui-v2 dialog.ca-modal:not([data-kind="blocking"]) .modal-close-btn,
.ui-v2 dialog.ca-modal:not([data-kind="blocking"]) .love-calendar-modal-close {
  display: none;
}

/* ─────────────────────────────────────────────────────────────
   SHEET - modal.js adds .ca-modal--sheet below 600px when the root
   carries data-modal-mobile="sheet"
   ───────────────────────────────────────────────────────────── */
.ui-v2 dialog.ca-modal.ca-modal--sheet[open] {
  align-items: flex-end;
  padding: 0;
}

.ui-v2 dialog.ca-modal.ca-modal--sheet > .modal {
  width: 100% !important;
  max-width: 100% !important;
  max-height: calc(100dvh - 24px) !important;
  padding-bottom: env(safe-area-inset-bottom);
  border-radius: var(--r-xl) var(--r-xl) 0 0 !important;
  animation: ca-sheet-in var(--dur-3) var(--ease-out);
}

@keyframes ca-sheet-in {
  from {
    transform: translateY(100%);
  }
}

/* Grab handle. */
.ui-v2 dialog.ca-modal.ca-modal--sheet > .modal::before {
  content: "";
  display: block;
  width: 36px;
  height: 4px;
  margin: var(--sp-8) auto;
  border-radius: var(--r-pill);
  background: var(--ivory-700);
}

/* Stacked actions: the primary one comes last in the DOM, so it ends last. */
.ui-v2 dialog.ca-modal.ca-modal--sheet .modal-footer {
  flex-direction: column;
  align-items: stretch;
}

/* ─────────────────────────────────────────────────────────────
   MODERATION MODALS (ALS-1190) - Signaler, Bloquer, Débloquer
   appModeration/report_modal.html and block_modal.html keep the legacy
   markup and every id moderation.js and blocking.js read. Their legacy
   look is materialize-override.css:81-253 (report) and 255-451 (block,
   unblock), mostly !important: each !important below names what it
   beats. Under v2 the titles read « Signaler <first name> », « Bloquer
   <first name> » and « Débloquer <first name> » (no subtitle), the report
   category is a native select (browser-default, skipped by FormSelect) and
   both selects have a visible label.
   ───────────────────────────────────────────────────────────── */

/* Panel: one flex column that scrolls as a whole, so the footer sticks.
   Beats materialize-override.css:87-105 and 256-275 (display: none, flex
   only with .open, overflow: hidden, legacy fill, border and shadow). */
.ui-v2 dialog.ca-modal > :is(.report-user-modal, .block-user-modal, .unblock-user-modal) {
  display: flex !important;
  flex-direction: column !important;
  overflow-y: auto !important;
  background: var(--surface-2) !important;
  border: 1px solid var(--rule-dialog) !important;
  box-shadow: var(--shadow-dialog) !important;
}

/* The sheet's grab handle is a flex item here: it keeps its 4px. */
.ui-v2 dialog.ca-modal.ca-modal--sheet > :is(.report-user-modal, .block-user-modal)::before {
  flex-shrink: 0;
}

/* Content grows, never shrinks, and leaves the scroll to the panel.
   Beats materialize-override.css:81-84, 107-114 and 285-293 (padding,
   overflow: hidden, flex: 1 1 auto). */
.ui-v2 dialog.ca-modal > :is(.report-user-modal, .block-user-modal, .unblock-user-modal) > .modal-content {
  overflow: visible !important;
  flex: 1 0 auto !important;
  padding: var(--sp-24) !important;
}

/* Cormorant 28/34, as .ca-modal__title. Beats materialize-override.css:
   489-492 (h1-h6 Montserrat 600) and 323-328 (.block-modal-title size,
   line height and colour). */
.ui-v2 dialog.ca-modal > :is(.report-user-modal, .block-user-modal, .unblock-user-modal) :is(.report-modal-title, .block-modal-title) {
  font-family: var(--font-display) !important;
  font-size: 28px !important;
  line-height: 34px !important;
  font-weight: 500 !important;
  letter-spacing: var(--ls-display);
  color: var(--ivory-100) !important;
}

/* The first name moderation.js and blocking.js write keeps the title type
   over style.css:115-118 (p, span 1rem/1.5). */
.ui-v2 dialog.ca-modal > :is(.report-user-modal, .block-user-modal, .unblock-user-modal) :is(.report-modal-title, .block-modal-title) span {
  font: inherit;
  color: inherit;
}

/* Block description as a v2 notice: hairline on every side, no coloured
   left border. */
.ui-v2 dialog.ca-modal > :is(.report-user-modal, .block-user-modal, .unblock-user-modal) .block-modal-description {
  padding: var(--sp-16) var(--sp-20);
  background: var(--surface-1);
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
}

/* Beats materialize-override.css:348-353 (size, line height, colour). */
.ui-v2 dialog.ca-modal > :is(.report-user-modal, .block-user-modal, .unblock-user-modal) .block-modal-description p {
  font-size: 15px !important;
  line-height: 24px !important;
  color: var(--ivory-300) !important;
}

/* Fields: label above its control, never floating. No !important on
   display: blocking.js hides #block-reason-text-wrapper inline. The
   margin beats materialize-override.css:355-357 (.block-modal-field). */
.ui-v2 dialog.ca-modal > :is(.report-user-modal, .block-user-modal, .unblock-user-modal) :is(.report-modal-field, .block-modal-field) {
  display: flex;
  flex-direction: column;
  gap: var(--sp-8);
  margin: var(--sp-20) 0 0 !important;
}

/* Outranks the Materialize .input-field > label (absolute, translated);
   the colour beats materialize-override.css:156-158 and 359-362. */
.ui-v2 dialog.ca-modal > :is(.report-user-modal, .block-user-modal, .unblock-user-modal) :is(.report-modal-field, .block-modal-field) > label {
  position: static;
  order: -1;
  margin: 0;
  transform: none;
  font: 600 var(--fs-label)/var(--lh-label) var(--font-ui);
  color: var(--ivory-300) !important;
}

/* Controls in the .ca-field__control look; the native select keeps its own
   arrow. Outranks style.css:561-569 (select frame); the textarea frame
   beats materialize-override.css:172-181, 364-374 and 454-460. */
.ui-v2 dialog.ca-modal > :is(.report-user-modal, .block-user-modal, .unblock-user-modal) :is(select, textarea) {
  display: block;
  box-sizing: border-box;
  width: 100%;
  min-width: 0;
  margin: 0;
  border: 1px solid var(--ivory-700) !important;
  border-radius: var(--r-md) !important;
  background-color: var(--surface-2) !important;
  color: var(--ivory-100) !important;
  font: 400 16px/24px var(--font-ui);
  color-scheme: dark;
  transition:
    border-color var(--dur-1) var(--ease-out),
    box-shadow var(--dur-1) var(--ease-out);
}

.ui-v2 dialog.ca-modal > :is(.report-user-modal, .block-user-modal, .unblock-user-modal) select {
  height: 48px;
  padding: 0 var(--sp-16);
  cursor: pointer;
}

/* Beats materialize-override.css:172-181 and 364-374 (min-height and
   padding). */
.ui-v2 dialog.ca-modal > :is(.report-user-modal, .block-user-modal, .unblock-user-modal) textarea {
  height: auto;
  min-height: 132px !important;
  padding: var(--sp-12) var(--sp-16) !important;
  resize: vertical;
  overflow-y: auto;
}

.ui-v2 dialog.ca-modal > :is(.report-user-modal, .block-user-modal, .unblock-user-modal) textarea::placeholder {
  color: var(--ivory-500);
  opacity: 1;
}

/* Violet border and 3px ring, as .ca-field__control:focus. The border
   beats the frame above and materialize-override.css:172-181. */
.ui-v2 dialog.ca-modal > :is(.report-user-modal, .block-user-modal, .unblock-user-modal) :is(select, textarea):focus {
  outline: none;
  border-color: var(--violet-400) !important;
  box-shadow: 0 0 0 3px var(--field-ring);
}

/* Counters: 12px tabular figures, right-aligned. Beats
   materialize-override.css:152-154 and 376-381 (colour and size). */
.ui-v2 dialog.ca-modal > :is(.report-user-modal, .block-user-modal, .unblock-user-modal) :is(.report-modal-helper, .block-modal-helper) {
  display: block;
  min-height: 0;
  margin: 0;
  color: var(--ivory-500) !important;
  font-family: var(--font-ui);
  font-size: 12px !important;
  line-height: 16px;
  font-variant-numeric: tabular-nums;
  text-align: right;
}

.ui-v2 dialog.ca-modal > :is(.report-user-modal, .block-user-modal, .unblock-user-modal) :is(.report-modal-helper, .block-modal-helper) span {
  font: inherit;
  color: inherit;
}

/* Feedback as a v2 notice in both states. Beats materialize-override.css:
   202-206 and 478-481 (.card-panel fill and border, colour) and the
   materialize.min.css .green.lighten-4 / .red.lighten-4 fills that
   moderation.js adds. */
.ui-v2 dialog.ca-modal > :is(.report-user-modal, .block-user-modal, .unblock-user-modal) .report-modal-feedback {
  margin: var(--sp-20) 0 0;
  padding: var(--sp-12) var(--sp-16);
  border: 1px solid var(--rule) !important;
  border-radius: var(--r-md);
  background-color: var(--surface-1) !important;
  box-shadow: none;
  color: var(--ivory-100) !important;
}

.ui-v2 dialog.ca-modal > :is(.report-user-modal, .block-user-modal, .unblock-user-modal) .report-modal-feedback span {
  font: 400 14px/22px var(--font-ui);
}

/* Beats materialize.min.css .green-text.text-darken-2 (!important). */
.ui-v2 dialog.ca-modal > :is(.report-user-modal, .block-user-modal, .unblock-user-modal) .report-modal-feedback .green-text {
  color: var(--success) !important;
}

/* Beats materialize.min.css .red-text.text-darken-2 (!important). */
.ui-v2 dialog.ca-modal > :is(.report-user-modal, .block-user-modal, .unblock-user-modal) .report-modal-feedback .red-text {
  color: var(--danger-text) !important;
}

/* Footer sticks to the bottom of the scrolling panel. Beats
   materialize-override.css:208-226 and 383-410 (legacy fill, border,
   radius, 64px minimum and padding). */
.ui-v2 dialog.ca-modal > :is(.report-user-modal, .block-user-modal, .unblock-user-modal) > .modal-footer {
  position: sticky;
  bottom: 0;
  height: auto !important;
  min-height: 0 !important;
  padding: var(--sp-16) var(--sp-24) !important;
  border-top: 1px solid var(--rule-soft) !important;
  border-radius: 0 !important;
  background: var(--surface-2) !important;
}

.ui-v2 dialog.ca-modal > :is(.report-user-modal, .block-user-modal, .unblock-user-modal) :is(.report-modal-actions, .block-modal-actions) {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--sp-12);
  width: 100%;
}

/* Sheet: stacked, full-width actions; the primary one comes last in the
   DOM, so it ends last. */
.ui-v2 dialog.ca-modal.ca-modal--sheet > :is(.report-user-modal, .block-user-modal, .unblock-user-modal) :is(.report-modal-actions, .block-modal-actions) {
  flex-direction: column;
  align-items: stretch;
}

/* v2 pill buttons, 48px minimum: never upper-cased, the label wraps
   instead of being clipped. The radius beats materialize-override.css:
   431-435 and 442-446. */
.ui-v2 dialog.ca-modal > :is(.report-user-modal, .block-user-modal, .unblock-user-modal) :is(.report-modal-actions, .block-modal-actions) > button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-8);
  box-sizing: border-box;
  min-height: 48px;
  height: auto;
  margin: 0;
  padding: var(--sp-12) 28px;
  border: 1px solid transparent;
  border-radius: var(--r-pill) !important;
  font: 600 var(--fs-button)/var(--lh-button) var(--font-ui);
  text-align: center;
  text-transform: none;
  letter-spacing: normal;
  white-space: normal;
  box-shadow: none;
  cursor: pointer;
}

.ui-v2 dialog.ca-modal > :is(.report-user-modal, .block-user-modal, .unblock-user-modal) :is(.report-modal-actions, .block-modal-actions) > button:focus-visible {
  outline: 2px solid var(--violet-300);
  outline-offset: 3px;
}

/* Cancel, secondary look; :focus restates it over Materialize teal.
   Beats materialize-override.css:74-77 (.btn-flat fill on focus) and
   245-248 / 419-423 (cancel colour). */
.ui-v2 dialog.ca-modal > :is(.report-user-modal, .block-user-modal, .unblock-user-modal) :is(.report-modal-actions, .block-modal-actions) > .modal-close,
.ui-v2 dialog.ca-modal > :is(.report-user-modal, .block-user-modal, .unblock-user-modal) :is(.report-modal-actions, .block-modal-actions) > .modal-close:focus {
  border-color: var(--line-strong);
  background-color: transparent !important;
  color: var(--ivory-100) !important;
}

/* Beats materialize-override.css:74-77, 250-253 and 425-429 (hover fills). */
.ui-v2 dialog.ca-modal > :is(.report-user-modal, .block-user-modal, .unblock-user-modal) :is(.report-modal-actions, .block-modal-actions) > .modal-close:hover {
  border-color: var(--ivory-300);
  background-color: var(--wash-hover) !important;
}

/* Primary, brand gradient and its edge (as .ca-btn--primary); ids, so
   hover and focus need no restating.
   Beats materialize-override.css:59-72 (.btn fills), 442-451 (green
   unblock fills), the Materialize .purple / .green colour classes and
   materialize.min.css .btn.disabled (grey label while moderation.js
   sends). */
.ui-v2 dialog.ca-modal > :is(.report-user-modal, .unblock-user-modal) :is(#submit-report-btn, #confirm-unblock-btn) {
  background-color: transparent !important;
  background-image: var(--gradient-brand);
  box-shadow: var(--gradient-brand-edge);
  color: var(--ivory-100) !important;
}

/* Danger fill. Beats materialize-override.css:59-72 and 431-440 (.btn
   and red block fills, hover included). */
.ui-v2 dialog.ca-modal > .block-user-modal #confirm-block-btn {
  background-color: var(--danger-fill) !important;
  background-image: none;
  color: var(--on-accent);
}

.ui-v2 dialog.ca-modal > :is(.report-user-modal, .block-user-modal, .unblock-user-modal) :is(#submit-report-btn, #confirm-block-btn, #confirm-unblock-btn):hover {
  filter: brightness(1.1);
}

/* ─────────────────────────────────────────────────────────────
   PAGE LOCK & FORCED COLOURS
   ───────────────────────────────────────────────────────────── */
body.ui-v2.ca-modal-open {
  overflow: hidden;
}

@media (forced-colors: active) {
  .ui-v2 dialog.ca-modal > .modal {
    border: 1px solid CanvasText;
  }

  /* Forced colours drop the focus ring (box-shadow) and the border colour,
     so the moderation fields get a system outline, as .ca-field__control
     in components.css. */
  .ui-v2 dialog.ca-modal > :is(.report-user-modal, .block-user-modal, .unblock-user-modal) :is(select, textarea):focus {
    outline: 2px solid Highlight;
    outline-offset: 2px;
  }
}

/* ─────────────────────────────────────────────────────────────
   PROFILE NUDGE - appAccounts/partials/profile_nudge_modal.html
   The completion bar is harmony.css's dimension row; here it only
   drops the row rule and keeps its distance from the text.
   ───────────────────────────────────────────────────────────── */
.ui-v2 dialog.ca-modal .ca-nudge__progress {
  margin-top: var(--sp-20);
  border-bottom: 0;
}
