/* ==========================================================
   Constellation & frieze
   ========================================================== */

.constellation{
  position:relative;
  width:100%;
  aspect-ratio:16/9;
  min-height:420px;
  margin:0;
  isolation:isolate;
}

/* ---- edges ------------------------------------------------ */
.constellation svg.edges{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  z-index:1;
  pointer-events:none;
  overflow:visible;
}
.constellation .edge{
  fill:none;
  stroke:var(--terracotta,#a8492e);
  stroke-width:1;
  vector-effect:non-scaling-stroke;
  opacity:.20;
  stroke-dasharray:var(--len,300);
  stroke-dashoffset:var(--len,300);
  transition:opacity .45s ease, stroke-width .45s ease;
}
.constellation.drawn .edge{
  animation:edge-draw 1.6s cubic-bezier(.3,.7,.2,1) forwards;
  animation-delay:calc(var(--i,0) * 55ms);
}
@keyframes edge-draw{ to{ stroke-dashoffset:0 } }
.constellation .edge.hot{opacity:.85;stroke-width:1.8}
.constellation .edge.cold{opacity:.05}

/* ---- nodes ------------------------------------------------ */
.constellation figure {
  position: absolute;
  margin: 0;
  z-index: 2;
  width: var(--w, 13%);
  left: calc(var(--x, 50) * 1%);
  top: calc(var(--y, 50) * 1%);
  transform: translate(-50%, -50%) scale(.72);
  opacity: 0;
  transition:
    opacity .7s ease,
    transform .8s cubic-bezier(.2,.8,.2,1),
    filter .4s ease;
  transition-delay: calc(var(--i, 0) * 90ms);
  cursor: pointer;
}
.constellation.drawn figure{opacity:1;transform:translate(-50%,-50%) scale(1)}

.constellation .node-media{
  position:relative;
  display:block;
  width:100%;
  aspect-ratio:1;
  border-radius:50%;
  overflow:hidden;
  background:var(--paper-deep,#ebe1d0);
  box-shadow:0 10px 30px rgba(58,36,22,.22), 0 0 0 1px rgba(127,52,35,.35);
  transition:box-shadow .4s ease, transform .5s cubic-bezier(.2,.8,.2,1);
}
/* Some nodes are not round. A graph of mixed things should look mixed. */
.constellation figure.sq .node-media{border-radius:4px;aspect-ratio:4/5}
.constellation figure.arch .node-media{border-radius:50% 50% 6px 6px / 32% 32% 6px 6px;aspect-ratio:3/4}

.constellation img{
  width:100%;height:100%;
  object-fit:cover;
  display:block;
  filter:saturate(1.1) contrast(1.04) hue-rotate(-4deg);
  transition:filter .45s ease, transform 3s ease;
}
.constellation figure:hover .node-media,
.constellation figure:focus-visible .node-media{
  transform:scale(1.09);
  box-shadow:0 18px 46px rgba(58,36,22,.34), 0 0 0 2px var(--terracotta,#a8492e);
}
.constellation figure:hover img{transform:scale(1.06)}
.constellation.has-focus figure:not(.hot){filter:grayscale(.7) brightness(.86);opacity:.4}

/* the small terracotta pin that anchors each node to its edges */
.constellation .node-media::after{
  content:"";
  position:absolute;
  inset:auto 50% -7px auto;
  transform:translateX(50%);
  width:7px;height:7px;
  border-radius:50%;
  background:var(--terracotta,#a8492e);
  box-shadow:0 0 0 3px var(--paper-light,#fbf8f1);
}

.constellation figcaption{
  position:absolute;
  left:50%;
  top:calc(100% + 12px);
  transform:translateX(-50%);
  width:max-content;
  max-width:160px;
  text-align:center;
  font:400 .7rem/1.35 var(--sans);
  color:var(--muted,#655f56);
  opacity:0;
  transition:opacity .35s ease;
  pointer-events:none;
}
.constellation figure:hover figcaption,
.constellation figure:focus-visible figcaption{opacity:1}

/* idle drift — each node on its own slow orbit */
@media (prefers-reduced-motion:no-preference){
  .constellation.drawn figure{
    animation:drift var(--dur,17s) ease-in-out infinite;
    animation-delay:calc(var(--i,0) * -2.4s);
  }
  @keyframes drift{
    0%,100%{transform:translate(-50%,-50%) scale(1)}
    33%    {transform:translate(calc(-50% + 7px),calc(-50% - 9px)) scale(1)}
    66%    {transform:translate(calc(-50% - 6px),calc(-50% + 6px)) scale(1)}
  }
  .constellation figure:nth-child(3n)  {--dur:21s}
  .constellation figure:nth-child(4n)  {--dur:14s}
  .constellation figure:hover{animation-play-state:paused}
}

@media (max-width:900px){
  .constellation{aspect-ratio:4/5;min-height:520px}
  .constellation figure{width:var(--wm,22%)}
  .constellation figcaption{max-width:110px;font-size:.64rem}
}

/* ==========================================================
   THE FRIEZE
   A continuous band of images that never stops, like a
   frieze unrolling. Butted edge to edge, no gaps, no boxes.
   ========================================================== */

.frieze{
  position:relative;
  overflow:hidden;
  margin:0;
  border-block:1px solid var(--line,rgba(75,55,38,.18));
  background:var(--paper-deep,#ebe1d0);
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
}
.frieze-track{
  display:flex;
  width:max-content;
  animation:frieze-run 68s linear infinite;
}
.frieze figure{
  position:relative;
  margin:0;
  flex:none;
  width:clamp(180px,20vw,300px);
  height:clamp(150px,16vw,230px);
  overflow:hidden;
}
.frieze img{
  width:100%;height:100%;
  object-fit:cover;
  display:block;
  filter:saturate(1.05) contrast(1.03) hue-rotate(-4deg) brightness(.94);
  transition:filter .5s ease, transform .8s ease;
}
.frieze figure:hover img{filter:saturate(1.18) contrast(1.06) brightness(1.04);transform:scale(1.05)}
.frieze:hover .frieze-track{animation-play-state:paused}
@keyframes frieze-run{ from{transform:translateX(0)} to{transform:translateX(-50%)} }

.frieze figcaption{
  position:absolute;
  inset:auto 0 0 0;
  padding:26px 12px 10px;
  background:linear-gradient(180deg,rgba(38,25,18,0),rgba(38,25,18,.8));
  color:#f4e9db;
  font:400 .68rem/1.35 var(--sans);
  opacity:0;
  transition:opacity .35s ease;
}
.frieze figure:hover figcaption{opacity:1}

/* ==========================================================
   LIGHTBOX
   ========================================================== */

.lb[hidden]{display:none}
.lb{
  position:fixed;
  inset:0;
  z-index:950;
  display:grid;
  place-items:center;
  padding:5vh 5vw;
  background:rgba(26,18,13,.93);
  backdrop-filter:blur(4px);
  animation:lb-in .3s ease;
}
@keyframes lb-in{from{opacity:0}to{opacity:1}}
.lb img{
  max-width:100%;
  max-height:78vh;
  width:auto;height:auto;
  box-shadow:0 40px 90px rgba(0,0,0,.6);
  animation:lb-rise .45s cubic-bezier(.2,.8,.2,1);
}
@keyframes lb-rise{from{transform:translateY(18px) scale(.98);opacity:0}to{transform:none;opacity:1}}
.lb figcaption{
  margin-top:18px;
  max-width:64ch;
  text-align:center;
  font:400 .82rem/1.6 var(--sans);
  color:#d9c9b5;
}
.lb figcaption b{color:#f0c9a8;font-weight:600}
.lb-close{
  position:fixed;
  top:20px;right:24px;
  border:0;background:none;
  font:300 2.4rem/1 var(--sans);
  color:#e8dccb;
  cursor:pointer;
}
.lb-close:hover{color:#fff}

/* ==========================================================
   MOTION OFF
   ========================================================== */

@media (prefers-reduced-motion:reduce){
  .constellation figure{opacity:1;transform:translate(-50%,-50%);animation:none}
  .constellation .edge{stroke-dashoffset:0;animation:none}
  .frieze-track{animation:none;width:100%;overflow-x:auto}
  .lb,.lb img{animation:none}
}
html.a11y-motion .constellation figure{opacity:1 !important;animation:none !important;transform:translate(-50%,-50%) !important}
html.a11y-motion .constellation .edge{stroke-dashoffset:0 !important;animation:none !important}
html.a11y-motion .frieze-track{animation:none !important}
html.a11y-contrast .constellation.has-focus figure:not(.hot){filter:none;opacity:1}
html.a11y-contrast .constellation img,
html.a11y-contrast .frieze img{filter:none !important}
