/* The GLYPH CONTROLS a conversation row builds itself - the provider
 * mark at its head, the share mark and the pin toggle at its tail - plus
 * the drag surface they sit on. Markup:
 * web/src/lib/sidebar-shell/ (RowChip.svelte, RowPin.svelte, row-chips.ts).
 *
 * Split out of client/css/session-sidebar-density.css on 2026-09-21 for
 * the 500-line budget that file is held to, along the same seam the JS
 * took: that file is the three DENSITY modes and the row geometry they
 * set, this one is the controls, which look the same at all three.
 *
 * MUST load AFTER session-sidebar-density.css (whose `.session-sidebar-
 * row-main` rules the row cursor here sits alongside) and BEFORE
 * session-row-menu.css, which pulls the kebab back toward the pin and has
 * to win over the sizing here.
 */

/* ---- Provider mark ---------------------------------------------------
 * The glyph slot at the head of the row, which since 2026-09-21 says
 * which agent family the session is running instead of offering a drag
 * handle. The mark itself is drawn by client/js/agent-family-icon.js.
 *
 * IT IS STILL THE TOUCH DRAG HANDLE, which is the whole reason
 * `touch-action: none` is on THIS element and not on the row. A pointer
 * drag surface has to claim the touch or the browser pans instead of
 * sending moves, and a row that claims the touch is a sidebar a finger
 * cannot scroll. So a mouse or pen drags from anywhere on the row and a
 * finger drags from here. See web/src/lib/sidebar-shell/row-drag.ts.
 *
 * FIXED WIDTH, NOT INTRINSIC. The mark is 14px and the slot is 16px, so
 * every row's name starts at the same x whichever provider it is and
 * whether or not the family resolved - a name column that shifts when a
 * poll tick learns the family is worse than one that is a pixel wide. */

@layer components {
.session-sidebar-row-provider {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    color: var(--oc-text-secondary);
    flex-shrink: 0;
    touch-action: none;
    line-height: 0;
    position: relative;
}

/* A family we could not determine is drawn as a dashed ring and is
 * deliberately the quietest thing on the row: it is the absence of a
 * measurement, not a provider called "unknown".
 *
 * KEYED ON THE DATA ATTRIBUTE, NEVER ON THE LABEL. This selector used to
 * read `[aria-label="agent not determined"]`, a verbatim copy of one
 * entry in the label table. Nothing connected the two: reword that
 * sentence, or translate it, and the dimming silently stops with no test
 * going red and nothing to grep for. `data-agent-family` is the same
 * normalised key the mark itself is chosen by, so the style and the
 * glyph cannot disagree about which family this is. */
.session-sidebar-row-sleeping-icon,
.session-sidebar-row-wake-icon,
.session-sidebar-row-archived-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    color: var(--oc-text-muted);
    flex-shrink: 0;
    line-height: 0;
}

/* The wake clock is a button when it can open the session's automations (#2688): reset to look like its 16px neighbours. */
button.session-sidebar-row-wake-icon {
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: var(--oc-radius);
    background: transparent;
    cursor: pointer;
}

button.session-sidebar-row-wake-icon:hover {
    color: var(--oc-text);
}

/* THE ROLE MARK (Task Manager roles, #1705): the project lead's star, a 7px glyph pinned to the provider mark's corner, so the row's
 * one accent stays the provider and the role reads as a mark ON it. Tokens only: the star is the accent (--oc-orange). The provider
 * slot is the positioning box. (The do-not-disturb badge is gone, #2604.) */
.session-sidebar-row-provider__lead {
    position: absolute;
    right: -3px;
    width: 7px;
    height: 7px;
    display: inline-flex;
    pointer-events: none;
    line-height: 0;
}

.session-sidebar-row-provider__lead {
    top: -1px; /* at the compact, normal and full density a -3px star sat 1px from the row's top edge */
    color: var(--oc-orange);
}

.session-sidebar-row-provider__lead svg {
    fill: currentColor;
}

.session-sidebar-row-provider[data-agent-family="unknown"] {
    color: var(--oc-text-muted);
    opacity: 0.6;
}

/* ---- The row is the drag surface, and says nothing about it ----------
 * The ARROW on the row body (owner, 2026-09-23: rows use the normal
 * cursor, the hand only over the status dot). A mouse drag still starts
 * anywhere on the row; `grabbing` below still shows while one is in
 * flight. Buttons inside the row keep their hand: they are buttons. */

.session-sidebar-row-main {
    cursor: default;
}

.session-sidebar-row .status-dot {
    cursor: pointer;
}

.session-sidebar-row-main button {
    cursor: pointer;
}

/* THE RENAME FIELD IS A TEXT FIELD AND MUST SAY SO. This rule used to
 * name `input` alongside `button` and gave the inline rename editor an
 * arrow cursor: `.session-sidebar-row-main input` is (0,2,1) and beats
 * `.session-sidebar-rename-input`, so the field a user is about to type
 * into looked like something to click. `auto` rather than `text` so the
 * browser still picks the right caret for whatever input type a future
 * control uses; the only job here is to stop `grab` inheriting down. */
.session-sidebar-row-main input {
    cursor: auto;
}

.session-sidebar-list--dragging .session-sidebar-row-main,
.session-sidebar-list--dragging .session-sidebar-row .status-dot {
    cursor: grabbing;
}

/* ---- The share mark -------------------------------------------------
 * The telescope immediately before the pin, drawn only on a session with
 * a LIVE read-only link (docs/spectator-links.md). Markup:
 * web/src/lib/sidebar-shell/row-chips.ts::sharePlan.
 *
 * SIZED AND SHAPED AS THE PIN BELOW, to the pixel and deliberately: the
 * two sit side by side, and a neighbour half a pixel off reads as a
 * rendering fault rather than as a different control.
 *
 * CYAN, NOT THE PIN'S ORANGE, because the two say different kinds of
 * thing. Orange on this row means "you put this here" - a pin, a focus
 * ring. This is not a preference of the owner's, it is a fact about who
 * else can see the session, so it takes the palette's other accent. It
 * is coloured AT REST rather than on hover, because the whole point of
 * the mark is to be noticed without being hunted for.
 *
 * NO COLOUR LITERAL, only `--oc-*` tokens. That is what keeps all 26
 * themes working with no per-theme rule. */

.session-sidebar-row-share {
    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-cyan);
    cursor: pointer;
    flex-shrink: 0;
    transition: color 120ms ease, background 120ms ease, border-color 120ms ease;
}

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

/* ---- Per-row pin -----------------------------------------------------
 * Sized and coloured to match .session-sidebar-row-delete and
 * .mark-unread-toggle, so the row's controls read as one set. */

.session-sidebar-row-pin,
.session-sidebar-row-key {
    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-pin:hover,
.session-sidebar-row-pin:focus-visible {
    color: var(--oc-orange);
    background: var(--oc-ground-hover);
    outline: none;
}

.session-sidebar-row-pin[aria-pressed="true"] {
    color: var(--oc-orange);
}

/* ---- Page and remote browser rows: pop out (task manager item 439) ---
 * The same 18px slot, muted colour and hover chip as the pin, BEFORE the pin, so the pin stays beside the kebab
 * (#1670). Closing is the row menu's item; the always-on close x was removed, and comes back only while Shift is
 * held, in the kebab's slot (#1697, below). */

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

/* ---- The red close x while Shift is held (#1697) ---------------------
 * Joe: "shift kebab on left side bar of browsers is close tab with the
 * kebab changing to a red x". BrowserRow.svelte draws the holder
 * `.session-sidebar-row-shift-close` (the x inside it) as a sibling AFTER
 * the kebab, and marks the row data-shift-close="1", ONLY while Shift is
 * down, so Shift-up markup is the legacy row byte for byte.
 *
 * THE X LANDS IN THE KEBAB'S SLOT WITHOUT RESTATING A SIZE: the holder
 * covers the main line and takes the line's own padding (`inherit`), so
 * its end-aligned x sits exactly where the last flex item, the kebab,
 * sits at every density; it lets clicks through everywhere but the x.
 * The x is the kebab trigger's tap target on the space scale (one
 * --oc-space-5 wide, stretched to the line's height; the trigger itself is
 * `min-width: 24px` plus its own padding, client/css/session-row-menu.css).
 *
 * EVERY BROWSER AND PAGE ROW SWAPS AT ONCE while Shift is held (the
 * owner, 2026-10-12, #1697 follow-up: "i want it to show whenever
 * click is pushed", read as whenever Shift is held), not only the hovered
 * or focused one; releasing Shift, or the window losing focus, takes every
 * x away. Each x still closes only its own row. A focused ROW keeps its
 * keyboard path, Shift+Enter, Shift+Space or Shift+Delete running its x
 * (onRowKeydown, web/src/lib/sidebar-shell/row-reorder.ts). A row whose
 * kebab has focus (after its menu closes) or whose menu is open keeps the
 * kebab, so focus is never parked on a hidden control and can return to
 * it on close. While the x shows, the kebab is `visibility: hidden` but
 * keeps its box, so Shift+F10 and right click still anchor the menu. Destructive token --oc-coral, a little
 * brighter on hover (the focus.css lift tokens); focus is focus.css's own
 * rule on the reserved 1px border. Touch has no Shift, so nothing changes
 * there. */
.session-sidebar-row[data-shift-close="1"] .session-sidebar-row-main {
    position: relative;
}

.session-sidebar-row-shift-close {
    position: absolute;
    inset: 0;
    box-sizing: border-box;
    padding: inherit;
    display: none;
    justify-content: flex-end;
    align-items: stretch;
    pointer-events: none;
}

.session-sidebar-row[data-shift-close="1"]:not(:has([aria-expanded="true"], .session-row-menu-trigger:focus)) .session-sidebar-row-shift-close {
    display: flex;
}

.session-sidebar-row[data-shift-close="1"]:not(:has([aria-expanded="true"], .session-row-menu-trigger:focus)) .session-row-menu-trigger {
    visibility: hidden;
}

.session-sidebar-row-key--close {
    pointer-events: auto;
    width: auto;
    height: auto;
    min-width: var(--oc-space-5);
    padding: 0;
    color: var(--oc-coral);
}

.session-sidebar-row-key--close:hover,
.session-sidebar-row-key--close:focus-visible {
    color: color-mix(in oklab, var(--oc-coral) var(--oc-focus-keep), var(--oc-focus-lift));
}

/* ---- A file row's unsaved-changes dot (item 539, docs/open-files.md) --
 * A file opened for the owner with edits not yet on disk draws one small
 * dot right after its name, in the waiting color (--oc-yellow: the owner
 * has something to do), the same fact the file screen's "unsaved" flag
 * says in words. Saved, the dot is not drawn at all. */
.session-sidebar-row-dirty {
    flex: 0 0 auto;
    width: var(--oc-space-2);
    height: var(--oc-space-2);
    margin: 0 var(--oc-space-1);
    border-radius: 50%;
    background: var(--oc-yellow);
}

/* THE PIN LEANS WHEN IT IS NOT IN (owner, 2026-09-21: "I want the pins
 * tilted for unpinned, and straight up when pinned"). ONE glyph, one
 * rotation, keyed off the button's own `aria-pressed` - so the shape and
 * the announced state are the same fact and cannot drift, and the tilt is
 * an ADDITION to a state the button already says in words rather than the
 * only thing carrying it.
 *
 * The transform is on the SVG, not the button: rotating the button would
 * turn its focus ring and its hover chip with it. 45 degrees is enough to
 * read as "resting on the desk" at 13px; a smaller angle looks like a
 * rendering fault rather than a state. */
.session-sidebar-row-pin svg {
    transform: rotate(-45deg);
    transition: transform 140ms ease;
}

.session-sidebar-row-pin[aria-pressed="true"] svg {
    transform: none;
}

@media (prefers-reduced-motion: reduce) {
    .session-sidebar-row-pin svg {
        transition: none;
    }
}

/* ---- The model mark (the robot) -------------------------------------
 *
 * Sits immediately right of the provider mark. The provider says WHOSE
 * agent this is; this says WHICH MODEL of theirs is running and roughly
 * what it costs. See client/js/session-model-icon.js.
 *
 * THE FIVE TINTS ARE `--usage-scale-1` THROUGH `-5`, declared just below.
 * They were the old per-session usage panel's scale and moved here when
 * that panel was replaced by the provider ledger panel (issue #431),
 * since this robot is their one remaining reader.
 *
 * The tier is decided server-side from the model's published OUTPUT
 * price, so no price list lives in this stylesheet either. A model the
 * price table does not carry arrives with NO tier, matches none of the
 * five rules, and keeps the muted default - an untinted robot is the
 * honest answer for a model nobody has priced, and is never mistaken
 * for "cheap".
 *
 * THE FIVE-STOP SCALE IS A THEME'S TO OVERRIDE, AND THAT IS THE
 * SUPPORTED PATH. The values below are DEFAULTS, written in terms of
 * tokens every bundled theme already ships, so the scale follows any
 * palette with no per-theme rule. A theme that wants its own ramp names
 * those five keys in its own `cssVars`: theme variables are written
 * INLINE on `:root` by client/js/themes/registry.js, and an inline
 * declaration beats a stylesheet rule, so the override works with no
 * code change here. It always runs cool to hot: step 1 is cheapest,
 * step 5 is priciest. */

:root {
    /* 1 GREEN. */
    --usage-scale-1: var(--color-success);
    /* 2 BLUE. */
    --usage-scale-2: var(--color-info);
    /* 3 YELLOW. */
    --usage-scale-3: var(--color-warning);
    /* 4 ORANGE. No theme ships an orange token, so it is mixed from the
     * two it does ship, which keeps it inside the theme's own palette
     * instead of importing a literal that would clash on a light one. */
    --usage-scale-4: color-mix(in srgb, var(--color-warning) 55%, var(--color-danger));
    /* 5 RED. */
    --usage-scale-5: var(--color-danger);
}

.session-sidebar-row-model {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* 16x16, MATCHING .session-sidebar-row-provider's SLOT so the two
     * marks render at the same size side by side; the mark inside is
     * 14x14 same as the provider's, same 1px margin on every side. */
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    /* The no-tier default. Muted, so an unpriced model recedes rather
     * than competing with the five that mean something. */
    color: var(--oc-text-muted);
}

.session-sidebar-row-model[data-model-tier="1"] { color: var(--usage-scale-1); }
.session-sidebar-row-model[data-model-tier="2"] { color: var(--usage-scale-2); }
.session-sidebar-row-model[data-model-tier="3"] { color: var(--usage-scale-3); }
.session-sidebar-row-model[data-model-tier="4"] { color: var(--usage-scale-4); }
.session-sidebar-row-model[data-model-tier="5"] { color: var(--usage-scale-5); }

/* THE TOP OF BOTH LADDERS, AND NOTHING ELSE. The priciest model run at
 * the highest effort. Owner: "make the robot be purple with an animated
 * sparkle evaporating around it."
 *
 * The purple is the ONE colour this feature adds, because the five-step
 * scale it borrows has no sixth step - and that is the point: the state
 * is deliberately outside the ordinary ladder, so it cannot be mistaken
 * for "slightly more expensive than red". It reuses `--oc-violet`, the
 * one fixed violet mark (issue #905) - the same family the keep-awake cup
 * and the auto-switch icon wear - rather than a hardcoded hex, so it
 * stays a token even though the mark itself is not theme-derived. */
.session-sidebar-row-model[data-model-top="1"] {
    --model-top-ink: var(--oc-violet);
    color: var(--model-top-ink);
}

/* THE SPARKLE EVAPORATES: it rises and fades rather than pulsing in
 * place, which is what "evaporating around it" describes.
 *
 * IT IS A PSEUDO-ELEMENT PAIR ON ITS OWN ABSOLUTE LAYER, never the
 * robot's own stroke. Animating the glyph itself would make a
 * twelve-pixel outline shimmer until it stopped reading as a robot, and
 * the element's box must not move - the row's other marks are aligned
 * against it. `position: absolute` plus `pointer-events: none` keeps
 * this out of layout and out of the way of the row's click and drag
 * handling entirely. */
/* THE WRAPPER (issue #1821): the spark is a SIBLING of the mark, not its child. The mark is a backdrop root
 * (will-change: opacity, effort-level.css) and a compositor animation inside one costs 2 to 3 times the GPU of the same
 * animation outside it. The wrapper is the mark's own 16px box, so the spark's inset is unchanged. */
.session-sidebar-row-model-wrap {
    --model-top-ink: var(--oc-violet);
    position: relative;
    display: inline-flex;
    flex-shrink: 0;
}

.session-sidebar-row-model__spark {
    position: absolute;
    inset: -3px;
    pointer-events: none;
}

.session-sidebar-row-model__spark::before,
.session-sidebar-row-model__spark::after {
    content: "";
    position: absolute;
    width: 2px;
    height: 2px;
    border-radius: 50%;
    background: var(--model-top-ink);
    opacity: 0;
    animation: session-model-spark 2.4s ease-out infinite;
}

.session-sidebar-row-model__spark::before {
    left: 1px;
    bottom: 3px;
}

/* The second mote is offset in BOTH space and time, so the two read as
 * a drift rather than as a blink. */
.session-sidebar-row-model__spark::after {
    right: 2px;
    bottom: 1px;
    animation-delay: 1.2s;
}

@keyframes session-model-spark {
    0%   { opacity: 0; transform: translateY(0) scale(0.6); }
    20%  { opacity: 0.9; }
    100% { opacity: 0; transform: translateY(-9px) scale(1); }
}

/* A READER WHO ASKED FOR NO MOTION STILL GETS THE STATE. The sparkle
 * stops, and the purple robot is what carries "top model, top effort" on
 * its own - the colour was always the signal and the motion the
 * flourish. Matches how client/css/status-led.css treats its spinner. */
@media (prefers-reduced-motion: reduce) {
    .session-sidebar-row-model__spark::before,
    .session-sidebar-row-model__spark::after {
        animation: none;
        opacity: 0;
    }
}

/* ANIMATIONS SETTING (issue #1617): `html[data-motion="off"]` wears the reduced-motion look above, whatever the OS says;
 * the animation itself is stopped by the one rule in animation-pause.css. */
:root[data-motion="off"] .session-sidebar-row-model__spark::before,
:root[data-motion="off"] .session-sidebar-row-model__spark::after {
    opacity: 0;
}
}
