// ============================================================
// Paper — návrh na rozvod manželstva (bez maloletých detí)
// § 22 a nasl. zákona č. 36/2005 Z. z. o rodine
// ============================================================

// SUDY — zoznam okresných a mestských súdov SR je definovaný v components/sudy.js
// (zdieľaný s PaperDeti.jsx) a vystavený ako window.SUDY.

const removeDiacritics = (str) => str.normalize('NFD').replace(/[̀-ͯ]/g, '').toLowerCase();

// ============================================================
// Gender helpers — prechyľovanie procesných označení (§ 60 a nasl. CSP)
// a rodinnoprávnych označení podľa pohlavia. Manželstvo je v zmysle § 1
// ods. 1 ZoR zväzok muža a ženy, takže pohlavie odporcu odvodzujeme ako
// opak navrhovateľa — len jediný vstup pre celý dokument.
// (Zdieľaný pattern s PaperDeti.jsx; v Paper.jsx bez kid-helperov.)
// ============================================================
const POHLAVIE_FORMS = {
  navrhovatel: {
    muz:  { nom: 'navrhovateľ',   gen: 'navrhovateľa',  dat: 'navrhovateľovi', ak: 'navrhovateľa',  lok: 'navrhovateľovi', instr: 'navrhovateľom' },
    zena: { nom: 'navrhovateľka', gen: 'navrhovateľky', dat: 'navrhovateľke',  ak: 'navrhovateľku', lok: 'navrhovateľke',  instr: 'navrhovateľkou' },
  },
  odporca: {
    muz:  { nom: 'odporca',   gen: 'odporcu',   dat: 'odporcovi', ak: 'odporcu',   lok: 'odporcovi', instr: 'odporcom' },
    zena: { nom: 'odporkyňa', gen: 'odporkyne', dat: 'odporkyni', ak: 'odporkyňu', lok: 'odporkyni', instr: 'odporkyňou' },
  },
};
const oznacenie = (rola, pohlavie, pad = 'nom') => POHLAVIE_FORMS[rola][pohlavie][pad];
const oznacenieCap = (rola, pohlavie, pad = 'nom') => {
  const s = oznacenie(rola, pohlavie, pad);
  return s.charAt(0).toUpperCase() + s.slice(1);
};

const MANZEL_FORMS = {
  muz:  { nom: 'manžel',   gen: 'manžela',  dat: 'manželovi', ak: 'manžela',  lok: 'manželovi', instr: 'manželom' },
  zena: { nom: 'manželka', gen: 'manželky', dat: 'manželke',  ak: 'manželku', lok: 'manželke',  instr: 'manželkou' },
};
const manzelOznacenie = (pohlavie, pad = 'nom') => MANZEL_FORMS[pohlavie][pad];

// Sloveso v minulom čase, 1. osoba sg. — zaklad = mužský tvar (uzavrel,
// uvedomil, oznámil...), pre ženu pridáme '-a'.
const slovesoMinuly = (zaklad, pohlavie) => pohlavie === 'zena' ? zaklad + 'a' : zaklad;

// Privlastňovacie zámeno 3. osoby sg. — "jeho" / "jej".
const privlastn = (pohlavie) => pohlavie === 'muz' ? 'jeho' : 'jej';

// Heuristika pohlavia z priezviska. Posledný token, prípony typické pre
// slovenské feminíny (-ová, -cká, -ská, -ná, -tá, -lá), fallback -á.
const FEM_NAME_RE = /(?:ová|cká|ská|ná|tá|lá|á)$/i;
const detectGenderFromName = (fullName) => {
  if (!fullName) return null;
  const tokens = fullName.trim().split(/\s+/);
  if (!tokens.length || !tokens[tokens.length - 1]) return null;
  const last = tokens[tokens.length - 1].normalize('NFC');
  return FEM_NAME_RE.test(last) ? 'zena' : 'muz';
};

// Perzistencia meta dát Paper.jsx (oddelený kľúč od PaperDeti, aby sa
// pohlavie z dvoch generátorov nemiešalo).
const META_STORAGE_KEY = 'ziadostorozvod.meta.bezdeti.v1';

const SAMPLE_TEXT_1 = 'S odporcom sme sa zoznámili približne pred [počet] rokmi. Pred uzavretím manželstva sme sa spoznávali [počet] rokov a verili sme, že naše hodnoty, ciele a predstavy o spoločnom živote sú zhodné. Manželstvo sme uzavreli z lásky a so spoločnou víziou založiť harmonickú rodinu. V prvých mesiacoch nášho manželstva náš vzťah napĺňal naše očakávania — trávili sme spolu voľný čas, podporovali sa v osobných cieľoch a budovali spoločnú domácnosť.';

const SAMPLE_TEXT_2 = 'Postupne začali v našom manželstve vznikať nezhody, ktorých príčinou bolo predovšetkým [stručný dôvod — odlišné životné priority, problémy s rodinou jedného z manželov, nedostatok komunikácie, finančné nezhody, alebo iné]. Spočiatku sme sa snažili problémy riešiť rozhovormi a vzájomnými ústupkami. Postupom času sa však napätie stupňovalo, hádky boli čoraz častejšie a ich riešenie čoraz ťažšie. Definitívny zlom v našom vzťahu nastal približne pred [časový údaj], keď [konkrétna udalosť — napr. zistenie nevery, vážny konflikt, vzájomné odcudzenie, rozhodnutie odporcu o odsťahovaní]. Po tejto udalosti som si uvedomil/-a, že v manželstve nedokážem ďalej zotrvať.';

const SAMPLE_TEXT_3 = 'Keď som odporcovi oznámil/-a svoje rozhodnutie ukončiť manželstvo, jeho/jej reakcia bola [zmierená / odmietavá / bez záujmu]. Naše manželské spolužitie už dlhodobo neplní svoju funkciu. Nehospodárime spoločne — nemáme spoločný účet, každý si nakupuje potraviny samostatne a stravujeme sa oddelene. Nemáme spoločné záľuby, netrávime spolu voľný čas a postupne sa rozišli aj naši spoloční známi. Intímny styk sme mali naposledy približne pred [časový údaj] a od tej doby sme spolu nemali žiadny intímny kontakt. Hoci formálne žijeme v spoločnej domácnosti, fakticky vedieme úplne oddelené životy.';

const SAMPLE_TEXT_4 = 'Pokúsili sme sa o obnovu nášho manželstva niekoľkými spôsobmi — [napr. absolvovali sme spoločne partnerskú poradňu, mediáciu u odborníka, viedli sme otvorené rozhovory o našich problémoch, dohodli sme si spoločnú dovolenku v snahe oživiť vzťah]. Napriek úprimnej snahe oboch strán sa nám však nepodarilo obnoviť dôveru a vzájomnú blízkosť. Obnova manželstva už podľa môjho presvedčenia nie je možná, pretože medzi nami chýba citová väzba, dôvera aj základná vôľa pokračovať v spoločnom živote. Manželstvo je z mojej strany definitívne ukončené a v rozvode vidím jediné riešenie, aby sme obaja mohli začať novú etapu života.';

// Controlled contentEditable — to isté pole žije na dvoch miestach (bod 1.1
// a petit) a synchronizuje sa cez zdieľaný state.
//
// Cursor preservation: písanie do tohto inputu nesmie spôsobiť prepis textContent
// (cursor by skočil na začiatok). isTypingRef príznak rozlíši, či zmena value
// prišla z tohto inputu (skip DOM write) alebo z druhej inštancie (write).
const SyncedEd = ({ value, onChange, placeholder, lg, num }) => {
  const ref = React.useRef(null);
  const isTypingRef = React.useRef(false);

  React.useEffect(() => {
    if (ref.current && !isTypingRef.current && ref.current.textContent !== value) {
      ref.current.textContent = value;
    }
    isTypingRef.current = false;
  }, [value]);

  const cls = [
    "ed",
    lg && "ed-lg",
    num && "ed-num",
    !value && "ed-empty",
  ].filter(Boolean).join(" ");

  return (
    <span
      ref={ref}
      className={cls}
      contentEditable
      suppressContentEditableWarning
      onInput={(e) => {
        isTypingRef.current = true;
        onChange(e.currentTarget.textContent);
      }}
      data-placeholder={placeholder}
      role="textbox"
      aria-label={placeholder}
    />
  );
};

// Rozbaliteľný panel so vzorovým textom pre kategórie 2.1-2.4 v Čl. II.
// onUse vloží text do Ed block poľa a panel zatvorí; onClose len zatvorí.
const SamplePanel = ({ sampleText, onUse, onClose }) => (
  <div className="no-copy no-print" style={{
    background: 'var(--ivory-2)',
    border: '1px solid var(--rule)',
    borderRadius: 'var(--r-sm)',
    padding: '12px 16px',
    margin: '8px 0',
    fontSize: '0.88em',
    lineHeight: 1.6,
    color: 'var(--ink-2)',
    position: 'relative'
  }}>
    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 8 }}>
      <strong style={{ fontSize: '0.85em', textTransform: 'uppercase', letterSpacing: '0.06em', color: 'var(--ink-3)' }}>Vzorový text — len ako inšpirácia</strong>
      <button
        onClick={onClose}
        style={{ border: 'none', background: 'transparent', cursor: 'pointer', fontSize: '1.2em', color: 'var(--ink-3)', padding: 0, lineHeight: 1 }}
        aria-label="Skryť vzor"
      >×</button>
    </div>
    <div style={{ fontStyle: 'italic', marginBottom: 12 }}>
      {sampleText}
    </div>
    {/* Mobile-safe handler: onPointerDown vyvolá akciu okamžite (na touch
        bez 300ms tap delay), preventDefault + stopPropagation zabránia, aby
        sa click bublinka dostala do parent kontajnera ešte predtým, ako sa
        textContent prenesie do Ed bloku. onClick zachovaný pre keyboard
        accessibility (Tab + Enter). Akcia je idempotent. */}
    <button
      type="button"
      onPointerDown={(e) => { e.preventDefault(); e.stopPropagation(); onUse && onUse(e); }}
      onClick={(e) => { e.preventDefault(); e.stopPropagation(); onUse && onUse(e); }}
      style={{
        fontSize: '0.85em',
        padding: '6px 14px',
        border: '1px solid var(--oxblood)',
        borderRadius: 'var(--r-sm)',
        background: 'var(--paper)',
        color: 'var(--oxblood)',
        cursor: 'pointer',
        fontWeight: 500
      }}
    >Použiť tento text →</button>
  </div>
);

// Modul-level komponent — stabilná funkčná referencia, vďaka čomu si <input>
// drží focus medzi keystrokes. State žije v Paper a tečie cez props, takže
// hlavička aj bod 1.3 zdieľajú ten istý vybraný súd.
const SudAutocomplete = ({ sudQuery, setSudQuery, sudVybrany, setSudVybrany, sudDropdown, setSudDropdown, sudFiltered }) => (
  <span style={{ position: 'relative', display: 'inline-block', minWidth: 280 }}>
    <input
      type="text"
      value={sudVybrany ? sudVybrany.nazov : sudQuery}
      onChange={(e) => { setSudQuery(e.target.value); setSudVybrany(null); setSudDropdown(true); }}
      onFocus={() => setSudDropdown(true)}
      onBlur={() => setTimeout(() => setSudDropdown(false), 150)}
      placeholder="začnite písať názov súdu..."
      style={{
        padding: '3px 8px',
        border: '1px solid var(--rule)',
        borderRadius: 'var(--r-sm)',
        fontFamily: 'var(--serif)',
        fontSize: '0.95em',
        background: 'var(--ed-bg, #fefce8)',
        width: '100%',
      }}
    />
    {sudDropdown && sudFiltered.length > 0 && (
      <ul style={{
        position: 'absolute',
        top: '100%',
        left: 0,
        right: 0,
        background: 'var(--paper, #ffffff)',
        backdropFilter: 'none',
        border: '1px solid var(--rule)',
        borderRadius: 'var(--r-sm)',
        boxShadow: '0 4px 16px rgba(0,0,0,0.10)',
        listStyle: 'none',
        margin: 0,
        padding: '4px 0',
        zIndex: 1000,
        maxHeight: 220,
        overflowY: 'auto',
      }}>
        {sudFiltered.map(s => (
          <li
            key={s.nazov}
            onMouseDown={() => { setSudVybrany(s); setSudQuery(''); setSudDropdown(false); }}
            style={{
              padding: '2px 12px',
              cursor: 'pointer',
              fontSize: '0.9em',
              fontFamily: 'var(--serif)',
              background: 'var(--paper, #ffffff)',
            }}
            onMouseEnter={e => e.currentTarget.style.background = 'var(--ivory-2)'}
            onMouseLeave={e => e.currentTarget.style.background = 'var(--paper, #ffffff)'}
          >
            {s.nazov}
          </li>
        ))}
      </ul>
    )}
  </span>
);

// ============================================================
// TipBtn — floating "TIP" pin v gutteri papiera. Definovaný NA module-leveli
// (mimo Paper), aby React zachoval identitu komponentu cez Paper re-rendery.
// Inak (keď bol TipBtn definovaný vnútri Paper) každý Paper render mu pridelil
// novú function reference → React unmount + mount → useLayoutEffect zbehol
// znova a krátky frame s initial topPx=0 spôsoboval vizuálny "preskok" tipov
// pri scrolle (scroll-spy IntersectionObserver triggeruje setActiveArticle/
// setActiveTipKey, čo Paper re-renderuje).
//
// Top sa počíta RAZ pri reálnom mount-e + na zmenu výšky .paper-a cez
// ResizeObserver (otvorenie wizardu, vkladanie vzoru, edit textu, viewport
// resize). Počas scrollu sa NEPREPOČÍTAVA → tipy sú vizuálne stabilné.
// activeTipKey + onTipClick sú doručené cez TipContext, takže prop drilling
// do 13 call-sites netreba.
// ============================================================
const TipContext = React.createContext({ activeTipKey: null, onTipClick: null });

const TipBtn = ({ pointKey }) => {
  const { activeTipKey, onTipClick } = React.useContext(TipContext);
  const buttonRef = React.useRef(null);
  const [topPx, setTopPx] = React.useState(0);

  React.useLayoutEffect(() => {
    const button = buttonRef.current;
    if (!button) return;
    const anchor = button.parentNode;
    const paper = button.closest('.paper');
    if (!paper || !anchor) return;

    const update = () => {
      // offsetTop chain anchor → .paper. Po našich CSS zmenách je anchor.offsetParent
      // priamo .paper, walk je defenzívny pre prípad neskoršieho pozicovaného wrapperu.
      let top = anchor.offsetTop;
      let p = anchor.offsetParent;
      while (p && p !== paper) {
        top += p.offsetTop;
        p = p.offsetParent;
      }
      setTopPx(top + 2);
    };
    update();

    const ro = new ResizeObserver(update);
    ro.observe(paper);
    window.addEventListener('resize', update);
    return () => { ro.disconnect(); window.removeEventListener('resize', update); };
  }, []);

  return (
    <button
      ref={buttonRef}
      type="button"
      className={`tip-pin no-print ${activeTipKey === pointKey ? 'active' : ''}`}
      data-tip-key={pointKey}
      onClick={(e) => { e.stopPropagation(); onTipClick && onTipClick(pointKey); }}
      aria-label={`Zobraziť tip k bodu ${pointKey}`}
      title={`Tip k bodu ${pointKey}`}
      contentEditable={false}
      style={{ top: `${topPx}px` }}
    >
      TIP
    </button>
  );
};

const Paper = ({ doctype, navrhovatel, setNavrhovatel, odporca, setOdporca, setActiveArticle, setActiveTipKey, onTipClick, activeTipKey }) => {
  const [menoNavrhovatela, setMenoNavrhovatela] = React.useState('');
  const [rodnePriezvisko, setRodnePriezvisko] = React.useState('');

  // Pohlavie navrhovateľa (jediný vstup; pohlavie odporcu = opak, § 1 ZoR).
  // Hydrácia + perzistencia v META_STORAGE_KEY; userTouchedGender uzamkne
  // autodetekciu z priezviska potom, čo používateľ explicitne prepol radio.
  const [navrhovatelPohlavie, setNavrhovatelPohlavieRaw] = React.useState(() => {
    try {
      const raw = localStorage.getItem(META_STORAGE_KEY);
      if (raw) {
        const m = JSON.parse(raw);
        if (m && (m.navrhovatelPohlavie === 'muz' || m.navrhovatelPohlavie === 'zena')) {
          return m.navrhovatelPohlavie;
        }
      }
    } catch (e) {}
    return 'muz';
  });
  const [userTouchedGender, setUserTouchedGender] = React.useState(() => {
    try {
      const raw = localStorage.getItem(META_STORAGE_KEY);
      if (raw) {
        const m = JSON.parse(raw);
        return !!(m && m.userTouchedGender);
      }
    } catch (e) {}
    return false;
  });
  React.useEffect(() => {
    try {
      localStorage.setItem(META_STORAGE_KEY, JSON.stringify({ navrhovatelPohlavie, userTouchedGender }));
    } catch (e) {}
  }, [navrhovatelPohlavie, userTouchedGender]);

  // User-facing setter (UI radio) — uzamkne autodetekciu.
  const setNavrhovatelPohlavie = (g) => {
    setNavrhovatelPohlavieRaw(g);
    setUserTouchedGender(true);
  };

  // Autodetekcia z priezviska — beží iba kým user nestlačí radio. Po explicit
  // prepnutí ostáva flag userTouchedGender = true, autodetekcia ďalej nebeží.
  React.useEffect(() => {
    if (userTouchedGender) return;
    const detected = detectGenderFromName(menoNavrhovatela);
    if (detected && detected !== navrhovatelPohlavie) {
      setNavrhovatelPohlavieRaw(detected);
    }
  }, [menoNavrhovatela, userTouchedGender]);

  // Pohlavie odporcu = opak navrhovateľa. Manželstvo = zväzok muža a ženy
  // (§ 1 ods. 1 ZoR), takže pri zmene pohlavia navrhovateľa sa odporca
  // automaticky prepne. Žiadny samostatný vstup pre odporcu.
  const odporcaPohlavie = navrhovatelPohlavie === 'muz' ? 'zena' : 'muz';

  const [dalsieDokazy, setDalsieDokazy] = React.useState('');
  const [q1, setQ1] = React.useState(null); // null | 'ano' | 'nie'
  const [q2, setQ2] = React.useState(null); // null | 'ano' | 'nie'
  const [q3, setQ3] = React.useState(null); // null | 'ano' | 'nie'
  const [sudQuery, setSudQuery] = React.useState('');
  const [sudVybrany, setSudVybrany] = React.useState(null);
  const [sudDropdown, setSudDropdown] = React.useState(false);
  // Údaje o sobáši — zdieľané medzi bodom 1.1 a petitom v Čl. III.
  const [datumSobasa, setDatumSobasa] = React.useState('');
  const [miestoSobasa, setMiestoSobasa] = React.useState('');
  const [maticnyUrad, setMaticnyUrad] = React.useState('');
  const [zvazok, setZvazok] = React.useState('');
  const [rocnik, setRocnik] = React.useState('');
  const [strana, setStrana] = React.useState('');
  const [poradoveCislo, setPoradoveCislo] = React.useState('');
  const kategoria1Ref = React.useRef(null);
  const kategoria2Ref = React.useRef(null);
  const kategoria3Ref = React.useRef(null);
  const kategoria4Ref = React.useRef(null);
  const [showSample1, setShowSample1] = React.useState(false);
  const [showSample2, setShowSample2] = React.useState(false);
  const [showSample3, setShowSample3] = React.useState(false);
  const [showSample4, setShowSample4] = React.useState(false);

  const fillSampleText = (refName, text) => {
    const refMap = { kategoria1Ref, kategoria2Ref, kategoria3Ref, kategoria4Ref };
    const ref = refMap[refName];
    if (ref?.current) {
      ref.current.textContent = text;
      ref.current.dispatchEvent(new Event('input', { bubbles: true }));
    }
  };
  const sudFiltered = sudQuery.length > 0
    ? window.SUDY.filter(s => removeDiacritics(s.nazov).includes(removeDiacritics(sudQuery)))
    : [];

  // Pre prehľadnosť — props pre <SudAutocomplete {...sudProps} /> obalíme do jedného objektu.
  const sudProps = { sudQuery, setSudQuery, sudVybrany, setSudVybrany, sudDropdown, setSudDropdown, sudFiltered };

  // TipBtn je definovaný na module-leveli (viď vyššie). Tu len obalíme paper
  // do TipContext.Provider-a, aby všetky <TipBtn> dostali aktuálny activeTipKey
  // + onTipClick. Memoize-ujeme value, aby sa Provider re-rendery zbytočne
  // netriggerovali pri identických hodnotách.
  const tipCtx = React.useMemo(() => ({ activeTipKey, onTipClick }), [activeTipKey, onTipClick]);

  // Scroll-spy: activeArticle sleduje článok v čítacej zóne viewport-u;
  // activeTipKey sleduje top-most TipBtn v užšej zóne (20–40% viewport-u).
  // Pozorujeme PRIAMO tlačidlá s [data-tip-key] (všetky tipy, nielen tie
  // v p.has-tip) — po refaktoringu má každé tlačidlo position: absolute
  // s top podľa offsetTop rodiča, takže jeho pozícia v viewport-e verne
  // odráža miesto kde tip patrí v dokumente.
  // Deps obsahujú q1/q2/q3 — keď user prepne wizard, conditional q3 tip
  // mountne a treba ho re-observovať.
  React.useEffect(() => {
    const articles = document.querySelectorAll('.paper .article[id]');
    const obs = new IntersectionObserver((entries) => {
      entries.forEach(e => { if (e.isIntersecting) setActiveArticle(e.target.id); });
    }, { rootMargin: '-35% 0px -55% 0px' });
    articles.forEach(a => obs.observe(a));

    const tipButtons = document.querySelectorAll('.paper [data-tip-key]');
    let currentKey = null;
    const pObs = new IntersectionObserver((entries) => {
      const hits = entries
        .filter(e => e.isIntersecting)
        .map(e => ({ key: e.target.dataset.tipKey, top: e.boundingClientRect.top }))
        .sort((a, b) => a.top - b.top);
      if (hits.length && hits[0].key !== currentKey) {
        currentKey = hits[0].key;
        setActiveTipKey && setActiveTipKey(currentKey);
      }
    }, { rootMargin: '-20% 0px -60% 0px' });
    tipButtons.forEach(btn => pObs.observe(btn));

    return () => { obs.disconnect(); pObs.disconnect(); };
  }, [doctype, q1, q2, q3]);

  return (
    <TipContext.Provider value={tipCtx}>
    <div className="paper-stage">
      <article className="paper" aria-label="Návrh na rozvod — editovateľný dokument">

        {/* Hlavička dokumentu — ľavý stĺpec prázdny (miesto pre podpis advokáta), pravý: adresát súdu + dátum */}
        <header className="paper-header" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 48 }}>
          <div className="paper-header-left"></div>
          <div className="paper-header-right">
            <div style={{ borderBottom: '1px solid var(--ink)', width: '100%', marginBottom: 16 }}></div>
            <div className="no-copy no-print" style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
              <SudAutocomplete {...sudProps} />
              <TipBtn pointKey="header-sud" />
            </div>
            {sudVybrany && (
              <>
                <div className="no-print" style={{ fontSize: '0.95em', fontStyle: 'italic', paddingLeft: 9, marginTop: 2 }}>{sudVybrany.ulica}</div>
                <div className="no-print" style={{ fontSize: '0.95em', fontStyle: 'italic', paddingLeft: 9 }}>{sudVybrany.mesto}</div>
              </>
            )}
            <div className="ed-select-print-block">{sudVybrany ? sudVybrany.nazov : ''}</div>
            <div className="ed-select-print-block">{sudVybrany ? sudVybrany.ulica : ''}</div>
            <div className="ed-select-print-block">{sudVybrany ? sudVybrany.mesto : ''}</div>
            <div style={{ borderBottom: '1px solid var(--ink)', width: '100%', margin: '16px 0 8px' }}></div>
            <p style={{ margin: 0 }}>
              V{' '}
              <Ed defaultValue="" placeholder="miesto" />
              , dňa{' '}
              <Ed defaultValue="" placeholder="DD. MM. RRRR" />
            </p>
          </div>
        </header>

        {/* Účastníci konania */}
        <div className="parties-table" style={{ display: 'flex', flexDirection: 'column', gap: 20, padding: '24px 0', borderTop: '1px solid var(--rule)', borderBottom: '1px solid var(--rule)', margin: '64px 0 32px' }}>
          {/* Voľba pohlavia navrhovateľa — UI control mimo PDF/Word.
              Pohlavie odporcu sa odvodí automaticky (§ 1 ZoR). */}
          <div className="no-copy no-print" style={{ display: 'flex', gap: 16, alignItems: 'center', fontSize: '0.85em', color: 'var(--ink-3)' }}>
            <span style={{ fontFamily: 'var(--mono)', letterSpacing: '0.04em', textTransform: 'uppercase' }}>Navrhovateľ je:</span>
            <label style={{ display: 'inline-flex', alignItems: 'center', gap: 4, cursor: 'pointer' }}>
              <input
                type="radio"
                name="navrhovatel-pohlavie"
                value="muz"
                checked={navrhovatelPohlavie === 'muz'}
                onChange={() => setNavrhovatelPohlavie('muz')}
              />
              <span>muž</span>
            </label>
            <label style={{ display: 'inline-flex', alignItems: 'center', gap: 4, cursor: 'pointer' }}>
              <input
                type="radio"
                name="navrhovatel-pohlavie"
                value="zena"
                checked={navrhovatelPohlavie === 'zena'}
                onChange={() => setNavrhovatelPohlavie('zena')}
              />
              <span>žena</span>
            </label>
          </div>

          <div style={{ marginBottom: 20 }}>
            <div style={{ fontWeight: 'bold', marginBottom: 8 }}>{oznacenieCap('navrhovatel', navrhovatelPohlavie)}:</div>
            <div className="party-grid">
              <span>Meno a priezvisko:</span>
              <div style={{ display: 'flex', gap: 8, alignItems: 'baseline' }}>
                <SyncedEd value={menoNavrhovatela} onChange={setMenoNavrhovatela} placeholder="meno a priezvisko" />
                <span style={{ whiteSpace: 'nowrap' }}>rod.:</span>
                <SyncedEd value={rodnePriezvisko} onChange={setRodnePriezvisko} placeholder="rodné priezvisko" />
              </div>
              <span>Dátum narodenia:</span> <Ed defaultValue="" placeholder="DD. MM. RRRR" />
              <span>Trvalý pobyt:</span> <Ed defaultValue="" placeholder="ulica, PSČ mesto" />
              <span>Občianstvo:</span> <Ed defaultValue="" placeholder="uveďte občianstvo" />
            </div>
            <div style={{ fontStyle: 'italic', marginTop: 6 }}>(ďalej len „{oznacenie('navrhovatel', navrhovatelPohlavie)}")</div>
          </div>

          <div>
            <div style={{ fontWeight: 'bold', marginBottom: 8 }}>{oznacenieCap('odporca', odporcaPohlavie)}:</div>
            <div className="party-grid">
              <span>Meno a priezvisko:</span>
              <div style={{ display: 'flex', gap: 8, alignItems: 'baseline' }}>
                <Ed defaultValue="" placeholder="meno a priezvisko" />
                <span style={{ whiteSpace: 'nowrap' }}>rod.:</span>
                <Ed defaultValue="" placeholder="rodné priezvisko" />
              </div>
              <span>Dátum narodenia:</span> <Ed defaultValue="" placeholder="DD. MM. RRRR" />
              <span>Trvalý pobyt:</span> <Ed defaultValue="" placeholder="ulica, PSČ mesto" />
              <span>Občianstvo:</span> <Ed defaultValue="" placeholder="uveďte občianstvo" />
            </div>
            <div style={{ fontStyle: 'italic', marginTop: 6 }}>(ďalej len „{oznacenie('odporca', odporcaPohlavie)}")</div>
          </div>
        </div>

        {/* Názov dokumentu */}
        <h1 className="doc-title" style={{ marginTop: 48 }}>Návrh na rozvod manželstva</h1>
        <div className="doc-sub">podľa § 22 a nasl. zákona č. 36/2005 Z. z. o rodine</div>
        <p className="small" style={{ textAlign: 'left' }}>
          Súdny poplatok{' '}
          <Ed
            select
            options={[
              { v: 'vyzva', label: 'bude uhradený na výzvu súdu.' },
              { v: 'kolok', label: 'je uhradený spolu s návrhom formou kolku.' },
            ]}
          />
          <TipBtn pointKey="header-poplatok" />
        </p>

        {/* Čl. I — Manželstvo účastníkov */}
        <section className="article page-break-before" id="art-1">
          <div className="article-head">
            <div className="article-num">Článok I</div>
            <span className="article-title">Manželstvo účastníkov</span>
          </div>

          <p className="has-tip">
            <TipBtn pointKey="1.1" />
            <strong>1.1</strong>&nbsp;&nbsp;S {oznacenie('odporca', odporcaPohlavie, 'instr')} sme uzavreli manželstvo dňa{' '}
            <SyncedEd value={datumSobasa} onChange={setDatumSobasa} placeholder="DD. MM. RRRR" />
            {' '}v{' '}
            <SyncedEd value={miestoSobasa} onChange={setMiestoSobasa} placeholder="mesto" />
            . Zapísané je v knihe manželstiev matričného úradu{' '}
            <SyncedEd value={maticnyUrad} onChange={setMaticnyUrad} placeholder="názov matričného úradu" lg />
            , zväzok{' '}
            <SyncedEd value={zvazok} onChange={setZvazok} placeholder="č." num />
            , ročník{' '}
            <SyncedEd value={rocnik} onChange={setRocnik} placeholder="RRRR" num />
            , strana{' '}
            <SyncedEd value={strana} onChange={setStrana} placeholder="č." num />
            {' '}pod poradovým číslom{' '}
            <SyncedEd value={poradoveCislo} onChange={setPoradoveCislo} placeholder="č." num />
            . Z nášho manželstva s {oznacenie('odporca', odporcaPohlavie, 'instr')} nepochádzajú žiadne maloleté deti.
          </p>

          <p style={{ margin: '16px 0 8px' }}>
            <strong>1.2 Miestna príslušnosť súdu na rozhodnutie</strong>
          </p>

          <div className="no-copy no-print" style={{ margin: '12px 0', padding: '16px', background: 'var(--ivory-2)', borderRadius: 'var(--r-sm)', border: '1px solid var(--rule)' }}>

            <p style={{ fontStyle: 'italic', color: 'var(--ink-2)', marginBottom: 16, fontSize: '0.9em' }}>
              Teraz spolu určíme príslušnosť súdu. Prosím odpovedzte na otázky:
            </p>

            {/* Otázka 1 */}
            <div style={{ marginBottom: 12 }}>
              <TipBtn pointKey="1.2-q1" />
              <div style={{ fontWeight: 500, marginBottom: 8 }}>Mali ste s {oznacenie('odporca', odporcaPohlavie, 'instr')} spoločné bydlisko?</div>
              <div style={{ display: 'flex', gap: 8 }}>
                <button className={q1 === 'ano' ? 'btn btn-sm btn-oxblood' : 'btn btn-sm btn-ghost'} onClick={() => { setQ1('ano'); setQ2(null); setQ3(null); }}>Áno</button>
                <button className={q1 === 'nie' ? 'btn btn-sm btn-oxblood' : 'btn btn-sm btn-ghost'} onClick={() => { setQ1('nie'); setQ2(null); setQ3(null); }}>Nie</button>
              </div>
            </div>

            {/* Otázka 2 — ak q1 === 'ano' */}
            {q1 === 'ano' && (
              <div style={{ marginBottom: 12 }}>
                <div style={{ fontWeight: 500, marginBottom: 8 }}>Býva niektorý z vás na tej adrese dodnes?</div>
                <div style={{ display: 'flex', gap: 8 }}>
                  <button className={q2 === 'ano' ? 'btn btn-sm btn-oxblood' : 'btn btn-sm btn-ghost'} onClick={() => setQ2('ano')}>Áno</button>
                  <button className={q2 === 'nie' ? 'btn btn-sm btn-oxblood' : 'btn btn-sm btn-ghost'} onClick={() => setQ2('nie')}>Nie</button>
                </div>
              </div>
            )}

            {/* Otázka 3 — ak q1 === 'nie' alebo q2 === 'nie' */}
            {(q1 === 'nie' || q2 === 'nie') && (
              <div style={{ marginBottom: 12 }}>
                <TipBtn pointKey="1.2-q3" />
                <div style={{ fontWeight: 500, marginBottom: 8 }}>Má {oznacenie('odporca', odporcaPohlavie, 'nom')} trvalý pobyt na Slovensku?</div>
                <div style={{ display: 'flex', gap: 8 }}>
                  <button className={q3 === 'ano' ? 'btn btn-sm btn-oxblood' : 'btn btn-sm btn-ghost'} onClick={() => setQ3('ano')}>Áno</button>
                  <button className={q3 === 'nie' ? 'btn btn-sm btn-oxblood' : 'btn btn-sm btn-ghost'} onClick={() => setQ3('nie')}>Nie</button>
                </div>
              </div>
            )}

          </div>

          {/* Výsledok — text do návrhu + adresové pole + hint o príslušnosti.
              Mimo wizardu, aby ostal viditeľný v PDF/Word exporte. */}
          {/* Vetva A — q1=áno, q2=áno: spoločné bydlisko, dodnes tam niekto býva */}
          {q1 === 'ano' && q2 === 'ano' && (
            <div style={{ marginTop: 8, padding: '12px', background: 'var(--paper)', borderRadius: 'var(--r-sm)' }}>
              <p style={{ margin: '0 0 8px' }}>
                Posledným spoločným bydliskom účastníkov je <Ed placeholder="adresa posledného spoločného bydliska" /> a v obvode tohto súdu má bydlisko aspoň jeden z účastníkov.
              </p>
              <div className="no-copy no-print" style={{ fontSize: '0.82em', color: 'var(--ink-3)' }}>→ Príslušný súd: súd v obvode tejto adresy (§ 92 zák. č. 161/2015 Z. z. – CMP)</div>
            </div>
          )}

          {/* Vetva B1 — q1=áno, q2=nie, q3=áno: bývali spolu, už tam nikto, odporca má TP na SR */}
          {q1 === 'ano' && q2 === 'nie' && q3 === 'ano' && (
            <div style={{ marginTop: 8, padding: '12px', background: 'var(--paper)', borderRadius: 'var(--r-sm)' }}>
              <p style={{ margin: '0 0 8px' }}>
                Posledným spoločným bydliskom účastníkov bolo <Ed placeholder="adresa posledného spoločného bydliska" />. Účastníci nemajú v obvode toho istého súdu bydlisko, preto sa miestna príslušnosť súdu určuje podľa trvalého pobytu {oznacenie('odporca', odporcaPohlavie, 'gen')}, ktorým je <Ed placeholder={'trvalý pobyt ' + oznacenie('odporca', odporcaPohlavie, 'gen')} />.
              </p>
              <div className="no-copy no-print" style={{ fontSize: '0.82em', color: 'var(--ink-3)' }}>→ Príslušný súd: všeobecný súd {oznacenie('odporca', odporcaPohlavie, 'gen')} (§ 92 CMP)</div>
            </div>
          )}

          {/* Vetva B2 — q1=áno, q2=nie, q3=nie: bývali spolu, už tam nikto, odporca nemá TP na SR */}
          {q1 === 'ano' && q2 === 'nie' && q3 === 'nie' && (
            <div style={{ marginTop: 8, padding: '12px', background: 'var(--paper)', borderRadius: 'var(--r-sm)' }}>
              <p style={{ margin: '0 0 8px' }}>
                Posledným spoločným bydliskom účastníkov bolo <Ed placeholder="adresa posledného spoločného bydliska" />. {oznacenieCap('odporca', odporcaPohlavie, 'nom')} nemá trvalý pobyt na území Slovenskej republiky, preto sa miestna príslušnosť súdu určuje podľa trvalého pobytu {oznacenie('navrhovatel', navrhovatelPohlavie, 'gen')}, ktorým je <Ed placeholder={'trvalý pobyt ' + oznacenie('navrhovatel', navrhovatelPohlavie, 'gen')} />.
              </p>
              <div className="no-copy no-print" style={{ fontSize: '0.82em', color: 'var(--ink-3)' }}>→ Príslušný súd: všeobecný súd {oznacenie('navrhovatel', navrhovatelPohlavie, 'gen')} (§ 92 CMP)</div>
            </div>
          )}

          {/* Vetva C — q1=nie, q3=áno: nemali spoločné bydlisko, odporca má TP na SR */}
          {q1 === 'nie' && q3 === 'ano' && (
            <div style={{ marginTop: 8, padding: '12px', background: 'var(--paper)', borderRadius: 'var(--r-sm)' }}>
              <p style={{ margin: '0 0 8px' }}>
                Účastníci nemali spoločné bydlisko v obvode toho istého súdu, preto sa miestna príslušnosť súdu určuje podľa trvalého pobytu {oznacenie('odporca', odporcaPohlavie, 'gen')}, ktorým je <Ed placeholder={'trvalý pobyt ' + oznacenie('odporca', odporcaPohlavie, 'gen')} />.
              </p>
              <div className="no-copy no-print" style={{ fontSize: '0.82em', color: 'var(--ink-3)' }}>→ Príslušný súd: všeobecný súd {oznacenie('odporca', odporcaPohlavie, 'gen')} (§ 92 CMP)</div>
            </div>
          )}

          {/* Vetva D — q1=nie, q3=nie: nemali spoločné bydlisko, odporca nemá TP na SR */}
          {q1 === 'nie' && q3 === 'nie' && (
            <div style={{ marginTop: 8, padding: '12px', background: 'var(--paper)', borderRadius: 'var(--r-sm)' }}>
              <p style={{ margin: '0 0 8px' }}>
                Účastníci nemali spoločné bydlisko v obvode toho istého súdu. {oznacenieCap('odporca', odporcaPohlavie, 'nom')} nemá trvalý pobyt na území Slovenskej republiky, preto sa miestna príslušnosť súdu určuje podľa trvalého pobytu {oznacenie('navrhovatel', navrhovatelPohlavie, 'gen')}, ktorým je <Ed placeholder={'trvalý pobyt ' + oznacenie('navrhovatel', navrhovatelPohlavie, 'gen')} />.
              </p>
              <div className="no-copy no-print" style={{ fontSize: '0.82em', color: 'var(--ink-3)' }}>→ Príslušný súd: všeobecný súd {oznacenie('navrhovatel', navrhovatelPohlavie, 'gen')} (§ 92 CMP)</div>
            </div>
          )}

          <p className="autocomplete-host" style={{ margin: '8px 0 6px' }}>
            Miestne príslušným súdom je{'  '}
            <span className="no-copy no-print">
              <SudAutocomplete {...sudProps} />
            </span>
            <span className="ed-select-print">{sudVybrany ? sudVybrany.nazov : ''}</span>
          </p>

          <p className="evidence"><em>Dôkaz:</em> sobášny list</p>
        </section>

        {/* Čl. II — Rozvrat manželstva */}
        <section className="article" id="art-2">
          <div className="article-head">
            <div className="article-num">Článok II</div>
            <span className="article-title">Rozvrat manželstva</span>
          </div>

          <p className="has-tip">
            <TipBtn pointKey="art-2" />
            Vzťahy medzi účastníkmi sú vážne narušené a trvalo rozvrátené, pričom nie je nádej na obnovenie manželského spolužitia z nasledovných dôvodov:
          </p>

          <div style={{ marginBottom: 24 }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 6 }}>
              <strong>2.1 História a začiatok manželstva</strong>
              <TipBtn pointKey="2.1" />
              <button
                className="no-copy no-print"
                onClick={() => setShowSample1(!showSample1)}
                style={{ fontSize: '0.78em', padding: '3px 10px', border: '1px solid var(--rule)', borderRadius: 'var(--r-sm)', background: 'var(--paper)', cursor: 'pointer', color: 'var(--ink-2)' }}
              >{showSample1 ? 'Skryť vzor' : 'Zobraziť vzor textu'}</button>
            </div>
            <p className="no-copy no-print" style={{ fontStyle: 'italic', fontSize: '0.85em', color: 'var(--ink-3)', margin: '0 0 8px' }}>
              Ako dlho ste sa poznali pred manželstvom? Prečo ste sa zosobášili? Aké bolo manželstvo na začiatku?
            </p>
            {showSample1 && (
              <SamplePanel
                sampleText={SAMPLE_TEXT_1}
                onUse={() => { fillSampleText('kategoria1Ref', SAMPLE_TEXT_1); setShowSample1(false); }}
                onClose={() => setShowSample1(false)}
              />
            )}
            <Ed block ref={kategoria1Ref} placeholder="Tu napíšte vlastnú odpoveď..." />
          </div>

          <div style={{ marginBottom: 24 }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 6 }}>
              <strong>2.2 Vznik a vývoj problémov</strong>
              <TipBtn pointKey="2.2" />
              <button
                className="no-copy no-print"
                onClick={() => setShowSample2(!showSample2)}
                style={{ fontSize: '0.78em', padding: '3px 10px', border: '1px solid var(--rule)', borderRadius: 'var(--r-sm)', background: 'var(--paper)', cursor: 'pointer', color: 'var(--ink-2)' }}
              >{showSample2 ? 'Skryť vzor' : 'Zobraziť vzor textu'}</button>
            </div>
            <p className="no-copy no-print" style={{ fontStyle: 'italic', fontSize: '0.85em', color: 'var(--ink-3)', margin: '0 0 8px' }}>
              Kedy nastali prvé problémy a čo ich spôsobilo? Snažili ste sa ich riešiť — ak áno, ako? Kedy nastal zlom, že ste si povedali, že už nechcete zotrvať v manželstve, a čo bolo tým zlomom?
            </p>
            {showSample2 && (
              <SamplePanel
                sampleText={SAMPLE_TEXT_2}
                onUse={() => { fillSampleText('kategoria2Ref', SAMPLE_TEXT_2); setShowSample2(false); }}
                onClose={() => setShowSample2(false)}
              />
            )}
            <Ed block ref={kategoria2Ref} placeholder="Tu napíšte vlastnú odpoveď..." />
          </div>

          <div style={{ marginBottom: 24 }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 6 }}>
              <strong>2.3 Súčasný stav vzťahu</strong>
              <TipBtn pointKey="2.3" />
              <button
                className="no-copy no-print"
                onClick={() => setShowSample3(!showSample3)}
                style={{ fontSize: '0.78em', padding: '3px 10px', border: '1px solid var(--rule)', borderRadius: 'var(--r-sm)', background: 'var(--paper)', cursor: 'pointer', color: 'var(--ink-2)' }}
              >{showSample3 ? 'Skryť vzor' : 'Zobraziť vzor textu'}</button>
            </div>
            <p className="no-copy no-print" style={{ fontStyle: 'italic', fontSize: '0.85em', color: 'var(--ink-3)', margin: '0 0 8px' }}>
              Keď ste manželovi/manželke povedali, že chcete rozvod, aká bola jeho/jej reakcia? Hospodárite spoločne — máte spoločný účet, kto kupuje potraviny, kto varí? Máte spoločných známych, záľuby, spoločné akcie? Kedy ste mali naposledy intímny styk?
            </p>
            {showSample3 && (
              <SamplePanel
                sampleText={SAMPLE_TEXT_3}
                onUse={() => { fillSampleText('kategoria3Ref', SAMPLE_TEXT_3); setShowSample3(false); }}
                onClose={() => setShowSample3(false)}
              />
            )}
            <Ed block ref={kategoria3Ref} placeholder="Tu napíšte vlastnú odpoveď..." />
          </div>

          <div style={{ marginBottom: 24 }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 6 }}>
              <strong>2.4 Pokusy o obnovu a výhľad do budúcnosti</strong>
              <TipBtn pointKey="2.4" />
              <button
                className="no-copy no-print"
                onClick={() => setShowSample4(!showSample4)}
                style={{ fontSize: '0.78em', padding: '3px 10px', border: '1px solid var(--rule)', borderRadius: 'var(--r-sm)', background: 'var(--paper)', cursor: 'pointer', color: 'var(--ink-2)' }}
              >{showSample4 ? 'Skryť vzor' : 'Zobraziť vzor textu'}</button>
            </div>
            <p className="no-copy no-print" style={{ fontStyle: 'italic', fontSize: '0.85em', color: 'var(--ink-3)', margin: '0 0 8px' }}>
              Snažili ste sa o obnovu manželstva — ak áno, akým spôsobom? Prečo podľa Vás obnova manželstva už nie je možná?
            </p>
            {showSample4 && (
              <SamplePanel
                sampleText={SAMPLE_TEXT_4}
                onUse={() => { fillSampleText('kategoria4Ref', SAMPLE_TEXT_4); setShowSample4(false); }}
                onClose={() => setShowSample4(false)}
              />
            )}
            <Ed block ref={kategoria4Ref} placeholder="Tu napíšte vlastnú odpoveď..." />
          </div>

          <p>
            Na základe vyššie uvedeného je zrejmé, že manželstvo účastníkov je hlboko a trvalo rozvrátené v zmysle § 23 ods. 1 zákona č. 36/2005 Z. z. o rodine a nemôže plniť svoj účel.
          </p>
        </section>

        {/* Čl. III — Právny základ */}
        <section className="article" id="art-3">
          <div style={{ pageBreakInside: 'avoid', breakInside: 'avoid' }}>
            <div className="article-head">
              <div className="article-num">Článok III</div>
              <span className="article-title">Právny základ</span>
            </div>

            <p>
              <strong>3.1</strong>&nbsp;&nbsp;Podľa § 23 ods. 1 zákona č. 36/2005 Z. z. o rodine súd môže manželstvo na návrh niektorého z manželov rozviesť, ak sú vzťahy medzi manželmi tak vážne narušené a trvalo rozvrátené, že manželstvo nemôže plniť svoj účel a od manželov nemožno očakávať obnovenie manželského spolužitia.
            </p>
          </div>

          <p>
            <strong>3.2</strong>&nbsp;&nbsp;Naše manželstvo dlhodobo neplní svoju spoločenskú funkciu. Rozvrat je trvalý a obnovenie manželského spolužitia nie je možné očakávať.
          </p>

          <p className="has-tip" style={{ margin: '12px 0' }}>
            <TipBtn pointKey="3.3" />
            <strong>3.3</strong> Na základe vyššie uvedeného navrhujem, aby súd po vykonanom dokazovaní vydal tento:
          </p>
        </section>

        {/* Návrh výroku */}
        <section className="proposed-verdict" id="art-verdict">
          <h3 className="verdict-heading">r o z s u d o k :</h3>
          <p>
            Súd manželstvo účastníkov konania uzavreté dňa{' '}
            <SyncedEd value={datumSobasa} onChange={setDatumSobasa} placeholder="DD. MM. RRRR" />
            {' '}v{' '}
            <SyncedEd value={miestoSobasa} onChange={setMiestoSobasa} placeholder="mesto" />
            , zapísané v knihe manželstiev matričného úradu{' '}
            <SyncedEd value={maticnyUrad} onChange={setMaticnyUrad} placeholder="názov matričného úradu" lg />
            , zväzok{' '}
            <SyncedEd value={zvazok} onChange={setZvazok} placeholder="č." num />
            , ročník{' '}
            <SyncedEd value={rocnik} onChange={setRocnik} placeholder="RRRR" num />
            , strana{' '}
            <SyncedEd value={strana} onChange={setStrana} placeholder="č." num />
            {' '}pod poradovým číslom{' '}
            <SyncedEd value={poradoveCislo} onChange={setPoradoveCislo} placeholder="č." num />
            {' '}<strong>r o z v á d z a</strong>.
          </p>
          <p>Žiaden z účastníkov n e m á právo na náhradu trov konania.</p>
        </section>

        {/* Záverečná časť — podpis + prílohy spolu, aby sa nezalomili na rôzne strany */}
        <div style={{ pageBreakInside: 'avoid', breakInside: 'avoid' }}>
          <div className="signature-row" style={{ marginTop: 24, display: 'flex', justifyContent: 'flex-end' }}>
            <div style={{ textAlign: 'center', minWidth: 240 }}>
              <div style={{ borderBottom: '1px solid var(--ink)', marginBottom: 6, height: 28 }}></div>
              <div className="no-print" style={{ fontFamily: 'var(--serif)' }}>{menoNavrhovatela}</div>
              <span className="ed-select-print">{menoNavrhovatela}</span>
            </div>
          </div>

          {/* Prílohy */}
          <div className="prilohy" style={{ marginTop: 36 }}>
            <p><TipBtn pointKey="prilohy" /><strong>Prílohy:</strong></p>
            <p>– sobášny list</p>
            <p>
              {dalsieDokazy && (
                <span className="ed-select-print">– {dalsieDokazy}</span>
              )}
              <span className="no-print">– <SyncedEd value={dalsieDokazy} onChange={setDalsieDokazy} placeholder="ďalšie dôkazy" /></span>
            </p>
          </div>
        </div>

      </article>

      {/* Actions — obrazovka only, print/Word skrýva (CSS ich rieši cez @media print) */}
      <div className="paper-actions no-print" role="group" aria-label="Akcie s návrhom">
        <div className="paper-actions__row">
          <button type="button" className="btn-download" onClick={() => window.print()}>
            <span className="btn-download__glyph" aria-hidden="true">↓</span>
            <span className="btn-download__main">Stiahnuť ako PDF</span>
            <span className="btn-download__meta">A4</span>
          </button>
          <button type="button" className="btn-download btn-download--ghost" onClick={() => window.__downloadAsDoc && window.__downloadAsDoc()}>
            <span className="btn-download__glyph" aria-hidden="true">↓</span>
            <span className="btn-download__main">Stiahnuť ako Word</span>
            <span className="btn-download__meta">.doc</span>
          </button>
          <button type="button" className="btn-download btn-download--danger" onClick={() => window.__clearFormFields && window.__clearFormFields()}>
            <span className="btn-download__glyph" aria-hidden="true">✕</span>
            <span className="btn-download__main">Vymazať údaje</span>
            <span className="btn-download__meta">natrvalo</span>
          </button>
        </div>
        <p className="paper-actions__note">
          PDF sa otvorí v dialógu tlače prehliadača — v cieli zvoľte <em>Uložiť ako PDF</em>. Word (.doc) otvoríte v MS Word alebo LibreOffice a môžete návrh ďalej upraviť.
        </p>
      </div>
    </div>
    </TipContext.Provider>
  );
};

// ============================================================
// downloadAsDoc — export paper HTML to .doc (Word)
// Class names referenced: .paper, .article, .article-head, .article-num,
// .article-title, .doc-title, .doc-sub, .ed, .ed-select, .ed-select-print,
// .paper-actions, .signatures, .sig-block, .sig-person, .sig-cap, .sig-name,
// .sig-line, .doc-footer-meta, .party-alias, .party-alias-term, .tip-pin
// ============================================================
function downloadAsDoc() {
  const article = document.querySelector('article.paper');
  if (!article) return;
  const clone = article.cloneNode(true);

  // 1) Remove chrome that has no meaning on paper
  const killSelectors = [
    '.tip-pin', '.tip-pin-inline', '.tip-back',
    '.seg-toggle', '.seg-add',
    '.party-add', '.party-type-switch', '.party-type-switch-sub',
    '.party-type-switch-wrap', '.inflation-variant-picker',
    '.legal-hint',
    '.no-copy', '.no-print',
  ];
  clone.querySelectorAll(killSelectors.join(',')).forEach(el => el.remove());

  // 3) Replace <select.ed-select> with its selected option's label (plain text)
  clone.querySelectorAll('select.ed-select').forEach(sel => {
    const liveSel = findMatchingLiveElement(article, clone, sel);
    let label = '';
    if (liveSel && liveSel.options && liveSel.selectedIndex >= 0) {
      label = liveSel.options[liveSel.selectedIndex].textContent || '';
    } else {
      const first = sel.querySelector('option');
      label = first ? first.textContent : '';
    }
    const span = document.createElement('span');
    span.textContent = label;
    sel.parentNode.replaceChild(span, sel);
  });

  // 3b) Signature-row → align="right" tabuľka. MUSÍ bežať PRED step 4, ktorý unwrap-uje
  // .ed-select-print spany na text nody — inak by sme z signature-row už nevedeli prečítať
  // menoNavrhovatela (jediný element nesúci hodnotu po killovaní .no-print v step 2).
  // Word table layout: explicitné `width: 200pt` na <table> a `height: 36pt` na hornej
  // bunke — Word ignoruje `min-width` na <td>, takže bez tohto by sa bunka zmrštila na
  // šírku &nbsp; a podpisová čiara by vyzerala ako tenká pomlčka.
  clone.querySelectorAll('.signature-row').forEach(row => {
    const printSpan = row.querySelector('.ed-select-print');
    const meno = printSpan ? (printSpan.textContent || '').trim() : '';
    const wrap = document.createElement('div');
    wrap.setAttribute('align', 'right');
    wrap.style.cssText = 'margin-top:36pt;margin-bottom:18pt;';
    wrap.innerHTML =
      '<table align="right" cellpadding="0" cellspacing="0" border="0" style="border-collapse:collapse;width:200pt;">' +
        '<tr><td style="border-bottom:1px solid #000;height:36pt;line-height:36pt;padding:0;">&nbsp;</td></tr>' +
        '<tr><td style="text-align:center;padding-top:6pt;font-family:Georgia,serif;">' + meno + '</td></tr>' +
      '</table>';
    row.parentNode.replaceChild(wrap, row);
  });

  // 4) Mirror elements for selects (Ed komponent ich označuje aria-hidden="true")
  // — odstrániť úplne, lebo step 3 už nahradil <select> tým istým textom.
  // Ostatné .ed-select-print (autocomplete sud nazov, dalsie dokazy …) unwrap na text,
  // aby sa hodnota dostala do dokumentu (na obrazovke sú display:none).
  clone.querySelectorAll('.ed-select-print').forEach(el => {
    if (el.getAttribute('aria-hidden') === 'true') {
      el.remove();
      return;
    }
    const textNode = document.createTextNode(el.textContent || '');
    el.parentNode.replaceChild(textNode, el);
  });
  // Block-variant tej istej veci (adresa súdu v hlavičke) — unwrap so zachovaním
  // line-breaks (každý <div class="ed-select-print-block"> sa nahradí odsekom,
  // aby v Worde každý zostal na vlastnom riadku).
  clone.querySelectorAll('.ed-select-print-block').forEach(el => {
    const text = (el.textContent || '').trim();
    if (!text) { el.remove(); return; }
    const p = document.createElement('p');
    p.setAttribute('align', 'right');
    p.style.cssText = 'margin:0;line-height:1.5;text-align:right;';
    p.textContent = text;
    el.parentNode.replaceChild(p, el);
  });

  // 4d) Hlavička dokumentu — pravý stĺpec má byť zarovnaný vpravo a medzi
  // adresou súdu a riadkom „Bratislava, [dátum]" má byť prázdny odsek.
  const headerRight = clone.querySelector('.paper-header-right');
  if (headerRight) {
    headerRight.setAttribute('align', 'right');
    headerRight.style.textAlign = 'right';
    // Prázdny riadok pred odsekom obsahujúcim "Bratislava," (posledný <p> v stĺpci)
    const ps = headerRight.querySelectorAll(':scope > p');
    const dateP = ps[ps.length - 1];
    if (dateP) {
      dateP.setAttribute('align', 'right');
      dateP.style.textAlign = 'right';
      const spacer = document.createElement('p');
      spacer.style.cssText = 'margin:0;line-height:1.5;';
      spacer.innerHTML = '&nbsp;';
      dateP.parentNode.insertBefore(spacer, dateP);
    }
  }

  // 4c) party-grid → HTML tabuľka. CSS Grid je v Worde nespoľahlivý, label
  // a hodnota sa zlepujú. Tabuľka má každý label v ľavom stĺpci, hodnotu v
  // pravom; každý pár na vlastnom riadku. Spúšťa sa pred krokom 5 (unwrap .ed),
  // aby textContent .ed polí bol stále dostupný.
  clone.querySelectorAll('.party-grid').forEach(grid => {
    const children = Array.from(grid.children);
    const tbl = document.createElement('table');
    tbl.setAttribute('cellpadding', '0');
    tbl.setAttribute('cellspacing', '0');
    tbl.setAttribute('border', '0');
    tbl.style.cssText = 'border-collapse:collapse;width:100%;margin:0 0 8pt;';
    for (let i = 0; i < children.length; i += 2) {
      const labelEl = children[i];
      const valueEl = children[i + 1];
      if (!labelEl || !valueEl) break;
      // Hodnota zložená z viacerých detí (napr. meno + "rod.:" + rodné priezvisko)
      // spojí children textContent medzerou; jednoduché Ed pole použije svoj textContent.
      const elementChildren = Array.from(valueEl.children);
      const valueText = elementChildren.length > 0
        ? elementChildren.map(c => (c.textContent || '').trim()).filter(Boolean).join(' ')
        : (valueEl.textContent || '').trim();
      const tr = document.createElement('tr');
      const tdLabel = document.createElement('td');
      tdLabel.style.cssText = 'width:160px;vertical-align:baseline;padding:1pt 12pt 1pt 0;';
      tdLabel.textContent = (labelEl.textContent || '').trim();
      const tdValue = document.createElement('td');
      tdValue.style.cssText = 'vertical-align:baseline;padding:1pt 0;';
      tdValue.textContent = valueText;
      tr.appendChild(tdLabel);
      tr.appendChild(tdValue);
      tbl.appendChild(tr);
    }
    grid.parentNode.replaceChild(tbl, grid);
  });

  // 4e) Page-break-before — pred každý element s touto triedou vlož Word-specific
  // <br> s mso-special-character, ktorý Word interpretuje ako tvrdé zalomenie strany.
  // CSS page-break-before sa v staršom HTML-Word renderingu spoľahlivo neuplatní.
  clone.querySelectorAll('.page-break-before').forEach(el => {
    const br = document.createElement('br');
    br.setAttribute('clear', 'all');
    br.style.cssText = 'mso-special-character:line-break;page-break-before:always;';
    el.parentNode.insertBefore(br, el);
    // Doplniť aj inline style, nech moderný Word/LibreOffice zachytí oba mechanizmy.
    el.style.pageBreakBefore = 'always';
  });

  // 5) Turn contentEditable .ed spans into plain text.
  // .ed-block (Čl. II — kategórie 2.1-2.4, viacriadkový text) konvertujeme na <p>,
  // nie na <span>, aby Word korektne aplikoval text-align: justify (Word ho na
  // inline elementoch nehonoruje). white-space: pre-wrap zachová newliny.
  clone.querySelectorAll('.ed').forEach(ed => {
    const text = ed.textContent || '';
    if (ed.classList.contains('ed-block')) {
      const p = document.createElement('p');
      p.style.cssText = 'text-align:justify;white-space:pre-wrap;margin:0 0 10pt;';
      p.textContent = text;
      ed.parentNode.replaceChild(p, ed);
    } else {
      const span = document.createElement('span');
      span.textContent = text;
      ed.parentNode.replaceChild(span, ed);
    }
  });

  // 6) Remove download actions footer if it slipped in
  clone.querySelectorAll('.paper-actions').forEach(el => el.remove());

  // 6a) Convert signatures block into a 2-column TABLE — Word renders tables reliably
  //     (CSS grid & inline-block with fixed % are flaky in .doc HTML)
  const sigGrid = clone.querySelector('.signatures');
  if (sigGrid) {
    const blocks = Array.from(sigGrid.querySelectorAll(':scope > .sig-block'));
    const [left, right] = [blocks[0], blocks[1]];
    const table = document.createElement('table');
    table.setAttribute('width', '100%');
    table.setAttribute('cellpadding', '0');
    table.setAttribute('cellspacing', '0');
    table.setAttribute('border', '0');
    table.style.cssText = 'margin-top:48pt;width:100%;border-collapse:collapse;';
    const tr = document.createElement('tr');
    [left, right].forEach(b => {
      const td = document.createElement('td');
      td.setAttribute('width', '50%');
      td.style.cssText = 'width:50%;vertical-align:top;text-align:center;padding:0 12pt;';
      if (b) td.appendChild(b);
      tr.appendChild(td);
    });
    table.appendChild(tr);
    sigGrid.parentNode.replaceChild(table, sigGrid);
  }

  // 6b) Rebuild sig-block as a single table — Word respects table-cell padding
  // but applies automatic paragraph spacing to <div>s. Tables reliably stay tight.
  clone.querySelectorAll('.sig-block').forEach(block => {
    const outerCap = block.querySelector(':scope > .sig-cap');
    const persons = Array.from(block.querySelectorAll(':scope > .sig-person'));

    const tbl = document.createElement('table');
    tbl.setAttribute('width', '100%');
    tbl.setAttribute('cellpadding', '0');
    tbl.setAttribute('cellspacing', '0');
    tbl.setAttribute('border', '0');
    tbl.style.cssText = 'width:100%;border-collapse:collapse;';

    const mkRow = (html, css, innerCss) => {
      const tr = document.createElement('tr');
      const td = document.createElement('td');
      td.setAttribute('align', 'center');
      td.style.cssText = 'padding:0;text-align:center;line-height:1;' + (css || '');
      td.innerHTML =
        '<p align="center" style="margin:0;padding:0;text-align:center;' +
        'mso-margin-top-alt:0;mso-margin-bottom-alt:0;' +
        'mso-line-height-rule:exactly;line-height:115%;' + (innerCss || '') + '">' +
        html + '</p>';
      tr.appendChild(td);
      tbl.appendChild(tr);
    };

    if (outerCap) {
      mkRow(
        outerCap.textContent.trim().toUpperCase(),
        'padding:0 0 44pt;text-align:center;',
        "font-family:'IBM Plex Sans',Arial,sans-serif;font-size:9pt;letter-spacing:1.5pt;color:#555;text-align:center;"
      );
    }

    persons.forEach((person, idx) => {
      const cap  = person.querySelector('.sig-cap');
      const name = person.querySelector('.sig-name');
      if (idx > 0) {
        mkRow('&nbsp;', 'padding:28pt 0 0;', 'font-size:1pt;line-height:1pt;');
      }
      mkRow('&nbsp;', 'border-bottom:1px solid #0f1116;height:1pt;line-height:1pt;font-size:1pt;');
      mkRow(
        cap ? cap.textContent.trim().toUpperCase() : '',
        'padding-top:6pt;text-align:center;',
        "font-family:'IBM Plex Sans',Arial,sans-serif;font-size:9pt;letter-spacing:1.5pt;color:#555;text-align:center;"
      );
      mkRow(
        name ? name.textContent.trim() : '',
        'padding-top:3pt;text-align:center;',
        'font-size:10pt;font-style:italic;color:#666;text-align:center;'
      );
    });

    block.innerHTML = '';
    block.appendChild(tbl);
  });

  // 6c) Footer meta — Word doesn't flex; render as inline with dot separators
  const meta = clone.querySelector('.doc-footer-meta');
  if (meta) {
    const spans = Array.from(meta.querySelectorAll(':scope > span'));
    meta.innerHTML = spans.map(s => s.textContent.trim()).join(' &nbsp;·&nbsp; ');
  }

  // 7) Inline minimal styling — Word understands a subset of CSS
  const styles = `
    @page WordSection1 { size: A4; margin: 2cm 2cm 2.2cm 2cm; mso-footer: f1; mso-footer-margin: 1.2cm; }
    div.WordSection1 { page: WordSection1; }
    p.MsoFooter, li.MsoFooter, div.MsoFooter { margin: 0; padding: 0; mso-pagination: widow-orphan; text-align: center; font-family: "IBM Plex Mono", Consolas, monospace; font-size: 9pt; color: #888888; }
    body { font-family: "Libre Caslon Text", Georgia, serif; color: #0f1116; font-size: 12pt; line-height: 1.5; }
    .sig-block, .sig-block div, .sig-block p { mso-margin-top-alt: 0; mso-margin-bottom-alt: 0; }
    h1.doc-title { font-size: 16pt; text-align: center; letter-spacing: 2pt; margin: 0 0 6pt; text-transform: uppercase; font-weight: 700; }
    .doc-sub { text-align: center; font-family: "IBM Plex Mono", Consolas, monospace; font-size: 9pt; letter-spacing: 1.5pt; text-transform: uppercase; color: #555; margin: 0 0 18pt; }
    .doc-note { text-align: center; font-size: 9pt; color: #666; margin: 0 0 24pt; font-style: italic; }
    .article { margin: 0 0 22pt; }
    .article-head { text-align: center; margin: 22pt 0 10pt; }
    .article-num { font-family: "Libre Caslon Text", Georgia, serif; font-size: 13pt; font-weight: 700; letter-spacing: 3pt; text-transform: uppercase; }
    .article-title { display: block; font-style: italic; color: #333; font-size: 11pt; margin-top: 2pt; letter-spacing: 1pt; }
    p { margin: 0 0 10pt; text-align: justify; }
    strong { font-weight: 700; }
    em, i { font-style: italic; }
    .signatures { margin-top: 48pt; width: 100%; }
    .sig-block { display: inline-block; width: 48%; vertical-align: top; text-align: center; }
    .sig-block .sig-cap { margin: 0; padding: 0; }
    .sig-block .sig-cap + .sig-person .sig-line { margin-top: 36pt; }
    .sig-cap { font-family: "IBM Plex Sans", Arial, sans-serif; font-size: 9pt; letter-spacing: 1.5pt; text-transform: uppercase; color: #555; margin: 0; padding: 0; line-height: 1.3; }
    .sig-line { border-bottom: 1px solid #0f1116; margin: 36pt 0 4pt; height: 1pt; line-height: 1pt; font-size: 1pt; }
    .sig-name { font-size: 10pt; font-style: italic; color: #666; margin: 2pt 0 0; padding: 0; line-height: 1.3; }
    .sig-person { margin: 0; padding: 0; }
    .sig-person + .sig-person .sig-line { margin-top: 36pt; }
    .sig-person .sig-cap { margin-top: 2pt; }
    .doc-footer-meta { margin-top: 36pt; padding-top: 10pt; border-top: 1px solid #ccc; font-family: "IBM Plex Mono", Consolas, monospace; font-size: 8pt; letter-spacing: 1.5pt; text-transform: uppercase; color: #555; }
    .doc-footer-meta span { margin-right: 24pt; }
    .party-alias { font-style: italic; color: #555; margin-top: 6pt; font-size: 11pt; }
    .party-alias-term { font-style: normal; font-weight: 600; color: #0f1116; }
    .parties { margin: 18pt 0 24pt; }
    .party-line { margin: 0 0 4pt; }
    .paper-header { margin: 0 0 24pt; }
    .doc-date { margin-top: 24pt; }
    .proposed-verdict { margin: 24pt 0; padding: 18pt; border: 1pt solid #0f1116; background: #fafafa; }
    .verdict-heading { text-align: center; font-family: "Libre Caslon Text", Georgia, serif; font-size: 14pt; letter-spacing: 4pt; text-transform: uppercase; margin: 0 0 12pt; font-weight: 700; }
    .evidence { font-style: italic; color: #555; margin-top: 6pt; }
    .prilohy p { margin: 0 0 4pt; }
  `;

  // 8) Compose the Word HTML shell.
  // Footer cez @page mso-footer + <div mso-element:footer id="f1"> — Word renderuje
  // ako pravú pätičku na každej strane. Štýly riadi p.MsoFooter v <style> bloku
  // (center, mono 9pt, šedá). Footer div MUSÍ byť sibling .WordSection1, nie dieťa
  // — Word jeho obsah nezobrazí v toku dokumentu, len ho pripojí ako page footer.
  const body = clone.outerHTML;
  const footer = `<div style='mso-element:footer' id="f1"><p class="MsoFooter">Vytvorené pomocou webovej stránky - ziadostorozvod.sk</p></div>`;
  const html =
`<html xmlns:o="urn:schemas-microsoft-com:office:office"
       xmlns:w="urn:schemas-microsoft-com:office:word"
       xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta charset="utf-8" />
<title>Návrh na rozvod manželstva</title>
<!--[if gte mso 9]><xml><w:WordDocument><w:View>Print</w:View><w:Zoom>100</w:Zoom></w:WordDocument></xml><![endif]-->
<style>${styles}</style>
</head>
<body>
<div class="WordSection1">${body}</div>
${footer}
</body>
</html>`;

  // 9) Trigger download
  window.__lastDocHtml = html;
  const blob = new Blob(['﻿', html], { type: 'application/msword' });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = 'navrh-na-rozvod.doc';
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
  setTimeout(() => URL.revokeObjectURL(url), 1000);
}

// Helper: given cloned node, find corresponding live node in source tree
// (same relative position in the DOM).
function findMatchingLiveElement(liveRoot, cloneRoot, cloneEl) {
  const path = [];
  let n = cloneEl;
  while (n && n !== cloneRoot) {
    const p = n.parentNode;
    if (!p) break;
    path.unshift(Array.prototype.indexOf.call(p.children, n));
    n = p;
  }
  let cur = liveRoot;
  for (const idx of path) {
    if (!cur || !cur.children || !cur.children[idx]) return null;
    cur = cur.children[idx];
  }
  return cur;
}

window.Paper = Paper;
window.__downloadAsDoc = downloadAsDoc;
