# CSS-Only Tooltip Pattern (replaces native `title=""`)

Native `title=""` tooltips are unreliable inside Livewire pages that re-render on click/poll —
the browser tooltip runs on its own internal timer + mouseleave state, which desyncs when
Livewire morphs the DOM under the cursor (a click triggers a re-render mid-hover → the
browser never gets a clean mouseleave → the tooltip visually sticks on screen, detached from
the actual cursor position). This is a real, reproducible problem in this app, not a one-off —
use this pattern instead of `title=""` anywhere a hover hint is wanted, especially inside a
frequently-re-rendering Livewire component.

First hit/fixed in `plugins/webkul/jlr-epc/resources/views/filament/pages/browse-catalogue.blade.php`
(vehicle/section tile "how old is this data" hints) — see that file for a live reference.

---

## The pattern

`data-tooltip="..."` attribute + a pure CSS `::after` pseudo-element, shown via `:hover`:

```css
[data-tooltip] { position:relative; }
[data-tooltip]::after {
    content:attr(data-tooltip);
    position:absolute;bottom:100%;left:50%;transform:translateX(-50%);
    margin-bottom:6px;padding:4px 9px;border-radius:5px;
    background:#111827;color:#f9fafb;font-size:.6875rem;font-weight:500;white-space:nowrap;
    opacity:0;visibility:hidden;pointer-events:none;transition:opacity .12s ease;
    z-index:60;box-shadow:0 2px 6px rgba(0,0,0,.15);
}
[data-tooltip]:hover::after { opacity:1;visibility:visible; }
```

```html
<div data-tooltip="Fully extracted · data from 3 days ago">...</div>
```

**Why this doesn't get stuck**: there's no browser-internal state to desync. `:hover` is
re-evaluated continuously against the actual current cursor position on every paint — even
across a Livewire morph, the tooltip only ever shows while the cursor is genuinely over the
element right now. It literally cannot show a stale/phantom tooltip the way native `title`
can.

Paste the CSS block once per page (inside that page's own `<style>` block — this codebase
doesn't have a shared/global stylesheet for admin pages, each Filament page's blade carries
its own `<style>`), then use `data-tooltip="..."` anywhere `title="..."` would have gone.

---

## The gotcha: `overflow:hidden` on the tooltip's own element

If the element carrying `data-tooltip` (or the one the `::after` is positioned relative to)
has `overflow:hidden` — extremely common on card/tile components, to clip an image to the
card's rounded corners — the tooltip **silently never appears**, because the pseudo-element
renders *outside* that element's own box (`bottom:100%` = above it) and gets clipped by the
same rule.

This bit the first real usage: `.jlr-vehicle-card`/`.jlr-section-card` both had
`overflow:hidden` for exactly this image-clipping reason. Fix: **move the `overflow:hidden`
off the tooltip-bearing element and onto a narrower inner wrapper that only wraps the image**,
so the outer (tooltip-bearing) element can stay `overflow:visible`:

```css
/* WRONG — overflow:hidden on the same element that carries data-tooltip clips the tooltip */
.card { overflow:hidden; border-radius:.75rem; }

/* RIGHT — clipping moves to an inner wrapper; the card itself stays overflow:visible */
.card { border-radius:.75rem; } /* no overflow:hidden here */
.card-media { overflow:hidden; border-radius:.75rem .75rem 0 0; } /* just wraps the image */
```

```html
<div class="card" data-tooltip="...">
    <div class="card-media"><img ...></div>
    <div class="card-body">...</div>
</div>
```

Before shipping a new `data-tooltip`, check every ancestor between it and the page root for
`overflow:hidden` (or `overflow:auto`/`scroll`, same clipping effect) — not just the element
itself. A tooltip that silently never renders is the single most likely failure mode with this
pattern; the CSS itself doesn't error or warn, it just clips invisibly.

---

## Checklist when adding to a new page

1. Add the `[data-tooltip]`/`[data-tooltip]::after` CSS block to that page's own `<style>`
   (copy verbatim from above, or from `browse-catalogue.blade.php`).
2. Replace `title="{{ $foo }}"` with `data-tooltip="{{ $foo }}"` on the element.
3. Check every ancestor of that element for `overflow:hidden`/`auto`/`scroll` — if any exists
   between the tooltip element and wherever the tooltip needs room to render (usually above
   it), move that overflow rule to a narrower inner wrapper instead, per the gotcha above.
4. If the tooltip text can be long/variable-length and the element is narrow, consider adding
   `max-width` + `white-space:normal` to the `::after` rule instead of `white-space:nowrap` —
   the default above assumes a short one-line hint.

---

## Reference implementation

- `plugins/webkul/jlr-epc/resources/views/filament/pages/browse-catalogue.blade.php` —
  vehicle tiles and section tiles both use `data-tooltip` for their "extraction status · data
  age" hint, and both needed the `overflow:hidden` fix (`.jlr-vehicle-card-media` wrapper for
  vehicle tiles; `.jlr-section-thumb`, which already existed, absorbed it for section tiles).
