launchframe 0.1.5 → 0.1.6

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.
@@ -170,6 +170,120 @@ export interface DesignSystem {
170
170
  notes: string[];
171
171
  }
172
172
 
173
+ /* -------------------------------------------------------------------------- */
174
+ /* Layout mirror (per-site) */
175
+ /* -------------------------------------------------------------------------- */
176
+
177
+ /**
178
+ * Structural roles a top-level section can play. Inferred heuristically from
179
+ * geometry, content kinds, and document position — not from the source's
180
+ * class names.
181
+ */
182
+ export type SectionRole =
183
+ | "nav"
184
+ | "hero"
185
+ | "feature-grid"
186
+ | "feature-deep-dive"
187
+ | "proof-logos"
188
+ | "proof-quotes"
189
+ | "pricing"
190
+ | "conversion"
191
+ | "footer"
192
+ | "other";
193
+
194
+ /**
195
+ * Coarse composition shape used by the emitter to pick a wrapper layout.
196
+ */
197
+ export type Composition =
198
+ | "single-column"
199
+ | "split-2"
200
+ | "grid-2"
201
+ | "grid-3"
202
+ | "grid-4"
203
+ | "list"
204
+ | "logo-row"
205
+ | "unknown";
206
+
207
+ /**
208
+ * The kinds of content a section can hold. The emitter renders an
209
+ * appropriately-styled placeholder (`<TextSlot>` / `<MediaSlot>`) per slot
210
+ * so the user fills in their own copy and assets.
211
+ */
212
+ export type SlotKind =
213
+ | "heading-1"
214
+ | "heading-2"
215
+ | "heading-3"
216
+ | "eyebrow"
217
+ | "body"
218
+ | "bullet"
219
+ | "button-primary"
220
+ | "button-secondary"
221
+ | "image"
222
+ | "logo-mono"
223
+ | "icon"
224
+ | "code"
225
+ | "badge"
226
+ | "input"
227
+ | "video";
228
+
229
+ export interface SlotCount {
230
+ kind: SlotKind;
231
+ count: number;
232
+ }
233
+
234
+ /**
235
+ * A single top-level section in document order. Geometry is normalized to
236
+ * [0, 1] over the rendered page so the emitter can compare relative weight.
237
+ */
238
+ export interface SectionLayout {
239
+ /** Stable id assigned in document order: s1, s2, ... */
240
+ id: string;
241
+ role: SectionRole;
242
+ composition: Composition;
243
+ density: "thin" | "balanced" | "dense";
244
+ /** Bounding box [x, y, w, h] normalized to [0, 1] over the rendered page. */
245
+ bbox: [number, number, number, number];
246
+ /** Aggregated content-kind counts inside the section. */
247
+ slots: SlotCount[];
248
+ /** Per-section style hints; the emitter applies these as inline overrides. */
249
+ styles: {
250
+ backgroundHex: string | null;
251
+ foregroundHex: string | null;
252
+ paddingTopPx: number | null;
253
+ paddingBottomPx: number | null;
254
+ };
255
+ /** Free-form notes the emitter surfaces in `MIRROR_NOTES.md`. */
256
+ notes: string[];
257
+ }
258
+
259
+ /**
260
+ * Page-level computed-style tokens. These complement the synthesized
261
+ * `DesignSystem` so a mirror page can apply a site-specific theme without
262
+ * the system having to reseed the cross-corpus palette.
263
+ */
264
+ export interface SiteTokens {
265
+ bodyFontFamily: string;
266
+ headingFontFamily: string;
267
+ backgroundHex: string;
268
+ foregroundHex: string;
269
+ primaryHex: string;
270
+ mutedHex: string;
271
+ borderHex: string;
272
+ radiusPx: number;
273
+ containerPx: number | null;
274
+ }
275
+
276
+ export interface SiteLayout {
277
+ url: string;
278
+ host: string;
279
+ capturedAt: string;
280
+ viewport: { width: number; height: number };
281
+ /** Full rendered page height in CSS pixels. */
282
+ pageHeightPx: number;
283
+ sections: SectionLayout[];
284
+ tokens: SiteTokens;
285
+ }
286
+
173
287
  /* -------------------------------------------------------------------------- */
174
288
  /* Run summary */
175
289
  /* -------------------------------------------------------------------------- */
@@ -180,6 +294,10 @@ export interface SiteCapture {
180
294
  capturedAt: string;
181
295
  screenshotPath: string;
182
296
  rawTokensPath: string;
297
+ /** Path to the per-site `SiteLayout` JSON, if the mirror crawl succeeded. */
298
+ layoutPath?: string;
299
+ /** Path to the per-site mirror page directory, if emission succeeded. */
300
+ mirrorDir?: string;
183
301
  status: "ok" | "skipped" | "failed";
184
302
  reason?: string;
185
303
  }