);
}
function Vignette({ strength = 0.6 }) {
return (
);
}
function Letterbox() {
return (
<>
>
);
}
// Tree silhouettes — feathered tops, vertical strokes
function TreeBand({ y = 600, height = 200, density = 14, color = G.forestDeep, seed = 1, opacity = 1 }) {
// Deterministic pseudo-random
const rand = (i) => {
const x = Math.sin(seed * 37 + i * 91) * 10000;
return x - Math.floor(x);
};
const trees = [];
for (let i = 0; i < density; i++) {
const x = (i / density) * 100 + (rand(i) - 0.5) * 4;
const h = 0.55 + rand(i + 100) * 0.45;
const w = 5 + rand(i + 200) * 7;
trees.push(
);
}
return (
);
}
// Mountain silhouettes — jagged ridge line
function MountainRidge({ y = 400, height = 240, color = G.coldBlue, seed = 1, opacity = 1 }) {
const rand = (i) => {
const x = Math.sin(seed * 53 + i * 67) * 10000;
return x - Math.floor(x);
};
const points = ['0,100'];
const steps = 18;
for (let i = 0; i <= steps; i++) {
const x = (i / steps) * 100;
const peakH = 35 + rand(i) * 50;
points.push(`${x},${100 - peakH}`);
}
points.push('100,100');
return (
);
}
// Sun shafts — radial gleam suggesting golden-hour light through trees
function SunShaft({ x = '60%', y = '40%', size = 600, color = G.amberSoft }) {
return (
);
}
// Floating dust particles
function Particles({ count = 30, seed = 1, opacity = 0.4 }) {
const time = useTime();
const dots = [];
for (let i = 0; i < count; i++) {
const r1 = ((Math.sin(seed * 13 + i * 31) + 1) * 50);
const r2 = ((Math.sin(seed * 7 + i * 47) + 1) * 50);
const drift = Math.sin(time * 0.3 + i) * 1.5;
const bob = Math.sin(time * 0.6 + i * 1.3) * 1;
const size = 1.2 + ((Math.sin(seed + i * 5) + 1) * 0.8);
dots.push(
);
}
return
{dots}
;
}
// ── Phone composition wrapper ──────────────────────────────────────────────
// Renders an iPhone shell at given transform with the given screen inside.
function PhoneFrame({ children, scale = 1, x = 0, y = 0, rotate = 0, glow = false }) {
return (