/* Shared styles for the detail-popup engine (popups.js): modal card, marquee
   gallery, project mini-chips. Linked by projects.html AND about.html - edit
   HERE, not per-page. */

.gallery{scrollbar-width:none;-ms-overflow-style:none;} /* marquee strip: no visible scrollbar */
.gallery::-webkit-scrollbar{display:none;}
.gtile .gcap{opacity:0;transition:opacity .25s;}
.gtile:hover .gcap{opacity:1;}
.mchip{cursor:pointer;display:inline-flex;align-items:center;gap:9px;background:#fff;border:1.5px solid #ddccae;border-radius:30px;padding:8px 15px;transition:border-color .2s,transform .2s;}

/* ------------------------------------------- detail modal: viewport-bound --
   The popup has to fit the viewport at any size: the backdrop is a fixed
   full-viewport sheet that never scrolls, the card is capped to the viewport
   and becomes a flex column, the banner (with the close X) is pinned, and only
   the body below it scrolls (as a fallback - content is sized to fit). */
.pm-back{align-items:center !important;padding:24px !important;
  overflow:hidden !important;overscroll-behavior:contain;}
.pm-card{display:flex !important;flex-direction:column !important;
  max-height:calc(100vh - 36px) !important;}
.pm-head{flex:0 0 auto !important;}
/* The banner is written as a fixed 135px box: the date pill is absolutely
   placed in its top-left corner, and the org line + title are bottom-aligned
   underneath it. When both of those wrap the pair outgrows 135px and, being
   bottom-aligned, overflows UPWARD into the pill - 18 of the 40 cards collided
   at 390px, and Pier & Vehicle Detection and LiDAR Performance Benchmarking
   still did at 768px. So: let the banner grow rather than overflow, and hold
   the pill's own row clear so the two can never share a line. 48px is measured,
   not guessed: it is the slack a single-line header already had, so a card that
   fitted before either keeps its 135px banner or gains 2px, and only the ones
   that were overlapping actually grow. */
.pm-head{height:auto !important;min-height:135px !important;padding-top:48px !important;}
.pm-body{flex:1 1 auto;min-height:0;overflow-y:auto !important;
  overscroll-behavior:contain;}
/* Cards are written to fit the viewport; a few stray pixels of rounding should
   not turn the body into a scroll region on desktop. Reclaiming the block
   padding closes that gap without touching the copy - 2026-08-27 pass took the
   bottom from 12px to 4px and the top from 18px to 12px, which is what cleared
   the last single-digit overflows on handi, r-mavi, smart-mailbox and the Omron
   experience card. */
@media (min-width:561px){ .pm-body{padding-top:12px !important;padding-bottom:4px !important;} }

@media (max-width:560px){
  .pm-back{padding:10px !important;}
  .pm-logo{display:none !important;} /* company logo chip collides with long names on phones */
  [data-close]{position:fixed !important;top:16px !important;right:16px !important;
    width:44px !important;height:44px !important;font-size:22px !important;
    background:rgba(30,39,72,.82) !important;z-index:130;}
  /* gallery tiles stack instead of scrolling sideways; the duplicate marquee
     sets ([data-g2]/[data-g3]) are dead weight when stacked.
     EXCEPT the dual-row experience gallery (.gallery-dual): it aggregates every
     linked project's media - 40 tiles for Omron - and stacking that vertically
     would bury the highlights under ~7000px of photos. It stays a pair of
     swipeable strips on phones, just shorter. */
  .gallery:not(.gallery-dual){flex-direction:column !important;overflow-x:hidden !important;}
  .gallery:not(.gallery-dual) [data-g1]{flex-direction:column !important;width:100% !important;}
  .gallery:not(.gallery-dual) [data-g2],.gallery:not(.gallery-dual) [data-g3]{display:none !important;}
  .gallery:not(.gallery-dual) .gtile{width:100% !important;height:172px !important;aspect-ratio:auto !important;}
  .gallery-dual .gtile{height:132px !important;}
  /* captions are always-on for touch, and a dual-row tile is a third the
     width of a stacked one - one elided line so the label sits on the photo
     instead of burying it. (-webkit-line-clamp is no good here: overflow
     clips at the PADDING box, so a clamped caption still leaks a sliver of
     the next line into the bottom padding.) */
  .gallery-dual .gcap{font-size:9px !important;padding:14px 9px 7px !important;
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  /* `> picture > img` too: media.js wraps gallery images in a <picture> for
     the AVIF/WebP choice (the wrapper is display:contents, so it adds no box). */
  .gallery:not(.gallery-dual) .gtile > img,
  .gallery:not(.gallery-dual) .gtile > picture > img{width:100% !important;height:100% !important;object-fit:cover !important;}
  .gtile .gcap{opacity:1 !important;} /* no hover on touch - captions always on */
  .pm-card[style*="border-radius:16px"]{
    max-height:calc(100vh - 24px) !important;
    max-height:calc(100dvh - 24px) !important;
    overflow:hidden !important;}
}

/* ---------------------------------------- short-viewport (laptop) fitting --
   2026-08-27. The no-inner-scroll rule held at 1440x900 but 27 of 40 cards
   still scrolled at 1280x800 - a 13" laptop. That is 100px of viewport, not a
   copy problem, so it is fixed structurally rather than by gutting the cards:
   below 860px tall the banner loses its generous top padding and the gallery
   strip drops from 20vh to 14vh. Together that is ~89px, which is what the
   worst card (carabiner-fracture, 78px over) needed. The desktop look at
   >=861px tall is untouched. */
@media (min-width:561px) and (max-height:860px){
  .pm-head{min-height:96px !important;padding-top:26px !important;}
  .gtile{height:clamp(88px,11vh,150px) !important;}
  /* the experience cards stack TWO gallery rows, so every vh here counts twice
     - Omron was the worst of them at 47px over. */
  .gallery-dual .gtile{height:clamp(70px,9vh,130px) !important;}
}
