3v324v23 commited on
Commit
aa2dc4c
·
1 Parent(s): bf1986f

fix: enhance visual representation of lesson paths with new SVG elements and animations

Browse files
Files changed (1) hide show
  1. static/index.html +34 -14
static/index.html CHANGED
@@ -126,10 +126,21 @@ body.home:not(.manage) #toNow{bottom:76px} body.home:not(.manage) #logoutBtn{bot
126
  #dailyDlg{width:min(92vw,380px)}
127
  .path{--track:color-mix(in srgb,var(--muted) 75%,var(--bg));position:relative;width:100%;max-width:460px;margin:4px auto 72px;background:#101510 url("/static/assets/arabic-calligraphy-path.webp?v=7") top center/100% auto repeat-y}
128
  .road{position:absolute;left:50%;top:0;width:1px;height:100%;overflow:visible;pointer-events:none}
129
- .road path{fill:none;stroke:var(--line);stroke-width:12;stroke-linecap:round}
130
- .road .went{stroke:var(--olive)}
131
- .road .live{stroke:var(--olive);stroke-dasharray:1 21;animation:march 1.1s linear infinite}
132
- @keyframes march{to{stroke-dashoffset:-22}}
 
 
 
 
 
 
 
 
 
 
 
133
  .chapter{position:absolute;left:0;right:0;height:64px;display:grid;grid-template-columns:1fr auto;align-items:center;gap:4px 12px;padding:10px 16px 12px;border:0;border-radius:16px;background:var(--olive);color:var(--on-olive);box-shadow:0 4px 0 var(--olive-deep);font:400 20px/1.1 var(--f-display);text-align:start;cursor:pointer;transition:transform .08s,box-shadow .08s}
134
  .chapter small{font:700 13px/1 var(--f-body)}
135
  .chapter i{grid-column:1/-1;height:6px;border-radius:999px;background:color-mix(in srgb,var(--on-olive) 28%,transparent);overflow:hidden}
@@ -175,9 +186,13 @@ body.home:not(.manage) #toNow{bottom:76px} body.home:not(.manage) #logoutBtn{bot
175
  .tag.soon{background:var(--amber)} .tag.late{background:var(--sumac)}
176
  .sat.now .ring::after{content:"";position:absolute;inset:-5px;border-radius:50%;border:2px solid var(--c);animation:beckon 1.8s ease-out infinite}
177
  @keyframes beckon{from{transform:scale(.92);opacity:.9}to{transform:scale(1.18);opacity:0}}
178
- .cup{position:absolute;left:calc(50% + var(--x));top:var(--y);width:60px;height:60px;margin:-30px 0 0 -30px;display:grid;place-items:center;border-radius:50%;background:var(--surface);border:4px solid var(--track);font-size:26px;line-height:1}
179
- .cup:not(.won)>span{filter:grayscale(1);opacity:.55}
180
- .cup.won{background:var(--amber-bg);border-color:var(--amber);box-shadow:0 0 0 6px color-mix(in srgb,var(--amber) 22%,transparent)}
 
 
 
 
181
  #toNow{position:fixed;bottom:16px;left:50%;transform:translateX(-50%);z-index:8;padding:9px 16px;border:0;border-radius:999px;background:var(--olive);color:var(--on-olive);box-shadow:0 3px 0 var(--olive-deep),0 6px 16px rgb(0 0 0/.25);font:700 14px/1 var(--f-body);cursor:pointer}
182
  @media (prefers-reduced-motion:reduce){.dot,.chapter{transition:none}.tag,.road .live{animation:none}.sat.now .ring::after{animation:none;opacity:.6}}
183
  .verb-dlg{width:min(94vw,560px);max-height:92vh;padding:0;border:0;border-radius:20px;background:var(--bg);color:var(--ink);box-shadow:0 18px 70px rgb(0 0 0/.35)}
@@ -1391,7 +1406,7 @@ function drawPath(stay){
1391
  label.append(mark("",v.title,"b"),mark("",seen?"✓ נצפה":"סרטון","small")); b.append(label);
1392
  b.title=`סרטון: ${v.title}`; b.setAttribute("aria-label",b.title);
1393
  b.onclick=()=>playVideo(v); if(shut[at]) lock(b,dot,v.title); box.append(b);
1394
- stops.push({x,y,went:seen}); y+=STEP; return;
1395
  }
1396
  const i=cats.indexOf(c), t=parts[i], cur=now&&i===todo, [b,dot]=ball(t,cur), [x,label]=seat(b,at);
1397
  const hw=hws.find(h=>h.c===c), mine=!!hw; // a homework topic: its bubble counts the days left
@@ -1410,17 +1425,22 @@ function drawPath(stay){
1410
  label.append(mine&&t.over?mark("","✓ שיעורי הבית הושלמו 🎉","small"):count(t,did)); b.append(label);
1411
  b.title=(mine&&!t.over?`שיעורי בית, ${hw.msg}. `:"")+`${c.name}: ${did} ${t.done} מתוך ${t.n}`; b.setAttribute("aria-label",b.title);
1412
  b.onclick=()=>openCat(c); if(shut[at]) lock(b,dot,c.name); box.append(b);
1413
- stops.push({x,y,went:t.over,cur}); y+=STEP;
1414
  });
1415
- const cup=document.createElement("div"), x=-SWAY[items.length%8]*amp; // the lesson's end: gold once all of it was practised
1416
  cup.className="cup"+(whole.over?" won":""); cup.style.setProperty("--x",x+"px"); cup.style.setProperty("--y",y+"px");
1417
- cup.setAttribute("role","img"); cup.setAttribute("aria-label",`${l.name}: ${whole.over?"הושלם":"עוד לא הושלם"}`); cup.append(mark("","🏆")); box.append(cup);
1418
- stops.push({x,y,went:whole.over}); y+=30+30;
 
 
 
1419
  }
1420
  box.style.height=Math.max(0,y-30)+"px";
1421
- stops.slice(1).forEach((b,k)=>{ // a curve from each stop to the next: green after a finished topic, marching into the one to do now
1422
  const a=stops[k], h=(b.y-a.y)/2, d=`M${a.x} ${a.y}C${a.x} ${a.y+h} ${b.x} ${b.y-h} ${b.x} ${b.y}`;
1423
- for(const cls of b.cur?["","live"]:[a.went?"went":""]){ const p=document.createElementNS(NS,"path"); p.setAttribute("d",d); if(cls) p.setAttribute("class",cls); road.append(p); }
 
 
1424
  });
1425
  const at=box.querySelector("[aria-current]"), back=$("toNow");
1426
  if(home&&at&&!stay) at.scrollIntoView({block:"center"});
 
126
  #dailyDlg{width:min(92vw,380px)}
127
  .path{--track:color-mix(in srgb,var(--muted) 75%,var(--bg));position:relative;width:100%;max-width:460px;margin:4px auto 72px;background:#101510 url("/static/assets/arabic-calligraphy-path.webp?v=7") top center/100% auto repeat-y}
128
  .road{position:absolute;left:50%;top:0;width:1px;height:100%;overflow:visible;pointer-events:none}
129
+ .road path{fill:none;stroke-linecap:round}
130
+ .road .thread{stroke:#43513B;stroke-width:3}
131
+ .road .bead-shadow{stroke:#111611;stroke-width:15;stroke-dasharray:3 15;filter:drop-shadow(1px 3px 2px rgb(0 0 0/.8))}
132
+ .road .beads{stroke:#344030;stroke-width:12.5;stroke-dasharray:3 15}
133
+ .road .bead-light{stroke:#66775C;stroke-width:8;stroke-dasharray:2.2 15.8;transform:translate(-1px,-1px)}
134
+ .road .bead-shine{stroke:#C8D5BD;stroke-width:3.2;stroke-dasharray:.5 17.5;opacity:.78;transform:translate(-2.4px,-2.6px)}
135
+ .road .beads.went{stroke:#617653}.road .bead-light.went{stroke:#93AA7D}.road .bead-shine.went{stroke:#E5F2D7}
136
+ .road .beads.live{stroke:#7D966A}.road .bead-light.live{stroke:#B5CE9B}.road .bead-shine.live{stroke:#F3FFE8}
137
+ .road .live{animation:march 1.1s linear infinite}
138
+ .road .lesson-thread{stroke:#171C18;stroke-width:8;filter:drop-shadow(1px 2px 1px rgb(0 0 0/.65))}
139
+ .road .lesson-weave-a,.road .lesson-weave-b{stroke-width:5;stroke-dasharray:8 8}
140
+ .road .lesson-weave-a{stroke:#78866C}
141
+ .road .lesson-weave-b{stroke:#C3C9BD;stroke-dashoffset:8}
142
+ .road .lesson-weave-glint{stroke:#F0F2EC;stroke-width:1.4;stroke-dasharray:3 13;stroke-dashoffset:1;opacity:.55;transform:translate(-1px,-1px)}
143
+ @keyframes march{to{stroke-dashoffset:-18}}
144
  .chapter{position:absolute;left:0;right:0;height:64px;display:grid;grid-template-columns:1fr auto;align-items:center;gap:4px 12px;padding:10px 16px 12px;border:0;border-radius:16px;background:var(--olive);color:var(--on-olive);box-shadow:0 4px 0 var(--olive-deep);font:400 20px/1.1 var(--f-display);text-align:start;cursor:pointer;transition:transform .08s,box-shadow .08s}
145
  .chapter small{font:700 13px/1 var(--f-body)}
146
  .chapter i{grid-column:1/-1;height:6px;border-radius:999px;background:color-mix(in srgb,var(--on-olive) 28%,transparent);overflow:hidden}
 
186
  .tag.soon{background:var(--amber)} .tag.late{background:var(--sumac)}
187
  .sat.now .ring::after{content:"";position:absolute;inset:-5px;border-radius:50%;border:2px solid var(--c);animation:beckon 1.8s ease-out infinite}
188
  @keyframes beckon{from{transform:scale(.92);opacity:.9}to{transform:scale(1.18);opacity:0}}
189
+ .cup{position:absolute;left:calc(50% + var(--x));top:var(--y);width:72px;height:72px;margin:-36px 0 0 -36px;display:flex;justify-content:center;align-items:center;border:0;background:none;line-height:1;filter:drop-shadow(0 2px 2px rgb(0 0 0/.45))}
190
+ .masbaha-finial{position:relative;width:64px;height:64px;box-sizing:border-box;color:#252B26;border:6px solid var(--track);border-radius:50%;background:radial-gradient(circle at 34% 27%,#FAFBF7 0 8%,#D9DDD6 30%,#929993 64%,#626964 100%);box-shadow:inset -3px -4px 6px rgb(0 0 0/.3),inset 2px 2px 3px rgb(255 255 255/.7),0 4px 0 color-mix(in srgb,var(--track) 75%,#000)}
191
+ .masbaha-motif{position:absolute;inset:3px;width:46px;height:46px;overflow:visible;filter:drop-shadow(0 1px 0 rgb(255 255 255/.5))}
192
+ .masbaha-motif polygon{fill:none;stroke:currentColor;stroke-width:3.5;stroke-linejoin:bevel}
193
+ .masbaha-motif .inner{stroke-width:2.3}
194
+ .cup.won{filter:drop-shadow(0 0 6px color-mix(in srgb,var(--olive) 85%,transparent)) drop-shadow(0 2px 2px rgb(0 0 0/.45))}
195
+ .cup.won .masbaha-finial{color:var(--olive-deep);border-color:var(--olive);box-shadow:inset -3px -4px 6px rgb(0 0 0/.3),inset 2px 2px 3px rgb(255 255 255/.7),0 4px 0 var(--olive-deep)}
196
  #toNow{position:fixed;bottom:16px;left:50%;transform:translateX(-50%);z-index:8;padding:9px 16px;border:0;border-radius:999px;background:var(--olive);color:var(--on-olive);box-shadow:0 3px 0 var(--olive-deep),0 6px 16px rgb(0 0 0/.25);font:700 14px/1 var(--f-body);cursor:pointer}
197
  @media (prefers-reduced-motion:reduce){.dot,.chapter{transition:none}.tag,.road .live{animation:none}.sat.now .ring::after{animation:none;opacity:.6}}
198
  .verb-dlg{width:min(94vw,560px);max-height:92vh;padding:0;border:0;border-radius:20px;background:var(--bg);color:var(--ink);box-shadow:0 18px 70px rgb(0 0 0/.35)}
 
1406
  label.append(mark("",v.title,"b"),mark("",seen?"✓ נצפה":"סרטון","small")); b.append(label);
1407
  b.title=`סרטון: ${v.title}`; b.setAttribute("aria-label",b.title);
1408
  b.onclick=()=>playVideo(v); if(shut[at]) lock(b,dot,v.title); box.append(b);
1409
+ stops.push({x,y,went:seen,breakBefore:at===0}); y+=STEP; return;
1410
  }
1411
  const i=cats.indexOf(c), t=parts[i], cur=now&&i===todo, [b,dot]=ball(t,cur), [x,label]=seat(b,at);
1412
  const hw=hws.find(h=>h.c===c), mine=!!hw; // a homework topic: its bubble counts the days left
 
1425
  label.append(mine&&t.over?mark("","✓ שיעורי הבית הושלמו 🎉","small"):count(t,did)); b.append(label);
1426
  b.title=(mine&&!t.over?`שיעורי בית, ${hw.msg}. `:"")+`${c.name}: ${did} ${t.done} מתוך ${t.n}`; b.setAttribute("aria-label",b.title);
1427
  b.onclick=()=>openCat(c); if(shut[at]) lock(b,dot,c.name); box.append(b);
1428
+ stops.push({x,y,went:t.over,cur,breakBefore:at===0}); y+=STEP;
1429
  });
1430
+ const cup=document.createElement("div"), x=-SWAY[items.length%8]*amp; // the lesson ends with the masbaha's ornamental finial
1431
  cup.className="cup"+(whole.over?" won":""); cup.style.setProperty("--x",x+"px"); cup.style.setProperty("--y",y+"px");
1432
+ cup.setAttribute("role","img"); cup.setAttribute("aria-label",`${l.name}: ${whole.over?"הושלם":"עוד לא הושלם"}`);
1433
+ const finial=mark("masbaha-finial",""), petal=`<polygon points="50,2 66,11 66,29 50,38 34,29 34,11"/><polygon class="inner" points="50,9 60,15 60,25 50,31 40,25 40,15"/>`;
1434
+ finial.innerHTML=`<svg class="masbaha-motif" viewBox="0 0 100 100" aria-hidden="true">${[0,60,120,180,240,300].map(a=>`<g transform="rotate(${a} 50 50)">${petal}</g>`).join("")}<polygon points="50,29 70,64 30,64"/><polygon points="50,71 30,36 70,36"/></svg>`;
1435
+ cup.append(finial); box.append(cup);
1436
+ stops.push({x,y,went:whole.over}); y+=80; // room for the round lesson finial before the woven link
1437
  }
1438
  box.style.height=Math.max(0,y-30)+"px";
1439
+ stops.slice(1).forEach((b,k)=>{ // beads within a lesson; a woven cord joins its finial to the lesson that follows
1440
  const a=stops[k], h=(b.y-a.y)/2, d=`M${a.x} ${a.y}C${a.x} ${a.y+h} ${b.x} ${b.y-h} ${b.x} ${b.y}`;
1441
+ const state=b.cur?" live":a.went?" went":"";
1442
+ const layers=b.breakBefore?["lesson-thread","lesson-weave-a","lesson-weave-b","lesson-weave-glint"]:["thread","bead-shadow"+state,"beads"+state,"bead-light"+state,"bead-shine"+state];
1443
+ for(const cls of layers){ const p=document.createElementNS(NS,"path"); p.setAttribute("d",d); p.setAttribute("class",cls); road.append(p); }
1444
  });
1445
  const at=box.querySelector("[aria-current]"), back=$("toNow");
1446
  if(home&&at&&!stay) at.scrollIntoView({block:"center"});