/*
 * PBJ Invoicing — portal styles (Phase 3).
 *
 * These rules dress the invoicing screens that live INSIDE the pbj-crm portal.
 * Self-contained, no frameworks, no build step. Every class is prefixed
 * pbjinv-, and the tokens below deliberately mirror pbj-crm.css one for one so
 * an invoicing screen is indistinguishable from a CRM screen: same greys, same
 * blue, same 6px radius, same 14px table type.
 *
 * The variables are declared on .pbjcrm-portal (the shell we are painted into)
 * AND on .pbjinv-scope, so the same stylesheet still works if invoicing is ever
 * rendered outside the CRM shell. Falling back to the CRM's own variables where
 * they exist means a future CRM re-theme carries invoicing along with it.
 *
 * The PUBLIC tokenized invoice page has its OWN stylesheet (pbj-inv-public.css)
 * — nothing here is loaded there.
 */

.pbjcrm-portal,
.pbjinv-scope {
	--pbjinv-bg: var(--pbjcrm-surface, #ffffff);
	--pbjinv-bg-soft: var(--pbjcrm-surface-alt, #f6f7f8);
	--pbjinv-border: var(--pbjcrm-border, #d8dce0);
	--pbjinv-text: var(--pbjcrm-text, #1d2327);
	--pbjinv-muted: var(--pbjcrm-muted, #646d76);
	--pbjinv-primary: var(--pbjcrm-accent, #2271b1);
	--pbjinv-primary-dark: var(--pbjcrm-accent-strong, #135e96);
	--pbjinv-danger: var(--pbjcrm-danger, #b32d2e);
	--pbjinv-ok: var(--pbjcrm-success, #1a7a3c);
	--pbjinv-warn: var(--pbjcrm-warning, #996800);

	/*
	 * THE ORANGE FOR THE PAST-DUE DOT, and the one token here that is NOT the
	 * CRM's. The suite's warning colour is #996800 — an amber chosen to be
	 * readable as TEXT on a pale chip (.pbjinv-status-partial), where contrast
	 * against white is what matters. Painted as a solid 10px circle beside a red
	 * one it reads brown, and at that size brown next to #b32d2e is the same dot
	 * twice: exactly the distinction Jake asked these dots to carry (orange =
	 * past due, red = past the late fee) collapses.
	 *
	 * So the dot gets a purpose-made orange that stays orange at 10px, and still
	 * defers to a suite token the day one exists: --pbjcrm-orange wins if the CRM
	 * ever declares it.
	 */
	--pbjinv-due-orange: var(--pbjcrm-orange, #e08a00);
	--pbjinv-radius: var(--pbjcrm-radius, 6px);
}

/* ------------------------------------------------------------ Type helpers */

.pbjinv-muted {
	color: var(--pbjinv-muted);
}

.pbjinv-error {
	color: var(--pbjinv-danger);
	background: color-mix(in srgb, var(--pbjcrm-danger, #b32d2e) 10%, var(--pbjcrm-surface, #fff));
	border: 1px solid color-mix(in srgb, var(--pbjcrm-danger, #b32d2e) 35%, var(--pbjcrm-surface, #fff));
	border-radius: var(--pbjinv-radius);
	padding: 8px 12px;
	margin: 8px 0;
}

.pbjinv-empty {
	color: var(--pbjinv-muted);
	background: var(--pbjinv-bg-soft);
	border: 1px dashed var(--pbjinv-border);
	border-radius: var(--pbjinv-radius);
	padding: 14px 16px;
	font-size: 14px;
}

.pbjinv-loading {
	font-size: 14px;
}

.pbjinv-noaccess h2 {
	margin-top: 0;
	font-size: 19px;
}

/* -------------------------------------------------------------- Containers */

.pbjinv-card:not(.pbjcrm-ucard) {
	background: var(--pbjinv-bg);
	border: 1px solid var(--pbjinv-border);
	border-radius: var(--pbjinv-radius);
	padding: 16px 18px;
	margin-bottom: 14px;
}

.pbjinv-card:not(.pbjcrm-ucard) > h3 {
	margin: 0 0 10px;
	font-size: 15px;
}

.pbjinv-document-cards {
	display: grid;
	gap: 12px;
	margin-bottom: 14px;
}

.pbjinv-owed-sort,
.pbjinv-owed-buckets {
	display: flex;
	flex-wrap: wrap;
	gap: 8px 14px;
}

.pbjinv-owed-sort {
	margin-bottom: 12px;
}

.pbjinv-owed-fact {
	font-size: 13px;
}

.pbjinv-owed-totals {
	display: grid;
	gap: 10px;
}

.pbjinv-panel {
	border: 1px solid var(--pbjinv-border);
	border-radius: var(--pbjinv-radius);
	background: var(--pbjinv-bg);
	padding: 12px 14px;
}

.pbjinv-panel h3 {
	margin: 0 0 8px;
	font-size: 14px;
}

.pbjinv-view-head {
	margin-bottom: 12px;
}

.pbjinv-view-head h2 {
	margin: 0 0 2px;
	font-size: 19px;
}

.pbjinv-view-head p {
	margin: 0;
	font-size: 13px;
}

.pbjinv-backlink {
	margin: 0 0 10px;
}

/* ----------------------------------------------------------------- Buttons */

.pbjinv-btn {
	display: inline-block;
	border: 1px solid var(--pbjinv-border);
	background: var(--pbjinv-bg);
	color: var(--pbjinv-text);
	border-radius: var(--pbjinv-radius);
	padding: 8px 16px;
	font-size: 14px;
	line-height: 1.3;
	cursor: pointer;
	text-decoration: none;
	transition: background 0.15s ease, border-color 0.15s ease;
}

.pbjinv-btn:hover {
	background: var(--pbjinv-bg-soft);
	border-color: var(--pbjinv-muted);
	color: var(--pbjinv-text);
}

.pbjinv-btn-primary {
	background: var(--pbjinv-primary);
	border-color: var(--pbjinv-primary);
	color: var(--pbjcrm-accent-contrast, #fff);
}

.pbjinv-btn-primary:hover {
	background: var(--pbjinv-primary-dark);
	border-color: var(--pbjinv-primary-dark);
	color: var(--pbjcrm-accent-contrast, #fff);
}

.pbjinv-btn-danger {
	color: var(--pbjinv-danger);
	border-color: color-mix(in srgb, var(--pbjcrm-danger, #b32d2e) 40%, var(--pbjcrm-surface, #fff));
}

.pbjinv-btn-ghost {
	border-color: transparent;
	color: var(--pbjinv-primary);
	background: transparent;
}

.pbjinv-btn-ghost:hover {
	border-color: var(--pbjinv-border);
}

.pbjinv-btn-sm {
	padding: 5px 11px;
	font-size: 13px;
}

.pbjinv-btn:disabled {
	opacity: 0.5;
	cursor: not-allowed;
}

.pbjinv-linkbtn {
	border: none;
	background: none;
	padding: 0;
	margin: 0;
	color: var(--pbjinv-primary);
	font: inherit;
	cursor: pointer;
	text-align: left;
}

.pbjinv-linkbtn:hover {
	color: var(--pbjinv-primary-dark);
	text-decoration: underline;
}

.pbjinv-actions {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	align-items: center;
	margin: 12px 0 4px;
}

/* ------------------------------------------------------------------- Forms */

.pbjcrm-portal .pbjinv-field input[type="text"],
.pbjcrm-portal .pbjinv-field input[type="date"],
.pbjcrm-portal .pbjinv-field input[type="number"],
.pbjcrm-portal .pbjinv-field textarea,
.pbjinv-scope input[type="text"],
.pbjinv-scope input[type="date"],
.pbjinv-scope input[type="number"],
.pbjinv-scope input[type="search"],
.pbjinv-scope select,
.pbjinv-scope textarea {
	width: 100%;
	max-width: 100%;
	padding: 7px 10px;
	border: 1px solid var(--pbjinv-border);
	border-radius: var(--pbjinv-radius);
	background: var(--pbjcrm-surface, #fff);
	color: var(--pbjinv-text);
	font-size: 14px;
}

.pbjinv-field {
	margin: 0 0 12px;
}

.pbjinv-field label {
	display: block;
	font-weight: 600;
	margin-bottom: 3px;
	font-size: 13px;
}

.pbjinv-field-hint {
	margin: 3px 0 0;
	font-size: 12px;
	font-weight: 400;
}

.pbjinv-inline-label {
	display: inline-flex !important;
	align-items: center;
	gap: 6px;
	font-weight: 400 !important;
	margin-right: 10px;
	font-size: 14px;
}

.pbjinv-inline-label input[type="checkbox"],
.pbjinv-inline-label input[type="radio"] {
	width: auto;
	margin: 0;
}

.pbjinv-radios {
	display: flex;
	flex-wrap: wrap;
	gap: 4px 12px;
	margin-bottom: 8px;
}

.pbjinv-grid-2 {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
	gap: 0 14px;
}

.pbjcrm-portal .pbjinv-num,
.pbjinv-scope .pbjinv-num {
	width: 130px;
}

.pbjcrm-portal .pbjinv-money,
.pbjcrm-portal .pbjinv-qty,
.pbjinv-scope .pbjinv-money,
.pbjinv-scope .pbjinv-qty {
	width: 100%;
	text-align: right;
	font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------- Toolbars */

.pbjinv-toolbar {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	align-items: center;
	margin-bottom: 12px;
}

.pbjinv-toolbar .pbjinv-spacer {
	flex: 1;
}

.pbjcrm-portal .pbjinv-toolbar input[type="search"],
.pbjinv-scope .pbjinv-toolbar input[type="search"] {
	width: 220px;
}

.pbjcrm-portal .pbjinv-toolbar select,
.pbjinv-scope .pbjinv-toolbar select {
	width: auto;
}

/* ----------------------------------------------------------- Totals strip */

.pbjinv-strip {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin-bottom: 12px;
}

.pbjinv-stat {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 2px;
	border: 1px solid var(--pbjinv-border);
	border-radius: var(--pbjinv-radius);
	background: var(--pbjinv-bg-soft);
	padding: 8px 14px;
	min-width: 108px;
	cursor: pointer;
	font: inherit;
	color: var(--pbjinv-text);
	text-align: left;
}

.pbjinv-stat:hover {
	border-color: var(--pbjinv-primary);
}

.pbjinv-stat-static {
	cursor: default;
}

.pbjinv-stat-static:hover {
	border-color: var(--pbjinv-border);
}

.pbjinv-stat strong {
	font-size: 20px;
	line-height: 1.1;
	font-variant-numeric: tabular-nums;
}

.pbjinv-stat-label {
	font-size: 12px;
	color: var(--pbjinv-muted);
}

/* ------------------------------------------------------------------ Tables */

.pbjinv-table {
	width: 100%;
	border-collapse: collapse;
	background: var(--pbjinv-bg);
	border: 1px solid var(--pbjinv-border);
	font-size: 14px;
}

.pbjinv-table th,
.pbjinv-table td {
	text-align: left;
	padding: 8px 10px;
	border-bottom: 1px solid var(--pbjinv-border);
	vertical-align: top;
}

.pbjinv-table th {
	background: var(--pbjinv-bg-soft);
	font-weight: 600;
	font-size: 13px;
}

.pbjinv-table tbody tr:last-child td {
	border-bottom: none;
}

.pbjinv-table tbody tr.pbjinv-row-click {
	cursor: pointer;
}

.pbjinv-table tbody tr.pbjinv-row-click:hover {
	background: var(--pbjinv-bg-soft);
}

.pbjinv-table .pbjinv-num-col {
	text-align: right;
	white-space: nowrap;
	font-variant-numeric: tabular-nums;
}

.pbjinv-table .pbjinv-col-tax {
	width: 52px;
	text-align: center;
}

.pbjinv-table .pbjinv-col-qty {
	width: 110px;
}

.pbjinv-table .pbjinv-col-ctl {
	width: 1%;
	white-space: nowrap;
}

.pbjinv-table tfoot td {
	background: var(--pbjinv-bg-soft);
	font-size: 13px;
}

.pbjinv-table tr.pbjinv-refunded td {
	color: var(--pbjinv-muted);
	text-decoration: line-through;
}

.pbjinv-overdue {
	color: var(--pbjinv-danger);
	font-weight: 600;
}

.pbjinv-pager {
	display: flex;
	align-items: center;
	gap: 10px;
	margin-top: 12px;
	font-size: 13px;
	color: var(--pbjinv-muted);
}

/* ------------------------------------------------------- Badges and chips */

.pbjinv-badge {
	display: inline-block;
	border-radius: 999px;
	padding: 1px 9px;
	font-size: 12px;
	font-weight: 600;
	background: var(--pbjinv-bg-soft);
	border: 1px solid var(--pbjinv-border);
	white-space: nowrap;
	margin-right: 4px;
}

.pbjinv-badge-invoice {
	background: color-mix(in srgb, var(--pbjcrm-accent, #2271b1) 10%, var(--pbjcrm-surface, #fff));
	border-color: color-mix(in srgb, var(--pbjcrm-accent, #2271b1) 30%, var(--pbjcrm-surface, #fff));
	color: var(--pbjcrm-accent-strong, #1f4e79);
}

.pbjinv-badge-estimate {
	background: color-mix(in srgb, var(--pbjcrm-accent, #2271b1) 8%, var(--pbjcrm-surface, #fff));
	border-color: color-mix(in srgb, var(--pbjcrm-accent, #2271b1) 25%, var(--pbjcrm-surface, #fff));
	color: var(--pbjcrm-accent-strong, #4b3b7a);
}

.pbjinv-badge-overdue {
	background: color-mix(in srgb, var(--pbjcrm-danger, #b32d2e) 10%, var(--pbjcrm-surface, #fff));
	border-color: color-mix(in srgb, var(--pbjcrm-danger, #b32d2e) 35%, var(--pbjcrm-surface, #fff));
	color: var(--pbjinv-danger);
}

.pbjinv-status {
	display: inline-block;
	border-radius: 999px;
	padding: 1px 9px;
	font-size: 12px;
	font-weight: 700;
	white-space: nowrap;
	background: var(--pbjinv-bg-soft);
	border: 1px solid var(--pbjinv-border);
	color: var(--pbjinv-muted);
}

.pbjinv-status-draft {
	background: var(--pbjinv-bg-soft);
	color: var(--pbjinv-muted);
}

.pbjinv-status-sent,
.pbjinv-status-viewed,
.pbjinv-status-active {
	background: color-mix(in srgb, var(--pbjcrm-accent, #2271b1) 10%, var(--pbjcrm-surface, #fff));
	border-color: color-mix(in srgb, var(--pbjcrm-accent, #2271b1) 30%, var(--pbjcrm-surface, #fff));
	color: var(--pbjcrm-accent-strong, #1f4e79);
}

.pbjinv-status-partial,
.pbjinv-status-paused {
	background: color-mix(in srgb, var(--pbjcrm-warning, #996800) 12%, var(--pbjcrm-surface, #fff));
	border-color: color-mix(in srgb, var(--pbjcrm-warning, #996800) 35%, var(--pbjcrm-surface, #fff));
	color: var(--pbjinv-warn);
}

.pbjinv-status-paid,
.pbjinv-status-accepted {
	background: color-mix(in srgb, var(--pbjcrm-success, #1a7a3c) 10%, var(--pbjcrm-surface, #fff));
	border-color: color-mix(in srgb, var(--pbjcrm-success, #1a7a3c) 35%, var(--pbjcrm-surface, #fff));
	color: var(--pbjinv-ok);
}

.pbjinv-status-overdue,
.pbjinv-status-declined {
	background: color-mix(in srgb, var(--pbjcrm-danger, #b32d2e) 10%, var(--pbjcrm-surface, #fff));
	border-color: color-mix(in srgb, var(--pbjcrm-danger, #b32d2e) 35%, var(--pbjcrm-surface, #fff));
	color: var(--pbjinv-danger);
}

/*
 * THE DUE-STATE DOT (1.31.0). Jake, 2026-08-19: "orange circle = past due date,
 * red circle = past the late-fee point".
 *
 * Drawn ONLY when the server sent a `due_state` — there is no "no dot" class,
 * because the absence of the element IS that state (see dueDot() in pbj-inv.js
 * and PBJ_INV_Invoices::due_state()).
 *
 * COLOUR IS NEVER THE ONLY CARRIER: every dot ships title + aria-label ("Past
 * due" / "Past late fee"), so a screen reader and a colour-blind reader both get
 * the words. The ring is a slightly stronger shade of the dot's own colour, so
 * the two states stay apart on a mono print-out and against dark backgrounds.
 */
.pbjinv-due-dot {
	display: inline-block;
	flex: none;
	width: 10px;
	height: 10px;
	border-radius: 50%;
	vertical-align: middle;
	margin-right: 6px;
}

.pbjinv-due-overdue {
	background: var(--pbjinv-due-orange);
	box-shadow: 0 0 0 1px color-mix(in srgb, var(--pbjinv-due-orange) 55%, var(--pbjcrm-text, #1d2327));
}

.pbjinv-due-late {
	background: var(--pbjinv-danger);
	box-shadow: 0 0 0 1px color-mix(in srgb, var(--pbjcrm-danger, #b32d2e) 55%, var(--pbjcrm-text, #1d2327));
}

/* The document header spaces its own children (flex, gap 8px), so the dot's
   own margin would be counted twice there. */
.pbjinv-detail-title .pbjinv-due-dot {
	margin-right: 0;
}

.pbjinv-status-void,
.pbjinv-status-expired,
.pbjinv-status-finished {
	background: var(--pbjinv-bg-soft);
	border-color: var(--pbjinv-border);
	color: var(--pbjinv-muted);
	text-decoration: line-through;
}

/* -------------------------------------------------------------- Typeahead */

.pbjinv-typeahead-wrap {
	max-width: 380px;
	margin-bottom: 6px;
}

.pbjcrm-portal .pbjinv-typeahead-input,
.pbjinv-scope .pbjinv-typeahead-input {
	width: 100%;
	padding: 7px 10px;
	border: 1px solid var(--pbjinv-border);
	border-radius: var(--pbjinv-radius);
	background: var(--pbjcrm-surface, #fff);
	color: var(--pbjinv-text);
	font-size: 14px;
}

.pbjinv-typeahead {
	border-radius: var(--pbjinv-radius);
	overflow: hidden;
}

.pbjinv-typeahead:not(:empty) {
	border: 1px solid var(--pbjinv-border);
	margin-top: 4px;
}

.pbjinv-typeahead-item {
	display: block;
	width: 100%;
	text-align: left;
	border: none;
	border-bottom: 1px solid var(--pbjinv-border);
	background: var(--pbjcrm-surface, #fff);
	padding: 6px 10px;
	font-size: 13px;
	color: var(--pbjinv-text);
	cursor: pointer;
}

.pbjinv-typeahead-item:last-child {
	border-bottom: none;
}

.pbjinv-typeahead-item:hover {
	background: var(--pbjinv-bg-soft);
}

.pbjinv-chosen {
	margin: 2px 0 10px;
	font-size: 13px;
	color: var(--pbjinv-muted);
}

/* ------------------------------------------------------ Recipient picking */

.pbjinv-recipients {
	margin-top: 8px;
}

.pbjinv-recipients > label {
	display: block;
	font-weight: 600;
	font-size: 13px;
	margin-bottom: 4px;
}

/* ------------------------------------ "Money owed to you" column explainer */

.pbjinv-explainer-list {
	margin: 8px 0 10px;
	padding-left: 20px;
	font-size: 13px;
	line-height: 1.6;
}

.pbjinv-explainer-list li {
	margin: 0 0 2px;
}

.pbjinv-checklist {
	border: 1px solid var(--pbjinv-border);
	border-radius: var(--pbjinv-radius);
	background: var(--pbjinv-bg-soft);
	padding: 8px 10px;
	max-height: 190px;
	overflow-y: auto;
}

.pbjinv-checkrow {
	display: flex !important;
	width: 100%;
	margin: 0 0 4px;
}

/* ------------------------------------------------------------ Items editor */

.pbjinv-items-table td {
	vertical-align: middle;
}

.pbjinv-rowctl {
	display: flex;
	gap: 2px;
}

.pbjinv-rowctl .pbjinv-btn {
	padding: 4px 8px;
	line-height: 1;
}

/* The saved line-item picker above the table, and the per-row save button. */

.pbjinv-saved-bar {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 8px;
	margin: 0 0 10px;
}

.pbjinv-saved-bar label {
	font-weight: 600;
}

.pbjinv-saved-bar select {
	min-width: 220px;
	max-width: 100%;
}

.pbjinv-table .pbjinv-col-reuse {
	width: 1%;
	white-space: nowrap;
}

.pbjinv-btn-reuse {
	padding: 4px 8px;
	line-height: 1;
}

/* --------------------------------------------------------- Detail screens */

.pbjinv-detail-head h2 {
	margin: 0;
	font-size: 22px;
}

.pbjinv-detail-title {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
	margin-bottom: 8px;
}

/* The row that carries the document's Edit control and its print icon, at the
   very top of the record (2026-08-13). Right-aligned so it never competes with
   the invoice number for the eye, and wrapping rather than squeezing when the
   screen is narrow. */
.pbjinv-detail-controls {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: flex-end;
	gap: 6px;
	margin-bottom: 6px;
}

.pbjinv-detail-controls:empty {
	display: none;
}

.pbjinv-detail-meta p {
	margin: 0 0 3px;
	font-size: 13px;
}

.pbjinv-detail-layout {
	display: grid;
	grid-template-columns: minmax(0, 2fr) minmax(260px, 1fr);
	gap: 16px;
	align-items: start;
}

.pbjinv-detail-main {
	min-width: 0;
}

.pbjinv-detail-side {
	display: flex;
	flex-direction: column;
	gap: 12px;
}

.pbjinv-totals {
	width: 100%;
	border-collapse: collapse;
	font-size: 14px;
}

.pbjinv-totals td {
	padding: 4px 0;
	border-bottom: 1px solid var(--pbjinv-bg-soft);
}

.pbjinv-totals .pbjinv-num-col {
	text-align: right;
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}

.pbjinv-totals tr.pbjinv-total-row td {
	font-weight: 700;
	border-top: 1px solid var(--pbjinv-border);
	border-bottom: none;
}

.pbjinv-totals tr.pbjinv-deposit-row td {
	color: var(--pbjinv-warn);
	font-weight: 600;
}

/* --------------------------------------------------------- Activity feed */

.pbjinv-feed {
	display: flex;
	flex-direction: column;
	gap: 2px;
}

.pbjinv-feed-row {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	align-items: baseline;
	padding: 6px 0;
	border-bottom: 1px solid var(--pbjinv-bg-soft);
	font-size: 13px;
}

.pbjinv-feed-type {
	font-weight: 600;
	min-width: 150px;
}

.pbjinv-feed-time {
	font-size: 12px;
}

.pbjinv-feed-detail {
	color: var(--pbjinv-text);
}

/* ------------------------------------------------------------------ Modal */

/* The scrim is the suite's now (--pbjcrm-overlay, 2026-08-15) — six dialogs
   across four plugins each had their own rgba() and no two matched. The modal
   itself already re-declares the tokens it needs, with literal fallbacks,
   because it is portalled to <body>; that is the pattern the rest of the suite
   was brought up to and it is why this file needed only one line. */
.pbjinv-modal-backdrop {
	position: fixed;
	inset: 0;
	background: var(--pbjcrm-overlay, rgba(29, 35, 39, 0.45));
	color: var(--pbjinv-text, var(--pbjcrm-text, #1d2327));
	z-index: 99990;
	display: flex;
	align-items: flex-start;
	justify-content: center;
	padding: 40px 16px;
	overflow-y: auto;
}

.pbjinv-modal {
	background: var(--pbjinv-bg, #fff);
	color: var(--pbjinv-text, #1d2327);
	/* The dialog's own edge — see the measurement in pbj-crm.css. It had none at
	   all, relying on the shadow, which says nothing at 3:1 on a dark preset. */
	border: 1px solid var(--pbjcrm-edge, #8e9296);
	border-radius: 8px;
	box-shadow: 0 10px 40px rgba(0, 0, 0, 0.28);
	width: 100%;
	max-width: 420px;
	font-size: 15px;
	line-height: 1.5;

	/* The dialog is portalled to <body>, outside .pbjcrm-portal, so it declares
	   the tokens it needs itself rather than inheriting them. */
	--pbjinv-bg: var(--pbjcrm-surface, #ffffff);
	--pbjinv-bg-soft: var(--pbjcrm-surface-alt, #f6f7f8);
	--pbjinv-border: var(--pbjcrm-border, #d8dce0);
	--pbjinv-text: var(--pbjcrm-text, #1d2327);
	--pbjinv-muted: var(--pbjcrm-muted, #646d76);
	--pbjinv-primary: var(--pbjcrm-accent, #2271b1);
	--pbjinv-primary-dark: var(--pbjcrm-accent-strong, #135e96);
	--pbjinv-danger: var(--pbjcrm-danger, #b32d2e);
	--pbjinv-radius: var(--pbjcrm-radius, 6px);
}

.pbjinv-modal * {
	box-sizing: border-box;
}

.pbjinv-modal input[type="text"],
.pbjinv-modal input[type="date"],
.pbjinv-modal input[type="number"],
.pbjinv-modal select,
.pbjinv-modal textarea {
	width: 100%;
	padding: 7px 10px;
	border: 1px solid var(--pbjinv-border);
	border-radius: var(--pbjinv-radius);
	background: var(--pbjcrm-surface, #fff);
	color: var(--pbjinv-text);
	font-size: 14px;
}

.pbjinv-modal-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 8px;
	padding: 14px 16px;
	border-bottom: 1px solid var(--pbjinv-border);
}

.pbjinv-modal-head h3 {
	margin: 0;
	font-size: 16px;
}

.pbjinv-modal-x {
	border: none;
	background: none;
	color: var(--pbjinv-muted);
	font-size: 14px;
	line-height: 1;
	cursor: pointer;
	padding: 4px;
}

.pbjinv-modal-x:hover {
	color: var(--pbjinv-danger);
}

.pbjinv-modal-body {
	padding: 14px 16px;
}

.pbjinv-modal-body p {
	margin: 0 0 10px;
	font-size: 13px;
}

.pbjinv-modal-foot {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	justify-content: flex-end;
	padding: 12px 16px;
	border-top: 1px solid var(--pbjinv-border);
	background: var(--pbjinv-bg-soft);
	border-radius: 0 0 8px 8px;
}

/* ------------------------------------------------------------ Responsive */

@media (max-width: 782px) {
	.pbjinv-detail-layout {
		grid-template-columns: 1fr;
	}

	.pbjinv-table th.pbjinv-col-optional,
	.pbjinv-table td.pbjinv-col-optional {
		display: none;
	}

	.pbjcrm-portal .pbjinv-toolbar input[type="search"],
	.pbjinv-scope .pbjinv-toolbar input[type="search"] {
		width: 100%;
	}

	.pbjcrm-portal .pbjinv-toolbar select,
	.pbjinv-scope .pbjinv-toolbar select {
		flex: 1;
		min-width: 130px;
	}

	.pbjinv-stat {
		flex: 1;
		min-width: 96px;
	}

	.pbjinv-feed-type {
		min-width: 0;
	}
}

@media (max-width: 480px) {
	.pbjinv-table th.pbjinv-col-narrow-hide,
	.pbjinv-table td.pbjinv-col-narrow-hide {
		display: none;
	}

	.pbjinv-card:not(.pbjcrm-ucard) {
		padding: 12px 12px;
	}

	.pbjinv-table th,
	.pbjinv-table td {
		padding: 6px 7px;
		font-size: 13px;
	}

	.pbjinv-table .pbjinv-col-qty {
		width: 76px;
	}

	.pbjinv-modal-backdrop {
		padding: 16px 8px;
	}

	.pbjinv-actions .pbjinv-btn {
		flex: 1;
		text-align: center;
	}
}

@media (max-width: 360px) {
	.pbjinv-view-head h2 {
		font-size: 17px;
	}

	.pbjinv-detail-head h2 {
		font-size: 19px;
	}
}

/* --------------------------------------------------------------- Printing */

/*
 * THE ONE PRINT BLOCK IN THIS FILE — there must never be a second one.
 *
 * Jake, 2026-08-13: "All items should have a clear edit button on the top …
 * as well as a print icon". The icon is in paintDetail()'s controls row; this
 * is what decides what the icon actually produces.
 *
 * THE RULE: what prints is the DOCUMENT — its number, its customer, its lines,
 * its totals — not the software around it. This block answers for pbjinv-
 * classes ONLY. The portal's menus, sub-menus, header, phone bar and toasts
 * are the CRM shell's chrome and are hidden by the single @media print block in
 * pbj-crm.css, which this screen renders inside. Re-hiding .pbjcrm-nav here
 * would be the same rule written twice.
 *
 * ⛔ This is NOT the customer's copy. The tokenized public page has its own
 * stylesheet and its own PDF, and "Download PDF" beside the public link is
 * still the thing to send somebody. This is the agent's screen on paper.
 *
 * Every rule carries !important because the 782px and 600px mobile blocks
 * further down the file DO match a sheet of paper (a letter page is about
 * 700 CSS px wide once the margins are off) and would otherwise have the last
 * word.
 */

@media print {
	/* --- Anything you press, and the bars that hold them. --- */
	.pbjinv-toolbar,
	.pbjinv-actions,
	.pbjinv-detail-controls,
	.pbjinv-pager,
	.pbjinv-backlink,
	.pbjinv-modal-backdrop,
	.pbjinv-btn {
		display: none !important;
	}

	/* --- Two columns on a screen are one column on a page, so the totals and
	   the terms read as a continuation of the document rather than a margin
	   that the printer may clip. --- */
	.pbjinv-detail-layout {
		display: block !important;
	}

	/* --- Boxes stop being boxes: on paper the whitespace already separates
	   them and the border is only ink. --- */
	.pbjinv-card:not(.pbjcrm-ucard),
	.pbjinv-panel {
		border: 0 !important;
		box-shadow: none !important;
		padding-left: 0 !important;
		padding-right: 0 !important;
	}

	/* --- Nothing scrolls on paper. A scrolling box prints its first screenful
	   and silently loses the rest, which on an invoice means losing lines. --- */
	.pbjinv-table,
	.pbjinv-detail-main,
	.pbjinv-detail-side {
		overflow: visible !important;
		max-height: none !important;
	}

	/* --- Keep the money together: a totals block split across a page break is
	   how somebody reads half a figure. --- */
	.pbjinv-card:not(.pbjcrm-ucard),
	.pbjinv-panel,
	.pbjinv-totals {
		break-inside: avoid;
		page-break-inside: avoid;
	}
}

/* ===========================================================================
   MOBILE PASS (appended 2026-08-04) — phones and small tablets.

   APPEND-ONLY: nothing above this line is touched, so desktop renders exactly
   as before. These blocks ADD to the 782px / 480px / 360px work already in the
   file (which collapses the detail layout, hides the optional columns, tightens
   the table padding and stretches the action buttons) — any property those
   blocks already set for a narrower width is deliberately left alone here, and
   the print block at the end still has the last word on paper.

   Breakpoints match the file's own: 782px large phones / small tablets,
   600px phones. Colours come from the --pbjinv-* tokens, which alias the CRM's.
   =========================================================================== */

@media (max-width: 782px) {
	/* --- Touch targets. --- */
	.pbjinv-btn,
	.pbjinv-stat,
	.pbjinv-typeahead-item {
		min-height: 40px;
	}

	.pbjinv-btn {
		display: inline-flex;
		align-items: center;
		justify-content: center;
	}

	/* The +/- controls on an invoice line stay compact — they sit inside a
	   table row — but square and thumb-sized rather than a sliver. */
	.pbjinv-rowctl .pbjinv-btn {
		min-width: 36px;
		min-height: 36px;
	}

	.pbjinv-btn-sm {
		min-height: 36px;
	}

	.pbjcrm-portal .pbjinv-field input[type="text"],
	.pbjcrm-portal .pbjinv-field input[type="date"],
	.pbjcrm-portal .pbjinv-field input[type="number"],
	.pbjinv-scope input[type="text"],
	.pbjinv-scope input[type="date"],
	.pbjinv-scope input[type="number"],
	.pbjinv-scope input[type="search"],
	.pbjinv-scope select,
	.pbjinv-modal input[type="text"],
	.pbjinv-modal input[type="date"],
	.pbjinv-modal input[type="number"],
	.pbjinv-modal select {
		min-height: 40px;
	}

	/* Wrapped rows need air between the lines too. */
	.pbjinv-actions,
	.pbjinv-strip,
	.pbjinv-radios,
	.pbjinv-detail-title,
	.pbjinv-modal-foot {
		row-gap: 8px;
	}

	/* Written as one line; allowed to become two. */
	.pbjinv-pager {
		flex-wrap: wrap;
	}
}

@media (max-width: 600px) {
	/* --- Toolbars: search and the drop-downs go full width, the buttons
	   share what is left of the row. --- */
	.pbjinv-toolbar {
		align-items: stretch;
	}

	.pbjcrm-portal .pbjinv-toolbar > input,
	.pbjcrm-portal .pbjinv-toolbar > select,
	.pbjcrm-portal .pbjinv-toolbar > label,
	.pbjinv-scope .pbjinv-toolbar > input,
	.pbjinv-scope .pbjinv-toolbar > select,
	.pbjinv-scope .pbjinv-toolbar > label {
		flex: 1 1 100%;
		width: 100%;
	}

	.pbjinv-toolbar .pbjinv-btn {
		flex: 1 1 auto;
	}

	.pbjinv-toolbar .pbjinv-spacer {
		display: none;
	}

	/* --- Tables. The optional and narrow-hide columns are already dropped
	   above; this is the safety net for the money columns that are left. The
	   invoice list and the line-items editor become blocks that drag sideways
	   rather than being cut off at the screen edge, and a table that already
	   fits still fills the width exactly as before. --- */
	.pbjinv-table {
		display: block;
		overflow-x: auto;
		-webkit-overflow-scrolling: touch;
	}

	/* The totals table is two columns of figures — it always fits, and must
	   keep sitting flush in the side panel. */
	.pbjinv-totals {
		display: table;
	}

	/* --- The stats strip across the top of the list: two per row rather than
	   four squeezed ones. --- */
	.pbjinv-stat {
		flex: 1 1 calc(50% - 8px);
	}

	/* --- Dialogs go full width, with the tokens' own radius kept. --- */
	.pbjinv-modal {
		max-width: none;
	}

	/* --- Panels and cards: a little more room inside. --- */
	.pbjinv-panel {
		padding: 10px 12px;
	}

	/* Type above value on the activity feed instead of a 150px hanging
	   column (the 782px block already released the minimum width). */
	.pbjinv-feed-row {
		gap: 2px 8px;
	}

	.pbjinv-feed-type {
		flex: 1 1 100%;
	}

	/* The picker and the recipient list stop being desk-width. */
	.pbjinv-typeahead-wrap {
		max-width: none;
	}
}

/* ===========================================================================
   1.16.0 (suite rows 13.2 / 13.4 / 13.6) — the savable description block under
   the line items, the inherited-defaults preview on notes/terms, and the
   re-open dialog's reason counter.

   APPEND-ONLY, like the mobile pass above: nothing before this line is touched.

   THEMING RULE, stated because this suite has shipped four contrast bugs that
   were invisible in a diff: every colour below is a --pbjinv-* token declared
   at the top of this file (and re-declared on .pbjinv-modal, which is portalled
   to <body> and inherits nothing). No hex literal is introduced where a token
   exists, and every control names its own `color` rather than trusting an
   inheritance that a <button> or a bare <textarea> does not actually have.
   =========================================================================== */

/* --- Placeholders. The inherited notes/terms preview (13.4) IS a placeholder,
   so it has to be a deliberate, legible grey rather than whatever the browser
   chooses to fade `color` to — on a dark preset the UA default lands somewhere
   between invisible and plain wrong, which is the same defect class as the
   date-picker glyph that stayed black because nothing declared color-scheme. --- */
.pbjcrm-portal .pbjinv-field input::placeholder,
.pbjcrm-portal .pbjinv-field textarea::placeholder,
.pbjinv-scope input::placeholder,
.pbjinv-scope textarea::placeholder,
.pbjinv-linenotes-text::placeholder,
.pbjinv-modal input::placeholder,
.pbjinv-modal textarea::placeholder {
	color: var(--pbjinv-muted);
	opacity: 1;
}

/* --- The description block in the line-items editor. --- */

.pbjinv-linenotes {
	margin-top: 14px;
	padding-top: 12px;
	border-top: 1px solid var(--pbjinv-border);
	color: var(--pbjinv-text);
}

.pbjinv-linenotes-head {
	margin: 0 0 2px;
	font-size: 14px;
	font-weight: 600;
	color: var(--pbjinv-text);
}

.pbjinv-linenotes > .pbjinv-field-hint {
	margin: 0 0 8px;
}

/* This textarea sits OUTSIDE a .pbjinv-field, so the portal's field rules
   above never reach it. It therefore declares its own box AND its own colours:
   a control that inherits nothing falls back to the UA's white box and black
   text, which is exactly how a dark-preset contrast bug gets shipped. */
.pbjcrm-portal .pbjinv-linenotes-text,
.pbjinv-scope .pbjinv-linenotes-text,
.pbjinv-linenotes-text {
	display: block;
	width: 100%;
	max-width: 100%;
	padding: 7px 10px;
	border: 1px solid var(--pbjinv-border);
	border-radius: var(--pbjinv-radius);
	background: var(--pbjinv-bg);
	color: var(--pbjinv-text);
	font-family: inherit;
	font-size: 14px;
	line-height: 1.5;
}

.pbjinv-linenotes-text:focus {
	border-color: var(--pbjinv-primary);
	outline: none;
	box-shadow: 0 0 0 1px var(--pbjinv-primary);
}

/* A one-button row under a field. The button inside names its own colour
   through .pbjinv-btn / .pbjinv-btn-ghost; this only positions it. */
.pbjinv-mini-actions {
	margin: 6px 0 0;
}

/* --- The same description, read-only, on the detail screen. --- */

.pbjinv-linenotes-read {
	margin-top: 12px;
	padding-top: 10px;
	border-top: 1px solid var(--pbjinv-border);
	color: var(--pbjinv-text);
}

.pbjinv-linenotes-body {
	margin: 0;
	font-size: 14px;
	line-height: 1.55;
	color: var(--pbjinv-text);
	/* Typed line breaks are part of the wording. textContent preserves them
	   and this is what makes them visible. */
	white-space: pre-wrap;
	overflow-wrap: break-word;
}

/* --- The re-open dialog's reason counter (13.6). Lives inside .pbjinv-modal,
   which re-declares --pbjinv-muted and --pbjinv-danger for exactly this
   reason. --- */

.pbjinv-counter {
	margin: 4px 0 0;
	font-variant-numeric: tabular-nums;
}

.pbjinv-counter-over {
	color: var(--pbjinv-danger);
	font-weight: 600;
}

/* ===========================================================================
   Mobile invoice editor. The desktop table remains a table; only the phone
   breakpoint turns each tbody row into a labelled card. Native iOS date
   controls also need min-width:0 — width/max-width alone do not override the
   browser's intrinsic date-control width.
   =========================================================================== */

@media (max-width: 782px) {
	.pbjinv-grid-2,
	.pbjinv-grid-2 > *,
	.pbjinv-field {
		min-width: 0;
	}

	.pbjcrm-portal .pbjinv-field input[type="date"],
	.pbjinv-scope .pbjinv-field input[type="date"],
	.pbjinv-modal .pbjinv-field input[type="date"] {
		display: block;
		box-sizing: border-box;
		width: 100%;
		min-width: 0;
		max-width: 320px;
	}

	.pbjinv-items-table {
		display: block;
		width: 100%;
		max-width: 100%;
		overflow: visible;
		border: 0;
	}

	.pbjinv-items-table thead {
		display: none;
	}

	.pbjinv-items-table tbody,
	.pbjinv-items-table tfoot {
		display: block;
		width: 100%;
	}

	.pbjinv-items-table tbody tr {
		display: block;
		box-sizing: border-box;
		width: 100%;
		max-width: 100%;
		margin: 0 0 12px;
		padding: 10px;
		border: 1px solid var(--pbjinv-border);
		border-radius: var(--pbjinv-radius);
		background: var(--pbjinv-bg-soft);
	}

	.pbjinv-items-table tbody td {
		display: grid;
		grid-template-columns: minmax(92px, 34%) minmax(0, 1fr);
		align-items: center;
		gap: 8px;
		width: 100%;
		min-width: 0;
		padding: 6px 0;
		border: 0;
		white-space: normal;
		text-align: left;
	}

	/* Beat the desktop column classes: stacked rows own the full card width. */
	.pbjinv-table.pbjinv-items-table tbody td,
	.pbjinv-table.pbjinv-items-table tbody td.pbjinv-col-qty,
	.pbjinv-table.pbjinv-items-table tbody td.pbjinv-col-tax,
	.pbjinv-table.pbjinv-items-table tbody td.pbjinv-col-reuse,
	.pbjinv-table.pbjinv-items-table tbody td.pbjinv-col-ctl {
		box-sizing: border-box;
		width: 100%;
		min-width: 0;
		max-width: 100%;
		white-space: normal;
		text-align: left;
	}

	.pbjinv-items-table tbody td::before,
	.pbjinv-items-table .pbjinv-subtotal-preview::before {
		content: attr(data-label);
		font-size: 12px;
		font-weight: 600;
		line-height: 1.3;
		color: var(--pbjinv-muted);
		text-align: left;
	}

	.pbjinv-items-table tbody td > input[type="text"] {
		box-sizing: border-box;
		width: 100%;
		min-width: 0;
		max-width: 100%;
	}

	.pbjinv-items-table tbody td > input[type="checkbox"] {
		width: auto;
		min-width: 20px;
		min-height: 20px;
		margin: 0;
		justify-self: start;
	}

	.pbjinv-items-table .pbjinv-rowctl {
		flex-wrap: wrap;
		gap: 6px;
	}

	.pbjinv-items-table .pbjinv-btn-reuse {
		justify-self: start;
		white-space: normal;
	}

	.pbjinv-items-table .pbjinv-remove-line {
		font-size: 0;
	}

	.pbjinv-items-table .pbjinv-remove-line::after {
		content: "Delete";
		font-size: 13px;
	}

	.pbjinv-items-table tfoot tr {
		display: block;
		padding: 2px 10px 8px;
	}

	.pbjinv-items-table tfoot td {
		display: none;
	}

	.pbjinv-items-table tfoot .pbjinv-subtotal-preview {
		display: grid;
		grid-template-columns: minmax(92px, 34%) minmax(0, 1fr);
		gap: 8px;
		width: 100%;
		padding: 8px 0;
		border: 0;
		text-align: right;
	}

	.pbjinv-add-line {
		margin: 8px 0 14px;
	}

	.pbjinv-add-line .pbjinv-add-line-btn {
		width: 100%;
	}
}

@media (max-width: 390px) {
	.pbjcrm-portal .pbjinv-field input[type="date"],
	.pbjinv-scope .pbjinv-field input[type="date"],
	.pbjinv-modal .pbjinv-field input[type="date"] {
		max-width: 100%;
	}
}
