{"version":3,"file":"ProjectCard.DJO2Vcsv.mjs","names":["useState","useRef"],"sources":["https:/framerusercontent.com/modules/4FYfST3M46ae6ppupJzD/JwiYEVqa2Xj5gNNAgqhR/ProjectCard.js"],"sourcesContent":["import{jsx as _jsx}from\"react/jsx-runtime\";import{useState,useRef,useEffect}from\"react\";import{motion,useAnimation}from\"framer-motion\";import{addPropertyControls,ControlType}from\"framer\";import{GlassSlab,slabControls,frontImageStyle,REF_WIDTH}from\"https://framerusercontent.com/modules/kMMYS8UBn6GnLD47s0s6/mZEJfAiAlBcV8CfovcS0/GlassSlab.js\";export default function ProjectCard({image=null,link=\"\",cardThickness=25,borderWidth=5,borderTint=\"#ffffff\",borderOpacity=1,borderGrain=0,edgeTint=\"#ffffff\",edgeOpacity=.35,edgeGrain=.28,lightContrast=.6,edgeLines=.5,edgeLineTint=\"#ffffff\",shadowIntensity=1,cornerReveal=true,tiltX=0,tiltY=0,tiltZ=0,wiggleAngle=22,wiggleSpeed=2.2,wigglePause=.3,mobileMode=false}){const[isHovered,setIsHovered]=useState(false);const spinControls=useAnimation();// isTouchMode is controlled entirely by the mobileMode prop.\n// In Framer, set Mobile Mode = on for your tablet and phone\n// breakpoint variants of this page — Framer handles the rest.\nconst isTouchMode=mobileMode;// Measure the real rendered width and derive the scale factor from the\n// 350px reference, so thickness/border/lift/shadow stay proportional.\nconst containerRef=useRef(null);const[measuredW,setMeasuredW]=useState(REF_WIDTH);useEffect(()=>{if(!containerRef.current)return;const ro=new ResizeObserver(([entry])=>{const w=entry.contentRect.width;if(w)setMeasuredW(w);});ro.observe(containerRef.current);return()=>ro.disconnect();},[]);const scale=measuredW/REF_WIDTH;const handleHoverStart=()=>{if(isTouchMode)return;setIsHovered(true);spinControls.start({rotateY:[0,-wiggleAngle,wiggleAngle,-wiggleAngle,wiggleAngle,0],transition:{duration:wiggleSpeed,ease:\"easeInOut\",repeat:Infinity,repeatDelay:wigglePause}});};const handleHoverEnd=()=>{if(isTouchMode)return;setIsHovered(false);spinControls.start({rotateY:0,transition:{duration:.5,ease:\"easeOut\"}});};const handleClick=()=>{if(link)window.location.href=link;};return(/*\n         * Tilt wrapper: static isometric orientation — match tiltX/Y/Z\n         * to whatever values you have set in the carousel.\n         * The spin animation plays on the inner motion.div independently.\n         *//*#__PURE__*/_jsx(\"div\",{ref:containerRef,style:{width:\"100%\",height:\"100%\",// overflow: visible lets the lift animate past the component's\n// own boundary — the Stack frame above becomes the actual mask\noverflow:\"visible\",// Re-establish the 3D context in case a Stack parent flattened it\ntransformStyle:\"preserve-3d\",transform:`rotateX(${tiltX}deg) rotateY(${tiltY}deg) rotateZ(${tiltZ}deg)`},children:/*#__PURE__*/_jsx(motion.div,{animate:spinControls,onHoverStart:handleHoverStart,onHoverEnd:handleHoverEnd,onClick:handleClick,style:{width:\"100%\",height:\"100%\",position:\"relative\",cursor:link?\"pointer\":\"default\",transformStyle:\"preserve-3d\",WebkitTapHighlightColor:\"transparent\",userSelect:\"none\",overflow:\"visible\"},children:/*#__PURE__*/_jsx(GlassSlab,{scale:scale,cardThickness:cardThickness,borderWidth:borderWidth,borderTint:borderTint,borderOpacity:borderOpacity,borderGrain:borderGrain,edgeTint:edgeTint,edgeOpacity:edgeOpacity,edgeGrain:edgeGrain,lightContrast:lightContrast,edgeLines:edgeLines,edgeLineTint:edgeLineTint,shadowIntensity:shadowIntensity,cornerReveal:cornerReveal,lift:isHovered?28*scale:0,isHovered:isHovered,children:image?/*#__PURE__*/_jsx(\"img\",{src:image,draggable:false,style:frontImageStyle}):/*#__PURE__*/_jsx(\"div\",{style:{width:\"100%\",height:\"100%\",background:\"#d0d0d0\",display:\"flex\",alignItems:\"center\",justifyContent:\"center\",color:\"#888\",fontSize:13,fontFamily:\"sans-serif\",letterSpacing:\"0.05em\"},children:\"Add image\"})})})}));}addPropertyControls(ProjectCard,{image:{type:ControlType.Image,title:\"Image\"},link:{type:ControlType.Link,title:\"Home Link\"},mobileMode:{type:ControlType.Boolean,title:\"Mobile Mode\",defaultValue:false,description:\"Force touch behaviour — auto-detected from screen width normally\"},// Shared cube controls — single source of truth in GlassSlab.jsx\n...slabControls,tiltX:{type:ControlType.Number,title:\"Tilt X\",defaultValue:0,min:-60,max:60,step:1},tiltY:{type:ControlType.Number,title:\"Tilt Y\",defaultValue:0,min:-60,max:60,step:1},tiltZ:{type:ControlType.Number,title:\"Tilt Z\",defaultValue:0,min:-45,max:45,step:1},wiggleAngle:{type:ControlType.Number,title:\"Wiggle Angle\",defaultValue:22,min:1,max:60,step:1,displayStepper:false,description:\"How far the card swings left and right\"},wiggleSpeed:{type:ControlType.Number,title:\"Wiggle Speed\",defaultValue:2.2,min:.4,max:6,step:.1,displayStepper:false,description:\"Duration of one full wiggle cycle in seconds\"},wigglePause:{type:ControlType.Number,title:\"Wiggle Pause\",defaultValue:.3,min:0,max:3,step:.1,displayStepper:false,description:\"Pause between wiggle cycles in seconds\"}});\nexport const __FramerMetadata__ = {\"exports\":{\"default\":{\"type\":\"reactComponent\",\"name\":\"ProjectCard\",\"slots\":[],\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}"],"mappings":"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"}