/* ============================================================================
   RAC DCP — 3D CINEMATIC MOTION & CAMERA STYLING LAYER
   ============================================================================
   
   WHAT THIS FILE DOES:
   This stylesheet powers all the 3D depth, perspective, and cinematic camera
   effects on the website when viewed on desktop and high-performance screens.
   
   HOW IT IS STRUCTURED:
   1. It is loaded AFTER `style.css`.
   2. Every single rule is safely scoped under `html.motion-on`.
      - On high-end computers: `html.motion-on` is added by motion.js, activating 3D.
      - On phones, battery-saver mode, or low-spec computers: `html.motion-off` is used,
        meaning the website looks clean, fast, and uses standard web layout with
        zero performance lag!
   ============================================================================ */


/* ============================================================================
   0. ENGINE PREREQUISITES & CONFLICT PREVENTION
   ============================================================================ */

/* 
 * 1. Disable browser's native smooth-scroll:
 * style.css has `scroll-behavior: smooth`. If the browser tries to animate
 * scrolling while our JavaScript physics engine is also calculating 60 smooth frames
 * per second, they will fight each other and cause jittery stuttering.
 * Setting `scroll-behavior: auto` gives full smooth control to the JS engine.
 */
html.motion-on {
    scroll-behavior: auto;
}

/* 
 * 2. Offset anchor links:
 * When you click a link like "#about" or "#projects", this ensures the section
 * heading stops 94px below the top of the screen so it isn't hidden under
 * our fixed 78px navigation bar.
 */
html.motion-on [id] {
    scroll-margin-top: 94px;
}

/* 
 * 3. Prevent page layout shifting when popups open:
 * When a modal lightbox opens, the page scrollbar disappears. Adding this
 * custom padding variable (--sbw = scrollbar width) prevents the entire webpage
 * from abruptly jumping or shifting to the right.
 */
html.motion-on body.lightbox-open {
    padding-right: var(--sbw, 0px);
}

/* 
 * 4. Remove conflicting CSS transitions during fast scrolling:
 * During rapid scrolling, JS dynamically tilts cards. We neutralize any slow CSS
 * transform transitions so cards tilt instantaneously and cleanly without smearing.
 */
html.motion-on .scroll-velocity-active .project-card,
html.motion-on .scroll-velocity-active .board-card,
html.motion-on .scroll-velocity-active .achievement-card,
html.motion-on .scroll-velocity-active .publication-card {
    transition: box-shadow .35s ease, border-color .35s ease !important;
}


/* ============================================================================
   1. UNLOCKING REAL 3D Z-DEPTH
   ============================================================================
   IMPORTANT BROWSER RULE:
   In CSS 3D graphics, if a parent card has `overflow: hidden`, the browser
   flattens all 3D layers onto a single flat 2D plane (destroying transform-style: preserve-3d).
   
   SOLUTION:
   We set `overflow: visible` on the outer card so its text and badges can pop
   forward in real 3D space toward the screen (translateZ), and we move the rounded
   corner image cropping down into the inner image containers instead!
   ============================================================================ */

/* Allow cards to project elements outwards in 3D */
html.motion-on .impact-card,
html.motion-on .project-card,
html.motion-on .achievement-card,
html.motion-on .board-card,
html.motion-on .people-card,
html.motion-on .event-card,
html.motion-on .gallery-item {
    overflow: visible;
}

/* Maintain rounded top corners on the inner image containers */
html.motion-on .project-image     { border-radius: 20px 20px 0 0; }   /* Top-left & top-right rounded */
html.motion-on .achievement-image { border-radius: 20px 20px 0 0; }   /* Top-left & top-right rounded */
html.motion-on .people-photo      { border-radius: 14px 14px 0 0; }   /* Top-left & top-right rounded */
html.motion-on .event-poster      { border-radius: 18px 0 0 18px; }   /* Left corners rounded */

/* Member photos need both overflow hidden and rounded corners */
html.motion-on .member-photo {
    overflow: hidden;
    border-radius: 20px 20px 0 0;
}

/* Gallery images: Fill their container smoothly with rounded corners */
html.motion-on .gallery-item img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: 16px;
    display: block;
}

/* 
 * Hero Section 3D Viewport:
 * Gives the hero section a 1500px camera perspective so 3D elements
 * appear natural to the human eye (items closer look bigger, items further look smaller).
 */
html.motion-on .hero {
    overflow: clip; /* Keeps background gradients contained without creating an unwanted scrollbar */
    perspective: 1500px;
    perspective-origin: 50% 40%;
}


/* ============================================================================
   2. 3D COMPOSITOR SURFACES & CARD TILTS
   ============================================================================ */

/*
 * Enable 3D rendering context on all interactive cards.
 * We transition box-shadow, borders, and colors with CSS, but leave
 * the `transform` property to JavaScript so there is zero animation lag or smearing.
 */
html.motion-on .project-card,
html.motion-on .board-card,
html.motion-on .achievement-card,
html.motion-on .publication-card,
html.motion-on .contact-card,
html.motion-on .impact-card,
html.motion-on .website-creator-card,
html.motion-on .gallery-item,
html.motion-on .people-card,
html.motion-on .event-card,
html.motion-on .rebel-menu-card,
html.motion-on .join-highlight {
    transform-style: preserve-3d;
    transition: box-shadow .35s cubic-bezier(.2, 0, .2, 1),
                border-color .35s ease,
                background-color .35s ease;
}

/*
 * DISABLE CSS HOVER LIFTS:
 * Normally in simple CSS, `:hover` does `transform: translateY(-8px)`.
 * However, our JavaScript engine (motion.js) calculates interactive 3D mouse tilt,
 * spring physics, and lift dynamically on every frame.
 * Setting `transform: none` here stops CSS from fighting JavaScript, allowing
 * the smooth mouse-tracking tilt to work flawlessly!
 */
html.motion-on .project-card:hover,
html.motion-on .board-card:hover,
html.motion-on .achievement-card:hover,
html.motion-on .publication-card:hover,
html.motion-on .contact-card:hover,
html.motion-on .impact-card:hover,
html.motion-on .website-creator-card:hover,
html.motion-on .gallery-item:hover,
html.motion-on .people-card:hover,
html.motion-on .event-card:hover,
html.motion-on .rebel-menu-card:hover,
html.motion-on .join-highlight:hover {
    transform: none;
}

/*
 * PARALLAX DEPTH LAYERS (Floating elements inside the card):
 * Because we enabled `preserve-3d`, these elements physically float forward
 * toward the viewer in 3D space!
 * - Large impact stats float 58px above the card surface!
 * - Text descriptions float 34px above the card!
 * When the user moves their mouse and the card tilts, these layers shift at
 * different speeds, creating a stunning holographic depth effect.
 */
html.motion-on .impact-number        { transform: translateZ(58px); }
html.motion-on .impact-label         { transform: translateZ(30px); }
html.motion-on .project-content,
html.motion-on .achievement-content  { transform: translateZ(34px); }
html.motion-on .member-info,
html.motion-on .people-info          { transform: translateZ(26px); }

/*
 * SPECULAR LIGHT GLARE:
 * A semi-transparent glossy reflection placed over the card.
 * motion.js tracks the mouse cursor and moves a radial spotlight gradient
 * across this layer, giving cards a premium glass/metallic sheen.
 */
html.motion-on .card-glare {
    position: absolute;
    inset: 0;
    border-radius: inherit;
    opacity: 0;
    pointer-events: none; /* Allows mouse clicks to pass through to the card buttons */
    transition: opacity .3s ease;
    mix-blend-mode: overlay; /* Blends naturally with the card image/colors */
    z-index: 10;
}


/* ============================================================================
   3. CINEMATIC SPLIT-TEXT HEADINGS
   ============================================================================
   Breaks headings into individual words wrapped in invisible masks (.mw).
   Each word (.mwi) starts tilted downward by -78 degrees and slides up smoothly
   into view, giving a movie-title reveal effect as you scroll.
   ============================================================================ */

/* The outer word mask (clips the word while it is hidden below) */
html.motion-on .mw {
    display: inline-block;
    overflow: hidden;
    vertical-align: top;
    padding-bottom: .16em;   /* Extra bottom space so letters like 'g', 'y', 'p' don't get cut off */
    margin-bottom: -.16em;
}

/* The inner word: starts tilted down in 3D and transparent */
html.motion-on .mwi {
    display: inline-block;
    transform: perspective(700px) rotateX(-78deg) translateY(110%);
    opacity: 0;
    transition: transform .78s cubic-bezier(.16, 1, .3, 1),
                opacity .55s cubic-bezier(.16, 1, .3, 1);
}

/* When the word enters the viewport, animate it to upright position */
html.motion-on .mw.is-in .mwi {
    transform: perspective(700px) rotateX(0deg) translateY(0);
    opacity: 1;
}

/* When a hero slider changes, old words tilt upward and fade out */
html.motion-on .mw.is-out .mwi {
    transform: perspective(700px) rotateX(52deg) translateY(-95%);
    opacity: 0;
    transition: transform .34s cubic-bezier(.4, 0, 1, 1),
                opacity .28s ease;
}

/* Hero Carousel Slide cross-fade timings */
html.motion-on .hero-slide,
html.motion-on .hero-slide.active {
    transform: none;
}

html.motion-on .hero-slide {
    opacity: 0;
    transition: opacity .16s ease-out;
}

html.motion-on .hero-slide.active {
    opacity: 1;
    transition: opacity .34s ease-in .06s;
}


/* ============================================================================
   4. ODOMETER NUMBER COUNTERS (SLOT-MACHINE DIGITS)
   ============================================================================
   Replaces static numbers with rolling mechanical odometer columns.
   Each digit is stacked in a vertical column (0 through 9) that rolls
   upward like a classic slot machine or car mileage gauge!
   ============================================================================ */

/* The outer odometer container with 3D tilt */
html.motion-on .odo {
    display: inline-flex;
    align-items: flex-end;
    transform: perspective(900px) rotateX(-58deg);
    opacity: 0;
    transform-origin: 50% 100%;
    transition: transform .85s cubic-bezier(.16, 1, .3, 1),
                opacity .5s ease;
}

html.motion-on .odo.is-in {
    transform: perspective(900px) rotateX(0deg);
    opacity: 1;
}

/* A single digit column: hides all numbers except the current one visible in the 1em box */
html.motion-on .odo-col {
    height: 1em;
    line-height: 1;
    overflow: hidden;
    display: inline-block;
}

/* The vertical strip of digits 0 through 9 */
html.motion-on .odo-strip {
    display: block;
    transform: translateY(0em);
    will-change: transform;
}

/* When spinning to target number, smoothly slide the strip upward */
html.motion-on .odo.is-rolling .odo-strip {
    transition: transform var(--odo-dur, 2s) cubic-bezier(.17, .84, .34, 1);
}

/* Individual digit box */
html.motion-on .odo-digit {
    display: block;
    height: 1em;
    line-height: 1;
}

/* Separator symbols like commas or plus signs */
html.motion-on .odo-sep {
    display: inline-block;
    line-height: 1;
}


/* ============================================================================
   5. SITE CHROME & CSS CUSTOM PROPERTY BRIDGE
   ============================================================================
   These elements already have running CSS keyframe animations.
   To avoid conflicts between CSS animations and JavaScript:
     - JavaScript ONLY updates CSS variables (like --mx, --my, --wheel-rot).
     - CSS animations use these variables inside their `transform` property.
   This guarantees 100% smooth 60fps animations with zero stutter!
   ============================================================================ */

/* Ambient Glowing Background Orbs */
@keyframes motionOrbFloat1 {
    0%   { transform: translate3d(var(--mx, 0px), var(--my, 0px), 0) translate(0, 0) scale(1); }
    100% { transform: translate3d(var(--mx, 0px), var(--my, 0px), 0) translate(-60px, 80px) scale(1.1); }
}
@keyframes motionOrbFloat2 {
    0%   { transform: translate3d(var(--mx, 0px), var(--my, 0px), 0) translate(0, 0) scale(1); }
    100% { transform: translate3d(var(--mx, 0px), var(--my, 0px), 0) translate(75px, -65px) scale(1.12); }
}
html.motion-on .ambient-orb-1 {
    animation: motionOrbFloat1 20s ease-in-out infinite alternate;
    filter: blur(74px);
}
html.motion-on .ambient-orb-2 {
    animation: motionOrbFloat2 24s ease-in-out infinite alternate;
    filter: blur(74px);
}

/* Back-to-Top Circular Dial (bottom right corner) */
html.motion-on .scroll-top-dial {
    transform: translateY(var(--dy, 20px))
               scale(var(--ds, .85))
               rotateX(var(--drx, 0deg))
               rotateY(var(--dry, 0deg));
    transform-style: preserve-3d;
}
html.motion-on .scroll-top-dial.visible { --dy: 0px;  --ds: 1; }
html.motion-on .scroll-top-dial:hover   { --dy: -4px; --ds: 1.08; }

/* Floating Section Minimap (right screen edge) */
html.motion-on .section-minimap {
    transform: translateY(-50%)
               perspective(600px)
               rotateY(var(--mmry, 0deg))
               translateZ(var(--mmz, 0px));
}
html.motion-on .minimap-dot {
    transform-style: preserve-3d;
}

/* Floating Notification Widget */
@keyframes motionFloatWidget {
    0%, 100% { transform: translateY(0) scale(1)
                          rotateY(var(--nry, 0deg)) translateZ(var(--nz, 0px)); }
    50%      { transform: translateY(-8px) scale(1.04)
                          rotateY(var(--nry, 0deg)) translateZ(var(--nz, 0px)); }
}
html.motion-on .notification-button {
    animation: motionFloatWidget 3.5s ease-in-out infinite;
}
html.motion-on .notification-panel {
    transform: perspective(1200px) rotateX(-14deg) translateY(20px) scale(.94);
    transform-origin: 100% 100%;
}
html.motion-on .notification-panel.active {
    transform: perspective(1200px) rotateX(0deg) translateY(0) scale(1);
}

/* Fixed Navigation Bar Scroll Shadow */
html.motion-on .navbar {
    transition: box-shadow .3s ease, background-color .3s ease;
}
html.motion-on .navbar.is-scrolled {
    box-shadow: 0 8px 25px rgba(0, 0, 0, .08);
}


/* ============================================================================
   6. INTRO ENTRANCE CASCADE
   ============================================================================
   Plays once when the site preloader finishes counting up to 100%.
   The navigation bar smoothly slides down from the top in 3D.
   ============================================================================ */

html.motion-on.motion-intro .navbar {
    animation: motionNavDrop .95s cubic-bezier(.16, 1, .3, 1) both;
}
@keyframes motionNavDrop {
    from { transform: translateY(-100%) rotateX(-34deg); opacity: 0; }
    to   { transform: translateY(0) rotateX(0deg); opacity: 1; }
}

html.motion-on.motion-intro .ambient-orb {
    animation-delay: .1s;
}


/* ============================================================================
   7. ACCESSIBILITY: REDUCED MOTION SAFEGUARD
   ============================================================================
   If the user has enabled "Reduce Motion" in their Windows / macOS / iOS
   settings, we immediately turn off all heavy 3D camera animations and
   flying effects to prevent motion sickness or dizziness.
   ============================================================================ */

@media (prefers-reduced-motion: reduce) {
    html.motion-on .mw  { overflow: visible; }
    html.motion-on .mwi {
        transform: none !important;
        opacity: 1 !important;
        transition: none !important;
    }

    html.motion-on .odo { display: none; }

    html.motion-on .ambient-orb-1,
    html.motion-on .ambient-orb-2,
    html.motion-on .notification-button {
        animation: none !important;
    }

    html.motion-on.motion-intro .navbar {
        animation: none !important;
    }

    html.motion-on .hero-slide,
    html.motion-on .hero-slide.active {
        transition: none !important;
    }
}


/* ============================================================================
   8. TOUCH & SMALL SCREEN PERFORMANCE OPTIMIZATION
   ============================================================================ */

@media (max-width: 1024px) {
    /* Hide the second blurred background orb on tablets/mobile to save battery and GPU */
    html.motion-on .ambient-orb-2 { display: none; }
}


/* ============================================================================
   SCROLL SCENE 1 — 3D PROJECT CAMERA FLY-THROUGH
   ============================================================================
   As you scroll through the Projects section, the project cards appear as if
   you are flying through a 3D corridor in space. Cards float past the camera!
   
   If 3D is disabled (touch screens, reduced motion, small screens), the container
   reverts to `display: contents` so it renders as the standard, clean grid!
   ============================================================================ */

.fly-track,
.fly-stage {
    display: contents; /* Inactive by default: zero layout interference */
}

/* Active 3D Fly-through Corridor */
html.fly-on .fly-track {
    display: block;
    position: relative;
    height: var(--fly-h, 400vh); /* The virtual track distance for scrolling */
}

/* Soft dark vignette so card text is easily readable */
html.fly-on .fly-stage::before {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: radial-gradient(ellipse at 50% 46%,
                rgba(11, 46, 33, 0) 34%, rgba(11, 46, 33, 0.07) 100%);
}

/* The fixed 3D camera viewport */
html.fly-on .fly-stage {
    display: block;
    position: sticky;
    top: 0;
    height: 100vh;
    overflow: hidden;
    perspective: 1000px;
    perspective-origin: 50% 46%;
}

html.fly-on .fly-stage .project-grid {
    position: absolute;
    inset: 0;
    display: block;
    transform-style: preserve-3d;
}

html.fly-on .fly-stage .project-card {
    position: absolute;
    left: 50%;
    top: 50%;
    width: min(430px, 82vw);
    margin: 0;
    will-change: transform, opacity;
    backface-visibility: hidden;
}

/* Project fly-through progress badge at the bottom of the screen */
html.fly-on .fly-counter {
    position: absolute;
    left: 50%;
    bottom: 38px;
    transform: translateX(-50%);
    z-index: 5;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 18px;
    border-radius: 9999px;
    background: rgba(11, 46, 33, 0.72);
    backdrop-filter: blur(10px);
    border: 1px solid rgba(52, 211, 153, 0.3);
    color: #d1fae5;
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.08em;
}

html.fly-on .fly-counter .fly-bar {
    width: 86px;
    height: 3px;
    border-radius: 2px;
    background: rgba(255, 255, 255, 0.2);
    overflow: hidden;
}

html.fly-on .fly-counter .fly-bar i {
    display: block;
    height: 100%;
    width: var(--fly-p, 0%);
    background: #34d399;
}

.fly-counter { display: none; }


/* ============================================================================
   GEARED ROTARY WHEEL
   ============================================================================
   The Rotary gear emblem inside the back-to-top dial physically spins in sync
   with how far the user has scrolled down the page!
   ============================================================================ */

.rotary-gear {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 30px;
    height: 30px;
    margin: -15px 0 0 -15px;
    pointer-events: none;
    transform: rotate(var(--wheel-rot, 0deg)); /* Rotated smoothly by motion.js */
    color: var(--emerald-text, #067a52);
    opacity: 0.9;
}

html.motion-on .scroll-top-dial .dial-arrow {
    transition: opacity .25s ease, transform .2s ease;
}

/* The arrow fades in when hovered; the Rotary wheel is the resting state */
html.motion-on .scroll-top-dial .dial-arrow { opacity: 0; }
html.motion-on .scroll-top-dial:hover .dial-arrow { opacity: 1; }
html.motion-on .scroll-top-dial:hover .rotary-gear { opacity: 0.18; }
html.motion-on .scroll-top-dial:focus-visible .dial-arrow { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
    .rotary-gear { transform: none !important; }
    html.motion-on .scroll-top-dial .dial-arrow { opacity: 1; }
    html.motion-on .scroll-top-dial .rotary-gear { opacity: 0.18; }
}


/* ============================================================================
   SCROLL SCENE 2 — SIDEWAYS PHOTO GALLERY RAIL
   ============================================================================
   Instead of stacking 70+ gallery photos vertically down an endless page,
   the gallery locks into place and glides smoothly horizontally as you scroll!
   Organized into two compact rows.
   ============================================================================ */

.rail-track,
.rail-stage {
    display: contents;
}

html.rail-on .rail-track {
    display: block;
    position: relative;
    height: var(--rail-h, 400vh);
}

html.rail-on .rail-stage {
    display: block;
    position: sticky;
    top: 0;
    height: 100vh;
    overflow: hidden;
    display: flex;
    align-items: center;
}

html.rail-on .rail-stage .gallery-grid {
    display: grid;
    grid-auto-flow: column;
    grid-template-columns: none;
    grid-template-rows: repeat(2, 232px);
    grid-auto-columns: 300px;
    gap: 18px;
    width: max-content;
    padding: 0 6vw;
    will-change: transform;
}

html.rail-on .rail-stage .gallery-item {
    aspect-ratio: auto;
    height: 232px;
}


/* ============================================================================
   SCROLL SCENE 3 — AWARDS STACKING DECK
   ============================================================================
   As the user scrolls down through club achievements and awards, each award card
   sticks to the top and stacks like a physical deck of cards!
   ============================================================================ */

html.stack-on .achievement-grid.is-deck {
    display: block !important;
    grid-template-columns: none !important;
    max-width: 680px;
    margin-inline: auto;
}

html.stack-on .achievement-grid.is-deck .achievement-card {
    position: sticky;
    top: calc(96px + var(--deck-i, 0) * 14px); /* Staggered stacking offset */
    display: grid;
    grid-template-columns: 150px 1fr;
    align-items: center;
    gap: 20px;
    height: 132px;
    margin: 0 0 26px;
    overflow: hidden;
    will-change: transform;
}

html.stack-on .achievement-grid.is-deck .achievement-image {
    height: 132px;
    aspect-ratio: auto;
    border-radius: 20px 0 0 20px;
}

html.stack-on .achievement-grid.is-deck .achievement-content {
    padding: 0 22px 0 0;
    transform: none;
}

html.stack-on .achievement-grid.is-deck .achievement-content h4 {
    font-size: 0.98rem;
    line-height: 1.3;
}


/* ============================================================================
   SCROLL SCENE 4 — HERO BACKDROP ZOOM-THROUGH
   ============================================================================
   Scrolling down past the hero gently travels *into* the hero photography
   background rather than sliding it away, providing cinematic scale.
   ============================================================================ */

html.herozoom-on .hero-backdrop {
    will-change: transform, opacity;
}
