diff --git a/.gitignore b/.gitignore index 6f1f718f17..af23a74142 100755 --- a/.gitignore +++ b/.gitignore @@ -71,4 +71,5 @@ tsconfig.tsbuildinfo infra/pgdata/ -tmp \ No newline at end of file +tmp +details.md \ No newline at end of file diff --git a/README.md b/README.md index 66ecd6e56e..2f9b52c320 100755 --- a/README.md +++ b/README.md @@ -49,6 +49,55 @@ pnpm dev Navigate to `localhost:9876` +## Fonts + +PubPub uses three main font families, plus CJK variants: + +- **Source Sans 3** — headers, titles, UI text +- **Source Serif 4** — body text in pubs +- **Outfit** — landing page +- **Noto Serif TC/JP/KR/SC** and **Noto Sans TC/JP/KR/SC** — CJK content + +All fonts are variable-weight woff2 files from [Fontsource](https://fontsource.org/), hosted on S3 at `assets.pubpub.org/fonts//`. The font files are not stored in this repo. + +### How it works + +A single `fonts.css` on S3 contains all the `@font-face` declarations (~940 rules) for every font family. Each rule uses `unicode-range` subsetting, so browsers only download the woff2 slices for characters actually on the page. + +The font CSS is loaded via `` tags in `server/Html.tsx` (web) and `workers/tasks/export/html.tsx` (PDF exports), so the browser can start fetching it in parallel with other resources. + +### Cache busting + +Files on `assets.pubpub.org` have a long TTL. To avoid cache issues, all font files live under a content-hashed directory (`/fonts//`). The hash is derived from the sha256 of all generated files. If nothing changes, the hash stays the same and nothing gets re-uploaded. If anything changes, you get a new directory and new URLs automatically. + +Old versions remain on S3 harmlessly — they'll just stop being referenced. + +### Updating fonts + +Run the upload script: + +``` +# Dry run — downloads fonts, generates CSS, shows what would happen, updates source files +scripts/upload-fonts-to-s3.sh --dry-run + +# Real run — same as above, but also uploads to S3 +AWS_ACCESS_KEY_ID=... AWS_SECRET_ACCESS_KEY=... scripts/upload-fonts-to-s3.sh +``` + +The script: + +1. Downloads fontsource packages directly from npm (nothing gets installed in the project) +2. Copies all woff2 files to a staging directory +3. Generates `fonts.css` with corrected `font-family` names and relative `url()` paths +4. Computes a content hash from everything in the staging directory +5. Uploads to `s3://assets.pubpub.org/fonts//` +6. Updates the font URL in `server/Html.tsx` and `workers/tasks/export/html.tsx` + +After running the script, commit the updated source files. You need AWS credentials with write access to the `assets.pubpub.org` bucket. + +To add or remove font families, edit the `PACKAGES` and `CSS_SOURCES` arrays in the script, and update `client/styles/variables.scss` to match. + + ## Storybook To build and test components, we use Storybook. To run: diff --git a/client/components/PubPreview/pubPreview.scss b/client/components/PubPreview/pubPreview.scss index 58bbaf3f30..21573c12af 100644 --- a/client/components/PubPreview/pubPreview.scss +++ b/client/components/PubPreview/pubPreview.scss @@ -70,8 +70,9 @@ text-decoration: underline; } .pub-title { - font-weight: 500; + font-weight: 650; font-size: 24px; + letter-spacing: 0px; line-height: 1.33 !important; } } @@ -156,6 +157,7 @@ .pub-title { font-weight: 400; font-size: 22px; + letter-spacing: 0px; line-height: 1.33 !important; } } @@ -197,6 +199,7 @@ .pub-title { font-weight: 400; font-size: 18px; + letter-spacing: 0px; line-height: 1.33 !important; } } @@ -213,7 +216,7 @@ .title-wrapper { padding-bottom: 5px; font-family: - multi-display, + 'Source Sans 3', -apple-system, 'BlinkMacSystemFont', 'Segoe UI', @@ -228,7 +231,8 @@ .pub-title { line-height: 1.25 !important; display: inline; - font-weight: 500; + font-weight: 650; + letter-spacing: 0.2px; } .authors { font-size: 14px; diff --git a/client/containers/Landing/landing.scss b/client/containers/Landing/landing.scss index 43b8828a7c..489ceffb10 100644 --- a/client/containers/Landing/landing.scss +++ b/client/containers/Landing/landing.scss @@ -51,12 +51,12 @@ $leftColumnWidth: 20%; #landing-container { /***** Globals *****/ - font-family: upgrade, sans-serif; - font-weight: 300; + font-family: 'Outfit', sans-serif; + font-weight: 400; font-style: normal; font-size: 1em; line-height: 2em; - letter-spacing: 1px; + letter-spacing: 0.2px; strong { font-weight: 500; } @@ -183,9 +183,10 @@ $leftColumnWidth: 20%; .content { h1 { margin: 1em 0 0.5em 0; - font-weight: 400; + font-weight: 500; font-style: normal; - font-size: 4em; + font-size: 3.9em; + letter-spacing: 0.2px; } h2 { margin: 0.75em 0; @@ -203,9 +204,10 @@ $leftColumnWidth: 20%; .subtitle { max-width: 500px; font-size: 1.5em; - font-family: upgrade-lights, sans-serif; - font-weight: 500; + font-family: 'Outfit', sans-serif; + font-weight: 200; font-style: normal; + letter-spacing: 0px; } } } @@ -234,13 +236,13 @@ $leftColumnWidth: 20%; .feature-number { font-size: 1em; line-height: 2em; - font-weight: 200; + font-weight: 300; text-transform: uppercase; } h4 { font-size: 1.25em; line-height: 2em; - font-weight: 400; + font-weight: 500; } > div:nth-child(odd) { text-align: right; @@ -281,8 +283,8 @@ $leftColumnWidth: 20%; ul { margin-top: 4em; list-style-type: none; - font-family: upgrade-lights; - font-weight: 500; + font-family: 'Outfit', sans-serif; + font-weight: 250; li { margin: 2.4em 0; } @@ -389,8 +391,8 @@ $leftColumnWidth: 20%; .description { font-size: 0.9em; line-height: 1.2em; - font-family: upgrade-light; - font-weight: 300; + font-family: 'Outfit', sans-serif; + font-weight: 300; font-style: italic; } } @@ -425,12 +427,13 @@ $leftColumnWidth: 20%; .container { h4 { font-size: 2em; - font-weight: 300; + font-weight: 350; line-height: 1.2em; + letter-spacing: 0px; } p.disclaimer { - font-family: upgrade-lights; - font-weight: 200; + font-family: 'Outfit', sans-serif; + font-weight: 100; font-style: italic; } } diff --git a/client/containers/Pub/PubDocument/pubBody.scss b/client/containers/Pub/PubDocument/pubBody.scss index ee549c93f1..5b94ddb72f 100644 --- a/client/containers/Pub/PubDocument/pubBody.scss +++ b/client/containers/Pub/PubDocument/pubBody.scss @@ -5,7 +5,7 @@ $bp: vendor.$bp-namespace; @import 'styles/variables.scss'; @import '../pub.scss'; -$pub-body-font-size: if-is-export(14px, 20px); +$pub-body-font-size: if-is-export(13px, 19px); .pub-body-component .editor.ProseMirror, .pub-body-styles { @@ -40,40 +40,45 @@ $pub-body-font-size: if-is-export(14px, 20px); } } h1 { - font-size: 1.4em; - font-weight: 600; - line-height: 1.3em; + font-size: 1.6em; + font-weight: 700; + line-height: 1.1em; letter-spacing: 0px; } h2 { - font-size: 1.3em; - line-height: 1.3em; - font-weight: 500; + font-size: 1.4em; + line-height: 1.1em; + font-weight: 600; letter-spacing: 0px; } h3 { - font-size: 1.2em; - line-height: 1.3em; + font-size: 1.25em; + line-height: 0.8em; font-weight: 400; - letter-spacing: 0.5px; + letter-spacing: 0px; } h4 { font-size: 1em; line-height: 1.3em; - font-weight: 500; - letter-spacing: 0.5px; + font-weight: 600; + letter-spacing: 0px; } h5 { font-size: 1em; line-height: 1.3em; - font-weight: 400; - letter-spacing: 0.5px; + font-weight: 500; + letter-spacing: 0px; } h6 { font-size: 1em; line-height: 1.3em; font-weight: 300; - letter-spacing: 0.5px; + letter-spacing: 0px; + } + // Neutralize inside headings — headings should look + // the same regardless of whether the user toggled bold. + h1, h2, h3, h4, h5, h6 { + strong { font-weight: inherit; } } * + h1, * + h2, @@ -86,11 +91,10 @@ $pub-body-font-size: if-is-export(14px, 20px); p, li { font-family: $body-font; - letter-spacing: 0.01rem; font-weight: 400; font-style: normal; - line-height: 1.7; - letter-spacing: -0.003em; + line-height: if-is-export(1.7, 1.75); + letter-spacing: -0.023em; word-break: break-word; } diff --git a/client/containers/Pub/PubHeader/pubHeader.scss b/client/containers/Pub/PubHeader/pubHeader.scss index a07e7b5460..ced68426e9 100644 --- a/client/containers/Pub/PubHeader/pubHeader.scss +++ b/client/containers/Pub/PubHeader/pubHeader.scss @@ -53,7 +53,8 @@ $mobile-bottom-buttons-spacing: 10px; margin: 0; font-size: 48px; line-height: 1.5em; - font-weight: normal; + font-weight: 450; + letter-spacing: -1.1px; font-family: $header-font; box-decoration-break: clone; @include smaller-viewport { @@ -101,18 +102,19 @@ $mobile-bottom-buttons-spacing: 10px; padding-top: $title-elements-spacing; margin: 0; font-size: 18px; - font-weight: normal; + font-weight: 400; + letter-spacing: 0.3px; font-family: $header-font; } .byline-component { padding-top: $title-elements-spacing; margin: 0; - font-size: 18px; + font-size: 19px; font-style: italic; - font-weight: normal; + font-weight: 400; font-family: $header-font; - letter-spacing: 0.5px; + letter-spacing: 0.1px; .byline-icon svg { width: 14px; height: auto; diff --git a/client/styles/base.scss b/client/styles/base.scss index 86ce3da5e0..c2b2a918b4 100644 --- a/client/styles/base.scss +++ b/client/styles/base.scss @@ -6,7 +6,6 @@ @import '~@blueprintjs/icons/lib/css/blueprint-icons.css'; @import './grid.scss'; -@import url('https://use.typekit.net/kmi0tdo.css'); @import './variables.scss'; @import './typography.scss'; diff --git a/client/styles/variables.scss b/client/styles/variables.scss index be7cb70642..9fd883e7fe 100644 --- a/client/styles/variables.scss +++ b/client/styles/variables.scss @@ -6,16 +6,16 @@ } $cjk-body-font: - source-han-serif-tc, source-han-serif-korean, source-han-serif-japanese, source-han-serif-sc; + 'Noto Serif TC', 'Noto Serif KR', 'Noto Serif JP', 'Noto Serif SC'; $cjk-header-font: - source-han-sans-cjk-tc, source-han-sans-cjk-ko, source-han-sans-cjk-ja, source-han-sans-cjk-sc; + 'Noto Sans TC', 'Noto Sans KR', 'Noto Sans JP', 'Noto Sans SC'; $base-font: -apple-system, 'BlinkMacSystemFont', 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Open Sans', 'Helvetica Neue', sans-serif; $header-font: - multi-display, + 'Source Sans 3', -apple-system, 'BlinkMacSystemFont', 'Segoe UI', @@ -28,11 +28,7 @@ $header-font: sans-serif, $cjk-header-font; -// We make this distinction because Adobe Acrobat hates skolar -$export-body-font: - Georgia, Cambria, 'Times New Roman', Times, 'DejaVu Serif', $cjk-body-font, serif; -$screen-body-font: skolar-latin, Georgia, Cambria, 'Times New Roman', Times, serif; -$body-font: if-is-export($export-body-font, $screen-body-font); +$body-font: 'Source Serif 4', Georgia, Cambria, 'Times New Roman', Times, serif; $mobile-cutoff: 750px; diff --git a/scripts/upload-fonts-to-s3.sh b/scripts/upload-fonts-to-s3.sh new file mode 100755 index 0000000000..9a3a07ed70 --- /dev/null +++ b/scripts/upload-fonts-to-s3.sh @@ -0,0 +1,232 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Download font files from npm (fontsource), upload to S3 under a +# content-hashed directory, and update source files to point at it. +# +# Files are uploaded to: s3://assets.pubpub.org/fonts// +# The hash is derived from the content of all generated files, so +# updating fonts always produces a new URL — no cache purging needed. +# +# This is a one-time (or rare) script — run it when adding or updating fonts. +# No fontsource npm packages need to be installed in the project. +# +# Prerequisites: +# - AWS CLI configured (credentials in env or ~/.aws/credentials) +# - curl, tar, sed, shasum +# +# Usage: +# scripts/upload-fonts-to-s3.sh # download, upload, update source files +# scripts/upload-fonts-to-s3.sh --dry-run # download + preview, skip upload + +BUCKET="assets.pubpub.org" +S3_BASE="fonts" +DRY_RUN=false + +if [[ "${1:-}" == "--dry-run" ]]; then + DRY_RUN=true + echo "=== DRY RUN — no files will be uploaded ===" + echo +fi + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" +EXPORT_HTML="$ROOT_DIR/workers/tasks/export/html.tsx" +SERVER_HTML="$ROOT_DIR/server/Html.tsx" +WORK_DIR=$(mktemp -d) +trap 'rm -rf "$WORK_DIR"' EXIT + +STAGING_DIR="$WORK_DIR/upload" +PKG_DIR="$WORK_DIR/packages" +mkdir -p "$STAGING_DIR" "$PKG_DIR" + +# --------------------------------------------------------------------------- +# Verify AWS credentials before doing anything slow +# --------------------------------------------------------------------------- + +if [[ "$DRY_RUN" == "false" ]]; then + echo "Verifying AWS credentials..." + if ! aws s3api head-bucket --bucket "$BUCKET" 2>/dev/null; then + echo "ERROR: Cannot access s3://$BUCKET/" + echo "Check that AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set correctly." + echo "You can test with: aws s3 ls s3://$BUCKET/ --max-items 1" + exit 1 + fi + echo "AWS credentials OK." + echo +fi + +# --------------------------------------------------------------------------- +# Font packages to download from npm +# --------------------------------------------------------------------------- + +PACKAGES=( + "@fontsource-variable/source-sans-3" + "@fontsource-variable/source-serif-4" + "@fontsource-variable/outfit" + "@fontsource-variable/noto-serif-tc" + "@fontsource-variable/noto-serif-jp" + "@fontsource-variable/noto-serif-kr" + "@fontsource-variable/noto-serif-sc" + "@fontsource-variable/noto-sans-tc" + "@fontsource-variable/noto-sans-jp" + "@fontsource-variable/noto-sans-kr" + "@fontsource-variable/noto-sans-sc" +) + +# --------------------------------------------------------------------------- +# Download and extract packages directly from npm registry +# --------------------------------------------------------------------------- + +echo "Downloading font packages from npm..." + +for pkg in "${PACKAGES[@]}"; do + short_name="${pkg#@fontsource-variable/}" + echo " $pkg" + + tarball_url=$(npm view "$pkg" dist.tarball 2>/dev/null) + if [[ -z "$tarball_url" ]]; then + echo "ERROR: Could not find $pkg on npm" + exit 1 + fi + + pkg_extract="$PKG_DIR/$short_name" + mkdir -p "$pkg_extract" + curl -sL "$tarball_url" | tar xz -C "$pkg_extract" --strip-components=1 + + # Copy woff2 files to staging + if [[ -d "$pkg_extract/files" ]]; then + cp "$pkg_extract/files"/*.woff2 "$STAGING_DIR/" 2>/dev/null || true + fi +done + +TOTAL_WOFF2=$(ls "$STAGING_DIR"/*.woff2 2>/dev/null | wc -l | tr -d ' ') +echo +echo "Downloaded $TOTAL_WOFF2 woff2 files" +echo + +# --------------------------------------------------------------------------- +# Generate fonts.css and fonts-cjk.css (hosted on S3 alongside the woff2 files) +# --------------------------------------------------------------------------- + +# Helper: process a list of CSS_SOURCES entries into a CSS file. +# woff2 files are referenced with relative url() since CSS lives alongside them. +generate_css() { + local output_file="$1" + shift + local sources=("$@") + + { + echo "/* Auto-generated by scripts/upload-fonts-to-s3.sh */" + echo + + for entry in "${sources[@]}"; do + IFS=':' read -r short_name css_file family_override <<< "$entry" + css_path="$PKG_DIR/$short_name/$css_file" + + if [[ ! -f "$css_path" ]]; then + echo "WARNING: $css_path not found, skipping" >&2 + continue + fi + + echo "/* === $family_override ($css_file) === */" + + sed -E \ + -e "s|font-family: '[^']*Variable'|font-family: '${family_override}'|g" \ + -e "s|url\(\./files/([^)]+)\)|url(\1)|g" \ + -e "s|format\('woff2-variations'\)|format('woff2')|g" \ + "$css_path" + + echo + done + } > "$output_file" + + local faces size + faces=$(grep -c "@font-face" "$output_file") + size=$(wc -c < "$output_file" | tr -d ' ') + echo " $(basename "$output_file"): $faces @font-face rules, ${size} bytes" +} + +# All font sources: main + CJK in a single fonts.css +CSS_SOURCES=( + # Main fonts + "source-sans-3:index.css:Source Sans 3" + "source-sans-3:wght-italic.css:Source Sans 3" + "source-serif-4:index.css:Source Serif 4" + "source-serif-4:wght-italic.css:Source Serif 4" + "outfit:index.css:Outfit" + # CJK fonts (Noto Serif + Noto Sans for TC, JP, KR, SC) + "noto-serif-tc:index.css:Noto Serif TC" + "noto-serif-jp:index.css:Noto Serif JP" + "noto-serif-kr:index.css:Noto Serif KR" + "noto-serif-sc:index.css:Noto Serif SC" + "noto-sans-tc:index.css:Noto Sans TC" + "noto-sans-jp:index.css:Noto Sans JP" + "noto-sans-kr:index.css:Noto Sans KR" + "noto-sans-sc:index.css:Noto Sans SC" +) + +echo "Generating fonts.css..." +generate_css "$STAGING_DIR/fonts.css" "${CSS_SOURCES[@]}" +echo + +# --------------------------------------------------------------------------- +# Compute content hash from all generated files +# --------------------------------------------------------------------------- + +CONTENT_HASH=$(find "$STAGING_DIR" -type f | sort | xargs cat | shasum -a 256 | cut -c1-8) +S3_PREFIX="$S3_BASE/$CONTENT_HASH" +BASE_URL="https://$BUCKET/$S3_PREFIX" + +echo "Content hash: $CONTENT_HASH" +echo "S3 path: s3://$BUCKET/$S3_PREFIX/" +echo "Public URL: $BASE_URL/" +echo + +# --------------------------------------------------------------------------- +# Upload to S3 +# --------------------------------------------------------------------------- + +if [[ "$DRY_RUN" == "false" ]]; then + echo "Uploading to s3://$BUCKET/$S3_PREFIX/ ..." + + # Upload woff2 files with long cache + aws s3 sync "$STAGING_DIR/" "s3://$BUCKET/$S3_PREFIX/" \ + --acl public-read \ + --cache-control "public, max-age=31536000, immutable" \ + --exclude "*" --include "*.woff2" \ + --content-type "font/woff2" + + # Upload CSS files + for css in "$STAGING_DIR"/*.css; do + aws s3 cp "$css" "s3://$BUCKET/$S3_PREFIX/$(basename "$css")" \ + --acl public-read \ + --cache-control "public, max-age=31536000, immutable" \ + --content-type "text/css" + done + + echo "Upload complete." +else + echo "Would upload $TOTAL_WOFF2 woff2 files + fonts.css to s3://$BUCKET/$S3_PREFIX/" +fi + +echo + +# --------------------------------------------------------------------------- +# Update source files to point at the new hashed URL +# --------------------------------------------------------------------------- + +# 1. server/Html.tsx — fonts href +sed -i '' -E \ + "s|href=\"https://assets.pubpub.org/fonts/[^\"]+/fonts.css\"|href=\"${BASE_URL}/fonts.css\"|" \ + "$SERVER_HTML" +echo "Updated $SERVER_HTML" + +# 2. workers/tasks/export/html.tsx — fontsHref constant +sed -i '' -E \ + "s|const fontsHref = '.*';|const fontsHref = '${BASE_URL}/fonts.css';|" \ + "$EXPORT_HTML" +echo "Updated $EXPORT_HTML" + +echo +echo "Done! Commit the changes." diff --git a/server/Html.tsx b/server/Html.tsx index 2e0eae3670..3e5ab767f6 100644 --- a/server/Html.tsx +++ b/server/Html.tsx @@ -91,6 +91,8 @@ const Html = (props: Props) => { content="jmmJFnkSOeIEuS54adOzGMwc0kwpsa8wQ-L4GyPpPDg" /> {/* */} + + {customScripts?.css && ( + + + +
+ + +
+

Font Tuner v2

+

Left = original Typekit · Right = new Google Font · Adjust sliders & dropdowns

+ + +
View Mode
+
+ +
+ + + +
Font Selection
+
+ + +
+
+ + +
+
+ + +
+ + +
Pub Header — Title (h1)
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
Pub Header — Description
+
+ + +
+
+ + +
+
+ + +
+ +
Pub Header — Byline
+
+ + +
+
+ + +
+
+ + +
+ + +
Pub Body — h1
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
Pub Body — h2
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
Pub Body — h3
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
Pub Body — h4 / h5 / h6
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
Pub Body — Paragraph
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ + +
PDF Export — Cover Title
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
PDF Export — Body
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ + +
Landing — Global
+
+ + +
+
+ + +
+
+ + +
+ +
Landing — Hero h1
+
+ + +
+
+ + +
+
+ + +
+ +
Landing — Hero h2
+
+ + +
+
+ + +
+ +
Landing — Subtitle (was upgrade-lights 500)
+
+ + +
+
+ + +
+
+ + +
+ +
Landing — Feature list (was upgrade-lights 500)
+
+ + +
+ +
Landing — Community desc (was upgrade-light 300)
+
+ + +
+ +
Landing — Disclaimer (was upgrade-lights 200)
+
+ + +
+ +
Landing — h3 / h4
+
+ + +
+
+ + +
+ +
Landing — CTA heading
+
+ + +
+
+ + +
+
+ + +
+ + +
Pub Preview — Title
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ + +
+
Import / Restore Values
+

Paste a previous output here and click Import to restore all values:

+ + +
+ + +
+
Export
+ + +
+
+ + +
+ + +
Pub Header — Default Theme (no background)
+
+
+
Before (multi-display)
+
+

The Future of Open Access Publishing and Knowledge Sharing

+

A comprehensive exploration of emerging models for academic publishing

+ +
+
+
+
After (Inter)
+
+

The Future of Open Access Publishing and Knowledge Sharing

+

A comprehensive exploration of emerging models for academic publishing

+ +
+
+
+ + +
Pub Header — Light Theme
+
+
+
Before (multi-display)
+
+

The Future of Open Access Publishing and Knowledge Sharing

+

A comprehensive exploration of emerging models for academic publishing

+ +
+
+
+
After (Inter)
+
+

The Future of Open Access Publishing and Knowledge Sharing

+

A comprehensive exploration of emerging models for academic publishing

+ +
+
+
+ + +
Pub Header — White Blocks Theme (box-decoration-break)
+
+
+
Before (multi-display)
+
+

The Future of Open Access Publishing and Knowledge Sharing

+

A comprehensive exploration of emerging models

+ +
+
+
+
After (Inter)
+
+

The Future of Open Access Publishing and Knowledge Sharing

+

A comprehensive exploration of emerging models

+ +
+
+
+ + +
Pub Header — Black Blocks Theme
+
+
+
Before (multi-display)
+
+

The Future of Open Access Publishing and Knowledge Sharing

+

A comprehensive exploration of emerging models

+ +
+
+
+
After (Inter)
+
+

The Future of Open Access Publishing and Knowledge Sharing

+

A comprehensive exploration of emerging models

+ +
+
+
+ + +
Pub Body — Content (headings + body text)
+
+
+
Before (multi-display + skolar-latin)
+

1. Introduction to Open Publishing Infrastructure

+

The landscape of academic publishing is undergoing a fundamental transformation. Open-access mandates from funding agencies, combined with new digital-first platforms, are reshaping how research is disseminated and consumed.

+

1.1 Historical Context

+

From the earliest scientific journals of the 17th century to modern preprint servers, the mechanisms for sharing knowledge have continuously evolved.

+

1.1.1 The Journal Model

+

Peer-reviewed journals remain the gold standard for academic credentialing, yet their business models have come under increasing scrutiny.

+
Subscription-Based Access
+
Paywall Economics
+

A Note on Terminology

+
+
+
After (Inter + Source Serif 4)
+

1. Introduction to Open Publishing Infrastructure

+

The landscape of academic publishing is undergoing a fundamental transformation. Open-access mandates from funding agencies, combined with new digital-first platforms, are reshaping how research is disseminated and consumed.

+

1.1 Historical Context

+

From the earliest scientific journals of the 17th century to modern preprint servers, the mechanisms for sharing knowledge have continuously evolved.

+

1.1.1 The Journal Model

+

Peer-reviewed journals remain the gold standard for academic credentialing, yet their business models have come under increasing scrutiny.

+
Subscription-Based Access
+
Paywall Economics
+

A Note on Terminology

+
+
+ + +
PDF Export — Cover Page + Body (Letter-size simulation)
+
+
+
Before (multi-display + skolar-latin at export sizes)
+
+
The Future of Open Access Publishing and Knowledge Sharing
+
Catherine Ahearn, Travis Rich, Gabriel Stein
+
Published in Journal of Open Science · Jan 15, 2024
+
+
+

1. Introduction to Open Publishing

+

The landscape of academic publishing is undergoing a fundamental transformation. Open-access mandates from funding agencies, combined with new digital-first platforms, are reshaping how research is disseminated and consumed globally.

+

1.1 Historical Context

+

From the earliest scientific journals of the 17th century to modern preprint servers, the mechanisms for sharing knowledge have continuously evolved.

+
+
+
+
After (Inter + Source Serif 4)
+
+
The Future of Open Access Publishing and Knowledge Sharing
+
Catherine Ahearn, Travis Rich, Gabriel Stein
+
Published in Journal of Open Science · Jan 15, 2024
+
+
+

1. Introduction to Open Publishing

+

The landscape of academic publishing is undergoing a fundamental transformation. Open-access mandates from funding agencies, combined with new digital-first platforms, are reshaping how research is disseminated and consumed globally.

+

1.1 Historical Context

+

From the earliest scientific journals of the 17th century to modern preprint servers, the mechanisms for sharing knowledge have continuously evolved.

+
+
+
+ + +
Pub Preview — Cards (header font at smaller sizes)
+
+
+
Before (multi-display)
+
+
The Future of Open Access Publishing and Knowledge Sharing
+
Catherine Ahearn, Travis Rich, Gabriel Stein
+
A comprehensive exploration of emerging models for academic publishing in the digital age.
+
+
+
+
+
Medium Preview: Community-Led Research Platforms
+
A comprehensive exploration of emerging models for academic publishing.
+
+
+
+
Community-Led Research Platforms
+
By the Knowledge Futures Lab
+
+
+
A Brief Introduction to Scholarly Infrastructure
+
Jan 15, 2024
+
+
+
+
After (Inter)
+
+
The Future of Open Access Publishing and Knowledge Sharing
+
Catherine Ahearn, Travis Rich, Gabriel Stein
+
A comprehensive exploration of emerging models for academic publishing in the digital age.
+
+
+
+
+
Medium Preview: Community-Led Research Platforms
+
A comprehensive exploration of emerging models for academic publishing.
+
+
+
+
Community-Led Research Platforms
+
By the Knowledge Futures Lab
+
+
+
A Brief Introduction to Scholarly Infrastructure
+
Jan 15, 2024
+
+
+
+ + +
Landing Page — Hero
+
+
+
Before (upgrade + upgrade-lights)
+
+

PubPub

+

An open-source, community-led, end-to-end publishing platform for knowledge communities.

+

Create knowledge. Share it with audiences who care.

+
+
+
+
After (Outfit)
+
+

PubPub

+

An open-source, community-led, end-to-end publishing platform for knowledge communities.

+

Create knowledge. Share it with audiences who care.

+
+
+
+ + +
Landing Page — Features
+
+
+
Before (upgrade + upgrade-lights)
+
+

Key Features

+

Collaborate & edit with co-authors in real time

+
    +
  • Keep everyone in the loop
  • +
  • Assign roles on-the-fly
  • +
  • Easy multi-file imports
  • +
  • Complex-content friendly
  • +
+
+
+
+
After (Outfit)
+
+

Key Features

+

Collaborate & edit with co-authors in real time

+
    +
  • Keep everyone in the loop
  • +
  • Assign roles on-the-fly
  • +
  • Easy multi-file imports
  • +
  • Complex-content friendly
  • +
+
+
+
+ + +
Landing Page — Communities & Disclaimer
+
+
+
Before (upgrade-light / upgrade-lights)
+
+

Harvard Data Science Review

+

A Harvard initiative focusing on foundational thinking, research milestones, and educational innovation in data science.

+
+

Start building with PubPub today.

+

PubPub is free to use. A premium hosted version is available for organizations that need additional support.

+
+
+
+
+
After (Outfit)
+
+

Harvard Data Science Review

+

A Harvard initiative focusing on foundational thinking, research milestones, and educational innovation in data science.

+
+

Start building with PubPub today.

+

PubPub is free to use. A premium hosted version is available for organizations that need additional support.

+
+
+
+
+ +
+
+ + + + diff --git a/workers/tasks/export/html.tsx b/workers/tasks/export/html.tsx index afef635099..6f85acbd23 100644 --- a/workers/tasks/export/html.tsx +++ b/workers/tasks/export/html.tsx @@ -17,18 +17,7 @@ import { digestCitation, getAffiliations, getDedupedAffliations } from './util'; const nonExportableNodeTypes = ['discussion']; -// This script is provided by the "cjk-fonts" Web Fonts project that we manage from here: -// https://fonts.adobe.com/my_fonts#web_projects-section -const loadCjkFontsScript = ` -(function(d) { - var config = { - kitId: 'seb8nix', - scriptTimeout: 3000, - async: true - }, - h=d.documentElement,t=setTimeout(function(){h.className=h.className.replace(/\bwf-loading\b/g,"")+" wf-inactive";},config.scriptTimeout),tk=d.createElement("script"),f=false,s=d.getElementsByTagName("script")[0],a;h.className+=" wf-loading";tk.src='https://use.typekit.net/'+config.kitId+'.js';tk.async=true;tk.onload=tk.onreadystatechange=function(){a=this.readyState;if(f||a&&a!="complete"&&a!="loaded")return;f=true;clearTimeout(t);try{Typekit.load(config)}catch(e){}};s.parentNode.insertBefore(tk,s) -})(document); -`; +const fontsHref = 'https://assets.pubpub.org/fonts/8da286c6/fonts.css'; let cachedCss: string | null = null; @@ -294,9 +283,8 @@ export const renderStaticHtml = async (options: RenderStaticHtmlOptions) => { {title} +