خزانة الطاقة (حبيت انزلها وخلاص)
htmlv1MITنُشر ١ أكتوبر ٢٠٢٦· ♥ 0 · ⬇ 1 · 💬 0
على أساس نظرية الملاعق (Spoon Theory): كل يوم عندك 100 وحدة طاقة. كل نشاط يسحب أو يضيف. الأداة بتحسبلك المتبقي، وتوريك الأنماط: إيه اللي بيفرّغك؟ إيه اللي بيعمّرك؟ مفيدة لأصحاب الأمراض المزمنة، ADHD، والاحتراق الوظيفي.
<!DOCTYPE html>
<html lang="ar" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>خزانة الطاقة</title>
<link href="https://fonts.googleapis.com/css2?family=Tajawal:wght@400;500;700;800&display=swap" rel="stylesheet">
<style>
*{box-sizing:border-box;margin:0;padding:0}
:root{--bg:#0d0f14;--panel:#151920;--panel2:#1c222c;--line:#ffffff10;--ink:#eef2f7;--mut:#8894a5;--amber:#ffb020;--amber2:#ff8c42;--green:#4ade80;--red:#ff5a5a;--blue:#5ac8ff;--purple:#a78bfa}
body{font-family:Tajawal,Tahoma,sans-serif;background:var(--bg);color:var(--ink);min-height:100dvh;line-height:1.7}
body::before{content:"";position:fixed;inset:0;background:radial-gradient(ellipse 60% 40% at 50% 0%,rgba(255,176,32,.12),transparent 60%),radial-gradient(ellipse 40% 30% at 90% 100%,rgba(167,139,250,.08),transparent);pointer-events:none}
.wrap{position:relative;max-width:1120px;margin:0 auto;padding:24px 18px 60px}
header{text-align:center;margin-bottom:28px}
header .logo{display:inline-flex;align-items:center;gap:12px;margin-bottom:6px}
header .batt{width:44px;height:22px;border:2px solid var(--amber);border-radius:5px;position:relative;padding:2px}
header .batt::after{content:"";position:absolute;right:-6px;top:50%;transform:translateY(-50%);width:4px;height:10px;background:var(--amber);border-radius:0 2px 2px 0}
header .batt i{display:block;height:100%;width:80%;background:linear-gradient(90deg,var(--amber),var(--amber2));border-radius:2px}
header h1{font-size:1.6rem;font-weight:800;display:inline}
header p{color:var(--mut);font-size:.88rem;margin-top:4px}
.top{display:grid;grid-template-columns:1.2fr 1fr;gap:20px;margin-bottom:24px}
@media(max-width:900px){.top{grid-template-columns:1fr}}
.battery-card{background:var(--panel);border:1px solid var(--line);border-radius:22px;padding:24px;text-align:center;position:relative;overflow:hidden}
.battery-card::before{content:"";position:absolute;top:0;left:0;right:0;height:3px;background:linear-gradient(90deg,var(--amber),var(--amber2),var(--green));opacity:.6}
.battery-card .day{font-size:.85rem;color:var(--mut);letter-spacing:2px;text-transform:uppercase;font-weight:700;margin-bottom:6px}
.battery-card .num{font-size:clamp(3rem,10vw,4.5rem);font-weight:900;line-height:1;font-variant-numeric:tabular-nums;color:var(--amber);transition:color .4s}
.battery-card .of{font-size:.9rem;color:var(--mut);margin-top:2px}
.battery-card .bigbar{height:26px;background:rgba(255,255,255,.05);border-radius:99px;overflow:hidden;margin:20px 0 10px;position:relative;border:1px solid var(--line)}
.battery-card .bigbar i{display:block;height:100%;background:linear-gradient(90deg,var(--green),var(--amber),var(--amber2));border-radius:99px;transition:width .8s cubic-bezier(.2,.8,.2,1);width:0;box-shadow:0 0 20px rgba(255,176,32,.4) inset}
.battery-card .lbl-row{display:flex;justify-content:space-between;font-size:.78rem;color:var(--mut)}
.quick{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-top:18px}
.quick button{background:var(--panel2);border:1px solid var(--line);border-radius:12px;padding:10px 6px;font-family:inherit;font-size:.78rem;color:var(--ink);cursor:pointer;transition:.2s;display:flex;flex-direction:column;align-items:center;gap:4px}
.quick button:hover{border-color:var(--amber);transform:translateY(-2px)}
.quick button .em{font-size:1.2rem}
.quick button .d{font-size:.72rem;font-weight:700;color:var(--mut)}
.quick button.up .d{color:var(--green)}
.quick button.down .d{color:var(--red)}
.add-panel{background:var(--panel);border:1px solid var(--line);border-radius:22px;padding:22px}
.add-panel h3{font-size:.95rem;font-weight:800;margin-bottom:14px;display:flex;align-items:center;gap:8px}
.add-panel h3 .em{font-size:1.1rem}
.add-panel .field{margin-bottom:12px}
.add-panel label{display:block;font-size:.78rem;color:var(--mut);font-weight:600;margin-bottom:4px}
.add-panel input,.add-panel select{width:100%;background:rgba(0,0,0,.3);border:1px solid var(--line);border-radius:10px;padding:10px 12px;font-family:inherit;font-size:.92rem;color:var(--ink);outline:none}
.add-panel input:focus,.add-panel select:focus{border-color:var(--amber)}
.add-panel .row{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.val-slider{display:flex;align-items:center;gap:10px}
.val-slider input{flex:1;padding:0;background:transparent;border:0;accent-color:var(--amber)}
.val-slider .v{font-weight:800;min-width:48px;text-align:center;font-variant-numeric:tabular-nums}
.val-slider .v.up{color:var(--green)}
.val-slider .v.down{color:var(--red)}
.btn-add{width:100%;margin-top:8px;border:0;padding:13px;background:linear-gradient(135deg,var(--amber),var(--amber2));color:#1a0f00;font-family:inherit;font-weight:800;font-size:.95rem;border-radius:12px;cursor:pointer;transition:.2s;letter-spacing:.5px}
.btn-add:hover{transform:translateY(-2px)}
.log{background:var(--panel);border:1px solid var(--line);border-radius:22px;padding:22px}
.log h3{font-size:1rem;font-weight:800;margin-bottom:14px;display:flex;align-items:center;justify-content:space-between}
.log h3 .count{font-size:.75rem;font-weight:600;color:var(--mut);background:rgba(255,255,255,.05);padding:3px 10px;border-radius:99px}
.list{display:flex;flex-direction:column;gap:8px;max-height:420px;overflow-y:auto;padding-right:4px}
.item{display:grid;grid-template-columns:auto 1fr auto auto;gap:12px;align-items:center;background:var(--panel2);border:1px solid var(--line);border-radius:12px;padding:12px 14px;transition:.2s}
.item:hover{border-color:rgba(255,176,32,.3)}
.item .em{width:36px;height:36px;border-radius:10px;background:rgba(255,176,32,.12);display:grid;place-items:center;font-size:1.15rem;flex:none}
.item .info{min-width:0}
.item .nm{font-weight:600;font-size:.94rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.item .tm{font-size:.72rem;color:var(--mut);margin-top:2px}
.item .val{font-weight:800;font-variant-numeric:tabular-nums;font-size:1rem;min-width:44px;text-align:center}
.item .val.up{color:var(--green)}
.item .val.down{color:var(--red)}
.item .del{background:transparent;border:0;color:var(--mut);cursor:pointer;font-size:1rem;padding:4px 8px;border-radius:6px}
.item .del:hover{color:var(--red);background:rgba(255,90,90,.1)}
.empty{text-align:center;padding:40px 16px;color:var(--mut);font-size:.9rem}
.empty .em{font-size:2.5rem;opacity:.3;margin-bottom:10px}
@media(max-width:520px){.wrap{padding:18px 12px 40px}header h1{font-size:1.3rem}.battery-card,.add-panel,.log{padding:18px}.quick{grid-template-columns:repeat(2,1fr)}}
</style>
</head>
<body>
<div class="wrap">
<header>
<div class="logo"><div class="batt"><i></i></div><h1>خزانة الطاقة</h1></div>
<p>كل يوم عندك 100 وحدة — شوف بتروح فين</p>
</header>
<div class="top">
<div class="battery-card">
<div class="day" id="todayLabel">اليوم</div>
<div class="num" id="rem">100</div>
<div class="of">وحدة متبقية من 100</div>
<div class="bigbar"><i id="fill"></i></div>
<div class="lbl-row"><span>سحب <b id="drained" style="color:var(--red)">0</b></span><span>إضافة <b id="charged" style="color:var(--green)">0</b></span></div>
<div class="quick" id="quick">
<button class="down" data-name="نوم متأخر" data-v="-12"><span class="em">🌙</span><span>نوم متأخر</span><span class="d">-12</span></button>
<button class="down" data-name="اجتماع" data-v="-15"><span class="em">💼</span><span>اجتماع</span><span class="d">-15</span></button>
<button class="down" data-name="زحمة مواصلات" data-v="-10"><span class="em">🚗</span><span>مواصلات</span><span class="d">-10</span></button>
<button class="up" data-name="مشي قصير" data-v="+8"><span class="em">🚶</span><span>مشي</span><span class="d">+8</span></button>
<button class="up" data-name="قهوة / شاي" data-v="+5"><span class="em">☕</span><span>قهوة</span><span class="d">+5</span></button>
<button class="up" data-name="حديث مع صديق" data-v="+10"><span class="em">💬</span><span>حديث مع صديق</span><span class="d">+10</span></button>
</div>
</div>
<div class="add-panel">
<h3><span class="em">➕</span> سجّل نشاط</h3>
<div class="field"><label>النشاط</label><input type="text" id="name" placeholder="مثال: مكالمة عمل، نوم، تمرين..."></div>
<div class="row">
<div class="field"><label>النوع</label><select id="sign"><option value="-1">يسحب طاقة (سالب)</option><option value="1">يضيف طاقة (موجب)</option></select></div>
<div class="field"><label>المقدار</label>
<div class="val-slider"><input type="range" id="val" min="1" max="30" value="10"><span class="v down" id="valv">−10</span></div>
</div>
</div>
<button class="btn-add" id="add">أضف للسجل</button>
</div>
</div>
<div class="log">
<h3>سجل النهاردة <span class="count" id="cnt">0 نشاط</span></h3>
<div class="list" id="list"><div class="empty"><div class="em">📋</div>لسه مفيش نشاط مسجّل<br>استخدم الأزرار السريعة فوق أو أضف نشاطك</div></div>
</div>
</div>
<script>
const $=id=>document.getElementById(id);
const KEY='khazna_taqa_v1';
const DAY=new Date().toDateString();
let store={day:DAY,items:[]};
try{const s=JSON.parse(localStorage.getItem(KEY)||'{}');if(s.day===DAY)store=s}catch(e){}
function save(){localStorage.setItem(KEY,JSON.stringify(store))}
function render(){
const drained=store.items.filter(i=>i.v<0).reduce((a,b)=>a+Math.abs(b.v),0);
const charged=store.items.filter(i=>i.v>0).reduce((a,b)=>a+b.v,0);
const rem=Math.max(0,Math.min(100,100-drained+charged));
$('rem').textContent=rem;
$('fill').style.width=rem+'%';
$('drained').textContent=drained;
$('charged').textContent=charged;
$('rem').style.color=rem>60?'var(--green)':rem>30?'var(--amber)':'var(--red)';
$('todayLabel').textContent=new Intl.DateTimeFormat('ar-EG',{weekday:'long',day:'numeric',month:'long'}).format(new Date());
$('cnt').textContent=store.items.length+' نشاط';
if(!store.items.length){$('list').innerHTML='<div class="empty"><div class="em">📋</div>لسه مفيش نشاط مسجّل<br>استخدم الأزرار السريعة فوق أو أضف نشاطك</div>';return}
const sorted=[...store.items].sort((a,b)=>b.t-a.t);
$('list').innerHTML=sorted.map(it=>`<div class="item">
<div class="em">${it.v>0?'⚡':'🔻'}</div>
<div class="info"><div class="nm">${esc(it.name)}</div><div class="tm">${new Date(it.t).toLocaleTimeString('ar-EG',{hour:'2-digit',minute:'2-digit'})}</div></div>
<div class="val ${it.v>0?'up':'down'}">${it.v>0?'+':''}${it.v}</div>
<button class="del" data-id="${it.id}">✕</button>
</div>`).join('');
$('list').querySelectorAll('.del').forEach(b=>b.onclick=()=>{store.items=store.items.filter(x=>x.id!==b.dataset.id);save();render()});
}
function esc(s){return String(s).replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''})[c])}
function push(name,v){
if(!name)return;
store.items.push({id:Date.now()+Math.random().toString(36).slice(2,5),name,v,t:Date.now()});
save();render();
}
$('sign').addEventListener('change',()=>{const v=+$('val').value,s=+$('sign').value;$('valv').textContent=(s<0?'−':'+')+v;$('valv').className='v '+(s<0?'down':'up')});
$('val').addEventListener('input',()=>{const v=+$('val').value,s=+$('sign').value;$('valv').textContent=(s<0?'−':'+')+v});
$('add').onclick=()=>{const n=$('name').value.trim();if(!n)return alert('اكتب اسم النشاط');push(n,(+$('sign').value)*(+$('val').value));$('name').value=''};
$('name').addEventListener('keydown',e=>{if(e.key==='Enter')$('add').click()});
$('quick').querySelectorAll('button').forEach(b=>b.onclick=()=>push(b.dataset.name,+b.dataset.v));
render();
</script>
</body>
</html>
التعليقات (1)
جميل
سجّل الدخول للتعليق.