/* ==========================================================================
   ABTB 2026 — project page: description, photo grid, lightbox.

   Hand-written, unlike abtb-2026-{trendy,elevated}.css which are generated from
   the prototypes. Loaded only by the project page templates, on top of the skin
   stylesheet, and it reads that file's tokens (--ink, --accent, --line, …) so it
   follows the theme without redefining anything.

   The photo grid needs no JS row engine: every tile is one column with the same
   aspect-ratio, so rows are uniform by construction. The engine in abtb-2026.js
   exists for the listing grids, where cards span two columns.
   ========================================================================== */

/* ------------------------------------------------------------------ intro */
.project-lead {
  max-width: 68ch;
  color: var(--ink-soft);
  font-size: 17px;
  line-height: 1.65;
}
.project-lead p { margin: 0 0 1em; }
.project-lead p:last-child { margin-bottom: 0; }
.project-lead sup { font-size: .7em; }
.project-lead a { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; }

/* facts row under the title: year, tag list */
.project-facts {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 22px;
  margin: 0 0 26px;
  font-size: 13.5px;
  color: var(--ink-soft);
}
.project-facts .fact { display: inline-flex; align-items: center; gap: 8px; }
.project-facts .fact-label {
  font-size: 10.5px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.project-facts .fact-value { color: var(--ink); font-weight: 600; }
.project-facts .fact-tags { display: inline-flex; flex-wrap: wrap; gap: 6px; }
.project-facts .fact-tags span {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--accent);
  background: var(--accent-soft);
  padding: 3px 9px;
  border-radius: 100px;
}

/* ------------------------------------------------------------- photo grid */
.photo-section { padding: clamp(28px, 5vw, 52px) 0 clamp(48px, 8vw, 90px); }
.photo-section h2 {
  font-size: clamp(20px, 2.6vw, 26px);
  margin: 0 0 6px;
  color: var(--ink);
}
.photo-count { font-size: 13.5px; color: var(--ink-soft); margin: 0 0 22px; }
.photo-count strong { color: var(--accent); font-weight: 700; }

/* Justified rows, not a uniform grid.

   The first version put every photograph in a 4/3 tile with object-fit: cover.
   On the live Реновация касс page two of the four shots are portrait
   (2250x3000), so a third of each picture was cropped away to make it fit a
   landscape thumbnail. For an architecture practice the proportions of a
   photograph are part of the work.

   Each tile now publishes its own ratio as --ar (from the real pixel size the
   CMS stores) and asks for exactly the width that ratio needs at the row
   height. flex-grow is set to the same ratio, so the leftover pixels on each
   line are shared out in proportion to width: wide photographs stay wide, tall
   ones stay tall, and the rows still come out flush on both edges. The residual
   crop is a percent or two rather than a third of the frame.

   No JS: the browser's own line-breaking does the work the row engine in
   abtb-2026.js does for the spanning cards on the listing grids. */
.photo-grid {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(8px, 1.2vw, 14px);
}
/* Without this the final line stretches its one or two survivors across the
   whole width. A greedy invisible item soaks up the leftover instead, so the
   last row keeps the same scale as the rest. */
.photo-grid::after { content: ''; flex-grow: 999999; }

.photo-item {
  --ar: 1.5;                              /* overwritten inline per photo */
  --row-h: clamp(170px, 22vw, 290px);
  position: relative;
  display: block;
  flex: var(--ar) 1 calc(var(--ar) * var(--row-h));
  height: var(--row-h);
  min-width: 0;
  border: 0;
  padding: 0;
  border-radius: 14px;
  overflow: hidden;
  background: var(--paper);
  cursor: zoom-in;
  transition: box-shadow .25s ease;
}
.photo-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform .5s cubic-bezier(.2,.8,.2,1);
}
.photo-item:hover { box-shadow: 0 18px 36px -18px var(--glow, rgba(0,0,0,.35)); }
.photo-item:hover img { transform: scale(1.045); }
.photo-item:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* The opening shot runs the full width at its own proportions, capped so a
   portrait photograph cannot fill the whole screen before anything else. */
.photo-item.lead {
  flex: 1 1 100%;
  height: auto;
  aspect-ratio: var(--ar);
  max-height: min(74vh, 700px);
}

/* On a phone a justified row is two postage stamps. One photograph per line at
   its own proportions is the whole point of the page. */
@media (max-width: 560px) {
  .photo-item {
    flex: 1 1 100%;
    height: auto;
    aspect-ratio: var(--ar);
    max-height: 76vh;
  }
}

/* A real caption from the CMS, shown over the foot of the tile. Upload
   filenames ("7_final_22") are dropped in the template, so anything that
   reaches here is something a person wrote. */
.photo-caption {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: 26px 14px 11px;
  font-size: 12.5px;
  line-height: 1.35;
  text-align: left;
  color: #fff;
  background: linear-gradient(to top, rgba(6,8,14,.72), rgba(6,8,14,0));
  opacity: 0;
  transform: translateY(6px);
  transition: opacity .22s ease, transform .22s ease;
  pointer-events: none;
}
.photo-item:hover .photo-caption,
.photo-item:focus-visible .photo-caption { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .photo-item, .photo-item img, .photo-caption { transition: none; }
  .photo-item:hover img { transform: none; }
}

/* --------------------------------------------------------------- lightbox */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(6, 8, 14, .93);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  opacity: 0;
  visibility: hidden;
  transition: opacity .22s ease, visibility .22s;
}
.lightbox.open { opacity: 1; visibility: visible; }
.lightbox-figure {
  position: relative;          /* the loading spinner is ::after on this box */
  margin: 0;
  max-width: min(1400px, 94vw);
  max-height: 88vh;
  display: flex;
  flex-direction: column;
  gap: 12px;
  align-items: center;
}
.lightbox-figure img {
  max-width: 100%;
  /* leave room for the caption so a tall photo cannot push it off screen */
  max-height: calc(88vh - 52px);
  object-fit: contain;
  border-radius: 8px;
  background: #0b0d13;
}
.lightbox-caption {
  color: rgba(255,255,255,.82);
  font-size: 13.5px;
  text-align: center;
  max-width: 70ch;
}

/* click the photo to switch between fit-to-screen and true size: on a plan or
   a section the detail is only readable at 1:1 */
.lightbox-figure img { cursor: zoom-in; }
.lightbox.zoomed .lightbox-figure { max-width: 100vw; max-height: 100vh; overflow: auto; }
.lightbox.zoomed .lightbox-figure img {
  max-width: none;
  max-height: none;
  width: auto;
  height: auto;
  cursor: zoom-out;
}
.lightbox.zoomed .lightbox-caption { display: none; }

/* a full-size architectural photograph takes a moment even on a good line */
.lightbox-figure::after {
  content: '';
  position: absolute;
  top: 50%; left: 50%;
  width: 34px; height: 34px;
  margin: -17px 0 0 -17px;
  border: 2px solid rgba(255,255,255,.25);
  border-top-color: rgba(255,255,255,.9);
  border-radius: 100px;
  opacity: 0;
  pointer-events: none;
  animation: lightbox-spin .8s linear infinite;
}
.lightbox.loading .lightbox-figure::after { opacity: 1; }
.lightbox.loading .lightbox-figure img { opacity: .35; }
.lightbox-figure img { transition: opacity .2s ease; }
@keyframes lightbox-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .lightbox-figure::after { animation: none; }
}

.lightbox-close,
.lightbox-nav {
  position: absolute;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  border-radius: 100px;
  border: 1px solid rgba(255,255,255,.22);
  background: rgba(255,255,255,.08);
  color: #fff;
  cursor: pointer;
  transition: background .18s ease, border-color .18s ease, transform .18s ease;
}
.lightbox-close:hover,
.lightbox-nav:hover { background: rgba(255,255,255,.18); border-color: rgba(255,255,255,.5); }
.lightbox-close:focus-visible,
.lightbox-nav:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.lightbox-close svg, .lightbox-nav svg { width: 20px; height: 20px; }
.lightbox-close { top: 18px; right: 18px; }
.lightbox-nav.prev { left: 18px; }
.lightbox-nav.next { right: 18px; }
@media (max-width: 640px) {
  .lightbox-nav { bottom: 18px; top: auto; width: 44px; height: 44px; }
  .lightbox-nav.prev { left: calc(50% - 56px); }
  .lightbox-nav.next { right: calc(50% - 56px); }
}

.lightbox-counter {
  position: absolute;
  top: 22px;
  left: 22px;
  color: rgba(255,255,255,.7);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}

/* a single-photo album has nothing to page through */
.lightbox.single .lightbox-nav,
.lightbox.single .lightbox-counter { display: none; }

body.lightbox-open { overflow: hidden; }
