/* ============================================================================
   Modal / Default — COMPONENTS.md §4.1, parts §4.4

   Shell: fill, radius, and a Header / Content / Footer stack. §4.1 records the
   shell padding and gap as `RAW 0` because "spacing lives on the
   sub-components" — reproduced: nothing here pads the shell itself.

   Two page findings are implemented rather than reproduced:
     · §4 F1 — "No elevation and no scrim on any modal shell", though
       `Elevation/Modal` and `surface/scrim` "exist and are documented for this
       exact case". Both are applied here.
     · §4 F2 — the Figma shell fills with `surface/raised`, but
       `surface/overlay` was created "specifically so overlay elevation could
       diverge from cards later" and nothing consumes it. A modal is that case,
       so this uses `surface/overlay`. Today the two resolve identically, so
       this is free; when they diverge, the modal follows the right one.

   `Inner Sroll` (§4 F5, a typo in the DS variant value) is the type used here:
   fixed height, the content band scrolls. The typo is not carried into code.

   TODO(tokens): every bare px length in this file is a SIZE or a BREAKPOINT.
   DESIGN.md §12.4 records both as not built.
   ========================================================================== */

.modal-layer {
  position: fixed;
  inset: 0;
  z-index: 200; /* TODO(tokens): z-index scale not built — DESIGN.md §12.4 */
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-lg);
  /* §4 F1: the scrim the Figma component does not show. */
  background: var(--color-surface-scrim);
}

.modal-layer[hidden] {
  display: none;
}

.modal {
  display: flex;
  flex-direction: column;
  /* §4.1 Width axis — Small 480 / Medium 640 / Large 800 / X Large 1024. */
  inline-size: 100%;
  max-inline-size: 640px; /* Medium */
  max-block-size: 100%;
  background: var(--color-surface-overlay);
  border-radius: var(--shape-radius-modal);
  /* §4 F1: Elevation/Modal, which the component omits. */
  box-shadow: var(--elevation-modal);
  /* DESIGN.md §8: shadow does not read in Dark, so a hairline carries the
     edge there instead. One declaration, not a forked Light/Dark rule. */
  border: var(--border-width-thin) solid
    light-dark(transparent, var(--color-border-default));
  overflow: hidden;
}

.modal--sm {
  max-inline-size: 480px;
}

/* --- Modal / Default / Header — §4.4 ------------------------------------- */
.modal__header {
  display: flex;
  align-items: flex-start;
  gap: var(--space-sm);
  flex: none;
  padding: var(--space-lg);
  padding-block-end: var(--space-sm);
}

.modal__title {
  margin: 0;
  flex: 1 1 auto;
  /* §4.4: title is `content/headline` / `Heading/SM Regular`. */
  color: var(--color-content-headline);
  font-family: var(--font-family-display);
  font-size: var(--font-heading-sm-size);
  line-height: var(--font-heading-sm-line-height);
  font-weight: var(--font-weight-bold);
  letter-spacing: var(--font-letter-spacing-default);
}

.modal__close {
  display: inline-flex;
  flex: none;
  align-items: center;
  justify-content: center;
  /* TODO(tokens): size not built. 32px is the DS's Default control height. */
  inline-size: 32px;
  block-size: 32px;
  border-radius: var(--shape-radius-button);
  color: var(--color-content-secondary);
  transition: background-color 100ms ease, color 100ms ease; /* TODO(tokens): motion */
}
.modal__close:hover {
  /* Button / Text hover, §1.1. */
  background: var(--color-soft-neutral-default);
  color: var(--color-on-soft-neutral);
}
.modal__close:active {
  background: var(--color-soft-neutral-pressed);
}

/* --- Modal / Default / Content — §4.4 -----------------------------------
   §4.4 marks the Figma Content set as "placeholder styling, not a shipping
   surface" (`soft/brand/default` fill on a brand tint). It is a swap slot, so
   only its padding is real; the fill is deliberately not reproduced. */
.modal__content {
  flex: 1 1 auto;
  min-block-size: 0;
  overflow-y: auto;
  scrollbar-width: thin;
  padding-inline: var(--space-lg);
  padding-block: var(--space-sm);
}

/* --- Modal / Default / Footer — §4.4 ------------------------------------- */
.modal__footer {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  flex: none;
  padding: var(--space-lg);
  padding-block-start: var(--space-sm);
}

/* §4.4 footer order: extra action, cancel, primary. The extra action pushes
   the pair to the trailing edge. */
.modal__footer-spacer {
  flex: 1 1 auto;
}

@media (max-width: 599px) {
  .modal-layer {
    padding: var(--space-none);
    align-items: stretch;
  }
  .modal {
    max-inline-size: none;
    border-radius: var(--radius-none);
    border: 0;
  }
}

/* `display: flex` on the class outranks the UA's `[hidden] { display: none }`
   — the trap button.css documents for `.btn[hidden]`. The close control is
   hidden on a step that must be resolved with a control rather than abandoned:
   checkout.css's Stripe hand-off, where the page cannot yet say whether the
   card was charged. Without this the X stays clickable and offers a way out
   that the Escape key and the scrim are both correctly refusing. */
.modal__close[hidden] {
  display: none;
}
