/* TPF Theme - main stylesheet.
   Mobile first. Colors and font from the old TPF design.
   Old site used Bootstrap 3 + image sprites - here rebuilt with
   CSS variables, flexbox and clip-path (no framework). */

/* ---------- design tokens ---------- */

:root {
	/* colors from old style.css */
	--tpf-magenta: #902360;        /* main brand color (nav band, buttons) */
	--tpf-magenta-dark: #671945;   /* active/hover states */
	--tpf-magenta-mid: #802e5e;
	--tpf-pink: #c53387;           /* accents */
	--tpf-link: #b92d7b;           /* link color */
	--tpf-bg-pink-light: #faf0fa;  /* light pink backgrounds */
	--tpf-bg-gray: #f5f5f5;
	--tpf-text: #333;
	--tpf-text-light: #999;
	--tpf-white: #fff;

	--tpf-font: 'Dosis', Arial, Helvetica, sans-serif;
	--tpf-container: 1170px;
}

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

* {
	box-sizing: border-box;
}

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

a {
	color: var(--tpf-link);
	text-decoration: none;
}

a:hover,
a:focus {
	color: var(--tpf-magenta-dark);
	text-decoration: underline;
}

img {
	max-width: 100%;
	height: auto;
}

.container {
	width: 100%;
	max-width: var(--tpf-container);
	margin: 0 auto;
	padding: 0 15px;
}

.screen-reader-text {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip: rect(0 0 0 0);
	white-space: nowrap;
}

/* ---------- header: top area ---------- */

.site-header {
	position: relative;
}

/* angled corner graphics from the old design - sit left/right of the
   nav band and rise into the white header area (desktop only) */
.nav-wings {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	height: 238px;
	overflow: hidden;
	pointer-events: none;
	display: none;
}

.nav-wings .container {
	position: relative;
	height: 100%;
}

.nav-wings .inner-left,
.nav-wings .inner-right {
	position: absolute;
	bottom: 0;
	width: 346px;
	height: 238px;
}

.nav-wings .inner-left {
	left: -346px;
	background: url('../i/bkg/header-left.png') no-repeat right bottom;
}

.nav-wings .inner-right {
	right: -346px;
	background: url('../i/bkg/header-right.png') no-repeat left bottom;
}

.header-top {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-start;
	justify-content: space-between;
	gap: 10px;
	padding-top: 12px;
	padding-bottom: 12px;
}

.branding {
	display: flex;
	align-items: center;
	gap: 18px;
}

.site-logo img {
	width: 90px;
	display: block;
}

.slogan .site-title {
	margin: 0;
	font-size: 26px;
	font-weight: 600;
	color: #222;
}

.slogan .site-tagline {
	margin: 4px 0 0;
	font-size: 15px;
	color: var(--tpf-pink);
}

/* login button: dark angled box like the old design */
.btn-login {
	display: inline-block;
	padding: 8px 22px;
	background: #2b2b2b;
	color: var(--tpf-white);
	font-size: 14px;
	font-weight: 600;
	clip-path: polygon(6% 0, 100% 0, 94% 100%, 0 100%);
}

.btn-login:hover,
.btn-login:focus {
	background: var(--tpf-magenta);
	color: var(--tpf-white);
	text-decoration: none;
}

.member-name {
	display: inline-block;
	margin-right: 10px;
	font-weight: 600;
	color: var(--tpf-magenta);
}

/* plugin forms (login, register, reset, profile) + notices.
   Fields use the soft pink gradient from the front page registration box. */
.tpf-form input[type='text'],
.tpf-form input[type='email'],
.tpf-form input[type='password'],
.tpf-form input[type='number'],
.tpf-form input[type='date'],
.tpf-form select {
	width: 100%;
	max-width: 360px;
	padding: 8px 10px;
	border: 1px solid #d9b3d0;
	border-radius: 4px;
	background: linear-gradient(#f4e1f4, #fff);
	font-family: var(--tpf-font);
	font-size: 15px;
	color: var(--tpf-text);
}

.tpf-form select {
	width: auto;
	cursor: pointer;
}

.tpf-form input:focus,
.tpf-form select:focus {
	outline: 2px solid var(--tpf-pink);
	outline-offset: 0;
}

.tpf-submit {
	padding: 10px 24px;
	background: var(--tpf-magenta);
	color: var(--tpf-white);
	border: 0;
	border-radius: 4px;
	font-family: var(--tpf-font);
	font-size: 16px;
	font-weight: 600;
	cursor: pointer;
}

.tpf-submit:hover {
	background: var(--tpf-magenta-dark);
}

/* lets an <a> (not just a <button>) share .tpf-submit's look - e.g. the
   "Contact Support" link in Account settings (M9.5 fix round) */
.tpf-btn-link {
	display: inline-block;
	text-decoration: none;
}

.tpf-notice {
	padding: 10px 15px;
	border-radius: 4px;
	background: var(--tpf-bg-pink-light);
	border-left: 4px solid var(--tpf-magenta);
	margin: 15px 0;
}

.tpf-notice.tpf-error {
	background: #fdeaea;
	border-left-color: #c0392b;
}

.tpf-notice.tpf-success {
	background: #eaf7ea;
	border-left-color: #27ae60;
}

/* account settings: delete account (M3.5) - deliberately red, stands apart from
   the rest of the brand-magenta UI so it reads as a one-way, careful action */
.tpf-danger {
	color: #c0392b;
}

.tpf-delete-btn {
	padding: 10px 24px;
	background: #fff;
	color: #c0392b;
	border: 1px solid #c0392b;
	border-radius: 4px;
	font-family: var(--tpf-font);
	font-size: 16px;
	font-weight: 600;
	cursor: pointer;
}

.tpf-delete-btn:hover {
	background: #c0392b;
	color: var(--tpf-white);
}

/* location autocomplete (M4.1) - dropdown sits directly under the text field.
   .tpf-field is a <div>, not a <p>, on purpose: a <ul> inside an open <p>
   makes the browser implicitly close that <p> (and everything opened inside
   it - label, span, all of it), so the dropdown re-appears as a sibling of
   the <p> instead of a child of .tpf-location-picker, breaking the "position:
   absolute" containing block and making it jump to an unrelated place on the
   page. A <div> has no such restriction. Margin here matches the browser's
   default <p> spacing so this field lines up with the other <p>-based ones. */
.tpf-field {
	margin: 1em 0;
}

.tpf-location-picker {
	position: relative;
	display: inline-block;
	width: 100%;
	max-width: 360px;
}

.tpf-location-suggestions {
	position: absolute;
	z-index: 10;
	top: 100%;
	left: 0;
	right: 0;
	margin: 2px 0 0;
	padding: 4px 0;
	list-style: none;
	background: var(--tpf-white);
	border: 1px solid #d9b3d0;
	border-radius: 4px;
	box-shadow: 0 4px 10px rgba(0, 0, 0, 0.12);
	max-height: 220px;
	overflow-y: auto;
}

.tpf-location-suggestions li {
	padding: 6px 10px;
	cursor: pointer;
	font-size: 14px;
}

.tpf-location-suggestions li:hover,
.tpf-location-suggestions li.active {
	background: var(--tpf-bg-pink-light);
}

/* account area: menu like the old sidebar + styles table */
.tpf-account-menu ul {
	list-style: none;
	margin: 0 0 20px;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
}

.tpf-account-menu a {
	display: block;
	padding: 8px 14px;
	background: var(--tpf-bg-pink-light);
	border-radius: 4px;
	font-weight: 500;
}

.tpf-account-menu .active a {
	background: var(--tpf-magenta);
	color: var(--tpf-white);
}

/* inner tabs (fix round, Miron 15-07-2026: "Mein Profil und
   Kontoeinstellungen ist so lang. Könnten wir da Tabs machen?") - used
   inside "My profile" and "Account settings" to split each page's long
   section list into tabs. Same pill look as .tpf-account-menu above (own
   class rather than reusing it directly - this is a nested, smaller-scale
   nav one level down, not the top-level account sidebar). */
.tpf-tabs-nav {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	margin: 0 0 20px;
	border-bottom: 1px solid var(--tpf-bg-gray);
	padding-bottom: 12px;
}

.tpf-tab-btn {
	display: block;
	padding: 6px 12px;
	background: var(--tpf-bg-pink-light);
	border-radius: 4px;
	font-weight: 500;
	font-size: 0.95em;
}

.tpf-tab-btn.active {
	background: var(--tpf-magenta);
	color: var(--tpf-white);
}

.tpf-tab-panel {
	display: none;
}

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

/* generic visual separator INSIDE a tab panel, for two settings that share
   one form/save button but don't otherwise belong together (fix round,
   Miron 15-07-2026: "zwischen Mitgliedsnummer und 'Nur gasttänzer' brauche
   ich optisch eine Trennung, sonst ist das verwirrend, weil es ja nicht
   zusammen gehört") */
.tpf-section-divider {
	border: none;
	border-top: 1px solid var(--tpf-bg-gray);
	margin: 20px 0;
}

.tpf-styles {
	border-collapse: collapse;
	width: 100%;
	max-width: 700px;
}

/* partner search (M4.2) - filter form + result cards.
   Went through 3 rounds on 08-07-2026 before settling here (see TP_Ads
   class docblock / TP_Search::shortcode_search() for the full history) -
   back to its ORIGINAL flex-wrap row (fits as many fields as the
   available width allows), since the 2-column grid tried in between was
   itself reverted once Miron clarified he wanted the ad slot in its own
   column next to the options, not the individual fields rearranged. */
/* M13.3: course list filter form (Tanzstil/Wochentag/Standort/Kurs-Gruppe)
   reuses this exact same inline-row layout - see
   TP_Courses::render_filter_form(). */
.tpf-search-form,
.tpf-course-filter-form {
	display: flex;
	flex-wrap: wrap;
	gap: 15px;
	align-items: flex-end;
	margin-bottom: 20px;
}

.tpf-search-form .tpf-field,
.tpf-course-filter-form .tpf-field {
	margin: 0;
}

/* M9.3: options + ad slot side by side (only rendered when an ad actually
   configured - see shortcode_search()), reusing the same generic 2-column
   grid the course/event detail pages already use. Narrower max-width than
   .tpf-detail-columns' other uses since the options form itself doesn't
   need much horizontal room - keeps the ad from being stretched too wide
   either. */
.tpf-search-options-row {
	max-width: 900px;
}

.tpf-search-count {
	font-weight: 600;
	color: var(--tpf-magenta-dark);
}

.tpf-search-empty {
	padding: 20px;
	background: var(--tpf-bg-pink-light);
	border-radius: 4px;
}

.tpf-profile-cards {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
	gap: 18px;
}

.tpf-profile-card {
	position: relative;
	border: 1px solid #d9b3d0;
	border-radius: 6px;
	overflow: hidden;
	background: var(--tpf-white);
	transition: box-shadow 0.15s;
}

.tpf-profile-card:hover {
	box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
}

.tpf-profile-card-link {
	display: block;
	color: var(--tpf-text);
	text-decoration: none;
}

.tpf-profile-card-photo {
	display: block;
	width: 100%;
	aspect-ratio: 1 / 1;
	object-fit: cover;
	background: var(--tpf-bg-pink-light);
}

.tpf-profile-card-noimg {
	display: flex;
	align-items: center;
	justify-content: center;
}

.tpf-profile-card-body {
	padding: 10px 12px;
}

.tpf-profile-card-body strong {
	display: block;
	font-size: 15px;
}

.tpf-profile-card-meta {
	display: block;
	font-size: 13px;
	color: #7a5a72;
}

/* [tpf_new_members] footer/widget shortcode (fix, Miron 14-07-2026, after a
   staging screenshot: "Die Felder sind zu groß. vielleicht 1/2 Größe und 2
   nebeneinander?") - the shared .tpf-profile-cards grid above defaults to
   minmax(180px, 1fr), which in a typical narrow sidebar/footer column
   collapses to a single very large card per row. Scoped to this widget's
   own wrapper class (.tpf-new-members-widget, set by
   TP_Search::shortcode_new_members()) rather than changing the shared
   default - the full search results grid on the search page still needs
   its own wider auto-fill behavior, unaffected by this. Always exactly 2
   columns regardless of container width, as asked ("2 nebeneinander"),
   plus a smaller gap/name size to match the smaller card. */
.tpf-new-members-widget .tpf-profile-cards {
	grid-template-columns: repeat(2, 1fr);
	gap: 10px;
}

.tpf-new-members-widget .tpf-profile-card-body {
	padding: 6px 8px;
}

.tpf-new-members-widget .tpf-profile-card-body strong {
	font-size: 13px;
}

.tpf-pagination {
	display: flex;
	gap: 8px;
	margin-top: 20px;
}

/* M8.2: teacher cards - reusable piece embedded later into course pages
   (M8.5); [tpf_teachers_test] is a temporary QA-only preview, see
   class-tp-teachers.php */
.tpf-teacher-cards {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
	gap: 18px;
}

.tpf-teacher-card {
	border: 1px solid #d9b3d0;
	border-radius: 6px;
	overflow: hidden;
	background: var(--tpf-white);
	/* fix (Miron 07-07-2026, course detail page): render_card() is a
	   compact card everywhere - in the [tpf_teachers_test] grid (M8.2)
	   each cell already constrains its width (minmax(180px, 1fr)), but
	   embedded directly into a page's normal content flow (M8.5a course
	   detail) there is no such constraint, so "width: 100%" on the photo
	   below stretched to the full content column and (with aspect-ratio
	   1/1) turned into a huge square. Capping the card itself keeps it
	   card-sized in ANY context, not just inside the test grid. */
	max-width: 240px;
}

.tpf-teacher-card-photo {
	display: block;
	width: 100%;
	/* fix (Miron 07-07-2026, live TT-DB staging test: "Tanzlehrer
	   abgeschnitten"): real TT-DB photos (tt3tanzlehrer.bild) are portrait
	   (~2:3), not square - the old forced "aspect-ratio: 1/1; object-fit:
	   cover" cropped them. Card width stays capped (.tpf-teacher-card
	   max-width above), but the image itself now keeps its own natural
	   ratio ("height: auto") instead of being forced/cropped to a square -
	   Miron: "wir müssen hier die Breite von uns nehmen, aber das Format
	   von TTDB für das Bild". The placeholder box (no photo set) has no
	   natural ratio of its own, so it keeps a fixed 1/1 square below. */
	height: auto;
	background: var(--tpf-bg-pink-light);
}

.tpf-teacher-card-noimg {
	display: flex;
	align-items: center;
	justify-content: center;
	aspect-ratio: 1 / 1;
}

.tpf-teacher-card-body {
	padding: 10px 12px;
}

.tpf-teacher-card-name {
	display: block;
	font-size: 15px;
	margin-bottom: 4px;
}

.tpf-teacher-card-bio {
	font-size: 13px;
	color: #7a5a72;
	margin: 0;
}

/* M8.3: venue cards - reusable piece embedded later into course/event pages
   (M8.4/8.5); [tpf_venues_test] is a temporary QA-only preview, see
   class-tp-venues.php */
.tpf-venue-cards {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
	gap: 18px;
}

.tpf-venue-card {
	border: 1px solid #d9b3d0;
	border-radius: 6px;
	padding: 10px 12px;
	background: var(--tpf-white);
	/* fix (Miron 07-07-2026, course detail page: "Standort ist viel breiter
	   als Tanzlehrer") - same reasoning/cap as .tpf-teacher-card above: this
	   card has no photo to stretch, but embedded directly in a page's normal
	   content flow it still has no width constraint of its own and ends up
	   spanning the full content column next to the much narrower teacher
	   card. Same max-width keeps both cards visually consistent. */
	max-width: 240px;
}

.tpf-venue-card-name {
	display: block;
	font-size: 15px;
	margin-bottom: 4px;
}

.tpf-venue-card-address {
	font-size: 13px;
	color: #7a5a72;
	margin: 0;
}

/* M8.4a: public events list + detail page (display only - follow/partner
   search/iCal come as separate later steps, see class-tp-events.php) */
.tpf-event-list {
	display: flex;
	flex-direction: column;
	gap: 2px;
}

.tpf-event-list-item {
	display: flex;
	gap: 16px;
	padding: 12px 0;
	border-bottom: 1px solid #eadbe6;
}

/* event photo (M8.4b add-on, decision Miron 06-07-2026: "bitte immer
   Veranstaltungsbild 1:1 mitdenken... notfalls da auch dieses rosa Feld,
   wenn es keins gibt" - same placeholder box in the list AND on the detail
   page, "damit die Seiten und Listen gleich sind") - always square,
   same aspect-ratio approach as the teacher/venue card photos */
.tpf-event-list-photo {
	flex: 0 0 auto;
	width: 60px;
	height: 60px;
	aspect-ratio: 1 / 1;
	object-fit: cover;
	border-radius: 4px;
	background: var(--tpf-bg-pink-light);
}

.tpf-event-list-photo-noimg {
	background: var(--tpf-bg-pink-light);
}

/* Shrunk from max-width 360px to the same 60px tile size as
   .tpf-event-list-photo above (Miron 16-07-2026, right after the full-height
   2-column redesign: "Das Bild kann auch auf die Größe von den normalen
   Kacheln [reduziert werden]") - now sits inside the half-width
   .tpf-detail-col-main alongside the title, not spanning the whole page
   above everything. */
.tpf-event-page-photo {
	display: block;
	width: 60px;
	aspect-ratio: 1 / 1;
	object-fit: cover;
	border-radius: 4px;
	background: var(--tpf-bg-pink-light);
	margin-bottom: 10px;
}

.tpf-event-page-photo-noimg {
	background: var(--tpf-bg-pink-light);
}

.tpf-event-list-date {
	flex: 0 0 auto;
	min-width: 160px;
	color: #7a5a72;
	font-size: 14px;
}

.tpf-event-list-title {
	font-size: 16px;
	font-weight: 600;
	color: var(--tpf-text);
	text-decoration: none;
}

a.tpf-event-list-title:hover {
	text-decoration: underline;
}

.tpf-event-list-venue {
	font-size: 13px;
	color: #7a5a72;
}

.tpf-event-badge {
	display: inline-block;
	padding: 2px 8px;
	border-radius: 4px;
	font-size: 12px;
	font-weight: 600;
}

.tpf-event-badge-cancelled {
	background: #f8d7da;
	color: #842029;
}

.tpf-event-badge-soldout {
	background: #fff3cd;
	color: #664d03;
}

.tpf-event-page-title {
	margin-bottom: 6px;
}

.tpf-event-page-datetime {
	color: #7a5a72;
	font-size: 15px;
}

.tpf-event-page-venue {
	font-size: 14px;
}

.tpf-event-page-ical {
	margin: 4px 0 16px;
}

.tpf-event-page-ical a {
	font-size: 14px;
	text-decoration: none;
	border: 1px solid #d8b8cf;
	border-radius: 4px;
	padding: 5px 12px;
	display: inline-block;
}

.tpf-event-page-ical a:hover {
	background: #f7ecf4;
}

.tpf-event-page-description {
	margin-top: 16px;
}

.tpf-pagination a,
.tpf-page-current {
	padding: 6px 12px;
	border-radius: 4px;
	background: var(--tpf-bg-pink-light);
	text-decoration: none;
	color: var(--tpf-text);
}

.tpf-page-current {
	background: var(--tpf-magenta);
	color: var(--tpf-white);
	font-weight: 600;
}

/* public profile page (M4.3) - photo column + info column, old portal layout */
.tpf-profile-page {
	display: flex;
	flex-wrap: wrap;
	gap: 30px;
	align-items: flex-start;
}

.tpf-profile-page-photos {
	flex: 0 0 260px;
	max-width: 100%;
}

.tpf-profile-page-mainphoto {
	display: block;
	width: 100%;
	max-width: 260px;
	aspect-ratio: 1 / 1;
	object-fit: cover;
	border-radius: 6px;
	background: var(--tpf-bg-pink-light);
}

.tpf-profile-page-nophoto {
	max-width: 260px;
}

.tpf-profile-page-thumbs {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin-top: 10px;
}

.tpf-profile-page-thumb {
	width: 60px;
	height: 60px;
	object-fit: cover;
	border-radius: 4px;
	cursor: pointer;
}

.tpf-profile-page-thumb:hover,
.tpf-profile-page-thumb:focus {
	outline: 2px solid var(--tpf-magenta);
}

.tpf-profile-page-info {
	flex: 1 1 320px;
	min-width: 260px;
}

.tpf-profile-page-info h1 {
	margin-top: 0;
}

.tpf-profile-page-styles {
	margin: 0 0 15px;
	padding-left: 20px;
}

.tpf-profile-page-lastseen {
	color: #7a5a72;
	font-size: 14px;
}

.tpf-profile-page-nearby {
	flex-basis: 100%;
	margin-top: 10px;
}

/* messaging button shown but disabled until M6 exists (decision Miron 05-07-2026) */
.tpf-btn-disabled {
	opacity: 0.5;
	cursor: not-allowed;
}

.tpf-btn-disabled:hover {
	background: var(--tpf-magenta);
}

.tpf-styles th,
.tpf-styles td {
	padding: 6px 10px;
	border-bottom: 1px dotted #ccc;
	text-align: left;
}

/* saved searches (M4.4) - "save this search" button on the search page +
   the list in the account area */
.tpf-save-search-form {
	margin: 15px 0;
}

.tpf-saved-searches {
	border-collapse: collapse;
	width: 100%;
	max-width: 700px;
}

.tpf-saved-searches th,
.tpf-saved-searches td {
	padding: 8px 10px;
	border-bottom: 1px dotted #ccc;
	text-align: left;
	vertical-align: middle;
}

.tpf-inline-form {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	margin: 0;
}

/* favorites (M5.1) - star button on search cards + profile page, and the
   "my favorites" list in the account area */
.tpf-favorite-star {
	appearance: none;
	border: none;
	background: rgba(255, 255, 255, 0.85);
	color: #b8a0b3;
	font-size: 18px;
	line-height: 1;
	width: 32px;
	height: 32px;
	border-radius: 50%;
	cursor: pointer;
	display: flex;
	align-items: center;
	justify-content: center;
	transition: color 0.15s, transform 0.1s;
}

.tpf-favorite-star:hover {
	color: var(--tpf-magenta);
	transform: scale(1.08);
}

.tpf-favorite-star.is-favorite {
	color: var(--tpf-magenta);
}

.tpf-favorite-star:disabled {
	cursor: wait;
	opacity: 0.6;
}

/* on a search result card: floating top-right over the photo */
.tpf-profile-card > .tpf-favorite-star {
	position: absolute;
	top: 8px;
	right: 8px;
	z-index: 2;
}

/* on the profile page: floating top-right over the main photo (fix, Miron
   09-07-2026: "der Stern kann auch überall wie bei der Profilsuche im
   Bild sein" - moved off the name heading to match the search-card
   placement). .tpf-profile-page-info h1 keeps its flex/gap layout for the
   block icon + report button that still live there.

   Follow-up bugfix (Miron 09-07-2026): "wenn auf der Profilseite keine
   Foto drauf ist, dann ist der Stern verloren... ich glaube wir brauchen
   auch rosa Feld als Platzhalter" - display:inline-block here had no
   width to size itself by, so its child's `width: 100%` had nothing to
   resolve against and collapsed to 0x0 (a real photo's intrinsic size
   papered over this, the "no photo" placeholder <div> has no intrinsic
   size at all, so it vanished completely - only the absolutely-positioned
   star, which doesn't contribute to its 0x0 parent's layout size, was
   still visible, floating with nothing around it). block + width:100% (of
   the existing 260px-wide .tpf-profile-page-photos column) fixes both the
   sizing AND brings back the pink placeholder background, which was
   already defined on .tpf-profile-page-mainphoto/-nophoto all along. */
.tpf-profile-page-mainphoto-wrap {
	position: relative;
	display: block;
	width: 100%;
}

.tpf-profile-page-mainphoto-wrap > .tpf-favorite-star {
	position: absolute;
	top: 8px;
	right: 8px;
	z-index: 2;
}

.tpf-profile-page-info h1 {
	display: flex;
	align-items: center;
	gap: 10px;
}

/* small-thumbnail star overlay (fix, Miron 09-07-2026: star added to
   several list views with much smaller photos than the search cards -
   inbox, chat header, Pinnwand/course-event ad lists, course/event
   partner-searcher lists) - shrunk-down variant of the same star, floating
   over the corner of whatever thumbnail it wraps. One shared wrapper class
   used by all of them instead of a bespoke rule per view. */
.tpf-star-photo-wrap {
	position: relative;
	display: inline-flex;
	flex-shrink: 0;
}

.tpf-star-photo-wrap > .tpf-favorite-star {
	position: absolute;
	top: -6px;
	right: -6px;
	width: 20px;
	height: 20px;
	font-size: 11px;
	background: var(--tpf-white);
	box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
	z-index: 2;
}

/* inbox list: the star isn't inside a wrapper span (the photo stays
   inside its row-wide <a> so clicking it still opens the conversation) -
   positioned relative to the row itself instead, over the fixed-size
   44px photo's top-left corner */
.tpf-conversation-item > .tpf-favorite-star {
	position: absolute;
	top: 6px;
	left: 32px;
	width: 20px;
	height: 20px;
	font-size: 11px;
	background: var(--tpf-white);
	box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
	z-index: 2;
}

.tpf-favorites-list {
	border-collapse: collapse;
	width: 100%;
	max-width: 700px;
}

.tpf-favorites-list td {
	padding: 8px 10px;
	border-bottom: 1px dotted #ccc;
	vertical-align: middle;
}

.tpf-favorites-thumb {
	display: block;
	width: 48px;
	height: 48px;
	object-fit: cover;
	border-radius: 4px;
	background: var(--tpf-bg-pink-light);
}

.tpf-favorites-noimg {
	background: var(--tpf-bg-pink-light);
}

/* friends (M5.2) - button widget on the profile page + sections on the
   combined "Friends & favorites" account page */
.tpf-friend-action {
	margin: 10px 0 15px;
}

.tpf-friend-action.is-loading {
	opacity: 0.6;
	pointer-events: none;
}

.tpf-friend-status {
	color: #7a5a72;
	font-size: 14px;
}

.tpf-friend-btn {
	padding: 8px 18px;
	background: var(--tpf-magenta);
	color: var(--tpf-white);
	border: 0;
	border-radius: 4px;
	font-family: var(--tpf-font);
	font-size: 14px;
	font-weight: 600;
	cursor: pointer;
}

.tpf-friend-btn:hover {
	background: var(--tpf-magenta-dark);
}

.tpf-friend-btn-secondary {
	background: transparent;
	color: var(--tpf-magenta);
	border: 1px solid var(--tpf-magenta);
}

.tpf-friend-btn-secondary:hover {
	background: var(--tpf-bg-pink-light);
}

.tpf-mutual-friends {
	color: #7a5a72;
	font-size: 14px;
	margin-top: -6px;
}

.tpf-account-content h3 {
	margin-top: 25px;
	border-bottom: 1px solid #eadce8;
	padding-bottom: 4px;
}

.tpf-account-content h3:first-child {
	margin-top: 0;
}

/* M8.4b: "Friends & favorites" account page as a grid - single column by
   default (mobile), 2 columns on desktop (decision Miron 06-07-2026, when
   asked where the new "Followed events" section should live). All spacing
   between sections comes from the grid `gap` below - each section's own
   heading always sits at margin-top:0 (fix: an earlier ":first-child"
   version of this rule matched EVERY section's heading anyway, since each
   is the first child of its own wrapper div, which accidentally killed the
   25px gap the old single-column layout had between headings; using `gap`
   for that spacing instead is the correct fix, not a workaround). */
.tpf-account-grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: 25px;
}

/* M8.5/8.4-Fix: course/event detail page as a 2-column grid on desktop
   (decision Miron 07-07-2026: "könnten auf dem Desktop ruhig wieder in die
   2. Spalte" - referencing this exact .tpf-account-grid pattern above, so
   deliberately the same single-column-mobile/2-column-desktop shape and
   gaps rather than a new one-off layout).

   Courses - column 1 (.tpf-detail-col-main): schedule/style/teacher+venue
   cards/description. Column 2 (.tpf-detail-col-side): partner-searchers
   list + the classified-ads-for-this list
   (TP_Classifieds::render_ads_for_link()). The title, follow star,
   partner-search toggle and "Create ad for this" button stay OUTSIDE this
   grid, above it, unchanged since 07-07-2026.

   Events - extended twice on 16-07-2026, both times same day: first "die
   ganze Seite ... 2-spaltig ... dass Pinnwand und Chat immer in der
   rechten Spalte sind" moved the "More information" link and the group
   chat INTO the grid (link into column 1 after venue/description, chat as
   column 2's last item, after partner-searchers/Pinnwand/ad slot) instead
   of both rendering full-width below it. Then, same day, after seeing that
   on staging: "Bitte die 2. Spalte oben am Bild schon anfangen. Im Moment
   beginnt die Spalte erst unten." - photo, title, follow star,
   partner-search toggle, "Create ad" button, cancelled/sold-out badge,
   datetime and the iCal link ALL moved into column 1 too, at its very top,
   so nothing renders above the grid any more and column 2 starts level
   with the photo. Courses have no chat and keep their original,
   smaller column 1 - unaffected by either event-only change. */
.tpf-detail-columns {
	display: grid;
	grid-template-columns: 1fr;
	gap: 25px;
}

.tpf-detail-col-side h3:first-child {
	margin-top: 0;
}

.tpf-account-section h3 {
	margin-top: 0;
}

/* event follow star (M8.4b) - same shape as .tpf-favorite-star (decision
   Miron 06-07-2026, after seeing the original plain grey button on
   staging: "Können wir da auch einen Stern nutzen wie Favoriten?"). Sized
   like the profile-page star (standalone next to the event title, not
   floating over a photo), not the smaller card-corner variant. */
.tpf-event-follow-star {
	appearance: none;
	border: none;
	background: transparent;
	color: #b8a0b3;
	font-size: 22px;
	line-height: 1;
	width: 36px;
	height: 36px;
	border-radius: 50%;
	cursor: pointer;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	transition: color 0.15s, transform 0.1s;
}

.tpf-event-follow-star:hover {
	color: var(--tpf-magenta);
	transform: scale(1.08);
}

.tpf-event-follow-star.is-following {
	color: var(--tpf-magenta);
}

.tpf-event-follow-star:disabled {
	cursor: wait;
	opacity: 0.6;
}

/* star sits right after the title (decision Miron 06-07-2026: "den Stern
   hinter den Titel machen"), same placement as the favorite star next to
   the profile name */
.tpf-event-page-title .tpf-event-follow-star {
	font-size: 20px;
	width: 32px;
	height: 32px;
	vertical-align: middle;
}

/* partner-search toggle switch (M8.4c, fix 07-07-2026 - was a second star,
   Miron: "wer soll denn verstehen, was 1 Stern und 2 Sterne bedeuten?").
   Standard accessible switch pattern (role="switch" + aria-checked, set in
   PHP/JS) - the track/thumb pair communicates state visually, the label
   text stays constant ("Tanzpartner*in gesucht"), own row below the title
   rather than squeezed into the heading next to the follow star. */
.tpf-event-partner-toggle {
	appearance: none;
	border: none;
	background: transparent;
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 8px 0;
	cursor: pointer;
	font-family: inherit;
	font-size: 15px;
	color: var(--tpf-text, #333);
}

.tpf-event-partner-toggle .tpf-toggle-track {
	position: relative;
	width: 42px;
	height: 24px;
	border-radius: 12px;
	background: #ddd0da;
	transition: background 0.15s;
	flex-shrink: 0;
}

.tpf-event-partner-toggle .tpf-toggle-thumb {
	position: absolute;
	top: 2px;
	left: 2px;
	width: 20px;
	height: 20px;
	border-radius: 50%;
	background: #fff;
	box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
	transition: transform 0.15s;
}

.tpf-event-partner-toggle[aria-checked="true"] .tpf-toggle-track {
	background: var(--tpf-magenta);
}

.tpf-event-partner-toggle[aria-checked="true"] .tpf-toggle-thumb {
	transform: translateX(18px);
}

.tpf-event-partner-toggle:hover .tpf-toggle-track {
	filter: brightness(0.95);
}

.tpf-event-partner-toggle:disabled {
	cursor: wait;
	opacity: 0.6;
}

/* generic hidden utility (M8.4c) - originally used to hide the
   partner-search toggle/"Create ad" button until following; both are always
   visible now (fix, Miron 07-07-2026, round 4 - see
   class-tp-interaction.php's ajax_toggle_event_search_partner()), so nothing
   currently applies this class to them, but the utility itself stays for
   any future hide/reveal need. */
.tpf-hidden {
	display: none;
}

.tpf-request-teaser {
	margin-top: 15px;
}

.tpf-message-teaser {
	margin-top: 15px;
}

/* messages (M6.1) - conversation list + chat thread on the account page */
.tpf-conversation-list {
	list-style: none;
	margin: 0;
	padding: 0;
	max-width: 700px;
}

.tpf-conversation-item {
	position: relative;
	border-bottom: 1px dotted #ccc;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 10px;
}

/* unread highlight (fix, Miron 09-07-2026: "das hätte ich gerne... die
   ganze Zeile rosa unterlegen" - the bold name alone wasn't eye-catching
   enough). Same light-pink token already used for the chat bubble
   background/own-message tint, so this reads as "part of the same design
   language" rather than a one-off color. */
.tpf-conversation-item.tpf-conversation-unread {
	background: var(--tpf-bg-pink-light);
	border-radius: 6px;
}

.tpf-conversation-item a {
	display: flex;
	flex: 1;
	flex-direction: row;
	align-items: center;
	gap: 10px;
	padding: 10px 4px;
	color: var(--tpf-text);
	text-decoration: none;
	min-width: 0;
}

/* "Ausblenden"/"Einblenden" action (M6.1.1 conversation-hide extension) -
   sits at the row's far right, .tpf-inline-form already covers its layout */
.tpf-conversation-item .tpf-inline-form .tpf-delete-btn {
	padding: 4px 12px;
	font-size: 13px;
	white-space: nowrap;
}

/* photo + name/date, extension round - photo left, text stacked to its right.
   Square (1:1), same crop/border-radius convention as every other member
   photo (.tpf-profile-page-mainphoto, .tpf-photo img) - bugfix Miron
   05-07-2026, this was accidentally rounded to a circle at first */
.tpf-conversation-photo {
	width: 44px;
	height: 44px;
	aspect-ratio: 1 / 1;
	object-fit: cover;
	border-radius: 6px;
	flex-shrink: 0;
	background: var(--tpf-bg-pink-light);
}

/* pink placeholder tile when a member has no uploaded photo (fix, Miron
   09-07-2026: "auch im Nachrichteneingang sollte rosa Kachel sein") - a
   plain <div> sharing .tpf-conversation-photo's size/background instead of
   an <img>, same "never just blank" convention as .tpf-profile-card-noimg
   and .tpf-profile-page-nophoto */
.tpf-conversation-noimg {
	display: block;
}

.tpf-conversation-info {
	display: flex;
	flex-direction: column;
	gap: 2px;
}

.tpf-conversation-item.tpf-conversation-unread strong {
	color: var(--tpf-magenta);
}

.tpf-conversation-preview {
	font-size: 14px;
	color: #7a5a72;
}

/* thread header: other member's photo + name, links to their profile
   (extension round) */
.tpf-thread-header {
	display: flex;
	align-items: center;
	gap: 10px;
	margin-bottom: 10px;
}

/* square (1:1), same convention as every other member photo - bugfix Miron
   05-07-2026, this was accidentally rounded to a circle at first */
.tpf-thread-photo {
	width: 56px;
	height: 56px;
	aspect-ratio: 1 / 1;
	object-fit: cover;
	border-radius: 6px;
}

.tpf-thread-header h3 {
	margin: 0;
}

.tpf-message-thread {
	max-height: 480px;
	overflow-y: auto;
	display: flex;
	flex-direction: column;
	gap: 10px;
	padding: 15px;
	margin: 15px 0;
	background: var(--tpf-bg-pink-light);
	border-radius: 6px;
}

.tpf-message-bubble {
	max-width: 75%;
	padding: 8px 12px;
	border-radius: 10px;
	background: var(--tpf-white);
	border: 1px solid #eadce8;
}

.tpf-message-bubble.is-loading {
	opacity: 0.5;
}

.tpf-message-own {
	align-self: flex-end;
	background: #f6e3f0;
	border-color: var(--tpf-magenta);
}

.tpf-message-other {
	align-self: flex-start;
}

/* still within the "visually new" window (extension round, decision Miron
   05-07-2026: at least 10s, or until the viewer replies) - removed by
   messages.js, not by a server re-render, once markRead() fires */
.tpf-message-bubble.tpf-message-unread {
	border-color: var(--tpf-magenta);
	box-shadow: 0 0 0 1px var(--tpf-magenta);
}

.tpf-message-bubble.tpf-message-unread .tpf-message-text {
	font-weight: 600;
}

/* profile-page embed: a bit shorter than the full account-page thread */
.tpf-profile-embed-thread {
	max-height: 320px;
}

.tpf-message-meta {
	font-size: 12px;
	color: #7a5a72;
	margin-bottom: 3px;
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 8px;
}

.tpf-message-meta-text {
	flex: 1;
	min-width: 0;
}

/* icon redesign (Miron 08-07-2026: "Die Symbole neben das Datum/Uhrzeit") -
   retract/hide/report now sit at the end of the meta line instead of a
   separate row under the message text */
.tpf-message-icons {
	flex: none;
	white-space: nowrap;
}

.tpf-message-icon-btn {
	appearance: none;
	background: none;
	border: none;
	color: #a37b98;
	font-size: 15px;
	line-height: 1;
	cursor: pointer;
	padding: 0;
}

.tpf-message-icon-btn:hover {
	color: var(--tpf-magenta);
}

.tpf-message-icons .tpf-report-btn {
	margin-left: 6px;
}

/* classified-ad reference (schema v17, fix Miron 07-07-2026) - sits inline
   in the same meta line as name/timestamp ("neben Name und Uhrzeit") */
.tpf-message-meta a {
	color: var(--tpf-magenta);
}

/* heads-up notice above the compose box when replying via a classified
   ad's "Send message" button - same subdued look as .tpf-field-hint, own
   class in case this needs to diverge later */
.tpf-message-ref-notice {
	font-size: 13px;
	color: #7a5a72;
	margin: 0 0 6px;
}

.tpf-message-text {
	font-size: 15px;
	white-space: pre-wrap;
	word-break: break-word;
}

.tpf-message-deleted {
	font-style: italic;
	color: #999;
}

/* .tpf-message-action-btn: retract/hide are now icon buttons living in
   .tpf-message-icons (see .tpf-message-icon-btn above) - the class itself
   stays on the <button> markup unchanged (messages.js click handler keys
   off it), this rule now only supplies the base reset, sizing/color comes
   from .tpf-message-icon-btn */
.tpf-message-action-btn {
	appearance: none;
	background: none;
	border: none;
	cursor: pointer;
	padding: 0;
}

/* one-time explanation of the 3 message icons, shown once below the
   thread (Miron 08-07-2026: "Alle 3 Symbole unter dem Chatfenster einmal
   erklären.") - render_message_icon_legend() in class-tp-messages.php */
.tpf-message-icon-legend {
	display: flex;
	flex-wrap: wrap;
	gap: 4px 16px;
	font-size: 12px;
	color: #7a5a72;
	margin: 6px 0 14px;
}

.tpf-message-form {
	max-width: 700px;
}

/* textfield + send button row (fix, Miron 07-07-2026, round 4: the
   .tpf-message-ref-notice used to be a flex sibling of the textarea/button
   inside .tpf-message-form, which was itself the flex row - so the notice
   rode along beside the textfield instead of sitting above it. The flex
   row now lives on this wrapper only, .tpf-message-form is a plain block
   so the notice (a direct child, rendered before this row) always stacks
   above it. */
.tpf-message-compose-row {
	display: flex;
	gap: 10px;
	align-items: flex-end;
}

.tpf-message-input {
	flex: 1;
	min-height: 60px;
	padding: 8px 10px;
	border: 1px solid #ccc;
	border-radius: 4px;
	font-family: var(--tpf-font);
	font-size: 15px;
	resize: vertical;
}

/* Support chat FAQ deflection (M9.5, decision Miron 09-07-2026) - static
   box above the compose form (render_support_faq_box()) and the
   send-time interstitial (messages.js's showFaqInterstitial()), only ever
   present on the Support thread (data-support-thread="1"). */
.tpf-support-faq {
	max-width: 700px;
	margin: 10px 0;
	padding: 8px 12px;
	background: var(--tpf-bg-pink-light);
	border-radius: 6px;
	font-size: 14px;
}

.tpf-support-faq summary {
	cursor: pointer;
	font-weight: 600;
	color: var(--tpf-pink);
}

.tpf-support-faq dl {
	margin: 8px 0 0;
}

.tpf-support-faq dt {
	font-weight: 600;
	margin-top: 8px;
}

.tpf-support-faq dd {
	margin: 2px 0 0;
	color: #555;
}

.tpf-support-faq-interstitial {
	max-width: 700px;
	margin: 0 0 10px;
	padding: 10px 14px;
	background: var(--tpf-bg-pink-light);
	border: 1px solid var(--tpf-pink);
	border-radius: 6px;
	font-size: 14px;
}

/* keyword chips (fix round, Miron 09-07-2026: "erst als Schlagwörter
   aufmachen. Es könnte auch mehrere passende FAQs geben") - one chip per
   matching FAQ entry, click expands its answer inline below the chip. */
.tpf-support-faq-chip-row {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin-bottom: 10px;
}

.tpf-support-faq-chip-wrap {
	flex: 1 1 auto;
}

.tpf-support-faq-chip {
	background: var(--tpf-white);
	border: 1px solid var(--tpf-pink);
	color: var(--tpf-pink);
	border-radius: 999px;
	padding: 6px 14px;
	font-size: 13px;
	cursor: pointer;
}

.tpf-support-faq-chip.is-expanded {
	background: var(--tpf-pink);
	color: var(--tpf-white);
}

.tpf-support-faq-chip-answer {
	margin: 6px 0 0;
	padding: 8px 10px;
	background: var(--tpf-white);
	border-radius: 4px;
	color: #555;
}

.tpf-support-faq-actions button {
	margin-right: 8px;
}

.tpf-support-faq-edit-btn {
	background: none;
	border: 1px solid #ccc;
	border-radius: 4px;
	padding: 6px 12px;
	cursor: pointer;
}

/* "---- Neue Anfrage vom ... ----" divider (fix round, Miron 09-07-2026:
   "damit wir im Support schneller sehen, wo es neu anfängt") - purely a
   rendering artifact (TP_Messages::render_support_divider()), no separate
   message row in the database. */
.tpf-support-divider {
	max-width: 700px;
	margin: 14px 0;
	text-align: center;
	font-size: 12px;
	color: #999;
	letter-spacing: 0.5px;
}

/* shown instead of the compose form once staff marks a Support thread
   done (fix round, Miron 09-07-2026) - render_thread()'s $support_resolved
   branch. */
.tpf-support-resolved-notice {
	max-width: 700px;
	padding: 10px 14px;
	background: var(--tpf-bg-pink-light);
	border-radius: 6px;
	color: #555;
}

.tpf-profile textarea {
	width: 100%;
	max-width: 500px;
	padding: 8px 10px;
	border: 1px solid #ccc;
	border-radius: 4px;
	font-family: var(--tpf-font);
	font-size: 15px;
}

/* file inputs: style the native "Durchsuchen" button like our submit buttons */
.tpf-form input[type='file'] {
	font-family: var(--tpf-font);
	font-size: 15px;
}

/* exactly the same metrics as .tpf-submit so both buttons look identical */
.tpf-form input[type='file']::file-selector-button {
	padding: 10px 24px;
	margin-right: 12px;
	background: var(--tpf-magenta);
	color: var(--tpf-white);
	border: 0;
	border-radius: 4px;
	font-family: var(--tpf-font);
	font-size: 16px;
	font-weight: 600;
	line-height: 1.5;
	cursor: pointer;
}

.tpf-form input[type='file']::file-selector-button:hover {
	background: var(--tpf-magenta-dark);
}

/* protected member photos: block casual save/drag (screenshots stay possible) */
img.tpf-protected {
	user-select: none;
	-webkit-user-select: none;
	-webkit-touch-callout: none;
	pointer-events: auto;
}

/* photo gallery in the account */
.tpf-photo-grid {
	display: flex;
	flex-wrap: wrap;
	gap: 15px;
	margin-top: 20px;
}

.tpf-photo {
	position: relative;
	width: 160px;
}

.tpf-photo img {
	width: 160px;
	height: 160px;
	object-fit: cover;
	border-radius: 6px;
	display: block;
}

.tpf-photo.is-main img {
	outline: 3px solid var(--tpf-magenta);
}

.tpf-photo-badge {
	position: absolute;
	top: 6px;
	left: 6px;
	background: var(--tpf-magenta);
	color: var(--tpf-white);
	font-size: 12px;
	padding: 2px 8px;
	border-radius: 3px;
}

.tpf-photo-actions {
	margin-top: 6px;
	display: flex;
	gap: 6px;
	flex-wrap: wrap;
}

.tpf-photo-btn {
	padding: 4px 10px;
	font-size: 13px;
	font-family: var(--tpf-font);
	background: var(--tpf-bg-pink-light);
	border: 1px solid #d9b3d0;
	border-radius: 3px;
	cursor: pointer;
}

.tpf-photo-btn:hover {
	background: var(--tpf-magenta);
	color: var(--tpf-white);
}

/* photo crop modal (M3.4 step 2) - main photo only */
.tpf-crop-modal {
	position: fixed;
	inset: 0;
	background: rgba(0, 0, 0, 0.6);
	display: flex;
	align-items: center;
	justify-content: center;
	z-index: 100;
	padding: 20px;
}

.tpf-crop-modal[hidden] {
	display: none;
}

.tpf-crop-dialog {
	background: var(--tpf-white);
	border-radius: 6px;
	padding: 20px;
	max-width: 480px;
	width: 100%;
}

.tpf-crop-dialog h3 {
	margin-top: 0;
}

/* width/height are set in JS to exactly match the photo's aspect ratio (no
   letterboxing) - crop math depends on the stage being the same shape as the
   photo, otherwise fractions would not map back to the right pixels on save */
.tpf-crop-stage {
	position: relative;
	max-width: 100%;
	margin: 0 auto 15px;
	background: var(--tpf-bg-gray);
	overflow: hidden;
	touch-action: none;
}

.tpf-crop-image {
	position: absolute;
	inset: 0;
	/* !important: something on the live site (likely a WordPress/plugin default
	   image rule such as "img { max-width:100%; height:auto }") was overriding our
	   width/height:100% and stopping the photo from filling the crop stage (found
	   by Miron on staging, 05-07-2026: image stuck at natural size in the top-left
	   corner, crop box then extended past it). The crop math itself was correct -
	   the box just no longer matched what the photo visually showed. !important
	   guarantees this specific, narrow rule wins regardless of the exact source */
	width: 100% !important;
	height: 100% !important;
	max-width: none !important;
	display: block;
	pointer-events: none;
	user-select: none;
}

.tpf-crop-box {
	position: absolute;
	border: 2px solid var(--tpf-magenta);
	box-shadow: 0 0 0 2000px rgba(0, 0, 0, 0.45);
	cursor: move;
	touch-action: none;
}

.tpf-crop-handle {
	position: absolute;
	right: -8px;
	bottom: -8px;
	width: 18px;
	height: 18px;
	border-radius: 50%;
	background: var(--tpf-magenta);
	border: 2px solid var(--tpf-white);
	cursor: nwse-resize;
	touch-action: none;
}

.tpf-crop-form {
	display: flex;
	gap: 10px;
	align-items: center;
	flex-wrap: wrap;
}

/* ---------- header: nav band ---------- */

.nav-band {
	background: var(--tpf-magenta);
	position: relative;
}

.nav-row {
	display: flex;
	flex-direction: column;
	gap: 8px;
	padding-top: 8px;
	padding-bottom: 8px;
}

/* burger button - visible on small screens only */
.nav-toggle {
	display: inline-flex;
	flex-direction: column;
	gap: 4px;
	padding: 10px;
	background: var(--tpf-magenta-dark);
	border: 0;
	border-radius: 4px;
	cursor: pointer;
}

.nav-toggle .icon-bar {
	width: 22px;
	height: 2px;
	background: var(--tpf-white);
}

.nav-menu {
	display: none;
}

.nav-menu.is-open {
	display: block;
}

/* covers both wp_nav_menu (ul.menu) and the wp_page_menu fallback (div.menu > ul) */
.nav-menu ul {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
}

.nav-menu .menu a {
	display: block;
	padding: 10px 14px;
	color: var(--tpf-white);
	font-size: 15px;
	font-weight: 500;
}

.nav-menu .menu a:hover,
.nav-menu .menu a:focus,
.nav-menu .menu .current-menu-item > a,
.nav-menu .menu .current_page_item > a {
	background: var(--tpf-magenta-dark);
	border-radius: 4px;
	text-decoration: none;
}

/* quick search in the nav band - only rendered when radius search is on
   (M4.1 setting), see header.php */
.header-search {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
}

.header-search input {
	padding: 7px 10px;
	border: 0;
	border-radius: 3px;
	font-family: var(--tpf-font);
	font-size: 14px;
	min-width: 0;
	flex: 1 1 80px;
	width: 90px;
}

.btn-search {
	padding: 7px 18px;
	background: var(--tpf-magenta-dark);
	color: var(--tpf-white);
	border: 0;
	border-radius: 3px;
	font-family: var(--tpf-font);
	font-size: 14px;
	font-weight: 600;
	cursor: pointer;
}

.btn-search:hover,
.btn-search:focus {
	background: var(--tpf-pink);
}

/* ---------- front page: hero (teaser) ---------- */

/* dark hero with dancing couple - image and boxes from the old design */
.home-teaser {
	background: #000 url('../i/teaser.jpg') no-repeat top center;
	padding: 20px 0 30px;
}

.teaser-inner {
	display: flex;
	flex-direction: column;
	gap: 25px;
}

.why-register {
	padding-top: 100px; /* let the couple image show on small screens */
}

.why-register h2 {
	color: var(--tpf-white);
	font-size: 22px;
	font-weight: 500;
	margin: 0 0 4px;
	padding: 8px 10px;
	background: url('../i/why-register-header.png') repeat 0 0;
	text-shadow: 0 1px 1px #000;
}

.why-register ul {
	list-style: none;
	margin: 0;
	padding: 0;
}

.why-register li {
	color: var(--tpf-white);
	margin-bottom: 4px;
	min-height: 50px;
	display: flex;
	align-items: center;
	padding: 8px 10px 8px 25px;
	background: url('../i/why-register-li.png') repeat 0 0;
	position: relative;
	text-shadow: 0 1px 1px #000;
}

.why-register li::before {
	content: '';
	display: block;
	width: 25px;
	height: 50px;
	background: url('../i/why-register-bullet.png') no-repeat center center;
	position: absolute;
	left: 0;
	top: 50%;
	transform: translateY(-50%);
}

.registration-box h2 {
	text-align: center;
	color: var(--tpf-white);
	font-weight: 400;
	font-size: 23px;
	height: 55px;
	line-height: 55px;
	margin: 0;
	background: url('../i/reg-form-header.png') no-repeat top center;
}

.registration-box form {
	background: transparent url('../i/reg-background.png') repeat 0 0;
	padding: 30px 20px 0;
	border-radius: 8px;
}

.registration-box .form-group {
	border: 1px solid var(--tpf-white);
	border-radius: 4px;
	background: linear-gradient(#e8c3e8, #fff);
	box-shadow: 0 5px 5px rgba(0, 0, 0, 0.6);
	position: relative;
	height: 44px;
	margin-bottom: 15px;
}

.registration-box .form-group input {
	width: 100%;
	height: 42px;
	padding: 0 30px 0 10px;
	background: none;
	border: 0;
	outline: 0;
	font-family: var(--tpf-font);
	font-size: 15px;
}

/* small input icons from the original sprite */
.registration-box .icon {
	position: absolute;
	top: 15px;
	right: 10px;
	background: url('../i/sprite.png') no-repeat;
}

.registration-box .icon-input-user {
	width: 10px;
	height: 13px;
	background-position: -135px -88px;
}

.registration-box .icon-input-email {
	width: 15px;
	height: 15px;
	background-position: -135px -32px;
}

.registration-box .submit {
	display: block;
	width: calc(100% + 40px);
	margin: 0 -20px;
	height: 60px;
	padding: 0;
	font-family: var(--tpf-font);
	font-size: 20px;
	font-weight: 300;
	color: var(--tpf-white);
	background: linear-gradient(#aa3177, #690c3c);
	border: 0;
	border-radius: 8px;
	cursor: pointer;
}

.registration-box .submit:hover {
	background: linear-gradient(#771448, #aa3177);
}

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

.site-content {
	min-height: 50vh;
	padding: 20px 0;
	background: url('../i/bkg/content.png') repeat-x 0 0;
}

/* ---------- content elements (breadcrumbs, articles, post list) ---------- */

.breadcrumbs {
	min-height: 50px;
	line-height: 50px;
	font-size: 15px;
	font-weight: 300;
	background: url('../i/bkg/breadcrumbs.png') no-repeat 0 0;
	padding-left: 37px;
	margin-left: -37px;
	clear: both;
}

.breadcrumbs .divider {
	color: var(--tpf-text-light);
	padding: 0 4px;
}

.entry-title {
	margin: 25px 0 10px;
	font-weight: 600;
}

.entry-date {
	display: block;
	margin-bottom: 15px;
	color: var(--tpf-text-light);
	font-size: 14px;
}

.entry-content img {
	height: auto;
}

/* post list (news) - dotted separators like the old design */
.post-list-item {
	padding: 20px 0;
	border-bottom: 1px dotted #ccc;
}

.post-list-title {
	margin: 0 0 5px;
	font-size: 22px;
	font-weight: 600;
}

.post-list-excerpt p {
	margin: 5px 0 10px;
}

.btn-more {
	display: inline-block;
	padding: 6px 16px;
	background: var(--tpf-magenta);
	color: var(--tpf-white);
	border-radius: 3px;
	font-size: 14px;
	font-weight: 600;
}

.btn-more:hover,
.btn-more:focus {
	background: var(--tpf-magenta-dark);
	color: var(--tpf-white);
	text-decoration: none;
}

/* pagination - magenta numbers like the old portal */
.pagination {
	margin: 25px 0;
	text-align: center;
}

.pagination .page-numbers {
	display: inline-block;
	min-width: 34px;
	padding: 5px 8px;
	margin: 0 2px;
	border: 1px solid #ddd;
	border-radius: 3px;
	color: var(--tpf-link);
}

.pagination .page-numbers.current {
	background: var(--tpf-magenta);
	border-color: var(--tpf-magenta);
	color: var(--tpf-white);
}

.pagination a.page-numbers:hover {
	background: var(--tpf-bg-pink-light);
	text-decoration: none;
}

/* 404 */
.error-404 {
	padding: 20px 0 40px;
}

/* ---------- footer ---------- */

.site-footer {
	margin-top: 40px;
	background: var(--tpf-bg-gray) url('../i/bkg/footer.png') repeat-x 0 0;
	padding: 30px 0 20px;
	font-size: 14px;
}

.footer-columns {
	display: grid;
	grid-template-columns: 1fr;
	gap: 25px;
	padding-bottom: 25px;
}

.footer-column .widget-title {
	margin: 0 0 4px;
	font-size: 17px;
	font-weight: 600;
	color: #222;
}

/* thin line under column titles (old design "shadow") */
.footer-column .shadow {
	height: 2px;
	background: linear-gradient(to right, var(--tpf-magenta) 0 60px, #ddd 60px);
	margin-bottom: 12px;
}

.footer-column ul {
	list-style: none;
	margin: 0;
	padding: 0;
}

.footer-column li {
	padding: 4px 0;
	border-bottom: 1px dotted #ccc;
}

.footer-bottom {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	align-items: center;
	gap: 10px;
	border-top: 1px solid #ddd;
	padding-top: 15px;
}

/* covers both wp_nav_menu (ul.menu) and the wp_page_menu fallback (div.menu > ul) */
.footer-nav ul {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
}

.footer-nav li:not(:last-child)::after {
	content: '|';
	color: var(--tpf-text-light);
	margin: 0 8px;
}

.copyright p {
	margin: 0;
	color: #555;
}

.social-links {
	display: flex;
	align-items: center;
	justify-content: flex-end;
	gap: 10px;
	margin-top: 15px;
}

.social-links span {
	font-weight: 600;
}

/* 24x24 sprite from the old design (facebook/twitter, hover row below) */
.social {
	width: 24px;
	height: 24px;
	background: url('../i/social.png') no-repeat;
	display: inline-block;
}

.social.facebook {
	background-position: 0 0;
}

.social.facebook:hover {
	background-position: 0 -24px;
}

/* Instagram (Fix-ToDo 18-07-2026): own 24x48 sprite drawn to match the old
   social.png style (grey tile, white glyph, black on hover) - the old sprite
   only ever contained facebook/twitter/google+ */
.social.instagram {
	background-image: url('../i/social-instagram.png');
	background-position: 0 0;
}

.social.instagram:hover {
	background-position: 0 -24px;
}

/* Latest blog posts (M13.6b): [tpf_latest_posts] on the dashboard and in
   widget areas - simple stacked cards in the TPF look */
.tpf-latest-posts h2 {
	margin-bottom: 10px;
}

.tpf-latest-posts .tpf-post-card {
	background: #fff;
	border: 1px solid var(--border, #e5dbe2);
	border-radius: 6px;
	padding: 12px 15px;
	margin-bottom: 10px;
	/* fix round 18-07-2026: featured image as the shared 60px tile
	   (.tpf-event-list-photo) on the left, "wie bei Kursen" */
	display: flex;
	align-items: flex-start;
	gap: 12px;
}

.tpf-latest-posts .tpf-post-card-body {
	min-width: 0;
}

.tpf-latest-posts .tpf-post-card a.tpf-post-title {
	font-weight: 600;
	text-decoration: none;
}

.tpf-latest-posts .tpf-post-date {
	color: #8c7a87;
	font-size: 0.85em;
	margin: 2px 0 6px;
}

.tpf-latest-posts .tpf-post-excerpt {
	margin: 0;
}

/* Profile visitors (M13.6b): dashboard section reuses the shared
   .tpf-profile-cards row; only the "when" line under the name is new */
.tpf-visitors .tpf-visit-time {
	display: block;
	color: #8c7a87;
	font-size: 0.8em;
	font-weight: 400;
}

/* Dashboard 2-column layout (fix round, Miron 18-07-2026: "Neue Mitglieder
   viel zu groß. Vielleicht auch hier auf dem Desktop 2 Spalten und die
   neuen User in die 2. Spalte.") - mobile: stacked, desktop (same 768px
   breakpoint as .tpf-detail-columns): main content 2/3, side column 1/3.
   The members widget's own fixed 2-column card rule then yields nicely
   small cards in that narrow side column, footer-widget look. Visitor
   cards in the wide main column get their own small-tile rule instead. */
.tpf-dashboard-columns {
	display: grid;
	grid-template-columns: 1fr;
	gap: 25px;
}

.tpf-visitors .tpf-profile-cards {
	grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
	gap: 10px;
}

.tpf-visitors .tpf-profile-card-body {
	padding: 6px 8px;
}

@media (min-width: 768px) {
	.tpf-dashboard-columns {
		grid-template-columns: 2fr 1fr;
		gap: 25px 40px;
	}

	.tpf-dashboard-col-main > h2:first-child {
		margin-top: 0;
	}
}

/* Venue photo (M13.6c: "Foto-Upload für Tanzlehrer und Standorte ... damit
   diese aussehen, wie alles was aus TTDB kommt") - same natural-ratio rule
   as .tpf-teacher-card-photo above */
.tpf-venue-card-photo {
	display: block;
	width: 100%;
	height: auto;
	border-radius: 6px 6px 0 0;
	margin-bottom: 8px;
}

/* blocking (M6.1.1) - icon button next to the star/friend button on the
   profile page, and the collapsible "Blocked members" list at the bottom of
   the "Friends & favorites" account page */
.tpf-block-icon {
	appearance: none;
	border: none;
	background: transparent;
	color: #b8a0b3;
	font-size: 22px;
	line-height: 1;
	width: 36px;
	height: 36px;
	border-radius: 50%;
	cursor: pointer;
	display: flex;
	align-items: center;
	justify-content: center;
	transition: color 0.15s, transform 0.1s;
}

.tpf-block-icon:hover {
	color: #c0392b;
	transform: scale(1.08);
}

.tpf-block-icon.is-blocked {
	color: #c0392b;
}

.tpf-block-icon:disabled {
	cursor: wait;
	opacity: 0.6;
}

/* collapsible sections - "Blocked members" (M6.1.1) and "hidden
   conversations" (general inbox declutter, same round) share this look */
.tpf-blocked-section,
.tpf-hidden-conversations {
	margin-top: 20px;
	border-top: 1px dotted #ccc;
	padding-top: 12px;
}

.tpf-blocked-section summary,
.tpf-hidden-conversations summary {
	cursor: pointer;
	font-weight: 600;
	color: #7a5a72;
}

.tpf-blocked-section ul,
.tpf-hidden-conversations ul {
	margin-top: 10px;
}

/* ---------- desktop (min-width 768px) ---------- */

@media (min-width: 768px) {
	.nav-wings {
		display: block;
	}

	/* M8.4b: 2-column "Friends & favorites" account page on desktop.
	   Bugfix (Miron staging test 06-07-2026, "nicht zweispaltig, Abstände
	   stimmen nicht"): row-gap was accidentally set to 0 here, which -
	   combined with the h3 margin bug fixed above - made every section
	   crowd together instead of forming a real 2-column grid. */
	.tpf-account-grid {
		grid-template-columns: 1fr 1fr;
		gap: 25px 40px;
	}

	/* M8.5/8.4-Fix: course/event detail page 2-column grid, see mobile rule
	   above for the full reasoning */
	.tpf-detail-columns {
		grid-template-columns: 1fr 1fr;
		gap: 25px 40px;
	}

	/* front page hero: boxes side by side like the old design */
	.home-teaser {
		padding: 0;
	}

	.teaser-inner {
		position: relative;
		height: 488px;
		flex-direction: row;
	}

	.why-register {
		position: absolute;
		left: 15px;
		bottom: 17px;
		width: 410px;
		padding-top: 0;
	}

	.registration-box {
		position: absolute;
		right: 15px;
		top: 15px;
		width: 280px;
	}

	.registration-box .submit {
		height: 80px;
		font-size: 22px;
	}

	.site-logo img {
		width: 110px;
	}

	.slogan .site-title {
		font-size: 30px;
	}

	.nav-toggle {
		display: none;
	}

	.nav-row {
		flex-direction: row;
		align-items: center;
		justify-content: space-between;
	}

	.nav-menu {
		display: block;
	}

	.nav-menu .menu {
		flex-direction: row;
	}

	.footer-columns {
		grid-template-columns: repeat(4, 1fr);
	}
}

/* newsletter signup (M7.1) - footer form, account settings section, and the
   dashboard opt-in banner all reuse these same classes */
.tpf-newsletter-signup .tpf-form,
.tpf-newsletter-banner .tpf-form {
	max-width: none;
}

.tpf-newsletter-signup input[type='email'] {
	max-width: none;
	width: 100%;
}

.tpf-newsletter-choice {
	margin: 6px 0 !important;
}

.tpf-newsletter-choice label {
	display: flex;
	align-items: flex-start;
	gap: 6px;
	font-weight: 400;
	cursor: pointer;
}

.tpf-newsletter-choice input[type='checkbox'] {
	margin-top: 3px;
	width: auto;
}

.tpf-newsletter-pending {
	color: var(--tpf-text-light);
	font-size: 12px;
	font-style: italic;
}

.tpf-newsletter-result {
	margin-top: 8px;
	font-size: 14px;
}

.tpf-newsletter-result.tpf-success {
	color: #27ae60;
}

.tpf-newsletter-result.tpf-error {
	color: #c0392b;
}

.tpf-newsletter-banner {
	max-width: 480px;
}

/* plain text-styled button - used for the dashboard banner's "Later"
   dismiss action, sitting next to the primary .tpf-submit button */
.tpf-link-button {
	background: none;
	border: 0;
	padding: 0;
	color: var(--tpf-link);
	font-family: var(--tpf-font);
	font-size: 15px;
	text-decoration: underline;
	cursor: pointer;
}

.tpf-link-button:hover {
	color: var(--tpf-magenta-dark);
}

/* M8.5a: courses/groups list + detail page (display only, same pattern as
   .tpf-event-list above) - no photo field yet, unlike events, see
   class-tp-courses.php */
.tpf-course-list {
	display: flex;
	flex-direction: column;
	gap: 2px;
}

.tpf-course-list-item {
	padding: 12px 0;
	border-bottom: 1px solid #eadbe6;
}

.tpf-course-list-title {
	font-size: 16px;
	font-weight: 600;
	color: var(--tpf-text);
	text-decoration: none;
}

a.tpf-course-list-title:hover {
	text-decoration: underline;
}

.tpf-course-list-schedule {
	font-size: 13px;
	color: #7a5a72;
}

/* start/end date (fix, Miron 08-07-2026) - same muted style as schedule/venue */
.tpf-course-list-dates {
	font-size: 13px;
	color: #7a5a72;
}

.tpf-course-list-venue {
	font-size: 13px;
	color: #7a5a72;
}

.tpf-course-badge {
	display: inline-block;
	padding: 2px 8px;
	border-radius: 4px;
	font-size: 12px;
	font-weight: 600;
}

.tpf-course-badge-group {
	background: #e6f0fa;
	color: #1a4f80;
}

/* Fix-ToDo (Miron 15-07-2026): 3 separate small badges for courses/groups
   that have an open Einzelplatz, an active classified ad, and/or an active
   partner search - each its own distinct color, same base pattern as
   .tpf-course-badge-group above. */
.tpf-course-badge-einzelplatz {
	background: #fdecea;
	color: #96281b;
}

.tpf-course-badge-ad {
	background: #fff4e0;
	color: #8a5a00;
}

.tpf-course-badge-search {
	background: #e8f6ec;
	color: #1e6b3a;
}

.tpf-course-page-title {
	margin-bottom: 6px;
}

/* course follow star (M8.5b) - same shape as .tpf-event-follow-star, own
   class (not shared) so course-specific changes never touch the already-
   tested event styling, same reasoning as the duplicated JS file. */
.tpf-course-follow-star {
	appearance: none;
	border: none;
	background: transparent;
	color: #b8a0b3;
	font-size: 22px;
	line-height: 1;
	width: 36px;
	height: 36px;
	border-radius: 50%;
	cursor: pointer;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	transition: color 0.15s, transform 0.1s;
}

.tpf-course-follow-star:hover {
	color: var(--tpf-magenta);
	transform: scale(1.08);
}

.tpf-course-follow-star.is-following {
	color: var(--tpf-magenta);
}

.tpf-course-follow-star:disabled {
	cursor: wait;
	opacity: 0.6;
}

.tpf-course-page-title .tpf-course-follow-star {
	font-size: 20px;
	width: 32px;
	height: 32px;
	vertical-align: middle;
}

/* partner-search toggle switch for courses (M8.5c) - exact copy of
   .tpf-event-partner-toggle's rules under its own class, so future
   course-specific styling never touches the event toggle (same
   one-class-per-feature convention as the follow star above). Built as a
   toggle from the start here (mirrors 8.4c's end state after its fix, see
   docs/modules/interaction.md). */
.tpf-course-partner-toggle {
	appearance: none;
	border: none;
	background: transparent;
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 8px 0;
	cursor: pointer;
	font-family: inherit;
	font-size: 15px;
	color: var(--tpf-text, #333);
}

.tpf-course-partner-toggle .tpf-toggle-track {
	position: relative;
	width: 42px;
	height: 24px;
	border-radius: 12px;
	background: #ddd0da;
	transition: background 0.15s;
	flex-shrink: 0;
}

.tpf-course-partner-toggle .tpf-toggle-thumb {
	position: absolute;
	top: 2px;
	left: 2px;
	width: 20px;
	height: 20px;
	border-radius: 50%;
	background: #fff;
	box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
	transition: transform 0.15s;
}

.tpf-course-partner-toggle[aria-checked="true"] .tpf-toggle-track {
	background: var(--tpf-magenta);
}

.tpf-course-partner-toggle[aria-checked="true"] .tpf-toggle-thumb {
	transform: translateX(18px);
}

.tpf-course-partner-toggle:hover .tpf-toggle-track {
	filter: brightness(0.95);
}

.tpf-course-partner-toggle:disabled {
	cursor: wait;
	opacity: 0.6;
}

.tpf-course-page-schedule {
	color: #7a5a72;
	font-size: 15px;
}

/* start/end date (fix, Miron 08-07-2026) - same muted tone as the schedule
   line right above it, they belong together visually */
.tpf-course-page-dates {
	color: #7a5a72;
	font-size: 15px;
	margin-top: -8px;
}

/* registration link (fix, Miron 08-07-2026) - same button-link look as the
   event page's "Add to calendar" link (.tpf-event-page-ical) */
.tpf-course-page-register {
	margin: 4px 0 16px;
}

.tpf-course-page-register a {
	font-size: 14px;
	text-decoration: none;
	border: 1px solid #d8b8cf;
	border-radius: 4px;
	padding: 6px 12px;
	display: inline-block;
	color: #851159;
}

.tpf-course-page-register a:hover {
	background: #f7ecf4;
}

.tpf-course-page-styles {
	font-size: 14px;
}

.tpf-course-page-teacher,
.tpf-course-page-venue {
	font-size: 14px;
}

.tpf-course-page-description {
	margin-top: 16px;
}

/* classified ads (M8.6) - account-embedded list + create/edit form */
.tpf-classifieds-list {
	border-collapse: collapse;
	width: 100%;
	max-width: 800px;
}

.tpf-classifieds-list th,
.tpf-classifieds-list td {
	padding: 8px 10px;
	border-bottom: 1px dotted #ccc;
	text-align: left;
	vertical-align: middle;
}

/* an expired ad stays visible/manageable in the account (only the future
   public list in M8.7 will hide it) - dimmed row + small badge make that
   status obvious here without removing it from the list */
.tpf-classifieds-list tr.tpf-expired {
	opacity: 0.6;
}

.tpf-badge-expired {
	display: inline-block;
	padding: 1px 8px;
	border-radius: 10px;
	background: #fdeaea;
	color: #c0392b;
	font-size: 12px;
	font-weight: 600;
}

/* M9.1 fix round: admin-hidden classified ad, shown to its owner on their
   own management list (class-tp-classifieds.php render_list()) and next to
   the inline preview on the admin Meldungen page - same pill shape as
   .tpf-badge-expired, neutral grey rather than red (not an error state, an
   admin decision) */
.tpf-badge-hidden {
	display: inline-block;
	padding: 1px 8px;
	border-radius: 10px;
	background: #ece6ea;
	color: #6a4f64;
	font-size: 12px;
	font-weight: 600;
}

.tpf-classified-form textarea {
	width: 100%;
	max-width: 500px;
	padding: 10px 12px;
	border: 1px solid #ddd;
	border-radius: 4px;
	font-family: var(--tpf-font);
	font-size: 15px;
	box-sizing: border-box;
}

.tpf-classified-form textarea:focus {
	outline: none;
	border-color: var(--tpf-magenta);
}

.tpf-classified-form select {
	max-width: 500px;
}

.tpf-field-hint {
	display: inline-block;
	margin-top: 4px;
	color: #7a5a72;
	font-size: 13px;
}

/* "Create ad" button (M8.6 redesign) - course/event detail page, always
   visible (fix, Miron 07-07-2026, round 4 - saving a linked ad auto-follows
   instead of requiring following first, see TP_Classifieds::handle_save()) */
.tpf-ad-button {
	display: inline-block;
	margin-top: 8px;
	padding: 8px 18px;
	border: 1px solid var(--tpf-magenta);
	border-radius: 4px;
	color: var(--tpf-magenta);
	text-decoration: none;
	font-weight: 600;
	font-size: 14px;
}

.tpf-ad-button:hover {
	background: var(--tpf-magenta);
	color: var(--tpf-white);
}

/* read-only link display in the classified-ad account form (M8.6 redesign) -
   no dropdown here anymore, just the current link + a "remove" checkbox */
.tpf-classified-link-display {
	padding: 8px 12px;
	background: var(--tpf-bg-pink-light);
	border-radius: 4px;
}

/* guest-facing count-only teasers on the course/event detail page (decision
   Miron 07-07-2026: "4 Mitglieder suchen hier..." / "es gibt 3 Anzeigen
   dafür", never shown when the count is 0 - callers already return '' in
   that case) - same subdued look as .tpf-field-hint, own class per section
   in case Miron later wants them to diverge */
.tpf-partner-search-teaser,
.tpf-classifieds-teaser {
	color: #7a5a72;
	font-size: 14px;
}

/* classified ads linked to this course/event (TP_Classifieds::
   render_ads_for_link(), M8.5/8.4-Fix 2-column redesign) - member-only
   list, same photo-thumbnail idea as .tpf-favorites-list but a card layout
   rather than a table since each entry also carries a title/text/button */
.tpf-classified-ad-list {
	display: flex;
	flex-direction: column;
	gap: 16px;
	/* fix (Miron 07-07-2026, 2-column detail page: "Bild von Profil, das
	   sucht, und aus der Anzeige sind nicht untereinander"): the
	   partner-searchers list above this one is a <table> whose first <td>
	   (.tpf-favorites-list td { padding: 8px 10px; }) insets its photo 10px
	   from the column's left edge. This list is a flex column with no such
	   inset, so its photos sat flush at 0px - 10px out of line with the
	   list above it. Matching left padding here lines both lists' photos up
	   on the same vertical edge. */
	padding-left: 10px;
}

.tpf-classified-ad-item {
	display: flex;
	gap: 12px;
}

.tpf-classified-ad-photo {
	flex: 0 0 auto;
}

.tpf-classified-ad-body h4 {
	margin: 2px 0 4px;
}

.tpf-classified-ad-author {
	font-size: 13px;
	color: #7a5a72;
	margin: 0;
}

.tpf-classified-ad-own {
	font-size: 13px;
	color: #7a5a72;
	font-style: italic;
}

/* M8.7 "Pinnwand" (public sitewide list) - "Linked to: <course/event>" line
   per ad (render_board_list()) - only needed sitewide, since on the
   course's/event's own page (render_ads_for_link()) the link is already
   implied by where the page lives */
.tpf-classified-ad-link {
	font-size: 13px;
	color: #7a5a72;
	margin: 4px 0;
}

/* 0.89 "Einzelplätze in Kursen" (Miron 15-07-2026) - rebuilds the public
   page/shortcode already live on traumtaenzer.de. Two-column card per
   entry (main info left, location/partner-needed/age-height/register link
   right) - same visual role as the old page's inline <table>, built as
   flex here instead. */
.tpf-einzelplatz-section {
	margin-bottom: 32px;
}

.tpf-einzelplatz-empty {
	color: #7a5a72;
	font-style: italic;
}

.tpf-einzelplatz-entry {
	display: flex;
	gap: 16px;
	padding: 14px 0;
	border-bottom: 1px solid #e5d9e2;
}

.tpf-einzelplatz-entry:last-child {
	border-bottom: none;
}

.tpf-einzelplatz-entry-main {
	flex: 1 1 auto;
}

.tpf-einzelplatz-entry-main h4 {
	margin: 2px 0 4px;
}

.tpf-einzelplatz-entry-sessions {
	font-size: 13px;
	color: #7a5a72;
	margin: 6px 0 0;
}

.tpf-einzelplatz-entry-side {
	flex: 0 0 220px;
	text-align: center;
}

/* fix (Miron 15-07-2026): full Einzelplatz info card on the course's own
   detail page (TP_Einzelplatz::render_course_badge()) - same "Kleinanzeige"
   card look as .tpf-classified-ad-item, since Miron explicitly asked for
   the same detail level as a classified ad rather than a plain link. */
.tpf-einzelplatz-course-badge {
	margin-bottom: 16px;
	padding: 12px;
	background: var(--tpf-bg-pink-light);
	border-radius: 6px;
}

.tpf-einzelplatz-course-badge h3 {
	margin: 0 0 8px;
	font-size: 15px;
}

.tpf-einzelplatz-course-badge-entry {
	padding: 8px 0;
	border-top: 1px solid #e5d9e2;
	font-size: 13px;
}

.tpf-einzelplatz-course-badge-entry:first-of-type {
	border-top: none;
}

/* M8.7 "Pinnwand" - guest teaser's deduplicated list of linked courses/
   events (decision Miron 07-07-2026: "Anzahl + Liste der verlinkten Kurse/
   Events", render_board_guest_teaser()) */
.tpf-classifieds-teaser-links {
	margin: 4px 0 0;
	padding-left: 20px;
}

/* M8.7 masonry/list view toggle (fix, Miron 07-07-2026: "sieht langweilig
   aus... alles untereinander" - see render_board_view_toggle()). Masonry
   is the CSS default (.tpf-board-masonry, added server-side); JS only ever
   REMOVES it (switching to list) or re-adds it, so a visitor without JS
   still gets the masonry look rather than a broken hybrid. */
.tpf-board-view-toggle {
	display: flex;
	justify-content: flex-end;
	gap: 6px;
	margin-bottom: 12px;
}

.tpf-view-toggle-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	padding: 0;
	border: 1px solid #ddd;
	border-radius: 6px;
	background: var(--tpf-white);
	cursor: pointer;
}

.tpf-view-toggle-btn[aria-pressed="true"] {
	background: var(--tpf-magenta);
	border-color: var(--tpf-magenta);
}

/* icons are plain CSS shapes (bars / 2x2 grid), not an icon font or SVG -
   same "no extra dependency" convention as render_star()'s &#9733; entity */
.tpf-icon-list,
.tpf-icon-masonry {
	display: grid;
	width: 16px;
	height: 16px;
}

.tpf-icon-list {
	gap: 3px;
	align-content: center;
}

.tpf-icon-list i {
	display: block;
	height: 2px;
	background: var(--tpf-text);
	border-radius: 1px;
}

.tpf-view-toggle-btn[aria-pressed="true"] .tpf-icon-list i {
	background: var(--tpf-white);
}

.tpf-icon-masonry {
	grid-template-columns: repeat(2, 1fr);
	grid-template-rows: repeat(2, 1fr);
	gap: 3px;
}

.tpf-icon-masonry i {
	display: block;
	background: var(--tpf-text);
	border-radius: 1px;
}

.tpf-view-toggle-btn[aria-pressed="true"] .tpf-icon-masonry i {
	background: var(--tpf-white);
}

/* tile layout for the sitewide board's member list (default view), 1/2/3
   columns by breakpoint. Originally built as plain CSS multi-column
   ("poor man's masonry", decision Miron 07-07-2026: "ich denke ein CSS
   sollte reichen") - REPLACED with CSS Grid (fix, Miron staging test
   07-07-2026: "jetzt setzt eine ältere Anzeige 1. Zeile 2. Spalte...
   sollten wir die Kleinanzeigen dann von links nach rechts anordnen und
   nicht untereinander"). CSS multi-column always fills top-to-bottom per
   COLUMN first (then wraps to the next column, balanced by total content
   height) - with cards of varying text length, that routinely put an
   older ad above a newer one once read left-to-right. Grid places items
   row-major (left-to-right, top-to-bottom, exactly DOM/query order =
   newest-first) - guaranteed correct reading order, confirmed over a
   custom JS height-balancing script (which would keep the "waterfall"
   look but can EQUALLY misorder items - same root issue, just rarer -
   see docs/modules/classifieds.md). Trade-off accepted: every card in a
   row is stretched to the tallest card in that row (grid rows are
   uniform height), so this is a tidy tile grid rather than a true
   Pinterest waterfall - still far livelier than the single-column list. */
.tpf-board-masonry {
	/* .tpf-classified-ad-list sets `display: flex` (see above) - overridden
	   here so `display: grid` (not flex) actually applies */
	display: grid;
	grid-template-columns: 1fr;
	gap: 16px;
	padding-left: 0; /* the plain-list inset (see above) doesn't apply in a grid */
}

.tpf-board-masonry .tpf-classified-ad-item {
	display: block; /* override the plain list's flex row - photo stacks above the text in a narrow column */
	padding: 12px;
	border: 1px solid #eee;
	border-radius: 8px;
}

.tpf-board-masonry .tpf-classified-ad-photo {
	margin-bottom: 8px;
}

@media (min-width: 640px) {
	.tpf-board-masonry {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (min-width: 992px) {
	.tpf-board-masonry {
		grid-template-columns: repeat(3, 1fr);
	}
}

/* M9.3 ad slots (TP_Ads::render_slot()) - placeholders only, hidden
   entirely until a publisher ID + this position's ad-slot ID are both
   configured. Same border/radius treatment as .tpf-classified-ad-item so a
   slot dropped into the Pinnwand masonry doesn't look like a broken hole;
   generic enough to also work standalone in the footer/sidebar and detail
   page side columns. */
.tpf-ad-slot {
	padding: 12px;
	border: 1px solid #eee;
	border-radius: 8px;
	text-align: center;
	overflow: hidden;
}

.tpf-ad-label {
	font-size: 11px;
	text-transform: uppercase;
	letter-spacing: 0.05em;
	color: #a37b98;
	margin: 0 0 6px;
}

/* preview boxes (M9.3-fix, Miron 08-07-2026: "die Flächen als rosa Kästen
   anzeigen, damit ich die Positionen sehe") - shown instead of a real ad
   whenever the "Enable ad slots" switch is on but this position has no
   publisher/slot ID configured yet. Deliberately pink/dashed so it's
   unmistakably a placeholder, never confusable with a real ad. */
.tpf-ad-slot-preview {
	background: #ffe3f0;
	border: 1px dashed #d6789e;
	min-height: 90px;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
}

.tpf-ad-preview-position {
	font-weight: 600;
	color: #7a5a72;
	margin: 0;
}

/* creation date (fix, Miron 07-07-2026: "sollten wir bei allen Anzeigen
   vielleicht das Erstellungsdatum dazu schreiben") - shown inline right
   next to the author name (fix round 2, Miron: "das Wort 'Erstellt:' kann
   weg. Das ergibt sich. Das Datum gerne neben den Namen des Profils, aber
   Farbe so lassen" - no label, no separate line, same subdued color as
   .tpf-classified-ad-author which it's now nested inside, inherited here
   rather than a new declaration, kept as its own class per Miron's "Farbe
   so lassen" in case it needs to diverge from the author color later) */
.tpf-classified-ad-date {
	color: #7a5a72;
}

/* M9.1 report button - profile page (next to star/block icon), message
   bubble action row, classified ad card. Icon-only (fix round, Miron
   07-07-2026: "neben der Fahne zum Melden, muss kein Text stehen") -
   deliberately understated (small, muted) rather than a bright warning
   color - reporting should be easy to find but not visually dominate the
   page. aria-label carries the accessible name since there's no text. */
.tpf-report-btn {
	appearance: none;
	background: none;
	border: none;
	color: #a37b98;
	font-size: 15px;
	line-height: 1;
	cursor: pointer;
	padding: 0;
}

.tpf-report-btn:hover {
	color: #c0392b;
}

.tpf-report-btn:disabled {
	cursor: default;
	opacity: 0.6;
}

/* profile page h1 already houses the star + block icon (both larger, 22px)
   - the report button sits inline after them, so give it a bit of left
   margin and nudge it onto the text baseline rather than the icons' box */
.tpf-profile-page-info h1 .tpf-report-btn {
	margin-left: 8px;
	vertical-align: middle;
}

.tpf-report-form {
	margin-top: 6px;
	padding: 10px;
	background: #faf5f8;
	border: 1px solid #e6d5e2;
	border-radius: 6px;
	max-width: 360px;
	text-align: left;
}

/* fix round: reason hint(s) - what to report, and (message reports only)
   that the message text itself is shown to the team */
.tpf-report-hint {
	font-size: 12px;
	color: #7a5a72;
	margin: 0 0 6px;
}

.tpf-report-form textarea {
	width: 100%;
	min-height: 60px;
	box-sizing: border-box;
	resize: vertical;
	font-size: 13px;
}

.tpf-report-form-actions {
	margin-top: 6px;
	display: flex;
	gap: 8px;
}

/* fix round: follow-up "block + hide conversation?" prompt shown after a
   successful message report - assets/js/report-action.js */
.tpf-report-block-prompt {
	margin-top: 10px;
	padding-top: 10px;
	border-top: 1px solid #e6d5e2;
}

.tpf-report-block-prompt p {
	font-size: 13px;
	margin: 0 0 6px;
}

.tpf-report-block-yes,
.tpf-report-block-no {
	font-size: 13px;
	padding: 6px 12px;
	border-radius: 4px;
	cursor: pointer;
	margin-right: 8px;
}

.tpf-report-block-yes {
	background: var(--tpf-magenta);
	color: #fff;
	border: none;
}

.tpf-report-block-no {
	background: none;
	border: 1px solid #d8c3d3;
	color: #7a5a72;
}

.tpf-report-send {
	background: var(--tpf-magenta);
	color: #fff;
	border: none;
	border-radius: 4px;
	padding: 6px 12px;
	font-size: 13px;
	cursor: pointer;
}

.tpf-report-send:disabled {
	opacity: 0.6;
	cursor: wait;
}

.tpf-report-cancel {
	appearance: none;
	background: none;
	border: none;
	color: #7a5a72;
	font-size: 13px;
	cursor: pointer;
	text-decoration: underline;
}

.tpf-report-result {
	font-size: 13px;
	color: #6a8f5a;
	margin: 0;
}

.tpf-report-result.tpf-report-error {
	color: #c0392b;
}

/* M9.2 "Mitglieder" admin page - action links row, same spacing convention
   as other admin list pages in this project */
.wrap table.widefat td a {
	white-space: nowrap;
}

/* M11.1a public FAQ page ([tpf_faq] shortcode) */
.tpf-faq {
	max-width: 700px;
	margin: 0 auto;
}

.tpf-faq-search {
	width: 100%;
	box-sizing: border-box;
	padding: 10px 14px;
	margin-bottom: 20px;
	border: 1px solid #ddd;
	border-radius: 4px;
	font-family: var(--tpf-font);
	font-size: 15px;
}

.tpf-faq-search:focus {
	outline: none;
	border-color: var(--tpf-pink);
}

.tpf-faq-no-results {
	color: var(--tpf-text-light);
	font-size: 14px;
}

.tpf-faq-item {
	background: var(--tpf-bg-pink-light);
	border-radius: 6px;
	padding: 12px 16px;
	margin-bottom: 10px;
}

.tpf-faq-question {
	cursor: pointer;
	font-weight: 600;
	color: var(--tpf-text);
}

.tpf-faq-question::marker {
	color: var(--tpf-pink);
}

.tpf-faq-answer {
	margin-top: 8px;
	color: var(--tpf-text);
	font-size: 14px;
}

.tpf-faq-answer p:last-child {
	margin-bottom: 0;
}

.tpf-faq-empty {
	color: var(--tpf-text-light);
}

/* ---------------------------------------------------------------
   M13.2: event group chat (Miron 16-07-2026) - same overall bubble
   look as the 1:1 message thread (.tpf-message-bubble/-thread), own
   class names since this is a public multi-member box rather than a
   1:1 conversation
   --------------------------------------------------------------- */

.tpf-group-chat {
	margin-top: 24px;
}

.tpf-group-chat-messages {
	max-height: 480px;
	overflow-y: auto;
	display: flex;
	flex-direction: column;
	gap: 10px;
	padding: 15px;
	margin: 15px 0;
	background: var(--tpf-bg-pink-light);
	border-radius: 6px;
}

.tpf-group-chat-message {
	max-width: 75%;
	padding: 8px 12px;
	border-radius: 10px;
	background: var(--tpf-white);
	border: 1px solid #eadce8;
	display: flex;
	align-items: flex-start;
	gap: 8px;
}

.tpf-group-chat-message.tpf-group-chat-own {
	align-self: flex-end;
	background: #f6e3f0;
	border-color: var(--tpf-magenta);
}

/* mini-avatar next to each message (Miron 16-07-2026: "neben jede
   Nachricht im Gruppenchat das Mini-Bild... wie im Postfach"). Fix, same
   day (Miron, after seeing this on staging: "Kleine Bilder fehlen noch. Da
   ist nur eins und rund."): shape changed from a circle to the same
   rounded-square tile as .tpf-conversation-photo on .../konto/?view=messages
   (the exact page Miron originally referenced), and a pink placeholder
   variant added so a member without an uploaded photo still shows a tile
   instead of nothing at all - same "never just blank" convention as
   .tpf-conversation-noimg/.tpf-profile-card-noimg. */
.tpf-group-chat-avatar-wrap {
	flex: none;
}

.tpf-group-chat-avatar {
	width: 32px;
	height: 32px;
	border-radius: 4px;
	object-fit: cover;
	display: block;
}

.tpf-group-chat-avatar-noimg {
	background: var(--tpf-bg-pink-light);
}

.tpf-group-chat-body {
	flex: 1;
	min-width: 0;
}

.tpf-group-chat-meta {
	font-size: 12px;
	color: #7a5a72;
	margin-bottom: 3px;
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 8px;
}

.tpf-group-chat-meta-text {
	flex: 1;
	min-width: 0;
}

.tpf-group-chat-icons {
	flex: none;
	white-space: nowrap;
}

.tpf-group-chat-action-btn {
	appearance: none;
	background: none;
	border: none;
	color: #a37b98;
	font-size: 15px;
	line-height: 1;
	cursor: pointer;
	padding: 0;
}

.tpf-group-chat-action-btn:hover {
	color: var(--tpf-magenta);
}

.tpf-group-chat-text.tpf-group-chat-deleted {
	font-style: italic;
	color: var(--tpf-text-light);
}

.tpf-group-chat-form {
	display: flex;
	flex-direction: column;
	gap: 8px;
}

.tpf-group-chat-input {
	width: 100%;
	min-height: 60px;
	resize: vertical;
	padding: 8px 10px;
	border: 1px solid #eadce8;
	border-radius: 6px;
	font-family: inherit;
}

.tpf-group-chat-form button[type="submit"] {
	align-self: flex-end;
}

.tpf-group-chat-hint {
	color: var(--tpf-text-light);
	font-size: 14px;
}

/* "Neue Aktivitäten" hint next to a followed event's title on the account
   page (Miron 16-07-2026: "so wie bei ungelesenen Nachrichten im
   Posteingang") - same highlight color as .tpf-conversation-unread, just a
   small inline badge rather than a whole-row style since this list mixes
   several unrelated columns */
.tpf-group-chat-new-hint {
	color: var(--tpf-magenta);
	font-weight: 600;
	font-size: 12px;
}

/* ---------- M13.7: "?"-Hilfe-Icons (Link zur Anleitung) ---------- */

.tpf-help-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 18px;
	height: 18px;
	margin-left: 8px;
	border-radius: 50%;
	/* hellrosa statt Magenta (Miron 18-07-2026: "Im Moment fällt es
	   sehr auf") - dezenter Kreis, Magenta erst beim Drüberfahren */
	background: var(--tpf-bg-pink-light);
	color: var(--tpf-magenta);
	font-size: 12px;
	font-weight: 700;
	line-height: 1;
	text-decoration: none;
	vertical-align: middle;
	cursor: help;
}

.tpf-help-icon:hover,
.tpf-help-icon:focus {
	background: var(--tpf-magenta-dark);
	color: var(--tpf-white);
	text-decoration: none;
}

/* eigene Zeile rechtsbündig auf Seiten, deren Überschrift der
   WP-Seitentitel ist (Suche, Kurse, Veranstaltungen, Pinnwand,
   Einzelplätze) */
.tpf-help-icon-row {
	text-align: right;
	margin: -8px 0 10px;
}

.tpf-help-icon-row .tpf-help-icon {
	margin-left: 0;
}
