:root {
	--color-bg: #f4f6f8;
	--color-surface: #ffffff;
	--color-border: #dde2e7;
	--color-text: #1f2933;
	--color-text-muted: #5a6875;
	--color-primary: #2f6fed;
	--color-primary-dark: #1d4fbf;
	--color-info-bg: #fff3b0;
	--color-ai-bg: #eef3ff;
	--radius: 8px;
	--spacing: 16px;
}

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

body {
	font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
	background: var(--color-bg);
	color: var(--color-text);
	margin: 0;
	line-height: 1.5;
}

a {
	color: var(--color-primary);
}

h1, h2, h3 {
	line-height: 1.25;
}

h1 {
	font-size: 1.6em;
}

/* Top navigation (logged-in pages) */

.topnav {
	background: var(--color-surface);
	border-bottom: 1px solid var(--color-border);
	position: sticky;
	top: 0;
	z-index: 10;
}

.topnav-inner {
	max-width: 1100px;
	margin: 0 auto;
	padding: 10px var(--spacing);
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 6px 16px;
}

.topnav-brand {
	font-weight: 700;
	margin-right: auto;
	text-decoration: none;
	color: var(--color-text);
}

.topnav-links {
	display: flex;
	flex-wrap: wrap;
	gap: 2px;
}

.topnav-links a {
	display: inline-block;
	padding: 8px 12px;
	border-radius: var(--radius);
	text-decoration: none;
	color: var(--color-text-muted);
	font-size: 0.95em;
}

.topnav-links a.active,
.topnav-links a:hover {
	background: var(--color-bg);
	color: var(--color-primary);
}

/* Page content */

#main-content, #main-form {
	max-width: 1100px;
	width: 100%;
	margin: 0 auto;
	padding: var(--spacing);
}

#main-form {
	max-width: 480px;
}

#main-form h1 {
	text-align: center;
}

.information {
	background-color: var(--color-info-bg);
	border-radius: var(--radius);
	padding: 12px 16px;
	margin: 16px 0;
}

/* Forms */

form input[type='text'],
form input[type='email'],
form input[type='password'],
form select {
	width: 100%;
	max-width: 400px;
	padding: 10px 12px;
	margin-top: 4px;
	border: 1px solid var(--color-border);
	border-radius: var(--radius);
	background: var(--color-surface);
	color: var(--color-text);
	font-size: 1em;
}

form input[type='text']:focus,
form input[type='email']:focus,
form input[type='password']:focus,
form select:focus {
	outline: none;
	border-color: var(--color-primary);
	box-shadow: 0 0 0 3px rgba(47, 111, 237, 0.15);
}

input[type='submit'] {
	display: inline-block;
	padding: 10px 20px;
	margin-top: 8px;
	background: var(--color-primary);
	color: #fff;
	border: none;
	border-radius: var(--radius);
	font-size: 1em;
	cursor: pointer;
}

input[type='submit']:hover {
	background: var(--color-primary-dark);
}

label {
	cursor: pointer;
}

/* "Genutzte KI" (polar-settings.php) only makes sense once AI is enabled -
   hidden by default, revealed via the checkbox's :checked state rather
   than JS, since it's a plain same-parent sibling. */
.ai-provider-select {
	display: none;
}

#ai-enabled:checked ~ .ai-provider-select {
	display: block;
}

/* "Urlaub" date/alternative-sleep fields (polar-settings.php) only make
   sense once the "on vacation" checkbox is ticked - same pattern as
   .ai-provider-select above. */
.vacation-fields {
	display: none;
}

#on-vacation:checked ~ .vacation-fields {
	display: block;
}

/* Generic tabs (polar-settings.php) - used both for the top-level
   "Technische Optionen" / "Persönliche Daten" split and, nested inside
   the former, the KI-Funktionen provider tabs. */

.tab-buttons {
	display: flex;
	gap: 4px;
	border-bottom: 1px solid var(--color-border);
	margin-bottom: 16px;
}

.tab-button {
	display: inline-block;
	padding: 8px 16px;
	border: none;
	border-bottom: 2px solid transparent;
	background: none;
	font-size: 1em;
	color: var(--color-text-muted);
	text-decoration: none;
	cursor: pointer;
}

.tab-button.active {
	color: var(--color-primary);
	border-bottom-color: var(--color-primary);
}

.tab-panel {
	display: none;
}

.tab-panel.active {
	display: block;
}

/* KI-Funktionen provider tabs' two-column layout (polar-settings.php) */

.ai-tab-columns {
	display: flex;
	gap: 32px;
}

.ai-tab-fields, .ai-tab-text {
	flex: 1;
	min-width: 0;
}

.ai-tab-text {
	color: var(--color-text-muted);
}

.ai-test-result {
	margin-left: 8px;
}

.ai-test-ok {
	color: #1a7f37;
}

.ai-test-fail {
	color: #c0362c;
}

/* Workout suggestion + status-quo + 3-month-goal boxes (polar-dashboard.php) */

.ai-workout-box, .ai-status-box, .ai-goal-box, .training-plan-section {
	background: var(--color-ai-bg);
	border-radius: var(--radius);
	padding: 12px 16px;
	margin: 16px 0;
}

/* "Trainingsplan" tab (polar-dashboard.php) - one .training-plan-section
   per goal (plus the goal-independent one), each its own draggable-row
   table. */
.training-plan-row {
	cursor: grab;
}

.training-plan-row.dragging {
	opacity: 0.4;
}

.training-plan-drag-handle {
	color: var(--color-text-muted);
	user-select: none;
}

.delete-training-plan-item {
	text-decoration: none;
}

.training-plan-evaluation-result {
	margin-top: 12px;
}

/* "Status Quo" + "Gewicht & BMI" side by side on desktop (polar-dashboard.php)
   - the weekly chart doesn't need full width, so splitting the tab this way
   fits both without either one feeling cramped. min-width: 0 lets a flex
   item's wide content (the week table, the chart) actually shrink to the
   column instead of forcing it wider - stacks single-column under 640px,
   same breakpoint as the other two-column layouts on this page. */
.status-quo-columns {
	display: flex;
	gap: 24px;
	align-items: flex-start;
}

.status-quo-columns > .ai-status-box {
	flex: 1 1 0%;
	min-width: 0;
}

/* "Status Quo - Laufende Woche" (left) at 3/5, "Gewicht & BMI" (right) at
   2/5 on desktop - both still start from the same flex-basis: 0%, so the
   3:2 flex-grow ratio alone decides the split regardless of either box's
   content width. Only applies here (not to the mobile breakpoint below,
   which switches to a stacked column layout where a width ratio no longer
   means anything). */
.status-quo-columns > .ai-status-box:first-child {
	flex: 3 1 0%;
}

.status-quo-columns > .ai-status-box:last-child {
	flex: 2 1 0%;
}

.ai-result {
	margin-top: 12px;
	max-height: 240px;
	overflow-y: auto;
	white-space: pre-wrap;
}

.ai-result.ai-result-error {
	color: #c0362c;
}

/* Scored AI evaluation card (render_scored_evaluation_points() in
   src/Support/helpers.php) - shared by the "Tägliches Ernährungsziel"
   evaluation and the weekly-evaluation history entries (polar-dashboard.php)
   alike, both parsed from the same "Kurzbezeichnung | Note | Text" prompt
   format. A bordered surface of its own rather than sitting flush in the
   surrounding box, since .ai-result's white-space: pre-wrap would
   otherwise preserve this template's own PHP indentation as visible
   leading whitespace (same fix as .goal-text above). */
.scored-evaluation-entry {
	white-space: normal;
	background: var(--color-surface);
	border: 1px solid var(--color-border);
	border-radius: var(--radius);
	padding: 12px 16px;
}

/* Date/delete-link header row, shared by the nutrition-goal-evaluation and
   goal-strategy cards (the weekly-evaluation entry has its own KW/date/
   delete header baked into render_evaluation_entry() instead). */
.evaluation-meta {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	gap: 12px;
	font-size: 0.85em;
	color: var(--color-text-muted);
	margin-bottom: 10px;
}

.scored-evaluation-list {
	margin: 0;
	padding-left: 20px;
}

.scored-evaluation-list li {
	margin-bottom: 8px;
}

.scored-evaluation-list li:last-child {
	margin-bottom: 0;
}

.scored-evaluation-list strong {
	color: var(--color-primary-dark);
}

/* "Allgemein" part of a scored evaluation - heading (with its 0-10 score)
   plus a short paragraph, sitting above the per-goal bullet list rather
   than being one of its <li>s. */
.scored-evaluation-general strong {
	color: var(--color-primary-dark);
}

.scored-evaluation-general p {
	margin: 4px 0 0;
}

.scored-evaluation-goals {
	margin-top: 10px;
}

/* Active/archived goal rows (polar-dashboard.php) - same target icon for
   every goal (topic isn't structured data, so this doesn't try to guess
   one per goal), text in the middle, action icons (erreicht/aufgeben/
   löschen) pinned to the end via flex. */
.goal-entry {
	display: flex;
	align-items: center;
	gap: 12px;
	border: 1px solid var(--color-border);
	border-radius: var(--radius);
}

/* "Strategie generieren" button + result for one goal (polar-dashboard.php) -
   sits right below that goal's .goal-entry row, not inside its flex layout,
   since the generated strategy text needs its own full-width block. */
.goal-strategy {
	margin: 8px 0 16px;
}

.goal-strategy .scored-evaluation-entry {
	margin-top: 8px;
}

.goal-icon {
	font-size: 40px;
	line-height: 1;
	flex: 0 0 auto;
}

.goal-text {
	flex: 1;
	min-width: 0;
	text-align: left;
	/* Overrides .ai-result's white-space: pre-wrap - without this, the
	   PHP template's own indentation before the goal text/date (just
	   source formatting, not meant to be visible) gets preserved as
	   literal leading spaces, pushing the text right instead of flush
	   against the icon. */
	white-space: normal;
}

/* "festgelegt am ..." / status-am-Datum line under a goal (polar-dashboard.php)
   - own line, light gray, so it reads as metadata rather than competing
   with the goal text itself for space/attention. */
/* "-> ca. 10 Minuten schneller (...)" line under a goal (polar-dashboard.php) -
   own line like .goal-date below it, but normal ink (not muted) since this
   is substantive content (the concrete meaning of the goal), not metadata. */
.goal-note {
	display: block;
}

.goal-date {
	display: block;
	color: var(--color-text-muted);
	font-size: 0.85em;
}

.goal-actions {
	flex: 0 0 auto;
	white-space: nowrap;
	font-size: 1.3em;
}

.goal-actions a {
	margin-left: 8px;
	text-decoration: none;
}

/* Weekly-evaluation history (polar-dashboard.php) - all entries share one
   scroll area instead of each .ai-result scrolling on its own, with a
   horizontal, clickable list of weeks pinned above it that jumps the
   matching entry into view. */
.week-history-nav {
	display: flex;
	gap: 6px;
	overflow-x: auto;
	padding-bottom: 8px;
	margin-bottom: 8px;
	border-bottom: 1px solid var(--color-border);
	white-space: nowrap;
}

.week-history-nav a {
	flex: 0 0 auto;
	padding: 4px 10px;
	border-radius: var(--radius);
	background: var(--color-surface);
	border: 1px solid var(--color-border);
	color: var(--color-text);
	font-size: 0.85em;
	text-decoration: none;
}

.week-history-nav a:hover, .week-history-nav a.active {
	border-color: var(--color-primary);
	color: var(--color-primary);
}

.week-history-scroll {
	max-height: 480px;
	overflow-y: auto;
}

.week-history-scroll .ai-result {
	max-height: none;
	overflow: visible;
}

/* Per-entry delete link in the weekly-evaluation history (polar-dashboard.php) */
.delete-week-evaluation {
	margin-left: 8px;
	font-size: 0.85em;
	color: var(--color-text-muted);
}

/* Per-row edit/delete links in the Gewicht & BMI table (polar-dashboard.php) */
.edit-weight-entry, .delete-weight-entry {
	font-size: 0.85em;
	color: var(--color-text-muted);
}

/* Nutrition-goal history table (polar-dashboard.php) - rows are
   sync-driven, read-only snapshots, except the fat/carb/protein inputs
   which the per-row pencil enables in place for a manual correction. */
.nutrition-goal-table input[type="number"] {
	width: 80px;
}

.nutrition-goal-table input[disabled] {
	color: var(--color-text);
	background: transparent;
	border-color: transparent;
}

/* Per-row links in the nutrition-goal history (polar-dashboard.php):
   "fddb sync", the edit pencil and the Speichern/Abbrechen pair. */
.sync-fddb-now,
.edit-nutrition-goal,
.nutrition-goal-edit-actions a {
	font-size: 0.85em;
	color: var(--color-text-muted);
}

.edit-nutrition-goal {
	margin-left: 6px;
	text-decoration: none;
}

.nutrition-goal-edit-actions a {
	margin-left: 6px;
}

.sync-fddb-now.syncing,
.save-nutrition-goal.saving {
	pointer-events: none;
	opacity: 0.6;
}

@media (max-width: 640px) {

	.ai-tab-columns {
		flex-direction: column;
		gap: 12px;
	}

	.status-quo-columns {
		flex-direction: column;
		gap: 0;
	}
}

/* Tables - scrollable as a whole rather than reflowing, so columns stay
   aligned on a phone-width viewport instead of wrapping into a jumble. */

table {
	display: block;
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
	border-collapse: collapse;
	width: 100%;
	margin-top: 12px;
	background: var(--color-surface);
	border-radius: var(--radius);
}

table, th, td {
	border: 1px solid var(--color-border);
	padding: 8px 12px;
}

th {
	background-color: var(--color-bg);
	text-align: left;
	white-space: nowrap;
}

canvas {
	max-width: 100%;
}

.activity-details-row > td {
	padding: 8px 12px;
	background: var(--color-bg);
}

.activity-details-row table {
	margin-top: 0;
}

.sport-cell .edit-sport,
.sport-cell .save-sport,
.sport-cell .cancel-sport {
	text-decoration: none;
	cursor: pointer;
}

/* Day-grouped activity list (polar-main.php) */

/* The generic `table{display:block}` rule sizes itself from visible
   content, which for this table would mean it renders narrow while every
   day is collapsed and suddenly jumps wide the moment one is expanded
   (the hidden nested table contributes nothing to that calculation until
   shown). Scroll via a wrapping div instead, and give the table itself a
   fixed column layout (a blank trailing column soaking up the remainder)
   so its width never depends on which day happens to be expanded. */
.table-scroll {
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
}

.day-table {
	display: table;
	table-layout: fixed;
	width: 100%;
	min-width: 790px;
}

/* "Alle Sportarten" table (polar-stats-year.php) - same expand/collapse
   shape (and the same width-jump concern) as .day-table above, just with
   sports instead of days as the clickable rows. */
.all-sports-table {
	display: table;
	table-layout: fixed;
	width: 100%;
	min-width: 560px;
}

/* Status-quo week summary table (polar-dashboard.php) - same expand/
   collapse shape as .day-table/.all-sports-table above, just narrower
   (one summary row, one clickable week instead of many days/sports). */
.week-summary-table {
	display: table;
	table-layout: fixed;
	width: 100%;
	min-width: 340px;
}

.day-row > td {
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.day-row {
	cursor: pointer;
}

.day-row:hover {
	background: var(--color-bg);
}

.day-toggle::before {
	content: "\25B8"; /* ▸ */
	display: inline-block;
	margin-right: 4px;
	color: var(--color-text-muted);
}

.day-row.expanded .day-toggle::before {
	content: "\25BE"; /* ▾ */
}

/* "Liste" view's day-separator rows - same shape as the clickable "cluster"
   day-row, but static: no toggle arrow, no hover affordance, and its
   activities (rendered via the shared render_day_activities()) are always
   visible rather than starting collapsed - see .day-detail-static below. */
.day-row-static {
	cursor: default;
}

.day-row-static:hover {
	background: none;
}

.day-row-static .day-toggle::before {
	content: "";
}

.day-detail-row > td {
	padding: 0;
	border-top: none;
}

.day-detail.day-detail-static {
	display: block;
}

.day-detail {
	display: none;
	padding: 8px 12px 16px;
	background: var(--color-bg);
}

.day-detail table {
	margin-top: 0;
	font-size: 0.85em;
}

/* "Gewicht & BMI" table (polar-dashboard.php) - same size as .day-detail
   table above, so it doesn't look oversized next to the day-by-day detail
   table it sits next to in the 3/5-2/5 status-quo layout. */
.weight-history-table {
	font-size: 0.85em;
}

.weight-history-table .weight-actions-header {
	font-size: 1.7em;
	vertical-align: middle;
}

.weight-history-table .edit-weight-entry,
.weight-history-table .delete-weight-entry {
	text-decoration: none;
}

.weight-history-table .delete-weight-entry {
	color: #c0362c;
}

.weight-history-table .edit-weight-entry + .delete-weight-entry {
	margin-left: 10px;
}

#footer {
	max-width: 1100px;
	margin: 32px auto 24px;
	padding: 0 var(--spacing);
	color: var(--color-text-muted);
	font-size: 0.9em;
}

#footer a {
	color: var(--color-text-muted);
}

@media (max-width: 640px) {

	.topnav-inner {
		padding: 8px 12px;
	}

	.topnav-brand {
		width: 100%;
	}

	#main-content, #main-form {
		padding: 12px;
	}

	h1 {
		font-size: 1.35em;
	}

	input[type='submit'] {
		width: 100%;
	}

	form input[type='text'],
	form input[type='email'],
	form input[type='password'],
	form select {
		max-width: none;
	}
}

/* Recipe-match info icon + click-to-open ingredient tooltip
   (polar-nutrition.php) - a native title="" tooltip isn't discoverable on
   touch devices and needs a hover, so this is a visible button instead,
   opened by click and positioned by JS (see functions.js) since the
   day-detail table sits inside an overflow-x:auto scroll container that
   would otherwise clip an absolutely-positioned popover. */
.recipe-info {
	display: inline-block;
	width: 16px;
	height: 16px;
	line-height: 15px;
	text-align: center;
	border-radius: 50%;
	border: 1px solid var(--color-border);
	background: var(--color-surface);
	color: var(--color-text-muted);
	font-size: 12px;
	cursor: pointer;
	padding: 0;
	margin-left: 4px;
	vertical-align: middle;
}

.recipe-info:hover {
	color: var(--color-primary);
	border-color: var(--color-primary);
}

.recipe-tooltip {
	position: fixed;
	z-index: 50;
	max-width: 320px;
	background: var(--color-text);
	color: var(--color-surface);
	font-size: 0.85em;
	line-height: 1.5;
	padding: 8px 12px;
	border-radius: var(--radius);
	box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25);
}

/* Cron-attempt diagnostic line (polar-nutrition.php) - same red as
   .ai-result-error, reused so "something failed" reads consistently
   across the app regardless of which feature it's about. */
.sync-error {
	color: #c0362c;
}
