PageSourceSearch

https://sodam-portfolio.vercel.app/_next/static/immutable/chunks/0124k4sh9okst.js

js sodam-portfolio.vercel.app collected 2026-10-03 07:46:17 UTC 73,463 bytes, 2 lines download raw bytes

1(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,769614,e=>{"use strict";var t=e.i(289978),a=e.i(408317),i=e.i(352387),s=e.i(166712),o=e.i(290551),l=e.i(607873),r=e.i(205132),n=e.i(139368),n=n;function c({project:e,youtubeId:a,primaryLink:i,primaryLinkLabel:s,PrimaryLinkIcon:o,ytRatioStr:l,ytRatioFloat:d,nativeMediaStyle:p,nativeMediaClasses:u,setSelectedMedia:h}){if(a)return(0,t.jsx)("div",{className:"w-full flex justify-center items-center",children:(0,t.jsx)("iframe",{src:`https://www.youtube.com/embed/${a}?autoplay=0&muted=0`,className:"rounded-2xl shadow-2xl border border-white/5",style:{aspectRatio:l,maxWidth:`calc(70vh * ${d})`,maxHeight:"70vh",width:"100%"},allowFullScreen:!0,title:e.title})});if(e.videoUrl&&!a)return(0,t.jsxs)("div",{className:"w-full flex justify-center items-center group relative cursor-pointer",children:[(0,t.jsx)("video",{src:e.videoUrl,className:"rounded-2xl shadow-2xl border border-white/5 object-contain",style:p,controls:!0,autoPlay:!0,muted:!0,loop:!0,playsInline:!0}),(0,t.jsx)("button",{onClick:()=>h({url:e.videoUrl,type:"video"}),className:"absolute top-4 right-4 z-10 p-3 rounded-full bg-black/60 backdrop-blur-md border border-white/10 text-white/70 hover:text-white hover:bg-black/80 transition-all opacity-0 group-hover:opacity-100 shadow-xl",title:"Expand Video",children:(0,t.jsx)(n.default,{className:"w-5 h-5"})})]});let m=(0,r.getThumbnailUrl)(e);return m?(0,t.jsxs)("button",{type:"button",className:"w-full flex justify-center items-center group cursor-pointer relative border-none bg-transparent p-0 outline-none","aria-label":`${e.title} 상세보기`,onClick:()=>{i?window.open(i,"_blank","noopener,noreferrer"):h({url:m,type:"image"})},onKeyDown:e=>{("Enter"===e.key||" "===e.key)&&(e.preventDefault(),i?window.open(i,"_blank","noopener,noreferrer"):h({url:m,type:"image"}))},children:[(0,t.jsx)("img",{src:m,alt:e.title,className:u,style:p}),i?(0,t.jsx)("div",{className:"absolute inset-0 m-auto flex items-center justify-center rounded-2xl bg-black/40 opacity-0 group-hover:opacity-100 transition-opacity duration-500",style:p,children:(0,t.jsxs)("div",{className:"flex items-center gap-3 px-8 py-4 rounded-full bg-white text-black font-black uppercase tracking-widest hover:scale-105 transition-transform shadow-2xl",children:[s,(0,t.jsx)(o,{className:"w-5 h-5"})]})}):(0,t.jsx)("div",{className:"absolute top-4 right-4 z-10 p-3 rounded-full bg-black/60 backdrop-blur-md border border-white/10 text-white/70 hover:text-white hover:bg-black/80 transition-all opacity-0 group-hover:opacity-100 shadow-xl",children:(0,t.jsx)(n.default,{className:"w-5 h-5"})})]}):null}var d=e.i(780728),p=e.i(349684),p=p,u=e.i(722863),u=u,h=e.i(594986);function m({category:e}){return(0,t.jsx)("nav",{className:"fixed top-0 left-0 w-full z-50 px-6 py-6 pointer-events-none",children:(0,t.jsxs)("div",{className:"container mx-auto flex justify-between items-center pointer-events-auto",children:[(0,t.jsxs)(d.default,{href:`/work?category=${encodeURIComponent(e)}`,className:"flex items-center gap-4 px-6 py-3 rounded-full bg-white/5 backdrop-blur-2xl border border-white/10 text-sm font-black uppercase tracking-[0.2em] text-white/70 hover:text-white hover:bg-white/10 hover:border-white/20 transition-all group shadow-2xl",children:[(0,t.jsx)(p.default,{className:"w-5 h-5 group-hover:-translate-x-2 transition-transform duration-500"}),(0,t.jsx)("span",{className:"hidden sm:inline",children:"Back to Archive"}),(0,t.jsx)("span",{className:"sm:hidden",children:"Work"})]}),(0,t.jsxs)("div",{className:"flex items-center gap-4",children:[(0,t.jsx)("div",{className:"hidden md:flex px-6 py-3 rounded-full bg-black/40 backdrop-blur-xl border border-white/5 text-[10px] font-black tracking-[0.3em] uppercase text-white/40",children:e}),(0,t.jsx)(h.motion.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:()=>window.scrollTo({top:0,behavior:"smooth"}),className:"w-12 h-12 rounded-full bg-(--accent-primary)/10 backdrop-blur-xl border border-(--accent-primary)/20 flex items-center justify-center text-(--accent-primary) hover:bg-(--accent-primary)/20 transition-all",children:(0,t.jsx)(u.default,{className:"w-5 h-5"})})]})]})})}var g=e.i(222539),f=e.i(919722);function x({title:e,category:a,tags:i,titleStyle:s,animations:o,taxonomyStyles:l,titleFontFamily:r,titleFontSize:n,accentTags:c=!0}){let{transition:d,getFadeInVariants:p}=(0,f.useAnimationEngine)(o),u=(0,g.getElementStyles)(s);return(0,t.jsxs)(h.motion.div,{variants:p("up"),initial:"initial",animate:"animate",transition:d,className:"space-y-6",children:[(0,t.jsxs)("div",{className:"flex items-center gap-4",children:[(0,t.jsx)("div",{className:"h-px w-12 bg-(--accent-primary)"}),(0,t.jsx)("span",{className:"text-[10px] tracking-[0.4em] uppercase text-(--accent-primary) font-black",children:a??"PROJECT"})]}),(0,t.jsx)("h1",{className:"font-black uppercase tracking-tighter leading-[0.9] text-white gradient-text pb-4 whitespace-pre-wrap",style:{...u,fontFamily:r??u.fontFamily,fontSize:n??"clamp(2rem, 8vw, 4.5rem)",wordBreak:"break-word",overflowWrap:"anywhere"},children:e}),(0,t.jsx)("div",{className:"flex flex-wrap gap-1.5 md:gap-3 pt-6",children:i?.map(e=>{let a="next.js"===e.toLowerCase()||"react"===e.toLowerCase()||"ai"===e.toLowerCase(),i=l?.[e];return(0,t.jsx)("span",{className:`px-2.5 py-1 md:px-4 md:py-2 rounded-lg text-[9px] md:text-[10px] uppercase tracking-[0.1em] md:tracking-[0.2em] border transition-all duration-500
2                ${!i&&a&&c?"border-(--accent-primary)/30 bg-(--accent-primary)/10 text-(--accent-primary) shadow-[0_0_20px_rgba(var(--accent-rgb),0.1)] font-black":!i?"border-white/5 bg-white/2 text-white/40 hover:border-white/20 hover:text-white font-black":"font-bold"}`,style:i?{color:i.color,borderColor:i.border?.replace("1px solid ",""),backgroundColor:i.backgroundColor,fontWeight:i.fontWeight}:{},children:e},e)})})]})}function b({fullDescription:e,description:a,approach:i,challenges:s,descriptionStyle:o,approachStyle:l}){let r=(0,g.getElementStyles)(o),n=(0,g.getElementStyles)(l);return(0,t.jsxs)("div",{className:"space-y-12",children:[(0,t.jsxs)("div",{className:"space-y-6",children:[(0,t.jsxs)("h3",{className:"text-[11px] font-black uppercase tracking-[0.4em] text-(--accent-primary) flex items-center gap-3",children:[(0,t.jsx)("span",{className:"w-2 h-2 rounded-full bg-(--accent-primary)"}),"CONCEPT"]}),(0,t.jsx)("p",{className:"text-2xl md:text-3xl font-black tracking-tight leading-[1.2] text-white whitespace-pre-wrap",style:r,children:e||a})]}),(i||s&&s.length>0)&&(0,t.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-12",children:[i&&(0,t.jsxs)("div",{className:"space-y-6",children:[(0,t.jsx)("h4",{className:"text-[10px] font-black uppercase tracking-[0.5em] text-white/30",children:"PROCESS"}),(0,t.jsx)("p",{className:"text-lg text-zinc-400 font-light leading-relaxed whitespace-pre-wrap",style:n,children:i})]}),s&&s.length>0&&(0,t.jsxs)("div",{className:"space-y-6",children:[(0,t.jsx)("h4",{className:"text-[10px] font-black uppercase tracking-[0.5em] text-white/30",children:"HIGHLIGHT"}),(0,t.jsx)("div",{className:"flex flex-col gap-4",children:s.map((e,a)=>(0,t.jsxs)("div",{className:"flex gap-4 group",children:[(0,t.jsxs)("span",{className:"text-(--accent-primary) font-black text-xs shrink-0",children:["0",a+1]}),(0,t.jsx)("p",{className:"text-sm text-zinc-500 group-hover:text-zinc-300 transition-colors",children:e})]},e))})]})]})]})}var n=n;function y({title:e,images:a,setSelectedMedia:i}){return a&&0!==a.length?(0,t.jsx)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-8 pt-20",children:a.map(a=>(0,t.jsxs)("div",{className:"rounded-3xl overflow-hidden border border-white/5 bg-zinc-900 aspect-square group cursor-pointer relative",onClick:()=>i({url:a,type:"image"}),children:[(0,t.jsx)(o.default,{src:a,alt:`${e} detail`,fill:!0,sizes:"(max-width: 768px) 100vw, 50vw",className:"object-cover group-hover:scale-105 transition-transform duration-700"}),(0,t.jsx)("div",{className:"absolute inset-0 bg-black/40 opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex items-center justify-center",children:(0,t.jsx)(n.default,{className:"w-8 h-8 text-white/50"})})]},a))}):null}var w=e.i(896263);function v({project:e,nextProject:a}){return(0,t.jsx)("div",{className:"sticky top-40 space-y-8",children:(0,t.jsxs)("div",{className:"p-8 rounded-4xl border border-white/5 bg-white/3 backdrop-blur-2xl space-y-10",children:[(0,t.jsxs)("div",{className:"space-y-6",children:[(0,t.jsx)("h4",{className:"text-[10px] font-black uppercase tracking-[0.4em] text-white/20",children:"CONNECT_&_DEPLOY"}),(0,t.jsxs)("div",{className:"space-y-3",children:[e.liveUrl&&(0,t.jsxs)("a",{href:e.liveUrl,target:"_blank",rel:"noopener noreferrer",className:"flex items-center justify-between w-full px-6 py-4 rounded-xl bg-white text-black text-[11px] font-black uppercase tracking-widest hover:bg-blue-50 transition-all group",children:["Launch_Live_App",(0,t.jsx)(i.ExternalLink,{className:"w-4 h-4 group-hover:translate-x-1 group-hover:-translate-y-1 transition-transform"})]}),e.githubUrl&&(0,t.jsxs)("a",{href:e.githubUrl,target:"_blank",rel:"noopener noreferrer",className:"flex items-center justify-between w-full px-6 py-4 rounded-xl bg-white/5 border border-white/10 text-[11px] font-black uppercase tracking-widest hover:bg-white/10 transition-all group",children:["Source_Repository",(0,t.jsx)(s.Github,{className:"w-4 h-4"})]})]})]}),(0,t.jsxs)("div",{className:"pt-6 border-t border-white/5 flex items-center justify-between",children:[(0,t.jsxs)("div",{className:"space-y-1",children:[(0,t.jsx)("p",{className:"text-[10px] uppercase font-black text-white/20 tracking-widest",children:"NEXT_PHASE"}),(0,t.jsx)(d.default,{href:`/work/${a.id}`,className:"text-xl font-black tracking-tighter hover:text-(--accent-primary) transition-colors",children:a.title})]}),(0,t.jsx)(d.default,{href:`/work/${a.id}`,className:"w-12 h-12 rounded-full bg-white/5 border border-white/10 flex items-center justify-center hover:bg-(--accent-primary) transition-all group",children:(0,t.jsx)(w.ChevronRight,{className:"w-6 h-6 group-hover:translate-x-1 transition-transform"})})]})]})})}var j=e.i(136451),C=e.i(732954);function A({selectedMedia:e,setSelectedMedia:a}){return(0,t.jsx)(C.AnimatePresence,{children:e&&(0,t.jsxs)(h.motion.div,{initial:{opacity:0}
2,animate:{opacity:1},exit:{opacity:0},className:"fixed inset-0 z-100 bg-black/95 backdrop-blur-xl flex items-center justify-center p-4 sm:p-8",onClick:()=>a(null),children:[(0,t.jsx)("button",{onClick:()=>a(null),className:"absolute top-6 right-6 z-101 w-12 h-12 rounded-full bg-white/10 border border-white/20 flex items-center justify-center text-white/70 hover:text-white hover:bg-white/20 transition-all backdrop-blur-md",children:(0,t.jsx)(j.X,{className:"w-6 h-6"})}),(0,t.jsx)(h.motion.div,{initial:{scale:.9,opacity:0},animate:{scale:1,opacity:1},exit:{scale:.9,opacity:0},transition:{type:"spring",damping:25,stiffness:300},className:"relative w-full max-w-7xl max-h-[90vh] aspect-video rounded-2xl overflow-hidden shadow-2xl border border-white/10",onClick:e=>e.stopPropagation(),children:"image"===e.type?(0,t.jsx)(o.default,{src:e.url,alt:"Expanded view",fill:!0,className:"object-contain",sizes:"100vw",quality:100}):(0,t.jsx)("video",{src:e.url,className:"w-full h-full object-contain",controls:!0,autoPlay:!0,playsInline:!0})})]})})}var I=e.i(126181),k=e.i(144271);function N({project:e,nextProject:a}){let i=e.tags??[],o=!!e.techWalkthrough&&e.techWalkthrough.steps.length>0,l=e.challenges??[];return(0,t.jsx)("div",{className:"mx-auto max-w-4xl",children:(0,t.jsxs)("div",{className:"relative isolate space-y-10 overflow-hidden rounded-3xl border border-white/15 bg-zinc-900 p-8 text-left md:p-12",children:[(0,t.jsx)(k.default,{className:"pointer-events-none absolute -top-16 -right-16 -z-10 h-72 w-72 rounded-full blur-2xl"}),(0,t.jsxs)("div",{className:"space-y-5",children:[e.githubUrl&&(0,t.jsx)("div",{className:"flex justify-end",children:(0,t.jsxs)("a",{href:e.githubUrl,target:"_blank",rel:"noopener noreferrer",className:"inline-flex w-fit shrink-0 items-center gap-2 rounded-full border border-blue-400/40 bg-blue-500/15 px-5 py-2.5 text-[10px] font-black uppercase tracking-widest text-blue-300 transition-all hover:border-blue-400 hover:bg-blue-500 hover:text-white",children:[(0,t.jsx)(s.Github,{className:"h-4 w-4"}),"GitHub",(0,t.jsx)(I.ArrowUpRight,{className:"h-3.5 w-3.5"})]})}),(0,t.jsx)("h1",{className:"text-3xl font-black uppercase tracking-tighter text-white md:text-5xl",children:e.title}),(0,t.jsx)("p",{className:"max-w-2xl whitespace-pre-line text-base leading-relaxed text-white/70 md:text-lg",children:e.description}),i.length>0&&(0,t.jsx)("div",{className:"flex flex-wrap gap-1.5",children:i.map(e=>(0,t.jsx)("span",{className:"rounded-xs border border-white/15 px-2 py-1 font-mono text-[9px] text-white/55",children:e},e))})]}),(0,t.jsxs)("div",{className:"space-y-6 border-t border-white/10 pt-8",children:[(0,t.jsxs)("h3",{className:"flex items-center gap-3 text-[11px] font-black uppercase tracking-[0.4em] text-blue-400",children:[(0,t.jsx)("span",{className:"h-2 w-2 rounded-full bg-blue-400"}),"README"]}),(0,t.jsx)("p",{className:"whitespace-pre-wrap text-base font-bold leading-[1.3] tracking-tight text-white md:text-xl",children:e.fullDescription||e.description})]}),l.length>0&&(0,t.jsxs)("div",{className:"space-y-4 border-t border-white/10 pt-8",children:[(0,t.jsxs)("h4",{className:"flex items-center gap-3 text-[11px] font-black uppercase tracking-[0.4em] text-blue-400",children:[(0,t.jsx)("span",{className:"h-2 w-2 rounded-full bg-blue-400"}),"HIGHLIGHTS"]}),(0,t.jsx)("ul",{className:"grid grid-cols-1 gap-3 md:grid-cols-2",children:l.map((e,a)=>(0,t.jsxs)("li",{className:"flex gap-3 text-sm leading-relaxed text-zinc-300",children:[(0,t.jsx)("span",{className:"inline-flex h-fit shrink-0 items-center rounded-md bg-white/5 px-1.5 py-0.5 font-mono text-xs text-white",children:String(a+1).padStart(2,"0")}),e]},e))})]}),o&&(0,t.jsxs)("div",{className:"space-y-4 border-t border-white/10 pt-8",children:[(0,t.jsxs)("h4",{className:"flex items-center gap-3 text-[11px] font-black uppercase tracking-[0.4em] text-blue-400",children:[(0,t.jsx)("span",{className:"h-2 w-2 rounded-full bg-blue-400"}),"HOW IT WORKS"]}),e.techWalkthrough.description&&(0,t.jsx)("p",{className:"text-sm leading-relaxed text-zinc-400",children:e.techWalkthrough.description}),(0,t.jsx)("ol",{className:"space-y-2",children:e.techWalkthrough.steps.map((e,a)=>(0,t.jsxs)("li",{className:"flex gap-4 text-sm leading-relaxed text-zinc-300",children:[(0,t.jsx)("span",{className:"inline-flex h-fit shrink-0 items-center rounded-md bg-white/5 px-1.5 py-0.5 font-mono text-xs text-white",children:String(a+1).padStart(2,"0")}),e]},e))})]}),(0,t.jsx)("div",{className:"flex items-center justify-end border-t border-white/10 pt-8",children:(0,t.jsxs)(d.default,{href:`/work/${a.id}`,className:"group inline-flex items-center gap-3 text-sm font-bold text-white/60 transition-colors hover:text-white",children:[a.title,(0,t.jsx)("span",{className:"flex h-8 w-8 items-center justify-center rounded-full border border-white/10 bg-white/5 transition-all group-hover:bg-blue-500",children:(0,t.jsx)(w.ChevronRight,{className:"h-4 w-4 transition-transform group-hover:translate-x-0.5"})})]})})]})})}var S=e.i(608586),D=e.i(532325);function U({project:e,settings:a}){let s=e.images&&e.images.length>0?e.images:e.thumbnail?[e.thumbnail]:[],{active:l,setActive:r,containerRef:n}=(0,D.useImageCarousel)(s.length);return(0,t.jsxs)("div",{className:"max-w-4xl mx-auto text-left",children:[(0,t.jsx)(x,{title:e.title,category:e.category,tags:e.tags,titleStyle:e.titleStyle,animations:a?.appearance?.animations,taxonomyStyles:{},titleFontFamily:"'Pretendard', sans-serif",titleFontSize:"clamp(1.75rem, 6.5vw, 3.5rem)",accentTags:!1}),s[0]&&(0,t.jsxs)("div",{className:"mt-8 space-y-3",children:[(0,t.jsxs)("div",{ref:n,className:"group relative w-full overflow-hidden rounded-2xl border border-white/10 bg-zinc-900 shadow-2xl",children:[(0,t.jsx)("a",{href:e.liveUrl,target:"_blank",rel:"noopener noreferrer",className:"block w-full",children:(0,t.jsx)("div",{className:"relative w-full aspect-video overflow-hidden bg-zinc-950",children:s.map((a,i)=>(0,t.jsx)(o.default,{src:a,alt:e.title,fill:!0,sizes:"(max-width: 1024px) 100vw, 900px",priority:0===i,className:"object-cover transition-opacity duration-700 group-hover:scale-[1.02]",style:{opacity:+(i===l)}},a))})}),s.length>1&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("button",{type:"button","aria-label":"이전 화면",onClick:e=>{e.preventDefault(),e.stopPropagation(),r(e=>(e-1+s.length)%s.length)},className:"absolute inset-y-0 left-0 z-30 flex w-1/5 items-center justify-start pl-3 opacity-0 transition-opacity duration-300 hover:opacity-100 focus-visible:opacity-100 active:opacity-100",children:(0,t.jsx)("span",{className:"rounded-full bg-black/50 p-1.5 backdrop-blur-sm",children:(0,t.jsx)(S.ChevronLeft,{className:"h-5 w-5 text-white"})})}),(0,t.jsx)("button",{type:"button","aria-label":"다음 화면",onClick:e=>{e.preventDefault(),e.stopPropagation(),r(e=>(e+1)%s.length)},className:"absolute inset-y-0 right-0 z-30 flex w-1/5 items-center justify-end pr-3 opacity-0 transition-opacity duration-300 hover:opacity-100 focus-visible:opacity-100 active:opacity-100",children:(0,t.jsx)("span",{className:"rounded-full bg-black/50 p-1.5 backdrop-blur-sm",children:(0,t.jsx)(w.ChevronRight,{className:"h-5 w-5 text-white"})})}),(0,t.jsx)("div",{className:"absolute top-4 right-4 z-40 flex gap-1.5 rounded-full bg-black/40 px-2.5 py-2 backdrop-blur-sm",children:s.map((e,a)=>(0,t.jsx)("button",{type:"button","aria-label":`${a+1}번째 화면 보기`,onClick:e=>{e.preventDefault(),e.stopPropagation(),r(a)},style:{minHeight:0,minWidth:0},className:`h-2.5 w-2.5 rounded-full transition-colors duration-300 focus-visible:outline focus-visible:outline-2 focus-visible:outline-white ${a===l?"bg-blue-400":"bg-white/30 hover:bg-white/60"}`},e))})]}),e.liveUrl&&(0,t.jsxs)("a",{href:e.liveUrl,target:"_blank",rel:"noopener noreferrer",style:{minHeight:0,minWidth:0},className:"absolute bottom-5 right-5 z-40 inline-flex items-center gap-1.5 rounded-full border border-white/15 bg-black/45 backdrop-blur-xl px-3 py-1.5 text-[9px] font-black uppercase tracking-widest text-white transition-all hover:bg-white hover:text-black",children:["Live",(0,t.jsx)(i.ExternalLink,{className:"h-3 w-3"})]})]}),e.liveUrl&&(0,t.jsxs)("p",{className:"flex items-center gap-1.5 text-[12px] text-white/55",children:[(0,t.jsx)(i.ExternalLink,{className:"h-3.5 w-3.5 shrink-0"}),"가운데를 누르면 실제 사이트로 이동합니다"]})]}),(0,t.jsx)("div",{className:"mt-16",children:(0,t.jsx)(b,{fullDescription:e.fullDescription??"",description:e.description,approach:e.approach??"",challenges:e.challenges??[],descriptionStyle:e.descriptionStyle,approachStyle:e.approachStyle})})]})}function E(){return(0,t.jsxs)("div",{className:"min-h-screen bg-black flex flex-col items-center justify-center space-y-8",children:[(0,t.jsxs)("div",{className:"relative",children:[(0,t.jsx)("div",{className:"absolute inset-0 blur-2xl bg-blue-500/20 animate-pulse"}),(0,t.jsx)("h1",{className:"text-4xl font-black text-white relative",children:"PROJECT_NOT_FOUND"})]}),(0,t.jsx)(d.default,{href:"/work",className:"text-(--accent-primary) hover:underline uppercase tracking-widest text-xs font-bold",children:"Return to Archive"})]})}e.s(["default",0,function({params:e}){let{id:n}=(0,a.use)(e),d=l.default,p=d.find(e=>e.id===n),[u,h]=(0,a.useState)(null),[g,f]=(0,a.useState)(null),[w,j]=(0,a.useState)({});if((0,a.useEffect)(()=>{(async()=>{try{let[e,t]=await Promise.all([fetch(`/api/admin/update?type=sett
2ings&t=${Date.now()}`,{cache:"no-store"}),fetch(`/api/admin/update?type=site-config&t=${Date.now()}`,{cache:"no-store"})]),a=await e.json(),i=await t.json();a.success&&f(a.data),i.success&&i.data?.taxonomyStyles&&j(i.data.taxonomyStyles)}catch(e){console.error("Failed to fetch data:",e)}})()},[]),a.default.useEffect(()=>{u?document.body.style.overflow="hidden":document.body.style.overflow="unset"},[u]),!p)return(0,t.jsx)(E,{});let C=d.findIndex(e=>e.id===n),I=d[(C+1)%d.length],k=(0,r.getYoutubeId)(p.videoUrl)||(0,r.getYoutubeId)(p.liveUrl),S=p.liveUrl||p.githubUrl,D=p.liveUrl?"Launch Live App":"View Source (GitHub)",R=p.liveUrl?i.ExternalLink:s.Github,L=p.videoUrl||p.liveUrl||"",P=(0,r.isYoutubeShorts)(L),z=!k&&!p.videoUrl&&!p.thumbnail&&Array.isArray(p.images)&&p.images.length>0?p.images.slice(1):p.images,F=e=>{let t=e.split("/");return 2===t.length?Number(t[0])/Number(t[1]):16/9},W=p.aspectRatio&&"auto"!==p.aspectRatio,G=W?p.aspectRatio:"16/9",M="16/9";W?M=G:P&&(M="9/16");let T=F(M),H=W?{aspectRatio:G,width:"100%",maxWidth:`calc(65vh * ${F(G)})`,maxHeight:"65vh"}:{width:"auto",height:"auto",maxHeight:"65vh"};return(0,t.jsxs)("main",{className:"min-h-screen bg-black text-white selection:bg-blue-500/30",children:[(0,t.jsxs)("div",{className:"fixed inset-0 z-0 pointer-events-none opacity-20",children:[(()=>{if("Vibe Coding"===p.category&&!p.thumbnail&&!p.videoUrl&&!(p.images&&p.images.length>0)&&!k)return(0,t.jsx)("div",{className:"w-full h-full bg-linear-to-br from-neutral-900 via-black to-neutral-900"});if(p.videoUrl&&!k)return(0,t.jsx)("video",{src:p.videoUrl,className:"w-full h-full object-cover blur-[100px]",autoPlay:!0,muted:!0,loop:!0,playsInline:!0});let e="/images/placeholder.jpg";if(p.thumbnail){let t=(0,r.getYoutubeId)(p.thumbnail);e=t?(0,r.getYoutubeThumbnail)(t)||e:p.thumbnail}else p.images&&p.images.length>0?e=p.images[0]:k&&(e=(0,r.getYoutubeThumbnail)(k)||e);return(0,t.jsx)(o.default,{src:e,alt:"",fill:!0,sizes:"100vw",className:"object-cover blur-[100px]"})})(),(0,t.jsx)("div",{className:"absolute inset-0 bg-black/40"})]}),(0,t.jsx)(m,{category:p.category}),(0,t.jsx)("section",{className:"relative pt-32 md:pt-48 pb-20 px-4 md:px-8 z-10",children:(0,t.jsx)("div",{className:"container mx-auto",children:"Vibe Coding"===p.category?(0,t.jsx)(N,{project:p,nextProject:I}):"Web Site"===p.category?(0,t.jsx)(U,{project:p,nextProject:I,settings:g,taxonomyStyles:w,setSelectedMedia:h}):(0,t.jsxs)("div",{className:"max-w-5xl mx-auto space-y-12",children:[(0,t.jsx)(x,{title:p.title,category:p.category,tags:p.tags,titleStyle:p.titleStyle,animations:g?.appearance?.animations,taxonomyStyles:w}),(0,t.jsx)("div",{className:"relative w-full flex justify-center items-center",children:(0,t.jsx)(c,{project:p,youtubeId:k,primaryLink:S,primaryLinkLabel:D,PrimaryLinkIcon:R,ytRatioStr:M,ytRatioFloat:T,nativeMediaStyle:H,nativeMediaClasses:"max-w-full rounded-2xl shadow-2xl border border-white/10 object-contain transition-transform duration-500 group-hover:scale-[1.02] bg-zinc-900",setSelectedMedia:h})}),(0,t.jsxs)("div",{className:"grid grid-cols-1 lg:grid-cols-12 gap-16 pt-12",children:[(0,t.jsxs)("div",{className:"lg:col-span-8 space-y-20",children:[(0,t.jsx)(b,{fullDescription:p.fullDescription,description:p.description,approach:p.approach,challenges:p.challenges,descriptionStyle:p.descriptionStyle,approachStyle:p.approachStyle}),(0,t.jsx)(y,{title:p.title,images:z,setSelectedMedia:h})]}),(0,t.jsx)("div",{className:"lg:col-span-4",children:(0,t.jsx)(v,{project:p,nextProject:I})})]})]})})}),(0,t.jsx)(A,{selectedMedia:u,setSelectedMedia:h})]})}],769614)},607873,(e,t,a)=>{t.exports=JSON.parse('[{"id":"cafe-oneulharu-demo","title":"카페 오늘하루","category":"Web Site","thumbnail":"/images/projects/cafe-oneulharu-pc-01-home-20260904.webp","description":"웜톤 팔레트와 실사 이미지로 카페 분위기를 담은 반응형 원페이지입니다.","cardDescription":"실제 배포까지 마친 카페 브랜드 원페이지 웹사이트","tags":["Next.js","Tailwind CSS","Vercel"],"images":["/images/projects/cafe-oneulharu-pc-01-home-20260904.webp","/images/projects/cafe-oneulharu-pc-02-menu-20260904.webp","/images/projects/cafe-oneulharu-pc-03-about-20260905-b69da8.webp","/images/projects/cafe-oneulharu-pc-04-location-20260905-0f7a20.webp"],"mobileImages":["/images/projects/cafe-oneulharu-mobile-hero.webp","/images/projects/cafe-oneulharu-mobile-menu.webp"],"liveUrl":"https://cafe-oneulharu-demo.vercel.app","screenshotPages":["/","/menu","/about","/location"],"aspectRatio":"16/9","approach":"소개·메뉴·영업시간이 하나의 스크롤 흐름으로 자연스럽게 이어지도록 설계했습니다. 기획부터 실제 배포까지 서비스 오픈 수준으로 제작합니다.","challenges":["반응형 레이아웃으로 PC·모바일 모두 동일한 완성도로 구현","실사 이미지와 웜톤 컬러로 매장 분위기를 그대로 전달","제작부터 실제 배포까지 원스톱으로 완결"]},{"id":"cass-beer-ai-ad","title":"CASS AI 광고","category":"AI Content","aspectRatio":"9/16","featured":true,"thumbnail":"https://img.youtube.com/vi/LEfLc6z26Oc/maxresdefault.jpg","description":"카스(Cass) 맥주 AI 광고 영상 (17초)","fullDescription":"카스의 청량함을 AI로 풀어낸 맥주 광고.","tags":["stable diffusion","comfyui","midjourney","kling ai","veo","photoshop","premiere pro","capcut"],"videoUrl":"https://www.youtube.com/shorts/LEfLc6z26Oc","challenges":["거품 질감을 AI로 설득력 있게 표현하기","17초 안에 브랜드 에너지 전달","청량 컬러 톤 일관성 유지"],"approach":"청량한 거품과 컬러감에 집중한 프롬프트로 빠른 리듬의 맥주 광고 완성.","images":[],"chosen":false,"selected":false},{"id":"fila-pantera-ai-ad","title":"PANTERA AI 광고","category":"AI Content","aspectRatio":"9/16","featured":true,"thumbnail":"https://img.youtube.com/vi/GMl1eoqvstE/maxresdefault.jpg","description":"FILA 판테라 스니커즈 컬렉션 AI 광고 영상","fullDescription":"FILA 판테라의 스트릿 감성을 AI로 담은 스니커즈 광고.","tags":["comfyui","midjourney","kling ai","photoshop","premiere pro","capcut"],"videoUrl":"https://www.youtube.com/shorts/GMl1eoqvstE","challenges":["신발 소재 디테일을 AI로 정밀하게 표현하기","스포츠 브랜드 특유의 역동감","FILA 브랜드 컬러 아이덴티티 유지"],"approach":"스니커즈 디테일을 레퍼런스 이미지로 잡고 스트릿 감성의 앵글로 영상 연결.","images":[],"chosen":false,"selected":false},{"id":"missha-dare-tint-ai-ad","title":"MISSHA AI 광고","category":"AI Content","aspectRatio":"9/16","featured":true,"thumbnail":"https://img.youtube.com/vi/kuDxUp-R2-8/maxresdefault.jpg","description":"MISSHA 데어틴트 멜티 벨벳 립 제품 AI 광고 영상","fullDescription":"벨벳 립의 질감과 색감을 AI 비주얼로 살린 뷰티 광고.","tags":["stable diffusion","comfyui","midjourney","kling ai","veo","photoshop","premiere pro","capcut"],"videoUrl":"https://www.youtube.com/shorts/kuDxUp-R2-8","challenges":["립 제품의 벨벳 질감 AI로 재현","뷰티 광고 특유의 감성 분위기","짧은 포맷에서 제품 매력 극대화"],"approach":"벨벳 립 색감과 질감을 뷰티 특화 프롬프트로 정밀하게 잡아낸 광고.","images":[],"chosen":false,"selected":false},{"id":"kanu-hanok-ai-ad","title":"KANU AI 광고","category":"AI Content","aspectRatio":"9/16","featured":false,"thumbnail":"https://img.youtube.com/vi/c7zIMhZXjxA/maxresdefault.jpg","description":"전통 한옥 배경의 카누 스프링블렌드 아메리카노 AI 광고","fullDescription":"한옥과 아메리카노, 어울릴 것 같지 않은 조합을 AI로 맞춰본 봄 광고.","tags":["stable diffusion","comfyui","midjourney","kling ai","veo","photoshop","premiere pro","capcut"],"videoUrl":"https://www.youtube.com/shorts/c7zIMhZXjxA","challenges":["한옥 건축 디테일 AI로 표현하기","커피와 전통 공간의 어색함 없애기","봄 감성 컬러 톤 일관성"],"approach":"한옥 배경과 제품 프롬프트를 따로 잡아 봄 감성으로 자연스럽게 연결.","images":[],"chosen":false,"selected":false},{"id":"dior-fashion-ai-ad","title":"Dior 패션 AI 광고","category":"AI Content","aspectRatio":"9/16","featured":false,"thumbnail":"https://img.youtube.com/vi/SEwZ8FFnvN4/maxresdefault.jpg","description":"Stable Diffusion + Midjourney로 제작한 디올 AI 패션 광고","fullDescription":"AI로 재해석한 Dior의 우아한 패션 무드.","tags":["stable diffusion","comfyui","midjourney","kling ai","veo","photoshop","premiere pro","capcut"],"videoUrl":"https://www.youtube.com/shorts/SEwZ8FFnvN4","challenges":["하이패션 의상의 섬세한 소재감 표현","디올 특유의 우아한 무드 재현","명품 광고 조명·구도 구현"],"approach":"디올 런웨이 레퍼런스를 분석해 의상 실루엣과 고급 조명감을 프롬프트에 반영.","
2images":[],"chosen":false,"selected":false},{"id":"adidas-superstar-ai-ad","title":"Superstar AI 광고","category":"AI Content","aspectRatio":"9/16","featured":false,"thumbnail":"https://img.youtube.com/vi/Ffyt7vgB6vA/maxresdefault.jpg","description":"아디다스 슈퍼스타 신발 AI 광고 영상","fullDescription":"클래식 스니커즈 슈퍼스타를 AI로 다시 무대 위에 올린 광고.","tags":["stable diffusion","comfyui","midjourney","kling ai","veo","photoshop","premiere pro","capcut"],"videoUrl":"https://www.youtube.com/shorts/Ffyt7vgB6vA","challenges":["슈퍼스타 아이코닉 디자인 디테일 재현","스트릿 감성의 에너지 표현","클래식과 현대 무드 동시에 담기"],"approach":"쉘토 디테일과 스트라이프를 레퍼런스로 잡고 스트릿 무드 앵글로 영상 완성.","images":[],"chosen":false,"selected":false},{"id":"genesis-car-ai-ad","title":"Genesis AI 광고","category":"AI Content","aspectRatio":"9/16","featured":false,"thumbnail":"https://img.youtube.com/vi/K1e8d_cbwMA/maxresdefault.jpg","description":"현대 Genesis(제네시스) 자동차 AI 광고 영상","fullDescription":"제네시스의 프리미엄 감성을 AI 영상으로 잡아낸 자동차 광고.","tags":["stable diffusion","comfyui","midjourney","kling ai","veo","photoshop","premiere pro","capcut"],"videoUrl":"https://www.youtube.com/shorts/K1e8d_cbwMA","challenges":["자동차 금속 질감과 곡선 AI로 표현하기","프리미엄 브랜드 무드 일관성","야간 드라이브 느낌 영상으로 구현"],"approach":"제네시스의 곡선 디자인과 야간 프리미엄 조명을 중심으로 영상 무드 완성.","images":[],"chosen":false,"selected":false},{"id":"elle-cover-ai-model-v1","title":"ELLE AI 모델 vol.1","category":"AI Content","aspectRatio":"9/16","featured":false,"thumbnail":"https://img.youtube.com/vi/XzQ1aMpTweI/maxresdefault.jpg","description":"AI 여자 모델이 ELLE 매거진 커버를 차지하다","fullDescription":"AI 모델로 만든 첫 번째 ELLE 커버 컨셉.","tags":["stable diffusion","comfyui","midjourney","kling ai","veo","photoshop","premiere pro","capcut"],"videoUrl":"https://www.youtube.com/shorts/XzQ1aMpTweI","challenges":["AI 모델 얼굴 일관성 유지","편집 패션 스타일 조명·구도","잡지 커버 수준의 디테일 완성도"],"approach":"잡지 커버 레이아웃을 레퍼런스로 AI 모델의 포즈와 조명을 편집 패션 스타일로 조율.","images":[],"chosen":false,"selected":false},{"id":"elle-cover-ai-model-v2","title":"ELLE AI 모델 vol.2","category":"AI Content","aspectRatio":"9/16","featured":false,"thumbnail":"https://img.youtube.com/vi/bJzYsTFAMSk/maxresdefault.jpg","description":"AI 모델이 ELLE 매거진 커버 모델이 되다 (Stable Diffusion + ComfyUI)","fullDescription":"디테일을 더 다듬은 두 번째 AI ELLE 커버 컨셉.","tags":["stable diffusion","comfyui","midjourney","kling ai","veo","photoshop","premiere pro","capcut"],"videoUrl":"https://www.youtube.com/shorts/bJzYsTFAMSk","challenges":["vol.1 대비 세부 묘사 개선","컬러 그레이딩 일관성","패션 무드 완성도 끌어올리기"],"approach":"vol.1 피드백을 반영해 모델 디테일과 배경 완성도를 한 단계 더 다듬은 버전.","images":[],"chosen":false,"selected":false},{"id":"ai-fashion-change","title":"패션 체인지 AI 영상","category":"AI Content","aspectRatio":"9/16","featured":false,"thumbnail":"https://img.youtube.com/vi/iN3TUWYflGc/maxresdefault.jpg","description":"AI로 같은 포즈를 유지하면서 패션 체인지","fullDescription":"같은 포즈를 유지하며 AI로 패션을 전환하는 실험적 영상.","tags":["stable diffusion","comfyui","midjourney","kling ai","veo","photoshop","premiere pro","capcut"],"videoUrl":"https://www.youtube.com/shorts/iN3TUWYflGc","challenges":["포즈 유지하면서 의상만 전환하기","전환 장면의 자연스러운 흐름","다양한 스타일을 짧은 클립에 담기"],"approach":"같은 포즈를 유지하면서 의상만 전환되는 흐름을 AI 영상으로 자연스럽게 이어 붙였다.","images":[],"chosen":false,"selected":false},{"id":"seoul-vlog-ai","title":"AI 서울 탐방 브이로그","category":"AI Content","aspectRatio":"9/16","featured":false,"thumbnail":"https://img.youtube.com/vi/qGVERP79EgM/maxresdefault.jpg","description":"AI로 제작한 서울 탐방 브이로그 영상","fullDescription":"카메라 없이 AI로만 서울 곳곳을 담은 도시 브이로그.","tags":["stable diffusion","comfyui","midjourney","kling ai","veo","photoshop","premiere pro","capcut"],"videoUrl":"https://www.youtube.com/shorts/qGVERP79EgM","challenges":["서울 실제 장소의 사실감 있는 재현","브이로그 특유의 자연스러운 흐름","다양한 장소를 일관된 톤으로 연결하기"],"approach":"서울 각 지역의 랜드마크와 분위기를 AI 이미지로 생성해 브이로그 형식으로 편집.","images":[],"chosen":false,"selected":false}
2,{"id":"cherry-blossom-ai-girl","title":"AI 벚꽃 축제 소녀","category":"AI Content","aspectRatio":"9/16","featured":false,"thumbnail":"https://img.youtube.com/vi/ScNcbp_mxBc/maxresdefault.jpg","description":"AI로 만든 벚꽃 축제 감성 영상","fullDescription":"봄 벚꽃과 AI 캐릭터, 계절 감성을 담은 짧은 영상.","tags":["stable diffusion","comfyui","midjourney","kling ai","veo","photoshop","premiere pro","capcut"],"videoUrl":"https://www.youtube.com/shorts/ScNcbp_mxBc","challenges":["벚꽃 꽃잎의 자연스러운 움직임 표현","캐릭터와 배경의 어울림","봄 감성 컬러 톤 표현"],"approach":"봄 벚꽃 배경과 AI 캐릭터를 계절 감성에 맞게 조율해 짧은 영상 한 편으로 완성.","images":[],"chosen":false,"selected":false},{"id":"cocacola-ai-ad","title":"코카콜라 AI 광고","category":"AI Content","aspectRatio":"9/16","featured":false,"thumbnail":"https://img.youtube.com/vi/YF48kwwAOXU/maxresdefault.jpg","description":"AI로 만든 코카콜라 글로벌 브랜드 광고 영상","fullDescription":"레드 컬러 하나로 승부한 코카콜라 AI 광고.","tags":["stable diffusion","comfyui","midjourney","kling ai","veo","photoshop","premiere pro","capcut"],"videoUrl":"https://www.youtube.com/shorts/YF48kwwAOXU","challenges":["코카콜라 레드의 강렬함을 AI로 표현하기","글로벌 브랜드 특유의 í
2Œí•œ 에너지 재현","Shorts 포맷에서 브랜드 임팩트 극대화"],"approach":"코카콜라 레드 하나로 압도하는 방식으로 잡고 제품과 컬러 에너지 중심으로 구성.","images":[],"chosen":false,"selected":false},{"id":"gucci-perfume-ai-ad","title":"GUCCI 향수 AI 광고","category":"AI Content","aspectRatio":"9/16","featured":false,"thumbnail":"https://img.youtube.com/vi/wqWERlr3Km4/maxresdefault.jpg","description":"GUCCI 향수 럭셔리 브랜드 AI 광고 영상","fullDescription":"GUCCI 향수의 아방가르드한 감성을 AI로 담은 광고.","tags":["stable diffusion","comfyui","midjourney","kling ai","veo","photoshop","premiere pro","capcut"],"videoUrl":"https://www.youtube.com/shorts/wqWERlr3Km4","challenges":["향수의 투명함과 질감 AI로 표현하기","구찌 특유의 아방가르드 무드 재현","럭셔리 광고의 몽환적 분위기 구현"],"approach":"구찌의 아방가르드 레퍼런스를 분석해 몽환적이고 고급스러운 향수 광고 비주얼 완성.","images":[],"chosen":false,"selected":false},{"id":"cj-logistics-ai-ad","title":"CJ 대한통운 AI 광고","category":"AI Content","aspectRatio":"9/16","featured":false,"thumbnail":"https://img.youtube.com/vi/R-nVGAdK_g8/maxresdefault.jpg","description":"AI로 제작한 CJ 대한통운(O-NE) 택배 브랜드 광고 영상","fullDescription":"실사 광고 수준으로 완성한 CJ 대한통운 AI 브랜드 영상.","tags":["midjourney","kling ai","photoshop","premiere pro","capcut"],"videoUrl":"https://www.youtube.com/shorts/R-nVGAdK_g8","challenges":["택배 서비스 특성을 시각적으로 표현하기","CJ 브랜드 아이덴티티 일관성","Shorts 포맷에서 임팩트 있는 전달"],"approach":"CJ 브랜드 컬러와 물류 특성을 키워드로 잡아 실사 광고 느낌의 영상 완성.","images":[],"chosen":false,"selected":false},{"id":"quiznos-contest-2025","title":"퀴즈노스 공모전 응모작","category":"Contest","aspectRatio":"9/16","featured":false,"thumbnail":"https://img.youtube.com/vi/0LHTdWy6JRI/maxresdefault.jpg","description":"2025 제2회 퀴즈노스 영상 콘테스트 응모 AI 작품","fullDescription":"2025 퀴즈노스 영상 공모전에 AI 광고로 승부한 응모작.","tags":["stable diffusion","comfyui","midjourney","kling ai","veo","photoshop","premiere pro","capcut"],"videoUrl":"https://www.youtube.com/shorts/0LHTdWy6JRI","challenges":["공모전 기준에 맞는 완성도 확보","퀴즈노스 브랜드를 AI로 매력적으로 표현하기","Shorts 포맷에서 강렬한 인상 남기기"],"approach":"공모전 심사 기준을 먼저 분석하고 퀴즈노스 브랜드를 AI 광고로 표현해 출품.","images":[],"chosen":false,"selected":false},{"id":"celine-bag-ai-ad","title":"CELINE AI 광고","category":"AI Content","aspectRatio":"9/16","featured":false,"thumbnail":"https://img.youtube.com/vi/rCEeizmVjxQ/maxresdefault.jpg","description":"AI로 만든 셀린느(Celine) 럭셔리 가방 광고 영상","fullDescription":"셀린느의 미니멀한 감성을 AI로 풀어낸 럭셔리 가방 광고.","tags":["stable diffusion","comfyui","flux","midjourney","kling ai","photoshop","premiere pro","capcut"],"videoUrl":"https://www.youtube.com/shorts/rCEeizmVjxQ","challenges":["가죽 소재의 디테일과 질감 AI로 재현","셀린느 미니멀 브랜드 감성 표현","럭셔리 광고 특유의 절제된 무드 유지"],"approach":"셀린느의 미니멀한 감성을 Flux와 Midjourney를 조합해 럭셔리 가방 광고로 완성.","images":[],"chosen":false,"selected":false},{"id":"weekly24-challenge","title":"ad1day 챌린지","category":"Contest","aspectRatio":"9/16","featured":false,"thumbnail":"https://img.youtube.com/vi/4vcYj0VBZzo/maxresdefault.jpg","description":"ad1day weekly24(위클리24) 챌린지 응모 AI 영상 작품","fullDescription":"ad1day weekly24 챌린지에 매주 완성해 응모한 AI 영상.","tags":["stable diffusion","comfyui","midjourney","kling ai","veo","photoshop","premiere pro","capcut"],"videoUrl":"https://www.youtube.com/shorts/4vcYj0VBZzo","challenges":["매주 마감에 맞춘 빠른 제작 속도","다양한 브랜드에 맞ê²
2Œ 스타일 전환하기","짧은 시간 안에 광고 완성도 유지"],"approach":"매주 주어진 브랜드 주제에 맞춰 AI 광고를 빠르게 제작해 챌린지에 응모.","images":[],"chosen":false,"selected":false},{"id":"baskinrobbins-ai-ad","title":"베스킨라빈스 AI 광고","category":"AI Content","aspectRatio":"9/16","featured":false,"thumbnail":"https://img.youtube.com/vi/7E4i-Nbt-5A/maxresdefault.jpg","description":"Stable Diffusion으로 제작한 베스킨라빈스 AI 광고 영상","fullDescription":"달콤하고 화사한 색감으로 만든 베스킨라빈스 AI 광고.","tags":["stable diffusion","comfyui","midjourney","kling ai","veo","photoshop","premiere pro","capcut"],"videoUrl":"https://www.youtube.com/shorts/7E4i-Nbt-5A","challenges":["아이스크림 질감과 색감 AI로 표현하기","베스킨라빈스 특유의 밝고 화사한 분위기 재현","제품 매력을 Shorts에서 극대화하기"],"approach":"아이스크림 특유의 달콤하고 화사한 컬러감을 중심으로 제품 광고 완성.","images":[],"chosen":false,"selected":false},{"id":"drdre-headset-ai-ad","title":"닥터드레 AI 영상","category":"AI Content","aspectRatio":"9/16","featured":false,"thumbnail":"https://img.youtube.com/vi/XqUuEwNbz94/maxresdefault.jpg","description":"AI로 만든 화려한 컨셉의 닥터드레 헤드셋 광고 영상","fullDescription":"음악과 비주얼의 충돌을 극적으로 담은 AI 헤드셋 광고.","tags":["stable diffusion","comfyui","flux","midjourney","kling ai","photoshop","premiere pro","capcut"],"videoUrl":"https://www.youtube.com/shorts/XqUuEwNbz94","challenges":["드레 브랜드 특유의 강렬한 비주얼 아이덴티티 재현","헤드셋 제품과 음악 에너지 연결하기","화려한 컨셉 아트와 제품 광고의 균형"],"approach":"드레의 브랜드 에너지를 Flux와 ComfyUI로 강렬한 비주얼로 잡아 헤드셋 광고 완성.","images":[],"chosen":false,"selected":false},{"id":"jeju-samdasoo-ai-ad","title":"제주 삼다수 AI 광고","category":"AI Content","aspectRatio":"9/16","featured":false,"thumbnail":"https://img.youtube.com/vi/jrAzQej2urY/maxresdefault.jpg","description":"제주 삼다수 프리미엄 생수 브랜드 AI 광고 영상","fullDescription":"제주 자연의 청결함을 시네마틱하게 담은 삼다수 AI 광고.","tags":["midjourney","kling ai","photoshop","premiere pro","capcut"],"videoUrl":"https://www.youtube.com/shorts/jrAzQej2urY","challenges":["제주 자연 풍경 사실감 있게 AI로 재현하기","물의 투명함과 ì²­ê²° 이미지 표현","브랜드 감성과 AI 비주얼의 조화"],"approach":"제주 자연의 청결함을 키워드로 시네마틱한 풍경 이미지를 생성해 브랜드 영상 완성.","images":[],"chosen":false,"selected":false},{"id":"gargrin-ai-ad","title":"가그린 AI 광고","category":"AI Content","aspectRatio":"9/16","featured":false,"thumbnail":"https://img.youtube.com/vi/UkkfAaE347s/maxresdefault.jpg","description":"동아제약 가그린 구강청결제 AI 광고 영상","fullDescription":"상쾌함을 시각화한 가그린 AI 광고.","tags":["midjourney","kling ai","photoshop","premiere pro","capcut"],"videoUrl":"https://www.youtube.com/shorts/UkkfAaE347s","challenges":["가그린 특유의 민트 색감과 ì²­ê²° 이미지","제품 특성을 시각적으로 자연스럽게 전달하기","짧은 러닝타임 안에 브랜드 메시지 전달"],"approach":"민트 컬러와 상쾌함을 키워드로 프롬프트를 구성해 구강청결제 광고 완성.","images":[],"chosen":false,"selected":false},{"id":"gobansikdang-ai-ad","title":"고반식당 AI 광고","category":"Contest","aspectRatio":"16/9","featured":false,"thumbnail":"https://img.youtube.com/vi/k3K2SQUGF7Q/maxresdefault.jpg","description":"매경미디어그룹 AI 영상광고 공모전 참여작","fullDescription":"매경미디어그룹 AI 광고 공모전에 팀과 함께 도전한 고반식당 출품작.","tags":["stable diffusion","comfyui","midjourney","kling ai","veo","photoshop","premiere pro","capcut"],"videoUrl":"https://www.youtube.com/watch?v=k3K2SQUGF7Q","challenges":["팀 협업으로 일관된 비주얼 방향 유지하기","고반식당 브랜드 감성을 AI로 표현하기","공모전 마감에 맞춘 완성도 확보"],"approach":"팀원들과 역할을 나눠 고반식당 브랜드를 분석하고 AI 영상으로 공모전 출품작 완성.","images":[],"chosen":false,"selected":false}
2,{"id":"sodam-harness-eng","title":"SoDam Harness Eng","category":"Vibe Coding","aspectRatio":"16/9","featured":false,"thumbnail":"","description":"AI가 위험한 작업을 하려 할 때 자동으로 막고 백업해 되돌릴 수 있게 해주는 Claude Code 안전벨트 플러그인","cardDescription":"AI가 위험한 작업을 하려 할 때 자동으로 막고 백업해 되돌릴 수 있게 해주는 안전벨트 도구","ogDescription":"AI가 위험한 작업을 하려 할 때 자동으로 막고 백업해 되돌릴 수 있게 해주는 Claude Code 안전벨트 플러그인 — 완전 로컬, 인터넷 전송 없음","fullDescription":"실사용 중 파일을 다른 폴더로 옮기면 백업도 확인 질문도 없이 원본이 그대로 사라지는 구멍을 발견해 막았다.","tags":["JavaScript","Claude Code","AI Safety","Guardrails","Hooks","Backup","Undo","Beginner Friendly"],"githubUrl":"https://github.com/sodam-ai/SoDam-Harness-Eng","images":[],"challenges":["확인창 빈도는 조정해도 치명적 작업 차단과 비밀 파일 재확인은 항상 그대로 유지","비밀번호·토큰·인증서 파일은 아예 접근하지 않고 백업에서도 제외","git commit 직전 비밀파일이 섞이면 이름만 확인해 먼저 물어봄","이름 바꾸기·복사로 덮어써지는 기존 파일까지 전부 백업 대상으로 포함"],"techWalkthrough":{"title":"위험도 3단계로 나눠 판단하는 경비원 구조","description":"","steps":["AI가 도구를 쓰기 전에 경비원 역할의 훅이 먼저 위험도를 판단","안전한 작업은 그냥 진행되고, 위험한 작업만 백업 후 확인을 거침","재앙급 작업은 확인 절차 없이 즉시 차단","인터넷 연결 없이 전부 내 컴퓨터 안에서만 판단하고 저장","같은 폴더에서 반복되는 작업은 12시간 동안 확인을 건너뛰도록 설정 가능","백업은 최근 100개·30일 기준으로 자동 정리됨","Codex에서는 같은 자동 차단 대신 Codex 자체 승인창과 샌드박스로 대신 보호"]},"chosen":false,"selected":false},{"id":"sodam-context-eng","title":"SoDam Context Eng","category":"Vibe Coding","aspectRatio":"16/9","featured":false,"thumbnail":"","description":"코드를 몰라도 AI 사용설명서를 쉬운 한국어로 검진하고 정리해주는 Claude Code·Codex 플러그인","cardDescription":"코드를 몰라도 AI 사용설명서를 쉬운 한국어로 검진하고 정리해주는 도구","ogDescription":"코드를 몰라도 AI 사용설명서(CLAUDE.md·AGENTS.md)를 쉬운 한국어로 검진하고 정리해주는 Claude Code·Codex 플러그인 — 비밀키는 절대 읽지 않고 가려서만 확인","fullDescription":"보안 감사 중 되돌리기 기능에 백업 폴더 밖의 아무 파일이나 지정하면 그 내용이 그대로 복사되는 결함을 발견해 우회 경로까지 막았다.","tags":["JavaScript","Claude Code","Codex","Context Engineering","Security","Checkup","Korean","Beginner Friendly"],"githubUrl":"https://github.com/sodam-ai/SoDam-Context-Eng","images":[],"challenges":["비밀키는 값을 읽거나 보여주지 않고, 있다는 사실만 가린 채로 확인","허락 없이는 파일을 만들지도 고치지도 않고, 항상 백업부터 만든 뒤에만 적용","자격증명·시스템 폴더는 백업·처방·되돌리기 전부 자동으로 거부","모순·부풀림처럼 규칙만으론 못 잡는 항목은 동의를 구한 뒤에만 AI가 직접 판단"],"techWalkthrough":{"title":"AI가 원본을 직접 안 읽고 요약 결과만 보는 CLI-JSON 경계 구조","description":"","steps":["검진은 내부 검사기가 파일을 읽고 비밀키 값은 뺀 요약 결과만 AI에게 전달","판정 규칙은 코드가 아니라 JSON 데이터로 관리해 새 항목 추가가 쉬움","참고 점수는 새로 계산하지 않고 이미 찾은 문제 개수로 그 자리에서 뺄셈","정기 점검 알림은 마지막 점검 시각만 기록해두고 30일이 지났을 때만 짧게 안내","코덱스는 상위 폴더까지 합쳐서 확인하지만 클로드코드는 지정한 파일만 확인","외부 라이브러리 없이 동작해 공급망 위험을 줄임","안전·금지 같은 규칙이 담긴 줄은 정리 과정에서 자동으로 보존됨"]},"chosen":false,"selected":false}
2,{"id":"sodam-loop-eng","title":"SoDam Loop Eng","category":"Vibe Coding","aspectRatio":"16/9","featured":false,"thumbnail":"","description":"AI에게 \'이거 될 때까지 고쳐줘\'를 시켜도 무한 반복·폭주 없이 안전하게 돌아가는 Claude Code 플러그인","cardDescription":"AI에게 \'이거 될 때까지 고쳐줘\'를 시켜도 무한 반복·폭주 없이 안전하게 돌아가는 도구","ogDescription":"AI에게 \'이거 될 때까지 고쳐줘\'를 시켜도 무한 반복·폭주 없이 안전하게 돌아가는 Claude Code 플러그인 — 완료됐다고 다 된 게 아니라 검사 근거가 있어야 통과","fullDescription":"무한 반복으로 11.7시간·6,239회나 폭주했던 실제 사고가 있어, 반복 횟수 상한을 0(무한)으로는 절대 설정하지 못하게 만들었다.","tags":["JavaScript","Claude Code","AI Safety","Guardrails","Automation","Iteration","Security","Beginner Friendly"],"githubUrl":"https://github.com/sodam-ai/SoDam-Loop-Eng","images":[],"challenges":["회차마다 이번엔 뭘 바꿀지 먼저 한 줄 안내하지 않으면 파일 수정 자체가 막힘","같은 결과가 3번 반복되면 헛도는 걸로 보고 자동으로 멈춤","삭제·강제 푸시 같은 위험 작업은 반복 중에도 매번 확인을 거침","정기점검 모드는 결과만 보고할 뿐 코드에 수정 기능 자체가 없어 절대 못 고침"],"techWalkthrough":{"title":"반복 모터와 안전 게이트를 분리한 구조","description":"","steps":["시작 전 목표를 다듬고 백업부터 만든 뒤 무결성까지 확인하고서야 반복을 시작","실행으로 합격 여부가 나오는 검사와 사람이 봐야 하는 검사를 등급을 나눠 다르게 판정","자기 자신의 안전 파일을 건드리는 시도는 어떤 권한 모드에서도 항상 차단됨","같은 창을 두 개 띄워도 세션별로 상태가 섞이지 않도록 격리",".env·인증서처럼 비밀로 보이는 파일은 내용을 안 열어보고 이름만으로 백업 제외","완료·8회·30분·헛돌기·진동 중 하나만 걸려도 자동으로 멈추고 한국어로 요약","외부 라이브러리 없이 Node 내장 기능만으로 동작"]},"chosen":false,"selected":false},{"id":"sodam-prompt-eng","title":"SoDam Prompt Eng","category":"Vibe Coding","aspectRatio":"16/9","featured":false,"thumbnail":"","description":"AI를 처음 쓰는 분도 빈칸만 채우면 되는 한국어 글쓰기 스킬 10종을 모아 놓은 Claude Code 플러그인","cardDescription":"AI를 처음 쓰는 분도 빈칸만 채우면 되는 한국어 글쓰기 스킬 10종을 모아 놓은 도구","ogDescription":"AI를 처음 쓰는 분도 빈칸만 채우면 되는 한국어 글쓰기 스킬 10종을 모아 놓은 Claude Code 플러그인 — 서버·비용 없이 전부 무료","fullDescription":"Claude Code의 알려진 제한 때문에 스킬 폴더만으로는 슬래시 명령어가 안정적으로 등록되지 않는다는 걸 발견해, 명령어 폴더를 따로 만들어 해결했다.","tags":["Claude Code","Korean","Codex","Student","Prompt Engineering","Writing Assistant","AI Education","Skills Plugin"],"githubUrl":"https://github.com/sodam-ai/SoDam-Prompt-Eng","images":[],"challenges":["새 스킬이 필요하면 대화로 직접 설계해서 만드는 메타 스킬도 지원","개인정보 유도·프롬프트 탈취·과장광고 유도 공격까지 실제로 방어 확인","이름·전화번호 같은 개인정보 입력을 유도하지 않도록 스킬 자체를 설계","서버·CI 비용을 0원으로 유지하려고 자동화 파이프라인을 일부러 두지 않음"],"techWalkthrough":{"title":"빈칸 채우기 방식의 SKILL.md 템플릿 구조","description":"","steps":["슬래시 명령어든 자연어든 같은 SKILL.md로 빈칸을 채워 동작","실제 글 생성은 내 컴퓨터가 아니라 AI 회사 서버에서 처리됨","결과물은 채팅창에만 나오고 따로 저장되지 않음","긴글 요약·영어 번역처럼 입력이 하나뿐인 스킬은 전체 텍스트를 한 번에 받음","여러 AI 도구에 설치 위치만 다를 뿐 스킬 파일 내용은 동일하게 적용됨","스킬 10종 중 원하는 것만 골라서 설
2치할 수 있음","새 스킬을 기여하면 정해진 검증 스크립트가 형식과 안전 패턴을 자동으로 확인"]},"chosen":false,"selected":false},{"id":"sodam-agentic-eng","title":"SoDam Agentic Eng","category":"Vibe Coding","aspectRatio":"16/9","featured":false,"thumbnail":"","description":"AI에게 뭘 시키기 전 계획부터 보여주고, 끝나면 쉬운 말로 검토해주는 Claude Code·Codex 플러그인","cardDescription":"AI에게 뭘 시키기 전 계획부터 보여주고, 끝나면 쉬운 말로 검토해주는 도구","ogDescription":"AI에게 뭘 시키기 전 계획부터 보여주고, 끝나면 쉬운 말로 검토해주는 Claude Code·Codex 플러그인 — 위험한 명령은 자동으로 차단하거나 확인받음","fullDescription":"Codex에서 실행 중엔 형제 플러그인에게 안전 점검을 위임해도 아무도 못 받는다는 결함을 발견해, Codex에서는 항상 전체 안전장치를 자체 실행하도록 고쳤다.","tags":["JavaScript","Claude Code","Codex","Korean","Safety Hooks","Beginner Friendly","Agentic Engineering","Onboarding"],"githubUrl":"https://github.com/sodam-ai/SoDam-Agentic-Eng","images":[],"challenges":["치명적인 명령은 형제 플러그인 설치 여부와 무관하게 항상 자체적으로 차단","확인·차단 판정마다 안전 기록을 남기고, 비밀값은 저장 전 자동으로 가림","Codex에서 실행 중일 땐 형제에게 위임하지 않고 항상 전체 안전장치를 자체 실행","출처를 확인 안 한 외부 코드를 곧바로 실행하는 명령까지 감지해서 차단"],"techWalkthrough":{"title":"실행 직전에 가로채 안전·확인·차단을 판정하는 구조","description":"","steps":["도구를 실행하기 직전 안전 훅이 먼저 끼어들어 안전·확인·차단 중 하나로 판정","형제 플러그인이 살아있으면 겹치는 위험은 형제에게 위임해 확인창이 두 번 안 뜨게 함","치명적인 명령·설정 파일 위조는 형제 유무와 무관하게 항상 자체적으로 차단","Codex 배포본인지 스스로 판별해, Codex에서는 형제 위임 없이 항상 전체 폴백 사용","확인·차단 판정만 기록하고, 안전하게 통과한 작업은 기록하지 않아 로그가 안 쌓임","외부 네트워크 요청이나 비밀값 저장 없이 도구 이름과 인자만 표준입력으로 확인","규칙 값은 코드가 아니라 데이터 파일로 관리해 코드 수정 없이 조정 가능"]},"chosen":false,"selected":false},{"id":"sodam-reverse-eng","title":"SoDam Reverse Eng","category":"Vibe Coding","aspectRatio":"16/9","featured":false,"thumbnail":"","description":"내 코드가 어떻게 동작하는지 쉬운 한국어로 설명해주고, 보안 장치를 무력화하려는 요청은 자동으로 거부하는 Claude Code 플러그인","cardDescription":"내 코드가 어떻게 동작하는지 쉬운 한국어로 설명해주고, 위험한 요청은 자동으로 거부하는 도구","ogDescription":"내 코드가 어떻게 동작하는지 쉬운 한국어로 설명해주는 Claude Code 플러그인 — 보안 장치를 무력화하려는 요청은 항상 거부, 방어·교육·본인 소유물 분석 전용","fullDescription":"형제 플러그인이 있어도 위험한 요청을 놓치지 않도록, 형제 유무와 무관하게 항상 스스로 안전 점검을 다시 수행하도록 만들었다.","tags":["JavaScript","Claude Code","Korean","Security","Reverse Engineering","Defensive Security","Static Analysis","Android"],"githubUrl":"https://github.com/sodam-ai/SoDam-Reverse-Eng","images":[],"challenges":["보안 장치를 무력화하려는 요청은 이유를 막론하고 항상 거부","안전장치 파일이 바뀌면 통과가 아니라 분석을 즉시 중단","분석 중 발견한 비밀번호·API 키는 보고서에 자동으로 가려서 표시","본인 소유·허가 여부를 버튼 선택형 질문 3개로 먼저 확인한 뒤에만 분석 시작"],"techWalkthrough":{"title":"AI 거부·실시간 차단·무결성 점검을 겹겹이 쌓은 안전 3층 구조","description":"","steps":["분석 시작 전 안전장치 3층이 전부 정상인지 스스로 먼저 재확인","소유권·분석 목적·이용 동의 질문 3개를 버튼으로 통과해야 다음 단계로 진행","코드는 읽기만 하고 절대 실행하지 않음","위험한 요청은 AI 자체 판단과 실시간 차단 훅이 이중으로 거부","안전파일이 바뀌었는지 SHA-256 해시로 확인하는 단계까지 통과해야 동작","분석 결과는 내 컴퓨터에만 저장되고 외부 서버로 전송되지 않음","형제 플러그인이 있으면 위험 패턴을 ê
2³µìœ í•´ 더 강한 안전망을 구성"]},"chosen":false,"selected":false},{"id":"sodam-persona","title":"SoDam Persona","category":"Vibe Coding","aspectRatio":"16/9","featured":false,"thumbnail":"","description":"Claude Code에 15명 전문가 관점을 입혀, 상황에 맞게 자동으로 깊이 있게 답하는\\nAI 페르소나 플러그인","cardDescription":"AI 어시스턴트에 15명 전문가 관점을 입혀, 상황에 맞게 자동으로 깊이 있게 답하는\\n페르소나 플러그인","ogDescription":"Claude Code에 15명 전문가 관점을 입혀, 상황에 맞게 자동으로 깊이 있게 답하는 AI 페르소나 플러그인","fullDescription":"인터뷰 방식으로 새 전문가 관점을 직접 만들거나 ê³ ì¹  수 있고, 관련 파일이 전부 자동으로 맞춰진다.","tags":["JavaScript","Prompt Engineering","CI/CD","Persona","Claude Code","LLM","Hooks","Developer Tools"],"githubUrl":"https://github.com/sodam-ai/SoDam-Persona","images":[],"challenges":["개발·보안·투자 15명 전문가 관점 자동 적용","법률·회계세무 등 균형 잡힌 답변을 자동 제공","세무·법률처럼 민감하면 확인 안내 자동 첨부","새 컴퓨터에서도 짧은 설치로 복원"],"techWalkthrough":{"title":"hookê³¼ skill을 분리한 2단 구조","description":"","steps":["세션·메시지마다 hook이 자동 실행돼 답변 원칙을 AI에 전달","투자·법률 등 특정 주제 감지 시 skill이 깊이 있게 지원","skill이 꺼진 평소엔 가볍게 유지돼 부담 없음","정본 파일 하나로 관리해 확장판과 내용 불일치 방지","hook은 상대경로로 동작해 새 컴퓨터에서도 복원","저장소에 올릴 때마다 GitHub Actions가 관점·규칙 수와 면책 문구를 자동 검사"]},"chosen":false,"selected":false},{"id":"claudetower","title":"ClaudeTower","category":"Vibe Coding","aspectRatio":"16/9","featured":false,"thumbnail":"","description":"Claude Code 화면 아래쪽에 작업 위치·모델·Git 브랜치·대화 사용량·비용·사용률을 보여주는 도구","cardDescription":"AI 코딩 도구 화면 아래쪽에 작업 위치·모델·Git 브랜치·대화 사용량·비용·사용률을 보여주는 상태표시줄","fullDescription":"화면 폭에 따라 막대 그래프 밀도와 표시 항목이 자동으로 조절된다. 넓으면 더 촘촘하게, 좁으면 덜 중요한 항목부터 자동으로 숨겨 줄바꿈을 막는다.","ogDescription":"Claude Code 화면 아래쪽에 작업 위치·모델·Git 브랜치·대화 사용량·비용·사용률을 보여주는 도구 — 설치 파일 하나로 바로 실행","tags":["JavaScript","CLI","Claude Code","Single Executable","Node.js","Statusline","Cross-Platform","Security"],"githubUrl":"https://github.com/sodam-ai/ClaudeTower","images":[],"challenges":["Git 저장소일 때만 브랜치·변경사항 자동 표시","개발 흐름을 방해하지 않고 필요한 정보만 확인 가능","계정 정보를 전혀 다루지 않아 보안 이슈를 원천 차단","복잡한 명령어 없이 채팅 한마디로 설정 변경 가능"],"techWalkthrough":{"title":"상태표시줄과 계정 기능을 모듈 단위로 완전히 분리한 아키텍처","description":"","steps":["Claude Code가 3초 주기로 작업 위치·모델·컨텍스트·비용 정보를 JSON으로 전달","전달받은 값을 사람이 읽기 좋은 한 줄로 가공해 즉시 화면에 반환","외부 서버로 전송하지 않고 전부 내 컴퓨터 안에서만 처리","보안을 위해 상태표시줄과 계정전환 모듈을 처음부터 분리해서 설계","계정 코드는 빌드 시점에 실행 파일에서 자동으로 제외됨","두 기능이 서로 섞이지 않았는지 매 빌드마다 자동으로 검사","Node.js 설치 없이 실행되는 단일 실행파일(SEA)이라 파일 하나로 바로 실행"]},"chosen":false,"selected":false},{"id":"sodam-wikimate","title":"SoDam WikiMate","category":"Vibe Coding","aspectRatio":"16/9","featured":false,"thumbnail":"","description":"AI에게 \'정리해줘\'라고 말하면 흩어진 자료를 옵시디언에 정리·연결·분류·요약까지 해주는 Claude Code 플러그인","cardDescription":"말 한마디로 흩어진 자료를 옵시디언 노트로 정리하고,\\n연결·분류·요약까지 자동으로 해주는 도구","ogDescription":"AI에게 \'정리해줘\'라고 말하면 흩어진 자료를 옵시디언 노트로 정리하고, 관련 노트끼리 연결·분류·요약까지 자동으로 해주는 Claude Code 플러그인 — 삭제 없이 안전하게","fullDescription":"실제로 볼트 밖으로 파일ì
2„ 빼돌리는 공격을 직접 시도해봤고, 위험한 경로는 전부 차단되어 볼트 안에만 파일이 만들어지는 것까지 확인했다.","tags":["JavaScript","MCP","Claude Code","Codex","Obsidian","Notion","Knowledge Management","AI Agent"],"githubUrl":"https://github.com/sodam-ai/SoDam-WikiMate","images":[],"challenges":["요약·자동분류 등 쓰기 작업은 항상 계획부터 보여주고 승인해야 실행","요약 기능은 원문을 수정하는 코드 경로 자체가 없어 원본 그대로 ë³´ì¡´","실행 후에는 별도 검수 서브에이전트가 원문 왜곡 여부를 재확인","삭제 기능 없이 보관함으로 이동만 해 언제든 되돌리기 가능"],"techWalkthrough":{"title":"AI가 판단하고 서버는 후보 제공과 안전한 쓰기만 담당하는 구조","description":"","steps":["MCP 서버 하나가 정리·점검·수정·기록·보관함찾기·링크·분류·요약 8개 도구를 배선","관련·분류 판단은 AI가 직접 하고, 서버는 후보 제공과 안전한 쓰기만 담당","한 노트에 이어지는 관련 노트는 최대 5개로 코드가 강제해 그래프가 엉키는 것을 방지","볼트 밖 경로·상위 폴더 이동·네트워크 경로는 코드로 전부 차단","외부 텍스트 속 지시문은 명령이 아니라 데이터로만 처리해 프롬프트 인젝션을 방어","만들거나 옮기거나 고친 모든 작업이 로그 파일에 자동으로 기록","외부 라이브러리 없이 Node.js 기본 기능만으로 동작하는 무의존 서버"]},"chosen":false,"selected":false},{"id":"sodam-o-brain","title":"SoDam O-Brain","category":"Vibe Coding","aspectRatio":"16/9","featured":false,"thumbnail":"","description":"Claude Code·Codex 대화에서 결정·약속을 자동으로 기억해두고, 지식 그래프로 검색·시각화해주는 완전 로컬 AI 기억 도구","cardDescription":"AI 대화에서 결정·약속을 자동으로 기억해두고,\\n지식 그래프로 검색·시각화해주는 완전 로컬 기억 도구","ogDescription":"Claude Code·Codex 대화에서 결정·약속을 자동으로 기억해두고, 지식 그래프로 검색·시각화해주는 완전 로컬 AI 기억 도구 — 외부 전송 없이 API 키·과금도 없음","fullDescription":"기억이 5000건까지 쌓인 환경에서 그래프 생성이 9.8초 걸리던 걸, 일정 개수를 넘으면 자동으로 단순화하는 성능 가드로 8ms까지 줄였다(약 300ë°°).","tags":["JavaScript","SQLite","Knowledge Graph","MCP","Claude Code","Local-First","Memory","Embeddings"],"githubUrl":"https://github.com/sodam-ai/SoDam_O-Brain","images":[],"challenges":["API 키·비밀번호는 저장 전 자동으로 지워지고, 서버도 내 컴퓨터 안에서만 열림","확인된 기억이 자동 추출 노이즈보다 검색 ê²°ê³¼ 위로 오도록 순위 반영","비슷한 기억은 자동으로 찾아 병합·삭제 제안, 완전히 같은 내용은 일괄 정리도 가능","삭제해도 10초 안에 되돌릴 수 있고, ê·¸ 전에 자동 백업부터 만들어둠"],"techWalkthrough":{"title":"키워드 검색과 의미 검색을 함께 쓰는 하이브리드 구조","description":"","steps":["대화 내용은 보안 필터를 거친 뒤 로컬 AI 임베딩을 만들어 SQLite에 저장","검색은 키워드(FTS5)와 의미 유사도(벡터) 결과를 함께 반영해 순위를 매김","AI가 자동으로 뽑아낸 기억은 30일 반감기로 신뢰도가 점점 낮아짐","날짜를 지정하면 ê·¸ 시점 기준으로 살아있던 기억만 시간여행하듯 조회 가능","관계가 없는 기억은 사람이 직접 연결 여부를 결정하는 제안 큐로만 올라감","서버 실행마다 새 로컬 API 토큰을 발급해 모든 요청을 검사","웹 대시보드 자체는 Claude Code 없이도 단독으로 실행 가능"]},"chosen":false,"selected":false},{"id":"sodam-agent","title":"SoDam-Agent","category":"Vibe Coding","aspectRatio":"16/9","featured":false,"thumbnail":"","description":"Claude Code에 AI 에이전트 팀 10종을 한 번에 설치하고, 내 에이전트도 직접 만들고 가르칠 수 있는 플러그인","cardDescription":"역할별 AI 에이전트 팀 10종을 한 번에 설치하고,\\n설치 후에는 내 에이전트를 직접 만들고 가르칠 수 있는 도구","ogDescription":"Claude Code에 역할별 AI 에이전트 팀 10종을 한 번에 설치하고, 설치 후에는 내 에이전트를 직접 만들고 가르칠 수 있는 플러그인 — Codex·Gemini CLI·Cursor용 베타 지원까지","fullDescription":"남이 만든 팀 파일의 설명·모델 값에 줄바꿈을 몰래 심어 에이전트 권한을 조작하는 공격을 실제로 재현해 찾아내고 막았다.","tags":["JavaScript","Claude Code","Subagents","MCP","Plugin Marketplace","Codex","Cursor","Agent Team"],"githubUrl":"https://github.com/sodam-ai/SoDam-Agent","images":[],"challenges":["팀 에이전트는 직접 ê³ ì¹  수 없고, 복사본을 만들어야만 내 방식대로 가르칠 수 있음","위험한 명령을 담은 도구나 알 수 없는 필드가 섞인 팀 파일은 설치 전에 자동으로 걸러짐","API 키는 파일에 직접 적지 않고 이름만 등록해 실제 값은 내 컴퓨터 환경변수에 남김","Codex·Gemini CLI·Cursor는 방식이 달라 못 미치는 부분까지 정직하게 밝히고 지원"],"techWalkthrough":{"title":"서버 없이 GitHubê³¼ Claude Code만으로 동작하는 설치형 구조","description":"","steps":["마켓플레이스 등록 한 번, 팀 설치는 원하는 팀만 골라서 설
2치","설치된 팀은 GitHub에서 받아와 캐시 폴더에 저장, 재시작하면 팀:역할로 등록됨","이름이 팀:역할 형식이라 내가 만든 직원과 팀 직원이 항상 구분됨","각 직원은 검토자는 읽기 전용처럼 필요한 도구만 최소 권한으로 부여받음","context7 같은 자료검색 도구는 웹앱팀·리서치팀 설치 시 자동으로 함께 연결됨","새 직원 만들기·가르치기·저장·복사·삭제까지 명령 5개로 터미널 없이 처리","직원 삭제는 백업 파일을 남기고 최신 10개까지만 자동으로 유지"]},"chosen":false,"selected":false},{"id":"sodam-design-kit","title":"SoDam Design Kit","category":"Vibe Coding","aspectRatio":"16/9","featured":false,"thumbnail":"","description":"Figma 디자인을 shadcn/ui 코드로 만들고, 실제 브라우저 검증을 통과해야만 완료로 인정하는 Claude Code 디자인 자동화 플러그인","cardDescription":"Figma 디자인을 shadcn/ui 코드로 만들고, 실제 브라우저 검증을 통과해야만 완료로 인정하는 도구","ogDescription":"Figma 디자인을 shadcn/ui 코드로 만들고, 실제 브라우저 검증(Playwright+axe-core)을 통과해야만 완료로 인정하는 Claude Code 디자인 자동화 플러그인 — 완료 보고 자체를 기계적으로 차단","fullDescription":"판정서에는 성공이라고 적혀 있는데 정작 스크린샷 파일이 프로젝트 폴더 밖에 저장되는 결함을 새 세션 재현 테스트 중 발견해, 저장 위치를 항상 프로젝트 폴더 기준으로 다시 계산하도록 고쳤다.","tags":["JavaScript","Claude Code","Figma","Next.js","shadcn/ui","Playwright","Accessibility","Design Automation"],"githubUrl":"https://github.com/sodam-ai/SoDam-Design-Kit","images":[],"challenges":["실제 브라우저 검증을 통과 못 하면 완료라고 보고하는 것 자체를 기계적으로 차단","새 컴포넌트에 색상·간격 값이 숫자로 하드코딩돼 있으면 배치 자체를 거부","모바일·태블릿·PC 3가지 화면 크기와 접근성 검사를 자동으로 통과해야 함","실패해도 최대 3회까지 자동 재시도하고, 연속 2회 실패해야 최종 실패로 확정"],"techWalkthrough":{"title":"Figma 디자인을 읽어 코드로 만들고 브라우저에서 직접 검증하는 파이프라인","description":"","steps":["Figma 공유 링크를 읽어 컴포넌트 매핑 정보로 기록","매핑된 컴포넌트는 재사용하고, 없는 컴포넌트는 새로 코드로 생성","생성한 코드를 미리보기 화면으로 띄우고 개발 서버를 자동 실행","실제 브라우저에서 접근성 검사와 3가지 화면 크기 검사를 자동 실행","통과하면 판정서를 남기고, 실패하면 완료 보고 자체가 막힘","한 번 읽은 Figma 정보는 저장해두고 재사용해 무료 플랜의 월 6회 제한을 아낌","Figma 이미지 주소는 7일 뒤 만료되므로 즉시 내려받아 로컬에 저장"]},"chosen":false,"selected":false},{"id":"business-counselor","title":"Business Counselor","category":"Vibe Coding","aspectRatio":"16/9","featured":false,"thumbnail":"","description":"사업 아이디어를 13명 전문가 관점과 적대 토론으로 냉철하게 판독해 go·iterate·no-go 판정까지 내려주는 Claude Code 플러그인","cardDescription":"사업 아이디어를 13명 전문가 관점으로 냉철하게 판독해\\ngo·iterate·no-go로 판정해주는 도구","ogDescription":"사업 아이디어를 입력하면 13명 전문가 관점과 적대 토론으로 냉철하게 판독해 go·iterate·no-go 판정까지 내려주는 Claude Code 플러그인 — 외부 전송 없이 전부 로컬에만 저장","fullDescription":"분석을 맡는 서브에이전트에는 읽기·쓰기 권한만 주고 인터넷 접속 도구 자체를 아예 주지 않아, 외부로 새어나가는 게 정책이 아니라 구조적으로 불가능하다.","tags":["Claude Code","Markdown","Prompt Engineering","Business Analysis","Lean Canvas","Decision Support","CLI","Startup"],"githubUrl":"https://github.com/sodam-ai/business-counselor","
2images":[],"challenges":["법무·투자자 관점이 강하게 부정적이면 판정은 보완·비추천 쪽으로 강제로 기울어짐","아이디어가 모호하면 AI가 임의로 넘겨짚지 않고 먼저 보강 질문부터 함","프로필 기반으로 AI가 먼저 사업 아이디어를 추천해주는 기능도 지원","모든 결정 기록은 지우거나 고칠 수 없게 계속 쌓이기만 함"],"techWalkthrough":{"title":"명령 하나가 서브에이전트 호출 한 번으로 5단계 분석을 전부 끝내는 구조","description":"","steps":["evaluate 한 번으로 13명 평가부터 적대 토론까지 5단계를 모두 한 번에 처리","평가 결과에는 어느 시점 프로필을 기준으로 만들어졌는지 확인 값이 실제로 계산되어 함께 저장됨","결과는 판정·확신도·강점·막힌 곳·다음 행동을 담은 「한눈 요약」 카드로 먼저 보여줌","전체 모드로 보면 5단계 상세 분석까지 같은 깊이로 전부 확인 가능","별도 서버나 데이터베이스 없이 마크다운 파일과 Claude Code 하나로만 동작","인터뷰로 쌓은 자본·시간·역량 정보가 있으면 평가가 내 상황에 맞춰 더 구체적으로 나옴","프로필을 지우면 비가역 경고와 명시적 확인을 거친 뒤에만 실제로 삭제됨"]},"chosen":false,"selected":false}]')}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.