02 / 20
All 20 in 20 Tailwind CSS Popovers
- 01Tailwind Popover Show and Hide with the Popover API
- 02Tailwind Auto vs Manual Popover Behavior
- 03Tailwind Anchored Popover with CSS Anchor Positioning
- 04Tailwind Popover Entry and Exit Animation
- 05Tailwind Popover Backdrop and Light Dismiss
- 06Tailwind Position Area Popover Placement Grid
- 07Tailwind Popover Flip with Position Try Fallbacks
- 08Tailwind Tooltip Arrow Pointing to Anchor
- 09Tailwind Dropdown Matching Anchor Width
- 10Tailwind Nested Popover Submenu
- 11Tailwind Custom Select Listbox Popover
- 12Tailwind Tooltip on Hover and Focus
- 13Tailwind User Profile Dropdown Menu
- 14Tailwind Date Picker Popover
- 15Tailwind Filter Dropdown with Checkboxes
- 16Tailwind Popover Fallback and Polyfill
- 17Tailwind Popover vs Dialog Modal
- 18Tailwind Glassmorphism Popover
- 19Tailwind Dark Mode Popover Toggle
- 20Tailwind Accessible Tooltip with ARIA
Tailwind Auto vs Manual Popover Behavior
Two state machines, side by side, clickable. popover="auto" light-dismisses, answers Escape and closes other autos; popover="manual" ignores all three. The port adds what the original only described: a live status LED beside every invoker, lit by group-has-[#id:popover-open]/root:, so you watch opening Activity switch Notifications off.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="tpop-02 group/root w-full min-h-svh bg-tpop02-navy bg-[linear-gradient(var(--color-tpop02-grid)_1px,transparent_1px),linear-gradient(90deg,var(--color-tpop02-grid)_1px,transparent_1px)] bg-[size:32px_32px] px-4 py-9 font-tpop02-sans text-tpop02-ink" aria-label="Auto versus manual popover demo">
<div class="grid min-h-[calc(100svh-72px)] max-w-full place-items-center">
<div class="w-full min-w-0 max-w-[44rem] rounded-sm border border-tpop02-rule bg-tpop02-board px-5 pt-6 pb-6.5 shadow-[0_30px_60px_-30px_oklch(0_0_0/0.7)]">
<header class="mb-5.5">
<h2 class="mb-1.5 text-[clamp(21px,4.4vw,28px)] font-semibold leading-tight tracking-[-0.02em]">Dismissal is a state, not a style</h2>
<p class="text-[13.5px] text-tpop02-mut">Open all three. Then click the empty board — and watch the lights.</p>
</header>
<div class="grid grid-cols-[repeat(auto-fit,minmax(min(100%,15rem),1fr))] gap-4.5">
<div class="min-w-0 rounded-sm border border-tpop02-rule bg-tpop02-navy px-3.5 py-4">
<p class="mb-3.5 inline-block rounded-sm bg-tpop02-ok px-2 py-1.5 font-tpop02-mono text-[11px] font-semibold leading-none text-tpop02-navy">popover="auto"</p>
<div class="mb-4 grid gap-2">
<button id="tpop-02-trigger" type="button" popovertarget="tpop-02-auto" class="flex min-h-11 cursor-pointer items-center justify-between gap-3 rounded-sm bg-tpop02-ink px-3.5 text-[13px] font-semibold text-tpop02-navy transition-colors hover:bg-tpop02-ink/90 focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tpop02-ok">
Toggle notifications
<span aria-hidden="true" class="size-2 rounded-full bg-tpop02-navy/25 transition-[background-color,box-shadow] duration-200 group-has-[#tpop-02-auto:popover-open]/root:bg-tpop02-okdeep group-has-[#tpop-02-auto:popover-open]/root:shadow-[0_0_0_3px_oklch(0.62_0.12_180/0.3)]"></span>
</button>
<button type="button" popovertarget="tpop-02-auto2" class="flex min-h-11 cursor-pointer items-center justify-between gap-3 rounded-sm border border-tpop02-rule px-3.5 text-[13px] font-semibold text-tpop02-ink transition-colors hover:border-tpop02-mut focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tpop02-ok">
Toggle activity
<span aria-hidden="true" class="size-2 rounded-full bg-tpop02-rule transition-[background-color,box-shadow] duration-200 group-has-[#tpop-02-auto2:popover-open]/root:bg-tpop02-ok group-has-[#tpop-02-auto2:popover-open]/root:shadow-[0_0_10px_var(--color-tpop02-ok)]"></span>
</button>
</div>
<ul class="grid gap-2">
<li class="relative min-w-0 pl-4 text-[13px] leading-normal text-tpop02-mut before:absolute before:top-[7px] before:left-0 before:size-1.5 before:bg-tpop02-ok">Outside click closes it</li>
<li class="relative min-w-0 pl-4 text-[13px] leading-normal text-tpop02-mut before:absolute before:top-[7px] before:left-0 before:size-1.5 before:bg-tpop02-ok">Escape closes it</li>
<li class="relative min-w-0 pl-4 text-[13px] leading-normal text-tpop02-mut before:absolute before:top-[7px] before:left-0 before:size-1.5 before:bg-tpop02-ok">Opening another auto closes it</li>
</ul>
</div>
<div class="min-w-0 rounded-sm border border-tpop02-rule bg-tpop02-navy px-3.5 py-4">
<p class="mb-3.5 inline-block rounded-sm bg-tpop02-warn px-2 py-1.5 font-tpop02-mono text-[11px] font-semibold leading-none text-tpop02-navy">popover="manual"</p>
<div class="mb-4 grid gap-2">
<button type="button" popovertarget="tpop-02-manual" popovertargetaction="show" class="flex min-h-11 cursor-pointer items-center justify-between gap-3 rounded-sm bg-tpop02-ink px-3.5 text-[13px] font-semibold text-tpop02-navy transition-colors hover:bg-tpop02-ink/90 focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tpop02-warn">
Show inspector
<span aria-hidden="true" class="size-2 rounded-full bg-tpop02-navy/25 transition-[background-color,box-shadow] duration-200 group-has-[#tpop-02-manual:popover-open]/root:bg-tpop02-warndeep group-has-[#tpop-02-manual:popover-open]/root:shadow-[0_0_0_3px_oklch(0.7_0.13_65/0.35)]"></span>
</button>
<button type="button" popovertarget="tpop-02-manual" popovertargetaction="hide" class="flex min-h-11 cursor-pointer items-center justify-between gap-3 rounded-sm border border-tpop02-rule px-3.5 text-[13px] font-semibold text-tpop02-ink transition-colors hover:border-tpop02-mut focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tpop02-warn">Hide inspector</button>
</div>
<ul class="grid gap-2">
<li class="relative min-w-0 pl-4 text-[13px] leading-normal text-tpop02-mut before:absolute before:top-[7px] before:left-0 before:size-1.5 before:bg-tpop02-warn">Outside click does nothing</li>
<li class="relative min-w-0 pl-4 text-[13px] leading-normal text-tpop02-mut before:absolute before:top-[7px] before:left-0 before:size-1.5 before:bg-tpop02-warn">Escape does nothing</li>
<li class="relative min-w-0 pl-4 text-[13px] leading-normal text-tpop02-mut before:absolute before:top-[7px] before:left-0 before:size-1.5 before:bg-tpop02-warn">You own dismissal</li>
</ul>
</div>
</div>
</div>
</div>
<div popover="auto" id="tpop-02-auto" role="group" aria-label="Notifications" class="fixed inset-auto bottom-6 left-6 w-[min(19rem,calc(100vw-28px))] rounded-sm border border-tpop02-rule border-l-2 border-l-tpop02-ok bg-tpop02-surface px-4 pt-4 pb-3.5 text-tpop02-ink opacity-0 shadow-[0_26px_50px_-24px_oklch(0_0_0/0.85)] transition-[opacity,translate,display,overlay] duration-200 ease-out transition-discrete open:opacity-100 starting:open:translate-y-3 starting:open:opacity-0 motion-reduce:transition-none max-[560px]:inset-x-3.5 max-[560px]:bottom-3.5 max-[560px]:w-auto">
<p class="mb-2 text-xs font-semibold uppercase tracking-[0.08em] text-tpop02-mut">Notifications</p>
<p class="mb-1.5 text-[13.5px] leading-normal">Priya Sharma approved deploy <span class="font-tpop02-mono text-[0.9em] text-tpop02-ok">web-4821</span>.</p>
<p class="mb-1.5 text-[13.5px] leading-normal">Nightly export finished in 4m 12s.</p>
<p class="mt-2.5 border-t border-tpop02-rule pt-2.5 text-xs text-tpop02-mut">Auto · light dismiss on</p>
</div>
<div popover="auto" id="tpop-02-auto2" role="group" aria-label="Activity" class="fixed inset-auto top-6 right-6 w-[min(19rem,calc(100vw-28px))] rounded-sm border border-tpop02-rule border-l-2 border-l-tpop02-ok bg-tpop02-surface px-4 pt-4 pb-3.5 text-tpop02-ink opacity-0 shadow-[0_26px_50px_-24px_oklch(0_0_0/0.85)] transition-[opacity,translate,display,overlay] duration-200 ease-out transition-discrete open:opacity-100 starting:open:-translate-y-3 starting:open:opacity-0 motion-reduce:transition-none max-[560px]:inset-x-3.5 max-[560px]:top-3.5 max-[560px]:w-auto">
<p class="mb-2 text-xs font-semibold uppercase tracking-[0.08em] text-tpop02-mut">Activity</p>
<p class="mb-1.5 text-[13.5px] leading-normal">Jordan Lee opened a draft on Billing.</p>
<p class="mt-2.5 border-t border-tpop02-rule pt-2.5 text-xs text-tpop02-mut">Opening me closed the other auto panel</p>
</div>
<div popover="manual" id="tpop-02-manual" role="group" aria-label="Request inspector" class="fixed inset-auto right-6 bottom-6 w-[min(19rem,calc(100vw-28px))] rounded-sm border border-tpop02-warn bg-tpop02-surface px-4 pt-4 pb-3.5 text-tpop02-ink opacity-0 shadow-[0_26px_50px_-24px_oklch(0_0_0/0.85)] transition-[opacity,translate,display,overlay] duration-200 ease-out transition-discrete open:opacity-100 starting:open:translate-y-3 starting:open:opacity-0 motion-reduce:transition-none max-[560px]:inset-x-3.5 max-[560px]:bottom-21 max-[560px]:w-auto">
<div class="flex items-center justify-between gap-2">
<p class="mb-2 text-xs font-semibold uppercase tracking-[0.08em] text-tpop02-mut">Request inspector</p>
<button type="button" popovertarget="tpop-02-manual" popovertargetaction="hide" aria-label="Close inspector" class="-mt-3.5 -mr-3 inline-flex size-11 cursor-pointer items-center justify-center text-tpop02-warn focus-visible:outline-3 focus-visible:outline-offset-1 focus-visible:outline-tpop02-warn">
<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.9" aria-hidden="true"><path d="M4 4l8 8M12 4l-8 8"/></svg>
</button>
</div>
<p class="mb-1.5 text-[13.5px] leading-normal"><span class="font-tpop02-mono text-[0.9em] text-tpop02-ok">GET /v2/accounts</span> · 200 · 84ms</p>
<p class="mb-1.5 text-[13.5px] leading-normal"><span class="font-tpop02-mono text-[0.9em] text-tpop02-ok">POST /v2/tokens</span> · 201 · 132ms</p>
<p class="mt-2.5 border-t border-tpop02-rule pt-2.5 text-xs text-tpop02-warn">Manual · nothing dismisses me but that button</p>
</div>
</section><section class="tpop-02 group/root w-full min-h-svh bg-tpop02-navy bg-[linear-gradient(var(--color-tpop02-grid)_1px,transparent_1px),linear-gradient(90deg,var(--color-tpop02-grid)_1px,transparent_1px)] bg-[size:32px_32px] px-4 py-9 font-tpop02-sans text-tpop02-ink" aria-label="Auto versus manual popover demo">
<div class="grid min-h-[calc(100svh-72px)] max-w-full place-items-center">
<div class="w-full min-w-0 max-w-[44rem] rounded-sm border border-tpop02-rule bg-tpop02-board px-5 pt-6 pb-6.5 shadow-[0_30px_60px_-30px_oklch(0_0_0/0.7)]">
<header class="mb-5.5">
<h2 class="mb-1.5 text-[clamp(21px,4.4vw,28px)] font-semibold leading-tight tracking-[-0.02em]">Dismissal is a state, not a style</h2>
<p class="text-[13.5px] text-tpop02-mut">Open all three. Then click the empty board — and watch the lights.</p>
</header>
<div class="grid grid-cols-[repeat(auto-fit,minmax(min(100%,15rem),1fr))] gap-4.5">
<div class="min-w-0 rounded-sm border border-tpop02-rule bg-tpop02-navy px-3.5 py-4">
<p class="mb-3.5 inline-block rounded-sm bg-tpop02-ok px-2 py-1.5 font-tpop02-mono text-[11px] font-semibold leading-none text-tpop02-navy">popover="auto"</p>
<div class="mb-4 grid gap-2">
<button id="tpop-02-trigger" type="button" popovertarget="tpop-02-auto" class="flex min-h-11 cursor-pointer items-center justify-between gap-3 rounded-sm bg-tpop02-ink px-3.5 text-[13px] font-semibold text-tpop02-navy transition-colors hover:bg-tpop02-ink/90 focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tpop02-ok">
Toggle notifications
<span aria-hidden="true" class="size-2 rounded-full bg-tpop02-navy/25 transition-[background-color,box-shadow] duration-200 group-has-[#tpop-02-auto:popover-open]/root:bg-tpop02-okdeep group-has-[#tpop-02-auto:popover-open]/root:shadow-[0_0_0_3px_oklch(0.62_0.12_180/0.3)]"></span>
</button>
<button type="button" popovertarget="tpop-02-auto2" class="flex min-h-11 cursor-pointer items-center justify-between gap-3 rounded-sm border border-tpop02-rule px-3.5 text-[13px] font-semibold text-tpop02-ink transition-colors hover:border-tpop02-mut focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tpop02-ok">
Toggle activity
<span aria-hidden="true" class="size-2 rounded-full bg-tpop02-rule transition-[background-color,box-shadow] duration-200 group-has-[#tpop-02-auto2:popover-open]/root:bg-tpop02-ok group-has-[#tpop-02-auto2:popover-open]/root:shadow-[0_0_10px_var(--color-tpop02-ok)]"></span>
</button>
</div>
<ul class="grid gap-2">
<li class="relative min-w-0 pl-4 text-[13px] leading-normal text-tpop02-mut before:absolute before:top-[7px] before:left-0 before:size-1.5 before:bg-tpop02-ok">Outside click closes it</li>
<li class="relative min-w-0 pl-4 text-[13px] leading-normal text-tpop02-mut before:absolute before:top-[7px] before:left-0 before:size-1.5 before:bg-tpop02-ok">Escape closes it</li>
<li class="relative min-w-0 pl-4 text-[13px] leading-normal text-tpop02-mut before:absolute before:top-[7px] before:left-0 before:size-1.5 before:bg-tpop02-ok">Opening another auto closes it</li>
</ul>
</div>
<div class="min-w-0 rounded-sm border border-tpop02-rule bg-tpop02-navy px-3.5 py-4">
<p class="mb-3.5 inline-block rounded-sm bg-tpop02-warn px-2 py-1.5 font-tpop02-mono text-[11px] font-semibold leading-none text-tpop02-navy">popover="manual"</p>
<div class="mb-4 grid gap-2">
<button type="button" popovertarget="tpop-02-manual" popovertargetaction="show" class="flex min-h-11 cursor-pointer items-center justify-between gap-3 rounded-sm bg-tpop02-ink px-3.5 text-[13px] font-semibold text-tpop02-navy transition-colors hover:bg-tpop02-ink/90 focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tpop02-warn">
Show inspector
<span aria-hidden="true" class="size-2 rounded-full bg-tpop02-navy/25 transition-[background-color,box-shadow] duration-200 group-has-[#tpop-02-manual:popover-open]/root:bg-tpop02-warndeep group-has-[#tpop-02-manual:popover-open]/root:shadow-[0_0_0_3px_oklch(0.7_0.13_65/0.35)]"></span>
</button>
<button type="button" popovertarget="tpop-02-manual" popovertargetaction="hide" class="flex min-h-11 cursor-pointer items-center justify-between gap-3 rounded-sm border border-tpop02-rule px-3.5 text-[13px] font-semibold text-tpop02-ink transition-colors hover:border-tpop02-mut focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tpop02-warn">Hide inspector</button>
</div>
<ul class="grid gap-2">
<li class="relative min-w-0 pl-4 text-[13px] leading-normal text-tpop02-mut before:absolute before:top-[7px] before:left-0 before:size-1.5 before:bg-tpop02-warn">Outside click does nothing</li>
<li class="relative min-w-0 pl-4 text-[13px] leading-normal text-tpop02-mut before:absolute before:top-[7px] before:left-0 before:size-1.5 before:bg-tpop02-warn">Escape does nothing</li>
<li class="relative min-w-0 pl-4 text-[13px] leading-normal text-tpop02-mut before:absolute before:top-[7px] before:left-0 before:size-1.5 before:bg-tpop02-warn">You own dismissal</li>
</ul>
</div>
</div>
</div>
</div>
<div popover="auto" id="tpop-02-auto" role="group" aria-label="Notifications" class="fixed inset-auto bottom-6 left-6 w-[min(19rem,calc(100vw-28px))] rounded-sm border border-tpop02-rule border-l-2 border-l-tpop02-ok bg-tpop02-surface px-4 pt-4 pb-3.5 text-tpop02-ink opacity-0 shadow-[0_26px_50px_-24px_oklch(0_0_0/0.85)] transition-[opacity,translate,display,overlay] duration-200 ease-out transition-discrete open:opacity-100 starting:open:translate-y-3 starting:open:opacity-0 motion-reduce:transition-none max-[560px]:inset-x-3.5 max-[560px]:bottom-3.5 max-[560px]:w-auto">
<p class="mb-2 text-xs font-semibold uppercase tracking-[0.08em] text-tpop02-mut">Notifications</p>
<p class="mb-1.5 text-[13.5px] leading-normal">Priya Sharma approved deploy <span class="font-tpop02-mono text-[0.9em] text-tpop02-ok">web-4821</span>.</p>
<p class="mb-1.5 text-[13.5px] leading-normal">Nightly export finished in 4m 12s.</p>
<p class="mt-2.5 border-t border-tpop02-rule pt-2.5 text-xs text-tpop02-mut">Auto · light dismiss on</p>
</div>
<div popover="auto" id="tpop-02-auto2" role="group" aria-label="Activity" class="fixed inset-auto top-6 right-6 w-[min(19rem,calc(100vw-28px))] rounded-sm border border-tpop02-rule border-l-2 border-l-tpop02-ok bg-tpop02-surface px-4 pt-4 pb-3.5 text-tpop02-ink opacity-0 shadow-[0_26px_50px_-24px_oklch(0_0_0/0.85)] transition-[opacity,translate,display,overlay] duration-200 ease-out transition-discrete open:opacity-100 starting:open:-translate-y-3 starting:open:opacity-0 motion-reduce:transition-none max-[560px]:inset-x-3.5 max-[560px]:top-3.5 max-[560px]:w-auto">
<p class="mb-2 text-xs font-semibold uppercase tracking-[0.08em] text-tpop02-mut">Activity</p>
<p class="mb-1.5 text-[13.5px] leading-normal">Jordan Lee opened a draft on Billing.</p>
<p class="mt-2.5 border-t border-tpop02-rule pt-2.5 text-xs text-tpop02-mut">Opening me closed the other auto panel</p>
</div>
<div popover="manual" id="tpop-02-manual" role="group" aria-label="Request inspector" class="fixed inset-auto right-6 bottom-6 w-[min(19rem,calc(100vw-28px))] rounded-sm border border-tpop02-warn bg-tpop02-surface px-4 pt-4 pb-3.5 text-tpop02-ink opacity-0 shadow-[0_26px_50px_-24px_oklch(0_0_0/0.85)] transition-[opacity,translate,display,overlay] duration-200 ease-out transition-discrete open:opacity-100 starting:open:translate-y-3 starting:open:opacity-0 motion-reduce:transition-none max-[560px]:inset-x-3.5 max-[560px]:bottom-21 max-[560px]:w-auto">
<div class="flex items-center justify-between gap-2">
<p class="mb-2 text-xs font-semibold uppercase tracking-[0.08em] text-tpop02-mut">Request inspector</p>
<button type="button" popovertarget="tpop-02-manual" popovertargetaction="hide" aria-label="Close inspector" class="-mt-3.5 -mr-3 inline-flex size-11 cursor-pointer items-center justify-center text-tpop02-warn focus-visible:outline-3 focus-visible:outline-offset-1 focus-visible:outline-tpop02-warn">
<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.9" aria-hidden="true"><path d="M4 4l8 8M12 4l-8 8"/></svg>
</button>
</div>
<p class="mb-1.5 text-[13.5px] leading-normal"><span class="font-tpop02-mono text-[0.9em] text-tpop02-ok">GET /v2/accounts</span> · 200 · 84ms</p>
<p class="mb-1.5 text-[13.5px] leading-normal"><span class="font-tpop02-mono text-[0.9em] text-tpop02-ok">POST /v2/tokens</span> · 201 · 132ms</p>
<p class="mt-2.5 border-t border-tpop02-rule pt-2.5 text-xs text-tpop02-warn">Manual · nothing dismisses me but that button</p>
</div>
</section>@import "tailwindcss";
@theme {
--color-tpop02-navy: #0a152a;
--color-tpop02-navy: oklch(0.2 0.045 262);
--color-tpop02-grid: #16243c8c;
--color-tpop02-grid: oklch(0.26 0.05 262 / 0.55);
--color-tpop02-board: #13213c;
--color-tpop02-board: oklch(0.25 0.055 262);
--color-tpop02-surface: #1c3051;
--color-tpop02-surface: oklch(0.31 0.065 260);
--color-tpop02-ink: #e8eff9;
--color-tpop02-ink: oklch(0.95 0.015 255);
--color-tpop02-mut: #a6b9d5;
--color-tpop02-mut: oklch(0.78 0.045 258);
--color-tpop02-rule: #29415f;
--color-tpop02-rule: oklch(0.37 0.06 255);
--color-tpop02-ok: #61d5c0;
--color-tpop02-ok: oklch(0.8 0.11 180);
--color-tpop02-okdeep: #007b6b;
--color-tpop02-okdeep: oklch(0.52 0.1 180);
--color-tpop02-warn: #f6b069;
--color-tpop02-warn: oklch(0.81 0.12 65);
--color-tpop02-warndeep: #b3621e;
--color-tpop02-warndeep: oklch(0.58 0.13 55);
--font-tpop02-sans: 'Space Grotesk', system-ui, sans-serif;
--font-tpop02-mono: 'JetBrains Mono', ui-monospace, monospace;
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities, so the
stage is sized before the browser build compiles. */
.tpop-02 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-tpop02-navy: #0a152a;
--color-tpop02-navy: oklch(0.2 0.045 262);
--color-tpop02-grid: #16243c8c;
--color-tpop02-grid: oklch(0.26 0.05 262 / 0.55);
--color-tpop02-board: #13213c;
--color-tpop02-board: oklch(0.25 0.055 262);
--color-tpop02-surface: #1c3051;
--color-tpop02-surface: oklch(0.31 0.065 260);
--color-tpop02-ink: #e8eff9;
--color-tpop02-ink: oklch(0.95 0.015 255);
--color-tpop02-mut: #a6b9d5;
--color-tpop02-mut: oklch(0.78 0.045 258);
--color-tpop02-rule: #29415f;
--color-tpop02-rule: oklch(0.37 0.06 255);
--color-tpop02-ok: #61d5c0;
--color-tpop02-ok: oklch(0.8 0.11 180);
--color-tpop02-okdeep: #007b6b;
--color-tpop02-okdeep: oklch(0.52 0.1 180);
--color-tpop02-warn: #f6b069;
--color-tpop02-warn: oklch(0.81 0.12 65);
--color-tpop02-warndeep: #b3621e;
--color-tpop02-warndeep: oklch(0.58 0.13 55);
--font-tpop02-sans: 'Space Grotesk', system-ui, sans-serif;
--font-tpop02-mono: 'JetBrains Mono', ui-monospace, monospace;
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities, so the
stage is sized before the browser build compiles. */
.tpop-02 {
width: 100%;
min-height: 100svh;
}Setup — do this once per project
Skip this if your project already runs Tailwind v4.
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>Compiles in the browser — perfect for a CodePen or a quick test, not for production.
npm install tailwindcss @tailwindcss/vite
npm install tailwindcss @tailwindcss/vite// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})Any v4 setup works — Vite, PostCSS or the CLI. Nothing in this demo is bundler-specific.
@import "tailwindcss";
@theme {
--color-tpop02-navy: #0a152a;
--color-tpop02-navy: oklch(0.2 0.045 262);
--color-tpop02-grid: #16243c8c;
--color-tpop02-grid: oklch(0.26 0.05 262 / 0.55);
--color-tpop02-board: #13213c;
--color-tpop02-board: oklch(0.25 0.055 262);
--color-tpop02-surface: #1c3051;
--color-tpop02-surface: oklch(0.31 0.065 260);
--color-tpop02-ink: #e8eff9;
--color-tpop02-ink: oklch(0.95 0.015 255);
--color-tpop02-mut: #a6b9d5;
--color-tpop02-mut: oklch(0.78 0.045 258);
--color-tpop02-rule: #29415f;
--color-tpop02-rule: oklch(0.37 0.06 255);
--color-tpop02-ok: #61d5c0;
--color-tpop02-ok: oklch(0.8 0.11 180);
--color-tpop02-okdeep: #007b6b;
--color-tpop02-okdeep: oklch(0.52 0.1 180);
--color-tpop02-warn: #f6b069;
--color-tpop02-warn: oklch(0.81 0.12 65);
--color-tpop02-warndeep: #b3621e;
--color-tpop02-warndeep: oklch(0.58 0.13 55);
--font-tpop02-sans: 'Space Grotesk', system-ui, sans-serif;
--font-tpop02-mono: 'JetBrains Mono', ui-monospace, monospace;
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities, so the
stage is sized before the browser build compiles. */
.tpop-02 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-tpop02-navy: #0a152a;
--color-tpop02-navy: oklch(0.2 0.045 262);
--color-tpop02-grid: #16243c8c;
--color-tpop02-grid: oklch(0.26 0.05 262 / 0.55);
--color-tpop02-board: #13213c;
--color-tpop02-board: oklch(0.25 0.055 262);
--color-tpop02-surface: #1c3051;
--color-tpop02-surface: oklch(0.31 0.065 260);
--color-tpop02-ink: #e8eff9;
--color-tpop02-ink: oklch(0.95 0.015 255);
--color-tpop02-mut: #a6b9d5;
--color-tpop02-mut: oklch(0.78 0.045 258);
--color-tpop02-rule: #29415f;
--color-tpop02-rule: oklch(0.37 0.06 255);
--color-tpop02-ok: #61d5c0;
--color-tpop02-ok: oklch(0.8 0.11 180);
--color-tpop02-okdeep: #007b6b;
--color-tpop02-okdeep: oklch(0.52 0.1 180);
--color-tpop02-warn: #f6b069;
--color-tpop02-warn: oklch(0.81 0.12 65);
--color-tpop02-warndeep: #b3621e;
--color-tpop02-warndeep: oklch(0.58 0.13 55);
--font-tpop02-sans: 'Space Grotesk', system-ui, sans-serif;
--font-tpop02-mono: 'JetBrains Mono', ui-monospace, monospace;
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities, so the
stage is sized before the browser build compiles. */
.tpop-02 {
width: 100%;
min-height: 100svh;
}<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400..700&family=JetBrains+Mono:wght@400;500;600;700&display=swap">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400..700&family=JetBrains+Mono:wght@400;500;600;700&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- Three
.pop-02__panel--*inset rules and a 560px media block becameinset-auto bottom-6 left-6 max-[560px]:inset-x-3.5on each panel — the docking and the re-docking sit on the element they move. .pop-02__rule::beforebecamebefore:absolute before:size-1.5 before:bg-tpop02-ok; bullets are now coloured by mode (teal auto, amber manual).- UI upgrade from the CSS original: every invoker carries a status LED lit by
group-has-[#id:popover-open]/root:, turning the one-at-a-time rule from prose into something you watch happen — zero JS. - UI upgrade: panels now rise from their docking edge and fade out on close (the original popped), the board sits on a faint blueprint grid, and muted copy rose from
#9db2d4tooklch(0.78).
Here's a working CSS demo from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Tailwind Auto vs Manual Popover Behavior
Source: https://codefronts.com/snippets/tailwind-css-popovers/tailwind-popover-auto-vs-manual/
Two state machines, side by side, clickable. popover="auto" light-dismisses, answers Escape and closes other autos; popover="manual" ignores all three. The port adds what the original only described: a live status LED beside every invoker, lit by group-has-[#id:popover-open]/root:, so you watch opening Activity switch Notifications off.
## HTML
```html
<section class="tpop-02 group/root w-full min-h-svh bg-tpop02-navy bg-[linear-gradient(var(--color-tpop02-grid)_1px,transparent_1px),linear-gradient(90deg,var(--color-tpop02-grid)_1px,transparent_1px)] bg-[size:32px_32px] px-4 py-9 font-tpop02-sans text-tpop02-ink" aria-label="Auto versus manual popover demo">
<div class="grid min-h-[calc(100svh-72px)] max-w-full place-items-center">
<div class="w-full min-w-0 max-w-[44rem] rounded-sm border border-tpop02-rule bg-tpop02-board px-5 pt-6 pb-6.5 shadow-[0_30px_60px_-30px_oklch(0_0_0/0.7)]">
<header class="mb-5.5">
<h2 class="mb-1.5 text-[clamp(21px,4.4vw,28px)] font-semibold leading-tight tracking-[-0.02em]">Dismissal is a state, not a style</h2>
<p class="text-[13.5px] text-tpop02-mut">Open all three. Then click the empty board — and watch the lights.</p>
</header>
<div class="grid grid-cols-[repeat(auto-fit,minmax(min(100%,15rem),1fr))] gap-4.5">
<div class="min-w-0 rounded-sm border border-tpop02-rule bg-tpop02-navy px-3.5 py-4">
<p class="mb-3.5 inline-block rounded-sm bg-tpop02-ok px-2 py-1.5 font-tpop02-mono text-[11px] font-semibold leading-none text-tpop02-navy">popover="auto"</p>
<div class="mb-4 grid gap-2">
<button id="tpop-02-trigger" type="button" popovertarget="tpop-02-auto" class="flex min-h-11 cursor-pointer items-center justify-between gap-3 rounded-sm bg-tpop02-ink px-3.5 text-[13px] font-semibold text-tpop02-navy transition-colors hover:bg-tpop02-ink/90 focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tpop02-ok">
Toggle notifications
<span aria-hidden="true" class="size-2 rounded-full bg-tpop02-navy/25 transition-[background-color,box-shadow] duration-200 group-has-[#tpop-02-auto:popover-open]/root:bg-tpop02-okdeep group-has-[#tpop-02-auto:popover-open]/root:shadow-[0_0_0_3px_oklch(0.62_0.12_180/0.3)]"></span>
</button>
<button type="button" popovertarget="tpop-02-auto2" class="flex min-h-11 cursor-pointer items-center justify-between gap-3 rounded-sm border border-tpop02-rule px-3.5 text-[13px] font-semibold text-tpop02-ink transition-colors hover:border-tpop02-mut focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tpop02-ok">
Toggle activity
<span aria-hidden="true" class="size-2 rounded-full bg-tpop02-rule transition-[background-color,box-shadow] duration-200 group-has-[#tpop-02-auto2:popover-open]/root:bg-tpop02-ok group-has-[#tpop-02-auto2:popover-open]/root:shadow-[0_0_10px_var(--color-tpop02-ok)]"></span>
</button>
</div>
<ul class="grid gap-2">
<li class="relative min-w-0 pl-4 text-[13px] leading-normal text-tpop02-mut before:absolute before:top-[7px] before:left-0 before:size-1.5 before:bg-tpop02-ok">Outside click closes it</li>
<li class="relative min-w-0 pl-4 text-[13px] leading-normal text-tpop02-mut before:absolute before:top-[7px] before:left-0 before:size-1.5 before:bg-tpop02-ok">Escape closes it</li>
<li class="relative min-w-0 pl-4 text-[13px] leading-normal text-tpop02-mut before:absolute before:top-[7px] before:left-0 before:size-1.5 before:bg-tpop02-ok">Opening another auto closes it</li>
</ul>
</div>
<div class="min-w-0 rounded-sm border border-tpop02-rule bg-tpop02-navy px-3.5 py-4">
<p class="mb-3.5 inline-block rounded-sm bg-tpop02-warn px-2 py-1.5 font-tpop02-mono text-[11px] font-semibold leading-none text-tpop02-navy">popover="manual"</p>
<div class="mb-4 grid gap-2">
<button type="button" popovertarget="tpop-02-manual" popovertargetaction="show" class="flex min-h-11 cursor-pointer items-center justify-between gap-3 rounded-sm bg-tpop02-ink px-3.5 text-[13px] font-semibold text-tpop02-navy transition-colors hover:bg-tpop02-ink/90 focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tpop02-warn">
Show inspector
<span aria-hidden="true" class="size-2 rounded-full bg-tpop02-navy/25 transition-[background-color,box-shadow] duration-200 group-has-[#tpop-02-manual:popover-open]/root:bg-tpop02-warndeep group-has-[#tpop-02-manual:popover-open]/root:shadow-[0_0_0_3px_oklch(0.7_0.13_65/0.35)]"></span>
</button>
<button type="button" popovertarget="tpop-02-manual" popovertargetaction="hide" class="flex min-h-11 cursor-pointer items-center justify-between gap-3 rounded-sm border border-tpop02-rule px-3.5 text-[13px] font-semibold text-tpop02-ink transition-colors hover:border-tpop02-mut focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tpop02-warn">Hide inspector</button>
</div>
<ul class="grid gap-2">
<li class="relative min-w-0 pl-4 text-[13px] leading-normal text-tpop02-mut before:absolute before:top-[7px] before:left-0 before:size-1.5 before:bg-tpop02-warn">Outside click does nothing</li>
<li class="relative min-w-0 pl-4 text-[13px] leading-normal text-tpop02-mut before:absolute before:top-[7px] before:left-0 before:size-1.5 before:bg-tpop02-warn">Escape does nothing</li>
<li class="relative min-w-0 pl-4 text-[13px] leading-normal text-tpop02-mut before:absolute before:top-[7px] before:left-0 before:size-1.5 before:bg-tpop02-warn">You own dismissal</li>
</ul>
</div>
</div>
</div>
</div>
<div popover="auto" id="tpop-02-auto" role="group" aria-label="Notifications" class="fixed inset-auto bottom-6 left-6 w-[min(19rem,calc(100vw-28px))] rounded-sm border border-tpop02-rule border-l-2 border-l-tpop02-ok bg-tpop02-surface px-4 pt-4 pb-3.5 text-tpop02-ink opacity-0 shadow-[0_26px_50px_-24px_oklch(0_0_0/0.85)] transition-[opacity,translate,display,overlay] duration-200 ease-out transition-discrete open:opacity-100 starting:open:translate-y-3 starting:open:opacity-0 motion-reduce:transition-none max-[560px]:inset-x-3.5 max-[560px]:bottom-3.5 max-[560px]:w-auto">
<p class="mb-2 text-xs font-semibold uppercase tracking-[0.08em] text-tpop02-mut">Notifications</p>
<p class="mb-1.5 text-[13.5px] leading-normal">Priya Sharma approved deploy <span class="font-tpop02-mono text-[0.9em] text-tpop02-ok">web-4821</span>.</p>
<p class="mb-1.5 text-[13.5px] leading-normal">Nightly export finished in 4m 12s.</p>
<p class="mt-2.5 border-t border-tpop02-rule pt-2.5 text-xs text-tpop02-mut">Auto · light dismiss on</p>
</div>
<div popover="auto" id="tpop-02-auto2" role="group" aria-label="Activity" class="fixed inset-auto top-6 right-6 w-[min(19rem,calc(100vw-28px))] rounded-sm border border-tpop02-rule border-l-2 border-l-tpop02-ok bg-tpop02-surface px-4 pt-4 pb-3.5 text-tpop02-ink opacity-0 shadow-[0_26px_50px_-24px_oklch(0_0_0/0.85)] transition-[opacity,translate,display,overlay] duration-200 ease-out transition-discrete open:opacity-100 starting:open:-translate-y-3 starting:open:opacity-0 motion-reduce:transition-none max-[560px]:inset-x-3.5 max-[560px]:top-3.5 max-[560px]:w-auto">
<p class="mb-2 text-xs font-semibold uppercase tracking-[0.08em] text-tpop02-mut">Activity</p>
<p class="mb-1.5 text-[13.5px] leading-normal">Jordan Lee opened a draft on Billing.</p>
<p class="mt-2.5 border-t border-tpop02-rule pt-2.5 text-xs text-tpop02-mut">Opening me closed the other auto panel</p>
</div>
<div popover="manual" id="tpop-02-manual" role="group" aria-label="Request inspector" class="fixed inset-auto right-6 bottom-6 w-[min(19rem,calc(100vw-28px))] rounded-sm border border-tpop02-warn bg-tpop02-surface px-4 pt-4 pb-3.5 text-tpop02-ink opacity-0 shadow-[0_26px_50px_-24px_oklch(0_0_0/0.85)] transition-[opacity,translate,display,overlay] duration-200 ease-out transition-discrete open:opacity-100 starting:open:translate-y-3 starting:open:opacity-0 motion-reduce:transition-none max-[560px]:inset-x-3.5 max-[560px]:bottom-21 max-[560px]:w-auto">
<div class="flex items-center justify-between gap-2">
<p class="mb-2 text-xs font-semibold uppercase tracking-[0.08em] text-tpop02-mut">Request inspector</p>
<button type="button" popovertarget="tpop-02-manual" popovertargetaction="hide" aria-label="Close inspector" class="-mt-3.5 -mr-3 inline-flex size-11 cursor-pointer items-center justify-center text-tpop02-warn focus-visible:outline-3 focus-visible:outline-offset-1 focus-visible:outline-tpop02-warn">
<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.9" aria-hidden="true"><path d="M4 4l8 8M12 4l-8 8"/></svg>
</button>
</div>
<p class="mb-1.5 text-[13.5px] leading-normal"><span class="font-tpop02-mono text-[0.9em] text-tpop02-ok">GET /v2/accounts</span> · 200 · 84ms</p>
<p class="mb-1.5 text-[13.5px] leading-normal"><span class="font-tpop02-mono text-[0.9em] text-tpop02-ok">POST /v2/tokens</span> · 201 · 132ms</p>
<p class="mt-2.5 border-t border-tpop02-rule pt-2.5 text-xs text-tpop02-warn">Manual · nothing dismisses me but that button</p>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tpop02-navy: #0a152a;
--color-tpop02-navy: oklch(0.2 0.045 262);
--color-tpop02-grid: #16243c8c;
--color-tpop02-grid: oklch(0.26 0.05 262 / 0.55);
--color-tpop02-board: #13213c;
--color-tpop02-board: oklch(0.25 0.055 262);
--color-tpop02-surface: #1c3051;
--color-tpop02-surface: oklch(0.31 0.065 260);
--color-tpop02-ink: #e8eff9;
--color-tpop02-ink: oklch(0.95 0.015 255);
--color-tpop02-mut: #a6b9d5;
--color-tpop02-mut: oklch(0.78 0.045 258);
--color-tpop02-rule: #29415f;
--color-tpop02-rule: oklch(0.37 0.06 255);
--color-tpop02-ok: #61d5c0;
--color-tpop02-ok: oklch(0.8 0.11 180);
--color-tpop02-okdeep: #007b6b;
--color-tpop02-okdeep: oklch(0.52 0.1 180);
--color-tpop02-warn: #f6b069;
--color-tpop02-warn: oklch(0.81 0.12 65);
--color-tpop02-warndeep: #b3621e;
--color-tpop02-warndeep: oklch(0.58 0.13 55);
--font-tpop02-sans: 'Space Grotesk', system-ui, sans-serif;
--font-tpop02-mono: 'JetBrains Mono', ui-monospace, monospace;
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities, so the
stage is sized before the browser build compiles. */
.tpop-02 {
width: 100%;
min-height: 100svh;
}
```Here's a working CSS demo from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Tailwind Auto vs Manual Popover Behavior
Source: https://codefronts.com/snippets/tailwind-css-popovers/tailwind-popover-auto-vs-manual/
Two state machines, side by side, clickable. popover="auto" light-dismisses, answers Escape and closes other autos; popover="manual" ignores all three. The port adds what the original only described: a live status LED beside every invoker, lit by group-has-[#id:popover-open]/root:, so you watch opening Activity switch Notifications off.
## HTML
```html
<section class="tpop-02 group/root w-full min-h-svh bg-tpop02-navy bg-[linear-gradient(var(--color-tpop02-grid)_1px,transparent_1px),linear-gradient(90deg,var(--color-tpop02-grid)_1px,transparent_1px)] bg-[size:32px_32px] px-4 py-9 font-tpop02-sans text-tpop02-ink" aria-label="Auto versus manual popover demo">
<div class="grid min-h-[calc(100svh-72px)] max-w-full place-items-center">
<div class="w-full min-w-0 max-w-[44rem] rounded-sm border border-tpop02-rule bg-tpop02-board px-5 pt-6 pb-6.5 shadow-[0_30px_60px_-30px_oklch(0_0_0/0.7)]">
<header class="mb-5.5">
<h2 class="mb-1.5 text-[clamp(21px,4.4vw,28px)] font-semibold leading-tight tracking-[-0.02em]">Dismissal is a state, not a style</h2>
<p class="text-[13.5px] text-tpop02-mut">Open all three. Then click the empty board — and watch the lights.</p>
</header>
<div class="grid grid-cols-[repeat(auto-fit,minmax(min(100%,15rem),1fr))] gap-4.5">
<div class="min-w-0 rounded-sm border border-tpop02-rule bg-tpop02-navy px-3.5 py-4">
<p class="mb-3.5 inline-block rounded-sm bg-tpop02-ok px-2 py-1.5 font-tpop02-mono text-[11px] font-semibold leading-none text-tpop02-navy">popover="auto"</p>
<div class="mb-4 grid gap-2">
<button id="tpop-02-trigger" type="button" popovertarget="tpop-02-auto" class="flex min-h-11 cursor-pointer items-center justify-between gap-3 rounded-sm bg-tpop02-ink px-3.5 text-[13px] font-semibold text-tpop02-navy transition-colors hover:bg-tpop02-ink/90 focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tpop02-ok">
Toggle notifications
<span aria-hidden="true" class="size-2 rounded-full bg-tpop02-navy/25 transition-[background-color,box-shadow] duration-200 group-has-[#tpop-02-auto:popover-open]/root:bg-tpop02-okdeep group-has-[#tpop-02-auto:popover-open]/root:shadow-[0_0_0_3px_oklch(0.62_0.12_180/0.3)]"></span>
</button>
<button type="button" popovertarget="tpop-02-auto2" class="flex min-h-11 cursor-pointer items-center justify-between gap-3 rounded-sm border border-tpop02-rule px-3.5 text-[13px] font-semibold text-tpop02-ink transition-colors hover:border-tpop02-mut focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tpop02-ok">
Toggle activity
<span aria-hidden="true" class="size-2 rounded-full bg-tpop02-rule transition-[background-color,box-shadow] duration-200 group-has-[#tpop-02-auto2:popover-open]/root:bg-tpop02-ok group-has-[#tpop-02-auto2:popover-open]/root:shadow-[0_0_10px_var(--color-tpop02-ok)]"></span>
</button>
</div>
<ul class="grid gap-2">
<li class="relative min-w-0 pl-4 text-[13px] leading-normal text-tpop02-mut before:absolute before:top-[7px] before:left-0 before:size-1.5 before:bg-tpop02-ok">Outside click closes it</li>
<li class="relative min-w-0 pl-4 text-[13px] leading-normal text-tpop02-mut before:absolute before:top-[7px] before:left-0 before:size-1.5 before:bg-tpop02-ok">Escape closes it</li>
<li class="relative min-w-0 pl-4 text-[13px] leading-normal text-tpop02-mut before:absolute before:top-[7px] before:left-0 before:size-1.5 before:bg-tpop02-ok">Opening another auto closes it</li>
</ul>
</div>
<div class="min-w-0 rounded-sm border border-tpop02-rule bg-tpop02-navy px-3.5 py-4">
<p class="mb-3.5 inline-block rounded-sm bg-tpop02-warn px-2 py-1.5 font-tpop02-mono text-[11px] font-semibold leading-none text-tpop02-navy">popover="manual"</p>
<div class="mb-4 grid gap-2">
<button type="button" popovertarget="tpop-02-manual" popovertargetaction="show" class="flex min-h-11 cursor-pointer items-center justify-between gap-3 rounded-sm bg-tpop02-ink px-3.5 text-[13px] font-semibold text-tpop02-navy transition-colors hover:bg-tpop02-ink/90 focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tpop02-warn">
Show inspector
<span aria-hidden="true" class="size-2 rounded-full bg-tpop02-navy/25 transition-[background-color,box-shadow] duration-200 group-has-[#tpop-02-manual:popover-open]/root:bg-tpop02-warndeep group-has-[#tpop-02-manual:popover-open]/root:shadow-[0_0_0_3px_oklch(0.7_0.13_65/0.35)]"></span>
</button>
<button type="button" popovertarget="tpop-02-manual" popovertargetaction="hide" class="flex min-h-11 cursor-pointer items-center justify-between gap-3 rounded-sm border border-tpop02-rule px-3.5 text-[13px] font-semibold text-tpop02-ink transition-colors hover:border-tpop02-mut focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tpop02-warn">Hide inspector</button>
</div>
<ul class="grid gap-2">
<li class="relative min-w-0 pl-4 text-[13px] leading-normal text-tpop02-mut before:absolute before:top-[7px] before:left-0 before:size-1.5 before:bg-tpop02-warn">Outside click does nothing</li>
<li class="relative min-w-0 pl-4 text-[13px] leading-normal text-tpop02-mut before:absolute before:top-[7px] before:left-0 before:size-1.5 before:bg-tpop02-warn">Escape does nothing</li>
<li class="relative min-w-0 pl-4 text-[13px] leading-normal text-tpop02-mut before:absolute before:top-[7px] before:left-0 before:size-1.5 before:bg-tpop02-warn">You own dismissal</li>
</ul>
</div>
</div>
</div>
</div>
<div popover="auto" id="tpop-02-auto" role="group" aria-label="Notifications" class="fixed inset-auto bottom-6 left-6 w-[min(19rem,calc(100vw-28px))] rounded-sm border border-tpop02-rule border-l-2 border-l-tpop02-ok bg-tpop02-surface px-4 pt-4 pb-3.5 text-tpop02-ink opacity-0 shadow-[0_26px_50px_-24px_oklch(0_0_0/0.85)] transition-[opacity,translate,display,overlay] duration-200 ease-out transition-discrete open:opacity-100 starting:open:translate-y-3 starting:open:opacity-0 motion-reduce:transition-none max-[560px]:inset-x-3.5 max-[560px]:bottom-3.5 max-[560px]:w-auto">
<p class="mb-2 text-xs font-semibold uppercase tracking-[0.08em] text-tpop02-mut">Notifications</p>
<p class="mb-1.5 text-[13.5px] leading-normal">Priya Sharma approved deploy <span class="font-tpop02-mono text-[0.9em] text-tpop02-ok">web-4821</span>.</p>
<p class="mb-1.5 text-[13.5px] leading-normal">Nightly export finished in 4m 12s.</p>
<p class="mt-2.5 border-t border-tpop02-rule pt-2.5 text-xs text-tpop02-mut">Auto · light dismiss on</p>
</div>
<div popover="auto" id="tpop-02-auto2" role="group" aria-label="Activity" class="fixed inset-auto top-6 right-6 w-[min(19rem,calc(100vw-28px))] rounded-sm border border-tpop02-rule border-l-2 border-l-tpop02-ok bg-tpop02-surface px-4 pt-4 pb-3.5 text-tpop02-ink opacity-0 shadow-[0_26px_50px_-24px_oklch(0_0_0/0.85)] transition-[opacity,translate,display,overlay] duration-200 ease-out transition-discrete open:opacity-100 starting:open:-translate-y-3 starting:open:opacity-0 motion-reduce:transition-none max-[560px]:inset-x-3.5 max-[560px]:top-3.5 max-[560px]:w-auto">
<p class="mb-2 text-xs font-semibold uppercase tracking-[0.08em] text-tpop02-mut">Activity</p>
<p class="mb-1.5 text-[13.5px] leading-normal">Jordan Lee opened a draft on Billing.</p>
<p class="mt-2.5 border-t border-tpop02-rule pt-2.5 text-xs text-tpop02-mut">Opening me closed the other auto panel</p>
</div>
<div popover="manual" id="tpop-02-manual" role="group" aria-label="Request inspector" class="fixed inset-auto right-6 bottom-6 w-[min(19rem,calc(100vw-28px))] rounded-sm border border-tpop02-warn bg-tpop02-surface px-4 pt-4 pb-3.5 text-tpop02-ink opacity-0 shadow-[0_26px_50px_-24px_oklch(0_0_0/0.85)] transition-[opacity,translate,display,overlay] duration-200 ease-out transition-discrete open:opacity-100 starting:open:translate-y-3 starting:open:opacity-0 motion-reduce:transition-none max-[560px]:inset-x-3.5 max-[560px]:bottom-21 max-[560px]:w-auto">
<div class="flex items-center justify-between gap-2">
<p class="mb-2 text-xs font-semibold uppercase tracking-[0.08em] text-tpop02-mut">Request inspector</p>
<button type="button" popovertarget="tpop-02-manual" popovertargetaction="hide" aria-label="Close inspector" class="-mt-3.5 -mr-3 inline-flex size-11 cursor-pointer items-center justify-center text-tpop02-warn focus-visible:outline-3 focus-visible:outline-offset-1 focus-visible:outline-tpop02-warn">
<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.9" aria-hidden="true"><path d="M4 4l8 8M12 4l-8 8"/></svg>
</button>
</div>
<p class="mb-1.5 text-[13.5px] leading-normal"><span class="font-tpop02-mono text-[0.9em] text-tpop02-ok">GET /v2/accounts</span> · 200 · 84ms</p>
<p class="mb-1.5 text-[13.5px] leading-normal"><span class="font-tpop02-mono text-[0.9em] text-tpop02-ok">POST /v2/tokens</span> · 201 · 132ms</p>
<p class="mt-2.5 border-t border-tpop02-rule pt-2.5 text-xs text-tpop02-warn">Manual · nothing dismisses me but that button</p>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tpop02-navy: #0a152a;
--color-tpop02-navy: oklch(0.2 0.045 262);
--color-tpop02-grid: #16243c8c;
--color-tpop02-grid: oklch(0.26 0.05 262 / 0.55);
--color-tpop02-board: #13213c;
--color-tpop02-board: oklch(0.25 0.055 262);
--color-tpop02-surface: #1c3051;
--color-tpop02-surface: oklch(0.31 0.065 260);
--color-tpop02-ink: #e8eff9;
--color-tpop02-ink: oklch(0.95 0.015 255);
--color-tpop02-mut: #a6b9d5;
--color-tpop02-mut: oklch(0.78 0.045 258);
--color-tpop02-rule: #29415f;
--color-tpop02-rule: oklch(0.37 0.06 255);
--color-tpop02-ok: #61d5c0;
--color-tpop02-ok: oklch(0.8 0.11 180);
--color-tpop02-okdeep: #007b6b;
--color-tpop02-okdeep: oklch(0.52 0.1 180);
--color-tpop02-warn: #f6b069;
--color-tpop02-warn: oklch(0.81 0.12 65);
--color-tpop02-warndeep: #b3621e;
--color-tpop02-warndeep: oklch(0.58 0.13 55);
--font-tpop02-sans: 'Space Grotesk', system-ui, sans-serif;
--font-tpop02-mono: 'JetBrains Mono', ui-monospace, monospace;
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities, so the
stage is sized before the browser build compiles. */
.tpop-02 {
width: 100%;
min-height: 100svh;
}
```How this works
Auto and manual are not a styling flag. An auto popover joins a stack the browser maintains: opening one closes any other auto that is not its ancestor, outside clicks dismiss it and Escape closes the topmost. A manual popover joins nothing — it closes only when told to.
The LEDs make the rule visible. Every panel is a descendant of the root, so the root can ask which ones are open:
<span class="size-2 rounded-full bg-tpop02-rule
group-has-[#tpop-02-auto:popover-open]/root:bg-tpop02-ok
group-has-[#tpop-02-auto:popover-open]/root:shadow-[0_0_10px_var(--color-tpop02-ok)]">Open Notifications, then Activity: the first LED goes dark on its own. Open the inspector and click the board: its LED stays lit.
Choose by asking who owns dismissal. If the user's next click elsewhere means "never mind", use auto and write no code. If the panel holds work in progress, use manual and ship a visible close.
Make it yours
- Flip the inspector to
popover="auto"and watch the three LEDs start fighting over one slot. - Square corners: the whole board uses
rounded-sm; swap forrounded-nonefor a harder dashboard read. - Re-dock: change
bottom-6 left-6totop-6 left-1/2 -translate-x-1/2for a centred toast position.
Gotchas — read before shipping
- A manual popover with no visible close is a trap — no light dismiss, no Escape.
- Two
toggleinvokers on one manual panel can disagree about state; use explicitshowandhide. inset-automust precede the side utilities in effect — Tailwind ordersinsetbeforebottom/left, so the pair composes correctly.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 114+ | 17+ | 125+ | 114+ |
Both popover states and all three popovertargetaction values landed with the attribute; :has() for the LEDs is Chrome 105 / Safari 15.4 / Firefox 121.