fix: enhance visual representation of lesson paths with new SVG elements and animations
Browse files- 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
|
| 130 |
-
.road .
|
| 131 |
-
.road .
|
| 132 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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:
|
| 179 |
-
.
|
| 180 |
-
.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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
|
| 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?"הושלם":"עוד לא הושלם"}`);
|
| 1418 |
-
|
|
|
|
|
|
|
|
|
|
| 1419 |
}
|
| 1420 |
box.style.height=Math.max(0,y-30)+"px";
|
| 1421 |
-
stops.slice(1).forEach((b,k)=>{ //
|
| 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 |
-
|
|
|
|
|
|
|
| 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"});
|