/* =====================================================================
 * Session sidebar ROWS - one agent in the list, and the one row above
 * them that is not an agent.
 * ---------------------------------------------------------------------
 * WHY THIS IS A SEPARATE FILE. session-sidebar.css went over the
 * project's 500-line convention, and the rows were the largest coherent
 * thing in it that is not the panel. session-sidebar.css keeps the
 * CONTAINER - the toggle, the backdrop, the sliding and docked panel,
 * its header, its list box and its pinned foot - and this file keeps
 * what sits INSIDE the list. It is the same seam the JS already uses:
 * web/src/lib/drawer/controller.ts owns the panel, web/src/lib/sidebar-shell/SessionRow.svelte owns a row.
 *
 * CASCADE ORDER IS A CONTRACT HERE, not a preference. These rules were
 * the TAIL of session-sidebar.css, so index.html links this file
 * IMMEDIATELY AFTER it and BEFORE session-sidebar-density.css and
 * session-sidebar-row-controls.css, both of which deliberately override
 * row geometry and the per-row icon buttons. Moving this link later or
 * earlier changes which declaration wins.
 *
 * Tokens come from styles.css's :root and from session-sidebar.css's
 * --sidebar-dock-w; nothing new is defined here.
 * ===================================================================== */

/* ---- Rows ----------------------------------------------------------
 * Deliberately simpler than the launchpad's .running-session-row (no
 * rename/kill controls in the sidebar MVP - switching only). */

@layer components {
.session-sidebar-row {
    display: flex;
    align-items: center;
    gap: var(--oc-space-2);
    padding: 10px 10px;
    margin-bottom: var(--oc-space-1);
    border-radius: var(--oc-radius-sm);
    /* ONE CONTAINER, QUERIED BELOW (visual QA, issue #1061 follow-up):
     * the row's own inline size, not the viewport, is what decides which
     * optional pieces this row can afford. Named rather than anonymous so
     * a nested container (none exists today) cannot be queried by
     * accident. See "THE OVERFLOW DROP ORDER" at the foot of this file. */
    container-name: sidebar-row;
    container-type: inline-size;
    /* The arrow, not the hand: only the status dot shows a hand
     * (session-sidebar-row-controls.css). */
    cursor: default;
    background: transparent;
    /* ONE BORDER, ONE COLOUR, FOUR SIDES - the same ring
     * `.running-session-row` carries on the home screen (styles.css
     * ~2733). This was `1px solid transparent`, so an ordinary row had no
     * visible edge at all and the only thing separating rows in a dense
     * list was the coloured left bar a pinned or session-themed row drew.
     * "get rid of the thick left bar like on the homepage and clean it
     * like the homepage looks now" removes that bar, so the separation
     * job has to move somewhere, and the home screen already decided
     * where: a neutral theme token on all four edges. The width is
     * unchanged from the transparent border it replaces, so this costs no
     * layout and no reflow - only the colour is new. */
    border: 1px solid var(--oc-line-panel);
    transition: background 120ms ease, border-color 120ms ease;
}

.session-sidebar-row:hover {
    background: var(--oc-ground-hover);
}

/* THE CURRENT SESSION, and the reason removing the left bars costs
 * nothing here. `active` never had a rail: it has always been an accent
 * BACKGROUND, an accent 1px border on all four sides, and a bold accent
 * name below - three cues, none of them a left-side colour bar, plus
 * `aria-selected="true"` on the row so it is not colour-only.
 *
 * A 3px inline-start rail WAS measured on the current row and read as
 * this state; it was not. That rail is session-theme-tint.css painting
 * `--session-theme-accent`, which happened to be the same orange as the
 * host theme's accent, so the two were indistinguishable on screen. It
 * marks which SESSION THEME a row carries, not which row you are in.
 *
 * What changes here is only that the neutral rows around it now draw
 * their own hairline, so the accent edge on this row is a different
 * COLOUR of ring rather than the only ring on screen. That is
 * the same way the home screen tells its rows apart, and it reads as one
 * family with a 1px theme border where a 3px bar does not. */
.session-sidebar-row[aria-selected="true"] {
    background: var(--oc-orange-tint);
    border-color: var(--oc-orange);
}

.session-sidebar-row-name {
    flex: 1;
    /* A NAME NEVER FULLY DISAPPEARS (visual QA, issue #1061 follow-up: a
     * busy row at the 320px default was measured collapsing this to one
     * character, and at the 240px minimum to none at all). ~8 characters
     * ellipsized is the floor; the container query below sheds the
     * row's OPTIONAL pieces before this ever has to shrink past it. */
    min-width: 8ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--oc-text-primary);
}

.session-sidebar-row[aria-selected="true"] .session-sidebar-row-name {
    font-weight: bold;
}

.session-sidebar-row-badge {
    font-size: 0.65em;
    padding: 1px 5px;
    border-radius: var(--oc-radius-sm);
    letter-spacing: 0.4px;
    color: var(--oc-text-muted);
    border: 1px solid var(--oc-line-faint);
    flex-shrink: 0;
}

/* A remote row's host label (issue #162, slice S6): the same small
 * bordered chip as `.session-sidebar-row-badge` (it carries that class
 * too), tracked uppercase on its own, so this one label reads distinctly
 * from the plain-case origin badge it sits beside. Shown QUIETLY when the
 * host is anything but reachable - dimmed, never a colour change - so a
 * degraded or offline host reads as a fact to notice, not an alarm; the
 * LED, not this label, carries the alarm treatment. */
.session-sidebar-row-host {
    text-transform: uppercase;
}

/* A session an automation run started (issue #171): the same quiet bordered chip, tracked uppercase, muted tokens, never the accent. */
.session-sidebar-row-auto {
    text-transform: uppercase;
}

/* A CLOSED session (#1845): stopped, not asleep, not archived. No status light; the same quiet bordered chip as the auto and
 * host chips, tracked uppercase, a dashed hairline so it reads as "ended" beside the solid ones, muted tokens, never the accent.
 * The name dims with it. Tokens only. */
.session-sidebar-row-closed {
    text-transform: uppercase;
    border-style: dashed;
}

/* An ARCHIVED row (#1855) is a record, not a sleeper: no status light, the archive box, and its name dims like a closed one. */
.session-sidebar-row[data-closed="1"] .session-sidebar-row-name,
.session-sidebar-row[data-archived="1"] .session-sidebar-row-name {
    color: var(--oc-text-muted);
}

.session-sidebar-row-host[data-host-state] {
    opacity: 0.55;
}

/* ---- Per-row close / remove -----------------------------------------
 * The row's one destructive control: X (close) on a running row, trash
 * (remove) on a stopped one, built by client/js/session-row-actions.js
 * and styled identically either way - the glyph carries the difference,
 * not the color. Sized/positioned to match .session-sidebar-row-pin
 * (same 18x18 hit target) but always neutral-colored until hover, then
 * goes red - same treatment as .project-delete-btn - so a destructive
 * control never looks alarming until the user is actually pointed at it. */
.session-sidebar-row-delete {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    padding: 0;
    border-radius: var(--oc-radius-sm);
    background: transparent;
    border: 1px solid transparent;
    color: var(--oc-text-muted);
    cursor: pointer;
    flex-shrink: 0;
    transition: color 120ms ease, background 120ms ease, border-color 120ms ease;
}

.session-sidebar-row-delete:hover,
.session-sidebar-row-delete:focus-visible {
    color: var(--oc-coral);
    background: var(--oc-ground-hover);
    border-color: var(--oc-coral);
    outline: none;
}

/* NO WORK RECORDED YET, made visible rather than merely implied.
 *
 * The sidebar is ordered by `last_work_at`, so a session that has never
 * been measured working sits at the bottom - the same place a human
 * reads as "the stalest thing I own". Those are different statements.
 * The row is dimmed and carries a title saying so, so the third outcome
 * is something you can SEE, not something the ordering silently folds
 * into the tail of the measured rows. */
.session-sidebar-row[data-work="unrecorded"] .session-sidebar-row-name {
    opacity: 0.72;
}

/* AN ASLEEP ROW (issue #537): its agent and tmux session are stopped to free
   memory and it wakes from its own menu. Greyed as a whole; its status light
   is the shared LED's moon (client/css/status-led.css). */
.session-sidebar-row[data-asleep="1"] .session-sidebar-row-main {
    opacity: 0.55;
}

/* THE ARMED WAKE (issue #1505, Adam (Adoom666), 2026-10-10: "when i click on a
   sleeping agent in the agents drawer have a WAKE button in the middle of it
   appear (small) and an X to the right to cancel"). A click on an asleep row
   draws this overlay INSIDE the row's own box (absolute, inset 0), so no row
   changes height at any density; the row's content dims behind it and goes
   inert (SessionRow.svelte). `wake` is the shared calm confirm
   (`.modal-btn-confirm`, client/css/text-prompt-modal.css) shrunk to the row:
   this class carries geometry plus a raised ground, so the name under it
   does not run through the label. The X is the pin's small icon button
   (session-sidebar-row-controls.css), neutral because cancelling is not
   destructive. Both keep a reserved 1px border, so the shared focus rule
   (web/src/opscenter/focus.css) brightens it; hit areas widen with a
   pseudo-element, never a taller box (the compact row is 24px). */
.session-sidebar-row[data-wake-armed] {
    position: relative;
}
.session-sidebar-row[data-wake-armed] > :not(.session-sidebar-row-wake-arm) {
    opacity: 0.4;
}
/* The right-hand control cluster (optional icons, cup, pin, kebab) is inert
   while armed, and its dimmed glyphs sat under the X (they overlapped it by up
   to 324px2 in compact). `visibility: hidden` keeps their layout, so the row
   does not shift, and leaves the X alone at the right edge. */
.session-sidebar-row[data-wake-armed] .session-sidebar-row-controls-cluster {
    visibility: hidden;
}
.session-sidebar-row-wake-arm {
    position: absolute;
    inset: 0;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: center;
}
[data-wake-arm-go]::after,
[data-wake-arm-cancel]::after {
    content: "";
    position: absolute;
    inset: -2px -8px;
}
/* The cancel X is the base IconButton's close variant (web/src/lib/base/icon-button.css); this places it and keeps it an 18px
 * square at every width (its ::after is the thumb's hit area, so the base 44px phone square would only cover the row). */
[data-wake-arm-cancel] {
    --oc-ibtn-size: 18px;
    --_btn-h: 18px;
    position: absolute;
    top: 50%;
    right: var(--oc-space-1);
    transform: translateY(-50%);
    width: 18px;
    height: 18px;
}
@media (pointer: coarse) {
    [data-wake-arm-go]::after,
    [data-wake-arm-cancel]::after {
        inset: -3px -14px;
    }
}

/* THE RIGHT-HAND CONTROL CLUSTER (Joe, 2026-09-28, issue #1045: "the
   icons for tasks and subagents should be toward right side, by pin.
   all those icons and kebab can be closer"). One wrapper around the
   subagent icon, the schedule icon, the keep-awake cup, the pin and the
   kebab (or a dead row's inline restart/remove in the kebab's place),
   holding every gap between them to ONE 2px rhythm AT EVERY DENSITY -
   the row's own `.session-sidebar-row-main` flex `gap` is 5px in compact
   and 8px in cozy/detailed (session-sidebar-density.css), which is right
   for the rest of the row but was never meant to also be this cluster's
   rhythm. `client/css/session-row-menu.css`'s older per-pair pull-back
   margins (the pin-to-kebab gap, the cup's own margin) are zeroed OUT
   inside this wrapper so they do not stack with this gap; they are
   UNCHANGED outside it, since `web/src/lib/launchpad/RunningSessionRow.svelte`
   draws the same pin/kebab/cup classes with no such wrapper and stays on
   the old rhythm.

   THE CLUSTER MAY SHRINK, AND ONLY ITS OPTIONAL ICONS GIVE (issue #1211):
   `flex-shrink: 1` with `min-width: 0` lets the row take room back from
   the cluster once the name has reached its 8ch floor (the name's basis
   is 0, so it gives its spare width first and nothing past its floor).
   Inside the cluster every control but `.session-sidebar-row-optional-icons`
   stays `flex-shrink: 0`, so that group absorbs all of it. See "THE
   OVERFLOW DROP ORDER" at the foot of this file. */
.session-sidebar-row-controls-cluster {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    flex-shrink: 1;
    min-width: 0;
}

/* THE KEBAB IS ALWAYS THE RIGHTMOST CONTROL OF THE ROW (task manager item 454, Joe (ccsliinc), 2026-10-12: "i want the kebab
   always to the right"). The row's own markup already draws it last; `order` makes that a rule of the layout rather
   than of the markup, so no icon added to the cluster, now or later (the Carnivore timers button, the update-ready
   mark, a dead row's inline actions), can land to its right. Both kebabs carry the one trigger class. */
.session-sidebar-row-controls-cluster > .session-row-menu-trigger {
    order: 99;
}

/* THE OPTIONAL ICONS GIVE WAY BY REAL OVERFLOW (issue #1211). The agents,
   shells and timers icons sit in this one-line wrapping group: when the
   group is narrower than its icons, the rightmost wrap onto a second line
   that the fixed height and `overflow: hidden` never paint. Right to left
   IS the ruled drop order (timers, then shells, then agents: issue #1061),
   so it holds by construction, and nothing is dropped while it fits.
   `justify-content: flex-end` keeps what is left against the cup and pin.
   Drawn only when the row has at least one of the three. */
.session-sidebar-row-optional-icons {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    align-items: center;
    gap: inherit;
    height: 16px;
    overflow: hidden;
    flex: 0 1 auto;
    min-width: 0;
}

/* COMPACT BRINGS THE CLUSTER A LITTLE CLOSER (Joe (ccsliinc), 2026-09-28,
 * issue #1061 follow-up: "on compact you can bring the icons a little
 * closer together"). 2px -> 1px, and the trigger's own side padding
 * trims from 6px to 4px (session-row-menu.css) - both still leave a
 * usable tap/click target, and cozy/detailed are UNCHANGED. */
.session-sidebar-panel[data-density="compact"] .session-sidebar-row-controls-cluster {
    gap: 1px;
}

/* THREE ICON-ONLY MARKERS, ALWAYS ON UNLESS THE PREFERENCE HIDES THEM
   PER DENSITY, IN THAT CLUSTER (Joe, 2026-09-28, issue #1045; split from
   two into three and made preference-gated by issue #1061: "one clear
   name per kind... agents = sub-agents, shells = background
   shells/monitors, timers = the existing clock" - the visibility itself
   is a JS-side gate, `web/src/lib/drawer/row-icon-prefs.ts`, not CSS). None draws a visible
   number: the running count, the parked reason and the next-fire time
   are the `title`/`aria-label` only, read the same way the provider mark
   beside them is (`role="img"`). Sized and centred like the 16px
   provider mark slot, the glyph itself at 13px like the pin and the
   keep-awake cup, so the row's icon-only marks share one optical weight.

   `.session-sidebar-row-agents-icon` and `.session-sidebar-row-shells-icon`
   are both WORK, so both take the same `--oc-green` the cozy/detailed
   subagent chip already uses (#748) - a running sub-agent and an open
   background shell/monitor are both "this session is doing something in
   the background" and read as one colour, told apart by their glyph
   (people vs a terminal window) rather than by a second colour.
   `.session-sidebar-row-timers-icon` (renamed from "schedule", no
   behaviour change) is a fact about the future, not work in progress, so
   it stays the calm secondary token the timer chip beside it already
   uses (#893). */
.session-sidebar-row-agents-icon,
.session-sidebar-row-shells-icon,
.session-sidebar-row-timers-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    line-height: 0;
}

.session-sidebar-row-agents-icon,
.session-sidebar-row-shells-icon {
    color: var(--oc-green);
}

.session-sidebar-row-timers-icon {
    color: var(--oc-text-secondary);
}

/* THE CARNIVORE TIMERS ICON (task manager item 454, Joe (ccsliinc), 2026-10-12; status colors #1639): a session's automations, an
   alarm clock in the optional-icons group beside the timers icon, painted by the server's status word through the shared
   `.oc-timer-state` rules below (the stats bar's automations figure wears the same). Unlike the icon-only marks it is a button:
   a click opens the Automations page on that session. Reset to look like its 16px neighbours; hover brightens the state
   colour instead of replacing it, so the status survives the hover. */
.session-sidebar-row-automations-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: var(--oc-radius);
    background: transparent;
    color: var(--oc-timer-tone, var(--oc-text-dim));
    line-height: 0;
    cursor: pointer;
}

.session-sidebar-row-automations-icon:hover {
    filter: brightness(1.3);
}

/* THE CARNIVORE TIMERS STATUS (#1639, Joe (ccsliinc), 2026-10-12: "green if all ok, yellow if something failed for that
   session or there is a warning, red on error and a grey with x over it if the timers are disabled"). One rule for the
   session row's icon and the stats bar's figure: `.oc-timer-state[data-state]` sets the tone from the existing semantic
   tokens (green, yellow, coral, dim) and `.oc-timer-glyph` paints the glyph in it. Disabled adds a drawn x, two 1px
   diagonals in the same dim tone, over the glyph (no new colour). The word comes from the server
   (`src/core/automations/timer_status.py`); a missing `data-state` leaves the surface's own neutral colour. */
.oc-timer-state[data-state='ok'] { --oc-timer-tone: var(--oc-green); }
.oc-timer-state[data-state='warning'] { --oc-timer-tone: var(--oc-yellow); }
.oc-timer-state[data-state='error'] { --oc-timer-tone: var(--oc-coral); }
.oc-timer-state[data-state='disabled'] { --oc-timer-tone: var(--oc-text-dim); }

.oc-timer-glyph {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--oc-timer-tone, currentColor);
    line-height: 0;
}

.oc-timer-state[data-state='disabled'] .oc-timer-glyph::after {
    content: '';
    position: absolute;
    inset: 1px;
    pointer-events: none;
    background:
        linear-gradient(to top right, transparent calc(50% - 0.5px), currentColor calc(50% - 0.5px), currentColor calc(50% + 0.5px), transparent calc(50% + 0.5px)),
        linear-gradient(to bottom right, transparent calc(50% - 0.5px), currentColor calc(50% - 0.5px), currentColor calc(50% + 0.5px), transparent calc(50% + 0.5px));
}

/* THE WORKFLOW MARK (issue #1130, Adam (Adoom666), 2026-09-29: "small but
   noticeable"). Drawn directly left of the pin (in the right-hand cluster) at every density while a
   Workflow tool run is in flight (`workflow_active`). --oc-cyan is the
   colour the subagent count already turns for a workflow (#852), so the
   two read as one fact; a slow opacity pulse is what makes it catch the
   eye without adding width. Never
   preference-gated, never dropped by the overflow order below. */
.session-sidebar-row-workflow-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    line-height: 0;
    color: var(--oc-cyan);
    animation: session-sidebar-workflow-pulse 2.4s ease-in-out infinite;
}

@keyframes session-sidebar-workflow-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.6; }
}

@media (prefers-reduced-motion: reduce) {
    .session-sidebar-row-workflow-icon {
        animation: none;
    }
}

/* ---- THE OVERFLOW DROP ORDER (visual QA, issue #1061 follow-up) -----
 *
 * A busy row (running sub-agents, an open background shell, a live
 * timer, the keep-awake cup) was measured collapsing its own name to one
 * character at the drawer's 320px default width, and to nothing at all
 * at its 240px minimum (web/src/lib/drawer/resize.ts's MIN_WIDTH_PX),
 * with the pin and kebab pushed past the list's own `overflow-x: hidden`
 * edge (session-sidebar.css) and unreachable. Orchestrator's ruling,
 * reversible: the name keeps a readable floor (8ch, above) and the pin
 * and the kebab/update-ready trigger, both already `flex-shrink: 0`
 * (session-sidebar-row-controls.css, session-row-menu.css), are NEVER
 * among the things given up. What gives, LOWEST VALUE FIRST:
 *
 *   1. the plain-text counts: cozy's clickable subagent/timer chips
 *      (`.subagent-count--button`, `.timer-chip--button`) and detailed's
 *      bare inline number (`.session-row__subagent-count`) - these only
 *      ever restate what the matching icon's own title/aria-label
 *      already says, so they are the cheapest thing on the row. Dropped
 *      by the row's OWN width (`container-name: sidebar-row` above).
 *   2-4. the timers icon, then the shells icon, then the agents icon,
 *      dropped by REAL OVERFLOW, not by a width: they share
 *      `.session-sidebar-row-optional-icons` (above), which gives up
 *      its rightmost icon first and only once the name has reached its
 *      floor. They USED TO drop at fixed row widths (275, 260, 245px),
 *      whatever the row carried, so a quiet row inside a band at the
 *      320px default drawer (about 272px wide) lost its only icon with
 *      100px to spare (issue #1211, Joe (ccsliinc), 2026-10-01: "fantasy
 *      football has timers, not seeing in sidebar"). Held in a real
 *      browser by tests/python/drawer/test_sidebar_row_icon_fit.py.
 *   5. the keep-awake cup, LAST: a kept-awake row is holding this Mac
 *      awake (issue #617), so it keeps the room as long as any exists.
 *      This threshold sits below the panel's own 240px floor and is a
 *      defensive floor, not a state the drawer's resize handle can reach.
 *
 * A DROPPED ICON'S INFO IS NOT LOST: every icon's `title`/`aria-label`
 * is set at paint time whether or not it is currently painted
 * (web/src/lib/sidebar-shell/row-chips.ts), so the row's own
 * hover state still carries it once the icon has room again. */
@container sidebar-row (max-width: 300px) {
    .session-sidebar-row .subagent-count--button,
    .session-sidebar-row .timer-chip--button,
    .session-sidebar-row .session-row__subagent-count {
        display: none;
    }
}

@container sidebar-row (max-width: 200px) {
    .session-sidebar-row-keep-awake {
        display: none;
    }
}
}

/* THE WAKE BUTTON'S SIZE, OUTSIDE THE LAYER ON PURPOSE: `.modal-btn` (styles.css)
 * and `.modal-btn-confirm` (text-prompt-modal.css) are unlayered, so a rule in
 * `@layer components` would lose to their padding, font size and clear ground
 * whatever its specificity. Geometry and the raised ground only; the outline,
 * label colour and focus edge stay the shared confirm's (issue #1505). */
.session-sidebar-row [data-wake-arm-go] {
    position: relative;
    box-sizing: border-box;
    height: min(22px, calc(100% - 2px));
    padding: 0 var(--oc-space-3);
    font-size: 0.75rem;
    line-height: 1;
    background: var(--oc-ground-raised);
}
.session-sidebar-row [data-wake-arm-go]:hover:not([aria-disabled="true"]) {
    background: var(--oc-orange-tint);
}
.session-sidebar-row [data-wake-arm-go][aria-disabled="true"] {
    opacity: 0.6;
    cursor: default;
}

/* THE BELL LIGHT (feature plan #4, Q5): a program rang the terminal bell, so the row wears a static yellow left
   hairline for a moment (web/src/lib/session-badges/progress.svelte.ts sets data-bell, then clears it). No sound,
   no card, no animation. */
@layer components {
    .session-sidebar-row[data-bell='1'] {
        box-shadow: inset 2px 0 0 var(--oc-yellow);
    }
}
