@datatechsolutions/tympan-tokens 0.4.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/THIRD_PARTY_NOTICES.md +5 -5
- package/dist/contrast-report.md +95 -95
- package/dist/dtcg/astrlabe.dark-high.tokens.json +99 -43
- package/dist/dtcg/astrlabe.dark.tokens.json +137 -81
- package/dist/dtcg/astrlabe.light-high.tokens.json +146 -33
- package/dist/dtcg/astrlabe.light.tokens.json +211 -98
- package/dist/fonts.css +80 -80
- package/dist/index.d.ts +257 -58
- package/dist/index.js +568 -36
- package/dist/index.js.map +1 -1
- package/dist/print-themes/print-aquarela.css +7 -7
- package/dist/print-themes/print-art-nouveau.css +2 -2
- package/dist/print-themes/print-atlas-oficial.css +7 -7
- package/dist/print-themes/print-azulejo-modernista.css +2 -2
- package/dist/print-themes/print-bauhaus.css +2 -2
- package/dist/print-themes/print-blocos-coloridos.css +5 -5
- package/dist/print-themes/print-brutalista.css +8 -8
- package/dist/print-themes/print-caderno.css +14 -14
- package/dist/print-themes/print-cartao-postal.css +5 -5
- package/dist/print-themes/print-cientifico.css +3 -3
- package/dist/print-themes/print-concretismo.css +8 -8
- package/dist/print-themes/print-construtivismo.css +6 -6
- package/dist/print-themes/print-cordel.css +6 -6
- package/dist/print-themes/print-dados-br.css +12 -12
- package/dist/print-themes/print-dashboard.css +18 -18
- package/dist/print-themes/print-diagrama-modernista.css +3 -3
- package/dist/print-themes/print-divulgacao.css +3 -3
- package/dist/print-themes/print-fluxo-historico.css +3 -3
- package/dist/print-themes/print-grade-holandesa.css +2 -2
- package/dist/print-themes/print-graficos-1900.css +6 -6
- package/dist/print-themes/print-infografico-ilustrado.css +6 -6
- package/dist/print-themes/print-isotype.css +2 -2
- package/dist/print-themes/print-jornal-1959.css +5 -5
- package/dist/print-themes/print-jornal.css +6 -6
- package/dist/print-themes/print-mapa-de-metro.css +1 -1
- package/dist/print-themes/print-memphis.css +5 -5
- package/dist/print-themes/print-minimo-de-tinta.css +4 -4
- package/dist/print-themes/print-papel-recortado.css +2 -2
- package/dist/print-themes/print-papel-salmao.css +6 -6
- package/dist/print-themes/print-pictogramas.css +2 -2
- package/dist/print-themes/print-pop-art.css +2 -2
- package/dist/print-themes/print-prancheta-clara.css +5 -5
- package/dist/print-themes/print-prancheta.css +5 -5
- package/dist/print-themes/print-proporcao-modular.css +2 -2
- package/dist/print-themes/print-riso.css +4 -4
- package/dist/print-themes/print-semanario.css +13 -13
- package/dist/print-themes/print-sinalizacao.css +8 -8
- package/dist/print-themes/print-suico.css +4 -4
- package/dist/print-themes/print-tropicalia.css +3 -3
- package/dist/print-themes.css +133 -133
- package/dist/tokens.css +247 -124
- package/dist/tokens.json +124 -66
- package/dist/values.js +124 -66
- package/fonts/ibmplexsans/ibmplexsans-italic-cyrillic-400_500_600.woff2 +0 -0
- package/fonts/ibmplexsans/ibmplexsans-italic-cyrillic-ext-400_500_600.woff2 +0 -0
- package/fonts/ibmplexsans/ibmplexsans-italic-greek-400_500_600.woff2 +0 -0
- package/fonts/ibmplexsans/ibmplexsans-italic-latin-400_500_600.woff2 +0 -0
- package/fonts/ibmplexsans/ibmplexsans-italic-latin-ext-400_500_600.woff2 +0 -0
- package/fonts/ibmplexsans/ibmplexsans-italic-vietnamese-400_500_600.woff2 +0 -0
- package/fonts/manifest.json +998 -820
- package/fonts/nunitosans/nunitosans-normal-cyrillic-400_600_700_800.woff2 +0 -0
- package/fonts/nunitosans/nunitosans-normal-cyrillic-ext-400_600_700_800.woff2 +0 -0
- package/fonts/nunitosans/nunitosans-normal-latin-400_600_700_800.woff2 +0 -0
- package/fonts/nunitosans/nunitosans-normal-latin-ext-400_600_700_800.woff2 +0 -0
- package/fonts/nunitosans/nunitosans-normal-vietnamese-400_600_700_800.woff2 +0 -0
- package/fonts/sourceserif4/sourceserif4-italic-cyrillic-400_600.woff2 +0 -0
- package/fonts/sourceserif4/sourceserif4-italic-cyrillic-ext-400_600.woff2 +0 -0
- package/fonts/sourceserif4/sourceserif4-italic-greek-400_600.woff2 +0 -0
- package/fonts/sourceserif4/sourceserif4-italic-latin-400_600.woff2 +0 -0
- package/fonts/sourceserif4/sourceserif4-italic-latin-ext-400_600.woff2 +0 -0
- package/fonts/sourceserif4/sourceserif4-italic-vietnamese-400_600.woff2 +0 -0
- package/package.json +1 -1
- package/src/fonts.ts +2 -2
- package/src/index.ts +1 -0
- package/src/presets.ts +115 -16
- package/src/print-book-themes.ts +239 -0
- package/src/print-presets.ts +220 -10
- package/src/stylesheet.ts +5 -0
- package/src/theme.ts +35 -5
- /package/fonts/ibmplexsans/{ibmplexsans-italic-cyrillic.woff2 → ibmplexsans-italic-cyrillic-400.woff2} +0 -0
- /package/fonts/ibmplexsans/{ibmplexsans-italic-cyrillic-ext.woff2 → ibmplexsans-italic-cyrillic-ext-400.woff2} +0 -0
- /package/fonts/ibmplexsans/{ibmplexsans-italic-greek.woff2 → ibmplexsans-italic-greek-400.woff2} +0 -0
- /package/fonts/ibmplexsans/{ibmplexsans-italic-latin.woff2 → ibmplexsans-italic-latin-400.woff2} +0 -0
- /package/fonts/ibmplexsans/{ibmplexsans-italic-latin-ext.woff2 → ibmplexsans-italic-latin-ext-400.woff2} +0 -0
- /package/fonts/ibmplexsans/{ibmplexsans-italic-vietnamese.woff2 → ibmplexsans-italic-vietnamese-400.woff2} +0 -0
- /package/fonts/sourceserif4/{sourceserif4-italic-cyrillic.woff2 → sourceserif4-italic-cyrillic-400.woff2} +0 -0
- /package/fonts/sourceserif4/{sourceserif4-italic-cyrillic-ext.woff2 → sourceserif4-italic-cyrillic-ext-400.woff2} +0 -0
- /package/fonts/sourceserif4/{sourceserif4-italic-greek.woff2 → sourceserif4-italic-greek-400.woff2} +0 -0
- /package/fonts/sourceserif4/{sourceserif4-italic-latin.woff2 → sourceserif4-italic-latin-400.woff2} +0 -0
- /package/fonts/sourceserif4/{sourceserif4-italic-latin-ext.woff2 → sourceserif4-italic-latin-ext-400.woff2} +0 -0
- /package/fonts/sourceserif4/{sourceserif4-italic-vietnamese.woff2 → sourceserif4-italic-vietnamese-400.woff2} +0 -0
package/src/print-presets.ts
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
// white variant) into `--ty-print-*` custom properties on
|
|
12
12
|
// `[data-ty-print-style="<name>"]`.
|
|
13
13
|
|
|
14
|
-
import { luminance, parseColor, toHex, type Rgba } from './color.ts'
|
|
14
|
+
import { contrastRatio, luminance, oklchToRgb, parseColor, rgbToOklch, toHex, type Rgba } from './color.ts'
|
|
15
15
|
import { PRINT_STYLE_ALIASES, warnDeprecatedPrintId, type PrintStyleAlias } from './print-aliases.ts'
|
|
16
16
|
|
|
17
17
|
export type RenderizadorGrafico = 'limpo' | 'mao' | 'isotype' | 'gravura' | 'prancheta' | 'aquarela' | 'riso' | 'pontos'
|
|
@@ -20,7 +20,17 @@ export type EstadoProva = 'sustentada' | 'refutada' | 'nao-da-para-afirmar' | 'p
|
|
|
20
20
|
|
|
21
21
|
export const ESTADOS_PROVA: readonly EstadoProva[] = ['sustentada', 'refutada', 'nao-da-para-afirmar', 'pendente', 'sem-dado', 'nao-testada']
|
|
22
22
|
|
|
23
|
-
/** The word printed for each proof state (
|
|
23
|
+
/** The word printed for each proof state in English (tympan-print picks by the book's `lang`). */
|
|
24
|
+
export const ROTULOS_PROVA_EN: Record<EstadoProva, string> = {
|
|
25
|
+
sustentada: 'Supported',
|
|
26
|
+
refutada: 'Refuted',
|
|
27
|
+
'nao-da-para-afirmar': 'Cannot claim',
|
|
28
|
+
pendente: 'Pending',
|
|
29
|
+
'sem-dado': 'No data',
|
|
30
|
+
'nao-testada': 'Not tested',
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** The word printed for each proof state (always visible, whatever the mark's shape); pt-BR. */
|
|
24
34
|
export const ROTULOS_PROVA: Record<EstadoProva, string> = {
|
|
25
35
|
sustentada: 'Sustentada',
|
|
26
36
|
refutada: 'Refutada',
|
|
@@ -52,6 +62,16 @@ export interface PrintCores {
|
|
|
52
62
|
prova: Record<EstadoProva, string>
|
|
53
63
|
/** Colours of page ornaments only (frames, tiles, waves); never data. Up to four. */
|
|
54
64
|
ornamento?: string[]
|
|
65
|
+
/** Colours by category key (official party colours…): used by categorical maps, parliament and bars. */
|
|
66
|
+
categorias?: Record<string, string>
|
|
67
|
+
/** Colours of data themes (blocks of a panel page: economia, saude…); --ty-print-tema-<id>. */
|
|
68
|
+
temas?: Record<string, string>
|
|
69
|
+
/** The series of interest in maps and charts (default: `destaque`), when the accent of the page differs from the data ink. */
|
|
70
|
+
interesse?: string
|
|
71
|
+
/** Data palette, diverging: the low and the high side (default destaque2 × destaque). */
|
|
72
|
+
divergente?: [string, string]
|
|
73
|
+
/** Data palette, qualitative (party, category: no implied order), up to eight (default: a colour-blind-safe set). */
|
|
74
|
+
categorica?: string[]
|
|
55
75
|
}
|
|
56
76
|
|
|
57
77
|
/** Partial colours: any role, and any subset of the proof states. */
|
|
@@ -137,6 +157,16 @@ export interface PrintEstrutura {
|
|
|
137
157
|
*/
|
|
138
158
|
realce?: 'serie' | 'linha'
|
|
139
159
|
/** Head of each small multiple: plain title (default), a band in the highlighter colour with an arrow (Schiphol), a dark band (Vignelli), a band in the ornament colour (Aicher), each multiple on its own tinted card (Le Corbusier, Bayer). */
|
|
160
|
+
/**
|
|
161
|
+
* Long runs (one page per unit, thousands of pages): no page ornaments, no tinted panel fills, the 'bolso'
|
|
162
|
+
* panel as a rule instead of a filled box. The style's type, colours and frames stay.
|
|
163
|
+
*/
|
|
164
|
+
economiaTinta?: boolean
|
|
165
|
+
/**
|
|
166
|
+
* Pages without a molde fill the type area: panels widen to close their row of the six columns and rows of
|
|
167
|
+
* panels share the free height (dashboard). A page can turn it on or off with `preencher`.
|
|
168
|
+
*/
|
|
169
|
+
preencher?: boolean
|
|
140
170
|
cabecaMultiplo?: 'titulo' | 'faixa' | 'faixa-escura' | 'faixa-cor' | 'caixa-cor'
|
|
141
171
|
}
|
|
142
172
|
|
|
@@ -176,7 +206,7 @@ export type Moldura =
|
|
|
176
206
|
| 'formas' // triangle, square and circle (Bauhaus)
|
|
177
207
|
| 'quartos' // quarter circles in the page corners (diagrama-modernista)
|
|
178
208
|
|
|
179
|
-
export interface PrintStyle {
|
|
209
|
+
export interface PrintStyle extends PrintTemaExtras {
|
|
180
210
|
/** Stable id, e.g. 'jornal'. */
|
|
181
211
|
name: string
|
|
182
212
|
/** Human label, e.g. "Editorial de jornal". */
|
|
@@ -207,10 +237,94 @@ export interface PrintStyle {
|
|
|
207
237
|
* has approved variations (ink, duotone, per style), see LogoDatatech.
|
|
208
238
|
*/
|
|
209
239
|
logo?: 'cor' | 'mono'
|
|
240
|
+
/** Typesetting options a book may need against the style's idiom (see PrintTexto). */
|
|
241
|
+
texto?: PrintTexto
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Typesetting switches for books whose content fights the style: a style in lower case (bauhaus,
|
|
246
|
+
* diagrama-modernista) would print "boa vista" for a proper name; a style with old-style figures would
|
|
247
|
+
* misalign table columns.
|
|
248
|
+
*/
|
|
249
|
+
export interface PrintTexto {
|
|
250
|
+
/**
|
|
251
|
+
* 'estilo' (default): page titles and eyebrows follow the style's casing. 'preservar': the level-1 title,
|
|
252
|
+
* eyebrows and table cells keep the casing written in the content (proper names, codes), while panel labels
|
|
253
|
+
* and running heads keep the style's.
|
|
254
|
+
*/
|
|
255
|
+
nomesProprios?: 'estilo' | 'preservar'
|
|
256
|
+
/** Figures in table cells: 'tabular' (default, lining and equal width, columns align) or 'proporcional'. */
|
|
257
|
+
numerosTabela?: 'tabular' | 'proporcional'
|
|
258
|
+
/** Font weight per role (titles, key numbers, labels, body, notes, mono), e.g. { titulo: 600, numero: 600 }. */
|
|
259
|
+
pesos?: Partial<Record<keyof PrintFontes, number>>
|
|
260
|
+
/** Figures per role: 'tabular' (equal width, lining) or 'proporcional'. Tables follow `numerosTabela`. */
|
|
261
|
+
algarismos?: Partial<Record<'numero' | 'rotulo' | 'corpo', 'tabular' | 'proporcional'>>
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// ---------------------------------------------------------------------------
|
|
265
|
+
// Book-theme extras (see print-book-themes.ts)
|
|
266
|
+
// ---------------------------------------------------------------------------
|
|
267
|
+
|
|
268
|
+
/** A mark the theme prints (publisher logo, collection seal): an image URL (data: URIs work offline) and its text alternative. */
|
|
269
|
+
export interface PrintMarca {
|
|
270
|
+
src: string
|
|
271
|
+
alt: string
|
|
272
|
+
/** Width in mm where the mark is placed (default 18 for the logo, 12 for the seal). */
|
|
273
|
+
largura?: number
|
|
274
|
+
/** Image used in black and white print (default: the same `src`, greyed by CSS). */
|
|
275
|
+
srcPb?: string
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/** Page format and print finishing. */
|
|
279
|
+
export interface PrintPagina {
|
|
280
|
+
/** Trim width in mm (default 170). */
|
|
281
|
+
largura?: number
|
|
282
|
+
/** Trim height in mm (default 240). */
|
|
283
|
+
altura?: number
|
|
284
|
+
/** Bleed in mm added around every page when the book prints for the press (default 3). */
|
|
285
|
+
sangria?: number
|
|
286
|
+
/** Crop marks in the slug, outside the bleed (default false). */
|
|
287
|
+
marcasCorte?: boolean
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/** Running head and folio. */
|
|
291
|
+
export interface PrintFolio {
|
|
292
|
+
/** Where the folio sits: outer corner (default) or centred. */
|
|
293
|
+
folio?: 'externo' | 'centro'
|
|
294
|
+
/** Where the running head sits: outer corner (default), centred, or not printed. */
|
|
295
|
+
cabeco?: 'externo' | 'centro' | 'nenhum'
|
|
296
|
+
/** Text before the folio number, e.g. "p. ". */
|
|
297
|
+
prefixoFolio?: string
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/** A local font file (offline, deterministic builds and EPUB): one @font-face. */
|
|
301
|
+
export interface PrintFonteLocal {
|
|
302
|
+
/** Family name as used in the theme's font stacks. */
|
|
303
|
+
familia: string
|
|
304
|
+
/** URL or path of the .woff2 (relative to the HTML, absolute, or a data: URI). */
|
|
305
|
+
src: string
|
|
306
|
+
peso?: number | string
|
|
307
|
+
estilo?: 'normal' | 'italic'
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/** What a theme adds to a preset beyond the style tokens. */
|
|
311
|
+
export interface PrintTemaExtras {
|
|
312
|
+
marcas?: { editora?: PrintMarca; selo?: PrintMarca }
|
|
313
|
+
pagina?: PrintPagina
|
|
314
|
+
folio?: PrintFolio
|
|
315
|
+
/** Local font files; with them PrintBook can run without network (`fontes="locais"`). */
|
|
316
|
+
fontesLocais?: PrintFonteLocal[]
|
|
317
|
+
/**
|
|
318
|
+
* Trace of a number (Rastro): sign it with the theme's seal (`marcas.selo`) or the lakebrasil mark, and add
|
|
319
|
+
* the lake version seal when the version carries a date. Default: neutral (neither).
|
|
320
|
+
*/
|
|
321
|
+
rastro?: { assinatura?: 'selo' | 'lakebrasil' | 'nenhuma'; seloLake?: boolean }
|
|
322
|
+
/** Texts the print components write by themselves, by key (see tympan-print i18n: TEXTOS_PT / TEXTOS_EN). */
|
|
323
|
+
textos?: Record<string, string>
|
|
210
324
|
}
|
|
211
325
|
|
|
212
326
|
/** Any token of a style may be overridden by the editor (partial, nested). */
|
|
213
|
-
export interface PrintStyleOverrides {
|
|
327
|
+
export interface PrintStyleOverrides extends PrintTemaExtras {
|
|
214
328
|
label?: string
|
|
215
329
|
fontes?: Partial<PrintFontes>
|
|
216
330
|
googleFonts?: string[]
|
|
@@ -224,6 +338,7 @@ export interface PrintStyleOverrides {
|
|
|
224
338
|
pb?: PrintCoresParciais
|
|
225
339
|
estrutura?: Partial<PrintEstrutura>
|
|
226
340
|
logo?: 'cor' | 'mono'
|
|
341
|
+
texto?: PrintTexto
|
|
227
342
|
}
|
|
228
343
|
|
|
229
344
|
// ---------------------------------------------------------------------------
|
|
@@ -265,8 +380,9 @@ const dashboard: PrintStyle = {
|
|
|
265
380
|
tinta2: '#3d3933',
|
|
266
381
|
tinta3: '#5f594f',
|
|
267
382
|
linha: '#d6cfc2',
|
|
268
|
-
|
|
269
|
-
|
|
383
|
+
// The highlight is not the ink (a highlighted bar must stand out): rust, AA on the paper, not a party colour.
|
|
384
|
+
destaque: '#9a4f2a',
|
|
385
|
+
destaque2: '#c4b8a8',
|
|
270
386
|
marcaTexto: '#f3e6cf',
|
|
271
387
|
contexto: '#8f877a',
|
|
272
388
|
prova: {
|
|
@@ -285,7 +401,7 @@ const dashboard: PrintStyle = {
|
|
|
285
401
|
raio: 1.6,
|
|
286
402
|
caixaAlta: false,
|
|
287
403
|
pb: {},
|
|
288
|
-
estrutura: { painel: 'nenhum', rotulo: 'letra', rotuloCaixa: 'alta', notas: 'dentro', figura: 'simples', minusculas: false },
|
|
404
|
+
estrutura: { painel: 'nenhum', rotulo: 'letra', rotuloCaixa: 'alta', notas: 'dentro', figura: 'simples', minusculas: false, preencher: true },
|
|
289
405
|
}
|
|
290
406
|
|
|
291
407
|
const graficos1900: PrintStyle = {
|
|
@@ -1476,7 +1592,26 @@ function mergeCores(base: PrintCores, over?: PrintCoresParciais): PrintCores {
|
|
|
1476
1592
|
if (!over) return base
|
|
1477
1593
|
const { prova, ...rest } = over
|
|
1478
1594
|
const clean = Object.fromEntries(Object.entries(rest).filter(([, v]) => v !== undefined)) as Partial<PrintCores>
|
|
1479
|
-
|
|
1595
|
+
const temas = base.temas || clean.temas ? { temas: { ...base.temas, ...clean.temas } } : {}
|
|
1596
|
+
const categorias = base.categorias || clean.categorias ? { categorias: { ...base.categorias, ...clean.categorias } } : {}
|
|
1597
|
+
return { ...base, ...clean, ...temas, ...categorias, prova: { ...base.prova, ...(prova ?? {}) } }
|
|
1598
|
+
}
|
|
1599
|
+
|
|
1600
|
+
function mergeExtras(base: PrintTemaExtras, over: PrintTemaExtras): PrintTemaExtras {
|
|
1601
|
+
const out: PrintTemaExtras = {}
|
|
1602
|
+
const marcas = { ...base.marcas, ...over.marcas }
|
|
1603
|
+
if (Object.keys(marcas).length) out.marcas = marcas
|
|
1604
|
+
const pagina = { ...base.pagina, ...over.pagina }
|
|
1605
|
+
if (Object.keys(pagina).length) out.pagina = pagina
|
|
1606
|
+
const folio = { ...base.folio, ...over.folio }
|
|
1607
|
+
if (Object.keys(folio).length) out.folio = folio
|
|
1608
|
+
const fl = over.fontesLocais ?? base.fontesLocais
|
|
1609
|
+
if (fl) out.fontesLocais = fl
|
|
1610
|
+
const rs = { ...base.rastro, ...over.rastro }
|
|
1611
|
+
if (Object.keys(rs).length) out.rastro = rs
|
|
1612
|
+
const tx = { ...base.textos, ...over.textos }
|
|
1613
|
+
if (Object.keys(tx).length) out.textos = tx
|
|
1614
|
+
return out
|
|
1480
1615
|
}
|
|
1481
1616
|
|
|
1482
1617
|
/** A style with the editor's overrides applied (nested, partial). */
|
|
@@ -1494,9 +1629,12 @@ export function mergePrintStyle(style: PrintStyle, overrides?: PrintStyleOverrid
|
|
|
1494
1629
|
marcaProva: overrides.marcaProva ?? style.marcaProva,
|
|
1495
1630
|
raio: overrides.raio ?? style.raio,
|
|
1496
1631
|
caixaAlta: overrides.caixaAlta ?? style.caixaAlta,
|
|
1497
|
-
|
|
1632
|
+
// P&B adjustments stay partial: merging them over the full colour set would put colours back over the greys.
|
|
1633
|
+
pb: overrides.pb ? { ...style.pb, ...overrides.pb, ...(style.pb.prova || overrides.pb.prova ? { prova: { ...style.pb.prova, ...overrides.pb.prova } } : {}) } : style.pb,
|
|
1498
1634
|
estrutura: { ...style.estrutura, ...overrides.estrutura },
|
|
1499
1635
|
logo: overrides.logo ?? style.logo,
|
|
1636
|
+
...(overrides.texto || style.texto ? { texto: { ...style.texto, ...overrides.texto } } : {}),
|
|
1637
|
+
...mergeExtras(style, overrides),
|
|
1500
1638
|
}
|
|
1501
1639
|
}
|
|
1502
1640
|
|
|
@@ -1525,6 +1663,10 @@ export function printStyleCoresPb(style: PrintStyle): PrintCores {
|
|
|
1525
1663
|
contexto: toGrey(g.contexto),
|
|
1526
1664
|
prova: Object.fromEntries(ESTADOS_PROVA.map((e) => [e, toGrey(g.prova[e])])) as Record<EstadoProva, string>,
|
|
1527
1665
|
...(g.ornamento ? { ornamento: g.ornamento.map(toGrey) } : {}),
|
|
1666
|
+
...(g.interesse ? { interesse: toGrey(g.interesse) } : {}),
|
|
1667
|
+
...(g.temas ? { temas: Object.fromEntries(Object.entries(g.temas).map(([k, v]) => [k, toGrey(v)])) } : {}),
|
|
1668
|
+
...(g.divergente ? { divergente: g.divergente.map(toGrey) as [string, string] } : {}),
|
|
1669
|
+
categorica: categoricaDoEstilo(style).map(toGrey),
|
|
1528
1670
|
}
|
|
1529
1671
|
return mergeCores(grey, style.pb)
|
|
1530
1672
|
}
|
|
@@ -1550,7 +1692,7 @@ export function resolvePrintStyle(style: PrintStyle | PrintStyleId, options: Omi
|
|
|
1550
1692
|
return { ...merged, cor: printStyleCoresPb(merged) }
|
|
1551
1693
|
}
|
|
1552
1694
|
|
|
1553
|
-
const kebab: Record<Exclude<keyof PrintCores, 'prova' | 'ornamento'>, string> = {
|
|
1695
|
+
const kebab: Record<Exclude<keyof PrintCores, 'prova' | 'ornamento' | 'divergente' | 'categorica' | 'interesse' | 'temas' | 'categorias'>, string> = {
|
|
1554
1696
|
papel: 'papel',
|
|
1555
1697
|
tinta: 'tinta',
|
|
1556
1698
|
tinta2: 'tinta-2',
|
|
@@ -1564,6 +1706,58 @@ const kebab: Record<Exclude<keyof PrintCores, 'prova' | 'ornamento'>, string> =
|
|
|
1564
1706
|
|
|
1565
1707
|
const num = (n: number) => String(Math.round(n * 1000) / 1000)
|
|
1566
1708
|
|
|
1709
|
+
/**
|
|
1710
|
+
* `cor` moved along OKLCH lightness (hue and chroma kept) until it reaches `min`:1 against `papel`: the
|
|
1711
|
+
* context grey of a theme stays visible on cream paper (areas ≥ 1.5:1, strokes ≥ 3:1).
|
|
1712
|
+
*/
|
|
1713
|
+
export function contrasteMinimo(cor: string, papel: string, min: number): string {
|
|
1714
|
+
const p = parseColor(papel)
|
|
1715
|
+
if (contrastRatio(parseColor(cor), p) >= min) return toHex(parseColor(cor))
|
|
1716
|
+
const v = rgbToOklch(parseColor(cor))
|
|
1717
|
+
const passo = luminance(p) > 0.2 ? -0.005 : 0.005
|
|
1718
|
+
let out = parseColor(cor)
|
|
1719
|
+
for (let i = 0; i < 200 && contrastRatio(out, p) < min; i++) {
|
|
1720
|
+
v.l = Math.min(0.995, Math.max(0.02, v.l + passo))
|
|
1721
|
+
out = oklchToRgb(v)
|
|
1722
|
+
}
|
|
1723
|
+
return toHex(out)
|
|
1724
|
+
}
|
|
1725
|
+
|
|
1726
|
+
const SELETORES_PAPEL: Record<keyof PrintFontes, string> = {
|
|
1727
|
+
titulo: ':is(h1, h2, h3, h4, .ty-print-title, .ty-print-figure-title, [class*="-title"]:not(.ty-print-panel-title, .ty-print-block-title, .ty-print-margin-title))',
|
|
1728
|
+
numero: ':is(.ty-print-number-value, .ty-print-table td[data-numerica], .ty-print-parliament-total, [class*="-numero"], [class*="-number"])',
|
|
1729
|
+
rotulo: ':is(.ty-print-panel-title, .ty-print-block-title, .ty-print-margin-title, .ty-print-sobretitle, .ty-print-table th, .ty-print-map-legend, .ty-print-running-head, .ty-print-folio, .ty-print-letter)',
|
|
1730
|
+
corpo: '',
|
|
1731
|
+
anotacao: ':is(.ty-print-annotation, .ty-print-margin, .ty-print-callout-text)',
|
|
1732
|
+
mono: ':is(code, pre, .ty-print-mono, .ty-print-table td[data-mono])',
|
|
1733
|
+
}
|
|
1734
|
+
|
|
1735
|
+
/**
|
|
1736
|
+
* Unlayered rules (they win over `@layer tympan-print`) for a theme's per-role font weights and figures,
|
|
1737
|
+
* scoped to `seletor`; '' when the theme sets neither.
|
|
1738
|
+
*/
|
|
1739
|
+
export function printTextoRolesCss(style: Pick<PrintStyle, 'texto'>, seletor: string): string {
|
|
1740
|
+
const out: string[] = []
|
|
1741
|
+
for (const [papel, peso] of Object.entries(style.texto?.pesos ?? {}) as Array<[keyof PrintFontes, number]>) {
|
|
1742
|
+
const s = SELETORES_PAPEL[papel]
|
|
1743
|
+
out.push(`${seletor}${s ? ` ${s}` : ''} { font-weight: ${peso}; }`)
|
|
1744
|
+
}
|
|
1745
|
+
for (const [papel, a] of Object.entries(style.texto?.algarismos ?? {}) as Array<[keyof PrintFontes, string]>) {
|
|
1746
|
+
const s = SELETORES_PAPEL[papel]
|
|
1747
|
+
out.push(`${seletor}${s ? ` ${s}` : ''} { font-variant-numeric: ${a === 'tabular' ? 'tabular-nums lining-nums' : 'proportional-nums'}; }`)
|
|
1748
|
+
}
|
|
1749
|
+
return out.join('\n')
|
|
1750
|
+
}
|
|
1751
|
+
|
|
1752
|
+
/** Qualitative palette (Okabe & Ito 2008, colour-blind safe) used when a style defines none. */
|
|
1753
|
+
export const CATEGORICA_PADRAO = ['#0072b2', '#e69f00', '#009e73', '#cc79a7', '#56b4e9', '#d55e00', '#f0e442', '#555555'] as const
|
|
1754
|
+
|
|
1755
|
+
/** The eight qualitative data colours of a style: its own `categorica`, completed by CATEGORICA_PADRAO. */
|
|
1756
|
+
export function categoricaDoEstilo(style: Pick<PrintStyle, 'cor'>): string[] {
|
|
1757
|
+
const own = style.cor.categorica ?? []
|
|
1758
|
+
return Array.from({ length: 8 }, (_, i) => own[i] ?? CATEGORICA_PADRAO[i]!)
|
|
1759
|
+
}
|
|
1760
|
+
|
|
1567
1761
|
/** Custom properties of a resolved style, in a stable order. */
|
|
1568
1762
|
export function printStyleVariables(style: PrintStyle): Array<[string, string]> {
|
|
1569
1763
|
const vars: Array<[string, string]> = []
|
|
@@ -1581,6 +1775,22 @@ export function printStyleVariables(style: PrintStyle): Array<[string, string]>
|
|
|
1581
1775
|
vars.push(['--ty-print-rotulo-caixa', minusculas ? 'lowercase' : rc === 'alta' ? 'uppercase' : 'none'])
|
|
1582
1776
|
vars.push(['--ty-print-rotulo-variante', rc === 'versalete' ? 'small-caps' : 'normal'])
|
|
1583
1777
|
vars.push(['--ty-print-rotulo-espaco', rc === 'normal' ? 'normal' : '0.07em'])
|
|
1778
|
+
vars.push(['--ty-print-pagina-largura', `${num(style.pagina?.largura ?? 170)}mm`])
|
|
1779
|
+
vars.push(['--ty-print-pagina-altura', `${num(style.pagina?.altura ?? 240)}mm`])
|
|
1780
|
+
const preservar = style.texto?.nomesProprios === 'preservar'
|
|
1781
|
+
vars.push(['--ty-print-titulo1-caixa', preservar ? 'none' : style.caixaAlta ? 'uppercase' : minusculas ? 'lowercase' : 'none'])
|
|
1782
|
+
vars.push(['--ty-print-sobretitulo-caixa', preservar ? 'none' : minusculas ? 'lowercase' : rc === 'alta' ? 'uppercase' : 'none'])
|
|
1783
|
+
vars.push(['--ty-print-celula-caixa', preservar ? 'none' : minusculas ? 'lowercase' : 'none'])
|
|
1784
|
+
vars.push(['--ty-print-tabela-numeros', style.texto?.numerosTabela === 'proporcional' ? 'proportional-nums lining-nums' : 'tabular-nums lining-nums'])
|
|
1785
|
+
for (const [k, v] of Object.entries(style.cor.temas ?? {})) vars.push([`--ty-print-tema-${k.replace(/[^a-z0-9-]/gi, '')}`, v])
|
|
1786
|
+
vars.push(['--ty-print-interesse', style.cor.interesse ?? style.cor.destaque])
|
|
1787
|
+
vars.push(['--ty-print-contexto-area', contrasteMinimo(style.cor.contexto, style.cor.papel, 1.5)])
|
|
1788
|
+
vars.push(['--ty-print-contexto-traco', contrasteMinimo(style.cor.contexto, style.cor.papel, 3)])
|
|
1789
|
+
const dv = style.cor.divergente ?? [style.cor.destaque2, style.cor.destaque]
|
|
1790
|
+
vars.push(['--ty-print-divergente-1', dv[0]])
|
|
1791
|
+
vars.push(['--ty-print-divergente-2', dv[1]])
|
|
1792
|
+
const cat = categoricaDoEstilo(style)
|
|
1793
|
+
cat.forEach((c, i) => vars.push([`--ty-print-categorica-${i + 1}`, c]))
|
|
1584
1794
|
const orn = style.cor.ornamento ?? []
|
|
1585
1795
|
const reserva = [style.cor.destaque, style.cor.destaque2, style.cor.tinta, style.cor.marcaTexto]
|
|
1586
1796
|
for (let i = 0; i < 4; i++) vars.push([`--ty-print-ornamento-${i + 1}`, orn[i] ?? reserva[i]!])
|
package/src/stylesheet.ts
CHANGED
|
@@ -120,6 +120,9 @@ export const FORCED_COLORS_VARS: VarList = [
|
|
|
120
120
|
['--ty-shadow-modal', 'none'],
|
|
121
121
|
['--ty-glass-blur-sheet', '0px'],
|
|
122
122
|
['--ty-glass-blur-floating', '0px'],
|
|
123
|
+
['--ty-glass-edge', 'CanvasText'],
|
|
124
|
+
['--ty-glass-fill', 'Canvas'],
|
|
125
|
+
['--ty-glass-fill-raised', 'Canvas'],
|
|
123
126
|
]
|
|
124
127
|
|
|
125
128
|
/** Reduced transparency (and no backdrop-filter support): opaque surfaces, no blur, no ambient. */
|
|
@@ -130,6 +133,8 @@ export const OPAQUE_VARS: VarList = [
|
|
|
130
133
|
['--ty-glass-blur-sheet', '0px !important'],
|
|
131
134
|
['--ty-glass-blur-floating', '0px !important'],
|
|
132
135
|
['--ty-glass-saturate', '1 !important'],
|
|
136
|
+
['--ty-glass-fill', 'var(--ty-surface-solid) !important'],
|
|
137
|
+
['--ty-glass-fill-raised', 'var(--ty-surface-raised-solid) !important'],
|
|
133
138
|
['--ty-ambient-1', 'transparent !important'],
|
|
134
139
|
['--ty-ambient-2', 'transparent !important'],
|
|
135
140
|
]
|
package/src/theme.ts
CHANGED
|
@@ -70,6 +70,31 @@ export interface ThemeConfig {
|
|
|
70
70
|
elevation?: Elevation
|
|
71
71
|
/** Arbitrary string variables (e.g. for textures) */
|
|
72
72
|
strings?: Record<string, string>
|
|
73
|
+
/**
|
|
74
|
+
* String variables per mode (`--ty-<name>`), for values that differ
|
|
75
|
+
* between light and dark: a glass edge, a fill gradient, a brand mark
|
|
76
|
+
* gradient. Like pins, they are exact design values: the generated
|
|
77
|
+
* high-contrast variant leaves them out, so components fall back.
|
|
78
|
+
*/
|
|
79
|
+
modeStrings?: Partial<Record<Mode, Record<string, string>>>
|
|
80
|
+
/** Backdrop saturation of glass surfaces per mode (1.15 when omitted). */
|
|
81
|
+
glassSaturate?: Partial<Record<Mode, number>>
|
|
82
|
+
/** Exact shadow layers per mode, replacing the generated ones by name. */
|
|
83
|
+
shadowPins?: Partial<Record<Mode, Partial<Record<ShadowName, ShadowPin[]>>>>
|
|
84
|
+
/** Card and sheet radii in px, when they do not follow the control radius. */
|
|
85
|
+
radii?: Partial<Record<'card' | 'sheet', number>>
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export type ShadowName = 'sheet' | 'raised' | 'floating' | 'modal' | 'sheet-inset'
|
|
89
|
+
|
|
90
|
+
/** One shadow layer of `shadowPins`, its colour as a CSS colour string. */
|
|
91
|
+
export interface ShadowPin {
|
|
92
|
+
x: number
|
|
93
|
+
y: number
|
|
94
|
+
blur: number
|
|
95
|
+
spread: number
|
|
96
|
+
color: string
|
|
97
|
+
inset?: boolean
|
|
73
98
|
}
|
|
74
99
|
|
|
75
100
|
export const RAMP_STEPS = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950] as const
|
|
@@ -288,7 +313,7 @@ export interface ResolvedTheme {
|
|
|
288
313
|
colors: Record<string, Rgba>
|
|
289
314
|
ramps: Record<SeedName, Record<RampStep, Rgba>>
|
|
290
315
|
cta: { angle: number; stops: Rgba[] }
|
|
291
|
-
shadows: Record<
|
|
316
|
+
shadows: Record<ShadowName, ShadowLayer[]>
|
|
292
317
|
/** Pixel dimensions (radius, glass blur, focus width). */
|
|
293
318
|
dimensions: Record<string, number>
|
|
294
319
|
/** Font stacks keyed by token name (`serif`, `sans`, `mono`); empty when the theme keeps the base stacks. */
|
|
@@ -471,19 +496,24 @@ export function resolveTheme(config: ThemeConfig, mode: Mode, contrastOverride?:
|
|
|
471
496
|
}
|
|
472
497
|
}
|
|
473
498
|
|
|
499
|
+
const shadowPins = config.shadowPins?.[mode] ?? {}
|
|
500
|
+
for (const [name, layers] of Object.entries(shadowPins) as Array<[ShadowName, ShadowPin[]]>) {
|
|
501
|
+
shadows[name] = layers.map((l) => ({ ...l, color: parseColor(l.color) }))
|
|
502
|
+
}
|
|
503
|
+
|
|
474
504
|
const R = config.radius
|
|
475
505
|
const dimensions: Record<string, number> = {
|
|
476
506
|
radius: R,
|
|
477
507
|
'radius-control': R,
|
|
478
|
-
'radius-card': Math.round(R * 1.6),
|
|
479
|
-
'radius-sheet': Math.round(R * 2.4),
|
|
508
|
+
'radius-card': config.radii?.card ?? Math.round(R * 1.6),
|
|
509
|
+
'radius-sheet': config.radii?.sheet ?? Math.round(R * 2.4),
|
|
480
510
|
'radius-pill': 999,
|
|
481
511
|
'radius-agent': Math.max(2, Math.round(R * 0.6)),
|
|
482
512
|
'focus-width': contrast === 'high' ? 3 : 2,
|
|
483
513
|
'glass-blur-sheet': config.glass ? 20 : 0,
|
|
484
514
|
'glass-blur-floating': config.glass ? 24 : 0,
|
|
485
515
|
}
|
|
486
|
-
const numbers: Record<string, number> = { 'glass-saturate': config.glass ? 1.15 : 1 }
|
|
516
|
+
const numbers: Record<string, number> = { 'glass-saturate': config.glass ? (config.glassSaturate?.[mode] ?? 1.15) : 1 }
|
|
487
517
|
|
|
488
518
|
const fonts: ResolvedTheme['fonts'] = {}
|
|
489
519
|
for (const role of ['display', 'body', 'mono'] as const) {
|
|
@@ -491,7 +521,7 @@ export function resolveTheme(config: ThemeConfig, mode: Mode, contrastOverride?:
|
|
|
491
521
|
if (list?.length) fonts[FONT_ROLE_TOKENS[role]] = [...list]
|
|
492
522
|
}
|
|
493
523
|
|
|
494
|
-
return { name: config.name, mode, contrast, colors, ramps, cta: { angle: 135, stops: ctaStops }, shadows, dimensions, numbers, fonts, strings: config.strings
|
|
524
|
+
return { name: config.name, mode, contrast, colors, ramps, cta: { angle: 135, stops: ctaStops }, shadows, dimensions, numbers, fonts, strings: { ...config.strings, ...(contrast === config.contrast ? config.modeStrings?.[mode] : undefined) }, report }
|
|
495
525
|
}
|
|
496
526
|
|
|
497
527
|
// ---------------------------------------------------------------------------
|
|
File without changes
|
|
File without changes
|
/package/fonts/ibmplexsans/{ibmplexsans-italic-greek.woff2 → ibmplexsans-italic-greek-400.woff2}
RENAMED
|
File without changes
|
/package/fonts/ibmplexsans/{ibmplexsans-italic-latin.woff2 → ibmplexsans-italic-latin-400.woff2}
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/fonts/sourceserif4/{sourceserif4-italic-greek.woff2 → sourceserif4-italic-greek-400.woff2}
RENAMED
|
File without changes
|
/package/fonts/sourceserif4/{sourceserif4-italic-latin.woff2 → sourceserif4-italic-latin-400.woff2}
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|