/*
 * PBJ Helpdesk — front-end portal styles (Phase 7 + Phase 5 mail client).
 * Self-contained, no frameworks. Every class is prefixed pbjhd-.
 */

/* ------------------------------------------------------------ Base shell */

.pbjhd-portal,
.pbjhd-login {
	--pbjhd-bg: var(--pbjcrm-surface, #ffffff);
	--pbjhd-bg-soft: var(--pbjcrm-surface-alt, #f6f7f8);
	--pbjhd-border: var(--pbjcrm-border, #d8dce0);
	--pbjhd-text: var(--pbjcrm-text, #1d2327);
	--pbjhd-muted: var(--pbjcrm-muted, #646d76);
	--pbjhd-primary: var(--pbjcrm-accent, #2271b1);
	--pbjhd-primary-dark: var(--pbjcrm-accent-strong, #135e96);
	--pbjhd-danger: var(--pbjcrm-danger, #b32d2e);
	--pbjhd-ok: var(--pbjcrm-success, #1a7a3c);
	--pbjhd-warn: var(--pbjcrm-warning, #996800);
	--pbjhd-radius: var(--pbjcrm-radius, 6px);
	/* 2.11.0: these two were USED and never DEFINED, so every rule reading them
	   fell through to its literal fallback and stopped following the CRM's
	   theme. --pbjhd-hover was the visible one: it is the highlight on a search
	   suggestion, and its fallback rgba(0,0,0,.05) is a BLACK wash, so on the
	   CRM's Dark preset (surface #1f2229) hovering a suggestion made the row
	   DARKER and the highlight disappeared — you could not see what you were
	   about to click. The CRM's own list uses surface-alt, which is lighter on
	   dark and darker on light, so it reads correctly both ways; we take the
	   same token rather than inventing a second answer. */
	--pbjhd-hover: var(--pbjcrm-surface-alt, #f6f7f8);
	--pbjhd-accent: var(--pbjcrm-accent, #2271b1);
	color: var(--pbjhd-text);
	font-size: 15px;
	line-height: 1.5;
	max-width: 1080px;
	margin: 0 auto;
	/* 1.0.1: paint our own surface, because inheriting the WordPress theme's
	   background made inactive nav and text unreadable on dark sites.
	   1.8.0: that surface now follows PBJ CRM's theme (see the variables above)
	   rather than being hardcoded light — so the CRM's Dark preset gives a dark
	   card with light text, and a site with no CRM still gets the light
	   fallbacks. It is still OUR surface either way; the site's theme never
	   reaches in. */
	background: var(--pbjhd-bg);
	padding: 24px;
	border-radius: var(--pbjhd-radius);
}

.pbjhd-portal *,
.pbjhd-login * {
	box-sizing: border-box;
}

/* ------------------------------------------------- The page gutter (2.28.0)

   ⛔ THE STANDALONE PORTAL HAD NO PADDING AT ALL, AND NOTHING ELSE WAS GOING TO
   GIVE IT ANY (Jake, 2026-08-14, with a screenshot of a ticket flush against
   the left edge). There was no layout rule on `.pbjhd-portal` whatsoever — not
   a max-width, not a margin, not a gutter — so on a page whose theme provides
   no container of its own, the ticket number, the subject and the conversation
   all began at x=0.

   ⛔ `:not(.pbjhd-embedded)` IS LOAD-BEARING. Mounted inside the CRM portal the
   host ALREADY supplies 28px, and the existing
   `.pbjhd-crm-section .pbjhd-portal.pbjhd-embedded` rule zeroes this file's
   padding for exactly that reason — but that rule is scoped to a CRM ancestor,
   so a future host that embeds us without it would inherit a double gutter.
   Excluding the embedded case here means the padding is never applied twice, in
   either arrangement, rather than being applied and then taken away again.

   The phone gets a smaller one further down — on a 390px screen a 16px gutter
   either side is already 8% of the glass.

   ⚠️ THE TOKEN IS `--pbjcrm-space`, WHICH THE CRM ACTUALLY EMITS (14px). The
   first version reached for `--pbjhd-space`, which reads naturally and does not
   exist anywhere in this file — a var() naming an undeclared token silently
   uses its fallback and looks like it worked, so nothing would have flagged it.
   This file consumes the CRM's palette and spacing by design; check the emitted
   list before inventing a name. */
.pbjhd-portal:not(.pbjhd-embedded) {
	padding: var(--pbjcrm-space, 16px) var(--pbjcrm-space, 16px) 32px;
}

.pbjhd-card {
	background: var(--pbjhd-bg);
	border: 1px solid var(--pbjhd-border);
	border-radius: var(--pbjhd-radius);
	padding: 20px 24px;
}

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

.pbjhd-error {
	color: var(--pbjhd-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(--pbjhd-radius);
	padding: 8px 12px;
}

.pbjhd-notice {
	color: var(--pbjhd-ok);
	background: color-mix(in srgb, var(--pbjcrm-success, #1a7a3c) 10%, var(--pbjcrm-surface, #fff));
	border: 1px solid color-mix(in srgb, var(--pbjcrm-success, #1a7a3c) 35%, var(--pbjcrm-surface, #fff));
	border-radius: var(--pbjhd-radius);
	padding: 8px 12px;
}

/* ⛔ A NOTICE HAS TO LAND WHERE THE READER IS LOOKING (2026-08-22).

   notice() inserts its box at the TOP of <main>, which was fine while the page
   itself scrolled. The CRM portal's shell is now one clipped viewport with a
   single scrolling region, so the top of <main> is off-screen for anybody
   working part-way down a long screen — Triage above all, where the answer to
   a click landed somewhere the reader could not see and the control read as
   dead.

   ⚠️ IT IS A SECOND CLASS, DELIBERATELY. .pbjhd-notice and .pbjhd-error are
   painted INLINE into panels at dozens of call sites ("that list did not
   load"), and those must stay exactly where they are drawn. Only the box
   notice() builds carries this one, so only the transient message floats.

   z-index 880 sits it UNDER the CRM's fixed footer (890) and its header (900)
   rather than over either. 72px of clearance keeps TWO things off it on a hub
   site: the footer (34px, 40px in bulk mode) and the CRM's own toast stack,
   which is body-appended at bottom:16px and is somebody else's message — two
   notices printed on top of each other is worse than one that is late. On the
   standalone portal that clearance is simply a margin.

   ⚠️ position:fixed is safe here because the CRM shell puts no transform on
   .pbjcrm-app or .pbjcrm-view, which pbj-crm.css says out loud ("The app
   carries no transform"). A transform on either would make this box fixed to
   THAT element instead of the viewport. */
.pbjhd-toast {
	position: fixed;
	right: 16px;
	bottom: 72px;
	z-index: 880;
	margin: 0;
	max-width: min(420px, calc(100vw - 32px));
	box-shadow: 0 2px 10px rgba(0, 0, 0, 0.18);
}

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

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

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

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

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

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

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

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

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

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

/* Tell the BROWSER the page went dark, so it draws its own dark widgets.
   Nothing declared a color-scheme, so the UA still believed it was painting on
   white and drew the date field's ::-webkit-calendar-picker-indicator as a
   black glyph — invisible on the dark input beside it ("Book this in", reported
   on the Dark preset). filter: invert() would hide the symptom by damaging the
   icon and breaks wherever a host theme has already inverted something; saying
   what the surface actually is fixes the picker, the spinners and the drop-down
   lists at once. pbjcrm-is-dark is the CRM theme's OWN dark switch
   (PBJ_CRM_Theme::body_classes()) and this is its first consumer — it only
   exists on a dark preset, so light presets are untouched. */
.pbjcrm-is-dark .pbjhd-portal input[type="text"],
.pbjcrm-is-dark .pbjhd-portal input[type="email"],
.pbjcrm-is-dark .pbjhd-portal input[type="number"],
.pbjcrm-is-dark .pbjhd-portal input[type="date"],
.pbjcrm-is-dark .pbjhd-portal input[type="time"],
.pbjcrm-is-dark .pbjhd-portal input[type="search"],
.pbjcrm-is-dark .pbjhd-portal input[type="password"],
.pbjcrm-is-dark .pbjhd-portal select,
.pbjcrm-is-dark .pbjhd-portal textarea,
.pbjcrm-is-dark .pbjhd-login input[type="text"],
.pbjcrm-is-dark .pbjhd-login input[type="password"] {
	color-scheme: dark;
}

.pbjhd-portal select {
	width: auto;
	max-width: 100%;
}

.pbjhd-portal textarea {
	min-height: 110px;
	resize: vertical;
}

.pbjhd-portal label,
.pbjhd-login label {
	display: block;
	font-weight: 600;
	margin-bottom: 3px;
	font-size: 13px;
}

.pbjhd-field {
	margin: 0 0 14px;
}

.pbjhd-inline-label {
	display: inline-flex !important;
	align-items: center;
	gap: 6px;
	font-weight: 400 !important;
}

/* ---------------------------------------------------------------- Login */

.pbjhd-login {
	max-width: 420px;
	margin: 40px auto;
}

.pbjhd-login-title {
	margin-top: 0;
}

.pbjhd-lost {
	margin-bottom: 0;
	font-size: 13px;
}

/* --------------------------------------------------------------- Topbar */

.pbjhd-topbar {
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 10px 0;
}

.pbjhd-brand {
	font-size: 18px;
	font-weight: 700;
}

.pbjhd-topbar-user {
	margin-left: auto;
	color: var(--pbjhd-muted);
	font-size: 13px;
}

.pbjhd-logout {
	font-size: 13px;
}

/* ------------------------------------------------------------------ Nav */

.pbjhd-nav {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	border-bottom: 2px solid var(--pbjhd-border);
	padding-bottom: 8px;
	margin-bottom: 16px;
}

/* The Settings section's contents (5.2). It reuses .pbjhd-nav for the pill
   layout, so it has to undo that rule's own chrome: a second border here would
   draw a line straight under the main nav's line, and flex-basis puts the row
   on its own line instead of trailing after the section button. */
.pbjhd-subnav {
	flex-basis: 100%;
	width: 100%;
	border-bottom: 0;
	padding-bottom: 0;
	margin: 6px 0 0;
	padding-left: 10px;
}

.pbjhd-nav-item {
	border: 1px solid transparent;
	background: transparent;
	color: var(--pbjhd-text);
	border-radius: 999px; /* 1.1.0: pill tabs with clearer states */
	padding: 8px 15px;
	font-size: 14px;
	font-weight: 500;
	cursor: pointer;
	transition: background 0.15s ease, border-color 0.15s ease;
}

.pbjhd-nav-item:hover {
	background: var(--pbjhd-bg-soft);
	border-color: var(--pbjhd-border);
}

.pbjhd-nav-item.pbjhd-active {
	background: var(--pbjhd-primary);
	border-color: var(--pbjhd-primary-dark);
	color: var(--pbjcrm-accent-contrast, #fff);
	font-weight: 700;
	box-shadow: 0 1px 4px rgba(19, 94, 150, 0.35);
}

/* -------------------------------------------------------------- Toolbar */

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

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

.pbjhd-toolbar input[type="search"],
.pbjhd-toolbar input[type="text"] {
	width: 200px;
}

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

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

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

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

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

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

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

.pbjhd-ticket-number {
	font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
	font-size: 12px;
	color: var(--pbjhd-muted);
	white-space: nowrap;
}

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

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

.pbjhd-badge-status {
	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);
}

/* A ticket-number badge that opens the ticket. It is a real <button>, so it
   needs the button chrome taken off it and the pointer put back on. */
.pbjhd-badge-link {
	cursor: pointer;
	font-family: inherit;
	line-height: inherit;
	text-decoration: underline;
	text-underline-offset: 2px;
}

.pbjhd-badge-link:hover,
.pbjhd-badge-link:focus-visible {
	background: color-mix(in srgb, var(--pbjcrm-accent, #2271b1) 22%, var(--pbjcrm-surface, #fff));
}

.pbjhd-prio-low {
	background: var(--pbjcrm-surface-alt, #f0f0f1);
	color: var(--pbjcrm-text-soft, #50575e);
}

.pbjhd-prio-normal {
	background: color-mix(in srgb, var(--pbjcrm-accent, #2271b1) 10%, var(--pbjcrm-surface, #fff));
	color: var(--pbjcrm-accent-strong, #1f4e79);
}

.pbjhd-prio-high {
	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(--pbjhd-warn);
}

.pbjhd-prio-urgent {
	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(--pbjhd-danger);
}

.pbjhd-sla-chip {
	display: inline-block;
	border-radius: 4px;
	padding: 1px 7px;
	font-size: 11px;
	font-weight: 700;
	margin-right: 4px;
	white-space: nowrap;
}

.pbjhd-sla-due {
	background: color-mix(in srgb, var(--pbjcrm-warning, #996800) 12%, var(--pbjcrm-surface, #fff));
	color: var(--pbjhd-warn);
}

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

.pbjhd-sla-met {
	background: color-mix(in srgb, var(--pbjcrm-success, #1a7a3c) 10%, var(--pbjcrm-surface, #fff));
	color: var(--pbjhd-ok);
}

/* ----------------------------------------------------------- Pagination */

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

/* ---------------------------------------------------------- Ticket view */

.pbjhd-ticket-head {
	display: flex;
	flex-wrap: wrap;
	gap: 8px 14px;
	align-items: baseline;
	margin-bottom: 4px;
}

.pbjhd-ticket-head h2 {
	margin: 0;
	font-size: 20px;
}

/* The heading is the rename control for anybody the server would let rename it
   — the class is only ever added for that person, so this is not a style that
   promises an action somebody cannot take. The underline is dotted rather than
   solid so it does not read as a link; nothing here is navigation.
   ⛔ NOT ONE HEX: the colours are the same tokens the rest of the file takes
   from the CRM, so the affordance follows the Dark preset like everything
   else. */
.pbjhd-subject-editable {
	cursor: text;
	border-bottom: 1px dotted var(--pbjhd-border);
}

.pbjhd-subject-editable:hover,
.pbjhd-subject-editable:focus {
	border-bottom-color: var(--pbjhd-accent);
}

/* The field takes the heading's own size and colour, so the words do not jump
   or change weight at the moment they become editable. An <input> inherits
   neither font nor colour — the same trap the .pbjhd-ticket-controls block
   above describes for <button>. */
.pbjhd-subject-input {
	font: inherit;
	color: var(--pbjhd-text);
	background: var(--pbjhd-bg);
	border: 1px solid var(--pbjhd-accent);
	border-radius: var(--pbjhd-radius);
	padding: 2px 6px;
	width: 100%;
	max-width: 42rem;
}

/* Saving: the field is already disabled, and this says so. */
.pbjhd-subject-saving .pbjhd-subject-input {
	opacity: .6;
	cursor: progress;
}

/* The control bar sits on the same line as the number and the subject and is
   pushed to the far end, so the record's own controls (Edit, Print) never get
   confused with the module actions below (Book this in, Create an invoice). */
.pbjhd-ticket-controls {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
	margin-left: auto;
}

/* ⚠️ A <button> DOES NOT INHERIT `color` — the same trap the
   .pbjhd-book-actions block at the foot of this file describes. Both controls
   name it, so neither goes user-agent black on the CRM's Dark preset. */
.pbjhd-ticket-controls .pbjhd-btn {
	color: var(--pbjhd-text);
}

.pbjhd-print-btn {
	display: inline-flex;
	align-items: center;
	gap: 6px;
}

/* The glyph takes its colour from the button, which named one above. */
.pbjhd-icon-print {
	flex: 0 0 auto;
}

/* REMOVED IN 2.27.0: `.pbjhd-side-editing .pbjhd-panel`. Edit used to switch the
   side column into an editing MODE and this outlined the panels it had woken up.
   There is no mode any more — every control in the Attributes panel is live from
   the moment the screen draws — so Edit is now a jump-and-focus and the class it
   toggled is gone from the JS. The rule went with it rather than being left to
   match nothing. */

/* ------------------------- Ticket record blocks: REMOVED IN 2.27.0, all but one

   `.pbjhd-record`, `.pbjhd-rec-block`, `.pbjhd-rec-body`, `.pbjhd-rec-fact`,
   `.pbjhd-rec-label`, `.pbjhd-rec-value` and `.pbjhd-rec-sla` dressed the
   read-only WHO / WHAT / WHEN blocks under the ticket heading. Those blocks are
   gone — every fact in them is now a live control in the Attributes panel — and
   the JS emits none of these class names any more (verified by grep, not
   assumed), so the rules went with them rather than being left to match nothing.

   ⛔ `.pbjhd-rec-heading` STAYS AND IS STILL EMITTED. It dresses the WHY heading
   above the Conversation / Timeline pair, which is the one record heading left
   in the main column. Deleting it would strip that heading on every ticket.

   `.pbjhd-rec-block` also survives in the @media print break-inside list at the
   foot of this file; that is harmless and is left alone. */

.pbjhd-rec-heading {
	margin: 0;
	flex: 0 0 68px;
	font-size: 12px;
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--pbjhd-muted);
}

/* WHY heads the Conversation / Timeline pair, so it sits in the main column.
   `.pbjhd-rec-heading` above sets `flex: 0 0 68px`, which did the work when it
   was one heading in a flex row of facts; standing alone in a block container
   the flex shorthand is inert, so only the margin below applies. Left as is —
   the heading is shared, and giving it a second rule per context is how the two
   drift apart. */
.pbjhd-why-heading {
	margin: 0 0 6px;
}

/* ------------------------------------- The Attributes panel (2.27.0)

   One editable copy of who / what / when, in the side column. It replaced six
   things: the three read-only record blocks AND the status / priority /
   reassign / recategorize / change-who panels that restated them as controls.

   ⛔ NOT ONE COLOUR IS DECLARED HERE. Every value below is a --pbjhd-* token,
   which is itself an alias of the CRM's palette — the CRM owns the colours and
   this file consumes them (the rule the triage feed's kind colours follow). The
   SLA chips keep their own state colours, declared elsewhere, because urgency
   is the one thing on this panel allowed to shout. */

.pbjhd-attrs {
	padding: 0;
}

/* The disclosure triangle is the browser's, and it is kept — it is the
   affordance that says this opens, and on a phone it starts shut. */
.pbjhd-attr-summary {
	cursor: pointer;
	padding: 12px;
	list-style-position: inside;
}

.pbjhd-attr-summary h3 {
	display: inline;
	margin: 0;
	font-size: 14px;
}

.pbjhd-attrs[open] .pbjhd-attr-summary {
	border-bottom: 1px solid var(--pbjhd-border);
}

.pbjhd-attr-body {
	display: flex;
	flex-direction: column;
	gap: 8px;
	padding: 12px;
}

/* Who / What / When still read top to bottom inside the panel — the container
   is new, the three groupings are not. */
.pbjhd-attr-sub {
	margin: 6px 0 0;
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--pbjhd-muted);
}

.pbjhd-attr-sub:first-child {
	margin-top: 0;
}

/* Label left, control right. The label column is fixed so every control on the
   panel starts at the same x — a ragged left edge on a stack of dropdowns is
   what made the old side column read as five unrelated boxes. */
.pbjhd-attr {
	display: flex;
	align-items: center;
	gap: 8px;
	font-size: 13px;
}

.pbjhd-attr-label {
	flex: 0 0 88px;
	color: var(--pbjhd-muted);
}

.pbjhd-attr-value {
	flex: 1 1 auto;
	min-width: 0;
	color: var(--pbjhd-text);
}

/* ⚠️ A <select> and an <input> DO NOT INHERIT `color` or `font` — the same trap
   .pbjhd-ticket-controls names above. Without this the whole panel goes
   user-agent black on the CRM's dark presets. */
.pbjhd-attr-value select,
.pbjhd-attr-value input {
	width: 100%;
	max-width: 100%;
	box-sizing: border-box;
	font: inherit;
	font-size: 13px;
	color: var(--pbjhd-text);
	background: var(--pbjhd-bg);
	border: 1px solid var(--pbjhd-border);
	border-radius: var(--pbjhd-radius);
	padding: 3px 6px;
}

/* And the native date picker's own popup + calendar glyph, which is drawn by
   the browser and ignores `color` entirely. Same fix, and the same reason, as
   the CRM's 10.6 `color-scheme` rule — without it the picker is white-on-white
   on a dark preset. `inherit` follows whatever the page has already declared,
   rather than forcing a mode this plugin has no business choosing. */
.pbjhd-attr-value input[type="datetime-local"] {
	color-scheme: inherit;
}

.pbjhd-attr-customer {
	display: flex;
	align-items: center;
	gap: 8px;
	flex-wrap: wrap;
}

.pbjhd-attr-change {
	flex: 0 0 auto;
	color: var(--pbjhd-text);
}

.pbjhd-attr-hint {
	margin: 2px 0 0;
	font-size: 12px;
}

/* Every detail in the requester card, and the client row on the panel. */
/* ⛔ THE FALLBACK IS THE FIX (item 2, 2026-08-15). Jake reported the Client row
   as "an unthemed red underlined link", and this rule is why: `var(--pbjhd-primary)`
   with NO fallback is INVALID AT COMPUTED-VALUE TIME whenever that property has
   not been painted — the declaration is thrown away entirely and the anchor falls
   back to the browser's own link colours, which is where the red and the underline
   came from. It is the same defect item 3 fixed at the theme layer, and the same
   lesson: a token with no fallback is not a colour, it is a colour that USUALLY
   works.

   `--pbjcrm-link` is named ahead of the helpdesk's own token because the CRM owns
   the palette and this row is read inside the CRM portal more often than not; the
   helpdesk token is next, and a literal is last so there is always an answer. */
.pbjhd-detail-link,
.pbjhd-person-link {
	color: var(--pbjcrm-link, var(--pbjhd-primary, #2271b1));
	text-decoration: none;
	overflow-wrap: anywhere;
}

/* Underlined ON HOVER AND FOCUS ONLY — it has to be discoverable as a link
   without shouting on a panel that is mostly labels and values. */
.pbjhd-detail-link:hover,
.pbjhd-detail-link:focus,
.pbjhd-person-link:hover,
.pbjhd-person-link:focus {
	text-decoration: underline;
}

/* ⚠️ :visited is stated deliberately. Without it an agent who opened a customer
   once gets a different colour from one they have not, in the same panel — the
   identical defect .pbjcrm-queue-title carries a comment about, caught on screen
   and invisible in a diff. A person is the same person whether or not you looked
   at them yesterday. */
.pbjhd-detail-link:visited,
.pbjhd-person-link:visited {
	color: var(--pbjcrm-link, var(--pbjhd-primary, #2271b1));
}

.pbjhd-requester {
	padding: 0;
}

.pbjhd-requester .pbjhd-req-list,
.pbjhd-requester > p {
	padding: 0 12px 12px;
}

/* Generic dialog (2.27.0) — the customer picker. Same shape as the mail
   dialogs, which is why both come out of modalShell(); the class names are
   separate so a change to one cannot silently restyle the other. */

/* ⛔ portalRoot() is `#pbjhd-portal || document.body` (pbj-helpdesk.js), so the
   <body> branch is REACHABLE and these dialogs must not rely on inheriting the
   portal's colour. Both overlays therefore state the pair, and both take the
   suite's shared scrim (--pbjcrm-overlay, 2026-08-15) instead of the two
   different private rgba() values they used to carry. */
.pbjhd-modal-overlay {
	position: fixed;
	inset: 0;
	background: var(--pbjcrm-overlay, rgba(0, 0, 0, .5));
	color: var(--pbjhd-text, var(--pbjcrm-text, #1d2327));
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 16px;
	z-index: 100000;
}

/* --pbjcrm-edge over the card's own hairline, for the reason measured in
   pbj-crm.css: --pbjhd-border resolves to --pbjcrm-border, which is a row
   divider and measures well under 3:1 against the panel it encloses. */
.pbjhd-modal-modal {
	width: min(560px, 100%);
	max-height: 90vh;
	overflow: auto;
	border-color: var(--pbjcrm-edge, #8e9296);
}

.pbjhd-modal-modal h3 {
	margin-top: 0;
}

.pbjhd-modal-actions {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin-top: 12px;
}

/* ⚠️ :not(.pbjhd-btn-primary) IS LOAD-BEARING. A bare `.pbjhd-modal-actions
   .pbjhd-btn` out-specifies `.pbjhd-btn-primary` (0,2,0 against 0,1,0), so it
   would repaint the Save button's text to the body colour on its own accent
   background — which is exactly the contrast defect this rule exists to avoid,
   inflicted on the one button that had never had it. */
.pbjhd-modal-actions .pbjhd-btn:not(.pbjhd-btn-primary) {
	color: var(--pbjhd-text);
}

/* Kept: .pbjhd-ticket-meta is no longer emitted by paintTicket() (the record
   blocks replaced it), but the class is cheap and removing a rule other code
   might still reach for is not this change's job. */
.pbjhd-ticket-meta {
	display: flex;
	flex-wrap: wrap;
	gap: 6px 14px;
	font-size: 13px;
	color: var(--pbjhd-muted);
	margin-bottom: 14px;
}

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

.pbjhd-thread {
	display: flex;
	flex-direction: column;
	gap: 10px;
}

.pbjhd-entry {
	border: 1px solid var(--pbjhd-border);
	border-radius: var(--pbjhd-radius);
	background: var(--pbjhd-bg);
}

.pbjhd-entry-note {
	background: color-mix(in srgb, var(--pbjcrm-warning, #996800) 10%, var(--pbjcrm-surface, #fff));
	border-color: color-mix(in srgb, var(--pbjcrm-warning, #996800) 35%, var(--pbjcrm-surface, #fff));
}

.pbjhd-entry-system {
	background: var(--pbjhd-bg-soft);
	font-size: 13px;
}

.pbjhd-entry-head {
	display: flex;
	gap: 8px;
	align-items: baseline;
	padding: 7px 12px;
	border-bottom: 1px solid var(--pbjhd-border);
	font-size: 12px;
	color: var(--pbjhd-muted);
}

.pbjhd-entry-author {
	font-weight: 700;
	color: var(--pbjhd-text);
}

.pbjhd-entry-time {
	margin-left: auto;
	white-space: nowrap;
}

.pbjhd-entry-body {
	padding: 10px 12px;
	overflow-wrap: anywhere;
}

.pbjhd-entry-body p:first-child {
	margin-top: 0;
}

.pbjhd-entry-body p:last-child {
	margin-bottom: 0;
}

.pbjhd-entry-atts {
	padding: 0 12px 10px;
	font-size: 13px;
}

.pbjhd-entry-atts a {
	margin-right: 10px;
}

.pbjhd-delivery-failed {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 10px;
	margin: 0 12px 10px;
	padding: 8px 10px;
	border: 1px solid var(--pbjcrm-danger, #b42318);
	border-radius: var(--pbjhd-radius);
	color: var(--pbjcrm-danger, #b42318);
}

/* Reply box */

.pbjhd-replybox {
	border: 1px solid var(--pbjhd-border);
	border-radius: var(--pbjhd-radius);
	padding: 12px;
	background: var(--pbjhd-bg);
}

.pbjhd-replybox.pbjhd-note-mode {
	background: color-mix(in srgb, var(--pbjcrm-warning, #996800) 10%, var(--pbjcrm-surface, #fff));
}

.pbjhd-replybox-tools {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	align-items: center;
	margin-bottom: 8px;
}

.pbjhd-replybox-actions {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	align-items: center;
	margin-top: 8px;
}

.pbjhd-upload-list {
	font-size: 13px;
	color: var(--pbjhd-muted);
	margin: 6px 0 0;
	padding: 0;
	list-style: none;
}

/* Sidebar panels */

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

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

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

.pbjhd-panel .pbjhd-field:last-child {
	margin-bottom: 0;
}

/* Status stepper */

.pbjhd-stepper {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
}

.pbjhd-step {
	border: 1px solid var(--pbjhd-border);
	background: var(--pbjhd-bg-soft);
	border-radius: 999px;
	padding: 3px 11px;
	font-size: 12px;
	color: var(--pbjhd-muted);
}

.pbjhd-step.pbjhd-step-current {
	background: var(--pbjhd-primary);
	border-color: var(--pbjhd-primary);
	color: var(--pbjcrm-accent-contrast, #fff);
	font-weight: 700;
}

button.pbjhd-step.pbjhd-step-allowed {
	cursor: pointer;
	color: var(--pbjhd-primary);
	background: var(--pbjcrm-surface, #fff);
}

button.pbjhd-step.pbjhd-step-allowed:hover {
	border-color: var(--pbjhd-primary);
}

/* To-dos */

.pbjhd-todos {
	list-style: none;
	margin: 0 0 10px;
	padding: 0;
}

.pbjhd-todos li {
	display: flex;
	align-items: center;
	gap: 8px;
	padding: 4px 0;
	border-bottom: 1px dashed var(--pbjhd-border);
	font-size: 14px;
}

.pbjhd-todos li:last-child {
	border-bottom: none;
}

.pbjhd-todo-done {
	text-decoration: line-through;
	color: var(--pbjhd-muted);
}

.pbjhd-todo-del {
	margin-left: auto;
	background: none;
	border: none;
	color: var(--pbjhd-danger);
	cursor: pointer;
	font-size: 13px;
}

.pbjhd-todo-add {
	display: flex;
	gap: 6px;
}

/* ⛔ THE SAME SHAPE AS THE CRM'S CHECKLIST BOX — SWEPT IN THE SAME TURN (9b).
   `flex: 1` is `1 1 0%`: a zero basis, so the box has no width except what
   flex-grow hands it. Below 600px this file already stacks the row (see the
   media block further down, which is the DELIBERATE fix and predates this one),
   so the phone case was covered here. The band it did not cover is 600-782px
   and any engine that declines to grow a form control — which is exactly what
   collapsed the CRM's equivalent box to 22px on an iPhone. An honest basis plus
   a floor closes that band too, without touching the stacking rule below. */
.pbjhd-todo-add input {
	flex: 1 1 auto;
	min-width: 140px;
}

/* Canned picker */

.pbjhd-canned-list {
	max-height: 220px;
	overflow: auto;
	border: 1px solid var(--pbjhd-border);
	border-radius: var(--pbjhd-radius);
	margin-top: 6px;
}

.pbjhd-canned-item {
	display: flex;
	gap: 8px;
	align-items: center;
	padding: 6px 10px;
	border-bottom: 1px solid var(--pbjhd-border);
	font-size: 13px;
}

.pbjhd-canned-item:last-child {
	border-bottom: none;
}

.pbjhd-canned-item .pbjhd-badge {
	margin-left: auto;
}

/* ------------------------------------------------------------- Reports */

.pbjhd-report-cards {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
	gap: 12px;
	margin-bottom: 16px;
}

.pbjhd-report-card {
	border: 1px solid var(--pbjhd-border);
	border-radius: var(--pbjhd-radius);
	background: var(--pbjhd-bg);
	padding: 12px 14px;
}

.pbjhd-report-card .pbjhd-metric {
	font-size: 24px;
	font-weight: 700;
	display: block;
}

.pbjhd-report-card .pbjhd-metric-label {
	font-size: 12px;
	color: var(--pbjhd-muted);
}

.pbjhd-chart-wrap {
	border: 1px solid var(--pbjhd-border);
	border-radius: var(--pbjhd-radius);
	background: var(--pbjhd-bg);
	padding: 12px;
	margin-bottom: 16px;
}

.pbjhd-chart-wrap h3 {
	margin: 0 0 8px;
	font-size: 14px;
}

.pbjhd-chart-wrap canvas {
	width: 100%;
	height: auto;
	display: block;
}

.pbjhd-legend {
	display: flex;
	gap: 14px;
	font-size: 12px;
	color: var(--pbjhd-muted);
	margin-top: 6px;
}

.pbjhd-legend .pbjhd-swatch {
	display: inline-block;
	width: 10px;
	height: 10px;
	border-radius: 2px;
	margin-right: 4px;
}

.pbjhd-report-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
	gap: 16px;
	margin-bottom: 16px;
}

/* ------------------------------------------------------ Profile / config */

.pbjhd-pref-table select {
	min-width: 110px;
}

.pbjhd-section {
	margin-bottom: 24px;
}

.pbjhd-section > h3 {
	margin: 0 0 10px;
	padding-bottom: 6px;
	border-bottom: 1px solid var(--pbjhd-border);
}

/* Triage: the clickable "Tickets assigned to you" card and the cards it opens.
   Plain variables only — no color-mix() with a %% anywhere near this file
   (2.3.0 removed seventeen of those after browsers dropped every one). */

.pbjhd-report-card-action {
	cursor: pointer;
}

.pbjhd-report-card-action:hover,
.pbjhd-report-card-action:focus-visible {
	background: var(--pbjhd-bg-soft);
	border-color: var(--pbjhd-accent, var(--pbjhd-border));
}

.pbjhd-ticket-cards {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: 6px;
}

.pbjhd-ticket-card:not(.pbjcrm-ucard) {
	border: 1px solid var(--pbjhd-border);
	border-radius: var(--pbjhd-radius);
	background: var(--pbjhd-bg);
	padding: 10px 12px;
	cursor: pointer;
}

.pbjhd-ticket-card:not(.pbjcrm-ucard):hover {
	background: var(--pbjhd-bg-soft);
}

.pbjhd-ticket-reading-thread {
	min-width: 0;
}


.pbjhd-ticket-card-top {
	display: flex;
	align-items: center;
	gap: 8px;
	flex-wrap: wrap;
	margin-bottom: 6px;
}

.pbjhd-ticket-card-subject {
	margin: 0 0 8px;
	font-weight: 600;
	line-height: 1.35;
}

.pbjhd-ticket-card-foot {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 8px;
	flex-wrap: wrap;
	font-size: 12px;
}

/* Which ticket an entry belongs to. Renders only in the Team tab's member
   feed — a ticket's own timeline sends no ticket_number, so the element is
   never created there. */
.pbjhd-tl-ticket {
	font-size: 12px;
	margin: 2px 0 4px;
}

.pbjhd-tl-ticket a {
	color: var(--pbjhd-muted);
	text-decoration: none;
}

.pbjhd-tl-ticket a:hover {
	text-decoration: underline;
}

.pbjhd-config-form {
	border: 1px solid var(--pbjhd-border);
	border-radius: var(--pbjhd-radius);
	background: var(--pbjhd-bg-soft);
	padding: 12px;
	margin-top: 10px;
}

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

/* --------------------------------------------------------------- Triage */

/* .pbjhd-triage-mailcount was removed in 2.8.0 with the element it styled —
   the "New messages (not tickets yet)" count card. Deleting the rule alongside
   the markup is the point: a selector outliving its element is how a stylesheet
   turns into a list of things nobody dares touch. */

/* .pbjhd-triage-daylink removed with its element in 2.8.0 — the Triage ->
   Today link did not navigate and was pulled rather than shipped broken. If
   the link comes back, the style comes back with it. */

/* ---------------------------------------------------- Mail client (admin) */

.pbjhd-mail {
	display: flex;
	gap: 16px;
	align-items: start;
}

.pbjhd-mail-side {
	flex: 0 0 230px;
	min-width: 210px;
	max-width: 250px;
	overflow: auto;
	border: 1px solid var(--pbjhd-border);
	border-radius: var(--pbjhd-radius);
	background: var(--pbjhd-bg);
	padding: 10px;
}

.pbjhd-mail-sidetools {
	display: flex;
	gap: 6px;
	flex-wrap: wrap;
	margin-bottom: 10px;
}

/* The mailbox names the current account; it is not a container around Inbox.
   Keep that context in one ordinary field so mailbox and pile choices remain
   flat peers at every width. */
.pbjhd-mailbox-field {
	display: grid;
	gap: 5px;
	margin: 0 0 8px;
}

.pbjhd-mailbox-label {
	font-size: 12px;
	font-weight: 700;
	color: var(--pbjhd-muted);
}

.pbjhd-mailbox-field select {
	width: 100%;
	min-width: 0;
}

.pbjhd-mail-mbx {
	display: flex;
	width: 100%;
	align-items: center;
	gap: 6px;
	border: none;
	background: transparent;
	color: var(--pbjhd-text);
	border-radius: var(--pbjhd-radius);
	padding: 6px 8px;
	font-size: 14px;
	font-weight: 600;
	text-align: left;
	cursor: pointer;
}

.pbjhd-mail-mbx:hover {
	background: var(--pbjhd-bg-soft);
}

.pbjhd-mail-mbx.pbjhd-active {
	background: var(--pbjhd-primary);
	color: var(--pbjcrm-accent-contrast, #fff);
}

/* 2.13.0 / phase 11.2 — the "All mailboxes" entry. It is an ordinary rail
   button that happens to mean every mailbox, so it is styled as one and given
   a rule underneath rather than a colour of its own: the separator says "the
   real mailboxes start here" without inventing a second visual language for
   something that behaves identically. Colour comes from the themed tokens like
   everything else in this file — .pbjhd-mail-frame (10.5) is the ONE element
   that opts out of theming and this is not it. */
.pbjhd-mail-mbx-all {
	border-bottom: 1px solid var(--pbjhd-border);
	border-radius: var(--pbjhd-radius) var(--pbjhd-radius) 0 0;
	margin-bottom: 4px;
}

/* 2.13.0 / phase 11.3 — the "which customer is this address?" bar. Rides
   .pbjhd-notice for its colours so it inherits whatever that already resolves
   to on every preset; only layout is added here. Deliberately NOT given its own
   background: 10.5 and 10.6 were both contrast defects invisible in a diff, and
   the cheapest way not to add a third is not to introduce a colour pair that
   nothing else in the file has already had to get right. */
.pbjhd-clarify {
	margin: 0 0 12px;
}

.pbjhd-clarify-q {
	margin: 0 0 8px;
	font-weight: 600;
}

.pbjhd-clarify-opts {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	align-items: center;
}

.pbjhd-clarify-current {
	opacity: 0.85;
}

/* .pbjhd-mail-folder-name shared this rule until 2.9.0. The folder tree it
   belonged to was cut in 1.10.1 (collection is INBOX-only), so the selector had
   no element left to match. */
.pbjhd-mail-mbx-label {
	flex: 1;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	min-width: 0;
}

/* 1.7.0 — the four piles (Inbox / Filed / Spam / Bin).
   Drawn as real buttons rather than a text list, and deliberately heavier than
   the server folders below them: these are the piles somebody moves mail
   between all day, and the folders are reference. */
.pbjhd-mail-piles {
	display: flex;
	flex-direction: column;
	gap: 2px;
	margin: 6px 0 10px;
	padding-left: 0;
}

.pbjhd-mail-pile {
	display: flex;
	width: 100%;
	align-items: center;
	justify-content: space-between;
	gap: 6px;
	border: 1px solid transparent;
	background: transparent;
	color: var(--pbjhd-text);
	border-radius: var(--pbjhd-radius);
	padding: 6px 9px;
	font-size: 13px;
	font-weight: 600;
	text-align: left;
	cursor: pointer;
}

.pbjhd-mail-pile:hover {
	background: var(--pbjhd-bg-soft);
}

.pbjhd-mail-pile.pbjhd-active {
	background: var(--pbjhd-primary);
	border-color: var(--pbjhd-primary);
	color: var(--pbjcrm-accent-contrast, #fff);
}

.pbjhd-mail-pile-count {
	font-size: 12px;
	font-weight: 700;
	opacity: .75;
}

/* The sender-block tick that sits beside the spam button. */
.pbjhd-mail-blockask {
	display: inline-flex;
	align-items: center;
	gap: 5px;
	font-size: 12px;
	color: var(--pbjhd-muted);
	cursor: pointer;
}

/* "This became a ticket, so it is kept" — a sentence where the destructive
   buttons would otherwise be. */
.pbjhd-mail-kept {
	font-size: 12px;
	font-style: italic;
}

.pbjhd-mail-folders {
	margin: 2px 0 10px;
	padding-left: 10px;
}

.pbjhd-mail-folder {
	display: flex;
	width: 100%;
	align-items: center;
	gap: 6px;
	border: none;
	background: transparent;
	color: var(--pbjhd-muted);
	border-radius: var(--pbjhd-radius);
	padding: 4px 8px;
	font-size: 13px;
	text-align: left;
	cursor: pointer;
}

.pbjhd-mail-folder:hover {
	background: var(--pbjhd-bg-soft);
}

.pbjhd-mail-folder.pbjhd-active {
	background: var(--pbjhd-bg-soft);
	color: var(--pbjhd-primary);
	font-weight: 700;
}

.pbjhd-mail-count {
	background: var(--pbjhd-primary);
	color: var(--pbjcrm-accent-contrast, #fff);
	border-radius: 999px;
	padding: 0 7px;
	font-size: 11px;
	font-weight: 700;
	line-height: 1.6;
}

.pbjhd-mail-mbx.pbjhd-active .pbjhd-mail-count {
	background: var(--pbjcrm-surface, #fff);
	color: var(--pbjhd-primary);
}

.pbjhd-mail-main {
	flex: 1 1 auto;
	min-width: 0;
}

.pbjhd-mail-table td {
	vertical-align: middle;
}

tr.pbjhd-mail-unseen td {
	font-weight: 700;
}

.pbjhd-mail-subject {
	margin-right: 6px;
}

.pbjhd-mail-attflag {
	margin-right: 6px;
	font-size: 12px;
}

/* Reader */

.pbjhd-mail-head h2 {
	margin: 0 0 8px;
	font-size: 19px;
}

.pbjhd-mail-meta {
	font-size: 13px;
	color: var(--pbjhd-text);
	display: flex;
	flex-direction: column;
	gap: 2px;
	margin-bottom: 10px;
	overflow-wrap: anywhere;
}

.pbjhd-mail-actions {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	margin-bottom: 4px;
}

.pbjhd-mail-atts {
	margin-top: 8px;
	font-size: 13px;
}

.pbjhd-mail-atts a {
	margin-right: 12px;
}

.pbjhd-mail-bodywrap {
	margin-top: 12px;
}

.pbjhd-mail-remotebar {
	display: flex;
	align-items: center;
	gap: 10px;
	flex-wrap: wrap;
	border: 1px solid color-mix(in srgb, var(--pbjcrm-warning, #996800) 35%, var(--pbjcrm-surface, #fff));
	background: color-mix(in srgb, var(--pbjcrm-warning, #996800) 12%, var(--pbjcrm-surface, #fff));
	color: var(--pbjhd-warn);
	border-radius: var(--pbjhd-radius) var(--pbjhd-radius) 0 0;
	padding: 6px 12px;
	font-size: 13px;
}

/* The ONE element that does not follow the theme's surface. An iframe canvas is
   transparent, so whatever this element paints shows through the message; with
   a themed surface here the Dark preset put the srcdoc's dark text on a dark
   background and the mail could not be read. A message is authored for a white
   page, and renderMailBody() now paints one inside the frame — this background
   simply has to AGREE with it on every preset, or the two disagree at the edges
   while the frame is still empty. The border and corners stay themed. */
.pbjhd-mail-frame {
	display: block;
	width: 100%;
	height: 460px;
	border: 1px solid var(--pbjhd-border);
	border-radius: var(--pbjhd-radius);
	background: #ffffff;
}

.pbjhd-mail-remotebar + .pbjhd-mail-frame {
	border-top-left-radius: 0;
	border-top-right-radius: 0;
}

.pbjhd-mail-textbody {
	white-space: pre-wrap;
	overflow-wrap: anywhere;
	font-size: 14px;
}

/* Compose / convert modals */

.pbjhd-mail-overlay {
	position: fixed;
	inset: 0;
	background: var(--pbjcrm-overlay, rgba(29, 35, 39, 0.55));
	color: var(--pbjhd-text, var(--pbjcrm-text, #1d2327));
	z-index: 99990;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 16px;
}

.pbjhd-mail-modal {
	width: 100%;
	max-width: 620px;
	max-height: 90vh;
	overflow: auto;
	border-color: var(--pbjcrm-edge, #8e9296);
	box-shadow: 0 10px 40px rgba(0, 0, 0, 0.25);
}

.pbjhd-mail-modal h3 {
	margin-top: 0;
}

.pbjhd-mail-modal input[type="text"],
.pbjhd-mail-modal input[type="email"],
.pbjhd-mail-modal select,
.pbjhd-mail-modal textarea {
	width: 100%;
	max-width: 100%;
	padding: 7px 10px;
	border: 1px solid var(--pbjhd-border, #d8dce0);
	border-radius: var(--pbjhd-radius, 6px);
	background: var(--pbjcrm-surface, #fff);
	color: var(--pbjhd-text, #1d2327);
	font-size: 14px;
	box-sizing: border-box;
}

/* ------------------------------------------- 1.1.0 friendliness helpers */

.pbjhd-adminlink {
	font-size: 13px;
	font-weight: 600;
	white-space: nowrap;
}

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

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

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

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

.pbjhd-intro {
	display: flex;
	align-items: center;
	gap: 12px;
	background: color-mix(in srgb, var(--pbjcrm-accent, #2271b1) 10%, var(--pbjcrm-surface, #fff));
	border: 1px solid color-mix(in srgb, var(--pbjcrm-accent, #2271b1) 30%, var(--pbjcrm-surface, #fff));
	color: var(--pbjcrm-accent-strong, #1f4e79);
	border-radius: var(--pbjhd-radius);
	padding: 10px 14px;
	margin-bottom: 14px;
	font-size: 14px;
}

.pbjhd-intro span {
	flex: 1;
}

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

/* -------------------------------------------- 1.1.0 agent intake form */

.pbjhd-intake-section {
	border: 1px solid var(--pbjhd-border);
	border-radius: var(--pbjhd-radius);
	background: var(--pbjhd-bg);
	padding: 14px 16px;
	margin-bottom: 14px;
}

.pbjhd-intake-section h3 {
	margin: 0 0 10px;
	font-size: 14px;
}

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

.pbjhd-intake-section p.pbjhd-muted {
	margin: -4px 0 10px;
	font-size: 13px;
}

/* ---------------------------- 1.3.0 "Who is this for?" chooser + typeahead */

.pbjhd-forwho-modes {
	display: flex;
	flex-wrap: wrap;
	gap: 6px 18px;
	margin: 0 0 12px;
}

.pbjhd-forwho-picker {
	margin: 0 0 6px;
}

.pbjhd-typeahead {
	position: relative;
}

.pbjhd-typeahead-input {
	width: 100%;
}

.pbjhd-typeahead-results {
	display: flex;
	flex-direction: column;
	max-height: 240px;
	overflow-y: auto;
}

/* 2.11.0: matched to the CRM's own suggestion list (.pbjcrm-typeahead), so the
   two controls read as one product. It used to paint var(--pbjhd-bg) — the same
   colour as the card behind it — with no shadow and a top border removed, so on
   any preset the dropdown had no edge and appeared to merge into the panel. */
.pbjhd-typeahead-results:not(:empty) {
	border: 1px solid var(--pbjhd-border);
	border-radius: var(--pbjhd-radius);
	overflow: hidden;
	background: var(--pbjcrm-surface, #fff);
	box-shadow: var(--pbjcrm-shadow-raised, 0 1px 3px rgba(0, 0, 0, 0.18));
	margin-top: 4px;
}

.pbjhd-typeahead-results p.pbjhd-muted {
	margin: 0;
	padding: 8px 10px;
	font-size: 13px;
}

/* 2.11.0 — THE BUG THAT MADE SEARCH LOOK BROKEN RATHER THAN UNSTYLED.
   These are <button> elements, and a button does NOT inherit `color` from its
   parent: with no colour of its own it paints the UA's `buttontext`, which is
   black in every browser. `font: inherit` was set and `color` was not, so on the
   CRM's Dark preset the suggestions were black text on a dark surface — the
   request had returned rows, the buttons were in the DOM and clickable, and the
   list looked empty. Reported as "business search doesn't work"; it was working
   the whole time and could not be read. Always set BOTH on a themed button. */
.pbjhd-typeahead-option {
	display: block;
	width: 100%;
	padding: 8px 10px;
	border: 0;
	border-bottom: 1px solid var(--pbjhd-border);
	background: transparent;
	color: var(--pbjhd-text);
	font: inherit;
	text-align: left;
	cursor: pointer;
}

.pbjhd-typeahead-option:last-child {
	border-bottom: 0;
}

.pbjhd-typeahead-option:hover,
.pbjhd-typeahead-option:focus {
	background: var(--pbjhd-hover, rgba(0, 0, 0, 0.05));
}

.pbjhd-typeahead-chosen:empty {
	display: none;
}

.pbjhd-typeahead-chosen {
	margin-top: 4px;
	font-size: 13px;
}

.pbjhd-btn-small {
	padding: 2px 8px;
	font-size: 12px;
}

.pbjhd-byhand {
	margin-top: 12px;
	border-top: 1px solid var(--pbjhd-border);
	padding-top: 10px;
}

.pbjhd-byhand summary {
	cursor: pointer;
	font-size: 13px;
}

/* ------------------------------------------- 1.1.0 requester panel (CRM) */

#pbjhd-requester-panel .pbjhd-req-list {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	gap: 2px 10px;
	margin: 0;
	font-size: 13px;
}

#pbjhd-requester-panel dt {
	color: var(--pbjhd-muted);
	white-space: nowrap;
}

#pbjhd-requester-panel dd {
	margin: 0;
	overflow-wrap: anywhere;
}

#pbjhd-requester-panel p.pbjhd-muted {
	margin: 8px 0 0;
	font-size: 12px;
}

/* ------------------------------------------------- 1.1.0 Team management */

.pbjhd-team-head {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 6px 14px;
	margin-bottom: 10px;
}

.pbjhd-team-head h3 {
	margin: 0;
	font-size: 16px;
}

.pbjhd-team-head .pbjhd-muted {
	font-size: 13px;
}

.pbjhd-team-cards {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
	gap: 10px;
	margin-bottom: 12px;
}

.pbjhd-emp-card:not(.pbjcrm-ucard) {
	border: 1px solid var(--pbjhd-border);
	border-radius: var(--pbjhd-radius);
	background: var(--pbjhd-bg-soft);
	padding: 10px 12px;
}

.pbjhd-emp-name {
	display: block;
	border: none;
	background: none;
	padding: 0;
	margin: 0 0 6px;
	font-size: 15px;
	font-weight: 700;
	color: var(--pbjhd-primary);
	cursor: pointer;
	text-align: left;
}

.pbjhd-emp-name:hover {
	color: var(--pbjhd-primary-dark);
	text-decoration: underline;
}

.pbjhd-emp-meta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 4px 10px;
	font-size: 12px;
	color: var(--pbjhd-muted);
}

.pbjhd-emp-overdue {
	color: var(--pbjhd-danger);
	font-weight: 700;
}

.pbjhd-emp-actions {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	margin-top: 8px;
}

.pbjhd-emp-actions select {
	font-size: 12px;
	max-width: 100%;
}

.pbjhd-team-tools {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
	border-top: 1px solid var(--pbjhd-border);
	padding-top: 10px;
}

/* ------------------------------------- Triage, the manager home (2.22.0) */

.pbjhd-triage-block h4 {
	margin: 14px 0 6px;
	font-size: 14px;
}

/* .pbjhd-triage-pick and .pbjhd-is-picked were removed on 2026-08-22 with the
   elements they styled: the "handing over" bar at the top of the team column
   and the outline on a picked-up card. Handing a ticket over is one act on the
   ticket now (assigneePicker()), so there is no selection to hold and nothing
   to mark as held. */

/* ------------------------------------------- The searchable agent picker */

/* ⛔ ONE WIDGET, SIX PLACES (2026-08-22) — triage's unassigned pile, the ticket
   screen's Who panel, a team member's ticket list, the ticket list's bulk bar,
   the new-ticket form and the convert-a-message modal. There is no second set
   of rules for "the one in the card" because there is no second widget.

   The list is ABSOLUTE over a relative wrapper, so it lifts off the card rather
   than growing it and shoving the rest of the pile down while somebody reads
   it. z-index 3 clears the card's own chrome and stays far below the portal's
   fixed furniture — this is a panel inside the page, not over it. */
.pbjhd-apick {
	position: relative;
	display: inline-block;
	min-width: 170px;
	max-width: 100%;
}

.pbjhd-apick-input {
	width: 100%;
	box-sizing: border-box;
	font-size: 13px;
	padding: 5px 8px;
}

.pbjhd-apick-list {
	position: absolute;
	z-index: 3;
	top: calc(100% + 2px);
	left: 0;
	right: 0;
	margin: 0;
	padding: 4px 0;
	list-style: none;

	/* Long rosters scroll rather than running off the bottom of the screen. */
	max-height: 220px;
	overflow-y: auto;

	background: var(--pbjhd-surface);
	border: 1px solid var(--pbjhd-border);
	border-radius: var(--pbjhd-radius);
	box-shadow: 0 4px 14px rgba(0, 0, 0, 0.16);
	font-size: 13px;
}

.pbjhd-apick-option {
	padding: 6px 10px;
	cursor: pointer;
	/* A name is one line: two people with long names must not make one row
	   twice the height of its neighbour. */
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

/* ⚠️ THE ACTIVE ROW IS NOT :hover. Focus never leaves the input (the combobox
   is driven by aria-activedescendant), so the browser has no :focus to draw
   here and the arrow keys would move an invisible cursor. .is-active IS the
   caret, and the pointer gets :hover on top of it. */
.pbjhd-apick-option.is-active {
	background: var(--pbjhd-hover);
}

.pbjhd-apick-option:hover {
	background: var(--pbjhd-hover);
}

/* The person the record already names, so a reader can see what they are
   about to change before they change it. */
.pbjhd-apick-option.is-current {
	font-weight: 600;
}

.pbjhd-apick-empty {
	padding: 6px 10px;
	color: var(--pbjhd-muted);
}

/* Ungrouped staff are a LIST, not a team: names and numbers, no card. */
.pbjhd-triage-flat {
	list-style: none;
	margin: 0;
	padding: 0;
}

.pbjhd-triage-flat li {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
	padding: 6px 0;
	border-bottom: 1px solid var(--pbjhd-border);
	font-size: 13px;
}

.pbjhd-triage-flat li:last-child {
	border-bottom: none;
}

.pbjhd-triage-flat .pbjhd-emp-name {
	margin: 0;
	font-size: 14px;
}

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

@media (max-width: 782px) {
	/* ⛔ THE PHONE ORDER OF THE TICKET SCREEN IS DECLARED HERE AND NOWHERE ELSE
	   (Jake, 2026-08-14). Desktop is the DOM order — conversation left,
	   requester / attributes / to-dos / portal account down the right. The phone
	   order is different in a way no amount of stacking can produce, because it
	   SPLITS the side column across the conversation:

	       Attributes → conversation + timeline tabs → to-dos → portal → requester

	   `display: contents` dissolves .pbjhd-side so its panels become direct grid
	   items of the layout, and `order` then interleaves them with the main
	   column. ONE DOM, two orders, no JS asking how wide the window is and no
	   second render path to keep in step.

	   ⚠️ A NEW PANEL WITH NO RULE HERE GETS order:0 AND LANDS ABOVE EVERYTHING.
	   Anything appended to the side column in paintTicket() needs a class and a
	   line in this block, or it silently jumps to the top of the phone screen.

	   ⚠️ `display: contents` removes the box, so .pbjhd-side's own `gap` goes
	   with it — the gap below is what puts the spacing back on the layout. */
	/* ⚠️ `align-items: stretch` IS NOT BOILERPLATE — IT UNDOES AN INHERITANCE.
	   The desktop rule sets `align-items: start`, which on a GRID means "do not
	   stretch rows vertically" and is right there. Switched to a COLUMN flex box
	   the same declaration means "do not stretch across the WIDTH", so every
	   panel shrank to its content and the whole screen rendered in a ~425px strip
	   down the left. Found on screen; it was invisible in the diff, because the
	   line that caused it is the one line this block does not contain. */
	.pbjhd-ticket-layout {
		display: flex;
		flex-direction: column;
		align-items: stretch;
		gap: 14px;
	}

	.pbjhd-side {
		display: contents;
	}

	.pbjhd-attrs {
		order: 1;
	}

	.pbjhd-ticket-main {
		order: 2;
	}

	.pbjhd-todos-panel {
		order: 3;
	}

	.pbjhd-invite-panel {
		order: 4;
	}

	/* Reference material, and the last thing you need on a phone. */
	#pbjhd-requester-panel {
		order: 5;
	}

	.pbjhd-mail {
		flex-direction: column;
	}

	.pbjhd-mail-side {
		flex-basis: auto;
		width: 100%;
		min-width: 0;
		max-width: none;
		resize: none;
		border: 0;
		background: transparent;
		padding: 0;
		overflow: visible;
	}

	.pbjhd-mail-piles-main {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 6px;
	}

	.pbjhd-mail-piles-main .pbjhd-mail-pile {
		min-width: 0;
	}

	.pbjhd-mail-frame {
		height: 360px;
	}

	.pbjhd-mail-modal {
		max-height: 96vh;
	}

	.pbjhd-portal {
		font-size: 14px;
	}

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

	.pbjhd-toolbar input[type="search"],
	.pbjhd-toolbar input[type="text"] {
		width: 100%;
	}

	.pbjhd-nav {
		gap: 4px;
	}

	.pbjhd-nav-item {
		padding: 6px 9px;
		font-size: 13px;
	}

	.pbjhd-card {
		padding: 14px;
	}
}

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

	.pbjhd-topbar {
		flex-wrap: wrap;
	}
}

/* ------------------------------------------------------------------------- *
 * 1.2.0 — the portal mounted inside a host (the PBJ CRM portal).
 *
 * Same shell, same styles, minus the outer chrome: the host already centres the
 * page and draws its own card, so a second width limit and a second rounded box
 * only look like a mistake. The self-contained light SURFACE from 1.0.1 stays
 * as it is — a host may be themed dark, and this portal's text colours are
 * still the light-background ones.
 * ------------------------------------------------------------------------- */
.pbjhd-crm-section .pbjhd-portal.pbjhd-embedded {
	max-width: none;
	margin: 0;
	padding: 0;
}

.pbjhd-crm-section .pbjhd-portal.pbjhd-embedded .pbjhd-nav {
	margin-top: 0;
}

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

   APPEND-ONLY: everything above is untouched, so desktop is unchanged. These
   blocks ADD to the 782px / 480px responsive work already in the file (which
   already collapses the ticket layout and the mail client's two columns and
   hides the optional table columns) — properties those blocks already set are
   deliberately left alone here.

   Breakpoints match the ones the file already uses: 782px for large phones and
   small tablets, 600px for a phone held in one hand. Colours come from the
   --pbjhd-* tokens, which alias the CRM's theme.
   =========================================================================== */

@media (max-width: 782px) {
	/* --- Touch targets: 44px minimum on everything a thumb has to hit. --- */
	.pbjhd-btn,
	.pbjhd-nav-item,
	button.pbjhd-step,
	.pbjhd-mail-mbx,
	.pbjhd-mail-pile,
	.pbjhd-mail-folder,
	.pbjhd-typeahead-option,
	.pbjhd-canned-item {
		min-height: 44px;
	}

	.pbjhd-btn,
	.pbjhd-nav-item,
	button.pbjhd-step {
		display: inline-flex;
		align-items: center;
		justify-content: center;
	}

	/* The small buttons inside a to-do row or a card stay small in type but
	   not in target. */
	.pbjhd-btn-sm,
	.pbjhd-btn-small {
		min-height: 44px;
	}

	.pbjhd-portal input[type="text"],
	.pbjhd-portal input[type="email"],
	.pbjhd-portal input[type="number"],
	.pbjhd-portal input[type="date"],
	.pbjhd-portal input[type="search"],
	.pbjhd-portal input[type="password"],
	.pbjhd-portal select,
	.pbjhd-login input[type="text"],
	.pbjhd-login input[type="password"] {
		min-height: 44px;
	}

	/* Wrapped rows of pills need room between the lines as well as beside. */
	.pbjhd-nav,
	.pbjhd-stepper,
	.pbjhd-mail-actions,
	.pbjhd-replybox-tools,
	.pbjhd-replybox-actions,
	.pbjhd-emp-actions,
	.pbjhd-team-tools {
		row-gap: 8px;
	}

	/* Rows that were written as a single line: let them fall onto two rather
	   than squeezing the timestamp into nothing. */
	.pbjhd-pager,
	.pbjhd-entry-head,
	.pbjhd-legend,
	.pbjhd-todos li {
		flex-wrap: wrap;
	}

	/* The mail rail sits ABOVE the list here (the 782px block above already
	   dropped the two columns to one), so it should read as a strip of piles
	   rather than a tall sidebar: the indents go, and the two tool buttons
	   share the row. */
	.pbjhd-mail-piles,
	.pbjhd-mail-folders {
		padding-left: 0;
	}

	.pbjhd-mail-sidetools .pbjhd-btn {
		flex: 1 1 auto;
	}
}

@media (max-width: 600px) {
	/* --- Toolbars: the search box takes the whole width, the buttons share
	   what is left. --- */
	.pbjhd-toolbar {
		align-items: stretch;
	}

	.pbjhd-toolbar > input,
	.pbjhd-toolbar > select,
	.pbjhd-toolbar > label {
		flex: 1 1 100%;
		width: 100%;
	}

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

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

	/* --- Tables. The optional columns are already hidden above; this makes
	   sure whatever is left can be reached by dragging the table sideways
	   instead of being cut off at the screen edge. A table that fits still
	   fills the width exactly as before. --- */
	.pbjhd-table {
		display: block;
		overflow-x: auto;
		-webkit-overflow-scrolling: touch;
	}

	/* --- Ticket screen. --- */
	.pbjhd-ticket-head h2 {
		font-size: 17px;
	}

	.pbjhd-entry-time {
		margin-left: 0;
	}

	.pbjhd-panel,
	.pbjhd-emp-card:not(.pbjcrm-ucard),
	.pbjhd-report-card,
	.pbjhd-intake-section {
		padding: 10px 12px;
	}

	.pbjhd-card {
		padding: 12px;
	}

	/* --- Mail: the compose / convert dialogs go full width. The reading
	   frame's height is already set for narrow screens by the 782px block
	   above, so it is left alone. --- */
	.pbjhd-mail-overlay {
		align-items: flex-start;
		padding: 8px;
	}

	.pbjhd-mail-modal {
		max-width: none;
		max-height: calc(100vh - 16px);
	}

	/* The account context and piles are already a flat strip at this width. */
	.pbjhd-mail-side {
		padding: 0;
	}

	/* --- Reply box and to-dos: the add row stacks so the input is usable. --- */
	.pbjhd-todo-add {
		flex-wrap: wrap;
	}

	.pbjhd-todo-add input {
		flex: 1 1 100%;
	}

	.pbjhd-todo-add .pbjhd-btn {
		flex: 1 1 auto;
	}
}

/* --------------------------------------------------------------------------
   2.4.0 — follow-up suggestions and the ticket timeline.
   -------------------------------------------------------------------------- */

/* The caution flag on an inbox row. Warning colour, not danger: nothing has
   gone wrong, there is just something worth a look. */
.pbjhd-mail-followup-flag {
	margin-left: 0.4em;
	color: var(--pbjhd-warn);
	font-weight: 700;
}

.pbjhd-mail-table tr.pbjhd-mail-followup td {
	box-shadow: inset 3px 0 0 var(--pbjhd-warn);
}

/* The prompt on the open email. */
.pbjhd-followup-prompt {
	margin-top: 1em;
	padding: 0.9em 1em;
	border: 1px solid var(--pbjhd-warn);
	border-left-width: 4px;
	border-radius: var(--pbjhd-radius);
	background: var(--pbjhd-bg-soft);
}

.pbjhd-followup-lead {
	margin: 0 0 0.35em;
	display: flex;
	align-items: center;
	gap: 0.45em;
}

.pbjhd-followup-icon {
	color: var(--pbjhd-warn);
	font-size: 1.15em;
}

.pbjhd-followup-prompt p {
	margin: 0 0 0.5em;
}

.pbjhd-followup-target {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 0.4em;
}

.pbjhd-followup-actions {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5em;
	margin-top: 0.6em;
}

/* Conversation / Timeline switch. */
.pbjhd-thread-tabs {
	display: flex;
	gap: 0.25em;
	margin-bottom: 0.9em;
	border-bottom: 1px solid var(--pbjhd-border);
}

.pbjhd-thread-tabs .pbjhd-tab {
	appearance: none;
	background: none;
	border: 1px solid transparent;
	border-bottom: none;
	border-radius: var(--pbjhd-radius) var(--pbjhd-radius) 0 0;
	padding: 0.5em 0.95em;
	margin-bottom: -1px;
	cursor: pointer;
	color: var(--pbjhd-muted);
	font: inherit;
	font-weight: 600;
}

.pbjhd-thread-tabs .pbjhd-tab:hover {
	color: var(--pbjhd-text);
}

.pbjhd-thread-tabs .pbjhd-tab-on {
	background: var(--pbjhd-bg);
	border-color: var(--pbjhd-border);
	color: var(--pbjhd-text);
}

/* The rail itself. The line down the left is drawn on the list, not on each
   item, so it stays unbroken between entries and behind the day headings. */
.pbjhd-timeline {
	list-style: none;
	margin: 0;
	padding: 0 0 0 1.75em;
	position: relative;
}

.pbjhd-timeline::before {
	content: "";
	position: absolute;
	left: 0.62em;
	top: 0.4em;
	bottom: 0.4em;
	width: 2px;
	background: var(--pbjhd-border);
}

.pbjhd-tl-day {
	position: relative;
	margin: 1.1em 0 0.6em -1.75em;
	padding-left: 1.75em;
	font-weight: 700;
	font-size: 0.92em;
	color: var(--pbjhd-muted);
	text-transform: uppercase;
	letter-spacing: 0.03em;
}

.pbjhd-timeline > li:first-child.pbjhd-tl-day {
	margin-top: 0;
}

.pbjhd-tl-item {
	position: relative;
	margin: 0 0 0.85em;
	padding: 0.6em 0.8em;
	border: 1px solid var(--pbjhd-border);
	border-radius: var(--pbjhd-radius);
	background: var(--pbjhd-bg);
}

/* The dot sits on the rail, centred on it, with a ring of page background so
   the line appears to pass behind rather than through it. */
.pbjhd-tl-icon {
	position: absolute;
	left: -1.75em;
	top: 0.55em;
	width: 1.25em;
	height: 1.25em;
	line-height: 1.25em;
	text-align: center;
	font-size: 0.85em;
	border-radius: 50%;
	background: var(--pbjhd-bg);
	box-shadow: 0 0 0 2px var(--pbjhd-bg);
}

.pbjhd-tl-head {
	display: flex;
	align-items: baseline;
	flex-wrap: wrap;
	gap: 0.5em;
	margin-bottom: 0.25em;
}

.pbjhd-tl-label {
	font-weight: 700;
}

.pbjhd-tl-author {
	color: var(--pbjhd-muted);
}

.pbjhd-tl-time {
	margin-left: auto;
	color: var(--pbjhd-muted);
	font-size: 0.88em;
	white-space: nowrap;
}

.pbjhd-tl-body {
	overflow-wrap: anywhere;
}

.pbjhd-tl-body > *:first-child {
	margin-top: 0;
}

.pbjhd-tl-body > *:last-child {
	margin-bottom: 0;
}

.pbjhd-tl-atts {
	display: flex;
	flex-wrap: wrap;
	gap: 0.6em;
	margin-top: 0.5em;
}

/* An internal note is staff-only. It reads differently on purpose, so nobody
   ever mistakes one for something the customer has seen. */
.pbjhd-tl-private {
	background: var(--pbjhd-bg-soft);
	border-style: dashed;
}

/* Events the customer never said, faded back so the rail reads as a story
   with the conversation in it rather than a log with replies buried in it. */
.pbjhd-tl-status,
.pbjhd-tl-priority,
.pbjhd-tl-assignment,
.pbjhd-tl-category,
.pbjhd-tl-customer,
.pbjhd-tl-generic {
	background: var(--pbjhd-bg-soft);
}

.pbjhd-tl-sla {
	border-color: var(--pbjhd-warn);
}

.pbjhd-tl-followup_attached {
	border-color: var(--pbjhd-primary);
}

@media (max-width: 640px) {
	.pbjhd-tl-time {
		margin-left: 0;
		width: 100%;
	}
}

/* ------------------------------------------------- Ticket top action bar */

/* Things you do to the WHOLE ticket, sitting under the meta line and above
   the two-column layout. It is a flex row so a second control can be added
   beside the first without touching this file, and the form it opens takes
   the full width because a date, a time and a note do not fit in a chip. */

.pbjhd-ticket-actions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
	margin: 0 0 16px;
}

/* A bar whose last control took itself away (a 501 on "Book this in" means the
   scheduling module has gone) must not leave a 16px hole behind it. */
.pbjhd-ticket-actions:empty {
	display: none;
	margin: 0;
}

.pbjhd-book {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
	flex: 1 1 100%;
}

/* 2.15.0 — "Create an invoice". Same full-width row as .pbjhd-book so the two
   controls stack predictably instead of one of them deciding the row height.
   The control itself is an <a class="pbjhd-btn">, and .pbjhd-btn names its own
   `color` (line 87), so it does not fall back to the user agent's link blue on
   the CRM's Dark preset — the same trap the comment on .pbjhd-book-actions
   below describes for buttons. */
.pbjhd-invoice-action {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
	flex: 1 1 100%;
}

.pbjhd-book-form {
	flex: 1 1 100%;
	border: 1px solid var(--pbjhd-border);
	border-radius: var(--pbjhd-radius);
	background: var(--pbjhd-bg-soft);
	color: var(--pbjhd-text);
	padding: 14px 16px;
}

.pbjhd-book-form h3 {
	margin: 0 0 10px;
	font-size: 15px;
	color: var(--pbjhd-text);
}

.pbjhd-book-form p {
	margin: 0 0 6px;
	font-size: 13px;
}

.pbjhd-book-modes {
	display: flex;
	flex-wrap: wrap;
	gap: 6px 20px;
	margin-bottom: 4px;
}

.pbjhd-book-row {
	display: flex;
	flex-wrap: wrap;
	gap: 0 14px;
}

.pbjhd-book-row .pbjhd-field {
	flex: 1 1 180px;
}

.pbjhd-book-warn {
	color: var(--pbjhd-warn);
}

.pbjhd-book-actions {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin-top: 12px;
}

/* ⚠️ A <button> DOES NOT INHERIT `color`. Every rule in this block that can
   land on one names the colour explicitly, because the alternative is the
   user agent's own black — which is invisible on the CRM's Dark preset, where
   --pbjhd-bg-soft is a dark surface. That exact bug has already been fixed
   once in this file (see --pbjhd-hover at the top); it is not coming back
   through the back door of a button that only inherited its colour by luck. */
.pbjhd-book-actions .pbjhd-btn {
	color: var(--pbjhd-text);
}

.pbjhd-book-actions .pbjhd-btn-primary {
	color: var(--pbjcrm-accent-contrast, #fff);
}

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

/* The Print control in the ticket's top bar calls window.print(); this is what
   makes the result worth the paper. What comes out is the ticket and whichever
   thread tab is on screen — everything you cannot click on paper goes.
 *
 * ⚠️ COLOUR IS FORCED TO BLACK-ON-WHITE ON PURPOSE, and it is not cosmetic.
 * The palette comes from the CRM's theme variables, so on the Dark preset
 * --pbjhd-text is a LIGHT colour: printed unchanged it is white ink on white
 * paper, i.e. a blank page that looks like a bug in the plugin. Forcing the
 * two colours is the only version that is right on every preset, and it is the
 * same reasoning as the --pbjhd-hover fix at the top of this file.
 *
 * ⚠️ THE TAB THE READER IS ON IS THE TAB THAT PRINTS, and nothing here has to
 * arrange that: showTab() sets display on the thread and the timeline as INLINE
 * styles, which no stylesheet rule can or should override. Conversation is the
 * default, so the ordinary printout is the ticket and its conversation. */

@media print {

	/* Portal chrome, navigation, and every control. */
	.pbjhd-topbar,
	.pbjhd-nav,
	.pbjhd-subnav,
	.pbjhd-tabs,
	.pbjhd-replybox,
	.pbjhd-ticket-controls,
	.pbjhd-ticket-actions,
	.pbjhd-bulkbar,
	.pbjhd-clarify,
	.pbjhd-btn,
	.pbjhd-intro,
	.pbjhd-notice,
	.pbjhd-error,
	.pbjhd-toolbar,
	#pbjhd-mail-root,
	#pbjhd-nav {
		display: none !important;
	}

	/* Nothing to type into on paper. */
	.pbjhd-app select,
	.pbjhd-app textarea,
	.pbjhd-app input[type="text"],
	.pbjhd-app input[type="search"],
	.pbjhd-app input[type="email"],
	.pbjhd-app input[type="date"] {
		display: none !important;
	}

	/* ⛔ THE ATTRIBUTES PANEL IS THE EXCEPTION TO THE RULE ABOVE, AND IT HAS TO
	   BE. Since 2.27.0 the ticket's status, priority, category, assignee and
	   dates are no longer printed as text anywhere — they ARE these controls, so
	   the blanket "nothing to type into on paper" hide would print a column of
	   labels with nothing beside them. That is worse than useless: it looks like
	   the ticket has no status.

	   A <select> renders its selected option's text, so it is put back and
	   stripped of every affordance instead — no border, no background, no arrow.
	   What lands on the page is the value, reading as plain text.

	   ⚠️ THESE RULES MUST STAY BELOW THE HIDE BLOCK. Both selectors are 0,2,0
	   and both carry !important, so the later one wins — move this above and the
	   panel silently disappears from every printout again. */
	.pbjhd-attr-value select,
	.pbjhd-attr-value input {
		display: inline-block !important;
		width: auto !important;
		border: 0 !important;
		padding: 0 !important;
		background: none !important;
		-webkit-appearance: none;
		-moz-appearance: none;
		appearance: none;
	}

	/* The rename affordance is an affordance, not a fact about the ticket.
	   Paper cannot be clicked. */
	.pbjhd-subject-editable {
		border-bottom: 0 !important;
	}

	/* One column: the side column's facts follow the conversation rather than
	   being squeezed into a third of the page width. */
	.pbjhd-ticket-layout {
		display: block !important;
	}

	.pbjhd-side {
		margin-top: 12px;
	}

	/* See the note above: legible on every theme preset, including Dark. */
	.pbjhd-portal,
	.pbjhd-portal * {
		background: transparent !important;
		color: #000 !important;
		box-shadow: none !important;
	}

	.pbjhd-portal *,
	.pbjhd-portal *::before,
	.pbjhd-portal *::after {
		border-color: #999 !important;
	}

	/* Do not split a reply, a note or a fact block across two sheets. */
	.pbjhd-entry,
	.pbjhd-panel,
	.pbjhd-rec-block,
	.pbjhd-tl-entry {
		break-inside: avoid;
		page-break-inside: avoid;
	}
}

/* 2.29.0 — "Add this email to a ticket": the manual filing control.
   Colours are tokens only; this file declares no literal hex so a themed
   site keeps its own palette. */
.pbjhd-mail-assign { margin: 12px 0 4px; }
.pbjhd-mail-assign-panel { margin-top: 8px; padding: 10px; border: 1px solid var(--pbjhd-border); border-radius: 6px; background: var(--pbjhd-surface); }
.pbjhd-mail-assign-panel input[type="search"] { width: 100%; box-sizing: border-box; }
.pbjhd-mail-assign-results { margin-top: 8px; max-height: 260px; overflow-y: auto; }
.pbjhd-mail-assign-row { display: flex; align-items: center; gap: 8px; padding: 6px 0; border-top: 1px solid var(--pbjhd-border); }
.pbjhd-mail-assign-row:first-child { border-top: 0; }
.pbjhd-mail-assign-subject { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ------------------------------------------------------------------ 2.41.0
 * The reply composer's "Send to" row. The recipient rows are ordinary
 * inline-label checkboxes, but the label carries a name AND an address badge,
 * which on a 390px phone is wider than the screen — so the row is allowed to
 * WRAP and the badge is allowed to BREAK, instead of pushing the whole ticket
 * screen sideways (caught by the 390px iframe probe before ship).
 */
.pbjhd-sendto { margin: 8px 0; }
.pbjhd-sendto .pbjhd-inline-label {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 4px 6px;
	max-width: 100%;
	min-width: 0;
}
.pbjhd-sendto .pbjhd-badge {
	max-width: 100%;
	overflow-wrap: anywhere;
	word-break: break-word;
	white-space: normal;
}
.pbjhd-sendto-list { display: flex; flex-direction: column; gap: 4px; }
.pbjhd-sendto-panel { max-width: 100%; }

/* ==========================================================================
   2.41.0 — THE SUITE'S ONE CARD TEMPLATE, ON THIS PLUGIN'S SURFACES

   The JS half is the "THE SUITE'S ONE CARD TEMPLATE" block in
   assets/js/pbj-helpdesk.js. Read that first. In short: the CRM publishes one
   card template on window.pbjCrmPortal and every row surface here now hands it
   a root element instead of drawing a row of its own.

   ⛔ THERE IS ALMOST NOTHING TO STYLE HERE, AND THAT IS THE POINT. The card's
   insides — the icon column, the title stack, the status/date row, the footer,
   and the single type edge — are `.pbjcrm-ucard*` and belong to pbj-crm.css.
	Restating any of them here would be this plugin quietly forking the
	template, which is the thing the release removes. What is below is only the
	mail stream wrapper; the card root and every part inside it belong to CRM.

   ⛔ AND IT IS ALL DEAD WEIGHT ON AN OLDER HUB, DELIBERATELY. No rule here is
   needed by the table path: a site whose CRM has no template never grows an
   element with these classes, so the old screens are unaffected by every line
   of it.
   ========================================================================== */

/* ===========================================================================
   2.43.0 — THE THREE THINGS THIS RELEASE ADDED TO THE SCREENS

   ⛔ EVERY COLOUR HERE IS var(--pbjcrm-*, #fallback). Not one literal, so a
   site on any of the CRM's presets gets its own palette and a site with no
   CRM tokens at all still gets a readable control.
   =========================================================================== */

/* ---------------------------------- Item 7: the inline ticket-action row */

/* The row that holds "Book this in", "Close this ticket" and "I have seen
   this" side by side inside the wrapping action bar.

   ⛔ IT WRAPS, AND THAT IS THE WHOLE REASON IT EXISTS. Until 2.43.0 this row
   borrowed `.pbjhd-attr` for one property — a flex row that does NOT wrap —
   with a note in the JS saying to swap the name in if a real class ever
   landed. Two short buttons survived that at 390px; three do not, and the
   last two helpdesk releases each shipped a phone overflow that three
   readings of a stylesheet called correct. So the row wraps, and `min-width:
   0` lets it shrink inside the bar rather than forcing the bar wider than the
   screen. */
.pbjhd-ticket-actions-pair {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
	flex: 1 1 auto;
	min-width: 0;
}

/* "I have seen this." Amber, the same hue waitingGlyph() wears, because it is
   the control that answers that glyph — and deliberately NOT red (that is
   closing) and NOT the primary blue (that is sending something). */
.pbjhd-btn-ack {
	color: var(--pbjcrm-warning, #996800);
	border-color: color-mix(in srgb, var(--pbjcrm-warning, #996800) 40%, var(--pbjcrm-surface, #fff));
	background: color-mix(in srgb, var(--pbjcrm-warning, #996800) 8%, var(--pbjcrm-surface, #fff));
}

.pbjhd-btn-ack:hover {
	background: color-mix(in srgb, var(--pbjcrm-warning, #996800) 16%, var(--pbjcrm-surface, #fff));
	border-color: color-mix(in srgb, var(--pbjcrm-warning, #996800) 55%, var(--pbjcrm-surface, #fff));
}

/* ------------------------------------- Item 3: the multi-select bulk bar */

/* One bar, both surfaces (ticket lists and the mail list). It only exists
   while something is ticked, so it may be loud: it is the answer to "what
   happens to these six". */
.pbjhd-bulkbar {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
	margin: 0 0 12px;
	padding: 8px 10px;
	border: 1px solid color-mix(in srgb, var(--pbjcrm-accent, #2271b1) 30%, var(--pbjcrm-surface, #fff));
	border-radius: var(--pbjhd-radius);
	background: color-mix(in srgb, var(--pbjcrm-accent, #2271b1) 8%, var(--pbjcrm-surface, #fff));
}

/* ⚠️ A <select> DOES NOT INHERIT `color` or `font` — the same trap
   .pbjhd-attr-value names above. Without this the two dropdowns go
   user-agent black on the CRM's dark presets. `max-width` keeps a long
   agent name from making the bar wider than the phone. */
.pbjhd-bulkbar select {
	max-width: 100%;
	box-sizing: border-box;
	font: inherit;
	font-size: 13px;
	color: var(--pbjhd-text);
}

.pbjhd-bulk-count {
	flex: 0 0 auto;
	color: var(--pbjhd-text);
	font-size: 13px;
}

/* Collapses to nothing when the bar wraps, rather than claiming a line of
   its own: `flex-basis: 0` means it only ever takes leftover space. */
.pbjhd-bulkbar .pbjhd-spacer {
	flex: 1 1 0;
	min-width: 0;
}

/* "Email the customer", "Block the sender" — a tick beside the button it
   qualifies, so the rarer choice needs no dialog.

   ⛔ IT CARRIES `.pbjhd-inline-label` IN THE MARKUP, AND THAT IS NOT
   DECORATION. `.pbjhd-portal label` (line 216) makes EVERY label in this
   portal `display: block; font-weight: 600` — a form-field rule that is right
   for a form field and wrong for a checkbox row, which is exactly why
   `.pbjhd-inline-label` already exists with its two `!important`s. Found by
   measuring rather than by reading: at 390px the tick and its words came out
   on two lines, in bold, and three readings of the stylesheet called it
   correct. */
.pbjhd-bulk-opt {
	gap: 4px;
	max-width: 100%;
	min-width: 0;
	font-size: 13px;
	color: var(--pbjhd-muted);
	cursor: pointer;
}

/* ------------------------------- Item 3: what the last run actually did */

/* ⛔ THIS IS THE HALF THAT MUST NOT BE QUIET. The { done, skipped[] }
   envelope exists so a partial refusal is visible, so the card is drawn
   whenever there is an answer to give — and the amber left edge marks it as
   something to read rather than as a success message to ignore. */
.pbjhd-bulk-report {
	margin: 0 0 12px;
	padding: 10px 12px;
	border: 1px solid var(--pbjhd-border);
	border-left: 4px solid var(--pbjcrm-warning, #996800);
	border-radius: var(--pbjhd-radius);
	background: var(--pbjhd-bg-soft);
	color: var(--pbjhd-text);
	font-size: 13px;
}

.pbjhd-bulk-report p {
	margin: 0 0 6px;
}

.pbjhd-bulk-done {
	font-weight: 700;
}

.pbjhd-bulk-left {
	color: var(--pbjhd-muted);
}

.pbjhd-bulk-skipped {
	margin: 0 0 8px;
	padding-left: 18px;
}

/* A ticket subject and a server's sentence are both long, and neither has a
   space where the phone wants one. */
.pbjhd-bulk-skipped li {
	margin: 0 0 3px;
	overflow-wrap: anywhere;
}

/* ------------------------------------ Item 3: the "add people" chip list */

.pbjhd-bulk-chips {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	margin: 0 0 8px;
}

.pbjhd-bulk-chip {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	max-width: 100%;
	padding: 2px 8px;
	border: 1px solid var(--pbjhd-border);
	border-radius: 999px;
	background: var(--pbjhd-bg-soft);
	color: var(--pbjhd-text);
	font-size: 12px;
	overflow-wrap: anywhere;
}

.pbjhd-bulk-chip-x {
	border: 0;
	padding: 0 2px;
	background: none;
	color: var(--pbjhd-muted);
	font-size: 15px;
	line-height: 1;
	cursor: pointer;
}

.pbjhd-bulk-chip-x:hover {
	color: var(--pbjhd-danger);
}

/* ------------------------------------------- Item 4: the merge dialogue */

/* One ticket per line, its radio first, so "which one stays" is answered by
   pointing at a ticket rather than by reading a dropdown of numbers. */
/* ⚠️ SCOPED TO BEAT `.pbjhd-portal label` (0,1,1), for the reason spelled out
   on .pbjhd-bulk-opt above. Unscoped, every one of these choices rendered as a
   bold block with the ticket number welded to the subject. */
.pbjhd-portal .pbjhd-merge-choice,
.pbjhd-login .pbjhd-merge-choice {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 6px;
	margin: 0;
	padding: 7px 0;
	border-bottom: 1px solid var(--pbjhd-border);
	color: var(--pbjhd-text);
	font-size: 13px;
	font-weight: 400;
	cursor: pointer;
}

.pbjhd-merge-choice span {
	min-width: 0;
	overflow-wrap: anywhere;
}

/* Where the cross-customer question is asked. It is a QUESTION: the server's
   own sentence, then the button that answers it. */
.pbjhd-merge-refusal {
	margin: 10px 0 0;
}

.pbjhd-merge-refusal .pbjhd-error {
	margin: 0 0 8px;
}

/* -------------------------- Item 3: "which ticket?" for attaching emails */

.pbjhd-bulk-picklist {
	display: flex;
	flex-direction: column;
	gap: 6px;
	margin-top: 10px;
	max-height: 260px;
	overflow-y: auto;
}

.pbjhd-bulk-pick {
	text-align: left;
	overflow-wrap: anywhere;
}

/* --------------------------------------------------------- On a phone */

/* ⚠️ MEASURED, NOT ASSUMED. The last two helpdesk releases each shipped a
   phone overflow that three readings of this stylesheet called correct and
   only a measurement found.

   ⛔ IT IS THE TOOLBAR'S OWN PHONE PATTERN, NOT A SECOND ONE. `.pbjhd-toolbar`
   at 600px already decided how a row of controls behaves on a phone —
   dropdowns and labels take the whole line, buttons share what is left, the
   spacer goes — and a bulk bar IS a toolbar that only appears when something
   is ticked. Same breakpoint, same three rules, so the two rows of controls
   on a ticket list cannot start behaving differently.

   Stretching every button to full width was measured first and rejected: it
   made the bar 486px tall on an 844px screen. */
@media (max-width: 600px) {

	.pbjhd-bulkbar {
		gap: 6px;
		align-items: stretch;
	}

	.pbjhd-bulkbar > select,
	.pbjhd-bulkbar > label {
		flex: 1 1 100%;
		width: 100%;
	}

	.pbjhd-bulkbar .pbjhd-btn {
		flex: 1 1 auto;
	}

	.pbjhd-bulkbar .pbjhd-spacer {
		display: none;
	}

	.pbjhd-bulk-count {
		flex: 1 1 100%;
	}
}

/* --------------------------------------------------------------------------
   Refined communication workspaces: compact rows, one adjustable master pane,
   structured compose surfaces, and the CRM-owned footer bulk mode.
   Layout only; every colour continues to come from the existing theme tokens.
   -------------------------------------------------------------------------- */

.pbjhd-mail-open-full {
	margin-left: auto;
}

.pbjhd-mail-reader-back {
	margin-top: 0;
}

/* A CRM embed already has the suite's one area rail. Mailbox and pile state are
   compact filters above the workspace here, with no second bordered rail or
   nested destination strip. Standalone Helpdesk keeps .pbjhd-mail-side. */
.pbjhd-mail-embedded {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: 10px;
}

.pbjhd-mail-context {
	display: flex;
	align-items: end;
	flex-wrap: wrap;
	gap: 8px;
	min-width: 0;
}

.pbjhd-mail-context .pbjhd-mail-sidetools {
	margin: 0;
}

.pbjhd-mail-context .pbjhd-mailbox-field {
	flex: 1 1 220px;
	margin: 0;
}

.pbjhd-mail-context > .pbjhd-btn {
	align-self: end;
}

.pbjhd-mail-context-actions {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 6px;
}

#pbj-crm-footer .pbjhd-mail-context-actions {
	flex-wrap: nowrap;
	max-width: 100%;
	overflow-x: auto;
	color: var(--pbjcrm-text);
}

#pbj-crm-footer .pbjhd-mail-context-actions .pbjhd-mail-blockask,
#pbj-crm-footer .pbjhd-mail-context-actions .pbjhd-mail-kept {
	color: var(--pbjcrm-muted);
}

.pbjhd-compose {
	max-width: 720px;
	padding: 0;
	overflow: hidden;
}

.pbjhd-compose > h3,
.pbjhd-compose-section,
.pbjhd-compose-actions {
	padding: 14px 16px;
}

.pbjhd-compose > h3 {
	margin: 0;
	border-bottom: 1px solid var(--pbjhd-border);
}

.pbjhd-compose-section + .pbjhd-compose-section,
.pbjhd-compose-actions {
	border-top: 1px solid var(--pbjhd-border);
}

.pbjhd-compose-section h4 {
	margin: 0 0 12px;
}

.pbjhd-compose-section .pbjhd-field:last-child,
.pbjhd-compose-section > .pbjhd-muted:last-child {
	margin-bottom: 0;
}

.pbjhd-compose-actions {
	justify-content: flex-end;
	margin-top: 0;
}

.pbjhd-compose-chips {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 8px;
	min-height: 36px;
}

.pbjhd-compose-chips [role="button"],
.pbjhd-compose-chip {
	cursor: pointer;
}

.pbjhd-compose-addressing[hidden] {
	display: none;
}

.pbjhd-compose-addressing {
	display: grid;
	gap: 10px;
	margin-top: 10px;
	padding: 12px;
	border: 1px solid var(--pbjhd-border);
	border-radius: var(--pbjhd-radius);
	background: var(--pbjcrm-surface, var(--pbjhd-bg));
}

.pbjhd-compose-addressing .pbjhd-field {
	margin: 0;
}

.pbjhd-compose textarea {
	min-height: 180px;
}

.pbjhd-compose-ticket {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	min-height: 36px;
	cursor: pointer;
}

#pbj-crm-footer > .pbjhd-bulkbar {
	width: 100%;
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: 0;
	background: transparent;
	flex-wrap: nowrap;
	overflow-x: auto;
}

@media (max-width: 782px) {
	.pbjhd-mail-main {
		padding-bottom: env(safe-area-inset-bottom);
	}

	.pbjhd-compose > h3,
	.pbjhd-compose-section,
	.pbjhd-compose-actions {
		padding: 12px;
	}

	.pbjhd-compose-actions .pbjhd-btn {
		flex: 1 1 0;
	}

	.pbjhd-mail-context {
		align-items: stretch;
	}

	.pbjhd-mail-context .pbjhd-mail-sidetools,
	.pbjhd-mail-context .pbjhd-mailbox-field,
	.pbjhd-mail-context > .pbjhd-btn {
		flex: 1 1 100%;
	}

	.pbjhd-mail-context .pbjhd-btn,
	.pbjhd-mail-context select,
	.pbjhd-compose-chips [role="button"],
	.pbjhd-compose-ticket {
		min-height: 44px;
	}

	#pbj-crm-footer > .pbjhd-bulkbar .pbjhd-btn,
	#pbj-crm-footer > .pbjhd-bulkbar select,
	#pbj-crm-footer > .pbjhd-bulkbar label {
		min-height: 44px;
		flex: 0 0 auto;
	}
}
