/* Reusable component styles (buttons, cards, forms, etc.) */

/* ============ SIDEBAR NAVBAR ============ */

.sidebar {
	position: fixed;
	left: 0;
	top: 0;
	bottom: 0;
	width: 250px;
	background-color: var(--bg-secondary);
	border-right: 1px solid var(--border-color);
	display: flex;
	flex-direction: column;
	z-index: 100;
	transition: width 0.3s ease;
}

/* Sidebar Toggle Button */
.sidebar-toggle {
	position: absolute;
	right: -12px;
	top: 50%;
	transform: translateY(-50%);
	width: 24px;
	height: 48px;
	background: var(--bg-secondary);
	border: 1px solid var(--border-color);
	border-radius: 0 8px 8px 0;
	display: flex;
	align-items: center;
	justify-content: center;
	cursor: pointer;
	z-index: 101;
	transition: all 0.2s ease;
	padding: 0;
}

.sidebar-toggle:hover {
	background: var(--bg-tertiary);
	border-color: var(--primary-color);
}

.sidebar-toggle svg {
	width: 16px;
	height: 16px;
	color: var(--text-muted);
	transition: transform 0.3s ease;
}

.sidebar-toggle:hover svg {
	color: var(--primary-color);
}

.sidebar-header {
	padding: var(--spacing-lg);
	border-bottom: 1px solid var(--border-color);
}

.sidebar-logo {
	font-size: var(--font-size-xl);
	font-weight: 700;
	color: var(--color-primary);
	text-decoration: none;
}

.sidebar-logo:hover {
	color: var(--color-primary-hover);
}

.sidebar-nav {
	flex: 1;
	padding: var(--spacing-md) 0;
	overflow-y: auto;
}

.nav-section {
	margin-bottom: var(--spacing-lg);
}

.nav-section-title {
	padding: var(--spacing-sm) var(--spacing-lg);
	font-size: var(--font-size-sm);
	font-weight: 600;
	color: var(--text-muted);
	text-transform: uppercase;
	letter-spacing: 0.05em;
}

.nav-item {
	display: flex;
	align-items: center;
	gap: var(--spacing-sm);
	padding: var(--spacing-sm) var(--spacing-lg);
	color: var(--text-secondary);
	text-decoration: none;
	position: relative;
	overflow: hidden;
	transition: color 0.25s ease, background-color 0.25s ease;
}

/* A Systems link before the server has said where that product lives. Dimmed
   and not clickable, because a link that looks live and goes nowhere is worse
   than one that looks dead - the admin retries instead of reporting it. */
.nav-item[aria-disabled="true"] {
	opacity: 0.45;
	cursor: default;
	pointer-events: none;
}

/* Background glow effect */
.nav-item::before {
	content: '';
	position: absolute;
	inset: 0;
	background: linear-gradient(90deg, var(--color-primary), transparent);
	opacity: 0;
	transition: opacity 0.3s ease;
}

/* Left accent bar */
.nav-item::after {
	content: '';
	position: absolute;
	left: 0;
	top: 50%;
	height: 0;
	width: 3px;
	background: var(--color-primary);
	border-radius: 0 2px 2px 0;
	box-shadow: 0 0 8px var(--color-primary);
	transition: height 0.25s ease, top 0.25s ease;
}

.nav-item:hover {
	background-color: var(--bg-tertiary);
	color: var(--text-primary);
}

.nav-item:hover::before {
	opacity: 0.05;
}

.nav-item:hover::after {
	height: 50%;
	top: 25%;
}

.nav-item.active {
	background-color: var(--bg-tertiary);
	color: var(--color-primary);
}

.nav-item.active::before {
	opacity: 0.1;
}

.nav-item.active::after {
	height: 60%;
	top: 20%;
}

.nav-item-icon {
	width: 20px;
	height: 20px;
	opacity: 0.7;
}

.nav-item:hover .nav-item-icon,
.nav-item.active .nav-item-icon {
	opacity: 1;
}

.sidebar-footer {
	padding: var(--spacing-md) var(--spacing-lg);
	border-top: 1px solid var(--border-color);
}

.sidebar-user {
	display: flex;
	align-items: center;
	gap: var(--spacing-sm);
	margin-bottom: var(--spacing-sm);
}

.sidebar-user-avatar {
	width: 36px;
	height: 36px;
	border-radius: var(--radius-full);
	background-color: var(--color-primary);
	display: flex;
	align-items: center;
	justify-content: center;
	font-weight: 600;
	color: white;
}

.sidebar-user-info {
	flex: 1;
	min-width: 0;
}

.sidebar-user-name {
	font-weight: 500;
	color: var(--text-primary);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.sidebar-user-role {
	font-size: var(--font-size-sm);
	color: var(--text-muted);
}

.sidebar-logout {
	display: flex;
	align-items: center;
	gap: var(--spacing-sm);
	padding: var(--spacing-sm);
	width: 100%;
	background: none;
	border: none;
	color: var(--text-secondary);
	cursor: pointer;
	border-radius: var(--radius-md);
	transition: all var(--transition-fast);
}

.sidebar-logout:hover {
	background-color: var(--bg-tertiary);
	color: var(--color-danger);
}

/* Collapsed Sidebar State */
.sidebar.collapsed {
	width: 60px;
}

.sidebar.collapsed .sidebar-logo {
	display: none;
}

.sidebar.collapsed .sidebar-header {
	padding: var(--spacing-md);
	display: flex;
	justify-content: center;
}

.sidebar.collapsed .sidebar-header::before {
	content: 'K';
	font-size: var(--font-size-xl);
	font-weight: 700;
	color: var(--color-primary);
}

.sidebar.collapsed .nav-section-title {
	display: none;
}

.sidebar.collapsed .nav-item {
	justify-content: center;
	padding: var(--spacing-sm);
}

.sidebar.collapsed .nav-item span {
	display: none;
}

.sidebar.collapsed .nav-item-icon {
	width: 24px;
	height: 24px;
}

.sidebar.collapsed .sidebar-toggle svg {
	transform: rotate(180deg);
}

.sidebar.collapsed .sidebar-footer {
	padding: var(--spacing-sm);
}

.sidebar.collapsed .sidebar-user-info {
	display: none;
}

.sidebar.collapsed .sidebar-user {
	justify-content: center;
}

.sidebar.collapsed .sidebar-logout span {
	display: none;
}

.sidebar.collapsed .sidebar-logout {
	justify-content: center;
}

/* Main content adjusts with sidebar */
.main-content {
	margin-left: 250px;
	min-height: 100vh;
	padding: var(--spacing-xl);
	transition: margin-left 0.3s ease;
}

body.sidebar-collapsed .main-content {
	margin-left: 60px;
}

.page-header {
	margin-bottom: var(--spacing-xl);
}

.page-title {
	font-size: var(--font-size-2xl);
	font-weight: 600;
	color: var(--text-primary);
	margin-bottom: var(--spacing-xs);
}

.page-subtitle {
	color: var(--text-secondary);
}

/* ============ CARDS ============ */

.card {
	background-color: var(--bg-card);
	border-radius: var(--radius-lg);
	border: 1px solid var(--border-color);
	padding: var(--spacing-lg);
}

.card-header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	margin-bottom: var(--spacing-md);
}

.card-title {
	font-size: var(--font-size-lg);
	font-weight: 600;
	color: var(--text-primary);
}

/* ============ STATS GRID ============ */

.stats-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
	gap: var(--spacing-md);
	margin-bottom: var(--spacing-xl);
}

.stat-card {
	background-color: var(--bg-card);
	border-radius: var(--radius-lg);
	border: 1px solid var(--border-color);
	padding: var(--spacing-lg);
}

.stat-label {
	font-size: var(--font-size-sm);
	color: var(--text-muted);
	margin-bottom: var(--spacing-xs);
}

.stat-value {
	font-size: var(--font-size-2xl);
	font-weight: 600;
	color: var(--text-primary);
}

/* ============ TABLES ============ */

.table-container {
	overflow-x: auto;
}

.data-table {
	width: 100%;
	border-collapse: collapse;
}

.data-table th,
.data-table td {
	padding: var(--spacing-sm) var(--spacing-md);
	text-align: left;
	border-bottom: 1px solid var(--border-color);
}

.data-table th {
	font-weight: 600;
	color: var(--text-secondary);
	font-size: var(--font-size-sm);
}

/* A heading you can click has to look like one, and has to say which way it
   sorted. The arrow is a pseudo-element so it never lands in textContent - the
   sorter reads headings to decide which are sortable, and an arrow baked into
   the markup would become part of the label it tests. */
.data-table th.is-sortable {
	cursor: pointer;
	user-select: none;
	white-space: nowrap;
}
.data-table th.is-sortable:hover { color: var(--text-primary); }
.data-table th.is-sortable::after {
	content: '';
	display: inline-block;
	margin-left: 0.35rem;
	border-left: 4px solid transparent;
	border-right: 4px solid transparent;
	border-bottom: 5px solid currentColor;
	opacity: 0;                      /* only on hover, until it is the sorted one */
	transform: translateY(-1px);
	transition: opacity 0.12s;
}
.data-table th.is-sortable:hover::after { opacity: 0.35; }
.data-table th.is-sorted { color: var(--text-primary); }
.data-table th.is-sorted::after { opacity: 1; }
.data-table th.is-sorted-desc::after {
	border-bottom: 0;
	border-top: 5px solid currentColor;
}

.data-table td {
	color: var(--text-primary);
}

.data-table tbody tr:hover {
	background-color: var(--bg-tertiary);
}

/* ============ BADGES ============ */

.badge {
	display: inline-block;
	padding: 2px var(--spacing-sm);
	font-size: var(--font-size-sm);
	font-weight: 500;
	border-radius: var(--radius-full);
}

.badge-success {
	background-color: rgba(16, 185, 129, 0.1);
	color: var(--color-success);
}

.badge-danger {
	background-color: rgba(239, 68, 68, 0.1);
	color: var(--color-danger);
}

.badge-warning {
	background-color: rgba(245, 158, 11, 0.1);
	color: var(--color-warning);
}

.badge-primary {
	background-color: rgba(79, 70, 229, 0.1);
	color: var(--color-primary);
}

.badge-secondary {
	background-color: rgba(107, 114, 128, 0.1);
	color: var(--color-secondary);
}

/* ============ ACTION BAR ============ */

.action-bar {
	display: flex;
	justify-content: space-between;
	align-items: center;
	margin-bottom: var(--spacing-lg);
	gap: var(--spacing-md);
}

.search-box {
	flex: 1;
	max-width: 300px;
}

.btn-icon {
	width: 18px;
	height: 18px;
	margin-right: var(--spacing-xs);
}

/* ============ MODALS ============ */

.modal-overlay {
	position: fixed;
	inset: 0;
	background-color: rgba(0, 0, 0, 0.6);
	display: flex;
	align-items: center;
	justify-content: center;
	z-index: 200;
	opacity: 0;
	visibility: hidden;
	transition: all var(--transition-base);
}

.modal-overlay.active {
	opacity: 1;
	visibility: visible;
}

.modal {
	background-color: var(--bg-secondary);
	border-radius: var(--radius-lg);
	border: 1px solid var(--border-color);
	width: 100%;
	max-width: 500px;
	max-height: 90vh;
	overflow-y: auto;
	transform: scale(0.95);
	transition: transform var(--transition-base);
}

.modal-overlay.active .modal {
	transform: scale(1);
}

.modal-sm {
	max-width: 400px;
}

.modal-header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: var(--spacing-lg);
	border-bottom: 1px solid var(--border-color);
}

.modal-title {
	font-size: var(--font-size-lg);
	font-weight: 600;
	color: var(--text-primary);
}

.modal-close {
	background: none;
	border: none;
	font-size: 1.5rem;
	color: var(--text-muted);
	cursor: pointer;
	padding: 0;
	line-height: 1;
}

.modal-close:hover {
	color: var(--text-primary);
}

.modal-body {
	padding: var(--spacing-lg);
}

.modal-footer {
	display: flex;
	justify-content: flex-end;
	gap: var(--spacing-sm);
	padding: var(--spacing-lg);
	border-top: 1px solid var(--border-color);
}

/* ============ FORM EXTRAS ============ */

.form-hint {
	display: block;
	margin-top: var(--spacing-xs);
	font-size: var(--font-size-sm);
	color: var(--text-muted);
}

.checkbox-label {
	display: flex;
	align-items: center;
	gap: var(--spacing-sm);
	cursor: pointer;
	color: var(--text-primary);
}

.checkbox-label input[type="checkbox"] {
	width: 1rem;
	height: 1rem;
	accent-color: var(--color-primary);
}

/* ============ ICON BUTTONS ============ */

.btn-icon-sm {
	background: none;
	border: none;
	padding: var(--spacing-xs);
	cursor: pointer;
	color: var(--text-secondary);
	border-radius: var(--radius-md);
	transition: all var(--transition-fast);
}

.btn-icon-sm:hover {
	background-color: var(--bg-tertiary);
	color: var(--text-primary);
}

.btn-icon-sm svg {
	width: 18px;
	height: 18px;
}

.btn-icon-danger:hover {
	color: var(--color-danger);
}

.action-buttons {
	display: flex;
	gap: var(--spacing-xs);
}

/* ============ USER CELL ============ */

.user-cell {
	display: flex;
	align-items: center;
	gap: var(--spacing-sm);
}

.user-avatar {
	width: 32px;
	height: 32px;
	border-radius: var(--radius-full);
	background-color: var(--color-primary);
	display: flex;
	align-items: center;
	justify-content: center;
	font-weight: 600;
	font-size: var(--font-size-sm);
	color: white;
}

/* ============ BUTTON VARIANTS ============ */

.btn-danger {
	background-color: var(--color-danger);
	color: white;
}

.btn-danger:hover {
	background-color: #dc2626;
}

/* ============ TEXT UTILITIES ============ */

.text-danger {
	color: var(--color-danger);
	font-size: var(--font-size-sm);
	margin-top: var(--spacing-sm);
}

/* ============ TOAST NOTIFICATIONS ============ */

.toast-container {
	position: fixed;
	top: var(--spacing-lg);
	right: var(--spacing-lg);
	z-index: 9999;
	display: flex;
	flex-direction: column;
	gap: var(--spacing-sm);
	pointer-events: none;
}

.toast {
	display: flex;
	align-items: center;
	gap: var(--spacing-sm);
	padding: var(--spacing-md) var(--spacing-lg);
	background: var(--bg-secondary);
	border: 1px solid var(--border-color);
	border-radius: var(--radius-lg);
	box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
	pointer-events: auto;
	min-width: 300px;
	max-width: 450px;
	opacity: 0;
	transform: translateX(100%);
	transition: none;
}

.toast-show {
	animation: toast-in 0.3s ease forwards;
}

.toast-hiding {
	animation: toast-out 0.25s ease forwards;
}

@keyframes toast-in {
	from {
		opacity: 0;
		transform: translateX(100%);
	}
	to {
		opacity: 1;
		transform: translateX(0);
	}
}

@keyframes toast-out {
	from {
		opacity: 1;
		transform: translateX(0);
	}
	to {
		opacity: 0;
		transform: translateX(100%);
	}
}

.toast-icon {
	flex-shrink: 0;
	width: 20px;
	height: 20px;
}

.toast-icon svg {
	width: 100%;
	height: 100%;
}

.toast-message {
	flex: 1;
	font-size: var(--font-size-sm);
	color: var(--text-primary);
}

.toast-close {
	flex-shrink: 0;
	width: 24px;
	height: 24px;
	padding: 0;
	background: none;
	border: none;
	color: var(--text-muted);
	cursor: pointer;
	font-size: 18px;
	line-height: 1;
	opacity: 0.6;
	transition: opacity 0.15s ease;
}

.toast-close:hover {
	opacity: 1;
}

/* Toast types */
.toast-success {
	border-left: 3px solid var(--color-success);
}

.toast-success .toast-icon {
	color: var(--color-success);
}

.toast-error {
	border-left: 3px solid var(--color-danger);
}

.toast-error .toast-icon {
	color: var(--color-danger);
}

.toast-warning {
	border-left: 3px solid var(--color-warning);
}

.toast-warning .toast-icon {
	color: var(--color-warning);
}

.toast-info {
	border-left: 3px solid var(--color-primary);
}

.toast-info .toast-icon {
	color: var(--color-primary);
}

/* ── Supported devices ───────────────────────────────────────────────────────
   Shared by the admin panel and BoatLink: the same list answering the same
   question, so it is styled once here rather than in each shell's own sheet. */
/* The admin catalogue's three product groups. Only that view groups - both
   front ends are filtered to their own product before they render. */
.sd-group + .sd-group { margin-top: var(--spacing-lg); padding-top: var(--spacing-lg); border-top: 1px solid var(--border-color); }
.sd-group-title {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	margin: 0 0 0.15rem;
	font-size: 1rem;
	color: var(--text-primary);
}
.sd-group-count {
	font-size: 0.75rem;
	font-weight: 600;
	color: var(--text-secondary);
	background: var(--bg-tertiary);
	border-radius: var(--radius-full);
	padding: 0.1rem 0.5rem;
	font-variant-numeric: tabular-nums;
}
.sd-group-blurb { margin: 0 0 0.6rem; color: var(--text-muted); font-size: var(--font-size-sm); }

.sd-list { display: block; }

.sd-item { border-bottom: 1px solid var(--border-color); }
.sd-item:last-child { border-bottom: 0; }

.sd-item > summary {
	display: flex;
	align-items: baseline;
	gap: var(--spacing-sm, 8px);
	padding: 12px 0;
	cursor: pointer;
	list-style: none;
}

.sd-item > summary::-webkit-details-marker { display: none; }

.sd-name {
	flex: 1;
	min-width: 0;
	font-weight: 600;
	color: var(--text-primary);
}

.sd-conn {
	flex: none;
	font-size: 0.72rem;
	color: var(--text-muted);
	text-transform: uppercase;
	letter-spacing: 0.03em;
}

.sd-status {
	flex: none;
	padding: 2px 8px;
	border-radius: 9999px;
	font-size: 0.68rem;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	background: var(--bg-tertiary);
	color: var(--text-muted);
}

.sd-status-beta { background: rgba(245, 158, 11, 0.16); color: #f59e0b; }
.sd-status-planned { background: rgba(148, 163, 184, 0.16); color: #94a3b8; }
.sd-status-discontinued { background: rgba(148, 163, 184, 0.16); color: #94a3b8; }

/* The archive: products no longer sold, kept because the units fitted still
   report and whoever has one still needs the wiring and the traps.
   Set apart from the product groups rather than badged inside them - those
   answer "what can I fit", and something unbuyable is a wrong answer there
   however it is labelled. Collapsed, so a shopper scrolls past one line. */
.sd-archive {
	margin-top: var(--spacing-lg);
	padding-top: var(--spacing-lg);
	border-top: 1px solid var(--border-color);
}
.sd-archive-summary {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	cursor: pointer;
	font-size: 1rem;
	font-weight: 600;
	color: var(--text-secondary);
	list-style: none;
}
.sd-archive-summary::-webkit-details-marker { display: none; }
.sd-archive-summary::before {
	content: '▸';
	font-size: 0.8em;
	color: var(--text-muted);
	transition: transform 0.15s ease;
}
.sd-archive[open] > .sd-archive-summary::before { transform: rotate(90deg); }

/* Retired entries read dimmer than current ones, but the text stays legible -
   this is reference material for someone troubleshooting, not a tombstone. */
.sd-archive .sd-item > summary .sd-name { color: var(--text-secondary); }
.sd-retired {
	margin: 0 0 0.5rem;
	padding: 0.5rem 0.7rem;
	border-left: 3px solid var(--border-color);
	background: var(--bg-tertiary);
	border-radius: var(--radius-sm);
	color: var(--text-secondary);
	font-size: var(--font-size-sm);
}
.sd-retired em { color: var(--text-muted); font-style: normal; display: block; margin-top: 0.25rem; }

.sd-body {
	padding: 0 0 14px;
	font-size: 0.85rem;
	color: var(--text-secondary);
	line-height: 1.5;
}

.sd-summary { margin: 0 0 8px; }

.sd-reports,
.sd-note {
	margin: 0 0 8px;
	color: var(--text-muted);
}

.sd-secret,
.sd-note {
	padding: 8px 10px;
	border-radius: 8px;
}

.sd-secret {
	margin: 0 0 8px;
	background: rgba(245, 158, 11, 0.10);
	color: #f59e0b;
}

.sd-note { background: rgba(148, 163, 184, 0.10); }

.sd-steps { margin: 0; padding-left: 1.25em; }
.sd-steps li { margin-bottom: 6px; }

/* ── Dropdowns ───────────────────────────────────────────────────────────────
   One treatment for every <select> in every product. There are 57 of them
   across 20 files, and before this they were styled in five different
   stylesheets or not at all - so the same control looked different on the admin
   panel, the boat page and the user dashboard, and several rendered as the raw
   browser widget on a dark surface.

   Two halves to a dropdown and only one is ours. The closed control is an
   ordinary box we can style; the popup list is drawn by the operating system
   and CSS cannot touch it. `color-scheme: dark` in variables.css is what makes
   that half dark - the rules here are the half we own.

   Lives in components.css because every product loads it: admin, BoatLink,
   HomeLink, the user dashboard and the login page all pull it in before their
   own sheet. */
select {
	/* The native arrow goes, so we own the whole box. Everything below assumes
	   it - remove this and the chevron doubles up. */
	appearance: none;
	-webkit-appearance: none;
	-moz-appearance: none;

	padding: 0.4rem 2rem 0.4rem 0.65rem;
	background-color: var(--bg-tertiary);
	border: 1px solid var(--border-color);
	border-radius: var(--radius-md, 0.5rem);
	color: var(--text-primary);
	font: inherit;
	line-height: 1.4;
	cursor: pointer;
	max-width: 100%;

	/* A drawn chevron rather than an icon font or an extra wrapper element:
	   57 controls across 20 files, and none of them has a spare span to hang
	   one on. Hard-coded slate rather than currentColor because a background
	   image cannot inherit it, which is safe here - there is one theme. */
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%2394a3b8' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 0.55rem center;
	background-size: 0.85rem;
}

select:hover:not(:disabled) {
	border-color: var(--text-muted);
}

select:focus-visible {
	outline: 2px solid var(--border-focus, #4f46e5);
	outline-offset: 1px;
	border-color: var(--border-focus, #4f46e5);
}

/* Keyboard focus gets the ring above; a mouse click should not paint one. */
select:focus:not(:focus-visible) {
	outline: none;
	border-color: var(--border-focus, #4f46e5);
}

select:disabled {
	opacity: 0.55;
	cursor: not-allowed;
}

/* An open list box or a multi-select is not a dropdown: it has no popup and no
   collapsed state, so a chevron floating in its top-right corner is furniture
   pointing at nothing. */
select[multiple],
select[size]:not([size="1"]) {
	background-image: none;
	padding-right: 0.65rem;
	cursor: default;
}

/* Respected by Firefox and by Chrome on Windows; ignored elsewhere, where
   color-scheme already did the work. Set anyway because where it applies it is
   the difference between a readable list and a white one. */
select option {
	background-color: var(--bg-secondary);
	color: var(--text-primary);
}

select option:disabled {
	color: var(--text-muted);
}
