docs(site): vertical pipeline on mobile, click tooltips, consistent chrome
All checks were successful
docs / build-and-deploy (push) Successful in 2s

- Pipeline diagram stacks vertically with downward arrows on mobile (row on
  >=720px) instead of the awkward wrap.
- Tooltip cards now open on CLICK (works on touch too), the card itself is
  clickable and opens the symbol's page in a NEW TAB, and an outside click or
  Escape closes it. Replaces the hover-only behavior.
- Reference pages get their own nav — Home / API Reference / Source ↗ — instead
  of the landing-only Features/Examples/Get started anchors, and now include the
  Source link.
- Unify the container width (1120px) across the landing and all reference pages
  so the header and content align between them.
- Reword extern/@export FFI docs from "C-ABI" to "native" for consistency with
  the site's no-C wording.

Verified in-browser at 375px and 1280px: vertical pipeline, click→card→new-tab,
outside-click close, correct reference nav, aligned container; 158 examples still
compile.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-08-29 18:42:40 +03:00
parent c93eca80af
commit 31f1019a69
7 changed files with 62 additions and 41 deletions

View file

@ -107,13 +107,26 @@
document.querySelectorAll('pre[data-lang="ludic"]').forEach(pre => { pre.innerHTML = highlight(pre.textContent); });
}
/* ---- hover cards ------------------------------------------------------- */
let cardEl = null, cardTimer = null;
/* ---- tooltip cards: click a token to open; click the card to open the ---
---- page in a new tab; click outside (or Escape) to close ------------- */
let cardEl = null, cardAnchor = null;
function ensureCard(){
if (cardEl) return cardEl;
cardEl = document.createElement("div"); cardEl.className = "hovercard"; cardEl.hidden = true;
cardEl.addEventListener("click", () => {
const h = cardEl.dataset.href; if (h) window.open(h, "_blank", "noopener");
});
document.body.appendChild(cardEl); return cardEl;
}
function positionCard(a){
const el = cardEl, r = a.getBoundingClientRect();
const cw = el.offsetWidth, ch = el.offsetHeight;
let left = r.left, top = r.bottom + 8;
if (left + cw > window.innerWidth - 12) left = window.innerWidth - cw - 12;
if (left < 12) left = 12;
if (top + ch > window.innerHeight - 12) top = r.top - ch - 8;
el.style.left = Math.max(12,left) + "px"; el.style.top = Math.max(12,top) + "px";
}
function showCard(a){
const id = a.getAttribute("data-id"); if (!id) return;
const c = CARDS[id]; if (!c) return;
@ -122,30 +135,25 @@
+ (c.kind||"").replace("namespace-method","method") + '</span><span class="hc-name">'+esc(c.name||"")+'</span></div>'
+ (c.sig ? '<code class="hc-sig">'+esc(c.sig)+'</code>' : "")
+ '<div class="hc-tip">'+esc(c.tip||"")+'</div>'
+ '<div class="hc-foot">'+esc(c.section||"")+' · click to open</div>';
el.hidden = false;
const r = a.getBoundingClientRect();
const cw = el.offsetWidth, ch = el.offsetHeight;
let left = r.left, top = r.bottom + 8;
if (left + cw > window.innerWidth - 12) left = window.innerWidth - cw - 12;
if (left < 12) left = 12;
if (top + ch > window.innerHeight - 12) top = r.top - ch - 8;
el.style.left = Math.max(12,left) + "px"; el.style.top = Math.max(12,top) + "px";
+ '<div class="hc-foot">'+esc(c.section||"")+' · open in new tab ↗</div>';
el.dataset.href = a.getAttribute("href") || "";
el.hidden = false; cardAnchor = a; positionCard(a);
}
function hideCard(){ if (cardEl) cardEl.hidden = true; }
function hideCard(){ if (cardEl){ cardEl.hidden = true; cardAnchor = null; } }
function installCards(){
// hover cards are a pointer affordance; skip on touch so a tap just navigates
if (!(window.matchMedia && window.matchMedia("(hover: hover)").matches)) return;
document.addEventListener("mouseover", e => {
document.addEventListener("click", e => {
const a = e.target.closest && e.target.closest("a.tok[data-id]");
if (!a) return;
clearTimeout(cardTimer); cardTimer = setTimeout(()=>showCard(a), 130);
if (a){ e.preventDefault(); showCard(a); return; } // token -> open card
if (cardEl && !cardEl.hidden && !(e.target.closest && e.target.closest(".hovercard"))) hideCard(); // outside -> close
});
document.addEventListener("mouseout", e => {
const a = e.target.closest && e.target.closest("a.tok[data-id]");
if (a){ clearTimeout(cardTimer); hideCard(); }
});
window.addEventListener("scroll", hideCard, {passive:true});
document.addEventListener("keydown", e => { if (e.key === "Escape") hideCard(); });
window.addEventListener("resize", hideCard);
window.addEventListener("scroll", () => {
if (cardEl && !cardEl.hidden && cardAnchor){
const r = cardAnchor.getBoundingClientRect();
if (r.bottom < 0 || r.top > window.innerHeight) hideCard(); else positionCard(cardAnchor);
}
}, {passive:true});
}
/* ---- flash the scrolled-to target ------------------------------------- */