/*
    Login dialog, confirm dialog, buttons, notification text - the modal chrome View.Login.js and
    View.ConfirmDialog.js need. Grows in step 4 with the leads grid/forms.
*/

#GreyOut {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 200;
}

.ModalDialog {
    display: none;
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background: var(--surface);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
    z-index: 201;
    width: 90%;
    max-width: 360px;
    padding: 0;
}

.SectionHeading {
    padding: 16px 20px;
    border-bottom: 1px solid var(--border);
}

.SectionHeading h2 {
    margin: 0;
    font-size: 16px;
}

#LoginContent,
#ConfirmDialogContent {
    padding: 20px;
}

.LoginFormElement {
    margin-bottom: 14px;
    display: flex;
    flex-direction: column;
    font-size: 13px;
    color: var(--text-muted);
}

.LoginFormElementControl {
    margin-top: 4px;
}

/* Scoped to input rather than the bare .LoginFormElementControl class - the class is now
   also used on #LoginScreenStatus (a <label>, added so its markup matches Schedule's/
   ReportDesigner's), which should stay a plain status line rather than picking up an
   input-styled border/padding box. */
input.LoginFormElementControl {
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    font-size: 14px;
    font-family: inherit;
    color: var(--text);
}

input.LoginFormElementControl[type="button"] {
    background: var(--brand);
    color: var(--text-on-brand);
    border: none;
    cursor: pointer;
    font-weight: 600;
}

input.LoginFormElementControl[type="button"]:hover {
    background: var(--brand-hover);
}

label#LoginScreenStatus {
    color: var(--danger);
    font-size: 13px;
    min-height: 16px;
    display: block;
}

/* ── Confirm dialog ────────────────────────────────────────────────────────── */

#ConfirmDialogScreen #ConfirmDialogHeading {
    margin: 0 0 8px;
    font-size: 16px;
}

#ConfirmDialogScreen #ConfirmDialogText {
    color: var(--text-muted);
    font-size: 14px;
    margin-bottom: 14px;
}

#ConfirmDialogInputRow {
    display: none;
    margin-bottom: 14px;
}

#ConfirmDialogInput {
    width: 100%;
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    font-family: inherit;
    font-size: 14px;
}

#ConfirmDialogInputError {
    display: none;
    color: var(--danger);
    font-size: 12px;
    margin-top: 4px;
}

#ConfirmDialogButtons {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
}

.SalesButton {
    padding: 8px 16px;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text);
    cursor: pointer;
    font-size: 14px;
    font-family: inherit;
}

.SalesButton:hover {
    background: var(--surface-2);
}

.SalesButton.Primary {
    background: var(--brand);
    border-color: var(--brand);
    color: var(--text-on-brand);
}

.SalesButton.Primary:hover {
    background: var(--brand-hover);
}

/* ── Fly-in customer drawer (create/edit lead screens) ────────────────────── */

.SalesCustomerDrawerToggle {
    position: fixed;
    top: 50%;
    right: 20px;
    transform: translateY(-50%);
    z-index: 50;
    display: flex;
    align-items: center;
    gap: 8px;
    box-shadow: var(--shadow);
}

/* Below the nav's own breakpoint the form goes single-column and fills the width, so a toggle
   pinned to the middle of the right edge sits on top of it (it covered Delivery Address on the
   lead screens at 768px). Drop it to the bottom-right as an icon-only floating button instead,
   clear of the fields and out of the way of anything but the very bottom of the page. */
@media (max-width: 1100px) {
    .SalesCustomerDrawerToggle {
        top: auto;
        bottom: 20px;
        right: 16px;
        transform: none;
        border-radius: 50%;
        width: 48px;
        height: 48px;
        justify-content: center;
        padding: 0;
    }

    .SalesCustomerDrawerToggle span {
        display: none;
    }
}

.SalesCustomerDrawerToggle:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

.SalesCustomerDrawerToggle:disabled:hover {
    background: var(--surface);
}

.SalesCustomerDrawerScrim {
    display: none;
    position: fixed;
    top: var(--header-height);
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.3);
    z-index: 150;
}

.SalesCustomerDrawerScrim.Open {
    display: block;
}

.SalesCustomerDrawer {
    position: fixed;
    top: var(--header-height);
    right: 0;
    bottom: 0;
    /* width is set inline (View.SalesCustomerDrawer.js) - user-resizable, persisted to
       localStorage. This is only the pre-JS/fallback value. */
    width: 748px;
    max-width: 90vw;
    background: var(--page-bg);
    box-shadow: var(--shadow-lg);
    z-index: 151;
    /* No overflow/scrolling here - only .SalesCustomerDrawerContent (below) scrolls, so the resize
       handle (a sibling of it, not a child) stays fixed in the middle of the screen regardless of
       how far the customer record inside is scrolled. */
    display: flex;
    flex-direction: column;
    transform: translateX(100%);
    transition: transform 0.2s ease;
}

.SalesCustomerDrawer.Open {
    transform: translateX(0);
}

.SalesCustomerDrawer.Resizing {
    /* No transform/width transition while actively dragging - it fights the drag and lags the cursor. */
    transition: none;
    user-select: none;
}

.SalesCustomerDrawerResizeHandle {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 18px;
    cursor: ew-resize;
    background: transparent;
    /* Stops the browser's own touch-scroll/pan gesture from fighting the drag on tablets - the
       JS drives the resize entirely off touchmove instead. */
    touch-action: none;
    z-index: 2;
}

.SalesCustomerDrawerResizeHandle:hover,
.SalesCustomerDrawer.Resizing .SalesCustomerDrawerResizeHandle {
    background: rgba(25, 118, 210, 0.08);
}

/* Grab icon fixed halfway down the handle - see the handle's own doc comment (View.SalesCustomerDrawer.js) for why this needs to be visible rather than hover-only. */
.SalesCustomerDrawerResizeGrip {
    position: absolute;
    top: 50%;
    left: 1px;
    transform: translateY(-50%);
    width: 16px;
    height: 64px;
    border-radius: 8px;
    background: var(--surface);
    border: 1px solid var(--border);
    box-shadow: var(--shadow);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-muted);
    font-size: 13px;
    pointer-events: none;
}

.SalesCustomerDrawerResizeHandle:hover .SalesCustomerDrawerResizeGrip,
.SalesCustomerDrawer.Resizing .SalesCustomerDrawerResizeGrip {
    color: var(--brand);
    border-color: var(--brand);
}

.SalesCustomerDrawerContent {
    /* The one scrolling pane inside the drawer - see .SalesCustomerDrawer's own comment on why
       overflow lives here and not on the drawer itself. */
    flex: 1 1 auto;
    overflow-y: auto;
    padding: 20px 20px 20px 26px;
}

.SalesCustomerDrawerContent .SalesForm {
    grid-template-columns: 1fr;
}

.SalesCustomerDrawer.TwoColumn .SalesCustomerDrawerContent .SalesForm {
    /* Toggled by width, not a viewport media query - the drawer's own width (View.SalesCustomerDrawer.js's
       TWO_COLUMN_MIN_WIDTH), not the page's, is what determines whether two columns actually fit. */
    grid-template-columns: 1fr 1fr;
}

/* ── Recent Activity fly-in (View.SalesCustomerActivityDrawer.js) ────────────
   Same fly-in-from-the-right/resize chrome as .SalesCustomerDrawer (including reusing its
   .SalesCustomerDrawerResizeHandle/Grip rules directly - see that file's own comment on why),
   just a higher z-index so it stacks visibly on top when opened from inside that drawer - both
   share View.SalesCustomerDetail.js's renderHeader. */

.SalesActivityDrawerScrim {
    display: none;
    position: fixed;
    top: var(--header-height);
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.3);
    z-index: 160;
}

.SalesActivityDrawerScrim.Open {
    display: block;
}

.SalesCustomerActivityDrawer {
    position: fixed;
    top: var(--header-height);
    right: 0;
    bottom: 0;
    /* width is set inline (View.SalesCustomerActivityDrawer.js) - user-resizable, defaults to
       half the viewport, persisted to its own localStorage key. This is only the pre-JS value. */
    width: 50vw;
    max-width: 90vw;
    background: var(--page-bg);
    box-shadow: var(--shadow-lg);
    z-index: 161;
    /* No overflow/scrolling here - only .SalesCustomerDrawerContent scrolls, same reasoning as
       .SalesCustomerDrawer's own comment (keeps the resize handle fixed in place). */
    display: flex;
    flex-direction: column;
    transform: translateX(100%);
    transition: transform 0.2s ease;
}

.SalesCustomerActivityDrawer.Open {
    transform: translateX(0);
}

.SalesCustomerActivityDrawer.Resizing {
    transition: none;
    user-select: none;
}

/* The header here is a direct child of the drawer, not of the padded .SalesCustomerDrawerContent
   pane below it (kept outside so it stays put while the timeline scrolls) - so it needs its own
   padding rather than inheriting the content pane's, matching that pane's own left/top spacing
   (26px/20px - see .SalesCustomerDrawerContent) so the heading lines up with the timeline below it
   instead of sitting flush against the drawer's edge. */
.SalesCustomerActivityDrawer > .SalesDetailHeader {
    padding: 20px 20px 0 26px;
    margin-bottom: 12px;
}

/* ── Customer overview: account details card + 12-month activity chart, side by side ─────────
   .SalesForm is capped at 900px, which left a lot of dead space to its right on a wide screen -
   the chart fills it. Falls back to stacked below 1400px, where two columns would squeeze both. */

.SalesCustomerOverview {
    display: flex;
    flex-wrap: wrap;
    gap: 20px;
    align-items: flex-start;
    margin-bottom: 16px;
}

.SalesCustomerOverview > .SalesForm {
    flex: 1 1 480px;
    margin-bottom: 0;
}

.SalesCustomerChartPanel {
    flex: 1 1 420px;
    min-width: 0; /* flex items default to min-width:auto - without this the canvas can't shrink */
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 20px;
}

.SalesCustomerChartContainer {
    position: relative;
    height: 260px;
}

/* Pills on the left, Expand on the right. Wraps rather than squashing the Expand button off the
   edge when the panel is narrow (it shares a row with three pills). */
.SalesCustomerChartHeader {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}

.SalesCustomerChartHeader .SalesActivityFilterPills {
    margin-bottom: 0;
}

.SalesChartExpandButton {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

/* ── Expanded chart modal ────────────────────────────────────────────────────
   5% inset all round (so 90% x 90% of the viewport), for reading the chart on a tablet. Sits
   above both fly-in drawers (z-index 161) so it can be opened from the customer drawer too. */

.SalesChartModalScrim {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 200;
}

.SalesChartModal {
    position: fixed;
    top: 5%;
    left: 5%;
    right: 5%;
    bottom: 5%;
    z-index: 201;
    display: flex;
    flex-direction: column;
    gap: 12px;
    background: var(--surface);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
    padding: 20px;
}

.SalesChartModalHeader {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
}

.SalesChartModalHeader h2 {
    margin: 0;
    margin-right: auto; /* pushes the pills + Close to the right, title stays left */
}

.SalesChartModalHeader .SalesActivityFilterPills {
    margin-bottom: 0;
}

/* min-height:0 is what lets this flex child actually shrink to the dialog's height - without it
   the canvas grows unbounded and pushes the dialog past its 5% inset. */
.SalesChartModalBody {
    position: relative;
    flex: 1 1 auto;
    min-height: 0;
}

/* LEAD/JOB/INVOICE filter pills - shared by the Recent Activity fly-in's timeline and the
   customer overview chart. All active by default; toggling re-filters client-side, no re-fetch. */
.SalesActivityFilterPills {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 12px;
}

/* The chart's own pills additionally get their series colour painted on inline when active (see
   renderActivityChart's `paint`), so they act as the chart's legend - nothing needed here for
   that beyond the base pill styling below. */

.SalesActivityFilterPill {
    padding: 5px 14px;
    border-radius: 999px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text-muted);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
}

.SalesActivityFilterPill:hover {
    border-color: var(--brand);
}

.SalesActivityFilterPill.Active {
    background: var(--brand);
    border-color: var(--brand);
    color: #fff;
}

.SalesActivityTimeline {
    list-style: none;
    margin: 0;
    padding: 4px 0;
}

.SalesActivityTimelineItem {
    display: flex;
    gap: 12px;
    padding: 12px 0;
    border-bottom: 1px solid var(--border);
}

.SalesActivityTimelineItem:last-child {
    border-bottom: none;
}

.SalesActivityTimelineIcon {
    flex: 0 0 auto;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--surface-2);
    color: var(--text-muted);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
}

/* Left column: title + date/detail - grows to fill whatever the right column (type + $) doesn't need. */
.SalesActivityTimelineMain {
    min-width: 0;
    flex: 1 1 auto;
}

.SalesActivityTimelineTitle {
    font-weight: 600;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.SalesActivityTimelineTitle a {
    color: var(--brand);
    text-decoration: none;
}

.SalesActivityTimelineTitle a:hover {
    text-decoration: underline;
}

.SalesActivityTimelineMeta {
    margin-top: 2px;
    font-size: 13px;
    color: var(--text-muted);
}

/* Right column: LEAD/JOB/INVOICE label with its $ value directly beneath - kept as its own
   fixed-width column (not inline with the title) specifically so the amount is easy to scan down
   the whole list, per the user's own ask. */
.SalesActivityTimelineAside {
    flex: 0 0 auto;
    text-align: right;
}

.SalesActivityTimelineType {
    font-weight: 400;
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--text-muted);
}

.SalesActivityTimelineAmount {
    margin-top: 2px;
    font-weight: 600;
    font-size: 13px;
    color: var(--text);
}

/* ── Notification bar text ────────────────────────────────────────────────── */

#NotificationContent {
    display: none;
    font-size: 13px;
}

/* ── Generic placeholder panel content (step 3 stubs) ─────────────────────── */

.SalesView h2 {
    margin-top: 0;
    font-size: 20px;
}

.SalesView p {
    color: var(--text-muted);
}

/* ── Status chips (grid cell + filter row) ────────────────────────────────── */
/* Stub class names come from SalesLeadWebServices.AvailableStatusOptions() - one per
   SalesLeadStatus value. Lost/Sold/OnHold carry meaning (see CLAUDE.md's Mobile theming note on
   not darkening/neutralising colours that convey status); every other status is neutral. */

.SalesStatusChip {
    display: inline-block;
    padding: 3px 10px;
    border-radius: 12px;
    font-size: 12px;
    font-weight: 600;
    white-space: nowrap;
    border: 1px solid var(--border);
    color: var(--text-muted);
    background: var(--surface-2);
}

.SalesStatusChip.sales-lead-status-lost {
    background: var(--danger);
    color: #fff;
    border-color: var(--danger);
}

.SalesStatusChip.sales-lead-status-sold {
    background: #2E7D32;
    color: #fff;
    border-color: #2E7D32;
}

.SalesStatusChip.sales-lead-status-on-hold {
    background: #F9A825;
    color: #fff;
    border-color: #F9A825;
}

/* ── Tasks (View.SalesTasksList/Create/Detail) ─────────────────────────────── */

/* Task status chips reuse .SalesStatusChip's base; these stubs colour the non-neutral states.
   Pending keeps the base muted look deliberately - it's the resting state. */
.SalesStatusChip.sales-task-status-in-progress {
    background: var(--brand);
    color: #fff;
    border-color: var(--brand);
}

.SalesStatusChip.sales-task-status-waiting {
    background: #F9A825;
    color: #fff;
    border-color: #F9A825;
}

.SalesStatusChip.sales-task-status-done {
    background: #2E7D32;
    color: #fff;
    border-color: #2E7D32;
}

.SalesTaskFilterRow {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 16px;
    margin-bottom: 8px;
}

.SalesTaskFilterRow .SalesActivityFilterPills {
    margin-bottom: 0;
}

.SalesTaskDateFilter {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    color: var(--text-muted);
}

.SalesTaskDateFilter input,
.SalesTaskAssigneeFilter {
    padding: 6px 8px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    font-family: inherit;
    font-size: 13px;
    color: var(--text);
    background: var(--surface);
}

.SalesTaskGroupHeading {
    margin: 20px 0 8px;
}

.SalesTaskGroupHeading.Overdue {
    color: var(--danger);
}

.SalesTaskRepeatBadge {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 10px;
    font-size: 12px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    color: var(--text-muted);
    white-space: nowrap;
}

/* Row-level status select - smaller than a form select, and visually quiet until used. */
.SalesTaskStatusSelect {
    padding: 4px 6px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    font-family: inherit;
    font-size: 13px;
    color: var(--text);
    background: var(--surface);
}

/* "every [N] [unit]" inline control group on the create/detail forms. */
.SalesTaskRepeatDetail {
    display: flex;
    align-items: center;
    gap: 8px;
}

.SalesTaskRepeatDetail .SalesTaskRepeatFrequency {
    width: 70px;
}

.SalesChipRow {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 16px;
}

.SalesStatusChipFilter {
    padding: 6px 14px;
    border-radius: 16px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text);
    cursor: pointer;
    font-size: 13px;
    font-family: inherit;
}

.SalesStatusChipFilter:hover {
    background: var(--surface-2);
}

.SalesStatusChipFilter.Active {
    background: var(--brand);
    border-color: var(--brand);
    color: var(--text-on-brand);
    font-weight: 600;
}

/* ── Grid ──────────────────────────────────────────────────────────────────── */

.SalesGridContainer {
    /* Own scroll container, never the page (see Sales-Port-Spec.md, section 11.2/8.4) */
    overflow-x: auto;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}

.SalesLeadsTable {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
}

.SalesLeadsTable th,
.SalesLeadsTable td {
    padding: 8px 12px;
    text-align: left;
    white-space: nowrap;
    border-bottom: 1px solid var(--border);
}

.SalesLeadsTable th {
    background: var(--surface-2);
    font-weight: 600;
    color: var(--text-muted);
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.SalesLeadsTable th.Sortable {
    cursor: pointer;
    user-select: none;
}

.SalesLeadsTable th.Sortable:hover {
    color: var(--text);
}

.SalesLeadsTable th .fa {
    margin-left: 4px;
}

/* Only rows with a real navigation (View.SalesLeadsTable's onRowClick, View.SalesCustomersList's
   row click) carry .SalesRowClickable - a read-only table (e.g. the customer detail screen's ERP
   Jobs list) gets no hover affordance, since it isn't actually clickable. Light blue, not the
   neutral --surface-2 used elsewhere, so a clickable row reads as distinctly interactive. */
.SalesLeadsTable tbody tr.SalesRowClickable:hover {
    background: rgba(25, 118, 210, 0.08);
    cursor: pointer;
}

/* Tasks list groups tasks into a separate <table> per date heading (Overdue/Today/date - see
   View.SalesTasksList.js's renderTasks) rather than one continuous table, so each group's browser-
   computed auto column widths were independent of its siblings - columns drifted out of alignment
   between groups whenever their content happened to size differently (e.g. one group's Assigned To
   names are wider than another's). Fixed, shared column widths keep every group's grid lined up
   regardless of what its own rows contain. Scoped to .SalesTaskList so the other screens sharing
   .SalesLeadsTable (Leads/Customers lists) keep their own auto-sized columns. */
.SalesTaskList .SalesLeadsTable {
    table-layout: fixed;
}

.SalesTaskList .SalesLeadsTable th:nth-child(1),
.SalesTaskList .SalesLeadsTable td:nth-child(1) {
    width: 8%;
}

.SalesTaskList .SalesLeadsTable th:nth-child(2),
.SalesTaskList .SalesLeadsTable td:nth-child(2) {
    width: 22%;
}

.SalesTaskList .SalesLeadsTable th:nth-child(3),
.SalesTaskList .SalesLeadsTable td:nth-child(3) {
    width: 20%;
}

.SalesTaskList .SalesLeadsTable th:nth-child(4),
.SalesTaskList .SalesLeadsTable td:nth-child(4) {
    width: 18%;
}

.SalesTaskList .SalesLeadsTable th:nth-child(5),
.SalesTaskList .SalesLeadsTable td:nth-child(5) {
    width: 14%;
}

.SalesTaskList .SalesLeadsTable th:nth-child(6),
.SalesTaskList .SalesLeadsTable td:nth-child(6) {
    width: 18%;
}

/* table-layout:fixed (above) stops columns auto-sizing to content, so Task/Customer/Assigned To -
   the free-text columns most likely to overflow a fixed width - need their own truncation instead
   of the table just growing wider than its container. */
.SalesTaskList .SalesLeadsTable td:nth-child(2),
.SalesTaskList .SalesLeadsTable td:nth-child(3),
.SalesTaskList .SalesLeadsTable td:nth-child(4) {
    overflow: hidden;
    text-overflow: ellipsis;
}

.SalesEmptyState {
    text-align: center;
    color: var(--text-muted);
    padding: 24px !important;
}

/* ── Expandable job row (customer-level and per-item Jobs lists) ─────────── */

.SalesJobDetailRow > td,
.SalesInvoiceDetailRow > td {
    background: var(--surface-2);
    padding: 4px 16px 16px !important;
    border-top: none;
}

.SalesJobDetailRow .SalesForm {
    grid-template-columns: 1fr 1fr;
    border: none;
    background: transparent;
    padding: 0;
    max-width: none;
}

.SalesJobDescriptionRow {
    /* Spans both of the form's own columns, not the 2-cell label/value split every other row
       uses - a job description running to multiple lines/numbered points reads poorly squeezed
       into a half-width column. */
    grid-column: 1 / -1;
}

.SalesJobDescriptionValue {
    /* Preserves the description's own line breaks/spacing (white-space: normal, the default,
       collapses them) while still wrapping long lines and never exceeding the row's own width -
       max-width: 100% + overflow-wrap stop a single long unbroken line from pushing the table wider
       than its container. */
    white-space: pre-wrap;
    overflow-wrap: break-word;
    max-width: 100%;
}

.SalesJobMemoList {
    list-style: none;
    margin: 0;
    padding: 0;
}

.SalesJobMemoList li {
    padding: 6px 10px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    margin-bottom: 6px;
    font-size: 13px;
}

.SalesJobTransactions {
    margin-top: 12px;
}

.SalesTransactionLinesTotal {
    display: flex;
    justify-content: flex-end;
    gap: 6px;
    padding: 10px 16px;
    border-top: 2px solid var(--border);
    font-size: 14px;
}

/* Contacts list on the /Customer/ detail view (above the Customer Item section) - static, not
   expandable like .SalesCustomerItemsList's rows, so no caret/click affordance. */
.SalesContactsList {
    list-style: none;
    margin: 0;
    padding: 4px 0;
}

.SalesContactsList > li {
    padding: 8px 16px;
    border-bottom: 1px solid var(--border);
}

.SalesContactsList > li:last-child {
    border-bottom: none;
}

.SalesContactName {
    font-weight: 600;
    color: var(--text);
}

.SalesContactPosition {
    color: var(--text-muted);
    margin-left: 6px;
}

.SalesContactMeta {
    margin-top: 2px;
    font-size: 13px;
    color: var(--text-muted);
}

.SalesCustomerItemsList {
    list-style: none;
    margin: 0;
    padding: 4px 0;
}

.SalesCustomerItemsList > li {
    border-bottom: 1px solid var(--border);
}

.SalesCustomerItemsList > li:last-child {
    border-bottom: none;
}

/* Clickable row - expands/collapses .SalesCustomerItemDetail below it (leads/jobs referencing
   this specific item, not just the customer as a whole). */
.SalesCustomerItemSummary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px 16px;
    cursor: pointer;
}

.SalesCustomerItemSummary:hover {
    background: var(--surface-2);
}

.SalesCustomerItemCaret {
    color: var(--text-muted);
    transition: transform 0.15s ease;
}

.SalesCustomerItemRow.Expanded .SalesCustomerItemCaret {
    transform: rotate(180deg);
}

.SalesCustomerItemDetail {
    padding: 4px 16px 16px 28px;
    background: var(--surface-2);
    border-top: 1px solid var(--border);
}

.SalesCustomerItemDetail h4 {
    font-size: 13px;
    color: var(--text-muted);
    margin: 12px 0 6px;
}

.SalesCustomerItemDetail h4:first-child {
    margin-top: 4px;
}

.SalesRowActions {
    white-space: nowrap;
}

.SalesRowActions .SalesButton {
    padding: 4px 10px;
    margin-right: 4px;
}

/* ── Pager ─────────────────────────────────────────────────────────────────── */

.SalesPager {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    margin-top: 16px;
}

.SalesPagerLabel {
    font-size: 13px;
    color: var(--text-muted);
    margin: 0 8px;
}

/* ── Detail header (lead detail screen) ───────────────────────────────────── */

.SalesDetailHeader {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 20px;
}

.SalesDetailHeader h2 {
    margin: 0;
}

.SalesDetailSubheading {
    color: var(--text-muted);
    font-size: 14px;
    margin-top: -8px;
    margin-bottom: 16px;
}

/* ── Forms (lead detail/create, add-activity) ─────────────────────────────── */
/* Two columns >=1100px, one column below it - see Sales-Port-Spec.md, section 11.2 (step 4.6). */

.SalesForm {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 4px 24px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 20px;
    max-width: 900px;
}

/* Grid items default to min-width:auto, so a <select> with one very long option (a tenant's own
   long division/location/status name, no fixed length) can force its whole 1fr column wider than
   its fair share, squeezing the sibling column - "grid blowout". min-width:0 lets the column
   shrink to its track size and the <select> itself truncate/scroll instead. */
.SalesForm > .SalesFormRow {
    min-width: 0;
}

@media (max-width: 1100px) {
    .SalesForm {
        grid-template-columns: 1fr;
    }
}

.SalesFormRow {
    display: flex;
    flex-direction: column;
    margin-bottom: 14px;
    font-size: 13px;
    color: var(--text-muted);
}

.SalesFormRow label {
    margin-bottom: 4px;
}

.SalesFormRow input[type="text"],
.SalesFormRow input[type="email"],
.SalesFormRow input[type="number"],
.SalesFormRow input[type="date"],
.SalesFormRow input[type="time"],
.SalesFormRow select,
.SalesFormRow textarea {
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    font-size: 14px;
    font-family: inherit;
    color: var(--text);
    background: var(--surface);
}

.SalesFormRow input:focus,
.SalesFormRow select:focus,
.SalesFormRow textarea:focus {
    outline: none;
    border-color: var(--brand);
}

.SalesFormRow input[type="checkbox"] {
    width: 18px;
    height: 18px;
    align-self: flex-start;
}

.SalesCharCounter {
    font-size: 11px;
    text-align: right;
    margin-top: 4px;
}

.SalesFormButtons {
    grid-column: 1 / -1;
    display: flex;
    gap: 8px;
    margin-top: 8px;
}

.SalesFormButtons a.SalesButton {
    text-decoration: none;
    display: inline-flex;
    align-items: center;
}

/* ── Collapsible "Show More" fields (create lead) ─────────────────────────── */

.SalesShowMoreToggle {
    grid-column: 1 / -1;
    justify-self: start;
    margin-bottom: 6px;
}

/* display:contents (not none/block) so its .SalesFormRow children keep participating directly in
   .SalesForm's own grid once expanded, instead of being laid out inside a nested one-column box. */
.SalesFormMoreFields {
    display: none;
}

.SalesFormMoreFields.Expanded {
    display: contents;
}

/* Customer Name/Contact Name/Phone/Email on the create-lead form (View.SalesLeadCreate.js) -
   same display:none/display:contents toggle as .SalesFormMoreFields above, but driven by the
   customer picker's own state (an ERP pick, or "enter customer details manually") rather than
   the Show More button, so these fields surface right under Customer as soon as there's a
   customer context for them, instead of needing a separate click. */
.SalesCustomerDetailsFields {
    display: none;
}

.SalesCustomerDetailsFields.Expanded {
    display: contents;
}

.SalesFormRow.SpanTwo {
    grid-column: 1 / -1;
}

/* Delivery Address's "copy from customer" buttons (create/detail lead screens) - sits directly
   under the textarea, same row. Buttons hide individually per-address when that ERP address is
   blank (see populateContactContext in both views), so this stays a plain flex row rather than a
   fixed two-button grid. */
.SalesAddressCopyButtons {
    display: flex;
    gap: 8px;
    margin-top: 6px;
}

.SalesAddressCopyButtons .SalesButton {
    padding: 6px 12px;
    font-size: 12px;
}

/* Work Title on the create-lead form - a taller single-line input, same visual weight as the
   textarea fields around it (Work Required is rows:6; a plain <input> has no "rows" attribute,
   so the height is set directly). ~50% taller than the ~35px a default input renders at. */
.SalesFormRow input.SalesTallInput {
    height: 52px;
}

/* ── Activity trail ────────────────────────────────────────────────────────── */

.SalesActivityTable {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
    margin-top: 12px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}

.SalesActivityTable th,
.SalesActivityTable td {
    padding: 8px 12px;
    text-align: left;
    border-bottom: 1px solid var(--border);
}

.SalesActivityTable th {
    background: var(--surface-2);
    font-weight: 600;
    color: var(--text-muted);
    font-size: 12px;
    text-transform: uppercase;
}

.SalesYesNo {
    display: inline-block;
    padding: 2px 10px;
    border-radius: 12px;
    font-size: 12px;
    font-weight: 600;
}

.SalesYesNo.Yes {
    background: #2E7D32;
    color: #fff;
}

.SalesYesNo.No {
    background: #F9A825;
    color: #fff;
}

/* ── Customer picker (create lead) ────────────────────────────────────────── */

.SalesCustomerPicker {
    position: relative;
}

.SalesCustomerPicker input[type="text"] {
    width: 100%;
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    font-size: 14px;
    font-family: inherit;
    color: var(--text);
    background: var(--surface);
}

.SalesCustomerPickerResults {
    position: absolute;
    z-index: 10;
    top: 100%;
    left: 0;
    right: 0;
    max-height: 220px;
    overflow-y: auto;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
    margin-top: 2px;
}

.SalesCustomerPickerResultRow {
    padding: 8px 10px;
    font-size: 13px;
    cursor: pointer;
    border-bottom: 1px solid var(--border);
}

.SalesCustomerPickerResultRow:last-child {
    border-bottom: none;
}

.SalesCustomerPickerResultRow:hover {
    background: var(--surface-2);
}

.SalesCustomerPickerLocked {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface-2);
    font-size: 14px;
}

.SalesCustomerPickerManualLink {
    display: inline-block;
    margin-top: 6px;
    font-size: 12px;
    color: var(--brand);
}

/* ── Product picker (quote lines) - reuses .SalesCustomerPickerResults/ResultRow above ──────── */

.SalesProductPicker {
    position: relative;
    max-width: 480px;
    margin-bottom: 12px;
}

.SalesProductPicker input[type="text"] {
    width: 100%;
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    font-size: 14px;
    font-family: inherit;
    color: var(--text);
    background: var(--surface);
}

/* ── Quote lines table + totals ───────────────────────────────────────────── */

.SalesQuoteLinesSection {
    margin-top: 24px;
}

.SalesQuoteLinesTable input {
    width: 100%;
    padding: 6px 8px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    font-size: 13px;
    font-family: inherit;
    color: var(--text);
    background: var(--surface);
}

.SalesQuoteLineDescription {
    min-width: 160px;
}

/* Drag-to-reorder - see View.SalesQuoteEdit.js makeRowDraggable. */
.SalesQuoteLinesTable td.SalesQuoteLineDragCell {
    width: 24px;
    padding-right: 0;
    text-align: center;
}

.SalesQuoteLineDragHandle {
    display: inline-block;
    padding: 4px;
    color: var(--text-muted, var(--text));
    opacity: 0.6;
    cursor: grab;
    border-radius: var(--radius);
}

.SalesQuoteLineDragHandle:hover,
.SalesQuoteLineDragHandle:focus {
    opacity: 1;
}

.SalesQuoteLineRow.Dragging {
    opacity: 0.4;
}

.SalesQuoteLineRow.DropBefore td {
    box-shadow: inset 0 2px 0 var(--brand);
}

.SalesQuoteLineRow.DropAfter td {
    box-shadow: inset 0 -2px 0 var(--brand);
}

/* No .SalesQuoteLineGst - GST is one rate for the whole quote now, applied at the bottom, so the
   per-line column it styled is gone. */
.SalesQuoteLineQty,
.SalesQuoteLineDiscount {
    width: 60px;
}

.SalesQuoteLineUnit {
    width: 70px;
}

.SalesQuoteLineUnitPrice,
.SalesQuoteLineCost {
    width: 90px;
}

.SalesQuoteLineMargin {
    width: 70px;
}

/* A line quoted at cost. Marked for as long as the zero stands, confirmed or not - see
   View.SalesQuoteEdit.js's markZeroMargin. */
.SalesQuoteLinesTable input.SalesQuoteLineMargin.ZeroMargin {
    border-color: var(--danger);
    color: var(--danger);
}

/* No cost, so the line has no margin to work out - see markEmptyCost. */
.SalesQuoteLinesTable input.SalesQuoteLineCost.EmptyCost {
    border-color: var(--danger);
}

/* Margin % and Disc % headings set one figure for every line in a single tap - see
   View.SalesQuoteEdit.js's promptForAllLines. Drawn as a small button so it reads as something to
   press; a plain heading gives no hint that anything happens when you touch it. */
.SalesQuoteLinesTable th.SalesQuoteBulkEditHeading {
    padding-top: 4px;
    padding-bottom: 4px;
}

.SalesQuoteBulkEditButton {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 3px 8px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    /* th sets its own size/weight/case - inherit rather than restating them here. */
    font: inherit;
    text-transform: inherit;
    letter-spacing: inherit;
    color: var(--text);
    cursor: pointer;
    white-space: nowrap;
    -webkit-user-select: none;
    user-select: none;
}

.SalesQuoteBulkEditButton .fa {
    font-size: 11px;
    opacity: 0.65;
}

.SalesQuoteBulkEditButton:hover,
.SalesQuoteBulkEditButton:focus {
    border-color: var(--brand);
    color: var(--brand);
}

.SalesQuoteBulkEditButton:hover .fa,
.SalesQuoteBulkEditButton:focus .fa {
    opacity: 1;
}

.SalesQuoteLineTotal {
    font-weight: 600;
    white-space: nowrap;
}

/* Narrow window: ten columns squeeze the money fields down to a few unreadable pixels, which is
   what the quote lines looked like in a side-by-side preview pane. Each line becomes two visual
   rows instead - the product across the top, every other field wrapping beneath it and aligned
   right. Still one <tr> with the same cells, so drag-to-reorder, the inputs and every handler are
   untouched; only the layout changes. */
@media (max-width: 1100px) {
    .SalesQuoteLinesTable,
    .SalesQuoteLinesTable thead,
    .SalesQuoteLinesTable thead tr,
    .SalesQuoteLinesTable tbody {
        display: block;
    }

    /* The column headings no longer sit above anything once the cells stack - but the two
       bulk-edit buttons still have to be reachable, so the header row keeps just those and reads
       as a small toolbar above the lines. */
    .SalesQuoteLinesTable thead th:not(.SalesQuoteBulkEditHeading) {
        display: none;
    }

    .SalesQuoteLinesTable thead tr {
        display: flex;
        justify-content: flex-end;
        gap: 8px;
        padding: 4px 6px;
    }

    .SalesQuoteLinesTable tr.SalesQuoteLineRow {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        justify-content: flex-end;
        /* Tight enough that Qty through Total stay on one line at ~780px of content - the width a
           preview pane leaves once the nav rail is in. Any looser and the Total wraps alone onto a
           third row, which is the thing this layout exists to avoid. */
        gap: 6px 8px;
        padding: 8px 6px;
        border-bottom: 1px solid var(--border);
    }

    .SalesQuoteLinesTable tr.SalesQuoteLineRow td {
        display: inline-flex;
        align-items: center;
        gap: 4px;
        width: auto;
        padding: 0;
        border: none;
    }

    /* Top row: the drag handle and the product, filling the width so everything else wraps under it. */
    .SalesQuoteLinesTable tr.SalesQuoteLineRow td.SalesQuoteLineDragCell {
        order: 1;
        width: 24px;
    }

    /* Wide enough that the first figure cannot also fit on this line, so the figures always wrap
       together onto the second - two rows per line, never three. The 150px covers the Remove button
       and the gaps either side of it; the product itself flexes into whatever is left. */
    .SalesQuoteLinesTable tr.SalesQuoteLineRow td:nth-child(2) {
        order: 2;
        flex: 1 1 calc(100% - 150px);
    }

    .SalesQuoteLinesTable tr.SalesQuoteLineRow td:nth-child(2) input {
        width: 100%;
    }

    /* Remove rides on the product's row rather than trailing the figures onto a third. */
    .SalesQuoteLinesTable tr.SalesQuoteLineRow td:last-child {
        order: 3;
        margin-left: auto;
    }

    /* Bottom row: the figures, in source order, pushed right by the row's own justify-content. */
    .SalesQuoteLinesTable tr.SalesQuoteLineRow td:nth-child(n+3):not(:last-child) {
        order: 4;
    }

    /* Each field says what it is, since there is no heading above it any more. */
    .SalesQuoteLinesTable tr.SalesQuoteLineRow td:nth-child(n+3):not(:last-child)[data-label]::before {
        content: attr(data-label);
        font-size: 10px;
        color: var(--text-muted);
        white-space: nowrap;
    }

    /* Sized so every figure reads in full - the clipping this layout exists to fix - while the six
       fields plus the Total still share one line. */
    .SalesQuoteLinesTable .SalesQuoteLineQty,
    .SalesQuoteLinesTable .SalesQuoteLineUnit {
        width: 46px;
    }

    .SalesQuoteLinesTable .SalesQuoteLineDiscount {
        width: 52px;
    }

    /* Wider than the other percentages: a margin worked back from a price runs to two decimals
       (155.38), and clipping that is the fault this whole layout exists to fix. */
    .SalesQuoteLinesTable .SalesQuoteLineMargin {
        width: 64px;
    }

    .SalesQuoteLinesTable .SalesQuoteLineCost,
    .SalesQuoteLinesTable .SalesQuoteLineUnitPrice {
        width: 70px;
    }

    .SalesQuoteLinesTable td.SalesQuoteLineTotal {
        font-size: 15px;
    }
}

.SalesQuoteTotalsRow {
    display: flex;
    justify-content: flex-end;
    margin-top: 12px;
}

.SalesQuoteTotals {
    text-align: right;
    font-size: 14px;
    color: var(--text);
}

.SalesQuoteTotals > div {
    margin-bottom: 4px;
}

.SalesQuoteTotalsGrandTotal {
    font-size: 18px;
    font-weight: 700;
}

.SalesQuoteErpTotal {
    color: var(--text-muted, var(--text));
    font-size: 13px;
}

/* Sits under the grand total to say these figures are Tradie's own arithmetic until the accounting
   system prices the quote on submission. Quieter than the totals it qualifies, and given room above
   so it reads as a caption rather than as another figure. */
.SalesQuoteTotalsNote {
    color: var(--text-muted, var(--text));
    font-size: 12px;
    font-style: italic;
    margin-top: 8px;
    max-width: 320px;
}

/* A value the form shows but nobody types (the quote's Quoted By / Entered By). Set at an input's
   height and in the body colour, so it lines up with the fields beside it without looking like one. */
.SalesFormStatic {
    color: var(--text);
    font-size: 14px;
    min-height: 34px;
    display: flex;
    align-items: center;
}

/* One line under a field saying where its contents go. */
.SalesFormHint {
    font-size: 12px;
    margin-top: 4px;
}

/* Fills the empty half of a grid row so the next pair starts on a row of its own. Nothing to fill
   once the form collapses to one column. */
.SalesFormRow.SalesFormSpacer {
    margin: 0;
}

@media (max-width: 1100px) {
    .SalesFormRow.SalesFormSpacer {
        display: none;
    }
}

/* Awaiting approval - deliberately not the amber of a draft. A draft is somebody's own work in
   progress; this one is blocked on another person, which is a different thing to see at a glance.
   See Sales-UnifiedQuotes-Design.md section 6. */
.SalesStatusChip.SalesQuotePendingApproval {
    background: #6A1B9A;
    color: #fff;
    border-color: #6A1B9A;
}

/* When a quote was submitted, and whether the last attempt failed - secondary to the status chip
   it sits under, on the editor's header and in the Quotes list's status column. */
.SalesQuoteSyncStatus {
    color: var(--text-muted, var(--text));
    font-size: 12px;
    margin-top: 4px;
}

/* ── Dashboard filter panel ───────────────────────────────────────────────── */
/* Reuses .SalesForm's grid/input styling (see the Forms section above) - just a narrower row height
   since every field here is a dropdown/date/radio group, never a textarea. */

.SalesFilterPanel {
    margin-bottom: 20px;
}

.SalesFilterPanel .SalesFormRow {
    margin-bottom: 10px;
}

.SalesRadioGroup {
    display: flex;
    align-items: center;
    gap: 16px;
    padding-top: 6px;
}

.SalesRadioGroup input[type="radio"] {
    margin-right: 4px;
}

.SalesRadioGroup label {
    font-size: 14px;
    color: var(--text);
    margin: 0;
}

/* ── KPI tiles ─────────────────────────────────────────────────────────────── */

.SalesKpiRow {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    margin-bottom: 20px;
}

.SalesKpiTile {
    flex: 1 1 140px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 16px;
    text-align: center;
}

.SalesKpiValue {
    font-size: 24px;
    font-weight: 700;
    color: var(--brand-ink);
}

.SalesKpiLabel {
    font-size: 12px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.03em;
    margin-top: 4px;
}

/* ── Dashboard filter row + upcoming-tasks widget ─────────────────────────────
   The filter column and the widget share one flex row, 2:1 (2/3 filters, 1/3 tasks) via matching
   flex-basis:0 + flex-grow ratios - align-items' default (stretch) is what makes the widget match
   the filter panel's height with no explicit height needed. Stacks below 900px, same breakpoint
   as the chart row, since there's no room for both side by side. */

.SalesDashboardTopRow {
    display: flex;
    gap: 16px;
    margin-bottom: 20px;
}

/* A flex column, not a plain block: it holds the filter panel AND the "Showing ... leads for ..."
   summary beneath it, and the panel used to be height:100% of this column - which left the
   summary no room at all and dropped it on top of the panel's bottom border. Stacking them here
   lets the panel take the space the summary doesn't. */
.SalesDashboardFilterColumn {
    flex: 2 1 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.SalesDashboardFilterColumn .SalesFilterPanel {
    margin-bottom: 0;
    /* Fills whatever the summary line below leaves, so the column still matches the height of the
       Upcoming Tasks card beside it. */
    flex: 1 1 auto;
    /* Overrides .SalesForm's 900px cap - that cap exists for readable text-field widths on a
       lead/customer detail form, not for a proportionally-sized dashboard column. */
    max-width: none;
}

/* Borrows .SalesDetailSubheading for its colour and size only - that class also carries a
   negative top margin, which exists to tuck a subheading under a detail screen's header and
   here just pulled this line up into the panel above it. The column's own gap does the spacing. */
#SalesDashboardDescription {
    margin-top: 0;
    margin-bottom: 0;
}

/* Bare flex item, no padding/border of its own - some browsers skew flex-grow's 2:1 distribution
   when the item itself carries padding/border, even with box-sizing:border-box and min-width:0.
   The card's visual chrome lives on .SalesUpcomingTasksCard instead, same "padding lives on a
   child, not the flex item" shape as .SalesDashboardFilterColumn/.SalesFilterPanel above. */
.SalesUpcomingTasksWidget {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.SalesUpcomingTasksCard {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 6px 16px 12px;
}

.SalesUpcomingTasksHeader {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 8px;
}

/* Extra-specific selector (not just ".SalesUpcomingTasksHeader h3") - needed to beat ".SalesView
   h3"'s own margin/font-size reset further down this file, which has equal specificity and would
   otherwise win on source order alone, putting its 24px top margin back above this heading. */
.SalesUpcomingTasksWidget .SalesUpcomingTasksHeader h3 {
    margin: 0;
    font-size: 14px;
}

.SalesUpcomingTasksHeader a {
    font-size: 12px;
}

.SalesUpcomingTasksList {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    gap: 2px;
    overflow-y: auto;
}

.SalesUpcomingTaskRow {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 4px;
    border-radius: var(--radius);
    cursor: pointer;
}

.SalesUpcomingTaskRow:hover {
    background: var(--surface-2);
}

.SalesUpcomingTaskDue {
    flex: 0 0 auto;
    font-size: 12px;
    color: var(--text-muted);
}

.SalesUpcomingTaskDue.Overdue {
    color: var(--danger);
    font-weight: 600;
}

.SalesUpcomingTaskTitle {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.SalesUpcomingTaskCustomer {
    flex: 0 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 12px;
    color: var(--text-muted);
}

.SalesUpcomingTaskAssignee {
    flex: 0 0 auto;
    max-width: 110px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 12px;
    color: var(--text-muted);
}

.SalesUpcomingTaskStatus {
    flex: 0 0 auto;
}

@media (max-width: 900px) {
    .SalesDashboardTopRow {
        flex-direction: column;
    }

    .SalesUpcomingTasksWidget {
        flex: 1 1 auto;
        width: 100%;
    }
}

/* ── Dashboard charts ──────────────────────────────────────────────────────── */

.SalesChartRow {
    display: flex;
    gap: 16px;
    margin-bottom: 20px;
}

.SalesChartCard {
    flex: 1 1 0;
    min-width: 0;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 16px;
}

.SalesChartCard h3 {
    margin: 0 0 12px;
    font-size: 14px;
}

.SalesChartCard > div:not(.SalesChartEmptyState) {
    position: relative;
    height: 260px;
}

.SalesChartEmptyState {
    text-align: center;
    color: var(--text-muted);
    padding: 40px 0;
}

@media (max-width: 1100px) {
    .SalesChartRow {
        flex-direction: column;
    }
}

/* ── Customers list + detail ──────────────────────────────────────────────── */
/* The Customers screens reuse .SalesLeadsTable/.SalesGridContainer/.SalesForm wholesale - only
   the pieces below have no existing equivalent. See View.SalesCustomersList.js/View.SalesCustomerDetail.js. */

.SalesCustomersSearchRow {
    margin-bottom: 12px;
}

/* Positioning context for the clear button, and where the field's width now lives - the input
   itself is width:100% of this so the button can sit inside its right edge. */
.SalesSearchWrap {
    position: relative;
    display: block;
    width: 100%;
    max-width: 360px;
}

.SalesSearchWrap input {
    width: 100%;
    /* Right padding keeps typed text from running under the clear button. */
    padding: 8px 34px 8px 10px;
    border: 1px solid var(--border);
    border-radius: 4px;
    background: var(--surface);
    color: var(--text);
    font-family: inherit;
    font-size: 14px;
}

.SalesSearchWrap input:focus {
    outline: none;
    border-color: var(--brand);
}

/* Inset by 1px so it never overlaps the input's own border. */
.SalesSearchClear {
    position: absolute;
    top: 1px;
    right: 1px;
    bottom: 1px;
    width: 30px;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--text-muted);
    font-size: 14px;
    line-height: 1;
    cursor: pointer;
}

.SalesSearchClear:hover {
    color: var(--text);
}

/* Read-only counterpart to a .SalesFormRow's input - same box metrics as one, minus the border,
   so a details card lines up with the edit forms elsewhere in the app. */
.SalesDetailValue {
    padding: 8px 0;
    font-size: 14px;
    color: var(--text);
    word-break: break-word;
}

/* Section headings within a detail screen (Current Leads / Historic Leads / Jobs). */
.SalesView h3 {
    margin: 24px 0 8px;
    font-size: 16px;
}

/* renderPagedSection's search box (Current Leads / Historic Leads / Jobs on the customer detail
   screen) - .SalesSearchWrap already gives the input its box styling; this just adds the same
   bottom margin .SalesCustomersSearchRow uses ahead of the grid below it. */
.SalesPagedSearchRow {
    margin-bottom: 10px;
}

.SalesShowMoreButton {
    margin-top: 10px;
}

/* Lead detail's Status field - the dropdown plus its explicit "Change Status" button on one
   line (View.SalesLeadDetail.js renderForm). The select takes whatever width the button leaves. */
.SalesStatusChangeRow {
    display: flex;
    gap: 8px;
    align-items: stretch;
}

.SalesStatusChangeRow select {
    flex: 1;
    min-width: 0;
}

.SalesStatusChangeRow .SalesButton {
    white-space: nowrap;
}

/* Quote Description's "add boiler-plate" picker - a dropdown of saved templates plus an Add
   button, sitting directly under the textarea in the same row (same shape as
   .SalesAddressCopyButtons above). Hidden entirely on a tenant with no templates defined. */
.SalesQuoteTemplatePicker {
    display: flex;
    gap: 8px;
    margin-top: 6px;
    align-items: center;
}

.SalesQuoteTemplatePicker select {
    flex: 0 1 260px;
    min-width: 0;
}

.SalesQuoteTemplatePicker .SalesButton {
    padding: 6px 12px;
    font-size: 12px;
}
