Skip to content

Rewrite/angular latest - #11

Merged
sirmmo merged 12 commits into
masterfrom
rewrite/angular-latest
Apr 29, 2026
Merged

Rewrite/angular latest#11
sirmmo merged 12 commits into
masterfrom
rewrite/angular-latest

Conversation

@sirmmo

@sirmmo sirmmo commented Apr 29, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

sirmmo and others added 12 commits April 28, 2026 00:28
Adds the full favicon set (SVG, 96px PNG, .ico, 180px Apple touch) and
the web manifest to the page head. SVG icon takes precedence on browsers
that support it (sharp at every density); PNG + ICO are fallbacks.

Also patches the ancillary metadata that visitors actually see:
- <title> is now "GeoContext — OpenHistoryMap" (was "GeocontextFront",
  the Angular CLI placeholder).
- <meta name=description> for share previews and search.
- <meta name=theme-color> + manifest theme/background match the
  paper-cream surface from the editorial pass (oklch ≈ #faf6ee).
- Manifest name + short_name + description corrected from the
  "MyWebSite / MySite" generator placeholders.

All hrefs are relative so they resolve correctly under the deployed
<base href="/geocontext-front/"> on GitHub Pages without forcing the
domain root.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds a theme toggle button in the masthead, positioned right before the
Map / static-page nav links (with a faint hairline separator so the
control reads as a control, not a nav item).

- New GcxThemeService (gcx-core): light/dark signal, persists choice to
  localStorage under "gcx:theme", mirrors current value onto
  `<html data-theme="…">` via effect(). Default is light per the
  editorial design context — we don't auto-follow prefers-color-scheme,
  dark is an explicit opt-in. Exported from public-api.
- styles.scss: `:root[data-theme='dark']` palette — warm dark surfaces
  (oklch 16/20/24% L, hue 80) with cream ink, terracotta lifted to
  oklch 70%/80% for contrast against the dark surface. Material's
  --mat-sys-* aliases already point at the --gcx-* tokens, so the
  drawer / tabs / slide-toggle / form fields flip palette automatically
  with no SCSS theme rebuild. `color-scheme:` set on each variant so the
  browser's default form widgets and scrollbars match.
- Masthead button: Material light_mode / dark_mode icon; aria-label and
  title describe the *target* state ("Switch to dark mode" while light
  is active, and vice versa). Same affordance treatment as the menu
  button — transparent background, terracotta on hover.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replaces the hand-rolled raster-OSM default style with OpenFreeMap's
free, vector, no-API-key bright cartography
(https://tiles.openfreemap.org/styles/bright). MapLibre fetches the
style URL directly; the existing 'load' handshake before host.ready()
already waits for the vector style to settle, so no lifecycle changes
needed. Apps that want a different default can still subclass the
directive or just declare an explicit basemap at the top of `layers[]`.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The previous attempt put `> :not(router-outlet) { position: absolute }`
in gcx-main's component styles. That rule is scoped by Angular's view
encapsulation to gcx-main's template — but the routed component is
inserted by the router OUTSIDE that scope, so the rule never matched
and the route component sized to its content instead of filling the
outlet. Result: the map collapsed to ~300px on first paint.

Moving the absolute fill to each route component's own `:host` styles
(MapRouteComponent, RepoMapRouteComponent) — those rules are applied
to the host element directly and don't depend on the parent's
encapsulation. The outlet stays `position: relative` as the anchor.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…r changes

The CSS chain to fill height was correct after the previous fix, but
both MapLibre and Leaflet snapshot the container's clientWidth/Height
at construction. If the layout (router-outlet, mat-drawer-container,
maybe vector-style load) settles a frame later, the GL canvas / tile
layer locks at that initial 300-ish-pixel snapshot and only catches up
when something else triggers a relayout (sidebar toggle, viewport
resize). That's why the map was stuck small until the user interacted.

Both flavours now install a ResizeObserver on the map element with a
single-rAF debounce. Whenever the container's dimensions actually
change — initial paint, late layout, sidebar toggle, viewport
resize — they call map.resize() (MapLibre) or map.invalidateSize()
(Leaflet) and the renderer catches up. Disconnected on ngOnDestroy.

Leaflet flavour also gained the missing OnDestroy hook (it had
subscription teardowns to clean up but no place to run them).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The ResizeObserver from the previous commit catches container delta
changes, but on the very first paint there may be no delta to observe
— the canvas is born small and the parent never grows past it.
Scheduling map.resize() (or invalidateSize for Leaflet) 100 ms after
the load handshake forces one extra measurement after the layout
should have settled. Cheap, idempotent, complements the observer
without replacing it.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…y table or html

A new layer type registered as "markers" / "marker" that renders Point
features as traditional clickable map pins (Leaflet L.marker, MapLibre
maplibregl.Marker) and binds a popup to each. Popup body comes from
the feature's `html` property when present (rendered as raw HTML the
author trusts), otherwise the same property-table summary the sidebar
Details tab shows: a sniffed title (`name`/`title`/`nome`/`label`)
plus a definition list of remaining non-empty properties.

Configure in gcx.json:
  { "name": "Sites", "type": "markers", "datasource": "places",
    "conf": { "htmlField": "popup_html" } }

`htmlField` defaults to "html"; pass any property name for repos that
ship pre-rendered HTML under a different key.

- mn-geo-layers
  - Extends GeoJsonFeaturesDescriptor with `marker?: 'circles' | 'pins'`
    and `popup?: { htmlField? }`. Backwards compatible — FeatureLayer
    omits both, behaves as before.
  - New shared util `buildPopupHtml(feature, htmlField)` — emits the
    `.gcx-popup` markup styled by app's styles.scss; escapes HTML for
    auto-rendered properties, passes raw author HTML untouched.
  - New MarkersLayer + provideMnGeoLayersMarkers().

- mn-geo-flavours-leaflet
  - geojson-features dispatch branches on `desc.marker === 'pins'`:
    pin mode → L.marker (default Leaflet icon), circle mode → existing
    circleMarker styling. bindPopup attached for any descriptor with a
    `popup` field, regardless of marker mode.

- mn-geo-flavours-mapbox
  - Pin mode goes through a new `renderPinMarkers` helper that walks
    Point features, instantiates maplibregl.Marker (coloured from
    style.options.fillColor / .color, terracotta fallback), attaches a
    Popup with the built HTML, and tracks owned markers per descriptor
    id. setLayerVisibility hides/shows them via inline display; remove
    /ngOnDestroy clean up. Circle mode also gains popup support — the
    GL click handler now opens a Popup at the click lngLat when the
    descriptor has a `popup` field, plus pointer cursor on hover.
    `subscribe` for live data on pin layers re-renders markers.

- styles.scss
  - .gcx-popup typography matches the sidebar Details tab (display
    serif title with terracotta cue rule, Public-Sans dt + EB-Garamond
    dd grid). Repaints Leaflet's and MapLibre's popup containers in
    the paper palette so the chrome doesn't fight the editorial body.

- app.config wires provideMnGeoLayersMarkers().

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…tation.js exports

Static pages can now reference markdown (rendered via marked) in addition
to HTML; format is inferred from the URL extension (.md, .cff) when not
set explicitly. In repo mode, ChcxStaticService HEAD-probes README.md
and CITATION.cff at the repo root and registers them under default
slugs when present.

CITATION.cff pages render through a new <chcx-citation> component that
converts the CFF YAML to CSL-JSON and uses citation.js (lazy-loaded) to
export to APA, Vancouver, Harvard, BibTeX, BibLaTeX, RIS, and CSL-JSON,
with copy-to-clipboard and download-as-file controls. The engine and
CSL templates land in lazy chunks, so the main bundle is unchanged.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Hardcoded grays (#f6f6f4 backgrounds, #555/#666 text, #ccc rules,
#b00020 errors) rendered as light-on-white in dark mode. Switch to the
project's --gcx-paper-*, --gcx-ink-*, --gcx-rule, and --gcx-accent-deep
tokens so the citation block and markdown pages flip with
<html data-theme="dark">. Errors use accent-italic instead of red —
on-brand for both surfaces.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds setLayerOrder(ids) to the flavour contract — Leaflet uses
bringToFront / setZIndex; MapLibre walks the stack bottom-up calling
moveLayer for the descriptor id and any -fill/-line/-circle sublayers.

Sidebar layer rows get a ⋮⋮ drag handle (CDK drag-drop). On drop the
layers signal is reordered with moveItemInArray and the new id list
flows to the active flavour, restacking native layers in place. Drag
is disabled while the search filter is active so previousIndex /
currentIndex always refer to the unfiltered list. Convention:
ids[0] = top of the sidebar = drawn on top.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Grid 1fr defaults to minmax(auto, 1fr), so the text column refuses to
shrink below its intrinsic width and a long layer name pushes the
trailing auto column (the slide toggle) outside the sidebar. Switch to
minmax(0, 1fr), add min-width: 0 + ellipsis on the name + source spans,
and clip horizontal overflow on the list as a backstop.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Footer/colophon GCX_VERSION + projects/gcx-core/package.json are kept
in lockstep per version.ts; bumping both.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@sirmmo
sirmmo merged commit ad651bb into master Apr 29, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant