Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,5 @@ tsconfig.tsbuildinfo

infra/pgdata/

tmp
tmp
details.md
49 changes: 49 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/<hash>/`. 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 `<link>` 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/<hash>/`). 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/<hash>/`
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:
Expand Down
10 changes: 7 additions & 3 deletions client/components/PubPreview/pubPreview.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -156,6 +157,7 @@
.pub-title {
font-weight: 400;
font-size: 22px;
letter-spacing: 0px;
line-height: 1.33 !important;
}
}
Expand Down Expand Up @@ -197,6 +199,7 @@
.pub-title {
font-weight: 400;
font-size: 18px;
letter-spacing: 0px;
line-height: 1.33 !important;
}
}
Expand All @@ -213,7 +216,7 @@
.title-wrapper {
padding-bottom: 5px;
font-family:
multi-display,
'Source Sans 3',
-apple-system,
'BlinkMacSystemFont',
'Segoe UI',
Expand All @@ -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;
Expand Down
35 changes: 19 additions & 16 deletions client/containers/Landing/landing.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand All @@ -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;
}
}
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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;
}
}
Expand Down
40 changes: 22 additions & 18 deletions client/containers/Pub/PubDocument/pubBody.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 <strong> 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,
Expand All @@ -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;
}

Expand Down
12 changes: 7 additions & 5 deletions client/containers/Pub/PubHeader/pubHeader.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
Expand Down
1 change: 0 additions & 1 deletion client/styles/base.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down
12 changes: 4 additions & 8 deletions client/styles/variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -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;

Expand Down
Loading
Loading