> ## Documentation Index
> Fetch the complete documentation index at: https://docs.edicek.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Search

export const LoopVideo = ({src, poster, variant, autoPreload}) => (variant === 'tall' || variant === 'classic') && typeof autoPreload === 'boolean' ? <div onMouseEnter={e => {
  const replay = e.currentTarget.querySelector('[data-replay]');
  if (replay) replay.style.opacity = '1';
}} onMouseLeave={e => {
  const replay = e.currentTarget.querySelector('[data-replay]');
  if (replay) replay.style.opacity = '0';
}} style={{
  position: 'relative',
  margin: '18px 0 6px',
  aspectRatio: variant === 'tall' ? '3 / 4' : '4 / 3',
  borderRadius: '14px',
  border: '1px solid #ecdfcd',
  overflow: 'hidden',
  background: '#FFFBF2'
}}>
    <video ref={el => {
  if (!el || el.dataset.lazyInit) return;
  el.dataset.lazyInit = '1';
  el.muted = true;
  const box = el.parentElement;
  const loading = box && box.querySelector('[data-loading]');
  const hideLoading = () => {
    if (loading && el.readyState >= 2) loading.style.opacity = '0';
  };
  el.addEventListener('loadeddata', hideLoading);
  el.addEventListener('playing', hideLoading);
  const startPlay = () => {
    el.play().catch(() => {});
  };
  if (autoPreload || typeof IntersectionObserver === 'undefined') {
    startPlay();
    return;
  }
  const io = new IntersectionObserver(entries => {
    entries.forEach(entry => {
      if (entry.isIntersecting) startPlay(); else el.pause();
    });
  }, {
    rootMargin: '150px'
  });
  io.observe(el);
}} muted loop playsInline preload={autoPreload ? 'auto' : 'none'} poster={poster} onClick={e => {
  const el = e.currentTarget;
  const pill = el.parentElement && el.parentElement.querySelector('[data-pill]');
  const show = (text, autoHide) => {
    if (!pill) return;
    pill.textContent = text;
    clearTimeout(pill._t);
    pill.style.opacity = '1';
    if (autoHide) {
      pill._t = setTimeout(() => {
        pill.style.opacity = '0';
      }, 900);
    }
  };
  if (el.paused) {
    el.play().catch(() => {});
    show('Unpaused', true);
  } else {
    el.pause();
    show('Paused', false);
  }
}} style={{
  position: 'absolute',
  inset: 0,
  width: '100%',
  height: '100%',
  margin: 0,
  objectFit: 'cover',
  display: 'block',
  cursor: 'pointer'
}}>
      <source src={src} type="video/mp4" />
    </video>
    <div data-loading style={{
  position: 'absolute',
  inset: 0,
  display: 'flex',
  alignItems: 'center',
  justifyContent: 'center',
  opacity: 1,
  transition: 'opacity 0.3s ease',
  pointerEvents: 'none',
  backgroundColor: '#FFFBF2',
  backgroundImage: 'url(/images/video-background.jpeg)',
  backgroundSize: 'auto 100%',
  backgroundPosition: 'center',
  backgroundRepeat: 'no-repeat',
  fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',
  fontSize: '11px',
  fontWeight: 600,
  letterSpacing: '0.08em',
  textTransform: 'uppercase',
  color: '#8a7f70'
}}>
      Video is loading…
    </div>
    <button data-replay type="button" aria-label="Replay from the start" onClick={e => {
  e.stopPropagation();
  const box = e.currentTarget.parentElement;
  const video = box && box.querySelector('video');
  const pill = box && box.querySelector('[data-pill]');
  if (pill) pill.style.opacity = '0';
  if (video) {
    video.currentTime = 0;
    video.play().catch(() => {});
  }
}} style={{
  position: 'absolute',
  top: '10px',
  left: '10px',
  display: 'flex',
  alignItems: 'center',
  justifyContent: 'center',
  width: '32px',
  height: '32px',
  padding: 0,
  opacity: 0,
  transition: 'opacity 0.25s ease',
  color: '#ffffff',
  background: 'rgba(19, 22, 27, 0.72)',
  backdropFilter: 'blur(4px)',
  border: 'none',
  borderRadius: '999px',
  cursor: 'pointer'
}}>
      <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
        <path d="M3 12a9 9 0 1 0 3-6.7L3 8" />
        <path d="M3 3v5h5" />
      </svg>
    </button>
    <div data-pill style={{
  position: 'absolute',
  top: '10px',
  right: '10px',
  opacity: 0,
  transition: 'opacity 0.25s ease',
  fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',
  fontSize: '11px',
  fontWeight: 600,
  letterSpacing: '0.06em',
  textTransform: 'uppercase',
  color: '#ffffff',
  background: 'rgba(19, 22, 27, 0.72)',
  backdropFilter: 'blur(4px)',
  borderRadius: '999px',
  padding: '4px 10px',
  pointerEvents: 'none'
}}>
      Paused
    </div>
  </div> : <div style={{
  margin: '18px 0 6px',
  padding: '12px 16px',
  borderRadius: '10px',
  border: '2px solid #d33',
  background: '#ffe5e5',
  color: '#990000',
  fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',
  fontSize: '13px',
  lineHeight: 1.5
}}>
      {'<LoopVideo>'} needs <strong>variant</strong> (<strong>"tall"</strong> = 3:4 or <strong>"classic"</strong> = 4:3)
      and <strong>autoPreload</strong> ({'{true}'} or {'{false}'}).
    </div>;

Find anything you've saved by describing it in your own words. Search understands what you mean - and even the **WHY** you saved it - so the right card comes back without remembering the exact title or keyword.

### Make your first search

Type what you're after in your own words, then open any result. It works the same everywhere.

<Tabs>
  <Tab title="iPhone & iPad">
    <LoopVideo src="/videos/search-ios.mp4" variant="tall" autoPreload={true} />
  </Tab>

  <Tab title="Mac">
    <LoopVideo src="/videos/search-mac.mp4" variant="classic" autoPreload={false} />
  </Tab>

  <Tab title="Web">
    <LoopVideo src="/videos/search-web.mp4" variant="classic" autoPreload={false} />
  </Tab>
</Tabs>

## Search by meaning, not keywords

Instead of matching exact words, Search understands the meaning behind your query and lines it up against everything you've saved - so you can look for things the way you remember them, not the way they were originally written.

It reads across the whole card: your note about **WHY** you saved it, the title, the description, the link, and the text of what you saved. That's why a card can surface even when your query and the original share no words at all - the match is about meaning, not spelling. The best matches show up at the top, and the further down you go, the less related the cards get.

Unlike [Chat](/core-features/chat), which answers you in a conversation, Search hands back the actual cards. Results look just like your timeline - open a bookmark in your browser, or open a note to read and edit it.

## Tips

* **Add a note when you save** - The **WHY** you write on a card is the strongest signal Search has. Write it the way you'd go looking for it later - the words that would come to mind when you try to find it in a few weeks. Even a few words of context give Search a much better chance of putting the right card in front of you. Learn more in [Cards](/core-features/cards).
* **Search the way you remember** - Don't worry about exact keywords. If all you recall is *"something about morning productivity routines"*, just search for that. The AI works from meaning, so it finds the right card even when the wording is different.
* **Be specific when you can** - If you remember details like *"the gardening article with tips about tomatoes"*, include them. More context narrows the results, which helps a lot once you've saved a lot of cards.
* **Search in any language** - Look for content in English that you saved in Czech, or the other way around. The AI matches meaning across languages, so use whatever feels natural.

## Next steps

<Columns cols={2}>
  <Card title="Chat" icon="comments" href="/core-features/chat">
    Turn results into a conversation.
  </Card>

  <Card title="Cards" icon="layer-group" href="/core-features/cards">
    What you can search across.
  </Card>
</Columns>
