diff --git a/system/public/whistlegraph.org/index.html b/system/public/whistlegraph.org/index.html index 035dff4b4c..3781ae93dd 100644 --- a/system/public/whistlegraph.org/index.html +++ b/system/public/whistlegraph.org/index.html @@ -224,6 +224,16 @@ ul.plain{list-style:none} ul.plain li{padding:3px 0} ul.plain li::before{content:"– "; color:var(--margin)} + /* long category lists fold to their first few rows; the "…" opens the rest */ + ul.plain li.morefold{cursor:pointer; color:var(--margin); letter-spacing:3px; font-size:17px; line-height:1} + ul.plain li.morefold::before{content:""} + ul.plain li.morefold:hover{background:var(--hi)} + + /* the code cloud — every code in the index at once, sized by reach */ + .codecloud{display:flex; flex-wrap:wrap; gap:1px 11px; align-items:baseline; margin:10px 0 4px; + font-family:var(--mono); line-height:1.75} + .codecloud a{color:var(--link); text-decoration:none; white-space:nowrap} + .codecloud a:hover{background:var(--hi)} p.glab{color:var(--margin); font-size:11.5px; letter-spacing:.06em; text-transform:uppercase; margin:12px 0 2px} .zine{display:inline-block} .zine img{width:118px; height:auto; border:1px solid var(--line); background:var(--art); display:block; margin:5px 0 3px} @@ -232,22 +242,6 @@ .rail div{padding:3px 0} .rail b{color:var(--margin); font-weight:normal; margin-right:8px} - /* Concept drawings for what comes next. They are colored pencil on white - paper, so they keep the paper backing (--art) in either theme rather than - floating on the night ground. */ - .future{display:grid; grid-template-columns:1fr; gap:18px; margin:10px 0 4px} - @media (min-width:620px){ .future{grid-template-columns:1fr 1fr; gap:20px} } - .future figure{margin:0} - /* Landscape panels take the full width instead of sitting beside a portrait, - which otherwise leaves a column-height hole under them. */ - .future figure.wide{grid-column:1/-1} - .future img{width:100%; height:auto; display:block; border:1px solid var(--line); - background:var(--art); margin:0 0 6px} - .future figcaption{color:var(--dim); font-size:12.5px; line-height:1.55} - .future figcaption b{color:var(--ink); font-weight:600; display:block; font-size:13px} - .future .doc{color:var(--margin); font-family:var(--mono); font-size:10.5px; - letter-spacing:.06em; text-transform:uppercase} - footer{margin-top:22px; color:var(--dim); font-size:12px; line-height:1.8} footer a{color:var(--dim)} @@ -403,6 +397,10 @@
+Appearances
@@ -453,46 +451,6 @@
The Whistlegraph Zine — Sex Magazine (ed. Asher Penn), 2023. 60pp, 750 copies.
-
-
-
-
-
-
-
- Colored pencil, 2026.
-.{jpg,mp4}
const fmtViews=v=>v>=1e6?`${(v/1e6).toFixed(1)}M`:v>=1e3?`${Math.round(v/1e3)}K`:`${v}`;
@@ -775,6 +750,19 @@ function buildView(){
if(q){ VIEW=WORKS.filter(match); return; }
VIEW=[...WORKS.slice(0,CURATED_N), {divider:true}, ...WORKS.slice(CURATED_N)];
}
+// The code cloud: every confirmed code at once, sized by the log of its reach,
+// tinted with its own swatch color. One glance shows where the views live.
+function renderCloud(){
+ const el=document.getElementById("codeCloud"); if(!el||!WORKS.length) return;
+ const logs=WORKS.map(w=>Math.log(1+(w.views||0)));
+ const lo=Math.min(...logs), hi=Math.max(...logs);
+ el.innerHTML=WORKS.map((w,i)=>{
+ const t=hi>lo?(logs[i]-lo)/(hi-lo):0;
+ return `${w.code}`;
+ }).join("");
+}
+
function renderMore(){
let html="";
const end=Math.min(SHOWN+PAGE, VIEW.length);
@@ -905,7 +893,11 @@ Promise.all([
const open=document.getElementById("filterPanel").classList.toggle("open");
filterToggle.setAttribute("aria-expanded",String(open));
});
- renderReset();
+ document.getElementById("codeCloud").addEventListener("click",e=>{
+ const a=e.target.closest("a[data-code]"); if(!a) return;
+ e.preventDefault(); go(a.dataset.code);
+ });
+ renderReset(); renderCloud();
document.querySelectorAll("#workSortbar button[data-sort]").forEach(b=>b.addEventListener("click",()=>{
document.querySelectorAll("#workSortbar button[data-sort]").forEach(x=>x.classList.remove("on"));
b.classList.add("on");
@@ -935,7 +927,7 @@ Promise.all([
// it immediately when opened.
// Background reconcile must never scroll — it fires on idle, seconds after
// load, when the visitor may already be reading partway down the page.
- const reconcilePosts=()=>loadPosts().then(()=>{if(curSection==="works"&&!document.getElementById("detail").classList.contains("on"))renderReset(false)});
+ const reconcilePosts=()=>loadPosts().then(()=>{renderCloud();if(curSection==="works"&&!document.getElementById("detail").classList.contains("on"))renderReset(false)});
if("requestIdleCallback" in window)requestIdleCallback(reconcilePosts);else setTimeout(reconcilePosts,0);
});