Skip to content
Polytope

Changelog

Every release, newest first, on the history wall.

0.7

11 October 2026On npm and PyPI

Release 0.7.2. Every release gets its numeral on the wall below, newest first, with what changed and how to update.

0.7

  • 0.7.2, the Atlas flies again

    13 October 2026

    • The Atlas flies from entry to entry again, as in 0.7.0. The ride with the scroll in 0.7.1 followed every step of the wheel and moved too fast to read.
    • Two things from 0.7.1 stay, in the flights' own pace. A short entry still gets its landing: scroll past up to two entries during a flight and the ball stops at their places in turn, each of those legs a little quicker, while a longer jump flies straight there. And a new entry mid-flight turns the ball from where it is, with its trail unbroken, where before it jumped ahead to the place it had been flying to.
    • Kept from 0.7.1 as well: outlines out of view are not drawn, the kind filter comes with the page, the caption under the pinned globe on phones keeps two lines, an entry with no place holds the globe at the one before it, and a drag cut short by the window losing focus leaves no touch behind.
    • To update: npm update @dario-loi/polytope. Nothing in the markup changes.
  • 0.7.1, steadier loading and scrolling

    13 October 2026

    • A complex with autoplay="visible" waits as bare points from the first paint. Before, the server's finished drawing showed until the script loaded, then vanished and grew again, which on a slow phone looked like a flash. Without script, or with reduced motion, it is still drawn finished, and if no script takes over within five seconds the finished drawing comes back.
    • The complex keeps every edge and triangle it has drawn, in order of the radius where each appears, so a new radius adds or removes only the cells in between instead of redrawing the whole figure. On a CPU slowed six times, a frame of the growth went from 16 to 6 ms at 36 points and from 57 to 11 ms at 120. Dragging the slider gets the same saving.
    • The slider's printed value, the edge and triangle counts, and the complex's label are written only when they change, and the label keeps the finished counts while the complex grows.
    • A growing complex's slider and counts start at 0, to match the bare points, and the script sets them as it grows. With scripts off they are hidden, since they cannot move. Printing, or switching reduced motion on mid-growth, jumps to the finished complex. A probability machine that has not run yet, or is still running, shows its settled curve on paper.
    • The Atlas rides the route with the scroll. Between two entries the globe and the ball move along the great circle as the reader scrolls, and back when they scroll up. Before, a timed flight started once the next entry was current and trailed behind the reading, and a short entry passed in a moment could be skipped. A stop on the way settles on the current entry, and a fast scroll catches up through every place it passed. Dragging or zooming the globe still leaves it where the reader put it, and under reduced motion it still jumps.
    • The Atlas draws less. A continent's coast is kept in runs, and a run out of view is drawn as a line between its ends, which leaves every pixel on screen the same; at a stop's zoom a frame is 15 to 45% quicker. A moving globe keeps the coarse outlines until zoom 5, and a scroll that leaves the globe where it is draws nothing. With the CPU slowed four times, a scroll through a CV on a phone drops 16% of frames, against 46% before. On phones the caption under the pinned globe keeps two lines, so a longer name no longer pushes the entries down and flips the current one back.
    • The Atlas draws its kind filter on the server. Before, the script added it above the entries once it loaded, and on a phone the list moved down about 64px under the reader. With scripts off the filter is hidden. Plain HTML keeps working as before: an empty, hidden filter box is filled by the script.
    • <Seo citation> gives its ScholarlyArticle record an @id: the canonical address with #article. A fuller record of the same paper that a site writes with that @id now merges with it, where before a page carried two records that counted as two works. citation.id sets another one; a noindex page has none unless given. See SEO.
    • <Seo> writes records that share an @id as one, with the fields given in schema winning and the ones they leave out kept. A site's fuller record of a paper now merges into the one Seo writes, so a page no longer lists every author twice. The Person record has an @id, the site's home with #person (or person.id); on the home page siteName writes a WebSite record, #website; and the paper record gains its PDF, preview picture, page range, language, and mainEntityOfPage from the props already given.
    • Fixes: an Atlas entry with no place, such as remote work, holds the globe at the place before it; before, the map stopped there with an error. A drag cut short by the window losing focus no longer leaves a touch behind that turns the next drag into a pinch. A drag mid-way, or reduced motion switched on, ends the ride cleanly with the place's name back. A complex whose points or radius is not a number draws the default instead of nothing.
    • To update: npm update @dario-loi/polytope. Nothing in the markup changes.
  • 0.7.0, list pages

    13 October 2026

    • New <Card> and <CardGrid> for list pages of papers, posts, and projects: a black panel with the entry's figure, or a complex seeded from its title, then the title, a meta line, a summary, and tags. A lead card spans the row and sets its title in wood type; a grid with fewer cards than columns shares the row between them. Labels over a figure use the new flag tokens and .ply-label--flag. See Cards.
    • <PaperHeader fold={12}> folds a long author list to the first names, yours, and the last, with a button for the rest. The fold is in the page as built, so nothing moves while it loads; without script, and on paper, the list shows whole. <PubList fold> folds author lines as text. A link with primary: true becomes the header's primary button.
    • The pager shows a title's name and keeps its subtitle for screen readers, so a paper's long title no longer outweighs the page. Its labels balance, and prevText and nextText rename the directions.
    • A mast without an exhibit stays one column at every width, so a list page's title is no longer squeezed beside an empty column. <Mast compact> sets a smaller title. New <MastTitle> and <WoodTitle> set mast and header titles in your own layouts, sized from a table of Ultra's widths, and the helpers behind them (woodTitle, splitTitle, emWidth) are exported.
    • BibTeX wraps long fields under their value instead of scrolling; <Code wrap> does the same for any block. A code block takes focus only while it scrolls.
    • Fixes: under reduced motion, a theme change no longer paints the whole Atlas tomato. The chapter menu closes on Escape, a press outside, or focus moving past it. Printed code is in ink, a long code block no longer leaves a page nearly blank, and links to other sites print their address. The wordmark, publication titles, and the author toggle grow to 44px targets under a finger, and .ply-target does the same for your own links. A segmented row fits a phone, a ghost button that wraps lines up with the row's edge, and the abstract's label is set as the other section headings.
    • <Atlas quiet> drops the place count and drag hint from the caption. <Empty level> makes its title a heading, as a 404 needs, and its mark is now a few loose points. <PubList label={false}> drops the region name where your own section has a heading. <ThemeToggle persist={false}> keeps the choice for the page only; the docs now say the toggle stores ply-theme in localStorage. A slider's value is set in the text face, so a page without code loads no mono font, and @dario-loi/polytope/fonts.css is exported for loading the CSS a component at a time.
    • To update: npm install @dario-loi/polytope@^0.7.0, since npm update stays within 0.6. Headers in a box that shrinks to fit its content now need a width. Pager labels with a colon show only the name, and BibTeX blocks wrap; pass split={false} or wrap={false} to keep the old look.

0.6

  • 0.6.3, long titles

    12 October 2026

    • Paper and post titles size to the header's own width, not the window's, so a title in a column beside an exhibit sets as it does across the page. Before, it kept its full size there, about nine characters to a line. A title runs about 22 characters to a line, and longer lines for a long title, so most keep to three lines. On phones a long title can drop toward 24px, and a title's longest word never breaks.
    • A paper title with a subtitle (the part after the first colon) sets the name in wood type and the subtitle under it in the text face. The colon stays in the heading, hidden, so screen readers and copies keep the whole title. Pass split={false} to keep the whole title in wood type. See Research for the plain HTML.
    • Short hyphenated terms such as Test-Time stay on one line. The venue line is balanced, so its last word is not left alone. Author, affiliation, and tag rows keep one baseline inside .ply-prose.
    • To update: npm update. A title with a colon now shows its subtitle under the name; pass split={false} where you want one kept whole.
  • 0.6.2, your name in bold

    12 October 2026

    • <PaperHeader> takes me, the author name to set in bold, as <PubList> already did. The other names drop to regular weight so yours shows; every name was semibold, so a bolder weight alone would not. In plain HTML, give your li in .ply-authors the class ply-me. See Research.
    • To update: npm update, then pass me with your name as it reads in authors. A header without it looks as before.
  • 0.6.1, long routes

    12 October 2026

    • The Atlas route fades with time. While an entry is current, the moves into and out of its place keep the full chalk, and the rest of the route fades with each move away from it, to 0.55, 0.3, then 0.15 of the chalk, so a long CV no longer covers the globe in lines. With no entry current, as past the last entry, the whole route is chalk. The weights ease in as the current entry changes.
    • A flight whose route passes near a pole turns the globe smoothly with the route and lands with north up. Before, keeping north up all the way could spin the globe half a turn in a few frames. If a drag stops a flight partway, the drag turns the globe the way the pointer moves, and the globe turns back to north up once you let go.
    • To update: npm update. Nothing to change in your pages.
  • 0.6.0, reading pages

    12 October 2026

    • New: .ply-article and <Article>, the frame for a paper, a post, or a page of notes. The text sits at the centre of the page, the on-this-page list hangs in a rail at the left edge from 80rem, and the margin after the text holds sidenotes and margin figures. No block straddles the edge between text and margin: in an article, .ply-wide keeps to the text, and a long table or line of code scrolls in its own frame. Below 80rem the list waits in an "On this page" disclosure above the text, and the current section in the rail gets the tomato point. <Article> builds the list from the headings at build time, so it needs no script. Before, a paper page kept its text against the left edge, with the margin and the list both to its right. See Space and layout.
    • New: .ply-margin and <Figure margin> put a small figure, table, or code block in the margin, beside the paragraph after it. On narrow screens it stays in the text.
    • New: <PostHeader>, for posts and notes: the title set like a paper's, a lede, the date, the reading time, and tags. The new blog post pattern shows a whole post.
    • The margin widens with the page, from 14rem to 21rem, so sidenotes end at the page's edge. A section heading starts below any sidenote still beside the text, so a note no longer sits beside the next section. On a docs page, a wide block (.ply-wide) also starts below the note, so it no longer runs over one, and <Figure wide> runs past the text like any wide block; before, it only dropped its maximum width.
    • Docs pages put the text at the centre of the page once the sidebar has room beside it, and the on-this-page list hangs under the current page in the sidebar. Sidenotes open into the margin whenever the main column has room for it, without waiting for 90rem.
    • From 100rem, docs and article text is 18px in a 38rem column: the same 68 characters to a line, at a size that suits a wide screen. New tokens: --ply-size-body-wide, --ply-layout-measure-wide, and --ply-layout-margin.
    • <SideNav> takes a current slot, shown under the current page's link. On docs pages the phone menu lists the page's sections there too.
    • Paper and post titles balance their lines and are capped in em, so a title breaks the same way at every wide width and does not reflow when Ultra arrives. Table captions keep to the measure and stay in view while a wide table scrolls. A screen reader reads a sidenote's number once. The auto on-this-page list skips the headings of a paper or post header shown inside a page, and stays hidden until it has entries.
    • To update: npm install @dario-loi/polytope@^0.6.0. A docs grid that still has .ply-docs__toc keeps its three columns from 80rem; to move the list into the sidebar, put it in the current slot of <SideNav>. A paper page built by hand can switch to <Article>, as the paper pattern's source does.

0.5

  • 0.5.1, faster pages

    12 October 2026

    • Text keeps its size while the fonts load. New fallback faces scale Arial or Liberation Sans to Libre Franklin and Menlo, Liberation Mono, or Courier New to JetBrains Mono, and Ultra falls back to Liberation Serif Bold where Georgia is missing. Before, on a machine without Georgia, titles jumped when Ultra arrived. The font tokens name the new faces, which come with polytope.css.
    • Equation and M bring KaTeX's stylesheet, so only pages with math load it. An import of katex/dist/katex.min.css in your layout is no longer needed, and keeping it does no harm.
    • Code blocks below the screen skip their layout until the reader nears them.
    • The Atlas decodes its map and draws its first frame in short slices, so the page stays responsive while it does, and the server's globe stays up until the first frame is whole. The close outlines load once the reader scrolls, points, or presses a key. Its geometry runs about three times faster, with the same result.
    • The top bar keeps the search field's word wherever the tabs fit set closer, and drops it only when they need the room. Under reduced motion it could show the menu where the tabs fit; it now measures after its own changes settle, and again when fonts arrive.
    • A Copy button on a block titled with a file name reads "Copy train.py from Code panels".
    • To update: npm update. Nothing to change in your pages.
  • 0.5.0, search engines

    12 October 2026

    • New: <Seo> writes the head tags that search engines and link previews read: the title, the description, a canonical link, Open Graph and Twitter cards, and noindex. With person it adds a Person record for a homepage or CV; with citation, the citation_ tags Google Scholar indexes papers by and a ScholarlyArticle record. See Search engines.
    • The top bar shows the chapter tabs wherever they fit. Where they do not, they first set closer and the search field drops its word, then they fold into the menu. Before, between 72rem and the width the tabs needed, the bar ran past the edge of the page; on these docs that was from 1152px to about 1420px, most laptops. The new js/topbar.js measures the fit; TopBar and js/all.js load it.
    • Without the script, the tabs still show from 72rem, and tabs that do not fit scroll in their row instead of widening the page.
    • These docs now have a sitemap, link previews, and structured data, all from <Seo> and @astrojs/sitemap.
    • To update: npm install @dario-loi/polytope@^0.5.0. If your own CSS shows or hides .ply-topbar__links, check it against the data-ply-tabs attribute the script sets on the bar.

0.4

  • 0.4.1, fixes from an audit of 0.4.0

    12 October 2026

    • On phones the Atlas names the entry the reader can see. Before, the pinned globe covered the entry it showed. The globe is shorter on phones, and its caption names the current entry.
    • Wide tables, display equations, and .ply-scroll-cue boxes can be scrolled from the keyboard. While their content overflows, the new js/scroll.js makes each one a named region that takes focus, and when it fits again it is no longer a tab stop. js/all.js and Equation load it.
    • On touch screens, Atlas pins are 44px targets. The drawn point keeps its size.
    • Atlas frames cost about a quarter less to draw. js/all.js loads the Atlas element only on pages that have one.
    • The Atlas caption counts moves between places, so a return to a city counts again. When the reader reaches the end of the entries, the route lights up in the order it was travelled.
    • Search lists first the pages whose title or a section heading names every word of the query, and shows the chapter links again when nothing matches. The search button answers Space.
    • Each Copy button is named for the section its code sits in, as in "Copy the HTML for Text fields".
    • The table of contents skips headings inside an Atlas, and sidenote numbers stay out of the search index.
    • To update: npm update. Nothing to change in your pages.
  • 0.4.0, the Atlas

    12 October 2026

    • New: <Atlas> and <AtlasStop>, a globe of the places in a CV beside the entries that happened there. As the reader scrolls, the globe turns to each entry's place and a tomato ball travels the route to it. Pins pick entries and a filter shows one kind of entry; drag, pinch, or Ctrl and scroll move the globe. See Atlas and the new CV page pattern.
    • The kit draws the map itself, from Natural Earth country outlines with borders as the United States recognizes them, so there are no map tiles, keys, or outside services. About 60KB, compressed, loads when an Atlas connects, and 76KB more for close views when it nears the screen.
    • Without JavaScript the server draws the finished globe with its places and route. Under reduced motion the globe jumps instead of flying, and on paper it prints once above the entries.
    • js/all.js now registers <ply-atlas>. The map code and data load only on pages that have one.
    • To update: npm install @dario-loi/polytope@^0.4.0. Nothing that already existed changed.

0.3

  • 0.3.0, site search and a new emblem

    12 October 2026

    • Your site can have search. Put <Search> in the top bar, run npx pagefind --site dist after your build, and mark each page's main content with data-pagefind-body. Readers open it with / or Ctrl+K; results come from your own pages, with nothing hosted elsewhere. See Navigation.
    • The Vietoris-Rips complex is the emblem: it opens these docs and draws the favicon. <Complex autoplay="visible"> grows it from bare points the first time it is seen; without the attribute nothing changes.
    • Inside a panel, controls now read: checkboxes, switches, ghost buttons, inline code, and tables draw in chalk on black. If you set something inside a .ply-panel to --ply-color-text and meant black, use --ply-ink-950.
    • Long content no longer widens a page. A long button label wraps to two balanced lines, a long tag wraps, a segmented row longer than its space scrolls in its frame, and names in a table's first column stay whole while the table scrolls.
    • hidden now hides any element, including one whose class sets a display, such as a button.
    • Pages written right to left mirror the switch, the select arrow, the sidebar point, the menu, the skip link, and sidenotes. Code blocks stay left to right.
    • Code blocks show the soft scroll cue, and each Copy button is named for the code it copies.
    • .ply-wide on a block inside the reading column now runs to the edge of a main column that names itself ply-main.
    • A complex with many points stays responsive: past 2000 triangles its fill is drawn as one shape.
    • To update: npm install @dario-loi/polytope@^0.3.0. Check panels that hold your own content, and buttons you gave a fixed height.

0.2

  • 0.2.1, three fixes from sites that use it

    11 October 2026

    • A .ply-visually-hidden element inside a wide table no longer widens the page. Table wraps, display equations, .ply-scroll-cue, and code blocks are now the containing block for what they scroll.
    • Printed pages keep the fill of primary buttons, pressed segments, the current tab, checked boxes, switches, labels, tags, and status marks. Before, their labels printed white on white and checked boxes printed empty.
    • The Empty title is display size again. The rule for its body text no longer matches the title.
  • 0.2.0, fixes from an accessibility audit

    11 October 2026

    • The Astro components load their scripts from dist/js. In 0.1.4, six of them (ThemeToggle, Machine, Complex, Code, Slider, Toc) imported files the npm package leaves out, so a site that installed from npm failed to build. npm run check:package now fails CI when a packaged file points at something the package does not ship.
    • A hovered button fills with --ply-color-accent-text and labels with the new --ply-color-on-accent, which keeps 4.5:1 in both themes.
    • Inside panels and code blocks, muted text and the focus ring take their panel values. On mustard notes the ring is black. Mark other surfaces with data-surface="panel" or data-surface="note".
    • Windows contrast themes keep checks, radio balls, switches, the current tab, and status marks visible. Pages print in the light theme with ink-on-white panels.
    • On touch screens, small controls grow to 44px. The top bar and the pager fit at 320px.
    • Citation cards no longer widen the page on phones, stay open under the pointer, and close with Escape (js/cite.js).
    • A machine that starts by itself finishes within five seconds. Changing its attributes no longer fires ply-machine-done, and its label reads out the counts.
    • Sliders set aria-valuetext, the loading indicator announces its text, and the theme toggle is a "Dark theme" toggle button.
    • PaperHeader and AppShell take a level prop for their heading. Sidenotes stay inline when the main column has no room for the margin.
    • New token --ply-size-ui (15px) for tabs, tables, notes, and sidebar links. Chart text uses --ply-size-xs.
    • Titles no longer jump when Ultra arrives. A new Ultra Fallback face scales Georgia Bold to Ultra's metrics, and the display stack lists it right after Ultra.
    • To update: Status is a live region only with live, so add it where a script changes a status outside an app shell. The kbd and blockquote element defaults moved to the base layer, and any class now wins over them.

0.1

  • 0.1.4, on npm and PyPI

    11 October 2026

    • Polytope is published as @dario-loi/polytope on npm and polytope-theme on PyPI. Installs need no .npmrc line, and upgrades work with npm update.
    • The design command runs as npx @dario-loi/polytope, which can only ever fetch this package.
    • A release workflow publishes both packages from GitHub releases through trusted publishing, with npm provenance.
  • 0.1.3, no install scripts

    11 October 2026

    • The built dist/ is now committed and the prepare script is gone, so installing from GitHub runs no install scripts. npm 12 no longer prints the "install scripts blocked" warning, and nothing needs approving.
    • CI rebuilds and fails if the committed dist/ differs from a fresh build.
  • 0.1.2, safer install commands

    11 October 2026

    • Install commands quote the git address, since zsh reads an unquoted # as a glob pattern.
    • The docs and the command's own messages no longer suggest npx polytope-design, which falls back to the public npm registry when the package is missing. Use ./node_modules/.bin/polytope-design or an npm run script.
    • A no-npm path for static sites: fetch DESIGN.md and design.json pinned to a release tag.
  • 0.1.1, the design record ships

    11 October 2026

    • The package now includes DESIGN.md and design.json, the files Impeccable reads to know a project's visual system.
    • New command polytope-design copies them into a site; --check reports a stale copy.
    • CI runs on Node 24 and the current GitHub action versions.
  • 0.1.0, first release

    11 October 2026

    • Tokens in the W3C format, compiled to CSS, JavaScript and TypeScript, JSON, Sass, Tailwind v4, LaTeX, a code theme, and Python.
    • CSS core in cascade layers, with light and dark themes and self-hosted fonts.
    • Components for buttons, navigation, notes, forms, tables, code, research pages, long-form writing, demos, and charts.
    • Two working models: the probability machine and the complex.
    • 32 Astro components.
    • Python theme for matplotlib, plotly, Gradio, and Streamlit.
    • This site, with three pattern pages.