/* ============================================================================
   ZLEF — Charts, Graphs & Timelines · shared visualization chrome
   Source of truth: https://da.zlef.fr  ·  pairs with zl-charts.js
   ----------------------------------------------------------------------------
   Import AFTER tokens.css in any zlef.fr project that draws data:
       <link rel="stylesheet" href="https://da.zlef.fr/tokens.css">
       <link rel="stylesheet" href="https://da.zlef.fr/zl-charts.css">
       <script defer src="https://da.zlef.fr/zl-charts.js"></script>

   Method follows the ZLEF data-viz rules (see da.zlef.fr § Charts, llms.txt):
   ONE axis (never dual), fixed categorical order (never cycled), a legend for
   ≥2 series, selective direct labels, hairline grid, 2px surface gaps between
   touching marks, tooltips by default (hover on desktop, tap on mobile), and a
   table-view twin of every chart. ZLEF is dark-only, so there is one mode.

   The categorical palette is CVD-validated on the ZLEF chart surface (#0e0e13):
   worst *adjacent* Machado-2009 ΔE = 14.7 (clears the ≥12 target), so bars,
   lines, stacks and areas are safe on color alone. Scatter/heatmap/small-
   multiples (where ANY two marks can touch) sit in the 8–12 floor band → the
   engine ships secondary encoding there (direct labels + optional texture).
   ========================================================================== */

:root {
  /* ── Categorical slots — fixed order, assigned 1..N in sequence, NEVER cycled.
        A 9th series is not a new hue; it folds into "Other" (--zlc-other). ── */
  --zlc-cat-1: #8a9a3c;   /* olive-green  (ties to the ZLEF primary accent)   */
  --zlc-cat-2: #a86fb2;   /* grape-mauve  (ties to the ZLEF secondary accent) */
  --zlc-cat-3: #b8842a;   /* amber                                            */
  --zlc-cat-4: #cf5064;   /* rose-red                                         */
  --zlc-cat-5: #159a8b;   /* teal                                             */
  --zlc-cat-6: #6f7ad0;   /* periwinkle (data-only muted blue, not a UI hue)  */
  --zlc-cat-7: #c65f37;   /* terracotta                                       */
  --zlc-cat-8: #3fa877;   /* aqua-green                                       */

  /* ── Sequential ramp — one hue (olive), near-surface → bright = low → high.
        For heatmaps / choropleths / magnitude. ── */
  --zlc-seq-1: #23281a;
  --zlc-seq-2: #39421c;
  --zlc-seq-3: #556025;
  --zlc-seq-4: #74842f;
  --zlc-seq-5: #93a747;
  --zlc-seq-6: #b3c766;
  --zlc-seq-7: #d6e29a;

  /* ── Diverging pair — rose-red ↔ neutral gray ↔ olive (polarity / vs target) */
  --zlc-div-neg-2: #c2566a;
  --zlc-div-neg-1: #8f4a56;
  --zlc-div-mid:   #3a3a42;   /* neutral gray midpoint (reads as "nothing")    */
  --zlc-div-pos-1: #647534;
  --zlc-div-pos-2: #9dae50;

  /* ── Status — RESERVED for state (good→critical); always with icon+label.
        Distinct from the categorical slots so status never impersonates a series. */
  --zlc-good:     var(--zl-success);   /* #6f9a3a */
  --zlc-warning:  var(--zl-warning);   /* #c79a3e */
  --zlc-serious:  #c65f37;
  --zlc-critical: var(--zl-danger);    /* #c2566a */

  /* ── Chart chrome & ink (mapped to the ZLEF tokens) ── */
  --zlc-surface:   var(--zl-surface-1);           /* the chart plane           */
  --zlc-grid:      var(--zl-line);                /* hairline gridlines        */
  --zlc-axis:      var(--zl-line-strong);         /* baseline / axis           */
  --zlc-ink:       var(--zl-text);                /* values, emphasis          */
  --zlc-ink-2:     var(--zl-text-soft);           /* labels                    */
  --zlc-ink-muted: var(--zl-text-muted);          /* axis ticks, captions      */
  --zlc-other:     #55564f;                       /* "Other" / de-emphasis gray */
  --zlc-deemph:    #33343b;                       /* emphasis-chart background series */
}

/* ============================================================================
   FIGURE — the container every chart mounts in
   ========================================================================== */
.zlc {
  display: block;
  margin: 0;
  color: var(--zlc-ink);
  font-family: var(--zl-font);
  --_anim: var(--zl-dur) var(--zl-ease);
}
/* ── no mobile blue tap-flash / no UA blue focus ring anywhere in a chart.
      (-webkit-tap-highlight-color is inherited, but we name the roots, the svg
      and the hit layer explicitly per spec.) Real controls keep the DA ring. ── */
.zlc, .zlc svg, .zlc-svg, .zlc-scroll, .zlc .tip-hit, .zlc-btn, #zlc-tip {
  -webkit-tap-highlight-color: transparent;
}
.zlc svg:focus, .zlc-svg:focus, .zlc .tip-hit, .zlc .tip-hit:focus,
.zlc-tl-node, .zlc-tl-period, .zlc-bar, .zlc-cell { outline: none; }
.zlc-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--zl-space-4); margin-bottom: var(--zl-space-3);
}
.zlc-titles { min-width: 0; }
.zlc-title { font-size: var(--zl-text-lg); font-weight: var(--zl-weight-bold); line-height: 1.25; }
.zlc-sub   { font-size: var(--zl-text-sm); color: var(--zlc-ink-muted); margin-top: 2px; }
.zlc-actions { display: flex; gap: 6px; flex: none; }
.zlc-btn {
  font: inherit; font-size: var(--zl-text-xs); font-weight: var(--zl-weight-medium);
  color: var(--zlc-ink-2); background: transparent;
  border: 1px solid var(--zl-line-strong); border-radius: var(--zl-radius-sm);
  padding: 5px 9px; min-height: 30px; cursor: pointer;
  transition: color var(--_anim), border-color var(--_anim), background var(--_anim);
}
.zlc-btn:hover { color: var(--zlc-ink); border-color: rgba(255,255,255,.22); background: rgba(255,255,255,.04); }
.zlc-btn[aria-pressed="true"] { color: var(--zl-accent-soft); border-color: rgba(157,174,80,.4); background: var(--zl-accent-wash); }
.zlc-btn:focus { outline: none; }
.zlc-btn:focus-visible { outline: none; box-shadow: var(--zl-focus-ring); }

/* horizontal-scroll shell — dense temporal charts get a min-width in JS and
   scroll inside their own box instead of overflowing the page. */
.zlc-scroll { overflow-x: auto; overflow-y: hidden; scrollbar-width: thin; }
.zlc-scroll::-webkit-scrollbar { height: 8px; }
.zlc-scroll::-webkit-scrollbar-thumb { background: var(--zl-surface-3); border-radius: var(--zl-radius-pill); }

svg.zlc-svg { display: block; width: 100%; height: auto; overflow: visible; }
.zlc[data-loading] svg.zlc-svg { opacity: .4; transition: opacity var(--zl-dur-slow) var(--zl-ease); }

/* ── zoom + pan (temporal charts) ── */
.zlc-plot { position: relative; }
.zlc-scroll.zlc-zoomable { touch-action: pan-x; cursor: grab; overscroll-behavior-x: contain; }
.zlc-scroll.zlc-zoomable:active { cursor: grabbing; }
.zlc-scroll.zlc-zoomable svg.zlc-svg { overflow: hidden; }   /* pixel-mode: clip to its own width */
.zlc-yover { position: absolute; top: 0; left: 0; z-index: 2; height: 100%; width: auto;
             pointer-events: none; overflow: visible; }
/* zoom control cluster (segmented) in the actions row */
.zlc-zoom { display: inline-flex; gap: 0; }
.zlc-zoom .zlc-zbtn { width: 32px; padding: 0; font-size: 17px; line-height: 1; border-radius: 0;
                      margin-left: -1px; }
.zlc-zoom .zlc-zbtn:first-child { border-radius: var(--zl-radius-sm) 0 0 var(--zl-radius-sm); margin-left: 0; }
.zlc-zoom .zlc-zbtn:last-child  { border-radius: 0 var(--zl-radius-sm) var(--zl-radius-sm) 0; }
.zlc-zoom .zlc-zbtn:hover { z-index: 1; }
.zlc-zoom .zlc-zbtn:disabled { opacity: .35; cursor: not-allowed; }

/* ── SVG marks (specs are fixed across every chart) ── */
.zlc-svg .zlc-grid-line { stroke: var(--zlc-grid); stroke-width: 1; shape-rendering: crispEdges; }
.zlc-svg .zlc-base      { stroke: var(--zlc-axis); stroke-width: 1; shape-rendering: crispEdges; }
.zlc-svg .zlc-ax        { fill: var(--zlc-ink-muted); font-size: 12px; font-family: var(--zl-font); }
.zlc-svg .zlc-ax--y     { text-anchor: end; }
.zlc-svg .zlc-axtitle   { fill: var(--zlc-ink-2); font-size: 12.5px; font-weight: var(--zl-weight-medium); }
.zlc-svg .zlc-line      { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round;
                          transition: opacity var(--_anim); }
.zlc-svg .zlc-area      { stroke: none; }
.zlc-svg .zlc-bar       { transition: opacity var(--_anim), filter var(--_anim); }
.zlc-svg .zlc-bar.hot   { filter: brightness(1.18); }
.zlc-svg .zlc-dot       { transition: r 120ms var(--zl-ease); }
.zlc-svg .zlc-dot.hot   { r: 6.5; }
.zlc-svg .zlc-cross     { stroke: var(--zl-line-strong); stroke-width: 1; shape-rendering: crispEdges;
                          opacity: 0; pointer-events: none; transition: opacity var(--zl-dur-fast) var(--zl-ease); }
.zlc-svg .zlc-cross.on  { opacity: 1; }
.zlc-svg .zlc-dlabel    { fill: var(--zlc-ink); font-size: 12px; font-weight: var(--zl-weight-medium);
                          font-variant-numeric: tabular-nums; paint-order: stroke;
                          stroke: var(--zlc-surface); stroke-width: 3px; }
.zlc-svg .zlc-seglabel  { font-size: 11.5px; font-weight: var(--zl-weight-medium); }
/* stacked-column total — muted direct label above the top of each stack */
.zlc-svg .zlc-total     { fill: var(--zlc-ink-muted); font-size: 11.5px; font-weight: var(--zl-weight-medium);
                          font-variant-numeric: tabular-nums; text-anchor: middle; paint-order: stroke;
                          stroke: var(--zlc-surface); stroke-width: 3px; }
.zlc-svg .tip-hit       { fill: transparent; cursor: pointer; }
/* series greyed out via legend isolate */
.zlc-svg .zlc-faded     { opacity: .14 !important; }

/* ── Legend (HTML — the dependable identity channel for ≥2 series) ── */
.zlc-legend {
  display: flex; flex-wrap: wrap; gap: 6px 16px; margin-top: var(--zl-space-3);
  font-size: var(--zl-text-sm); color: var(--zlc-ink-2);
}
.zlc-legend .zlc-key {
  display: inline-flex; align-items: center; gap: 8px; cursor: pointer; user-select: none;
  padding: 2px 4px; border-radius: var(--zl-radius-sm);
  -webkit-tap-highlight-color: transparent;
  transition: color var(--_anim), opacity var(--_anim), box-shadow var(--zl-dur-fast) var(--zl-ease);
}
.zlc-legend .zlc-key:hover { color: var(--zlc-ink); }
/* keep a keyboard focus ring, but use the DA olive ring — never the UA blue */
.zlc-legend .zlc-key:focus { outline: none; }
.zlc-legend .zlc-key:focus-visible { outline: none; box-shadow: var(--zl-focus-ring); }
.zlc-legend .zlc-key[aria-pressed="false"] { opacity: .4; }
.zlc-legend .zlc-key i { flex: none; }
.zlc-legend .zlc-key .sw-rect { width: 13px; height: 13px; border-radius: 3px; }
.zlc-legend .zlc-key .sw-line { width: 16px; height: 3px; border-radius: 2px; }

/* ── Floating tooltip — one node, shared across every chart on the page ── */
#zlc-tip {
  position: fixed; z-index: 9999; pointer-events: none;
  left: -9999px; top: -9999px; max-width: 260px;
  background: rgba(14,14,19,.97); color: var(--zl-text);
  border: 1px solid var(--zl-line-strong); border-radius: var(--zl-radius-md);
  box-shadow: var(--zl-shadow-md); backdrop-filter: blur(6px);
  padding: 9px 11px; font-family: var(--zl-font); font-size: var(--zl-text-sm);
  opacity: 0; transform: translateY(3px);
  transition: opacity var(--zl-dur-fast) var(--zl-ease), transform var(--zl-dur-fast) var(--zl-ease);
}
#zlc-tip.show { opacity: 1; transform: none; }
#zlc-tip .tip-head { font-weight: var(--zl-weight-bold); font-size: var(--zl-text-xs);
  letter-spacing: .02em; color: var(--zlc-ink-2); margin-bottom: 6px; }
#zlc-tip .tip-row { display: flex; align-items: baseline; gap: 8px; padding: 1px 0; }
#zlc-tip .tip-row .k { display: inline-block; width: 12px; height: 3px; border-radius: 2px;
  flex: none; align-self: center; }
#zlc-tip .tip-row .k.dot { width: 9px; height: 9px; border-radius: 50%; }
#zlc-tip .tip-row .lb { color: var(--zlc-ink-2); font-size: var(--zl-text-sm); margin-right: auto; }
#zlc-tip .tip-row .vl { font-weight: var(--zl-weight-bold); font-variant-numeric: tabular-nums; }
/* stacked "Total" row — set off by a hairline divider, brighter ink */
#zlc-tip .tip-sep { height: 1px; background: var(--zl-line-strong); margin: 6px 0 5px; }
#zlc-tip .tip-row.tip-total .lb { color: var(--zlc-ink); font-weight: var(--zl-weight-bold); }
#zlc-tip .tip-row.tip-total .vl { color: var(--zlc-ink); }

/* ============================================================================
   FIGURE FORMS — stat tile · meter · sparkline
   ========================================================================== */
.zlc-stat { display: flex; flex-direction: column; gap: 4px; }
.zlc-stat-label { font-size: var(--zl-text-sm); color: var(--zlc-ink-muted); }
.zlc-stat-row   { display: flex; align-items: flex-end; gap: 10px; flex-wrap: wrap; }
.zlc-stat-val   { font-size: var(--zl-text-3xl); font-weight: var(--zl-weight-bold);
                  line-height: 1; letter-spacing: -.01em; }        /* proportional figures */
.zlc-stat-delta { display: inline-flex; align-items: center; gap: 3px; font-size: var(--zl-text-sm);
                  font-weight: var(--zl-weight-medium); }
.zlc-stat-delta.up   { color: var(--zlc-good); }
.zlc-stat-delta.down { color: var(--zlc-critical); }
.zlc-stat-delta.flat { color: var(--zlc-ink-muted); }
.zlc-stat-sub  { font-size: var(--zl-text-xs); color: var(--zlc-ink-muted); }
.zlc-hero { font-size: clamp(48px, 8vw, 72px); font-weight: var(--zl-weight-bold); line-height: 1;
            letter-spacing: -.02em; }

.zlc-meter { display: block; }
.zlc-meter-track {
  position: relative; height: 12px; border-radius: var(--zl-radius-pill);
  background: var(--zl-surface-2); overflow: hidden;
}
.zlc-meter-fill {
  position: absolute; inset: 0 auto 0 0; border-radius: inherit;
  background: var(--zl-accent-soft);
  transition: width var(--zl-dur-slow) var(--zl-ease), background var(--zl-dur) var(--zl-ease);
}
.zlc-meter-fill.warning  { background: var(--zlc-warning); }
.zlc-meter-fill.critical { background: var(--zlc-critical); }
.zlc-meter-head { display: flex; justify-content: space-between; font-size: var(--zl-text-sm);
                  margin-bottom: 6px; color: var(--zlc-ink-2); }
.zlc-meter-head b { color: var(--zlc-ink); font-variant-numeric: tabular-nums; }
.zlc-spark { display: inline-block; vertical-align: middle; height: 1.4em; }

/* ============================================================================
   TABLE VIEW — the accessibility twin of every chart
   ========================================================================== */
.zlc-table-wrap { overflow-x: auto; margin-top: var(--zl-space-3); }
.zlc-table { border-collapse: collapse; width: 100%; font-size: var(--zl-text-sm);
             font-variant-numeric: tabular-nums; }
.zlc-table th, .zlc-table td { padding: 8px 16px; text-align: right; border-bottom: 1px solid var(--zl-line); }
.zlc-table th:first-child, .zlc-table td:first-child { text-align: left; padding-left: 4px; }
.zlc-table thead th { color: var(--zlc-ink-2); font-weight: var(--zl-weight-bold);
                      border-bottom-color: var(--zl-line-strong); white-space: nowrap; }
.zlc-table tbody tr:hover { background: rgba(255,255,255,.03); }
/* series swatch — lives in the header th (and any td); keep a clear gap to its label */
.zlc-table th .sw, .zlc-table td .sw { display: inline-block; width: 10px; height: 10px;
                    border-radius: 2px; margin-right: 8px; vertical-align: middle; }
/* Total column — right-aligned, mono (table is tabular-nums), emphasised */
.zlc-table .zlc-total-col { font-weight: var(--zl-weight-bold); color: var(--zlc-ink);
                    border-left: 1px solid var(--zl-line); }
.zlc-table thead th.zlc-total-col { color: var(--zlc-ink-2); }

/* ============================================================================
   TIMELINE — events & periods along a time axis
   ========================================================================== */
.zlc-tl { display: flex; flex-direction: column; }
.zlc-tl .zlc-tl-axis { stroke: var(--zlc-axis); stroke-width: 2; }
.zlc-tl .zlc-tl-tick { stroke: var(--zlc-grid); stroke-width: 1; shape-rendering: crispEdges; }
.zlc-tl .zlc-tl-period { transition: opacity var(--_anim); }
.zlc-tl .zlc-tl-node  { transition: r 120ms var(--zl-ease); }
.zlc-tl .zlc-tl-node.hot { r: 7; }
.zlc-tl .zlc-tl-label { fill: var(--zlc-ink-2); font-size: 12px; }
.zlc-tl .zlc-tl-label.strong { fill: var(--zlc-ink); font-weight: var(--zl-weight-medium); }

/* ============================================================================
   EMPTY STATE
   ========================================================================== */
.zlc-empty {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 6px; min-height: 120px; padding: var(--zl-space-5);
  color: var(--zlc-ink-muted); text-align: center; font-size: var(--zl-text-sm);
  border: 1px dashed var(--zl-line-strong); border-radius: var(--zl-radius-md);
}
.zlc-empty svg { opacity: .5; }

/* ============================================================================
   ACCESSIBILITY / MOTION
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  .zlc-svg .zlc-line, .zlc-svg .zlc-bar, .zlc-svg .zlc-dot,
  .zlc-meter-fill, #zlc-tip { transition-duration: .001ms !important; }
}
/* texture backup channel (CVD / print / forced-colors) — opt-in via .zlc-textured */
@media (forced-colors: active) {
  .zlc-svg .zlc-line { stroke: CanvasText; }
  .zlc-svg .zlc-bar, .zlc-svg .zlc-area { forced-color-adjust: none; }
}
