 

/* ---------------------------------------------------------------- layout
 *
 * `!important` HERE, AND WHY IT IS NOT A LAZY ESCAPE HATCH.
 *
 * The frozen sheets carry, in this order:
 *
 *     form#your-profile { display: flex }                      <- an ID beats a class
 *     .btn { background-color: transparent !important; color: #222 !important }
 *     button[type="submit"] { display: block;
 *                             background: conic-gradient(...) !important;
 *                             background-color: initial !important }
 *
 * Measured on the page: the form computed to `display: flex` while its own
 * `grid-template-columns` still read `repeat(auto-fit, minmax(288px, 1fr))`. That is the
 * worst kind of wrong -- the specified value is visible in devtools and completely inert,
 * because flex ignores it. The five sections then laid out as a ROW, 622px wide, in
 * columns of 144, 88, 79, 77 and 90 pixels.
 *
 * So each rule below REPRODUCES THE WINNING SELECTOR and answers it with the same
 * importance. Raising specificity alone cannot beat `!important`, and beating an ID
 * without one needs `html body form#your-profile`, which is not a thing anyone should
 * have to write. This is 10.93: a computed style carrying three of your declarations and
 * not the fourth is ONE DECLARATION LOSING, and the fix is to match its weight, not to
 * out-shout it.
 */
.form-profile {
	--mcn-form-gap: 1.25rem;
	--mcn-form-col: 15rem;

	display: grid;
	grid-template-columns: repeat( auto-fit, minmax( var( --mcn-form-col ), 1fr ) );
	gap: var( --mcn-form-gap );
	align-items: start;
	margin: 0 0 var( --mcn-form-gap );

	/*
	 * A CAP, AND IT IS THE WHOLE POINT OF THE LAYOUT.
	 *
	 * Measured before this: an 890px form with fields 435px wide, and a bio box the width of
	 * the page. A form is not a table and its content does not want the full measure of a
	 * document -- an input you have to look across to find the end of is an input you have to
	 * re-read to check you typed the right thing. The live site caps its fields at about
	 * 245px, and this is that, in a slightly larger unit.
	 *
	 * `auto-fit` rather than a fixed column count is what does the "when it fits" part: the
	 * grid asks how many 15rem tracks the capped width holds and makes exactly that many, so
	 * First/Last sit side by side on a desktop and stack on a phone without a breakpoint
	 * written for either. A fixed `repeat(2, 1fr)` would be two columns on a 360px phone.
	 */
	max-width: 62rem;
}

/* `.form-profile` is the grid; `.form-grid` is the grid INSIDE a section, so a section can be
   re-laid-out without touching the form's own grid. Two rules, because one grid doing both
   jobs means a section can never span differently from the form. */
.form-grid {
	display: grid;
	grid-template-columns: repeat( auto-fit, minmax( var( --mcn-form-col ), 1fr ) );
	gap: 1rem 1.25rem;
	align-items: start;
}

/* A textarea is not a one-line field and reads wrong in a narrow column beside three inputs. */
.form-row-wide {
	grid-column: 1 / -1;
}

/* Same selector, same importance, later in source than the frozen rule that wins it. */
form#your-profile {
	display: grid !important;
}

.form-profile > .form-note,
.form-profile > .form-row-submit,
.form-profile > form {
	grid-column: 1 / -1;
}

/* Each fieldset is one bordered block, and it spans the grid on its own row so a section reads
   as a section rather than as two columns of unrelated inputs. */
.form-profile fieldset {
	grid-column: 1 / -1;
	min-width: 0;
}

.form-profile legend {
	/*
	 * THE HEADING IS A RULE WITH A LABEL IN IT, WHICH IS WHAT THE LIVE SITE DOES.
	 *
	 * `Social networks` and `Password change` are centred between two hairlines on the live
	 * page, and the effect is worth having: it separates two long lists of fields without
	 * spending a panel border on it, and the panel itself can then stop being a box that
	 * competes with the inputs inside it.
	 *
	 * `flex` on the legend, with the two rules as pseudo-elements that flex to fill, is how a
	 * `<legend>` -- which is the only element a fieldset may legally contain as its first
	 * child, and which therefore cannot hold a wrapper div -- gets a row of its own. A
	 * floated `::before`/`::after` pair is the older trick; flex does not need the float
	 * cleared and survives a long label without the rules collapsing.
	 */
	align-items: center;
	color: #ffffff;
	display: flex;
	font-size: 0.9375rem;
	font-weight: 700;
	gap: 0.875rem;
	justify-content: center;
	padding: 0;
	text-align: center;
	width: 100%;
}

.form-profile legend::before,
.form-profile legend::after {
	background: #2e2e34;
	content: "";
	flex: 1 1 auto;
	height: 1px;
}

/* ---------------------------------------------------------------- fields */

.form-profile .form-row {
	display: flex;
	flex-direction: column;
	gap: 0.375rem;
	margin: 0;
	min-width: 0;
}

/*
 * A LABEL THAT CARRIES AN ICON.
 *
 * The label is a flex row so the glyph sits on the text's optical centre line rather than on
 * the text's baseline, and `gap` is the space between them. The theme's own `.nav .svg-icon +
 * span` rule is the same idea for menus; this is the form's version of it and it exists because
 * the label now contains a `<span class="form-label-text">` for exactly that reason.
 *
 * `align-items: center` rather than `baseline`: an 16px glyph beside a 13px label aligned on
 * the baseline sits visibly low, and centring is what puts the two marks on one line.
 *
 * The glyph is sized here rather than left to `.svg-icon`'s 1.125rem, because a form label is
 * smaller than a menu row and a 18px mark beside a 13px label is the wrong proportion.
 */
.form-profile label {
	align-items: center;
	color: #f2f2f4;
	display: flex;
	font-size: 0.8125rem;
	font-weight: 600;
	gap: 0.4375rem;
	letter-spacing: 0.01em;
	line-height: 1.4;
}

.form-profile label > svg.svg-icon {
	color: #8a8a94;
	flex-shrink: 0;
	height: 0.9375rem;
	width: 0.9375rem;
}

/* A label with no icon in it must not carry the flex row's gap, or its text sits a
   half-character in from where every other label starts. */
.form-profile .form-label {
	align-items: center;
	color: #f2f2f4;
	display: flex;
	font-size: 0.8125rem;
	font-weight: 600;
	gap: 0.4375rem;
	letter-spacing: 0.01em;
	line-height: 1.4;
}

.form-profile .form-label-text {
	min-width: 0;
}

.form-profile .form-hint {
	color: #8a8a94;
	font-size: 0.75rem;
	line-height: 1.4;
}

/* ---------------------------------------------------------------- inputs */

/*
 * `:not(.form-control-file)` ON THE FIRST SELECTOR, AND IT IS NOT COSMETIC.
 *
 * The file input carries `form-control` so it inherits the padding, border and font, and that
 * same class is what the width rule below keys on. `.form-profile .form-control` is TWO
 * classes and so outranks a bare `.form-control-file`, which measured at 903px wide and 14px
 * tall -- the off-screen trick doing nothing at all, and a native "Choose File" sitting visibly
 * next to the button meant to replace it.
 *
 * Excluding the one element is the precise fix. Raising `.form-control-file` to two classes
 * would TIE with this rule and then depend on which of the two is written later, which is the
 * same load-order coin-flip 10.93 is about -- and `:not()` states the exception where the
 * exception actually is.
 */
.form-profile .form-control:not(.form-control-file),
.form-profile input[type="text"],
.form-profile input[type="email"],
.form-profile input[type="url"],
.form-profile input[type="password"],
.form-profile select,
.form-profile textarea {
	background: #000000 !important;
	border: 1px solid #2e2e34 !important;
	border-radius: 6px;
	color: #ffffff;
	font: inherit;
	line-height: 1.5;
	max-width: none !important;
	min-height: 2.75rem;
	padding: 0.5rem 0.75rem;
	width: 100%;
}

/* A 1px edge is what makes a #000000 field visible on a #101010 panel: the two are one step
   apart and read as nothing at all without it. */
.form-profile .form-control:hover,
.form-profile input[type="text"]:hover,
.form-profile input[type="email"]:hover,
.form-profile input[type="url"]:hover,
.form-profile select:hover,
.form-profile textarea:hover {
	border-color: #3d3d46 !important;
}

.form-profile .form-control:focus,
.form-profile input[type="text"]:focus,
.form-profile input[type="email"]:focus,
.form-profile input[type="url"]:focus,
.form-profile select:focus,
.form-profile textarea:focus {
	border-color: #5a5a66 !important;
	outline: 2px solid #5a5a66;
	outline-offset: 1px;
}

/*
 * THE BIO IS A PROSE FIELD, NOT A ONE-LINE FIELD.
 *
 * 7rem showed about three lines, which is enough to look wrong on a blank profile
 * and far too little to write one in. 12rem is roughly eight lines: enough that the
 * member can see more of what they have written than they are typing, which is the
 * whole point of a field you write in prose.
 *
 * The `!important` is load-bearing rather than lazy. The theme sets
 * `.form-profile .form-control:not([type=checkbox]) { min-height: 44px }`, which
 * scores higher than a bare `textarea` selector, so without it the field measured
 * exactly 44px on the real page no matter what was written here.
 */
.form-profile textarea {
	min-height: 12rem !important;
	resize: vertical;
}

.form-profile input[type="file"] {
	color: #f2f2f4;
	min-height: 0;
	padding: 0.375rem 0;
}

.form-profile input[type="file"]::file-selector-button {
	background: #101010;
	border: 1px solid #2e2e34;
	border-radius: 6px;
	color: #ffffff;
	cursor: pointer;
	font: inherit;
	margin-right: 0.75rem;
	padding: 0.5rem 0.875rem;
}

.form-profile input[type="file"]::file-selector-button:hover {
	background: #161616;
	border-color: #3d3d46;
}

/* ---------------------------------------------------------------- field validation
 *
 * Status indicators for platform URL fields: checking (spinner), valid (checkmark),
 * invalid (cross). The indicator appears at the end of the field row.
 */
.form-row {
	position: relative;
}

.field-status {
	display: inline-flex;
	align-items: center;
	gap: 0.375rem;
	margin-left: 0.5rem;
	font-size: 0.75rem;
	line-height: 1;
	vertical-align: middle;
}

.field-status svg {
	flex-shrink: 0;
	width: 1rem;
	height: 1rem;
}

.field-status .spinner {
	animation: spin 1s linear infinite;
	color: #8a8a94;
}

.field-status .checkmark {
	color: #55ff00;
}

.field-status .cross {
	color: #d63b3b;
}

.field-status .status-text {
	color: #8a8a94;
	font-size: 0.75rem;
}

@keyframes spin {
	from { transform: rotate(0deg); }
	to { transform: rotate(360deg); }
}

/* Valid state: green border, keep checkmark visible */
.form-row.field-valid .form-control,
.form-row.field-valid input[type="url"],
.form-row.field-valid input[type="text"],
.form-row.field-valid input[type="email"] {
	border-color: #55ff00 !important;
}

.form-row.field-valid .field-status .checkmark {
	color: #55ff00;
}

/* Invalid state: red border */
.form-row.field-invalid .form-control,
.form-row.field-invalid input[type="url"],
.form-row.field-invalid input[type="text"],
.form-row.field-invalid input[type="email"] {
	border-color: #d63b3b !important;
}

.form-row.field-invalid .field-status .cross {
	color: #d63b3b;
}

/* Checking state: blue border with spinner */
.form-row.field-checking .form-control,
.form-row.field-checking input[type="url"],
.form-row.field-checking input[type="text"],
.form-row.field-checking input[type="email"] {
	border-color: #4a9eff !important;
}

/* Keep validation state visible after form save (until field is changed again) */
.form-row.field-valid.saved .field-status .checkmark,
.form-row.field-invalid.saved .field-status .cross {
	opacity: 1;
}

/* Social field row adjustments for status indicator */
.form-row-social {
	flex-wrap: wrap;
	align-items: flex-start;
}

.form-row-social .form-control {
	flex: 1;
	min-width: 0;
}

.form-row-social .field-status {
	margin-top: 0.25rem;
}

/* ---------------------------------------------------------------- sections */

/* `.form-profile` is the two-column grid; `.form-grid` is the grid INSIDE a section, so a
   section can be re-laid-out without touching the form's own grid. Two rules, because one
   grid doing both jobs means a section can never span differently from the form. */
.form-grid {
	display: grid;
	grid-template-columns: repeat( auto-fit, minmax( 15rem, 1fr ) );
	gap: 1rem 1.25rem;
	align-items: start;
}

/* A textarea is not a one-line field and reads wrong in a narrow column beside three inputs. */

.form-profile fieldset {
	background: #101010;
	border: 1px solid #2e2e34;
	border-radius: 8px;
	margin: 0;
	padding: 1.125rem 1.25rem 1.25rem;
}

.form-profile legend {
	color: #ffffff;
	font-size: 0.9375rem;
	font-weight: 700;
	padding: 0 0.5rem;
}

/* The social networks are many one-line fields, so they are their own tight grid rather than
   inheriting the two-column layout, where fifteen items would leave a ragged last row. */
.profile-form-social-networks {
	display: grid;
	grid-template-columns: repeat( auto-fit, minmax( 13rem, 1fr ) );
	gap: 0.75rem 1rem;
}

.profile-form-social-networks legend {
	grid-column: 1 / -1;
}

.profile-form-social-networks .form-row-social {
	margin: 0;
}

/* ---------------------------------------------------------------- danger
 *
 * RED, AND ONLY RED, ON THE DELETE CONTROLS.
 *
 * A destructive action is the one control on this page whose consequence cannot be
 * undone by the person who clicks it, and colour is the cheapest signal a visitor
 * actually reads. A confirmation dialog is required as well and is still there --
 * colour is not a substitute for a second deliberate step, it is the thing that
 * makes the second step findable.
 *
 * The red is a real one rather than `red`, because `red` is #ff0000: at full
 * saturation on a black page it blooms, and the label loses its edges. #d63b3b is
 * dark enough to sit on #000000 without glare and light enough to read as danger.
 * The hover is one step brighter for the same reason the rest of the palette has
 * a hover row: the state has to be visible on a black surface.
 *
 * `.btn-delete` is on ALL THREE delete controls -- the one that reveals the
 * confirmation and the two that submit it -- because a control that changes colour
 * once you have already opened the dialog is a control whose colour is a progress
 * indicator rather than a warning.
 */

.btn-delete {
	background: #d63b3b !important;
	border: 1px solid #e05555 !important;
	border-radius: 6px;
	color: #ffffff !important;
}

/*
 * `.btn.btn-delete`, NOT `.btn-delete`.
 *
 * The frozen sheet has `.btn { background-color: transparent !important; color: #222 !important }`.
 * Both rules are `!important`, both are one class, so the winner is whichever comes LAST in
 * source order -- and the frozen one does. Measured, the button came out
 * `rgba(0,0,0,0)` with `rgb(34,34,34)` text: a transparent button with near-black writing
 * on a black page, which is invisible and which no amount of re-reading MY stylesheet would
 * have explained. Two classes beat one, and the tie stops depending on load order.
 *
 * Both longhands are set as well as the shorthand, because the frozen sheet sets
 * `background-color` on its own and a shorthand here would leave the longhand to be won
 * separately by whichever rule reaches it last.
 */
.btn.btn-delete {
	background: #d63b3b !important;
	background-color: #d63b3b !important;
	border: 1px solid #e05555 !important;
	color: #ffffff !important;
}

.btn-delete:hover,
.btn-delete:focus-visible {
	background: #e05555 !important;
	border-color: #f06a6a !important;
}

.btn-delete:focus-visible {
	outline: 2px solid #f06a6a;
	outline-offset: 2px;
}

/* ---------------------------------------------------------------- icons in buttons
 *
 * An icon is a flex item beside a label, so the two are aligned as a row with the
 * label allowed to take the remaining width. `align-items: center` is what puts the
 * glyph on the text's optical centre line -- without it a 18px icon next to a 16px
 * cap-height label sits visibly high, because the default stretch is to the line box.
 *
 * The gap is on the BUTTON rather than as a margin on the icon, so the space between
 * glyph and label is identical whichever side of the button the icon is on and
 * whichever set draws it. The theme's own rule is `.nav .svg-icon + span { margin }`,
 * which is why `menu_items()` puts the icon immediately before a `<span>`: the same
 * contract, followed here for the same reason.
 */

/*
 * `.form-profile .btn-with-icon`, NOT `.btn-with-icon`.
 *
 * `button[type="submit"] { display: block !important }` in the frozen sheet is one element
 * selector plus one attribute, which outranks one class -- so the Save button computed to
 * `display: block` while this rule's own `gap: 8px` was visibly in force. Two classes beat
 * an element-plus-attribute, and the icon then sits in a flex row beside its label instead
 * of on its own line.
 */
.form-profile .btn-with-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
	line-height: 1.2;
}

.form-profile .btn-with-icon > span {
	min-width: 0;
}

/* The 1.125rem default from the theme's .svg-icon rule is right for a menu row and
   slightly large inside a button, so the button states its own. */
.btn-with-icon > svg.svg-icon {
	width: 1rem;
	height: 1rem;
	flex-shrink: 0;
}

 

.form-row-wide > .mcn-notice {
	margin: 0;
}

/* A renderer that prints nothing must not leave a heading over an empty row, so the
   section is the thing that is worth keeping and the row is only a wrapper. */
.form-section-platform:has( .mcn-connect-buttons, .mcn-buttons ) .form-row-wide {
	min-width: 0;
}

/* ---------------------------------------------------------------- footer row
 *
 * SAVE ON ONE END, DELETE ON THE OTHER.
 *
 * The two used to sit about 40px apart, stacked, with the destructive one immediately under
 * the last field a member was editing. Distance is the cheapest safety a destructive control
 * can have, and it costs one flex row: Save sits left where it has always been, and the
 * delete control sits at the far end of the same line, so the two are a screen apart rather
 * than a click apart.
 *
 * It is a ROW and not two rows because the danger is specifically about being NEXT TO Save.
 * Stacking them one under the other on separate lines would put them back within a thumb's
 * reach of each other on a narrow screen, which is the case this is protecting.
 *
 * `flex-wrap` puts the delete control on its own line rather than letting the two overlap on
 * a phone, and the row keeps Save's own alignment instead of centring it.
 */

.form-profile-footer {
	align-items: center;
	border-top: 1px solid #2e2e34;
	display: flex;
	flex-wrap: wrap;
	gap: 1rem;
	justify-content: space-between;
	margin-top: 1.75rem;
	max-width: 62rem;
	padding-top: 1.25rem;
	width: 100%;
}

/*
 * `margin-left: auto`, BECAUSE THERE IS ONLY ONE CHILD IN HERE.
 *
 * `justify-content: space-between` on the footer puts its children at opposite ends -- and the
 * footer has exactly ONE child, the delete control, because the Save button lives inside the
 * profile form and cannot be moved here without nesting a form in a form. With one child,
 * space-between places it at the START and does nothing else, which is how the red button
 * ended up under the fields on the left where it started.
 *
 * `margin-left: auto` on the child is the way to push one item to the end of a flex row, and it
 * is not a hack around the layout: it is the same thing space-between would have done if there
 * were two children.
 */
.form-profile-footer > * {
	flex: 0 0 auto;
	margin-left: auto;
}

/* ---------------------------------------------------------------- upload */

.form-avatar {
	align-items: center;
	display: flex;
	gap: 1rem;
}

/*
 * THE CHARACTER PICKER IS NOT PART OF THE AVATAR COLUMN.
 *
 * It lived inside `.form-avatar-controls`, a 200px column beside the preview
 * thumbnail, so the grid had exactly one column and kept that at every screen width:
 * twelve faces stacked in a tall narrow strip. The picker is taken out of that
 * column and laid across the full width of the row instead.
 *
 * The row becomes a grid so the picker can have a full-width line of its own WITHOUT
 * being taken out of the flow. An absolutely positioned panel would be removed from
 * the flow and everything below it would close over the top of it while it is open.
 */
/*
 * THE AVATAR ROW SPANS THE WHOLE FORM.
 *
 * It sits in `.form-grid`, a two-column grid of 320px tracks, so as one cell it was
 * given half the form no matter how wide the page got. A picker of twelve faces
 * needs more than 320px to be anything but a stack, and the row it is in is about
 * one field, not a pair of them.
 */
.form-grid > .form-row-avatar { grid-column: 1 / -1; }

.form-row-avatar { display: grid !important; grid-template-columns: auto minmax(0, 1fr); align-items: start; column-gap: 1rem; }
.form-row-avatar > .form-label { grid-column: 1 / -1; }
.form-row-avatar > .form-avatar { grid-column: 1; grid-row: 2; }
.form-row-avatar > .form-avatar-controls { grid-column: 2; grid-row: 2; }
.form-row-avatar .preset-picker { grid-column: 1 / -1; grid-row: 3; width: 100%; }

@media (max-width: 600px) {
	.form-row-avatar { grid-template-columns: minmax(0, 1fr); }
	.form-row-avatar > .form-avatar,
	.form-row-avatar > .form-avatar-controls,
	.form-row-avatar .preset-picker { grid-column: 1; }
	.form-row-avatar > .form-avatar { grid-row: 2; margin-bottom: .75rem; }
	.form-row-avatar > .form-avatar-controls { grid-row: 3; }
	.form-row-avatar .preset-picker { grid-row: 4; }
}

.form-avatar-preview {
	background: #101010;
	border: 1px solid #2e2e34;
	border-radius: 50%;
	flex: 0 0 auto;
	height: 72px;
	overflow: hidden;
	width: 72px;
}

.form-avatar-preview img {
	display: block;
	height: 100%;
	object-fit: cover;
	width: 100%;
}

.form-avatar-controls {
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	min-width: 0;
}

/*
 * THE PRESET PICKER.
 *
 * The characters and backdrops are opt-in, not part of the form's shape: a member who
 * came here to upload a photograph should not have to scroll past twelve faces to reach
 * the upload, so the panel is closed until the button is pressed.
 */
.preset-picker { margin-top: 0.25rem; position: relative; width: 100%; }

.preset-toggle {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	padding: 0.45rem 0.8rem;
	border: 1px solid #ffffff2e;
	border-radius: 999px;
	background: #ffffff0a;
	color: inherit;
	font: inherit;
	font-size: 0.85rem;
	cursor: pointer;
}

.preset-toggle:hover { background: #ffffff14; }
.preset-toggle:focus-visible { outline: 2px solid #b58aff; outline-offset: 2px; }
.preset-toggle svg { width: 18px; height: 18px; flex: 0 0 18px; opacity: 0.85; }

.preset-panel {
	margin-top: 0.6rem;
	padding: 0.85rem;
	border: 1px solid #2e2e34;
	border-radius: 14px;
	background: #101010;
}

.preset-panel[hidden] { display: none; }

.preset-panel-note {
	margin: 0 0 0.7rem;
	font-size: 0.78rem;
	line-height: 1.4;
	color: #a1a1aa;
}

/*
 * THE GRID.
 *
 * `auto-fill` with a `minmax` floor rather than a fixed column count, so the picker
 * uses the whole width it is given and the number of columns follows the space
 * instead of being pinned to one number that is wrong at every other size.
 *
 * Every track is a fixed height and every child is clipped to it. The columns
 * previously had no height of their own, so a wide swatch in the second row was
 * free to paint over the label of the row above: the row boxes were only as tall as
 * their text, and the images were not part of that. A definite row height plus
 * `overflow: hidden` is what stops one row ever drawing into another.
 */
.preset-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(88px, 1fr));
	gap: 0.55rem;
	align-items: stretch;
}

.preset-grid-wide { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }

.preset-option {
	display: grid;
	grid-template-rows: 56px  auto;
	justify-items: center;
	align-content: start;
	gap: 0.4rem;
	height: 92px;
	overflow: hidden;
	padding: 0.45rem 0.3rem;
	border: 1px solid #ffffff1f;
	border-radius: 12px;
	background: #ffffff08;
	color: #d4d4d8;
	font: inherit;
	font-size: 0.72rem;
	line-height: 1.25;
	cursor: pointer;
	min-width: 0;
}

.preset-option-wide {
	grid-template-rows: 60px auto;
	height: 96px;
}

.preset-option:hover { background: #ffffff14; border-color: #ffffff33; }
.preset-option:focus-visible { outline: 2px solid #b58aff; outline-offset: 2px; }

.preset-option img {
	grid-row: 1;
	align-self: center;
	justify-self: center;
	display: block;
	width: 56px;
	height: 56px;
	max-width: 100%;
	border-radius: 50%;
	object-fit: cover;
}

.preset-option .preset-swatch {
	justify-self: stretch;
	align-self: stretch;
	width: 100%;
	height: 100%;
	border-radius: 8px;
	object-fit: cover;
}

/* "None" wears the same slot as a picture so the row does not change height. */
.preset-none-mark {
	grid-row: 1;
	align-self: center;
	justify-self: center;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 56px;
	height: 56px;
	border: 1px dashed #ffffff33;
	border-radius: 50%;
	color: #8b8b95;
}

.preset-none-mark svg { width: 24px; height: 24px; }

.preset-option.is-selected {
	border-color: #b58aff;
	background: #b58aff1f;
	color: #fff;
}

.preset-option.is-selected .preset-none-mark {
	border-style: solid;
	border-color: #b58aff;
	color: #d9c4ff;
}

.preset-option-name {
	grid-row: 2;
	align-self: start;
	max-width: 100%;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	text-align: center;
}

@media (max-width: 600px) {
	.preset-grid { grid-template-columns: repeat(auto-fill, minmax(76px, 1fr)); gap: 0.45rem; }
	.preset-grid-wide { grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); }
	.preset-option { font-size: 0.68rem; }
}

/* A very wide editor should not stretch three columns across a 1600px panel. */
@media (min-width: 1100px) {
	.preset-grid { grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); max-width: 720px; }
	.preset-grid-wide { grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); max-width: 1080px; }
}

@media (prefers-reduced-motion: no-preference) {
	.preset-panel { animation: presetPanelIn 140ms ease-out; }
	@keyframes presetPanelIn {
		from { opacity: 0; transform: translateY(-4px); }
		to { opacity: 1; transform: translateY(0); }
	}
}

/*
 * A BUTTON INSTEAD OF "Choose File No file chosen".
 *
 * The native control paints itself in the operating system's own colours at its own size, so
 * on this page it arrives as a light grey slab in a black form. The real `<input type="file">`
 * is still in the document -- it is what the form submits and what `save_avatar()` reads --
 * but it is not what the member sees.
 *
 * IT IS HIDDEN WITH `position: absolute` AND A 1px SIZE, NOT `display: none`, because a
 * display:none input is still focusable-by-label in most browsers but is skipped by some
 * assistive technology, and the label stops announcing it as a file field. Off-screen but
 * present keeps it in the accessibility tree and keeps the label working, which is the whole
 * reason the visible thing is a `<label for>` rather than a `<div>` with a click handler.
 */

/*
 * Two classes, because the frozen sheets carry `button, input { height: 2.5rem }` and that is
 * one element plus one element -- specificity 0-1-1, which a bare `.form-control-file` (0-1-0)
 * loses. Measured before this: the input came out 903px wide and 14px tall. The width was fixed
 * by the `:not()` above; the height needs its own two classes.
 *
 * BUT THE HEIGHT IS NOT 1PX AND NO STYLESHEET CAN MAKE IT SO.
 *
 * Measured: an inline `height: 1px !important` on the element still measures 14px. A file input
 * has an INTRINSIC minimum height in this engine, set by the button it draws inside itself, and
 * it is not a cascade question -- there is no declaration left to out-rank. So `clip-path` is
 * what actually hides it, and `overflow: hidden` alone would leave a 2x14 box that a later
 * stylesheet could make visible again by restoring opacity.
 *
 * NOT `display: none`, deliberately. A display:none input is removed from the accessibility tree
 * in several browsers, which leaves the visible label pointing at something that is no longer
 * announced as a file field. This keeps it focusable, keeps the label working, and keeps the
 * name and the accept list on the element the form actually submits.
 */
.form-profile .form-control-file {
	clip-path: inset(50%);
	height: 1px;
	opacity: 0;
	overflow: hidden;
	padding: 0;
	position: absolute;
	white-space: nowrap;
	width: 1px;
}

.btn-upload {
	align-items: center;
	background: #000000;
	border: 1px solid #2e2e34;
	border-radius: 6px;
	color: #ffffff;
	cursor: pointer;
	display: inline-flex;
	font: inherit;
	font-weight: 600;
	gap: 0.5rem;
	justify-content: center;
	min-height: 2.5rem;
	padding: 0.4rem 1rem;
	width: fit-content;
}

.btn-upload:hover {
	background: #161616;
	border-color: #3d3d46;
}

.btn-upload:focus-within {
	outline: 2px solid #5a5a66;
	outline-offset: 2px;
}

.btn-upload > svg.svg-icon {
	width: 1rem;
	height: 1rem;
	flex-shrink: 0;
}

/* ---------------------------------------------------------------- surfaces
 *
 * #070707, NOT #101010, FOR THESE SECTIONS.
 *
 * The standing palette gives #101010 to panels and #000000 to the page. These three blocks
 * sit ON the page rather than floating above it -- they are regions of the document, not
 * overlays -- and at one step off the page they read as a panel; a quarter of the way they
 * read as a region of the page, which is what they are. #070707 is that quarter step, and the
 * 1px #2e2e34 edge is what separates it from #000000 at all: two near-blacks with no border
 * are one black.
 *
 * Stated here rather than inherited so the value is in one place for whoever changes it next.
 */
.form-profile fieldset {
	background: #070707;
	border: 1px solid #2e2e34;
}

 
.form-profile .success,
.success {
	color: #55ff00 !important;
	background: #000000 !important;
	border: 1px solid #1e1e1e !important;
	border-radius: 0.5em !important;
	padding: 1rem !important;
	display: grid !important;
}

/* ---------------------------------------------------------------- submit */

.form-profile .form-row-submit {
	display: flex;
	flex-direction: row;
	gap: 0.75rem;
	justify-content: flex-start !important;
	margin: 0;
}

/*
 * Save ON THE LEFT, DELETE ON THE RIGHT. Both are ends of the same column.
 *
 * With Save right-aligned it measured 37px from the delete button -- the two controls a member
 * must never press together were nearly touching, which defeats the whole point of moving the
 * delete button away. The live site puts Update bottom-left and Delete bottom-right, and that
 * separation is what makes the distance do any work.
 *
 * `flex-start` and the footer's `margin-left: auto` are the two halves of one arrangement, and
 * they are in different files because the delete control cannot be inside this form. That is
 * the price of the second form, and it is cheaper than a nested one.
 */

/*
 * `flex-direction: row`, SAID EXPLICITLY, AND IT IS MY OWN FAULT.
 *
 * `.form-row` is `flex-direction: column` so that a label sits above its input. The submit
 * row is a `.form-row` too, so it inherited `column` -- which turns `justify-content: flex-end`
 * from "to the right" into "to the bottom", and leaves `align-items` (default `normal`, which
 * is `stretch`) as the property that sets the button's WIDTH.
 *
 * Measured: `align-self: flex-start` collapsed the button from 854px to 176px, and
 * `max-width: fit-content` did the same. A cross-axis property changing the width is the
 * fingerprint of a container whose main axis is vertical; no `width` declaration was ever
 * involved, and `width: auto` was already winning.
 *
 * So the button was stretched, not sized. Stating the direction here is the whole fix, and it
 * is worth stating rather than assuming: a class shared by two layouts is one class too many.
 */

/*
 * `width: auto`, AND IT HAS TO BE SAID HERE.
 *
 * A frozen sheet carries `.form-profile .btn-primary { width: 100% }` -- the same selector,
 * in a file that loads later than this one. Measured, the Save button came out 854px wide
 * in an 890px form: a button labelled "Save profile" stretched across the whole page, with
 * its icon and label centred in the middle of it. `justify-content: flex-end` on the row
 * cannot help, because the item is not smaller than its container; a frozen
 * `.form-profile .form-row-submit { justify-content: stretch }` comes later still.
 *
 * `auto` rather than a number, so the button is exactly as wide as its icon and its label.
 */
.form-profile .btn-primary {
	width: auto !important;
}

.form-profile .btn-primary {
	background: #ffffff !important;
	background-color: #ffffff !important;
	border: 1px solid #ffffff !important;
	border-radius: 6px;
	color: #101010 !important;
	cursor: pointer;
	font: inherit;
	font-weight: 700;
	min-height: 2.75rem;
	padding: 0.5rem 1.75rem;
}

.form-profile .btn-primary:hover {
	background: #e6e6e6 !important;
	background-color: #e6e6e6 !important;
	border-color: #e6e6e6 !important;
	color: #000000 !important;
}

/*
 * WHITE, WITH BLACK TEXT. An inverted button.
 *
 * On a page that is entirely dark, every other control is a dark box with a light edge, so
 * the primary action looks like the rest of them. An inverted button is the one thing on the
 * page that reads as "this is the thing you press", and it costs nothing to implement
 * correctly because there is no colour to fight a dark-theme sheet over -- white is white.
 *
 * `!important` is here for the same reason as everywhere else in this file: the frozen sheets
 * carry `button[type="submit"] { background: conic-gradient(...) !important }`, and answering
 * an `!important` with a louder selector is 10.93's failure rather than its lesson.
 */
.form-profile .btn-primary:hover,
.form-profile .btn-primary:focus-visible {
	outline: 2px solid #ffffff;
	outline-offset: 2px;
}

/* ---------------------------------------------------------------- notices */

.form-profile .form-note {
	color: #f2f2f4;
	margin: 0;
}

/* ---------------------------------------------------------------- narrow */

@media ( max-width: 782px ) {
	.form-profile {
		grid-template-columns: 1fr;
	}

	/* A full-width button on a narrow screen is the right answer there, so this reverses the
	   `auto` above -- and it needs the same importance, because the frozen `width: 100%` it
	   is cancelling is itself `!important` and sits in a later file. */
	.form-profile .form-row-submit {
		justify-content: stretch !important;
	}

	.form-profile .btn-primary {
		width: 100% !important;
	}
}

@media ( prefers-reduced-motion: reduce ) {
	.form-profile * {
		transition: none !important;
	}
}

/* ---------------------------------------------------------------- profile nav / menu */

 
ul.menu-profile-menu-container {
	background: #101010 !important;
	border: 1px solid #2e2e34 !important;
	border-radius: 1rem !important;
	box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
	overflow: hidden; /* keeps border-radius on children */
}

/* The inner <ul> should not have its own background/border */
ul.menu-profile-menu-container > .nav {
	background: transparent !important;
	border: none !important;
	border-radius: 0 !important;
}

/* Menu items: the <li> elements */
ul.menu-profile-menu-container .menu-item {
	border-bottom: 1px solid #2e2e34;
}

ul.menu-profile-menu-container .menu-item:last-child {
	border-bottom: none;
}

/* Menu links: the <a> elements */
ul.menu-profile-menu-container .menu-item > a {
	display: flex;
	align-items: center;
	gap: 0.75rem;
	padding: 0.75rem 1rem;
	color: #f2f2f4 !important;
	text-decoration: none;
	transition: background 0.15s ease;
}

ul.menu-profile-menu-container .menu-item > a:hover,
ul.menu-profile-menu-container .menu-item > a:focus {
	background: #161616 !important;
	color: #ffffff !important;
}

/* The icon inside the link */
ul.menu-profile-menu-container .menu-item > a > .svg-icon {
	flex-shrink: 0;
	width: 1.25rem;
	height: 1.25rem;
	color: #8a8a94;
}

ul.menu-profile-menu-container .menu-item > a:hover > .svg-icon,
ul.menu-profile-menu-container .menu-item > a:focus > .svg-icon {
	color: #f2f2f4;
}

/* The span text */
ul.menu-profile-menu-container .menu-item > a > span {
	flex: 1;
	font-size: 0.875rem;
	font-weight: 500;
	line-height: 1.4;
}

/* Sub-menu (if any) */
ul.menu-profile-menu-container .sub-menu {
	background: #101010 !important;
	border: 1px solid #2e2e34 !important;
	border-radius: 0.5rem !important;
	box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

ul.menu-profile-menu-container .sub-menu .menu-item > a {
	padding-left: 1.5rem;
	font-size: 0.8125rem;
}

/* Active/current item */
ul.menu-profile-menu-container .current-menu-item > a,
ul.menu-profile-menu-container .current-menu-ancestor > a {
	background: #161616 !important;
	color: #ffffff !important;
}

ul.menu-profile-menu-container .current-menu-item > a > .svg-icon,
ul.menu-profile-menu-container .current-menu-ancestor > a > .svg-icon {
	color: #ffffff;
}

/* Ensure the container itself is positioned correctly for dropdown */
ul.menu-profile-menu-container {
	position: relative;
}

/* If this is a dropdown triggered by a button, ensure proper positioning */
ul.menu-profile-menu-container[hidden] {
	display: none !important;
}



 

 
.nav .sub-menu {
	position: absolute;
	top: 100%;
	left: -1rem;
	z-index: 10;
	display: none;
	min-width: 140px;
	margin: 0;
	padding: 0.25rem 0;
	list-style: none;
	background: var(--musiveo-background, #101010);
	border: 1px solid var(--musiveo-border, #2e2e34);
	border-radius: 4px;
	box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}

/* Show sub-menu on hover/focus of parent */
.nav .menu-item:hover > .sub-menu,
.nav .menu-item:focus-within > .sub-menu {
	display: block;
}

/* Sub-menu items */
.nav .sub-menu .menu-item {
	border: none;
}

.nav .sub-menu .menu-item > a {
	padding: 0.5rem 1rem;
	font-size: 0.8125rem;
}

.nav .sub-menu .menu-item > a:hover,
.nav .sub-menu .menu-item > a:focus {
	background: #161616 !important;
}

 
.user-edit-link {
	background: #101010 !important;
	border-radius: 0.75rem;
	padding: 0.75rem;
}

/* ---------------------------------------------------------------- user platforms in header
 *
 * Platform icons next to play button: filled icons for connected platforms
 * (YouTube, Twitch) + a more-button dropdown for other social networks.
 */
/*
 * THE PROFILE HEADER ROW IS A ROW, AND THE MARKS SIT IN IT SIDE BY SIDE.
 *
 * `.user-platforms` had `margin-left: auto`, which pushes it to the far end of whatever row
 * it is in -- correct in the edit form, where it is the only thing in a row of its own, and
 * wrong in the profile header, where it is the third thing after Play and Follow and ends up
 * pushed off to the edge instead of beside them. The rule is scoped to the header below.
 */
.header-user .entry-meta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.75rem;
}

.header-user .entry-meta /*
 * NOTHING BETWEEN A MARK AND THE PAGE MAY CLIP.
 *
 * The tooltip is drawn at `bottom: calc(100% + 0.5rem)` -- ABOVE its own link -- and the
 * arrow at `bottom: calc(100% + 0.25rem)`, so both hang outside the box they belong to.
 *
 * That is exactly what `overflow: hidden` on any ancestor destroys: the element is laid out
 * correctly, computed `opacity: 1`, computed `visibility: visible`, correct `z-index`, and
 * **not one pixel of it is painted** (AGENTS.md section 10.34). The rule is not wrong and the
 * pseudo-element is not missing; it is simply outside the clip.
 *
 * These three are the chain from the link up to the panel, and they are ours. The rule is
 * stated rather than assumed, because the alternative -- discovering which of them clips --
 * needs a computed style, and this site cannot be measured in a browser from here (10.165).
 */
.header-user .entry-meta,
.user-platforms,
.user-platforms-primary {
	overflow: visible;
}

.user-platforms {
	margin-left: 0;
	flex-wrap: wrap;
	gap: 0.5rem;
}
/*
 * NOTHING BETWEEN A MARK AND THE PAGE MAY CLIP.
 *
 * The tooltip is drawn at `bottom: calc(100% + 0.5rem)` -- ABOVE its own link -- and the
 * arrow at `bottom: calc(100% + 0.25rem)`, so both hang outside the box they belong to.
 *
 * That is exactly what `overflow: hidden` on any ancestor destroys: the element is laid out
 * correctly, computed `opacity: 1`, computed `visibility: visible`, correct `z-index`, and
 * **not one pixel of it is painted** (AGENTS.md section 10.34). The rule is not wrong and the
 * pseudo-element is not missing; it is simply outside the clip.
 *
 * These three are the chain from the link up to the panel, and they are ours. The rule is
 * stated rather than assumed, because the alternative -- discovering which of them clips --
 * needs a computed style, and this site cannot be measured in a browser from here (10.165).
 */
.header-user .entry-meta,
.user-platforms,
.user-platforms-primary {
	overflow: visible;
}

.user-platforms {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	margin-left: auto;
}

.user-platforms-primary {
	display: flex;
	align-items: center;
	gap: 0.5rem;
}

.user-platform-link {
	/*
	 * position: relative, OR THE TOOLTIP IS PLACED AGAINST SOMETHING ELSE.
	 *
	 * `::after` and `::before` here are the tooltip and its arrow, both `position: absolute`
	 * with `bottom: calc(100% + 0.5rem)`. With no positioned ancestor on the element they
	 * resolve against whatever further ancestor happens to be positioned -- on the profile
	 * header that is the header itself, so every tooltip in the row is drawn in the same
	 * place at the top of the page instead of above its own mark.
	 *
	 * `flex: 0 0 auto` so a mark cannot be squeezed narrower than its circle by a flex row
	 * that is trying to fit the Play button too, which is what "too small" is when the row
	 * has four marks in it.
	 */
	position: relative;
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 3rem;
	height: 3rem;
	border-radius: 50%;
	color: #f2f2f4;
	text-decoration: none;
	transition: color 0.15s ease, transform 0.15s ease;
}

.user-platform-link:hover,
.user-platform-link:focus {
	/*
	 * NO SURFACE ON HOVER EITHER.
	 *
	 * The mark has no background at rest, so painting one on hover is not a hover state --
	 * it is a different control appearing, and it is the exact "dark grey slab" the mark was
	 * asked to stop being. What changes is the COLOUR, which is what a hover on a glyph is
	 * for, plus a small scale so it reads as responsive without becoming a button.
	 */
	color: #ffffff;
	outline: none;
	transform: scale(1.15);
}

.user-platform-link > .svg-icon {
	width: 1.5rem;
	height: 1.5rem;
	flex-shrink: 0;
}





.user-platform-link {
	position: relative;
}

/* More button and dropdown */
.user-platforms-more {
	position: relative;
}

.user-platforms-toggle {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 3rem;
	height: 3rem;
	border-radius: 50%;
	background: #101010;
	border: 1px solid #2e2e34;
	color: #8a8a94;
	cursor: pointer;
	transition: color 0.15s ease, transform 0.15s ease;
}

.user-platforms-toggle:hover,
.user-platforms-toggle:focus {
	background: #161616;
	border-color: #3d3d46;
	color: #f2f2f4;
	outline: none;
	transform: scale(1.1);
}

.user-platforms-toggle > .svg-icon {
	width: 1.5rem;
	height: 1.5rem;
	flex-shrink: 0;
}

/* Tooltip for more button */
.user-platforms-toggle::after {
	content: attr(aria-label);
	position: absolute;
	bottom: calc(100% + 0.5rem);
	left: 50%;
	transform: translateX(-50%);
	padding: 0.375rem 0.75rem;
	background: #000000;
	border: 1px solid #2e2e34;
	border-radius: 0.375rem;
	font-size: 0.75rem;
	font-weight: 500;
	color: #f2f2f4;
	white-space: nowrap;
	opacity: 0;
	visibility: hidden;
	transition: opacity 0.15s ease, visibility 0.15s ease, transform 0.15s ease;
	z-index: 30;
	pointer-events: none;
}

.user-platforms-toggle:hover::after,
.user-platforms-toggle:focus::after {
	opacity: 1;
	visibility: visible;
}

.user-platforms-toggle::before {
	content: '';
	position: absolute;
	bottom: calc(100% + 0.25rem);
	left: 50%;
	transform: translateX(-50%);
	border: 0.375rem solid transparent;
	border-top-color: #000000;
	opacity: 0;
	visibility: hidden;
	transition: opacity 0.15s ease, visibility 0.15s ease;
	z-index: 30;
	pointer-events: none;
}

.user-platforms-toggle:hover::before,
.user-platforms-toggle:focus::before {
	opacity: 1;
	visibility: visible;
}

.user-platforms-toggle {
	position: relative;
}

.user-platforms-dropdown {
	position: absolute;
	top: 100%;
	right: 0;
	z-index: 20;
	margin-top: 0.375rem;
	min-width: 160px;
	background: #101010;
	border: 1px solid #2e2e34;
	border-radius: 0.5rem;
	box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
	overflow: hidden;
}

.user-platforms-dropdown[hidden] {
	display: none;
}

.user-platforms-dropdown:not([hidden]) {
	display: block;
}

.user-platforms-list {
	list-style: none;
	margin: 0;
	padding: 0.25rem 0;
}

.user-platforms-list li {
	margin: 0;
}

.user-platforms-list .user-platform-link {
	display: flex;
	align-items: center;
	gap: 0.75rem;
	width: auto;
	height: auto;
	padding: 0.5rem 1rem;
	border-radius: 0;
	border: none;
	border-bottom: 1px solid #2e2e34;
	background: transparent;
	color: #f2f2f4;
}

.user-platforms-list .user-platform-link:hover,
.user-platforms-list .user-platform-link:focus {
	background: #161616;
	border-color: transparent;
	color: #ffffff;
}

.user-platforms-list .user-platform-link > .svg-icon {
	width: 1.125rem;
	height: 1.125rem;
	color: #8a8a94;
	flex-shrink: 0;
}

.user-platforms-list .user-platform-link:hover > .svg-icon,
.user-platforms-list .user-platform-link:focus > .svg-icon {
	color: #f2f2f4;
}

.user-platforms-list .user-platform-link span {
	font-size: 0.8125rem;
	font-weight: 500;
	line-height: 1.4;
}

.user-platforms-list li:last-child .user-platform-link {
	border-bottom: none;
}

/* ---------------------------------------------------------------- delete account confirmation
 *
 * The confirmation dialog appears when the "Delete my account" button is clicked.
 * It uses the same dark grey panel styling as other floating elements.
 */
.delete-account-confirm {
	background: #101010;
	border: 1px solid #2e2e34;
	border-radius: 0.75rem;
	padding: 1.5rem;
	margin-top: 1rem;
	box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
}

.delete-account-confirm[hidden] {
	display: none;
}

.delete-account-confirm:not([hidden]) {
	display: block;
	animation: fadeIn 0.15s ease;
}

@keyframes fadeIn {
	from { opacity: 0; transform: translateY(-0.5rem); }
	to { opacity: 1; transform: translateY(0); }
}

.delete-account-confirm .notice {
	background: #070707;
	border: 1px solid #2e2e34;
	border-radius: 0.5rem;
	padding: 1rem;
	margin: 0 0 1.5rem;
	color: #f2f2f4;
	font-size: 0.875rem;
	line-height: 1.5;
}

.delete-account-form {
	display: flex;
	flex-direction: column;
	gap: 1rem;
}

.delete-account-form .form-row {
	margin: 0;
}

.delete-account-form .form-control {
	background: #000000 !important;
	border: 1px solid #2e2e34 !important;
	border-radius: 6px;
	color: #ffffff;
	padding: 0.5rem 0.75rem;
	min-height: 2.75rem;
	width: 100%;
}

.delete-account-form .form-control:focus {
	border-color: #5a5a66 !important;
	outline: 2px solid #5a5a66;
	outline-offset: 1px;
}

.delete-account-form .form-row-submit {
	display: flex;
	gap: 0.75rem;
	flex-wrap: wrap;
	margin-top: 0.5rem;
}

.delete-account-form .btn {
	flex: 0 0 auto;
}

/* ---------------------------------------------------------------- delete account modal
 *
 * A proper modal dialog for account deletion, centered on screen,
 * responsive, with backdrop, focus trap, and Escape to close.
 */
 
.delete-account-modal {
	position: fixed !important;
	inset: 0 !important;
	top: 0 !important;
	left: 0 !important;
	right: 0 !important;
	bottom: 0 !important;
	width: 100%;
	height: 100%;
	margin: 0;
	padding: 1rem;
	z-index: 2147483000;   /* above every z-index the theme and the player use */

	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 1000;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 1rem;
}

.delete-account-modal[hidden] {
	display: none;
}

.delete-account-modal:not([hidden]) {
	display: flex;
	animation: fadeIn 0.15s ease;
}

@keyframes fadeIn {
	from { opacity: 0; }
	to { opacity: 1; }
}

.delete-account-modal-backdrop {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	background: rgba(0, 0, 0, 0.7);
	animation: fadeIn 0.15s ease;
}

.delete-account-modal-panel {
	position: relative;
	background: #101010;
	border: 1px solid #2e2e34;
	border-radius: 0.75rem;
	box-shadow: 0 24px 48px rgba(0, 0, 0, 0.5);
	width: 100%;
	max-width: 28rem;
	max-height: 90vh;
	overflow: hidden;
	display: flex;
	flex-direction: column;
	animation: slideUp 0.15s ease;
}

@keyframes slideUp {
	from { opacity: 0; transform: translateY(1rem); }
	to { opacity: 1; transform: translateY(0); }
}

.delete-account-modal-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 1rem 1.25rem;
	border-bottom: 1px solid #2e2e34;
	flex-shrink: 0;
}

.delete-account-modal-title {
	margin: 0;
	font-size: 1.125rem;
	font-weight: 600;
	color: #f2f2f4;
}

.delete-account-modal-close {
	background: none;
	border: none;
	color: #8a8a94;
	font-size: 1.5rem;
	line-height: 1;
	padding: 0;
	cursor: pointer;
	transition: color 0.15s ease;
}

.delete-account-modal-close:hover,
.delete-account-modal-close:focus {
	color: #f2f2f4;
	outline: none;
}

.delete-account-modal-body {
	padding: 1.25rem;
	overflow-y: auto;
	flex: 1 1 auto;
	min-height: 0;
}

.delete-account-modal-warning {
	margin: 0 0 1.5rem;
	color: #f2f2f4;
	font-size: 0.875rem;
	line-height: 1.5;
}

/* `.delete-account-form` is declared once, with the inline delete block above. */

/* Responsive adjustments for small screens */
@media (max-width: 480px) {
	.delete-account-modal {
		padding: 0.5rem;
	}
	
	.delete-account-modal-panel {
		max-width: 100%;
		border-radius: 0.5rem;
	}
	
	.delete-account-modal-head,
	.delete-account-modal-body {
		padding: 1rem;
	}
}

/* ---------------------------------------------------------------- profile form AJAX
 *
 * Toast notifications, button spinner, and connector note.
 */

/* Button spinner */
.btn-with-icon {
	position: relative;
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
}

.btn-with-icon .btn-spinner {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 1em;
	height: 1em;
	animation: spin 1s linear infinite;
	color: inherit;
}

@keyframes spin {
	from { transform: rotate(0deg); }
	to { transform: rotate(360deg); }
}

.btn-with-icon[disabled] {
	opacity: 0.7;
	cursor: not-allowed;
}

.btn-with-icon[disabled] .btn-text {
	opacity: 0.7;
}

/* Toast notifications */
.profile-toast {
	position: fixed;
	bottom: 2rem;
	right: 2rem;
	z-index: 9999;
	display: flex;
	align-items: center;
	gap: 0.75rem;
	padding: 1rem 1.5rem;
	background: #101010;
	border: 1px solid #2e2e34;
	border-radius: 0.5rem;
	box-shadow: 0 12px 24px rgba(0, 0, 0, 0.4);
	color: #f2f2f4;
	font-size: 0.875rem;
	transform: translateY(100px);
	opacity: 0;
	transition: transform 0.3s ease, opacity 0.3s ease;
	max-width: 90vw;
}

.profile-toast.show {
	transform: translateY(0);
	opacity: 1;
}

.profile-toast-success {
	border-color: #28a745;
}

.profile-toast-success .toast-icon {
	color: #28a745;
}

.profile-toast-error {
	border-color: #d63b3b;
}

.profile-toast-error .toast-icon {
	color: #d63b3b;
}

.toast-icon {
	flex-shrink: 0;
	width: 1.25rem;
	height: 1.25rem;
}

/* Connector note */
.form-note-connector {
	display: flex;
	align-items: flex-start;
	gap: 0.5rem;
	padding: 1rem;
	background: #0a0a0a;
	border: 1px solid #2e2e34;
	border-radius: 0.5rem;
	color: #8a8a94;
	font-size: 0.8125rem;
	line-height: 1.5;
	margin-top: 1rem;
}

.form-note-connector .svg-icon {
	flex-shrink: 0;
	width: 1.25rem;
	height: 1.25rem;
	color: #5a5a66;
	margin-top: 0.125rem;
}

/*
 * "KEEP MY ACCOUNT" IS WHITE, NOT GREY.
 *
 * It is the second of two buttons and the SAFE one, and it was painted in the same dark grey
 * as the panel behind it -- so on a dark panel the only legible thing in the footer was the
 * destructive action. A cancel that is hard to read is not a cancel.
 *
 * Stated as `color`, not as a background, so the hover rule a frozen sheet carries for
 * `.btn` cannot leave the label grey-on-grey on hover (AGENTS.md section 10.93: reproduce the
 * winner's property, not just its selector).
 */
.delete-account-modal .btn:not(.btn-delete) {
	color: #ffffff !important;
	border-color: #2e2e34 !important;
}

.delete-account-modal .btn:not(.btn-delete):hover,
.delete-account-modal .btn:not(.btn-delete):focus-visible {
	color: #ffffff !important;
	background: #161616 !important;
	border-color: #3d3d46 !important;
}
 
.musiveo-tip-float {
	position: fixed;
	z-index: 2147483647;
	background: rgba(10, 10, 14, 0.92);
	color: #fff;
	font-size: 12px;
	font-weight: 600;
	line-height: 1.4;
	padding: 6px 10px;
	border-radius: 8px;
	border: 1px solid rgba(255, 255, 255, 0.14);
	box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
	white-space: nowrap;
	pointer-events: none;
	animation: musiveo-tip-in 0.15s ease-out;
}

.musiveo-tip-float[hidden] {
	display: none;
}

@keyframes musiveo-tip-in {
	from { opacity: 0; transform: translateY(3px); }
	to { opacity: 1; transform: none; }
}

/*
 * THE HOVERED MARK BRIGHTENS. The tooltip reads the same colour as the surface it names, and
 * a grey glyph under a near-black bubble is two greys.
 */
.user-platform-link:hover,
.user-platform-link:focus {
	color: #ffffff;
}
/*
 * THE INDICATOR GOES INSIDE THE FIELD, NOT AFTER IT.
 *
 * `getStatusIndicator()` appends the node to the row, and `display: inline-flex` with a
 * left margin places it after the `<input>`. An `<input>` is a replaced element that
 * fills the available width, so "after the input" is a line of its own below the field --
 * which is why every validated network field grew the row by one line the moment it was
 * checked, and the form changed height as the member typed.
 *
 * `position: absolute` over the field's own right-hand padding puts it inside the box
 * where a status belongs, and `padding-right` on the control reserves the room so a long
 * message is never drawn under it. The spinner, the tick and the message are ONE flex
 * box anchored to that edge, so nothing can land on top of anything else.
 *
 * `.form-row { position: relative }` is declared once, with the validation block above.
 */

.form-row .field-status {
	position: absolute;
	top: 2.35em;
	right: 0.75rem;
	margin-left: 0;
	max-width: calc(100% - 1.5rem);
	background: #101010;
	border-radius: 4px;
	padding: 0.125rem 0.375rem;
	/* Above the input's own background, so a message stays readable over its value. */
	z-index: 2;
}

.form-row.field-checking .form-control,
.form-row.field-valid .form-control,
.form-row.field-invalid .form-control {
	padding-right: 3.25rem;
}

/*
 * ROOM FOR THE TICK OR THE SPINNER ALONE.
 *
 * The padding above is for the mark. This is for the message, which is wider, and it is
 * applied only when there IS a message -- a field that is merely valid should not carry
 * 14rem of empty padding on the right, or the typed value is squeezed for no reason.
 */
.form-row.field-invalid .form-control {
	padding-right: 14rem;
}

.form-row .field-status .status-text {
	color: #d63b3b;
	font-weight: 600;
}

.form-row.field-valid .field-status .status-text,
.form-row.field-checking .field-status .status-text {
	color: #f2f2f4;
}

/*
 * THE VERIFICATION BADGE.
 *
 * A pill that sits under the email field and states a fact about the ACCOUNT rather than
 * an opinion about the address. Three states, and the middle one is a state the design
 * has to have: while an address is being typed no verdict exists, and the previous one no
 * longer describes what is in the field. A badge that stayed "Verified" through an edit
 * would be asserting something false.
 */
.email-verified-badge {
	display: inline-flex;
	align-items: center;
	gap: 0.3125rem;
	margin-top: 0.375rem;
	padding: 0.1875rem 0.5rem;
	border: 1px solid #2e2e34;
	border-radius: 999px;
	font-size: 0.6875rem;
	font-weight: 600;
	line-height: 1.4;
	letter-spacing: 0.01em;
	white-space: nowrap;
}

.email-verified-badge::before {
	content: '';
	width: 0.5rem;
	height: 0.5rem;
	border-radius: 50%;
	background: currentColor;
	flex-shrink: 0;
}

.email-verified-badge.is-confirmed {
	color: #4ade80;
	border-color: #14532d;
	background: #052e16;
}

.email-verified-badge.is-unconfirmed {
	color: #fbbf24;
	border-color: #453411;
	background: #1c1408;
}

.email-verified-badge.is-pending {
	color: #a1a1aa;
	border-color: #2e2e34;
	background: #161616;
}

/*
 * WHILE THE CHECK IS IN FLIGHT, THE FIELD SAYS SO.
 *
 * A pending state on the spinner alone is invisible to anyone not looking at the mark,
 * and the mark is 16px. The border is the part of the control a person is actually
 * looking at, so the field itself carries the state.
 */
.form-row.field-checking .form-control {
	border-color: #3d3d46;
}
.user-platforms-dropdown.musiveo-ui-menu:not([hidden]) { display: block; position: fixed; inset: auto; margin: 0; z-index: var(--z-modal, 500) !important; min-width: 0; width: min(15rem, calc(100vw - 16px)); padding: .375rem; border: 1px solid var(--musiveo-ui-border, #292929); border-radius: 12px; background: var(--musiveo-ui-surface, #151515); color: #eee; box-shadow: 0 12px 32px #0006; overflow-x: hidden; overflow-y: auto; scrollbar-width: none; }
.user-platforms-dropdown.musiveo-ui-menu .user-platforms-list { display: block; padding: 0; margin: 0; list-style: none; }
.user-platforms-dropdown.musiveo-ui-menu .dropdown-item > svg { width: 18px !important; height: 18px !important; min-width: 18px !important; max-width: 18px !important; max-height: 18px !important; flex: 0 0 18px !important; margin: 0 !important; }
.user-platforms-dropdown.musiveo-ui-menu .dropdown-item { display: flex; align-items: center; gap: .6rem; text-align: start; justify-content: flex-start; white-space: normal; overflow-wrap: anywhere; }

/* Image choices share one compact, readable upload surface. */
.form-profile .profile-image-copy { display:flex; flex-direction:column; align-items:center; gap:.4rem; min-width:0; }
.form-profile .profile-image-copy strong { font-size:.9rem; font-weight:600; }
.form-profile .profile-image-copy .form-hint { margin:0; font-size:.8rem; line-height:1.5; color:#aaa; max-width:38rem; }
.form-profile .profile-image-dropzone > svg { width:24px; height:24px; flex:0 0 24px; }
.form-profile .profile-image-or { display:flex; align-items:center; gap:.8rem; margin:.9rem 0; color:#aaa; font-size:.85rem; }
.form-profile .profile-image-or::before, .form-profile .profile-image-or::after { content:""; height:1px; background:#ffffff18; flex:1; }
.form-profile .profile-image-status { display:block; width:100%; margin:.55rem 0 0; font-size:.875rem; line-height:1.5; }
.form-profile .profile-image-status:empty { display:none; }
.form-profile .profile-image-status.is-error { padding:.65rem .8rem; border:1px solid #e7717155; border-radius:.65rem; background:#7f1d1d24; color:#ffb4b4; font-weight:500; }
.user-navigation .user-followers { display:inline-flex !important; align-items:center; margin-inline-start:.35rem; }
.user-navigation .user-followers .count { position:static !important; display:inline-flex !important; align-items:center; justify-content:center; min-width:1.25rem; height:auto; padding:0 .25rem; border:0; background:transparent; color:#aaa; font-size:.75rem; line-height:1.5; }

.form-profile .form-row-avatar { grid-template-columns:minmax(0,1fr); }
.form-profile .form-row-avatar > .form-avatar { grid-column:1; grid-row:2; width:100%; }
.form-profile .form-row-avatar > .profile-image-or { grid-column:1; grid-row:3; }
.form-profile .form-row-avatar > .preset-picker { grid-column:1; grid-row:4; }

/* Place each alternative directly below its own upload field. */
.form-profile :is(.form-row-avatar,.form-section-background) > .profile-image-or {
 width:100%; grid-column:1 / -1; box-sizing:border-box; align-self:center;
}
.form-profile .profile-image-or::before,.form-profile .profile-image-or::after { max-width:5rem; }
.form-profile .profile-image-or { justify-content:center; }
.form-profile :is(.form-row-avatar,.form-section-background) > .preset-picker { width:100%; grid-column:1 / -1; }

.form-profile { width:100%; max-width:100% !important; box-sizing:border-box; }

.form-profile .preset-picker > .preset-toggle { display:flex; margin-inline:auto; }

/* Image alternatives share responsive columns without changing submitted fields. */
.form-profile .profile-image-sections { grid-column:1/-1; display:grid; grid-template-columns:repeat(auto-fit,minmax(min(100%,22rem),1fr)); gap:1.5rem; min-width:0; align-items:start; }
.form-profile .profile-image-sections > .form-section { grid-column:auto; min-width:0; margin:0; }
.form-profile .profile-image-sections .form-row-avatar { display:flex !important; flex-direction:column; align-items:center; gap:0; width:100%; margin:0; }
.form-profile .profile-image-sections .form-avatar { display:flex; flex-direction:column; align-items:center; width:100%; gap:1rem; }
.form-profile .profile-image-sections .form-avatar-preview { width:96px; height:96px; margin:2rem auto 1rem; }
.form-profile .profile-image-sections .form-avatar-controls { width:100%; max-width:28rem; margin-inline:auto; }
.form-profile .profile-image-sections .form-section-background { display:block !important; }
.form-profile .profile-image-sections .profile-background-preview-wrap { width:100%; max-width:28rem; margin:1rem auto 0; }
.form-profile .profile-image-sections .profile-background-preview { min-height:0; height:128px; width:100%; }
.form-profile .profile-image-sections .profile-image-dropzone { box-sizing:border-box; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:.75rem; width:100%; max-width:28rem; min-height:164px; padding:1.25rem !important; margin-block:0; margin-inline:auto; text-align:center; }
.form-profile .profile-image-sections .profile-image-dropzone > svg { width:36px; height:36px; flex:0 0 36px; }
.form-profile .profile-image-sections .form-row { width:100%; min-width:0; }
.form-profile .profile-image-sections .form-row:not(.form-row-avatar) { margin:0; }
.form-profile .profile-image-sections .form-section-background > .form-row { padding:0; }
.form-profile .form-control:not([type=checkbox]):not([type=radio]) { width:100%; max-width:100%; min-height:44px; padding:.75rem .9rem !important; border:1px solid #ffffff24 !important; border-radius:.65rem !important; background:#0a0a0a !important; color:#f5f5f7; font:inherit; box-shadow:none; }
