/* =====================================================================
   mtzn-figures  -  system wykresow i diagramow dla mtzn.pl
   Renderowanie w stylu Cerebras (deklaratywny SVG + stan w data-* +
   CSS + cienki runtime JS), ale w palecie olyve (ciemne khaki + krem).

   Kazda figura to samowystarczalna ciemna "karta". Styl niesie sama,
   wiec wyglada tak samo na kazdej stronie (blog post_content i Elementor).
   Zero zaleznosci zewnetrznych. Font: Inter Tight (self-hosted na mtzn.pl).
   ===================================================================== */

.mtzn-fig {
  /* --- paleta marki (olyve) --- */
  --mfig-bg: #0e0f0f;
  --mfig-panel-top: #20211c;
  --mfig-panel-bot: #15160f;
  --mfig-panel-solid: #1c1d15;
  --mfig-well: #141510;

  --mfig-border-soft: #2c2c25;
  --mfig-border: #33332a;
  --mfig-border-strong: #454533;

  --mfig-ink: #f3efd7;          /* naglowki, jasny krem */
  --mfig-ink-2: #ecead2;
  --mfig-cream: #fefce1;        /* najjasniejszy akcent = etap AI */
  --mfig-text: #cfceb0;
  --mfig-text-2: #bbbaa6;

  --mfig-muted: #8d8c7d;
  --mfig-muted-2: #77766a;
  --mfig-muted-3: #6f6e60;

  --mfig-khaki: #aaa997;        /* akcent khaki = wyjscia / reguly */
  --mfig-khaki-2: #a8a691;
  --mfig-line: #6b6a5a;         /* laczniki */
  --mfig-bar-top: #c3c2ab;
  --mfig-bar-bot: #82816d;

  --mfig-radius: 18px;
  --mfig-radius-sm: 13px;
  --mfig-gap: clamp(18px, 3vw, 30px);

  /* tempo animacji (jedno miejsce do strojenia) */
  --mfig-ease: cubic-bezier(.22, .61, .36, 1);
  --mfig-ease-out: cubic-bezier(.16, 1, .3, 1);
  --mfig-t-reveal: .7s;
  --mfig-t-draw: .9s;
  --mfig-step: 90ms;           /* odstep miedzy elementami w kaskadzie */

  display: block;
  position: relative;
  margin: 40px auto;
  max-width: 960px;
  background:
    radial-gradient(120% 140% at 85% -10%, rgba(254, 252, 225, .05), transparent 55%),
    linear-gradient(180deg, #101110, var(--mfig-bg));
  border: 1px solid var(--mfig-border-soft);
  border-radius: var(--mfig-radius);
  padding: clamp(18px, 3.2vw, 34px);
  color: var(--mfig-text);
  font-family: 'Inter Tight', system-ui, -apple-system, Segoe UI, Arial, sans-serif;
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
}

/* modyfikator: figura na pelna szerokosc bloku tekstu (np. szerokie kontenery
   Elementora, gdzie domyslne 960px zostawia luke po prawej stronie) */
.mtzn-fig--full { max-width: none; }

/* opcjonalny naglowek nad figura */
.mtzn-fig__head {
  margin: 0 0 clamp(14px, 2vw, 22px);
}
.mtzn-fig__title {
  margin: 0;
  font-size: clamp(19px, 2.4vw, 26px);
  line-height: 1.22;
  font-weight: 700;
  color: var(--mfig-ink);
  letter-spacing: -.01em;
}
.mtzn-fig__sub {
  margin: 6px 0 0;
  font-size: clamp(14px, 1.6vw, 17px);
  color: var(--mfig-muted);
  font-weight: 400;
}

/* scena SVG - skaluje sie plynnie, zachowuje proporcje viewBox */
.mtzn-fig__stage {
  position: relative;
  width: 100%;
}
.mtzn-fig__stage svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

/* podpis pod figura */
.mtzn-fig__cap {
  margin: clamp(14px, 2vw, 20px) 2px 0;
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--mfig-muted);
}
.mtzn-fig__cap b { color: var(--mfig-text-2); font-weight: 600; }

/* typografia wewnatrz SVG (klasy nadawane elementom <text>) */
.mtzn-fig .t-ink   { fill: var(--mfig-ink); }
.mtzn-fig .t-ink2  { fill: var(--mfig-ink-2); }
.mtzn-fig .t-text  { fill: var(--mfig-text); }
.mtzn-fig .t-text2 { fill: var(--mfig-text-2); }
.mtzn-fig .t-muted { fill: var(--mfig-muted); }
.mtzn-fig .t-cream { fill: var(--mfig-cream); }
.mtzn-fig .t-khaki { fill: var(--mfig-khaki-2); }
.mtzn-fig text { font-family: inherit; }

/* wypelnienia / obrysy uzywane w SVG */
.mtzn-fig .n-fill   { fill: url(#mfigChip); }
.mtzn-fig .n-solid  { fill: var(--mfig-panel-solid); }
.mtzn-fig .n-well   { fill: var(--mfig-well); }
.mtzn-fig .s-soft   { stroke: var(--mfig-border-soft); }
.mtzn-fig .s-base   { stroke: var(--mfig-border); }
.mtzn-fig .s-strong { stroke: var(--mfig-border-strong); }
.mtzn-fig .acc-cream { fill: var(--mfig-cream); }
.mtzn-fig .acc-khaki { fill: var(--mfig-khaki); }
.mtzn-fig .acc-muted { fill: var(--mfig-muted-2); }

/* =====================================================================
   BIBLIOTEKA ANIMACJI
   Wyzwalane przez klase .is-in dokladana na figure przez runtime, gdy
   figura wejdzie w widok. Kolejnosc buduje --i (stagger) na elemencie.
   ===================================================================== */

/* wspolna zasada: przed wejsciem elementy sa "schowane" */
@media (prefers-reduced-motion: no-preference) {

  /* --- reveal: pojawienie sie wezlow (fade + delikatny dojazd w gore) --- */
  .mtzn-fig .mfig-node,
  .mtzn-fig .mfig-reveal {
    opacity: 0;
    transform: translateY(14px);
    transition:
      opacity var(--mfig-t-reveal) var(--mfig-ease-out),
      transform var(--mfig-t-reveal) var(--mfig-ease-out);
    transition-delay: calc(var(--i, 0) * var(--mfig-step));
  }
  .mtzn-fig.is-in .mfig-node,
  .mtzn-fig.is-in .mfig-reveal {
    opacity: 1;
    transform: none;
  }
  /* w SVG transform potrzebuje ukladu wlasnego pudelka elementu */
  .mtzn-fig svg .mfig-node,
  .mtzn-fig svg .mfig-reveal { transform-box: fill-box; transform-origin: center; }

  /* --- draw: rysowanie krawedzi / laczników.
        Kazda sciezka ma atrybut pathLength="1", wiec dlugosc = 1
        niezaleznie od geometrii. --- */
  .mtzn-fig .mfig-edge {
    stroke-dasharray: 1;
    stroke-dashoffset: 1;
    transition: stroke-dashoffset var(--mfig-t-draw) var(--mfig-ease);
    transition-delay: calc(var(--i, 0) * var(--mfig-step) + 120ms);
  }
  .mtzn-fig.is-in .mfig-edge { stroke-dashoffset: 0; }

  /* --- grow: slupki rosnace od podstawy --- */
  .mtzn-fig .mfig-bar {
    transform: scaleY(0);
    transform-box: fill-box;
    transform-origin: bottom;
    transition: transform .85s var(--mfig-ease-out);
    transition-delay: calc(var(--i, 0) * var(--mfig-step));
  }
  .mtzn-fig.is-in .mfig-bar { transform: scaleY(1); }

  /* --- pop: liczby / etykiety, ktore maja "wskoczyc" po slupku --- */
  .mtzn-fig .mfig-pop {
    opacity: 0;
    transform: translateY(6px) scale(.9);
    transform-box: fill-box;
    transform-origin: center;
    transition: opacity .45s ease, transform .45s var(--mfig-ease-out);
    transition-delay: calc(var(--i, 0) * var(--mfig-step) + 380ms);
  }
  .mtzn-fig.is-in .mfig-pop { opacity: 1; transform: none; }

  /* --- fade: spokojne pojawienie (bez ruchu), np. statyczna linia
        przerywana petli zwrotnej. Gra raz i zostaje. --- */
  .mtzn-fig .mfig-fade {
    opacity: 0;
    transition: opacity var(--mfig-t-reveal) var(--mfig-ease-out);
    transition-delay: calc(var(--i, 0) * var(--mfig-step) + 200ms);
  }
  .mtzn-fig.is-in .mfig-fade { opacity: 1; }

  /* --- hover: uniesienie wezla pod kursorem --- */
  .mtzn-fig .mfig-node.is-live { transition: transform .25s var(--mfig-ease), filter .25s ease; cursor: default; }
  @media (hover: hover) and (pointer: fine) {
    .mtzn-fig.is-in .mfig-node.is-live:hover {
      transform: translateY(-3px);
      filter: drop-shadow(0 8px 16px rgba(0,0,0,.5));
    }
  }
}

/* Redukcja ruchu: nic sie nie animuje, wszystko od razu widoczne. */
@media (prefers-reduced-motion: reduce) {
  .mtzn-fig .mfig-node,
  .mtzn-fig .mfig-reveal,
  .mtzn-fig .mfig-fade,
  .mtzn-fig .mfig-pop { opacity: 1 !important; transform: none !important; }
  .mtzn-fig .mfig-edge { stroke-dashoffset: 0 !important; }
  .mtzn-fig .mfig-bar { transform: none !important; }
}

/* =====================================================================
   KOMPONENT INTERAKTYWNY: przelacznik etapow (zakladki)
   Wzorzec jak hero "hybrid" u Cerebras: stan trzyma [data-stage] na
   korzeniu, a CSS pokazuje wlasciwa warstwe. JS tylko przelacza atrybut.
   ===================================================================== */
.mtzn-fig__tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 0 clamp(14px, 2vw, 20px);
}
.mtzn-fig__tab {
  appearance: none;
  border: 1px solid var(--mfig-border);
  background: linear-gradient(180deg, var(--mfig-panel-top), var(--mfig-panel-bot));
  color: var(--mfig-text-2);
  font: 600 14px/1 'Inter Tight', system-ui, sans-serif;
  padding: 10px 15px;
  border-radius: 999px;
  cursor: pointer;
  transition: color .2s, border-color .2s, background .2s, transform .1s;
}
.mtzn-fig__tab:hover { color: var(--mfig-ink); border-color: var(--mfig-border-strong); }
.mtzn-fig__tab:active { transform: translateY(1px); }
.mtzn-fig__tab[aria-pressed="true"] {
  color: #14150e;
  background: var(--mfig-cream);
  border-color: var(--mfig-cream);
}
.mtzn-fig__tab:focus-visible { outline: 2px solid var(--mfig-cream); outline-offset: 3px; }

/* warstwy scen przelaczane przez [data-stage] na korzeniu figury */
.mtzn-fig[data-has-stages] .mfig-layer {
  opacity: 0;
  transition: opacity .4s var(--mfig-ease);
  pointer-events: none;
}
.mtzn-fig[data-stage="0"] .mfig-layer[data-layer="0"],
.mtzn-fig[data-stage="1"] .mfig-layer[data-layer="1"],
.mtzn-fig[data-stage="2"] .mfig-layer[data-layer="2"],
.mtzn-fig[data-stage="3"] .mfig-layer[data-layer="3"] {
  opacity: 1;
  pointer-events: auto;
}

/* czytnik ekranu */
.mtzn-fig .sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* --- responsywnosc: na waskich ekranach mniejszy padding --- */
@media (max-width: 600px) {
  .mtzn-fig { margin: 28px auto; border-radius: 14px; }
}

/* =====================================================================
   POWIEKSZENIE: przycisk "plus" w rogu + modal z zoomem i przesuwaniem
   Rozwiazuje czytelnosc szerokich diagramow (i mermaidow): klik otwiera
   pelnoekranowy podglad, w ktorym mozna zoomowac i przesuwac.
   ===================================================================== */
/* !important bo motyw olyve narzuca styl na kazdy <button> (padding 15px 30px,
   szerokosc), co inaczej rozjezdza przycisk i zeruje szerokosc ikony SVG. */
.mtzn-fig__expand {
  position: absolute;
  top: 14px; right: 14px; z-index: 4;
  width: 40px !important; height: 40px !important;
  min-width: 0 !important; padding: 0 !important; line-height: 1 !important;
  display: inline-flex !important; align-items: center; justify-content: center;
  border: 1px solid var(--mfig-border) !important;
  border-radius: 11px !important;
  background: rgba(16, 17, 14, .66) !important;
  color: var(--mfig-text-2) !important;
  cursor: pointer;
  opacity: .55;
  box-shadow: none !important;
  transition: opacity .2s, color .2s, border-color .2s, background .2s, transform .1s;
  -webkit-backdrop-filter: blur(5px); backdrop-filter: blur(5px);
}
.mtzn-fig:hover .mtzn-fig__expand,
.mtzn-fig:focus-within .mtzn-fig__expand { opacity: 1; }
.mtzn-fig__expand:hover { color: var(--mfig-ink); border-color: var(--mfig-border-strong); background: rgba(28, 29, 21, .92); }
.mtzn-fig__expand:active { transform: translateY(1px); }
.mtzn-fig__expand:focus-visible { opacity: 1; outline: 2px solid var(--mfig-cream); outline-offset: 2px; }
.mtzn-fig__expand svg { width: 20px !important; height: 20px !important; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* nakladka modala (dokladana do <body>)
   UWAGA: zadnego backdrop-filter na tej warstwie. Element z backdrop-filter
   staje sie "backdrop root", przez co Chrome renderuje CALE poddrzewo (czyli
   nasz rysunek) przez dodatkowa teksture - na ekranach HiDPI wychodzi z tego
   rozmyty SVG od pierwszej klatki. Tlo i tak jest prawie kryjace, wiec rozmycie
   nic nie wnosilo. */
.mtzn-fig-modal {
  position: fixed; inset: 0; z-index: 99999;
  display: flex; flex-direction: column;
  background: rgba(6, 7, 6, .97);
  opacity: 0; visibility: hidden;
  transition: opacity .22s ease, visibility 0s linear .22s;
  font-family: 'Inter Tight', system-ui, -apple-system, Segoe UI, Arial, sans-serif;
}
.mtzn-fig-modal.is-open { opacity: 1; visibility: visible; transition: opacity .22s ease; }
.mtzn-fig-modal__bar {
  display: flex; align-items: center; gap: 9px;
  padding: 14px 16px;
  border-bottom: 1px solid rgba(255, 255, 255, .06);
}
.mtzn-fig-modal__title {
  margin-right: auto; padding-left: 4px;
  color: var(--mfig-ink); font-weight: 600; font-size: 16px; line-height: 1.25;
  max-width: 58%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.mtzn-fig-modal__hint {
  color: var(--mfig-muted); font-size: 13px; margin-right: 6px;
}
@media (max-width: 720px) { .mtzn-fig-modal__hint { display: none; } }
.mtzn-fig-modal__btn {
  width: 42px !important; height: 42px !important; flex: none;
  min-width: 0 !important; padding: 0 !important; line-height: 1 !important;
  display: inline-flex !important; align-items: center; justify-content: center;
  border: 1px solid var(--mfig-border) !important; border-radius: 11px !important;
  background: var(--mfig-panel-solid) !important; color: var(--mfig-text-2) !important;
  cursor: pointer; font: 600 20px/1 'Inter Tight', system-ui, sans-serif;
  box-shadow: none !important;
  transition: color .2s, border-color .2s, background .2s, transform .1s;
}
.mtzn-fig-modal__btn:hover { color: var(--mfig-ink) !important; border-color: var(--mfig-border-strong) !important; background: #23241b !important; }
.mtzn-fig-modal__btn:active { transform: translateY(1px); }
.mtzn-fig-modal__btn:focus-visible { outline: 2px solid var(--mfig-cream); outline-offset: 2px; }
.mtzn-fig-modal__btn svg { width: 20px !important; height: 20px !important; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

.mtzn-fig-modal__stage {
  flex: 1; position: relative; overflow: hidden;
  cursor: grab; touch-action: none; user-select: none; -webkit-user-select: none;
}
.mtzn-fig-modal__stage.is-panning { cursor: grabbing; }
.mtzn-fig-modal__content {
  position: absolute; top: 0; left: 0;
  transform-origin: 0 0;
}
/* Promocja do wlasnej warstwy TYLKO na czas przeciagania - wtedy liczy sie
   plynnosc. W spoczynku warstwy nie ma, wiec SVG jest rysowany wektorowo w
   pelnej rozdzielczosci (a nie rozciagany z zapamietanej bitmapy). */
.mtzn-fig-modal__stage.is-panning .mtzn-fig-modal__content { will-change: transform; }
/* w modalu figura bez ramki/tla/marginesu - liczy sie sam rysunek */
.mtzn-fig--in-modal {
  margin: 0 !important; max-width: none !important;
  background: none !important; border: 0 !important; padding: 0 !important;
  border-radius: 0 !important;
}
.mtzn-fig--in-modal .mtzn-fig__head,
.mtzn-fig--in-modal .mtzn-fig__cap,
.mtzn-fig--in-modal .mtzn-fig__tabs,
.mtzn-fig--in-modal .mtzn-fig__expand { display: none !important; }
.mtzn-fig--in-modal .mtzn-fig__stage svg { width: 100%; height: 100%; }

@media (prefers-reduced-motion: reduce) {
  .mtzn-fig-modal { transition: none; }
}
