/* New Computer Modern (NCM) webfont setup — Antonis Tsolomitis's successor to
   Computer Modern Unicode, distributed on CTAN (fonts/newcomputermodern) under
   the GUST Font License (see "GUST Font License.txt" beside the font files).

   Replaces the old CMU cmun*.ttf set. Two things NCM buys us over CMU: real
   OpenType features — `smcp`/`c2sc` small caps and `onum` oldstyle figures,
   none of which CMU's TTFs carried, so `font-variant-caps` no longer has to be
   synthesized by the browser — and a much wider, better-hinted glyph set.

   Shipped as woff2 rather than the upstream .otf: the CFF outlines compress to
   roughly half (e.g. NewCM10-Regular 701 KB otf -> 325 KB woff2), and every
   browser that renders this book supports it. Files live in src/fonts/ and
   mdBook copies them next to this stylesheet.

   IMPORTANT — do not regenerate these from the upstream .otf by straight
   conversion. NewCM10-Regular.otf and NewCM10-Italic.otf as published on CTAN
   contain malformed CFF charstrings in the Phonetic Extensions block
   (U+1D4D-U+1D5D): glyphs such as uni1D50 open with a `cntrmask` operator with
   zero preceding stem hints and an empty mask. OTS — the font sanitiser in both
   Chrome and Firefox — rejects the file outright with

       OTS parsing error: CFF : Failed validating CharStrings INDEX

   and the browser then silently falls back to Times for ALL body text and
   italics. (The Bold and Book cuts declare `hstemhm` properly and are fine,
   which makes the breakage easy to miss: headings look right.) These files are
   therefore rebuilt with that range dropped:

       pyftsubset NewCM10-Regular.otf --unicodes-file=<all cmap codepoints
         minus U+1D4D-U+1D5D> --layout-features='*' --glyph-names
         --flavor=woff2 --output-file=NewCM10-Regular.woff2

   `--layout-features='*'` is what keeps smcp/c2sc/onum alive; pyftsubset's
   default feature set would drop them. After regenerating, verify in a browser
   that the face actually loads — a rejected font is invisible in the page,
   it just quietly renders as Times.

   Files expected in the SAME folder as this CSS:
   NewCM10-{Regular,Italic,Bold,BoldItalic}.woff2
   NewCMSans10-{Regular,Oblique,Bold,BoldOblique}.woff2
   NewCMMono10-{Regular,Italic,Bold,BoldOblique}.woff2
*/

/* ===== New Computer Modern (serif / roman) ===== */
@font-face {
  font-family: "New Computer Modern";
  font-style: normal;
  font-weight: 400;
  src: url("NewCM10-Regular.woff2") format("woff2");
  font-display: swap;
}
@font-face {
  font-family: "New Computer Modern";
  font-style: italic;
  font-weight: 400;
  src: url("NewCM10-Italic.woff2") format("woff2"); /* true italic, not slanted */
  font-display: swap;
}
@font-face {
  font-family: "New Computer Modern";
  font-style: normal;
  font-weight: 700;
  src: url("NewCM10-Bold.woff2") format("woff2");
  font-display: swap;
}
@font-face {
  font-family: "New Computer Modern";
  font-style: italic;
  font-weight: 700;
  src: url("NewCM10-BoldItalic.woff2") format("woff2");
  font-display: swap;
}
/* NCM's serif has no separate slanted cut (unlike CMU, where these pointed at
   the Concrete italic), so an `oblique` request lands on the true italic. */
@font-face {
  font-family: "New Computer Modern";
  font-style: oblique;
  font-weight: 400;
  src: url("NewCM10-Italic.woff2") format("woff2");
  font-display: swap;
}
@font-face {
  font-family: "New Computer Modern";
  font-style: oblique;
  font-weight: 700;
  src: url("NewCM10-BoldItalic.woff2") format("woff2");
  font-display: swap;
}

/* If mdBook asks for 300/600/800, alias to nearest real weight. NCM also ships
   a heavier "Book" optical cut meant for screens; swapping the 400 rules to
   NewCM10-Book* is the one-line way to darken the page if the text ever reads
   too thin. */
@font-face {
  font-family: "New Computer Modern";
  font-style: normal;
  font-weight: 300;
  src: url("NewCM10-Regular.woff2") format("woff2");
  font-display: swap;
}
@font-face {
  font-family: "New Computer Modern";
  font-style: italic;
  font-weight: 300;
  src: url("NewCM10-Italic.woff2") format("woff2");
  font-display: swap;
}
@font-face {
  font-family: "New Computer Modern";
  font-style: normal;
  font-weight: 600;
  src: url("NewCM10-Bold.woff2") format("woff2");
  font-display: swap;
}
@font-face {
  font-family: "New Computer Modern";
  font-style: italic;
  font-weight: 600;
  src: url("NewCM10-BoldItalic.woff2") format("woff2");
  font-display: swap;
}
@font-face {
  font-family: "New Computer Modern";
  font-style: normal;
  font-weight: 800;
  src: url("NewCM10-Bold.woff2") format("woff2");
  font-display: swap;
}
@font-face {
  font-family: "New Computer Modern";
  font-style: italic;
  font-weight: 800;
  src: url("NewCM10-BoldItalic.woff2") format("woff2");
  font-display: swap;
}

/* ===== New Computer Modern Sans (optional, for UI bits) =====
   NCM's sans has no light cut, so the old CMU 300 (cmunsl) maps to Regular. */
@font-face {
  font-family: "New Computer Modern Sans";
  font-style: normal;
  font-weight: 300;
  src: url("NewCMSans10-Regular.woff2") format("woff2");
  font-display: swap;
}
@font-face {
  font-family: "New Computer Modern Sans";
  font-style: normal;
  font-weight: 400;
  src: url("NewCMSans10-Regular.woff2") format("woff2");
  font-display: swap;
}
/* The sans is slanted rather than truly italic; both requests get that cut. */
@font-face {
  font-family: "New Computer Modern Sans";
  font-style: italic;
  font-weight: 400;
  src: url("NewCMSans10-Oblique.woff2") format("woff2");
  font-display: swap;
}
@font-face {
  font-family: "New Computer Modern Sans";
  font-style: oblique;
  font-weight: 400;
  src: url("NewCMSans10-Oblique.woff2") format("woff2");
  font-display: swap;
}
@font-face {
  font-family: "New Computer Modern Sans";
  font-style: normal;
  font-weight: 700;
  src: url("NewCMSans10-Bold.woff2") format("woff2");
  font-display: swap;
}
@font-face {
  font-family: "New Computer Modern Sans";
  font-style: italic;
  font-weight: 700;
  src: url("NewCMSans10-BoldOblique.woff2") format("woff2");
  font-display: swap;
}
@font-face {
  font-family: "New Computer Modern Sans";
  font-style: oblique;
  font-weight: 700;
  src: url("NewCMSans10-BoldOblique.woff2") format("woff2");
  font-display: swap;
}

/* ===== New Computer Modern Mono (typewriter) =====
   NCM names the bold slanted cut BoldOblique; there is no BoldItalic. */
@font-face {
  font-family: "New Computer Modern Mono";
  font-style: normal;
  font-weight: 400;
  src: url("NewCMMono10-Regular.woff2") format("woff2");
  font-display: swap;
}
@font-face {
  font-family: "New Computer Modern Mono";
  font-style: italic;
  font-weight: 400;
  src: url("NewCMMono10-Italic.woff2") format("woff2");
  font-display: swap;
}
@font-face {
  font-family: "New Computer Modern Mono";
  font-style: normal;
  font-weight: 700;
  src: url("NewCMMono10-Bold.woff2") format("woff2");
  font-display: swap;
}
@font-face {
  font-family: "New Computer Modern Mono";
  font-style: italic;
  font-weight: 700;
  src: url("NewCMMono10-BoldOblique.woff2") format("woff2");
  font-display: swap;
}

/* ===== SITP Double Struck (blackboard bold) =====
   STIX Two Math's double-struck letters, outlined throughout like the ℝ of a
   Times-set calculus text, in place of KaTeX_AMS's msbm where only the stem is
   doubled. The cmap is remapped so plain ASCII A-Z/a-z/0-9 draw the
   double-struck glyphs, which is what lets KaTeX's `.mathbb` spans (holding a
   literal "R") use it directly; see preprocessors/gen-double-struck-font.py
   and the `.mathbb` rule in custom.css. Renamed from STIX per its OFL
   ("STIX Two OFL.txt").

   size-adjust lifts STIX's 0.657em cap height to Computer Modern's 0.683em so
   ℝ stands as tall as the R of the surrounding text. */
@font-face {
  font-family: "SITP Double Struck";
  font-style: normal;
  font-weight: 400;
  src: url("SITPDoubleStruck-Regular.woff2") format("woff2");
  size-adjust: 104%;
  font-display: swap;
}

/* ===== Goudy Initialen drop caps =====
   Frederic W. Goudy's floriated initials (Lanston Monotype No. 296, c. 1918):
   a roman capital on a vine-and-leaf ground inside a ruled square, after the
   woodcut initials of 15th/16th-century printing. Digitized by Dieter Steffmann
   and distributed on CTAN (fonts/initials) under the LPPL.

   Upstream ships only Type 1 (GoudyIn.pfb), which browsers can't load, so each
   capital was converted to a CFF woff2 of its own: outlines copied through
   fontTools (t1Lib glyph -> T2CharStringPen -> FontBuilder), no other changes,
   and checked with OTS (`ots.sanitize`, the sanitizer Chrome and Firefox run).
   Every glyph is the same 800x800 box on the baseline with an 840 advance, and
   the vertical metrics are set to exactly that box (ascent 800, descent 0) so
   the dropcap geometry in custom.css can be computed rather than eyeballed.

   26 single-glyph files, one per capital. unicode-range makes the browser
   fetch ONLY the letter a page actually starts with. Used by the opt-in
   `.dropcap` wrapper class (see custom.css). */
@font-face {
  font-family: "Goudy Initialen";
  font-style: normal;
  font-weight: 400;
  src: url("GoudyInitialen-A.woff2") format("woff2");
  unicode-range: U+0041;
  font-display: swap;
}
@font-face {
  font-family: "Goudy Initialen";
  font-style: normal;
  font-weight: 400;
  src: url("GoudyInitialen-B.woff2") format("woff2");
  unicode-range: U+0042;
  font-display: swap;
}
@font-face {
  font-family: "Goudy Initialen";
  font-style: normal;
  font-weight: 400;
  src: url("GoudyInitialen-C.woff2") format("woff2");
  unicode-range: U+0043;
  font-display: swap;
}
@font-face {
  font-family: "Goudy Initialen";
  font-style: normal;
  font-weight: 400;
  src: url("GoudyInitialen-D.woff2") format("woff2");
  unicode-range: U+0044;
  font-display: swap;
}
@font-face {
  font-family: "Goudy Initialen";
  font-style: normal;
  font-weight: 400;
  src: url("GoudyInitialen-E.woff2") format("woff2");
  unicode-range: U+0045;
  font-display: swap;
}
@font-face {
  font-family: "Goudy Initialen";
  font-style: normal;
  font-weight: 400;
  src: url("GoudyInitialen-F.woff2") format("woff2");
  unicode-range: U+0046;
  font-display: swap;
}
@font-face {
  font-family: "Goudy Initialen";
  font-style: normal;
  font-weight: 400;
  src: url("GoudyInitialen-G.woff2") format("woff2");
  unicode-range: U+0047;
  font-display: swap;
}
@font-face {
  font-family: "Goudy Initialen";
  font-style: normal;
  font-weight: 400;
  src: url("GoudyInitialen-H.woff2") format("woff2");
  unicode-range: U+0048;
  font-display: swap;
}
@font-face {
  font-family: "Goudy Initialen";
  font-style: normal;
  font-weight: 400;
  src: url("GoudyInitialen-I.woff2") format("woff2");
  unicode-range: U+0049;
  font-display: swap;
}
@font-face {
  font-family: "Goudy Initialen";
  font-style: normal;
  font-weight: 400;
  src: url("GoudyInitialen-J.woff2") format("woff2");
  unicode-range: U+004A;
  font-display: swap;
}
@font-face {
  font-family: "Goudy Initialen";
  font-style: normal;
  font-weight: 400;
  src: url("GoudyInitialen-K.woff2") format("woff2");
  unicode-range: U+004B;
  font-display: swap;
}
@font-face {
  font-family: "Goudy Initialen";
  font-style: normal;
  font-weight: 400;
  src: url("GoudyInitialen-L.woff2") format("woff2");
  unicode-range: U+004C;
  font-display: swap;
}
@font-face {
  font-family: "Goudy Initialen";
  font-style: normal;
  font-weight: 400;
  src: url("GoudyInitialen-M.woff2") format("woff2");
  unicode-range: U+004D;
  font-display: swap;
}
@font-face {
  font-family: "Goudy Initialen";
  font-style: normal;
  font-weight: 400;
  src: url("GoudyInitialen-N.woff2") format("woff2");
  unicode-range: U+004E;
  font-display: swap;
}
@font-face {
  font-family: "Goudy Initialen";
  font-style: normal;
  font-weight: 400;
  src: url("GoudyInitialen-O.woff2") format("woff2");
  unicode-range: U+004F;
  font-display: swap;
}
@font-face {
  font-family: "Goudy Initialen";
  font-style: normal;
  font-weight: 400;
  src: url("GoudyInitialen-P.woff2") format("woff2");
  unicode-range: U+0050;
  font-display: swap;
}
@font-face {
  font-family: "Goudy Initialen";
  font-style: normal;
  font-weight: 400;
  src: url("GoudyInitialen-Q.woff2") format("woff2");
  unicode-range: U+0051;
  font-display: swap;
}
@font-face {
  font-family: "Goudy Initialen";
  font-style: normal;
  font-weight: 400;
  src: url("GoudyInitialen-R.woff2") format("woff2");
  unicode-range: U+0052;
  font-display: swap;
}
@font-face {
  font-family: "Goudy Initialen";
  font-style: normal;
  font-weight: 400;
  src: url("GoudyInitialen-S.woff2") format("woff2");
  unicode-range: U+0053;
  font-display: swap;
}
@font-face {
  font-family: "Goudy Initialen";
  font-style: normal;
  font-weight: 400;
  src: url("GoudyInitialen-T.woff2") format("woff2");
  unicode-range: U+0054;
  font-display: swap;
}
@font-face {
  font-family: "Goudy Initialen";
  font-style: normal;
  font-weight: 400;
  src: url("GoudyInitialen-U.woff2") format("woff2");
  unicode-range: U+0055;
  font-display: swap;
}
@font-face {
  font-family: "Goudy Initialen";
  font-style: normal;
  font-weight: 400;
  src: url("GoudyInitialen-V.woff2") format("woff2");
  unicode-range: U+0056;
  font-display: swap;
}
@font-face {
  font-family: "Goudy Initialen";
  font-style: normal;
  font-weight: 400;
  src: url("GoudyInitialen-W.woff2") format("woff2");
  unicode-range: U+0057;
  font-display: swap;
}
@font-face {
  font-family: "Goudy Initialen";
  font-style: normal;
  font-weight: 400;
  src: url("GoudyInitialen-X.woff2") format("woff2");
  unicode-range: U+0058;
  font-display: swap;
}
@font-face {
  font-family: "Goudy Initialen";
  font-style: normal;
  font-weight: 400;
  src: url("GoudyInitialen-Y.woff2") format("woff2");
  unicode-range: U+0059;
  font-display: swap;
}
@font-face {
  font-family: "Goudy Initialen";
  font-style: normal;
  font-weight: 400;
  src: url("GoudyInitialen-Z.woff2") format("woff2");
  unicode-range: U+005A;
  font-display: swap;
}
