/* =====================================================================
   GlyBeat Blog — scoped styles, loaded after /css/style.css
   Reuses the site's existing tokens (--p1, --b1, --f-disp, etc.)
   ===================================================================== */

/* ── Ambient Vessel background ──
   Echoes the app's own flowing-blood-vessel visual (BloodVesselScene.swift):
   dark-red cell blobs drifting at different depths with a gentle bob, a
   slow-breathing colored glow, and a glass highlight sheen. Deliberately
   constant-speed, never varying — the app's own design notes say varying
   speed reads as anxiety-inducing to users, which applies here too.
   transform/opacity only, so there's nothing for it to ever reflow or
   garble, and it's inert under prefers-reduced-motion. */
.vessel-bg {
  position: fixed; inset: 0; z-index: -1; overflow: hidden;
  pointer-events: none; opacity: 0.45; /* was 0.22 — raised per user request 2026-10-30, revert to 0.22 if wanted */
}
.vessel-blob {
  position: absolute; border-radius: 50%; filter: blur(70px); will-change: transform;
}
.vessel-blob-1 {
  width: 440px; height: 170px; top: 6%; left: -22%;
  background: radial-gradient(circle, rgba(204,48,48,0.85), rgba(204,48,48,0) 70%);
  animation: vesselDriftA 42s linear infinite;
}
.vessel-blob-2 {
  width: 320px; height: 130px; top: 46%; left: -28%;
  background: radial-gradient(circle, rgba(255,140,107,0.8), rgba(255,140,107,0) 70%);
  animation: vesselDriftB 56s linear infinite;
}
.vessel-blob-3 {
  width: 280px; height: 110px; top: 70%; left: -20%;
  background: radial-gradient(circle, rgba(204,48,48,0.75), rgba(204,48,48,0) 70%);
  animation: vesselDriftA 50s linear infinite reverse;
}
.vessel-blob-4 {
  width: 220px; height: 95px; top: 24%; left: -30%;
  background: radial-gradient(circle, rgba(79,62,232,0.7), rgba(79,62,232,0) 70%);
  animation: vesselDriftB 64s linear infinite;
}
@keyframes vesselDriftA {
  0%   { transform: translate(0, 0); }
  50%  { transform: translate(62vw, -22px); }
  100% { transform: translate(124vw, 0); }
}
@keyframes vesselDriftB {
  0%   { transform: translate(0, 0); }
  50%  { transform: translate(58vw, 18px); }
  100% { transform: translate(118vw, 0); }
}
.vessel-glow {
  position: absolute; inset: -25%; border-radius: 50%;
  background: radial-gradient(ellipse at 50% 45%, rgba(79,62,232,0.4), rgba(79,62,232,0) 60%);
  animation: vesselPulse 5.5s ease-in-out infinite;
}
@keyframes vesselPulse {
  0%, 100% { opacity: 0.45; transform: scale(1); }
  50%      { opacity: 0.8; transform: scale(1.05); }
}
.vessel-sheen {
  position: absolute; inset: -10% -60%;
  background: linear-gradient(100deg, rgba(255,255,255,0) 20%, rgba(255,255,255,0.028) 50%, rgba(255,255,255,0) 80%);
  animation: vesselSheen 16s linear infinite;
}
@keyframes vesselSheen {
  0%   { transform: translateX(-20%); }
  100% { transform: translateX(20%); }
}
@media (prefers-reduced-motion: reduce) {
  .vessel-blob, .vessel-glow, .vessel-sheen { animation: none; }
}

/* ── Filter bar: search + category pills ──
   Uniform pills throughout (including "All" — no more mixed rounded-vs-
   grid look), in a horizontally scrollable row so it scales cleanly to
   many more categories later instead of wrapping into a ragged grid.
   Works without the 3D shelf engine — this is a base-layer feature so it
   still functions (and is still visible) on mobile/touch/reduced-motion,
   it just doesn't reposition the 3D shelf on those. */
html.no-js .filter-bar { display: none; }
.filter-bar {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: 14px; max-width: 820px; margin: 0 auto 10px; padding: 0 24px;
}
.search-field { position: relative; flex: 1 1 220px; max-width: 280px; min-width: 170px; }
.search-field svg {
  position: absolute; left: 14px; top: 50%; transform: translateY(-50%);
  width: 15px; height: 15px; color: var(--t3); pointer-events: none;
}
.search-field input {
  width: 100%; background: var(--b3); border: 1px solid var(--bd3); border-radius: 100px;
  padding: 10px 14px 10px 36px; font-size: 0.85rem; color: var(--t1); font-family: var(--f-body);
  transition: border-color 0.3s;
}
.search-field input::placeholder { color: var(--t3); }
.search-field input:focus { outline: none; border-color: var(--p2); }

.cat-tabs {
  display: flex; gap: 8px; overflow-x: auto; scroll-snap-type: x proximity;
  max-width: 100%; flex: 1 1 auto; padding: 2px 4px; scrollbar-width: none;
  mask-image: linear-gradient(90deg, transparent 0, #000 16px, #000 calc(100% - 16px), transparent 100%);
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 16px, #000 calc(100% - 16px), transparent 100%);
}
.cat-tabs::-webkit-scrollbar { display: none; }
.cat-tab {
  flex: 0 0 auto; scroll-snap-align: start;
  background: none; border: 1px solid var(--bd3); border-radius: 100px;
  color: var(--t3); font: inherit; font-family: var(--f-disp); font-weight: 600;
  font-size: 0.78rem; letter-spacing: 0.03em; padding: 10px 18px; cursor: pointer;
  white-space: nowrap; transition: color 0.3s, background 0.3s, border-color 0.3s;
}
.cat-tab.is-active { color: #fff; background: var(--p1); border-color: var(--p1); }
.cat-tab:hover:not(.is-active) { border-color: var(--p2); color: var(--t2); }

.filter-status { text-align: center; font-size: 0.78rem; color: var(--t3); margin: 0 0 36px; min-height: 1em; }
.filter-empty {
  text-align: center; color: var(--t3); font-size: 0.95rem; max-width: 420px;
  margin: 0 auto 48px; padding: 36px 24px; border: 1px dashed var(--bd3); border-radius: var(--r-lg);
}
.tape.is-filtered-out { display: none !important; }

/* ── Shelf wrapper ── */
.shelf-wrap { position: relative; max-width: 1100px; margin: 0 auto; padding: 0 24px 40px; }
.shelf { position: relative; }
.shelf-stage {
  display: flex; flex-wrap: wrap; gap: 22px; justify-content: center; align-items: stretch;
}

/* Default (no-JS / mobile / reduced-motion) card look */
.tape { list-style: none; width: 300px; max-width: 100%; }
.tape-face {
  display: block; height: 100%; border-radius: var(--r-lg); overflow: hidden;
  padding: 24px 22px; text-decoration: none; color: #fff; position: relative;
  background:
    /* bright specular streak, upper-left, like light catching curved glass */
    linear-gradient(115deg, rgba(255,255,255,0.65) 0%, rgba(255,255,255,0.12) 14%, rgba(255,255,255,0) 30%),
    /* thin bright rim down the left edge, soft shadow down the right — suggests a rounded, glossy surface */
    linear-gradient(90deg, rgba(255,255,255,0.3) 0%, rgba(255,255,255,0) 7%, rgba(255,255,255,0) 88%, rgba(0,0,0,0.22) 100%),
    linear-gradient(165deg, var(--tape-a) 0%, var(--tape-b) 100%);
  border: 1px solid rgba(255,255,255,0.28);
  box-shadow:
    0 24px 56px -22px rgba(0,0,0,0.6),
    inset 0 2px 0 rgba(255,255,255,0.5),
    inset 0 -46px 60px -34px rgba(0,0,0,0.4),
    inset 0 0 0 1px rgba(255,255,255,0.06);
  transition: transform 0.3s var(--ease-out), box-shadow 0.3s var(--ease-out);
}
.tape-face:hover, .tape-face:focus-visible {
  transform: translateY(-4px);
  box-shadow: 0 30px 66px -20px rgba(0,0,0,0.65), inset 0 2px 0 rgba(255,255,255,0.55), inset 0 -46px 60px -34px rgba(0,0,0,0.4);
}
.tape-face::after { content: ''; position: absolute; inset: 0; background: #000; opacity: var(--shade, 0); pointer-events: none; }
/* soft round highlight blob, like a bottle/glass catching an overhead light */
.tape-face::before {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(ellipse 120% 46% at 22% -6%, rgba(255,255,255,0.38), rgba(255,255,255,0) 62%);
}

/* Real frosted glass — added by shelf.js only on the centred cover, and only
   once it's fully turned to face the viewer and stopped moving (rotateY is
   exactly 0 at that moment). backdrop-filter is unreliable on a rotated/
   mid-transform element across browsers, so it's never applied while a tape
   is turning — see the "squishing" bug this replaced. */
.tape.is-glass .tape-face {
  background:
    linear-gradient(115deg, rgba(255,255,255,0.5) 0%, rgba(255,255,255,0.1) 18%, rgba(255,255,255,0) 34%),
    linear-gradient(90deg, rgba(255,255,255,0.2) 0%, rgba(255,255,255,0) 8%, rgba(255,255,255,0) 86%, rgba(0,0,0,0.16) 100%),
    linear-gradient(165deg, color-mix(in srgb, var(--tape-a) 74%, transparent) 0%, color-mix(in srgb, var(--tape-b) 74%, transparent) 100%);
  backdrop-filter: blur(20px) saturate(160%);
  -webkit-backdrop-filter: blur(20px) saturate(160%);
  box-shadow:
    0 34px 76px -20px rgba(0,0,0,0.7),
    inset 0 2px 0 rgba(255,255,255,0.6),
    inset 0 -46px 60px -34px rgba(0,0,0,0.28),
    inset 0 0 0 1px rgba(255,255,255,0.22);
  transition: background 0.5s ease, box-shadow 0.5s ease, backdrop-filter 0.5s ease;
}
.tape-tag {
  display: inline-block; font-family: var(--f-disp); font-size: 0.68rem; font-weight: 700;
  letter-spacing: 0.09em; text-transform: uppercase; opacity: 0.85;
}
.tape-title { font-family: var(--f-disp); font-weight: 700; font-size: 1.15rem; line-height: 1.3; margin-top: 12px; }
.tape-excerpt {
  font-size: 0.88rem; line-height: 1.55; margin-top: 10px;
  color: #fff; text-shadow: 0 1px 4px rgba(0,0,0,0.45);
}
.tape-meta { display: block; font-size: 0.72rem; opacity: 0.75; margin-top: 16px; letter-spacing: 0.03em; font-weight: 600; }

/* Caption + arrows: only meaningful in 3D mode, hidden otherwise */
.shelf-caption, .shelf-arrows { display: none; }

/* ── Desktop 3D enhancement (added by shelf.js only when supported) ──
   CoverFlow-style: every card is always the same size, same font-size,
   same horizontal text, all the time. Only transform/opacity/filter ever
   change per frame — properties the compositor handles identically on
   every browser, with zero text reflow. Nothing here can "squish", because
   nothing here ever changes what the text looks like or how much space it
   has — only where the whole, untouched card sits in 3D space. */
.shelf.is-3d { height: min(440px, 48vw); perspective: 1400px; perspective-origin: 50% 50%; }
.shelf.is-3d .shelf-stage { position: absolute; inset: 0; display: block; }
.shelf.is-3d .tape {
  position: absolute; top: 50%; left: 50%; width: var(--card-w, 230px); height: 82%;
  will-change: transform, opacity;
}
.shelf.is-3d .tape-face { height: 100%; display: flex; flex-direction: column; }
.shelf.is-3d .tape-title {
  font-size: 1.08rem; line-height: 1.3;
  display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden;
}
.shelf.is-3d .tape-excerpt {
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
  font-size: 0.82rem; margin-top: 10px;
}
.shelf.is-3d .tape-meta { margin-top: auto; padding-top: 14px; }
.shelf.is-3d .tape.is-hover .tape-face { filter: brightness(1.12); }
.shelf.is-3d .tape.is-active .tape-title { font-size: 1.18rem; }
.shelf.is-3d .tape.is-active .tape-face { box-shadow: 0 34px 80px -22px rgba(0,0,0,0.65), 0 0 0 1px rgba(255,255,255,0.08) inset; }

/* Shown via inline style (display:flex) by shelf.js once the shelf is enhanced —
   kept in normal document flow (not absolutely positioned) so its real height
   pushes the CTA box below it down instead of overlapping it. */
.shelf-caption {
  flex-direction: column; align-items: center; gap: 5px; text-align: center;
  max-width: min(92%, 620px); margin: 32px auto 0;
  transition: opacity 0.25s, transform 0.25s;
}
.shelf-caption-tag { font-family: var(--f-disp); font-size: 0.72rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--p2); }
.shelf-caption-title { font-family: var(--f-disp); font-size: 1.3rem; font-weight: 700; color: var(--t1); }
.shelf-caption-excerpt { font-size: 0.92rem; line-height: 1.55; color: var(--t2); margin-top: 2px; }
.shelf-caption-meta { font-size: 0.78rem; color: var(--t3); margin-top: 2px; }

.shelf.is-3d .shelf-arrows { display: flex; position: absolute; inset: 0; justify-content: space-between; align-items: center; pointer-events: none; }
.shelf-arrow {
  pointer-events: auto; width: 44px; height: 44px; border-radius: 50%; border: 1px solid var(--bd3);
  background: rgba(15,14,26,0.6); color: var(--t1); font-size: 1.3rem; cursor: pointer;
  display: flex; align-items: center; justify-content: center; transition: border-color 0.3s, transform 0.2s;
}
.shelf-arrow:hover { border-color: var(--p2); transform: scale(1.06); }
.shelf-arrow:disabled { opacity: 0.3; cursor: default; }
.shelf-arrow:disabled:hover { transform: none; border-color: var(--bd3); }

@media (max-width: 899px) {
  .shelf.is-3d { height: auto; perspective: none; }
  .shelf.is-3d .shelf-stage { position: static; display: flex; }
  .shelf.is-3d .tape { position: relative; top: auto; left: auto; transform: none !important; width: 100% !important; }
}

/* ── Blog listing footer CTA ── */
.blog-cta {
  max-width: 760px; margin: 60px auto 0; text-align: center; padding: 48px 32px;
  border-radius: var(--r-xl); background: linear-gradient(155deg, var(--b3), var(--b4));
  border: 1px solid var(--bd2);
}
.blog-cta h2 { font-size: 1.6rem; margin-bottom: 10px; }
.blog-cta p { color: var(--t3); margin-bottom: 22px; }

/* =====================================================================
   Individual article pages
   ===================================================================== */
.post-back {
  display: inline-flex; align-items: center; gap: 6px; font-size: 0.85rem; font-weight: 600;
  color: var(--t3); margin: calc(var(--nav-h) + 28px) 0 0; padding: 0 24px; max-width: var(--max-w);
  margin-left: auto; margin-right: auto;
}
.post-back:hover { color: var(--p2); }

.post-hero-wrap { max-width: var(--max-w); margin: 18px auto 0; padding: 0 24px; }
.post-tag { display: inline-flex; align-items: center; gap: 6px; }
.post-title { font-size: clamp(1.9rem, 4vw, 2.7rem); margin: 16px 0 14px; max-width: 820px; }
.post-meta-row { display: flex; gap: 14px; align-items: center; color: var(--t3); font-size: 0.86rem; margin-bottom: 28px; }
.post-meta-row .dot { width: 3px; height: 3px; border-radius: 50%; background: var(--t3); }

.post-hero-banner {
  width: 100%; height: auto; border-radius: var(--r-xl);
  display: block; margin-bottom: 48px; background: var(--b3);
}
/* Fallback treatment if a page still uses the old placeholder div (no real photo yet) */
div.post-hero-banner {
  height: min(320px, 42vw); overflow: hidden; position: relative;
  display: flex; align-items: center; justify-content: center;
}
div.post-hero-banner svg { width: 64px; height: 64px; opacity: 0.9; }
div.post-hero-banner::after {
  content: 'Placeholder cover — swap for the real photo from this article\'s Photo Brief';
  position: absolute; bottom: 14px; left: 50%; transform: translateX(-50%);
  font-size: 0.68rem; letter-spacing: 0.03em; color: rgba(255,255,255,0.65);
  background: rgba(0,0,0,0.25); padding: 4px 10px; border-radius: 100px; white-space: nowrap;
}

.post-prose { max-width: 720px; margin: 0 auto; padding: 0 24px 20px; }
.post-prose h2 { font-size: 1.5rem; margin: 40px 0 16px; }
.post-prose p { margin-bottom: 18px; font-size: 1.04rem; line-height: 1.75; color: var(--t2); }
.post-prose ul { margin: 0 0 20px; padding-left: 0; display: flex; flex-direction: column; gap: 10px; }
.post-prose li { font-size: 1.02rem; line-height: 1.65; color: var(--t2); padding-left: 24px; position: relative; }
.post-prose li::before { content: ''; position: absolute; left: 0; top: 10px; width: 7px; height: 7px; border-radius: 50%; background: var(--p2); }
.post-prose strong { color: var(--t1); font-weight: 600; }

.post-callout {
  border-left: 3px solid var(--a1); background: rgba(255,179,71,0.07); border-radius: 0 var(--r-sm) var(--r-sm) 0;
  padding: 16px 20px; margin: 32px 0; font-size: 0.92rem; line-height: 1.65; color: var(--t3);
}
.post-callout strong { color: var(--a2); }

.post-cta {
  max-width: 720px; margin: 48px auto 0; padding: 40px 32px; text-align: center;
  border-radius: var(--r-xl); background: linear-gradient(155deg, var(--b3), var(--b4)); border: 1px solid var(--bd2);
}
.post-cta h2 { font-size: 1.5rem; margin-bottom: 10px; }
.post-cta p { color: var(--t3); margin-bottom: 24px; }

.post-more { max-width: var(--max-w); margin: 64px auto 0; padding: 40px 24px 0; border-top: 1px solid var(--bd1); }
.post-more h3 { font-size: 1.1rem; margin-bottom: 20px; color: var(--t3); font-weight: 600; }
.post-more-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
@media (max-width: 700px) { .post-more-grid { grid-template-columns: 1fr; } }
.post-more-card {
  display: block; padding: 20px; border-radius: var(--r-md); border: 1px solid var(--bd2);
  text-decoration: none; transition: border-color 0.3s, transform 0.2s;
}
.post-more-card:hover { border-color: var(--p2); transform: translateY(-2px); }
.post-more-card .tag { font-size: 0.68rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--p2); }
.post-more-card h4 { font-size: 1rem; margin: 8px 0 0; color: var(--t1); }
