/*
 * Shared tokens and utilities.
 *
 * Block CSS loads BEFORE this file, so theme.css wins ties. Moving a rule
 * out of here into a block stylesheet therefore LOWERS its priority.
 */

:root {
	/* The code-block palette of the original portada. */
	--jme-ink: #000000;
	--jme-paper: #ffffff;
	--jme-accent: #ff6600;
	--jme-screen: #15e315;
	--jme-screen-dim: #005500;
	--jme-symbol: #d8d5dc;
	--jme-rose: #b54a46;
	--jme-grey: #272727;

	/* Chrome. --jme-bar-h is load-bearing: the mobile panel's top offset and
	   the anchor scroll offset are both derived from it, so it must equal the
	   rendered height of the bar. */
	--jme-bar-h: 80px;
	--jme-measure: 1140px;

	/* Reveal timing, shared by every target. */
	--jme-reveal-dur: 620ms;
	--jme-reveal-ease: cubic-bezier( 0.22, 0.61, 0.36, 1 );
}

/* The original grows its logo — and so the bar — at 960px (main.css:64-68).
   80px = 60px logo + the original's 10px top/bottom padding; 120px = 100px
   logo + the same 10px, which is the measured height of the original's bar.
   This must stay in lockstep with jme/site-header's own max-height media
   query: the token is read by .jme-site-header__bar's min-height and by
   html's scroll-padding-top below, neither of which is a descendant of the
   other, so the override has to live at :root to reach both. */
@media ( min-width: 960px ) {
	:root {
		--jme-bar-h: 120px;
	}
}

/* The original's bands butt up against one another: the only vertical space
   between two of them is each band's own padding, and the boxes banner's top
   edge meets the header's bottom with a hard edge. Core's layout styles would
   insert a 24px block gap between every child of .wp-site-blocks and of main;
   these selectors drop it for the chrome and for this theme's own section
   blocks, leaving ordinary post content on other templates alone. */
.wp-site-blocks > * + *,
main > .jme-hero,
main > .jme-about,
main > .jme-section {
	margin-block-start: 0;
}

/* The theme defines its own visually-hidden class rather than trusting
   block-library's .screen-reader-text to be enqueued on every page. */
.jme-sr {
	position: absolute !important;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip-path: inset( 50% );
	white-space: nowrap;
	border: 0;
}

.jme-section {
	padding-block: var( --wp--preset--spacing--60 );
}

.jme-section__inner {
	max-width: var( --jme-measure );
	margin-inline: auto;
	padding-inline: 1rem;
}

.jme-icon {
	width: 1em;
	height: 1em;
	fill: currentColor;
	display: inline-block;
	vertical-align: -0.125em;
}

/* Smooth anchor scrolling, with the sticky bar accounted for. Done in CSS so
   there is no JS in the path — the original animated it with jQuery. */
html {
	scroll-behavior: smooth;
	scroll-padding-top: calc( var( --jme-bar-h ) + 1rem );
}

@media ( prefers-reduced-motion: reduce ) {
	html { scroll-behavior: auto; }
}

/*
 * Scroll reveal.
 *
 * Gated on html.js, and that class has a WATCHDOG (see chrome.php and
 * reveal.js): gating on it alone would make the whole page invisible if
 * reveal.js ever 404s.
 *
 * :where() around the target list is load-bearing, not tidiness. Written
 * flat, the hidden selector outranks `html.js .is-inview` and the element
 * stays at opacity 0 forever. :where() drops the list to zero specificity so
 * both rules sit at `html.js` alone.
 *
 * Only opacity and transform animate, so a reveal can never reflow the page.
 *
 * Constraint for every block that applies .jme-reveal to an element: this
 * rule OWNS that element's transform. `.is-inview` sets it to `none` at
 * (0,3,1), which outranks any plain class selector a block's own stylesheet
 * could put on the same element, so a persistent transform (an offset, a
 * rotation, anything not meant to animate away) will be silently cancelled
 * the moment the element comes into view. Use a different property (margin,
 * for example) for a persistent effect, or put the transform on a child
 * element that is not itself .jme-reveal. (jme/tech-stack hit this with its
 * nth-child icon offset — see its style.scss.)
 */
html.js :where( .jme-reveal ) {
	opacity: 0;
	transform: translateY( 18px );
}

html.js .jme-reveal.is-inview {
	opacity: 1;
	transform: none;
	transition:
		opacity var( --jme-reveal-dur ) var( --jme-reveal-ease ),
		transform var( --jme-reveal-dur ) var( --jme-reveal-ease );
}

@media ( prefers-reduced-motion: reduce ) {
	html.js :where( .jme-reveal ) {
		opacity: 1;
		transform: none;
	}
}
