Skip to content

Repository files navigation

sarc.systems

Website of the Studio for Advanced Research in Cybernetics (SARC). Static site built with Hugo Extended. Git + Markdown are the CMS.

See CLAUDE.md for the full project conventions — read it before changing anything.

Requirements

  • Hugo Extended v0.164.0 (pinned; the extended build is required for image processing and asset bundling). Check with hugo version — the string must contain +extended.

    brew install hugo          # macOS
    

Commands

make dev        # hugo server with drafts (-D) + future posts, local dev
make build      # production build (minified, correct baseURL) -> public/
make check      # production build + required-output and link checks
make new-post SLUG=my-entry   # new journal bundle from the archetype
make deploy     # check, then push main; GitHub Actions publishes to Pages

Structure

  • content/ — Markdown. Journal entries are leaf page bundles under content/journal/<year>/<slug>/ and carry their own images/audio/diagrams.
  • layouts/ — the custom theme (plain HTML templates, no third-party theme).
  • assets/css/ — plain CSS, concatenated + minified through Hugo.
  • assets/js/ — minimal progressive-enhancement JS (the landing mark).
  • assets/img/ — source visual assets, incl. the SARC four-row mark.
  • static/ — passthrough files (robots.txt, favicon, …).

The SARC four-row mark

The homepage masthead renders the live SVG reconstruction of the four-row mark — layouts/partials/mark.html, generated by scripts/generate-mark.py (make mark) from the Nasalization letterforms in design/fonts/Nasalization-Rg.otf. All sixteen letters (four rows, reflected across the figure's centre in pairs) are independently transformable SVG groups — no passive <use>; assets/js/mark.js turns one random letter 90° at a time on a fixed cadence. It ships no font (glyphs are baked to paths), degrades to a static readable state with no JS, and stays canonical under prefers-reduced-motion.

The original raster (assets/img/rect15_larger.png) is preserved unchanged and used as the social/Open-Graph preview image. See assets/img/README.md.

Homepage quote

Beneath the mark sits one SARC-curated editorial quotation — data/homepage_quotes.yaml, resolved by layouts/partials/homepage-quote.html. This is homepage content, not the Library: quotes never become Library entries and never touch Library front matter, filters, JSON, or random selection. library_ref is an optional pointer into the Library (a resolvable library.id) and is validated at build time (homepage-quotes-validate.html) — an unresolvable reference fails the build. Selection is session-stable (sessionStorage, revalidated against the enabled set on every read) and never becomes URL state. The first enabled quote is the deterministic no-JS/pre-JS fallback; assets/js/homepage-quote.js is inlined (not <script src defer>) specifically so the session pick replaces it before the fallback can visibly flash. See CLAUDE.md § Homepage quote for the full editorial rules and the author/work/full/no-link attribution rule.

Library

The Library (/library/) is one unified catalog of entries — a growing research collection and small knowledge graph, not a set of sections. Every durable thing SARC wants to identify, annotate, connect, or point toward is an entry (essays, books, manuals, people, groups, recordings, releases, websites, systems, …). Type, subject, and access are metadata and filters, never shelves. The landing shows a chance-picked "From the Library" entry, then the View switch and Type/Subject filters (collapsed by default behind a native disclosure), then the full ruled catalog. The controls render below the chance panel but still define its field: the chance pick and the catalog below it are both sampled/filtered from that exact same field (one matching-set computation, not two) regardless of DOM order. A Catalog/Images view switch presents the same filtered entries as a thumbnail-only grid instead of full records — same images, same crop, same order, filters and URL state shared with Catalog. Images is the default view (?view=catalog opts back into the ruled records; an absent or invalid view resolves to Images). A third, experimental Map view (?view=map) draws the same matching entries as a force-directed diagram of explicit editorial relationships only — creators[].ref and related[].ref, nothing inferred from shared subjects — via assets/js/library-map.js; see CLAUDE.md § Library for the full data-flow and what it deliberately doesn't do (no knowledge graph, no similarity/recommendation logic, no clustering). The chance pick is revalidated against the active filters/view on every change (kept if still eligible, redrawn otherwise, restricted to image-bearing entries in Images view) and is sessionStorage-only — it never becomes URL state. Requires JS; Catalog with an unfiltered chance pick is the no-JS fallback. See CLAUDE.md § Library for the full behavior (shared thumbnail partial, accessibility, chance-selection eligibility/revalidation). Section colour is Forest.

Add an entry (one archetype for everything):

hugo new --kind library-entry library/research/person/some-slug/index.md

Entries are stored under their Collection, then a public-type directory — content/library/<collection>/<public-type>/<slug>/ (research is the only Collection today; public types: person | group | organization | work | system | place | concept | event) — but always publish flat within their Collection at /library/<collection>/<slug>/ (e.g. /library/research/some-slug/); neither the Collection nor the type folder appears past that in the URL. See docs/library-v2.md for the Library v2 architecture this reflects. Edit the front matter and set draft: false. Key fields:

  • library.id — stable, unique id (not the title/URL); relationships resolve through it. library.type — one controlled type (book | person | group | organization | manual | album | essay | website | system | …; person for an individual, group for a band/ensemble, organization for an institution). library.sarc_worktrue if SARC made it (a filter axis, not a shelf). All validated against data/library.yaml.
  • subjects — controlled terms (why it matters to SARC); power the filter.
  • creators{name, role, ref?}. A ref (another entry's library.id) links the name and auto-adds a Works in the Library list on that entry. related are {ref, relation} editorial links.
  • images — ordered; the first is the primary (list thumbnail + entry featured image). Live in the page bundle; alt required. Optional per-image caption / credit / source / role / anchor / rights (anchor: Top crops the thumbnail from the top when a centred crop cuts through a head). No hotlinking. credit and source are different claims: source is the exact page the image was obtained from/verified against (never a bare homepage or a platform name like "Bandcamp"/"Wikipedia"); credit is who actually made or supplies it (a photographer, archive, or "SARC") — leave it absent rather than naming the site you found the image on. Per-image rights.status (sarc-owned | public-domain | licensed | permitted | unknown — distinct from the hosted-file rights.status below) records the image's copyright condition; a separate use.basis (identification | editorial | promotional | fair-use | archival) plus use.note records why SARC is using it when rights aren't sarc-owned/public-domain/licensed/ permitted — kept apart so the schema never implies more legal certainty than it has. See CLAUDE.md § Library for full examples and make library-image-audit for an offline report on every image's metadata.
  • access{label, kind, url|file} (many per entry). hosted-file needs a bundle file; external kinds open in a new tab. url/file are exclusive.
  • rights.status (only for a hosted file) — sarc-owned | public-domain | licensed | permitted | archival | review. A hosted file with review/unset rights fails the build — keep it a draft. archival = good-faith hosting of a long-discontinued product's docs, taken down on request (not a public-domain claim). Don't fabricate rights.

Cross-site inclusion. A page elsewhere (e.g. a Systems manual) joins the catalog with library: { include: true, id: … } — no copying, canonical URL stays put. Moving a URL: add the old path under aliases:.

The research catalog is also emitted as /library/research/index.json (/library/index.json is the Library root — currently a placeholder until Phase 3 of the Library v2 migration lands, see docs/library-v2.md). See data/library.yaml for the vocabularies and CLAUDE.md § Library for full conventions (graph, images, random, filtering, rights, the private iCloud policy, why no database).

Deploy

Hosted on GitHub Pages. Pushing to main triggers .github/workflows/deploy.yml, which builds the site with the pinned Hugo version and publishes it. make deploy runs make check first, then pushes main (build/publish happens on the runner, not locally).

The custom domain (sarc.systems) is pinned by static/CNAME, and GitHub issues/renews the HTTPS certificate. DNS + email live on Fastmail: the apex A records point at GitHub Pages while MX/DKIM/SPF stay on Fastmail — never touch the mail records when editing DNS. Deploy from main only; public/ is gitignored and never hand-edited.

About

Website of the Studio for Advanced Research in Cybernetics (SARC)

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages