{"spec_id":"area-elevation-profile","library":"makie","language":"julia","code":"# anyplot.ai\n# area-elevation-profile: Terrain Elevation Profile Along Transect\n# Library: makie 0.22.10 | Julia 1.11.9\n# Quality: 90/100 | Created: 2026-06-10\n\nusing CairoMakie\nusing Colors\nusing Random\n\nRandom.seed!(42)\n\n# Theme tokens\nconst THEME       = get(ENV, \"ANYPLOT_THEME\", \"light\")\nconst PAGE_BG     = THEME == \"light\" ? colorant\"#FAF8F1\" : colorant\"#1A1A17\"\nconst ELEVATED_BG = THEME == \"light\" ? colorant\"#FFFDF6\" : colorant\"#242420\"\nconst INK         = THEME == \"light\" ? colorant\"#1A1A17\" : colorant\"#F0EFE8\"\nconst INK_SOFT    = THEME == \"light\" ? colorant\"#4A4A44\" : colorant\"#B8B7B0\"\nconst INK_MUTED   = THEME == \"light\" ? colorant\"#6B6A63\" : colorant\"#A8A79F\"\nconst FILL_ALPHA  = THEME == \"light\" ? 0.28f0 : 0.42f0\n\nconst IMPRINT_PALETTE = [\n    colorant\"#009E73\",  # 1 — brand green (first series, always)\n    colorant\"#C475FD\",  # 2 — lavender\n    colorant\"#4467A3\",  # 3 — blue\n    colorant\"#BD8233\",  # 4 — ochre\n    colorant\"#AE3030\",  # 5 — matte red (semantic: bad/loss)\n    colorant\"#2ABCCD\",  # 6 — cyan\n    colorant\"#954477\",  # 7 — rose\n    colorant\"#99B314\",  # 8 — lime\n]\n\n# Data: Fictional alpine traverse — 80 km route across passes and summits\nwp_dist = [  0.0,  10.0,  18.0,  26.0,  35.0,  45.0,  60.0,  70.0,  80.0]\nwp_elev = [950.0, 1600.0, 2750.0, 2050.0, 3180.0, 2600.0, 2900.0, 2150.0, 1050.0]\n\nn = 320\ndistance = collect(range(0.0, 80.0, length=n))\n\nfunction lerp_elev(d)\n    for i in 2:length(wp_dist)\n        if d <= wp_dist[i]\n            t = (d - wp_dist[i-1]) / (wp_dist[i] - wp_dist[i-1])\n            return wp_elev[i-1] + t * (wp_elev[i] - wp_elev[i-1])\n        end\n    end\n    return wp_elev[end]\nend\n\nelev_base = lerp_elev.(distance)\n\nfunction gauss_smooth(v, sigma)\n    nv = length(v)\n    ks = round(Int, 3 * sigma)\n    result = similar(v, Float64)\n    for i in 1:nv\n        s = 0.0; w = 0.0\n        for j in max(1, i - ks):min(nv, i + ks)\n            wj = exp(-0.5 * ((j - i) / sigma)^2)\n            s += wj * v[j]; w += wj\n        end\n        result[i] = s / w\n    end\n    return result\nend\n\n# Terrain micro-texture via superimposed sinusoids (no cumulative drift)\nterrain_noise = zeros(n)\nfor freq in [4, 9, 17, 29]\n    terrain_noise .+= randn() .* sin.(range(0.0, Float64(freq) * π, length=n) .+ rand() * 2π)\nend\nterrain_noise = gauss_smooth(terrain_noise, 3.0) .* 28.0\n\nelevation = elev_base .+ terrain_noise\n\n# Key landmarks — pairs of (distance_km, label)\nlm_dists   = [  0.0,       18.0,          35.0,          45.0,          60.0,       80.0]\nlm_labels  = [\"Trailhead\", \"First Pass\", \"Summit Peak\", \"Col de Neige\", \"Grand Col\", \"Trail End\"]\nlm_idx     = [argmin(abs.(distance .- d)) for d in lm_dists]\nlm_elevs   = elevation[lm_idx]\nlm_offsets = [180.0, 180.0, 200.0, -230.0, 180.0, 180.0]\nlm_valigns = [:bottom, :bottom, :bottom, :top, :bottom, :bottom]\nlm_haligns = [:left,   :center, :center,  :center,        :center,     :right  ]\n\nconst TITLE = \"area-elevation-profile · julia · makie · anyplot.ai\"\ntitle_fontsize = 20  # 51 chars < 67 baseline — no scaling needed\n\n# Figure\nfig = Figure(\n    size            = (1600, 900),\n    fontsize        = 14,\n    backgroundcolor = PAGE_BG,\n)\n\nax = Axis(\n    fig[1, 1];\n    title              = TITLE,\n    titlesize          = title_fontsize,\n    titlecolor         = INK,\n    xlabel             = \"Distance (km)\",\n    ylabel             = \"Elevation (m)\",\n    xlabelsize         = 14,\n    ylabelsize         = 14,\n    xlabelcolor        = INK,\n    ylabelcolor        = INK,\n    xticklabelsize     = 12,\n    yticklabelsize     = 12,\n    xticklabelcolor    = INK_SOFT,\n    yticklabelcolor    = INK_SOFT,\n    xtickcolor         = INK_SOFT,\n    ytickcolor         = INK_SOFT,\n    backgroundcolor    = PAGE_BG,\n    topspinevisible    = false,\n    rightspinevisible  = false,\n    leftspinecolor     = INK_SOFT,\n    bottomspinecolor   = INK_SOFT,\n    xgridvisible       = false,\n    ygridcolor         = RGBAf(INK.r, INK.g, INK.b, 0.12),\n    yminorgridvisible  = false,\n    xminorgridvisible  = false,\n    limits             = (0.0, 82.0, 500.0, 3700.0),\n)\n\n# Filled terrain silhouette (Imprint brand green; alpha higher on dark for equal visual weight)\nband!(ax, distance, fill(500.0, n), elevation;\n      color = RGBAf(IMPRINT_PALETTE[1].r, IMPRINT_PALETTE[1].g, IMPRINT_PALETTE[1].b, FILL_ALPHA))\n\n# Profile line\nlines!(ax, distance, elevation;\n       color = IMPRINT_PALETTE[1], linewidth = 2.5)\n\n# Landmark annotations — Summit Peak gets extra emphasis as the highest point\nfor i in 1:length(lm_dists)\n    d    = lm_dists[i]\n    name = lm_labels[i]\n    elev = lm_elevs[i]\n    off  = lm_offsets[i]\n    va   = lm_valigns[i]\n\n    is_summit = (name == \"Summit Peak\")\n    msize     = is_summit ? 13 : 9\n    mstroke   = is_summit ? 2.5f0 : 1.5f0\n\n    # Connector line from terrain point to label position\n    lines!(ax, [d, d], [elev, elev + off];\n           color = RGBAf(INK_MUTED.r, INK_MUTED.g, INK_MUTED.b, 0.5),\n           linewidth = 0.8)\n\n    # Dot marker at elevation (Summit Peak larger for focal hierarchy)\n    scatter!(ax, [d], [elev];\n             color = IMPRINT_PALETTE[1], markersize = msize,\n             strokecolor = PAGE_BG, strokewidth = mstroke)\n\n    # Label: name + elevation; 13 pt for mobile readability\n    text!(ax, d, elev + off;\n          text     = \"$(name)\\n$(round(Int, elev)) m\",\n          align    = (lm_haligns[i], va),\n          fontsize = 13,\n          color    = INK_SOFT)\nend\n\n# Vertical exaggeration note (bottom-right)\ntext!(ax, 80.0, 540.0;\n      text     = \"VE ≈ 15×\",\n      align    = (:right, :bottom),\n      fontsize = 13,\n      color    = INK_MUTED)\n\nsave(\"plot-$(THEME).png\", fig; px_per_unit = 2)\n"}