/* ==========================================================================
   Hiệu ứng dùng chung (điều khiển bởi assets/js/site.js và assets/js/lightbox.js).
   Không có JS: nội dung hiển thị bình thường, không có hiệu ứng.
   ========================================================================== */

/* Dải lụa nền vẽ dần theo cuộn (dugarco_ribbon()) ------------------------------ */

.scroll-ribbon {
	position: absolute;
	top: 0;
	left: 0;
	z-index: -1;
	width: 100%;
	pointer-events: none;
}

.scroll-ribbon svg {
	width: 100%;
	height: 100%;
}

/* pathLength="1": độ dài nét tính theo tỉ lệ 0–1. Không có JS thì tự vẽ 1 lần khi tải trang;
   có JS (.is-ready) thì site.js đặt stroke-dashoffset theo vị trí cuộn. */
.scroll-ribbon path {
	fill: none;
	stroke: #fdc04f;
	stroke-width: 56px;
	stroke-linecap: round;
	stroke-linejoin: round;
	stroke-dasharray: 1 1;
	animation: ribbon-draw 2.4s cubic-bezier(0.4, 0, 0.2, 1) 0.2s both;
}

.scroll-ribbon.is-ready path {
	animation: none;
}

/* Dải lụa trang chủ cần JS đo vùng hiển thị: không có JS thì ẩn. */
.scroll-ribbon[data-ribbon-stretch]:not(.is-ready) {
	display: none;
}

.scroll-ribbon[data-ribbon-stretch] path {
	stroke-width: clamp(18px, 2.92vw, 56px);
}

@keyframes ribbon-draw {
	from { stroke-dashoffset: 1; }
	to { stroke-dashoffset: 0; }
}

/* Sticker bay theo chuột (assets/js/sticker-trail.js) ------------------------------------------------- */

.sticker-trail {
	position: absolute;
	inset: 0;
	z-index: 0;
	overflow: hidden;
	pointer-events: none;
}

/* Cỡ gốc 5vw như tribestays. JS đặt vị trí + góc nghiêng cho khung, độ to + độ mờ cho ảnh. */
.sticker-trail__item {
	position: absolute;
	top: 0;
	left: 0;
	width: 5vw;
	height: 5vw;
}

.sticker-trail__item img {
	width: 100%;
	height: 100%;
	object-fit: contain;
	opacity: 0;
	user-select: none;
}

/* Hiện dần khi cuộn tới (site.js chỉ gắn .reveal cho phần tử còn nằm dưới màn hình lúc tải trang) ------ */

/* Lò xo tắt dần (nảy quá ~16% rồi dội lại nhẹ). Trình duyệt chưa hỗ trợ linear(): nảy quá 1 lần. */
:root {
	--ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
}

@supports (transition-timing-function: linear(0, 1)) {
	:root {
		--ease-spring: linear(0, 0.074, 0.25, 0.47, 0.688, 0.876, 1.017, 1.108, 1.153, 1.162, 1.146, 1.115, 1.079, 1.044, 1.015, 0.993, 0.98, 0.974, 0.974, 0.977, 0.982, 0.988, 0.994, 0.998, 1.002, 1.004, 1.004, 1.004, 1);
	}
}

/* !important: CSS của block (vd. ".cap-card { transition: background-color … }", ".market-pin .icon") cụ thể hơn
   sẽ đè mất transition của hiệu ứng. Chỉ có tác dụng trong lúc hiện; xong thì site.js gỡ class.
   Phần tử có transform riêng thì dời vị trí bằng thuộc tính "translate" (transform bị hiệu ứng đè trong lúc hiện).
   Hiện xong, độ mờ trở về giá trị riêng của phần tử (vd. chữ trang trí 0.2), không ép về 1. */
.reveal {
	transform: translateY(48px) !important;
	transition: opacity 0.8s ease, transform 0.9s cubic-bezier(0.2, 0.7, 0.2, 1) !important;
	transition-delay: var(--reveal-delay, 0s) !important;
}

.reveal:not(.is-revealed) {
	opacity: 0 !important;
}

.reveal--left { transform: translateX(-80px) !important; }
.reveal--right { transform: translateX(80px) !important; }
.reveal--zoom { transform: scale(0.92) !important; }
.reveal--pop { transform: scale(0.2) !important; }

/* Tiêu đề section: trồi lên xa và chậm hơn (opacity và transform cùng thời gian để class được gỡ khi đã đứng yên). */
.reveal--title {
	transform: translateY(96px) !important;
	transition: opacity 1.6s ease, transform 1.6s cubic-bezier(0.16, 1, 0.3, 1) !important;
	transition-delay: var(--reveal-delay, 0s) !important;
}

/* Banner (Partner Voices): mở rộng từ giữa ra 4 mép. */
.reveal--unfold {
	clip-path: inset(14% 10% round clamp(24px, 3.33vw, 64px)) !important;
	transform: scale(0.96) !important;
	transition: opacity 1.4s ease, transform 1.4s cubic-bezier(0.16, 1, 0.3, 1), clip-path 1.4s cubic-bezier(0.16, 1, 0.3, 1) !important;
	transition-delay: var(--reveal-delay, 0s) !important;
}

.reveal--unfold.is-revealed {
	clip-path: inset(0 round clamp(24px, 3.33vw, 64px)) !important;
}

/* Chữ nền lớn: trượt ngang vào chỗ, chậm, 1 lần (Partner Voices). */
.reveal--drift {
	transform: translateX(14%) !important;
	transition: opacity 1.6s ease, transform 2s cubic-bezier(0.16, 1, 0.3, 1) !important;
	transition-delay: var(--reveal-delay, 0s) !important;
}

/* Thẻ bài viết: trồi lên, ảnh bên trong thu nhỏ dần về cỡ thật. Transform của thẻ dài bằng hiệu ứng ảnh
   (site.js gỡ class khi transform của thẻ xong – ảnh phải xong trước đó). */
.reveal--card {
	transition: opacity 1s ease, transform 1.4s cubic-bezier(0.16, 1, 0.3, 1) !important;
	transition-delay: var(--reveal-delay, 0s) !important;
}

.reveal--card img {
	transform: scale(1.18);
	transition: transform 1.4s cubic-bezier(0.16, 1, 0.3, 1);
	transition-delay: var(--reveal-delay, 0s);
}

.reveal--card.is-revealed img {
	transform: none;
}

/* Ghim bản đồ: rơi từ cao xuống, nảy như lò xo khi chạm bản đồ. */
.reveal--pin {
	transform: translateY(-90px) scale(0.3) !important;
	transition: opacity 0.5s ease, transform 1.2s var(--ease-spring) !important;
	transition-delay: var(--reveal-delay, 0s) !important;
}

/* Dòng chữ trồi lên từ sau một đường kẻ vô hình ở chân dòng (clip-path chạy cùng nhịp với transform). */
.reveal--line {
	transform: translateY(100%) !important;
	clip-path: inset(-0.3em -0.3em 100% -0.3em) !important;
	transition: opacity 0.6s ease, transform 1s cubic-bezier(0.2, 0.7, 0.2, 1), clip-path 1s cubic-bezier(0.2, 0.7, 0.2, 1) !important;
	transition-delay: var(--reveal-delay, 0s) !important;
}

.reveal--line.is-revealed {
	clip-path: inset(-0.3em) !important;
}

/* Trượt từ dưới lên, nảy như lò xo khi tới chỗ. Phần tử chạy lại theo cuộn, tới từ phía trên (cuộn lên): rơi xuống. */
.reveal--spring {
	transform: translateY(140px) !important;
	transition: opacity 0.5s ease, transform 1.1s var(--ease-spring) !important;
	transition-delay: var(--reveal-delay, 0s) !important;
}

.reveal--spring.reveal--above {
	transform: translateY(-140px) !important;
}

/* Thẻ chia bài: bay lên như thẻ của tribestays.com (lệch 100px, mờ → rõ trong 1s, chậm dần), CSS của block lật thẻ từ
   mặt sau ra mặt trước trong lúc bay. Transform của thẻ kéo dài hơn lượt lật (site.js gỡ class khi transform thẻ xong,
   gỡ sớm sẽ cắt ngang lượt lật). Tới từ phía trên (cuộn lên): rơi xuống. */
.reveal--deal {
	transform: translateY(100px) !important;
	transition: opacity 1s cubic-bezier(0.33, 1, 0.68, 1), transform 1.6s cubic-bezier(0.22, 1, 0.36, 1) !important;
	transition-delay: var(--reveal-delay, 0s) !important;
}

.reveal--deal.reveal--above {
	transform: translateY(-100px) !important;
}

/* Ảnh tung vào chỗ: từ dưới lên, nhỏ hơn, nghiêng xen kẽ trái / phải, nảy lò xo khi tới chỗ (School uniform – collage). */
.reveal--toss {
	transform: translateY(90px) rotate(-5deg) scale(0.88) !important;
	transition: opacity 0.6s ease, transform 1.2s var(--ease-spring) !important;
	transition-delay: var(--reveal-delay, 0s) !important;
}

.reveal--toss:nth-child(even) {
	transform: translateY(90px) rotate(5deg) scale(0.88) !important;
}

.reveal.is-revealed {
	transform: none !important;
}

/* Lúc gắn class: ẩn ngay, không chạy hiệu ứng ngược hiện → ẩn (site.js gỡ .is-instant sau 1 lần tính style). */
.reveal.is-instant {
	transition: none !important;
}

/* Tiêu đề hiện từng chữ (site.js, WORDS): mỗi chữ nằm sau một mặt nạ, trồi lên và đứng thẳng lại, lần lượt trái → phải.
   Mặt nạ (clip-path) nới ra ngoài khung chữ để dấu tiếng Việt / đuôi chữ Q không bị cắt; hiện xong (.is-done) thì bỏ. */
.split-words {
	animation: none !important; /* thay hiệu ứng dự phòng không JS của block (nếu có) */
}

.split-word {
	display: inline-block;
	clip-path: inset(-0.4em -0.2em -0.15em);
}

.split-word__inner {
	display: inline-block;
	transform: translateY(120%) rotate(4deg);
	transform-origin: 0 100%;
}

.split-words.is-played .split-word__inner {
	animation: split-word-in 1.2s cubic-bezier(0.22, 1, 0.36, 1) calc(0.1s + var(--i, 0) * 0.14s) both;
}

.split-words.is-done .split-word {
	clip-path: none;
}

@keyframes split-word-in {
	from { transform: translateY(120%) rotate(4deg); }
	to { transform: none; }
}

/* Lightbox xem ảnh lớn, phóng to / thu nhỏ ---------------------------------- */

[data-lightbox] img {
	cursor: zoom-in;
}

html.has-lightbox {
	overflow: hidden;
}

.lightbox {
	position: fixed;
	inset: 0;
	width: 100%;
	max-width: none;
	height: 100%;
	max-height: none;
	margin: 0;
	padding: 0;
	overflow: hidden;
	border: 0;
	background: rgba(10, 10, 10, 0.95);
	color: #fff;
	font-family: var(--font-body);
}

.lightbox::backdrop {
	background: transparent;
}

.lightbox[open] {
	animation: lightbox-in 0.25s ease both;
}

@keyframes lightbox-in {
	from { opacity: 0; }
}

.lightbox__stage {
	position: absolute;
	inset: 0;
	display: grid;
	place-items: center;
	overflow: hidden;
	touch-action: none;
	cursor: zoom-in;
}

.lightbox.is-zoomed .lightbox__stage {
	cursor: grab;
}

.lightbox.is-dragging .lightbox__stage {
	cursor: grabbing;
}

.lightbox__image {
	width: auto;
	max-width: calc(100vw - 2 * clamp(16px, 6vw, 120px));
	height: auto;
	max-height: calc(100dvh - 2 * clamp(72px, 8vh, 96px));
	object-fit: contain;
	transition: transform 0.25s ease;
	user-select: none;
	-webkit-user-drag: none;
}

.lightbox.is-dragging .lightbox__image,
.lightbox.is-pinching .lightbox__image {
	transition: none;
}

.lightbox__bar {
	position: absolute;
	top: clamp(12px, 2vh, 24px);
	right: clamp(12px, 2vw, 24px);
	z-index: 1;
	display: flex;
	align-items: center;
	gap: 8px;
}

.lightbox__counter {
	position: absolute;
	top: clamp(12px, 2vh, 24px);
	left: clamp(12px, 2vw, 24px);
	z-index: 1;
	display: grid;
	place-items: center;
	min-height: 48px;
	font-size: 14px;
	font-variant-numeric: tabular-nums;
	color: rgba(255, 255, 255, 0.8);
}

.lightbox__level {
	min-width: 5ch;
	font-size: 14px;
	font-variant-numeric: tabular-nums;
	text-align: center;
	color: rgba(255, 255, 255, 0.8);
}

.lightbox__button {
	display: grid;
	place-items: center;
	width: 48px;
	height: 48px;
	padding: 0;
	border: 1px solid rgba(255, 255, 255, 0.3);
	border-radius: 50%;
	background: rgba(0, 0, 0, 0.45);
	color: #fff;
	cursor: pointer;
	transition: background-color 0.2s, opacity 0.2s;
}

.lightbox__button:hover:not(:disabled) {
	background: rgba(255, 255, 255, 0.18);
}

.lightbox__button:disabled {
	opacity: 0.35;
	cursor: default;
}

.lightbox__nav {
	position: absolute;
	top: 50%;
	z-index: 1;
	transform: translateY(-50%);
}

.lightbox__nav--prev { left: clamp(12px, 2vw, 24px); }
.lightbox__nav--next { right: clamp(12px, 2vw, 24px); }

.lightbox__caption {
	position: absolute;
	bottom: clamp(16px, 3vh, 32px);
	left: 50%;
	z-index: 1;
	width: max-content;
	max-width: min(80ch, 100% - 32px);
	font-size: 14px;
	text-align: center;
	color: rgba(255, 255, 255, 0.8);
	transform: translateX(-50%);
	pointer-events: none;
}

.lightbox__caption:empty {
	display: none;
}
