/* ─────────────────────────────────────────────────────────────────────────────
   tsk-menu.css — the platform kebab menu
   Try Swiss Knife | tryswissknife.com

   ONE implementation of the kebab ("Actions") menu, shared by every tool that
   has one. Before this file each tool carried its own forked copy, and they had
   drifted into five different layouts — right-anchored dropdown, centred modal,
   bottom sheet, top sheet, side drawer — with four different height caps and
   three tools that could not scroll at all. This file is the single source.

   ── Required markup (already used by every tool) ────────────────────────────
     <div class="menu-overlay" id="menu-overlay">
       <div class="menu-content">
         <div class="menu-header">…title… .menu-header-right (lang + close)…</div>
         <div class="menu-scroll">
           …one or more .menu-action buttons…
         </div>
       </div>
     </div>

   `.menu-scroll` is NOT optional. It is what scrolls, and it exists so that the
   language selector — which lives in .menu-header and opens an absolutely
   positioned dropdown — sits OUTSIDE the scroller. Put overflow on
   .menu-content instead and that dropdown is clipped the moment the menu is
   long enough to scroll (PLATFORM.md says the same thing about the menu card).

   The open/closed class is `.active` on .menu-overlay, matching every other
   overlay on the platform.

   ── What this file owns vs. what the tool owns ──────────────────────────────
   Owned here: where the menu opens, how wide it is, how tall it can get, what
   scrolls, and the open/close transition. Tools must not restate any of that.

   Owned by the tool: the look of the card and its rows — .menu-header,
   .menu-action, .close-menu, colours, typography. A paper-diary tool and a
   clean-utility tool should still look like themselves.

   ── Tuning hooks (set on :root in the tool's own styles.css) ────────────────
     --tsk-menu-align   width of .header-inner, so the menu's right edge lines
                        up with the kebab button. Default 1200px. Set it if the
                        tool's header uses anything else; use 100vw for a
                        full-bleed header with no max-width.
     --tsk-menu-inset   the header's own horizontal padding. Default 1.5rem.
     --tsk-header-h     header height at each breakpoint; the menu hangs 8px
                        below it. Defaults track the platform header.
     --tsk-menu-z       stacking order. Default 1200 — above the sticky header
                        (1000). Raise it only if the tool's own modals sit
                        higher and can open over an open menu.
     --tsk-menu-pad     card padding. Set to 0 (plus --tsk-menu-scroll-gutter: 0)
                        when the tool's rows are full-bleed and carry their own.
     --tsk-menu-bg / --tsk-menu-radius / --tsk-menu-shadow / --tsk-menu-scrim
   ───────────────────────────────────────────────────────────────────────── */

.menu-overlay {
    position: fixed;
    inset: 0;
    z-index: var(--tsk-menu-z, 1200);
    background: var(--tsk-menu-scrim, rgba(0, 0, 0, 0.5));

    /* Flex, not absolute positioning: the overlay's padding box then defines
       how tall the card is allowed to be, so `max-height: 100%` below needs no
       dvh arithmetic and cannot be forgotten. The padding is also what anchors
       the card under the kebab. */
    display: flex;
    justify-content: flex-end;
    align-items: flex-start;
    padding:
        calc(var(--tsk-header-h, 56px) + 8px)
        max(calc((100vw - var(--tsk-menu-align, 1200px)) / 2 + var(--tsk-menu-inset, 1.5rem)), 1rem)
        1rem;

    opacity: 0;
    visibility: hidden;
    transition: opacity 0.22s ease, visibility 0.22s ease;
}

.menu-overlay.active {
    opacity: 1;
    visibility: visible;
}

.menu-content {
    display: flex;
    flex-direction: column;
    width: min(360px, 100%);

    /* Resolves against the overlay's content box — i.e. the space below the
       header — so a long menu scrolls instead of running off the screen. */
    max-height: 100%;

    background: var(--tsk-menu-bg, var(--color-white, var(--bg-card, #fff)));
    border-radius: var(--tsk-menu-radius, var(--radius-xl, 16px));
    box-shadow: var(--tsk-menu-shadow, var(--shadow-lg, 0 8px 24px rgba(0, 0, 0, 0.13)));
    /* 0 for a tool whose rows are full-bleed and carry their own inset. */
    padding: var(--tsk-menu-pad, 16px 20px 18px);

    transform: scale(0.95);
    transform-origin: top right;
    opacity: 0;
    pointer-events: none;
    transition: transform 0.22s ease, opacity 0.22s ease;
}

.menu-overlay.active .menu-content {
    transform: scale(1);
    opacity: 1;
    pointer-events: auto;
}

/* The title row stays put while the actions scroll under it. */
.menu-content > .menu-header {
    flex-shrink: 0;
}

.menu-scroll {
    overflow-y: auto;
    overscroll-behavior: contain;
    /* Negative margin + matching padding so focus rings on the first and last
       rows are not shaved off by the scroll container's edge. Set the gutter to
       0 alongside --tsk-menu-pad: 0, or full-bleed rows spill past the card. */
    margin: 0 calc(var(--tsk-menu-scroll-gutter, 4px) * -1);
    padding: 1px var(--tsk-menu-scroll-gutter, 4px) 0;
}

/* The platform header shrinks at these breakpoints, so the default anchor
   follows it. Declared on :root, not on .menu-overlay — a page that sets its
   own --tsk-header-h does so on :root in its own stylesheet, which loads after
   this file and must keep winning at every width. Horizontal inset needs no
   override: the max() floor above already takes over below 1200px. */
@media (max-width: 768px) {
    :root { --tsk-header-h: 52px; }
}

@media (max-width: 480px) {
    :root { --tsk-header-h: 48px; }
}

@media (prefers-reduced-motion: reduce) {
    .menu-overlay,
    .menu-content {
        transition: none;
    }
}
