/* ===========================================================================
 * Self-hosted webfonts. Replaces the three fonts.googleapis.com /
 * fonts.gstatic.com <link> tags that every page used to carry.
 *
 * WHY: the site is operated from Germany. A request to Google's font CDN
 * hands that visitor's IP address to a US company before the page has drawn
 * anything, which is the best-known GDPR exposure a static site can have.
 * Hosting the faces here removes the request entirely — no third party is
 * contacted to render a page.
 *
 * PATHS: every url() below is relative to THIS FILE, not to the page that
 * links it. That is the whole reason the @font-face block lives in a
 * stylesheet rather than in each page's <style>: `jost-400.woff2` resolves
 * correctly from `/`, from `/faq/` and from `/ar/pricing/` alike, with no
 * depth arithmetic and nothing starting with `/`. A page reaches this file
 * through a depth-correct href that its own build step writes —
 * `{{@rel:assets/fonts/fonts.css}}` in a template, `assets/fonts/fonts.css`
 * in a .dc.html source, which deartifact.py prefixes.
 *
 * ---------------------------------------------------------------------------
 * WHAT THE FACES COVER  (measured 2026-09-14 from the cmap of the shipped
 * files, not from memory — ADR-450)
 * ---------------------------------------------------------------------------
 *
 *   jost-400/500/600.woff2   530 codepoints
 *       Latin, Latin-1, Latin Extended-A, Cyrillic (Russian AND Ukrainian),
 *       punctuation, currency, fractions, a handful of maths signs.
 *       NOT Greek. NOT Vietnamese. NOT any non-Latin, non-Cyrillic script.
 *
 *   jetbrains-mono-400/500.woff2   1372 codepoints
 *       Latin, Latin Extended, Vietnamese, Greek, Cyrillic incl. Ukrainian.
 *       The mono stack needs nothing from this file's script rules: it already
 *       sets every language the site ships that uses a Latin/Greek/Cyrillic
 *       alphabet.
 *
 * The previous version of this note claimed Jost covered "Greek and basic
 * Cyrillic". Both halves were wrong and the wrong half that mattered was
 * Greek: Jost carries exactly four Greek codepoints — Δ U+0394, Ω U+03A9,
 * μ U+03BC, π U+03C0 — and they are maths signs, not letters. Because π and μ
 * are also ordinary letters in Greek words, Jost was supplying one or two
 * glyphs into otherwise-San-Francisco Greek words: 1276 of them across the
 * site, a different typeface for one letter in the middle of a word. The
 * `unicode-range` below is what stops that, and it is the reason these faces
 * carry a range at all.
 *
 * THE RULE, stated once: Jost serves every codepoint it carries, except
 * Greek. U+0370-U+03FF is withheld so that a Greek run is set in one face
 * instead of two. Nothing else on the site uses Δ Ω μ π — checked, zero
 * occurrences outside the Greek locale — so withholding them costs nothing.
 *
 * ---------------------------------------------------------------------------
 * UKRAINIAN — why these files are not upstream Jost
 * ---------------------------------------------------------------------------
 * Upstream Jost has no і, І, ї, Ї, є or Є, and `і` is one of the commonest
 * letters in Ukrainian (924 occurrences on this site). Every Ukrainian word
 * containing one was being set in two faces at once. There is no fuller Jost
 * on the build machine and no network to fetch one, so the shipped files were
 * repaired in place (tools/build-ukrainian-jost.py):
 *
 *     і І ї Ї   no glyph added. Unicode disunified these from Latin i I ï Ï
 *               for encoding, not for shape, so the cmap points the Cyrillic
 *               codepoints at the Latin glyphs already in the file. 0 bytes.
 *     є Є       the horizontal mirror of э Э, which the file already had.
 *               Jost is monolinear, so a mirror inverts no stress.
 *
 * The rule that governs this repair is DERIVE, NEVER DRAW: every added glyph
 * is made of contours Jost's own designer drew. That is why ґ and Ґ are NOT
 * here — ghe-with-upturn needs new geometry, and a drawn one is not Jost's.
 * They appear nowhere in the site's copy; `tools/font-gate.py` fails the build
 * if that ever changes. SIL OFL 1.1 permits the modification and Jost declares
 * no Reserved Font Name, so the family name is unchanged.
 *
 * Cost of the repair: +344 bytes across the three weights (243 968 -> 244 312
 * for all five faces, 238.2 KB -> 238.6 KB). Four of the six letters cost
 * nothing at all, being cmap entries pointing at glyphs already present.
 *
 * ---------------------------------------------------------------------------
 * EVERY OTHER SCRIPT — deliberately the system face, and why not a webfont
 * ---------------------------------------------------------------------------
 * Eighteen of the forty-four languages are written in a script neither family
 * carries. Self-hosting faces for them would cost megabytes to spare a visitor
 * a face they already own: this is a macOS app's website, and macOS ships a
 * good face for every one of these scripts. So the fallback is the answer —
 * but a fallback that is *chosen* rather than merely arrived at.
 *
 * What it resolves to was measured in Chromium, per locale, on the real pages
 * (tools/font-gate.py --report):
 *
 *   ja        Hiragino Sans          hi mr    Kohinoor Devanagari
 *   ko        Apple SD Gothic Neo    bn       Kohinoor Bangla
 *   zh-Hans   PingFang SC            gu       Kohinoor Gujarati
 *   zh-Hant   PingFang TC            pa       Mukta Mahee
 *   th        Thonburi               kn       Noto Sans Kannada
 *   ar ur     Geeza Pro              ml       Malayalam Sangam MN
 *   el        San Francisco          or       Noto Sans Oriya
 *   he        Arial Hebrew (below)   ta       Tamil Sangam MN
 *                                    te       Kohinoor Telugu
 *
 * Only ONE of those is named in CSS, and the reason the other seventeen are
 * not is worth writing down, because naming them looks like the tidier option
 * and is in fact a regression:
 *
 *   1. `unicode-range` cannot tell languages apart, only scripts. Han is one
 *      block shared by ja, zh-Hans and zh-Hant, which want three different
 *      regional faces; the Arabic block is shared by ar and ur, which want
 *      Geeza Pro and Nastaliq. Pinning a face per *script* would force one
 *      language's glyph shapes onto another's. The browser picks per
 *      *language*, using the page's lang attribute, and is strictly better
 *      informed than this file can be.
 *   2. Pinning with local() loses weight matching. The headline is weight 600
 *      and the system is already resolving it to real semibolds — the measured
 *      faces include "Noto Sans Kannada SemiBold" and "MuktaMahee SemiBold".
 *      A local() src names one style; the 600 would come back regular.
 *   3. macOS system faces refuse to bind through local() at all. SF Pro,
 *      SF Hebrew, SF Arabic and Geeza Pro were each probed in Chromium and
 *      none of them resolves. Naming them would be a comment, not a rule.
 *
 * So: seventeen scripts are documented here and enforced by the gate, which
 * fails if a headline stops resolving to the face this table names. Hebrew is
 * the one exception — see below.
 * ======================================================================== */

/* --- Jost: the house face, Latin and Cyrillic. Greek deliberately withheld;
 *     see THE RULE above. The ranges are the shipped cmap, generated from the
 *     files themselves, minus U+0394 / U+03A9 / U+03BC-03C0. ------------- */

@font-face {
  font-family: 'Jost';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("jost-400.woff2") format("woff2");
  unicode-range: U+0000-000D, U+0020-007E, U+00A0-017E, U+0192, U+0212-021B,
                 U+0237, U+02C6-02C7, U+02D8-02DD, U+0300-0312, U+0326-0328,
                 U+0400-045E, U+1E80-1E89, U+1E9E, U+1EF2-1EF3, U+2010-2044,
                 U+2070-2089, U+20AC, U+20BD, U+2122, U+2150-215E, U+2202-222B,
                 U+2248, U+2260-2265, U+25CA, U+FF10-FF19;
}

@font-face {
  font-family: 'Jost';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("jost-500.woff2") format("woff2");
  unicode-range: U+0000-000D, U+0020-007E, U+00A0-017E, U+0192, U+0212-021B,
                 U+0237, U+02C6-02C7, U+02D8-02DD, U+0300-0312, U+0326-0328,
                 U+0400-045E, U+1E80-1E89, U+1E9E, U+1EF2-1EF3, U+2010-2044,
                 U+2070-2089, U+20AC, U+20BD, U+2122, U+2150-215E, U+2202-222B,
                 U+2248, U+2260-2265, U+25CA, U+FF10-FF19;
}

@font-face {
  font-family: 'Jost';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("jost-600.woff2") format("woff2");
  unicode-range: U+0000-000D, U+0020-007E, U+00A0-017E, U+0192, U+0212-021B,
                 U+0237, U+02C6-02C7, U+02D8-02DD, U+0300-0312, U+0326-0328,
                 U+0400-045E, U+1E80-1E89, U+1E9E, U+1EF2-1EF3, U+2010-2044,
                 U+2070-2089, U+20AC, U+20BD, U+2122, U+2150-215E, U+2202-222B,
                 U+2248, U+2260-2265, U+25CA, U+FF10-FF19;
}

/* --- Hebrew: the one script named in CSS. -----------------------------------
 * Left alone, Hebrew walks the page stack (-apple-system, BlinkMacSystemFont,
 * 'Helvetica Neue', sans-serif) and lands on Lucida Grande, which carries no
 * bold — so a weight-600 Hebrew headline was a synthesised one. Arial Hebrew
 * has a real Bold, binds through local(), and sits better beside a geometric
 * face. It is declared under the family name 'Jost' so that the stacks already
 * written into the pages pick it up with no change to any page.
 * Falls through to the previous behaviour wherever it is not installed. */

/* These declare the SAME three discrete weights as the Jost faces above, and
 * never a weight range. A range here (font-weight: 500 900) silently breaks
 * every Latin headline on the site: Chromium picks the face for family+weight
 * FIRST and consults unicode-range only afterwards, so a range that contained
 * 600 won the weight match for Latin text, failed the range test, and dropped
 * the whole family — every weight-600 headline in all 44 locales fell to
 * -apple-system. Matching weights exactly leaves unicode-range as the only
 * thing that differs, which is what makes the split work. */

@font-face {
  font-family: 'Jost';
  font-style: normal;
  font-weight: 400;
  src: local("Arial Hebrew"), local("ArialHB");
  unicode-range: U+0590-05FF, U+FB1D-FB4F;
}

@font-face {
  font-family: 'Jost';
  font-style: normal;
  font-weight: 500;
  src: local("Arial Hebrew Bold"), local("ArialHB-Bold"), local("Arial Hebrew");
  unicode-range: U+0590-05FF, U+FB1D-FB4F;
}

@font-face {
  font-family: 'Jost';
  font-style: normal;
  font-weight: 600;
  src: local("Arial Hebrew Bold"), local("ArialHB-Bold"), local("Arial Hebrew");
  unicode-range: U+0590-05FF, U+FB1D-FB4F;
}

/* --- Vietnamese: the one language that has to leave the house face. ---------
 * Vietnamese is written in Latin, so Jost sets most of it — but not the
 * precomposed vowel+tone letters (ả ắ ế ợ …), 92 of which are missing. The
 * result was two faces inside almost every content word: `Sắp`, `xếp.`,
 * `Hợp`. Unlike Greek this cannot be fixed with unicode-range, because the
 * broken runs are *Latin*; withholding them would break all 25 other Latin
 * languages too. It cannot be fixed by repairing the font either — the rule
 * above is derive-never-draw, and 92 tone-marked vowels are type design, not
 * derivation. Montserrat (OFL, on the build machine, covers Vietnamese) was
 * considered and rejected: unverifiable provenance for a shipped binary, and a
 * second display family for one locale.
 *
 * So Vietnamese gets one face for the whole page instead of two per word. This
 * is the trade the owner named: a headline in San Francisco is not a disaster;
 * a word in two faces is. */

:lang(vi) {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue',
               Helvetica, sans-serif;
}

:lang(vi) code, :lang(vi) kbd, :lang(vi) samp, :lang(vi) pre,
:lang(vi) [data-mono] {
  font-family: 'JetBrains Mono', ui-monospace, monospace;  /* covers vi fully */
}

/* --- JetBrains Mono: code, tags, numerals. No range needed — it carries every
 *     script the site sets in it, Vietnamese and Ukrainian included. ------- */

@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("jetbrains-mono-400.woff2") format("woff2");
}

@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("jetbrains-mono-500.woff2") format("woff2");
}

/* SOURCES (both SIL OFL 1.1; the licences sit beside this file and must ship
 * with it):
 *   Jost            google/fonts ofl/jost/Jost[wght].ttf, instanced at
 *                   400/500/600, compressed to woff2, then repaired for
 *                   Ukrainian as described above.          -> Jost-OFL.txt
 *   JetBrains Mono  JetBrains/JetBrainsMono fonts/webfonts,
 *                   upstream woff2, byte-for-byte.  -> JetBrainsMono-OFL.txt
 *
 * font-display: swap matches the `&display=swap` the Google URL carried, so
 * text is painted in the fallback immediately and never invisible. The two
 * local() faces carry no font-display: there is nothing to download and
 * nothing to swap. */
