/* =====================================================================
 * Session sidebar - row DENSITY, the reorder controls, and the two
 * three-outcome blocks the list can draw instead of rows.
 * ---------------------------------------------------------------------
 * Its own file so client/css/session-sidebar.css stays under the 500-line
 * project convention. Loaded AFTER it, because the density rules override
 * the base `.session-sidebar-row` padding declared there.
 *
 * EVERY COLOUR HERE IS AN EXISTING THEME TOKEN from styles.css's :root.
 * This round is mechanics, not a visual language: nothing below invents a
 * palette, and the cozy row is byte-for-byte the row that shipped before
 * the density control existed.
 *
 * WHERE THE HEIGHT DIFFERENCE COMES FROM. Four levers, all declared and
 * all measurable: row padding, line-height, whether a second line exists
 * at all, and an explicit per-mode `min-height` that makes the three
 * numbers a stated contract rather than an accident of whichever
 * controls ride the line. See THE DENSITY CONTRACT at the foot of this
 * file. No inline styles and no JS-computed sizes, so
 * scripts/archive/verify/verify_sidebar_sessions.py can measure the real boxes in a
 * real Chromium and the numbers mean something.
 * ===================================================================== */

/* ---- Row shell -------------------------------------------------------
 * The row is now a column: a main line, and (detailed only) a meta line.
 * The base rule in session-sidebar.css still owns background, border and
 * hover. */

@layer components {
.session-sidebar-row {
    display: block;
    padding: 0;
    /* Every mode below states its own height. See THE DENSITY CONTRACT
     * at the foot of this file for why that is a min-height and not a
     * fixed height. */
    box-sizing: border-box;
}

.session-sidebar-row-main {
    display: flex;
    align-items: center;
    gap: var(--oc-space-2);
    min-width: 0;
}

/* THE PILL MUST NOT WRAP INSIDE A 320px BAR. "unknown family" is two
 * words and the bar is narrow, so the pill wrapped to two lines and made
 * the cozy row 59.34px tall - measured, in a real browser, against an
 * expected ~44. The row is not a wrapping layout; the NAME gives way and
 * already ellipsizes. Capping the pill keeps a long name from eating the
 * name column. */
/* KEYBOARD FOCUS IS THE SHARED RULE (web/src/opscenter/focus.css): the row's own 1px border
 * (session-sidebar-rows.css) brightens, so the row draws no ring of its own (Joe, 2026-10-28, "focusring"). */

/* THE PINNED RAIL IS GONE, AND `[data-pinned="1"]` NOW PAINTS NOTHING.
 * Deliberately no rule here, so this comment is the record of why.
 *
 * It was `box-shadow: inset 2px 0 0 var(--color-accent)`, defended as
 * the answer to "why is this one at the top". That question has three
 * answers already, all in the markup and none colour-only: the `pinned`
 * group HEADER the row sits under with its own count; the row's POSITION
 * in that band; and the row's own pin BUTTON, emitted at every density,
 * carrying `aria-pressed="true"` and drawn in the accent by
 * `.session-sidebar-row-pin[aria-pressed="true"]` below. The rail was a
 * fourth, colour-only restatement of a fact three other things say.
 *
 * It was also already unreliable. session-theme-tint.css matches
 * `.session-sidebar-row[data-session-theme]` at the SAME specificity and
 * loads after it, so it replaced `box-shadow` outright: any pinned row
 * that also carried a session theme had no rail at all, and nobody could
 * tell which by looking. A cue that silently vanishes for a subset of
 * the rows it describes is not a cue.
 *
 * And it is the shape the request names: "get rid of the thick left bar
 * like on the homepage and clean it like the homepage looks now". A 2px
 * inline-start rail is a left-side colour bar whatever it encodes. Do not
 * reintroduce one here without first deciding which of the four signals
 * is authoritative. */

/* THE ROW'S TRAILING PADDING IS SMALLER THAN ITS LEADING PADDING, at
 * every density, and the asymmetry is deliberate (owner, 2026-09-21:
 * "move the pin and kabob icons over more - there's extra space at the
 * end there"). The two controls at that end carry their own padding as a
 * tap target - `.session-row-menu-trigger` is `padding: 0 6px` in
 * client/css/session-row-menu.css - so the row's own padding was landing
 * on top of it and pushing the glyphs a control's width in from the edge.
 * Trimming the row's side rather than the trigger's is what moves them
 * over WITHOUT shrinking the thumb target, which is the thing that must
 * not move. The leading edge keeps its full padding: nothing there has
 * padding of its own, and the status light needs the room.
 *
 * ---- compact (DEFAULT) ----------------------------------------------
 * The "super thin bars so i can see more" end of the request, and the
 * mode the panel opens in since 2026-09-21: the bar is docked open on
 * every screen now, so fitting more of the list on screen beats spending
 * height on every row by default. The row builder draws no badge and no
 * last-worked stamp here.
 *
 * THIS COMMENT USED TO DEFEND KEEPING THE FAMILY PILL HERE, on the
 * reasoning that a density mode must not quietly delete information
 * nobody asked to lose. That does not survive the user asking for the
 * pill to go ("i dont think we need the pills in the sidebare take out
 * for now"): it is gone from all three modes, home keeps its own. */

.session-sidebar-panel[data-density="compact"] .session-sidebar-row {
    margin-bottom: 1px;
    /* RESTATED AT 24px, unchanged, despite the font-size drop below - see
     * THE DENSITY CONTRACT at the foot of this file. A shrunk glyph must
     * never silently shrink the row along with it. */
    min-height: 24px;
}

.session-sidebar-panel[data-density="compact"] .session-sidebar-row-main {
    padding: 2px 2px 2px var(--oc-space-2);
    gap: var(--sidebar-row-main-gap);
    line-height: 1.15;
    /* Reduced from 0.85em (owner, 2026-09-22: "Reduce the font size and
     * weight for sessions so the project / group names are larger" - see
     * .session-sidebar-group__header in session-sidebar-groups.css). */
    font-size: 0.78em;
}

.session-sidebar-panel[data-density="compact"] .mark-unread-toggle {
    width: 16px;
    height: 16px;
}

/* The gap between bands scales down in compact mode: compact exists to
 * show more rows in the same height, and a full-size band gap would eat
 * back the room the tighter rows just bought. The value is the
 * `--sidebar-band-gap` token, overridden for compact in
 * session-sidebar-band-structure.css (issue #897). */

/* ---- cozy -----------------------------------------------------------
 * The compact line's contents at 10px padding on both axes, PLUS the two
 * things the extra height now buys: the origin badge when the session is
 * external, and the relative last-worked stamp. Both ride the existing
 * line box - the tallest thing on it is still the name at 1em/1.4 - so
 * the declared 46px is unchanged by the redesign. */

.session-sidebar-panel[data-density="cozy"] .session-sidebar-row {
    /* RESTATED AT 46px, unchanged - see THE DENSITY CONTRACT at the foot
     * of this file, and the compact rule above for why this is stated. */
    min-height: 46px;
}

.session-sidebar-panel[data-density="cozy"] .session-sidebar-row-main {
    padding: 10px 2px 10px 10px;
    line-height: 1.4;
    /* Session rows shrink a touch at every density so the group/project
     * headers above them read as the bigger thing on the list. */
    font-size: 0.92em;
}

/* ---- detailed -------------------------------------------------------
 * "or more detail": the first line is the compact line, and the second
 * carries the origin badge, the age, the last-worked stamp and the
 * resting activity note. Nothing is drawn on both lines, which is what
 * keeps the second one about something. The agent family pill used to
 * sit here and no longer exists on this surface. */

.session-sidebar-panel[data-density="detailed"] .session-sidebar-row {
    /* RESTATED AT 66px, unchanged - see THE DENSITY CONTRACT at the foot
     * of this file. */
    min-height: 66px;
}

.session-sidebar-panel[data-density="detailed"] .session-sidebar-row-main {
    padding: 10px 2px 2px 10px;
    line-height: 1.4;
    font-size: 0.92em;
}

/* THE SECOND LINE MAY NEVER GROW A THIRD. It now carries up to four
 * parts inside a 320px bar, and a flex line that overflowed would push
 * the row past the 66px this file declares - the exact failure the
 * min-height block at the foot of this file exists to prevent, arriving
 * from the other direction. Flex already refuses to wrap; `overflow:
 * hidden` plus the ellipsis on the note below is what makes the
 * overflow degrade instead of spilling. The note is the only part
 * allowed to shrink: origin, age and stamp are all short and fixed. */
.session-sidebar-row-meta {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 0 10px 9px 34px;
    min-height: 18px;
    overflow: hidden;
}

.session-sidebar-row-age,
.session-sidebar-row-when {
    font-size: 0.7em;
    color: var(--oc-text-muted);
    white-space: nowrap;
    flex-shrink: 0;
}

/* The resting note beside a status, e.g. "shell still running". Last on
 * the line and the only part that gives way. */
.session-sidebar-row-hint {
    font-size: 0.7em;
    color: var(--oc-text-secondary);
    font-style: italic;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* THE LAST-WORKED STAMP ON THE COZY LINE. It sits after the name, which
 * is the flex item that grows, so it is pushed hard against the row's
 * controls - right-aligned without a `margin-left: auto` that would
 * fight the name for the same space. The list is SORTED by this value
 * (web/src/lib/drawer/fetch.ts defaultSort), so until it was drawn the rows
 * were ordered by something nothing on screen said. */
.session-sidebar-panel[data-density="cozy"] .session-sidebar-row-main
    .session-sidebar-row-when {
    margin-left: 2px;
}

/* The density control is the view menu in the sidebar's top bar, styled
 * there (web/src/lib/drawer-tabs/ViewMenu.svelte). */

/* ---- Three-outcome blocks --------------------------------------------
 * Neither of these is a row, and neither carries an action control. A
 * control against a session whose existence could not be confirmed either
 * does nothing or does something to the wrong session. */

.session-sidebar-attention,
.session-sidebar-notice {
    margin: 6px var(--oc-space-1) 10px var(--oc-space-1);
    padding: var(--oc-space-2) 10px;
    border: 1px solid var(--oc-yellow);
    border-radius: var(--oc-radius-sm);
    background: var(--oc-ground-hover);
}

.session-sidebar-attention__head {
    font-size: 0.65em;
    letter-spacing: 0.6px;
    color: var(--oc-yellow);
    font-weight: bold;
}

.session-sidebar-attention__title,
.session-sidebar-notice__title {
    font-size: 0.8em;
    color: var(--oc-text-bright);
    font-weight: bold;
    margin-top: 2px;
}

.session-sidebar-attention__detail,
.session-sidebar-notice__detail {
    font-size: 0.72em;
    color: var(--oc-text-secondary);
    margin-top: 3px;
    overflow-wrap: anywhere;
}

/* A remembered slot whose session is not listed is not an error and not a
 * silent drop, so it gets the quietest treatment on offer while still
 * being on screen. */
.session-sidebar-note {
    margin: 6px var(--oc-space-1) 2px var(--oc-space-1);
    padding: var(--oc-space-1) 6px;
    font-size: 0.68em;
    color: var(--oc-text-secondary);
    border-top: 1px solid var(--oc-line-faint);
}

/* Visually hidden, still announced. The reorder feedback has to reach a
 * screen reader without adding a line of chrome for sighted users. */
.session-sidebar-live {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* =====================================================================
 * THE DENSITY CONTRACT
 *
 * compact 24px, cozy 46px, detailed 66px, measured on the ROW, in a real
 * browser, by scripts/archive/verify/verify_sidebar_sessions.py and by the geometry
 * suite in tests/.
 *
 * THE 2026-09-21 REDESIGN MOVED NONE OF THE THREE. Cozy gained an origin
 * badge and a last-worked stamp, detailed's second line gained the age,
 * the stamp and a resting note; every one of them rides an existing line
 * box, so the three numbers above were re-measured and came back
 * unchanged rather than being edited to match whatever came out.
 *
 * WHY THE NUMBERS ARE STATED HERE RATHER THAN LEFT TO ADD UP. Before
 * this block the three heights were whatever the padding, the
 * line-height and the tallest control on the line happened to produce.
 * That is not a contract, it is an outcome: removing the family pill
 * this round would have silently shortened every mode, and adding any
 * control taller than the current tallest would silently lengthen them.
 * A number that moves when an unrelated control is added or removed
 * cannot be asserted against.
 *
 * WHY min-height AND NOT height. A row must still be allowed to grow
 * when its own content genuinely needs the space - a long name that
 * wraps, or a browser at a larger base font. Pinning `height` would clip
 * that instead of showing it, which trades a visible layout stretch for
 * an invisible truncation. The floor is the contract; the ceiling is the
 * content's business.
 *
 * DETAILED'S SECOND LINE is `.session-sidebar-row-meta`: the origin
 * badge, the age, the last-worked stamp and the resting note. It holds
 * its own `min-height: 18px` for the same reason this block exists - the
 * family pill used to sit there, and the line had to keep its height
 * when the pill left it - and now an `overflow: hidden` for the mirror
 * reason, so four parts in a 320px bar cannot push it the other way.
 * ===================================================================== */

/* ---- Context gauge (issue #1102) ---------------------------------------
 * The row's own 1px bottom border, recoloured as a fill (Adam (Adoom666),
 * 2026-09-30: the border itself, not a line under it), drawn by the shared
 * LimitGauge (fill form) in the foot bar's absolute usage ladder. Placed
 * over the border box's bottom edge and pointer-transparent, so it takes no
 * height, no width from the name and no click from the row: no layout shift
 * at any density. The bottom corners follow the row's radius; the gauge's
 * own inset-ringed track is flattened because a 1px bar cannot carry it, and
 * the empty part of the track stays clear so the plain border shows. */
.session-sidebar-row[data-context-gauge] {
    position: relative;
}

.session-sidebar-row-context {
    position: absolute;
    /* Starts one corner radius in so it clears the curve, fades in over its
     * first 5px, and sits 25% dimmer (Adam (Adoom666), 2026-09-30). */
    inset: auto -1px -1px var(--oc-radius-sm);
    pointer-events: none;
    overflow: hidden;
    /* The clip box is as tall as the corner radius, not the 1px bar: CSS
     * scales a radius down to fit its box, so a 1px-tall clip had no curve
     * and a full bar's right end stuck out past the rounded corner. The bar
     * sits on the box's bottom edge and the box's curve clips it. */
    height: var(--oc-radius-sm);
    justify-content: flex-end;
    border-radius: 0 0 var(--oc-radius-sm) 0;
    opacity: 0.75;
    -webkit-mask-image: linear-gradient(to right, transparent, var(--oc-text-primary) 5px);
    mask-image: linear-gradient(to right, transparent, var(--oc-text-primary) 5px);
}

.session-sidebar-row-context .oc-gauge__bar {
    border-radius: 0;
    background: transparent;
    box-shadow: none;
}
}
