# Product hero mockup — light stage, 3D device render, floating gradient insight cards, AI chat panel

Learned 2026-08-13 replicating reference R#7 (node 200:4493, a flattened
raster of an accounting-automation SaaS hero shot → replica on new page
"SaaS Automation", frame `R#7-replica` 203:10, Quorra v.0). First entry in
this ledger for a "product marketing hero" genre: a photorealistic 3D
device render composited with a flat dashboard UI, rather than the
glass-panel or duotone-poster genres already logged.

- **A projective device-mockup composite cannot be rebuilt as a projective
  transform — Figma nodes are affine-only.** The reference sits a real
  UI on a perspective-tilted virtual plane with true foreshortening
  (parallel lines converge, far elements shrink); Figma's `relativeTransform`
  is a 2D affine matrix (rotation, scale, shear) with no vanishing point.
  Medium decision, recorded with the user rather than attempted: the
  dashboard UI was rebuilt flat/undistorted (real text, real vector
  shapes, correct relative proportions), and only the closed-laptop
  hardware — real device photography, unreproducible as vector at this
  fidelity — was kept as an image citation, cropped from the reference
  and masked to its own silhouette so it composites over the flat UI
  exactly where the reference's laptop occludes its floating panels.
- **A rectangular crop of a composited photo drags in whatever else sits
  in that rectangle.** The first laptop crop (a plain bounding box) baked
  in fragments of the reference's OWN ghost-panel text ("Average Account
  Stats", "56,1%") that sat above the laptop's true silhouette edge —
  duplicating content already rebuilt natively one layer below, a same-
  session echo of this ledger's earlier "judge by effect on the
  background" discipline but for a raster asset instead of a blur. Fixed
  by tracing the silhouette (column-wise scan for near-neutral gray
  pixels, `sips`-cropped and sampled) into a polygon and using it as a
  Figma vector mask, so only the true device pixels render and the
  rebuilt UI shows through everywhere else.
- **Figma's mask direction is the opposite of layer-stack intuition: the
  mask must be the FIRST child (bottom of z-order), not the last
  (top).** Per the Plugin API's own doc for `isMask`, a mask node masks
  its *subsequent* siblings — the ones listed *after* it in the
  `children` array, which render *above* it. Placing the mask node last
  (as in Photoshop/Sketch, where the mask sits visually on top) masks
  nothing, since nothing comes after it; the laptop crop rendered fully
  unmasked, silently reproducing the exact leak the mask was built to
  fix, until the ordering was reversed (`layer.insertChild(0, mask)`).
- **`vectorPaths` assignment auto-computes `node.x`/`node.y` from the
  path's bounding box — setting them afterward re-offsets the whole
  shape.** Echoes this ledger's earlier vector-rebase lesson (*Duotone
  poster app* entry) but for position, not icon placement: a mask
  polygon authored in frame-absolute coordinates (`M 0 996 L …`) had its
  auto-assigned origin (`x:0, y:870`, the path's true bounding-box
  top-left) overwritten by an explicit `mask.x = 0; mask.y = 0` issued
  right after — shifting the whole polygon up by 870px and silently
  disabling the intended clip. Confirmed by reading `mask.x/y` back
  immediately after assignment, before touching them: if they don't
  already match the intended placement, the path data is wrong, not the
  node's position — fix the path, don't override the auto-derived
  transform.
- **A translucent "stacked sheet" motif needs real alpha, not a lighter
  opaque tint.** The reference's fanned card-behind-card effect (also
  present on the left dashboard cluster, one card ghosted behind another)
  reads as glass specifically because the rearmost sheets let whatever
  sits behind them — including a card's own header row — show through
  faintly. Building the back sheets as opaque pale-green fills (instead
  of `opacity < 1` on a saturated fill) visually erased the "Anomalies"
  card header sitting underneath, caught by a blind diff pass as a
  missing element rather than an occlusion choice.
- **Emoji characters used as icon glyphs render in their native color,
  not the text node's fill.** A "⚡" character set with a dark fill still
  rendered bright orange/yellow — Figma renders certain Unicode ranges
  (emoji-presentation codepoints) as color glyphs regardless of the
  `fills` property, silently ignoring the intended monochrome color. Fix:
  build icon glyphs (bolt, sparkle, check) as simple `vectorPaths` shapes
  with an explicit solid fill, never as a colored-emoji character standing
  in for an icon.
- **Percent signs in the reference's big numerals are true superscripts**
  (smaller size, raised baseline), not full-cap-height characters inline
  with the digits — `setRangeFontSize` on just the `%` character's index
  range reproduces it without a separate text node.
- **Connotes**: a real 3D-rendered device in front of a dematerialized,
  semi-transparent UI reads as "the software is bigger than the screen it
  runs on" — the product overflows its hardware, a common SaaS-marketing
  move distinct from this ledger's screen-in-frame entries (*Clinical
  Wellness*, *Duotone poster*) where the UI stays confined to a device
  bezel. The fanned, rotated duplicate cards (the same "Account Insights"
  message repeated three times at decreasing opacity) stage a single
  static fact as if it were actively arriving — motion implied without
  animation, the same rhetorical move as a drop shadow implying depth
  without a z-axis. A single saturated accent (mint green) carrying every
  live number against black/white/gray is this ledger's now-familiar
  "one accent = the signal" discipline (*Edge-lit active row*, *Clinical
  Wellness*), here spent on financial anomalies rather than vitals or
  state — the accent means "this changed since last time," full stop,
  regardless of genre.
