Update game-datcards-improved.user.js

This commit is contained in:
2026-07-22 19:02:47 +02:00
parent b7b01b327c
commit 24e91899f4
+2 -128
View File
@@ -196,106 +196,11 @@
const FONT_STYLE_ID = 'gdc-card-font'; const FONT_STYLE_ID = 'gdc-card-font';
const FONT_PREF_KEY = 'gdc-card-font-enabled'; const FONT_PREF_KEY = 'gdc-card-font-enabled';
// The official sizes are point sizes on a printed card, and CSS pt units say // Family swap only: sizes, weights and casing are left to the app so the two
// nothing about how large the app happens to draw that card. So instead of // renderings can be compared side by side.
// using pt directly, measure each card and derive how many layout pixels one
// point of the printed card is worth; --gdc-pt below carries that value.
// Printed datacard width, 8in. Measured back from an official card: its body
// text sits at ~1.3% of the card width, which puts 7.5pt at this reference.
// Raising it shrinks all card text and lowering it grows it, so it doubles as
// the tuning knob for the overall type size:
// localStorage.setItem('gdc-card-width-pt', 560)
const CARD_WIDTH_PT = 576;
function cardWidthPt() {
return Number(localStorage.getItem('gdc-card-width-pt')) || CARD_WIDTH_PT;
}
function pt(size) {
return `calc(${size} * var(--gdc-pt, 1.333px))`;
}
// offsetWidth is the untransformed layout width, so this stays correct
// whether the app zooms cards by scaling the layout or by a CSS transform.
function updateFontScale() {
const reference = cardWidthPt();
document.querySelectorAll('.unit').forEach((unit) => {
const width = unit.offsetWidth;
if (!width) return;
const value = width / reference + 'px';
if (unit.style.getPropertyValue('--gdc-pt') !== value) {
unit.style.setProperty('--gdc-pt', value);
}
});
}
function cardFontCss() { function cardFontCss() {
return ` return `
.unit, .unit * { font-family: ${CARD_FONT}, sans-serif !important; } .unit, .unit * { font-family: ${CARD_FONT}, sans-serif !important; }
/* Unit name: extra bold 15pt, slightly tracked out as on the printed card */
.unit .name_container .name {
font-weight: 800 !important;
font-size: ${pt(15)} !important;
letter-spacing: 0.02em !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;
}
/* Section banners ("RANGED WEAPONS", "ABILITIES", "KEYWORDS:") are set a
step larger than body text on the printed card, and tracked out. */
.unit .heading .title:not(.center),
.unit .invul .title,
.unit .footer .title {
font-weight: 700 !important;
font-size: ${pt(9)} !important;
letter-spacing: 0.04em !important;
}
/* General weapon and abilities text: regular or bold 7.5pt */
.unit .stats_container .caption,
.unit .heading .title.center,
.unit .ability .name,
.unit .ability .value,
.unit .footer .value {
font-weight: 700 !important;
font-size: ${pt(7.5)} !important;
}
.unit .weapon .value,
.unit .ability .title,
.unit .ability .description,
.unit .description-container .description {
font-weight: 400 !important;
font-size: ${pt(7.5)} !important;
}
/* Keyword lists are small caps, not the plain title case the app uses. */
.unit .footer .value {
font-variant-caps: small-caps !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;
}
`; `;
} }
@@ -303,33 +208,11 @@
return localStorage.getItem(FONT_PREF_KEY) === '1'; return localStorage.getItem(FONT_PREF_KEY) === '1';
} }
// Cards get re-rendered on every edit and resized by the zoom control, so the
// scale has to be recomputed rather than set once.
var domObserver = null;
var sizeObserver = null;
var scalePending = false;
function scheduleFontScale() {
if (scalePending) return;
scalePending = true;
requestAnimationFrame(() => {
scalePending = false;
updateFontScale();
document.querySelectorAll('.unit').forEach((unit) => sizeObserver.observe(unit));
});
}
function applyCardFont(enabled) { function applyCardFont(enabled) {
const existing = document.getElementById(FONT_STYLE_ID); const existing = document.getElementById(FONT_STYLE_ID);
if (!enabled) { if (!enabled) {
if (existing) existing.remove(); if (existing) existing.remove();
if (domObserver) {
domObserver.disconnect();
sizeObserver.disconnect();
domObserver = null;
sizeObserver = null;
}
return; return;
} }
@@ -337,15 +220,6 @@
style.id = FONT_STYLE_ID; style.id = FONT_STYLE_ID;
style.textContent = cardFontCss(); style.textContent = cardFontCss();
if (!existing) document.head.appendChild(style); if (!existing) document.head.appendChild(style);
if (!domObserver) {
// childList only: the scale is written to the cards as an inline custom
// property, and watching attributes here would retrigger on our own write.
sizeObserver = new ResizeObserver(scheduleFontScale);
domObserver = new MutationObserver(scheduleFontScale);
domObserver.observe(document.body, { childList: true, subtree: true });
}
scheduleFontScale();
} }
function syncCardFontButton() { function syncCardFontButton() {