/* TestimonialFilmReelBackground
   Diagonal, continuously-scrolling "film reel" strips built from real (approved)
   patient testimonial photos. Decorative background layer only - always sits
   behind foreground content via the .tfr-overlay + container z-index. Photos are
   clickable through to their full testimonial (see .tfr-frame pointer-events). */

.tfr-bg {
    position: absolute;
    inset: 0;
    overflow: hidden;
    z-index: 0;
    pointer-events: none;
    /* White canvas + thin black outline, like the rest of the site, instead of the
       dark cinematic backdrop this started as. The overlay wash below and the hero
       copy's text colors (set per-page, e.g. switch-to-weight-loss-agents.php's
       .wla-story / reel_widget.php's .tr-story) both flip to dark-on-light to match. */
    background: #fff;
    border: 2px solid #000;
    box-sizing: border-box;
}

.tfr-overlay {
    position: absolute;
    inset: 0;
    z-index: 3;
    /* Light wash (was a dark gradient) - mutes the reel photos enough for DARK hero
       text to read on top of a white canvas, same purpose as before, inverted tone. */
    background: linear-gradient(180deg, rgba(255,255,255,.82) 0%, rgba(255,255,255,.6) 45%, rgba(255,255,255,.85) 100%);
    opacity: .8;
    pointer-events: none; /* let clicks fall through to .tfr-frame links beneath it */
}

/* The belt is rotated ONCE, oversized well past the viewport on every side, so its
   corners always cover the container regardless of angle. Individual reels are just
   plain (unrotated) flex columns inside it - this is what fixes the black-triangle
   gaps/cutoff at the edges: previously each reel rotated itself individually and
   fell short of the corners at typical hero heights.
   Sizing math: for a centered rectangle W'xH' rotated by angle a to fully cover an
   axis-aligned WxH box, you need W' >= W*cos(a) + H*sin(a) and, critically,
   H' >= W*sin(a) + H*cos(a) - that second one scales with W (not H), so on a wide,
   short hero (common on desktop) the required H' can be several hundred percent of
   the section's own height. 240% was only safe up to roughly a 3:1 width:height
   hero; 500%/240% below comfortably covers ultra-wide monitors too. Also no gap
   between lanes - a visible empty channel the full belt height reads as a long
   diagonal "line" rather than film. */
.tfr-belt {
    position: absolute;
    top: 50%;
    left: 50%;
    /* Fallback only - testimonial-film-reel-background.js sets exact pixel width/height
       inline once it can measure the real container, which is also what it uses to
       decide how many lanes to build (see computeReelCount) - keep these two in sync
       if this fallback ever needs adjusting. */
    width: 240%;
    height: 500%;
    transform: translate3d(-50%, -50%, 0) rotate(var(--tfr-angle, -30deg));
    transform-origin: center center;
    display: flex;
    /* Must match computeReelCount()'s desiredGap in the JS - lane COUNT is chosen so
       reelCount lanes at (frame width + this gap) roughly fill the belt's real width,
       so this needs to be the actual rendered gap, not a guess (that mismatch, plus
       lanes stretching to fill an oversized belt via flex:1 1 0 regardless of actual
       content width, is what made spacing feel arbitrary - reported 2026-07-04:
       "lanes are too wide for the content they're holding"). */
    gap: 32px;
    z-index: 1;
}

.tfr-reel {
    /* Fixed width matching the frame's own outer width (200px image + 15px padding
       *2 + 3px border *2 - border tightened 6px -> 3px 2026-07-04, see .tfr-frame),
       NOT flex:1 1 0 - equal division of the belt's own (rotation-coverage-driven,
       often far wider than the viewport) width left each lane hundreds of pixels
       wider than its ~236px-wide content, with huge unpredictable slack on both
       sides instead of a deliberate, tight gap. Keep in sync with computeReelCount()'s
       frameOuterWidth in the JS if this ever changes again. */
    flex: 0 0 236px;
    height: 100%;
    position: relative;
    overflow: hidden;
}

.tfr-track {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    display: flex;
    flex-direction: column;
    /* align-items defaults to "stretch" - without this, each frame stretches to the
       full (wide) lane width while its fixed-size photo stays put on the left,
       leaving a big black dead zone to the right of every photo. Center instead. */
    align-items: center;
    /* No gap: a gap here shows as a white row between frames (the container's own white
       background peeking through), reported unwanted 2026-07-04 - two frames' own 6px
       black borders touching directly already reads as plenty of separation without it. */
    gap: 0;
    animation: tfr-scroll-up var(--tfr-speed, 50s) linear infinite;
    animation-delay: var(--tfr-delay, 0s);
    will-change: transform;
}

.tfr-reel[data-dir="down"] .tfr-track {
    animation-name: tfr-scroll-down;
}

/* Freeze the whole row while a tooltip in it is open, otherwise the link inside is a
   moving target - hovering/focusing any frame (or its popped-out tooltip, still a DOM
   descendant of the track) counts here since :hover bubbles up through ancestors. */
.tfr-track:hover,
.tfr-track:focus-within {
    animation-play-state: paused;
}

@keyframes tfr-scroll-up {
    from { transform: translate3d(0, 0, 0); }
    to   { transform: translate3d(0, -50%, 0); }
}

@keyframes tfr-scroll-down {
    from { transform: translate3d(0, -50%, 0); }
    to   { transform: translate3d(0, 0, 0); }
}

.tfr-frame {
    flex: 0 0 auto;
    position: relative;
    /* background and border MUST be the same value - a frame's own padding area
       (background) touching its own border ring used to show as two visibly different
       near-blacks (#000 vs #121110), a seam even within a single frame's margin. With
       .tfr-track's gap now 0 (frames touch directly), that mismatch plus the box-shadow
       below (a faint white hairline meant to read against a GAP, now doubling up at every
       frame-to-frame seam instead) combined into three visible bands where the two
       photos meet - reported 2026-07-04. One flat black, no box-shadow, and the seam is
       just one continuous color like real film stock. */
    background: #000;
    /* Border tightened 6px -> 3px (requested 2026-07-04, "too much black border between
       photos" - two touching frames' border+padding was stacking up to 24px of black
       between photos). Reducing this also shrinks the frame's total outer width, so
       .tfr-reel's flex-basis (236px) and computeReelCount()'s frameOuterWidth in the JS
       must stay in sync with this value - not just cosmetic on its own. */
    border: 3px solid #000;
    border-radius: 0; /* no rounded corners, requested 2026-07-04 */
    /* Vertical padding trimmed 11px -> 6px -> 4px (less black above/below the photo,
       requested 2026-07-04 twice); horizontal stays 15px - that's load-bearing clearance
       for the 9px sprocket-hole strip on each side (see the #home2026 override + hole
       rule below), not just cosmetic spacing, so don't shrink it to match. */
    padding: 4px 15px;
    pointer-events: auto; /* the only clickable island inside the otherwise inert background */
    cursor: pointer;
}

/* switch-to-weight-loss-agents.php wraps this shared component in #home2026, whose own
   home.css carries a blanket `#home2026 * { margin:0; padding:0 }` reset. That ID selector
   outranks the plain-class .tfr-frame rule above regardless of source order, silently
   zeroing the padding and letting the photo bleed to within ~1px of the sprocket-hole
   strip (reported 2026-07-04). Restate the same padding at matching ID+class specificity
   so it wins in that context too - reel_widget.php's pages have no such wrapper and were
   never affected, which is why the two pages looked different despite sharing one CSS file. */
#home2026 .tfr-frame {
    padding: 4px 15px; /* keep in sync with the plain .tfr-frame rule above */
}

/* Sprocket holes run along the two edges PARALLEL to the direction of travel (each
   reel scrolls vertically), same as a real filmstrip's perforated rails run along
   its length, not across each individual frame - and CRITICALLY, on .tfr-track (the
   element that actually scrolls), not on each .tfr-frame. They used to live on
   .tfr-frame, which meant the dot pattern (repeat-y, 18px pitch) restarted fresh at
   every single frame's own top edge. A frame's total height is essentially never an
   exact multiple of 18px, so the pattern got cut off mid-dot at each frame's bottom,
   then a new full dot began right after on the next frame - a visibly broken rhythm
   at every seam (a half-width "crescent" dot butting against a full one), reported
   2026-07-04 as "if this reel went into a machine, it would jam." Real film
   perforations are continuous along the whole strip, indifferent to frame content -
   putting the pattern on .tfr-track instead makes it one unbroken rhythm down the
   entire scrolling lane, regardless of where any individual frame starts or ends.
   Dots are LIGHT (not #000): the frame's own solid #000 background sits behind them
   at all times now (see the padding-fix history above), and black-on-black is
   invisible - same as real film, where the perforated rail is a lighter cutout in a
   darker border. */
.tfr-track::before,
.tfr-track::after {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    width: 9px;
    background-image: radial-gradient(circle, rgba(255,255,255,.55) 44%, transparent 46%);
    background-size: 9px 18px;
    background-repeat: repeat-y;
    background-position: center 5px;
    /* z-index so the dots paint above every .tfr-frame sibling regardless of DOM order -
       same reasoning as the old per-frame fix (generated-content paint order is not
       reliable on its own), just anchored to the track instead of each frame now. */
    z-index: 2;
}

/* Centered within the frame's own black margin (border + padding), not flush against the
   track's outer edge - the margin is 18px wide (3px border + 15px padding) and the dot
   column is 9px, so each side needs a (18-9)/2 = 4.5px inset to split the leftover space
   evenly instead of hugging the outer edge with all the slack on the photo side
   (reported 2026-07-04: "circles are slightly too close to the edge"). */
.tfr-track::before { left: 4.5px; }
.tfr-track::after { right: 4.5px; }

.tfr-frame a {
    /* The public thumbnail endpoint returns variable aspect ratios (e.g. 56x100,
       74x100), not a padded 100x100 square - fix the visible window to a set size
       and object-fit:cover on the img crops each photo to fill it completely. */
    display: block;
    position: relative;
    width: 200px;
    height: 240px;
    overflow: hidden;
    border-radius: 0; /* no rounded corners, requested 2026-07-04 - matches the frame above */
}

.tfr-frame img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    filter: grayscale(.15) sepia(.12) contrast(1.05);
    opacity: .82;
    transition: opacity .15s ease;
}

.tfr-frame:hover img,
.tfr-frame:focus-within img {
    opacity: 1;
}

/* Hover popout - appended to <body> by JS (testimonial-film-reel-background.js), NOT
   nested inside .tfr-frame. Every ancestor in the reel (.tfr-reel, .tfr-bg) uses
   overflow:hidden for the endless-scroll masking effect, which was clipping the top of a
   nested tooltip - its padding/title rendered outside the visible clip area (looked like
   missing margins, reported 2026-07-03). Living in <body> and positioned via
   getBoundingClientRect() sidesteps that entirely, so no counter-rotation is needed either
   (it's not inside the rotated belt/frame ancestry any more).
   position:absolute (not fixed) + scrollX/Y-adjusted coordinates (see the JS) - this
   tooltip tracks a point in scrollable page content, not the viewport, so it needs
   document-relative positioning. Fixed positioning was the actual bug behind the
   "tooltip shows up in a random spot on the page" report (2026-07-03). */
.tfr-tooltip {
    position: absolute;
    width: 220px;
    background: #fff;
    color: #1c1c1c;
    border-radius: 10px;
    padding: 13px 15px;
    font-size: .82rem;
    line-height: 1.45;
    box-shadow: 0 12px 32px rgba(0,0,0,.4);
    opacity: 0;
    visibility: hidden;
    transition: opacity .15s ease, visibility .15s ease;
    pointer-events: none;
    text-align: left;
    z-index: 60;
}

.tfr-tooltip.is-visible {
    opacity: 1;
    visibility: visible;
}

.tfr-tooltip .tfr-title {
    display: block;
    margin-bottom: 4px;
    font-size: .88rem;
    color: #10202E;
}

.tfr-tooltip .tfr-cta {
    display: block;
    margin-top: 8px;
    font-weight: 700;
    font-size: .76rem;
    letter-spacing: .01em;
    color: #F0584C;
}

/* Static fallback for prefers-reduced-motion: freeze frame, no motion at all */
.tfr-bg.tfr-static .tfr-track {
    animation: none !important;
    transform: translate3d(0, -18%, 0);
}

@media (prefers-reduced-motion: reduce) {
    .tfr-track {
        animation: none !important;
        transform: translate3d(0, -18%, 0);
    }
}

/* Mobile: fewer, smaller, calmer strips (reel count itself is also reduced in JS) */
@media (max-width: 768px) {
    /* Lane count itself is now decided in JS (computeReelCount, mobile branch) to
       match the belt's real width - no CSS-side hiding needed any more. */
    .tfr-belt {
        gap: 18px;
    }
    .tfr-reel {
        flex: 0 0 137px; /* matches .tfr-frame a 115px + padding 9px*2 + border 2px*2 below */
    }
    .tfr-frame {
        border-width: 2px; /* tightened 4px -> 2px, matches desktop's 6px -> 3px trim */
        padding: 4px 9px; /* vertical trimmed 7px -> 4px, matches desktop's 11px -> 6px -> 4px trim */
    }
    #home2026 .tfr-frame {
        padding: 4px 9px; /* same #home2026-reset override as the desktop rule above */
    }
    /* Mobile's black margin is narrower (2px border + 9px padding = 11px vs desktop's
       18px), so the same 9px dot column only leaves (11-9)/2 = 1px to center with. */
    .tfr-track::before { left: 1px; }
    .tfr-track::after { right: 1px; }
    .tfr-frame a {
        width: 115px;
        height: 140px;
    }
    .tfr-tooltip {
        display: none; /* hover has no meaning on touch; tap navigates straight through */
    }
    .tfr-overlay {
        opacity: .78;
    }
}
