/* ==========================================================================
   Portfolio (portfolio/index.html). Page-only styles.
   One idea: a screening reel. The title card and all 21 client sites ride one
   pinned horizontal reel on desktop (lit screens in a dark room, the one in the
   middle fully lit). Phones, tablets, short screens, reduced motion and no-JS get
   the same content as a hero + poster grid.
   ========================================================================== */

/* ---------- 1. Title card (hero) ----------------------------------------- */
.reel { position: relative; background: var(--void); }

.reel__title {
  position: relative;
  isolation: isolate;
  display: flex;
  align-items: flex-end;
  min-height: min(90svh, 820px);
  padding: calc(var(--header-h) + var(--space-xl)) var(--gutter) var(--space-xl);
  overflow: hidden;
}
.reel__photo { position: absolute; inset: 0; z-index: -1; overflow: hidden; }
.reel__photo img { width: 100%; height: 100%; object-fit: cover; object-position: 38% 30%; }
.reel__photo::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg, rgba(5, 8, 12, .7) 0%, rgba(5, 8, 12, .05) 26%, rgba(5, 8, 12, .2) 48%, rgba(5, 8, 12, .86) 76%, var(--void) 100%),
    linear-gradient(90deg, rgba(5, 8, 12, .55) 0%, rgba(5, 8, 12, 0) 60%);
}
.reel__intro {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  display: grid;
  gap: var(--space-m);
  justify-items: start;
}
.reel__intro h1 {
  font-size: min(clamp(3.75rem, 1rem + 11vw, 10rem), 17vh);
  line-height: .86;
  letter-spacing: -.045em;
  max-width: 8ch;
}
.reel__intro .lede { max-width: 38ch; color: var(--text-2); }
.reel__count {
  display: flex;
  align-items: center;
  gap: .9rem;
  margin-top: .35rem;
  color: var(--text-2);
  font-size: .9375rem;
  line-height: 1.35;
  max-width: 34ch;
}
.reel__count-num {
  font-family: var(--font-num);
  font-weight: 900;
  font-size: 3.25rem;
  line-height: .8;
  color: var(--cyan);
  font-variant-numeric: lining-nums tabular-nums;
}

@media (max-width: 959.98px) {
  .reel__title { display: grid; min-height: 0; padding: 0 var(--gutter) var(--space-m); }
  .reel__photo { position: relative; inset: auto; z-index: 0; margin: 0 calc(-1 * var(--gutter)); aspect-ratio: 4 / 3.3; }
  .reel__photo img { object-position: 34% 28%; }
  .reel__photo::after { background: linear-gradient(180deg, rgba(5, 8, 12, .62) 0%, rgba(5, 8, 12, 0) 26%, rgba(5, 8, 12, 0) 52%, rgba(5, 8, 12, .8) 82%, var(--void) 100%); }
  .reel__intro { position: relative; z-index: 1; margin-top: min(-18vw, -64px); }
  .reel__intro .btn-row { width: 100%; }
  .reel__intro .btn { flex: 1 1 auto; }
}
@media (min-width: 640px) and (max-width: 959.98px) {
  .reel__photo { aspect-ratio: 16 / 9; }
  .reel__intro { margin-top: -12vw; }
}

/* ---------- 2. Chapters + posters (grid layout: the default) -------------- */
.reel__chapter {
  width: 100%;
  max-width: calc(var(--container) + var(--gutter) * 2);
  margin-inline: auto;
  padding: var(--space-xl) var(--gutter) 0;
}
.reel__chapter + .reel__chapter { padding-top: var(--space-2xl); }
.reel__chapter-title { font-size: var(--step-3); max-width: 16ch; margin-bottom: var(--space-l); }
.reel__list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-l) .875rem;
}
@media (min-width: 640px) { .reel__list { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-l) 1.25rem; } }
@media (min-width: 960px) { .reel__list { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-xl) 2rem; } }

.poster { min-width: 0; }
.poster__link { display: block; border-radius: var(--radius); }
.poster__link:focus-visible { outline: none; }
.poster__frame {
  position: relative;
  display: block;
  aspect-ratio: 1020 / 1400;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--night-2);
  box-shadow: 0 0 0 1px rgba(234, 241, 247, .08), 0 44px 70px -40px rgba(0, 0, 0, .95);
  transition: transform .7s var(--ease-out), box-shadow .7s var(--ease-out);
}
.poster__frame img { width: 100%; height: 100%; object-fit: cover; }
.poster__shade {
  position: absolute;
  inset: 0;
  background: var(--void);
  opacity: 0;
  pointer-events: none;
}
.poster__link:focus-visible .poster__frame { outline: 2px solid var(--cyan); outline-offset: 4px; }
.poster__cap { display: grid; gap: .1rem; margin-top: 1rem; }
.poster__name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.0625rem, .95rem + .45vw, 1.3125rem);
  line-height: 1.15;
  letter-spacing: -.022em;
  word-spacing: .03em;
  color: var(--text);
  text-wrap: balance;
}
.poster__meta { font-size: .9375rem; line-height: 1.4; color: var(--muted); }
.poster__url {
  margin-top: .3rem;
  width: fit-content;
  max-width: 100%;
  font-size: .875rem;
  line-height: 1.35;
  color: var(--cyan);
  overflow-wrap: anywhere;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: .22em;
  text-decoration-color: rgba(0, 198, 242, .35);
  transition: text-decoration-color var(--dur-fast);
}
@media (hover: hover) {
  .poster__link:hover .poster__frame { transform: translateY(-6px); box-shadow: 0 0 0 1px rgba(0, 198, 242, .55), 0 54px 80px -40px rgba(0, 0, 0, .95); }
  .poster__link:hover .poster__url { text-decoration-color: var(--cyan); }
}
@media (max-width: 639.98px) {
  .poster__cap { margin-top: .75rem; }
  .poster__meta { font-size: .875rem; }
  .poster__url { font-size: .8125rem; }
}

/* End card */
.reel__end {
  width: 100%;
  max-width: calc(var(--container) + var(--gutter) * 2);
  margin-inline: auto;
  padding: var(--space-2xl) var(--gutter) var(--space-xl);
  display: grid;
  gap: var(--space-m);
  justify-items: start;
}
.reel__end-title { font-size: var(--step-4); max-width: 11ch; }
.reel__end p { font-size: var(--step-1); line-height: 1.5; color: var(--text-2); max-width: 40ch; }
.reel__rail { display: none; }
.reel__nav { display: none; }   /* arrows exist only on the pinned reel (the grid has nothing to step through) */

/* ---------- 3. The reel (desktop, motion allowed, JS booted) ------------- */
@media (min-width: 960px) and (min-height: 700px) and (prefers-reduced-motion: no-preference) {
  html.js:not(.reveal-failed) .reel { --poster-h: min(58vh, 640px); }
  html.js:not(.reveal-failed) .reel__frame {
    position: relative;
    height: 100vh;
    overflow: hidden;
    overflow: clip;
  }
  html.js:not(.reveal-failed) .reel__track {
    display: flex;
    align-items: stretch;
    width: max-content;
    height: 100%;
    padding-right: max(var(--gutter), 6vw);
    will-change: transform;
  }

  /* Title card: the photo panel, bleeding off the left edge and fading into the dark */
  html.js:not(.reveal-failed) .reel__title {
    flex: none;
    width: clamp(600px, 54vw, 1000px);
    min-height: 0;
    height: 100%;
    padding: calc(var(--header-h) + 4vh) clamp(2rem, 5vw, 5rem) max(14vh, 116px) max(var(--gutter), (100vw - var(--container)) / 2);
  }
  html.js:not(.reveal-failed) .reel__photo img { position: absolute; top: 0; left: -24%; width: 124%; max-width: none; height: 100%; object-position: 30% 30%; will-change: transform; }
  html.js:not(.reveal-failed) .reel__photo::after {
    background:
      linear-gradient(180deg, rgba(5, 8, 12, .72) 0%, rgba(5, 8, 12, 0) 24%, rgba(5, 8, 12, .08) 50%, rgba(5, 8, 12, .88) 82%, var(--void) 100%),
      linear-gradient(90deg, rgba(5, 8, 12, .62) 0%, rgba(5, 8, 12, .12) 44%, rgba(5, 8, 12, .35) 74%, var(--void) 100%);
  }
  html.js:not(.reveal-failed) .reel__intro { max-width: none; margin: 0; }
  html.js:not(.reveal-failed) .reel__intro h1 { font-size: min(clamp(4.5rem, 8.2vw, 9.5rem), 16.5vh); }
  html.js:not(.reveal-failed) .reel__intro .lede { font-size: min(var(--step-1), 2.7vh); }
  html.js:not(.reveal-failed) .reel__intro { gap: min(var(--space-m), 2.8vh); }

  /* Chapters: a caption line over a row of lit screens */
  html.js:not(.reveal-failed) .reel__chapter {
    flex: none;
    width: auto;
    max-width: none;
    margin: 0 0 0 clamp(3rem, 6vw, 7rem);
    padding: calc(var(--header-h) + 1vh) 0 9vh;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
  html.js:not(.reveal-failed) .reel__chapter + .reel__chapter { margin-left: clamp(5rem, 10vw, 11rem); }
  html.js:not(.reveal-failed) .reel__chapter-title {
    max-width: none;
    white-space: nowrap;
    font-size: min(clamp(1.5rem, .9rem + 1.1vw, 2.25rem), 4.2vh);
    margin-bottom: 2.6vh;
    letter-spacing: -.035em;
    width: fit-content;
    will-change: transform;
  }
  html.js:not(.reveal-failed) .reel__list { display: flex; gap: clamp(1.75rem, 2.8vw, 3.25rem); }
  html.js:not(.reveal-failed) .poster { flex: none; width: calc(var(--poster-h) * 1020 / 1400); }
  html.js:not(.reveal-failed) .poster__cap { margin-top: 1.8vh; }
  html.js:not(.reveal-failed) .poster__name { font-size: min(1.3125rem, 2.5vh); }
  html.js:not(.reveal-failed) .poster__meta { font-size: min(.9375rem, 1.9vh); }

  html.js:not(.reveal-failed) .reel__end {
    flex: none;
    align-self: center;
    width: clamp(380px, 30vw, 520px);
    max-width: none;
    margin: 0 0 0 clamp(5rem, 10vw, 11rem);
    padding: var(--header-h) 0 0;
  }
  html.js:not(.reveal-failed) .reel__end-title { font-size: min(var(--step-4), 9vh); }

  /* Progress rail: the drawn line, stopping short of the floating call button */
  html.js:not(.reveal-failed) .reel__rail {
    display: block;
    position: absolute;
    left: max(var(--gutter), (100vw - var(--container)) / 2);
    right: calc(max(var(--gutter), (100vw - var(--container)) / 2) + 72px);
    bottom: 4.2vh;
    height: 2px;
    border-radius: 2px;
    background: var(--line);
    overflow: hidden;
  }
  html.js:not(.reveal-failed) .reel__rail i { display: block; height: 100%; background: var(--cyan); transform: scaleX(0); transform-origin: 0 50%; }

  /* Click-through arrows: round frosted controls on the middle of the screenshots
     (JS sets --reel-nav-y), at both edges where the neighbouring sites peek in. The
     right one sits in the call button's column, well above it. With no site left on
     a side the arrow steps aside, because the title card and end card use those edges. */
  html.js:not(.reveal-failed) .reel__nav {
    display: block;
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
  }
  html.js:not(.reveal-failed) .reel__arrow {
    --arrow: 56px;
    position: absolute;
    top: var(--reel-nav-y, 50%);
    display: grid;
    place-items: center;
    width: var(--arrow);
    height: var(--arrow);
    margin-top: calc(var(--arrow) / -2);
    border-radius: 50%;
    border: 1px solid var(--line-2);
    background: rgba(5, 8, 12, .78);                     /* the header's frosted glass */
    -webkit-backdrop-filter: blur(16px) saturate(150%);
    backdrop-filter: blur(16px) saturate(150%);
    color: var(--text);
    box-shadow: 0 12px 28px -12px rgba(0, 0, 0, .7);
    pointer-events: auto;
    -webkit-tap-highlight-color: transparent;
    transition: opacity var(--dur) var(--ease-out), visibility 0s, color var(--dur-fast), border-color var(--dur-fast), background-color var(--dur-fast), transform var(--dur) var(--ease-out);
  }
  html.js:not(.reveal-failed) .reel__arrow svg { width: 22px; height: 22px; }
  html.js:not(.reveal-failed) .reel__arrow--prev { left: calc(22px + env(safe-area-inset-left)); }
  html.js:not(.reveal-failed) .reel__arrow--next { right: calc(22px + env(safe-area-inset-right)); }
  html.js:not(.reveal-failed) .reel__arrow:active { transform: scale(.94); }
  html.js:not(.reveal-failed) .reel__arrow:focus-visible { outline: 2px solid var(--cyan); outline-offset: 3px; border-radius: 50%; }
  html.js:not(.reveal-failed) .reel__arrow[aria-disabled="true"] {
    opacity: 0;
    visibility: hidden;
    cursor: default;
    transition: opacity var(--dur) var(--ease-out), visibility 0s linear var(--dur);
  }
  /* ...but never vanish from under keyboard focus: dim instead */
  html.js:not(.reveal-failed) .reel__arrow[aria-disabled="true"]:focus-visible { opacity: .4; visibility: visible; transition-delay: 0s; }
}
@media (min-width: 960px) and (min-height: 700px) and (prefers-reduced-motion: no-preference) and (hover: hover) {
  html.js:not(.reveal-failed) .reel__arrow:not([aria-disabled="true"]):hover { color: var(--cyan); border-color: var(--cyan); }
}

/* ---------- 4. Finale ----------------------------------------------------- */
.page-portfolio .finale h2 { max-width: 15ch; }
.page-portfolio .finale .lede { max-width: 52ch; }
.page-portfolio .finale__bg img { object-position: 64% 40%; }

/* Load check: the inline stylesheet guard re-fetches this file if this rule is missing. Keep it last. */
:root { --css-portfolio: 1; }
