// ============================================================
// Paper — A4 telo dokumentu kúpnej zmluvy s inline editovateľnými poliami
// Štruktúra: VIII článkov (predmet, cena, odovzdanie, vlastníctvo,
// povinnosti predávajúceho, povinnosti kupujúceho, vady, záverečné).
// ============================================================

// Mobile UA detection — Word-export tlačidlo na mobile by sa mu nezobrazilo,
// preto je vypnuté. Test override: ?forceDesktopUI=1 v URL.
const __IS_MOBILE_DEVICE = (() => {
  if (typeof navigator === 'undefined') return false;
  try {
    const params = new URLSearchParams(window.location.search);
    if (params.get('forceDesktopUI') === '1') return false;
  } catch (e) {}
  return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent || '');
})();

// PartyBlock — person/entrepreneur toggle for a single party line
const PartyBlock = ({ label, type, onTypeChange, onRemove, demo, onDisplayChange }) => {
  const isPerson = type === 'person';
  const [bizKind, setBizKind] = React.useState('po'); // 'po' = právnická osoba, 'szco' = fyzická osoba – podnikateľ

  const [personName, setPersonName] = React.useState('');
  const [companyName, setCompanyName] = React.useState('');
  const [companyRep, setCompanyRep] = React.useState('');

  React.useEffect(() => {
    if (!onDisplayChange) return;
    let text = '';
    if (isPerson) {
      text = personName.trim();
    } else if (bizKind === 'po') {
      const nm = companyName.trim();
      const rep = companyRep.trim();
      text = nm && rep ? `${nm} — zast. ${rep}` : nm;
    } else {
      text = companyName.trim();
    }
    onDisplayChange(text);
  }, [isPerson, bizKind, personName, companyName, companyRep]);
  const isSeller = label.toLowerCase().startsWith('pred');
  const roleGen = isSeller ? 'predávajúceho' : 'kupujúceho';
  return (
    <div className="party-block">
      <div className="party-role no-copy">
        <span className="party-role-label">{label}</span>
        <div className="party-type-switches">
          <div className="party-type-switch" role="tablist" aria-label="Typ osoby">
            <button
              role="tab"
              aria-selected={isPerson}
              className={isPerson ? 'active' : ''}
              onClick={() => onTypeChange('person')}
            >
              <svg width="11" height="11" viewBox="0 0 12 12" fill="none" aria-hidden="true">
                <circle cx="6" cy="4" r="2.1" stroke="currentColor" strokeWidth="1.1"/>
                <path d="M2.2 10.5c.5-2 2-3 3.8-3s3.3 1 3.8 3" stroke="currentColor" strokeWidth="1.1" strokeLinecap="round"/>
              </svg>
              Fyzická osoba
            </button>
            <button
              role="tab"
              aria-selected={!isPerson}
              className={!isPerson ? 'active' : ''}
              onClick={() => onTypeChange('company')}
            >
              <svg width="11" height="11" viewBox="0 0 12 12" fill="none" aria-hidden="true">
                <rect x="1.8" y="2.3" width="8.4" height="7.4" stroke="currentColor" strokeWidth="1.1"/>
                <path d="M4 5.2h1M7 5.2h1M4 7.2h1M7 7.2h1" stroke="currentColor" strokeWidth="1.1" strokeLinecap="round"/>
              </svg>
              Podnikateľ
            </button>
          </div>
          {!isPerson && (
            <div className="party-type-switch party-type-switch-sub" role="tablist" aria-label="Typ podnikateľa">
              <button
                role="tab"
                aria-selected={bizKind === 'po'}
                className={bizKind === 'po' ? 'active' : ''}
                onClick={() => setBizKind('po')}
              >
                Právnická osoba
              </button>
              <button
                role="tab"
                aria-selected={bizKind === 'szco'}
                className={bizKind === 'szco' ? 'active' : ''}
                onClick={() => setBizKind('szco')}
              >
                FO – podnikateľ
              </button>
            </div>
          )}
        </div>
        {onRemove && <button className="remove" onClick={onRemove} aria-label="Odstrániť">×</button>}
      </div>

      {isPerson ? (
        <p className="party-line">
          <span className="party-field"><span className="ed-cg"><Ed defaultValue={demo.name} placeholder="Meno a priezvisko" lg onValueChange={setPersonName} />,</span></span>
          {' '}<span className="party-field">nar. <span className="ed-cg"><Ed defaultValue={demo.born} placeholder="DD. MM. RRRR" />,</span></span>
          {' '}<span className="party-field">r. č. <span className="ed-cg"><Ed defaultValue="" placeholder="000000/0000" />,</span></span>
          {' '}<span className="party-field">trvalý pobyt <span className="ed-cg"><Ed defaultValue={demo.addr} placeholder="Ulica, č., PSČ, mesto" xl />,</span></span>
          {' '}<span className="party-field">č. OP <span className="ed-cg"><Ed defaultValue="" placeholder="napr. EK 884 231" />,</span></span>
          {' '}<span className="party-field">tel. <span className="ed-cg"><Ed defaultValue="" placeholder="0900 000 000" />,</span></span>
          {' '}<span className="party-field">e-mail <span className="ed-cg"><Ed defaultValue="" placeholder="email@email.com" lg />{isSeller ? ',' : ''}</span></span>
          {isSeller && <>{' '}<span className="party-field">IBAN <span className="ed-cg"><Ed defaultValue="" placeholder="SK00 0000 0000 0000 0000 0000" xl /></span></span></>}
        </p>
      ) : (
        <p className="party-line">
          <span className="party-field"><span className="ed-cg"><Ed defaultValue="" placeholder="Obchodné meno" lg onValueChange={setCompanyName} />,</span></span>
          {' '}<span className="party-field">{bizKind === 'po' ? 'sídlo' : 'miesto podnikania'} <span className="ed-cg"><Ed defaultValue="" placeholder="Ulica, č., PSČ, mesto" xl />,</span></span>
          {' '}<span className="party-field"><span className="ed-cg">IČO: <Ed defaultValue="" placeholder="00 000 000" />,</span></span>
          {' '}<span className="party-field"><span className="ed-cg">DIČ: <Ed defaultValue="" placeholder="0000000000" />,</span></span>
          {bizKind === 'po' && <>{' '}<span className="party-field">zapísaná v <span className="ed-cg"><Ed defaultValue="" placeholder="OR Mestského súdu …, odd. …, vl. č. …" xl />,</span></span></>}
          {bizKind === 'po' && <>{' '}<span className="party-field">zastúpená <span className="ed-cg"><Ed defaultValue="" placeholder="meno a funkcia konateľa" lg onValueChange={setCompanyRep} />,</span></span></>}
          {' '}<span className="party-field">tel. <span className="ed-cg"><Ed defaultValue="" placeholder="0900 000 000" />,</span></span>
          {' '}<span className="party-field">e-mail <span className="ed-cg"><Ed defaultValue="" placeholder="email@email.com" lg />{isSeller ? ',' : ''}</span></span>
          {isSeller && <>{' '}<span className="party-field">IBAN <span className="ed-cg"><Ed defaultValue="" placeholder="SK00 0000 0000 0000 0000 0000" xl /></span></span></>}
        </p>
      )}
    </div>
  );
};

window.PartyBlock = PartyBlock;

// ============================================================
// Doctype-specific identifikačné polia pre Čl. II bod 2.2
// (preložené do JSX pomocou .map() v render-i). Každý field má:
//   label       — text pred input poľom
//   placeholder — vzorová hodnota
//   size        — 'lg' | 'xl' (Ed wide variant)
//   num         — true pre čísla (zarovnanie vpravo)
//   suffix      — text za poľom (napr. " km")
// Doctypy sú zámerne minimálne — len polia, ktoré reálne dávajú zmysel
// pre daný typ vozidla. Napr. prívesný vozík O1 nemá motor → žiadny EK,
// žiadny tachometer, často ani EVČ.
// ============================================================
const VEHICLE_FIELDS = {
  auto: [
    { label: 'Druh vozidla / kategória', placeholder: 'napr. M1 — osobné vozidlo', size: 'lg' },
    { label: 'Továrenská značka', placeholder: 'napr. Škoda', size: 'lg' },
    { label: 'Obchodný názov / model', placeholder: 'napr. Octavia Combi 2.0 TDI', size: 'xl' },
    { label: 'Variant / verzia (ak je)', placeholder: 'napr. Style 110 kW', size: 'lg' },
    { label: 'Identifikačné číslo vozidla (VIN)', placeholder: '17 znakov, napr. TMBJB7NE6P0123456', size: 'xl', num: true },
    { label: 'Evidenčné číslo vozidla (EVČ)', placeholder: 'napr. BA-123AB' },
    { label: 'Rok výroby', placeholder: 'napr. 2019', num: true },
    { label: 'Dátum prvej evidencie', placeholder: 'DD. MM. RRRR' },
    { label: 'Farba (vonkajšia)', placeholder: 'napr. Race Blue metalíza', size: 'lg' },
    { label: 'Stav počítadla kilometrov ku dňu podpisu zmluvy', placeholder: 'napr. 124 850', num: true, suffix: ' km' },
    { label: 'Číslo osvedčenia o evidencii časť II (technický preukaz)', placeholder: 'napr. SK 123 456' },
    { label: 'Platnosť STK do', placeholder: 'MM / RRRR' },
    { label: 'Platnosť EK do', placeholder: 'MM / RRRR' },
    { label: 'Výbava a príslušenstvo', placeholder: 'napr. klimatizácia, ťažné zariadenie, 2× zimné kolesá, 2× kľúč', size: 'xl' },
  ],
  motorka: [
    { label: 'Druh vozidla / kategória', placeholder: 'napr. L3e — motocykel (alebo L1e moped, L7e štvorkolka)', size: 'xl' },
    { label: 'Továrenská značka', placeholder: 'napr. Yamaha', size: 'lg' },
    { label: 'Obchodný názov / model', placeholder: 'napr. MT-07', size: 'lg' },
    { label: 'Variant / verzia (ak je)', placeholder: 'napr. ABS 55 kW', size: 'lg' },
    { label: 'Identifikačné číslo vozidla (VIN, na ráme pri hlave riadenia)', placeholder: '17 znakov, napr. JYARM37E0PA001234', size: 'xl', num: true },
    { label: 'Číslo motora', placeholder: 'napr. CP2E-1234567', size: 'lg' },
    { label: 'Evidenčné číslo vozidla (EVČ)', placeholder: 'napr. BA-123AB' },
    { label: 'Objem motora', placeholder: 'napr. 689', num: true, suffix: ' cm³' },
    { label: 'Výkon motora', placeholder: 'napr. 55', num: true, suffix: ' kW' },
    { label: 'Rok výroby', placeholder: 'napr. 2021', num: true },
    { label: 'Dátum prvej evidencie', placeholder: 'DD. MM. RRRR' },
    { label: 'Farba', placeholder: 'napr. Storm Blue', size: 'lg' },
    { label: 'Stav počítadla kilometrov ku dňu podpisu zmluvy', placeholder: 'napr. 18 500', num: true, suffix: ' km' },
    { label: 'Číslo osvedčenia o evidencii časť II', placeholder: 'napr. SK 123 456' },
    { label: 'Platnosť STK do', placeholder: 'MM / RRRR' },
    { label: 'Výbava a príslušenstvo', placeholder: 'napr. bočné kufre, ohrev rukovätí, originálny výfuk, 2× kľúč, prilba', size: 'xl' },
  ],
  dodavka: [
    { label: 'Druh vozidla / kategória', placeholder: 'napr. N1 — úžitkové do 3,5 t (alebo N2 do 12 t, N3 nad 12 t)', size: 'xl' },
    { label: 'Továrenská značka', placeholder: 'napr. Mercedes-Benz', size: 'lg' },
    { label: 'Obchodný názov / model', placeholder: 'napr. Sprinter 316 CDI L2H2', size: 'xl' },
    { label: 'Variant / verzia (ak je)', placeholder: 'napr. dlhá verzia, vysoká strecha', size: 'lg' },
    { label: 'Identifikačné číslo vozidla (VIN)', placeholder: '17 znakov, napr. WDB9066131S123456', size: 'xl', num: true },
    { label: 'Evidenčné číslo vozidla (EVČ)', placeholder: 'napr. BA-123AB' },
    { label: 'Rok výroby', placeholder: 'napr. 2018', num: true },
    { label: 'Dátum prvej evidencie', placeholder: 'DD. MM. RRRR' },
    { label: 'Farba', placeholder: 'napr. arktická biela', size: 'lg' },
    { label: 'Stav počítadla kilometrov ku dňu podpisu zmluvy', placeholder: 'napr. 245 000', num: true, suffix: ' km' },
    { label: 'Najväčšia povolená hmotnosť', placeholder: 'napr. 3 500', num: true, suffix: ' kg' },
    { label: 'Užitočná hmotnosť (nosnosť)', placeholder: 'napr. 1 200', num: true, suffix: ' kg' },
    { label: 'Číslo osvedčenia o evidencii časť II', placeholder: 'napr. SK 123 456' },
    { label: 'Platnosť STK do', placeholder: 'MM / RRRR' },
    { label: 'Platnosť EK do', placeholder: 'MM / RRRR' },
    { label: 'Výbava a príslušenstvo', placeholder: 'napr. ťažné zariadenie, drevené obloženie nákladového priestoru, klimatizácia, GPS, tachograf', size: 'xl' },
  ],
  pripojne: [
    { label: 'Druh vozíka / kategória', placeholder: 'napr. O1 — do 750 kg (alebo O2, O3, O4)', size: 'xl' },
    { label: 'Továrenská značka / výrobca', placeholder: 'napr. Agados, Brenderup, Vezeko', size: 'lg' },
    { label: 'Typ / model', placeholder: 'napr. Vz-21, Tipper 1205', size: 'lg' },
    { label: 'Identifikačné číslo (VIN, na typovom štítku alebo ráme)', placeholder: '17 znakov; pri starších modeloch môže mať menej', size: 'xl', num: true },
    { label: 'Evidenčné číslo vozidla (EVČ, ak je pridelené)', placeholder: 'napr. BA-123AB' },
    { label: 'Rok výroby', placeholder: 'napr. 2020', num: true },
    { label: 'Farba', placeholder: 'napr. čierna', size: 'lg' },
    { label: 'Najväčšia povolená hmotnosť', placeholder: 'napr. 750', num: true, suffix: ' kg' },
    { label: 'Užitočná hmotnosť (nosnosť)', placeholder: 'napr. 500', num: true, suffix: ' kg' },
    { label: 'Rozmery ložnej plochy', placeholder: 'napr. 2 050 × 1 250 × 350 mm', size: 'lg' },
    { label: 'Pneumatiky', placeholder: 'napr. 145/80 R13', size: 'lg' },
    { label: 'Číslo osvedčenia o evidencii (ak je vydané)', placeholder: 'napr. SK 123 456' },
    { label: 'Platnosť STK do (pri kategórii O2 a vyššej)', placeholder: 'MM / RRRR' },
    { label: 'Výbava a príslušenstvo', placeholder: 'napr. plachta, oje s nábežnou brzdou, podporné koliesko, 13-pólová zásuvka', size: 'xl' },
  ],
};

const Paper = ({ doctype, sellers, setSellers, buyers, setBuyers, optionals, setActiveArticle, setActiveTipKey, onTipClick, activeTipKey }) => {
  const meta = DOCTYPES.find(d => d.id === doctype) || DOCTYPES[0];

  // Small floating "TIP" button on the paper margin
  const TipBtn = ({ pointKey, inline, end }) => (
    <button
      type="button"
      className={`tip-pin no-print ${inline ? 'tip-pin-inline' : ''} ${end ? 'tip-pin-end' : ''} ${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}
    >
      TIP
    </button>
  );

  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 points = document.querySelectorAll('.paper p.has-tip .tip-pin[data-tip-key]');
    const pointEls = Array.from(points).map(btn => ({ el: btn.closest('p.has-tip'), key: btn.dataset.tipKey }));
    let currentKey = null;
    const pObs = new IntersectionObserver((entries) => {
      const hits = entries
        .filter(e => e.isIntersecting)
        .map(e => {
          const found = pointEls.find(pe => pe.el === e.target);
          return found ? { ...found, top: e.boundingClientRect.top } : null;
        })
        .filter(Boolean)
        .sort((a, b) => a.top - b.top);
      if (hits.length && hits[0].key !== currentKey) {
        currentKey = hits[0].key;
        setActiveTipKey && setActiveTipKey(currentKey);
      }
    }, { rootMargin: '-30% 0px -60% 0px' });
    pointEls.forEach(pe => pe.el && pObs.observe(pe.el));

    return () => { obs.disconnect(); pObs.disconnect(); };
  }, [doctype, sellers.length, buyers.length, optionals]);

  const addSeller = () => sellers.length < 10 && setSellers([...sellers, { id: Date.now(), type: 'person' }]);
  const removeSeller = (id) => sellers.length > 1 && setSellers(sellers.filter(l => l.id !== id));
  const setSellerType = (id, type) => setSellers(sellers.map(l => l.id === id ? { ...l, type } : l));
  const addBuyer = () => buyers.length < 10 && setBuyers([...buyers, { id: Date.now() + 1, type: 'person' }]);
  const removeBuyer = (id) => buyers.length > 1 && setBuyers(buyers.filter(t => t.id !== id));
  const setBuyerType = (id, type) => setBuyers(buyers.map(t => t.id === id ? { ...t, type } : t));

  const demoSeller = (i) => i === 0 ? { name: 'Mária Kováčová', born: '12. 03. 1974', id: 'EK 884 231', addr: 'Záhradnícka 12, 821 08 Bratislava' } : { name: '', born: '', id: '', addr: '' };
  const demoBuyer  = (i) => i === 0 ? { name: 'Ing. Peter Novák', born: '04. 08. 1991', id: 'HC 112 490', addr: 'Mickiewiczova 3, 811 07 Bratislava' } : { name: '', born: '', id: '', addr: '' };

  // Display names for signature area — fed by PartyBlock onDisplayChange
  const [sellerDisplay, setSellerDisplay] = React.useState({});
  const [buyerDisplay, setBuyerDisplay] = React.useState({});
  const setSD = (id) => (text) => setSellerDisplay(s => (s[id] === text ? s : { ...s, [id]: text }));
  const setBD = (id) => (text) => setBuyerDisplay(s => (s[id] === text ? s : { ...s, [id]: text }));

  // ===== Grammar helpers for singular/plural in parties =====
  const S = sellers.length > 1; // Predávajúci (plural)
  const B = buyers.length > 1;  // Kupujúci (plural)

  // Predávajúci
  const P_N   = S ? 'Predávajúci' : 'Predávajúci';      // nominatív (rovnaký tvar)
  const P_G   = S ? 'Predávajúcich' : 'Predávajúceho';  // genitív / akuzatív
  const P_D   = S ? 'Predávajúcim' : 'Predávajúcemu';   // datív
  const P_JE  = S ? 'sú' : 'je';
  const P_BY  = S ? 'boli' : 'bol';
  const P_VYH = S ? 'vyhlasujú' : 'vyhlasuje';
  const P_ZAV = S ? 'zaväzujú sa' : 'zaväzuje sa';
  const P_OPR = S ? 'oprávnení' : 'oprávnený';
  const P_POV = S ? 'povinní' : 'povinný';
  const P_POT = S ? 'potvrdzujú' : 'potvrdzuje';
  const P_ODV = S ? 'odovzdali' : 'odovzdal';
  const P_OD2 = S ? 'odovzdajú' : 'odovzdá';

  // Kupujúci
  const K_N   = B ? 'Kupujúci' : 'Kupujúci';
  const K_G   = B ? 'Kupujúcich' : 'Kupujúceho';
  const K_D   = B ? 'Kupujúcim' : 'Kupujúcemu';
  const K_JE  = B ? 'sú' : 'je';
  const K_BY  = B ? 'boli' : 'bol';
  const K_VYH = B ? 'vyhlasujú' : 'vyhlasuje';
  const K_OPR = B ? 'oprávnení' : 'oprávnený';
  const K_POV = B ? 'povinní' : 'povinný';
  const K_ZAV = B ? 'zaväzujú sa' : 'zaväzuje sa';
  const K_PRE = B ? 'prevzali' : 'prevzal';
  const K_BOL = B ? 'boli oboznámení' : 'bol oboznámený';

  // ----- State pre selecty / podmienené sekcie -----
  const [paymentMode, setPaymentMode] = React.useState('prevod');           // hotovost | prevod | kombinacia
  const [bankSchedule, setBankSchedule] = React.useState('jednorazovo');     // jednorazovo | mesacne | individualne
  const [comboSchedule, setComboSchedule] = React.useState('jednorazovo');   // pre časť C — prevodná zložka
  const [handover, setHandover] = React.useState('priPodpise');              // priPodpise | neskor
  const [ownership, setOwnership] = React.useState('odovzdanim');            // odovzdanim | prepisom | zaplatenim
  const [defects, setDefects] = React.useState('bez');                       // bez | s
  const [prepisMode, setPrepisMode] = React.useState('spolocne');            // spolocne | predavajuci | kupujuci | elektronicky
  const [evcMode, setEvcMode] = React.useState('zachovat');                  // zachovat | ponechat
  const hasPaymentInstallments =
    (paymentMode === 'prevod' && (bankSchedule === 'mesacne' || bankSchedule === 'individualne')) ||
    (paymentMode === 'kombinacia' && (comboSchedule === 'mesacne' || comboSchedule === 'individualne'));

  const penaltyPoint = (() => {
    if (paymentMode === 'hotovost') return '3.5';
    if (paymentMode === 'kombinacia') return hasPaymentInstallments ? '3.7' : '3.6';
    return hasPaymentInstallments ? '3.6' : '3.5';
  })();

  // Doctype-specific labels (vrátane placeholderu pre doklady v 2.3)
  const VEH = (() => {
    if (doctype === 'motorka')  return { nom: 'motocykel', gen: 'motocykla', aku: 'motocykel', dal: 'motocyklu', lab: 'motocykel', regKind: 'EVČ', hasOdo: true,
      docsPlaceholder: 'napr. osvedčenie o evidencii časť I + II, servisná knižka, originálny kľúč, návod na obsluhu' };
    if (doctype === 'dodavka')  return { nom: 'úžitkové vozidlo', gen: 'úžitkového vozidla', aku: 'úžitkové vozidlo', dal: 'úžitkovému vozidlu', lab: 'vozidlo', regKind: 'EVČ', hasOdo: true,
      docsPlaceholder: 'napr. osvedčenie o evidencii časť I + II, servisná knižka, 2× kľúč, karta tachografu, doklad o poslednej STK/EK' };
    if (doctype === 'pripojne') return { nom: 'prívesný vozík', gen: 'prívesného vozíka', aku: 'prívesný vozík', dal: 'prívesnému vozíku', lab: 'prívesný vozík', regKind: 'EVČ (ak je pridelené)', hasOdo: false,
      docsPlaceholder: 'napr. osvedčenie o evidencii (ak je vydané), typový štítok, návod na obsluhu' };
    return { nom: 'motorové vozidlo', gen: 'motorového vozidla', aku: 'motorové vozidlo', dal: 'motorovému vozidlu', lab: 'vozidlo', regKind: 'EVČ', hasOdo: true,
      docsPlaceholder: 'napr. osvedčenie o evidencii časť I + II, servisná knižka, 2× kľúč, návod na obsluhu' };
  })();

  return (
    <div className="paper-stage">
      <article className="paper" aria-label="Kúpna zmluva — editovateľný dokument">
        <h1 className="doc-title">{meta.title}</h1>
        <div className="doc-sub">
          uzatvorená podľa {meta.ref || '§ 588 a nasl. Občianskeho zákonníka'}
        </div>

        {/* Čl. I — Zmluvné strany */}
        <section className="article" id="art-1">
          <div className="article-head">
            <div className="article-num">Článok I</div>
            <span className="article-title">Zmluvné strany</span>
          </div>

          <p className="party-heading" style={{ fontWeight: 600, marginTop: 18, marginBottom: 10 }}>Predávajúci:</p>

          {sellers.map((l, i) => {
            const d = demoSeller(i);
            const label = sellers.length > 1 ? `Predávajúci č. ${String(i + 1).padStart(2, '0')}` : 'Predávajúci';
            return (
              <PartyBlock key={l.id} label={label} type={l.type || 'person'}
                onTypeChange={(t) => setSellerType(l.id, t)}
                onRemove={sellers.length > 1 ? () => removeSeller(l.id) : null}
                onDisplayChange={setSD(l.id)}
                demo={d} />
            );
          })}

          <div style={{ marginTop: 10, marginBottom: 4 }}>
            <button className="party-add party-add-left" onClick={addSeller} disabled={sellers.length >= 10}>+ Ďalší predávajúci</button>
          </div>

          <p className="party-alias">
            (ďalej len „<span className="party-alias-term">{P_N}</span>")
          </p>

          <p className="no-copy" style={{ textAlign: 'center', fontStyle: 'italic', color: 'var(--ink-3)', margin: '14px 0' }}>a</p>

          <p className="party-heading" style={{ fontWeight: 600, marginTop: 18, marginBottom: 10 }}>Kupujúci:</p>

          {buyers.map((t, i) => {
            const d = demoBuyer(i);
            const label = buyers.length > 1 ? `Kupujúci č. ${String(i + 1).padStart(2, '0')}` : 'Kupujúci';
            return (
              <PartyBlock key={t.id} label={label} type={t.type || 'person'}
                onTypeChange={(tp) => setBuyerType(t.id, tp)}
                onRemove={buyers.length > 1 ? () => removeBuyer(t.id) : null}
                onDisplayChange={setBD(t.id)}
                demo={d} />
            );
          })}

          <div style={{ marginTop: 10, marginBottom: 4 }}>
            <button className="party-add party-add-left" onClick={addBuyer} disabled={buyers.length >= 10}>+ Ďalší kupujúci</button>
          </div>

          <p className="party-alias">
            (ďalej len „<span className="party-alias-term">{K_N}</span>")
          </p>

          <p style={{ marginTop: 18, fontStyle: 'italic', color: 'var(--ink-3)', fontSize: 13 }}>
            (ďalej {P_N} a {K_N} spolu aj ako „<span style={{ color: 'var(--ink)' }}>Zmluvné strany</span>")
          </p>
        </section>

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

          <p className="has-tip">
            <TipBtn pointKey="2.1" />
            <strong>2.1</strong> &nbsp;{P_N} {P_VYH}, že {S ? 'sú výlučnými spoluvlastníkmi' : 'je výlučným vlastníkom'} nižšie špecifikovaného {VEH.gen} (ďalej len „<em>predmet kúpy</em>" alebo „<em>{VEH.lab}</em>").
          </p>

          <p className="has-tip">
            <TipBtn pointKey="2.2" />
            <strong>2.2</strong> &nbsp;Predmetom kúpy podľa tejto zmluvy je {VEH.nom} s nasledujúcimi identifikačnými údajmi:
          </p>
          <ul className="vehicle-spec" style={{ listStyle: 'none', paddingLeft: 24, margin: '6px 0 12px' }}>
            {VEHICLE_FIELDS[doctype].map((f, i) => (
              <li key={i}>
                {f.label}: <Ed defaultValue="" placeholder={f.placeholder}
                  lg={f.size === 'lg'} xl={f.size === 'xl'} num={f.num} />{f.suffix || ''}
              </li>
            ))}
          </ul>

          <p className="has-tip">
            <TipBtn pointKey="2.3" />
            <strong>2.3</strong> &nbsp;Spolu s predmetom kúpy {P_N} {P_OD2} {K_D} aj nasledujúce doklady a vybavenie:{' '}
            <Ed defaultValue="" placeholder={VEH.docsPlaceholder} xl />.
          </p>
        </section>

        {/* Čl. III — Kúpna cena a jej splatnosť */}
        <section className="article" id="art-3">
          <div className="article-head">
            <div className="article-num">Článok III</div>
            <span className="article-title">Kúpna cena a jej splatnosť</span>
          </div>

          <p className="has-tip">
            <TipBtn pointKey="3.1" />
            <strong>3.1</strong> &nbsp;Zmluvné strany sa dohodli na kúpnej cene predmetu kúpy vo výške{' '}
            <Ed defaultValue="" placeholder="napr. 12 500" num /> EUR (slovom:{' '}
            <Ed defaultValue="" placeholder="napr. dvanásťtisíc päťsto eur" xl />).
          </p>

          <p className="has-tip">
            <TipBtn pointKey="3.2" />
            <strong>3.2</strong> &nbsp;{K_N} sa zaväzuje zaplatiť kúpnu cenu{' '}
            <Ed select defaultValue="prevod" onValueChange={setPaymentMode} options={[
              { v: 'hotovost',    label: 'v hotovosti pri podpise zmluvy.' },
              { v: 'prevod',      label: 'bezhotovostným prevodom na účet predávajúceho.' },
              { v: 'kombinacia',  label: 'sčasti v hotovosti pri podpise a sčasti bezhotovostným prevodom na účet predávajúceho.' },
            ]} />
          </p>

          {paymentMode === 'hotovost' && (<>
            <p className="has-tip">
              <TipBtn pointKey="3.3-hotovost" />
              <strong>3.3</strong> &nbsp;Kúpna cena bola zaplatená v hotovosti k rukám {P_G} pri podpise tejto zmluvy. Podpisom tejto zmluvy {P_N} {P_POT} prevzatie kúpnej ceny v plnej výške podľa bodu 3.1 a tento bod nahrádza samostatný príjmový doklad.
            </p>
            <p className="has-tip">
              <TipBtn pointKey="3.4-hotovost-limit" />
              <strong>3.4</strong> &nbsp;Zmluvné strany berú na vedomie, že podľa zákona č. 394/2012 Z. z. je zakázané vykonať platbu v hotovosti prevyšujúcu 5 000 EUR, ak zákon neustanovuje inak; pri platbe medzi fyzickými osobami, ktoré nie sú podnikateľmi, je zákonný limit 15 000 EUR. Do limitu sa započítava aj súčet viacerých hotovostných platieb, ak vyplývajú z tejto zmluvy. Ak by hotovostná platba podľa tejto zmluvy prevyšovala príslušný zákonný limit, zmluvné strany sa zaväzujú uskutočniť ju bezhotovostným prevodom.
            </p>
          </>)}

          {paymentMode === 'prevod' && (<>
            <p className="has-tip">
              <TipBtn pointKey="3.3-prevod" />
              <strong>3.3</strong> &nbsp;Kúpna cena bude zaplatená bezhotovostným prevodom na bankový účet {P_G} uvedený v Čl. I tejto zmluvy, variabilný symbol:{' '}
              <Ed defaultValue="" placeholder="napr. VIN posledných 6 číslic" />.
            </p>
            <p className="has-tip">
              <TipBtn pointKey="3.4-prevod" />
              <strong>3.4</strong> &nbsp;Kúpna cena bude zaplatená{' '}
              <Ed select defaultValue="jednorazovo" onValueChange={setBankSchedule} options={[
                { v: 'jednorazovo',   label: 'jednorazovo, najneskôr do dňa odovzdania predmetu kúpy' },
                { v: 'mesacne',       label: 'v pravidelných mesačných splátkach' },
                { v: 'individualne',  label: 'podľa individuálneho splátkového kalendára dohodnutého nižšie' },
              ]} />
              {bankSchedule === 'jednorazovo' && (
                <>, najneskôr do <Ed defaultValue="" placeholder="DD. MM. RRRR" />.</>
              )}
              {bankSchedule === 'mesacne' && (
                <>. Výška mesačnej splátky je <Ed defaultValue="" placeholder="napr. 350" num /> EUR
                {' '}(slovom: <Ed defaultValue="" placeholder="napr. tristopäťdesiat eur" lg />),
                {' '}prvá splátka je splatná dňa <Ed defaultValue="" placeholder="DD. MM. RRRR" />,
                {' '}ďalšie splátky vždy do {' '}<Ed defaultValue="" placeholder="napr. 15." num />.{' '}dňa kalendárneho mesiaca, a to až do úplného zaplatenia kúpnej ceny.</>
              )}
              {bankSchedule === 'individualne' && (
                <>: <Ed defaultValue="" placeholder="podrobný splátkový kalendár — dátumy a sumy jednotlivých splátok" xl />.</>
              )}
            </p>
            {(bankSchedule === 'mesacne' || bankSchedule === 'individualne') && (
              <p className="has-tip">
                <TipBtn pointKey="3.5-splatky" />
                <strong>3.5</strong> &nbsp;Zmluvné strany sa dohodli, že omeškanie {K_G} so zaplatením čo i len jednej splátky o viac ako{' '}
                <Ed defaultValue="" placeholder="napr. 7" num /> dní spôsobuje stratu výhody splátok. Zostávajúca časť kúpnej ceny sa stáva splatnou v celom rozsahu, a to dňom nasledujúcim po uplynutí uvedenej lehoty.
              </p>
            )}
          </>)}

          {paymentMode === 'kombinacia' && (<>
            <p className="has-tip">
              <TipBtn pointKey="3.3-kombi" />
              <strong>3.3</strong> &nbsp;Časť kúpnej ceny vo výške <Ed defaultValue="" placeholder="napr. 5 000" num /> EUR{' '}
              (slovom: <Ed defaultValue="" placeholder="napr. päťtisíc eur" lg />){' '}bola zaplatená v hotovosti k rukám {P_G} pri podpise tejto zmluvy. Podpisom tejto zmluvy {P_N} {P_POT} prevzatie tejto sumy.
            </p>
            <p className="has-tip">
              <TipBtn pointKey="3.4-kombi-limit" />
              <strong>3.4</strong> &nbsp;Hotovostná časť kúpnej ceny podľa bodu 3.3 nesmie prevyšovať zákonný limit hotovostnej platby podľa zákona č. 394/2012 Z. z.; všeobecný limit je 5 000 EUR a pri platbe medzi fyzickými osobami, ktoré nie sú podnikateľmi, 15 000 EUR. Do limitu sa započítava aj súčet viacerých hotovostných platieb, ak vyplývajú z tejto zmluvy.
            </p>
            <p className="has-tip">
              <TipBtn pointKey="3.5-kombi" />
              <strong>3.5</strong> &nbsp;Zostávajúca časť kúpnej ceny vo výške <Ed defaultValue="" placeholder="napr. 7 500" num /> EUR{' '}
              (slovom: <Ed defaultValue="" placeholder="napr. sedemtisíc päťsto eur" lg />){' '}bude zaplatená bezhotovostným prevodom na účet {P_G} uvedený v Čl. I tejto zmluvy{' '}
              <Ed select defaultValue="jednorazovo" onValueChange={setComboSchedule} options={[
                { v: 'jednorazovo',  label: 'jednorazovo' },
                { v: 'mesacne',      label: 'v pravidelných mesačných splátkach' },
                { v: 'individualne', label: 'podľa individuálneho splátkového kalendára' },
              ]} />
              {comboSchedule === 'jednorazovo' && (
                <>, najneskôr do <Ed defaultValue="" placeholder="DD. MM. RRRR" />.</>
              )}
              {comboSchedule === 'mesacne' && (
                <>. Výška mesačnej splátky je <Ed defaultValue="" placeholder="napr. 250" num /> EUR
                {' '}(slovom: <Ed defaultValue="" placeholder="napr. dvestopäťdesiat eur" lg />),
                {' '}prvá splátka je splatná dňa <Ed defaultValue="" placeholder="DD. MM. RRRR" />,
                {' '}ďalšie splátky vždy do <Ed defaultValue="" placeholder="napr. 15." num />.{' '}dňa kalendárneho mesiaca, a to až do úplného zaplatenia.</>
              )}
              {comboSchedule === 'individualne' && (
                <>: <Ed defaultValue="" placeholder="podrobný splátkový kalendár" xl />.</>
              )}
            </p>
            {(comboSchedule === 'mesacne' || comboSchedule === 'individualne') && (
              <p className="has-tip">
                <TipBtn pointKey="3.5-splatky" />
                <strong>3.6</strong> &nbsp;Omeškanie {K_G} so zaplatením čo i len jednej splátky o viac ako{' '}
                <Ed defaultValue="" placeholder="napr. 7" num /> dní spôsobuje stratu výhody splátok a zostávajúca časť kúpnej ceny sa stáva splatnou v celom rozsahu.
              </p>
            )}
          </>)}

          {optionals['c-penalty'] && (
            <p className="has-tip">
              <TipBtn pointKey="3.x-pokuta" />
              <strong>{penaltyPoint}</strong> &nbsp;Pre prípad omeškania {K_G} so zaplatením kúpnej ceny alebo jej časti sa zmluvné strany dohodli na zmluvnej pokute vo výške{' '}
              <Ed defaultValue="0,05" placeholder="napr. 0,05" num /> % z dlžnej sumy za každý začatý deň omeškania. Tým nie je dotknuté právo {P_G} na náhradu škody a na úroky z omeškania v zákonnej výške.
            </p>
          )}
        </section>

        {/* Čl. IV — Odovzdanie predmetu kúpy */}
        <section className="article" id="art-4">
          <div className="article-head">
            <div className="article-num">Článok IV</div>
            <span className="article-title">Odovzdanie predmetu kúpy</span>
          </div>

          <p className="has-tip">
            <TipBtn pointKey="4.1" />
            <strong>4.1</strong> &nbsp;{P_N} {P_OD2} predmet kúpy {K_D}{' '}
            <Ed select defaultValue="priPodpise" onValueChange={setHandover} options={[
              { v: 'priPodpise', label: 'pri podpise tejto zmluvy.' },
              { v: 'neskor',     label: 'v lehote dohodnutej v bode 4.2 tejto zmluvy.' },
            ]} />
          </p>

          {handover === 'priPodpise' && (<>
            <p className="has-tip">
              <TipBtn pointKey="4.2-pri" />
              <strong>4.2</strong> &nbsp;Podpisom tejto zmluvy {P_N} {P_POT} odovzdanie a {K_N} {S || B ? 'potvrdzujú' : 'potvrdzuje'} prevzatie {VEH.gen} v stave zodpovedajúcom jeho identifikácii podľa Čl. II, vrátane všetkých dokladov a vybavenia uvedených v bodoch 2.2 a 2.3.
            </p>
            <p>
              <strong>4.3</strong> &nbsp;Miesto odovzdania: <Ed defaultValue="" placeholder="presná adresa odovzdania" xl />.
            </p>
          </>)}

          {handover === 'neskor' && (<>
            <p className="has-tip">
              <TipBtn pointKey="4.2-neskor" />
              <strong>4.2</strong> &nbsp;Predmet kúpy bude odovzdaný{' '}
              <Ed defaultValue="" placeholder={'DD. MM. RRRR alebo „do … dní od …"'} xl />,
              {' '}na adrese <Ed defaultValue="" placeholder="adresa odovzdania" xl />.
            </p>
            {optionals['c-protocol'] && (
              <p className="has-tip">
                <TipBtn pointKey="4.3-protokol" />
                <strong>4.3</strong> &nbsp;O odovzdaní a prevzatí predmetu kúpy zmluvné strany spíšu samostatný preberací protokol, ktorý bude obsahovať najmä stav počítadla kilometrov ku dňu odovzdania, fotodokumentáciu vonkajšieho aj vnútorného stavu vozidla, zoznam odovzdaných dokladov a kľúčov a prípadné výhrady {K_G} k stavu vozidla.
              </p>
            )}
          </>)}
        </section>

        {/* Čl. V — Prechod vlastníckeho práva */}
        <section className="article" id="art-5">
          <div className="article-head">
            <div className="article-num">Článok V</div>
            <span className="article-title">Prechod vlastníckeho práva</span>
          </div>
          <p className="has-tip">
            <TipBtn pointKey="5.1" />
            <strong>5.1</strong> &nbsp;Vlastnícke právo k predmetu kúpy prechádza z {P_G} na {K_G}{' '}
            <Ed select defaultValue="odovzdanim" onValueChange={setOwnership} options={[
              { v: 'odovzdanim',  label: 'okamihom odovzdania predmetu kúpy podľa Čl. IV tejto zmluvy.' },
              { v: 'prepisom',    label: 'okamihom zápisu zmeny držiteľa vozidla v evidencii vozidiel vedenej dopravným inšpektorátom.' },
              { v: 'zaplatenim',  label: 'okamihom úplného zaplatenia kúpnej ceny podľa Čl. III tejto zmluvy.' },
            ]} />
          </p>
          <p className="has-tip">
            <TipBtn pointKey="5.2" />
            <strong>5.2</strong> &nbsp;Nebezpečenstvo škody na predmete kúpy prechádza na {K_G} okamihom prevzatia predmetu kúpy podľa Čl. IV tejto zmluvy, a to bez ohľadu na okamih nadobudnutia vlastníckeho práva podľa bodu 5.1.
          </p>
        </section>

        {/* Čl. VI — Povinnosti a vyhlásenia predávajúceho */}
        <section className="article" id="art-6">
          <div className="article-head">
            <div className="article-num">Článok VI</div>
            <span className="article-title">Povinnosti a vyhlásenia predávajúceho</span>
          </div>

          <p className="has-tip">
            <TipBtn pointKey="6.1" />
            <strong>6.1</strong> &nbsp;{P_N} {P_VYH}, že:
          </p>
          <ul style={{ paddingLeft: 28, margin: '4px 0 12px' }}>
            <li>{S ? 'sú výlučnými spoluvlastníkmi' : 'je výlučným vlastníkom'} predmetu kúpy a {P_JE} {P_OPR} s ním nakladať bez akéhokoľvek obmedzenia;</li>
            <li>na predmete kúpy neviaznu žiadne dlhy, ťarchy, záložné práva, leasingové ani úverové vzťahy, predkupné ani iné vecné práva tretích osôb;</li>
            <li>predmet kúpy nie je predmetom prebiehajúceho exekučného, konkurzného alebo iného konania, ktoré by mohlo obmedziť alebo vylúčiť jeho prevod na {K_G};</li>
            <li>neuzatvoril žiadnu inú zmluvu, ktorá by obmedzovala alebo vylučovala prevod vlastníckeho práva k predmetu kúpy na {K_G};</li>
            <li>predmet kúpy nepochádza z trestnej činnosti, nie je vedený ako odcudzený a údaje uvedené v Čl. II zodpovedajú údajom v dokladoch o vozidle.</li>
          </ul>

          <p className="has-tip">
            <TipBtn pointKey="6.2" />
            <strong>6.2</strong> &nbsp;V prípade, ak sa ktorékoľvek vyhlásenie {P_G} podľa bodu 6.1 ukáže ako nepravdivé, neúplné alebo zavádzajúce, {K_N} {K_JE} {K_OPR} odstúpiť od tejto zmluvy s účinnosťou ku dňu doručenia oznámenia o odstúpení {P_D} a požadovať vrátenie zaplatenej kúpnej ceny v plnej výške, a to bez ohľadu na náhradu škody, ktorá mu vznikla.
          </p>
        </section>

        {/* Čl. VII — Prepis vozidla a vady predmetu kúpy */}
        <section className="article" id="art-7">
          <div className="article-head">
            <div className="article-num">Článok VII</div>
            <span className="article-title">Prepis vozidla a vady predmetu kúpy</span>
          </div>

          <p className="has-tip">
            <TipBtn pointKey="7.1" />
            <strong>7.1</strong> &nbsp;Zmluvné strany sa zaväzujú oznámiť zmenu držby a vlastníctva predmetu kúpy ktorémukoľvek orgánu Policajného zboru (dopravnému inšpektorátu) v súlade s § 117 zákona č. 8/2009 Z. z. o cestnej premávke najneskôr do{' '}
            <Ed select defaultValue="30" options={[
              { v: '15', label: '15' },
              { v: '20', label: '20' },
              { v: '30', label: '30' },
            ]} /> dní odo dňa uzatvorenia tejto zmluvy. Prepis sa vykoná{' '}
            <Ed select defaultValue="spolocne" onValueChange={setPrepisMode} options={[
              { v: 'spolocne',     label: 'osobne za prítomnosti oboch zmluvných strán na dopravnom inšpektoráte.' },
              { v: 'predavajuci',  label: 'osobne Predávajúcim na dopravnom inšpektoráte na základe písomného plnomocenstva Kupujúceho.' },
              { v: 'kupujuci',     label: 'osobne Kupujúcim na dopravnom inšpektoráte na základe tejto zmluvy s úradne osvedčenými podpismi.' },
              { v: 'elektronicky', label: 'elektronicky prostredníctvom služby Ministerstva vnútra SR (kvalifikovaným elektronickým podpisom).' },
            ]} />
          </p>

          {prepisMode === 'spolocne' && (
            <p className="has-tip">
              <TipBtn pointKey="7.2-spolocne" />
              <strong>7.2</strong> &nbsp;Pri spoločnej osobnej návšteve dopravného inšpektorátu {P_N} {P_OD2} polícii osvedčenie o evidencii časť I aj časť II a obe zmluvné strany preukážu svoju totožnosť. Polícia vykoná zápis zmeny držby a vlastníctva v evidencii vozidiel a vydá nové osvedčenie o evidencii časť I priamo na mieste.
            </p>
          )}

          {prepisMode === 'predavajuci' && (
            <p className="has-tip">
              <TipBtn pointKey="7.2-predavajuci" />
              <strong>7.2</strong> &nbsp;{K_N} {K_ZAV} odovzdať {P_D} pri podpise tejto zmluvy <strong>písomné plnomocenstvo s úradne osvedčeným podpisom</strong> oprávňujúce {P_G} k podaniu žiadosti o prepis vozidla v jeho mene; alternatívne {K_N} osvedčí svoj podpis priamo na jednom vyhotovení tejto zmluvy určenom pre dopravný inšpektorát. {P_N} pri podaní žiadosti predloží polícii osvedčenie o evidencii časť II (veľký technický preukaz). Polícia následne zašle nové osvedčenie o evidencii časť I aj časť II priamo na adresu {K_G} poštou.
            </p>
          )}

          {prepisMode === 'kupujuci' && (
            <p className="has-tip">
              <TipBtn pointKey="7.2-kupujuci" />
              <strong>7.2</strong> &nbsp;{P_N} {P_ZAV} odovzdať {K_D} pri podpise tejto zmluvy osvedčenie o evidencii časť II (veľký technický preukaz) a všetky ďalšie potrebné doklady. Zmluva bude vyhotovená s úradne osvedčenými podpismi oboch zmluvných strán. {K_N} pri podaní žiadosti o prepis predloží polícii túto zmluvu a osvedčenie o evidencii.
            </p>
          )}

          {prepisMode === 'elektronicky' && (
            <p className="has-tip">
              <TipBtn pointKey="7.2-elektronicky" />
              <strong>7.2</strong> &nbsp;Prepis bude podaný elektronicky cez portál Ministerstva vnútra SR (slovensko.sk). {K_N} udelí {P_D} <strong>elektronické plnomocenstvo</strong> podpísané kvalifikovaným elektronickým podpisom (KEP). Žiadosť o udelenie plnomocenstva je platná 5 pracovných dní od jej zaslania. Nové doklady (osvedčenie o evidencii časť I aj časť II) zašle polícia poštou priamo na adresu {K_G}.
            </p>
          )}

          <p className="has-tip">
            <TipBtn pointKey="7.3" />
            <strong>7.3</strong> &nbsp;Zmluvné strany sa dohodli, že tabuľky s evidenčným číslom vozidla{' '}
            <Ed select defaultValue="zachovat" onValueChange={setEvcMode} options={[
              { v: 'zachovat', label: 'zostávajú na vozidle a prechádzajú spolu s ním na Kupujúceho (štandardný postup podľa zák. č. 8/2009 Z. z.).' },
              { v: 'ponechat', label: 'si Predávajúci ponecháva; Predávajúci túto skutočnosť oznámi polícii pri prepise a polícia pridelí Kupujúcemu nové evidenčné číslo.' },
            ]} />
            {evcMode === 'ponechat' && (
              <> Nové tabuľky s evidenčným číslom zašle polícia spolu s dokladmi priamo na adresu {K_G} na Slovensku.</>
            )}
          </p>

          {optionals['c-warranty'] && (
            <p className="has-tip">
              <TipBtn pointKey="7.4" />
              <strong>7.4</strong> &nbsp;{K_N} {K_VYH}, že {B ? 'sa pred podpisom tejto zmluvy oboznámili' : 'sa pred podpisom tejto zmluvy oboznámil'} so stavom predmetu kúpy, vykonal jeho fyzickú aj funkčnú prehliadku (vrátane skúšobnej jazdy v primeranom rozsahu) a {B ? 'nemajú' : 'nemá'} k jeho stavu výhrady okrem prípadných vád výslovne uvedených v bode 7.5.
            </p>
          )}

          <p className="has-tip">
            <TipBtn pointKey="7.5" />
            <strong>7.5</strong> &nbsp;Zistené vady predmetu kúpy ku dňu uzatvorenia tejto zmluvy sú{' '}
            <Ed select defaultValue="bez" onValueChange={setDefects} options={[
              { v: 'bez', label: 'žiadne — predmet kúpy je bez zjavných vád.' },
              { v: 's',   label: 'nasledujúce — uvedené v zozname nižšie:' },
            ]} />
            {defects === 's' && (
              <><Ed defaultValue="" placeholder="podrobný opis vád, napr. odretý nárazník vpravo, opotrebené brzdové platničky, nefunkčný stierač zadného okna" block />.</>
            )}
          </p>

          <p className="has-tip">
            <TipBtn pointKey="7.6" />
            <strong>7.6</strong> &nbsp;Zodpovednosť za vady predmetu kúpy sa riadi príslušnými ustanoveniami Občianskeho zákonníka, najmä § 596 až § 600. {P_N} {P_VYH}, že mu nie sú známe žiadne skryté vady predmetu kúpy, ktoré by neuviedol v bode 7.5 a ktoré by bránili riadnemu užívaniu predmetu kúpy na obvyklý účel.
          </p>

          <p className="has-tip">
            <TipBtn pointKey="7.7" />
            <strong>7.7</strong> &nbsp;{K_N} {K_BOL} s tým, že predmet kúpy je vec použitá. Vlastnosti zodpovedajúce bežnému opotrebeniu primeranému veku, počtu najazdených kilometrov a spôsobu doterajšieho užívania sa nepovažujú za vady.
          </p>
        </section>

        {/* Čl. VIII — Záverečné ustanovenia */}
        <section className="article" id="art-8">
          <div className="article-head">
            <div className="article-num">Článok VIII</div>
            <span className="article-title">Záverečné ustanovenia</span>
          </div>

          <p className="has-tip">
            <TipBtn pointKey="8.1" />
            <strong>8.1</strong> &nbsp;Ak ku dňu, keď podľa bodu 5.1 tejto zmluvy malo prejsť vlastnícke právo k predmetu kúpy na {K_G}, k tomuto prechodu nedôjde, a tento stav trvá viac ako 30 dní, je strana, ktorá toto omeškanie nezavinila, oprávnená od tejto zmluvy odstúpiť.
          </p>

          <p className="has-tip">
            <TipBtn pointKey="8.2" />
            <strong>8.2</strong> &nbsp;Doručovanie. Písomnosti podľa tejto zmluvy sa doručujú na adresy zmluvných strán uvedené v Čl. I. Za riadne doručenú sa považuje aj zásielka, ktorá sa vrátila ako neprevzatá v odbernej lehote alebo s poznámkou „adresát neznámy" či „odsťahoval sa", a to dňom takéhoto vrátenia.
          </p>

          <p className="has-tip">
            <TipBtn pointKey="8.3" />
            <strong>8.3</strong> &nbsp;Zmluvné strany sa dohodli, že všetky spory (vrátane sporov o vady predmetu kúpy a o vrátenie kúpnej ceny), ktoré vzniknú z tejto zmluvy budú riešené (písomne a zrýchlenou formou) rozhodcom JUDr. Milanom Ficekom, advokátom, so sídlom: Žilinská 14, 81105 Bratislava ako vybranou osobou podľa § 6 ods. 3 zákona č. 244/2002 Z. z. o rozhodcovskom konaní a to podľa pravidiel zverejnených v Obchodnom vestníku pod č. 96/2016, značka: O000260 (t.j. pravidlá spoločnosti Rozhodcovské konanie SR s.r.o.). Rozhodcovské konanie bude vedené v súlade s právnymi predpismi SR.
          </p>

          <p>
            <strong>8.4</strong> &nbsp;Zmluvné strany sa dohodli, že táto zmluva sa vyhotovuje v dvoch rovnopisoch, pričom každá zo zmluvných strán obdrží po jednom rovnopise.
          </p>

          <p>
            <strong>8.5</strong> &nbsp;Táto zmluva nadobúda platnosť a účinnosť dňom jej podpisu oboma zmluvnými stranami. Akékoľvek zmeny a doplnenia tejto zmluvy je možné vykonať len písomnými dodatkami podpísanými oboma zmluvnými stranami.
          </p>

          <p>
            <strong>8.6</strong> &nbsp;Právne vzťahy neupravené touto zmluvou sa riadia príslušnými ustanoveniami zákona č. 40/1964 Zb. Občianskeho zákonníka a ďalšími všeobecne záväznými právnymi predpismi Slovenskej republiky.
          </p>

          <p>
            <strong>8.7</strong> &nbsp;Zmluvné strany vyhlasujú, že si zmluvu pred jej podpisom prečítali, jej obsahu porozumeli, prejavy ich vôle sú slobodné, vážne, určité a zrozumiteľné a že zmluvu uzatvárajú nie v tiesni a nie za nápadne nevýhodných podmienok. Na znak súhlasu s celým obsahom zmluvy pripájajú svoje vlastnoručné podpisy.
          </p>
        </section>

        {/* Signatures — replikované z najomnazmluva.sk */}
        <div className="signatures">
          <div className="sig-block">
            <div className="sig-cap">V <Ed defaultValue="Bratislave" placeholder="Mesto" />, dňa <Ed defaultValue="" placeholder="DD. MM. RRRR" /></div>
            {sellers.map((l, i) => {
              const nm = (sellerDisplay[l.id] || '').trim();
              return (
                <div className="sig-person" key={l.id}>
                  <div className="sig-line"></div>
                  <div className="sig-cap">{S ? `Predávajúci č. ${String(i + 1).padStart(2, '0')}` : 'Predávajúci'}</div>
                  <div className="sig-name">{nm || 'Meno a priezvisko'}</div>
                </div>
              );
            })}
          </div>
          <div className="sig-block">
            <div className="sig-cap">V <Ed defaultValue="Bratislave" placeholder="Mesto" />, dňa <Ed defaultValue="" placeholder="DD. MM. RRRR" /></div>
            {buyers.map((t, i) => {
              const nm = (buyerDisplay[t.id] || '').trim();
              return (
                <div className="sig-person" key={t.id}>
                  <div className="sig-line"></div>
                  <div className="sig-cap">{B ? `Kupujúci č. ${String(i + 1).padStart(2, '0')}` : 'Kupujúci'}</div>
                  <div className="sig-name">{nm || 'Meno a priezvisko'}</div>
                </div>
              );
            })}
          </div>
        </div>

        <div className="doc-footer-meta">
          <span>Vzor zmluvy pripravili advokáti z FICEK &amp; Partners</span>
          <span>Vzor je verejne prístupný na www.{window.SITE_NAME}</span>
          <span>v1.0 · Rev. máj 2026</span>
        </div>
      </article>

      <div className="paper-actions" role="group" aria-label="Akcie so zmluvou">
        <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 · v1.0</span>
          </button>
          {!__IS_MOBILE_DEVICE && (
            <button type="button" className="btn-download btn-download--ghost" data-export-word onClick={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 · v1.0</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">nevratná akcia</span>
          </button>
        </div>
        {__IS_MOBILE_DEVICE ? (
          <p className="paper-actions__note paper-actions__note--mobile" role="note" data-mobile-note>
            <span className="paper-actions__note-icon" aria-hidden="true">ⓘ</span>
            <span>Stiahnutie vo formáte Word je momentálne dostupné iba na počítači. Pre mobil odporúčame stiahnutie v PDF.</span>
          </p>
        ) : (
          <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 v LibreOffice a môžete zmluvu ďalej upraviť.
          </p>
        )}
      </div>
    </div>
  );
};

// -------------------------------------------------------------
// Word (.doc) export — serialize the <article.paper> DOM as a
// Word-compatible HTML document and trigger a download.
// Replikované z najomnazmluva.sk (s úpravami pre kúpnu zmluvu na auto):
// kloná article, strip-uje editovateľné chrome (inputs, selects, tip
// buttons, party add/remove), wrap-ne v Word HTML header s MSO namespaces.
// -------------------------------------------------------------
function downloadAsDoc() {
  const article = document.querySelector('article.paper');
  if (!article) return;

  // 0) Snapshot live <select> selections into the clone *before* any DOM
  //    mutation. Steps below remove elements (.tip-pin, .party-add, …) —
  //    that shifts every .children index, so a later position-based
  //    live↔clone mapping (findMatchingLiveElement) lands on a wrong
  //    <select>. cloneNode(true) preserves DOM order 1:1, so we pair
  //    selects by index and stamp each clone with its live `selectedIndex`.
  const liveSelects = Array.from(article.querySelectorAll('select.ed-select-native'));
  const clone = article.cloneNode(true);
  const cloneSelectsForSnap = clone.querySelectorAll('select.ed-select-native');
  cloneSelectsForSnap.forEach((cs, i) => {
    const live = liveSelects[i];
    if (live) cs.setAttribute('data-live-selected', String(live.selectedIndex));
  });

  // 1) Drop disabled optional clauses/articles completely (legacy z najom; v kza
  //    používame conditional React render, takže typicky tu nič nebude).
  clone.querySelectorAll('.article.optional.disabled, .optional-clause.disabled').forEach(el => el.remove());

  // 2) 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',
  ];
  clone.querySelectorAll(killSelectors.join(',')).forEach(el => el.remove());

  // 2a) Per-party UI bar (`.party-role`):
  //     Single party — remove entirely; the `.party-heading` paragraph above
  //       already says "Predávajúci:" / "Kupujúci:".
  //     Multi-party — keep the role label ("Predávajúci č. 01", "č. 02" …)
  //       as a legal separator; only strip the × remove button.
  clone.querySelectorAll('.party-role').forEach(role => {
    const labelEl = role.querySelector('.party-role-label');
    const labelText = labelEl ? (labelEl.textContent || '') : '';
    const isMulti = /č\.\s*\d/.test(labelText);
    if (!isMulti) {
      role.remove();
    } else {
      role.querySelectorAll('button.remove').forEach(b => b.remove());
    }
  });

  // 3) Replace <select.ed-select-native> with its selected option's label (plain text).
  clone.querySelectorAll('select.ed-select-native').forEach(sel => {
    const idx = parseInt(sel.getAttribute('data-live-selected') || '0', 10);
    const opts = sel.querySelectorAll('option');
    const picked = opts[idx] || opts[0];
    const label = picked ? (picked.textContent || '') : '';
    const span = document.createElement('span');
    span.textContent = label;
    sel.parentNode.replaceChild(span, sel);
  });

  // 4) Mirror spans for selects are redundant — step 3 already inserted the label.
  clone.querySelectorAll('.ed-select-print').forEach(el => el.remove());

  // 5) Turn contentEditable .ed spans into plain text
  clone.querySelectorAll('.ed').forEach(ed => {
    const text = ed.textContent || '';
    const span = document.createElement('span');
    span.textContent = text;
    ed.parentNode.replaceChild(span, ed);
  });

  // 5a) Word "justify-with-<br>" bug — split <p> at every top-level <br>
  //     so each segment becomes its own paragraph (justify leaves last lines alone).
  clone.querySelectorAll('p').forEach(p => {
    if (!Array.from(p.childNodes).some(n => n.nodeType === 1 && n.tagName === 'BR')) return;
    const groups = [[]];
    Array.from(p.childNodes).forEach(node => {
      if (node.nodeType === 1 && node.tagName === 'BR') groups.push([]);
      else groups[groups.length - 1].push(node);
    });
    const newParas = groups.map(g => {
      const np = document.createElement('p');
      for (const a of p.attributes) np.setAttribute(a.name, a.value);
      g.forEach(n => np.appendChild(n));
      return np;
    }).filter(np => np.textContent.trim().length > 0 || np.children.length > 0);
    if (newParas.length === 0) return;
    p.replaceWith(...newParas);
  });

  // 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.
  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 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, div.MsoFooter { margin: 0; padding: 0; text-align: left; font-family: "IBM Plex Mono", Consolas, monospace; font-size: 8pt; letter-spacing: 0.5pt; color: #777; }
    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 36pt; }
    .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; }
    ul { margin: 6pt 0 10pt 18pt; padding: 0; }
    ul li { margin: 0 0 4pt; }
    .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 { margin: 10pt 0 14pt; padding-left: 10pt; border-left: 2pt solid #0f1116; }
    .party-role { font-family: "IBM Plex Mono", Consolas, monospace; font-size: 9pt; letter-spacing: 1.5pt; text-transform: uppercase; color: #555; margin-bottom: 4pt; }
    .party-alias { font-style: italic; color: #555; margin-top: 6pt; font-size: 11pt; }
    .party-alias-term { font-style: normal; font-weight: 600; color: #0f1116; }
    .vehicle-spec { list-style: none; padding-left: 18pt; margin: 6pt 0 12pt; }
    .vehicle-spec li { margin: 0 0 3pt; }
  `;

  // 8) Compose the Word HTML shell
  const body = clone.outerHTML;
  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>Kúpna zmluva na motorové vozidlo</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>
<div style="mso-element:footer" id="f1">
  <p class="MsoFooter" align="left" style="text-align:left;">Vzor stiahnutý zadarmo z www.${window.SITE_NAME}</p>
</div>
</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 = 'kupna-zmluva-auto.doc';
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
  setTimeout(() => URL.revokeObjectURL(url), 1000);
}

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