/* Page-level layout: cards, tables, stat tiles, thumbnails, flags. */
.card { background: var(--net-bg-card); border: 1px solid var(--net-border); border-radius: var(--net-border-radius-md); padding: var(--net-spacing-lg); margin-bottom: var(--net-spacing-lg); box-shadow: var(--net-shadow-base); }
.card h2 { display: flex; align-items: center; gap: 0.5rem; }
.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: var(--net-spacing-lg); }
.stat-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--net-spacing-md); margin-bottom: var(--net-spacing-lg); }
.stat-tile { background: var(--net-bg-card); border: 1px solid var(--net-border); border-radius: var(--net-border-radius-md); padding: var(--net-spacing-md); }
.stat-tile .value { font-size: var(--net-font-size-xl); font-weight: 700; font-variant-numeric: tabular-nums; }
.is-neg { color: var(--dp-money-bad); }
/* Money colours (theme.css tokens): apply to any amount that is a flow or a problem. */
.money-in  { color: var(--dp-money-in); }
.money-out { color: var(--dp-money-out); }
.money-bad { color: var(--dp-money-bad); font-weight: 700; }
/* Money that has not moved yet - expected (promised, not issued) or owed (not paid): the flow's colour, but quieter. */
.money-in.is-soft, .money-out.is-soft { opacity: 0.75; font-style: italic; font-weight: 400; }
.stat-tile .sub { font-size: var(--net-font-size-xs); margin-top: 0.15rem; }
/* An auto claim's one row: when both the rental and the towing have a limit, two thin bars, each named. */
.coverage-row.is-auto .auto-bar { display: grid; grid-template-columns: 4rem 1fr; align-items: center; gap: 0.5rem; }
.coverage-row.is-auto .auto-bar small { font-size: var(--net-font-size-xs); }
.coverage-row.is-auto .auto-bar + .auto-bar { margin-top: 0.2rem; }
.badge.money-in  { background: var(--dp-money-in-soft);  color: var(--dp-tint-ok-text); }
.badge.money-out { background: var(--dp-money-out-soft); color: var(--dp-tint-warn-text); }
.badge.money-bad { background: var(--dp-money-bad-soft); color: var(--dp-tint-bad-text); }
.stat-tile.money-in .value  { color: var(--dp-money-in); }
.stat-tile.money-out .value { color: var(--dp-money-out); }
.stat-tile.money-bad .value { color: var(--dp-money-bad); }
.progress > span.is-out { background: var(--dp-money-out); }
.progress > span.is-bad { background: var(--dp-money-bad); }
.progress > span.is-unpaid { background: color-mix(in srgb, var(--dp-money-bad) 78%, #5a1a26); }   /* unreimbursed: out of pocket on an advance (dp_money_bar, no limit) */
/* Two segments in one bar (Coverage C): what the carrier paid, then what is claimed beyond it. */
.progress.is-stacked { display: flex; }
.progress.is-stacked > span { flex: 0 0 auto; }
.progress > span.is-in { background: var(--dp-money-in); }
.progress > span.is-out-soft { background: var(--dp-money-out-soft); }
.progress > span.is-in-soft { background: var(--dp-money-in-soft); }     /* an advance paid but not spent yet (dp_money_bar) */   /* the not-yet part of a claim (Coverage B) */
.stat-tile.is-link { display: block; text-decoration: none; color: inherit; }
.stat-tile.is-link:hover { border-color: var(--net-color-primary); text-decoration: none; }
.tl-recent-row { padding: 0.3rem 0; border-bottom: 1px dashed var(--net-border); font-size: var(--net-font-size-sm); }
.tl-recent-row:last-child { border-bottom: 0; }
.tl-recent-when { display: inline-block; width: 6.5rem; }
/* Overview's recent events: date · title (takes the room) · every badge, right-aligned; on a narrow screen the badges wrap under. */
.tl-recent-row { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 0.75rem; row-gap: 0.25rem; }
.tl-recent-when { flex: 0 0 6.5rem; }
.tl-recent-title { flex: 1 1 16rem; min-width: 0; }
.tl-recent-tags { display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: 0.25rem; margin-left: auto; }
.tl-recent-tags .badge { display: inline-flex; align-items: center; margin: 0; line-height: 1.45; }
.tl-chip { display: inline-block; padding: 0 0.45rem; border-radius: var(--net-border-radius-xl); background: var(--net-bg-accent); text-decoration: none; color: inherit; white-space: nowrap; }
.tl-chip.is-on { background: var(--net-color-primary); color: #fff; }
/* Category chips behind a disclosure on the summary line (Timeline page, Overview's Timeline panel). */
.tl-cats > summary { cursor: pointer; list-style: none; user-select: none; }
.tl-cats > summary::-webkit-details-marker { display: none; }
.tl-cats-toggle { text-decoration: underline dotted; }
.tl-cats-toggle::after { content: ' ▸'; }
.tl-cats[open] .tl-cats-toggle::after { content: ' ▾'; }
.tl-cats-list { display: flex; flex-wrap: wrap; gap: 0.3rem 0.4rem; margin-top: var(--net-spacing-sm); }
.stat-tile .label { font-size: var(--net-font-size-xs); color: var(--net-text-muted); text-transform: uppercase; letter-spacing: 0.05em; }

.table-wrap { overflow-x: clip; /* no scroll box: headers stick to the page, ui.tablescroll.js pans a wide table from a bar pinned at the bottom */ background: var(--net-bg-card); border: 1px solid var(--net-border); border-radius: var(--net-border-radius-md); }
table.data { width: 100%; border-collapse: collapse; font-size: var(--net-font-size-sm); }
table.data th, table.data td { padding: 0.5rem 0.5rem; border-bottom: 1px solid var(--net-border); text-align: left; vertical-align: middle; white-space: nowrap; }
table.data th { background: var(--net-bg-accent); font-weight: 600; position: sticky; top: var(--dp-top-offset, var(--net-header-height)); z-index: var(--net-z-raised); }   /* frozen under the top bar on every list (owner, 2026-10-06; the offset is measured by ui.tablescroll.js) */
/* Sort by column (ui.tablesort.js, every data table): a sortable header shows a faint ⇅, the sorted one ▲ / ▼. */
table.data th.is-sortable { cursor: pointer; user-select: none; }
table.data th.is-sortable:hover { color: var(--net-color-primary); }
table.data th.is-sortable::after { content: ' \21C5'; opacity: 0.3; font-size: 0.8em; }
table.data th.is-sorted-asc::after { content: ' \25B2'; opacity: 1; }
table.data th.is-sorted-desc::after { content: ' \25BC'; opacity: 1; }
table.data td.wrap, table.data th.wrap { white-space: normal; min-width: 220px; }
/* A wrapping cell must be able to break a long part number ("W11256462/WPW10492276/…"), or that one
   token sets the column's minimum width and pushes the whole grid into a horizontal scroll. */
table.data td.wrap { overflow-wrap: anywhere; }
/* Cells whose badge may drop under the value instead of widening the column (room + "post-loss"). */
table.data td.stack { white-space: normal; }
table.data td.stack .badge { white-space: nowrap; }
table.data td.num, table.data th.num { text-align: right; font-variant-numeric: tabular-nums; }
/* Controls inside table cells: no form spacing, top-aligned so the inputs of a
   row line up even when one cell carries a caption under its field, and numeric
   fields pushed right under their right-aligned headers. */
table.data td > .ctrl-wrapper { margin-bottom: 0; }
table.data td:has(> .ctrl-wrapper) { vertical-align: top; }
table.data td.num > .ctrl-wrapper { margin-left: auto; }
/* .table-pick: a dropdown in a table cell takes its column's width instead of
   forcing a sideways scroll (a percentage width lets the table shrink it, down
   to the min-width). Long labels are shortened server-side so what a narrow box
   clips is never the part that matters (Settings people: the claim number). */
table.data td > .ctrl-wrapper.table-pick { min-width: 10rem; }
table.data .table-pick .ctrl-field { width: 100%; max-width: 24rem; }
/* The same value shown as text (your own row) may wrap, or it would hold the column open. */
table.data .table-pick-text { white-space: normal; }
table.data tbody tr:hover { background: var(--net-bg-accent); }
/* A line outside the claim (a not-in-claim category) or a cancelled order line: everyone can ignore
   it, so the whole row recedes - text, badges and the name alike - and comes forward on hover. */
table.data tbody tr.muted > td { opacity: 0.45; }
table.data tbody tr.muted:hover > td { opacity: 0.85; }
table.data tbody tr.is-noclaim a.item-name, table.data tbody tr.is-component a.item-name { color: var(--net-text-muted); font-weight: 400; }
/* Settings > People: a person's row opens its name / email editor row under it (local.people.js). */
table.data tr.user-row { cursor: pointer; }
table.data tr.user-row.is-editing, table.data tr.user-editor { background: var(--dp-edit-row); }
table.data tr.user-editor:hover { background: var(--dp-edit-row); }
tr.user-editor .field-row { align-items: flex-end; margin-bottom: 0.25rem; }
tr.user-editor small { font-size: var(--net-font-size-xs); }
/* A full-width editor row in a table wider than its wrap: the fields stay in the VISIBLE part - shifted by the pan, capped
   at the wrap's width (ui.tablescroll.js sets both vars), so Name / Email / Done never run off screen (2026-10-07). */
table.data tr[data-for] > td.sub { white-space: normal; }
table.data tr[data-for] > td.sub > * {
    box-sizing: border-box; max-width: calc(var(--dp-wrap-w, 100%) - 1.5rem);
    transform: translateX(var(--dp-pan, 0px));
}
tr.user-editor .field-row { flex-wrap: wrap; }
table.data tr.user-editor > td.sub > .user-merge { margin-top: var(--net-spacing-sm); padding-top: var(--net-spacing-sm); border-top: 1px dashed var(--net-border); max-width: min(48rem, calc(var(--dp-wrap-w, 100%) - 1.5rem)); }
tr.user-editor .field-row > .ctrl-wrapper { min-width: 0; margin-bottom: 0; }
/* Done sits centred on the boxes, whatever their height in the layout: the actions stretch to the row, the label-high
   padding (ui.forms.css) skips the label line, and the button centres in the box-high rest. */
table.data tr.user-editor .field-row > .filter-actions { align-self: stretch; margin-bottom: 0; align-items: center; }
table.data tbody tr.is-picked { background: var(--dp-picked-row); }
table.data tbody tr[data-href] { cursor: pointer; }
table.data .grip { cursor: grab; color: var(--net-text-muted); user-select: none; }
table.data tr.is-dragging { opacity: 0.4; }
table.data tr.drop-before td { box-shadow: inset 0 2px 0 var(--net-color-primary); }
table.data tr.drop-after  td { box-shadow: inset 0 -2px 0 var(--net-color-primary); }

.toolbar { display: flex; flex-wrap: wrap; gap: var(--net-spacing-sm); align-items: center; margin-bottom: var(--net-spacing-md); }
.toolbar .ctrl-wrapper { margin: 0; flex: 0 1 220px; }
.toolbar .spacer { flex: 1 1 auto; }
.summary-line { font-size: var(--net-font-size-sm); color: var(--net-text-muted); margin: var(--net-spacing-sm) 0; }

.badge { display: inline-block; padding: 0.1rem 0.5rem; border-radius: var(--net-border-radius-xl); font-size: var(--net-font-size-xs); font-weight: 600; background: var(--net-bg-accent); color: var(--net-text-primary); }
.badge.is-damaged   { background: rgba(224, 82, 82, 0.22); color: var(--dp-tint-bad-text); }
.badge.is-destroyed { background: rgba(224, 82, 82, 0.35); color: var(--dp-tint-bad-text); }
.badge.is-undamaged { background: rgba(47, 179, 106, 0.22); color: var(--dp-tint-ok-text); }
.badge.is-cleanable { background: rgba(240, 173, 78, 0.22); color: var(--dp-tint-warn-text); }
.badge.is-missing   { background: rgba(154, 165, 180, 0.22); color: var(--dp-tint-muted-text); }
.flag-swatch { display: inline-block; width: 12px; height: 12px; border-radius: 3px; border: 1px solid rgba(0,0,0,0.25); vertical-align: middle; margin-right: 0.3rem; }

.thumb-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: var(--net-spacing-md); }
.thumb { background: var(--net-bg-card); border: 1px solid var(--net-border); border-radius: var(--net-border-radius-md); padding: 0.4rem; cursor: pointer; position: relative; }
.thumb.is-selected { outline: 3px solid var(--net-color-primary); }
.thumb img { width: 100%; height: 120px; object-fit: cover; border-radius: var(--net-border-radius-sm); background: var(--net-bg-accent); display: block; }
.thumb .noimg { height: 120px; display: flex; align-items: center; justify-content: center; color: var(--net-text-muted); background: var(--net-bg-accent); border-radius: var(--net-border-radius-sm); font-size: var(--net-font-size-sm); }
.thumb .media-video { position: relative; display: block; height: 120px; border-radius: var(--net-border-radius-sm); background: #111; }
.thumb .media-video img { background: transparent; }
/* A video tile: its still with a play mark (every stored video is an .mp4 - api _core/Media.php). */
.play-badge { position: absolute; left: 50%; top: 50%; width: 2.6rem; height: 2.6rem; margin: -1.3rem 0 0 -1.3rem; border-radius: 50%; display: flex; align-items: center; justify-content: center; padding-left: 0.2rem; background: rgba(0,0,0,0.55); color: #fff; font-size: 1.1rem; line-height: 1; pointer-events: none; box-shadow: 0 0 0 2px rgba(255,255,255,0.75); }
.thumb .cap { font-size: var(--net-font-size-xs); margin-top: 0.3rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.thumb .sub { font-size: 0.68rem; color: var(--net-text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.thumb .type-tag { position: absolute; top: 0.6rem; left: 0.6rem; background: rgba(0,0,0,0.6); color: #fff; font-size: 0.65rem; padding: 0.1rem 0.4rem; border-radius: 3px; text-transform: uppercase; }
.thumb .sub.is-shared { color: var(--net-text); }
/* Item editor > Photos > Reuse (local.photos.js): find another line, tick its photos, add them here. Tiles are the photo
   tiles' size (120px pictures) with a tick top-right; a picture already on this item is greyed out. */
.reuse-box { border: 1px dashed var(--net-border); border-radius: var(--net-border-radius-md); padding: var(--net-spacing-md); margin-bottom: var(--net-spacing-md); display: flex; flex-direction: column; gap: var(--net-spacing-sm); }
.reuse-box[hidden] { display: none; }
.reuse-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.25rem var(--net-spacing-sm); }
.reuse-line + .reuse-line { margin-top: var(--net-spacing-sm); }
.reuse-line-head { font-size: var(--net-font-size-sm); margin-bottom: 0.35rem; }
.reuse-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: var(--net-spacing-md); }
.reuse-tile { position: relative; display: block; background: var(--net-bg-card); border: 1px solid var(--net-border); border-radius: var(--net-border-radius-md); padding: 0.4rem; cursor: pointer; }
.reuse-tile:has(input:checked) { border-color: var(--net-color-primary); box-shadow: 0 0 0 1px var(--net-color-primary); }
.reuse-tile img { width: 100%; height: 120px; object-fit: cover; border-radius: var(--net-border-radius-sm); background: var(--net-bg-accent); display: block; }
.reuse-tile input[type="checkbox"] { position: absolute; top: 0.6rem; right: 0.6rem; width: 1.15rem; height: 1.15rem; margin: 0; z-index: 1; accent-color: var(--net-color-primary); }
.reuse-tile .type-tag { position: absolute; top: 0.6rem; left: 0.6rem; background: rgba(0,0,0,0.6); color: #fff; font-size: 0.65rem; padding: 0.1rem 0.4rem; border-radius: 3px; text-transform: uppercase; }
.reuse-tile .play-badge { top: calc(0.4rem + 60px); }
.reuse-cap { display: block; font-size: var(--net-font-size-xs); margin-top: 0.3rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.reuse-tile.is-here { opacity: 0.45; cursor: default; }
.reuse-actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: var(--net-spacing-sm); }
.reuse-actions .form-status { margin-right: auto; }
@media (max-width: 600px) { .reuse-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } .reuse-tile img { height: auto; aspect-ratio: 4 / 3; } }

.dropzone { border: 2px dashed var(--net-border-accent); border-radius: var(--net-border-radius-md); padding: var(--net-spacing-xl); text-align: center; color: var(--net-text-muted); background: var(--net-bg-primary); transition: border-color var(--net-transition-fast), background var(--net-transition-fast); }
.dropzone.is-over { border-color: var(--net-color-primary); background: rgba(79, 143, 247, 0.12); }
.dropzone input[type="file"] { display: none; }
/* THE drop card (dp_drop_card, php/utils/docs.php): icon · "Drop files here or choose files" + hint · the upload's
   own fields compact at the right end · picked thumbnails under. Without JS the plain picker shows instead. */
.drop-card { padding: var(--net-spacing-md); text-align: left; cursor: pointer; }
.drop-card > input[type="file"] { display: block; margin: 0 0 var(--net-spacing-sm); cursor: pointer; }
.drop-card.js-ready > input[type="file"] { display: none; }
.drop-card.has-files { cursor: default; }
.drop-card-main { display: flex; flex-wrap: wrap; align-items: center; gap: var(--net-spacing-md); }
.drop-card-icon { flex: 0 0 auto; font-size: 1.8rem; line-height: 1; }
.drop-card-text { flex: 1 1 14rem; min-width: 0; display: flex; flex-direction: column; gap: 0.1rem; font-size: var(--net-font-size-sm); color: var(--net-text-muted); }
.drop-card-text strong { color: var(--net-text-primary); }
.drop-card-text a { pointer-events: auto; }
.drop-card-text small { font-size: var(--net-font-size-xs); }
.drop-card-side { flex: 0 0 auto; margin-left: auto; display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--net-spacing-sm); cursor: default; }
.drop-card-side .ctrl-wrapper { margin: 0; gap: 0.1rem; }
.drop-card-side .ctrl-wrapper > label, .drop-card-side > label { font-size: var(--net-font-size-xs); font-weight: 600; color: var(--net-text-muted); }
.drop-card-side .ctrl-field, .drop-card-side select { min-height: 30px; padding: 0.2rem 0.45rem; font-size: var(--net-font-size-sm); width: auto; max-width: 16rem; }
.drop-card .picked-thumbs { justify-content: flex-start; margin-top: var(--net-spacing-sm); }
.drop-card .picked-thumbs:empty { display: none; }
.drop-card .picked-thumb { position: relative; margin: 0; width: 96px; }
.drop-card .picked-thumb img, .drop-card .picked-thumb .noimg { display: block; width: 96px; height: 96px; object-fit: cover; border-radius: var(--net-border-radius-base); border: 1px solid var(--net-border); }
.drop-card .picked-thumb .noimg { display: flex; align-items: center; justify-content: center; background: var(--net-bg-accent); font-weight: 700; }
.drop-card .picked-thumb figcaption { font-size: 0.65rem; color: var(--net-text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-top: 2px; }
.drop-card [data-role="picked-count"]:empty, .drop-card .form-status:empty { display: none; }
.drop-card .progress { margin-top: var(--net-spacing-sm); }
/* ONE file tile, app-wide (owner, 2026-10-07: "all the image and document and upload file-related stuff should be the exact
   same"): a portrait tile of --dp-tile-w x --dp-tile-h - the upload tile (dp_drop_card 'tile': every drop card with a "Filed
   as", the row editors' dp_doc_uploader too), the files of a Timeline event / Funds entry (.le-docs-tiles) and the files
   picked into a drop card waiting to go up. In a photo grid the upload tile is a cell like the photos beside it. */
:root { --dp-tile-w: 132px; --dp-tile-h: 176px; }
.drop-card.is-tile { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--net-spacing-md); padding: 0; border: 0; background: none; }
.drop-card.is-tile .drop-card-main { flex: 0 0 auto; width: var(--dp-tile-w); min-height: var(--dp-tile-h); flex-direction: column; flex-wrap: nowrap; align-items: stretch; justify-content: flex-start; gap: 0.35rem;
    padding: 0.6rem 0.5rem 0.5rem; border: 2px dashed var(--net-border-accent); border-radius: var(--net-border-radius-md); background: var(--net-bg-primary); text-align: center;
    transition: border-color var(--net-transition-fast), background var(--net-transition-fast); }
.drop-card.is-tile:hover .drop-card-main { border-color: var(--net-color-primary); }
.drop-card.is-tile.is-over { background: none; }
.drop-card.is-tile.is-over .drop-card-main { border-style: solid; border-color: var(--net-color-primary); background: rgba(79, 143, 247, 0.12); }
.drop-card.is-tile .drop-card-icon { font-size: 2.2rem; margin-top: auto; }
.drop-card.is-tile .drop-card-text { flex: 0 0 auto; align-items: center; font-size: var(--net-font-size-xs); line-height: 1.35; margin-bottom: auto; }
.drop-card.is-tile .drop-card-text small { display: none; }
.drop-card.is-tile .drop-card-side { margin: 0; width: 100%; flex-direction: column; align-items: stretch; gap: 0; }
.drop-card.is-tile .drop-card-side .ctrl-wrapper { width: 100%; text-align: left; }
.drop-card.is-tile .drop-card-side .ctrl-wrapper > label { font-size: 0.62rem; }
.drop-card.is-tile .drop-card-side .ctrl-field, .drop-card.is-tile .drop-card-side select { width: 100%; max-width: none; min-height: 0; height: 1.6rem; padding: 0 1.2rem 0 0.35rem; font-size: 0.7rem; }
.drop-card.is-tile .picked-thumbs { margin: 0; flex: 1 1 0; min-width: 0; justify-content: flex-start; gap: var(--net-spacing-md); }
.drop-card.is-tile .picked-thumb { width: var(--dp-tile-w); }
.drop-card.is-tile .picked-thumb img, .drop-card.is-tile .picked-thumb .noimg { width: 100%; height: calc(var(--dp-tile-h) - 1.1rem); }
.drop-card.is-tile > .progress, .drop-card.is-tile > .form-status, .drop-card.is-tile > [data-role="picked-count"] { flex: 1 1 100%; margin: 0; }
/* In a photo grid the tile IS a cell: it takes the cell's width and the row's height. */
.thumb-grid > .drop-card.is-tile { align-self: stretch; flex-direction: column; flex-wrap: nowrap; }
.thumb-grid > .drop-card.is-tile .drop-card-main { width: 100%; flex: 1 1 auto; }
/* The fields on a photo tile (type, caption) are small: the picture is the point. */
.thumb .ctrl-wrapper { margin: 0 0 0.25rem; gap: 0.1rem; }
.thumb .ctrl-wrapper > label { font-size: 0.65rem; }
.thumb .ctrl-field { min-height: 28px; padding: 0.15rem 0.35rem; font-size: var(--net-font-size-xs); }
.progress { height: 6px; background: var(--net-bg-accent); border-radius: 3px; overflow: hidden; margin-top: var(--net-spacing-sm); }
.progress > span { display: block; height: 100%; width: 0; background: var(--net-color-primary); transition: width 0.2s ease; }

.alert { padding: var(--net-spacing-md); border-radius: var(--net-border-radius-base); margin-bottom: var(--net-spacing-md); border: 1px solid transparent; }
.alert-info { background: rgba(79, 143, 247, 0.15); border-color: rgba(79, 143, 247, 0.45); color: var(--dp-tint-info-text); }
.alert-warn { background: rgba(240, 173, 78, 0.15); border-color: rgba(240, 173, 78, 0.5); color: var(--dp-tint-warn-text); }
.alert-error { background: rgba(224, 82, 82, 0.15); border-color: rgba(224, 82, 82, 0.5); color: var(--dp-tint-bad-text); }
.alert-ok { background: rgba(47, 179, 106, 0.15); border-color: rgba(47, 179, 106, 0.5); color: var(--dp-tint-ok-text); }
.empty { padding: var(--net-spacing-xl); text-align: center; color: var(--net-text-muted); }
.sign-in-box { max-width: 420px; margin: 8vh auto; }
/* The tagline under the name (owner, 2026-10-09). */
.sign-in-box h1 { margin-bottom: 0.15rem; }
.sign-in-tagline { margin: 0 0 1rem; font-style: italic; color: var(--net-text-secondary, var(--net-text-muted)); letter-spacing: 0.01em; }
.kv { display: grid; grid-template-columns: max-content 1fr; gap: 0.25rem 1rem; font-size: var(--net-font-size-sm); }
.kv dt { color: var(--net-text-muted); }
.kv dd { margin: 0; }

.flag-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 0.25rem var(--net-spacing-lg); }
.flag-row { display: flex; align-items: center; gap: 0.6rem; }
.flag-row .flag-color { flex: 0 0 64px; font-size: var(--net-font-size-sm); }
.flag-row .ctrl-wrapper { flex: 1 1 auto; margin-bottom: 0.4rem; }
.flag-swatch-lg { width: 18px; height: 18px; margin: 0; }
.claim-card .claim-cover { width: 100%; height: 140px; object-fit: cover; border-radius: var(--net-border-radius-sm); margin-bottom: var(--net-spacing-sm); display: block; background: var(--net-bg-accent); }
.claim-card .claim-cover.noimg { display: flex; align-items: center; justify-content: center; font-size: 2.5rem; opacity: 0.5; }
.claim-card { display: flex; flex-direction: column; }
.claim-card .claim-card-open { margin-top: auto; padding-top: var(--net-spacing-sm); display: flex; justify-content: flex-end; }
.cover-row { display: flex; flex-wrap: wrap; gap: var(--net-spacing-lg); align-items: stretch; }
/* Right of the photo: upload controls on top, the 3D tour link pushed to the bottom (level with the photo). */
.cover-side { flex: 1 1 260px; min-width: 0; display: flex; flex-direction: column; justify-content: space-between; gap: var(--net-spacing-sm); }
.cover-side .tour-row { margin-top: auto; margin-bottom: 0; }
/* The View button lines up with the link box: same bottom, same height. */
.cover-side .tour-row { align-items: flex-end; }
.cover-side .tour-row > .filter-actions { padding-top: 0; margin-bottom: 0; }
.cover-side .tour-row > .ctrl-wrapper { margin-bottom: 0; }
.cover-side .tour-row > .filter-actions .btn { min-height: var(--dp-tour-field-h, 40px); }
.cover-preview { width: 320px; max-width: 100%; height: 220px; object-fit: cover; border-radius: var(--net-border-radius-md); background: var(--net-bg-accent); display: block; }
.cover-preview.noimg { display: flex; align-items: center; justify-content: center; color: var(--net-text-muted); }
.cover-form { flex: 0 0 auto; }

/* Filter + action bars that follow you down long lists (Items, Amazon). */
.sticky-tools { position: sticky; top: var(--net-header-height); z-index: var(--net-z-sticky); background: var(--net-bg-body); padding-top: var(--net-spacing-sm); margin: 0 calc(-1 * var(--net-spacing-sm)); padding-left: var(--net-spacing-sm); padding-right: var(--net-spacing-sm); box-shadow: 0 6px 8px -6px rgba(0,0,0,0.35); }
/* Padding, not the last toolbar's margin: a margin collapses out of the box and the stuck row sits flush on the table. */
.sticky-tools { padding-bottom: var(--net-spacing-sm); }
.sticky-tools .toolbar:last-child { margin-bottom: 0; }
.amz-link { text-decoration: none; margin-left: 0.3rem; opacity: 0.7; font-size: 0.9em; }
.amz-link:hover { opacity: 1; text-decoration: none; }

/* Contacts: small cards (<details>); the open one spans the row and shows its fields. */
.contact-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: var(--net-spacing-md); }
.contact-card { border: 1px solid var(--net-border); border-radius: var(--net-border-radius-md); background: var(--net-bg-primary); min-width: 0; }
.contact-card:hover { border-color: var(--net-border-accent); }
.contact-card[open] { grid-column: 1 / -1; border-color: var(--net-color-primary); }
.contact-sum { list-style: none; cursor: pointer; position: relative; display: flex; flex-direction: column; gap: 0.15rem; padding: var(--net-spacing-md); padding-right: 2.2rem; }
.contact-sum::-webkit-details-marker { display: none; }
/* The caret sits on the middle line of the role row: same top, same height (role line-height 1.4). */
.contact-sum::after { content: '▼'; position: absolute; top: var(--net-spacing-md); right: var(--net-spacing-md); height: calc(var(--net-font-size-xs) * 1.4); display: flex; align-items: center; font-size: 0.8rem; line-height: 1; color: var(--net-text-muted); transition: transform var(--net-transition-fast); }
.contact-card[open] > .contact-sum::after { transform: rotate(180deg); }
.contact-sum:hover::after { color: var(--net-color-primary); }
.contact-role { font-size: var(--net-font-size-xs); line-height: 1.4; text-transform: uppercase; letter-spacing: 0.05em; color: var(--net-text-muted); }
/* The title line: collapsed = the main (starred) role only; open = every role, the main one first (owner, 2026-10-06). */
.contact-card[open] .contact-role .cr-main, .contact-card:not([open]) .contact-role .cr-all { display: none; }
.contact-name { font-size: var(--net-font-size-base); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.contact-sub { font-size: var(--net-font-size-sm); color: var(--net-text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.contact-reach { display: flex; flex-wrap: wrap; gap: 0.1rem 0.9rem; font-size: var(--net-font-size-sm); margin-top: 0.2rem; }
.contact-reach a { color: var(--net-color-primary); text-decoration: none; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
.contact-reach a:hover { text-decoration: underline; }
.contact-reach a[data-sum="phone"]::before { content: 'Direct '; color: var(--net-text-muted); }
.contact-reach a[data-sum="phone_alt"]::before { content: 'Office '; color: var(--net-text-muted); }
/* One number on the card: the direct line, else the office line. */
.contact-reach a[data-sum="phone"]:not(:empty) ~ a[data-sum="phone_alt"] { display: none; }
.contact-sum [data-sum]:empty { display: none; }
.contact-add { border-style: dashed; }
/* Drag to reorder (local.claim.js): the dragged card dims, a bar marks where it lands. */
.contact-card.is-dragging { opacity: 0.45; }
.contact-card.drop-before { box-shadow: -4px 0 0 var(--net-color-primary); }
.contact-card.drop-after { box-shadow: 4px 0 0 var(--net-color-primary); }
/* Overview tiles reorder the same way (local.claim.js; the person's order, set_pref tiles.overview) - the blue mark shows only while dragging. */
.stat-tile[draggable="true"] { cursor: grab; }
.stat-tile.is-dragging { opacity: 0.45; }
.stat-tile.drop-before { box-shadow: -4px 0 0 var(--net-color-primary); }
.stat-tile.drop-after { box-shadow: 4px 0 0 var(--net-color-primary); }
.contact-add .contact-name { color: var(--net-color-primary); }
.contact-body { border-top: 1px solid var(--net-border); padding: var(--net-spacing-md); }
/* Contact photos (2026-10-04): a round portrait beside the name on the card face; in the open card a larger
   one heads a column left of the fields, with "Add a photo" under it and the app-wide hover 🗑️ on it. The
   person's own picture (they sign in) or a photo added on the card; else the default silhouette. */
.contact-head { display: flex; align-items: center; gap: 0.75rem; min-width: 0; margin-top: 0.3rem; }
.contact-id { display: flex; flex-direction: column; gap: 0.1rem; min-width: 0; }
.contact-photo { width: 52px; height: 52px; flex: 0 0 auto; display: block; border-radius: 50%; object-fit: cover; object-position: center top;
    background: var(--net-bg-accent); border: 2px solid var(--net-border-accent); box-shadow: 0 1px 4px rgba(0, 0, 0, 0.35); }
.contact-photo.is-default { border-color: var(--net-border); }
.contact-photo.is-lg { width: 96px; height: 96px; }
.contact-body:not(.is-plain) { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: var(--net-spacing-lg); align-items: start; }
.cf-photo { display: flex; flex-direction: column; align-items: center; gap: 0.45rem; width: 8.5rem; text-align: center; padding-top: 0.2rem; }
.cf-photo .pic-box { line-height: 0; }
.cf-photo label.btn { cursor: pointer; }
.cf-photo small { font-size: var(--net-font-size-xs); line-height: 1.3; }
.cf-photo.is-busy { opacity: 0.6; pointer-events: none; }
/* The card's 🗑️ (destructive = left-most): the photo column stretches to the fields' height and the button
   drops to its foot, so it sits on the Notes row, as tall as the box. */
.contact-body:not(.is-plain) > .cf-photo { align-self: stretch; }
.contact-body:not(.is-plain) .cf-row:last-child > .ctrl-wrapper { margin-bottom: 0; }
.cf-photo .cf-del { margin-top: auto; line-height: 0; }
.cf-photo .cf-del .btn { min-height: 40px; gap: 0.35rem; }
/* "Add a photo" / "Change photo" and "Delete" are one width (owner: "it felt right to be the same size"). */
.cf-photo label.btn, .cf-photo .cf-del .btn { width: 7.5rem; justify-content: center; }
@media (max-width: 640px) {
    .contact-body:not(.is-plain) { grid-template-columns: minmax(0, 1fr); }
    .cf-photo { width: auto; flex-direction: row; justify-content: flex-start; text-align: left; }
    .cf-photo .cf-del { margin-top: 0; }
}
.contact-actions { display: flex; align-items: center; gap: var(--net-spacing-md); flex-wrap: wrap; }
.contact-actions .spacer { flex: 1 1 auto; }
/* The Sign-in switch row: switch, then what it means right now; the 🔑 on the card face = can sign in. */
.contact-actions .ctrl-switch { margin: 0; }
.signin-status { font-size: var(--net-font-size-xs); max-width: 46rem; }
.signin-status.is-error { color: var(--dp-money-bad); }
.contact-signin-badge { margin-left: 0.35rem; font-size: 0.8em; }
/* Contact card editor: three rows sized to their content. Role fits its label; Name / Company / Title share
   the rest; the phones fit "(555) 555-5555 ext. 123456" and no more; Email takes the room left by the
   Sign-in switch that closes its row; Notes takes the whole last row (the 🗑️ is under the photo). */
.contact-body .cf-row { column-gap: var(--net-spacing-md); }
.contact-body .cf-name, .contact-body .cf-company, .contact-body .cf-title { flex: 1 1 10rem; }
.contact-body .cf-phone { flex: 0 0 15.75rem; }
.contact-body .cf-email { flex: 1 1 14rem; }
.contact-body .cf-signin { flex: 0 0 auto; }
.contact-body .cf-notes { flex: 1 1 20rem; }

.coverage-row { margin-bottom: var(--net-spacing-md); }
.badge.is-cov-loss_of_use { background: #dbeafe; color: #1e3a8a; }
.badge.is-cov-dwelling, .badge.is-cov-other_structures { background: #ede9fe; color: #4c1d95; }
.layout-apply .layout-pick { flex: 0 1 420px; }
.layout-apply .layout-name { flex: 1 1 360px; }
.layout-apply .ctrl-wrapper { margin-bottom: 0.4rem; }
.layout-apply .ctrl-help { white-space: nowrap; }
.layout-apply .layout-help { flex: 1 1 100%; margin-top: -0.25rem; font-size: var(--net-font-size-xs); }
.id-row { display: flex; gap: var(--net-spacing-sm); align-items: flex-end; }   /* the button sits level with the BOX, centred on it (owner, 2026-10-08) */
.id-row .ctrl-wrapper { flex: 1 1 auto; margin-bottom: 0; }   /* the row carries the field's bottom margin, so the box's bottom IS the row's */
.id-row { margin-bottom: var(--net-spacing-md); }
/* Sync Id is centred on the Inventory ID BOX (owner, 2026-10-08): a 2rem button, its bottom margin = half of what the box is
   taller - --dp-id-box-h is the field's height (40px here; X-Port's hairline fields are 34px, model.xactimate.css). */
.id-row { --dp-id-box-h: 40px; }
.id-row .btn { white-space: nowrap; height: 2rem; min-height: 0; padding-top: 0; padding-bottom: 0; align-self: flex-end; margin-bottom: calc((var(--dp-id-box-h) - 2rem) / 2); }
.id-row .btn.is-stale { background: var(--net-color-warning); color: var(--net-text-primary); }
/* Filter bars (.toolbar, and the labelled .filter-bar): every dropdown is as
   wide as its longest option and never shrinks (no cropped choices), the
   search box takes whatever is left, and the buttons (.filter-actions: Filter,
   Clear) stay together on one line. */
.toolbar .ctrl-select, .filter-bar .ctrl-select { flex: 0 0 auto; }
.toolbar .ctrl-select .ctrl-field, .filter-bar .ctrl-select .ctrl-field { width: auto; max-width: 100%; }
.toolbar .ctrl-wrapper[data-field="q"], .filter-bar .ctrl-wrapper[data-field="q"] { flex: 1 1 240px; }
.toolbar .ctrl-wrapper[data-field="q"] .ctrl-field { width: 100%; }
.filter-actions { display: flex; flex: 0 0 auto; gap: var(--net-spacing-sm); align-items: center; white-space: nowrap; }
.field-row > .filter-actions { margin-bottom: var(--net-spacing-sm); }
.toolbar > .filter-actions.is-end { margin-left: auto; }
/* Checkbox filters take a row of their own under the search / dropdowns / Apply line. */
.toolbar .filter-checks { display: flex; flex: 1 1 100%; flex-wrap: wrap; gap: var(--net-spacing-xs) var(--net-spacing-md); align-items: center; }
/* Action rows (Items / Amazon): the same controls as the filter bar, sized to their contents. */
.toolbar .ctrl-wrapper.fit { flex: 0 0 auto; margin: 0; }
.field-row .ctrl-wrapper.fit { flex: 0 0 auto; }
.ctrl-wrapper.fit .ctrl-field { width: auto; }
.toolbar .btn { min-height: 40px; }
.stat-tile.is-review { border-color: var(--net-color-warning); }   /* needs attention: the border's colour only, never a thick edge (owner, 2026-10-07) */

/* Structure estimates (/structure) */
.estimate-tabs { display: flex; flex-wrap: wrap; gap: var(--net-spacing-sm); margin-bottom: var(--net-spacing-md); }
h2.structure-group { margin: var(--net-spacing-lg) 0 var(--net-spacing-sm); font-size: var(--net-font-size-lg); }
.panel .area-total { font-variant-numeric: tabular-nums; }
.area-meta { align-items: start; }   /* a form-grid since 2026-10-07: fixed columns in every area panel */
.area-measure, .area-note { font-size: var(--net-font-size-sm); margin: var(--net-spacing-xs) 0; }
.area-openings { font-size: var(--net-font-size-sm); margin-bottom: var(--net-spacing-sm); }
.area-openings ul { margin: var(--net-spacing-xs) 0 0; padding-left: 1.2rem; columns: 2 260px; }
table.structure-lines td .ctrl-wrapper { margin: 0; }
table.structure-lines tr.rv-agreed   { box-shadow: inset 3px 0 0 var(--net-color-success); }
table.structure-lines tr.rv-question { box-shadow: inset 3px 0 0 var(--net-color-warning); }
table.structure-lines tr.rv-dispute, table.structure-lines tr.rv-missing { box-shadow: inset 3px 0 0 var(--net-color-danger); }
table.kv th { width: 180px; position: static; }
.kv-pair { display: inline-block; margin-right: var(--net-spacing-md); white-space: nowrap; }

/* Simple / Adjuster view toggle (items pages) */
.view-toggle { display: inline-flex; border: 1px solid var(--net-border); border-radius: var(--net-border-radius-xl); overflow: hidden; font-size: var(--net-font-size-xs); font-weight: 600; vertical-align: middle; }
.view-toggle a, .view-toggle span { padding: 0.3rem 0.7rem; color: var(--net-text-muted); text-decoration: none; white-space: nowrap; }
.view-toggle a:hover { background: var(--net-bg-accent); color: var(--net-text-primary); }
.view-toggle .is-on { background: var(--net-color-primary); color: #fff; }
.badge.is-sublimit { background: rgba(240, 173, 78, 0.22); color: var(--dp-tint-warn-text); }
.badge.is-replaced { background: rgba(47, 179, 106, 0.22); color: var(--dp-tint-ok-text); }


/* Imports hub */
.import-sources { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: var(--net-spacing-md); }
.import-source h2 { margin-top: 0; }
.import-source p { font-size: var(--net-font-size-sm); }

/* Documents */
.doc-row { padding: var(--net-spacing-sm) 0; border-bottom: 1px solid var(--net-border); }
.doc-row:last-child { border-bottom: 0; }
.doc-file { display: flex; gap: 0.6rem; align-items: center; text-decoration: none; color: inherit; margin-bottom: 0.3rem; }
.doc-icon { font-size: 1.5rem; flex: 0 0 auto; }
.doc-meta { display: flex; flex-direction: column; min-width: 0; }
.doc-name { font-weight: 600; word-break: break-all; }
.doc-fields .ctrl-wrapper { margin-bottom: 0.3rem; }
.doc-actions { display: flex; gap: 0.4rem; align-items: flex-end; flex-wrap: wrap; padding-bottom: 0.4rem; }
/* In a document's field grid the buttons sit centred on the input line: a
   label-high top pad (1.45 = body line-height) then a 40px band like the fields. */
.doc-fields .doc-actions { align-self: start; align-items: center; align-content: center; padding-bottom: 0; padding-top: calc(var(--net-font-size-sm) * 1.45 + 0.2rem); min-height: calc(var(--net-font-size-sm) * 1.45 + 0.2rem + 40px); }
/* A document's decision (Status): a badge on its header; rejected / superseded paperwork is dimmed. */
.doc-status { flex: 0 0 auto; }
.doc-status:empty { display: none; }
.badge.is-doc-pending    { background: rgba(240, 173, 78, 0.22); color: var(--dp-tint-warn-text); }
.badge.is-doc-accepted   { background: rgba(47, 179, 106, 0.22); color: var(--dp-tint-ok-text); }
.badge.is-doc-rejected   { background: rgba(224, 82, 82, 0.22); color: var(--dp-tint-bad-text); }
.badge.is-doc-superseded { background: rgba(154, 165, 180, 0.22); color: var(--dp-tint-muted-text); }
.doc-row.is-rejected .doc-file .doc-meta, .doc-row.is-superseded .doc-file .doc-meta { opacity: 0.6; }
/* New document: Upload a file / Web link / DamagePort record as ONE segmented control (the selected
   segment carries the primary colour), each pane its own form below it. */
.doc-type-switch { display: inline-flex; gap: 0; margin: 0 0 var(--net-spacing-md); flex-wrap: wrap; }
.doc-type-switch .btn { flex: 0 0 auto; border-radius: 0; background: var(--net-bg-accent); color: var(--net-text-secondary, var(--net-text-muted)); border: 1px solid var(--net-border); }
.doc-type-switch .btn + .btn { margin-left: -1px; }
.doc-type-switch .btn:first-child { border-radius: var(--net-border-radius-base) 0 0 var(--net-border-radius-base); }
.doc-type-switch .btn:last-child { border-radius: 0 var(--net-border-radius-base) var(--net-border-radius-base) 0; }
.doc-type-switch .btn[aria-selected="true"] { background: var(--net-color-primary); border-color: var(--net-color-primary); color: #fff; position: relative; z-index: 1; }
.doc-pane > .muted:first-child { margin-top: 0; }
/* Each pane's action row: Cancel on the left, the pane's submit (Upload / Add link / Link record) on the right. */
.doc-new-actions { justify-content: space-between; margin-bottom: 0; }
/* A record link reads like a link to the record, not a file name. */
.doc-row.is-record .doc-name { word-break: normal; }
.doc-row.is-record a.doc-file:hover .doc-name { text-decoration: underline; }
@media (max-width: 600px) { .doc-type-switch { display: flex; } .doc-type-switch .btn { flex: 1 1 auto; } }

/* Entity navigator (item editor): First / Back / List / New / Next / Last share
   the row evenly, like Citadel's update.php control. Disabled ends are spans. */
.entity-nav { margin: calc(-1 * var(--net-spacing-sm)) 0 var(--net-spacing-lg); }
/* Page header, two rows (Item, Items, Amazon): the title on its own, then
   .head-tools - page buttons left and, on the item editor, the navigator
   right with every button as wide as the longest ("Last ▶|"), so the row
   reads as one control and never jitters. On desktop the item editor's row
   sticks under the site header while the title scrolls away (owner
   2026-09-29), the same treatment as the lists' .sticky-tools. */
.page-head:has(+ .head-tools) { margin-bottom: var(--net-spacing-sm); }
.head-tools { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: var(--net-spacing-md); margin-bottom: var(--net-spacing-lg); }
.head-tools .actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--net-spacing-sm); }
.head-tools .entity-nav { margin: 0 0 0 auto; }
.head-tools .entity-nav-row { width: auto; }
.head-tools .entity-nav-row > .btn { flex: 0 0 auto; width: 6.5rem; }
@media (min-width: 769px) {
    .page-item .head-tools {
        position: sticky; top: var(--net-header-height); z-index: var(--net-z-sticky);
        background: var(--net-bg-body); margin: 0 calc(-1 * var(--net-spacing-sm)) var(--net-spacing-lg);
        padding: var(--net-spacing-sm) var(--net-spacing-sm); box-shadow: 0 6px 8px -6px rgba(0,0,0,0.35);
    }
}
.entity-nav-row { display: flex; gap: var(--net-spacing-sm); width: 100%; }
.entity-nav-row > .btn { flex: 1 1 0; min-width: 0; justify-content: center; white-space: nowrap; }
.entity-nav-row > .btn.is-disabled { opacity: 0.45; cursor: not-allowed; pointer-events: none; }
.entity-nav-caption { font-size: var(--net-font-size-xs); margin-top: 0.3rem; text-align: right; }
/* Compact (Capture's facts cards): First / Back / Next / Last are arrow squares, Save and New share the rest. */
.entity-nav.is-compact .entity-nav-row { gap: 0.3rem; }
.entity-nav.is-compact .entity-nav-row > .btn.is-arrow { flex: 0 0 2.4rem; padding-left: 0; padding-right: 0; }
.funds-head { display: flex; align-items: center; justify-content: space-between; gap: var(--net-spacing-md); margin-top: var(--net-spacing-lg); }
/* Record panels (overview: Policy limits, Policy & claim details). Each record is a quiet read-only
   line of label-over-value cells on an evenly spaced grid (auto-fit: the cells share the width);
   clicking it opens its editor under it, the fields on the SAME grid in the same order (.rec-fields
   keeps the ✎ column clear so each field sits under its cell). An extra limit is a one-line record
   (.is-line: label · rate · maximum). local.claim.js recordPanels(). */
.rec-intro { margin-top: 0; font-size: var(--net-font-size-sm); }
.rec-row { padding: 0.45rem 0.6rem; border-radius: var(--net-border-radius-base); border-bottom: 1px dashed var(--net-border); }
.rec-row:last-child { border-bottom: 0; }
.rec-row.is-editable:hover { background: var(--dp-hover-row); }
.rec-row:target, .rec-row.is-editing { background: var(--dp-edit-row); }
.rec-row.is-editable > .rec-view { cursor: pointer; }
.rec-view { display: grid; grid-template-columns: 1fr 2rem; gap: 0.15rem var(--net-spacing-md); align-items: start; }
.rec-view.is-line { grid-template-columns: minmax(10rem, 1fr) auto auto 2rem; align-items: baseline; }
.rec-cells, .rec-fields { display: grid; grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); gap: 0.4rem var(--net-spacing-md); }
.rec-fields { margin-right: calc(2rem + var(--net-spacing-md)); gap: 0 var(--net-spacing-md); }
.rec-cell { display: flex; flex-direction: column; min-width: 0; line-height: 1.3; }
.rec-cell.is-wide { grid-column: span 2; }
.rec-cell.is-full { grid-column: 1 / -1; }
.rec-cell small { font-size: var(--net-font-size-xs); color: var(--net-text-muted); }
.rec-v, .lv-max b { font-weight: 600; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.rec-v.is-empty { color: var(--net-text-muted); font-weight: 400; }
.rec-cell.is-full .rec-v { font-weight: 400; white-space: pre-wrap; display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden; }
.lv-label { font-weight: 600; min-width: 0; }
.lv-rate, .lv-max { white-space: nowrap; font-size: var(--net-font-size-sm); }
.rec-meta { grid-column: 1 / -1; font-size: var(--net-font-size-xs); }
.rec-edit { width: 26px; height: 26px; border: 0; border-radius: 50%; background: transparent; color: var(--net-text-muted); cursor: pointer; font-size: 0.95rem; opacity: 0; justify-self: end; }
.rec-row:hover .rec-edit, .rec-row.is-editing .rec-edit { opacity: 1; }
.rec-edit:hover { background: var(--net-bg-accent); color: var(--net-text-primary); }
.rec-editor { margin-top: var(--net-spacing-sm); padding-top: var(--net-spacing-sm); border-top: 1px solid var(--net-border); }
/* Remove far left, Done far right - a hand aiming at Done never lands on Remove. */
.rec-editor-actions, .limit-foot { display: flex; align-items: center; gap: var(--net-spacing-sm); }
.rec-editor-actions .spacer, .limit-foot .spacer { flex: 1 1 auto; }
.rec-editor-actions .muted, .limit-foot .muted { font-size: var(--net-font-size-xs); }
.limit-foot { margin-top: var(--net-spacing-sm); }
.limit-add { align-items: flex-end; margin-top: var(--net-spacing-sm); }
.limit-add[hidden] { display: none; }
@media (max-width: 600px) {
    .rec-view.is-line { grid-template-columns: 1fr 2rem; }
    .lv-rate, .lv-max { grid-column: 1; }
    .rec-edit { opacity: 1; grid-column: 2; grid-row: 1; }
    .rec-fields { margin-right: 0; }
    .rec-cell.is-wide { grid-column: 1 / -1; }
}
.pending-code { font-size: 1.05em; letter-spacing: 0.08em; background: var(--dp-money-out-soft); padding: 0.1rem 0.4rem; border-radius: var(--net-border-radius-base); }
.form-status.is-warn { color: var(--net-color-warning); }

/* A car rental billed to the carrier: green like covered money, striped - an estimate, on its account (dp_money_bar $direct). */
.progress > span.is-direct { background: repeating-linear-gradient(135deg, var(--dp-money-in) 0 6px, rgba(47, 179, 106, 0.55) 6px 10px); }
.badge.is-ongoing { background: rgba(79, 143, 247, 0.22); color: var(--dp-tint-info-text); }

/* Settings > Categories & depreciation: compact. Header labels small and free to wrap ("Useful life / (yrs)"),
   so a column is as wide as its box, not its words; the number boxes fit their 3-4 characters ("100", "12.5");
   tighter cell padding; the room saved goes to Notes. */
#categories-table th { font-size: var(--net-font-size-xs); white-space: nowrap; line-height: 1.2; vertical-align: bottom; }   /* one line; units sit in the boxes' placeholders */
#categories-table th, #categories-table td { padding-left: 0.4rem; padding-right: 0.4rem; }
#categories-table th.wrap, #categories-table td.wrap { min-width: 0; }   /* the table-wide 220px minimum; the two rules below set this table's */
#categories-table th.num { width: 4.25rem; }
#categories-table td.cat-notes { min-width: 11rem; }
#categories-table th:first-child, #categories-table td:first-child { min-width: 11.5rem; }
#categories-table td .ctrl-select .ctrl-field { max-width: 11.5rem; text-overflow: ellipsis; }
#categories-table td.cat-notes .ctrl-wrapper { width: 11rem; min-width: 100%; }   /* a text box keeps ~200px in a table cell unless told */
#categories-table td.cat-notes .ctrl-field { width: 100%; }
/* Settings > Claim categories: a checkbox's hint ("bought after the loss") sits beside it, not under it. */
#buckets-table .ctrl-checkbox { display: flex; flex-direction: row; align-items: center; gap: 0.5rem; flex-wrap: nowrap; }
#buckets-table .ctrl-checkbox .ctrl-help { margin: 0; white-space: nowrap; }

/* Long explanations fold away (explain_open / explain_close in builder.php): a plain <details>, closed on
   every load - nothing remembered. The summary is one small muted line: "ⓘ How these bars are worked out ▸". */
details.explain { margin: var(--net-spacing-xs) 0 var(--net-spacing-sm); color: var(--net-text-muted); }
details.explain > summary { cursor: pointer; list-style: none; display: inline-flex; align-items: center; gap: 0.35rem; font-size: var(--net-font-size-xs); user-select: none; }
details.explain > summary::-webkit-details-marker { display: none; }
details.explain > summary::before { content: 'ⓘ'; font-size: 1.05em; }
details.explain > summary::after { content: '▸'; transition: transform var(--net-transition-fast); }
details.explain[open] > summary::after { transform: rotate(90deg); }
details.explain > summary:hover { color: var(--net-text-primary); }
details.explain > .explain-body { margin-top: 0.35rem; font-size: var(--net-font-size-sm); line-height: 1.5; }

/* ── Item attention (who has the next thing to do) ───────────────────────────────────────────
   Responsibility, not error: the item name takes the primary stakeholder's colour (--attn-<key>,
   set per account by dp_attention_style()); a letter chip marks every stakeholder with work. The
   name is still a link (keyboard, middle-click) but no longer LOOKS like one - the row is the click
   target. Red stays reserved for real problems. */
:root { --attn-homeowner: #f2a65a; --attn-inventory: #5bc0de; --attn-pa: #b794f6; }
a.item-name { color: var(--net-text-primary); text-decoration: none; font-weight: 500; }
a.item-name:hover, a.item-name:focus { text-decoration: none; filter: brightness(1.15); }
.attn-cell { white-space: nowrap; width: 1%; }
.attn-chip { display: inline-block; min-width: 1.25em; padding: 0 0.3em; margin-right: 2px; border-radius: 3px; font-size: 0.7rem; font-weight: 700; line-height: 1.5; text-align: center;
             color: var(--c); border: 1px solid var(--c); background: transparent; cursor: help; opacity: 0.75; }
.attn-chip.is-primary { background: var(--c); color: #10141c; opacity: 1; }
.attn-ok { color: var(--net-color-success); font-weight: 700; cursor: help; }
.attn-na { color: var(--net-text-muted); opacity: 0.5; cursor: help; }
.attn-summary { white-space: normal; }
.attn-count { display: inline-block; margin: 0 0.15rem; padding: 0 0.4rem; border-radius: var(--net-border-radius-xl); background: var(--net-bg-accent); color: inherit; text-decoration: none; white-space: nowrap; }
.attn-count:hover { text-decoration: none; filter: brightness(1.2); }
.attn-count.is-on { outline: 1px solid var(--c, var(--net-color-primary)); }
/* Two columns (owner, 2026-10-07): the "Needs" lines wrap on the left (.attn-lines), "＋ Mark for…" holds the TOP-RIGHT corner
   and keeps its width - the coloured text wraps before it, never under it. The lines' padding puts their first line level
   with the middle of the select. A phone puts the control on its own line at the top. */
.attn-banner { display: flex; align-items: flex-start; gap: var(--net-spacing-sm) var(--net-spacing-lg); padding: 0.4rem 0.7rem; margin-bottom: var(--net-spacing-md); border: 1px solid var(--net-border); border-radius: var(--net-border-radius-md); background: var(--net-bg-primary); font-size: var(--net-font-size-sm); }
.attn-banner .attn-lines { flex: 1 1 auto; min-width: 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.25rem var(--net-spacing-lg); padding-top: 0.45rem; }
.attn-banner.is-complete { color: var(--net-text-muted); }
/* "＋ Mark for…" (076): the hand-marking control. */
.attn-banner .attn-mark { flex: 0 1 auto; margin-left: auto; display: inline-flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: 0.35rem; }
@media (max-width: 600px) {
    .attn-banner { flex-direction: column-reverse; align-items: stretch; }
    .attn-banner .attn-mark { margin-left: 0; justify-content: flex-start; }
    .attn-banner .attn-lines { padding-top: 0; }
}
.attn-banner .attn-mark-more { display: inline-flex; align-items: center; gap: 0.35rem; }
.attn-banner .attn-mark-more[hidden] { display: none; }
.attn-banner .attn-mark .ctrl-wrapper { margin: 0; }
.attn-banner .attn-mark input[name="need_note"] { min-width: 14rem; }
.attn-banner .js-need-clear { --tg: var(--net-text-muted); }
.attn-settings { display: grid; gap: var(--net-spacing-sm); }
.attn-setting-row { display: flex; align-items: center; gap: var(--net-spacing-md); }
.attn-setting-row .ctrl-wrapper { margin: 0; flex: 0 0 auto; }
.attn-setting-row input[type="color"] { width: 3rem; height: 2rem; min-height: 0; padding: 2px; cursor: pointer; }
.attn-setting-text { flex: 1 1 auto; min-width: 0; }

/* Column chooser (php/utils/columns.php): a "Columns" button with a checkbox menu, right end of a list's header row. */
.col-picker { position: relative; }
.col-picker > summary { list-style: none; cursor: pointer; user-select: none; }
.col-picker > summary::-webkit-details-marker { display: none; }
.col-picker > summary small { font-weight: 400; opacity: 0.8; }
.col-picker-menu { position: absolute; right: 0; top: calc(100% + 4px); z-index: var(--net-z-dropdown); min-width: 15rem; padding: var(--net-spacing-sm) var(--net-spacing-md);
                   background: var(--net-bg-card); border: 1px solid var(--net-border-accent); border-radius: var(--net-border-radius-md); box-shadow: var(--net-shadow-lg); }
.col-picker-hint { font-size: var(--net-font-size-xs); margin-bottom: 0.3rem; }
.col-picker-list { display: flex; flex-direction: column; max-height: 60vh; overflow-y: auto; }
.col-picker-item { display: flex; align-items: center; gap: 0.4rem; font-size: var(--net-font-size-sm); white-space: nowrap; padding: 0.1rem 0.2rem; border-radius: var(--net-border-radius-base); }
.col-picker-item:hover { background: var(--net-bg-accent); }
.col-picker-item.is-dragging { opacity: 0.4; }
.col-picker-item label { flex: 1 1 auto; display: flex; align-items: center; gap: 0.4rem; cursor: pointer; }
.col-picker-item input { accent-color: var(--net-color-primary); }
.col-grip { cursor: grab; color: var(--net-text-muted); user-select: none; }
.col-move { display: flex; gap: 2px; }
.col-move button { width: 22px; height: 22px; padding: 0; border: 1px solid var(--net-border); border-radius: 3px; background: transparent; color: var(--net-text-muted); font-size: 0.6rem; line-height: 1; cursor: pointer; }
.col-move button:hover { background: var(--net-bg-accent); color: var(--net-text-primary); }
.col-picker-foot { display: flex; align-items: center; gap: var(--net-spacing-sm); margin-top: var(--net-spacing-sm); padding-top: var(--net-spacing-sm); border-top: 1px solid var(--net-border); font-size: var(--net-font-size-xs); }
@media (max-width: 768px) { .col-picker-menu { right: auto; left: 0; } }

/* Item editor: the retailer's listing picture sits LEFT of the Name and Room rows (local.item.js).
   A thumbnail that enlarges on hover, with Keep / look-up-again under it. No ASIN = no column. */
.item-top { display: block; }
.item-top.has-pic { display: flex; align-items: flex-start; gap: var(--net-spacing-md); }
.item-top-fields { flex: 1 1 auto; min-width: 0; }
.product-pic { flex: 0 0 132px; width: 132px; }
.product-pic-thumb { position: relative; display: block; width: 132px; height: 132px; border: 1px solid var(--net-border); border-radius: var(--net-border-radius-md); background: #fff; }
.product-pic-thumb > img:first-child { width: 100%; height: 100%; object-fit: contain; border-radius: var(--net-border-radius-md); display: block; }
.product-pic-zoom { display: none; position: absolute; left: calc(100% + 10px); top: 0; z-index: var(--net-z-dropdown); width: 420px; max-width: 60vw; max-height: 70vh; object-fit: contain; background: #fff; border: 1px solid var(--net-border-accent); border-radius: var(--net-border-radius-md); box-shadow: var(--net-shadow-lg); }
.product-pic-thumb:hover .product-pic-zoom, .product-pic-thumb:focus .product-pic-zoom { display: block; }
.product-pic-none { display: flex; align-items: center; justify-content: center; text-align: center; width: 132px; height: 132px; border: 1px dashed var(--net-border); border-radius: var(--net-border-radius-md); color: var(--net-text-muted); font-size: var(--net-font-size-xs); padding: 0.5rem; }
/* The hidden attribute must win over the display rules above (thumb while empty, placeholder once found). */
.product-pic-thumb[hidden], .product-pic-none[hidden] { display: none; }
.product-pic-status { margin: 0 0 var(--net-spacing-sm); min-height: 0; font-size: var(--net-font-size-xs); }
.product-pic-status:empty { display: none; }
.ctrl-field.is-filled { box-shadow: 0 0 0 2px var(--dp-money-in-soft); transition: box-shadow 0.6s ease; }
@media (max-width: 768px) {
    .item-top.has-pic { flex-direction: column; }
    .product-pic { flex-basis: auto; display: flex; gap: var(--net-spacing-sm); width: auto; align-items: flex-end; }
    .product-pic-zoom { left: 0; top: calc(100% + 8px); width: 80vw; }
}

/* Record stamps (php/utils/stamps.php, 2026-10-02): the last line of an edit screen - who last changed
   the record on the LEFT, who made it on the RIGHT. Quiet on purpose: it is a footnote, not a field. */
.rec-stamp { display: flex; justify-content: space-between; align-items: baseline; gap: 0.25rem var(--net-spacing-lg); flex-wrap: wrap;
    margin-top: var(--net-spacing-sm); padding-top: 0.35rem; border-top: 1px dashed var(--net-border);
    font-size: var(--net-font-size-xs); color: var(--net-text-muted); }
.rec-stamp-new { margin-left: auto; text-align: right; }
.rec-stamp-mod:empty { display: none; }

/* Documentation: a document is a CARD until it is edited (2026-10-02, like the contact cards). The face
   says what it is - icon, title, file / link / record, size and date, the decision badge, Open - and a
   click opens that one card across the row with its fields and, at the foot, who filed and who last
   changed it. */
.doc-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(270px, 1fr)); gap: var(--net-spacing-md); }
.doc-card { border: 1px solid var(--net-border); border-radius: var(--net-border-radius-md); background: var(--net-bg-primary); min-width: 0; }
.doc-card:hover { border-color: var(--net-border-accent); }
.doc-card[open] { grid-column: 1 / -1; border-color: var(--net-color-primary); }
.doc-sum { list-style: none; cursor: pointer; display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 0.35rem 0.6rem; align-items: start; padding: var(--net-spacing-md); height: 100%; }
.doc-sum::-webkit-details-marker { display: none; }
.doc-card[open] > .doc-sum { height: auto; }
.doc-sum .doc-meta { gap: 0.1rem; }
.doc-title { overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.doc-sum .doc-name { font-weight: 400; font-size: var(--net-font-size-sm); color: var(--net-text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; word-break: normal; }
.doc-note { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-style: italic; }
.doc-note:empty { display: none; }
/* Custom tags (077) on a record's line / card: small 🏷️ badges in their colours, wrapping. */
.doc-ctags, .tl-v-ctags, .le-v-ctags { display: inline-flex; flex-wrap: wrap; gap: 0.2rem; }
.doc-ctags:empty, .tl-v-ctags:empty, .le-v-ctags:empty { display: none; }
.badge.is-ctag .tg-i { font-size: 0.85em; }
.doc-foot { grid-column: 1 / -1; align-self: end; display: flex; align-items: center; justify-content: space-between; gap: var(--net-spacing-sm); min-height: 1.6rem; }
.doc-foot .doc-open { margin-left: auto; }
.doc-body { border-top: 1px solid var(--net-border); padding: var(--net-spacing-md); }
.doc-card.is-rejected .doc-sum .doc-meta, .doc-card.is-superseded .doc-sum .doc-meta { opacity: 0.6; }

/* Settings > Activity (migration 050): the owner's log of who did what. One line per thing (autosave
   chatter folded, xN), a day header between days, the kind as an emoji, the record as a link. */
.act-people { display: flex; flex-wrap: wrap; gap: 0.35rem; margin: 0 0 var(--net-spacing-sm); }
.act-person { text-decoration: none; }
.act-person.is-on { background: var(--net-color-primary); color: #fff; }
.act-table td { vertical-align: top; }
/* Your own last few lines: their own panel under the team's (pages/activity, 2026-10-07). */
.act-mine .act-when { white-space: nowrap; }
.act-mine-meta { font-weight: 400; white-space: nowrap; }
/* The filter line rides on .tl-toolbar (one line, narrow dates); the claim box gets a set width and
   ui.fit-options.js cuts the claim name to it (never the number), the search box takes the rest. */
.act-toolbar .ctrl-wrapper.act-claim-pick { flex: 0 1 15rem; min-width: 9rem; }
.act-toolbar .ctrl-wrapper.act-claim-pick .ctrl-field { width: 100%; }
.act-toolbar .ctrl-wrapper[data-field="act_q"] { flex: 1 1 12rem; min-width: 8rem; }
.act-toolbar .ctrl-wrapper[data-field="act_q"] .ctrl-field { width: 100%; }
.act-table .act-day td { background: var(--net-bg-accent); font-size: var(--net-font-size-xs); text-transform: uppercase; letter-spacing: 0.06em; color: var(--net-text-muted); padding: 0.3rem 0.6rem; }
.act-when { white-space: nowrap; font-variant-numeric: tabular-nums; }
.act-count { font-size: 0.65rem; padding: 0 0.35rem; }
.act-who { white-space: nowrap; font-weight: 600; }
.act-kind { display: inline-block; width: 1.4em; text-align: center; }
.act-fields { font-family: var(--net-font-mono, ui-monospace, monospace); font-size: var(--net-font-size-xs); }
.act-claim { opacity: 0.75; }
.act-where code { font-size: var(--net-font-size-xs); }
.act-row.is-delete .act-what { color: var(--dp-money-bad, #e74c3c); }
.act-row.is-view .act-what { color: var(--net-text-muted); }
.act-pages { margin-top: var(--net-spacing-sm); font-size: var(--net-font-size-sm); }

/* Settings > Me and My Team: the people table under your own profile (2026-10-04). */
.settings-sub { display: flex; align-items: center; gap: var(--net-spacing-sm); margin: var(--net-spacing-lg) 0 var(--net-spacing-sm);
    padding-top: var(--net-spacing-md); border-top: 1px solid var(--net-color-border, rgba(255,255,255,.08)); font-size: var(--net-font-size-md, 1rem); }
tr.user-row.is-self .u-name::after { content: ' (you)'; color: var(--net-color-text-muted, #8a94a6); font-weight: normal; }
/* Under a person's name: who added them, and how many people are on their team. */
.u-name-cell .u-by { display: block; font-size: var(--net-font-size-xs); line-height: 1.3; }

/* Remove a picture, app-wide (2026-10-04) - Citadel's .image-tile-delete (ravenbreath ui.picture.css), in maroon
   with a 🗑️: a circle pushed past the picture's top-right corner so only its inner part shows (3rem circle,
   -1.25rem offsets), HIDDEN until the picture is hovered (or focused); always shown on touch screens.
   Markup: `<button class="pic-del ..." aria-label title><span aria-hidden="true">🗑️</span></button>` as a DIRECT
   child of the picture's positioned box (.pic-box, .thumb, .picked-thumb, .le-doc). The circle is clipped
   to the box with clip-path (not overflow:hidden on the box, which would cut off the Amazon picture's zoom).
   --pic-del-inset = how far the picture sits inside its box (a .thumb's padding); --pic-del-r = the
   picture's corner radius. A round picture (.pic-box.is-round, the avatar) gets a whole small circle on its
   edge at 45 degrees instead - a round picture has no corner. */
.pic-box { position: relative; display: inline-block; }
.pic-del {
    --pic-del-size: 3rem; --pic-del-inset: 0px; --pic-del-r: var(--net-border-radius-md);
    --pic-del-cut: calc(var(--pic-del-size) * 0.4167);
    position: absolute; z-index: 2;
    top: calc(var(--pic-del-inset) - var(--pic-del-cut)); right: calc(var(--pic-del-inset) - var(--pic-del-cut));
    width: var(--pic-del-size); height: var(--pic-del-size); margin: 0;
    padding: calc(var(--pic-del-size) / 3) calc(var(--pic-del-size) / 3) 0 0;
    display: flex; align-items: center; justify-content: center;
    border: 0; border-radius: 50%;
    clip-path: inset(var(--pic-del-cut) var(--pic-del-cut) 0 0 round 0 var(--pic-del-r) 0 0);
    background: rgba(128, 24, 40, 0.72); color: #fff; font-size: 1rem; line-height: 1; cursor: pointer;
    opacity: 0; transition: opacity 0.15s, background-color 0.15s;
}
.pic-del > span { pointer-events: none; }
:hover > .pic-del, :focus-within > .pic-del, .pic-del:focus-visible { opacity: 1; }
.pic-del:hover, .pic-del:focus-visible { background: rgba(160, 32, 52, 0.95); }
.pic-del:focus-visible { outline: none; }
.pic-del[hidden] { display: none; }
@media (hover: none) { .pic-del { opacity: 1; } }
.pic-del.is-sm { --pic-del-size: 1.9rem; --pic-del-r: var(--net-border-radius-base); font-size: 0.65rem; }
/* Where each picture sits in its box. */
.thumb > .pic-del { --pic-del-inset: 0.4rem; --pic-del-r: var(--net-border-radius-sm); }
.picked-thumb > .pic-del { --pic-del-size: 2.4rem; --pic-del-r: var(--net-border-radius-base); font-size: 0.8rem; }
.pic-box.is-round { line-height: 0; }
.pic-box.is-round > .pic-del { --pic-del-size: 2rem; top: calc(14.64% - 1rem); right: calc(14.64% - 1rem); padding: 0; clip-path: none; font-size: 0.85rem; box-shadow: 0 1px 4px rgba(0, 0, 0, 0.45); }
/* Same corner, not destructive: the Amazon listing picture's ↻ (look it up again). Neutral, blue on hover. */
.pic-del.is-refresh { background: rgba(24, 32, 46, 0.72); font-size: 1.15rem; font-weight: 700; }
.pic-del.is-refresh:hover, .pic-del.is-refresh:focus-visible { background: var(--net-color-primary); }
.pic-del.is-refresh.is-busy { opacity: 1; cursor: progress; }
.pic-del.is-refresh.is-busy > span { animation: pic-spin 0.9s linear infinite; }
@keyframes pic-spin { to { transform: rotate(360deg); } }
.cover-row .pic-box { display: block; max-width: 100%; }
.product-pic-box { display: block; width: 132px; }
/* Settings > My Team: the account holder (migration 055) - the owner no co-owner can remove. */
.badge.is-holder { background: var(--dp-money-in-soft, rgba(46, 160, 67, 0.2)); color: var(--net-text-primary); }
/* Documentation: who a document is for (Visible to), on the card's face as a folded "👁 Visible to N ▸" line;
   a click shows the badges (local.documents.js). Folded on every load - nothing is stored. */
.doc-aud-wrap[hidden] { display: none; }
.doc-aud-toggle { all: unset; cursor: pointer; font-size: inherit; color: var(--net-text-muted); white-space: nowrap; }
.doc-aud-toggle:hover, .doc-aud-toggle:focus-visible { color: var(--net-text-primary); text-decoration: underline; }
.doc-aud-caret { display: inline-block; transition: transform 0.15s; }
.doc-aud-wrap.is-open .doc-aud-caret { transform: rotate(90deg); }
.doc-aud { display: none; }
.doc-aud-wrap.is-open .doc-aud { display: flex; flex-wrap: wrap; gap: 0.2rem; margin-top: 0.25rem; }
.doc-aud .badge { font-weight: 500; }
/* Items: free tags under / beside the name, each a link that filters the list by it. */
.item-tags { display: inline-flex; flex-wrap: wrap; gap: 0.2rem; }
/* A coloured tag (php/utils/tags.php, the tags control): --tg is its colour - a tint behind the text and a ring,
   so the words stay readable in both themes. The icon says which field an automatic tag comes from. */
.badge.tg { background: color-mix(in srgb, var(--tg, #9aa4b2) 22%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--tg, #9aa4b2) 62%, transparent); color: var(--net-text-primary); font-weight: 500; text-decoration: none; white-space: nowrap; }
a.badge.tg:hover { background: color-mix(in srgb, var(--tg, #9aa4b2) 45%, transparent); text-decoration: none; }
.badge.tg .tg-i { margin-right: 0.25rem; font-size: 0.85em; }
.ctrl-tags .tags-locked { display: contents; }
.ctrl-tags .tag-chip.is-locked { padding-right: 0.6rem; cursor: help; }
/* Settings > Attention / Flag / Tag colors: see "Colour lists" near the end of this file. */
/* A row with a SUB-ROW (the Items badge line): the cells up to the name span both lines, the sub-row's one
   cell sits under the columns after it. The two <tr> read as one row. */
table.data tr.has-sub > td:not([rowspan]) { border-bottom: 0; padding-bottom: 0.15rem; vertical-align: top; }
table.data tr.sub-row > td.sub { padding-top: 0; white-space: normal; }
table.data tbody tr.has-sub:hover + tr.sub-row, table.data tbody tr.has-sub:has(+ tr.sub-row:hover) { background: var(--net-bg-accent); }
table.data tbody tr.is-picked + tr.sub-row { background: var(--dp-picked-row); }
/* The badges sit at the RIGHT end of the sub-row (owner, 2026-10-06), wrapping from the right. */
.item-strip { display: flex; flex-wrap: wrap; gap: 0.25rem; align-items: center; justify-content: flex-end; }
.item-strip .badge { white-space: nowrap; }
.item-strip .bx-needs b { margin-right: 0.15rem; }
.item-strip .bx-needs.is-primary { box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--tg) 80%, transparent); }
/* The Columns menu's "Badges: ..." ticks. */
.hide-needs .bx-needs, .hide-tags .bx-tags, .hide-damage .bx-damage { display: none; }
.col-picker-badge { padding: 0.15rem 0.5rem 0.15rem 1.6rem; }
.col-picker-badge:first-of-type, .col-picker-item + .col-picker-badge { border-top: 1px solid var(--net-border); margin-top: 0.25rem; padding-top: 0.4rem; }
.le-v-party .badge, .tl-v-people .badge { margin-right: 0.2rem; }
/* Timeline category chips and filters wear badge colours (--tg, Settings > Tag colors > Timeline categories). */
.tl-chip.tg { background: color-mix(in srgb, var(--tg, #7d8796) 22%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--tg, #7d8796) 62%, transparent); color: var(--net-text-primary); }
.tl-chip.tg.is-on { background: color-mix(in srgb, var(--tg, #7d8796) 70%, transparent); box-shadow: inset 0 0 0 2px var(--tg, #7d8796); color: #fff; font-weight: 600; }
/* The active filters, above the category list: each a badge, × removes it. */
.tl-active { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem; margin: var(--net-spacing-sm) 0 0; font-size: var(--net-font-size-sm); }
.tl-active .tl-active-x { font-size: var(--net-font-size-sm); padding: 0.15rem 0.6rem; }
.tl-active .tl-active-x span { margin-left: 0.25rem; opacity: 0.7; }
.tl-active .tl-active-x:hover span { opacity: 1; }
.tl-active-clear { font-size: var(--net-font-size-xs); margin-left: 0.25rem; }
.tl-status-link { color: inherit; text-decoration: none; }
.tl-status-link:hover { text-decoration: underline; }
/* Timeline filters: one toolbar line (claim, from, to, search), then the badge rows - category, status. */
.tl-toolbar { flex-wrap: nowrap; }
.tl-toolbar .ctrl-wrapper.tl-date { flex: 0 0 9.25rem; }
.tl-toolbar .ctrl-wrapper.tl-date .ctrl-field { padding-left: 0.45rem; padding-right: 0.3rem; }
.tl-toolbar .ctrl-wrapper[data-field="q"] { flex: 1 1 12rem; min-width: 8rem; }
@media (max-width: 760px) { .tl-toolbar { flex-wrap: wrap; } }
.tl-count { margin-bottom: var(--net-spacing-xs); }
.tl-filters { display: block; margin: 0.4rem 0 0; font-size: var(--net-font-size-sm); border-top: 1px solid var(--net-border); }
.tl-filters .tl-cats-list { display: flex; flex-wrap: wrap; align-items: center; gap: 0.3rem; }
/* A filter SECTION: emoji + title (a size up from the badges), a thin rule under it, its badges folded away until asked. */
.tl-filter-group { border-bottom: 1px solid var(--net-border); }
.tl-filter-group > summary { cursor: pointer; list-style: none; display: flex; align-items: center; gap: 0.45rem; padding: 0.45rem 0.15rem; }
.tl-filter-group > summary::-webkit-details-marker { display: none; }
.tl-filter-group > summary::after { content: '▸'; margin-left: auto; color: var(--net-text-muted); font-size: 0.8rem; }
.tl-filter-group[open] > summary::after { content: '▾'; }
.tl-filter-group > summary:hover { background: var(--net-bg-accent); }
.tl-filters-label { font-size: 1.05rem; font-weight: 600; color: var(--net-text-primary); }
.tl-filters-label .tl-sec-i { flex: 0 0 1.4rem; text-align: center; }
.tl-filters-label .tl-sec-on { font-size: var(--net-font-size-xs); font-weight: 600; }
.tl-filters-label .tl-sec-n { font-weight: 400; }
.tl-filter-group > .tl-cats-list { padding: 0.1rem 0.15rem 0.6rem 2rem; margin-top: 0; }
/* The whole filter block folds under "Filters". */
.tl-filters-box { margin-bottom: var(--net-spacing-md); }
.tl-filters-box > summary { cursor: pointer; list-style: none; }
.tl-filters-box > summary::-webkit-details-marker { display: none; }
.tl-filters-box > summary::before { content: '▸'; display: inline-block; width: 1rem; color: var(--net-text-muted); }
.tl-filters-box[open] > summary::before { content: '▾'; }
.tl-filters-title { font-weight: 600; }
.tl-filters .tl-chip.is-more { display: none; }
.tl-filters .is-all .tl-chip.is-more { display: inline-block; }
.tl-chip.tg small { opacity: 0.75; font-weight: 600; margin-left: 0.15rem; }
/* Badge filters on Funds and Items share the Timeline's block; an icon in a chip sits like in a tag. */
.tl-chip.tg .tg-i { margin-right: 0.2rem; font-size: 0.85em; }
.tl-filters .is-all .js-chips-more, .tl-filters .js-chips-more { margin-left: 0.2rem; }
/* Segmented control with BUTTONS (Timeline's Expand all | Collapse all): the look of the Simple | Adjuster toggle. */
.view-toggle button { padding: 0.3rem 0.7rem; border: 0; background: transparent; color: var(--net-text-muted); font: inherit; font-weight: 600; white-space: nowrap; cursor: pointer; }
.view-toggle button + button { border-left: 1px solid var(--net-border); }
.view-toggle button:hover, .view-toggle button:focus-visible { background: var(--net-bg-accent); color: var(--net-text-primary); }
.view-toggle button:active { background: var(--net-color-primary); color: #fff; }
/* The Columns menu on a filter line (Items): after the Filter button, never stretched. */
.toolbar > .toolbar-cols { flex: 0 0 auto; }
.toolbar > .toolbar-cols .col-picker > summary { min-height: 40px; display: inline-flex; align-items: center; }
/* Under the listing-picture placeholder: the person supplies the picture link (item editor). */
.product-pic { flex-direction: column; align-items: stretch; }   /* the picture, then the button under it */
.product-pic .pp-paste { display: block; flex: 0 0 auto; width: 132px; margin-top: 0.35rem; white-space: normal; line-height: 1.2; padding: 0.3rem 0.25rem; min-height: 0; }
.product-pic .pp-paste[hidden], .pp-manual[hidden] { display: none; }
/* "Add" type buttons sit on the RIGHT, everywhere (owner, 2026-10-05): a form's own Add / Save / Import row ends at
   the right edge (the sign-in card keeps its own layout); page-level ones are the right-hand .actions of the head line. */
.form-actions { justify-content: flex-end; }
.page-sign-in .form-actions { justify-content: flex-start; }

/* How DamagePort looks to you (partials/blocks/profile-look.php, on /profile only). */
.look-card { display: grid; gap: var(--net-spacing-lg); }
.look-row { display: grid; gap: var(--net-spacing-sm); }
.look-head { display: flex; flex-direction: column; gap: 0.15rem; }
.look-head small { font-size: var(--net-font-size-sm); }
.look-row .ui-pick { font-size: var(--net-font-size-sm); justify-self: start; }
.look-row .ui-pick a, .look-row .ui-pick span { padding: 0.45rem 0.9rem; }
.look-blurbs { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.25rem; font-size: var(--net-font-size-sm); }
.look-blurbs li { padding: 0.35rem 0.6rem; border-left: 3px solid transparent; border-radius: var(--net-border-radius-sm); }
.look-blurbs li.is-on { border-left-color: var(--net-color-primary); background: var(--net-bg-accent); }
@media (max-width: 600px) {
    .look-row .ui-pick { display: flex; flex-wrap: wrap; justify-self: stretch; }
    .look-row .ui-pick a, .look-row .ui-pick span { flex: 1 1 auto; text-align: center; }
    .profile-menu-row { flex-direction: column; align-items: flex-start; gap: 0.3rem; }
}

/* The Items page's Grouping pane (pages/items/_grouping.php; the Xactimate model's XactContents layout): rooms with
   their subtotal and line count on the left of the grid, the room in view marked. Phones fold it above the grid. */
.items-split { display: flex; gap: var(--net-spacing-md); align-items: flex-start; }
.items-split > .table-wrap { flex: 1 1 auto; min-width: 0; }
/* Full length, no scrollbar of its own (owner, 2026-10-06): taller than the screen = the PAGE scrolls. Not sticky either -
   a sticky pane taller than the screen would hide its lower rooms until the grid ended. */
.grouping-pane { flex: 0 0 19rem; width: 19rem; background: var(--net-bg-card); border: 1px solid var(--net-border); border-radius: var(--net-border-radius-md); font-size: var(--net-font-size-sm); }
.grouping-pane summary { list-style: none; cursor: default; }
.grouping-pane summary::-webkit-details-marker { display: none; }
.grouping-head { display: flex; align-items: center; justify-content: space-between; padding: 0.45rem 0.6rem; border-bottom: 1px solid var(--net-border); background: var(--net-bg-accent); font-weight: 600; }
.grouping-head a { font-weight: 400; font-size: var(--net-font-size-xs); }
.grouping-cols { display: grid; grid-template-columns: 1fr 5.75rem 2.6rem; gap: 0.4rem; padding: 0.3rem 0.6rem; color: var(--net-text-muted); font-size: var(--net-font-size-xs); border-bottom: 1px solid var(--net-border); }
.grouping-cols span:nth-child(n+2), .grouping-row .g-sum, .grouping-row .g-n { text-align: right; font-variant-numeric: tabular-nums; }
.grouping-row { display: grid; grid-template-columns: 1fr 5.75rem 2.6rem; gap: 0.4rem; padding: 0.3rem 0.6rem; color: var(--net-text-primary); text-decoration: none; border-left: 3px solid transparent; }
.grouping-row:hover { background: var(--net-bg-accent); text-decoration: none; }
.grouping-row.is-on { background: var(--dp-edit-row); border-left-color: var(--net-color-primary); font-weight: 600; }
.grouping-row.is-root { font-weight: 600; }
.grouping-row.is-level { color: var(--net-text-muted); font-size: var(--net-font-size-xs); text-transform: uppercase; letter-spacing: 0.04em; padding-top: 0.5rem; pointer-events: none; }
.grouping-row.is-room { padding-left: 1.4rem; }
.grouping-row.is-muted .g-name { color: var(--net-text-muted); }
.grouping-row .g-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.grouping-row .g-name code { font-size: 0.7rem; color: var(--net-text-muted); margin-left: 0.3rem; }
@media (max-width: 900px) {
    .items-split { display: block; }
    .grouping-pane { position: static; width: auto; max-height: none; margin-bottom: var(--net-spacing-md); }
    .grouping-pane summary { cursor: pointer; }
    .grouping-pane:not([open]) .grouping-cols, .grouping-pane:not([open]) .grouping-row { display: none; }
}

/* ── Grid mode on the Items table ("Excel mode", pages/items/_row.php + ui.grid.js) ──
   A spreadsheet, not a form in a table (owner, 2026-10-06, after XactContents' Inventory grid): thin gridlines on
   every cell, 28px rows, small type, and a field that IS the cell - no box, no underline, no spinner - until it has
   the focus, when it gets Excel's blue outline. The wrap is its own scroll box (both scrollbars in view, the header
   sticky), so a wide grid scrolls sideways without the page. */
.table-wrap.is-grid-wrap { overflow-x: clip; border: 1px solid var(--net-border-accent); border-radius: var(--net-border-radius-sm); background: var(--net-bg-card); }
/* ONE vertical scrollbar - the page's (owner, 2026-10-06: a box scrolling inside a scrolling page confuses people). Sideways:
   the columns are fitted to the window by default (ui.colresize.js), so there is nothing to scroll; when a person drags
   them wider, this thin bar pinned to the bottom of the screen is the only sideways scrollbar (ui.grid.js keeps it and
   the grid in step). The wrap's own bar is hidden. */
.grid-hscroll { position: sticky; bottom: 0; z-index: var(--net-z-sticky); height: 14px; overflow-x: auto; overflow-y: hidden; background: var(--net-bg-accent); border: 1px solid var(--net-border-accent); border-top: 0; border-radius: 0 0 var(--net-border-radius-sm) var(--net-border-radius-sm); display: none; }
.grid-hscroll.is-needed { display: block; }
.grid-hscroll > div { height: 1px; }
table.data.is-grid { border-collapse: separate; border-spacing: 0; font-size: 0.8rem; }
table.data.is-grid th, table.data.is-grid td { border-right: 1px solid var(--net-border); border-bottom: 1px solid var(--net-border); height: 28px; padding: 0 0.35rem; vertical-align: middle; white-space: nowrap; }
table.data.is-grid th:last-child, table.data.is-grid td:last-child { border-right: 0; }
table.data.is-grid th { padding: 0.25rem 0.4rem; background: var(--net-bg-accent); font-size: 0.74rem; font-weight: 600; z-index: 2; box-shadow: inset 0 -1px 0 var(--net-border-accent); }
table.data.is-grid td.wrap { white-space: nowrap; min-width: 0; }
table.data.is-grid td:has(> .grid-cell) { padding: 0; }
table.data.is-grid td > .ctrl-wrapper.grid-cell { margin: 0; display: block; }
table.data.is-grid .grid-cell .ctrl-field { display: block; width: 100%; min-height: 28px; height: 28px; padding: 0 0.35rem; border: 0; border-radius: 0; background: transparent; box-shadow: none; font-size: 0.8rem; color: inherit; }
table.data.is-grid .grid-cell .ctrl-field:focus { outline: 2px solid var(--net-color-primary); outline-offset: -2px; background: var(--net-bg-primary); box-shadow: none; }
table.data.is-grid .grid-cell .ctrl-field[readonly] { background: transparent; color: var(--net-text-muted); }
table.data.is-grid .grid-cell input[type="number"] { -moz-appearance: textfield; appearance: textfield; text-align: right; }
table.data.is-grid .grid-cell input::-webkit-outer-spin-button, table.data.is-grid .grid-cell input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
table.data.is-grid .grid-cell select.ctrl-field { padding-right: 1.1rem; text-overflow: ellipsis; }
table.data.is-grid .grid-cell.ctrl-checkbox .ctrl-check { min-height: 28px; height: 28px; margin: 0; justify-content: center; }
table.data.is-grid .money-box.has-money:not(:focus-within) > .money-view { padding: 0 0.35rem; justify-content: flex-end; }
table.data.is-grid td.grid-name { min-width: 22rem; position: relative; }
table.data.is-grid td.grid-name .grid-cell .ctrl-field { padding-right: 1.3rem; }
table.data.is-grid td.grid-name .flag-swatch { position: absolute; left: 0.2rem; top: 50%; transform: translateY(-50%); z-index: 1; }
table.data.is-grid td.grid-name .flag-swatch + .grid-cell .ctrl-field { padding-left: 1.2rem; }
table.data.is-grid td.grid-name .grid-open { position: absolute; right: 0.2rem; top: 50%; transform: translateY(-50%); font-size: 0.75rem; line-height: 1; opacity: 0.45; text-decoration: none; }
table.data.is-grid td.grid-name .grid-open:hover { opacity: 1; }
table.data.is-grid td.grid-notes { min-width: 14rem; }
table.data.is-grid td.num { width: 6.25rem; text-align: right; }
table.data.is-grid td.grid-xact { padding: 0; }
table.data.is-grid td.grid-xact .grid-cell { display: inline-block; width: 3.4rem; margin: 0; vertical-align: top; border-right: 1px solid var(--net-border); }
table.data.is-grid td.grid-xact .grid-cell + .grid-cell { width: 4.6rem; border-right: 0; }
table.data.is-grid td > .ctrl-wrapper.table-pick { min-width: 11rem; }
table.data.is-grid td > .ctrl-wrapper.table-pick .ctrl-field { max-width: none; }
table.data.is-grid td code { font-size: 0.72rem; }
table.data.is-grid tbody tr:hover { background: transparent; }
table.data.is-grid tbody tr:hover td { background: var(--dp-hover-row); }
table.data.is-grid tbody tr:has(.ctrl-field:focus) td { background: var(--dp-edit-row); }
table.data.is-grid tbody tr.is-picked td { background: var(--dp-picked-row); }
table.data.is-grid tr.grid-new td { background: var(--dp-edit-row); }
table.data.is-grid tr.grid-new .grid-cell .ctrl-field { font-style: italic; }
table.data.is-grid td .pick { margin: 0; }
table.data.is-grid td > .grid-cell { height: 28px; overflow: hidden; }
table.data.is-grid .grid-cell.ctrl-checkbox, table.data.is-grid .grid-cell.ctrl-checkbox .ctrl-check { height: 28px; min-height: 0; padding: 0; margin: 0; line-height: 28px; display: flex; align-items: center; justify-content: center; }
table.data.is-grid .grid-cell.ctrl-checkbox .ctrl-field { width: 1rem; height: 1rem; min-height: 0; margin: 0; }
/* Sized columns + drag handles (ui.colresize.js): fixed layout obeys the <th> widths; cells cut what does not fit. */
table.data.is-grid { table-layout: fixed; width: 100%; }
table.data.is-grid th, table.data.is-grid td { overflow: hidden; text-overflow: ellipsis; }
table.data.is-grid th { position: sticky; }
table.data.is-grid th .col-grip { position: absolute; top: 0; right: -4px; width: 8px; height: 100%; cursor: col-resize; z-index: 3; }
table.data.is-grid th .col-grip:hover, table.data.is-resizing th .col-grip { background: color-mix(in srgb, var(--net-color-primary) 45%, transparent); }
table.data.is-resizing { user-select: none; }
table.data.is-grid td.grid-name { min-width: 0; }
/* Any other list with sized columns (table.is-sized - Settings > My Team): same fixed layout and handles; a dropdown
   fills its column (no 10rem floor), long words break instead of pushing the column wider. */
table.data.is-sized { table-layout: fixed; width: 100%; }
table.data.is-sized th { position: sticky; overflow: hidden; text-overflow: ellipsis; }
table.data.is-sized td { overflow: hidden; overflow-wrap: anywhere; }
table.data.is-sized th .col-grip { position: absolute; top: 0; right: -4px; width: 8px; height: 100%; cursor: col-resize; z-index: 3; }
table.data.is-sized th .col-grip:hover, table.data.is-sized.is-resizing th .col-grip { background: color-mix(in srgb, var(--net-color-primary) 45%, transparent); }
/* The handle is FINDABLE (owner, 2026-10-07: "only visible when you accidentally mouse over it"): a thin grey line at every
   resizable header's right edge, brighter on hover / while dragging. Drawn inside the handle's left half, because the <th>
   clips what sticks out past its edge. */
table.data.is-grid th .col-grip::after, table.data.is-sized th .col-grip::after { content: ''; position: absolute; top: 22%; bottom: 22%; left: 2px; width: 1px; background: var(--net-text-muted); opacity: 0.45; pointer-events: none; }
table.data.is-grid th .col-grip:hover::after, table.data.is-sized th .col-grip:hover::after, table.data.is-resizing th .col-grip::after { top: 0; bottom: 0; width: 2px; opacity: 1; background: var(--net-color-primary); }
table.data.is-sized td > .ctrl-wrapper.table-pick { min-width: 0; }
table.data.is-sized .table-pick .ctrl-field, table.data.is-sized .table-pick .roles-main { max-width: none; }
.team-tools { display: flex; justify-content: flex-start; align-items: center; gap: var(--net-spacing-sm); margin-bottom: var(--net-spacing-xs); }
.team-tools .team-cols { margin-left: auto; }
.view-toggle button.is-on, .view-toggle button.is-on:hover { background: var(--net-color-primary); color: #fff; }
/* My Team > Org (2026-10-07): a tree of cards, each under their team leader; the lines are the tree's own borders.
   TOP LEVELS SIT SIDE BY SIDE (owner: "2 maybe 3 on a single row"): the root list is a grid of ~16rem columns, one per
   top-level person, their team below them. Any card with a team in view folds it (.org-fold = the team count + caret;
   cookie dp_org_fold). Drag a card (.is-movable) onto another / onto .org-top; local.people.js marks the valid targets. */
.org { background: var(--net-bg-card); border: 1px solid var(--net-border); border-radius: var(--net-border-radius-md); padding: var(--net-spacing-md); }
.org[hidden], .table-wrap[hidden], .team-tools [hidden] { display: none; }
.org-help { font-size: var(--net-font-size-xs); margin: 0 0 var(--net-spacing-sm); }
.org-top { border: 2px dashed var(--net-border-accent); border-radius: var(--net-border-radius-md); padding: 0.45rem 0.75rem; margin-bottom: var(--net-spacing-sm); font-size: var(--net-font-size-sm); color: var(--net-text-muted); text-align: center; }
.org-tree { list-style: none; margin: 0; padding: 0; }
.org-tree.is-root { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 16rem), 1fr)); gap: var(--net-spacing-md) var(--net-spacing-lg); align-items: start; }
.org-tree .org-tree { margin-left: 0.85rem; padding-left: 1rem; border-left: 1px solid var(--net-border-accent); }
.org-node { position: relative; padding-top: 0.35rem; }
.org-tree.is-root > .org-node { padding-top: 0; }
.org-node.is-folded > .org-tree { display: none; }
.org-tree .org-tree > .org-node::before { content: ''; position: absolute; left: -1rem; top: calc(0.35rem + 1.9rem); width: 1rem; border-top: 1px solid var(--net-border-accent); }
/* the last child's line stops at its card: a background patch hides the parent's vertical border below it */
.org-tree .org-tree > .org-node:last-child::after { content: ''; position: absolute; left: calc(-1rem - 1px); top: calc(0.35rem + 1.9rem + 1px); bottom: 0; width: 1px; background: var(--net-bg-card); }
/* one fixed card height, so the connector (1.9rem down = the card's middle) always meets it */
.org-card { display: flex; align-items: center; gap: 0.5rem; padding: 0.35rem 0.5rem; background: var(--net-bg-primary); border: 1px solid var(--net-border); border-radius: var(--net-border-radius-md); box-sizing: border-box; height: 3.8rem; overflow: hidden; }
.org-card.is-me { border-color: var(--net-color-primary); }
.org-card.is-off { opacity: 0.6; }
.org-card.is-movable { cursor: grab; }
.org-card.is-dragging { opacity: 0.4; }
.org-grip { color: var(--net-text-muted); font-size: 0.95rem; line-height: 1; cursor: grab; user-select: none; margin-right: -0.15rem; }
.org-card .org-avatar { width: 30px; height: 30px; font-size: 0.68rem; border-color: var(--net-border-accent); }
.org-body { flex: 1 1 auto; min-width: 0; }
.org-name { font-weight: 600; font-size: var(--net-font-size-sm); line-height: 1.25; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.org-sub { display: flex; flex-wrap: nowrap; gap: 0.2rem; margin-top: 0.1rem; overflow: hidden; }
.org-sub .role-badges { display: contents; }
.org-sub .badge { font-size: 0.62rem; padding: 0.05rem 0.4rem; white-space: nowrap; flex: 0 0 auto; }
.org-sub .role-badges .badge:first-child { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.org-meta { font-size: 0.68rem; line-height: 1.3; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.org-count { font-size: 0.62rem; flex: 0 0 auto; }
/* The fold button = the team count + a caret (▾ open, ▸ folded). */
.org-fold { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 0.25rem; padding: 0.15rem 0.4rem; border: 1px solid var(--net-border-accent); border-radius: var(--net-border-radius-xl); background: transparent; color: var(--net-text-primary); font: inherit; font-size: 0.66rem; font-weight: 600; cursor: pointer; }
.org-fold:hover, .org-fold:focus-visible { background: var(--net-bg-accent); }
.org-caret::before { content: ''; display: inline-block; width: 0; height: 0; border-left: 4px solid transparent; border-right: 4px solid transparent; border-top: 5px solid currentColor; transition: transform var(--net-transition-fast); }
.org-node.is-folded > .org-card .org-caret::before { transform: rotate(-90deg); }
.org-node.is-folded > .org-card .org-fold { border-color: var(--net-color-primary); }
.org.is-dragging .org-card[data-drop="ok"], .org.is-dragging .org-top[data-drop="ok"] { outline: 2px dashed var(--net-color-primary); outline-offset: 2px; }
.org.is-dragging .org-card:not([data-drop="ok"]):not(.is-dragging) { opacity: 0.45; }
.org .org-card.is-over, .org .org-top.is-over { background: color-mix(in srgb, var(--net-color-primary) 18%, var(--net-bg-primary)); outline-style: solid; }
@media (max-width: 600px) {
    .org { padding: var(--net-spacing-sm); }
    .org-tree .org-tree { margin-left: 0.5rem; padding-left: 0.75rem; }
    .org-tree .org-tree > .org-node::before { left: -0.75rem; width: 0.75rem; }
    .org-tree .org-tree > .org-node:last-child::after { left: calc(-0.75rem - 1px); }
    .org-grip { display: none; }
}
/* A wrapping name box (the cell is two rows tall when a badge row sits under it): the wrapper is pinned to the
   cell's four edges, so the box fills it whatever the badge row's height, shows two lines and cuts the rest. */
table.data.is-grid td.grid-name > .grid-cell.grid-wrap { position: absolute; inset: 0; height: auto; overflow: hidden; }
table.data.is-grid td.grid-name > .grid-cell.grid-wrap .ctrl-field { height: 100%; min-height: 28px; resize: none; white-space: pre-wrap; overflow: hidden; line-height: 1.3; padding-top: 0.3rem; padding-bottom: 0.3rem; }
/* The badge row under a grid line starts at the LEFT of its cell (the list pushes it right, under the far columns;
   in a 2,000px grid "right" is off the screen). */
table.data.is-grid tr.sub-row > td.sub { height: auto; overflow: visible; white-space: normal; padding: 0.15rem 0.35rem 0.25rem; }
table.data.is-grid .item-strip { justify-content: flex-start; }
/* The wrapping name: the words show through .grid-view (clamped to the lines that fit, "…" at the cut) while the
   textarea underneath keeps the value with transparent text; on focus the overlay goes and the box is typed in. */
table.data.is-grid td.grid-name > .grid-view { position: absolute; inset: 0; z-index: 1; pointer-events: none; padding: 0.3rem 1.3rem 0.3rem 0.35rem; font-size: 0.8rem; line-height: 1.3; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; text-overflow: ellipsis; white-space: normal; overflow-wrap: anywhere; }
table.data.is-grid td.grid-name .flag-swatch ~ .grid-view { padding-left: 1.2rem; }
table.data.is-grid td.grid-name:not(:focus-within) > .grid-cell.grid-wrap .ctrl-field { color: transparent; caret-color: transparent; }
table.data.is-grid td.grid-name:focus-within > .grid-view { display: none; }
table.data.is-grid td.grid-name > .grid-cell.grid-wrap textarea.ctrl-field { height: 100%; }
/* One-line boxes end in "…" too while they are not being typed in. */
table.data.is-grid .grid-cell input.ctrl-field:not(:focus) { text-overflow: ellipsis; }
/* Saved: the ROW flashes green and fades (owner, 2026-10-06 - the little "Saved" popup is clipped by the cells and
   Xactimate feels like this); a failed save flashes red and the row keeps a red edge until it saves. */
table.data.is-grid .autosave-indicator { display: none !important; }
/* The pulse: a strong green (red) wash with a brightened, bold line that fades over 1.6 s - must be seen in either theme (owner). */
@keyframes dp-grid-saved { 0%, 20% { background-color: color-mix(in srgb, var(--dp-money-in) 62%, transparent); box-shadow: inset 0 0 0 2px var(--dp-money-in); } 100% { background-color: transparent; box-shadow: none; } }
@keyframes dp-grid-failed { 0% { background-color: color-mix(in srgb, var(--net-color-danger) 62%, transparent); box-shadow: inset 0 0 0 2px var(--net-color-danger); } 100% { background-color: transparent; box-shadow: none; } }
table.data.is-grid tr.is-saved-flash > td { animation: dp-grid-saved 0.7s ease-out; }
table.data.is-grid tr.is-failed-flash > td { animation: dp-grid-failed 1.6s ease-out; }
table.data.is-grid tr.has-save-error > td:first-child { box-shadow: inset 3px 0 0 var(--net-color-danger); }
/* Filter section headings a notch smaller (owner, 2026-10-06). */
.tl-filter-group > summary { padding: 0.3rem 0.15rem; font-size: 0.88rem; }
.tl-filter-group > summary > :not(.badge) { font-size: inherit; }
/* The pinned sideways bar for ANY wide table (ui.tablescroll.js): shown only when the table is wider than its wrap. */
.table-hscroll { position: sticky; bottom: 0; z-index: var(--net-z-sticky); height: 14px; overflow-x: auto; overflow-y: hidden; background: var(--net-bg-accent); border: 1px solid var(--net-border-accent); border-top: 0; border-radius: 0 0 var(--net-border-radius-sm) var(--net-border-radius-sm); display: none; }
.table-hscroll.is-needed { display: block; }
.table-hscroll > div { height: 1px; }
.items-split > .table-col, .table-col { flex: 1 1 auto; min-width: 0; }
/* Money in a grid cell: the formatted label (ui.money.js) shows and the raw number stays transparent until focused -
   the grid's "color: inherit" had put both on screen at once. */
table.data.is-grid .money-box.has-money:not(:focus-within) > input.ctrl-field { color: transparent; }
/* Quick Entry strip over the Items grid (pages/items/_strip.php; X1's line-item entry; local.items-strip.js). */
.qe-strip { background: var(--net-bg-card); border: 1px solid var(--net-border-accent); border-radius: var(--net-border-radius-sm); margin-bottom: var(--net-spacing-sm); font-size: 0.82rem; }
.qe-head { display: flex; align-items: center; gap: 0.6rem; padding: 0.3rem 0.6rem; background: var(--net-bg-accent); border-bottom: 1px solid var(--net-border); }
.qe-title { font-weight: 600; }
.qe-which { font-size: var(--net-font-size-xs); }
.qe-actions { margin-left: auto; display: flex; gap: 0.35rem; }
.qe-actions .btn { min-height: 26px; padding: 0.1rem 0.9rem; font-size: 0.8rem; }
.qe-row { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.25rem 0.6rem; padding: 0.35rem 0.6rem; }
.qe-row + .qe-row { padding-top: 0; }
.qe-strip .ctrl-wrapper.qe-field { margin: 0; flex: 0 0 auto; }
.qe-strip .ctrl-wrapper.qe-field > label { font-size: 0.68rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em; color: var(--net-text-muted); }
.qe-strip .ctrl-wrapper.qe-field .ctrl-field { min-height: 28px; height: 28px; padding: 0 0.4rem; font-size: 0.82rem; width: 6rem; }
.qe-strip .ctrl-wrapper.qe-field.ctrl-type-number .ctrl-field { width: 5.5rem; text-align: right; }
.qe-strip [data-field="xact_cat"] .ctrl-field { width: 4rem; }
.qe-strip [data-field="xact_sel"] .ctrl-field { width: 5rem; }
.qe-strip .qe-desc { flex: 1 1 18rem; }
.qe-strip .qe-desc .ctrl-field { width: 100%; }
.qe-strip .qe-room .ctrl-field { width: 13rem; }
.qe-strip [data-field="coverage"] .ctrl-field { width: 12rem; }
.qe-strip [data-field="condition_before"] .ctrl-field { width: 7rem; }
.qe-strip .ctrl-checkbox.qe-field .ctrl-check { min-height: 28px; }
.qe-calc { display: flex; align-items: flex-end; gap: 0.3rem; }
.qe-op { padding-bottom: 0.45rem; color: var(--net-text-muted); }
.qe-total { padding-bottom: 0.35rem; font-weight: 600; font-variant-numeric: tabular-nums; min-width: 5rem; }
table.data.is-grid tbody tr.is-current td { background: var(--dp-picked-row); }
.qe-strip .ctrl-checkbox.qe-field .ctrl-check { gap: 0.35rem; font-size: 0.68rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em; color: var(--net-text-muted); padding-bottom: 0.1rem; }
.qe-strip .ctrl-checkbox.qe-field .ctrl-field { width: 1rem; height: 1rem; }
.tm-note { font-size: var(--net-font-size-xs); margin: 0 0 var(--net-spacing-sm); }
/* Quick Entry widths (owner, 2026-10-06): Desc, Grouping and Cov take the spare room - these outrank the 6rem default. */
.qe-strip .ctrl-wrapper.qe-field.qe-desc { flex: 3 1 20rem; }
.qe-strip .ctrl-wrapper.qe-field.qe-desc .ctrl-field { width: 100%; }
.qe-strip .ctrl-wrapper.qe-field.qe-room { flex: 1 1 14rem; }
.qe-strip .ctrl-wrapper.qe-field.qe-room .ctrl-field { width: 100%; }
.qe-strip .ctrl-wrapper.qe-field[data-field="coverage"] { flex: 1 1 14rem; }
.qe-strip .ctrl-wrapper.qe-field[data-field="coverage"] .ctrl-field { width: 100%; }
.qe-strip .ctrl-wrapper.qe-field[data-field="condition_before"] .ctrl-field { width: 8rem; }
/* A flagged line in the grid: the whole row faintly tinted with the flag's colour (no swatch; reads in both themes);
   the save flash paints over it and fades back to it. */
table.data tbody tr[style*="--flag"] > td { background-color: color-mix(in srgb, var(--flag) 6%, transparent); }
table.data tbody tr[style*="--flag"]:hover > td { background-color: color-mix(in srgb, var(--flag) 11%, transparent); }
.qe-strip .ctrl-wrapper.qe-field.qe-room { flex: 0 1 18rem; }
/* The list's item name: at most three lines, the rest cut with "…" (owner, 2026-10-06); the whole name is the tooltip. */
#items-table:not(.is-grid) td.wrap > a.item-name { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; text-overflow: ellipsis; }
/* The Items list / grid totals row (pages/items/default.php tfoot; owner 2026-10-07, XactContents RCV / Tax / Depr / ACV):
   every line the filters select that is in the claim - one group's subtotal when the Grouping pane picks one. */
table.data tfoot tr.items-totals > td { border-top: 2px solid var(--net-border-accent); background: var(--net-bg-accent); font-variant-numeric: tabular-nums; white-space: nowrap; }
table.data.is-grid tfoot tr.items-totals > td { height: 32px; padding: 0 0.35rem; }
/* Not priced yet (pages/items/_row.php td.is-unpriced; XactContents' yellow): drawn as a background IMAGE so it sits on top
   of whatever background COLOUR the row has (flag tint, hover, focus, the save flash) without replacing it.
   Kept faint on purpose (owner, 2026-10-07: "less bold") - a hint, not an alarm; one strength in --dp-unpriced. */
:root { --dp-unpriced: color-mix(in srgb, var(--net-color-warning) 12%, transparent); }
table.data td.is-unpriced { background-image: linear-gradient(var(--dp-unpriced), var(--dp-unpriced)); }
/* Pricing workspace (pages/pricing; XactContents' Pricing screen, 2026-10-07): the list of lines on the left (scrolls
   with the page - no scroll box of its own), the line being priced on the right, kept in view while the list scrolls. */
.pricing-split { display: grid; grid-template-columns: minmax(18rem, 26rem) minmax(0, 1fr); gap: var(--net-spacing-md); align-items: start; }
.pricing-list { background: var(--net-bg-card); border: 1px solid var(--net-border); border-radius: var(--net-border-radius-md); padding: var(--net-spacing-sm); min-width: 0; }
.pricing-tabs { display: flex; flex-wrap: wrap; margin-bottom: var(--net-spacing-sm); }
.pricing-tabs a { text-decoration: none; }
.pricing-tabs .pr-n { font-size: var(--net-font-size-xs); opacity: 0.8; margin-left: 0.2rem; }
.pricing-find { margin-bottom: var(--net-spacing-sm); }
.pricing-empty { padding: var(--net-spacing-md); text-align: center; }
.pr-group { padding: 0.5rem 0.4rem 0.2rem; font-size: var(--net-font-size-xs); font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; color: var(--net-text-muted); }
.pr-group code { text-transform: none; font-weight: 400; }
.pr-row { display: grid; grid-template-columns: 7.2rem minmax(0, 1fr) 2.2rem 5.5rem; gap: 0.4rem; align-items: center; padding: 0.3rem 0.4rem; border-left: 3px solid transparent; border-radius: var(--net-border-radius-sm); color: var(--net-text-primary); text-decoration: none; font-size: var(--net-font-size-sm); }
.pr-row:hover { background: var(--dp-hover-row); text-decoration: none; }
.pr-row.is-on { background: var(--dp-edit-row); border-left-color: var(--net-color-primary); }
.pr-row.is-done { box-shadow: inset 0 0 0 1px var(--dp-money-in); }
.pr-row code { font-size: 0.72rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pr-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pr-qty { text-align: right; color: var(--net-text-muted); font-size: var(--net-font-size-xs); }
.pr-price { text-align: right; font-variant-numeric: tabular-nums; border-radius: var(--net-border-radius-sm); padding: 0.05rem 0.3rem; min-height: 1.3rem; }
.pr-price.is-unpriced, .pricing-facts dd.is-unpriced { background: var(--dp-unpriced); }
.pricing-work { position: sticky; top: calc(var(--net-header-height, 0px) + var(--dp-top-offset, 0px) + 0.5rem); display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--net-spacing-sm); min-width: 0; }
.pricing-work > .card { margin: 0; }
/* Head = a grid (owner, 2026-10-07): picture | meta line | buttons on the first row; the name and brand / model run from the
   picture's edge to the card's right edge under the buttons, instead of a narrow column beside them. */
.pricing-item-head { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: start; column-gap: 0; }
.pricing-head-text { display: contents; }
.pricing-item-head > .pricing-pic { grid-column: 1; grid-row: 1 / span 3; margin-right: var(--net-spacing-md); }
.pricing-item-head .pricing-meta { grid-column: 2; grid-row: 1; align-self: center; min-width: 0; }
.pricing-item-head > .pricing-nav { grid-column: 3; grid-row: 1; margin-left: var(--net-spacing-sm); }
.pricing-item-head .pricing-name, .pricing-item-head .pricing-bm { grid-column: 2 / -1; min-width: 0; }
.pricing-pic { width: 72px; height: 72px; object-fit: contain; background: #fff; border-radius: var(--net-border-radius-sm); flex: 0 0 auto; }
.pricing-name { margin: 0.15rem 0; font-size: 1.15rem; }
.pricing-nav { display: flex; gap: 0.3rem; flex: 0 0 auto; }
.pricing-facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr)); gap: 0.4rem var(--net-spacing-md); margin: var(--net-spacing-sm) 0 0; }
.pricing-facts dt { font-size: var(--net-font-size-xs); color: var(--net-text-muted); }
.pricing-facts dd { margin: 0; font-variant-numeric: tabular-nums; border-radius: var(--net-border-radius-sm); }
.pricing-verified { margin: var(--net-spacing-sm) 0 0; font-size: var(--net-font-size-sm); color: var(--dp-money-in); }
.pricing-verified.is-skip { color: var(--net-text-muted); }
.pricing-sources { display: flex; flex-wrap: wrap; gap: 0.35rem; margin: 0.35rem 0; }
.pricing-actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--net-spacing-sm); }
.pricing-skip { display: inline-flex; align-items: center; gap: 0.35rem; }
.pricing-skip .ctrl-wrapper { margin: 0; }
/* AI pricing (local.ai.js pricing()): the card above the search - the line's photos as tiles to tick (with their captions),
   the status line, then what the AI found. Fields it filled carry ✨ until edited, as on Funds. */
:root { --dp-ai: #8b5cf6; }   /* the AI colour (Funds sets the same on its form) */
/* The "✨ AI mode" switch - Funds' receipts, /pricing (top right of the item card), the item editor's pricing panel. */
.ai-switch { display: inline-flex; align-items: center; gap: 0.4rem; padding: 0.2rem 0.65rem; border: 1px solid color-mix(in srgb, var(--dp-ai) 55%, transparent); border-radius: 999px; font-weight: 600; font-size: var(--net-font-size-sm); cursor: pointer; background: color-mix(in srgb, var(--dp-ai) 12%, transparent); white-space: nowrap; }
.ai-switch input { accent-color: var(--dp-ai); margin: 0; }
.pricing-nav { align-items: center; flex-wrap: wrap; justify-content: flex-end; }
.ai-panel-bar { display: flex; justify-content: flex-end; margin: 0 0 var(--net-spacing-sm); }
.pricing-ai[hidden] { display: none !important; }
.panel-body > .pricing-ai, .ai-panel-bar + .pricing-ai { margin-bottom: var(--net-spacing-md); }
.pr-ai-vals { display: grid; gap: 0.1rem; }
.pr-ai-vals a { overflow-wrap: anywhere; }
.pr-ai-btns { display: flex; flex-wrap: wrap; gap: 0.35rem; }
/* AI pricing posture (082): Conservative ← Balanced → Assertive. The track fills to the value in the AI purple. */
.ai-posture { display: grid; gap: 0.25rem; }
.ai-posture .ctrl-wrapper { margin: 0; }
.ai-posture input[type="range"] { width: 100%; margin: 0; accent-color: var(--dp-ai); height: 1.4rem; padding: 0; border: 0; background: transparent; box-shadow: none; cursor: pointer; }
.ai-posture input[type="range"]:disabled { cursor: not-allowed; opacity: 0.55; }
.ai-posture-scale { display: grid; grid-template-columns: 15fr 25fr 21fr 29fr 11fr; font-size: var(--net-font-size-xs); color: var(--net-text-muted); }
.ai-posture-scale span { text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ai-posture-scale span:first-child { text-align: left; } .ai-posture-scale span:last-child { text-align: right; }
.ai-posture-line { font-size: var(--net-font-size-sm); }
.ai-posture-lab { font-weight: 600; }
.ai-posture-read { font-size: var(--net-font-size-sm); }
.ai-posture-read b { color: var(--dp-ai); }
.ai-posture-box { margin-top: var(--net-spacing-md); padding-top: var(--net-spacing-sm); border-top: 1px solid var(--net-border); display: grid; gap: 0.35rem; }
.ai-posture-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.5rem; }
.ai-posture-head .form-section { margin: 0; }
.ai-posture-head .ctrl-wrapper { margin: 0; }
.ai-posture-intro { margin: 0; font-size: var(--net-font-size-sm); }
.ai-posture-box.is-off .ai-posture-read { opacity: 0.6; }
.ai-posture-box.is-panel { margin-top: 0; padding-top: 0; border-top: 0; }
.ai-posture-box.is-panel .ai-posture-head { flex-wrap: nowrap; align-items: flex-start; }
.ai-posture-box.is-panel .ai-posture-intro { flex: 1 1 0; min-width: 0; }
.ai-posture-box.is-panel .ai-posture-head > .ctrl-wrapper { flex: 0 0 auto; width: auto; max-width: none; }
@media (max-width: 600px) { .ai-posture-box.is-panel .ai-posture-head { flex-wrap: wrap; } }
.pricing-ai-posture { margin: 0.2rem 0; font-size: var(--net-font-size-sm); }
.pricing-ai-posture b { color: var(--dp-ai); }
/* AI describing (Item panel): the words it proposes, set off like a quote until "Use this description". */
.ds-ai-text { margin: 0.35rem 0; padding: 0.5rem 0.75rem; border-left: 3px solid var(--dp-ai); background: color-mix(in srgb, var(--dp-ai) 8%, transparent); border-radius: 0 4px 4px 0; white-space: pre-line; }
.pr-ai-comps { margin: 0; padding-left: 1.4rem; display: grid; gap: 0.1rem; min-width: 0; flex: 1 1 16rem; font-size: var(--net-font-size-sm); }
.pr-ai-comps li { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 0.5rem; min-width: 0; }
.pr-ai-comps li > a, .pr-ai-comps li > span:not(.badge) { min-width: 0; overflow-wrap: anywhere; max-width: 100%; }
.pr-ai-comps.is-dropped { list-style: none; padding-left: 1.4rem; color: var(--net-text-muted); }
.pr-ai-comps.is-dropped li { text-decoration: line-through; text-decoration-color: color-mix(in srgb, var(--net-text-muted) 60%, transparent); }
.pr-ai-comp-price { font-variant-numeric: tabular-nums; min-width: 5.5rem; }
.pr-ai-comps li.is-picked { font-weight: 600; }
.pr-ai-comps li.is-picked .pr-ai-comp-price { color: var(--dp-ai); }
.pr-ai-pick-badge { font-size: 0.66rem; background: color-mix(in srgb, var(--dp-ai) 22%, transparent); color: var(--dp-ai); }
.ai-trail { margin-top: var(--net-spacing-sm); --dp-ai: #8b5cf6; }
.ai-trail .pr-ai-comps { margin-top: 0.3rem; }
.badge.ai-mod { margin-left: 0.5rem; vertical-align: middle; font-size: 0.68rem; font-weight: 600; background: color-mix(in srgb, var(--dp-ai) 22%, transparent); color: var(--dp-ai); border: 1px solid color-mix(in srgb, var(--dp-ai) 55%, transparent); }
.pr-ai-hint { display: grid; gap: 0.2rem; margin: 0.35rem 0; font-size: var(--net-font-size-sm); }
.pr-ai-hint textarea { width: 100%; min-height: 2.6rem; resize: vertical; font: inherit; padding: 0.35rem 0.5rem; border-radius: var(--net-border-radius-base); border: 1px solid var(--net-border); background: var(--net-bg-input, transparent); color: inherit; }
.pr-ai-hint textarea:focus { outline: none; border-color: var(--dp-ai); box-shadow: 0 0 0 2px color-mix(in srgb, var(--dp-ai) 35%, transparent); }
.pr-ai-fix { display: flex; align-items: flex-start; gap: 0.35rem; padding: 0.3rem 0.5rem; border-radius: var(--net-border-radius-base); background: color-mix(in srgb, var(--dp-ai) 10%, transparent); cursor: pointer; }
.pr-ai-fix input { accent-color: var(--dp-ai); margin-top: 0.2rem; }
.pricing-ai { border-color: color-mix(in srgb, var(--dp-ai) 45%, var(--net-border)); }
/* Folded, the status line and the result still show under the header (they sit after the panel body). */
.pricing-ai.is-collapsed > .ai-status:not([hidden]), .pricing-ai.is-collapsed > .pricing-ai-result:not([hidden]) { margin-top: calc(var(--net-spacing-lg) + 0.35rem); }
.pricing-ai-head [data-role="pr-ai-go"] { background: var(--dp-ai); border-color: var(--dp-ai); }
.pricing-ai-help { margin: 0.3rem 0; font-size: var(--net-font-size-sm); }
.pricing-ai-photos { display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); gap: 0.4rem; margin: 0.35rem 0; }
.pr-ai-photo { position: relative; display: grid; gap: 0.15rem; padding: 3px; border: 2px solid transparent; border-radius: var(--net-border-radius-sm); cursor: pointer; opacity: 0.55; transition: opacity 0.15s, border-color 0.15s; }
.pr-ai-photo:hover { opacity: 0.85; }
.pr-ai-photo.is-on { opacity: 1; border-color: var(--dp-ai); background: color-mix(in srgb, var(--dp-ai) 10%, transparent); }
.pr-ai-photo.is-refused { animation: dp-ai-shake 0.3s linear 2; }
.pr-ai-photo input { position: absolute; top: 6px; left: 6px; margin: 0; z-index: 1; accent-color: var(--dp-ai); width: 1rem; height: 1rem; }
.pr-ai-thumb { display: block; aspect-ratio: 1; overflow: hidden; border-radius: var(--net-border-radius-sm); background: var(--net-bg-input, rgba(127,127,127,0.12)); }
.pr-ai-thumb img, .pr-ai-thumb .media-video { display: block; width: 100%; height: 100%; object-fit: cover; }
.pr-ai-thumb .media-video { position: relative; }
.pr-ai-cap { font-size: 0.7rem; line-height: 1.2; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@keyframes dp-ai-shake { 25% { transform: translateX(-3px); } 75% { transform: translateX(3px); } }
.pricing-ai .ai-status { display: flex; align-items: flex-start; gap: 0.6rem; margin: 0.35rem 0 0; font-size: var(--net-font-size-sm); padding: 0.35rem 0.6rem; border-radius: var(--net-border-radius-base); background: color-mix(in srgb, var(--dp-ai) 10%, transparent); }
.pricing-ai .ai-status[hidden], .pricing-ai-result[hidden] { display: none; }
.pricing-ai .ai-status.is-error { background: rgba(224, 82, 82, 0.15); color: var(--dp-tint-bad-text); }
.pricing-ai .ai-status.is-busy::before { content: ''; flex: 0 0 auto; display: inline-block; width: 0.8em; height: 0.8em; margin-top: 0.2em; border: 2px solid var(--dp-ai); border-right-color: transparent; border-radius: 50%; animation: dp-ai-spin 0.8s linear infinite; }
.pricing-ai .ai-status-text { flex: 1 1 auto; min-width: 0; }
.pricing-ai .ai-status-tools { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 0.35rem; }
.pricing-ai .ai-status-close { background: none; border: 0; color: inherit; font-size: 1.15rem; line-height: 1; padding: 0 0.2rem; cursor: pointer; opacity: 0.75; }
.pricing-ai .ai-status-close:hover { opacity: 1; }
@keyframes dp-ai-spin { to { transform: rotate(360deg); } }
.pricing-ai.is-reading .pr-ai-photo { pointer-events: none; }
.pricing-ai-result { margin-top: 0.5rem; padding-top: 0.5rem; border-top: 1px solid var(--net-border); font-size: var(--net-font-size-sm); display: grid; gap: 0.3rem; }
.pricing-ai-result p { margin: 0; }
.pr-ai-what { font-weight: 600; }
.pr-ai-price { display: flex; flex-wrap: wrap; align-items: center; gap: 0.2rem 0.4rem; font-variant-numeric: tabular-nums; }
.pr-ai-conf { margin-left: auto; font-size: 0.68rem; }
.pr-ai-conf.is-high { background: rgba(46, 160, 67, 0.2); color: var(--dp-tint-ok-text); }
.pr-ai-conf.is-medium { background: rgba(212, 160, 23, 0.22); color: var(--dp-tint-warn-text); }
.pr-ai-conf.is-low { background: rgba(224, 82, 82, 0.18); color: var(--dp-tint-bad-text); }
.pr-ai-notes { color: var(--dp-tint-warn-text); }
.pr-ai-looked { display: flex; flex-wrap: wrap; gap: 0.2rem 0.5rem; align-items: baseline; }
.pr-ai-sources { margin: 0; padding: 0; list-style: none; display: grid; gap: 0.1rem; min-width: 0; flex: 1 1 14rem; }
.pr-ai-sources a { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pricing-form .ctrl-wrapper.is-ai .ctrl-field, .pricing-search .ctrl-wrapper.is-ai .ctrl-field, .page-item .ctrl-wrapper.is-ai .ctrl-field { box-shadow: 0 0 0 2px color-mix(in srgb, var(--dp-ai) 65%, transparent); }
.pricing-form .ctrl-wrapper.is-ai > label::after, .pricing-search .ctrl-wrapper.is-ai > label::after, .page-item .ctrl-wrapper.is-ai > label::after { content: ' ✨ ' attr(data-ai-note); font-weight: 400; font-size: var(--net-font-size-xs); color: var(--dp-ai); }
@media (max-width: 600px) { .pricing-ai-photos { grid-template-columns: repeat(auto-fill, minmax(72px, 1fr)); } .pr-ai-conf { margin-left: 0; } }
@media (max-width: 900px) {
    .pricing-split { grid-template-columns: minmax(0, 1fr); }   /* not 1fr: its min-content width pushed every card past a phone screen */
    .pricing-work { position: static; order: -1; }
}
/* The Items bulk row's "Set…" (field, value, Apply) stays together when the row wraps. */
#items-actions .bulk-set { display: inline-flex; align-items: center; gap: 0.35rem; flex-wrap: nowrap; }
#items-actions .bulk-set [data-role="bulk-value-box"] .ctrl-wrapper { margin: 0; }
/* ONE line on a desktop (owner, 2026-10-08: the wrap "causes too much drama"): the dropdowns give up width instead of
   pushing Flag / Set… onto a second line - each cut with "…" (the full words stay in the open list), the room list
   gives up the most; words and buttons never shrink. Tablets and phones keep the wrap. */
@media (min-width: 1024px) {
    #items-actions { flex-wrap: nowrap; }
    #items-actions > span, #items-actions > label, #items-actions .bulk-set > .btn { flex: 0 0 auto; white-space: nowrap; }
    #items-actions > .ctrl-wrapper.fit, #items-actions .bulk-set > .ctrl-wrapper { flex: 0 1 auto; min-width: 6rem; }
    #items-actions > .ctrl-wrapper.fit:has([data-role="move-room"]) { flex-shrink: 3; min-width: 8rem; }
    #items-actions .bulk-set { display: contents; }   /* its field, value and Apply share out the row like the rest */
    #items-actions .bulk-set [data-role="bulk-value-box"] { display: flex; flex: 0 1 auto; min-width: 6rem; }
    #items-actions .bulk-set [data-role="bulk-value-box"][hidden] { display: none; }
    #items-actions .bulk-set [data-role="bulk-value-box"] > * { flex: 1 1 auto; min-width: 0; }
    #items-actions .ctrl-field { width: 100%; min-width: 0; max-width: 100%; text-overflow: ellipsis; }   /* max-width: the value box is given width: 9rem inline */
}
/* F9 line note box (ui.line-note.js) over an Items grid line. */
.line-note { position: fixed; z-index: 1300; width: min(26rem, calc(100vw - 16px)); background: var(--net-bg-card); border: 1px solid var(--net-border-accent); border-radius: var(--net-border-radius-md); box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45); padding: 0.6rem; display: grid; gap: 0.45rem; }
.line-note textarea { width: 100%; font: inherit; color: var(--net-text-primary); background: var(--net-bg-primary); border: 1px solid var(--net-border-accent); border-radius: var(--net-border-radius-base); padding: 0.4rem 0.5rem; resize: vertical; }
.line-note-actions { display: flex; align-items: center; gap: 0.4rem; justify-content: flex-end; font-size: var(--net-font-size-xs); }
.line-note-actions .muted { margin-right: auto; }
/* Export > Complete the estimate: the option on its own line, the buttons together on the left under it. */
.complete-form { display: grid; gap: var(--net-spacing-sm); justify-items: start; }
.complete-form .complete-opt { display: inline-flex; align-items: center; gap: 0.4rem; }
.complete-form .complete-buttons { display: flex; flex-wrap: wrap; gap: var(--net-spacing-sm); justify-content: flex-start; }
/* A claim card for someone else's claim you were added to (people across claims). */
.claim-card .claim-shared { margin: -0.15rem 0 0.35rem; font-size: var(--net-font-size-sm); }

/* Settings > AI assistant (migration 070): status lines, then the key form. Save is FIRST in the markup (Enter in a
   box saves) but shown last, on the right; Remove sits far left of the group. */
.ai-settings .ai-status { display: grid; gap: 0.2rem; margin: var(--net-spacing-sm) 0 var(--net-spacing-md); font-size: var(--net-font-size-sm); }
.ai-settings .ai-actions .ai-remove { order: 1; margin-right: auto; }
.ai-settings .ai-actions .ai-test { order: 2; }
.ai-settings .ai-actions .ai-save { order: 3; }
/* AI assistant > Models for each job (migration 072): the job and why on the left, the tier it needs, the model dropdown right. */
.ai-settings .ai-models { display: grid; gap: 0.35rem; margin: var(--net-spacing-sm) 0; padding: var(--net-spacing-sm) var(--net-spacing-md); border: 1px solid var(--net-border); border-radius: var(--net-border-radius-md); }
.ai-settings .ai-models-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.25rem 0.6rem; margin-bottom: 0.2rem; }
.ai-settings .ai-models-head small { font-size: var(--net-font-size-xs); }
.ai-settings .ai-model-row { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(12rem, 20rem); gap: 0.6rem; align-items: center; padding: 0.35rem 0; border-top: 1px solid var(--net-border); }
.ai-settings .ai-model-job { display: grid; gap: 0.05rem; min-width: 0; }
.ai-settings .ai-model-job small { font-size: var(--net-font-size-xs); }
.ai-settings .ai-model-row.is-coming .ai-model-job > span { opacity: 0.75; }
.ai-settings .ai-model-pick .ctrl-wrapper { margin: 0; }
.ai-settings .ai-model-pick .ctrl-field { width: 100%; }
.ai-settings .ai-tier { white-space: nowrap; }
.ai-settings .ai-tier.is-fast { background: var(--dp-money-in-soft); color: var(--dp-tint-ok-text); }
.ai-settings .ai-tier.is-balanced { background: rgba(79, 143, 247, 0.18); color: var(--dp-tint-info-text); }
.ai-settings .ai-tier.is-smart { background: rgba(139, 92, 246, 0.2); color: var(--dp-tint-info-text); }
.ai-settings .ai-actions .ai-pause { order: 2; }
@media (max-width: 600px) { .ai-settings .ai-model-row { grid-template-columns: 1fr auto; } .ai-settings .ai-model-pick { grid-column: 1 / -1; } }
/* AI assistant buttons: ONE height for the row (owner, 2026-10-07) - the emoji in Remove / Pause made them taller than Save.
   Remove key is btn-danger, like Remove claim / Delete item. */
.ai-settings .ai-actions .btn { height: 34px; min-height: 34px; padding-top: 0; padding-bottom: 0; display: inline-flex; align-items: center; gap: 0.35rem; line-height: 1; }
.ai-settings .ai-actions .btn .btn-emoji { font-size: 1em; line-height: 1; }

/* Phone wording (2026-10-07, owner: "font sized smaller, and less verbose in mobile views"): .m-hide = detail a phone
   drops, .m-only = the short word a phone shows instead. Wrap words, never whole controls. */
.m-only { display: none; }
@media (max-width: 600px) {
    .m-hide { display: none !important; }
    .m-only { display: inline; }
    /* Money tiles: smaller numbers and labels; three tiles sit on one row instead of 2 + 1. */
    .site-main .stat-tiles { gap: var(--net-spacing-sm); margin-bottom: var(--net-spacing-md); }
    .site-main .stat-tiles:has(> .stat-tile:nth-child(3):last-child) { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .site-main .stat-tile { padding: 0.5rem 0.55rem; min-width: 0; }
    .site-main .stat-tile .value { font-size: 1rem; line-height: 1.25; overflow-wrap: anywhere; }
    .site-main .stat-tile .label { font-size: 0.6rem; letter-spacing: 0.03em; line-height: 1.3; margin-top: 0.15rem; }
    .site-main .stat-tile .sub { font-size: 0.68rem; }
    /* Coverage rows: one size down, tighter. */
    .coverage-row { font-size: var(--net-font-size-sm); line-height: 1.4; margin-bottom: var(--net-spacing-sm); }
    .coverage-row strong { display: block; font-size: var(--net-font-size-sm); }
    .coverage-row .progress { margin-top: 0.3rem; }
}

/* Colour lists (Settings > Attention colors, Flag colors, Tag colors), ONE component (owner, 2026-10-08: "no consistency on
   spacing at all ... use some base css"). Every row = [colour box] [badge], every size and gap comes from the tokens
   below and the --net-spacing scale - never a one-off number. The colour box (a colour input, or a flag's fixed swatch)
   and the badge are the same height; the badge owns the text inset, the field typed into it is bare (.is-bare,
   ui.forms.css: no border, padding or focus ring of its own in any workspace model). Built-in rows, editable rows, the
   locked Yellow flag, hidden rows and "＋ Add new" all share these rules. × hides a Tag colors entry; hidden ones sit in
   the "Hidden" list with ＋. One "↺ Restore defaults" per panel, top right beside its description (local.colors.js). */
.tagc-intro, .tagc-grid, .tagc-head, .tagc-hidden {
    --tagc-h: 2rem;          /* a row: colour box and badge */
    --tagc-sw: 2.5rem;       /* the colour box's width */
    --tagc-px: 0.7rem;       /* the badge's text inset, both ends */
}
.tagc-intro { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--net-spacing-lg); margin-bottom: var(--net-spacing-md); }
.tagc-intro p { margin: 0; }
.tagc-intro .btn { flex: 0 0 auto; white-space: nowrap; }
.tagc-head { font-size: var(--net-font-size-sm); margin: var(--net-spacing-lg) 0 var(--net-spacing-sm); }
.tagc-head:first-child { margin-top: 0; }
.tagc-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); gap: var(--net-spacing-sm) var(--net-spacing-lg); }
.tagc-grid + details { margin-top: var(--net-spacing-md); }
.tagc-row { display: flex; align-items: center; gap: var(--net-spacing-sm); min-width: 0; height: var(--tagc-h); }

/* The colour box: a colour input or a flag's swatch - one size, one frame. */
.tagc-row .ctrl-wrapper.tagc-color { flex: 0 0 var(--tagc-sw); width: var(--tagc-sw); height: var(--tagc-h); }
.tagc-row .ctrl-wrapper.tagc-color .ctrl-field, .tagc-row .tagc-swatch {
    width: var(--tagc-sw); height: var(--tagc-h); padding: 2px; cursor: pointer;
    border: 1px solid var(--net-border-accent); border-radius: var(--net-border-radius-base); background: transparent;
}
.tagc-row .tagc-swatch { flex: 0 0 var(--tagc-sw); padding: 0; cursor: default; box-shadow: inset 0 0 0 2px var(--net-bg-card); }
.tagc-row .ctrl-wrapper.tagc-color .ctrl-field::-webkit-color-swatch-wrapper { padding: 0; }
.tagc-row .ctrl-wrapper.tagc-color .ctrl-field::-webkit-color-swatch { border: 0; border-radius: 3px; }
.tagc-row .ctrl-wrapper.tagc-color .ctrl-field::-moz-color-swatch { border: 0; border-radius: 3px; }

/* The badge: fills the rest of the row, text inset --tagc-px at both ends; an × / ＋ / 💾 button at its end eats into the
   right inset so it sits as close to the edge as the text does to the left one. */
.tagc-row > .badge {
    flex: 1 1 auto; min-width: 0; height: var(--tagc-h);
    display: inline-flex; align-items: center; gap: var(--net-spacing-xs);
    padding: 0 var(--tagc-px); overflow: hidden; white-space: nowrap;
}
.tagc-row > .badge .tg-i, .tagc-row > .badge .attn-letter, .tagc-row > .badge .badge-add-plus { flex: 0 0 auto; margin: 0; }
.tagc-row > .badge .badge-add-plus { font-weight: 700; }
.tagc-row > .badge .ctrl-wrapper { flex: 1 1 auto; min-width: 0; height: 100%; }
.tagc-row > .badge .ctrl-field, .tagc-row > .badge .badge-text { font-weight: 500; text-overflow: ellipsis; }
.tagc-row > .badge .badge-text { flex: 1 1 auto; min-width: 0; overflow: hidden; }
.tagc-row > .badge .ctrl-field::placeholder { color: inherit; opacity: 0.55; font-style: italic; }
.tagc-row > .badge-edit:focus-within { box-shadow: inset 0 0 0 2px var(--tg); }
.tagc-row > .badge > .badge-x { margin-right: calc(var(--net-spacing-xs) - var(--tagc-px)); }
.badge-x { flex: 0 0 auto; border: 0; background: transparent; color: inherit; opacity: 0.6; cursor: pointer; font: inherit; font-size: 0.95rem; line-height: 1; padding: 0.15rem 0.35rem; border-radius: 999px; }
.badge-x:hover, .badge-x:focus-visible { opacity: 1; background: color-mix(in srgb, var(--tg, #888) 35%, transparent); }

/* Hidden (Tag colors): faded, ＋ instead of ×, no colour box. */
.tagc-hidden { margin-top: var(--net-spacing-lg); }
.tagc-hidden > summary { cursor: pointer; font-size: var(--net-font-size-sm); font-weight: 600; }
.tagc-hidden .tagc-grid { margin-top: var(--net-spacing-sm); }
.tagc-hidden .tagc-row .badge { opacity: 0.6; }
.tagc-row .js-tagc-show { display: none; }
.tagc-hidden .tagc-row .js-tagc-show { display: inline-block; }
.tagc-hidden .tagc-row .js-tagc-hide, .tagc-hidden .tagc-row > .ctrl-wrapper { display: none; }

/* "＋ Add new": the last row of every list - a dashed, quieter badge that reads as "make another". Typing in it, it looks
   like the badge it will become (the tint + ring of .badge.tg); only the 💾 shows it is not saved yet. */
.tagc-row.is-add .badge-add { border: 1px dashed color-mix(in srgb, var(--tg, #888) 55%, transparent); box-shadow: none; background: transparent; }
.tagc-row.is-add .badge-add:focus-within, .tagc-row.is-add .badge-add:has(.ctrl-field:not(:placeholder-shown)) { border-color: transparent; background: color-mix(in srgb, var(--tg, #9aa4b2) 22%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--tg, #9aa4b2) 62%, transparent); }
.tagc-row.is-add .badge-add:focus-within .badge-add-plus, .tagc-row.is-add .badge-add:has(.ctrl-field:not(:placeholder-shown)) .badge-add-plus { display: none; }
.tagc-row.is-add .badge-add .js-tagc-add { display: none; }
/* Typed words keep the 💾 shown even after the box loses focus (a click on 💾 blurs the box first on some browsers). */
.tagc-row.is-add .badge-add:focus-within .js-tagc-add, .tagc-row.is-add .badge-add:has(.ctrl-field:not(:placeholder-shown)) .js-tagc-add { display: inline-block; opacity: 1; }
.tagc-row.is-add .ctrl-field::placeholder { opacity: 0.75; font-weight: 600; font-style: normal; }
.tagc-row.is-add .ctrl-field:focus::placeholder { opacity: 0.35; font-weight: 500; }
.tagc-row.is-add.is-busy { opacity: 0.5; pointer-events: none; }
/* The Restore defaults confirmation: now -> default, one row per badge that changes. */
.restore-table { width: 100%; }
.restore-table td { vertical-align: middle; padding: 0.3rem 0.5rem; }
.restore-table td:nth-child(2) { width: 1.5rem; text-align: center; }
@media (max-width: 600px) {
    .tagc-intro { flex-direction: column; }
    .tagc-intro .btn { align-self: flex-end; }
}
/* Bulk-action rows (Items, Amazon): "Flag color…" and what follows it sit at the right end, the gap opens after
   "renumber" (owner, 2026-10-07: fill the white space). A wrapped row keeps it at the right of its own line. */
.toolbar > .ctrl-wrapper.fit.bulk-flag { margin-left: auto; }   /* outranks .toolbar .ctrl-wrapper.fit { margin: 0 } */
/* 24-column form rows (owner, 2026-10-07: the item editor's pricing and quantity panels). Wrap a .form-grid in
   <div class="grid24"> and give each cell class g24 + style="--w:N" (its width out of 24). Only while the PANEL is wide
   enough (a container query, not the viewport - the sidebar and the panel's own padding vary); narrower, each cell's
   ordinary span-N class takes over, so always give one. */
.grid24 { container-type: inline-size; }
@container (min-width: 1100px) {
    .grid24 > .form-grid { grid-template-columns: repeat(24, minmax(0, 1fr)); }
    .grid24 > .form-grid > .g24 { grid-column: span var(--w, 24); }
}
/* .is-880: a panel whose rows are planned for 24 columns from 880px (the item editor's purchase panel, 2026-10-07: a normal
   laptop's panel is ~1100px and used to fall back to 12). */
@container (min-width: 880px) {
    .grid24.is-880 > .form-grid { grid-template-columns: repeat(24, minmax(0, 1fr)); }
    .grid24.is-880 > .form-grid > .g24 { grid-column: span var(--w, 24); }
}
/* The AI "Replacement cost" panel is a row of the purchase grid (row 2): it spans every column. */
#purchase-grid > .pricing-ai { grid-column: 1 / -1; margin: 0 0 var(--net-spacing-md); }
/* Labels in the purchase grid stay ONE line (owner, 2026-10-07: a wrapped label pushed its box down): cut with "…" when a cell is
   truly too narrow (a ~1000px panel), never wrapped. The order number's label names the store from "Where bought" (local.item.js). */
#purchase-grid [data-field] > label { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* A hidden cell that KEEPS its slot (item editor: type of damage / severity on an undamaged item), so the fields after it
   never jump into the gap. Invisible and out of the tab order; local.item.js still toggles [hidden] as for every damage-only part. */
.form-grid > .keeps-slot[hidden] { display: block; visibility: hidden; }
/* Record panels on the 12-column grid (owner, 2026-10-07: "same field, same place"): a view line .rec-cells.is-12 with each
   cell's width in --c lines up cell by cell with its editor .form-grid.is-rec, which keeps the ✎ column clear like .rec-fields.
   Policy & claim details and Policy use it. */
.rec-cells.is-12 { grid-template-columns: repeat(12, minmax(0, 1fr)); }
.rec-cells.is-12 > .rec-cell { grid-column: span var(--c, 3); }
.rec-editor > .form-grid.is-rec { margin-right: calc(2rem + var(--net-spacing-md)); }
/* The coverage record = six equal cells (deductible, A-D, lettering), so an auto claim's lone Deductible keeps the same width. */
@media (min-width: 901px) {
    .rec-row.is-six .rec-cells, .rec-row.is-six .rec-fields { grid-template-columns: repeat(6, minmax(0, 1fr)); }
}
@media (max-width: 900px) {
    .rec-cells.is-12 > .rec-cell { grid-column: span 6; }
    .rec-cells.is-12 > .rec-cell[style*="--c:12"], .rec-cells.is-12 > .rec-cell[style*="--c:9"] { grid-column: 1 / -1; }
    .rec-editor > .form-grid.is-rec { margin-right: 0; }
}
/* "No other limits yet ..." wraps BEFORE the Add a limit button, which stays top-right. */
.limit-foot { align-items: flex-start; }
.limit-foot > .muted { flex: 1 1 auto; min-width: 0; }
.limit-add .js-limit-name[hidden] { display: none; }
/* Export templates > Options: the label cell that leads the condition row ("Our condition → theirs"). */
.cond-map-head { display: flex; flex-direction: column; justify-content: flex-end; padding-bottom: 0.4rem; line-height: 1.25; }
.cond-map-head small { font-size: var(--net-font-size-xs); }
/* A note and its button on one line: the words take the room and wrap, the button stays top-right (2026-10-07; Capture's
   "More rows" and "Add photos"). Use .text-then-button on any such row: text FIRST in the markup, then the button. */
.text-then-button { display: flex; align-items: flex-start; gap: var(--net-spacing-md); flex-wrap: nowrap; }
.text-then-button > small, .text-then-button > span { flex: 1 1 auto; min-width: 0; }
.text-then-button > .ctrl-wrapper, .text-then-button > .btn { flex: 0 0 auto; margin: 0; }

/* Need to know on the Overview (owner, 2026-10-07; $_ntk in pages/claim/_index.php): what the owner's OWN roles would not need
   sits folded behind a small "show more ›" - under the tile grid, and at the foot of the coverage card. Open, the hidden
   tiles join the same grid. */
.stat-tiles > .ntk-more:not([hidden]) { display: contents; }
.ntk-toggle-row { display: flex; justify-content: flex-end; margin: -0.6rem 0 var(--net-spacing-md); }
.card .ntk-toggle-row { margin: 0.15rem 0 0; }
.ntk-toggle { background: none; border: 0; padding: 0.1rem 0.25rem; font: inherit; font-size: var(--net-font-size-xs); color: var(--net-text-muted); cursor: pointer; }
.ntk-toggle:hover, .ntk-toggle:focus-visible { color: var(--net-color-primary); text-decoration: underline; }
/* Composite items (2026-10-08, migration 084): the switch's two rows swap with [hidden]; a component line says where it belongs.
   A piece's badge in Components opens that line. */
.form-grid > [data-comp][hidden] { display: none; }
.comp-of { display: flex; align-items: center; justify-content: space-between; gap: var(--net-spacing-md); padding: var(--net-spacing-sm) var(--net-spacing-md);
           border: 1px solid var(--net-border); border-radius: var(--net-border-radius-base); background: var(--net-bg-accent); margin-bottom: var(--net-spacing-md); }
.comp-of .btn { flex: 0 0 auto; }
.item-f-components .tags-list .tag-chip { cursor: pointer; }
.item-f-components .tags-list .tag-chip:hover .tag-text { text-decoration: underline; }
.comp-sum { display: block; margin-top: var(--net-spacing-xs); font-size: var(--net-font-size-xs); }
/* A composite's Photos panel: its pieces' photos sit in the same grid after its own, read-only (item/default.php). A dashed
   frame and the "🧩 COMPONENT" tag (upper case like ITEM) tell them apart from the line's own photos; nothing on them edits. */
.thumb.is-component { border-style: dashed; cursor: default; }
.thumb.is-component > a > img, .thumb.is-component > a > .media-video { opacity: 0.85; }
.thumb.is-component:hover > a > img, .thumb.is-component:hover > a > .media-video { opacity: 1; }
.thumb.is-component .cap a { font-family: var(--net-font-mono, monospace); }
/* The composite's cell (2026-10-08, owner): the form's own 12 columns, so the search sits where Brand / Model were (8) and
   Valuation basis where Serial was (4). The Components field's wrapper is display:contents - its label, search box, found
   lines and picked list are placed straight on this grid; the found lines span rows 3-4 so the picked list (row 4, under
   the piece count) starts right under Valuation basis however long the found list is. */
/* A composite's estimate under Purchase price / date (local.item.js): grey like a field's help line, in the help line's place
   (the wrapper's bottom margin taken back); amber = a piece has no price / date, red = the date is before the newest piece. */
.comp-est { display: block; margin: calc(0.2rem - var(--net-spacing-md)) 0 var(--net-spacing-md); font-size: var(--net-font-size-xs); color: var(--net-text-muted); }
.comp-est[hidden] { display: none; }
.comp-est.is-warn { color: var(--net-color-warning); }
.comp-est.is-bad { color: var(--dp-money-bad); }
.comp-est-use { border: 0; background: transparent; padding: 0 0.15rem; color: var(--net-color-primary); font: inherit; cursor: pointer; }
.comp-est-use:hover, .comp-est-use:focus-visible { text-decoration: underline; }
.form-grid > .comp-grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); grid-template-rows: auto auto auto 1fr; column-gap: var(--net-spacing-md); align-items: start; margin-bottom: var(--net-spacing-md); }
.form-grid > .comp-grid[hidden] { display: none; }
.comp-grid > .item-f-components { display: contents; }
.comp-grid > .item-f-components > label { grid-column: 1 / 9; grid-row: 1; }
.comp-grid > .item-f-components > .tags-box { grid-column: 1 / 9; grid-row: 2; margin-top: 0.2rem; }
.comp-grid > .item-f-components > .tags-suggest { grid-column: 1 / 9; grid-row: 3 / 5; }
.comp-grid > .comp-basis { grid-column: 9 / 13; grid-row: 1 / 3; }
.comp-grid > .comp-basis > .ctrl-wrapper { margin-bottom: 0; }
.comp-grid > .comp-sum { grid-column: 9 / 13; grid-row: 3; margin-top: 0.3rem; }
.comp-grid > .item-f-components > .tags-list.is-out { grid-column: 9 / 13; grid-row: 4; margin-top: 0.3rem; }
.comp-grid > .item-f-components > .ctrl-help { grid-column: 1 / 9; }
@media (max-width: 600px) {
    .form-grid > .comp-grid { grid-template-columns: minmax(0, 1fr); grid-template-rows: none; }
    .comp-grid > .item-f-components > label { grid-column: 1; grid-row: 1; }
    .comp-grid > .item-f-components > .tags-box { grid-column: 1; grid-row: 2; }
    .comp-grid > .item-f-components > .tags-suggest { grid-column: 1; grid-row: 3; }
    .comp-grid > .comp-basis { grid-column: 1; grid-row: 4; margin-top: var(--net-spacing-md); }
    .comp-grid > .comp-sum { grid-column: 1; grid-row: 5; }
    .comp-grid > .item-f-components > .tags-list.is-out { grid-column: 1; grid-row: 6; }
}
/* Settings > Who sees what (085): role rows under their group, the built-in areas as plain badges, two tags fields; a saved row
   flashes (local.visibility.js). */
.vis-table td { vertical-align: top; }
.vis-table tr.vis-group td { font-weight: 600; font-size: var(--net-font-size-sm); color: var(--net-text-muted); background: var(--net-bg-accent); }
.vis-table .vis-built .badge { margin: 0 var(--net-spacing-xs) var(--net-spacing-xs) 0; }
.vis-table .ctrl-wrapper { margin-bottom: 0; min-width: 14rem; }
.vis-table .vis-hint { font-size: var(--net-font-size-xs); margin-top: var(--net-spacing-xs); }
.vis-table tr.is-saved > td { background: var(--dp-money-in-soft); transition: background 0.4s ease; }
.vis-table tr.is-failed > td { background: var(--dp-money-bad-soft); }


/* Recovery Tools invitation on a new claim's Overview (pages/claim, 091): one line, the two buttons right. */
.tools-invite { display: flex; align-items: center; justify-content: space-between; gap: var(--net-spacing-md); flex-wrap: wrap; border: 1px solid var(--net-color-primary); }
.tools-invite-text { flex: 1 1 22rem; }
.tools-invite-actions { display: flex; gap: var(--net-spacing-sm); }
.tools-invite-actions form { margin: 0; }
