/* Session row ACTION MENU - the three-dot trigger on a session row and
 * the panel it opens. Behaviour is in web/src/lib/item-menu/row-open.ts;
 * this file is only what it looks like.
 *
 * Every colour here is a token, so the menu follows whichever theme is
 * on. There is no hardcoded light or dark value anywhere below: the app
 * repaints these variables per theme, and a literal would be the one
 * element on screen that did not follow.
 *
 * NO CIRCLE AROUND THE GLYPH. The owner's standing rule for the left
 * list: "just dont want any circles around icons on left menu. squared
 * is ok like close, but no border is probably better." So the trigger is
 * a mark on the row's own background and hover is expressed as COLOUR.
 * The focus ring is the one exception, and it is an outline, which draws
 * outside the box and so cannot re-introduce a chip.
 *
 * THIN GLYPH, WIDE TARGET. The dots render at 16px; a thumb needs 44.
 * The target is widened HORIZONTALLY on the real box and grown
 * VERTICALLY only through a transparent overlay, because the row's
 * height is declared per density in
 * client/css/session-sidebar-density.css - a taller button would grow
 * the row, and a 44px overlay on a 24px compact row would reach into its
 * neighbours and steal two taps to save one.
 *
 * THE PANEL IS position: fixed AND MOUNTED ON THE BODY, because
 * `.session-sidebar-panel` carries a translateX for its slide and a
 * transformed ancestor becomes the containing block for a fixed
 * descendant. Placement comes from client/js/anchor-popover.js; the
 * height cap is applied in JS against the VISUAL viewport and the
 * declarations here are the floor under it.
 *
 * MUST load AFTER session-sidebar.css, session-sidebar-density.css and
 * session-row-inline-controls.css: those size row controls as small
 * square icon buttons, and this file has to win over them.
 */

/* ---- The row's trigger ------------------------------------------------ */

@layer components {
.session-row-menu-trigger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    /* The containing block for the tap-area overlay below. */
    position: relative;
    padding: 0 6px;
    min-width: 24px;
    align-self: stretch;
    background: transparent;
    border: none;
    border-radius: 0;
    /* The louder ink read too bold for a control that just opens a menu
     * (owner: "make the dots not as bold"), so this is the secondary
     * tier, the same one the row's own quiet text uses; hover and focus
     * still light it to --oc-text-bright below, so it stays fully
     * readable on intent. --color-fg-strong, which that hover rule used
     * to name, was defined nowhere in the app: it resolved to nothing, so
     * the hover never changed the colour at all. */
    color: var(--oc-text-secondary);
    cursor: pointer;
    line-height: 0;
    transition: color 120ms ease;
}

/* Owner: "remove the gap between the dots and the pin". The row's own
 * flex `gap` (session-sidebar-density.css) is uniform across every
 * control on the row - grip, dot, name, pin, this trigger - so it cannot
 * be zeroed there without also collapsing spacing the request did not
 * name. This cancels it for JUST this one adjacent pair, by pulling the
 * trigger back toward the pin by exactly the gap it would otherwise
 * leave. `.session-row-menu-trigger` only ever follows the pin directly
 * on a LIVE row (a dead row's inline restart/remove sits there instead),
 * which is the one case this request is about. Matches the gap per
 * density: 8px in cozy/detailed (the base rule's value), 5px in compact -
 * PLUS 2px MORE (Joe, 2026-09-28: "close the gap slightly between the
 * pin and the 3 dots"), the same 2px this file's keep-awake sibling rule
 * tightens by, so every control on the row's tail moves by one rhythm. */
.session-sidebar-row-pin + .session-row-menu-trigger {
    margin-inline-start: -10px;
}

.session-sidebar-panel[data-density="compact"] .session-sidebar-row-pin + .session-row-menu-trigger {
    margin-inline-start: -7px;
}

/* INSIDE THE SIDEBAR ROW'S CONTROL CLUSTER (issue #1045,
 * client/css/session-sidebar-rows.css), THE PULL-BACK ABOVE IS ZEROED,
 * NOT STACKED: that wrapper already holds every gap in it to one 2px
 * rhythm, so adding this file's own -10px/-7px on top would collapse the
 * pin and the kebab into each other. The extra class makes both rules
 * here beat the unscoped ones above regardless of source order. The
 * launchpad's `.running-session-row` (RunningSessionRow.svelte) has no
 * such wrapper and is UNCHANGED: it keeps the pull-back exactly as
 * before.
 *
 * ZEROING THIS MARGIN LEFT A VISIBLY WIDER GAP BEFORE THE KEBAB THAN
 * BETWEEN THE OTHER ICONS (Joe, 2026-09-28, issue #1061: "the pin moved
 * away from the kebab... between icons is close but icons to kebab is
 * far"). The cluster's flex `gap` is 2px, same as every other pair in
 * it, but the trigger button itself carries `padding: 0 6px` (the
 * thumb-sized tap target, see the file header), so a margin of 0 here
 * still left the dots glyph sitting 2px (gap) + 6px (the trigger's own
 * left padding) = 8px past the pin, four times the 2px rhythm every
 * other pair in the cluster keeps. -6px cancels exactly that padding, so
 * the glyph lands the same 2px past the pin as the subagent/schedule
 * icons and the cup sit past each other - the padding stays for the tap
 * target (only the trigger's POSITION moves; `::after` below still
 * covers the button's own box, unchanged), just not for the visual gap.
 * Same value at every density: the padding this cancels is not
 * density-scoped either. Not the compact-only -7px case above, which
 * pulls back a DIFFERENT (larger, `-2px` extra) rhythm live outside the
 * cluster. */
.session-sidebar-row-controls-cluster .session-sidebar-row-pin + .session-row-menu-trigger,
.session-sidebar-panel[data-density="compact"] .session-sidebar-row-controls-cluster .session-sidebar-row-pin + .session-row-menu-trigger {
    margin-inline-start: -6px;
}

/* THE KEEP-AWAKE CUP MOVES BY THE SAME 2px (Joe, 2026-09-28: "also the
 * coffee cup"), on both sides, so it reads as one adjustment with the
 * pin/dots pull-back above rather than a different rhythm. The cup only
 * ever draws between the share mark (or, absent that, the model mark)
 * and the pin - web/src/lib/sidebar-shell/row-plan.ts's fixed order - so pulling
 * both its edges in tightens the whole tail uniformly. See
 * client/css/session-sidebar-keep-awake.css for the button's own box. */
.session-sidebar-row-keep-awake {
    margin-inline: -2px;
}

/* Same reset as the pin-to-kebab rule above, and for the same reason:
 * the cluster wrapper already gives the cup a 2px gap on both sides. */
.session-sidebar-row-controls-cluster .session-sidebar-row-keep-awake {
    margin-inline: 0;
}

/* COMPACT ONLY: trim the trigger's own side padding along with the
 * cluster's tighter gap above (session-sidebar-rows.css), issue #1061
 * follow-up, 2026-09-28, "bring the icons a little closer together".
 * Still a usable click target; cozy/detailed keep the 6px above. */
.session-sidebar-panel[data-density="compact"] .session-row-menu-trigger {
    padding: 0 var(--oc-space-1);
}

.session-row-menu-trigger:hover,
.session-row-menu-trigger[aria-expanded="true"] {
    color: var(--oc-text-bright);
}

/* MENU HIDDEN BY THE drawer_row_icons `menu` TOGGLE (issue #1061
 * follow-up, 2026-09-28): the kebab stays in the DOM - right click, long
 * press/touch and Shift+F10 all still find it
 * (web/src/lib/sidebar-shell/row-menu-gestures.ts) - just faint until the row is
 * hovered or focused, so a mouse user can still see where it is. Never
 * applied while the update-ready state is showing
 * (`web/src/lib/item-menu/row-context.ts::triggerHtml` only sets this modifier when
 * `agentUpdateReady` is false): "hiding the kebab never hides an update"
 * is enforced there, not here. */
.session-row-menu-trigger--dim {
    opacity: 0;
    transition: opacity 120ms ease;
}

.session-sidebar-row:hover .session-row-menu-trigger--dim,
.session-sidebar-row:focus-within .session-row-menu-trigger--dim,
.session-row-menu-trigger--dim[aria-expanded="true"] {
    opacity: 0.45;
}

.session-row-menu-trigger--dim:hover,
.session-row-menu-trigger--dim:focus-visible {
    opacity: 1;
}

/* A transparent positioned pseudo-element belongs to its originating
 * element for hit testing, so this gives the trigger a thumb-sized
 * target without adding a pixel to the layout. `left/right: 0` keeps it
 * from reaching sideways into the control next to it. */
.session-row-menu-trigger::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    top: 50%;
    height: 100%;
    transform: translateY(-50%);
}

@media (pointer: coarse) {
    .session-row-menu-trigger {
        min-width: 36px;
        padding: 0 10px;
    }

    /* The padding grew to 10px on a coarse pointer above, so the -6px
     * cluster cancellation needs to grow to -10px with it, same reason
     * as the fine-pointer rule (issue #1061). */
    .session-sidebar-row-controls-cluster .session-sidebar-row-pin + .session-row-menu-trigger {
        margin-inline-start: -10px;
    }

    /* 44px tall, but only where the row is tall enough to hold it. See
     * the file header for why compact is excluded. */
    .session-sidebar-panel[data-density="cozy"] .session-row-menu-trigger::after,
    .session-sidebar-panel[data-density="detailed"] .session-row-menu-trigger::after,
    .running-session-row .session-row-menu-trigger::after {
        height: 44px;
    }

    /* THE COMMANDS THEMSELVES, BACK TO A TAPPABLE SIZE. The compact
     * item above is sized for a mouse. A finger has no such precision,
     * and this menu carries destructive commands ("kill session") one
     * row from harmless ones, so a cramped list here is a mis-tap
     * waiting to happen. Only the box grows; the icon and type stay as
     * they are, so the menu still reads as the same denser design. */
    .session-row-menu .session-row-menu__item {
        min-height: 38px;
        padding: 6px 9px; /* one pixel less each side: the reserved border takes it */
    }
}

/* ---- The panel -------------------------------------------------------- */

.session-row-menu {
    position: fixed;
    z-index: 1200;
    min-width: 200px;
    /* Never wider than the screen. The placement rule clamps a popover
     * into the viewport, but a panel wider than the viewport has no
     * position that satisfies both edges, so the width is capped first.
     *
     * AND NEVER WIDER THAN A MENU SHOULD BE. The refusal text on an
     * unavailable item is a whole sentence, and a grid track sizes to its
     * content: measured, one refusal stretched the panel to 730px, which
     * is not a menu any more, it is a dialog. The 320px cap is what makes
     * `white-space: normal` on the reason actually wrap. Two declarations,
     * plainest first: an engine without `min()` still gets the viewport
     * clamp, which is the one that keeps the panel reachable. */
    max-width: calc(100vw - 16px);
    max-width: min(320px, calc(100vw - 16px));
    padding: 3px;
    display: flex;
    flex-direction: column;
    gap: 0;
    /* ===================================================================
     * THE ANCHORED-POPOVER LOOK. THIS IS THE ONE PLACE IT IS ARGUED; THE
     * OTHER THREE MENUS APPLY THE SAME THREE DECLARATIONS AND POINT HERE.
     *
     * Four menus shared one vocabulary of theme variables - this one, the
     * header overflow panel (header-menu.css), the sidebar's row-detail
     * menu (session-sidebar-density.css) and the group menu
     * (session-sidebar-groups.css). The vocabulary was
     * --color-bg-elevated / --color-bg-raised for the ground,
     * --color-border for the edge, --radius-md for the corner and
     * --shadow-modal for the lift. Four menus, one decision, so the
     * mapping onto the military-terminal palette is made once:
     *
     *   ground   --color-bg-elevated / -raised  ->  --oc-ground-raised
     *   edge     --color-border                 ->  --oc-line-panel
     *   corner   --radius-md / --radius-sm      ->  --oc-radius-sm
     *   lift     --shadow-modal                 ->  nothing
     *
     * THE LIFT WAS DROPPED ON PURPOSE, AND THIS MENU IS WHERE THAT CHANGED.
     * The palette defines --oc-shadow-lift and the operations center
     * dashboard, which is the reference this look is taken from, did not
     * use it on a single floating surface: a popover was separated from
     * what is under it by the contrast between a raised ground and a
     * hairline, never by a glow. The OTHER THREE MENUS THIS COMMENT IS
     * SHARED WITH (header-menu.css, session-sidebar-density.css,
     * session-sidebar-groups.css) STILL FOLLOW THAT RULE - read this
     * addendum as scoped to `.session-row-menu` alone, not a change to the
     * vocabulary above.
     *
     * The raised tier is also deliberate. A floating panel never reuses
     * the ground of the surface it opens over; --oc-ground-raised is the
     * tier that exists for exactly this.
     *
     * ADDENDUM, 2026-09-22 (owner ask): THIS ONE MENU GOT A BORDER AND A
     * GLOW, TAKEN FROM THE TERMINAL'S OWN PROMPT-HEADER CHROME
     * (web/src/lib/terminal-search/PromptHeader.svelte), so a kebab menu
     * reads like the rest of this app's "this is chrome, not content"
     * language rather than a plain floating box. THAT STATIC GRADIENT
     * RING IS SUPERSEDED BELOW, 2026-09-23 - read on.
     *
     * ADDENDUM, 2026-09-23 (owner ask): THE STATIC GRADIENT RING IS
     * REPLACED BY AN ANIMATED "BREATHING" HALO, and the background goes
     * back to a plain flat fill (the ground token was never the thing
     * that needed a second layer - the gradient trick above existed only
     * to fake a two-colour border, which a real `border` now draws).
     * Reference: the Insiders app's product Edit modal, a 1px translucent
     * border plus a 3-layer box-shadow cycling between two accents on a
     * 5s ease-in-out loop - ring, near glow, far glow. Same two tokens
     * the prompt strip uses, so this still reads as the same chrome
     * language: `--oc-strip-edge` is A (the resting accent, already
     * diluted toward the panel's own hairline) and `--oc-orange` is B
     * (the same accent at full strength, the "inhale"). Both colours are
     * threaded through `color-mix(in srgb, <token> N%, transparent)`
     * rather than hex+alpha, so a theme that repaints either token
     * repaints the halo with it - no literal colour anywhere in this
     * rule. The near and far glow layers carry a small downward y-offset
     * (4px, 10px) so the halo still reads heavier at the bottom than the
     * top, the "weighted down" feel the gradient ring used to carry; the
     * ring layer itself (`0 0 0 1px`) stays centred, since a ring is not
     * a light source. A real drop shadow - flat black, not a theme token,
     * because it has to read on a LIGHT theme where every --oc-* accent
     * is itself light - rides in every layer list below so the animation
     * never erases it mid-cycle. `prefers-reduced-motion` gets its own
     * static shadow with the same three ingredients (ring, one glow,
     * drop shadow) and no motion at all (that override is gone now, see
     * the addenda below). `.session-row-menu`'s own `overflow-y: auto` does
     * not clip this box's OWN box-shadow (overflow only clips a box's
     * descendants, never its own border-image/shadow layer), so the halo
     * is never cut off even while a tall menu scrolls.
     *
     * ADDENDUM, 2026-09-23 (owner ask): "the glow is a little too intense,
     * half it." Every halo layer's colour percentage is halved from the
     * addendum above - the static border and every ring/near-glow/far-glow
     * stop in both keyframe phases and the reduced-motion fallback - while
     * blur radii, spread, timing, hues and the flat black drop shadows are
     * untouched.
     *
     * ADDENDUM, 2026-09-23 (owner ask): "the glow is still too wide ...
     * change it to 5px" and "it should circumnavigate, not pulse". THE
     * BREATHING HALO ABOVE IS GONE. The border became a conic gradient
     * whose bright spot travelled around the edge, animated through a
     * registered `--srm-angle` custom property. SUPERSEDED BELOW.
     *
     * ADDENDUM, 2026-09-23 (owner ask): "temp disable the glow animation
     * and make the glow only 5px wide with the border gradient topdown and
     * a drop shadow under that." The orbit is temporarily disabled: no
     * `animation`, no `--srm-angle`, no keyframes. The border goes back to
     * a STATIC top-to-bottom gradient, darker at the top
     * (`--oc-line-panel`) and brighter at the bottom (`--oc-strip-edge`),
     * the same two tokens and the same direction the pre-orbit gradient
     * ring used (commit d2806e97). It still rides the element's OWN
     * background layers - an opaque ground clipped to the padding box
     * under the gradient clipped to the border box, behind a transparent
     * 1px border - rather than a `::before` pseudo-element, because a
     * pseudo whose containing block is this same scrolling panel drifts
     * across the items as a tall menu scrolls; painting the box's own
     * background is immune to that (`background-attachment` stays
     * `scroll`, its default, which pins the layers to the box's real
     * edges while only the items move). The glow is ONE static layer, 3px
     * downward offset plus 2px blur, spread 0, so it reaches at most 5px
     * past the edge - never stronger than the halved intensity above. The
     * two flat black drop shadows are unchanged.
     *
     * ADDENDUM, 2026-09-23 (owner ask): "make a subtle border animation
     * that has a slight shimmer go around the cell for the menu (not a
     * diffused glow) ... something to signify that its active but not
     * distracting." The glow and both drop shadows above are UNTOUCHED -
     * this is a border-only effect, no blur, no bloom, no box-shadow
     * change. A THIRD border-box layer is added on top of the static
     * top-down gradient: a conic-gradient carrying one short, soft arc
     * (`--srm-shimmer`, `--oc-strip-edge` at low opacity, ~60deg of soft
     * falloff either side of its centre - well inside a diffused glow's
     * territory) that travels a full lap around the 1px edge every 6s,
     * linear, via the registered `--srm-angle` custom property below. It
     * is still a background layer, never a `::before`, for the same
     * scrolling-panel reason as the gradient underneath it: painted here
     * it is pinned to the box's real border, not the scrolled content.
     * The keyframes run the angle a full 360deg lap (0deg to 360deg,
     * which is the SAME conic-gradient at both ends) rather than any
     * partial sweep, on purpose: an engine that has no `@property` cannot
     * interpolate `--srm-angle` between keyframes and instead flips
     * discretely between the literal start and end values - but since
     * those two values paint an identical arc, that engine renders one
     * unmoving frame the whole cycle, degrading straight to a still
     * border with no jump, no broken pose, and no extra `@supports` gate
     * required. `prefers-reduced-motion: reduce` drops the animation AND
     * the shimmer layer outright, leaving the plain static top-down
     * gradient with nothing riding on it.
     *
     * ADDENDUM, 2026-09-23 (owner ask): "i only see the border shimmer in
     * the top left corner ... make it a little brighter and longer", then
     * "add that 'popup focus' style to all popup menus". THE WHOLE LOOK
     * ABOVE MOVED TO client/css/popup-focus.css, as the `.popup-focus`
     * class every popup menu in the app now carries (this panel gets it in
     * web/src/lib/item-menu/row-open.ts). This rule no longer declares a
     * border, ground, shadow or animation, and `--srm-angle` and its
     * keyframes are gone; that file carries the measurement of why the
     * sheen only showed at the top and what changed.
     * ================================================================ */
    border-radius: var(--oc-radius-sm);
    /* A MENU TALLER THAN THE SCREEN SCROLLS ITSELF. The JS cap measures
     * the visual viewport and wins over these; they are the fallback for
     * a run where it has not been applied yet. vh then dvh, in that
     * order: the raw unit is the fallback for an engine with no dvh, and
     * the dynamic one is what stops a mobile browser's collapsing URL bar
     * from sizing this against a viewport the user cannot see. Asserted
     * by tests/test_viewport_units.node.mjs. */
    max-height: calc(100vh - 16px);
    max-height: calc(100dvh - 16px);
    overflow-y: auto;
    overflow-x: hidden;
    overscroll-behavior: contain;
}

/* ---- One item --------------------------------------------------------- */

.session-row-menu .session-row-menu__item {
    display: grid;
    /* The icon sits in its own fixed column so every label starts at the
     * same x whatever glyph is beside it - the same reasoning the group
     * header applies to its count (--sidebar-gutter in
     * session-sidebar-groups.css). Label takes the room, the shortcut
     * letter is pinned to the right edge in its own column so every
     * letter lines up whatever the label length. The reason, when there
     * is one, spans all three columns under them. */
    grid-template-columns: 14px 1fr auto;
    align-items: center;
    gap: 2px var(--oc-space-2);
    width: 100%;
    min-width: 0;
    /* COMPACT BY DEFAULT, ROOMY UNDER A FINGER. Owner, 2026-09-22:
     * collapse this menu's spacing and icon/font size to match a
     * reference that fits roughly half again as many commands in the
     * same height. The row box was 40px tall with 7px/10px padding,
     * which is a touch target standing in for a pointer target.
     *
     * The touch size is NOT simply deleted - it moves to the
     * `pointer: coarse` block below, which restores the taller row on
     * the devices that need it. Shrinking a menu item to 26px
     * everywhere would have made every command on a phone a harder
     * tap, which is not what "make it denser" asked for. */
    min-height: 26px;
    /* One pixel less each side than the old 3px / --oc-space-2, because the reserved border below takes it: the label
     * and icon stay exactly where they were. */
    padding: 2px calc(var(--oc-space-2) - 1px);
    box-sizing: border-box;
    background: transparent;
    /* A reserved, invisible 1px border (Joe, 2026-10-28, "focusring"): the shared focus rule
     * (web/src/opscenter/focus.css) brightens it on keyboard focus, so the item draws no ring of its own. */
    border: 1px solid transparent;
    border-radius: var(--oc-radius-sm);
    color: var(--oc-text-primary);
    font-family: inherit;
    /* Matches the status key toggle's label ("what the lights mean" in
     * the status-light legend, which was removed on 2026-09-22) - same
     * 0.68em value, and both resolve against the same unstyled 16px root,
     * so this computes to the identical pixel size. Size only: the
     * status key label is an uppercase section heading with letter-
     * spacing and bold weight, none of which belongs on a command. */
    font-size: 0.68em;
    text-align: left;
    cursor: pointer;
    transition: background 120ms ease, color 120ms ease;
}

/* The item's prefix icon. Fixed at the grid's 14px first column so every
 * glyph occupies the same box regardless of its own drawn size (each is
 * rendered at 12px, passed explicitly by web/src/lib/item-menu/menus/row.ts
 * rather than taken from the icon module's default, which other callers
 * still use at 14px), which is
 * what keeps every label starting at the same x. No colour of its own -
 * it inherits the button's `color`, which is how the close item's glyph
 * turns red on hover/focus along with its label and shortcut, with no
 * extra rule needed. */
.session-row-menu .session-row-menu__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 14px;
    height: 14px;
    flex-shrink: 0;
    line-height: 0;
}

.session-row-menu .session-row-menu__label {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* The shortcut letter. Muted, right-aligned, and never the thing the eye
 * lands on first - it is a hint about the keyboard, not part of the
 * label. */
.session-row-menu .session-row-menu__key {
    justify-self: end;
    display: inline-flex;
    align-items: center;
    gap: var(--oc-space-1);
    color: var(--oc-text-muted);
    font-size: 0.68rem;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

/* The ONE branch item's ("add to"/"add") chevron, sat inside the same key
 * cell as its shortcut letter (issue #954) - the vanilla panel's twin of
 * CascadeMenu.svelte's `.acm-chevron`, same glyph, same muted colour, so a
 * branch reads identically whether it is drawn here or in the compiled
 * Svelte tree. */
.session-row-menu .session-row-menu__chevron {
    display: inline-flex;
    flex-shrink: 0;
    color: var(--oc-text-muted);
}

/* A secondary line under a row's label (the widgets place menu's "fits as" size). A disabled
 * item's reason is NOT printed: it is the shared tooltip's words (Adam (Adoom666), 2026-10-21). */
.session-row-menu .session-row-menu__reason {
    grid-column: 1 / -1;
    color: var(--oc-text-secondary);
    font-size: 0.72rem;
    line-height: 1.35;
    white-space: normal;
}

.session-row-menu .session-row-menu__item:hover,
.session-row-menu .session-row-menu__item:focus-visible {
    background: var(--oc-ground-hover);
    color: var(--oc-text-bright);
    outline: none;
}

/* AN UNAVAILABLE ITEM IS GRAYED and still takes focus, so it still gets a focus ring
 * (and the tooltip with its reason shows on hover and on focus); what it loses is the
 * pointer cursor and the full-strength label and icon. Same row height, icon column and
 * key column as an enabled item. */
.session-row-menu .session-row-menu__item[aria-disabled="true"] {
    cursor: default;
    color: var(--oc-text-dim);
}

.session-row-menu .session-row-menu__item[aria-disabled="true"] .session-row-menu__icon {
    opacity: 0.55;
}

.session-row-menu .session-row-menu__item[aria-disabled="true"]:hover,
.session-row-menu .session-row-menu__item[aria-disabled="true"]:focus-visible {
    background: var(--oc-ground-field);
    color: var(--oc-text-dim);
}

/* ---- The separator ----------------------------------------------------- */

/* Close is the only destructive entry in this menu, and it sits apart
 * from the four that are not, so a mis-aimed thumb lands on empty space
 * rather than on the control that kills a process. */
.session-row-menu .session-row-menu__sep {
    height: 1px;
    margin: 3px 6px;
    background: var(--oc-line-rule);
}

/* The destructive entry wears the coral token at rest (widget menu contract slice 2, issue #1785: "danger tone for destructive items",
 * the same as CascadeMenu's `.acm-item--danger`), a different token from the confirming rows. It stays last, behind its own hairline. */
.session-row-menu .session-row-menu__item[data-row-menu-item="close"]:not([aria-disabled="true"]),
.session-row-menu .session-row-menu__item[data-row-menu-item="close"]:not([aria-disabled="true"]) .session-row-menu__key {
    color: var(--oc-coral);
}

.session-row-menu .session-row-menu__item[data-row-menu-item="close"]:hover,
.session-row-menu .session-row-menu__item[data-row-menu-item="close"]:focus-visible {
    background: var(--oc-ground-hover);
}

/* ---- Update ready (issue #1061) --------------------------------------
 *
 * Joe (ccsliinc), 2026-09-28: "replace the kebab with a green update
 * icon... clicking it will bring the submenu with green update on top."
 * The trigger swaps its glyph in JS (web/src/lib/item-menu/row-context.ts::triggerHtml);
 * here it only takes the accent colour, same token the row's other
 * "background work" icons already use (session-sidebar-rows.css). Focus
 * and hover stay the SAME green rather than escalating to a brighter one,
 * since this state is informative, not destructive. */
.session-row-menu-trigger--update {
    color: var(--oc-green);
}

.session-row-menu-trigger--update:hover,
.session-row-menu-trigger--update[aria-expanded="true"] {
    color: var(--oc-green);
    opacity: 0.85;
}

/* MCP DROPPED (task manager "Sidebar: yellow ! when its MCP dropped"): the trigger's glyph becomes a mark in the warning
 * token, in the update icon's slot (web/src/lib/item-menu/row-context.ts::triggerHtml; the update icon wins when both apply).
 * Colour only, like the update state: same element, same size, no ring. Hover and open keep the hue. */
.session-row-menu-trigger--mcp,
.session-row-menu-trigger--mcp:hover,
.session-row-menu-trigger--mcp[aria-expanded="true"] {
    color: var(--oc-yellow);
}

/* The menu's own first item, "update and restart" - green icon, green
 * label, same neutral background as every other item until hovered. */
.session-row-menu__item.session-row-menu-panel__item--update {
    color: var(--oc-green);
}

.session-row-menu__item.session-row-menu-panel__item--update:hover,
.session-row-menu__item.session-row-menu-panel__item--update:focus-visible {
    background: var(--oc-ground-hover);
    color: var(--oc-green);
}

/* ---- Shift held over the update-ready trigger (issue #1061 follow-up,
 * 2026-09-29, Joe (ccsliinc): "holding shift on update should just change
 * the icon color not a border") --
 *
 * `data-shift-restart` is set by web/src/lib/item-menu/row-open.ts on
 * every rendered `.session-row-menu-trigger--update` while Shift is down.
 * ONLY the colour changes, green to the warning yellow: no ring, no
 * border, no shadow, same glyph, same size. Shift-click still runs the
 * identical `update-restart` action (web/src/lib/item-menu/row-open.ts); the colour
 * says "acts now". Declared after the hover/expanded rules so it wins. The
 * tooltip/aria-label swap is that same module's job, not CSS's. */
.session-row-menu-trigger--update[data-shift-restart="1"],
.session-row-menu-trigger--update[data-shift-restart="1"]:hover,
.session-row-menu-trigger--update[data-shift-restart="1"][aria-expanded="true"] {
    color: var(--oc-yellow);
}

/* Disabled (a live subagent/shell/timer refuses it, Joe: "since a
 * restart ends them"): the shared disabled treatment wins over the green,
 * so a refused item reads as refused first. */
.session-row-menu__item.session-row-menu-panel__item--update[aria-disabled="true"] {
    color: var(--oc-text-muted);
}
}
