diff --git a/js/game-datcards-improved.user.js b/js/game-datcards-improved.user.js
index 99aebf9..cb96723 100644
--- a/js/game-datcards-improved.user.js
+++ b/js/game-datcards-improved.user.js
@@ -1,8 +1,8 @@
// ==UserScript==
// @name Game Datacards - Improved
// @namespace local
-// @version 1.0
-// @description Adds card image export/import (ZIP) to the header and a button to rotate card backs for printing
+// @version 1.1
+// @description Adds card image export/import (ZIP) to the header, a button to rotate card backs for printing and a toggle for the official 10th edition card font
// @match *://game-datacards.eu/*
// @grant none
// @run-at document-idle
@@ -145,6 +145,9 @@
const EXPORT_ICON =
'';
+ const FONT_ICON =
+ '';
+
const IMPORT_ICON =
'';
@@ -155,7 +158,10 @@
b.title = title;
b.setAttribute('aria-label', title);
b.innerHTML = iconSvg;
- b.onclick = () => fn().catch((e) => alert('Error: ' + e.message));
+ b.onclick = () => {
+ const r = fn();
+ if (r && typeof r.catch === 'function') r.catch((e) => alert('Error: ' + e.message));
+ };
return b;
}
@@ -170,14 +176,120 @@
group.className = 'app-header-group';
group.appendChild(mkBtn('gdc-img-export', 'Export card images', EXPORT_ICON, doExport));
group.appendChild(mkBtn('gdc-img-import', 'Import card images', IMPORT_ICON, doImport));
+ group.appendChild(mkBtn('gdc-card-font', 'Card font: Conduit ITC', FONT_ICON, toggleCardFont));
// Insert the group right before the settings button's group,
// so the buttons sit to the left of the cog.
const settingsGroup = settingsBtn.closest('.app-header-group');
settingsGroup.parentNode.insertBefore(group, settingsGroup);
+ syncCardFontButton();
return true;
}
+ // ---------------------------------------------------------------------------
+ // Official 10th edition card font
+ // ---------------------------------------------------------------------------
+
+ // The font has to be installed locally; the extra names cover the different
+ // family names the foundry/converters use for the same face.
+ const CARD_FONT = "'ConduitITCStd', 'Conduit ITC Std', 'ConduitITC Std', 'Conduit ITC'";
+ const FONT_STYLE_ID = 'gdc-card-font';
+ const FONT_PREF_KEY = 'gdc-card-font-enabled';
+
+ // Sizes below are the official ones for a full size card. The app draws cards
+ // scaled by --card-scaling-factor, so every size is scaled along with it.
+ function pt(size) {
+ return `calc(${size}pt * var(--card-scaling-factor, 1))`;
+ }
+
+ function cardFontCss() {
+ return `
+ .unit, .unit * { font-family: ${CARD_FONT}, sans-serif !important; }
+
+ /* Unit name: extra bold 15pt */
+ .unit .name_container .name {
+ font-weight: 800 !important;
+ font-size: ${pt(15)} !important;
+ }
+
+ /* Unit description: light italic 8pt */
+ .unit .name_container .subname,
+ .unit .header .description {
+ font-weight: 300 !important;
+ font-style: italic !important;
+ font-size: ${pt(8)} !important;
+ }
+
+ /* Unit values: bold 14pt */
+ .unit .stats_container .value,
+ .unit .stats_container .value-text {
+ font-weight: 700 !important;
+ font-size: ${pt(14)} !important;
+ }
+
+ /* General weapon and abilities text: regular or bold 7.5pt */
+ .unit .stats_container .caption,
+ .unit .invul .title,
+ .unit .heading .title,
+ .unit .ability .name,
+ .unit .ability .title,
+ .unit .footer .title,
+ .unit .footer .value {
+ font-weight: 700 !important;
+ font-size: ${pt(7.5)} !important;
+ }
+
+ .unit .weapon .value,
+ .unit .ability .value,
+ .unit .ability .description,
+ .unit .description-container .description {
+ font-weight: 400 !important;
+ font-size: ${pt(7.5)} !important;
+ }
+
+ /* Weapon abilities (the keyword/rule chips): bold 5.5pt */
+ .unit .keyword-button,
+ .unit .keyword-button span,
+ .unit .rule-button,
+ .unit .rule-button span {
+ font-weight: 700 !important;
+ font-size: ${pt(5.5)} !important;
+ }
+ `;
+ }
+
+ function isCardFontEnabled() {
+ return localStorage.getItem(FONT_PREF_KEY) === '1';
+ }
+
+ function applyCardFont(enabled) {
+ const existing = document.getElementById(FONT_STYLE_ID);
+ if (!enabled) {
+ if (existing) existing.remove();
+ return;
+ }
+ const style = existing || document.createElement('style');
+ style.id = FONT_STYLE_ID;
+ style.textContent = cardFontCss();
+ if (!existing) document.head.appendChild(style);
+ }
+
+ function syncCardFontButton() {
+ const btn = document.getElementById('gdc-card-font');
+ if (!btn) return;
+ const on = isCardFontEnabled();
+ btn.style.color = on ? '#e8b923' : '';
+ btn.title = on ? 'Card font: Conduit ITC (on)' : 'Card font: Conduit ITC (off)';
+ btn.setAttribute('aria-pressed', on ? 'true' : 'false');
+ }
+
+ function toggleCardFont() {
+ const next = !isCardFontEnabled();
+ localStorage.setItem(FONT_PREF_KEY, next ? '1' : '0');
+ applyCardFont(next);
+ syncCardFontButton();
+ }
+
// ---------------------------------------------------------------------------
// Rotate card backs for printing
// ---------------------------------------------------------------------------
@@ -240,6 +352,8 @@
// The app renders after load, and the print sidebar only exists on the print
// view, so keep watching the DOM until both mount points have been handled.
+ applyCardFont(isCardFontEnabled());
+
var headerDone = addHeaderButtons();
var sidebarDone = addRotateButton();