/* The shared grid shape: any list with a column catalog mounts it, so nothing here
   is named after a surface. Look copied from HubSpot's list (Nick's pick 2026-09-01). */

/* Bounded, so the header can stick to its top and the frozen column can slide
   under the rest. A table that scrolled with the page would have neither.
   Isolated, so the rungs its sticky parts climb stay inside the grid: a menu
   the toolbar opens over it sits above the whole table, frozen headers
   included, instead of losing to whatever shares its rung and comes later.
   The 70vh cap is the fallback bound; inside a viewport-fit page
   (.global-page-fill, main.css) flex hands the wrap its height and lifts
   the cap. */
.global-grid-wrap {
    position: relative;
    isolation: isolate;
    overflow: auto;
    overscroll-behavior: contain;
    max-height: 70vh;
}

.global-grid {
    /* Where text ellipsizes; a drag overrides it per column (_grid_resize_js.html). */
    --grid-col-max: 18rem;
    /* The height EVERY row is drawn at, and the name that rides it. These are the
       standard step's own values, so a grid that names no step is still never sized by
       its contents, and --rows-standard needs no rule of its own. */
    --grid-row-h: 3rem;
    --grid-name-size: var(--font-size-lg);
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    font-size: var(--font-size-md);
    color: var(--color-text);
    background: var(--color-card-bg);
}

/* The steps that move off the base (property_columns.ROW_HEIGHT_STEPS). A roomier row
   buys a bigger name rather than more empty space, and the face grows with it — the
   atom's own next size up, mounted where the cell is rendered. */
.global-grid--rows-compact {
    --grid-row-h: 2.25rem;
    --grid-name-size: var(--font-size-md);
}

.global-grid--rows-relaxed {
    --grid-row-h: 4rem;
    --grid-name-size: var(--font-size-h4);
}

/* ── The header band ─────────────────────────────────────────────────────── */
.global-grid__head {
    position: sticky;
    top: 0;
    z-index: var(--z-sticky);
    background: var(--color-card-bg);
    border-bottom: 1px solid var(--color-border);
    padding: var(--spacing-sm) var(--spacing-md);
    text-align: left;
    font-size: var(--font-size-md);
    font-weight: var(--font-weight-body);
    color: var(--color-text-secondary);
    white-space: nowrap;
    vertical-align: middle;
}

/* The heading the grid is ordered by comes back to the data's own ink. The
   arrow is already on it, so nothing else has to mark it. */
.global-grid__head:has(.global-grid__sort-mark) {
    color: var(--color-text);
    font-weight: var(--font-weight-medium);
}

/* The frozen band. Its headers sit above both the band and the rows, so they
   take the one rung higher (inside the wrap's own stack — see above); how far
   in each sits is a measurement, so
   _grid_resize_js.html writes the `left` beside the widths. */
.global-grid__head--pinned {
    z-index: var(--z-dropdown);
}

.global-grid__head--pinned,
.global-grid__cell--pinned {
    position: sticky;
    left: 0;
    background: var(--grid-tone-bg, var(--color-card-bg));
}

.global-grid__cell--pinned {
    z-index: var(--z-raised);
}

/* Only the band's last column draws the seam, so one rule marks where the
   frozen columns end however many of them there are. */
.global-grid__head--edge,
.global-grid__cell--edge {
    border-right: 1px solid var(--color-border-subtle);
}

/* A sortable heading is a button that looks like its label. */
.global-grid__sort {
    display: inline-flex;
    align-items: center;
    gap: var(--spacing-xs);
    padding: 0;
    border: 0;
    background: transparent;
    color: inherit;
    font: inherit;
    cursor: pointer;
}

.global-grid__sort:hover {
    color: var(--color-text-light);
}

.global-grid__sort-mark {
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
}

/* A property this reader may not see: the column stays (Nick's rule), the lock
   is the whole of what it says. */
.global-grid__lock {
    margin-left: var(--spacing-xs);
    color: var(--color-text-muted);
    font-size: var(--font-size-xs);
}

/* ── The drag edge ─────────────────────────────────────────────────────────
   The hit area is wider than the line a reader sees. touch-action lets the drag
   own touch input instead of fighting the wrap's own scrolling. */
.global-grid__resize {
    position: absolute;
    top: 0;
    right: -4px;
    width: 9px;
    height: 100%;
    z-index: var(--z-raised);
    cursor: col-resize;
    user-select: none;
    touch-action: none;
}

.global-grid__resize::after {
    content: "";
    position: absolute;
    top: 6px;
    bottom: 6px;
    left: 4px;
    width: 1px;
    background: transparent;
    transition: background var(--transition-fast);
}

.global-grid__head:hover .global-grid__resize::after,
.global-grid__resize:hover::after {
    background: var(--color-text-muted);
}

/* Mid-drag the pointer is often nowhere near the handle, so the cursor and the
   no-select rule move to the page. */
body.global-grid-resizing {
    cursor: col-resize;
    user-select: none;
}

/* The column adder. Its own column, holding the leftover width so the real
   columns stay as narrow as their content. */
.global-grid__adder {
    position: sticky;
    top: 0;
    z-index: var(--z-sticky);
    width: 100%;
    background: var(--color-card-bg);
    border-bottom: 1px solid var(--color-border);
    padding: var(--spacing-sm) var(--spacing-md);
    text-align: left;
}

.global-grid__addbtn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.5rem;
    height: 1.5rem;
    padding: 0;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: var(--color-card-bg);
    color: var(--color-text-muted);
    cursor: pointer;
}

.global-grid__addbtn:hover {
    background: var(--color-surface-subtle);
    color: var(--color-text);
}

/* The heading's own menu, HubSpot's three dots: out of the way until the
   heading is under the pointer, and always there for the keyboard. */
.global-grid__headbtn {
    margin-left: var(--spacing-xs);
    padding: 0 var(--spacing-2xs);
    border: 0;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--color-text-muted);
    font-size: var(--font-size-xs);
    cursor: pointer;
    opacity: 0;
}

.global-grid__head:hover .global-grid__headbtn,
.global-grid__headbtn:focus-visible {
    opacity: 1;
}

.global-grid__headbtn:hover {
    background: var(--color-surface-hover);
    color: var(--color-text);
}

/* ── Rows and cells ────────────────────────────────────────────────────────
   The hover fill is repainted on the frozen cell too: it is its own painted
   surface, so the row's background never shows through it. */
.global-grid__cell {
    height: var(--grid-row-h);
    /* No vertical padding: the height is the whole of the room a row gets, so a
       cell can never be drawn taller than the one beside it. */
    padding: 0 var(--spacing-md);
    border-bottom: 1px solid var(--color-border-subtle);
    vertical-align: middle;
    white-space: nowrap;
}

/* Several small things in one cell — skill pills, a "+2". They ride one line and the
   cell clips what does not fit, rather than wrapping and pushing the row taller. */
.global-grid__chips {
    display: flex;
    align-items: center;
    gap: var(--spacing-xs);
    max-width: var(--grid-col-max);
}

/* The pills are what a narrow column eats, never the count beside them: a cell
   that drops "+3" reads as a worker who holds four skills and no more. */
.global-grid__pills {
    display: flex;
    align-items: center;
    gap: var(--spacing-xs);
    min-width: 0;
    overflow: hidden;
}

.global-grid__pills > *,
.global-grid__chips > .global-chip {
    flex: none;
}

.global-grid__row:nth-child(even) .global-grid__cell,
.global-grid__row:nth-child(even) .global-grid__cell--pinned {
    background: var(--grid-tone-bg, var(--color-surface-subtle));
}

/* The tint, not --color-surface-hover: that grey is the one the cell borders are
   drawn in, so a row filled with it loses the rule under it just as the pointer
   arrives. */
.global-grid__row:hover .global-grid__cell,
.global-grid__row:hover .global-grid__cell--pinned {
    background: var(--grid-tone-bg, var(--color-action-tint));
}

/* Conditional styling — the platform's four semantic slots and nothing else
   (Nick's rule, 2026-09-02). A rule paints one CELL; the zebra and hover fills
   are written against the ROW, which makes them the more specific pair, so
   source order settles nothing between them. Every fill above therefore reads
   the tone first and keeps its own colour as the fallback — otherwise a rule
   paints only the odd rows the pointer is not on, and a filter change
   reshuffles which rows those are (Nick, 2026-09-03). The opportunities table
   (milestones.css, .opportunities-milestone-propcell and the milestone cells,
   .opportunities-milestone-td) wears the same stamp, so its cells share these
   rules rather than repeating the tokens. A rule's tone wins over the late red:
   the rule is the coordinator's own word on that cell. */
.global-grid__cell[data-tone],
.opportunities-milestone-propcell[data-tone],
.opportunities-milestone-td[data-tone] {
    background: var(--grid-tone-bg);
    color: var(--grid-tone-text);
}

.global-grid__cell[data-tone="success"],
.opportunities-milestone-propcell[data-tone="success"],
.opportunities-milestone-td[data-tone="success"] {
    --grid-tone-bg: var(--color-success-bg);
    --grid-tone-text: var(--color-success-text);
}

.global-grid__cell[data-tone="warning"],
.opportunities-milestone-propcell[data-tone="warning"],
.opportunities-milestone-td[data-tone="warning"] {
    --grid-tone-bg: var(--color-warning-bg);
    --grid-tone-text: var(--color-warning-text);
}

.global-grid__cell[data-tone="danger"],
.opportunities-milestone-propcell[data-tone="danger"],
.opportunities-milestone-td[data-tone="danger"] {
    --grid-tone-bg: var(--color-error-subtle);
    --grid-tone-text: var(--color-error-text);
}

.global-grid__cell[data-tone="info"],
.opportunities-milestone-propcell[data-tone="info"],
.opportunities-milestone-td[data-tone="info"] {
    --grid-tone-bg: var(--status-info-bg);
    --grid-tone-text: var(--color-info);
}

/* The last column soaks up the leftover width so nothing else has to stretch. */
.global-grid__cell--filler {
    width: 100%;
}

/* A cell nobody filled in still has to read as a cell. */
.global-grid__empty {
    color: var(--color-text-muted);
}

/* ── An editable cell ──────────────────────────────────────────────────────
   The whole cell is the target, the way HubSpot's is. The pencil's room is held
   whether it shows or not, so nothing shifts as the pointer crosses. */
.global-grid__cell--editable {
    cursor: text;
    padding-right: var(--spacing-lg);
}

/* The frozen column is already sticky, which positions it; relative there would
   unfreeze it. Everywhere else the cell has to become the pencil's anchor. */
.global-grid__cell--editable:not(.global-grid__cell--pinned) {
    position: relative;
}

.global-grid__row:hover .global-grid__cell--editable:hover {
    background: var(--grid-tone-bg, var(--color-card-bg));
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-inset-ring-neutral);
}

/* An outline, not a shadow, so it never trades places with the well above. */
.global-grid__cell--editable:focus-visible {
    outline: 2px solid var(--color-focus-ring);
    outline-offset: -2px;
}

/* Only under the pointer: a column of pencils would be louder than the values. */
.global-grid__pencil {
    position: absolute;
    top: 50%;
    right: var(--spacing-sm);
    transform: translateY(-50%);
    color: var(--color-text-muted);
    font-size: var(--font-size-xs);
    opacity: 0;
}

.global-grid__cell--editable:hover .global-grid__pencil,
.global-grid__cell--editable:focus-visible .global-grid__pencil {
    opacity: 1;
}

.global-grid__value {
    display: inline-block;
    max-width: var(--grid-col-max);
    overflow: hidden;
    text-overflow: ellipsis;
    vertical-align: bottom;
}

/* A day already gone — the Skill expires column's lapsed date. The value turns
   the failure red instead of growing a badge, so the column stays one column
   of dates and the red one is the row that needs a hand. */
.global-grid__value--expired {
    color: var(--color-error);
}

/* A link_template cell: "Open ↗" instead of the raw value, so the click reads
   as leaving the page rather than editing the cell. @click.stop (in the
   template) keeps the row's own click-to-edit from also firing. */
.global-grid__link {
    display: inline-flex;
    align-items: center;
    color: var(--color-action);
    text-decoration: none;
}

.global-grid__link:hover,
.global-grid__link:focus-visible {
    text-decoration: underline;
}

.global-grid__link i {
    font-size: var(--font-size-xs);
    margin-left: var(--spacing-xs);
}

/* The first cell is the row's only way into the record, so every other cell stays
   free to be read, selected and edited (HubSpot's list, Nick 09-02). The link itself
   belongs to whatever atom draws that cell — for a person, components/person-chip.css. */
.global-grid .global-person-chip {
    vertical-align: middle;
}

/* The name is the one value in a row that grows with the row, so the grid sizes it
   from its own step rather than taking whichever size the atom was drawn at. It also
   ellipses here: the atom wraps a name it cannot fit, which is right in a card and
   would make one row taller than the next in a grid. */
.global-grid .global-person-chip__name {
    font-size: var(--grid-name-size);
    max-width: var(--grid-col-max);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* What is STORED in an editable cell, which is what a control starts from
   (property_columns.raw_values). Never drawn, and never rendered at all on a
   cell this reader may not change. */
.global-grid__raw {
    display: none;
}

/* ── The editor ────────────────────────────────────────────────────────────
   One editor for the whole grid, laid over whichever cell was clicked and sized
   to that column by _grid_editor_js.html, so a change happens in the cell. */
.global-grid-editor {
    position: absolute;
    z-index: var(--z-dropdown);
    padding: var(--spacing-xs);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: var(--color-card-bg);
    box-shadow: var(--shadow-menu);
}

/* The Ramp vendor cell's editor holds the profile's three-step pick one step at
   a time, so it needs more room than a value box and no more than a phone has.
   ramp-match-cell.js repeats the width (PANEL_WIDTH) for its fit math and
   narrows it on a grid that is narrower still. */
.global-grid-editor--ramp {
    width: 22rem;
    max-width: 100%;
    padding: var(--spacing-sm);
}

/* One area at a time: the arrows in the head replace the profile's numbered
   markers and the line between them. */
.global-grid-editor--ramp .payments-setup-step__marker,
.global-grid-editor--ramp .payments-setup-step__line {
    display: none;
}

.global-grid-editor--ramp .payments-setup-step {
    padding-bottom: 0;
}

.global-grid-editor--ramp .payments-setup-step__control {
    max-width: none;
}

.global-grid-editor--ramp .payments-setup-actions {
    margin-top: var(--spacing-sm);
    padding-top: var(--spacing-sm);
}

/* Whose rail the panel works: the Ramp mark at the head's right. */
.global-grid-editor__mark {
    flex: none;
    height: 12px;
    width: auto;
    opacity: .8;
}

/* One person to pay: a check and their name, centred, and nothing else. */
.global-grid-editor__payee {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--spacing-xs);
    padding: var(--spacing-md) 0;
    font-weight: var(--font-weight-medium);
    text-align: center;
}

.global-grid-editor__payee .bi {
    font-size: var(--font-size-display);
    line-height: 1;
    color: var(--color-success);
}

.global-grid-editor__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--spacing-sm);
    margin-bottom: var(--spacing-xs);
    font-weight: var(--font-weight-medium);
}

.global-grid-editor__nav {
    display: inline-flex;
    align-items: center;
    gap: var(--spacing-2xs);
}

.global-grid-editor__count {
    min-width: 3rem;
    text-align: center;
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-medium);
    color: var(--color-text-muted);
}

.global-grid-editor__arrow {
    padding: var(--spacing-2xs) var(--spacing-xs);
    line-height: 1;
}

.global-grid-editor__input {
    width: 100%;
    padding: var(--spacing-xs) var(--spacing-sm);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    font-size: var(--font-size-md);
    color: var(--color-text);
    background: var(--color-card-bg);
}

.global-grid-editor__input:focus {
    outline: none;
    box-shadow: var(--shadow-focus-ring);
}

.global-grid-editor__list {
    max-height: 14rem;
    overflow-y: auto;
    overscroll-behavior: contain;
    margin: 0;
    padding: 0;
    list-style: none;
}

.global-grid-editor__option,
.global-grid-picker__option {
    display: flex;
    align-items: center;
    gap: var(--spacing-sm);
    width: 100%;
    padding: var(--spacing-xs) var(--spacing-sm);
    border: 0;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--color-text);
    font-size: var(--font-size-md);
    text-align: left;
    cursor: pointer;
}

.global-grid-editor__option:hover,
.global-grid-editor__option.is-active {
    background: var(--color-surface-subtle);
}

.global-grid-editor__actions {
    display: flex;
    justify-content: flex-end;
    gap: var(--spacing-xs);
    padding-top: var(--spacing-xs);
}

/* Neutral ink, not the org's fill: controls on this platform are greyscale
   (Nick, 2026-09-01). */
.global-grid-editor__btn {
    padding: var(--spacing-xs) var(--spacing-sm);
    border: 0;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    cursor: pointer;
}

.global-grid-editor__btn:hover {
    color: var(--color-text);
    background: var(--color-surface-subtle);
}

.global-grid-editor__btn--primary,
.global-grid-editor__btn--primary:hover {
    background: var(--color-neutral-ink);
    color: var(--color-neutral-ink-fg);
}

.global-grid-editor__btn:disabled {
    cursor: default;
    opacity: 0.5;
}

/* ── The column picker ───────────────────────────────────────────────────── */
.global-grid-picker {
    position: absolute;
    z-index: var(--z-dropdown);
    width: 16rem;
    padding: var(--spacing-sm);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: var(--color-card-bg);
    box-shadow: var(--shadow-menu);
}

.global-grid-picker__search {
    width: 100%;
    margin-bottom: var(--spacing-xs);
    padding: var(--spacing-xs) var(--spacing-sm);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    font-size: var(--font-size-md);
}

.global-grid-picker__list {
    max-height: 16rem;
    overflow-y: auto;
    overscroll-behavior: contain;
    margin: 0;
    padding: 0;
    list-style: none;
}

.global-grid-picker__option:hover {
    background: var(--color-surface-subtle);
}

.global-grid-picker__option:disabled {
    color: var(--color-text-muted);
    cursor: default;
}

.global-grid-picker__option:disabled:hover {
    background: transparent;
}

/* The heading menu. Same surface as the picker, narrower, and its rows are the
   picker's own option rows. */
.global-grid-menu {
    position: absolute;
    z-index: var(--z-dropdown);
    width: 14rem;
    padding: var(--spacing-xs);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: var(--color-card-bg);
    box-shadow: var(--shadow-menu);
}
