/* ============================================================================
   Tailwind Operations — application stylesheet
   ----------------------------------------------------------------------------
   Replaces styles/invoices_styles.css for pages converted to the modern
   layout (layout_header.php / layout_footer.php). Unconverted pages still
   load the old stylesheet, so the two can coexist during the rollout.

   The page CONTENT is deliberately left as-is during conversion: it still
   uses <table border="1">, class="pageName", class="bodyText" and so on.
   This file styles those legacy hooks so existing markup looks right without
   rewriting every page's internals.
   ========================================================================= */

:root {
	--bg:            #f5f6f8;
	--surface:       #ffffff;
	--border:        #e3e6ea;
	--border-strong: #cdd3da;

	--text:          #1f2933;
	--text-muted:    #66727f;
	--text-invert:   #ffffff;

	--accent:        #2563eb;
	--accent-hover:  #1d4ed8;
	--accent-soft:   #eff4ff;

	--danger:        #b42318;
	--radius:        6px;
	--shadow:        0 1px 2px rgba(16, 24, 40, .06), 0 1px 3px rgba(16, 24, 40, .10);

	--sidebar-w:     220px;
	--font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue",
	        Arial, sans-serif;
}

/* ---------------------------------------------------------------- base --- */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
	margin: 0;
	font-family: var(--font);
	font-size: 14px;
	line-height: 1.5;
	color: var(--text);
	background: var(--bg);
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

h1, h2, h3 { margin: 0 0 .6em; font-weight: 600; line-height: 1.25; }
h2 { font-size: 1.15rem; }
h3 { font-size: 1rem; }

/* -------------------------------------------------------------- topbar --- */

.topbar {
	display: flex;
	align-items: center;
	gap: 16px;
	padding: 10px 20px;
	background: var(--surface);
	border-bottom: 1px solid var(--border);
}

.topbar__logo img { display: block; height: 34px; width: auto; }


.topbar__meta {
	margin-left: auto;
	display: flex;
	align-items: center;
	gap: 14px;
	font-size: .82rem;
	color: var(--text-muted);
	text-align: right;
}

.topbar__user { font-weight: 500; color: var(--text); }

/* Shown instead of the user name when nobody is signed in. Lives in the
   topbar so it is present on every page -- the pages with no sidebar have
   no other route to the login screen. */
.topbar__login {
	padding: 5px 13px;
	border-radius: var(--radius);
	background: var(--accent);
	color: var(--text-invert);
	font-size: .82rem;
	font-weight: 500;
	text-decoration: none;
}
.topbar__login:hover { background: var(--accent-hover); text-decoration: none; }

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

.shell {
	display: flex;
	align-items: flex-start;
	gap: 0;
	min-height: calc(100vh - 55px);
}

/* ------------------------------------------------------------- sidebar --- */

.sidebar {
	flex: 0 0 var(--sidebar-w);
	width: var(--sidebar-w);
	padding: 14px 10px;
	background: var(--surface);
	border-right: 1px solid var(--border);
	align-self: stretch;
}

.nav-link {
	display: block;
	padding: 7px 11px;
	margin-bottom: 1px;
	border-radius: var(--radius);
	color: var(--text);
	font-size: .875rem;
	text-decoration: none;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.nav-link:hover {
	background: var(--accent-soft);
	color: var(--accent-hover);
	text-decoration: none;
}

.nav-link.is-active {
	background: var(--accent);
	color: var(--text-invert);
	font-weight: 500;
}

/* Divider between groups in the sidebar. An entry with href '-' in a menu
   include renders one of these instead of a link. */
.nav-sep {
	border: 0;
	border-top: 1px solid var(--border);
	margin: 9px 11px;
}

/* ------------------------------------------------------------- content --- */

.content {
	flex: 1 1 auto;
	min-width: 0;          /* lets wide tables scroll instead of blowing out */
	padding: 22px 26px 40px;
}

/* The converted pages keep a full-width wrapper <table> around their content.
   Neutralise it so it behaves like a plain block. */
.content > table {
	width: 100%;
	border-collapse: collapse;
}
.content > table > tbody > tr > td { padding: 0; }

/* ------------------------------------------- legacy content type hooks --- */

.pageName {
	display: block;
	font-size: 1.4rem;
	font-weight: 600;
	letter-spacing: -.01em;
	color: var(--text);
	padding-bottom: 10px;
	margin-bottom: 16px;
	border-bottom: 1px solid var(--border);
}

.bodyText { font-size: .9rem; color: var(--text); }
.smallText { font-size: .8rem; color: var(--text-muted); }
.subHeader { font-size: .8rem; font-weight: 600; letter-spacing: .04em;
             text-transform: uppercase; color: var(--text-muted); }

/* --------------------------------------------------------- data tables --- */

/* Real tabular data. These stay <table> on purpose -- they are tables. */
.content table[border],
.content table.data {
	width: auto;
	max-width: 100%;
	border-collapse: collapse;
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	box-shadow: var(--shadow);
	margin: 0 0 18px;
	font-size: .875rem;
	overflow: hidden;
}

.content table[border] td,
.content table[border] th {
	border: 1px solid var(--border);
	padding: 7px 11px;
	text-align: left;
	vertical-align: middle;
}

/* First row acts as the header in this codebase (cells wrapped in <b>) */
.content table[border] tr:first-child td { background: #f0f2f5; }
.content table[border] tr:first-child td b { color: var(--text); font-weight: 600; }

.content table[border] tr:hover td { background: var(--accent-soft); }
.content table[border] tr:first-child:hover td { background: #f0f2f5; }

/* --------------------------------------------------------- tile grids --- */

/* Launcher tiles (Administration, and the main dashboard when it is
   converted). A grid rather than a table: every tile is the same size and
   they stay aligned regardless of label length or how many there are.
   The whole tile is the link, so the click target is the card, not a
   button whose width followed its text. */
.tile-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(165px, 1fr));
	gap: 14px;
	max-width: 940px;
	margin: 4px 0 10px;
}

.tile {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 13px;
	min-height: 140px;
	padding: 20px 14px;
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	box-shadow: var(--shadow);
	color: var(--text);
	text-align: center;
	text-decoration: none;
}

.tile:hover {
	border-color: var(--accent);
	color: var(--accent-hover);
	text-decoration: none;
	box-shadow: 0 2px 10px rgba(37, 99, 235, .16);
}

.tile img {
	width: 42px;
	height: 42px;
	opacity: .55;          /* the icons are solid black; soften to grey */
}
.tile:hover img { opacity: .9; }

.tile span { font-size: .875rem; font-weight: 500; line-height: 1.35; }

@media (max-width: 860px) {
	.tile-grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 10px; }
	.tile { min-height: 118px; padding: 16px 10px; }
	.tile img { width: 34px; height: 34px; }
}

/* ----------------------------------------------------- report selector --- */

/* The row of report buttons on the Revenue Statistics pages. It used to be a
   nine-column table, so its width was a hard floor on the width of the whole
   page -- nine full-size buttons could not wrap no matter how narrow the
   window got. As a flex row they reflow onto a second line instead, and the
   page stops being wider than the screen. */
.report-tabs {
	display: flex;
	flex-wrap: wrap;
	gap: 5px;
	margin: 0 0 14px;
}

.report-tabs input[type="submit"] {
	margin: 0;
	padding: 5px 11px;
	font-size: .8rem;
}

/* ----------------------------------------------------- billing mode --- */

/* The full-current-month switch above the Generate Invoices list. Set off
   from the list so it reads as a control over the whole table rather than
   as another row of it. */
.billing-mode {
	display: inline-flex;
	align-items: center;
	gap: 10px;
	margin: 0 0 14px;
	padding: 9px 13px;
	background: var(--accent-soft);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	font-size: .875rem;
}

.billing-mode label {
	display: inline-flex;
	align-items: baseline;
	gap: 8px;
	cursor: pointer;
}

.billing-mode__note {
	color: var(--text-muted);
	font-size: .82rem;
}

/* -------------------------------------------------------- result cards --- */

/* One card per group on report pages that repeat a block per client/vendor.
   Reports used to run together because each block was just a heading, a
   table and a button with nothing between them. */
.result-card {
	background: var(--surface);
	border: 1px solid var(--border);
	border-left: 3px solid var(--accent);
	border-radius: var(--radius);
	box-shadow: var(--shadow);
	padding: 15px 18px 16px;
	margin: 0 0 16px;
}

.result-card > h2 {
	margin: 0 0 12px;
	padding-bottom: 9px;
	border-bottom: 1px solid var(--border);
	font-size: 1.02rem;
	color: var(--text);
}

/* Tables sit flat inside a card -- the card is already the frame, so the
   table keeps its grid but drops its own shadow and outer rounding. */
.result-card table[border] {
	box-shadow: none;
	border-radius: 0;
	margin-bottom: 10px;
}

/* The running total that follows each table */
.result-card > form { margin-top: 4px; }

/* ---------------------------------------------------------------- forms --- */

input[type="text"], input[type="password"], input[type="email"],
input[type="number"], input[type="date"], select, textarea {
	font-family: inherit;
	font-size: .875rem;
	color: var(--text);
	padding: 6px 9px;
	border: 1px solid var(--border-strong);
	border-radius: var(--radius);
	background: var(--surface);
	max-width: 100%;
}

input[type="text"]:focus, input[type="password"]:focus, input[type="email"]:focus,
input[type="number"]:focus, input[type="date"]:focus, select:focus, textarea:focus {
	outline: none;
	border-color: var(--accent);
	box-shadow: 0 0 0 3px rgba(37, 99, 235, .12);
}

textarea { line-height: 1.45; }

input[type="submit"], button, .btn {
	/* inline-block matters for .btn on an <a>: an inline element ignores
	   vertical padding for line-height purposes, so the button bled into the
	   lines above and below it. Inputs and buttons are inline-block already. */
	display: inline-block;
	font-family: inherit;
	font-size: .875rem;
	font-weight: 500;
	line-height: 1.2;
	padding: 7px 14px;
	margin: 2px 3px 2px 0;
	color: var(--text-invert);
	background: var(--accent);
	border: 1px solid var(--accent);
	border-radius: var(--radius);
	cursor: pointer;
	text-decoration: none;
}

input[type="submit"]:hover, button:hover, .btn:hover { background: var(--accent-hover); }
/* The global a:hover underline would otherwise strike through the button face */
a.btn, a.btn:hover { color: var(--text-invert); text-decoration: none; }

/* Destructive-sounding actions read as such without touching the markup */
input[type="submit"][value="Delete"],
input[type="submit"][value*="Delete"] {
	background: var(--danger);
	border-color: var(--danger);
}

input[type="checkbox"], input[type="radio"] { accent-color: var(--accent); }

/* Shown where a chart or table would be when a filter matches nothing.
   Reads as information rather than as an error. */
.no-records {
	margin: 4px 0 18px;
	padding: 14px 16px;
	background: var(--surface);
	border: 1px dashed var(--border-strong);
	border-radius: var(--radius);
	color: var(--text-muted);
	font-size: .9rem;
}

/* --------------------------------------------------------------- misc --- */

hr { border: 0; border-top: 1px solid var(--border); margin: 18px 0; }

ol, ul { padding-left: 20px; }
ol li, ul li { margin-bottom: 5px; }

/* ---------------------------------------------------------- responsive --- */

@media (max-width: 860px) {
	.shell { flex-direction: column; }
	.sidebar {
		flex: 1 1 auto;
		width: 100%;
		border-right: 0;
		border-bottom: 1px solid var(--border);
		display: flex;
		flex-wrap: wrap;
		gap: 3px;
		padding: 9px 12px;
	}
	.nav-link { padding: 6px 10px; font-size: .82rem; }
	.content { padding: 16px 14px 30px; }
	.topbar { flex-wrap: wrap; gap: 8px 14px; }
	.topbar__meta { margin-left: 0; width: 100%; justify-content: flex-start; }
	/* wide data tables scroll rather than break the page */
	.content table[border] { display: block; overflow-x: auto; white-space: nowrap; }
}

/*
 * Very large edit grids -- currently P&L Pipeline, 268 rows carrying seven
 * inputs and two drop-downs each: about 2,400 form controls, 536 native
 * selects and 9,000 nodes in one table. Laying that out is what makes the tab
 * report "Page Unresponsive" on a slower machine. The message is the browser's
 * main thread blocking; nothing about it is server side.
 *
 * table-layout: fixed is the lever that does not change behaviour. With the
 * default auto layout the browser must measure the contents of every cell in
 * all 268 rows before it can choose column widths -- two passes over the whole
 * table. Fixed layout takes the widths below and lays out in one pass, without
 * measuring the rest.
 *
 * The widths are a visual change: columns no longer size themselves to their
 * contents. Nothing about the form changes -- same fields, same names, same
 * values posted.
 *
 * NOT content-visibility. CSS containment does not apply to internal table
 * elements, so content-visibility on a <tr> is ignored. Making it apply means
 * taking the rows out of table layout altogether (display: grid on each row),
 * which is a much bigger change to how the page looks. Only worth it if fixed
 * layout proves insufficient.
 */
.pipeline-grid {
	table-layout: fixed;
	width: 100%;
}
/* Columns are addressed by POSITION, so adding or removing one shifts every
   rule after it. Removing the Status column on 2026-10-22 did exactly that:
   its 9% landed on Comments, and the specified widths no longer summed near
   100%, so browsers spread the surplus across every column -- which is what
   made the checkbox column look fat.
   The last column is deliberately left unspecified so it absorbs whatever is
   left over. Keep it that way: it is what stops a future column change from
   redistributing into the checkbox again.
     1 select · 2 Client · 3 Title · 4 Owner · 5 Est Value
     6 Est Months · 7 Probability · 8 Est Close · (9 Comments, elastic) */
.pipeline-grid td:nth-child(1) { width: 34px; }
.pipeline-grid td:nth-child(2) { width: 15%; }
.pipeline-grid td:nth-child(3) { width: 20%; }
.pipeline-grid td:nth-child(4) { width: 10%; }
.pipeline-grid td:nth-child(5) { width: 9%; }
.pipeline-grid td:nth-child(6) { width: 7%; }
.pipeline-grid td:nth-child(7) { width: 8%; }
.pipeline-grid td:nth-child(8) { width: 9%; }
.pipeline-grid input[type=text],
.pipeline-grid select { width: 100%; box-sizing: border-box; }
