/* The wall. A salon hang, not a product grid.

   Sizes and rotations are set on each frame by the generator, so the layout is
   settled before a single byte of art arrives and nothing shifts as it does.
   The rules here only say how a frame looks; which frame gets which piece is
   assets/gallery.js.

   Focus is the thing that must never be covered. Frames lean on each other by
   a few pixels, so any frame that takes focus or hover is lifted above its
   neighbours, and the caption is always on the page rather than behind a
   hover state. */

/* ---------- the room ---------- */
.room{
  background:
    radial-gradient(120% 70% at 50% -10%, rgba(201,168,76,.10), transparent 62%),
    radial-gradient(80% 50% at 50% 110%, rgba(201,168,76,.05), transparent 60%),
    var(--bg);
  border-top:1px solid var(--border);
  border-bottom:1px solid var(--border);
  padding-block:clamp(34px,5vw,64px);
}
.room .wrap{position:relative}

/* ---------- the hang ---------- */
.hang{
  display:grid;
  grid-template-columns:repeat(16,minmax(0,1fr));
  gap:clamp(14px,2.2vw,30px);
  align-items:start;
  padding-block:6px;
}

.fr{
  grid-column:span var(--span,4);
  margin-top:var(--drop,0px);
  transform:rotate(var(--rot,0deg));
  transform-origin:50% 12%;
  transition:transform .28s var(--ease), filter .28s var(--ease);
  min-width:0;
}
/* a frame that is being read comes forward and straightens up */
.fr:hover,.fr:focus-within{transform:rotate(0deg) translateY(-4px);z-index:5}
.fr:focus-within{z-index:9}

.fr-link{display:grid;gap:9px}

/* the picture itself. aspect-ratio reserves the box, so art fades into a
   space that was already the right shape */
.fr-art{
  position:relative;display:grid;place-items:center;overflow:hidden;
  aspect-ratio:var(--ar,1);
  background:linear-gradient(160deg,var(--bg3),var(--bg2));
  border:1px solid var(--border-m);
  border-radius:var(--r);
  box-shadow:0 1px 0 rgba(255,255,255,.05) inset,
             0 10px 26px -14px rgba(0,0,0,.9),
             0 2px 6px -3px rgba(0,0,0,.7);
}
.fr-art::after{      /* gallery light: a soft wash from the top-left */
  content:'';position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(150deg,rgba(255,255,255,.06),transparent 42%);
}
/* the picture is in the frame from the start so lazy loading works, but it is
   only shown once it has loaded — a gateway that never answers leaves the
   plaque exactly where it was */
.fr-art img,.fr-art video{width:100%;height:100%;object-fit:cover;position:absolute;inset:0;
  opacity:0;transition:opacity .45s var(--ease)}
.fr-art.has-art img,.fr-art.has-art video{opacity:1}
.fr-art.has-art{border-color:var(--border-s)}
.fr-art.has-art .fr-plaque{opacity:0}

/* what a frame says before any art arrives — and what it falls back to */
.fr-plaque{
  display:grid;gap:6px;place-items:center;text-align:center;padding:14px;
  transition:opacity .3s var(--ease);
}
.fr-plaque b{font-family:var(--serif);font-weight:300;font-size:clamp(15px,1.6vw,21px);
  line-height:1.15;color:var(--text-2)}
.fr-plaque i{font-family:var(--mono);font-style:normal;font-size:10px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--text-3)}

.fr-cap{display:grid;gap:3px;padding-inline:2px}
.fr-name{font-family:var(--serif);font-size:clamp(14px,1.5vw,18px);font-weight:300;
  line-height:1.2;color:var(--text);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fr-coll{font-family:var(--mono);font-size:10.5px;letter-spacing:.13em;text-transform:uppercase;
  color:var(--text-3);transition:color .2s}
.fr-link:hover .fr-coll,.fr-link:focus-visible .fr-coll{color:var(--gold)}

/* ---------- the wall's own words ---------- */
/* The wall's label. On the gallery it sits above the hang, where a visitor
   reads it before scrolling six thousand pixels of art — which is the whole
   point of telling them a collection did not answer. */
.wall-bar{display:flex;flex-wrap:wrap;align-items:center;gap:14px 20px;
  margin-top:clamp(22px,3vw,34px)}
.wall-bar.top{margin-top:0;margin-bottom:clamp(20px,2.6vw,30px);
  padding-bottom:16px;border-bottom:1px solid var(--border)}
.wall-note{font-family:var(--mono);font-size:11.5px;letter-spacing:.1em;color:var(--text-3);
  margin-right:auto}

/* ---------- tablet ---------- */
@media (max-width:900px){
  .hang{grid-template-columns:repeat(6,minmax(0,1fr));gap:16px}
  .fr{grid-column:span var(--span-m,3)}
}

/* ---------- phone ----------
   Not the desktop collage shrunk down. Two columns, gentler tilts, no drop
   offsets, captions on their own line: the same room, hung for a small wall. */
@media (max-width:560px){
  .hang{grid-template-columns:repeat(4,minmax(0,1fr));gap:12px}
  .fr{grid-column:span var(--span-s,2);margin-top:0;
      transform:rotate(calc(var(--rot,0deg) * .45))}
  .fr-art{box-shadow:0 6px 16px -10px rgba(0,0,0,.9)}
  .fr-name{font-size:14px;white-space:normal}
  .wall-note{margin-right:0;width:100%}
}

/* ---------- homepage preview ---------- */
.peek .hang{gap:clamp(12px,1.8vw,22px)}
.peek .fr-cap{gap:2px}
.peek .fr-name{font-size:clamp(13px,1.1vw,15px)}
.peek .fr-coll{font-size:10px}
.peek-head{display:grid;gap:10px;max-width:52ch;margin-bottom:clamp(20px,3vw,30px)}

/* ---------- reduced motion ----------
   Rotation is decoration. Someone who has asked for less movement gets a
   straight, still wall — the art, the captions and the controls are all
   unchanged. */
@media (prefers-reduced-motion:reduce){
  .fr,.fr:hover,.fr:focus-within{transform:none;transition:none}
  .fr-art img,.fr-art video{transition:none}
  .fr-plaque{transition:none}
  html{scroll-behavior:auto}
}
