/**
 * product.coverflow-showcase — 3D coverflow product showcase.
 *
 * Every value comes from a --cfs-* custom property written onto the instance
 * element by the renderer, so two instances on one page never share state and a
 * setting change is a token change rather than a new rule. Colour tokens fall
 * back to the skin contract when the instance leaves them empty, which is what
 * lets a Pack restyle this section without touching the section.
 *
 * The card frame is the point: the media box OWNS the aspect ratio and the image
 * is told to fill it, so photographs of any proportion — and a card with no
 * photograph at all — produce the same rectangle.
 */

/*
 * This showcase wants a clean black top edge, not the shared street-magazine
 * torn-paper seam other slot transitions use (layouts/street-magazine.css,
 * `.dm-slot + .dm-slot::before`). Scoped to the slot wrapping THIS section
 * only, so the seam mechanism itself — and every other section pairing that
 * still wants it — is untouched.
 */
[data-dm-layout="street-magazine"][data-dm-seam="torn-paper"] .dm-slot:has(.dm-coverflow)::before {
	/* !important: tied specificity with the seam rule in layouts/street-magazine.css
	   means whichever stylesheet loads later wins by source order alone — a
	   pattern stylesheet has no business depending on layout enqueue order to
	   win that tie, so this says the override explicitly instead. */
	content: none !important;
}

.dm-coverflow {
  --cfs-card-w: 340px;
  --cfs-card-h: 600px;
  --cfs-radius: 18px;
  --cfs-perspective: 1500px;
  --cfs-shadow-strength: 0.55;
  --cfs-active-scale: 1;

  --cfs-media-ratio: 4/5;
  --cfs-media-fit: cover;
  --cfs-media-pos: center;

  --cfs-content-h: 176px;
  --cfs-content-pad: 18px;
  --cfs-title-size: 19px;
  --cfs-desc-size: 13px;
  --cfs-meta-size: 13px;

  --cfs-section-bg: var(--dm-bg, #171220);
  --cfs-card-bg: var(--dm-surface, #1f1a26);
  --cfs-card-border: var(--dm-border, rgba(255, 255, 255, 0.1));
  --cfs-title: var(--dm-text, #f5f1f8);
  --cfs-meta: var(--dm-text, #d6cde0);
  --cfs-muted: var(--dm-muted, #9c91aa);
  --cfs-accent: var(--dm-primary, #ff8a5b);
  --cfs-ind: var(--dm-border, rgba(255, 255, 255, 0.22));
  --cfs-ind-active: var(--dm-primary, #ff8a5b);
  --cfs-btn-bg: rgba(255, 255, 255, 0.07);
  --cfs-btn-text: var(--dm-text, #f5f1f8);
  --cfs-btn-border: var(--dm-border, rgba(255, 255, 255, 0.16));
  /* Ink for the numeral, which is drawn ON a photograph and so cannot take the
     card's own text colour. Named as a token rather than written as a literal,
     so a pack can change it (blueprint-parity forbids a literal on `color:`). */
  --cfs-index-ink: var(--dm-on-primary, #ffffff);
  /* The reusable display-font token every pack already defines for a
     poster-style headline (Anton-class condensed faces, etc.) — this pattern
     simply never wired it in before; the intro heading is the one place a
     coverflow-style showcase wants that register instead of body text. */
  --cfs-font-display: var(--dm-font-display, var(--dm-font-body, inherit));

  --cfs-speed: 520ms;
  --cfs-ease: cubic-bezier(0.22, 0.61, 0.28, 1);

  position: relative;
  overflow: hidden;
  padding: 26px 0 18px;
  background: var(--cfs-section-bg);
  font-family: var(--dm-font-body, inherit);
}
.dm-coverflow[data-stage-fixed="true"] {
  padding: 10px 0 8px;
}

/* One soft pool of light behind the active card. The only decoration. */
.dm-coverflow::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 38%;
  transform: translate(-50%, -50%);
  width: min(760px, 86%);
  aspect-ratio: 2/1;
  border-radius: 50%;
  background: radial-gradient(ellipse at center, var(--cfs-accent), transparent 68%);
  opacity: 0.22;
  pointer-events: none;
}

.dm-coverflow__intro {
  position: relative;
  z-index: 2;
  max-width: 720px;
  margin: 0 auto 26px;
  padding: 0 20px;
  text-align: center;
}
.dm-coverflow__eyebrow {
  margin: 0 0 6px;
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--cfs-accent);
}
.dm-coverflow__intro h2 {
  margin: 0;
  color: var(--cfs-title);
  font-family: var(--cfs-font-display);
  font-size: clamp(30px, 3.8vw, 46px);
  font-weight: 700;
  line-height: 0.96;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  text-wrap: balance;
}
.dm-coverflow__intro-accent { color: var(--cfs-accent); }
.dm-coverflow__intro-rule {
  display: block;
  width: 140px;
  height: 4px;
  margin: 12px auto 0;
  background: var(--cfs-accent);
  border-radius: 2px;
}
.dm-coverflow__intro p {
  margin: 8px 0 0;
  color: var(--cfs-muted);
  font-size: 14px;
  line-height: 1.6;
}

.dm-coverflow__viewport {
  position: relative;
  height: calc(var(--cfs-card-h) * var(--cfs-active-scale) + 56px);
  perspective: var(--cfs-perspective);
  perspective-origin: 50% 46%;
  touch-action: pan-y;
  cursor: grab;
  outline: none;
}
/* WANNABE's active card fills ~93% of the section height — the generic 56px
   viewport allowance (headroom for rotateY/scale on every side card in the
   continuous-geometry mode) is dead space this preset doesn't need. */
.dm-coverflow[data-stage-fixed="true"] .dm-coverflow__viewport {
  height: calc(var(--cfs-card-h) * var(--cfs-active-scale) + 12px);
}
.dm-coverflow__viewport:focus-visible {
  box-shadow: inset 0 0 0 2px var(--cfs-accent);
}
.dm-coverflow__viewport.is-dragging {
  cursor: grabbing;
}
.dm-coverflow__track {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  /* Explicitly above the pedestal (z-index 1). The cards' inline 900-1000
     z-indexes only order cards against each other INSIDE this preserve-3d
     context — against a sibling they count for nothing, and with z-index
     left auto the whole track painted underneath the pedestal. Invisible
     while the pedestal was a 56px ellipse; a tall stage image covered the
     cards completely (2026-08-19, found on carousel-3d, same bug here). */
  z-index: 2;
}

/*
 * The pedestal is plain 2D geometry, a sibling of .dm-coverflow__track rather
 * than a child of it: it never enters the preserve-3d chain, carries no
 * transform of its own beyond a static translate+scale (never one driven by
 * the active index) and is pointer-events:none, so it structurally cannot
 * shift activeCardCenterX or intercept the drag/click handlers bound to the
 * viewport. z-index is left low (cards set 900-1000 inline, arrows sit at 20)
 * so it paints behind both without needing to touch either.
 *
 * Sized from the composition (stage_width defaults to 720px, independent of
 * card_width), not from the active card, so it reads as a platform the whole
 * carousel stands on rather than a bar that tracks one card. max-width plus
 * the section's own overflow:hidden are the horizontal-overflow backstop —
 * both hold regardless of stage_scale.
 */
.dm-coverflow__pedestal {
  position: absolute;
  left: calc(50% + var(--cfs-stage-offset-x, 0px));
  bottom: var(--cfs-stage-offset-y, 16px);
  transform: translateX(-50%) scale(var(--cfs-stage-scale, 1));
  transform-origin: center bottom;
  width: var(--cfs-stage-w, 880px);
  max-width: calc(100% - 32px);
  opacity: var(--cfs-stage-opacity, 1);
  z-index: 1;
  pointer-events: none;
}

/* CSS mode: an ellipse (border-radius:50% on a wide, shallow box), not a
   rounded rectangle — --cfs-stage-radius is kept as a written token for
   backward compatibility but no longer drives this shape; a platform reads
   as elliptical/perspective, not as a bar with rounded ends. */
/* CSS mode: a showroom plinth, not a decorative platform — see carousel-3d.css
   for the full reasoning; identical construction with --cfs variables. */
.dm-coverflow__pedestal--css {
  height: var(--cfs-stage-h, 56px);
  border-radius: 50%;
  background:
    radial-gradient(ellipse 85% 55% at 50% 28%, rgba(196, 178, 148, 0.14), transparent 65%),
    var(--cfs-stage-surface, #1c1b17);
  box-shadow: 0 10px 26px rgba(0, 0, 0, calc(0.6 * var(--cfs-stage-shadow-strength, 0.5)));
}
.dm-coverflow[data-stage-style="platform"] .dm-coverflow__pedestal--css {
  box-shadow:
    0 3px 0 0 rgba(0, 0, 0, 0.35) inset,
    0 10px 26px rgba(0, 0, 0, calc(0.6 * var(--cfs-stage-shadow-strength, 0.5)));
}
.dm-coverflow[data-stage-style="floating"] .dm-coverflow__pedestal--css {
  opacity: calc(var(--cfs-stage-opacity, 1) * 0.9);
  box-shadow: 0 16px 36px rgba(0, 0, 0, calc(0.7 * var(--cfs-stage-shadow-strength, 0.5)));
}

/* Image mode: the site's own designed asset (transparent PNG/WebP expected),
   via the existing asset_slots/media-picker contract — not a raster fill on
   the CSS shape above, and not a second media library. Height defaults to
   auto so the asset's own aspect ratio is never distorted; a Detail author
   who wants an explicit height gets object-fit:contain, never stretch. */
.dm-coverflow__pedestal--image img {
  display: block;
  width: 100%;
  height: auto;
}
.dm-coverflow__pedestal--image[data-stage-height="fixed"] img {
  height: var(--cfs-stage-h, 56px);
  object-fit: contain;
  object-position: center bottom;
}

/* The front lip: the platform slice painted OVER the cards' bottom edge so
   they read as standing on it (foreground occlusion). Same geometry variables
   as the back pedestal — one platform, two paint layers — and the same static
   contract: no index-driven transform, no pointer events. z-index 3 sits above
   the track's 2 and below the arrows. */
.dm-coverflow__pedestal-front {
  position: absolute;
  left: calc(50% + var(--cfs-stage-offset-x, 0px));
  bottom: var(--cfs-stage-offset-y, 16px);
  transform: translateX(-50%) scale(var(--cfs-stage-scale, 1));
  transform-origin: center bottom;
  width: var(--cfs-stage-w, 880px);
  max-width: calc(100% - 32px);
  opacity: var(--cfs-stage-opacity, 1);
  z-index: 3;
  pointer-events: none;
}
.dm-coverflow__pedestal-front img {
  display: block;
  width: 100%;
  height: auto;
}
.dm-coverflow__pedestal-front[data-stage-height="fixed"] img {
  height: var(--cfs-stage-h, 56px);
  object-fit: contain;
  object-position: center bottom;
}

/* CSS front lip: the bottom `stage_depth`px of the SAME ellipse the back
   layer draws — see carousel-3d.css for the construction reasoning. */
.dm-coverflow__pedestal-front--css {
  height: var(--cfs-stage-h, 56px);
  border-radius: 50%;
  clip-path: inset(calc(100% - var(--cfs-stage-depth, 12px)) 0 0 0);
  background: linear-gradient(
    to bottom,
    var(--cfs-stage-border, rgba(196, 178, 148, 0.30)) calc(100% - var(--cfs-stage-depth, 12px)),
    var(--cfs-stage-border, rgba(196, 178, 148, 0.30)) calc(100% - var(--cfs-stage-depth, 12px) + 1.5px),
    #141412 calc(100% - var(--cfs-stage-depth, 12px) + 1.5px),
    #090909 100%
  );
}

.dm-coverflow__card {
  position: absolute;
  left: 50%;
  top: 50%;
  width: var(--cfs-card-w);
  height: var(--cfs-card-h);
  margin-left: calc(var(--cfs-card-w) / -2);
  margin-top: calc(var(--cfs-card-h) / -2);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--cfs-card-bg);
  border: 1px solid var(--cfs-card-border);
  border-radius: var(--cfs-radius);
  transform-style: preserve-3d;
  /* Every card shares the same unscaled box (top:50%/margin-top:-h/2 below),
     so their bottoms already coincide before any scale is applied. Scaling
     from the default centre origin would then float a shrunk side card's
     bottom edge upward, off the shared floor. Anchoring the origin at the
     bottom instead means scale() only eats into the card from the top, so
     every card — active or side, whatever its scale — keeps the same
     bottom edge: a real common baseline, not a platform graphic. */
  transform-origin: 50% 100%;
  will-change: transform, opacity, filter;
  box-shadow:
    0 calc(28px * var(--cfs-shadow-strength)) calc(60px * var(--cfs-shadow-strength))
    rgba(0, 0, 0, calc(0.6 * var(--cfs-shadow-strength)));
  transition:
    transform var(--cfs-speed) var(--cfs-ease),
    opacity var(--cfs-speed) var(--cfs-ease),
    filter var(--cfs-speed) var(--cfs-ease);
}
/*
 * This card renders as a real <article> element (semantic content region).
 * Some site-side stylesheets normalise the theme's own <article> content
 * wrapper with a bare `body.home article { width:100% !important; margin:0
 * !important; ... }` reset -- a selector far broader than its author meant,
 * since it also matches this component's cards. The plain (non-!important)
 * width/margin-left above cannot win against that: !important only loses to
 * another !important of equal-or-higher specificity. This reasserts exactly
 * the properties that reset breaks, at higher specificity (ancestor-scoped,
 * two classes vs. the reset's element+class+element) than a bare element
 * selector can reach, so this card's own centering math is never at the
 * mercy of an unrelated stylesheet's content-width reset.
 */
.dm-coverflow__viewport .dm-coverflow__card {
  width: var(--cfs-card-w) !important;
  max-width: var(--cfs-card-w) !important;
  margin-left: calc(var(--cfs-card-w) / -2) !important;
}

/*
 * Fixed-slot staging (stage_fixed setting, e.g. the wannabe-showcase preset):
 * three hand-set physical positions — previous / active / next — instead of
 * a position computed from distance. Horizontal centring still comes from
 * the base rule's left:50%/margin-left:-half above; this only overrides the
 * vertical anchor (bottom instead of centred) and adds each slot's own
 * offset/scale/rotation on top of that centred point. The JS
 * (renderFixedStage in coverflow-showcase.js) does nothing but assign
 * data-stage — CSS owns every visual value here, so the transition on the
 * base card rule animates a real "old slot -> new slot" jump whenever a
 * card's assigned slot changes, not a per-frame recalculation.
 */
.dm-coverflow[data-stage-fixed="true"] .dm-coverflow__card {
  top: auto;
  bottom: 0;
  margin-top: 0;
  opacity: 0;
  pointer-events: none;
  /* Measured off the reference: the active card's centre sits at ~50% of the
     FULL section width, not 50% of this narrower stage column — centring
     here (the column's own 50%) put the whole cluster visibly too far right
     against the wide info column this preset uses (confirmed via normalized
     bbox comparison, 2026-08-20). */
  left: 37%;
}
.dm-coverflow[data-stage-fixed="true"] .dm-coverflow__card[data-stage="active"] {
  transform: scale(1);
  opacity: 1;
  z-index: 3;
  filter: brightness(1);
}
.dm-coverflow[data-stage-fixed="true"] .dm-coverflow__card[data-stage="prev"] {
  /* Measured directly off the WANNABE reference (1918x738 source), not
     mirrored from the next slot: prev sits closer in and lifted off the
     shared floor by about 8% of its own height, not perfectly flush. */
  transform: translateX(-63%) translateY(-8%) scale(0.80) rotateY(6deg);
  opacity: 0.92;
  z-index: 2;
  filter: brightness(0.82);
}
.dm-coverflow[data-stage-fixed="true"] .dm-coverflow__card[data-stage="next"] {
  transform: translateX(70%) translateY(-8%) scale(0.84) rotateY(-5deg);
  opacity: 0.92;
  z-index: 2;
  filter: brightness(0.85);
}
.dm-coverflow__viewport.is-dragging .dm-coverflow__card {
  transition: none;
}

/* THE MEDIA FRAME — owns the ratio; the image fills it; no image still leaves it. */
.dm-coverflow__media {
  position: relative;
  flex: 0 0 auto;
  width: 100%;
  aspect-ratio: var(--cfs-media-ratio);
  overflow: hidden;
  background: linear-gradient(150deg, var(--cfs-card-border), var(--cfs-card-bg));
}
.dm-coverflow__media img {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: var(--cfs-media-fit);
  object-position: var(--cfs-media-pos);
}
/*
 * site-shell.css's global `body.dm-site-shell-enabled img { height: auto; }`
 * (a sane default for ordinary content images) has higher specificity
 * (0,1,2 - two elements, one class) than the plain rule above (0,1,1 - one
 * element, one class), so it wins and overrides height:100% with height:auto.
 * A loaded image then renders at its own intrinsic aspect ratio scaled to the
 * resolved width instead of filling the media box, leaving the box's own
 * decorative background (a gradient toward --cfs-card-bg) showing through as
 * a visible band beneath the image - most visible with the card content strip
 * off, when the media box is the entire card. Reasserted here at higher
 * specificity (0,2,1 - two classes, one element), scoped to this component
 * only; every other image on the site keeps the global auto-height default.
 */
.dm-coverflow__card .dm-coverflow__media img {
  height: 100%;
}
.dm-coverflow__badge {
  position: absolute;
  left: 12px;
  top: 12px;
  z-index: 2;
  padding: 5px 9px;
  border-radius: 999px;
  font-size: 10.5px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--cfs-accent);
  background: var(--cfs-card-bg);
  border: 1px solid var(--cfs-accent);
}
.dm-coverflow__index {
  position: absolute;
  right: 12px;
  bottom: 8px;
  z-index: 2;
  font-size: 40px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--cfs-index-ink);
  opacity: 0.28;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 1px 8px rgba(0, 0, 0, 0.4);
}

/* CONTENT — fixed height, so one line of text and three make the same card. */
.dm-coverflow__content {
  flex: 1 1 auto;
  min-height: 0;
  height: var(--cfs-content-h);
  padding: var(--cfs-content-pad);
  display: flex;
  flex-direction: column;
  gap: 5px;
  overflow: hidden;
}
.dm-coverflow__card-eyebrow {
  margin: 0;
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--cfs-accent);
}
.dm-coverflow__card h3 {
  margin: 0;
  font-size: var(--cfs-title-size);
  font-weight: 640;
  line-height: 1.25;
  letter-spacing: -0.012em;
  color: var(--cfs-title);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.dm-coverflow__description {
  margin: 0;
  font-size: var(--cfs-desc-size);
  line-height: 1.5;
  color: var(--cfs-muted);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.dm-coverflow__foot {
  margin-top: auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.dm-coverflow__commerce {
  display: flex;
  align-items: baseline;
  gap: 7px;
  font-size: var(--cfs-meta-size);
}
.dm-coverflow__price {
  margin: 0;
  color: var(--cfs-meta);
  font-weight: 640;
  font-variant-numeric: tabular-nums;
}
.dm-coverflow__price del {
  margin-left: 6px;
  color: var(--cfs-muted);
  font-size: 0.86em;
  font-weight: 400;
}
.dm-coverflow__status {
  color: var(--cfs-muted);
  font-size: 0.9em;
}
.dm-coverflow__cta {
  padding: 7px 13px;
  border-radius: 999px;
  font-size: 12.5px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  color: var(--cfs-btn-text);
  background: var(--cfs-btn-bg);
  border: 1px solid var(--cfs-btn-border);
  transition: background 0.15s, border-color 0.15s;
}
.dm-coverflow__cta:hover,
.dm-coverflow__cta:focus-visible {
  border-color: var(--cfs-accent);
}

.dm-coverflow__arrows {
  position: absolute;
  inset: 0;
  z-index: 20;
  pointer-events: none;
}
.dm-coverflow__arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  pointer-events: auto;
  box-sizing: border-box;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  cursor: pointer;
  color: var(--cfs-btn-text);
  background: var(--cfs-btn-bg);
  border: 1px solid var(--cfs-btn-border);
  font-size: 17px;
  line-height: 1;
  transition: border-color 0.15s, background 0.15s;
}
/* prev/next must always look identical to each other, and both must read as
   a TRUE circle. A theme/skin-level rule targeting bare `button` (e.g. a pack
   skin's `.dm-skin-xxx button{border-radius:...}` reset) carries an element
   selector our own class-only rule above doesn't, so it can out-specificity
   this block and flatten the corners to a square even though nothing here
   changed (confirmed via computed style: both arrows were rendering at
   border-radius:0, 2026-08-20) — likewise a theme-level `button:hover` can
   win the interaction states and leave one arrow in the theme's default
   colour. Every state re-asserts the same properties explicitly so neither
   can happen regardless of what other stylesheets declare for `button`. */
.dm-coverflow__arrow,
.dm-coverflow__arrow:hover,
.dm-coverflow__arrow:focus,
.dm-coverflow__arrow:focus-visible,
.dm-coverflow__arrow:active {
  border-radius: 50% !important;
  background: var(--cfs-btn-bg) !important;
  color: var(--cfs-btn-text) !important;
  border-color: var(--cfs-btn-border) !important;
}
.dm-coverflow__arrow:hover,
.dm-coverflow__arrow:focus-visible {
  border-color: var(--cfs-accent) !important;
}
.dm-coverflow__arrow:focus-visible {
  outline: 2px solid var(--cfs-accent);
  outline-offset: 2px;
}
.dm-coverflow__arrow--prev { left: clamp(10px, 3%, 34px); }
.dm-coverflow__arrow--next { right: clamp(10px, 3%, 34px); }

/* Arrow design variants (arrows_style). "ghost" is the default look above. */
.dm-coverflow[data-arrows-style="solid"] .dm-coverflow__arrow,
.dm-coverflow[data-arrows-style="solid"] .dm-coverflow__arrow:hover,
.dm-coverflow[data-arrows-style="solid"] .dm-coverflow__arrow:focus,
.dm-coverflow[data-arrows-style="solid"] .dm-coverflow__arrow:focus-visible,
.dm-coverflow[data-arrows-style="solid"] .dm-coverflow__arrow:active {
  background: var(--cfs-accent) !important;
  color: var(--cfs-section-bg) !important;
  border-color: transparent !important;
}
.dm-coverflow[data-arrows-style="minimal"] .dm-coverflow__arrow,
.dm-coverflow[data-arrows-style="minimal"] .dm-coverflow__arrow:hover,
.dm-coverflow[data-arrows-style="minimal"] .dm-coverflow__arrow:focus,
.dm-coverflow[data-arrows-style="minimal"] .dm-coverflow__arrow:focus-visible,
.dm-coverflow[data-arrows-style="minimal"] .dm-coverflow__arrow:active {
  background: transparent !important;
  border-color: transparent !important;
  font-size: 28px;
}
/* A thin accent-coloured ring on a dark/transparent interior with a light
   glyph — bigger target, minimal chrome. Reusable across any coverflow
   instance via arrows_style, not specific to one product's copy. */
.dm-coverflow[data-arrows-style="circle-outline"] .dm-coverflow__arrow,
.dm-coverflow[data-arrows-style="circle-outline"] .dm-coverflow__arrow:hover,
.dm-coverflow[data-arrows-style="circle-outline"] .dm-coverflow__arrow:focus,
.dm-coverflow[data-arrows-style="circle-outline"] .dm-coverflow__arrow:focus-visible,
.dm-coverflow[data-arrows-style="circle-outline"] .dm-coverflow__arrow:active {
  /* !important + explicit box-sizing: some ancestor context (the moved
     previous button's new flow position included) was inflating the
     unqualified width past the declared value while height stayed put,
     rendering an ellipse instead of a circle — pin both dimensions and the
     box model so they can never drift apart (2026-08-20). */
  box-sizing: border-box !important;
  width: 60px !important;
  height: 60px !important;
  padding: 0 !important;
  min-width: 0 !important;
  min-height: 0 !important;
  background: rgba(0, 0, 0, 0.35) !important;
  color: var(--cfs-title) !important;
  border: 2px solid var(--cfs-accent) !important;
  font-size: 21px;
}

/* Arrow position variants (arrows_position). "edge" is the default above;
   "near" pins each arrow just outside the active-card-plus-neighbours cluster,
   so they read as part of the composition instead of floating at the section's
   far edges. Vertical centring is unchanged: 50% of the viewport is the cards'
   own vertical centre (cards are top:50% translated). */
.dm-coverflow[data-arrows-position="near"] .dm-coverflow__arrow--prev {
  left: max(8px, calc(50% - var(--cfs-cluster-half, 480px) - 80px));
}
.dm-coverflow[data-arrows-position="near"] .dm-coverflow__arrow--next {
  right: max(8px, calc(50% - var(--cfs-cluster-half, 480px) - 80px));
}
/* Fixed-stage next arrow: measured directly off the WANNABE reference as an
   inset from the stage zone's own right edge, not derived from the
   cluster-half formula above (which assumes the symmetric side_offset
   geometry this preset's cards no longer use). */
.dm-coverflow[data-stage-fixed="true"][data-arrows-position="near"] .dm-coverflow__arrow--next {
  right: 6%;
}

/*
 * GREEN BADGER DETAIL CORRECTION DIRECTIVE v2 (2026-08-21), P0-2 — a control
 * row (prev / counter / next) directly under the stage, not overlaid at the
 * cards' own vertical centre like "edge"/"near". The viewport already has
 * position:relative and a fixed height, so top:100% lands exactly on its
 * bottom edge without touching that height or clipping anything (no
 * overflow:hidden anywhere in this chain) — sibling elements (active-content,
 * indicators) don't reserve room for it since it stays absolutely positioned,
 * so .dm-coverflow__active-content gets extra margin-top below to compensate.
 */
.dm-coverflow[data-arrows-position="below"] .dm-coverflow__arrows {
	position: relative;
	inset: auto;
	transform: none;
	width: fit-content;
	margin: 22px auto 0;
	display: flex;
	align-items: center;
	gap: 20px;
	pointer-events: auto;
	z-index: 5;
}
.dm-coverflow[data-arrows-position="below"] .dm-coverflow__arrow--prev,
.dm-coverflow[data-arrows-position="below"] .dm-coverflow__arrow--next {
  position: static;
  top: auto;
  left: auto;
  right: auto;
  transform: none;
}
.dm-coverflow[data-arrows-position="below"] .dm-coverflow__active-content {
	margin-top: 24px;
}
.dm-coverflow__position--stage {
  display: none;
  margin: 0;
  font-family: var(--dm-font-display, inherit);
  font-weight: 700;
  font-size: 15px;
  letter-spacing: 0.04em;
  color: var(--cfs-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.dm-coverflow[data-arrows-position="below"] .dm-coverflow__position--stage {
  display: block;
}

.dm-coverflow__indicators {
  position: relative;
  z-index: 5;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 7px;
  margin-top: 22px;
}
.dm-coverflow__dot {
  width: 22px;
  height: 4px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  cursor: pointer;
  background: var(--cfs-ind);
  transition: background 0.2s, width 0.2s;
}
.dm-coverflow__dot[aria-current="true"] {
  width: 40px;
  background: var(--cfs-ind-active);
}
.dm-coverflow__dot:focus-visible {
  outline: 2px solid var(--cfs-accent);
  outline-offset: 3px;
}

.dm-coverflow[data-arrows="false"] .dm-coverflow__arrows { display: none; }
.dm-coverflow[data-indicators="false"] .dm-coverflow__indicators { display: none; }

/*
 * content_layout: "left" — the reference composition. The intro heading, the
 * active-card mirror and the indicators are rendered (in this mode only) inside
 * one `.dm-coverflow__left-stack` wrapper, so they behave as ONE grid item next
 * to the card stage. That is what makes `align-items: center` on a single-row
 * grid centre the whole text column against the stage's real height — three
 * separate items each centred on their own auto-sized row track (the previous
 * approach) pushed the group toward the bottom instead, since the stage's much
 * taller intrinsic height skews how the three auto rows split the space
 * (2026-08-20). The "top" default keeps the old flat markup and is untouched.
 */
.dm-coverflow[data-content-layout="left"] {
	display: grid;
	grid-template-columns: clamp(200px, 22%, 420px) minmax(0, 1fr);
	grid-template-areas: "stack stage";
	align-items: center;
	column-gap: clamp(8px, 2vw, 24px);
	padding-left: clamp(16px, 4vw, 56px);
}
.dm-coverflow[data-content-layout="left"] .dm-coverflow__left-stack {
	grid-area: stack;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
}
/* WANNABE's editorial column starts near the top of the composition and
   leaves the remaining space below the previous-arrow empty — centring it
   against the (much taller) active card leaves it floating too low. Measured
   off the reference: the headline's own top sits at ~11% of the section
   height. */
.dm-coverflow[data-stage-fixed="true"] .dm-coverflow__left-stack {
	align-self: start;
	margin-top: 10%;
}
.dm-coverflow[data-content-layout="left"] .dm-coverflow__intro {
	margin: 0;
	padding: 0;
	max-width: none;
	text-align: left;
}
.dm-coverflow[data-content-layout="left"] .dm-coverflow__intro-rule { margin: 16px 0 0; }
.dm-coverflow[data-content-layout="left"] .dm-coverflow__position { display: none; }
.dm-coverflow[data-content-layout="left"] .dm-coverflow__viewport { grid-area: stage; }
.dm-coverflow[data-content-layout="left"] .dm-coverflow__active-content {
	margin: 14px 0 0;
	padding: 0;
	max-width: none;
	text-align: left;
}
.dm-coverflow[data-content-layout="left"] .dm-coverflow__active-content-item { text-align: left; }
.dm-coverflow[data-content-layout="left"] .dm-coverflow__indicators {
	justify-content: flex-start;
	margin-top: 18px;
}
/* The previous-card control lives in the info stack for this layout (see
   render_product_coverflow()) — flow position, not the absolute/inset-0
   positioning the same button uses next to the cards. */
.dm-coverflow__arrows--stack {
	position: static;
	inset: auto;
	z-index: auto;
	pointer-events: auto;
	margin-top: 22px;
}
/* Measured off the reference: the previous-arrow sits much further down the
   section than a plain 22px gap gives once the active card is this tall —
   its own height (the one number in this preset already scaled to the
   section) is the relative unit that keeps the arrow proportionally in
   place if card_width ever changes, not a fixed px gap. */
.dm-coverflow[data-stage-fixed="true"] .dm-coverflow__arrows--stack {
	margin-top: calc(var(--cfs-card-h) * 0.24);
}
.dm-coverflow__arrows--stack .dm-coverflow__arrow--prev {
	position: static;
	left: auto;
	transform: none;
}
.dm-coverflow[data-content-layout="left"]::before { left: 62%; }
@media (max-width: 860px) {
	/* The side column has no room on a phone — fall back to the stacked layout. */
	.dm-coverflow[data-content-layout="left"] {
		display: block;
		padding-left: 0;
	}
	.dm-coverflow[data-content-layout="left"] .dm-coverflow__left-stack { align-items: center; }
	.dm-coverflow[data-content-layout="left"] .dm-coverflow__intro,
	.dm-coverflow[data-content-layout="left"] .dm-coverflow__active-content {
		text-align: center;
		margin: 0 auto 26px;
		padding: 0 20px;
	}
	.dm-coverflow[data-content-layout="left"] .dm-coverflow__indicators { justify-content: center; }
}

/*
 * content_layout: "theater" (2026-08-21, source-v2 migration reference).
 *
 * Intro in its own column; stage + the active-card mirror + indicators
 * stacked in a second column beside it — reference's
 * `.theater{grid-template-columns:minmax(270px,370px) 1fr}` with
 * `.active-info` sitting BELOW the stage rather than beside the intro (the
 * distinction from "left", which puts the mirror in the intro's own
 * column). `.dm-coverflow__stage-group` is the one new wrapper the renderer
 * emits for this mode only — every element inside it is queried by the
 * pattern script through its own data-attribute, so nesting it changes
 * nothing about behaviour.
 */
.dm-coverflow[data-content-layout="theater"] {
	display: grid;
	grid-template-columns: minmax(270px, 370px) 1fr;
	align-items: center;
	column-gap: clamp(24px, 4vw, 64px);
	padding-inline: clamp(20px, 5vw, 64px);
}
.dm-coverflow[data-content-layout="theater"] .dm-coverflow__intro {
	margin: 0;
	padding: 0;
	max-width: none;
	text-align: left;
}
.dm-coverflow[data-content-layout="theater"] .dm-coverflow__intro-rule { margin: 16px 0 0; }
.dm-coverflow[data-content-layout="theater"] .dm-coverflow__position { display: none; }
/* Higher specificity than the rule directly above (two attributes, not one)
   so a stage counter in theater layout is not re-hidden by it. */
.dm-coverflow[data-content-layout="theater"][data-arrows-position="below"] .dm-coverflow__position--stage {
	display: block;
}
.dm-coverflow[data-content-layout="theater"] .dm-coverflow__stage-group { min-width: 0; }
.dm-coverflow[data-content-layout="theater"] .dm-coverflow__active-content {
	margin: 22px auto 0;
	max-width: 720px;
	padding: 22px 0 0;
	border-top: 1px solid var(--cfs-card-border);
	text-align: left;
}
/* Reference's active-info is a 3-column row (spec+name | price | cta); this
   section's markup keeps eyebrow/title as separate siblings before .foot
   rather than one wrapper div, so the same visual relation is built with a
   2-column grid instead — eyebrow+title stacked in column 1, .foot (which
   already holds price and the CTA as its own flex row) spanning column 2. */
.dm-coverflow[data-content-layout="theater"] .dm-coverflow__active-content-item {
	display: grid;
	grid-template-columns: 1fr auto;
	align-items: center;
	column-gap: 28px;
}
/*
 * GREEN BADGER DETAIL CORRECTION DIRECTIVE v2 (2026-08-21), reviewer
 * correction #3 — a real bug in this shared pattern, not Green-Badger-only:
 * the theater-layout rule above (attribute + 2 classes) is more specific
 * than the generic `.dm-coverflow__active-content-item[hidden]{display:none}`
 * rule elsewhere in this file (1 class + 1 attribute), so every inactive
 * product's info row rendered anyway in theater layout — all 5 products
 * listed vertically instead of only the active one. Matching the theater
 * selector's own specificity plus [hidden] guarantees this wins regardless
 * of source order.
 */
.dm-coverflow[data-content-layout="theater"] .dm-coverflow__active-content-item[hidden] {
	display: none;
}
.dm-coverflow[data-content-layout="theater"] .dm-coverflow__active-content-eyebrow {
	grid-column: 1;
	grid-row: 1;
	margin: 0 0 7px;
}
.dm-coverflow[data-content-layout="theater"] .dm-coverflow__active-content-item h3 {
	grid-column: 1;
	grid-row: 2;
	margin: 0;
}
/* Reference's active-info carries no description line — kept out of this
   layout's row rather than given a third grid row nobody asked for. */
.dm-coverflow[data-content-layout="theater"] .dm-coverflow__active-content-desc { display: none; }
.dm-coverflow[data-content-layout="theater"] .dm-coverflow__active-content-foot {
	grid-column: 2;
	grid-row: 1 / 3;
	gap: 24px;
}
.dm-coverflow[data-content-layout="theater"] .dm-coverflow__indicators {
	justify-content: flex-start;
	margin-top: 14px;
}
.dm-coverflow[data-content-layout="theater"]::before { left: 66%; }
@media (max-width: 860px) {
	.dm-coverflow[data-content-layout="theater"] {
		display: block;
		padding-inline: clamp(16px, 4vw, 32px);
	}
	.dm-coverflow[data-content-layout="theater"] .dm-coverflow__intro {
		text-align: center;
		max-width: 420px;
		margin: 0 auto 26px;
	}
	.dm-coverflow[data-content-layout="theater"] .dm-coverflow__active-content-item {
		grid-template-columns: 1fr;
		justify-items: center;
		text-align: center;
		row-gap: 10px;
	}
	.dm-coverflow[data-content-layout="theater"] .dm-coverflow__active-content-eyebrow,
	.dm-coverflow[data-content-layout="theater"] .dm-coverflow__active-content-item h3 { grid-column: 1; }
	.dm-coverflow[data-content-layout="theater"] .dm-coverflow__active-content-foot {
		grid-column: 1;
		grid-row: auto;
		justify-content: center;
	}
	.dm-coverflow[data-content-layout="theater"] .dm-coverflow__indicators { justify-content: center; }
}

/*
 * Active-content mirror: one panel per card (same eleven-key fields the card
 * itself renders), all but the active one carrying the `hidden` attribute.
 * The pattern script moves `hidden` as the active index changes — see
 * coverflow-showcase.js. `hidden` drops an inactive panel from layout, the
 * accessibility tree and the tab order in one step, so its CTA link cannot be
 * focused while some other card is active.
 */
.dm-coverflow__active-content {
  position: relative;
  z-index: 2;
  max-width: 640px;
  margin: var(--cfs-active-gap, 18px) auto 0;
  padding: 0 20px;
  text-align: var(--cfs-active-align, center);
}
.dm-coverflow__active-content-item[hidden] { display: none; }
.dm-coverflow__active-content-eyebrow {
  margin: 0 0 4px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--cfs-accent);
}
.dm-coverflow__active-content-headline ~ .dm-coverflow__active-content-eyebrow { margin-top: 22px; }
.dm-coverflow__active-content-headline {
  margin: 0;
  color: var(--cfs-title);
  font-family: var(--cfs-font-display);
  font-size: clamp(30px, 3.8vw, 46px);
  font-weight: 700;
  line-height: 0.96;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  text-wrap: balance;
}
.dm-coverflow__active-content-item h3 {
  margin: 0 0 6px;
  font-size: var(--cfs-active-title-size, 22px);
  font-weight: 640;
  line-height: 1.2;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--cfs-title);
}
.dm-coverflow__active-content-headline ~ h3 { margin-top: 14px; }
.dm-coverflow__active-content-desc {
  margin: 0 0 10px;
  font-size: var(--cfs-active-desc-size, 14px);
  line-height: 1.55;
  color: var(--cfs-muted);
}
.dm-coverflow__active-content-foot {
  display: flex;
  align-items: center;
  justify-content: var(--cfs-active-justify, center);
  flex-wrap: wrap;
  gap: 12px;
}
.dm-coverflow__active-content-meta {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-size: var(--cfs-meta-size, 13px);
}
.dm-coverflow__active-content-badge {
  padding: 3px 9px;
  border-radius: 999px;
  font-size: 10.5px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--cfs-accent);
  border: 1px solid var(--cfs-accent);
}
.dm-coverflow__active-content-price {
  color: var(--cfs-title);
  font-size: 1.4em;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.dm-coverflow__active-content-price del {
  margin-left: 6px;
  color: var(--cfs-muted);
  font-size: 0.86em;
  font-weight: 400;
}
.dm-coverflow__active-content-status { color: var(--cfs-muted); font-size: 0.9em; }
.dm-coverflow__active-content-cta {
  padding: 8px 16px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  color: var(--cfs-btn-text);
  background: var(--cfs-btn-bg);
  border: 1px solid var(--cfs-btn-border);
  transition: background 0.15s, border-color 0.15s;
}
.dm-coverflow__active-content-cta:hover,
.dm-coverflow__active-content-cta:focus-visible {
  border-color: var(--cfs-accent);
}

.dm-coverflow__position {
  margin: 8px 0 0;
  text-align: center;
  font-size: 12px;
  color: var(--cfs-muted);
  font-variant-numeric: tabular-nums;
}

/* No script, no 3D: the cards stay a readable row rather than a pile. */
.dm-coverflow:not([data-ready="true"]) .dm-coverflow__viewport {
  height: auto;
  perspective: none;
}
.dm-coverflow:not([data-ready="true"]) .dm-coverflow__track {
  position: static;
  display: flex;
  gap: 20px;
  overflow-x: auto;
  padding: 4px 20px 14px;
}
.dm-coverflow:not([data-ready="true"]) .dm-coverflow__card {
  position: static;
  flex: 0 0 auto;
  margin: 0;
}
.dm-coverflow:not([data-ready="true"]) .dm-coverflow__arrows { display: none; }

@media (prefers-reduced-motion: reduce) {
  .dm-coverflow__card { transition-duration: 1ms; }
  .dm-coverflow__arrow { transition: none; }
}
