/* public/css/project-modal.css — project detail modal (design: docs/superpowers/specs/2026-09-03-project-modal-design.md §3.1)
   Loaded together with /project/project-css/project-detail.css, which owns the
   panel's content layout -- the modal renders the same .box.yu-detail skeleton
   as the SSR detail page (YuProjectMarkup.renderDetailSkeleton). Rules here are
   the panel chrome plus resets for globals the card pages load and the detail
   page does not. */

.pm-root {
  position: fixed;
  inset: 0;
  z-index: 1000;
}
.pm-root[hidden] {
  display: none;
}
.pm-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.72);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  opacity: 0;
}
.pm-panel {
  /* Single source of truth for the panel's width -- the .solgen override below
     consumes it too. The 140px budget (70px each side) is what keeps the panel's
     right edge clear of the 51px AI circle, which sits 16..67px in from the
     viewport's right edge: at any width the panel ends at least 3px short of it,
     so .pm-bar in the panel's bottom-right corner can never meet the circle.
     Unchanged at 1440x900: still 1200px wide at left 120. */
  --pm-panel-w: min(1200px, calc(100vw - 140px));
  position: fixed;
  top: 6vh;
  left: max(70px, calc(50% - 600px));
  width: var(--pm-panel-w);
  height: 88vh;
  display: flex;
  flex-direction: column;
  background: #0b0b0b;
  color: #fff7ec;
  border-radius: 16px;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.6);
  overflow: hidden;
  outline: none;
  will-change: transform;
}
/* Desktop: the controls float at the panel's bottom-right, mirroring the detail
   page's own .nav, and stay out of the scroll flow so .pm-scroll wraps the whole
   .box.yu-detail. */
.pm-bar {
  position: absolute;
  right: 24px;
  bottom: 20px;
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 10px;
}
.pm-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border: none;
  border-radius: 18px;
  background: #1b1a1a;
  opacity: 0.8;
  cursor: pointer;
  transition: opacity 0.2s ease, transform 0.2s ease;
}
.pm-btn:hover,
.pm-btn:focus-visible {
  opacity: 1;
  transform: scale(1.06);
}
.pm-btn img {
  width: 16px;
  height: 16px;
}
.pm-nav {
  display: flex;
  gap: 10px;
}
.pm-scroll {
  flex: 1 1 auto;
  height: 100%;
  overflow-x: hidden;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}
.pm-ghost {
  position: fixed;
  z-index: 1001;
  object-fit: cover;
  border-radius: 12px;
  pointer-events: none;
}
body.pm-lock {
  overflow: hidden !important;
  transition: none;
}
/* main.css owns a global `.show` (absolute, 50vw x 60vh, translate(-50%,-50%)) for
   the home hero. The detail hero image and showImage()'s lightbox both carry that
   class, so pin them back down wherever the modal is mounted. */
body.pm-open .overlay,
body.pm-open .overlay.show {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  width: auto;
  height: auto;
  padding: 0;
  transform: none;
  z-index: 1300;
}

/* project-detail.css now owns the panel's layout, exactly as on the detail page.
   The only rules below are resets for globals that the card pages load and the
   detail page does not -- without them main.css would relayout the hero. */

/* The page sizes the box at 85vw (1224px at 1440) and centres it with
   project-info.css's `body { display:flex; justify-content:center }` -- neither
   of which works inside a 1200px panel. Filling the panel keeps the box within
   2% of the page's own dimensions (left 360 vs 368, right 780 vs 795, hero 936
   vs 954) and leaves the 85vw .solgen centred to within 12px. */
.pm-panel .yu-detail.box {
  width: 100%;
}

/* main.css:246 defines a global `.show` (display:flex; position:absolute;
   top/left:50%; translate(-50%,-50%); z-index:5; width:50vw; height:60vh;
   padding:10pt; transition:all .9s) for the home hero. The detail hero image
   carries the same class, so reset every property main.css sets that
   project-detail.css does not, and let project-detail.css keep width /
   object-fit / mix-blend-mode. */
.pm-panel .yu-detail.box .showbox .show {
  /* block == the page's computed value (a flex item of .showbox blockifies) */
  display: block;
  top: auto;
  left: auto;
  transform: none;
  transition: none;
  z-index: auto;
  height: auto;
  padding: 0;
}
/* `position` only leaks above 900px: project-detail.css leaves it unset there,
   while its own <=900px block sets `position: absolute` on the hero (a 100vw
   layer behind the text) and must keep winning. */
@media (min-width: 901px) {
  .pm-panel .yu-detail.box .showbox .show {
    position: static;
  }

  /* Desktop inset: the content never touches the panel edge. 96px at the bottom
     is the runway for the floating .pm-bar. Padding lives on .pm-scroll only --
     one layer -- so .yu-detail.box keeps filling the padded width and the
     columns stay at the page's own 30% / 65% split. */
  .pm-scroll {
    box-sizing: border-box;
    padding: 40px 48px 96px;
  }

  /* project-detail.css sizes the first screen in vh (box/.z-1/.showbox all 80vh,
     with 10vh margins). Inside the panel the "viewport" is the padded content
     area -- 88vh minus the 40+96 padding -- so re-base exactly those rules on it;
     without this the title column and the hero run under .pm-bar. */
  .pm-panel {
    --pm-screen: calc(88vh - 136px);
  }
  .pm-panel .yu-detail.box,
  .pm-panel .yu-detail.box .z-1,
  .pm-panel .yu-detail.box .showbox {
    height: var(--pm-screen);
  }
  .pm-panel .yu-detail.box .z-1 {
    /* 10vh below an 80vh column would push the title past the content area */
    margin-bottom: 0;
  }
  .pm-panel .yu-detail.box .showbox {
    /* centre the hero in the content area instead of the page's 10vh offset,
       and keep the gap to the next right-column block proportional (60/80). */
    justify-content: center;
    margin-top: 0;
    margin-bottom: calc(var(--pm-screen) * 0.75);
  }
  .pm-panel .yu-detail.box .showbox .show {
    /* last resort on short viewports: the hero shrinks rather than overflowing */
    max-height: 100%;
    object-fit: contain;
  }
  /* project-detail.css gives the slogan 85vw so it spans the page beneath both
     columns. It starts at the content's left edge, so inside the panel it has
     to be the content width (panel minus the 48px side padding) or it runs past
     the panel and gets clipped. */
  .pm-panel .yu-detail.box .left .solgen {
    width: calc(var(--pm-panel-w) - 96px);
    max-width: none;
  }
}

@media (max-width: 900px) {
  /* Single scroll layer: the panel itself is the only scroll container, and the
     body is frozen with position:fixed (iOS Safari ignores overflow:hidden).
     project-modal.js writes body.style.top = -scrollY and restores it on close. */
  body.pm-lock {
    position: fixed;
    left: 0;
    width: 100%;
  }
  .pm-panel {
    position: fixed;
    inset: 0;
    top: 0;
    left: 0;
    display: block;
    width: 100%;
    height: 100%;
    border-radius: 0;
    overflow-x: hidden;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
    /* No will-change here: a promoted ancestor would become the containing
       block for the position:fixed .pm-bar and drag it along when scrolling. */
    will-change: auto;
  }
  /* Not a scroller here (.pm-panel is), just the padding box: side inset plus
     the runway under the floating bottom-left .pm-bar. */
  .pm-scroll {
    box-sizing: border-box;
    overflow: visible;
    -webkit-overflow-scrolling: auto;
    overscroll-behavior: auto;
    padding: 12px 16px calc(env(safe-area-inset-bottom, 0px) + 88px);
  }
  /* Button bar floats bottom-left so it never meets the AI pill (bottom-right).
     Three 44px buttons + two 10px gaps = 152px, leaving > 150px on a 375px screen. */
  .pm-bar {
    position: fixed;
    left: 12px;
    /* clear the desktop `right: 24px`, or the bar stretches across the AI
       circle's corner even though its buttons stop at 164px */
    right: auto;
    bottom: calc(env(safe-area-inset-bottom, 0px) + 14px);
    z-index: 1001;
    justify-content: flex-start;
    gap: 10px;
    width: auto;
    height: auto;
    padding: 0;
    background: none;
  }
  .pm-btn {
    width: 44px;
    height: 44px;
    border-radius: 22px;
    opacity: 1;
    background: rgba(27, 26, 26, 0.82);
    -webkit-backdrop-filter: blur(18px);
    backdrop-filter: blur(18px);
  }
  .pm-btn img {
    width: 18px;
    height: 18px;
  }
  .pm-nav {
    display: contents;
  }
  /* project-detail.css already has its own <=900px block for .yu-detail.box;
     .pm-scroll's padding above now owns the room under the last block, so the
     box only has to stop stretching to a fixed 90% of the panel. */
  .pm-panel .yu-detail.box {
    height: auto;
  }
  /* While the modal is open the AI pill collapses to its 51px circle and hugs
     the bottom-right corner, opposite .pm-bar. Scoped with body.pm-open so
     yu-ai-widget.css stays untouched. width:auto is shrink-to-fit — it measures
     51px next to the compact pill, and still fits the panel if the user opens it. */
  body.pm-open #yu-ai-widget-root {
    left: auto;
    right: 14px;
    bottom: calc(env(safe-area-inset-bottom, 0px) + 14px);
    width: auto;
    max-width: calc(100vw - 28px);
    padding: 0;
  }
  body.pm-open #yu-ai-widget-root .yu-ai-widget:not(.is-open) {
    width: 51px;
    max-width: 51px;
    margin-left: 0;
    margin-right: 0;
  }
  body.pm-open #yu-ai-widget-root .yu-ai-widget:not(.is-open) .yu-ai-pill {
    width: 51px;
    max-width: 51px;
    height: 51px;
    border-radius: 50%;
    padding: 0;
    gap: 0;
    justify-content: center;
  }
  body.pm-open #yu-ai-widget-root .yu-ai-widget:not(.is-open) .yu-ai-pill #yuAiGreetingText {
    display: none;
  }
}

/* Desktop: while the modal is open the AI pill collapses to its 51px circle and
   sits in the viewport's bottom-right corner. The panel is min(1200px, 92vw)
   centred, so at 1440 it ends 120px from the right edge and the circle (16..67px
   in) never reaches it -- .pm-bar owns the panel's own bottom-right. */
@media (min-width: 901px) {
  body.pm-open #yu-ai-widget-root {
    left: auto;
    right: 16px;
    bottom: 16px;
  }
  body.pm-open #yu-ai-widget-root .yu-ai-widget:not(.is-open) {
    width: 51px;
    max-width: 51px;
  }
  body.pm-open #yu-ai-widget-root .yu-ai-widget:not(.is-open) .yu-ai-pill {
    width: 51px;
    max-width: 51px;
    height: 51px;
    border-radius: 50%;
    padding: 0;
    gap: 0;
    justify-content: center;
  }
  body.pm-open #yu-ai-widget-root .yu-ai-widget:not(.is-open) .yu-ai-pill #yuAiGreetingText {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .pm-btn {
    transition: none;
  }
}
