// ============================================================
// SCREEN 5 · INVENTORY
// ============================================================

const POTION_TYPES = {
  '':           { label: 'Стандартне (2d4+2)',     kind: 'heal', dice: [2,4],  bonus: 2  },
  'greater':    { label: 'Потужне (4d4+4)',         kind: 'heal', dice: [4,4],  bonus: 4  },
  'superior':   { label: 'Видатне (8d4+8)',         kind: 'heal', dice: [8,4],  bonus: 8  },
  'supreme':    { label: 'Верховне (10d4+20)',      kind: 'heal', dice: [10,4], bonus: 20 },
  'slot':       { label: 'Чарунка (відновити 1)',   kind: 'slot' },
  'str_buff':   { label: 'Міць (STR 21 на 1 год.)', kind: 'stat', stat: 'STR', value: 21 },
  'dex_buff':   { label: 'Спритність (DEX 21)',     kind: 'stat', stat: 'DEX', value: 21 },
  'con_buff':   { label: 'Стійкість (CON 21)',      kind: 'stat', stat: 'CON', value: 21 },
};

const ScreenInventory = ({ ch, setCh, isAdmin, onConvertAllWeights }) => {
  const { push } = useToast();
  if (!ch) return null;
  const [filter, setFilter] = useState('Усі');
  const [addOpen, setAddOpen] = useState(false);
  const [newItem, setNewItem] = useState({ name: '', qty: 1, wt: 0, type: 'інше', equip: false, magic: false, note: '', potionType: '', capacity: 0 });
  const [editOpen, setEditOpen] = useState(false);
  const [editIdx, setEditIdx] = useState(null);
  const [editItem, setEditItem] = useState(null);
  const [expandedContainers, setExpandedContainers] = useState({});
  const [dragOverId, setDragOverId] = useState(null);       // _id контейнера (drop INTO)
  const [dragOverTarget, setDragOverTarget] = useState(null); // { id, above } для reorder

  // --- Inventory та currency живуть у ch (зберігаються в localStorage) ---
  const items = Array.isArray(ch.inventory) ? ch.inventory : [];
  const setItems = (updater) => setCh(c => ({
    ...c,
    inventory: typeof updater === 'function' ? updater(Array.isArray(c.inventory) ? c.inventory : []) : updater,
  }));

  const currency = ch.currency || CURRENCY.reduce((a, c) => ({ ...a, [c.k]: c.v }), {});
  const setCurrency = (updater) => setCh(c => ({
    ...c,
    currency: typeof updater === 'function' ? updater(c.currency || CURRENCY.reduce((a, x) => ({ ...a, [x.k]: x.v }), {})) : updater,
  }));

  // Draft state для currency — щоб не скидати до 0 поки користувач ще друкує
  const [currencyDraft, setCurrencyDraft] = useState({});
  const commitCurrency = (k, rawVal) => {
    const val = Math.max(0, parseInt(rawVal, 10) || 0);
    setCurrencyDraft(d => { const n = { ...d }; delete n[k]; return n; });
    setCurrency(s => ({ ...s, [k]: val }));
  };

  const TYPES = ['Усі', 'зброя', 'броня', 'зілля', 'свиток', 'контейнер', 'магічні', 'інше'];
  const filtered = filter === 'Усі' ? items
    : filter === 'магічні' ? items.filter(i => i.magic)
    : filter === 'інше' ? items.filter(i => !['зброя','броня','зілля','свиток','контейнер'].includes(i.type))
    : items.filter(i => i.type === filter);

  const totalWt = items.reduce((sum, i) => sum + (i.wt || 0) * (i.qty || 1), 0);
  const wtPct = (totalWt / ch.carryMax) * 100;
  const wtState = wtPct > 100 ? 'crit' : wtPct > 67 ? 'warn' : 'ok';

  // Парсить формулу типу "2d6+4", "1d4", "d8-1", "3d6"
  const parseFormula = (formula) => {
    if (!formula) return null;
    const m = String(formula).trim().match(/^(\d*)d(\d+)([+-]\d+)?$/i);
    if (!m) return null;
    return { numDice: parseInt(m[1]) || 1, die: parseInt(m[2]), bonus: parseInt(m[3]) || 0 };
  };

  const rollFormula = (formula) => {
    const p = parseFormula(formula);
    if (!p) return { total: 0, detail: '?' };
    const rolls = rollDice(p.numDice, p.die);
    const total = rolls.reduce((a, b) => a + b, 0) + p.bonus;
    return { total, detail: `${p.numDice}d${p.die}${p.bonus >= 0 ? '+' : ''}${p.bonus || ''}` };
  };

  const consumeItem = (c, item) => ({
    ...c,
    inventory: (Array.isArray(c.inventory) ? c.inventory : [])
      .map(i => (i._id && i._id === item._id) || i === item ? { ...i, qty: i.qty - 1 } : i)
      .filter(i => i.qty > 0),
  });

  const useItem = (item) => {
    if (item.action === 'drink') {
      // Кастомний ефект має пріоритет над типом зілля
      const ce = item.customEffect;
      if (ce) {
        if (ce.kind === 'heal') {
          // Підтримка формули (пріоритет) або окремих полів
          let heal, detail;
          if (ce.formula) {
            const r = rollFormula(ce.formula);
            heal = r.total; detail = r.detail;
          } else {
            const nd = ce.numDice ?? 2, die = ce.die ?? 4, bon = ce.bonus ?? 2;
            heal = rollDice(nd, die).reduce((a, b) => a + b, 0) + bon;
            detail = `${nd}d${die}${bon >= 0 ? '+' : ''}${bon || ''}`;
          }
          setCh(c => ({ ...consumeItem(c, item), hp: Math.min(c.hpMax, c.hp + heal) }));
          push({ icon: 'potion', label: item.name, value: `+${heal}`, detail });
        } else if (ce.kind === 'flat_heal') {
          const heal = ce.amount ?? 10;
          setCh(c => ({ ...consumeItem(c, item), hp: Math.min(c.hpMax, c.hp + heal) }));
          push({ icon: 'potion', label: item.name, value: `+${heal}`, detail: 'фікс.' });
        } else if (ce.kind === 'slot') {
          setCh(c => {
            const slots = { ...(c.spellSlots || {}) };
            const lvl = Object.keys(slots).map(Number).sort((a,b)=>a-b).find(l => (slots[l]?.used||0) > 0);
            if (lvl == null) { push({ label: '⚠ Всі чарунки повні' }); return c; }
            slots[lvl] = { ...slots[lvl], used: slots[lvl].used - 1 };
            push({ icon: 'spell', label: item.name, detail: `Чарунка ${lvl} рівня відновлена` });
            return { ...consumeItem(c, item), spellSlots: slots };
          });
        } else if (ce.kind === 'stat') {
          setCh(c => {
            const prev = (c.abilityScores || {})[ce.stat] ?? 10;
            const newVal = ce.mode === 'add' ? prev + (ce.value ?? 2) : Math.max(prev, ce.value ?? 21);
            const buff = { id: Math.random().toString(36).slice(2,8), name: item.name, stat: ce.stat, original: prev, ts: Date.now() };
            push({ icon: 'potion', label: item.name, detail: `${ce.stat} ${ce.mode === 'add' ? `+${ce.value ?? 2}` : `→ ${newVal}`} · зніми коли закінчиться` });
            return { ...consumeItem(c, item), abilityScores: { ...(c.abilityScores||{}), [ce.stat]: newVal }, activeBuffs: [...(c.activeBuffs||[]), buff] };
          });
        } else {
          setCh(c => consumeItem(c, item));
          push({ icon: 'potion', label: item.name, detail: item.note || 'ефект застосовано' });
        }
        return;
      }
      const pt = POTION_TYPES[item.potionType || ''] || POTION_TYPES[''];
      if (pt.kind === 'heal') {
        const heal = rollDice(...pt.dice).reduce((a, b) => a + b, 0) + pt.bonus;
        setCh(c => ({ ...consumeItem(c, item), hp: Math.min(c.hpMax, c.hp + heal) }));
        push({ icon: 'potion', label: item.name, value: `+${heal}`, detail: `${pt.dice[0]}d${pt.dice[1]}+${pt.bonus}` });
      } else if (pt.kind === 'slot') {
        setCh(c => {
          const slots = { ...(c.spellSlots || {}) };
          const lvl = Object.keys(slots).map(Number).sort((a,b)=>a-b).find(l => (slots[l]?.used||0) > 0);
          if (lvl == null) { push({ label: '⚠ Всі чарунки повні' }); return c; }
          slots[lvl] = { ...slots[lvl], used: slots[lvl].used - 1 };
          push({ icon: 'spell', label: item.name, detail: `Чарунка ${lvl} рівня відновлена` });
          return { ...consumeItem(c, item), spellSlots: slots };
        });
      } else if (pt.kind === 'stat') {
        setCh(c => {
          const prev = (c.abilityScores || {})[pt.stat] ?? 10;
          const newVal = Math.max(prev, pt.value);
          const buff = { id: Math.random().toString(36).slice(2,8), name: item.name, stat: pt.stat, original: prev, ts: Date.now() };
          push({ icon: 'potion', label: item.name, detail: `${pt.stat} → ${newVal} · зніми коли закінчиться` });
          return { ...consumeItem(c, item), abilityScores: { ...(c.abilityScores||{}), [pt.stat]: newVal }, activeBuffs: [...(c.activeBuffs||[]), buff] };
        });
      }
    } else if (item.action === 'scroll') {
      setCh(c => consumeItem(c, item));
      push({ icon: 'scroll', label: 'Свиток використано', detail: item.name });
    }
  };

  const openEdit = (it, idx) => { setEditItem({ ...it }); setEditIdx(idx); setEditOpen(true); };
  const saveEdit = () => {
    if (!editItem?.name?.trim()) return;
    // Призначаємо _id старим предметам при першому редагуванні
    const saved = { ...editItem, name: editItem.name.trim() };
    if (!saved._id) saved._id = Math.random().toString(36).slice(2, 10);
    setItems(its => its.map((x, i) => i === editIdx ? saved : x));
    setEditOpen(false);
    push({ label: `Збережено: ${saved.name}` });
  };

  const deleteItem = (item) => {
    setCh(c => ({
      ...c,
      inventory: (Array.isArray(c.inventory) ? c.inventory : []).filter(i => i !== item),
    }));
    push({ label: `Видалено: ${item.name}` });
  };

  const submitNewItem = () => {
    if (!newItem.name.trim()) return;
    const item = { ...newItem, name: newItem.name.trim(), _id: Math.random().toString(36).slice(2,10) };
    if (item.type !== 'контейнер') delete item.capacity;
    if (item.type !== 'зілля') delete item.potionType;
    // Зілля автоматично отримує дію "пити"
    if (item.type === 'зілля' && !item.action) item.action = 'drink';
    // Свитки автоматично отримують дію "scroll"
    if (item.type === 'свиток' && !item.action) item.action = 'scroll';
    setItems(its => [...its, item]);
    setNewItem({ name: '', qty: 1, wt: 0, type: 'інше', equip: false, magic: false, note: '', potionType: '', capacity: 0 });
    setAddOpen(false);
    push({ label: `Додано: ${newItem.name.trim()}` });
  };

  const totalGP = ((currency.PP||0)*10 + (currency.GP||0) + (currency.EP||0)*0.5 + (currency.SP||0)*0.1 + (currency.CP||0)*0.01).toFixed(2);

  const doShortRest = () => {
    const avail = ch.hitDiceTotal - (ch.hitDiceUsed || 0);
    if (avail <= 0) {
      push({ label: '⚠ Нема кубиків HP', detail: `Всі ${ch.hitDiceTotal}d${ch.hitDie} вичерпано` });
      return;
    }
    const conMod = Math.floor(((ch.abilityScores || {}).CON ?? 10) / 2) - 5;
    const roll = rollDie(ch.hitDie);
    const heal = Math.max(1, roll + conMod);
    setCh(c => ({
      ...c,
      hp: Math.min(c.hpMax, c.hp + heal),
      hitDiceUsed: (c.hitDiceUsed || 0) + 1,
    }));
    push({ icon: 'sun', label: 'Короткий відпочинок', value: `+${heal} HP`, detail: `d${ch.hitDie}[${roll}]${conMod >= 0 ? '+' : ''}${conMod} CON · залишилось ${avail - 1}/${ch.hitDiceTotal}` });
  };

  const potions = items.filter(i => i.action === 'drink');
  const scrolls = items.filter(i => i.type === 'свиток');

  return (
    <>
      <SectionHeader
        title="Інвентар"
        eyebrow={`${items.length} предметів · ${totalWt.toFixed(1)} / ${ch.carryMax} кг`}
        action={
          <div className="flex ig-6">
            {isAdmin && onConvertAllWeights && (
              <Btn ghost sm title="Конвертувати ваги всіх персонажів: фунти → кг (×0.454)" onClick={onConvertAllWeights}>
                ⚖ фунти→кг
              </Btn>
            )}
            <Btn primary sm onClick={() => setAddOpen(true)}><Icon name="plus" size={11}/> Предмет</Btn>
          </div>
        }
      />

      {/* Currency strip */}
      <Card className="mb-16" headClass="plain">
        <div className="currency-strip">
          {CURRENCY.map(c => (
            <div key={c.k} className={`currency-coin ${c.color}`}>
              <div className="coin-disk"><span>{c.k}</span></div>
              <input
                className="coin-input"
                type="number"
                min="0"
                value={currencyDraft[c.k] !== undefined ? currencyDraft[c.k] : (currency[c.k] ?? 0)}
                onChange={e => setCurrencyDraft(d => ({ ...d, [c.k]: e.target.value }))}
                onBlur={e => commitCurrency(c.k, e.target.value)}
                onKeyDown={e => e.key === 'Enter' && e.target.blur()}
                onWheel={e => e.target.blur()}
              />
              <div className="caps mono dim" style={{ fontSize: 9 }}>{c.name}</div>
            </div>
          ))}
          <div style={{ width: 1, alignSelf: 'stretch', background: 'var(--line-1)' }}/>
          <div className="currency-coin total">
            <div className="caps mono" style={{ fontSize: 9, color: 'var(--gold-0)' }}>Усього у ЗМ</div>
            <div className="display" style={{ fontSize: 28, color: 'var(--gold-1)' }}>{totalGP}</div>
          </div>
        </div>
      </Card>

      <div className="inventory-grid">
        {/* Items table */}
        <Card title="Речі" tag={`${filtered.length} показано`}
          action={
            <div className="flex ig-4 iwrap">
              {TYPES.map(t => <Chip key={t} active={filter === t} onClick={() => setFilter(t)}>{t}</Chip>)}
            </div>
          }>
          <div className="inv-row head">
            <div></div><div>Назва</div><div>×</div><div>Вага</div><div>Тип</div><div>Надіто</div><div></div>
          </div>
          {items.filter(i => filter === 'Усі' ? !i.containerId
              : filter === 'магічні' ? i.magic && !i.containerId
              : filter === 'інше' ? !['зброя','броня','зілля','свиток','контейнер'].includes(i.type) && !i.containerId
              : i.type === filter && !i.containerId
            ).map(it => {
              const realIdx = items.indexOf(it);
              const isContainer = it.type === 'контейнер';
              const isExpanded = !!expandedContainers[it._id];
              const children = isContainer && it._id ? items.filter(i => i.containerId === it._id) : [];
              const containerWt = children.reduce((s, c) => s + (c.wt||0)*(c.qty||1), 0);
              const isDragTarget = dragOverId === it._id;

              const renderItemRow = (row, rowIdx, indented, inContainer) => {
                const isReorderTarget = !!dragOverTarget && !!row._id && dragOverTarget.id === row._id;
                const isContainerTarget = dragOverId === row._id;
                return (
                <div key={row._id || rowIdx}
                  style={{ position: 'relative' }}
                  className={`inv-row${indented ? ' inv-row--child' : ''}${isContainerTarget ? ' inv-row--dragover' : ''}`}
                  draggable={!!row._id}
                  onDragStart={e => { e.dataTransfer.setData('text/plain', row._id); e.dataTransfer.effectAllowed = 'move'; }}
                  onDragOver={e => {
                    e.preventDefault(); e.stopPropagation();
                    if (row.type === 'контейнер' && row._id) {
                      setDragOverId(row._id);
                      setDragOverTarget(null);
                    } else if (row._id) {
                      setDragOverId(null);
                      const rect = e.currentTarget.getBoundingClientRect();
                      setDragOverTarget({ id: row._id, above: (e.clientY - rect.top) < rect.height / 2 });
                    }
                  }}
                  onDragLeave={e => { if (!e.currentTarget.contains(e.relatedTarget)) { setDragOverId(null); setDragOverTarget(null); } }}
                  onDrop={e => {
                    e.preventDefault();
                    const dragId = e.dataTransfer.getData('text/plain');
                    if (!dragId || dragId === row._id) { setDragOverId(null); setDragOverTarget(null); return; }
                    if (row.type === 'контейнер' && row._id) {
                      // Drop INTO container — перевіряємо ліміт
                      const draggedItem = items.find(x => x._id === dragId);
                      if (row.capacity > 0 && draggedItem) {
                        const currentWt = items.filter(i => i.containerId === row._id).reduce((s, i) => s + (i.wt||0)*(i.qty||1), 0);
                        const addWt = (draggedItem.wt||0) * (draggedItem.qty||1);
                        if (currentWt + addWt > row.capacity) {
                          push({ label: `⚠ Ліміт «${row.name}»`, detail: `${(currentWt+addWt).toFixed(1)} > ${row.capacity} кг` });
                          setDragOverId(null); setDragOverTarget(null); return;
                        }
                      }
                      setItems(its => its.map(x => x._id === dragId ? { ...x, containerId: row._id } : x));
                      setExpandedContainers(ec => ({ ...ec, [row._id]: true }));
                      push({ label: `Переміщено до «${row.name}»` });
                    } else {
                      // Reorder + extract from container
                      const above = dragOverTarget?.above ?? true;
                      setItems(its => {
                        const arr = [...its];
                        const fromIdx = arr.findIndex(x => x._id === dragId);
                        if (fromIdx === -1) return its;
                        const [moved] = arr.splice(fromIdx, 1);
                        const updatedMoved = { ...moved, containerId: undefined };
                        const toIdx = arr.findIndex(x => x._id === row._id);
                        if (toIdx === -1) return [...arr, updatedMoved];
                        arr.splice(above ? toIdx : toIdx + 1, 0, updatedMoved);
                        return arr;
                      });
                    }
                    setDragOverId(null); setDragOverTarget(null);
                  }}>
                  {/* Лінія-індикатор перестановки */}
                  {isReorderTarget && <div style={{ position:'absolute', left:0, right:0, height:2, background:'var(--gold-1)', zIndex:10, top: dragOverTarget.above ? 0 : 'auto', bottom: dragOverTarget.above ? 'auto' : 0 }}/>}
                  <div className="inv-icon"
                    style={{ cursor: row.type === 'контейнер' ? 'pointer' : 'default' }}
                    onClick={row.type === 'контейнер' && row._id
                      ? () => setExpandedContainers(ec => ({ ...ec, [row._id]: !ec[row._id] }))
                      : undefined}>
                    {row.type === 'зброя' && <Icon name="sword" size={14}/>}
                    {row.type === 'броня' && <Icon name="shield" size={14}/>}
                    {row.type === 'зілля' && <Icon name="potion" size={14}/>}
                    {row.type === 'свиток' && <Icon name="scroll" size={14}/>}
                    {row.type === 'контейнер' && <span style={{ fontSize: 11, userSelect: 'none' }}>{!!expandedContainers[row._id] ? '▾' : '▸'} <span style={{fontSize:12}}>🎒</span></span>}
                    {!['зброя','броня','зілля','свиток','контейнер'].includes(row.type) && <Icon name="bag" size={14}/>}
                  </div>
                  <div className="icol ig-2">
                    <div className="flex ica ig-6">
                      <span style={{ fontWeight: 600 }}>{row.name}</span>
                      {row.magic && <Chip sm color="violet" fill>магіч.</Chip>}
                    </div>
                    {row.type === 'контейнер' && row.capacity > 0 && (() => {
                      const pct = Math.min(100, (containerWt / row.capacity) * 100);
                      const over = containerWt > row.capacity;
                      return (
                        <div style={{ display:'flex', alignItems:'center', gap:6 }}>
                          <div style={{ flex:1, height:4, background:'var(--bg-2)', borderRadius:2, overflow:'hidden' }}>
                            <div style={{ width:`${pct}%`, height:'100%', background: over ? 'var(--crimson-1)' : 'var(--gold-1)', borderRadius:2, transition:'width 0.2s' }}/>
                          </div>
                          <span className="mono" style={{ fontSize:10, color: over ? 'var(--crimson-1)' : 'var(--ink-3)', whiteSpace:'nowrap' }}>
                            {containerWt.toFixed(1)}/{row.capacity} кг
                          </span>
                        </div>
                      );
                    })()}
                    {row.note && <div className="mono" style={{ fontSize: 10, color: 'var(--ink-3)', maxWidth: 260, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{row.note}</div>}
                  </div>
                  <div className="display" style={{ fontSize: 14 }}>
                    <button style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'var(--ink-3)', padding: '0 2px' }}
                      onClick={() => setItems(its => its.map((x, i) => i === rowIdx ? { ...x, qty: Math.max(1, x.qty - 1) } : x))}>−</button>
                    {row.qty}
                    <button style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'var(--ink-3)', padding: '0 2px' }}
                      onClick={() => setItems(its => its.map((x, i) => i === rowIdx ? { ...x, qty: x.qty + 1 } : x))}>+</button>
                  </div>
                  <div className="mono dim" style={{ fontSize: 11 }}>{((row.wt||0)*(row.qty||1)).toFixed(1)} кг</div>
                  <div className="mono dim" style={{ fontSize: 11 }}>{row.type}</div>
                  <div>
                    <Dot color="emerald" on={row.equip}
                      onClick={() => setItems(its => its.map((x, i) => i === rowIdx ? { ...x, equip: !x.equip } : x))}/>
                  </div>
                  <div className="flex ig-4" style={{ justifyContent: 'flex-end' }}>
                    {row.action && <Btn sm onClick={() => useItem(row)}>{row.action === 'drink' ? 'пити' : 'каст'}</Btn>}
                    {inContainer && <IconBtn name="x" size={11} title="Вийняти з сумки" onClick={() => setItems(its => its.map(x => x._id === row._id ? { ...x, containerId: undefined } : x))}/>}
                    <IconBtn name="edit" size={12} title="Редагувати" onClick={() => openEdit(row, rowIdx)}/>
                    <IconBtn name="trash" size={12} title="Видалити" onClick={() => deleteItem(row)}/>
                  </div>
                </div>
                );
              };

              return (
                <React.Fragment key={it._id || realIdx}>
                  {renderItemRow(it, realIdx, false, false)}
                  {isContainer && isExpanded && children.map(child => renderItemRow(child, items.indexOf(child), true, true))}
                  {isContainer && isExpanded && children.length === 0 && (
                    <div className={`inv-row inv-row--child inv-row--empty${isDragTarget ? ' inv-row--dragover' : ''}`}
                      onDragOver={e => { e.preventDefault(); setDragOverId(it._id); }}
                      onDragLeave={() => setDragOverId(d => d === it._id ? null : d)}
                      onDrop={e => {
                        e.preventDefault();
                        const dragId = e.dataTransfer.getData('text/plain');
                        if (!dragId) { setDragOverId(null); return; }
                        setItems(its => its.map(x => x._id === dragId ? { ...x, containerId: it._id } : x));
                        setDragOverId(null);
                      }}>
                      <span className="mono dim" style={{ fontSize: 11, gridColumn: '1/-1' }}>Перетягни предмет сюди…</span>
                    </div>
                  )}
                </React.Fragment>
              );
            })}
          {items.filter(i => filter === 'Усі' ? !i.containerId : i.type === filter && !i.containerId).length === 0 && (
            <div className="mono dim" style={{ textAlign: 'center', padding: '16px 0', fontSize: 12 }}>Нічого не знайдено</div>
          )}
        </Card>

        <div className="icol ig-16">
          {/* Weight */}
          <Card title="Навантаження">
            <div className="flex iba ija mb-6">
              <span className="display" style={{ fontSize: 32, color: wtState === 'crit' ? 'var(--crimson-1)' : wtState === 'warn' ? '#e0a050' : 'var(--ink-0)' }}>{totalWt.toFixed(1)}</span>
              <span className="mono dim" style={{ fontSize: 12 }}>/ {ch.carryMax} кг</span>
            </div>
            <Bar pct={wtPct} color={wtState === 'crit' ? 'crimson' : wtState === 'warn' ? '' : 'emerald'} lg/>
            <div className="mono dim mt-8" style={{ fontSize: 10, lineHeight: 1.6 }}>
              {(() => {
                const light = Math.round(ch.carryMax / 3);
                const heavy = Math.round(ch.carryMax * 2 / 3);
                return <>
                  · 0–{light} кг: норма<br/>
                  · {light}–{heavy} кг: <span style={{ color: '#e0a050' }}>обтяження (–10 швид.)</span><br/>
                  · {heavy}+ кг: <span style={{ color: 'var(--crimson-1)' }}>важке обт. (–20 швид.)</span>
                </>;
              })()}
            </div>
          </Card>

          {/* Quick actions */}
          <Card title="Швидкі дії" tag="з інвентаря">
            <div className="icol ig-6">
              {potions.length > 0
                ? potions.map(p => (
                    <Btn key={p.name} onClick={() => useItem(p)}>
                      <Icon name="potion" size={14}/> Пити: {p.name} ×{p.qty}
                    </Btn>
                  ))
                : <span className="mono dim" style={{ fontSize: 11 }}>Немає зілля</span>
              }
              {scrolls.length > 0
                ? scrolls.map(s => (
                    <Btn key={s.name} ghost sm onClick={() => useItem({ ...s, action: 'scroll' })}>
                      <Icon name="scroll" size={12}/> {s.name}
                    </Btn>
                  ))
                : <span className="mono dim" style={{ fontSize: 11 }}>Немає свитків</span>
              }
              <Btn ghost sm onClick={doShortRest}>
                <Icon name="sun" size={12}/> Короткий відпочинок <span className="mono dim" style={{ fontSize: 10, marginLeft: 4 }}>{ch.hitDiceTotal - (ch.hitDiceUsed || 0)}d{ch.hitDie}</span>
              </Btn>
            </div>
          </Card>

          {/* Активні ефекти (статові бафи) */}
          {(ch.activeBuffs || []).length > 0 && (
            <Card title="Активні ефекти" tag={`${ch.activeBuffs.length}`}>
              <div className="icol ig-6">
                {(ch.activeBuffs || []).map(buff => (
                  <div key={buff.id} className="flex ica ig-8" style={{ fontSize: 12, padding: '4px 0', borderBottom: '1px solid var(--line-2)' }}>
                    <Icon name="potion" size={13} style={{ color: 'var(--gold-1)', flexShrink: 0 }}/>
                    <div className="igrow">
                      <span style={{ fontWeight: 600 }}>{buff.name}</span>
                      <span className="mono dim" style={{ fontSize: 10, marginLeft: 6 }}>{buff.stat} (було {buff.original})</span>
                    </div>
                    <Btn sm ghost onClick={() => setCh(c => ({
                      ...c,
                      abilityScores: { ...(c.abilityScores||{}), [buff.stat]: buff.original },
                      activeBuffs: (c.activeBuffs||[]).filter(b => b.id !== buff.id),
                    }))}>
                      Зняти
                    </Btn>
                  </div>
                ))}
              </div>
            </Card>
          )}
        </div>
      </div>

      {/* ===== MODAL: Редагувати предмет ===== */}
      {editOpen && editItem && (
        <div className="dice-overlay-backdrop" onClick={() => setEditOpen(false)}>
          <div className="dice-overlay" style={{ width: 480, minHeight: 460 }} onClick={e => e.stopPropagation()}>
            <div className="dice-overlay-head">
              <Icon name="edit" size={18} style={{ color: 'var(--gold-1)' }}/>
              <h2>Редагувати предмет</h2>
              <div className="igrow"/>
              <IconBtn name="x" onClick={() => setEditOpen(false)}/>
            </div>
            <div className="dice-overlay-body">
              <div className="icol ig-12">
                <div className="flex ig-8">
                  <div className="igrow">
                    <div className="field-label mb-4">Назва *</div>
                    <input className="input" autoFocus value={editItem.name}
                      onChange={e => setEditItem(v => ({ ...v, name: e.target.value }))}
                      onKeyDown={e => e.key === 'Enter' && saveEdit()}/>
                  </div>
                  <div style={{ width: 70 }}>
                    <div className="field-label mb-4">К-сть</div>
                    <input className="input" type="number" min="1" value={editItem.qty}
                      onChange={e => setEditItem(v => ({ ...v, qty: Math.max(1, Number(e.target.value)||1) }))}/>
                  </div>
                  <div style={{ width: 80 }}>
                    <div className="field-label mb-4">Вага (кг)</div>
                    <input className="input" type="number" min="0" step="0.1" value={editItem.wt}
                      onChange={e => setEditItem(v => ({ ...v, wt: Number(e.target.value)||0 }))}/>
                  </div>
                </div>
                <div className="flex ig-8">
                  <div className="igrow">
                    <div className="field-label mb-4">Тип</div>
                    <select className="input" value={editItem.type}
                      onChange={e => setEditItem(v => ({ ...v, type: e.target.value }))}>
                      {['зброя','броня','зілля','свиток','контейнер','магічні','інше'].map(t => <option key={t}>{t}</option>)}
                    </select>
                  </div>
                  {editItem.type === 'контейнер' ? (
                    <div style={{ width: 100 }}>
                      <div className="field-label mb-4">Ліміт (кг)</div>
                      <input className="input" type="number" min="0" step="0.5" value={editItem.capacity||0}
                        onChange={e => setEditItem(v => ({ ...v, capacity: Number(e.target.value)||0 }))}/>
                    </div>
                  ) : (
                    <div style={{ width: 90 }}>
                      <div className="field-label mb-4">Дія</div>
                      <select className="input" value={editItem.action || ''}
                        onChange={e => setEditItem(v => ({ ...v, action: e.target.value || undefined }))}>
                        <option value="">—</option>
                        <option value="drink">пити</option>
                        <option value="scroll">свиток</option>
                      </select>
                    </div>
                  )}
                  <div style={{ display:'flex', flexDirection:'column', gap:4, justifyContent:'flex-end' }}>
                    <label className="flex ica ig-6" style={{ cursor:'pointer', fontSize:12 }}>
                      <input type="checkbox" checked={!!editItem.equip}
                        onChange={e => setEditItem(v => ({ ...v, equip: e.target.checked }))}/>
                      Надіто
                    </label>
                    <label className="flex ica ig-6" style={{ cursor:'pointer', fontSize:12 }}>
                      <input type="checkbox" checked={!!editItem.magic}
                        onChange={e => setEditItem(v => ({ ...v, magic: e.target.checked }))}/>
                      Магічний
                    </label>
                  </div>
                </div>
                {editItem.type === 'зілля' && (
                  <div>
                    <div className="field-label mb-4">Тип зілля</div>
                    <select className="input" value={editItem.potionType || ''}
                      onChange={e => setEditItem(v => ({ ...v, potionType: e.target.value }))}>
                      {Object.entries(POTION_TYPES).map(([k, v]) => <option key={k} value={k}>{v.label}</option>)}
                    </select>
                  </div>
                )}
                {items.filter(i => i.type === 'контейнер').length > 0 && editItem.type !== 'контейнер' && (
                  <div>
                    <div className="field-label mb-4">У сумці</div>
                    <select className="input" value={editItem.containerId || ''}
                      onChange={e => setEditItem(v => ({ ...v, containerId: e.target.value || undefined }))}>
                      <option value="">— без сумки —</option>
                      {items.filter(i => i.type === 'контейнер' && i._id).map(c => (
                        <option key={c._id} value={c._id}>{c.name}</option>
                      ))}
                    </select>
                  </div>
                )}
                <div>
                  <div className="field-label mb-4">Нотатка</div>
                  <input className="input" placeholder="опис, де знайшли, властивості…"
                    value={editItem.note || ''}
                    onChange={e => setEditItem(v => ({ ...v, note: e.target.value }))}/>
                </div>
                {isAdmin && editItem.type === 'зілля' && (
                  <div style={{ background: 'var(--bg-1)', border: '1px solid var(--line-1)', borderRadius: 6, padding: '10px 12px' }}>
                    <div className="field-label mb-8" style={{ color: 'var(--gold-0)' }}>⚗ Кастомний ефект (адмін)</div>
                    <div className="flex ig-8 mb-8">
                      <div className="igrow">
                        <div className="field-label mb-4">Вид ефекту</div>
                        <select className="input" value={editItem.customEffect?.kind || 'heal'}
                          onChange={e => setEditItem(v => ({ ...v, customEffect: { ...(v.customEffect||{}), kind: e.target.value } }))}>
                          <option value="heal">Лікування (кубики)</option>
                          <option value="flat_heal">Лікування (фіксоване)</option>
                          <option value="slot">Відновити чарунку</option>
                          <option value="stat">Стат (тимчасово)</option>
                          <option value="note_only">Тільки нотатка/опис</option>
                        </select>
                      </div>
                    </div>
                    {(editItem.customEffect?.kind === 'heal' || !editItem.customEffect?.kind) && (
                      <div>
                        <div className="field-label mb-4">Формула <span className="mono dim" style={{fontSize:10}}>напр. 2d6+4 · 1d4 · 3d8-1</span></div>
                        <input className="input" placeholder="2d4+2"
                          value={editItem.customEffect?.formula ?? ''}
                          onChange={e => setEditItem(v => ({ ...v, customEffect: { ...(v.customEffect||{}), formula: e.target.value } }))}/>
                        {editItem.customEffect?.formula && !parseFormula(editItem.customEffect.formula) && (
                          <div className="mono" style={{fontSize:10,color:'var(--crimson-1)',marginTop:3}}>⚠ Невірний формат. Приклад: 2d6+3</div>
                        )}
                      </div>
                    )}
                    {editItem.customEffect?.kind === 'flat_heal' && (
                      <div style={{ width: 100 }}>
                        <div className="field-label mb-4">HP</div>
                        <input className="input" type="number" min="1"
                          value={editItem.customEffect?.amount ?? 10}
                          onChange={e => setEditItem(v => ({ ...v, customEffect: { ...(v.customEffect||{}), amount: Number(e.target.value)||1 } }))}/>
                      </div>
                    )}
                    {editItem.customEffect?.kind === 'stat' && (
                      <div className="flex ig-8 iwrap">
                        <div style={{ width: 90 }}>
                          <div className="field-label mb-4">Характ.</div>
                          <select className="input" value={editItem.customEffect?.stat || 'STR'}
                            onChange={e => setEditItem(v => ({ ...v, customEffect: { ...(v.customEffect||{}), stat: e.target.value } }))}>
                            {['STR','DEX','CON','INT','WIS','CHA'].map(s => <option key={s}>{s}</option>)}
                          </select>
                        </div>
                        <div style={{ width: 90 }}>
                          <div className="field-label mb-4">Режим</div>
                          <select className="input" value={editItem.customEffect?.mode || 'set'}
                            onChange={e => setEditItem(v => ({ ...v, customEffect: { ...(v.customEffect||{}), mode: e.target.value } }))}>
                            <option value="set">= встановити</option>
                            <option value="add">+ додати</option>
                          </select>
                        </div>
                        <div style={{ width: 80 }}>
                          <div className="field-label mb-4">{editItem.customEffect?.mode === 'add' ? '+N' : 'Значення'}</div>
                          <input className="input" type="number" min="1" max="30"
                            value={editItem.customEffect?.value ?? (editItem.customEffect?.mode === 'add' ? 2 : 21)}
                            onChange={e => setEditItem(v => ({ ...v, customEffect: { ...(v.customEffect||{}), value: Number(e.target.value)||1 } }))}/>
                        </div>
                      </div>
                    )}
                  </div>
                )}
                {isAdmin && (
                  <div className="flex ica ig-8" style={{ opacity: 0.6 }}>
                    <span className="mono" style={{ fontSize: 10 }}>ID: {editItem._id || '—'}</span>
                    {editItem._id && (
                      <button style={{ background:'none', border:'none', cursor:'pointer', fontSize:10, color:'var(--gold-0)', padding:0 }}
                        onClick={() => { navigator.clipboard.writeText(editItem._id); push({ label: 'ID скопійовано' }); }}>
                        📋
                      </button>
                    )}
                  </div>
                )}
                <div className="flex ig-8 mt-4">
                  <Btn primary onClick={saveEdit}><Icon name="check" size={12}/> Зберегти</Btn>
                  <Btn ghost onClick={() => setEditOpen(false)}>Скасувати</Btn>
                </div>
              </div>
            </div>
          </div>
        </div>
      )}

      {/* ===== MODAL: Додати предмет ===== */}
      {addOpen && (
        <div className="dice-overlay-backdrop" onClick={() => setAddOpen(false)}>
          <div className="dice-overlay" style={{ width: 480, minHeight: 460 }} onClick={e => e.stopPropagation()}>
            <div className="dice-overlay-head">
              <Icon name="bag" size={18} style={{ color: 'var(--gold-1)' }}/>
              <h2>Новий предмет</h2>
              <div className="igrow"/>
              <IconBtn name="x" onClick={() => setAddOpen(false)}/>
            </div>
            <div className="dice-overlay-body">
              <div className="icol ig-12">
                <div className="flex ig-8">
                  <div className="igrow">
                    <div className="field-label mb-4">Назва *</div>
                    <input className="input" placeholder="Зілля лікування" autoFocus
                      value={newItem.name}
                      onChange={e => setNewItem(v => ({ ...v, name: e.target.value }))}
                      onKeyDown={e => e.key === 'Enter' && submitNewItem()}/>
                  </div>
                  <div style={{ width: 70 }}>
                    <div className="field-label mb-4">К-сть</div>
                    <input className="input" type="number" min="1" value={newItem.qty}
                      onChange={e => setNewItem(v => ({ ...v, qty: Math.max(1, Number(e.target.value)||1) }))}/>
                  </div>
                  <div style={{ width: 80 }}>
                    <div className="field-label mb-4">Вага (кг)</div>
                    <input className="input" type="number" min="0" step="0.1" value={newItem.wt}
                      onChange={e => setNewItem(v => ({ ...v, wt: Number(e.target.value)||0 }))}/>
                  </div>
                </div>
                <div className="flex ig-8">
                  <div className="igrow">
                    <div className="field-label mb-4">Тип</div>
                    <select className="input" value={newItem.type}
                      onChange={e => setNewItem(v => ({ ...v, type: e.target.value }))}>
                      {['зброя','броня','зілля','свиток','контейнер','магічні','інше'].map(t => <option key={t}>{t}</option>)}
                    </select>
                  </div>
                  {newItem.type === 'контейнер' ? (
                    <div style={{ width: 100 }}>
                      <div className="field-label mb-4">Ліміт (кг)</div>
                      <input className="input" type="number" min="0" step="0.5" value={newItem.capacity}
                        onChange={e => setNewItem(v => ({ ...v, capacity: Number(e.target.value)||0 }))}/>
                    </div>
                  ) : (
                    <div style={{ width: 90 }}>
                      <div className="field-label mb-4">Дія</div>
                      <select className="input" value={newItem.action || ''}
                        onChange={e => setNewItem(v => ({ ...v, action: e.target.value || undefined }))}>
                        <option value="">—</option>
                        <option value="drink">пити</option>
                        <option value="scroll">свиток</option>
                      </select>
                    </div>
                  )}
                  <div style={{ display:'flex', flexDirection:'column', gap:4, justifyContent:'flex-end' }}>
                    <label className="flex ica ig-6" style={{ cursor:'pointer', fontSize:12 }}>
                      <input type="checkbox" checked={newItem.equip}
                        onChange={e => setNewItem(v => ({ ...v, equip: e.target.checked }))}/>
                      Надіто
                    </label>
                    <label className="flex ica ig-6" style={{ cursor:'pointer', fontSize:12 }}>
                      <input type="checkbox" checked={newItem.magic}
                        onChange={e => setNewItem(v => ({ ...v, magic: e.target.checked }))}/>
                      Магічний
                    </label>
                  </div>
                </div>
                {newItem.type === 'зілля' && (
                  <div>
                    <div className="field-label mb-4">Тип зілля</div>
                    <select className="input" value={newItem.potionType || ''}
                      onChange={e => setNewItem(v => ({ ...v, potionType: e.target.value }))}>
                      {Object.entries(POTION_TYPES).map(([k, v]) => <option key={k} value={k}>{v.label}</option>)}
                    </select>
                  </div>
                )}
                {isAdmin && newItem.type === 'зілля' && (
                  <div style={{ background: 'var(--bg-1)', border: '1px solid var(--line-1)', borderRadius: 6, padding: '10px 12px' }}>
                    <div className="field-label mb-8" style={{ color: 'var(--gold-0)' }}>⚗ Кастомний ефект (адмін)</div>
                    <div className="flex ig-8 mb-8">
                      <div className="igrow">
                        <div className="field-label mb-4">Вид ефекту</div>
                        <select className="input" value={newItem.customEffect?.kind || 'heal'}
                          onChange={e => setNewItem(v => ({ ...v, customEffect: { ...(v.customEffect||{}), kind: e.target.value } }))}>
                          <option value="heal">Лікування (кубики)</option>
                          <option value="flat_heal">Лікування (фіксоване)</option>
                          <option value="slot">Відновити чарунку</option>
                          <option value="stat">Стат (тимчасово)</option>
                          <option value="note_only">Тільки нотатка/опис</option>
                        </select>
                      </div>
                    </div>
                    {(newItem.customEffect?.kind === 'heal' || !newItem.customEffect?.kind) && (
                      <div>
                        <div className="field-label mb-4">Формула <span className="mono dim" style={{fontSize:10}}>напр. 2d6+4 · 1d4 · 3d8-1</span></div>
                        <input className="input" placeholder="2d4+2"
                          value={newItem.customEffect?.formula ?? ''}
                          onChange={e => setNewItem(v => ({ ...v, customEffect: { ...(v.customEffect||{}), formula: e.target.value } }))}/>
                        {newItem.customEffect?.formula && !parseFormula(newItem.customEffect.formula) && (
                          <div className="mono" style={{fontSize:10,color:'var(--crimson-1)',marginTop:3}}>⚠ Невірний формат. Приклад: 2d6+3</div>
                        )}
                      </div>
                    )}
                    {newItem.customEffect?.kind === 'flat_heal' && (
                      <div style={{ width: 100 }}>
                        <div className="field-label mb-4">HP</div>
                        <input className="input" type="number" min="1"
                          value={newItem.customEffect?.amount ?? 10}
                          onChange={e => setNewItem(v => ({ ...v, customEffect: { ...(v.customEffect||{}), amount: Number(e.target.value)||1 } }))}/>
                      </div>
                    )}
                    {newItem.customEffect?.kind === 'stat' && (
                      <div className="flex ig-8 iwrap">
                        <div style={{ width: 90 }}>
                          <div className="field-label mb-4">Характ.</div>
                          <select className="input" value={newItem.customEffect?.stat || 'STR'}
                            onChange={e => setNewItem(v => ({ ...v, customEffect: { ...(v.customEffect||{}), stat: e.target.value } }))}>
                            {['STR','DEX','CON','INT','WIS','CHA'].map(s => <option key={s}>{s}</option>)}
                          </select>
                        </div>
                        <div style={{ width: 90 }}>
                          <div className="field-label mb-4">Режим</div>
                          <select className="input" value={newItem.customEffect?.mode || 'set'}
                            onChange={e => setNewItem(v => ({ ...v, customEffect: { ...(v.customEffect||{}), mode: e.target.value } }))}>
                            <option value="set">= встановити</option>
                            <option value="add">+ додати</option>
                          </select>
                        </div>
                        <div style={{ width: 80 }}>
                          <div className="field-label mb-4">{newItem.customEffect?.mode === 'add' ? '+N' : 'Значення'}</div>
                          <input className="input" type="number" min="1" max="30"
                            value={newItem.customEffect?.value ?? (newItem.customEffect?.mode === 'add' ? 2 : 21)}
                            onChange={e => setNewItem(v => ({ ...v, customEffect: { ...(v.customEffect||{}), value: Number(e.target.value)||1 } }))}/>
                        </div>
                      </div>
                    )}
                  </div>
                )}
                <div>
                  <div className="field-label mb-4">Нотатка</div>
                  <input className="input" placeholder="опис, де знайшли, властивості…"
                    value={newItem.note || ''}
                    onChange={e => setNewItem(v => ({ ...v, note: e.target.value }))}/>
                </div>
                <div className="flex ig-8 mt-4">
                  <Btn primary onClick={submitNewItem}><Icon name="plus" size={12}/> Додати</Btn>
                  <Btn ghost onClick={() => setAddOpen(false)}>Скасувати</Btn>
                </div>
              </div>
            </div>
          </div>
        </div>
      )}
    </>
  );
};

// ============================================================
// SCREEN 6 · FEATURES
// ============================================================

const FeatureBlock = ({ name, src, body, uses, onUse, onReset, onDelete, onEdit }) => (
  <div className="feature-card">
    <div className="flex ica ig-8 mb-6">
      <span className="display" style={{ fontSize: 14, color: 'var(--ink-0)' }}>{name}</span>
      <span className="mono dim" style={{ fontSize: 10 }}>{src}</span>
      <div className="igrow"/>
      {uses && (
        <div className="flex ica ig-4">
          {Array.from({ length: uses.total }).map((_, i) => (
            <Dot key={i} on={i < uses.total - uses.used}
              onClick={() => onUse && onUse(i)}/>
          ))}
          <span className="mono dim" style={{ fontSize: 10, marginLeft: 4 }}>{uses.total - uses.used}/{uses.total}</span>
          {uses.used > 0 && onReset && (
            <Btn sm ghost onClick={onReset} style={{ marginLeft: 4 }} title="Відновити заряди">↺</Btn>
          )}
        </div>
      )}
      {onEdit && (
        <IconBtn name="edit" size={12} title="Редагувати" onClick={onEdit}/>
      )}
      {onDelete && (
        <IconBtn name="trash" size={12} title="Видалити" onClick={onDelete}/>
      )}
    </div>
    <div className="script" style={{ fontSize: 14, color: 'var(--ink-1)', lineHeight: 1.55 }}>{body}</div>
  </div>
);

const ScreenFeatures = ({ ch, setCh }) => {
  const { push } = useToast();
  if (!ch) return null;
  const charges = ch.featureCharges || {};
  const [addFeatOpen, setAddFeatOpen] = useState(false);
  const [newFeat, setNewFeat] = useState({ name: '', src: 'Риса', body: '', usesTotal: 0, category: 'class' });
  const [editFeatOpen, setEditFeatOpen] = useState(false);
  const [editFeatIdx, setEditFeatIdx] = useState(null);
  const [editFeatDraft, setEditFeatDraft] = useState(null);

  const useCharge = (name) => {
    const feature = FEATURES_CLASS.find(f => f.name === name)
      || FEATURES_FEATS.find(f => f.name === name)
      || (ch.customFeatures || []).find(f => f.name === name);
    if (!feature?.uses) return;
    setCh(c => {
      const cur = (c.featureCharges || {})[name] || 0;
      return {
        ...c,
        featureCharges: { ...(c.featureCharges || {}), [name]: Math.min(feature.uses.total, cur + 1) },
      };
    });
  };

  const resetCharge = (name) => {
    setCh(c => ({ ...c, featureCharges: { ...(c.featureCharges || {}), [name]: 0 } }));
  };

  return (
    <>
      <SectionHeader
        title="Риси та здібності"
        eyebrow="класові · расові · фічі · з відстеженням використань"
        action={<Btn primary sm onClick={() => setAddFeatOpen(true)}><Icon name="plus" size={11}/> Риса</Btn>}
      />

      <div className="features-grid">
        {(() => {
          const customClass = (ch.customFeatures || []).filter(f => !f.category || f.category === 'class');
          const customRace  = (ch.customFeatures || []).filter(f => f.category === 'race');
          const customFeat  = (ch.customFeatures || []).filter(f => f.category === 'feat');
          const renderCustom = (f) => {
            const idx = (ch.customFeatures || []).indexOf(f);
            return (
              <FeatureBlock key={f.name} {...f}
                uses={f.uses ? { ...f.uses, used: charges[f.name] || 0 } : undefined}
                onUse={() => useCharge(f.name)}
                onReset={() => resetCharge(f.name)}
                onEdit={() => { setEditFeatDraft({ ...f }); setEditFeatIdx(idx); setEditFeatOpen(true); }}
                onDelete={() => {
                  setCh(c => ({ ...c, customFeatures: (c.customFeatures || []).filter((_, i) => i !== idx) }));
                  push({ label: `Видалено: ${f.name}` });
                }}/>
            );
          };
          return (
            <>
              <Card title="Класові" tag={`${FEATURES_CLASS.length + customClass.length} · ${ch.klass} ${ch.level}`}>
                {FEATURES_CLASS.map(f => (
                  <FeatureBlock key={f.name} {...f}
                    uses={f.uses ? { ...f.uses, used: charges[f.name] || 0 } : undefined}
                    onUse={() => useCharge(f.name)}
                    onReset={() => resetCharge(f.name)}/>
                ))}
                {customClass.map(renderCustom)}
              </Card>
              <Card title="Расові" tag={`${FEATURES_RACE.length + customRace.length} · ${ch.race}`}>
                {FEATURES_RACE.map(f => <FeatureBlock key={f.name} {...f}/>)}
                {customRace.map(renderCustom)}
              </Card>
              <Card title="Фічі (Feats)" tag={`${FEATURES_FEATS.length + customFeat.length} шт`}>
                {FEATURES_FEATS.length === 0 && customFeat.length === 0
                  ? <div className="mono dim" style={{ fontSize: 12, padding: '8px 0' }}>Немає фічів</div>
                  : FEATURES_FEATS.map(f => (
                      <FeatureBlock key={f.name} {...f}
                        uses={f.uses ? { ...f.uses, used: charges[f.name] || 0 } : undefined}
                        onUse={() => useCharge(f.name)}
                        onReset={() => resetCharge(f.name)}/>
                    ))
                }
                {customFeat.map(renderCustom)}
              </Card>
            </>
          );
        })()}
      </div>

      {/* ===== MODAL: Редагувати рису ===== */}
      {editFeatOpen && editFeatDraft && (
        <div className="dice-overlay-backdrop" onClick={() => setEditFeatOpen(false)}>
          <div className="dice-overlay" style={{ width: 500, minHeight: '55vh' }} onClick={e => e.stopPropagation()}>
            <div className="dice-overlay-head">
              <Icon name="edit" size={18} style={{ color: 'var(--gold-1)' }}/>
              <h2>Редагувати рису</h2>
              <div className="igrow"/>
              <IconBtn name="x" onClick={() => setEditFeatOpen(false)}/>
            </div>
            <div className="dice-overlay-body" style={{ display: 'flex', flexDirection: 'column' }}>
              <div style={{ display: 'flex', flexDirection: 'column', flex: 1, gap: 12, minHeight: 0 }}>
                <div className="flex ig-8">
                  <div className="igrow">
                    <div className="field-label mb-4">Назва *</div>
                    <input className="input" autoFocus value={editFeatDraft.name}
                      onChange={e => setEditFeatDraft(v => ({ ...v, name: e.target.value }))}/>
                  </div>
                  <div className="igrow">
                    <div className="field-label mb-4">Джерело</div>
                    <input className="input" value={editFeatDraft.src || ''}
                      onChange={e => setEditFeatDraft(v => ({ ...v, src: e.target.value }))}/>
                  </div>
                  <div style={{ width: 90 }}>
                    <div className="field-label mb-4">Категорія</div>
                    <select className="input" value={editFeatDraft.category || 'class'}
                      onChange={e => setEditFeatDraft(v => ({ ...v, category: e.target.value }))}>
                      <option value="class">Класові</option>
                      <option value="race">Расові</option>
                      <option value="feat">Фічі</option>
                    </select>
                  </div>
                  <div style={{ width: 80 }}>
                    <div className="field-label mb-4">Використань</div>
                    <input className="input" type="number" min="0" max="20"
                      value={editFeatDraft.uses?.total || 0}
                      onChange={e => {
                        const n = Math.max(0, Number(e.target.value) || 0);
                        setEditFeatDraft(v => ({ ...v, uses: n > 0 ? { total: n, used: v.uses?.used || 0 } : null }));
                      }}/>
                  </div>
                </div>
                <div style={{ flex: 1, display: 'flex', flexDirection: 'column', minHeight: 0 }}>
                  <div className="field-label mb-4">Опис</div>
                  <textarea className="textarea" style={{ flex: 1, resize: 'none', minHeight: 80 }}
                    value={editFeatDraft.body || ''}
                    onChange={e => setEditFeatDraft(v => ({ ...v, body: e.target.value }))}/>
                </div>
                <div className="flex ig-8">
                  <Btn primary onClick={() => {
                    if (!editFeatDraft.name?.trim()) return;
                    setCh(c => ({
                      ...c,
                      customFeatures: (c.customFeatures || []).map((f, i) => i === editFeatIdx ? { ...editFeatDraft, name: editFeatDraft.name.trim() } : f),
                    }));
                    push({ label: `Збережено: ${editFeatDraft.name.trim()}` });
                    setEditFeatOpen(false);
                  }}><Icon name="check" size={12}/> Зберегти</Btn>
                  <Btn ghost onClick={() => setEditFeatOpen(false)}>Скасувати</Btn>
                </div>
              </div>
            </div>
          </div>
        </div>
      )}

      {/* ===== MODAL: Нова риса ===== */}
      {addFeatOpen && (
        <div className="dice-overlay-backdrop" onClick={() => setAddFeatOpen(false)}>
          <div className="dice-overlay" style={{ width: 500, minHeight: '62vh' }} onClick={e => e.stopPropagation()}>
            <div className="dice-overlay-head">
              <Icon name="star" size={18} style={{ color: 'var(--gold-1)' }}/>
              <h2>Нова риса / здібність</h2>
              <div className="igrow"/>
              <IconBtn name="x" onClick={() => setAddFeatOpen(false)}/>
            </div>
            <div className="dice-overlay-body" style={{ display: 'flex', flexDirection: 'column' }}>
              <div style={{ display: 'flex', flexDirection: 'column', flex: 1, gap: 12, minHeight: 0 }}>
                <div className="flex ig-8">
                  <div className="igrow">
                    <div className="field-label mb-4">Назва *</div>
                    <input className="input" placeholder="Назва риси" autoFocus
                      value={newFeat.name} onChange={e => setNewFeat(v => ({ ...v, name: e.target.value }))}/>
                  </div>
                  <div className="igrow">
                    <div className="field-label mb-4">Джерело</div>
                    <input className="input" placeholder="Клас / Раса / Риса"
                      value={newFeat.src} onChange={e => setNewFeat(v => ({ ...v, src: e.target.value }))}/>
                  </div>
                  <div style={{ width: 90 }}>
                    <div className="field-label mb-4">Категорія</div>
                    <select className="input" value={newFeat.category}
                      onChange={e => setNewFeat(v => ({ ...v, category: e.target.value }))}>
                      <option value="class">Класові</option>
                      <option value="race">Расові</option>
                      <option value="feat">Фічі</option>
                    </select>
                  </div>
                  <div style={{ width: 80 }}>
                    <div className="field-label mb-4">Використань</div>
                    <input className="input" type="number" min="0" max="20" placeholder="0"
                      title="0 = без трекінгу"
                      value={newFeat.usesTotal || ''}
                      onChange={e => setNewFeat(v => ({ ...v, usesTotal: Math.max(0, Number(e.target.value) || 0) }))}/>
                  </div>
                </div>
                <div style={{ flex: 1, display: 'flex', flexDirection: 'column', minHeight: 0 }}>
                  <div className="field-label mb-4">Опис</div>
                  <textarea className="textarea" style={{ flex: 1, resize: 'none', minHeight: 80 }}
                    placeholder="Опис здібності…"
                    value={newFeat.body} onChange={e => setNewFeat(v => ({ ...v, body: e.target.value }))}/>
                </div>
                <div className="flex ig-8">
                  <Btn primary onClick={() => {
                    if (!newFeat.name.trim()) return;
                    const fname = newFeat.name.trim();
                    const uses = newFeat.usesTotal > 0 ? { total: newFeat.usesTotal, used: 0 } : null;
                    setCh(c => ({ ...c, customFeatures: [...(c.customFeatures || []), { name: fname, src: newFeat.src, body: newFeat.body, uses, category: newFeat.category }] }));
                    setNewFeat({ name: '', src: 'Риса', body: '', usesTotal: 0, category: 'class' });
                    setAddFeatOpen(false);
                    push({ icon: 'star', label: `Рису додано: ${fname}` });
                  }}><Icon name="plus" size={12}/> Додати</Btn>
                  <Btn ghost onClick={() => setAddFeatOpen(false)}>Скасувати</Btn>
                </div>
              </div>
            </div>
          </div>
        </div>
      )}
    </>
  );
};

window.ScreenInventory = ScreenInventory;
window.ScreenFeatures = ScreenFeatures;
