/* ── Production Roster — the studio's day-by-day resourcing grid ─────────────
 *
 * Prefix is `ros-`. `rost-` was rejected because it reads as a typo of `rest-`,
 * and `bat-` (Baton) set the precedent of a short three-letter module prefix.
 *
 * ⚠ EVERY VALUE HERE IS A DESIGN TOKEN from main.css `:root`, and each one was
 * grepped out of it before being used. A rule referencing a token nothing
 * defines fails SILENTLY — the element renders, unstyled, and looks intentional.
 */

/* ── ★ THE SPACING LANGUAGE ──────────────────────────────────────────────────
 *
 * Reported from real use, about the week navigator: "the styling and spacing
 * makes them seem unconnected... the spacing should develop a language that
 * relates the elements consistently."
 *
 * It was right, and the cause was that ONE gap did every job. Prev, the date,
 * the range and next sat the same distance apart as they did from "This week",
 * so nothing said which of them operated on which. Proximity is the only cue a
 * toolbar has, and spending it evenly spends it on nothing.
 *
 * Four steps, each meaning exactly one thing. Every gap on this screen is one
 * of them; if a new rule needs a fifth, the rule is probably wrong.
 *
 *   --ros-gap-welded    0     parts of ONE control. No gap at all — a shared
 *                             border and hairline dividers instead, because
 *                             adjacency is what says "one thing".
 *   --ros-gap-tight     4px   repeated peers in a set: pills, chips, swatches.
 *   --ros-gap-related   8px   distinct controls doing the same job, e.g. the
 *                             week segment and "This week".
 *   --ros-gap-group     16px  separate clusters on one row: the week group and
 *                             the actions group.
 *   --ros-gap-section   24px  the horizontal bands: toolbar / summary /
 *                             filters / grid.
 */
.ros-root {
    --ros-gap-welded: 0;
    --ros-gap-tight: var(--spacing-xs);
    --ros-gap-related: var(--spacing-sm);
    --ros-gap-group: var(--spacing-md);
    --ros-gap-section: var(--spacing-lg);

    display: flex;
    flex-direction: column;
    gap: var(--ros-gap-section);
    padding: var(--spacing-md);
    color: var(--text-primary);
}

/* ── toolbar: week navigation + the two write actions ───────────────────── */

.ros-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--ros-gap-group);      /* two clusters, so a GROUP gap */
}

.ros-week,
.ros-toolbar-actions {
    display: flex;
    align-items: center;
    gap: var(--ros-gap-related);    /* peers doing the same job */
}

/* ── ★ THE SEGMENTED WEEK CONTROL ────────────────────────────────────────────
 *
 * One border around prev / date / range / next, hairline dividers between, and
 * NO gap inside. That is the whole fix: the elements read as one control
 * because they are drawn as one, and "This week" reads as a separate action
 * because it sits outside at a related-gap.
 *
 * A single height token drives the segment and every sibling button, so the
 * toolbar sits on one baseline instead of four. */
.ros-segment {
    --ros-control-height: 34px;

    display: inline-flex;
    align-items: stretch;
    gap: var(--ros-gap-welded);
    height: var(--ros-control-height);
    border: 1px solid var(--border-default);
    border-radius: var(--border-radius-md);
    background: var(--bg-muted);
    overflow: hidden;
}

/* The dividers ARE the grouping. A border-left on every child but the first
 * costs one rule and cannot fall out of step with the number of children. */
.ros-segment > * + * {
    border-left: 1px solid var(--border-default);
}

.ros-seg-btn {
    display: flex;
    align-items: center;
    padding: 0 var(--spacing-sm);
    background: transparent;
    border: none;
    color: var(--text-secondary);
    font-family: inherit;
    font-size: var(--font-size-body-md);
    line-height: 1;
    cursor: pointer;
    transition: background var(--transition-fast), color var(--transition-fast);
}

.ros-seg-btn:hover {
    background: var(--interactive-hover);
    color: var(--text-primary);
}

.ros-seg-date {
    display: flex;
    align-items: center;
    padding: 0 var(--spacing-xs) 0 var(--spacing-sm);
}

.ros-seg-date input {
    background: transparent;
    border: none;
    color: var(--text-secondary);
    font-family: var(--font-family-mono);
    font-size: var(--font-size-ui-sm);
    padding: 0;
}

/* The human-readable range is the LABEL of the control, so it carries the
 * emphasis and the date input beside it reads as the way to change it. */
.ros-seg-range {
    display: flex;
    align-items: center;
    padding: 0 var(--spacing-md);
    color: var(--text-primary);
    font-weight: 600;
    font-size: var(--font-size-body-sm);
    white-space: nowrap;
    min-width: 132px;
}

.ros-toolbar .ros-btn,
.ros-toolbar .ros-search {
    height: 34px;                   /* the same token the segment uses */
}

.ros-btn {
    background: var(--bg-muted);
    color: var(--text-primary);
    border: 1px solid var(--border-default);
    border-radius: var(--border-radius-md);
    padding: 6px 12px;
    font-size: var(--font-size-ui-md);
    font-family: inherit;
    cursor: pointer;
    transition: background var(--transition-fast);
}

.ros-btn:hover {
    background: var(--interactive-hover);
}

.ros-btn--primary {
    background: var(--accent-main);
    border-color: var(--accent-main);
    color: var(--shade-white);
}

.ros-btn--danger {
    background: transparent;
    border-color: var(--accent-danger);
    color: var(--accent-danger);
}

.ros-btn--ghost {
    background: transparent;
    border-color: transparent;
    color: var(--text-secondary);
}

.ros-btn--icon {
    padding: 6px 10px;
}

.ros-date,
.ros-search {
    background: var(--bg-muted);
    color: var(--text-primary);
    border: 1px solid var(--border-default);
    border-radius: var(--border-radius-md);
    padding: 6px 10px;
    font-family: inherit;
    font-size: var(--font-size-ui-md);
}

/* ── summary bar ─────────────────────────────────────────────────────────── */

.ros-summary {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
    gap: var(--ros-gap-related);    /* peers doing the same job */
}

.ros-card {
    background: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-left: 3px solid var(--border-strong);
    border-radius: var(--border-radius-md);
    padding: var(--spacing-sm) var(--spacing-md);
}

.ros-card-num {
    font-family: var(--font-family-mono);
    font-size: var(--font-size-h4);
    line-height: var(--line-height-h4);
}

.ros-card-label {
    color: var(--text-secondary);
    font-size: var(--font-size-body-xs);
}

/* The four states, and they are the ONE colour vocabulary in this module —
 * the badge, the swatch and the card all read from these same four tokens, so
 * "over-booked" cannot be one red on a card and a different red on a badge. */
.ros-card--free   { border-left-color: var(--text-muted); }
.ros-card--under  { border-left-color: var(--accent-main); }
.ros-card--full   { border-left-color: var(--accent-confirm); }
.ros-card--over   { border-left-color: var(--accent-danger); }

/* ── filters ─────────────────────────────────────────────────────────────── */

/* Clusters (view toggle · department pills · utilization pills · free-on-day)
 * at a GROUP gap; the repeated pills inside each at a TIGHT gap. That contrast
 * is what makes four clusters read as four rather than as twelve chips. */
.ros-filters {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--ros-gap-group);
}

.ros-views {
    display: inline-flex;
    border: 1px solid var(--border-default);
    border-radius: var(--border-radius-md);
    overflow: hidden;
}

.ros-views button {
    background: transparent;
    color: var(--text-secondary);
    border: none;
    padding: 6px 14px;
    font-family: inherit;
    font-size: var(--font-size-ui-md);
    cursor: pointer;
}

.ros-views button.is-active {
    background: var(--bg-muted);
    color: var(--text-primary);
}

.ros-pills,
.ros-utils {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ros-gap-tight);      /* repeated peers in a set */
}

.ros-pill,
.ros-util {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: transparent;
    color: var(--text-secondary);
    border: 1px solid var(--border-subtle);
    border-radius: 999px;
    padding: 4px 10px;
    font-family: inherit;
    font-size: var(--font-size-ui-sm);
    cursor: pointer;
}

.ros-pill.is-active,
.ros-util.is-active {
    background: var(--bg-muted);
    color: var(--text-primary);
    border-color: var(--border-strong);
}

.ros-pill-count {
    color: var(--text-muted);
    font-family: var(--font-family-mono);
}

.ros-swatch {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    display: inline-block;
}

.ros-swatch--all    { background: var(--text-disabled); }
.ros-swatch--free   { background: var(--text-muted); }
.ros-swatch--under  { background: var(--accent-main); }
.ros-swatch--full   { background: var(--accent-confirm); }
.ros-swatch--over   { background: var(--accent-danger); }

/* ★ The combined filter, drawn as the two swatches it unions rather than as a
 * sixth colour. A new colour would imply a fifth utilization STATE, and there
 * are four — this pill selects two of them, and the swatch should say so. Split
 * at a hard stop so it reads as two halves, not as a gradient. */
.ros-swatch--free-under {
    background: linear-gradient(
        90deg,
        var(--text-muted) 0 50%,
        var(--accent-main) 50% 100%);
}

.ros-free-toggle {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--text-secondary);
    font-size: var(--font-size-ui-md);
}

.ros-free-toggle select {
    background: var(--bg-muted);
    color: var(--text-primary);
    border: 1px solid var(--border-default);
    border-radius: var(--border-radius-sm);
    padding: 3px 6px;
    font-family: inherit;
}

/* ── the grid ────────────────────────────────────────────────────────────── */

.ros-grid-wrap {
    overflow-x: auto;
    border: 1px solid var(--border-subtle);
    border-radius: var(--border-radius-md);
}

/* ★ FIXED LAYOUT, so opening a cell editor cannot resize the week.
 *
 * Reported from real use: "when clicking add the column gets wider, then when
 * leaving the form, it gets narrow again... it also doesn't seem necessary."
 * Correct on both counts. With `table-layout: auto` the browser re-measures
 * every column against its widest cell, so the <select> inside one open editor
 * reflowed the entire grid — and reflowed it BACK on close. The prototype did
 * the same; in a dense grid it reads as the page flinching.
 *
 * `table-layout: fixed` makes the first row's widths the whole answer, so the
 * editor has to fit the column rather than the column fitting the editor. The
 * widths below are what the read-only content already needed. */
.ros-grid {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
    font-size: var(--font-size-body-sm);
}

/* Every column is declared, because `table-layout: fixed` divides any leftover
 * space between columns that are not — and one undeclared column would absorb
 * all of it. */
.ros-name-col,
.ros-name-cell {
    width: 232px;
}

.ros-day,
.ros-cell {
    width: 132px;
}

.ros-util-col,
.ros-util-cell {
    width: 168px;
}

/* A fixed column clips rather than growing, so anything that could be long has
 * to say how it behaves. A project name wraps; it is the content people read. */
.ros-cell-task,
.ros-person-name,
.ros-person-meta {
    overflow-wrap: anywhere;
}

.ros-grid th {
    text-align: left;
    padding: var(--spacing-sm);
    color: var(--text-secondary);
    font-size: var(--font-size-ui-sm);
    font-weight: 600;
    background: var(--bg-surface);
    border-bottom: 1px solid var(--border-default);
    position: sticky;
    top: 0;
    z-index: 1;
}

.ros-grid td {
    padding: 6px var(--spacing-sm);
    border-bottom: 1px solid var(--border-subtle);
    vertical-align: top;
}

/* The name column stays put while the week scrolls sideways — without it the
 * rows are anonymous the moment somebody looks at Thursday. */
.ros-name-col,
.ros-name-cell {
    position: sticky;
    left: 0;
    background: var(--bg-primary);
    z-index: 2;
    min-width: 200px;
}

.ros-day-date {
    display: block;
    color: var(--text-muted);
    font-weight: 400;
}

.ros-day.is-today,
.ros-cell.is-today {
    background: var(--bg-surface);
}

/* ── ★ L5 — FOCUS ONE DAY ────────────────────────────────────────────────────
 *
 * "Today mode vs week mode — just highlights the day better when you want to
 * focus on a single day." Asked for as a UX change with no data behind it, and
 * built as exactly that: the other four days are still drawn, still editable
 * and still counted in every badge. Nothing is filtered.
 *
 * The whole effect is width plus contrast. `table-layout: fixed` takes its
 * widths from the header row, so declaring them on `.ros-day` is what actually
 * moves the column; `.ros-cell` matches so the two cannot disagree. */
.ros-day.is-focused,
.ros-cell.is-focused {
    width: 300px;
}

.ros-day.is-focused {
    color: var(--text-primary);
}

.ros-cell.is-focused {
    background: var(--bg-surface);
}

/* The focused column is edged rather than merely wider, so it reads as one
 * column singled out rather than as a table that has gone wrong. */
.ros-day.is-focused,
.ros-cell.is-focused {
    box-shadow: inset 1px 0 0 var(--accent-main), inset -1px 0 0 var(--accent-main);
}

/* ⚠ Dimmed, NOT hidden, and still at a readable contrast. The point of focusing
 * Wednesday is usually to place work on it, and what is on Tuesday and Thursday
 * is precisely what decides whether you can. A collapsed column would answer the
 * narrow question and hide the one the producer is actually asking. */
.ros-day.is-unfocused,
.ros-cell.is-unfocused {
    width: 96px;
    opacity: 0.55;
}

.ros-day-btn {
    display: block;
    width: 100%;
    background: none;
    border: none;
    padding: 0;
    text-align: left;
    font: inherit;
    color: inherit;
    cursor: pointer;
    border-radius: var(--border-radius-sm);
}

.ros-day-btn:hover {
    color: var(--text-primary);
}

.ros-divider td {
    background: var(--bg-muted);
    color: var(--text-secondary);
    font-size: var(--font-size-ui-sm);
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.ros-divider--title td {
    background: var(--bg-surface);
    text-transform: none;
    letter-spacing: 0;
    padding-left: var(--spacing-lg);
}

.ros-person {
    display: block;
    width: 100%;
    text-align: left;
    background: transparent;
    border: none;
    color: inherit;
    font-family: inherit;
    cursor: pointer;
    padding: 0;
}

.ros-person-name {
    display: block;
    color: var(--text-primary);
    font-weight: 600;
}

.ros-person-meta,
.ros-person-cap {
    display: block;
    color: var(--text-secondary);
    font-size: var(--font-size-body-xs);
}

/* The same argument vertically: a read-only booking and an open editor have to
 * occupy the same height, or the row jumps as well as the column. */
.ros-cell-row,
.ros-cell-edit {
    min-height: 34px;
}

.ros-cell-row {
    border-radius: var(--border-radius-sm);
    padding: 3px 6px;
    cursor: pointer;
}

.ros-cell-row:hover {
    background: var(--interactive-hover);
}

/* A split day's bookings stack as repeated peers of one another, so TIGHT — the
 * vocabulary's "repeated peers in a set". Anything looser and two halves of one
 * Tuesday read as two separate days. */
.ros-cell-rows {
    display: flex;
    flex-direction: column;
    gap: var(--ros-gap-tight);
}

/* Offered on every cell, but quiet on one that already has bookings: it is the
 * way to a SECOND booking, not the cell's main affordance. */
.ros-cell-add {
    color: var(--text-disabled);
    font-size: var(--font-size-body-xs);
    padding: 0 6px;
    cursor: pointer;
    border-radius: var(--border-radius-sm);
}

.ros-cell-add:hover {
    background: var(--interactive-hover);
    color: var(--text-secondary);
}

/* Shown only on a split or impossible day — on a single booking it would just
 * repeat the figure directly above it.
 *
 * ⚠ The rule sits ABOVE the total and the total sits directly under the bookings
 * it sums, so the line separates "the bookings and their total" from "+ add"
 * rather than separating the total from what it totals. */
.ros-cell-total {
    padding: 2px 6px 0;
    color: var(--text-secondary);
    font-family: var(--font-family-mono);
    font-size: var(--font-size-body-xs);
    border-top: 1px solid var(--border-subtle);
}

/* ★ A day over 24 hours. A HIGHLIGHT, deliberately not a write-time guard
 * (jmeyers, 2026-09-17): its usual cause is a producer genuinely double-booking
 * somebody across two projects without noticing, which is the thing this tool
 * exists to make visible. Refusing the write would hide it instead. */
.ros-cell-total.is-impossible {
    color: var(--text-error, #f87171);
    font-weight: 600;
}

.ros-cell-task {
    border-left: 3px solid var(--border-strong);
    padding-left: 6px;
    color: var(--text-primary);
}

.ros-cell-hours-read {
    color: var(--text-secondary);
    font-family: var(--font-family-mono);
    font-size: var(--font-size-body-xs);
    padding-left: 9px;
}

.ros-cell-empty {
    color: var(--text-disabled);
    font-size: var(--font-size-body-xs);
}

/* Grid rather than flex: the hours box is a FIXED 52px, the remove is a fixed
 * 18px, and the project picker takes what is left — so the editor is exactly as
 * wide as the column whatever the longest project name happens to be. With flex
 * the picker's intrinsic width leaked back out and pushed the column open again.
 *
 * ⚠ The third track is declared even when there is no button to put in it (a new
 * row renders a spacer), so opening an existing booking and opening a new one do
 * not lay out differently. */
.ros-cell-edit {
    display: grid;
    grid-template-columns: 1fr 52px 18px;
    gap: var(--ros-gap-tight, 4px);
    align-items: start;
}

/* Inside the open editor only. An (x) beside every booking all week would be a
 * delete one mis-click away; opening the row first is the acknowledgement. */
.ros-cell-remove {
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
    color: var(--text-muted);
    font-size: var(--font-size-body-sm);
    line-height: 1.4;
}

.ros-cell-remove:hover {
    color: var(--text-error, #f87171);
}

.ros-cell-edit select,
.ros-cell-edit input {
    background: var(--bg-muted);
    color: var(--text-primary);
    border: 1px solid var(--interactive-focus);
    border-radius: var(--border-radius-sm);
    padding: 3px 4px;
    font-family: inherit;
    font-size: var(--font-size-body-xs);
    /* ⚠ `min-width: 0` is what lets a grid item shrink below its intrinsic
     * content width. Without it a <select> refuses to go narrower than its
     * longest <option>, which is the other half of the column-widening. */
    min-width: 0;
    width: 100%;
}

.ros-badge {
    display: inline-block;
    border-radius: 999px;
    padding: 2px 8px;
    font-size: var(--font-size-ui-xs);
    white-space: nowrap;
}

.ros-badge--free   { background: var(--bg-muted); color: var(--text-muted); }
.ros-badge--under  { background: var(--bg-muted); color: var(--accent-main); }
.ros-badge--full   { background: var(--bg-muted); color: var(--accent-confirm); }
.ros-badge--over   { background: var(--bg-muted); color: var(--accent-danger); }

.ros-util-pct {
    display: block;
    color: var(--text-muted);
    font-family: var(--font-family-mono);
    font-size: var(--font-size-ui-xs);
}

/* ── by-project view ─────────────────────────────────────────────────────── */

.ros-project-card {
    background: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--border-radius-md);
    margin-bottom: var(--spacing-sm);
    overflow: hidden;
}

.ros-project-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: var(--spacing-sm) var(--spacing-md);
    border-bottom: 1px solid var(--border-subtle);
}

.ros-project-name {
    border-left: 3px solid var(--accent-main);
    padding-left: var(--spacing-sm);
    font-weight: 600;
}

.ros-project-meta {
    color: var(--text-secondary);
    font-size: var(--font-size-body-xs);
}

.ros-project-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--font-size-body-sm);
}

.ros-project-table th {
    text-align: left;
    padding: 4px var(--spacing-md);
    color: var(--text-muted);
    font-size: var(--font-size-ui-xs);
    font-weight: 600;
}

.ros-project-table td {
    padding: 4px var(--spacing-md);
    border-top: 1px solid var(--border-subtle);
}

.ros-project-hrs,
.ros-project-total {
    font-family: var(--font-family-mono);
    text-align: center;
}

.ros-project-hrs.is-blank {
    color: var(--text-disabled);
}

.ros-unassigned {
    background: var(--bg-surface);
    border: 1px dashed var(--border-default);
    border-radius: var(--border-radius-md);
    padding: var(--spacing-sm) var(--spacing-md);
}

.ros-unassigned-head {
    color: var(--text-secondary);
    font-size: var(--font-size-body-xs);
    margin-bottom: var(--spacing-xs);
}

.ros-unassigned-names {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-xs);
}

.ros-unassigned-names span {
    background: var(--bg-muted);
    border-radius: var(--border-radius-sm);
    padding: 2px 8px;
    font-size: var(--font-size-body-xs);
}

/* ── modals ──────────────────────────────────────────────────────────────── */

.ros-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.6);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1000;
}

.ros-modal {
    background: var(--bg-elevated);
    border: 1px solid var(--border-default);
    border-radius: var(--border-radius-lg);
    box-shadow: var(--shadow-lg);
    padding: var(--spacing-lg);
    width: 420px;
    max-width: 92vw;
    max-height: 88vh;
    overflow-y: auto;
}

.ros-modal--wide {
    width: 620px;
}

.ros-modal h3 {
    margin: 0 0 var(--spacing-md);
    font-size: var(--font-size-h5);
}

.ros-modal label {
    display: block;
    margin-top: var(--spacing-sm);
    color: var(--text-secondary);
    font-size: var(--font-size-ui-sm);
}

.ros-modal input[type="text"],
.ros-modal input[type="number"],
.ros-modal input[type="date"],
.ros-modal input[type="search"],
.ros-modal select {
    width: 100%;
    background: var(--bg-muted);
    color: var(--text-primary);
    border: 1px solid var(--border-default);
    border-radius: var(--border-radius-md);
    padding: 7px 9px;
    font-family: inherit;
    font-size: var(--font-size-body-sm);
}

.ros-checkbox {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: var(--spacing-sm);
}

.ros-modal-actions {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--spacing-sm);
    margin-top: var(--spacing-lg);
}

.ros-modal-actions-right {
    display: flex;
    gap: var(--ros-gap-related, var(--spacing-sm));
}

/* ── quick-create: department / title / project, without leaving what you were
 * doing. It STACKS above whatever opened it, so the person form stays visible
 * behind it and the context is not lost. */
.ros-modal--narrow {
    width: 360px;
}

.ros-backdrop--stacked {
    /* One above the modal that opened it; the dimming compounds, which is what
     * says which layer is live. */
    z-index: 1001;
    background: rgba(0, 0, 0, 0.45);
}

.ros-qc-hint {
    margin: 0 0 var(--spacing-sm);
    color: var(--text-secondary);
    font-size: var(--font-size-body-xs);
    line-height: 1.5;
}

.ros-qc-colour {
    display: flex;
    align-items: center;
    gap: var(--spacing-sm);
}

.ros-qc-colour input[type="color"] {
    width: 40px;
    min-width: 40px;
    height: 34px;
    padding: 2px;
    background: var(--bg-muted);
    border: 1px solid var(--border-default);
    border-radius: var(--border-radius-md);
    cursor: pointer;
}

.ros-btn:disabled {
    opacity: 0.6;
    cursor: default;
}

.ros-modal-error {
    margin-top: var(--spacing-sm);
    color: var(--accent-danger);
    font-size: var(--font-size-body-xs);
}

.ros-bulk-span {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: var(--spacing-sm);
}

.ros-bulk-tools {
    display: flex;
    align-items: center;
    gap: var(--spacing-sm);
    margin-top: var(--spacing-xs);
}

.ros-link {
    background: none;
    border: none;
    color: var(--accent-main);
    font-family: inherit;
    font-size: var(--font-size-ui-sm);
    cursor: pointer;
    padding: 0;
}

.ros-bulk-count {
    margin-left: auto;
    color: var(--text-muted);
    font-size: var(--font-size-ui-sm);
}

.ros-bulk-list {
    max-height: 200px;
    overflow-y: auto;
    border: 1px solid var(--border-subtle);
    border-radius: var(--border-radius-md);
    margin-top: var(--spacing-xs);
}

.ros-bulk-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 5px var(--spacing-sm);
    margin: 0;
    font-size: var(--font-size-body-sm);
}

/* ★ THE CONFLICT REPORT — §10 D2's recommendation made visible. It is the one
 * block in this module that has to read as a warning rather than as furniture,
 * because the button beside it destroys somebody else's week. */
.ros-conflicts {
    margin-top: var(--spacing-md);
    border: 1px solid var(--accent-caution);
    border-radius: var(--border-radius-md);
    padding: var(--spacing-sm) var(--spacing-md);
    background: var(--bg-muted);
}

.ros-conflicts-head {
    color: var(--accent-caution);
    font-weight: 600;
    font-size: var(--font-size-body-sm);
}

.ros-conflicts ul {
    margin: var(--spacing-xs) 0 0;
    padding-left: var(--spacing-md);
    max-height: 160px;
    overflow-y: auto;
    font-size: var(--font-size-body-xs);
    color: var(--text-secondary);
}

.ros-conflicts-more {
    color: var(--text-muted);
    font-size: var(--font-size-body-xs);
}

/* ── shared ──────────────────────────────────────────────────────────────── */

.ros-empty {
    padding: var(--spacing-xl);
    text-align: center;
    color: var(--text-muted);
    font-size: var(--font-size-body-sm);
}

.ros-note {
    color: var(--text-muted);
    font-size: var(--font-size-body-xs);
    line-height: 1.5;
}

/* ── Presence (§7, lane C) ───────────────────────────────────────────────────
 *
 * Two marks, answering two different questions:
 *
 *   .ros-presence        the header zone — "is anybody else in the roster at all?"
 *   .ros-peer-editing    a booking marker — "is somebody in THIS booking?"
 *
 * ★ The peer's colour arrives as a custom property set by the surgical paint
 * (rosterPresence.paintPresence), never as an inline background, so a marker can
 * be restyled here without the JS knowing anything about how it looks. The colour
 * itself is derived from the peer's clientId, so it is stable within a session and
 * the same on every screen. */

.ros-presence-host {
    display: flex;
    align-items: center;
}

/* ⚠ An EMPTY host still consumes one of `.ros-toolbar-actions`'s flex gaps, so a roster where
 * presence never started — no Group, a node test, an unreachable hub — would carry a permanent
 * phantom space before the search box that nothing explains. It costs one toolbar reflow when
 * presence does come up, which is a one-time shift at mount rather than a standing defect. */
.ros-presence-host:empty {
    display: none;
}

.ros-presence {
    display: flex;
    align-items: center;
    gap: var(--ros-gap-tight);      /* repeated peers in a set */
}

.ros-avatar {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: var(--font-size-ui-xs);
    font-weight: 600;
    color: #fff;
    /* The ring separates overlapping chips from the toolbar behind them, and it is
     * the PAGE's ground rather than a fixed white so it holds in both themes. */
    box-shadow: 0 0 0 2px var(--bg-primary);
    user-select: none;
}

/* "You" reads as a peer of the others, not as a different kind of thing — but it
 * is hollow, because a filled chip for yourself competes with the people the zone
 * exists to tell you about. */
.ros-avatar--self {
    background: transparent !important;
    color: var(--text-secondary);
    box-shadow: inset 0 0 0 1px var(--border-strong), 0 0 0 2px var(--bg-primary);
}

.ros-avatar--more {
    background: var(--bg-muted) !important;
    color: var(--text-secondary);
}

.ros-presence-label {
    font-size: var(--font-size-body-xs);
    color: var(--text-disabled);
    white-space: nowrap;
}

/* ★ THE BOOKING MARKER: a tint plus an INSET outline, both in the peer's own colour.
 *
 * ⚠ NOT A LEFT BAR, and the screenshot gate is what caught it. `.ros-cell-task`
 * already carries a left border in the PROJECT's colour, which is load-bearing — it
 * is how a producer reads which project a booking is on at a glance. A second
 * coloured bar immediately beside it puts two different meanings in the same visual
 * idiom, one cell apart, and the reader has to learn which is which. The tint says
 * "occupied" without competing for that idiom at all.
 *
 * ⚠ `outline` with a NEGATIVE offset, not `border`: an outline is painted outside
 * the box model, so it costs no layout, and pulling it inward keeps it inside the
 * cell rather than bleeding over the column divider. A border would shift the row by
 * a pixel and make the whole week twitch every time somebody opened a cell.
 *
 * ⚠ Deliberately quiet. This fires while a colleague is mid-edit, which on a busy
 * week is often — and a marker loud enough to be read as an error is one people
 * learn to ignore. It has to be noticeable when looked at, not attention-grabbing. */
.ros-cell-row.ros-peer-editing,
.ros-cell-add.ros-peer-editing,
.ros-cell-empty.ros-peer-editing,
.ros-cell-edit.ros-peer-editing {
    background: color-mix(in srgb, var(--ros-peer-colour, var(--accent-main)) 14%, transparent);
    outline: 1px solid color-mix(in srgb, var(--ros-peer-colour, var(--accent-main)) 55%, transparent);
    outline-offset: -1px;
    border-radius: var(--border-radius-sm);
    cursor: pointer;
}

/* The one place it gets louder: YOU are in the booking a peer is also in. That is the
 * collision the whole feature exists for, so it earns a solid outline at full colour. */
.ros-cell-edit.ros-peer-editing {
    outline: 1px solid var(--ros-peer-colour, var(--accent-main));
}

/* A hover on a marked row must not wash the tint out — the marker outranks the
 * hover, because "somebody is in here" matters more than "your pointer is here". */
.ros-cell-row.ros-peer-editing:hover {
    background: color-mix(in srgb, var(--ros-peer-colour, var(--accent-main)) 22%, transparent);
}
