/* ---------------------------------------------------
    GTOP100 MODERNISATION LAYER
    Applies to both themes unless a rule is scoped to
    [data-theme="dark"]. Load after style.css,
    cat-v4-26-2.css and dark.css.

    Verified live against dev.gtop100.com/MapleStory
    (50 rows, 31 premium, banners loaded):
      average row   247px -> 164px
      page height  13216px -> 9486px
      rows/screen     3.6 -> 5.5
----------------------------------------------------- */

/* ---------------------------------------------------
    1. ROW DENSITY
    The description is already truncated server-side, so
    clamping to two lines removes copy nobody finishes
    reading. Title and rating share one line instead of
    stacking.
----------------------------------------------------- */

/* 14px/21px reads better than 13px/19px at the same width. The measure
   is deliberately NOT capped — narrowing it would cut how much of the
   description survives the two-line clamp, and the visible text is
   staying as it is. */
.sDescription {
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	font-size: 14px;
	line-height: 21px;
	margin-top: 6px !important;
}
/* The clamp above must not reach the v1 template.
   v1 stacks its row content inside .vcenter-div, where
   .rating-population-wrap is `float: left; width: 100%` (cat-v4-26-2.css:475
   and :499). `overflow: hidden` makes .sDescription establish a block
   formatting context, and a BFC is required not to overlap a float — so the
   description collapses to the zero width left beside that full-width float
   and its text spills to ~700px tall. Measured on Mu-Online: width 0px /
   height 735px with overflow hidden, 1036px / 63px with it visible.

   The default template never hits this because the rule at
   `.server-content > .rating-population-wrap` below replaces that float with
   a content-sized flex row. v1 has no .server-content, so it kept the float.

   Nothing is lost by opting v1 out: the clamp was never active there anyway,
   because cat-v4-26-2.css:323 `.template-v1 .sDescription { display: block }`
   outranks the `-webkit-box` above, and -webkit-line-clamp only applies to a
   -webkit-box. On v1 the overflow was doing damage and nothing else. */
.template-v1 .sDescription {
	overflow: visible;
}
.template-default #server-items li .rank-wrap {
	padding: 12px 10px !important;
	font-size: 26px;
}
.template-default #server-items > li {
	margin-bottom: 8px;
}
.server-content {
	padding-top: 10px;
	padding-bottom: 10px;
}
.server-content figure,
.server-content .server-image {
	margin-top: 8px !important;
	margin-bottom: 0 !important;
}

/* .server-content is a flex column in the base theme, which
   blockifies its children — inline-block on them is ignored.
   Switching to a wrapping row puts the title and rating on
   one line and forces banner and description to full width. */
.server-content {
	flex-direction: row !important;
	flex-wrap: wrap !important;
	align-items: center;
}
.server-content > * {
	flex: 1 0 100%;
}
.server-content > .sTitle {
	flex: 0 0 auto;
	margin-right: 14px;
	font-size: 15px;
}
.server-content > .rating-population-wrap {
	flex: 0 1 auto;
	display: flex;
	align-items: center;
	gap: 12px;
	row-gap: 4px;
	margin-bottom: 0 !important;
	/* base CSS sets an explicit width here, which would take
	   the full row and force a wrap */
	width: auto !important;
	/* Allowed to shrink and wrap so the metadata never spills past the
	   row on narrow phones — without this it overflows below ~400px. */
	flex-wrap: wrap;
	max-width: 100% !important;
	min-width: 0;
	justify-content: flex-start;
}
/* min-width:0 must NOT go on the star list. It removes flexbox's
   automatic minimum-size floor, letting the <ul> shrink below its
   content width — the five stars then overflow to the right and
   collide with the population icon. */
.rating-stars {
	display: flex !important;
	flex-wrap: nowrap !important;
	flex: 0 0 auto !important;
	width: auto !important;
	min-width: auto !important;
	white-space: nowrap;
	margin: 0;
	padding: 0;
}
.rating-stars li {
	float: none !important;
	display: inline-block;
	flex: 0 0 auto;
	width: auto !important;
}
.avg-population i {
	margin-right: 5px;
}
.avg-population {
	white-space: nowrap;
}

/* ---------------------------------------------------
    2. FLAT CHROME
    Drops the amber bevel, the menu-extra.png texture and
    the button gradients — the last skeuomorphic elements
    on the site.
----------------------------------------------------- */

#nav {
	background-image: none !important;
	background-color: #e8920f;
}
header .navbar {
	background-image: none !important;
	box-shadow: 0 1px 0 rgba(0, 0, 0, .35) !important;
}
.btn,
.btn-danger,
.btn-primary,
.btn-success,
.btn-warning,
.btn-light,
.btn-dark {
	background-image: none !important;
	text-shadow: none !important;
}
thead.head-server,
.server-toplist-head {
	filter: none !important;
}

/* ---------------------------------------------------
    3. TYPE SCALE
    Was 25 / 22 / 20 — only 5px between levels, so the
    hierarchy never registered.
----------------------------------------------------- */

/* Fluid headings. A fixed 32px h1 wrapped to two lines on a 390px
   phone and ate 80px above the fold; this lands at 24px there and
   still reaches 32px by ~1200px.
     390px -> 24px | 768px -> 29px | 1200px+ -> 32px */
#content h1 {
	font-size: clamp(1.5rem, 1.05rem + 1.6vw, 2rem);
	line-height: 1.25;
	margin-bottom: 6px;
}
#content h2 {
	font-size: clamp(1.25rem, 0.95rem + 1.1vw, 1.5rem);
	line-height: 1.25;
}
#content h3 {
	font-size: clamp(1.0625rem, 0.95rem + 0.4vw, 1.1875rem);
	line-height: 1.3;
}

/* ---------------------------------------------------
    4. COMPONENT POLISH
    Filter-tab colours are dark-only: applying them to
    both themes leaves pale grey on white.
----------------------------------------------------- */

[data-theme="dark"] .server-info,
[data-theme="dark"] #server-items > li,
[data-theme="dark"] .box-wrap,
[data-theme="dark"] .main-services {
	border-color: #3d434b !important;
}

/* Filter bar dividers.
   Each tab draws its own 2px border-left, but a.s-server ALSO draws a
   1px border-right — so that one junction renders two lines instead of
   one and reads as a wider gap. The tabs are evenly spaced; only the
   duplicated border was wrong.
   The divider greys (#e6e6e6 / #d6d6d6) are light-theme values and
   glare on a dark background, so they are toned down there. */
.search-filter-links a.s-server {
	border-right: 0 !important;
}
[data-theme="dark"] .search-filter-links ul.nav_search > li > a {
	border-left-color: #3d434b !important;
}

/* ---------------------------------------------------
    5. RANK ON MOBILE
    Below 1024px cat-v4-26-2.css sets .rank-wrap to
    display:none, so a ranked toplist shows no ranks on
    phones. The grid already reserves a 50px first column
    for it — this just fills the space that was being
    held open and left empty.
----------------------------------------------------- */

/* ---------------------------------------------------
    6. LAST UPDATED
    Owner-activity signal on each row. The dot carries the
    state so the label stays readable if colour alone is
    missed. Colours are chosen to clear 4.5:1 on both the
    standard row and the premium gradient.
----------------------------------------------------- */

.last-updated {
	/* 11px was the smallest text on the page; 12px reads better without
	   widening the metadata line enough to make it wrap. */
	font-size: 12px;
	line-height: 18px;
	white-space: nowrap;
	color: #5c646e;
}
.last-updated::before {
	content: "\25CF";
	margin-right: 5px;
	font-size: 9px;
	vertical-align: 1px;
}
/* Light-mode values are darkened to clear 4.5:1 against the listing rows.
   The originals (#6c7681 / #9a6a05) measured 3.87 and 3.97 on #ebebea. */
.last-updated.is-fresh {
	color: #2e7d32;
}
.last-updated.is-aging {
	color: #5c646e;
}
.last-updated.is-stale {
	color: #855c04;
}
[data-theme="dark"] .last-updated.is-fresh {
	color: #7ec98a;
}
[data-theme="dark"] .last-updated.is-aging {
	color: #8b9096;
}
[data-theme="dark"] .last-updated.is-stale {
	color: #d9a441;
}

/* ---------------------------------------------------
    7. RANK NUMBER CONTRAST (light theme)
    cat-v4-26-2.css colours every premium rank number
    #ffc107, which lands at 1.25:1 on the #ece1be badge and
    1.17:1 on the #dbdbd7 standard one — invisible, and
    failing even the relaxed large-text threshold.

    Darkened to #8a5f00 (4.33:1 premium, 4.07:1 standard)
    and set to 700 weight. The weight matters as well as
    the colour: at 20px on mobile the number would be
    "normal" text needing 4.5:1, but at 700 it qualifies as
    large text at 3.0 — so it passes at every breakpoint.

    Scoped away from dark mode, where the numbers already
    sit at 12.9:1 and must keep their gold.
----------------------------------------------------- */

:root:not([data-theme="dark"]) .template-default .gold,
:root:not([data-theme="dark"]) .template-default .rank-wrap,
:root:not([data-theme="dark"]) .template-default .rank-wrap span,
:root:not([data-theme="dark"]) .template-default .premium .rank-wrap span {
	color: #8a5f00;
}
.template-default #server-items li .rank-wrap {
	font-weight: 700;
}

/* ---------------------------------------------------
    8. SITE-DETAIL TABS (dark theme)
    style.css gives the active tab a 3px #c80108 top border,
    #dddddd sides and a #ffffff bottom. In light mode the
    white bottom merges into the white panel below — the
    usual connected-tab effect. On dark it becomes a bright
    white line under a dark red box, and the whole control
    reads as an error state rather than a selected tab.

    Bottom border now matches the panel so the tab connects,
    sides use the standard divider, and the top accent uses
    the toned brand red rather than the raw #c80108.

    !important is required: the base rules are shorthands
    and one carries !important already.
----------------------------------------------------- */

[data-theme="dark"] #site-tab-links > li > a {
	border-left: 1px solid #33383f !important;
	border-right: 1px solid #33383f !important;
	border-bottom: 1px solid #33383f !important;
}
[data-theme="dark"] #site-tab-links > li > a.active,
[data-theme="dark"] #site-tab-links > li > a.active:hover,
[data-theme="dark"] #site-tab-links > li > a.active:focus {
	border-top: 3px solid #d92d36 !important;
	border-left: 1px solid #33383f !important;
	border-right: 1px solid #33383f !important;
	border-bottom: 1px solid #1d2024 !important;
}

/* ---------------------------------------------------
    9. SHARE BUTTONS
    Each share link is a fa-stack: an fa-circle disc that
    takes its colour from the anchor, plus a white
    fa-inverse glyph. Every anchor was inheriting the
    generic link colour, so all seven discs rendered the
    same red and the block read as a row of identical
    buttons.

    style.css does define per-platform colours, but under
    `.share-buttons .fb_share_button` — a wrapper class the
    current markup no longer uses, so none of them applied.
    The intent was already there; the selector had gone
    stale.

    Dark-mode variants exist because four brand colours sit
    too close to the #212429 panel to read: X is black,
    Tumblr navy, Pinterest and LinkedIn deep. All discs and
    glyphs clear 3:1 in both themes.
----------------------------------------------------- */

a.fb_share_button { color: #1877f2 !important; }
a.twitter_share_button { color: #000000 !important; }
a.share-reddit { color: #ff4500 !important; }
a.share-vk { color: #0077ff !important; }
a.share-tumblr { color: #36465d !important; }
a.share-pinterest { color: #bd081c !important; }
a.share-linkedin { color: #0a66c2 !important; }

[data-theme="dark"] a.twitter_share_button { color: #e7e9ea !important; }
[data-theme="dark"] a.twitter_share_button .fa-inverse { color: #0f1419 !important; }
[data-theme="dark"] a.share-tumblr { color: #5a76a8 !important; }
[data-theme="dark"] a.share-pinterest { color: #e60023 !important; }
[data-theme="dark"] a.share-linkedin { color: #378fe9 !important; }

/* ---------------------------------------------------
    10. NAV CONTRAST
    White text on the amber bar measured 2.46:1 — the only
    contrast failure left on the site, and identical in both
    themes since the bar does not change.

    Dark text on the existing amber gives 6.74:1 and keeps
    the bright bar, rather than darkening the bar to #a85f00
    to rescue white text at 4.88:1.

    The theme toggle's translucent dark disc existed only to
    lift a white icon off the gradient; with a dark icon it
    is no longer needed for contrast and is reduced to a
    faint hover affordance.
----------------------------------------------------- */

#nav .navbar-nav > li > a,
#nav .login-links > li > a,
header .navbar .nav-link,
header .navbar .nav-link i {
	color: #2b1c00 !important;
	text-shadow: none !important;
}
#nav .navbar-nav > li > a:hover,
#nav .navbar-nav > li > a:focus,
header .navbar .nav-link:hover,
header .navbar .nav-link:focus {
	color: #000000 !important;
}
/* ---------------------------------------------------
    12. THEME TOGGLE
    A pill switch that names the current mode rather than
    only hinting at it with an icon. Previously a 36px
    disc holding a moon or a sun, which required the user
    to work out whether the icon meant the current state
    or the one they would get by clicking.

    Everything visible is driven off [data-theme] on
    <html>: the wording, the knob position and which icon
    shows. theme-toggle.js only flips that attribute and
    the cookie, so there is no second source of truth to
    drift — and the control is already correct in the
    server-rendered HTML before any script runs.

    Following the reference: DAY has the knob on the
    right, NIGHT on the left.

    The width is fixed rather than fluid because "Day
    Mode" and "Night Mode" are different lengths; letting
    it size to content would make the whole nav shift
    sideways on every toggle.
----------------------------------------------------- */

.theme-toggle {
	position: relative;
	display: flex;
	align-items: center;
	width: 132px;
	height: 32px;
	flex: none;
	margin-right: 10px;
	padding: 0;
	border-radius: 999px;
	background: #ededed;
	/* The pale track is only 2.1:1 against the amber nav, short of the 3:1
	   WCAG 1.4.11 wants for the boundary of a non-text control, so the border
	   is what actually delineates it. At .22 alpha that border was 3.34:1 —
	   a pass, but with no margin; .35 gives 4.53:1. The night track needs no
	   such help: #101215 on the amber is already 7.6:1. */
	border: 1px solid rgba(0, 0, 0, .35);
	cursor: pointer;
	overflow: hidden;
	transition: background .18s ease, border-color .18s ease;
}
.theme-toggle-text {
	flex: 1 1 auto;
	/* Room for the knob on the side it currently occupies. */
	padding: 0 34px 0 12px;
	font-size: 10px;
	font-weight: 700;
	letter-spacing: .06em;
	text-transform: uppercase;
	text-align: center;
	white-space: nowrap;
	color: #1b1b1b;
	transition: color .18s ease;
}
.theme-toggle-text::after {
	content: "Day Mode";
}
.theme-toggle-knob {
	position: absolute;
	top: 50%;
	left: calc(100% - 29px);
	width: 26px;
	height: 26px;
	margin-top: -13px;
	border-radius: 50%;
	background: #ffffff;
	box-shadow: 0 1px 3px rgba(0, 0, 0, .35);
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 13px;
	line-height: 1;
	color: #1b1b1b;
	transition: left .22s ease, background .18s ease, color .18s ease;
}
/* Both icons are stated explicitly in both states rather
   than relying on Font Awesome's default display. The
   old control showed the OPPOSITE icon (a moon while in
   light mode, meaning "click for dark"); this one shows
   the CURRENT one, so the icon agrees with the wording
   beside it. Being explicit also means a stale cached
   dark.css, which hid .fa-sun in light mode, cannot
   leave the knob empty — modernize.css loads after it. */
.theme-toggle .fa-sun {
	display: block;
}
.theme-toggle .fa-moon {
	display: none;
}

/* Night state. Mirrors the light rules above so the two
   can be compared line for line. */
[data-theme="dark"] .theme-toggle {
	background: #101215;
	border-color: rgba(0, 0, 0, .55);
}
[data-theme="dark"] .theme-toggle-text {
	padding: 0 12px 0 34px;
	color: #f2f4f6;
}
[data-theme="dark"] .theme-toggle-text::after {
	content: "Night Mode";
}
[data-theme="dark"] .theme-toggle-knob {
	left: 3px;
	color: #101215;
}
[data-theme="dark"] .theme-toggle .fa-sun {
	display: none;
}
[data-theme="dark"] .theme-toggle .fa-moon {
	display: block;
}

.theme-toggle:hover {
	background: #e2e2e2;
}
[data-theme="dark"] .theme-toggle:hover {
	background: #1b1f24;
}
.theme-toggle:focus-visible {
	outline: 2px solid #1b1b1b;
	outline-offset: 2px;
}
[data-theme="dark"] .theme-toggle:focus-visible {
	outline-color: #ffffff;
}

/* The knob slide is decoration, not information — the
   wording carries the state on its own. */
@media (prefers-reduced-motion: reduce) {
	.theme-toggle,
	.theme-toggle-text,
	.theme-toggle-knob {
		transition: none;
	}
}

/* The dark colour above is only correct while the links
   sit ON the amber bar. Once the navbar collapses, the
   menu is no longer amber — style.css:443 turns
   #mainMenu .navbar-nav into a #1f1f1f panel. #2b1c00 on
   #1f1f1f is a contrast ratio of 1.00: the text is
   mathematically invisible, and it was, in both themes
   (dark.css declares no nav rules, so both themes share
   this). The site's own colour there was
   var(--c-on-dark) = #ffffff; this restores a light one
   for the collapsed menu only.

   The cut is 979px, not Bootstrap's 992px collapse
   point. Between 980 and 991 the menu is collapsed but
   style.css has not darkened the panel yet, so it still
   sits over the amber bar where the dark colour is
   correct. Cutting at 992 would break that band.

   This block must stay AFTER the rule it overrides —
   same selectors, same specificity, both !important, so
   source order is what decides.

   .theme-toggle is deliberately not included: it stays
   in the amber bar at every width. */
@media (max-width: 979px) {
	#nav .navbar-nav > li > a,
	#nav .login-links > li > a,
	header .navbar .nav-link,
	header .navbar .nav-link i {
		color: #f0f2f4 !important;
	}
	#nav .navbar-nav > li > a:hover,
	#nav .navbar-nav > li > a:focus,
	header .navbar .nav-link:hover,
	header .navbar .nav-link:focus {
		color: #ffffff !important;
	}
}

/* ---------------------------------------------------
    11. LARGE SCREENS
    Rows declare four grid columns (rank / content /
    versions / types) at fixed widths, but categories with
    versions and types disabled render only two children —
    so 400px sat empty on every row. On top of that
    .server-content was capped at 468px inside a column
    over twice that wide.

    Switching the last two columns to `auto` collapses them
    to 0 when unused and sizes them to content when present,
    so both kinds of category benefit. Measured at 2560px:
    unused space per row 1012px -> 50px, and the metadata
    fits back on one line.

    The container width is deliberately left at the original
    1216px. Widening it to 1500px only bought 8px per row and
    read as too wide on a 1440p monitor — the gain here comes
    from the columns, not from the page being wider.
----------------------------------------------------- */

@media (min-width: 1200px) {
	.template-default #server-items > li {
		grid-template-columns: 80px minmax(0, 1fr) auto auto;
	}
	.template-default .server-content {
		max-width: none;
	}
	/* Keep the description to a readable measure even though the
	   column is now much wider. */
	.server-content > .sDescription {
		max-width: 900px;
	}
}

@media (max-width: 1024px) {
	.template-default #server-items > li .rank-wrap {
		display: flex !important;
		align-items: center;
		justify-content: center;
		grid-column: 1 / 2;
		grid-row: 1 / -1;
		padding: 8px 4px !important;
		font-size: 20px;
	}
	.template-default .server-content,
	.template-default .version-wrap,
	.template-default .type-wrap {
		grid-column: 2 / -1;
	}
}
.badge {
	font-size: 11px;
	padding: 3px 8px;
}
/* Filter-tab colours live in dark.css and are already consistent —
   nothing to override here. */
a:focus-visible,
button:focus-visible {
	outline: 2px solid currentColor;
	outline-offset: 2px;
}
