Skip to content

Commit 052dbb7

Browse files
committed
Open the hub with a library search and move the team numbers lower
The first screen now leads with what a learner can do: a search box into the library (with live counts of materials and glossary terms) above the start buttons. The four team numbers move to the top of the Builder section, so the curriculum starts inside the first screen on a desktop and about one and a half screens down on a phone. The level-test card above the ladder is one slim line until the test is taken. On phones Pseudo waits for the first scroll before it greets, so it does not cover the first screen.
1 parent 4b4b7bb commit 052dbb7

4 files changed

Lines changed: 99 additions & 44 deletions

File tree

‎assets/css/hub.css‎

Lines changed: 65 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2222,22 +2222,22 @@ dialog.sheet .toast:not(.show) { transition: opacity .25s ease, visibility 0s li
22222222
.hero .featured a { padding: 7px 12px; }
22232223
.hero .featured .t { font-size: 14.5px; }
22242224
/* the team's numbers sit in one slim row: value and label beside a small trend line */
2225-
.hero .hero-grid { grid-template-columns: minmax(0, 1fr); margin-top: 10px; }
2226-
.hero .growth { grid-template-columns: repeat(4, minmax(0, 1fr)); grid-auto-rows: auto; gap: 10px; }
2227-
.hero .tile { display: grid; grid-template-columns: auto minmax(0, 1fr); grid-template-rows: auto auto auto; column-gap: 14px; row-gap: 0; align-items: center; padding: 12px 16px; min-height: 0; }
2228-
.hero .tile-label { font-size: 13px; }
2229-
.hero .tile-value { font-size: 28px; }
2230-
.hero .tile-value small { font-size: 14px; }
2231-
.hero .tile-delta { font-size: 12.5px; }
2232-
.hero .tile .spark { grid-column: 2; grid-row: 1 / -1; margin: 0; padding: 0; min-height: 0; height: 56px; }
2233-
.hero .tile .spark svg { min-height: 0; height: 52px; max-height: 52px; }
2234-
.hero .tile .spark-axis { display: none; }
2235-
.hero .tile .spark-empty { display: none; }
2236-
.hero .tile .mini-bars { grid-column: 2; grid-row: 1 / -1; margin: 0; padding: 0; gap: 3px; font-size: 11.5px; }
2237-
.hero .tile .mini-bars .tr { height: 4px; margin-top: -1px; }
2238-
/* the curriculum starts right under the numbers */
2225+
.nums.hero-grid { grid-template-columns: minmax(0, 1fr); margin-top: 10px; }
2226+
.nums .growth { grid-template-columns: repeat(4, minmax(0, 1fr)); grid-auto-rows: auto; gap: 10px; }
2227+
.nums .tile { display: grid; grid-template-columns: auto minmax(0, 1fr); grid-template-rows: auto auto auto; column-gap: 14px; row-gap: 0; align-items: center; padding: 12px 16px; min-height: 0; }
2228+
.nums .tile-label { font-size: 13px; }
2229+
.nums .tile-value { font-size: 28px; }
2230+
.nums .tile-value small { font-size: 14px; }
2231+
.nums .tile-delta { font-size: 12.5px; }
2232+
.nums .tile .spark { grid-column: 2; grid-row: 1 / -1; margin: 0; padding: 0; min-height: 0; height: 56px; }
2233+
.nums .tile .spark svg { min-height: 0; height: 52px; max-height: 52px; }
2234+
.nums .tile .spark-axis { display: none; }
2235+
.nums .tile .spark-empty { display: none; }
2236+
.nums .tile .mini-bars { grid-column: 2; grid-row: 1 / -1; margin: 0; padding: 0; gap: 3px; font-size: 11.5px; }
2237+
.nums .tile .mini-bars .tr { height: 4px; margin-top: -1px; }
2238+
/* the curriculum starts right under the hero */
22392239
#curriculum.band { padding-top: 40px; }
2240-
@media (max-width: 1160px) { .hero .growth { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
2240+
@media (max-width: 1160px) { .nums .growth { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
22412241
@media (max-width: 860px) {
22422242
.hero .banner { padding: 24px 20px; align-items: stretch; }
22432243
.hero .banner-side { width: 100%; margin-top: 16px; }
@@ -2246,24 +2246,24 @@ dialog.sheet .toast:not(.show) { transition: opacity .25s ease, visibility 0s li
22462246
.hero .banner-cta .pill { min-height: 44px; }
22472247
}
22482248
@media (max-width: 520px) {
2249-
.hero .growth { gap: 8px; }
2250-
.hero .tile { grid-template-columns: minmax(0, 1fr); padding: 10px 12px; }
2251-
.hero .tile .spark, .hero .tile .mini-bars { display: none; }
2252-
.hero .tile-value { font-size: 24px; }
2249+
.nums .growth { gap: 8px; }
2250+
.nums .tile { grid-template-columns: minmax(0, 1fr); padding: 10px 12px; }
2251+
.nums .tile .spark, .nums .tile .mini-bars { display: none; }
2252+
.nums .tile-value { font-size: 24px; }
22532253
}
22542254

22552255
/* trend lines mark each cohort on the axis */
22562256
.spark .pt { fill: var(--surface); stroke: var(--accent); stroke-width: 1.5; vector-effect: non-scaling-stroke; }
22572257
.spark-axis { position: relative; display: block; height: 16px; margin-top: 4px; }
22582258
.spark-axis .tk { position: absolute; top: 0; transform: translateX(-50%); font-size: 11px; line-height: 16px; letter-spacing: -.01em; white-space: nowrap; }
22592259
.spark-axis .tk.last { color: var(--ink); font-weight: 700; }
2260-
.hero .tile { padding: 18px 20px 14px; row-gap: 2px; }
2261-
.hero .tile .spark { height: auto; align-self: stretch; display: flex; flex-direction: column; justify-content: flex-end; }
2262-
.hero .tile .spark svg { height: 76px; max-height: 76px; }
2263-
.hero .tile .spark-axis { display: block; }
2264-
.hero .tile .mini-bars { gap: 6px; font-size: 12px; align-self: center; }
2265-
.hero .tile .mini-bars .tr { height: 5px; }
2266-
.hero .tile-value { font-size: 32px; margin: 2px 0; }
2260+
.nums .tile { padding: 18px 20px 14px; row-gap: 2px; }
2261+
.nums .tile .spark { height: auto; align-self: stretch; display: flex; flex-direction: column; justify-content: flex-end; }
2262+
.nums .tile .spark svg { height: 76px; max-height: 76px; }
2263+
.nums .tile .spark-axis { display: block; }
2264+
.nums .tile .mini-bars { gap: 6px; font-size: 12px; align-self: center; }
2265+
.nums .tile .mini-bars .tr { height: 5px; }
2266+
.nums .tile-value { font-size: 32px; margin: 2px 0; }
22672267

22682268
/* the next forum card: facts in two columns, the state beside the button, the timetable folded inside */
22692269
@media (min-width: 861px) {
@@ -2289,12 +2289,12 @@ dialog.sheet .toast:not(.show) { transition: opacity .25s ease, visibility 0s li
22892289
.events .event.past .ev-name .when { font-size: 13px; }
22902290
}
22912291
/* numbers first, then the trend across cohorts at full tile width */
2292-
.hero .tile { grid-template-columns: auto minmax(0, 1fr); grid-template-areas: "l l" "v d" "s s"; column-gap: 10px; align-items: baseline; }
2293-
.hero .tile > .tile-label { grid-area: l; }
2294-
.hero .tile > .tile-value { grid-area: v; }
2295-
.hero .tile > .tile-delta { grid-area: d; justify-self: end; text-align: right; }
2296-
.hero .tile > .spark, .hero .tile > .mini-bars, .hero .tile > .spark-empty { grid-area: s; grid-column: 1 / -1; grid-row: auto; margin-top: 8px; align-self: end; }
2297-
.hero .tile .spark svg { height: 54px; max-height: 54px; }
2292+
.nums .tile { grid-template-columns: auto minmax(0, 1fr); grid-template-areas: "l l" "v d" "s s"; column-gap: 10px; align-items: baseline; }
2293+
.nums .tile > .tile-label { grid-area: l; }
2294+
.nums .tile > .tile-value { grid-area: v; }
2295+
.nums .tile > .tile-delta { grid-area: d; justify-self: end; text-align: right; }
2296+
.nums .tile > .spark, .nums .tile > .mini-bars, .nums .tile > .spark-empty { grid-area: s; grid-column: 1 / -1; grid-row: auto; margin-top: 8px; align-self: end; }
2297+
.nums .tile .spark svg { height: 54px; max-height: 54px; }
22982298
.event.next .ev-head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; }
22992299
.event.next .ev-head .soon-tag { order: 2; align-self: center; }
23002300
.ev-gallery .ev-org { font-size: 12.5px; line-height: 1.5; text-align: center; margin-top: 2px; }
@@ -2315,12 +2315,12 @@ dialog.sheet .toast:not(.show) { transition: opacity .25s ease, visibility 0s li
23152315

23162316
/* phone: the number tiles stack label, number, note and chart in one column */
23172317
@media (max-width: 560px) {
2318-
.hero .tile { grid-template-columns: minmax(0, 1fr); grid-template-areas: "l" "v" "d" "s"; padding: 12px 14px; }
2319-
.hero .tile > .tile-delta { justify-self: start; text-align: left; font-size: 12px; line-height: 1.35; }
2320-
.hero .tile-value { font-size: 28px; }
2321-
.hero .tile .spark svg { height: 48px; max-height: 48px; }
2322-
.hero .tile .mini-bars { display: grid; gap: 4px; font-size: 11.5px; }
2323-
.hero .tile .mini-bars .tr { height: 4px; }
2318+
.nums .tile { grid-template-columns: minmax(0, 1fr); grid-template-areas: "l" "v" "d" "s"; padding: 12px 14px; }
2319+
.nums .tile > .tile-delta { justify-self: start; text-align: left; font-size: 12px; line-height: 1.35; }
2320+
.nums .tile-value { font-size: 28px; }
2321+
.nums .tile .spark svg { height: 48px; max-height: 48px; }
2322+
.nums .tile .mini-bars { display: grid; gap: 4px; font-size: 11.5px; }
2323+
.nums .tile .mini-bars .tr { height: 4px; }
23242324
}
23252325

23262326
/* after the forum: the card says it has ended, and the list takes the full width once no card is left */
@@ -2637,3 +2637,30 @@ body.has-helper .site-footer { padding-bottom: calc(96px + env(safe-area-inset-b
26372637
.hp-sug.hp-next { display: flex; flex-wrap: wrap; gap: 6px; }
26382638
.hp-sug.hp-next[hidden] { display: none; }
26392639
.hp-next button { font-size: 13px; padding: 5px 11px; min-height: 32px; background: var(--surface); }
2640+
2641+
/* the hero: one search box into the library, above the ways to start */
2642+
.hero-search { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; margin-top: 18px; max-width: 560px; }
2643+
.hs-box { display: flex; align-items: center; gap: 10px; min-height: 50px; padding: 0 16px; border-radius: 14px; background: #fff; color: #5b5f7a; }
2644+
.hs-box:focus-within { outline: 3px solid var(--focus); outline-offset: 2px; }
2645+
.hs-box svg { width: 18px; height: 18px; flex-shrink: 0; }
2646+
.hs-box input { flex: 1; min-width: 0; border: 0; outline: 0; background: transparent; font: inherit; font-size: 16px; color: #14162B; }
2647+
.hs-box input::placeholder { color: #7a7e98; }
2648+
.hs-go { min-height: 50px; padding: 0 22px; border: 0; border-radius: 14px; background: rgba(255, 255, 255, .16); color: #fff; font: inherit; font-weight: 700; font-size: 15px; cursor: pointer; }
2649+
.hs-go:hover { background: rgba(255, 255, 255, .26); }
2650+
.hs-go:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
2651+
.hs-note { grid-column: 1 / -1; margin: 2px 2px 0; font-size: 13.5px; color: rgba(255, 255, 255, .78); }
2652+
.hs-note a { color: #fff; font-weight: 700; text-decoration: underline; text-decoration-color: rgba(255, 255, 255, .4); text-underline-offset: 4px; }
2653+
.hs-note a:hover { text-decoration-color: #fff; }
2654+
.hs-note a:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; border-radius: 4px; }
2655+
.hero .banner-cta { margin-top: 16px; }
2656+
/* the team's numbers now open the Builder section */
2657+
.nums.hero-grid { margin: 0 0 18px; }
2658+
/* the level test is one slim line above the ladder until it has been taken */
2659+
.lt-card.lt-slim { padding: 14px 22px; gap: 10px 24px; margin-bottom: 18px; border-radius: 18px; }
2660+
.lt-card.lt-slim .lt-t h3 { font-size: 18px; margin: 0 0 2px; }
2661+
.lt-card.lt-slim .lt-t p:last-child { font-size: 13.5px; }
2662+
.lt-card.lt-slim .pill { min-height: 40px; padding: 0 18px; }
2663+
@media (max-width: 960px) { .lt-card.lt-slim { grid-template-columns: minmax(0, 1fr) auto; } }
2664+
@media (max-width: 520px) { .lt-card.lt-slim { grid-template-columns: minmax(0, 1fr); } .lt-card.lt-slim .lt-t p:last-child { display: none; } }
2665+
/* the open-source list keeps to the top of its panel when the left column grows */
2666+
@media (min-width: 861px) { .hero .banner-side { justify-content: flex-start; align-self: center; } .hero .featured { align-content: start; } }

‎assets/js/helper.js‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -478,11 +478,16 @@
478478
With the experiment off, variant() is null and Pseudo greets as usual. */
479479
const exp = window.hubExperiment;
480480
const gate = Promise.all([exp ? exp.variant("pseudo-greeting", 1200) : null, load()]).then(([v]) => v);
481-
setTimeout(() => gate.then((v) => {
481+
const greet = () => gate.then((v) => {
482482
const eligible = !quiet() && panel.hidden && !spoke && !said().includes(`${page}:${line.id}`);
483483
if (v && eligible) exp.expose("pseudo-greeting");
484484
if (v !== "control") speak(line);
485-
}), 1600);
485+
});
486+
/* on a phone the bubble would cover the first screen, so Pseudo waits until the reader starts scrolling */
487+
if (matchMedia("(max-width: 760px)").matches && scrollY < 40) {
488+
const onScroll = () => { if (scrollY < 40) return; removeEventListener("scroll", onScroll); setTimeout(greet, 900); };
489+
addEventListener("scroll", onScroll, { passive: true });
490+
} else setTimeout(greet, 1600);
486491
return;
487492
}
488493
if (line.when === "half") {

‎assets/js/hub.js‎

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -519,10 +519,11 @@
519519
if (!box || !state.leveltest) return;
520520
const mine = myLevel(), lv = mine && levelOf(mine.level);
521521
const n = state.leveltest.questions.length;
522+
box.classList.toggle("lt-slim", !lv);
522523
box.innerHTML = lv
523524
? `<div class="lt-t"><p class="lt-k">내 레벨 진단 결과</p><h3>${LV(lv.id)} · ${esc(lv.tier || lv.name)}</h3><p>${esc(bandLine(mine))}</p></div>
524525
<div class="lt-acts"><button type="button" class="pill solid" data-goto-level="${lv.id}">내 코스 보기</button><button type="button" class="pill" data-test-open="retry">다시 진단</button></div>`
525-
: `<div class="lt-t"><p class="lt-k">어디서 시작할지 모르겠다면</p><h3>3분 진단으로 내 레벨 찾기</h3><p>실무 상황 문제 ${n}개를 풀면 시작할 Level과 첫 자료, 다시 볼 개념을 알려 드립니다.</p></div>
526+
: `<div class="lt-t"><h3>어디서 시작할지 모르겠다면, 3분 레벨 진단</h3><p>실무 상황 문제 ${n}개를 풀면 시작할 Level과 첫 자료, 다시 볼 개념을 알려 드립니다.</p></div>
526527
<div class="lt-acts"><button type="button" class="pill solid" data-test-open="card">진단 시작</button></div>`;
527528
}
528529
function scoreTest() {
@@ -1187,6 +1188,14 @@
11871188
return `<div class="tp-shelf s-${esc(tok(s.id))}"><h3>${esc(s.name)}</h3>
11881189
<ul>${ts.slice(0, SHOW).map((t) => `<li><a href="library.html#${esc(tok(t.id))}" data-event="library_topic" data-event-params='${esc(JSON.stringify({ topic: tok(t.id), source: "hub" }))}'>${esc(t.name)}</a></li>`).join("")}${ts.length > SHOW ? `<li><a class="tp-more" href="library.html?shelf=${esc(tok(s.id))}">${ts.length - SHOW}개 더</a></li>` : ""}</ul></div>`;
11891190
}).join("");
1191+
/* the hero's search line says how much there is to find */
1192+
const note = $("#hs-note");
1193+
if (note) {
1194+
const items = d.topics.reduce((n, t) => n + (t.items || []).length, 0);
1195+
const line = (terms) => `<a href="library.html">자료 ${items}개</a>와 <a href="library.html?view=glossary">${terms ? `용어 ${terms}개` : "용어집"}</a>에서 찾습니다.`;
1196+
note.innerHTML = line(0);
1197+
getJSON("data/glossary.json").then((g) => { note.innerHTML = line((g.sections || []).reduce((n, x) => n + (x.terms || []).length, 0)); }).catch(() => {});
1198+
}
11901199
}
11911200

11921201
/* the next Data Forum gets the space; past ones are one line each */
@@ -1791,6 +1800,11 @@
17911800
const joinTarget = (href) => (/discord/.test(href) ? "discord" : /Project-template/.test(href) ? "template" : /is%3Aissue|is:issue/.test(href) ? "issue" : /pseudo-lab\.com/.test(href) ? "runner" : "other");
17921801

17931802
function wire() {
1803+
/* a search from the hero or the topics section goes to the library page, which records the words it searched */
1804+
document.addEventListener("submit", (e) => {
1805+
const f = e.target.closest(".hero-search, .tp-search");
1806+
if (f) track("start_click", { target: "library_search", placement: f.classList.contains("hero-search") ? "hero" : "topics" });
1807+
});
17941808
document.addEventListener("click", (e) => {
17951809
const fa = e.target.closest("#featured a");
17961810
if (fa) track("click_featured", { repo: fa.dataset.repo || "" });

‎index.html‎

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,15 @@
5353
<p class="banner-kicker"><span>Pseudo-Lab</span><span class="sep" aria-hidden="true"></span>인과추론팀 <b>Causal-Lab</b></p>
5454
<h1 id="hero-title">Causal Inference Hub</h1>
5555
<p class="banner-lede">2022년부터 함께 만든 인과추론과 온라인 실험 자료를 주제별로 찾고, Level 0–4 커리큘럼으로 따라갈 수 있게 엮었습니다.</p>
56+
<form class="hero-search" action="library.html" method="get" role="search">
57+
<label class="hs-box">
58+
<span class="sr-only">자료실에서 주제, 방법, 용어로 찾기</span>
59+
<svg viewBox="0 0 20 20" aria-hidden="true"><circle cx="8.5" cy="8.5" r="5.5" fill="none" stroke="currentColor" stroke-width="2"/><path d="m13 13 4.5 4.5" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>
60+
<input type="search" name="q" placeholder="이중차분, CUPED, 실험군…" autocomplete="off" enterkeyhint="search">
61+
</label>
62+
<button type="submit" class="hs-go">찾기</button>
63+
<p class="hs-note" id="hs-note"><a href="library.html">자료실</a>과 <a href="library.html?view=glossary">용어집</a>에서 찾습니다.</p>
64+
</form>
5665
<div class="banner-cta">
5766
<a class="pill solid" href="https://www.youtube.com/@CausalStudio" target="_blank" rel="noopener" data-event="start_click" data-event-params='{"target":"youtube","placement":"hero"}'><svg class="yt" viewBox="0 0 24 24" width="18" height="18" aria-hidden="true"><rect x="1.5" y="4.5" width="21" height="15" rx="4.5" fill="#FF0033"/><path d="M10 8.8v6.4l5.4-3.2z" fill="#fff"/></svg>입문 영상으로 시작하기</a>
5867
<a class="pill" href="https://causalinferencelab.github.io/Causal-Inference-with-Python/" data-event="start_click" data-event-params='{"target":"webbook","placement":"hero"}'>웹북으로 시작하기</a>
@@ -69,9 +78,6 @@ <h1 id="hero-title">Causal Inference Hub</h1>
6978
</div>
7079
</div>
7180
<a class="next-event" id="next-event" href="#events" data-event="click_event" data-event-params='{"action":"next_strip","placement":"hero"}' hidden></a>
72-
<div class="hero-grid">
73-
<ul class="growth" id="growth" aria-label="팀의 성장 지표"></ul>
74-
</div>
7581
</div>
7682
</section>
7783

@@ -145,6 +151,9 @@ <h2 id="topics-title">자료실</h2>
145151
<h2 id="contrib-title">프로젝트를 연 Builder</h2>
146152
<p id="contrib-sub"></p>
147153
</div>
154+
<div class="nums hero-grid">
155+
<ul class="growth" id="growth" aria-label="팀의 성장 지표"></ul>
156+
</div>
148157
<ol class="top3" id="top3"></ol>
149158
<div class="crew-row">
150159
<div class="people-rail" id="people-rail" aria-label="함께한 Builder"></div>

0 commit comments

Comments
 (0)