@bendyline/squisq 2.0.1 → 2.1.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/dist/{Doc-ylqWKDc_.d.ts → Doc-DynJleo-.d.ts} +159 -2
- package/dist/{ImageEditDoc-D828IXJ1.d.ts → ImageEditDoc-Ca4Tr9uN.d.ts} +1 -1
- package/dist/{chunk-PXLVXTLW.js → chunk-ILWDXLUK.js} +24 -6
- package/dist/chunk-ILWDXLUK.js.map +1 -0
- package/dist/{chunk-W4O2TX5I.js → chunk-JHZWYRSW.js} +569 -1
- package/dist/chunk-JHZWYRSW.js.map +1 -0
- package/dist/{chunk-X6DUONGT.js → chunk-JI77MGAK.js} +123 -10
- package/dist/chunk-JI77MGAK.js.map +1 -0
- package/dist/{chunk-TFJVXUHH.js → chunk-OTKVFVL6.js} +1403 -41
- package/dist/chunk-OTKVFVL6.js.map +1 -0
- package/dist/{chunk-MMPBOUK7.js → chunk-QUUPYOSP.js} +8 -2
- package/dist/chunk-QUUPYOSP.js.map +1 -0
- package/dist/chunk-VWCJ2WXC.js +215 -0
- package/dist/chunk-VWCJ2WXC.js.map +1 -0
- package/dist/{chunk-2PWOO4ZE.js → chunk-VYFRI7R6.js} +2 -2
- package/dist/{chunk-CY2R2VPR.js → chunk-XNLB57UD.js} +2 -2
- package/dist/doc/index.d.ts +144 -5
- package/dist/doc/index.js +24 -4
- package/dist/generate/index.d.ts +1 -1
- package/dist/imageEdit/index.d.ts +3 -3
- package/dist/index.d.ts +6 -5
- package/dist/index.js +66 -8
- package/dist/jsonForm/index.d.ts +1 -1
- package/dist/jsonForm/index.js +4 -4
- package/dist/materializePageSection-DDzubQXo.d.ts +223 -0
- package/dist/narration/index.d.ts +1 -1
- package/dist/narration/index.js +3 -3
- package/dist/schemas/index.d.ts +30 -5
- package/dist/schemas/index.js +41 -3
- package/dist/{themeLibrary-RjVgLpUi.d.ts → themeLibrary-B72m0W1y.d.ts} +1 -1
- package/dist/transform/index.d.ts +8 -9
- package/dist/transform/index.js +1 -1
- package/package.json +1 -1
- package/src/__tests__/materializeBlockLayers.test.ts +32 -0
- package/src/__tests__/materializePageSections.test.ts +404 -0
- package/src/__tests__/pageStyle.test.ts +258 -0
- package/src/__tests__/templateAnnotationParse.test.ts +13 -0
- package/src/doc/index.ts +34 -0
- package/src/doc/materializeBlockLayers.ts +170 -9
- package/src/doc/page/PageSection.ts +174 -0
- package/src/doc/page/materializePageSection.ts +616 -0
- package/src/doc/page/resolvePageBlock.ts +108 -0
- package/src/doc/page/sectionExtractors.ts +466 -0
- package/src/doc/pageCss.ts +628 -0
- package/src/doc/templateInputs.ts +1 -0
- package/src/schemas/Doc.ts +22 -1
- package/src/schemas/PageStyle.ts +213 -0
- package/src/schemas/Theme.ts +7 -0
- package/src/schemas/index.ts +2 -0
- package/src/schemas/pageStyleDefaults.ts +204 -0
- package/src/schemas/themeCompile.ts +7 -0
- package/src/schemas/themeValidator.ts +183 -0
- package/src/schemas/themes/bold.json +29 -0
- package/src/schemas/themes/cinematic.json +32 -0
- package/src/schemas/themes/documentary.json +29 -0
- package/src/schemas/themes/gezellig.json +30 -0
- package/src/schemas/themes/magazine.json +37 -0
- package/src/schemas/themes/minimalist.json +29 -0
- package/src/schemas/themes/morning-light.json +32 -0
- package/src/schemas/themes/standard-dark.json +24 -0
- package/src/schemas/themes/standard.json +24 -0
- package/src/schemas/themes/tech-dark.json +42 -0
- package/src/schemas/themes/warm-earth.json +24 -0
- package/src/transform/registry.ts +19 -0
- package/src/transform/styles/dataDriven.ts +1 -0
- package/src/transform/styles/documentary.ts +1 -0
- package/src/transform/styles/magazine.ts +1 -0
- package/src/transform/styles/minimal.ts +1 -0
- package/src/transform/styles/narrative.ts +1 -0
- package/src/transform/types.ts +7 -0
- package/dist/chunk-FVJUUTEM.js +0 -74
- package/dist/chunk-FVJUUTEM.js.map +0 -1
- package/dist/chunk-MMPBOUK7.js.map +0 -1
- package/dist/chunk-PXLVXTLW.js.map +0 -1
- package/dist/chunk-TFJVXUHH.js.map +0 -1
- package/dist/chunk-W4O2TX5I.js.map +0 -1
- package/dist/chunk-X6DUONGT.js.map +0 -1
- /package/dist/{chunk-2PWOO4ZE.js.map → chunk-VYFRI7R6.js.map} +0 -0
- /package/dist/{chunk-CY2R2VPR.js.map → chunk-XNLB57UD.js.map} +0 -0
|
@@ -0,0 +1,628 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Page CSS — the single source of truth for Page (linear) mode styling.
|
|
3
|
+
*
|
|
4
|
+
* `PAGE_BASE_CSS` is structural and theme-independent: every color, font,
|
|
5
|
+
* and dimension flows through `--squisq-page-*` custom properties
|
|
6
|
+
* (`buildPageCssVars`) and the token data-attributes the renderer stamps on
|
|
7
|
+
* the `.squisq-page` wrapper (`pageStyleDataAttributes`). One stylesheet
|
|
8
|
+
* therefore serves all themes and all design families — a theme changes the
|
|
9
|
+
* page's look purely through vars + data attributes, never through
|
|
10
|
+
* generated CSS.
|
|
11
|
+
*
|
|
12
|
+
* Consumers:
|
|
13
|
+
* - React `LinearDocView` injects `<style data-squisq-page>` with
|
|
14
|
+
* `PAGE_BASE_CSS` and sets the vars inline (self-contained — no CSS
|
|
15
|
+
* import needed, which keeps the standalone bundle and single-file HTML
|
|
16
|
+
* exports working).
|
|
17
|
+
* - A string-HTML exporter can call `buildPageCss(theme)` for the same
|
|
18
|
+
* bytes plus a `.squisq-page { … }` var block.
|
|
19
|
+
*
|
|
20
|
+
* Responsive behavior uses container queries against the scroll container
|
|
21
|
+
* (named `squisq-page`), with a media-query fallback for engines without
|
|
22
|
+
* container support.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import type { Theme } from '../schemas/Theme.js';
|
|
26
|
+
import type { ThemePageStyle } from '../schemas/PageStyle.js';
|
|
27
|
+
import { resolveFontFamily } from '../schemas/fontStacks.js';
|
|
28
|
+
import { DEFAULT_THEME } from '../schemas/themeLibrary.js';
|
|
29
|
+
import { resolvePageStyle } from './page/materializePageSection.js';
|
|
30
|
+
|
|
31
|
+
/** Subtle noise texture (tiny inline SVG) for the `noise` page pattern. */
|
|
32
|
+
const NOISE_DATA_URI =
|
|
33
|
+
"url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)' opacity='0.35'/%3E%3C/svg%3E\")";
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Custom-property values for a theme's page rendition. Set these inline on
|
|
37
|
+
* the `.squisq-page` wrapper (React) or in a `.squisq-page { … }` rule
|
|
38
|
+
* (string export). Per-section accent vars (`--squisq-page-accent*`) get
|
|
39
|
+
* page-level defaults here and are overridden per section by the renderer.
|
|
40
|
+
*/
|
|
41
|
+
export function buildPageCssVars(
|
|
42
|
+
theme?: Theme,
|
|
43
|
+
pageStyle?: ThemePageStyle,
|
|
44
|
+
): Record<string, string> {
|
|
45
|
+
const t = theme ?? DEFAULT_THEME;
|
|
46
|
+
const style = pageStyle ?? resolvePageStyle(t);
|
|
47
|
+
const colors = t.colors;
|
|
48
|
+
const typography = t.typography;
|
|
49
|
+
return {
|
|
50
|
+
'--squisq-page-bg': colors.background,
|
|
51
|
+
'--squisq-page-bg-alt': colors.backgroundLight,
|
|
52
|
+
'--squisq-page-text': colors.text,
|
|
53
|
+
'--squisq-page-text-muted': colors.textMuted,
|
|
54
|
+
'--squisq-page-primary': colors.primary,
|
|
55
|
+
'--squisq-page-secondary': colors.secondary,
|
|
56
|
+
'--squisq-page-highlight': colors.highlight,
|
|
57
|
+
'--squisq-page-title-font': resolveFontFamily(typography.titleFont, 'Georgia, serif'),
|
|
58
|
+
'--squisq-page-body-font': resolveFontFamily(typography.bodyFont, 'system-ui, sans-serif'),
|
|
59
|
+
'--squisq-page-mono-font': resolveFontFamily(
|
|
60
|
+
typography.monoFont,
|
|
61
|
+
'ui-monospace, SFMono-Regular, Menlo, monospace',
|
|
62
|
+
),
|
|
63
|
+
'--squisq-page-line-height': String(typography.lineHeight ?? 1.65),
|
|
64
|
+
'--squisq-page-title-weight': typography.titleWeight === 'normal' ? '400' : '700',
|
|
65
|
+
'--squisq-page-content-max': `${style.tokens.contentMaxWidth}px`,
|
|
66
|
+
'--squisq-page-wide-max': `${style.tokens.wideMaxWidth}px`,
|
|
67
|
+
'--squisq-page-radius': `${style.tokens.cornerRadius}px`,
|
|
68
|
+
// Per-section accent defaults; the renderer overrides these per section.
|
|
69
|
+
'--squisq-page-accent': colors.primary,
|
|
70
|
+
'--squisq-page-accent-bg': colors.backgroundLight,
|
|
71
|
+
'--squisq-page-accent-text': colors.text,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* The token data-attributes the renderer stamps on `.squisq-page` so the
|
|
77
|
+
* structural CSS can branch per design decision. Shared by React and any
|
|
78
|
+
* string exporter so both emit identical markup.
|
|
79
|
+
*/
|
|
80
|
+
export function pageStyleDataAttributes(pageStyle: ThemePageStyle): Record<string, string> {
|
|
81
|
+
const tokens = pageStyle.tokens;
|
|
82
|
+
const attrs: Record<string, string> = {
|
|
83
|
+
'data-family': pageStyle.family,
|
|
84
|
+
'data-spacing': tokens.sectionSpacing,
|
|
85
|
+
'data-divider': tokens.divider,
|
|
86
|
+
'data-rhythm': tokens.backgroundRhythm,
|
|
87
|
+
'data-hero-style': tokens.heroStyle,
|
|
88
|
+
'data-eyebrow': tokens.headingTreatment.eyebrow,
|
|
89
|
+
'data-heading-scale': tokens.headingTreatment.scale,
|
|
90
|
+
'data-framing': tokens.imageFraming,
|
|
91
|
+
'data-shadow': tokens.shadow,
|
|
92
|
+
'data-quote-mark': tokens.quoteMark,
|
|
93
|
+
'data-numerals': tokens.numeralStyle,
|
|
94
|
+
};
|
|
95
|
+
if (tokens.headingTreatment.case && tokens.headingTreatment.case !== 'none') {
|
|
96
|
+
attrs['data-heading-case'] = tokens.headingTreatment.case;
|
|
97
|
+
}
|
|
98
|
+
if (tokens.headingTreatment.underline && tokens.headingTreatment.underline !== 'none') {
|
|
99
|
+
attrs['data-underline'] = tokens.headingTreatment.underline;
|
|
100
|
+
}
|
|
101
|
+
if (tokens.pattern && tokens.pattern !== 'none') {
|
|
102
|
+
attrs['data-pattern'] = tokens.pattern;
|
|
103
|
+
}
|
|
104
|
+
return attrs;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** Shared responsive collapse rules (referenced from both query forms). */
|
|
108
|
+
const NARROW_RULES = `
|
|
109
|
+
.squisq-page-hero-grid { grid-template-columns: 1fr; gap: 1.5rem; }
|
|
110
|
+
.squisq-page-feature { grid-template-columns: 1fr; }
|
|
111
|
+
.squisq-page-feature--media-right .squisq-page-feature-media { order: 0; }
|
|
112
|
+
.squisq-page-stats { flex-direction: column; gap: 1.75rem; }
|
|
113
|
+
.squisq-page-cards { grid-template-columns: 1fr; }
|
|
114
|
+
.squisq-page-gallery { grid-template-columns: repeat(2, 1fr); }
|
|
115
|
+
.squisq-page-milestone { grid-template-columns: 1fr; gap: 0.5rem; }
|
|
116
|
+
.squisq-page-milestone-rail { display: none; }
|
|
117
|
+
.squisq-page-section-inner { padding-inline: 18px; }
|
|
118
|
+
`;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Structural, theme-independent stylesheet for the page rendition.
|
|
122
|
+
* Everything is scoped under `.squisq-page`.
|
|
123
|
+
*/
|
|
124
|
+
export const PAGE_BASE_CSS = `
|
|
125
|
+
/* ── Base ─────────────────────────────────────────────────────────── */
|
|
126
|
+
.squisq-page {
|
|
127
|
+
background: var(--squisq-page-bg);
|
|
128
|
+
color: var(--squisq-page-text);
|
|
129
|
+
font-family: var(--squisq-page-body-font);
|
|
130
|
+
line-height: var(--squisq-page-line-height);
|
|
131
|
+
--squisq-page-divider-color: color-mix(in srgb, var(--squisq-page-text) 16%, transparent);
|
|
132
|
+
--squisq-page-section-pad: 3.5rem;
|
|
133
|
+
--squisq-page-shadow: none;
|
|
134
|
+
}
|
|
135
|
+
.squisq-page *, .squisq-page *::before, .squisq-page *::after { box-sizing: border-box; }
|
|
136
|
+
.squisq-page img { max-width: 100%; height: auto; }
|
|
137
|
+
|
|
138
|
+
/* Page pattern washes (very low intensity) */
|
|
139
|
+
.squisq-page[data-pattern='dots'] {
|
|
140
|
+
background-image: radial-gradient(color-mix(in srgb, var(--squisq-page-text) 7%, transparent) 1px, transparent 1px);
|
|
141
|
+
background-size: 22px 22px;
|
|
142
|
+
}
|
|
143
|
+
.squisq-page[data-pattern='grid'] {
|
|
144
|
+
background-image:
|
|
145
|
+
linear-gradient(color-mix(in srgb, var(--squisq-page-primary) 7%, transparent) 1px, transparent 1px),
|
|
146
|
+
linear-gradient(90deg, color-mix(in srgb, var(--squisq-page-primary) 7%, transparent) 1px, transparent 1px);
|
|
147
|
+
background-size: 44px 44px;
|
|
148
|
+
}
|
|
149
|
+
.squisq-page[data-pattern='diagonal'] {
|
|
150
|
+
background-image: repeating-linear-gradient(
|
|
151
|
+
-45deg,
|
|
152
|
+
color-mix(in srgb, var(--squisq-page-text) 4%, transparent) 0 1px,
|
|
153
|
+
transparent 1px 14px
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
.squisq-page[data-pattern='noise'] { background-image: ${NOISE_DATA_URI}; }
|
|
157
|
+
|
|
158
|
+
/* Spacing scale */
|
|
159
|
+
.squisq-page[data-spacing='compact'] { --squisq-page-section-pad: 2.25rem; }
|
|
160
|
+
.squisq-page[data-spacing='comfortable'] { --squisq-page-section-pad: 3.5rem; }
|
|
161
|
+
.squisq-page[data-spacing='generous'] { --squisq-page-section-pad: 5.25rem; }
|
|
162
|
+
|
|
163
|
+
/* Shadow language */
|
|
164
|
+
.squisq-page[data-shadow='soft'] { --squisq-page-shadow: 0 14px 36px color-mix(in srgb, var(--squisq-page-text) 14%, transparent); }
|
|
165
|
+
.squisq-page[data-shadow='crisp'] { --squisq-page-shadow: 0 2px 10px color-mix(in srgb, var(--squisq-page-text) 26%, transparent); }
|
|
166
|
+
.squisq-page[data-shadow='heavy'] { --squisq-page-shadow: 10px 10px 0 color-mix(in srgb, var(--squisq-page-text) 82%, transparent); }
|
|
167
|
+
|
|
168
|
+
/* ── Sections ─────────────────────────────────────────────────────── */
|
|
169
|
+
.squisq-page-section { position: relative; padding-block: var(--squisq-page-section-pad); }
|
|
170
|
+
.squisq-page-section-inner {
|
|
171
|
+
max-width: var(--squisq-page-content-max);
|
|
172
|
+
margin-inline: auto;
|
|
173
|
+
padding-inline: 24px;
|
|
174
|
+
}
|
|
175
|
+
/* Backdrops anchor to the section; these content roots stack above them. */
|
|
176
|
+
.squisq-page-hero-body,
|
|
177
|
+
.squisq-page-banner-body,
|
|
178
|
+
.squisq-page-quote-figure { position: relative; }
|
|
179
|
+
.squisq-page-section--feature-split .squisq-page-section-inner,
|
|
180
|
+
.squisq-page-section--gallery .squisq-page-section-inner,
|
|
181
|
+
.squisq-page-section--table-section .squisq-page-section-inner,
|
|
182
|
+
.squisq-page-section--canvas-embed .squisq-page-section-inner,
|
|
183
|
+
.squisq-page-section--stat-band .squisq-page-section-inner,
|
|
184
|
+
.squisq-page-section--card-grid .squisq-page-section-inner,
|
|
185
|
+
.squisq-page-section--media-figure .squisq-page-section-inner,
|
|
186
|
+
.squisq-page-section--hero .squisq-page-section-inner {
|
|
187
|
+
max-width: var(--squisq-page-wide-max);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/* Background rhythm */
|
|
191
|
+
.squisq-page-section--bg-alternate { background: var(--squisq-page-bg-alt); }
|
|
192
|
+
.squisq-page-section--bg-accent {
|
|
193
|
+
background: var(--squisq-page-accent-bg);
|
|
194
|
+
color: var(--squisq-page-accent-text);
|
|
195
|
+
}
|
|
196
|
+
.squisq-page-section--bg-media { color: #ffffff; }
|
|
197
|
+
|
|
198
|
+
/* Dividers between adjacent sections */
|
|
199
|
+
.squisq-page[data-divider='hairline'] .squisq-page-section + .squisq-page-section { border-top: 1px solid var(--squisq-page-divider-color); }
|
|
200
|
+
.squisq-page[data-divider='thick-rule'] .squisq-page-section + .squisq-page-section { border-top: 3px solid var(--squisq-page-primary); }
|
|
201
|
+
.squisq-page[data-divider='double-rule'] .squisq-page-section + .squisq-page-section { border-top: 4px double var(--squisq-page-divider-color); }
|
|
202
|
+
.squisq-page[data-divider='dotted'] .squisq-page-section + .squisq-page-section { border-top: 2px dotted var(--squisq-page-divider-color); }
|
|
203
|
+
/* Banded sections carry their own edges; media sections never need rules. */
|
|
204
|
+
.squisq-page .squisq-page-section--bg-media,
|
|
205
|
+
.squisq-page .squisq-page-section--bg-media + .squisq-page-section,
|
|
206
|
+
.squisq-page .squisq-page-section--timeline-rail + .squisq-page-section--timeline-rail { border-top: none; }
|
|
207
|
+
|
|
208
|
+
/* ── Headings, eyebrows ───────────────────────────────────────────── */
|
|
209
|
+
.squisq-page-section-title {
|
|
210
|
+
font-family: var(--squisq-page-title-font);
|
|
211
|
+
font-weight: var(--squisq-page-title-weight);
|
|
212
|
+
line-height: 1.15;
|
|
213
|
+
margin: 0 0 0.5em;
|
|
214
|
+
}
|
|
215
|
+
.squisq-page[data-heading-case='uppercase'] .squisq-page-section-title { text-transform: uppercase; letter-spacing: 0.03em; }
|
|
216
|
+
.squisq-page[data-underline='accent-bar'] .squisq-page-section-title::after {
|
|
217
|
+
content: '';
|
|
218
|
+
display: block;
|
|
219
|
+
width: 56px;
|
|
220
|
+
height: 4px;
|
|
221
|
+
margin-top: 0.4em;
|
|
222
|
+
border-radius: 2px;
|
|
223
|
+
background: var(--squisq-page-accent);
|
|
224
|
+
}
|
|
225
|
+
.squisq-page[data-underline='full-rule'] .squisq-page-section-title {
|
|
226
|
+
border-bottom: 1px solid var(--squisq-page-divider-color);
|
|
227
|
+
padding-bottom: 0.35em;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
.squisq-page-eyebrow {
|
|
231
|
+
display: block;
|
|
232
|
+
font-size: 0.8125rem;
|
|
233
|
+
font-weight: 600;
|
|
234
|
+
letter-spacing: 0.14em;
|
|
235
|
+
text-transform: uppercase;
|
|
236
|
+
color: var(--squisq-page-accent);
|
|
237
|
+
margin: 0 0 0.9em;
|
|
238
|
+
}
|
|
239
|
+
.squisq-page[data-eyebrow='numbered'] .squisq-page-eyebrow::after { content: ' —'; color: var(--squisq-page-text-muted); }
|
|
240
|
+
.squisq-page[data-eyebrow='mono-tag'] .squisq-page-eyebrow {
|
|
241
|
+
display: inline-block;
|
|
242
|
+
font-family: var(--squisq-page-mono-font);
|
|
243
|
+
text-transform: none;
|
|
244
|
+
letter-spacing: 0.06em;
|
|
245
|
+
border: 1px solid color-mix(in srgb, var(--squisq-page-accent) 55%, transparent);
|
|
246
|
+
border-radius: var(--squisq-page-radius);
|
|
247
|
+
padding: 0.15em 0.6em;
|
|
248
|
+
background: color-mix(in srgb, var(--squisq-page-accent) 10%, transparent);
|
|
249
|
+
}
|
|
250
|
+
.squisq-page[data-eyebrow='mono-tag'] .squisq-page-eyebrow::before { content: '['; opacity: 0.6; }
|
|
251
|
+
.squisq-page[data-eyebrow='mono-tag'] .squisq-page-eyebrow::after { content: ']'; opacity: 0.6; }
|
|
252
|
+
|
|
253
|
+
/* ── Hero ─────────────────────────────────────────────────────────── */
|
|
254
|
+
.squisq-page-section--hero { padding-block: calc(var(--squisq-page-section-pad) * 1.5); }
|
|
255
|
+
.squisq-page-hero-title {
|
|
256
|
+
font-family: var(--squisq-page-title-font);
|
|
257
|
+
font-weight: var(--squisq-page-title-weight);
|
|
258
|
+
line-height: 1.08;
|
|
259
|
+
margin: 0;
|
|
260
|
+
font-size: 2.75rem;
|
|
261
|
+
}
|
|
262
|
+
.squisq-page[data-heading-scale='display'] .squisq-page-hero-title { font-size: 3.4rem; }
|
|
263
|
+
.squisq-page[data-heading-scale='oversized'] .squisq-page-hero-title { font-size: 4rem; font-size: clamp(3rem, 9cqw, 6rem); line-height: 1.02; }
|
|
264
|
+
.squisq-page[data-heading-case='uppercase'] .squisq-page-hero-title { text-transform: uppercase; letter-spacing: 0.02em; }
|
|
265
|
+
.squisq-page-hero-subtitle {
|
|
266
|
+
margin: 1.1em 0 0;
|
|
267
|
+
font-size: 1.25rem;
|
|
268
|
+
color: var(--squisq-page-text-muted);
|
|
269
|
+
max-width: 42em;
|
|
270
|
+
white-space: pre-line;
|
|
271
|
+
}
|
|
272
|
+
.squisq-page-section--bg-media .squisq-page-hero-subtitle { color: rgba(255, 255, 255, 0.88); }
|
|
273
|
+
|
|
274
|
+
/* Stacked (default): centered column */
|
|
275
|
+
.squisq-page[data-hero-style='stacked'] .squisq-page-hero-body { text-align: center; }
|
|
276
|
+
.squisq-page[data-hero-style='stacked'] .squisq-page-hero-subtitle { margin-inline: auto; }
|
|
277
|
+
|
|
278
|
+
/* Oversized type: hard left, no decoration */
|
|
279
|
+
.squisq-page[data-hero-style='oversized-type'] .squisq-page-hero-title { font-size: 4.25rem; font-size: clamp(3.25rem, 10cqw, 6.5rem); line-height: 0.98; }
|
|
280
|
+
|
|
281
|
+
/* Split: text and media side by side */
|
|
282
|
+
.squisq-page-hero-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 3rem; align-items: center; }
|
|
283
|
+
.squisq-page-hero-grid .squisq-page-hero-media img { width: 100%; object-fit: cover; }
|
|
284
|
+
|
|
285
|
+
/* Full-bleed & letterbox: media behind text */
|
|
286
|
+
.squisq-page-section--hero-media {
|
|
287
|
+
padding-block: 0;
|
|
288
|
+
min-height: min(72svh, 620px);
|
|
289
|
+
display: flex;
|
|
290
|
+
align-items: flex-end;
|
|
291
|
+
}
|
|
292
|
+
.squisq-page[data-hero-style='letterbox'] .squisq-page-section--hero-media { min-height: min(52svh, 460px); }
|
|
293
|
+
.squisq-page-hero-backdrop { position: absolute; inset: 0; overflow: hidden; }
|
|
294
|
+
.squisq-page-hero-backdrop img { width: 100%; height: 100%; object-fit: cover; }
|
|
295
|
+
.squisq-page-hero-backdrop::after {
|
|
296
|
+
content: '';
|
|
297
|
+
position: absolute;
|
|
298
|
+
inset: 0;
|
|
299
|
+
background: linear-gradient(180deg, rgba(0, 0, 0, 0.1) 30%, rgba(0, 0, 0, 0.68) 100%);
|
|
300
|
+
}
|
|
301
|
+
.squisq-page[data-hero-style='letterbox'] .squisq-page-hero-backdrop img { filter: saturate(0.9); }
|
|
302
|
+
.squisq-page-section--hero-media .squisq-page-section-inner { padding-block: 3rem; width: 100%; }
|
|
303
|
+
|
|
304
|
+
/* ── Banner (sectionHeader) ───────────────────────────────────────── */
|
|
305
|
+
.squisq-page-banner-title { font-size: 2rem; }
|
|
306
|
+
.squisq-page[data-heading-scale='display'] .squisq-page-banner-title { font-size: 2.5rem; }
|
|
307
|
+
.squisq-page[data-heading-scale='oversized'] .squisq-page-banner-title { font-size: 3rem; font-size: clamp(2.25rem, 6cqw, 3.75rem); }
|
|
308
|
+
.squisq-page-section--banner.squisq-page-section--bg-media { padding-block: 0; min-height: 280px; display: flex; align-items: flex-end; }
|
|
309
|
+
.squisq-page-section--banner.squisq-page-section--bg-media .squisq-page-section-inner { padding-block: 2rem; width: 100%; }
|
|
310
|
+
.squisq-page-section--banner .squisq-page-section-title { margin-bottom: 0; }
|
|
311
|
+
|
|
312
|
+
/* ── Stat band ────────────────────────────────────────────────────── */
|
|
313
|
+
.squisq-page-stats { display: flex; gap: 3rem; justify-content: center; text-align: center; flex-wrap: wrap; }
|
|
314
|
+
.squisq-page-stat { flex: 1 1 220px; max-width: 420px; }
|
|
315
|
+
.squisq-page-stat-value {
|
|
316
|
+
display: block;
|
|
317
|
+
font-family: var(--squisq-page-title-font);
|
|
318
|
+
font-weight: 700;
|
|
319
|
+
font-size: 3.25rem;
|
|
320
|
+
line-height: 1;
|
|
321
|
+
color: var(--squisq-page-accent);
|
|
322
|
+
}
|
|
323
|
+
.squisq-page[data-numerals='oversized'] .squisq-page-stat-value { font-size: 4.5rem; font-size: clamp(3.5rem, 8cqw, 5.5rem); }
|
|
324
|
+
.squisq-page[data-numerals='mono'] .squisq-page-stat-value { font-family: var(--squisq-page-mono-font); letter-spacing: -0.02em; }
|
|
325
|
+
.squisq-page[data-numerals='boxed'] .squisq-page-stat-value {
|
|
326
|
+
display: inline-block;
|
|
327
|
+
border: 2px solid var(--squisq-page-accent);
|
|
328
|
+
border-radius: var(--squisq-page-radius);
|
|
329
|
+
padding: 0.18em 0.4em;
|
|
330
|
+
}
|
|
331
|
+
.squisq-page-stat-title { display: block; margin-top: 0.9em; font-size: 1.125rem; font-weight: 600; }
|
|
332
|
+
.squisq-page-stat-body { display: block; margin-top: 0.45em; color: var(--squisq-page-text-muted); font-size: 0.95rem; }
|
|
333
|
+
.squisq-page-stat-meta { text-align: center; margin-top: 1.5rem; color: var(--squisq-page-text-muted); font-size: 0.85rem; }
|
|
334
|
+
.squisq-page-stat-bar { height: 10px; border-radius: 999px; background: var(--squisq-page-accent); margin-top: 0.8em; }
|
|
335
|
+
.squisq-page-stat--bars { text-align: left; }
|
|
336
|
+
|
|
337
|
+
/* ── Quote band ───────────────────────────────────────────────────── */
|
|
338
|
+
.squisq-page-quote {
|
|
339
|
+
margin: 0;
|
|
340
|
+
font-family: var(--squisq-page-title-font);
|
|
341
|
+
font-size: 1.6rem;
|
|
342
|
+
line-height: 1.35;
|
|
343
|
+
white-space: pre-line;
|
|
344
|
+
}
|
|
345
|
+
.squisq-page-section--em-strong .squisq-page-quote { font-size: 2.1rem; }
|
|
346
|
+
.squisq-page-section--em-quiet .squisq-page-quote { font-size: 1.25rem; color: var(--squisq-page-text-muted); }
|
|
347
|
+
.squisq-page-quote-attribution { margin-top: 1.1em; font-family: var(--squisq-page-body-font); font-size: 0.95rem; color: var(--squisq-page-text-muted); }
|
|
348
|
+
.squisq-page-quote-attribution::before { content: '— '; }
|
|
349
|
+
.squisq-page[data-quote-mark='accent-bar'] .squisq-page-quote-figure { border-left: 4px solid var(--squisq-page-accent); padding-left: 1.5rem; }
|
|
350
|
+
.squisq-page[data-quote-mark='oversized-glyph'] .squisq-page-quote-figure { position: relative; padding-top: 1.25rem; }
|
|
351
|
+
.squisq-page[data-quote-mark='oversized-glyph'] .squisq-page-quote-figure::before {
|
|
352
|
+
content: '\\201C';
|
|
353
|
+
position: absolute;
|
|
354
|
+
top: -0.12em;
|
|
355
|
+
left: -0.05em;
|
|
356
|
+
font-family: var(--squisq-page-title-font);
|
|
357
|
+
font-size: 5.5rem;
|
|
358
|
+
line-height: 1;
|
|
359
|
+
color: color-mix(in srgb, var(--squisq-page-accent) 42%, transparent);
|
|
360
|
+
pointer-events: none;
|
|
361
|
+
}
|
|
362
|
+
.squisq-page-section--v-display .squisq-page-quote-figure { text-align: center; border-left: none; }
|
|
363
|
+
.squisq-page-section--v-display .squisq-page-quote { font-size: 2.4rem; font-size: clamp(1.9rem, 5cqw, 3rem); }
|
|
364
|
+
.squisq-page-section--v-editorial .squisq-page-quote-figure {
|
|
365
|
+
border-block: 3px solid var(--squisq-page-primary);
|
|
366
|
+
border-left: none;
|
|
367
|
+
padding: 2rem 0.5rem;
|
|
368
|
+
}
|
|
369
|
+
/* Full-bleed quote over media */
|
|
370
|
+
.squisq-page-section--quote-band.squisq-page-section--bg-media { padding-block: 0; min-height: 380px; display: flex; align-items: center; }
|
|
371
|
+
.squisq-page-section--quote-band.squisq-page-section--bg-media .squisq-page-section-inner { padding-block: 3.5rem; }
|
|
372
|
+
.squisq-page-quote-backdrop { position: absolute; inset: 0; overflow: hidden; }
|
|
373
|
+
.squisq-page-quote-backdrop img, .squisq-page-quote-backdrop video { width: 100%; height: 100%; object-fit: cover; }
|
|
374
|
+
.squisq-page-quote-backdrop::after { content: ''; position: absolute; inset: 0; background: rgba(0, 0, 0, 0.55); }
|
|
375
|
+
.squisq-page-section--quote-band[data-hint-vignette] .squisq-page-quote-backdrop::after {
|
|
376
|
+
background: radial-gradient(ellipse at center, rgba(0, 0, 0, 0.35) 0%, rgba(0, 0, 0, 0.75) 100%);
|
|
377
|
+
}
|
|
378
|
+
.squisq-page-section--quote-band.squisq-page-section--bg-media .squisq-page-quote-figure { border: none; text-align: center; }
|
|
379
|
+
|
|
380
|
+
/* ── Feature split ────────────────────────────────────────────────── */
|
|
381
|
+
.squisq-page-feature { display: grid; grid-template-columns: 1fr 1fr; gap: 3rem; align-items: center; }
|
|
382
|
+
.squisq-page-feature--media-right .squisq-page-feature-media { order: 2; }
|
|
383
|
+
.squisq-page-feature-media img { width: 100%; object-fit: cover; }
|
|
384
|
+
.squisq-page-feature-title { font-size: 1.75rem; }
|
|
385
|
+
.squisq-page-feature-body { color: var(--squisq-page-text-muted); font-size: 1.05rem; white-space: pre-line; margin: 0; }
|
|
386
|
+
|
|
387
|
+
/* ── Media figure ─────────────────────────────────────────────────── */
|
|
388
|
+
.squisq-page-figure { margin: 0; }
|
|
389
|
+
.squisq-page-figure img, .squisq-page-figure video { width: 100%; display: block; }
|
|
390
|
+
.squisq-page-figure figcaption { margin-top: 0.9em; font-size: 0.9rem; color: var(--squisq-page-text-muted); text-align: center; }
|
|
391
|
+
.squisq-page-media-credit { font-size: 0.78rem; opacity: 0.75; }
|
|
392
|
+
|
|
393
|
+
/* Media frame treatment (figures, features, gallery tiles, cards) */
|
|
394
|
+
.squisq-page-media-frame { overflow: hidden; }
|
|
395
|
+
.squisq-page[data-framing='rounded'] .squisq-page-media-frame { border-radius: var(--squisq-page-radius); }
|
|
396
|
+
.squisq-page[data-framing='bordered'] .squisq-page-media-frame { border: 3px solid var(--squisq-page-text); }
|
|
397
|
+
.squisq-page[data-framing='polaroid'] .squisq-page-media-frame {
|
|
398
|
+
background: #ffffff;
|
|
399
|
+
padding: 10px 10px 16px;
|
|
400
|
+
border: 1px solid rgba(0, 0, 0, 0.12);
|
|
401
|
+
border-radius: 2px;
|
|
402
|
+
}
|
|
403
|
+
.squisq-page[data-framing='letterboxed'] .squisq-page-media-frame img { aspect-ratio: 21 / 9; object-fit: cover; }
|
|
404
|
+
.squisq-page[data-framing='circle-accent'] .squisq-page-media-frame { border-radius: calc(var(--squisq-page-radius) * 2); }
|
|
405
|
+
.squisq-page .squisq-page-media-frame { box-shadow: var(--squisq-page-shadow); }
|
|
406
|
+
|
|
407
|
+
/* Rich body nodes that the selected template did not consume. This universal
|
|
408
|
+
* supplement keeps diagrams/media visible without making every template
|
|
409
|
+
* duplicate the same preservation logic. */
|
|
410
|
+
.squisq-page-rich-content {
|
|
411
|
+
margin-top: clamp(1.5rem, 4vw, 3rem);
|
|
412
|
+
padding-top: clamp(1.25rem, 3vw, 2rem);
|
|
413
|
+
border-top: 1px solid var(--squisq-page-divider-color);
|
|
414
|
+
}
|
|
415
|
+
.squisq-page-rich-content :is(img, video) { display: block; max-width: 100%; height: auto; margin-inline: auto; }
|
|
416
|
+
.squisq-page-rich-content .squisq-md-mermaid { min-height: min(520px, 62vh); margin-block: 0; }
|
|
417
|
+
|
|
418
|
+
/* ── Gallery ──────────────────────────────────────────────────────── */
|
|
419
|
+
.squisq-page-gallery { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1.25rem; }
|
|
420
|
+
.squisq-page-gallery .squisq-page-media-frame img { width: 100%; height: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
|
|
421
|
+
.squisq-page-gallery-caption { margin-top: 1.1rem; text-align: center; font-size: 0.9rem; color: var(--squisq-page-text-muted); }
|
|
422
|
+
|
|
423
|
+
/* ── Callout ──────────────────────────────────────────────────────── */
|
|
424
|
+
.squisq-page-callout {
|
|
425
|
+
border-radius: var(--squisq-page-radius);
|
|
426
|
+
border: 1px solid color-mix(in srgb, var(--squisq-page-accent) 32%, transparent);
|
|
427
|
+
border-left: 5px solid var(--squisq-page-accent);
|
|
428
|
+
background: color-mix(in srgb, var(--squisq-page-accent) 7%, var(--squisq-page-bg));
|
|
429
|
+
padding: 1.75rem 2rem;
|
|
430
|
+
box-shadow: var(--squisq-page-shadow);
|
|
431
|
+
display: flex;
|
|
432
|
+
gap: 1.75rem;
|
|
433
|
+
align-items: flex-start;
|
|
434
|
+
}
|
|
435
|
+
.squisq-page-callout-title { font-family: var(--squisq-page-title-font); font-size: 1.35rem; font-weight: 700; margin: 0 0 0.5em; }
|
|
436
|
+
.squisq-page-callout-body { margin: 0; white-space: pre-line; }
|
|
437
|
+
.squisq-page-callout-meta { margin-top: 0.9em; font-size: 0.82rem; color: var(--squisq-page-text-muted); }
|
|
438
|
+
.squisq-page-callout .squisq-page-media-frame { flex: 0 0 132px; }
|
|
439
|
+
.squisq-page-callout .squisq-page-media-frame img { width: 132px; height: 132px; object-fit: cover; }
|
|
440
|
+
.squisq-page-callout[data-hint-framing='circle-accent'] .squisq-page-media-frame,
|
|
441
|
+
.squisq-page-callout[data-hint-framing='circle-accent'] .squisq-page-media-frame img { border-radius: 50%; }
|
|
442
|
+
.squisq-page-section--v-definition .squisq-page-callout-title { font-style: italic; }
|
|
443
|
+
.squisq-page-section--v-diagnostic .squisq-page-callout { border-left-color: var(--squisq-page-highlight); }
|
|
444
|
+
|
|
445
|
+
/* ── Card grid ────────────────────────────────────────────────────── */
|
|
446
|
+
.squisq-page-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 1.5rem; }
|
|
447
|
+
.squisq-page-card {
|
|
448
|
+
border-radius: var(--squisq-page-radius);
|
|
449
|
+
background: var(--squisq-page-bg-alt);
|
|
450
|
+
border-top: 4px solid var(--squisq-page-card-accent, var(--squisq-page-accent));
|
|
451
|
+
padding: 1.75rem 1.75rem 1.9rem;
|
|
452
|
+
box-shadow: var(--squisq-page-shadow);
|
|
453
|
+
}
|
|
454
|
+
.squisq-page-card-title { font-family: var(--squisq-page-title-font); font-size: 1.3rem; margin: 0 0 0.4em; }
|
|
455
|
+
.squisq-page-card-body { margin: 0; color: var(--squisq-page-text-muted); white-space: pre-line; }
|
|
456
|
+
.squisq-page-cards-title { text-align: center; font-size: 1.9rem; margin-bottom: 1.75rem; }
|
|
457
|
+
|
|
458
|
+
/* ── Item list ────────────────────────────────────────────────────── */
|
|
459
|
+
.squisq-page-items { list-style: none; margin: 0; padding: 0; counter-reset: squisq-item; max-width: 40em; }
|
|
460
|
+
.squisq-page-items li {
|
|
461
|
+
counter-increment: squisq-item;
|
|
462
|
+
position: relative;
|
|
463
|
+
padding: 0.9em 0 0.9em 3.4em;
|
|
464
|
+
font-size: 1.1rem;
|
|
465
|
+
}
|
|
466
|
+
.squisq-page-items li + li { border-top: 1px solid var(--squisq-page-divider-color); }
|
|
467
|
+
.squisq-page-items li::before {
|
|
468
|
+
content: counter(squisq-item, decimal-leading-zero);
|
|
469
|
+
position: absolute;
|
|
470
|
+
left: 0;
|
|
471
|
+
top: 0.85em;
|
|
472
|
+
font-family: var(--squisq-page-title-font);
|
|
473
|
+
font-weight: 700;
|
|
474
|
+
color: var(--squisq-page-accent);
|
|
475
|
+
font-size: 1.15em;
|
|
476
|
+
}
|
|
477
|
+
.squisq-page[data-numerals='mono'] .squisq-page-items li::before { font-family: var(--squisq-page-mono-font); }
|
|
478
|
+
.squisq-page-items-title { font-size: 1.9rem; }
|
|
479
|
+
|
|
480
|
+
/* ── Timeline rail (dateEvent) ────────────────────────────────────── */
|
|
481
|
+
.squisq-page-section--timeline-rail { padding-block: 1.4rem; }
|
|
482
|
+
.squisq-page-section--timeline-rail:first-child { padding-top: var(--squisq-page-section-pad); }
|
|
483
|
+
.squisq-page-milestone { display: grid; grid-template-columns: 150px 1fr; gap: 2rem; align-items: baseline; position: relative; }
|
|
484
|
+
.squisq-page-milestone-date {
|
|
485
|
+
font-family: var(--squisq-page-title-font);
|
|
486
|
+
font-weight: 700;
|
|
487
|
+
color: var(--squisq-page-accent);
|
|
488
|
+
font-size: 1.05rem;
|
|
489
|
+
text-align: right;
|
|
490
|
+
}
|
|
491
|
+
.squisq-page-milestone-rail {
|
|
492
|
+
position: absolute;
|
|
493
|
+
left: 166px;
|
|
494
|
+
top: -1.4rem;
|
|
495
|
+
bottom: -1.4rem;
|
|
496
|
+
width: 2px;
|
|
497
|
+
background: color-mix(in srgb, var(--squisq-page-accent) 35%, transparent);
|
|
498
|
+
}
|
|
499
|
+
.squisq-page-milestone-rail::after {
|
|
500
|
+
content: '';
|
|
501
|
+
position: absolute;
|
|
502
|
+
left: 50%;
|
|
503
|
+
top: 0.55em;
|
|
504
|
+
width: 12px;
|
|
505
|
+
height: 12px;
|
|
506
|
+
border-radius: 50%;
|
|
507
|
+
transform: translateX(-50%);
|
|
508
|
+
background: var(--squisq-page-accent);
|
|
509
|
+
border: 2px solid var(--squisq-page-bg);
|
|
510
|
+
}
|
|
511
|
+
.squisq-page-milestone-body { padding-left: 2.25rem; white-space: pre-line; }
|
|
512
|
+
.squisq-page-milestone-footer { margin-top: 0.5em; font-size: 0.85rem; color: var(--squisq-page-text-muted); }
|
|
513
|
+
|
|
514
|
+
/* ── Table section ────────────────────────────────────────────────── */
|
|
515
|
+
.squisq-page-table-title { font-size: 1.9rem; }
|
|
516
|
+
.squisq-page-table-scroll { overflow-x: auto; border-radius: var(--squisq-page-radius); box-shadow: var(--squisq-page-shadow); }
|
|
517
|
+
.squisq-page-table { width: 100%; border-collapse: collapse; font-size: 0.98rem; }
|
|
518
|
+
.squisq-page-table th {
|
|
519
|
+
background: var(--squisq-page-accent-bg);
|
|
520
|
+
color: var(--squisq-page-accent-text);
|
|
521
|
+
font-family: var(--squisq-page-title-font);
|
|
522
|
+
text-align: left;
|
|
523
|
+
padding: 0.8em 1em;
|
|
524
|
+
}
|
|
525
|
+
.squisq-page-table td { padding: 0.7em 1em; border-top: 1px solid var(--squisq-page-divider-color); }
|
|
526
|
+
.squisq-page-table tbody tr:nth-child(even) { background: color-mix(in srgb, var(--squisq-page-text) 3.5%, transparent); }
|
|
527
|
+
|
|
528
|
+
/* ── Canvas embed (spatial SVG) ───────────────────────────────────── */
|
|
529
|
+
.squisq-page-canvas {
|
|
530
|
+
width: 100%;
|
|
531
|
+
margin-inline: auto;
|
|
532
|
+
overflow: hidden;
|
|
533
|
+
border-radius: var(--squisq-page-radius);
|
|
534
|
+
}
|
|
535
|
+
.squisq-page-canvas svg { display: block; width: 100%; height: 100%; }
|
|
536
|
+
.squisq-page-canvas--framed { border: 1px solid var(--squisq-page-divider-color); box-shadow: var(--squisq-page-shadow); }
|
|
537
|
+
.squisq-page-canvas--terminal { border: 1px solid color-mix(in srgb, var(--squisq-page-accent) 45%, transparent); }
|
|
538
|
+
.squisq-page-canvas--terminal::before {
|
|
539
|
+
content: '\\25CF \\25CF \\25CF';
|
|
540
|
+
display: block;
|
|
541
|
+
font-size: 9px;
|
|
542
|
+
letter-spacing: 4px;
|
|
543
|
+
padding: 6px 12px;
|
|
544
|
+
color: color-mix(in srgb, var(--squisq-page-accent) 70%, transparent);
|
|
545
|
+
background: color-mix(in srgb, var(--squisq-page-accent) 9%, var(--squisq-page-bg));
|
|
546
|
+
border-bottom: 1px solid color-mix(in srgb, var(--squisq-page-accent) 30%, transparent);
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
/* ── Prose ────────────────────────────────────────────────────────── */
|
|
550
|
+
.squisq-page-section--prose { padding-block: calc(var(--squisq-page-section-pad) * 0.45); }
|
|
551
|
+
.squisq-page[data-divider] .squisq-page-section--prose + .squisq-page-section--prose { border-top: none; }
|
|
552
|
+
.squisq-page-prose { font-size: 1.05rem; }
|
|
553
|
+
.squisq-page-prose p { margin: 0; }
|
|
554
|
+
.squisq-page-prose p + p { margin-top: 1.25em; }
|
|
555
|
+
.squisq-page-prose > * + * { margin-top: 1.1em; }
|
|
556
|
+
.squisq-page-prose a { color: var(--squisq-page-primary); text-decoration-color: color-mix(in srgb, var(--squisq-page-primary) 40%, transparent); }
|
|
557
|
+
.squisq-page-prose code { font-family: var(--squisq-page-mono-font); font-size: 0.9em; background: color-mix(in srgb, var(--squisq-page-text) 8%, transparent); border-radius: 4px; padding: 0.12em 0.35em; }
|
|
558
|
+
.squisq-page-prose pre { background: color-mix(in srgb, var(--squisq-page-text) 6%, transparent); border-radius: var(--squisq-page-radius); padding: 1em 1.25em; overflow-x: auto; }
|
|
559
|
+
.squisq-page-prose pre code { background: none; padding: 0; }
|
|
560
|
+
.squisq-page-prose blockquote { margin: 0; border-left: 4px solid var(--squisq-page-accent); padding-left: 1.25em; color: var(--squisq-page-text-muted); }
|
|
561
|
+
.squisq-page-prose ul, .squisq-page-prose ol { padding-left: 1.5em; margin: 0; }
|
|
562
|
+
.squisq-page-prose li + li { margin-top: 0.4em; }
|
|
563
|
+
.squisq-page-prose hr { border: none; border-top: 1px solid var(--squisq-page-divider-color); }
|
|
564
|
+
.squisq-page-prose table { width: 100%; border-collapse: collapse; }
|
|
565
|
+
.squisq-page-prose th { font-family: var(--squisq-page-title-font); text-align: left; padding: 0.6em 0.8em; border-bottom: 2px solid var(--squisq-page-divider-color); }
|
|
566
|
+
.squisq-page-prose td { padding: 0.55em 0.8em; border-bottom: 1px solid var(--squisq-page-divider-color); }
|
|
567
|
+
.squisq-page-prose img { border-radius: var(--squisq-page-radius); }
|
|
568
|
+
.squisq-page-prose h1, .squisq-page-prose h2, .squisq-page-prose h3,
|
|
569
|
+
.squisq-page-prose h4, .squisq-page-prose h5, .squisq-page-prose h6 {
|
|
570
|
+
font-family: var(--squisq-page-title-font);
|
|
571
|
+
font-weight: var(--squisq-page-title-weight);
|
|
572
|
+
line-height: 1.2;
|
|
573
|
+
margin: 0 0 0.45em;
|
|
574
|
+
}
|
|
575
|
+
.squisq-page-prose h1 { font-size: 2.1rem; }
|
|
576
|
+
.squisq-page-prose h2 { font-size: 1.65rem; }
|
|
577
|
+
.squisq-page-prose h3 { font-size: 1.35rem; }
|
|
578
|
+
.squisq-page-prose h4, .squisq-page-prose h5, .squisq-page-prose h6 { font-size: 1.15rem; }
|
|
579
|
+
.squisq-page-section--prose[data-hint-drop-cap] .squisq-page-prose > p:first-child::first-letter {
|
|
580
|
+
font-family: var(--squisq-page-title-font);
|
|
581
|
+
font-size: 3.4em;
|
|
582
|
+
font-weight: 700;
|
|
583
|
+
float: left;
|
|
584
|
+
line-height: 0.85;
|
|
585
|
+
padding-right: 0.12em;
|
|
586
|
+
color: var(--squisq-page-accent);
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
/* ── Footer band ──────────────────────────────────────────────────── */
|
|
590
|
+
.squisq-page-section--footer { text-align: center; }
|
|
591
|
+
|
|
592
|
+
/* ── Thin-margin embedding (chat bubbles) ─────────────────────────── */
|
|
593
|
+
.squisq-page--thin .squisq-page-section-inner { padding-inline: 0; }
|
|
594
|
+
.squisq-page--thin .squisq-page-section { padding-block: 1.5rem; }
|
|
595
|
+
|
|
596
|
+
/* Thumbnail image mode */
|
|
597
|
+
.squisq-page--thumbnail-images .squisq-page-prose img,
|
|
598
|
+
.squisq-page--thumbnail-images .squisq-page-figure img { max-width: 100px; max-height: 100px; object-fit: cover; }
|
|
599
|
+
|
|
600
|
+
/* ── Reveal animation (progressive enhancement) ───────────────────── */
|
|
601
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
602
|
+
.squisq-page-reveal { opacity: 0; transform: translateY(14px); transition: opacity 0.55s ease, transform 0.55s ease; }
|
|
603
|
+
.squisq-page-reveal--in { opacity: 1; transform: none; }
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
/* ── Responsive ───────────────────────────────────────────────────── */
|
|
607
|
+
@container squisq-page (max-width: 720px) {
|
|
608
|
+
${NARROW_RULES}
|
|
609
|
+
}
|
|
610
|
+
@supports not (container-type: inline-size) {
|
|
611
|
+
@media (max-width: 720px) {
|
|
612
|
+
${NARROW_RULES}
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
`;
|
|
616
|
+
|
|
617
|
+
/**
|
|
618
|
+
* Complete stylesheet for a themed page: a `.squisq-page { … }` variable
|
|
619
|
+
* block followed by the structural CSS. For string-HTML consumers; the
|
|
620
|
+
* React view sets the vars inline instead.
|
|
621
|
+
*/
|
|
622
|
+
export function buildPageCss(theme?: Theme): string {
|
|
623
|
+
const vars = buildPageCssVars(theme);
|
|
624
|
+
const varLines = Object.entries(vars)
|
|
625
|
+
.map(([name, value]) => ` ${name}: ${value};`)
|
|
626
|
+
.join('\n');
|
|
627
|
+
return `.squisq-page {\n${varLines}\n}\n${PAGE_BASE_CSS}`;
|
|
628
|
+
}
|
|
@@ -49,6 +49,7 @@ export interface FirstImage {
|
|
|
49
49
|
export function extractBodyPlainText(contents?: MarkdownBlockNode[]): string {
|
|
50
50
|
if (!contents || contents.length === 0) return '';
|
|
51
51
|
return contents
|
|
52
|
+
.filter((node) => !(node.type === 'code' && node.lang?.trim().toLowerCase() === 'mermaid'))
|
|
52
53
|
.map((n) => extractPlainText(n))
|
|
53
54
|
.join('\n')
|
|
54
55
|
.trim();
|
package/src/schemas/Doc.ts
CHANGED
|
@@ -381,7 +381,8 @@ export type Layer =
|
|
|
381
381
|
| MapLayer
|
|
382
382
|
| VideoLayer
|
|
383
383
|
| TableLayer
|
|
384
|
-
| TreeLayer
|
|
384
|
+
| TreeLayer
|
|
385
|
+
| MermaidLayer;
|
|
385
386
|
|
|
386
387
|
interface BaseLayer {
|
|
387
388
|
/** Unique identifier for this layer */
|
|
@@ -759,6 +760,26 @@ export interface TreeLayerStyle {
|
|
|
759
760
|
fileIcon?: string;
|
|
760
761
|
}
|
|
761
762
|
|
|
763
|
+
/**
|
|
764
|
+
* Mermaid diagram layer — renders an authored `mermaid` code fence through
|
|
765
|
+
* the official Mermaid runtime while keeping the fence source authoritative.
|
|
766
|
+
* Like video/table/tree layers, the browser renderer hosts the diagram in an
|
|
767
|
+
* SVG `<foreignObject>` so it participates in slide layout and frame capture.
|
|
768
|
+
*/
|
|
769
|
+
export interface MermaidLayer extends BaseLayer {
|
|
770
|
+
type: 'mermaid';
|
|
771
|
+
content: {
|
|
772
|
+
/** Complete Mermaid source, excluding the Markdown fence delimiters. */
|
|
773
|
+
source: string;
|
|
774
|
+
/** Theme-derived panel color behind the generated SVG. */
|
|
775
|
+
background?: string;
|
|
776
|
+
/** Theme-derived foreground used by loading/error states. */
|
|
777
|
+
foreground?: string;
|
|
778
|
+
/** Inner panel padding in pixels. */
|
|
779
|
+
padding?: number;
|
|
780
|
+
};
|
|
781
|
+
}
|
|
782
|
+
|
|
762
783
|
/**
|
|
763
784
|
* Available map tile styles from free/open-source providers.
|
|
764
785
|
*/
|