/* ============================================================
   NEUVEX SOFTWARE SHOWCASE — 3D Coverflow Styles

   No boxed "stage" panel — the component has no background,
   padding-box or border of its own, so it can be dropped into any
   section on the site and it'll just take on whatever that
   section's background already is. The cards are the only visual
   weight here, sized up so the centre image reads as the hero.

   Reads colour/font tokens straight from neuvex-style.css
   (--text, --text-muted, --text-dim, --accent-hover, --border,
   --surface, --white) — no new brand colours introduced.

   The visual positioning itself (translateX, rotateY, scale per
   card) is calculated in showcase.js and applied as inline
   transforms — CSS here just defines the perspective, the card's
   own look, and the transition so those inline changes animate.

   Load this AFTER neuvex-style.css.
============================================================= */

.showcase {
  /* Spacing/size tokens for the coverflow geometry — the only
     things JS needs to read back via getComputedStyle. These are
     deliberately large: the brief here is "images do all the
     work", so the centre card should read as a genuine hero
     visual, not a thumbnail. */
  --cf-card-w:   clamp(340px, 46vw, 700px);
  --cf-ratio:    16 / 9;
  --cf-step-x:   clamp(150px, 21vw, 340px);
  --cf-step-z:   clamp(120px, 13vw, 230px);
  --cf-rotate:   46deg;

  padding: 0 0 clamp(48px, 6vw, 80px);
}

/* ---------------------------------------------------------------- */
/* Stage — just the perspective viewport, no background/panel of     */
/* its own. Bottom padding is still needed so the reflection has     */
/* room to fade out without overlapping the caption below it.        */
/* ---------------------------------------------------------------- */

.showcase-stage-wrap {
  /* side padding keeps the arrows clear of the outermost cards;
     minimal bottom padding — the caption sits close to the card
     and overlaps the reflection intentionally, rather than the
     reflection reserving its own whitespace */
  padding: 0 clamp(56px, 8vw, 96px) clamp(16px, 2vw, 0px);
}

.showcase-stage {
  position: relative;
  height: clamp(280px, 27vw, 460px);
  perspective: 1800px;
  isolation: isolate;
  outline: none;
  /* prevents the browser's native touch scroll from fighting our
     own pointer-based swipe handling */
  touch-action: pan-y;
}

.showcase-stage:focus-visible {
  outline: 2px solid var(--accent-hover);
  outline-offset: 8px;
  border-radius: 12px;
}

.showcase-track {
  position: absolute;
  inset: 0;
  list-style: none;
  margin: 0;
  padding: 0;
  perspective: 1800px;
  transform-style: flat;
}

/* ---------------------------------------------------------------- */
/* Slide — positioned by JS via inline transform/opacity/z-index.    */
/* CSS only supplies the transition so those changes animate, and    */
/* the base centering.                                               */
/* ---------------------------------------------------------------- */

.cf-slide {
  position: absolute;
  top: 50%;
  left: 50%;
  width: var(--cf-card-w);
  transform-style: flat;
  backface-visibility: hidden;
  will-change: transform, opacity;
  transition: transform 0.65s cubic-bezier(0.22, 1, 0.36, 1),
              opacity 0.5s ease;
  cursor: pointer;
}

.cf-slide.is-active {
  cursor: default;
}

/* ---------------------------------------------------------------- */
/* Card — the image IS the card. No tray, no visible background —    */
/* just the screenshot, edge-to-edge, with a soft rounded corner     */
/* and enough shadow to lift it off whatever the section's own       */
/* background happens to be.                                         */
/* ---------------------------------------------------------------- */

.cf-card {
  display: block;
  position: relative;
}

.cf-card-face {
  display: block;
  aspect-ratio: var(--cf-ratio);
  border-radius: 14px;
  overflow: hidden;
  border: 1px solid var(--border);
  box-shadow: 0 24px 48px -20px rgba(17, 17, 17, 0.35);
  transition: box-shadow 0.4s ease;
}

.is-active .cf-card-face {
  box-shadow: 0 36px 64px -18px rgba(17, 17, 17, 0.42);
}

.cf-card-face img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* ---------------------------------------------------------------- */
/* Reflection — a mirrored, fading copy beneath the card sitting     */
/* almost flush against it. Uses pure alpha fade (no colour), so it  */
/* reads correctly regardless of what background this component is  */
/* dropped onto — a light page, a dark section, anything.            */
/* ---------------------------------------------------------------- */

.cf-reflection {
  display: block;
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  margin-top: 2px;
  aspect-ratio: var(--cf-ratio);
  overflow: hidden;
  border-radius: 14px;
  transform: scaleY(-1);
  opacity: 0.22;
  -webkit-mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.7), transparent 46%);
          mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.7), transparent 46%);
  pointer-events: none;
}

.cf-reflection img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* ---------------------------------------------------------------- */
/* Arrows — plain chrome buttons in your standard site style,        */
/* pinned to the outer edges of the stage. Neutral enough to sit on  */
/* any section background rather than assuming a dark floor.         */
/* ---------------------------------------------------------------- */

.showcase-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  box-shadow: inset 0 1px 0 var(--white), 0 8px 20px -8px rgba(17, 17, 17, 0.25);
  cursor: pointer;
  z-index: 60;
  transition: background 0.25s cubic-bezier(0.22, 1, 0.36, 1),
              transform 0.2s cubic-bezier(0.22, 1, 0.36, 1);
}

.showcase-arrow[data-showcase-prev] { left: 0; }
.showcase-arrow[data-showcase-next] { right: 0; }

.showcase-arrow:hover {
  background: var(--accent);
}

.showcase-arrow:active {
  transform: translateY(-50%) scale(0.94);
}

.showcase-arrow:focus-visible {
  outline: 2px solid var(--accent-hover);
  outline-offset: 2px;
}

/* ---------------------------------------------------------------- */
/* Caption — single block below the stage. Updated by JS to match    */
/* whichever card is centred, crossfades between slides.             */
/* ---------------------------------------------------------------- */

.showcase-caption {
  text-align: center;
  max-width: 480px;
  margin: 8px auto 0;
}

.showcase-caption-pill {
  display: inline-block;
  font-family: 'Sora', 'Inter', sans-serif;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin-bottom: 8px;
  opacity: 1;
  transition: opacity 0.25s ease;
}

.showcase-caption h3 {
  font-family: 'Sora', 'Inter', sans-serif;
  font-size: clamp(22px, 2.8vw, 30px);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--text);
  margin: 0;
  opacity: 1;
  transition: opacity 0.25s ease;
}

.showcase-caption.is-fading .showcase-caption-pill,
.showcase-caption.is-fading h3 {
  opacity: 0;
}

/* ---------------------------------------------------------------- */
/* Dots — centred beneath the caption                                 */
/*                                                                    */
/* Accessibility fix: the visible dot stays an 8px circle (22px      */
/* pill when active) for the same look as before, but the actual     */
/* <button> hit area is enlarged to 28x28px via ::before so it meets */
/* the WCAG 2.5.8 minimum target size (24x24 CSS px). The visible    */
/* dot is drawn as a ::before pseudo-element centred inside the      */
/* button rather than being the button's own background/size.        */
/* ---------------------------------------------------------------- */

.showcase-dots {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 20px;
}

.showcase-dots button {
  width: 28px;
  height: 28px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: transparent;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}

.showcase-dots button::before {
  content: "";
  display: block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #747474;
  transition: background 0.2s ease, width 0.2s ease;
}

.showcase-dots button[aria-selected="true"]::before {
  background: #6bc2f0;
  width: 22px;
  border-radius: 100px;
}

.showcase-dots button:focus-visible {
  outline: 2px solid var(--accent-hover);
  outline-offset: 3px;
}

/* ---------------------------------------------------------------- */
/* Responsive                                                         */
/* ---------------------------------------------------------------- */

@media (max-width: 640px) {
  .showcase-stage-wrap {
    padding: 0 44px clamp(50px, 14vw, 90px);
  }

  .showcase-arrow {
    width: 40px;
    height: 40px;
  }
}

/* prefers-reduced-motion is already handled globally in
   neuvex-style.css (it disables all transitions/animations
   sitewide) — the coverflow's own transitions inherit that. */
