.cg-record-backdrop { position: fixed; inset: 0; z-index: var(--cg-z-drawer); display: grid; place-items: center; padding: 24px; background: rgba(25, 34, 46, 0.34); backdrop-filter: blur(1px); } .cg-record-modal { width: min(1120px, calc(100vw - 48px)); height: min(760px, calc(100vh - 48px)); min-height: 420px; display: flex; flex-direction: column; overflow: hidden; border: 1px solid color-mix(in srgb, var(--lp-line) 82%, var(--lp-muted)); border-radius: 12px; background: var(--lp-surface); box-shadow: 0 30px 80px rgba(20, 30, 43, 0.24), 0 4px 18px rgba(20, 30, 43, 0.12); color: var(--lp-ink); font-family: Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif; font-size: var(--lp-fs-xs); animation: cg-record-open 150ms cubic-bezier(0.2, 0, 0, 1); } .cg-record-modal:focus { outline: none; } /* Universal linked-record viewer: the target is the real Grid surface, not a JSON-shaped approximation. It is deliberately wider than the record detail so filtering and multi-column sorting have the same working room they do on the database page. */ .cg-link-grid-modal { width: min(1320px, calc(100vw - 48px)); height: min(840px, calc(100vh - 48px)); min-height: 460px; display: flex; flex-direction: column; overflow: hidden; border: 1px solid color-mix(in srgb, var(--lp-line) 82%, var(--lp-muted)); border-radius: 12px; background: var(--lp-surface); box-shadow: 0 30px 80px rgba(20, 30, 43, 0.24), 0 4px 18px rgba(20, 30, 43, 0.12); color: var(--lp-ink); font-family: Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif; font-size: var(--lp-fs-xs); animation: cg-record-open 150ms cubic-bezier(0.2, 0, 0, 1); } .cg-link-grid-modal:focus { outline: none; } .cg-link-grid-head { flex: 0 0 54px; min-height: 54px; display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 0 14px 0 18px; border-bottom: 1px solid var(--lp-line); background: var(--lp-surface); } .cg-link-grid-title { font-size: var(--lp-fs-sm); font-weight: 650; line-height: 1.2; } .cg-link-grid-sub { margin-top: 2px; color: var(--lp-muted); font-size: var(--lp-fs-3xs); } .cg-link-grid-body { flex: 1 1 auto; min-width: 0; min-height: 0; background: var(--lp-surface); } .cg-link-grid-foot { flex: 0 0 52px; display: flex; align-items: center; justify-content: flex-end; gap: 8px; padding: 8px 14px; border-top: 1px solid var(--lp-line); background: var(--lp-surface); } @keyframes cg-record-open { from { opacity: 0; transform: translateY(8px) scale(0.992); } } .cg-record-modal > .cg-detail-header { height: 46px; padding: 0 12px; background: var(--lp-surface); } .cg-record-layout { flex: 1 1 auto; min-height: 0; display: grid; grid-template-columns: minmax(0, 1.95fr) minmax(300px, 0.95fr); } .cg-record-modal--single { width: min(880px, calc(100vw - 48px)); } .cg-record-modal--single .cg-record-layout { grid-template-columns: minmax(0, 1fr); } .cg-record-main { min-width: 0; min-height: 0; display: flex; flex-direction: column; } .cg-record-main .cg-detail-titlewrap { padding: 22px 28px 18px; } .cg-record-main .cg-detail-title { font-size: var(--lp-fs-lg); line-height: 1.25; } .cg-record-main .cg-detail-body { min-height: 0; padding: 4px 12px 28px; scrollbar-gutter: stable; } .cg-record-main .cg-detail-section { padding: 16px; } /* ========================================================================== Wave 2026-08-02 item 2 — the record fields: no yellow, one subtle box. ========================================================================== Owner: "kill yellow, subtle outline for all field types." Before this, exactly one kind of field had a treatment — the editable overlay notes, in a gold frame on a gold wash (index.css:2027) — and every other field was bare text under a hairline. So the loudest thing in the panel was also the least important, and the panel had two layouts: label ABOVE a full-width textarea for notes, label BESIDE the value for the rest. Now every field is one row on one grid: label left, a value SLOT right. The slot carries a 1px --lp-line hairline and --lp-r-md corners, and the fill is what says whether it is yours: --lp-surface-2 (warm grey) read-only — an Odoo attribute, a picked choice, a star rating you set from the table --lp-surface (white) editable — type here That replaces the signal the yellow wash used to carry (this stratum is your data, not the ERP's) with one that is also an affordance: the bright slots are the ones that respond. Interaction, not decoration, marks them. EVERY rule here is scoped `.cg-record-main …` so it (a) outranks the index.css base block, which is FROZEN for the other sessions this wave, and (b) stops at the record modal — the same `.cg-detail-*` classes dress surfaces this file does not own. Specificity, never source order: the :focus and ::placeholder overrides below exist because their index.css counterparts tie at (0,2,0) and (0,1,1), and a tie is decided by bundle order — which is not a thing to bet a gold glow on. */ .cg-record-main .cg-detail-field { min-height: 0; align-items: flex-start; gap: 12px; padding: 3px 0; /* The hairline separator is REPLACED by the box, not stacked under it — a ruled row around a bordered slot reads as a rendering fault. */ border-bottom: none; } .cg-record-main .cg-detail-label { flex: 0 0 160px; /* Optical, not arithmetic: 7px lands the 12px label on the same line as the 13px value inside its 1px border + 5px padding. */ padding-top: 7px; color: var(--lp-muted); font-size: var(--lp-fs-2xs); line-height: 1.45; } .cg-record-main .cg-detail-value { min-height: 30px; padding: 5px 9px; border: 1px solid var(--lp-line); border-radius: var(--lp-r-md); background: var(--lp-surface-2); line-height: 1.45; } /* ⭐ Wave-23 C8 (owner item 4 / ruling R9) — a MACHINE-OWNED field's value slot. `--lp-machine-tint` is EXACTLY what the canvas wash (`theme.MACHINE_CELL`, `washOf(LP_MACHINE_DEEP, 0.12)`) composites to over white, so the drawer slot and the grid cell are one grey rather than two that were each picked to look right on their own — the sibling-panel rule (DESIGN.md §2) applied across two rendering technologies instead of two panes. THE VALUE KEEPS ITS INK, deliberately, on both surfaces. The wash is the whole signal; dimming the number as well would say the figure matters less, and an automation-written follower count is the entire reason its column exists. Background only — no border change, no second marker. The column menu already says "Filled by automation" once, and DESIGN.md §4 is that the app does not narrate itself twice. */ .cg-record-main .cg-detail-field.is-machine .cg-detail-value { background: var(--lp-machine-tint); } /* A rating's marks are 18px inline SVG; on the text baseline they hang their descender space below the line box and grow the slot past every neighbour. */ .cg-record-main .cg-detail-value .cg-stars { vertical-align: middle; } /* An editable field is the same ROW as every other one now — index.css stacks it (flex-direction: column, and a label with `flex: none`), which is what made the notes the odd block out. */ .cg-record-main .cg-detail-field--edit { flex-direction: row; align-items: flex-start; gap: 12px; } .cg-record-main .cg-detail-field--edit .cg-detail-label { flex: 0 0 160px; } /* The value column of an editable row: the box, then its action link. */ .cg-detail-editwrap { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; } .cg-record-main .cg-detail-textarea { /* The owner's "big static box" was min-height: 76px. One row is the resting size; AutoTextarea grows it from there, so an empty note is as quiet as an empty value and a long one is readable without a scrollbar. */ min-height: 30px; max-height: 260px; padding: 5px 9px; overflow-y: auto; /* The height is measured, so a drag handle would fight the measurement: the next keystroke re-fits and snaps back whatever was dragged. */ resize: none; border: 1px solid var(--lp-line); background: var(--lp-surface); line-height: 1.45; } .cg-record-main .cg-detail-textarea:hover:not(:focus) { border-color: color-mix(in srgb, var(--lp-line) 45%, var(--lp-muted)); } .cg-record-main .cg-detail-textarea:focus { /* Identical to the comment composer below — same modal, same gesture, so the same mark. `box-shadow: none` is load-bearing: without it index.css:2047's 3px gold glow survives an override that only changes the border. */ outline: 2px solid var(--lp-blue-deep); outline-offset: -1px; border-color: transparent; box-shadow: none; } .cg-record-main .cg-detail-textarea::placeholder { /* --lp-muted is the palette's body-safe grey (4.83:1). The stock #a2a2ac was picked against the gold wash and reads as 2.7:1 on white — and "Add notes…" is an instruction, not decoration. */ color: var(--lp-muted); opacity: 1; } /* A checkbox IS its own control; boxing it would frame a 15px square in a 30px slot and say nothing. It only needs to sit on the label's line. */ .cg-record-main .cg-detail-checkbox { margin-top: 7px; } /* ========================================================================== Wave 14 item 9 — an editor for EVERY user-created field type. ========================================================================== Until now one type was editable here (notes) and the other eight read. The affordance law item 2 established is what makes this scale without a legend: --lp-surface-2 (warm grey) read-only --lp-surface (white) yours to change so `--live` is the ONLY thing that says "this responds", across nine row shapes. It is deliberately the same white the textarea already used, not a new colour: adding a third fill would turn a two-state signal into a puzzle. ONE BOX PER ROW. The controls are borderless and transparent INSIDE the slot rather than bordered themselves — a bordered input inside a bordered slot draws two rectangles 1px apart, which reads as a rendering fault, and it would also break the single label-left/value-right grid every other row sits on. The focus ring therefore lands on the SLOT (`:focus-within`) and the control's own outline is suppressed; the ring is the same 2px inset blue as the textarea and the comment composer, because it is the same gesture in the same modal. ⚠ `font: inherit` is NOT used on these controls. The `font` shorthand RESETS `font-variant-numeric`, which `.cg-detail-value` sets to tabular-nums (index.css:2013) — so the shorthand would silently un-align every number in the panel. The longhands are spelled out instead. */ .cg-record-main .cg-detail-value--live { background: var(--lp-surface); } .cg-record-main .cg-detail-value--live:hover:not(:focus-within) { border-color: color-mix(in srgb, var(--lp-line) 45%, var(--lp-muted)); } .cg-record-main .cg-detail-value--live:focus-within { outline: 2px solid var(--lp-blue-deep); outline-offset: -1px; border-color: transparent; } /* The slot as a ROW: an avatar, a currency mark or a hint sits beside its control instead of above it. */ .cg-record-main .cg-detail-pickslot { display: flex; align-items: center; gap: 7px; } .cg-record-main .cg-detail-select, .cg-record-main .cg-detail-input { flex: 1 1 auto; min-width: 0; width: 100%; padding: 0; border: 0; background: transparent; color: var(--lp-ink); font-family: inherit; font-size: inherit; font-weight: inherit; line-height: 1.45; } /* The ring is on the slot; a second one inside it would draw a rectangle around a rectangle. */ .cg-record-main .cg-detail-select:focus, .cg-record-main .cg-detail-input:focus { outline: none; } .cg-record-main .cg-detail-select { /* The native arrow is kept — it is the only thing that says "pick" once the border has been handed to the slot. */ cursor: pointer; margin-left: -2px; } .cg-record-main .cg-detail-input--num { text-align: right; } /* Spinners removed, and not for looks: this panel SCROLLS, and a wheel event over a focused number input changes the value in Chrome. A currency figure silently edited by scrolling past it is data loss with no gesture behind it. The right-aligned tabular figure and the unit mark carry the type. */ .cg-record-main .cg-detail-input--num::-webkit-outer-spin-button, .cg-record-main .cg-detail-input--num::-webkit-inner-spin-button { appearance: none; margin: 0; } .cg-record-main .cg-detail-input--num { -moz-appearance: textfield; appearance: textfield; } .cg-record-main .cg-detail-unit, .cg-record-main .cg-detail-hint { flex: 0 0 auto; color: var(--lp-muted); font-size: var(--lp-fs-2xs); } .cg-record-main .cg-detail-hint { font-style: italic; } .cg-record-main .cg-detail-nochoice { color: var(--lp-muted); font-size: var(--lp-fs-2xs); } /* Multiselect: a chip row, not a `