Skip to content

Commit ce25948

Browse files
committed
Turn the curriculum steps into a roadmap with quests to clear
The five levels sit on one road as stages, each with a progress ring, and a pin marks the first stage not yet cleared. Materials are numbered quests with a clear button on the card; clearing every quest in a stage shows the finish card. A small tracker beside the tab note counts quests and stage badges, kept in this browser only.
1 parent b16a7f3 commit ce25948

3 files changed

Lines changed: 149 additions & 30 deletions

File tree

‎assets/css/hub.css‎

Lines changed: 75 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1491,8 +1491,6 @@ button.btn.sm { font-size: 14px; }
14911491
.ev-num { white-space: nowrap; }
14921492

14931493
/* ---------- curriculum as courses: tier names, who it is for, the Builders, a first look, the textbook ---------- */
1494-
.st-en { font-size: 12px; color: var(--muted); letter-spacing: .02em; }
1495-
.step button[aria-pressed="true"] .st-en { color: rgba(255, 255, 255, .7); }
14961494
.lv-for { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px; font-size: 14.5px; color: var(--ink); margin-top: 6px; }
14971495
.lv-for b { font-size: 12px; font-weight: 800; color: var(--accent); background: color-mix(in srgb, var(--accent) 11%, var(--surface)); padding: 2px 9px; border-radius: 999px; }
14981496
.lv-crew { grid-column: 1 / -1; margin-top: 8px; display: flex; align-items: center; flex-wrap: wrap; gap: 8px 14px; }
@@ -1511,9 +1509,7 @@ button.btn.sm { font-size: 14px; }
15111509
.ep-tags { display: flex; flex-wrap: wrap; gap: 2px 10px; margin-top: 8px; font-size: 12.5px; font-weight: 700; color: color-mix(in srgb, var(--c) 72%, var(--ink)); }
15121510
.ep-spec { display: flex; flex-direction: column; gap: 3px; font-size: 13.5px; color: var(--ink); }
15131511
.ep-spec b { display: inline-block; min-width: 2.6em; margin-right: 8px; font-size: 12px; font-weight: 700; color: var(--muted); }
1514-
#shelf .ep.has-try { position: relative; }
1515-
#shelf .ep.has-try > button { padding-bottom: 58px; }
1516-
.ep-try { position: absolute; left: 18px; bottom: 14px; display: inline-flex; align-items: center; padding: 5px 13px; border-radius: 999px; background: var(--surface); border: 1px solid var(--rule); color: var(--accent); font-size: 13.5px; font-weight: 700; text-decoration: none; }
1512+
.ep-try { display: inline-flex; align-items: center; padding: 5px 13px; border-radius: 999px; background: var(--surface); border: 1px solid var(--rule); color: var(--accent); font-size: 13.5px; font-weight: 700; text-decoration: none; }
15171513
.ep-try:hover { border-color: var(--accent); }
15181514
.ep-try:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
15191515
.lv-text { margin-top: 18px; padding: 16px 18px; border-radius: 16px; border: 1.5px dashed color-mix(in srgb, var(--l-main) 45%, var(--rule)); }
@@ -1529,3 +1525,77 @@ button.btn.sm { font-size: 14px; }
15291525
.tb-c { font-size: 13px; color: var(--muted); }
15301526
.tb-go { display: flex; flex-wrap: wrap; gap: 6px; }
15311527
#shelf .tb.picked { box-shadow: 0 0 0 3px var(--l-main); }
1528+
1529+
/* ---------- roadmap: five stages on one road, quests that can be cleared ---------- */
1530+
.note-row { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 20px; }
1531+
.note-row .tab-note { flex: 1 1 360px; }
1532+
.quest-hud { display: flex; align-items: center; gap: 6px 12px; font-size: 13.5px; color: var(--muted); }
1533+
.qh-k { font-weight: 800; color: var(--ink); }
1534+
.qh-bar { width: 120px; height: 8px; border-radius: 999px; background: var(--surface); overflow: hidden; }
1535+
.qh-bar i { display: block; height: 100%; border-radius: inherit; background: linear-gradient(90deg, var(--accent), #FFC93C); transition: width .4s ease; }
1536+
.qh-n b { color: var(--ink); font-size: 15px; }
1537+
.path-k span { letter-spacing: .05em; }
1538+
.path { position: relative; gap: 0; padding: 4px 6px; border-radius: 22px; background: linear-gradient(90deg, color-mix(in srgb, var(--accent) 6%, var(--surface)) 0 60%, color-mix(in srgb, var(--l-ai) 9%, var(--surface)) 60% 100%); }
1539+
.step:not(:last-child)::after { top: 55px; left: calc(50% + 34px); right: calc(-50% + 34px); width: auto; height: 6px; border: 0; border-radius: 3px; transform: none; opacity: 1; z-index: 0; background: repeating-linear-gradient(90deg, color-mix(in srgb, var(--muted) 45%, transparent) 0 10px, transparent 10px 18px); }
1540+
.step.cleared:not(:last-child)::after { background: #FFC93C; }
1541+
.step button { position: relative; align-items: center; text-align: center; gap: 2px; padding: 30px 8px 12px; background: transparent; }
1542+
.step button:hover { background: color-mix(in srgb, var(--surface) 75%, transparent); box-shadow: none; }
1543+
.step button[aria-pressed="true"], .step button[aria-pressed="true"]:hover { background: var(--surface); color: var(--ink); box-shadow: 0 6px 20px rgba(20, 22, 43, .1); }
1544+
.step button[aria-pressed="true"] .st-q, .step button[aria-pressed="true"] .st-meta { color: var(--muted); }
1545+
.step button[aria-pressed="true"] .st-makers .avatar.sm { box-shadow: 0 0 0 2px var(--surface); }
1546+
.st-node { position: relative; z-index: 1; width: 56px; height: 56px; border-radius: 50%; display: grid; place-items: center; flex-shrink: 0; background: conic-gradient(var(--accent) calc(var(--p, 0) * 1%), color-mix(in srgb, var(--muted) 28%, var(--surface)) 0); }
1547+
.step.build .st-node { background: conic-gradient(var(--l-ai) calc(var(--p, 0) * 1%), color-mix(in srgb, var(--muted) 28%, var(--surface)) 0); }
1548+
.st-node::before { content: ""; position: absolute; inset: 5px; border-radius: 50%; background: var(--surface); }
1549+
.st-node .st-id { position: relative; font-size: 20px; }
1550+
.step button[aria-pressed="true"] .st-node::before { background: #23276A; }
1551+
.step button[aria-pressed="true"] .st-id { color: #FFD54A; }
1552+
.step.cleared .st-node { background: #FFC93C; }
1553+
.step.cleared .st-node::before { background: #FFF3C4; }
1554+
.step.cleared .st-id, .step.cleared button[aria-pressed="true"] .st-id { color: #8A5A00; font-size: 24px; }
1555+
.step.cleared button[aria-pressed="true"] .st-node::before { background: #FFE38A; }
1556+
.st-pin { position: absolute; top: 6px; left: 50%; transform: translateX(-50%); z-index: 2; padding: 2px 9px; border-radius: 999px; background: var(--accent); color: #fff; font-size: 12px; font-weight: 800; white-space: nowrap; }
1557+
.st-pin::after { content: ""; position: absolute; left: 50%; bottom: -4px; width: 8px; height: 8px; background: inherit; transform: translateX(-50%) rotate(45deg); border-radius: 1px; z-index: -1; }
1558+
@media (prefers-reduced-motion: no-preference) {
1559+
.st-pin { animation: st-bob 2.4s ease-in-out infinite; }
1560+
@keyframes st-bob { 0%, 100% { transform: translate(-50%, 0); } 50% { transform: translate(-50%, -3px); } }
1561+
}
1562+
.st-name { margin-top: 8px; font-size: 15.5px; }
1563+
.st-q { font-size: 13px; }
1564+
.st-meta { margin-top: 2px; padding-top: 0; }
1565+
.st-clear { color: #8A5A00; font-weight: 800; letter-spacing: .06em; }
1566+
.st-makers { justify-content: center; }
1567+
@media (max-width: 860px) {
1568+
.path { grid-auto-columns: 136px; gap: 0; background: var(--surface); }
1569+
.step::after { display: block; }
1570+
.step .st-q { -webkit-line-clamp: 1; }
1571+
.step .st-makers { display: none; }
1572+
.lv-kick { display: none; }
1573+
.stage-goal { flex-basis: 100%; }
1574+
}
1575+
.lv-kick { margin: 0 0 2px; font-size: 12px; font-weight: 800; letter-spacing: .06em; color: var(--muted); }
1576+
.lv-t .lv-kick { margin-top: 0; font-size: 12px; }
1577+
#shelf .ep:not(.tb) { display: flex; flex-direction: column; border-radius: 16px; background: var(--surface-2); }
1578+
#shelf .ep:not(.tb) > button, #shelf .ep:not(.tb) > button:hover { background: transparent; flex: 1; }
1579+
#shelf .ep:not(.tb):hover { background: color-mix(in srgb, var(--c) 8%, var(--surface-2)); }
1580+
#shelf .ep.picked, #shelf .ep.picked > button { box-shadow: none; }
1581+
#shelf .ep.picked { box-shadow: 0 0 0 3px var(--c); }
1582+
#shelf .ep.cleared { box-shadow: inset 0 0 0 2px #FFC93C; }
1583+
.ep-q { font-size: 12px; font-weight: 800; letter-spacing: .02em; color: var(--muted); flex-shrink: 0; }
1584+
#shelf .ep-done { background: #FFC93C; color: #14162B; letter-spacing: .06em; }
1585+
.ep-acts { display: flex; align-items: center; gap: 8px; padding: 0 18px 16px; }
1586+
.ep-clear { all: unset; box-sizing: border-box; cursor: pointer; margin-left: auto; padding: 5px 13px; border-radius: 999px; border: 1.5px dashed color-mix(in srgb, var(--muted) 60%, transparent); color: var(--muted); font-size: 13.5px; font-weight: 700; white-space: nowrap; }
1587+
.ep-clear:hover { color: var(--ink); border-color: var(--ink); }
1588+
.ep-clear:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
1589+
.ep-clear[aria-pressed="true"] { border: 1.5px solid #FFC93C; background: #FFE9A8; color: #6B4500; }
1590+
.lv-foot { margin-top: 16px; display: flex; flex-wrap: wrap; align-items: stretch; gap: 10px; }
1591+
.lv-foot .lv-next { margin-top: 0; flex: 0 0 auto; display: flex; align-items: center; }
1592+
.stage-goal { flex: 1 1 320px; display: flex; align-items: center; flex-wrap: wrap; gap: 6px 12px; padding: 10px 16px; border-radius: 12px; background: var(--surface-2); font-size: 14px; }
1593+
.sg-badge { padding: 3px 10px; border-radius: 999px; background: var(--ink); color: var(--surface); font-size: 12px; font-weight: 800; letter-spacing: .04em; }
1594+
.sg-n { margin-left: auto; font-weight: 800; }
1595+
.stage-goal.clear { background: #FFF3C4; color: #3A2A00; }
1596+
.stage-goal.clear .sg-badge { background: #FFC93C; color: #14162B; }
1597+
.stage-goal .btn.sm { margin-left: auto; }
1598+
@media (prefers-reduced-motion: no-preference) {
1599+
.stage-goal.pop { animation: sg-pop .7s ease; }
1600+
@keyframes sg-pop { 0% { transform: scale(.96); } 55% { transform: scale(1.02); } 100% { transform: scale(1); } }
1601+
}

0 commit comments

Comments
 (0)