/* ================================================================
   MOD: PORTFOLIO — Rolodex carousel
   Requires: core.css tokens. Requires: portfolio-carousel.js.
   HTML needed: <section class="portfolio" id="portfolio">
     <div class="container"><header class="portfolio-header reveal">...</header></div>
     <div class="carousel-viewport" id="carouselViewport">
       <div class="carousel-track" id="carouselTrack" role="list">
         <a class="carousel-card" role="listitem" href="...">
           <div class="carousel-card-media" style="background: ...;">
             <img src="..." alt="..." loading="lazy" />
           </div>
           <div class="carousel-caption">
             <span class="carousel-caption-label">...</span>
             <span class="carousel-caption-title">...</span>
           </div>
         </a>
         <!-- Add carousel-card--portrait or carousel-card--square as needed -->
       </div>
       <div class="carousel-nav">
         <button class="carousel-btn" id="carouselPrev">&#8592;</button>
         <div class="carousel-dots" id="carouselDots"></div>
         <button class="carousel-btn" id="carouselNext">&#8594;</button>
       </div>
     </div>
   </section>
================================================================ */

.portfolio { background: var(--color-bg); padding: var(--section-pad); scroll-margin-top: 32px; }
.portfolio-header { margin-bottom: 48px; }

.carousel-viewport { position: relative; width: 100%; overflow: hidden; padding: 48px 0 40px; }

.carousel-track { display: flex; align-items: flex-start; gap: clamp(12px, 3vw, 24px); transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1); will-change: transform; }

/* .carousel-card is the OUTER item: controls width (via flex-basis)
   and the shared focus/blur effect (scale + saturation) for the
   whole item — image box AND caption fade/scale together. */
.carousel-card {
  flex: 0 0 clamp(240px, 34vw, 480px);
  display: flex;
  flex-direction: column;
  gap: 14px;
  cursor: pointer;
  transform: scale(0.88);
  filter: saturate(0.7) brightness(0.94);
  transition:
    transform 0.5s cubic-bezier(0.4, 0, 0.2, 1),
    filter 0.5s cubic-bezier(0.4, 0, 0.2, 1);
  text-decoration: none;
}
.carousel-card.is-center {
  transform: scale(1);
  filter: saturate(1) brightness(1);
  z-index: 2;
}

/* object-fit: contain shows the whole screenshot with no cropping;
   letterboxing is filled by each card's own inline gradient
   background so empty space reads as a brand-colored frame. */
.carousel-card-media {
  position: relative;
  width: 100%;
  aspect-ratio: 480 / 340;
  border-radius: var(--radius-md);
  overflow: hidden;
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-card);
  transition: box-shadow 0.5s cubic-bezier(0.4, 0, 0.2, 1), border-color 0.5s ease;
}
.carousel-card.is-center .carousel-card-media {
  box-shadow: var(--shadow-hover), 0 0 0 1px rgba(var(--accent2-rgb),0.25);
  border-color: rgba(var(--accent2-rgb),0.35);
}

.carousel-card-media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center;
  z-index: 0;
  display: block;
}

/* Optional aspect-ratio variants — add the modifier class per card
   to match the screenshot's real proportions and minimize letterboxing. */
.carousel-card--portrait { flex: 0 0 clamp(140px, 17vw, 230px); }
.carousel-card--portrait .carousel-card-media { aspect-ratio: 9 / 19.5; }

.carousel-card--square { flex: 0 0 clamp(220px, 30vw, 420px); }
.carousel-card--square .carousel-card-media { aspect-ratio: 2035 / 1916; }

/* Caption lives below the image box as its own panel, always
   visible, with a soft teal glow (via --shadow-glow) when centered. */
.carousel-caption {
  width: 100%;
  padding: 14px 18px;
  border-radius: var(--radius-sm);
  background: var(--color-card);
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-sm);
  transition: box-shadow 0.4s ease, border-color 0.4s ease;
}
.carousel-card.is-center .carousel-caption {
  box-shadow: var(--shadow-glow), var(--shadow-sm);
  border-color: rgba(var(--accent2-rgb),0.4);
}
.carousel-caption-label { font-family: var(--font-display); font-size: 0.68rem; letter-spacing: 0.2em; text-transform: uppercase; color: var(--accent1-dark); margin-bottom: 4px; display: block; }
.carousel-caption-title { font-family: var(--font-display); font-size: 1.05rem; font-weight: 700; color: var(--text-color); }

/* Optional third caption line — used by The Vault (mods/vault.css) to
   show a price under the item name. Safe to leave unused elsewhere. */
.carousel-caption-price { font-family: var(--font-display); font-size: 0.92rem; font-weight: 600; color: var(--accent1-dark); margin-top: 6px; display: block; }
[data-theme="dark"] .carousel-caption-price { color: var(--accent1); }

.carousel-nav { display: flex; align-items: center; justify-content: center; gap: 20px; margin-top: 28px; }
.carousel-btn {
  width: 44px; height: 44px; border-radius: 50%;
  background: var(--color-card); border: 1px solid var(--color-border);
  color: var(--text-color); font-size: 1.1rem; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: background var(--transition), border-color var(--transition), transform var(--transition), box-shadow var(--transition), color var(--transition);
  box-shadow: var(--shadow-sm);
}
.carousel-btn:hover { background: var(--accent1); border-color: var(--accent1); color: var(--paper); transform: scale(1.08); box-shadow: var(--shadow-hover); }
.carousel-btn:focus-visible { outline: 2px solid var(--accent1); outline-offset: 3px; }

.carousel-dots { display: flex; gap: 8px; align-items: center; }
.carousel-dot { width: 7px; height: 7px; border-radius: 50%; background: rgba(var(--fg-rgb), 0.18); border: none; cursor: pointer; padding: 0; transition: background var(--transition), transform var(--transition); }
.carousel-dot.is-active { background: var(--accent1); transform: scale(1.35); }