Skip to content

Site conventions

Small, consistent rules that apply to every report and page.

Every report's Quick Stats table includes a Weather row directly under Lat/Lon:

  • URL: https://forecast.weather.gov/MapClick.php?lat=<summit_lat>&lon=<summit_lon> (primary summit's LiDAR coords)
  • This is the same NOAA target that 14ers / LoJ / peakbagger all link to — one link covers all three
  • Value format: [NOAA forecast](URL) (same target as 14ers / LoJ / peakbagger weather links)
  • Multi-peak reports: use the primary peak's coords, label Weather (Primary Pk) — the forecast resolution covers the cluster

Drive-from-home (required, clickable)

The "Drive from Boulder" / "Drive from home" row must be a clickable Google Maps directions link:

  • Origin: the climber's home address (Kyle: 1162 Peakview Circle, Boulder, CO 80302)
  • Destination: the primary trailhead's coordinates
  • URL: https://www.google.com/maps/dir/?api=1&origin=<url-encoded-address>&destination=<lat>,<lon>
  • Format: **[1h 42m via Google Maps](URL)** (origin: <short address>)
  • Drive time itself is measured via Maps directions (Playwright), not estimated

"Closest" = drive time, not haversine

When ranking peaks by proximity, default to drive time from the climber's home, not straight-line distance. Haversine badly misorders Colorado peaks (a Sangre peak can be farther in miles but a shorter drive than an Elk Range peak). Use haversine only as a first-cut net to pull candidates (top 50–75), then rank the finalists by Maps drive time.

Implemented site-wide via docs/javascripts/external-links-new-tab.js (Material document$-subscribed; marks every external-origin a[href^="http"] with target="_blank" rel="noopener noreferrer" on load and on instant-nav).

  • Just write plain markdown links [text](url) — do NOT add {target="_blank"} or raw HTML
  • Internal links (peak↔peak, anchors) stay same-tab automatically
  • If a theme/plugin update breaks it, fix the JS — don't add per-link attributes

Prose rules (Kyle, 2026-07-12)

  • No acclimatization talk. Anyone climbing these peaks is already acclimatized — don't spend words on it (a "warm-up before the crux" framing is fine; altitude adjustment is not). Only relevant if we ever cover 15,000'+ objectives.
  • No weekday framing. Itineraries are "Day 1, Day 2, …" — never Thu/Fri/Sat (dates are the reader's business, not the report's).

Naming conventions

  • Slugs use underscores: jacque_peak, crestolita_broken_hand
  • Single-peak / day-trip reports: docs/peaks/<slug>.md
  • Multi-day trips: docs/trips/<slug>.md
  • Per-climber (friend) reports: docs/peaks/<slug>.<climber>.md (Kyle = unsuffixed default)
  • Saved narrow-downs: docs/lists/YYYY-MM-DD_<slug>.md
  • GPX: gpx/<slug>/<slug>_<author>_<year>_<source><id>.gpx
  • Maps: docs/maps/<slug>.png

Publishing checklist

After writing/updating a report: 1. Add to mkdocs.yml nav 2. Add to docs/index.md (grouped by region/category) 3. Commit + push 4. Confirm the GitHub Actions deploy is green before calling it done

Report frontmatter (structured, machine-readable)

Every report opens with a YAML frontmatter block. Beyond image: (the link-preview card), these fields make reports queryable — they drive the auto-generated index / sortable peak table (planned) and the link-preview metadata.

---
image: maps/<slug>.png        # link-preview card (the report's own overview map)
range: Sangre de Cristo       # peak_db range — drives grouping/filtering
drive_time: "3h 58m"          # from the climber's home (matches the report's drive row)
yds_class: "3"                # YDS class of the standard line (quoted; `yds_class` not
                              #   `class`, to avoid the Jinja reserved-word gotcha)
gain: "6,400–7,100 ft"        # standard-route gain (range if multiple TRs)
status: unclimbed             # unclimbed | climbed (for the default climber)
caltopo_id: 6TKA0RH           # research map ID (omit if none yet)
regional_map_id: VKGB00L      # the range's regional "GPS Tracks" map
# Structured stat fields — single source of truth for the "At a glance" callout,
# the sortable index table, and the nav badges. Numeric so they sort correctly.
dist_mi: 12.3                 # recommended-route distance (omit until a route is computed)
gain_ft: 6750                 # recommended/representative gain as a plain number
class: "3"                    # clean sortable class ("2", "2+", "2-3", "3")
peaks: 2                      # ranked peaks
days: 1                       # >1 for trips (then add days_detail)
drive_h: 4.0                  # drive hours as a number (for sorting)
# Trips only — per-day breakdown for the callout:
# days_detail:
#   - {label: "Trio", peaks: 3, dist_mi: 11, gain_ft: 3750, class: "2"}
---

check_reports.py warns on any report missing the recommended fields (range, drive_time, yds_class, gain, status, regional_map_id). The structured stat fields (dist_mi, gain_ft, class, peaks, days, drive_h) drive the at-a-glance callout / sortable table / nav badges — gen_quickstats.py and gen_index.py read them and have --check lints. After editing them, run both (or build_report --finalize). dist_mi comes from build_recommended_route.py; leave it off until a route exists ( in the table).

Landing-page peak table (auto-generated)

docs/index.md has a sortable peak table between <!-- PEAKS_TABLE_START --> and <!-- PEAKS_TABLE_END -->, generated from each report's frontmatter by scripts/gen_index.py (sorted by drive time; click headers to re-sort via tablesort). Don't hand-edit between the markers. After adding/editing a report:

scripts/gen_index.py     # regenerate the table

CI runs gen_index.py --check and fails if the table is stale.

Naming multi-peak reports

For a single-day multi-peak report (a combo/cluster day, not a stated multi-day trip):

  • 2 peaks → list both, e.g. # Crestolita + Broken Hand Peak — combination day (Sangre de Cristo), # Mount Powell + Eagles Nest — combination day (Gore Range).
  • 3+ peaks → <tallest peak name> Group, e.g. # Telluride Peak Group (San Juan Mountains, Imogene Pass area) (Telluride 13,514' is tallest of Telluride/T7/T8).

Keep the after-dash / parenthetical subtitle either way. A stated multi-day report keeps a descriptive title (e.g. "Lakes of the Clouds — 7-peak loop"). (Kyle, 2026-06-03)