/* ═══════════════════════════════════════════════════════════════════
   Reusable modal dialog (templates/core/_modal.html) - native <dialog>
   styled to match Blacktop+ (docs/color-palette.md). A <dialog> shown via
   showModal() renders in the browser's top layer, above everything else
   on the page unconditionally, so unlike every other floating element in
   this app (page-loader.css z-index:9999, nav-progress.css z-index:100,
   back-to-top.css z-index:35, .hl-league-nav z-index:40 in base.css) this
   component needs no z-index of its own and can never be accidentally
   covered by one of them.
   ═══════════════════════════════════════════════════════════════════ */

.hl-modal-trigger {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

.hl-modal-trigger-icon {
  display: inline-flex;
}
.hl-modal-trigger-icon svg {
  width: 18px;
  height: 18px;
}

/* Scoped box-sizing reset - this project has no global `* { box-sizing:
   border-box }` (only opted in per-component, e.g. .hl-page), so a child
   like .hl-modal-cta below combining width:100% with its own padding/
   border would otherwise overflow the panel by that padding+border
   amount under the default content-box model. */
dialog.hl-modal-dialog,
dialog.hl-modal-dialog *,
dialog.hl-modal-dialog *::before,
dialog.hl-modal-dialog *::after {
  box-sizing: border-box;
}

dialog.hl-modal-dialog {
  /* Centering is normally free from the UA stylesheet's `dialog:modal`
     rule (position:fixed; inset-block:0; margin:auto), but stated
     explicitly here so it can't be silently lost to a future rule this
     file adds that happens to set one of these without the others. */
  position: fixed;
  inset: 0;
  margin: auto;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 16px;
  background: var(--bg-raised);
  color: var(--text);
  width: min(92vw, 480px);
  max-height: min(85dvh, 640px);
  box-shadow: 0 24px 64px -16px rgba(0, 0, 0, 0.6), 0 4px 16px -4px rgba(0, 0, 0, 0.4);
  overscroll-behavior: contain;
}

dialog.hl-modal-dialog--sm { width: min(92vw, 360px); }
dialog.hl-modal-dialog--lg { width: min(94vw, 720px); }

dialog.hl-modal-dialog::backdrop {
  background: rgba(6, 5, 4, 0.72);
  backdrop-filter: blur(3px);
}

.hl-modal-panel {
  display: flex;
  flex-direction: column;
  max-height: inherit;
}

.hl-modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-4) var(--space-3);
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}

.hl-modal-title {
  margin: 0;
}

.hl-modal-close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: none;
  background: transparent;
  color: var(--text-secondary);
  cursor: pointer;
  flex-shrink: 0;
  transition: background 0.15s ease, color 0.15s ease, transform 0.15s ease;
}
.hl-modal-close:hover { background: var(--bg-card); color: var(--text); transform: rotate(90deg); }
.hl-modal-close:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.hl-modal-close svg { width: 18px; height: 18px; }

.hl-modal-body {
  padding: var(--space-4);
  overflow-y: auto;
  overscroll-behavior: contain;
  color: var(--text-secondary);
}
.hl-modal-body p:last-child { margin-bottom: 0; }

.hl-modal-footer {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4) var(--space-4);
  border-top: 1px solid var(--border);
  flex-shrink: 0;
}

/* Value-prop bullet list + full-width CTA - generic enough for any modal
   body (teaser/upsell dialogs, not just landing.html's "Start a league")
   to reuse rather than hand-rolling inline styles per page. */
.hl-modal-feature-list {
  list-style: none;
  margin: 0 0 var(--space-5);
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.hl-modal-feature-item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  color: var(--text);
}
.hl-modal-feature-item svg { flex-shrink: 0; color: var(--primary); }
/* Same positional accent-color rotation as landing.css's
   .landing-feature:nth-child(n) .landing-feature-icon. */
.hl-modal-feature-item:nth-child(2) svg { color: var(--teal); }
.hl-modal-feature-item:nth-child(3) svg { color: var(--gold); }
.hl-modal-feature-item:nth-child(4) svg { color: var(--violet); }
.hl-modal-feature-item:nth-child(5) svg { color: var(--lime); }

.hl-modal-cta.hl-btn {
  width: 100%;
  /* landing.css's `.landing-page a { color: inherit }` (0,1,1) otherwise
     out-specificities .hl-btn-primary's `color: var(--on-primary)` (0,1,0)
     for this one link-styled-as-button, since the modal is nested inside
     .landing-page - the CTA rendered in the muted body-text color instead
     of matching every other primary button on the page. Two classes here
     (0,2,0) beats that regardless of its element selector. */
  color: var(--on-primary);
}

/* ─── "Start a league" teaser content ───────────────────────────────
   Scoped under hl-start-league-* (not a generic hl-modal-* name, unlike
   .hl-modal-feature-list above) - specific to this one teaser's own
   coming-soon framing, not shared modal chrome another dialog body would
   reuse. See templates/core/_start_league_modal_body.html. */
.hl-start-league-teaser {
  display: flex;
  justify-content: center;
  padding: var(--space-5) 0;
}
.hl-start-league-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px 5px 10px;
  border-radius: 999px;
  background: rgba(242, 106, 16, 0.12);
  border: 1px solid rgba(242, 106, 16, 0.32);
  color: var(--primary-hover);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.4px;
  text-transform: uppercase;
}
/* Larger standalone variant - now the only content in the teaser besides
   the CTA, so it carries more visual weight than it did as a small kicker
   above a paragraph. */
.hl-start-league-badge--lg {
  padding: 9px 18px 9px 14px;
  font-size: 14px;
  letter-spacing: 0.6px;
}
.hl-start-league-badge svg { width: 14px; height: 14px; flex-shrink: 0; }
.hl-start-league-badge--lg svg { width: 17px; height: 17px; }
@media (prefers-reduced-motion: no-preference) {
  .hl-start-league-badge svg { animation: hl-start-league-bell 2.6s ease-in-out infinite; transform-origin: 50% 15%; }
}
@keyframes hl-start-league-bell {
  0%, 65%, 100% { transform: rotate(0deg); }
  69% { transform: rotate(-12deg); }
  73% { transform: rotate(10deg); }
  77% { transform: rotate(-8deg); }
  81% { transform: rotate(4deg); }
  85% { transform: rotate(0deg); }
}

/* Subtle glow, scoped to this one dialog instance by id (not the shared
   .hl-modal-dialog base rule) so it doesn't bleed into any other modal
   that reuses core/_modal.html later - same radial-orange treatment as
   the hero watermark and the mobile nav drawer elsewhere on this page. */
#start-league-modal .hl-modal-panel {
  background: radial-gradient(260px 180px at 100% 0%, rgba(242, 106, 16, 0.10), transparent 70%);
}

/* Background scroll lock while any modal is open - :has() is already the
   established technique for this in the app (back-to-top.css uses it to
   detect .hl-league-shell), so this stays consistent with the project's
   supported-browser floor instead of adding a scroll-lock JS helper. */
body:has(dialog.hl-modal-dialog[open]) {
  overflow: hidden;
}

/* ─── Animation ──────────────────────────────────────────────────────
   Two layers on open: the dialog frame scales/fades in (snappy
   ease-out-expo feel), then .hl-modal-panel's content does its own
   short fade-and-rise a beat later so the content doesn't feel like a
   flat sticker glued to the frame. Exit uses @starting-style +
   allow-discrete (web.dev's "Entry and exit animations using CSS
   transitions" recipe) so display:none <-> block can still transition
   smoothly instead of the browser default of just snapping; unsupported
   browsers fall back to an instant show/hide, no branching needed.
   Skipped entirely under reduced motion rather than just shortened - a
   modal popping in/scaling is a bigger, more disorienting motion than
   e.g. back-to-top's small nudge. */
@media (prefers-reduced-motion: no-preference) {
  dialog.hl-modal-dialog {
    opacity: 0;
    transform: translateY(14px) scale(0.96);
    transition: opacity 0.22s cubic-bezier(0.16, 1, 0.3, 1),
                transform 0.22s cubic-bezier(0.16, 1, 0.3, 1),
                overlay 0.22s ease allow-discrete,
                display 0.22s ease allow-discrete;
  }
  dialog.hl-modal-dialog[open] {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
  @starting-style {
    dialog.hl-modal-dialog[open] {
      opacity: 0;
      transform: translateY(14px) scale(0.96);
    }
  }

  dialog.hl-modal-dialog::backdrop {
    opacity: 0;
    transition: opacity 0.22s ease, overlay 0.22s ease allow-discrete, display 0.22s ease allow-discrete;
  }
  dialog.hl-modal-dialog[open]::backdrop {
    opacity: 1;
  }
  @starting-style {
    dialog.hl-modal-dialog[open]::backdrop {
      opacity: 0;
    }
  }

  @keyframes hl-modal-content-in {
    from { opacity: 0; transform: translateY(8px); }
    to { opacity: 1; transform: translateY(0); }
  }
  dialog.hl-modal-dialog[open] .hl-modal-panel {
    animation: hl-modal-content-in 0.28s cubic-bezier(0.16, 1, 0.3, 1) 0.05s both;
  }
}

/* ─── Mobile: still a centered floating card, just narrower margins and
   a taller allowance - NOT an edge-to-edge full-screen sheet. Forcing
   height:100%/inset:0 here previously pinned short content to the top
   of an otherwise-empty full-height sheet, which read as "stuck at the
   top" rather than a modal. dvh (not vh) so mobile browser chrome
   showing/hiding doesn't jump the sizing. */
@media (max-width: 560px) {
  dialog.hl-modal-dialog,
  dialog.hl-modal-dialog--sm,
  dialog.hl-modal-dialog--lg {
    width: min(94vw, 440px);
    max-height: min(88dvh, 640px);
    border-radius: 14px;
  }
}
