/* Dropdowns with no JavaScript: popover opens, closes on Esc or an outside click and returns focus; CSS anchor positioning places
the menu next to its button and flips it when there is no room; @starting-style animates both ways. */
.pm-btn{display:inline-flex;align-items:center;gap:8px;height:40px;padding:0 14px;border:0;border-radius:10px;background:var(--pm-accent);color:#fff;font:inherit;font-weight:600;
cursor:pointer;box-shadow:0 8px 18px -8px rgba(162,28,175,.7);transition:background-color .15s}
.pm-btn:hover{background:#86198f}
.pm-btn svg{width:16px;height:16px}
.pm-btn.ghost{width:36px;height:36px;padding:0;justify-content:center;background:none;color:var(--pm-muted);box-shadow:none}
.pm-btn.ghost:hover{background:var(--pm-hover);color:var(--pm-ink)}
.pm-btn:focus-visible{outline:2px solid var(--pm-accent);outline-offset:2px}
.pm-menu{min-width:224px;padding:6px;background:#fff;color:var(--pm-ink);border:1px solid var(--pm-line);border-radius:12px;
box-shadow:0 2px 6px rgba(34,27,43,.06),0 20px 44px -14px rgba(34,27,43,.3)}
.pm-item{display:flex;align-items:center;gap:10px;width:100%;padding:8px 10px;border:0;border-radius:8px;background:none;color:var(--pm-ink);font:inherit;font-size:.875rem;
font-weight:500;line-height:1.4;text-align:left;white-space:nowrap;cursor:pointer}
.pm-item>svg{width:16px;height:16px;flex:none;color:var(--pm-muted)}
.pm-item:hover,.pm-item:focus-visible{background:var(--pm-hover)}
.pm-item:focus-visible{outline:2px solid var(--pm-accent);outline-offset:-2px}
.pm-item.danger,.pm-item.danger>svg{color:var(--pm-danger)}
.pm-item.danger:hover{background:var(--pm-danger-bg)}
.pm-wrap{--pm-ink:#221b2b;--pm-muted:#625a6c;--pm-line:#ebe4f0;--pm-hover:#f7f0fa;--pm-accent:#a21caf;--pm-danger:#b42318;--pm-danger-bg:#fef3f2;font-size:.875rem}
.pm-card{display:flex;align-items:center;gap:12px;padding:12px 12px 12px 14px;background:#fff;border:1px solid var(--pm-line);border-radius:14px;box-shadow:0 1px 2px rgba(34,27,43,.05)}
.pm-thumb{flex:none;width:44px;height:44px;border-radius:10px;background:conic-gradient(from 200deg,#a21caf,#db2777,#f59e0b,#a21caf)}
.pm-thumb.b{background:linear-gradient(135deg,#0ea5e9,#6366f1 60%,#a21caf)}
.pm-card b{display:block;color:var(--pm-ink);font-weight:600;line-height:1.35}
.pm-card small{display:block;color:var(--pm-muted);font-size:.8rem}
.pm-card .pm{margin-left:auto}
.pm-note{margin:16px 2px 0;color:var(--pm-muted);font-size:.8rem;line-height:1.5}
.pm-note code{padding:1px 5px;border-radius:5px;background:#f3eef6;color:#6b1d74;font-size:.75rem}
.pm-sep{height:1px;margin:6px -6px;background:var(--pm-line)}
.pm-head{padding:6px 10px 4px;color:var(--pm-muted);font-size:.6875rem;font-weight:700;letter-spacing:.07em;text-transform:uppercase}
.pm-chev{width:14px;height:14px;margin-left:auto}
.pm-kbd{margin-left:auto;padding-left:18px;color:var(--pm-muted);font:500 .75rem ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
/* Each .pm wrapper sets --anchor to a unique name that links its button to its popover. */
.pm{position:relative;display:inline-block}
.pm>button,.pm-sub>button{anchor-name:var(--anchor)}
.pm-menu{position:fixed;position-anchor:var(--anchor);inset:auto;margin:6px 0 0;position-area:block-end span-inline-end;
position-try-fallbacks:flip-block,flip-inline,flip-block flip-inline}
.pm-menu.end{position-area:block-end span-inline-start;position-try-fallbacks:flip-block,flip-inline,flip-block flip-inline}
.pm-menu.side{margin:-7px 0 0 4px;position-area:inline-end span-block-end;position-try-fallbacks:flip-inline,block-end span-inline-start,block-start span-inline-start}
/* Open and close animations: @starting-style gives the first frame, allow-discrete keeps it in the top layer while it fades out. */
.pm-menu{opacity:0;translate:0 -4px;transition:opacity .16s,translate .16s,overlay .16s allow-discrete,display .16s allow-discrete}
.pm-menu:popover-open{opacity:1;translate:0 0}
@starting-style{.pm-menu:popover-open{opacity:0;translate:0 -4px}}
/* No anchor positioning: show the menu as a sheet at the bottom of the window instead. */
@supports not (anchor-name:--a){
.pm-menu,.pm-menu.end,.pm-menu.side{inset:auto 12px 12px;width:auto;max-width:360px;margin:0 auto}
}
@media (prefers-reduced-motion:reduce){.pm-menu{transition:none}}
Dropdowns with no JavaScript at all, built on the popover attribute and CSS anchor positioning. Popover menu placed with anchor positioning is a Share button whose menu is anchored under it with position-anchor and position-area; position-try-fallbacks flips it above or to the other side when it would leave the window. Nested popover with a side fallback is a more menu on a design file whose Export item opens a second popover beside it, which flips to the left when there is no room on the right and drops below or above it as a last resort. The browser handles the rest: popovertarget opens and closes each menu, Esc and a click outside close it, focus returns to the button, and a nested popover keeps its parent open. Each item uses popovertargetaction=”hide” so choosing it closes the menu without a script. @starting-style and transition-behavior: allow-discrete fade and slide the menu in and out. In browsers without anchor positioning the menus appear as a sheet at the bottom of the window instead of an unplaced box. These are disclosure-style menus reached with Tab, not ARIA menus with arrow keys.
What’s included
popover and popovertarget with no JavaScript
Anchored with position-anchor and position-area
position-try-fallbacks flip the menu near window edges
Nested popover submenu that keeps its parent open
Open and close animation with @starting-style
Bottom-sheet fallback where anchor positioning is missing
Accessibility
Buttons use popovertarget, so browsers expose their expanded state, and each popover is labelled. Items are ordinary buttons reached with Tab, Esc closes the top popover and returns focus to the button that opened it. Focus outlines are visible on every control and the transitions switch off under prefers-reduced-motion. Because there is no script, there are no arrow-key menu semantics; use the script from set 1 if you need a full ARIA menu.
Customise it
Each .pm wrapper sets --anchor to a unique name that links its button and popover; change position-area to open the menu elsewhere. Colours are the --pm-* custom properties. In Tailwind edit the [position-area:...] and [position-try-fallbacks:...] classes and the hex values.