{"id":93,"date":"2026-08-31T20:58:49","date_gmt":"2026-08-31T20:58:49","guid":{"rendered":"https:\/\/onbrand.dk\/?page_id=93"},"modified":"2026-08-31T21:00:38","modified_gmt":"2026-08-31T21:00:38","slug":"breakdance-93","status":"publish","type":"page","link":"https:\/\/onbrand.dk\/index.php\/breakdance-93\/","title":{"rendered":"Breakdance &#8211; 93"},"content":{"rendered":"<main id='bde-main'><section class=\"bde-section-93-100 bde-section\">\n  \n  \n\t\n\n\n\n<div class=\"section-container\"><div class=\"bde-code-block-93-101 bde-code-block\">\n\n  <!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  {transform: rotate(90deg);}\n  <meta charset=\"UTF-8\" \/>\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" \/>\n  <title>KATIR<\/title>\n  <style>\n    :root{\n      --bg:#0f172a; --panel:#111827; --muted:#334155; --text:#e5e7eb; --ring:#94a3b8;\n      --yellow:#f59e0b; --blue:#3b82f6; --red:#ef4444; --black:#616161; --white:#45db3d;\n      --ok:#ffffff;\n    }\n    *{box-sizing:border-box}\n    html,body{height:100%; overflow:hidden}\n    body{margin:0; font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,Arial; background:#0b1222; color:var(--text)}\n\n    \/* --- screen rotation shell --- *\/\n    #rotator{\n      position:fixed;\n      top:50%; left:50%;\n      overflow:auto;\n      -webkit-overflow-scrolling:touch;\n      container-type:size;\n      container-name:screen;\n    }\n    \/* upright: box matches viewport *\/\n    #rotator.rot-0{ width:100vw; height:100dvh; transform:translate(-50%,-50%) rotate(0deg); }\n    #rotator.rot-180{ width:100vw; height:100dvh; transform:translate(-50%,-50%) rotate(180deg); }\n    \/* sideways: box dimensions swap, so the rotated result fills the viewport *\/\n    #rotator.rot-90{ width:100dvh; height:100vw; transform:translate(-50%,-50%) rotate(90deg); }\n    #rotator.rot-270{ width:100dvh; height:100vw; transform:translate(-50%,-50%) rotate(270deg); }\n\n    .wrap{max-width:1380px; margin:0 auto; padding:10px; height:100%; display:grid; grid-template-columns:1.15fr .85fr; gap:10px}\n    \/* container queries, not media queries: they measure the rotated box, not the device *\/\n    @container screen (max-width: 1024px){ .wrap{grid-template-columns:1fr; grid-template-rows:auto 1fr; height:auto; min-height:100%} }\n\n    .card{background:rgba(17,24,39,.92); border:1px solid #1f2937; border-radius:14px; padding:10px}\n    .row{display:flex; align-items:center}\n    .col{display:flex; flex-direction:column}\n    .g8{gap:8px} .g10{gap:10px} .g6{gap:6px}\n\n    .title{font-size:24px; font-weight:900}\n    .chip{border:1px solid #334155; border-radius:999px; padding:5px 10px; font-size:13px}\n\n    input[type=\"text\"], input[type=\"number\"]{background:#0b1220; color:var(--text); border:1px solid #334155; border-radius:10px; padding:10px; font-size:16px}\n\n    .btn{border:1px solid #374151; background:#0b1220; color:var(--text); padding:10px 12px; border-radius:12px; cursor:pointer; transition:.14s; font-weight:800; min-height:40px; min-width:42px; font-size:15px; user-select:none; position:relative; overflow:hidden}\n    .btn:hover{transform:translateY(-1px); border-color:var(--ring)}\n    .btn:active{transform:translateY(0)}\n    .btn.ghost{background:#0b1220}\n    .btn.main{background:linear-gradient(135deg,#1f2937,#0b1220)}\n    .btn.bad{background:rgba(239,68,68,.28); border-color:#ef4444}\n\n    .flash{box-shadow:0 0 0 2px var(--ok) inset; animation:flash .22s ease}\n    @keyframes flash{0%{transform:scale(.98)}100%{transform:scale(1)}}\n    .pulse{animation:pulse .4s ease}\n    @keyframes pulse{0%{transform:scale(1)}50%{transform:scale(1.08)}100%{transform:scale(1)}}\n\n    .dealer{outline:2px solid var(--ok)}\n    .winner{background:rgba(34,197,94,.08)} \/* legacy *\/\n\n    table{width:100%; border-collapse:separate; border-spacing:0; border-radius:12px; overflow:hidden; border:1px solid #1f2937}\n    th,td{padding:10px; border-bottom:1px solid #1f2937; text-align:center; font-size:15px}\n    th:first-child,td:first-child{text-align:left}\n    tr:last-child td{border-bottom:none}\n\n    .grid-players{display:grid; grid-template-columns:repeat(2,minmax(280px,1fr)); gap:10px}\n    .grid-controls{display:grid; grid-template-columns:repeat(2,minmax(300px,1fr)); gap:10px}\n    @container screen (max-width: 640px){ .grid-controls, .grid-players{grid-template-columns:1fr} }\n\n    .quick{display:grid; grid-template-columns:repeat(7,1fr); gap:6px}\n\n    \/* round log *\/\n    .log{max-height:120px; overflow:auto; font-size:12px; line-height:1.35;\n         background:#0b1220; border:1px solid #1f2937; border-radius:10px; padding:8px; margin-top:8px}\n    .log b{font-weight:800}\n\n    \/* editable score inputs in table *\/\n    .score-input{\n      width:100%;\n      background:transparent;\n      border:none;\n      color:inherit;\n      text-align:center;\n      font:inherit;\n      padding:0;\n      outline:none;\n      -moz-appearance:textfield;\n    }\n    .score-input::-webkit-outer-spin-button,\n    .score-input::-webkit-inner-spin-button{\n      -webkit-appearance:none;\n      margin:0;\n    }\n         \/* Auto-shrink large score text *\/\n.shrink {\n  font-size: 13px !important;\n}\n  <\/style>\n<\/head>\n<body>\n  <div id=\"rotator\" class=\"rot-90\">\n  <div class=\"wrap\">\n    <!-- Left: Controls -->\n    <div class=\"card\" style=\"display:flex; flex-direction:column; gap:8px\">\n      <div class=\"row g8\" style=\"justify-content:space-between; flex-wrap:wrap\">\n        <div class=\"title\">KATIR<\/div>\n        <div class=\"row g8\" style=\"flex-wrap:wrap\">\n          <div id=\"colorBtns\" class=\"row g6\">\n            <button class=\"btn\" data-color=\"yellow\" title=\"x3\">\ud83d\udfe1<\/button>\n            <button class=\"btn\" data-color=\"blue\"   title=\"x4\">\ud83d\udd35<\/button>\n            <button class=\"btn\" data-color=\"red\"    title=\"x5\">\ud83d\udd34<\/button>\n            <button class=\"btn\" data-color=\"black\"  title=\"x6\">\u26aa<\/button>\n            <button class=\"btn\" data-color=\"white\"  title=\"x7\">\ud83d\udfe2<\/button>\n          <\/div>\n          <button id=\"undoBtn\" class=\"btn\">Undo<\/button>\n          <button id=\"resetBtn\" class=\"btn ghost\">Reset<\/button>\n          <button id=\"rotateBtn\" class=\"btn ghost\" title=\"Turn the screen 90\u00b0\">\u27f3<\/button>\n          <label class=\"row g6\"><input type=\"checkbox\" id=\"partnerToggle\"\/> <span class=\"chip\">Partners<\/span><\/label>\n        <\/div>\n      <\/div>\n\n      <div class=\"grid-players\">\n        <input id=\"p0\" placeholder=\"Enes\" value=\"Enes\"\/>\n        <input id=\"p1\" placeholder=\"Ismail\" value=\"Ismail\"\/>\n        <input id=\"p2\" placeholder=\"Tolga\" value=\"Tolga\"\/>\n        <input id=\"p3\" placeholder=\"Mustafa\" value=\"Mustafa\"\/>\n      <\/div>\n\n      <div class=\"row g10\" style=\"flex-wrap:wrap\">\n        <span class=\"chip\">R: <b id=\"roundLabel\">1\/9<\/b><\/span>\n        <span class=\"chip\">Dealer: <b id=\"dealerLabel\">Player 1<\/b><\/span>\n      <\/div>\n\n      <div id=\"controls\" class=\"grid-controls\"><\/div>\n\n      <div class=\"card\" style=\"background:#0b1220\">\n        <div class=\"row g8\" style=\"flex-wrap:wrap; align-items:center; justify-content:space-between\">\n          <div class=\"row g6\" id=\"winnerPick\">Winner:<\/div>\n          <div class=\"row g6\">\n            <!-- \u2b50 joker-finish toggle -->\n            <label class=\"row g6\" title=\"Winner finished with okey in the middle\">\n              <input type=\"checkbox\" id=\"jokerFinishToggle\" \/>\n              <span>\u2b50<\/span>\n            <\/label>\n            <button id=\"patBtn\" class=\"btn ghost\" title=\"No winner\">Pat<\/button>\n            <button id=\"endRoundBtn\" class=\"btn main\">End Round<\/button>\n          <\/div>\n        <\/div>\n        <div id=\"leftovers\" class=\"row g6\" style=\"flex-wrap:wrap; margin-top:8px\"><\/div>\n\n        <!-- Round log (minimal, no heading) -->\n        <div id=\"roundLog\" class=\"log\"><\/div>\n      <\/div>\n    <\/div>\n\n    <!-- Right: Scores -->\n    <div class=\"card\" style=\"display:flex; flex-direction:column\">\n      <div class=\"row g8\" style=\"justify-content:space-between; align-items:center\">\n        <div class=\"title\">Scores<\/div>\n        <div id=\"teamBox\" class=\"chip\" style=\"display:none\"><\/div>\n      <\/div>\n      <div style=\"flex:1; overflow:auto; margin-top:6px\">\n        <table id=\"scoreTable\"><\/table>\n      <\/div>\n    <\/div>\n  <\/div>\n  <\/div>\n\n<script>\n(function(){\n  const ROUNDS=9, PLAYERS=4, STORAGE_KEY='katir_clean_v1', ROT_KEY='katir_rotation';\n  const MULT={yellow:3, blue:4, red:5, black:6, white:7};\n  const COLORS={\n    yellow:getCSS('--yellow'),\n    blue:getCSS('--blue'),\n    red:getCSS('--red'),\n    black:getCSS('--black'),\n    white:getCSS('--white')\n  };\n  function getCSS(v){return getComputedStyle(document.documentElement).getPropertyValue(v).trim();}\n\n  \/\/ --- color helpers for score table tinting ---\n  function parseColor(str){\n    if(!str) return {r:255,g:255,b:255};\n    str = String(str).trim();\n    if(str.startsWith('#')){\n      const r = parseInt(str.slice(1,3),16);\n      const g = parseInt(str.slice(3,5),16);\n      const b = parseInt(str.slice(5,7),16);\n      return {r,g,b};\n    } else if(str.startsWith('rgb')){\n      const m = str.match(\/rgba?\\((\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\/i);\n      if(m) return {r:+m[1], g:+m[2], b:+m[3]};\n    }\n    return {r:255,g:255,b:255};\n  }\n  function rgbaFromKey(key, alpha){\n    const {r,g,b} = parseColor(COLORS[key]);\n    return `rgba(${r},${g},${b},${alpha})`;\n  }\n\n  const state={\n    players:[\"Player 1\",\"Player 2\",\"Player 3\",\"Player 4\"],\n    round:1,\n    perRound:Array.from({length:ROUNDS},()=>Array(PLAYERS).fill(0)),\n    roundColor:Array(ROUNDS).fill(null), \/\/ chosen at start\n    winnerIndex:Array(ROUNDS).fill(null),\n    pat:Array(ROUNDS).fill(false),\n    leftovers:Array.from({length:ROUNDS},()=>Array(PLAYERS).fill(0)), \/\/ raw leftover values before multiplier\n    locked:Array(ROUNDS).fill(false),\n    history:[],                         \/\/ global history of score changes\n    partner:false,\n    jokerFinish:Array(ROUNDS).fill(false) \/\/ \u2b50 finish per round\n  };\n\n  \/\/ DOM refs\n  const ids=s=>document.getElementById(s);\n  const pInputs=[0,1,2,3].map(i=>ids('p'+i));\n  const colorBtns=ids('colorBtns');\n  const undoBtn=ids('undoBtn');\n  const partnerToggle=ids('partnerToggle');\n  const roundLabel=ids('roundLabel');\n  const dealerLabel=ids('dealerLabel');\n  const controls=ids('controls');\n  const winnerPick=ids('winnerPick');\n  const leftoversWrap=ids('leftovers');\n  const endRoundBtn=ids('endRoundBtn');\n  const patBtn=ids('patBtn');\n  const scoreTable=ids('scoreTable');\n  const teamBox=ids('teamBox');\n  const roundLog=ids('roundLog');\n  const resetBtn = document.getElementById('resetBtn');\n  const jokerFinishToggle = document.getElementById('jokerFinishToggle');\n  const rotator = document.getElementById('rotator');\n  const rotateBtn = document.getElementById('rotateBtn');\n\n  \/\/ --- rotation ---\n  let rotation = 90;\n  try{\n    const saved = Number(localStorage.getItem(ROT_KEY));\n    if([0,90,180,270].includes(saved)) rotation = saved;\n  }catch{}\n  function applyRotation(){\n    rotator.className = 'rot-' + rotation;\n    try{ localStorage.setItem(ROT_KEY, String(rotation)); }catch{}\n  }\n\n  function save(){localStorage.setItem(STORAGE_KEY, JSON.stringify(state));}\n  function load(){\n    try{\n      const raw=localStorage.getItem(STORAGE_KEY);\n      if(raw){\n        Object.assign(state, JSON.parse(raw));\n      }\n    }catch{}\n    \/\/ safety for old saves\n    if(!Array.isArray(state.history)) state.history=[];\n    if(!Array.isArray(state.jokerFinish)) state.jokerFinish = Array(ROUNDS).fill(false);\n  }\n  function dealer(){return (state.round-1)%PLAYERS}\n\n  function press(btn){if(!btn) return; btn.classList.remove('flash'); void btn.offsetWidth; btn.classList.add('flash'); setTimeout(()=>btn.classList.remove('flash'),220)}\n\n  \/\/ simple logger (prepends newest line)\n  function log(msg){\n    const time=new Date().toLocaleTimeString();\n    roundLog.innerHTML = `<div>[${time}] ${msg}<\/div>` + roundLog.innerHTML;\n  }\n  function clearLog(){ roundLog.innerHTML=''; }\n\n  function renderTop(){\n    \/\/ color buttons\n    const r=state.round-1; const c=state.roundColor[r];\n    Array.from(colorBtns.querySelectorAll('button')).forEach(b=>{\n      const key=b.dataset.color;\n      b.style.opacity = c===key? '1':'0.6';\n      b.style.outline = c===key? `2px solid ${COLORS[key]}`:'1px solid #374151';\n      b.onclick=(ev)=>{\n        if(state.locked[r]) return;\n        press(ev.currentTarget);\n        state.roundColor[r]=key;\n        save();\n        renderAll();\n      };\n    });\n    \/\/ labels\n    roundLabel.textContent=`${state.round}\/9`;\n    dealerLabel.textContent=state.players[dealer()];\n\n    \/\/ \u2b50 joker finish toggle state\n    jokerFinishToggle.checked = !!state.jokerFinish[r];\n  }\n\n  function renderNames(){\n    pInputs.forEach((el,i)=>{\n      el.value=state.players[i];\n      el.onchange=()=>{\n        state.players[i]=el.value||`Player ${i+1}`;\n        save();\n        renderAll();\n      };\n    });\n  }\n\n  function addPenalty(p,delta){\n    const r=state.round-1; if(state.locked[r]) return;\n    state.perRound[r][p]+=delta;\n    \/\/ record change in global history\n    state.history.push({round:r, player:p, delta});\n    save();\n    renderTable();\n    const tag=document.getElementById(`rt-${p}`);\n    if(tag){\n      tag.textContent=state.perRound[r][p];\n      tag.classList.remove('pulse'); void tag.offsetWidth; tag.classList.add('pulse');\n    }\n    log(`${state.players[p]} ${delta>0?'+':''}${delta}`);\n  }\n\n  function renderControls(){\n    controls.innerHTML=''; leftoversWrap.innerHTML='';\n    const r=state.round-1; const c=state.roundColor[r];\n    for(let i=0;i<PLAYERS;i++){\n      const box=document.createElement('div'); box.className='card'; box.style.background='#0b1220';\n      if(i===dealer()){\n        box.classList.add('dealer');\n        box.style.outlineColor = c? COLORS[c] : 'var(--ok)';\n      }\n      const head=document.createElement('div'); head.className='row g8'; head.style.justifyContent='space-between';\n      head.innerHTML=`<div style=\"font-weight:800\">${state.players[i]} ${i===dealer()?'<span class=\"chip\">Dealer<\/span>':''}<\/div><div class=\"chip\">Round <span id=\"rt-${i}\">${state.perRound[r][i]}<\/span><\/div>`;\n      box.appendChild(head);\n\n      \/\/ custom + add\n      const grid=document.createElement('div'); grid.className='row g8';\n      const num=document.createElement('input'); num.type='number'; num.placeholder='Custom'; num.step='10'; num.min='-9999'; num.style.flex='1';\n      const add=document.createElement('button'); add.className='btn main'; add.textContent='Add';\n      add.onclick=(ev)=>{\n        const v=Number(num.value);\n        if(!Number.isFinite(v)) return;\n        press(ev.currentTarget);\n        addPenalty(i,v);\n        num.value='';\n      };\n      grid.appendChild(num); grid.appendChild(add); box.appendChild(grid);\n\n      \/\/ quick buttons 10..130 and 250 (red)\n      const quick=document.createElement('div'); quick.className='quick';\n      for(let q=10;q<=130;q+=10){\n        const b=document.createElement('button'); b.className='btn ghost'; b.textContent=`+${q}`;\n        b.onclick=(ev)=>{press(ev.currentTarget); addPenalty(i,q);};\n        quick.appendChild(b);\n      }\n      const b250=document.createElement('button'); b250.className='btn bad'; b250.textContent='+250';\n      b250.onclick=(ev)=>{press(ev.currentTarget); addPenalty(i,250);};\n      quick.appendChild(b250);\n      box.appendChild(quick);\n      controls.appendChild(box);\n\n      \/\/ leftovers input for end-of-round penalties (multiplied later)\n      const lo=document.createElement('input'); lo.type='number'; lo.placeholder=`Elde kalan \u2013 ${state.players[i]}`; lo.value = state.leftovers[r][i] || '';\n      lo.onchange=()=>{ state.leftovers[r][i]=Number(lo.value)||0; save(); };\n      leftoversWrap.appendChild(lo);\n    }\n  }\n\n  function renderWinnerPick(){\n    const r=state.round-1; winnerPick.innerHTML='Winner:';\n    for(let i=0;i<PLAYERS;i++){\n      const inp=document.createElement('input'); inp.type='radio'; inp.name='w'; inp.value=String(i);\n      if(state.winnerIndex[r]===i) inp.checked=true;\n      inp.onchange=()=>{ state.winnerIndex[r]=i; save(); };\n      winnerPick.appendChild(inp);\n      const txt=document.createElement('span'); txt.textContent=' '+state.players[i]+' ';\n      winnerPick.appendChild(txt);\n    }\n  }\n\nfunction endRound(pat){\n  const r=state.round-1;\n  if(state.locked[r]) return;\n\n  const color=state.roundColor[r];\n  if(!color){\n    alert('Pick color');\n    return;\n  }\n\n  const w=state.winnerIndex[r];\n\n  \/\/ \u2757 New rule: non-Pat rounds must have a winner\n  if(!pat && (w === null || w === undefined)){\n    alert('Pick a winner');\n    return;\n  }\n\n  state.pat[r]=!!pat;\n  const mult=MULT[color];\n  const doubleWinner = !!state.jokerFinish[r]; \/\/ \u2b50 => double bonus\n  const bonusMult = mult * (doubleWinner ? 2 : 1);\n\n  \/\/ apply leftovers * multiplier to all non-winners (if Pat, everyone is non-winner)\n  for(let i=0;i<PLAYERS;i++){\n    if(pat || i!==w){\n      const raw = Number(state.leftovers[r][i])||0;\n      const add = raw * mult; \/\/ leftovers always use normal multiplier\n      if(add !== 0){\n        state.perRound[r][i]+= add;\n        state.history.push({round:r, player:i, delta:add});\n        log(`${state.players[i]} +${add} (leftover ${raw}\u00d7${mult})`);\n      }\n    }\n  }\n\n  \/\/ apply winner bonus if any\n  if(!pat && w!=null){\n    const bonus = -100*bonusMult;\n    state.perRound[r][w] += bonus;\n    state.history.push({round:r, player:w, delta:bonus});\n    log(`${state.players[w]} ${bonus} (winner bonus${doubleWinner?' \u2b50':''})`);\n  } else if(pat){\n    log(`Pat \u2013 no winner bonus`);\n  }\n\n  state.locked[r]=true;\n  save();\n\n  if(state.round<ROUNDS){\n    state.round++;\n    \/\/ log stays (persistent across rounds)\n  } else {\n    const totals=getTotals(); const min=Math.min(...totals); const idx=totals.indexOf(min);\n    alert(`Game finished: ${state.players[idx]} (${min})`);\n  }\n\n  renderAll();\n}\n\n\n  function undo(){\n    const last = state.history.pop();\n    if(!last) return;\n    const {round, player, delta} = last;\n    state.perRound[round][player] -= delta;\n    save();\n    renderAll();\n    log(`Undo: ${state.players[player]} ${delta>0?'-':''}${-delta}`);\n  }\n\n  function reset() {\n    if (!confirm('Reset?')) return;\n    state.players = [\"Enes\",\"Ismail\",\"Tolga\",\"Mustafa\"];\n    state.round = 1;\n    state.perRound = Array.from({length:ROUNDS},()=>Array(PLAYERS).fill(0));\n    state.roundColor = Array(ROUNDS).fill(null);\n    state.winnerIndex = Array(ROUNDS).fill(null);\n    state.pat = Array(ROUNDS).fill(false);\n    state.leftovers = Array.from({length:ROUNDS},()=>Array(PLAYERS).fill(0));\n    state.locked = Array(ROUNDS).fill(false);\n    state.history = [];\n    state.jokerFinish = Array(ROUNDS).fill(false);\n    save();\n    clearLog();\n    renderAll();\n  }\n\n  function getTotals(){\n    const t=Array(PLAYERS).fill(0);\n    for(let r=0;r<ROUNDS;r++){\n      for(let p=0;p<PLAYERS;p++){\n        t[p]+=state.perRound[r][p];\n      }\n    }\n    return t;\n  }\n  function teamTotals(t){ return [t[0]+t[2], t[1]+t[3]]; }\n\n  \/\/ Score table with color coding + partner diff + editable cells\n  function renderTable(){\n    const headers=['','Player',...Array.from({length:ROUNDS},(_,i)=>`R${i+1}`),'Total'];\n    const totals=getTotals();\n\n    \/\/ header\n    let html = '<thead><tr>';\n    html += `<th><\/th><th>Player<\/th>`;\n    for(let r=0;r<ROUNDS;r++){\n      const key = state.roundColor[r];\n      const headStyle = key ? ` style=\"background:${rgbaFromKey(key,0.12)}\"` : '';\n      html += `<th${headStyle}>R${r+1}<\/th>`;\n    }\n    html += `<th>Total<\/th><\/tr><\/thead><tbody>`;\n\n    \/\/ rows\n    for(let p=0;p<PLAYERS;p++){\n      const dealerIcon=(p===dealer())?'\ud83c\udca0':'';\n      html+='<tr>';\n      html+=`<td>${dealerIcon}<\/td>`;\n      html+=`<td>${state.players[p]}<\/td>`;\n\n      for(let r=0;r<ROUNDS;r++){\n        const key = state.roundColor[r];\n        const isWinner = state.winnerIndex[r]===p && state.locked[r] && !state.pat[r];\n        const val = state.perRound[r][p];\n\n        let style = '';\n        if(key){\n          const base = rgbaFromKey(key, isWinner ? 0.24 : 0.12);\n          style = ` style=\"background:${base}`;\n          if(isWinner){\n            style += `;box-shadow:inset 0 0 0 2px ${COLORS[key]};font-weight:700`;\n          }\n          style += `\"`;\n        }\n\n        html+=`<td${style}><input class=\"score-input ${String(val).length > 4 ? 'shrink' : ''}\" type=\"number\" data-r=\"${r}\" data-p=\"${p}\" value=\"${val}\"><\/td>`;\n}\n\n      html+=`<td><b>${totals[p]}<\/b><\/td>`;\n      html+='<\/tr>';\n    }\n    html+='<\/tbody>';\n    scoreTable.innerHTML=html;\n\n    \/\/ attach listeners to editable cells\n    Array.from(scoreTable.querySelectorAll('.score-input')).forEach(inp=>{\n     inp.onchange = () => {\n  const r = Number(inp.dataset.r);\n  const p = Number(inp.dataset.p);\n  const oldVal = state.perRound[r][p];\n  const newVal = Number(inp.value) || 0;\n\n  \/\/ Apply shrink class if needed\n  if(String(newVal).length > 4) inp.classList.add('shrink');\n  else inp.classList.remove('shrink');\n\n        if(newVal === oldVal) return;\n        const delta = newVal - oldVal;\n        state.perRound[r][p] = newVal;\n        state.history.push({round:r, player:p, delta});\n        save();\n        renderTable(); \/\/ re-render totals & keep edits\n        log(`Manual edit: ${state.players[p]} R${r+1} ${oldVal}\u2192${newVal}`);\n      };\n    });\n\n    if(state.partner){\n      const [A,B]=teamTotals(totals); \/\/ A = P1+P3, B = P2+P4\n      let diffText;\n      if (A === B) {\n        diffText = ' | Diff: 0 (Tied)';\n      } else if (A < B) {\n        const diff = B - A;\n        diffText = ` |\ud83c\udfc5P1+P3\ud83c\udfc5${diff}`;\n      } else {\n        const diff = A - B;\n        diffText = ` |\ud83c\udfc5P2+P4\ud83c\udfc5${diff}`;\n      }\n\n      teamBox.style.display='inline-block';\n      teamBox.textContent=`P1+P3: ${A} | P2+P4: ${B}${diffText}`;\n    } else {\n      teamBox.style.display='none';\n      teamBox.textContent='';\n    }\n  }\n\n  function renderAll(){ renderTop(); renderNames(); renderControls(); renderWinnerPick(); renderTable(); }\n\n  \/\/ Wire-up\n  undoBtn.onclick=()=>undo();\n  resetBtn.onclick=reset;\n  rotateBtn.onclick=(ev)=>{ press(ev.currentTarget); rotation=(rotation+90)%360; applyRotation(); };\n  partnerToggle.onchange=()=>{ state.partner=partnerToggle.checked; save(); renderTable(); };\n  endRoundBtn.onclick=()=>endRound(false);\n  patBtn.onclick=()=>endRound(true);\n  jokerFinishToggle.onchange = () => {\n    const r = state.round-1;\n    state.jokerFinish[r] = jokerFinishToggle.checked;\n    save();\n  };\n\n  \/\/ init\n  applyRotation();\n  load();\n  partnerToggle.checked=!!state.partner;\n  renderAll();\n})();\n<\/script>\n<\/body>\n<\/html>\n\n\n<\/div><\/div>\n<\/section><\/main>","protected":false},"excerpt":{"rendered":"<p>{transform: rotate(90deg);} KATIR KATIR \ud83d\udfe1 \ud83d\udd35 \ud83d\udd34 \u26aa \ud83d\udfe2 Undo Reset \u27f3 Partners R: 1\/9 Dealer: Player 1 Winner: \u2b50 Pat End Round Scores<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_breakdance_hide_in_design_set":false,"_breakdance_tags":"","footnotes":""},"class_list":["post-93","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/onbrand.dk\/index.php\/wp-json\/wp\/v2\/pages\/93","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/onbrand.dk\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/onbrand.dk\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/onbrand.dk\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/onbrand.dk\/index.php\/wp-json\/wp\/v2\/comments?post=93"}],"version-history":[{"count":4,"href":"https:\/\/onbrand.dk\/index.php\/wp-json\/wp\/v2\/pages\/93\/revisions"}],"predecessor-version":[{"id":97,"href":"https:\/\/onbrand.dk\/index.php\/wp-json\/wp\/v2\/pages\/93\/revisions\/97"}],"wp:attachment":[{"href":"https:\/\/onbrand.dk\/index.php\/wp-json\/wp\/v2\/media?parent=93"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}