All notable changes to Telar will be documented in this file.
Upgrade environment repair release. Fixes the "Upgrade Telar" GitHub Actions workflow, which has failed with a Python ModuleNotFoundError for every site upgrading to v1.5.0 or later — the workflow installed only two of the packages the upgrade's data-regeneration step needs. upgrade.py now installs its own dependencies as a fallback, so upgrades succeed even on sites whose workflow file predates this fix (GitHub does not allow automated upgrades to modify workflow files). Also repairs two regressions from earlier releases: a package-lock.json left out of sync by the v1.6.0 upgrade, and a missing guard that let Telar's internal framework tests run — and fail — on user sites. Tooling and workflows only — no site content, configuration, or display changes.
- Upgrade workflow
ModuleNotFoundError. The "Upgrade Telar" GitHub Actions workflow installed onlypyyamlandpandas, but the upgrade's data-regeneration step also needsmarkdown,Pillow,jinja2, andcryptography. No workflow-driven upgrade targeting v1.5.0 or later could have succeeded. The workflow now installs the fullrequirements.txt, matching the build workflow. - Upgrade tooling now self-sufficient.
upgrade.pyinstalls its own dependencies from the release's tooling bundle before regenerating data, with a fallback to the site's own copy. This means upgrades succeed even on sites that haven't recopied the fixed workflow file above. - Corrected
package-lock.json. The v1.6.0 upgrade leftpackage-lock.jsonout of sync withpackage.json, which brokenpm ciin site test workflows. This release ships a regenerated, matching pair, and the v1.6.2 migration re-applies both together on upgrade. - Framework tests no longer run on user sites. A guard that keeps Telar's own test suite from running on user sites was dropped in v1.5.0, causing spurious test-failure emails whenever dependabot opened a pull request on a user site. The guard is restored.
- No more duplicate upgrade issues. Re-running the "Upgrade Telar" workflow no longer files a second upgrade issue alongside an existing open one for the same version.
.github/dependabot.yml. Dependency updates are managed through the Telar release process, not per-site. The file is removed from the template and, via the v1.6.2 migration, from existing user sites. Repository-level GitHub security alerts are unaffected.
- Migration script
scripts/migrations/v161_to_v162.pyupgrades automatically from v1.6.1 (and chains through from earlier versions). Two manual steps: recopying.github/workflows/upgrade.ymlfrom the template is recommended but not urgent, sinceupgrade.pynow self-installs its dependencies regardless; recopying.github/workflows/telar-tests.ymlstops Telar's framework tests from running on your site. Thedependabot.ymlremoval is informational only. - New consistency tests run in Telar's own CI on every pull request to catch this class of workflow/dependency mismatch before it ships again.
Upgrade-tooling fix release. The v1.6.0 upgrade could not actually be applied: the upgrade script never registered the v1.6.0 migration, so direct upgrade runs stopped at v1.5.4 while reporting success — and the release was missing the verified tooling package the "Upgrade Telar" workflow downloads, so workflow runs failed before making any changes. Both are fixed; upgrading to v1.6.1 applies everything v1.6.0 contained. No site content, configuration, or display changes.
- Upgrade chain repaired.
scripts/upgrade.pynow registers the v1.5.4 → v1.6.0 migration (the migration itself shipped with v1.6.0 but was never wired in) and the new v1.6.0 → v1.6.1 step. Upgrades from any earlier version now run through to v1.6.1 and stamp the version they actually installed. - Verified tooling package published. The
telar-scripts-v1.6.1.tar.gzrelease asset and its checksum, which the "Upgrade Telar" workflow requires since v1.5.0, ship with this release (v1.6.0 shipped without them, so the workflow failed closed before touching any site).
- If an upgrade run reported success but left your site at v1.5.4, run the upgrade again — the chain now continues through to v1.6.1. If the "Upgrade Telar" workflow failed with a download error, that was this bug.
- No site was ever left broken or half-upgraded: the workflow path failed before starting, and the direct path completed a valid upgrade to v1.5.4.
Code health release. Housekeeping across the whole framework — verified dead-code removal, consolidation of duplicated logic, honest labelling of generated vs source files — plus a rebuilt private-stories pipeline, a localization sweep, and a long tail of fixes. Framework files and language packs upgrade automatically; one manual step is required for sites that use private stories (see Notes).
- Private stories rebuilt. Encryption now happens after the site is built, from the fully rendered page: unlocked stories render glossary links, LaTeX, and localized errors exactly like open stories. The build scans its own output for private content before publishing, and a site with private stories and an outdated build workflow fails on purpose rather than publishing unprotected.
- Localization sweep. Interface text that was hardcoded in English now follows the site language (media-type labels, audio controls, story chrome, glossary headings, panel errors, carousel controls, degraded-mode navigation, upgrade alerts, embed banner fallback); pipeline warnings and the upgrade summary are generated in the site's language.
- Theme colours where they belong. Headings, glossary letters, filter toggles, and panel blockquotes follow the active theme; DEMO labels use the brand colour; the accordion focus ring is visible again.
- Code health. Over 750 lines of verified dead code removed; duplicated logic consolidated to single homes (media-type lists, SCSS mixins, pipeline helpers, IIIF thumbnail resolution, object-page theme/video logic, KaTeX configuration); generated files carry generated-file banners and are marked linguist-generated; comments state constraints instead of narrating history. No reader-facing changes.
- Alt text from the objects CSV now reaches object pages and story steps (from Ana María Cárdenas Gasca's fix).
- Audio clips honour
clip_starton first play, not only after looping. - LaTeX in a step's question or answer (without layer text) now loads the renderer.
- Local tile generation without libvips produces tiles the viewer can actually request; the generator names its backend and recommends libvips.
- The objects page no longer makes doomed image-server requests for video/audio objects; thumbnail resolution is hardened across IIIF profile variants.
- Panels: no instance leak on reopen, state stays in sync on outside dismissal, close icon shows in vertical/embed layouts.
- Embedded stories use the site-wide 1024px responsive boundary; button navigation starts from the intro card; uppercase audio extensions recognised; palette-transparency images composite onto white; a text step without coordinates shows the full object; title-card text renders as plain text per its contract.
- Manual step for private-story sites: v1.6.0's build workflow adds the encryption step, and GitHub does not allow automated upgrades to modify workflow files — recopy
build.ymlfrom the template (the Compositor does this automatically). Until then, marking a storyprivate: yesfails the build by design. See the release notes for details. - Language packs are replaced wholesale on upgrade, as in previous releases — re-apply customisations.
- Known issues: two long-standing story-engine behaviours (a card briefly lingering over the title after "Back to Start"; the URL step fragment not updating during ordinary scrolling) ship documented, to be fixed at the root by a planned story-engine restructure.
CI/build fix release. Adds a GitHub Pages concurrency group to the build workflow so rapid successive builds of the same repository no longer race on Pages' one-deployment-per-repo limit. CI only — no content, schema, or configuration changes. Upgrade in place or simply redeploy.
- Spurious "build failed" emails on rapid successive builds. GitHub Pages allows only one in-progress deployment per repository, so when several builds started within the same second (for example, when a new site is created and multiple commits plus a manual run land together) the losing runs failed their "Deploy to GitHub Pages" step and emailed the owner, even though the site deployed correctly. Build runs are now grouped per branch with a
concurrencysetting and superseded runs are cancelled, so the newest build wins cleanly with no failure noise.
- The only changed framework file is
.github/workflows/build.yml. The Telar Compositor updates it automatically on upgrade; sites upgrading via the "Upgrade Telar" Actions workflow or locally must add theconcurrencyblock by hand, since GitHub does not allow automated upgrades to modify workflow files (see the release notes for the exact snippet).
Internationalization fix release. Built-in interface text that still showed in English on Spanish-language sites (telar_language: es) now follows the site language. Display only — no content, schema, or configuration changes. Upgrade in place or simply redeploy.
- Interface text now follows the site language. Several built-in strings were hardcoded in English and stayed untranslated on Spanish sites: the "Back to Collection" and "Back to Glossary" links, the coordinate tool button with its Copy X / Y / Zoom and copy-manifest tooltips, the "Image Viewer Unavailable" alerts, the Google Sheets and theme configuration-error banners, the thumbnail "Loading..." placeholders, and the footer credit line. They now read from the language pack and follow
telar_language. - Objects and glossary headings now translated. The objects and glossary page headings, and the Medium/Genre and media-type filter labels on the objects page, now follow the site language instead of showing in English.
- Duplicate browser-tab title on translated pages. Translated pages emitted two
<title>tags, and the second (added by the SEO plugin) was always English. Each page now has a single, language-aware title. The home, objects, and glossary browser-tab titles follow the site language through a new optionaltitle_keyfield (see Migration).
- Objects page wording (English sites). The objects page now takes its heading and browser-tab title from the language pack: the browser-tab title reads "Objects" (was "Objects in the Stories") and the page heading reads "See the objects behind the stories". Spanish sites already used these strings.
- Social-share preview titles (
og:title/twitter:title) still come from the static English page title and remain English on translated sites. The SEO plugin binds them to page front matter and cannot suppress just the social title; this is a known, separate limitation.
Small fix release for the validation warning banners. Display only — no content changes and no manual steps. Upgrade in place or simply redeploy.
- Glossary warning message. When a story references a glossary term that doesn't exist, the warning showed a literal
{{ file_path }}placeholder and pointed only totelar-content/texts/glossary/. It now names the missing term cleanly and points to your glossary spreadsheet as well as the markdown folder. - Story banner heading shown twice. The warning banner on a story's intro card repeated the same line as both its heading and its description; it now has a proper heading.
- Homepage warning banners now translated. The "Object configuration issues detected" and "Story configuration issues detected" banners on the homepage (headings and the "Navigate to ... to see more details." line) were hardcoded in English; they now follow the site language.
- Routine dependency updates:
lenis,esbuild,vitest,@vimeo/player(npm);cryptography,jinja2,pillow-heif,playwright,pyyaml(Python);ruby/setup-ruby(CI). No behavior change.
- The README version badge had lagged at 1.4.0 through the last two releases; it is now correct.
Small fix release for glossary auto-linking. The [[term]] syntax now works in story step texts, and glossary terms match regardless of letter case. Runtime and tooling only — no content changes and no migration. Upgrade in place or simply redeploy.
- Glossary links in story step texts. Writing
[[term]]in a story step's answer text now creates a glossary link, just as it already did inside layer panels. Previously the brackets published as plain text. The question line is a heading and is intentionally left as plain text. - Case-insensitive glossary terms.
[[Term]],[[term]], and[[TERM]]now all resolve to the same glossary entry, matching whatever id the glossary defines (so an acronym written[[IIIF]]links correctly). The link points at the glossary entry's own page regardless of how the term was typed.
- In password-protected stories, a
[[term]]in the step text shows as plain text (the term's name) rather than a clickable link. Glossary links inside layer panels still work in protected stories. (Inline glossary links in the step texts of protected stories may come in a later release.)
Robustness and security release. Runtime and tooling only — no content changes; existing stories, objects, and configuration continue to work unchanged. This release hardens the build pipeline, the story viewer, and the automatic upgrade workflow, adds defensive input handling and output escaping throughout, and removes the last third-party CDN dependency by vendoring the audio waveform library. The automatic upgrade applies everything except two manual steps (see Migration).
- Output escaping throughout. Author-supplied content (titles, alt text, captions, questions and answers, glossary terms, image attributes) is now escaped at every render sink, in both the Python build and the JavaScript runtime. Jinja2 autoescaping is enabled for widget rendering.
- TLS certificate verification restored on all Google Sheets and IIIF manifest fetches (verification had been disabled).
- Protected (password-locked) stories. The build now fails closed if a protected story cannot be encrypted, instead of shipping it as plaintext; PBKDF2 iterations raised from 100,000 to 210,000; encrypted stories no longer expose byline, description, or SEO metadata; the in-browser unlock cache no longer stores decrypted content.
- Hardened automatic upgrade workflow. It now downloads its tooling as a checksum-verified release asset and runs it in isolation, refusing to run unverified code. The target-version input is validated and passed safely.
- KaTeX math rendering is constrained to safe links only.
- Path-traversal guards on object IDs and story layer filenames, and size caps on all remote reads (Sheets, demo bundle, PDFs, IIIF).
- Audio waveform library vendored. WaveSurfer is now served from your own site instead of a CDN, so audio stories and audio object pages work offline and carry no third-party runtime dependency.
- Upgrade engine. Framework files are now installed atomically (all-or-nothing with backup and restore), and migrations are chained strictly, failing closed on any error.
- Dependency floors raised. Minimum versions bumped for
pandas(3.0.3),markdown(3.10.2), andcryptography(48.0.0), plus the test toolspytest(9.0.3) andpytest-cov(7.1.0). Sites upgrading in place are unaffected — the framework fixes use the standard library — so the new floors apply to fresh installs and the project's own CI.
- IIIF viewer plate visibility. The image plate now stays visible when navigating between steps that share the same object, and same-object focal interpolation uses the correct step list.
- Story panels. Closing a panel is handled consistently (no double-close), and opening a layer panel correctly dismisses an already-open panel.
- Deep links. Panel-open timers are cancelled if the reader navigates during load, so a panel no longer pops open over a different step.
- YouTube and Google Drive video sizing. Non-16:9 videos are now sized to their true aspect (or given an intentional dark letterbox frame) instead of floating in the page background.
- Audio and scroll-engine lifecycle. Resolved assorted race conditions and re-initialization issues.
- Theme button text. Restored the button-text color fix (carried from a v1.4.0 hotfix that missed the v1.4.0 tag) so themed buttons no longer render with invisible text.
- Story step order. Steps now render in the order of their
stepnumber rather than the spreadsheet's saved row order, so a story whose rows ended up out of sequence still displays correctly. Falls back safely to the saved order if step values are missing or non-numeric.
- The automatic upgrade applies all of the above. Two manual steps remain, listed in your
UPGRADE_SUMMARY.mdafter upgrading:- Update your two GitHub Actions workflow files (
upgrade.yml,build.yml) by hand — GitHub does not allow the automated upgrade to modify workflow files. Your site keeps building if you skip this; the changes only harden your workflows. - Re-apply any customizations to the language packs (
en.yml/es.yml), which were refreshed with the new protected-story sharing warnings.
- Update your two GitHub Actions workflow files (
- No content changes: no CSV schema, story-step, or
_config.ymlkey changes.
Runtime upgrade with no content changes required. Existing stories, objects, and configuration continue to work unchanged. This release replaces the Tify viewer with a custom, self-hosted OpenSeadragon wrapper and rebuilds the responsive system around a single source of truth, fixing cross-device IIIF centering.
-
Cross-device IIIF centering: Rewrote the focal-point algorithm using a two-circle model that derives a device-independent focal radius from the authoring aspect ratio and reads the measured text-card rectangle. Fixes focal points landing off-target across viewport widths, high-zoom near-bottom clipping, iPad portrait Y pinning, horizontal drift under zoom, and a low baseline. Verified on iPhone and iPad portrait via iOS Simulator and a 12-cell device matrix.
-
Deep-link and in-story navigation jump:
navigateToStep()andapplyDeepLinkOnLoad()previously used a manual scroll poke that left the scroll engine in a stale state, freezing the IIIF viewer at a partially-interpolated zoom. Both now use a forced immediate scroll with snap-index sync, giving a deterministic jump to the authored position. -
iOS Safari URL-bar layout jump: All layout-affecting heights now use
dvhwith avhfallback via@supports. Eliminates the reflow that occurred when the Safari URL bar showed or hid on scroll. -
Notch safe-area clearance: Applied
env(safe-area-inset-*)at the credits badge, mobile navigation buttons, and mobile text card using themax(<offset>, env(...))idiom. -
Hover styles on touch devices: All
:hoverrules are now wrapped in@media (hover: hover) and (pointer: fine), so touch devices no longer show sticky hover states. -
Reduced-motion compliance: Smooth scrolling is disabled when
prefers-reduced-motionis set, and IIIF pan/zoom animations apply immediately under the same preference.
-
Custom IIIF viewer: New
assets/js/telar-story/iiif-viewer.jsandiiif-manifest.jswrap OpenSeadragon and parse IIIF Presentation API v2 and v3 manifests, supporting multi-page manifests, a pagination chrome for multi-page objects, and an error fallback UI. Scroll-to-zoom and click-to-zoom stay under Telar's scroll-engine control on story plates; object pages opt in to zoom gestures. -
layout-mode.js— responsive runtime module: Replaces the binarystate.isMobileViewportflag with astate.layoutModeabstraction ('horizontal'/'vertical'). Owns the singleresize/orientationchangelistener in the runtime and reads breakpoints from CSS custom properties so JS and CSS cannot drift. -
--telar-*CSS custom properties:_sass/_responsive.scssis now the single source of truth for layout-affecting constants (breakpoints, card geometry, density tiers, audio/video scaling factors), mirrored to--telar-*properties on:rootfor JS to read viagetComputedStyle. -
Container queries on
.text-card:container-type: inline-sizeadded; font size, padding, gap, and line height inside the card now scale off the card's own width. -
Six
object.viewer.*language keys inen.ymlandes.yml(prev_page,next_page,page_input_label,page_input_aria,image_unavailable_title,image_unavailable_detail) for the IIIF viewer chrome and error UI.
-
Cascade layer order: Bootstrap 5.3.0 is now loaded inside a
@layercascade layer, so Telar's own rules take precedence without!important. Over 150 Bootstrap-fight!importantdeclarations removed across_sass/. -
Breakpoints recalibrated: the vertical layout now activates at widths narrower than 1024px or aspect ratios narrower than 3:4, covering tablets in portrait as well as phones.
-
Height-tier blocks consolidated: nine
@media (max-height: ...)blocks across the stylesheets collapsed into one block in_sass/_responsive.scss. -
Vendored OpenSeadragon 6.0.2:
assets/vendor/openseadragon.min.js(337 KB) replaces the Tify CDN load. Source and SHA-256 digest are recorded inassets/vendor/README.md.
-
Tify IIIF viewer and Vue dependency: removed the Tify CDN stylesheet and module imports from
_layouts/story.htmland_layouts/object.html, along with the 56!importantdeclarations in_sass/_viewer.scssthat existed solely to hide Tify's UI chrome. Tify's ~529 KB CDN payload (469 KB JS + 60 KB CSS) gives way to a 337 KB vendored OpenSeadragon — about 190 KB less viewer code, served locally with no CDN dependency. -
state.isMobileViewport: replaced bystate.layoutMode. -
Stale bundle files:
assets/js/telar-story.bundle.jsandassets/js/telar-story-bundle.jsdeleted (unreferenced leftovers from an earlier build naming scheme).
i18n hygiene plus a new sister-file localization convention. Wires up Telar's existing language packs in places that previously hardcoded English, introduces a sister-file convention for localizing user pages, and refreshes the demo content to reflect current capabilities (multimedia, Telar Compositor, dual storytelling/collections framing).
-
Homepage headings rendered in English for Spanish users:
_layouts/index.htmlnow resolves the stories and objects headings viapage.X | default: lang.pages.X | default: "<English literal>". Previously the layout dropped straight to the English literal when nopage.*override was set, and the template'sindex.mdshipped with English page-overrides that shadowed the i18n for every existing user withtelar_language: es -
Empty-state messages and IIIF URL warning hardcoded in English:
_layouts/index.html,_layouts/objects-index.html,_layouts/glossary-index.html, and_includes/iiif-url-warning.htmlnow referencelang.empty_states.*andlang.errors.iiif_mismatch.*keys that were already defined in both language files but never used. Spanish-language sites now show empty-state guidance and the IIIF mismatch troubleshooting modal in Spanish -
JS thumbnail fallback strings hardcoded in English:
_layouts/index.htmland_layouts/objects-index.htmlnow injectTelarI18nandTelarI18nIIIFconstants from the lang values, so the "Failed to load" and "No image" placeholders displayed when a thumbnail fails appear in the site's active language -
Empty-state messages pointed at the wrong content directory: empty-state guidance previously told users to add story/object/glossary files to
_stories/,_objects/, or_glossary/. Those directories are auto-generated; the canonical user-content paths are undertelar-content/spreadsheets/andtelar-content/texts/glossary/. The lang values had the correct paths; wiring them up fixed both the i18n bug and the misleading guidance -
Migration script language detection for Spanish sites:
BaseMigration._detect_language()was looking fortelar_languagenested under thetelar:block in_config.yml, but the key has always been a top-level key. Every Spanish-language site fell through to the English default for migration manual steps. The base class now reads the correct top-level key, so Spanish sites now get the Spanish-language manual steps inUPGRADE_SUMMARY.mdand (in v1.3.0 specifically) the conditionalacerca.mdcreation guard sees the correct language
-
Sister-file localization for user pages (
telar-content/texts/pages/):scripts/generate_collections.pynow detects markdown files with frontmatterlocalized_for: <canonical>.mdandlanguage: <code>. Whensite.telar_languagematches the sister'slanguage, the build uses the sister's content but writes output under the canonical filename — so/about/resolves to the right language without URL duplication. The v1.3.0 template ships withacerca.mdas the Spanish sister ofabout.md; users can add siblings for other languages following the same convention -
lang.index_page.welcomekey carrying the homepage welcome content as a multi-line markdown block scalar in both EN and ES. The defaultindex.mdbody now renders{{ lang.index_page.welcome | markdownify }}with a bilingual EN/ES override comment explaining how site owners replace it with their own content -
lang.pages.glossary_introkey for the glossary page intro sentence, paired with EN and ES values.pages/glossary.mdbody now references this key -
lang.errors.iiif_mismatch.local_fix_check_configandlocal_fix_run_with_note: two missing keys completing the IIIF URL warning's local-development fallback section -
Migration script
v121_to_v130.pyand matchingmigration.jsonmanifest: conditional content cleanup that removes the three staleindex.mdfrontmatter keys and replaces user-content bodies (welcome, glossary, objects, about) with the v1.3.0 lang-key templates only when a SHA-256 hash check confirms the file is byte-for-byte identical to the v1.2.1 default. Any user customisation preserves the file untouched. For sites withtelar_language: eswhoseabout.mdis unchanged from the v1.2.1 default, the migration also createsacerca.mdautomatically so the site immediately renders Spanish content at/about/. Sites with a customisedabout.mdskip this — otherwise the new sister file would shadow the customisation
-
Default content of welcome and about pages refreshed to reflect current Telar capabilities. Both now name both Telar modes (digital storytelling and publishing small digital collections), name multimedia coverage (IIIF images, video, audio, narrative text, contextual layers), present the three setup paths (Telar Compositor, GitHub template + Sheets, hands-on local), and link to the Telar Compositor. Previous content described Telar as it was around v0.7 (single-mode storytelling, GitHub template only, no audio/video, no Compositor)
-
pages/glossary.md,pages/objects.md,index.mdrewritten to render via lang keys rather than hardcoded English. Each file carries a bilingual EN/ES HTML override comment explaining how to replace the default with custom content. The pattern uses{% assign lang = site.data.languages[site.telar_language] | default: site.data.languages.en %}at the top of the page (the layout's ownlangassignment isn't visible to the page body, which Jekyll renders before wrapping in the layout) -
telar-content/texts/pages/about.mdrewritten with the refreshed copy plus a sentence in the Customize alert documenting the sister-file convention for site owners adding additional languages
- Stale
lang.pages.home_titlekey from bothen.ymlandes.yml. Defined since v1.0.0-beta but never referenced from any layout, include, or script
Patch release with a demo content fetch fix and project metadata additions.
- Demo content fetch tolerates v-prefixed
telar.version:scripts/fetch_demo_content.pypreviously raisedValueErrorinternally when_config.ymlhad a v-prefixed version string (e.g.version: "v1.2.0") and silently built sites with no demo content. An earlier version of the Telar Compositor's upgrade flow wrote v-prefixed strings into some sites; the compositor was fixed, but historical bad values persisted in upgraded sites. The fetcher now strips a leadingv(orV) when reading the version and again as defence-in-depth when parsing entries from the remoteversions.jsonindex. A new warning surfaces in the build log if a site version cannot be parsed for any other reason. Sites with stale v-prefixed values continue to work; the value can optionally be cleaned up to a bare numeric version
CITATION.cffwith author and ORCID metadata for academic citation- Migration script
v120_to_v121.pyand matchingmigration.jsonmanifest for the demo content fetch fix
- Expanded
package.jsonmetadata (version,description,license,author,contributors,homepage,repository,bugs) for clarity in the npm/GitHub ecosystem
Story structure and UX improvements.
-
Section card table of contents: Stories with
show_sections: yesin project.csv display a navigable TOC on the title card, listing every section card as a clickable link. The title card uses the layer 2 panel background color when TOC is enabled. Addmostrar_secciones: sifor Spanish-language sites -
Back to Start button: The "Back to Home" button in the top-left corner now switches to "Back to Start" once readers scroll past the title card. Clicking it returns to the title card. On mobile, the button shows a contextual icon (home or up-arrow)
-
In-story navigation: New
navigateToStep()andnavigateToIntro()functions allow jumping between steps from within the story, used by the TOC links and the Back to Start button -
Migration manifest: Each release now includes a machine-readable
migration.jsondescribing content transforms, attached as a GitHub Release asset. The Telar Compositor uses these manifests to upgrade sites through its web interface
- Story card placeholders: Homepage thumbnails now show the first letter of the story title instead of an auto-generated ordinal number. Related story links on object pages show the title only
- Deep link parent panel stacking: Deep links to layer 2 panels (e.g.
#s3l2) now correctly open layer 1 underneath, so all parent panels are visible when arriving via a shared link
Structural and navigational features for richer storytelling.
-
Deep linking: Share URLs that point to a specific step in a story, optionally with a panel layer open. The URL fragment updates silently as the reader scrolls, and shared links open directly at the right position
-
Title cards: Chapter heading cards that appear between story steps. Mark a step row with an empty object to create a title card — it displays styled heading text without a media viewer and participates fully in scroll, keyboard, and button navigation
-
Collection mode: Set
collection_mode: truein_config.ymlto flip the homepage to a collection-first layout with large object thumbnails and stories below. Default mode is unchanged -
Bibliography styling: Use the
:::bibliographywidget block in panel markdown content to format references with hanging indent (first line flush, subsequent lines indented) -
Share panel "this view" tab: The share panel now includes a tab that copies the current URL with the reader's exact position
-
Panel scroll: Wheel events inside open panels are no longer intercepted by the scroll engine. Users can scroll panel content freely without the story advancing
-
Keyboard navigation in panels: Arrow keys, Page Up/Down, and Spacebar now scroll panel content when a panel is open, instead of navigating story steps
-
Video/audio not paused on title cards: Media players now properly deactivate when scrolling from a video or audio card into a title card, in both directions
-
IIIF viewer background on object pages: The Telar weave pattern now shows correctly behind the IIIF viewer on object pages, instead of Tify's default grey dot grid
-
Audio object detection: Audio objects are now correctly detected even without the
audiowaveformsystem dependency, via a new audio manifest generated during the CSV-to-JSON pipeline -
ArrowRight on first step: Fixed an issue where pressing ArrowRight immediately after arriving at step 1 from the intro could fail because the scroll animation briefly reset the step index
- Panel DOM attributes: All panels now carry a
data-telar-panelattribute for consistent selector targeting
A new milestone.
This is Telar's twenty-fourth release. For the first time, Telar can weave together images, video, and audio — a major new stage that we hope will help you tell all sorts of new stories. Together with a fluid scroll engine (no more jumping!), a new card-stack architecture, and the WYSIWYG Telar Compositor, these features round out the roadmap we first sketched when we started building Telar. It finally feels like a 1.0.
None of this would have happened without all of you who tested early versions, reported what was broken, and told us what you needed. Thank you.
— Juan
-
Video support: YouTube, Vimeo, and Google Drive videos in stories and on object pages. Clip control (start, end, loop) lets you highlight specific segments
-
Audio support: Audio files with WaveSurfer waveform visualization in stories and on object pages. Clip regions for selecting segments
-
Clip time picker: Interactive tool on object pages for setting video and audio clip boundaries. Copy start/end times directly into your spreadsheet
-
Card-stack scroll architecture: Stories now use a continuous scroll model with magnetic waypoints instead of the previous step-by-step navigation. Cards slide over previous ones, creating a fluid reading experience
-
Media type detection and filtering: Objects are automatically classified as Image, Video, or Audio. The gallery page has separate type and medium filters
-
Alt text support: New
alt_textcolumn in story and object spreadsheets for accessibility descriptions, with automatic fallback to object titles -
Inline Lucide SVG icons: All icons are now self-hosted inline SVGs, replacing the Google Material Symbols and Bootstrap Icons CDN dependencies
-
Audio build pipeline: New
process_audio.pyscript for clip extraction and waveform peak data generation, integrated into the local build script and GitHub Actions workflow
-
Scroll system: Replaced the discrete step accumulator with Lenis continuous scroll and magnetic snap waypoints
-
Card rendering: New per-scene card pool with z-index banding replaces the previous split-column viewer/narrative layout
-
Mobile layout: Text cards are bottom-anchored on mobile with frosted glass styling
-
Object pages: Media-type-conditional rendering — images get the IIIF viewer with coordinate panel, videos get embeds with clip picker, audio gets waveform with region-based clip picker
-
Gallery: Video and audio objects show icon placeholders. Two separate filter sections (Type and Medium/Genre)
-
Viewer preloading:
max_viewer_cardsdefault reduced from 10 to 8
- Google Material Symbols CDN dependency: Replaced by inline Lucide SVGs
- Bootstrap Icons CDN dependency: Replaced by inline Lucide SVGs
PDF dependency fix.
- PDF IIIF tile generation in CI: PyMuPDF was not listed in
requirements.txt, so CI skipped IIIF tile generation for PDF objects entirely. PDF objects now get tiles generated correctly during builds
IIIF bug fixes, multi-page story improvements, and coordinate panel restyle.
-
IIIF crash for small images: Images smaller than 512px (the tile size) produced an empty
scaleFactorsarray ininfo.json, crashing OpenSeadragon/Tify with aRangeError. Now defaults to[1] -
IIIF edge tile 404s: Images larger than 1024px showed 404 errors for edge tiles. The
sizesarray had a single full-resolution entry that caused OpenSeadragon to miscalculate edge tile dimensions -
IIIF thumbnail generation: Thumbnails for all scaleFactor levels are now pre-rendered during IIIF generation, and width-only directories from libvips get
{w},{h}counterparts. Fixes broken homepage and gallery thumbnails -
Story page switching for multi-page objects: Navigating between story steps that reference different pages of the same object (e.g. different PDF pages) now correctly loads the new page instead of staying on the original
-
Coordinate finder column order: Multi-page coordinate copy buttons now output
x,y,zoom,pageto match the spreadsheet column order (waspage,x,y,zoom) -
Page column case normalisation: The
Pagecolumn from Google Sheets (capital P) is now normalised topage(lowercase), fixing PDF page-specific manifest loading in stories -
Page selector truncation: Fixed Tify 0.35 page selector text being cut off by targeting the renamed
.tify-dropdown-buttonclass -
Coordinate panel heading colour: The panel heading is now explicitly coloured in dark/light variants, overriding the global heading colour rule that made it unreadable on dark theme backgrounds
-
Object viewer orientation: Changed from landscape (fixed 600px height) to portrait (4:5 aspect ratio) on object pages
-
Coordinate panel styling: Replaced 50+ inline styles with a new SCSS partial (
_coordinate-panel.scss) using theme-aware colours via CSS custom properties and WCAG luminance detection -
Coordinate panel internationalisation: Instructions now use language keys instead of hardcoded English, with a multi-page variant that mentions the Page value
-
Thumbnail size selection: Homepage and objects gallery now pick the smallest IIIF size >= 400px wide for thumbnails, instead of blindly using the smallest available size
IIIF tile rendering fix and workflow cleanup. Thanks to Ashley Vazquez for reporting the Windows rendering issue.
-
IIIF tile rendering on Windows: Fixed incomplete
sizesarray ininfo.jsonthat caused OpenSeadragon to miscalculate zoom levels and request tiles with negative region coordinates. Thepatch_info_json()function now scans bothw,handw,(width-only) thumbnail directories generated by libvips. Thanks to Ashley Vazquez for catching this! -
TIFY 96px thumbnail: Generate
full/96,/0/default.jpgthumbnail that TIFY v0.35 hardcodes for its page navigator panel, regardless of IIIF profile level. Previously 404'd on static Level 0 hosting
- Test workflow scoped to main repos: The Test Telar Scripts workflow now only runs on
UCSB-AMPLab/telarandjuancobo/telar, preventing unnecessary CI runs on user sites that inherit the workflow
LaTeX math rendering and a file extension bug fix. Thanks to Jaydon Schuler!
-
LaTeX math rendering (KaTeX): Automatic per-page LaTeX detection and rendering using KaTeX 0.16.21. Supports inline math (
$...$), display math ($$...$$), and environments (\begin{align},\begin{equation}, etc.). Detection uses smart heuristics to avoid false positives (e.g.$50does not trigger math rendering). LaTeX works in story panels, object descriptions, glossary definitions, and custom pages. Sites without LaTeX content have zero overhead -- KaTeX is only loaded on pages that need it -
Encrypted story LaTeX support: Stories protected with encryption now support LaTeX. KaTeX loads dynamically after decryption if the story content contains math notation
- Case-insensitive file extension matching: Objects with uppercase extensions (e.g.
image.JPG,photo.PNG) no longer trigger false "file missing" warnings during the build or on the site. Extension comparison now uses case-insensitive matching when scanning the objects directory
Faster builds, simpler setup, and multi-page document support.
-
libvips IIIF tile generation: 28x faster tile generation using libvips as the preferred backend (
vips dzsave --layout iiif3). Falls back automatically to the Pythoniiiflibrary if thevipsCLI is not available. GitHub Actions workflow installslibvips-toolsautomatically -
Tify viewer: Replaced UniversalViewer with Tify (v0.35.0) across all viewer contexts. Tify uses fewer DOM nodes, provides a Promise-based readiness API, and exposes the OpenSeadragon viewer through a documented public property. All existing viewport coordinates remain compatible
-
PDF document support: PDF files placed in
telar-content/objects/are rendered into multi-page IIIF tile pyramids with per-page single-canvas manifests. Requires PyMuPDF (pip install pymupdf) -
Multi-page IIIF support: Story steps can reference specific pages of multi-page objects using a new
pagecolumn in the story CSV. The coordinate picker on object pages detects multi-page objects, shows pagination controls, and includes the page number in copied coordinates -
Custom metadata fields: Extra columns in
objects.csvbeyond the standard fields are now passed through to object pages and rendered in the metadata section. Labels check language keys first, then fall back to the column name with underscores replaced by spaces -
Trama theme: New default theme featuring Telar's new visual identity, by Adelaida Ávila. Terracotta links and buttons, lavender layer backgrounds, Space Grotesk headings, Roboto Condensed body text. The Paisajes theme remains available and existing sites keep their configured theme
-
Content folder restructure:
components/renamed totelar-content/, withimages/renamed toobjects/(now holds images and PDFs) andstructures/renamed tospreadsheets/. Thetelar-prefix makes the user content directory clearly identifiable. Migration script handles the rename automatically -
Single Google Sheets URL: Simplified from requiring both a shared URL and a published URL to using only the published URL. Users no longer need to "Share with link" -- only "Publish to web". If
shared_urlis still present in_config.yml, it is silently ignored
Onboarding and demo content release with documentation restructure, template simplification, and Spanish-language spreadsheet support.
-
Spanish-language spreadsheet support: Google Sheets tabs named
glosarioare now recognized and routed correctly alongsideglossary. Theinstruccionestab is also properly skipped during fetch -
Updated demo content: Demo bundles now include v0.8.0 metadata fields (year, object_type, subjects, featured, source) so demo objects appear correctly in the gallery filter system
-
Google Sheets template simplified: Reduced from 8 tabs to 6 by removing example story tabs. Users now duplicate
blank_template/plantilla_en_blancoto create new stories -
Demo object merging: The demo content system now handles both v0.6.0 bundles (with
medium,dimensions,location) and v0.8.0+ bundles (withyear,object_type,subjects,featured,source)
Content and access release adding story protection, an enhanced gallery system, and glossary CSV support.
-
Protected stories: Stories can now be encrypted with a site-wide key. Add
protected=yesto a story's row inproject.csvand setstory_keyin_config.yml. Protected stories are encrypted at build time using AES-256-GCM and decrypted in the browser when viewers enter the key. An unlock overlay with session persistence means the key only needs to be entered once per browser session. Share links can optionally include the key for convenient access -
Browse and search for objects: The objects page now includes a filter sidebar, full-text search (powered by Lunr.js), and sort controls. Filters use OR within a category and AND across categories. Desktop shows a 250px sidebar on the right; mobile shows a collapsible "Filter by" pill. Disable with
browse_and_search: falsein_config.yml -
Featured objects on homepage: Optionally display a sample of objects on the homepage with smaller 170px cards. Configure with
show_sample_on_homepage: trueandfeatured_countin_config.yml. Objects can be explicitly marked with afeaturedcolumn inobjects.csv, or selected randomly at build time -
Glossary CSV support: Define glossary terms in
components/structures/glossary.csvas an alternative to individual markdown files. Supports inline definitions and file references. Existing markdown glossaries continue to work unchanged -
Share panel redesign: The share panel now uses pill-style tabs ("this story" / "this whole site") with inline copy buttons. For protected stories, a privacy toggle lets you choose whether to include the key in shared links and embed codes, with clear warnings about access implications
-
Config setting renames:
hide_storiesrenamed toskip_storiesandhide_collectionsrenamed toskip_collectionsunderdevelopment-features. Old names still work for backward compatibility -
New config section:
collection_interfacesettings control the objects gallery (browse and search, homepage link, featured objects) -
Object metadata fields: Objects CSV now supports
year,object_type,subjects, andfeaturedcolumns for richer filtering. Thelocationfield has been renamed tosource(old name still supported)
Migration from v0.7.0-beta:
- Run
python3 scripts/upgrade.pyto upgrade automatically - Manual step required: Copy updated
.github/workflows/build.ymlfrom the Telar repository (adds search data generation step) - For local development: Install
cryptographypackage:pip install -r requirements.txt
Infrastructure and code quality release focusing on maintainability, testing, and accessibility.
-
Test infrastructure: Comprehensive automated testing with 305 tests across three frameworks. Python unit tests (235 tests) cover CSV processing, widget parsing, IIIF metadata extraction, and more. JavaScript unit tests (35 tests) verify viewer, navigation, and panel logic. End-to-end tests (35 tests) use Playwright to test story navigation, embed mode, and panel interactions in a real browser
-
Consolidated CI workflow: Single
telar-tests.ymlworkflow runs both Python and JavaScript tests on push/PR. Supports selective test runs via workflow dispatch for faster iteration -
Dependabot: Automatic security updates for GitHub Actions dependencies
-
Modular Python scripts: The 2,750-line
csv_to_json.pyis now a 14-moduletelar/package with clear separation of concerns. Each module has a focused purpose:csv_utils.pyfor CSV handling,widgets.pyfor widget parsing,iiif_metadata.pyfor IIIF extraction, etc. The original script remains as a backward-compatible wrapper -
Modular JavaScript: The 1,872-line
story.jsis now 6 ES modules bundled by esbuild.state.jscentralises all mutable state,navigation.jshandles all navigation modes,viewer.jsmanages IIIF viewer lifecycle, etc. Consolidated 135 lines of duplicated code into shared utilities -
SCSS partials: The 3,374-line
telar.scssis now 9 focused partials in_sass/. Reusable mixins for tab colours and viewer hiding reduce duplication. Each partial has a narrative description explaining its purpose -
Node.js required: esbuild is now used to bundle JavaScript. Run
npm installbefore building locally. Thebuild_local_site.pyscript handles this automatically
-
Accessibility (WCAG AA): Fixed colour contrast on intro hints, added navigation landmark for home button, changed story container to semantic
<main>element. Verified with axe-core accessibility audit -
Navigation z-index: Fixed intro step covering navigation buttons when scrolling back from later steps
-
Pandas 3.0 compatibility: Fixed emoji sanitisation failing on pandas 3.0 due to StringDtype change
Migration from v0.6.3-beta:
- Run
python3 scripts/upgrade.pyto upgrade automatically - Manual step required: Copy updated GitHub Actions workflows from the Telar repository (build.yml, upgrade.yml, telar-tests.yml)
- For local development: Run
npm installto install esbuild for JavaScript bundling
- Inline panel content: Write panel text directly in your spreadsheet instead of creating separate markdown files. Supports three methods: (1) entering text directly in cells, (2) pasting markdown text with optional YAML frontmatter, or (3) referencing external markdown files for complex content. The
layer1_filecolumn has been renamed tolayer1_content(old name still works for backward compatibility)
- Column naming:
layer1_file,layer2_file,layer3_filerenamed tolayer1_content,layer2_content,layer3_contentto reflect their expanded purpose. Spanish equivalents:contenido_capa1,contenido_capa2,contenido_capa3. Old column names remain supported for backward compatibility
- Empty state messages: Error messages now reference user-editable locations (spreadsheet,
components/directory) instead of internal Jekyll directories
Migration from v0.6.2-beta:
- Run
python3 scripts/upgrade.pyto upgrade automatically - No breaking changes — existing spreadsheets and markdown files work without modification
-
Improved viewer preloading: Complete overhaul of how Telar loads IIIF viewers eliminates black screens and speeds up navigation. All IIIF manifests are fetched in parallel when the story page loads, so images are ready before you scroll to them. Hovering over a story card on the homepage begins loading its manifests. A subtle shimmer animation shows when a viewer is initializing. Preloading behavior can be tuned via
development-features.viewer_preloadingin_config.yml -
Glossary-to-glossary linking: You can now use
[[term]]syntax inside glossary definitions to link to other glossary terms -
All-in-one build script for local sites: New
build_local_site.pyruns the complete local build process with a single command. Use--skip-iiiffor faster rebuilds when images haven't changed,--skip-fetchto skip demo content fetching. Serves on port 4001 by default -
Development feature flags: New
development-featuressection in_config.ymlwithhide_stories(temporarily hide stories) andhide_collections(hide both objects and stories) for rapid testing
-
Case-insensitive object references: Object IDs in your story spreadsheet now match regardless of capitalization (e.g.,
LEVIATHANfindsleviathan) -
Case-insensitive file paths: Markdown file paths work regardless of case, preventing broken links when deploying from Mac to GitHub Pages
-
Index page image overflow: Large images on the homepage no longer overflow their containers
-
Panel title spacing: Improved spacing below panel titles for better readability
-
Panel title markup: Panel titles now use proper
<h1>elements for accessibility
- Sample glossary entries: Removed placeholder glossary entries (colonial-period, reduccion, resguardo, viceroyalty, iiif-manifest, markdown) that were not used by the template stories
Migration from v0.6.1-beta:
- Run
python3 scripts/upgrade.pyto upgrade automatically - No breaking changes
- Bilingual README: Framework README now includes both English and Spanish versions in a single file. Streamlined content removes duplication and directs users to comprehensive documentation at telar.org
- EXIF orientation in thumbnails: Fixed thumbnails displaying sideways/upside-down for smartphone photos with EXIF rotation metadata. The IIIF tile generator now correctly detects and applies all EXIF orientations (90°, 180°, 270°). Regenerate IIIF tiles to see correctly oriented thumbnails:
python3 scripts/generate_iiif.py - Migration script template pollution: Fixed v0.5.0→v0.6.0 migration adding unwanted template files to existing sites. The migration now only adds templates (
your-story/,tu-historia/, demo glossary) to new sites without custom content
- Demo content fetching: New
include_demo_contentconfiguration option in_config.ymlallows sites to optionally fetch versioned, multilingual demo content from content.telar.org - Automatic demo integration: Demo stories and glossary entries are automatically merged with your content during the build process
- Smart cleanup: Template now ships without bundled demo content - fetch only when needed
- Bilingual demos: Demo content adapts to your site language (English or Spanish)
- Version matching: Fetches highest compatible demo version for your site
- User-editable pages: Create custom pages in
components/texts/pages/directory (about, contact, etc.) - Configurable navigation menu: Edit menu items via
_data/navigation.ymlwith bilingual support - Full Telar features: Widgets and glossary links work on custom pages
- Responsive layout: New
user-page.htmllayout provides centered, mobile-friendly content
- New home: telar.org: Unified website with landing page, documentation, and demo content hosting
- Comprehensive documentation: Complete documentation site at telar.org/docs (English) and telar.org/guia (Spanish)
- Version callouts: Documentation clearly indicates which features require v0.6.0+
- Improved structure: Documentation reorganized with dedicated developer section (Section 8)
- Backwards-compatible redirects: Old ampl.clair.ucsb.edu/telar-docs URLs redirect to telar.org/docs
- Semantic story names: Optional
story_idcolumn inproject.csvenables custom story identifiers like "your-story" or "colonial-maps" - Better organization: Story filenames and tab names match your chosen identifiers exactly
- Fully backward compatible: Falls back to numbered stories (
story-1,story-2) whenstory_idnot provided - Automatic discovery: Scripts process all story CSVs automatically
- Spanish column headers: Use Spanish headers in your CSVs (
paso,objeto,pregunta,respuesta, etc.) - Dual header rows: Support for bilingual header rows with automatic detection
- Spanish filenames: Support for Spanish CSV filenames (
proyecto.csv,objetos.csv) with fallback to English - Spanish Google Sheets tabs: Automatically detects Spanish tab names in Google Sheets
- Fully backward compatible: English-only CSVs work exactly as before
- Visible attribution: New dismissable badge displays object credits in bottom-left corner of viewer
- Configurable: Enable/disable via
show_object_creditsin_config.yml - Bilingual: Supports English "Credit:" and Spanish "Crédito:" prefixes
- Respectful design: Matches step number badge styling with subtle transparency
- Fixed: Scrolling within panels no longer triggers story navigation - panels now have proper scroll isolation
- Fixed: Viewer column scroll interference - Universal Viewer zoom/pan now works without triggering step changes
- Improved keyboard navigation: ↑/↓ for steps, ←/→ for panels, Escape to close
- Click outside to close: Panels close when clicking on darkened backdrop
- Better visual feedback: Subtle dark backdrop extends beyond viewport during panel focus
- Based on initial implementation by Sanjana Bhupathi
- Fixed: Demo objects now appear after user objects - prevents demo content from cluttering the top of the objects index page
- Fixed: Quoted comment lines now properly filtered - handles Google Sheets CSV export format where cells containing commas are quoted
- Gitignore improvements: Generated files (
_data/*.json,_jekyll-files/) now ignored by git - Single source of truth: Only source files (CSVs, markdown) tracked in version control
- Cleaner git history: Build-generated content no longer pollutes commit history
- Migration handles cleanup: Upgrade script removes generated files from git index automatically
- Better sizing: Logo limited to max-height 80px with responsive styling
- Cleaner homepage: Logo removed from index page (header only)
- Documentation: Updated config comment with recommended dimensions (300x120px)
- Rich text in bylines: Project bylines now support markdown formatting (links, emphasis, etc.)
- Enabled via markdownify filter in story.html layout
- Rounded corners: Tab buttons have rounded top corners (0.5rem)
- Transparent background: Only tab buttons visible, cleaner appearance
- Visual hierarchy: Inactive tabs dimmed (opacity 0.7), active tabs full opacity
- Color consistency: Matches accordion pattern with appropriate layer colors
- Language data expansion: New language strings for credits, updated navigation
- Improved fallbacks: Bilingual navigation with graceful degradation
Migration from v0.5.0-beta:
- Fully automated via
python3 scripts/upgrade.py - Zero manual steps for GitHub Pages users (automatic rebuild)
- Local developers: Regenerate data files and test build
- Demo content cleanup uses CSV-smart detection to preserve user-modified content
- Complete iframe embedding system for educational and blog platforms (Canvas, Moodle, Blackboard, WordPress, Squarespace, Wix)
- Embed mode detection via
?embed=trueURL parameter with automatic UI adjustments - Forced navigation buttons on all viewports including desktop with custom positioning and responsive typography
- "View full site" dismissible banner with multilingual support and frosted glass effect
- Successfully tested in production Canvas LMS with cross-browser and mobile testing complete
- Comprehensive documentation with educator guide and troubleshooting section
- Share button component with OS-specific icons and three variants (story page, navbar, icon-only)
- Share panel modal with two tabs: Share Links (clean URLs) and Embed Code (8 dimension presets)
- Platform presets: Canvas (100% × 800px), Moodle/Blackboard (100% × 700px), WordPress (100% × 600px), Squarespace (100% × 600px), Wix (100% × 550px), Mobile (375px × 500px), Fixed (800 × 600), Custom
- Copy to clipboard with visual feedback for both share URLs and embed codes
- Full multilingual support (English + Spanish) with platform documentation links
- Native support for HEIC (iPhone photos), WebP, and TIFF formats
- Case-insensitive extension matching (
.JPG,.png,.HEICall work) - Automatic JPEG conversion during IIIF tile generation with original file preservation
- Handles transparency (RGBA, LA modes) and palette modes with proper conversion
- Eliminates false warnings for uppercase file extensions
- Build-time dimension analysis using PIL/Pillow with zero runtime cost
- Four size classes: Compact (400px), Default (550px), Tall (700px), Portrait (850px)
- Automatic assignment based on maximum aspect ratio in carousel
- Eliminates manual configuration for carousel heights
- Extended fluid typography from story steps to all panel contents using CSS
clamp() - Max-width constraints for panel images on narrow screens
- Improved readability across all device sizes
- Scrollable story steps prevent navigation button cutoff (changed
overflow: hiddentooverflow-y: auto) - Panel image width constraints force
max-width: 100%on mobile (≤768px) while preserving desktop sizing
- Captions moved below images for better accessibility
- Black container background for better image contrast
- Reduced typography (0.9rem text, 0.8rem credit) with indicators positioned above captions
- Disabled keyboard navigation to prevent story navigation interference
- Placeholder directories with READMEs:
components/pdfs/(v0.6.0),components/audio/(v0.7.0),components/3d-models/(v0.8.0) - Prevents incompatible implementations before official support
- All scripts, styles, and workflows now include version headers for better tracking
- Format:
Version: v0.5.0-beta(Python/YAML) or@version v0.5.0-beta(JS/CSS)
- Removed subdirectories:
components/images/objects/andcomponents/images/additional/→components/images/ - Updated default paths in csv_to_json.py, generate_iiif.py, and validation
- Automated migration via upgrade script
- Changed from directory-based to CSV-driven: Only processes objects in
objects.csvwithout external manifests - Automatic file detection by
object_idsupporting multiple extensions (case-insensitive) - Faster generation with no orphaned tiles
- Renamed
iiif_manifest→source_urlfor future media type compatibility (PDFs, videos, 3D, audio) - Full backward compatibility: Both column names work, automatic aliasing in both directions
- Updated templates with Liquid fallback pattern
- Smart change detection only triggers IIIF when changed images match object IDs in objects.csv
- Cache optimization for more efficient CI/CD pipeline
- Deleted scrollama.min.js and openseadragon.min.js (~47KB savings) - Telar uses custom scroll system and UniversalViewer's bundled OpenSeadragon
- Deleted docs/google_sheets_integration/ folder - fully documented in official docs site
- Restored 1,382 lines accidentally deleted from
csv_to_json.pyin commit f62acee (Nov 8, 2025) - Root cause: Commit overwrote file, removing core v0.4.0 functionality
- Features restored:
- Widget processing (~350 lines): accordion, carousel, tabs with Bootstrap HTML generation
- IIIF metadata auto-population (~400 lines): extracts title, creator, period, location, credit
- Glossary auto-linking (~150 lines):
[[term_id]]syntax processing - Multilingual support (~100 lines): language string loading and interpolation
- Applied v0.5.0 updates to restored code (version header, flattened image paths)
- Restored frontend components for widgets and glossary (~115 lines total)
- Widget panel-specific styling: Layer 1 widgets use Layer 2 colors and vice versa
- Enhanced glossary functionality: Proper title extraction, both inline and index links work
- Widget initialization: Added widgets.js script tag
- Glossary multilingual support: Language-aware panel labels and "Key term:" prefix
- Fixed h2, h3, h4 color inheritance in layer 2 panels (white on dark purple background)
- Improved error message formatting for missing glossary terms with quoted, bold term IDs
- Added file path context showing exactly which markdown file contains the broken reference
- Natural sentence structure replaces technical phrasing for better readability
- Example: "In the file stories/story2/step4-layer2.md, you reference the glossary term 'term', but this term does not exist in components/texts/glossary/"
- Files modified:
scripts/csv_to_json.py,_data/languages/en.yml,_data/languages/es.yml
- Automated v0.4.x → v0.5.0 migration:
- File relocation: old subdirectories →
components/images/ - CSV column update:
iiif_manifest→source_url - Name conflict detection and empty directory cleanup
- File relocation: old subdirectories →
- Full backward compatibility: No breaking changes for existing sites
- Complete framework comments restored: Migration now restores all missing comments in _config.yml
- Top header comments: Framework title and GitHub URL now restored at file beginning
- Complete testing-features section: Entire section created if missing (not just comments)
- Impact: Sites upgrading from v0.3.4 through multiple versions now have complete config structure
- Files modified:
scripts/migrations/v040_to_v041.py
- Touch navigation support: iPad and touch devices can now navigate stories using swipe gestures
- Desktop viewport mode: Fixes issue where touch scrolling didn't trigger story step changes
- Swipe to navigate: Swipe up for next step, swipe down for previous step
- Respects cooldowns: Same 600ms cooldown as mouse/trackpad scrolling
- Files modified:
assets/js/story.js(added touch event handlers)
- Automatic regeneration: IIIF tiles now regenerate when _config.yml changes
- Prevents broken images: Fixes issue where baseurl changes caused image serving failures
- Smart detection: Added _config.yml to change detection pattern in build workflow
- Thanks to Tara for reporting this issue
- Files modified:
.github/workflows/build.yml(updated change detection pattern)
- Portrait photos now display correctly: Images from phones/cameras no longer appear rotated 90 degrees
- EXIF metadata respected: Script now applies EXIF orientation data before generating IIIF tiles
- User experience: Students can upload phone photos directly without manual rotation
- Visual feedback: Console displays "↻ Applied EXIF orientation correction" when rotation is applied
- Thanks to Tara for helping spot this issue
- Files modified:
scripts/generate_iiif.py(bothgenerate_iiif_for_image()andcopy_base_image())
- Automatic optimization: Build workflow now intelligently detects when IIIF tile regeneration is needed
- Git diff-based detection: Compares changed files between commits to determine if images or objects.csv changed
- Manual override: Workflow dispatch includes "Force IIIF tile regeneration" checkbox (default: checked for safety)
- Multiple failsafes: Defaults to full build on first commit, detection errors, or uncertain cases
- GitHub Actions caching: IIIF tiles cached between builds to prevent deletion when skipping regeneration
- Cache key strategy: Automatically invalidates cache when image files change using hash-based keys
- Time savings: Faster deployments for content-only changes (stories, text, metadata)
- User experience: Silent optimization for automatic builds, explicit control for manual triggers
How it works:
- Automatic builds (push to main): Detects file changes, skips IIIF if only content changed
- Manual builds: User checkbox to skip IIIF regeneration (safe default always regenerates)
- Cache system: Tiles saved after generation, restored when skipping, automatically invalidated on image changes
Technical details:
- Detection step runs before IIIF generation
- Checks
git diff --name-only HEAD~1 HEADfor changed files - Triggers IIIF when: images in
components/images/objects/orobjects.csvchanged - Skips IIIF when: Only content files changed (stories, glossary, configs, layouts, etc.)
- Cache operations: restore → generate (if needed) → save → restore to _site (if skipped)
- Root cause identified: GitHub Actions workflows are ephemeral - each run starts fresh with no IIIF tiles
- Problem: Skipping IIIF generation left
_site/iiif/objects/empty, deployment replaced entire site, deleting live tiles - Solution: GitHub Actions cache system preserves tiles between workflow runs
- Cache strategy:
- Restore cache after Jekyll build
- Generate and cache tiles (if needed)
- Restore cached tiles to
_site/when skipping regeneration - Cache key based on image directory hash for automatic invalidation
- Safety features: Warns if cache unavailable, logs all cache operations, fails gracefully
- Testing: Confirmed working on demo site (ampl.clair.ucsb.edu/telar)
- Impact: Critical fix prevents tile deletion, enables safe optimization
- Long site titles now wrap naturally on mobile devices instead of overflowing or being cut off
- Hamburger menu right-aligned for better mobile UX
- Flexbox properties adjusted for proper text flow on small screens
- Added
white-space: normalto allow proper text wrapping - Reduced display-4 font size on mobile for better readability
- Works in conjunction with existing height-based responsive design
- CSS rules added to enable proper text wrapping for site titles
- Ensures titles display cleanly across all mobile screen sizes
- Tested with various title lengths on different devices
- Fixed link styling on home page for consistent appearance
- Proper theme color application to site description links
- Build workflow now includes smart IIIF detection and caching (4 new steps, ~76 lines added)
- Migration framework updated with
README.mdandindex.htmlfor complete v0.4.1 upgrades
- Migration script bug fixed: v0.3.4→v0.4.0 migration was deleting ALL comments from
_config.yml - GitHub Actions workflow bug fixed: Workflow was using
yaml.dump()which stripped all comments after migration - Comment restoration added: v0.4.0→v0.4.1 migration now detects and restores 13 types of missing comments
- Comments restored: Site Settings, Story Interface, PLEASE DO NOT EDIT warning, Collections, Build Settings, Defaults, Telar Settings, Plugins, WEBrick, Development & Testing, Christmas Tree Mode, and all setup instructions
- Root cause:
_ensure_google_sheets_comments()in v034_to_v040.py used destructivewhile loop + pop()pattern - Secondary cause: Workflow step "Update version in _config.yml" used
yaml.safe_load()+yaml.dump()after migrations - Impact: Users upgrading from v0.3.4 to v0.4.0 lost all documentation in their config files
- Note for users: After upgrading to v0.4.1, you need to update your
.github/workflows/upgrade.ymlfile ONCE (see upgrade instructions)
- Complete mobile code recovery: Restored ~1,300 lines of mobile responsive code accidentally lost in v0.4.0 release
- Height-based responsive design: 4-tier progressive system for small screens (Tiers 1-3: 700px, 667px, 600px height breakpoints)
- Mobile panel UI: Fixed-size panels with stacking visibility and proper viewport positioning
- Graceful panel transitions: Navigation cooldown, skeleton shimmer loading, fade-only transitions on mobile
- Mobile preloading: Aggressive ±2 step preloading on mobile, enhanced 3/2 forward/backward on desktop
- Offcanvas adjustments: Progressive typography and spacing reductions for small screens
- Site-wide scaling: Consistent mobile experience across all pages
- Root cause: Upstream merge in commit f62acee overwrote local mobile development
- Impact: Major regression fix - restores complete mobile UX from v0.4.0
- Responsive breakpoints: Single column layout up to 441px width, two columns from 442px-768px
- Explicit column control: Replaced auto-fill grid behavior with explicit column counts for predictable mobile layout
- iPhone Pro Max optimization: 440px width devices display single column for optimal readability
- Removed conflicting rules: Fixed 576px media query that was overriding mobile breakpoints
- Sheets copy button: New button in coordinate picker that copies tab-separated values (x\ty\tzoom) for direct pasting into Google Sheets
- CSV copy button: Renamed existing button to "x, y, zoom (CSV)" for clarity
- Button order: Sheets button first (primary workflow), CSV button second
- Multilingual support: Button labels and "Copied!" feedback respect
telar_languagesetting - Both buttons provide visual feedback ("Copied!" / "¡Copiado!")
- Coordinate picker now has two copy buttons instead of one, with clear labels indicating format
- Coordinate picker buttons are now fully multilingual (English/Spanish)
- Complete interface internationalization for English and Spanish
- Language files:
_data/lang/en.ymland_data/lang/es.ymlwith 300+ UI strings - Language-aware templates: All layouts and includes updated with multilingual string lookups
- Configuration:
telar_languagesetting in_config.yml(supportsenandes) - Automatic language detection and fallback logic
- All navigation, buttons, labels, error messages, and instructions translated
- Warning messages and IIIF error explanations (~40 detailed error messages) fully multilingual
- Language files:
- Three widget types for rich content presentation in story panels:
- Carousel widget: Image carousel with navigation controls, captions, and credit attribution
- Tabs widget: Tabbed content panels for organizing multi-perspective information (2-4 tabs)
- Accordion widget: Collapsible content sections for hierarchical information (2-6 panels)
- CommonMark-style syntax:
:::widget_type ... :::for clear block boundaries - Python widget parser: Build-time processing with Jinja2 templates (~350 lines)
- Bootstrap 5 integration: Responsive widgets that match site theme
- External URL support: Images can be referenced from http:// and https:// URLs
- Build-time validation: Comprehensive error checking with accessibility warnings
- Opposite panel colors: Widgets use contrasting colors for visual hierarchy (Layer 1 widgets use Layer 2 colors and vice versa)
- Wiki-style inline syntax:
[[term_id]]for automatic term references in narrative text - Custom display text:
[[term_id|display text]]for flexible grammar - Automatic link generation: Links open glossary slide-over panels
- Build-time validation: Warns about broken term references
- CSS styling: Theme-colored links with visual distinction
- Full multilingual support: Works seamlessly in both English and Spanish
- Automatic extraction of object metadata from IIIF manifests
- Supports both API versions: IIIF Presentation API v2.0 and v3.0
- Six auto-populated fields: title, description, creator, period, location, credit
- Language-aware extraction: Uses site's
telar_languagesetting with fallback to English - Smart credit detection: Filters legal boilerplate, prefers actual attribution
- Fallback hierarchy: CSV values → IIIF manifest → empty (user control maintained)
- HTML stripping: Ensures YAML safety
- Refined field matching: Prioritizes specific field names to avoid false matches
- 9 extraction helper functions: ~400 lines of comprehensive IIIF metadata handling
- Mobile story navigation: Graceful panel transitions with skeleton shimmer loading indicator
- 400ms navigation cooldown to prevent rapid clicking
- Subtle animated gradient during viewer initialization
- Faster transitions (fade only, no slide animations)
- Aggressive preloading (±2 steps on mobile)
- Height-based responsive design: 4-tier progressive system for small screens
- Tier 1 (≤700px): 10-15% typography reduction
- Tier 2 (≤667px - iPhone SE): 20-25% reduction, 55vh:45vh viewer:panel ratio
- Tier 3 (≤600px): 30-35% reduction for very small Android devices
- Dual-axis media queries prevent triggering on short desktop windows
- Site-wide mobile optimizations:
- Offcanvas panels: Reduced padding, font sizes, and spacing
- Object gallery: Single column layout on mobile (≤767px)
- Glossary index: Optimized spacing (33-50% reduction in margins)
- Collection grid: Reduced gaps and image heights
- Navbar brand: Smaller font size on small screens
- Mobile panel refinements:
- Glossary panel: 6vw left offset, 8vh top position, 76vh height, 94vw width
- Navigation buttons: Reduced to 45px on small screens
- Enhanced touch interactions and viewport handling
- Configurable step indicators: New
story_interfacesection in_config.ymlshow_story_steps: Toggle "Step X" overlay visibility (CSS-based)include_demo_content: Preparation for v0.5.0 demo content feature
- Theme creator attribution: Optional
creatorandcreator_urlfields in theme YAML files- Displayed in site footer when present
- Recognizes theme contributions while maintaining clean footer design
- All 5 preset themes updated with attribution
- Google Fonts documentation: Inline comments in theme files explaining how to use custom fonts
- Direct link to Google Fonts
- Format examples and syntax guidance
- Fallback font requirements
- Optional author/creator attribution for stories
- New
bylinecolumn inproject.csv - Displays on homepage story cards (beneath title, smaller font, muted color)
- Displays on story intro slide (as h3 between subtitle and description)
- Fully optional and responsive
- New
- Christmas Tree Mode: Comprehensive testing tool for multilingual warnings (displays all warnings at once, lighting site up like a Christmas tree)
--christmas-treeflag incsv_to_json.pyor config-based in_config.yml- Injects test objects with various intentional error conditions
- All test objects marked with 🎄 emoji for easy identification
- Triggers all warning message types for verification
- Automated cleanup system removes test files when disabled
- Enhanced preloading: Desktop preloads 3 steps ahead and 2 behind (vs 2/1 previously) for smoother navigation
- Footer enhancements: Multilingual footer with theme attribution support, language-aware copyright and navigation strings
- Story back button: Desktop shows text only (icon hidden), mobile shows icon only (text hidden) for cleaner design
- Carousel captions: Moved below images instead of overlaid for better readability
- Carousel image display: Centered with equal widths using flexbox
- Widget visual contrast: Widgets use opposite panel colors (Layer 1 widgets use Layer 2 colors, Layer 2 widgets use Layer 1 colors)
- Numeric object_id YAML parsing: Added quotes around object_id values to prevent YAML parsers from treating numeric filenames as integers. Gracias, Adelaida!
- Google Sheets quotation marks: Created
escape_yaml()helper function to handle quotation marks in all user-editable fields (dimensions, titles, etc.). Thanks, Jeff!
- IIIF manifest 429 rate-limit false positives: Skip 429 errors for unchanged manifests between builds
- IIIF mismatch localhost/127.0.0.1: Normalize both URLs to prevent false positive warnings
- IIIF manifest validation with redirects: Changed from HEAD to GET request to properly follow 301/302 redirects
- IIIF field matching precision: Improved metadata extraction to avoid false matches (e.g., "Repository" vs "Location Depicted")
- Panel heading colors: Fixed h1-h6 elements in panel bodies to use correct theme text colors instead of wrong CSS variables
- Hyperlink colors in panels: All links (footnotes and general hyperlinks) now use theme link color via
var(--color-link) - Glossary popup title: Fixed bug where popup displayed link text instead of actual glossary term title; now correctly extracts title from h1 tag
- Carousel display bug: Fixed all slides showing simultaneously by adding explicit display:none/flex rules
- Mobile panel heights: Fixed viewer/narrative split and panel positioning on mobile devices
- Mobile layout issues: Resolved various mobile-specific layout problems with panel stacking and viewport calculations
- Step number localization: Fixed Spanish sites showing "Step X" instead of "Paso X" by using language file lookups in JavaScript
- v034_to_v040 migration script: Automated upgrade from v0.3.4 to v0.4.0
- Adds
story_interfaceconfiguration section with full comments to_config.yml - Ensures Google Sheets integration comments are present for users upgrading from earlier versions
- Creates
_data/lang/directory and fetches English/Spanish language files from GitHub - Updates all framework files (layouts, includes, scripts, styles, JavaScript)
- Adds upgrade notification system (
_layouts/upgrade-summary.html,_includes/upgrade-alert.html) - Fetches framework documentation files (README.md, docs/README.md)
- Non-breaking migration: all new features are additive, existing sites continue to work
- 6 optional manual steps for users to explore new features
- Adds
-
Automated upgrade system: Issue-based automated upgrade workflow to migrate sites from older Telar versions
- GitHub Actions workflow (
.github/workflows/upgrade.yml) for one-click upgrades - Python-based migration framework (
scripts/upgrade.py) with modular version-specific migrations - Automatic version detection from
_config.yml - Incremental migration support (v0.2.0 → v0.3.0 → v0.3.1 → v0.3.2 → v0.3.3 → v0.3.4)
- Automatic upgrade branch and issue creation with categorized summary
- User creates pull request manually from issue link when ready to merge
- Conditional manual steps section (only shown if steps required)
- Verification checklist for post-upgrade testing
- v020_to_v030 migration: Fetches Python scripts from GitHub to ensure sites receive validation logic for IIIF manifests, thumbnails, and object references
- v033_to_v034 migration: Adds missing framework files (
README.md,docs/README.md, layouts, includes, scripts) to ensure all sites receive updated files
- GitHub Actions workflow (
-
Language configuration (WIP): New
telar_languagesetting in_config.ymlfor future internationalization support- Currently supports:
en(English),es(Spanish) - Default value:
en - Migration script automatically adds this field when upgrading from earlier versions
- Note: Internationalization features are work in progress; this configuration prepares sites for future multi-language support
- Currently supports:
- Validation alert styling: Fixed inconsistent styling between IIIF URL warning and upgrade success alert
- Added
font-weight: 400 !importantto.telar-alertCSS class to prevent lighter font weight inheritance from.page-contentwrapper - Ensures all validation warnings (theme, Google Sheets, objects, stories, IIIF URL, upgrade) display with consistent typography regardless of HTML placement
- Added
- GitHub Actions workflow: Removed git push step that conflicted with branch protection rules. The workflow was attempting to commit generated files back to the protected main branch, causing deployment failures. Generated files are build artifacts that don't need to be committed to the repository.
- Image sizing in panel markdown: New syntax
{size}for controlling image sizes in panel content- Supports both short (
sm,md,lg,full) and long (small,medium,large) size names - Default path for relative images:
/components/images/additional/ - Sizes: small (250px), medium (450px, default), large (700px), full-width (100%)
- Absolute paths and URLs work as expected
- Example:
{large}or{sm}
- Supports both short (
- Markdown syntax documentation: Comprehensive reference guide added to documentation site covering all markdown features, image sizing, rich media embeds, code blocks, footnotes, and best practices
- Default panel image size: Increased from 300px to 450px max-width for better visibility
- Scheduled builds removed: Removed daily midnight cron job from build workflow. Builds now only trigger on push to main or manual workflow dispatch.
- Index page refactored for easier customization: Moved
index.htmlto_layouts/index.htmland created editableindex.mdin root directory- Users can now customize welcome message, stories heading, and objects section text in simple markdown
- Demo site notice is now in markdown and easily removable
- Support for
{count}placeholder in objects intro text - Customizable via frontmatter:
stories_heading,stories_intro,objects_heading,objects_intro
- Critical thumbnail loading bug: Fixed thumbnails not displaying on objects page due to empty string handling in Liquid templates. Objects with empty
thumbnailoriiif_manifestvalues now properly fall through to appropriate fallback logic. - Local image viewer bug: Fixed local images (self-hosted IIIF) not loading in object detail pages due to empty
iiif_manifeststring being treated as truthy in Liquid conditionals. - Objects gallery thumbnails: Fixed local image thumbnails not loading in objects gallery by adding non-empty string checks to all
iiif_manifestconditionals.
- Google Sheets integration: Config-based workflow supporting both GitHub Pages and local development. Users paste shared and published URLs into
_config.ymlfor automatic GID discovery and CSV fetching. No GitHub Secrets required.fetch_google_sheets.pyscript for local CSV fetchingdiscover_sheet_gids.pyfor automatic tab GID discovery from published sheets- Excel template with demo data at
docs/google_sheets_integration/telar-template.xlsx - Google Sheets Template available and can easily be duplicated, at https://bit.ly/telar-template
- Local development guide at
docs/google_sheets_integration/README.md - Instruction rows and columns: Add notes and instructions directly in Google Sheets or CSVs that are automatically filtered out during processing
- Rows starting with
#are skipped (useful for section breaks, TODOs, and temporary comments) - Columns with names starting with
#(e.g.,# Instructions,# Notes) are ignored during JSON conversion - Template includes
# Instructionscolumn with examples for user guidance
- Rows starting with
- Comprehensive error messaging system: User-friendly warnings displayed on index, objects, and story pages when configuration issues are detected
- Object ID validation: Automatic stripping of file extensions from object IDs and warnings for spaces in filenames
- IIIF manifest validation: Full validation of external IIIF manifests with detailed error messages
- Thumbnail validation: Automatic detection and clearing of invalid thumbnail values (placeholders, non-image files)
- Build-time warnings: Console logging with structured [INFO] and [WARN] messages during CSV to JSON conversion
- Index page issue summary: Context-aware warnings that link directly to affected objects or stories
- Objects gallery warnings: Summary of all objects with configuration issues with links to details
- Story intro warnings: Display of configuration issues before users scroll, preventing confusion
- Panel error handling: JavaScript-based detection and display of missing images in panel content
- IIIF manifest copy button: Object pages now display the full IIIF manifest URL in a copyable code box with one-click copy functionality
- Individual coordinate copy buttons: Each coordinate (X, Y, Zoom) in the coordinate identification panel now has its own copy button for quick copying of individual values
- Theme system: Flexible theming system with 4 preset themes and support for custom themes
- Preset themes: Paisajes Coloniales (default), Neogranadina, Santa Barbara, and Austin
- Easy theme switching via
_config.ymlwith single-line configuration - Customizable colors (primary, secondary, panel backgrounds) and fonts (headings, body)
- Advanced users can create
_data/themes/custom.ymlfor fully custom themes (gitignored by default) - Dynamic CSS generation using SCSS with Liquid templating
- Orphaned file cleanup: generate_collections.py now properly removes old files before generating new ones, preventing stale content
- Default content management: Google Sheets is now the recommended default workflow, with CSV files as an optional alternative for users who prefer direct file editing
- Error message clarity: All user-facing errors reference "configuration CSV or Google Sheet" for clarity
- Object warning field: Added object_warning to Jekyll collection frontmatter for template access
- Objects CSV column order: Moved iiif_manifest to position 4 (after description) for better visibility and logical grouping
- Story CSV column order: Reordered columns to group related fields - object and coordinates (x, y, zoom) now appear at start after step number, followed by question/answer, then panel configuration
- Story intro layout: Intro slide now appears in the narrative column (left side) instead of full-screen, with step 1's viewer visible immediately on the right for a cleaner, more consistent experience
- Glossary page styling: Glossary term links now use theme link colors and body font for consistent theming
- Glossary navigation: Clicking glossary terms on the glossary index page now opens a slide-over panel instead of navigating to separate pages, providing a smoother browsing experience
- Panels slide away and then back in when switching between terms for smooth transitions
- Glossary panels are narrower than story layer 2 panels (45% vs 55%) for clear visual hierarchy
- Back button added to glossary panel header for easy dismissal, matching story panel design
- Theme fallback system: Multi-tier protection against theme configuration errors
- Three types of error detection: missing theme, malformed YAML, or critical system failure
- Automatic fallback to paisajes (default) theme when configured theme is unavailable
- Protected fallback copy in
scripts/defaults/themes/as ultimate backup - Hardcoded CSS defaults ensure site functions even if all theme files are damaged
- User-friendly warning messages on index page explain issues and suggest fixes
- Deprecated glossary CSV workflow: Glossary feature now sources content exclusively from markdown files in
_glossary/. CSV-based glossary input has been removed. - Non-functional project.csv fields: Removed
primary_color,secondary_color,font_headings, andfont_bodyfromproject.csv(these values were not being used by templates). Theme customization now handled via the new theme system in_data/themes/.
- Scrolling system overhaul: Replaced Scrollama library with custom discrete step-based card stacking architecture to enable multiple IIIF objects within a single story. Each object gets its own preloaded viewer card that slides up/down as users navigate through steps.
- Animation timing: Reduced viewer pan/zoom animation duration from 36 seconds to 4 seconds for more natural pacing
- Cleaner viewer UI: Hidden UniversalViewer color picker and adjustment panels for distraction-free viewing
- Critical navigation bug: Fixed viewer cards getting stuck or invisible after backward→forward navigation cycles
- Z-index layering: Resolved issue where reused viewer cards appeared behind currently visible cards
- State management: Added complete state reset when reusing viewer cards (clears inline styles, transitions, opacity)
- Intro handling: Improved viewer reference management when navigating to/from story intro
- Story 2 showcase: Added comprehensive demo story with rich media examples (images, videos, markdown formatting)
- Enhanced logging: Improved console debugging messages for bounds checking and state transitions
- Fixed IIIF thumbnails loading at low resolution on home and objects pages by extracting 400px canvas images instead of tiny thumbnail properties
- Fixed markdown syntax not rendering in panels by adding markdown-to-HTML conversion in csv_to_json.py script
- Added comprehensive footnote styling for both panel layers with proper contrast and visual hierarchy
- Added markdown module to requirements.txt for GitHub Actions CI/CD compatibility
- Fixed image URLs in slide-over panels not working when site is deployed to subdirectories by automatically detecting and prepending the base URL
- IIIF integration - Local images with auto-generated tiles
- External IIIF - Support for remote IIIF Image API
- Scrollytelling - Coordinate-based navigation with UniversalViewer
- Layered panels - Two content layers (Layer 1 and Layer 2)
- Glossary pages - Standalone term definition pages at
/glossary/{term_id}/ - Object gallery - Browsable grid with detail pages
- Coordinate identification tool - Interactive tool to find x,y,zoom values on object pages
- Components architecture - CSV files + markdown content separation
- CSV to JSON workflow - Python scripts for data processing
- IIIF tile generation - Automated image pyramid creation with iiif-static
- GitHub Actions ready - Automated builds and deployment pipeline
Planned for v0.2:
- Glossary auto-linking - Automatic detection and linking of terms within narrative text
- Google Sheets integration - Edit content via web interface without CSV files
- Visual story editor - Point-and-click coordinate selection
Future versions:
- Annotation support - Clickable markers on IIIF images that open panels with additional information
- Multi-language support - Internationalization and localization
- 3D object support - Integration with 3D viewers
- Timeline visualizations - Temporal navigation for chronological narratives
- Advanced theming options - Customizable design templates
- Content must be edited as CSV files and markdown (no web interface yet)
- Local development requires Python 3.9+ and Ruby 3.0+ setup
- Coordinate identification tool requires running Jekyll locally or on published site
- Story coordinates must be manually entered in CSV files
- Framework: Jekyll 4.3+ static site generator
- IIIF Viewer: UniversalViewer 4.0
- Scrollytelling: Custom discrete step-based card stacking system
- Styling: Bootstrap 5
- Image Processing: Python iiif-static library
This is a beta release for testing. The framework is feature-complete for CSV-based workflows but has not been extensively tested with real-world projects. We welcome feedback and bug reports via GitHub Issues.
See README.md for installation and usage instructions.