/*
Theme Name: Terroo
Description: Terroo marketing site theme (migrated from Webflow).
Author: Terroo
Version: 1.0.0
*/

:root {
	/* v2 palette (redesign pass): dropped the mustard/teal accent duo in
	   favor of a single rust accent over a warmer cream, with softer
	   text-primary/secondary browns instead of near-black ink. Old variable
	   names kept where the role didn't change (--color-tint, --color-border,
	   --color-rust-deep) so every selector referencing them updates for
	   free; only the underlying hex moved. */
	--color-bg: #f5f0e8;
	--color-ink: #2b2118;
	--color-rust: #b84c32;
	--color-rust-deep: #a83e28;
	--color-taupe: #4a3728;
	--color-tint: #f0e3d6;
	/* The deeper/warmer tint used for hero bands, closing bands, and
	   blockquote callouts -- was hardcoded as `#ede1d4` in 4 separate
	   places; promoted to a variable so every usage stays in sync from one
	   source instead of drifting if one gets edited and the others don't. */
	--color-tint-deep: #ede1d4;
	--color-card-bg: #fffaf2;
	/* --color-cream-soft (#f5efe6) removed -- an RGB-distance audit of the
	   whole palette found it within 2-3 units of --color-bg (#f5f0e8),
	   virtually indistinguishable and almost certainly drift from separate
	   edits rather than a deliberate second near-white, unlike the
	   --color-tint/--color-tint-deep or --color-rust/--color-rust-deep
	   pairs (both much further apart and each used differently on
	   purpose). Its 3 usages now read var(--color-bg) directly. */
	/* Bare RGB triplet (no alpha) so --color-border and any one-off shadow
	   alpha can compose from the same source via rgba(var(--color-shadow-
	   rgb), X) instead of each hardcoding this triplet separately -- found
	   two .terroo-card box-shadows doing exactly that during the same
	   audit (0.35/0.4 alpha, needs the same RGB as --color-border but
	   --color-border's own alpha is fixed at 0.16). */
	--color-shadow-rgb: 28, 26, 23;
	--color-border: rgba(var(--color-shadow-rgb), 0.16);
	/* Muted greige "tape" accent -- replaces mustard as the one decorative
	   highlight color still in use (polaroid quote mark). */
	--color-highlight: #c8c2b8;
	/* Pure white -- distinct from the warm off-white --color-card-bg
	   (#fffaf2). Used for text sitting on a solid rust background and for
	   a couple of plain form-input backgrounds; was hardcoded as `#fff` in
	   4 places before this audit. */
	--color-white: #fff;
	/* Muted sage green -- the site's only genuinely "success" signal color.
	   Added per feedback: form success messages were previously bordered
	   in --color-rust, the same hue family as --color-rust-deep's error
	   state, so the two states read as barely distinguishable variants of
	   the same warning-ish orange instead of clearly success vs error. */
	--color-success: #4a7c59;
	--font-serif: 'Fraunces', Georgia, serif;
	--font-sans: 'Inter Tight', 'Inter', sans-serif;
	--font-mono: 'JetBrains Mono', monospace;
	--container-max: 1280px;
	--section-pad: 112px;
	--section-pad-mobile: 56px;
	/* Hard-shadow offset scale -- the site's signature flat, no-blur
	   diagonal shadow (`Npx Npx 0 var(--color-x)`), used ~19 times across
	   buttons/cards/photo frames. An audit found the offset hand-typed
	   inconsistently each time (1.5/2/3/4/5/6/8px), including two
	   same-family components (.terroo-security-card / .terroo-mini-card)
	   at different offsets and three buttons each with their own rest
	   offset -- confirmed as drift, not deliberate distinctions, and
	   converged onto this 3-step scale. `sm`/`base` are also reused for
	   the buttons' hover/press states (the offset shrinks as the button
	   "presses in"), so the translate() that moves the button on
	   hover/press must stay numerically in sync with these same values. */
	--shadow-offset-sm: 2px;    /* button hover/pressed state */
	--shadow-offset-base: 4px;  /* buttons at rest; cards (mini-card, security-card, dropdown menu) */
	--shadow-offset-md: 6px;    /* .terroo-hero-image::before's MOBILE-only override -- the offset panel itself shrinks proportionally (32px insets -> 16px) at that width, so its shadow shrinks too (not a separate component, despite the name) */
	--shadow-offset-lg: 8px;    /* photo frames at desktop (.terroo-hero-image, .terroo-security-photo, newsletter panel), door cards */
}

* {
	box-sizing: border-box;
}

html {
	scroll-behavior: smooth;
}

body {
	position: relative;
	margin: 0;
	background: var(--color-bg);
	color: var(--color-ink);
	font-family: var(--font-sans);
	font-size: 17px;
	line-height: 1.5;
	-webkit-font-smoothing: antialiased;
	overflow-x: hidden;
}

/* Subtle grain texture -- a fixed, low-opacity fractal-noise overlay gives
   the flat cream/ink color fields a tactile, printed feel instead of reading
   as plain digital color. Cheap (inline SVG, no image request) and themeable
   since it just multiplies over whatever's beneath it. */
body::before {
	content: '';
	position: fixed;
	inset: 0;
	z-index: 9999;
	pointer-events: none;
	opacity: 0.035;
	mix-blend-mode: multiply;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

img {
	max-width: 100%;
	display: block;
}

a {
	color: inherit;
	text-decoration: none;
}

.terroo-container {
	max-width: var(--container-max);
	margin: 0 auto;
	padding: 0 40px;
}

@media (max-width: 767px) {
	.terroo-container {
		padding: 0 20px;
	}
}

/* ---------- Section rhythm ----------
   Elementor's own "CSS Classes" advanced control isn't wired up on the
   `section` element in this version (verified: only widgets/columns render
   it), so every section instead got a unique `_element_id` -- which IS
   rendered as a real HTML id -- and vertical spacing is driven from that
   here, one rule per section, instead of a shared class.
   top and bottom both var(--section-pad) -- per explicit feedback, every
   section (hero excluded -- it has its own rule below) gets SYMMETRIC
   top/bottom padding now, replacing the earlier deliberate asymmetry
   (112 top / 64 bottom, "more air above than below" for a less boxed-in
   rhythm). #comment-ca-marche, #securite and #rejoindre override bottom
   again below (they need special handling -- securite has a distinct
   Figma-verified magnitude, and the other two are merged sections whose
   real trailing space lives on a nested inner-section, not here) so this
   rule's bottom value only actually lands on #manifeste/#dictionary/
   #newsletter. #closing/#contact are dead selectors -- that wrap-up module
   was removed from the page content at some point; left harmless rather
   than risk deleting something still referenced elsewhere. */
#comment-ca-marche,
#securite,
#rejoindre,
#manifeste,
#dictionary,
#closing,
#contact,
#newsletter,
#securite-intro,
#securite-references,
#securite-cta,
#securite-consequences,
#securite-transparency,
#securite-precautions,
#securite-promises,
#securite-contact,
#manifeste-origine,
#manifeste-pourquoi,
#manifeste-croyance,
#manifeste-qui,
#manifeste-besoin,
#manifeste-contemplons,
#manifeste-closing,
#ccm-steps,
#ccm-moments,
#ccm-trust,
#ccm-closing,
#manifeste-hero,
#contact-hero,
#legal-hero,
#terms-hero,
#contact-reach,
#contact-form-section,
#contact-cta,
#local-principles,
#local-faq,
#local-note {
	padding: var(--section-pad) 40px var(--section-pad);
}

/* Every one of these sections' own `.elementor-widget-wrap.elementor-
   element-populated` column wrap carries its own undocumented 10px
   padding by default (gotcha #8) -- stacking on top of this rule's own
   declared padding above, so the actual visible gap to the first/last
   piece of content was 66px instead of the intended 56px (mobile) /
   122px instead of 112px (desktop), on BOTH the top and bottom edge.
   Confirmed live: measured a 10px gap between the section's own
   padding-box edge and its content on #securite/#rejoindre specifically,
   but the underlying cause applies to every section in this shared list
   equally, not just those two. Zeroed here, once, for all of them,
   instead of chasing it down section by section (already fixed
   individually for a few specific components elsewhere in this file --
   .terroo-newsletter-band, .terroo-hero-image, .terroo-security-photo --
   this is the same fix generalized for the plain/no-special-class
   sections that were still missing it). */
#comment-ca-marche > .elementor-container > .elementor-column > .elementor-widget-wrap,
#securite > .elementor-container > .elementor-column > .elementor-widget-wrap,
#rejoindre > .elementor-container > .elementor-column > .elementor-widget-wrap,
#manifeste > .elementor-container > .elementor-column > .elementor-widget-wrap,
#dictionary > .elementor-container > .elementor-column > .elementor-widget-wrap,
#contact > .elementor-container > .elementor-column > .elementor-widget-wrap,
#newsletter > .elementor-container > .elementor-column > .elementor-widget-wrap,
#securite-intro > .elementor-container > .elementor-column > .elementor-widget-wrap,
#securite-references > .elementor-container > .elementor-column > .elementor-widget-wrap,
#securite-cta > .elementor-container > .elementor-column > .elementor-widget-wrap,
#securite-consequences > .elementor-container > .elementor-column > .elementor-widget-wrap,
#securite-transparency > .elementor-container > .elementor-column > .elementor-widget-wrap,
#securite-precautions > .elementor-container > .elementor-column > .elementor-widget-wrap,
#securite-promises > .elementor-container > .elementor-column > .elementor-widget-wrap,
#securite-contact > .elementor-container > .elementor-column > .elementor-widget-wrap,
#manifeste-origine > .elementor-container > .elementor-column > .elementor-widget-wrap,
#manifeste-pourquoi > .elementor-container > .elementor-column > .elementor-widget-wrap,
#manifeste-croyance > .elementor-container > .elementor-column > .elementor-widget-wrap,
#manifeste-qui > .elementor-container > .elementor-column > .elementor-widget-wrap,
#manifeste-besoin > .elementor-container > .elementor-column > .elementor-widget-wrap,
#manifeste-contemplons > .elementor-container > .elementor-column > .elementor-widget-wrap,
#manifeste-closing > .elementor-container > .elementor-column > .elementor-widget-wrap,
#ccm-steps > .elementor-container > .elementor-column > .elementor-widget-wrap,
#ccm-moments > .elementor-container > .elementor-column > .elementor-widget-wrap,
#ccm-trust > .elementor-container > .elementor-column > .elementor-widget-wrap,
#ccm-closing > .elementor-container > .elementor-column > .elementor-widget-wrap,
#manifeste-hero > .elementor-container > .elementor-column > .elementor-widget-wrap,
#contact-hero > .elementor-container > .elementor-column > .elementor-widget-wrap,
#legal-hero > .elementor-container > .elementor-column > .elementor-widget-wrap,
#terms-hero > .elementor-container > .elementor-column > .elementor-widget-wrap,
#contact-reach > .elementor-container > .elementor-column > .elementor-widget-wrap,
#contact-form-section > .elementor-container > .elementor-column > .elementor-widget-wrap,
#contact-cta > .elementor-container > .elementor-column > .elementor-widget-wrap,
#local-principles > .elementor-container > .elementor-column > .elementor-widget-wrap,
#local-faq > .elementor-container > .elementor-column > .elementor-widget-wrap,
#local-note > .elementor-container > .elementor-column > .elementor-widget-wrap {
	padding: 0 !important;
}

/* Fills the viewport instead of just shrinking to fit its own content --
   the earlier fix (scaling text/photo down on short screens) stopped the
   hero from overflowing the viewport, but left it shorter than the
   viewport, revealing a sliver of the next section without scrolling.
   min-height + centering makes the hero claim the full first screen (below
   the header) either way, with the shrink-to-fit rules still doing their
   job of keeping the content itself from overflowing that space. 94px
   matches the header's actual rendered height. */
#hero {
	min-height: calc(100vh - 94px);
	display: flex;
	align-items: center;
	/* Figma (node-id=77-58) specs a flat 112px, not viewport-relative. */
	padding-top: 112px;
	padding-bottom: 112px;
}

/* comment-ca-marche now contains its title AND the cards grid AND the
   "voir comment ça marche" link as one section (matching Figma, where this
   is one frame) -- was 3 separate top-level sections. The two nested
   pieces get zero left/right padding (the outer column above already
   provides the page's 40px gutters) and no top padding of their own --
   the title's own 56px margin-bottom (.terroo-section-title) is the only
   gap between title and grid, so stacking a second top padding here would
   double it. cards-grid keeps a bottom padding as the internal gap before
   the link below it; comment-ca-marche's own bottom is what used to be
   #experiences-link's trailing space, now the outer section's job --
   var(--section-pad), matching top (was a distinct 48px; symmetric
   top/bottom per feedback, see the shared rule's comment above). */
#comment-ca-marche {
	/* Per feedback: cream band, matching the same tint #rejoindre/#dictionary
	   already use -- driven from the shared variable, not a native Elementor
	   background setting (same reasoning as #ccm-moments elsewhere in this
	   file: keeps every "cream band" section reading from one source). */
	background: var(--color-tint);
	padding-bottom: var(--section-pad);
}

/* Figma (node-id=180-186) specs this section's title centered, unlike the
   sitewide `.terroo-section-title` default (left-aligned, used by
   #securite/#rejoindre/etc.) -- scoped override, not a change to the
   shared rule, since the other sections using that class stay left.
   `text-align: center` alone only centers the text WITHIN the title's own
   box -- the shared rule's `max-width: 640px` shrinks that box to 640px
   but doesn't center the box itself, so without margin:auto too, the box
   sits flush against the column's left edge with merely-centered text
   inside it (confirmed live: box measured 70-710px against a 70-1210px
   section, not actually centered). margin:auto centers the box itself. */
#comment-ca-marche .terroo-section-title,
#comment-ca-marche .terroo-section-title .elementor-heading-title {
	text-align: center;
	margin-left: auto !important;
	margin-right: auto !important;
	/* Widened from the shared rule's 640px per feedback -- scoped here,
	   not a change to the shared value (which stays 640px for every other
	   section using .terroo-section-title). */
	max-width: 720px;
}

#cards-grid {
	padding: 0 0 64px;
}

#experiences-link {
	padding: 0;
}

/* Forces the nested grid/link sections onto their own row instead of
   trying to sit beside the title in the column's flex-wrap layout (see
   the #securite comment below for the full explanation of why this is
   needed -- same mechanism, just first documented there). */
#comment-ca-marche > .elementor-container > .elementor-column > .elementor-widget-wrap > .elementor-inner-section {
	flex: 0 0 100%;
}

/* rejoindre now contains its title AND the two door cards as one section
   (was 2). Same reasoning as comment-ca-marche above: doors-row loses its
   own left/right padding (rejoindre's 80px gutters already apply) and its
   own top padding (title's 56px margin is the gap); rejoindre's own
   bottom (var(--section-pad)) is what used to be #doors-row's trailing
   space. */
#rejoindre {
	padding-bottom: var(--section-pad);
}

#doors-row {
	padding: 0 0 var(--section-pad);
}

#rejoindre > .elementor-container > .elementor-column > .elementor-widget-wrap > .elementor-inner-section {
	flex: 0 0 100%;
}

/* securite now contains its title+intro row AND the photo/pillars row as
   one section (was 2). Figma specs 80px left/right (not the site's usual
   40px) for this section specifically. Top/bottom used to carry a one-off
   180px, but that was inconsistent with this same section's own tablet
   and mobile rules (both already normalize to the standard
   var(--section-pad)/var(--section-pad-mobile) below) and, per feedback,
   was just too big -- standardized to var(--section-pad) here too so all
   three breakpoints agree. */
#securite {
	padding: var(--section-pad) 80px var(--section-pad);
}

#security-pillars {
	padding: 0;
}

/* Elementor's `.elementor-widget-wrap` is flex-row + wrap by default (see
   the earlier #securite title/intro comment) -- with the grid/doors/pillars
   content now living in the SAME column as the title(s) above it, it would
   otherwise try to sit on the same row as them if there's leftover width,
   the same bug the title+intro side-by-side fix addressed. Forcing it to
   consume the full row (flex-basis 100%) guarantees it always wraps onto
   its own line below, regardless of how much room the title(s) leave. */
#securite > .elementor-container > .elementor-column > .elementor-widget-wrap > .elementor-inner-section {
	flex: 0 0 100%;
}

/* Title sits next to the intro paragraph (Elementor's own
   `.elementor-widget-wrap` flex-row default) -- explicit gap instead of
   relying on leftover row space. 80px, matching Figma: this single `gap`
   value covers BOTH the title-to-intro gap (horizontal, since they're side
   by side) AND the intro-row-to-content-row gap (vertical, since the
   photo/pillars content wraps to a new line below) -- Figma specs 80px for
   both, so one value does double duty here.
   flex-wrap: wrap, not nowrap -- title+intro's combined width (~1200px)
   already fits the container on its own at every width this matters, so
   they still land on one row without forcing it; wrap is what lets the
   security-pillars inner-section (flex-basis 100% above) drop to its own
   row below them instead of being squeezed onto the same line. nowrap was
   fine back when this column only had the two of them, but broke the
   moment security-pillars got folded in as a third child.
   Scoped with `>` all the way down to the direct column wrap -- a plain
   descendant selector here also matched every pillar card's OWN internal
   widget-wrap (title widget + text widget), which is a `.elementor-widget-wrap`
   too, at any depth inside #securite. That gave each pillar card an 80px
   gap between its title and text on top of the title's own 12px margin
   (92px total instead of 12px) -- broken in the exact same way the
   .terroo-section-title / .terroo-pillar-title fixes elsewhere in this
   file were broken, just one level more indirect. */
#securite > .elementor-container > .elementor-column > .elementor-widget-wrap {
	flex-wrap: wrap;
	/* Back to top-aligned per feedback (was briefly center-aligned to fix
	   the same visual mismatch -- reverted in favor of nudging the intro
	   down instead, see .terroo-body-lg's own padding-top below). */
	align-items: flex-start;
	gap: 80px;
}

/* Figma specs a fixed 560px title (not the shared .terroo-section-title's
   640px max-width used by comment-ca-marche/rejoindre) with the intro
   paragraph flexing to fill whatever's left -- scoped to #securite so the
   other two section titles aren't affected. */
#securite .terroo-section-title {
	width: 560px;
	max-width: 560px;
	flex-shrink: 0;
}

/* margin-bottom: 0 needed for the same reason as the title's own override
   above -- the intro paragraph isn't the last child either (the content
   row follows it), so it was independently picking up Elementor's default
   20px `.elementor-widget:not(:last-child)` margin, on top of the flex
   gap, on top of the title's own leak. Between title and body being the
   two row items and whichever is taller (body wraps to 2 lines, so it
   usually is) driving the row's effective bottom edge, this was the last
   of three stacked contributors pushing the real gap to 140px instead of
   80px. */
#securite .terroo-body-lg {
	flex: 1 0 0;
	margin-bottom: 0 !important;
	/* Per feedback: back to top-aligned with the title (see the shared row's
	   align-items above), but nudged down 16px so it doesn't sit flush
	   against the title's own cap-height -- a middle ground between a full
	   flex-start (title visibly taller/higher) and the earlier
	   align-items:center attempt. */
	padding-top: 16px;
}

/* Side-by-side title+intro is desktop-only: their combined width doesn't
   fit a mobile viewport, so stack them (and the security-pillars block
   below them) into a single column instead, same breakpoint as the rest
   of the file.
   flex-wrap: nowrap is required alongside flex-direction: column -- wrap
   is still `wrap` from the base rule above, and column-direction + wrap
   lays items into multiple side-by-side *columns* once they exceed the
   container's available height, instead of one continuous vertical stack.
   That's what was pushing security-pillars off to a phantom second column
   far to the right, overflowing the viewport. */
@media (max-width: 767px) {
	/* gap: 0, not a stacking value -- a flex `gap` applies the SAME distance
	   to every adjacent pair (title-to-body, body-to-content), and the user
	   flagged the title-to-body gap specifically as too big relative to
	   body-to-content. Switched to per-child margin-bottom below so each
	   pair can be tuned independently; the container itself no longer adds
	   any spacing of its own. */
	#securite > .elementor-container > .elementor-column > .elementor-widget-wrap {
		flex-direction: column;
		flex-wrap: nowrap;
		gap: 0;
	}

	/* The unconditional `flex: 0 0 100%` rule above (desktop row+wrap
	   context, where flex-basis is a WIDTH) was still reaching
	   #security-pillars and #securite-cta-row here at mobile, where this
	   wrap is column-direction -- flex-basis on a column flex container
	   sets HEIGHT, not width. With the wrap's own height auto/undefined,
	   two children both demanding "100% height" resolved to the same
	   indeterminate ~1629px box each (confirmed live: both elements'
	   getBoundingClientRect().height were bit-for-bit identical), stacking
	   into ~3000px of mostly-empty section and burying the "Learn more
	   about safety" button far down the page, well past where it visually
	   reads as part of the section -- reported as "the button is missing".
	   `auto` restores natural content-based height, which is what a
	   column stack needs (100% was only ever meaningful for the desktop
	   row's "full width, own line" trick). */
	#securite > .elementor-container > .elementor-column > .elementor-widget-wrap > .elementor-inner-section {
		flex: 0 0 auto;
	}

	/* Gap between the last pillar card and the "Learn more about safety"
	   button below it -- the container's own `gap: 0` above (mobile) means
	   nothing else provides this space, so the two sat flush against each
	   other once the height bug above was fixed. Matches the same 32px
	   mobile stacking value used elsewhere in this section (body-to-content
	   gap, card-to-card gap). */
	#securite-cta-row {
		margin-top: 32px;
	}

	/* The desktop-only fixed 560px title width above would otherwise
	   overflow a mobile column. */
	#securite .terroo-section-title {
		width: 100%;
		max-width: 100%;
	}

	/* Title-to-body gap itself is set further down the file, right after the
	   unconditional `#securite .terroo-section-title { margin-bottom: 0
	   !important; }` rule it needs to win against (same selector/specificity
	   -- later source position wins, so it can't live here). */

	/* Body-to-content gap stays at the site's usual 32px mobile stacking
	   value (matches cards-grid, security-pillars, doors-row) -- now that
	   the container `gap` is 0, this margin is what actually produces it.
	   Overrides the unconditional `#securite .terroo-body-lg { margin-bottom:
	   0 !important; }` above (same specificity, later in source wins). */
	#securite .terroo-body-lg {
		margin-bottom: 32px !important;
	}
}

/* This was a stale rule from before securite/security-pillars got merged
   into one section -- it re-added an 8px top / var(--section-pad) bottom
   padding that duplicated (and, being later in the file, silently won
   over) the `#security-pillars { padding: 0; }` rule above. That's the
   "broken padding" bug: security-pillars was getting real padding again
   despite the merge intending it to have none. Removed; the actual
   photo/pillars column gap lives on the row below. */
/* 70px, not the 80px Figma token -- Elementor's own column padding adds
   ~10px on top of column-gap (same discrepancy documented on #securite's
   title-to-intro gap elsewhere in this file), so 70 is what actually
   renders as 80. */
/* align-items: flex-start -- Elementor's container defaults to
   align-items:stretch, which never mattered while .terroo-security-photo
   was a plain <div> inside a text-editor widget's raw HTML (that div sized
   to its own img content regardless of what the flex row around it did).
   Now that the class lives on the COLUMN itself (a native Image widget,
   Part 3's refactor), the column IS a direct flex item of this container,
   so it stretched to match the taller pillars column -- and the ::before
   offset panel, sized off top:32/bottom:-32 relative to that stretched
   column, ballooned into a tall empty box far past the photo's actual
   bottom edge. Matches the design intent already documented on
   .terroo-security-photo itself: "top-aligned next to the pillars, not
   stretched to match their height". */
#security-pillars > .elementor-container {
	column-gap: 70px;
	align-items: flex-start;
}

/* Tablet: four separate fixes for this section at 768-1024px.

   1. Top AND bottom padding: securite's 180px top/bottom (symmetrized to
      match each other, see the #securite comment above) is a desktop-scale
      value tied to the full 1440px design. The first tablet pass here only
      reduced bottom, not top -- an oversight, not a deliberate asymmetry;
      top was still rendering at the full 180px, reading as a large empty
      gap above the title that had nothing to do with the (correctly fixed)
      bottom. Both reduced to the site's standard var(--section-pad)
      (112px) now, matching each other.
   2. Title+intro row: the title's fixed 560px width plus the 80px gap
      (615px+ needed before the intro even starts) only left room for the
      intro to squeeze into ~150-200px at these widths -- forced to wrap
      onto its own line at the very narrow end of the tablet range purely
      by accident (overflow), but NOT at the wider end (~1024px, where
      there's technically just enough room for both), where it instead sat
      cramped next to the title. Forcing column stacking here (same
      mechanism as the mobile rule above) makes the intro reliably render
      below the title across the WHOLE tablet range, not just the narrow
      sliver where it happened to overflow into that layout anyway.
   3. Photo/cards row: same `column-gap`-is-additive overflow as the hero
      and doors-row tablet fixes elsewhere in this file -- two
      `elementor-col-50` columns (photo, pillar-cards) plus a 70px
      column-gap always summed to more than 100% of the row's width, so it
      silently wrapped to a stacked layout instead of sitting side by side
      (the first tablet pass here only added a row-gap for that stacked
      case, papering over the wrap instead of fixing the overflow that
      caused it -- reported back as "right column should be next to left
      column"). calc(50% - 35px) per column (half of the 70px gap) makes
      the math sum to exactly 100%, so the row can't overflow into a wrap;
      the earlier row-gap is dead weight now (harmless, only applies when
      wrapped) but left in place rather than risk removing something that
      still matters if content ever grows wide enough to wrap again.
   4. Bottom padding covered under point 1. */
@media (min-width: 768px) and (max-width: 1024px) {
	#securite {
		padding-top: var(--section-pad);
		padding-bottom: var(--section-pad);
	}

	#securite > .elementor-container > .elementor-column > .elementor-widget-wrap {
		flex-direction: column;
		flex-wrap: nowrap;
		gap: 32px;
	}

	#securite .terroo-section-title {
		width: 100%;
		max-width: 100%;
	}

	#securite .terroo-body-lg {
		margin-bottom: 0 !important;
	}

	#security-pillars > .elementor-container {
		row-gap: 40px;
	}

	#security-pillars > .elementor-container > .elementor-column {
		width: calc(50% - 35px) !important;
		max-width: calc(50% - 35px) !important;
		flex: 0 0 calc(50% - 35px) !important;
	}
}

/* v2: this band gets extra horizontal breathing room (80px instead of the
   site's usual 40px) and a much wider gap between the two door cards
   (80px instead of 24px) now that they're visually differentiated rather
   than a matching pair.
   left/right live ONLY here, not on #doors-row too -- the pair used to both
   carry 80px, which double-padded the merged section (rejoindre's own
   gutters PLUS doors-row's own gutters stacking inside them) and squeezed
   the card row down to ~960px instead of the full content width, leaving
   dead space on both sides that doesn't exist in Figma (node-id=77-91).
   bottom is 0, not a leftover 8px -- doors-row's own var(--section-pad)
   below is the section's real trailing space (see the comment near line
   158), so rejoindre's own bottom just needs to get out of its way; the
   stray 8px was pushing the total to 120px instead of Figma's 112. */
#rejoindre {
	padding-bottom: 0;
	padding-left: 80px;
	padding-right: 80px;
}

#doors-row {
	padding-top: 4px;
	padding-bottom: var(--section-pad);
}

#doors-row > .elementor-container {
	column-gap: 80px;
}

/* Tablet: Elementor's own `.elementor-col-50` class computes each column at
   exactly 50% of the container -- fine on its own, but `column-gap` is
   ADDITIVE on top of that (flexbox gap doesn't shrink flex-basis), so the
   two 50% columns plus the 80px gap always demanded more than 100% of the
   container's width at every width tested. flex-shrink:0 (Elementor's
   default here) meant neither column gave way, so the row overflowed and
   wrapped -- the two door cards stacked instead of sitting side by side,
   which is what was reported. Explicit `calc(50% - 16px)` widths (with the
   gap tightened to 32px) make the math actually sum to 100%, so it can
   never overflow into a wrap. */
@media (min-width: 768px) and (max-width: 1024px) {
	#doors-row > .elementor-container {
		column-gap: 32px;
	}

	#doors-row > .elementor-container > .elementor-column {
		width: calc(50% - 16px) !important;
		max-width: calc(50% - 16px) !important;
		flex: 0 0 calc(50% - 16px) !important;
	}
}

/* padding-bottom: 0, not 48px -- that 48px was a leftover from before
   comment-ca-marche/cards-grid/experiences-link got merged into one
   section (back when experiences-link was its own standalone section with
   its own trailing space). Left in place, it was stacking with
   comment-ca-marche's own bottom padding below for a real (if
   undocumented) double-bottom on desktop -- same bug class as the
   doors-row/rejoindre and security-pillars/securite pairs elsewhere in
   this file, just never caught here since nobody had looked at this
   specific gap until now. comment-ca-marche's own bottom is the section's
   only real trailing space now, same pattern as those other two. */
#experiences-link {
	padding-top: 0;
	padding-bottom: 0;
}

/* v2: manifesto quote gets extra left margin (112px vs the site's usual
   40px) to push the big quote glyph further from the edge; right stays the
   standard 40px. #securite-promises reuses this same rule -- it's the
   exact same quote section/component as #manifeste (dark rust bg,
   .terroo-quote-col column), not a lookalike, so it gets the identical
   padding treatment rather than its own duplicated copy of these values. */
#manifeste,
#securite-promises {
	padding-left: 112px;
	padding-right: 40px;
}

/* #closing + #contact share the same tint background (set in the PHP
   build) and read as one wrap-up module -- see the fuller explanation on
   .terroo-mini-card below. Tight pairing, same pattern as the
   #securite/#security-pillars and #rejoindre/#doors-row pairs above. */
#closing {
	padding-bottom: 40px;
}

#contact {
	padding-top: 0;
	padding-bottom: var(--section-pad);
}

@media (max-width: 767px) {
	/* hero is NOT in this list -- it gets its own rule below (32px sides
	   instead of the 20px everyone else uses, and a distinct, deliberately
	   smaller bottom instead of matching top like the rest of the page
	   now does). bottom is var(--section-pad-mobile), matching top --
	   symmetric per feedback, was a distinct 40px. */
	#comment-ca-marche,
	#securite,
	#rejoindre,
	#manifeste,
	#dictionary,
	#closing,
	#contact,
	#newsletter,
	#securite-intro,
	#securite-references,
	#securite-cta,
	#securite-consequences,
	#securite-transparency,
	#securite-precautions,
	#securite-promises,
	#securite-contact,
	#manifeste-origine,
	#manifeste-pourquoi,
	#manifeste-croyance,
	#manifeste-qui,
	#manifeste-besoin,
	#manifeste-contemplons,
	#manifeste-closing,
	#ccm-steps,
	#ccm-moments,
	#ccm-trust,
	#ccm-closing,
	#manifeste-hero,
	#contact-hero,
	#legal-hero,
	#terms-hero,
	#contact-reach,
	#contact-form-section,
	#contact-cta,
	#local-principles,
	#local-faq,
	#local-note {
		padding: var(--section-pad-mobile) 20px var(--section-pad-mobile);
	}

	/* Top/bottom now match every other section's mobile padding
	   (var(--section-pad-mobile), same as the shared rule above) per
	   feedback -- previously an asymmetric, deliberately reduced 24px
	   bottom, since reverted. Sides stay 32px (was 20px, inherited from
	   the shared rule above before hero was split out) -- see the
	   #hero > .elementor-container comment below for why 20px wasn't
	   actually rendering as 20px anyway. */
	#hero {
		padding: var(--section-pad-mobile) 32px var(--section-pad-mobile);
	}

	/* cards-grid/experiences-link/doors-row/security-pillars are nested
	   inside comment-ca-marche/rejoindre/securite now (see the desktop
	   rules above) -- their left/right padding must stay 0 at every width,
	   not just desktop, or they'd double up with their outer section's
	   20px mobile gutters. */
	#cards-grid,
	#experiences-link,
	#doors-row,
	#security-pillars {
		padding-left: 0;
		padding-right: 0;
	}

	/* doors-row's desktop padding-bottom is var(--section-pad) (112px) --
	   its own trailing space back when it was a standalone section. That
	   was never reset for mobile, so it was stacking with #rejoindre's own
	   40px mobile bottom padding for ~150px of dead space before the next
	   section. Zeroed; rejoindre's own padding is the only trailing space
	   now, same as the other merged sections. */
	#doors-row {
		padding-bottom: 0;
	}

	/* Same bug, same fix, one section over: experiences-link's own 48px
	   desktop padding-bottom (its old standalone trailing space) was never
	   reset for mobile either, stacking with comment-ca-marche's own 40px
	   mobile bottom for ~88px of dead space below the "Voir comment ça
	   marche" button before the next section. Zeroed. */
	#experiences-link {
		padding-bottom: 0;
	}

	/* Zeroing #experiences-link's own padding above still left 32px of
	   incidental dead space stacked underneath it, unrelated to any
	   section-padding rule in this file: Elementor's own default
	   `.elementor-widget-wrap.elementor-element-populated { padding: 10px }`
	   gutter appears TWICE in this nesting (once on experiences-link's own
	   inner column wrap, once on comment-ca-marche's outer one that wraps
	   the whole merged inner-section), plus the raw <p> around the link
	   picking up the browser's default paragraph margin (12px, scaled to
	   this text's small font-size) -- 10+10+12 = 32px nobody designed,
	   found by walking the actual box chain from the link up to
	   comment-ca-marche's own edge. Zeroed all three so the section's own
	   40px bottom padding is the only trailing space left, matching every
	   other merged section's mobile pattern in this file. */
	#experiences-link > .elementor-container > .elementor-column > .elementor-widget-wrap,
	#comment-ca-marche > .elementor-container > .elementor-column > .elementor-widget-wrap {
		padding-bottom: 0;
	}

	#experiences-link p {
		margin-bottom: 0;
	}

	/* column-gap only creates horizontal space between columns -- with no
	   row-gap, they had zero space between them once they stack into a
	   single column on mobile (same gotcha as cards-grid's own mobile
	   row-gap above). Same fix for doors-row's two door cards. */
	#security-pillars > .elementor-container,
	#doors-row > .elementor-container {
		row-gap: 32px;
	}

	/* 64px (desktop value, gap from the last card row down to the "voir
	   comment ça marche" link) stood out against every other mobile
	   stacking gap on the page, all harmonized to 32px in this pass. */
	#cards-grid {
		padding-bottom: 32px;
	}
}

/* ---------- Buttons (global pill styles) ---------- */
/* !important is deliberate here: free Elementor's button widget exposes no
   per-instance text-color/radius/padding/typography controls (verified against
   the 4.2.1 widget registry), only background-color. These classes are the
   only reliable way to override its base .elementor-button CSS regardless of
   stylesheet load order. */
/* Two DOM shapes need covering:
   1. A plain `<a class="btn-pill">` used directly in header.php/footer.php.
   2. The Elementor button widget, where `_css_classes` lands the class on the
      *wrapper* div (`.elementor-widget-button.btn-pill`), not on the real
      `<a class="elementor-button">` link inside it -- confirmed by inspecting
      the rendered DOM (the wrapper div picked up "btn-pill" while the actual
      link kept Elementor's own default button box, rendering as a nested
      "box inside a box"). Style the real link via the descendant selector
      and neutralize the wrapper div so it doesn't paint its own box too. */
/* Chunky "sticker" buttons: flat hard-edge offset shadow instead of a soft
   blur, and the shadow shrinks + button shifts into it on press -- a
   tactile, playful move common to hostel/community brands (closer to a
   badge or a ticket stub than a corporate CTA). */
/* padding/font-size: 16px/32px/16px, not the old 17px/30px/15px -- per the
   site's 8px rule (every spacing/sizing value should be a multiple or
   divisor of 8px), which the original values drifted from. */
a.btn-pill,
a.btn-pill-outline,
.btn-pill .elementor-button,
.btn-pill-outline .elementor-button {
	display: inline-flex !important;
	align-items: center;
	gap: 8px;
	font-family: var(--font-sans) !important;
	font-weight: 800 !important;
	font-style: normal !important;
	font-size: 16px !important;
	line-height: 1 !important;
	padding: 16px 32px !important;
	border-radius: 999px !important;
	border: 2px solid var(--color-ink) !important;
	cursor: pointer;
	transition: transform 0.12s ease, box-shadow 0.12s ease;
	text-decoration: none !important;
	box-shadow: var(--shadow-offset-base) var(--shadow-offset-base) 0 var(--color-ink) !important;
}

a.btn-pill:hover,
a.btn-pill-outline:hover,
.btn-pill .elementor-button:hover,
.btn-pill-outline .elementor-button:hover {
	transform: translate(var(--shadow-offset-sm), var(--shadow-offset-sm));
	box-shadow: var(--shadow-offset-sm) var(--shadow-offset-sm) 0 var(--color-ink) !important;
}

a.btn-pill:active,
a.btn-pill-outline:active,
.btn-pill .elementor-button:active,
.btn-pill-outline .elementor-button:active {
	transform: translate(var(--shadow-offset-base), var(--shadow-offset-base));
	box-shadow: 0 0 0 var(--color-ink) !important;
}

a.btn-pill,
.btn-pill .elementor-button {
	background: var(--color-rust) !important;
	color: var(--color-white) !important;
}

a.btn-pill-outline,
.btn-pill-outline .elementor-button {
	background: var(--color-bg) !important;
	color: var(--color-ink) !important;
}

/* The wrapper div itself should be invisible -- no box, no padding. */
div.elementor-widget-button.btn-pill,
div.elementor-widget-button.btn-pill-outline {
	background: none !important;
	border: none !important;
	padding: 0 !important;
}

/* ---------- Header ---------- */
.terroo-header {
	position: sticky;
	top: 0;
	z-index: 100;
	background: var(--color-bg);
	border-bottom: 1px solid var(--color-border);
}

.terroo-header__inner {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 24px;
	padding: 24px 40px; /* was 20px, per the site's 8px grid rule */
	max-width: var(--container-max);
	margin: 0 auto;
}

.terroo-logo {
	font-family: var(--font-serif);
	font-size: 22px;
	font-weight: 600;
	color: var(--color-ink);
}

.terroo-logo img {
	height: 40px;
	width: auto;
	display: block;
}

.terroo-nav {
	flex: 1;
}

.terroo-nav ul {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 32px;
	list-style: none;
	margin: 0;
	padding: 0;
}

.terroo-nav a {
	font-size: 15px;
	color: var(--color-ink);
}

.terroo-nav a:hover {
	color: var(--color-rust);
}

.terroo-header__actions {
	display: flex;
	align-items: center;
	gap: 16px;
}

.terroo-lang {
	position: relative;
}

/* !important on background/border here for the same reason documented
   throughout this file: some Elementor default `button` rule was winning
   the specificity tie and painting this solid rust regardless of "none" --
   confirmed via computed styles (backgroundColor was rgb(192,74,48) despite
   this rule saying "none"). Rebuilt as a proper chunky circular icon button
   (thick border, hard shadow, real 40px touch target) instead of the
   cramped 32x22 unstyled-button box it was rendering as. */
.terroo-lang__toggle {
	background: var(--color-bg) !important;
	border: 2px solid var(--color-ink) !important;
	border-radius: 50%;
	width: 40px;
	height: 40px;
	cursor: pointer;
	display: flex;
	align-items: center;
	justify-content: center;
	color: var(--color-ink);
	box-shadow: var(--shadow-offset-base) var(--shadow-offset-base) 0 var(--color-rust);
	transition: transform 0.12s ease, box-shadow 0.12s ease;
}

.terroo-lang__toggle:hover {
	transform: translate(var(--shadow-offset-sm), var(--shadow-offset-sm));
	box-shadow: var(--shadow-offset-sm) var(--shadow-offset-sm) 0 var(--color-rust);
}

/* The gap between the toggle button and the menu used to be a `top` offset
   on this element -- which put that 14px strip *outside* .terroo-lang__menu's
   own box, so it wasn't part of the hoverable area at all. Moving the mouse
   from the button down toward the links crossed that dead zone, exited
   :hover on the parent, and the menu closed before it could be reached.
   Fixed by moving the gap inside this box as padding-top (still invisible,
   but now genuinely part of this element for hover purposes) and putting
   the visible border/shadow/background on a separate inner wrapper instead
   of on this outer one. */
.terroo-lang__menu {
	display: none;
	position: absolute;
	right: 0;
	top: 100%;
	padding-top: 16px; /* was 14px, per the site's 8px grid rule */
	min-width: 110px;
	z-index: 10;
}

.terroo-lang__menu.is-open {
	display: block;
}

/* Hover-open is a bonus for real pointer devices only. On touchscreens,
   tapping the toggle satisfies `:hover` too (mobile browsers apply a
   "sticky hover" on tap that only clears on a tap elsewhere) -- with the
   plain `.terroo-lang:hover` rule unscoped, that sticky hover state kept
   the menu visually open even after the JS below correctly toggled
   `.is-open` off on a second tap. Gating hover behind (hover: hover) and
   (pointer: fine) means touch devices rely solely on `.is-open`, so tap
   opens, tap the toggle again or tap outside actually closes it. */
@media (hover: hover) and (pointer: fine) {
	.terroo-lang:hover .terroo-lang__menu {
		display: block;
	}
}

.terroo-lang__menu-inner {
	background: var(--color-bg);
	border: 2px solid var(--color-ink);
	border-radius: 16px;
	padding: 8px;
	box-shadow: var(--shadow-offset-base) var(--shadow-offset-base) 0 var(--color-ink);
}

.terroo-lang__menu a {
	display: block;
	padding: 8px 12px;
	border-radius: 8px;
	font-family: var(--font-mono);
	font-size: 13px;
	font-weight: 700;
	letter-spacing: 0.02em;
	text-transform: uppercase;
	color: var(--color-ink);
}

.terroo-lang__menu a:hover {
	background: var(--color-tint);
}

/* Burger menu removed per Figma v2 (node-id=11-6): the mobile/tablet header
   is logo + CTA + language toggle only, no nav disclosure. The button
   element and its toggle JS are gone from header.php/nav-toggle.js; .terroo-nav
   just stays hidden below 991px with nothing to reopen it, matching the
   design. Kept .terroo-nav.is-open's own rules removed too since nothing
   can ever add that class anymore. */
@media (max-width: 991px) {
	.terroo-nav {
		display: none;
	}

	/* Figma's "Style=Small" button variant (node-id=11-6): 14px/800 label,
	   12px/16px padding instead of desktop's 16px/32px -- desktop's size
	   was designed for the header's extra horizontal room, which mobile/
	   tablet doesn't have next to the logo + globe icon. */
	.terroo-header__actions .btn-pill {
		padding: 12px 16px !important;
		font-size: 14px !important;
		gap: 4px;
	}
}

/* ---------- Eyebrow / mono labels ---------- */
.terroo-eyebrow {
	font-family: var(--font-mono);
	font-size: 12px;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--color-rust-deep); /* #a83e28, per feedback -- was --color-taupe */
}

/* ---------- Footer ---------- */
.terroo-footer {
	border-top: 1px solid var(--color-border);
	padding: 64px 40px 32px;
}

.terroo-footer__inner {
	max-width: var(--container-max);
	margin: 0 auto;
}

/* padding-right: Figma (node-id=93:133) puts an extra 40px on the Top row
   specifically, on top of the footer's own 40px side padding -- the
   columns end up inset 80px from the right edge while the bottom bar
   (icon included) stays at the footer's base 40px. Asymmetric on purpose
   per the design, not a mismatch to fix. */
.terroo-footer__top {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	gap: 40px;
	padding-bottom: 40px;
	padding-right: 40px;
}

/* Wraps the logo + tagline so both stack together as ONE flex item
   alongside .terroo-footer__columns -- .terroo-footer__top itself stays
   `justify-content: space-between` between just these two groups, same
   as before the logo was added. */
.terroo-footer__brand {
	display: flex;
	flex-direction: column;
	gap: 24px;
}

/* align-self: flex-start on the LINK (the actual flex item now that the
   logo is wrapped in an <a>) -- .terroo-footer__brand's flex column
   stretches items to fill its cross size (width) by default, which would
   force it to that full width too instead of sizing to its content;
   without this, the SVG's own preserveAspectRatio centers the (correctly
   proportioned) mark inside that oversized box, reading as "centered"
   rather than stretched. Confirmed live: width computed 340px (the
   container's width) instead of the intrinsic ~91px at height:32px. */
.terroo-footer__logo-link {
	display: block;
	align-self: flex-start;
}

.terroo-footer__logo {
	height: 32px;
	width: auto;
	display: block;
}

.terroo-footer__tagline {
	max-width: 340px;
	font-family: var(--font-serif);
	font-size: 20px;
	line-height: 1.3;
	color: var(--color-taupe);
}

.terroo-footer__columns {
	display: flex;
	gap: 128px;
	flex-wrap: wrap;
}

/* v2.2: third color pass on this component -- rust-deep, then ink, now
   taupe (Figma's color/text-secondary). Links move back from rust to ink
   at the same time (see .terroo-footer__col a below); the swap-then-swap-
   back pattern is why this comment keeps getting rewritten instead of just
   silently changing the value -- re-pulled node-id=93:133 and confirmed via
   get_variable_defs each time, not just the screenshot, since this
   component's colors have now changed on three separate revisions.
   letter-spacing/margin still corrected to match the site's one Label/Mono
   Bold token (0.06em, matches the door/pillar eyebrows elsewhere in this
   file) and its 16px header-to-links gap. */
.terroo-footer__col h4 {
	font-family: var(--font-mono);
	font-size: 12px;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--color-taupe);
	margin: 0 0 16px;
}

.terroo-footer__col ul {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 16px; /* was 12px, per the site's 8px grid rule */
}

/* Figma specs Label/Nav here: Inter Medium 16px (was a plain 15px with no
   weight set, i.e. regular 400). Color back to ink (v2.2, see the h4
   comment above) -- rust is now reserved for the hover state below. */
.terroo-footer__col a {
	font-size: 16px;
	font-weight: 500;
	color: var(--color-ink);
}

.terroo-footer__col a:hover {
	color: var(--color-rust);
}

/* padding-top corrected 24px -> 16px per Figma. */
.terroo-footer__bottom {
	display: flex;
	justify-content: space-between;
	align-items: center;
	flex-wrap: wrap;
	gap: 16px; /* was 12px, per the site's 8px grid rule */
	padding-top: 16px;
	border-top: 1px solid var(--color-border);
	font-size: 14px;
	line-height: 1.8;
	color: var(--color-ink);
}

/* v2.1: the colorful gradient Instagram glyph was replaced in Figma with a
   single-color outline icon (a plain svgrepo.com asset, 40px not 48px) --
   fill="currentColor" in the markup, color set here to rust so it's easy
   to re-theme without touching the SVG.
   line-height:0 keeps the inline SVG from adding descender space below
   itself (a bare `<a>` around an inline-level SVG otherwise sits a few
   px taller than the icon, throwing off align-items:center against the
   copyright text next to it). */
.terroo-footer__instagram {
	display: inline-flex;
	color: var(--color-rust);
	line-height: 0;
	transition: color 0.12s ease, opacity 0.12s ease;
}

.terroo-footer__instagram:hover {
	color: var(--color-rust-deep);
	opacity: 0.8;
}

/* Tablet: the desktop 128px column gap (sized for a full 1440px row) was
   never scaled down for anything narrower than the mobile breakpoint, so
   at tablet widths -- still 3 columns side by side, just in much less
   room -- the gap alone ate up over a third of the row, reading as a
   doubled/oversized gap relative to how narrow each column's own content
   is. 64px per feedback (was 32px). */
@media (min-width: 768px) and (max-width: 1024px) {
	.terroo-footer__columns {
		gap: 64px;
	}
}

@media (max-width: 767px) {
	.terroo-footer {
		padding: 48px 20px 24px;
	}

	/* 64px per feedback (was 32px) -- matches the tablet value above. */
	.terroo-footer__columns {
		gap: 64px;
	}

	/* The desktop-only extra 40px right inset on the top row (see the
	   .terroo-footer__top comment above) is a desktop design choice tied to
	   that wide 3-column layout -- at mobile widths the columns stack under
	   the tagline instead, so keeping it would just push everything 40px
	   off-center against the bottom bar's plain 20px sides for no reason. */
	.terroo-footer__top {
		padding-right: 0;
	}
}

/* ---------- Page content components ---------- */

/* Hero: asymmetric 58/42 split (set at the Elementor data level), image
   bleeding past the container to the viewport's right edge, and a giant,
   near-invisible watermark word behind the heading for texture/identity
   without competing with the real content. */
#hero {
	position: relative;
	overflow: hidden;
}

/* Scroll-cue: a bouncing chevron pinned to the very bottom of the SCREEN
   (viewport), not just the bottom of the hero's own content box --
   encouraging visitors to keep scrolling. Native Icon widget (Elementor
   free core, not Pro-gated) rather than a hand-typed <svg>/<a> in a
   WYSIWYG -- it's a clickable link (jumps to the next section), so per
   this project's own WYSIWYG-vs-native rule it needs its own native
   widget, same as any other button/CTA.
   `position: absolute` relative to #hero was tried first and hit a real
   wall: #hero's own content (`.elementor-container`) is vertically
   CENTERED within #hero's tall box (`#hero { align-items: center }`), so
   the container's own box is shorter than #hero and doesn't reach #hero's
   true bottom edge -- and TWO Elementor-core defaults between the icon and
   #hero (the column, and its `.elementor-widget-wrap`) each carry their
   own `position: relative`, becoming the icon's actual containing block
   instead of #hero regardless of which one got reset first. Chasing that
   chain confirmed centering could be fixed, but `bottom: Xpx` would always
   measure from whichever short box ended up as the containing block, not
   the visual bottom of the screen -- and that gap isn't a fixed value
   (it changes with viewport height, since the container is centered, not
   pinned). `position: fixed` sidesteps all of it: fixed elements ignore
   every ancestor's `position` and always resolve against the viewport
   itself (confirmed no ancestor sets `transform`/`filter`/`will-change`,
   which would otherwise create a competing containing block). Visibility
   is handled by a small scroll listener (nav-toggle.js) -- per feedback,
   hides after 120px of scroll specifically, not tied to the hero's own
   (viewport-tall) height at all -- rather than trying to solve that in
   pure CSS. */
.terroo-scroll-cue {
	position: fixed !important;
	left: 50%;
	bottom: 16px;
	transform: translateX(-50%);
	z-index: 2;
	transition: opacity 0.2s ease;
}

.terroo-scroll-cue.is-hidden {
	opacity: 0;
	pointer-events: none;
}

/* !important on color: Elementor's own icon-color control generates
   `{{WRAPPER}}.elementor-view-default .elementor-icon { color: ... }`
   (3 classes' worth of specificity vs this rule's 2), ties/beats this rule
   and its inline <style> loads after the theme's stylesheet -- same
   recurring gotcha #5 pattern documented elsewhere in this file for any
   custom class styling content inside `.elementor`. */
.terroo-scroll-cue .elementor-icon {
	color: var(--color-rust) !important;
	font-size: 28px;
	opacity: 0.5;
	animation: terroo-scroll-cue-bounce 2s ease-in-out infinite;
}

.terroo-scroll-cue .elementor-icon:hover {
	color: var(--color-rust-deep) !important;
	opacity: 1;
}

@keyframes terroo-scroll-cue-bounce {
	0%, 20%, 50%, 80%, 100% {
		transform: translateY(0);
	}
	40% {
		transform: translateY(-8px);
	}
	60% {
		transform: translateY(-4px);
	}
}

/* Hidden on short viewports (the vh-based hero padding/photo clamps
   elsewhere in this file already fight for space there) and on mobile,
   where the next section is one swipe away and the cue would otherwise
   overlap the stacked photo/text content. */
@media (max-height: 700px), (max-width: 767px) {
	.terroo-scroll-cue {
		display: none;
	}
}

@media (prefers-reduced-motion: reduce) {
	.terroo-scroll-cue .elementor-icon {
		animation: none;
	}
}

/* The two hero columns were sitting flush against each other with zero
   gap (verified via getBoundingClientRect -- col1's right edge and col2's
   left edge were the exact same pixel), which read as cramped given how
   much is happening in each column now.
   align-items: flex-start (not center) -- the photo column is taller than
   the text column, so centering them left the photo hanging well below the
   buttons while its top sat lower than the heading's top: unbalanced in
   both directions at once. Top-aligning both lines the heading and the
   badge/photo top up together instead. */
/* The row is centered as a single block (justify-content: center on a
   max-width:none row) instead of pinned to the left with the photo
   bleeding all the way to the viewport's right edge -- that read as
   lopsided rather than "wide". The photo column now sizes to its own
   content (flex: 0 0 auto) instead of stretching to fill whatever space is
   left, because the photo's size is driven by its own height cap below,
   not by how much horizontal room happens to be available. */
#hero > .elementor-container {
	position: relative;
	z-index: 1;
	align-items: flex-start;
	justify-content: center;
	/* Figma (node-id=77-58): 128px gap between the text/photo columns,
	   80px side padding (was 56px/40px). */
	column-gap: 128px;
	max-width: none;
	padding: 0 80px;
}

/* Elementor's 58/42 percentage split (set at the data level) left a dead
   gap in the middle at wide viewports -- the text content itself (heading,
   46ch paragraph) never came close to filling a 58%-wide column, so there
   was empty cream space between the copy and the photo column starting.
   Pinning the text column to a fixed 640px fixes that. */
#hero > .elementor-container > .elementor-column:first-child {
	width: 640px !important;
	flex: 0 0 640px !important;
	max-width: 640px;
	/* Per feedback: the column being a fixed 640px doesn't mean the text
	   itself fills that width -- the heading/paragraph naturally wrap
	   narrower than 640px, so left-aligned text still hugs the column's
	   left edge, reading unbalanced against the photo's own centered
	   weight on the right. Centering the column's content (text + the
	   button row) makes it read as a deliberately centered block instead. */
	text-align: center;
}

#hero > .elementor-container > .elementor-column:last-child {
	width: auto !important;
	flex: 0 0 auto !important;
	max-width: none !important;
}

/* Tablet (and any width down to 768px): the text column was capped at 50%
   here, but the photo column (last-child) was left on its unconditional
   `width: auto` / height-driven sizing (clamp(320px, 60vh, 620px) height,
   width following from aspect-ratio) -- at tablet viewport heights that
   still computes a photo wide enough that 50% text + that photo + the 56px
   column-gap added up to MORE than the container's width. flex-shrink:0 on
   both meant neither gave way, so the row overflowed and flex-wrap:wrap
   (set on the container) kicked in, dropping the photo to its own row --
   the two columns stacked instead of sitting side by side, which is what
   was reported. Capping the photo column at 50% too and switching it to
   the same width-driven sizing already used for it at mobile (100% of its
   now-fixed-width column, height following from aspect-ratio) makes both
   columns' widths sum to a fixed 100% - gap, so they can never overflow
   into a wrap. column-gap tightened to match (56px was fine at 50/50 but
   reads better slightly tighter at these narrower widths). */
@media (max-width: 1200px) {
	/* calc(), not a plain 50% -- 50%+50%+40px column-gap still overflows
	   the container's CONTENT width specifically: the container itself
	   carries its own 40px side padding (`#hero > .elementor-container {
	   padding: 0 40px; }`, desktop rule, still in effect here), so two
	   columns at a flat 50% already consume the container's full content
	   width on their own, before the gap is even added -- same
	   gap-is-additive issue as the doors-row tablet fix elsewhere in this
	   file. calc(50% - 20px) per column with a 40px gap sums to exactly
	   100%, so it can't overflow into a wrap. */
	#hero > .elementor-container > .elementor-column:first-child {
		width: calc(50% - 20px) !important;
		flex: 0 0 calc(50% - 20px) !important;
		max-width: calc(50% - 20px) !important;
	}

	#hero > .elementor-container > .elementor-column:last-child {
		width: calc(50% - 20px) !important;
		flex: 0 0 calc(50% - 20px) !important;
		max-width: calc(50% - 20px) !important;
	}

	#hero > .elementor-container {
		column-gap: 40px;
	}

	.terroo-hero-image {
		width: 100%;
	}

	/* width/height for this breakpoint actually live further down the file,
	   right after .terroo-hero-image img's own base rule (same reasoning as
	   the mobile override there: the base rule's `height: clamp(...)
	   !important` is unconditional and appears LATER in the file, so an
	   equal-specificity !important override placed here, earlier, loses the
	   source-order tiebreak and silently does nothing -- confirmed live,
	   computed height stayed at the clamp value despite this block
	   "setting" it). */
}

@media (max-width: 767px) {
	/* column-reverse flips the VISUAL stack (photo above text) without
	   touching source order -- screen readers/keyboard nav still hit the
	   text column first, matching the desktop reading order, only the
	   painted order changes. row-gap replaces the old margin-top on
	   .terroo-hero-image below: a per-element margin only produces a gap on
	   whichever side it's declared, so it broke the moment the visual order
	   flipped (it would've landed above the photo instead of between the
	   photo and the text); row-gap is direction-agnostic and always lands
	   between the two stacked items regardless of which renders first. */
	/* padding: 0, not 0 20px -- this container sat INSIDE #hero, which
	   already carries its own 32px side padding (see the #hero mobile rule
	   above), so the old 20px here was a second, redundant inset stacking
	   on top of it (~50px effective instead of the intended 32px -- found
	   by measuring the rendered heading position directly, not just
	   reading the cascade). Zeroed; #hero's own padding is the only
	   horizontal inset now, same pattern used for every other merged/
	   nested section in this file. */
	/* flex-wrap: nowrap is required alongside flex-direction: column-reverse --
	   Elementor's own container default is flex-wrap: wrap (not set anywhere
	   in this theme file, it just ships that way), and column-direction +
	   wrap lays items into multiple side-by-side *columns* once their
	   combined height exceeds the container's available height, instead of
	   one continuous vertical stack -- the exact same mechanism already
	   documented on #securite's own mobile fix elsewhere in this file, just
	   missed here when column-reverse was first added for the hero
	   photo-above-text flip. With the hero's stacked photo+text content
	   comfortably taller than one screen on most phones, this was silently
	   wrapping the second item into a phantom second column at roughly half
	   width -- reported back as "display is broken (should be full width)":
	   a narrow, oddly-cropped photo and single-word-per-line heading text
	   sitting side by side instead of one full-width stacked column. */
	#hero > .elementor-container {
		column-gap: 0;
		row-gap: 48px;
		flex-direction: column-reverse;
		flex-wrap: nowrap;
		padding: 0;
	}

	/* Elementor's own `.elementor-widget-wrap.elementor-element-populated`
	   default (10px all round, undocumented anywhere -- verified by
	   walking the box chain from the heading up to #hero) was adding a
	   third layer of horizontal inset on top of #hero's own 32px, landing
	   the heading at 42px from the edge instead of 32px. Same "hidden
	   Elementor gutter" bug hit elsewhere in this file (the security photo
	   column, the comment-ca-marche/experiences-link nesting); zeroed here
	   too. */
	#hero > .elementor-container > .elementor-column > .elementor-widget-wrap {
		padding: 0;
	}

	/* max-width needs !important too, not just width/flex -- without it, the
	   tablet rule's `max-width: calc(50% - 20px) !important` (both ≤1200px
	   and ≤767px match at phone widths, so both are in play) still won:
	   `!important` always beats a non-`!important` declaration regardless of
	   selector specificity or source order. width:100% was correctly being
	   set (534px, the full column-reverse container width) but then capped
	   right back down to ~247px by that surviving max-width -- getComputedStyle
	   for `width` reports the USED value after max-width is applied, so it
	   read as "width is 247px" even though the `width` property's own source
	   value really was 100%, which is what made this one confusing to
	   diagnose (flex-basis and width both looked "correctly" overridden;
	   max-width was the one property still losing). */
	#hero > .elementor-container > .elementor-column:first-child,
	#hero > .elementor-container > .elementor-column:last-child {
		width: 100% !important;
		flex: 1 1 100% !important;
		max-width: 100% !important;
	}
}

/* !important on font-family here is deliberate: Elementor's own
   `.elementor-widget-text-editor { font-family: ... }` default rule has the
   exact same specificity (single class) and was winning the tie by loading
   later in the cascade -- silently rendering this in Inter Tight instead of
   Fraunces despite this rule being correct all along. */
/* Font-size is now bounded by vh as well as vw (min() of the two) -- on a
   short/wide viewport the vw value alone stayed huge and the heading ate
   most of the available height by itself. */
/* color also needs !important here, same root cause as font-family above:
   Elementor's own default text-editor color rule was winning the tie and
   silently rendering this in taupe (#6B5F52) instead of ink (#1C1A17). */
/* Floor raised 32px -> 40px per feedback that the mobile hero title read
   too small -- the vw/vh terms only overtake that floor above ~625px
   width (6.4vw=40 at 625px) or a tall-enough viewport, so this only
   affects phones; tablet/desktop were already scaling past 40px via the
   fluid terms and are unaffected. */
/* Both selectors, same pattern as .terroo-section-title elsewhere in this
   file: now that the hero title is a genuine Elementor Heading widget
   (not the raw-div text-editor hack this used to be), its actual text
   sits inside a nested <h1 class="elementor-heading-title">, one level
   below the .terroo-hero-heading class itself (which lives on the outer
   .elementor-widget wrapper, via _css_classes). font-size/weight/color
   etc. are inherited properties, so in principle the outer class alone
   should reach the nested h1 regardless -- but Elementor's own kit
   typography defaults target .elementor-heading-title directly (a real
   match, not mere inheritance), and a direct match always beats
   inheritance no matter what the ancestor says. Confirmed live: without
   this second selector, the title was rendering at kit defaults (500
   weight, ~138px oversized font) instead of this rule's 600/clamp(84px). */
.terroo-hero-heading,
.terroo-hero-heading .elementor-heading-title {
	font-family: var(--font-serif) !important;
	font-size: clamp(40px, min(6.4vw, 8vh), 84px);
	letter-spacing: -0.01em;
	/* v2: opened up from 1.02 to 1.2 -- the tighter value read cramped
	   against the rest of the hero's more generous spacing below. */
	line-height: 1.2;
	/* !important added -- was silently losing to Elementor's own
	   `.elementor-widget-text-editor` default (same specificity, one class
	   each; Elementor's stylesheet loads after the theme's and wins the
	   tie), the same recurring pattern documented elsewhere in this file
	   for exactly this reason. The homepage hero title has been rendering
	   at the browser default (400) this whole time despite this rule
	   always having said 600 -- caught only because the /securite page's
	   own heading (a plain <p>, no competing Elementor wrapper classes)
	   rendered the stated 600 correctly and the two no longer matched. */
	font-weight: 600 !important;
	color: var(--color-ink) !important;
}

/* margin stays scoped to the outer widget wrapper only (not duplicated
   onto .elementor-heading-title) -- this is specifically neutralizing
   Elementor's own widget-level `:not(:last-child)` default, which only
   ever applies to the outer .elementor-widget box, not the inner tag. */
.terroo-hero-heading {
	/* Flat 40px, matching Figma (node-id=77-58) exactly -- was a vh-clamp
	   kept as a short-viewport safety net; per this pass's explicit
	   "match Figma's paddings/gaps" request, that compromise is dropped in
	   favor of the literal spec value.
	   !important required: this widget isn't the last child in its column
	   (the body paragraph follows it), so Elementor's own
	   `.elementor-widget:not(:last-child) { margin-block-end: 20px }`
	   outranks a plain single-class rule (two selectors' worth of
	   specificity vs one) and was silently pinning this at a flat 20px
	   regardless of what this clamp said -- same root cause as the
	   .terroo-section-title and .terroo-pillar-title fixes below, just
	   discovered here first. */
	margin: 0 0 40px !important;
}

.terroo-hero-heading .accent {
	font-style: italic;
	font-weight: 400;
	color: var(--color-rust);
}

/* Three DOM shapes need covering, all under the one harmonized class:
   (1) `.terroo-body-lg` itself -- matches when the class sits directly on
   the element carrying the text (e.g. a plain `<p class="terroo-body-lg">`
   used standalone). (2) `.elementor-widget-text-editor p.terroo-body-lg`
   -- the class landing directly on a `<p>` tag inside a text-editor
   widget's raw HTML (dictionary's definition, manifeste-hero's intro).
   (3) `.elementor-widget-text-editor.terroo-body-lg p` -- the WIDGET-level
   case (`_css_classes` on the wrapper div, e.g. #hero/#securite/
   #securite-hero's intros), where the actual visible text is a BARE `<p>`
   nested inside that wrapper.
   (3) is not optional: it was missing when this rule was first
   harmonized to 20px/taupe, and every widget-level instance kept silently
   rendering the sitewide default's 18px/ink instead -- because font-size
   set on the WRAPPER only reaches that inner bare `<p>` via inheritance,
   and an inherited value (even from an `!important` declaration) always
   loses to ANY rule that matches the element directly, regardless of
   importance. The harmonized `.elementor-widget-text-editor p` default
   rule elsewhere in this file is exactly that kind of direct match, so it
   was winning every time despite this rule's own `!important`. Confirmed
   by checking the WRAPPER's own computed style (correctly 20px) versus
   the actual rendered `<p>` inside it (still 18px) -- checking only the
   wrapper is what let this regression go unnoticed the first time. */
.terroo-body-lg,
.elementor-widget-text-editor p.terroo-body-lg,
.elementor-widget-text-editor.terroo-body-lg p {
	font-size: 20px !important;
	line-height: 1.6;
	color: var(--color-taupe) !important;
	max-width: 46ch;
}

/* #hero's own paragraph still needs its own margin-bottom fix (Elementor's
   inter-widget margin default), just no longer its own font-size/color --
   those are harmonized on the shared rule above now. */
#hero .terroo-body-lg {
	/* Elementor's own default `.elementor-widget:not(:last-child)` gives
	   every widget a 20px margin-bottom -- stacking with the 40px
	   margin-top below to produce a 60px gap instead of the specced 40px.
	   Zeroed here, at the widget level. */
	margin-bottom: 0;
	/* Figma (node-id=77-58) specs this paragraph at the column's full
	   640px measure, not the shared .terroo-body-lg rule's 46ch (~460px)
	   cap -- scoped override, the shared cap stays as-is for every other
	   .terroo-body-lg usage on the site. This only reaches the WRAPPER div
	   though (see below). */
	max-width: 640px;
}

/* The wrapper's max-width above doesn't reach the actual bare <p> Elementor
   renders inside it -- the shared sitewide rule's own compound selector
   (`.elementor-widget-text-editor.terroo-body-lg p { max-width: 46ch }`)
   matches that <p> DIRECTLY, and a direct match always wins over a value
   merely inherited from the wrapper, regardless of !important (same root
   cause documented at length on the shared .terroo-body-lg rule itself).
   Confirmed live: the wrapper measured 620px correctly, but the actual
   text sat in a 532px-wide left-flush box inside it, off-center from the
   heading above. Overriding the same compound shape here, scoped to
   #hero, removes the cap so the text uses the wrapper's full width. */
#hero .elementor-widget-text-editor.terroo-body-lg p {
	max-width: none;
}

/* Same gotcha, one level deeper: margin:0 on the widget div above doesn't
   reach the raw `<p>` this text-editor widget renders internally (see the
   security pillars' text rule for the same pattern), so the browser's own
   default ~1em paragraph margin was *also* adding to the gap independently
   of the widget-level fix above. Both have to be zeroed. */
#hero .terroo-body-lg p {
	margin: 0;
}

/* `.terroo-btn-row` doesn't exist anywhere in the rendered markup -- the
   two hero buttons are actually two Elementor columns inside a nested
   `.elementor-inner-section` (their side-by-side layout + 16px column-gap
   already comes from Elementor's own column/gap system, not from this
   class). Targeting the real element instead of the dead selector, scoped
   to #hero since inner-sections are also used elsewhere on the page (e.g.
   the security pillars).
   Flat 40px, not a vh clamp: Figma specs a fixed 40px gap here (unlike the
   hero's overall vertical rhythm, which does need to shrink on short
   viewports), and the previous clamp() was exactly why this measured short
   of 40 in the first place. */
#hero .elementor-inner-section {
	margin-top: 40px;
}

/* The button row's own container defaults to left-aligned flex, so once
   the column's text is centered above, the two buttons need the same
   explicit centering -- same "size each column to its own content, center
   the row itself" technique already used for #manifeste-closing-buttons. */
#hero .elementor-inner-section > .elementor-container {
	justify-content: center;
	/* Figma (node-id=77-58): 16px gap between the two buttons. */
	column-gap: 16px;
}

#hero .elementor-inner-section > .elementor-container > .elementor-column {
	width: auto !important;
	flex: 0 0 auto !important;
}

/* #experiences-link's own "I am a traveler"/"I am a local" button pair --
   same underlying structure and same fix as #hero's row directly above
   (two columns inside a nested `.elementor-inner-section`, defaulting to
   an even 50/50 split rather than centered/content-sized), just scoped to
   this section instead. */
#experiences-link .elementor-inner-section > .elementor-container {
	justify-content: center;
	column-gap: 16px;
}

#experiences-link .elementor-inner-section > .elementor-container > .elementor-column {
	width: auto !important;
	flex: 0 0 auto !important;
}

/* The photo column now naturally reaches the viewport's right edge (the
   container has no max-width and no right padding -- see the
   #hero > .elementor-container rule above), so the old negative-margin
   "bleed" trick is gone; this just carries the offset rust panel and
   asymmetric organic corner radius that make it read as "designed" rather
   than a plain rounded photo.
   width: fit-content -- the photo's size is now driven by its own height
   (see the img rule below) with width following via aspect-ratio, so this
   wrapper needs to hug that box instead of stretching to fill its column
   (which would leave the offset ::before panel positioned against the
   wrong, wider edge). */
.terroo-hero-image {
	position: relative;
	width: fit-content;
}

/* v2: offset panel simplified to the site's one accent color (rust border +
   rust-deep hard shadow, tint fill) instead of the old teal-fill/mustard-
   shadow combo -- matches the security photo and newsletter band, which now
   all share this exact treatment. */
.terroo-hero-image::before {
	content: '';
	position: absolute;
	/* v2: offset bumped from 28 to 32px, matching the panel/photo growing
	   from 416 to 480px wide -- kept proportional to the new size. */
	top: 32px;
	left: -32px;
	right: 32px;
	bottom: -32px;
	background: var(--color-tint);
	border: 2px solid var(--color-rust);
	border-radius: 4px 120px 4px 120px;
	box-shadow: var(--shadow-offset-lg) var(--shadow-offset-lg) 0 var(--color-rust-deep);
	z-index: 0;
}

/* Height-driven instead of width-driven: height is a clamp against the
   viewport (with header height, hero padding, and the badge/tape overhang
   above the photo all budgeted for), and width follows from aspect-ratio.
   This is what actually guarantees the whole hero fits in one screen --
   the previous width:100%-of-column approach meant the photo's height was
   whatever the available horizontal space happened to produce, which is
   how it ended up taller than the viewport once the column widened. */
.terroo-hero-image img {
	position: relative;
	z-index: 1;
	border: 2px solid var(--color-rust) !important;
	border-radius: 4px 120px 4px 120px !important;
	width: auto !important;
	height: clamp(320px, 60vh, 620px) !important;
	max-width: 100%;
	object-fit: cover !important;
	/* v2: was a clean 4/5 (416x520) -- now specced as 480x520, a wider,
	   less classically-proportioned crop. */
	aspect-ratio: 480/520;
}

/* Tablet (≤1200px, matches the column-width breakpoint above): same
   decoupling problem as the mobile override below, just found later --
   the photo column got capped at 50% width, but this image's height was
   still independently driven by the desktop clamp(...) vh-based rule
   above, so its aspect-ratio-derived width routinely didn't match what
   the now-50%-capped column actually had room for, overflowing the row
   into a wrap (see the #hero > .elementor-container comment further up).
   Switching to width-driven sizing here (same technique as the mobile
   rule) makes the image's rendered width always match its column's
   actual width, which is what the column-capping fix up there needs to
   hold. Must sit here, after the base rule -- see this file's other
   `.terroo-hero-image img` overrides for why a same-specificity
   !important placed earlier in the file loses to this unconditional one. */
@media (max-width: 1200px) {
	.terroo-hero-image img {
		width: 100% !important;
		height: auto !important;
	}
}

@media (max-width: 767px) {
	/* height needs !important too, not just width -- without it, the base
	   rule's `height: clamp(320px, 60vh, 620px) !important` above still won
	   (equal selector, later !important beats an earlier non-important
	   declaration), leaving width driven by the column (100%) and height
	   driven independently by viewport height. Those two tracked completely
	   different things, so the rendered box stopped matching the 480/520
	   aspect-ratio the base rule declares -- decoupled, but not clipped, the
	   image visibly stretched into a taller crop than desktop.
	   max-height dropped too: with width now fixed at 100%, a max-height
	   cap here would re-introduce the same decoupling (height clamped
	   independently of the width it's supposed to track). aspect-ratio
	   (inherited from the base rule, untouched by this override) is what
	   should govern height from here on -- at mobile column widths that
	   works out well under any viewport-height concern the old cap was
	   guarding against anyway. */
	.terroo-hero-image img {
		width: 100% !important;
		height: auto !important;
	}

	.terroo-hero-image {
		width: 100%;
	}
}

/* The badge is now its own text-editor widget (see Part 3 image-widget
   refactor), a sibling of the image widget rather than living inside the
   same wrapper div as the <img>. Elementor's own core CSS sets
   `.elementor-widget { position: relative }` on every widget, so without
   this override the badge's OWN widget wrapper -- not the .terroo-hero-image
   column -- becomes its positioning context, anchoring top:-34px/left:-34px
   to wherever that (second, lower) flex item happens to sit instead of the
   photo's actual top-left corner. Resetting it back to static restores the
   column as the nearest positioned ancestor, same as before the refactor. */
.terroo-hero-image > .elementor-widget-wrap > .elementor-widget-text-editor {
	position: static;
}

/* The badge being its own separate (second) widget also means the image
   widget is no longer the sole/last widget in the column -- Elementor's
   own `.elementor-widget:not(:last-child) { margin-block-end: 20px }`
   default started applying, plus `.elementor-widget-wrap.elementor-
   element-populated`'s own undocumented 10px top+bottom padding -- both
   contribute to the COLUMN's own height (472px measured) even though the
   badge itself has zero visible height (its content is absolutely
   positioned, out of flow). Since .terroo-hero-image::before (the offset
   frame) is sized off the COLUMN's box, not the image's, that extra 40px
   was making the frame extend visibly past the photo's actual bottom
   edge. Neutralized here so the column -- and the frame -- hug the image
   tightly again, same recurring fix pattern used throughout this file
   wherever a single WYSIWYG/image block got split into multiple widgets.
   !important on padding: `.terroo-hero-image > .elementor-widget-wrap`
   ties Elementor's own `.elementor-widget-wrap.elementor-element-populated`
   rule exactly on specificity (two classes each), and Elementor's own
   stylesheet loads after the theme's, winning the tie silently -- same
   recurring issue as gotcha #5 in this project's playbook. */
.terroo-hero-image > .elementor-widget-wrap {
	padding: 0 !important;
}

.terroo-hero-image > .elementor-widget-wrap > .elementor-widget:not(:last-child) {
	margin-block-end: 0;
}

/* Circular "sticker" badge pinned on the photo, tilted like a real sticker
   slapped on a hostel luggage tag -- a classic backpacker-site device a
   plain editorial layout wouldn't use. Pure decoration (CSS-generated
   content), so it's intentionally left out of the accessibility tree. Lives
   on its own wrapper element now instead of a second ::after on the image
   (the tape strip took that slot), positioned with plain absolute values. */
.terroo-hero-badge {
	position: absolute;
	top: -34px;
	left: -34px;
	z-index: 3;
	width: 108px;
	height: 108px;
	border-radius: 50%;
	/* v2: white/rust "stamp" instead of solid mustard + hard ink shadow --
	   quieter, no shadow, matches the newsletter badge's same treatment. */
	background: var(--color-card-bg);
	border: 2px solid var(--color-rust);
	display: flex;
	align-items: center;
	justify-content: center;
	text-align: center;
	font-family: var(--font-mono);
	font-size: 10px;
	font-weight: 700;
	letter-spacing: 0.02em;
	text-transform: uppercase;
	color: var(--color-rust);
	line-height: 1.4;
	padding: 16px; /* was 14px, per the site's 8px grid rule */
	transform: rotate(-10deg);
	pointer-events: none;
}

@media (max-width: 767px) {
	/* margin-top removed -- the container's own row-gap (see the
	   #hero > .elementor-container mobile block above) now provides the
	   gap between the stacked photo/text columns regardless of which one
	   renders first, so a fixed margin on this specific element isn't
	   needed (and would double up the spacing on whichever side it landed). */
	.terroo-hero-image {
		margin-right: 0;
	}

	.terroo-hero-image::before {
		top: 16px;
		left: -16px;
		right: 16px;
		bottom: -16px;
		box-shadow: var(--shadow-offset-md) var(--shadow-offset-md) 0 var(--color-rust-deep);
	}

	.terroo-hero-badge {
		width: 84px;
		height: 84px;
		top: -20px;
		left: -20px;
		font-size: 7px;
	}
}

/* Heading-widget quirk (see the trust-section comment further down for the
   full explanation): the inner `.elementor-heading-title` needs its own
   !important rule, since Elementor prints a direct color/font-family rule
   on that tag that beats anything merely inherited from the wrapper. */
/* Floor raised 28px -> 34px per feedback that mobile section titles read
   too small -- 3.6vw only overtakes that floor above ~944px width, so on
   every phone (and most tablets) this was rendering flat at the floor
   value; raising it doesn't touch desktop, which was already scaling past
   34px well before the 46px cap. */
.terroo-section-title,
.terroo-section-title .elementor-heading-title {
	font-family: var(--font-serif) !important;
	font-size: clamp(34px, 3.6vw, 46px) !important;
	letter-spacing: -0.01em;
	line-height: 1.15 !important;
	color: var(--color-ink) !important;
	max-width: 640px;
}

/* rejoindre's title is a standalone heading (no paired intro row sharing
   its line, unlike securite's), and Figma (node-id=77-91) shows it as one
   unwrapped line at this width -- the shared 640px cap above was forcing
   an early second-line wrap that doesn't exist in the design.
   Both selectors, matching the base rule above -- the outer
   `.terroo-section-title` wrapper div isn't what wraps the text, the inner
   `.elementor-heading-title` <h2> is, so overriding only the outer one (as
   a first pass here did) left the h2's own 640px cap doing the wrapping
   regardless. */
#rejoindre .terroo-section-title,
#rejoindre .terroo-section-title .elementor-heading-title {
	max-width: none;
}

/* Same fix, same reasoning, "For travelers" page's moments-section title
   ("What each encounter actually is.") -- the shared 640px cap forces an
   early wrap that isn't wanted here. Both selectors, matching the
   #rejoindre override above. */
#ccm-moments .terroo-section-title,
#ccm-moments .terroo-section-title .elementor-heading-title {
	max-width: none;
}

/* !important required: this title always has a following sibling now (the
   merged-in grid/doors/pillars content), so Elementor's
   `.elementor-widget:not(:last-child)` default (two selectors' worth of
   specificity) beats a plain single-class rule and silently collapses the
   gap to a flat 20px instead of this value.
   80px so the space below the title reads the same in comment-ca-marche,
   rejoindre and securite -- matches securite's own title-to-content gap
   (see the #securite override below for why that one needed zeroing out
   instead). */
.terroo-section-title {
	margin: 0 0 80px !important;
}

/* 80px is a desktop value -- on mobile it read like a lot of dead space
   (same issue #securite had with its flex `gap`, just via margin here
   instead). Tightened to 32px to match the site's other mobile stacking
   gaps (cards-grid, security-pillars, doors-row, and #securite's own
   mobile gap). */
@media (max-width: 767px) {
	.terroo-section-title {
		margin: 0 0 32px !important;
	}
}

/* securite's title sits in a flex ROW with the intro paragraph (see
   `#securite > ... > .elementor-widget-wrap` above), and the 80px gap
   below that row down to the photo/pillars content already comes from
   that container's own `gap` property -- a flex `gap` and a child's own
   margin are additive, not either-or, so leaving the 80px margin above in
   place here stacked to a real 140px gap (56+80, back when this was
   56px) instead of 80px. Zeroed so the flex gap is the only contributor. */
#securite .terroo-section-title {
	margin-bottom: 0 !important;
}

/* Mobile-only: title-to-body gap halved per user feedback (32px -> 16px,
   the mobile widget-wrap `gap` is 0 now -- see the mobile block above --
   so this margin is the sole source of that gap). Same selector/specificity
   as the zeroing rule directly above; must sit after it in source order to
   win at mobile widths. */
@media (max-width: 767px) {
	#securite .terroo-section-title {
		margin-bottom: 16px !important;
	}
}

/* image-box widget: `_css_classes` lands "terroo-card" on the wrapper div,
   not on the image/title/description directly -- target Elementor's own
   generated inner classes instead (verified against the rendered DOM). */
/* Polaroid treatment, take 2: the whole `.terroo-card` wrapper IS the print
   now -- an off-white card with a thin frame and a soft realistic shadow,
   photo flush near the top, title+description sitting inside the SAME card
   on the caption strip below the photo (real polaroid layout), instead of
   the previous version where only the photo had a fake border and the text
   lived outside it on the page background. The tilt and the tape strip move
   from the photo to the card itself, since it's the card that's "pinned up"
   now, not just the photo inside it. */
/* v2: white card, no border, bigger radius, softer/bigger corner + more
   bottom air (16/16/32 instead of 14/14/26), and the caption is centered
   inside its own inset (see .elementor-image-box-content below) instead of
   running edge-to-edge left-aligned. */
.terroo-card {
	position: relative;
	/* was var(--color-card-bg-white, #fff) -- that variable was never
	   defined in :root, so this always silently fell through to the
	   plain-white fallback instead of the intended warm card tone; fixed
	   to the real existing variable (same value .terroo-mini-card already
	   uses below). */
	background: var(--color-card-bg);
	border-radius: 8px;
	padding: 16px 16px 32px;
	box-shadow: 0 18px 32px -16px rgba(var(--color-shadow-rgb), 0.35);
	transition: transform 0.25s ease, box-shadow 0.25s ease;
}

.terroo-card:hover {
	transform: rotate(0deg) !important;
	box-shadow: 0 22px 40px -16px rgba(var(--color-shadow-rgb), 0.4);
}

.terroo-card .elementor-image-box-wrapper {
	position: relative;
	z-index: 1;
}

.terroo-card .elementor-image-box-img {
	display: block !important;
	width: 100% !important;
	margin: 0 0 16px !important;
	position: relative;
}

.terroo-card .elementor-image-box-img img {
	display: block !important;
	border-radius: 4px !important;
	aspect-ratio: 4/3;
	object-fit: cover !important;
	width: 100% !important;
	height: auto !important;
}

.terroo-card::after {
	content: '';
	position: absolute;
	top: -12px;
	left: 50%;
	width: 64px;
	height: 26px;
	/* v2: the mustard "tape" is gone -- reuse the same translucent ink tint
	   as --color-border for a much quieter, paper-shadow-like strip. */
	background: var(--color-border);
	transform: translateX(-50%) rotate(-3deg);
	z-index: 2;
}

.terroo-card .elementor-image-box-content {
	display: flex;
	flex-direction: column;
	gap: 16px;
	padding: 16px 24px;
	text-align: center;
}

/* ---------- Shared card typography: "Card Heading" / "Card Body" ---------- */
/* Every card on the site -- the homepage's native image-box "polaroid"
   cards, door cards, and /securite's mini-cards -- now reads from these
   same two definitions, instead of each card type carrying its own
   separately-maintained (but visually near-identical) rule. Typography is
   shared in one place; margin is NOT, split into its own rule per context
   below, since the two contexts get their spacing from genuinely different
   mechanisms: the polaroid relies on `.elementor-image-box-content`'s own
   `gap: 16px` flex layout (so its title/description margins must stay 0 --
   flex `gap` doesn't collapse with a sibling's own margin, it just adds to
   it, so any non-zero margin here would double the polaroid's spacing),
   while a plain WYSIWYG `<h3>+<p>` pair (door/mini-cards) has no such flex
   gap and needs the heading's own bottom margin to create that same
   spacing instead. Compound `.elementor-widget-text-editor h3/p.terroo-card-*`
   selectors (0,2,1) reliably outrank the harmonized
   `.elementor-widget-text-editor h2/h3/p` sitewide defaults (0,1,1)
   regardless of source order. */
.elementor-widget-text-editor h3.terroo-card-heading,
.terroo-card .elementor-image-box-title {
	font-family: var(--font-serif) !important;
	font-size: 24px !important;
	font-weight: 600 !important;
	line-height: 1.2 !important;
	color: var(--color-ink) !important;
	padding: 0 !important;
}

.elementor-widget-text-editor h3.terroo-card-heading {
	margin: 0 0 16px !important;
}

.terroo-card .elementor-image-box-title {
	margin: 0 !important;
}

.elementor-widget-text-editor p.terroo-card-body,
.terroo-card .elementor-image-box-description {
	font-size: 16px !important;
	line-height: 1.6 !important;
	color: var(--color-ink) !important;
	margin: 0 !important;
	padding: 0 !important;
}

/* Scrapbook-wall card grid: alternating vertical offsets, a gentle rotation
   per photo, an alternating tape color, and an oversized numeral floating
   behind each card in a matching accent -- three colors cycling through the
   set instead of one repeated tone, so the grid itself reads "playful", not
   just each card individually.
   One 6-column section (cards-grid), not two separate 3-column rows -- the
   3-card stagger/rotation pattern just repeats every 3rd card (1&4, 2&5,
   3&6) so the second visual "row" reads the same as the first at desktop
   width, but the whole thing is a single flex-wrap grid, so 2-up (tablet)
   and 1-up (mobile) wrap cleanly across all 6 cards instead of wrapping
   each old row independently (which used to leave two orphaned single
   cards instead of one clean last row). */
#cards-grid .elementor-column {
	transition: transform 0.2s ease;
}

#cards-grid .elementor-column:nth-child(2),
#cards-grid .elementor-column:nth-child(5) {
	transform: translateY(-32px);
}

#cards-grid .elementor-column:nth-child(3),
#cards-grid .elementor-column:nth-child(6) {
	transform: translateY(16px);
}

#cards-grid .elementor-column:nth-child(1) .terroo-card,
#cards-grid .elementor-column:nth-child(4) .terroo-card {
	transform: rotate(-2.2deg);
}

#cards-grid .elementor-column:nth-child(2) .terroo-card,
#cards-grid .elementor-column:nth-child(5) .terroo-card {
	transform: rotate(1.8deg);
}

#cards-grid .elementor-column:nth-child(3) .terroo-card,
#cards-grid .elementor-column:nth-child(6) .terroo-card {
	transform: rotate(-1.5deg);
}

/* v2: tape is now a single translucent ink tint on every card (see
   .terroo-card::after above) instead of cycling mustard/rust/teal per
   column -- removed the per-nth-child color overrides that used to do that. */

/* Desktop: force 3-per-row explicitly instead of trusting Elementor's own
   sizing for a 6-column section. Verified this matters, not just belt and
   braces: splitting the old 2x3-column layout into one 6-column section
   made Elementor size all 6 columns to fit a single row (shrunk to ~180px
   each) instead of wrapping into two rows of 3 at 33.33% -- its internal
   column-width mechanism reacts to sibling *count*, not just the
   `elementor-col-33.33` class, so a fixed 3-per-row can't be assumed and
   needs the same explicit override as the tablet block below. row-gap
   recreates the ~48px visual gap the old two-section layout got for free
   from each section's own padding. */
@media (min-width: 1025px) {
	#cards-grid .elementor-container {
		flex-wrap: wrap;
		row-gap: 48px;
	}

	#cards-grid .elementor-column {
		width: 33.333% !important;
		max-width: 33.333% !important;
		flex: 0 0 33.333% !important;
	}
}

/* Tablet: 2 cards per row instead of Elementor's default single-column
   stack below 1024px (its own responsive system collapses every
   `.elementor-column` to 100% width there). `!important` is required to
   win regardless of the exact mechanism Elementor uses internally to set
   that width (observed to not be a plain, overridable `width` rule on this
   version -- same reasoning as the `!important` fights documented
   elsewhere in this file, just via a different, harder-to-trace
   mechanism). Being a single 6-item flex-wrap grid, this wraps cleanly into
   3 full rows of 2 -- the vertical stagger below is disabled for this same
   range so it doesn't collide with the wrap. Row-gap added explicitly:
   Elementor's default gap class only sets column-gap, so wrapped rows would
   otherwise sit flush against each other. */
@media (min-width: 768px) and (max-width: 1024px) {
	#cards-grid .elementor-container {
		flex-wrap: wrap;
		row-gap: 40px;
	}

	#cards-grid .elementor-column {
		width: 50% !important;
		max-width: 50% !important;
		flex: 0 0 50% !important;
	}
}

/* Mobile: same reasoning, 1 column -- still needs an explicit row-gap for
   the same reason as the tablet block above. */
@media (max-width: 767px) {
	#cards-grid .elementor-container {
		row-gap: 32px;
	}
}

/* Vertical stagger (translateY on nth-child(2)/(3)/(5)/(6)) only makes
   sense in the 3-across desktop rows it was designed for -- disabled
   through the tablet 2-up wrap too, not just mobile's single column, so a
   card doesn't shift into the row above it. */
@media (max-width: 1024px) {
	#cards-grid .elementor-column:nth-child(2),
	#cards-grid .elementor-column:nth-child(3),
	#cards-grid .elementor-column:nth-child(5),
	#cards-grid .elementor-column:nth-child(6) {
		transform: none;
	}
}

/* ---------- Trust section: beige background with the real photo ---------- */
/* Reworked from a dark text-only block to a plain beige background (same
   cream as the rest of the page, no color-block override) with the
   section's own photo given the same border/shadow treatment as the hero
   photo (no tape -- that's reserved for the polaroid experience cards)
   instead of relying on a dark background alone to make this section
   distinct. */
/* .terroo-pillar-title / .terroo-pillar-text removed entirely -- per
   feedback, security-pillars' 3 cards are now single-WYSIWYG, using the
   same shared .terroo-card-heading/.terroo-card-body classes as every
   other card on the site (polaroid, door, mini-cards), replacing the old
   [native heading widget + text-editor widget] pair and its bespoke
   mono/uppercase/rust eyebrow-style title treatment. Confirmed unused
   anywhere else on either page. */

/* Each pillar is now its own card (mini-card treatment: white background,
   thick ink border, hard shadow) instead of a plain stacked/divided list --
   spacing between them is a margin on the wrapping inner-section rather
   than a divider line.
   `.terroo-security-card-row` (set via `_css_classes` on the inner-section
   in the PHP) never actually applied -- confirmed the established finding
   elsewhere in this file that Elementor's section element doesn't render
   `_css_classes` at all, only widgets/columns do. All 3 inner-sections
   render with the same generic `.elementor-inner-section` class instead,
   so the gap is targeted structurally via :not(:last-child) on that. */
/* Figma specs 24px here (was 28px). */
#security-pillars .elementor-inner-section:not(:last-child) {
	margin-bottom: 24px;
}

.terroo-security-card {
	background: var(--color-card-bg);
	border: 2px solid var(--color-ink);
	border-radius: 20px;
	padding: 32px;
	box-shadow: var(--shadow-offset-base) var(--shadow-offset-base) 0 var(--color-ink);
}

/* Same rust/tint treatment as the hero photo -- now also the same 32px
   offset and 8px shadow (was 28px/4px, differentiated from the hero on
   purpose at the time; Figma has since specced them identically).
   height:100% removed -- it stretched this wrapper to match the taller
   pillars column (Elementor's own container defaults to flex
   align-items:stretch), which is what let the img's own height:100% below
   inflate past its actual 1:1 design ratio (Figma node-id=77-97 specs this
   photo as a plain 560x560 square, top-aligned next to the pillars, not
   stretched to match their height). Now sizes to its own content -- i.e.
   whatever the aspect-ratio'd img below actually renders at. */
.terroo-security-photo {
	position: relative;
}

/* `.elementor-widget-wrap.elementor-element-populated`'s own undocumented
   10px top+bottom padding (gotcha #8 in this project's playbook) was
   adding 20px to the COLUMN's own height beyond the image's actual
   height (this column holds a single Image widget with no other
   siblings, so nothing else explains the gap). Since .terroo-security-
   photo::before (the offset frame) is sized off the column's box, not
   the image's, that extra 20px was making the frame extend visibly past
   the photo's actual bottom edge -- same bug/fix as .terroo-hero-image
   elsewhere in this file, just never applied here. Shared by both usages
   of this class (homepage #security-pillars and /securite's
   #securite-hero), fixed once for both. !important: ties Elementor's own
   same-specificity rule and loses the load-order tiebreak otherwise (see
   gotcha #5). */
.terroo-security-photo > .elementor-widget-wrap {
	padding: 0 !important;
}

.terroo-security-photo::before {
	content: '';
	position: absolute;
	top: 32px;
	left: -32px;
	right: 32px;
	bottom: -32px;
	background: var(--color-tint);
	border: 2px solid var(--color-rust);
	border-radius: 4px 120px 4px 120px;
	box-shadow: var(--shadow-offset-lg) var(--shadow-offset-lg) 0 var(--color-rust-deep);
	z-index: 0;
}

/* !important on border/border-radius/object-fit: same recurring issue as
   elsewhere in this file -- this raw <img> (inside a text-editor widget)
   was losing the corner-radius/border to some other default `img` rule
   without it, rendering as a plain square photo instead of matching the
   hero's rounded-corner treatment.
   height/min-height replaced with aspect-ratio: 1/1 (Figma node-id=77-97's
   Security Photo is a fixed 560x560 square) -- the old `height:100%` tied
   this img's height to whatever the parent column happened to be (the
   taller pillars column via flex stretch, see the .terroo-security-photo
   comment above), which floated independently of this img's own width and
   produced a different ratio at every viewport -- 505x520 (0.97) at one
   desktop width tested, a much taller/narrower crop on mobile once the
   column narrowed but that stretched height didn't shrink to match. Same
   fix pattern as .terroo-hero-image img elsewhere in this file: lock the
   ratio, let height follow width. */
.terroo-security-photo img {
	position: relative;
	z-index: 1;
	display: block;
	width: 100% !important;
	height: auto !important;
	aspect-ratio: 1 / 1;
	border: 2px solid var(--color-rust) !important;
	border-radius: 4px 120px 4px 120px !important;
	object-fit: cover !important;
}

@media (max-width: 767px) {
	.terroo-security-photo {
		margin-bottom: 48px;
	}

	.terroo-security-photo::before {
		top: 16px;
		left: -16px;
		right: 16px;
		bottom: -16px;
	}

	.terroo-security-card {
		padding: 24px; /* was 22px, per the site's 8px grid rule */
	}
}

/* ---------- Two doors: deliberate hierarchy, not two identical cards ---------- */
/* #rejoindre / #doors-row carry a native mustard section background (set
   in the PHP build) -- a hard color-block, not a subtle tint, so this beat
   in the page is unmistakably different from the cream sections around it.
   Both doors get the identical bordered/shadowed card treatment (an
   earlier version gave the first door a card and left the second sitting
   bare on the mustard to reflect the copy's "door we open first" framing --
   changed back to matching cards per feedback that they should look the
   same). */
.terroo-section-title--on-mustard,
.terroo-section-title--on-mustard .elementor-heading-title {
	color: var(--color-ink) !important;
}

/* .terroo-door-eyebrow/.terroo-door-title/.terroo-door-text removed -- per
   feedback, the door cards now use bare tags harmonized to the sitewide
   defaults: the eyebrow reuses the standard `.terroo-eyebrow` format (same
   one used everywhere else, instead of a near-duplicate door-specific
   class), the title is a bare `h3`, the text is a bare `p`
   (.elementor-widget-text-editor h3/p further down this file). See the
   `.terroo-door` rule below for the card's own spacing adjustment now that
   its children pull their margins from those shared rules instead of a
   uniform Figma-specced 16px each. */

/* .terroo-door/.terroo-door--primary/.terroo-door--secondary now live on
   the COLUMN (`css_classes`), not an inner wrapper div -- the card's CTA
   used to be a plain `<a class="btn-pill">` typed straight into this same
   raw-HTML block, but per the "buttons are never built in TinyMCE" rule
   it's now a native Button widget, a separate sibling of the text-editor
   widget holding the eyebrow/title/text. Same class-move pattern already
   used for .terroo-hero-image/.terroo-security-photo elsewhere in this
   file, just for a card instead of a photo frame. */
.terroo-door {
	position: relative;
	height: 100%;
	background: var(--color-card-bg);
	border-radius: 4px 32px 4px 32px;
	padding: 32px;
}

/* v2: the two doors are no longer visually identical -- the featured door
   (whichever is first, currently "Je voyage") gets the rust accent, the
   other keeps the original ink accent. */
.terroo-door--primary {
	border: 2px solid var(--color-rust);
	box-shadow: var(--shadow-offset-lg) var(--shadow-offset-lg) 0 var(--color-rust-deep);
}

.terroo-door--secondary {
	border: 2px solid var(--color-ink);
	box-shadow: var(--shadow-offset-lg) var(--shadow-offset-lg) 0 var(--color-ink);
}

/* The text-editor widget and the button widget are now two separate
   siblings inside the card (see comment above .terroo-door) -- Elementor's
   own `.elementor-widget:not(:last-child) { margin-block-end: 20px }`
   default doesn't match the desired gap, so it's replaced with an
   explicit 32px here rather than just zeroed. (It used to be zeroed,
   relying on .terroo-door-text's own 16px margin-bottom to provide the
   gap instead -- but that class is gone now, retired in favor of the
   shared .terroo-card-body class, which is deliberately margin:0 for ITS
   other usages, i.e. polaroid/mini-card/security-pillars, where it's
   either the last element in the card or relies on a flex `gap` instead.
   Door cards are the one card type where Card Body isn't the last
   element -- the button follows -- so this gap has to live here, on the
   widget-to-widget margin, instead of on .terroo-card-body itself. 32px
   (not the original 16px) per feedback, and matches the 8px grid rule. */
.terroo-door > .elementor-widget-wrap > .elementor-widget:not(:last-child) {
	margin-block-end: 32px;
}

@media (max-width: 767px) {
	.terroo-door {
		padding: 24px;
	}
}

/* ---------- Wrap-up mini-cards (contact + stories teaser) ---------- */
/* These replaced two isolated single lines of centered text floating in
   huge empty sections -- the actual complaint was how sparse/weak that
   stretch of the page felt next to the bold sections around it. Reusing
   the door's white-card/hard-shadow language instead of inventing a new
   one keeps it feeling like part of the same system. */
.terroo-mini-card {
	position: relative;
	height: 100%;
	background: var(--color-card-bg);
	border: 2px solid var(--color-ink);
	border-radius: 24px;
	padding: 32px; /* was 36px, per the site's 8px grid rule -- also now matches .terroo-door's own padding */
	box-shadow: var(--shadow-offset-base) var(--shadow-offset-base) 0 var(--color-ink);
}

/* .terroo-mini-card-text removed -- per feedback, the mini-cards' body
   copy is now a bare `p`, harmonized to the sitewide default
   (.elementor-widget-text-editor p further down this file). */

/* #securite-precautions .terroo-mini-card .terroo-pillar-title removed --
   per feedback, each mini-card is now a single WYSIWYG widget (title +
   text) using the new "Card Heading" TinyMCE format
   (h3.terroo-card-heading, styled near .terroo-card's own polaroid title
   above) instead of a raw <h4 class="terroo-pillar-title">, so there's no
   longer a mismatched eyebrow-label style here to override. */

.terroo-mini-card-badge {
	position: absolute;
	top: -18px;
	right: 24px;
	/* was var(--color-mustard) -- never defined in :root, a leftover from
	   the pre-"v2 palette" mustard/teal era (confirmed unused in any live
	   page's content, so currently dead CSS, but should still resolve to a
	   valid color); fixed to the redesign's one accent color. */
	background: var(--color-rust);
	border: 2px solid var(--color-ink);
	border-radius: 999px;
	padding: 6px 16px;
	font-family: var(--font-mono);
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	color: var(--color-ink);
	transform: rotate(4deg);
}

/* .btn-pill-sm removed -- its only usage sitewide was the
   "experiences-link" CTA ("Voir comment ça marche →"), which per feedback
   ("this button should be bigger and centered") now reuses the standard
   .btn-pill style instead of a bespoke smaller variant, so there was
   nothing left referencing this class. Centering itself is handled by the
   Button widget's own native "align" control (settings.align = 'center'),
   not a CSS rule -- no hardcoded alignment needed. */

/* Manifesto quote: broken out of the centered mold -- left-aligned, an
   oversized quotation glyph standing in the margin, generous negative space
   to the right instead of a symmetric block of italic text. */
.terroo-quote-col {
	position: relative;
	max-width: 820px;
	padding-left: 64px;
}

.terroo-quote-col::before {
	content: '\201C';
	position: absolute;
	top: -0.4em;
	left: -0.08em;
	font-family: var(--font-serif);
	font-size: 180px;
	line-height: 1;
	/* v2: muted greige instead of mustard -- the quote mark is the one
	   place --color-highlight is used. */
	color: var(--color-highlight);
	opacity: 0.55;
	pointer-events: none;
}

/* Compound `.elementor-widget-text-editor p.terroo-quote` (0,2,1) added
   alongside the plain class -- since the "harmonize paragraph styles
   sitewide" pass, a bare `.terroo-quote` (0,1,0) would otherwise lose to
   `.elementor-widget-text-editor p` (0,1,1) despite the class living
   directly on the <p> tag itself. */
.terroo-quote,
.elementor-widget-text-editor p.terroo-quote {
	font-family: var(--font-serif);
	font-style: italic;
	font-size: clamp(26px, 3.4vw, 40px);
	line-height: 1.35;
	text-align: left;
	margin: 0 0 24px !important;
	color: var(--color-bg);
}

/* `.terroo-quote` above is a `<p>` *inside* the raw-HTML text-editor
   widget, not the widget itself -- same layered pattern as the pillar
   title/wrapper fix below. The outer widget div, having the attribution
   widget as a following sibling, independently carries Elementor's own
   `.elementor-widget:not(:last-child)` 20px margin-bottom. Unlike the
   pillar title (where the wrapper/child margins collapsed), these two
   don't collapse here -- flex-item children don't collapse margins with
   their own content the same way block children do -- so the two 20+24
   were stacking into a 44px gap instead of the intended 24px. Zeroing the
   wrapper removes it from the sum entirely. */
.terroo-quote-col .elementor-widget:not(:last-child) {
	margin-bottom: 0 !important;
}

.terroo-quote-attr {
	text-align: left;
	display: block;
	color: var(--color-bg);
}

@media (max-width: 767px) {
	.terroo-quote-col {
		padding-left: 32px;
	}

	.terroo-quote-col::before {
		font-size: 100px;
	}
}

/* v2: dictionary section moved from a dark teal block with a mustard glow
   to a light tint background matching the doors section, so the radial
   "stain" (mustard-on-teal) and the cream-on-dark text no longer apply --
   text now reads dark-on-light like the rest of the page. */
#dictionary {
	position: relative;
}

#dictionary > .elementor-container {
	position: relative;
	z-index: 1;
}

/* v3: dropped .terroo-dictionary-word / .terroo-dictionary-phonetic /
   .terroo-dictionary-def -- per the user's explicit "no hardcode"
   instruction, this section no longer carries any bespoke classes. The
   title is a bare <h2> (the theme/kit's own default H2 style), the
   phonetic term reuses the existing "Eyebrow" TinyMCE format
   (<p class="terroo-eyebrow">, styled at its own sitewide rule further up
   this file), and the definition is a bare <p> ("Paragraph" format) --
   all three now read from shared, reusable styles instead of one-off
   classes that existed only for this single section. */

/* Definition paragraph narrowed to 560px per feedback (400px, then 540px,
   then 560px per the site's 8px grid rule -- 540 isn't a multiple of 8)
   -- scoped to this section specifically (not a change to the shared
   bare-`p` default further down this file, which every other harmonized
   paragraph sitewide also reads from). margin auto centers the
   now-narrower box itself; .terroo-centered-text's own text-align:center
   only centers the text *inside* the paragraph's box, not the box within
   its column. */
#dictionary .elementor-widget-text-editor p:not(.terroo-eyebrow) {
	max-width: 560px;
	margin-left: auto;
	margin-right: auto;
}

/* .terroo-closing-heading removed -- per feedback, the newsletter band's
   heading is now a bare `h2`, harmonized to the sitewide default
   (.elementor-widget-text-editor h2 further down this file). Confirmed
   unused anywhere else on either page (the "closing CTA section" heading
   widget this comment used to also describe no longer exists on the live
   site). */

.terroo-centered-text {
	text-align: center;
}

.terroo-centered-row .elementor-widget-wrap {
	display: flex;
	flex-wrap: wrap;
	gap: 16px;
	align-items: center;
	justify-content: center;
}

/* Brought in line with the rest of the page's language: thick border +
   hard offset shadow (like the doors/mini-cards/buttons) instead of a
   plain soft-edged dark box, plus the same tilted sticker badge used on
   the hero. Before this it was the one block still carrying the old
   soft/subtle styling from an earlier pass. */
/* No `overflow: hidden` here -- the sticker badge below is deliberately
   positioned partly outside the box (like the hero photo's badge), and
   hiding overflow would clip it. The glow's bounds are kept inside the box
   instead (no negative offsets) so it doesn't need clipping either. */
/* v2: flipped from a dark ink band to a light card-bg band (rust border +
   rust-deep shadow instead of mustard border + rust shadow), matching the
   hero/security offset-panel treatment instead of standing out as the
   page's one dark block. */
.terroo-newsletter-band {
	position: relative;
	background: var(--color-card-bg);
	border: 2px solid var(--color-rust);
	border-radius: 4px 56px 4px 56px;
	padding: 80px 56px;
	text-align: center;
	box-shadow: var(--shadow-offset-lg) var(--shadow-offset-lg) 0 var(--color-rust-deep);
}

/* Was a `.terroo-newsletter-band::after` pseudo-element with the badge text
   baked into CSS `content:` -- per feedback, converted to a real Polylang
   string (rendered via terroo_str() in functions.php) output through
   `[terroo_newsletter_badge]`. Per feedback, rebuilt to match the hero
   badge's own construction exactly: a plain `<span class="terroo-
   newsletter-badge">` inside a dedicated Text Editor widget (a sibling of
   the heading/form widgets), not a standalone Shortcode-type widget with
   the class on the widget div itself -- same markup shape as
   .terroo-hero-badge above, so this rule needs no !important fights
   against Elementor's own widget-type defaults (see the
   .terroo-newsletter-band > .elementor-widget-wrap > .elementor-widget-
   text-editor:first-child rule below for the one positioning-context
   reset this still needs, same as the hero's own text-editor:first-child
   reset). */
.terroo-newsletter-badge {
	position: absolute;
	top: -32px; /* was -30px, per the site's 8px grid rule -- also now matches the -32px offset used by every other photo/badge frame in this file */
	left: 40px;
	z-index: 2;
	/* 108px, matching .terroo-hero-badge's own size exactly (was 96px) --
	   per feedback, the two "sticker" badges should be built and sized the
	   same way. */
	width: 108px;
	height: 108px;
	border-radius: 50%;
	background: var(--color-card-bg);
	border: 2px solid var(--color-rust);
	display: flex;
	align-items: center;
	justify-content: center;
	text-align: center;
	font-family: var(--font-mono);
	font-size: 9px;
	font-weight: 700;
	letter-spacing: 0.02em;
	text-transform: uppercase;
	color: var(--color-rust);
	line-height: 1.4;
	padding: 16px; /* was 12px, per the site's 8px grid rule */
	transform: rotate(8deg);
}

/* Badge widget's own containing block needs to be .terroo-newsletter-band
   itself (position:relative, declared above), not this specific widget's
   own box -- same gotcha and same fix as .terroo-hero-image's own
   `> .elementor-widget-wrap > .elementor-widget-text-editor` reset:
   Elementor's core `.elementor-widget { position: relative }` default
   sits closer in the DOM and wins otherwise. :first-child scopes this to
   just the badge widget, not the band's other text-editor widget (the
   heading/intro). */
.terroo-newsletter-band > .elementor-widget-wrap > .elementor-widget-text-editor:first-child {
	position: static;
}

@media (max-width: 767px) {
	/* Shrunk (76px -> 84px, matching .terroo-hero-badge's own mobile size --
	   was 64px) and pulled further up/out (-20px -> -32px, also now
	   matching the -32px offset every other photo/badge frame in this file
	   uses) per feedback -- reduces how far the badge's own bottom edge
	   reaches into the band, which is what let .terroo-newsletter-band's
	   mobile padding-top come down from 80px to 48px below instead of
	   needing that much clearance. Padding tightened to match the smaller
	   circle (16px would leave too little text width). */
	.terroo-newsletter-badge {
		width: 84px;
		height: 84px;
		top: -32px;
		left: 24px;
		font-size: 7px;
		padding: 8px;
	}
}

.terroo-newsletter-band > * {
	position: relative;
}

/* .terroo-newsletter-band now lives on the COLUMN (`css_classes`), not an
   inner wrapper div -- the CF7 form used to be raw HTML (the plugin's own
   shortcode output, hand-pasted) typed straight into this same Text Editor
   widget, but per the "fields are never built in TinyMCE" rule it's now
   Elementor's native Shortcode widget rendering `[contact-form-7 ...]`, a
   separate sibling of the text-editor widget holding the heading/intro.
   Same class-move + gap-neutralization pattern as .terroo-door above:
   Elementor's own `.elementor-widget:not(:last-child) { margin-block-end:
   20px }` default would otherwise stack on top of .wpcf7-form's own
   `margin: 28px auto 0` top margin, so it's cancelled here, leaving that
   28px as the sole source of the heading/intro-to-form gap. */
.terroo-newsletter-band > .elementor-widget-wrap > .elementor-widget:not(:last-child) {
	margin-block-end: 0;
}

/* Audit fix: `.elementor-widget-wrap.elementor-element-populated`'s own
   undocumented 10px padding (gotcha #8 in this project's playbook) was
   adding 10px on top of the band's real 80px top/bottom padding on both
   edges -- measured 92px from the band's outer edge to the heading/from
   the form to the band's bottom, instead of the intended 80px (the
   remaining 2px is the band's own border, correctly part of the box
   edge, not extra). Zeroed here so the wrap no longer contributes its
   own padding inside the band's real one.
   position: static -- the badge widget's containing block needs to be
   .terroo-newsletter-band itself (position:relative, declared above), but
   this wrap's own default `position: relative` (Elementor core) sits
   closer in the DOM and was winning instead (same gotcha as the hero's
   scroll-cue elsewhere in this file -- confirmed live: offsetParent was
   this wrap, badge rendered full-width instead of a 96x96 circle).
   Nothing else in this column relies on the wrap being a positioning
   context. */
.terroo-newsletter-band > .elementor-widget-wrap {
	padding: 0 !important;
	position: static;
}

/* Audit fix: the intro paragraph is now a bare `<p>`, so it carries the
   harmonized sitewide default's own 16px margin-bottom -- which stacked
   on top of `.wpcf7-form`'s own intentional `margin: 28px auto 0` top
   margin below, widening the intro-to-form gap to 44px instead of the
   intended 28px. Zeroed here so the form's own margin is the only
   contributor, same fix pattern as elsewhere in this file. */
.terroo-newsletter-band .elementor-widget-text-editor p:last-child {
	margin-bottom: 0;
}

/* .terroo-newsletter-band .terroo-closing-heading / .terroo-body-lg
   overrides removed -- both the heading and intro are now bare h2/p
   (harmonized, see the h2/p removal notes above), so there's no longer a
   class here for these selectors to match. The heading's ink color and
   centering already come for free: harmonized `.elementor-widget-text-editor
   h2` already defaults to ink, and `.terroo-newsletter-band` itself sets
   `text-align: center`, which the bare `<p>` naturally inherits. The one
   real loss is the intro's taupe color (was a deliberate secondary-text
   treatment) -- it now reads ink like every other harmonized paragraph,
   per the "abandon specific classes" instruction. */

.terroo-newsletter-band .wpcf7-form {
	max-width: 420px;
	margin: 32px auto 0; /* was 28px, per the site's 8px grid rule */
	display: flex;
	gap: 8px; /* was 10px, per the site's 8px grid rule */
	flex-wrap: wrap;
	justify-content: center;
}

.terroo-newsletter-band .wpcf7-form-control-wrap {
	flex: 1 1 240px;
}

/* CF7 wraps the email field + submit button in its own <p> tag (not
   something this theme's markup controls -- it's plugin-generated), which
   was never targeted anywhere in this file and so still carried the
   browser's own default paragraph margin (~17px top+bottom at this font
   size). That extra margin was the real source of the band's bottom
   padding reading bigger than the top -- ~17px added below the submit
   button, on top of the band's own real 80px padding, with no matching
   addition above (the form's own `margin: 32px auto 0` already accounts
   for the top gap intentionally). Zeroed so `.wpcf7-form`'s own layout is
   the only thing governing spacing here. */
.terroo-newsletter-band .wpcf7-form p {
	margin: 0;
	position: relative; /* anchors .wpcf7-spinner below, once it's taken out of flow */
}

/* CF7's own loading spinner (shown briefly during actual AJAX submission,
   otherwise invisible) sits right after the submit button inside that
   same <p>, as a normal inline-block flow element -- meaning it still
   reserves its own ~24px of height even while invisible, which was the
   second, smaller contributor to the band's bottom padding reading
   bigger than the top (after the <p>'s own default margin, fixed above).
   Taken out of flow entirely via absolute positioning so it no longer
   affects the <p>'s height; still renders in roughly the same spot,
   centered just below the button, when CF7 actually shows it. */
.terroo-newsletter-band .wpcf7-spinner {
	position: absolute;
	top: 100%;
	left: 50%;
	transform: translateX(-50%);
	margin: 8px 0 0;
}

/* Thick border + hard offset shadow, matching the buttons/mini-cards/doors
   everywhere else on the page instead of a soft translucent pill. */
.terroo-newsletter-band input[type='email'] {
	width: 100%;
	padding: 16px 16px; /* was 12px 16px, per the site's 8px grid rule */
	border-radius: 999px;
	border: 2px solid var(--color-border);
	background: var(--color-white);
	color: var(--color-ink);
	font-family: var(--font-sans);
	font-weight: 600;
	font-size: 16px;
}

.terroo-newsletter-band input[type='email']::placeholder {
	color: var(--color-border);
}

.terroo-newsletter-band input[type='submit'] {
	display: block;
	margin: 16px auto 0; /* was 14px, per the site's 8px grid rule */
	padding: 16px 24px; /* was 14px 24px, per the site's 8px grid rule */
	border-radius: 999px;
	border: 2px solid var(--color-ink);
	background: var(--color-rust);
	color: var(--color-white);
	font-family: var(--font-sans);
	font-weight: 800;
	font-size: 15px;
	cursor: pointer;
	box-shadow: var(--shadow-offset-base) var(--shadow-offset-base) 0 var(--color-ink);
	transition: transform 0.12s ease, box-shadow 0.12s ease;
}

.terroo-newsletter-band input[type='submit']:hover {
	transform: translate(var(--shadow-offset-sm), var(--shadow-offset-sm));
	box-shadow: var(--shadow-offset-sm) var(--shadow-offset-sm) 0 var(--color-ink);
}

/* Standing rule for every CF7 form on the site, not just this one: CF7's
   own default response box/field-error styling is a bare browser-style
   green/red bordered rectangle plus plain red field-level text --
   completely off-brand next to the site's pill buttons and hard-shadow
   cards. Themed HERE, as a sitewide default on the bare `.wpcf7-*`
   classes (not scoped to `.terroo-newsletter-band`), so any NEW form
   built on this site inherits it automatically instead of needing this
   fix copy-pasted again -- confirmed this was previously scoped to just
   the newsletter band and had to be re-added for the contact form; don't
   repeat that. !important on border/background: overrides CF7's own
   inline-ish default border-color, same recurring issue as gotcha #5 in
   this project's playbook. */
.wpcf7-response-output {
	color: var(--color-ink);
	max-width: 420px;
	margin: 16px auto 0 !important; /* CF7's own `.wpcf7 form .wpcf7-response-output` rule (extra `form` element) outranks both this and padding below on specificity otherwise */
	padding: 16px 24px !important;
	background: var(--color-card-bg) !important;
	border: 2px solid var(--color-rust) !important; /* neutral fallback -- real submissions always add .wpcf7-mail-sent-ok or one of the error classes below, which override this */
	border-radius: 16px;
	box-shadow: var(--shadow-offset-base) var(--shadow-offset-base) 0 var(--color-ink);
	font-family: var(--font-sans);
	font-weight: 600;
	font-size: 15px;
	line-height: 1.5;
	text-align: center;
}

.wpcf7-response-output.wpcf7-mail-sent-ok {
	border-color: var(--color-success) !important;
}

.wpcf7-response-output.wpcf7-validation-errors,
.wpcf7-response-output.wpcf7-spam-blocked,
.wpcf7-response-output.wpcf7-mail-failed,
.wpcf7-response-output.wpcf7-aborted {
	border-color: var(--color-rust-deep) !important;
}

/* Per-field validation tips (the small text CF7 drops under an invalid
   field) -- default is plain red browser-style text with no relationship
   to the site's own type/color system. */
.wpcf7-not-valid-tip {
	display: block;
	margin-top: 6px;
	color: var(--color-rust-deep) !important;
	font-family: var(--font-sans);
	font-weight: 600;
	font-size: 13px;
}

/* CF7 marks an invalid field with this class -- give it the same rust-deep
   accent as the tip below it instead of the browser's own default red
   outline, so the two read as one connected error state. */
.wpcf7-form-control.wpcf7-not-valid {
	border-color: var(--color-rust-deep) !important;
}

.terroo-micro {
	font-size: 13px;
	color: var(--color-taupe);
	text-align: center;
	margin: 16px 0 0;
}

.terroo-newsletter-band .terroo-micro {
	color: var(--color-taupe);
	opacity: 0.8;
}

@media (max-width: 767px) {
	.terroo-door {
		padding: 24px; /* was 28px, per the site's 8px grid rule */
	}

	/* padding-top specifically (not the shorthand's old flat 36px): the
	   ::after badge is absolutely positioned at `top: -32px` with a 64px
	   height (see the mobile override above, shrunk per feedback), so its
	   bottom edge now sits only 32px into the box (was 56px before the
	   badge shrink). 36px of top padding would just barely clear it with
	   ~4px to spare -- bumped to 48px for a bit more breathing room,
	   instead of the old 80px this used to need. Much closer to the 40px
	   bottom now (was an 44px top/bottom gap, now 8px) without adding
	   pointless empty space the way just matching bottom-to-top would
	   have. Bottom bumped 36px -> 40px too, onto the 8px grid. */
	.terroo-newsletter-band {
		padding: 48px 24px 40px;
	}
}

/* ---------- Secondary-page hero ---------- */
/* A deliberately distinct component from #hero -- NOT a shared-selector
   mirror of the homepage hero. Built to match Figma node-id=154-182
   exactly: tint background, photo column FIRST (left, ~1/3) with the
   offset-panel photo treatment, text column SECOND (right, ~2/3), no CTA
   buttons, flat 80px padding on all sides (not stacked on top of the
   site's standard section-rhythm padding). Reuses .terroo-hero-heading
   for the title (unchanged) and .terroo-security-photo -- the same
   offset-panel/hard-shadow photo component already built for this page's
   trust section, which happens to be pixel-for-pixel the same treatment
   Figma specs for this hero's photo (asymmetric 4px/120px corner radius,
   rust border, offset tint panel behind with a hard shadow) -- rather
   than the homepage's plain rounded-rect .terroo-hero-image. */
/* #ccm-hero (the "Comment ça marche" page's hero) reuses this exact
   component now too -- per feedback, it should look identical to
   #securite-hero (same photo-left/text-right treatment, tint band, no CTA
   buttons), just with its own copy. Every selector below is shared between
   the two ids rather than duplicated. #local-hero joined the same group
   later (the "Local" page's hero) -- CTA button included this time (a
   plain .btn-pill widget added as content, not a new layout). */
#securite-hero,
#ccm-hero,
#local-hero {
	position: relative;
	overflow: visible; /* .terroo-security-photo's offset panel extends past the image's own box */
	background: var(--color-tint-deep); /* was var(--color-tint)/#f0e3d6 -- merged into the page's one cream tint per feedback */
	padding-top: 80px;
	padding-bottom: 120px; /* 80px + 40px per feedback */
}

#securite-hero > .elementor-container,
#ccm-hero > .elementor-container,
#local-hero > .elementor-container {
	position: relative;
	z-index: 1;
	align-items: center;
	column-gap: 80px;
	max-width: var(--container-max);
	margin: 0 auto;
	padding: 0 40px;
}

/* Figma: 400px photo / 800px text on a 1280px container (1:2 ratio),
   with an 80px gap between. Expressed as a normalized 33.33%/66.67% split
   (the two content columns' own ratio, gap excluded) with half the gap
   (40px) subtracted from each column's share -- same additive-column-gap
   fix used elsewhere in this file -- so the two sum to exactly 100%
   including the gap, at any container width, not just exactly 1280px. */
#securite-hero > .elementor-container > .elementor-column:first-child,
#ccm-hero > .elementor-container > .elementor-column:first-child,
#local-hero > .elementor-container > .elementor-column:first-child {
	width: calc(33.3333% - 40px) !important;
	flex: 0 0 calc(33.3333% - 40px) !important;
	max-width: calc(33.3333% - 40px) !important;
}

#securite-hero > .elementor-container > .elementor-column:last-child,
#ccm-hero > .elementor-container > .elementor-column:last-child,
#local-hero > .elementor-container > .elementor-column:last-child {
	width: calc(66.6667% - 40px) !important;
	flex: 0 0 calc(66.6667% - 40px) !important;
	max-width: calc(66.6667% - 40px) !important;
}

/* Same 20px/taupe body treatment #hero uses, kept as this component's own
   rule rather than reusing #hero's selector -- the two are deliberately
   no longer linked (see the component comment above). */
/* font-size/color harmonized onto the shared .terroo-body-lg rule now --
   only the margin-bottom fix (same Elementor inter-widget default as
   #hero's copy of this) still needs to live here. */
#securite-hero .terroo-body-lg,
#ccm-hero .terroo-body-lg,
#local-hero .terroo-body-lg {
	margin-bottom: 0;
}

#securite-hero .terroo-body-lg p,
#ccm-hero .terroo-body-lg p,
#local-hero .terroo-body-lg p {
	margin: 0;
}

/* #local-hero is the one usage of this component with a button after the
   intro paragraph, so the paragraph's own margin-bottom:0 above (meant for
   when it's the last widget) would leave the button flush against it --
   restore a gap just for that one extra widget. 40px (was 24px) per
   feedback -- the original gap read as too tight against the button. */
#local-hero .terroo-body-lg {
	margin-bottom: 40px !important;
}

/* Per feedback: tighter gap between the eyebrow and the title below it, at
   every breakpoint (not just mobile) -- the eyebrow is the text column's
   first widget, so Elementor's own `.elementor-widget:not(:last-child) {
   margin-block-end: 20px }` default (two selectors' worth of specificity)
   is what's currently producing that gap; needs `!important` to beat it. */
#securite-hero > .elementor-container > .elementor-column:last-child > .elementor-widget-wrap > .elementor-widget:first-child,
#ccm-hero > .elementor-container > .elementor-column:last-child > .elementor-widget-wrap > .elementor-widget:first-child,
#local-hero > .elementor-container > .elementor-column:last-child > .elementor-widget-wrap > .elementor-widget:first-child {
	margin-bottom: 8px !important;
}

@media (max-width: 767px) {
	#securite-hero,
	#ccm-hero,
	#local-hero {
		padding-top: 40px;
		padding-bottom: 40px;
	}

	#securite-hero > .elementor-container,
	#ccm-hero > .elementor-container,
	#local-hero > .elementor-container {
		column-gap: 0;
		row-gap: 0; /* .terroo-security-photo's own margin-bottom:48px handles the stack gap */
		flex-direction: column;
		flex-wrap: nowrap;
		padding: 0 20px;
	}

	#securite-hero > .elementor-container > .elementor-column:first-child,
	#securite-hero > .elementor-container > .elementor-column:last-child,
	#ccm-hero > .elementor-container > .elementor-column:first-child,
	#ccm-hero > .elementor-container > .elementor-column:last-child,
	#local-hero > .elementor-container > .elementor-column:first-child,
	#local-hero > .elementor-container > .elementor-column:last-child {
		width: 100% !important;
		flex: 1 1 100% !important;
		max-width: 100% !important;
	}

	/* Per feedback: more air between the photo and the eyebrow below it on
	   mobile -- these compound selectors (1 id + 1 class) already outrank
	   the base `.terroo-security-photo { margin-bottom: 48px; }` mobile
	   rule above on specificity alone, so no !important/source-order fight
	   needed. Scoped to just these two heroes rather than the shared class
	   itself, since `.terroo-security-photo` is also used by the
	   homepage's #security-pillars, which isn't part of this request. */
	#securite-hero .terroo-security-photo,
	#ccm-hero .terroo-security-photo,
	#local-hero .terroo-security-photo {
		margin-bottom: 64px;
	}
}

/* ---------- Centered no-photo hero (Manifeste/Manifesto, Contact,
   Legal Notice[s], Terms of Service) ---------- */
/* One shared component, not near-duplicates -- per feedback, an earlier
   pass had #manifeste-hero (its own 80px padding + a distinct
   --color-tint-deep) and #contact-hero (the standard --section-pad via
   the shared padding list a bit above, plus plain --color-tint) as two
   almost-but-not-quite-identical implementations of the same "centered,
   no photo, one .terroo-content-col widget" hero, then a new #legal-hero
   copied #contact-hero's background/text-align but never got added to
   that shared padding list at all (rendered with zero padding as a
   result). All of these now use the exact same background, padding (via
   the shared list above), and centering -- single column: eyebrow,
   .terroo-hero-heading (reused as-is; sets no text-align of its own, so
   it centers purely by inheriting this rule's text-align:center), and an
   optional intro paragraph, all as one .terroo-content-col WYSIWYG widget.
   Legal Notice[s]/Terms of Service just omit the intro paragraph -- not a
   variant, simply that page's own content having one fewer element in
   the same widget. */
#manifeste-hero,
#contact-hero,
#legal-hero,
#terms-hero {
	background: var(--color-tint);
	text-align: center;
}

#manifeste-hero .terroo-content-col,
#contact-hero .terroo-content-col,
#legal-hero .terroo-content-col,
#terms-hero .terroo-content-col {
	margin-left: auto;
	margin-right: auto;
}

/* Intro paragraph narrower than the section's own 720px content-col cap --
   matches the screenshot's noticeably tighter, centered two-line intro,
   same technique as #dictionary's definition-width fix earlier this
   session (max-width + margin auto on the specific bare <p>, not the
   whole content-col). N/A on #legal-hero/#terms-hero (no intro paragraph
   there), but harmless to include since the selector simply never matches
   anything. */
#manifeste-hero .elementor-widget-text-editor p:not(.terroo-eyebrow),
#contact-hero .elementor-widget-text-editor p:not(.terroo-eyebrow),
#legal-hero .elementor-widget-text-editor p:not(.terroo-eyebrow),
#terms-hero .elementor-widget-text-editor p:not(.terroo-eyebrow) {
	max-width: 560px;
	margin-left: auto;
	margin-right: auto;
}

/* No scoped override needed here anymore -- .terroo-body-lg's shared rule
   now covers font-size/color for every usage sitewide (was briefly 24px
   here specifically, reverted as part of harmonizing back to the one
   shared value every other .terroo-body-lg uses). This paragraph also
   needs no margin-bottom fix unlike #hero/#securite-hero's copies of that
   -- it lives inside .terroo-content-col, whose own `> *:last-child`
   reset already zeroes it. Mobile padding is now handled by the shared
   list at the top of this file (`--section-pad-mobile`), same as
   #contact-hero/#legal-hero -- no page-specific override needed here
   anymore. */

/* ---------- Manifeste page closing band ---------- */
#manifeste-closing {
	text-align: center;
}

#manifeste-closing .terroo-content-col {
	margin-left: auto;
	margin-right: auto;
	margin-bottom: 32px;
}

/* Per feedback: the two buttons weren't reading as a tight, aligned pair
   -- each Button widget's own `align:center` setting only centers it
   WITHIN its own column, and with two equal 50%-width columns that put
   ~370px of column width around each button instead of grouping them
   together, leaving a large dead gap between them. Fixed by sizing each
   column to its own content (`width: auto`) and centering the ROW itself
   instead of each button independently -- the buttons now sit directly
   next to each other with a deliberate 16px gap, centered as one group. */
#manifeste-closing-buttons > .elementor-container {
	justify-content: center;
	column-gap: 16px;
	row-gap: 16px;
}

#manifeste-closing-buttons > .elementor-container > .elementor-column {
	width: auto !important;
	flex: 0 0 auto !important;
	max-width: 100% !important;
}

/* Each column's own `.elementor-widget-wrap.elementor-element-populated`
   10px default padding (gotcha #8) was adding 20px on top of the 16px
   column-gap above -- 36px measured instead of 16px. Zeroed so the gap
   is exactly what's declared. */
#manifeste-closing-buttons > .elementor-container > .elementor-column > .elementor-widget-wrap {
	padding: 0 !important;
}

@media (max-width: 767px) {
	#manifeste-closing-buttons > .elementor-container {
		flex-direction: column;
		align-items: center;
	}

	#manifeste-closing-buttons > .elementor-container > .elementor-column {
		width: 100% !important;
		flex: 1 1 100% !important;
	}
}

/* Per feedback: halve the gap between consecutive "Partie N" sections
   specifically -- NOT the hero-to-first or last-to-closing gaps, which
   aren't between two Partie sections and stay at the site's standard
   var(--section-pad)/var(--section-pad-mobile). Sections carry no margin
   between them (confirmed elsewhere in this file) -- the visible gap
   between two consecutive sections is simply sectionA's own bottom
   padding + sectionB's own top padding (112px + 112px = 224px desktop,
   56px + 56px = 112px mobile). Halving that total means each side becomes
   56px (desktop) / 28px (mobile) instead of 112px/56px -- so each
   "inner" edge (an origine/pourquoi/croyance/qui/besoin side that faces
   ANOTHER Partie section) is overridden, while the two "outer" edges
   (origine's top, facing the hero; contemplons's bottom, facing the
   closing band) are deliberately left at the full, unhalved value.
   Single-ID selectors here tie the shared padding list's own specificity,
   so this only wins because it's positioned later in the file -- keep it
   below that list. */
#manifeste-origine {
	padding-bottom: 56px;
}

#manifeste-pourquoi,
#manifeste-croyance,
#manifeste-qui,
#manifeste-besoin {
	padding-top: 56px;
	padding-bottom: 56px;
}

#manifeste-contemplons {
	padding-top: 56px;
}

@media (max-width: 767px) {
	#manifeste-origine {
		padding-bottom: 28px;
	}

	#manifeste-pourquoi,
	#manifeste-croyance,
	#manifeste-qui,
	#manifeste-besoin {
		padding-top: 28px;
		padding-bottom: 28px;
	}

	#manifeste-contemplons {
		padding-top: 28px;
	}
}

/* ---------- "Comment ça marche" page ---------- */
/* The `.accent` italic-rust word treatment (built for #hero's title) is
   reused across this page's own section titles too ("Simple,
   *intentionnellement*.", etc.) -- same rule, just no longer scoped only
   to `.terroo-hero-heading`. */
.terroo-section-title .accent {
	font-style: italic;
	font-weight: 400;
	color: var(--color-rust);
}

/* Section 1 (#ccm-hero) is identical to /securite's own hero component --
   see the shared #securite-hero/#ccm-hero rules above (per feedback: this
   page's hero should look exactly like /securite's, no CTA buttons). No
   new CSS needed for it here. */

/* ---- Section 2: "Simple, intentionnellement." -- 3 numbered polaroid cards ---- */
/* Reuses .terroo-card (the homepage's native image-box "polaroid" widget)
   as-is for the photo/title/description frame -- only the numeral and the
   plain (non-staggered, non-tilted) 3-up grid are new, since #cards-grid's
   own scrapbook stagger/tilt is scoped to that specific id and doesn't
   leak in here. */
#ccm-steps-grid {
	counter-reset: ccm-step;
}

#ccm-steps-grid .elementor-column {
	counter-increment: ccm-step;
}

/* Numeral sits as the first item in the polaroid's own flex-column caption
   (.elementor-image-box-content, gap:16px) -- inserting it here (rather
   than into title_text, which Elementor escapes as plain text with no room
   for its own styled span) keeps the numeral and the title as genuinely
   separate, independently-styled pieces. decimal-leading-zero matches this
   site's existing "#1"/"#2" door-card numbering convention, just zero-padded
   per the Figma "01/02/03" spec for this component. */
#ccm-steps-grid .elementor-image-box-content::before {
	content: counter(ccm-step, decimal-leading-zero);
	display: block;
	font-family: var(--font-serif);
	font-size: 24px; /* was 40px, per feedback -- read oversized against the "Découvrir" title below it */
	font-weight: 600;
	color: var(--color-rust);
	line-height: 1;
}

@media (min-width: 1025px) {
	#ccm-steps-grid .elementor-container {
		flex-wrap: wrap;
		row-gap: 48px;
	}

	#ccm-steps-grid .elementor-column {
		width: 33.333% !important;
		max-width: 33.333% !important;
		flex: 0 0 33.333% !important;
	}
}

@media (max-width: 1024px) {
	#ccm-steps-grid .elementor-container {
		row-gap: 40px;
	}
}

/* Per feedback: the eyebrow numeral and the card heading should sit on the
   SAME line ("01  Partager un repas"), not stacked. Both are ordinary
   block-level tags (p/h3) rendered as plain siblings inside the same
   WYSIWYG widget, so switching both to `inline-block` lets them flow like
   text -- the eyebrow's own right margin becomes the gap between them
   (replacing the earlier stacked-layout bottom-margin tightening), and
   `vertical-align: middle` keeps the small mono numeral visually centered
   against the much taller serif heading instead of sitting on its
   baseline. `#id .class` (1 id + 1 class) still outranks the sitewide
   `.elementor-widget-text-editor p.terroo-eyebrow` rule (0 id + 2 classes +
   1 tag) on specificity alone. */
#ccm-moments-list .terroo-eyebrow,
#ccm-trust-grid .terroo-eyebrow {
	display: inline-block;
	margin: 0 12px 0 0;
	line-height: 1; /* the sitewide .terroo-eyebrow rule sets no line-height of its own, so it was inheriting the page's ~1.5 -- a taller line box than the "01" glyph itself needs */
	vertical-align: middle;
	/* `vertical-align: middle` aligns an inline box's own midpoint against a
	   point derived from the PARENT's font metrics, not the sibling h3's --
	   with a 12px mono eyebrow next to a 24px serif heading, that anchor
	   point doesn't land where the two visually read as "aligned", leaving
	   the eyebrow sitting ~8px low. Calibrated pixel nudge instead of
	   fighting inline vertical-align further -- confirmed live via
	   getBoundingClientRect() that this exact pairing is 8px off, matching
	   the note elsewhere in this file that vertical-align/inline-block
	   metrics need live measurement, not guessing. */
	position: relative;
	top: -8px;
}

#ccm-moments-list .terroo-card-heading,
#ccm-trust-grid .terroo-card-heading {
	display: inline-block;
	vertical-align: middle;
}

/* ---- Section 3: "Ce que chaque rencontre est vraiment." -- 6 photo/text rows ---- */
/* New template: one plain rounded photo + one text-editor (eyebrow + card
   heading + card body, same shared classes every other card on the site
   uses) per row, stacked with a divider -- not a card/box treatment like
   .terroo-card or .terroo-security-card, a plainer editorial layout to
   keep 6 consecutive rows from reading as heavy. */
/* Background driven purely by CSS (var(--color-tint-deep), the same
   variable #securite-hero/#ccm-hero and #ccm-closing use) rather than
   Elementor's own native background-color setting -- that setting can't
   reference a CSS variable at all, so keeping it there would mean either
   a second hand-typed hex (drift risk, which is exactly how this section
   ended up on `#ebdfd4` instead of the hero's actual `#ede1d4` in the
   first place) or an inline style with no shared source of truth. */
#ccm-moments {
	background: var(--color-tint-deep);
}


#ccm-moments-list > .elementor-container > .elementor-column > .elementor-widget-wrap > .elementor-inner-section:not(:last-child) {
	margin-bottom: 56px;
	padding-bottom: 56px;
	border-bottom: 1px solid var(--color-border);
}

/* Each row is its own inner-section given an `_element_id` (#ccm-moment-1
   .. -6) rather than a `_css_classes` value -- per gotcha #13 elsewhere in
   this file, `_css_classes` on a `section` element is silently dropped by
   this Elementor version, only `_element_id` actually renders. Figma-style
   1/3 photo, 2/3 text split, gap subtracted from each side's percentage per
   the additive-column-gap fix used elsewhere (gotcha #9) so the two sum to
   exactly 100% including the gap. */
#ccm-moment-1 > .elementor-container,
#ccm-moment-2 > .elementor-container,
#ccm-moment-3 > .elementor-container,
#ccm-moment-4 > .elementor-container,
#ccm-moment-5 > .elementor-container,
#ccm-moment-6 > .elementor-container {
	align-items: center;
	column-gap: 64px;
}

#ccm-moment-1 > .elementor-container > .elementor-column:first-child,
#ccm-moment-2 > .elementor-container > .elementor-column:first-child,
#ccm-moment-3 > .elementor-container > .elementor-column:first-child,
#ccm-moment-4 > .elementor-container > .elementor-column:first-child,
#ccm-moment-5 > .elementor-container > .elementor-column:first-child,
#ccm-moment-6 > .elementor-container > .elementor-column:first-child {
	width: calc(38.2% - 32px) !important;
	flex: 0 0 calc(38.2% - 32px) !important;
	max-width: calc(38.2% - 32px) !important;
}

#ccm-moment-1 > .elementor-container > .elementor-column:last-child,
#ccm-moment-2 > .elementor-container > .elementor-column:last-child,
#ccm-moment-3 > .elementor-container > .elementor-column:last-child,
#ccm-moment-4 > .elementor-container > .elementor-column:last-child,
#ccm-moment-5 > .elementor-container > .elementor-column:last-child,
#ccm-moment-6 > .elementor-container > .elementor-column:last-child {
	width: calc(61.8% - 32px) !important;
	flex: 0 0 calc(61.8% - 32px) !important;
	max-width: calc(61.8% - 32px) !important;
}

.terroo-moment-photo img {
	display: block !important;
	width: 100% !important;
	height: auto !important;
	aspect-ratio: 2/1;
	object-fit: cover !important;
	border-radius: 8px !important;
}

@media (max-width: 767px) {
	#ccm-moments-list > .elementor-container > .elementor-column > .elementor-widget-wrap > .elementor-inner-section:not(:last-child) {
		margin-bottom: 32px;
		padding-bottom: 32px;
	}

	#ccm-moment-1 > .elementor-container,
	#ccm-moment-2 > .elementor-container,
	#ccm-moment-3 > .elementor-container,
	#ccm-moment-4 > .elementor-container,
	#ccm-moment-5 > .elementor-container,
	#ccm-moment-6 > .elementor-container {
		flex-direction: column;
		row-gap: 24px;
	}

	#ccm-moment-1 > .elementor-container > .elementor-column:first-child,
	#ccm-moment-1 > .elementor-container > .elementor-column:last-child,
	#ccm-moment-2 > .elementor-container > .elementor-column:first-child,
	#ccm-moment-2 > .elementor-container > .elementor-column:last-child,
	#ccm-moment-3 > .elementor-container > .elementor-column:first-child,
	#ccm-moment-3 > .elementor-container > .elementor-column:last-child,
	#ccm-moment-4 > .elementor-container > .elementor-column:first-child,
	#ccm-moment-4 > .elementor-container > .elementor-column:last-child,
	#ccm-moment-5 > .elementor-container > .elementor-column:first-child,
	#ccm-moment-5 > .elementor-container > .elementor-column:last-child,
	#ccm-moment-6 > .elementor-container > .elementor-column:first-child,
	#ccm-moment-6 > .elementor-container > .elementor-column:last-child {
		width: 100% !important;
		flex: 1 1 100% !important;
		max-width: 100% !important;
	}
}

/* ---- Section 4: "Chaque rencontre est choisie..." -- 3 plain trust items + CTA ---- */
/* New template distinct from /securite's boxed `.terroo-security-card`
   (white bg, border, hard shadow) -- a plainer left-accent-bar treatment,
   since this is a condensed teaser for the real page, not the destination
   itself. Same shared eyebrow/card-heading/card-body classes throughout. */
.terroo-trust-item {
	border-left: 3px solid var(--color-rust);
	padding-left: 20px;
}

#ccm-trust-grid {
	margin-bottom: 48px;
}

@media (min-width: 1025px) {
	#ccm-trust-grid .elementor-container {
		column-gap: 40px;
	}

	#ccm-trust-grid .elementor-column {
		width: calc(33.333% - 26.667px) !important;
		max-width: calc(33.333% - 26.667px) !important;
		flex: 0 0 calc(33.333% - 26.667px) !important;
	}
}

@media (max-width: 1024px) {
	#ccm-trust-grid .elementor-container {
		row-gap: 32px;
	}
}

/* ---- Closing band ---- */
/* Same tint band + centered content-col pattern as /manifeste's closing,
   with an eyebrow ("PRÊTS ?") and two buttons (like #hero's own button
   row) instead of one. */
#ccm-closing {
	text-align: center;
	background: var(--color-tint-deep);
}

#ccm-closing .terroo-content-col {
	margin-left: auto;
	margin-right: auto;
	margin-bottom: 32px;
}

#ccm-closing-buttons > .elementor-container {
	justify-content: center;
	column-gap: 16px;
	row-gap: 16px;
}

#ccm-closing-buttons > .elementor-container > .elementor-column {
	width: auto !important;
	flex: 0 0 auto !important;
	max-width: 100% !important;
}

#ccm-closing-buttons > .elementor-container > .elementor-column > .elementor-widget-wrap {
	padding: 0 !important;
}

@media (max-width: 767px) {
	#ccm-closing-buttons > .elementor-container {
		flex-direction: column;
		align-items: center;
	}

	#ccm-closing-buttons > .elementor-container > .elementor-column {
		width: 100% !important;
		flex: 1 1 100% !important;
	}
}

/* ---------- Sécurité (Trust & Safety) page ---------- */
/* New components built for the dedicated /securite page -- reuses the
   homepage's established tokens (--color-rust, --font-serif, --font-mono,
   .btn-pill, .terroo-mini-card, .terroo-quote family) rather than
   inventing a new visual language, per the project's own "prefer native/
   existing over custom" rule. */

/* Long-form text column: caps line length for the paragraph-heavy sections
   on this page (intro, references, consequences, transparency,
   precautions) -- full section width reads as uncomfortably long lines of
   body text, unlike the homepage's short, single-sentence sections.
   Centered on the page via auto margins so it doesn't just sit flush
   against the column's left edge. Only used on /securite (confirmed -- no
   other page references this class), so centering it here can't affect
   anything else on the site.

   Each of these 5 sections is a SINGLE WYSIWYG (text-editor) widget --
   this class lives on that one widget (via _css_classes) -- and per
   feedback, the styles below are pre-configured directly on the plain
   semantic tags (h2/h3/h4/p/ul/table/blockquote) rather than requiring a
   hand-typed CSS class on every element. That's what a real editor gets
   for free just by using the WYSIWYG's own Heading 2/3/4, Paragraph,
   Bulleted List and Quote formats -- no class attribute to type or get
   wrong. Elementor's own `.elementor-widget:not(:last-child)` 20px default
   (which only ever applied BETWEEN separate widgets) doesn't contribute
   anything here since there's one widget per section, not one per
   paragraph -- every gap below comes entirely from these margins, via
   normal CSS margin collapsing between plain sibling elements. */
.terroo-content-col {
	max-width: 720px;
	margin-left: auto !important;
	margin-right: auto !important;
}

.terroo-content-col > *:first-child {
	margin-top: 0 !important;
}

.terroo-content-col > *:last-child {
	margin-bottom: 0 !important;
}

/* ---------- Harmonized TinyMCE typography (sitewide) ---------- */
/* Per feedback: rather than scoping the theme's H2/H3/P/Eyebrow look to
   `.terroo-content-col` (originally built for /securite's content
   sections only), these now apply to any `.elementor-widget-text-editor`
   sitewide -- so manually applying a Format from the TinyMCE dropdown
   (Heading 2, Heading 3, Paragraph, Eyebrow) renders consistently no
   matter which page/section it's used in, instead of only working inside
   /securite. `.terroo-content-col`'s own h2/h3/p selectors are gone --
   subsumed by the plain `.elementor-widget-text-editor` versions below
   (identical values), one definition instead of two.
   A handful of existing widget-level classes render genuinely distinct
   designs on top of a `<p>` (the big italic .terroo-quote, compact
   14px .terroo-pillar-text card copy, etc.) -- those stay as their own
   dedicated, sufficiently-specific overrides rather than exceptions
   carved out here; see each class's own rule elsewhere in this file. */
.elementor-widget-text-editor h2 {
	font-family: var(--font-serif);
	font-size: clamp(34px, 3.6vw, 46px);
	font-weight: 700;
	letter-spacing: -0.01em;
	line-height: 1.15;
	color: var(--color-ink);
	margin: 0 0 32px;
}

/* Eyebrow label ("Partie 1/2/3", "Séjours chez l'habitant") is a
   <p class="terroo-eyebrow">, not a heading tag -- it's a visual label,
   not a real entry in the page's heading outline, so it shouldn't claim a
   heading level. Compound class+tag selector so it reliably outranks the
   plain `.elementor-widget-text-editor p` rule below regardless of source
   order (both would otherwise tie at one-class-plus-tag specificity). */
.elementor-widget-text-editor p.terroo-eyebrow {
	font-family: var(--font-mono);
	font-size: 12px;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--color-rust-deep); /* #a83e28, per feedback -- was --color-taupe, matches .terroo-eyebrow's own base rule */
	margin: 0 0 24px;
}

/* H3 = subheading ("Comment ça marche", "Ce que contient un avis") --
   smaller and left-aligned, distinct from the section's own H2 above it
   without competing with it. */
.elementor-widget-text-editor h3 {
	font-family: var(--font-serif);
	font-size: 22px;
	line-height: 1.3;
	color: var(--color-ink);
	margin: 32px 0 16px;
}

/* P = body paragraph. No !important needed: unlike the old per-paragraph
   widget structure, this only has to beat the browser's own UA default `p`
   margin, which loses to any author rule regardless of specificity. */
.elementor-widget-text-editor p {
	font-size: 18px;
	line-height: 1.6;
	color: var(--color-ink);
	margin: 0 0 16px;
}

/* UL = checklist. */
.terroo-content-col ul {
	list-style: none;
	margin: 0 0 24px;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 16px; /* was 12px, per the site's 8px grid rule */
}

.terroo-content-col ul li {
	position: relative;
	padding-left: 24px; /* was 28px, per the site's 8px grid rule */
	font-size: 18px;
	line-height: 1.6;
	color: var(--color-ink);
}

.terroo-content-col ul li::before {
	content: '';
	position: absolute;
	left: 0;
	top: 9px;
	width: 10px;
	height: 10px;
	background: var(--color-rust);
	border-radius: 50%;
}

/* OL = numbered list (first used on /manifeste's "7 rules" section) --
   mirrors UL above exactly (flex column, same gap/font/color), swapping
   the filled-dot bullet for an actual numeral via a CSS counter, since a
   numbered list reads as an ordered set of terms/rules rather than a
   checklist. padding-left is 32px, not UL's 24px -- an 8px-grid step up
   to comfortably fit two-digit numerals without the text column shifting
   between single- and double-digit items. */
.terroo-content-col ol {
	list-style: none;
	counter-reset: terroo-ol;
	margin: 0 0 24px;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 16px;
}

.terroo-content-col ol li {
	position: relative;
	counter-increment: terroo-ol;
	padding-left: 32px;
	font-size: 18px;
	line-height: 1.6;
	color: var(--color-ink);
}

.terroo-content-col ol li::before {
	content: counter(terroo-ol) '.';
	position: absolute;
	left: 0;
	top: 0;
	font-family: var(--font-mono);
	font-weight: 700;
	color: var(--color-rust);
}

/* TABLE = consequence-scale table: plain and legible over anything
   decorative -- this is the one place on the page presenting literal
   reference data, not editorial copy. */
.terroo-content-col table {
	width: 100%;
	border-collapse: collapse;
	margin: 24px 0;
	font-size: 15px;
}

.terroo-content-col th,
.terroo-content-col td {
	text-align: left;
	padding: 16px; /* was 14px 16px, per the site's 8px grid rule */
	border-bottom: 1px solid var(--color-border);
	vertical-align: top;
}

.terroo-content-col th {
	font-family: var(--font-mono);
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--color-rust-deep);
}

.terroo-content-col td:first-child {
	color: var(--color-ink);
	font-weight: 600;
	width: 45%;
}

.terroo-content-col td:last-child {
	color: var(--color-taupe);
}

@media (max-width: 767px) {
	.terroo-content-col table {
		font-size: 14px;
	}

	.terroo-content-col th,
	.terroo-content-col td {
		padding: 8px; /* was 10px 8px, per the site's 8px grid rule */
	}
}

/* BLOCKQUOTE = callout aside ("Pourquoi ça fonctionne", the trust/safety
   pull-quotes) -- the WYSIWYG's own "Quote" format, styled as a tint
   background + rust left border card instead of the browser's plain
   indent, matching the site's existing hard-edge/bordered-card language.
   var(--color-tint-deep) (not --color-tint/#f0e3d6) is the one merged/kept
   tint value used elsewhere on this page (see #securite-references'
   background). Resets the browser's own default blockquote margin/indent
   (`margin: 1em 40px`) as part of the same declaration. */
.terroo-content-col blockquote {
	background: var(--color-tint-deep);
	border-left: 4px solid var(--color-rust);
	border-radius: 4px;
	padding: 24px 28px;
	margin: 32px 0;
}

/* Callout label ("Pourquoi ça fonctionne") -- optional, only some callouts
   have one. Per feedback, this is now the same shared .terroo-eyebrow
   class used everywhere else on the site (a <p class="terroo-eyebrow">),
   not a separate <cite>-tag style -- the two were near-identical anyway
   (mono, uppercase, rust-deep), so this drops the second definition
   rather than keeping them in sync by hand. Only the blockquote-specific
   spacing (was cite's own margin-bottom) still needs to live here, since
   bare .terroo-eyebrow carries no margin of its own. */
.terroo-content-col blockquote .terroo-eyebrow {
	margin-bottom: 10px;
}

/* Higher specificity than the plain .terroo-content-col p rule above, so
   this correctly overrides it for paragraphs nested inside a blockquote.
   :not(.terroo-eyebrow) excludes the callout label above -- without it,
   this rule's italic serif quote styling would also paint over the
   eyebrow paragraph, since both are plain <p> elements inside the same
   blockquote. */
.terroo-content-col blockquote p:not(.terroo-eyebrow) {
	font-family: var(--font-serif);
	font-style: italic;
	font-size: 19px;
	line-height: 1.5;
	color: var(--color-ink);
	margin: 0;
}

/* `.terroo-section-title--on-dark` / `.terroo-body--on-dark` used to give
   the closing contact-band component (Manifeste/Sécurité) light text for a
   dark #2b2118 background. Per feedback, all 4 closing bands
   (Sécurité/Safety's contact band, Manifeste/Manifesto's closing band)
   switched to the same cream/light treatment as the homepage's
   #ccm-closing, so the on-dark variants are no longer applied by any post
   (confirmed) -- rules kept only as dead-but-documented history until
   confirmed unneeded elsewhere; the title/body/micro classes now simply
   fall back to their normal light-background colors (ink / taupe), same
   as everywhere else on the site. */

/* .terroo-quote-col--light (the page-specific light-background variant of
   the quote, plus its centering/alignment overrides) has been removed --
   #securite-promises now reuses #manifeste's actual dark .terroo-quote-col
   component unmodified instead of a light adaptation of it, so none of
   this is needed anymore. */

/* Two-card comparison row (locals vs. travelers) inside the precautions
   band -- per feedback, each card is now a real Elementor column holding
   its own single WYSIWYG widget (title + text), not a raw
   <div class="terroo-mini-card"> pair crammed inside the section's other
   content. .terroo-compare-row (a plain flex wrapper around two raw divs)
   is gone along with that markup -- Elementor's own column layout handles
   the side-by-side split natively now; this just adds the width cap/gap
   values the old class used to provide, scoped to the new inner section's
   `_element_id` (`securite-precautions-cards`).
   Aligned to the same 720px centered column as the heading above and the
   callout below, same reasoning as before: without this, the row would
   render at the full ~1120px column width while its neighbors sit in the
   standard 720px `.terroo-content-col`, breaking alignment on both edges.
   margin-top/bottom: 32px each -- .terroo-content-col's own
   `> *:first-child`/`:last-child` margin-reset (built for one continuous
   WYSIWYG flow) would otherwise zero out the natural gap the eyebrow+h2
   widget's h2 and the blockquote widget's <p> used to contribute on
   either side of this row, now that they're separate widgets instead of
   siblings in the same one -- restoring the same 32px total spacing
   directly on the row instead of fighting that reset. */
#securite-precautions-cards > .elementor-container {
	max-width: 720px;
	margin-left: auto;
	margin-right: auto;
	column-gap: 24px;
}

/* column-gap only creates space BETWEEN columns sitting side by side --
   once the two `.terroo-mini-card` columns wrap into a single stack below
   1024px (Elementor's own default column-stacking breakpoint), that gap
   stops applying and the cards render flush against each other with zero
   space between (same gotcha hit elsewhere in this file, e.g. #cards-grid's
   own row-gap). Explicit row-gap restores a gap once stacked. */
@media (max-width: 1024px) {
	#securite-precautions-cards > .elementor-container {
		row-gap: 24px;
	}
}

#securite-precautions-cards {
	margin-top: 32px;
	margin-bottom: 32px;
}

/* The eyebrow+h2 widget is no longer the only/last widget in its column
   (the cards inner-section and blockquote widget follow it) -- Elementor's
   own `.elementor-widget:not(:last-child) { margin-block-end: 20px }`
   default was stacking on top of the 32px above, widening the h2-to-cards
   gap to 52px. Neutralized here, same recurring fix pattern used
   throughout this file wherever a single WYSIWYG block got split into
   multiple widgets/sections. */
#securite-precautions > .elementor-container > .elementor-column > .elementor-widget-wrap > .elementor-widget:not(:last-child) {
	margin-block-end: 0;
}

/* Contact band (page footer-adjacent CTA): cream/light treatment, same
   family as the homepage's #ccm-closing band -- per feedback, switched
   from the original dark #2b2118 background (each host section's own
   background_color is set directly in that post's Elementor data, not
   here). A large tappable email link stands in for a form -- this page's
   safety-specific "questions?" isn't the same lead-capture intent as the
   homepage's newsletter band, so it's a lighter, simpler component rather
   than reusing .terroo-newsletter-band wholesale. */
.terroo-contact-band {
	text-align: center;
}

/* Centering rebuilt as flex instead of text-align + margin:auto on the
   title specifically -- per repeated feedback this stayed visibly
   off-center on at least one report despite every computed-style check
   run against it (server CSS, Elementor's generated per-post CSS, and
   live getBoundingClientRect on both the wrapper and the actual <h2> all
   measured correctly centered every time this was tested, across 4
   viewport widths, even after a full delete-and-rebuild of the block with
   fresh widget IDs and a forced Elementor CSS regeneration -- never
   reproduced directly). Rather than keep chasing the same margin:auto
   mechanism, this switches the whole column to flex centering instead:
   `align-items: center` on the flex column centers each child by its OWN
   box size directly, with no dependency on that child's own margin
   resolving to `auto` correctly -- a fundamentally more robust mechanism
   than text-align + per-child margin overrides, and removes the failure
   mode entirely rather than re-verifying it away. */
.terroo-contact-band > .elementor-widget-wrap {
	display: flex !important;
	flex-direction: column !important;
	align-items: center !important;
}

.terroo-contact-band .terroo-section-title {
	margin-bottom: 16px !important;
}

/* Replaced the plain underlined email link with a proper .btn-pill button
   -- same rhythm as the old link (8px above, 20px below) via margin on the
   widget itself, since .btn-pill's own hard-shadow/border styling already
   covers the visual treatment. */
.terroo-contact-button {
	margin: 8px 0 20px !important;
}

.terroo-contact-band .terroo-micro {
	color: var(--color-taupe);
	opacity: 0.8;
}

/* ---------- Contact page (/contact) ---------- */
/* New page, new components -- nothing existing matched the screenshot's
   specific layouts (a centered no-photo hero without a tint band, a
   split "big email link + divided reach-us list" row, a split "message +
   CF7 form" band, and a plain left-aligned closing CTA), so these are
   built fresh, reusing established tokens/classes (.terroo-eyebrow,
   .terroo-hero-heading, .terroo-body-lg, .terroo-content-col, .accent,
   .btn-pill) throughout rather than inventing new typography. */

/* ---- Section 1: Hero ("Write to us.") ---- */
/* Shares the "centered no-photo hero" component with #manifeste-hero and
   #legal-hero -- see that shared rule block earlier in this file. Nothing
   contact-page-specific left to declare here. */

/* ---- Section 2: "Reach us" -- big email link + divided reach-us list ---- */
#contact-reach > .elementor-container {
	align-items: start;
	column-gap: 80px;
}

/* !important on text-decoration: Elementor's own core reset
   (`.elementor a { text-decoration: none; }`) ties this on specificity
   (one class + one tag vs one class) and wins the load-order tie -- same
   gotcha #5 pattern documented throughout this file for any custom class
   styling a link inside .elementor content. */
.terroo-contact-email {
	font-family: var(--font-serif);
	font-size: 32px;
	color: var(--color-rust);
	text-decoration: underline !important;
	text-decoration-thickness: 1px;
	text-underline-offset: 8px;
	display: inline-block;
}

.terroo-contact-reach-list > .elementor-widget-wrap > .elementor-widget:not(:last-child) {
	border-bottom: 1px solid var(--color-border);
	padding-bottom: 24px;
	margin-bottom: 24px !important;
}

.terroo-contact-reach-list .elementor-widget-text-editor {
	text-align: center;
}

.terroo-contact-reach-list .terroo-eyebrow {
	display: block;
	margin-bottom: 8px;
}

@media (max-width: 767px) {
	#contact-reach > .elementor-container {
		flex-direction: column;
		row-gap: 40px;
	}
}

/* ---- Section 3: "Send a message" -- tint band, intro + CF7 form ---- */
#contact-form-section {
	background: var(--color-rust-deep);
}

/* Dark-background variant: every text element in this section defaults to
   ink/rust colors meant for a light background, so each needs its own
   light-on-dark override -- the form's white input fields need no change,
   they already read fine against the dark band. Matches the same
   text-on-dark treatment (var(--color-bg), warm cream rather than pure
   white) used by .terroo-quote elsewhere in this file for the same
   rust-deep background. */
#contact-form-section .terroo-eyebrow {
	color: var(--color-bg);
}

#contact-form-section h2 {
	color: var(--color-bg) !important;
}

#contact-form-section h2 .accent {
	color: var(--color-tint) !important;
}

#contact-form-section .terroo-content-col p {
	color: var(--color-tint);
}

#contact-form-section .terroo-contact-form .wpcf7-form label {
	color: var(--color-bg);
}

#contact-form-section > .elementor-container {
	align-items: start;
	column-gap: 80px;
}

@media (max-width: 767px) {
	#contact-form-section > .elementor-container {
		flex-direction: column;
		row-gap: 40px;
	}
}

.terroo-contact-form .wpcf7-form label {
	display: block;
	font-family: var(--font-serif);
	font-weight: 700;
	font-size: 16px;
	color: var(--color-ink);
	margin-bottom: 8px;
}

.terroo-contact-form .wpcf7-form p {
	margin: 0 0 24px;
}

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

/* Matches .terroo-newsletter-band's own input styling exactly (border,
   background, weight, padding) rather than a separate field treatment --
   same pill radius for the single-line fields/select; textarea keeps a
   smaller radius since a 999px pill on a tall multi-line box would just
   read as an odd capsule, not a deliberate shape choice. */
.terroo-contact-form input[type='text'],
.terroo-contact-form input[type='email'],
.terroo-contact-form select {
	width: 100%;
	padding: 16px 16px; /* was 12px 16px, matching the newsletter field's own 8px-grid value */
	border-radius: 999px;
	border: 2px solid var(--color-border);
	background: var(--color-white);
	color: var(--color-ink);
	font-family: var(--font-sans);
	font-weight: 600;
	font-size: 16px;
}

/* select's own chevron: the browser's native arrow was left in place with
   no room budgeted for it, so it sat wherever the OS/browser decided,
   crowding the text at this field's width. `appearance: none` removes
   that native control entirely and this SVG chevron (inked to
   --color-ink, matching the language-switcher's own icon color)
   replaces it, positioned with the same 16px inset the field's own
   padding already uses everywhere else. The OPEN option list itself is
   native OS/browser chrome once triggered -- no cross-browser CSS reaches
   inside it, so this only covers the closed-state control. */
.terroo-contact-form select {
	appearance: none;
	-webkit-appearance: none;
	padding-right: 44px;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%232b2118' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 16px center;
}

.terroo-contact-form input[type='text']::placeholder,
.terroo-contact-form input[type='email']::placeholder {
	color: var(--color-border);
}

.terroo-contact-form textarea {
	width: 100%;
	padding: 16px 16px;
	border-radius: 24px;
	border: 2px solid var(--color-border);
	background: var(--color-white);
	color: var(--color-ink);
	font-family: var(--font-sans);
	font-weight: 600;
	font-size: 16px;
	min-height: 120px;
	resize: vertical;
}

.terroo-contact-form textarea::placeholder {
	color: var(--color-border);
}

.terroo-contact-form input[type='submit'] {
	padding: 16px 32px !important;
	border-radius: 999px !important;
	border: 2px solid var(--color-ink) !important;
	background: var(--color-rust) !important;
	color: var(--color-white) !important;
	font-family: var(--font-sans) !important;
	font-weight: 800 !important;
	font-size: 16px !important;
	cursor: pointer;
	box-shadow: var(--shadow-offset-base) var(--shadow-offset-base) 0 var(--color-ink) !important;
	transition: transform 0.12s ease, box-shadow 0.12s ease;
}

.terroo-contact-form input[type='submit']:hover {
	transform: translate(var(--shadow-offset-sm), var(--shadow-offset-sm));
	box-shadow: var(--shadow-offset-sm) var(--shadow-offset-sm) 0 var(--color-ink) !important;
}

/* ---- Section 4: "Or start directly." -- closing CTA ---- */
/* The original version of this (plain, left-aligned, its own bespoke
   layout) had a centering complaint that survived several fix attempts
   and was never reproduced in testing, so the section was removed
   entirely rather than left broken. Rebuilt now reusing
   .terroo-contact-band -- the same already-proven, already-centered
   component used by /manifeste, /securite and /safety's own closing
   bands -- instead of re-inventing a bespoke layout a second time.
   Nothing page-specific left to declare: background/padding come from
   the shared section-padding list earlier in this file (already includes
   #contact-cta), and title/body/button/centering all come from
   .terroo-contact-band itself. */

/* ---------- Legal Notice page ---------- */
/* Simple, text-only page -- no photo, no tint band, just the plain page
   cream throughout (body's own --color-bg already covers it, so neither
   section below needs its own `background`). Reuses established
   components throughout rather than inventing new ones, per the
   project's "prefer existing over custom" rule. */

/* ---- Hero: shares the "centered no-photo hero" component with
   #manifeste-hero and #contact-hero (see that shared rule block earlier
   in this file, near #manifeste-hero) -- just "Terroo" instead of
   "Contact" and no intro paragraph. Nothing legal-notice-specific left to
   declare for the hero itself. */

/* ---- Item list: reuses .terroo-contact-reach-list verbatim (same class,
   same column, no page-specific overrides) -- per feedback, an earlier
   version of this built its own `.terroo-legal-row`/`.terroo-legal-label`
   2-column component from scratch instead of noticing this one already
   covers the exact same shape (centered eyebrow label above a paragraph,
   divided by a hairline between items). Each item is one text-editor
   widget, `<p class="terroo-eyebrow">LABEL</p>` + body paragraph(s), same
   as #contact-reach's Locals/Travelers/Partnerships/Press items -- the
   divider/spacing/centering all come from that shared class, nothing new
   needed here except capping the column's width for readability, since
   this list is the only content in its row (#contact-reach's own copy of
   the class sits beside a second column, which already constrains it).
   Shared with #terms-items (Terms of Service) -- same exact template,
   per feedback, rather than a per-page copy. */
#legal-items,
#terms-items {
	padding-top: 80px;
	padding-bottom: 80px;
}

@media (max-width: 767px) {
	#legal-items,
	#terms-items {
		padding-top: 40px;
		padding-bottom: 40px;
	}
}

#legal-items .terroo-contact-reach-list,
#terms-items .terroo-contact-reach-list {
	max-width: 640px;
	margin-left: auto;
	margin-right: auto;
}

/* text-decoration: !important beats Elementor's own core link reset
   (`.elementor a { text-decoration: none }`), same gotcha #5 pattern
   documented throughout this file for any custom class styling a link
   inside .elementor content. Not part of .terroo-contact-reach-list itself
   since its own source content (Locals/Travelers/...) never contained a
   link -- this is a legal-page-specific addition, not a duplicated
   component. */
#legal-items a,
#terms-items a {
	color: var(--color-rust);
	text-decoration: underline !important;
	text-decoration-thickness: 1px;
	text-underline-offset: 3px;
}

/* ---- "Last updated" line: centered italic, like a colophon. ---- */
#legal-footer-note,
#terms-footer-note {
	text-align: center;
}

.terroo-legal-updated {
	font-family: var(--font-serif);
	font-style: italic;
	font-size: 18px;
	color: var(--color-ink);
}

/* ---------- "Local" page ---------- */
/* Reuses existing components throughout -- the hero is literally
   #securite-hero/#ccm-hero's own shared component (added to that
   selector list, see near the top of this file), the closing note reuses
   #securite-promises' .terroo-quote-col band, and the rest draws on
   .terroo-hero-heading, .terroo-body-lg, .btn-pill, .terroo-section-title,
   .accent, .terroo-contact-reach-list, .terroo-eyebrow. The one genuinely
   new piece is the FAQ list (.terroo-faq-list), since nothing existing
   covers a left-aligned question/answer pair. */

/* ---- Bridge line: thin one-line link to the traveler page, reusing the
   plain .terroo-eyebrow label + a rust underlined link (same link
   treatment as the legal pages' body links). #traveler-bridge is the
   same component reused on the "For travelers" page, linking back to
   "For locals" -- joined into this selector list rather than duplicated. */
#local-bridge,
#traveler-bridge {
	padding: 32px 40px;
}

#local-bridge .elementor-widget-text-editor,
#traveler-bridge .elementor-widget-text-editor {
	max-width: var(--container-max);
	margin: 0 auto;
}

#local-bridge .terroo-eyebrow,
#traveler-bridge .terroo-eyebrow {
	margin-right: 16px;
}

#local-bridge a,
#traveler-bridge a {
	color: var(--color-rust);
	text-decoration: underline !important;
	text-decoration-thickness: 1px;
	text-underline-offset: 3px;
}

/* ---- Five principles: same template as Legal Notice/Terms of Service's
   own item list -- plain page cream (no special background), each item a
   .terroo-eyebrow label above a paragraph, divided by a hairline, via
   .terroo-contact-reach-list verbatim. An earlier version of this put the
   list on a dark --color-ink band with bare "01 · statement" lines and no
   eyebrow -- replaced to match the light template exactly instead. */
#local-principles {
	text-align: center;
}

/* text-align:center above only centers INLINE content within a box, not
   the box itself -- .terroo-section-title's own 640px max-width (see its
   base rule) otherwise leaves the title's block sitting flush-left. Same
   fix already used for .terroo-content-col elsewhere (e.g. #manifeste-
   hero, #contact-hero) whenever a max-width-capped block needs to be
   centered as a whole, not just its text. */
/* !important: the base .terroo-section-title rule sets its own
   `margin: 0 0 80px !important` shorthand (all four sides), which would
   otherwise win over a plain margin-left/right here. */
#local-principles .terroo-section-title {
	margin-left: auto !important;
	margin-right: auto !important;
}

/* margin-top: 0, not an extra 48px -- .terroo-section-title above already
   carries its own 80px margin-bottom (base rule), so an additional top
   margin here was stacking to a 128px gap below the title, wider than
   every other section-title-to-content gap on the site. */
#local-principles .terroo-contact-reach-list {
	max-width: 640px;
	margin: 0 auto;
}

/* ---- FAQ: same 2-column, top-aligned split as #contact-reach (title in
   a narrower left column, content in a wider right column, both starting
   at the same vertical position) -- per feedback, rather than the title
   stacked above a centered list. .terroo-faq-list itself is the one
   genuinely new component here: left-aligned question (bold, with an
   .accent word) + answer paragraph, divided by a hairline between items,
   same divider mechanism as .terroo-contact-reach-list but left- instead
   of center-aligned, since a Q&A list reads naturally left-to-right. */
#local-faq {
	background: var(--color-tint);
}

#local-faq > .elementor-container {
	align-items: start;
	column-gap: 80px;
}

@media (max-width: 767px) {
	#local-faq > .elementor-container {
		flex-direction: column;
		row-gap: 40px;
	}
}

.terroo-faq-list > .elementor-widget-wrap > .elementor-widget:not(:last-child) {
	border-bottom: 1px solid var(--color-border);
	padding-bottom: 24px;
	margin-bottom: 24px !important;
}

.terroo-faq-question {
	font-family: var(--font-serif);
	font-size: 22px;
	font-weight: 600;
	color: var(--color-ink);
	margin: 0 0 8px;
}

.terroo-faq-question .accent {
	font-style: italic;
	font-weight: 400;
	color: var(--color-rust);
}

.terroo-faq-answer {
	font-size: 17px;
	line-height: 1.6;
	color: var(--color-taupe);
	margin: 0;
}

/* ---- Note: literally #securite-promises' own .terroo-quote-col band --
   nothing page-specific left to declare, the class already handles
   background/centering/typography. */

/* ---------- Error pages (404, 403, 500, 503) ----------
   404.php is a real theme template, so it goes through header.php/
   footer.php like any page and gets the full nav/language/font stack --
   these rules just style its own centered message block. The 403/500/503
   static HTML fallbacks (wp-content/error-pages/) are self-contained and
   inline their own copy of these same rules, since they must render even
   if WordPress itself never loads. */
.terroo-error-page {
	background: var(--color-tint-deep);
	padding: var(--section-pad-mobile) 0;
	min-height: 60vh;
	display: flex;
	align-items: center;
}

@media (min-width: 768px) {
	.terroo-error-page {
		padding: var(--section-pad) 0;
	}
}

.terroo-error-page__inner {
	text-align: center;
	max-width: 560px;
}

.terroo-error-page__inner .terroo-eyebrow {
	display: block;
	margin-bottom: 16px;
}

.terroo-error-page__inner h1 {
	font-family: var(--font-serif);
	font-size: clamp(32px, 5vw, 48px);
	font-weight: 600;
	color: var(--color-ink);
	margin: 0 0 16px;
}

.terroo-error-page__inner p {
	font-family: var(--font-sans);
	font-size: 17px;
	line-height: 1.6;
	color: var(--color-taupe);
	margin: 0 0 32px;
}

/* ---------- Blog: listing grid, filter pills, article layout ----------
   New namespace (terroo-blog-*) instead of reusing .terroo-card: that class
   is the homepage's rotated "polaroid" treatment, wrong tone for an
   editorial blog grid. Flat cards, hover lift, category badge + reading
   time meta row, matching the rest of the site's warm-cream/rust/serif
   system. */
.terroo-blog-filters {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
	margin: 40px 0 48px;
}

button.terroo-blog-filter-pill {
	font-family: var(--font-sans) !important;
	font-size: 15px !important;
	font-weight: 600 !important;
	color: var(--color-ink) !important;
	background: var(--color-card-bg) !important;
	border: 1px solid var(--color-border) !important;
	border-radius: 999px !important;
	padding: 10px 20px !important;
	cursor: pointer;
	transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
	display: inline-flex;
	align-items: center;
	gap: 8px;
}

button.terroo-blog-filter-pill:hover {
	border-color: var(--color-rust) !important;
}

button.terroo-blog-filter-pill.is-active {
	background: var(--color-rust) !important;
	border-color: var(--color-rust) !important;
	color: var(--color-white) !important;
}

.terroo-blog-grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 32px;
}

@media (max-width: 1024px) {
	.terroo-blog-grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (max-width: 640px) {
	.terroo-blog-grid {
		grid-template-columns: 1fr;
	}
}

.terroo-blog-grid-item {
	display: none;
}

.terroo-blog-grid-item.is-visible {
	display: block;
}

/* Photo-card treatment for the blog grid, matching the homepage's
   .terroo-card polaroid frame (white card, inset photo, tape strip) --
   straight (no per-card rotation, unlike the homepage scrapbook grid,
   since a content grid needs to read as ordered, not playful) so the
   badge/title/excerpt stay easy to scan across many cards. */
.terroo-blog-card {
	display: block;
	position: relative;
	background: var(--color-card-bg);
	border: none;
	border-radius: 8px;
	padding: 16px 16px 24px;
	box-shadow: 0 18px 32px -16px rgba(var(--color-shadow-rgb), 0.35);
	text-decoration: none;
	transition: transform 0.2s ease, box-shadow 0.2s ease;
	height: 100%;
	box-sizing: border-box;
}

.terroo-blog-card:hover {
	transform: translateY(-4px);
	box-shadow: 0 22px 40px -16px rgba(var(--color-shadow-rgb), 0.4);
}

.terroo-blog-card::after {
	content: '';
	position: absolute;
	top: -12px;
	left: 50%;
	width: 64px;
	height: 26px;
	background: var(--color-border);
	transform: translateX(-50%) rotate(-3deg);
	z-index: 2;
}

.terroo-blog-card-image {
	position: relative;
	z-index: 1;
	aspect-ratio: 4/3;
	overflow: hidden;
	border-radius: 4px;
	margin: 0 0 16px;
}

.terroo-blog-card-image img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	border-radius: 4px;
}

.terroo-blog-card-body {
	padding: 0 8px;
}

.terroo-blog-meta {
	display: flex;
	align-items: center;
	gap: 10px;
	margin-bottom: 16px;
	flex-wrap: wrap;
}

.terroo-blog-badge {
	font-family: var(--font-mono);
	font-size: 12px;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.02em;
	color: var(--color-rust-deep);
	background: var(--color-tint);
	border-radius: 999px;
	padding: 5px 12px;
	white-space: nowrap;
}

.terroo-blog-readtime {
	font-family: var(--font-sans);
	font-size: 13px;
	color: var(--color-taupe);
	display: inline-flex;
	align-items: center;
	gap: 5px;
	white-space: nowrap;
}

.terroo-blog-readtime::before {
	content: '\25F4';
	font-size: 12px;
}

.terroo-blog-card-title {
	font-family: var(--font-serif);
	font-size: 22px;
	font-weight: 600;
	line-height: 1.3;
	color: var(--color-ink);
	margin: 0 0 12px;
}

.terroo-blog-card-excerpt {
	font-family: var(--font-sans);
	font-size: 15px;
	line-height: 1.6;
	color: var(--color-taupe);
	margin: 0;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

/* ---------- Article page: breadcrumb, meta row, sticky TOC ---------- */
.terroo-breadcrumb {
	font-family: var(--font-sans);
	font-size: 14px;
	color: var(--color-taupe);
	margin: 0;
}

.terroo-breadcrumb a {
	color: var(--color-taupe);
	text-decoration: none;
}

.terroo-breadcrumb a:hover {
	color: var(--color-rust);
}

.terroo-breadcrumb .sep {
	margin: 0 8px;
	color: var(--color-border);
}

.terroo-article-layout {
	align-items: flex-start !important;
}

.terroo-toc-col {
	position: sticky;
	top: 32px;
}

.terroo-toc {
	background: var(--color-card-bg);
	border: 1px solid var(--color-border);
	border-radius: 12px;
	padding: 28px 24px;
}

.terroo-toc-label {
	font-family: var(--font-mono);
	font-size: 12px;
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--color-rust-deep);
	display: block;
	margin: 0 0 16px;
}

.terroo-toc-link {
	display: block;
	font-family: var(--font-sans);
	font-size: 15px;
	line-height: 1.4;
	color: var(--color-taupe);
	text-decoration: none;
	padding: 10px 0;
	border-top: 1px solid var(--color-border);
}

.terroo-toc a:first-of-type .terroo-toc-link {
	border-top: none;
	padding-top: 0;
}

.terroo-toc-link:hover {
	color: var(--color-rust);
}

@media (max-width: 1024px) {
	.terroo-toc-col {
		display: none;
	}
}

.terroo-tldr-box {
	background: var(--color-tint);
	border-left: 4px solid var(--color-rust);
	border-radius: 8px;
	padding: 24px 28px;
}

.terroo-tldr-label {
	font-family: var(--font-mono);
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	color: var(--color-rust-deep);
	display: block;
	margin: 0 0 10px;
}

/* Inline article photo: was a plain Elementor "image" widget with only
   `.terroo-card` on it (a class built for image-BOX widgets, whose photo
   sizing rules target `.elementor-image-box-img img`, an element that
   doesn't exist on a plain image widget). With nothing constraining it,
   the raw <img> rendered at its native upload size and overflowed the
   68%-wide article column instead of matching the text measure above and
   below it. Fix: give the widget BOTH `terroo-content-col` (720px cap,
   auto-centered -- same box the surrounding text sections use) and this
   class, which fixes the photo's own aspect ratio/fit/corners the same
   way `.terroo-card .elementor-image-box-img img` does for polaroid
   cards. */
.terroo-article-image {
	margin: 8px 0 32px;
}

.terroo-article-image img {
	width: 100%;
	height: auto;
	aspect-ratio: 16/10;
	object-fit: cover;
	border-radius: 12px;
	display: block;
}

.terroo-article-updated {
	font-size: 0.85rem;
	color: #6B5F52;
	margin: 24px 0 0;
	font-style: italic;
}

/* Blog listing hero subline: `.terroo-body-lg` carries a sitewide ~46ch
   max-width (see its own rule elsewhere in this file) meant for the
   homepage's short hero blurbs -- on the blog listing it made the intro
   paragraph wrap much narrower than the `.terroo-content-col` box its
   own wrapper sits in, so it visually failed to line up with the
   full-width card grid directly below it even though both are nominally
   the same 720px box. Scoped override: let it use the full content-col
   width here so its right edge matches the grid's. */
#bloglist-hero .terroo-body-lg {
	max-width: none;
}
