<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<title>Laboratorium tablic</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Sora:wght@500;700&family=JetBrains+Mono:wght@500&display=swap">
<style>
:root{--bg:#f3f1fb;--panel:#fff;--ink:#241f4a;--mute:#6b6692;--line:#dcd8f0;--btn:#e9e6fa;--btnh:#d9d4f5;--code:#efecfb;
box-sizing:border-box;padding-top:env(safe-area-inset-top,0px);padding-bottom:env(safe-area-inset-bottom,0px)}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){--bg:#17123a;--panel:#211a4f;--ink:#f1eeff;--mute:#a49ed4;--line:#372f73;--btn:#2e2565;--btnh:#3d3285;--code:#150f36}}
:root[data-theme="dark"]{--bg:#17123a;--panel:#211a4f;--ink:#f1eeff;--mute:#a49ed4;--line:#372f73;--btn:#2e2565;--btnh:#3d3285;--code:#150f36}
html{scroll-padding-top:env(safe-area-inset-top,0px)}
*{box-sizing:border-box}
body{margin:0;background:var(--bg);color:var(--ink);font-family:'Sora',system-ui,sans-serif;line-height:1.5}
main{max-width:760px;margin:0 auto;padding:20px 16px 40px}
h1{font-size:1.6rem;margin:0 0 4px}
.sub{color:var(--mute);margin:0 0 18px;font-size:.95rem}
.panel{background:var(--panel);border:1px solid var(--line);border-radius:18px;padding:16px;margin-bottom:14px}
.stage{display:flex;align-items:flex-end;gap:6px;height:230px;overflow-x:auto;padding:6px 2px 0}
.bar{flex:1 0 34px;max-width:70px;border-radius:10px 10px 4px 4px;display:flex;flex-direction:column;align-items:center;justify-content:flex-start;
color:#fff;font-weight:700;font-size:.9rem;padding-top:6px;position:relative;animation:pop .35s cubic-bezier(.3,1.5,.5,1);transition:height .4s}
.bar i{position:absolute;bottom:-22px;font:500 .75rem 'JetBrains Mono',monospace;color:var(--mute);font-style:normal}
.stage-wrap{padding-bottom:24px}
.empty{margin:auto;color:var(--mute)}
@keyframes pop{from{transform:scaleY(.2);opacity:0}to{transform:none;opacity:1}}
@media (prefers-reduced-motion:reduce){.bar{animation:none;transition:none}}
.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(110px,1fr));gap:8px;margin-top:6px}
.stat{background:var(--btn);border-radius:12px;padding:8px 12px}
.stat b{display:block;font-size:1.15rem}
.stat span{font-size:.78rem;color:var(--mute)}
h2{font-size:.95rem;margin:0 0 10px}
.btns{display:flex;flex-wrap:wrap;gap:8px}
button{font:500 .85rem 'JetBrains Mono',monospace;background:var(--btn);color:var(--ink);border:0;border-radius:10px;padding:10px 12px;cursor:pointer;min-height:42px}
button:hover{background:var(--btnh)}
button:focus-visible{outline:3px solid #7c5cff;outline-offset:2px}
button.go{background:#6b4cff;color:#fff}
.arr{font:500 .9rem 'JetBrains Mono',monospace;background:var(--code);border-radius:12px;padding:12px;overflow-x:auto;white-space:nowrap}
.log{font:500 .82rem 'JetBrains Mono',monospace;background:var(--code);border-radius:12px;padding:10px 12px;min-height:70px}
.log div{padding:2px 0;color:var(--mute)}
.log div:first-child{color:var(--ink)}
.log em{color:#8a6cff;font-style:normal}
</style>
</head>
<body>
<main>
<h1>Laboratorium tablic</h1>
<p class="sub">Kliknij metodę i zobacz, co robi z tablicą. Wysokość i kolor słupka zależą od wartości.</p>

<div class="panel">
<div class="stage-wrap"><div class="stage" id="stage"></div></div>
<div class="arr" id="arr"></div>
<div class="stats" id="stats"></div>
</div>

<div class="panel">
<h2>Dodawanie i usuwanie</h2>
<div class="btns">
<button data-op="push">push(losowa)</button>
<button data-op="pop">pop()</button>
<button data-op="unshift">unshift(losowa)</button>
<button data-op="shift">shift()</button>
<button data-op="splice">splice(1, 1)</button>
</div>
</div>

<div class="panel">
<h2>Przekształcanie</h2>
<div class="btns">
<button data-op="map">map(x =&gt; x * 2)</button>
<button data-op="filter">filter(x =&gt; x % 2 === 0)</button>
<button data-op="big">filter(x =&gt; x &gt; 15)</button>
<button data-op="sort">sort((a, b) =&gt; a - b)</button>
<button data-op="reverse">reverse()</button>
<button class="go" data-op="reset">Losuj nową tablicę</button>
</div>
</div>

<div class="panel">
<h2>Historia wywołań</h2>
<div class="log" id="log"></div>
</div>
</main>

<script>
let arr = [];
const rnd = () => Math.floor(Math.random() * 40) + 1;
const stage = document.getElementById('stage');

function fresh() { arr = Array.from({length: 7}, rnd); }

function render() {
  stage.innerHTML = '';
  if (arr.length === 0) {
    stage.innerHTML = '<p class="empty">Tablica jest pusta [ ]. Dodaj element przez push lub unshift.</p>';
  }
  arr.forEach((v, i) => {
    const d = document.createElement('div');
    d.className = 'bar';
    const h = Math.min(v, 100);
    d.style.height = (30 + h * 1.9) + 'px';
    d.style.background = 'linear-gradient(180deg,hsl(' + ((v * 9) % 360) + ' 85% 62%),hsl(' + ((v * 9 + 40) % 360) + ' 75% 45%))';
    d.innerHTML = v + '<i>' + i + '</i>';
    stage.appendChild(d);
  });
  document.getElementById('arr').textContent = 'const tab = [' + arr.join(', ') + '];';
  const sum = arr.reduce((s, x) => s + x, 0);
  const stats = [
    ['length', arr.length],
    ['suma (reduce)', sum],
    ['średnia', arr.length ? (sum / arr.length).toFixed(1) : '–'],
    ['min', arr.length ? Math.min(...arr) : '–'],
    ['max', arr.length ? Math.max(...arr) : '–']
  ];
  document.getElementById('stats').innerHTML = stats.map(s => '<div class="stat"><b>' + s[1] + '</b><span>' + s[0] + '</span></div>').join('');
}

const logs = [];
function log(code, note) {
  logs.unshift('<div>' + code + ' <em>// ' + note + '</em></div>');
  if (logs.length > 6) logs.pop();
  document.getElementById('log').innerHTML = logs.join('');
}

const ops = {
  push() { const n = rnd(); arr.push(n); log('tab.push(' + n + ')', 'dodano na końcu'); },
  pop() { const r = arr.pop(); log('tab.pop()', r === undefined ? 'zwróciło undefined' : 'zwróciło ' + r); },
  unshift() { const n = rnd(); arr.unshift(n); log('tab.unshift(' + n + ')', 'dodano na początku'); },
  shift() { const r = arr.shift(); log('tab.shift()', r === undefined ? 'zwróciło undefined' : 'zwróciło ' + r); },
  splice() { const r = arr.splice(1, 1); log('tab.splice(1, 1)', r.length ? 'usunięto ' + r[0] + ' z indeksu 1' : 'brak elementu na indeksie 1'); },
  map() { arr = arr.map(x => x * 2); log('tab = tab.map(x => x * 2)', 'nowa tablica, każdy element razy 2'); },
  filter() { const before = arr.length; arr = arr.filter(x => x % 2 === 0); log('tab = tab.filter(x => x % 2 === 0)', 'zostało ' + arr.length + ' z ' + before); },
  big() { const before = arr.length; arr = arr.filter(x => x > 15); log('tab = tab.filter(x => x > 15)', 'zostało ' + arr.length + ' z ' + before); },
  sort() { arr.sort((a, b) => a - b); log('tab.sort((a, b) => a - b)', 'rosnąco, zmienia tablicę w miejscu'); },
  reverse() { arr.reverse(); log('tab.reverse()', 'odwrócona kolejność'); },
  reset() { fresh(); log('tab = Array.from({length: 7}, losowa)', 'nowa tablica'); }
};

document.querySelectorAll('button[data-op]').forEach(b =>
  b.addEventListener('click', () => { ops[b.dataset.op](); render(); })
);
fresh();
render();
log('const tab = [...]', 'zacznij od klikania metod');
</script>
</body>
</html>