/*
 * R&R Project Services — theme.css
 *
 * Intentionally minimal. All visual design is handled in Elementor.
 *
 * IMPORTANT (Elementor v4 / Atomic CSS): do NOT add broad resets here.
 * Avoid selectors like *, html, body, div, section, ul, li, a, button or
 * form elements, and never use `all: reset` or global box-sizing overrides.
 * Such rules conflict with Elementor's scoped, atomic CSS output. Keep any
 * rules narrowly scoped to this theme's own classes (e.g. .site-main) only.
 *
 * Performance note: this file must stay tiny — it loads on every page. Any
 * substantial styling belongs in Elementor (which generates per-page CSS),
 * not here.
 *
 * Contents:
 *   0. Design tokens (colours, gradient, radii, font stack) from the Figma
 *      design system — consumed by every component stylesheet.
 *   1. Skip-to-content accessibility utility.
 *   2. Hero LCP <img> support (see rrps_home_hero_inject in inc/performance.php).
 *   3. Brand font stack spliced into Elementor's global font variables.
 */

/* 0. Design tokens (Figma: RRQS → variables). */
:root {
	--rrps-navy: #0e2b47;        /* 01 */
	--rrps-blue: #1e4b67;        /* 02 */
	--rrps-teal-dark: #2f6f7f;   /* 03 */
	--rrps-teal: #4fa0ab;        /* 04 */
	--rrps-teal-light: #77c4cf;  /* 05 */
	--rrps-ice: #effdff;         /* Light Blue */
	--rrps-gray-50: #f5f6f6;
	--rrps-gray-100: #e5e7e8;
	--rrps-gray-200: #ced0d3;
	--rrps-gray-300: #acafb4;
	--rrps-gray-400: #82868e;
	--rrps-gray-500: #676b73;
	--rrps-gray-800: #424348;
	--rrps-gray-900: #3a3b3f;
	--rrps-gray-950: #242528;
	--rrps-gradient: linear-gradient(-57deg, #77c3ce 0%, #4f9fab 18.8%, #2e6f7f 35%, #1e4b67 68.4%, #0e2b47 85.5%);
	--rrps-gradient-bar: linear-gradient(90deg, #0e2b47 0%, #1e4b67 20%, #2e6f7f 59%, #4f9fab 78%, #77c3ce 100%);
	--rrps-radius-card: 16px;
	--rrps-radius-btn: 12px;
	--rrps-font: "Montserrat", "Montserrat Fallback", Arial, "Helvetica Neue", Helvetica, sans-serif;
}

/*
 * Base typeface. The one intentional element rule in this file: Elementor's
 * kit CSS sets the body font on Elementor-built pages, but native templates
 * (search, 404 fallback, plain pages) would otherwise fall back to the
 * browser default. Same specificity as Elementor's rule, which loads later
 * and therefore wins — so the kit stays the source of truth where present.
 */
body {
	margin: 0; /* browser default is 8px; neither Elementor nor this theme's reset-free CSS removes it */
	font-family: var(--rrps-font);
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}

/* 1. Visually hidden, but available to screen readers and keyboard users. */
.screen-reader-text {
	border: 0;
	clip: rect(1px, 1px, 1px, 1px);
	clip-path: inset(50%);
	height: 1px;
	width: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	position: absolute !important;
	word-wrap: normal !important;
}

/* Reveal the skip link when it receives keyboard focus. */
.skip-link.screen-reader-text:focus {
	clip: auto;
	clip-path: none;
	height: auto;
	width: auto;
	margin: 0;
	padding: 16px 24px;
	position: fixed !important;
	top: 8px;
	left: 8px;
	z-index: 100000;
	display: block;
	background: #fff;
	color: #111;
	font-size: 14px;
	line-height: 1;
	text-decoration: underline;
}

/*
 * 2. Mobile hero LCP image. When `rrps_home_hero_slides` is populated, the
 * mobile hero image is injected as a real <img> (see inc/performance.php) so
 * the browser paints it as soon as it decodes rather than after layout
 * settles. It fills the hero container behind the content; Elementor's
 * slideshow layer (built on interaction) sits over it showing the identical
 * first image. The container itself must be `position: relative` — add the
 * hero container's element-id class alongside the rule below when wiring it up.
 */
.rrps-hero-img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	z-index: 0;
	pointer-events: none;
}

/*
 * 3. Font-swap (FOUT) guard.
 *
 * Montserrat is self-hosted and preloaded (inc/fonts.php) with a
 * metric-matched "Montserrat Fallback" face, so a late font never moves
 * text. Elementor's global typography is set to Montserrat; these overrides
 * splice the fallback into its generated font stacks. `!important` wins on
 * the custom-property definition regardless of source order.
 */
:root {
	--e-global-typography-primary-font-family: var(--rrps-font) !important;
	--e-global-typography-secondary-font-family: var(--rrps-font) !important;
	--e-global-typography-text-font-family: var(--rrps-font) !important;
	--e-global-typography-accent-font-family: var(--rrps-font) !important;
}

/*
 * 4. Elementor Global Class companions.
 *
 * The home page (and future pages) are built with Elementor v4 Global
 * Classes named rrps-heading-light / rrps-heading-dark / rrps-btn-primary /
 * rrps-btn-outline. Global Classes cannot express descendant selectors,
 * pseudo-elements or hover states, so those live here, keyed to the same
 * class names. Two-tone headings: the accent phrase is wrapped in <em>.
 */
.rrps-heading-light em,
.rrps-heading-dark em {
	font-style: normal;
}

.rrps-heading-light em {
	color: var(--rrps-navy);
}

.rrps-heading-dark em {
	color: var(--rrps-ice);
}

/* Doubled class selectors (0,2,0 / 0,3,0) so these beat the Elementor kit's
   global `.elementor-kit-N a` and `a:hover` link colours (0,1,1 / 0,2,1). */
.rrps-btn-primary.rrps-btn-primary,
.rrps-btn-outline.rrps-btn-outline {
	transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}

.rrps-btn-primary.rrps-btn-primary {
	color: #fff;
}

.rrps-btn-outline.rrps-btn-outline {
	color: var(--rrps-blue);
}

.rrps-btn-primary.rrps-btn-primary:hover,
.rrps-btn-primary.rrps-btn-primary:focus-visible {
	background-color: var(--rrps-blue);
	color: #fff;
}

.rrps-btn-outline.rrps-btn-outline:hover,
.rrps-btn-outline.rrps-btn-outline:focus-visible {
	background-color: var(--rrps-ice);
	color: var(--rrps-navy);
}

.rrps-btn-primary:focus-visible,
.rrps-btn-outline:focus-visible {
	outline: 2px solid var(--rrps-teal-light);
	outline-offset: 2px;
}

/* Trailing arrow-up-right icon (Lucide), drawn with a mask so it takes the
   button's text colour. */
.rrps-btn-primary::after,
.rrps-btn-outline::after {
	content: "";
	flex: 0 0 auto;
	width: 20px;
	height: 20px;
	background-color: currentColor;
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M7 7h10v10'/%3E%3Cpath d='M7 17 17 7'/%3E%3C/svg%3E") center / contain no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M7 7h10v10'/%3E%3Cpath d='M7 17 17 7'/%3E%3C/svg%3E") center / contain no-repeat;
	transition: transform 0.2s ease;
}

.rrps-btn-primary:hover::after,
.rrps-btn-outline:hover::after {
	transform: translate(1px, -1px);
}

@media (prefers-reduced-motion: reduce) {
	.rrps-btn-primary,
	.rrps-btn-outline,
	.rrps-btn-primary::after,
	.rrps-btn-outline::after {
		transition: none;
	}

	.rrps-btn-primary:hover::after,
	.rrps-btn-outline:hover::after {
		transform: none;
	}
}

/*
 * 5. Site footer (Elementor Pro Theme Builder template, CSS ID "site-footer").
 * The newsletter form's consent text contains a link that Elementor's form
 * widget cannot colour independently; keep it legible on the navy footer.
 */
#site-footer .elementor-field-type-acceptance a {
	color: var(--rrps-ice);
	text-decoration: underline;
	text-underline-offset: 2px;
}

#site-footer .elementor-field-type-acceptance a:hover {
	color: #fff;
}

/* Office addresses, phone numbers and emails (footer offices and Contact Us office cards) are real
   links (Google Maps, tel:, mailto:) that read as plain text until hovered. The ID / doubled class
   selectors beat the Elementor kit's global link colours (.elementor-kit-N a / a:hover). */
#site-footer .e-paragraph-base[class*="s-office-"] a,
.e-paragraph-base.e-paragraph-base[class*="s-contact-office-"] a {
	color: inherit;
	font-weight: inherit;
	text-decoration: none;
	text-underline-offset: 3px;
	transition: color 0.2s ease;
}

#site-footer .e-paragraph-base[class*="s-office-"] a:hover,
#site-footer .e-paragraph-base[class*="s-office-"] a:focus-visible {
	color: #fff;
	text-decoration: underline;
}

.e-paragraph-base.e-paragraph-base[class*="s-contact-office-"] a:hover,
.e-paragraph-base.e-paragraph-base[class*="s-contact-office-"] a:focus-visible {
	color: var(--rrps-teal-dark);
	text-decoration: underline;
}

/* Newsletter Subscribe (glass button set in the footer templates): Elementor only defines a hover text colour. */
#site-footer .elementor-field-type-submit .elementor-button[type="submit"] {
	transition: background-color 0.2s ease, border-color 0.2s ease;
}

#site-footer .elementor-field-type-submit .elementor-button[type="submit"]:hover,
#site-footer .elementor-field-type-submit .elementor-button[type="submit"]:focus-visible {
	border-color: rgba(255, 255, 255, 0.5);
	background-color: rgba(255, 255, 255, 0.22);
}

/* "Made with ... by Digital Fold" credit: the link carries inline colour/decoration styles. */
#site-footer a[href*="digitalfold.co.za"] {
	transition: color 0.2s ease;
}

#site-footer a[href*="digitalfold.co.za"]:hover,
#site-footer a[href*="digitalfold.co.za"]:focus-visible {
	color: var(--rrps-teal-light) !important;
	text-decoration: underline !important;
	text-underline-offset: 2px;
}

/* [rrps_icon] wrapper: inline, sized by the SVG, inherits colour. */
.rrps-icon {
	display: inline-flex;
	flex: 0 0 auto;
	vertical-align: middle;
	line-height: 0;
}

/* ---- Legal pages (Privacy Policy / Terms): Elementor Text Editor inside #legal-content ---- */
#legal-content {
	font-size: 16px;
	line-height: 1.5;
	color: var(--rrps-gray-950);
}

#legal-content h2 {
	margin: 48px 0 24px;
	font-size: 40px;
	font-weight: 700;
	line-height: 1.2;
	color: var(--rrps-teal-dark);
}

#legal-content h3 {
	margin: 32px 0 16px;
	font-size: 24px;
	font-weight: 600;
	line-height: 1.4;
	color: var(--rrps-navy);
}

#legal-content h2:first-child,
#legal-content h3:first-child,
#legal-content .elementor-widget-container > h2:first-child {
	margin-top: 0;
}

#legal-content p,
#legal-content ul,
#legal-content ol {
	margin: 0 0 24px;
}

#legal-content p:last-child {
	margin-bottom: 0;
}

#legal-content a {
	color: var(--rrps-teal-dark);
}

/* Tablet and mobile (Figma Privacy Policy tablet 2955-11354, mobile 3016-12806): compact
 * headings; body copy steps down to 14px like the article body. */
@media (max-width: 1024px) {
	/* The Text Editor widget carries the kit's 16px, so size it and its copy directly. */
	#legal-content,
	#legal-content .elementor-widget-text-editor,
	#legal-content p,
	#legal-content li {
		font-size: 14px;
	}

	#legal-content h2 {
		margin: 40px 0 16px;
		font-size: 26px;
	}

	#legal-content h3 {
		margin: 24px 0 12px;
		font-size: 20px;
	}

	#legal-content p,
	#legal-content ul,
	#legal-content ol {
		margin-bottom: 20px;
	}
}

@media (max-width: 767px) {
	#legal-content h2 {
		margin-top: 32px;
	}
}

/* ---- Contact form: phones ----
 * Name and email rows stay two-up (Figma mobile 3016-12950), so the inputs drop
 * their inner side padding to line up with their labels and keep placeholders
 * from being cut off. */
@media (max-width: 767px) {
	.s-contact-form-card .elementor-form .elementor-field-group .elementor-field-textual {
		padding-inline: 0;
	}
}

/* ---- Home hero: soft light wash behind the copy so it reads over the photo ---- */
/*
 * Header: sticks to the top, hides while scrolling down and slides back in on
 * scroll up (see theme.js). Elementor sets position: sticky on the header
 * itself, but its theme-builder wrapper is only as tall as the header, so the
 * header scrolled away with it: the wrapper is what has to stick.
 */
.elementor-location-header {
	position: sticky;
	top: 0;
	z-index: 100;
}

#site-header {
	transition: transform 0.32s cubic-bezier(0.22, 1, 0.36, 1), box-shadow 0.32s ease;
	will-change: transform;
}

#site-header.is-stuck {
	box-shadow: 0 8px 24px rgba(14, 43, 71, 0.08);
}

#site-header.is-hidden {
	transform: translateY(-100%);
	box-shadow: none;
}

@media (prefers-reduced-motion: reduce) {
	#site-header {
		transition: none;
	}
}

/* ---- Footer: tablet and mobile ----
 * The nav-menu and form widgets inside the footer carry no stable classes of
 * their own, so they are reached through their atomic parent containers
 * (.s-footer-quick, .s-footer-newsletter, .s-footer-legal). Selectors repeat
 * the widget's own classes so they outrank Elementor Pro's column-width and
 * button-alignment rules. */
@media (min-width: 768px) and (max-width: 1024px) {
	/* Quick links in two columns of four. */
	.s-footer-quick .elementor-nav-menu--main .elementor-nav-menu {
		display: grid;
		grid-auto-flow: column;
		grid-template-rows: repeat(4, auto);
		column-gap: 24px;
	}

	/* Newsletter on one row (first name, last name, email, Subscribe), consent below. */
	.s-footer-newsletter .elementor-form-fields-wrapper {
		align-items: flex-end;
	}

	.s-footer-newsletter .elementor-form-fields-wrapper .elementor-field-group.elementor-column:not(.elementor-field-type-submit):not(.elementor-field-type-acceptance) {
		flex: 1 1 0;
		width: auto;
		max-width: none;
	}

	.s-footer-newsletter .elementor-form-fields-wrapper .elementor-field-group.elementor-column.elementor-field-type-submit {
		flex: 0 0 auto;
		width: auto;
		max-width: none;
	}

	.s-footer-newsletter .elementor-form-fields-wrapper .elementor-field-group.elementor-column.elementor-field-type-acceptance {
		order: 10;
	}
}

@media (max-width: 767px) {
	/* First and last name share a row; email below. */
	.s-footer-newsletter .elementor-form-fields-wrapper .elementor-field-group.elementor-column.elementor-field-group-first_name,
	.s-footer-newsletter .elementor-form-fields-wrapper .elementor-field-group.elementor-column.elementor-field-group-last_name {
		flex: 1 1 0;
		width: auto;
		max-width: none;
	}

	/* Subscribe centred under the consent line. */
	.s-footer-newsletter .elementor-form-fields-wrapper .elementor-field-group.elementor-column.elementor-field-type-submit {
		justify-content: center;
	}

	.s-footer-newsletter .elementor-field-type-submit .elementor-button {
		width: auto;
		flex: 0 0 auto;
	}

	/* Legal links spread across the row above the copyright line. */
	.s-footer-legal .elementor-widget.elementor-widget-nav-menu,
	.s-footer-legal .elementor-nav-menu--main,
	.s-footer-legal .elementor-nav-menu--main .elementor-nav-menu {
		width: 100%;
	}

	.s-footer-legal .elementor-nav-menu--main .elementor-nav-menu {
		justify-content: space-around;
	}
}

/*
 * Home testimonials: when no testimonial is published the shortcode renders
 * nothing (and never enqueues testimonials.css), so this lives here to hide
 * the whole Elementor section (#testimonials / .s-testimonials), heading
 * included, instead of leaving an empty band.
 */
#testimonials:not(:has(.rrps-testimonials__card)),
.s-testimonials:not(:has(.rrps-testimonials__card)) {
	display: none;
}

/*
 * Home "What We Do": the two decorative layers in the top-right corner are
 * Elementor global classes (.s-services-decor-vector / -mask) set to a fixed
 * 1138px from 65.49% in, so on viewports wider than about 3300px (or a zoomed-
 * out browser) they stop short of the section's right edge. Let the box grow
 * to the edge and scale the artwork to fill it.
 */
.elementor .s-services .s-services-decor-vector,
.elementor .s-services .s-services-decor-mask {
	width: max(1138px, 34.51%);
	background-size: cover;
}

/*
 * Section anchors (/#services, /#industries): keep the target clear of the
 * sticky header on native fragment jumps. --rrps-header-h is kept current by
 * theme.js; the fallback is the desktop header height.
 */
html {
	scroll-padding-top: var(--rrps-header-h, 81px);
}

/*
 * Home news band on phones: "View All News" moves below the article slider.
 * The Elementor header row (.s-news-header) holds the eyebrow+title block
 * and the button; on phones the row dissolves into the section's column so
 * the button can be ordered after the grid.
 */
@media (max-width: 767px) {
	.elementor .s-news-in > .s-news-header {
		display: contents;
	}

	.elementor .s-news-in > .s-news-header > .rrps-btn-primary {
		order: 2;
	}

	.elementor .s-news-in > .s-news-grid {
		order: 1;
	}
}

/*
 * Footer CTA band on phones: the mobile decor layers are Elementor global
 * classes (.s-footer-cta-decor-lines / -watermark) whose mobile rules set
 * opacity 5% / 4% on SVGs that already bake in the same opacity, so the
 * patterns rendered at a fraction of a percent and looked missing. The SVGs
 * carry the Figma opacity; the box is fully opaque. They also sit on the
 * bottom edge as in the design instead of at fixed top offsets that only
 * matched the Figma frame height.
 */
@media (max-width: 767px) {
	.elementor .s-footer-cta .s-footer-cta-decor-lines {
		opacity: 1;
		inset-block-start: auto;
		inset-block-end: -10px;
		inset-inline-start: auto;
		inset-inline-end: -150px;
	}

	.elementor .s-footer-cta .s-footer-cta-decor-watermark {
		opacity: 1;
		inset-block-start: auto;
		inset-block-end: 0;
	}
}
