/* ---------- sections ---------- */

.section{padding:7vh var(--edge)}
.section__title{margin-bottom:3.4vh;display:block}
.section__title,.pairgrid h2{
  font-size:clamp(.95rem,1.7vw,1.3rem);
  letter-spacing:.02em;
}

/* no rule and no doubled-up padding between the last project row and About —
   #projects already carries 7vh of its own bottom padding, so dropping this
   section's top padding leaves the same 7vh gap the hero has above Projects,
   instead of the two sections' padding stacking to 14vh */
#about{padding-top:0}

/* ---------- rows ---------- */

.rows{list-style:none}
.row{border-bottom:var(--rule-row) solid var(--fg)}
.row:first-child{border-top:var(--rule-row) solid var(--fg)}

.row__head, .rows__header{
  width:100%;
  display:grid;
  grid-template-columns:1fr 335px 60px;
  align-items:center;
  gap:20px;
}
.row__head{
  padding:11px 0;
  background:none;border:0;text-align:left;cursor:pointer;
  font:inherit;color:inherit;
}
.row__name{
  min-width:0;
  font-family:var(--display);
  font-weight:500;
  font-size:17px;
  line-height:1.15;letter-spacing:.01em;
  transition:opacity .18s ease;
}

.row__category{
  justify-self:start;
  text-align:left;
  white-space:nowrap;
  font-family:var(--display);
  font-weight:500;
  font-size:17px;
  line-height:1.15;letter-spacing:.01em;
  color:var(--muted);
}

.row__year{
  justify-self:end;
  font-family:var(--display);
  font-weight:500;
  font-size:17px;
  line-height:1.15;letter-spacing:.01em;
  color:var(--muted);
}

.rows__header{
  margin-bottom:11px;
}
.rows__header span{
  text-transform:uppercase;
}
.rows__header span:nth-child(2){justify-self:start;text-align:left}
.rows__header span:nth-child(3){justify-self:end;text-align:right}

.dot{
  flex:0 0 auto;width:9px;height:9px;border-radius:50%;
  background:var(--fg);
  transition:transform .22s ease, background .22s ease, box-shadow .22s ease;
}
.row__head:hover .dot{transform:scale(1.35)}
.row.open .dot{background:transparent;box-shadow:inset 0 0 0 2px var(--fg);transform:scale(1.35)}

/* panel colour is re-rolled on every open. the reveal (and the close, whether
   by hand or auto-closed on scroll) animates via the grid-rows trick, rather
   than an instant display:none/block cut */
.row__body{
  display:grid;
  grid-template-rows:0fr;
  overflow:hidden;
  margin-bottom:0;
  background:var(--panel);
  color:var(--panel-fg);
  transition:grid-template-rows .5s cubic-bezier(.65,0,.35,1), margin-bottom .5s cubic-bezier(.65,0,.35,1);
}
.row__body > .detail{
  min-height:0;
  padding:0 26px;
  transition:padding-block .5s cubic-bezier(.65,0,.35,1);
}
.row.open .row__body{
  grid-template-rows:1fr;
  --bg:var(--panel);
  --fg:var(--panel-fg);
  --muted:color-mix(in srgb, var(--panel-fg) 72%, var(--panel));
  --fill:color-mix(in srgb, var(--panel) 86%, var(--panel-fg));
  margin-bottom:16px;
}
.row.open .row__body > .detail{padding-block:26px}

/* used only for the auto-close that fires once a row is fully off-screen
   above the viewport: collapses in one frame instead of animating over .5s,
   so the browser's scroll-position compensation happens once instead of
   fighting the live scroll for half a second (which is what caused the
   stutter) — nothing is visible either way since the row is off-screen */
.row.row--instant .row__body,
.row.row--instant .row__body > .detail{
  transition:none !important;
}

.row__facts{
  display:flex;flex-wrap:wrap;gap:6px 28px;
  font-size:13px;letter-spacing:.05em;color:var(--muted);
  margin-bottom:20px;
}

/* hovering anything clickable borrows a colour from the project palette */
.row__head:hover .row__name,
.nav__link:hover,
.nav__mark:hover{
  color:var(--hov, var(--fg));
  opacity:1;
}

/* ---------- carousel ---------- */

.carousel{position:relative}
.carousel__stage{
  position:relative;background:var(--fill);
  aspect-ratio:4/3;overflow:hidden;
  cursor:grab;
  touch-action:pan-y;           /* swipe sideways here, scroll the page vertically */
  transition:aspect-ratio .25s ease;
}
.carousel__stage.is-portrait,
.carousel__stage.is-square{aspect-ratio:4/3}
.carousel__stage.is-portrait img,
.carousel__stage.is-square img{
  object-fit:contain;
  object-position:left center;
  background:var(--panel, var(--bg));
}
.carousel__stage.dragging{cursor:grabbing}
.carousel__slide img{
  user-select:none;
  -webkit-user-drag:none;
}
.carousel__slide{
  position:absolute;inset:0;
  opacity:0;transition:opacity .9s ease;
}
.carousel__slide.on{opacity:1}
.carousel__slide img{
  width:100%;height:100%;
  object-fit:cover;display:block;
}

.carousel__bar{
  display:flex;align-items:center;gap:12px;margin-top:9px;
  font-size:12px;letter-spacing:.05em;color:var(--muted);
}
.carousel__btn{
  font:inherit;font-size:14px;line-height:1;
  background:none;border:0;padding:4px 6px;cursor:pointer;color:var(--fg);
}
.carousel__btn:hover{opacity:.5}
.carousel__count{margin-left:auto}

/* the actual prev/next control now lives on the image itself (hover shows
   the shared cursor-dot "Previous"/"Next" label, split left/right) rather
   than as separate arrow buttons */

/* fullscreen toggle — a small indicator in the image's top-right corner,
   opens the image in the in-page lightbox below (not real browser
   fullscreen) */
.carousel__fullscreen{
  position:absolute;
  top:10px; right:10px;
  z-index:3;
  width:32px;height:32px;
  display:flex;align-items:center;justify-content:center;
  background:rgba(15,15,15,.45);
  border:0;border-radius:50%;
  color:#fff;
  opacity:.8;
  transition:opacity .2s ease, background-color .2s ease;
}
.carousel__stage:hover .carousel__fullscreen{opacity:1}
.carousel__fullscreen:hover{background:rgba(15,15,15,.7)}
.carousel__fullscreen svg{width:14px;height:14px;display:block;pointer-events:none}
