/* ===========================================================================
   ONE RAID STUDIO — portfolio.css
   Only what is unique to the portfolio page. Shared layout lives in base.css.
   =========================================================================== */

.page-head::before{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:
    radial-gradient(54% 62% at 78% 16%,rgba(0,229,255,.1),transparent 70%),
    radial-gradient(50% 56% at 20% 24%,rgba(199,41,65,.2),transparent 72%);
}

.gallery-wrap{padding-block:0 var(--sec-y)}
.gallery-wrap .wrap{display:flex;flex-direction:column;gap:var(--sp-5)}

/* ------------------------------------------------------------- filters */
.filters{display:flex;flex-wrap:wrap;gap:10px;align-items:center}
.filter{
  display:inline-flex;align-items:center;min-height:var(--tap);
  padding:10px 16px;
  font-family:var(--mono);font-size:var(--fs-label);letter-spacing:.1em;text-transform:uppercase;
  color:var(--text-muted);background:var(--surface);
  border:2px solid var(--border);box-shadow:var(--sh-1);cursor:pointer;
  transition:color var(--dur-fast) var(--ease),border-color var(--dur-fast) var(--ease),
             transform var(--dur-fast) var(--ease),box-shadow var(--dur-fast) var(--ease);
}
.filter:hover{color:var(--text);border-color:var(--neon-red)}
.filter:active{transform:translate(2px,2px);box-shadow:1px 1px 0 var(--maroon)}
.filter.is-on{background:var(--brand-red-lit);color:var(--white);border-color:var(--neon-red);box-shadow:var(--sh-1),var(--glow-sm)}
.filters__count{
  font-family:var(--mono);font-size:var(--fs-label);letter-spacing:.1em;
  text-transform:uppercase;color:var(--text-dim);
}

/* -------------------------------------------------------- GALLERY GRID
   Card sizes are set per item with data-span="COLUMNSxROWS", e.g.

       <figure class="shot" data-cat="models" data-span="2x1">   wide
       <figure class="shot" data-cat="pixel"  data-span="1x2">   tall
       <figure class="shot" data-cat="models" data-span="2x2">   big

   1, 2 and 3 work on either axis; omit the attribute entirely for 1x1.
   Row height is set to the resolved column width by portfolio.js, so 1x1
   is square, 2x1 is 2:1, 1x2 is 1:2, and so on. Spans clamp down on their
   own as the column count drops on smaller screens.                      */
.gallery{
  --cols:3;
  display:grid;
  grid-template-columns:repeat(var(--cols),minmax(0,1fr));
  grid-auto-rows:var(--row,240px);
  grid-auto-flow:dense;
  gap:var(--sp-4);
}
.shot[data-span^="2"]{grid-column:span 2}
.shot[data-span^="3"]{grid-column:span 3}
.shot[data-span$="2"]{grid-row:span 2}
.shot[data-span$="3"]{grid-row:span 3}

.shot{
  position:relative;margin:0;overflow:hidden;
  border:2px solid var(--border);box-shadow:var(--sh-2);background:var(--surface-2);
  transition:transform var(--dur) var(--ease),box-shadow var(--dur) var(--ease),border-color var(--dur) var(--ease);
}
.shot:hover{transform:translate(-2px,-2px);box-shadow:var(--sh-3);border-color:var(--neon-red)}
.shot:focus-within{border-color:var(--neon-cyan)}

/* the whole tile is one button, so it opens on click, Enter and Space */
.shot__btn{
  display:block;position:absolute;inset:0;width:100%;height:100%;
  padding:0;border:0;background:none;cursor:pointer;
}
.shot__btn img{width:100%;height:100%;object-fit:cover}
.shot__btn::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,transparent 55%,rgba(11,4,16,.55) 100%);
  opacity:0;transition:opacity var(--dur) var(--ease);
}
.shot:hover .shot__btn::after,
.shot__btn:focus-visible::after{opacity:1}

.shot figcaption{
  position:absolute;left:8px;bottom:8px;pointer-events:none;
  font-family:var(--mono);font-size:.62rem;letter-spacing:.1em;text-transform:uppercase;
  color:var(--text);background:rgba(11,4,16,.88);border:1px solid var(--border);padding:5px 8px;
}
.shot__zoom{
  position:absolute;right:8px;bottom:8px;pointer-events:none;
  font-family:var(--mono);font-size:.6rem;letter-spacing:.1em;text-transform:uppercase;
  color:var(--neon-cyan);background:rgba(11,4,16,.88);border:1px solid var(--neon-cyan);padding:5px 8px;
  opacity:0;transform:translateY(4px);
  transition:opacity var(--dur) var(--ease),transform var(--dur) var(--ease);
}
.shot:hover .shot__zoom,
.shot__btn:focus-visible ~ .shot__zoom{opacity:1;transform:none}

/* Every tile is a studio sample, not a named client commission. The flag says
   so on the tile itself so the claim is never implied by omission. */
.shot__flag{
  position:absolute;left:8px;top:8px;z-index:1;pointer-events:none;
  font-family:var(--mono);font-weight:700;font-size:.58rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--white);
  background:var(--brand-red-deep);border:1px solid var(--neon-red);padding:4px 7px;
}

/* Filtering is driven by portfolio.js, which flags non-matching tiles with
   data-hidden. This single rule covers every category — previously each one
   needed its own selector pair here, so a new filter button silently did
   nothing until this block was edited too. */
.shot[data-hidden]{display:none}

.gallery__empty{
  grid-column:1 / -1;padding:var(--sp-8) var(--sp-5);text-align:center;
  border:2px dashed var(--border);
  font-family:var(--mono);font-size:var(--fs-label);letter-spacing:.1em;
  text-transform:uppercase;color:var(--text-dim);
}

/* ----------------------------------------------------------- LIGHTBOX */
/* flex centring, not `display:block` + auto margins — the panel was pinned to
   the top of the viewport. The backdrop is absolutely positioned, so it stays
   out of flow and still covers the full screen behind the centred panel. */
.lightbox{
  position:fixed;inset:0;z-index:9600;
  display:none;align-items:center;justify-content:center;
  padding:var(--gutter);
}
.lightbox.is-open{display:flex}
.lightbox__backdrop{position:absolute;inset:0;background:rgba(5,2,8,.9);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px)}
.lightbox__panel{
  position:relative;
  display:flex;flex-direction:column;
  width:min(1000px,100%);
  max-height:100%;
  background:var(--surface);border:2px solid var(--border);
  box-shadow:var(--sh-3);
  overscroll-behavior:contain;overflow:auto;
}
.lightbox__media{
  position:relative;flex:0 0 auto;
  aspect-ratio:4/3;max-height:60dvh;
  background:var(--surface-2);border-bottom:2px solid var(--border);
}
.lightbox__media img{width:100%;height:100%;object-fit:contain}
.lightbox__body{display:flex;flex-direction:column;gap:var(--sp-3);padding:var(--sp-5)}
.lightbox__desc{max-width:70ch;font-size:var(--fs-sm);line-height:1.6;color:var(--text-muted)}
.lightbox__meta{display:flex;flex-wrap:wrap;gap:var(--sp-3);align-items:center}

.lightbox__close{
  position:absolute;top:8px;right:8px;z-index:2;
  width:var(--tap);height:var(--tap);
  background:var(--surface-2);border:2px solid var(--border);box-shadow:var(--sh-1);
  color:var(--neon-red);font-family:var(--mono);font-size:1.1rem;cursor:pointer;
}
.lightbox__close:hover{border-color:var(--neon-red)}
.lightbox__nav{
  position:absolute;top:50%;transform:translateY(-50%);z-index:2;
  width:var(--tap);height:var(--tap);
  background:rgba(11,4,16,.82);border:2px solid var(--border);box-shadow:var(--sh-1);
  color:var(--text);font-family:var(--mono);font-size:1.2rem;cursor:pointer;
}
.lightbox__nav:hover{border-color:var(--neon-cyan);color:var(--white)}
.lightbox__nav--prev{left:8px}
.lightbox__nav--next{right:8px}
.lightbox__counter{
  font-family:var(--mono);font-size:var(--fs-label);letter-spacing:.1em;
  text-transform:uppercase;color:var(--text-dim);
}

/* ---------------------------------------------------------- RESPONSIVE */
@media (max-width:900px){
  .gallery{--cols:2}
  .shot[data-span^="3"]{grid-column:span 2}
}
@media (max-width:560px){
  .gallery{--cols:1}
  .shot[data-span^="2"],.shot[data-span^="3"]{grid-column:span 1}
  .shot[data-span$="2"],.shot[data-span$="3"]{grid-row:span 1}
  .lightbox__media{max-height:42dvh}
}
