/* ============================================================
   2026 ekino Tech Radar — Landing
   ============================================================
   Tokens follow DESIGN.md. Single Graphik family across the
   surface (serif reserved for essays elsewhere). OKLCH only.
   ============================================================ */

/* ------------------------------------------------------------
   Graphik (self-hosted, license inherited from ekino.fr).
   Four static weights. The bold face is declared across the
   700–900 range so the 900 display titles ("2026", hero) render
   as true Graphik bold instead of a synthesised faux-black.
   ------------------------------------------------------------ */
@font-face {
  font-family: "Graphik";
  src: url("/wp-content/themes/AppTheme/assets/fonts/graphik-light-webfont.woff2") format("woff2");
  font-weight: 300;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Graphik";
  src: url("/wp-content/themes/AppTheme/assets/fonts/graphik-regular-webfont.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Graphik";
  src: url("/wp-content/themes/AppTheme/assets/fonts/graphik-semibold-webfont.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Graphik";
  src: url("/wp-content/themes/AppTheme/assets/fonts/graphik-bold-webfont.woff2") format("woff2");
  font-weight: 700 900;
  font-style: normal;
  font-display: swap;
}

:root {
  /* Neutrals: white + neutral grays (chroma 0). */
  --paper-0: #ffffff;
  --paper-1: #f1f1f1;
  --paper-2: #e7e7e7;
  --rule:    #cccccc;
  --ink-3:   oklch(70% 0 0);
  --ink-2:   oklch(55% 0 0);
  --ink-1:   oklch(32% 0 0);
  --ink-0:   oklch(18% 0 0);

  /* Brand & accent */
  --brand-yellow:      oklch(89% 0.17 95);
  --brand-yellow-ink:  oklch(35% 0.05 95);
  --brand-yellow-soft: oklch(96% 0.04 95);
  --ink-link:          oklch(40% 0.16 260);

  /* The four heritage pastels are now TENDANCE colours (t1..t4), not quadrant
     fills. Token names kept for continuity; mapped to tendances in the blip CSS.
     t1 Souveraineté · t2 Agentique · t3 Intention · t4 Agents maison. */
  --quad-techniques: oklch(74% 0.13 350);  /* pink     — tendance 1 */
  --quad-infra:      oklch(84% 0.07 60);   /* peach    — tendance 2 */
  --quad-tools:      oklch(83% 0.08 305);  /* lavender — tendance 3 */
  --quad-languages:  oklch(85% 0.10 165);  /* mint     — tendance 4 */
  --quad-all:        var(--brand-yellow);  /* yellow   — "Tous les quadrants" */
  /* Blips hors tendance : un bleu de la même famille tonale que les quatre
     pastels (chroma médiane 0.07), écho pastel du bleu héritage ekino #4c81c9.
     Sans anneau ni numéro, ils restent distincts des blips tendance. */
  --blip-neutral:    oklch(80% 0.07 245);  /* light blue — no tendance */

  /* Type stacks */
  --font-ui: "Graphik", -apple-system, BlinkMacSystemFont,
             "Helvetica Neue", Helvetica, Arial, sans-serif;

  /* Spatial scale */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 64px;
  --space-9: 96px;
  --space-10: 128px;

  /* Motion */
  --ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1);
  --ease-out-expo:  cubic-bezier(0.16, 1, 0.3, 1);
  --dur-1: 120ms;
  --dur-2: 240ms;
  --dur-3: 480ms;

  /* Focus indicator (WCAG 2.2 — 1.4.11 non-text contrast ≥3:1).
     A dark --ink-0 outline carries the contrast on ANY background
     (≥16:1 on our paper tints, ≥13:1 against the yellow), while an inner
     --brand-yellow halo keeps the brand identity. Works on light surfaces
     and on the dark --ink-0 buttons (yellow rings the button, dark ink rings
     the page). Apply the trio together via these tokens. */
  --focus-outline: 2px solid var(--ink-0);
  --focus-offset: 2px;
  --focus-halo: 0 0 0 2px var(--brand-yellow);

  --measure: 68ch;
  /* Aligned with the corp header container content: .container is
     max-width 1238px with 24px inline paddings → 1190px of content. */
  --bound-wide: 1190px;
  --bound-read: 720px;

  /* Chrome. The global ekino.fr header/footer are provided by the host site;
     only the Tech Radar sub-mast is ours, so the header height is 0. */
  --global-header-h: 0px;
  --sub-mast-h: 80px;
  --chrome-h: calc(var(--global-header-h) + var(--sub-mast-h));
}

@media (max-width: 900px) {
  :root {
    --global-header-h: 0px;
    --sub-mast-h: 64px;
  }
}

/* ============================================================
   Reset & base
   ============================================================ */

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

/* The corp theme (theme.css via wp_head) styles bare ul/ol/li globally
   (disc bullets, padding-left, margin-bottom, 1.4rem/300 type, relative li).
   Neutralize inside the radar shell: every radar list re-styles itself via
   its own class, and those rules come later in this file so they win ties. */
.shell ul,
.shell ol {
  margin: 0;
  padding: 0;
  list-style: none;
}
.shell li {
  list-style: none;
  position: static;
  margin: 0;
  padding: 0;
  font-size: inherit;
  font-weight: inherit;
  line-height: inherit;
}

/* The corp sticky header (.mainHeader, z-index 10 site-wide) must paint above
   the radar's sticky bars (sub-mast 19, filter band 12): raise it on this page
   only (this stylesheet is loaded by the radar page alone). The facet dropdown
   (30) opens downward and never overlaps the header. */
.mainHeader {
  z-index: 40;
}

html {
  /* font-size intentionally unset: the corp reset imposes 62.5% (1rem = 10px);
     every rem value in this file is pre-scaled x1.6 from the upstream build
     (see templates/TechRadar/README.md) */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

body {
  margin: 0;
  font-family: var(--font-ui);
  font-size: 1.7rem; /* 17px editorial body */
  line-height: 1.5;
  color: var(--ink-1);
  background: var(--paper-0);
  /* Only "kern": this Graphik build has buggy OpenType tables — "frac"
     mangled numbers/dates, and ligatures render "<nombre> %" with a stray
     quote glyph (space + % substitution). Disable ligatures explicitly
     (text-rendering:optimizeLegibility would otherwise force them back on). */
  font-feature-settings: "kern";
  font-variant-ligatures: none;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

a {
  color: inherit;
  text-decoration: none;
  text-decoration-skip-ink: auto;
  transition: color var(--dur-1) var(--ease-out-quart);
}

a:focus-visible,
button:focus-visible {
  outline: var(--focus-outline);
  outline-offset: var(--focus-offset);
  box-shadow: var(--focus-halo);
  border-radius: 1px;
}

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

::selection {
  background: var(--brand-yellow-soft);
  color: var(--ink-0);
}

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

.shell {
  display: grid;
  grid-template-rows: auto;
  min-height: 100dvh;
}

.bleed {
  width: 100%;
  /* 24px fixed (was clamp(24px, 4vw, 96px)): matches the corp .container
     inline paddings so radar and header content edges line up */
  padding-inline: var(--space-5);
}

.bleed > .bound {
  max-width: var(--bound-wide);
  margin-inline: auto;
  width: 100%;
}

/* Horizontal hairline divider used between bands */
.hairline {
  border: 0;
  height: 1px;
  background: var(--rule);
  margin: 0;
}

/* ============================================================
   Bar 2 — Tech Radar sub-mast
   ============================================================ */

.sub-mast {
  position: sticky;
  top: var(--global-header-h);
  z-index: 19;
  background: var(--paper-1);
  border-bottom: 1px solid transparent;
  transition: border-color var(--dur-2) var(--ease-out-quart);
}

.sub-mast[data-scrolled] {
  border-bottom-color: var(--rule);
}

.sub-mast > .bound {
  display: grid;
  grid-template-columns: auto auto auto 1fr auto;
  align-items: center;
  gap: clamp(var(--space-4), 2.4vw, var(--space-6));
  height: var(--sub-mast-h);
}

.tr-mark {
  display: inline-grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  column-gap: var(--space-3);
  color: var(--ink-0);
  text-decoration: none;
}

.tr-burst {
  width: auto;
  height: 24px;
  flex-shrink: 0;
}

.tr-words {
  display: grid;
  line-height: 0.95;
}

.tr-line-1 {
  font-weight: 900;
  letter-spacing: -0.02em;
  font-size: clamp(1.5rem, 1.4vw, 1.8rem);
  text-transform: uppercase;
}

.tr-line-2 {
  font-weight: 400;
  color: var(--ink-1);
  font-size: clamp(1.1rem, 0.9vw, 1.2rem);
  letter-spacing: 0;
  margin-top: 2px;
}

.tr-divider {
  width: 1px;
  height: 28px;
  background: var(--rule);
}

.tr-year {
  font-family: var(--font-ui);
  font-weight: 700;
  font-size: 1.3rem;
  letter-spacing: 0.02em;
  color: var(--brand-yellow-ink);
  background: var(--brand-yellow);
  padding: 3px 7px;
  border-radius: 3px;
  font-variant-numeric: tabular-nums;
}

.local-nav {
  justify-self: end;
  display: flex;
  gap: clamp(var(--space-4), 2vw, var(--space-6));
  font-size: 1.4rem;
  font-weight: 500;
  color: var(--ink-2);
}

.local-nav a {
  padding-block: 4px;
  position: relative;
  transition: color var(--dur-1) var(--ease-out-quart);
}

.local-nav a:hover,
.local-nav a:focus-visible {
  color: var(--ink-0);
}

.local-nav a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -2px;
  height: 2px;
  background: var(--brand-yellow);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--dur-2) var(--ease-out-quart);
}

.local-nav a:hover::after,
.local-nav a:focus-visible::after {
  transform: scaleX(1);
}

.tr-burger {
  display: none;
  width: 32px;
  height: 32px;
  border: 0;
  background: transparent;
  cursor: pointer;
  padding: 8px;
  flex-direction: column;
  justify-content: space-between;
}

.tr-burger span {
  display: block;
  height: 1.5px;
  background: var(--ink-0);
  border-radius: 1px;
  transform-origin: center;
  transition: transform var(--dur-1) var(--ease-out-quart);
}

/* Open state: the two bars cross into an X (transform only). */
.tr-burger[aria-expanded="true"] span:first-child {
  transform: translateY(7.25px) rotate(45deg);
}
.tr-burger[aria-expanded="true"] span:last-child {
  transform: translateY(-7.25px) rotate(-45deg);
}

/* Mobile nav panel: drops under the sub-mast (≤900px), replacing the inline
   local-nav that is display:none at this width. Hairline-framed, ≥44px targets. */
.tr-mobile-nav { display: none; }
@media (max-width: 900px) {
  .tr-mobile-nav:not([hidden]) {
    display: flex;
    flex-direction: column;
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    z-index: 18;
    background: var(--paper-1);
    border-top: 1px solid var(--rule);
    border-bottom: 1px solid var(--rule);
    padding-inline: var(--space-5); /* keep in sync with .bleed */
    box-shadow: 0 12px 24px -16px color-mix(in oklch, var(--ink-0) 40%, transparent);
  }
  .tr-mobile-nav a {
    display: flex;
    align-items: center;
    min-height: 44px;
    padding-block: var(--space-2);
    font-size: 1.6rem;
    font-weight: 500;
    color: var(--ink-1);
    border-bottom: 1px solid var(--rule);
    transition: color var(--dur-1) var(--ease-out-quart);
  }
  .tr-mobile-nav a:last-child { border-bottom: 0; }
  .tr-mobile-nav a:hover,
  .tr-mobile-nav a:focus-visible { color: var(--ink-0); }
}

/* Scroll anchors land below the two sticky bars. */
:where([id]) {
  scroll-margin-top: calc(var(--chrome-h) + var(--space-3));
}

/* ============================================================
   Editorial hero (tendances stack, text-only full width)
   ============================================================ */

.hero {
  padding-block:
    clamp(var(--space-6), 6vh, var(--space-8))
    clamp(var(--space-7), 8vh, var(--space-9));
  min-height: calc(100svh - var(--chrome-h));
  display: grid;
  align-items: center;
}

.hero > .bound {
  display: grid;
  grid-template-columns: 1fr;
}

/* — Editorial title block — */

.hero-text {
  display: grid;
  gap: clamp(var(--space-4), 2.4vh, var(--space-5));
  align-content: center;
}

.hero-kicker {
  font-size: 1.3rem;
  font-weight: 500;
  color: var(--ink-2);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin: 0;
  font-variant-numeric: tabular-nums;
}

.hero-heading {
  margin: 0;
  font-size: clamp(3.4rem, 4.8vw, 6.2rem);
  line-height: 0.98;
  font-weight: 900;
  letter-spacing: -0.035em;
  color: var(--ink-0);
  text-wrap: balance;
}

/* The presenting paragraphs: the editorial frame for the four trends.
   Real <p> separated by a small gap (was <br />). */
.hero-intro {
  margin: 0;
  max-width: 80ch;
  display: grid;
  gap: 0.5em;
}
.hero-intro p {
  margin: 0;
  font-size: clamp(1.7rem, 1.45vw, 2.1rem);
  line-height: 1.55;
  color: var(--ink-1);
  letter-spacing: -0.005em;
}

/* — The sommaire: four trends as a rule-separated index — */

.hero-index {
  list-style: none;
  margin: clamp(var(--space-2), 1vh, var(--space-3)) 0 0;
  padding: 0;
  border-top: 1px solid var(--rule);
  counter-reset: none;
}

.hero-index > li {
  border-bottom: 1px solid var(--rule);
}

.hero-tendance {
  display: grid;
  grid-template-columns: auto auto minmax(0, 1fr) auto;
  grid-template-areas:
    "num dot name go"
    "num dot blurb go";
  align-items: center;
  column-gap: clamp(var(--space-3), 1.6vw, var(--space-5));
  row-gap: 2px;
  text-decoration: none;
  color: inherit;
  padding-block: clamp(var(--space-2), 1.1vh, var(--space-3));
  transition: transform var(--dur-2) var(--ease-out-quart);
}

.hero-tendance[data-trend="1"] { --trend-color: var(--quad-techniques); }
.hero-tendance[data-trend="2"] { --trend-color: var(--quad-infra); }
.hero-tendance[data-trend="3"] { --trend-color: var(--quad-tools); }
.hero-tendance[data-trend="4"] { --trend-color: var(--quad-languages); }

.hero-tendance .num {
  grid-area: num;
  align-self: center;
  font-size: 1.4rem;
  font-weight: 600;
  color: var(--ink-2);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}

.hero-tendance .dot {
  grid-area: dot;
  align-self: center;
  width: clamp(11px, 1vw, 14px);
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--trend-color, var(--ink-3));
}

.hero-tendance .name {
  grid-area: name;
  align-self: end;
  font-size: clamp(2.4rem, 2.7vw, 3.8rem);
  line-height: 1;
  font-weight: 900;
  letter-spacing: -0.03em;
  color: var(--ink-0);
  transition: color var(--dur-1) var(--ease-out-quart);
}

.hero-tendance .blurb {
  grid-area: blurb;
  align-self: start;
  font-size: 1.5rem;
  line-height: 1.4;
  color: var(--ink-2);
  max-width: 52ch;
}

.hero-tendance .go {
  grid-area: go;
  align-self: center;
  justify-self: end;
  font-size: 2rem;
  color: var(--trend-color, var(--ink-3));
  opacity: 0;
  transform: translateX(-6px);
  transition: opacity var(--dur-2) var(--ease-out-quart),
              transform var(--dur-2) var(--ease-out-quart);
}

.hero-tendance:hover,
.hero-tendance:focus-visible {
  transform: translateX(clamp(4px, 0.6vw, 10px));
}

.hero-tendance:hover .name,
.hero-tendance:focus-visible .name {
  color: color-mix(in oklch, var(--trend-color) 55%, var(--ink-0));
}

.hero-tendance:hover .go,
.hero-tendance:focus-visible .go {
  opacity: 1;
  transform: translateX(0);
}

@media (prefers-reduced-motion: reduce) {
  .hero-tendance,
  .hero-tendance .go { transition: none; }
  .hero-tendance:hover,
  .hero-tendance:focus-visible { transform: none; }
  .hero-tendance:hover .go,
  .hero-tendance:focus-visible .go { opacity: 1; transform: none; }
}

.hero-scroll {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  font-size: 1.4rem;
  font-weight: 500;
  color: var(--ink-2);
  width: max-content;
  margin-top: var(--space-2);
}

.hero-scroll .arrow {
  font-weight: 400;
  transition: transform var(--dur-2) var(--ease-out-quart);
}

.hero-scroll:hover { color: var(--ink-0); }
.hero-scroll:hover .arrow { transform: translateY(3px); }

/* ============================================================
   Radar band
   ============================================================ */

.radar-band {
  padding-block: clamp(var(--space-7), 8vh, var(--space-10));
  position: relative;
  background: var(--paper-1);
  border-block: 1px solid var(--rule);
}

.radar-band > .bound {
  display: grid;
  gap: clamp(var(--space-5), 4vh, var(--space-7));
}

/* — Heading — */

.radar-head {
  display: grid;
  gap: var(--space-3);
  max-width: 60ch;
}

.radar-head .kicker {
  color: var(--ink-1);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-size: 1.2rem;
  font-weight: 500;
}

.radar-head h2 {
  margin: 0;
  font-size: clamp(2.6rem, 3vw, 4.2rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.05;
  color: var(--ink-0);
  text-wrap: balance;
}

.radar-head .radar-sub {
  margin: 0;
  font-size: 1.5rem;
  line-height: 1.5;
  color: var(--ink-1);
  max-width: 60ch;
  text-wrap: pretty;
}

/* Live result count / empty state */
.radar-status {
  margin: 0;
  font-size: 1.3rem;
  color: var(--ink-1);
  font-variant-numeric: tabular-nums;
}
.radar-status #radar-count { color: var(--ink-0); font-weight: 600; }
.radar-status.is-empty { color: var(--ink-1); font-weight: 500; }

/* — Filter chips — */

.radar-toolbar {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: var(--space-3) var(--space-4);
  /* One line (tendance pills + a Thèmes multi-select dropdown), pinned just
     under the sticky sub-mast so the filters stay visible with the radar.
     overflow visible so the dropdown popover isn't clipped. */
  overflow: visible;
  position: sticky;
  top: var(--chrome-h);
  z-index: 12;
  background: var(--paper-1);
  padding-block: var(--space-2);
  border-bottom: 1px solid var(--rule);
  scroll-padding-inline: var(--space-4);
}

/* Faceted filter groups: hairline-separated, laid out inline on one row. */
.facet-group {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: var(--space-3);
  position: relative;
  flex-shrink: 0;
}

/* Hairline divider between groups (skip the first). */
.facet-group + .facet-group {
  padding-left: var(--space-5);
}
.facet-group + .facet-group::before {
  content: "";
  position: absolute;
  left: 0;
  top: 2px;
  bottom: 4px;
  width: 1px;
  background: var(--rule);
}

.facet-label {
  font-family: var(--font-ui);
  font-size: 1.1rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-1);
}

.facet-pills {
  display: flex;
  flex-wrap: nowrap;
  gap: var(--space-2);
  flex-shrink: 0;
}

.radar-search {
  font-family: var(--font-ui);
  font-size: 1.4rem;
  color: var(--ink-0);
  background: var(--paper-0);
  border: 1px solid var(--rule);
  border-radius: 100px;
  padding: var(--space-2) var(--space-4);
  width: 100%;
  box-sizing: border-box;
  min-height: 38px;
  transition: border-color var(--dur-1) var(--ease-out-quart);
}
.radar-search::placeholder { color: var(--ink-2); }
.radar-search:hover { border-color: var(--ink-3); }
.radar-search:focus-visible {
  outline: var(--focus-outline);
  outline-offset: var(--focus-offset);
  box-shadow: var(--focus-halo);
  border-color: var(--ink-0);
}

.radar-filter {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  min-height: 34px;
  flex-shrink: 0;
  white-space: nowrap;
  border: 1px solid var(--rule);
  border-radius: 100px;
  background: var(--paper-0);
  font-family: var(--font-ui);
  font-size: 1.3rem;
  font-weight: 500;
  color: var(--ink-2);
  cursor: pointer;
  transition: border-color var(--dur-1) var(--ease-out-quart),
              color var(--dur-1) var(--ease-out-quart),
              background-color var(--dur-1) var(--ease-out-quart);
}

.radar-filter:hover { color: var(--ink-0); border-color: var(--ink-3); }

.radar-filter[aria-pressed="true"] {
  color: var(--ink-0);
  border-color: var(--ink-0);
  background: var(--paper-2);
}

.radar-filter:focus-visible {
  outline: var(--focus-outline);
  outline-offset: var(--focus-offset);
  box-shadow: var(--focus-halo);
  border-color: var(--ink-0);
}

.chip-dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}

.chip-dot[data-quad="all"]        { background: var(--quad-all); }
.chip-dot[data-quad="techniques"] { background: var(--quad-techniques); }
.chip-dot[data-quad="infra"]      { background: var(--quad-infra); }
.chip-dot[data-quad="tools"]      { background: var(--quad-tools); }
.chip-dot[data-quad="languages"]  { background: var(--quad-languages); }

/* IA chip: a yellow border is the wink to the yellow AI blip ring. */
.radar-filter--ai { border-color: var(--brand-yellow); }
.radar-filter--ai:hover { border-color: var(--brand-yellow); }
.radar-filter--ai[aria-pressed="true"] {
  border-color: var(--brand-yellow);
  background: var(--brand-yellow);
  color: var(--brand-yellow-ink);
  font-weight: 600;
}

/* — Thèmes multi-select dropdown — */
.facet-dd { position: relative; }

.facet-dd-toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  min-height: 34px;
  border: 1px solid var(--rule);
  border-radius: 100px;
  background: var(--paper-0);
  font-family: var(--font-ui);
  color: var(--ink-2);
  cursor: pointer;
  white-space: nowrap;
  transition: border-color var(--dur-1) var(--ease-out-quart),
              color var(--dur-1) var(--ease-out-quart),
              background-color var(--dur-1) var(--ease-out-quart);
}
.facet-dd-toggle .facet-label {
  font-size: 1.3rem;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: inherit;
}
.facet-dd-toggle:hover { color: var(--ink-0); border-color: var(--ink-3); }
.facet-dd-toggle:focus-visible {
  outline: var(--focus-outline);
  outline-offset: var(--focus-offset);
  box-shadow: var(--focus-halo);
  border-color: var(--ink-0);
}
.facet-dd-toggle.is-active {
  color: var(--ink-0);
  border-color: var(--ink-0);
  background: var(--paper-2);
}

.facet-dd-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 100px;
  background: var(--brand-yellow);
  color: var(--ink-0);
  font-size: 1.1rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.facet-dd-count[hidden] { display: none; }

.facet-dd-caret {
  width: 0;
  height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 5px solid currentColor;
  margin-left: 2px;
  transition: transform var(--dur-1) var(--ease-out-quart);
}
.facet-dd-toggle[aria-expanded="true"] .facet-dd-caret { transform: rotate(180deg); }

.facet-dd-menu {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  z-index: 30;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  width: max-content;
  max-width: min(420px, 86vw);
  padding: var(--space-3);
  background: var(--paper-0);
  border: 1px solid var(--rule);
  border-radius: 8px;
  box-shadow: 0 12px 32px -12px color-mix(in oklch, var(--ink-0) 40%, transparent);
}
.facet-dd-menu[hidden] { display: none; }

/* — Stage: radar + drawer — */

.radar-stage {
  display: grid;
  /* radar | adoption-level index. The detail panel is now an overlay
     (slide-over), not a grid column. */
  grid-template-columns: minmax(0, 1fr) clamp(220px, 22vw, 300px);
  gap: clamp(var(--space-4), 2vw, var(--space-6));
  align-items: start;
  position: relative;
}

.radar-mount {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 1;
  /* Cap by available height so the whole radar (with its corner labels) fits
     in the viewport beneath the sticky sub-mast + filter bar — filters and
     radar stay visible together without scrolling the labels out of view. */
  max-width: min(86vmin, 820px, calc(100svh - var(--chrome-h) - 12.8rem));
  margin-inline: auto;
}

/* Anchor jumps (#radar, nav) land below the sticky chrome. */
#radar { scroll-margin-top: var(--chrome-h); }

.radar-svg {
  width: 100%;
  height: 100%;
  overflow: visible;
  font-family: var(--font-ui);
}

/* Rings — darkened from --rule to --ink-3 for legibility/contrast (a11y). */
/* White plot disc behind the rings: the radar circle reads white on the grey band. */
.radar-svg .radar-disc { fill: var(--paper-0); }
.radar-svg .ring { stroke: var(--ink-3); }
.radar-svg .ring-core { stroke: var(--ink-3); }

/* Quadrant separators — same darker ink, near-full opacity so they read. */
.radar-svg .axis { stroke: var(--ink-3); stroke-width: 1; stroke-opacity: 0.9; }

/* Ring labels */
.radar-svg .ring-label {
  fill: var(--ink-1);
  font-size: 15px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  paint-order: stroke;
  stroke: var(--paper-0);
  stroke-width: 4;
  pointer-events: none;
}

/* Center mark */
.radar-svg .radar-center-bg { fill: var(--ink-0); }
.radar-svg .radar-center {
  fill: var(--brand-yellow);
  font-size: 44px;
  font-weight: 900;
  letter-spacing: -0.04em;
}

/* Blips */
.radar-svg .blip { cursor: pointer; outline: none; }

/* Marker = circle for every blip. Scaled via transform. ONE ring max per blip:
   AI blips get a yellow ring that REPLACES the tendance ring (never two rings),
   while tendance members get a tendance-coloured ring. Colour now encodes
   TENDANCE, not quadrant: a blip in tendance N carries that tendance hue in
   --qc, plus a ring and a number (1..4). Blips in no tendance render neutral
   black. Position still encodes the quadrant (the spatial axes). */
.radar-svg .blip[data-tendance="t1"] { --qc: var(--quad-techniques); }
.radar-svg .blip[data-tendance="t2"] { --qc: var(--quad-infra); }
.radar-svg .blip[data-tendance="t3"] { --qc: var(--quad-tools); }
.radar-svg .blip[data-tendance="t4"] { --qc: var(--quad-languages); }

/* Marker fill = tendance hue when in a tendance, else neutral black. */
.radar-svg .blip-marker {
  /* No tendance = quiet pastel blue: same tonal family as the tendance hues,
     but ring-less and number-less, so these background blips harmonise with
     the coloured population without competing with it. */
  fill: var(--qc, var(--blip-neutral));
  stroke: none;
  transform-box: fill-box;
  transform-origin: center;
  transition: transform var(--dur-1) var(--ease-out-quart),
              fill-opacity var(--dur-1) var(--ease-out-quart),
              stroke var(--dur-1) var(--ease-out-quart);
}

/* Single ring: tendance colour by default (members). */
.radar-svg .blip-ring {
  stroke: var(--qc);
  stroke-width: 1.6;
  transform-box: fill-box;
  transform-origin: center;
  transition: transform var(--dur-1) var(--ease-out-quart);
}
/* AI blips: the ring is yellow and REPLACES the tendance ring (one ring max). */
.radar-svg .blip[data-ai="true"] .blip-ring {
  stroke: var(--brand-yellow);
}
.radar-svg .blip-num {
  fill: var(--ink-0);
  font: 600 9px var(--font-ui);
  text-anchor: middle;
  dominant-baseline: central;
  pointer-events: none;
  transform-box: fill-box;
  transform-origin: center;
  transition: transform var(--dur-1) var(--ease-out-quart);
}

.radar-svg .blip:hover .blip-marker,
.radar-svg .blip:focus-visible .blip-marker { transform: scale(1.3); }

.radar-svg .blip:focus-visible .blip-marker {
  stroke: var(--ink-0);
  stroke-width: 2;
}

/* Selected blip = the same blip, scaled up uniformly: it keeps its tendance
   colour, its original ring (now enlarged) and its number. No extra halo —
   the bigger dot + bigger ring is the selection cue. */
.radar-svg .blip.is-selected .blip-marker,
.radar-svg .blip.is-selected .blip-ring,
.radar-svg .blip.is-selected .blip-num {
  transform: scale(2);
}

/* Radar "ping": expanding, fading rings that loop continuously out of the
   selected blip. Two rings staggered by half a cycle so one is always moving. */
.radar-svg .blip-pulse {
  fill: none;
  stroke: none;
  pointer-events: none;
  transform-box: fill-box;
  transform-origin: center;
}
/* The wave is born at scale(2) = exactly on the selected ring (14×2=28) or at
   the selected dot's edge (10×2=20), then radiates far beyond the glyph: the
   static ring is the emitter, never an obstacle. */
@keyframes blip-ping {
  0%   { transform: scale(2);   stroke-opacity: 0.55; }
  100% { transform: scale(4.6); stroke-opacity: 0; }
}
.radar-svg .blip.is-selected .blip-pulse {
  stroke: var(--qc, var(--blip-neutral));
  stroke-width: 1.4;
  animation: blip-ping 2s linear infinite;
}
/* An AI blip emits yellow waves from its yellow ring (whatever its fill). */
.radar-svg .blip[data-ai="true"].is-selected .blip-pulse {
  stroke: var(--brand-yellow);
}
.radar-svg .blip.is-selected .blip-pulse--2 { animation-delay: -1s; }

/* Filtering / highlight: blips not matching the active filter dim out.
   Driven by JS toggling .is-dimmed (covers AI, tendance, cat, lang modes). */
.radar-svg .blip.is-dimmed .blip-marker,
.radar-svg .blip.is-dimmed .blip-ring,
.radar-svg .blip.is-dimmed .blip-num {
  fill-opacity: 0.1;
  stroke-opacity: 0.1;
}
.radar-svg .blip.is-dimmed .blip-marker { fill: var(--ink-3); }
/* A selected blip is never visually dimmed, even under an active filter. */
.radar-svg .blip.is-selected.is-dimmed .blip-marker { fill: var(--qc, var(--blip-neutral)); }
.radar-svg .blip.is-selected.is-dimmed .blip-marker,
.radar-svg .blip.is-selected.is-dimmed .blip-ring,
.radar-svg .blip.is-selected.is-dimmed .blip-num {
  fill-opacity: 1;
  stroke-opacity: 1;
}
.radar-svg .blip.is-dimmed:hover .blip-marker,
.radar-svg .blip.is-dimmed:focus-visible .blip-marker,
.radar-svg .blip.is-dimmed:hover .blip-ring,
.radar-svg .blip.is-dimmed:focus-visible .blip-ring,
.radar-svg .blip.is-dimmed:hover .blip-num,
.radar-svg .blip.is-dimmed:focus-visible .blip-num {
  fill-opacity: 0.75;
  stroke-opacity: 0.75;
}

@media (prefers-reduced-motion: reduce) {
  .radar-svg .blip-marker { transition: none; }
  .radar-svg .blip.is-selected .blip-pulse { animation: none; }
}

/* Floating hover/focus label */
.radar-tip {
  position: absolute;
  transform: translate(-50%, -130%);
  background: var(--ink-0);
  color: var(--paper-0);
  font-size: 1.2rem;
  font-weight: 500;
  padding: 4px 8px;
  border-radius: 4px;
  pointer-events: none;
  white-space: nowrap;
  z-index: 3;
}

/* Quadrant labels (HTML layer, corners of the stage) */
.radar-quad-labels {
  position: absolute;
  inset: 0;
  margin: 0;
  padding: 0;
  list-style: none;
  pointer-events: none;
}

.radar-quad-labels li {
  position: absolute;
  font-size: clamp(1.5rem, 1.1vw, 1.7rem);
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--ink-1);
  max-width: 14ch;
  line-height: 1.15;
}

/* Place labels at the four corners of the radar mount (left column only). */
.radar-quad-labels li[data-quad="techniques"] { top: 0; left: 0; }
.radar-quad-labels li[data-quad="tools"]       { top: 0; right: 0; text-align: right; }
.radar-quad-labels li[data-quad="infra"]       { bottom: 0; left: 0; }
.radar-quad-labels li[data-quad="languages"]   { bottom: 0; right: 0; text-align: right; }

/* — Detail = slide-over overlay (desktop) / bottom sheet (≤640px) — */

/* Scrim: only opaque on the ≤640px bottom-sheet. On desktop the radar stays
   visible and interactive (DESIGN.md: no blocking modal). */
.radar-scrim { display: none; }

.radar-drawer {
  position: fixed;
  top: var(--chrome-h);
  right: 0;
  bottom: 0;
  width: clamp(320px, 30vw, 420px);
  z-index: 15;
  background: var(--paper-0);
  border-left: 1px solid var(--rule);
  box-shadow: -8px 0 32px -16px color-mix(in oklch, var(--ink-0) 35%, transparent);
  padding: clamp(var(--space-4), 2vw, var(--space-6));
  overflow: auto;
  /* Hidden by default: slid off to the right, inert. */
  transform: translateX(100%);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: transform var(--dur-2) var(--ease-out-quart),
              opacity var(--dur-2) var(--ease-out-quart),
              visibility 0s linear var(--dur-2);
}

.radar-drawer.is-open {
  transform: translateX(0);
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: transform var(--dur-2) var(--ease-out-quart),
              opacity var(--dur-2) var(--ease-out-quart);
}

@media (prefers-reduced-motion: reduce) {
  .radar-drawer { transition: none; }
}

.drawer-detail { position: relative; }

/* Header row: ‹ › prev/next + close, each a 44×44 touch target. */
.drawer-nav {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}

.drawer-prev,
.drawer-next,
.drawer-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border: 1px solid var(--rule);
  background: var(--paper-0);
  font-size: 2.2rem;
  line-height: 1;
  color: var(--ink-1);
  cursor: pointer;
  border-radius: 4px;
  transition: border-color var(--dur-1) var(--ease-out-quart),
              color var(--dur-1) var(--ease-out-quart),
              background-color var(--dur-1) var(--ease-out-quart);
}
.drawer-prev:hover,
.drawer-next:hover,
.drawer-close:hover { color: var(--ink-0); border-color: var(--ink-3); background: var(--paper-1); }

.drawer-prev:focus-visible,
.drawer-next:focus-visible,
.drawer-close:focus-visible {
  outline: var(--focus-outline);
  outline-offset: var(--focus-offset);
  box-shadow: var(--focus-halo);
  border-color: var(--ink-0);
}

.drawer-prev[disabled],
.drawer-next[disabled] {
  opacity: 0.35;
  cursor: default;
  pointer-events: none;
}

.drawer-close {
  margin-left: auto;
  font-size: 2.4rem;
}

.drawer-name:focus-visible {
  outline: var(--focus-outline);
  outline-offset: var(--focus-offset);
  box-shadow: var(--focus-halo);
  border-radius: 2px;
}

.drawer-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
  margin: 0 0 var(--space-3);
  font-size: 1.2rem;
}

.drawer-quad {
  color: var(--ink-2);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-weight: 500;
}

/* Maturity badges are NEUTRAL (hairline pill, no fill): colour now encodes
   tendances only, a tinted ring badge would read as a tendance link. */
.drawer-ring {
  font-weight: 600;
  padding: 3px 8px;
  border-radius: 100px;
  border: 1px solid var(--rule);
  color: var(--ink-1);
}

.drawer-name {
  margin: 0 0 var(--space-3);
  font-size: clamp(1.8rem, 1.6vw, 2.4rem);
  font-weight: 700;
  letter-spacing: -0.015em;
  line-height: 1.1;
  color: var(--ink-0);
  text-wrap: balance;
}

.drawer-body {
  font-size: 1.5rem;
  line-height: 1.6;
  color: var(--ink-1);
}

.drawer-body p { margin: 0 0 var(--space-3); }
.drawer-body p:last-child { margin-bottom: 0; }

.drawer-cats {
  list-style: none;
  margin: var(--space-4) 0 0;
  padding: var(--space-4) 0 0;
  border-top: 1px solid var(--rule);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.drawer-cats li {
  font-size: 1.2rem;
  color: var(--ink-1);
  background: var(--paper-1);
  border: 1px solid var(--rule);
  padding: 3px 8px;
  border-radius: 100px;
}

.drawer-cats li.is-ai {
  color: var(--brand-yellow-ink);
  background: var(--brand-yellow);
  border-color: transparent;
  font-weight: 600;
}

/* Tendance chips: shown first, coloured with the tendance hue (matching the blip). */
.drawer-cats li.is-tendance {
  color: var(--ink-0);
  border-color: transparent;
  font-weight: 600;
}
.drawer-cats li.is-tendance[data-tendance="t1"] { background: var(--quad-techniques); }
.drawer-cats li.is-tendance[data-tendance="t2"] { background: var(--quad-infra); }
.drawer-cats li.is-tendance[data-tendance="t3"] { background: var(--quad-tools); }
.drawer-cats li.is-tendance[data-tendance="t4"] { background: var(--quad-languages); }

/* Clickable chips mirror the toolbar filters (filter the radar on click). */
.drawer-cats li.is-clickable {
  cursor: pointer;
  transition: border-color var(--dur-1) var(--ease-out-quart),
              filter var(--dur-1) var(--ease-out-quart);
}
.drawer-cats li.is-clickable:hover { border-color: var(--ink-0); filter: brightness(0.96); }
.drawer-cats li.is-clickable:focus-visible {
  outline: var(--focus-outline);
  outline-offset: var(--focus-offset);
  box-shadow: var(--focus-halo);
}

.drawer-link {
  display: inline-flex;
  align-items: center;
  width: max-content;
  margin-top: var(--space-3);
  font-size: 1.4rem;
  font-weight: 500;
  color: var(--ink-link);
  border-bottom: 1px solid color-mix(in oklch, var(--ink-link) 35%, transparent);
  padding-bottom: 1px;
  transition: border-color var(--dur-1) var(--ease-out-quart);
}
.drawer-link:hover { border-bottom-color: var(--ink-link); }
.drawer-link[hidden] { display: none; }

.drawer-copy {
  margin-top: var(--space-5);
  margin-left: auto;
  display: flex;
  width: max-content;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--rule);
  border-radius: 100px;
  background: var(--paper-0);
  font-family: var(--font-ui);
  font-size: 1.3rem;
  font-weight: 500;
  color: var(--ink-1);
  cursor: pointer;
  transition: border-color var(--dur-1) var(--ease-out-quart), color var(--dur-1) var(--ease-out-quart);
}
.drawer-copy::before {
  content: "";
  width: 13px; height: 13px;
  border: 1.5px solid currentColor;
  border-radius: 3px;
  opacity: 0.7;
}
.drawer-copy:hover { border-color: var(--ink-3); color: var(--ink-0); }
.drawer-copy .copy-done { display: none; }
.drawer-copy.is-copied { color: var(--brand-yellow-ink); border-color: var(--brand-yellow); }
.drawer-copy.is-copied .copy-label { display: none; }
.drawer-copy.is-copied .copy-done { display: inline; }
.drawer-copy.is-copied::before {
  border-color: var(--brand-yellow-ink);
  background: var(--brand-yellow);
}

/* — Mobile list (radar alternative ≤900px) — */

.radar-list { display: none; }     /* shown only at ≤900px (see media query) */

.radar-list-group { margin-bottom: var(--space-6); }

.radar-list-head {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  margin: 0 0 var(--space-2);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--rule);
  font-size: 1.3rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-0);
}
.radar-list-head .dot { width: 10px; height: 10px; border-radius: 50%; }
.radar-list-head .dot[data-quad="techniques"] { background: var(--quad-techniques); }
.radar-list-head .dot[data-quad="infra"]      { background: var(--quad-infra); }
.radar-list-head .dot[data-quad="tools"]      { background: var(--quad-tools); }
.radar-list-head .dot[data-quad="languages"]  { background: var(--quad-languages); }
.radar-list-head .count { margin-left: auto; color: var(--ink-1); font-variant-numeric: tabular-nums; }

.radar-list-item { border-bottom: 1px solid var(--rule); }

.radar-list-item > summary {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) 0;
  cursor: pointer;
  list-style: none;
}
.radar-list-item > summary::-webkit-details-marker { display: none; }

.radar-list-item .ai-glyph {
  width: 11px; height: 11px;
  border-radius: 50%;
  background: var(--blip-neutral);
  box-shadow: 0 0 0 2px var(--brand-yellow);
  flex-shrink: 0;
}
.radar-list-item .li-name { font-weight: 500; color: var(--ink-0); font-size: 1.5rem; }

.radar-list-item .li-ring {
  margin-left: auto;
  font-size: 1.1rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 2px 7px;
  border-radius: 100px;
  border: 1px solid var(--rule);
  color: var(--ink-1);
}

.radar-list-item .li-body {
  padding: 0 0 var(--space-4);
  font-size: 1.4rem;
  line-height: 1.55;
  color: var(--ink-1);
}
.radar-list-item .li-body p { margin: 0 0 var(--space-3); }
.radar-list-item .li-cats {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.radar-list-item .li-cats li {
  font-size: 1.1rem;
  color: var(--ink-1);
  background: var(--paper-1);
  border: 1px solid var(--rule);
  padding: 2px 7px;
  border-radius: 100px;
}

/* — Adoption-level list (desktop column beside the radar) — */

.radar-rings {
  position: sticky;
  top: calc(var(--chrome-h) + var(--space-4));
  display: flex;
  flex-direction: column;
  max-height: calc(100vh - var(--chrome-h) - var(--space-7));
  background: var(--paper-0);
  border: 1px solid var(--rule);
  border-radius: 4px;
  --rings-pad: clamp(var(--space-3), 1.4vw, var(--space-5));
  padding: var(--rings-pad);
}

/* Fixed header (out of the scroll zone) + scrollable body. */
.rings-search {
  flex: 0 0 auto;
  margin-bottom: var(--space-3);
}

.rings-title {
  flex: 0 0 auto;
  margin: 0 0 var(--space-3);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--rule);
  font-size: 1.2rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-2);
}

.rings-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  /* Pull the scrollbar out to the panel's right border, and pad the content
     back so item text and the count sit clear of the scrollbar. */
  margin-right: calc(-1 * var(--rings-pad));
  padding-right: var(--rings-pad);
}

.rings-group { margin-bottom: var(--space-4); }
.rings-group:last-child { margin-bottom: 0; }

.rings-head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0 0 var(--space-2);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--rule);
}

.rings-badge {
  font-size: 1.1rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 2px 8px;
  border-radius: 100px;
  border: 1px solid var(--rule);
  color: var(--ink-1);
}

.rings-count {
  margin-left: auto;
  font-size: 1.2rem;
  color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}

.rings-items { list-style: none; margin: 0; padding: 0; }

.rings-item { margin: 0; }
.rings-item[hidden] { display: none; }

.rings-link {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  padding: 5px var(--space-2);
  border: 0;
  border-radius: 4px;
  background: transparent;
  font-family: var(--font-ui);
  font-size: 1.3rem;
  line-height: 1.3;
  color: var(--ink-1);
  text-align: left;
  cursor: pointer;
  transition: background var(--dur-1) var(--ease-out-quart), color var(--dur-1) var(--ease-out-quart);
}
.rings-link:hover { background: var(--paper-1); color: var(--ink-0); }
.rings-link:focus-visible { outline: 2px solid var(--ink-link); outline-offset: -2px; }

.rings-item.is-active .rings-link {
  background: var(--brand-yellow-soft);
  color: var(--ink-0);
  font-weight: 600;
}

.rings-dot {
  width: 9px; height: 9px;
  border-radius: 50%;
  flex-shrink: 0;
  background: var(--blip-neutral); /* default: no tendance = pastel blue (mirrors the radar) */
}
.rings-dot[data-tendance="t1"] { background: var(--quad-techniques); }
.rings-dot[data-tendance="t2"] { background: var(--quad-infra); }
.rings-dot[data-tendance="t3"] { background: var(--quad-tools); }
.rings-dot[data-tendance="t4"] { background: var(--quad-languages); }

/* AI item: yellow ring around the dot (mirrors the radar blip). */
.rings-dot[data-ai="true"] {
  box-shadow: 0 0 0 2px var(--brand-yellow);
  margin: 2px;
}

.rings-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ============================================================
   Tendances detail bands
   ============================================================ */

.tendance-band {
  border-top: 1px solid var(--rule);
  padding-block: clamp(var(--space-8), 10vh, var(--space-10));
  position: relative;
  isolation: isolate;
}

.tendance-band[data-trend="1"] { --tc: var(--quad-techniques); }
.tendance-band[data-trend="2"] { --tc: var(--quad-infra); }
.tendance-band[data-trend="3"] { --tc: var(--quad-tools); }
.tendance-band[data-trend="4"] { --tc: var(--quad-languages); }

/* The pastels are light; for text and the large number, use a darkened
   same-hue ink so the tendance identity survives at AA contrast. */
.tendance-band { --tc-ink: color-mix(in oklch, var(--tc) 55%, var(--ink-0)); }


.tendance-band > .bound {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: clamp(var(--space-6), 5vw, var(--space-9));
  align-items: start;
}

.tendance-marker {
  display: grid;
  gap: var(--space-4);
  align-content: start;
  position: sticky;
  /* below the full chrome (corp header + sub-mast), not a bare viewport
     offset (was clamp(48px, 12vh, 96px), tuned for the standalone build) */
  top: calc(var(--chrome-h) + var(--space-5));
}

.tendance-marker .num {
  font-size: clamp(4rem, 6vw, 7.2rem);
  font-weight: 900;
  letter-spacing: -0.04em;
  line-height: 0.9;
  color: var(--tc-ink);
  font-variant-numeric: tabular-nums;
}

.tendance-marker .name {
  font-size: clamp(2rem, 2vw, 2.6rem);
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.15;
  color: var(--ink-0);
  margin: 0;
}

.tendance-body {
  display: grid;
  gap: var(--space-5);
  max-width: var(--measure);
}

.tendance-body .lede {
  font-size: clamp(1.8rem, 1.5vw, 2.2rem);
  line-height: 1.4;
  color: var(--ink-0);
  font-weight: 500;
  letter-spacing: -0.005em;
  max-width: none;
}

.tendance-body p {
  font-size: 1.7rem;
  line-height: 1.6;
  color: var(--ink-1);
  margin: 0;
}

.tendance-body .read-more {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-3);
  color: var(--tc-ink);
  font-weight: 500;
  font-size: 1.5rem;
  border-bottom: 1px solid color-mix(in oklch, var(--tc) 55%, transparent);
  padding-bottom: 2px;
  width: max-content;
}

.tendance-body .read-more:hover {
  border-bottom-color: var(--tc);
}

.tendance-technos-intro {
  margin: var(--space-4) 0 var(--space-2);
  font-size: 1.4rem;
  color: var(--ink-2);
}
.tendance-technos-intro span { color: var(--tc-ink); font-weight: 700; font-variant-numeric: tabular-nums; }

.tendance-technos {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0;
}

.tendance-technos li {
  border-bottom: 1px solid color-mix(in oklch, var(--tc) 18%, var(--rule));
}

.tendance-technos li:last-child { border-bottom: 0; }

.tendance-technos .t-link {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--space-4);
  align-items: baseline;
  /* Full-bleed row: padding only (no negative margin, no radius) so the hover
     fill spans flush from the top hairline to the bottom one, edge to edge. */
  padding-block: var(--space-2);
  text-decoration: none;
  color: inherit;
  transition: background-color var(--dur-1) var(--ease-out-quart);
}

.tendance-technos .t-link:hover {
  background-color: color-mix(in oklch, var(--tc) 12%, transparent);
}

.tendance-technos .t-link:hover .t-name {
  color: var(--tc-ink);
}

.tendance-technos .t-link:focus-visible {
  outline: 2px solid var(--tc-ink);
  outline-offset: 2px;
}

.tendance-technos .t-name {
  color: var(--ink-0);
  font-weight: 500;
  font-size: 1.5rem;
  transition: color var(--dur-1) var(--ease-out-quart);
}

.tendance-technos .t-ring {
  color: var(--tc-ink);
  font-weight: 600;
  font-size: 1.1rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

@media (pointer: coarse) {
  .tendance-technos .t-link {
    min-height: 44px;
    align-items: center;
    padding-block: var(--space-3);
  }
}

/* ============================================================
   Articles (prolonger la lecture)
   ============================================================ */

.articles {
  padding-block: clamp(var(--space-8), 10vh, var(--space-10));
  border-top: 1px solid var(--rule);
}

.articles > .bound {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: clamp(var(--space-6), 5vw, var(--space-9));
  align-items: start;
}

.articles .kicker {
  color: var(--ink-2);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-size: 1.2rem;
  font-weight: 500;
  margin-bottom: var(--space-3);
}

.articles .title {
  font-size: clamp(2.6rem, 3vw, 4.2rem);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.02em;
  margin: 0;
  color: var(--ink-0);
}

.articles .body { display: grid; }

.article-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border-bottom: 1px solid var(--rule);
}

.article-item {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--space-5);
  align-items: start;
  padding-block: var(--space-5);
  border-top: 1px solid var(--rule);
  text-decoration: none;
  color: inherit;
}

.article-text { display: grid; gap: var(--space-2); }

.article-title {
  font-size: clamp(1.8rem, 1.7vw, 2.4rem);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--ink-0);
  transition: color var(--dur-1) var(--ease-out-quart);
  max-width: 34ch;
}

.article-excerpt {
  font-size: 1.5rem;
  line-height: 1.5;
  color: var(--ink-2);
  max-width: 56ch;
}

.article-meta {
  font-size: 1.2rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-2);
}

.article-arrow {
  font-size: 1.8rem;
  color: var(--ink-2);
  align-self: center;
  transition: transform var(--dur-2) var(--ease-out-expo), color var(--dur-1) var(--ease-out-quart);
}

.article-item:hover .article-title,
.article-item:focus-visible .article-title { color: var(--ink-link); }
.article-item:hover .article-arrow,
.article-item:focus-visible .article-arrow { transform: translate(3px, -3px); color: var(--ink-0); }

.article-all {
  display: inline-flex; align-items: center; gap: var(--space-2); width: max-content;
  margin-top: var(--space-5);
  font-family: var(--font-ui); font-weight: 600; color: var(--ink-0); text-decoration: none;
  border-bottom: 2px solid var(--brand-yellow); padding-bottom: 2px;
}
/* Animate the arrow (transform), not the layout `gap`. */
.article-all span[aria-hidden="true"] { transition: transform var(--dur-1) var(--ease-out-quart); }
.article-all:hover span[aria-hidden="true"] { transform: translateX(3px); }

/* ============================================================
   Solutions ekino (zone dédiée : ekos / Ekino Agentic Foundation)
   ============================================================ */
/* Grey band, no border-top: the background shift delimits the section (the
   layout already carries enough hairlines). Mirrors the radar band surface. */
.solutions {
  padding-block: clamp(var(--space-8), 10vh, var(--space-10));
  background: var(--paper-1);
}
.solutions .kicker {
  color: var(--ink-1); letter-spacing: 0.1em; text-transform: uppercase;
  font-size: 1.2rem; font-weight: 500; margin-bottom: var(--space-3);
}
.solutions .title {
  margin: 0; font-size: clamp(2.6rem, 3vw, 4.2rem); font-weight: 700;
  letter-spacing: -0.02em; line-height: 1.05; color: var(--ink-0); text-wrap: balance;
}
.solutions-lede {
  margin: var(--space-4) 0 0; max-width: var(--measure);
  font-size: clamp(1.7rem, 1.4vw, 2rem); line-height: 1.5; color: var(--ink-1);
}

/* Feature blocks (ekos / Ekino Agentic Foundation), full-width with a CTA. */
.article-features {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(var(--space-5), 3vw, var(--space-7));
  margin-top: var(--space-7);
}
/* Two side-by-side blocks: text stacked, contact CTA aligned at the bottom. */
.feature-block {
  border-top: 1px solid var(--rule);
  padding-top: var(--space-5);
  display: grid;
  grid-template-rows: auto auto 1fr auto;
  gap: var(--space-3);
}
.feature-kicker {
  margin: 0;
  font-size: 1.2rem; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--ink-1); font-weight: 500;
}
.feature-title {
  margin: 0;
  font-size: clamp(2.4rem, 2.4vw, 3.4rem); font-weight: 700;
  letter-spacing: -0.02em; line-height: 1.05; color: var(--ink-0);
}
.feature-desc {
  margin: 0;
  font-size: 1.5rem; line-height: 1.55; color: var(--ink-1);
}
.feature-cta {
  justify-self: start; align-self: end; margin-top: var(--space-3);
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: var(--space-3) var(--space-5);
  background: var(--ink-0); color: var(--paper-0);
  border-radius: 100px; text-decoration: none; white-space: nowrap;
  font-family: var(--font-ui); font-weight: 600; font-size: 1.5rem;
  transition: background-color var(--dur-1) var(--ease-out-quart),
              color var(--dur-1) var(--ease-out-quart);
}
.feature-cta:hover { background: var(--brand-yellow); color: var(--brand-yellow-ink); }
.feature-cta:focus-visible {
  outline: var(--focus-outline);
  outline-offset: var(--focus-offset);
  box-shadow: var(--focus-halo);
}
.feature-soon {
  margin: 0;
  width: max-content;
  font-size: 1.1rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--brand-yellow-ink); background: var(--brand-yellow-soft);
  padding: 2px 8px; border-radius: 100px;
}
.article-item.is-soon { cursor: default; }
.article-item.is-soon .article-title { color: var(--ink-2); }
.article-item.is-soon .article-arrow { color: var(--ink-3); }
@media (max-width: 640px) {
  .article-features { grid-template-columns: 1fr; gap: var(--space-6); }
}

/* ============================================================
   Responsive
   ============================================================ */


@media (max-width: 900px) {
  .tendance-band > .bound,
  .articles > .bound {
    grid-template-columns: 1fr;
  }

  .tendance-marker { position: static; }

  /* Sub-mast hides local nav at this breakpoint */
  .local-nav { display: none; }
  .tr-burger { display: flex; }
  .sub-mast > .bound {
    grid-template-columns: 1fr auto auto;
  }
  .tr-divider { display: none; }

  /* Radar stays the hero down to ~640px; the index stacks below it. */
  .radar-stage {
    grid-template-columns: 1fr;
  }
  .radar-rings {
    position: static;
    max-height: none;
  }
  .radar-list { display: none; }

  /* Toolbar wraps onto several rows (no horizontal overflow 641–900px). Each
     facet group takes a full row and stacks its label above its pills, so the
     pills wrap within the viewport width instead of forcing a scroll. */
  .radar-toolbar { flex-wrap: wrap; }
  .facet-group {
    flex-basis: 100%;
    flex-direction: column;
    align-items: flex-start;
  }
  .facet-pills { flex-wrap: wrap; width: 100%; }
  .facet-group + .facet-group { padding-left: 0; }
  .facet-group + .facet-group::before { display: none; }
  .radar-search { width: 100%; }
}

@media (max-width: 640px) {
  .radar-mount {
    max-width: min(96vw, 560px);
  }
  /* Quadrant corner labels get tiny on small screens to avoid blip overlap. */
  .radar-quad-labels li { font-size: 1rem; max-width: 9ch; }

  .tr-line-2 { display: none; }

  /* Below this width the SVG is too dense for touch: swap to the list index.
     Keep only the name search from the right panel, moved above the list. */
  .radar-mount { display: none; }
  .radar-rings {
    display: block;
    order: -1;            /* search sits above the mobile list (DOM order has it last) */
    position: static;
    max-height: none;
    border: 0;
    padding: 0;
    margin-bottom: var(--space-5);
    background: none;
  }
  .radar-rings .rings-title,
  .radar-rings .rings-scroll { display: none; }
  .radar-rings .rings-search { margin-bottom: 0; }
  .radar-list { display: block; }

  /* Detail becomes a bottom sheet: full width, slides up, with a scrim
     and a light focus trap (DESIGN.md exception for mobile). */
  .radar-scrim {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 14;
    background: color-mix(in oklch, var(--ink-0) 45%, transparent);
    opacity: 0;
    transition: opacity var(--dur-2) var(--ease-out-quart);
    pointer-events: none;
  }
  .radar-scrim.is-open { opacity: 1; pointer-events: auto; }

  .radar-drawer {
    top: auto;
    left: 0;
    right: 0;
    bottom: 0;
    width: auto;
    max-height: 82vh;
    border-left: 0;
    border-top: 1px solid var(--rule);
    border-radius: 12px 12px 0 0;
    box-shadow: 0 -8px 32px -16px color-mix(in oklch, var(--ink-0) 45%, transparent);
    transform: translateY(100%);
  }
  .radar-drawer.is-open { transform: translateY(0); }

  @media (prefers-reduced-motion: reduce) {
    .radar-scrim { transition: none; }
  }
}

/* Touch devices get larger tap targets regardless of viewport width. */
@media (pointer: coarse) {
  .radar-filter { min-height: 44px; }
  .radar-search { min-height: 44px; }
  .rings-link { min-height: 44px; }
  .radar-list-item > summary { min-height: 44px; }
}

/* Filter pills collapse behind a "Filtres" disclosure on phones. */
.radar-filters-toggle { display: none; }   /* desktop: toolbar always visible, no toggle */
@media (max-width: 640px) {
  .radar-filters-toggle {
    display: inline-flex; align-items: center; gap: var(--space-2);
    min-height: 44px; padding: var(--space-2) var(--space-4);
    border: 1px solid var(--rule); border-radius: 100px;
    background: var(--paper-0);
    font-family: var(--font-ui); font-size: 1.4rem; font-weight: 500;
    color: var(--ink-1); cursor: pointer;
  }
  .radar-filters-toggle[aria-expanded="true"] { border-color: var(--ink-0); color: var(--ink-0); }
  /* On phones the toolbar is a collapsible panel, not a sticky one-line bar. */
  .radar-toolbar {
    display: none;
    position: static;
    top: auto;
    overflow: visible;
    flex-wrap: wrap;
    border-bottom: 0;
    padding-block: 0;
    background: none;
  }
  .radar-toolbar.is-open { display: flex; }
  .facet-group { flex-direction: column; align-items: flex-start; }
  .facet-pills { flex-wrap: wrap; }
  /* On phones the themes show inline (no popover) — the toolbar is already a
     collapsible panel, so a nested dropdown is redundant. */
  .facet-dd-toggle { display: none; }
  .facet-dd-menu {
    position: static;
    display: flex;
    width: auto;
    max-width: none;
    padding: 0;
    border: 0;
    box-shadow: none;
    background: none;
  }
  .facet-dd-menu[hidden] { display: flex; }
}

@media (max-width: 640px) {
  /* Index drops the trailing arrow (no hover on touch) and tightens type. */
  .hero-tendance {
    grid-template-columns: auto auto minmax(0, 1fr);
    grid-template-areas:
      "num dot name"
      "num dot blurb";
    column-gap: var(--space-3);
  }
  .hero-tendance .go { display: none; }
  .hero-tendance .name { font-size: clamp(2.2rem, 6.4vw, 3rem); }
  .hero-tendance .blurb { font-size: 1.4rem; }
}

@media (min-width: 1280px) {
  .hero {
    padding-block: clamp(var(--space-8), 10vh, var(--space-10));
  }
}

/* ============================================================
   Article page (article.html) — long-form, radar-linked
   ============================================================ */
.article-page {
  padding-block: clamp(var(--space-7), 8vh, var(--space-9));
  background: var(--paper-0);
}
.article-page > .bound { max-width: 73.6rem; }

.article-head { margin-bottom: var(--space-7); }
.article-kicker {
  margin: 0 0 var(--space-3);
  font-size: 1.2rem; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ink-2); font-weight: 500;
}
.article-h1 {
  margin: 0 0 var(--space-4);
  font-size: clamp(3rem, 4vw, 4.8rem);
  font-weight: 700; letter-spacing: -0.02em; line-height: 1.05;
  color: var(--ink-0); text-wrap: balance;
}
.article-standfirst {
  margin: 0; max-width: 42ch;
  font-size: clamp(1.8rem, 1.6vw, 2.2rem); line-height: 1.4;
  color: var(--ink-1); font-weight: 500;
}

.article-body { font-size: 1.7rem; line-height: 1.65; color: var(--ink-0); }
.article-body p { margin: 0 0 var(--space-4); text-wrap: pretty; }
.article-body a {
  color: var(--ink-0);
  text-decoration: underline; text-underline-offset: 2px; text-decoration-thickness: 1px;
  text-decoration-color: color-mix(in oklch, var(--ink-0) 35%, transparent);
  transition: text-decoration-color var(--dur-1) var(--ease-out-quart);
}
.article-body a:hover { text-decoration-color: var(--brand-yellow); }

.article-section { margin-top: var(--space-7); }
.article-section h2 {
  margin: 0 0 var(--space-4);
  font-size: clamp(2.2rem, 2.2vw, 3rem);
  font-weight: 700; letter-spacing: -0.015em; line-height: 1.15; color: var(--ink-0);
}
/* Punchline: no side-stripe. A short yellow filet ABOVE the line + generous
   vertical margins carry the emphasis typographically. */
.article-punch {
  position: relative;
  margin: var(--space-7) 0;
  padding-top: var(--space-4);
  font-size: clamp(1.8rem, 1.6vw, 2.2rem); font-weight: 600; color: var(--ink-0);
}
.article-punch::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 48px;
  height: 2px;
  background: var(--brand-yellow);
}
.article-cta {
  display: inline-flex; align-items: center; gap: var(--space-2);
  font-family: var(--font-ui); font-weight: 600; font-size: 1.5rem;
  color: var(--ink-0); text-decoration: none;
  border-bottom: 2px solid var(--brand-yellow); padding-bottom: 2px; width: max-content;
}
.article-cta span[aria-hidden="true"] { transition: transform var(--dur-1) var(--ease-out-quart); }
.article-cta:hover span[aria-hidden="true"] { transform: translateX(3px); }
.article-cta:focus-visible {
  outline: var(--focus-outline);
  outline-offset: var(--focus-offset);
  box-shadow: var(--focus-halo);
}

/* Per-tendance "on the radar" list, accented with the tendance hue. */
.radar-technos {
  --tc: var(--ink-0);
  margin: var(--space-5) 0 var(--space-6);
  padding: var(--space-4) var(--space-5);
  background: var(--paper-1);
  border: 1px solid var(--rule);
  border-radius: 4px;
}
.radar-technos[data-trend="1"] { --tc: var(--quad-techniques); }
.radar-technos[data-trend="2"] { --tc: var(--quad-infra); }
.radar-technos[data-trend="3"] { --tc: var(--quad-tools); }
.radar-technos[data-trend="4"] { --tc: var(--quad-languages); }
.radar-technos-title {
  margin: 0 0 var(--space-3);
  font-family: var(--font-ui); font-size: 1.2rem; letter-spacing: 0.08em;
  text-transform: uppercase; font-weight: 600; color: var(--ink-1);
}
/* Tendance identity now lives in the title (coloured dot), not a side-stripe. */
.radar-technos-title::before {
  content: "";
  display: inline-block;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  margin-right: var(--space-2);
  background: var(--tc);
}
.radar-technos-title span { color: color-mix(in oklch, var(--tc) 60%, var(--ink-0)); font-weight: 700; }
.radar-technos ul {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 0 var(--space-5);
}
.radar-technos li {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-2);
  padding-block: 6px;
  border-bottom: 1px solid color-mix(in oklch, var(--tc) 15%, var(--rule));
}
.radar-technos li a { text-decoration: none; color: var(--ink-0); font-size: 1.5rem; }
.radar-technos li a:hover { text-decoration: underline; text-underline-offset: 2px; text-decoration-color: var(--tc); }
.radar-technos .tr-ring {
  flex-shrink: 0;
  font-family: var(--font-ui); font-size: 1rem; letter-spacing: 0.06em; text-transform: uppercase;
  font-weight: 600; color: color-mix(in oklch, var(--tc) 55%, var(--ink-0));
}

.article-sources ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-3); }
.article-sources li { position: relative; padding-left: var(--space-4); font-size: 1.5rem; line-height: 1.5; color: var(--ink-1); }
.article-sources li::before { content: ""; position: absolute; left: 0; top: 0.6em; width: 4px; height: 4px; border-radius: 50%; background: var(--ink-3); }
.article-sources strong { color: var(--ink-0); }

.article-note {
  margin-top: var(--space-5); padding-top: var(--space-4);
  border-top: 1px solid var(--rule);
  font-size: 1.5rem; color: var(--ink-1);
}
.article-back {
  display: inline-flex; align-items: center; gap: var(--space-2);
  margin-top: var(--space-7);
  font-family: var(--font-ui); font-weight: 600; color: var(--ink-0); text-decoration: none;
}
/* Back-arrow points left, so it slides left on hover. */
.article-back span[aria-hidden="true"] { transition: transform var(--dur-1) var(--ease-out-quart); }
.article-back:hover span[aria-hidden="true"] { transform: translateX(-3px); }

/* ============================================================
   Tendance key figure (chiffre clé, depuis l'article)
   ============================================================ */
.tendance-stat { margin: var(--space-3) 0 0; font-size: 1.4rem; line-height: 1.5; color: var(--ink-2); }
.tendance-stat strong { color: var(--tc-ink); font-weight: 700; }
.tendance-stat em { font-style: italic; color: var(--ink-2); }

