/**
 * Scrolling photo strip: the row of portrait tiles that loops right to left,
 * can be dragged, and lifts + reveals a caption on hover/tap.
 *
 * Shared by the homepage ("Our Students' Latest Achievements",
 * template-parts/achievements-showcase.php) and the school pages' hero
 * (page-school.php). The rules were moved here out of homepage.css unchanged,
 * and every selector is scoped to both page roots with :is() - the same
 * ID-level specificity as before, and still nothing leaks onto Elementor
 * pages. Tokens (elevation, radius, motion, colours) come from whichever page
 * root it sits in; homepage.css and prestasi.css define the same set.
 * Behaviour: assets/js/achievements-marquee.js (loop + drag) and
 * assets/js/achievements-tile-tap.js (tap-to-reveal on touch).
 */

/* Deliberately outside .hp-container on the homepage so the strip bleeds
   full-width. This is the clipping "viewport" - hp-achieve-track underneath is
   the part that actually moves, non-stop, right to left, looping forever.

   Not a scroll container on purpose, even though the strip can be dragged:
   assets/js/achievements-marquee.js does that with pointer events instead,
   because a horizontally-scrollable box swallows the vertical wheel in
   Chrome and this loop has no end for that scroll to chain out of. */
:is(#homepage-custom, #story-page) .hp-achieve-strip {
	/* Seconds per full pass. Read by achievements-marquee.js as well as by
	   the fallback animation below, so both stay on one value. */
	--hp-achieve-duration: 42s;
	position: relative;
	overflow: hidden;
	padding: 18px 0 24px;
	/* Sideways gestures drive the strip; up/down ones stay with the page. */
	touch-action: pan-y;
	-webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
	mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}

@media (hover: hover) and (pointer: fine) {
	:is(#homepage-custom, #story-page) .hp-achieve-strip.is-manual {
		cursor: grab;
	}

	:is(#homepage-custom, #story-page) .hp-achieve-strip.is-dragging {
		cursor: grabbing;
	}
}

/* Doubled tile list (see the template's two-pass loop) animated to -50%,
   which loops near-seamlessly since both halves are identical. Keeps rolling
   even while a tile is hovered/lifted - it does not pause.

   This is the no-JS fallback: achievements-marquee.js adds .is-manual and
   drives the same movement itself, so the strip can be dragged while it
   runs. */
:is(#homepage-custom, #story-page) .hp-achieve-track {
	display: flex;
	width: max-content;
	gap: 18px;
	animation: hp-achieve-scroll var(--hp-achieve-duration) linear infinite;
}

:is(#homepage-custom, #story-page) .hp-achieve-strip.is-manual .hp-achieve-track {
	animation: none;
}

/* Nothing should animate its way to a new position under a finger/cursor
   that is dragging it. */
:is(#homepage-custom, #story-page) .hp-achieve-strip.is-dragging .hp-achieve-tile {
	transition: none;
}

@keyframes hp-achieve-scroll {
	from {
		transform: translateX(0);
	}
	to {
		transform: translateX(-50%);
	}
}

:is(#homepage-custom, #story-page) .hp-achieve-tile {
	/* On the homepage a real <a> to the achievement's Instagram post; on the
	   school pages a plain <div>. Flex items are blockified per spec
	   regardless of tag, so both size identically. Only these two are needed
	   to undo anchor defaults; everything else here already targeted the
	   class, not the element. */
	display: block;
	text-decoration: none;
	position: relative;
	flex: 0 0 200px;
	aspect-ratio: 3 / 4;
	overflow: hidden;
	border-radius: var(--radius-md);
	cursor: pointer;
	/* Light fill, not --color-dark-surface: on a light section a black tile
	   reads as a hole, and it's what any entry still missing its photo falls
	   back to. The rim is a dark hairline (a white one is invisible here) and
	   shadows do the lifting, which they can on light. box-shadow isn't
	   clipped by this element's own overflow:hidden - that only clips
	   descendants - so the hover lift still reads. */
	background: var(--color-surface-muted);
	border: 1px solid var(--color-border);
	box-shadow: var(--elevation-2);
	transition: transform var(--motion-slow) ease, box-shadow var(--motion-slow) ease, border-color var(--motion-slow) ease;
}

/* The actual tile lifts here (not just the photo cropping inside it), and
   z-index brings it above its neighbors so the raised edge/shadow isn't
   tucked underneath the next tile in the row. */
:is(#homepage-custom, #story-page) .hp-achieve-tile:hover,
:is(#homepage-custom, #story-page) .hp-achieve-tile.is-active {
	transform: translateY(-10px);
	z-index: 2;
	border-color: rgba(18, 35, 60, 0.16);
	box-shadow: var(--elevation-4);
}

/* Stand-in for entries that have no photo file yet. Deliberately quiet -
   it should read as "photo pending", not as a designed graphic. */
:is(#homepage-custom, #story-page) .hp-achieve-tile-placeholder {
	display: flex;
	align-items: center;
	justify-content: center;
	background: linear-gradient(160deg, #eef2f8, #dfe6f0);
	color: rgba(18, 35, 60, 0.22);
	font-size: 2.4em;
}

:is(#homepage-custom, #story-page) .hp-achieve-tile-photo {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform var(--motion-slow) ease;
}

:is(#homepage-custom, #story-page) .hp-achieve-tile:hover .hp-achieve-tile-photo,
:is(#homepage-custom, #story-page) .hp-achieve-tile.is-active .hp-achieve-tile-photo {
	transform: translateY(-16px);
}

/* Sits above the photo (so it visually slides up "over" the lower part of
   it) and starts pushed below the tile's own clip boundary, so it's fully
   hidden until the hover/tap state brings it up. */
:is(#homepage-custom, #story-page) .hp-achieve-tile-reveal {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 2;
	display: flex;
	flex-direction: column;
	gap: 4px;
	padding: 16px 14px 14px;
	background: linear-gradient(180deg, rgba(10, 10, 12, 0) 0%, rgba(10, 10, 12, 0.92) 55%);
	transform: translateY(100%);
	opacity: 0;
	transition: transform var(--motion-base) ease, opacity var(--motion-base) ease;
}

:is(#homepage-custom, #story-page) .hp-achieve-tile:hover .hp-achieve-tile-reveal,
:is(#homepage-custom, #story-page) .hp-achieve-tile.is-active .hp-achieve-tile-reveal {
	transform: translateY(0);
	opacity: 1;
}

:is(#homepage-custom, #story-page) .hp-achieve-tile-title {
	font-family: 'Inter', sans-serif;
	font-weight: 400;
	font-size: 0.82em;
	line-height: 1.35;
	color: #fff;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

:is(#homepage-custom, #story-page) .hp-achieve-tile-name {
	font-family: 'Inter', sans-serif;
	font-weight: 800;
	font-size: 0.92em;
	letter-spacing: -0.1px;
	background: linear-gradient(90deg, var(--color-gradient-start-on-dark), var(--color-gradient-end-on-dark));
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
}

@media only screen and (max-width: 767px) {
	:is(#homepage-custom, #story-page) .hp-achieve-tile {
		flex-basis: 150px;
	}

	/* Quicker than the desktop pass. The tiles are narrower here and only a
	   couple fit on screen at once, so at the desktop duration the strip
	   covers far less ground per second and reads as barely moving. 14s was
	   the other extreme and read as hurried. */
	:is(#homepage-custom, #story-page) .hp-achieve-strip {
		--hp-achieve-duration: 24s;
	}
}

@media (prefers-reduced-motion: reduce) {
	:is(#homepage-custom, #story-page) .hp-achieve-track {
		animation: none;
	}

	:is(#homepage-custom, #story-page) .hp-achieve-tile-photo,
	:is(#homepage-custom, #story-page) .hp-achieve-tile-reveal {
		transition: none;
	}
}
