About this website

27 min read

Source of the website of the Canepa Research Lab, caneparesearch.org. The site is built with Jekyll and published through GitHub Pages from a separate and private repository. A HISTORY.md file in the source repository records the site’s milestones and the Cloudflare changes that git does not.

Build the site locally

The repository is private: ask Prof. Canepa for access, then clone it and install the dependencies (Ruby 3 and Bundler; the Jekyll version is pinned in the Gemfile):

git clone [email protected]:caneparesearch/source-care-website.git
cd source-care-website
bundle install

Build the site into _site/ with bundle exec jekyll build, or preview it with bundle exec jekyll serve and open http://127.0.0.1:4000/.

A local preview runs in Jekyll’s “development” environment, which leaves out the upgrade-insecure-requests Content-Security-Policy directive that the live site sends (update.sh builds with JEKYLL_ENV=production). This is expected: sent locally, it would make the browser retry every link over HTTPS against a plain-HTTP server.

Publish

publish.sh commits, pushes and publishes in one step:

./publish.sh "short description of the change" [new-file ...]

It commits the changes to tracked files (brand-new files only if you name them, never .jekyll-cache/), pushes, then runs update.sh with the same message. Add -n for a dry run or -y to skip the confirmation. It runs only on main, and stops before committing if the remote has commits you do not have. The live site is always built from a private snapshot (a temporary git worktree) of main, never from this folder’s files, so a checkout of another branch cannot end up on the live site (that happened once, on 8 October 2026, for about a minute).

update.sh publishes without committing anything. It needs caneparesearch.github.io checked out next to this repository, the aws CLI with access to the carepapers bucket, and jq:

./update.sh "short description of the change"

In turn it:

So a page or image deleted or renamed here disappears from the live site on the next publish (a renamed page keeps working through redirect_from:, see below). It refuses to deploy from a missing or nearly empty _site/, so a failed build cannot wipe the site. After publishing, check that caneparesearch.github.io has a new commit; if it does not, run ./update.sh on its own.

Content

Every page is a Markdown file with a short YAML header. The date at the start of a post’s file name is its post date. Pictures go in images/, in a folder named after the section.

Section Location Header fields
News news/_posts/YYYY-MM-DD-short-topic.md layout: post, category: news, title, author (first name of a team member), optional image and image_fit: contain
Team team/_posts/<date>-<name>.md layout: member, title, position, image, alumni: true for former members, and optional email, profile, profile_label, website, linkedin, github, scholar, orcid, twitter, cv, calendar, aliases, papers, alumni_group (see Team below)
Research research/_posts/ layout: post, title, image, order, references, and optional description, image_fit, image_position, image_transparent, splash, short_title, listed and sitemap (see Research pages below)
Papers papers/_posts/<date>-<first-author>-<journal>-<year>.md layout: paper, title, authors, journal, year, doi, image, and optional pdf and github
Videos videos/_posts/YYYY-MM-DD-speaker-event.md layout: video, title, author, conference, youtubeId

Addresses and renames

A page’s address is built from its file name, without the date, so a name must be unique and is best left unchanged once the page is out. Keep names lowercase, with words joined by hyphens:

  • News: the date it was posted (two-digit month and day), then a few words saying what it is about, for example 2026-09-19-moving-to-purdue.md, at /news/moving-to-purdue/.
  • Papers: <date>-<first-author>-<journal>-<year>, with the journal’s ISO 4 abbreviation in hyphens, for example 2025-01-30-park-nat-mater-2025.md; add a and b after the year for two papers by the same first author in the same journal and year.
  • Team: <date>-<name>, matching the person’s title, for example 2020-10-25-aaron-tieu.md.
  • Videos: the talk’s date, the speaker’s surname and the event, for example 2021-04-20-canepa-mrs-seattle.md.

A post’s picture takes the same name as the post: for news, images/news/<name>.jpg for a photo or .png for a graphic or screenshot (a second picture in the text adds -figure); for papers, images/papers/<name>.png; for team members, images/team/<name>.jpg. Research pictures take the name of their page (its file name without the date) and an underscore: images/research/<page>_splash.jpg (or .png) for the page’s own picture, and images/research/<page>_<what-it-shows>.png for a figure in the text, in a few hyphenated words, for example batteries_nasicon-voltage-map.png.

To rename a page, list its old address in its header under redirect_from: (for example - /papers/old-name/), and _plugins/redirect-from.rb writes a redirect there. A rename that changes only letter case (such as /team/Piero-Canepa/ to /team/piero-canepa/) cannot have one: a Mac’s disk ignores case, so the redirect page would be written over the page itself. GitHub Pages tells the two apart, so the 404 page runs js/not-found-redirect.js, which sends a visitor to the lowercase address when that page exists. Every page except the 404 page names its own address in a <link rel="canonical"> (redirect pages name the new one), so search engines count variants such as /papers/?q=… as that page.

News

On the News page every picture is shown in the same 3:2 frame: photos fill it, cropped from the bottom, while logos (images/misc/logo_*, any .svg) and pictures more than twice as wide as tall are shown whole inside it. Add image_fit: contain to show a picture whole as well, for example a logo saved as a .jpg.

Papers

  • The PDF is stored in the carepapers S3 bucket as <year>/<name>.pdf and is public. Set pdf: <year>/<name>.pdf; the site builds the download link from it.
  • A preprint’s doi on arXiv (10.48550/arXiv.…) shows the arXiv icon and label, and one on ChemRxiv (10.26434/chemrxiv.…) a flask icon and the label “ChemRxiv”, instead of the DOI icon.
  • Write authors surname first, Surname I. I., comma-separated, with “and” before the last one (also after a comma when there are three or more) and your own name in <b>: Xie W., Deng Z., and <b>Canepa P.</b>. The site shows them initials first (“W. Xie, Z. Deng, and P. Canepa”, the initials_first filter in _plugins/initials-first.rb), while the Google Scholar tags, BibTeX, the team pages’ Publications and the Papers search read the stored form.
  • Write journal as <i>Journal</i> volume, pages (year), with the ISO 4 abbreviation (except Angewandte Chemie International Edition, written Angew. Chem.), no comma after the journal name, an en dash in page ranges and no issue number: <i>Chem. Mater.</i> 33, 5652–5667 (2021). Use <i>Journal</i> (year) while volume and pages are not known, and <i>arXiv</i> (year) or <i>ChemRxiv</i> (year) for a preprint. Keep anything else, such as a book’s ISBN, in a field of its own.
  • The line under a paper’s title is made from authors and journal; when it would wrap, js/citation-fit.js shortens the authors to the first ones that fit plus “et al.”, always keeping P. Canepa, with the full list in the tooltip. The short references on the home and Papers pages (A. First et al., <i>Journal</i>) come from the same fields (_includes/paper-ref.html), so the old ref field is no longer used.
  • Every paper lists its topics in its header, topics: [solid-state-batteries, interfaces], by the slugs in _data/topics.yml (Batteries, Lithium, Sodium, Solid-state batteries, Multivalent, Interfaces, Electrochemistry, Organic electroactive materials, Porous frameworks, Method development, Software and data, Optical materials, Other topics). _plugins/paper-topics.rb adds the topics those imply (a battery type adds Batteries, and Batteries adds Electrochemistry), and stops the build on an unknown slug or a paper with none. Software and data is not set by hand: every paper the Software page lists for a code (papers in _data/software.yml) gets it, and its page links to that code. The Papers page shows the topics as filter buttons, combined with the search and kept in the address (/papers/?topic=batteries); a paper’s page lists its topics, and a research page named as a topic’s research ends with a link to all our papers on it.
  • The Collaborators page (papers/collaborators/) draws everyone we have written with as a network, built at every build from the papers’ authors by _plugins/collaborators.rb and drawn by js/collaborators.js with D3’s force layout, self-hosted in js/vendor/d3-force.min.js because the Content-Security-Policy allows scripts only from this site. Team members are matched as on their team pages (by their papers list, or as “Surname I”); an author written in more than one way (“Cheetham A.” and “Cheetham A. K.”) is merged by a line in _data/collaborator_names.yml.
  • The search box on the Papers page (js/paper-filter.js) matches every word typed against each paper’s title, authors, journal (also by its full name, from _data/journals.yml: add a line there for a new journal), year, DOI and abstract. A full name such as “Jean-Noël Chotard” finds “Chotard J.-N.”, a team member is found by their name alone (“Tara”; a team page’s aliases: adds other names), and words in double quotes must appear together. The query stays in the address (/papers/?q=sodium), so a filtered list can be shared. The abstracts come from papers/search.json, built from every paper’s ## Abstract section and downloaded only once the box is used.

Team

  • Write a bio in the first person. When a member leaves, set alumni: true, open the bio with where they are now (“I am now a research scientist at …”), and put finished student or postdoc periods in the past tense; hobbies and current interests stay in the present. Current members are listed most recently added first. Alumni are grouped by the position they held (research fellows, PhD students, master’s students, undergraduate and summer students, then research staff), alphabetically within each group; the group comes from position, or from alumni_group (research-fellows, phd-students, masters-students, undergraduates or staff) when the position names a later job, as for Zeyu Deng.
  • Sidebar links are shown alphabetically by label, whatever their order in the header. profile is a university profile page, shown as “University profile” (set profile_label for another heading, such as “Institutional profile”); website is a personal website; linkedin is the name in linkedin.com/in/<name>; twitter is the X handle, linked to x.com; scholar is the Google Scholar profile ID (the user= part of its address).
  • “Life in the group”, between the current members and the alumni, shows the photos listed in _data/gallery.yml (its header says how to add one: the picture in images/gallery/, its smaller copy, a date and a caption), in one horizontal strip, newest first, with the year over the first photo of each year: it is swiped on phones, scrolled sideways elsewhere, and js/gallery-strip.js adds arrow buttons wherever there is a mouse or trackpad, whatever the window’s width. Only add a photo everyone recognisable in it is happy to share.
  • Under Publications, a member’s page lists every paper whose authors contain their surname and first initial (“Wang J” for Juefan Wang). When that is shared with other authors, list their papers by address instead, papers: [wang-chem-mater-2021, wang-mater-futures-2023], as Juefan Wang, Yan Li and Yuheng Li have; Crossref (https://api.crossref.org/works/<doi>) gives each author’s full given name, to sort out whose paper is whose.

Research pages

  • order sets a page’s place on the Research page (battery topics first), and in the row of research pictures on the home page, which shows the first four; there each title fits on one line, so a longer one needs a shorter form there, in short_title.
  • references lists the addresses of our papers the page cites (/papers/<name>/), in order of first citation; {% include research-refs.html refs=page.references %} lists them under “Relevant references” in the style of the papers’ pages, linked to them, and each citation in the text is a superscript number linked to the same page. A paper from another group, which has no page here, is given as authors, journal and doi.
  • Figures in the text are <figure class="text-figure"> blocks, placed before the paragraph they illustrate: floated right beside it, with their caption under them, and across the column on phones. Number them in order and cite each in the text (“see Figure 1”). Add the class text-figure-medium to give a figure 36% of the column instead of 45%, or text-figure-small for 30% (a square or tall figure). Add text-figure-left to place a figure on the left of its paragraph instead.
  • On the Research page each picture fills a 3:2 frame, cropped from the bottom; a picture more than twice as wide as tall, or one whose page sets image_fit: contain, is shown whole, and image_position (for example center 40%) moves the crop. A picture on a transparent background (saved as PNG, with a WebP copy that keeps the transparency) takes image_transparent: true, so it sits straight on the page in dark mode instead of on the white card other pictures get. A page’s image also shows at the top of the page itself; set splash: false when it is set in the text as a figure instead.
  • listed: false with sitemap: false keeps a page at its address but leaves it off the Research page, its Index, the site search and the sitemap, as for Non-linear optics.

Conventions

  • The navigation bar lists Research, Papers, Software, Team, News and Join, in that order (what the lab does, its output, its people, then news, and a way in for prospective members); its links are in _layouts/default.html. The pages in misc/_posts/ are linked from the footer by their title; give one a nav_title for a shorter label (About) or footer: false to leave it out (Join, already in the navigation bar).
  • Titles and headings are in sentence case, with capitals only for the first word and for proper nouns (“Organic electroactive materials”, “Graduate study at Purdue”); paper titles keep their journal’s capitals, and people’s positions on the Team page (“PhD Student”) keep theirs.
  • Dates are shown as “Sept. 19, 2026” everywhere (the ap_date filter in _plugins/last-update.rb).
  • News and research posts show an estimated reading time after their date, as do the About, Join, and Mission and values pages under their title: the words of the text, without its references, at 200 a minute, rounded up (_includes/reading-time.html). To add it to another page, put <p class="news-author">{% include reading-time.html text=page.content %}</p> after its title block.
  • Every page gets a <meta name="description"> for search results: its own description field, otherwise a paper’s abstract or Talk by <author> at <conference>: <title> for a video, otherwise a post’s first paragraph, otherwise the site tagline in _config.yml, cut to 160 characters. The home page sets its own in index.html; add a description to any other page whose first paragraph makes a poor summary. Character references in titles and descriptions (&#58;, &alpha;) are decoded for link previews by the decode_entities filter (_plugins/decode-entities.rb).

E-mail addresses

Never write an e-mail address in a page. Use the include instead, which prints “name [at] example.org” and lets js/email-links.js build the mailto: link only while a visitor hovers, focuses or taps it, so the address is in neither the page source nor the loaded page. The member layout does this for a team page’s email field.

{% include email-link.html address="[email protected]" %}

Design

The site is a light layer over a trimmed Bootstrap 5 grid: text set in Inter, colors that follow the visitor’s light or dark setting and meet WCAG AA contrast in both, and every font, icon and script served from the site itself, apart from Google Analytics, the Altmetric and Dimensions badges, and the embedded videos and map. Pages are meant to load quickly on a phone, so pictures are served as WebP with their space reserved, and listing thumbnails load only as they scroll into view. The sections below give the details.

Styles and layout

  • Styles are SCSS partials in css/, compiled into css/style.css; layouts are in _layouts/ and shared snippets in _includes/.
  • Only the parts of Bootstrap 5 the site uses are compiled in: the @imports at the top of css/style.scss (grid, containers, type, nav, navbar, collapse transitions, breadcrumb, helpers and utilities), which roughly halves the stylesheet. Cards, buttons, forms, dropdowns and modals are left out, so a page that uses one looks unstyled until its import is added there, in the same order as bootstrap.scss. Bootstrap’s JavaScript is not loaded either: js/nav-toggle.js opens and closes the mobile menu with Bootstrap’s collapse classes.
  • Long text fades out instead of stretching its row. Titles fade after two lines on the News page and four in its Index view, with the date and author below always in full (the fade-lines mixin in css/_variables.scss, which leaves titles whole on phones). On the Papers page js/paper-titles.js fades a title on the last line that keeps the card no taller than its picture (.is-cut), or after five lines without JavaScript. Preview text fades (the fade-box mixin in css/style.scss) at a fixed height in the news list (.feedbox) and after five lines (six on phones) on the Research page (.feedboxblog). The home page’s Recent news and Recent papers show their two newest items in full.
  • The card grids show one, two or three cards a row by window width, so text is not squeezed into narrow columns:

    Page Cards a row, by window width
    Papers one below 992px, two at 992–1399px, three from 1400px; 64px apart
    Team one below 768px, two at 768–1199px, three from 1200px; 30px apart
    News, Index view one below 768px, two at 768–1199px, three from 1200px; 30px apart

    The Papers page switches later because each paper’s text sits beside a 120px picture, so the text is never narrower than about 245px; its wider gap (.paper-row) keeps each title closer to its own picture than to the next card’s.

  • On the News, Research and Software pages each picture sits in its own column beside the text, in a 3:2 frame; on phones, Research and Software pictures keep their own proportions, at most 240px wide and 180px tall.
  • A “back to top” button (js/back-to-top.js, .back-to-top) fades in once a page is scrolled past 600px and scrolls smoothly to the top (instantly if the visitor prefers reduced motion); it is added once in _layouts/default.html, so every page has it.
  • The navbar’s magnifying glass opens a search overlay (_includes/search-dialog.html, js/search-dialog.js, .search-dialog): one large field with the six best matches under it as you type and a “See all” link when there are more. Enter opens /search/?q=... with every result; Escape, the close button or a click outside closes it. The overlay and the search page share their matching (js/search-core.js), so they find the same pages in the same order, and both give the time the search took (“7 pages in 0.4 ms”); the overlay downloads the search index the first time it is opened. Without JavaScript the icon is a plain link to /search/. The X that Chrome, Edge and Safari show in a search field is restyled as the overlay’s thin close X.
  • The footer shows “Last update on Oct. 6, 2026 · Loaded in 0.42 s” at its right edge (below the copyright on phones). The date is that of the latest commit (_plugins/last-update.rb), so it changes when the content does; the load time is the visitor’s own, from the browser’s Navigation Timing API (js/load-time.js), and is hidden when the browser does not report it.
  • Markdown tables on this page are styled under .about-text, since Bootstrap’s table styles are not compiled in; on phones each row stacks into a block.

Colors and accessibility

  • Colors are CSS variables in css/_theme.scss. The site follows the visitor’s light or dark setting, and the moon/sun button in the navigation bar switches and remembers the choice.
  • All text meets WCAG AA contrast (4.5:1) in both themes; keep it that way when you change a color (the navigation bar’s hover and active text uses $link-color-navlink-on-dark in css/_variables.scss for this reason). Links in running text are not underlined, since their color sets them apart, except those drawn in the color of the surrounding text (the home page’s introduction, the author and DOI links in .smallnote, the footer credits), which get a faint underline so they are not told apart by color alone (WCAG 1.4.1).
  • Every page’s content sits in a <main> element, and icon-only links carry an aria-label, with aria-hidden="true" on the icon.

Fonts

  • Text is set in Inter, self-hosted in css/fonts/inter/ with its @font-face rules in css/_inter.scss: in the unicode-range subsets Google Fonts uses, so pages do not wait on two connections to Google before their text can render. _layouts/default.html preloads normal-latin.woff2, the one file every page needs. Until Inter has loaded, the text is set in “Inter fallback” (also in css/_inter.scss): Arial, or Liberation Sans on Linux, scaled to take the same room, so the page does not shift when Inter replaces it. Inter’s alternate lowercase l with a tail (cv05) and capital I with crossbars (cv08) are turned on in css/style.scss, so that I and l are told apart in formulas such as LiCl or Li₃InCl₆. Google Fonts’ copies of Inter drop these alternates, so the files are cut from the official release (rsms.me/inter) by _scripts/subset-inter-font.py, which explains how to rerun it.
  • Until October 2026 the site used IBM Plex Sans, kept on the ibm-plex-sans branch. Its files (css/fonts/ibm-plex-sans/, css/_plex-sans.scss) are still in main, so switching back means changing the @import and font-family in css/style.scss and the preload in _layouts/default.html. Inter runs about 4% wider than Plex at the same size.
  • iOS Safari would link number runs such as a paper’s pages as phone numbers; <meta name="format-detection" content="telephone=no"> stops it, so a real phone number needs an explicit tel: link.

Icons

  • Icons are Font Awesome Free 6.7.2 (fa-solid, fa-regular and fa-brands, for example fa-brands fa-x-twitter) and Academicons 1.9.5 (ai ai-doi), both self-hosted: the SCSS in css/fontawesome/ and css/_academicons.scss, the fonts in css/webfonts/ and css/fonts/. The sun of the light/dark button is a hand-drawn inline SVG in _layouts/default.html, because Font Awesome’s looks like a cog.
  • Both icon fonts are trimmed to the icons the site uses (about 5 KB instead of 300 KB for Font Awesome, 3 KB instead of 128 KB for Academicons), and css/_icons.scss emits only those icons’ classes. To use a new icon, add its name to $fa-used-icons or $ai-used-icons in css/_icons.scss and run python3 _scripts/subset-icon-fonts.py (needs pip install fonttools brotli); an unlisted icon shows as a blank square. The script also updates the fingerprints in css/_icons-version.scss; commit that file with the fonts. The full fonts are in _fontawesome-webfonts/ and _academicons-webfonts/, which Jekyll does not publish. To upgrade Font Awesome, replace css/fontawesome/ with the new release’s scss/ and _fontawesome-webfonts/ with its webfonts/ (the .woff2 files), then run the script.
  • images/favicon/favicon.ico (and its copy at the repository root) holds 16, 32, 48 and 64px images; keep all four if you regenerate it, or it renders blurry on high-DPI displays. images/favicon/browserconfig.xml (Windows tiles) is published like any other file; _config.yml must not exclude *.xml, or it would be dropped.

Images

  • Pictures rendered through _includes/responsive-image.html (graphical abstracts, research and news pictures, team photos) are served as WebP, with the original PNG or JPEG as a <picture> fallback. Add a WebP copy beside every new picture (cwebp original.png -o original.webp) and never delete the original. A few large pictures also have smaller WebP copies, listed in _data/responsive_images.yml, which phones and the home page’s research row load instead: a news photo has a 640px copy, <name>-640w.webp, listed with the original’s width; a research picture lists the original’s width and then those of its copies, as [800, 640, 360] for <name>-640w.webp and <name>-360w.webp. A page passes the width a picture takes in its layout as the include’s sizes, so the browser picks the smallest copy that is sharp enough.
  • _data/image_sizes.yml records each picture’s width and height, so the include can reserve its space and the page does not shift while it loads; add an entry with sips -g pixelWidth -g pixelHeight path/to/image.
  • Thumbnails on the listing pages (news, research, papers, team) pass loading="lazy" to the include, so they load only once they scroll into view.

Analytics

  • Google Analytics is in js/analytics.js (loaded by _includes/ga.html), not inline, because of the Content-Security-Policy (see Security). It queues the page view at once but downloads the ~150 KB gtag.js library only after the page has loaded, so it does not slow the first paint on phones; a visitor who leaves before then is not counted.

Browsers and standards

  • Supported browsers are current Chrome, Edge, Firefox, Safari and Opera; Internet Explorer is not (the theme relies on CSS custom properties, and Bootstrap 5 dropped it).
  • The site is checked by hand, from time to time, with the W3C Nu Html Checker and the W3C CSS Validator (most recently in September 2026, on one page per layout and the compiled stylesheet), and what they find is fixed; the CSS validator’s remaining messages are informational (vendor-prefixed selectors and custom properties, which it cannot evaluate).
  • The scripts in js/ follow JavaScript Standard Style: no semicolons, two-space indentation, const and let, and a space before a function’s parentheses. With Node.js installed, npx standard --env browser js/ checks them and --fix corrects most problems, without adding files to the repository; run it by hand when the scripts change. Write new JavaScript as a file in js/, never inline (see Security).

The HTML and CSS badges run the live site through the validator; the scripts are checked with npx standard, as described above, and the JavaScript badge leads to the style guide. HTML5 logo by the W3C (CC BY 3.0); CSS logo by the CSS-Next Community Group (CC0); JS logo by Christopher Williams and Manuel Strehl (MIT).

Security

Cloudflare settings

  • Rules → Transform Rules, rule “CSP and permissions” (all requests) sets three response headers. Content-Security-Policy is stricter than the <meta> one: default-src 'self', and script-src allows the site’s own files, a few named hosts (Google Tag Manager, Altmetric, Dimensions) and inline scripts only by their exact SHA-256 hash. The theme script in _includes/theme.html is the only inline script left, so keep its formatting: editing it, or adding another inline script, blocks it silently until its new hash is added to the rule. The rule still lists a second hash, for a jQuery call removed in September 2026, which can be deleted. A new third-party script, stylesheet, image or API host must be added to the matching directive. frame-src allows https://www.youtube.com for the talks and https://maps.google.com https://www.google.com for the map on the Contact us page (the embed starts at the first and redirects to the second). The rule also sets Permissions-Policy (camera, microphone, geolocation, payment and USB off) and Cross-Origin-Opener-Policy: same-origin.
  • SSL/TLS → Edge Certificates: HSTS on for 12 months with includeSubDomains (every subdomain must serve HTTPS; today only www, which redirects to the main site), preload off; X-Content-Type-Options: nosniff on.
  • Caching → Cache Rules: “Versioned CSS and JS, 1 year” (/css/style.css and /js/*, safe because a changed file gets a new ?v=), and “Fonts and images, 30 days” (/css/fonts/, /css/webfonts/, /images/: 31 days in browsers, while Cloudflare’s own copy follows the 10-minute origin setting). Pages keep GitHub Pages’ 10 minutes. An image keeps its address when it changes, so a returning visitor can see the old one for up to a month: give a replaced image a new file name. The icon fonts carry their own fingerprint (css/_icons-version.scss), so a changed icon set gets new addresses.

File conventions

.gitattributes and .editorconfig keep every text file in UTF-8 with LF line endings and a final newline, as POSIX defines a text file; let your editor honour them. The one exception is google736838dc293297e8.html, the Google Search Console verification file, which must stay exactly as Google issued it.

License

All source code in this repository, consisting of files with extensions .html, .css, .scss, .rb or .js, is freely available under an MIT license, unless otherwise noted within a file. You’re welcome to borrow or repurpose code to build your own site. The license’s text is in the LICENSE file of the source repository.

The MIT License (MIT)

Copyright (c) 2018-present Pieremanuele Canepa with the help of Bedford and CWD

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.