/*
 * Project shell: the /projects/details layout (header, rooms rail, KPI tiles, Room breakdown panel).
 * Spec: docs/superpowers/specs/2026-10-11-project-details-revised-layout-design.md, section 4.4.
 *
 * App.razor links this file on every page, so it must stay inert everywhere else:
 *  - every selector starts with .project-details-page, inside @media and @container too. The prefix also
 *    lets these rules outrank the page's compact typography rules in themes/theme-base.css;
 *  - no literal hex colour and no !important. Colours come from the --app-* and --eq-* theme tokens;
 *  - every class this file introduces carries the ps- prefix, because the Cobalt collision test scans the
 *    global stylesheets for the class names the /ai-consulting page uses.
 * ProjectShellCssGuardTests enforces the first two rules.
 *
 * Density: this page uses the relaxed register by owner decision D2 (2026-10-11): 8px radius, 16px padding,
 * a 22px/600 title. It is a deliberate exception to the design system's dense rules.
 */

.project-details-page {
    --ps-radius: 8px;
    --ps-pad: 16px;
}

/* ---------- Header (Surface B) ---------- */

/* z-index 12 lets the Actions menu (Bootstrap, 1000) and the version menu paint over the lock badge (10)
   and its popover (11), and still sit under the AVIP column (1058). */
.project-details-page .ps-header {
    position: relative;
    z-index: 12;
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: var(--ps-pad);
    padding: var(--ps-pad) 0;
}

.project-details-page .ps-header-main {
    flex: 1 1 auto;
    min-width: 0;
}

.project-details-page .ps-breadcrumb {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    line-height: 1.4;
    color: var(--app-text-label);
}

.project-details-page .ps-breadcrumb a {
    color: var(--app-accent-border);
    text-decoration: none;
}

.project-details-page .ps-breadcrumb a:hover {
    text-decoration: underline;
}

.project-details-page .ps-title-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px 12px;
    margin: 4px 0;
}

.project-details-page .ps-title {
    margin: 0;
    min-width: 0;
    font-size: 22px;
    font-weight: 600;
    line-height: 1.25;
    color: var(--app-text-strong);
    overflow-wrap: anywhere;
}

.project-details-page .ps-meta {
    font-size: 12px;
    line-height: 1.4;
    color: var(--app-text-label);
}

/* ---------- Pills: project status, and the version picker's trigger ---------- */

/* VersionsPicker's scoped .picker-trigger rule has the same specificity; this file loads after
   BlazorApp1.styles.css, so the override wins on order. */
.project-details-page .ps-status-pill,
.project-details-page .picker-trigger {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 26px;
    padding: 0 10px;
    font-size: 12px;
    font-weight: 500;
    line-height: 1;
    white-space: nowrap;
    border: 1px solid var(--app-border-color);
    border-radius: 999px;
    background: transparent;
    cursor: pointer;
    transition: background-color var(--app-transition-fast), border-color var(--app-transition-fast);
}

.project-details-page .ps-status-pill:focus-visible,
.project-details-page .picker-trigger:focus-visible {
    outline: 2px solid var(--app-accent-border);
    outline-offset: 2px;
}

.project-details-page .ps-status-pill i {
    font-size: 11px;
}

.project-details-page .ps-status-pill:hover {
    border-color: currentColor;
}

.project-details-page .ps-status-pill--progress {
    color: var(--app-accent-border);
    border-color: var(--app-accent-border);
    background: var(--app-accent-tint);
}

.project-details-page .ps-status-pill--revision {
    color: var(--app-status-warn);
    border-color: color-mix(in srgb, var(--app-status-warn) 50%, transparent);
    background: color-mix(in srgb, var(--app-status-warn) 10%, transparent);
}

.project-details-page .ps-status-pill--complete {
    color: var(--app-status-ok);
    border-color: color-mix(in srgb, var(--app-status-ok) 50%, transparent);
    background: color-mix(in srgb, var(--app-status-ok) 10%, transparent);
}

.project-details-page .ps-status-pill--default {
    color: var(--app-text-label);
    border-color: var(--app-border-color);
}

.project-details-page .picker-trigger {
    color: var(--app-text-strong);
    border-color: var(--app-accent-border);
    background: var(--app-accent-tint);
}

/* Also replaces the scoped hover, whose fallback paints a pale light-mode fill on the dark theme. */
.project-details-page .ps-status-pill--progress:hover,
.project-details-page .picker-trigger:hover {
    background: color-mix(in srgb, var(--app-accent-border) 18%, transparent);
}

.project-details-page .picker-trigger .row-current-mark {
    width: auto;
    font-size: 10px;
    color: var(--app-accent-border);
}

.project-details-page .picker-trigger .picker-chev {
    font-size: 9px;
    color: var(--app-text-label);
}

/* ---------- Header actions: timer chip, reset, Ask AVIP, Actions ---------- */

.project-details-page .ps-header-actions {
    flex: none;
    display: flex;
    align-items: center;
    gap: 8px;
}

.project-details-page .ps-timer-chip,
.project-details-page .ps-ask-avip {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    height: 36px;
    padding: 0 14px;
    font-size: 13px;
    line-height: 1;
    white-space: nowrap;
    border: 1px solid var(--app-border-color);
    border-radius: var(--ps-radius);
    background: var(--app-surface-panel);
    cursor: pointer;
    transition: background-color var(--app-transition-fast), border-color var(--app-transition-fast);
}

.project-details-page .ps-timer-chip {
    font-family: var(--bs-font-monospace);
    font-variant-numeric: tabular-nums;
    color: var(--app-text-data);
}

.project-details-page .ps-timer-glyph {
    font-size: 10px;
}

.project-details-page .ps-ask-avip {
    font-weight: 600;
    color: var(--app-text-strong);
}

.project-details-page .ps-timer-chip:hover,
.project-details-page .ps-ask-avip:hover {
    background: var(--app-surface-hover);
}

.project-details-page .ps-ask-avip.active {
    border-color: var(--app-accent-border);
    background: var(--app-accent-tint);
}

.project-details-page .ps-timer-reset {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    padding: 0;
    font-size: 11px;
    color: var(--app-text-label);
    border: 1px solid var(--app-border-color);
    border-radius: var(--ps-radius);
    background: transparent;
    cursor: pointer;
}

.project-details-page .ps-timer-reset:hover {
    color: var(--app-text-strong);
    background: var(--app-surface-hover);
}

.project-details-page .ps-timer-chip:focus-visible,
.project-details-page .ps-ask-avip:focus-visible,
.project-details-page .ps-timer-reset:focus-visible {
    outline: 2px solid var(--app-accent-border);
    outline-offset: 2px;
}

/* The header's one solid control. --bs-white is Bootstrap 5.1's root white: the app has no --app-* token
   that stays white in both themes, and the label sits on the same blue fill in both. */
.project-details-page .ps-actions-btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    height: 36px;
    padding: 0 16px;
    font-size: 13px;
    font-weight: 600;
    line-height: 1;
    color: var(--bs-white);
    border: 1px solid var(--app-brand-primary);
    border-radius: var(--ps-radius);
    background: var(--app-brand-primary);
}

.project-details-page .ps-actions-btn:hover,
.project-details-page .ps-actions-btn[aria-expanded="true"] {
    color: var(--bs-white);
    background: color-mix(in srgb, var(--app-brand-primary) 85%, var(--bs-white));
}

/* Bootstrap's .btn:focus ring would stay on after a mouse click; the keyboard ring below replaces it. */
.project-details-page .ps-actions-btn:focus {
    box-shadow: none;
}

.project-details-page .ps-actions-btn:focus-visible {
    color: var(--bs-white);
    outline: 2px solid var(--app-accent-border);
    outline-offset: 2px;
}

.project-details-page .ps-actions-btn i {
    font-size: 10px;
    transition: transform var(--app-transition-fast);
}

.project-details-page .ps-actions-btn[aria-expanded="true"] i {
    transform: rotate(180deg);
}

/* ---------- Shell frame and grid ---------- */

/* The query container for the horizontal rail mode. It wraps the outer LockedOverlay, so the grid and the lock
   badge are its descendants (a container query restyles only descendants), while the header stays outside it.
   Spec section 6 item 3: Safari must not clip a position: fixed descendant of an inline-size container. Where it
   does, the @container block below becomes viewport media queries keyed on main.main-full and this declaration
   goes. */
.project-details-page .ps-shell-frame {
    container-type: inline-size;
    container-name: ps-shell;
}

/* Rail | room panel. align-items: start keeps the rail at its own height instead of stretching to the panel's. */
.project-details-page .ps-shell-body {
    display: grid;
    grid-template-columns: 330px minmax(0, 1fr);
    gap: var(--ps-pad);
    align-items: start;
}

.project-details-page .ps-room-panel {
    min-width: 0;
}

/* ---------- Rooms rail (Surface C) ---------- */

.project-details-page .ps-rail {
    background: var(--app-surface-panel);
    border: 1px solid var(--app-border-hairline);
    border-radius: var(--ps-radius);
    padding: 12px;
}

/* "Rooms" and the count on one baseline, then "+ Room" pushed right. The negative inline margin runs the
   hairline to the rail's edges, as the mockup draws it. */
.project-details-page .ps-rail-head {
    display: flex;
    align-items: baseline;
    gap: 6px;
    margin: 0 -12px 8px;
    padding: 0 12px 12px;
    border-bottom: 1px solid var(--app-border-hairline);
    font-size: 14px;
    font-weight: 600;
    line-height: 1.3;
    color: var(--app-text-strong);
}

.project-details-page .ps-rail-head > span + span {
    font-size: 12px;
    font-weight: 400;
    color: var(--app-text-label);
}

.project-details-page .ps-rail-add {
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    height: 28px;
    padding: 0 10px;
    font-size: 13px;
    font-weight: 500;
    line-height: 1;
    white-space: nowrap;
    color: var(--app-text-strong);
    border: 1px solid var(--app-border-color);
    border-radius: 6px;
    background: transparent;
    cursor: pointer;
    transition: background-color var(--app-transition-fast);
}

.project-details-page .ps-rail-add:hover:not(:disabled) {
    background: var(--app-surface-hover);
}

.project-details-page .ps-rail-add:disabled {
    color: var(--app-text-disabled);
    cursor: not-allowed;
}

/* A room row: the name (two lines at most) and its total on the first line, "n items" under the name. */
.project-details-page .ps-rail-row {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 2px 12px;
    padding: 10px 12px;
    margin-bottom: 4px;
    border-radius: 6px;
    cursor: pointer;
    transition: background-color var(--app-transition-fast);
}

.project-details-page .ps-rail-row:hover {
    background: var(--app-surface-hover);
}

/* The open room: the raised slab with the accent outline. Listed with :hover so hovering keeps the slab. */
.project-details-page .ps-rail-row--active,
.project-details-page .ps-rail-row--active:hover {
    background: var(--app-surface-raised);
    box-shadow: inset 0 0 0 1px var(--app-accent-border);
}

.project-details-page .ps-rail-row:focus-visible,
.project-details-page .ps-rail-archived-toggle:focus-visible,
.project-details-page .ps-rail-add:focus-visible {
    outline: 2px solid var(--app-accent-border);
    outline-offset: 2px;
}

.project-details-page .ps-rail-name {
    min-width: 0;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
    overflow-wrap: anywhere;
    font-size: 13px;
    font-weight: 500;
    line-height: 1.35;
    color: var(--app-text-strong);
}

.project-details-page .ps-rail-row--active .ps-rail-name {
    font-weight: 600;
}

.project-details-page .ps-rail-optional {
    font-size: 12px;
    font-weight: 400;
    color: var(--app-text-label);
}

.project-details-page .ps-rail-total {
    font-size: 13px;
    font-weight: 600;
    line-height: 1.35;
    text-align: right;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
    color: var(--app-text-strong);
}

.project-details-page .ps-rail-count {
    font-size: 12px;
    line-height: 1.35;
    color: var(--app-text-label);
}

/* A room with unpriced lines: "n unpriced" in the warning ink, right of "n items" under the total. */
.project-details-page .ps-rail-attn {
    grid-column: 2;
    grid-row: 2;
    justify-self: end;
    font-size: 12px;
    line-height: 1.35;
    color: var(--app-status-warn);
    white-space: nowrap;
}

/* A room with units not drawn: "n not drawn" in the warning ink, right-aligned under the total in row 2, or in row 3
   under "n unpriced" (--below). A fixed row keeps it beside the item count: auto placement would put it after a
   full-width "in lieu of" or "link broken" line. */
.project-details-page .ps-rail-drawn {
    grid-column: 2;
    grid-row: 2;
    justify-self: end;
    font-size: 12px;
    line-height: 1.35;
    color: var(--app-status-warn);
    white-space: nowrap;
}

.project-details-page .ps-rail-drawn--below {
    grid-row: 3;
}

/* A linked optional room's sub-line under the row: "in lieu of {Base}", or "link broken" in the warning ink when
   its link does not resolve. Full width, so a long base name never squeezes the total. */
.project-details-page .ps-rail-lieu {
    grid-column: 1 / -1;
    font-size: 12px;
    color: var(--app-text-label);
}

.project-details-page .ps-rail-lieu--warn {
    color: var(--app-status-warn);
}

/* Archived rooms: the whole row reads in the disabled ink. */
.project-details-page .ps-rail-row--muted :is(.ps-rail-name, .ps-rail-optional, .ps-rail-total, .ps-rail-count) {
    color: var(--app-text-disabled);
}

/* A separate rule, not a fifth entry in the list above: :is() takes its most specific argument, so adding this
   selector there would raise the specificity of every listed element. The warning keeps its ink on archived rows. */
.project-details-page .ps-rail-row--muted .ps-rail-lieu:not(.ps-rail-lieu--warn) {
    color: var(--app-text-disabled);
}

.project-details-page .ps-rail-archived {
    margin-top: 8px;
}

.project-details-page .ps-rail-archived-toggle {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 6px 12px;
    margin-bottom: 4px;
    font-size: 12px;
    color: var(--app-text-label);
    border-radius: 6px;
    cursor: pointer;
    transition: background-color var(--app-transition-fast);
}

.project-details-page .ps-rail-archived-toggle:hover {
    background: var(--app-surface-hover);
}

.project-details-page .ps-rail-archived-toggle i {
    font-size: 9px;
    transition: transform var(--app-transition-fast);
}

.project-details-page .ps-rail-archived-toggle[aria-expanded="true"] i {
    transform: rotate(90deg);
}

.project-details-page .ps-rail-empty {
    padding: 16px 12px;
    font-size: 13px;
    text-align: center;
    color: var(--app-text-label);
}

/* Project total, then the quieter optional line; label left, figure right on each. The hairline runs to the
   rail's edges like the head's. */
.project-details-page .ps-rail-footer {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin: 8px -12px 0;
    padding: 12px 12px 0;
    border-top: 1px solid var(--app-border-hairline);
}

.project-details-page .ps-rail-footer-total,
.project-details-page .ps-rail-footer-optional {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 12px;
    font-size: 12px;
    color: var(--app-text-label);
}

.project-details-page .ps-rail-footer-total > span + span {
    font-size: 14px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--app-text-strong);
}

.project-details-page .ps-rail-footer-optional > span + span {
    font-variant-numeric: tabular-nums;
}

/* ---------- Lock badge and popover over the rail head ---------- */

/* The outer LockedOverlay paints its badge and popover top-right of its wrapper (LockedOverlay.razor.css:46-56,
   :70-78), which is now the room panel's toolbar. Two columns: both sit over the right end of the rail head,
   where "+ Room" is disabled on a locked version. The popover keeps its default 38px drop below the badge.
   Both grow leftwards from that anchor, and .project-details-page clips what passes the rail's left edge (it is
   overflow-auto), so both are capped at the rail's width less 16px each side. The badge label ellipsizes and
   stays on one line, so the popover below it never overlaps it; the popover repeats the approval date in full.
   The popover's values wrap, an approver id with no spaces included (LockedOverlay.razor:24). */
.project-details-page .ps-shell-frame > .locked-overlay-wrapper > .locked-overlay-badge {
    top: 10px;
    left: calc(330px - 16px);
    right: auto;
    transform: translateX(-100%);
    max-width: calc(330px - 32px);
}

.project-details-page .ps-shell-frame > .locked-overlay-wrapper > .locked-overlay-badge > .badge-label {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

.project-details-page .ps-shell-frame > .locked-overlay-wrapper > .locked-overlay-popover {
    top: 48px;
    left: calc(330px - 16px);
    right: auto;
    transform: translateX(-100%);
    max-width: calc(330px - 32px);
}

/* Only the values break anywhere; the row labels ("Approver:") keep their width and never split. */
.project-details-page .ps-shell-frame > .locked-overlay-wrapper > .locked-overlay-popover .val {
    overflow-wrap: anywhere;
}

/* ---------- KPI tiles (Surface D) ---------- */

/* Four equal columns whatever the tile count: when nothing needs attention the fourth slot stays empty. */
.project-details-page .ps-kpi {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--ps-pad);
}

.project-details-page .ps-tile {
    min-width: 0;
    background: var(--app-surface-panel);
    border: 1px solid var(--app-border-hairline);
    border-radius: var(--ps-radius);
    padding: var(--ps-pad);
}

.project-details-page .ps-tile-label {
    font-size: 12px;
    line-height: 1.4;
    color: var(--app-text-label);
}

/* A figure too wide for a narrow tile wraps inside it rather than painting over the next tile. */
.project-details-page .ps-tile-value {
    margin-top: 4px;
    font-size: 24px;
    font-weight: 700;
    line-height: 1.25;
    font-variant-numeric: tabular-nums;
    color: var(--app-text-strong);
    overflow-wrap: anywhere;
}

/* "× n rooms = $…" under the Sell figure. */
.project-details-page .ps-tile-sub {
    margin-top: 4px;
    font-size: 12px;
    line-height: 1.4;
    font-variant-numeric: tabular-nums;
    color: var(--app-text-label);
}

/* "Room, before tax" under each figure: says what the tile adds up, since the table footer's Equipment total is a
   smaller number. Same register as .ps-tile-sub. */
.project-details-page .ps-tile-note {
    margin-top: 4px;
    font-size: 12px;
    line-height: 1.4;
    color: var(--app-text-label);
}

.project-details-page .ps-margin {
    font-size: 14px;
    font-weight: 600;
    color: var(--app-status-ok);
}

/* A loss: the dollars and the percent both read in the danger colour. Listed after .ps-tile-value and .ps-margin,
   whose specificity it shares, so it wins on order. */
.project-details-page .ps-margin--negative {
    color: var(--app-danger);
}

/* The attention tile: amber outline and tint, and the amber label and count the mockup draws. */
.project-details-page .ps-tile--attention {
    border-color: var(--app-status-warn);
    background: color-mix(in srgb, var(--app-status-warn) 12%, var(--app-surface-panel));
}

.project-details-page .ps-tile--attention .ps-tile-label {
    color: var(--app-status-warn);
}

.project-details-page .ps-tile--attention .ps-tile-value {
    font-size: 16px;
    font-weight: 600;
    color: var(--app-status-warn);
}

/* One attention line: its count and its Find button. A second line (units not drawn under items unpriced) sits a
   little below the first. */
.project-details-page .ps-tile-line + .ps-tile-line {
    margin-top: 8px;
}

/* "Find price" and the not-drawn line's "Find": buttons styled as links. */
.project-details-page .ps-find-price,
.project-details-page .ps-find-not-drawn {
    margin-top: 4px;
    padding: 0;
    font-size: 13px;
    font-weight: 500;
    line-height: 1.4;
    color: var(--app-status-warn);
    text-decoration: underline;
    text-underline-offset: 2px;
    border: 0;
    background: none;
    cursor: pointer;
}

.project-details-page .ps-find-price:hover:not(:disabled),
.project-details-page .ps-find-not-drawn:hover:not(:disabled) {
    text-decoration-thickness: 2px;
}

.project-details-page .ps-find-price:focus-visible,
.project-details-page .ps-find-not-drawn:focus-visible {
    outline: 2px solid var(--app-accent-border);
    outline-offset: 2px;
}

.project-details-page .ps-find-price:disabled,
.project-details-page .ps-find-not-drawn:disabled {
    color: var(--app-text-disabled);
    text-decoration: none;
    cursor: not-allowed;
}

/* The strip's place in the room card: first in the room's body, between the toolbar and the table, inset from the
   card's edges like the mockup's tile row. */
.project-details-page .ps-room-panel .ps-kpi {
    padding: var(--ps-pad);
}

/* ---------- Room toolbar (Surface D) ---------- */

/* "+ Add product": the room panel's one solid control. The fill is the theme's .btn-primary; this rule lifts the
   label above the page's compact 400 weight and keeps it on one line when the actions group wraps. */
.project-details-page .ps-add-product {
    font-weight: 600;
    white-space: nowrap;
}

/* The "⋯" overflow trigger: as tall as its .btn-sm neighbours, never narrower than it is tall, and bold enough
   for the three dots to read at the compact size. */
.project-details-page .ps-room-more {
    min-width: 28px;
    font-weight: 700;
}

/* ---------- Room breakdown (Surface F) ---------- */

/* The Room Summary, Install Summary and the two financial summary cards, folded behind one toggle. Collapsed, the
   panel is the toggle row alone. The root also carries .room-summary-section, which the page's fullscreen rule
   hides. */
.project-details-page .ps-breakdown {
    margin-top: 8px;
}

/* Open, the four cards follow the toggle; the bottom padding keeps the last one off the room card's edge. */
.project-details-page .ps-breakdown--open {
    padding-bottom: 8px;
}

/* A div with role="button", not a button: the lock overlay disables buttons, and the cards stay readable on a
   locked version. projectShell.js stops Space from scrolling the page when this element has focus. */
.project-details-page .ps-breakdown-toggle {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px;
    border-top: 1px solid var(--app-border-hairline);
    font-size: 13px;
    font-weight: 600;
    line-height: 1.3;
    color: var(--app-text-strong);
    cursor: pointer;
    user-select: none;
    transition: background-color var(--app-transition-fast);
}

.project-details-page .ps-breakdown-toggle:hover {
    background: var(--app-surface-hover);
}

/* Inset, because the toggle spans the card's full width and the card would clip an outer ring. */
.project-details-page .ps-breakdown-toggle:focus-visible {
    outline: 2px solid var(--app-accent-border);
    outline-offset: -2px;
}

.project-details-page .ps-breakdown-toggle i {
    font-size: 10px;
    color: var(--app-text-label);
    transition: transform var(--app-transition-fast);
}

.project-details-page .ps-breakdown-toggle[aria-expanded="true"] i {
    transform: rotate(90deg);
}

/* ---------- Horizontal rail mode ---------- */

/* One stacked column with the rail's rows as wrapping chips (outlined; the open room keeps its accent slab),
   whenever the shell is under 1100px wide or the AVIP panel is open. CSS cannot share one block between a container query and a class, so the block is written
   twice; keep the two copies identical. The badge and popover return to their defaults (top 12px / 50px,
   right 16px, from LockedOverlay.razor.css) and drop the two-column width cap. */
@container ps-shell (max-width: 1099.98px) {
    .project-details-page .ps-shell-body {
        grid-template-columns: 1fr;
    }

    .project-details-page .ps-rail-list,
    .project-details-page .ps-rail-archived {
        display: flex;
        flex-wrap: wrap;
        gap: 6px;
    }

    .project-details-page .ps-rail-archived-toggle {
        flex-basis: 100%;
        margin-bottom: 0;
    }

    .project-details-page .ps-rail-row {
        grid-template-columns: auto auto;
        padding: 6px 10px;
        margin-bottom: 0;
        max-width: 100%;
    }

    .project-details-page .ps-rail-row:not(.ps-rail-row--active) {
        box-shadow: inset 0 0 0 1px var(--app-border-hairline);
    }

    .project-details-page .ps-rail-count {
        display: none;
    }

    /* A chip hides "in lieu of" with the count; "link broken" stays as the chip's second line. */
    .project-details-page .ps-rail-lieu:not(.ps-rail-lieu--warn) {
        display: none;
    }

    /* "n unpriced" spans the chip under the name and total, after "link broken" when both show. */
    .project-details-page .ps-rail-attn {
        grid-column: 1 / -1;
        grid-row: auto;
        justify-self: start;
    }

    /* "n not drawn" spans the chip too, after "n unpriced" when both show. */
    .project-details-page .ps-rail-drawn {
        grid-column: 1 / -1;
        grid-row: auto;
        justify-self: start;
    }

    .project-details-page .ps-shell-frame > .locked-overlay-wrapper > .locked-overlay-badge {
        top: 12px;
        left: auto;
        right: 16px;
        transform: none;
        max-width: none;
    }

    .project-details-page .ps-shell-frame > .locked-overlay-wrapper > .locked-overlay-popover {
        top: 50px;
        left: auto;
        right: 16px;
        transform: none;
        max-width: none;
    }
}

.project-details-page .ps-shell.ps-assistant-open .ps-shell-body {
    grid-template-columns: 1fr;
}

.project-details-page .ps-shell.ps-assistant-open .ps-rail-list,
.project-details-page .ps-shell.ps-assistant-open .ps-rail-archived {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.project-details-page .ps-shell.ps-assistant-open .ps-rail-archived-toggle {
    flex-basis: 100%;
    margin-bottom: 0;
}

.project-details-page .ps-shell.ps-assistant-open .ps-rail-row {
    grid-template-columns: auto auto;
    padding: 6px 10px;
    margin-bottom: 0;
    max-width: 100%;
}

.project-details-page .ps-shell.ps-assistant-open .ps-rail-row:not(.ps-rail-row--active) {
    box-shadow: inset 0 0 0 1px var(--app-border-hairline);
}

.project-details-page .ps-shell.ps-assistant-open .ps-rail-count {
    display: none;
}

/* A chip hides "in lieu of" with the count; "link broken" stays as the chip's second line. */
.project-details-page .ps-shell.ps-assistant-open .ps-rail-lieu:not(.ps-rail-lieu--warn) {
    display: none;
}

/* "n unpriced" spans the chip under the name and total, after "link broken" when both show. */
.project-details-page .ps-shell.ps-assistant-open .ps-rail-attn {
    grid-column: 1 / -1;
    grid-row: auto;
    justify-self: start;
}

/* "n not drawn" spans the chip too, after "n unpriced" when both show. */
.project-details-page .ps-shell.ps-assistant-open .ps-rail-drawn {
    grid-column: 1 / -1;
    grid-row: auto;
    justify-self: start;
}

.project-details-page .ps-shell.ps-assistant-open .ps-shell-frame > .locked-overlay-wrapper > .locked-overlay-badge {
    top: 12px;
    left: auto;
    right: 16px;
    transform: none;
    max-width: none;
}

.project-details-page .ps-shell.ps-assistant-open .ps-shell-frame > .locked-overlay-wrapper > .locked-overlay-popover {
    top: 50px;
    left: auto;
    right: 16px;
    transform: none;
    max-width: none;
}

/* ---------- Fullscreen room ---------- */

/* The page's own fullscreen rule hides only direct children of .project-details-page. Everything here sits
   inside .ps-shell, which stays visible because it holds the room card, so these are hidden by name. */
.project-details-page.fullscreen-mode-active :is(.ps-header, .drift-banner, .project-financial-summary, .detailed-summary-section, .ps-rail, .ps-kpi) {
    display: none;
}

/* The fullscreen room card is position: fixed. No ancestor of it may be a size container, or it could trap the
   card (spec section 4.1), so the frame stops being one while a room is fullscreen. */
.project-details-page.fullscreen-mode-active .ps-shell-frame {
    container-type: normal;
}
