/* =========================================================================
   MERLIN — DESIGN SYSTEM + SHARED CHROME
   Loaded by every page. Blog-only components live in blog.css.

   Three colour families only: cream (warm neutral surfaces), charcoal (ink +
   inverse) and acid (the single accent). No gradients, no second accent.
   The brand separates planes with 1px hairlines rather than elevation.
   ========================================================================= */
:root {
	--font-sans:    'Archivo', system-ui, -apple-system, 'Helvetica Neue', sans-serif;
	--font-display: 'Archivo Black', 'Archivo', sans-serif;
	--font-mono:     ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Courier New', monospace;

	--cream-50:  #FAF9F8;  --cream-100: #F4F2EF;  --cream-200: #EBE7E2;  --cream-300: #DED8D0;
	--cream-400: #CEC5B9;  --cream-500: #BCAF9F;  --cream-800: #726151;  --cream-900: #594D3F;

	--charcoal-50:  #F6F6F6;  --charcoal-200: #DEDEDE;  --charcoal-300: #BDBDBD;
	--charcoal-500: #757575;  --charcoal-700: #424242;  --charcoal-800: #242424;  --charcoal-900: #121212;

	--acid-50:  #FBFFE5;  --acid-100: #EFFFB3;  --acid-200: #E3FF80;
	--acid-400: #C8FF00;  --acid-500: #B2E300;  --acid-600: #93BD00;
	/* Warm translucent stroke drawn inside every acid fill */
	--acid-outline: #774B3A1A;
	/* Secondary accent, used by the method panel */
	--mint:       #3DFFBB;

	/* Semantic surfaces */
	--canvas:         #FFFFFF;
	--canvas-sunk:    var(--cream-100);
	--canvas-inverse: var(--charcoal-800);
	--canvas-sage:    #E5E9E5;
	--paper:          #FFFFFF;
	--accent:         var(--acid-400);

	/* Semantic ink */
	--ink:           var(--charcoal-800);
	--ink-secondary: var(--charcoal-500);
	--ink-muted:     var(--charcoal-500);
	--ink-faint:     var(--cream-500);
	--on-accent:     var(--charcoal-800);
	--on-inverse:    #FFFFFF;
	--on-inverse-secondary: rgba(255, 255, 255, 0.8);
	--on-inverse-muted:     rgba(255, 255, 255, 0.5);

	/* Hairlines — the brand draws with 1px rules constantly */
	--line:         var(--cream-200);
	--line-strong:  var(--cream-300);
	--line-inverse: var(--charcoal-700);
	--line-sage:    rgba(36, 36, 36, 0.2);
	--hairline-inset: rgba(0, 0, 0, 0.08);

	--radius-xs: 3px;  --radius-sm: 4px;  --radius-md: 7px;  --radius-lg: 8px;
	--radius-xl: 12px; --radius-2xl: 20px; --radius-pill: 9999px;

	--shadow-sm:    0 1px 3px rgba(0, 0, 0, 0.05);
	--shadow-md:    0 4px 20px rgba(0, 0, 0, 0.08);
	--shadow-lg:    0 8px 32px rgba(0, 0, 0, 0.06);
	--shadow-inset: inset 0 0 0 1px var(--hairline-inset);

	--focus-ring:    rgba(36, 36, 36, 0.35);
	--ease-standard: cubic-bezier(0.2, 0, 0, 1);
	--ease-nav:      cubic-bezier(0.16, 1, 0.3, 1);
	--dur-fast: 120ms;  --dur-base: 180ms;

	--maxw:     1368px;
	--maxw-nav: 1100px;
	--measure:  804px;
	--band:     5rem;
}

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

html { scroll-behavior: smooth; }
body {
	margin: 0;
	background: var(--canvas);
	color: var(--ink);
	font-family: var(--font-sans);
	font-size: 16px;
	line-height: 1.5;
	-webkit-font-smoothing: antialiased;
}
::selection { background: color-mix(in srgb, var(--accent), transparent 35%); color: var(--ink); }
a { color: inherit; text-decoration: none; }
/* Opt-in link, usable anywhere — highlighted like a marker pen rather than underlined.
   Semi-transparent so the ink shows through the stroke, the way real highlighter sits
   over text rather than behind it, and full height so it reads as a swiped band. */
a.inline-link {
	font-weight: 600;
	/* background-color, not an image: unlike background-image it animates, so the
	   second pass on hover fades in instead of snapping */
	background-color: color-mix(in srgb, var(--accent), transparent 35%);
	box-decoration-break: clone;
	-webkit-box-decoration-break: clone;
	padding: 0 3px;
	transition: background-color var(--dur-base) var(--ease-standard);
}
/* Gone over a second time on hover — denser, not taller */
a.inline-link:hover { background-color: color-mix(in srgb, var(--accent), transparent 15%); }
/* Same highlighter on plain text — no link, no hover, just the stroke */
.mark {
	background-color: color-mix(in srgb, var(--accent), transparent 35%);
	box-decoration-break: clone;
	-webkit-box-decoration-break: clone;
	padding: 0 3px;
}
img { display: block; max-width: 100%; }
ul { list-style: none; margin: 0; padding: 0; }
strong { font-weight: 600; }


/* =========================================================================
   TYPOGRAPHY
   One ramp, four levels. Sizes step at 768px and 1024px — no clamp(), so the
   scale stays predictable and matches the design kit exactly.

   h1  page title, once per page          h3  card / item title
   h2  section title                      h4  minor title (footer columns)
   ========================================================================= */
h1, h2, h3, h4 { color: var(--ink); margin: 0; text-wrap: balance; }

h1, .h1 { font-size: 2.5rem;  line-height: 1.04; letter-spacing: -0.02em;  font-weight: 500; }
h2, .h2 { font-size: 2rem;    line-height: 1.06; letter-spacing: -0.018em; font-weight: 500; }
h3, .h3 { font-size: 1.3rem;  line-height: 1.18; letter-spacing: -0.005em; font-weight: 500; }
h4, .h4 { font-size: 0.875rem; line-height: 1.36; letter-spacing: 0.04em;  font-weight: 600; text-transform: uppercase; }

/* Hero-scale title — reserved for the home h1 and the final CTA */
.title-xl { font-size: 2.5rem; line-height: 1.04; letter-spacing: -0.025em; font-weight: 500; }

p { margin: 0; text-wrap: pretty; }

.lead      { font-size: 1.1rem;   line-height: 1.44; }
.body      { font-size: 1rem;     line-height: 1.44; }
.body-sm   { font-size: 0.875rem; line-height: 1.5;  }
.muted     { color: var(--ink-secondary); }

/* Uppercase eyebrow above every section title */
.overline {
	display: block;
	font-size: 0.75rem;
	font-weight: 600;
	line-height: 1.28;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	color: var(--ink-secondary);
}
/* An eyebrow and the title under it are one unit — pull them out of the 40px
   section rhythm and set their own spacing */
.overline + h2,
.overline + p,
.overline + .title-right,
.overline + .section-head { margin-top: -22px; }

@media (min-width: 768px) {
	h1, .h1   { font-size: 3rem; }
	h2, .h2   { font-size: 2.25rem; }
	h3, .h3   { font-size: 1.4rem; }
	.title-xl { font-size: 4rem; }
	.lead     { font-size: 1.1rem; }
}
@media (min-width: 1024px) {
	h1, .h1   { font-size: 4rem; }
	h2, .h2   { font-size: 2.5rem; }
	h3, .h3   { font-size: 1.75rem; }
	.title-xl { font-size: 5rem; }
	.lead     { font-size: 1.5rem; }
	.body     { font-size: 1.25rem; }
	.body-sm  { font-size: 1rem; }
}


/* =========================================================================
   LAYOUT
   .wrap is the 1368px measure used by every section.
   .panel is the rounded plate the brand uses to group a section on a tint.
   ========================================================================= */
.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 20px; }

section { padding: 96px 0 0; }
.section-stack { display: flex; flex-direction: column; gap: 40px; }
/* Pulls an item back towards the one above it — for a paragraph that continues the
   previous one rather than opening a new beat */
.tight-above { margin-top: -24px; }
.section-head  { display: flex; flex-wrap: wrap; gap: 32px; align-items: flex-end; justify-content: space-between; }
.section-head p { max-width: 440px; text-align: right; }

/* Right-aligned section title, used on the inverse panels */
.title-right { display: flex; justify-content: flex-end; }
.title-right h2 { max-width: 720px; text-align: right; }

.panel {
	border-radius: var(--radius-2xl);
	padding: 64px 0;
}
.panel-sunk    { background: var(--canvas-sunk); outline: 2px solid #fff; }
.panel-inverse { background: var(--canvas-inverse); color: var(--on-inverse); }
.panel-cream   { background: var(--cream-900); color: var(--cream-50); }
.panel-sage    { background: var(--canvas-sage); }
.panel-plain   { background: #F2F2F2; }
.panel-inset   { padding-left: 16px; padding-right: 16px; }
/* Consecutive plates read as one stack — a tight 32px between them rather than the
   96px that separates sections. Scoped to these pairs so the rest keeps its air. */
#cas-usage + #methode,
#methode + #souverainete,
#souverainete + #offres,
#offres + #equipe { padding-top: 32px; }

/* Inverse panels repaint their own type */
.panel-inverse h2, .panel-inverse h3,
.panel-cream h2,   .panel-cream h3   { color: #fff; }
.panel-inverse .overline { color: var(--on-inverse-muted); }
.panel-cream .overline   { color: var(--cream-400); }
.panel-inverse .muted    { color: var(--on-inverse-secondary); }
.panel-cream .muted      { color: var(--cream-300); }

.measure { max-width: var(--measure); }


/* =========================================================================
   BUTTONS
   ========================================================================= */
.btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	height: 40px;
	padding: 0 20px;
	background: var(--accent);
	color: var(--on-accent);
	border: none;
	border-radius: var(--radius-pill);
	/* Inside the radius, not a border — the design system draws every acid fill this way */
	outline: 1px solid var(--acid-outline);
	outline-offset: -1px;
	font-family: var(--font-sans);
	font-size: 0.875rem;
	font-weight: 600;
	letter-spacing: 0.02em;
	white-space: nowrap;
	cursor: pointer;
	transition: background var(--dur-fast) var(--ease-standard), transform var(--dur-fast) var(--ease-standard);
}
/* Darkened from --accent rather than hard-coded, so the whole button family
   follows whatever the accent is set to */
.btn:hover  { background: color-mix(in srgb, var(--accent), black 12%); }
.btn:active { background: color-mix(in srgb, var(--accent), black 22%); transform: scale(0.98); }
.btn-sm     { height: 36px; padding: 0 18px; font-size: 0.8125rem; }
.btn-lg     { height: 52px; padding: 0 32px; font-size: 1rem; }
.btn-dark   { background: var(--ink); color: #fff; outline-color: transparent; }
.btn-dark:hover { background: var(--charcoal-900); }

/* Button + reassurance line underneath */
.cta-group { display: flex; flex-direction: column; gap: 12px; align-items: flex-start; }
/* Indented by the button's own padding, so the note lines up with the label inside
   it rather than with the pill's outer edge */
.cta-group > p { padding-left: 20px; }
.cta-group:has(.btn-lg) > p { padding-left: 32px; }
.cta-group--center > p { padding-left: 0; }
.cta-group--center { align-items: center; text-align: center; }


/* =========================================================================
   HEADER — floating pill navbar, fixed to the top on every page
   ========================================================================= */
/* Two states. At rest the bar is full-bleed and invisible — logo hard left, links
   hard right, no plate. Over the first 120px of scroll it collapses into a centred
   pill — driven frame by frame off --dock rather than by CSS transitions, so every
   part moves as one and the bar can be scrubbed backwards just as smoothly. */
header {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	z-index: 50;
	/* --dock runs 0 → 1, written by the JS on every scroll frame. Every value below
	   is interpolated from it, so the whole bar is a direct function of scroll
	   position: no transition to fall behind, nothing arriving out of step. */
	--dock: 0;
	/* Carries the open state's generous top offset, and gives it back as the bar docks.
	   Living here rather than on the plate keeps the plate's own height constant. */
	padding: calc(36px - var(--dock) * 16px) calc(var(--dock) * 48px) 0;
}
.navbar-inner {
	position: relative;
	display: flex;
	align-items: center;
	gap: 8px;
	width: 100%;
	margin: 0 auto;
	/* Only the horizontal padding animates. The vertical one is fixed, so the bar keeps
	   a constant height and its contents never drift up as the plate appears. */
	max-width: calc(100% - var(--dock) * (100% - 700px));
	padding: 12px calc(48px - var(--dock) * 24px);
	border-radius: calc(var(--dock) * 40px);
	background: rgba(255, 255, 255, var(--dock));
	outline: 1px solid rgba(222, 216, 208, var(--dock));
	outline-offset: -1px;
	box-shadow: 0 8px 32px rgba(0, 0, 0, calc(var(--dock) * 0.06));
}
/* justify-self:start keeps the clickable area on the logo itself, while the
   navbar's flex:1 spacer pushes the right-hand group hard against the edge */
.brand { display: flex; align-items: center; padding: 0 8px; justify-self: start; }

/* Links and CTA are one welded block — they migrate together, never apart */
.navbar-group { display: flex; align-items: center; gap: 16px; margin-left: auto; }

/* Width comes from each img's own attribute — 110px in the footer, where --dock is 0.
   In the navbar it is indexed on --dock like everything else: 92px open, 78px docked,
   moving with the bar rather than on a timer of its own. */
.brand img { height: auto; object-fit: contain; }
.navbar-inner .brand img { width: calc(92px - var(--dock) * 14px); }

.navbar-links { display: flex; align-items: center; gap: 8px; }
.navbar-links a {
	padding: 8px 12px;
	border-radius: var(--radius-lg);
	font-size: 0.875rem;
	font-weight: 600;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	color: var(--ink);
	transition: background var(--dur-fast) var(--ease-standard);
}
.navbar-links a:hover { background: var(--cream-100); }

.nav-right { display: flex; align-items: center; gap: 12px; }
/* Availability pill: a live green dot, the phone glyph and the number, inside a
   hairline capsule — it reads as "the line is open" rather than as a plain link. */
.nav-phone {
	display: inline-flex;
	align-items: center;
	gap: 9px;
	padding: 6px 14px 6px 10px;
	border: 1px solid var(--line-strong);
	border-radius: var(--radius-pill);
	background: var(--paper);
	font-size: 0.875rem;
	font-weight: 500;
	letter-spacing: 0.01em;
	white-space: nowrap;
	color: var(--ink);
	transition: color var(--dur-fast) var(--ease-standard);
	/* The pill is 700px wide — the phone number folds away as the bar closes in,
	   indexed on --dock so it shrinks in step with everything else */
	max-width: calc((1 - var(--dock)) * 210px);
	overflow: hidden;
	opacity: calc(1 - var(--dock) * 1.6);
	/* The capsule's own padding and border have to fold away too, or a stub of it
	   is left behind once the number itself has gone */
	padding-left: calc((1 - var(--dock)) * 10px);
	padding-right: calc((1 - var(--dock)) * 14px);
	border-width: calc(1px - var(--dock) * 1px);
}
.nav-phone:hover { color: var(--ink); border-color: var(--ink-faint); background: var(--cream-50); }
.nav-phone svg { width: 14px; height: 14px; flex: none; opacity: 0.75; }

/* The dot itself, plus a halo that pulses outward from it */
.nav-phone-dot {
	position: relative;
	display: inline-flex;
	width: 8px;
	height: 8px;
	flex: none;
	border-radius: 50%;
	background: #10B981;
}
.nav-phone-dot::before {
	content: '';
	position: absolute;
	inset: 0;
	border-radius: 50%;
	background: #34D399;
	animation: phone-ping 1.8s cubic-bezier(0, 0, 0.2, 1) infinite;
}
@keyframes phone-ping {
	0%   { transform: scale(1);   opacity: 0.7; }
	75%, 100% { transform: scale(2.2); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
	.nav-phone-dot::before { animation: none; }
}


/* =========================================================================
   LANGUAGE SWITCHER + MOBILE MENU — JS-driven, shared with the blog
   ========================================================================= */
.lang-switcher { position: relative; display: inline-flex; }
.lang-switcher-btn { display: flex; align-items: center; padding: 0; border: none; background: transparent; cursor: pointer; }
.lang-switcher-btn img { width: 22px; height: 22px; object-fit: cover; border-radius: 50%; border: 1px solid var(--line); transition: border-color var(--dur-fast) var(--ease-standard); }
.lang-switcher-btn:hover img { border-color: var(--line-strong); }
.lang-switcher-dropdown {
	position: absolute; top: calc(100% + 8px); right: 0; z-index: 200; min-width: 8rem; padding: 6px;
	display: none; flex-direction: column; gap: 2px;
	background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg);
}
.lang-switcher.is-open .lang-switcher-dropdown { display: flex; }
.lang-switcher-dropdown a { display: flex; align-items: center; gap: 8px; padding: 7px 9px; border-radius: var(--radius-sm); color: var(--ink-secondary); font-size: 0.8125rem; transition: background var(--dur-fast) var(--ease-standard), color var(--dur-fast) var(--ease-standard); }
.lang-switcher-dropdown a:hover { background: var(--cream-100); color: var(--ink); }
.lang-switcher-dropdown a.is-current { color: var(--ink); font-weight: 600; }
.lang-switcher-dropdown a img { width: 20px; height: 20px; object-fit: cover; border-radius: 50%; flex-shrink: 0; }

.mobile-menu-toggle, .mobile-menu-panel { display: none; }


/* =========================================================================
   HERO — full-height cream plate with the animated centre rule
   ========================================================================= */
/* Default is the plain hero — no track, no stage. The JS adds .is-reveal to opt
   in, so a page without JS (or with reduced motion) never gets a broken layout.
   Once armed, the section becomes a 225vh scroll track driving a viewport-tall
   sticky stage, where two layers share the exact same footprint: the cream plate
   on top slides up out of frame while the layer underneath scales up into place —
   an uncovering, not a cross-fade. */
.hero { position: relative; padding: 16px; }
/* 100vh of sticky stage + 75vh of reveal + 50vh holding the uncovered card still,
   so the black panel is seen full-screen and alone before the page scrolls on. That
   last stretch is the only place the track may sit idle: it has something to show. */
.hero.is-reveal { padding: 0; height: 225vh; }
.hero-sticky { position: static; }
.hero.is-reveal .hero-sticky {
	position: sticky;
	top: 0;
	height: 100vh;
	height: 100dvh;
	padding: 16px;
	box-sizing: border-box;
	overflow: hidden;
}
.hero-reveal { display: none; }
.hero.is-reveal .hero-reveal {
	display: block;
	position: absolute;
	inset: 16px;
	overflow: hidden;
	border-radius: var(--radius-2xl);
	background: var(--canvas-inverse);
	/* Start state — JS drives it to scale(1) / translateY(0) as the track scrolls.
	   Opaque from the first frame: the plate on top is what hides it. */
	transform: translateY(15px) scale(0.94);
	transform-origin: center;
	will-change: transform;
}
.hero-reveal-video {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	/* Carries its own radius: a transformed parent's overflow:hidden does not reliably
	   clip a descendant, so the corners are clipped on the element itself. */
	border-radius: inherit;
	opacity: var(--sl-video, 1);
}

/* CRT trim over the video: horizontal scanlines plus a finer vertical grille, both
   drawn as repeating gradients — no image, no extra request. mix-blend-mode makes
   them bite into the picture instead of greying it out with a flat overlay. */
.scanlines {
	/* Every knob the dev panel writes to. Line = the dark rule, gap = the pitch it
	   repeats on, so gap 3 / thickness 1 means one dark pixel every three. */
	--sl-h-opacity:   0.14;
	--sl-h-thickness: 2px;
	--sl-h-gap:       5px;
	--sl-v-opacity:   0.14;
	--sl-v-thickness: 2px;
	--sl-v-gap:       4px;
	--sl-vignette:    0.42;
	--sl-vignette-start: 58%;

	position: absolute;
	inset: 0;
	pointer-events: none;
	background-image:
		repeating-linear-gradient(
			to bottom,
			rgba(0, 0, 0, var(--sl-h-opacity)) 0px,
			rgba(0, 0, 0, var(--sl-h-opacity)) var(--sl-h-thickness),
			transparent var(--sl-h-thickness),
			transparent var(--sl-h-gap)
		),
		repeating-linear-gradient(
			to right,
			rgba(0, 0, 0, var(--sl-v-opacity)) 0px,
			rgba(0, 0, 0, var(--sl-v-opacity)) var(--sl-v-thickness),
			transparent var(--sl-v-thickness),
			transparent var(--sl-v-gap)
		);
	border-radius: inherit;
	mix-blend-mode: multiply;
}
/* Vignette + phosphor glow, kept on its own layer so it does not multiply */
.scanlines::after {
	content: '';
	position: absolute;
	inset: 0;
	border-radius: inherit;
	background:
		radial-gradient(ellipse at center, transparent var(--sl-vignette-start), rgba(0, 0, 0, var(--sl-vignette)) 100%);
}
.hero-plate {
	position: relative;
	overflow: hidden;
	box-sizing: border-box;
	display: flex;
	flex-direction: column;
	min-height: calc(100vh - 32px);
	padding: 150px 20px 48px;
	background: var(--canvas-sunk);
	border-radius: var(--radius-2xl);
	outline: 2px solid #fff;
}
.hero.is-reveal .hero-plate {
	height: 100%;
	min-height: 0;
	will-change: transform;
}
.hero-rule {
	position: absolute;
	left: 50%;
	top: 0;
	width: 1.5px;
	height: 100%;
	transform: translateX(-50%);
	transform-origin: top;
	background: var(--line-strong);
	animation: hero-line 550ms cubic-bezier(.05, .2, .64, .3) 250ms both;
}
@keyframes hero-line {
	from { transform: translateX(-50%) scaleY(0); }
	to   { transform: translateX(-50%) scaleY(1); }
}
/* padding-top nudges the copy down the plate, away from the navbar, without moving
   the mark — which is pinned to the plate itself, outside this flow. */
.hero-inner { position: relative; display: flex; flex-direction: column; gap: 28px; height: 100%; padding-top: 80px; max-width: var(--maxw); margin: 0 auto; }
.hero-head  { display: flex; flex-direction: column; gap: 24px; align-items: flex-start; }
.hero-head h1 { max-width: 1000px; }
.hero-lede { max-width: 620px; }
/* Two equal halves, so the mark on the right can be centred in a real half rather
   than in a flex column whose width follows the copy beside it. */
.hero-grid  { display: grid; grid-template-columns: 1fr 1fr; gap: 48px; align-items: end; }
.hero-copy  { max-width: 640px; display: flex; flex-direction: column; gap: 40px; }
/* Pinned to the right half of the plate, not laid out in the grid: the plate's
   padding is lopsided (150px top, 48px bottom), so anything centred in the flow
   sits low. Absolute positioning centres it against the plate itself. */
/* Pinned to the plate's right half. Inset values are measured from the plate's
   border box, so they ignore its lopsided padding (150px top, 48px bottom) and
   50% is genuinely half the plate — which is what "centred on the right" means. */
.hero-visual {
	position: absolute;
	inset: 0 0 0 50%;
	display: flex;
	align-items: center;
	justify-content: center;
	pointer-events: none;
}
/* The M carries the hero's visual weight — same mark as the favicon */
.hero-m { width: 62%; height: auto; }

@media (max-width: 860px) {
	.hero-grid { grid-template-columns: 1fr; }
	.hero-visual { display: none; }
}
.hero-parked[hidden] { display: none; }

/* Credibility line, separated by a rule */
.hero-proof {
	max-width: 560px;
	padding-top: 16px;
	border-top: 1px solid var(--line-strong);
	color: var(--ink-secondary);
}

@media (min-width: 768px) {
	.hero-plate { padding-left: 48px; padding-right: 48px; }
}


/* =========================================================================
   SHARED BLOCKS
   ========================================================================= */

/* Grids */
.grid-2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); gap: 48px; }
.grid-3 { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 24px; }
.grid-4 { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 32px; }

/* Card — white plate with a 1.5px outline, used for use cases and pricing */
.card {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: 14px;
	padding: 28px;
	background: var(--paper);
	border: 1px solid #E5E5E7;
	border-radius: 16px;
	box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
	transition: transform 0.3s ease, box-shadow 0.3s ease;
}
/* Lift only where the cards are a set being scanned — the pricing table and the
   production list use .card as a container, and lifting those would imply a link */
.grid-3 .card:hover {
	transform: translateY(-2px);
	box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
}
/* Footnote pinned to the bottom of a card, above a hairline */
.card-note {
	margin-top: auto;
	padding-top: 14px;
	border-top: 1px solid var(--line);
	font-size: 0.875rem;
	color: var(--ink-secondary);
}

/* Stat split — two headline figures set against the copy that reads them. The
   contrast between the numbers is the argument, so they carry the visual weight. */
.stat-split {
	display: grid;
	grid-template-columns: repeat(2, minmax(140px, 200px)) minmax(300px, 1fr);
	gap: 32px 48px;
	align-items: start;
	padding-top: 40px;
	/* Same hairline as the divider below — both sit on the sage panel */
	border-top: 1px solid var(--line-sage);
}
.stat-figure { display: flex; flex-direction: column; gap: 10px; }
.stat-value {
	font-size: 3.5rem;
	line-height: 1;
	letter-spacing: -0.03em;
	font-weight: 500;
	font-variant-numeric: tabular-nums;
	color: var(--ink);
}
/* The second figure is the gap in the market — marked, not shouted */
.stat-figure:nth-child(2) .stat-value {
	background-image: linear-gradient(color-mix(in srgb, var(--accent), transparent 35%), color-mix(in srgb, var(--accent), transparent 35%));
	background-repeat: no-repeat;
	background-position: 0 88%;
	background-size: 100% 38%;
	padding: 0 6px;
	margin-left: -6px;
}
.stat-copy { display: flex; flex-direction: column; gap: 16px; }
.stat-source { font-size: 0.75rem; }
/* Opens the second movement inside the same section: a rule and a little air,
   enough to separate the pillars from the figures without splitting them apart */
.stat-divider { padding-top: 40px; border-top: 1px solid var(--line-sage); }

@media (min-width: 1024px) {
	.stat-value { font-size: 4.5rem; }
}
@media (max-width: 860px) {
	.stat-split { grid-template-columns: 1fr 1fr; }
	.stat-copy  { grid-column: 1 / -1; }
}
@media (max-width: 480px) {
	.stat-split { grid-template-columns: 1fr; }
}

/* Use-case grid — many short cards rather than a few long ones: the point is the
   breadth of what an agent can take on. Tech tags sit at the bottom so every card
   ends on the same line whatever its text length. */
.usecase-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
	gap: 16px;
}
.usecase {
	display: flex;
	flex-direction: column;
	gap: 10px;
	padding: 24px;
	background: var(--paper);
	border: 1px solid #E5E5E7;
	border-radius: 16px;
	box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
	transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.usecase:hover {
	transform: translateY(-2px);
	box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
}
.usecase h3 { font-size: 1.0625rem; line-height: 1.3; }
.usecase p  { flex: 1; }

/* Pushed to the card's foot, so the tags line up across the row */
.usecase-tags {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	margin-top: auto;
	padding-top: 6px;
}
.usecase-tags span {
	padding: 3px 9px;
	background: var(--cream-100);
	border-radius: var(--radius-sm);
	font-size: 0.6875rem;
	font-weight: 600;
	letter-spacing: 0.02em;
	color: var(--ink-secondary);
	white-space: nowrap;
}

/* Feature — icon + title + text, on the tinted panels */
.feature { display: flex; flex-direction: column; gap: 16px; }
.feature .ico {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 48px;
	height: 48px;
	border-radius: var(--radius-md);
	background: var(--cream-800);
	color: var(--cream-400);
}
.panel-inverse .feature .ico { background: var(--charcoal-700); color: var(--charcoal-300); }
/* On the light sage panel the mark is drawn dark, like the type around it */
.panel-sage .feature .ico { background: var(--ink); color: var(--canvas-sage); }

/* Step — numbered method item */
/* Method panel runs on acid mint rather than the page accent: chartreuse on
   charcoal turns muddy, mint keeps its bite. */
.panel-inverse { --method-accent: var(--mint); }

/* Two by two: four columns squeezed each step into a narrow strip, and the
   "vous repartez avec" blocks had no room to breathe. */
.step-grid {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 48px 64px;
	margin-top: 24px;
}
@media (max-width: 720px) { .step-grid { grid-template-columns: 1fr; gap: 40px; } }

.step { display: flex; flex-direction: column; gap: 12px; }
/* Only the step number is accented; the period after it keeps the muted tone, so
   the eye catches the sequence rather than the calendar. */
.step .overline { color: var(--method-accent, var(--accent)); }
.step .step-when {
	display: block;
	margin-top: 3px;
	text-transform: none;
	letter-spacing: 0.01em;
	font-weight: 400;
	color: var(--on-inverse-muted);
}
/* Méthode — deliverable per step + commitments row (inverse panel) */
.step .handoff {
	/* Pushed to the foot of the step so every "vous repartez avec" starts on the
	   same line, whatever the description above it runs to */
	margin-top: auto;
	padding-top: 4px;
	padding-left: 14px;
	border-left: 2px solid var(--method-accent, var(--accent));
}
.panel-inverse .step .handoff { color: var(--on-inverse-secondary); }
.step .handoff b {
	display: block;
	font-size: 0.6875rem;
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--method-accent, var(--accent));
	margin-bottom: 2px;
}
.method-commitments {
	display: flex;
	flex-wrap: wrap;
	gap: 12px 32px;
	padding-top: 32px;
	border-top: 1px solid var(--line-inverse);
}
.method-commitments span { font-size: 0.875rem; }
.panel-inverse .method-commitments span { color: var(--on-inverse-secondary); }
.method-commitments span::before { content: "\2713\00a0 "; color: var(--method-accent, var(--accent)); }

/* Numbered offer row */
.offer-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); column-gap: 48px; }
.offer { display: flex; gap: 20px; padding: 12px 0 28px; }
.offer .num { padding-top: 6px; font-size: 0.75rem; font-weight: 600; letter-spacing: 0.04em; color: var(--ink-secondary); }
.offer-body { display: flex; flex-direction: column; gap: 8px; }

/* Definition rows — pricing table, production list, sovereignty list */
.rows { display: flex; flex-direction: column; max-width: 900px; }
.row {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	gap: 16px;
	padding: 14px 0;
	/* Lighter than --line-strong: these rules run the full width of the card and
	   only need to separate, not to draw attention */
	border-top: 1px solid var(--line);
}
.row:last-child { padding-bottom: 0; }
/* The first row opens the list — its rule would just double the container's edge */
.rows > .row:first-child { border-top: 0; padding-top: 0; }
.row .val { font-weight: 600; white-space: nowrap; font-variant-numeric: tabular-nums; }
.row .val-text { text-align: right; color: var(--ink-secondary); white-space: normal; }

/* Stacked rows with a title + description per line (sovereignty) */
.rows-stacked .row {
	flex-direction: column;
	align-items: flex-start;
	gap: 6px;
	padding: 20px 0;
	border-top: 1px solid var(--line-sage);
}

/* Pill tags — the stack section */
.tags { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.tag {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 8px 18px;
	border: 1px solid var(--line);
	border-radius: var(--radius-pill);
	font-size: 0.875rem;
}
.tag b {
	padding: 2px 10px;
	background: var(--ink);
	color: #fff;
	border-radius: var(--radius-pill);
	font-size: 0.75rem;
	font-weight: 600;
	letter-spacing: 0.04em;
	text-transform: uppercase;
}

/* Logo wall + team photos — placeholders until the real assets land */
/* Marquee — the track holds the list twice and slides by exactly half its width, so
   the loop is seamless. Full-bleed: it breaks out of .wrap to run edge to edge. */
.logo-marquee {
	position: relative;
	width: 100vw;
	margin-left: 50%;
	transform: translateX(-50%);
	overflow: hidden;
	/* Fade both ends so logos enter and leave instead of being cut off */
	-webkit-mask-image: linear-gradient(to right, transparent, #000 8%, #000 92%, transparent);
	        mask-image: linear-gradient(to right, transparent, #000 8%, #000 92%, transparent);
}
.logo-track {
	display: flex;
	width: max-content;
	animation: logo-scroll 60s linear infinite;
}
.logo-marquee:hover .logo-track { animation-play-state: paused; }

@keyframes logo-scroll {
	from { transform: translateX(0); }
	to   { transform: translateX(-50%); }
}

/* A square viewport, as on the source site: every mark is a 128x128 viewBox, so the
   per-logo percentages in the markup resolve against a square and each one keeps the
   optical weight it was tuned for. A single uniform size would leave wide wordmarks
   tiny and compact ones oversized. */
.logo-cell {
	display: flex;
	flex: none;
	align-items: center;
	justify-content: center;
	width: 110px;
	height: 110px;
	margin: 0 20px;
}
.logo-cell img { object-fit: contain; }

@media (prefers-reduced-motion: reduce) {
	.logo-track { animation: none; flex-wrap: wrap; justify-content: center; width: 100%; }
}

.person { display: flex; flex-direction: column; gap: 12px; }
.person .photo {
	display: flex;
	align-items: center;
	justify-content: center;
	aspect-ratio: 1;
	padding: 12px;
	background: var(--paper);
	border-radius: var(--radius-xl);
	outline: 1px solid var(--line);
	outline-offset: -1px;
	font-size: 0.75rem;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	text-align: center;
	color: var(--ink-faint);
}

/* Media frame — inset hairline instead of a border, per the brand */
.media {
	position: relative;
	overflow: hidden;
	border-radius: var(--radius-xl);
	box-shadow: var(--shadow-inset);
}
.media-placeholder {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: 100%;
	padding: 24px;
	background: var(--cream-200);
	font-size: 0.75rem;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	text-align: center;
	color: var(--ink-faint);
}


/* =========================================================================
   TOOL MARQUEES — two rows sliding in opposite directions
   Each track holds its list twice and shifts by exactly half its width, so the
   loop is seamless. The second row runs the same animation in reverse.
   ========================================================================= */
.tool-marquee {
	position: relative;
	width: 100vw;
	margin-left: 50%;
	transform: translateX(-50%);
	overflow: hidden;
	padding: 8px 0;
	-webkit-mask-image: linear-gradient(to right, transparent, #000 6%, #000 94%, transparent);
	        mask-image: linear-gradient(to right, transparent, #000 6%, #000 94%, transparent);
}
/* Air between the intro copy and the first row; the two rows stay tight together */
.tool-marquee { margin-top: 56px; }
.tool-marquee + .tool-marquee { margin-top: 16px; }
/* Sections carry no bottom padding, so the second row would sit right against the
   next section — this gives the stack room to close. */
#stack { padding-bottom: 56px; }

.tool-track {
	display: flex;
	gap: 16px;
	width: max-content;
	animation: tool-scroll 70s linear infinite;
}
.tool-track--right { animation-direction: reverse; }
.tool-marquee:hover .tool-track { animation-play-state: paused; }

@keyframes tool-scroll {
	from { transform: translateX(0); }
	to   { transform: translateX(-50%); }
}

/* Icon + label, as one chip */
.tool-chip {
	display: flex;
	flex: none;
	align-items: center;
	gap: 12px;
	padding: 14px 20px 14px 16px;
	background: var(--paper);
	border-radius: var(--radius-xl);
	outline: 1px solid var(--line);
	outline-offset: -1px;
	font-size: 0.875rem;
	font-weight: 500;
	white-space: nowrap;
	transition: box-shadow var(--dur-base) var(--ease-standard);
}
.tool-chip:hover { box-shadow: var(--shadow-md); }
.tool-chip img { width: 24px; height: 24px; flex: none; object-fit: contain; }

@media (prefers-reduced-motion: reduce) {
	.tool-track { animation: none; flex-wrap: wrap; justify-content: center; width: 100%; }
	.tool-marquee { -webkit-mask-image: none; mask-image: none; }
}


/* =========================================================================
   FAQ — native <details>, no JS needed
   ========================================================================= */
.faq-list { display: flex; flex-direction: column; max-width: 900px; }
.faq-list details { border-top: 1px solid var(--line-strong); }
.faq-list details:last-child { border-bottom: 1px solid var(--line-strong); }
.faq-list summary {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	gap: 24px;
	padding: 20px 0;
	list-style: none;
	cursor: pointer;
	font-size: 1.3rem;
	font-weight: 500;
	line-height: 1.18;
}
.faq-list summary::-webkit-details-marker { display: none; }
.faq-list summary .pm { color: var(--ink-secondary); transition: transform var(--dur-base) var(--ease-standard); }
.faq-list details[open] summary .pm { transform: rotate(45deg); }
.faq-list .ans { max-width: var(--measure); padding: 0 0 24px; color: var(--ink-secondary); }
.faq-list .ans a { text-decoration: underline; text-underline-offset: 3px; }

@media (min-width: 1024px) {
	.faq-list summary { font-size: 1.75rem; }
}


/* =========================================================================
   FINAL CTA + FOOTER
   The footer is injected into every page by build-site.js — edit the partial
   in build/partials/footers/, never the copy inside a page.
   ========================================================================= */
/* Light band above the dark footer: the closing call sits on paper, not charcoal */
.final-band { background: var(--canvas-sunk); color: var(--ink); }
.final-light h2 { color: var(--ink); }
.final-light .muted { color: var(--ink-secondary); }

.final {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 20px;
	padding: 72px 20px 56px;
	text-align: center;
}
.final h2 { max-width: 900px; }
.final p  { max-width: 640px; }
.final .btn { margin-top: 4px; }
/* The phone link, on the light band: dark ink, underlined on hover */
.final p a { color: var(--ink); text-underline-offset: 4px; font-weight: 600; }

footer { position: relative; background: var(--canvas-inverse); color: var(--on-inverse); }
.foot-grid {
	display: grid;
	grid-template-columns: 1.4fr 1fr 1fr 1fr;
	gap: 40px;
	padding: 64px 0 80px;
}
.foot-brand { display: flex; flex-direction: column; gap: 12px; }
/* Uses logo-inverse.svg — a white-lettering variant that keeps the three coloured
   squares. A CSS filter cannot do this: invert() would rotate their hues too. */
.foot-brand img { width: 110px; height: auto; }
.foot-brand p { font-size: 0.875rem; color: var(--on-inverse-muted); }
.foot-brand a { color: var(--on-inverse-secondary); }
.foot-col { display: flex; flex-direction: column; gap: 10px; }
.foot-col h4 { color: var(--on-inverse-muted); }
.foot-col a { font-size: 0.875rem; color: var(--on-inverse-secondary); transition: color var(--dur-fast) var(--ease-standard); }
.foot-col a:hover { color: #fff; }
.foot-lang { font-size: 0.75rem; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--on-inverse-muted); }
.foot-lang a { color: var(--on-inverse-muted); }
.foot-lang a:hover { color: #fff; }

/* Acid bands closing the page — decorative, hidden from assistive tech */
/* The three coloured stripes carry the wordmark; the legal bar below is a separate
   band and stays clear of it, at its own height. */
.foot-stripes {
	position: relative;
	overflow: hidden;
}
/* Sits on top of the stripes in solid ink — it is the sign-off, not a watermark */
.foot-bands-mark {
	position: absolute;
	left: 50%;
	top: 50%;
	z-index: 1;
	transform: translate(-50%, -50%);
	width: 92%;
	max-width: 1400px;
	height: auto;
	pointer-events: none;
}
.foot-band { height: calc(var(--band) * 2.6); }
.foot-band-1 { background: var(--accent); }
.foot-band-2 { background: color-mix(in srgb, var(--accent), white 40%); }
.foot-band-3 { background: color-mix(in srgb, var(--accent), white 65%); }
.foot-legal {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	min-height: var(--band);
	padding: 12px 20px;
	background: color-mix(in srgb, var(--accent), white 85%);
	color: var(--ink);
	font-size: 0.875rem;
}
.foot-legal a { text-underline-offset: 4px; text-decoration: underline; }
.foot-legal .links { display: flex; align-items: center; gap: 24px; }


/* =========================================================================
   CONTENT PAGES — breadcrumb + prose (service pages, legal pages)
   ========================================================================= */
.breadcrumb { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; padding: 20px 0 0; font-size: 0.8125rem; color: var(--ink-muted); }
.breadcrumb a:hover { color: var(--ink); }
.breadcrumb .sep { color: var(--ink-faint); }
.breadcrumb .here { color: var(--ink); font-weight: 600; }

.prose { max-width: var(--measure); }
.prose > p { margin: 0 0 18px; line-height: 1.7; color: var(--ink-secondary); }
.prose h2 { margin: 44px 0 14px; }
.prose h3 { margin: 28px 0 8px; }
.prose ul.bullets { display: flex; flex-direction: column; gap: 10px; margin: 0 0 20px; }
.prose ul.bullets li { position: relative; padding-left: 26px; line-height: 1.6; }
.prose ul.bullets li::before { content: ''; position: absolute; left: 6px; top: 9px; width: 7px; height: 7px; border-radius: 50%; background: color-mix(in srgb, var(--accent), black 12%); }
.prose ol { display: flex; flex-direction: column; gap: 12px; margin: 0 0 20px; padding: 0; counter-reset: step; }
.prose ol li { position: relative; padding-left: 42px; line-height: 1.6; counter-increment: step; }
.prose ol li::before {
	content: counter(step);
	position: absolute; left: 0; top: -1px;
	display: inline-flex; align-items: center; justify-content: center;
	width: 27px; height: 27px;
	background: var(--accent); color: var(--on-accent);
	outline: 1px solid var(--acid-outline); outline-offset: -1px;
	border-radius: 50%; font-size: 0.8125rem; font-weight: 700;
}
.prose .callout { margin: 26px 0; padding: 18px 22px; background: var(--canvas-sunk); border-radius: var(--radius-xl); line-height: 1.6; }


/* =========================================================================
   RESPONSIVE
   ========================================================================= */
@media (max-width: 900px) {
	.foot-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 860px) {
	.navbar-links { display: none; }

	/* Tighter chrome — 48px of side padding is half the screen on a phone */
	header { padding: calc(16px - var(--dock) * 4px) calc(var(--dock) * 12px) 0; }
	.navbar-inner {
		padding: 10px calc(16px + var(--dock) * 4px);
		border-radius: calc(var(--dock) * 32px);
	}
	.mobile-menu-toggle {
		order: -1;
		display: inline-flex; flex-direction: column; justify-content: center; gap: 4px;
		width: 38px; height: 38px; padding: 0;
		background: transparent; border: 0; cursor: pointer;
	}
	.mobile-menu-toggle span { display: block; width: 20px; height: 2px; border-radius: var(--radius-pill); background: var(--ink); }
	.mobile-menu-panel {
		position: absolute; top: calc(100% + 8px); left: 16px; z-index: 200; min-width: 13rem;
		flex-direction: column; gap: 4px; padding: 8px;
		background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg);
	}
	.is-mobile-menu-open .mobile-menu-panel { display: flex; }
	.mobile-menu-panel a { padding: 11px 14px; border-radius: var(--radius-sm); font-size: 0.9375rem; font-weight: 600; color: var(--ink); }
	.mobile-menu-panel a:hover { background: var(--cream-100); }

	.section-head { align-items: flex-start; }
	.section-head p { text-align: left; }
	.title-right { justify-content: flex-start; }
	.title-right h2 { text-align: left; }

	/* Too little room to spend 1.25 screens on a reveal — drop the track.
	   The JS disables itself at the same width, so nothing drives these layers. */
	.hero.is-reveal { padding: 16px; height: auto; }
	.hero.is-reveal .hero-sticky { position: static; height: auto; padding: 0; overflow: visible; }
	.hero.is-reveal .hero-plate { min-height: calc(100vh - 32px); height: auto; }
	.hero.is-reveal .hero-reveal { display: none; }
}
@media (max-width: 620px) {
	section { padding: 64px 0 0; }
	.panel  { padding: 48px 0; }
	.hero-plate { padding-top: 120px; }
	.grid-2, .grid-3, .grid-4, .foot-grid, .logo-wall { grid-template-columns: 1fr; }
	.offer-list { grid-template-columns: 1fr; }
	.final { padding: 80px 20px 64px; }
	.final-link { font-size: 2rem; }
	.row .val-text { text-align: left; }
}


/* =========================================================================
   DEV ONLY — accent colour picker
   Delete this block, its markup in index.html and its IIFE in main.js
   before launch. Nothing else references .accent-picker.
   ========================================================================= */
.accent-picker {
	position: fixed;
	top: 50%;
	right: 12px;
	z-index: 100;
	transform: translateY(-50%);
	display: flex;
	flex-direction: column;
	gap: 6px;
	padding: 8px;
	background: var(--paper);
	border-radius: var(--radius-lg);
	outline: 1px solid var(--line);
	outline-offset: -1px;
	box-shadow: var(--shadow-lg);
}
.accent-picker button {
	width: 26px;
	height: 26px;
	padding: 0;
	background: var(--swatch);
	border: none;
	border-radius: var(--radius-sm);
	outline: 2px solid transparent;
	outline-offset: 1px;
	cursor: pointer;
	transition: outline-color var(--dur-fast) var(--ease-standard), transform var(--dur-fast) var(--ease-standard);
}
.accent-picker button:hover      { transform: scale(1.12); }
.accent-picker button.is-active  { outline-color: var(--ink); }

/* --- CRT grid tuner ------------------------------------------------------ */
.grid-panel[hidden] { display: none; }
.grid-panel {
	position: fixed;
	top: 12px;
	right: 12px;
	z-index: 100;
	width: 260px;
	font-size: 12px;
	background: var(--paper);
	border-radius: var(--radius-lg);
	outline: 1px solid var(--line);
	outline-offset: -1px;
	box-shadow: var(--shadow-lg);
}
.grid-panel-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 10px 12px;
	font-weight: 600;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	border-bottom: 1px solid var(--line);
}
.grid-panel-toggle {
	width: 22px; height: 22px; padding: 0;
	display: inline-flex; align-items: center; justify-content: center;
	background: var(--cream-100); border: none; border-radius: var(--radius-sm);
	font-size: 14px; line-height: 1; cursor: pointer;
}
.grid-panel-body { display: flex; flex-direction: column; gap: 10px; padding: 12px; }
.grid-panel.is-collapsed .grid-panel-body { display: none; }
.grid-panel label { display: flex; flex-direction: column; gap: 4px; color: var(--ink-secondary); }
.grid-panel label b { color: var(--ink); font-variant-numeric: tabular-nums; }
.grid-panel input[type=range] { width: 100%; accent-color: var(--ink); }
.grid-panel hr { width: 100%; height: 1px; margin: 2px 0; border: 0; background: var(--line); }
.grid-panel-actions { display: flex; gap: 6px; margin-top: 2px; }
.grid-panel-actions button {
	flex: 1;
	padding: 7px 8px;
	background: var(--cream-100); color: var(--ink);
	border: none; border-radius: var(--radius-sm);
	font-family: var(--font-sans); font-size: 11px; font-weight: 600; cursor: pointer;
}
.grid-panel-actions button:hover { background: var(--cream-200); }

/* --- Video transport (overlays the video, bottom right of the card) ------- */
.video-controls {
	position: absolute;
	right: 20px;
	bottom: 20px;
	z-index: 2;
	display: flex;
	gap: 8px;
}
.video-controls button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	padding: 0;
	color: #fff;
	background: rgba(0, 0, 0, 0.35);
	backdrop-filter: blur(6px);
	-webkit-backdrop-filter: blur(6px);
	border: 1px solid rgba(255, 255, 255, 0.25);
	border-radius: var(--radius-pill);
	cursor: pointer;
	transition: background var(--dur-fast) var(--ease-standard);
}
.video-controls button:hover { background: rgba(0, 0, 0, 0.6); }
.video-controls svg { width: 18px; height: 18px; display: block; }
/* One icon shows at a time — .is-on marks sound playing */
.video-controls [data-video-sound] .icon-sound { display: none; }
.video-controls [data-video-sound].is-on .icon-muted { display: none; }
.video-controls [data-video-sound].is-on .icon-sound { display: block; }
