/* ── Text / blog post (project variant) ─────────────────────────────────────── */
/* Long-form writing on the black projector field. A fixed header (the risen
   gallery footer — rule + metadata, like the single-image viewer) stays pinned
   while the body scrolls beneath. Images are sticky in the left column: a
   second image rises and takes the first one's place. */

body[data-view="post"] {
  --post-header-h: 58px;   /* fixed-header height — sticky offset + body inset */
  --post-inset: 16px;      /* shared left/right inset: the header rule spans the
                              same width as the banner/footer lines (16px), and
                              the image's left edge lines up with "Back" */
  background: #000;
  color: #d8d8d8;
}

/* Like the single-image viewer: no top/bottom chrome. The full-height field
   starts on the white page background, so the post slides up looking like the
   gallery, then dips to black on arrival (postLoadDip below). No banner-mask /
   footer covers needed — no light/dark mismatch to hide while still white. */
body[data-view="post"] .banner-mask { display: none; }

/* Reuse the gallery footer as the post's top bar, like the single-image viewer.
   Naming the header's bar-inner `site-footer` morphs the footer LINE up on the
   way in and back down on "Back". The field (root) slides underneath (index.css
   vtSlide*); gallery cover chrome is dropped via html[data-vt-deep]. */
body[data-view="post"] .post-header .bar-inner { view-transition-name: site-footer; }

/* ── Fixed header — same treatment as the single-image viewer top bar ────────── */
.post-header {
  background: #000;
  left: 0;
  padding-top: 14px;
  position: fixed;
  right: 0;
  top: 0;
  z-index: 950;
  /* Dips white → black on arrival in lockstep with the field. */
  animation: postLoadDip 0.7s ease var(--vt-slow) both;
}

.post-header .bar-inner {
  align-items: baseline;
  border-top: 1px solid #2e2e2e;
  display: flex;
  gap: 24px;
  justify-content: space-between;
  margin: 0 var(--post-inset);
  padding: 8px 0 14px;
}

.post-header .viewer-title { font-weight: 500; white-space: nowrap; }
.post-header .viewer-year { opacity: 0.7; white-space: nowrap; }
.post-header .viewer-desc {
  opacity: 0.7;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ── Scrolling body: sticky image(s) left, text right ───────────────────────── */
.post-standalone {
  background: #000;
  color: #d8d8d8;
  min-height: 100vh;
  min-height: 100dvh;
  padding: var(--post-header-h) var(--post-inset) 12vh;
  /* Same load dip as the viewer (viewerLoadDip): the field arrives on the white
     background — so the slide-up reads as the gallery — then turns black.
     Delayed by --vt-slow so the white phase holds through the slide and the dip
     starts once the page has landed. */
  animation: postLoadDip 0.7s ease var(--vt-slow) both;
}

/* The dip carries the TEXT with it: dark-on-white while the page slides in (so
   the header/body never read as a blank white band), light-on-black once
   settled. */
@keyframes postLoadDip {
  from { background-color: var(--main-bg-color); color: var(--main-text-color); }
  to   { background-color: #000; color: #d8d8d8; }
}

@media (prefers-reduced-motion: reduce) {
  .post-standalone,
  .post-header { animation: none; }
}

.post-body {
  display: grid;
  grid-template-columns: minmax(0, 40%) minmax(0, 1fr);
  gap: 56px;
  padding-top: 40px;
  /* default align-items:stretch keeps the media column as tall as the text, so
     the last sticky image can travel the full length of the read */
}

.post-media { min-width: 0; }

/* Each image pins just under the fixed header. With several stacked, the next
   one rises and pushes the previous away — a second image trumps the first. */
.post-figure {
  margin: 0 0 24px;
  position: sticky;
  top: calc(var(--post-header-h) + 16px);
}
.post-figure:last-child { margin-bottom: 0; }

.post-figure img {
  display: block;
  width: 100%;
  height: auto;
  object-fit: cover;
  /* Same vivid backlit-slide treatment as the image viewer. */
  filter: brightness(1.04) saturate(1.08);
}

/* ── Body typography (Kirby Blocks) ─────────────────────────────────────────── */
.post-text {
  font-size: clamp(18px, 1.7vw, 30px);
  line-height: 1.34;
  max-width: 62ch;
  min-width: 0;
}

.post-text > * + * { margin-top: 1.1em; }
.post-text h1,
.post-text h2,
.post-text h3 { font-weight: 500; line-height: 1.12; }
.post-text h2 { font-size: 1.2em; }
.post-text h3 { font-size: 1.05em; }
.post-text a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.post-text ul,
.post-text ol { padding-left: 1.4em; }
.post-text li + li { margin-top: 0.3em; }
.post-text blockquote {
  border-left: 2px solid #2e2e2e;
  margin: 0;
  padding-left: 1em;
  opacity: 0.85;
}
.post-text figure { margin: 1.4em 0; }
.post-text figure img { display: block; height: auto; width: 100%; }
.post-text figure figcaption { font-size: 0.7em; opacity: 0.6; margin-top: 0.5em; }
.post-text hr { border: 0; border-top: 1px solid #2e2e2e; margin: 1.8em 0; }

/* Stack on narrow screens: cover on top (no longer sticky), text below.
   (700px = the site-wide mobile breakpoint.) The header goes in-flow: its
   metadata stacks to a variable height (see the deep-view rules in index.css),
   so the fixed-header + --post-header-h padding model no longer holds. */
@media (max-width: 700px) {
  .post-header { position: static; }
  .post-standalone { padding-top: 0; }
  .post-body { grid-template-columns: 1fr; gap: 24px; padding-top: 24px; }
  .post-figure { position: static; max-width: 440px; margin-bottom: 16px; }
  .post-text { font-size: 19px; max-width: none; }
}
