"""Generate the .nav-fern watermark scene: a wide, NON-repeating composition. Lush redesign (v2.47.0): the old "stick figure" fronds were too skinny. Now each side gets a layered pair -- a big bold foreground frond with wide, veined leaflets plus a smaller, paler frond behind it for depth. Stems are thicker, leaflets are larger with side veins, opacity is a touch stronger. Still a watermark (sage over navy), just one with actual presence. Builds one wide scene (1440x120): fronds sweep in from the bottom-left and bottom-right and fade out, flowing *under* the nav words along the bottom edge rather than sitting behind every button. Everything fades to transparent at the scene edges so cropping never shows a hard cutoff. Outputs the CSS background-image data URI. """ import math from urllib.parse import quote W, H = 1440, 120 def fmt(v): s = f"{v:.1f}" return s[:-2] if s.endswith(".0") else s def cubic(p0, p1, p2, p3, t): x = (1 - t) ** 3 * p0[0] + 3 * (1 - t) ** 2 * t * p1[0] + 3 * (1 - t) * t ** 2 * p2[0] + t ** 3 * p3[0] y = (1 - t) ** 3 * p0[1] + 3 * (1 - t) ** 2 * t * p1[1] + 3 * (1 - t) * t ** 2 * p2[1] + t ** 3 * p3[1] return (x, y) def cubic_tangent(p0, p1, p2, p3, t): dx = 3 * (1 - t) ** 2 * (p1[0] - p0[0]) + 6 * (1 - t) * t * (p2[0] - p1[0]) + 3 * t ** 2 * (p3[0] - p2[0]) dy = 3 * (1 - t) ** 2 * (p1[1] - p0[1]) + 6 * (1 - t) * t * (p2[1] - p1[1]) + 3 * t ** 2 * (p3[1] - p2[1]) n = math.hypot(dx, dy) or 1.0 return (dx / n, dy / n) def frond_paths(p0, p1, p2, p3, n_pairs=26, leaf_base=32.0, leaf_tip=6.0, tilt_deg=28.0, up_scale=0.62, width_factor=0.44, side_veins=True): """One arching frond: stem + paired wide leaflets with veins + tip curl.""" paths = [] paths.append( ("stem", f"M{fmt(p0[0])} {fmt(p0[1])} " f"C{fmt(p1[0])} {fmt(p1[1])} {fmt(p2[0])} {fmt(p2[1])} {fmt(p3[0])} {fmt(p3[1])}") ) tx, ty = cubic(p0, p1, p2, p3, 1.0) tan = cubic_tangent(p0, p1, p2, p3, 1.0) ang = math.atan2(tan[1], tan[0]) + math.radians(150) curl_r = 4.5 paths.append( ("stem", f"M{fmt(tx)} {fmt(ty)} q{fmt(math.cos(ang) * curl_r)} {fmt(math.sin(ang) * curl_r)} " f"{fmt(math.cos(ang + 1.2) * curl_r)} {fmt(math.sin(ang + 1.2) * curl_r)}") ) tilt = math.radians(tilt_deg) cos_t, sin_t = math.cos(tilt), math.sin(tilt) for i in range(n_pairs): t = 0.04 + (0.92 - 0.04) * i / (n_pairs - 1) px, py = cubic(p0, p1, p2, p3, t) ux, uy = cubic_tangent(p0, p1, p2, p3, t) L = leaf_base + (leaf_tip - leaf_base) * (t / 0.92) for side in (1, -1): nx, ny = (-uy * side, ux * side) dx = nx * cos_t + ux * sin_t dy = ny * cos_t + uy * sin_t n = math.hypot(dx, dy) or 1.0 dx, dy = dx / n, dy / n Lside = L * up_scale if dy < 0 else L # upward leaflets stay short tipx, tipy = px + dx * Lside, py + dy * Lside w = Lside * width_factor mx, my = px + dx * Lside * 0.52, py + dy * Lside * 0.52 wx, wy = -dy * w, dx * w # Wide lens-shaped leaflet blade. paths.append( ("leaf", f"M{fmt(px)} {fmt(py)} " f"Q{fmt(mx + wx)} {fmt(my + wy)} {fmt(tipx)} {fmt(tipy)} " f"Q{fmt(mx - wx)} {fmt(my - wy)} {fmt(px)} {fmt(py)} Z") ) # Center vein. paths.append(("vein", f"M{fmt(px)} {fmt(py)} L{fmt(tipx)} {fmt(tipy)}")) # Side veins on the bigger leaflets. if side_veins and Lside > 15: for f in (0.35, 0.62): vx, vy = px + dx * Lside * f, py + dy * Lside * f vw = w * 0.55 * (1 - f * 0.5) paths.append( ("vein", f"M{fmt(vx)} {fmt(vy)} " f"l{fmt((-dy * 0.7 + dx * 0.35) * vw)} {fmt((dx * 0.7 + dy * 0.35) * vw)}") ) paths.append( ("vein", f"M{fmt(vx)} {fmt(vy)} " f"l{fmt((dy * 0.7 + dx * 0.35) * vw)} {fmt((-dx * 0.7 + dy * 0.35) * vw)}") ) return paths # One dramatic frond per side: rises from the bottom corner, arches inward, # tips stop before the center (no crossing). # (Compositions live under __main__ so gen_fern_hero.py can reuse the builders.) def fade(id_, color, peak): return ( f"" f"" f"" f"" f"" f"" f"" ) def group(paths, grad_id, stem_w): stems = "".join(f"" for kind, d in paths if kind == "stem") leaves = "".join(f"" for kind, d in paths if kind == "leaf") veins = "".join(f"" for kind, d in paths if kind == "vein") return ( f"" # Stems: gradient stroke. f"{stems}" # Leaflets: FILLED with the gradient (this is what makes them lush # instead of stick-figure outlines), thin gradient edge for crispness. f"{leaves}" # Veins: carved in dark navy at low opacity for leaf detail. f"{veins}" f"" ) def main(): fore_left = frond_paths((40, 118), (250, 110), (480, 60), (620, 30), n_pairs=20, leaf_base=46.0, leaf_tip=5.0, tilt_deg=32.0, up_scale=0.70, width_factor=0.36, side_veins=True) fore_right = frond_paths((1400, 118), (1190, 110), (960, 60), (820, 30), n_pairs=20, leaf_base=46.0, leaf_tip=5.0, tilt_deg=32.0, up_scale=0.70, width_factor=0.36, side_veins=True) svg = ( f"" f"{fade('fadeFore', '#a4c09d', 0.20)}" f"{group(fore_left, 'fadeFore', 3.4)}" f"{group(fore_right, 'fadeFore', 3.4)}" f"" ) uri = "data:image/svg+xml," + quote(svg, safe="()*,;:@/?~!$&'") n_paths = sum(len(p) for p in (fore_left, fore_right)) print(f"paths: {n_paths}; uri chars: {len(uri)}") print("---- preview svg ----") print(svg.replace( "viewBox='0 0 1440 120'", "viewBox='0 0 1440 120' style='background:#1b2a4a;display:block'")) print("---- css ----") print(".nav-fern {") print(f" background-image: url(\"{uri}\");") print(" background-repeat: no-repeat;") print(" background-size: cover;") print(" background-position: bottom center;") print("}") if __name__ == "__main__": main()