/* @jsx React.createElement */
const { useState, useEffect, useRef, useMemo } = React;
/* ============================================================
   Yappari — SIGNAGE (POS screen: fullscreen player + kiosk layout)
   ============================================================ */
function fmtDur(s) {
  if (!s) return '\u2014';
  const m = Math.floor(s / 60), ss = s % 60;
  return m > 0 ? m + ':' + String(ss).padStart(2, '0') : ss + ' dtk';
}

// drawn poster art for a media item (placeholder creative)
function MediaArt({ media, big }) {
  const known = ['bottle', 'can', 'carton', 'cupnoodle', 'bag', 'bar'];
  let inner;
  if (media.glyph === 'blossom') inner = React.createElement(PlumBlossom, { size: big ? 120 : 52, color: '#fff' });
  else if (media.glyph === 'qr') {
    const cells = [];
    const pat = [1,1,1,0,1,0,1, 1,0,1,1,0,1,1, 1,1,0,0,1,1,0, 0,1,1,1,0,0,1, 1,0,0,1,1,1,0, 0,1,1,0,1,0,1, 1,0,1,1,0,1,1];
    for (let i = 0; i < 49; i++) cells.push(React.createElement('div', { key: i, style: { background: pat[i] ? '#fff' : 'transparent', borderRadius: 1 } }));
    inner = React.createElement('div', { style: { display: 'grid', gridTemplateColumns: 'repeat(7,1fr)', gap: 2, width: big ? 96 : 40, height: big ? 96 : 40 } }, cells);
  } else if (known.includes(media.glyph)) inner = React.createElement(ProductGlyph, { glyph: media.glyph, color: '#fff', size: big ? 120 : 46, radius: 12 });
  else inner = React.createElement('div', { style: { fontFamily: 'var(--font-display)', fontSize: big ? 44 : 18, color: '#fff', letterSpacing: '.04em' } }, 'PROMO');
  return React.createElement('div', { style: { position: 'absolute', inset: 0, display: 'grid', placeItems: 'center', background: 'linear-gradient(150deg,' + media.color + ',' + media.color + 'cc 60%, rgba(0,0,0,.5))' } },
    React.createElement('div', { style: { filter: 'drop-shadow(0 4px 12px rgba(0,0,0,.3))' } }, inner));
}

// ---- POS product grid (touchscreen buy UI) ----
function PosGrid({ scale }) {
  const Y = window.YAPPARI;
  const prods = Y.PRODUCTS.slice(0, 8);
  const [sel, setSel] = useState(null);
  const s = scale || 1;
  return React.createElement('div', { style: { position: 'absolute', inset: 0, background: 'var(--bg)', display: 'flex', flexDirection: 'column' } },
    React.createElement('div', { style: { padding: 6 * s + 'px ' + 8 * s + 'px', display: 'flex', alignItems: 'center', gap: 6 * s, borderBottom: '1px solid var(--border-subtle)' } },
      React.createElement(PlumBlossom, { size: 14 * s, color: '#004080' }),
      React.createElement('span', { style: { fontWeight: 800, fontSize: 10 * s, color: 'var(--fg-1)' } }, 'Pilih Produk'),
      React.createElement('span', { className: 'jp', style: { fontSize: 8 * s, color: 'var(--fg-3)', marginLeft: 'auto' } }, '\u3084\u3063\u3071\u308a!')),
    React.createElement('div', { style: { flex: 1, overflow: 'hidden', padding: 6 * s, display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 5 * s, alignContent: 'start' } },
      prods.map(p => {
        const on = sel === p.id;
        return React.createElement('button', { key: p.id, onClick: () => setSel(p.id),
          style: { border: '1px solid ' + (on ? 'var(--accent)' : 'var(--border-subtle)'), borderRadius: 6 * s, background: on ? 'var(--st-warn-bg)' : 'var(--bg-elev)', padding: 4 * s, display: 'flex', alignItems: 'center', gap: 5 * s, cursor: 'pointer', boxShadow: on ? '0 0 0 2px rgba(240,64,0,.2)' : 'none', overflow: 'hidden' } },
          React.createElement(ProductGlyph, { glyph: p.glyph, color: p.color, size: 22 * s, radius: 4 }),
          React.createElement('div', { style: { minWidth: 0, textAlign: 'left' } },
            React.createElement('div', { style: { fontSize: 8.5 * s, fontWeight: 700, color: 'var(--fg-1)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' } }, p.name),
            React.createElement('div', { style: { fontSize: 9 * s, fontWeight: 800, color: 'var(--accent)' } }, fmtRpShort(p.price))));
      })),
  );
}

// ---- composed kiosk screen: header (16:9) + POS + footer strip ----
function KioskScreen({ headerMedia, footerMedia }) {
  const w = 248, h = 432;
  const headerH = Math.round(w * 9 / 16);
  const footerH = Math.round(w / 6);
  return React.createElement('div', { className: 'screen-bezel', style: { width: w + 26 } },
    React.createElement('div', { className: 'screen-glass', style: { width: w, height: h, display: 'flex', flexDirection: 'column' } },
      React.createElement('div', { style: { position: 'relative', height: headerH, flexShrink: 0, overflow: 'hidden', borderBottom: '2px solid rgba(0,0,0,.3)' } },
        headerMedia ? React.createElement('div', { key: headerMedia.id, style: { position: 'absolute', inset: 0, animation: 'fadeIn .5s var(--ease-out)' } }, React.createElement(MediaArt, { media: headerMedia, big: true })) : null,
        React.createElement('span', { style: { position: 'absolute', top: 5, left: 6, fontSize: 9, fontWeight: 800, color: 'rgba(255,255,255,.85)', letterSpacing: '.1em', textShadow: '0 1px 2px rgba(0,0,0,.4)' } }, 'IKLAN 16:9')),
      React.createElement('div', { style: { position: 'relative', flex: 1, overflow: 'hidden' } }, React.createElement(PosGrid, { scale: 1 })),
      React.createElement('div', { style: { position: 'relative', height: footerH, flexShrink: 0, overflow: 'hidden', borderTop: '2px solid rgba(0,0,0,.3)' } },
        footerMedia ? React.createElement('div', { key: footerMedia.id, style: { position: 'absolute', inset: 0, animation: 'fadeIn .5s var(--ease-out)' } }, React.createElement(MediaArt, { media: footerMedia })) : null,
        React.createElement('span', { style: { position: 'absolute', top: '50%', left: 8, transform: 'translateY(-50%)', fontSize: 8.5, fontWeight: 800, color: 'rgba(255,255,255,.9)', letterSpacing: '.08em' } }, 'FOOTER')),
    ),
  );
}

function ScreenPreview({ media, playing, prog, setPlaying, orient, settings, idx, total, onPrev, onNext }) {
  const portrait = orient === 'portrait';
  const w = portrait ? 224 : 360, h = portrait ? 398 : 202;
  return React.createElement('div', { className: 'screen-bezel', style: { width: w + 28 } },
    React.createElement('div', { className: 'screen-glass', style: { width: w, height: h, margin: '0 auto' } },
      media ? React.createElement(React.Fragment, null,
        React.createElement('div', { key: media.id, style: { position: 'absolute', inset: 0, animation: 'fadeIn .5s var(--ease-out)' } }, React.createElement(MediaArt, { media, big: true })),
        React.createElement('div', { style: { position: 'absolute', top: 0, left: 0, right: 0, padding: '10px 12px', background: 'linear-gradient(180deg,rgba(0,0,0,.5),transparent)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' } },
          React.createElement('span', { className: 'row gap-1', style: { color: '#fff', fontSize: 11, fontWeight: 700 } }, React.createElement('span', { style: { width: 7, height: 7, borderRadius: '50%', background: media.type === 'video' ? '#FF5A5A' : '#4ADE80' } }), media.type === 'video' ? 'VIDEO' : 'GAMBAR'),
          React.createElement('span', { style: { color: 'rgba(255,255,255,.85)', fontSize: 11, fontWeight: 700, fontFamily: 'var(--font-mono)' } }, (idx + 1) + '/' + total)),
        settings.priceOverlay && React.createElement('div', { style: { position: 'absolute', bottom: 26, left: 0, right: 0, textAlign: 'center' } },
          React.createElement('div', { style: { display: 'inline-block', background: 'rgba(0,20,38,.55)', backdropFilter: 'blur(4px)', color: '#fff', padding: '6px 14px', borderRadius: 999, fontWeight: 800, fontSize: 13 } }, media.name.split(' \u2014 ')[0])),
        React.createElement('div', { style: { position: 'absolute', bottom: 0, left: 0, right: 0, height: 5, background: 'rgba(255,255,255,.25)' } },
          React.createElement('div', { style: { height: '100%', width: (prog * 100) + '%', background: '#fff' } })),
      ) : React.createElement('div', { style: { position: 'absolute', inset: 0, display: 'grid', placeItems: 'center', color: 'rgba(255,255,255,.5)', fontSize: 13 } }, 'Playlist kosong'),
    ),
  );
}

function SignageView({ machines, selectedMachine }) {
  const Y = window.YAPPARI;
  const mediaMap = Object.fromEntries(Y.MEDIA.map(m => [m.id, m]));
  const [layoutMode, setLayoutMode] = useState('fullscreen'); // fullscreen | kiosk
  const [playlist, setPlaylist] = useState(Y.DEFAULT_PLAYLIST.slice());
  const [enabled, setEnabled] = useState(() => Object.fromEntries(Y.MEDIA.map(m => [m.id, Y.DEFAULT_PLAYLIST.includes(m.id)])));
  const [headerList, setHeaderList] = useState(['md07', 'md03', 'md05']);
  const [footerList, setFooterList] = useState(['md12', 'md05']);
  const [zone, setZone] = useState('header');
  const [settings, setSettings] = useState({ orient: 'portrait', transition: 'fade', imgDur: 8, loop: true, mute: true, priceOverlay: true, start: '07:00', end: '22:00' });
  const [query, setQuery] = useState('');
  const [typeF, setTypeF] = useState('all');
  const setS = (k, v) => setSettings(s => ({ ...s, [k]: v }));

  // fullscreen player
  const seq = playlist.filter(id => enabled[id]);
  const total = seq.length || 1;
  const [playing, setPlaying] = useState(true);
  const [idx, setIdx] = useState(0);
  const [prog, setProg] = useState(0);
  const curId = seq[idx % total];
  const cur = curId ? mediaMap[curId] : null;
  useEffect(() => {
    if (layoutMode !== 'fullscreen' || !playing || !cur) return;
    const secs = Math.max(3, Math.min(8, (cur.dur || settings.imgDur) * 0.4)) * 1000;
    let raf, start;
    const step = (t) => { if (!start) start = t; const p = Math.min(1, (t - start) / secs); setProg(p); if (p < 1) raf = requestAnimationFrame(step); else { setProg(0); setIdx(i => (i + 1) % total); } };
    raf = requestAnimationFrame(step);
    return () => cancelAnimationFrame(raf);
  }, [playing, curId, total, layoutMode]);

  // kiosk header/footer cyclers
  const [hIdx, setHIdx] = useState(0), [fIdx, setFIdx] = useState(0);
  useEffect(() => { if (layoutMode !== 'kiosk') return; const id = setInterval(() => setHIdx(i => i + 1), 4000); return () => clearInterval(id); }, [layoutMode, headerList.length]);
  useEffect(() => { if (layoutMode !== 'kiosk') return; const id = setInterval(() => setFIdx(i => i + 1), 6000); return () => clearInterval(id); }, [layoutMode, footerList.length]);
  const headerCur = headerList.length ? mediaMap[headerList[hIdx % headerList.length]] : null;
  const footerCur = footerList.length ? mediaMap[footerList[fIdx % footerList.length]] : null;

  // active list helpers (which list the library adds to)
  const target = layoutMode === 'fullscreen' ? 'full' : zone;
  const listFor = (t) => t === 'full' ? playlist : t === 'header' ? headerList : footerList;
  const setListFor = (t, fn) => { if (t === 'full') setPlaylist(fn); else if (t === 'header') setHeaderList(fn); else setFooterList(fn); };
  const move = (t, id, dir) => setListFor(t, pl => { const i = pl.indexOf(id), j = i + dir; if (j < 0 || j >= pl.length) return pl; const n = pl.slice(); [n[i], n[j]] = [n[j], n[i]]; return n; });
  const removeFrom = (t, id) => { setListFor(t, pl => pl.filter(x => x !== id)); if (t === 'full') setEnabled(e => ({ ...e, [id]: false })); };
  const addTo = (t, id) => { setListFor(t, pl => pl.includes(id) ? pl : [...pl, id]); if (t === 'full') setEnabled(e => ({ ...e, [id]: true })); };

  const totalDur = seq.reduce((a, id) => a + (mediaMap[id].dur || settings.imgDur), 0);
  const lib = Y.MEDIA.filter(m => (typeF === 'all' || m.type === typeF) && m.name.toLowerCase().includes(query.toLowerCase()));
  const mObj = machines.find(m => m.id === selectedMachine);

  // generic small list row
  const listRow = (t, id, i, list) => {
    const m = mediaMap[id]; const on = t === 'full' ? enabled[id] : true;
    const isNow = (t === 'full' && curId === id && on) || (t === 'header' && headerCur && headerCur.id === id) || (t === 'footer' && footerCur && footerCur.id === id);
    return React.createElement('div', { key: id, className: 'playlist-row' + (isNow ? ' playing' : ''), style: { opacity: on ? 1 : 0.5 } },
      React.createElement('div', { className: 'col', style: { gap: 0 } },
        React.createElement('button', { className: 'drag-handle', style: { background: 'none', border: 'none', padding: 0, height: 16 }, disabled: i === 0, onClick: () => move(t, id, -1) }, React.createElement(Icon, { name: 'chevronUp', size: 14 })),
        React.createElement('button', { className: 'drag-handle', style: { background: 'none', border: 'none', padding: 0, height: 16 }, disabled: i === list.length - 1, onClick: () => move(t, id, 1) }, React.createElement(Icon, { name: 'chevronDown', size: 14 }))),
      React.createElement('div', { style: { position: 'relative', width: 46, height: 46, borderRadius: 8, overflow: 'hidden', flexShrink: 0 } }, React.createElement(MediaArt, { media: m })),
      React.createElement('div', { style: { flex: 1, minWidth: 0 } },
        React.createElement('div', { className: 'row gap-2' },
          isNow && React.createElement('span', { style: { width: 7, height: 7, borderRadius: '50%', background: 'var(--st-online)', flexShrink: 0 } }),
          React.createElement('span', { style: { fontWeight: 700, fontSize: 13.5, color: 'var(--fg-1)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' } }, m.name)),
        React.createElement('div', { className: 'row gap-2', style: { marginTop: 3 } },
          React.createElement('span', { className: 'badge ' + (m.type === 'video' ? 'badge-error' : 'badge-info'), style: { padding: '1px 7px', fontSize: 10.5 } }, m.type === 'video' ? 'Video' : 'Gambar'),
          React.createElement('span', { className: 'muted', style: { fontSize: 12 } }, fmtDur(m.dur || settings.imgDur) + ' \u00b7 ' + m.orient))),
      t === 'full' && React.createElement('button', { className: 'toggle ' + (on ? 'on' : ''), onClick: () => setEnabled(e => ({ ...e, [id]: !e[id] })) }),
      React.createElement('button', { className: 'icon-btn', style: { width: 32, height: 32, color: 'var(--st-error)' }, onClick: () => removeFrom(t, id) }, React.createElement(Icon, { name: 'trash', size: 15 })));
  };

  const curList = listFor(target);

  return React.createElement('div', { className: 'view' },
    React.createElement('div', { className: 'l-split l-plano' },
      // ---- MAIN ----
      React.createElement('div', { className: 'col gap-5' },
        // mode selector banner
        React.createElement('div', { className: 'card card-pad', style: { display: 'flex', alignItems: 'center', gap: 'var(--sp-4)', flexWrap: 'wrap' } },
          React.createElement('div', { className: 'row gap-2', style: { fontWeight: 700, fontSize: 13, color: 'var(--fg-2)' } }, React.createElement(Icon, { name: 'screen', size: 16 }), 'Mode tampilan layar'),
          React.createElement('div', { className: 'row gap-2' },
            React.createElement('button', { className: 'chip ' + (layoutMode === 'fullscreen' ? 'active' : ''), onClick: () => setLayoutMode('fullscreen') }, React.createElement(Icon, { name: 'play', size: 13 }), 'Fullscreen'),
            React.createElement('button', { className: 'chip ' + (layoutMode === 'kiosk' ? 'active' : ''), onClick: () => setLayoutMode('kiosk') }, React.createElement(Icon, { name: 'layers', size: 13 }), 'Kiosk (Header + POS + Footer)')),
          React.createElement('span', { className: 'muted', style: { fontSize: 12.5, marginLeft: 'auto', maxWidth: 360 } }, layoutMode === 'fullscreen' ? 'Satu media menutupi seluruh layar.' : 'Header iklan 16:9, grid pilih produk di tengah, footer strip di bawah.')),

        layoutMode === 'fullscreen'
          ? React.createElement(SectionCard, {
              title: 'Playlist fullscreen', sub: seq.length + ' media \u00b7 durasi loop ' + fmtDur(totalDur), motif: true,
              right: React.createElement('span', { className: 'badge ' + (playing ? 'badge-online' : 'badge-soft') }, playing && React.createElement('span', { className: 'b-dot', style: { animation: 'ping 2s infinite' } }), playing ? 'Tayang' : 'Jeda'),
              bodyStyle: { padding: 'var(--sp-4)' },
            },
              React.createElement('div', { className: 'col gap-2' },
                playlist.length === 0 && React.createElement('div', { style: { padding: 24, textAlign: 'center', color: 'var(--fg-3)' } }, 'Belum ada media. Tambahkan dari pustaka.'),
                playlist.map((id, i) => listRow('full', id, i, playlist))))
          : React.createElement(SectionCard, {
              title: 'Media per zona', sub: 'Atur media tiap bagian layar kiosk', motif: true,
              right: React.createElement('div', { className: 'row gap-2' },
                React.createElement('button', { className: 'chip ' + (zone === 'header' ? 'active' : ''), onClick: () => setZone('header') }, 'Header 16:9'),
                React.createElement('button', { className: 'chip ' + (zone === 'footer' ? 'active' : ''), onClick: () => setZone('footer') }, 'Footer')),
              bodyStyle: { padding: 'var(--sp-4)' },
            },
              React.createElement('div', { style: { padding: '0 0 10px', fontSize: 12.5, color: 'var(--fg-3)' } }, zone === 'header' ? 'Banner iklan rasio 16:9 di atas \u2014 disarankan media landscape.' : 'Strip tipis di bawah \u2014 cocok untuk brand bar / promo singkat.'),
              React.createElement('div', { className: 'col gap-2' },
                curList.length === 0 && React.createElement('div', { style: { padding: 24, textAlign: 'center', color: 'var(--fg-3)' } }, 'Belum ada media untuk zona ini.'),
                curList.map((id, i) => listRow(zone, id, i, curList))),
              React.createElement('div', { style: { marginTop: 12, padding: '10px 12px', borderRadius: 'var(--r-2)', background: 'var(--st-maint-bg)', color: 'var(--fg-2)', fontSize: 12.5, display: 'flex', gap: 8, alignItems: 'center' } },
                React.createElement(Icon, { name: 'cube', size: 15, style: { color: 'var(--st-maint)' } }), 'Area POS di tengah otomatis menampilkan grid produk aktif mesin.')),

        // library (shared)
        React.createElement(SectionCard, {
          title: 'Pustaka media', sub: lib.length + ' aset \u00b7 klik untuk tambah ke ' + (target === 'full' ? 'playlist' : target === 'header' ? 'header' : 'footer'),
          right: React.createElement('div', { className: 'row gap-2' },
            React.createElement('button', { className: 'btn btn-ghost btn-sm' }, React.createElement(Icon, { name: 'upload', size: 15 }), 'Unggah'),
            React.createElement('button', { className: 'btn btn-primary btn-sm' }, React.createElement(Icon, { name: 'plus', size: 15 }), 'Tambah')),
          bodyStyle: { padding: 'var(--sp-5)' },
        },
          React.createElement('div', { className: 'row gap-3', style: { marginBottom: 16, flexWrap: 'wrap' } },
            React.createElement('div', { style: { position: 'relative', flex: 1, minWidth: 180 } },
              React.createElement(Icon, { name: 'search', size: 16, style: { position: 'absolute', left: 11, top: 10, color: 'var(--fg-3)' } }),
              React.createElement('input', { className: 'input', style: { paddingLeft: 36 }, placeholder: 'Cari media\u2026', value: query, onChange: e => setQuery(e.target.value) })),
            React.createElement('div', { className: 'row gap-2' },
              ['all', 'video', 'image'].map(t => React.createElement('button', { key: t, className: 'chip ' + (typeF === t ? 'active' : ''), onClick: () => setTypeF(t) }, t === 'all' ? 'Semua' : t === 'video' ? 'Video' : 'Gambar')))),
          React.createElement('div', { className: 'media-grid' },
            lib.map(m => {
              const inList = curList.includes(m.id);
              return React.createElement('button', { key: m.id, className: 'media-tile', onClick: () => addTo(target, m.id) },
                React.createElement('div', { className: 'media-thumb', style: { aspectRatio: m.orient === 'portrait' ? '3/4' : '16/9' } },
                  React.createElement(MediaArt, { media: m }),
                  m.type === 'video' && React.createElement('div', { className: 'media-play' }, React.createElement(Icon, { name: 'play', size: 18 })),
                  inList && React.createElement('span', { style: { position: 'absolute', top: 6, right: 6, width: 22, height: 22, borderRadius: '50%', background: 'var(--st-online)', color: '#fff', display: 'grid', placeItems: 'center' } }, React.createElement(Icon, { name: 'check', size: 13 }))),
                React.createElement('div', { style: { padding: '8px 10px' } },
                  React.createElement('div', { style: { fontWeight: 700, fontSize: 12.5, color: 'var(--fg-1)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' } }, m.name),
                  React.createElement('div', { className: 'row', style: { justifyContent: 'space-between', marginTop: 3 } },
                    React.createElement('span', { className: 'muted', style: { fontSize: 11 } }, m.w + '\u00d7' + m.h),
                    React.createElement('span', { className: 'muted', style: { fontSize: 11, fontWeight: 700 } }, fmtDur(m.dur)))));
            })),
        ),
      ),
      // ---- ASIDE: preview + settings ----
      React.createElement('div', { className: 'col gap-5', style: { position: 'sticky', top: 0 } },
        React.createElement(SectionCard, { title: 'Pratinjau layar', sub: (layoutMode === 'kiosk' ? 'Mode kiosk \u00b7 ' : 'Mode fullscreen \u00b7 ') + (mObj ? mObj.name : 'semua mesin'), motif: true, bodyStyle: { padding: 'var(--sp-5)' } },
          React.createElement('div', { className: 'col', style: { alignItems: 'center', gap: 14 } },
            layoutMode === 'kiosk'
              ? React.createElement(KioskScreen, { headerMedia: headerCur, footerMedia: footerCur })
              : React.createElement(ScreenPreview, { media: cur, playing, prog, setPlaying, orient: settings.orient, settings, idx: idx % total, total, onPrev: () => { setIdx(i => (i - 1 + total) % total); setProg(0); }, onNext: () => { setIdx(i => (i + 1) % total); setProg(0); } }),
            layoutMode === 'fullscreen' && React.createElement('div', { className: 'row gap-2' },
              React.createElement('button', { className: 'icon-btn', onClick: () => { setIdx(i => (i - 1 + total) % total); setProg(0); } }, React.createElement(Icon, { name: 'chevronLeft', size: 18 })),
              React.createElement('button', { className: 'btn btn-primary', style: { width: 110, justifyContent: 'center' }, onClick: () => setPlaying(p => !p) }, React.createElement(Icon, { name: playing ? 'power' : 'play', size: 16 }), playing ? 'Jeda' : 'Putar'),
              React.createElement('button', { className: 'icon-btn', onClick: () => { setIdx(i => (i + 1) % total); setProg(0); } }, React.createElement(Icon, { name: 'chevronRight', size: 18 }))),
          )),
        React.createElement(SectionCard, { title: 'Pengaturan player', sub: 'Mode tayang & slideshow', bodyStyle: { padding: 'var(--sp-5)' } },
          React.createElement('div', { className: 'col gap-5' },
            React.createElement('div', null,
              React.createElement('label', { className: 'field-label', style: { marginBottom: 8 } }, 'Orientasi layar'),
              React.createElement('div', { className: 'row gap-2' },
                [['portrait', 'Portrait'], ['landscape', 'Landscape']].map(([v, l]) => React.createElement('button', { key: v, className: 'chip ' + (settings.orient === v ? 'active' : ''), style: { flex: 1, justifyContent: 'center' }, onClick: () => setS('orient', v) }, l)))),
            React.createElement('div', null,
              React.createElement('label', { className: 'field-label', style: { marginBottom: 8 } }, 'Transisi antar media'),
              React.createElement('div', { className: 'row gap-2' },
                [['fade', 'Fade'], ['slide', 'Slide'], ['none', 'Tanpa']].map(([v, l]) => React.createElement('button', { key: v, className: 'chip ' + (settings.transition === v ? 'active' : ''), style: { flex: 1, justifyContent: 'center' }, onClick: () => setS('transition', v) }, l)))),
            React.createElement('div', null,
              React.createElement('div', { className: 'row', style: { justifyContent: 'space-between', marginBottom: 6 } },
                React.createElement('label', { className: 'field-label', style: { margin: 0 } }, 'Durasi default gambar'),
                React.createElement('span', { style: { fontFamily: 'var(--font-display)', fontSize: 20, color: 'var(--st-maint)' } }, settings.imgDur + ' dtk')),
              React.createElement('input', { type: 'range', className: 'range', min: 3, max: 30, value: settings.imgDur, onChange: e => setS('imgDur', +e.target.value) })),
            [['loop', 'Putar berulang (loop)', 'Ulangi playlist tanpa henti'], ['mute', 'Bisukan audio', 'Tanpa suara di layar'], ['priceOverlay', 'Overlay nama/harga', 'Tampilkan label produk di layar']].map(([k, label, sub]) =>
              React.createElement('div', { key: k, className: 'row', style: { justifyContent: 'space-between', paddingTop: 4, borderTop: '1px solid var(--border-subtle)' } },
                React.createElement('div', { style: { paddingTop: 8 } }, React.createElement('div', { style: { fontWeight: 700, fontSize: 14 } }, label), React.createElement('div', { style: { fontSize: 12, color: 'var(--fg-3)' } }, sub)),
                React.createElement('button', { className: 'toggle ' + (settings[k] ? 'on' : ''), style: { marginTop: 10 }, onClick: () => setS(k, !settings[k]) }))),
            React.createElement('div', { style: { paddingTop: 4, borderTop: '1px solid var(--border-subtle)' } },
              React.createElement('label', { className: 'field-label', style: { marginBottom: 8, marginTop: 8 } }, 'Jam tayang'),
              React.createElement('div', { className: 'row gap-3' },
                React.createElement('input', { type: 'time', className: 'input', value: settings.start, onChange: e => setS('start', e.target.value) }),
                React.createElement('span', { className: 'muted' }, '\u2013'),
                React.createElement('input', { type: 'time', className: 'input', value: settings.end, onChange: e => setS('end', e.target.value) }))),
            React.createElement('button', { className: 'btn btn-primary btn-stamp', style: { justifyContent: 'center', marginTop: 4 } }, React.createElement(Icon, { name: 'check', size: 16 }), 'Simpan & sinkron ke mesin'),
          )),
      ),
    ),
  );
}
Object.assign(window, { SignageView, MediaArt, ScreenPreview, KioskScreen, PosGrid, fmtDur });
