/* Socialhose brand typefaces — self-hosted.
 *
 * Univers (display/UI) + Melior (body) are the brand pair for marketing pages
 * and EDITORIAL email (newsletters, meetings, content downloads). Berkeley Mono
 * joins them for code — the same face the platform app runs on, so a curl
 * example on a landing page and the same command in the app read identically.
 * In marketing surfaces, prose never uses it.
 *
 * PRODUCT emails are the exception: alert and system/transactional templates
 * (templates/emails/tui/base.html and everything extending it) are set
 * entirely in Berkeley Mono — they are the app speaking, so they carry the
 * TUI grammar, not the marketing pair. Those templates declare their own
 * @font-face against https://socialhose.net/static/fonts/BerkeleyMono-*.woff2
 * and do not link this stylesheet.
 *
 * Charter is NOT a brand face any more. It stays declared purely as the serif
 * coverage fallback: Melior is Latin-only, and we ingest mentions in every
 * script, so a Greek or Cyrillic mention in a digest email picks up Charter
 * glyph-by-glyph. Every serif stack is therefore 'Melior', 'Charter', Georgia —
 * never Charter alone. (CJK is beyond both faces.)
 *
 * IBM Plex Sans Thai and IBM Plex Sans Arabic join them at the bottom of this
 * file. Neither is a brand face either — they exist because the marketing site
 * is published in Thai (/th/) and Arabic (/ar/), and no brand face covers a
 * single Thai or Arabic letter. Both are unicode-range'd to their own script,
 * so each draws that script and nothing else.
 *
 * Loaded by:
 *   - marketing pages via {% static 'css/brand-fonts.css' %}
 *   - email templates via the absolute https://socialhose.net/... URL (a mail
 *     client has no notion of our dev/staging hosts)
 *
 * The Latin faces are subset to Latin/Latin-Ext; characters outside that range
 * fall back per-character, which is what we want for user content in a digest
 * email. Thai and Arabic are the two scripts that fall back to a face we ship
 * rather than to whatever the OS happens to have.
 *
 * Adding a script here is two edits, and missing the second is silent: the
 * @font-face block at the bottom, and the face's name in every stack that
 * already lists its siblings (`grep "IBM Plex Sans Thai"`). A face declared but
 * absent from the stacks is downloaded by nobody and changes nothing.
 */

@font-face {
  font-family: 'Univers';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url("../fonts/Univers-Light.dcb9d421e774.woff2") format('woff2');
}
@font-face {
  font-family: 'Univers';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/Univers-Regular.6d5b5d3ca451.woff2") format('woff2');
}
@font-face {
  font-family: 'Univers';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/Univers-Italic.5fcdc503babf.woff2") format('woff2');
}
@font-face {
  font-family: 'Univers';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/Univers-Medium.929a2757d718.woff2") format('woff2');
}
@font-face {
  font-family: 'Univers';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/Univers-Bold.81ec8da72280.woff2") format('woff2');
}
@font-face {
  font-family: 'Univers';
  font-style: italic;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/Univers-BoldItalic.7917036e0129.woff2") format('woff2');
}

/* Melior (LT Std) — body. Zapf drew its bowls as superellipses rather than
 * ovals, which is why it sits under Berkeley Mono the way a conventional serif
 * doesn't; the two share a geometry.
 *
 * size-adjust: 103.4% makes the swap off Charter size-neutral. Melior's
 * x-height is 46.5% of the em against Charter's 48.1% (481/465 = 1.034), so at
 * an unchanged font-size it reads slightly small. Scaling the em restores the
 * previous apparent text size without touching a single font-size rule — the
 * same technique Berkeley uses at 106.18%.
 */
@font-face {
  font-family: 'Melior';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  size-adjust: 103.4%;
  src: url("../fonts/Melior-Roman.6cfd3f3470aa.woff2") format('woff2');
}
@font-face {
  font-family: 'Melior';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  size-adjust: 103.4%;
  src: url("../fonts/Melior-Italic.a513dfd2fca1.woff2") format('woff2');
}
@font-face {
  font-family: 'Melior';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  size-adjust: 103.4%;
  src: url("../fonts/Melior-Bold.54243b8f55da.woff2") format('woff2');
}
@font-face {
  font-family: 'Melior';
  font-style: italic;
  font-weight: 700;
  font-display: swap;
  size-adjust: 103.4%;
  src: url("../fonts/Melior-BoldItalic.01968c125554.woff2") format('woff2');
}

/* Charter — coverage fallback only, never a brand face. Carries the Cyrillic and
 * Greek that Melior lacks, so a mention in either script still renders. It does
 * NOT cover Thai: Charter maps exactly one codepoint in the Thai block, ฿ (baht),
 * which Latin faces carry as a currency symbol. Thai is handled by IBM Plex Sans
 * Thai at the bottom of this file.
 *
 * Deliberately NOT size-adjusted, and it happens to need no adjustment: Melior
 * scaled by 1.034 lands an x-height of 0.481 em, which is exactly Charter's
 * natural x-height. A Greek or Cyrillic run sits optically level with the Latin
 * beside it for free. If the Melior size-adjust above ever changes, recheck this.
 */
@font-face {
  font-family: 'Charter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/Charter-Roman.d14ccef9dd4b.woff2") format('woff2');
}
@font-face {
  font-family: 'Charter';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/Charter-Italic.ddfe344b6b4d.woff2") format('woff2');
}
@font-face {
  font-family: 'Charter';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/Charter-Bold.4f13cfc3eb27.woff2") format('woff2');
}
@font-face {
  font-family: 'Charter';
  font-style: italic;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/Charter-BoldItalic.90226f335bec.woff2") format('woff2');
}

/* Berkeley Mono (TX-02) — code only. size-adjust matches the platform app's
 * faces (frontend/src/styles/theme.css): Berkeley's x-height is 51.8% of the em,
 * so at an unchanged font-size it reads noticeably small. The same 106.18% here
 * keeps one Berkeley across app and marketing rather than two apparent sizes. */
@font-face {
  font-family: 'Berkeley Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  size-adjust: 106.18%;
  src: url("../fonts/BerkeleyMono-Regular.152c5a819cd3.woff2") format('woff2');
}
@font-face {
  font-family: 'Berkeley Mono';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  size-adjust: 106.18%;
  src: url("../fonts/BerkeleyMono-Bold.e2a60c4e1c05.woff2") format('woff2');
}

/* IBM Plex Sans Thai (Thai), self-hosted, SIL OFL 1.1.
 *
 * Thai-only subsets, so this face never touches Latin: unicode-range keeps it to
 * the Thai block, and Univers/Melior/Berkeley continue to draw everything else in
 * a mixed line. That is what lets a single family ride in every stack below
 * without restyling a single English page.
 *
 * These are the same Fontsource WOFF2 subsets the React app loads
 * (frontend/src/assets/fonts/), so Thai is one typeface across app, marketing,
 * PDF exports and share cards rather than three near-misses.
 *
 * size-adjust: 110%. Thai has no capitals and no ascenders, so a Thai line's
 * whole silhouette is the consonant body (ka/tha top out at 0.558 em here) while
 * a Latin line keeps reaching to cap height. Matching x-heights therefore sets
 * Thai too small -- the body wants to land between Latin x-height and cap height,
 * which is where Thai type conventionally sits against Latin. Measured from
 * assets/fonts/ at 1000 upm:
 *
 *              x-height   cap-height   midpoint   implied size-adjust
 *   Univers      50.5%       72.3%       61.4%          112%
 *   Melior*      48.1%       71.9%       60.0%          109%
 *   (* after Melior's own 103.4% size-adjust above, i.e. as actually rendered)
 *
 * One @font-face carries one size-adjust, and marketing needs Thai in both the
 * Univers UI stack and the Melior body stack. The two targets are under 3% apart
 * -- below the point where the mismatch is legible -- so 110% splits them. It is
 * also exactly the value frontend/src/styles/theme.css uses, which is the more
 * valuable property: Thai is metrically identical in the app and on the site.
 * (Rejected: two aliased families at 112%/109%. Real precision, but it doubles
 * these declarations and makes every stack in marketing.css context-dependent.)
 *
 * No ascent-override/descent-override, unlike the app. theme.css clamps Plex
 * Thai's line box (111.6/53.4) onto Berkeley's (95.6/24.5) to hold the terminal
 * grid, and documents that as a deliberate, non-free trade: Thai stacks, so a
 * tone mark sitting above an upper vowel via mkmk paints outside the clamped box.
 * Marketing has no grid to hold, so the natural line box stays and stacked marks
 * get the room they need. A Thai marketing line is consequently a little taller
 * than the Latin one. That is correct, not a regression -- do not "fix" it by
 * adding the overrides back.
 *
 * Weights 400/500/700 match the Univers weights in use, so nothing synthesises.
 * Files keep their upstream Fontsource names so re-fetching is unambiguous.
 */
@font-face {
  font-family: 'IBM Plex Sans Thai';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  size-adjust: 110%;
  src: url("../fonts/ibm-plex-sans-thai-thai-400-normal.e72e639292ac.woff2") format('woff2');
  unicode-range: U+0E01-0E5B, U+200B-200D;
}
@font-face {
  font-family: 'IBM Plex Sans Thai';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  size-adjust: 110%;
  src: url("../fonts/ibm-plex-sans-thai-thai-500-normal.c40569bb727d.woff2") format('woff2');
  unicode-range: U+0E01-0E5B, U+200B-200D;
}
@font-face {
  font-family: 'IBM Plex Sans Thai';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  size-adjust: 110%;
  src: url("../fonts/ibm-plex-sans-thai-thai-700-normal.029db11954e6.woff2") format('woff2');
  unicode-range: U+0E01-0E5B, U+200B-200D;
}

/* IBM Plex Sans Arabic (Arabic), self-hosted, SIL OFL 1.1.
 *
 * Same job as the Thai face above and declared the same way: Arabic-only
 * subsets, unicode-range'd so it draws Arabic and nothing else while
 * Univers/Melior/Berkeley keep every Latin glyph in a mixed line. Added when
 * the marketing site was published in Arabic at /ar/ -- neither brand face
 * maps a single Arabic codepoint, so without this every /ar/ page renders in
 * whatever the OS happens to have.
 *
 * Note what the range does NOT include. The upstream subset also carries
 * U+0020 (space) and U+00A0 (no-break space), and listing those would hand
 * this face the spaces in *English* pages -- word-spacing on the whole site
 * decided by a font that exists to draw Arabic. Only the Arabic blocks and the
 * two joiners are listed.
 *
 * Chosen to match the Thai decision -- one superfamily for the site's non-Latin
 * scripts -- and it is deliberately not the Arabic face used elsewhere in the
 * repo. There is no single one to match: the app sets Arabic in Kawkab Mono
 * because it has a monospace grid to hold, and share cards render it in Noto
 * Naskh / Tajawal because Pillow draws from the TTFs in assets/fonts. Those two
 * are incidental mention text; this is site chrome. See assets/fonts/FONTS.md.
 *
 * size-adjust: 107%. Arabic and Latin have no shared vertical anchor -- Arabic
 * has nothing that is an x-height and nothing that is a capital -- so the two
 * obvious targets disagree violently. Measured at 1000 upm:
 *
 *                          Plex Arabic   target        implied size-adjust
 *   alif/lam/kaf top          74.0%      Latin ascender      ~101%
 *   baa tooth (base body)     38.0%      Latin x-height      ~130%
 *
 * The gap is the whole problem: Arabic's body-to-alif ratio is 0.51 where
 * Latin's x-height-to-cap is 0.70, so anchoring on the tall strokes leaves the
 * body far too small to read, and anchoring on the body leaves alif towering
 * over the Latin beside it. 107% is the midpoint of the two optical targets
 * theme.css already settled on for Kawkab in the app -- alif a hair above the
 * Latin ascender, tooth height around 0.85 of the Latin x-height:
 *
 *              x-height   ascender    at 107%: alif 79.2%, tooth 40.7%
 *   Univers      50.5%      72.3%      alif clears it, tooth/x = 0.81
 *   Melior*      48.3%      77.0%      alif a hair above, tooth/x = 0.84
 *   (* as rendered, i.e. after Melior's own 103.4% size-adjust)
 *
 * No ascent-override/descent-override, for the reason the Thai block gives at
 * length: marketing has no grid to hold. Arabic descenders reach -30.4% against
 * Melior's -25.2%, so an Arabic line is a little taller than the Latin one.
 * That is correct -- do not "fix" it by copying the app's clamps, which exist
 * to hold a terminal grid this stylesheet does not have.
 *
 * Weights 400/500/700 match the Univers weights in use, so nothing synthesises.
 * Files keep their upstream Fontsource names so re-fetching is unambiguous
 * (@fontsource/ibm-plex-sans-arabic 5.3.0).
 */
@font-face {
  font-family: 'IBM Plex Sans Arabic';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  size-adjust: 107%;
  src: url("../fonts/ibm-plex-sans-arabic-arabic-400-normal.4fa3d81d41ab.woff2") format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+FB50-FDFF, U+FE70-FEFF, U+200C-200D;
}
@font-face {
  font-family: 'IBM Plex Sans Arabic';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  size-adjust: 107%;
  src: url("../fonts/ibm-plex-sans-arabic-arabic-500-normal.106892212ea7.woff2") format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+FB50-FDFF, U+FE70-FEFF, U+200C-200D;
}
@font-face {
  font-family: 'IBM Plex Sans Arabic';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  size-adjust: 107%;
  src: url("../fonts/ibm-plex-sans-arabic-arabic-700-normal.a4390abc98c2.woff2") format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+FB50-FDFF, U+FE70-FEFF, U+200C-200D;
}
