/* ── THE FEED, FULL PORTRAIT (2026-10-15, James: "UI/UX like patreon scrolling posts" → "no i want them to be full
   portrait like posts on instagram or patreon ... up top we have our little hub of like heres the premise and
   characters and all that stuff, and then you scroll down and its the feed") ──────────────────────────────────
   The series page scrolls: the hub screen (the loop, the name, the doors, the list) and under it THE FEED — every
   post newest first, one full-width portrait sticker each, the words under it, like a post. A LOCKED post (a Sub
   Level drop) is the same sticker blurred under a lock + MEMBERS ONLY with a Get in button under its words, in among
   the free ones. The chips (All · Episodes · Extras · Sub Level) stick to the top while the feed scrolls. /sub-level/
   carries the same cards, locked only, no chips. Loaded by /good-boy/ and /sub-level/ only; style.css untouched —
   the hub overrides it needs are at the end of this sheet. Written by deploy/write-episode-pages.py (feed_block). ── */

/* THE SECTION under the hub (James, 2026-10-15: "i dont like the page background for the feed can you just use that same
   background as on the premise page"): THE PANE.S GROUND — the campus loop, still playing, under the panes. 76 % tint +
   6 px blur. On a phone the hub.s loop is FIXED behind the whole page (it was absolute in the hub screen), so it stays
   under the feed as the page scrolls; the feed section carries the tint. On a desk the blurred campus still (.hub-ground)
   is already fixed behind everything, and the feed column takes the drawer.s 60 % tint. */
@media not ((min-width: 700px) and (min-aspect-ratio: 1 / 1)) {
  .series-hub .hub-loop { position: fixed; }
}
.feed-sec {
  position: relative; z-index: 1; padding: var(--space-2xl) var(--gutter) var(--space-5xl);
  background: oklch(0.13 0.035 262 / 0.76); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}
.feed-in { width: 100%; max-width: 540px; }
.feed-name {
  margin: 0 0 var(--space-md); font-family: var(--display); font-weight: 400;
  font-size: clamp(2rem, 9vw, 3.25rem); line-height: 1; color: var(--cream); text-transform: uppercase; white-space: nowrap;
  text-shadow: 0.06em 0.06em 0 var(--ink);
}
.feed-name .sec-count { text-shadow: none; }

/* THE CHIPS: stuck to the top while the feed scrolls, on the panes' tint */
.fd-chips {
  position: sticky; top: 0; z-index: 3;
  display: flex; flex-wrap: nowrap; gap: var(--space-sm); overflow-x: auto; scrollbar-width: none;   /* ONE ROW on a phone, it scrolls sideways */
  margin: 0 calc(-1 * var(--gutter)) var(--space-xl); padding: var(--space-md) var(--gutter);
  background: oklch(0.13 0.035 262 / 0.86); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
}
.fd-chips::-webkit-scrollbar { display: none; }
.fd-chip {
  display: inline-grid; grid-auto-flow: column; align-items: baseline; gap: 0.35em;
  margin: 0; flex: none; white-space: nowrap; padding: 0.5em 0.75em 0.42em; min-height: 40px;
  font-family: var(--display); font-size: 0.8125rem; line-height: 1; letter-spacing: 0.02em; text-transform: uppercase;
  color: var(--cream); background: oklch(0.97 0.03 95 / 0.08); border: 2px solid oklch(0.97 0.03 95 / 0.3); border-radius: 0;
  cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: background 160ms var(--ease-out), color 160ms var(--ease-out), box-shadow 160ms var(--ease-out);
}
.fd-chip .fd-n { font-family: var(--body); font-weight: 700; font-size: 0.8125rem; opacity: 0.75; }
.fd-chip[aria-pressed="true"] { color: var(--ink); background: var(--cyan); border-color: var(--ink); box-shadow: 3px 3px 0 var(--ink); }
.fd-chip[aria-pressed="true"] .fd-n { opacity: 0.85; }
.fd-chip:focus-visible { outline: 3px solid var(--cyan); outline-offset: 2px; }

/* THE POSTS */
.fd-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-4xl); }
.fd-item[hidden] { display: none; }
.fd-post { display: grid; gap: var(--space-md); }

/* the picture: the poster at the column's width, a sticker — cream edge, ink line, hard shadow, half the table's tilt */
.fd-pic {
  position: relative; display: block; aspect-ratio: 9 / 16; overflow: hidden; background: var(--navy);
  border: 5px solid var(--cream); outline: 2px solid var(--ink); box-shadow: 8px 8px 0 var(--ink);
  transform: rotate(calc(var(--r, -1.5deg) * 0.5)); margin: 4px 8px 8px 0;
  -webkit-tap-highlight-color: transparent;
  transition: transform 220ms var(--ease-out), box-shadow 220ms var(--ease-out);
}
.fd-pic img { display: block; width: 100%; height: 100%; object-fit: cover; }
@media (hover: hover) { .fd-pic:hover { transform: rotate(0deg) translate(-2px, -2px); box-shadow: 10px 10px 0 var(--ink); } }
.fd-pic:active { transform: rotate(0deg) translate(3px, 3px); box-shadow: 3px 3px 0 var(--ink); }
.fd-pic:focus-visible { outline: 3px solid var(--cyan); outline-offset: 3px; }

/* the NEW sticker (the pocket's, moved onto the newest episode's card) */
.fd-new {
  position: absolute; z-index: 2; top: 10px; left: -6px;
  font-family: var(--display); font-size: 1.0625rem; line-height: 1; text-transform: uppercase; color: var(--ink);
  background: var(--yellow); border: 3px solid var(--ink); box-shadow: 3px 3px 0 var(--ink);
  padding: 0.38em 0.55em 0.3em; transform: rotate(-8deg);
}
/* the quiet play disc on a free post (the cover card's): see-through ink, a cream mark, bottom right */
.fd-play {
  position: absolute; z-index: 2; right: 12px; bottom: 12px; width: 52px; height: 52px; border-radius: 50%;
  display: grid; place-items: center;
  background: oklch(0.22 0.06 262 / 0.7); border: 2px solid oklch(0.97 0.03 95 / 0.9);
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
}
.fd-play::after { content: ""; margin-left: 4px; border-style: solid; border-width: 9px 0 9px 15px; border-color: transparent transparent transparent var(--cream); }

/* the words under the picture, like a post's caption */
.fd-body { display: grid; justify-items: start; row-gap: 6px; padding: 0 2px; min-width: 0; }
.fd-kicker { font-size: 0.75rem; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--yellow); text-shadow: 1px 1px 0 var(--ink); font-variant-numeric: tabular-nums; }
.fd-title {
  font-family: var(--display); font-size: clamp(1.375rem, 6vw, 1.75rem); line-height: 1.02; text-transform: uppercase;
  color: var(--cream); text-decoration: none; text-wrap: balance; text-shadow: 2px 2px 0 var(--ink);
  -webkit-tap-highlight-color: transparent;
}
@media (hover: hover) { .fd-title:hover { color: var(--yellow); } }
.fd-title:focus-visible { outline: 3px solid var(--cyan); outline-offset: 3px; }
.fd-line { margin: 0; font-size: 1rem; line-height: 1.4; color: var(--navy-cream); }

/* LOCKED: the picture blurred and dimmed, the lock and MEMBERS ONLY on it, Get in under the words */
.fd-post.is-locked .fd-pic img { filter: blur(16px) saturate(0.8) brightness(0.6); transform: scale(1.12); }
.fd-lock {
  position: absolute; inset: 0; z-index: 2; display: grid; place-items: center; align-content: center; row-gap: 12px;
  color: var(--ink);
}
.fd-lock svg {
  width: 64px; height: 64px; padding: 14px; box-sizing: border-box; fill: currentColor;
  background: var(--yellow); border: 3px solid var(--ink); border-radius: 50%; box-shadow: 4px 4px 0 var(--ink);
}
.fd-lock-k {
  padding: 0.4em 0.65em 0.3em;
  font-family: var(--display); font-size: 1rem; line-height: 1; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--ink); background: var(--yellow); border: 3px solid var(--ink); box-shadow: 3px 3px 0 var(--ink);
  transform: rotate(-3deg);
}
.btn.fd-join { margin-top: 6px; min-height: 48px; font-size: 1rem; border-width: 3px; box-shadow: 4px 4px 0 var(--ink); }
.btn.fd-join:hover { box-shadow: 6px 6px 0 var(--ink); }
.btn.fd-join:active { box-shadow: 1px 1px 0 var(--ink); }

/* THE CAROUSEL (James, 2026-10-15: "build the carousels now"): the picture's frame — the same sticker as .fd-pic — holding
   a sideways track that snaps one picture at a time (CSS does the swipe; feed.js keeps the count + dots in step). The
   "n / N" count top right; the dots under the frame; on a desk, arrows on hover. A locked carousel is written as a
   locked .fd-pic (its cover blurred under the lock), never as a track. */
.fd-car {
  position: relative; display: block; aspect-ratio: var(--ar, 9 / 16);   /* a carousel keeps its cards own shape (Twink Jail is 3:4) */ overflow: hidden; background: var(--navy);
  border: 5px solid var(--cream); outline: 2px solid var(--ink); box-shadow: 8px 8px 0 var(--ink);
  transform: rotate(calc(var(--r, -1.5deg) * 0.5)); margin: 4px 8px 8px 0;
  /* no touch-action here (10-15, James: "up and down to continue to scroll the page does not" on his iPhone): Safari
     treats the pans it is told about as the only pans, and a vertical swipe that starts on the frame goes nowhere */
}
.fd-car:focus-visible { outline: 3px solid var(--cyan); outline-offset: 3px; }
.fd-car-track {
  list-style: none; margin: 0; padding: 0; height: 100%;
  display: flex; overflow: visible;   /* the FRAME clips; the track is what moves, so a clip on it would move away with it */
  /* THE SLIDES MOVE BY SCRIPT, NOT BY THE BROWSER (10-15, James: "still gets sticky sometimes" on his iPhone after the
     native scroller lost its extras): the track is not a scroll box at all. touch-action: pan-y hands every vertical
     swipe to the page before this code sees it; a sideways swipe arrives as pointer events and feed.js translates the
     track under the thumb, then snaps. Without the script the first picture shows and the dots do nothing. */
  touch-action: pan-y; will-change: transform;
  transition: transform 340ms var(--ease-out);
}
.fd-car-track.is-dragging { transition: none; }
.fd-car-track li { flex: 0 0 100%; height: 100%; user-select: none; -webkit-user-select: none; }
.fd-car-track img { -webkit-user-drag: none; pointer-events: none; }
.fd-car-track img { display: block; width: 100%; height: 100%; object-fit: cover; }
.fd-car-n {
  position: absolute; z-index: 2; top: 12px; right: 12px; padding: 0.35em 0.6em 0.28em;
  font-family: var(--display); font-size: 0.8125rem; line-height: 1; letter-spacing: 0.04em; color: var(--cream);
  background: oklch(0.22 0.06 262 / 0.7); border: 2px solid oklch(0.97 0.03 95 / 0.9);
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); font-variant-numeric: tabular-nums;
}
.fd-dots { display: flex; justify-content: center; gap: 7px; margin: 2px 0 0; }
.fd-dot {
  width: 9px; height: 9px; padding: 0; margin: 0; border-radius: 50%; cursor: pointer;
  background: oklch(0.97 0.03 95 / 0.35); border: 2px solid oklch(0.08 0.02 262 / 0.6);
  transition: background 160ms var(--ease-out), transform 160ms var(--ease-out);
}
.fd-dot.on { background: var(--yellow); border-color: var(--ink); transform: scale(1.25); }
.fd-dot:focus-visible { outline: 3px solid var(--cyan); outline-offset: 2px; }
/* the desk's arrows: hidden until the frame is hovered, gone at either end */
.fd-car-btn {
  position: absolute; z-index: 2; top: 50%; width: 44px; height: 44px; margin-top: -22px; padding: 0; border-radius: 50%;
  display: none; place-items: center; cursor: pointer; color: var(--cream);
  background: oklch(0.22 0.06 262 / 0.7); border: 2px solid oklch(0.97 0.03 95 / 0.9);
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
  opacity: 0; transition: opacity 160ms var(--ease-out);
}
.fd-car-btn svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; }
.fd-car-prev { left: 10px; } .fd-car-prev svg { transform: scaleX(-1); }
.fd-car-next { right: 10px; }
@media (hover: hover) and (pointer: fine) {
  .fd-car-btn { display: grid; }
  .fd-car:hover .fd-car-btn, .fd-car:focus-within .fd-car-btn { opacity: 1; }
  .fd-car.at-start .fd-car-prev, .fd-car.at-end .fd-car-next { opacity: 0; pointer-events: none; }
}
.fd-post.is-carousel span.fd-title { cursor: default; }
.fd-car[data-href] .fd-car-track { cursor: pointer; }   /* a tap opens the photo viewer (10-27) */

/* ARRIVAL: each post rises as the page reaches it is for later; for now a post is simply there */

/* THE HUB SCREEN ABOVE IT: the pocket is gone, so the name no longer leaves room for a poster to rise into */
.series-hub { --name-gap: var(--space-md); }
.hub-feed-door { grid-column: 1 / -1; }      /* the feed door takes its own row under the two-and-two on a phone */

/* ON A DESK: the feed continues in the hub's right-hand column, the loop's column left empty, the posts a post's width */
@media (min-width: 700px) and (min-aspect-ratio: 1 / 1) {
  .series-hub .hub-name { margin-bottom: var(--space-lg); }
  .feed-sec {
    display: grid; grid-template-columns: var(--loop-w) var(--hub-col); column-gap: var(--hub-gap);
    justify-content: start; padding: var(--space-3xl) 0 var(--space-5xl) var(--hub-left);
    background: none; -webkit-backdrop-filter: none; backdrop-filter: none;
  }
  .feed-in {
    grid-column: 2; max-width: 480px; box-sizing: content-box; padding: var(--space-2xl) var(--space-2xl) var(--space-3xl);
    background: oklch(0.13 0.035 262 / 0.6); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  }
  .feed-in .fd-chips { top: 0; }
  .fd-chips { margin-inline: 0; padding-inline: 0; }
  .fd-title { font-size: 1.75rem; }
  .hub-feed-door { grid-column: auto; }
}

/* ON /sub-level/: the feed sits in the cover's sheet (narrower, no chips); the Get in bar stays in reach at the foot
   of the sheet while it scrolls */
.sub-level .fd { margin-top: var(--space-xs); }
.sub-level .fd-list { gap: var(--space-2xl); }
.sub-level .fd-title { font-size: 1.375rem; }
.sl-stick {
  position: sticky; bottom: 0; z-index: 2;
  margin: var(--space-sm) calc(-1 * var(--space-lg)) calc(-1 * var(--space-lg));
  padding: var(--space-md) var(--space-lg) calc(var(--space-lg) + env(safe-area-inset-bottom, 0px));
  background: linear-gradient(to bottom, oklch(0.13 0.035 262 / 0), oklch(0.13 0.035 262 / 0.96) 26%);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}
.sl-stick .btn { width: 100%; font-size: 1.125rem; border-width: 3px; box-shadow: 4px 4px 0 var(--ink); }
.sl-stick .btn:hover { box-shadow: 6px 6px 0 var(--ink); }
.sl-stick .btn:active { box-shadow: 1px 1px 0 var(--ink); }
.sl-stick-k { display: block; margin: var(--space-sm) 0 var(--space-sm); text-align: center; font-size: 0.8125rem; font-weight: 700; color: var(--navy-dim); }

/* THE COMIC POST AS A COMIC BOOK (James, 2026-10-16: "redesign the comic on the feed ... it should be cooler and more comic
   like for the border"; it replaced the white-margin frame + yellow dot shadow + COMIC tag of the same morning): the cover
   of an issue lying on a little stack. A heavy ink frame; two cream pages fanned out behind it with the stack's hard ink
   shadow; the issue number top right, lettered like the logo; the title as a cover logo at the foot (the
   reader's title construction, values copied from comic-scroll.css .cs-sfx.xl: ink block, red side, halftone yellow face,
   bouncing letters); a READ IT! starburst (the yellow narration box came off, James 10-16: "i domt want the yellow badge that says scroll it"). Sizes in cqw of the cover. */
.fd-item[data-kind="comic"] .fd-post { position: relative; isolation: isolate; }
.fd-item[data-kind="comic"] .fd-pic { container-type: inline-size; border: 4px solid var(--ink); outline: 0; box-shadow: none; background: #fdfcf7; }
.fd-item[data-kind="comic"] .fd-pic::after { content: ""; position: absolute; inset: 0; z-index: 1; box-shadow: inset 0 0 0 2px #fdfcf7; pointer-events: none; }
.fd-item[data-kind="comic"] .fd-pic::before {   /* the cover's foot shaded in ink, so the logo + the box read over any drawing */
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 44%; z-index: 1; pointer-events: none;
  background: linear-gradient(to top, oklch(0.16 0.045 262 / 0.92) 0%, oklch(0.16 0.045 262 / 0.72) 45%, oklch(0.16 0.045 262 / 0) 100%);
}
.fd-item[data-kind="comic"] .fd-post::before, .fd-item[data-kind="comic"] .fd-post::after {
  content: ""; position: absolute; left: 0; top: 4px; width: calc(100% - 8px); aspect-ratio: 9 / 16;
  background: #fdfcf7; border: 3px solid var(--ink); transition: transform 220ms var(--ease-out);
}
.fd-item[data-kind="comic"] .fd-post::before { z-index: -1; transform: translate(6px, 6px) rotate(calc(var(--r, -1.5deg) * 0.5 + 1.8deg)); }
.fd-item[data-kind="comic"] .fd-post::after { z-index: -2; transform: translate(12px, 11px) rotate(calc(var(--r, -1.5deg) * 0.5 + 3.4deg)); box-shadow: 7px 7px 0 var(--ink); }
@media (hover: hover) {
  .fd-item[data-kind="comic"] .fd-pic:hover { box-shadow: none; }
  .fd-item[data-kind="comic"] .fd-post:has(.fd-pic:hover)::before { transform: translate(9px, 7px) rotate(calc(var(--r, -1.5deg) * 0.5 + 3deg)); }
  .fd-item[data-kind="comic"] .fd-post:has(.fd-pic:hover)::after { transform: translate(18px, 12px) rotate(calc(var(--r, -1.5deg) * 0.5 + 5.5deg)); }
}
.fd-item[data-kind="comic"] .fd-pic:active { box-shadow: none; }
.fd-item[data-kind="comic"] .fd-post:has(.fd-pic:active)::before { transform: translate(3px, 3px) rotate(calc(var(--r, -1.5deg) * 0.5 + 1deg)); }
.fd-item[data-kind="comic"] .fd-post:has(.fd-pic:active)::after { transform: translate(6px, 6px) rotate(calc(var(--r, -1.5deg) * 0.5 + 2deg)); }

/* the issue number (James, 10-16: "stylize #2 in the top right better, and dont put good boy comics or free ... and not on a
   white box"): #n lettered like the logo, bigger and tilted the other way, the # small and raised */
.fd-cb-no {
  position: absolute; z-index: 2; top: 4cqw; right: 6cqw; display: flex; align-items: flex-start; pointer-events: none;
  font-family: var(--display); font-size: 21cqw; line-height: 0.85; color: var(--ink); transform: rotate(8deg) skewX(-6deg);
}
.fd-cb-no .ch.hash { font-size: 0.5em; margin: 0.12em 0.06em 0 0; }
.fd-cb-logo {
  position: absolute; z-index: 2; left: 3cqw; right: 3cqw; bottom: 6cqw; display: flex; justify-content: center;
  font-family: var(--display); font-size: min(17cqw, calc(118cqw / var(--n, 8))); line-height: 0.9; color: var(--ink);
  transform: rotate(-4deg) skewX(-7deg); pointer-events: none;
}
.fd-cb-logo .sp { width: 0.28em; }
.fd-cb-logo .ch, .fd-cb-no .ch {
  position: relative; display: inline-block; margin-right: -0.035em;
  -webkit-text-stroke: 0.15em var(--ink); paint-order: stroke fill;
  text-shadow: 0.03em 0.03em 0 var(--ink), 0.06em 0.06em 0 var(--ink), 0.09em 0.09em 0 var(--ink);
}
.fd-cb-logo .ch:nth-child(odd) { transform: translateY(-0.035em) rotate(-3deg); }
.fd-cb-logo .ch:nth-child(even) { transform: translateY(0.03em) rotate(2.5deg); }
.fd-cb-logo .ch::before, .fd-cb-logo .ch::after, .fd-cb-no .ch::before, .fd-cb-no .ch::after { content: attr(data-t); position: absolute; text-shadow: none; }
.fd-cb-logo .ch::before, .fd-cb-no .ch::before { left: -0.05em; top: -0.05em; color: oklch(0.62 0.22 25); -webkit-text-stroke: 0; }
.fd-cb-logo .ch::after, .fd-cb-no .ch::after {
  left: -0.1em; top: -0.1em; -webkit-text-stroke: 0.045em var(--ink);
  background:
    radial-gradient(circle, oklch(0.62 0.19 45 / 0.5) 0 28%, transparent 32%) 0 0 / 0.11em 0.11em,
    linear-gradient(180deg, oklch(0.96 0.13 102) 0%, var(--yellow) 42%, oklch(0.78 0.18 62) 100%);
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
}

.fd-cb-burst {
  position: absolute; z-index: 3; right: 2cqw; bottom: 30cqw; width: 25cqw; aspect-ratio: 1; display: grid; place-items: center;
  transform: rotate(10deg); pointer-events: none; filter: drop-shadow(3px 3px 0 var(--ink));
}
.fd-cb-burst svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.fd-cb-burst polygon { fill: oklch(0.62 0.22 25); stroke: var(--ink); stroke-width: 3.5; stroke-linejoin: round; }
.fd-cb-burst-k {
  position: relative; font-family: var(--display); font-size: 5.6cqw; line-height: 0.92; text-align: center; text-transform: uppercase;
  color: var(--yellow); -webkit-text-stroke: 0.55cqw var(--ink); paint-order: stroke fill; transform: rotate(-6deg);
}
@media (hover: hover) { .fd-pic:hover .fd-cb-burst { transform: rotate(4deg) scale(1.08); transition: transform 220ms var(--ease-out); } }
@media (prefers-reduced-motion: no-preference) {
  .fd-cb-burst { animation: fd-cb-throb 2.4s ease-in-out infinite; }
  @keyframes fd-cb-throb { 0%, 100% { transform: rotate(10deg) scale(1); } 50% { transform: rotate(10deg) scale(1.06); } }
}
