// Swiss design language v2 - Home + Map // Single hot accent (#FF4D2E), strict grid, big sans, mono for data. const PHONE_W = 390; const PHONE_H = 844; function StatusBar({ time = '14:32', dark = false }) { const fg = dark ? '#FFFFFF' : '#000000'; return (
{time}
{/* signal */} {/* wifi */} {/* battery */}
); } function HomeIndicator({ dark = false }) { return (
); } function Frame({ children, dark = false, time = '14:32', bg }) { return (
{children}
); } const SWISS_ACCENT = '#FF4D2E'; const SWISS_INK = '#000000'; const SWISS_PAPER = '#FFFFFF'; const SWISS_GREY_3 = '#888888'; const SWISS_GREY_2 = '#BBBBBB'; const SWISS_GREY_1 = '#E5E5E5'; const SWISS_RULE = '#000000'; // Real photo avatars via Unsplash - round, with optional ring. // Photo IDs are stable Unsplash IDs of friendly portraits. const SWISS_PHOTOS = [ // Female-presenting 'photo-1494790108377-be9c29b29330', // young woman, smile 'photo-1438761681033-6461ffad8d80', // young woman, blonde 'photo-1544005313-94ddf0286df2', // young woman, dark hair 'photo-1487412720507-e7ab37603c6f', // woman, brown hair // Male-presenting 'photo-1500648767791-00dcc994a43e', // young man, friendly 'photo-1472099645785-5658abf4ff4e', // young man, beard 'photo-1507003211169-0a1dd7228f2d', // young man, glasses ]; function SwissAvatar({ variant = 0, size = 32, ring = 'none' /* 'none' | 'ink' | 'accent' */ }) { const id = SWISS_PHOTOS[variant % SWISS_PHOTOS.length]; const url = `https://images.unsplash.com/${id}?w=160&h=160&fit=crop&crop=faces&q=70`; const ringPx = ring === 'none' ? 0 : 2; const ringColor = ring === 'accent' ? SWISS_ACCENT : SWISS_INK; return (
); } // Map kind glyph - round, illustrated, character-driven (kept for reference / unused) function SwissKindGlyph() { return null; } window.SwissAvatar = SwissAvatar; window.SwissKindGlyph = SwissKindGlyph; // ─── Shared bits ────────────────────────────────────────────── function SwissMast({ dark = false }) { const ink = dark ? '#FFF' : SWISS_INK; return (
Wir. Raus. 14.05.26 / 14:32 / DO
); } function Rule({ heavy = false, color = SWISS_RULE }) { return
; } // ─── HOME (extended) ────────────────────────────────────────── function Swiss_Home() { return (
{/* Section label */}
Heute / Donnerstag Ausgabe 142
{/* Hero number - Swiss poster move */}
22
Orte für
heute Nachmittag.
{/* Tiny corner label */}
im radius
4,6 km
{/* Subtitle / rationale */}
18° und sonnig, leichter Westwind. Drei Buddys sind unterwegs. Drei kuratierte Vorschläge wenn du jetzt los willst.
{/* Weather strip - typographic */}
{[ { t:'14h', v:'18°', s:'sonnig', accent:true }, { t:'16h', v:'19°', s:'sonnig' }, { t:'18h', v:'17°', s:'wolkig' }, { t:'20h', v:'14°', s:'kühl' }, ].map((c, i) => (
{c.t}
{c.v}
{c.s}
))}
{/* Buddy strip - typographic, no avatars-as-decoration, just initials in squares */}
Buddys / Aktiv 3 / 8
{[ { i:'A', av:1, n:'Anna Igel', loc:'Naturbad Maria Einsiedel', t:'seit 13:50', dist:'1,3 km' }, { i:'B', av:4, n:'Ben Reh', loc:'Isarauen Thalkirchen', t:'seit 14:30', dist:'0,7 km' }, { i:'L', av:2, n:'Lena Fuchs', loc:'Floßlände Maria Einsiedel', t:'seit 14:10', dist:'1,7 km' }, ].map((b, i) => (
{b.n} {b.loc} · {b.t}
{b.dist}
))}
{/* Recommendations - three with full reasoning */}
Empfehlungen / 3 kuratiert · 14:32
{[ { n:'01', name:'Naturbad Maria Einsiedel', kind:'Schwimmen · Wiese', d:'1,3 km', age:'0-10 J', status:'Saison läuft', statusOk:true, why:'Naturbad in den Isarauen · Planschbereich · große Liegewiese · 4,6★ aus 1290 Bewertungen', buddy:{ name:'Anna Igel', text:'ist seit 13:50 dort', av:1 }, }, { n:'02', name:'Café Thalkirchen', kind:'Café · Pullacher Pl.', d:'0,3 km', age:'0-8 J', status:'offen bis 23 Uhr', statusOk:true, why:'Unaufgeregt am Pullacher Platz · Terrasse · 4,8★ aus 1070 Bewertungen · gut für kurzen Stopp', buddy: null, }, { n:'03', name:'Familienzentrum Sendling', kind:'Indoor · Plan B', d:'0,5 km', age:'0-10 J', status:'Plan B bei Regen', statusOk:false, why:'Offenes Café · Wickeltisch · Eltern-Treff · 4,7★ · falls die Wolken doch kommen', buddy: null, }, ].map((it, i) => (
{/* Header row */}
{it.n} {it.name} {it.d}
{/* Meta */}
{it.kind} · {it.age} · {it.status}
{/* Reason */}
{it.why}
{/* Buddy mention */} {it.buddy && (
{it.buddy.name} · {it.buddy.text}
)}
))}
{/* Fallback / discovery teaser */}
Auch in der Nähe +20 weitere
{[ { name:'Isarauen Thalkirchen', kind:'Natur', d:'0,7 km' }, { name:'Tierpark Hellabrunn', kind:'Tierpark', d:'1,4 km' }, { name:'Spielplatz Isarwinkel', kind:'Spielplatz', d:'1,1 km' }, { name:'Alter Wirt Thalkirchen', kind:'Biergarten', d:'0,8 km' }, ].map((it, i, arr) => (
{it.name} {it.kind} {it.d}
))}
{/* Bottom system note */}
Thalkirchen · 22 Orte · 4,6 km Radius sync 14:32:09
{/* Nav */} ); } // ─── MAP screen ─────────────────────────────────────────────── function Swiss_Map() { const mapRef = React.useRef(null); React.useEffect(() => { if (!mapRef.current || !window.L) return; const node = mapRef.current; if (node._bc_map) { node._bc_map.remove(); node._bc_map = null; } const map = L.map(node, { zoomControl: false, attributionControl: false, dragging: false, scrollWheelZoom: false, doubleClickZoom: false, tap: false, touchZoom: false, }); node._bc_map = map; L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png', { maxZoom: 19, subdomains: 'abcd', }).addTo(map); // Featured: hero spots in the Thalkirchen area, plus Westpark to give the map breath. const featured = ['p1','p2','p5','p11','p12','p21']; // Buddies present at: Café Thalkirchen (Mira-planned), Naturbad (Anna-active), Isarauen (Ben-active) const buddyAt = { p11: { i:'A', av:1 }, p1: { i:'M', av:0 }, p5: { i:'B', av:4 } }; // Center on Thalkirchen so the user's home neighborhood anchors the view. const userHome = [48.108, 11.546]; // Fit bounds to all featured POIs + user home so the map ALWAYS frames them. const featuredCoords = (window.POIS || []) .filter(p => featured.includes(p.id)) .map(p => [p.lat, p.lng]); featuredCoords.push(userHome); if (featuredCoords.length > 1) { map.fitBounds(featuredCoords, { padding: [50, 50] }); } else { map.setView(userHome, 14); } // Glyph per kind - sized for 24px / 36px coin (viewBox 32x32) function coinGlyph(kind, c='#FFF') { const sw = 2; const map = { // Slide on a hill spielplatz: ` `, // Cup with latte heart in foam cafe: ` `, // Wave with sun schwimmbad: ` `, // Two pine trees + bird natur: ` `, // Pillared museum facade with sun museum: ` `, // Stacked blocks indoor: ` `, tanzkurs: ` `, musikkurs: ` `, }; return map[kind] || map.spielplatz; } (window.POIS || []).forEach(p => { const isFeatured = featured.includes(p.id); const buddy = buddyAt[p.id]; const hasBuddy = !!buddy; const coinSize = isFeatured ? 44 : 28; const bg = hasBuddy ? SWISS_ACCENT : SWISS_INK; const ringColor = hasBuddy ? SWISS_INK : SWISS_PAPER; const ringWidth = isFeatured ? 2.5 : 2; const half = coinSize / 2; const inner = coinSize - ringWidth * 2; const buddyPhotoId = hasBuddy ? SWISS_PHOTOS[buddy.av % SWISS_PHOTOS.length] : null; let html = `
${coinGlyph(p.kind, '#FFF')}
`; if (hasBuddy && buddyPhotoId) { // Round avatar bubble - sits OUTSIDE the coin (top-right), no overlap const avSize = isFeatured ? 24 : 20; html += `
`; } html += `
`; const icon = L.divIcon({ className:'swiss-pin', html, iconSize: [coinSize, coinSize], iconAnchor: [half, half], }); L.marker([p.lat, p.lng], { icon, zIndexOffset: isFeatured ? 500 : 0 }).addTo(map); }); return () => { map.remove(); node._bc_map = null; }; }, []); const filters = [['Alle', true], ['Spiel', false], ['Café', false], ['Schwimmen', false], ['Indoor', false], ['Natur', false]]; const distances = ['1km','2km','5km','10km']; return ( {/* Header */}
Karte / Thalkirchen 22 Orte sichtbar
{/* Filter row */}
{filters.map(([l, on], i) => ( {l} ))}
{/* Map */}
{/* Map overlay - corner labels */}
N ↑   48°08′
{['+','−'].map((s, i) => (
{s}
))}
{/* Distance scale */}
1 KM
{/* Bottom panel - selected POI in Swiss grid style */}
{/* Active selection header */}
● Ausgewählt 22 Orte sichtbar
{/* Featured POI - Naturbad Maria Einsiedel · real data, buddy inline */}

Naturbad
Maria Einsiedel

1,3 km
Schwimmen · 0-10 J · Thalkirchen · 4,6★
{/* Buddy at this POI */}
Anna Igel · seit 13:50
{/* Inline mini-list of next two */}
{[ { n:'02', name:'Tierpark Hellabrunn', kind:'Tierpark', d:'1,4 km', buddy:{av:0, name:'Mira Otter'} }, { n:'03', name:'Isarauen Thalkirchen', kind:'Natur', d:'0,7 km', buddy:{av:4, name:'Ben Reh'} }, ].map((r, i) => (
{r.n} {r.buddy ? : } {r.name} {r.kind} {r.d}
))}
); } // ─── Bottom nav (shared) ────────────────────────────────────── function SwissNav({ active = 0 }) { const items = ['Heute', 'Karte', 'Buddys', 'Du']; return (
{items.map((l, i) => { const on = i === active; return (
{l}
); })}
); } window.Swiss_Home = Swiss_Home; window.Swiss_Map = Swiss_Map;