/**
 * Styles for the Photo RAW 2027 pages
 *
 * @copyright   2026, ON1
 */

/* !- Eyebrow */
.eyebrow {
	color: var(--blue-500);
	font-size: 0.6875rem;
	font-weight: 700;
}

/* !- Passed videos */
#passed-video {
	background: var(--bg-950);
	margin-top: -46px;
	padding: calc(5rem + 46px) 0 5rem 0;
}

#passed-video .video-figure {
	margin-bottom: 1.75rem;
}

#passed-video h2 {
	font-size: 1.875rem;
	font-weight: 700;
	letter-spacing: -0.01em;
	line-height: 1.2;
	margin-bottom: 1rem;
	text-align: center;
}

#passed-video .btn {
	padding: 0.9375rem 1.875rem;
}

/* !- Product navigation */
#product-navigation.is-sticky {
	background: color-mix(in srgb, var(--bg-900) 75%, transparent);
	border-top: 0;
}

@media (max-width: 575.98px) {
	#product-navigation {
		background: var(--bg-900);
	}
}

#product-navigation .nav {
	align-items: center;
}

@media (max-width: 575.98px) {
	#product-navigation .nav-item .nav-link {
		padding-left: 0.5rem;
		padding-right: 0.5rem;
	}
}

#product-navigation .nav-link small {
	font-size: var(--text-xs);
	position: relative;
	top: 0.125em;
}

#product-navigation .nav-link strong {
	color: var(--text-50);
	font-weight: 600;
}

#product-navigation .nav-link {
	color: var(--text-300);
	text-decoration: none;
}

#product-navigation .nav-link:hover {
	color: var(--text-50);
}


#product-navigation a.nav-link.active {
	color: var(--text-50);
}

#product-navigation a.nav-link.active small {
	border-bottom: 1px solid var(--text-50);
}

/* !- Hero */
#hero {
	background: var(--bg-950);
	margin-top: -46px;
	padding: calc(5rem + 46px) 0 2.5rem 0;
	text-align: center;
}

#passed-video + #hero {
	margin-top: 0;
	padding-top: 5rem;
}

#hero .eyebrow {
	margin-bottom: 2.25rem;
}

#hero .eyebrow span {
	align-items: center;
	background: var(--blue-transparent);
	border-radius: var(--border-radius);
	color: var(--blue-300);
	display: inline-flex;
	gap: 0.5rem;
	letter-spacing: 0.08em;
	padding: 0.3125rem 0.75rem;
	text-transform: uppercase;
}

#hero .eyebrow-icon {
	border-radius: 22%;
}

/* The mockup deliberately runs the two big headlines past the base type scale
   for hero impact: 76px here and 56px on the lockup below, dropping to 44/38 on
   narrow viewports. Matched literally rather than mapped onto --text-* steps,
   which top out at 3rem. */
#hero h1 {
	color: var(--white);
	font-size: 4.75rem;
	font-weight: 800;
	letter-spacing: -0.03em;
	line-height: 1.02;
	margin-bottom: 1.375rem;
}

/* The aperture ring in the product mark has exactly three blades - blue,
   orange/gold, purple/magenta - so the accent sweep uses those hues only. */
#hero .hero-accent {
	-webkit-background-clip: text;
	background-clip: text;
	background-image: linear-gradient(-40deg, var(--blue-500) 0%, var(--blue-300) 22%, var(--orange-500) 48%, var(--gold-400) 64%, var(--purple-500) 84%, var(--magenta-500) 100%);
	color: transparent;
}

#hero .hero-sub {
	color: var(--text-300);
	font-size: var(--text-lg);
	line-height: 1.6;
	margin-bottom: 2.25rem;
}

#hero .hero-note {
	color: var(--text-400);
	font-size: var(--text-xs);
	margin-bottom: 0;
}

/* Matches the NoNoise AI 2027 hero button: this padding plus Bootstrap's
   default 1rem, no font-size override, so the two 2027 product heroes carry the
   same CTA. Scoped to the hero, not the page - a bare .btn here would also
   catch the product subnav's .btn-sm and blow out its sizing. */
#hero .btn {
	padding: 0.9375rem 1.875rem;
}

/* !- Hero visual */
#hero-visual {
	background:
		linear-gradient(160deg, rgba(18, 14, 10, 0.6) 0%, rgba(14, 12, 10, 0.32) 45%, rgba(10, 9, 8, 0.7) 100%),
		url(https://ononesoft.cachefly.net/images/products/2027/photo-raw/on1-photo-raw-2027-hero-bridge-sunset.jpg) center 58% no-repeat;
	background-size: cover, cover;
	padding: 2.5rem 0 5.5rem 0;
	position: relative;
}

/* Fade the photo out at both ends so it merges into the flat sections either
   side instead of hard-cutting at the boundary. Up into the hero above
   (--bg-950), down into the page below (--bg-900). */
#hero-visual::before,
#hero-visual::after {
	content: '';
	height: 10rem;
	left: 0;
	pointer-events: none;
	position: absolute;
	right: 0;
}

#hero-visual::before {
	background: linear-gradient(to bottom, var(--bg-950), transparent);
	top: 0;
}

#hero-visual::after {
	background: linear-gradient(to bottom, transparent, var(--bg-900));
	bottom: 0;
}

#hero-visual .container {
	position: relative;
	z-index: 1;
}

#hero-visual .hero-lockup {
	margin-bottom: 3.5rem;
}

#hero-visual .hero-icon {
	border-radius: 22%;
	box-shadow: 0 1.875rem 4.375rem rgba(0, 0, 0, 0.4);
}

/* Matches the mockup's 56px gap between the icon and the headline below it. */
#hero-visual .hero-icon-wrap {
	margin-bottom: 3.5rem;
}

/* The lockup and strip sit on the photo in both themes, so their colors are
   pinned light rather than following the theme toggle. */
#hero-visual h2 {
	color: var(--white);
	font-size: 3.5rem;
	font-weight: 800;
	letter-spacing: -0.025em;
	line-height: 1.05;
	margin-bottom: 1.125rem;
	text-shadow: 0 0.125rem 0.875rem rgba(0, 0, 0, 0.45);
	text-wrap: balance;
}

/* :not() keeps this off the icon above, which needs its own bottom margin and
   would otherwise lose to this rule's higher specificity. */
#hero-visual .hero-lockup p:not(.hero-icon-wrap) {
	color: rgba(255, 255, 255, 0.86);
	margin-bottom: 0;
	text-shadow: 0 0.0625rem 0.5rem rgba(0, 0, 0, 0.4);
}

/* The mockup steps both oversized headlines down at its own 860px breakpoint;
   snapped to Bootstrap's lg boundary to stay on the grid's breakpoints. */
@media (max-width: 991.98px) {
	#hero h1 {
		font-size: 2.75rem;
	}

	#hero-visual h2 {
		font-size: 2.375rem;
	}
}

/* !- Icon strips (hero upgrade-ease strip, AI trust strip)
   Base is the mockup's icon-left/text-right row with no card chrome, which is
   how the trust strip renders. The hero variant restacks it centred and frosted
   because it sits on the photo rather than a flat section. */
.ease-item {
	align-items: flex-start;
	display: flex;
	gap: 0.875rem;
	text-align: left;
}

.ease-icon {
	align-items: center;
	background: var(--blue-transparent);
	border-radius: var(--border-radius);
	color: var(--blue-500);
	display: inline-flex;
	flex: none;
	height: 2.25rem;
	justify-content: center;
	width: 2.25rem;
}

.ease-title {
	color: var(--text-50);
	font-size: 0.90625rem;
	font-weight: 600;
	margin-bottom: 0.1875rem;
}

.ease-copy {
	color: var(--text-300);
	font-size: var(--text-xs);
	line-height: 1.5;
	margin-bottom: 0;
}

.trust-strip {
	margin-bottom: 5rem;
	margin-top: 4rem;
}

/* Hero variant: restacked, centred, frosted, over the photo, colors pinned
   light rather than following the theme toggle. */
#hero-visual .ease-item {
	backdrop-filter: blur(1.25rem) saturate(150%);
	-webkit-backdrop-filter: blur(1.25rem) saturate(150%);
	align-items: center;
	background: linear-gradient(165deg, rgba(255, 255, 255, 0.16), rgba(255, 255, 255, 0.05));
	border: 1px solid rgba(255, 255, 255, 0.18);
	border-radius: var(--border-radius);
	box-shadow: 0 1.25rem 2.75rem rgba(0, 0, 0, 0.3);
	flex-direction: column;
	gap: 0;
	height: 100%;
	padding: 1.875rem 1.625rem 2.125rem 1.625rem;
	text-align: center;
}

#hero-visual .ease-icon {
	background: rgba(255, 255, 255, 0.16);
	color: var(--blue-300);
	font-size: var(--text-xl);
	height: 2.875rem;
	margin-bottom: 0.75rem;
	width: 2.875rem;
}

#hero-visual .ease-title {
	color: var(--white);
	font-size: var(--text-base);
	text-shadow: 0 0.0625rem 0.375rem rgba(0, 0, 0, 0.4);
}

#hero-visual .ease-copy {
	color: rgba(255, 255, 255, 0.82);
	font-size: var(--text-sm);
	text-shadow: 0 0.0625rem 0.375rem rgba(0, 0, 0, 0.35);
}

/* !- Sections */
.section-intro {
	margin-bottom: 2.25rem;
}

/* !- NoNoise AI loupe
   #nonoise is a .pr-card, not a section - it must not carry section padding,
   or the id beats .pr-card's own and the content goes flush to the edge. */
.lp-frame {
	background: var(--bg-900);
	border-radius: var(--border-radius);
	cursor: crosshair;
	height: clamp(16.25rem, 62vw, 37.5rem);
	overflow: hidden;
	position: relative;
	touch-action: none;
	width: 100%;
}

.lp-frame:focus-visible {
	outline: 2px solid var(--blue-500);
	outline-offset: 3px;
}

.lp-base {
	background-position: center;
	background-size: cover;
	height: 100%;
	user-select: none;
	width: 100%;
}

.lp-badge {
	background: rgba(0, 0, 0, 0.5);
	backdrop-filter: blur(0.5rem);
	-webkit-backdrop-filter: blur(0.5rem);
	border-radius: var(--border-radius);
	color: var(--white);
	font-size: var(--text-micro);
	font-weight: 700;
	left: 1.25rem;
	letter-spacing: 0.08em;
	margin: 0;
	padding: 0.4375rem 0.875rem;
	position: absolute;
	text-transform: uppercase;
	top: 1.25rem;
	transition: opacity 0.12s cubic-bezier(0.4, 0, 0.2, 1);
}

.lp-compare.is-empty .lp-badge {
	opacity: 0;
}

.lp-empty {
	align-items: center;
	color: var(--text-400);
	display: none;
	font-size: var(--text-sm);
	inset: 0;
	justify-content: center;
	margin: 0;
	padding: 2.5rem;
	position: absolute;
	text-align: center;
}

.lp-compare.is-empty .lp-empty {
	display: flex;
}

.lp-loupe {
	border-radius: var(--border-radius);
	box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.9), 0 1.5rem 3rem rgba(0, 0, 0, 0.55);
	left: 0;
	opacity: 0;
	overflow: hidden;
	pointer-events: none;
	position: absolute;
	top: 0;
	transition: opacity 0.12s cubic-bezier(0.4, 0, 0.2, 1);
	will-change: transform;
}

.lp-layer {
	background-repeat: no-repeat;
	inset: 0;
	position: absolute;
	will-change: background-position;
}

.lp-after {
	clip-path: inset(0 0 0 50%);
}

.lp-before {
	clip-path: inset(0 50% 0 0);
}

.lp-loupe.is-held .lp-before {
	clip-path: inset(0 0 0 0);
}

.lp-divider {
	background: rgba(255, 255, 255, 0.85);
	bottom: 0;
	left: 50%;
	position: absolute;
	top: 0;
	transition: opacity 0.12s cubic-bezier(0.4, 0, 0.2, 1);
	width: 1px;
}

.lp-loupe.is-held .lp-divider {
	opacity: 0;
}

.lp-labels {
	bottom: 1rem;
	display: flex;
	justify-content: space-between;
	left: 0;
	padding: 0 1.125rem;
	position: absolute;
	right: 0;
}

/* Below ~300px wide the two corner chips collide, so they pair up centered. */
.lp-loupe.is-tight .lp-labels {
	bottom: 0.625rem;
	gap: 0.375rem;
	justify-content: center;
	padding: 0 0.625rem;
}

.lp-chip {
	align-items: center;
	background: rgba(0, 0, 0, 0.55);
	border-radius: var(--border-radius);
	color: var(--white);
	display: inline-flex;
	font-size: var(--text-micro);
	font-weight: 700;
	height: 1.375rem;
	letter-spacing: 0.08em;
	padding: 0 0.625rem;
	text-transform: uppercase;
	transition: opacity 0.12s cubic-bezier(0.4, 0, 0.2, 1);
	white-space: nowrap;
}

.lp-loupe.is-tight .lp-chip {
	height: 1.25rem;
	padding: 0 0.4375rem;
}

.lp-loupe.is-held .lp-chip-after {
	opacity: 0;
}

.lp-hint {
	align-items: center;
	display: flex;
	inset: 0;
	justify-content: center;
	pointer-events: none;
	position: absolute;
	transition: opacity 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}

.lp-compare.is-inside .lp-hint,
.lp-compare.is-empty .lp-hint {
	opacity: 0;
}

.lp-hint span {
	background: rgba(0, 0, 0, 0.5);
	backdrop-filter: blur(0.5rem);
	-webkit-backdrop-filter: blur(0.5rem);
	border-radius: var(--border-radius);
	color: var(--white);
	font-size: var(--text-sm);
	padding: 0.75rem 1.25rem;
}

/* !- Loupe photo picker */
.lp-rail {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem;
	margin-top: 1.125rem;
}

.lp-thumb {
	background: none;
	border: 0;
	border-radius: var(--border-radius);
	cursor: pointer;
	display: block;
	flex: 1 1 6rem;
	outline: 2px solid transparent;
	outline-offset: 2px;
	overflow: hidden;
	padding: 0;
	position: relative;
	transition: outline-color 0.2s ease, transform 0.2s ease;
}

.lp-thumb:hover {
	transform: translateY(-2px);
}

.lp-thumb:focus-visible {
	outline-color: var(--blue-500);
}

.lp-thumb.is-active {
	outline-color: var(--blue-500);
}

.lp-thumb img {
	aspect-ratio: 4 / 3;
	display: block;
	height: auto;
	object-fit: cover;
	width: 100%;
}

.lp-thumb-name {
	background: linear-gradient(to top, rgba(0, 0, 0, 0.65), transparent);
	bottom: 0;
	color: var(--white);
	font-size: var(--text-tiny);
	font-weight: 700;
	left: 0;
	letter-spacing: 0.08em;
	padding: 1.25rem 0.625rem 0.5rem 0.625rem;
	position: absolute;
	right: 0;
	text-align: left;
	text-transform: uppercase;
}

.lp-foot {
	color: var(--text-400);
	display: flex;
	flex-wrap: wrap;
	gap: 0.625rem 1.875rem;
	justify-content: space-between;
	margin-top: 1.125rem;
}

.lp-note {
	font-size: var(--text-xs);
	line-height: 1.4;
}

.lp-caption {
	font-size: var(--text-xs);
	white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
	.lp-thumb:hover {
		transform: none;
	}
}

/* !- What's New
   The act runs across three sections - #highlights, #culling, #highlights-more -
   because #culling has to pin data-theme="dark" for its card. Only the outer two
   edges carry padding so the three read as one continuous run. */
#highlights,
#highlights-more,
#highlights-rest {
	padding: 5rem 0;
}

/* Dark band, pinned via data-theme="dark" so it reads the same in either page
   theme. Three surfaces stack here - band, card, and the embed's own app window
   - so they are deliberately spread across the scale (950 / 800 / the embed's
   own greys) instead of sitting one step apart, where the boundaries turned to
   mud.

   The explicit color is not optional: pinning a region with data-theme only
   redefines the tokens. Any text without its own color rule keeps body's
   already-computed value, which on a light page is dark grey on a dark band. */
#culling,
#masking {
	background: var(--bg-950);
	color: var(--text-300);
	padding: 5rem 0;
}

/* Same value the embed paints on its own [data-outer] (#1E1E1E, its --bg), so
   the card and the iframe read as one continuous surface with no seam. The band
   behind them is a step darker to separate the section. */
#culling .pr-card,
#masking .pr-card {
	background: var(--bg-900);
	margin-bottom: 0;
}

#culling p,
#masking p {
	color: var(--text-300);
}

/* The gap between a card's copy and its full-bleed media, shared by all three
   of those cards so they read the same. Both embeds have their own outer padding
   zeroed (it doubled up with the card's), so this is the only thing separating
   the copy from the app window. #nonoise is itself the .pr-card rather than a
   section wrapping one, hence the different shape of its selector; without it
   the loupe sat 20px below its copy against the embeds' 36px. */
#culling .pr-card > p:not(.pr-badges):not(.pr-watch),
#masking .pr-card > p:not(.pr-badges):not(.pr-watch),
#nonoise > p:not(.pr-badges):not(.pr-watch) {
	margin-bottom: 2.25rem;
}

/* The card immediately above the band drops its own margin, so the separation is
   the section padding alone and matches the gap on the far side. */
#highlights > .container > .row:last-child .pr-card {
	margin-bottom: 0;
}

/* Same reasoning for the trust strip. Splitting #masking out of the band left
   the strip as its last row, so its own 5rem bottom margin started stacking on
   the section's 5rem padding - a 160px gap below against ~100px above. The
   section padding alone is the gap. */
#highlights-more > .container > .row:last-child .trust-strip {
	margin-bottom: 0;
}

#highlights .section-intro h2,
#highlights-more .section-intro h2,
#highlights-rest .section-intro h2 {
	font-size: var(--text-3xl);
	font-weight: 800;
	letter-spacing: -0.015em;
	text-wrap: balance;
}

/* !- Feature cards */
.pr-card {
	background: var(--bg-700);
	border-radius: var(--border-radius);
	box-shadow: 0 0.0625rem 0.125rem rgba(0, 0, 0, 0.05), 0 0.75rem 1.75rem rgba(0, 0, 0, 0.08);
	margin-bottom: 2.25rem;
	padding: 2.25rem;
}

.pr-card h3,
#culling h3,
#masking h3 {
	font-size: 1.75rem;
	font-weight: 800;
	letter-spacing: -0.02em;
	margin-bottom: 0.75rem;
	text-wrap: balance;
}

.pr-card > p,
.pr-card .col > p {
	color: var(--text-300);
	margin-bottom: 1.25rem;
}

/* Accent half of a feature headline. Blue, orange and purple only - the three
   blades in the product mark. */
.spot-blue {
	color: var(--blue-500);
}

.spot-orange {
	color: var(--orange-500);
}

.spot-purple {
	color: var(--purple-400);
}

/* !- Badges */
.pr-badges {
	margin-bottom: 1rem;
}

.pr-badge {
	border-radius: var(--border-radius);
	display: inline-block;
	font-size: var(--text-micro);
	font-weight: 700;
	letter-spacing: 0.08em;
	padding: 0.25rem 0.625rem;
	text-transform: uppercase;
	white-space: nowrap;
}

.pr-badge-blue {
	background: var(--blue-transparent);
	color: var(--blue-300);
}

.pr-badge-orange {
	background: var(--orange-transparent);
	color: var(--orange-500);
}

.pr-badge-purple {
	background: color-mix(in srgb, var(--purple-500) 18%, transparent);
	color: var(--purple-300);
}

.pr-badge-gold {
	background: var(--gold-transparent);
	color: var(--gold-500);
}

/* !- "See It in Action" */
.pr-watch a,
.pr-link {
	align-items: center;
	color: var(--blue-300);
	display: inline-flex;
	font-size: var(--text-sm);
	font-weight: 600;
	gap: 0.5rem;
	text-decoration: none;
}

.pr-watch a:hover,
.pr-link:hover {
	color: var(--blue-200);
	text-decoration: underline;
}

.pr-watch {
	margin-bottom: 1.25rem;
}

.pr-watch i {
	font-size: var(--text-2xl);
}

/* !- Placeholder imagery
   Every feature visual is a placeholder until real screenshots and photography
   land. Deliberately reads as a labelled slot, not as a real screenshot. */
.pr-shots {
	margin-top: 0.5rem;
}

.pr-shot {
	align-items: center;
	aspect-ratio: 4 / 3;
	background: var(--bg-600);
	border-radius: var(--border-radius);
	display: flex;
	flex-direction: column;
	gap: 0.625rem;
	justify-content: center;
	margin: 0;
	padding: 1rem;
	position: relative;
	text-align: center;
}

.pr-shot-wide {
	aspect-ratio: 3 / 2;
}

.pr-shot-square {
	aspect-ratio: 1 / 1;
}

.pr-shot i {
	color: var(--text-300);
	font-size: var(--text-3xl);
}

.pr-shot figcaption {
	color: var(--text-300);
	font-size: var(--text-xs);
	line-height: 1.4;
}

.pr-shot.is-pick {
	border-color: var(--gold-500);
	border-style: solid;
}

.pr-shot-pick {
	align-items: center;
	background: var(--gold-500);
	border-radius: 50%;
	color: var(--bg-950);
	display: flex;
	font-size: var(--text-micro);
	height: 1.375rem;
	justify-content: center;
	position: absolute;
	right: 0.5rem;
	top: 0.5rem;
	width: 1.375rem;
}

/* !- App theme preview
   The light/dark screenshot pair with drag-to-pan, full width below the copy.
   Full width because the screenshot is a 2074x1148 desktop capture - in a half
   column it rendered at 787px with only 58% visible, which is unreadable.

   The window's HEIGHT is what is set here, not an aspect ratio: the track takes
   its width from the image's own proportions, so there are no ratio constants to
   keep in sync with the CSS, and the pan distance is whatever actually overflows.
   photo-raw.js measures that off the DOM, so replacing the screenshots or
   changing these heights needs no recalculation.

   .is-light on [data-theme-preview] is the single state class: it drives the
   cross-fade and the sun/moon accents together. It refers to the THEME OF THE
   SCREENSHOT, not the site's theme - this component never touches
   :root[data-theme] or the on1-theme preference. */
.theme-controls {
	align-items: center;
	display: flex;
	flex-wrap: wrap;
	gap: 1.5rem;
	margin-top: 1.5rem;
}

.theme-toggle {
	align-items: center;
	display: flex;
	gap: 0.625rem;
	min-height: 2.75rem;
}

.theme-toggle-icon {
	color: var(--text-400);
	font-size: 1rem;
	transition: color 200ms cubic-bezier(0.4, 0, 0.2, 1);
}

[data-theme-preview] .theme-toggle-icon[data-theme-icon="dark"],
[data-theme-preview].is-light .theme-toggle-icon[data-theme-icon="light"] {
	color: var(--blue-500);
}

[data-theme-preview].is-light .theme-toggle-icon[data-theme-icon="dark"] {
	color: var(--text-400);
}

.theme-toggle-label {
	color: var(--text-100);
	font-size: var(--text-base);
	font-weight: 500;
	margin-left: 0.625rem;
}

/* Track 48x26 with a 20px knob, per the handoff. --bg-400 rather than the
   --bg-500 midtone: it is the one step that clears 3:1 against the card in dark
   without washing the white knob out. */
.theme-switch {
	appearance: none;
	background: var(--bg-400);
	border: 0;
	border-radius: 999px;
	cursor: pointer;
	flex: none;
	height: 1.625rem;
	margin: 0;
	position: relative;
	transition: background 200ms cubic-bezier(0.4, 0, 0.2, 1);
	width: 3rem;
}

.theme-switch::before {
	background: #fff;
	border-radius: 50%;
	content: '';
	height: 1.25rem;
	left: 0.1875rem;
	position: absolute;
	top: 0.1875rem;
	transition: transform 200ms cubic-bezier(0.4, 0, 0.2, 1);
	width: 1.25rem;
}

.theme-switch:checked {
	background: var(--blue-500);
}

.theme-switch:checked::before {
	transform: translateX(1.375rem);
}

.theme-switch:focus-visible {
	outline: 2px solid var(--blue-500);
	outline-offset: 2px;
}

/* Deliberately quiet, and gone for good once the visitor has dragged. */
.theme-pan-hint {
	align-items: center;
	color: var(--text-400);
	display: flex;
	font-size: var(--text-xs);
	gap: 0.5rem;
	margin: 0;
	transition: opacity 260ms cubic-bezier(0.4, 0, 0.2, 1);
}

.theme-pan-hint.is-spent {
	opacity: 0;
}

/* Hidden outright when the whole UI already fits and there is nothing to pan. */
.theme-pan-hint.is-idle {
	display: none;
}

/* The 12px inset keeps the app UI off the card edge.

   The colour is sampled off the screenshots' own outer edges - #1f1f1f in the
   dark app theme, #f6f6f6 in the light one - so the frame reads as an extension
   of the app window instead of a border around it. Literal hex rather than
   --bg-900 on purpose: this has to track the SCREENSHOT's theme, and --bg-900
   tracks the SITE's, which is what wrapped the dark UI in a near-white frame
   whenever the site was in light mode. */
.theme-frame {
	background: #1f1f1f;
	border-radius: calc(var(--border-radius) * 2);
	margin-top: 1.25rem;
	padding: 0.75rem;
}

[data-theme-preview].is-light .theme-frame {
	background: #f6f6f6;
}

.theme-viewport {
	border-radius: var(--border-radius);
	cursor: grab;
	/* 1148px - the screenshots' own height, so the app UI renders 1:1 and the
	   track is its natural 2074px. That is the crop the handoff designed around:
	   the image runs ~1.7x the frame width, so a bit over half of it shows and
	   the rest is what you drag to. Widen the frame without raising this and the
	   image shrinks to fit, which kills the zoom and the drag distance together.
	   This is the one number to change if the block is too tall. 56rem puts the
	   drag at ~418px on a wide screen, matching the feel of the original
	   narrow-column design, without the 1148px height that showing the image at
	   full native size would need. */
	height: 40rem;
	overflow: hidden;
	position: relative;
	touch-action: none;
	user-select: none;
	width: 100%;
}

.theme-viewport.is-dragging {
	cursor: grabbing;
}

/* Nothing overflows, so the grab cursor would be a lie. */
.theme-viewport.is-idle {
	cursor: default;
}

.theme-viewport:focus-visible {
	outline: 2px solid var(--blue-500);
	outline-offset: 2px;
}

.theme-track {
	height: 100%;
	left: 0;
	position: absolute;
	top: 0;
	width: max-content;
}

/* Height-driven: .theme-shot fills .theme-viewport's height, so the image's own
   proportions set the track width and there is no ratio constant to keep in
   sync. photo-raw.js measures the overflow off the DOM. */
.theme-shot {
	display: block;
	height: 100%;
	pointer-events: none;
	width: auto;
	-webkit-user-drag: none;
}

.theme-shot-dark {
	left: 0;
	position: absolute;
	top: 0;
	transition: opacity 200ms cubic-bezier(0.4, 0, 0.2, 1);
}

[data-theme-preview].is-light .theme-shot-dark {
	opacity: 0;
}

/* Signals "more UI this way", and clears at whichever end the pan reaches. */
.theme-fade {
	height: 100%;
	pointer-events: none;
	position: absolute;
	top: 0;
	transition: opacity 220ms cubic-bezier(0.4, 0, 0.2, 1);
	width: 15%;
}

.theme-fade.is-spent {
	opacity: 0;
}

.theme-fade-left {
	background: linear-gradient(to right, color-mix(in srgb, #1f1f1f 55%, transparent), transparent);
	left: 0;
}

[data-theme-preview].is-light .theme-fade-left {
	background: linear-gradient(to right, color-mix(in srgb, #f6f6f6 55%, transparent), transparent);
}

.theme-fade-right {
	background: linear-gradient(to left, color-mix(in srgb, #1f1f1f 55%, transparent), transparent);
	right: 0;
}

[data-theme-preview].is-light .theme-fade-right {
	background: linear-gradient(to left, color-mix(in srgb, #f6f6f6 55%, transparent), transparent);
}

@media (max-width: 991.98px) {
	.theme-viewport {
		height: 44rem;
	}
}

@media (max-width: 575.98px) {
	.theme-viewport {
		height: 30rem;
	}
}

@media (prefers-reduced-motion: reduce) {
	.theme-fade,
	.theme-pan-hint,
	.theme-shot-dark,
	.theme-switch,
	.theme-switch::before,
	.theme-toggle-icon {
		transition: none;
	}
}

/* !- Everything else */
/* The mockup gives this block 64px of air above and below. The top has to allow
   for the card above, which carries its own 36px bottom margin, so 28 + 36 = 64.
   The bottom is a plain 64px: the tile row's -16px gutter margin and its
   columns' +16px cancel out, so the first visible tile sits level with the row
   box. (Measuring to the row instead of the tile is what made an earlier pass
   read this as balanced when it was 64 above against 80 below.) */
#everything-else {
	margin-bottom: 4rem;
	margin-top: 1.75rem;
}

#everything-else h3 {
	font-size: 1.625rem;
	font-weight: 800;
	margin-bottom: 0.75rem;
}

.pr-tiles .pr-tile {
	background: var(--bg-700);
	border-radius: var(--border-radius);
	display: flex;
	flex-direction: column;
	gap: 0.75rem;
	height: 100%;
	padding: 1.625rem 1.5rem;
}

/* 2:1 slot at the top of each tile, so this grid isn't icon-and-text-only next
   to the more visual sections. Placeholder until real imagery lands. */
.pr-tile-thumb {
	align-items: center;
	aspect-ratio: 2 / 1;
	background: var(--bg-600);
	border-radius: var(--border-radius);
	display: flex;
	flex: none;
	justify-content: center;
	width: 100%;
}

.pr-tile-thumb i {
	color: var(--text-300);
	font-size: var(--text-xl);
}

.pr-tile-icon {
	align-items: center;
	background: var(--blue-transparent);
	border-radius: var(--border-radius);
	color: var(--blue-500);
	display: inline-flex;
	flex: none;
	font-size: var(--text-base);
	height: 2.375rem;
	justify-content: center;
	width: 2.375rem;
}

.pr-tile h4 {
	font-size: 0.96875rem;
	font-weight: 700;
	letter-spacing: -0.005em;
	margin-bottom: 0;
}

.pr-tile p {
	color: var(--text-300);
	font-size: var(--text-xs);
	line-height: 1.55;
	margin-bottom: 0;
}

/* Badge beside its note, wrapping below on narrow tiles, per the mockup. */
.pr-tile-note {
	align-items: flex-start;
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	margin-bottom: 0;
	padding-top: 0.75rem;
}

.pr-tile-note span:last-child {
	flex: 1;
	min-width: 10rem;
}

/* !- Customer spotlight */
#spotlight {
	padding: 5rem 0;
}

.pr-story p {
	color: var(--text-100);
	font-size: var(--text-lg);
	line-height: 1.6;
}

.pr-story-tools {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	margin-bottom: 1.25rem;
}

.pr-story-tools li {
	background: var(--bg-800);
	border-radius: var(--border-radius);
	color: var(--text-300);
	font-size: var(--text-xs);
	padding: 0.25rem 0.625rem;
}

.pr-story-name {
	color: var(--text-50);
	font-weight: 600;
	margin-bottom: 0.125rem;
}

.pr-story-role {
	color: var(--text-400);
	font-size: var(--text-xs);
}

/* !- Light theme contrast
 *
 * The accent scale is tuned for the dark surfaces, where the 300-500 steps sit
 * well clear of the background. On the light card (--bg-800, #eeeeef) the same
 * steps collapse, so each one moves down the scale until it measures at or
 * above WCAG AA against that surface. Ratios in the comments are against
 * #eeeeef, or against the badge's 16% accent wash over it.
 */
[data-theme="light"] #highlights .pr-badge-blue,
[data-theme="light"] #highlights-more .pr-badge-blue,
[data-theme="light"] #highlights-rest .pr-badge-blue {
	color: var(--blue-700); /* 4.90; 500 was 2.79 */
}

[data-theme="light"] #highlights .pr-badge-purple,
[data-theme="light"] #highlights-more .pr-badge-purple,
[data-theme="light"] #highlights-rest .pr-badge-purple {
	color: var(--purple-700); /* 5.91; 600 only reaches 4.26 */
}

[data-theme="light"] #highlights .pr-badge-gold,
[data-theme="light"] #highlights-more .pr-badge-gold,
[data-theme="light"] #highlights-rest .pr-badge-gold {
	color: var(--gold-900); /* 4.76; gold is the weakest hue here, 800 is 2.61 */
}

[data-theme="light"] #highlights .pr-badge-orange,
[data-theme="light"] #highlights-more .pr-badge-orange,
[data-theme="light"] #highlights-rest .pr-badge-orange {
	color: var(--orange-900); /* 5.95 */
}

[data-theme="light"] #highlights .pr-watch a,
[data-theme="light"] #highlights-more .pr-watch a,
[data-theme="light"] #highlights-rest .pr-watch a,
[data-theme="light"] #highlights .pr-link,
[data-theme="light"] #highlights-more .pr-link,
[data-theme="light"] #highlights-rest .pr-link {
	color: var(--blue-700); /* 5.91; 500 was 3.37, 600 only 4.46 */
}

[data-theme="light"] #highlights .pr-watch a:hover,
[data-theme="light"] #highlights-more .pr-watch a:hover,
[data-theme="light"] #highlights-rest .pr-watch a:hover,
[data-theme="light"] #highlights .pr-link:hover,
[data-theme="light"] #highlights-more .pr-link:hover,
[data-theme="light"] #highlights-rest .pr-link:hover {
	color: var(--blue-800);
}

/* Headline accents are large text, so they need 3:1 rather than 4.5:1. Blue and
   purple already clear it at 500; orange does not until 700. */

[data-theme="light"] #highlights .spot-orange,
[data-theme="light"] #highlights-more .spot-orange,
[data-theme="light"] #highlights-rest .spot-orange {
	color: var(--orange-700); /* 3.63; 500 was 2.12, 600 only 2.89 */
}

/* Plain anchors here would inherit base.css's --link, which measures 2.15
   against these surfaces. */
#hero .hero-note a {
	color: var(--blue-300);
}

/* No #hero rule in this block on purpose. #hero and #hero-visual carry
   data-theme="dark", so a [data-theme="light"] ancestor selector still matches
   inside them, but every token resolves to its dark value - which would paint
   light-theme colors on a permanently dark surface. Those sections keep their
   dark treatment in both themes. */

/* !- Buy page
 *
 * Mirrors the NoNoise AI 2027 buy treatment (the "Buy" block in
 * nonoise-ai.css) with Photo RAW's accents in place of NoNoise's: blue for the
 * Photo RAW box, purple for the Photo Studio subscription box, matching the
 * primary/subscription split already used on the overview page.
 *
 * Scoped to #photo-raw-2027-buy only where it would otherwise collide with the
 * overview page's own #buy ownership section, which shares the id but not the
 * .buy class.
 */
#buy {
	background: var(--bg-900);
	color: var(--text-400);
	padding: 5rem 0;
}

#photo-raw-2027-buy #buy {
	margin-top: -46px;
	padding: calc(5rem + 46px) 0 5rem 0;
}

#photo-raw-2027-buy #passed-video + #buy {
	margin-top: 0;
	padding-top: 5rem;
}

.buy h1 {
	font-size: var(--text-3xl);
	color: var(--text-50);
	font-weight: 700;
	line-height: 1.3;
	margin: 0 0 0.5em;
}

.buy h2 {
	line-height: 1.3;
}

.buy .eyebrow {
	margin: 0 0 1rem 0;
}

/* Gold is the pre-order urgency cue on the NoNoise page, not a product accent,
   so it carries over as gold rather than becoming blue. */
.buy .eyebrow span {
	background: var(--gold-transparent);
	border-radius: var(--border-radius);
	color: var(--gold-500);
	padding: 0.25rem 0.625rem;
}

.buy .discount-sign-in {
	color: var(--blue-300);
}

.buy .discount-sign-in i {
	font-size: 1.5rem;
	vertical-align: middle;
}

.buy .discount-sign-in a {
	color: var(--blue-300);
	text-decoration: underline;
}

.buy .discount-sign-in a:hover {
	color: var(--blue-100);
}

/* !- Buy boxes */
.buy .buy-box {
	background: linear-gradient(-40deg, color-mix(in srgb, var(--blue-500) 10%, transparent), color-mix(in srgb, var(--purple-500) 6%, transparent));
	border: 1px solid color-mix(in srgb, var(--blue-500) 30%, transparent);
	border-radius: var(--border-radius);
	height: 100%;
	overflow: hidden;
	padding: 2.25rem 1.75rem;
	position: relative;
	transition: border-color 0.2s ease;
}

.buy .buy-box::before {
	background: linear-gradient(-40deg, var(--blue-500), var(--purple-500));
	content: '';
	height: 0.25rem;
	left: 0;
	position: absolute;
	right: 0;
	top: 0;
}

.buy .buy-box:hover {
	border-color: color-mix(in srgb, var(--blue-500) 55%, transparent);
}

.buy .buy-box.buy-box-alt {
	background: linear-gradient(-40deg, color-mix(in srgb, var(--purple-500) 10%, transparent), color-mix(in srgb, var(--magenta-500) 8%, transparent));
	border: 1px solid color-mix(in srgb, var(--purple-500) 30%, transparent);
}

.buy .buy-box.buy-box-alt::before {
	background: linear-gradient(-40deg, var(--purple-500), var(--magenta-500));
}

.buy .buy-box.buy-box-alt:hover {
	border-color: color-mix(in srgb, var(--purple-500) 55%, transparent);
}

.buy .buy-box .buy-box-name {
	color: var(--text-50);
	font-size: 1.5rem;
}

.buy .buy-box .buy-box-pill {
	margin-bottom: 1rem;
}

.buy .buy-box .buy-box-pill span {
	border: 1px solid var(--bg-600);
	border-radius: 50rem;
	color: var(--text-400);
	font-size: var(--text-micro);
	font-weight: 700;
	letter-spacing: 0.08em;
	padding: 0.25rem 0.5rem;
	text-transform: uppercase;
}

.buy .buy-box .buy-box-desc {
	color: var(--text-400);
	font-size: var(--text-mini);
	line-height: 1.5;
	margin-bottom: 1.25rem;
}

.buy .buy-box .buy-box-features {
	color: var(--text-200);
	font-size: var(--text-xs);
	list-style: none;
	margin: 0 auto 0.75rem auto;
	padding-left: 0;
	text-align: start;
	width: 92%;
}

.buy .buy-box .buy-box-features li {
	align-items: baseline;
	display: flex;
	gap: 0.5rem;
	margin-bottom: 0.75rem;
}

.buy .buy-box .buy-box-features li::before {
	color: var(--blue-500);
	content: '\f00c';
	flex-shrink: 0;
	font: var(--fa-font-solid);
}

.buy .buy-box.buy-box-alt .buy-box-features li::before {
	color: var(--purple-400);
}

.buy .buy-box .buy-box-price {
	color: var(--text-50);
	font-size: 1.875rem;
	font-weight: 800;
	margin-bottom: 0.875rem;
}

.buy .buy-box .buy-box-price .fa-spin {
	color: var(--text-100);
	font-size: 1rem;
}

.buy .buy-box .buy-box-price del {
	color: var(--text-500);
	font-size: 1rem;
	font-weight: 400;
	margin-right: 0.5rem;
}

.buy .buy-box .buy-box-swap {
	margin-top: 1rem;
}

.buy .buy-box .buy-box-swap .form-check {
	align-items: center;
	cursor: pointer;
	display: inline-flex;
	gap: 0.5rem;
	margin: 0;
	padding: 0;
}

.buy .buy-box .buy-box-swap .form-check-input {
	cursor: pointer;
	flex: none;
	float: none;
	margin: 0;
}

.buy .buy-box .buy-box-swap span {
	color: var(--text-200);
	font-size: var(--text-xs);
	text-align: left;
}

.buy .buy-box .btn {
	margin-bottom: 0;
	padding: 0.75rem 1.5rem;
}

.buy .buy-section-note {
	font-size: var(--text-xs);
	line-height: 1.5;
}

.buy .buy-bottom-exp-guarantee {
	margin-top: 1.75rem;
}

/* !- Subscription upgrades */
.buy .buy-box .buy-box-details {
	padding-top: 0.5rem;
}

.buy .buy-box:not(.buy-box-alt) .buy-box-details .buy-box-price {
	margin-bottom: 0;
	padding-bottom: 0.875rem;
}

.buy .buy-box.buy-box-alt .upgrade-details {
	padding-top: 0.125rem;
}

.buy .buy-box.buy-box-alt .upgrade-details .eyebrow {
	color: var(--teal-500);
	margin-bottom: 0;
}

.buy .buy-box.buy-box-alt .upgrade-details .buy-box-price {
	margin-bottom: 0;
}

.buy .buy-box.buy-box-alt .upgrade-details .buy-box-note {
	margin-top: 0;
}

.buy .buy-box.buy-box-alt .upgrade-alert {
	background: #46267b;
	border: 1px solid #5f33a7;
	border-radius: var(--border-radius);
	color: #e6d6ff;
	margin: 1.75rem 0;
	padding: 0.75rem;
	text-align: start;
}

.buy .buy-box.buy-box-alt .upgrade-alert label {
	font-size: var(--text-xs);
}

/* !- Upgrade failure */
.buy .buy-box .upgrade-error {
	color: var(--red-500);
	font-size: var(--text-xs);
	font-weight: 600;
	margin-top: 0.75rem;
}

/* !- Tooltips */
.tooltip.buy-box-tooltip {
	--bs-tooltip-max-width: 350px;
	--bs-tooltip-padding-x: 0.75rem;
	--bs-tooltip-padding-y: 0.5rem;
}

.tooltip.buy-box-tooltip .tooltip-inner {
	text-align: start;
}

/* !- AI Culling walkthrough
   The piece has no internal scroll, so a fixed height either clips it or leaves
   dead space - and its height changes per step. It is served same-origin, so
   photo-raw.js reads the real content height off its own document and keeps it
   in sync. min-height is only the pre-JS floor so the band is not collapsed
   while the lazy iframe is still loading. */
.cull-frame {
	border: 0;
	display: block;
	min-height: 30rem;
	overflow: hidden;
	width: 100%;
}

/* !- Masking walkthrough
   The embed paints its own #1E1E1E ground and its chips and caption are coloured
   for a dark backdrop, so it is matched here rather than made transparent -
   letting the card show through would drop that copy onto --bg-700 in dark and
   near-white in light, where it does not have the contrast for it.

   min-height is only the floor before photo-raw.js measures the real content
   height; the embed reports its own, the same way the culling one does. */
.mask-frame {
	background: #1e1e1e;
	border: 0;
	border-radius: var(--border-radius);
	display: block;
	min-height: 24rem;
	overflow: hidden;
	width: 100%;
}

/* !- Brilliance AI slider */
/* Genre picker under the comparison, per the mockup. These are Bootstrap's own
   carousel indicators rather than a parallel control, so clicking one moves the
   slide and the active state is maintained for us - no custom JS, and the
   keyboard and ARIA behaviour comes along with it. Most of what follows is
   undoing Bootstrap's default indicator styling, which is built for 30x3px
   dashes pinned over the slide.

   .carousel-indicators and .row are both single-class selectors, so whichever
   Bootstrap ships last would win. The id here outranks both, which is why the
   row's own display, wrap and negative margins are restated rather than left to
   the cascade.

   No top margin on purpose: .row > * already carries margin-top: var(--bs-gutter-y),
   so the gap above the thumbs is the same 1rem as the gaps between them. Adding
   one here stacks on top of that instead of replacing it. */
#brilliance-ai .brilliance-thumbs {
	display: flex;
	flex-wrap: wrap;
	margin: 0 calc(-0.5 * var(--bs-gutter-x));
	padding: 0;
	position: static;
}

#brilliance-ai .brilliance-thumb {
	background: none;
	border: 0;
	border-radius: 0.5rem;
	box-sizing: border-box;
	cursor: pointer;
	flex: 1 1 0;
	height: auto;
	margin: 0;
	opacity: 1;
	outline: 2px solid transparent;
	outline-offset: 2px;
	overflow: hidden;
	padding: 0;
	position: relative;
	text-indent: 0;
	transition: outline-color 200ms cubic-bezier(0.4, 0, 0.2, 1), transform 200ms cubic-bezier(0.4, 0, 0.2, 1);
	width: auto;
}

#brilliance-ai .brilliance-thumb:hover {
	transform: translateY(-2px);
}

#brilliance-ai .brilliance-thumb.active {
	outline-color: var(--orange-500);
}

#brilliance-ai .brilliance-thumb:focus-visible {
	outline-color: var(--blue-500);
}

#brilliance-ai .brilliance-thumb img {
	display: block;
	height: auto;
	width: 100%;
}

/* Sits over the photo, so the scrim rather than a token keeps it legible on any
   of the four. */
#brilliance-ai .brilliance-thumb span {
	background: linear-gradient(to top, rgba(0, 0, 0, 0.8), transparent);
	bottom: 0;
	color: #fff;
	/* Matches .eyebrow, this sheet's existing small uppercase label size. */
	font-size: 0.6875rem;
	font-weight: 600;
	left: 0;
	letter-spacing: 0.08em;
	padding: 1.5rem 0.625rem 0.5rem;
	position: absolute;
	right: 0;
	text-align: left;
	text-transform: uppercase;
}

@media (prefers-reduced-motion: reduce) {
	#brilliance-ai .brilliance-thumb {
		transition: none;
	}

	#brilliance-ai .brilliance-thumb:hover {
		transform: none;
	}
}

/* The genre label reads under the comparison rather than over it, matching the
   mockup. Taking it out of Bootstrap's absolute overlay and into normal flow is
   enough: it stays inside .carousel-item, so it changes with the slide by
   itself - no JS, and the genre names keep a single source of truth. The item
   grows to contain it, so .carousel-inner's overflow never clips it. */
#brilliance-ai .carousel-caption {
	bottom: auto;
	left: auto;
	padding: 0;
	position: static;
	right: auto;
}

#brilliance-ai .carousel-caption p {
	margin: 1rem 0 0;
}

/* No pill any more - it is on the card now, not over a photo. Plain sentence
   case, matching the mockup's .compare-caption; the uppercase treatment belongs
   to the thumbnail labels, not here. */
#brilliance-ai .caption-text {
	color: var(--text-300);
	font-size: var(--text-sm);
}

/* !- RAW engine comparison (2026 vs 2027)
   From the design handoff, adapted three ways: its --res-* palette now points at
   the site tokens so the component follows the page theme instead of being
   dark-only; its section background, padding and font stack are dropped because
   .pr-card supplies those; and its intro rules are gone, since the card's own
   badge, h3 and copy are used rather than the component's duplicates.

   Gutters are the grid's (g-3), so there is no shared gap constant to keep in
   step with the JS any more. */
.res {
	--res-gold: var(--gold-500);
	--res-line: var(--bg-600);
	--res-motion: 120ms cubic-bezier(0.4, 0, 0.2, 1);
	--res-panel: var(--bg-800);
	--res-radius: calc(var(--border-radius) * 2);
	--res-radius-img: var(--border-radius);
	--res-text: var(--text-100);
	--res-text-hover: var(--text-50);
	--res-text-subtle: var(--text-500);
	--res-well: var(--bg-950);
}

.res *,
.res *::before,
.res *::after {
	box-sizing: border-box;
}

.res__stage {
	margin-top: 2.25rem;
}

/* The two columns are a plain Bootstrap row (row-cols-1 row-cols-md-2), so the
   stacking is the grid's, not the component's.

   .res__well is what locks the height: its aspect ratio is the WIDEST scene's,
   and its width is the column's, so its height is constant no matter which scene
   is showing. The frame inside then takes that height and derives its own width
   from --res-ar, so a portrait scene renders narrower instead of taller and the
   section never jumps.

   No max-height: the well fills its column, so a landscape scene's frame comes
   out exactly the column's width. min-height keeps it usable on narrow ones. */
.res__well {
	align-items: center;
	aspect-ratio: 3 / 2;
	display: flex;
	justify-content: center;
	min-height: 10rem;
	width: 100%;
}

.res__col-label {
	align-items: center;
	color: var(--res-text-subtle);
	display: flex;
	font-size: 0.6875rem;
	font-weight: 700;
	height: 1.125rem;
	letter-spacing: 0.12em;
	margin-bottom: 0.5rem;
	text-transform: uppercase;
}

.res__col--new .res__col-label {
	color: var(--res-gold);
}

.res__frame {
	aspect-ratio: var(--res-ar, 1.5);
	background: var(--res-well);
	border-radius: var(--res-radius-img);
	flex: none;
	height: 100%;
	max-width: 100%;
	overflow: hidden;
	position: relative;
	width: auto;
}

.res__frame img {
	display: block;
	height: 100%;
	inset: 0;
	object-fit: cover;
	position: absolute;
	width: 100%;
}

.res__controls {
	align-items: center;
	background: var(--res-panel);
	border-radius: var(--res-radius);
	display: grid;
	gap: 0.25rem 1rem;
	grid-template-columns: 1fr auto;
	margin: 1.25rem 0 0;
	padding: 1rem 1.125rem;
	width: 100%;
}

.res__slider-label {
	color: var(--res-text);
	cursor: default;
	font-size: var(--text-xs);
	font-weight: 700;
	user-select: none;
}

.res__value {
	color: var(--res-gold);
	font-size: var(--text-xs);
	font-variant-numeric: tabular-nums;
	font-weight: 700;
	text-align: right;
}

.res__track {
	grid-column: 1 / -1;
	height: 1.75rem;
	position: relative;
}

.res__track-bg,
.res__track-fill {
	border-radius: 2px;
	height: 4px;
	left: 0;
	pointer-events: none;
	position: absolute;
	top: 0.75rem;
}

.res__track-bg {
	background: var(--res-line);
	right: 0;
}

.res__track-fill {
	background: var(--res-gold);
	transition: width var(--res-motion);
	width: 10px;
}

.res__range {
	appearance: none;
	-webkit-appearance: none;
	background: transparent;
	cursor: pointer;
	display: block;
	height: 1.75rem;
	inset: 0;
	margin: 0;
	position: absolute;
	width: 100%;
}

.res__range::-webkit-slider-runnable-track {
	background: transparent;
	height: 4px;
}

.res__range::-moz-range-track {
	background: transparent;
	height: 4px;
}

.res__range::-webkit-slider-thumb {
	appearance: none;
	-webkit-appearance: none;
	background: var(--res-text);
	border: 0;
	border-radius: 50%;
	height: 1.25rem;
	margin-top: -8px;
	transition: background var(--res-motion);
	width: 1.25rem;
}

.res__range::-moz-range-thumb {
	background: var(--res-text);
	border: 0;
	border-radius: 50%;
	height: 1.25rem;
	width: 1.25rem;
}

/* A token rather than white: the knob is dark on a light page, so a white hover
   would disappear there. */
.res__range:hover::-webkit-slider-thumb {
	background: var(--res-text-hover);
}

.res__range:hover::-moz-range-thumb {
	background: var(--res-text-hover);
}

.res__range:focus-visible {
	border-radius: 4px;
	outline: 2px solid var(--res-gold);
	outline-offset: 4px;
}

.res__thumbs {
	display: grid;
	gap: 0.625rem;
	grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
	margin-top: 1.125rem;
}

.res__thumb {
	aspect-ratio: 16 / 9;
	background: var(--res-well);
	border: 0;
	border-radius: var(--res-radius-img);
	box-shadow: inset 0 0 0 1px var(--res-line);
	cursor: pointer;
	min-height: 3.5rem;
	min-width: 0;
	overflow: hidden;
	padding: 0;
	position: relative;
	transition: box-shadow var(--res-motion);
}

.res__thumb[aria-pressed="true"] {
	box-shadow: inset 0 0 0 2px var(--res-gold);
}

.res__thumb img {
	display: block;
	height: 100%;
	inset: 0;
	object-fit: cover;
	opacity: 0.55;
	position: absolute;
	transition: opacity var(--res-motion);
	width: 100%;
}

.res__thumb:hover img {
	opacity: 0.8;
}

.res__thumb[aria-pressed="true"] img {
	opacity: 1;
}

.res__thumb:focus-visible {
	outline: 2px solid var(--res-gold);
	outline-offset: 2px;
}

/* Sits over the photo, so the scrim keeps it legible in either theme. 11px to
   match the other picker labels on this page, not the handoff's 9px. */
.res__thumb-label {
	background: linear-gradient(to top, rgba(0, 0, 0, 0.72), rgba(0, 0, 0, 0));
	bottom: 0;
	color: #fff;
	font-size: 0.6875rem;
	left: 0;
	letter-spacing: 0.08em;
	padding: 1rem 0.5rem 0.4375rem;
	position: absolute;
	right: 0;
	text-align: left;
	text-transform: uppercase;
}

.res__caption {
	color: var(--res-text-subtle);
	font-size: var(--text-xs);
	line-height: 1.55;
	margin: 0.875rem 0 0;
	text-align: center;
	text-wrap: pretty;
}

@media (prefers-reduced-motion: reduce) {
	.res * {
		transition-duration: 0ms !important;
	}
}
