:root {
	--Red: #44A88C;
	--White: #FFFFFF;
	--Black: #000000;
	/* 2026-05-15: --Light-grey-1 used to be #E5E7EB which rendered as
	   almost-invisible borders on inputs, checkboxes, dividers, and
	   table cells against the white app background. Bumped to #B5BDCE
	   so the dozens of `border: 1px solid var(--Light-grey-1)` rules
	   across reports/, settings/, tracking/, vehicles/, etc. all
	   become legibly visible without having to touch each rule. The
	   four `background-color: var(--Light-grey-1)` sites (subtle
	   dividers in settings + tracking) also benefit — they read as
	   actual dividers now instead of looking like rendering glitches. */
	--Light-grey-1: #B5BDCE;
	--Light-grey-2: #F4F7FF;
	--Light-grey-3: #D0D6E7;
    --Light-grey-4: #9FA4B1;
	--Dark-grey-1: #004E51;
	--Dark-grey-2: #44A88C;
	--Dark-grey-3: #3CBA58;
  --Green: #44A88C;

  --Linear-transition: all 0.2s linear;
  --Cubic-transition: all 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
  --Ease-transition: all 0.5s ease-in-out;

  --Table-Cell-Spacing-X: 20px;
  --Table-Cell-Spacing-Y: 12px;

  /* Brand typefaces (brandbook): Satoshi carries body and UI, Sora carries
     display. --Font-Family keeps its name because 13 call sites across the
     app already point at it, so repointing it here migrates all of them. */
  --Font-Family: Satoshi, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --pv-font-body: var(--Font-Family);
  --pv-font-display: Sora, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --Basic-Forms-Input-Border-Radius: 8px;
}

/* Both faces are variable woff2: ~98KB for the pair, against the single
   854KB Inter TTF they replace (the app had no woff2 at all before this).
   Weight ranges are the fonts' real axis limits — Satoshi 300-900, Sora
   100-800. Nothing in the app asks for 900, so Sora's lower ceiling costs
   us nothing.
   Licensing: Sora is SIL OFL 1.1 (/fonts/Sora-OFL.txt). Satoshi is the ITF
   Free Font License (/fonts/Satoshi-FFL.txt), whose clause 02 restricts
   webfont serving without written consent — Periva holds that consent.
   Inter TTFs stay on disk: the report export pipeline and the server-side
   chart renderer still use them, and neither goes through this file. */
@font-face {
  font-family: Satoshi;
  src: url('/fonts/Satoshi-Variable.woff2') format('woff2');
  font-weight: 300 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: Satoshi;
  src: url('/fonts/Satoshi-VariableItalic.woff2') format('woff2');
  font-weight: 300 900;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: Sora;
  src: url('/fonts/Sora-Variable.woff2') format('woff2');
  font-weight: 100 800;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: Sora;
  src: url('/fonts/Sora-VariableItalic.woff2') format('woff2');
  font-weight: 100 800;
  font-style: italic;
  font-display: swap;
}

html,
body {
  transition: var(--Ease-transition);
  width: 100vw;
  height: 100vh;
  padding: 0;
  margin: 0;
  overflow: hidden;
  box-sizing: border-box;
  background-color: #202020;
  -webkit-font-smoothing: antialiased; /* Smoother text rendering on webkit browsers */
  -moz-osx-font-smoothing: grayscale;  /* Grayscale rendering on macOS */
}

html,
body,
td,
th,
input,
button,
textarea {
  transition: var(--Ease-transition);
	color: var(--Dark-grey-1);
	font-family: var(--Font-Family);
	font-size: 14px;
	font-style: normal;
	font-weight: 500;
	line-height: 24px;
	letter-spacing: 0.07px;
}

/* Display face on page titles only. Deeper heading levels are not a size
   hierarchy in this app — h2 covers everything from a 22px panel title down
   to a 13px uppercase card label, so applying the display face by tag put
   Sora on things that read as UI labels rather than headlines. Page titles
   are reliably h1, and anything else that should read as display opts in
   with var(--pv-font-display). Only the face changes here; size, weight and
   colour keep coming from wherever they already did. */
h1 {
	font-family: var(--pv-font-display);
}

textarea:focus, 
input:focus {
  transition: var(--Ease-transition);
  border-color: var(--Red);
  outline: none;
}

textarea {
  transition: var(--Ease-transition);
  border-color: var(--Light-grey-1);
}

input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
textarea:-webkit-autofill,
textarea:-webkit-autofill:hover,
textarea:-webkit-autofill:focus,
select:-webkit-autofill,
select:-webkit-autofill:hover,
select:-webkit-autofill:focus {
  transition: var(--Ease-transition);
  -webkit-box-shadow: 0 0 0px 1000px #e5e5e5 inset;
}
.scroller {
  scrollbar-height: 8px;
  scrollbar-width: 5px;
}
::-webkit-scrollbar,
.scroller::-webkit-scrollbar {
  height: 8px;
  width: 5px;
}
::-webkit-scrollbar-track,
.scroller::-webkit-scrollbar-track {
  border-radius: 5px;
}
/* Scrollbars, both axes, in the primary brand green. The bar they used to
   paint was --Dark-grey-3 (#3CBA58) — the brand's bright secondary green,
   not the primary — which is why it read as acid rather than Periva. */
::-webkit-scrollbar-thumb,
.scroller::-webkit-scrollbar-thumb {
  background-color: var(--pv-green);
  border-radius: 5px;
}
::-webkit-scrollbar-thumb:hover,
.scroller::-webkit-scrollbar-thumb:hover {
	background-color: var(--pv-green-dk);
}
/* Firefox has no thumb pseudo-element and takes thumb/track as a pair.
   Kept behind @supports because Chrome honours scrollbar-color too, and
   once it is set Chrome drops the ::-webkit-scrollbar rules above — which
   cost us the 5px/8px sizing and gave back a 15px system bar. */
@supports not selector(::-webkit-scrollbar) {
	* {
		scrollbar-color: var(--pv-green) transparent;
	}
}
::-moz-selection {
  color: var(--White);
  background-color: var(--Dark-grey-1);
}

::selection {
  color: var(--White);
  background-color: var(--Dark-grey-1);
}

select {
  transition: var(--Ease-transition);
  font-family: var(--Font-Family);
}

select * {
  padding: 12px;
  font-family: var(--Font-Family);
}

select option:hover {
  background-color: var(--Dark-grey-1);
}
.checkbox {
  width: 16px;
  height: 16px;
  border: 1px solid var(--Light-grey-1);
  background-color: var(--White);
  border-radius: 3px;
  cursor: pointer;
  transition: all 0.2s ease-in-out;
  margin-top: auto;
  margin-bottom: auto;
}
.checkbox:hover {
  transform: scale(1.1);
}
.checkbox-checked {
	background-image: url('/img/check.svg');
	background-color: var(--Red);
	background-position: 1px 1px;
	border: 1px solid var(--Red);
}
#loader {
  display: none;
  position: fixed;
  width: 100%;
  height: 100%;
  background-color: rgb(255, 255, 255, 0.8);
  background-image: url('/img/periva-solutions-logo-large.svg');
  background-repeat: no-repeat;
  background-position: center;
  background-size: 600px 230px;
  z-index: 10000;
}
#loader-car {
  position: fixed;
  offset-path: path('m -240.43899,-110.50239 c -35.88768,18.609084 -81.62274,45.480764 -85.82349,85.687443 -3.07313,29.4139017 23.12062,59.08181 48.47246,74.31027 30.20958,18.14643 70.89038,1.808218 105.3035,9.40091 50.74579,11.196228 94.73523,53.349167 146.69818,52.764167 51.872175,-0.58398 110.377501,-17.522004 145.21898,-55.955517 22.20955,-24.499279 17.89355,-63.6707273 26.44362,-95.61404 6.44614,-24.082995 -0.89228,-57.039318 18.73892,-72.406793 26.58832,-20.81357 71.38351,-16.765 101.29213,-1.0928 40.26978,21.101479 78.70943,67.570748 76.41168,112.97612263 C 340.9686,26.212713 314.59195,48.51823 291.01232,60.999953 c -24.4377,12.935937 -55.46355,13.742735 -82.54724,8.17378 -27.32881,-5.619357 -58.96771,-16.494675 -73.2825,-40.44312 -19.78134,-33.0939061 20.89372,-84.111695 -1.27132,-115.65879 -17.0588,-24.279483 -55.390099,-21.334373 -83.411457,-31.096533 -32.113288,-11.18771 -63.090845,-29.55088 -97.042773,-31.47307 -61.08751,-3.45848 -119.75214,25.22433 -179.87853,36.55846 -4.6605,0.87853 -9.80727,0.25378 -14.01749,2.43693 z');

  animation: move-loader-car 20000ms infinite;
  width: 45px;
  height: 45px;
  background-image: url('/img/loader-car.svg');
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}
@keyframes move-loader-car {
  0% {
    offset-distance: 0%;
  }
  100% {
    offset-distance: 100%;
  }
}
.search {
  display: block;
  width: 225px;
  height: 25px;
  background-color: #e5e5e5;
  border-radius: 18px;
  box-shadow: inset 0px 1px 3px #565656;
  background-image: url('/img/search.svg');
  background-repeat: no-repeat;
  background-size: 16px 16px;
  background-position: right 10px center;
  margin: 0px auto 0px auto;
  padding: 0px 32px 0px 10px;
  border: none;
}
/* 2026-07-25 (Wave 4.5): shared confirm / delete dialog.
   Replaces the old uppercase, red-X, float-button panel with a
   compact card that matches the modern modal language (soft dim,
   pv tokens, sentence-case copy, primary green confirm). */
#confirmDialog {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 10000;
  box-sizing: border-box;
  width: min(420px, calc(100vw - 32px));
  min-height: 0;
  height: auto;
  padding: 28px 28px 24px;
  background: var(--pv-surface, var(--White));
  border: 1px solid var(--pv-line, var(--Light-grey-1));
  border-radius: var(--pv-radius, 14px);
  box-shadow: var(--pv-shadow-hi, 0 4px 10px rgba(16, 24, 40, 0.08), 0 20px 40px -18px rgba(16, 24, 40, 0.34));
  animation: pvFade 0.18s var(--pv-ease, ease) both;
}

#confirmDialogClose {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 1;
  width: 32px;
  height: 32px;
  margin: 0;
  padding: 0;
  border: none;
  border-radius: var(--pv-radius-pill, 999px);
  background: transparent;
  color: var(--pv-ink-soft, #6B7A83);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  transition: background-color 0.15s var(--pv-ease, ease), color 0.15s var(--pv-ease, ease);
}
#confirmDialogClose::before {
  content: "\00d7";
}
#confirmDialogClose:hover {
  background: var(--pv-bg-1, #EEF2F6);
  color: var(--pv-ink, #004346);
  opacity: 1;
}
#confirmDialogMessage {
  margin: 8px 8px 0;
  width: auto;
  color: var(--pv-ink, var(--Dark-grey-1));
  text-align: center;
  text-transform: none;
  font-weight: 500;
  font-size: 17px;
  line-height: 1.45;
  letter-spacing: -0.01em;
}
#confirmDialogMessage p,
#confirmDialogMessage h2 {
  margin: 0;
  font: inherit;
  font-weight: inherit;
  color: inherit;
  text-transform: none;
}
#confirmDialogOK,
#confirmDialogCancel {
  float: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  width: auto;
  min-width: 112px;
  margin: 0;
  padding: 11px 18px;
  border-radius: var(--pv-btn-radius);
  font-size: 14px;
  font-weight: var(--pv-btn-weight);
  line-height: 1.2;
  text-align: center;
  cursor: pointer;
  transition: var(--pv-btn-transition);
}
#confirmDialogOK a,
#confirmDialogCancel a {
  color: inherit;
  text-decoration: none;
  pointer-events: none;
}
#confirmDialogCancel {
  color: var(--pv-ink, #004346);
  background: var(--pv-surface, #fff);
  border: none;
  box-shadow: var(--pv-btn-ghost-ring);
}
#confirmDialogCancel:hover {
  background: var(--pv-btn-ghost-hover);
}
#confirmDialogOK {
  color: #fff;
  background-color: var(--pv-green, var(--Green));
  background-image: var(--pv-btn-grad);
  border: none;
  box-shadow: var(--pv-btn-shadow);
}
#confirmDialogOK:hover {
  transform: translateY(-1px);
  box-shadow: var(--pv-btn-shadow-hi);
}
#confirmDialogOK:active,
#confirmDialogCancel:active { transform: translateY(1px); }
#confirmDialogControls {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 10px;
  width: 100%;
  margin-top: 22px;
  text-transform: none;
}
.dialog {
  position: fixed;
  top: 0px;
  left: 0px;
  width: 100%;
  height: 100%;
  background-color: rgb(86, 86, 86, 0.8);
  z-index: 5000;
}
.dialog-content {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  border-radius: 11px;
  border: 1px solid gray;
  box-shadow: 0px 1px 3px #565656;
  overflow: hidden;
}
.dialog-header {
  width: calc(100% - 20px);
  background-color: var(--Red);
  color: white;
  font-weight: bold;
  font-size: 14px;
  padding: 10px 10px 10px 10px;
}
.dialog-close {
  position: fixed;
  width: 70px;
  height: 70px;
  right: 20px;
  top: 20px;
  background-image: url('/img/modsvg.php?close-black,ffffff');
  background-repeat: no-repeat;
  background-size: 70px 70px;
  cursor: pointer;
}
.dialog-body {
  padding: 10px 10px 10px 10px;
  width: calc(100% - 20px);
  background-color: white;
}

.button {
  transition: background-color 0.5s ease;
  background-color: var(--Red);
  color: var(--White);
  border: none;
  border-radius: 5px;
  font-size: 14px;
  padding: 7px 10px 7px 10px;
  cursor: pointer;
  margin: 0 auto;
}

.decor {
  transform: rotate(45deg);
}

#confirmDialogOverlay {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  background: rgba(11, 17, 19, 0.48);
  z-index: 9999;
  animation: pvFade 0.16s var(--pv-ease, ease) both;
}

/* 2026-08-20 (review #8 item 2): the shared dim layer behind a modal —
   modalScrim() in lib/carpoint/common.js puts it up and takes it down.

   The layers a dialog has to clear, lowest first: page content, side menu
   (1000), side drawers and their own scrims (1900/1910), this scrim (1990),
   the dialog itself (2000). Anything that must stay legible over an open
   dialog — the shared confirm (9999) and toasts (100000) — sits above.
   Dialogs that predate this went as low as z-index 100, under the side menu,
   so their backdrop dimmed the page but left the navigation bright. */
#pv-modal-scrim {
  position: fixed;
  inset: 0;
  background: rgba(11, 17, 19, 0.5);
  z-index: 1990;
  display: none;
}

#pv-modal-scrim.is-open {
  display: block;
  animation: pvFade 0.16s var(--pv-ease, ease) both;
}

.flex-row {
  display: flex;
  flex-direction: row;
}

.flex-col {
  display: flex;
  flex-direction: column;
}

.flex-gap {
  gap: 24px;
}

.inline-flex {
  display: inline-flex;
  flex-direction: row;
}

.gap-10 {
  gap: 10px;
}

.gap-100 {
  gap: 100px;
}

.space-between {
  justify-content: space-between;
}

.flex-width-256 {
  min-width: 256px;
}

.mb-24 {
  margin-bottom: 24px;
}

.flex-column{
  display: flex;
  flex-direction: column;
}

/* =====================================================================
   2026-07-25 — object picker.

   This is one component with many mount points: the reports vehicle
   picker, the tracking history and event-template pickers, the operator
   access list in settings, the dashboard widgets and the tasks panel.
   It is built by ObjPicker.createElement(), and every mount point loads
   this file through theme/template.php, so styling it here is what makes
   the redesign land everywhere at once. Six per-page copies of an
   object_picker.css used to shadow this, all drifted apart into three
   incompatible design families; they were deleted in favour of this one
   definition, since every page that loaded them also loads this file.

   The problems being fixed: a group header row and a vehicle row looked
   near enough identical that the list read as one flat run of text, and
   the only mark of selection was a 16px checkbox, which is far too small
   a signal to scan by. Groups now sit in a heavier band, rows are
   indented beneath them and carry their selection across the full width,
   and a summary line states the count outright.
   ===================================================================== */
.obj-picker {
  color: var(--pv-ink);
  /* Explicit, because the component is dropped into host modals that set
     their own alignment — the operator modal centres its content, which
     left the group bands and vehicle names centred in that one place. */
  text-align: left;
}

/* --- Left pane: group navigation ---------------------------------- */
.obj-picker .left{
  background-color: var(--pv-bg-1, #F4F7F9);
  border-right: 1px solid var(--pv-line);
	padding: 16px 14px;
	height: 100% !important;
	box-sizing: border-box;
	min-width: 176px;
}

/* 2026-07-24 (Wave 4.5): in Drivers mode a driver isn't tied to a vehicle
   group, so grouping the rows under vehicle-group headers is misleading.
   The .mode-drivers class (toggled in obj_picker.js when the Drivers switch
   is active) hides the left group panel and the per-group headers so the
   rows read as one flat driver list. Switching back to Vehicles restores it. */
.obj-picker.mode-drivers .left { display: none !important; }
.obj-picker.mode-drivers .right .group > .title { display: none; }
.obj-picker .left .group-title{
  color: var(--pv-ink-soft);
  padding: 0 8px 10px 8px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
	width: auto;
}
.obj-picker .left .group .title {
  transition: background-color 0.15s var(--pv-ease), color 0.15s var(--pv-ease),
    box-shadow 0.15s var(--pv-ease);
	display: flex;
	align-items: center;
	gap: 8px;
	width: auto;
  text-align: left;
  padding: 8px 10px;
  margin-bottom: 4px;
	cursor: pointer;
	border-radius: 9px;
  border: none;
  /* A transparent bar reserves the space the selected state fills, so the
     label doesn't shift sideways when a group is picked. */
  box-shadow: inset 3px 0 0 transparent;
  font-size: 13px;
  color: var(--pv-ink);
}
.obj-picker .left .group .title:hover{
  color: var(--pv-ink);
  background-color: var(--pv-icon-btn-hover);
}
.obj-picker .left .group .title.selected{
	background-color: var(--pv-green-bg);
	color: var(--pv-green-ink);
	font-weight: 700;
	box-shadow: inset 3px 0 0 var(--pv-green);
}
.obj-picker .left .group .title span{
	display: block;
}
.obj-picker .left .group .title .name{
	width: auto;
	flex: 1 1 auto;
	min-width: 0;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}
/* Count reads as a badge rather than a stray number at the far right. */
.obj-picker .left .group .title .item-count{
	flex: 0 0 auto;
	text-align: center;
	min-width: 20px;
	padding: 1px 6px;
	border-radius: 999px;
	background: rgba(0, 67, 70, 0.08);
	color: var(--pv-ink-soft);
	font-size: 11px;
	font-weight: 700;
}
.obj-picker .left .group .title.selected .item-count{
	background: var(--pv-green);
	color: #fff;
}

/* --- Right pane -------------------------------------------------- */
/* Column layout so the scrolling list simply takes the space the panel
   and summary leave. Every mount point used to hand-compute this as
   `height: calc(100% - Npx) !important` with a different N, which is why
   adding a row to the chrome used to require touching four stylesheets. */
.obj-picker .right{
	display: flex;
	flex-direction: column;
	min-height: 0;
}
.obj-picker .right .panel{
	flex: 0 0 auto;
	width: auto;
	margin: 0;
	padding: 14px 16px 10px 16px;
}
.obj-picker .switch{
	display: flex;
	gap: 4px;
	margin: 0px auto 10px auto;
	padding: 3px;
	border-radius: 999px;
	background: var(--pv-bg-1, #F4F7F9);
	box-shadow: inset 0 0 0 1px var(--pv-line);
}
.obj-picker .switch button{
	flex: 1 1 0;
	background-color: transparent;
	color: var(--pv-ink-soft);
	width: auto;
	text-align: center;
	font-family: inherit;
	font-size: 12px;
	font-weight: 700;
	padding: 7px 8px;
	cursor: pointer;
	border-radius: 999px;
	border: none;
	transition: background-color 0.15s var(--pv-ease), color 0.15s var(--pv-ease);
}
.obj-picker .switch button:hover{
	color: var(--pv-ink);
}
.obj-picker .switch button.enabled{
	background-color: var(--pv-surface);
	color: var(--pv-ink);
	box-shadow: var(--pv-btn-raise-lo);
}
.obj-picker .filter{
  transition: border-color 0.15s var(--pv-ease), box-shadow 0.15s var(--pv-ease);
	background-image: url('/img/filter.svg');
  background-repeat: no-repeat;
	background-position: 12px center;
  padding: 9px 14px 9px 38px;
  border: 1px solid var(--pv-line-strong);
  border-radius: var(--pv-radius-sm, 10px);
	width: 100%;
	box-sizing: border-box;
	font-family: inherit;
	font-size: 13px;
	color: var(--pv-ink);
	margin: 0;
}
.obj-picker .filter:hover {
  border-color: var(--pv-green);
}
.obj-picker .filter:focus {
  outline: none;
  border-color: var(--pv-green);
  box-shadow: 0 0 0 3px rgba(68, 168, 140, 0.22);
}

/* --- Selection summary ------------------------------------------- */
.obj-picker .summary{
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 10px;
	flex: 0 0 auto;
	padding: 8px 16px;
	border-top: 1px solid var(--pv-line);
	border-bottom: 1px solid var(--pv-line);
	background: var(--pv-bg-1, #F4F7F9);
}
.obj-picker .summary .count{
	font-size: 12px;
	font-weight: 700;
	color: var(--pv-ink-soft);
	white-space: nowrap;
}
.obj-picker .summary.has-selection .count{
	color: var(--pv-green-ink);
}
.obj-picker .summary .actions{
	display: flex;
	gap: 6px;
	flex: 0 0 auto;
}
.obj-picker .summary button{
	background: transparent;
	border: none;
	padding: 4px 8px;
	border-radius: 7px;
	font-family: inherit;
	font-size: 12px;
	font-weight: 700;
	color: var(--pv-green-ink);
	cursor: pointer;
	transition: background-color 0.15s var(--pv-ease);
}
.obj-picker .summary button:hover{
	background: var(--pv-green-bg);
}
.obj-picker .summary button.clear-all{
	color: var(--pv-ink-soft);
}
.obj-picker .summary button.clear-all:hover{
	background: var(--pv-icon-btn-hover);
	color: var(--pv-ink);
}

/* --- Object list -------------------------------------------------- */
.obj-picker .right .list{
	flex: 1 1 auto;
	min-height: 0;
	height: auto !important;
	padding: 8px 12px 12px 12px;
}
/* The group band is the anchor the eye scans by, so it is deliberately
   heavier than the rows under it: darker fill, bolder and smaller caps
   type, and it spans the full width while rows are indented. */
.obj-picker .right .group .title{
	cursor: pointer;
	align-items: center;
  margin: 12px 0 4px 0;
  background-color: #E4EDF0;
	border-radius: 8px;
	padding: 8px 10px;
	color: var(--pv-ink);
	font-size: 11px;
	font-weight: 800;
	letter-spacing: 0.05em;
	text-transform: uppercase;
}
.obj-picker .right .group .title:hover{
	background-color: #DAE6EB;
}
.obj-picker .right .group .title.is-selected{
	background-color: var(--pv-green-bg-hi, #D8ECE4);
	color: var(--pv-green-ink);
}
/* A collapsed group with some but not all of its rows ticked would
   otherwise look identical to one with nothing ticked. */
.obj-picker .right .group .title.is-partial{
	box-shadow: inset 3px 0 0 var(--pv-green);
}
.obj-picker .right .group .title .name{
	flex: 1 1 auto;
	min-width: 0;
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
}
.obj-picker .right .group .title, .right .object{
	cursor: pointer;
	display: flex;
	position: relative;
  gap: 10px;
}
/* 2026-07-25: the chevron is an indicator, not the target — the whole
   header collapses the group (see obj_picker.js). It is laid out as a
   flex item so it is genuinely centred on the bar's midline; it used to
   be absolutely positioned at a fixed `top` and sat noticeably high. */
.obj-picker .right .group .collapse {
	position: static;
	flex: 0 0 auto;
	width: 16px;
	height: 16px;
	padding: 0;
	background-image: url('/img/modsvg.php?group-open,004346');
	background-repeat: no-repeat;
	background-position: center;
  background-color: transparent;
	border: none;
	cursor: pointer;
	opacity: 0.6;
	transition: transform 0.3s var(--pv-ease), opacity 0.15s var(--pv-ease);
}
.obj-picker .right .group .title:hover .collapse { opacity: 1; }
.obj-picker .right .group .collapse.group-closed{
  transform: rotate(-90deg);
}
/* Rows are indented under their band, so the hierarchy is legible even
   when a group scrolls off the top of the list. */
.obj-picker .object{
	align-items: center;
	padding: 7px 10px;
	margin: 2px 0 2px 10px;
	border-radius: 8px;
	box-shadow: inset 3px 0 0 transparent;
	transition: background-color 0.12s var(--pv-ease), box-shadow 0.12s var(--pv-ease);
}
.obj-picker .object:hover{
	background-color: var(--pv-icon-btn-hover);
}
/* Selection reads across the whole row, not off a 16px box. */
.obj-picker .object.is-selected{
	background-color: var(--pv-green-bg);
	box-shadow: inset 3px 0 0 var(--pv-green);
}
.obj-picker .object.is-selected:hover{
	background-color: var(--pv-green-bg-hi, #D8ECE4);
}
.obj-picker .object img{
	display: block;
	flex: 0 0 auto;
	width: 18px;
	height: 18px;
	opacity: 0.55;
}
.obj-picker .object.is-selected img{
	opacity: 1;
}
.obj-picker .object .label{
	flex: 1 1 auto;
	min-width: 0;
	font-size: 13px;
	overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.obj-picker .object.is-selected .label{
	color: var(--pv-green-ink);
	font-weight: 700;
}
.obj-picker .object .checkbox, .group .checkbox{
	margin: auto 0px;
  line-height: normal;
  min-width: 16px;
  min-height: 16px;
}
.obj-picker .object .settings, .group .settings{
	display: none;
}

.toast-popup {
    transition: var(--Ease-transition);
    padding: 20px 40px 20px 20px;
    color: var(--White);
    font-size: 14px;
    text-align: left;
	  background-image: url('/img/modsvg.php?alert,FFFFFF');
    background-position: right 10px center;
    background-repeat: no-repeat;
    background-size: 16px 16px;
    box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
    border-radius: 12px;	
}

.toast-popup.success-popup {
  background-color: var(--Green);
}

.toast-popup.error-popup {
  background-color: var(--Red);
  background-image: url('/img/modsvg.php?alert,FFFFFF');
}

.toast-popup.info-popup {
  background-color: var(--Dark-grey-1);
  background-image: url('/img/modsvg.php?alert,FFFFFF');
}

/* 2026-08-05: 'warning' was already being asked for by three call sites and had no
   rule at all, so `.toast-popup.warning-popup` matched nothing and the toast came out
   with no background colour — white-on-transparent text over whatever it happened to
   cover. The type is worth having rather than folding into the two that exist: "none
   of these vehicles has a driver in it" is neither a success nor an error, and calling
   it either teaches the operator to distrust the colour. */
.toast-popup.warning-popup {
  background-color: #B45309;
  background-image: url('/img/modsvg.php?alert,FFFFFF');
}

/* ============================================================
   Rich event toast — pushed by tracking/js/events_init.js.

   2026-05-16 v2: redesigned as a white card to match the email
   notification's structure + readability instead of the v1 solid
   green block (which read as a generic alert pill). Layout:

     ┌──────────────────────────────────────────────────┐
     │ ▌ <Event title>                              🔔 │  ← green left
     │   ────────────────────────────                  │    border + bell
     │   Vehicle  demo_US (AA00AA)                     │  ← label-value
     │   Driver   Jane                                 │    rows, light
     │   Time     2026-05-16 03:23:29                  │    grey labels
     │   <italic event description>                    │  ← optional
     └──────────────────────────────────────────────────┘

   The base .toast-popup defines color: white + alert background, both
   of which we have to undo because they're set as inline `style=` /
   CSS on the parent. !important on a handful of properties is the
   trade-off for not refactoring the shared widget. */
.toast-popup.event-popup {
  background-color: #fff !important;
  background-image: url('/img/modsvg.php?event-notification-enable,44A88C') !important;
  background-size: 20px 20px;
  background-position: right 16px top 16px;
  background-repeat: no-repeat;
  color: var(--Dark-grey-1);
  justify-content: flex-start !important;
  align-items: stretch !important;
  text-align: left;
  padding: 14px 52px 14px 18px; /* extra right pad so text never runs under the bell */
  border-left: 4px solid var(--Red); /* --Red is brand green #44A88C */
  border-radius: 6px;
  box-shadow: 0 4px 14px rgba(0, 78, 81, 0.15); /* subtle teal-tinted depth */
  flex-direction: column;
}
.event-toast-title {
  font-weight: 700;
  font-size: 14px;
  line-height: 1.2;
  color: var(--Dark-grey-1);
  padding-bottom: 6px;
  margin-bottom: 6px;
  border-bottom: 1px solid var(--Light-grey-2);
}
.event-toast-row {
  font-size: 12px;
  line-height: 1.5;
  display: flex;
  gap: 8px;
  color: var(--Dark-grey-1);
}
.event-toast-label {
  flex: 0 0 56px;
  color: var(--Light-grey-4);
  font-weight: 600;
  text-transform: uppercase;
  font-size: 10px;
  letter-spacing: 0.4px;
  padding-top: 1px; /* visually align label baseline with value */
}
.event-toast-plate {
  color: var(--Light-grey-4);
}
.event-toast-desc {
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid var(--Light-grey-2);
  font-style: italic;
  color: var(--Light-grey-4);
  display: block; /* override the flex row layout — desc is a paragraph, not a label/value pair */
}

#tutorial-spotlight{
	position: absolute;
	top: 0;
	left: 0;
	width: 100vw;
	height: 100vh;
	z-index: 5000;
}
#tutorial-spotlight-focus{
	position: absolute;
	width: 0px;
	height: 0px;
	top: 0px;
	left: 0px;
	box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.5);
	border-radius: 12px;
	border: 1px solid white;
	overflow: hidden;
}
#tutorial-spotlight-focus-inside{
    width: 100%;
    height: 100%;
    box-shadow: 0 0 20px 12px rgba(0, 0, 0, 0.2) inset;
}
#tutorial-spotlight-close{
	position: absolute;
	right: 10px;
	top: 10px;
	width: 30px;
	height: 30px;
	background-image: url('/img/modsvg.php?close-black,FFFFFF');
	background-repeat: no-repeat;
	cursor: pointer;
}
#tutorial-spotlight-message{
	position: absolute;
	left: 0px;
	top: 0px;
	padding: 20px;
	background-color: var(--Red);
	color: var(--White);
	font-size: 14px;
	width: 400px;
	border-radius: 12px;
	box-shadow: 0px 0px 5px 0px var(--White);
	text-align: justify;
}
#tutorial-spotlight-intro{
	position: absolute;
	left: 50%;
	top: 50%;
	transform: translate(-50%, -50%);
	background-color: var(--Red);
	color: var(--White);
	font-size: 16px;
	width: 460px;
	border-radius: 12px;
	box-shadow: 0px 0px 5px 0px var(--White);
	text-align: center;
	padding: 20px;
}
#tutorial-spotlight-intro_button{
	width: 130px;
	margin: 30px auto 0px auto;
	padding: 10px 16px;
	cursor: pointer;
	border: 1px solid var(--White);
	border-radius: 12px;
}
@media (max-width: 1920px) {
  .obj-picker .right {
    padding: 0;
  }
  .obj-picker .switch button {
    width: 128px;
    font-size: 10px;
    margin-right: 8px;
  }
  .obj-picker .right .panel {
    width: 242px;
    margin: auto;
  }
  .obj-picker .filter {
    width: 200px;
    padding: 4px 8px;
    text-indent: 24px;
    background-position: 10px 8px;
    font-size: 12px;
  }
  .obj-picker .right .group .title{
    font-size: 12px;
    padding: 4px 8px;
  }
  .checkbox {
    width: 10px;
    height: 10px;
  }
  .checkbox-checked{
    background-image: url(/img/check.svg);
    background-color: var(--Red);
    background-position: 1px 1px;
    background-size: 10px;
    border: 1px solid var(--Red);
    background-repeat: no-repeat;
    min-width: 12px;
    min-height: 12px;
  }
  .obj-picker .object .checkbox, .group .checkbox {
    min-width: 12px;
    min-height: 12px;
  }
  .obj-picker .right .group .collapse {
    top: 10px;
    width: 10px;
    height: 10px;
    background-size: 10px;
  }
  /* 2026-07-28: #event-item-list is /tracking's event-template list and its
     geometry belongs with the page, not in the shared theme — it was 200px wide
     with 24px of right padding against 2px of left, which is what pushed the
     template rows off-centre in the sidebar. Sizing now comes from the
     sidebar's content column (tracking.css); only the vertical rhythm is left. */
  #event-item-list {
    padding: 6px 0;
  }
}

/* =====================================================================
   2026-07-24 (Wave 4.5) — unified "modern" design tokens.
   Mirrors the /home dashboard + /reminders refresh (softer depth, rounder
   corners) so the rest of the app can adopt the same visual language
   incrementally, page by page. These are ADDITIVE: declaring them changes
   nothing until a page opts in by referencing var(--pv-*) or by
   re-scoping --Red locally.

   2026-07-25: repointed at the Periva brand book. Wave 4.5 had invented
   its own green, dark green and ink, none of which appear in the brand
   palette — the LEGACY variables were the correct ones all along
   (--Red #44A88C and --Dark-grey-3 #3CBA58 are both brand colours).
   Every value below is either a brand hex or a tint/shade of one, noted
   where it is derived.
     Primary   #004346  #44A88C  #000000  #FFFFFF
     Secondary #0B1926  #172A3A  #3A4B5A  #637788  #A8B6C1  #D4DCE2
               #3CBA58  #FBB13C  #DBEF00  #F02F3B                     */
:root {
	--pv-ink: #004346;
	--pv-ink-soft: #637788;
	--pv-green: #44A88C;
	--pv-green-dk: #3A8F77;      /* shade of #44A88C, gradient bottom stop */
	--pv-green-br: #3CBA58;      /* brand's brighter green, positive accents */
	--pv-green-bg: #E8F5F0;      /* tint of #44A88C, soft fills */
	--pv-green-bg-hi: #D8ECE4;   /* one step deeper, hover on soft fills */
	--pv-green-ink: #2F7A65;     /* shade of #44A88C dark enough to read as text on --pv-green-bg */
	--pv-line: #D4DCE2;
	--pv-line-strong: #A8B6C1;
	--pv-surface: #FFFFFF;
	--pv-bg-1: #EFF3F6;          /* tint of #D4DCE2, canvas top */
	--pv-bg-2: #D4DCE2;
	--pv-radius: 14px;
	--pv-radius-sm: 10px;
	--pv-radius-pill: 999px;
	--pv-shadow: 0 1px 2px rgba(16, 24, 40, 0.05), 0 12px 28px -16px rgba(16, 24, 40, 0.28);
	--pv-shadow-hi: 0 4px 10px rgba(16, 24, 40, 0.08), 0 20px 40px -18px rgba(16, 24, 40, 0.34);
	--pv-ease: cubic-bezier(0.22, 1, 0.36, 1);
}

/* Shared entrance keyframes used by the per-page refresh blocks. */
@keyframes pvRise {
	from { opacity: 0; transform: translateY(12px); }
	to   { opacity: 1; transform: translateY(0); }
}
@keyframes pvFade {
	from { opacity: 0; }
	to   { opacity: 1; }
}

/* =====================================================================
   2026-07-25 (Wave 4.5) — shared control recipe.

   /reminders/ is the reference implementation of the modern look, but
   every other page had re-derived its own button treatment during its
   refresh (flat fill vs gradient, 8/10 vs 11px radius, weight 600 vs
   700, four different green shadows, no press feedback). The result was
   a family resemblance rather than a match.

   These tokens lift the /reminders values out of reminders.css so the
   rest of the app consumes ONE definition. Pages adopt them by pointing
   their existing button selectors at the tokens inside their own Wave
   4.5 block — no markup changes, so page layout is untouched.
   ===================================================================== */
:root {
	/* 2026-08-01. One height for every control that can sit in a row with another
	   one — search boxes, selects, date fields, buttons. They were each sized by
	   their own padding and font size before, which put a 36px dropdown next to a
	   39px button next to a 40px date input, and the toolbars read as slightly
	   broken in a way that is hard to point at but easy to see. */
	--pv-control-h: 40px;
	--pv-btn-radius: 11px;
	--pv-btn-weight: 700;
	--pv-btn-pad: 11px 18px;
	--pv-btn-grad: linear-gradient(180deg, var(--pv-green) 0%, var(--pv-green-dk) 100%);
	--pv-btn-shadow: 0 8px 18px -8px rgba(68, 168, 140, 0.75);
	--pv-btn-shadow-hi: 0 12px 24px -8px rgba(68, 168, 140, 0.85);
	/* Secondary/ghost. 2026-07-25: these were a hairline inset ring, which
	   on a white pill sitting on the pale canvas read as a disabled input —
	   the button all but disappeared. They are raised instead, with enough
	   depth to separate from the background at a glance. The shadow is
	   tinted with brand ink rather than neutral grey so it stays warm
	   against the teal canvas. Each is a two-part light: an ambient ring
	   with no offset, which is what makes the TOP edge of a white button
	   readable on a white card, plus the offset key light below it. A
	   purely downward shadow left the top edge dissolving into the
	   surface wherever the button sat on white rather than the canvas. */
	--pv-btn-raise: 0 0 7px rgba(0, 67, 70, 0.16),
		0 4px 10px -2px rgba(0, 67, 70, 0.28),
		0 1px 3px rgba(0, 67, 70, 0.16);
	--pv-btn-raise-hi: 0 0 10px rgba(0, 67, 70, 0.20),
		0 10px 22px -6px rgba(0, 67, 70, 0.36),
		0 2px 5px rgba(0, 67, 70, 0.16);
	--pv-btn-raise-lo: 0 0 5px rgba(0, 67, 70, 0.16),
		0 1px 3px -1px rgba(0, 67, 70, 0.30);
	--pv-btn-ghost-ring: var(--pv-btn-raise);
	--pv-btn-ghost-hover: #F2F5F7;
	/* Destructive + warning are straight from the brand secondaries. */
	--pv-danger: #F02F3B;
	--pv-danger-dk: #C9202B;     /* shade of #F02F3B */
	--pv-danger-bg: #FDEAEC;     /* tint of #F02F3B */
	--pv-warn: #FBB13C;
	/* Quiet icon affordances (edit / delete / close). */
	--pv-icon-btn-size: 30px;
	--pv-icon-btn-hover: #EDF1F4;
	--pv-btn-transition: transform 0.15s var(--pv-ease), box-shadow 0.2s var(--pv-ease),
		background-color 0.2s var(--pv-ease), border-color 0.15s var(--pv-ease),
		color 0.15s var(--pv-ease), filter 0.15s var(--pv-ease);
}

/* Ready-made classes for new markup. Pages with their own button class
   names map onto the same declarations instead of using these. */
.pv-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 7px;
	box-sizing: border-box;
	min-height: var(--pv-control-h);
	padding: var(--pv-btn-pad);
	border: none;
	border-radius: var(--pv-btn-radius);
	font-family: inherit;
	font-size: 14px;
	font-weight: var(--pv-btn-weight);
	line-height: 1.2;
	text-decoration: none;
	cursor: pointer;
	transition: var(--pv-btn-transition);
}
.pv-btn[disabled] { opacity: 0.5; cursor: not-allowed; }

.pv-btn-primary {
	background-color: var(--pv-green);
	background-image: var(--pv-btn-grad);
	color: #fff;
	box-shadow: var(--pv-btn-shadow);
}
.pv-btn-primary:hover:not([disabled]) {
	transform: translateY(-1px);
	box-shadow: var(--pv-btn-shadow-hi);
}

.pv-btn-ghost {
	background: var(--pv-surface);
	color: var(--pv-ink);
	box-shadow: var(--pv-btn-raise);
}

/* Small. For buttons inside a popup or a row, where a full-height one would
   dominate whatever it sits next to — the date picker's Clear and Today, say. */
.pv-btn-sm {
	min-height: 32px;
	padding: 7px 13px;
	font-size: 13px;
}
.pv-btn-ghost:hover:not([disabled]) {
	background: var(--pv-btn-ghost-hover);
	transform: translateY(-1px);
	box-shadow: var(--pv-btn-raise-hi);
}
.pv-btn-ghost:active:not([disabled]) { box-shadow: var(--pv-btn-raise-lo); }

.pv-btn-danger {
	background: var(--pv-danger);
	color: #fff;
}
.pv-btn-danger:hover:not([disabled]) { background: var(--pv-danger-dk); }

/* Press feedback is declared after the variants so it wins over their
   hover lift (a mouse press is always also a hover). */
.pv-btn:active:not([disabled]) { transform: translateY(1px); }

.pv-icon-btn {
	display: grid;
	place-items: center;
	width: var(--pv-icon-btn-size);
	height: var(--pv-icon-btn-size);
	padding: 0;
	border: none;
	border-radius: 8px;
	/* background-color, not the `background` shorthand.
	 *
	 * 2026-08-01: it was the shorthand, and that is what made the row actions on
	 * /routes/ and the sites list look wrong the moment the pointer touched them.
	 * Those buttons carry their icon as a background-image and set position, size
	 * and repeat on .site-act — one class, so weaker than .pv-icon-btn:hover. The
	 * shorthand here reset all three back to their defaults for the length of the
	 * hover, and a 16px icon that suddenly tiles from the top-left corner reads as
	 * a rendering fault rather than a hover state. Setting only the colour leaves
	 * everything the icon needs alone. */
	background-color: transparent;
	color: var(--pv-ink-soft);
	cursor: pointer;
	transition: background-color 0.15s var(--pv-ease), color 0.15s var(--pv-ease);
}
.pv-icon-btn:hover {
	background-color: var(--pv-icon-btn-hover);
	color: var(--pv-ink);
}
.pv-icon-btn-danger:hover {
	background-color: var(--pv-danger-bg);
	color: var(--pv-danger);
}

@media (prefers-reduced-motion: reduce) {
	.pv-btn,
	.pv-btn:hover:not([disabled]),
	.pv-btn:active:not([disabled]) { transform: none; transition: none; }
}
/* ==================================================== checkboxes ======== *
 *
 * 2026-08-01. The routes pages were using the browser's own checkbox, which
 * draws a blue box on Chrome and a grey one on Safari — the one control on the
 * page that owed nothing to the design system, and the only blue anywhere near
 * it.
 *
 * Built from the same measurements as the app's long-standing div.checkbox (16px,
 * 3px corners, white, /img/check.svg on a filled ground) so it reads as the same
 * control as the ones on /reports. The fill is green rather than that one's red:
 * red is the old palette, and on a page where every other accent — focus rings,
 * hover borders, the primary button — is green, a red tick would look like a
 * warning rather than a yes.
 *
 * Scoped to the newer pages. The old ones toggle a class on a div and never see
 * a real checkbox, so a global rule would have nothing to do there. */
#routes-page input[type="checkbox"],
#routes-page input[type="radio"],
.modal-overlay input[type="checkbox"],
.modal-overlay input[type="radio"] {
	appearance: none;
	-webkit-appearance: none;
	box-sizing: border-box;
	flex: none;
	width: 16px;
	height: 16px;
	margin: 0;
	border: 1px solid var(--pv-line-strong);
	border-radius: 3px;
	background: var(--pv-surface);
	cursor: pointer;
	transition: background-color 0.15s var(--pv-ease), border-color 0.15s var(--pv-ease),
	            transform 0.15s var(--pv-ease);
}
#routes-page input[type="radio"],
.modal-overlay input[type="radio"] { border-radius: 50%; }

#routes-page input[type="checkbox"]:hover:not(:disabled),
#routes-page input[type="radio"]:hover:not(:disabled),
.modal-overlay input[type="checkbox"]:hover:not(:disabled),
.modal-overlay input[type="radio"]:hover:not(:disabled) {
	border-color: var(--pv-green);
	/* The same 1.1 nudge div.checkbox has, which is how the app has always said a
	   tick box is live. */
	transform: scale(1.1);
}

#routes-page input[type="checkbox"]:checked,
.modal-overlay input[type="checkbox"]:checked {
	border-color: var(--pv-green);
	background: var(--pv-green) url(/img/check.svg) no-repeat center;
}
#routes-page input[type="radio"]:checked,
.modal-overlay input[type="radio"]:checked {
	/* A dot rather than a tick, drawn with an inset ring so it needs no
	   pseudo-element — a replaced input cannot carry one. */
	border-color: var(--pv-green);
	background: var(--pv-green);
	box-shadow: inset 0 0 0 3px var(--pv-surface);
}

#routes-page input[type="checkbox"]:focus-visible,
#routes-page input[type="radio"]:focus-visible,
.modal-overlay input[type="checkbox"]:focus-visible,
.modal-overlay input[type="radio"]:focus-visible {
	border-color: var(--pv-green);
	box-shadow: 0 0 0 3px rgba(68, 168, 140, 0.16);
	outline: none;
}
#routes-page input[type="radio"]:checked:focus-visible,
.modal-overlay input[type="radio"]:checked:focus-visible {
	box-shadow: inset 0 0 0 3px var(--pv-surface), 0 0 0 3px rgba(68, 168, 140, 0.16);
}

#routes-page input[type="checkbox"]:disabled,
#routes-page input[type="radio"]:disabled,
.modal-overlay input[type="checkbox"]:disabled,
.modal-overlay input[type="radio"]:disabled {
	background-color: var(--pv-bg-1);
	border-color: var(--pv-line);
	cursor: default;
	transform: none;
}
#routes-page input[type="checkbox"]:disabled:checked,
.modal-overlay input[type="checkbox"]:disabled:checked {
	/* Still legibly ticked when read-only, just muted — a dispatched route shows
	   its settings without offering them. */
	background-color: var(--pv-line-strong);
	border-color: var(--pv-line-strong);
}

/* ============================================== date fields (PvDate) ====

   2026-08-01. `<input type="date">` draws a different calendar in every browser,
   none of them ours, and on Chrome a control whose height cannot be matched to the
   selects beside it. /reminders/ and /drivers/ each solved that by hand with the
   shared DateRangeSingleMonth widget; app/pvdate.js is that pattern extracted, and
   these are its styles, here rather than in a page stylesheet so the next page to
   adopt it copies nothing.

   The grid rules below are the ones from tracking/css/tracking.css, which is where
   /reminders/ and /drivers/ took theirs from, so all four calendars in the product
   lay out identically. */

/* The visible field. Deliberately built from the same measurements as
   .routes-filters select so a date sits level with a dropdown beside it. */
.pv-datefield {
	box-sizing: border-box;
	display: block;
	width: 100%;
	height: var(--pv-control-h);
	padding: 0 32px 0 11px;
	border: 1px solid var(--pv-line-strong);
	border-radius: var(--pv-radius-sm);
	background: var(--pv-surface);
	color: var(--pv-ink);
	font: inherit;
	font-size: 13px;
	text-align: left;
	cursor: pointer;
	box-sizing: border-box;
	transition: border-color .15s var(--pv-ease), box-shadow .15s var(--pv-ease);
	position: relative;
}

/* A calendar glyph drawn in CSS: two ticks for the binding and a ruled box. Cheaper
   than an icon request and it inherits the text colour, so the disabled and empty
   states need no second asset. */
.pv-datefield::after {
	content: '';
	position: absolute;
	right: 11px;
	top: 50%;
	width: 11px;
	height: 11px;
	margin-top: -6px;
	border: 1.4px solid var(--pv-ink-soft);
	border-radius: 2px;
	border-top-width: 3.2px;
	opacity: .75;
}

.pv-datefield:hover  { border-color: var(--pv-line-strong); }
.pv-datefield:focus  { outline: none; border-color: var(--pv-green); box-shadow: 0 0 0 3px rgba(68, 168, 140, 0.16); }
.pv-datefield.empty  { color: var(--pv-ink-soft); }

.pv-datefield:disabled {
	background: var(--pv-bg-1);
	color: var(--pv-ink-soft);
	cursor: default;
}

/* The popup */

/* 2026-08-12: was 900/901, which put it *behind* any modal (z:2000) that contained a
   date field — the calendar opened and was invisible, so the field looked dead. It has
   to outrank every container it can be opened from, and since it is a transient popup
   that closes on the next click there is no case where something else should cover it.
   Below the tutorial spotlight (9999) and the toasts (10000) on purpose. */
.pv-cal-veil {
	position: fixed;
	inset: 0;
	z-index: 5100;
	background: transparent;
}

.pv-cal {
	position: fixed;
	z-index: 5101;
	width: 320px;
	background: var(--pv-surface);
	border: 1px solid var(--pv-line);
	border-radius: var(--pv-radius);
	box-shadow: var(--pv-shadow-hi);
	animation: pvFade 0.14s var(--pv-ease) both;
}

.pv-cal-body { padding: 12px 12px 0; }

/* The widget lays its weeks out from a measured grid height, so this box has to
   have a real one — see the note in pvdate.js about opening the popup first. */
.pv-cal-grid { height: 300px; }

.pv-cal-foot {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 10px;
	padding: 10px 12px 12px;
	border-top: 1px solid var(--pv-line);
	margin-top: 10px;
}

.pv-cal-picked {
	font-size: 13px;
	font-weight: 600;
	color: var(--pv-ink);
}

.pv-cal-acts { display: flex; gap: 6px; }

/* DateRangeSingleMonth chrome, from tracking/css/tracking.css. */

.pv-cal .daterange .year {
	font-weight: 700;
	font-size: 14px;
	text-align: center;
	color: var(--pv-ink);
}
.pv-cal .daterange .weekday {
	text-align: center;
	font-size: 11px;
	color: var(--pv-ink-soft);
	padding: 5px;
}
.pv-cal .daterange .header { border-bottom: 1px solid var(--pv-line); }
.pv-cal .daterange .day {
	text-align: center;
	background: var(--pv-surface);
	position: relative;
}
.pv-cal .daterange .day-label {
	height: calc(100% - 10px);
	color: var(--pv-ink);
	padding-top: 10px;
	position: relative;
	z-index: 1;
	font-size: 13px;
}
.pv-cal .daterange .week { height: 40px; }
.pv-cal .daterange .week .day.disabled .day-label { display: none; }

/* Days outside the month being looked at, dimmed rather than hidden so the weeks
   keep their shape. */
.pv-cal .daterange .day-label { color: var(--pv-ink-soft); }
.pv-cal .daterange .current-month .day-label { color: var(--pv-ink); }

/* The selection, drawn as a circle on the cell rather than the label, so it centres
   regardless of the label's own padding. The shared
   calendar-range-startend.svg is 50x50 in the old CarPoint red and overflows a cell
   this size — same reasoning as the note in drivers/css/drivers.css. */
.pv-cal .daterange .week .day.selected::before {
	content: '';
	position: absolute;
	left: 50%;
	top: 50%;
	width: 30px;
	height: 30px;
	border-radius: 50%;
	background: var(--pv-green);
	transform: translate(-50%, -50%);
	z-index: 0;
}
.pv-cal .daterange .week .day.selected .day-label {
	color: #fff;
	font-weight: 700;
}
.pv-cal .daterange .day-label.current-date {
	color: var(--pv-green);
	font-weight: 700;
}
.pv-cal .daterange .week .day.selected .day-label.current-date { color: #fff; }

.pv-cal .daterange .week .day:hover:not(.selected)::before {
	content: '';
	position: absolute;
	left: 50%;
	top: 50%;
	width: 30px;
	height: 30px;
	border-radius: 50%;
	background: var(--pv-green-bg);
	transform: translate(-50%, -50%);
	z-index: 0;
}
