/* ============================================================================
   VEIL & THORN — GALLERY PAGE
   ----------------------------------------------------------------------------
   Loaded only by gallery.html, so the home page doesn't pay for it.

   The wall reuses .piece / .plate / .badge from components.css — same stencil
   -to-ink cure, same plate treatment — and overrides only what has to change:
   the grid becomes masonry columns, and plates take their natural height so
   photographs aren't cropped to a shape they weren't shot in.
   ========================================================================= */

/* ----------------------------------------------------------------------------
   Page head
   ------------------------------------------------------------------------- */

.gal-head{padding:clamp(120px,17vh,190px) var(--pad) clamp(28px,4vw,46px)}
.gal-head .h-xl{margin:0 0 20px; max-width:12ch}
.gal-head .lede{margin:0}

/* Sticks just under the fixed nav — the two are separate bars, so the offset
   has to match the nav's height rather than sitting at 0 and hiding behind it. */
.gal-bar{
  position:sticky; top:66px; z-index:6000;
  display:flex; flex-wrap:wrap; gap:14px 20px; align-items:center; justify-content:space-between;
  padding:14px var(--pad);
  background:rgba(11,10,12,.9); backdrop-filter:blur(14px);
  border-top:var(--rule); border-bottom:var(--rule);
}
@media(max-width:420px){ .gal-bar{top:64px} }
.chips{display:flex; flex-wrap:wrap; gap:8px; margin:0; padding:0; list-style:none}
.chip{
  cursor:pointer; background:transparent; border:1px solid rgba(253,194,219,.28);
  padding:8px 15px; color:var(--bone-soft);
  font-family:var(--data); font-size:11px; letter-spacing:.16em; text-transform:uppercase;
  transition:color .25s, border-color .25s, background .25s;
}
.chip:hover{color:var(--pink); border-color:var(--pink)}
.chip.is-on{background:var(--pink); border-color:var(--pink); color:var(--ink); font-weight:700}
.gal-bar .small{white-space:nowrap; margin:0}

/* ----------------------------------------------------------------------------
   The wall
   ----------------------------------------------------------------------------
   A plain grid of identical 4/5 cards rather than masonry. These are phone
   photographs of arms and backs, shot at whatever angle the chair allowed —
   left at their natural sizes the wall reads as a scrapbook. One shape makes
   it read as a body of work, and the lightbox still shows every photo whole
   and uncropped, so nothing is actually lost.

   A grid also reads left-to-right. Masonry columns run top-to-bottom, which
   silently scrambles the order you put pieces in.
   ------------------------------------------------------------------------- */
.shots{
  padding:clamp(28px,4vw,56px) var(--pad) clamp(60px,8vw,110px);
  display:grid; gap:clamp(18px,2.4vw,34px);
  grid-template-columns:repeat(3, 1fr);
  align-items:start;
}
@media(max-width:1000px){ .shots{grid-template-columns:repeat(2, 1fr)} }
@media(max-width:600px){  .shots{grid-template-columns:1fr} }

/* .piece is borrowed from the home page's 12-column grid and carries a
   `grid-column: span 4` with it. This is a 3-column grid, so that has to go or
   every card claims a whole row. */
.shot{margin:0; grid-column:auto}
.shot[hidden]{display:none}

.shot__btn{
  display:block; width:100%; padding:0; margin:0;
  background:none; border:0; cursor:pointer; text-align:left;
}

.shots .plate{transition:transform .5s cubic-bezier(.2,.8,.2,1)}
.shots .plate--art{padding:9%}
.shot__btn:hover .plate{transform:scale(1.02)}
.shot__btn:focus-visible{outline:2px solid var(--pink); outline-offset:4px}

/* A quiet "open me" hint, mouse only — touch users get it by tapping. */
.shot__btn .plate::before{
  content:"View"; position:absolute; z-index:4; right:0; bottom:0;
  padding:7px 12px; background:var(--ink); color:var(--bone);
  font-family:var(--data); font-size:10px; letter-spacing:.18em; text-transform:uppercase;
  opacity:0; transform:translateY(6px); transition:opacity .3s, transform .3s;
}
.shot__btn:hover .plate::before,
.shot__btn:focus-visible .plate::before{opacity:1; transform:none}
@media(hover:none){ .shot__btn .plate::before{display:none} }

/* Marks a cover-up that carries a before photo. Sits opposite the style badge
   rather than under it, so the two never stack up in the same corner. */
.badge--ba{
  left:auto; right:0;
  background:var(--pink); color:var(--ink); font-weight:700;
}

.shots__empty{padding:40px 0; color:var(--bone-soft)}

/* ----------------------------------------------------------------------------
   Lightbox
   ------------------------------------------------------------------------- */
body.lb-open{overflow:hidden}

.lb{
  position:fixed; inset:0; z-index:9600;
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:clamp(14px,2vh,26px); padding:clamp(56px,9vh,86px) clamp(16px,7vw,110px);
  background:rgba(6,5,7,.94); backdrop-filter:blur(10px);
  animation:lbIn .28s ease;
}
.lb[hidden]{display:none}
@keyframes lbIn{from{opacity:0} to{opacity:1}}

.lb__figure{
  margin:0; display:flex; flex-direction:column; align-items:center;
  gap:clamp(12px,2vh,20px); max-width:100%; min-height:0;
}
/* The stage borrows .plate for its skin/paper backing, so the fixed 4/5 crop
   and inner padding both have to come back off. It shrink-wraps whatever is
   inside it, so the backing never extends past the piece. */
.lb__stage{
  position:relative; overflow:hidden; display:grid; place-items:center;
  aspect-ratio:auto; padding:0; max-width:min(880px,92vw);
}
.lb__stage img{
  position:static; width:auto; height:auto;
  max-width:min(880px,92vw); max-height:62vh; object-fit:contain;
}
/* An SVG carries an aspect ratio but no intrinsic size, so it needs a definite
   height to size from — width:auto then follows the viewBox. Without this the
   whole stage collapses to a thumbnail. */
.lb__stage svg{height:min(62vh,680px); width:auto; max-width:min(860px,88vw)}
.lb__stage.plate--art{padding:clamp(14px,3vw,34px)}

/* Full black linework straight away — the lightbox is for looking at the piece,
   not for watching it draw itself on again. The dash properties have to be
   undone explicitly: components.css hides the strokes with them until a piece
   is inked, and nothing here would put them back otherwise. */
.lb__stage svg [data-ink],
.lb__stage svg [data-red]{
  fill:none; stroke:var(--ink-line); stroke-width:3.6;
  stroke-linecap:round; stroke-linejoin:round;
  stroke-dasharray:none; stroke-dashoffset:0; transition:none;
}
.lb__stage svg [data-red]{stroke-width:3; opacity:.6}
.lb__stage svg [data-fill]{fill:var(--ink-line); stroke:none; opacity:1; transition:none}

/* ----------------------------------------------------------------------------
   Before and after
   ----------------------------------------------------------------------------
   The finished piece is the element in flow, so it sizes the stage exactly as
   an ordinary photo would. The before photo is laid over the top of it and
   faded in and out.

   `contain` on the before, not `cover`: the two shots won't share an aspect
   ratio — different day, different phone, different distance — and cropping
   one to fit the other would cut the old tattoo in half, which is the thing
   being shown. It letterboxes against black instead, which reads as
   deliberate against a black lightbox.
   ------------------------------------------------------------------------- */
.cmp{position:relative; line-height:0; cursor:pointer}
.cmp img{display:block}
/* Set when the before photo turned out not to be on the server. */
.cmp--solo{cursor:default}

/* Qualified by .lb__stage on purpose: `.lb__stage img` above sets position and
   sizing, and a bare `.cmp__before` would lose to it on specificity no matter
   where it sat in the file. */
.lb__stage .cmp__before{
  position:absolute; inset:0;
  width:100%; height:100%;
  max-width:none; max-height:none;             /* undo the .lb__stage img sizing */
  object-fit:contain; background:var(--ink);
  opacity:0; transition:opacity .32s ease;
}
.cmp[data-showing="before"] .cmp__before{opacity:1}

.lb__compare{
  display:flex; flex-wrap:wrap; align-items:center; justify-content:center;
  gap:10px 16px;
}
.lb__compare[hidden]{display:none}

.cmp__switch{display:flex; gap:8px}
/* The chips are the filter chips from the bar above, so the two controls on
   this page that switch between things look like each other. */
.cmp__switch .chip{padding:7px 18px}

.cmp__hint{margin:0; color:var(--bone-soft); opacity:.75}
/* Nothing to tap on a mouse, and the buttons are right there. */
@media(hover:hover){ .cmp__hint{display:none} }

.lb__cap{text-align:center; max-width:58ch}
.lb__cap .eyebrow{margin:0 0 8px}
.lb__cap .h-md{margin:0 0 6px}
.lb__cap .small{margin:0}

.lb__count{position:absolute; left:50%; bottom:clamp(16px,3vh,30px); transform:translateX(-50%); margin:0}

.lb__close,.lb__nav{
  position:absolute; z-index:2; cursor:pointer;
  background:transparent; border:1px solid rgba(253,194,219,.3); color:var(--bone);
  transition:border-color .25s, color .25s, background .25s;
}
.lb__close:hover,.lb__nav:hover{border-color:var(--pink); color:var(--pink); background:rgba(253,194,219,.08)}

.lb__close{
  top:clamp(14px,3vh,26px); right:clamp(14px,4vw,34px);
  width:44px; height:44px; font-size:22px; line-height:1;
}
.lb__nav{
  top:50%; transform:translateY(-50%); width:48px; height:66px;
  display:grid; place-items:center;
}
.lb__nav::before{
  content:""; width:13px; height:13px;
  border-top:1.5px solid currentColor; border-right:1.5px solid currentColor;
}
.lb__nav--prev{left:clamp(10px,2.4vw,30px)}
.lb__nav--prev::before{transform:rotate(-135deg); margin-left:5px}
.lb__nav--next{right:clamp(10px,2.4vw,30px)}
.lb__nav--next::before{transform:rotate(45deg); margin-right:5px}

/* On a phone the arrows drop to the bottom corners, where a thumb actually
   reaches, and the piece gives up the height they need. */
@media(max-width:640px){
  .lb{padding:70px 12px 66px}
  .lb__nav{top:auto; bottom:14px; transform:none; width:44px; height:44px}
  .lb__stage img{max-height:46vh}
  .lb__stage svg{height:min(46vh,420px)}
}

/* ----------------------------------------------------------------------------
   Closing call to action
   ------------------------------------------------------------------------- */
.gal-cta{
  border-top:var(--rule); padding:clamp(56px,7vw,100px) var(--pad);
  text-align:center; background:linear-gradient(180deg, rgba(253,194,219,.045), transparent);
}
.gal-cta .h-lg{margin:0 0 16px}
.gal-cta p{margin:0 auto 28px; max-width:54ch; color:var(--bone-soft)}
.gal-cta .btns{justify-content:center}

@media (prefers-reduced-motion: reduce){
  .lb{animation:none}
  .shot__btn:hover .plate{transform:none}
  /* The swap still happens — it just happens at once instead of dissolving. */
  .lb__stage .cmp__before{transition:none}
}
