/* ============================================================
   Media — "Publication, Media & Awards"
   Left: selection window (.mediaSel).  Right: detail (.media__*).
   ============================================================ */

/* clip the right→left fade where it bleeds past the viewport edge
   (clip on x only, so the left panel's vertical overhang stays visible) */
.media { align-content: center; overflow-x: clip; }

.media__inner { width: min(100% - 2 * var(--section-pad), var(--maxw)); margin-inline: auto; }

.media__head { margin-bottom: var(--space-lg); }
/* title uses the shared .section-title (css/sections.css) */

/* ---- master / detail grid ---- */
.media__body {
  /* right→left fade lives here (see the fade knobs in the detail block) */
  --detail-fade: rgba(255, 255, 255, 0.05);
  --detail-fade-stop: 60%;
  /* gutter from the body's right edge to the viewport edge. The body is
     centred in the viewport (symmetric section padding + auto margins), so
     the gutter is simply half the leftover space — this is robust no matter
     how many nested paddings inset the container. 100% = the body's width. */
  --detail-bleed: calc((100vw - 100%) / 2);

  position: relative;
  z-index: 0;                    /* own stacking context so ::before sits behind */
  display: grid;
  grid-template-columns: minmax(300px, 380px) 1fr;
  gap: clamp(2rem, 5vw, 5rem);
  align-items: center;
}
/* the fade — on the UN-transformed grid, so no 3D skew shifts its edge.
   Its right edge is pushed out by --detail-bleed to meet the viewport edge. */
.media__body::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 40%;                     /* ~ where the detail column begins */
  right: calc(-1 * var(--detail-bleed));
  z-index: -1;                   /* behind both halves */
  background: linear-gradient(to left, var(--detail-fade), transparent var(--detail-fade-stop));
  pointer-events: none;
}

/* ============================================================
   Selection window (left half)
   ------------------------------------------------------------
   Visual controls — tweak these, everything reflows:

   | Variable            | Controls                                    |
   |---------------------|---------------------------------------------|
   | --sel-persp         | 3D perspective depth (smaller = stronger)   |
   | --sel-tilt-y        | panel Y-rotation (the main tilt)            |
   | --sel-tilt-x        | panel X-rotation (slight top/bottom lean)   |
   | --sel-radius        | corner radius of panel + ghost              |
   | --sel-ghost-x/y     | offset of the outline "ghost" copy behind   |
   | --sel-motif-x/y     | how far the dot/X motif box overhangs panel |
   | --sel-dot-size      | dot-grid spacing                            |
   | --sel-dot-color     | dot-grid color                              |
   | --sel-x-size        | size of the corner X marks                  |
   | --sel-x-color       | color of the corner X marks                 |
   | --sel-tick-radius   | radius of the ticker arc around the button  |
   | --sel-tick-spacing  | angle between adjacent ticks (fan spread)   |
   | --sel-tick-offset   | rotates the whole fan (0deg = centred top)  |
   | --sel-list-gap      | vertical gap between groups                 |
   | --sel-group-gap     | vertical gap between rows within a group    |
   | --sel-item-lh       | line-height of item labels (wrapped rows)   |
   ============================================================ */
.mediaSel {
  --sel-persp: 1500px;
  --sel-tilt-y: 10deg;
  --sel-tilt-x: 3.5deg;
  --sel-radius: 22px;
  --sel-ghost-x: -8px;
  --sel-ghost-y: 8px;
  --sel-motif-x: 34px;
  --sel-motif-y: 26px;
  --sel-dot-size: 15px;
  --sel-dot-color: rgba(255, 255, 255, 0.22);
  --sel-x-size: 13px;
  --sel-x-color: var(--accent-mid);
  --sel-tick-radius: 30px;
  --sel-tick-spacing: 14deg;
  --sel-tick-offset: 45deg;
  --sel-list-gap: 1.6rem;
  --sel-group-gap: 0.55rem;
  --sel-item-lh: 1.3;

  perspective: var(--sel-persp);
  perspective-origin: 60% 40%;
  /* breathing room so the tilted ghost + overhanging motif never clip */
  padding: 30px 46px 34px 20px;
}

/* the element that actually carries the 3D rotation */
.mediaSel__stage {
  position: relative;
  transform-style: preserve-3d;
  transform: rotateX(var(--sel-tilt-x)) rotateY(var(--sel-tilt-y));
}

/* ---- outline-only duplicate sitting behind, offset down-left ---- */
.mediaSel__ghost {
  position: absolute;
  inset: 0;
  z-index: 1;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: var(--sel-radius);
  transform: translate(var(--sel-ghost-x), var(--sel-ghost-y));
  pointer-events: none;
  /* fade the ghost out toward the bottom like the main panel */
  -webkit-mask-image: linear-gradient(180deg, #000 45%, transparent 92%);
          mask-image: linear-gradient(180deg, #000 45%, transparent 92%);
}

/* ---- corner motif box (bigger than the panel) ---- */
.mediaSel__motif {
  position: absolute;
  inset: calc(-1 * var(--sel-motif-y)) calc(-1 * var(--sel-motif-x));
  z-index: 0;
  pointer-events: none;
}

/* dot-grid patches, each fading diagonally out of a corner */
.mediaSel__dots {
  position: absolute;
  width: 66%;
  height: 60%;
  background-image: radial-gradient(circle, var(--sel-dot-color) 1px, transparent 1.6px);
  background-size: var(--sel-dot-size) var(--sel-dot-size);
}
.mediaSel__dots--tl {
  top: 0; left: 0;
  -webkit-mask-image: linear-gradient(to bottom right, #000, transparent 68%);
          mask-image: linear-gradient(to bottom right, #000, transparent 68%);
}
.mediaSel__dots--br {
  bottom: 0; right: 0;
  -webkit-mask-image: linear-gradient(to top left, #000, transparent 68%);
          mask-image: linear-gradient(to top left, #000, transparent 68%);
}

/* thin X marks in three corners of the motif box */
.mediaSel__x {
  position: absolute;
  width: var(--sel-x-size);
  height: var(--sel-x-size);
  background:
    linear-gradient(45deg,  transparent calc(50% - 0.6px), var(--sel-x-color) calc(50% - 0.6px), var(--sel-x-color) calc(50% + 0.6px), transparent calc(50% + 0.6px)),
    linear-gradient(-45deg, transparent calc(50% - 0.6px), var(--sel-x-color) calc(50% - 0.6px), var(--sel-x-color) calc(50% + 0.6px), transparent calc(50% + 0.6px));
}
.mediaSel__x--tl { top: 0;    left: 0;  }
.mediaSel__x--bl { bottom: 0; left: 0;  }
.mediaSel__x--br { bottom: 0; right: 0; }

/* ---- the main panel: gradient fill + gradient border, faded at base ---- */
.mediaSel__panel {
  position: relative;
  z-index: 2;
  padding: 26px 26px;
  border-radius: var(--sel-radius);
  /* fill fades to transparent toward the bottom */
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.055) 0%, rgba(255, 255, 255, 0.02) 38%, transparent 78%);
}
/* gradient border via masked pseudo-element; the border color itself
   fades to transparent toward the bottom, so no second mask is needed */
.mediaSel__panel::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(
    180deg,
    rgba(255, 255, 255, 0.55) 0%,
    rgba(255, 255, 255, 0.18) 42%,
    rgba(255, 255, 255, 0.02) 78%,
    transparent 100%
  );
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
  pointer-events: none;
}

/* ---- panel label (top-left, absolute) ---- */
.mediaSel__label {
  /* --- tunable knobs (mirror .section-title) --- */
  --label-fill-from: #ffffff;                    /* gradient fill: top   */
  --label-fill-to:   rgba(255, 255, 255, 0.45);  /* gradient fill: bottom */
  --label-outline:   rgba(255, 255, 255, 0.70);  /* solid text outline    */
  --label-stroke-w:  1px;

  position: absolute;
  top: 0px;
  left: 24px;
  transform: translate(0, -50%);
  font-family: var(--font-head);
  font-weight: 700;
  font-size: clamp(1.6rem, 1.2rem + 1.4vw, 2.2rem);
  line-height: 1;
  letter-spacing: 0.01em;

  /* gradient fill clipped to the glyphs */
  color: transparent;
  background: linear-gradient(90deg, var(--label-fill-from), var(--label-fill-to));
  -webkit-background-clip: text;
          background-clip: text;
  /* solid outline behind the gradient fill */
  -webkit-text-stroke: var(--label-stroke-w) var(--label-outline);
  paint-order: stroke fill;
  /* drop-shadow (not text-shadow) so it survives background-clip: text */
  filter: drop-shadow(0 2px 14px rgba(0, 0, 0, 0.55));
}

/* ---- cycle button (top-right) with ticker ring ---- */
.mediaSel__cycle {
  position: absolute;
  top: 0px;
  right: 10px;
  transform: translate(50%, -50%);
  width: 46px;
  height: 46px;
  display: grid;
  place-items: center;
  border: 0;
  background: transparent;
  color: var(--fg);
  cursor: pointer;
}
/* The visible circle lives on ::before so the press-scale shrinks only the
   VISUAL, not the button's 46px hit area. Scaling the button itself moved its
   edges out from under the cursor on an edge click, so pointerup landed outside
   and the click never fired. */
.mediaSel__cycle::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: 50%;
  border: 1px solid var(--border-strong);
  background: rgba(0, 0, 0, 1);
  transition: border-color 0.2s ease, background 0.2s ease, transform 0.2s ease;
}
.mediaSel__cycle:hover::before { border-color: var(--accent); background: rgb(31, 51, 8); }
.mediaSel__cycle:active::before,
.mediaSel__cycle:active .mediaSel__arrow { transform: scale(0.7); transition: transform 0s; }
.mediaSel__arrow { width: 20px; height: 20px; transition: transform 0.2s ease; }

/* ticker: one tick per panel, fanned in an arc over the button top */
.mediaSel__ticker {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.mediaSel__tick {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 2px;
  height: 6px;
  margin: -3px 0 0 -1px;         /* centre the tick before rotating out */
  border-radius: 1px;
  background: rgba(255, 255, 255, 0.22);
  transform-origin: 50% 50%;
  /* --i (signed offset from centre) is set inline in JS; spacing + radius
     are CSS controls, so the whole fan is tunable without touching JS */
  transform:
    rotate(calc(var(--sel-tick-offset) + var(--i, 0) * var(--sel-tick-spacing)))
    translateY(calc(-1 * var(--sel-tick-radius)));
  transition: background 0.25s ease, height 0.25s ease;
}
.mediaSel__tick.is-on { background: var(--accent); height: 8px; }

/* ---- selection list ---- */
.mediaSel__list {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--sel-list-gap);       /* spacing between groups */
}

.mediaSel__group {
  display: flex;
  flex-direction: column;
  gap: var(--sel-group-gap);      /* spacing between label + item rows */
}

.mediaSel__group-label {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--fg-faint);
}
.mediaSel__group-label span { flex: 0 0 auto; }
/* trailing hairline that runs to the panel edge */
.mediaSel__group-label::after {
  content: "";
  flex: 1 1 auto;
  height: 1px;
  background: linear-gradient(90deg, var(--border-strong), transparent);
}

.mediaSel__item {
  position: relative;
  display: block;
  width: 100%;
  padding: 0 0 0 0.9rem;
  text-align: left;
  color: var(--fg-dim);
  line-height: var(--sel-item-lh);   /* wrapped-line spacing; inherited by label + sub */
  transition: color 0.18s ease;
}
.mediaSel__item:hover { color: var(--fg); }

.mediaSel__item-label { font-weight: 500; font-size: var(--step-0); }
.mediaSel__item-sub {
  display: block;
  font-size: var(--step--1);
  color: var(--fg-faint);
}

/* active row: accent text + left bar */
.mediaSel__item.is-active { color: var(--accent); }
.mediaSel__item.is-active .mediaSel__item-sub { color: var(--fg-dim); }
.mediaSel__item.is-active::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.42rem;
  bottom: 0.42rem;
  width: 2px;
  border-radius: 1px;
  background: var(--accent);
  box-shadow: 0 0 10px var(--accent-glow);
}

/* ============================================================
   Detail panel (right half)
   ------------------------------------------------------------
   | Variable            | Controls                              |
   |---------------------|---------------------------------------|
   | --preview-max-h     | max height of the preview graphic     |
   | --preview-gap       | gap between graphic and its stroke    |
   | --preview-radius    | corner radius of the preview frame    |
   | --preview-stroke-w  | thickness of the gradient stroke      |
   | --preview-stroke    | the gradient used for the stroke      |
   | --media-aspect      | fallback aspect ratio for videos      |
   | --blurb-lines       | body lines shown before clamp + fade  |
   | --cta-fill-from/to  | Read-more button gradient fill        |
   | --cta-border        | Read-more button solid border color   |
   | --detail-persp      | 3D perspective depth of the container |
   | --detail-tilt-y     | container Y-rotation (main tilt)      |
   | --detail-tilt-x     | container X-rotation (slight lean)    |
   | --detail-pad-y      | top/bottom padding of the container   |
   | --detail-fade       | right→left fade fill (bright at right)|
   | --detail-fade-stop  | where the fade reaches transparent    |
   | --detail-bleed      | how far the fill bleeds past the right|
   ============================================================ */
.media__detail {
  --preview-max-h: 440px;
  --preview-gap: 10px;
  --preview-radius: 18px;
  --preview-stroke-w: 1px;
  --preview-stroke: linear-gradient(150deg, rgba(255, 255, 255, 0.55), rgba(255, 255, 255, 0.06) 52%, rgba(255, 255, 255, 0.28));
  --media-aspect: 16 / 9;
  --blurb-lines: 4;
  --cta-fill-from: #2b2b2b;
  --cta-fill-to: #141414;
  --cta-border: rgba(255, 255, 255, 0.22);
  --detail-persp: 1500px;
  --detail-tilt-y: -9deg;
  --detail-tilt-x: 2deg;
  --detail-pad-y: 2.75rem;

  position: relative;
  display: grid;
  grid-template-columns: 1fr minmax(280px, 46%);
  gap: clamp(1.5rem, 3vw, 3rem);
  align-items: center;
  min-height: 340px;
  padding: var(--detail-pad-y) 0;
  /* rotate the whole display in 3D (self-perspective keeps it isolated) */
  transform: perspective(var(--detail-persp)) rotateX(var(--detail-tilt-x)) rotateY(var(--detail-tilt-y));
  transform-style: preserve-3d;
  transition: opacity 0.25s ease;
}
.media__detail.is-swapping { opacity: 0; }

.media__detail-title {
  font-family: var(--font-head);
  font-weight: 700;
  font-size: var(--step-2);
  line-height: 1.1;
  color: var(--accent-mid);
  margin-bottom: 1rem;
}

/* body copy: clamped to a few lines and faded out at the bottom */
.media__detail-blurb {
  color: var(--fg-dim);
  max-width: 46ch;
  margin-bottom: 1.6rem;
  display: -webkit-box;
  -webkit-line-clamp: var(--blurb-lines);
  -webkit-box-orient: vertical;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(180deg, #000 45%, transparent);
          mask-image: linear-gradient(180deg, #000 45%, transparent);
}
/* no Read-More button → the clamp + fade have nothing to "read more" into,
   so drop them and show the whole blurb */
.media__detail-blurb--full {
  display: block;
  overflow: visible;
  -webkit-line-clamp: none;
  -webkit-mask-image: none;
          mask-image: none;
}

/* ---- layout modes (set from JS on .media__detail) ----
   is-stacked      : title but no blurb → title centred ABOVE the graphic
   is-graphic-only : no title, no blurb → just the graphic, centred */
.media__detail.is-stacked,
.media__detail.is-graphic-only {
  grid-template-columns: 1fr;
  justify-items: center;
  text-align: center;
}
/* tighten the title→graphic gap in stacked mode.
   the grid row-gap is the whole gap here, so the title's own margin is
   zeroed to avoid stacking two gaps on top of each other. */
.media__detail.is-stacked {
  --stacked-gap: 1rem;
  gap: var(--stacked-gap);
}
.media__detail.is-stacked .media__detail-title { margin-bottom: 0; }
/* full-width single column: size the video by HEIGHT so aspect-ratio gives a
   definite width. A percentage width here would resolve against the
   fit-content .media__preview parent (circular) and collapse to the embed's
   intrinsic size — iframes to ~300px, <video poster> to the poster's width. */
.media__detail.is-stacked .media__video,
.media__detail.is-graphic-only .media__video {
  height: var(--preview-max-h);
  width: auto;
  max-width: 100%;
}

/* Read-more button: gradient fill + solid border, centred under the text */
.media__cta {
  display: flex;
  width: fit-content;
  margin: 1.6rem auto 0;         /* auto margins centre it in the text column */
  align-items: center;
  gap: 0.5rem;
  padding: 0.8rem 1.6rem;
  border-radius: var(--r-pill);
  border: 1px solid var(--cta-border);
  background: linear-gradient(90deg, var(--cta-fill-from), var(--cta-fill-to));
  font-family: inherit;
  font-size: var(--step--1);
  font-weight: 600;
  color: var(--fg);
  cursor: pointer;
  transition: border-color 0.2s ease, filter 0.2s ease, transform 0.1s ease;
}
.media__cta:hover { border-color: var(--accent); filter: brightness(1.18); }
.media__cta:active { transform: translateY(1px); }

/* ---- preview graphic + its container ---- */
/* container hugs the graphic, adds a gap, and draws a gradient stroke */
.media__preview {
  position: relative;
  width: fit-content;
  max-width: 100%;
  margin-inline: auto;
  padding: var(--preview-gap);
  border-radius: var(--preview-radius);
  background: var(--bg-elev);
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.5);
}
.media__preview::before {          /* gradient stroke via masked border */
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: var(--preview-stroke-w);
  background: var(--preview-stroke);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
  pointer-events: none;
}

/* image: height capped, width follows its own aspect ratio */
.media__media {
  display: block;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: var(--preview-max-h);
  border-radius: calc(var(--preview-radius) - var(--preview-gap));
  object-fit: contain;
}
/* video: height fixed, width derived from --media-aspect (no JS) */
.media__video {
  height: var(--preview-max-h);
  width: auto;
  aspect-ratio: var(--media-aspect);
  max-width: 100%;
  border-radius: calc(var(--preview-radius) - var(--preview-gap));
  overflow: hidden;
}
.media__video iframe,
.media__video video {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
  object-fit: cover;
  background: #000;
}

/* ============================================================
   Read-more overlay
   ============================================================ */
body.media-overlay-open { overflow: hidden; }

.media-overlay {
  /* defined here (not on .media__detail) because the overlay is a direct
     child of <body>, so it can't inherit the detail-scoped variable */
  --overlay-bg: rgba(0, 0, 0, 0.9);

  position: fixed;
  inset: 0;
  z-index: var(--z-overlay);
  display: flex;
  background: var(--overlay-bg);
  opacity: 0;
  transition: opacity 0.32s ease;
}
/* class display:flex would otherwise override [hidden] and leave the
   invisible overlay covering the page, eating every click */
.media-overlay[hidden] { display: none; }
/* don't intercept clicks until it's actually open (covers the close fade) */
.media-overlay:not(.is-open) { pointer-events: none; }
.media-overlay.is-open { opacity: 1; pointer-events: auto; }
.media-overlay__backdrop { position: absolute; inset: 0; }

.media-overlay__scroll {
  position: relative;
  flex: 1;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  display: flex;
  justify-content: center;
  padding: clamp(1rem, 4vw, 3rem);
}
.media-overlay__img {
  align-self: flex-start;
  width: min(920px, 100%);
  height: auto;
  border-radius: var(--r-md);
  /* scale + fade in when the overlay opens */
  transform: scale(0.92);
  opacity: 0;
  transition: transform 0.34s var(--ease-out), opacity 0.34s ease;
}
.media-overlay.is-open .media-overlay__img { transform: scale(1); opacity: 1; }

/* matches .wib-overlay__close (What I Build overlay) exactly; kept
   position:fixed since the media overlay has no top bar to sit in */
.media-overlay__close {
  position: fixed;
  top: 18px;
  right: 18px;
  z-index: 1;
  flex: 0 0 auto;
  width: 40px; height: 40px;
  display: grid; place-items: center;
  border-radius: 50%;
  border: 1px solid var(--border);
  color: var(--fg-dim);
  cursor: pointer;
  transition: color 0.2s ease, border-color 0.2s ease;
}
.media-overlay__close:hover { color: var(--fg); border-color: var(--border-strong); }
.media-overlay__close svg { width: 14px; height: 14px; }

@media (max-width: 900px) {
  .media__body { grid-template-columns: 1fr; }
  .mediaSel { --sel-tilt-y: -5deg; --sel-tilt-x: 2deg; padding: 24px 34px 28px 12px; }
  .media__detail { grid-template-columns: 1fr; --preview-max-h: 320px; }
}

@media (prefers-reduced-motion: reduce) {
  .media-overlay, .media-overlay__img { transition: none; }
}
