/*
Theme Name: Caro Alberts
Theme URI: https://caroalberts.com
Description: Child theme of Hello Elementor for caroalberts.com. Holds the design tokens, type scale and interaction CSS that Elementor Free cannot express (no Custom CSS panel on the free tier). Page layout itself lives in Elementor.
Author: Caro Alberts
Template: hello-elementor
Version: 1.1.0
Text Domain: caro-alberts
*/

/* ==========================================================================
   Design tokens

   Every colour is sampled from the CARO ALBERTS wordmark, so the site and the
   logo are the same brand rather than two that happen to share a page. The
   chunky retro mark carries the personality; the layout and type stay quiet so
   the food photography does the talking.

   Mirrored in bin/lib/elementor.php and the Elementor global kit.
   ========================================================================== */

:root {
	--ca-cream: #f2e5dc; /* page ground — matches the wordmark artwork exactly */
	--ca-paper: #fbf4ef; /* lifted cream, for alternating bands */
	--ca-cocoa: #4a3122; /* ink: headings, nav, wordmark brown */
	--ca-cocoa-deep: #2e1d12; /* dark bands */
	--ca-body: #6e594b; /* body copy — 5.3:1 on cream */
	--ca-red: #b02420; /* primary accent — 6.9:1 on cream */
	--ca-pink: #e4a6b4; /* decorative; and eyebrows on dark grounds */
	--ca-blue: #8fb6da; /* decorative */
	--ca-line: #e0cfc2; /* hairlines */

	--ca-ease: cubic-bezier(0.22, 0.61, 0.36, 1);
	--ca-slow: 0.7s;
}

/* ==========================================================================
   Layout shell

   Every section is a full-width band holding one shell that carries the measure
   and the gutter. The measure lives here rather than in Elementor because a
   full-width Elementor container has no max-width control — it emits `--width`
   and drops anything else.
   ========================================================================== */

.ca-shell {
	width: 100%;
	max-width: var(--ca-shell, 1280px);
	margin-inline: auto;
}

.ca-shell--wide {
	--ca-shell: 1480px;
}

.ca-shell--narrow {
	--ca-shell: 1100px;
}

/* ==========================================================================
   Base
   ========================================================================== */

body {
	background-color: var(--ca-cream);
	color: var(--ca-body);
	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
}

::selection {
	background: var(--ca-red);
	color: var(--ca-cream);
}

img {
	/* Stops the 1px sub-pixel seam between stacked full-bleed images. */
	vertical-align: middle;
}

/* Respect the reduced-motion preference for every reveal and hover below. */
@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
		scroll-behavior: auto !important;
	}
}

/* ==========================================================================
   Typography refinements
   Elementor sets family/size/weight; these are the details it cannot.
   ========================================================================== */

h1,
h2,
h3,
.ca-display {
	text-wrap: balance;
	font-optical-sizing: auto;
}

.ca-prose p {
	max-width: 62ch;
}

.ca-prose p + p {
	margin-top: 1.35em;
}

/* Lead paragraph — the one under a page title. */
.ca-lead p {
	font-size: clamp(1.125rem, 1.6vw, 1.375rem);
	line-height: 1.6;
	color: var(--ca-cocoa);
	max-width: 46ch;
}

/* Eyebrow / label. Section kickers and project meta keys. */
.ca-eyebrow,
.ca-eyebrow p {
	font-family: "DM Sans", system-ui, sans-serif;
	font-size: 0.6875rem;
	font-weight: 500;
	letter-spacing: 0.2em;
	text-transform: uppercase;
	color: var(--ca-red);
	margin: 0;
}

/* A small round dot before each section kicker, cycling the wordmark's colours.
   The one deliberately playful detail borrowed from the logo.

   Hung off `ca-eyebrow--kicker`, which only ca_eyebrow() emits, so it applies at
   any nesting depth while tile captions and meta labels — which reuse the same
   type style — stay dotless. It goes on the inner <p>, not the Elementor widget
   wrapper, or it would sit on its own line above the text. */
.ca-eyebrow--kicker p::before {
	content: "";
	display: inline-block;
	width: 0.5em;
	height: 0.5em;
	margin-right: 0.85em;
	border-radius: 50%;
	background: currentColor;
	vertical-align: 0.08em;
}

.ca-section:nth-of-type(3n) .ca-eyebrow--kicker p::before {
	background: var(--ca-blue);
}

.ca-section:nth-of-type(3n + 2) .ca-eyebrow--kicker p::before {
	background: var(--ca-pink);
}


/* Big numeral down the left of the services list. A fixed min-width keeps the
   titles in a straight column — Fraunces has no tabular figures, so 01 and 02
   are not the same width. */
.ca-numeral {
	flex: 0 0 auto;
	min-width: 5rem;
	font-family: Fraunces, Georgia, serif;
	font-size: clamp(2.5rem, 5vw, 4rem);
	line-height: 0.9;
	color: var(--ca-line);
	font-variant-numeric: lining-nums;
	transition: color 0.5s var(--ca-ease);
}

.ca-service:hover .ca-numeral {
	color: var(--ca-pink);
}

/* ==========================================================================
   Links
   ========================================================================== */

.ca-prose a,
.ca-link {
	color: var(--ca-cocoa);
	text-decoration: none;
	background-image: linear-gradient(var(--ca-red), var(--ca-red));
	background-repeat: no-repeat;
	background-position: 0 100%;
	background-size: 100% 1px;
	transition: background-size var(--ca-slow) var(--ca-ease), color 0.3s var(--ca-ease);
}

.ca-prose a:hover,
.ca-link:hover {
	color: var(--ca-red);
	background-size: 100% 2px;
}

/* ==========================================================================
   Header
   ========================================================================== */

.ca-header {
	position: sticky;
	top: 0;
	z-index: 100;
	backdrop-filter: saturate(1.35) blur(12px);
	background-color: color-mix(in srgb, var(--ca-cream) 88%, transparent);
	border-bottom: 1px solid transparent;
	transition: border-color 0.4s var(--ca-ease), padding 0.4s var(--ca-ease);
}

@supports not (background-color: color-mix(in srgb, red 50%, transparent)) {
	.ca-header {
		background-color: rgba(242, 229, 220, 0.93);
	}
}

.ca-header.is-scrolled {
	border-bottom-color: var(--ca-line);
}

/* Elementor gives direct widget children of a row container an equal flex basis
   and sets `--flex-wrap-mobile: wrap`, which splits the header 50/50 and drops
   the nav — or the burger — onto a second line. The wordmark should take only
   the space it needs and the nav the rest, at every width. */
.ca-header {
	flex-wrap: nowrap;
}

.ca-header > .elementor-widget-image {
	flex: 0 0 auto;
}

.ca-header > .elementor-widget-navigation-menu {
	flex: 1 1 auto;
	min-width: 0;
}

@media (min-width: 1025px) {
	.ca-nav .hfe-nav-menu {
		flex-wrap: nowrap;
	}
}

/* Burger sits hard right and vertically centred with the wordmark. */
.ca-nav .hfe-nav-menu__toggle {
	margin-left: auto;
}

/* Wordmark: the supplied artwork, keyed to transparency by
   bin/make-logo-assets.py so it sits on the cream without a visible box. */
.ca-wordmark img {
	display: block;
	width: clamp(132px, 15vw, 188px);
	height: auto;
	transition: transform 0.5s var(--ca-ease);
}

.ca-wordmark a:hover img {
	transform: rotate(-1.2deg) scale(1.02);
}

/* Nav: letter-spaced caps with a hairline that grows from the left. */
.ca-nav .menu-item > a {
	position: relative;
	font-family: "DM Sans", system-ui, sans-serif;
	font-size: 0.75rem;
	font-weight: 500;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--ca-cocoa);
	padding: 0.5rem 0;
	text-decoration: none;
}

.ca-nav .menu-item > a::after {
	content: "";
	position: absolute;
	left: 0;
	bottom: 0;
	width: 100%;
	height: 1px;
	background: var(--ca-red);
	transform: scaleX(0);
	transform-origin: left;
	transition: transform 0.45s var(--ca-ease);
}

.ca-nav .menu-item > a:hover::after,
.ca-nav .current-menu-item > a::after,
.ca-nav .current_page_parent > a::after {
	transform: scaleX(1);
}

.ca-nav .current-menu-item > a,
.ca-nav .current_page_parent > a {
	color: var(--ca-red);
}

/* Mobile flyout. */
.ca-nav .elementor-nav-menu--dropdown {
	background-color: var(--ca-cream);
}

.ca-nav .elementor-nav-menu--dropdown a {
	color: var(--ca-cocoa) !important;
	font-family: "DM Sans", system-ui, sans-serif;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	font-size: 0.8125rem;
}

/* ==========================================================================
   Photo hero — full-bleed photograph, title on a solid cream card

   The card, rather than a gradient scrim, is what makes the overlay legible.
   A scrim dark enough for cream type over the high-key frames in this set needs
   about 70% opacity, which flattens the airy quality those shots were
   commissioned for. An opaque card leaves every photograph untouched and pins
   the type at 9:1 — cocoa on cream, the same pairing as the header.
   ========================================================================== */

.ca-hero {
	position: relative;
	/* Deliberately not `overflow: hidden` — the card bleeds past the bottom edge
	   on purpose, and a z-index keeps it above the section that follows. */
	z-index: 2;
}

/* A whisper of a gradient — not for contrast, just to seat the card against the
   photograph and stop a bright bottom edge fighting it. */
.ca-hero::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background: linear-gradient(to top, rgba(46, 29, 18, 0.22), rgba(46, 29, 18, 0) 45%);
	pointer-events: none;
}

/* The card sits on the bottom edge and bleeds into the section below it — a
   magazine device that ties the photograph to the page rather than floating on
   top of it. */
.ca-hero-shell {
	width: 100%;
	max-width: 1280px;
	margin-inline: auto;
}

.ca-hero-card {
	position: relative;
	z-index: 3;
	width: 100%;
	max-width: 620px;
	margin-bottom: clamp(-3.5rem, -4vw, -2rem);
	box-shadow: 0 24px 50px -22px rgba(46, 29, 18, 0.4);
}

/* The two arrival heroes carry a longer headline. */
.ca-hero-card--wide {
	max-width: 740px;
}


@media (max-width: 767px) {
	/* Full-bleed card on a phone: side gutters on a card this size waste the
	   little width there is. */
	.ca-hero-card {
		max-width: none;
		margin-bottom: 0;
		box-shadow: none;
	}
}

/* ==========================================================================
   Work grid
   Editorial rhythm: tiles are deliberately unequal so it reads as a
   contact sheet rather than a product catalogue.
   ========================================================================== */

.ca-grid {
	display: grid;
	grid-template-columns: repeat(12, 1fr);
	gap: clamp(1.5rem, 3vw, 3.5rem) clamp(1rem, 2.5vw, 2.5rem);
}

.ca-tile {
	position: relative;
	grid-column: span 6;
}

/* Alternating offsets — every other tile drops down a little, so the grid
   reads as a contact sheet rather than a product catalogue.

   This is expressed as a custom property rather than a `transform` because the
   scroll reveal also needs to translate these elements. Two rules both setting
   `transform` would mean the more specific one silently wins; instead each
   contributes a variable and the single transform below sums them. */
.ca-tile:nth-child(even) {
	--ca-stagger-y: clamp(1.5rem, 5vw, 5rem);
}

.ca-tile--wide {
	grid-column: span 12;
}

@media (max-width: 767px) {
	.ca-tile,
	.ca-tile--wide {
		grid-column: span 12;
	}

	.ca-tile:nth-child(even) {
		--ca-stagger-y: 0px;
	}
}

.ca-tile-media {
	overflow: hidden;
	background: var(--ca-line);
}

/* The 40 photographs run from 16:9 to 9:16, so tiles crop to a fixed ratio.
   Without this, grid rows size to the tallest portrait in the row and the
   landscape tiles float in a sea of empty cream. `aspect-ratio` plus
   `object-fit: cover` gets the crop without needing a height on any ancestor. */
.ca-tile-media img {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 4 / 5;
	object-fit: cover;
	object-position: center;
	transition: transform 1.1s var(--ca-ease);
}

.ca-tile--wide .ca-tile-media img {
	aspect-ratio: 16 / 7;
}

@media (max-width: 767px) {
	/* A 16:7 sliver is unreadable on a phone. */
	.ca-tile--wide .ca-tile-media img {
		aspect-ratio: 4 / 5;
	}
}

.ca-tile:hover .ca-tile-media img {
	transform: scale(1.045);
}

.ca-tile-client .elementor-heading-title,
.ca-tile-client .elementor-heading-title a {
	color: var(--ca-cocoa);
	text-decoration: none;
	transition: color 0.4s var(--ca-ease);
}

.ca-tile:hover .ca-tile-client .elementor-heading-title,
.ca-tile:hover .ca-tile-client .elementor-heading-title a {
	color: var(--ca-red);
}

.ca-tile a:focus-visible {
	outline: 2px solid var(--ca-red);
	outline-offset: 6px;
}

/* ==========================================================================
   Project (case study) pages
   ========================================================================== */

.ca-meta {
	border-top: 1px solid var(--ca-line);
	border-bottom: 1px solid var(--ca-line);
}

.ca-meta-key {
	font-family: "DM Sans", system-ui, sans-serif;
	font-size: 0.625rem;
	letter-spacing: 0.2em;
	text-transform: uppercase;
	color: var(--ca-red);
}

.ca-meta-value .elementor-heading-title {
	font-size: 0.9375rem;
	color: var(--ca-cocoa);
	line-height: 1.45;
}

/* Gallery: a responsive grid that keeps portrait and landscape honest. */
.ca-gallery .elementor-image-gallery .gallery {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(min(340px, 100%), 1fr));
	gap: clamp(0.75rem, 2vw, 1.75rem);
	margin: 0 !important;
}

/* Elementor ships `.gallery-columns-3 .gallery-item { max-width: 33.33% }` for
   the float-based WP gallery. Inside our CSS grid that clamps each frame to a
   third of its own cell, so max-width has to be released explicitly — width
   alone is not enough. */
.ca-gallery .elementor-image-gallery .gallery-item {
	margin: 0 !important;
	width: 100% !important;
	max-width: none !important;
	float: none !important;
	padding: 0 !important;
}

.ca-gallery .elementor-image-gallery .gallery-icon,
.ca-gallery .elementor-image-gallery .gallery-icon a {
	display: block;
	overflow: hidden;
}

.ca-gallery .elementor-image-gallery img {
	display: block;
	width: 100%;
	height: auto;
	border: none !important;
	transition: transform 1s var(--ca-ease);
}

.ca-gallery .elementor-image-gallery .gallery-item:hover img {
	transform: scale(1.03);
}

.ca-pager {
	border-top: 1px solid var(--ca-line);
}

.ca-pager a {
	text-decoration: none;
}

/* ==========================================================================
   Cookbook
   ========================================================================== */

/* The cover is cropped to the book block, so the lift is ours to supply. A real
   shadow beats the baked-in one from the info sheet: it can be tuned to the
   cream ground and it lifts on hover. */
.ca-book-cover img {
	display: block;
	width: 100%;
	max-width: 400px;
	height: auto;
	box-shadow: 0 2px 4px rgba(46, 29, 18, 0.1), 0 22px 44px -16px rgba(46, 29, 18, 0.42);
	transition: transform 0.6s var(--ca-ease), box-shadow 0.6s var(--ca-ease);
}

.ca-book-cover a:hover img {
	transform: translateY(-6px);
	box-shadow: 0 4px 8px rgba(46, 29, 18, 0.12), 0 32px 60px -18px rgba(46, 29, 18, 0.48);
}

/* ==========================================================================
   Prose lists
   Used by the cookbook page and the About credits.
   ========================================================================== */

.ca-prose ul {
	list-style: none;
	margin: 1.35em 0 0;
	padding: 0;
	max-width: 62ch;
}

.ca-prose li {
	position: relative;
	padding-left: 1.5em;
	margin-bottom: 0.6em;
}

.ca-prose li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.72em;
	width: 0.4em;
	height: 0.4em;
	border-radius: 50%;
	background: var(--ca-red);
}

.ca-prose li:nth-child(3n)::before {
	background: var(--ca-blue);
}

.ca-prose li:nth-child(3n + 2)::before {
	background: var(--ca-pink);
}

/* ==========================================================================
   Services list
   ========================================================================== */

.ca-service {
	border-top: 1px solid var(--ca-line);
	transition: background-color 0.5s var(--ca-ease);
}

.ca-service:last-of-type {
	border-bottom: 1px solid var(--ca-line);
}

/* ==========================================================================
   Dark bands (Koskaskenades, contact CTA, footer)
   ========================================================================== */

.ca-dark {
	background-color: var(--ca-cocoa-deep);
	color: rgba(242, 229, 220, 0.74);
}

.ca-dark h1,
.ca-dark h2,
.ca-dark h3,
.ca-dark .elementor-heading-title {
	color: var(--ca-cream);
}

/* Pink reads at 7.6:1 on the deep cocoa — the logo's own accent, legibly. */
.ca-dark .ca-eyebrow,
.ca-dark .ca-eyebrow p {
	color: var(--ca-pink);
}

.ca-dark .ca-prose p {
	color: rgba(242, 229, 220, 0.76);
}

.ca-dark .ca-lead p {
	color: var(--ca-cream);
}

.ca-dark .ca-meta {
	border-color: rgba(242, 229, 220, 0.18);
}

.ca-dark .ca-meta-key {
	color: var(--ca-pink);
}

.ca-dark .ca-meta-value .elementor-heading-title {
	color: var(--ca-cream);
}

.ca-dark .ca-prose a {
	color: var(--ca-cream);
	background-image: linear-gradient(var(--ca-pink), var(--ca-pink));
}

.ca-dark .ca-prose a:hover {
	color: var(--ca-pink);
}

/* Safety net for Elementor's global-typography fallbacks: several widget
   defaults resolve to the kit's `accent` preset, so anything that must stay
   upright says so here as well as in the kit. */
.ca-btn .elementor-button,
.ca-nav a,
.ca-eyebrow,
.ca-eyebrow p,
.ca-meta-key,
.ca-gallery .gallery-caption {
	font-style: normal;
}

/* ==========================================================================
   Buttons
   ========================================================================== */

.ca-btn .elementor-button {
	position: relative;
	overflow: hidden;
	border-radius: 0;
	font-family: "DM Sans", system-ui, sans-serif;
	font-size: 0.75rem;
	font-weight: 500;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	padding: 1.15em 2.4em;
	transition: color 0.45s var(--ca-ease), border-color 0.45s var(--ca-ease);
}

/* Wipe fill from the bottom on hover. */
.ca-btn .elementor-button::before {
	content: "";
	position: absolute;
	inset: 0;
	background: var(--ca-red);
	transform: translateY(101%);
	transition: transform 0.5s var(--ca-ease);
	z-index: 0;
}

.ca-btn .elementor-button:hover::before {
	transform: translateY(0);
}

.ca-btn .elementor-button-content-wrapper,
.ca-btn .elementor-button-text {
	position: relative;
	z-index: 1;
}

.ca-btn .elementor-button:hover {
	color: var(--ca-cream);
	border-color: var(--ca-red);
}

.ca-btn--light .elementor-button {
	color: var(--ca-cream);
	border: 1px solid rgba(242, 229, 220, 0.4);
}

/* ==========================================================================
   Client list
   ========================================================================== */

.ca-clients {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem 1.75rem;
	list-style: none;
	margin: 0;
	padding: 0;
}

.ca-clients li {
	font-family: Fraunces, Georgia, serif;
	font-size: clamp(1.125rem, 2.2vw, 1.75rem);
	color: var(--ca-cocoa);
	line-height: 1.35;
	max-width: none;
}

.ca-clients li::after {
	content: "·";
	margin-left: 1.75rem;
	color: var(--ca-red);
}

/* Cycle the wordmark's colours through the separators. */
.ca-clients li:nth-child(3n)::after {
	color: var(--ca-blue);
}

.ca-clients li:nth-child(3n + 2)::after {
	color: var(--ca-pink);
}

.ca-clients li:last-child::after {
	content: none;
}

/* ==========================================================================
   Scroll reveal
   Progressive enhancement: without JS, content is simply visible.
   ========================================================================== */

/* One transform declaration, summing every contributor. `--ca-stagger-y` comes
   from the work grid, `--ca-reveal-y` from the reveal state below. */
.ca-reveal,
.ca-tile {
	transform: translate3d(0, calc(var(--ca-stagger-y, 0px) + var(--ca-reveal-y, 0px)), 0);
	transition: opacity 0.9s var(--ca-ease), transform 0.9s var(--ca-ease);
}

@media (prefers-reduced-motion: no-preference) {
	html.ca-js .ca-reveal {
		opacity: 0;
		--ca-reveal-y: 18px;
		will-change: opacity, transform;
	}

	html.ca-js .ca-reveal.is-in {
		opacity: 1;
		--ca-reveal-y: 0px;
	}
}

/* ==========================================================================
   Forms (Contact Form 7)
   ========================================================================== */

.ca-form .wpcf7-form {
	display: grid;
	gap: 1.5rem;
}

.ca-form .wpcf7-form-control-wrap {
	display: block;
}

.ca-form label {
	display: block;
	font-family: "DM Sans", system-ui, sans-serif;
	font-size: 0.625rem;
	letter-spacing: 0.2em;
	text-transform: uppercase;
	color: var(--ca-red);
	margin-bottom: 0.6rem;
}

.ca-form input[type="text"],
.ca-form input[type="email"],
.ca-form input[type="tel"],
.ca-form select,
.ca-form textarea {
	width: 100%;
	background: transparent;
	border: 0;
	border-bottom: 1px solid var(--ca-line);
	border-radius: 0;
	padding: 0.65rem 0;
	font-family: "DM Sans", system-ui, sans-serif;
	font-size: 1rem;
	color: var(--ca-cocoa);
	transition: border-color 0.4s var(--ca-ease);
}

.ca-form input:focus,
.ca-form select:focus,
.ca-form textarea:focus {
	outline: none;
	border-bottom-color: var(--ca-red);
}

.ca-form textarea {
	min-height: 8rem;
	resize: vertical;
}

.ca-form .wpcf7-submit {
	justify-self: start;
	background: var(--ca-cocoa);
	color: var(--ca-cream);
	border: 0;
	border-radius: 0;
	padding: 1.15em 2.6em;
	font-family: "DM Sans", system-ui, sans-serif;
	font-size: 0.75rem;
	font-weight: 500;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	cursor: pointer;
	transition: background-color 0.4s var(--ca-ease);
}

.ca-form .wpcf7-submit:hover {
	background: var(--ca-red);
}

.ca-form .wpcf7-not-valid-tip {
	color: var(--ca-red);
	font-size: 0.8125rem;
	margin-top: 0.4rem;
}

.ca-form .wpcf7-response-output {
	border: 0 !important;
	border-left: 2px solid var(--ca-red) !important;
	margin: 0 !important;
	padding: 0.75rem 1rem !important;
	font-size: 0.9375rem;
}

/* ==========================================================================
   Footer
   ========================================================================== */

.ca-footer a {
	text-decoration: none;
	color: inherit;
	transition: color 0.35s var(--ca-ease);
}

.ca-footer a:hover {
	color: var(--ca-pink);
}

/* ==========================================================================
   Accessibility
   ========================================================================== */

.ca-skip-link {
	position: absolute;
	left: -9999px;
	top: 0;
	z-index: 999;
	padding: 0.75rem 1.25rem;
	background: var(--ca-cocoa);
	color: var(--ca-cream);
	font-size: 0.875rem;
}

.ca-skip-link:focus {
	left: 0;
}

a:focus-visible,
button:focus-visible,
:where(input, select, textarea):focus-visible {
	outline: 2px solid var(--ca-red);
	outline-offset: 3px;
}
