/* ==========================================================================
   Typewriter Showcase
   Layout principle: everything is a stacked CSS grid.
   - .tws-stage is one grid cell; image layer and card both occupy it.
   - The image layer is pushed down by --tws-image-offset, creating the
     overlap zone that the card covers (card in front, images behind).
   - All images share one grid cell -> the layer is always as tall as the
     tallest image at the current width. Same trick for the texts inside
     the card. No fixed sizes, no JS measurements, no layout shift.
   ========================================================================== */

.tws-stage {
	--tws-fade: 700ms;
	--tws-drift: 1.5em;
	--tws-drift-duration: 8000ms;
	--tws-image-offset: 14%;
	--tws-caret: #2563eb;

	display: grid;
	grid-template-areas: "stage";
	width: 100%;
}

/* ---- Image layer (behind) ---- */

.tws-image-layer {
	grid-area: stage;
	display: grid;
	grid-template-areas: "img";
	justify-items: center;
	align-items: start;
	margin-top: var(--tws-image-offset);
	z-index: 1;
}

.tws-image {
	grid-area: img;
	margin: 0;
	width: 100%;
	display: flex;
	justify-content: inherit;

	opacity: 0;
	transform: translateY(var(--tws-drift));
	transition:
		opacity var(--tws-fade) ease,
		transform var(--tws-drift-duration) cubic-bezier(0.16, 1, 0.3, 1);
	will-change: opacity, transform;
	pointer-events: none;
}

.tws-image img {
	width: 100%;
	height: auto;
	display: block;
}

.tws-image.is-active {
	opacity: 1;
	transform: translateY(0);
	pointer-events: auto;
}

/* Fade-out uses only opacity (short), so the drift never reverses visibly. */
.tws-image.is-leaving {
	opacity: 0;
	transform: translateY(0);
	transition: opacity var(--tws-fade) ease;
}

/* ---- Card (in front) ---- */

.tws-card {
	grid-area: stage;
	align-self: start;
	justify-self: start;
	z-index: 2;
	box-sizing: border-box;
	background: #fff;
}

.tws-card-label {
	display: flex;
	align-items: center;
	gap: 0.5em;
	font-size: 0.85em;
	font-weight: 600;
	letter-spacing: 0.02em;
	margin-bottom: 0.5em;
	opacity: 0.85;
}

.tws-card-label--bottom {
	margin-bottom: 0;
	margin-top: 0.75em;
}

/* ---- Icons (labels + text prefix) ---- */

.tws-label-icon {
	flex: none;
	display: inline-flex;
	align-items: center;
}

.tws-label-icon svg,
.tws-text-icon svg {
	width: 1em;
	height: auto;
}

/* ---- Text row: optional prefix icon + hanging indent ---- */

.tws-text-row {
	display: flex;
	align-items: flex-start;
}

/* The icon container shares the typed text's typography (same widget
   selector), so its single line box matches the text's first line;
   vertical-align then centers the icon on that line. */
.tws-text-icon {
	flex: none;
	margin-right: 0.4em;
}

.tws-text-icon i,
.tws-text-icon svg {
	vertical-align: middle;
}

/* ---- Text area: stacked measurers keep the height stable ---- */

.tws-text-area {
	display: grid;
	grid-template-areas: "text";
	flex: 1;
	min-width: 0;
}

.tws-measure,
.tws-typed {
	grid-area: text;
	margin: 0;
	/* identical box model so measurers predict the typed element's height */
	white-space: pre-wrap;
	overflow-wrap: break-word;
}

.tws-measure {
	visibility: hidden;
	pointer-events: none;
	user-select: none;
}

/* ---- Caret ---- */

.tws-caret {
	display: inline-block;
	width: 0.12em;
	height: 1em;
	margin-left: 0.08em;
	vertical-align: text-bottom;
	background: var(--tws-caret);
	animation: tws-blink 1.05s steps(1, end) infinite;
}

.tws-stage.tws-idle .tws-caret {
	opacity: 0;
	animation: none;
}

@keyframes tws-blink {
	0%, 55%  { opacity: 1; }
	56%, 100% { opacity: 0; }
}

/* ---- Screen reader text ---- */

.tws-sr-only {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/* ---- Reduced motion: static crossfade, no typing, no drift ---- */

@media (prefers-reduced-motion: reduce) {
	.tws-image {
		transform: none;
		transition: opacity var(--tws-fade) ease;
	}
	.tws-caret {
		display: none;
	}
}
