/*
 * Revia Homes - reset, typography and the things every page needs.
 *
 * Reads every value from assets/css/tokens.css. No literal colour belongs in
 * this file.
 *
 * @package Revia_Homes
 */

*,
*::before,
*::after {
	box-sizing: border-box;
}

html {
	-webkit-text-size-adjust: 100%;
	scroll-behavior: smooth;

	/*
	 * The fixed header would otherwise cover the top of whatever an anchor
	 * scrolls to. The handoff gives 96px for the front page and 100px for the
	 * sub-pages; the difference is the sub-page header's border, and one value
	 * with the larger clearance is kinder than two that have to be kept in sync.
	 */
	scroll-padding-top: var(--rh-scroll-offset);
}

body {
	margin: 0;
	background: var(--rh-paper);
	color: var(--rh-body);
	font-family: var(--rh-font-body);
	font-weight: var(--rh-w-regular);
	font-size: var(--rh-t-base);
	line-height: var(--rh-lh-p-intro);
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}

img,
svg,
video {
	max-width: 100%;
	height: auto;
	display: block;
}

h1,
h2,
h3,
h4,
p,
figure,
blockquote,
ul,
ol,
dl,
dd {
	margin: 0;
}

ul,
ol {
	padding: 0;
	list-style: none;
}

/*
 * A link takes its colour from the surface, through a token rather than
 * through a heavier selector. The weight is the point: (0,0,1) loses to every
 * component class, so a component that paints its own surface keeps its own
 * foreground automatically. See the --rh-link declaration further down.
 */
a {
	color: var(--rh-link, var(--rh-ink));
	text-decoration: none;
	transition: color var(--rh-t-header) var(--rh-ease);
}

a:hover {
	color: var(--rh-gold-text);
}

button {
	font: inherit;
	color: inherit;
	background: none;
	border: 0;
	padding: 0;
	cursor: pointer;
}

/*
 * A visible focus ring on everything interactive. The handoff's prototype
 * removed the outline and marked the gap itself (12): "Produkcioban lathato
 * fokuszgyuru kell minden interaktiv elemre." This is that ring, and it is
 * deliberately the same on light and dark - the offset carries it.
 */
:focus-visible {
	outline: 2px solid var(--rh-focus);
	outline-offset: 3px;
}

/*
 * The skip link.
 *
 * FIXED, not absolute, and that is the one interesting line. Absolute put it at
 * the top of the DOCUMENT, so on a scrolled page the browser could only show it
 * by scrolling there - measured: focusing it from 841px down pulled the whole
 * page back to 0. The link stayed usable, but a visitor tabbing backwards lost
 * their place. Fixed puts it at the top of the VIEWPORT instead: measured on the
 * same scrolled page, it lands at 0,0 and the scroll position does not move.
 */
.rh-skip {
	position: fixed;
	left: -9999px;
	top: 0;
	z-index: 100;
	background: var(--rh-ink);
	color: var(--rh-paper-warm);
	padding: 14px 22px;
	font-family: var(--rh-font-body);
	font-size: var(--rh-t-button);
	letter-spacing: var(--rh-ls-button);
	text-transform: uppercase;
}

.rh-skip:focus {
	left: 0;
	color: var(--rh-paper-warm);
}

/*
 * 🔴 THE hidden ATTRIBUTE HAS TO WIN, and without this it does not.
 *
 * Its only backing is the UA stylesheet's `[hidden] { display: none }`, and ANY
 * author rule that sets `display` on the same element beats a UA rule - it does
 * not matter that the author rule has no attribute selector in it. So an
 * element is hidden right up until someone gives its class a display.
 *
 * Measured: the before/after captions declare `display: flex`, so all four
 * rooms' captions rendered at once, three of them on top of the one that was
 * meant to show. The section came out 342px taller than the design and the
 * page said four contradictory things about the same photograph.
 *
 * !important is what normalize.css uses here, for this reason: the rule has to
 * outrank a component's own display, and specificity alone cannot promise that.
 */
[hidden] {
	display: none !important;
}

/* Screen-reader-only, the WordPress spelling so core's own markup matches. */
.screen-reader-text {
	border: 0;
	clip-path: inset(50%);
	height: 1px;
	margin: -1px;
	overflow: hidden;
	padding: 0;
	position: absolute;
	white-space: nowrap;
	width: 1px;
}

/* --------------------------------------------------------------------------
 * Layout helpers
 * ----------------------------------------------------------------------- */

.rh-wrap {
	max-width: var(--rh-max);
	margin-inline: auto;
	padding-inline: var(--rh-gutter);
}

.rh-section {
	padding-block: var(--rh-section-y);
}

/*
 * A surface declares what gold LETTERING looks like on it. See the
 * --rh-gold-text comment in assets/css/tokens.css for why this is inherited
 * rather than restated per component: on sand the tile eyebrow, the progress
 * figure and a plain link on hover all measured 4.28:1, and the last of those
 * has no class name to write a rule against.
 *
 * .rh-on-dark does not paint a background - it is what an element wears when
 * the dark surface is behind it (a photograph, the footer's own fill) - but it
 * carries the same declaration, because the question it answers is "what is
 * behind this text", not "what did this element paint".
 */
/*
 * A surface that paints must declare THE WHOLE FOREGROUND SET, not just the
 * gold one, and it must do so even when the value it declares is the page
 * default. The default is only the default until something ABOVE the surface
 * changes it, and nesting is exactly that case.
 *
 * The set is six: `color` for plain inherited text, --rh-link for every <a>,
 * and the four text steps a component can ask for by name - --rh-gold-text,
 * --rh-strong-text, --rh-body-text, --rh-muted-text. It used to be three,
 * and the last three arrived on 2026-09-15 with the same argument the first
 * three had: a component that does not paint cannot know what is behind it.
 *
 * Measured before this block existed, a .rh-section--sand nested in a
 * .rh-section--ink: a plain <a> came out #F7F5F2 on #F2F0ED - 1.05:1 - and
 * plain body text #B9BDC1 on #F2F0ED, 1.66:1. Both inherited from the ink
 * section, which declares them, over a surface that repaints the background
 * but took neither back. The gold WAS correct (5.72), because --rh-gold-text
 * is the one token the sand rule already restated. That contrast is the whole
 * lesson: the token that was declared came back, the two that were not did
 * not.
 *
 * There is no such section nesting in the theme today - phase 4's home page,
 * with its alternating pale / sand / ink bands, is where a sand card inside an
 * ink band becomes the most ordinary thing on the page.
 */
.rh-section--sand {
	background: var(--rh-sand);

	color: var(--rh-body);

	--rh-link: var(--rh-ink);
	--rh-gold-text: var(--rh-gold-hover);

	/*
	 * Sand is a light surface, and it is still not light enough for the quiet
	 * grey: --rh-muted is 5.00:1 on white and 4.40:1 here, below AA. It steps
	 * down to the body colour - there is no grey in between, and the reasoning
	 * for not inventing one is at --rh-muted-text in tokens.css.
	 *
	 * Nothing renders differently today: all five readers of the token stand
	 * on white cards. The first sand section that carries a .rh-facts label,
	 * a price note or a progress head is phase 4's, and it would have gone
	 * quietly under the threshold.
	 */
	--rh-muted-text: var(--rh-body);

	/*
	 * The other two steps are restated at their LIGHT values, and they have to
	 * be, for the same reason `color` and --rh-link are: sand is a light
	 * surface that can be nested in a dark one. Measured with this pair
	 * missing, a sand section inside an ink section: a .rh-tile__title came
	 * out --rh-paper-warm on --rh-sand, 1.16:1.
	 */
	--rh-strong-text: var(--rh-ink);
	--rh-body-text: var(--rh-body);
}

.rh-section--ink {
	background: var(--rh-ink);
	color: var(--rh-body-dark);

	--rh-gold-text: var(--rh-gold-light);
	--rh-strong-text: var(--rh-paper-warm);
	--rh-body-text: var(--rh-body-dark);
	--rh-muted-text: var(--rh-muted-dark);
}

.rh-on-dark {
	--rh-gold-text: var(--rh-gold-light);
	--rh-strong-text: var(--rh-paper-warm);
	--rh-body-text: var(--rh-body-dark);
	--rh-muted-text: var(--rh-muted-dark);
}

/*
 * Dark surfaces invert the link pair rather than restating it per component
 * (handoff 5.3) - and they do it by INHERITANCE, not by out-weighing the
 * components. The rule that matters is two lines up: `a` reads --rh-link and
 * weighs (0,0,1), so ANY component that sets its own colour from a class -
 * (0,1,0) - keeps it, on every surface, with nothing to remember.
 *
 * This used to be `.rh-on-dark a:not(:where(.rh-btn))` at (0,1,1), and the
 * :not() was load-bearing: without it a .rh-btn--paper inside .rh-on-dark was
 * --rh-paper-warm on white, 1.09:1 - invisible - and the :hover pair made it
 * --rh-gold-light on --rh-gold-ink, 2.01:1, so it never became readable at
 * all. The gold button lost its own white too, 4.87 -> 4.47, below AA.
 *
 * The :not() fixed those, but it asked the wrong question. It asked "does this
 * carry the class .rh-btn", when the thing that actually matters is "does this
 * paint its own surface". Measured on the (0,1,1) version: a new <a> with its
 * own pale background and no .rh-btn came out at 1.09:1 - the original fault,
 * reproduced exactly - and with its own gold background, 4.47. A <span> in the
 * same place was fine. So the old rule was safe only for components someone
 * had remembered to name, and phase 4 is where the new components arrive.
 *
 * CSS cannot ask "does this element paint a background". What it can do is
 * stop out-weighing the answer: a component that paints its own surface must
 * set its own colour anyway, and a class beats a bare element selector without
 * anyone deciding anything. Measured after the move: the same two cases are
 * 15.04 and 4.87, and all five .rh-btn variants are unchanged at rest and on a
 * real hover.
 *
 * One thing the old form could not do and this one can: a surface can take it
 * back. A pale card inside a dark section sets --rh-link to the dark ink and
 * its links are correct again; under the :not() version there was no way to
 * say that short of another selector at (0,1,1) or heavier.
 */
.rh-section--ink,
.rh-on-dark {
	--rh-link: var(--rh-paper-warm);
}

/*
 * The fixed header needs its height back on pages without a photo hero.
 * front-page.php leaves it out; everything else prints it.
 */
.rh-header-spacer {
	height: var(--rh-header-h);
}

/* --------------------------------------------------------------------------
 * Entrance animation
 *
 * The element starts shifted and transparent and is released by
 * IntersectionObserver (assets/js/site.js). The .rh-js gate matters: without
 * JavaScript nothing would ever add .rh-is-in, and every animated section would
 * stay invisible. So the starting state only applies when the script is there
 * to finish the job.
 * ----------------------------------------------------------------------- */

.rh-js .rh-enter {
	opacity: 0;
	transform: translateY(var(--rh-enter-shift));
	transition:
		opacity var(--rh-enter-duration) var(--rh-enter-ease),
		transform var(--rh-enter-duration) var(--rh-enter-ease);
	transition-delay: var(--rh-enter-delay, 0ms);
}

.rh-js .rh-enter.rh-is-in {
	opacity: 1;
	transform: none;
}

@media (prefers-reduced-motion: reduce) {

	html {
		scroll-behavior: auto;
	}

	*,
	*::before,
	*::after {
		animation-duration: .01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: .01ms !important;
		transition-delay: 0ms !important;
		scroll-behavior: auto !important;
	}

	/*
	 * Not just "instant" - the starting state has to go, or a reader who never
	 * triggers the observer (reduced motion often travels with other assistive
	 * settings) would be left looking at a shifted, invisible section.
	 */
	.rh-js .rh-enter {
		opacity: 1;
		transform: none;
	}
}

/*
 * The wordmark.
 *
 * overflow: visible is the handoff's own setting on this SVG. The viewBox has
 * enough padding for the 11-unit stroke and its square caps today, so nothing is
 * clipped without it - but the letters are drawings, and the next time one of
 * them is adjusted the clipping would show up as a hairline shaved off a stem
 * rather than as an error.
 */
.rh-wordmark {
	display: block;
	width: 100%;
	height: auto;
	overflow: visible;
}

/*
 * The phase-2 raw verification views.
 *
 * They print bare <h1>, <dl>, <ul> and <hr> straight into <main>, and used to
 * live off the browser's default 8px body margin - which body { margin: 0 }
 * above has just taken away. Without this they run into the edge of the window,
 * and they are still the tool for checking the phase-2 data.
 *
 * Deliberately narrow: only DIRECT children of <main>, only the bare tags those
 * views use, and only a CLASSLESS <article> - which is what raw-single.php
 * prints and what nothing in phases 4-5 will. A <section>, a <div> or any
 * article with a class is untouched, so the hero can still be edge to edge.
 * Phases 4-5 delete the raw views, and this rule goes with them.
 */
#rh-content > h1,
#rh-content > h2,
#rh-content > h3,
#rh-content > p,
#rh-content > ul,
#rh-content > ol,
#rh-content > dl,
#rh-content > hr,
#rh-content > table,
#rh-content > small,
#rh-content > pre,
#rh-content > article:not([class]) {
	max-width: var(--rh-max);
	margin-inline: auto;
	padding-inline: var(--rh-gutter);
}
