// desktop-screen-results.jsx — Search Results desktop screen

function ResultsDesktop({
  active = 'kauf',
  onNav = () => {},
  onOpenDetail = () => {},
  onOpenAI = () => {},
  onRefresh = () => {},
  onEvaluate = () => {},
  onExport = () => {},
  searchId = null,
  ctx = {},
  searchQuery = '',
  topBarProps = {},
  routeView = null,
  onSetResultsView = null,
} = {}) {
  const listings = desktopListings(ctx);
  const searches = desktopSearches(ctx);
  const search = searches.find(s => String(s.id) === String(searchId)) || searches.find(s => s.category === 'kauf') || searches[0];
  const defaultFilters = React.useCallback(() => ({
    platforms: { immoscout24: true, kleinanzeigen: true, wohnungsboerse: true },
    onlyScored: false,
    minScore: 0,
    provFreeOnly: false,
    balcony: false,
    elevator: false,
    denkmal: false,
    priceMin: search?.priceMin || '',
    priceMax: search?.priceMax || '',
    roomsMin: search?.roomsMin || '',
    roomsMax: search?.roomsMax || '',
    areaMin: search?.areaMin || '',
    areaMax: search?.areaMax || '',
  }), [search?.id]);
  const [filters, setFilters] = React.useState(defaultFilters);
  const [sort, setSort] = React.useState('score');
  const [view, setView] = React.useState(['grid', 'list', 'map'].includes(routeView) ? routeView : 'grid');
  const [page, setPage] = React.useState(1);
  const setResultView = (nextView) => {
    setView(nextView);
    onSetResultsView?.(nextView, search);
  };
  React.useEffect(() => {
    setFilters(defaultFilters());
    setPage(1);
  }, [defaultFilters]);
  React.useEffect(() => {
    if (['grid', 'list', 'map'].includes(routeView) && routeView !== view) setView(routeView);
  }, [routeView]);
  React.useEffect(() => setPage(1), [searchQuery, sort, view, JSON.stringify(filters)]);
  if (!search) {
    return (
      <DesktopFrame url="app.immobot.de/suchen">
        <Sidebar active={active} notifBadge={ctx.notifBadge || 0} onNav={onNav} user={ctx.user} taskLimit={ctx.taskLimit} />
        <main style={{ flex: 1, display: 'flex', flexDirection: 'column', minWidth: 0, background: 'var(--bg)' }}>
	          <DTopBar crumb={['Kaufen']} title="Suchergebnisse" subtitle="Noch keine Suche angelegt" {...topBarProps} />
          <section style={{ flex: 1, display: 'grid', placeItems: 'center', padding: 32 }}>
            <DCard padding={28} style={{ maxWidth: 420, textAlign: 'center' }}>
              <I.search style={{ width: 34, height: 34, color: 'var(--primary)' }} />
              <h2 style={{ margin: '12px 0 6px', fontFamily: 'var(--font-display)', fontSize: 26, fontWeight: 500 }}>Keine Suche gefunden</h2>
              <p style={{ margin: 0, color: 'var(--ink-muted)', fontSize: 13, lineHeight: 1.5 }}>Legen Sie zuerst eine Suche an, damit ImmoBot Treffer sammelt.</p>
            </DCard>
          </section>
        </main>
      </DesktopFrame>
    );
  }
  const base = listings.filter(l => String(l.searchId || l.task_id) === String(search.id) || (!l.searchId && l.type === search.category));
  const inRange = (value, min, max) => {
    const n = Number(value || 0);
    const low = Number(min || 0);
    const high = Number(max || 0);
    return (!low || n >= low) && (!high || n <= high);
  };
  const hasFeature = (listing, token) => desktopFeatureText(listing).includes(token);
  const filtered = desktopFilterByQuery(base, searchQuery)
    .filter(l => filters.platforms[l.platform || 'kleinanzeigen'] !== false)
    .filter(l => !filters.onlyScored || Number(l.aiScore || 0) > 0)
    .filter(l => !filters.minScore || Number(l.aiScore || 0) >= Number(filters.minScore))
    .filter(l => !filters.provFreeOnly || l.provisionsfrei)
    .filter(l => !filters.balcony || hasFeature(l, 'balkon'))
    .filter(l => !filters.elevator || hasFeature(l, 'aufzug'))
    .filter(l => !filters.denkmal || hasFeature(l, 'denkmal'))
    .filter(l => inRange(l.price, filters.priceMin, filters.priceMax))
    .filter(l => inRange(l.rooms, filters.roomsMin, filters.roomsMax))
    .filter(l => inRange(l.area, filters.areaMin, filters.areaMax))
    .sort((a, b) => {
      if (sort === 'price') return Number(a.price || 0) - Number(b.price || 0);
      if (sort === 'newest') return new Date(b.posted || 0) - new Date(a.posted || 0);
      if (sort === 'sqm') return (Number(a.price || 0) / Math.max(1, Number(a.area || 0))) - (Number(b.price || 0) / Math.max(1, Number(b.area || 0)));
      return Number(b.aiScore || 0) - Number(a.aiScore || 0);
    });
  const pageSize = view === 'grid' ? 6 : 10;
  const pageCount = Math.max(1, Math.ceil(filtered.length / pageSize));
  const currentPage = Math.min(page, pageCount);
  const shown = filtered.slice((currentPage - 1) * pageSize, currentPage * pageSize);
  const updateFilter = (key, value) => setFilters(f => ({ ...f, [key]: value }));
  const updatePlatform = (key) => setFilters(f => ({ ...f, platforms: { ...f.platforms, [key]: !f.platforms[key] } }));
  const scoreCount = (score) => base.filter(l => Number(l.aiScore || 0) >= score).length;
  const featureCount = (token) => base.filter(l => hasFeature(l, token)).length;

  return (
    <DesktopFrame url="app.immobot.de/suchen/altbau-berlin-ost">
      <Sidebar active={active} notifBadge={ctx.notifBadge || 0} onNav={onNav} user={ctx.user} taskLimit={ctx.taskLimit} />
      <main style={{ flex: 1, display: 'flex', flexDirection: 'column', minWidth: 0, background: 'var(--bg)' }}>
        <DTopBar
          crumb={['Kaufen', 'Meine Suchen']}
          title={search.name}
          subtitle={<span>
            {filtered.length} Treffer · zuletzt aktualisiert {fmtRelative(search.lastRun)} ·&nbsp;
            <span style={{ color: 'var(--success)' }}>● aktiv</span>
          </span>}
	          actions={<>
	            <DButton kind="ghost" icon={<I.refresh />} onClick={() => onRefresh(search)}>Aktualisieren</DButton>
	            {search.category === 'kauf' && <DButton kind="outline" icon={<I.spark />} onClick={() => onEvaluate(search)}>KI starten</DButton>}
	            <DButton kind="primary" icon={<I.download />} onClick={() => onExport(search)}>CSV</DButton>
	          </>}
	          {...topBarProps}
	        />

        <div style={{ flex: 1, display: 'flex', minHeight: 0 }}>
          {/* Filter rail */}
          <aside className="desktop-scroll" style={{
            width: 280, flexShrink: 0, borderRight: '1px solid var(--border)',
            background: 'var(--bg)', overflowY: 'auto', padding: '20px 22px 32px',
          }}>
            <div style={{ marginBottom: 22 }}>
              <FilterLabel>Stichwörter</FilterLabel>
              <div style={{ display: 'flex', flexWrap: 'wrap', gap: 5 }}>
                {desktopSearchKeywords(search).map(k => (
                  <DChip key={k} tone="success">{k}</DChip>
                ))}
                {desktopSearchExcludeKeywords(search).map(k => (
                  <DChip key={k} tone="danger">– {k}</DChip>
                ))}
              </div>
            </div>

	            <FilterGroup label="Preis (€)">
	              <RangeInputs leftVal={filters.priceMin} rightVal={filters.priceMax} onLeft={v => updateFilter('priceMin', v)} onRight={v => updateFilter('priceMax', v)} />
	              <MiniHistogram />
	            </FilterGroup>

	            <FilterGroup label="Zimmer">
	              <RangeInputs leftVal={filters.roomsMin} rightVal={filters.roomsMax} unit=" Zi." onLeft={v => updateFilter('roomsMin', v)} onRight={v => updateFilter('roomsMax', v)} />
	            </FilterGroup>

	            <FilterGroup label="Wohnfläche">
	              <RangeInputs leftVal={filters.areaMin} rightVal={filters.areaMax} unit=" m²" onLeft={v => updateFilter('areaMin', v)} onRight={v => updateFilter('areaMax', v)} />
	            </FilterGroup>

	            <FilterGroup label="Plattformen">
	              <CheckRow label="ImmoScout24" count={base.filter(l => l.platform === 'immoscout24').length} checked={filters.platforms.immoscout24} onClick={() => updatePlatform('immoscout24')} />
	              <CheckRow label="Kleinanzeigen" count={base.filter(l => (l.platform || 'kleinanzeigen') === 'kleinanzeigen').length} checked={filters.platforms.kleinanzeigen} onClick={() => updatePlatform('kleinanzeigen')} />
	              <CheckRow label="Wohnungsbörse" count={base.filter(l => l.platform === 'wohnungsboerse').length} checked={filters.platforms.wohnungsboerse} onClick={() => updatePlatform('wohnungsboerse')} />
	            </FilterGroup>

	            <FilterGroup label="KI-Bewertung">
	              <CheckRow label="Nur bewertete" count={base.filter(l => l.aiScore).length} checked={filters.onlyScored} onClick={() => updateFilter('onlyScored', !filters.onlyScored)} />
	              <CheckRow label="≥ 80 (Top)" count={scoreCount(80)} checked={filters.minScore === 80} onClick={() => updateFilter('minScore', filters.minScore === 80 ? 0 : 80)} />
	              <CheckRow label="≥ 70 (Gut)" count={scoreCount(70)} checked={filters.minScore === 70} onClick={() => updateFilter('minScore', filters.minScore === 70 ? 0 : 70)} />
	            </FilterGroup>

	            <FilterGroup label="Sonstiges">
	              <CheckRow label="Provisionsfrei" count={base.filter(l => l.provisionsfrei).length} checked={filters.provFreeOnly} onClick={() => updateFilter('provFreeOnly', !filters.provFreeOnly)} />
	              <CheckRow label="Mit Balkon" count={featureCount('balkon')} checked={filters.balcony} onClick={() => updateFilter('balcony', !filters.balcony)} />
	              <CheckRow label="Aufzug" count={featureCount('aufzug')} checked={filters.elevator} onClick={() => updateFilter('elevator', !filters.elevator)} />
	              <CheckRow label="Denkmalschutz" count={featureCount('denkmal')} checked={filters.denkmal} onClick={() => updateFilter('denkmal', !filters.denkmal)} />
	            </FilterGroup>

	            <button type="button" onClick={() => setFilters(defaultFilters())} style={{
	              marginTop: 12, width: '100%', padding: '10px 12px', borderRadius: 9,
              background: 'transparent', border: '1px solid var(--border-strong)',
              color: 'var(--ink-muted)', fontSize: 12, fontWeight: 600, cursor: 'pointer',
              fontFamily: 'var(--font-sans)',
            }}>Filter zurücksetzen</button>
          </aside>

          {/* Results pane */}
          <section className="desktop-scroll" style={{ flex: 1, overflowY: 'auto', minWidth: 0 }}>
            {/* Toolbar */}
            <div style={{
              position: 'sticky', top: 0, zIndex: 5,
              padding: '14px 28px', background: 'var(--bg)',
              borderBottom: '1px solid var(--border)',
              display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap',
            }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 4, minWidth: 0 }}>
	                <SortChip active={sort === 'score'} onClick={() => setSort('score')}>KI-Score ↓</SortChip>
	                <SortChip active={sort === 'price'} onClick={() => setSort('price')}>Preis ↑</SortChip>
	                <SortChip active={sort === 'newest'} onClick={() => setSort('newest')}>Neueste</SortChip>
	                <SortChip active={sort === 'sqm'} onClick={() => setSort('sqm')}>€ / m²</SortChip>
              </div>
              <div style={{ flex: 1 }} />
              <span style={{ fontSize: 12, color: 'var(--ink-muted)' }}>
	                Zeige <strong style={{ color: 'var(--ink)' }}>{filtered.length}</strong> von {base.length || search.matches}
	              </span>
	              <div style={{ display: 'flex', background: 'var(--surface)', border: '1px solid var(--border)', borderRadius: 8, padding: 2 }}>
	                <ViewToggle title="Raster" active={view === 'grid'} onClick={() => setResultView('grid')}><I.grid style={{ width: 14, height: 14 }} /></ViewToggle>
	                <ViewToggle title="Liste" active={view === 'list'} onClick={() => setResultView('list')}><I.list style={{ width: 14, height: 14 }} /></ViewToggle>
	                <ViewToggle title="Karte" active={view === 'map'} onClick={() => setResultView('map')}><I.pin style={{ width: 14, height: 14 }} /></ViewToggle>
	              </div>
            </div>

            <div style={{ padding: '20px 28px 32px' }}>
              {/* Insight banner */}
              <div style={{
                padding: '14px 18px', background: 'linear-gradient(110deg, var(--primary-soft) 0%, #FBF6E6 100%)',
                border: '1px solid #EFE0BA', borderRadius: 12, marginBottom: 18,
                display: 'flex', alignItems: 'center', gap: 14,
              }}>
                <span style={{
                  width: 36, height: 36, borderRadius: 10, background: 'var(--primary)',
                  color: '#fff', display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
                }}><I.spark style={{ width: 18, height: 18 }} /></span>
                <div style={{ flex: 1 }}>
                  <div style={{ fontSize: 13.5, fontWeight: 700, color: 'var(--primary-ink)' }}>
                    KI-Insight · 3 neue Top-Bewertungen seit gestern
                  </div>
                  <div style={{ fontSize: 12, color: 'var(--primary-ink)', opacity: .8, marginTop: 2 }}>
                    Der Quadratmeterpreis in <strong>Prenzlauer Berg</strong> liegt aktuell 4% unter dem 30-Tage-Schnitt. Gute Kaufgelegenheit.
                  </div>
                </div>
	                <DButton kind="outline" size="sm" disabled={!filtered[0]} onClick={() => filtered[0] && onOpenAI(filtered[0].id)}>Details →</DButton>
              </div>

	              {/* Listings */}
	              {view === 'grid' && (
	                <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 16 }}>
	                  {shown.map(l => (
	                    <DesktopListingCard key={l.id} listing={l} onTap={onOpenDetail} isFav={ctx.favs?.has(String(l.id)) || ctx.favs?.has(l.id)} onFav={ctx.toggleFav} />
	                  ))}
	                </div>
	              )}
	              {view === 'list' && (
	                <DCard padding={0}>
	                  {shown.map((l, i) => (
	                    <DesktopListingListRow key={l.id} listing={l} last={i === shown.length - 1} onTap={onOpenDetail} isFav={ctx.favs?.has(String(l.id)) || ctx.favs?.has(l.id)} onFav={ctx.toggleFav} />
	                  ))}
	                </DCard>
	              )}
		              {view === 'map' && (
		                <div style={{ display: 'grid', gridTemplateColumns: 'minmax(360px, .9fr) 1.1fr', gap: 16, alignItems: 'stretch' }}>
		                  <DCard padding={0}>
		                    {shown.map((l, i) => (
		                      <DesktopListingListRow key={l.id} listing={l} last={i === shown.length - 1} onTap={onOpenDetail} isFav={ctx.favs?.has(String(l.id)) || ctx.favs?.has(l.id)} onFav={ctx.toggleFav} compact />
		                    ))}
		                  </DCard>
		                  <DesktopResultsMap listings={shown} onOpen={onOpenDetail} />
		                </div>
		              )}
	              {shown.length === 0 && (
	                <DCard padding={24} style={{ textAlign: 'center' }}>
	                  <I.search style={{ width: 28, height: 28, color: 'var(--primary)' }} />
	                  <h3 style={{ margin: '10px 0 4px', fontFamily: 'var(--font-display)', fontSize: 22, fontWeight: 500 }}>Keine Treffer</h3>
	                  <p style={{ margin: 0, color: 'var(--ink-muted)', fontSize: 13 }}>Passen Sie Suche oder Filter an.</p>
	                </DCard>
	              )}

	              {/* Pagination */}
	              {pageCount > 1 && (
	                <div style={{ marginTop: 24, display: 'flex', justifyContent: 'center', gap: 6 }}>
	                  <PageBtn disabled={currentPage <= 1} onClick={() => setPage(Math.max(1, currentPage - 1))}>‹</PageBtn>
	                  {Array.from({ length: Math.min(pageCount, 5) }, (_, i) => i + 1).map(num => (
	                    <PageBtn key={num} active={num === currentPage} onClick={() => setPage(num)}>{num}</PageBtn>
	                  ))}
	                  <PageBtn disabled={currentPage >= pageCount} onClick={() => setPage(Math.min(pageCount, currentPage + 1))}>›</PageBtn>
	                </div>
	              )}
	            </div>
          </section>
        </div>
      </main>
    </DesktopFrame>
  );
}

function FilterLabel({ children }) {
  return <div style={{
    fontSize: 10.5, fontWeight: 700, color: 'var(--ink-muted)',
    letterSpacing: 0.07, textTransform: 'uppercase', marginBottom: 8,
  }}>{children}</div>;
}

function FilterGroup({ label, children }) {
  return (
    <div style={{ marginBottom: 22 }}>
      <FilterLabel>{label}</FilterLabel>
      {children}
    </div>
  );
}

function RangeInputs({ leftVal, rightVal, unit = '', onLeft, onRight }) {
  const inputStyle = {
    width: '100%', border: 0, background: 'transparent', outline: 'none',
    fontFamily: 'var(--font-sans)', fontSize: 12.5, color: 'var(--ink)',
    fontVariantNumeric: 'tabular-nums',
  };
  return (
    <div style={{ display: 'flex', gap: 6, marginBottom: 8 }}>
      <div style={{
        flex: 1, padding: '8px 10px', borderRadius: 8,
        background: 'var(--surface)', border: '1px solid var(--border)',
        fontSize: 12.5, fontVariantNumeric: 'tabular-nums', color: 'var(--ink)',
      }}>
        <input type="number" value={leftVal} onChange={e => onLeft?.(e.target.value)} style={inputStyle} aria-label="Minimum" />
      </div>
      <div style={{ color: 'var(--ink-faint)', fontSize: 13, alignSelf: 'center' }}>—</div>
      <div style={{
        flex: 1, padding: '8px 10px', borderRadius: 8,
        background: 'var(--surface)', border: '1px solid var(--border)',
        fontSize: 12.5, fontVariantNumeric: 'tabular-nums', color: 'var(--ink)',
      }}>
        <input type="number" value={rightVal} onChange={e => onRight?.(e.target.value)} style={inputStyle} aria-label="Maximum" />
      </div>
      {unit && <span style={{ alignSelf: 'center', fontSize: 11, color: 'var(--ink-muted)', whiteSpace: 'nowrap' }}>{unit.trim()}</span>}
    </div>
  );
}

function MiniHistogram() {
  // Stylized price-distribution histogram
  const bars = [3, 6, 9, 14, 18, 22, 19, 13, 9, 6, 4, 2];
  const max = Math.max(...bars);
  return (
    <div style={{ position: 'relative', height: 36, marginTop: 6 }}>
      <div style={{ display: 'flex', gap: 2, alignItems: 'flex-end', height: '100%' }}>
        {bars.map((b, i) => {
          const inRange = i >= 2 && i <= 7;
          return (
            <div key={i} style={{
              flex: 1, height: `${(b / max) * 100}%`,
              background: inRange ? 'var(--primary)' : 'var(--border-strong)',
              borderRadius: '2px 2px 0 0',
            }} />
          );
        })}
      </div>
      <div style={{ position: 'absolute', left: '16.6%', right: '33.3%', top: 0, bottom: 0, border: '1px solid var(--primary)', borderRadius: 4, opacity: .25, pointerEvents: 'none' }} />
    </div>
  );
}

function CheckRow({ label, count, checked, muted, onClick }) {
  return (
    <button type="button" onClick={onClick} disabled={muted && !onClick} style={{
      display: 'flex', alignItems: 'center', gap: 9, padding: '5px 0',
      opacity: muted ? .5 : 1, cursor: 'pointer',
      border: 0, background: 'transparent', width: '100%', fontFamily: 'var(--font-sans)',
    }}>
      <span style={{
        width: 16, height: 16, borderRadius: 4, flexShrink: 0,
        background: checked ? 'var(--ink)' : 'var(--surface)',
        border: checked ? '0' : '1.5px solid var(--border-strong)',
        display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
        color: '#fff',
      }}>{checked && <I.check style={{ width: 12, height: 12 }} />}</span>
      <span style={{ fontSize: 12.5, color: 'var(--ink-2)', flex: 1 }}>{label}</span>
      <span style={{ fontSize: 11, color: 'var(--ink-muted)', fontVariantNumeric: 'tabular-nums' }}>{count}</span>
    </button>
  );
}

function SortChip({ children, active, onClick }) {
  return (
    <button type="button" onClick={onClick} style={{
      padding: '6px 12px', borderRadius: 999, border: 0, cursor: 'pointer',
      background: active ? 'var(--ink)' : 'transparent',
      color: active ? '#fff' : 'var(--ink-muted)',
      fontFamily: 'var(--font-sans)', fontSize: 12.5, fontWeight: 600,
    }}>{children}</button>
  );
}

function ViewToggle({ children, active, onClick, title }) {
  return (
    <button type="button" title={title} onClick={onClick} style={{
      width: 28, height: 24, border: 0, borderRadius: 6, cursor: 'pointer',
      background: active ? 'var(--surface-2)' : 'transparent',
      color: active ? 'var(--ink)' : 'var(--ink-muted)',
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
    }}>{children}</button>
  );
}

function PageBtn({ children, active, onClick, disabled = false }) {
  return (
    <button type="button" onClick={onClick} disabled={disabled} style={{
      width: 32, height: 32, borderRadius: 8, border: '1px solid var(--border)', cursor: disabled ? 'default' : 'pointer',
      background: active ? 'var(--ink)' : 'var(--surface)',
      color: active ? '#fff' : 'var(--ink-2)',
      fontFamily: 'var(--font-sans)', fontSize: 12.5, fontWeight: 600,
      opacity: disabled ? .45 : 1,
    }}>{children}</button>
  );
}

function DesktopResultsMap({ listings = [], onOpen }) {
  const streets = ['Kastanienallee', 'Pappelallee', 'Schönhauser Allee', 'Danziger Straße', 'Greifswalder Straße', 'Winsstraße'];
  return (
    <DCard padding={0} style={{ minHeight: 520, overflow: 'hidden', position: 'relative', background: '#E5DED1' }}>
      <div style={{
        position: 'absolute', inset: 0,
        backgroundImage: 'linear-gradient(rgba(255,255,255,.52) 2px, transparent 2px), linear-gradient(90deg, rgba(255,255,255,.52) 2px, transparent 2px), linear-gradient(35deg, transparent 47%, rgba(255,255,255,.42) 48%, rgba(255,255,255,.42) 52%, transparent 53%)',
        backgroundSize: '72px 72px, 72px 72px, 180px 180px',
      }} />
      {streets.map((street, i) => (
        <div key={street} style={{
          position: 'absolute',
          left: `${8 + (i * 13) % 58}%`,
          top: `${12 + i * 13}%`,
          transform: `rotate(${i % 2 ? -22 : 16}deg)`,
          color: 'rgba(92,76,58,.44)',
          fontSize: 11,
          fontWeight: 800,
          letterSpacing: 0.02,
          textTransform: 'uppercase',
          pointerEvents: 'none',
        }}>{street}</div>
      ))}
      <div style={{
        position: 'absolute', left: 18, top: 18, zIndex: 2,
        padding: '8px 11px', borderRadius: 10, background: 'rgba(255,255,255,.9)',
        border: '1px solid rgba(255,255,255,.75)', fontSize: 12, fontWeight: 800,
        boxShadow: '0 8px 22px rgba(31,26,20,.1)',
      }}>
        Kartenansicht · {listings.length} Objekte
      </div>
      {listings.slice(0, 12).map((l, i) => (
        <button
          key={l.id}
          type="button"
          onClick={() => onOpen?.(l.id)}
          title={l.title}
          style={{
            position: 'absolute',
            left: `${14 + (i * 17) % 68}%`,
            top: `${22 + (i * 29) % 58}%`,
            zIndex: 3,
            border: 0,
            borderRadius: 999,
            padding: '7px 11px',
            background: l.aiScore >= 80 ? 'var(--success)' : 'var(--ink)',
            color: '#fff',
            fontSize: 11,
            fontWeight: 900,
            cursor: 'pointer',
            boxShadow: '0 10px 24px rgba(31,26,20,.2)',
            transform: 'translate(-50%, -50%)',
            whiteSpace: 'nowrap',
          }}
        >
          {fmtPriceShort(l.price)}
        </button>
      ))}
    </DCard>
  );
}

// ─── DesktopListingCard ────────────────────────────────────────────────
function DesktopListingCard({ listing, onTap, isFav = false, onFav }) {
  const isKauf = listing.type === 'kauf';
  const photos = desktopPhotos(listing);
  const normalizedPricePerSqm = Number(listing.pricePerSqm || 0);
  const sqm = isKauf && normalizedPricePerSqm
    ? normalizedPricePerSqm.toLocaleString('de-DE')
    : (isKauf && listing.area ? Math.round(Number(listing.price || 0) / Math.max(1, Number(listing.area || 0))).toLocaleString('de-DE') : null);
  return (
    <div onClick={() => onTap && onTap(listing.id)} style={{
      background: 'var(--surface)', border: '1px solid var(--border)',
      borderRadius: 14, overflow: 'hidden', cursor: 'pointer',
      transition: 'transform .12s ease, box-shadow .12s ease',
    }}>
      <div className="photo" style={{ height: 168, backgroundImage: `url(${photos[0]})`, position: 'relative' }}>
        <div style={{ position: 'absolute', top: 10, left: 10, display: 'flex', gap: 5 }}>
          <PlatformBadge platform={listing.platform} />
          {listing.provisionsfrei && (
            <span style={{
              background: 'rgba(255,255,255,.94)', padding: '3px 8px', borderRadius: 999,
              fontSize: 10, fontWeight: 700, color: 'var(--ink)',
            }}>PROVISIONSFREI</span>
          )}
        </div>
        <button type="button" onClick={(e) => { e.stopPropagation(); onFav?.(listing.id); }} style={{
          position: 'absolute', top: 10, right: 10,
          width: 32, height: 32, borderRadius: 999, border: 0,
          background: 'rgba(255,255,255,.94)', cursor: 'pointer',
          display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
          color: isFav ? 'var(--danger)' : 'var(--ink-muted)',
        }}>{isFav ? <I.heartFill style={{ width: 16, height: 16 }} /> : <I.heart style={{ width: 16, height: 16 }} />}</button>
        {listing.aiScore !== null && listing.aiScore !== undefined && (
          <div style={{
            position: 'absolute', bottom: 10, left: 10,
            background: '#fff', borderRadius: 999, padding: '3px 11px 3px 3px',
            display: 'inline-flex', alignItems: 'center', gap: 7,
            boxShadow: '0 3px 10px rgba(0,0,0,.18)',
          }}>
            <DScorePill score={listing.aiScore} size={26} />
            <span style={{ fontSize: 11, fontWeight: 700, letterSpacing: 0.04 }}>KI-Score</span>
          </div>
        )}
      </div>
      <div style={{ padding: '14px 16px 16px' }}>
        <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', gap: 8 }}>
          <div style={{ fontFamily: 'var(--font-display)', fontSize: 22, fontWeight: 500, letterSpacing: -0.01, color: 'var(--ink)' }}>
            {fmtPriceShort(listing.price)}
          </div>
          {sqm && (
            <div style={{ fontSize: 11, color: 'var(--ink-muted)', fontVariantNumeric: 'tabular-nums' }}>
              {sqm} €/m²
            </div>
          )}
        </div>
        <div style={{
          fontSize: 13.5, fontWeight: 600, color: 'var(--ink)', marginTop: 6, lineHeight: 1.3,
          overflow: 'hidden', display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical',
          minHeight: 35,
        }}>
          {listing.title}
        </div>
        <div style={{ fontSize: 12, color: 'var(--ink-muted)', marginTop: 6, display: 'flex', alignItems: 'center', gap: 4 }}>
          <I.pin style={{ width: 12, height: 12 }} /> {listing.district}, {listing.city}
        </div>
        <div className="hairline" style={{ marginTop: 12, marginBottom: 10 }} />
        <div style={{ display: 'flex', gap: 13, fontSize: 12, color: 'var(--ink-2)', fontWeight: 500 }}>
          <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4 }}><I.ruler style={{ width: 13, height: 13, opacity: .7 }} /> {fmtArea(listing.area)}</span>
          <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4 }}><I.bed style={{ width: 13, height: 13, opacity: .7 }} /> {listing.rooms} Zi.</span>
          <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4 }}><I.calendar style={{ width: 13, height: 13, opacity: .7 }} /> {listing.baujahr}</span>
        </div>
      </div>
    </div>
  );
}

function DesktopListingListRow({ listing, last, onTap, isFav = false, onFav, compact = false }) {
  const photos = desktopPhotos(listing);
  const normalizedPricePerSqm = Number(listing.pricePerSqm || 0);
  const sqm = listing.type === 'kauf' && normalizedPricePerSqm
    ? `${normalizedPricePerSqm.toLocaleString('de-DE')} €/m²`
    : (listing.type === 'kauf' && listing.area
      ? `${Math.round(Number(listing.price || 0) / Math.max(1, Number(listing.area || 0))).toLocaleString('de-DE')} €/m²`
      : null);
  return (
    <div role="button" tabIndex={0} onClick={() => onTap?.(listing.id)} onKeyDown={event => {
      if (event.key === 'Enter' || event.key === ' ') {
        event.preventDefault();
        onTap?.(listing.id);
      }
    }} style={{
      width: '100%',
      display: 'grid',
      gridTemplateColumns: compact ? '58px 1fr 90px 34px' : '72px 1.5fr .65fr .65fr .65fr 38px',
      gap: 12,
      alignItems: 'center',
      padding: compact ? '11px 14px' : '14px 18px',
      border: 0,
      borderBottom: last ? 'none' : '1px solid var(--border)',
      background: 'var(--surface)',
      cursor: 'pointer',
      textAlign: 'left',
      fontFamily: 'var(--font-sans)',
      color: 'var(--ink)',
    }}>
      <div className="photo" style={{ width: compact ? 58 : 72, height: compact ? 48 : 58, borderRadius: 9, backgroundImage: `url(${photos[0]})` }} />
      <div style={{ minWidth: 0 }}>
        <div style={{ fontSize: 13.5, fontWeight: 800, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{listing.title}</div>
        <div style={{ fontSize: 11.5, color: 'var(--ink-muted)', marginTop: 3, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
          {listing.district}, {listing.city} · {fmtArea(listing.area)} · {listing.rooms || '—'} Zi.
        </div>
      </div>
      <strong style={{ fontFamily: 'var(--font-display)', fontSize: compact ? 16 : 20, fontWeight: 500, whiteSpace: 'nowrap' }}>{fmtPriceShort(listing.price)}</strong>
      {!compact && <span style={{ fontSize: 12, color: 'var(--ink-muted)' }}>{sqm || fmtRelative(listing.posted)}</span>}
      {!compact && <DScorePill score={listing.aiScore || 0} />}
      <button type="button" onClick={(event) => { event.stopPropagation(); onFav?.(listing.id); }} style={{
        width: 32, height: 32, border: 0, borderRadius: 999, background: 'var(--surface-2)',
        color: isFav ? 'var(--danger)' : 'var(--ink-muted)', cursor: 'pointer',
        display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
      }}>
        {isFav ? <I.heartFill style={{ width: 15, height: 15 }} /> : <I.heart style={{ width: 15, height: 15 }} />}
      </button>
    </div>
  );
}

Object.assign(window, { ResultsDesktop, DesktopListingCard });
