/*
Theme Name: Aperture
Theme URI: https://example.com/aperture
Author: Suyash
Description: A single-page block theme for a cinematography journal. Dark-theatre palette, Didone display type, technical mono captions, and a film-grain surface. Built entirely from native WordPress blocks and patterns — no page builder.
Version: 2.0.1
Requires at least: 6.5
Tested up to: 6.7
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: aperture
Tags: blog, one-column, block-patterns, full-site-editing, editor-style, custom-colors, dark-mode-support
*/

/* ==========================================================================
   Aperture — CSS that theme.json cannot express.
   Colour, type and spacing tokens live in theme.json; this file holds the
   devices built on top of them.
   1 surface  2 type  3 frames  4 cards  5 hero  6 strip  7 buttons  8 motion
   ========================================================================== */

:root {
	--ap-ease: cubic-bezier(0.32, 0.72, 0, 1);
	--ap-slow: 700ms;
	--ap-quick: 320ms;
	--ap-bezel: 1rem;
	--ap-pad: 0.35rem;
}

/* 1 · Surface ------------------------------------------------------------ */

/* Fixed grain plate. Fixed + pointer-events:none, so it never repaints. */
body::after {
	content: "";
	position: fixed;
	inset: 0;
	z-index: 9;
	pointer-events: none;
	opacity: 0.07;
	mix-blend-mode: screen;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.86' numOctaves='3'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
}

body {
	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
}

/* 2 · Type --------------------------------------------------------------- */

/* Eyebrow — mono, tracked, tungsten, with a leading rule. Opens every section. */
.ap-eyebrow {
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--tiny) !important;
	font-weight: 500;
	letter-spacing: 0.24em;
	text-transform: uppercase;
	color: var(--wp--preset--color--accent);
	display: inline-flex;
	align-items: center;
	gap: 0.7rem;
	margin: 0 0 1.4rem;
}
.ap-eyebrow::before {
	content: "";
	width: 2.25rem;
	height: 1px;
	background: currentColor;
}

/* Technical caption — lens, stop, stock, plate numbers. */
.ap-meta {
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--tiny) !important;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--wp--preset--color--muted);
	line-height: 1.6;
}
.ap-meta strong { color: var(--wp--preset--color--accent); font-weight: 500; }

.ap-kicker {
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--tiny) !important;
	letter-spacing: 0.2em;
	text-transform: uppercase;
	color: var(--wp--preset--color--muted);
}
.ap-index {
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--tiny) !important;
	color: var(--wp--preset--color--accent);
	letter-spacing: 0.2em;
}

/* Standfirst — deliberately smaller than the old draft so the headline wins. */
.ap-standfirst {
	font-size: var(--wp--preset--font-size--large) !important;
	line-height: 1.5;
	max-width: 36ch;
}

/* Headings get a little optical weight back on a dark ground. */
:where(h1, h2, h3) { text-wrap: balance; }
.ap-accent { color: var(--wp--preset--color--accent); }

/* Rules */
.ap-rule {
	border: 0;
	border-top: 1px solid var(--wp--preset--color--hairline);
	margin: 0;
	height: 0;
	opacity: 1;
}
.ap-rule--accent {
	border-top-color: var(--wp--preset--color--accent);
	width: 4.5rem;
	border-top-width: 2px;
}

/* 3 · Frames ------------------------------------------------------------- */

/* The double bezel: an outer tray, an inner plate, concentric radii. */
.ap-frame {
	padding: var(--ap-pad);
	border-radius: var(--ap-bezel);
	background: linear-gradient(180deg, rgba(244, 241, 235, 0.1), rgba(244, 241, 235, 0.02));
	border: 1px solid rgba(244, 241, 235, 0.1);
	position: relative;
}
.ap-frame > * {
	border-radius: calc(var(--ap-bezel) - var(--ap-pad));
	overflow: hidden;
	display: block;
	margin: 0;
	box-shadow: inset 0 1px 0 rgba(244, 241, 235, 0.12);
}
.ap-frame figure { margin: 0; }
.ap-frame img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Fixed ratios so a grid of mixed-shape sources still lines up. */
.ap-card .ap-frame { aspect-ratio: 4 / 3; }
.ap-card .ap-frame > * { height: 100%; }

/* The grade. Nine unrelated sources, one register — colour returns on hover. */
.ap-grade img {
	filter: grayscale(0.8) contrast(1.32) brightness(0.92) sepia(0.14);
	transition: filter var(--ap-slow) var(--ap-ease), transform var(--ap-slow) var(--ap-ease);
	will-change: transform;
}
.ap-grade:hover img,
.ap-grade:focus-within img {
	filter: grayscale(0) contrast(1.04) brightness(1) sepia(0);
	transform: scale(1.04);
}

/* A tungsten wash over every plate, so stills sit in the palette rather than
   next to it. Static, never animated. */
.ap-grade::after {
	content: "";
	position: absolute;
	inset: var(--ap-pad);
	border-radius: calc(var(--ap-bezel) - var(--ap-pad));
	pointer-events: none;
	background: linear-gradient(190deg, rgba(224, 138, 69, 0.14), rgba(8, 8, 10, 0.45));
	mix-blend-mode: soft-light;
	transition: opacity var(--ap-slow) var(--ap-ease);
}
.ap-grade:hover::after { opacity: 0; }

/* 4 · Cards -------------------------------------------------------------- */

.ap-card {
	display: flex;
	flex-direction: column;
	gap: 1rem;
	transition: transform var(--ap-slow) var(--ap-ease);
}
.ap-card:hover { transform: translateY(-8px); }
.ap-card h3 a { transition: color var(--ap-quick) var(--ap-ease); }

/* 5 · Header and hero ---------------------------------------------------- */

.ap-nav {
	position: sticky;
	top: 0;
	z-index: 20;
	backdrop-filter: blur(18px) saturate(130%);
	-webkit-backdrop-filter: blur(18px) saturate(130%);
	background: color-mix(in srgb, var(--wp--preset--color--base) 70%, transparent);
	border-bottom: 1px solid var(--wp--preset--color--hairline);
}
.ap-nav .wp-block-navigation {
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--tiny);
	letter-spacing: 0.2em;
	text-transform: uppercase;
}
.wp-block-site-title a { text-decoration: none; }

/* The hero is a composition, not a photo with type on it: a black type column,
   a key light falling from the upper right, and a framed plate. */
.ap-hero {
	position: relative;
	isolation: isolate;
	overflow: hidden;
}
.ap-hero img.wp-block-cover__image-background {
	filter: contrast(1.12) saturate(1.1) brightness(0.86);
}
.ap-hero .wp-block-cover__inner-container { width: 100%; }

.ap-hero__title {
	line-height: 0.86;
	letter-spacing: -0.035em;
	text-shadow: 0 2px 40px rgba(8, 8, 10, 0.9);
}

/* The running order under the hero. */

/* 6 · Frame study — the strip between sprocket rails ---------------------- */

.ap-strip {
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: minmax(17rem, 23rem);
	gap: 1.25rem;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	padding-block: 2rem;
	scrollbar-width: thin;
	scrollbar-color: var(--wp--preset--color--hairline) transparent;
}
.ap-strip > * { scroll-snap-align: start; }
.ap-strip::-webkit-scrollbar { height: 3px; }
.ap-strip::-webkit-scrollbar-thumb { background: var(--wp--preset--color--hairline); }

.ap-sprockets { position: relative; }
.ap-sprockets::before,
.ap-sprockets::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	height: 9px;
	background-image: repeating-linear-gradient(
		90deg,
		var(--wp--preset--color--hairline) 0 16px,
		transparent 16px 38px
	);
	pointer-events: none;
}
.ap-sprockets::before { top: 0; }
.ap-sprockets::after { bottom: 0; }

/* 7 · Buttons ------------------------------------------------------------ */

/* Nested icon disc — the arrow never sits naked beside the label. */
.ap-cta a.wp-block-button__link {
	display: inline-flex;
	align-items: center;
	gap: 0.9rem;
	padding-right: 0.4rem !important;
	transition: background-color var(--ap-quick) var(--ap-ease),
		color var(--ap-quick) var(--ap-ease),
		border-color var(--ap-quick) var(--ap-ease),
		transform var(--ap-quick) var(--ap-ease);
}
.ap-cta a.wp-block-button__link::after {
	content: "↗";
	display: grid;
	place-items: center;
	width: 2rem;
	height: 2rem;
	border-radius: 999px;
	background: rgba(8, 8, 10, 0.14);
	font-size: 0.78rem;
	line-height: 1;
	transition: transform var(--ap-slow) var(--ap-ease), background-color var(--ap-quick) var(--ap-ease);
}
.ap-cta a.wp-block-button__link:hover::after {
	transform: translate(3px, -3px) scale(1.06);
}
.ap-cta a.wp-block-button__link:active { transform: scale(0.985); }

/* Ghost variant — used where a solid pill would outshout the headline. */
.wp-block-button.is-style-ghost > .wp-block-button__link {
	background: transparent;
	color: var(--wp--preset--color--contrast);
	border: 1px solid var(--wp--preset--color--hairline);
}
.wp-block-button.is-style-ghost > .wp-block-button__link::after {
	background: rgba(244, 241, 235, 0.08);
}
.wp-block-button.is-style-ghost > .wp-block-button__link:hover {
	background: var(--wp--preset--color--accent);
	border-color: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--base);
}

/* 8 · Bands and motion --------------------------------------------------- */

.ap-band { position: relative; }
.ap-band::before {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
	background: radial-gradient(50% 60% at 78% 0%, rgba(224, 138, 69, 0.11), rgba(8, 8, 10, 0) 72%);
}

/* Scroll-driven entry, no JavaScript. Browsers without view() timelines
   simply show the content, which is the correct fallback. */
@supports (animation-timeline: view()) {
	@media (prefers-reduced-motion: no-preference) {
		.ap-reveal {
			animation: ap-rise linear both;
			animation-timeline: view();
			animation-range: entry 6% cover 30%;
		}
	}
}
@keyframes ap-rise {
	from { opacity: 0; transform: translate3d(0, 2.5rem, 0); }
	to   { opacity: 1; transform: translate3d(0, 0, 0); }
}

:where(a, button, input, .wp-block-button__link):focus-visible {
	outline: 2px solid var(--wp--preset--color--accent);
	outline-offset: 3px;
	border-radius: 2px;
}

@media (prefers-reduced-motion: reduce) {
	*, *::before, *::after {
		animation-duration: 0.01ms !important;
		transition-duration: 0.01ms !important;
	}
	.ap-grade img { transform: none !important; }
}

/* 9 · Mobile — asymmetry collapses cleanly ------------------------------- */
@media (max-width: 781px) {
	.ap-standfirst { max-width: none; }
	.ap-strip { grid-auto-columns: minmax(14rem, 78vw); }
	.ap-frame { --ap-bezel: 0.75rem; }
}
/* 10 · Card plates — the grid reads as objects on a ground, not as loose
      images with captions under them. Outer tray, inner core. */
.ap-card--plate {
	background: linear-gradient(180deg, #16161C 0%, #101015 100%);
	border: 1px solid var(--wp--preset--color--hairline);
	border-radius: 1.15rem;
	padding: 0.5rem 0.5rem 1.75rem;
	transition: transform var(--ap-slow) var(--ap-ease), border-color var(--ap-quick) var(--ap-ease);
}
.ap-card--plate:hover { border-color: color-mix(in srgb, var(--wp--preset--color--accent) 45%, transparent); }
.ap-card--plate > :not(.ap-frame) { padding-inline: 1.15rem; }
.ap-card--plate .ap-frame {
	border: 0;
	background: none;
	padding: 0;
	--ap-bezel: 0.7rem;
	border-radius: 0.7rem;
}
.ap-card--plate .ap-frame > * { border-radius: 0.7rem; }
.ap-card--plate .ap-grade::after { inset: 0; border-radius: 0.7rem; }

/* 11 · Separators default to a short centred line in core; ours are structural
      rules that should run the full measure. */
.wp-block-separator.ap-rule:not(.ap-rule--accent) {
	width: 100%;
	max-width: none;
}

/* 12 · Rhythm fixes -------------------------------------------------------
   Columns stretch to match their tallest sibling, which left the subscribe
   plate half empty and the anatomy spread floating. Start-align instead, and
   hold the strip's cards to one baseline so four frames read as a strip
   rather than four loose cards. */
.ap-band .wp-block-columns,
.ap-split { align-items: start; }

.ap-strip > .ap-card { align-self: start; }
.ap-strip .ap-frame { aspect-ratio: 4 / 3; }
.ap-strip h3 { min-height: 2.1em; }

/* The grade was leaving a fifth of the original colour in, which read as a
   wash rather than a decision. Take it further; hover still restores it. */
.ap-grade img { filter: grayscale(0.9) contrast(1.34) brightness(0.9) sepia(0.16); }

/* A section head and its rule belong together; the separator under "Latest"
   was drifting away from the heading it belongs to. */
.ap-rule--accent { margin-bottom: 0; }

/* ==========================================================================
   13 · Direction change — the page had one value range and one muted accent,
   which read as dull however well the parts were set. Colour comes back into
   the stills, the accent becomes a field rather than a hairline, and the
   sequence alternates black → bone → black → tungsten instead of running
   five screens of unrelieved dark.
   ========================================================================== */

/* Stills are photographs again. Hover now pulls the colour *out*, which makes
   the interaction a deliberate act rather than a rescue. */
.ap-grade img {
	filter: contrast(1.1) saturate(1.06) brightness(1);
	transition: filter var(--ap-slow) var(--ap-ease), transform var(--ap-slow) var(--ap-ease);
}
.ap-grade:hover img,
.ap-grade:focus-within img {
	filter: grayscale(0.85) contrast(1.25) brightness(0.86);
	transform: scale(1.04);
}
.ap-grade::after { opacity: 0.45; }
.ap-grade:hover::after { opacity: 0.85; }

/* The hero: masthead type, set tight and large, over a still that keeps its
   colour on the lit side of the frame. */
.ap-hero__title {
	font-weight: 700;
	line-height: 0.82;
	letter-spacing: -0.045em;
	text-shadow: 0 4px 60px rgba(8, 8, 10, 0.85);
}
.ap-hero__inner { position: relative; }

/* An iris, drawn not photographed, bled off the top right of the hero. */
.ap-iris {
	position: absolute;
	top: clamp(-14rem, -12vw, -6rem);
	right: clamp(-6rem, -4vw, -2rem);
	width: clamp(16rem, 30vw, 30rem);
	aspect-ratio: 1;
	color: var(--wp--preset--color--accent);
	opacity: 0.5;
	pointer-events: none;
	animation: ap-iris-turn 90s linear infinite;
}
@keyframes ap-iris-turn { to { transform: rotate(360deg); } }

/* A tungsten field carrying the running order, moving slowly. */
.ap-ticker {
	overflow: hidden;
	padding-block: 0.85rem;
	border-block: 1px solid rgba(8, 8, 10, 0.25);
}
.ap-ticker__track {
	display: flex;
	width: max-content;
	animation: ap-ticker-run 42s linear infinite;
}
.ap-ticker__track span {
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--tiny);
	font-weight: 500;
	letter-spacing: 0.22em;
	text-transform: uppercase;
	white-space: nowrap;
	padding-right: 2.5rem;
}
.ap-ticker__track i { font-style: normal; padding-inline: 2.5rem; opacity: 0.55; }
@keyframes ap-ticker-run { to { transform: translate3d(-50%, 0, 0); } }

/* The bone section — a hard cut out of the dark, halfway down the page. */
.ap-invert { color: var(--wp--preset--color--base); }
.ap-invert h1, .ap-invert h2, .ap-invert h3, .ap-invert h4,
.ap-invert p, .ap-invert blockquote, .ap-invert li { color: var(--wp--preset--color--base); }
.ap-invert .ap-eyebrow { color: #9A4A18; }
.ap-invert .ap-kicker,
.ap-invert .ap-meta { color: rgba(8, 8, 10, 0.62); }
.ap-invert .ap-meta strong { color: #9A4A18; }
.ap-invert .ap-frame {
	background: linear-gradient(180deg, rgba(8, 8, 10, 0.12), rgba(8, 8, 10, 0.04));
	border-color: rgba(8, 8, 10, 0.16);
}
.ap-invert .ap-rule { border-top-color: rgba(8, 8, 10, 0.18); }
.ap-invert .wp-block-pullquote { border-left-color: #9A4A18 !important; }

/* The tungsten plate before the footer. */
.ap-plate-accent {
	border-radius: 1.25rem;
	color: var(--wp--preset--color--base);
	box-shadow: 0 40px 90px -50px rgba(224, 138, 69, 0.8);
}
.ap-plate-accent :where(h2, h3, p) { color: var(--wp--preset--color--base); }
.ap-plate-accent .ap-kicker,
.ap-plate-accent .ap-meta { color: rgba(8, 8, 10, 0.66); }
.ap-band::before { background: radial-gradient(52% 62% at 76% 0%, rgba(224, 138, 69, 0.18), rgba(8, 8, 10, 0) 72%); }

/* Oversized outlined numerals on the article cards — structure you can see
   from across the room. */
.ap-bignum {
	font-family: var(--wp--preset--font-family--display);
	font-size: clamp(3.5rem, 6vw, 5.5rem) !important;
	line-height: 0.8;
	font-weight: 700;
	color: transparent;
	-webkit-text-stroke: 1px var(--wp--preset--color--accent);
	letter-spacing: -0.02em;
	opacity: 0.85;
}

@media (prefers-reduced-motion: reduce) {
	.ap-ticker__track, .ap-iris { animation: none !important; }
}
@media (max-width: 781px) {
	.ap-iris { display: none; }
}
