/* ============================================================
   Sythe User Center — application shell

   Layout, typography and surfaces come from Web Awesome utility
   classes in the templates. What remains here is what the utility
   set has no equivalent for: the brand theme, the shell's three
   surface planes, the nav artwork, and a handful of fixed sizes.
   ============================================================ */

/* ---------- Brand palette, typography, scales ---------- */
:root {
	--wa-color-brand-05: #000f3a;
	--wa-color-brand-10: #001c48;
	--wa-color-brand-20: #083462;
	--wa-color-brand-30: #1d4777;
	--wa-color-brand-40: #315b8c;
	--wa-color-brand-50: #4d78ab;
	--wa-color-brand-60: #6d9acf;
	--wa-color-brand-70: #86b3ea;
	--wa-color-brand-80: #9ecdff;
	--wa-color-brand-90: #c9e8ff;
	--wa-color-brand-95: #dff4ff;

	--wa-font-family-body: "Space Grotesk", sans-serif;
	--wa-font-family-heading: "IBM Plex Sans Condensed", sans-serif;
	--wa-font-family-code: "Space Mono", monospace;
	--wa-font-family-longform: Podkova, serif;
	--wa-font-weight-body: 400;
	--wa-font-weight-heading: 500;
	--wa-font-weight-code: 400;
	--wa-font-weight-longform: 400;

	--wa-border-radius-scale: 1.33;
	--wa-border-width-scale: 1;
	--wa-space-scale: 1;
}

/* ---------- Shell planes ----------
   The theme maps surface-default to neutral-05 in dark mode, so nav and
   main both land on the same near-black and the layout reads as one void.
   These derive three distinct planes that work in either colour scheme. */
:root {
	--uc-nav-surface: color-mix(in oklab, var(--wa-color-surface-default), var(--wa-color-brand-50) 7%);
	--uc-main-surface: var(--wa-color-surface-lowered);
	--uc-panel-surface: color-mix(in oklab, var(--wa-color-surface-raised), var(--wa-color-brand-50) 4%);
	--uc-hairline: color-mix(in oklab, var(--wa-color-surface-border), transparent 30%);
	--uc-nav-width: 17rem;

	--uc-nav-image: url("https://img.sythe.org/background.jpg");
	--uc-nav-scrim: linear-gradient(rgb(0 0 0 / 90%), rgb(0 0 0 / 60%));
	/* Angled and lighter than the rail's scrim so the hero reads as its own
	   surface while still showing the same artwork. */
	--uc-hero-scrim: linear-gradient(105deg, rgb(0 0 0 / 92%) 40%, rgb(0 0 0 / 55%));
}

/* The main plane sits on the page itself rather than on .uc-main, which only
   grows to fit its content and would let the page background show through. */
html,
wa-page {
	background-color: var(--uc-main-surface);
}

/* ---------- Navigation rail ---------- */
.uc-nav {
	inline-size: var(--uc-nav-width);
	max-inline-size: var(--uc-nav-width);
	padding: var(--wa-space-l) var(--wa-space-m) var(--wa-space-xl);
	background-color: var(--uc-nav-surface);
	border-inline-end: var(--wa-border-width-s) solid var(--uc-hairline);
}

/* wa-page renders the navigation twice: a nav element on desktop and a
   wa-drawer on mobile, which slots the nav inside its own opaque panel. Both
   containers get the artwork, and `cover` keeps the crop consistent between
   a 17rem rail and a full-width drawer. */
.uc-nav,
wa-page::part(drawer__dialog) {
	background-image: var(--uc-nav-scrim), var(--uc-nav-image);
	background-repeat: no-repeat;
	background-position: center center;
	background-size: cover;
}

/* The drawer's body padding would otherwise frame the nav in bare panel. */
wa-page::part(drawer__body) {
	padding: 0;
}

/* In the drawer the panel behind it already carries the artwork; painting it
   on the nav as well would double the scrim at a second crop. */
wa-page[view="mobile"] .uc-nav {
	background-color: transparent;
	background-image: none;
}

.uc-logo {
	inline-size: 11rem;
	max-inline-size: 100%;
}

.uc-avatar {
	--size: 3.25rem;
	box-shadow: 0 0 0 var(--wa-border-width-m) var(--uc-hairline);
}

/* Lines the group label up with the nav buttons' own text inset. */
.uc-nav-label {
	padding-inline: var(--wa-form-control-padding-inline);
}

/* Nav items read as a list, so they align to the start and keep a tighter
   radius than a standalone button. */
.uc-nav wa-button::part(button) {
	justify-content: start;
	gap: var(--wa-space-s);
	border-radius: var(--wa-border-radius-m);
	color: var(--wa-color-text-normal);
}

/* No appearance gives a static quiet fill, and the rail marker is ours. */
.uc-nav wa-button[data-current]::part(button) {
	color: var(--wa-color-brand-on-quiet);
	background-color: var(--wa-color-brand-fill-quiet);
	box-shadow: inset 0.1875rem 0 0 0 var(--wa-color-brand-fill-loud);
}

/* ---------- Header ---------- */
.uc-header {
	padding-inline: var(--wa-space-l);
	background-color: color-mix(in oklab, var(--uc-nav-surface) 78%, transparent);
	-webkit-backdrop-filter: blur(14px) saturate(160%);
	backdrop-filter: blur(14px) saturate(160%);
	border-block-end: var(--wa-border-width-s) solid var(--uc-hairline);
}

/* ---------- Main content plane ---------- */
.uc-main {
	padding: var(--wa-space-xl) var(--wa-space-l) var(--wa-space-3xl);
}

/* Holds body copy to a readable measure, which no utility expresses. */
.uc-prose {
	max-inline-size: 60ch;
}

/* ---------- Panels ----------
   wa-card already supplies the padding, radius, border and shadow; only the
   brand-tinted surface and the softened hairline are ours. */
wa-card {
	background-color: var(--uc-panel-surface);
	border-color: var(--uc-hairline);
}

/* The header slot has padding of its own, so browser heading margins double it.
   A heading one level down is reached too: a header that pairs a heading with an
   icon slots the row rather than the heading itself. */
wa-card [slot="header"],
wa-card [slot="header"] :is(h1, h2, h3, h4) {
	margin: 0;
}

/* Cards in a grid stretch to the tallest, so let the body absorb the slack and
   keep the footer links on one line across the row. */
wa-card::part(body) {
	flex: 1 1 auto;
}

/* ---------- Hero ----------
   Carries the artwork rather than the panel tint, so its border would read as a
   stray outline against the image. */
.uc-hero {
	--spacing: var(--wa-space-2xl);

	background-image: var(--uc-hero-scrim), var(--uc-nav-image);
	background-repeat: no-repeat;
	background-position: center center;
	background-size: cover;
	border-color: transparent;
	box-shadow: var(--wa-shadow-m);
}

/* ---------- Profile header ----------
   The avatar sits beside the name rather than above it, and wraps under it on a
   narrow screen. */
.uc-profile {
	align-items: center;
}

.uc-profile-avatar {
	--size: 5.5rem;
	box-shadow: 0 0 0 var(--wa-border-width-m) var(--uc-hairline);
	flex: 0 0 auto;
}

/* Username images are drawn at a fixed height -- 40px in every one on file --
   and stand in for a heading, so they are held to that height and never scaled
   up past it, which would only blur the artwork.

   align-self is what keeps them in proportion. The stack around them is a flex
   column, whose default stretch sizes an item across the full width; that beats
   width: auto, so the image was pulled wide while max-height held its height. */
.uc-username-image {
	align-self: flex-start;
	display: block;
	height: auto;
	max-height: 2.5rem;
	max-width: 100%;
	width: auto;
}

/* Fits three cards across the content column and drops to two, then one. */
.uc-card-grid {
	--min-column-size: 20rem;
}

/* The icon in a tile's header corner labels the tile rather than competing with
   its heading, so it is quiet and sized to the heading beside it. */
.uc-tile-icon {
	color: var(--wa-color-text-quiet);
	font-size: var(--wa-font-size-l);
}

/* A perk the member has not reached. Greyed and dimmed rather than hidden: the
   point of showing it is that donating further would open it. Its footer says
   what that takes, and nothing inside is a link, so there is nothing to disable
   beyond the look. */
.uc-perk-locked {
	filter: grayscale(1);
	opacity: 0.55;
}

/* Perk descriptions are a sentence or two of varying length, so the footers
   would otherwise sit at different heights across a row. */
.uc-perk {
	display: flex;
	flex-direction: column;
	height: 100%;
}

/* Two attribute columns inside a card, which is far narrower than the page. */
.uc-spec-grid {
	--min-column-size: 7rem;
}

/* ---------- Chips, meters and leaderboard rows ----------
   Chip colours come from the variant class on the element, so wa-brand can swap
   for wa-success. */
.uc-stat-chip,
.uc-minirank-art {
	flex: 0 0 auto;
	color: var(--wa-color-on-quiet);
	background-color: var(--wa-color-fill-quiet);
}

/* Sized from the space scale so it tracks --wa-space-scale. */
.uc-stat-chip {
	inline-size: var(--wa-space-3xl);
	font-size: var(--wa-font-size-l);
}

/* MiniRank artwork is always a 32px sprite, so the slot is fixed in pixels
   rather than a scalable token — anything larger would upscale and blur it. */
.uc-minirank-art {
	inline-size: 32px;
	font-size: var(--wa-font-size-l);
}

.uc-minirank-art img {
	inline-size: 32px;
	block-size: 32px;
}

/* ---------- MiniRank directory ---------- */
.uc-minirank-grid {
	--min-column-size: 15rem;
	list-style: none;
	margin: 0;
	padding: 0;
}

.uc-minirank-tile {
	display: flex;
	align-items: center;
	gap: var(--wa-space-s);
	padding: var(--wa-space-s);
	border: var(--wa-border-width-s) solid var(--wa-color-surface-border);
	border-radius: var(--wa-border-radius-m);
}

/* The filter hides tiles with the attribute, which display: flex would beat. */
.uc-minirank-tile[hidden] {
	display: none;
}

/* Border only: held tiles come first, and a fill would turn the top of the
   list into a solid block. */
.uc-minirank-tile[data-held="1"] {
	border-color: var(--wa-color-success-border-loud);
}

/* min-inline-size lets a long name wrap rather than push the badge out. */
.uc-minirank-text {
	flex: 1 1 auto;
	min-inline-size: 0;
}

.uc-minirank-name {
	font-weight: var(--wa-font-weight-semibold);
	overflow-wrap: anywhere;
}

.uc-minirank-held {
	flex: 0 0 auto;
	align-self: flex-start;
}

.uc-minirank-search {
	flex: 1 1 16rem;
	max-inline-size: 24rem;
}

.uc-minirank-key {
	--min-column-size: 14rem;
	margin: 0;
}

.uc-minirank-key dd {
	margin: 0;
}

/* ---------- MiniRank manager ---------- */
.uc-mr-list {
	list-style: none;
	margin: 0;
	padding: 0;
}

.uc-mr-row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--wa-space-s);
	padding: var(--wa-space-2xs) var(--wa-space-s);
	background-color: var(--uc-panel-surface);
	border: var(--wa-border-width-s) solid var(--wa-color-surface-border);
	border-radius: var(--wa-border-radius-m);
	cursor: grab;
}

.uc-mr-row[data-dragging] {
	opacity: 0.4;
}

/* Still on the list but left off posts, so it reads as set aside. */
.uc-mr-row[data-skipped] .uc-minirank-art,
.uc-mr-row[data-skipped] .uc-minirank-name {
	opacity: 0.5;
}

.uc-mr-row[data-problem] {
	border-color: var(--wa-color-danger-border-loud);
}

.uc-mr-grip {
	flex: 0 0 auto;
	color: var(--wa-color-text-quiet);
}

/* Member uploads are not all the standard 130x40, so in a row the art is shown
   at its own size, held to that box, as the forum shows it. */
.uc-mr-row .uc-rank-art {
	flex: 0 0 auto;
	align-self: center;
}

.uc-mr-row .uc-rank-art img {
	inline-size: auto;
	block-size: auto;
	max-inline-size: 130px;
	max-block-size: 40px;
}

/* Lets the buttons drop under the name on a narrow screen. */
.uc-mr-controls {
	margin-inline-start: auto;
}

/* Kept in reach at the foot of a long list while there is something to save,
   and otherwise left at the end of the page rather than covering the lists. */
.uc-mr-savebar[data-dirty] {
	position: sticky;
	inset-block-end: var(--wa-space-m);
	z-index: 1;
	box-shadow: var(--wa-shadow-l);
}

/* ---------- User title ----------
   A title is a line of styled text with no box of its own, so the preview gives
   it one; a long unbroken title wraps rather than widening the card. */
.uc-title-preview {
	min-block-size: 2.5rem;
	padding: var(--wa-space-s) var(--wa-space-m);
	border: var(--wa-border-width-s) solid var(--wa-color-surface-border);
	border-radius: var(--wa-border-radius-m);
	overflow-wrap: anywhere;
}

.uc-title-source {
	display: block;
	font-size: var(--wa-font-size-xs);
	white-space: pre-wrap;
	overflow-wrap: anywhere;
}

/* ---------- Username images ----------
   Shown on the rank plate, at their own size up to the 200x40 the rules allow
   rather than the rank sprite's fixed 130x40. */
.uc-uimg-list {
	list-style: none;
	margin: 0;
	padding: 0;
}

.uc-uimg-row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--wa-space-m);
	padding: var(--wa-space-s);
	border: var(--wa-border-width-s) solid var(--wa-color-surface-border);
	border-radius: var(--wa-border-radius-m);
}

.uc-uimg-art {
	flex: 0 0 auto;
	align-self: center;
}

.uc-rank-art.uc-uimg-art img {
	inline-size: auto;
	block-size: auto;
	max-inline-size: 200px;
	max-block-size: 40px;
}

.uc-uimg-controls {
	margin-inline-start: auto;
}

/* The form shows and hides its parts with the attribute, which the layout
   utilities' display would beat. */
.uc-uimg-form [hidden] {
	display: none;
}

/* ---------- Custom rank ---------- */

.uc-crank-form [hidden],
#crank-pending [hidden] {
	display: none;
}

wa-card[hidden] {
	display: none;
}

/* Laid out as the plate is: left, gold pile, right, in one row at any width. */
.uc-crank-slots {
	display: grid;
	grid-template-columns: repeat(3, max-content);
	gap: var(--wa-space-m);
	align-items: start;
}

.uc-crank-slot {
	align-items: center;
	text-align: center;
}

/* Matches a small button's height, so the three slots line up underneath. */
.uc-crank-fixed {
	display: grid;
	place-items: center;
	min-block-size: var(--wa-form-control-height-s, 2rem);
}

/* Each icon sits on the rank's own dark plate, at its real 30px. */
.uc-crank-icon {
	display: grid;
	place-items: center;
	inline-size: 48px;
	block-size: 48px;
	background-color: #0d1c2a;
	border: 1px solid transparent;
	border-radius: var(--wa-border-radius-s);
}

.uc-crank-icon img {
	image-rendering: pixelated;
}

.uc-crank-icon-empty {
	border: 1px dashed var(--wa-color-neutral-border-loud);
}

.uc-crank-amount {
	max-inline-size: 16rem;
}

.uc-avatar-s {
	--size: var(--wa-space-2xl);
}

.uc-meter {
	--track-height: var(--wa-space-2xs);
}

/* Fixed width with tabular figures so names line up past rank 9. */
.uc-rank {
	flex: 0 0 auto;
	inline-size: var(--wa-space-m);
	font-variant-numeric: tabular-nums;
	text-align: center;
}

/* Leaderboard names are links, but a row of underlined accent text reads as a
   list of calls to action rather than a ranking, so the affordance waits for hover. */
.uc-member-link {
	color: inherit;
	text-decoration: none;
}

.uc-member-link:hover,
.uc-member-link:focus-visible {
	text-decoration: underline;
}

/* Uppercase micro-labels. Web Awesome has no letter-spacing utility, and
   uppercase at caption sizes needs the extra tracking to stay legible. */
.uc-eyebrow {
	letter-spacing: 0.08em;
}

/* ---------- FAQ ----------
   The jump links target these sections, so they have to clear the sticky
   header or the heading lands underneath it. */
.uc-faq-section {
	scroll-margin-block-start: var(--wa-space-xl);
}

/* Questions read as a list of equal rows, so each gets a divider and the
   summary carries the card's body weight rather than a heading's. */
.uc-faq:not(:last-of-type)::part(details) {
	border-block-end: var(--wa-border-width-s) solid var(--uc-hairline);
}

.uc-faq::part(summary) {
	font-weight: var(--wa-font-weight-semibold);
}

/* A list inside a layout utility loses its margins, but the markers still
   need their indent. */
.uc-faq-steps {
	margin: 0;
	padding-inline-start: var(--wa-space-l);
}

.uc-faq-steps li + li {
	margin-block-start: var(--wa-space-2xs);
}

/* ---------- Donations ----------
   Perk blurbs are a sentence or two, so the columns are wider than the
   MiniRank attribute grid and the hero still fits two across. */
.uc-perk-grid {
	--min-column-size: 15rem;
}

/* The hero CTA jumps here, so the card has to clear the sticky header. */
.uc-methods-section {
	scroll-margin-block-start: var(--wa-space-xl);
}

/* Same list-of-rows treatment as the FAQ questions. */
.uc-method:not(:last-of-type)::part(details) {
	border-block-end: var(--wa-border-width-s) solid var(--uc-hairline);
}

/* A category leads with artwork or, lacking any, its currency code. Both are
   drawn in the same fixed box so the names beside them hold one vertical line
   instead of stepping in and out down the list. */
.uc-method-code,
.uc-method-icon {
	flex: 0 0 auto;
	inline-size: var(--wa-space-2xl);
	block-size: var(--wa-space-2xl);
	border-radius: var(--wa-border-radius-s);
}

.uc-method-code {
	font-family: var(--wa-font-family-code);
	color: var(--wa-color-brand-on-quiet);
	background-color: var(--wa-color-brand-fill-quiet);
	line-height: var(--wa-space-2xl);
	text-align: center;
}

/* The artwork is third-party brand logos drawn against white -- Ethereum,
   Amazon and PayPal are all but black -- so this plate stays light in either
   colour scheme rather than inheriting the panel's surface, which would sink
   them. The ink is pinned for the same reason: the Font Awesome branch draws a
   glyph in currentColor on that same white. */
.uc-method-icon {
	padding: var(--wa-space-3xs);
	color: var(--wa-color-brand-05);
	background-color: #fff;
}

.uc-method-icon img {
	max-inline-size: 100%;
	max-block-size: 100%;
	object-fit: contain;
}

/* The panel is a good deal narrower than the page, so a cramped screen scrolls
   the table sideways rather than wrapping every figure onto two lines. */
.uc-fee-scroll {
	overflow-x: auto;
}

.uc-fee-table {
	inline-size: 100%;
	border-collapse: collapse;
}

.uc-fee-table :is(th, td) {
	padding: var(--wa-space-2xs) var(--wa-space-s);
	text-align: start;
}

/* The outer cells align to the panel's own edges rather than sitting inside a
   cell gutter the rest of the card doesn't have. */
.uc-fee-table :is(th, td):first-child {
	padding-inline-start: 0;
}

.uc-fee-table :is(th, td):last-child {
	padding-inline-end: 0;
	text-align: end;
}

.uc-fee-table thead th {
	font-size: var(--wa-font-size-2xs);
	color: var(--wa-color-text-quiet);
	letter-spacing: 0.08em;
	text-transform: uppercase;
	white-space: nowrap;
}

/* The provider cell is a row header for assistive tech, not a visual one, so
   it drops the bold a th carries by default. */
.uc-fee-table tbody th {
	font-weight: inherit;
}

/* Interior rules only: the card's own border closes the table off. */
.uc-fee-table tbody tr:not(:last-child) :is(th, td) {
	border-block-end: var(--wa-border-width-s) solid var(--uc-hairline);
}

/* Figures stack up for comparison down the column. */
.uc-fee-figure {
	font-variant-numeric: tabular-nums;
	white-space: nowrap;

	/* native.css tops every cell out. The provider cell sets the row's height --
	   its avatar is taller than a line of text -- so a figure left at the top
	   would sit above the name it belongs to. */
	vertical-align: middle;
}

/* A method whose terms are HTML in its own row rather than a template. Only the
   outer margins are ours: the browser gives the first and last element one, and
   the card's padding is already that gap. */
.uc-method-info > :first-child {
	margin-block-start: 0;
}

.uc-method-info > :last-child {
	margin-block-end: 0;
}

/* ---------- Perks ----------
   A level sets its artwork beside its perk list. The artwork column is sized to
   the rank sprites, which have a fixed natural width, and the perks take the
   rest; both fall to one column once the card is too narrow to hold them. */
.uc-level-body {
	display: flex;
	flex-wrap: wrap;
	gap: var(--wa-space-xl);
}

.uc-level-ranks {
	flex: 0 0 auto;
	inline-size: 14rem;
}

.uc-level-perks {
	flex: 1 1 20rem;
}

/* Rank sprites are drawn for the forum's light post background, so they get the
   same white plate as the payment artwork rather than sinking into a dark panel.
   The box shrinks to the image instead of filling the column. */
.uc-rank-art {
	align-self: start;
	padding: var(--wa-space-2xs);
	background-color: #0d1c2a;
	border-radius: var(--wa-border-radius-s);
}

/* Rank artwork is always a 130x40 sprite, so it is pinned there in pixels
   rather than a scalable token -- anything larger would upscale and blur it. */
.uc-rank-art img {
	display: block;
	inline-size: 130px;
	block-size: 40px;
}

/* Stands in for the legacy page's pie chart, at a size that sits inside the
   card header without crowding the level name. */
.uc-level-ring {
	--size: 3.75rem;
	--track-width: var(--wa-space-3xs);

	flex: 0 0 auto;
}

/* ---------- Mobile ---------- */
@media (max-width: 1152px) {
	.uc-nav {
		inline-size: auto;
		max-inline-size: none;
		border-inline-end: none;
	}

	.uc-main {
		padding-inline: var(--wa-space-m);
	}

	.uc-header {
		padding-inline: var(--wa-space-s);
	}
}

/* ---------- Staff tools ---------- */

.uc-staff-tool [hidden],
#donation-check [hidden] {
	display: none;
}

.uc-staff-field {
	flex: 1 1 10rem;
	max-width: 16rem;
}

/* ---------- Admin ---------- */

.uc-admin [hidden] {
	display: none;
}

.uc-admin-field {
	flex: 1 1 10rem;
	max-width: 16rem;
}

/* Filters on the left wrap among themselves, so the action on the right keeps its place. */
.uc-admin-toolbar {
	flex-wrap: nowrap;
}

.uc-admin-toolbar > form {
	flex: 1 1 auto;
	min-width: 0;
}

.uc-admin-wide {
	flex: 1 1 20rem;
	max-width: 32rem;
}

.uc-admin-form {
	max-width: 48rem;
}

.uc-admin-log {
	border-inline-start: var(--wa-border-width-m) solid var(--uc-hairline);
	padding-inline-start: var(--wa-space-m);
}

.uc-name-change-post {
	padding-block-end: var(--wa-space-l);
	border-block-end: var(--wa-border-width-s) solid var(--uc-hairline);
}

/* Posts are shown as text, so their own line breaks are the only layout they have. */
.uc-name-change-text {
	white-space: pre-line;
	overflow-wrap: anywhere;
}
