/* ==========================================================================
   Cercle Brugge 2026 -- phpBB 3.3.17 style
   Self-contained stylesheet (no @import, no build step).
   Parent style: prosilver (all templates inherited except overall_header.html
   and index_body.html, which add layout wrappers only -- everything else is
   the stock prosilver markup, reskinned here through its existing classes).
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Design tokens
   -------------------------------------------------------------------------- */
:root {
	/* Brand (from forumheader.svg: pitch green + ink black) */
	--brand-900: #0c3d1d;
	--brand-700: #0f7433;
	--brand-600: #17853b;
	--brand-500: #1e9c46;
	--brand-400: #34b45c;
	--brand-100: #e4f4e9;
	--brand-050: #f2faf4;

	--ink-900: #12140f;
	--ink-700: #3a4038;
	--ink-500: #6b7268;
	--ink-300: #9aa094;

	--surface: #ffffff;
	--surface-alt: #f6f8f5;
	--surface-sunken: #eef2ec;
	--line: #e2e6de;
	--line-strong: #cdd4c7;

	--amber: #a8730e;
	--amber-bg: #fbf1de;
	--red: #b23a3a;
	--red-bg: #fbeaea;
	--info: #2f7d8c;
	--info-bg: #e8f3f5;

	--font-sans: ui-sans-serif, system-ui, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
	--font-display: var(--font-sans);

	/* Every step shifted down by a fixed 0.07rem at both ends of the clamp()
	   (the vw coefficient -- fluid growth rate, not baseline size -- is
	   left as-is), per request for text "1 piece smaller" across the
	   board. Only affects font-size: spacing/layout uses the separate
	   --sp-* scale, untouched by this. */
	--fs-xs: clamp(0.69rem, 0.67rem + 0.06vw, 0.76rem);
	--fs-sm: clamp(0.77rem, 0.75rem + 0.08vw, 0.85rem);
	--fs-base: clamp(0.88rem, 0.85rem + 0.12vw, 0.98rem);
	--fs-md: clamp(0.98rem, 0.93rem + 0.2vw, 1.13rem);
	--fs-lg: clamp(1.18rem, 1.08rem + 0.45vw, 1.48rem);
	--fs-xl: clamp(1.53rem, 1.28rem + 1.1vw, 2.23rem);
	--fs-display: clamp(1.83rem, 1.43rem + 2vw, 2.93rem);

	--sp-1: 0.25rem;
	--sp-2: 0.5rem;
	--sp-3: 0.75rem;
	--sp-4: 1rem;
	--sp-5: 1.5rem;
	--sp-6: 2rem;
	--sp-7: 3rem;

	--gutter: clamp(1rem, 0.6rem + 2vw, 3rem);
	--container: 1440px;
	--sidebar: 320px;

	--radius-sm: 6px;
	--radius: 10px;
	--radius-lg: 18px;

	--shadow-sm: 0 1px 2px rgba(15, 30, 18, 0.07);
	--shadow: 0 6px 20px rgba(15, 30, 18, 0.09);
	--shadow-lg: 0 16px 40px rgba(15, 30, 18, 0.16);

	--focus-ring: 0 0 0 3px rgba(23, 133, 59, 0.35);

	color-scheme: light;
}

@media (prefers-color-scheme: dark) {
	:root:not([data-theme="light"]) {
		--brand-600: #2fae58;
		--brand-500: #3fcb6d;
		--brand-400: #57d980;
		--brand-100: rgba(63, 203, 109, 0.14);
		--brand-050: rgba(63, 203, 109, 0.08);

		--ink-900: #edefea;
		--ink-700: #c7cdc1;
		--ink-500: #939a8c;
		--ink-300: #6a7064;

		--surface: #171b14;
		--surface-alt: #1d2318;
		--surface-sunken: #10130e;
		--line: #2a3024;
		--line-strong: #384030;

		--amber: #e0ac4f;
		--amber-bg: rgba(224, 172, 79, 0.12);
		--red: #e07070;
		--red-bg: rgba(224, 112, 112, 0.12);
		--info: #6fc4d3;
		--info-bg: rgba(111, 196, 211, 0.1);

		--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
		--shadow: 0 6px 20px rgba(0, 0, 0, 0.45);
		--shadow-lg: 0 16px 40px rgba(0, 0, 0, 0.55);

		color-scheme: dark;
	}
}

:root[data-theme="dark"] {
	--brand-600: #2fae58;
	--brand-500: #3fcb6d;
	--brand-400: #57d980;
	--brand-100: rgba(63, 203, 109, 0.14);
	--brand-050: rgba(63, 203, 109, 0.08);
	--ink-900: #edefea;
	--ink-700: #c7cdc1;
	--ink-500: #939a8c;
	--ink-300: #6a7064;
	--surface: #171b14;
	--surface-alt: #1d2318;
	--surface-sunken: #10130e;
	--line: #2a3024;
	--line-strong: #384030;
	--amber: #e0ac4f;
	--amber-bg: rgba(224, 172, 79, 0.12);
	--red: #e07070;
	--red-bg: rgba(224, 112, 112, 0.12);
	--info: #6fc4d3;
	--info-bg: rgba(111, 196, 211, 0.1);
	color-scheme: dark;
}

/* --------------------------------------------------------------------------
   2. Reset / base
   -------------------------------------------------------------------------- */
* { box-sizing: border-box; }

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

html, body {
	margin: 0;
	padding: 0;
	background: var(--surface-alt);
	color: var(--ink-900);
	font-family: var(--font-sans);
	font-size: var(--fs-base);
	line-height: 1.55;
	-webkit-font-smoothing: antialiased;
}

img { max-width: 100%; }
svg { max-width: 100%; }

h1, h2, h3, h4, h5, h6 {
	font-family: var(--font-display);
	font-weight: 800;
	letter-spacing: -0.01em;
	line-height: 1.2;
	margin: 0 0 var(--sp-3);
	color: var(--ink-900);
}

p { margin: 0 0 var(--sp-3); }

a { color: var(--brand-600); text-decoration: none; }
a:hover { color: var(--brand-700); text-decoration: underline; }
a:focus-visible, button:focus-visible, input:focus-visible, textarea:focus-visible, select:focus-visible, [tabindex]:focus-visible {
	outline: none;
	box-shadow: var(--focus-ring);
	border-radius: var(--radius-sm);
}

hr { border: none; border-top: 1px solid var(--line); margin: var(--sp-4) 0; }

ul, ol { margin: 0 0 var(--sp-3); padding-left: 1.4em; }
ul.linklist, ul.topiclist, ul.cplist, ul.rules { list-style: none; margin: 0; padding: 0; }
dl, dt, dd { margin: 0; padding: 0; }

fieldset { border: none; margin: 0; padding: 0; }

/* Native <button> elements carry their own browser-default sizing/typography
   (unlike <a> and <input>), which is what made the search submit button not
   match the search input's height -- reset it to the same clean baseline. */
button {
	font: inherit;
	color: inherit;
	background: none;
	border: 0;
	margin: 0;
	padding: 0;
	cursor: pointer;
	/* Without this, some browsers keep native OS button chrome (its own
	   baked-in padding/sizing) that plain CSS padding/height can't fully
	   override -- this was the actual cause of the search button height
	   mismatch surviving the earlier padding/box-sizing fix. */
	appearance: none;
	-webkit-appearance: none;
	-moz-appearance: none;
}

/* Font consistency: form controls don't inherit font-family from the page
   by default in any browser -- they fall back to the OS's own UI font
   unless told otherwise. .inputbox/select/textarea/.button and friends
   further down all set font-family explicitly, which covers most of what
   the templates actually use, but that's a lot of individual rules to keep
   in sync, and easy for one input somewhere to slip through un-covered
   (a plain <input> without the .inputbox class, for instance) and quietly
   render in the browser's UI font instead of this stylesheet's -- which is
   what most of "a lot of different fonts visually" actually was. This is
   the standard, one-line fix (the same one normalize.css ships) rather
   than chasing individual elements one at a time. */
input, select, textarea, optgroup {
	font-family: inherit;
	font-size: inherit;
}

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

@media (prefers-reduced-motion: no-preference) {
	a, .button, .dropdown, .row, li.row { transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease; }
}

/* Utility */
.sr-only { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }
.skiplink a { position: absolute; left: -9999px; }
.skiplink a:focus { left: var(--sp-3); top: var(--sp-2); z-index: 200; background: var(--surface); padding: var(--sp-2) var(--sp-3); border-radius: var(--radius-sm); box-shadow: var(--shadow); }
.anchor, .top-anchor { display: block; height: 0; }
.hidden { display: none !important; }
.rightside { float: right; }
.leftside { float: left; }
[dir="rtl"] .rightside { float: left; }
[dir="rtl"] .leftside { float: right; }
.clearfix::after { content: ""; display: block; clear: both; }

/* --------------------------------------------------------------------------
   2b. Icon font bridge
   phpBB's templates mark every icon with a generic ".icon" class alongside
   the specific "fa-*" glyph class (e.g. <i class="icon fa-search fa-fw">).
   Font Awesome's own stylesheet (loaded separately via T_FONT_AWESOME_LINK)
   only styles ".fa"/"fa-*" -- it never sets the font-family for ".icon".
   Without this rule every icon renders as an invisible missing glyph.
   -------------------------------------------------------------------------- */
.icon, .button .icon, blockquote cite:before, .uncited:before {
	display: inline-block;
	font-family: "FontAwesome";
	font-weight: normal;
	font-style: normal;
	font-variant: normal;
	line-height: 1;
	text-rendering: auto;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}
.icon:before { padding-right: 0.15em; }
.button .icon:before { padding-right: 0; }
blockquote cite:before, .uncited:before { content: "\f10d"; padding-right: 0.4em; }
[dir="rtl"] blockquote cite:before, [dir="rtl"] .uncited:before { content: "\f10e"; }
.alert_close .icon:before { padding: 0; }

/* --------------------------------------------------------------------------
   3. Page shell
   -------------------------------------------------------------------------- */
#wrap, .wrap { background: transparent; min-height: 100%; }

.inner { max-width: var(--container); margin: 0 auto; padding: 0 var(--gutter); }

#page-body, .page-body { padding: var(--sp-6) 0 var(--sp-7); }

/* --------------------------------------------------------------------------
   4. Masthead / banner / header
   -------------------------------------------------------------------------- */
/* brand-900, not ink-900: ink-900 is a TEXT-contrast token that deliberately
   flips from near-black to near-white between light/dark mode -- correct
   for text, wrong for a background that's meant to always read as dark
   chrome (this header, the navbar, footer, topiclist header row, etc.).
   Using it as a background meant white text stayed on top of it in light
   mode (ink-900 dark there) but turned into white text on a now-near-white
   background in dark mode, invisible. brand-900 is never redefined for
   dark mode, so it stays the same dark green in both. */
#page-header { background: var(--brand-900); }

.masthead {
	position: relative;
}

.headerbar {
	/* The banner lives on .headerbar alone, NOT on the shared .masthead
	   wrapper that also contains .navbar. It used to sit on .masthead, so the
	   navbar's own height (opaque, solid ink-900) counted towards the box the
	   banner had to fit inside, squeezing the banner into a much smaller area
	   than it needed AND visually reading as "the navbar sits in front of the
	   banner" once the navbar's own background painted over its share of that
	   shared box. Locking aspect-ratio to the banner's own 2048:250 means the
	   box is ALWAYS exactly the banner's shape -- full width, full height,
	   zero cropping, zero letterboxing, by construction, with no dependency
	   on how much header content there is. background-color is a fallback
	   only for the rare case min-height overrides the ratio on extreme zoom. */
	position: relative;
	aspect-ratio: 2048 / 250;
	min-height: 3.5rem;
	background-color: var(--brand-600);
	background-image: url("images/banner.svg");
	background-repeat: no-repeat;
	background-position: center;
	background-size: contain;
	display: flex;
	align-items: center;
	color: #fff;
}

/* Whole banner is a click-to-home target (nothing else in .headerbar is
   visibly interactive now that site-description is hidden), positioned
   under the skiplink so its focus-visible state still escapes on top. */
.headerbar-link { position: absolute; inset: 0; z-index: 1; }

.headerbar .inner { width: 100%; display: flex; align-items: center; justify-content: flex-end; gap: var(--sp-5); flex-wrap: wrap; }

/* The banner's own artwork already carries the site name and crest visually.
   This block stays in the markup as an <h1> + logo for screen readers, SEO,
   and a plain fallback if CSS fails to load -- but is not shown once styled. */
.site-description {
	position: absolute !important;
	width: 1px; height: 1px;
	padding: 0; margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

.site_logo, .site-crest {
	display: block;
	width: 100%;
	height: 100%;
	background: url("images/crest.svg") center / contain no-repeat;
}

/* Search box: lives on the breadcrumb row now (a light strip), not the
   green banner it used to sit on -- so it needs light-on-light contrast
   (bordered light input, solid brand-coloured button) instead of the
   translucent-white-on-colour treatment that context used to call for. */
#search-box.search-box { flex: none; }
.search-box form { display: flex; align-items: stretch; height: 2.1rem; }
.search-box .inputbox {
	box-sizing: border-box;
	height: 100%;
	border-radius: var(--radius-sm) 0 0 var(--radius-sm);
	border: 1px solid var(--line-strong);
	border-right: none;
	background: var(--surface-alt);
	color: var(--ink-900);
	padding: 0 0.7rem;
	font-size: var(--fs-xs);
	min-width: 9rem;
}
.search-box .button {
	box-sizing: border-box;
	height: 100%;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 0 0.7rem;
	border-radius: 0;
	border: 1px solid var(--brand-600);
	background: var(--brand-600);
	color: #fff;
}
.search-box .button-search-end { border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
.search-box .button:hover { background: var(--brand-700); border-color: var(--brand-700); color: #fff; }

/* Navigation bar (also reused, unstickied, for the footer link row) */
.navbar { background: var(--brand-900); }
/* Divider between the banner and the navbar -- #39A150 isn't one of the
   existing --brand-* tokens (closest are brand-400 #34b45c / brand-500
   #1e9c46), so it's a deliberate one-off rather than a substitution.
   Scoped to #page-header's navbar only, since .navbar is the same class
   reused unstickied for the footer link row, which has no banner above it
   to divide from. */
#page-header .navbar { border-top: 3px solid #39A150; }
.navbar .inner { display: flex; flex-direction: column; padding-top: 0; padding-bottom: 0; }
/* Pure black, matching the banner artwork's own black (its crowd silhouette
   and ink accents are #000, not the site's warm near-black ink-900) so the
   seam where the navbar meets the banner above it reads as continuous. */
#page-header .navbar { position: sticky; top: 0; z-index: 50; box-shadow: var(--shadow-sm); background: #000000; }

ul.nav-main, ul.nav-breadcrumbs { display: flex; align-items: center; flex-wrap: wrap; margin: 0; padding: 0; list-style: none; gap: 0.15rem; }
/* flex-wrap: nowrap (overriding the shared rule above) is deliberate: phpBB's
   own responsive-nav script decides what to collapse into the hamburger menu
   by measuring whether this row actually overflows (scrollWidth vs
   clientWidth). Letting it wrap onto a second line instead of overflowing
   hid that measurement, so items got moved into the hamburger menu even when
   there was visibly enough room -- this is what keeps everything inline on
   a wide screen and only collapses what genuinely doesn't fit. */
/* overflow: hidden was here too, alongside nowrap, on the assumption both
   were needed for the overflow fix -- they weren't. scrollWidth vs
   clientWidth (what core.js measures) differ identically whether or not the
   overflow is visually clipped; nowrap alone is what stops it from wrapping
   onto a second line. overflow: hidden's only actual effect was clipping
   the notification/quick-links dropdown panels -- both position: absolute,
   but still clipped by an ancestor's overflow: hidden regardless -- which
   is why clicking the notification bell showed nothing. */
ul.nav-main { flex: 1 1 auto; flex-wrap: nowrap; min-height: 3rem; }
ul.nav-main > li > a {
	display: flex; align-items: center; gap: 0.4em;
	padding: 0.65rem 0.75rem;
	color: rgba(255,255,255,0.82);
	font-size: var(--fs-sm);
	font-weight: 600;
	border-radius: var(--radius-sm);
	white-space: nowrap;
}
ul.nav-main > li > a:hover { background: rgba(255,255,255,0.08); color: #fff; text-decoration: none; }
ul.nav-main li.separator { display: none; }
ul.nav-main li.hidden { display: none; }

/* Direct-child links inside the (light) breadcrumb strip, e.g. the responsive search icon */
ul.nav-breadcrumbs > li > a {
	display: flex; align-items: center; gap: 0.4em;
	padding: 0.4rem 0.6rem;
	color: var(--ink-500);
	font-size: var(--fs-sm);
	border-radius: var(--radius-sm);
}
ul.nav-breadcrumbs > li > a:hover { background: var(--brand-050); color: var(--brand-700); text-decoration: none; }

#quick-links > a.dropdown-trigger { color: var(--brand-400); }

.header-profile .header-avatar { display: flex; align-items: center; gap: 0.5em; padding: 0.5rem 0.75rem; color: #fff; font-weight: 600; font-size: var(--fs-sm); border-radius: var(--radius-sm); }
.header-profile .header-avatar:hover { background: rgba(255,255,255,0.08); text-decoration: none; }
.header-profile .avatar, .header-profile img { width: 1.6rem; height: 1.6rem; border-radius: 50%; object-fit: cover; }

.badge { display: inline-flex; align-items: center; justify-content: center; min-width: 1.2em; padding: 0.05em 0.4em; border-radius: 999px; background: var(--brand-500); color: #0c3d1d; font-size: 0.7rem; font-weight: 800; }

/* Breadcrumbs strip below the dark navbar */
ul.nav-breadcrumbs { background: var(--surface); border-radius: var(--radius) var(--radius) 0 0; padding: 0.5rem var(--sp-3); margin-bottom: -1px; }
.breadcrumbs { display: flex; flex-wrap: wrap; gap: 0.3rem; align-items: center; }
.breadcrumbs .crumb { display: flex; align-items: center; color: var(--ink-500); font-size: var(--fs-xs); }
.breadcrumbs .crumb a { color: var(--ink-700); display: inline-flex; align-items: center; gap: 0.35em; }
.breadcrumbs .crumb:not(:first-child)::before { content: "/"; margin-right: 0.4rem; color: var(--line-strong); }
.breadcrumbs .crumb a:hover { color: var(--brand-600); }
.responsive-search { margin-left: auto; }

/* Footer link row (navbar_footer.html reuses .navbar / .inner but its own list) */
/* white-space: nowrap (not the default) is the footer equivalent of the
   nav-main nowrap fix: these are inline-block items, which -- like flex-wrap
   -- can silently wrap onto a second line instead of overflowing. That hides
   true overflow from phpBB's own measurement, so it collapsed items into the
   hamburger menu even when there was visibly enough width for them inline. */
ul.nav-footer { padding: 0.75rem 0; white-space: nowrap; }
ul.nav-footer li { display: inline-block; margin: 0 0.75rem 0.4rem 0; }
ul.nav-footer li a { color: rgba(255,255,255,0.72); font-size: var(--fs-xs); display: inline-flex; align-items: center; gap: 0.35em; }
ul.nav-footer li a:hover { color: #fff; text-decoration: none; }
ul.nav-footer li.breadcrumbs { display: block; margin: 0 0 0.4rem; }
ul.nav-footer li.breadcrumbs .crumb { color: rgba(255,255,255,0.72); font-size: var(--fs-xs); }
ul.nav-footer li.breadcrumbs .crumb a { color: rgba(255,255,255,0.92); }
/* The lone "Alle tijden zijn UTC+02:00" entry -- the only <li> in the whole
   footer with no <a> inside it anywhere, so it can be targeted structurally
   without a template change. Scoped to #page-footer (not ul.nav-footer specifically) and
   matched by ":not(:has(a))" rather than ".rightside": when core.js clones
   this item into the overflow dropdown for the responsive menu, the clone
   keeps the "clone"/"clone-first" classes it adds but NOT the original
   "rightside" class -- so a .rightside-based rule only hid the original
   in-place copy, leaving the cloned one inside the dropdown still visible. */
#page-footer li:not(:has(a)) { display: none; }

/* --------------------------------------------------------------------------
   5. Dropdowns
   -------------------------------------------------------------------------- */
.dropdown-container { position: relative; }
.dropdown { display: none; position: absolute; top: 100%; z-index: 60; min-width: 13rem; margin-top: 0.6rem; }
.dropdown-container.dropdown-visible .dropdown,
.nojs .dropdown-container:hover .dropdown,
.dropdown-container:focus-within .dropdown { display: block; }
/* phpBB's own responsive-nav script (core.js) adds "dropdown-right" and
   "dropdown-own-up" to a dropdown-container when it decides -- at runtime,
   based on the trigger's actual position -- that the panel should hang off
   the right edge and/or open upward (e.g. the footer's overflow menu, which
   sits at the bottom of the page and would otherwise open downward into
   nothing). These two were never styled here, so the script's own fallback
   (a large negative inline margin, trying to compensate) shoved the whole
   panel off-screen instead -- this was the entire "empty dropdown" bug. */
/* !important here is deliberate and narrowly scoped: core.js measures the
   dropdown's rendered position and, if IT thinks that overflows, writes its
   own compensating inline margin-left/margin-right directly onto the
   element. That inline style still wins over a plain class rule (margin and
   right/left are different properties, so neither naturally overrides the
   other -- they stack), and the script's math assumes a default positioning
   this stylesheet no longer uses, so its "fix" was actively making things
   worse (shoving the panel further off-screen, adding a horizontal
   scrollbar). Forcing our own positioning is more reliable than trying to
   predict what the script will compute. */
.dropdown-left .dropdown, .dropdown-container.dropdown-left .dropdown,
.dropdown-container.dropdown-right .dropdown {
	right: 0 !important;
	left: auto !important;
	margin-left: 0 !important;
	margin-right: 0 !important;
}
.dropdown-up .dropdown, .dropdown-container.dropdown-own-up .dropdown { top: auto; bottom: 100%; margin-top: 0; margin-bottom: 0.6rem; }

/* Belt-and-suspenders for the footer specifically: rather than continuing to
   chase exactly when/whether core.js applies "dropdown-own-up" /
   "dropdown-right" (its class application and inline-margin compensation
   have proven unreliable to predict across the last couple of rounds), this
   hard-codes the one thing that's always true structurally -- anything
   inside #page-footer is near the bottom-right of the page, full stop -- so
   it opens upward and right-aligned unconditionally, independent of
   whatever classes or inline styles the script does or doesn't add. */
#page-footer .dropdown-container { position: relative !important; }
/* right/left both auto (not right: 0) is deliberate, per live testing:
   forcing right: 0 anchored the panel to the trigger's own right edge,
   which turned out to look wrong here even though it's the correct pattern
   for the header's dropdowns. Leaving both auto falls back to the
   element's static position instead, which is what actually looked right
   for this trigger. */
#page-footer .dropdown-container .dropdown {
	top: auto !important;
	bottom: 100% !important;
	right: auto !important;
	left: auto !important;
	margin: 0 0 0.6rem !important;
}

/* Deterministic alternative to core.js's own overflow measurement, which
   has proven unreliable to predict for this particular menu across many
   rounds of fixes: above this width, force every footer item inline
   (overriding the "hidden" class the script adds to originals once their
   content is cloned into the dropdown) and hide the hamburger trigger --
   and, with it, the dropdown entirely, sidestepping its positioning quirks
   altogether for the common desktop case. Below it, JS-driven collapse
   behaves as before. 1100px matches the breakpoint already used for the
   index page's sidebar; adjust if the footer's actual content width (7
   items plus the trigger) needs more or less room in practice. */
@media (min-width: 1100px) {
	/* :has(a), not just li.hidden: the timezone <li> (no <a> inside) is kept
	   permanently hidden by a separate, non-!important rule elsewhere
	   (#page-footer li:not(:has(a))). If the responsive script also marks
	   that same <li> "hidden" as part of its own collapse logic, this rule
	   -- being !important -- would win over that non-!important one
	   regardless of specificity, making the timezone text reappear at wide
	   widths. Scoping to :has(a) excludes it, since real nav items (the
	   ones this rule is actually meant to force back inline) all have one. */
	ul.nav-footer li.hidden:has(a) { display: inline-block !important; }
	ul.nav-footer li.responsive-menu { display: none !important; }
}

.pointer { display: none; }
.dropdown-contents {
	list-style: none; margin: 0; padding: 0.4rem;
	max-width: none !important;
	background: var(--surface);
	/* Explicit reset, not just on the links below: without it, plain text
	   inside here (e.g. a <li> with no <a> wrapper, like a timezone line)
	   inherits whatever colour its surrounding context uses -- in the
	   footer's case that's near-white, invisible against this white
	   background. That's what "content is still white" actually was. */
	color: var(--ink-700);
	border: 1px solid var(--line);
	border-radius: var(--radius);
	box-shadow: var(--shadow-lg);
}
/* .dropdown .dropdown-contents (not just .dropdown-contents) is deliberate:
   the footer's overflow menu clones items INTO a dropdown that itself lives
   physically inside <ul class="nav-footer"> (a sibling of the visible
   links, nested one level deeper) -- so ul.nav-footer li a's white text
   colour (correct for the visible footer links against the dark navbar)
   was also matching the cloned links here, since CSS descendant selectors
   don't care about z-index or visual layering, only DOM nesting. That
   selector is (0,1,3) specificity; plain ".dropdown-contents li a" is only
   (0,1,2), so it lost regardless of source order. Adding ".dropdown" here
   brings it to (0,2,2), which wins on class-count alone. */
.dropdown .dropdown-contents li a { display: flex; align-items: center; gap: 0.5em; padding: 0.5rem 0.7rem; border-radius: var(--radius-sm); color: var(--ink-700); font-size: var(--fs-sm); }
.dropdown .dropdown-contents li a:hover { background: var(--brand-050); color: var(--brand-700); text-decoration: none; }
/* Same bug, this time on display/margin instead of colour: "ul.nav-footer
   li { display: inline-block; margin: 0 0.75rem 0.4rem 0; }" is meant to
   lay the *visible* footer links out horizontally, but it's a descendant
   selector too, and the cloned <li> items inside the dropdown are also
   structural descendants of ul.nav-footer -- so they were inheriting
   inline-block layout meant for a horizontal row, which is what turned this
   into a horizontal strip instead of a normal stacked dropdown list. Only
   actually visible on mobile, since that's the only width where the
   dropdown mechanism engages at all now. */
.dropdown .dropdown-contents li { display: block; margin: 0; }
.dropdown-contents li.separator { height: 1px; margin: 0.35rem 0.4rem; background: var(--line); }
.dropdown-extended { width: 26rem; max-width: calc(100vw - 2rem); }
.dropdown-extended .header, .dropdown-extended .footer { padding: 0.6rem 0.8rem; font-size: var(--fs-xs); color: var(--ink-500); }
.dropdown-extended .footer { border-top: 1px solid var(--line); text-align: center; }
.dropdown-extended .header { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 0.4em; }
.dropdown-extended .header a { color: var(--brand-600); }

/* The notification panel content (avatar, title, timestamp, mark-read
   button) had no styling at all -- .dropdown-contents only covers the
   generic simple-link dropdowns (quick links, user menu, footer overflow);
   notification_dropdown.html's own <ul>/<li>/.notification-block markup was
   completely unstyled, which is why it rendered as bare bulleted text with
   the avatar stacked awkwardly above it and no clear separation between
   entries. */
.notification_list ul { list-style: none; margin: 0; padding: 0; max-height: 26rem; overflow-y: auto; }
.notification_list li { position: relative; list-style: none; border-top: 1px solid var(--line); }
.notification_list li:first-child { border-top: none; }
.notification_list li.bg2 { background: var(--brand-050); }
.notification_list li.no_notifications { padding: var(--sp-4); text-align: center; color: var(--ink-500); font-size: var(--fs-sm); }
/* .notification_list .dropdown-contents .notification-block (3 classes),
   not just .notification_list .notification-block (2): .notification-block
   is an <a> inside <li> inside .dropdown-contents, which the general
   ".dropdown .dropdown-contents li a" rule above also matches at (0,2,2)
   specificity -- its padding/align-items would silently win over a plain
   2-class rule here otherwise, same trap as the other dropdown fixes. */
.notification_list .dropdown-contents .notification-block {
	display: flex;
	align-items: flex-start;
	gap: var(--sp-3);
	padding: var(--sp-3) var(--sp-4);
	padding-right: 2.75rem;
	color: var(--ink-700);
}
.notification_list .dropdown-contents .notification-block:hover { background: var(--surface-alt); text-decoration: none; }
.notification_list .notification-block img { flex: none; width: 2.75rem; height: 2.75rem; border-radius: 50%; object-fit: cover; }
.notification_list .notification_text { min-width: 0; }
.notification_list .notification-title { margin: 0 0 0.15rem; font-size: var(--fs-sm); color: var(--ink-900); line-height: 1.4; }
.notification_list .notification-reference, .notification_list .notification-forum, .notification_list .notification-reason { margin: 0 0 0.15rem; font-size: var(--fs-xs); color: var(--ink-500); }
.notification_list .notification-time { margin: 0; font-size: var(--fs-xs); color: var(--ink-300); }
/* Mark-as-read: a sibling of .notification-block, not nested inside it, so
   with no positioning it fell to the bottom of the <li> in normal flow --
   an unlabelled icon at the end of a block, easy to miss as a button at
   all. Pinning it as a small round action button in the corner (the same
   pattern used for post-buttons elsewhere) makes it read as a control. */
.notification_list .dropdown-contents .mark_read {
	position: absolute;
	top: var(--sp-3);
	right: var(--sp-3);
	display: flex;
	align-items: center;
	justify-content: center;
	width: 1.9rem;
	height: 1.9rem;
	padding: 0;
	border-radius: 50%;
	background: var(--surface);
	border: 1px solid var(--line);
	color: var(--brand-600);
	box-shadow: var(--shadow-sm);
}
.notification_list .dropdown-contents .mark_read:hover { background: var(--brand-050); border-color: var(--brand-600); }
.notification_list .mark_read .icon { font-size: 1.1rem; }
/* .icon:before carries a site-wide padding-right (spacing for the common
   case of an icon sitting before adjacent text) that pushed this icon-only
   button's glyph off-centre -- it doesn't need that space with no text next
   to it. */
.notification_list .mark_read .icon:before { padding-right: 0; }

/* --------------------------------------------------------------------------
   6. Board layout (index sidebar grid, added by index_body.html)
   -------------------------------------------------------------------------- */
.board-layout {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--sp-5);
	align-items: start;
}
@media (min-width: 1100px) {
	.board-layout { grid-template-columns: minmax(0, 1fr) var(--sidebar); }
}
.board-side { display: flex; flex-direction: column; gap: var(--sp-4); min-width: 0; }

.time { color: var(--ink-500); font-size: var(--fs-xs); margin: 0 0 var(--sp-3); }
/* Not justify-content: space-between: viewtopic's action-bar has up to 4
   separate children (reply button, topic-tools dropdown, search box,
   pagination) -- space-between spreads all 4 evenly across the row, which
   drifted topic-tools away from the reply button instead of keeping them
   together. Grouping is done differently: a plain gap keeps whatever's
   here close together and left-aligned by default, and margin-left: auto
   on .search-box (below) pushes it -- and whatever follows it, i.e.
   pagination -- to the right as its own group. */
.action-bar { display: flex; align-items: center; flex-wrap: wrap; gap: var(--sp-3); justify-content: flex-start; margin-bottom: var(--sp-3); }
.action-bar.compact { justify-content: flex-end; }
.action-bar .search-box { margin-left: auto; }
/* Bottom action bar (viewtopic/viewforum) never has a .search-box to anchor
   on like the top bar does, so it never got the same "buttons grouped left,
   pagination pushed right" look -- give .pagination the same auto margin,
   scoped to bar-bottom only so it doesn't fight the top bar's own single
   auto-margin element (adding a second auto-margin element there would
   split the free space between both, pulling pagination away from the
   search box instead of keeping them together). */
.bar-bottom .pagination { margin-left: auto; }
/* The "Weergave / Sorteer op / Richting" view+sort form, hidden per request
   -- now on both viewforum and viewtopic (this used to spare viewtopic's
   copy deliberately; that's since been overridden by a further request).
   Targets the <form> itself via :has(), since the form tag carries no
   distinguishing class of its own -- only its child .sort-tools div does. */
.bar-bottom form:has(.sort-tools) { display: none; }
.mark-read { font-size: var(--fs-sm); color: var(--ink-500); }
.mark-read:hover { color: var(--brand-600); }

/* --------------------------------------------------------------------------
   7. Forum / topic lists
   -------------------------------------------------------------------------- */
.forabg, .forumbg, .panel {
	background: var(--surface);
	border: 1px solid var(--line);
	border-radius: var(--radius-lg);
	box-shadow: var(--shadow-sm);
	margin-bottom: var(--sp-5);
	overflow: hidden;
}
.forabg .inner, .forumbg .inner, .panel .inner { padding: 0; max-width: none; }

ul.topiclist { container-type: inline-size; }

ul.topiclist li.header {
	background: var(--brand-900);
	color: #fff;
}
/* Plain selector, not "dl.row-item": several UCP list headers (PM folder,
   bookmarks, notifications, group membership, attachments, drafts, ...)
   use a bare <dl> with no "row-item" class for their header row, so
   restricting this to dl.row-item left every one of them stacking dt/dd
   as separate blocks instead of laying them out as a row. */
ul.topiclist li.header dl { display: flex; align-items: center; padding: 0.7rem var(--sp-4); gap: var(--sp-3); }
ul.topiclist li.header dt { flex: 1 1 auto; font-size: var(--fs-sm); font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; }
/* The generic ".list-inner { color: var(--ink-500) }" rule below wins over
   this row's inherited white text (an explicit rule always beats an
   inherited value, no matter how specific the ancestor rule was), so a
   header whose .list-inner holds plain text -- e.g. viewforum's "Topics"
   column label, which isn't a link -- rendered near-invisible on this dark
   background. forumlist's category header happened to look fine only
   because its .list-inner holds an <a>, caught by the rule right below.
   Cover the plain-text case the same way. */
ul.topiclist li.header dt .list-inner { color: #fff; }
ul.topiclist li.header dt a { color: #fff; }
ul.topiclist li.header dd { flex: 0 0 auto; width: 6.5rem; font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.04em; color: rgba(255,255,255,0.7); text-align: center; }
ul.topiclist li.header dd.lastpost { width: 13rem; text-align: left; }

ul.topiclist li.row {
	position: relative;
	border-top: 1px solid var(--line);
}
ul.topiclist li.row:hover { background: var(--brand-050); }
ul.topiclist li.row.sticky, ul.topiclist li.row.announce { background: var(--amber-bg); }
ul.topiclist li.row.global-announce { background: var(--info-bg); }
ul.topiclist li.row.reported { background: var(--red-bg); }

/* Unread topics: a green tint so they stand out in the list without
   competing with the sticky/announce/reported colours above. brand-100 (one
   step darker than the original brand-050) per request -- brand-050 read as
   too faint to notice. TOPIC_IMG_STYLE puts "topic_unread"/"topic_unread_hot"
   (among others, including the "_mine" variants for topics the current user
   started) directly on this dl, not on the parent li, hence the different
   selector shape here. */
dl.topic_unread, dl.topic_unread_hot, dl.topic_unread_mine, dl.topic_unread_hot_mine { background: var(--brand-100); }

/* align-items: flex-start (not center) is deliberate: a row's dt (icon +
   title + meta + optional inline pagination) can be far taller than its dd
   siblings (topics/posts/lastpost). Centering them against that variable
   height made the stat columns visibly drift row to row; top-aligning pins
   every column to the title's own line regardless of how tall the row gets. */
dl.row-item { display: flex; align-items: flex-start; gap: var(--sp-3); padding: 0.85rem var(--sp-4); margin: 0; }
dl.row-item dt { position: relative; flex: 1 1 auto; min-width: 0; display: flex; align-items: flex-start; gap: var(--sp-3); }
/* Specificity note: this base rule is deliberately ".row-item dt::before" (one
   class + dt + ::before), NOT "dl.row-item dt::before" -- the extra "dl" type
   selector would outrank the per-status colour overrides below (which only
   carry one class + dt + ::before) regardless of source order, silently
   cancelling the read/unread colour difference. Keep both at equal specificity
   so source order (overrides declared later) decides. */
.row-item dt::before {
	flex: none;
	width: 2.25rem; height: 2.25rem;
	display: flex; align-items: center; justify-content: center;
	border-radius: 50%;
	background: var(--surface-sunken);
	font-family: "FontAwesome";
	font-weight: normal;
	font-size: 1rem;
	color: var(--ink-300);
	margin-top: 0.1rem;
}
.row-item-link { position: absolute; inset: 0; z-index: 1; }
.list-inner { position: relative; z-index: 2; min-width: 0; }

/* :visited explicitly matched too -- there's no :visited rule anywhere else
   in this stylesheet, so a clicked title was falling back to the browser's
   own default visited-link colour (a dull purple) instead of ink-900. That
   only showed up as "not good visible" on the topic list specifically
   because topics get clicked into constantly, while forums (rarely
   re-visited the same way) mostly kept showing the correct unvisited
   colour by chance -- both are the exact same rule here, so they'll always
   match now regardless of click history. */
.forumtitle, .topictitle, .forumtitle:visited, .topictitle:visited { font-weight: 700; color: var(--ink-900); font-size: var(--fs-md); }
.forumtitle:hover, .topictitle:hover { color: var(--brand-600); }
.list-inner { font-size: var(--fs-sm); color: var(--ink-500); }
.list-inner .subforum { font-size: var(--fs-xs); }

dd.topics, dd.posts, dd.views, dd.redirect { flex: 0 0 auto; width: 6.5rem; padding-top: 0.2rem; text-align: center; font-size: var(--fs-sm); color: var(--ink-700); }
dd.topics dfn, dd.posts dfn, dd.views dfn { display: block; font-size: var(--fs-xs); color: var(--ink-500); font-style: normal; }
dd.lastpost { flex: 0 0 auto; width: 13rem; padding-top: 0.2rem; font-size: var(--fs-xs); color: var(--ink-500); line-height: 1.4; }
dd.lastpost .lastsubject { color: var(--ink-700); font-weight: 600; display: inline; }
dd.lastpost dfn { font-style: normal; color: var(--ink-300); text-transform: uppercase; letter-spacing: 0.04em; font-size: 0.68rem; }
/* Forum overview (.forabg) only hides the repeated "Laatste bericht" label,
   since its topics/posts counts weren't asked to lose theirs. The topic
   list (.forumbg) hides all three -- replies, views, and last-post -- its
   column header already names each one, so repeating the label on every
   single row underneath is pure noise either way. */
.forabg dd.lastpost dfn { display: none; }
.forumbg dd.posts dfn, .forumbg dd.views dfn, .forumbg dd.lastpost dfn { display: none; }
dd.lastpost time { display: block; }

.icon-md { font-size: 1rem; }
.icon-lg { font-size: 1.3rem; }
.icon-blue, a:hover .icon-blue { color: var(--info); }
.icon-red, a:hover .icon-red { color: var(--red); }
.icon-green, a:hover .icon-green { color: var(--brand-600); }
.icon-orange, a:hover .icon-orange { color: var(--amber); }
.icon-gray, a:hover .icon-gray { color: var(--ink-500); }
.icon-lightgray, a:hover .icon-lightgray { color: var(--ink-300); }
.icon-black, a:hover .icon-black { color: var(--ink-900); }
.icon-bluegray, a:hover .icon-bluegray { color: var(--ink-700); }

/* Forum / topic status icons -- vector glyphs via Font Awesome, no image
   sprites. Read/unread is the signal people actually scan for, so it gets
   ONE high-contrast treatment (solid filled = unread, flat muted = read)
   applied uniformly to every kind of row -- plain topic, sticky, announcement,
   global, forum, pm -- via substring matching on phpBB's own status class
   names (e.g. "topic_unread_mine" contains "_unread"), instead of the
   previous per-kind colours that buried the read/unread difference under a
   kind-specific colour. The icon SHAPE (via `content`) is what shows the
   kind of row instead; order matters below, since later rules win ties. */
[class*="topic_"] dt::before,
[class*="pm_"] dt::before,
[class*="forum_"] dt::before { content: "\f0e5"; } /* comment */
[class*="announce_"] dt::before { content: "\f0a1"; } /* bullhorn */
[class*="global_"] dt::before { content: "\f0ac"; } /* globe */
[class*="sticky_"] dt::before { content: "\f08d"; } /* pin */
.forum_link dt::before { content: "\f08e"; } /* external link */
[class*="_hot"] dt::before { content: "\f06d"; } /* fire */
[class*="_locked"] dt::before { content: "\f023"; } /* lock -- wins over pin/bullhorn/globe for a locked+sticky/announce/global row */
.topic_moved dt::before { content: "\f064"; }

[class*="_read"] dt::before { background: var(--surface-sunken); color: var(--ink-500); }
[class*="_unread"] dt::before {
	background: var(--brand-600);
	color: #fff;
	box-shadow: 0 0 0 3px var(--brand-100);
}

/* .list-inner is deliberately a plain stacked block, not a wrapping flex
   row: letting the title and the "by <author> » <date>" meta line share a
   row (which an earlier version of this did at wide widths) made them run
   together unpredictably instead of always giving the title its own line. */
.topic-poster { display: block; margin-top: 0.15rem; font-size: var(--fs-xs); color: var(--ink-500); }
.left-box { margin-right: var(--sp-3); }

/* No-forums / empty panel */
.panel .inner { padding: var(--sp-5); }

/* Inline "jump to page" pagination inside a forum/topic row (multi-page
   topics). It reuses the generic .button class for its page-number links,
   which is sized for real actions -- scale it down here so it reads as
   compact row metadata instead of a row of full-size buttons, and align it
   flush with the title above it rather than the row's full width. */
.list-inner .pagination {
	width: 100%;
	margin-top: 0.35rem;
	font-size: var(--fs-xs);
	color: var(--ink-500);
	flex-wrap: wrap;
}
/* The leading fa-clone icon (a plain <span> sibling of the <ul>, marking
   "this topic spans multiple pages") -- removed per request. */
.list-inner .pagination > span:first-child { display: none; }
.list-inner .pagination .button {
	height: auto;
	min-width: 1.6rem;
	padding: 0.1rem 0.4rem;
	font-size: var(--fs-xs);
	font-weight: 600;
	line-height: 1.4;
}
.list-inner .pagination li.active span {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 1.6rem;
	padding: 0.1rem 0.4rem;
	border-radius: var(--radius-sm);
	background: var(--brand-600);
	color: #fff;
	font-weight: 700;
}

/* --------------------------------------------------------------------------
   8. Pagination
   -------------------------------------------------------------------------- */
.pagination { display: flex; align-items: center; gap: 0.3rem; font-size: var(--fs-sm); }
.pagination ul { display: flex; gap: 0.25rem; margin: 0; padding: 0; }
.pagination li { list-style: none; }
.pagination li a, .pagination li span {
	display: inline-flex; align-items: center; justify-content: center;
	min-width: 2rem; height: 2rem; padding: 0 0.5rem;
	border-radius: var(--radius-sm);
	color: var(--ink-700);
}
.pagination li a:hover { background: var(--brand-050); color: var(--brand-700); text-decoration: none; }
.pagination li.active span { background: var(--brand-600); color: #fff; font-weight: 700; }
.pagination li.ellipsis span { color: var(--ink-300); }

/* --------------------------------------------------------------------------
   9. Buttons & forms
   -------------------------------------------------------------------------- */
.button, a.button1, input.button1, a.button2, input.button2, input.button3 {
	display: inline-flex; align-items: center; justify-content: center; gap: 0.5em;
	font-family: var(--font-sans); font-size: var(--fs-sm); font-weight: 700;
	padding: 0.55rem 1rem;
	border-radius: var(--radius-sm);
	border: 1px solid var(--line-strong);
	background: var(--surface);
	color: var(--ink-900);
	cursor: pointer;
	line-height: 1.2;
}
.button:hover, a.button1:hover, input.button1:hover, a.button2:hover, input.button2:hover, input.button3:hover { border-color: var(--brand-600); color: var(--brand-700); text-decoration: none; }
a.button1, input.button1 { background: var(--brand-600); border-color: var(--brand-600); color: #fff; }
a.button1:hover, input.button1:hover { background: var(--brand-700); border-color: var(--brand-700); color: #fff; }
.button-icon-only { padding: 0.45rem; width: 2.1rem; height: 2.1rem; }
.button-secondary { border: none; background: transparent; color: var(--ink-500); }
.button-secondary:hover { color: var(--brand-600); }
.caret { display: inline-flex; }
input.disabled, .button.disabled { opacity: 0.5; cursor: default; pointer-events: none; }

.inputbox, select, textarea {
	font-family: var(--font-sans);
	font-size: var(--fs-base);
	padding: 0.55rem 0.75rem;
	border: 1px solid var(--line-strong);
	border-radius: var(--radius-sm);
	background: var(--surface);
	color: var(--ink-900);
}
.inputbox:hover, select:hover, textarea:hover { border-color: var(--ink-300); }
.inputbox:focus, select:focus, textarea:focus { border-color: var(--brand-600); }
textarea { width: 100%; font-family: inherit; resize: vertical; }

label { color: var(--ink-700); }
fieldset.quick-login { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3); }
fieldset.quick-login label { display: flex; align-items: center; gap: 0.4em; font-size: var(--fs-sm); }
fieldset.quick-login .inputbox { max-width: 9rem; }

/* Definition-list style forms used across UCP / MCP / posting */
fieldset dl { display: flex; flex-wrap: wrap; padding: var(--sp-3) 0; border-top: 1px solid var(--line); gap: var(--sp-2) var(--sp-4); }
fieldset dl:first-of-type { border-top: none; }
fieldset dl dt { flex: 0 0 12rem; font-weight: 600; font-size: var(--fs-sm); color: var(--ink-700); }
fieldset dl dd { flex: 1 1 16rem; margin: 0; }
@media (max-width: 640px) {
	fieldset dl { flex-direction: column; }
	fieldset dl dt { flex-basis: auto; }
}

/* --------------------------------------------------------------------------
   10. Post / topic view
   -------------------------------------------------------------------------- */
.topic-title { font-size: var(--fs-lg); margin-bottom: var(--sp-4); }
.topic_poll, .post { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); margin-bottom: var(--sp-4); overflow: hidden; }
/* The 2-column (avatar sidebar + content) grid only makes sense when a
   .postprofile sidebar actually exists -- viewtopic's real posts have one,
   but the "quote previous posts" review panel on the posting page (and
   topic_poll) is just .postbody alone. Applying the grid unconditionally
   put that lone child into CSS grid's auto-placed FIRST column (13rem,
   meant for the avatar), leaving the wide column empty -- "postbody not
   seeing it has more width". Default to plain single-column, and upgrade
   to the sidebar grid only when there's actually a sidebar to lay out. */
.topic_poll .inner, .post .inner { position: relative; padding: var(--sp-5); }
.post .inner:has(.postprofile) { display: grid; grid-template-columns: 13rem minmax(0,1fr); gap: var(--sp-5); }
@media (max-width: 760px) {
	.post .inner:has(.postprofile) { grid-template-columns: minmax(0,1fr); }
}
.post:target { border-color: var(--brand-500); box-shadow: 0 0 0 3px var(--brand-100); }
/* Unread posts: a lighter green tint than unread topics get (brand-050,
   not brand-100) per request -- kept distinct on purpose now rather than
   sharing one value, so a glance down a topic still shows which posts
   haven't been read yet without it competing as strongly as the list view's
   own unread indicator does. */
.post.unreadpost { background: var(--brand-050); }

.postprofile { font-size: var(--fs-sm); color: var(--ink-500); }
.avatar-container { margin-bottom: var(--sp-2); }
.avatar, .avatar-container img { border-radius: var(--radius); max-width: 100%; }
/* Every post avatar the same 150x150 box, real or fallback -- users can set
   an avatar of pretty much any size/ratio phpBB's own admin config allows,
   which without this would make some posts' avatars visibly larger than
   others. object-fit: cover fills the box either way (scaling down a
   bigger image, up a smaller one) instead of leaving gaps or distorting
   the aspect ratio. */
.postprofile .avatar-container { width: 150px; height: 150px; }
.postprofile .avatar-container img, .postprofile .avatar-container .avatar { width: 100%; height: 100%; object-fit: cover; }
/* phpBB only outputs an <img> here when a user actually has an avatar set --
   there's no built-in fallback markup for viewtopic, unlike some of the
   other templates. dt gets a "no-avatar" class in exactly that case, so a
   background-image on the (otherwise empty) container reproduces the old
   theme's placeholder without needing a template change -- sized to match
   the 150x150 box above, rather than the smaller placeholder used
   elsewhere (e.g. the notification list), since this one has no img of its
   own for the width/height rule above to apply to. */
dt.no-avatar .avatar-container {
	border-radius: var(--radius);
	background: var(--surface-sunken) url("images/no_avatar.gif") center / 60% no-repeat;
}
/* .postprofile strong is used two ways: the label prefix inside a dd (e.g.
   "Waarschuwingen:") AND, in the rare case a user has no profile link at
   all, the username itself (dt wraps it in <strong> only then -- normally
   it's a plain link, not a <strong>). display: block on a shared rule for
   both meant every label rendered on its own line, pushing its value down
   to the line below instead of keeping "Label: value" together -- that's
   what wasn't "on one line". Reverted to plain inline text at the
   sidebar's own font-size so labels stay inline with their values. The
   username needs to stay visually prominent despite that, so it's sized
   separately via .postprofile dt (what actually wraps it either way, linked
   or not) rather than through this shared rule. */
.postprofile strong { display: inline; font-size: inherit; font-weight: 700; color: var(--ink-900); }
.postprofile dt { font-size: var(--fs-md); font-weight: 700; color: var(--ink-900); }
.profile-rank { color: var(--brand-600); font-weight: 700; font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.03em; }
.profile-posts, .profile-joined, .profile-warnings { display: block; margin-top: 0.15rem; }
dd.profile-warnings { color: var(--red); }
.profile-contact { margin-top: var(--sp-2); }
/* Postprofile sidebar only shows avatar, username, rank and custom profile
   fields per request -- post count, joined date and the contact-icons
   dropdown are hidden (rank and custom fields, and .profile-warnings,
   stay). */
.postprofile dd.profile-posts,
.postprofile dd.profile-joined,
.postprofile dd.profile-contact {
	display: none;
}

.postbody { min-width: 0; }
/* Per-post subject/title ("Re: ...") hidden -- it repeats the topic title
   already shown once at the top of the page, on every single reply.
   .postbody h3, not the direct-child ">" version this used to be: h3 is
   actually nested one level deeper, inside #post_content{ID}, not a direct
   child of .postbody itself -- the ">" combinator was too strict and
   silently never matched it, which is why h3.first (the first post in a
   topic, marked with its own extra class) was still showing. */
.postbody h3 { display: none; }
/* padding-right reserves room for .post-buttons below, which is pinned to
   the card's top-right corner rather than sitting inline here -- without
   it, a wide button row (several action icons, or a reactions extension's
   own markup appended after them) could sit on top of this text instead of
   next to it. flex-wrap still covers anything the reservation doesn't. */
.author { display: flex; align-items: center; gap: var(--sp-3); margin-bottom: var(--sp-3); flex-wrap: wrap; padding-right: 12rem; }

/* Pinned to the post card's own top-right corner (not just the postbody
   column) rather than sitting inline in .author, per request. Some boards
   run a reactions/quote-count extension that appends its own markup here
   too (e.g. a like count) -- .post ul below is a defensive reset so any
   such injected <ul> never shows browser-default bullets, regardless of
   its exact class name, which is what caused the stray "•" before every
   icon. Icon colour is forced green here specifically: the shared .button
   rule uses a neutral ink colour everywhere else on purpose (search, forum
   actions, etc.), but this toolbar should read as the old theme's did. */
.post-buttons {
	position: absolute;
	top: var(--sp-4);
	right: var(--sp-4);
	display: flex;
	align-items: center;
	gap: 0.3rem;
	list-style: none;
	margin: 0;
	padding: 0;
}
.post-buttons .button-icon-only { border-color: transparent; background: var(--surface-sunken); }
.post-buttons .icon, .post-buttons .button { color: var(--brand-600); }
.post ul { list-style: none; margin: 0; padding: 0; }

/* Reactions/likes extension (not part of stock phpBB -- its icon is drawn
   via its own CSS ::before, not the .icon system above, which is why the
   earlier fix didn't reach it). Same fix as the old theme's, updated to the
   new brand green; !important carried over deliberately since it's
   overriding the extension's own bundled stylesheet, not this one. */
.like:before, .liked:before, .like_info:before, .liked_info:before {
	color: var(--brand-600) !important;
}
/* Same reactions extension: a.postlove-button also picks up the shared
   .button rule's icon-to-text gap (0.5em, sized for a normal button label),
   which reads as too loose for this icon+count pairing. */
.postlove-button { gap: 1px; }
.like { margin-bottom: 0 !important; }

.content { color: var(--ink-900); font-size: var(--fs-base); overflow-wrap: anywhere; line-height: 1.2; }
.content h1, .content h2, .content h3 { font-size: var(--fs-md); }
.content p { margin: 0 0 var(--sp-3); }
/* Unicode emoji in post bodies render via phpBB core's own
   <img class="emoji smilies"> markup -- these two rules are prosilver's own
   (this style never imports prosilver's CSS), sizing the image relative to
   the surrounding text so it reads inline like a character instead of a
   full-size image. Without them every emoji rendered at its native pixel
   size, which is what made them look oversized. */
.emoji {
	min-height: 18px;
	min-width: 18px;
	height: 1em;
	width: 1em;
}
.smilies {
	vertical-align: text-bottom;
}
/* :not(:has(img)) -- a [url][img]...[/img][/url] post link still gets the
   "postlink" class from phpBB even though it's really an image, not text;
   the underline/colour treatment (meant for a text link) just distorts the
   image's own edge in that case, so skip it whenever the link's content is
   an image rather than text. */
.postlink:not(:has(img)) { color: var(--brand-600); border-bottom: 1px solid var(--brand-100); }
.postlink:not(:has(img)):hover { color: var(--brand-700); border-bottom-color: var(--brand-500); text-decoration: none; }

blockquote { background: var(--surface-alt); border-left: 3px solid var(--brand-500); border-radius: var(--radius-sm); padding: var(--sp-3) var(--sp-4); margin: 0 0 var(--sp-3); }
blockquote blockquote { background: var(--surface-sunken); }
blockquote cite { display: block; font-size: var(--fs-xs); font-weight: 700; color: var(--ink-500); margin-bottom: 0.3rem; }

.codebox { background: var(--brand-900); color: #eef2ec; border-radius: var(--radius-sm); padding: var(--sp-3); margin-bottom: var(--sp-3); }
.codebox p { color: rgba(255,255,255,0.6); border-bottom: 1px solid rgba(255,255,255,0.15); padding-bottom: 0.3rem; margin-bottom: 0.5rem; font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.04em; }
.codebox code { color: #8ee8a8; font-family: ui-monospace, "Cascadia Code", Consolas, monospace; font-size: 0.85em; }

.attachbox { background: var(--surface-alt); border: 1px solid var(--line); border-radius: var(--radius); padding: var(--sp-3); margin-bottom: var(--sp-3); }
.attachbox dd { border-top: 1px solid var(--line); padding-top: var(--sp-2); margin-top: var(--sp-2); }
.attach-image img { border-radius: var(--radius-sm); border: 1px solid var(--line); }

.signature { border-top: 1px solid var(--line); margin-top: var(--sp-4); padding-top: var(--sp-3); font-size: var(--fs-sm); color: var(--ink-500); }

.notice, .rules, .post-notice { border-radius: var(--radius-sm); padding: var(--sp-3); font-size: var(--fs-sm); }
.notice { border-top: 1px solid var(--line); background: transparent; color: var(--ink-500); }
.rules, .post-notice.reported, .post-notice.unapproved, .post-notice.deleted { background: var(--red-bg); color: var(--red); }
.error { color: var(--red); font-weight: 600; }
.reported { background: var(--red-bg); }

/* Per-post "back to top" link, hidden per request. */
.back2top { display: none; }

/* Polls */
fieldset.polls { margin-bottom: var(--sp-4); }
fieldset.polls dl { display: block; border-top: 1px solid var(--line); padding: var(--sp-3) 0; }
.poll-title { font-size: var(--fs-md); margin-bottom: var(--sp-2); }
.resultbar { height: 0.6rem; border-radius: 999px; background: var(--surface-sunken); overflow: hidden; display: inline-block; min-width: 8rem; vertical-align: middle; }
.pollbar1, .pollbar2, .pollbar3, .pollbar4, .pollbar5 { height: 100%; background: var(--brand-500); display: block; }
.poll_total_vote_cnt, .poll_vote { font-size: var(--fs-xs); color: var(--ink-500); }

/* --------------------------------------------------------------------------
   11. Panels, stat blocks, tables (UCP / MCP / memberlist share these)
   -------------------------------------------------------------------------- */
.stat-block { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: var(--sp-4); box-shadow: var(--shadow-sm); }
.stat-block h3 { font-size: var(--fs-sm); text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-500); margin-bottom: var(--sp-2); }
.stat-block p { font-size: var(--fs-sm); color: var(--ink-700); margin: 0; }

/* Same trap as the post/postprofile grid bug from a few rounds ago: this
   class is hardcoded onto #cp-main in ucp_header.html for every single UCP
   page ("Profile", "Preferences", "Forumvoorkeuren", ...), regardless of
   whether that specific page's content actually has a two-part sidebar+form
   structure to lay out -- most of them are just one plain settings form. A
   forced 14rem-first-column grid squeezed that lone form into the narrow
   column meant for a sidebar that isn't there, leaving the wide column
   empty. Defaulting to plain block layout fixes every page that doesn't
   need two columns; if a specific UCP page (e.g. Manage Groups) turns out
   to genuinely have a list+form split worth laying out side by side, that's
   a targeted follow-up once we know which one. */
.panel-container { display: block; }

/* UCP/MCP sidebar beside content, like the old theme's float: left / width:
   19% + 81% pair -- reimplemented with flex instead of floats, so it
   doesn't need the old rule's clearfix and negative-margin hacks. #cp-menu
   sits inside its own unclassed wrapper <div style="width:100%"> (also
   holding the "friends online" / colour-legend boxes beneath it), which is
   what actually needs to become the flex column -- #cp-menu itself is just
   sized to fill it. Values below are as tuned live in DevTools (a fixed
   max(14rem, 19%) column read worse in practice than letting the wrapper
   flex-grow alongside #cp-main); stacked below 900px, where a real
   side-by-side column would be too cramped to use. */
@media (min-width: 900px) {
	.panel .inner:has(#cp-menu) { display: flex; align-items: flex-start; gap: var(--sp-4); }
	.panel .inner > div:has(> #cp-menu) { display: flex; flex-grow: 1; }
	#cp-main.panel-container { flex: 1 1 auto; min-width: 0; }
}
/* Same missing-reset bug as .tabs earlier: .navigation's links were styled,
   but the several separate <ul> blocks the UCP/MCP sidebar wraps them in
   (one per section, split by <hr>) never had list-style reset -- so every
   entry showed a browser-default bullet and default list indentation on
   top of the intended pill styling below. */
.navigation ul { list-style: none; margin: 0 0 var(--sp-2); padding: 0; }
.navigation li { list-style: none; }
.navigation a { display: block; padding: 0.5rem 0.75rem; border-radius: var(--radius-sm); color: var(--ink-700); font-size: var(--fs-sm); background: transparent; }
.navigation a:hover { background: var(--brand-050); color: var(--brand-700); text-decoration: none; }
.navigation .active-subsection a { background: var(--brand-100); color: var(--brand-700); font-weight: 700; }

/* .tabs/.minitabs are the OUTER <div id="tabs" class="tabs">; the actual
   <li class="tab"> items live one level down in a plain <ul> the markup
   always wraps them in. Flexing/list-resetting .tabs itself only affected
   that div's single child (the <ul>), leaving the <ul>/<li> themselves as
   an unstyled, bulleted, vertically-stacked default list -- this is what
   showed as bullets instead of a tab row. */
.tabs, .minitabs { margin: 0 0 var(--sp-3); }
.tabs > ul, .minitabs > ul { display: flex; gap: 0.25rem; list-style: none; margin: 0; padding: 0; flex-wrap: wrap; }
.tabs li, .minitabs li { list-style: none; }
.tabs .tab > a, .minitabs .tab > a { display: block; padding: 0.5rem 0.9rem; border-radius: var(--radius-sm) var(--radius-sm) 0 0; background: var(--surface-sunken); color: var(--ink-700); font-size: var(--fs-sm); font-weight: 600; }
.tabs .activetab > a, .minitabs .activetab > a { background: var(--surface); color: var(--brand-700); box-shadow: var(--shadow-sm); }

table.table1 { border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
table.table1 thead th { background: var(--brand-900); color: #fff; padding: 0.6rem var(--sp-3); font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.03em; text-align: left; }
table.table1 tbody td, table.table1 tbody th { padding: 0.6rem var(--sp-3); border-top: 1px solid var(--line); font-size: var(--fs-sm); }
table.table1 tbody tr:hover { background: var(--brand-050); }
table.zebra-list tr:nth-child(odd) td, ul.zebra-list li:nth-child(odd) { background: var(--surface-alt); }

.ucprowbg, .fieldsbg { background: var(--surface-alt); border-radius: var(--radius); padding: var(--sp-3); }

/* Memberlist: rank has its own column (see memberlist_body.html override)
   instead of sharing the name column -- keep the small rank icon/text
   centred like the other stat columns instead of left-aligned block text. */
/* th.rank/td.rank, not table.memberlist th.rank: the memberlist template has
   TWO tables -- the "leaders" one (only rendered for a group with leaders
   set) carries class="table1 memberlist", but the regular members table
   (the common case) is only class="table1", so the memberlist-scoped
   selector silently missed it. .rank as a column class isn't used anywhere
   else in this stylesheet (memberlist_body.html and memberlist_team.html
   are the only two templates with a rank column), so scoping directly to it
   is safe -- text-align removed per request, leaving just the nowrap so
   rank text/icons don't wrap awkwardly. */
th.rank, td.rank { white-space: nowrap; }

/* Jumpbox */
/* The forum "jump to forum" dropdown itself, hidden per request; the
   return-to-forum/index link above it (.jumpbox-return) is untouched. */
#jumpbox { display: none; }
.jumpbox-cat-link { display: block; padding: 0.5rem 0.75rem; background: var(--brand-900); color: #fff; font-weight: 700; font-size: var(--fs-xs); text-transform: uppercase; }
.jumpbox-forum-link, .jumpbox-sub-link { display: block; padding: 0.5rem 0.75rem; background: var(--surface); color: var(--ink-700); font-size: var(--fs-sm); }
.jumpbox-forum-link:hover, .jumpbox-sub-link:hover { background: var(--brand-050); text-decoration: none; }

/* Search results */
.search-results li:hover, .search-results li.active { background: var(--brand-050); }

/* --------------------------------------------------------------------------
   12. Modals / alerts
   -------------------------------------------------------------------------- */
.darkenwrapper { position: fixed; inset: 0; z-index: 500; display: none; }
.darken { position: absolute; inset: 0; background: rgba(12, 20, 15, 0.55); }
.phpbb_alert {
	position: fixed; top: 20%; left: 50%; transform: translateX(-50%);
	z-index: 501; max-width: 26rem; width: 90%;
	background: var(--surface); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg);
	padding: var(--sp-5); display: none;
}
.alert_close { position: absolute; top: 0.75rem; right: 0.75rem; color: var(--ink-300); }
.alert_title { margin-bottom: var(--sp-2); }

/* --------------------------------------------------------------------------
   12b. Memberlist "view profile" page only (form#viewprofile)
   -------------------------------------------------------------------------- */
/* The profile-summary panel and the contact/stats panel are separate
   sibling .panel elements (both direct children of #viewprofile), just
   stacking by default -- put them side by side, with the profile-summary
   one (which holds the dl.left-box elements) on the left per request. The
   third, conditional panel (signature, only when SIGNATURE is set) stays
   full-width below rather than joining the row -- :has(.postbody) singles
   it out, since that's the one thing only it contains. */
#viewprofile { display: flex; flex-wrap: wrap; gap: var(--sp-4); align-items: flex-start; }
#viewprofile > .panel { flex: 1 1 320px; }
#viewprofile > .panel:has(.postbody) { flex-basis: 100%; }

/* dl.details: dt/dd were falling back to plain block stacking (each on its
   own line, value below its label) since nothing styled them outside of a
   <fieldset> context. A 2-column grid fixes this cleanly because dt/dd
   alternate 1:1 here -- implicit grid auto-placement puts each dt in
   column 1 and its dd in column 2, and automatically wraps to a new row
   every time the next dt appears, without needing to hunt down where one
   pair ends and the next begins. Deliberately NOT applied to
   .avatar-rank-container (a different, non-alternating dt + two dd shape
   that was clearly meant as a simple centered stack, not a label:value
   list -- its dd's already carry inline text-align: center). Its dd(s)
   (rank text/image) are hidden outright per request -- unconditionally,
   since the template only ever renders this whole dl in the first place
   when there IS an avatar (it's wrapped in <!-- IF AVATAR_IMG -->), so
   there's no "avatar vs. no avatar" case to distinguish here. */
#viewprofile .avatar-rank-container dd { display: none; }
#viewprofile dl.details {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	column-gap: var(--sp-3);
	row-gap: 0.3rem;
	margin: 0 0 var(--sp-3);
}
#viewprofile dl.details dt { font-weight: 700; color: var(--ink-700); }
#viewprofile dl.details dd { margin: 0; min-width: 0; }

/* Groups > "Groups I belong to" (ucp_groups_membership.html, marked with
   .ucp-groups-membership via a template override since it shares its
   "dd.mark" / bare <fieldset> markup with other UCP list pages that keep
   theirs): the per-row "select"/"set as default" radios and the bottom
   action fieldset (Change default / Join / Resign / Demote) are the only
   things in dd.mark and that fieldset, so both go entirely per request. */
.ucp-groups-membership dd.mark { display: none; }
.ucp-groups-membership .list-inner input[type="radio"] { display: none; }
.ucp-groups-membership > fieldset { display: none; }

/* Same table-like dt/dd layout, scoped to the whole UCP body instead of just
   the profile page -- covers "Your details" on the UCP overview
   (ucp_main_front.html) and the privacy/GDPR data page, both of which use
   the same plain "dl.details" markup with nothing else styling it. The
   shared "auto" grid column naturally sizes to the widest dt across every
   row, which is what gives every dt the same width instead of each pair
   sizing independently. */
#cp-main dl.details {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	column-gap: var(--sp-3);
	row-gap: 0.3rem;
	margin: 0 0 var(--sp-3);
}
#cp-main dl.details dt { font-weight: 700; color: var(--ink-700); }
#cp-main dl.details dd { margin: 0; min-width: 0; }

/* --------------------------------------------------------------------------
   13. Footer
   -------------------------------------------------------------------------- */
#page-footer, .page-footer { background: var(--brand-900); color: rgba(255,255,255,0.72); margin-top: var(--sp-7); padding: var(--sp-5) 0; }
.page-footer .inner { display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4); align-items: center; justify-content: space-between; }
.footer-row { margin: 0; font-size: var(--fs-xs); }
.footer-link { color: rgba(255,255,255,0.72); }
.footer-link:hover { color: #fff; }
.copyright { width: 100%; }
.navbar-footer { border-bottom: 1px solid rgba(255,255,255,0.12); margin-bottom: var(--sp-3); padding-bottom: var(--sp-3); }

/* --------------------------------------------------------------------------
   14. Responsive
   -------------------------------------------------------------------------- */
@media (max-width: 700px) {
	/* Dedicated mobile banner asset -- simplified from the full banner.svg so
	   it stays legible at phone width instead of just being the same wide
	   artwork scaled down further. Its own aspect-ratio (700:199, ~3.52:1)
	   is nowhere near the desktop banner's (2048:250, ~8.19:1), so it has to
	   be swapped here too -- leaving the desktop ratio in place would size
	   this image as if it were 2.3x wider than it actually is. */
	.headerbar { background-image: url("images/banner-mobile.svg"); aspect-ratio: 700 / 199; }

	/* Icon-only nav on mobile: keeps the row compact instead of wrapping or
	   forcing horizontal scroll once several items are showing at once.
	   Clipped the same way .sr-only is, not display: none -- the latter
	   would also drop the label from the accessibility tree, leaving the
	   link with no accessible name at all (its icon is aria-hidden). This
	   doesn't touch .badge (an unread count), which is a <strong>, not a
	   <span>, so it stays visible next to the icon either way.
	   ul.nav-main > li > a > span, not the plain-descendant ".navbar
	   .nav-main li a span" this used to be: that version had no depth
	   limit, so it was also clipping every <span> nested inside a
	   dropdown's OWN content -- quick-links' menu item labels, and the
	   notification list's username -- since those are still, structurally,
	   *some* span inside *some* a inside *some* li inside ul.nav-main, just
	   many levels deeper than the top-level trigger this was meant for.
	   Direct-child combinators scope it to exactly the trigger labels. */
	ul.nav-main > li > a > span {
		position: absolute !important;
		width: 1px; height: 1px;
		padding: 0; margin: -1px;
		overflow: hidden;
		clip: rect(0, 0, 0, 0);
		white-space: nowrap;
		border: 0;
	}

	/* Every search box and its buttons -- header breadcrumb search, viewtopic's
	   inline search, memberlist search, wherever .search-box appears. */
	.search-box { display: none; }

	/* Index page's "last visit" / current-time line. */
	.board-main > .time { display: none; }

	/* Every dd inside a row -- dt (icon + title) stays. Covers both regular
	   rows (topics/posts/views/last-post columns) and the header row's
	   column labels for them, which would be meaningless on their own once
	   the cells they label are gone. */
	ul.topiclist li dd { display: none; }
	dl.row-item { flex-wrap: wrap; }

	/* Post author sidebar: dt (avatar + username) stays, every dd (rank,
	   post count, joined date, warnings, contact, custom fields) hidden. */
	.postprofile dd { display: none; }

	/* 50px avatars on mobile vs. 150px on desktop -- the desktop size would
	   eat a big share of a phone-width postprofile column. */
	.postprofile .avatar-container { width: 50px; height: 50px; margin: 0; }
	/* Username next to the avatar instead of stacked below it, and at a
	   smaller size than the desktop 150px-avatar layout called for (fs-lg
	   read as oversized once the whole header got this much more compact) --
	   this is what actually made "the total header" tall to begin with.
	   padding-right reserves room for post-buttons (below), which -- like
	   .author on desktop -- floats free of normal flow and would otherwise
	   sit on top of a long username instead of beside it. */
	.postprofile { padding-right: 7rem; }
	.postprofile dt { display: flex; align-items: center; gap: var(--sp-2); font-size: var(--fs-base); }

	.topic_poll .inner, .post .inner { padding: var(--sp-4); }
	/* Same reasoning as the compacted avatar/username: this grid's gap (set
	   once, shared with the desktop 2-column layout) becomes vertical space
	   between the now-stacked postprofile and postbody rows once the grid
	   collapses to one column here -- tightened for a smaller header. */
	.post .inner:has(.postprofile) { gap: var(--sp-2); }
	/* Smaller/closer-to-the-corner buttons on mobile: with only 3-4 left
	   visible (below) there's no need for the desktop spacing, and every
	   bit of height saved here is height off "the total header". */
	.post-buttons { top: var(--sp-3); right: var(--sp-3); gap: 0.2rem; }
	.post-buttons .button-icon-only { width: 1.9rem; height: 1.9rem; }

	/* .author's "posted by <username> »" phrase, hidden -- the username is
	   already shown once, prominently, in the postprofile sidebar above; on
	   mobile that sidebar stacks directly above the post content (the
	   grid's single-column fallback), so repeating the name here read as
	   the same username appearing twice in a row. .time (the actual date)
	   is left showing -- it's the one part of this line that isn't a
	   duplicate. Same markup element is left untouched on desktop, where
	   the two are far enough apart on the page that this wasn't a problem. */
	.author .responsive-hide { display: none; }
	.author { padding-right: 0; }

	/* post-buttons: left un-repositioned here (still position: absolute
	   against .post .inner, the same mechanism as desktop) rather than
	   pinned to .postbody/.author as an earlier round tried -- now that
	   postprofile is the first thing in the mobile single-column stack,
	   pinning to the *card's* own top-right corner already lands it level
	   with the username row without needing a separate mechanism. Only
	   edit/quote/report and the reactions extension's own button stay
   	   visible per request; delete/warn/info hidden -- matched by their
	   icon class, since none of these buttons has a class of its own to
	   target directly. */
	.post-buttons li:has(.fa-times),
	.post-buttons li:has(.fa-exclamation-triangle),
	.post-buttons li:has(.fa-info) {
		display: none;
	}

	/* Pagination: "first ... current ... last" instead of "first ...
	   current-2 through current+2 ... last", which was wide enough to run
	   off the edge of a phone screen (page numbers cut off, per
	   screenshot). Can't change which page numbers phpBB itself generates
	   server-side, but the plain page-number <li>s (unlike .active/
	   .ellipsis/.arrow, which all carry a class) have no class at all --
	   that's what makes them selectable as a set here. The selector below
	   reads as "a classless li that has an earlier classless sibling AND
	   has a later classless sibling", i.e. a middle one; the first and last
	   classless numbers -- along with the existing ellipsis either side of
	   them, and .active for the current page -- are left alone. Prev/next
	   arrows (.arrow.previous/.arrow.next) already carry their own class,
	   so this doesn't touch them -- they stay for that navigation. */
	.pagination li:not([class]) ~ li:not([class]):has(~ li:not([class])) {
		display: none;
	}

	/* Quick-links and notifications dropdowns were anchoring against their
	   own small trigger element (right: 0, or the default left: auto /
	   right: auto) -- fine on desktop, but on a narrow viewport a wide
	   panel anchored near the edge of a small trigger can extend well past
	   the opposite edge of the screen. This is the exact same failure mode
	   the footer dropdown had several rounds ago, just from triggers near
	   the left/centre instead of the right. Rather than keep fighting
	   trigger-relative positioning case by case, this makes the containing
	   block .navbar itself (already position: sticky, which qualifies as
	   "positioned" for this purpose) instead of the trigger <li>: position:
	   static on the trigger removes it from being the containing block, so
	   the browser's search for "nearest positioned ancestor" continues up
	   to .navbar, whose own width spans virtually the full viewport
	   regardless of where within it a given trigger sits. !important on
	   left/right/width because .dropdown-container.dropdown-right .dropdown
	   (further up, for the header's own right-anchored dropdowns) sets
	   right/left with !important too -- without matching it here, that
	   rule would still win over this one despite equal-or-lower
	   specificity, since !important beats specificity, not the other way
	   around. Scoped to #page-header specifically so it doesn't touch the
	   footer's .navbar (same class, reused) -- that one already has its
	   own working fix and wasn't reported as broken. */
	#page-header .navbar .dropdown-container { position: static; }
	#page-header .navbar .dropdown {
		left: var(--sp-3) !important;
		right: var(--sp-3) !important;
		width: auto !important;
		max-width: none !important;
	}
}

/* The @media (max-width: 500px) block that used to live here (dropping
   aspect-ratio entirely below 500px) is gone -- it was written for the
   desktop banner's extreme 2048:250 ratio conflicting with the 3.5rem
   min-height floor at narrow widths, and turned out to be actively
   counterproductive for the mobile banner: removing the ratio meant the
   box fell back to min-height alone (56px), and background-size: contain
   in a box that short shrinks a 700:199 image down to keep it inside that
   height -- rendering it at well under 100% of the viewport width instead
   of filling it, which is what "not visible, too small" actually was.
   banner-mobile.svg's own ratio only needs 56px of height below ~197px of
   width, a size no real device hits, so the conflict this guarded against
   doesn't meaningfully exist for it -- keeping aspect-ratio locked at every
   width is what actually keeps the banner at full width. */

@media (max-width: 480px) {
	.inner { padding: 0 var(--sp-3); }
}

/* Old Edge / IE fallback safety (no CSS var support): keep layout usable */
@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
	.forabg, .forumbg, .panel, .post, .topic_poll { background: #ffffff; }
}
