/*
Theme Name: Catch Fullscreen Child
Description: Child theme of Catch Fullscreen. Adds the "Prompt → Interface" CSS-only hero animation (handoff-pm-mikeylong-hero spec) behind the portrait cutout on the front page. Parent theme is untouched.
Author: Michael Long
Author URI: https://pm.mikeylong.com/
Template: catch-fullscreen
Version: 1.2.0
*/

/* =====================================================================
   Hero animation — "Prompt → Interface" (handoff spec §3–§4)
   Palette inverted per spec §5: the live hero is light (white photo bg),
   so dark strokes at rgba(0,0,0,.12–.28) replace the mock's light ones
   and the scrim is a white gradient. The prompt bar keeps its dark
   terminal look deliberately — it is the one intentional dark element.
   Scoped to the front page only (.home + is_front_page markup).
   ===================================================================== */

.home .custom-header.header-media {
	position: relative; /* parent theme also sets this; kept for clarity */
	overflow: hidden;
	background-color: #ffffff;
}

/* Layer order (spec §2): anim 1 < figure 2 < scrim 3 < prompt 4 < copy 5 */

.hero-anim,
.hero-anim * { box-sizing: border-box; }

.hero-anim {
	position: absolute;
	inset: 0;
	pointer-events: none;
	z-index: 1;
}

/* Paused 2026-08-20 at Michael's request: scenes behind the figure need
   more work. Prompt animation (.hero-prompt) is untouched and keeps running.
   All scene markup/CSS below is left in place, just hidden. */
.hero-anim {
	display: none;
}

/* faint dot grid across the whole hero */
.hero-anim::before {
	content: "";
	position: absolute;
	inset: 0;
	background-image: radial-gradient(#3d4e7d 1px, transparent 1px);
	background-size: 30px 30px;
	opacity: .18;
}

/* Three scenes — one per prompt phrase, gated on the same 24s cycle as the
   typing. Each fades in drifting from the right (off-frame, where the
   figure stands), tucks behind the top third of the head, and clears out
   before the next phrase. */
.hero-anim .scene {
	position: absolute;
	inset: 0;
	animation: hero-scene 24s ease-in-out infinite both;
}
.hero-anim .scene-2 { animation-delay: 8s; }
.hero-anim .scene-3 { animation-delay: 16s; }

.hero-anim .card {
	position: absolute;
	border: 1px solid #3d4e7d;
	border-radius: 5px;
	background: rgba(255, 255, 255, .6);
	padding: 13px;
	display: flex;
	gap: 9px;
	animation: hero-float 6.4s ease-in-out infinite;
}
.hero-anim .card--brief { left: 56%; top: 5%; width: 214px; height: 130px; flex-direction: column; }
.hero-anim .card--chart { left: 55%; top: 4%; width: 212px; height: 146px; align-items: flex-end; gap: 8px; }

/* scene 1 — a workflow line threading behind the head, off the right edge */
.hero-anim .flow-line {
	position: absolute;
	left: 58%;
	right: -60px;
	top: 10%;
	height: 2px;
	background: rgba(61, 78, 125, .35);
	border-radius: 1px;
}

.hero-anim .line       { height: 6px; background: rgba(61, 78, 125, .45); border-radius: 2px; }
.hero-anim .line--head { height: 8px; width: 54%; background: rgba(61, 78, 125, .75); }
.hero-anim .line--a    { width: 86%; }
.hero-anim .line--b    { width: 70%; }
.hero-anim .btn        { margin-top: auto; height: 20px; width: 72px; border: 1px solid #3d4e7d; border-radius: 3px; }

.hero-anim .bar {
	flex: 1;
	background: rgba(61, 78, 125, .55);
	border-radius: 2px 2px 0 0;
	transform-origin: bottom;
	animation: hero-barpulse 2.4s ease-in-out infinite;
}
.hero-anim .bar:nth-child(1) { height: 36%; }
.hero-anim .bar:nth-child(2) { height: 60%; animation-delay: .2s; }
.hero-anim .bar:nth-child(3) { height: 46%; background: #3d4e7d; animation-delay: .4s; }
.hero-anim .bar:nth-child(4) { height: 80%; animation-delay: .6s; }

.hero-anim .chips {
	position: absolute;
	left: 86%;
	right: -40px;
	top: 16%;
	display: flex;
	gap: 9px;
	overflow: hidden;
}
.hero-anim .chip { height: 26px; border: 1px solid #3d4e7d; border-radius: 13px; }
.hero-anim .chip:nth-child(1) { width: 70px; }
.hero-anim .chip:nth-child(2) { width: 54px; }
.hero-anim .chip:nth-child(3) { width: 88px; }

/* scene 2 — code block sliding in from beyond the right frame edge */
.hero-anim .code-block {
	position: absolute;
	left: 84%;
	right: -50px;
	top: 15%;
	border: 1px solid #3d4e7d;
	border-radius: 5px;
	background: rgba(255, 255, 255, .6);
	padding: 12px;
	display: flex;
	flex-direction: column;
	gap: 8px;
}
.hero-anim .code-block .line:nth-child(1) { width: 88%; }
.hero-anim .code-block .line:nth-child(2) { width: 64%; }
.hero-anim .code-block .line:nth-child(3) { width: 80%; }
.hero-anim .code-block .line:nth-child(4) { width: 52%; }

/* scene 3 — chat bubbles: reply bubble runs off-frame, dots = LLM typing */
.hero-anim .bubble {
	position: absolute;
	border: 1px solid #3d4e7d;
	border-radius: 14px;
	background: rgba(255, 255, 255, .7);
	padding: 12px 14px;
	display: flex;
	flex-direction: column;
	gap: 7px;
	animation: hero-float 6.4s ease-in-out infinite;
}
.hero-anim .bubble--left  { left: 57%; top: 5%; width: 190px; border-bottom-left-radius: 4px; }
.hero-anim .bubble--right {
	left: 85%;
	right: -30px;
	top: 19%;
	flex-direction: row;
	align-items: center;
	gap: 8px;
	border-bottom-right-radius: 4px;
	animation-delay: 1.2s;
}
.hero-anim .node {
	width: 9px;
	height: 9px;
	border-radius: 50%;
	background: #3d4e7d;
	animation: hero-pulse 1.7s ease-in-out infinite;
}
.hero-anim .node:nth-child(2) { animation-delay: .4s; }
.hero-anim .node:nth-child(3) { animation-delay: .8s; }
.hero-anim .node:nth-child(4) { animation-delay: 1.2s; }

/* The portrait cutout — right-aligned, bottom-anchored (spec §2 layer 3).
   Wide bust crop (850x791): height-driven with a max-width guard. */
.home .custom-header .hero-figure {
	position: absolute;
	right: 2%;
	bottom: 0;
	z-index: 2;
	height: 92%;
	width: auto;
	max-width: 62%;
	object-fit: contain;
	object-position: right bottom;
	margin: 0;
}

/* Scrim — light gradient (spec §5 inversion). Fade compressed vs the mock:
   our figure's left edge sits near 38%, so the scrim reaches ~0 by 40%
   to satisfy "must fade out before the figure" (spec §2). */
.hero-scrim {
	position: absolute;
	inset: 0;
	z-index: 3;
	background: linear-gradient(90deg,
		rgba(255, 255, 255, .95) 0%,
		rgba(255, 255, 255, .85) 22%,
		rgba(255, 255, 255, .25) 32%,
		rgba(255, 255, 255, 0) 40%);
}

/* Prompt box — lives inside .wrapper (not the header) so its `left` is
   relative to the SAME box the copy column sits in. .wrapper centers with
   an auto margin (continuous), while .entry-content-wrapper adds a further
   fixed margin-left that steps at the theme's own breakpoints: 45px
   (>=41.6875em), 100px (>=64em), 115px (>=85.375em), 130px (>=100em).
   Mirroring those exact steps below keeps this box's left edge flush with
   the "M. Long" / body-copy column at every width, instead of guessing a
   percentage that would drift from it. Sits ABOVE the scrim (spec). */
.hero-prompt {
	/* In the copy flow, not absolutely positioned: the box is injected into
	   the hero paragraph right after the "AI design technologist" line (see
	   header-media.php), so it inherits the copy column's left edge for free
	   and can never drift out of alignment at any viewport width. */
	width: 281px;
	max-width: 100%;
	margin: 12px 0 20px;
	border: 1px solid #d3d8de;
	border-radius: 6px;
	background: rgba(244, 246, 248, .96);
	padding: 13px 15px;
	display: grid;
	grid-template-columns: auto 1fr;
	column-gap: 9px;
	align-items: start;
	font: 12px/1.5 ui-monospace, SFMono-Regular, Menlo, monospace;
	text-align: left;
	pointer-events: none;
}
.hero-prompt .caret-glyph { grid-area: 1 / 1; color: #3d4e7d; font-size: 12px; padding-top: 1px; }

/* All three phrases share the same grid cell so the box height auto-fits
   the tallest phrase and never jumps mid-cycle. Each is a hard on/off gate
   (step-end, no fill-mode) — the typing below does the visual work, so a
   fade here would only muddy it. Base opacity 0 covers the pre-delay
   window for phrases 2 and 3. */
.hero-prompt .typed {
	grid-area: 1 / 2;
	color: #1f2733;
	opacity: 0;
	animation: hero-phrase 24s step-end infinite;
}
.hero-prompt .typed-2 { animation-delay: 8s; }
.hero-prompt .typed-3 { animation-delay: 16s; }

/* Typing across a WRAPPED box needs explicit lines: a single clipped span
   can only reveal one line. Each line is its own nowrap span whose width
   steps from 0 to its exact character count, line 2 starting after line 1
   finishes — so the text types out, wraps, and keeps going.
   The cursor is the line's own right border, which sits exactly at the
   clip edge, i.e. at the typed character. border-right-WIDTH is driven by
   the type animation (so the cursor hands off from line 1 to line 2),
   while border-right-COLOR is driven by a separate blink animation —
   different properties, so both animations run without conflicting. */
.hero-prompt .ln {
	display: block;
	white-space: nowrap;
	overflow: hidden;
	width: 0;
	/* content-box + 2px right padding widens the CLIP area just past the
	   text without changing the animated width, so the final glyph can
	   never be shaved by subpixel rounding (a 30ch line measures 216.75px
	   against 216.8px of actual text). */
	box-sizing: content-box;
	padding-right: 2px;
	border-right: 0 solid #3d4e7d;
	animation: hero-type-a 24s steps(28, end) infinite,
	           hero-blink 1.1s step-end infinite;
}
.hero-prompt .ln-2 { animation-name: hero-type-b, hero-blink; }
/* Line animations need the same phrase offset as their parent gate
   (animation-delay does not inherit); the blink stays free-running. */
.hero-prompt .typed-2 .ln { animation-delay: 8s, 0s; }
.hero-prompt .typed-3 .ln { animation-delay: 16s, 0s; }

/* Exact width AND step count per line: steps == characters means each step
   reveals exactly one whole letter, start to finish. */
.hero-prompt .typed-1 .ln-1 { --w: 28ch; animation-timing-function: steps(28, end), step-end; }
.hero-prompt .typed-1 .ln-2 { --w: 30ch; animation-timing-function: steps(30, end), step-end; }
.hero-prompt .typed-2 .ln-1 { --w: 30ch; animation-timing-function: steps(30, end), step-end; }
.hero-prompt .typed-2 .ln-2 { --w: 27ch; animation-timing-function: steps(27, end), step-end; }
.hero-prompt .typed-3 .ln-1 { --w: 29ch; animation-timing-function: steps(29, end), step-end; }
.hero-prompt .typed-3 .ln-2 { --w: 26ch; animation-timing-function: steps(26, end), step-end; }

/* Copy above everything (spec layer 5). Parent sets z-index:1 on the
   content block; the wrapper carries the copy, so lift it. Also the
   positioning context .hero-prompt is now nested inside (see above). */
.home .custom-header.header-media .wrapper {
	position: relative;
	z-index: 5;
}

.home .custom-header.header-media.has-hero-anim .wrapper {
	overflow: visible;
}


@keyframes hero-scene {
	0%          { opacity: 0; transform: translateX(28px); }
	2.5%        { opacity: 1; transform: translateX(0); }
	30%         { opacity: 1; transform: translateX(0); }
	33.3%, 100% { opacity: 0; transform: translateX(28px); }
}
@keyframes hero-barpulse { 0%, 100% { transform: scaleY(.45); } 50% { transform: scaleY(1); } }
@keyframes hero-fade     { 0% { opacity: 0; } 4% { opacity: 1; } 29% { opacity: 1; } 33.3%, 100% { opacity: 0; } }
@keyframes hero-caret    { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }
/* One phrase occupies 8s of the 24s cycle = 33.33%. */
@keyframes hero-phrase {
	0%     { opacity: 1; }
	33.33% { opacity: 1; }
	33.34% { opacity: 0; }
	100%   { opacity: 0; }
}
/* Line 1: types 0-5% (1.2s), then hands the cursor to line 2. */
@keyframes hero-type-a {
	0%     { width: 0;        border-right-width: 7px; }
	5%     { width: var(--w); border-right-width: 7px; }
	5.01%  { width: var(--w); border-right-width: 0; }
	33.33% { width: var(--w); border-right-width: 0; }
	33.34% { width: 0;        border-right-width: 0; }
	100%   { width: 0;        border-right-width: 0; }
}
/* Line 2: waits for line 1, types 5-7.5% (0.6s), keeps the cursor. */
@keyframes hero-type-b {
	0%     { width: 0;        border-right-width: 0; }
	/* hold the cursor fully hidden until line 1 hands off, otherwise it
	   interpolates 0->7px and a second cursor grows in while line 1 types */
	4.99%  { width: 0;        border-right-width: 0; }
	5%     { width: 0;        border-right-width: 7px; }
	7.5%   { width: var(--w); border-right-width: 7px; }
	33.33% { width: var(--w); border-right-width: 7px; }
	33.34% { width: 0;        border-right-width: 0; }
	100%   { width: 0;        border-right-width: 0; }
}
@keyframes hero-blink {
	0%, 49%   { border-right-color: #3d4e7d; }
	50%, 100% { border-right-color: transparent; }
}
@keyframes hero-float    { 0%, 100% { transform: translate(0, 0); } 50% { transform: translate(10px, -14px); } }
@keyframes hero-pulse    { 0%, 100% { opacity: .25; transform: scale(.85); } 50% { opacity: .9; transform: scale(1); } }

@media (prefers-reduced-motion: reduce) {
	.hero-anim *, .hero-prompt * { animation: none !important; }
	.hero-anim .scene { opacity: 1; }
	.hero-anim .scene-2, .hero-anim .scene-3 { display: none; }
	.hero-prompt .typed-1 { opacity: 1; }
	.hero-prompt .typed-2, .hero-prompt .typed-3 { display: none; }
	.hero-prompt .ln { width: auto !important; border-right-width: 0 !important; }
}

/* Between 901–1200px the figure and prompt converge: shrink both so the
   prompt's right edge never reaches the figure (acceptance criterion 3). */
@media (max-width: 1200px) {
	.home .custom-header .hero-figure { height: 84%; }
}


@media (max-width: 900px) {
	.hero-anim, .hero-prompt, .hero-scrim { display: none; }
	.home .custom-header .hero-figure {
		height: auto;
		width: 72%;
		max-width: 420px;
		right: 0;
	}
}
