/* Payroll styles (project-owned). Loaded after the framework's custom.css on
   every page and in a report's new tab (pages/header.php, pages/report_tab.php).
   Moved here from custom.css when Payroll adopted the template (2026-10-05). */

/* ==========================
   PAYSLIP REPORT (renderPayslipReport() in include/helpers/payroll.php)
   Lives here (not an inline <style> in the render function) so "View in New
   Tab" (include/asset.php's viewInNewTabButton() / src/mjs/helper.mjs's
   openReportInNewTab()) picks it up for free via the <link> tags it already
   clones — an inline <style> block wasn't reliably surviving that clone.
   ========================== */
.payslip-report {
	margin-top: 32px;
}
.payslip-report .row {
	max-width: 1280px;
	margin-left: auto;
	margin-right: auto;
}
/* g-4's negative row margin would push the cards' top border above the scroll area. */
.payslip-report > .row {
	--bs-gutter-x: 0;
	--bs-gutter-y: 0;
}
/* This wrapper only exists so print can group every 2 cards into their own
   atomic row (see .payslip-print-row under @media print below) - on screen
   it stays invisible via display:contents, so Bootstrap's .row/.col-md-6
   grid lays out every .col-md-6 as if it weren't there. */
.payslip-print-row {
	display: contents;
}
/* Explicit gutter, not Bootstrap's own .g-4 - Bootstrap applies its gutter
   padding/margin via the direct-child selector `.row > *`, which no longer
   matches .col-md-6 once display:contents interposes .payslip-print-row as
   an extra (invisible-but-real) DOM level between .row and .col-md-6. */
.payslip-report .col-md-6 {
	padding: 4px;
}
.payslip-card {
	border: 1px solid #333;
	padding: 12px 16px;
	height: 100%;
	font-size: 0.85rem;
	font-weight: 400;
	/* Column layout so the signature block can sit at the card's bottom. */
	display: flex;
	flex-direction: column;
}
/* Normal payslip text is weight 400 (something upstream renders it at 300).
   Kept before the other .payslip-* rules so their bold weights still win. */
.payslip-card div,
.payslip-card span,
.payslip-card td {
	font-weight: inherit;
}
/* Payslip text is pure black in light mode (incl. the always-light new tab)
   and pure white in dark mode. */
.payslip-card,
.payslip-card * {
	color: #000 !important;
}
[data-theme="dark"] .payslip-card,
[data-theme="dark"] .payslip-card * {
	color: #fff !important;
}
.payslip-header {
	display: flex;
	align-items: center;
	gap: 10px;
	border-bottom: 2px solid #333;
	padding-bottom: 6px;
	margin-bottom: 6px;
}
.payslip-logo {
	height: 36px;
	width: auto;
}
.payslip-company-name {
	font-weight: 700;
}
.payslip-meta {
	width: 100%;
	margin-bottom: 6px;
}
.payslip-meta td:first-child {
	white-space: nowrap;
	font-weight: 600;
	padding-right: 4px;
}
.payslip-body {
	width: 100%;
	border-collapse: collapse;
}
.payslip-body > tbody > tr > th,
.payslip-body > tr > th {
	text-align: left;
	border-bottom: 1px solid #333;
	padding-bottom: 2px;
}
.payslip-lines {
	width: 100%;
}
.payslip-lines td {
	padding: 1px 4px;
}
/* A heading section (ALLOWANCES, ADJUSTMENTS, ...) gets the same gap above
   and below; two sections in a row share one gap instead of doubling it. */
.payslip-lines .payslip-section-head td {
	padding-top: 0.25rem;
}
.payslip-lines .payslip-section-end td {
	padding-bottom: 0.25rem;
}
.payslip-lines .payslip-section-end + .payslip-section-head td {
	padding-top: 0.25rem;
}
.payslip-subtotal td {
	border-top: 1px solid #333;
	font-weight: 700;
	padding-top: 4px;
}
/* Column alignment: the line items sit in an inner table whose cells are
   inset 4px, so every other row (headings, subtotals, NET PAY) gets the same
   4px inset and the gap between the two columns is 16px on each side. */
.payslip-body > tbody > tr > :first-child {
	padding-left: 4px;
	padding-right: 16px;
}
.payslip-body > tbody > tr > :last-child {
	padding-left: 16px;
	padding-right: 4px;
}
.payslip-body > tbody > tr > td.align-top:first-child {
	padding-left: 0;
	padding-right: 12px;
}
.payslip-body > tbody > tr > td.align-top:last-child {
	padding-left: 12px;
	padding-right: 0;
}
.payslip-net {
	display: flex;
	justify-content: space-between;
	font-weight: 700;
	color: #c00000;
	font-size: 1.05rem;
	margin-top: 6px;
}
/* The NET PAY label/amount are their own spans; set their weight directly so
   the card's 400 for normal spans doesn't win over the line's own weight. */
.payslip-card .payslip-net span {
	font-weight: 700;
}
/* NET PAY as a row under GROSS INCOME, so its label and amount line up with
   that column (same right padding as the subtotal cell). */
.payslip-net-row td {
	font-weight: 700;
	font-size: 1.05rem;
	padding-top: 6px;
}
.payslip-signature {
	/* Pinned to the bottom, so both cards of a pair end level; the padding
	   keeps a fixed gap above it when the content fills the card, and a
	   longer payslip just makes both cards taller (never overlaps). */
	margin-top: auto;
	padding-top: 32px;
}
.payslip-signature .signature-line {
	display: inline-block;
	width: 180px;
	border-bottom: 1px solid #333;
	margin-left: 6px;
}
.payslip-signature > div {
	margin-bottom: 20px;
}
/* Space below DATE: 4px + the card's 12px bottom padding. */
.payslip-signature > div:last-child {
	margin-bottom: 4px;
}
/* employee/leave.php's Leave Credits balance table - never inline-style this
   table, add rules here instead. */
.leave-balances-table {
	border-color: var(--bs-gray-400);
}
.leave-balances-table-allotted-col {
	width: 140px;
}
/* Metronic's own theme CSS globally strips the bottom border off every
   table's last row - not just border-bottom-width, but border-bottom-style:
   none !important too (dist/plugins/metronic/css/style.bundle.css:37248's
   `.table tbody tr:last-child td { border-bottom: 0 !important;
   border-bottom-width: 0px !important; border-bottom-style: none !important;
   border-bottom-color: currentcolor !important; }`) - fine for the usual
   .table-row-bordered look (row separators only), but it defeats
   .table-bordered's whole point of a fully enclosed grid, leaving the bottom
   edge open. A first fix here only re-set border-bottom-width, which did
   nothing on its own since border-bottom-style was still forced to none -
   the border-bottom shorthand below resets width/style/color together, so
   it must be used (not just the -width sub-property) to actually win. */
.leave-balances-table.table-bordered tbody tr:last-child td {
	border-bottom: 1px solid var(--bs-gray-400) !important;
}
/* Complete Employee Report (renderCompleteEmployeeReport(), include/helpers/
   payroll.php). Fixed label/value fields use this grid rather than a table:
   each field owns its own cell with the label stacked above the value, so a
   long value (Address) wraps inside its own cell instead of stretching a
   shared table row and dragging neighbouring labels out of line. auto-fit
   also means the column count follows the available width - nothing has to
   be hand-assigned to a Bootstrap column that may not suit the data.
   No .text-muted anywhere in this report: a full-contrast label reads better
   on a printed record than a low-contrast gray one. */
.employee-report-fields {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
	gap: 12px 24px;
	align-items: start;
}
.employee-report-field-wide {
	grid-column: 1 / -1;
}
.employee-report-field-label {
	font-size: 0.8rem;
	font-weight: 600;
	letter-spacing: 0.02em;
	margin-bottom: 2px;
}
.employee-report-field-value {
	white-space: normal;
	overflow-wrap: anywhere;
	line-height: 1.35;
}
.employee-report-heading {
	font-weight: 700;
	padding-bottom: 4px;
	margin-bottom: 12px;
}
/* Only the field-grid sections (Personal/Employment/Government IDs) get a
   heading underline - the list sections (Dependents onward) already have
   their own bordered table right below, so a second border on the heading
   is redundant. */
.employee-report-heading:has(+ .employee-report-fields) {
	border-bottom: 1px solid var(--bs-gray-400);
}
.employee-report-section {
	margin-bottom: 24px;
}
/* Empty list sections (no dependents/allowances/loans/leave balances) are
   skipped entirely rather than rendered with a "None on file" placeholder,
   so whichever section actually ends up last varies per employee - :last-
   child (not a hardcoded class on one specific section) is what keeps the
   card from ending in extra blank space regardless of which sections a
   given employee's data happens to fill in. */
.employee-report-section:last-child {
	margin-bottom: 0;
}
/* Bootstrap vertically centers every <td>; top-align instead so a wrapped
   value in one column still lines up with its own row's other cells. */
.employee-report-table td,
.employee-report-table th {
	vertical-align: top;
	white-space: normal;
	overflow-wrap: anywhere;
}
/* Same fix as .leave-balances-table above: the vendored theme strips
   border-bottom off a table's last row entirely (style.bundle.css'
   `.table tbody tr:last-child td { border-bottom: 0 !important; ... }`),
   which defeats .table-bordered's fully-enclosed-grid look, leaving the
   bottom edge open. */
.employee-report-table.table-bordered tbody tr:last-child td {
	border-bottom: 1px solid var(--bs-gray-400) !important;
}
/* Per-employee batch grids (Incentives, Adjustment, Service Charge): same
   theme rule strips the last row's bottom border. Scoped to this class only. */
.batch-grid-table.table-bordered > tbody > tr:last-child > td,
.batch-grid-table.table-bordered > tbody > tr:last-child > th {
	border-bottom: 1px solid var(--bs-gray-400) !important;
}
.employee-report-col-narrow {
	width: 140px;
}
@media print {
	.employee-report-card {
		break-inside: avoid;
	}
	/* One employee per printed page. :not(:first-of-type), not
	   :not(:first-child) - the hidden data-export-table sits before the
	   first card as a sibling, so the first card is never its parent's
	   literal :first-child; :first-of-type (scoped to its own <div> tag,
	   the export table is a <table>) is what actually identifies it. */
	.employee-report-card:not(:first-of-type) {
		break-before: page;
	}
	/* Print only .payslip-report - hide every element that (a) isn't itself
	   inside it and (b) doesn't contain it as a descendant (i.e. isn't one
	   of its ancestors). Ancestors (sidebar/header/main wrappers, the
	   filter-form card, ...) stay in normal document flow with only
	   .payslip-report visible inside them; display:none (not
	   visibility:hidden + position:absolute) is what lets it paginate
	   normally across multiple pages instead of overlapping - an absolutely
	   positioned box taller than one page doesn't fragment across pages
	   correctly. */
	body:has(.payslip-report) *:not(.payslip-report):not(.payslip-report *):not(:has(.payslip-report)) {
		display: none !important;
	}
	/* Bootstrap's .row/.col-md-6 grid is display:flex, and fragmenting a flex
	   container across multiple printed pages is unreliable in Chrome (each
	   item's height gets recomputed per page fragment, compounding into a
	   growing overlap the more pages there are). renderPayslipReport() (see
	   include/helpers/payroll.php) works around this by grouping every 2
	   cards into their own small .payslip-print-row container instead of one
	   giant .row holding every card - each pair's flex row is tiny and kept
	   whole via break-inside:avoid, so it's never itself fragmented across a
	   page boundary. .payslip-report .row is switched to plain block flow
	   here since it's no longer the flex container doing the layout.
	   margin:0 also cancels Bootstrap's .g-4 gutter, which sets a NEGATIVE
	   margin on .row (offset on screen by matching .col-md-6 padding, which
	   print resets separately below) - left alone it pulls the row's content
	   past the page's own edge. */
	.payslip-report .row {
		display: block;
		margin: 0;
	}
	.payslip-print-row {
		display: flex;
		gap: 12px;
		break-inside: avoid;
		margin-bottom: 12px;
	}
	/* flex:1 1 0 (not width:50%) so each card shares the row's real width
	   around the gap above - width:50% on both children ignores the gap
	   entirely, overflowing the row (and the printable page) by that
	   amount. min-width:0 keeps a card's own content from forcing it wider
	   than its share. */
	.payslip-print-row .col-md-6 {
		display: block;
		flex: 1 1 0;
		min-width: 0;
		padding: 0;
	}
	/* No forced break-before between pairs (no hardcoded "N per page") - how
	   many pairs fit a page depends on paper size/orientation, which this
	   stylesheet has no way to know; break-inside:avoid on both the pair and
	   the card is enough for the browser to paginate naturally. height:100%
	   (matching the flex sibling's height) is already set unconditionally
	   above, not repeated here. */
	.payslip-card {
		break-inside: avoid;
	}
}

/* ==========================
   COMBINED SCHEDULE MODULE
   ========================== */
/* pages/admin/attendance/schedule.php's dashboard table - minimal padding on
   just the per-day schedule cells (it's a dense weekly grid there, not a
   plain data table) - the Name/Employee No. columns keep the table's normal
   padding, only td.schedule-cell is targeted - and squared-off,
   normal-weight badges (Bootstrap's own .badge defaults to bold + rounded,
   which reads as too heavy for a small per-day chip) - scoped to these two
   classes rather than overriding .badge/table-bordered globally, since other
   badges/tables elsewhere in the app still want the defaults. */
.schedule-table td.schedule-cell {
	padding: 2px 4px;
}
.schedule-badge {
	font-weight: initial;
	border-radius: 0;
}
/* Employee schedule popup: day badges sized like the weekly grid's. */
.fc .fc-event.schedule-badge {
	border-radius: 0;
	padding: 2px 4px;
	font-size: 1rem;
}
.fc .fc-event.schedule-badge .fc-event-main {
	color: inherit;
}
/* Schedule table: every text column, the day badges included, is left-aligned. */
.schedule-table .schedule-badge {
	text-align: left;
}

/* Deductions report: invalid government ID number, hover shows why */
.govt-id-invalid {
	cursor: help;
}

/* The Complete Employee Report is a stack of cards (outline drawn as a
   box-shadow), not one frozen table, so its pane keeps room for them. */
.employee-full-report.rpt-pane { padding: 0.5rem !important; }
/* Its cards all take the pane's width instead of each growing to its own
   widest table. */
.employee-full-report .rpt-freeze-wide { width: auto !important; min-width: 0 !important; }
.employee-full-report .rpt-freeze-card { position: static !important; width: auto !important; }

/* Rule pickers (Incident File "Rules Violated", Disciplinary Actions rule table):
   long rule names wrap onto more lines instead of being cut off or widening the
   page. Beats the dropdowns' fixed height and no-wrap in custom.css. */
.rule-picker .choices__inner,
.rule-picker .choices[data-type*="select-one"] .choices__inner {
	height: auto;
}
.rule-picker .choices__item,
.rule-picker .choices__list--single .choices__item,
.rule-picker .choices[data-type*="select-one"] .choices__list--single .choices__item,
.rule-picker .choices__list--dropdown .choices__item {
	white-space: normal;
	overflow: visible;
	text-overflow: clip;
	overflow-wrap: anywhere;
	word-break: normal;
}

/* Dashboard clickable boxes: hover with the theme's row-hover color (the stock
   light hover ignores the chosen theme, most visibly in dark mode). */
.dash-click-box:hover {
	background-color: var(--kt-table-hover-bg, var(--bs-light)) !important;
}

/* Incentive Rule Quota Tiers while the sales item features are off: the
   5th column (products counted) is hidden but its inputs still post, so
   the saved product lists are kept. */
.incentive-tier-no-products th:nth-child(5),
.incentive-tier-no-products td:nth-child(5) {
	display: none;
}

/* Headcount report: org unit tree (report CSS lives here, not inline, so it
   survives the View in New Tab clone) */
.headcount-tree,
.headcount-tree ul {
	list-style: none;
	margin: 0;
	padding-left: 0;
}
.headcount-tree ul {
	margin-left: 1.25rem;
	padding-left: 1rem;
	border-left: 1px dashed var(--bs-gray-400);
}
.headcount-node {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	padding: 0.5rem 0.75rem;
	margin: 0.35rem 0;
	border: 1px solid var(--bs-gray-300);
	border-radius: 0.475rem;
}
.headcount-node-company {
	background-color: var(--bs-gray-100);
}
.headcount-head {
	color: var(--bs-gray-900);
}
@media print {
	.headcount-node {
		break-inside: avoid;
	}
}
