// Atomes partagés : couleurs des couches, puces sociétés, badges, en-têtes
const LAYER_HUES = { L1: 262, L2: 215, L3: 32, L4: 175, L5: 95, L6: 320, L7: 0 };
const layerColor = (id, l = 0.72, c = 0.11) => `oklch(${l} ${c} ${LAYER_HUES[id]})`;
const layerFaint = (id) => `oklch(0.24 0.025 ${LAYER_HUES[id]})`;

const SIZE_ORDER = ["MEGA", "LARGE", "MID", "SMALL"];
const SIZE_STYLE = {
  MEGA:  { fs: 17, pad: "9px 16px",  weight: 640, dot: 11 },
  LARGE: { fs: 15, pad: "7px 13px",  weight: 560, dot: 8.5 },
  MID:   { fs: 13, pad: "5px 10px",  weight: 480, dot: 6.5 },
  SMALL: { fs: 11.5, pad: "3px 8px", weight: 430, dot: 4.5 },
};
const PROFIL_LABEL = { COEUR: "Cœur", MIXTE: "Mixte", SPEC: "Spéc", DISRUPTE: "Disrupté" };
const PROFIL_DESC = {
  COEUR: "Exposition IA directe et prouvée",
  MIXTE: "Exposition partielle ou thèse contestée",
  SPEC: "Optionnalité pré-revenus / pré-volume",
  DISRUPTE: "Exposition négative à l'IA",
};

// Puce société — taille de police = capitalisation ; style de bord = profil
function ChipSociete({ soc, accent, onClick, active, dim }) {
  const sz = SIZE_STYLE[soc.taille];
  const hue = LAYER_HUES[soc.couche];
  const isSpec = soc.profil === "SPEC";
  const isDisr = soc.profil === "DISRUPTE";
  const isCoeur = soc.profil === "COEUR";
  const border = isDisr
    ? "1px solid oklch(0.55 0.16 25 / 0.55)"
    : isSpec
      ? `1px dashed ${accent}88`
      : isCoeur
        ? `1px solid oklch(0.5 0.06 ${hue} / 0.65)`
        : `1px solid oklch(0.45 0.02 ${hue} / 0.5)`;
  return (
    <button
      onClick={onClick}
      title={soc.these}
      style={{
        display: "inline-flex", alignItems: "baseline", gap: 7,
        fontFamily: "var(--sans)", fontSize: sz.fs, fontWeight: sz.weight,
        padding: sz.pad, lineHeight: 1.25,
        color: isDisr ? "oklch(0.72 0.1 25)" : dim ? "oklch(0.55 0.01 80)" : "var(--ink)",
        background: active
          ? `oklch(0.32 0.05 ${hue})`
          : isCoeur ? `oklch(0.21 0.022 ${hue})` : "oklch(0.17 0.008 260)",
        border, borderRadius: 3, cursor: "pointer",
        opacity: dim ? 0.32 : 1,
        boxShadow: active ? `0 0 0 1.5px ${layerColor(soc.couche)}` : "none",
        transition: "opacity .18s, box-shadow .18s, background .18s",
        textDecoration: isDisr ? "line-through" : "none",
        textDecorationColor: "oklch(0.55 0.16 25 / 0.6)",
        textDecorationThickness: 1,
      }}
    >
      <span>{soc.nom}</span>
      <span style={{
        fontFamily: "var(--mono)", fontSize: Math.max(sz.fs - 4.5, 8.5),
        fontWeight: 400, color: `oklch(0.62 0.05 ${hue})`, letterSpacing: "0.02em",
      }}>{soc.ticker}</span>
    </button>
  );
}

// Pastille de taille pour les légendes
function DotTaille({ taille, accent }) {
  const d = SIZE_STYLE[taille].dot;
  return <span style={{
    width: d, height: d, borderRadius: "50%", flex: "none",
    background: accent || "var(--ink)", display: "inline-block",
  }}></span>;
}

function Kicker({ children, color }) {
  return <div style={{
    fontFamily: "var(--mono)", fontSize: 11, letterSpacing: "0.22em",
    textTransform: "uppercase", color: color || "var(--accent)", marginBottom: 10,
  }}>{children}</div>;
}

function HairTitle({ children, size = 30 }) {
  return <h2 style={{
    fontFamily: "var(--serif)", fontWeight: 480, fontSize: size,
    lineHeight: 1.12, margin: 0, color: "var(--ink)", textWrap: "pretty",
  }}>{children}</h2>;
}

// Badge goulet
function BadgeGoulet({ children, accent }) {
  return <span style={{
    display: "inline-flex", alignItems: "center", gap: 6,
    fontFamily: "var(--mono)", fontSize: 10.5, letterSpacing: "0.08em",
    color: accent, border: `1px solid ${accent}55`,
    padding: "3px 9px", borderRadius: 999, whiteSpace: "nowrap",
  }}>
    <span style={{ width: 5, height: 5, borderRadius: "50%", background: accent, animation: "pulse 2.4s infinite" }}></span>
    {children}
  </span>;
}

Object.assign(window, { LAYER_HUES, layerColor, layerFaint, SIZE_ORDER, SIZE_STYLE, PROFIL_LABEL, PROFIL_DESC, ChipSociete, DotTaille, Kicker, HairTitle, BadgeGoulet });
