/* 포트폴리오 — Figma 01 · PORTFOLIO DESIGNS (Desktop 1920 / Tablet 768 / Mobile 390, 가로·세로영상). */
.portfolio{
  --collection-gap:48px;--collection-bottom:120px;
  --grid-gap:32px;--more-top:32px;
  --card-pad:32px;--card-title:24px;--card-title-line:32px;
  --card-radius:2px; /* 목록 카드 모서리 — 거의 각지게, 끝만 살짝 굴린다 */
}

/* 제목 영역은 common.css의 .page-heading을 쓰고, 가운데 정렬과 아래 여백만 바꾼다. */
.portfolio .page-heading{align-items:center;text-align:center;padding-bottom:32px}

/* 형식 탭 */
.portfolio-collection{display:flex;flex-direction:column;align-items:center;gap:var(--collection-gap);padding-bottom:var(--collection-bottom)}
.format-tabs{position:relative;display:flex;gap:32px}
.format-tabs button{width:120px;height:48px;text-align:center;font-size:18px;line-height:24px;font-weight:500;color:var(--muted);transition:color .2s}
.format-tabs button[aria-selected=true],.format-tabs button:hover{color:var(--mint)}
.format-tabs::after{content:'';position:absolute;left:0;bottom:0;width:120px;height:2px;background:var(--mint);transition:transform .3s cubic-bezier(.2,.7,.2,1)}
.format-tabs.is-portrait::after{transform:translateX(152px)}

/* 카드 그리드 — 가로영상 16:9 2열, 세로영상 9:16 4열 */
.portfolio-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--grid-gap);width:100%;transition:opacity .3s,translate .3s var(--ease-in-out)}
.portfolio-grid.is-portrait{grid-template-columns:repeat(4,minmax(0,1fr));--card-pad:24px}
.portfolio-grid.is-switching{opacity:0;translate:0 24px}
/* 카드: 기울기(--rx·--ry)·빛(--gx·--gy)·이미지 밀림(--mx·--my)은 portfolio.js가 마우스 위치로 정한다. */
.portfolio-card{position:relative;display:block;overflow:hidden;border-radius:var(--card-radius);aspect-ratio:16/9;background:var(--surface);color:#fff;isolation:isolate;
  transform:perspective(1200px) rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg));transition:transform .7s var(--ease-out)}
.is-portrait .portfolio-card{aspect-ratio:9/16}
.portfolio-card.is-lifted{visibility:hidden}
.portfolio-card .card-media{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  translate:var(--mx,0px) var(--my,0px);scale:1.12;transition:scale .9s var(--ease-out),translate .7s var(--ease-out),filter .6s}
.portfolio-card:hover .card-media{scale:1.2}
.portfolio-grid:has(.portfolio-card:hover) .portfolio-card:not(:hover) .card-media{filter:brightness(.55) saturate(.6)}
.portfolio-card::before{content:'';position:absolute;inset:0;z-index:1;pointer-events:none;opacity:0;transition:opacity .5s;
  background:radial-gradient(circle at var(--gx,50%) var(--gy,50%),rgba(255,255,255,.22),rgba(94,234,212,.08) 30%,transparent 55%)}
.portfolio-card:hover::before{opacity:1}
/* 유튜브 미리보기: 재생이 시작되고 잠시 뒤(.is-previewing) 썸네일 위로 나타난다. 세로 카드에서도 가득 차게 16:9 플레이어를 키우고,
   가장자리에 붙는 유튜브 프로필·제목·로고가 잘려 나가도록 --preview-zoom만큼 확대한다(클수록 깔끔하지만 영상이 더 잘린다).
   scale로 늘리면 작은 플레이어를 잡아 늘린 셈이라 유튜브가 낮은 화질을 보내므로, 실제 크기를 키워 높은 화질을 받는다. */
.card-preview{--preview-zoom:1;position:absolute;inset:0;overflow:hidden;container-type:size;pointer-events:none;opacity:0;transition:opacity .5s}
.card-preview iframe{position:absolute;left:50%;top:50%;border:0;translate:-50% -50%;
  width:calc(max(100cqw,100cqh * 16 / 9) * var(--preview-zoom));height:calc(max(100cqh,100cqw * 9 / 16) * var(--preview-zoom))}
.portfolio-card.is-previewing .card-preview:not(.is-leaving){opacity:1}
.portfolio-card::after,.viewer-media::after{content:'';position:absolute;inset:50% 0 0;background:linear-gradient(180deg,rgba(0,0,0,0),rgba(0,0,0,.38) 50%,rgba(0,0,0,.92));pointer-events:none}
.card-number{position:absolute;top:var(--card-pad);right:var(--card-pad);z-index:1;font-size:14px;line-height:22px}
.card-title{position:absolute;left:var(--card-pad);right:var(--card-pad);bottom:var(--card-pad);z-index:1;font-size:var(--card-title);line-height:var(--card-title-line);font-weight:600;text-align:left}
/* 제목: 올리면 글자가 차례로 위로 넘어가며 민트 글자로 바뀐다. */
.portfolio-card .char>span{position:relative;transition:translate .55s var(--ease-out) calc(var(--i) * 18ms)}
.portfolio-card .char>span::after{content:attr(data-c);position:absolute;left:0;top:100%;color:var(--mint)}
.portfolio-card:hover .char>span,.portfolio-card:focus-visible .char>span{translate:0 -100%}
.portfolio-card .card-number{transition:translate .5s var(--ease-out),color .3s}
.portfolio-card:hover .card-number{translate:-4px 4px;color:var(--mint)}

/* 카드 등장: 아래에서 투명하게 시작해 부드럽게 떠오른다(처음 빠르고 끝에서 아주 천천히 멈춤). 한 번에 들어온 카드끼리는 --d만큼 차례로. */
@media(prefers-reduced-motion:no-preference){
  .js .portfolio-card:not(.is-in){opacity:0;translate:0 40px}
  .js .portfolio-card.is-in{animation:card-rise .9s var(--ease-out) var(--d,0ms) backwards}
  .viewer-dialog[open]::backdrop{animation:fade-in .6s}
  .viewer-dialog.is-closing::backdrop{animation:fade-out .6s .1s forwards}
  .viewer-dialog[open] .viewer-control,.viewer-dialog[open] .viewer-inquiry{animation:fade-in .6s .55s backwards}
  .viewer-dialog.is-closing .viewer-control,.viewer-dialog.is-closing .viewer-inquiry{opacity:0;transition:opacity .25s}
}
@keyframes card-rise{from{opacity:0;translate:0 40px}}
.portfolio-empty{padding:80px 0;color:var(--muted);font-size:18px;text-align:center}
.load-more-area{display:flex;justify-content:center;padding-top:var(--more-top)}
.load-more-area:has(> [hidden]){display:none}

/* 작품 뷰어 */
.viewer-dialog{--media-w:min(1280px,calc(100vw - 320px),calc((100dvh - 256px) * 16 / 9));--stage-gap:32px;
  --card-pad:32px;--card-title:24px;--card-title-line:32px;
  width:100%;max-width:none;height:100dvh;max-height:none;margin:0;padding:0 0 24px;border:0;background:transparent;
  flex-direction:column;align-items:center;justify-content:center;gap:32px}
.viewer-dialog[open]{display:flex}
.viewer-dialog::backdrop{background:rgba(0,0,0,.7)}
.viewer-dialog.is-portrait{--media-w:min(450px,calc((100dvh - 256px) * 9 / 16));--card-pad:24px}
.viewer-stage{display:flex;align-items:center;gap:var(--stage-gap)}
.viewer-control{flex:none;width:48px;height:48px;display:grid;place-items:center;border-radius:50%;transition:background .2s,translate .6s var(--ease-out)}
.viewer-control:hover{background:rgba(255,255,255,.12)}
.viewer-close{position:absolute;top:32px;right:48px}
.viewer-close img{transition:rotate .5s var(--ease-out)}
.viewer-close:hover img{rotate:90deg}
.viewer-media{position:relative;width:var(--media-w);aspect-ratio:16/9;overflow:hidden;border-radius:16px;background:#000;color:#fff;transform-origin:0 0}
.is-portrait .viewer-media{aspect-ratio:9/16}
.viewer-frame,.viewer-frame img,.viewer-frame video,.viewer-youtube,.viewer-youtube iframe{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.viewer-youtube iframe{border:0;background:transparent}
.viewer-media:has(video,iframe)::after,.viewer-media:has(video,iframe) .card-number,.viewer-media:has(video,iframe) .card-title{display:none}
/* 데스크톱은 마우스를 올리면 제목·번호가 나타나고, 터치 기기는 처음부터 보인다. */
@media(hover:hover){
  .viewer-media::after,.viewer-media .card-number,.viewer-media .card-title{opacity:0;transition:opacity .25s}
  .viewer-media:hover::after,.viewer-media:hover .card-number,.viewer-media:hover .card-title{opacity:1}
}

/* 전용 영상 플레이어(.vp) — 직접 올린 MP4를 모달에서 재생한다(portfolio.js videoPlayer).
   재생 중 2초 동안 움직임이 없으면(.is-idle) 막대와 커서를 숨겨 영상만 남긴다. */
.vp{--vp-pad:24px;position:absolute;inset:0;overflow:hidden;background:#000;color:#fff;cursor:pointer;user-select:none;-webkit-user-select:none}
.vp video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.is-portrait .vp video,.vp:fullscreen video{object-fit:contain}
.vp:fullscreen{--vp-pad:40px}
.vp::after{content:'';position:absolute;inset:auto 0 0;height:45%;pointer-events:none;background:linear-gradient(180deg,transparent,rgba(0,0,0,.75));transition:opacity .5s}
.vp-head{position:absolute;top:var(--vp-pad);left:var(--vp-pad);right:var(--vp-pad);z-index:1;display:flex;align-items:baseline;gap:12px;pointer-events:none;transition:opacity .5s,translate .5s var(--ease-out)}
.vp-head span{font:500 14px/22px var(--font-latin);color:var(--mint)}
.vp-head strong{font-size:20px;line-height:28px;font-weight:600;text-shadow:0 1px 12px rgba(0,0,0,.4)}
.vp-bar{position:absolute;left:var(--vp-pad);right:var(--vp-pad);bottom:var(--vp-pad);z-index:2;display:flex;align-items:center;gap:8px;cursor:default;
  transition:opacity .5s,translate .5s var(--ease-out)}
.vp-btn{flex:none;width:40px;height:40px;display:grid;place-items:center;border-radius:50%;transition:background .2s,scale .3s var(--ease-out)}
.vp-btn:hover{background:rgba(255,255,255,.14)}
.vp-btn:active{scale:.9}
.vp-btn svg{width:20px;height:20px;fill:currentColor}
.vp-btn [data-on],.vp-btn.is-on [data-off]{display:none}
.vp-btn.is-on [data-on]{display:block}
.vp-time{flex:none;min-width:96px;padding-inline:4px;font:500 13px/1 var(--font-latin);letter-spacing:.04em;font-variant-numeric:tabular-nums;color:rgba(255,255,255,.85)}
/* 재생 막대: 위로 올리면 굵어지고 손잡이·프레임 미리보기가 나타난다. */
.vp-track{--progress:0;--buffered:0;--hover:0;position:relative;flex:1;height:28px;cursor:pointer;touch-action:none}
.vp-track:focus-visible{outline-offset:2px}
.vp-line{position:absolute;left:0;right:0;top:50%;height:3px;translate:0 -50%;border-radius:3px;background:rgba(255,255,255,.22);overflow:hidden;transition:height .25s var(--ease-out)}
.vp-line i{position:absolute;inset:0;transform-origin:left}
.vp-line i:first-child{background:rgba(255,255,255,.3);scale:var(--buffered) 1}
.vp-line i:last-child{background:var(--mint);scale:var(--progress) 1}
.vp-knob{position:absolute;top:50%;left:calc(var(--progress) * 100%);width:14px;height:14px;margin:-7px 0 0 -7px;border-radius:50%;background:var(--mint);
  box-shadow:0 0 0 4px rgba(94,234,212,.25);scale:0;transition:scale .25s var(--ease-out)}
.vp-track:hover .vp-line,.vp-track.is-dragging .vp-line{height:6px}
.vp-track:hover .vp-knob,.vp-track.is-dragging .vp-knob,.vp-track:focus-visible .vp-knob{scale:1}
.vp-thumb{position:absolute;bottom:calc(100% + 10px);left:clamp(80px,calc(var(--hover) * 100%),calc(100% - 80px));width:160px;translate:-50% 0;
  display:flex;flex-direction:column;align-items:center;gap:6px;pointer-events:none;opacity:0;scale:.9;transition:opacity .2s,scale .3s var(--ease-out)}
.vp-thumb-img{width:160px;height:90px;border-radius:8px;border:1px solid rgba(255,255,255,.25);background:#111 no-repeat;box-shadow:0 8px 24px rgba(0,0,0,.4)}
.vp-thumb-time{padding:3px 8px;border-radius:999px;background:rgba(8,10,9,.7);font:500 12px/16px var(--font-latin);font-variant-numeric:tabular-nums}
.vp-track:hover .vp-thumb,.vp-track.is-dragging .vp-thumb{opacity:1;scale:1}
/* 가운데: 멈춰 있으면 큰 재생 버튼, 누를 때마다 아이콘이 퍼지며 사라진다. */
.vp-center{position:absolute;left:50%;top:50%;z-index:1;width:72px;height:72px;margin:-36px 0 0 -36px;display:grid;place-items:center;border-radius:50%;
  background:var(--mint);color:var(--bg);pointer-events:none;opacity:0;scale:.6;transition:opacity .35s,scale .5s var(--ease-out)}
.vp-center svg{width:26px;height:26px;fill:currentColor}
.vp.is-paused .vp-center{opacity:1;scale:1}
.vp-pulse{position:absolute;left:50%;top:50%;z-index:1;width:72px;height:72px;margin:-36px 0 0 -36px;display:grid;place-items:center;border-radius:50%;
  background:rgba(8,10,9,.5);pointer-events:none;opacity:0}
.vp-pulse svg{width:28px;height:28px;fill:#fff}
.vp.is-idle{cursor:none}
.vp.is-idle .vp-bar,.vp.is-idle .vp-head{opacity:0;translate:0 8px;pointer-events:none}
.vp.is-idle .vp-head{translate:0 -8px}
.vp.is-idle::after{opacity:0}

@media(min-width:1200px) and (max-width:1439px){
  .portfolio .portfolio-grid.is-portrait{--card-title:20px;--card-title-line:28px}
}
@media(max-width:1199px){
  .portfolio{
    --collection-gap:32px;--collection-bottom:80px;
    --grid-gap:24px;--card-pad:20px;--card-title:18px;--card-title-line:26px;
  }
  .format-tabs button{font-size:16px;font-weight:600}
  .portfolio-grid.is-portrait{grid-template-columns:repeat(2,minmax(0,1fr));--card-pad:20px}
  .viewer-dialog{--media-w:min(608px,calc(100vw - 160px),calc((100dvh - 256px) * 16 / 9));--stage-gap:16px;--card-pad:20px;--card-title:18px;--card-title-line:26px}
  .viewer-dialog.is-portrait{--media-w:min(360px,calc(100vw - 160px),calc((100dvh - 256px) * 9 / 16));--card-pad:20px}
  .viewer-close{top:24px;right:32px}
}
@media(max-width:599px){
  .portfolio{
    --collection-gap:24px;--collection-bottom:64px;
    --grid-gap:16px;--more-top:16px;--card-pad:16px;
  }
  .portfolio .page-heading{padding-bottom:24px}
  .format-tabs button{font-size:16px;line-height:22px;font-weight:500}
  .portfolio-grid.is-landscape{grid-template-columns:minmax(0,1fr)}
  .portfolio-grid.is-portrait{--card-pad:12px;--card-title:14px;--card-title-line:22px}
  .is-portrait .card-title{font-weight:700;letter-spacing:0}
  .viewer-dialog{--media-w:min(286px,calc(100vw - 104px));--stage-gap:4px;--card-pad:16px}
  .viewer-dialog.is-portrait{--media-w:min(270px,calc(100vw - 104px),calc((100dvh - 256px) * 9 / 16));--card-pad:12px;--card-title:14px;--card-title-line:22px}
  .viewer-close{top:20px;right:20px}
  .vp{--vp-pad:12px}
  .vp-head strong{font-size:15px;line-height:22px}
  .vp-bar{gap:2px}
  .vp-time{min-width:0;font-size:11px}
  .vp-btn{width:36px;height:36px}
  .vp-center{width:56px;height:56px;margin:-28px 0 0 -28px}
  .vp-center svg{width:20px;height:20px}
  .vp-thumb{display:none}
}
/* 데스크톱 — 목록은 좌우 빈 여백 없이 화면 폭을 다 쓰고(헤더·제목 영역은 서비스 페이지와 같은 폭), 가로영상은 큰 카드(2×2칸)와 작은 카드를 섞은 모자이크로 놓는다.
   4열에 10장마다 큰 카드 2장이 왼쪽·오른쪽 번갈아 놓인다(자리는 portfolio/index.php의 $bigCols → .is-big, --big-col). 세로는 2×2로 키우면 화면보다 길어져 5열로 고르게 둔다. */
@media(min-width:1200px){
  .portfolio-collection{--gutter:clamp(40px,3.4vw,80px)}
  .portfolio .container{max-width:none}
  .portfolio{--grid-gap:24px;--card-pad:clamp(16px,1.25vw,24px);--card-title:clamp(16px,1.05vw,20px);--card-title-line:clamp(24px,1.5vw,28px)}
  .portfolio-grid.is-landscape{grid-template-columns:repeat(4,minmax(0,1fr));grid-auto-flow:dense}
  .portfolio-grid.is-portrait{grid-template-columns:repeat(5,minmax(0,1fr));--card-title:24px;--card-title-line:32px}
  .portfolio-card.is-big{grid-column:var(--big-col,auto)/span 2;grid-row:span 2;place-self:stretch;--card-pad:40px;--card-title:32px;--card-title-line:42px}
}
@media(prefers-reduced-motion:reduce){
  .portfolio-card:hover .card-media{scale:1.12}
}
