/* ═══════════════════════════════════════════════════════════════════════════
   info02-trace.css — info02 뒷배경 라인 위를 도는 빛
   명탐정토토(dosiraktoto02) · 2026-09-28 · v2

   두 곳에 같은 연출이 걸린다 —
     A. info01 블록 "소소하게 토토를…"  뒷배경 트랙 라인 (겹친 링 4개)
     B. info02 블록 "날카롭게 찾고,…"   뒷배경 네트워크 (.bg01 / .bg02)

   레퍼런스: https://canvasui.dev/docs/components/vhs
   tools/ref.js 로 런타임에서 뽑은 VHS 셰이더
   (_lib/motion/captures/ref/canvasui-vhs/shaders/01.frag.glsl) 에서
   이 크기에 실제로 읽히는 것만 골라 옮겼다 —

     uAberration  R 은 앞, B 은 뒤로 번지는 색수차  → 빛 띠의 가로 그라디언트
     uBloom       비대칭 커널의 가로 번짐          → 띠 양끝 긴 감쇠
     uAcBeat      느린 밝기 맥동                   → tr-beat
     uCrease      가로 띠가 세로로 흘러가며 일그러짐 → .band
     uSwitching   가끔 한 번 크게 끊기는 드롭아웃  → tr-drop

   그레인(uGrain)과 스캔라인(uScanlines)은 뺐다. 선이 1px 라 픽셀 단위
   노이즈를 얹으면 연출이 아니라 선이 깨진 것으로 보인다.

   [왜 캔버스를 안 쓰는가]
   배경 장식이라 페이지가 열려 있는 내내 돈다. 캔버스면 rAF 가 계속 돌지만
   여기는 전부 transform/opacity 라 합성기에서만 돈다 — 메인 스레드 부하 0.

   [왜 conic-gradient 를 회전시키지 않는가]
   각도를 돌리려면 요소가 박스 대각선을 덮어야 해서 PC 에서 4.6Mpx 짜리
   레이어가 생긴다(DPR2 면 73MB). 중심에서 바깥으로 뻗은 막대 하나를
   돌리면 0.3Mpx 면 된다. 선에 닿는 지점은 똑같다.

   [마스크 — 원본 라인 파일을 그대로 쓰지 않는다]
   라인 알파가 낮아서(A 는 최대 0.25, B 는 0.53) 그대로 마스크로 쓰면
   빛이 그만큼 깎여 아무리 밝게 칠해도 안 보인다. 그래서 따로 구웠다 —

       glow = max( line / line.max(),  gauss(line, σ) / gauss.max() * 0.55 )

   첫째 항이 또렷한 선(A 는 4배 밝아진다), 둘째 항이 셰이더의 uBloom 이다.
   런타임 filter:blur 로 번지게 하면 회전하는 자식 때문에 매 프레임 다시
   흐려야 해서 합성기만으로 돈다는 이점이 사라진다.

     A → ..._bg_glow.png       σ 7(PC) / 5(모바일)
     B → ..._bg0N_glow.svg     σ 6. SVG 안에 박힌 PNG 를 1400x489 로 줄여
                               다시 심었다 — 네 SVG 가 같은 PNG 를 물고 있어
                               마스크 한 장이면 된다. 바깥 <rect> 의 회전·
                               위치를 그대로 두므로 원본과 정확히 겹친다.
                               여기는 알파 분포가 넓어 정규화만으로는 선 평균이
                               0.43 에 머물러(최대 픽셀차 110) 감마 0.55 를 더
                               걸었다 → 선 평균 0.63. A 는 원본 분포가 좁아
                               (평균/최대 = 0.72) 정규화만으로 충분하다.

   ※ 라인 원본을 바꾸면 이 마스크들도 위 식으로 다시 구워야 한다.

   [언제 켜지는가]
   index.html 의 main_info02_info01_ani() / main_info02_info02_ani() 가
   배경 등장이 끝난 뒤 .bg 에 is-traced 를 붙인다. 라인이 다 뜨기 전에
   빛이 돌면 무엇을 따라 도는 빛인지 안 읽힌다.
   ═══════════════════════════════════════════════════════════════════════════ */


/* ── 공용 ────────────────────────────────────────────────────────────────────
   .glow_con 을 쓰는 곳은 이 두 군데뿐이라 짧게 잡는다. 자리마다 다른 것은
   마스크와 아래 커스텀 속성뿐이다 —
     --tr-len      막대 길이 (박스 폭 기준). 박스 반대각보다 길어야 한다
     --tr-thick    막대 두께 (박스 높이 기준)
     --tr-falloff  길이 방향 감쇠. 밝은 구간을 선이 실제로 있는 거리에 맞춘다  */

#main_con > .info02_con .glow_con {
	--tr-lap:9s;      /* 한 바퀴 */
	--tr-beat:3.7s;   /* 밝기 맥동 — 한 바퀴와 약수 관계가 아니어야 반복이 안 읽힌다 */
	--tr-band:5.3s;   /* 트래킹 띠가 훑고 지나가는 주기 */
	--tr-drop:9.7s;   /* 드롭아웃 주기 */
	--tr-len:78%;
	--tr-thick:22%;

	position:absolute;
	top:0; left:0; right:0; bottom:0;
	pointer-events:none;
	z-index:1;                                   /* 배경 그림 위 */
	opacity:0;
	-webkit-transition:opacity 0.9s ease;
	        transition:opacity 0.9s ease;

	/* mask 기본 모드가 alpha 라 회색조 파일은 안 먹는다 — 모양은 알파에 있다 */
	-webkit-mask-size:100% 100%;  mask-size:100% 100%;
	-webkit-mask-repeat:no-repeat; mask-repeat:no-repeat;
	-webkit-mask-position:center;  mask-position:center;
}

#main_con > .info02_con .is-traced > .glow_con { opacity:1; }

/* 도는 빛 — 중심에 꽂힌 막대가 한 바퀴 돈다 */
#main_con > .info02_con .glow_con > .ray {
	position:absolute;
	top:50%; left:50%;
	width:var(--tr-len); height:var(--tr-thick);
	-webkit-transform-origin:0 50%;
	        transform-origin:0 50%;
	-webkit-animation:hd-tr-lap var(--tr-lap) linear infinite,
	                  hd-tr-beat var(--tr-beat) ease-in-out infinite;
	        animation:hd-tr-lap var(--tr-lap) linear infinite,
	                  hd-tr-beat var(--tr-beat) ease-in-out infinite;
	will-change:transform;
}

/* 색수차 — 셰이더는 R 을 +x, B 을 -x 에서 뽑는다(uAberration).
   막대는 시계방향으로 도니 진행쪽(아래)이 R, 꼬리쪽(위)이 B 다. */
#main_con > .info02_con .glow_con > .ray > i {
	display:block;
	width:100%; height:100%;
	background:linear-gradient(to bottom,
		rgba(90,150,255,0)     0%,
		rgba(90,150,255,0.45) 22%,
		rgba(170,210,255,0.8) 40%,
		rgba(240,248,255,1)   50%,
		rgba(255,180,170,0.8) 60%,
		rgba(255,105,105,0.45) 78%,
		rgba(255,105,105,0)  100%);
	-webkit-mask-image:var(--tr-falloff);
	        mask-image:var(--tr-falloff);
	-webkit-animation:hd-tr-drop var(--tr-drop) linear infinite;
	        animation:hd-tr-drop var(--tr-drop) linear infinite;
}

/* 트래킹 띠 — 셰이더 uCrease. 가로 띠가 세로로 흘러가며 지나간 자리를 흔든다 */
#main_con > .info02_con .glow_con > .band {
	position:absolute;
	left:0; right:0; top:0;
	height:9%;
	background:linear-gradient(to bottom,
		rgba(255,255,255,0)     0%,
		rgba(150,200,255,0.32) 38%,
		rgba(255,255,255,0.6)  52%,
		rgba(255,140,140,0.26) 68%,
		rgba(255,255,255,0)   100%);
	mix-blend-mode:screen;
	-webkit-animation:hd-tr-band var(--tr-band) linear infinite;
	        animation:hd-tr-band var(--tr-band) linear infinite;
	will-change:transform;
}

@-webkit-keyframes hd-tr-lap {
	from { -webkit-transform:translateY(-50%) rotate(0deg); }
	to   { -webkit-transform:translateY(-50%) rotate(360deg); }
}
@keyframes hd-tr-lap {
	from { transform:translateY(-50%) rotate(0deg); }
	to   { transform:translateY(-50%) rotate(360deg); }
}

/* uAcBeat — 느린 밝기 맥동 */
@-webkit-keyframes hd-tr-beat { 0%,100% { opacity:0.82; } 50% { opacity:1; } }
@keyframes hd-tr-beat        { 0%,100% { opacity:0.82; } 50% { opacity:1; } }

/* uSwitching — 한 주기에 한 번 크게 끊긴다. 나머지 시간은 가만히 있어야
   "가끔 튀는 것"으로 읽힌다 */
@-webkit-keyframes hd-tr-drop {
	0%,   86%  { -webkit-transform:none;                opacity:1; }
	87.5%      { -webkit-transform:translateX(-2.4%);   opacity:0.5; }
	89%        { -webkit-transform:translateX(3.2%);    opacity:1; }
	90.5%      { -webkit-transform:translateX(-1.1%);   opacity:0.72; }
	92%,  100% { -webkit-transform:none;                opacity:1; }
}
@keyframes hd-tr-drop {
	0%,   86%  { transform:none;              opacity:1; }
	87.5%      { transform:translateX(-2.4%); opacity:0.5; }
	89%        { transform:translateX(3.2%);  opacity:1; }
	90.5%      { transform:translateX(-1.1%); opacity:0.72; }
	92%,  100% { transform:none;              opacity:1; }
}

/* 띠 높이가 박스의 9% 라 위아래로 완전히 빼내려면 약 1100% 가 필요하다 */
@-webkit-keyframes hd-tr-band {
	from { -webkit-transform:translateY(1120%); }
	to   { -webkit-transform:translateY(-120%); }
}
@keyframes hd-tr-band {
	from { transform:translateY(1120%); }
	to   { transform:translateY(-120%); }
}


/* ── A. 트랙 라인 ("소소하게 토토를…") ───────────────────────────────────────
   선이 박스 가장자리를 도는 트랙이라, 빛의 밝은 구간을 그 거리에 맞춘다.
   PC 박스 1590x809 · 막대 길이 1240 기준 —
     위아래 직선 구간의 트랙: 중심에서 405px = 33%
     좌우 캡 구간의 트랙    : 중심에서 795px = 64%
   처음엔 76~97% 에 피크를 뒀다가 빛이 트랙 바깥 허공에서만 밝아
   거의 안 보였다 (실측: 최대 픽셀차 135 → 249 로 회복).              */
#main_con > .info02_con > .contents_con > .info01_con > .info01_con > .bg > .glow_con {
	--tr-falloff:linear-gradient(to right,
		rgba(0,0,0,0) 8%,     rgba(0,0,0,0.25) 22%,
		rgba(0,0,0,0.9) 34%,  rgba(0,0,0,1) 50%,
		rgba(0,0,0,0.95) 64%, rgba(0,0,0,0.55) 78%,
		rgba(0,0,0,0) 90%);
	-webkit-mask-image:url("/img/main/main_info02_info01_info01_img_con_bg_glow.png");
	        mask-image:url("/img/main/main_info02_info01_info01_img_con_bg_glow.png");
}


/* ── B. 네트워크 배경 ("날카롭게 찾고,…") ────────────────────────────────────
   여기는 선이 박스 전체에 깔려 있다. 그래서 감쇠를 넓게 잡아 가운데부터
   바깥까지 훑게 하고(레이더 훑기), 막대도 더 길고 두껍게 쓴다.
   박스가 둘(.bg01 왼쪽 / .bg02 오른쪽)이라 반대각이 각각 다르다 —
     PC     bg01 861x487(반대각 494) · bg02 767x544(469)  막대 88% → 758 / 675
     모바일 bg01 175x208(136)        · bg02 213x233(158)  막대 88% → 154 / 187
   78% 로 두면 모바일 bg01 이 136.5 대 136 으로 아슬아슬해 88% 로 올렸다.  */
#main_con > .info02_con > .contents_con > .info02_con > .contents_con > .img_con .bg > .glow_con {
	--tr-len:88%;
	--tr-thick:30%;
	--tr-falloff:linear-gradient(to right,
		rgba(0,0,0,0) 2%,    rgba(0,0,0,0.45) 14%,
		rgba(0,0,0,1) 30%,   rgba(0,0,0,1) 60%,
		rgba(0,0,0,0.6) 76%, rgba(0,0,0,0) 92%);
}

#main_con > .info02_con > .contents_con > .info02_con > .contents_con > .img_con .bg01 > .glow_con {
	-webkit-mask-image:url("/img/main/main_info02_info02_img_con_bg01_glow.svg");
	        mask-image:url("/img/main/main_info02_info02_img_con_bg01_glow.svg");
}
#main_con > .info02_con > .contents_con > .info02_con > .contents_con > .img_con .bg02 > .glow_con {
	-webkit-mask-image:url("/img/main/main_info02_info02_img_con_bg02_glow.svg");
	        mask-image:url("/img/main/main_info02_info02_img_con_bg02_glow.svg");
}

/* 좌우 두 판이 똑같이 돌면 헤드라이트 두 개처럼 보인다 — 오른쪽을 살짝 늦춘다 */
#main_con > .info02_con > .contents_con > .info02_con > .contents_con > .img_con .bg02 > .glow_con > .ray {
	-webkit-animation-delay:-2.4s, 0s;
	        animation-delay:-2.4s, 0s;
}
#main_con > .info02_con > .contents_con > .info02_con > .contents_con > .img_con .bg02 > .glow_con > .band {
	-webkit-animation-delay:-1.7s;
	        animation-delay:-1.7s;
}

/* 원본은 .bg 에 opacity 를 걸어 놨다. 그대로 두면 그룹 투명도라 빛까지
   0.3 으로 깎인다 — 흐리게 해야 할 것은 선 그림이므로 img 로 옮긴다.
   자식이 그림 하나뿐이라 보이는 결과는 같다.                          */
#main_con > .info02_con > .contents_con > .info02_con > .contents_con > .img_con .bg {
	opacity:1;
}
#main_con > .info02_con > .contents_con > .info02_con > .contents_con > .img_con .bg > img {
	opacity:0.3;
}


/* ── 모바일 ─────────────────────────────────────────────────────────────────
   라인 원본이 다르므로 마스크도 갈아 끼운다. 크기 지정은 그림 쪽과 똑같아야
   어긋나지 않는다 */
@media all and (max-width: 1024px) {
	#main_con > .info02_con .glow_con {
		--tr-lap:10.5s;      /* 화면이 좁아 같은 속도면 빨라 보인다 */
		--tr-band:6s;
	}
	#main_con > .info02_con > .contents_con > .info01_con > .info01_con > .bg > .glow_con {
		-webkit-mask-image:url("/img/main/m_main_info02_info01_info01_img_con_bg_glow.png");
		        mask-image:url("/img/main/m_main_info02_info01_info01_img_con_bg_glow.png");
	}
	#main_con > .info02_con > .contents_con > .info02_con > .contents_con > .img_con .bg01 > .glow_con {
		-webkit-mask-image:url("/img/main/m_main_info02_info02_img_con_bg01_glow.svg");
		        mask-image:url("/img/main/m_main_info02_info02_img_con_bg01_glow.svg");
	}
	#main_con > .info02_con > .contents_con > .info02_con > .contents_con > .img_con .bg02 > .glow_con {
		-webkit-mask-image:url("/img/main/m_main_info02_info02_img_con_bg02_glow.svg");
		        mask-image:url("/img/main/m_main_info02_info02_img_con_bg02_glow.svg");
	}
	/* 모바일 원본은 0.5 였다 */
	#main_con > .info02_con > .contents_con > .info02_con > .contents_con > .img_con .bg > img {
		opacity:0.5;
	}
}


/* ── 모션 최소화 ─────────────────────────────────────────────────────────────
   돌지 않게만 하고 빛 자체는 남긴다. 통째로 지우면 라인이 심심해진다 */
@media (prefers-reduced-motion: reduce) {
	#main_con > .info02_con .glow_con > .ray,
	#main_con > .info02_con .glow_con > .ray > i,
	#main_con > .info02_con .glow_con > .band {
		-webkit-animation:none !important;
		        animation:none !important;
	}
	#main_con > .info02_con .glow_con > .ray {
		-webkit-transform:translateY(-50%) rotate(-38deg);
		        transform:translateY(-50%) rotate(-38deg);
	}
	#main_con > .info02_con .glow_con > .band { display:none; }
}
