/*
 * NK ECO — modern design system (Step 6 redesign).
 *
 * Loaded alongside the legacy ecostyles.css during the page-by-page
 * conversion. Unconverted pages still render against the old CSS; new
 * pages opt in via:
 *   - HTML5 doctype: <!doctype html>
 *   - <body class="modern">     (gates all selectors below)
 *
 * Why gate everything on body.modern?
 *   The CSS reset (* { box-sizing: border-box; ... }) would otherwise
 *   reflow the legacy table-everywhere layout and break it. Scoping
 *   makes the new styles strictly opt-in.
 */

/* ============================================================== *
 * Design tokens                                                  *
 * ============================================================== */
:root {
	--nk-blue:           #0166A0;
	--nk-blue-dark:      #014E7A;
	--nk-blue-light:     #2A8BC0;

	--bg-page:           #f5f7fa;
	--bg-surface:        #ffffff;
	--bg-muted:          #f0f3f7;
	--bg-emph:           #e5ebf2;

	--text-primary:      #1a1f2b;
	--text-secondary:    #5a6373;
	--text-tertiary:     #8d97a8;
	--text-inverse:      #ffffff;

	--border-subtle:     rgba(0, 0, 0, 0.08);
	--border-default:    rgba(0, 0, 0, 0.14);
	--border-strong:     rgba(0, 0, 0, 0.22);

	--radius-sm:         6px;
	--radius-md:         10px;
	--radius-lg:         14px;
	--radius-pill:       999px;

	/* Status palette — used by badges + tinted cards */
	--status-draft-bg:      #eef0f3;
	--status-draft-fg:      #4a5568;
	--status-proposed-bg:   #fef3c7;
	--status-proposed-fg:   #854f0b;
	--status-pending-bg:    #fef3c7;
	--status-pending-fg:    #854f0b;
	--status-approved-bg:   #dbeafe;
	--status-approved-fg:   #0c447c;
	--status-completed-bg: #dcfce7;
	--status-completed-fg: #166534;
	--status-cancelled-bg: #fee2e2;
	--status-cancelled-fg: #991b1b;

	/* Focus ring used by inputs/buttons */
	--focus-ring:        0 0 0 3px rgba(1, 102, 160, 0.25);

	/* Font stack — system fonts, no Google Fonts dependency.
	   Matches GitHub/Stripe/Vercel admin UIs. */
	--font-sans:  -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
	--font-mono:  ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
}

/* ============================================================== *
 * Reset + base                                                    *
 * ============================================================== */
body.modern,
body.modern *,
body.modern *::before,
body.modern *::after {
	box-sizing: border-box;
}

body.modern {
	margin: 0;
	background: var(--bg-page);
	color: var(--text-primary);
	font-family: var(--font-sans);
	font-size: 14px;
	line-height: 1.5;
	-webkit-font-smoothing: antialiased;
	min-height: 100vh;
}

body.modern h1,
body.modern h2,
body.modern h3,
body.modern h4 {
	margin: 0 0 0.5em;
	font-weight: 600;
	line-height: 1.3;
}
body.modern h1 { font-size: 22px; }
body.modern h2 { font-size: 18px; }
body.modern h3 { font-size: 16px; }
body.modern h4 { font-size: 14px; }

body.modern p { margin: 0 0 1em; }
body.modern a { color: var(--nk-blue); text-decoration: none; }
body.modern a:hover { text-decoration: underline; }

/* ============================================================== *
 * Top navigation bar                                              *
 * ============================================================== */
body.modern .topnav {
	background: var(--nk-blue);
	color: var(--text-inverse);
	padding: 12px 24px;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	flex-wrap: wrap;
	box-shadow: 0 1px 0 rgba(0, 0, 0, 0.05);
}

body.modern .topnav__brand {
	display: flex;
	align-items: center;
	gap: 10px;
	font-size: 16px;
	font-weight: 600;
	color: var(--text-inverse);
	text-decoration: none;
}
body.modern .topnav__brand:hover { text-decoration: none; opacity: 0.9; }

body.modern .topnav__brand i {
	font-size: 22px;
}
/* Original NK Portal logo banner. Sized to fit the slim nav (~28px tall).
   The source image is a wide rectangle; height controls it and width
   auto-scales. */
body.modern .topnav__logo {
	height: 28px;
	width: auto;
	display: block;
	border-radius: 4px;
}

body.modern .topnav__company {
	font-size: 11px;
	font-weight: 500;
	background: rgba(255, 255, 255, 0.18);
	padding: 3px 9px;
	border-radius: var(--radius-md);
	letter-spacing: 0.5px;
	text-transform: uppercase;
}

body.modern .topnav__links {
	display: flex;
	align-items: center;
	gap: 4px;
	font-size: 13px;
}

body.modern .topnav__links a {
	color: rgba(255, 255, 255, 0.92);
	padding: 6px 12px;
	border-radius: var(--radius-md);
	transition: background 0.15s ease;
}

body.modern .topnav__links a:hover {
	background: rgba(255, 255, 255, 0.12);
	text-decoration: none;
}

body.modern .topnav__links a.is-active {
	background: rgba(255, 255, 255, 0.15);
	font-weight: 500;
}

body.modern .topnav__user {
	display: flex;
	align-items: center;
	gap: 10px;
	font-size: 12px;
	color: rgba(255, 255, 255, 0.85);
	margin-left: 8px;
	padding-left: 12px;
	border-left: 1px solid rgba(255, 255, 255, 0.2);
}

body.modern .topnav__avatar {
	width: 28px;
	height: 28px;
	border-radius: 50%;
	background: rgba(255, 255, 255, 0.22);
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 11px;
	font-weight: 600;
	color: var(--text-inverse);
}

body.modern .topnav__menu-toggle {
	display: none;
	background: transparent;
	border: none;
	color: var(--text-inverse);
	font-size: 22px;
	cursor: pointer;
	padding: 4px 8px;
}

/* Mobile: collapse nav links behind a hamburger toggle. */
@media (max-width: 720px) {
	body.modern .topnav__menu-toggle { display: block; }
	body.modern .topnav__links,
	body.modern .topnav__user {
		display: none;
		width: 100%;
		flex-direction: column;
		align-items: stretch;
		margin: 8px 0 0;
		padding: 0;
		border-left: 0;
		border-top: 1px solid rgba(255, 255, 255, 0.15);
		padding-top: 8px;
	}
	body.modern .topnav.is-open .topnav__links,
	body.modern .topnav.is-open .topnav__user {
		display: flex;
	}
	body.modern .topnav__links a {
		padding: 10px 12px;
	}
}

/* ============================================================== *
 * Page chrome                                                     *
 * ============================================================== */
body.modern .page {
	max-width: 1200px;
	margin: 0 auto;
	padding: 24px;
}

body.modern .page__title {
	font-size: 22px;
	font-weight: 600;
	margin: 0 0 4px;
}

body.modern .page__subtitle {
	font-size: 13px;
	color: var(--text-secondary);
	margin: 0 0 24px;
}

body.modern .page__header {
	display: flex;
	justify-content: space-between;
	align-items: flex-start;
	gap: 16px;
	margin-bottom: 20px;
	flex-wrap: wrap;
}

/* ============================================================== *
 * Cards                                                           *
 * ============================================================== */
body.modern .card {
	background: var(--bg-surface);
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-lg);
	padding: 20px 24px;
	margin-bottom: 16px;
}

body.modern .card__header {
	display: flex;
	justify-content: space-between;
	align-items: center;
	margin-bottom: 12px;
}

body.modern .card__title {
	font-size: 15px;
	font-weight: 600;
	margin: 0;
}

body.modern .card--compact {
	padding: 14px 18px;
}

/* ============================================================== *
 * KPI tiles                                                       *
 * ============================================================== */
body.modern .kpi-row {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
	gap: 12px;
	margin-bottom: 24px;
}

body.modern .kpi {
	background: var(--bg-surface);
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-md);
	padding: 14px 16px;
	display: block;
	color: inherit;
	text-decoration: none;
	transition: border-color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
}
/* When the KPI is rendered as an <a>, give it interactive affordance. */
body.modern a.kpi:hover {
	text-decoration: none;
	border-color: var(--border-strong);
	transform: translateY(-1px);
	box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
}
body.modern a.kpi:focus-visible {
	outline: none;
	box-shadow: var(--focus-ring);
}

body.modern .kpi__label {
	font-size: 12px;
	color: var(--text-secondary);
	font-weight: 500;
	text-transform: uppercase;
	letter-spacing: 0.5px;
}

body.modern .kpi__value {
	font-size: 26px;
	font-weight: 600;
	margin-top: 4px;
	line-height: 1.1;
}

/* Tinted KPI variants for status emphasis */
body.modern .kpi--draft     { background: var(--status-draft-bg);     }
body.modern .kpi--draft .kpi__label, body.modern .kpi--draft .kpi__value  { color: var(--status-draft-fg); }
body.modern .kpi--proposed  { background: var(--status-proposed-bg);  }
body.modern .kpi--proposed .kpi__label, body.modern .kpi--proposed .kpi__value { color: var(--status-proposed-fg); }
body.modern .kpi--approved  { background: var(--status-approved-bg);  }
body.modern .kpi--approved .kpi__label, body.modern .kpi--approved .kpi__value { color: var(--status-approved-fg); }
body.modern .kpi--completed { background: var(--status-completed-bg); }
body.modern .kpi--completed .kpi__label, body.modern .kpi--completed .kpi__value { color: var(--status-completed-fg); }

/* ============================================================== *
 * Status badges                                                   *
 * ============================================================== */
body.modern .badge {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	font-size: 11px;
	font-weight: 600;
	padding: 3px 10px;
	border-radius: var(--radius-pill);
	white-space: nowrap;
}

body.modern .badge--draft     { background: var(--status-draft-bg);     color: var(--status-draft-fg);     }
body.modern .badge--proposed  { background: var(--status-proposed-bg);  color: var(--status-proposed-fg);  }
body.modern .badge--pending   { background: var(--status-pending-bg);   color: var(--status-pending-fg);   }
body.modern .badge--approved  { background: var(--status-approved-bg);  color: var(--status-approved-fg);  }
body.modern .badge--completed { background: var(--status-completed-bg); color: var(--status-completed-fg); }
body.modern .badge--cancelled { background: var(--status-cancelled-bg); color: var(--status-cancelled-fg); }

/* ============================================================== *
 * Buttons                                                         *
 * ============================================================== */
body.modern .btn {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	font-family: inherit;
	font-size: 13px;
	font-weight: 500;
	line-height: 1;
	padding: 8px 14px;
	border-radius: var(--radius-md);
	border: 1px solid var(--border-default);
	background: var(--bg-surface);
	color: var(--text-primary);
	cursor: pointer;
	transition: background 0.15s ease, border-color 0.15s ease;
	text-decoration: none;
}

body.modern .btn:hover {
	background: var(--bg-muted);
	border-color: var(--border-strong);
	text-decoration: none;
}

body.modern .btn:focus-visible {
	outline: none;
	box-shadow: var(--focus-ring);
}

body.modern .btn--primary {
	background: var(--nk-blue);
	color: var(--text-inverse);
	border-color: var(--nk-blue);
}

body.modern .btn--primary:hover {
	background: var(--nk-blue-dark);
	border-color: var(--nk-blue-dark);
}

body.modern .btn--danger {
	background: var(--status-cancelled-fg);
	color: var(--text-inverse);
	border-color: var(--status-cancelled-fg);
}

body.modern .btn--sm {
	font-size: 12px;
	padding: 5px 10px;
}

body.modern .btn--icon { padding: 8px; }

/* ============================================================== *
 * Filter chips                                                    *
 * ============================================================== */
body.modern .chips {
	display: flex;
	gap: 6px;
	flex-wrap: wrap;
}

body.modern .chip {
	font-size: 12px;
	font-weight: 500;
	padding: 5px 12px;
	border-radius: var(--radius-pill);
	background: var(--bg-surface);
	border: 1px solid var(--border-default);
	color: var(--text-primary);
	cursor: pointer;
	text-decoration: none;
	display: inline-flex;
	align-items: center;
	gap: 5px;
}
body.modern .chip:hover { background: var(--bg-muted); text-decoration: none; }
body.modern .chip.is-active {
	background: var(--nk-blue);
	color: var(--text-inverse);
	border-color: var(--nk-blue);
}

/* ============================================================== *
 * Forms                                                           *
 * ============================================================== */
body.modern .field {
	margin-bottom: 16px;
}

body.modern .field__label {
	display: block;
	font-size: 12px;
	font-weight: 600;
	color: var(--text-secondary);
	margin-bottom: 6px;
	text-transform: uppercase;
	letter-spacing: 0.5px;
}

body.modern input[type="text"],
body.modern input[type="email"],
body.modern input[type="password"],
body.modern input[type="search"],
body.modern input[type="number"],
body.modern textarea,
body.modern select {
	font-family: inherit;
	font-size: 14px;
	padding: 8px 12px;
	border: 1px solid var(--border-default);
	border-radius: var(--radius-md);
	background: var(--bg-surface);
	color: var(--text-primary);
	width: 100%;
	max-width: 480px;
	transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

body.modern input:focus,
body.modern textarea:focus,
body.modern select:focus {
	outline: none;
	border-color: var(--nk-blue);
	box-shadow: var(--focus-ring);
}

body.modern textarea { min-height: 80px; resize: vertical; }

body.modern input[disabled],
body.modern textarea[disabled],
body.modern select[disabled] {
	background: var(--bg-muted);
	color: var(--text-tertiary);
	cursor: not-allowed;
}
/* readonly inputs (text/number/email/etc) get the same gray-out treatment
   as disabled ones — by default the browser leaves them looking normal
   even though they can't be edited, which is confusing for users. Note:
   <textarea readonly> and select don't behave identically to inputs but
   we mirror the styling for visual consistency. */
body.modern input[readonly],
body.modern textarea[readonly],
body.modern select[readonly] {
	background: var(--bg-muted);
	color: var(--text-tertiary);
	cursor: not-allowed;
}

/* ============================================================== *
 * Tables (data only — not used for layout)                        *
 * ============================================================== */
body.modern table.data {
	width: 100%;
	border-collapse: collapse;
	font-size: 13px;
}

body.modern table.data thead th {
	text-align: left;
	font-weight: 500;
	color: var(--text-secondary);
	background: var(--bg-muted);
	padding: 10px 12px;
	font-size: 12px;
	text-transform: uppercase;
	letter-spacing: 0.5px;
}

body.modern table.data tbody td {
	padding: 12px;
	border-bottom: 1px solid var(--border-subtle);
}

body.modern table.data tbody tr:last-child td { border-bottom: none; }
body.modern table.data tbody tr:hover { background: var(--bg-muted); }

/*
 * Responsive data table — at narrow widths the table reflows into stacked
 * cards. Each row becomes a card; each cell becomes a "label: value" row
 * driven by data-label="…" on the <td>. The <thead> is hidden because the
 * data-label values replace it.
 *
 * Requires markup of the form:
 *   <td data-label="E-mail">user@example.com</td>
 *
 * Cells without a data-label still render — they just won't show a label.
 */
@media (max-width: 720px) {
	body.modern table.data,
	body.modern table.data thead,
	body.modern table.data tbody,
	body.modern table.data tr,
	body.modern table.data th,
	body.modern table.data td {
		display: block;
		width: 100%;
	}
	body.modern table.data thead { display: none; }
	body.modern table.data tr {
		background: var(--bg-surface);
		border: 1px solid var(--nk-blue-light);
		border-radius: var(--radius-lg);
		padding: 14px 16px;
		margin-bottom: 14px;
		box-shadow: 0 1px 2px rgba(1, 102, 160, 0.06);
	}
	body.modern table.data tr:hover { background: var(--bg-surface); }
	body.modern table.data tbody tr:last-child { margin-bottom: 0; }
	/* Drop the outer .card chrome on mobile so the row-cards aren't double-bordered. */
	body.modern .card:has(table.data) {
		background: transparent;
		border: none;
		box-shadow: none;
		padding: 0 !important;
	}
	body.modern table.data tbody td {
		border-bottom: none;
		padding: 4px 0;
		display: flex;
		justify-content: space-between;
		align-items: center;
		gap: 12px;
		text-align: left !important;
	}
	body.modern table.data tbody td::before {
		content: attr(data-label);
		font-size: 11px;
		font-weight: 600;
		color: var(--text-secondary);
		text-transform: uppercase;
		letter-spacing: 0.5px;
		flex: 0 0 110px;
	}
	/* Cells without a data-label (e.g. the trailing action button) shouldn't
	   reserve the label column. */
	body.modern table.data tbody td:not([data-label])::before {
		display: none;
	}
}

/* ============================================================== *
 * Alerts / messages                                               *
 * ============================================================== */
body.modern .alert {
	padding: 12px 16px;
	border-radius: var(--radius-md);
	font-size: 13px;
	margin-bottom: 16px;
	border: 1px solid transparent;
}
body.modern .alert--info    { background: var(--status-approved-bg); color: var(--status-approved-fg); }
body.modern .alert--success { background: var(--status-completed-bg); color: var(--status-completed-fg); }
body.modern .alert--warning { background: var(--status-proposed-bg);  color: var(--status-proposed-fg);  }
body.modern .alert--error   { background: var(--status-cancelled-bg); color: var(--status-cancelled-fg); }

/* ============================================================== *
 * ECO form (Phase F)                                              *
 * The form still uses the legacy <table class="ecotable"> markup  *
 * internally — these rules only restyle the chrome inside .card.  *
 * ============================================================== */
body.modern.eco-form-page table.ecotable {
	width: 100%;
	border-collapse: collapse;
	font-size: 13px;
}
body.modern.eco-form-page table.ecotable td {
	padding: 10px 14px;
	vertical-align: top;
	border-bottom: 1px solid var(--border-subtle);
	text-align: left;   /* legacy html may inherit center from a parent */
}
/* The "label" column (first td in each non-section row) carries the legacy
   bgcolor="#f8f8f8" — restyle it as a muted-text label rather than a fill. */
body.modern.eco-form-page table.ecotable td[bgcolor="#f8f8f8"] {
	background: transparent !important;
	color: var(--text-secondary);
	font-weight: 500;
	width: 200px;
}
/* Section header rows (bgcolor="#dddddd") become clickable section headers. */
body.modern.eco-form-page table.ecotable td[bgcolor="#dddddd"] {
	background: var(--bg-muted) !important;
	color: var(--text-primary);
	font-weight: 600;
	font-size: 13px;
	text-transform: uppercase;
	letter-spacing: 0.5px;
	padding: 12px 16px;
	border-bottom: 1px solid var(--border-default);
	border-top: 1px solid var(--border-subtle);
	user-select: none;
}
body.modern.eco-form-page table.ecotable td[bgcolor="#dddddd"]:hover {
	background: var(--bg-emph) !important;
}

/* Inputs inside the form — let the body.modern rules size them, but allow
   inline width="..." overrides on text inputs (the form has explicit sizes). */
body.modern.eco-form-page input[type="text"],
body.modern.eco-form-page input[type="email"],
body.modern.eco-form-page input[type="password"],
body.modern.eco-form-page input[type="number"],
body.modern.eco-form-page textarea,
body.modern.eco-form-page select {
	max-width: 100%;
}
/* Approval / action button styles inside the form — give them a button look. */
body.modern.eco-form-page input[type="submit"],
body.modern.eco-form-page input[type="button"] {
	font-family: inherit;
	font-size: 13px;
	font-weight: 500;
	padding: 8px 14px;
	border-radius: var(--radius-md);
	border: 1px solid var(--border-default);
	background: var(--bg-surface);
	color: var(--text-primary);
	cursor: pointer;
}
body.modern.eco-form-page input[type="submit"]:hover,
body.modern.eco-form-page input[type="button"]:hover {
	background: var(--bg-muted);
}
/* Save buttons (the row with name="button") get primary styling. */
body.modern.eco-form-page input[name="button"][type="submit"] {
	background: var(--nk-blue);
	color: var(--text-inverse);
	border-color: var(--nk-blue);
}
body.modern.eco-form-page input[name="button"][type="submit"]:hover {
	background: var(--nk-blue-dark);
	border-color: var(--nk-blue-dark);
}
/* Optionstable inside Impact Checklist — drop the pixel widths so it fits. */
body.modern.eco-form-page table.optionstable td { padding: 8px 10px; }

/* ---- Sticky ECO title bar ------------------------------------------- *
 * Appears at the top of the viewport when the user scrolls past the
 * main page header. Slim — just the ECO #, name, and current status —
 * so it doesn't eat too much vertical space while editing the form.
 */
body.modern.eco-form-page .eco-stickybar {
	position: sticky;
	top: 0;
	z-index: 30;
	background: var(--bg-surface);
	border-bottom: 1px solid var(--border-subtle);
	padding: 8px 16px;
	margin: -24px -24px 16px;  /* bleed to .page edges */
	/* Two centered rows: identity (id + name + status) on top, action
	 * buttons below. Both centered horizontally. */
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 6px;
	font-size: 14px;
	font-weight: 500;
	color: var(--text-primary);
	box-shadow: 0 1px 4px rgba(0, 0, 0, 0.04);
}
/* Row 1 — identity cluster: id + name + badge, laid out inline, centered. */
body.modern.eco-form-page .eco-stickybar__left {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 10px;
	min-width: 0;
	flex-wrap: wrap;
}
body.modern.eco-form-page .eco-stickybar__id {
	font-weight: 600;
	color: var(--nk-blue);
}
body.modern.eco-form-page .eco-stickybar__name {
	font-weight: 400;
	color: var(--text-secondary);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	max-width: 480px;
}
/* Row 2 — action buttons, centered, forced onto a single line.
 * flex-wrap:nowrap keeps everything in one row; overflow-x:auto lets the
 * row scroll horizontally on narrow viewports rather than wrapping. */
body.modern.eco-form-page .eco-stickybar__actions {
	display: flex;
	gap: 6px;
	flex-wrap: nowrap;
	align-items: center;
	justify-content: center;
	overflow-x: auto;
	max-width: 100%;
	/* Hide the scrollbar on WebKit until the user actually scrolls — the
	 * row still scrolls with wheel/touch/keyboard. */
	scrollbar-width: thin;
}
body.modern.eco-form-page .eco-stickybar__actions::-webkit-scrollbar {
	height: 4px;
}
/* Compact button metrics inside the sticky bar so more fit on one row.
 * Smaller padding + font size than the general .btn styles, and each
 * button refuses to shrink below its content width (flex-shrink:0). */
body.modern.eco-form-page .eco-stickybar .btn,
body.modern.eco-form-page .eco-stickybar button,
body.modern.eco-form-page .eco-stickybar a.btn {
	font-size: 12px;
	padding: 5px 8px;
	white-space: nowrap;
	flex-shrink: 0;
}

/* On narrow viewports (mobile):
 *   - Secondary buttons collapse to icon-only (title attribute → tooltip)
 *   - Primary "Update and Save" gets its own full-width row above the icons
 *   - Actions row switches to flex-wrap so the primary button can force
 *     everything else onto the next line via flex-basis:100%
 *
 * Screen readers still get the labels because .btn__label is sr-only,
 * not display:none.
 *
 * Breakpoint of 768px matches typical tablet portrait / mobile widths. */
@media (max-width: 768px) {
	body.modern.eco-form-page .eco-stickybar__actions {
		flex-wrap: wrap;        /* allow the primary button to bump others down */
		overflow-x: visible;    /* no horizontal scroll needed once wrapping */
	}
	body.modern.eco-form-page .eco-stickybar__actions .btn__label {
		/* Visually hidden but accessible to screen readers. */
		position: absolute;
		width: 1px;
		height: 1px;
		padding: 0;
		margin: -1px;
		overflow: hidden;
		clip: rect(0, 0, 0, 0);
		white-space: nowrap;
		border: 0;
	}
	/* Primary button — full width, full label, its own row at the top of
	 * the action group. flex-basis:100% pushes every following sibling
	 * onto the next flex line. */
	body.modern.eco-form-page .eco-stickybar__actions .btn--primary {
		flex: 0 0 100%;
		max-width: 100%;
		justify-content: center;
		padding: 8px 12px;
	}
	body.modern.eco-form-page .eco-stickybar .btn,
	body.modern.eco-form-page .eco-stickybar button,
	body.modern.eco-form-page .eco-stickybar a.btn {
		padding: 6px 10px;   /* square-ish tap target */
	}
	body.modern.eco-form-page .eco-stickybar .btn i {
		font-size: 16px;      /* bump the icon so it reads at glance */
	}
}
body.modern.eco-form-page .eco-stickybar .btn,
body.modern.eco-form-page .eco-stickybar button {
	font-size: 12px;
	padding: 6px 10px;
}
body.modern.eco-form-page .eco-stickybar .btn--danger {
	background: var(--status-cancelled-fg);
	color: var(--text-inverse);
	border-color: var(--status-cancelled-fg);
}
body.modern.eco-form-page .eco-stickybar .btn--danger:hover {
	background: #7a1717;
	border-color: #7a1717;
}

/* ---- Save bar (rendered above + below the form) ---------------------- */
body.modern .eco-savebar {
	background: var(--bg-surface);
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-lg);
	padding: 14px 18px;
	margin: 0 0 16px;
	display: flex;
	justify-content: space-between;
	align-items: center;
	gap: 12px;
	flex-wrap: wrap;
}
body.modern .eco-savebar:last-child { margin: 18px 0 0; }
body.modern .eco-savebar__primary,
body.modern .eco-savebar__secondary {
	display: flex;
	gap: 8px;
	flex-wrap: wrap;
}
body.modern .eco-savebar .btn--danger {
	background: var(--status-cancelled-fg);
	color: var(--text-inverse);
	border-color: var(--status-cancelled-fg);
}
body.modern .eco-savebar .btn--danger:hover {
	background: #7a1717;
	border-color: #7a1717;
}

/* ---- Background section — parent parts picker ------------------------ */
/*
 * The Parent Parts/Models row has two <select> lists with inline
 * float:left + width:300px + an <a>-tag column for Add/Remove between
 * them. We make the parent <td> a flex container, neutralize the legacy
 * floats/widths via !important, and style the middle column as a
 * vertical stack of buttons. No markup changes — JS bindings on
 * #addmodel / #removemodel still hit the same elements.
 *
 * The :has() selectors target the <td> that contains #models. Modern
 * browsers (Chrome 105+, Safari 15.4+, Firefox 121+) all support :has().
 */
body.modern.eco-form-page td:has(#models) {
	display: flex !important;
	gap: 14px;
	align-items: stretch;
	flex-wrap: wrap;
}
/* The two select lists fill the available row; the middle column is auto-width. */
body.modern.eco-form-page #models,
body.modern.eco-form-page #modelstoadd {
	float: none !important;
	width: 100% !important;
	height: auto !important;
	min-height: 180px;
	flex: 1 1 220px;
	min-width: 0;
	max-width: none;
}
/* Middle column — Add / Remove button stack. */
body.modern.eco-form-page td:has(#models) > div {
	float: none !important;
	width: 110px !important;
	flex: 0 0 110px;
	display: flex;
	flex-direction: column;
	gap: 8px;
	justify-content: center;
	align-items: stretch;
	text-align: center;
	padding: 0;
}
/* The legacy <a href="javascript:" id="addmodel"> links — style as buttons. */
body.modern.eco-form-page td:has(#models) > div a {
	display: block;
	font-size: 13px;
	font-weight: 500;
	padding: 8px 12px;
	border-radius: var(--radius-md);
	border: 1px solid var(--border-default);
	background: var(--bg-surface);
	color: var(--text-primary);
	text-decoration: none;
	cursor: pointer;
}
body.modern.eco-form-page td:has(#models) > div a:hover {
	background: var(--bg-muted);
	text-decoration: none;
}
/* Hide the legacy <br/><br/> spacer between Add and Remove — flex gap handles it. */
body.modern.eco-form-page td:has(#models) > div br { display: none; }

/* Narrow screens — stack the two selects vertically with the buttons between. */
@media (max-width: 600px) {
	body.modern.eco-form-page td:has(#models) > div {
		width: 100% !important;
		flex: 0 0 auto;
		flex-direction: row;
	}
}

/* Textareas in the form: full-width responsive within the value cell. */
body.modern.eco-form-page table.ecotable td textarea {
	width: 100%;
	max-width: 720px;
	min-height: 70px;
}
/* Action / actionNotes textareas in the Actions-to-Resolve table.
 * width:100% + box-sizing:border-box so the textarea including padding
 * and border stays inside its cell (which is a fixed percentage width
 * via table-layout:fixed above). No min-width — the column width
 * dictates size, not the textarea. */
body.modern.eco-form-page table.ecotable td textarea.actiontext,
body.modern.eco-form-page table.ecotable td textarea.actionNotes,
body.modern.eco-form-page table.ecotable td textarea[name="actiontext[]"],
body.modern.eco-form-page table.ecotable td textarea[name="actionNotes[]"] {
	width: 100%;
	max-width: 100%;
	min-width: 0;
	min-height: 110px;
	box-sizing: border-box;
}

/* Actions section — override inline width="145px" on the Department /
 * Person cells and let the selects shrink to their column width. No
 * min-width on the select so the cell size controls, not the select's
 * natural longest-option width. Native selects truncate their visible
 * value with the browser's built-in ellipsis when the box is narrower
 * than the selected text — that's the desired behavior here. */
body.modern.eco-form-page tr.existingAction > td:nth-child(1),
body.modern.eco-form-page tr.existingAction > td:nth-child(2) {
	width: auto !important;
}
body.modern.eco-form-page tr.existingAction select {
	width: 100%;
	max-width: 100%;
	min-width: 0;
	box-sizing: border-box;
	/* Slightly denser padding so more characters fit before ellipsis. */
	padding: 4px 22px 4px 6px;   /* extra right pad reserves room for the arrow */
	font-size: 13px;
}
body.modern.eco-form-page tr.existingAction {
	vertical-align: top;
}

/* Outer form table (label + value columns). Fixed layout keeps its
 * columns from being pushed by nested content. Word-wrap on cell
 * text ensures long strings without spaces don't force horizontal
 * overflow. Scoped with :not() so the nested tables (actions,
 * approvers, dept-leads) keep their natural auto layout. */
body.modern.eco-form-page > .page > .card > form > table.ecotable,
body.modern.eco-form-page > .page > table.ecotable,
body.modern.eco-form-page form > table.ecotable {
	table-layout: fixed;
	width: 100%;
	word-wrap: break-word;
	overflow-wrap: anywhere;
}

/* Nested action / approver / dept-lead tables (plain <table>, no
 * .ecotable class). Use natural table layout so all columns render
 * visibly; the outer form is now 1400px wide so we have room for
 * every column without scrolling. */
body.modern.eco-form-page table.ecotable td > table {
	width: 100%;
	table-layout: auto;
}

/* Column min-widths + max-widths in the actions table. Sized to fit
 * within the ~1320px inner form width (1400 page - 40 page pad - 40
 * card pad). Sum of max-widths ≈ 990px which leaves plenty of room.
 * Applies to BOTH the header row and body rows so labels don't
 * collapse to vertical text. */
/* Actions table is 6 columns after merging Date into Complete:
 *   1 Department  |  2 Person  |  3 Action  |  4 Notes  |  5 Complete (+ date)  |  6 Delete
 *
 * Uses table-layout:fixed with explicit column widths. That forces the
 * browser to honor exactly these widths regardless of cell content —
 * no more overflow into margins from long textarea content, and no
 * more asymmetric whitespace from unbounded column growth. */
body.modern.eco-form-page table.ecotable td > table {
	table-layout: fixed;
}
body.modern.eco-form-page table.ecotable td > table > tbody > tr > td:nth-child(1) {
	width: 12%;   /* Department — ~165px in a 1320px container */
}
body.modern.eco-form-page table.ecotable td > table > tbody > tr > td:nth-child(2) {
	width: 14%;   /* Person — ~185px */
}
body.modern.eco-form-page table.ecotable td > table > tbody > tr > td:nth-child(3),
body.modern.eco-form-page table.ecotable td > table > tbody > tr > td:nth-child(4) {
	width: 28%;   /* Action + Notes — each ~370px */
}
body.modern.eco-form-page table.ecotable td > table > tbody > tr > td:nth-child(5) {
	width: 10%;   /* Complete + date/actor caption — ~130px */
	white-space: normal;
	word-wrap: break-word;
	vertical-align: top;
}
body.modern.eco-form-page table.ecotable td > table > tbody > tr > td:nth-child(6) {
	width: 8%;    /* Delete — ~105px, plenty for the word */
	white-space: nowrap;
}
/* Actions table sits inside a td colspan="2" — span the full cell
 * width AND zero out the cell's left/right padding so the table
 * edges align flush with the outer form column boundaries. That
 * gives symmetric left/right whitespace equal to the outer form
 * padding on both sides, no matter what the column widths sum to. */
body.modern.eco-form-page table.ecotable td[colspan="2"] {
	padding-left: 0;
	padding-right: 0;
}
body.modern.eco-form-page table.ecotable td[colspan="2"] > table {
	width: 100%;
	margin: 0;
	border-collapse: collapse;
}

/* ------------------------------------------------------------------
 * Mobile responsive — collapse the actions table to a stacked list
 * of "cards" per action so it works on phones. Each row becomes a
 * block; each cell shows its column header as a label above the value.
 * Triggered under 768px viewport.
 * ------------------------------------------------------------------ */
@media (max-width: 900px) {
	body.modern.eco-form-page table.ecotable td > table,
	body.modern.eco-form-page table.ecotable td > table > tbody,
	body.modern.eco-form-page table.ecotable td > table > tbody > tr,
	body.modern.eco-form-page table.ecotable td > table > tbody > tr > td {
		display: block;
		width: 100% !important;
		max-width: none !important;
		min-width: 0 !important;
	}
	/* Hide the header row on mobile — labels are shown inline via
	 * data-label attributes on each cell (added by JS at the bottom
	 * of eco_form.php on mobile). */
	body.modern.eco-form-page table.ecotable td > table > tbody > tr:first-child {
		display: none;
	}
	/* Card-style visual separation for each action. */
	body.modern.eco-form-page tr.existingAction {
		border: 1px solid var(--border-subtle, #e5e7eb);
		border-radius: 8px;
		padding: 10px;
		margin-bottom: 12px;
		background: var(--bg-surface, #fff);
	}
	body.modern.eco-form-page tr.existingAction > td {
		padding: 6px 4px;
		border-bottom: 1px dashed var(--border-subtle, #eee);
	}
	body.modern.eco-form-page tr.existingAction > td:last-child {
		border-bottom: none;
	}
	body.modern.eco-form-page tr.existingAction > td::before {
		content: attr(data-label);
		display: block;
		font-size: 11px;
		font-weight: 600;
		color: var(--text-tertiary, #8d97a8);
		text-transform: uppercase;
		letter-spacing: 0.3px;
		margin-bottom: 4px;
	}
	body.modern.eco-form-page tr.existingAction textarea {
		min-height: 80px;
	}
}
/* Background field — taller textarea, no width clamp. */
body.modern.eco-form-page #background,
body.modern.eco-form-page #public_desc {
	max-width: none;
}

/* ---- Mobile: stack the form's label / value pairs vertically ---------- *
 * The ECO form is one giant <table class="ecotable"> with two columns:
 * label (bgcolor=#f8f8f8) on the left, value on the right. On phone-
 * width viewports the 200px label column forces the value cell into a
 * narrow strip and content (notably the Parent Parts picker and
 * Image/PDF upload cell) appears to overflow. Switch to block-display
 * so the label sits on top of the value full-width.
 */
@media (max-width: 720px) {
	body.modern.eco-form-page table.ecotable,
	body.modern.eco-form-page table.ecotable tbody,
	body.modern.eco-form-page table.ecotable tr,
	body.modern.eco-form-page table.ecotable td {
		display: block;
		width: 100% !important;
	}
	body.modern.eco-form-page table.ecotable td[bgcolor="#f8f8f8"] {
		width: 100% !important;
		padding: 10px 14px 4px;
		font-size: 11px;
		text-transform: uppercase;
		letter-spacing: 0.5px;
		border-bottom: none;
	}
	body.modern.eco-form-page table.ecotable td {
		padding: 4px 14px 10px;
		border-bottom: none;
	}
	body.modern.eco-form-page table.ecotable tr {
		border-bottom: 1px solid var(--border-subtle);
		padding-bottom: 6px;
	}
	body.modern.eco-form-page table.ecotable td[colspan="2"][bgcolor="#dddddd"] {
		padding: 12px 16px;
	}
	/* Inputs / textareas fill the row on mobile. */
	body.modern.eco-form-page table.ecotable input[type="text"],
	body.modern.eco-form-page table.ecotable input[type="email"],
	body.modern.eco-form-page table.ecotable input[type="number"],
	body.modern.eco-form-page table.ecotable textarea {
		width: 100%;
		max-width: 100%;
		box-sizing: border-box;
	}
}

/* ============================================================== *
 * ECO list cards (Phase E)                                        *
 * ============================================================== */
body.modern .eco-section {
	margin-bottom: 28px;
}

body.modern .eco-section__header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	margin-bottom: 10px;
}

body.modern .eco-section__title {
	font-size: 14px;
	font-weight: 600;
	color: var(--text-secondary);
	text-transform: uppercase;
	letter-spacing: 0.5px;
	margin: 0;
}

body.modern .eco-section__count {
	font-size: 12px;
	color: var(--text-tertiary);
}

body.modern .eco-section__empty {
	background: var(--bg-surface);
	border: 1px dashed var(--border-default);
	border-radius: var(--radius-md);
	padding: 14px 18px;
	color: var(--text-tertiary);
	font-size: 13px;
}

body.modern .eco-cards {
	display: grid;
	gap: 10px;
}

body.modern .eco-card {
	background: var(--bg-surface);
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-lg);
	padding: 14px 18px;
	display: grid;
	grid-template-columns: 60px minmax(0, 1fr) auto auto;
	gap: 16px;
	align-items: center;
	transition: border-color 0.15s ease, box-shadow 0.15s ease;
	overflow: hidden;   /* keep content inside the rounded border */
}
/* .eco-card__main is the "1fr" grid column. Without min-width:0
 * (via minmax(0, 1fr) above) long unbroken text pushes the badge
 * and Open link beyond the card border. */
body.modern .eco-card__main {
	min-width: 0;
}
/* When the bulk-select checkbox is present, prepend a fifth column for
 * it. Without this override the checkbox landed in the id column and
 * pushed the Open link out of its `auto` slot on the right. */
body.modern .eco-card--bulkable {
	grid-template-columns: 24px 60px minmax(0, 1fr) auto auto;
}

body.modern .eco-card:hover {
	border-color: var(--nk-blue-light);
	box-shadow: 0 2px 6px rgba(1, 102, 160, 0.07);
}

body.modern .eco-card__id-label {
	font-size: 11px;
	color: var(--text-tertiary);
	font-weight: 500;
	text-transform: uppercase;
	letter-spacing: 0.5px;
}

body.modern .eco-card__id {
	font-size: 18px;
	font-weight: 600;
	color: var(--text-primary);
}

body.modern .eco-card__title {
	font-size: 14px;
	font-weight: 500;
	color: var(--text-primary);
	text-decoration: none;
}
body.modern .eco-card__title:hover { color: var(--nk-blue); text-decoration: none; }

body.modern .eco-card__meta {
	font-size: 12px;
	color: var(--text-secondary);
	margin-top: 3px;
	display: flex;
	gap: 12px;
	flex-wrap: wrap;
	align-items: center;
}
body.modern .eco-card__meta i { font-size: 13px; margin-right: 3px; vertical-align: -1px; }

body.modern .eco-card__open {
	color: var(--nk-blue);
	font-size: 13px;
	font-weight: 500;
	text-decoration: none;
	white-space: nowrap;
}
body.modern .eco-card__open:hover { text-decoration: none; }

/* Urgency stripe on the left edge (subtle visual cue). */
body.modern .eco-card--urg-high   { border-left: 3px solid var(--status-cancelled-fg); }
body.modern .eco-card--urg-medium { border-left: 3px solid var(--status-proposed-fg); }
body.modern .eco-card--urg-low    { border-left: 3px solid var(--status-completed-fg); }

/* Mobile reflow */
@media (max-width: 640px) {
	body.modern .eco-card {
		grid-template-columns: auto 1fr;
		grid-template-rows: auto auto;
	}
	body.modern .eco-card--bulkable {
		grid-template-columns: auto auto 1fr;
	}
	body.modern .eco-card__main { grid-column: 1 / -1; }
	body.modern .eco-card__open { grid-column: 2; justify-self: end; }
}

/* ============================================================== *
 * Auth shell — login / set_password / forgot                      *
 * Standalone full-viewport centered card. No top nav.             *
 * ============================================================== */
body.modern.auth-page {
	min-height: 100vh;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 24px;
}

body.modern .auth-card {
	background: var(--bg-surface);
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-lg);
	padding: 32px;
	width: 100%;
	max-width: 420px;
}

body.modern .auth-card__brand {
	display: flex;
	align-items: center;
	gap: 10px;
	color: var(--nk-blue);
	font-size: 18px;
	font-weight: 600;
	margin-bottom: 4px;
}
body.modern .auth-card__brand i { font-size: 22px; }

/* Original NK Portal banner above the auth card content. Constrained to the
   card width so it never overflows on phones; max-height keeps it from
   dominating the viewport. */
body.modern .auth-card__logo-link {
	display: block;
	margin-bottom: 16px;
	text-align: center;
}
body.modern .auth-card__logo {
	max-width: 100%;
	max-height: 60px;
	width: auto;
	border-radius: 6px;
}

body.modern .auth-card__subtitle {
	font-size: 13px;
	color: var(--text-secondary);
	margin-bottom: 24px;
}

body.modern .auth-card__footer {
	margin-top: 20px;
	font-size: 12px;
	color: var(--text-tertiary);
	text-align: center;
}

/* ============================================================== *
 * Generic list cards (admin Users + Parts/Models)                 *
 * Same visual treatment as .eco-card so listing screens read      *
 * consistently. Optional avatar column on the left.               *
 * ============================================================== */
body.modern .list-cards { display: grid; gap: 10px; }

body.modern .list-card {
	background: var(--bg-surface);
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-lg);
	padding: 14px 18px;
	display: grid;
	grid-template-columns: auto 1fr auto auto;
	gap: 16px;
	align-items: center;
	transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
body.modern .list-card:hover {
	border-color: var(--nk-blue-light);
	box-shadow: 0 2px 6px rgba(1, 102, 160, 0.07);
}
body.modern .list-card--no-avatar { grid-template-columns: 1fr auto auto; }

body.modern .list-card__avatar {
	width: 36px;
	height: 36px;
	bor

/* ==========================================================================
   Bulk PDF export UI (Feat 11) - checkbox + toolbar on list.php
   ==========================================================================
   Appended block. The rule above may or may not have been terminated in
   the working tree (see 46k HEAD vs 35k working copy); the leading close
   brace is defensive and harmless when the previous rule is already closed.
*/
}

/* Checkbox lives on the .eco-card grid. .eco-card is already a grid /
   flex container; we prepend the checkbox column and let the existing
   auto-layout absorb it. Kept small + subtle so it doesn't compete with
   the ECO id block. */
body.modern .eco-card__bulk {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding-right: 4px;
	cursor: pointer;
	user-select: none;
}
body.modern .eco-card__bulk input[type="checkbox"] {
	width: 18px;
	height: 18px;
	margin: 0;
	cursor: pointer;
	accent-color: var(--nk-blue, #0166A0);
}

/* Sticky bulk-actions toolbar. Sits below the search/chip row and stays
   visible while the user scrolls through cards. Hidden by default via the
   HTML `hidden` attribute; JS toggles it. */
body.modern .eco-bulk-bar {
	position: sticky;
	top: 8px;
	z-index: 30;
	display: flex;
	align-items: center;
	gap: 12px;
	flex-wrap: wrap;
	margin: 0 0 14px 0;
	padding: 10px 14px;
	background: var(--bg-surface, #fff);
	border: 1px solid var(--nk-blue-light, #cfe3f0);
	border-radius: var(--radius-lg, 10px);
	box-shadow: 0 2px 6px rgba(1, 102, 160, 0.10);
}
body.modern .eco-bulk-bar[hidden] { display: none; }

/* Floating scroll-to-top button, injected once by includes/ecohead.php.
 * Hidden until the user scrolls past ~300px, then fades in.
 * CSS was previously missing — the button rendered in normal document
 * flow at the top of the page. This lifts it to fixed-position FAB. */
body.modern .scroll-top {
	position: fixed;
	right: 24px;
	bottom: 24px;
	z-index: 50;
	width: 40px;
	height: 40px;
	border-radius: 50%;
	background: var(--nk-blue);
	color: var(--text-inverse);
	border: none;
	cursor: pointer;
	box-shadow: 0 4px 12px rgba(0, 0, 0, 0.18);
	display: none;
	align-items: center;
	justify-content: center;
	font-size: 18px;
	transition: transform 0.15s ease, background 0.15s ease;
}
body.modern .scroll-top.is-visible { display: flex; }
body.modern .scroll-top:hover {
	background: var(--nk-blue-dark);
	transform: translateY(-2px);
}
body.modern .eco-bulk-bar__count {
	font-weight: 600;
	color: var(--text-primary, #111);
}
body.modern .eco-bulk-bar__hint {
	font-size: 12px;
	margin-left: auto;
}

/* ------------------------------------------------------------------
 * "Needs you" highlighting on the ECO form.
 *
 * Every approver / action row can be marked with .is-my-turn when it
 * belongs to the current user AND needs their attention. We render:
 *   1. red left border + subtle bg tint on the row itself,
 *   2. emphasized (pulsing) Approve / Complete button in that row,
 *   3. red "Needs you" pill on the accordion header for any section
 *      that contains at least one is-my-turn row (JS-injected in
 *      eco_form.php's collapse setup).
 * ------------------------------------------------------------------ */
/* High specificity — inner-table cells have inline bgcolor (#f8f8f8)
 * which is a "presentation hint" and can be overridden without
 * !important, but the extra .is-my-turn scoping keeps us safe against
 * later legacy overrides. */
body.modern tr.is-my-turn > td,
body.modern table tr.is-my-turn > td {
	background-color: #fef2f2 !important;  /* soft red tint */
}
body.modern tr.is-my-turn > td:first-child,
body.modern table tr.is-my-turn > td:first-child {
	border-left: 4px solid #dc2626 !important;
}
body.modern tr.is-my-turn > td:not(:first-child),
body.modern table tr.is-my-turn > td:not(:first-child) {
	border-top: 1px solid #fecaca !important;
	border-bottom: 1px solid #fecaca !important;
}
/* Emphasize the Approve / Complete button inside a needs-you row. */
body.modern tr.is-my-turn input[type="button"],
body.modern tr.is-my-turn button[type="button"] {
	background: #dc2626;
	color: #fff;
	border: 1px solid #b91c1c;
	font-weight: 600;
	padding: 6px 12px;
	border-radius: 6px;
	cursor: pointer;
	animation: eco-needsme-pulse 2.2s ease-in-out infinite;
	box-shadow: 0 0 0 0 rgba(220, 38, 38, 0.4);
}
body.modern tr.is-my-turn input[type="button"]:hover,
body.modern tr.is-my-turn button[type="button"]:hover {
	background: #b91c1c;
}
@keyframes eco-needsme-pulse {
	0%   { box-shadow: 0 0 0 0 rgba(220, 38, 38, 0.5); }
	70%  { box-shadow: 0 0 0 8px rgba(220, 38, 38, 0);  }
	100% { box-shadow: 0 0 0 0 rgba(220, 38, 38, 0);    }
}
/* Tint the section header row when it contains the JS-injected badge —
 * so a collapsed section still calls attention against gray peers. */
body.modern tr.has-needs-me td[colspan="2"][bgcolor="#dddddd"] {
	background: #fff1f2 !important;
	border-left: 3px solid #dc2626 !important;
}
