{
  "$schema_note": "Canonical machine-readable style spec for the author's Julia/Makie scientific figures. Reconciled to author notes + key renders. Use to generate a Makie theme + plotting helpers.",
  "identity": {
    "name": "Open-Marker LaTeX Scientific House Style",
    "base_backend": "CairoMakie (export); GLMakie/WGLMakie (interactive)",
    "base_theme": "ggthemr(:fresh)",
    "theme_set_pattern": "set_theme!(ggthemr(:fresh)) inside each plotting function",
    "typography_engine": "LaTeXStrings + MathTeXEngine (texfont)",
    "signatures": [
      "All titles/labels are LaTeX L\"\\text{...}\"",
      "Tick labels in texfont(:bolditalic) (slanted bold-italic serif numerals)",
      "Open white-filled markers with colored strokes, drawn last in z-order",
      "Color-matched capped error bars drawn behind markers",
      "Triple-redundant series encoding: color + marker shape + linestyle held constant across a panel series",
      "(n=X) surfaced in title, legend label, or per-point",
      "Significance = square U-bracket + single star + literal (p=...)",
      "Red dashed physics fit curve",
      "High-res PNG export (px_per_unit 5 or 12) + SVG vector"
    ],
    "branches": {
      "legacy": "scatterlines! single-call; SEM error bars; Shapiro-Wilk; ** for p<0.01",
      "current": "separate errorbars!+scatter!; 95% CI (1.96*SEM) or LMM CI; Jarque-Bera+KS; single-star+p only",
      "slate_text": "explicit titlecolor/labelcolor/spinecolor overrides (#2C3E50/#34495E/#BDC3C7) + L-spine open frame",
      "plain_theme": "ggthemr(:fresh) defaults kept (full frame), no slate overrides (RFA, EKG)"
    }
  },
  "typography": {
    "fonts": {
      "title": "texfont(:bold)",
      "title_concrete_face": "TeX Gyre Heros Bold",
      "axis_labels_2d": "L\"\\text{...}\" (CMU-regular weight); force texfont(:regular) on plain-string labels to match",
      "axis_labels_3d": "texfont(:italic)",
      "tick_labels": "texfont(:bolditalic)",
      "tick_labels_slate_branch": {"x": "texfont(:bold)", "y": "texfont(:bolditalic)"},
      "n_labels": "texfont(:bolditalic) (current) or plain (legacy black series)",
      "pvalue_and_star": "texfont(:bold)",
      "legend_labels": "texfont(:bold)",
      "spanning_label_title": "texfont(:bold) / \"TeX Gyre Heros Bold\""
    },
    "sizes_by_role": {
      "figure_fontsize": {"author_notes_default": 13, "small_production": [15, 16], "large_ekg": [28, 30, 35], "ladder": [13, 14, 15, 16, 18, 20, 28, 30]},
      "titlesize": {"dominant_default": 17, "rnew_stats": 19, "slate_omny": 22, "titration": 19, "pf_unconstrained_axis": 22, "spanning_label": 26, "ekg": 35, "ekg_radar": 30},
      "axis_label_size": {"inherits": true, "explicit_small": [17, 18], "explicit_large": [20, 22, 33, 35]},
      "tick_label_size": {"inherits": true, "small": 16, "rnew": 17, "ekg": [20, 25], "omny_slate": 16},
      "n_label_size": {"small": [12, 14, 15], "large": 18},
      "star_size": {"rfa": 20, "rnew": 28},
      "pvalue_size": {"rfa": [11, 12], "rnew": 19},
      "legend_labelsize": {"small": [12, 16], "ekg": 30, "depth_enchan_horizontal": 12}
    },
    "latex": {
      "wrap_prose_in_text": true,
      "label_example": "L\"\\text{RFA Delivery Duration (sec)}\"",
      "superscript_units": "L\"\\text{Estimated Lesion Volume (mm}^3\\text{)}\"",
      "greek_inline": "L\"\\text{Impedance Drop (}\\Omega\\text{)}\"",
      "italic_emphasis": "L\"\\text{Voltage (mV, \\textit{baseline corrected})}\"",
      "bold_title_variant": "L\"\\textbf{Ablation Depth by Delivery Group}\"",
      "units_always_parenthesized": true,
      "rich_text_for_log_ticks": "rich(\"10\", superscript(\" $(Int64(log10(value)))\"))",
      "ylabelrotation_2pi_upright": {
        "snippet": "ylabelrotation = 2π   # upright y-label; pair with xticklabelrotation = π/4 (diagonal x-ticks)",
        "status": "known author idiom, DEFAULT OFF (disabled in current production), provide as opt-in"
      }
    }
  },
  "palette": {
    "named_colors": {
      "black": "#000000",
      "red": "#FF0000",
      "blue": "#0000FF",
      "white": "#FFFFFF",
      "fara_crimson": "#D12429",
      "vari1_belize_blue": "#3498DB",
      "vari2_navy": "#1B4F72",
      "vari1_steelblue_alt": "#4682B4",
      "vari2_darkblue_alt": "#00008B",
      "stsf_slate": "#2C3E50",
      "wet_asphalt": "#34495E",
      "legend_frame_gray": "#BDC3C7",
      "violin_volume_dusty_purple": "#6C5B7B",
      "violin_depth_navy": "#1B4F72",
      "rnew_20w_blue": "RGBf(0.00,0.45,0.70)",
      "rnew_30w_brick_red": "RGBf(0.65,0.20,0.22)",
      "rnew_titration_forest_green": "RGBf(0.09,0.42,0.12)",
      "titration_teal_30w": "RGBf(0.05,0.55,0.55)",
      "titration_purple": "purple",
      "ae_bar_darkgray_30w": "darkgray",
      "omny_green": "#27AE60",
      "omny_magenta": "#E91E63",
      "omny_orange": "#E67E22",
      "omny_purple": "#8E44AD",
      "omny_black": "#000000",
      "omny_goldenrod": "#B8860B",
      "omny_gray_fallback": "#7F8C8D",
      "lv_tissue_tan": "#cfa37a",
      "rv_tissue_slate_blue": "#7a9fcf",
      "depth_enchan_750v_blue": "#2E86C1",
      "depth_enchan_950v_red": "#E74C3C",
      "enchan_creatinine_green": "#27AE60",
      "enchan_tbili_orange": "#F39C12",
      "egh_saline_mauve_fill": "#B0A0B5",
      "egh_saline_plum_edge": "#6E4C6B",
      "egh_hydrogel_steel_fill": "#9DB6C4",
      "egh_hydrogel_teal_edge": "#3E6478",
      "egh_adas_saline_cornflower": "#AED4EC",
      "egh_adas_hydrogel_coral": "#F4B6B0",
      "raw_dot_red": "#FF0000",
      "grid_mid_gray": "RGBf(0.45,0.45,0.45)",
      "sig_bracket_near_black": "RGBf(0.20,0.20,0.20)"
    },
    "categorical_cycle": [
      {"idx": 1, "color_generic": "#000000", "color_pfa": "#D12429", "color_rnew": "RGBf(0.00,0.45,0.70)", "marker": "circle", "linestyle": "solid"},
      {"idx": 2, "color_generic": "#FF0000", "color_pfa": "#3498DB", "color_rnew": "RGBf(0.65,0.20,0.22)", "marker": "rect", "marker_alt": "utriangle", "linestyle": "dash"},
      {"idx": 3, "color_generic": "#0000FF", "color_pfa": "#1B4F72", "color_rnew": "RGBf(0.09,0.42,0.12)", "marker": "utriangle", "marker_alt": "rect", "linestyle": "dot"},
      {"idx": 4, "color_generic": "#2C3E50", "color_pfa": "#2C3E50", "marker": "diamond", "linestyle": "dashdot"}
    ],
    "categorical_cycle_concrete": {
      "rfa_generic": {"strokes": ["black", "red", "blue"], "markers": ["circle", "utriangle", "rect"], "linestyles": ["solid", "dash", "dot"]},
      "pfa_cohorts": {"colors": ["#D12429", "#3498DB", "#1B4F72", "#2C3E50"], "markers": ["circle", "rect", "utriangle", "diamond"], "linestyles": ["solid", "dash", "dot", "dashdot"]},
      "rnew_cohorts": {"colors": ["RGBf(0.00,0.45,0.70)", "RGBf(0.65,0.20,0.22)", "RGBf(0.09,0.42,0.12)"], "markers": ["circle", "diamond", "utriangle"], "marker_chronic": "rect", "linestyles": ["dash", "dashdot", "dot"], "linestyle_chronic": "dashdotdot"},
      "crowded_dynamic": {"strategy": "name-keyed color+marker (stable), linestyle assigned dynamically by descending peak value", "linestyle_cycle": ["solid", "dash", "dot", "dashdot"]}
    },
    "semantic": {
      "primary_series": "black",
      "second_series": "red",
      "third_series": "blue",
      "fourth_series": "#2C3E50",
      "physics_fit_curve": "red (always :dash, lw 2)",
      "raw_overlay_dots": "coral/red (filled, semi-transparent)",
      "open_marker_fill": "white",
      "FARA_FARAWAVE": "#D12429",
      "VARI1_commercial": "#3498DB",
      "VARI2_fast": "#1B4F72",
      "dual_energy_STSF": "#2C3E50",
      "rfa_20W": "RGBf(0.00,0.45,0.70) blue",
      "rfa_30W": "RGBf(0.65,0.20,0.22) brick red",
      "rfa_titration": "RGBf(0.09,0.42,0.12) green (or :purple legacy)",
      "title_text_slate": "#2C3E50",
      "axis_furniture_slate": "#34495E",
      "legend_frame_slate": "#BDC3C7",
      "gridline": "(:gray, 0.3)",
      "LV_tissue": "#cfa37a",
      "RV_tissue": "#7a9fcf",
      "ekg_color_semantics": {"black": "raw/primary", "red": "lowpass", "blue": "highpass/QRS", "green": "P-wave/passband", "orange": "T-wave/peaks"}
    },
    "alpha": {
      "raw_dots": [0.7, 0.4, 0.3],
      "violin_body_fill": 0.35,
      "violin_mean_bar": 0.8,
      "violin_sd_line": 0.6,
      "violin_sd_caps": 0.4,
      "gridlines": [0.3, 0.40],
      "legend_background_ekg": 0.8,
      "legend_background_slate": 0.95,
      "axis_background_slate": 0.95,
      "penumbra_outer_3d_shell": 0.5,
      "passband_band": 0.2,
      "rnew_ci_by_idx": {"1": 0.85, "2": 0.95, "3": 1.0}
    },
    "authoritative_rule": "The hex value is canonical over any source code comment (comments occasionally mislabel #000000 as 'teal' and #B8860B as 'goldenrod')."
  },
  "markers": {
    "open_marker_rule": {
      "description": "Summary/mean markers are hollow: white fill + colored stroke, drawn LAST (top of z-order).",
      "separated_form": "scatter!(ax, x, y; color=:white, marker=:circle, markersize=12, strokecolor=series_color, strokewidth=1)",
      "scatterlines_form": "scatterlines!(ax, x, y; linewidth=3, color=:black, marker=:circle, markercolor=:white, markersize=10, strokecolor=:black, strokewidth=1)",
      "exception": "Raw/individual observation dots and accent peaks are SOLID filled (coral (:red,0.7) raw, :orange peaks, :black jitter). Open-white rule applies to summary markers only."
    },
    "sizes": {
      "signature_scatterlines": 10,
      "standard_mean": 12,
      "legend_markerelement": 12,
      "titration_violin_enchan": 14,
      "rnew_solo_interactive": 15,
      "rnew_overlay_ekg_fft_bode": [20, 22, 25],
      "raw_jittered": [7, 8],
      "diagnostic_unfolded": 3
    },
    "strokewidths": {"standard": 1.0, "titration": 1.2, "slate_mean_and_legend": 1.5, "rnew_solo": 1.8, "rnew_overlay_enchan": [2.0, 2.2], "black_stroked_mean": 2.5, "ekg": 3},
    "multiseries_rotation": {
      "shapes": ["circle", "utriangle", "rect", "diamond"],
      "shapes_pfa": ["circle", "rect", "utriangle", "diamond"],
      "shapes_rnew": ["circle", "rect", "diamond", "utriangle"],
      "strokes": ["black", "red", "blue"],
      "linestyles": ["solid", "dash", "dot", "dashdot"],
      "ekg_shape_semantics": {"circle": "raw", "utriangle": "lowpass", "rect": "bandpass"},
      "full_shape_vocabulary": ["circle", "rect", "utriangle", "diamond", "pentagon", "dtriangle", "star5", "star4", "xcross", "hexagon", "cross"],
      "rule": "color + shape + linestyle rotate in lockstep; in EKG-style overlays the LINE color stays black and the marker stroke carries identity"
    }
  },
  "lines": {
    "widths": {
      "signature_and_raw_ecg": 3,
      "standard_data_slate": 2.2,
      "scatterlines_connector_rfa": 1.8,
      "thin_secondary_connector": 1.2,
      "fit_curve_rfa": 2,
      "fit_curve_rnew": [2.2, 2.4],
      "ekg_data": 5,
      "legend_lineelement": 3.5,
      "spinewidth_slate": 2.5,
      "gridwidth": [1, 0.85],
      "sig_bracket": [1.3, 1.4],
      "bar_stroke": [1.4, 1.5]
    },
    "linestyles": {
      "vocabulary": ["solid", "dash", "dot", "dashdot", "dashdotdot"],
      "semantics": {
        "solid": "primary / observed data; error bars; brackets",
        "dash": "the red fitted model curve (always); secondary / lowpass series",
        "dot": "bandpass / third series",
        "dashdot": "fourth cohort",
        "dashdotdot": "rnew chronic cohort"
      },
      "fit_curve": "lines!(ax, range(min,max,length=100), y_model; color=:red, linestyle=:dash, linewidth=2)  # length 200 titration, 400 rnew",
      "smoothing": {"biomarker": "CubicSpline 200pts", "lw_jun17": "PCHIP monotone-cubic", "ordinal_dipstick": "straight segments", "physics": "stretched-exponential fit"}
    }
  },
  "axes": {
    "spines": {
      "full_frame": {"used_by": ["RFA time-series", "EKG", "RNew stats"], "how": "ggthemr(:fresh) default, spines untouched"},
      "l_spine_open": {"used_by": ["slate biomarker", "OMNY", "EGH violin/box", "pf_unconstrained"], "how": "topspinevisible=false, rightspinevisible=false, leftspinecolor=#34495E, bottomspinecolor=#34495E, spinewidth=2.5"},
      "all_hidden": {"used_by": ["3D Axis3 recon", "dummy title axes"], "how": "*spinesvisible=false / hidedecorations!"}
    },
    "limits": {
      "rfa_duration_x": "xlims!(ax, 35, 320)",
      "single_category_x": "xlims!(ax, 0.3, 1.7)",
      "y_dynamic": "computed from data with asymmetric headroom; e.g. ylims!(ax, yMin - yRange*0.06, yMax + yRange*0.15)",
      "violin_y": "ylims!(ax, min - range*0.25, max + range*0.25)",
      "bar_y": ["ylims!(ax, 0, 75)", "ylims!(ax, 0, 100)", "ylims!(ax, 0, 50)"],
      "slate_omny": "often auto (yticks drive grid density)",
      "rule": "reserve top y-headroom proportional to number of significance brackets"
    },
    "ticks": {
      "duration": "ax.xticks = 60:30:300",
      "categorical": "ax.xticks = (positions, [\"20W\",\"30W\"]) or (time_numeric, labels)",
      "ordinal_dipstick": "yticks = (0:3, [\"Normal\",\"Trace\",\"1+\",\"2+\"])",
      "timepoints": ["Baseline", "TP1", "TP2", "TP3", "TP4", "TP5", "TP6", "Final"],
      "timepoints_alt": [["Pre", "Post", "Chronic"], ["Baseline", "50% PFA", "100% PFA", "Final (2 Hr. Post PFA)"]],
      "depth_yticks": "0:1:12",
      "width_yticks": "0:2:18",
      "fine_y": "0:50:350",
      "log_bode": {"xscale": "log10", "xtickformat": "10^n via rich/superscript", "xminorticks": "IntervalsBetween(5)", "yticks": "[0;-3;-15;-25;-35;-45]"},
      "mm_formatter_3d": "ax.xtickformat = xs -> [\"$(round(x*conversionFactor, digits=2))\" for x in xs]"
    },
    "label_rotation": {
      "ylabelrotation_2pi_upright": "opt-in, default off",
      "xticklabelrotation_pi4_diagonal": "opt-in, default off",
      "force_horizontal_categorical": "ax.xticklabelrotation = 0",
      "yticklabelspace_hack": "ax.yticklabelspace = 24.0 on Depth plot to equalize axis-box width with Width/Volume",
      "label_padding": {"xlabelpadding": 15, "ylabelpadding": 20}
    }
  },
  "grid": {
    "default": "inherited from ggthemr(:fresh) (light dashed gray on muted panel); RFA/EKG never override",
    "explicit_slate_rnew": {
      "visible": {"x": true, "y": true},
      "style": ":dash",
      "color": ["(:gray, 0.3)", "(RGBf(0.45,0.45,0.45), 0.40)"],
      "width": [1, 0.85]
    },
    "bar_charts": {"xgridvisible": false, "ygridvisible": true, "ygrid_every": "10%"},
    "violin_box": "horizontal-only dashed gray grid",
    "3d_and_dummy": "all grids off",
    "fine_y_via_ticks": "yticks = 0:50:350"
  },
  "errorbars": {
    "call": "errorbars!(ax, x, y, err; whiskerwidth=5, color=series_color, linewidth=1.3, direction=:y)",
    "draw_order": "BEFORE markers",
    "color_matching": "ALWAYS matches series (never gray); exceptions depth_ENCHAN & lw-jun17 use :black",
    "whiskerwidth": {"rfa": 5, "titration": 6, "slate_omny_biomarker": 10, "depth_enchan": 12},
    "linewidth": {"rfa": 1.3, "titration": [1.5, 1.6], "slate_rnew_solo": 2.0, "rnew_overlay_by_idx": {"1": 2.4, "2": 2.8, "3": 3.0}, "lw_jun17": 2.5},
    "caps": "always capped (flat T-caps)",
    "represents": {
      "current_rfa": "95% CI half-width = 1.96 * std(y) / sqrt(n)",
      "rnew": "LMM 95% CI (emmeans/lmer) from R stats_results.json",
      "omny_biomarker_egh_lwjun17": "±1 SD = std(y)",
      "legacy_and_depth_enchan_bars": "SEM = std(y)/sqrt(n)"
    },
    "rule": "always state the convention in caption/label; suppress whisker where n<2 (substitute 0.0, no cap)",
    "manual_form_rnew": "three lines! calls (vertical bar + two flat caps) instead of errorbars!, with per-idx alpha to disambiguate overlapping CI bars",
    "violin_sd_glyph": "±SD I-bar: spine lw 2.5, caps lw 2, mean bar lw 2.8, linecap=:round, alpha-graded black 0.8/0.6/0.4"
  },
  "significance": {
    "bracket_shape": "square U-bracket: lines!(ax, [x1,x1,x2,x2], [y, y+barHeight, y+barHeight, y])",
    "bracket_shape_rnew": "downward ticks: [y-tick_h, y, y, y-tick_h], tick_h = 0.030*yrange",
    "bracket_color": ["black", "RGBf(0.20,0.20,0.20)"],
    "bracket_linewidth": [1.3, 1.4],
    "stacking": "one row per significant pair stacked upward; row spacing ~0.115*yrange; barHeight yRange*0.02-0.055; ylim top expanded per bracket; sorted by (dur_i, dur_j)",
    "p_format": {
      "current": "p<0.0001 -> 'p<0.0001'; p<0.001 -> 'p<0.001'; else @sprintf('p=%.3f', p); RFA uses round(pval, digits=4); wrapped in parens '(p=...)'",
      "example_outputs": ["* (p=0.047)", "* (p<0.0001)", "* (p<0.001)", "(p=0.0015)"]
    },
    "star_thresholds": {
      "current_default": "single '*' for any p<0.05, ALWAYS with literal p-value; no tiering",
      "legacy_console_lwjun17": {"***": "p<0.001", "**": "p<0.01", "*": "p<0.05", "dagger": "p<0.10", "NS": "else"}
    },
    "star_styling": {"size_rfa": 20, "size_rnew": 28, "font": "texfont(:bold)", "pvalue_size_rfa": [11, 12], "pvalue_size_rnew": 19, "layout": "horizontally centered via pixel-width estimate (p_w_px ~ 6.5*len, star_w_px ~ 14)"},
    "not_on_plot": "AE / Fisher's exact results go in the caption, not the plot",
    "note": "EKG bracket!(style=:curly) is an ANNOTATION bracket (Δt/amplitude labels for P/QRS/T), not significance"
  },
  "legend": {
    "axislegend_inside": {
      "calls": [
        "axislegend(ax, position=:rt, backgroundcolor=(:white, 0.8), patchsize=(80.0f0,50.0f0))",
        "axislegend(\"Signals\", framevisible=true, position=:rt, backgroundcolor=(:white, 0.8), patchsize=(80.0f0,50.0f0))",
        "axislegend(position=:rb, patchsize=(40.0f0, 20.0f0))"
      ],
      "position_codes": ["rt", "rb", "lt", "ct"],
      "background": ["(:white, 0.8)", "(:white, 0.95)"]
    },
    "standalone_legend_cell": {
      "placement": "outside-right fig[1,2] (plot ~2/3, legend 1/3) or below fig[2,1] orientation=:horizontal (bars)",
      "elements": "composite [LineElement(linewidth=3.5, linestyle), MarkerElement(color=:white, strokecolor=color, strokewidth=1.5, markersize=12)]",
      "styling": "framevisible=true, framecolor=#BDC3C7, framewidth=2, backgroundcolor=(:white,0.95), labelsize=16, labelcolor=#2C3E50, labelfont=texfont(:bold), patchsize=(35,20), rowgap=15, padding=(20,20,15,15)",
      "ordering": "peak-sorted descending: sort!(entries, by=e->e.peak, rev=true); rnew uses explicit LEGEND_POSITION_BY_IDX to put 30W first"
    },
    "n_count_convention": {
      "in_label": "\"FARAWAVE (n=3)\"",
      "in_title": "\"... (n=3/group)\"",
      "per_tick_label": "\"Baseline (n=5)\"",
      "per_point_floating": "text!(ax, \"n=$(n)\", position=(xi,yi), align=(:left,:bottom), offset=(-32,22), fontsize=12, color=:black)"
    },
    "omission": "frequently omitted for single-series figures (guarded by if length(dataTypes) > 1), replaced by inline n= labels",
    "value_range_labels_ekg": "labels embed value ranges with arrows e.g. \"Heart Rate\\n(min BPM -> max BPM)\""
  },
  "figure": {
    "sizes": {
      "house_default": "(700, 500)",
      "facet_side_by_side": "(1400, 500)",
      "ekg_wide": ["(1400, 800)", "(1600, 800)"],
      "titration": "(800, 560)",
      "pf_unconstrained": "(1000, 600)",
      "slate_omny_legend_right": "(1200, 600)",
      "biomarker_3cohort": "(1100, 600)",
      "enchan_single_series": "(900, 600)",
      "rnew_solo": "(820, 620)",
      "rnew_overlay": "(920, 680)",
      "rnew_ae_bar": "(560, 560)",
      "recon_3d": "(900, 900) figure_padding=0",
      "rpeak_strip": "(1800, 200)",
      "depth_enchan_bar": "(600, 500)",
      "lw_jun17": "(900, 650)"
    },
    "fontsize": {"author_notes_default": 13, "production": [15, 16], "titration": 18, "pf_unconstrained": 20, "ekg": [28, 30], "lw_jun17": 14},
    "background": "white; axis (:white, 0.95) in slate branch",
    "layout": {
      "single_axis": "f[1,1] (most figures)",
      "facet": "f[1,1] + f[1,2], shared ticks, colsize!(f.layout, 1, Relative(0.5))",
      "spanning_title": "Label(f[0,:], text, fontsize=26, font=texfont(:bold), halign=:center)",
      "nested_gridlayout": "f[1,1][1,1:2] + f[1,1][1,3:5] with dummy axis for shared title and Bottom()-anchored Label for shared x-title",
      "faceting_across_files": "often separate PNG per (cohort, metric) rather than GridLayout"
    },
    "resolution": {
      "px_per_unit": {"rfa_production_rnew": 5, "slate_biomarker_omny": 12, "lw_jun17": 4, "simple_figs": "unset (1x)"},
      "note": "12x on 1200x600 -> ~14400x7200 px"
    },
    "export_formats": {
      "primary": "PNG via save(path, f, px_per_unit=N)",
      "vector": "SVG (EKG saves SVG exclusively; RFA SVG/PDF saves exist but commented)",
      "dir_pattern": "mkpath(\"figures/exports\") then save under it; anchored with @__DIR__ in some repos",
      "filenames": ["2acute_volume.png", "overlay_clean_volume.png", "ae_pop_rate.png", "pFhgb_all_catheters.png"],
      "display": "display(f) or bare f for interactive render"
    }
  },
  "archetypes": [
    {
      "id": "A1",
      "name": "Mean ± CI saturation curve over duration (with physics fit)",
      "description": "CORE archetype. Per-duration mean as open white circle + matched-color error bars + per-point n= labels + red dashed stretched-exponential fit + black significance U-brackets with exact p-values.",
      "makie_calls": ["errorbars!(whiskerwidth=5, lw 1.3)", "lines!(red, :dash, lw 2) fit", "scatter!(color=:white, marker=:circle, markersize=12, strokecolor, strokewidth=1)", "text! n=", "lines! U-bracket + text! star/p"],
      "defaults": {"marker": "circle", "fit": ":red :dash lw2", "draw_order": "errorbars -> fit -> markers -> n -> brackets", "do": "draw markers last; reserve y-headroom per bracket", "dont": "gray the whiskers; use straight fit"}
    },
    {
      "id": "A2",
      "name": "Multi-cohort temporal overlay",
      "description": "Several cohorts on one axis distinguished by rotating shape+color+linestyle; per-cohort color-matched error bars and n-labels. RNew uses 3 z-ordered passes.",
      "makie_calls": ["repeated errorbars!+scatter! (+lines! connector)", "plot_titration_overlay!", "axislegend or right-cell Legend"],
      "defaults": {"passes": "fits -> CI bars -> markers+legend", "overlay_fit": "lighten(c, 0.10)", "do": "stagger n-label per idx", "dont": "two overlapping cohorts share a dash"}
    },
    {
      "id": "A3",
      "name": "scatterlines mean-over-line (legacy single-call)",
      "description": "Older variant where connecting line and open markers are one call.",
      "makie_calls": ["scatterlines!(linewidth=1.8, color=:black, marker=:circle, markercolor=:white, markersize=10..12, strokecolor=:black, strokewidth=1)", "errorbars!"],
      "defaults": {"do": "keep markercolor=:white", "dont": "mix with separated form in same figure"}
    },
    {
      "id": "A4",
      "name": "Saturation / physics-fit overlay",
      "description": "Fitted diffusion-plateau model y=y_inf*[1-exp(-t/tau)]^beta drawn as smooth red dashed curve over means.",
      "makie_calls": ["lines!(range(min,max,length=100), model(x,p), color=:red, linestyle=:dash, linewidth=2)"],
      "defaults": {"beta": "0.5 depth/width (1D), 1.5 volume (3D)", "smooth_len": [100, 200, 400]}
    },
    {
      "id": "A5",
      "name": "Multi-series temporal mean±SD line (smoothed)",
      "description": "CORE for slate/OMNY/biomarker. CubicSpline-smoothed line + color-matched SD error bars + open white markers; right-cell composite Legend; (n=X) in labels/title.",
      "makie_calls": ["CubicSpline -> lines!(2.2)", "errorbars!(±SD, color-matched, direction=:y)", "scatter!(open white)", "Legend(fig[1,2], composite elements)"],
      "defaults": {"smooth": "CubicSpline 200pt", "do": "suppress whisker where n<2", "dont": "smooth ordinal dipstick"}
    },
    {
      "id": "A6",
      "name": "Ordinal / bucketed categorical temporal (dipstick)",
      "description": "Urinalysis scores Normal/Trace/1+/2+ with straight lines (no smoothing) and categorical yticks.",
      "makie_calls": ["lines!(straight)", "errorbars!", "scatter!(open)"],
      "defaults": {"yticks": "(0:3, [\"Normal\",\"Trace\",\"1+\",\"2+\"])"}
    },
    {
      "id": "A7",
      "name": "Mean-line-over-raw-dots with significance brackets",
      "description": "PCHIP monotone-cubic mean line, ±SD error bars, open mean markers (black stroke), all raw observations as translucent red dots, hand-drawn brackets with tiered stars + p.",
      "makie_calls": ["pchip_spline -> lines!(:black, lw 2.5)", "scatter!(raw (:red,0.7))", "lines!+text! brackets"],
      "defaults": {"raw_dot": "(:red,0.7) fill, (:darkred,0.8) stroke, size 8", "stars": "tiered ***/**/*"}
    },
    {
      "id": "A8",
      "name": "Grouped / AE bar chart",
      "description": "Categorical rate bars by power/cohort; k/n count above, % white inside tall bars else black above; fixed ylims; no x-grid.",
      "makie_calls": ["barplot!(color=[:black,:darkgray] or cohort colors, strokecolor=:black, strokewidth=1.4..1.5, width=0.55..0.6)", "text!(k/n)", "text!(%)"],
      "defaults": {"ylims": "0-75 or 0-100", "pct_inside_threshold": ">=8%", "dont": "render Fisher p on plot"}
    },
    {
      "id": "A9",
      "name": "Grouped bar + SEM + jittered individual points",
      "description": "Two delivery groups as semi-transparent bars (fill 0.7) with colored stroke, black SEM error bars, black jittered individual points; horizontal legend below.",
      "makie_calls": ["barplot!(color=[(c,0.7)...], strokecolor, strokewidth=2, width=0.6)", "errorbars!(:black, SEM)", "scatter!(jittered rand*0.15, :black, white stroke)"],
      "defaults": {"legend": "fig[2,1] orientation=:horizontal"}
    },
    {
      "id": "A10",
      "name": "Custom KDE violin + raw dots + mean/SD glyph",
      "description": "Hand-rolled Gaussian KDE -> poly! body (color,0.35) strokewidth 2.5; internal ±SD I-bar (alpha-graded black, linecap=:round); thick mean bar; jittered red raw dots; open L-spine.",
      "makie_calls": ["density_series -> poly!(Point2f, color=(c,0.35), strokecolor=c, strokewidth=2.5)", "lines!(...linecap=:round)", "scatter!(jitter, color=:red, strokecolor=:white)"],
      "defaults": {"raw_dot_size": 14, "sd_alpha": [0.8, 0.6, 0.4]}
    },
    {
      "id": "A11",
      "name": "Split/half violin & box plot with raw-data overlay (EGH)",
      "description": "Two-cohort distribution comparison; colored median + quartile crossbar; bright pure-red solid raw dots overlaid; L-spine, horizontal-only dashed grid; bracket with bold ** + literal (p=0.0088).",
      "makie_calls": ["violin!/boxplot! + scatter!(raw red) + lines!+text! bracket"],
      "defaults": {"violin_palette": "dusty mauve vs steel-blue", "box_palette": "cornflower vs coral", "raw_dot": "pure #FF0000 solid"}
    },
    {
      "id": "A12",
      "name": "Annotated single-trace ECG",
      "description": "Black base ECG line with colored P/QRS/T segment overlays, single-letter text! labels (fs 40), curly bracket! Δt/amplitude annotations color-matched.",
      "makie_calls": ["lines!(black, lw 3)", "highlightportion! (colored lines!)", "text!", "bracket!(style=:curly)"],
      "defaults": {"label_size": 40}
    },
    {
      "id": "A13",
      "name": "Multi-series filter-comparison (FFT spectrum)",
      "description": "3 signals (raw/lowpass/bandpass) as scatterlines with open markers; circle/utriangle/rect + solid/dash/dot + black/red/blue stroke, line stays black; split low/high-freq panels with dummy-axis shared title.",
      "makie_calls": ["scatterlines! x3 per panel", "GridLayout faceting", "dummy axis"],
      "defaults": {"marker_size": 25, "strokewidth": 3}
    },
    {
      "id": "A14",
      "name": "Bode magnitude (log-frequency)",
      "description": "log10 x-axis, 10^n rich-text tick formatter, scatter+lines red/blue, dashed vlines cutoffs (gapped for text), band! passband, inline text! cutoffs.",
      "makie_calls": ["scatter!", "lines!", "vlines!(:dash, lw 4)", "band!(green,0.2)", "text!", "custom xtickformat"],
      "defaults": {"yticks": "[0;-3;-15;-25;-35;-45]", "position": ":rb"}
    },
    {
      "id": "A15",
      "name": "Radar / spider plot",
      "description": "Manual cos/sin theta polar layout, gray dashed spokes, two closed scatterlines polygons (open markers), rotated perimeter text!, external Legend column; labels embed value ranges.",
      "makie_calls": ["lines! spokes", "scatterlines! x2 (+closing segments)", "text! rotated", "Legend(fig[1,2])"],
      "defaults": {"limits": "(-1.5,1.5,-1.5,1.5)", "aspect": 1}
    },
    {
      "id": "A16",
      "name": "Histogram (HRV)",
      "description": "Translucent red fill, red stroke, 30 bins, on ggthemr(:fresh).",
      "makie_calls": ["hist!(bins=30, color=(:red,0.3), strokecolor=:red, strokewidth=3, strokearound=true)"],
      "defaults": {}
    },
    {
      "id": "A17",
      "name": "PSD / Fourier trace",
      "description": "Single red PSD line (lw 5) with open white circles; LF/HF text! labels (fs 40); fixed xticks 0:0.1:1.0.",
      "makie_calls": ["lines!(red, open markers)", "text!"],
      "defaults": {}
    },
    {
      "id": "A18",
      "name": "ROC curve",
      "description": "scatterlines black with open white circles; trapezoidal AUC computed in-loop.",
      "makie_calls": ["scatterlines!", "manual trapezoid AUC loop"],
      "defaults": {}
    },
    {
      "id": "A19",
      "name": "Long temporal R-peak strip",
      "description": "Very wide (1800x200) line with detected R peaks as solid orange scatter via Findpeaks.findpeaks.",
      "makie_calls": ["lines!", "scatter!(:orange solid)", "findpeaks"],
      "defaults": {"findpeaks": "min_dist=0.5, min_height=9.0"}
    },
    {
      "id": "A20",
      "name": "3D iso-surface volume reconstruction (LV/RV/lesion)",
      "description": "Stacked contours -> 3D matrix -> marching-cubes iso-surfaces. LV opaque, RV translucent, lesion inner solid + outer penumbra alpha=0.5. Axis3 everything hidden. RNew photoshoot: fixed camera, mm-cubic framing, pure-blue bg chroma-keyed to alpha.",
      "makie_calls": ["volume!(ax, A; algorithm=:iso, isorange=1, isovalue=1, colormap=:websafe, transparency=true, alpha=0.5)", "translate!/rotate!", "tooltip!", "Axis3(aspect=(1,1,1), viewmode=:fit, hidden decorations)"],
      "defaults": {"colormap": ":websafe (or :mint)", "penumbra_alpha": 0.5, "camera": "az 45/225 el 10", "lv_tissue": "#cfa37a@0.9", "rv_tissue": "#7a9fcf@0.35"}
    },
    {
      "id": "A21",
      "name": "Text/console analytic report (non-figure)",
      "description": "@printf tabular cohort reports (AE rates, populations, outlier audits). Same data pipeline, no Makie output.",
      "makie_calls": ["none (Printf @printf tables)"],
      "defaults": {}
    }
  ],
  "stats_conventions": {
    "pairwise": "Mann-Whitney U default; Welch UnequalVarianceTTest only when both groups normal",
    "normality_gate": {"current": "Jarque-Bera + Exact KS", "legacy": "Shapiro-Wilk"},
    "omnibus": "One-Way ANOVA / Kruskal-Wallis",
    "repeated_measures": "MixedModels.jl / R lmer/nlme; likelihood-ratio tests; convergence-gated",
    "fit_model": "y = y_inf*(1 - exp(-(t/tau)))^beta, beta fixed (0.5 depth/width 1D, 1.5 volume 3D); report R2, F-p, AIC, RMSE, tau, plateau times",
    "outlier_rejection": "volume-only 1.5*IQR fences applied uniformly to all metrics (n>=4 groups)",
    "smoothing": ["CubicSpline 200pt", "PCHIP monotone-cubic", "straight (ordinal)", "physics fit"]
  },
  "invariants": [
    "set_theme!(ggthemr(:fresh)) base, inside each plotting function",
    "All titles/labels LaTeX L\"\\text{...}\"; units parenthesized; mm^3 via split \\text",
    "Titles texfont(:bold); tick labels texfont(:bolditalic) (slanted)",
    "Open white-filled summary markers with colored stroke, drawn last",
    "Error bars capped, color-matched to series, drawn behind markers",
    "Red dashed physics fit (:red :dash lw2) when a model is shown",
    "Multi-series = color + shape + linestyle, held constant across a panel series",
    "Significance = square U-bracket + single * + literal (p=...), stacked with reserved headroom (current path)",
    "(n=X) always surfaced (title, label, or per-point)",
    "RFA duration axis invariant: ticks 60:30:300, xlims!(35,320)",
    "PNG export at high px_per_unit (5 or 12); SVG for vector",
    "Cohort hue locked to identity and reused across panels"
  ],
  "per_figure_freedom": [
    "Frame: full box vs L-spine open vs all-hidden (3D)",
    "Slate text overrides (#2C3E50/#34495E/#BDC3C7) on/off",
    "Tick-font symmetry: both :bolditalic vs x-bold/y-bolditalic",
    "Error metric: 95% CI vs LMM CI vs SD vs SEM (but label which)",
    "Legend mechanism: axislegend inside vs standalone Legend cell vs omitted+inline n=; position rt/rb/lt/ct",
    "Smoothing: CubicSpline vs PCHIP vs straight vs physics-fit",
    "Star scheme: single-star+p (default) vs legacy tiered */**/***",
    "Figure size / fontsize / titlesize per the ladders",
    "px_per_unit (5 vs 12); PNG vs SVG",
    "ylabelrotation=2π / xticklabelrotation=π/4 opt-in (default off)",
    "Marker shape set, markersize, strokewidth within documented ranges",
    "Filled vs open for raw/individual points (raw=filled coral/red; summary=open white)"
  ]
}
