From 3b186b7724dd3ca0ff67c3c8a0f9823f0f161fc5 Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Thu, 1 Oct 2026 14:03:11 -0300 Subject: The landing's words jump to their recordings, the casts open on their telling frame, and #mode-box draws the box Each recording on the landing has an anchor (rec-); the "What's in it" words jump to theirs (Terminals, PDFs, Images, Diff review, Scripting) and the recording's caption ends in a link to the docs; Language servers and Themes, with no recording, link to the docs. A cast's `poster_at` in casts.toml picks the frame it shows until it plays: live-text at the error, terminals at the copied line, petscii on the Mandelbrot; the casts wait for the in-view script to play them. A caption may hold markup: the 9P clip links 9ns to setup. The downloads give their size, read from project.download, and the footer links the changes (project.changes). The guide's annotated pane has alt text, pin 1 beside the workspace tag rather than on Changelog, and pin 5 on the body's text; pin positions are written with repr, since str puts a U+2212 minus CSS cannot read. #mode-box(mark, unsaved:) draws a pane's box as it looks, in print and HTML. Co-Authored-By: Claude Opus 5.5 --- docs/site/casts/casts.toml | 4 ++++ docs/site/media/clips.toml | 4 ++-- docs/site/site.css | 7 +++++++ docs/site/site.typ | 44 ++++++++++++++++++++++++++++++-------------- 4 files changed, 43 insertions(+), 16 deletions(-) (limited to 'docs/site') diff --git a/docs/site/casts/casts.toml b/docs/site/casts/casts.toml index 9f0dd1a5..9cf8afb6 100644 --- a/docs/site/casts/casts.toml +++ b/docs/site/casts/casts.toml @@ -2,6 +2,7 @@ # shown: casts/.cast for each. Each plays by itself while on screen; all loop # and fit the page's width. While `ready` is false the cast shows # placeholder.svg, so the site builds before a recording exists. +# `poster_at` is the second whose frame stands for the cast before it plays. # test/record_casts.py writes the casts and this file. [[cast]] @@ -11,6 +12,7 @@ caption = "Rename a variable with helix keys, middle-click make, right-click the cols = 100 rows = 30 ready = true +poster_at = 14 [[cast]] name = "terminals" @@ -19,6 +21,7 @@ caption = "A shell beside a file: Ctrl-b, copy a line, page git log." cols = 100 rows = 30 ready = true +poster_at = 11 [[cast]] name = "petscii" @@ -27,3 +30,4 @@ caption = "No kitty graphics: a Mandelbrot in PETSCII, then the Intel manual sea cols = 100 rows = 30 ready = true +poster_at = 3 diff --git a/docs/site/media/clips.toml b/docs/site/media/clips.toml index 11f6e8f3..37dc9db9 100644 --- a/docs/site/media/clips.toml +++ b/docs/site/media/clips.toml @@ -1,6 +1,6 @@ # The landing page's recordings, in the order shown. For each clip the # site ships media/.webm and media/.mp4, with media/.png -# as the poster. `landing = false` keeps a clip off the landing (the +# as the poster; a caption may hold markup (#link). `landing = false` keeps a clip off the landing (the # terminal casts show the same) while its files stay for the chapters. While `ready` is false the clip shows placeholder.svg and # no video, so the site builds before a recording exists. @@ -32,7 +32,7 @@ landing = false [[clip]] name = "scripting-over-9p" -caption = "A shell under 9ns, where the session is a directory: ls, cat, echo." +caption = "A shell under #link(\"setup.html#ninens\")[9ns], where the session is a directory: ls, cat, echo." ready = true [[clip]] diff --git a/docs/site/site.css b/docs/site/site.css index 6e4a2e93..dc682eff 100644 --- a/docs/site/site.css +++ b/docs/site/site.css @@ -207,3 +207,10 @@ main[data-page="builtins"] .content h4 + p { margin-top:0; } .annotated .pins li { margin:.25em 0; } .annotated .pins li::marker { font:700 15px var(--mono); color:var(--amber); } @media (max-width:600px) { .annotated { grid-template-columns:minmax(0, 1fr); } } +.clip figcaption .more { font:15px var(--pixel); color:var(--leaf); margin-left:.3em; white-space:nowrap; } +.clip { scroll-margin-top:16px; } + +/* a pane's box: blank normal, ^ insert, $ raw; filled while unsaved */ +.mode-box { display:inline-flex; align-items:center; justify-content:center; width:1.15em; height:1.15em; vertical-align:-.15em; + font:700 .8em var(--mono); background:var(--tag); color:var(--ink); border:2px solid var(--leaf); border-radius:2px; } +.mode-box.unsaved { background:var(--amber); border-color:var(--amber); color:#1b120a; } diff --git a/docs/site/site.typ b/docs/site/site.typ index 787844f5..62b1292e 100644 --- a/docs/site/site.typ +++ b/docs/site/site.typ @@ -27,14 +27,16 @@ the interface, and the 9P protocol.], status: [Linux; macOS in progress. Version #version.], // what's in it: a word each, linked to where it is told; no prose + // what's in it: each word jumps to its recording on this page when it + // has one, and that recording's caption links on to the docs inside: ( - ("Terminals", "guide.html#terminals"), - ("PDFs", "builtins.html#builtin-PdfSections"), - ("Images", "reference.html#panes"), - ("Language servers", "setup.html#language-servers"), - ("Diff review", "guide.html#reviewing-diffs"), - ("Scripting", "scripting.html"), - ("Themes", "themes.html"), + (name: "Terminals", rec: "terminals", docs: "guide.html#terminals"), + (name: "PDFs", rec: "pdf-navigation", docs: "builtins.html#builtin-PdfSections"), + (name: "Images", rec: "image-pane", docs: "reference.html#panes"), + (name: "Language servers", rec: none, docs: "setup.html#language-servers"), + (name: "Diff review", rec: "diff-review", docs: "guide.html#reviewing-diffs"), + (name: "Scripting", rec: "scripting-over-9p", docs: "scripting.html"), + (name: "Themes", rec: none, docs: "themes.html"), ), terminal: [In a terminal], window: [In its own window], @@ -113,6 +115,7 @@ #el("footer", (class: "colophon"))[ pardes #version · source: #project.mirrors.map(m => el("a", (href: m.web))[#m.name]).join(", ") · + #el("a", (href: project.changes))[changes] · #if project.license != none [#project.license license · ] built from `docs/typ` with Typst · #el("a", (href: "fonts/LICENSE-DepartureMono.txt"))[fonts] (OFL) · @@ -147,25 +150,35 @@ ] #let placeholder = el("img", (src: "media/placeholder.svg", alt: "", width: "640", height: "400"))[] +/// A recording's caption: its text (which may hold #link markup), then the +/// docs of the "What's in it" word that jumps here, if any. +#let caption(c) = { + if c.caption.contains("#") { eval(c.caption, mode: "markup") } else { c.caption } + let to = landing.inside.find(i => i.rec == c.name) + if to != none [ #el("a", (class: "more", href: to.docs))[#to.name in the docs →]] +} + /// A terminal recording: a box the player fills, its data inline (so it /// plays from file://), its caption under it. #let ready-casts = casts.filter(c => c.ready) -#let cast(c, i) = el("figure", (class: if i == 0 { "clip cast first" } else { "clip cast" }))[ +#let cast(c, i) = el("figure", (class: if i == 0 { "clip cast first" } else { "clip cast" }, id: "rec-" + c.name))[ #if c.ready { el("div", (class: "player", id: "cast-" + c.name, "aria-label": c.title))[] } else { placeholder } - #el("figcaption")[#el("strong")[#c.title.] #c.caption] + #el("figcaption")[#el("strong")[#c.title.] #caption(c)] ] #let player-script = { let list = ready-casts.enumerate().map(((i, c)) => ( id: "cast-" + c.name, data: read("casts/" + c.name + ".cast"), - cols: c.cols, rows: c.rows, + cols: c.cols, rows: c.rows, poster: "npt:0:" + str(c.at("poster_at", default: 2)), )) // " { if (!('IntersectionObserver' in window)) return; " + @@ -184,7 +197,10 @@ #el("h1", (class: "masthead"))[pardes] #el("p", (class: "lead"))[#landing.lead] #el("ul", (class: "inside", "aria-label": "What's in it"))[ - #for (name, to) in landing.inside { el("li")[#el("a", (href: to))[#name]] } + #for i in landing.inside { + let to = if i.rec != none { "#rec-" + i.rec } else { i.docs } + el("li")[#el("a", (href: to, title: if i.rec != none { "watch it here; the docs: " + i.docs } else { "the docs" }))[#i.name]] + } ] #el("p", (class: "credit"))[#landing.credit] #el("p", (class: "runs"))[#landing.status] @@ -203,9 +219,9 @@ #el("h2", (class: "shelf"))[#landing.window] #el("div", (class: "clips"))[ #for c in clips.filter(c => c.at("landing", default: true)) { - el("figure", (class: "clip"))[ + el("figure", (class: "clip", id: "rec-" + c.name))[ #if c.ready { video(c) } else { placeholder } - #el("figcaption")[#c.caption] + #el("figcaption")[#caption(c)] ] } ] -- cgit v1.3