diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..0d461e1
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2026 Open Free Books contributors
+
+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.
diff --git a/content/credits.md b/content/credits.md
new file mode 100644
index 0000000..a4f01c2
--- /dev/null
+++ b/content/credits.md
@@ -0,0 +1,4 @@
++++
+title = "Credits"
+template = "credits.html"
++++
diff --git a/data/credits.json b/data/credits.json
new file mode 100644
index 0000000..7726dce
--- /dev/null
+++ b/data/credits.json
@@ -0,0 +1,82 @@
+{
+ "intro": "Open Free Books uses the open source libraries below (in alphabetical order—we try!).",
+ "contributors_note": "Textbook authors and maintainers are listed on the homepage.",
+ "project": {
+ "name": "Open Free Books",
+ "version": "0.0.1",
+ "license": "MIT",
+ "license_url": "https://github.com/hananoshikayomaru/openfreebooks/blob/main/LICENSE",
+ "copyright": "Copyright (c) 2026 Open Free Books contributors",
+ "url": "https://openfreebooks.org"
+ },
+ "libraries": [
+ {
+ "name": "Bun",
+ "version": "1.3.10",
+ "license": "MIT",
+ "license_url": "https://github.com/oven-sh/bun/blob/main/LICENSE.md",
+ "copyright": "Copyright (c) Oven-sh",
+ "url": "https://bun.sh"
+ },
+ {
+ "name": "Sass",
+ "version": "1.89.x",
+ "license": "MIT",
+ "license_url": "https://github.com/sass/dart-sass/blob/main/LICENSE",
+ "copyright": "Copyright (c) Google Inc. and contributors",
+ "url": "https://sass-lang.com"
+ },
+ {
+ "name": "Solid.js",
+ "version": "1.9.13",
+ "license": "MIT",
+ "license_url": "https://github.com/solidjs/solid/blob/main/LICENSE",
+ "copyright": "Copyright (c) 2016-2025 Ryan Carniato",
+ "url": "https://www.solidjs.com"
+ },
+ {
+ "name": "TypeScript",
+ "version": "5.9.3",
+ "license": "Apache License 2.0",
+ "license_url": "https://github.com/microsoft/TypeScript/blob/main/LICENSE.txt",
+ "copyright": "Copyright (c) Microsoft Corporation",
+ "url": "https://www.typescriptlang.org"
+ },
+ {
+ "name": "Vite",
+ "version": "6.4.2",
+ "license": "MIT",
+ "license_url": "https://github.com/vitejs/vite/blob/main/LICENSE",
+ "copyright": "Copyright (c) 2019-present VoidZero Inc. and Vite contributors",
+ "url": "https://vite.dev"
+ },
+ {
+ "name": "vite-plugin-solid",
+ "version": "2.11.12",
+ "license": "MIT",
+ "license_url": "https://github.com/solidjs/vite-plugin-solid/blob/main/LICENSE",
+ "copyright": "Copyright (c) 2021-present SolidJS contributors",
+ "url": "https://github.com/solidjs/vite-plugin-solid"
+ },
+ {
+ "name": "Zola",
+ "version": "0.22.1",
+ "license": "MIT",
+ "license_url": "https://github.com/getzola/zola/blob/master/LICENSE",
+ "copyright": "Copyright (c) 2017-present Vincent Prouillet and contributors",
+ "url": "https://www.getzola.org"
+ }
+ ],
+ "hosting": [
+ {
+ "name": "Cloudflare",
+ "url": "https://www.cloudflare.com",
+ "note": "Static site hosting, CDN, and deploy (Workers & Wrangler)"
+ },
+ {
+ "name": "GitHub",
+ "url": "https://github.com/hananoshikayomaru/openfreebooks",
+ "note": "Code hosting"
+ }
+ ]
+}
diff --git a/data/credits.types.ts b/data/credits.types.ts
new file mode 100644
index 0000000..d1f7946
--- /dev/null
+++ b/data/credits.types.ts
@@ -0,0 +1,34 @@
+/** Credits page data (`data/credits.json`). */
+
+export interface CreditProject {
+ name: string;
+ version: string;
+ license: string;
+ license_url: string;
+ copyright: string;
+ url?: string;
+}
+
+export interface CreditLibrary {
+ name: string;
+ version: string;
+ license: string;
+ license_url?: string;
+ copyright: string;
+ url: string;
+}
+
+export interface CreditHosting {
+ name: string;
+ version?: string;
+ url: string;
+ note: string;
+}
+
+export interface CreditsFile {
+ intro: string;
+ contributors_note: string;
+ project: CreditProject;
+ libraries: CreditLibrary[];
+ hosting: CreditHosting[];
+}
diff --git a/package.json b/package.json
index 14f2c1b..c005949 100644
--- a/package.json
+++ b/package.json
@@ -1,5 +1,6 @@
{
"name": "openfreebooks",
+ "version": "0.0.1",
"private": true,
"type": "module",
"scripts": {
diff --git a/spec.md b/spec.md
index f1f5ee8..2faf149 100644
--- a/spec.md
+++ b/spec.md
@@ -4,4 +4,6 @@ this project is free internet textbooks for elementary schools to university stu
this project is build using zola. interactivity by solid js. deployed to cloudflare.
-canvas feature use jsoncanvas standard by Obsidian.
\ No newline at end of file
+canvas feature use [jsoncanvas](https://jsoncanvas.org/spec/1.0/) standard by Obsidian. Viewer is [JSON canvas viewer](https://github.com/Hesprs/JSON-Canvas-Viewer).
+
+not markdown, html based. but in every page, we should have a copy as md button using [defuddle](https://github.com/kepano/defuddle).
\ No newline at end of file
diff --git a/static/icons/social/ATTRIBUTION.md b/static/icons/social/ATTRIBUTION.md
new file mode 100644
index 0000000..0e2cfab
--- /dev/null
+++ b/static/icons/social/ATTRIBUTION.md
@@ -0,0 +1,3 @@
+Social icons are from [Tabler Icons](https://tabler.io/icons) ([MIT License](https://github.com/tabler/tabler-icons/blob/master/LICENSE)).
+
+Source: https://github.com/tabler/tabler-icons/tree/main/icons/outline
diff --git a/static/icons/social/bluesky.svg b/static/icons/social/bluesky.svg
new file mode 100644
index 0000000..dc04b21
--- /dev/null
+++ b/static/icons/social/bluesky.svg
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/static/icons/social/discord.svg b/static/icons/social/discord.svg
new file mode 100644
index 0000000..a992400
--- /dev/null
+++ b/static/icons/social/discord.svg
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
diff --git a/static/icons/social/email.svg b/static/icons/social/email.svg
new file mode 100644
index 0000000..2e51946
--- /dev/null
+++ b/static/icons/social/email.svg
@@ -0,0 +1,20 @@
+
+
+
+
+
diff --git a/static/icons/social/facebook.svg b/static/icons/social/facebook.svg
new file mode 100644
index 0000000..c57aee6
--- /dev/null
+++ b/static/icons/social/facebook.svg
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/static/icons/social/github.svg b/static/icons/social/github.svg
new file mode 100644
index 0000000..513c9bd
--- /dev/null
+++ b/static/icons/social/github.svg
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/static/icons/social/gitlab.svg b/static/icons/social/gitlab.svg
new file mode 100644
index 0000000..d96bdf4
--- /dev/null
+++ b/static/icons/social/gitlab.svg
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/static/icons/social/instagram.svg b/static/icons/social/instagram.svg
new file mode 100644
index 0000000..d69523e
--- /dev/null
+++ b/static/icons/social/instagram.svg
@@ -0,0 +1,21 @@
+
+
+
+
+
+
diff --git a/static/icons/social/linkedin.svg b/static/icons/social/linkedin.svg
new file mode 100644
index 0000000..8318421
--- /dev/null
+++ b/static/icons/social/linkedin.svg
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
diff --git a/static/icons/social/mastodon.svg b/static/icons/social/mastodon.svg
new file mode 100644
index 0000000..54ac596
--- /dev/null
+++ b/static/icons/social/mastodon.svg
@@ -0,0 +1,20 @@
+
+
+
+
+
diff --git a/static/icons/social/medium.svg b/static/icons/social/medium.svg
new file mode 100644
index 0000000..5f0b934
--- /dev/null
+++ b/static/icons/social/medium.svg
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
diff --git a/static/icons/social/orcid.svg b/static/icons/social/orcid.svg
new file mode 100644
index 0000000..506d775
--- /dev/null
+++ b/static/icons/social/orcid.svg
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/static/icons/social/rss.svg b/static/icons/social/rss.svg
new file mode 100644
index 0000000..485d579
--- /dev/null
+++ b/static/icons/social/rss.svg
@@ -0,0 +1,21 @@
+
+
+
+
+
+
diff --git a/static/icons/social/scholar.svg b/static/icons/social/scholar.svg
new file mode 100644
index 0000000..2845625
--- /dev/null
+++ b/static/icons/social/scholar.svg
@@ -0,0 +1,20 @@
+
+
+
+
+
diff --git a/static/icons/social/substack.svg b/static/icons/social/substack.svg
new file mode 100644
index 0000000..e673025
--- /dev/null
+++ b/static/icons/social/substack.svg
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
diff --git a/static/icons/social/threads.svg b/static/icons/social/threads.svg
new file mode 100644
index 0000000..d6c0b9c
--- /dev/null
+++ b/static/icons/social/threads.svg
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/static/icons/social/tiktok.svg b/static/icons/social/tiktok.svg
new file mode 100644
index 0000000..1481298
--- /dev/null
+++ b/static/icons/social/tiktok.svg
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/static/icons/social/website.svg b/static/icons/social/website.svg
new file mode 100644
index 0000000..9803590
--- /dev/null
+++ b/static/icons/social/website.svg
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
diff --git a/static/icons/social/x.svg b/static/icons/social/x.svg
new file mode 100644
index 0000000..3f39f78
--- /dev/null
+++ b/static/icons/social/x.svg
@@ -0,0 +1,20 @@
+
+
+
+
+
diff --git a/static/icons/social/youtube.svg b/static/icons/social/youtube.svg
new file mode 100644
index 0000000..e636729
--- /dev/null
+++ b/static/icons/social/youtube.svg
@@ -0,0 +1,20 @@
+
+
+
+
+
diff --git a/themes/openfreebooks/sass/_credits.scss b/themes/openfreebooks/sass/_credits.scss
new file mode 100644
index 0000000..2e35efd
--- /dev/null
+++ b/themes/openfreebooks/sass/_credits.scss
@@ -0,0 +1,86 @@
+.credits-page {
+ padding: 54px 0 72px;
+ border-top: 1px solid var(--line);
+}
+
+.credits-prose {
+ max-width: var(--prose-width);
+}
+
+.credits-lead,
+.credits-contributors-note,
+.credits-section-intro {
+ margin: 0 0 1rem;
+ color: var(--soft-ink);
+ font-size: 1.05rem;
+ line-height: 1.72;
+}
+
+.credits-contributors-note a,
+.credits-entry-name a,
+.credits-entry-license a {
+ color: var(--accent);
+ font-weight: 600;
+ text-decoration: none;
+}
+
+.credits-contributors-note a:hover,
+.credits-contributors-note a:focus-visible,
+.credits-entry-name a:hover,
+.credits-entry-name a:focus-visible,
+.credits-entry-license a:hover,
+.credits-entry-license a:focus-visible {
+ text-decoration: underline;
+ text-underline-offset: 3px;
+}
+
+.credits-block {
+ margin-top: 40px;
+}
+
+.credits-section-title {
+ margin: 0 0 16px;
+ font-family: var(--font-heading);
+ font-size: clamp(1.35rem, 2.2vw, 1.85rem);
+ font-weight: 400;
+ line-height: 1.2;
+}
+
+.credits-entry {
+ margin: 0 0 28px;
+ padding-bottom: 28px;
+ border-bottom: 1px solid var(--line);
+}
+
+.credits-block .credits-entry:last-child {
+ margin-bottom: 0;
+ padding-bottom: 0;
+ border-bottom: none;
+}
+
+.credits-entry-name {
+ margin: 0 0 8px;
+ font-family: var(--font-heading);
+ font-size: 1.25rem;
+ font-weight: 400;
+ line-height: 1.25;
+}
+
+.credits-entry-name a {
+ color: var(--ink);
+}
+
+.credits-entry-version,
+.credits-entry-license,
+.credits-entry-copyright,
+.credits-entry-note {
+ margin: 0 0 6px;
+ color: var(--soft-ink);
+ font-size: 0.98rem;
+ line-height: 1.6;
+}
+
+.credits-entry-copyright:last-child,
+.credits-entry-note:last-child {
+ margin-bottom: 0;
+}
diff --git a/themes/openfreebooks/sass/_layout.scss b/themes/openfreebooks/sass/_layout.scss
index 66a8cc6..ee548b7 100644
--- a/themes/openfreebooks/sass/_layout.scss
+++ b/themes/openfreebooks/sass/_layout.scss
@@ -49,9 +49,21 @@ section.hero {
.footer-inner {
display: flex;
flex-wrap: wrap;
- justify-content: space-between;
align-items: baseline;
- gap: 12px 20px;
+ gap: 12px 24px;
+}
+
+.footer-copy {
+ flex: 1 1 16rem;
+ min-width: min(100%, 16rem);
+}
+
+.footer-links {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: baseline;
+ gap: 12px 24px;
+ flex-shrink: 0;
}
.footer-link {
diff --git a/themes/openfreebooks/sass/main.scss b/themes/openfreebooks/sass/main.scss
index 96aafe4..d3432f6 100644
--- a/themes/openfreebooks/sass/main.scss
+++ b/themes/openfreebooks/sass/main.scss
@@ -4,3 +4,4 @@
@import "components";
@import "why-sections";
@import "contributors";
+@import "credits";
diff --git a/themes/openfreebooks/static/404.html b/themes/openfreebooks/static/404.html
deleted file mode 100644
index 2925e02..0000000
--- a/themes/openfreebooks/static/404.html
+++ /dev/null
@@ -1,65 +0,0 @@
-
-
-
-
-
- Page not found | Open Free Books
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Page not found
-
That page is not in the catalog yet. Try the homepage or browse when books are published.
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/themes/openfreebooks/static/index.html b/themes/openfreebooks/static/index.html
deleted file mode 100644
index 7456d95..0000000
--- a/themes/openfreebooks/static/index.html
+++ /dev/null
@@ -1,755 +0,0 @@
-
-
-
-
-
- Open Free Books
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Open textbooks. Free to read. Open to improve.
-
- High-quality learning materials for elementary school through university — on the web, at no cost.
-
-
- Free means the whole book, for everyone — read it all online without paywalls.
- Open means open source — anyone can fix a typo, add a chapter, or fork a book on GitHub.
-
-
-
-
-
-
-
-
-
-
-
-
- Stack of textbooks and cost
-
-
-
-
-
-
- $
-
-
-
-
-
-
-
The problem
-
Textbook fees hit families hard
-
- In many countries, families pay hundreds of dollars per child each year for printed textbooks —
- on top of tuition, devices, and supplies. When money is tight, students share worn copies, skip
- buying books, or fall behind before the term begins.
-
-
- That cost is not a small inconvenience. It is a barrier to showing up prepared. Open Free Books
- exists so every learner can start the year with complete materials , not a receipt.
-
-
-
-
-
-
-
-
-
- Paper and PDF versus interactive HTML
-
-
- PDF
-
-
-
-
-
-
-
-
- </>
-
-
-
-
-
The medium
-
Long live the web — not the PDF
-
- Paper textbooks are fixed: one layout, one edition, no room to fix a typo until the next print run.
- Most “digital” versions are the same pages exported to PDF — still static, still hard to search,
- still impossible to embed a simulation or a live diagram.
-
-
- HTML on the open web is different. Chapters can link to sources, resize for any screen,
- include interactive figures, and improve over time. The book becomes something you use — not something
- you only carry.
-
-
-
-
-
-
-
-
-
- Teacher guiding, open textbook
-
-
-
-
-
-
-
-
-
-
-
-
People & books
-
Replace textbooks, not teachers
-
- A great teacher — whether in person or, someday, assisted by thoughtful tools — still sets pace,
- asks hard questions, and notices when a student is stuck. That relationship is not what we are
- trying to automate.
-
-
- Textbooks are different. They are reference and structure: explanations, exercises, diagrams.
- Those can be free, forkable, and kept current on the web so teachers spend less
- time hunting permissions and more time teaching.
-
-
-
-
-
-
-
-
-
- Student thinking with a textbook
-
-
-
-
-
-
- ?
-
-
-
-
-
-
Agency
-
Do not outsource your learning
-
- Finishing a chapter is not the same as understanding it. Skimming for answers, copying worked
- solutions, or rushing to the end leaves gaps that show up on the next test — and in the years after.
-
-
- Read slowly. Try the problems before you peek at hints. Sit with confusion long enough to name what
- you do not get. The textbook is a guide; the thinking still has to be yours. That habit
- is what school is really training, whether the subject is algebra or history.
-
-
-
-
-
-
-
-
-
- Open textbook and the earth
-
-
-
-
-
-
-
-
-
- OPEN
-
-
-
-
-
Planet
-
Open textbooks are gentler on the Earth
-
- Core curriculum changes slowly. Newton’s laws, the structure of a cell, and how fractions work do not
- need a new AI run every September. Regenerating the same chapter thousands of times burns electricity
- in data centers — for text that could have been written once and shared openly.
-
-
- One carefully reviewed book , published on the web for everyone, means less redundant
- compute, less e-waste from disposable PDFs, and fewer trucks moving heavy print runs. Students get
- stable material they can trust; the environment gets less waste from doing the same work over and over.
-
-
-
-
-
-
-
-
-
- Scholars and institutions worldwide
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Craft
-
Carefully crafted by brilliant people on Earth
-
- A textbook is not a bulk download. It is years of lectures distilled, diagrams redrawn until they
- click, exercises tested in real classrooms, and arguments tightened by reviewers who care about
- getting it right.
-
-
- Open Free Books gathers that work from educators and researchers at institutions around the world —
- people who have already spent their careers making hard ideas legible. We publish their care
- openly so the next student inherits the best version, not a disposable draft.
-
-
-
-
-
Contributors and partners from leading universities include
-
-
-
-
-
-
- MIT
-
-
-
-
- Harvard
- UNIVERSITY
-
-
-
-
- Stanford
-
-
-
-
- Berkeley
- UNIVERSITY OF CALIFORNIA
-
-
-
-
- Caltech
-
-
-
-
- Princeton
-
-
-
-
- Yale
-
-
-
-
- Columbia
-
-
-
-
- Cornell
-
-
-
-
-
-
-
- MIT
-
-
-
-
- Harvard
- UNIVERSITY
-
-
-
-
- Stanford
-
-
-
-
- Berkeley
- UNIVERSITY OF CALIFORNIA
-
-
-
-
- Caltech
-
-
-
-
- Princeton
-
-
-
-
- Yale
-
-
-
-
- Columbia
-
-
-
-
- Cornell
-
-
-
-
-
-
-
-
-
-
-
-
- CMU
-
-
-
-
- Oxford
- UNIVERSITY
-
-
-
-
- Cambridge
-
-
-
-
- Imperial
- COLLEGE LONDON
-
-
-
-
- LSE
-
-
-
-
- ETH
-
-
-
-
- Toronto
- UNIVERSITY OF
-
-
-
-
- McGill
-
-
-
-
- HKU
- THE UNIVERSITY OF HONG KONG
-
-
-
-
-
-
-
- CMU
-
-
-
-
- Oxford
- UNIVERSITY
-
-
-
-
- Cambridge
-
-
-
-
- Imperial
- COLLEGE LONDON
-
-
-
-
- LSE
-
-
-
-
- ETH
-
-
-
-
- Toronto
- UNIVERSITY OF
-
-
-
-
- McGill
-
-
-
-
- HKU
- THE UNIVERSITY OF HONG KONG
-
-
-
-
-
-
-
-
-
-
-
-
- HKUST
-
-
-
-
- CUHK
-
-
-
-
- NUS
- NATIONAL UNIVERSITY OF SINGAPORE
-
-
-
-
- Tsinghua
-
-
-
-
- PKU
-
-
-
-
- Tokyo
- UNIVERSITY OF
-
-
-
-
- ANU
-
-
-
-
- Melbourne
-
-
-
-
- IIT
- BOMBAY
-
-
-
-
-
-
-
- HKUST
-
-
-
-
- CUHK
-
-
-
-
- NUS
- NATIONAL UNIVERSITY OF SINGAPORE
-
-
-
-
- Tsinghua
-
-
-
-
- PKU
-
-
-
-
- Tokyo
- UNIVERSITY OF
-
-
-
-
- ANU
-
-
-
-
- Melbourne
-
-
-
-
- IIT
- BOMBAY
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Catalog
-
Browse by subject
-
-
- Mathematics
- Coming soon
- Algebra, calculus, statistics, and more — structured for self-study and classrooms.
-
-
- Science
- Coming soon
- Physics, chemistry, biology, and earth science from introductory to advanced levels.
-
-
- Humanities
- Coming soon
- History, literature, philosophy, and languages — readable, citable, and free to share.
-
-
- Computing
- Coming soon
- Programming, computer science fundamentals, and practical skills for students and teachers.
-
-
-
Subject pages and full catalogs are on the roadmap. Contribute a book on GitHub.
-
-
-
-
-
-
Featured
-
Featured books
-
-
- Your textbook here
- Placeholder
- We are building the first open catalog. The first published books will appear in this grid.
-
-
- Community contributions
- Open source
- Every book is a repository you can fork, translate, or adapt for your classroom.
-
-
-
Want to list a book? Open a pull request or start a discussion on GitHub.
-
-
-
-
-
-
-
-
People
-
Contributors
-
- Open Free Books is written and maintained in the open. These are the people building and reviewing the textbooks.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Want to contribute? Open a pull request on GitHub .
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/themes/openfreebooks/static/main.css b/themes/openfreebooks/static/main.css
deleted file mode 100644
index 997df6b..0000000
--- a/themes/openfreebooks/static/main.css
+++ /dev/null
@@ -1 +0,0 @@
-:root{--ink: #1a1a1a;--soft-ink: #555;--muted: #767676;--accent: #9a6b2e;--line: #e8e8e8;--paper: #f5f4f1;--header-bg-scrolled: rgba(252, 252, 253, 0.9);--card-bg: rgba(255, 255, 255, 0.66);--card-border: rgba(26, 26, 26, 0.08);--shadow-soft: rgba(20, 20, 20, 0.04);--mono: "IBM Plex Mono", "SFMono-Regular", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--font-heading: "Instrument Serif", serif;--font-body: Inter, Arial, sans-serif;--prose-width: 68ch;--grain-svg: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)' opacity='0.55'/%3E%3C/svg%3E")}[data-theme=dark]{--ink: #eceae4;--soft-ink: #b8b4ab;--muted: #8f8a80;--accent: #c4924a;--line: #3a3834;--paper: #1a1917;--header-bg-scrolled: rgba(26, 25, 23, 0.92);--card-bg: rgba(36, 34, 31, 0.72);--card-border: rgba(236, 234, 228, 0.1);--shadow-soft: rgba(0, 0, 0, 0.25)}@media (prefers-color-scheme: dark){:root:not([data-theme=light]){--ink: #eceae4;--soft-ink: #b8b4ab;--muted: #8f8a80;--accent: #c4924a;--line: #3a3834;--paper: #1a1917;--header-bg-scrolled: rgba(26, 25, 23, 0.92);--card-bg: rgba(36, 34, 31, 0.72);--card-border: rgba(236, 234, 228, 0.1);--shadow-soft: rgba(0, 0, 0, 0.25)}}body::before{content:"";position:fixed;inset:0;z-index:9999;pointer-events:none;opacity:.7;mix-blend-mode:multiply;background-image:var(--grain-svg);background-size:180px 180px}.contributor-dialog[open],.contributor-dialog[open] .contributor-dialog-panel{mix-blend-mode:normal}[data-theme=dark] body::before{opacity:.45;mix-blend-mode:soft-light}@media (prefers-color-scheme: dark){:root:not([data-theme=light]) body::before{opacity:.45;mix-blend-mode:soft-light}}*{box-sizing:border-box}html{scroll-behavior:smooth}@media (prefers-reduced-motion: reduce){html{scroll-behavior:auto}}html,body{margin:0;padding:0;background:var(--paper);color:var(--ink);font-family:var(--font-body)}.container{width:min(1100px,92vw);margin:0 auto}main{min-height:50vh}section{padding:54px 0}section.hero{padding:0}.footer{border-top:1px solid var(--line);margin-top:45px;padding:20px 0 34px;color:var(--soft-ink);font-size:.84rem}.footer-inner{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:baseline;gap:12px 20px}.footer-link{font-size:.78rem;color:var(--muted);text-decoration:none;letter-spacing:.02em}.footer-link:hover,.footer-link:focus-visible{color:var(--accent)}h1,h2,h3{margin:0;font-family:var(--font-heading);font-weight:400}.site-header{position:sticky;top:0;z-index:8;border-bottom:1px solid rgba(0,0,0,0);transition:background-color 320ms ease,border-color 320ms ease,box-shadow 320ms ease}.site-header.is-scrolled{backdrop-filter:blur(10px);background:var(--header-bg-scrolled);border-color:var(--line);box-shadow:0 8px 20px var(--shadow-soft)}.header-row{padding:24px 0;display:flex;justify-content:space-between;align-items:center;gap:20px;transition:padding 320ms ease}.site-header.is-scrolled .header-row{padding:13px 0}.brand{display:flex;align-items:center;gap:12px}.brand-name{font-family:var(--font-heading);font-weight:400;font-size:1.2rem;color:var(--ink);text-decoration:none}.brand-name:hover,.brand-name:focus-visible{color:var(--accent)}.header-actions{display:flex;align-items:center;gap:16px}.main-nav{display:flex;gap:26px}.main-nav a{color:var(--soft-ink);letter-spacing:.14em;text-transform:uppercase;font-size:.7rem;font-weight:700;font-family:var(--mono);text-decoration:none}.main-nav a:hover,.main-nav a:focus-visible{color:var(--accent)}.theme-toggle{display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;margin:0;padding:0;border:1px solid var(--line);border-radius:8px;background:rgba(0,0,0,0);color:var(--ink);cursor:pointer;transition:background-color .2s ease,border-color .2s ease}.theme-toggle:hover{background:color-mix(in srgb, var(--accent) 10%, rgba(0,0,0,0));border-color:color-mix(in srgb, var(--accent) 35%, var(--line))}.theme-toggle:focus-visible{outline:2px solid var(--accent);outline-offset:2px}.nav-burger{display:none;flex-direction:column;justify-content:center;align-items:center;gap:5px;width:32px;height:32px;margin:0;padding:0;border:0;border-radius:8px;background:rgba(0,0,0,0);color:var(--ink);cursor:pointer;position:relative;z-index:10003;transition:background-color .2s ease}.nav-burger:hover{background:color-mix(in srgb, var(--accent) 12%, rgba(0,0,0,0))}.nav-burger:focus-visible{outline:2px solid var(--accent);outline-offset:2px}.nav-burger-line{display:block;width:22px;height:2px;border-radius:1px;background:currentColor;transition:transform .32s ease,opacity .24s ease}.site-header.nav-is-open .nav-burger-line:nth-child(1){transform:translateY(7px) rotate(45deg)}.site-header.nav-is-open .nav-burger-line:nth-child(2){opacity:0}.site-header.nav-is-open .nav-burger-line:nth-child(3){transform:translateY(-7px) rotate(-45deg)}.nav-backdrop{display:none}.mobile-nav-panel{display:none}.hero{position:relative;min-height:min(88vh,720px);display:flex;flex-direction:column;padding:0}.hero .container{flex:1;display:flex;flex-direction:column;justify-content:center;padding-block:clamp(2rem,6vh,5rem)}.hero h1{max-width:860px;font-size:clamp(2.2rem,5.2vw,4.2rem);line-height:1.08}.hero-lead{max-width:680px;margin:24px 0 16px;color:var(--soft-ink);font-size:clamp(1.05rem,1.9vw,1.35rem);line-height:1.55}.hero-points{max-width:680px;margin:0 0 32px;padding:0;list-style:none;color:var(--soft-ink);font-size:1.02rem;line-height:1.65}.hero-points li{margin-bottom:.5rem;padding-left:1.25rem;position:relative}.hero-points li::before{content:"—";position:absolute;left:0;color:var(--accent)}.hero-actions{display:flex;flex-wrap:wrap;gap:20px;align-items:center}.button{display:inline-flex;align-items:center;justify-content:center;border-radius:4px;padding:16px 32px;text-decoration:none;font-weight:700;font-size:.93rem;letter-spacing:.02em;border:1px solid rgba(0,0,0,0);transition:transform 200ms ease,box-shadow 200ms ease,color 200ms ease}.button-primary{background:var(--accent);color:#fff}.button-primary:hover{transform:translateY(-1px);box-shadow:0 10px 24px color-mix(in srgb, var(--accent) 35%, rgba(0,0,0,0))}.button-secondary{color:var(--ink);border-color:rgba(0,0,0,0);background:rgba(0,0,0,0);padding-left:0;padding-right:0;border-radius:0}.button-secondary:hover{color:var(--accent)}.section-kicker{margin-bottom:8px;font-size:.72rem;letter-spacing:.16em;color:var(--accent);text-transform:uppercase;font-weight:700;font-family:var(--mono)}.section-title{font-size:clamp(1.75rem,3.1vw,2.8rem);margin-bottom:24px}.section-note{margin-top:14px;color:var(--muted);font-size:.88rem}.work-grid{display:grid;gap:18px;grid-template-columns:repeat(2, minmax(0, 1fr))}.work-card{background:var(--card-bg);border:1px solid var(--card-border);border-radius:0;overflow:hidden;padding:24px;transition:transform 350ms ease,opacity 500ms ease,translate 500ms ease;opacity:0;translate:0 20px}.work-card.is-inview{opacity:1;translate:0 0}.work-card:hover{transform:scale(1.01)}.work-card h3{margin:0 0 12px;font-size:clamp(1.4rem,2vw,1.85rem);line-height:1.2}.work-card p{color:var(--soft-ink);margin:0;font-size:1.02rem;line-height:1.7}.card-subtitle{font-style:italic;color:var(--muted);font-size:.98rem;margin-bottom:12px}.marquee-shell{margin:0;padding:0}.marquee{overflow:hidden;white-space:nowrap;width:100vw;margin-left:calc(-50vw + 50%);padding:14px 0}.marquee-track{display:inline-flex;align-items:center;animation:marquee-slide 32s linear infinite}.marquee-text{font-family:var(--font-heading);font-style:italic;font-weight:400;color:color-mix(in srgb, var(--ink) 72%, rgba(0,0,0,0));font-size:clamp(1.25rem,2.3vw,1.65rem);line-height:1.22;user-select:none;white-space:nowrap;display:inline-block;padding-right:3rem}.marquee-line{height:1px;background:linear-gradient(90deg, color-mix(in srgb, var(--accent) 45%, rgba(0,0,0,0)) 0%, color-mix(in srgb, var(--accent) 20%, rgba(0,0,0,0)) 100%)}@keyframes marquee-slide{from{transform:translateX(0)}to{transform:translateX(-33.333333%)}}@media (max-width: 900px){.work-grid{grid-template-columns:1fr}}@media (max-width: 467px){.nav-burger{display:inline-flex;margin-left:auto}.header-actions .main-nav{display:none}.site-header.nav-is-open{z-index:10000;background-color:var(--paper);border-bottom-color:var(--line);box-shadow:0 8px 20px var(--shadow-soft);backdrop-filter:none}.nav-backdrop{display:block;position:fixed;inset:0;z-index:10001;background:rgba(22,22,22,.48);backdrop-filter:blur(10px);opacity:0;pointer-events:none;transition:opacity .3s ease}.site-header.nav-is-open .nav-backdrop{opacity:1;pointer-events:auto}.mobile-nav-panel{position:fixed;inset:0;z-index:10002;display:flex;flex-direction:column;justify-content:flex-start;align-items:flex-start;gap:0;padding:96px 28px 40px;margin:0;background-color:var(--paper);opacity:0;visibility:hidden;pointer-events:none;transition:none}.mobile-nav-panel::before{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;opacity:.7;mix-blend-mode:multiply;background-image:var(--grain-svg);background-size:180px 180px}.site-header.nav-is-open .mobile-nav-panel{opacity:1;visibility:visible;pointer-events:auto;transition:opacity .3s ease,visibility .3s ease}.mobile-nav-panel a{position:relative;z-index:1;color:var(--soft-ink);letter-spacing:.14em;text-transform:uppercase;font-size:1.05rem;font-weight:700;font-family:var(--mono);text-decoration:none;padding:14px 0;width:100%}.mobile-nav-panel a:hover{color:var(--accent)}}@media (prefers-reduced-motion: reduce){.marquee-track{animation:none}.work-card{opacity:1;translate:0 0;transition:none}}@media (hover: none),(pointer: coarse){.marquee-track{animation-duration:48s}}.why-section{padding:64px 0;border-top:1px solid var(--line)}.why-row{display:grid;grid-template-columns:minmax(0, 1fr) minmax(0, 1fr);gap:clamp(32px,5vw,56px);align-items:center}.why-row--art-end .why-art{order:2}.why-row--art-end .why-copy{order:1}.why-art{display:flex;justify-content:center;align-items:center;opacity:0;translate:0 20px;transition:opacity 500ms ease,translate 500ms ease}.why-art.is-inview{opacity:1;translate:0 0}.why-art svg{width:min(100%,280px);height:auto;display:block}.why-copy{max-width:var(--prose-width);opacity:0;translate:0 20px;transition:opacity 500ms ease,translate 500ms ease}.why-copy.is-inview{opacity:1;translate:0 0}.why-copy .section-title{margin-bottom:16px}.why-copy p{margin:0 0 1rem;color:var(--soft-ink);font-size:1.05rem;line-height:1.72}.why-copy p:last-child{margin-bottom:0}.why-copy strong{color:var(--ink);font-weight:600}.why-section--community .why-craft-logos-wrap{overflow:hidden;opacity:0;translate:0 20px;transition:opacity 500ms ease,translate 500ms ease}.why-section--community .why-craft-logos-wrap.is-inview{opacity:1;translate:0 0}.university-logos-label{margin:0 0 24px;text-align:center;font-family:var(--mono);font-size:.68rem;letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}.university-carousel{display:flex;flex-direction:column;gap:12px;width:100vw;margin-left:calc(-50vw + 50%);overflow:hidden}.university-carousel-row{overflow:hidden;mask-image:linear-gradient(90deg, rgba(0,0,0,0) 0%, #000 6%, #000 94%, rgba(0,0,0,0) 100%)}.university-carousel-track{display:flex;width:max-content;animation:university-carousel-forward 52s linear infinite}.university-carousel-row--reverse .university-carousel-track{animation-name:university-carousel-reverse;animation-duration:58s}.university-carousel-row--slow .university-carousel-track{animation-duration:64s}.university-carousel-group{display:flex;flex-shrink:0;align-items:center;gap:12px;margin:0;padding:0 6px;list-style:none}@keyframes university-carousel-forward{from{transform:translateX(0)}to{transform:translateX(-50%)}}@keyframes university-carousel-reverse{from{transform:translateX(-50%)}to{transform:translateX(0)}}.university-logo{display:flex;align-items:center;justify-content:center;min-height:56px;padding:10px 12px;background:var(--card-bg);border:1px solid var(--card-border)}.university-logo svg{width:108px;height:auto;display:block;color:var(--ink)}.university-logo--mit{color:#a31f34}[data-theme=dark] .university-logo--mit{color:#e85a6f}.university-logo--harvard{color:#a51c30}[data-theme=dark] .university-logo--harvard{color:#e88a96}.university-logo--stanford{color:#8c1515}[data-theme=dark] .university-logo--stanford{color:#e88a8a}.university-logo--berkeley{color:#003262}[data-theme=dark] .university-logo--berkeley{color:#6a9fd4}.university-logo--caltech{color:#ff6c0c}[data-theme=dark] .university-logo--caltech{color:#f5a623}.university-logo--princeton{color:#e77500}[data-theme=dark] .university-logo--princeton{color:#f0a040}.university-logo--yale{color:#00356b}[data-theme=dark] .university-logo--yale{color:#6a9fd4}.university-logo--columbia{color:#003865}[data-theme=dark] .university-logo--columbia{color:#7eb3e8}.university-logo--cornell{color:#b31b1b}[data-theme=dark] .university-logo--cornell{color:#e85a6f}.university-logo--cmu{color:#c41230}[data-theme=dark] .university-logo--cmu{color:#e87888}.university-logo--oxford{color:#002147}[data-theme=dark] .university-logo--oxford{color:#7eb3e8}.university-logo--cambridge{color:#0072cf}[data-theme=dark] .university-logo--cambridge{color:#6ab0f0}.university-logo--imperial{color:#003e74}[data-theme=dark] .university-logo--imperial{color:#6a9fd4}.university-logo--lse{color:#e41f13}[data-theme=dark] .university-logo--lse{color:#f07870}.university-logo--eth{color:#1f407a}[data-theme=dark] .university-logo--eth{color:#6a9fd4}.university-logo--toronto{color:#002a5c}[data-theme=dark] .university-logo--toronto{color:#6a9fd4}.university-logo--mcgill{color:#ed1b2f}[data-theme=dark] .university-logo--mcgill{color:#f07888}.university-logo--hku{color:#006747}[data-theme=dark] .university-logo--hku{color:#3cb88a}.university-logo--hkust{color:#036}[data-theme=dark] .university-logo--hkust{color:#6a9fd4}.university-logo--cuhk{color:#7b2d8e}[data-theme=dark] .university-logo--cuhk{color:#c49ae0}.university-logo--nus{color:#ef7c00}[data-theme=dark] .university-logo--nus{color:#f5a623}.university-logo--tsinghua{color:#82318e}[data-theme=dark] .university-logo--tsinghua{color:#c49ae0}.university-logo--pku{color:#94070a}[data-theme=dark] .university-logo--pku{color:#e87878}.university-logo--utokyo{color:#003f87}[data-theme=dark] .university-logo--utokyo{color:#6a9fd4}.university-logo--anu{color:#c4a337}[data-theme=dark] .university-logo--anu{color:#e8c860}.university-logo--melbourne{color:#094183}[data-theme=dark] .university-logo--melbourne{color:#6a9fd4}.university-logo--iitb{color:#036}[data-theme=dark] .university-logo--iitb{color:#6a9fd4}@media (prefers-color-scheme: dark){:root:not([data-theme=light]) .university-logo--mit{color:#e85a6f}:root:not([data-theme=light]) .university-logo--harvard{color:#e88a96}:root:not([data-theme=light]) .university-logo--stanford{color:#e88a8a}:root:not([data-theme=light]) .university-logo--berkeley{color:#6a9fd4}:root:not([data-theme=light]) .university-logo--caltech{color:#f5a623}:root:not([data-theme=light]) .university-logo--princeton{color:#f0a040}:root:not([data-theme=light]) .university-logo--yale{color:#6a9fd4}:root:not([data-theme=light]) .university-logo--columbia{color:#7eb3e8}:root:not([data-theme=light]) .university-logo--cornell{color:#e85a6f}:root:not([data-theme=light]) .university-logo--cmu{color:#e87888}:root:not([data-theme=light]) .university-logo--oxford{color:#7eb3e8}:root:not([data-theme=light]) .university-logo--cambridge{color:#6ab0f0}:root:not([data-theme=light]) .university-logo--imperial{color:#6a9fd4}:root:not([data-theme=light]) .university-logo--lse{color:#f07870}:root:not([data-theme=light]) .university-logo--eth{color:#6a9fd4}:root:not([data-theme=light]) .university-logo--toronto{color:#6a9fd4}:root:not([data-theme=light]) .university-logo--mcgill{color:#f07888}:root:not([data-theme=light]) .university-logo--hku{color:#3cb88a}:root:not([data-theme=light]) .university-logo--hkust{color:#6a9fd4}:root:not([data-theme=light]) .university-logo--cuhk{color:#c49ae0}:root:not([data-theme=light]) .university-logo--nus{color:#f5a623}:root:not([data-theme=light]) .university-logo--tsinghua{color:#c49ae0}:root:not([data-theme=light]) .university-logo--pku{color:#e87878}:root:not([data-theme=light]) .university-logo--utokyo{color:#6a9fd4}:root:not([data-theme=light]) .university-logo--anu{color:#e8c860}:root:not([data-theme=light]) .university-logo--melbourne{color:#6a9fd4}:root:not([data-theme=light]) .university-logo--iitb{color:#6a9fd4}}@media (max-width: 900px){.why-row,.why-row--art-end{grid-template-columns:1fr}.why-row--art-end .why-art,.why-row--art-end .why-copy{order:unset}.why-art svg{width:min(100%,220px)}}@media (prefers-reduced-motion: reduce){.why-art,.why-copy,.why-section--community .why-craft-logos-wrap{opacity:1;translate:0 0;transition:none}.university-carousel-track{animation:none;flex-wrap:wrap;width:100%;justify-content:center}.university-carousel-row{mask-image:none}.university-carousel-group[aria-hidden=true]{display:none}.university-carousel{width:100%;margin-left:0}}.why-section--community{--community-block-gap: 72px}.why-section--community .why-craft-logos-wrap{margin-top:var(--community-block-gap)}.why-section--community .community-contributors{margin-top:var(--community-block-gap);padding-bottom:12px}.contributors-intro{max-width:var(--prose-width);margin:0 0 24px;color:var(--soft-ink);font-size:1.05rem;line-height:1.72}.contributors-avatar-grid{display:flex;flex-wrap:wrap;gap:4px;margin:0;padding:0;list-style:none}.contributors-avatar-item{opacity:0;translate:0 12px;transition:opacity 400ms ease,translate 400ms ease}.contributors-avatar-item.is-inview{opacity:1;translate:0 0}.contributor-avatar-btn{display:block;margin:0;padding:0;border:2px solid rgba(0,0,0,0);border-radius:50%;background:none;cursor:pointer;line-height:0;transition:border-color 160ms ease,transform 160ms ease}.contributor-avatar-btn:hover,.contributor-avatar-btn:focus-visible{border-color:var(--accent);transform:translateY(-2px);outline:none}.contributor-avatar-img,.contributor-avatar-fallback{display:block;width:48px;height:48px;border-radius:50%}.contributor-avatar-img{object-fit:cover;border:1px solid var(--card-border);background:var(--paper)}.contributor-avatar-fallback{display:flex;align-items:center;justify-content:center;background:var(--card-bg);border:1px solid var(--card-border);color:var(--accent);font-family:var(--font-heading);font-size:1.25rem;font-weight:400;text-transform:uppercase}.contributor-dialog{margin:auto;padding:0;border:none;max-width:min(92vw,440px);background-color:#f5f4f1;color:var(--ink);isolation:isolate}[data-theme=dark] .contributor-dialog{background-color:#1a1917}@media (prefers-color-scheme: dark){:root:not([data-theme=light]) .contributor-dialog{background-color:#1a1917}}.contributor-dialog::backdrop{background:rgba(26,26,26,.45)}[data-theme=dark] .contributor-dialog::backdrop{background:rgba(0,0,0,.62)}@media (prefers-color-scheme: dark){:root:not([data-theme=light]) .contributor-dialog::backdrop{background:rgba(0,0,0,.62)}}.contributor-dialog-panel{display:block;width:100%;box-sizing:border-box;position:relative;margin:0;padding:28px 28px 24px;border:1px solid var(--card-border);background-color:#f5f4f1;box-shadow:0 18px 48px var(--shadow-soft)}[data-theme=dark] .contributor-dialog-panel{background-color:#1a1917}@media (prefers-color-scheme: dark){:root:not([data-theme=light]) .contributor-dialog-panel{background-color:#1a1917}}.contributor-dialog-close{position:absolute;top:12px;right:12px;width:36px;height:36px;margin:0;padding:0;border:none;border-radius:50%;background:rgba(0,0,0,0);color:var(--muted);font-size:1.5rem;line-height:1;cursor:pointer}.contributor-dialog-close:hover,.contributor-dialog-close:focus-visible{color:var(--ink);background:var(--paper);outline:none}.contributor-dialog-header{display:flex;align-items:center;gap:18px;margin-bottom:18px;padding-right:28px}.contributor-dialog-avatar{flex-shrink:0;width:80px;height:80px;border-radius:50%;object-fit:cover;border:1px solid var(--card-border);background:var(--paper)}.contributor-dialog-name{margin:0 0 6px;font-family:var(--font-heading);font-size:clamp(1.35rem,2vw,1.75rem);font-weight:400;line-height:1.2}.contributor-dialog-job{margin:0;color:var(--accent);font-family:var(--mono);font-size:.72rem;letter-spacing:.1em;text-transform:uppercase;font-weight:700}.contributor-dialog-meta,.contributor-dialog-contributions{margin:0 0 14px;color:var(--soft-ink);font-size:.98rem;line-height:1.65}.contributor-meta-label{display:block;margin-bottom:4px;font-family:var(--mono);font-size:.68rem;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);font-weight:700}.contributor-contribution-list{margin:0;padding:0;list-style:none}.contributor-contribution-list li{position:relative;padding-left:1rem;margin-bottom:.35rem}.contributor-contribution-list li::before{content:"—";position:absolute;left:0;color:var(--accent)}.contributor-dialog-connect{margin-top:18px;padding-top:16px;border-top:1px solid var(--line)}.contributor-social-list{display:flex;flex-wrap:wrap;gap:10px;margin:8px 0 0;padding:0;list-style:none}.contributor-social-link{display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;border:1px solid var(--card-border);border-radius:50%;color:var(--ink);text-decoration:none;background:var(--paper);transition:border-color 160ms ease,color 160ms ease,transform 160ms ease}.contributor-social-link:hover,.contributor-social-link:focus-visible{border-color:var(--accent);color:var(--accent);transform:translateY(-1px);outline:none}.contributor-social-icon{display:block;flex-shrink:0}.why-section--community .section-note a{color:var(--accent)}.why-section--community .community-contributors .section-note{margin-top:28px}@media (prefers-reduced-motion: reduce){.contributors-avatar-item{opacity:1;translate:0 0;transition:none}.contributor-avatar-btn:hover,.contributor-avatar-btn:focus-visible{transform:none}}
\ No newline at end of file
diff --git a/themes/openfreebooks/static/robots.txt b/themes/openfreebooks/static/robots.txt
deleted file mode 100644
index 5c2271f..0000000
--- a/themes/openfreebooks/static/robots.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-User-agent: *
-Disallow:
-Allow: /
-Sitemap: https://openfreebooks.org/sitemap.xml
diff --git a/themes/openfreebooks/static/site.webmanifest b/themes/openfreebooks/static/site.webmanifest
deleted file mode 100644
index 573ed77..0000000
--- a/themes/openfreebooks/static/site.webmanifest
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "name": "Open Free Books",
- "short_name": "OpenFreeBooks",
- "icons": [
- {
- "src": "/android-chrome-192x192.png",
- "sizes": "192x192",
- "type": "image/png"
- },
- {
- "src": "/android-chrome-512x512.png",
- "sizes": "512x512",
- "type": "image/png"
- }
- ],
- "theme_color": "#9a6b2e",
- "background_color": "#f5f4f1",
- "display": "standalone"
-}
diff --git a/themes/openfreebooks/static/sitemap.xml b/themes/openfreebooks/static/sitemap.xml
deleted file mode 100644
index e2bfb64..0000000
--- a/themes/openfreebooks/static/sitemap.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
- https://openfreebooks.org/
-
-
diff --git a/themes/openfreebooks/templates/base.html b/themes/openfreebooks/templates/base.html
index 312318c..ed30a7e 100644
--- a/themes/openfreebooks/templates/base.html
+++ b/themes/openfreebooks/templates/base.html
@@ -41,8 +41,11 @@
diff --git a/themes/openfreebooks/templates/credits.html b/themes/openfreebooks/templates/credits.html
new file mode 100644
index 0000000..e9057d6
--- /dev/null
+++ b/themes/openfreebooks/templates/credits.html
@@ -0,0 +1,16 @@
+{% extends "base.html" %}
+
+{% block title %}Credits | {{ config.extra.site_title }}{% endblock title %}
+{% block meta_description %}
+
+{% endblock meta_description %}
+
+{% block content %}
+
+
+
Acknowledgements
+
{{ page.title }}
+ {% include "partials/credits-content.html" %}
+
+
+{% endblock content %}
diff --git a/themes/openfreebooks/templates/macros/social-icons.html b/themes/openfreebooks/templates/macros/social-icons.html
index c69b076..2190ab1 100644
--- a/themes/openfreebooks/templates/macros/social-icons.html
+++ b/themes/openfreebooks/templates/macros/social-icons.html
@@ -26,66 +26,47 @@
{% endmacro %}
{% macro social_icon(kind) %}
-
{% if kind == "email" %}
-
-
+{% include "partials/icons/social/email.html" %}
{% elif kind == "github" %}
-
+{% include "partials/icons/social/github.html" %}
{% elif kind == "gitlab" %}
-
+{% include "partials/icons/social/gitlab.html" %}
{% elif kind == "x" %}
-
+{% include "partials/icons/social/x.html" %}
{% elif kind == "youtube" %}
-
-
+{% include "partials/icons/social/youtube.html" %}
{% elif kind == "bluesky" %}
-
+{% include "partials/icons/social/bluesky.html" %}
{% elif kind == "linkedin" %}
-
-
-
-
+{% include "partials/icons/social/linkedin.html" %}
{% elif kind == "mastodon" %}
-
-
+{% include "partials/icons/social/mastodon.html" %}
{% elif kind == "instagram" %}
-
-
-
+{% include "partials/icons/social/instagram.html" %}
{% elif kind == "facebook" %}
-
+{% include "partials/icons/social/facebook.html" %}
{% elif kind == "threads" %}
-
+{% include "partials/icons/social/threads.html" %}
{% elif kind == "tiktok" %}
-
+{% include "partials/icons/social/tiktok.html" %}
{% elif kind == "discord" %}
-
-
+{% include "partials/icons/social/discord.html" %}
{% elif kind == "orcid" %}
-
-
+{% include "partials/icons/social/orcid.html" %}
{% elif kind == "scholar" %}
-
-
+{% include "partials/icons/social/scholar.html" %}
{% elif kind == "medium" %}
-
-
-
+{% include "partials/icons/social/medium.html" %}
{% elif kind == "substack" %}
-
+{% include "partials/icons/social/substack.html" %}
{% elif kind == "rss" %}
-
+{% include "partials/icons/social/rss.html" %}
{% else %}
-
-
+{% include "partials/icons/social/website.html" %}
{% endif %}
-
{% endmacro %}
{% macro website_icon() %}
-
-
-
-
+{% include "partials/icons/social/website.html" %}
{% endmacro %}
diff --git a/themes/openfreebooks/templates/partials/contributors-block.html b/themes/openfreebooks/templates/partials/contributors-block.html
index c7ee9e4..e262dd6 100644
--- a/themes/openfreebooks/templates/partials/contributors-block.html
+++ b/themes/openfreebooks/templates/partials/contributors-block.html
@@ -1,4 +1,4 @@
-{% set contributors_data = load_data(path="contributors.json", format="json") %}
+{% set contributors_data = load_data(path="data/contributors.json", format="json") %}