openvibers/openvibe.tours Commits

Routes draw the walk; sign-in button readable (#21)

OP OpenVibers committed 12 days ago · 66eccf05fa · 3 files, +19 −1

Changes

ddiff --git a/public/css/tours.css b/public/css/tours.css
iindex 15605e2..75bdd93 100644
---- a/public/css/tours.css
++++ b/public/css/tours.css
@@@ -29,7 +29,11 @@ html, body { margin: 0; background: var(--bg-primary, #0a0f1c); color: var(--tex
.tr-arc { opacity: .85; }
.tr-land { fill: var(--room-accent, #F98942); }
.tr-pin { fill: var(--room-accent, #F98942); stroke: var(--bg-primary, #0a0f1c); stroke-width: 2; }
++/* The walk between the stops, in order, under the pins. */
++.tr-path { fill: none; stroke: var(--room-accent, #F98942); stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 7 8; opacity: .75; }
.tr-pin-n { fill: #0a0f1c; font-size: 9px; font-weight: 800; }
++/* On the route map, numbers readable once the 600-wide map is scaled to a phone (about 0.6). */
++.tr-map-fallback .tr-pin-n { font-size: 14px; }
.tr-walk { filter: drop-shadow(0 2px 8px rgba(0,0,0,.4)); }
.tr-vis-badge { display: inline-block; margin-top: 6px; padding: 4px 10px; border-radius: 999px; font-size: .72rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--room-strong, var(--accent-light, #60a5fa)); border: 1px solid var(--border, color-mix(in srgb, var(--text-primary, #fff) 12%, transparent)); }
@@@ -41,6 +45,10 @@ html, body { margin: 0; background: var(--bg-primary, #0a0f1c); color: var(--tex
.tr-field > span { color: var(--text-secondary, #96a7c2); font-size: .8rem; font-weight: 700; }
.tr-field input, .tr-field select, .tr-field textarea { width: 100%; padding: 9px 11px; border-radius: 10px; border: 1px solid var(--border, rgba(255,255,255,.16)); background: var(--bg-primary, #0a0f1c); color: inherit; font: inherit; }
.tr-field input:focus-visible, .tr-field select:focus-visible, .tr-field textarea:focus-visible { outline: 2px solid var(--room-accent, #F98942); outline-offset: 1px; }
++/* A link styled as a button keeps the button's own colour: ".tr a" outranked ".tr-btn", and the sign-in button on /trips was orange
++ on orange (2026-11-01). */
++.tr a.tr-btn { color: var(--room-on, #0a0f1c); }
++.tr a.tr-btn-quiet { color: var(--text-primary, #e6edf7); }
.tr-btn { display: inline-flex; align-items: center; gap: 8px; padding: 10px 18px; border-radius: 11px; border: 1px solid transparent; background: var(--room-accent, #F98942); color: var(--room-on, #0a0f1c); font-weight: 800; font-size: .95rem; text-decoration: none; cursor: pointer; }
.tr-btn:hover { filter: brightness(1.06); }
.tr-btn-quiet { background: transparent; color: var(--text-primary, #e6edf7); border-color: var(--border, rgba(255,255,255,.18)); }
ddiff --git a/public/js/tours.js b/public/js/tours.js
iindex 155b670..25dd522 100644
---- a/public/js/tours.js
++++ b/public/js/tours.js
@@@ -44,6 +44,15 @@
});
try { map.fitBounds(bounds, { padding: 42, maxZoom: 15, duration: 0 }); } catch (e) { /* the centre is set */ }
map.on('load', function () {
++ // The walk itself: a dashed line through the stops in order, under the numbered pins (2026-11-01).
++ var coords = stops.map(function (s) { return [Number(s.lon), Number(s.lat)]; }).filter(function (c) { return Number.isFinite(c[0]) && Number.isFinite(c[1]); });
++ if (coords.length > 1) {
++ try {
++ var accent = (getComputedStyle(document.documentElement).getPropertyValue('--room-accent') || '').trim() || '#F98942';
++ map.addSource('tr-walk', { type: 'geojson', data: { type: 'Feature', properties: {}, geometry: { type: 'LineString', coordinates: coords } } });
++ map.addLayer({ id: 'tr-walk', type: 'line', source: 'tr-walk', layout: { 'line-join': 'round', 'line-cap': 'round' }, paint: { 'line-color': accent, 'line-width': 4, 'line-opacity': 0.85, 'line-dasharray': [1.2, 1.6] } });
++ } catch (e) { /* the pins alone still show the route */ }
++ }
var fallback = document.getElementById('tr-map-fallback');
if (fallback) fallback.classList.add('tr-map-fallback-out');
});
ddiff --git a/server/views/index.js b/server/views/index.js
iindex 72aad44..fe3224d 100644
---- a/server/views/index.js
++++ b/server/views/index.js
@@@ -281,7 +281,8 @@ function miniMap(stops, label) {
return `<figure class="tr-map-fallback" id="tr-map-fallback"><svg viewBox="0 0 600 240" role="img" aria-label="${esc(label)}">
<rect width="600" height="240" rx="14" class="tr-map-bg"/>
<path d="M0 80 H600 M0 160 H600 M120 0 V240 M300 0 V240 M480 0 V240" class="tr-map-grid"/>
--${pts.map((p, i) => `<g><circle cx="${x(Number(p.lon)).toFixed(1)}" cy="${y(Number(p.lat)).toFixed(1)}" r="9" class="tr-pin"/><text x="${x(Number(p.lon)).toFixed(1)}" y="${(y(Number(p.lat)) + 4).toFixed(1)}" text-anchor="middle" class="tr-pin-n">${i + 1}</text></g>`).join('')}
++${pts.length > 1 ? `<polyline points="${pts.map((p) => `${x(Number(p.lon)).toFixed(1)},${y(Number(p.lat)).toFixed(1)}`).join(' ')}" class="tr-path"/>` : ''}
++${pts.map((p, i) => `<g><circle cx="${x(Number(p.lon)).toFixed(1)}" cy="${y(Number(p.lat)).toFixed(1)}" r="14" class="tr-pin"/><text x="${x(Number(p.lon)).toFixed(1)}" y="${(y(Number(p.lat)) + 5).toFixed(1)}" text-anchor="middle" class="tr-pin-n">${i + 1}</text></g>`).join('')}
</svg><figcaption>${pts.length} ${pts.length === 1 ? 'stop' : 'stops'} on the map. ${SOURCE.osm}</figcaption></figure>`;
}