/* fl718-nyc-2015-2022.css — NYC 2015-2022 desktop styles
   Version: 1.0.2
   Last updated: 2026-09-30
   Extracted from nyc-2015-2022-index.html prototype (Seamus-approved,
   Step 4/6 QA-cleared 2026-09-28/29). After-content section removed —
   superseded site-wide by the shared template-parts/after-content.php
   partial + fl718-after-content.css (BUG-061); the prototype's own
   inline after-content CSS block is intentionally NOT ported here. */


    /* ============================================================
       ALL CSS SCOPED TO: body.fl718-nyc-2015-2022-page
       Every rule below uses this body class as its scope prefix.
       Never write an unscoped rule.
       ============================================================ */

    /* ------------------------------------------------------------
       BASE
       ------------------------------------------------------------ */
    body.fl718-nyc-2015-2022-page {
      margin: 0;
      padding: 0;
      /* overflow-x: clip — NOT hidden. hidden creates a new scroll
         container that breaks position:sticky and ScrollTrigger pins
         site-wide. Never overflow-x:hidden on body or html. */
      overflow-x: clip;
      background-color: #eeece9;
      color: #201f1d;
      -webkit-font-smoothing: antialiased;
    }

    :where(body.fl718-nyc-2015-2022-page) *,
    :where(body.fl718-nyc-2015-2022-page) *::before,
    :where(body.fl718-nyc-2015-2022-page) *::after {
      box-sizing: border-box;
    }

    body.fl718-nyc-2015-2022-page img {
      max-width: 100%;
      display: block;
    }

    body.fl718-nyc-2015-2022-page .fl718-ny2b-visually-hidden {
      position: absolute;
      width: 1px;
      height: 1px;
      padding: 0;
      margin: -1px;
      overflow: hidden;
      clip: rect(0, 0, 0, 0);
      white-space: nowrap;
      border: 0;
    }

    /* ============================================================
       HERO — "Close Focus" (first pass)
       This photo has almost no open negative space (dense corner-to-
       corner framing) — object-fit:cover, the site's usual hero crop,
       NOT Bucket A's departure into object-fit:contain (that was a
       reaction to Bucket A's own specific letterboxing problem, which
       this photo's tighter composition doesn't share).
       ============================================================ */

    body.fl718-nyc-2015-2022-page .fl718-ny2b-hero {
      position: relative;
      width: 100%;
      height: 100vh;
      overflow: clip;
      background-color: #201f1d;
      display: flex;
      align-items: center;
      justify-content: center;
    }

    body.fl718-nyc-2015-2022-page .fl718-ny2b-hero picture {
      position: absolute;
      inset: 0;
      display: block;
      width: 100%;
      height: 100%;
    }

    body.fl718-nyc-2015-2022-page .fl718-ny2b-hero__image {
      width: 100%;
      height: 100%;
      object-fit: cover;
      object-position: center 38%;
      display: block;
      /* Starting state for "Close Focus" — GSAP racks this from soft/
         wide/desaturated into sharp focus. Paired with the no-JS and
         reduced-motion fallbacks below: ship both or neither. */
      opacity: 0;
      filter: blur(14px) saturate(0.7) brightness(1.06);
      transform: scale(1.06);
      transform-origin: center center;
    }

    /* Faint one-time drift of motes/wisp — "steamy, cinematic, weather"
       quality without literally depicting fog not in the photo. A
       handful of soft low-opacity blurred dots that cross the frame
       once, overlapping the focus pull, then are removed by JS. */
    body.fl718-nyc-2015-2022-page .fl718-ny2b-hero__motes {
      position: absolute;
      inset: 0;
      z-index: 4;
      pointer-events: none;
      overflow: hidden;
    }
    body.fl718-nyc-2015-2022-page .fl718-ny2b-mote {
      position: absolute;
      border-radius: 50%;
      background: rgba(230, 232, 230, 0.5);
      filter: blur(6px);
      opacity: 0;
      will-change: transform, opacity;
    }

    /* Gradient lift for the bottom-anchored text block (see note below —
       this photo has no open wall space, so text sits in one
       conventional bottom block over a scrim, not Bucket A's 3-way split). */
    body.fl718-nyc-2015-2022-page .fl718-ny2b-hero__gradient {
      position: absolute;
      bottom: 0;
      left: 0;
      width: 100%;
      height: 46%;
      background: linear-gradient(to top, rgba(14, 13, 12, 0.72) 0%, transparent 100%);
      z-index: 5;
      pointer-events: none;
      opacity: 0;
    }

    /* Bottom-anchored text block — one conventional block, not a split.
       Per the editorial notes: this photo doesn't offer Bucket A's open
       wall-space alternative. */
    body.fl718-nyc-2015-2022-page .fl718-ny2b-hero__text-block {
      position: absolute;
      left: clamp(24px, 5vw, 64px);
      right: clamp(24px, 5vw, 64px);
      bottom: clamp(40px, 7vh, 88px);
      z-index: 10;
      pointer-events: none;
    }

    body.fl718-nyc-2015-2022-page .fl718-ny2b-hero__title {
      display: block;
      margin: 0 0 10px;
      font-family: 'Inter', system-ui, sans-serif;
      font-weight: 900;
      font-size: clamp(36px, 5.2vw, 72px);
      letter-spacing: -0.01em;
      line-height: 1.0;
      color: rgba(244, 243, 240, 0.98);
      text-shadow: 0 2px 20px rgba(6, 5, 5, 0.6), 0 1px 6px rgba(6, 5, 5, 0.4);
      opacity: 0;
      filter: blur(6px);
      transform: translateY(10px);
    }

    body.fl718-nyc-2015-2022-page .fl718-ny2b-hero__subtitle-row {
      display: flex;
      align-items: center;
      gap: 14px;
      margin: 0 0 8px;
      opacity: 0;
      filter: blur(6px);
      transform: translateY(8px);
    }

    body.fl718-nyc-2015-2022-page .fl718-ny2b-hero__rule {
      display: block;
      width: 28px;
      height: 1px;
      background: rgba(110, 130, 145, 0.7); /* the hero's own cool accent */
      flex-shrink: 0;
    }

    body.fl718-nyc-2015-2022-page .fl718-ny2b-hero__year {
      display: block;
      font-family: 'DM Sans', system-ui, sans-serif;
      font-weight: 500;
      font-size: clamp(11px, 1vw, 14px);
      letter-spacing: 0.18em;
      text-transform: uppercase;
      color: rgba(236, 236, 232, 0.88);
    }

    body.fl718-nyc-2015-2022-page .fl718-ny2b-hero__byline {
      margin: 0;
      max-width: 100%;
      white-space: nowrap;
      font-family: 'Inter', system-ui, sans-serif;
      font-weight: 400;
      font-size: clamp(15px, 1.3vw, 19px);
      line-height: 1.5;
      color: rgba(238, 237, 233, 0.94);
      text-shadow: 0 1px 3px rgba(6, 5, 5, 0.7), 0 1px 12px rgba(6, 5, 5, 0.6);
      opacity: 0;
      filter: blur(6px);
      transform: translateY(8px);
    }

    /* Reduced motion — hero shows its END STATE immediately. Reduced
       motion means skip the animation and KEEP the end state. */
    @media (prefers-reduced-motion: reduce) {
      body.fl718-nyc-2015-2022-page .fl718-ny2b-hero__image {
        opacity: 1 !important;
        filter: none !important;
        transform: none !important;
      }
      body.fl718-nyc-2015-2022-page .fl718-ny2b-hero__gradient,
      body.fl718-nyc-2015-2022-page .fl718-ny2b-hero__title,
      body.fl718-nyc-2015-2022-page .fl718-ny2b-hero__subtitle-row,
      body.fl718-nyc-2015-2022-page .fl718-ny2b-hero__byline {
        opacity: 1 !important;
        filter: none !important;
        transform: none !important;
      }
      body.fl718-nyc-2015-2022-page .fl718-ny2b-hero__motes {
        display: none !important;
      }
    }

    /* ============================================================
       GALLERY GRID — CSS-columns masonry, "Soft Focus" entrance
       All 76 frames landscape (measured) -> masonry family, same as
       Bucket A. 3 columns desktop -> 2 at 768px.
       ============================================================ */

    body.fl718-nyc-2015-2022-page .fl718-ny2b-grid {
      columns: 3;
      column-gap: 8px;
      padding: 8px;
      padding-top: 14vh;
      padding-bottom: 12vh;
      /* overflow: clip — the grid item's own pre-reveal transform:
         scale(1.04) start state (below) contributes to document
         scrollWidth even with overflow-x:clip on body, because the
         overflow originates from a scaled descendant, not body's own
         box. Same mechanism as the mobile grid's own fix (BUG found
         2026-09-29, see Web_Animation_Reference.md), applied here
         pre-emptively rather than waiting to reproduce it on desktop. */
      overflow: clip;
    }

    @media (max-width: 768px) {
      body.fl718-nyc-2015-2022-page .fl718-ny2b-grid {
        columns: 2;
        padding-top: 10vh;
      }
    }

    body.fl718-nyc-2015-2022-page .fl718-ny2b-item {
      break-inside: avoid;
      margin: 0 0 8px 0;
      overflow: visible;
      cursor: pointer;
      position: relative;
      display: block;
      opacity: 0;
      /* "Soft Focus" entrance start state — blurred + slightly scaled,
         GSAP sharpens/settles it. Paired with the reduced-motion
         fallback below: ship both or neither. */
      filter: blur(10px);
      transform: scale(1.04);
    }

    body.fl718-nyc-2015-2022-page .fl718-ny2b-item:focus {
      outline: none;
    }
    body.fl718-nyc-2015-2022-page .fl718-ny2b-item:focus-visible {
      outline: 2px solid rgba(110, 130, 145, 0.9);
      outline-offset: 3px;
    }

    body.fl718-nyc-2015-2022-page .fl718-ny2b-item img {
      width: 100%;
      height: auto;
      display: block;
      /* Hover "focus-pull" (see below) animates filter/transform on the
         IMG itself, not a layer over it — GSAP-driven, this transition
         is a safety net only for any non-GSAP state changes. */
      transition: none;
    }

    /* ── HOVER: soft focus-pull, first pass, not yet built/tested ─────
       Slight scale + a subtle sharpen/contrast bump on hover/focus,
       echoing the page's focus/depth idea a third time as a quiet
       micro-interaction — deliberately NOT Bucket A's hardware-coded
       "Perimeter Frame Snap" (this set has no chain-link/fire-escape
       material vocabulary to draw hardware from). GSAP owns the tween
       in Script 4; this CSS only sets up the transform-origin and a
       thin accent ring using the hero's own cool accent colour. ── */
    body.fl718-nyc-2015-2022-page .fl718-ny2b-item {
      transform-origin: center center;
    }

    body.fl718-nyc-2015-2022-page .fl718-ny2b-item__accent-ring {
      position: absolute;
      inset: 0;
      border: 1px solid rgba(110, 130, 145, 0);
      pointer-events: none;
      z-index: 2;
    }

    /* Reduced motion for the grid — show items at rest, no blur/scale. */
    @media (prefers-reduced-motion: reduce) {
      body.fl718-nyc-2015-2022-page .fl718-ny2b-item {
        opacity: 1 !important;
        filter: none !important;
        transform: none !important;
      }
    }

    /* No-JS fallback — if JS never runs, content must still be visible. */
    body.fl718-nyc-2015-2022-page:not(.fl718-js-loaded) .fl718-ny2b-item,
    body.fl718-nyc-2015-2022-page:not(.fl718-js-loaded) .fl718-ny2b-hero__image,
    body.fl718-nyc-2015-2022-page:not(.fl718-js-loaded) .fl718-ny2b-hero__gradient,
    body.fl718-nyc-2015-2022-page:not(.fl718-js-loaded) .fl718-ny2b-hero__title,
    body.fl718-nyc-2015-2022-page:not(.fl718-js-loaded) .fl718-ny2b-hero__subtitle-row,
    body.fl718-nyc-2015-2022-page:not(.fl718-js-loaded) .fl718-ny2b-hero__byline {
      opacity: 1 !important;
      filter: none !important;
      transform: none !important;
    }

    /* ============================================================
       LIGHTBOX
       Layer 1 (9000) backdrop  |  Layer 2 (9100) stage  |  Layer 3 (9200) UI
       Signature gesture: "blur-resolve" — the surrounding grid softly
       blurs/dims while the selected photo resolves into sharp focus.
       Arrival/departure only, never held. Plain crossfade on navigate.
       ============================================================ */

    body.fl718-nyc-2015-2022-page .fl718-ny2b-lb-dark {
      position: fixed;
      inset: 0;
      background: rgba(10, 9, 8, 0.92);
      opacity: 0;
      z-index: 9000;
      pointer-events: none;
    }
    body.fl718-nyc-2015-2022-page .fl718-ny2b-lb-dark.fl718-ny2b-lb-dark--active {
      pointer-events: auto;
    }

    body.fl718-nyc-2015-2022-page .fl718-ny2b-lb-stage {
      position: fixed;
      inset: 0;
      z-index: 9100;
      display: flex;
      align-items: center;
      justify-content: center;
      padding: 60px;
      opacity: 0;
      pointer-events: none;
    }
    @media (max-width: 900px) {
      body.fl718-nyc-2015-2022-page .fl718-ny2b-lb-stage { padding: 40px; }
    }
    body.fl718-nyc-2015-2022-page .fl718-ny2b-lb-stage--active {
      pointer-events: auto;
    }

    body.fl718-nyc-2015-2022-page .fl718-ny2b-lb-backdrop {
      position: absolute;
      inset: 0;
    }

    body.fl718-nyc-2015-2022-page .fl718-ny2b-lb-image-wrap {
      position: relative;
      max-width: 100%;
      max-height: 100%;
      display: flex;
      align-items: center;
      justify-content: center;
    }

    body.fl718-nyc-2015-2022-page .fl718-ny2b-lb-image {
      max-width: 100%;
      max-height: calc(100vh - 120px);
      display: block;
      opacity: 0;
      /* "Blur-resolve" start state — the incoming photo starts a touch
         soft and resolves in, echoing the page's focus idea a fourth
         time (hero, grid entrance, hover, and now the lightbox open). */
      filter: blur(8px);
    }

    body.fl718-nyc-2015-2022-page .fl718-ny2b-lb-caption {
      position: absolute;
      bottom: -34px;
      left: 0;
      right: 0;
      text-align: center;
      font-family: 'DM Sans', system-ui, sans-serif;
      font-size: clamp(0.75rem, 1vw, 0.9rem);
      color: #ccc;
      opacity: 0;
      margin: 0;
    }

    /* The rest of the grid, visible through the backdrop's edges on a
       narrow viewport or if the backdrop is ever made translucent —
       kept subtle-blur-capable for the "surrounding grid softens"
       half of the gesture. On this page the dark backdrop is opaque
       (rgba .92), so this rule is mostly a hook for a lighter backdrop
       treatment if that's revisited in concepting. */
    body.fl718-nyc-2015-2022-page.fl718-ny2b-lb-open .fl718-ny2b-grid {
      filter: blur(3px) brightness(0.85);
      transition: filter 0.5s ease;
    }
    @media (prefers-reduced-motion: reduce) {
      body.fl718-nyc-2015-2022-page.fl718-ny2b-lb-open .fl718-ny2b-grid {
        filter: none;
        transition: none;
      }
    }

    body.fl718-nyc-2015-2022-page .fl718-ny2b-lb-ui {
      position: fixed;
      inset: 0;
      z-index: 9200;
      opacity: 0;
      pointer-events: none;
    }
    body.fl718-nyc-2015-2022-page .fl718-ny2b-lb-ui--active {
      pointer-events: none; /* individual controls opt back in via tabindex/pointer-events */
    }

    /* BUG-097 — lightbox controls: LIGHTLY apparent, never loud (the lightbox is
       all about the photo). The old dark chip on a dark backdrop vanished; this is
       a dim glyph only (no ring, no chip), same 44px hit area, brightens on hover. Controls take
       pointer-events ONLY while the lightbox is open (state-scoping contract) —
       a closed lightbox must not swallow clicks on the photos beneath. */
    body.fl718-nyc-2015-2022-page .fl718-ny2b-lb-close-btn,
    body.fl718-nyc-2015-2022-page .fl718-ny2b-lb-nav {
      position: fixed;
      background: transparent;
      border: none;
      border-radius: 50%;
      width: 44px;
      height: 44px;
      display: flex;
      align-items: center;
      justify-content: center;
      cursor: pointer;
      padding: 0; /* GeneratePress gives every <button> padding:10px 20px, which crushed the 18px glyph to 2px inside a 44px box */
      pointer-events: none;
      color: rgba(238, 236, 233, 0.36);
      transition: background 0.35s ease, color 0.35s ease;
    }
    body.fl718-nyc-2015-2022-page .fl718-ny2b-lb-ui--active .fl718-ny2b-lb-close-btn,
    body.fl718-nyc-2015-2022-page .fl718-ny2b-lb-ui--active .fl718-ny2b-lb-nav {
      pointer-events: auto;
    }
    body.fl718-nyc-2015-2022-page .fl718-ny2b-lb-close-btn:hover,
    body.fl718-nyc-2015-2022-page .fl718-ny2b-lb-nav:hover {
      background: rgba(238, 236, 233, 0.06);
      color: rgba(238, 236, 233, 0.85);
    }
    body.fl718-nyc-2015-2022-page .fl718-ny2b-lb-close-btn svg,
    body.fl718-nyc-2015-2022-page .fl718-ny2b-lb-nav svg {
      width: 18px;
      height: 18px;
      stroke: currentColor;
      stroke-width: 1.25;
      fill: none;
    }
    body.fl718-nyc-2015-2022-page .fl718-ny2b-lb-close-btn {
      top: 24px;
      right: 24px;
    }
    body.fl718-nyc-2015-2022-page .fl718-ny2b-lb-prev { left: 24px; top: 50%; transform: translateY(-50%); }
    body.fl718-nyc-2015-2022-page .fl718-ny2b-lb-next { right: 24px; top: 50%; transform: translateY(-50%); }

    body.fl718-nyc-2015-2022-page .fl718-ny2b-lb-close-btn:focus-visible,
    body.fl718-nyc-2015-2022-page .fl718-ny2b-lb-nav:focus-visible {
      outline: 2px solid rgba(110, 130, 145, 0.9);
      outline-offset: 3px;
    }

    body.fl718-nyc-2015-2022-page .fl718-ny2b-lb-counter {
      position: fixed;
      bottom: 24px;
      left: 50%;
      transform: translateX(-50%);
      font-family: 'DM Sans', system-ui, sans-serif;
      font-size: 0.8rem;
      color: rgba(238, 238, 238, 0.8);
      pointer-events: none;
    }
