/* ============================================================
   BEINC — Our Work Section

   Architecture:
   - tr-section is pinned (GSAP ScrollTrigger pin:true) for 100vh while
     Moises overlay grows over it (true parallax zone).
   - #owFloating (fixed overlay, z:60, outside page-content) holds all text + stack.
     Phases (driven by pin progress 0-1 + post-pin scroll):
       A (pin 0-80%): Moises grows bottom→top with V-dip
       A (pin 40-80%): "Our | Work" text dissolves in + dashed line + ticks
       B (post-pin, 25vh desktop / 50vh mobile): text shrinks + moves to stack,
         scrambles to "Selected Projects", button + underline reveal
       C (grid scroll): verticals + horizontals reveal per row at 80% viewport
   - #ourWorkSection holds only grid + dashed lines (solid black2 bg)
   ============================================================ */

:root {
    --ow-stack-pad: 0%;                /* flush with pad-x (desktop) */
    --ow-stack-top: 10vh;              /* sticky top offset */
    --ow-grid-gap: var(--pad-x);
    --ow-target-scale: 0.3;            /* final text scale after shrink */
}

/* ── SECTION CONTAINER ────────────────────────────────────── */
.our-work-section {
    position: relative;
    background: var(--color-black2);
    color: var(--color-white);
    overflow: visible;
    z-index: 55;                        /* above Moises (z:50), below owFloating (z:60) */
}

.our-work-spacer {
    height: 0;         /* no gap — cards enter immediately after pin releases */
    width: 100%;
    pointer-events: none;
}

/* ── FLOATING OVERLAY (text + stack, fixed position) ─────── */
.ow-floating {
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    pointer-events: none;
    z-index: 60;                        /* above Moises (z:50), below nav (z:1000) */
    display: none;                      /* activated by JS */
    color: var(--color-white);
}

.ow-floating.-active { display: block; }

/* ── CENTER PLUS ICON (between words, desktop/tablet) ────
   JS positions and sizes this container the same way the older
   polaroid pair was positioned: rides the Moises V-dip → settles
   to centre → shrinks + fades during shrink phase. Hidden on
   mobile — mobile uses an identical plus inside .ow-words via
   .ow-mobile-icon. */
.ow-dash-center {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: clamp(72px, 7vw, 120px);
    aspect-ratio: 1 / 1;
    pointer-events: none;
    opacity: 0;                         /* JS drives visibility */
    color: var(--color-white);
    will-change: transform, opacity;
    z-index: 1;
}

/* ── PLUS ICON COMPONENT ──────────────────────────────────
   Lives inside .ow-dash-center (desktop/tablet) and .ow-mobile-icon
   (mobile). Two independent always-on animations layer together
   so the icon never repeats the same visual frame:
     .ow-plus__spin     → continuous rotation (14s)
     .ow-plus__breathe  → strong scale pulse (2.6s, scale 1 ↔ 1.12)
   Periods are deliberately coprime-ish so the combined motion
   feels alive and non-repetitive. */
.ow-plus {
    position: relative;
    width: 100%;
    height: 100%;
    pointer-events: none;
    color: var(--color-white);
}

.ow-plus__spin,
.ow-plus__breathe {
    width: 100%;
    height: 100%;
    transform-origin: center center;
}

.ow-plus__spin {
    animation: ow-plus-spin 14s linear infinite;
}

.ow-plus__breathe {
    animation: ow-plus-breathe 2.6s cubic-bezier(0.45, 0, 0.55, 1) infinite;
}

.ow-plus__svg {
    display: block;
    width: 100%;
    height: 100%;
}

@keyframes ow-plus-spin {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
}

@keyframes ow-plus-breathe {
    0%, 100% { transform: scale(1); }
    50%      { transform: scale(1.12); }
}

/* Respect users who don't want motion */
@media (prefers-reduced-motion: reduce) {
    .ow-plus__spin,
    .ow-plus__breathe { animation: none; }
}

/* ── WORDS (Our | Work) — visible during Phase A+B ────────── */
.ow-words {
    position: absolute;
    /* JS drives left/top/scale for center → stack-position transition */
    left: 50%;
    top: 50%;
    width: calc(100vw - var(--pad-x) * 2);
    transform: translate(-50%, -50%) scale(1);
    transform-origin: center center;
    display: flex;
    align-items: center;
    justify-content: flex-start;      /* divider flex:1 fills the space naturally */
    gap: 0;                           /* no gap — ticks butt right against words */
    opacity: 0;
    will-change: transform, left, top, opacity;
}

.ow-word {
    font-family: var(--font-heading);
    font-weight: var(--font-weight-medium);
    letter-spacing: var(--tracking-tight);
    line-height: 1;
    color: var(--color-white);
    font-size: clamp(64px, 14vw, 240px);
    flex-shrink: 0;
    white-space: nowrap;
}

.ow-word--right { padding-right: var(--pad-x); }

.ow-word .ow-char {
    display: inline-block;
    opacity: 0;
    transform: scale(1.5);
    filter: blur(0.15em);
    will-change: opacity, transform, filter;
}

/* ── DIVIDER (dashed line + ticks between words) ──────────── */
.ow-divider {
    flex: 1 1 auto;
    display: flex;
    align-items: center;
    justify-content: stretch;
    position: relative;
    margin: 0 calc(var(--space-5) * 2);   /* spacing between words and ticks */
}

.ow-divider__tick {
    width: var(--guide-width);
    height: 20px;
    flex-shrink: 0;
    border-left: var(--guide-border);
    transform: scaleY(0);
    transform-origin: center center;
    transition: transform 0.3s var(--ease-out-expo);
    will-change: transform;
}

.ow-divider__line {
    flex: 1 1 auto;
    height: var(--guide-width);
    border-top: var(--guide-border);
    transform: scaleX(0);
    transform-origin: center center;
    transition: transform 0.6s var(--ease-out-expo);
    will-change: transform;
}

/* Divider line + ticks driven by JS — no class toggle needed */

/* ── MOBILE PLUS ICON (replaces polaroid pair on mobile) ──────
   Wrapper around .ow-plus, sits inline between the "Our" and "Work"
   words and scales/moves with them via the parent owWords transform.
   JS additionally fades this wrapper's opacity during the shrink
   phase so the plus disappears before the scramble fires. Hidden
   on desktop. */
.ow-mobile-icon {
    display: none;
    width: clamp(20px, 6vw, 40px);
    aspect-ratio: 1 / 1;
    color: var(--color-white);
    flex-shrink: 0;
    will-change: opacity, transform;
}

/* ── STACK (Selected Projects + View all + Asterisk) ──────── */
.ow-stack {
    position: absolute;
    left: calc(var(--pad-x) + var(--ow-stack-pad));
    right: calc(var(--pad-x) + var(--ow-stack-pad));
    top: var(--ow-stack-top);
    display: flex;
    align-items: center;
    justify-content: space-between;
    opacity: 0;
    pointer-events: none;
    will-change: opacity;
}

.ow-stack__title {
    font-family: var(--font-heading);
    font-weight: var(--font-weight-medium);
    letter-spacing: var(--tracking-tight);
    line-height: 1.05;
    color: var(--color-white);
    font-size: clamp(24px, 3vw, 48px);
    margin: 0;
    white-space: nowrap;
}

.ow-stack__button {
    /* positioned absolutely by JS — centered between title and asterisk */
    pointer-events: auto;
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    text-decoration: none;
    color: var(--color-white);
    font-family: var(--font-heading);
    font-weight: var(--font-weight-medium);
    font-size: var(--text-sm);
    letter-spacing: var(--tracking-tight);
    white-space: nowrap;
    transition: gap 0.5s cubic-bezier(0.22, 1, 0.36, 1);  /* easeOutQuint */
    opacity: 0;                /* hidden until FadeUpReveal plays */
}
.ow-stack__button:hover {
    gap: var(--space-5);
}
.ow-stack__button-label { flex-shrink: 0; }
.ow-stack__button-arrow {
    width: 0.55em;
    height: 0.85em;
    flex-shrink: 0;
    fill: currentColor;
}

.ow-stack__asterisk {
    width: clamp(20px, 2.5vw, 40px);
    height: clamp(20px, 2.5vw, 40px);
    color: var(--color-white);
    fill: var(--color-white);
    flex-shrink: 0;
    will-change: transform;
    opacity: 0;               /* hidden until FadeUpReveal plays */
}

/* ── UNDERLINE BELOW STACK (center-out reveal) ────────────── */
.ow-underline {
    position: absolute;
    top: calc(var(--ow-stack-top) + clamp(36px, 5vw, 72px));
    left: 0;
    width: 100vw;
    height: var(--guide-width);
    border-top: var(--guide-border);
    transform: scaleX(0);
    transform-origin: center center;
    transition: transform 0.8s var(--ease-out-expo);
    will-change: transform;
}

.ow-floating.-stack-reveal .ow-stack { opacity: 1; pointer-events: auto; }
.ow-floating.-stack-reveal .ow-underline { transform: scaleX(1); }

/* Stack background: covers top of viewport → underline, full width */
.ow-floating::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: calc(var(--ow-stack-top) + clamp(36px, 5vw, 72px));  /* matches underline position */
    background: var(--color-black2);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.4s ease;
    z-index: -1;                     /* behind stack text but inside owFloating */
}
.ow-floating.-stack-reveal::before {
    opacity: 1;
}

/* ── GRID ──────────────────────────────────────────────────── */
.our-work-grid {
    position: relative;
    padding: 0 var(--pad-x);
    display: flex;
    flex-direction: column;
    z-index: 3;
}

.our-work-grid__row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--ow-grid-gap);
    /* Cards have an initial transform of translateX(40vw) for the right-to-left
       reveal. With DevTools docked, Chrome resolves `vw` against the FULL
       window inner width (which includes the DevTools panel), so the cards get
       pushed past the visible area and become the page's biggest horizontal
       overflow contributor. Clipping at the row level contains the pre-reveal
       translation cleanly — the cards still slide in from the row's right edge
       during the reveal, and the dashed horizontal lines (siblings, not
       children) are unaffected. */
    overflow: clip;
}

.our-work-grid__card {
    position: relative;
    transform: translateX(40vw);
    opacity: 0;
    will-change: transform, opacity;
}

/* ── DASHED LINES ─────────────────────────────────────────── */

/* Horizontal row dividers — 2 per row (top+bottom), full width, center-out reveal */
.our-work-line--horizontal {
    width: calc(100% + var(--pad-x) * 2);
    height: var(--guide-width);
    border-top: var(--guide-border);
    pointer-events: none;
    transform: scaleX(0);
    transform-origin: center center;
    transition: transform 0.6s var(--ease-out-expo);
    will-change: transform;
    margin-left: calc(-1 * var(--pad-x));
    margin-right: calc(-1 * var(--pad-x));
}

.our-work-line--horizontal.-revealed { transform: scaleX(1); }

/* Spread paired lines: line1 hugs row above, line2 hugs row below, gap between them */
.our-work-grid__row + .our-work-line--horizontal {
    margin-top: 0;                                  /* line sits right at row bottom edge */
}
.our-work-line--horizontal + .our-work-line--horizontal {
    margin-top: var(--ow-grid-gap);                 /* full gap between the two lines */
    margin-bottom: 0;                               /* line sits right at next row top edge */
}

/* Mobile-only CTA wrapper at the section's end — hidden by default,
   shown on mobile (see mobile media query for layout details). */
.ow-mobile-cta { display: none; }

/* Vertical dashed lines — absolute within .our-work-section so they
   span the section's full height (cards grid + spacer) and scroll out
   naturally as the section leaves viewport. Was previously
   position:fixed + 100vh, which caused them to overflow into the
   footer area and required a JS hide-on-leave. */
.our-work-vlines {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    z-index: 4;                     /* above bg, below cards (cards have no explicit z) */
    opacity: 0;
    transition: opacity 0.3s ease;
}

.our-work-vlines.-active { opacity: 1; }

.our-work-vline {
    position: absolute;
    top: 0;
    height: 100%;
    width: var(--guide-width);
    border-left: var(--guide-border);
    transform: scaleY(0);
    transform-origin: center center;
    transition: transform 0.8s var(--ease-out-expo);
    will-change: transform;
}

.our-work-vlines.-revealed .our-work-vline { transform: scaleY(1); }

.our-work-vline.-outer-left  { left: var(--pad-x); }
.our-work-vline.-outer-right { right: var(--pad-x); }
.our-work-vline.-inner-left  { left: calc(50vw - var(--ow-grid-gap) / 2 - var(--guide-width) / 2); }
.our-work-vline.-inner-right { left: calc(50vw + var(--ow-grid-gap) / 2 - var(--guide-width) / 2); }

/* ── TABLET (768-1023) ────────────────────────────────────── */
@media (min-width: 768px) and (max-width: 1023px) {
    :root { --ow-stack-pad: 4%; }
    .ow-word { font-size: clamp(56px, 12vw, 180px); }
}

/* ── MOBILE (< 768) ───────────────────────────────────────── */
@media (max-width: 767px) {
    :root { --ow-stack-pad: 4%; }

    /* Mobile: spacer keeps cards from sitting too close to the sticky
       "Selected Projects" bar at viewport top:10vh once formation
       completes. Words form via section-anchored positioning (see
       mobileWordsTopPx in JS), so the spacer is purely visual breathing
       room between the bar and the first card. */
    .our-work-spacer { height: 50vh; }

    .ow-word { font-size: clamp(48px, 16vw, 120px); }
    .ow-stack__title { font-size: clamp(20px, 5vw, 32px); }

    /* Clip the 40vw card slide-in so it never creates horizontal page overflow */
    .our-work-section { overflow-x: clip; }

    .our-work-grid {
        gap: var(--space-8);                 /* 40px between cards on mobile */
    }

    /* Rows stack as single-column grids; all 3 rows visible on mobile so
       each row's 2 stacked cards plus row 3's pair give the user a full
       6-card vertical run, each one sliding in independently as it
       enters viewport (see per-card ScrollTrigger in our-work-section.js). */
    .our-work-grid__row {
        grid-template-columns: 1fr;
        gap: var(--space-8);
    }

    /* No horizontal dashed lines on mobile — each card has a colored
       info-row footer below its image instead (see project-card.css). */
    .our-work-line--horizontal { display: none; }

    /* Mobile-only CTA between the last card and the closing dashed line.
       Centered .btn with breathing room above and below. Hidden on
       desktop (the sticky-bar button covers the desktop equivalent). */
    .ow-mobile-cta {
        display: flex;
        justify-content: center;
        padding: var(--space-9) 0 var(--space-9);
    }

    /* Edge-to-edge dashed line FLUSH against the last card's bottom
       edge (sits at .our-work-grid's box bottom, ABOVE the mobile CTA).
       Spans the full viewport width via 100vw + negative left offset
       so it ignores the grid's horizontal padding. Animates scaleX 0→1
       via .-end-line-revealed, toggled by JS when scrolled into view. */
    .our-work-grid::after {
        content: '';
        position: absolute;
        bottom: 0;
        left: calc(-1 * var(--pad-x));
        width: 100vw;
        height: var(--guide-width);
        border-top: var(--guide-border);
        transform: scaleX(0);
        transform-origin: center center;
        transition: transform 0.6s var(--ease-out-expo);
        will-change: transform;
        pointer-events: none;
    }
    .our-work-grid.-end-line-revealed::after {
        transform: scaleX(1);
    }

    .our-work-vline.-inner-left,
    .our-work-vline.-inner-right { display: none; }

    /* Mobile-specific Our Work header: words centered as a tight group with
       the dash icon between them. No desktop divider, no polaroid pair. */
    .ow-words {
        justify-content: center;
        gap: clamp(8px, 3vw, 24px);
        width: auto;
    }
    .ow-divider { display: none; }
    .ow-dash-center { display: none; }
    .ow-mobile-icon { display: block; }

    /* Sticky bar padding: override the desktop pad-x + ow-stack-pad sum
       (which compounds to ~8% on mobile because pad-x is already 4%).
       Keep just 2% on each side so "Selected Projects" + asterisk
       breathe at the viewport edges, not the section edges. */
    .ow-stack {
        left: 2%;
        right: 2%;
    }

    /* Hide the in-bar "Our Services" button on mobile — replaced by a
       full-size button at the end of the section (see .ow-mobile-cta). */
    .ow-stack__button { display: none !important; }
}
