/* Every rule below reads a var(--po-*) custom property with the original
 * Classic value as its fallback, the active theme's variable set and
 * theme-specific extras are appended at the BOTTOM of this file (see
 * includes/app-themes.php and the note there): the extras must come
 * after these rules to win the cascade, and this file's <style> tag is
 * (historically) never closed here, so the append happens inside it. */
/* Scoped box-sizing normalization (Mike 2026-07-28). Most themes apply a
 * global border-box reset; some (creditweb among them) do not, and there
 * the app's min-heights/widths measured the CONTENT box, inflating
 * buttons (~68px) and drifting multi-column forms like Time Off out of
 * alignment. This pins border-box for the PLUGIN'S OWN elements only,
 * keyed off the app's class prefixes; on themes that already reset,
 * it is a no-op, so the Pro sites render exactly as before. */
.job-form, .job-form *,
.paintops-appbar, .paintops-appbar *,
[class^="paintops-"], [class*=" paintops-"],
[class^="po-"], [class*=" po-"],
[class^="pab-"], [class*=" pab-"],
[class^="pbn-"], [class*=" pbn-"],
[class^="cs-"], [class*=" cs-"],
[class^="veh-"], [class*=" veh-"],
[class^="rl-"], [class*=" rl-"],
.addr-row, .addr-row * {
  box-sizing: border-box;
}

/* App-wide type (2026-08-31 visual refresh). One stack through --po-font
 * so a theme (or a future bundled webfont in assets/vendor/fonts) can
 * swap the face in one place. The default is the modern system stack:
 * zero payload, no remote font host (the wp.org review already made us
 * remove every remote call once, not walking that back), crisp on every
 * device. Same scoping trick as the border-box reset above, the app's
 * own class prefixes, so the host theme's pages are untouched; form
 * controls need the explicit inherit, they never inherit font by default. */
.job-form, .paintops-appbar,
[class^="paintops-"], [class*=" paintops-"],
[class^="po-"], [class*=" po-"],
[class^="pab-"], [class*=" pab-"],
[class^="pbn-"], [class*=" pbn-"],
[class^="cs-"], [class*=" cs-"],
[class^="veh-"], [class*=" veh-"],
[class^="rl-"], [class*=" rl-"],
.addr-row {
  font-family: var(--po-font, -apple-system, "Segoe UI", system-ui, Roboto, "Helvetica Neue", Arial, sans-serif);
}
.job-form button, .job-form input, .job-form select, .job-form textarea,
[class^="paintops-"] button, [class*=" paintops-"] button,
[class^="paintops-"] input, [class*=" paintops-"] input,
[class^="paintops-"] select, [class*=" paintops-"] select,
[class^="paintops-"] textarea, [class*=" paintops-"] textarea,
[class^="cs-"] button, [class*=" cs-"] button,
[class^="cs-"] input, [class*=" cs-"] input,
[class^="cs-"] select, [class*=" cs-"] select,
[class^="cs-"] textarea, [class*=" cs-"] textarea {
  font-family: inherit;
}

/* Form-submission notice banners, a full-width mint-green row on success and
 * a red row on error, shown after a POST reloads the page. Replaces the old
 * plain colored-text notices (was color:green / color:#b00) app-wide, so a
 * "Financials saved." / "Invoice created." confirmation is clearly visible
 * even when the reload takes a beat. */
.paintops-notice {
  padding: 12px 16px;
  border-radius: var(--po-radius, 8px);
  margin: 0 0 14px;
  font-size: 14px;
  font-weight: 600;
  border: 1px solid transparent;
  line-height: 1.4;
  animation: paintops-notice-in .18s ease-out;
}
.paintops-notice a { color: inherit; text-decoration: underline; }
.paintops-notice.is-success { background: #e6f6ec; color: #1a7a43; border-color: #b9e2c9; }
.paintops-notice.is-error   { background: #fdecea; color: #b3261e; border-color: #f3c2bd; }
@keyframes paintops-notice-in { from { opacity: 0; transform: translateY(-5px); } to { opacity: 1; transform: none; } }

/* Standardized screen title (2026-07-19): every app screen renders its
 * name through paintops_screen_title() (manage-jobs.php), an h2 with
 * this class, so titles are identical in size, weight, color, and
 * spacing everywhere (they used to vary screen to screen or be missing
 * entirely). Deliberately h2 (Mike's call). */
.po-screen-title {
  font-size: 24px;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--po-heading, #2f5aae);
  margin: 6px 0 16px;
  line-height: 1.25;
}
@media (max-width: 782px) {
  .po-screen-title { font-size: 21px; }
}

/* Address Row Styles */
.addr-row {
  display: grid;
  grid-template-columns: 2fr 1fr 0.5fr 0.8fr; /* Address | City | State | Zip */
  gap: 1rem;
  align-items: end; /* line up inputs */
}

.addr-row label {
  display: block;
  font-weight: 600;
  margin-bottom: .25rem;
}

.addr-row input {
  width: 100%;
  padding: .5rem;
  border: 1px solid var(--po-input-border, #ccc);
  border-radius: var(--po-radius-xs, 4px);
}

/* Job Form Styles */
.job-form {
  max-width: 100%;   /* Optional: limit width for readability */
  margin: 2rem auto;
  /* Reserves room at the bottom so the fixed Save bar (.paintops-sticky-save
     below) never overlaps the last field or the "Add Color"/"Remove"
     buttons underneath it. */
  padding-bottom: 90px;
}

/* Job Form Section Headings
 *
 * Used to break the New Job/Quote form (Job Info, Customer Info,
 * Scheduling, etc.) into visibly distinct sections instead of one long
 * scroll of labels/inputs that all look the same.
 */
.job-form-section {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 36px 0 18px;
  padding: 10px 14px;
  background: var(--po-accent-soft, rgba(70,130,180,0.08));
  border-left: 4px solid var(--po-accent, #4682B4);
  border-radius: var(--po-radius-xs, 4px);
  color: var(--po-heading, #2f5aae);
  font-size: 105%;
  font-weight: 700;
  letter-spacing: 0.3px;
  text-transform: uppercase;
}

.job-form-section:first-of-type {
  margin-top: 0;
}

/* Job Financials (?jobFinancials=X), replaces the plain bordered box,
 * pipe-separated summary line, and default WP-admin "widefat striped"
 * tables with something that matches the rest of the app: a card, a
 * row of at-a-glance stat tiles (profit colored green/red), and
 * branded table headers. */
.cs-financial-box {
  border: 1px solid var(--po-card-border, #ddd);
  border-radius: var(--po-radius, 8px);
  padding: 18px 20px 22px;
  margin: 20px 0;
  background: var(--po-card-bg, #fff);
  box-shadow: var(--po-card-shadow, 0 1px 2px rgba(0,0,0,.04));
}

.cs-financial-box > h3:first-child {
  margin-top: 0;
  color: var(--po-heading, #2f5aae);
  font-size: 130%;
}

/* Add Expense form (paintops_render_worker_add_receipt_box): the
 * Vendor/Category/Amount/Date fields sit in two compact columns on
 * desktop instead of one long stack (the old layout was a lot of
 * scrolling for a quick receipt entry) and the inputs fill their
 * column instead of rendering at tiny default widths. Back to a
 * single column on phones, where the stack is the right shape. */
.po-expense-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: 20px;
  max-width: 640px;
  align-items: start;
}
.po-expense-grid p { margin: 6px 0 10px; }
.po-expense-grid select,
.po-expense-grid input[type="text"],
.po-expense-grid input[type="date"] { width: 100%; max-width: 100%; }
@media (max-width: 782px) {
  .po-expense-grid { grid-template-columns: 1fr; }
}

.cs-fin-summary-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
  gap: 10px;
  margin: 14px 0 22px;
}

.cs-fin-stat {
  border: 1px solid var(--po-tile-border, #e6e6e6);
  border-radius: var(--po-radius-sm, 6px);
  padding: 10px 12px;
  background: var(--po-tile-bg, #fafbfc);
  text-align: center;
}

.cs-fin-stat span {
  display: block;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .03em;
  color: var(--po-text-soft, #808792);
  margin-bottom: 4px;
}

.cs-fin-stat strong {
  display: block;
  font-size: 19px;
  color: var(--po-text, #333);
}

.cs-fin-stat.cs-fin-primary {
  background: var(--po-accent-soft, rgba(70,130,180,0.08));
  border-color: var(--po-accent-line, rgba(70,130,180,0.3));
}

.cs-fin-stat.cs-fin-positive strong { color: var(--po-positive, #1e7e34); }
.cs-fin-stat.cs-fin-negative strong { color: var(--po-negative, #c0392b); }

.cs-fin-table {
  width: 100%;
  border-collapse: collapse;
  margin: 10px 0 6px;
}

.cs-fin-table th {
  background: var(--po-accent-soft, rgba(70,130,180,0.08));
  color: var(--po-heading, #2f5aae);
  text-align: left;
  padding: 9px 10px;
  font-size: 13px;
  font-weight: 600;
  border-bottom: 2px solid var(--po-accent-line, rgba(70,130,180,0.25));
}

.cs-fin-table td {
  padding: 8px 10px;
  border-bottom: 1px solid var(--po-line, #eee);
  vertical-align: middle;
}

.cs-fin-table tbody tr:hover td {
  background: var(--po-hover, #f8fafc);
}

/* Data tables (Quote Performance, Profit by Classification, Outstanding
 * Balances, rankings, the Vehicle expense log, etc.) on a phone. A sideways-
 * scrolling table clips values and never reads well, so instead each row
 * collapses into a vertical "Label: value" card, like the calendar's stacked
 * view. The column headers are copied onto each cell as data-label by
 * paintops_cs_fin_table_labelize() (printed once via wp_footer), so this works
 * for every .cs-fin-table AND .veh-table without editing each table's markup.
 * Desktop is unchanged (normal table). */
.cs-fin-tablewrap { margin: 10px 0 6px; }
@media (min-width: 783px) {
  .cs-fin-tablewrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
}
@media (max-width: 782px) {
  .cs-fin-table, .cs-fin-table > tbody, .cs-fin-table > tbody > tr, .cs-fin-table > tbody > tr > td,
  .veh-table, .veh-table > tbody, .veh-table > tbody > tr, .veh-table > tbody > tr > td {
    display: block !important;
    width: auto !important;
    min-width: 0 !important;
  }
  .cs-fin-table > thead, .veh-table > thead { display: none !important; }
  .cs-fin-table > tbody > tr, .veh-table > tbody > tr {
    border: 1px solid var(--po-card-border, #e2e6ea);
    border-radius: 8px;
    margin: 0 0 12px;
    padding: 4px 12px;
    background: var(--po-card-bg, #fff);
  }
  .cs-fin-table > tbody > tr > td, .veh-table > tbody > tr > td {
    display: flex !important;
    justify-content: space-between;
    align-items: baseline;
    gap: 16px;
    text-align: right;
    padding: 8px 0 !important;
    border: 0 !important;
    border-bottom: 1px solid var(--po-line, #eee) !important;
    white-space: normal !important;
  }
  .cs-fin-table > tbody > tr > td:last-child, .veh-table > tbody > tr > td:last-child { border-bottom: 0 !important; }
  /* (2026-07-19, Mike's overflow report) A stacked cell whose VALUE is a
   * whole form (the Vehicles rename row: input + Rename button) can't fit
   * beside its ::before label on a phone, and because these cells are
   * unwrappable flex rows the td forced the page wider than the viewport,
   * the entire app scrolled sideways. Let stacked cells wrap, and on
   * phones let the rename form take its own full-width line under the
   * label with the input free to shrink (its desktop 220px floor is what
   * blew the width). */
  .cs-fin-table > tbody > tr > td, .veh-table > tbody > tr > td { flex-wrap: wrap; }
  .veh-table > tbody > tr > td form { flex: 1 1 100%; flex-wrap: wrap; }
  .veh-table > tbody > tr > td form input[type="text"] { min-width: 0 !important; max-width: none !important; flex: 1 1 140px !important; }
  .veh-table .paintops-btn { flex: 0 0 auto; }
  .cs-fin-table > tbody > tr > td[data-label]::before,
  .veh-table > tbody > tr > td[data-label]::before {
    content: attr(data-label);
    font-weight: 600;
    color: var(--po-text-muted, #667581);
    text-align: left;
    white-space: nowrap;
  }
  /* A cell that spans the row (e.g. the Profit-by-Classification detail
   * drawer that holds a nested table) shouldn't be a label/value flex row. */
  .cs-fin-table > tbody > tr > td[colspan], .veh-table > tbody > tr > td[colspan] { display: block !important; padding: 6px 0 !important; }
}

.cs-fin-gross-box {
  border: 1px solid var(--po-tile-border, #e6e6e6);
  border-radius: var(--po-radius-sm, 6px);
  padding: 12px 14px;
  background: var(--po-tile-bg, #fafbfc);
  margin: 14px 0 20px;
  max-width: 320px;
}

/* Email Quote/Estimate/Bid (?estimates=1&csaction=send&getEstId=X),
 * replaces the plain heading + bare <p><label><input> stack (whatever
 * borders the theme happened to give inputs by default) with the same
 * card look used elsewhere in the app, and consistent field spacing. */
.paintops-email-quote-box {
  border: 1px solid var(--po-card-border, #ddd);
  border-radius: var(--po-radius, 8px);
  padding: 18px 20px 22px;
  margin: 20px 0;
  background: var(--po-card-bg, #fff);
  box-shadow: var(--po-card-shadow, 0 1px 2px rgba(0,0,0,.04));
  max-width: 720px;
}

.paintops-email-quote-box h2 {
  margin-top: 0;
  color: var(--po-heading, #2f5aae);
  font-size: 130%;
}

.paintops-email-quote-box p {
  margin-bottom: 18px;
}

.paintops-email-quote-box label {
  display: block;
  font-weight: 600;
  margin-bottom: 5px;
}

.paintops-email-quote-box input[type="email"],
.paintops-email-quote-box input[type="text"],
.paintops-email-quote-box textarea {
  width: 100%;
  max-width: 100%;
  padding: 11px 12px;
  min-height: 44px;
  border: 1px solid var(--po-input-border, #ccc);
  border-radius: var(--po-radius-xs, 5px);
  font-family: inherit;
  font-size: 16px;
  box-sizing: border-box;
}

.paintops-email-quote-box textarea {
  line-height: 1.5;
}

.paintops-email-quote-box input[type="file"] {
  margin-top: 6px;
}

/* Profits page (?profits=1), the Top/Bottom/All job cards in the
 * Profit Per Hour rankings. Reuses the same card look and
 * cs-fin-positive/cs-fin-negative coloring as Job Financials so the
 * whole reporting side of the app reads as one system instead of every
 * report inventing its own inline styles. (The separate year-over-year
 * comparison cards that used to live here were folded into the This
 * Year So Far / Last Year stat grids instead, see
 * paintops_render_yearly_financial_dashboard() in job-financials-addon.php,
 * so their .cs-year-* rules were removed along with them.) */
.cs-rank-card {
  border: 1px solid var(--po-card-border, #ddd);
  border-radius: var(--po-radius, 8px);
  padding: 15px;
  margin-bottom: 15px;
  background: var(--po-card-bg, #fff);
}

.cs-rank-card .cs-rank-customer {
  font-size: 16px;
  margin-bottom: 10px;
  line-height: 1.5;
}

/* Toggle links (i.e. "Copy Title & Description From a Past Job") that
 * show/hide a .hidden-box below them. inline-flex + gap (rather than the
 * plain inline-block this started as) lines up the leading dashicon with
 * the text, same convention as .pv-quick-actions a elsewhere. */
.job-form-toggle {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin: -6px 0 14px;
  font-size: 90%;
  color: var(--po-accent, #4682B4);
  text-decoration: underline dotted;
  cursor: pointer;
}

.job-form-toggle .dashicons {
  font-size: 15px;
  width: 15px;
  height: 15px;
  text-decoration: none;
}

/* Marks an actually-required label, since "all fields required unless
 * noted" (stated once at the top of the form) is easy to forget by the
 * time you're scrolling through a long form. */
.paintops-required {
  color: var(--po-negative, #b00);
  font-weight: 700;
}

/* Small "(i)" hover tooltip, used next to a label instead of a
 * `<p class="description">` line underneath, for a short note that
 * doesn't need to take up permanent space on the form (e.g. "manage
 * this list elsewhere," or "this only matters when X"). */
.paintops-tooltip {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  margin-left: 4px;
  border-radius: 50%;
  background: var(--po-tooltip-bg, #ccd6e4);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  font-style: normal;
  line-height: 16px;
  text-align: center;
  cursor: help;
  vertical-align: middle;
}

.paintops-tooltip:hover,
.paintops-tooltip:focus {
  background: var(--po-accent, #4682B4);
}

.paintops-tooltip .paintops-tooltip-text {
  visibility: hidden;
  opacity: 0;
  position: absolute;
  bottom: 130%;
  left: 50%;
  transform: translateX(-50%);
  width: 240px;
  background: var(--po-tooltip-panel, #23282d);
  color: #fff;
  font-size: 12px;
  font-weight: 400;
  line-height: 1.4;
  padding: 8px 10px;
  border-radius: var(--po-radius-sm, 6px);
  z-index: 20;
  transition: opacity 0.15s ease;
  pointer-events: none;
}

.paintops-tooltip:hover .paintops-tooltip-text,
.paintops-tooltip:focus .paintops-tooltip-text {
  visibility: visible;
  opacity: 1;
}

@media (max-width: 600px) {
  .paintops-tooltip .paintops-tooltip-text {
    width: 200px;
  }
}

/* Status pills (Quote / Estimate / Bid / Job), replaces a <select> with
 * tappable buttons, faster to use on a phone than opening a dropdown. */
.paintops-status-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 1rem;
}

.paintops-status-pill {
  flex: 1 1 auto;
  min-width: 90px;
  text-align: center;
  padding: 10px 14px;
  border: 1px solid var(--po-input-border, #ccc);
  border-radius: var(--po-radius-sm, 6px);
  background: var(--po-card-bg, #fff);
  color: var(--po-text, #333);
  font-weight: 600;
  cursor: pointer;
  user-select: none;
}

.paintops-status-pill:hover {
  background: var(--po-hover, #f2f6fa);
}

.paintops-status-pill.active {
  background: var(--po-accent, #4682B4);
  border-color: var(--po-accent, #4682B4);
  color: #fff;
}

/* Sticky Save bar, keeps the primary action reachable without
 * scrolling back up on a LONG form (New Job/Quote, New Quote/Estimate).
 * Don't use this on short forms that already fit on one screen, the
 * bordered/shadowed bar reads as an empty box with nothing in it next
 * to a small button, since there's no real scrolling for it to help
 * with. Use .paintops-form-save (below) there instead.
 *
 * position: fixed rather than position: sticky, sticky only works if
 * every single ancestor between this element and the viewport has
 * overflow: visible, and WP themes very commonly set overflow-x:
 * hidden somewhere in the page wrapper (to stop mobile horizontal
 * scroll), which silently breaks sticky with no error anywhere. Fixed
 * is anchored to the viewport itself, so it can't be broken by a
 * theme's wrapper markup. .job-form's padding-bottom below reserves
 * room so this bar never overlaps the last field on screen.
 */
.paintops-sticky-save {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 100;
  background: var(--po-card-bg, #fff);
  border-top: 1px solid var(--po-card-border, #ddd);
  padding: 14px 20px;
  text-align: center;
  box-shadow: 0 -2px 10px rgba(0,0,0,.08);
}

/* When the mobile bottom nav is active, the fixed Save bar stacks ABOVE
 * the nav. Its CONTAINER is anchored flush to the nav's top edge
 * (bottom = --pbn-bar, the nav's own height) and the anti-mis-tap
 * clearance between the Save button and the raised "+" is carried as
 * opaque padding INSIDE the container (--pbn-clear minus --pbn-bar,
 * plus the bar's normal 14px), so no page content ever shows in a gap
 * between the two bars while scrolling (Mike's ask, 2026-07-19). The
 * button's on-screen position is unchanged. Both vars are defined on
 * body.paintops-nav-bottom-active by the nav (manage-jobs.php); the
 * fallbacks keep this safe on its own and compute the same numbers. */
@media screen and (max-width: 782px) {
  body.paintops-nav-bottom-active .paintops-sticky-save {
    bottom: var(--pbn-bar, calc(64px + env(safe-area-inset-bottom)));
    padding-bottom: calc(14px + var(--pbn-clear, calc(100px + env(safe-area-inset-bottom))) - var(--pbn-bar, calc(64px + env(safe-area-inset-bottom))));
    box-shadow: 0 -2px 10px rgba(0,0,0,.14);
  }
  body.paintops-nav-bottom-active .job-form {
    padding-bottom: calc(var(--pbn-clear, 100px) + 96px);
  }
}

/* Plain save-button spacing for short forms (New Customer, etc.),
 * just breathing room, no bar/border/shadow/fixed positioning. */
.paintops-form-save {
  margin-top: 28px;
  margin-bottom: 40px;
}

/* Job Financials page: each section is its own full-size .cs-financial-box
 * (no outer wrapper box), stacked with a little gap, and the Save
 * Financials button uses the same fixed .paintops-sticky-save bar as the
 * job form, so this reserves room at the bottom so that bar never
 * overlaps the last box (Invoices / Receipts). */
.paintops-financials-page { padding-bottom: 90px; }
.paintops-financials-page > .cs-financial-box,
.paintops-financials-page > form > .cs-financial-box { margin-bottom: 16px; }

/* Job Financials page accordions (2026-07-22, Mike): every data section
 * (Gross, Payments, Hours, Invoices, Expenses) collapses to a one-line
 * summary with its saved totals on the right, same idea as the admin
 * settings accordions, so the page reads as a dashboard at a glance. The
 * Job Financials tiles and Estimate vs Actual stay open boxes above. */
details.cs-fin-acc {
  border: 1px solid var(--po-card-border, #ddd);
  border-radius: var(--po-radius, 8px);
  background: var(--po-card-bg, #fff);
  box-shadow: var(--po-card-shadow, 0 1px 2px rgba(0,0,0,.04));
  margin: 16px 0;
}
details.cs-fin-acc > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px 14px;
  flex-wrap: wrap;
  padding: 14px 18px;
  font-weight: 600;
  font-size: 16px;
  color: var(--po-heading, #2f5aae);
}
details.cs-fin-acc > summary::-webkit-details-marker { display: none; }
details.cs-fin-acc > summary::before {
  content: "\25B8";
  font-size: 13px;
  line-height: 1;
  color: var(--po-text-muted, #888);
  transition: transform 0.15s ease;
}
details.cs-fin-acc[open] > summary::before { transform: rotate(90deg); }
details.cs-fin-acc > summary .cs-fin-acc-meta {
  margin-left: auto;
  font-size: 13px;
  font-weight: 500;
  color: var(--po-text-muted, #777);
  text-align: right;
}
.cs-fin-acc-meta .pos { color: var(--po-positive, #1e7e34); font-weight: 600; }
.cs-fin-acc-meta .neg { color: var(--po-negative, #c0392b); font-weight: 600; }
.cs-fin-acc-meta .warn { color: #8a6d3b; font-weight: 600; }
details.cs-fin-acc > .cs-fin-acc-body { padding: 2px 18px 18px; }
/* Sections that render their own .cs-financial-box inside an accordion
 * (Invoices, Expenses) shed the inner card chrome so it doesn't double. */
details.cs-fin-acc .cs-financial-box {
  border: none !important;
  box-shadow: none !important;
  background: transparent;
  margin: 0 !important;
  padding: 0;
}

.job-form label {
  display: block;
  font-weight: 600;
  font-size: 15px;
  margin-bottom: 0.6rem;
  text-align: left;
}

.job-form input,
.job-form select,
.job-form textarea {
  width: 100% !important;
  padding: 0.5rem !important;
  margin-bottom: 2rem !important;
  border: 1px solid var(--po-input-border, #ccc) !important;
  border-radius: var(--po-radius-xs, 4px) !important;
  box-sizing: border-box !important;
}

/* Bigger, easier-to-hit typed fields for on-the-job phone use. 16px is the
 * threshold below which iOS auto-zooms the page the moment a field is
 * focused (jarring, and it leaves the crew scrolled and pinching back out),
 * so every typed field sits at 16px; min-height keeps each one a comfortable
 * thumb target and the extra padding gives the text room. Checkboxes and
 * radios are deliberately excluded (they keep their own 22px sizing below),
 * which is why this lists the typed input types instead of a bare
 * ".job-form input". */
.job-form input[type="text"],
.job-form input[type="email"],
.job-form input[type="tel"],
.job-form input[type="number"],
.job-form input[type="date"],
.job-form input[type="password"],
.job-form input[type="search"],
.job-form input[type="url"],
.job-form input:not([type]),
.job-form select,
.job-form textarea {
  font-size: 16px !important;
  min-height: 44px;
  padding: 0.7rem 0.75rem !important;
  line-height: 1.4;
}
.job-form textarea { min-height: 96px; }

/* Validation errors after a submit. Rendered as a prominent banner (not the
 * old bare red text) and, via a small script where it's echoed, scrolled
 * into view on load, so a failed save is never mistaken for a successful one
 * when the fixed Save bar sits over an off-screen error. */
.paintops-form-errors {
  margin: 0 0 20px;
  padding: 14px 16px;
  border: 1px solid #e6b3b0;
  border-left: 4px solid #c0392b;
  border-radius: var(--po-radius-xs, 4px);
  background: #fdecea;
  color: #9b1c17;
  font-size: 15px;
  line-height: 1.5;
}
.paintops-form-errors:focus { outline: none; }

/* Chromium on Windows draws a <select>'s selected-option text using its
 * own native OS chrome and ignores left/right padding on it completely,
 * this (not caching, not specificity) is why Job Category/Job
 * Classification never got any visible left inset even with !important
 * above; every OTHER field type (text inputs, textareas) doesn't have
 * this problem. Turning off the native appearance and drawing a plain
 * arrow ourselves hands the whole box back to normal CSS, so the padding
 * finally has something to apply to. */
.job-form select {
  appearance: none !important;
  -webkit-appearance: none !important;
  -moz-appearance: none !important;
  background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath fill='%23666' d='M1 1l5 5 5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.75rem center;
  background-size: 12px 8px;
  padding-right: 2.25rem !important;
}

/* Checkboxes/radios were inheriting the text-input rule just above,
 * width:100% stretched a checkbox to fill its container, which pushed its
 * label text onto its own line instead of sitting beside it (the "Work
 * Areas" Interior/Exterior checkboxes stacking oddly instead of sitting in
 * a row). Every checkbox/radio anywhere inside a .job-form is excluded
 * from that rule and sized on its own below instead, width/height are
 * deliberately NOT set here (even though this selector is more specific
 * than the app-wide input[type="checkbox"] rule below): setting them here
 * would win the cascade and silently override that rule's 22px, which is
 * exactly the bug that shrank these back down last time. The text-input
 * rule above now uses !important (to force real form fields to keep their
 * padding regardless of theme CSS), so every property here needs
 * !important too, or the !important above would win instead. */
.job-form input[type="checkbox"],
.job-form input[type="radio"] {
  padding: 0 !important;
  margin-bottom: 0 !important;
  border: none !important;
  border-radius: 0 !important;
}

/* App-wide checkbox sizing, the browser default (~13px) is a small,
 * easy-to-miss target, especially on a phone out on a job site. Sized
 * clearly larger than a line of body text, and applied everywhere
 * job-style.php loads (every app page), not just inside .job-form, so
 * Scope Components, Situational Clauses, and every other checklist in the
 * app gets the same bigger, consistent checkbox. accent-color re-themes
 * the native checkbox (check color/fill) without giving up native
 * behavior or accessibility the way a fully custom checkbox would.
 * !important on width/height only, since a couple of one-off checkboxes
 * elsewhere (e.g. the itemize-quote toggle) carry their own inline
 * width/height that would otherwise win by specificity and drift out of
 * sync with this app-wide size. */
input[type="checkbox"] {
  width: 22px !important;
  height: 22px !important;
  accent-color: var(--po-accent, #4682B4);
  cursor: pointer;
  flex-shrink: 0;
  vertical-align: middle;
}

.job-form button {
  background: var(--po-accent, #4682B4);
  color: #fff;
  padding: 0.7rem 1.2rem;
  min-height: 44px;
  font-size: 15px;
  border: none;
  border-radius: var(--po-radius-xs, 4px);
  cursor: pointer;
}

.job-form button:hover {
  opacity: 0.9;
}

/* Shared app-wide button look, for the buttons/links living OUTSIDE a
 * .job-form (page-level actions like "+ New Job/Quote", "+ New Customer",
 * "New Quote", "Analyze Photo") that used to fall back to WordPress's
 * plain default .button/.button-primary admin styling, which looks like
 * a wp-admin screen, not the rest of this app. Matches the same solid-
 * accent-color/white-text "primary" look as .job-form button above, plus
 * a bordered white "secondary" for a lower-emphasis action sitting next
 * to a primary one (Search next to +New Customer, Take/Choose Photo next
 * to Analyze Photo, etc.). */
/* !important throughout this whole group: a plain "any <button> inside
 * .job-form" element-selector rule above (.job-form button) has higher
 * specificity than a single class like .paintops-btn-secondary, so
 * without !important it silently won and painted every button (Take
 * Photo, Choose Photo, Analyze Photo, etc.) the same solid accent color
 * regardless of which variant class was actually on it. */
.paintops-btn {
  display: inline-block;
  padding: 0.7rem 1.3rem !important;
  min-height: 44px;
  border-radius: var(--po-radius-xs, 4px) !important;
  font-weight: 600;
  font-size: 15px;
  text-decoration: none;
  cursor: pointer;
  border: 1px solid transparent !important;
  transition: opacity 0.15s ease;
  line-height: 1.4;
}

.paintops-btn:hover {
  opacity: 0.85;
}

.paintops-btn-primary,
.paintops-btn-primary:visited {
  background: var(--po-accent, #4682B4) !important;
  color: #fff !important;
  border-color: var(--po-accent, #4682B4) !important;
}

.paintops-btn-secondary,
.paintops-btn-secondary:visited {
  background: var(--po-btn2-bg, #fff) !important;
  color: var(--po-accent, #4682B4) !important;
  border-color: var(--po-input-border, #ccc) !important;
}

/* AI action buttons (2026-07-22, Mike's pick from the mockups: the "G2
 * steel tint"). One shared class marks every AI-powered action, Analyze
 * Receipt, the quote builder's feedback/rewrite/materials trio, Explain
 * Profit, Scan with AI, as one family: a soft steel-tinted field with a
 * sparkles icon, quiet enough to never outrank a Save/Create button.
 * The icon is drawn with a CSS mask filled by currentColor, so it
 * recolors with the text under every theme with no per-button SVG
 * markup. Theme overrides live in app-themes.php as --po-ai-* vars
 * (Dark defines its own; light themes use these defaults, the tint is
 * near-neutral enough to sit under any accent). !important mirrors the
 * .paintops-btn convention, theme/WP .button rules are more specific. */
.paintops-btn-ai {
  display: inline-flex !important;
  align-items: center;
  gap: 7px;
  background: var(--po-ai-bg, #f1f6fa) !important;
  color: var(--po-ai-text, #3a6a94) !important;
  border: 1px solid var(--po-ai-border, #c3d4e2) !important;
  border-radius: var(--po-radius-xs, 4px) !important;
  font-weight: 600;
}
.paintops-btn-ai:hover,
.paintops-btn-ai:focus {
  background: var(--po-ai-bg-hover, #e5eff7) !important;
  color: var(--po-ai-text, #3a6a94) !important;
}
.paintops-btn-ai:disabled { opacity: .55; }
.paintops-btn-ai::before {
  content: "";
  flex: 0 0 15px;
  width: 15px;
  height: 15px;
  background-color: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9.6 5.6 11 2l1.4 3.6L16 7l-3.6 1.4L11 12 9.6 8.4 6 7l3.6-1.4Zm9 7.4.9-2.3.9 2.3 2.3.9-2.3.9-.9 2.3-.9-2.3-2.3-.9 2.3-.9ZM5.5 14l.9 2.3 2.3.9-2.3.9-.9 2.3-.9-2.3-2.3-.9 2.3-.9.9-2.3Z'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9.6 5.6 11 2l1.4 3.6L16 7l-3.6 1.4L11 12 9.6 8.4 6 7l3.6-1.4Zm9 7.4.9-2.3.9 2.3 2.3.9-2.3.9-.9 2.3-.9-2.3-2.3-.9 2.3-.9ZM5.5 14l.9 2.3 2.3.9-2.3.9-.9 2.3-.9-2.3-2.3-.9 2.3-.9.9-2.3Z'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* "Back to X" navigation link, sits above a sub-page's content (Job
 * Financials, Add Photos, Add Expense, Customer detail, Schedule Follow-
 * Up, etc.) as a bordered pill button instead of a bare "&larr; Back to"
 * text link, with extra top margin so it reads as clearly separate from
 * the main nav above it rather than crowding right up against it. */
.paintops-back-link,
.paintops-back-link:visited {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 28px 0 14px;
  padding: 0.5rem 0.9rem !important;
  background: var(--po-btn2-bg, #fff) !important;
  border: 1px solid var(--po-input-border, #ccc) !important;
  border-radius: var(--po-radius-xs, 4px) !important;
  color: var(--po-accent, #4682B4) !important;
  font-weight: 600;
  font-size: 14px;
  text-decoration: none;
}

.paintops-back-link:hover {
  background: var(--po-hover, #f7f7f7) !important;
}

.paintops-back-link .dashicons {
  font-size: 16px;
  width: 16px;
  height: 16px;
}

/* Hidden Content Box */
.hidden-box {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease-out, padding 0.3s ease-out;
}

.hidden-box.show {
  max-height: 7500px; /* adjust for content size */
  padding: 0.5rem 0;
}

/* Customer/Address/Scheduled glance row, originally just the Job
 * View page's own at-a-glance card, moved here (from a local <style>
 * block on that one page) so paintops_render_job_customer_summary()
 * can reuse it on every job sub-page (Financials, Add Expense, Photos,
 * Create Quote, Schedule Follow-Up), all of which load job-style.php
 * but never render job-view.php's own inline styles. */
.pv-glance-row { padding:4px 0; font-size:15px; }
.pv-glance-row strong { display:inline-block; min-width:110px; }

/* Inline glance variant (2026-07-19, Mike's tidy-the-top pass): the
 * Customer/Scheduled summary on job sub-pages sits on ONE line when the
 * width allows and wraps to stacked lines when it doesn't (flex-wrap,
 * the modern take on his two-float-divs idea). The label min-width is
 * dropped inside this variant so segments hug their content. */
.pv-glance-inline { display:flex; flex-wrap:wrap; gap:2px 36px; align-items:baseline; }
.pv-glance-inline .pv-glance-row { padding:2px 0; white-space:nowrap; }
.pv-glance-inline .pv-glance-row strong { min-width:0; margin-right:6px; }

/* Assigned team members in the "Workers:" glance row, with opt-in
   Call/Text links (job-view.php). Links only render when a teammate has
   saved a phone under PaintOps > Painters/Helpers. */
/* Workers glance row: each assigned worker is its OWN bordered capsule
 * (Mike 2026-07-22: plain names ran together and were hard to tell
 * apart), with the name, the YOU tag, and any Call/Text mini-pills
 * grouped inside one chip, distinct boundaries, still one compact row.
 * pv-team-nameonly (set server-side) evens the right padding on a chip
 * with no inner pills. */
.pv-team-member { display:inline-flex; align-items:center; gap:7px; margin:2px 8px 4px 0; padding:3px 6px 3px 11px; border:1px solid var(--po-card-border,#d0d5dd); border-radius:999px; background:var(--po-tile-bg,#fafbfc); white-space:nowrap; vertical-align:middle; }
.pv-team-member.pv-team-nameonly { padding-right:11px; }
.pv-team-name { font-weight:600; font-size:13px; }
.pv-team-contact { display:inline-block; font-size:12px; font-weight:600; line-height:1.7; text-decoration:none; padding:0 9px; border-radius:999px; border:1px solid var(--po-border,#d0d5dd); background:var(--po-card-bg,#fff); color:var(--po-accent,#2271b1); }
.pv-team-contact:hover, .pv-team-contact:focus { background:var(--po-accent,#2271b1); color:#fff; }
.pv-team-you { display:inline-block; font-size:11px; font-weight:700; line-height:1.7; padding:0 9px; border-radius:999px; background:var(--po-accent-soft,rgba(70,130,180,0.12)); color:var(--po-accent,#2271b1); text-transform:uppercase; letter-spacing:.3px; }
@media (max-width:600px) { .pv-team-member { display:flex; justify-content:space-between; gap:10px; margin:8px 0; } .pv-team-contact { padding:3px 16px; } }

/* Customer name as a two-click contact reveal (Mike 2026-07-22): dotted
 * underline signals it's tappable; the Call/Text pills only appear after
 * the name is clicked, so a pocket tap can't dial the customer. */
.pv-cust-toggle { cursor:pointer; text-decoration:underline dotted; text-underline-offset:3px; }
.pv-cust-toggle .pv-more-chevron { font-size:11px; color:var(--po-text-muted,#888); }

/* Job status chip in the glance box: upcoming / mid-run / past / done. */
.pv-status-chip { display:inline-block; font-size:12px; font-weight:700; line-height:1.9; padding:0 11px; border-radius:999px; }
.pv-status-upcoming { background:var(--po-accent-soft,rgba(70,130,180,0.12)); color:var(--po-accent,#2271b1); }
.pv-status-active { background:rgba(30,126,52,0.12); color:var(--po-positive,#1e7e34); }
.pv-status-done { background:var(--po-tile-bg,#f0f0f1); color:var(--po-text-muted,#666); border:1px solid var(--po-card-border,#ddd); }
.pv-status-past { background:#fff8ec; color:#8a5a00; border:1px solid #e0c36a; }

/* Job View (?viewEid=X) quick actions row + "More Actions" panel.
 * Referenced by job-view.php and estimates.php's quote-view page, but
 * never actually defined anywhere, these links were rendering as bare
 * unstyled text before this rule was added. */
.pv-quick-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 20px;
  margin: 10px 0 14px;
}

.pv-quick-actions a {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--po-accent, #4682B4);
  font-weight: 600;
  font-size: 15px;
  text-decoration: none;
}

.pv-quick-actions a:hover {
  text-decoration: underline;
}

.pv-quick-actions .dashicons {
  font-size: 18px;
  width: 18px;
  height: 18px;
}

.pv-dir-wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
}
.pv-dir-gear {
  margin-left: 4px;
  opacity: .65;
}
.pv-dir-gear:hover { opacity: 1; }
.pv-dir-gear .dashicons { font-size: 16px !important; width: 16px !important; height: 16px !important; }
.pv-dir-menu {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 60;
  min-width: 172px;
  margin-top: 6px;
  padding: 6px;
  background: var(--po-card-bg, #fff);
  border: 1px solid var(--po-card-border, #ddd);
  border-radius: var(--po-radius, 8px);
  box-shadow: 0 6px 20px rgba(0,0,0,.14);
}
.pv-dir-menu.show { display: block; }
.pv-dir-menu a {
  display: flex !important;
  align-items: center;
  gap: 6px;
  padding: 8px 10px;
  border-radius: 6px;
  color: var(--po-text, #333) !important;
  font-weight: 400 !important;
  font-size: 14px !important;
  white-space: nowrap;
  text-decoration: none;
}
.pv-dir-menu a:hover { background: var(--po-tile-bg, #f2f5fb); text-decoration: none; }
.pv-dir-menu a.is-current { font-weight: 600 !important; }
.pv-dir-check { font-size: 16px !important; width: 16px !important; height: 16px !important; color: #1a7a43; }

.pv-more-toggle {
  color: var(--po-text-muted, #555) !important;
}

.pv-more-toggle .pv-more-chevron {
  font-size: 10px;
}

.pv-more-actions {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--po-card-border, #ddd);
  border-radius: var(--po-radius, 8px);
  background: var(--po-tile-bg, #fafafa);
  margin-bottom: 20px;
}

.pv-more-actions a {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  color: var(--po-text, #333);
  font-size: 15px;
  text-decoration: none;
  border-bottom: 1px solid var(--po-line, #eee);
}

.pv-more-actions a:last-child {
  border-bottom: none;
}

.pv-more-actions a:hover {
  background: var(--po-hover, #f0f0f0);
}

.pv-more-actions .dashicons {
  font-size: 18px;
  width: 18px;
  height: 18px;
  color: var(--po-accent, #4682B4);
}

/* Job View Quick Actions as a tile grid (the .pv-quick-actions-tiles
 * modifier, only on the single-job view, NOT the list/board cards which
 * reuse plain .pv-quick-actions). Turns the old small text links
 * (Directions, Add Expense, Notes & Photos, More Actions) into equal,
 * thumb-sized icon-over-label tiles so they're easy to hit on a phone,
 * while staying visually secondary to the big Check In/Out box below them.
 * Placed after the base .pv-quick-actions rules so the grid display and the
 * tile look win over the flex/link styling for elements carrying both
 * classes. */
.pv-quick-actions-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  gap: 10px;
  align-items: stretch;
  margin: 12px 0 16px;
}
.pv-quick-actions-tiles > a,
.pv-quick-actions-tiles > .pv-dir-wrap,
.pv-quick-actions-tiles > .pv-more-toggle {
  margin: 0;
}
/* The shared tile face: applied to the plain action links, the More Actions
 * toggle, and the Directions main button (which lives inside .pv-dir-wrap). */
.pv-quick-actions-tiles > a,
.pv-quick-actions-tiles > .pv-more-toggle,
.pv-quick-actions-tiles .pv-dir-main {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 72px;
  height: 100%;
  padding: 12px 8px;
  border: 1px solid var(--po-card-border, #ddd);
  border-radius: var(--po-radius, 10px);
  background: var(--po-tile-bg, #f7f9fc);
  color: var(--po-accent, #4682B4) !important;
  font-weight: 600;
  font-size: 13px;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  box-sizing: border-box;
}
.pv-quick-actions-tiles > a:hover,
.pv-quick-actions-tiles > .pv-more-toggle:hover,
.pv-quick-actions-tiles .pv-dir-main:hover {
  background: var(--po-accent-soft, rgba(70,130,180,0.08));
  text-decoration: none;
}
.pv-quick-actions-tiles .dashicons {
  font-size: 24px !important;
  width: 24px !important;
  height: 24px !important;
}
/* Directions is a split control (main button + a small gear to pick the
 * maps app). Make the wrapper the tile cell, the main button fill it, and
 * tuck the gear into the top-right corner; its dropdown still opens below. */
.pv-quick-actions-tiles > .pv-dir-wrap {
  position: relative;
  display: block;
}
.pv-quick-actions-tiles .pv-dir-main {
  width: 100%;
}
.pv-quick-actions-tiles .pv-dir-gear {
  position: absolute;
  top: 5px;
  right: 5px;
  margin: 0;
  padding: 2px;
  z-index: 2;
}
.pv-quick-actions-tiles .pv-dir-menu {
  top: 100%;
  left: 0;
}
.pv-quick-actions-tiles > .pv-more-toggle .pv-more-chevron {
  font-size: 10px;
}

/* Job Card Components */
.job-card {
  border: 1px solid var(--po-card-border, #ddd);
  border-radius: var(--po-radius-sm, 6px);
  padding: 1rem 1.25rem;
  margin-bottom: 1.5rem;
  background: var(--po-card-bg, #fff);
  box-shadow: var(--po-card-shadow, 0 2px 4px rgba(0,0,0,.05));
}

.job-card-header {
  background: var(--po-card-header-bg, rgba(220,219,197,0.16));
  margin: 0 0 .75rem;
  padding: 10px 12px;
  border-radius: var(--po-radius-xs, 4px);
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.job-card .job-title {
  font-size: 19px;
  color: var(--po-heading, #2f5aae);
  margin: 0;
}

/* Small status chips on each job card: type (Quote/Estimate/Bid/Job),
 * completion, and the "Starts in/Started X ago" note, replaces the
 * plain, unstyled "Complete? No" text that used to float above the card
 * with something that reads at a glance. */
.job-card-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.job-badge {
  display: inline-block;
  padding: 2px 10px;
  border-radius: 12px;
  font-size: .75rem;
  font-weight: 600;
  white-space: nowrap;
}

.job-badge-quote     { background: #eef1f4; color: var(--po-text-muted, #666); }
.job-badge-estimate  { background: #e8f0fe; color: var(--po-heading, #2f5aae); }
.job-badge-bid       { background: #fdf3e0; color: #a5680a; }
.job-badge-job       { background: #e6f4ea; color: var(--po-positive, #1e7e34); }
.job-badge-complete-yes { background: #e6f4ea; color: var(--po-positive, #1e7e34); }
.job-badge-complete-no  { background: #fdecea; color: var(--po-negative, #c0392b); }
.job-badge-muted     { background: #f1f1f1; color: var(--po-text-muted, #777); }

.job-meta {
  font-size: .9rem;
  color: var(--po-text-muted, #666);
  display: flex;
  justify-content: space-between;
  margin-bottom: .75rem;
}

.job-meta a {
  color: var(--po-accent, #4682B4);
  text-decoration: none;
}

.job-meta a:hover {
  text-decoration: underline;
}

.job-desc {
  margin: 0;
  font-size: 1rem;
  line-height: 1.4;
}

/* Job Title Section */
.job-title {
  font-size: 24px;
  font-weight: bold;
  margin-top: 20px;
  margin-bottom: 10px;
  word-break: break-word;
}

.job-id,
.job-name {
  display: block;
  line-height: 1.3;
}

/* Responsive Layout */
@media (max-width: 768px) {
  .addr-row {
    grid-template-columns: 1fr; /* one per line */
  }

  table {
    width: 100%;
    table-layout: fixed;
    word-wrap: break-word;
  }

  td {
    display: block;
    width: 100%;
    box-sizing: border-box;
    padding: 6px 0;
  }

  tr {
    display: block;
    margin-bottom: 8px;
  }

  tr td:first-child {
    font-weight: bold;
    background: var(--po-tile-bg, #f5f5f5);
  }
}

/* PaintOps Buttons
 *
 * Every page under the app (Customers, Financials, Paint Colors,
 * Calendar, Resources, etc.) uses the WP-admin-style class names
 * button / button-primary / button-secondary for its action buttons.
 * Those classes carry no real styling of their own on the front end,
 * so a real <button> element's OS-native chrome (or whatever generic
 * .button rule the active theme happens to ship) was what actually
 * rendered, both bigger and visually inconsistent with the compact
 * nav pills above. This gives every one of those buttons one shared,
 * compact look that matches the nav bar's sizing and accent color,
 * loaded once here since job-style.php is required on every app page.
 */
.button,
a.button,
button.button,
input.button {
  display: inline-block;
  box-sizing: border-box;
  margin: 0;
  padding: 8px 16px !important;
  font-size: 14px !important;
  line-height: 1.4 !important;
  height: auto !important;
  border-radius: var(--po-radius-sm, 6px);
  border: 1px solid var(--po-accent, #4682B4);
  background: var(--po-card-bg, #fff);
  color: var(--po-accent, #4682B4);
  cursor: pointer;
  text-decoration: none;
}

.button:hover,
a.button:hover,
button.button:hover,
input.button:hover {
  opacity: 0.85;
}

/* App-page links pick up the theme accent instead of whatever default
 * blue the WP theme ships, bare <a> tags (customer names on board
 * cards, calendar job links, Related Visits dates) were the single
 * most visible off-theme element on the live site. Low specificity on
 * purpose: anything with its own class-based color rule (buttons, nav
 * pills, badges, the admin bar's #wpadminbar rules) still wins. */
a {
  color: var(--po-accent, #4682B4);
}

/* Hide the WP theme's own page header/title on app pages. The theme
 * was printing a giant "Jobs" H1 above the app on every route, it
 * duplicated the app's own headings (e.g. right above "Job #1 ...")
 * and pushed real content nearly a full screen down on phones. Covers
 * the common classic-theme and block-theme title markup; the document
 * <title> (and the section-label filter feeding it) is unaffected.
 * (2026-07-19) The old companion rule that merely SIZE-CAPPED the
 * title on themes with wrapper markup this list did not match (Neve's
 * .nv-page-title etc.) was folded in here: with the unified app bar
 * the theme H1 read as a duplicate of the app's own screen headings
 * (Mike's report, e.g. "Business" twice), and every screen where it
 * showed either duplicates a better in-app heading or is deliberately
 * title-less (matching full-screen canvas mode, which never had the
 * theme H1). So the theme title is now hidden on app pages across ALL
 * known markup, never just resized. */
.entry-header,
h1.entry-title,
h1.page-title,
h1.wp-block-post-title,
.nv-page-title,
.nv-page-title-wrap,
.page-header-inner h1,
header.entry-header h1,
.wp-block-post-title {
  display: none !important;
}

/* Primary save buttons (the sticky Save bar and the plain save row).
 * Some themes style bare <button>/.wp-element-button elements with
 * their own brand color at higher specificity than .job-form button
 * above, which made "Create" render WordPress-blue in the middle of
 * an otherwise accent-colored app. !important so the app's primary
 * action is always the app's accent, on any theme. */
.paintops-sticky-save button,
.paintops-form-save button,
.job-form button[type="submit"] {
  background: var(--po-accent, #4682B4) !important;
  color: #fff !important;
  border: none !important;
  border-radius: var(--po-radius-xs, 4px) !important;
  padding: 0.7rem 2.2rem !important;
  font-size: 15px !important;
  font-weight: 600;
  cursor: pointer;
}


/* Rows-based Jobs home (2026-08-31 redesign, includes/job-rows.php).
 * Grouped row lists: uppercase section labels, one card per section,
 * a fixed grid per row (status / job / crew or meta / date or action /
 * money) so the page scans identically every day. All colors ride the
 * --po-* theme variables. */
.po-jrows-head { display: flex; align-items: baseline; gap: 10px; margin: 22px 0 8px; }
.po-jrows-head:first-child { margin-top: 6px; }
.po-jrows-label { font-size: 13px; font-weight: 800; letter-spacing: .05em; text-transform: uppercase; color: var(--po-heading, #2f5aae); }
.po-jrows-meta { font-size: 13px; font-weight: 600; color: var(--po-text-muted, #667581); }
.po-jrows-card { background: var(--po-card-bg, #fff); border: 1px solid var(--po-card-border, #ddd); border-radius: var(--po-radius, 12px); box-shadow: var(--po-card-shadow, 0 1px 2px rgba(0,0,0,.04)); overflow: hidden; container-type: inline-size; }
.po-jrow { display: grid; grid-template-columns: 150px minmax(0, 1fr) 130px 150px 110px; gap: 14px; align-items: center; padding: 13px 18px; border-top: 1px solid var(--po-line, #f1f4f7); }
.po-jrow:first-child { border-top: none; }
.po-jrow-empty { display: block; color: var(--po-text-muted, #667581); font-size: 14px; }
.po-jrow-status { font-size: 12.5px; font-weight: 700; color: var(--po-text-muted, #667581); display: flex; align-items: center; gap: 7px; white-space: nowrap; }
.po-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; background: var(--po-text-soft, #9aa5b1); }
.po-dot-green { background: var(--po-positive, #1a7f37); }
.po-dot-blue { background: var(--po-accent, #3D5A80); }
.po-dot-amber { background: #d97706; }
.po-dot-gray { background: var(--po-text-soft, #9aa5b1); }
.po-jrow-main { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.po-jrow-title { font-weight: 700; font-size: 14.5px; color: var(--po-heading, #2f5aae); text-decoration: none; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.po-jrow-title:hover { text-decoration: underline; }
.po-jrow-sub { font-size: 13px; color: var(--po-text-muted, #667581); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.po-jrow-cell { font-size: 13.5px; color: var(--po-text, #2b3440); }
.po-jrow-cell a { font-weight: 700; }
.po-jrow-money { font-size: 13.5px; font-weight: 700; color: var(--po-heading, #2f5aae); text-align: right; white-space: nowrap; }
.po-jrow-due { color: var(--po-negative, #c0392b); }
.po-jrow-dim { color: var(--po-text-soft, #9aa5b1); }
.po-jrow-crew { display: inline-flex; }
.po-jrow-avatar { width: 27px; height: 27px; border-radius: 50%; background: var(--po-accent, #3D5A80); color: #fff; font-size: 11px; font-weight: 700; display: inline-flex; align-items: center; justify-content: center; border: 2px solid var(--po-card-bg, #fff); }
.po-jrow-avatar + .po-jrow-avatar { margin-left: -8px; }
.po-jrow-avatar-more { background: var(--po-tile-bg, #eef2f6); color: var(--po-text-muted, #667581); }
.po-jrows-foot { margin: 18px 0 4px; font-size: 13.5px; display: flex; align-items: center; gap: 10px; }
.po-jrows-foot a { font-weight: 700; }
.po-jrows-sep { color: var(--po-text-soft, #c3cad3); }
@media (max-width: 900px) {
  .po-jrow { grid-template-columns: minmax(0, 1fr) auto; }
  .po-jrow-status { order: 1; }
  .po-jrow-money { order: 2; }
  .po-jrow-main { order: 3; grid-column: 1 / -1; }
  .po-jrow-cell { order: 4; }
}
/* Themes with a normal content column give the card ~640px even on desktop,
 * which starved the 1fr title cell to nothing. Collapse by the CARD's own
 * width so the rows read correctly inside any theme (the viewport rule above
 * stays as the fallback for browsers without container queries). */
@container (max-width: 760px) {
  .po-jrow { grid-template-columns: minmax(0, 1fr) auto; }
  .po-jrow-status { order: 1; }
  .po-jrow-money { order: 2; }
  .po-jrow-main { order: 3; grid-column: 1 / -1; }
  .po-jrow-cell { order: 4; }
}
