/* AG Grid theme overrides.

   NOT wrapped in @layer (unlike the other split connect CSS files): every rule
   here overrides AG Grid's Quartz theme, which the JS Theming API injects
   UNLAYERED into <head>. Per the CSS cascade, unlayered declarations beat
   layered ones regardless of specificity — so these overrides must themselves
   stay unlayered to win. Wrapping them in `@layer infine.components` silently
   drops the field-state borders, cell alignment, and custom sort glyph
   (the b08a1d9 regression these rules were losing to). */
.connect-grid-wrap {
    padding: 0;
}

/* The sticky toolbar (#sticky-bar) provides its own xl side padding;
   the tip + grid get matching margins so everything aligns. */
.connect-grid-tip,
.connect-grid-host {
    margin: 0 var(--mantine-spacing-xl);
}

.connect-grid-host {
    /* Height is set inline by Grid: min(viewport-cap, content-height). No
       min-height — the frame should hug the rows, even when filtering down
       to a handful, so there's no empty gap below. */
    width: auto;
}

/* Header alignment to match ProductTable: bottom-aligned label, uppercase
   would break long labels so we keep mixed case but match font/colour/weight.
   Active sort column gets the darker blue (--infine-blue) bg. */
.connect-grid-host .ag-header-cell {
    align-items: flex-end;
}

.connect-grid-host .ag-header-cell-label {
    align-items: flex-end;
    padding-bottom: 4px;
    line-height: 1.25;
}

/* Active sort column gets the darker blue (--infine-blue) bg.
   AG Grid attaches `.ag-header-cell-sorted-asc/-desc` to the inner
   `.ag-cell-label-container`, so we target the parent header cell via :has(). */
.connect-grid-host .ag-header-cell:has(.ag-header-cell-sorted-asc),
.connect-grid-host .ag-header-cell:has(.ag-header-cell-sorted-desc) {
    background-color: var(--infine-blue) !important;
}

/* Replace AG Grid's icon-font sort glyph with chevron-up/chevron-down
   matching the existing ProductTable. Hide the default font-icon glyph
   inside the active sort indicator, then paint our own via ::before. */
.connect-grid-host .ag-sort-indicator-icon:not(.ag-hidden) .ag-icon {
    display: none;
}

.connect-grid-host .ag-sort-ascending-icon:not(.ag-hidden)::before,
.connect-grid-host .ag-sort-descending-icon:not(.ag-hidden)::before {
    content: "";
    display: inline-block;
    width: 14px;
    height: 14px;
    background-color: white;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-position: center;
    mask-position: center;
    -webkit-mask-size: contain;
    mask-size: contain;
    flex-shrink: 0;
    vertical-align: middle;
}

/* Tabler chevron-up */
.connect-grid-host .ag-sort-ascending-icon:not(.ag-hidden)::before {
    -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M6 15l6 -6l6 6'/></svg>");
    mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M6 15l6 -6l6 6'/></svg>");
}

/* Tabler chevron-down */
.connect-grid-host .ag-sort-descending-icon:not(.ag-hidden)::before {
    -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M6 9l6 6l6 -6'/></svg>");
    mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M6 9l6 6l6 -6'/></svg>");
}

/* Manual shift+click range highlight (Community AG Grid lacks the
   CellSelectionModule). Painted via direct DOM class toggling in JS. */
.connect-grid-host .ag-cell.connect-grid-cell-in-range {
    background-color: var(--infine-blue-light-fade) !important;
    box-shadow: inset 0 0 0 1px var(--infine-blue-light);
}

/* Required-but-empty cells: yellow background + orange bottom border so
   suppliers can spot mandatory data they still need to fill in. Bottom-
   only border keeps a row of empty cells visually calm — an all-sides
   highlight gets noisy when many cells are missing. */
.connect-grid-host .ag-cell.connect-grid-cell-required-empty {
    background-color: var(--infine-yellow-bg);
    border-bottom: 1px solid var(--infine-yellow-bright);
}

/* N/A cells: subtle grey so the user sees at a glance which fields don't
   apply to this row's product. Pairs with `editable: false` on the col-def
   so the cell never enters edit mode — the colour communicates the cause. */
.connect-grid-host .ag-cell.connect-grid-cell-na {
    background-color: var(--mantine-color-gray-0);
    color: var(--mantine-color-gray-6);
    cursor: default;
}

/* Error skin escalates above required-empty: red tint, 3 px red bottom
   border, and a red corner triangle so errors survive at narrow column
   widths. AG Grid's native tooltip surfaces the message on hover.

   Drawn as a real `border-bottom` (like the required-empty orange), not an
   inset box-shadow: the shadow floats inside the padding box, leaving Quartz's
   own cell border visible below it as a hairline gap. A border replaces that
   edge outright, so the red sits flush to the cell's bottom. */
.connect-grid-host .ag-cell.connect-grid-cell-error {
    background-color: var(--infine-red-bg);
    border-bottom: 3px solid var(--infine-red-bright);
    cursor: help;
}
.connect-grid-host .ag-cell.connect-grid-cell-error::after {
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    width: 0;
    height: 0;
    border-style: solid;
    border-width: 0 8px 8px 0;
    border-color: transparent var(--infine-red-bright) transparent transparent;
    pointer-events: none;
}

/* Required-field column header: render the orange SVG asterisk inside the
   text span (so it hugs the column title), then the optional footnote digit
   immediately after via the label-level pseudo. Order in the rendered cell:
   "Column title  *  N" — asterisk close to text, digit close to asterisk.

   The asterisk lives on `.ag-header-cell-text::after` because that pseudo
   sits inline-flush with the text content; `.ag-header-cell-label::after` is
   the last flex child of the label and is reserved for the optional digit. */
.connect-grid-host .ag-header-cell.connect-grid-required-header .ag-header-cell-text::after {
    content: "";
    display: inline-block;
    width: 12px;
    height: 12px;
    margin-left: 4px;
    background-color: var(--infine-yellow-bright);
    -webkit-mask: url("/required-marker.svg") no-repeat center / contain;
    mask: url("/required-marker.svg") no-repeat center / contain;
    vertical-align: middle;
    flex-shrink: 0;
}

/* Conditionally-required header variants — append a plain-digit footnote
   marker after the asterisk via `.ag-header-cell-label::after`. `--1` =
   private label only, `--2` = risk ingredients only, `--3` = certain
   ingredients only, `--1-2` = private label OR risk ingredients (rendered
   as both digits side-by-side; supersedes the older `--4` variant). */
.connect-grid-host .ag-header-cell.connect-grid-required-header--1   .ag-header-cell-label::after { content: "1"; }
.connect-grid-host .ag-header-cell.connect-grid-required-header--2   .ag-header-cell-label::after { content: "2"; }
.connect-grid-host .ag-header-cell.connect-grid-required-header--3   .ag-header-cell-label::after { content: "3"; }
.connect-grid-host .ag-header-cell.connect-grid-required-header--1-2 .ag-header-cell-label::after { content: "1 2"; }
.connect-grid-host .ag-header-cell[class*="connect-grid-required-header--"] .ag-header-cell-label::after {
    color: var(--infine-yellow-bright);
    font-weight: 700;
    font-size: 11px;
    margin-left: 2px;
    vertical-align: baseline;
    flex-shrink: 0;
}

/* Sticky-column shadow — soft right-edge gradient on the left-pinned region
   and matching left-edge gradient on the right-pinned region. Mirrors the
   .product-table treatment used in Evaluation/Catalogue. We attach the
   pseudo-elements to AG Grid's pinned containers and let them spill into
   the body scroll area. Static (always visible) since the Connect grid is
   virtually always horizontally scrollable. */
.connect-grid-host .ag-pinned-left-cols-container,
.connect-grid-host .ag-pinned-left-header {
    position: relative;
}
.connect-grid-host .ag-pinned-left-cols-container::after,
.connect-grid-host .ag-pinned-left-header::after {
    content: '';
    position: absolute;
    top: 0; right: 0; bottom: 0;
    width: 10px;
    transform: translateX(100%);
    background: linear-gradient(to right, rgba(0, 0, 0, 0.04), transparent);
    pointer-events: none;
    z-index: 2;
}
.connect-grid-host .ag-pinned-right-cols-container,
.connect-grid-host .ag-pinned-right-header {
    position: relative;
}
.connect-grid-host .ag-pinned-right-cols-container::before,
.connect-grid-host .ag-pinned-right-header::before {
    content: '';
    position: absolute;
    top: 0; left: 0; bottom: 0;
    width: 10px;
    transform: translateX(-100%);
    background: linear-gradient(to left, rgba(0, 0, 0, 0.04), transparent);
    pointer-events: none;
    z-index: 2;
}

/* Footnote legend strip below the grid — keys the conditional-required
   markers used in column headers. */
.connect-grid-legend {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 4px 24px;
    padding: 8px 32px 4px;
    font-size: 11px;
    color: var(--mantine-color-gray-7);
}
.connect-grid-legend-item {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.connect-grid-legend-item--note {
    color: var(--mantine-color-gray-7);
}
.connect-grid-legend-marker {
    color: var(--infine-yellow-bright);
    font-weight: 700;
    min-width: 16px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
/* Plain-* legend marker reuses the SVG-mask asterisk for visual parity with
   the column-header treatment of always-required fields. */
.connect-grid-legend-marker--star {
    width: 12px;
    height: 12px;
    background-color: var(--infine-yellow-bright);
    -webkit-mask: url("/required-marker.svg") no-repeat center / contain;
    mask: url("/required-marker.svg") no-repeat center / contain;
    /* Reset flex-item shrink/min-width so the SVG mask keeps its 12x12 box
       even when paired with a digit sibling inside a legend item. */
    flex-shrink: 0;
}
/* Plain digit paired with the SVG asterisk in a numbered legend variant.
   Negative margin pulls the digit flush against the asterisk (overriding the
   parent .connect-grid-legend-item flex `gap: 6px` between the two markers
   while leaving the gap to the description text intact). */
.connect-grid-legend-marker-digit {
    color: var(--infine-yellow-bright);
    font-weight: 700;
    margin-left: -6px;
}

/* Popup cell editor for long text fields — agLargeTextCellEditor in popup
   mode renders into .ag-popup-editor with .ag-large-text inside. Soft shadow
   and brand border so the floating editor reads as part of the Connect UI
   rather than AG Grid's default. */
.connect-grid-host .ag-popup-editor.ag-large-text {
    border: 1px solid var(--infine-blue-light);
    border-radius: 6px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
    background: white;
}
.connect-grid-host .ag-popup-editor.ag-large-text textarea.ag-input-field-input {
    padding: 8px 10px;
    font-family: inherit;
    font-size: 13px;
    line-height: 1.45;
}

/* Inline cell editing — mirror the focused-input chrome on the form
   so the editing affordance reads consistently across both surfaces.
   Resting cell colours, striping, and required-empty markers are
   AG Grid's; we only retheme the editing state. AG Grid's own
   `.ag-cell-inline-editing` rule uses `!important` on `border`, so we
   match it to land the brand colour. */
.connect-grid-host .ag-cell.ag-cell-inline-editing {
    background: white;
    border: 1px solid var(--infine-blue-bright) !important;
    box-shadow: 0 0 0 3px rgb(from var(--infine-blue-bright) r g b / 0.12);
    padding: 0;
}
.connect-grid-host .ag-cell.ag-cell-inline-editing .ag-input-field-input,
.connect-grid-host .ag-cell.ag-cell-inline-editing input.ag-text-field-input,
.connect-grid-host .ag-cell.ag-cell-inline-editing select {
    background: white;
    color: var(--infine-text);
    border: 0;
}

/* Expand-record column — left-pinned, 32 px wide. Resting state shows a
   small, light row number in the technical mono face so the column doesn't
   read as missing content. Row hover swaps the number for the expand icon
   (Airtable / Notion / Linear convention). Hovering the icon itself scales
   it up + tints brand-blue for a clear hit cue. Click navigates to the
   single-product view scoped to that row's product. */
.connect-grid-host .ag-cell.connect-grid-open-cell {
    padding: 0 !important;
}

.connect-grid-open-btn {
    position: relative;
    width: 100%;
    height: 100%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--mantine-color-gray-6);
    cursor: pointer;
}

.connect-grid-open-num {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    font-size: 10px;
    line-height: 1;
    color: var(--mantine-color-gray-4);
    pointer-events: none;
    transition: opacity 120ms ease;
}

.connect-grid-open-btn > svg {
    opacity: 0;
    transform: scale(1);
    transform-origin: center;
    transition: opacity 120ms ease, transform 140ms ease, color 120ms ease;
}

/* Row hover (any pinned segment) or keyboard focus: number → icon. AG Grid
   adds .ag-row-hover to every DOM segment that belongs to the same row, so
   hovering a body cell still reveals the icon in the left-pinned column. */
.connect-grid-host .ag-row.ag-row-hover .connect-grid-open-num,
.connect-grid-open-btn:focus-visible .connect-grid-open-num {
    opacity: 0;
}

.connect-grid-host .ag-row.ag-row-hover .connect-grid-open-btn > svg,
.connect-grid-open-btn:focus-visible > svg {
    opacity: 1;
}

/* Direct hover over the icon: pop + tint to make the affordance unmistakable. */
.connect-grid-open-btn:hover > svg {
    transform: scale(1.25);
    color: var(--infine-blue);
}

/* Hovering the icon button also tints the entire row one shade darker than
   the AG Grid row-hover blue (--infine-blue-bg → --infine-blue-light-fade)
   so the action's row scope is unmistakable. The class is toggled in JS
   because AG Grid splits each row across multiple DOM containers. The
   :not() guards keep the persistent yellow / range backgrounds intact. */
.connect-grid-host .ag-row.connect-grid-row-icon-hover .ag-cell:not(.connect-grid-cell-required-empty):not(.connect-grid-cell-error):not(.connect-grid-cell-na):not(.connect-grid-cell-in-range) {
    background-color: var(--infine-blue-light-fade);
}

.connect-grid-open-btn:focus-visible {
    outline: 2px solid var(--infine-blue);
    outline-offset: -3px;
    border-radius: 3px;
}

/* Two-blink tint on the row the user just returned from in single view. The
   class is added on grid-mount (to every row segment — left-pinned, body,
   right-pinned — since AG Grid splits rows across containers) once we've
   scrolled the row into view, then stripped after the animation finishes.
   Excludes the required-empty cells so we don't fight with their persistent
   yellow background. */
@keyframes connect-grid-row-just-viewed-flash {
    0%   { background-color: var(--infine-blue-light); }
    25%  { background-color: transparent; }
    50%  { background-color: var(--infine-blue-light); }
    100% { background-color: transparent; }
}

.connect-grid-host .ag-row.connect-grid-row-just-viewed .ag-cell:not(.connect-grid-cell-required-empty):not(.connect-grid-cell-error):not(.connect-grid-cell-na) {
    animation: connect-grid-row-just-viewed-flash 1600ms ease-out forwards;
}

/* Status cell renderer.

   The column used to repeat "In progress" or "Complete" text down every row,
   with a tiny percentage tucked to the right. Replaced with a horizontal
   completion bar that carries the same info in a single glance: fill width is
   the ratio, fill color encodes state (amber while in progress, green when
   complete). The trailing % stays as a tabular number for precise reads.
   Same shape as the single-product header bar, just thinner and inline. */
.connect-grid-host .ag-cell.connect-grid-status-cell {
    display: flex;
    align-items: center;
}

.connect-grid-status {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
}

.connect-grid-status-bar {
    flex: 1 1 auto;
    min-width: 0;
    height: 6px;
    background: var(--mantine-color-gray-2);
    border-radius: 3px;
    overflow: hidden;
}

.connect-grid-status-bar-fill {
    display: block;
    height: 100%;
    border-radius: 3px;
    transition: width 240ms cubic-bezier(0.22, 1, 0.36, 1),
                background-color 240ms ease;
}

/* Trailing percentage — tabular mono so digits don't jitter row-to-row while
   the column is sorted/filtered. Quiet grey, lets the bar carry the signal. */
.connect-grid-status-pct {
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    font-size: 11px;
    font-weight: normal;
    line-height: 1;
    color: var(--mantine-color-gray-6);
    flex-shrink: 0;
    min-width: 30px;
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* Per-row error count column. Empty rows render nothing; rows with errors get
   a compact red pill. Red is reserved for validator errors in this grid — the
   status column never uses red, so the two signals stay disambiguated. */
.connect-grid-host .ag-cell.connect-grid-error-count-cell {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
}

.connect-grid-error-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 22px;
    height: 20px;
    padding: 0 6px;
    border-radius: 10px;
    font-size: 11px;
    font-weight: 700;
    line-height: 1;
    color: white;
    background-color: var(--infine-red-bright);
}
