/*
 * Découverte V2 — design tokens.
 *
 * The whole visual identity, reviewable in one diff. Every value here is a role,
 * not a one-off: nothing downstream may hard-code a colour, a family or a step.
 *
 * COLOUR MODEL — OKLCH, so lightness is perceptual and the warm tint survives
 * every step. Never #000, never #fff: every neutral carries warmth.
 *
 * THE ONE RULE THAT SHAPES EVERYTHING: dark mode flips the CANVAS ONLY. The
 * olive is constant in both themes, which is what keeps the design's tonal
 * rhythm intact instead of inverting it (ADR-0022).
 *
 * Contrast was computed, not estimated. Every pair below is AA or better:
 *   ink/canvas 14.8 · muted/canvas 5.6 · ink/canvas dark 14.9 · muted dark 7.0
 *   on-olive/olive 13.4 · gold/olive 7.8 · accent-strong text on canvas 6.6
 *   off-white on the filled accent 4.9
 */

:root {
	color-scheme: light;

	/* --- the constant: olive. Identical in both themes. ------------------ */
	--dcv-olive:        oklch(0.255 0.021 132);
	--dcv-olive-deep:   oklch(0.205 0.019 132);
	--dcv-olive-raised: oklch(0.305 0.023 132);
	--dcv-on-olive:       oklch(0.945 0.010 86);
	--dcv-on-olive-muted: oklch(0.760 0.012 88);
	--dcv-on-olive-line:  oklch(0.945 0.010 86 / 0.18);

	/* Ornament. Tan/gold is licensed on dark ground ONLY. */
	--dcv-gold: oklch(0.780 0.072 80);

	/* --- the surface that flips ------------------------------------------ */
	--dcv-canvas:     oklch(0.968 0.011 86);
	--dcv-canvas-sunk: oklch(0.938 0.014 84);
	--dcv-ink:        oklch(0.245 0.017 74);
	--dcv-muted:      oklch(0.497 0.016 74);
	--dcv-line:       oklch(0.245 0.017 74 / 0.16);
	--dcv-line-strong: oklch(0.245 0.017 74 / 0.32);

	/* --- the one accent -------------------------------------------------- */
	/* Filled surfaces carry --dcv-on-olive; accent-strong is the text cut. */
	--dcv-accent:        oklch(0.523 0.145 40);
	--dcv-accent-strong: oklch(0.470 0.140 38);

	/*
	 * The terracotta a filled action rests on, pinned and theme-CONSTANT. The
	 * accent lightens in dark mode, which is right where it is a text colour and
	 * wrong where cream type sits on top of it: measured, that pairing fell to
	 * 4.23:1 in dark and failed AA. A button that carries one label colour needs
	 * one fill, in both themes. Cream on this: 4.94:1.
	 */
	--dcv-accent-action: oklch(0.523 0.145 40);

	/*
	 * --- the pigment: the five accent ROLES every component reads ---------
	 *
	 * Nothing downstream reads --dcv-accent-strong or --dcv-gold directly any
	 * more; everything reads a `cat` role. Unscoped — the Accueil, a search, a
	 * legal page, a 404 — the roles resolve to exactly the house values the site
	 * has always used, so a page with no section is unchanged to the pixel. A
	 * scoped page rebinds the same five roles to its Hub's pigment (ADR-0029).
	 *
	 *   ink   type and hairline weight ON THE CANVAS. Flips with the theme.
	 *   glow  the same pigment ON OLIVE, where a mid-tone would disappear.
	 *         Theme-CONSTANT, because the olive it sits on is theme-constant.
	 *   fill  a plate carrying cream type. Theme-constant, same reason.
	 *   wash  the faintest tint of the pigment, for a row under the pointer.
	 *   line  the pigment as a rule.
	 */
	--dcv-cat-ink:  var(--dcv-accent-strong);
	--dcv-cat-glow: var(--dcv-gold);
	--dcv-cat-fill: var(--dcv-accent-action);
	--dcv-cat-wash: var(--dcv-canvas-sunk);
	--dcv-cat-line: var(--dcv-line-strong);

	/* The house pigment, so an unknown scope degrades to terracotta, never to
	   an invalid colour. */
	--dcv-cat-h: 40;
	--dcv-cat-c: 0.145;

	/* --- the scrim: type over photography is never unprotected ----------- */
	--dcv-scrim-bottom: linear-gradient(
		to top,
		oklch(0.205 0.019 132 / 0.92) 0%,
		oklch(0.205 0.019 132 / 0.72) 28%,
		oklch(0.205 0.019 132 / 0.28) 62%,
		oklch(0.205 0.019 132 / 0) 100%
	);
	--dcv-scrim-left: linear-gradient(
		to right,
		oklch(0.205 0.019 132 / 0.88) 0%,
		oklch(0.205 0.019 132 / 0.55) 45%,
		oklch(0.205 0.019 132 / 0) 100%
	);

	/*
	 * The opening's veil. Not a scrim that merely darkens a photograph so type
	 * can survive on top of it: everything under the headline column is FULLY
	 * OPAQUE olive, so the headline is never on the photograph at all, and the
	 * photograph dissolves out of that flat ground instead of butting against it.
	 *
	 * The opaque run is a LENGTH, not a percentage — the gutter plus the exact
	 * width of the type column — so it tracks the type at every viewport instead
	 * of drifting off it. The caller sets --dcv-open-type; the fallback here is
	 * the same value that caller uses at its widest.
	 *
	 * Two layers: the directional fade, and a foot fade so the ruled row at the
	 * band's foot has no hard edge cutting across it.
	 */
	--dcv-veil-open: linear-gradient(
			to top,
			oklch(0.205 0.019 132) 0%,
			oklch(0.205 0.019 132 / 0.55) 15%,
			oklch(0.205 0.019 132 / 0) 42%
		),
		linear-gradient(
			to right,
			oklch(0.205 0.019 132) 0,
			oklch(0.205 0.019 132) calc(var(--dcv-gutter) + var(--dcv-open-type, 46rem)),
			oklch(0.205 0.019 132 / 0.84) calc(var(--dcv-gutter) + var(--dcv-open-type, 46rem) + 7rem),
			oklch(0.205 0.019 132 / 0.56) calc(var(--dcv-gutter) + var(--dcv-open-type, 46rem) + 18rem),
			oklch(0.205 0.019 132 / 0.34) 100%
		);

	/* The same idea vertically, for the phone layout where the photograph sits
	   above the type rather than behind it. */
	--dcv-veil-open-foot: linear-gradient(
		to top,
		oklch(0.205 0.019 132) 0%,
		oklch(0.205 0.019 132 / 0.42) 26%,
		oklch(0.205 0.019 132 / 0) 62%
	);

	/* --- type ------------------------------------------------------------ */
	--dcv-font-display: "Bluu Next", "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
	--dcv-font-ui: "Public Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;

	/*
	 * Strong scale contrast between display and interface, and deliberately no
	 * mid-sized voice between them. Headlines are fluid, not stepped per
	 * breakpoint.
	 */
	--dcv-display-1: clamp(2.6rem, 1.35rem + 5.4vw, 6rem);
	--dcv-display-2: clamp(2rem, 1.35rem + 2.9vw, 3.75rem);
	--dcv-display-3: clamp(1.5rem, 1.2rem + 1.4vw, 2.2rem);
	--dcv-display-4: clamp(1.15rem, 1.04rem + 0.5vw, 1.45rem);

	--dcv-text-xs:   0.75rem;
	--dcv-text-sm:   0.8125rem;
	--dcv-text-base: 0.9375rem;
	--dcv-text-prose: clamp(1.0625rem, 1rem + 0.28vw, 1.1875rem);

	--dcv-leading-display: 1.02;
	--dcv-leading-title: 1.12;
	--dcv-leading-ui: 1.45;
	--dcv-leading-prose: 1.68;

	/* The project signature: uppercase micro-labels on wide tracking. */
	--dcv-label-tracking: 0.19em;
	--dcv-label-weight: 620;

	/* --- measure and canvas ---------------------------------------------- */
	--dcv-measure: 41rem;   /* ~68 characters at the prose size */
	--dcv-breakout: 56rem;  /* one step wider: figures, ledgers, tables */
	--dcv-canvas-max: 82rem;
	--dcv-gutter: clamp(1.25rem, 4vw, 4.5rem);

	/*
	 * Rail widths, one per degradation state. The full width is set by the
	 * longest label in the architecture set on one line beside its Mark and its
	 * count — a navigation label is never wrapped and never truncated.
	 */
	--dcv-rail-width: 18rem;
	--dcv-rail-width-reduced: 4.5rem;
	--dcv-topbar-height: 3.5rem;
	--dcv-rail-offset: 0px; /* set per state below; the canvas reads only this */

	/* --- spacing: tight inside a group, generous between groups ---------- */
	--dcv-space-3xs: 0.25rem;
	--dcv-space-2xs: 0.5rem;
	--dcv-space-xs:  0.75rem;
	--dcv-space-sm:  1.125rem;
	--dcv-space-md:  1.75rem;
	--dcv-space-lg:  2.75rem;
	--dcv-space-xl:  4rem;
	/*
	 * The step between sections. It was 7rem at a laptop width, so every section
	 * boundary cost 224px of nothing and an archive spent two screens before its
	 * first article. Generous is a virtue on a page a reader is looking at; on a
	 * page a reader is looking *through*, it is a tax.
	 */
	--dcv-space-section: clamp(2.5rem, 4.4vw, 4.5rem);

	/* --- radii: a few pixels at most. Cards are not a universal container. */
	--dcv-radius: 3px;
	--dcv-radius-lg: 4px;

	/* --- motion: orientation and reveal, never spectacle ------------------ */
	--dcv-ease: cubic-bezier(0.16, 1, 0.3, 1);
	--dcv-duration-fast: 180ms;
	--dcv-duration: 420ms;
	--dcv-duration-slow: 900ms;

	/* --- focus: hover and focus produce the same affordance -------------- */
	--dcv-focus-width: 2px;
	--dcv-focus-offset: 3px;
	--dcv-focus-ring: var(--dcv-accent-strong);
}

/*
 * Dark. Declared twice on purpose: once for the OS preference (unless an
 * explicit light override is set), once for the explicit dark override, so the
 * toggle wins in both directions and neither can strand the other.
 */
@media (prefers-color-scheme: dark) {
	:root:not([data-dcv-theme="light"]) {
		color-scheme: dark;

		--dcv-canvas:      oklch(0.207 0.014 138);
		--dcv-canvas-sunk: oklch(0.248 0.015 138);
		--dcv-ink:         oklch(0.940 0.011 86);
		--dcv-muted:       oklch(0.712 0.013 88);
		--dcv-line:        oklch(0.940 0.011 86 / 0.15);
		--dcv-line-strong: oklch(0.940 0.011 86 / 0.30);

		--dcv-accent:        oklch(0.560 0.150 40);
		--dcv-accent-strong: oklch(0.700 0.130 46);

		--dcv-focus-ring: oklch(0.700 0.130 46);
	}
}

:root[data-dcv-theme="dark"] {
	color-scheme: dark;

	--dcv-canvas:      oklch(0.207 0.014 138);
	--dcv-canvas-sunk: oklch(0.248 0.015 138);
	--dcv-ink:         oklch(0.940 0.011 86);
	--dcv-muted:       oklch(0.712 0.013 88);
	--dcv-line:        oklch(0.940 0.011 86 / 0.15);
	--dcv-line-strong: oklch(0.940 0.011 86 / 0.30);

	--dcv-accent:        oklch(0.560 0.150 40);
	--dcv-accent-strong: oklch(0.700 0.130 46);

	--dcv-focus-ring: oklch(0.700 0.130 46);
}

/*
 * Rail degradation, as three states rather than a squeeze. The canvas never
 * reads a width: it reads --dcv-rail-offset, so a state change is one value.
 */
@media (min-width: 60rem) {
	:root { --dcv-rail-offset: var(--dcv-rail-width-reduced); }
}

@media (min-width: 75rem) {
	:root { --dcv-rail-offset: var(--dcv-rail-width); }
}

/*
 * ===========================================================================
 * THE EIGHT PIGMENTS (ADR-0029)
 * ===========================================================================
 *
 * One colour per Hub, so a reader always knows which room of the publication
 * they are standing in — including from the compass in the Rail, which takes the
 * pigment of the section being read.
 *
 * WHAT THIS IS NOT. It is not eight brand colours: the olive is still constant,
 * the canvas still flips alone, and terracotta is still the house accent for
 * everything that belongs to no section. It is one variable — a hue — swapped at
 * the document scope, from which five roles are DERIVED at fixed lightness. That
 * is what keeps eight sections looking like one publication instead of eight.
 *
 * WHY THESE HUES. Each one is the colour its subject actually is: the sea for
 * « où partir », the forest for « besoin de grand air », the lagoon for « le sel
 * et le sable », the brick of a city, the amber of a road at dusk, the wine on a
 * table, the plum of an evening room, the slate of a notebook. A reader should
 * not have to learn this code — recognising it is the whole point.
 *
 * The recorded anti-pattern this stays clear of is a category-reflex PALETTE:
 * hues picked at whatever saturation each one happens to reach, so the set reads
 * as a toy rainbow. That is not what this is. **Only the hue moves.** Lightness
 * is identical across all nine, and chroma sits inside one narrow envelope
 * (0.045–0.145), capped per hue at what sRGB can render — so every section has
 * the same weight on the page, and the olive-and-cream identity still carries it.
 *
 * EVERY VALUE BELOW WAS COMPUTED, NOT ESTIMATED. Against the canvas in both
 * themes, against the olive, and cream against every fill. The worst pair in the
 * whole set is 5.3:1; most are above 8:1.
 *
 *   pigment          hue   ink/canvas  ink/canvas dark  glow/olive  cream/fill
 *   bleu océan       236   5.73        8.39             8.49        5.47
 *   vert forêt       152   5.56        8.52             8.60        5.31
 *   brique            20   6.23        7.97             8.14        5.94
 *   turquoise        195   5.61        8.48             8.56        5.35
 *   ambre             72   5.95        8.20             8.33        5.68
 *   pourpre vin      345   6.22        7.97             8.14        5.94
 *   prune            312   6.08        8.09             8.24        5.81
 *   ardoise          250   5.81        8.31             8.42        5.54
 *   terracotta        40   6.23        7.99             8.15        5.95
 */

/* Où partir — le bleu de l'océan entre les continents, la couleur d'un
   planisphère. */
[data-dcv-hub="destinations"] { --dcv-cat-h: 236; --dcv-cat-c: 0.100; }

/* Besoin de grand air — le vert profond de la forêt et des parcs. */
[data-dcv-hub="randonnee-aventure-nature"] { --dcv-cat-h: 152; --dcv-cat-c: 0.098; }

/* Que faire sur place — la brique et la tuile d'une ville. Écarté du terracotta
   de la maison de 20° : brique côté rouge, terre cuite côté orange. */
[data-dcv-hub="guides-ville-activites"] { --dcv-cat-h: 20; --dcv-cat-c: 0.125; }

/* Le sel et le sable — le turquoise du lagon. */
[data-dcv-hub="plages-iles-paradisiaques"] { --dcv-cat-h: 195; --dcv-cat-c: 0.078; }

/* Prendre la route — l'ambre d'une route au couchant. */
[data-dcv-hub="road-trips-itineraires"] { --dcv-cat-h: 72; --dcv-cat-c: 0.100; }

/* Goûter la culture — le pourpre du vin sur une table. */
[data-dcv-hub="culture-gastronomie-evenements"] { --dcv-cat-h: 345; --dcv-cat-c: 0.115; }

/* Où poser ses valises — la prune d'une chambre le soir. */
[data-dcv-hub="hebergements-sejours"] { --dcv-cat-h: 312; --dcv-cat-c: 0.090; }

/* Bien préparer — l'ardoise du carnet et de la checklist. Le pigment le plus
   sourd du jeu, à dessein : c'est la rubrique qu'on consulte, pas celle dont on
   rêve. */
[data-dcv-hub="conseils-preparation-voyage"] { --dcv-cat-h: 250; --dcv-cat-c: 0.045; }

/* Le journal is every Hub at once, so it keeps the house pigment. */
[data-dcv-hub="journal"] { --dcv-cat-h: 40; --dcv-cat-c: 0.145; }

/*
 * The derivation. Lightness is fixed per role and only the hue moves, which is
 * the whole reason eight pigments hold together: every section's accent has the
 * same weight on the page, and the same contrast against the same grounds.
 *
 * It binds on ANY element carrying a scope, not only the document — the Rail
 * gives each of its eight rows its own scope, so the column can answer in the
 * colour of the row under the pointer.
 */
[data-dcv-hub] {
	--dcv-cat-ink:  oklch(0.485 var(--dcv-cat-c) var(--dcv-cat-h));
	--dcv-cat-glow: oklch(0.800 calc(var(--dcv-cat-c) * 0.62) var(--dcv-cat-h));
	--dcv-cat-fill: oklch(0.480 var(--dcv-cat-c) var(--dcv-cat-h));
	--dcv-cat-wash: oklch(0.945 calc(var(--dcv-cat-c) * 0.16) var(--dcv-cat-h));
	--dcv-cat-line: oklch(0.485 var(--dcv-cat-c) var(--dcv-cat-h) / 0.34);
}

/*
 * A scope also rebinds the house accent tokens themselves, so a component
 * written before any of this existed follows its section without being edited —
 * and so a scoped REGION of an unscoped page (the opening band on the Accueil,
 * which is one Article) is internally consistent rather than half-coloured.
 */
[data-dcv-hub] {
	--dcv-accent:        var(--dcv-cat-ink);
	--dcv-accent-strong: var(--dcv-cat-ink);
	--dcv-accent-action: var(--dcv-cat-fill);
	--dcv-focus-ring:    var(--dcv-cat-ink);
}

/*
 * Dark. The same rule as the rest of the design: only what sits on the canvas
 * flips. Declared twice, once per theme mechanism, for the same reason the
 * canvas is (the toggle must win in both directions).
 */
@media (prefers-color-scheme: dark) {
	:root:not([data-dcv-theme="light"]) [data-dcv-hub] {
		--dcv-cat-ink:  oklch(0.760 calc(var(--dcv-cat-c) * 0.72) var(--dcv-cat-h));
		--dcv-cat-wash: oklch(0.255 calc(var(--dcv-cat-c) * 0.20) var(--dcv-cat-h));
		--dcv-cat-line: oklch(0.760 calc(var(--dcv-cat-c) * 0.72) var(--dcv-cat-h) / 0.34);
	}
}

:root[data-dcv-theme="dark"] [data-dcv-hub] {
	--dcv-cat-ink:  oklch(0.760 calc(var(--dcv-cat-c) * 0.72) var(--dcv-cat-h));
	--dcv-cat-wash: oklch(0.255 calc(var(--dcv-cat-c) * 0.20) var(--dcv-cat-h));
	--dcv-cat-line: oklch(0.760 calc(var(--dcv-cat-c) * 0.72) var(--dcv-cat-h) / 0.34);
}
