/**
 * Portfolio Column Scroll widget styles.
 *
 * Layout only — the parallax/pin motion is applied as inline transforms by
 * portfolio-column-scroll.js (GSAP). Item inner markup (.portfolio-item .wrap
 * .a-img .content) matches the standard Portfolio widget so theme hover
 * overlays (.portfolio_hover_type_*) apply unchanged.
 */

.portfolio-column-scroll-block {
  /* --pcs-gap-x = horizontal spacing (between columns / between images in a row)
     --pcs-gap-y = vertical spacing (between images in a column / between rows) */
  --pcs-gap-x: 24px;
  --pcs-gap-y: 24px;
  --pcs-mcols: 2;
  --pcs-height: 100vh;
  /* Edge vignette overlay defaults.
     --pcs-vig-clear = radius of the clear (fully-visible) centre
     --pcs-vig-fade  = length of the fade from the clear centre to full colour */
  --pcs-vig-color: rgba(13, 13, 13, 1);
  --pcs-vig-shape: ellipse;
  --pcs-vig-clear: 20%;
  --pcs-vig-fade: 80%;
  position: relative;
}

/* Light theme — the heading overlaid on this block (gallery-column-scroll.php
   / portfolio-column-scroll.php) already renders its non-accent words in the
   theme's adaptive text colour (dark in light mode, see .pt-sword / .h in
   style.css), so it was already expecting a light backdrop here rather than
   the fixed dark vignette. Flip the vignette itself to match; this also keeps
   the 1px seam ring (which reuses --pcs-vig-color) matching the page.
   !important because each widget instance can set its own --pcs-vig-color via
   the Elementor "Vignette Color" control, output per-post with higher
   selector specificity than this shared rule can reach. */
body.site-light .portfolio-column-scroll-block {
  --pcs-vig-color: rgba(255, 255, 255, 1) !important;
}

/* ---------------------------------------------------------------------------
 * Edge vignette — a single static radial-gradient overlay fading the edges /
 * corners into --pcs-vig-color (oval by default, matching the block aspect).
 * pointer-events:none keeps clicks / popups working, and it never repaints
 * while columns drift — free at runtime (no JS, no images).
 *
 * The block also gets the vignette colour as its background so the gaps between
 * images don't reveal the page background as lighter stripes under the fade.
 * ------------------------------------------------------------------------- */
.portfolio-column-scroll-block.pcs-vignette {
  background-color: var(--pcs-vig-color);
  /* Paint a 1px ring of the vignette colour just outside the block. Under the
     theme's transform-based smooth scroll the clipped top/bottom edge can
     reveal a 1px sliver of the (lighter) page background as a seam; this ring
     covers it. It moves with the block, so the seam is always covered. */
  box-shadow: 0 0 0 1px var(--pcs-vig-color);
}

.portfolio-column-scroll-block.pcs-vignette::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;
  background: radial-gradient(
    var(--pcs-vig-shape) farthest-corner at center,
    transparent var(--pcs-vig-clear),
    var(--pcs-vig-color) calc(var(--pcs-vig-clear) + var(--pcs-vig-fade))
  );
}

/* When the scroll effect is live (added by JS), the widget becomes a fixed
   visible band: columns are taller than the band and slide *within* it, so the
   motion never overflows the widget or overlaps adjacent page sections. The
   static / editor / mobile fallbacks keep their natural height instead. */
.portfolio-column-scroll-block.pcs-active {
  overflow: hidden;
}

/* Vertical drift: fixed visible band; columns are taller and slide within it. */
.portfolio-column-scroll-block.pcs-active.pcs-mode-vertical {
  height: var(--pcs-height);
}

.portfolio-column-scroll-block.pcs-active.pcs-mode-vertical .pcs-track {
  height: 100%;
}

/* ---------------------------------------------------------------------------
 * Vertical mode — CSS grid of columns, each column a vertical stack.
 * ------------------------------------------------------------------------- */
.pcs-track.pcs-dir-vertical {
  display: grid;
  /* Fallback only — PHP sets the real grid-template-columns inline with a
     literal column count that matches the number of rendered .pcs-col elements,
     so the grid can never disagree with the DOM. (repeat() cannot take a CSS
     custom property as its count, so a var-based grid is not possible here.) */
  grid-template-columns: repeat(3, minmax(0, 1fr));
  column-gap: var(--pcs-gap-x);
  row-gap: var(--pcs-gap-y);
  align-items: start;
}

.pcs-dir-vertical .pcs-col {
  display: flex;
  flex-direction: column;
  gap: var(--pcs-gap-y);
  will-change: transform;
}

/* ---------------------------------------------------------------------------
 * Horizontal drift — rows stacked vertically, each row a strip wider than the
 * block. As the page scrolls, alternate rows drift left/right in opposite
 * directions (JS, on X), clipped by the block's overflow:hidden. No pinning.
 * ------------------------------------------------------------------------- */
.pcs-track.pcs-dir-horizontal {
  display: flex;
  flex-direction: column;
  gap: var(--pcs-gap-y);
}

.pcs-dir-horizontal .pcs-row {
  display: flex;
  flex-direction: row;
  gap: var(--pcs-gap-x);
  width: max-content;
  will-change: transform;
}

.pcs-dir-horizontal .pcs-item {
  width: 26vw;
  flex: 0 0 auto;
}

/* ---------------------------------------------------------------------------
 * Items — fixed aspect-ratio box keeps layout stable before images load so
 * ScrollTrigger measurements stay correct.
 * ------------------------------------------------------------------------- */
/* Reset the theme's .portfolio-item margin (it adds a stray vertical gap on top
   of the flex/grid gap). Block-scoped selector wins over the theme's rule. */
.portfolio-column-scroll-block .pcs-item {
  position: relative;
  margin: 0;
}

.pcs-item .wrap {
  position: relative;
}

.pcs-item .a-img {
  position: relative;
  width: 100%;
  padding-bottom: 130%;
  overflow: hidden;
  /* Promote each thumbnail to its own GPU layer and snap its raster to the
     pixel grid. Under the theme's transform-based smooth scroll this stops the
     rounded image edges from shimmering as thin light seams while the lanes
     drift; it has no runtime cost once composited. */
  transform: translateZ(0);
  backface-visibility: hidden;
}

.pcs-item .a-img > div {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
}

/* Keep the drifting lanes on their own clean raster layer too. */
.pcs-dir-vertical .pcs-col,
.pcs-dir-horizontal .pcs-row {
  backface-visibility: hidden;
}

.pcs-track.pcs-gap-off {
  --pcs-gap-x: 0px;
  --pcs-gap-y: 0px;
}

/* ---------------------------------------------------------------------------
 * Mobile — below the breakpoint the JS effect is reverted (matchMedia) and the
 * layout reflows. `display: contents` lets items flow into a plain grid while
 * keeping the column wrappers in the DOM.
 * ------------------------------------------------------------------------- */
@media (max-width: 767px) {
  .pcs-mobile-simple .pcs-track,
  .pcs-mobile-one .pcs-track {
    display: grid !important;
    width: auto !important;
    column-gap: var(--pcs-gap-x);
    row-gap: var(--pcs-gap-y);
    transform: none !important;
  }

  .pcs-mobile-simple .pcs-track {
    grid-template-columns: repeat(var(--pcs-mcols), minmax(0, 1fr));
  }

  .pcs-mobile-one .pcs-track {
    grid-template-columns: 1fr;
  }

  .pcs-mobile-simple .pcs-col,
  .pcs-mobile-one .pcs-col {
    display: contents;
  }

  /* Clear any inline transform left on columns when the effect is reverted. */
  .pcs-mobile-simple .pcs-col,
  .pcs-mobile-one .pcs-col {
    transform: none !important;
  }

  /* ---------------------------------------------------------------------
   * Horizontal mode — rows deliberately DON'T use `display: contents` here.
   * Nesting a `display: contents` row inside this grid, inside an Elementor
   * flex container up the ancestor chain, collapses the outer
   * `.elementor-widget`'s auto height to 0 (reproduced independent of
   * content size — a real Chromium flex/grid + `display: contents`
   * interaction bug, not a sizing threshold issue). The row stays a real
   * box instead: the track becomes a plain block (rows stack vertically via
   * margin), and each row wraps its own items into an N-column strip. The
   * result reads the same as a tiled grid — lane grouping only matters for
   * the desktop drift effect, not for the mobile reading order.
   * ------------------------------------------------------------------- */
  .pcs-mobile-simple .pcs-dir-horizontal,
  .pcs-mobile-one .pcs-dir-horizontal {
    display: block !important;
  }

  .pcs-mobile-simple .pcs-dir-horizontal .pcs-row,
  .pcs-mobile-one .pcs-dir-horizontal .pcs-row {
    display: flex !important;
    flex-wrap: wrap;
    width: auto !important;
    column-gap: var(--pcs-gap-x);
    row-gap: var(--pcs-gap-y);
    transform: none !important;
  }

  .pcs-mobile-simple .pcs-dir-horizontal .pcs-row + .pcs-row,
  .pcs-mobile-one .pcs-dir-horizontal .pcs-row + .pcs-row {
    margin-top: var(--pcs-gap-y);
  }

  .pcs-mobile-simple .pcs-dir-horizontal .pcs-item {
    width: calc((100% - (var(--pcs-mcols) - 1) * var(--pcs-gap-x)) / var(--pcs-mcols)) !important;
    flex: unset !important;
  }

  .pcs-mobile-one .pcs-dir-horizontal .pcs-item {
    width: 100% !important;
    flex: unset !important;
  }
}
