/*
 * BOM Equipment Table — dedicated stylesheet
 * Spec: docs/superpowers/specs/2026-07-06-bom-equipment-visual-refresh-design.md
 *
 * Scope: the room equipment table on the project details page
 * (Details.razor), scoped by the `.eq-quiet` class on the table tag.
 * Loaded AFTER BlazorApp1.styles.css (App.razor) so it can override the
 * Blazor-scoped component rules.
 *
 * Responsibility split (T3=a):
 *   - Colors, hover, striping-off, header fill  → presets.css (.eq-quiet
 *     overrides scoped at theme level, consuming --eq-* tokens).
 *   - Structural rules — spacing, typography, opacity, transitions, alignment
 *     — live HERE, consuming --eq-* / --bs-* variables only.
 *
 * HARD INVARIANTS (verified per commit):
 *   - Zero hex literals in this file (colors come from --eq-* tokens).
 *   - Zero forced-override flags in this file (theme-level overrides that need
 *     to beat Bootstrap defaults belong in presets.css, not here).
 *
 * Later tasks (§3-§13) fill in the structural rules under `.eq-quiet`.
 */

/* ===========================================================================
 * §8 — Column headers (structural half)
 * ---------------------------------------------------------------------------
 * The 10px size, weight 500, --eq-text-dim color and --eq-border bottom border
 * have to beat the shared `.table-header-themed th` forced-override rule
 * (presets.css) so they live in the presets `.eq-quiet` section. The properties
 * below have no competing forced-override, so they apply from here. `white-space`
 * and `padding` stay governed by the shared header rule (already nowrap / tight).
 * =========================================================================== */
.eq-quiet thead th {
    text-transform: uppercase;
    letter-spacing: 0.5px;
    vertical-align: middle;
}

/* Sticky header positioning — migrated verbatim from the Details.razor inline
 * `<style>` block so the header keeps pinning while the equipment list scrolls.
 * `.sticky-header` is used only by this table's `<thead>`. */
.eq-quiet .sticky-header {
    position: sticky;
    top: 0;
    z-index: 10;
}

/* ===========================================================================
 * §12 — Row density (replaces the deleted `.table-compact` inline rules)
 * ---------------------------------------------------------------------------
 * 36px data rows: dense but comfortable inline-edit targets. Scales with the
 * table's `zoom: @zoomLevel`. Row-divider color (--eq-border-hairline) has to
 * beat a shared `.table td` forced-override border rule and lives in presets.
 * =========================================================================== */
.eq-quiet tbody td {
    height: 36px;
    padding: 0.25rem 0.4rem;
    vertical-align: middle;
}

/* Compact inline inputs so a filled cell still fits the 36px row. */
.eq-quiet tbody .form-control,
.eq-quiet tbody .form-control-sm,
.eq-quiet tbody input[type="text"],
.eq-quiet tbody input[type="number"] {
    padding: 0.15rem 0.25rem;
    height: auto;
    min-height: 0;
    font-size: 0.8rem;
}

/* Keep count/badge pills compact in the dense row. Badge colors are unchanged
 * here — the money/count badge recolor is a later phase (§1/§2). */
.eq-quiet .badge {
    padding: 0.2rem 0.4rem;
    font-size: 0.75rem;
}

/* ===========================================================================
 * §9 — Column resize handles
 * ---------------------------------------------------------------------------
 * columnResize.js injects a bare `.resize-handle` div into each `th.resizable`
 * (and toggles `.resizing` on the th during a drag). The div is the grab target
 * and carries no inline styles. The global handle styling in app.css
 * (`th.resizable .resize-handle`, ~1372) is SHARED with the proposal table
 * (Details.razor) and is left intact; these higher-specificity `.eq-quiet`
 * rules quiet the handle for the equipment table only — no forced-override
 * needed (the app.css rules use none, so specificity + load order win cleanly).
 *
 * The div stays a wide transparent grab strip; the visible indicator is its
 * `::after` hairline, so resizing stays easy to grab while reading as a
 * hairline. No permanent vertical grid lines anywhere.
 * =========================================================================== */
.eq-quiet th.resizable .resize-handle {
    position: absolute;
    top: 0;
    right: 0;
    width: 8px;
    height: 100%;
    background: none;
    box-shadow: none;
    border-radius: 0;
    cursor: col-resize;
    z-index: 10;
}

/* Indicator, invisible at rest. */
.eq-quiet th.resizable .resize-handle::after {
    content: "";
    position: absolute;
    top: 25%;
    right: 0;
    width: 1px;
    height: 50%;
    background-color: var(--eq-text-zero);
    opacity: 0;
    transition: opacity 0.12s ease;
}

/* On header hover: reveal the 1px, half-height hairline. */
.eq-quiet th.resizable:hover .resize-handle::after {
    opacity: 1;
}

/* While dragging: 2px, full header height, accent color. */
.eq-quiet th.resizable.resizing .resize-handle::after {
    top: 0;
    width: 2px;
    height: 100%;
    background-color: var(--eq-accent);
    opacity: 1;
}

/* ===========================================================================
 * §7 — Column text hierarchy (structural half)
 * ---------------------------------------------------------------------------
 * Three tiers per spec §7. The per-column `eq-col-*` classes are added to the
 * loop/fixed cells in Details.razor. FONTS, SIZE, and ALIGNMENT live here (no
 * competing forced-override, so they apply from this file); the tier COLORS —
 * which must beat the shared forced-override color on `.table-input`
 * (presets.css) and the row-hover cell color — live in the presets `.eq-quiet`
 * section instead. The monospace stack matches the global one already used
 * throughout presets.css; `tabular-nums` follows the theme-base.css:213-216
 * numeric-alignment pattern.
 *
 * Primary Description (sans) and Secondary Make (sans) need no structural rule —
 * the table default is already sans-serif — so only their colors are set (presets).
 * =========================================================================== */

/* Primary — Model: monospace with tabular figures. */
.eq-quiet tbody td.eq-col-model .table-input {
    font-family: 'SF Mono', 'Cascadia Code', 'Fira Code', 'Consolas', monospace;
    font-variant-numeric: tabular-nums;
}

/* Primary — Qty: monospace with tabular figures (center alignment comes from the
 * input's own `text-center` class, preserved in markup). */
.eq-quiet tbody td.eq-col-qty .table-input {
    font-family: 'SF Mono', 'Cascadia Code', 'Fira Code', 'Consolas', monospace;
    font-variant-numeric: tabular-nums;
}

/* Tertiary — Part #: monospace 11px with tabular figures. */
.eq-quiet tbody td.eq-col-part .table-input {
    font-family: 'SF Mono', 'Cascadia Code', 'Fira Code', 'Consolas', monospace;
    font-variant-numeric: tabular-nums;
    font-size: 11px;
}

/* Tertiary — line number: a plain (non-input) cell. Monospace 11px, tabular
 * figures, right-aligned per spec §7. The table is table-layout:fixed, so the
 * header's 36px sets the column; min-width keeps it from ever dropping below
 * 3-digit width (resizable-columns cells clip overflow with an ellipsis, so a
 * narrower column would render "10" as "1…"). */
.eq-quiet thead th.eq-col-num,
.eq-quiet tbody td.eq-col-num {
    min-width: 36px;
}

.eq-quiet tbody td.eq-col-num {
    font-family: 'SF Mono', 'Cascadia Code', 'Fira Code', 'Consolas', monospace;
    font-variant-numeric: tabular-nums;
    font-size: 11px;
    text-align: right;
    white-space: nowrap;
}

/* ===========================================================================
 * §3 — Hover-only row actions
 * ---------------------------------------------------------------------------
 * The left icon cells (drag handle, copy) and the right-side per-row buttons
 * (highlight, delete), plus the divider row's drag/copy/delete cells, carry the
 * `.eq-row-actions` class in Details.razor. They rest at opacity 0 and fade to
 * full opacity in 150ms when the row is hovered OR when focus lands inside it
 * (`:focus-within` keeps keyboard/tab navigation from going blind — this second
 * selector is required, not optional).
 *
 * Opacity alone hides the controls; it does not disable them. The `<tr
 * draggable="true" data-item-id>` and the `.drag-handle` grab target that
 * dragDropHelper.js reads are untouched, so drag-to-reorder still works — the
 * handle simply becomes visible on hover before the user grabs it. Row-hover
 * background (`--eq-bg-raised`) and the `.highlighted-row` yellow fill both come
 * from the Task-1 presets bridge, so this file adds no `tr:hover { background }`
 * rule and does not regress highlighted rows.
 * =========================================================================== */
.eq-quiet tr .eq-row-actions {
    opacity: 0;
    transition: opacity 150ms ease;
}

.eq-quiet tr:hover .eq-row-actions,
.eq-quiet tr:focus-within .eq-row-actions {
    opacity: 1;
}

/* Rows in the multi-select copy set keep their action cells visible — the blue
   selected copy button IS the selection indicator, so it must not rest hidden.
   Background tint comes from presets.css (.eq-row-selected, --eq-bg-selected). */
.eq-quiet tr.eq-row-selected .eq-row-actions {
    opacity: 1;
}

/* ===========================================================================
 * §4 — Quiet category header rows (structural half)
 * ---------------------------------------------------------------------------
 * The former filled `.divider-row` becomes `.eq-cat-row`: a small uppercase
 * label (`.eq-cat-label`) followed by a hairline rule cell (`.eq-cat-rule`)
 * that runs to the table's right edge. No background fill.
 *
 * The label TYPE SCALE (11px / 600 / 0.8px / uppercase) and the row's breathing
 * room (16px above, 6px below — spec §4) live here (no competing forced-override,
 * so they apply from this file). The label COLOR (--eq-text-muted) has to beat
 * the shared `.table td` forced-override color rule and lives in the presets
 * `.eq-quiet` section instead.
 *
 * The hairline is painted as a 1px --eq-rule line centered in the rule cell via
 * background-image. The shared `.eq-quiet … td` forced-override fill sets only
 * the background-color longhand, so the image layer is not overridden and needs
 * no forced-override flag here.
 * =========================================================================== */
.eq-quiet .eq-cat-row td {
    height: auto;
    padding-top: 16px;
    padding-bottom: 6px;
}

.eq-quiet .eq-cat-label {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.8px;
    text-transform: uppercase;
}

.eq-quiet .eq-cat-rule {
    background-image: linear-gradient(var(--eq-rule), var(--eq-rule));
    background-repeat: no-repeat;
    background-size: 100% 1px;
    background-position: left center;
}

/* ===========================================================================
 * §5 — Category subtotal rows (structural half)
 * ---------------------------------------------------------------------------
 * Rendered at each group's END (Details.razor render loop) as ONE cell spanning
 * the whole row: value + category name at the LEFT edge, on a single line
 * (user request — the old layout parked them mid-table under Extended/Cost Ea
 * and wrapped in narrow columns). The full-row colspan + nowrap makes the
 * one-line guarantee independent of any column widths. COLORS (value
 * --eq-text-muted, name --eq-text-faint) and the row's 1px --eq-border bottom
 * rule beat shared forced-overrides and live in the presets `.eq-quiet` section. */
.eq-quiet .eq-subtotal-cell {
    text-align: left;
    white-space: nowrap;
}

.eq-quiet .eq-subtotal-value {
    font-family: 'SF Mono', 'Cascadia Code', 'Fira Code', 'Consolas', monospace;
    font-variant-numeric: tabular-nums;
    font-size: 12px;
}

.eq-quiet .eq-subtotal-name {
    font-size: 11px;
    margin-left: 10px;
}

/* ===========================================================================
 * §6 — Room total tfoot (structural half)
 * ---------------------------------------------------------------------------
 * A single `<tr class="eq-room-total">` in the table's `<tfoot>` (Details.razor
 * render). It is the sticky-bottom counterpart of the sticky header (§8):
 * `position: sticky; bottom: 0` pins the footer to the bottom edge of the
 * `.equipment-scroll-container` (70vh + overflow:auto normally, height:100% in
 * fullscreen) so the room total is always visible while the list scrolls. The
 * z-index matches the header's (equipment-table.css §8, z-index 10) so the
 * footer floats above scrolling rows. Sticky is set on the cells — the broadest-
 * supported target and the mirror of the header, which pins via its section.
 *
 * Label + value sit at the LEFT edge of the row (user request): the label spans
 * the drag/copy/# cells (right-aligned so "Room Total" butts against the value),
 * the value fills the first data column left-aligned — 14px/600 monospace with
 * tabular figures — so the pair reads as one unit without horizontal scrolling.
 * COLORS (fill --eq-bg-raised, 1px --eq-border top rule, label --eq-text-secondary,
 * value --eq-text-strong) beat shared forced-overrides and live in the presets
 * `.eq-quiet` section; the monospace stack matches the global one used throughout.
 * =========================================================================== */
.eq-quiet tfoot td {
    position: sticky;
    bottom: 0;
    z-index: 10;
}

.eq-quiet .eq-room-total-label {
    font-size: 12px;
    font-weight: 600;
    text-align: right;
    white-space: nowrap;
}

.eq-quiet .eq-room-total-value {
    font-family: 'SF Mono', 'Cascadia Code', 'Fira Code', 'Consolas', monospace;
    font-variant-numeric: tabular-nums;
    font-size: 14px;
    font-weight: 600;
    text-align: right;
}

.eq-quiet .eq-room-total-value--left {
    text-align: left;
}

/* ===========================================================================
 * §1/§2 — Display-only numeric cells (structural half)
 * ---------------------------------------------------------------------------
 * The product row's display money cells (Rate, Extended, Cost Total) and the
 * hours/count-derived extended cells (Labor/Prog/Config/STP/UTP/IDF Ext) render
 * their value through a shared `RenderQuietNumber` helper (Details.razor): a
 * value > 0 becomes `<span class="eq-money …">`, a zero/null becomes
 * `<span class="eq-zero">—</span>`. `.eq-money` supplies the monospace stack with
 * tabular figures so digits line up column-to-column; alignment already comes
 * from each cell's `text-end`, but right-align is declared here for intent. The
 * TIER COLORS (--sell green, --cost rose, --plain primary) and the em-dash color
 * (--eq-text-zero) must beat the shared `.table td` forced-override color rule and
 * the row-hover td color, so they live in the presets `.eq-quiet` section. The
 * monospace stack matches the global one used throughout presets.css.
 * =========================================================================== */
.eq-quiet .eq-money {
    font-family: 'SF Mono', 'Cascadia Code', 'Fira Code', 'Consolas', monospace;
    font-variant-numeric: tabular-nums;
    text-align: right;
    white-space: nowrap;
}

/* Read-only computed cells (a direct .eq-money / .eq-zero value, not an .eq-edit-cell)
   read as inert output: a default cursor, not the cell/text cursor the editable cells
   use. Pairs with the hover-underline affordance that only editable inputs get. */
.eq-quiet tbody td:has(> .eq-money),
.eq-quiet tbody td:has(> .eq-zero) {
    cursor: default;
}

/* ===========================================================================
 * §1/§2 [D2] — Edit-on-click numeric cells (structural half)
 * ---------------------------------------------------------------------------
 * Cost Ea, Override %, Labor/Programmer/Configuration Hrs, and — legacy cable
 * projects only — the STP/UTP/IDF counts show a formatted value at rest and
 * reveal the real <input> on click. The value region is wrapped in
 * `.eq-edit-cell`; inside it sit a `.eq-edit-display` span (the Task-8 dash-or-
 * value + tier fragment) and the existing input, which gains `.eq-edit-input`.
 *
 * The display span sits in normal flow and gives the wrapper its box; the input
 * is absolutely positioned to fill that box. At rest the input is transparent
 * (background/border via the §7 borderless rule; TEXT via the presets `.eq-quiet`
 * section) so only the display shows through. On `:focus-within` the display
 * span is hidden and the standard `.table-input:focus` ring reveals the input.
 * The input is NEVER display:none — it stays in the tab flow and stays clickable,
 * so the value area focuses on click and Tab still lands on it.
 *
 * The wrapper is inline-block, sized to the value (min-width keeps a usable click
 * target for the em dash), so the overlay covers the VALUE REGION ONLY: for Cost
 * Ea the `.stock-indicator` sibling stays beside it — visible and clickable — and
 * every td's `@onclick="SelectCell"` still fires for clicks in the surrounding
 * cell area (Excel-style selection). Colors/opacity live in presets `.eq-quiet`.
 *
 * `visibility` (not `display`) toggles the display span so the wrapper keeps its
 * height on focus and the absolutely-positioned input stays aligned to the value.
 * =========================================================================== */
.eq-quiet .eq-edit-cell {
    position: relative;
    display: inline-block;
    min-width: 5ch;
    max-width: 100%;
}

.eq-quiet .eq-edit-cell .eq-edit-display {
    display: block;
}

.eq-quiet .eq-edit-cell:focus-within .eq-edit-display {
    visibility: hidden;
}

.eq-quiet .eq-edit-cell .eq-edit-input {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    text-overflow: ellipsis;
}

/* Empty cells (the display span renders the .eq-zero em dash): hide the dash and
   let the input read as a recessed empty WELL — a dark rectangle (fill lives in
   the presets `.eq-quiet` section, --eq-bg-well) that marks the cell as fillable,
   so an empty EDITABLE cell is distinguishable from the read-only computed cells,
   which keep their direct-child em dash. `visibility` keeps the wrapper's box;
   the min-width gives the well a usable size while the base max-width:100% still
   caps it inside the column, keeping the Cost Ea stock-indicator sibling on the
   same line. The radius stays within the 2px panel-system maximum. */
.eq-quiet .eq-edit-cell:has(.eq-zero) {
    min-width: 9ch;
}
.eq-quiet .eq-edit-cell:has(.eq-zero) .eq-edit-display {
    visibility: hidden;
}
.eq-quiet .eq-edit-cell:has(.eq-zero) .eq-edit-input {
    border-radius: 2px;
}

/* While editing, the wrapper stretches to the full cell width (the at-rest box
   is only as wide as the value/well) and the placeholder hint renders a step
   smaller — together the hint ("Override %", "Labor Hours Ea") fits the box
   instead of clipping mid-word. The display span is already hidden on
   focus-within, so nothing else occupies the widened box. */
.eq-quiet .eq-edit-cell:focus-within {
    width: 100%;
}
.eq-quiet .eq-edit-input:focus::placeholder {
    font-size: 0.85em;
}

/* Native number-input spinner arrows crowded the value in these dense, narrow
   cells — and rendered on top of the display span at rest (the input's value text
   is transparent-at-rest, but the spinner control is not). Hide them; values are
   typed (and still accept the 0.25 step). */
.eq-quiet .eq-edit-input::-webkit-inner-spin-button,
.eq-quiet .eq-edit-input::-webkit-outer-spin-button {
    -webkit-appearance: none;
    appearance: none;
    margin: 0;
}
.eq-quiet .eq-edit-input[type="number"] {
    -moz-appearance: textfield;
    appearance: textfield;
}

/* ===========================================================================
 * §2 [D4] — Quiet status / override tags (structural half)
 * ---------------------------------------------------------------------------
 * The per-row "Auto-saved" confirmation and the conditional "Override" markup
 * flag were filled Bootstrap badges (bg-success / bg-warning). D4 reserves green
 * for sell dollars and quiets all chrome, so both drop the pill and render as
 * plain dim-gray text via `.eq-status-text`. This structural rule keeps them at
 * the table's small tertiary scale (matching the badge's former size, so the
 * status column doesn't grow louder than it was); the dim COLOR must beat the
 * shared `.table td` forced-override color rule and lives in the presets
 * `.eq-quiet` section instead.
 * =========================================================================== */
.eq-quiet .eq-status-text {
    font-size: 11px;
}

/* ===========================================================================
 * §10 — Column visibility picker (structural half)
 * ---------------------------------------------------------------------------
 * The picker is a Bootstrap-native dropdown (data-bs-toggle="dropdown"), cloned
 * from the in-toolbar Fill Prices control, so the toggle button, menu box, and
 * open/close behavior all inherit the theme's dropdown styling — no colors here.
 * `.eq-col-picker` is the structural hook: each hideable column is one checkbox
 * row (checked = the column is visible). Rows keep a comfortable single-line
 * click target and never wrap their label so the checkbox and name stay aligned.
 * =========================================================================== */
.eq-col-picker .dropdown-menu {
    min-width: 12rem;
}

.eq-col-picker .form-check {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    white-space: nowrap;
    padding-left: 0.75rem;
    margin-bottom: 0;
    min-height: 0;
}

/* Bootstrap's .form-check-input floats left with a -1.5em margin; inside the flex
   row that pulls the box out of alignment. Reset both so the checkbox and label
   sit on one baseline-centered line with the gap above. */
.eq-col-picker .form-check .form-check-input {
    float: none;
    margin: 0;
    flex-shrink: 0;
}

.eq-col-picker .form-check .form-check-label {
    margin: 0;
    cursor: pointer;
}

/* ===========================================================================
 * §11 — Room header toolbar (structural half)
 * ---------------------------------------------------------------------------
 * The normal room-card header is regrouped into `.eq-toolbar`: a flex row with
 * a left meta group (room name, QTY, product count) and a right actions group
 * (contextual buttons, Copy Room, Fill Prices, column picker, kebab overflow,
 * fullscreen/collapse). Flex `gap` supplies the inter-control spacing that the
 * old per-control `me-*`/`ms-*` utilities carried; the actions group wraps so a
 * narrow card never overflows its header. Fullscreen header is untouched (U1=a).
 * =========================================================================== */
.eq-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    width: 100%;
}

.eq-toolbar-meta,
.eq-toolbar-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.eq-toolbar-actions {
    flex-wrap: wrap;
    justify-content: flex-end;
}

/* Ghost action button — structural half (colors live in the presets `.eq-quiet`
 * section so the resting/hover text + border beat Bootstrap's `.btn` base). The
 * quiet-until-activated action buttons (Copy Room, Clear/Paste contextual) carry
 * `.eq-ghost-btn` in place of the old `.btn-outline-*` variants: a transparent
 * 1px-bordered button that brightens on hover. Size/padding/radius stay from the
 * retained `.btn.btn-sm` base. */
.eq-ghost-btn {
    border-width: 1px;
    border-style: solid;
    background-color: transparent;
    transition: color 0.15s ease, background-color 0.15s ease, border-color 0.15s ease;
}

/* ===========================================================================
 * §13 — Fullscreen room-card header (structural half)
 * ---------------------------------------------------------------------------
 * The fullscreen header is the `.card-header` element; it gains the
 * `.fullscreen-room-header` class only while a room is expanded. Its compact
 * padding is the sole structural rule (replacing the old inline gradient's
 * `padding: 0 8px`). Colors — the --eq-bg-raised fill, --eq-border bottom rule,
 * and the text-token re-maps — live in the presets `§13 Fullscreen chrome`
 * section (they beat Bootstrap's `.card-header` and the `.text-white` utilities,
 * so they need a theme-level forced override, which does not belong in this file).
 * The tabs and footer keep their positioning in the Details.razor inline block.
 * =========================================================================== */
.fullscreen-room-header {
    padding: 0 8px;
}

/* ===========================================================================
 * §14 — Owner Furnished rows (structural half)
 * ---------------------------------------------------------------------------
 * OFE lines are client-owned equipment: $0 material, labor still applies. The
 * "OFE" badge is the primary signal; a left accent rail on the first cell marks
 * the row without fighting table striping (full-row background fills need the
 * theme-level forced overrides that live in presets.css — these do not). Tokens
 * only, zero hex (file invariant).
 * =========================================================================== */
.eq-quiet tr.eq-row-ofe td:first-child {
    box-shadow: inset 3px 0 0 var(--eq-accent);
}

.eq-ofe-badge {
    display: inline-block;
    margin-top: 2px;
    padding: 0 4px;
    font-size: 9px;
    font-weight: 700;
    line-height: 14px;
    letter-spacing: 0.04em;
    color: var(--eq-accent);
    border: 1px solid var(--eq-accent);
    border-radius: 3px;
}
