/* ===================== Authentication styling =====================
   Built on the calculator's existing CSS variables so the auth pages inherit
   whatever interface colour and theme the user has chosen. */

.authPage {
	min-height: 100%;
	display: flex;
	align-items: flex-start;
	justify-content: center;
	padding: 2.5em 1em 3em 1em;
	box-sizing: border-box;
}

.authCard {
	width: 100%;
	max-width: 400px;
	/* slightly translucent so the code rain reads behind it without competing
	   with the form, which stays fully legible on top */
	background-color: var(--menu-bg-accent);
	background-color: color-mix(in srgb, var(--menu-bg-accent) 93%, transparent);
	backdrop-filter: blur(3px);
	-webkit-backdrop-filter: blur(3px);
	border: 1px solid var(--border-dark-accent);
	padding: 1.6em 1.6em 1.4em 1.6em;
	box-sizing: border-box;
	flex: 0 0 auto;
}

/* the card sits beside the perks on wide screens, above them on narrow */
.authPageWide {
	gap: 1.6em;
	flex-wrap: wrap;
}

.authPerks {
	width: 100%;
	max-width: 360px;
	align-self: center;
	background-color: color-mix(in srgb, var(--menu-bg-accent) 82%, transparent);
	backdrop-filter: blur(3px);
	-webkit-backdrop-filter: blur(3px);
	border: 1px solid var(--border-dark-accent);
	padding: 1.4em 1.5em;
	box-sizing: border-box;
}
.authPerksTitle {
	font-size: 115%;
	font-weight: 600;
	color: var(--font-white-1);
	margin-bottom: 0.9em;
}
.authFree {
	color: hsl(140 60% 60%);
	font-weight: 700;
	letter-spacing: 0.03em;
}
.authPerksList {
	list-style: none;
	margin: 0;
	padding: 0;
}
.authPerksList li {
	font-size: 88%;
	color: var(--font-white-2);
	line-height: 1.5em;
	padding: 0em 0em 0.9em 1.9em;
	position: relative;
	/* keeps a short paragraph from dropping one orphan word onto its own line */
	text-wrap: pretty;
	text-wrap: balance;
	hyphens: auto;
}
.authPerksList li b { color: var(--font-white-1); font-weight: 600; }
.authPerkIcon {
	position: absolute;
	left: 0;
	top: 0.05em;
	font-size: 105%;
	line-height: 1.3em;
}
.authPerksFoot {
	/* was --font-white-4, too faint to read against the rain */
	font-size: 83%;
	color: var(--font-white-2);
	border-top: 1px solid var(--separator-accent2);
	padding-top: 0.85em;
	margin-top: 0.2em;
	line-height: 1.5em;
	text-wrap: pretty;
	text-wrap: balance;
}
.authPerksFoot b { color: hsl(140 60% 65%); font-weight: 700; }

/* Wordmark, not an icon: it is a wide landscape lockup, so it is sized on
   width and given no border-radius or circular crop. */
.authLogo {
	display: block;
	max-width: 280px;
	width: 78%;
	height: auto;
	margin: 0 auto 1.1em auto;
}

/* Back to the calculator, pinned top-left, flashes green on click */
.authBackBtn {
	position: absolute;
	top: 0.9em;
	left: 0.9em;
	z-index: 5;
	font-size: 85%;
	font-weight: 500;
	color: var(--font-white-2);
	background-color: var(--btn-bg-accent);
	border: 1px solid var(--border-accent);
	border-bottom: 1px solid var(--border-accent) !important;
	padding: 0.4em 0.85em;
	text-decoration: none;
}
/* green on the way in as well as on the click, so the button reads as the way
   out of here rather than as another grey control */
.authBackBtn:hover {
	background-color: hsla(140 55% 40% / 0.45);
	border-color: hsl(140 55% 50%);
	color: #fff;
}
.authBackBtn.authBackFlash { animation: authBackFlash 0.7s ease-out; }
@keyframes authBackFlash {
	0%   { background-color: hsla(140 85% 55% / 0.75); color: #fff; border-color: hsl(140 70% 55%); }
	60%  { background-color: hsla(140 85% 55% / 0.3); }
	100% { background-color: var(--btn-bg-accent); }
}
@media (prefers-reduced-motion: reduce) {
	.authBackBtn.authBackFlash { animation: none; background-color: hsla(140 85% 55% / 0.4); }
}
@media (max-width: 560px) {
	.authBackBtn { position: static; display: inline-block; margin: 0.8em 0em 0em 0.8em; }
}

.authTitle {
	font-size: 150%;
	font-weight: 600;
	color: var(--font-white-1);
	text-align: center;
	margin-bottom: 0.25em;
}
.authSubtitle {
	font-size: 88%;
	color: var(--font-white-3);
	text-align: center;
	margin-bottom: 1.4em;
	line-height: 1.4em;
}

.authField { margin-bottom: 0.9em; }

.authLabel {
	display: block;
	font-size: 82%;
	font-weight: 600;
	color: var(--font-white-3);
	text-transform: uppercase;
	letter-spacing: 0.05em;
	margin-bottom: 0.35em;
}

.authInput {
	width: 100%;
	box-sizing: border-box;
	padding: 0.6em 0.7em;
	font-size: 100%;
	font-family: var(--font-family), "Arial", sans-serif;
	color: var(--font-white-1);
	background-color: var(--input-bg-accent);
	border: 1px solid var(--border-accent);
	outline: none;
}
.authInput:focus { border-color: var(--focus-outline); }
.authInput.authInputBad { border-color: hsl(5 70% 58%); }

.authFieldErr {
	font-size: 80%;
	color: hsl(5 75% 66%);
	padding-top: 0.3em;
}

.authBtn {
	width: 100%;
	box-sizing: border-box;
	padding: 0.65em 1em;
	font-size: 100%;
	font-weight: 600;
	font-family: var(--font-family), "Arial", sans-serif;
	color: var(--font-white-1);
	background-color: var(--btn-bg-accent);
	border: 1px solid var(--border-accent);
	outline: none;
	cursor: pointer;
	margin-top: 0.4em;
}
.authBtn:hover:not(:disabled) { background-color: var(--btn-hover-accent); }
.authBtn:disabled { opacity: 0.6; cursor: default; }

.authBtnDiscord {
	background-color: #5865F2;
	border-color: #5865F2;
	color: #fff;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 0.5em;
}
.authBtnDiscord:hover:not(:disabled) { background-color: #4752c4; }
.authBtnDiscord svg { width: 18px; height: 18px; fill: currentColor; }

.authDivider {
	display: flex;
	align-items: center;
	gap: 0.8em;
	margin: 1.2em 0em 1em 0em;
	color: var(--font-white-4);
	font-size: 80%;
	text-transform: uppercase;
	letter-spacing: 0.06em;
}
.authDivider::before, .authDivider::after {
	content: "";
	flex: 1;
	height: 1px;
	background-color: var(--separator-accent2);
}

.authMsg {
	font-size: 87%;
	padding: 0.6em 0.75em;
	margin-bottom: 1em;
	border: 1px solid transparent;
	line-height: 1.4em;
}
.authMsg-error   { color: hsl(5 80% 74%);   background: hsla(5 70% 40% / 0.15);   border-color: hsl(5 50% 40%); }
.authMsg-success { color: hsl(140 60% 72%); background: hsla(140 60% 35% / 0.15); border-color: hsl(140 40% 35%); }
.authMsg-info    { color: var(--font-white-2); background: hsla(0 0% 50% / 0.12); border-color: var(--border-dark-accent); }

.authFoot {
	text-align: center;
	font-size: 87%;
	color: var(--font-white-3);
	margin-top: 1.2em;
}
.authFoot a, .authLink {
	color: var(--focus-outline);
	border-bottom: 1px solid transparent;
}
.authFoot a:hover, .authLink:hover { border-bottom-color: var(--focus-outline); }

.authHint {
	font-size: 79%;
	color: var(--font-white-4);
	padding-top: 0.3em;
	line-height: 1.35em;
}

/* password strength meter */
.authMeter {
	display: flex;
	gap: 3px;
	margin-top: 0.4em;
}
.authMeterSeg {
	flex: 1;
	height: 3px;
	background: var(--border-dark-accent);
}
.authMeterSeg.on1, .authMeterSeg.on2 { background: hsl(5 70% 55%); }
.authMeterSeg.on3 { background: hsl(40 75% 55%); }
.authMeterSeg.on4, .authMeterSeg.on5 { background: hsl(140 55% 50%); }

.authSpinner {
	display: inline-block;
	width: 11px; height: 11px;
	margin-right: 0.5em;
	border: 2px solid currentColor;
	border-right-color: transparent;
	border-radius: 50%;
	animation: authSpin 0.7s linear infinite;
	vertical-align: -1px;
}
@keyframes authSpin { to { transform: rotate(360deg); } }

/* ---- nav integration ---- */

#authNavArea {
	display: inline-flex;
	align-items: center;
	gap: 0.15em;
	vertical-align: middle;
}
.authNavLink {
	font-size: 88%;
	font-weight: 500;
	color: var(--font-white-2);
	padding: 0.4em 0.7em;
	border-bottom: none !important;
}
.authNavLink:hover { color: var(--font-white-1); background-color: var(--btn-hover-accent); }
.authNavPrimary { color: var(--focus-outline); }

.authNavUser {
	display: inline-flex;
	align-items: center;
	gap: 0.4em;
	padding: 0.25em 0.5em;
	color: var(--font-white-2);
	border-bottom: none !important;
}
.authNavUser:hover { color: var(--font-white-1); background-color: var(--btn-hover-accent); }
.authNavAvatar {
	width: 20px; height: 20px;
	border-radius: 50%;
	object-fit: cover;
	display: inline-block;
}
.authNavAvatarFallback {
	background: var(--btn-active-accent);
	color: var(--font-white-1);
	font-size: 71%;
	font-weight: 600;
	text-align: center;
	line-height: 20px;
}
.authNavName { font-size: 88%; font-weight: 500; max-width: 130px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.authNavNote { font-size: 80%; color: var(--font-white-4); padding: 0em 0.6em; }

/* The shared close button sits at right:-29px, outside its panel. The
   astrology and profile panels clip their overflow, which hid it, so those two
   keep it inside the top-right corner instead. */
.astroBG > .closeMenuBtn,
.profileBG > .closeMenuBtn {
	right: 2px !important;
	top: 0px !important;
	z-index: 4;
}

/*              Profile tab panel             */
/* ########################################## */

.profileBG {
	max-width: min(700px, calc(100vw - 1.5em));
	box-sizing: border-box;
	padding-right: 1em;
}
.profileTabs {
	display: flex;
	flex-wrap: wrap;
	gap: 0.2em;
	padding: 0em 0.2em 0.7em 0.2em;
	border-bottom: 1px solid var(--separator-accent2);
	margin-bottom: 0.8em;
}
.intBtn3.profileTab {
	width: auto;
	padding: 0.2em 0.8em;
	font-size: 88%;
	margin: 0;
	opacity: 0.6;
}
.intBtn3.profileTab.profileTabOn {
	opacity: 1;
	background-color: var(--btn-active-accent);
}
.profileBody { min-height: 140px; }
.profileLoading, .profileNote {
	font-size: 84%;
	color: var(--font-white-3);
	padding: 0.5em 0.3em;
	line-height: 1.45em;
}
.profileNote.profileWarn { color: hsl(35 78% 66%); }
.profileNote.profileOk { color: hsl(140 55% 65%); }
.profileNote.profileFoot {
	border-top: 1px solid var(--border-dark-accent);
	margin-top: 0.6em;
	font-size: 79%;
}

.profileSearchRow { display: flex; align-items: center; gap: 0.6em; padding-bottom: 0.6em; }
.profileSearchInput {
	flex: 1;
	box-sizing: border-box;
	padding: 0.45em 0.6em;
	font-size: 95%;
	font-family: var(--font-family), "Arial", sans-serif;
	color: var(--font-white-1);
	background-color: var(--input-bg-accent);
	border: 1px solid var(--border-accent);
	outline: none;
}
.profileSearchInput:focus { border-color: var(--focus-outline); }
.profileCount { font-size: 80%; color: var(--font-white-4); min-width: 3em; text-align: right; }
/* Enabled only once the box holds a phrase not already saved verbatim - see
   profileAddFromSearch() - so it never reads as a second search button. */
.profileAddBtn { flex: 0 0 auto; white-space: nowrap; }
/* Live gematria preview under the search/add box - see profilePreviewUpdate().
   Reserves its line even when empty so the row above it does not jump. */
.profilePreview {
	min-height: 1.3em;
	padding: 0 0.1em 0.6em 0.1em;
	font-size: 85%;
	color: var(--font-white-3);
}
.profilePreview b { color: var(--font-white-1); }
/* Collapsed by default - see profileHidePublishedGet(). One line, not a
   button, so it reads as part of the list rather than another control. */
.profilePublishedToggle {
	font-size: 82%;
	color: var(--font-white-3);
	cursor: pointer;
	padding: 0.5em 0.2em;
	user-select: none;
}
.profilePublishedToggle:hover { color: var(--font-white-1); }

.profileList {
	max-height: 340px;
	overflow-y: auto;
	border: 1px solid var(--border-dark-accent);
}
.profileRow {
	display: flex;
	align-items: center;
	gap: 0.6em;
	padding: 0.4em 0.6em;
	border-bottom: 1px solid var(--border-dark-accent);
	font-size: 90%;
}
.profileRow:last-child { border-bottom: none; }
.profileRow:nth-child(odd) { background: var(--table-row-odd); }
.profileRowPhrase {
	flex: 1;
	color: var(--font-white-1);
	cursor: pointer;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}
.profileRowPhrase:hover { text-decoration: underline; }
.profileRowActions { display: flex; align-items: center; gap: 0.35em; flex: 0 0 auto; }
.profileWhen { font-size: 80%; color: var(--font-white-3); }

.profileMiniBtn {
	font-size: 80%;
	font-family: var(--font-family), "Arial", sans-serif;
	color: var(--font-white-2);
	background-color: var(--btn-bg-accent);
	border: 1px solid var(--border-accent);
	padding: 0.15em 0.55em;
	cursor: pointer;
	outline: none;
}
.profileMiniBtn:hover:not(:disabled) { background-color: var(--btn-hover-accent); color: var(--font-white-1); }
.profileMiniBtn:disabled { opacity: 0.5; cursor: default; }
.profileMiniBtn.profileMiniDanger { color: hsl(5 70% 68%); }
.profileMiniBtn.profileMiniDanger:hover { background-color: hsla(5 60% 45% / 0.3); }
/* the reset sits apart from the naming row below it, so the two are not read
   as one control */
/* Sized to sit on one line at the panel's width. Where it cannot - a phone -
   balance splits it evenly rather than dropping one word onto the second
   line, which is what looked wrong in the first place. */
.profileNoteOneLine {
	text-wrap: pretty;
	text-wrap: balance;
}

.profileDefaultRow {
	display: flex;
	align-items: center;
	gap: 0.6em;
	flex-wrap: wrap;
	padding: 0.5em 0 0.9em 0;
	margin-bottom: 0.6em;
	border-bottom: 1px solid var(--separator-accent2);
}
.profileMiniBtn.profileDefaultBtn { padding: 0.25em 0.7em; }
.profilePresetSaveRow { padding-top: 0.2em; }

/* armed: one more click carries it out. Replaces window.confirm, which the
   browser suppresses, so the button has to say so itself. */
.profileMiniBtn.profileArmed {
	background-color: hsl(5 60% 42%);
	border-color: hsl(5 65% 58%);
	color: #fff;
	font-weight: 600;
}

.profileBadge {
	font-size: 78%;
	padding: 0.12em 0.5em;
	border: 1px solid var(--border-accent);
	color: var(--font-white-3);
}
.profileBadge.profileBadgeOk { color: hsl(140 55% 65%); border-color: hsl(140 35% 40%); }

/* The avatar is the control: clicking the circle reveals the options */
.profileAvatarPick {
	position: relative;
	display: inline-block;
	cursor: pointer;
	border-radius: 50%;
	overflow: hidden;
	flex: 0 0 auto;
	padding: 0;
	border: none;
	background: none;
	line-height: 0;
}
.profileAvatarOpts { padding-top: 0.2em; }

/* Display name on the welcome page: the one thing worth doing here, so it is
   picked out in green rather than looking like every other field. */
.authNameField {
	border: 1px solid hsl(140 40% 38%);
	background: hsla(140 55% 40% / 0.10);
	padding: 0.8em 0.9em;
	margin-bottom: 0.9em;
}
.authNameField .authLabel { color: hsl(140 60% 70%); }
.authNameField .authInput {
	border-color: hsl(140 35% 42%);
	color: hsl(140 45% 88%);
}
.authNameField .authInput:focus {
	border-color: hsl(140 60% 58%);
	box-shadow: 0 0 0 2px hsla(140 60% 45% / 0.25);
}
.authBtn.authBtnPrimary {
	background-color: hsl(140 45% 32%);
	border-color: hsl(140 40% 45%);
	color: hsl(140 30% 95%);
}
.authBtn.authBtnPrimary:hover:not(:disabled) { background-color: hsl(140 48% 38%); }
.profileAvatarOverlay {
	position: absolute;
	left: 0; right: 0; bottom: 0;
	text-align: center;
	font-size: 72%;
	padding: 0.2em 0;
	color: #fff;
	background: hsla(0 0% 0% / 0.55);
	opacity: 0;
	transition: opacity 0.12s;
}
.profileAvatarPick:hover .profileAvatarOverlay,
.profileAvatarPick:focus-within .profileAvatarOverlay { opacity: 1; }
.profileNameRow { padding-top: 0.9em; }

/* Closing the account. Set apart from the rest of the tab so it cannot be
   mistaken for one of the ordinary settings above it. */
.profileDanger {
	margin-top: 1.2em;
	padding: 0.7em 0.8em;
	border: 1px solid hsl(5 45% 40%);
	background: hsla(5 60% 40% / 0.10);
}
.profileDangerTitle {
	font-weight: 600;
	color: hsl(5 75% 74%);
	padding-bottom: 0.3em;
}
.profileDangerRow {
	display: flex;
	align-items: center;
	gap: 0.5em;
	padding-top: 0.5em;
	flex-wrap: wrap;
}
.profileDangerRow .profileSearchInput { flex: 1 1 12em; min-width: 0; }
.profileBadge.profileBadgeBad { color: hsl(5 75% 70%); border-color: hsl(5 50% 45%); }

/* Which cypher a phrase is being published under */
.profileCiphSelect {
	font-family: var(--font-family), "Arial", sans-serif;
	font-size: 78%;
	color: var(--font-white-2);
	background-color: var(--input-bg-accent);
	border: 1px solid var(--border-accent);
	padding: 0.1em 0.2em;
	max-width: 9em;
	outline: none;
}

/* Searchable cipher picker. The menu is parented to <body> and positioned in
   fixed coordinates, because its row lives in a 340px scroll box that would
   otherwise clip it. profileCiphPlace() sets left/top/width/max-height. */
.profileCiphPick { position: relative; display: inline-block; }
.profileCiphInput { width: 9em; }
.profileCiphInput::placeholder { color: var(--font-white-4); }
.profileCiphMenu {
	position: fixed;
	z-index: 40;
	overflow-y: auto;
	background-color: var(--menu-bg-accent, var(--input-bg-accent));
	border: 1px solid var(--border-accent);
	box-shadow: 0 6px 18px hsla(0 0% 0% / 0.45);
	font-size: 78%;
}
.profileCiphGroup {
	padding: 0.25em 0.5em 0.1em;
	color: var(--font-white-4);
	font-size: 88%;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	position: sticky;
	top: 0;
	background-color: var(--menu-bg-accent, var(--input-bg-accent));
}
.profileCiphOpt {
	padding: 0.22em 0.6em;
	color: var(--font-white-2);
	cursor: pointer;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}
.profileCiphOpt b { color: var(--font-white-1); font-weight: 700; }
.profileCiphOpt.profileCiphOn { background-color: var(--btn-hover-accent); color: var(--font-white-1); }
.profileCiphNone { padding: 0.4em 0.6em; color: var(--font-white-4); }
.profileChipTerm { display: block; }
/* The cipher and its value, in that cipher's own colour. Bold because this is
   the reason the phrase was published, not a footnote to it - the grey it used
   to be read as disabled text. The inline colour comes from profileCipherColor. */
.profileChipCiph {
	display: block;
	font-size: 78%;
	font-weight: 700;
	color: var(--font-white-2);
	padding-top: 0.1em;
}
.profileChipVal {
	font-family: var(--font-family-mono), monospace;
	font-weight: 700;
	color: inherit;
}

/* A submission refused by the publishing rules. The row turns red and keeps
   the reason underneath, so it survives the re-render instead of disappearing
   with the notification. */
.profileRow.profileRowRefused {
	flex-wrap: wrap;
	background: hsla(5 60% 40% / 0.16) !important;
	border-left: 2px solid hsl(5 65% 55%);
}
.profileRow.profileRowRefused .profileRowPhrase { color: hsl(5 75% 78%); }
.profileRowWhy {
	flex: 1 0 100%;
	font-size: 84%;
	color: hsl(5 70% 74%);
	padding-top: 0.25em;
}

.profileLbRow { cursor: pointer; }
.profileLbRow:hover { background: var(--btn-hover-accent); }
/* Which name is expanded, so a second click on it reads as "close this" rather
   than doing nothing visible. */
.profileLbRow.profileLbOpen {
	background: var(--btn-hover-accent);
	border-left: 2px solid var(--font-white-3);
}
.profileLbRank {
	font-family: var(--font-family-mono), monospace;
	font-size: 85%;
	color: var(--font-white-4);
	width: 1.6em;
}
.profileLbAvatar {
	width: 22px; height: 22px;
	border-radius: 50%;
	object-fit: cover;
	flex: 0 0 auto;
}
.profileLbFallback {
	background: var(--btn-active-accent);
	color: var(--font-white-1);
	font-size: 72%;
	font-weight: 600;
	text-align: center;
	line-height: 22px;
}

.profileContribBox {
	margin-top: 0.8em;
	border: 1px solid var(--border-dark-accent);
	padding: 0.6em 0.7em;
	background: var(--breakdown-bg-accent);
}
.profileContribTitle {
	font-size: 86%;
	font-weight: 600;
	color: var(--font-white-2);
	padding-bottom: 0.5em;
}
.profileChips { display: flex; flex-wrap: wrap; gap: 0.35em; }
.profileChip {
	font-size: 84%;
	padding: 0.2em 0.6em;
	background: var(--btn-bg-accent);
	border: 1px solid var(--border-dark-accent);
	color: var(--font-white-2);
	cursor: pointer;
}
.profileChip:hover { background: var(--btn-hover-accent); color: var(--font-white-1); }

.profileAccountHead { display: flex; align-items: center; gap: 0.8em; padding: 0.2em 0.3em 1em 0.3em; }
.profileBigAvatar {
	width: 46px; height: 46px;
	border-radius: 50%;
	object-fit: cover;
	line-height: 46px;
	font-size: 140%;
}
.profileAccountName { font-size: 115%; font-weight: 600; color: var(--font-white-1); }
.profileAccountSub { font-size: 84%; color: var(--font-white-3); }
.profileAvatarRow { display: flex; align-items: center; gap: 0.5em; flex-wrap: wrap; padding: 0.2em 0.3em; }
.profileFileInput { font-size: 82%; color: var(--font-white-3); max-width: 100%; }

.profileSignedOut { padding: 1.4em 1em 1.6em 1em; text-align: center; max-width: 30em; }
.profileSignedOutTitle { font-size: 120%; font-weight: 600; color: var(--font-white-1); margin-bottom: 0.5em; }
.profileSignedOutText { font-size: 88%; color: var(--font-white-3); line-height: 1.5em; margin-bottom: 1.1em; }
.profileSignedOutBtns { display: flex; gap: 0.5em; justify-content: center; flex-wrap: wrap; }
.intBtn3.profileCta {
	width: auto;
	padding: 0.35em 1em;
	text-decoration: none;
	border-bottom: none !important;
	display: inline-block;
}
.intBtn3.profileCta.profileCtaPrimary { background-color: var(--btn-active-accent); color: var(--font-white-1); }

/* history sync indicator, sits just before the account links */
.histSyncStatus {
	font-size: 78%;
	color: var(--font-white-4);
	padding: 0em 0.5em;
	vertical-align: middle;
	white-space: nowrap;
}
.histSyncStatus.histSync-busy { color: var(--font-white-3); }
.histSyncStatus.histSync-ok   { color: hsl(140 45% 60%); }
.histSyncStatus.histSync-warn { color: hsl(35 75% 62%); }

/* ---- profile page ---- */

.authProfileRow {
	display: flex;
	justify-content: space-between;
	gap: 1em;
	padding: 0.55em 0em;
	border-bottom: 1px solid var(--border-dark-accent);
	font-size: 90%;
}
.authProfileRow:last-child { border-bottom: none; }
.authProfileKey { color: var(--font-white-3); }
.authProfileVal { color: var(--font-white-1); text-align: right; word-break: break-word; }
.authProfileHead {
	display: flex;
	align-items: center;
	gap: 0.8em;
	margin-bottom: 1.2em;
}
.authProfileAvatar {
	width: 52px; height: 52px;
	border-radius: 50%;
	object-fit: cover;
	background: var(--btn-active-accent);
	line-height: 52px;
	text-align: center;
	font-size: 150%;
	font-weight: 600;
	color: var(--font-white-1);
}
.authBadge {
	display: inline-block;
	font-size: 76%;
	padding: 0.15em 0.5em;
	border: 1px solid var(--border-accent);
	color: var(--font-white-3);
	margin-left: 0.4em;
}
.authBadgeOk { color: hsl(140 55% 65%); border-color: hsl(140 35% 40%); }

@media (max-width: 560px) {
	.authPage { padding: 1.2em 0.7em 2em 0.7em; }
	.authCard { padding: 1.2em 1.1em; }
}

/* ---- birth chart tab ---- */
.pcZodiacRow { display: flex; align-items: center; gap: 0.4em; flex-wrap: wrap; padding-bottom: 0.6em; }
.intBtn3.pcZodBtn { width: auto; margin: 0; padding: 0.25em 0.8em; }
.intBtn3.pcZodBtn.pcZodOn { background-color: var(--btn-active-accent); color: var(--font-white-1); font-weight: 600; }
/* One toolbar: the zodiac switch on the left, the print buttons pushed to the
   right with margin-left:auto so they stay right-aligned however the row wraps. */
.pcPrintGroup { display: flex; align-items: center; gap: 0.4em; margin-left: auto; flex-wrap: wrap; }
.pcPrintLab { font-size: 80%; color: var(--font-white-3); font-weight: 600; }
.intBtn3.pcPrintBtn { border-color: var(--font-white-4); }
/* the sentence about the two zodiacs, moved off the toolbar now five controls
   share it */
.pcZodiacNote { padding-bottom: 0.6em; }
@media (max-width: 620px) { /* stacked rather than squeezed */
	.pcPrintGroup { margin-left: 0; padding-top: 0.3em; }
}

.pcFields { padding-bottom: 0.6em; }
/* Time and Place as separate blocks. They used to be four rows in one stack at
   equal spacing, so the tickbox that belonged to Time sat just as close to
   Place as to Time and the two questions read as one. */
.pcBlock { padding-top: 0.45em; margin-top: 0.45em; border-top: 1px solid var(--separator-accent2); }
.pcRowSub { padding-top: 0; } /* a continuation of the row above, not a new one */
.pcRow { display: flex; align-items: center; gap: 0.4em; padding: 0.18em 0; flex-wrap: wrap; }
.pcLab { font-size: 82%; color: var(--font-white-1); font-weight: 600; width: 5em; flex: 0 0 auto; }
.pcIn {
	font-family: var(--font-family), "Arial", sans-serif;
	font-size: 88%;
	color: var(--font-white-1);
	background-color: var(--input-bg-accent);
	border: 1px solid var(--border-accent);
	padding: 0.15em 0.3em;
	width: 4.5em;
	outline: none;
}
.pcIn.pcInY { width: 5em; }
.pcIn.pcInPlace { flex: 1 1 10em; width: auto; min-width: 0; }
.pcChk { font-size: 80%; color: var(--font-white-3); display: inline-flex; align-items: center; gap: 0.4em; cursor: pointer; }
/* These were real checkboxes all along, but styles.css hides every native one
   ("input[type=checkbox] { visibility: hidden }") on the assumption that a
   .custChkBox span follows it. There is none here, so the box was invisible and
   the label read as plain text with no way to tell it was on or off. Rather
   than bolt on the span, the input itself is drawn: same look, one element,
   and the label still toggles it. */
.pcChk input[type=checkbox] {
	visibility: visible;
	-webkit-appearance: none;
	appearance: none;
	position: relative;
	flex: 0 0 auto;
	margin: 0;
	width: 15px;
	height: 15px;
	background-color: var(--btn-bg-accent);
	border: 1px solid var(--border-accent);
	cursor: pointer;
}
.pcChk:hover input[type=checkbox] { background-color: var(--btn-hover-accent); }
.pcChk input[type=checkbox]:active { background-color: var(--btn-active-accent); }
.pcChk input[type=checkbox]:checked::after { /* the tick */
	content: "";
	position: absolute;
	left: 4px;
	top: 0px;
	width: 3px;
	height: 8px;
	border: solid var(--font-white-1);
	border-width: 0 2px 2px 0;
	transform: rotate(45deg);
}
.pcChk input[type=checkbox]:focus-visible { outline: 1px solid var(--font-white-3); outline-offset: 1px; }
.pcUnknown { font-style: italic; }
.pcGeo { padding-bottom: 0.4em; }

.pcCanvasWrap { display: flex; justify-content: center; padding: 0.4em 0 0.6em 0; }
/* The element is square by rule, not by measurement. Setting both dimensions
   in JS meant a later reflow could clamp the width through max-width while the
   inline height stood, and the chart was drawn into a tall rectangle. */
#pcCanvas {
	display: block;
	width: 100%;
	max-width: 440px;
	height: auto;
	aspect-ratio: 1 / 1;
}

.pcSectionTitle {
	font-weight: 600; color: var(--font-white-1);
	border-bottom: 1px solid var(--separator-accent2);
	padding-bottom: 0.25em; margin: 0.6em 0 0.4em 0;
}
/* Transits are a separate reading from the birth chart above them, and the two
   were running together. A rule and real space make the break obvious. */
#pcTransits {
	margin-top: 1.1em;
	padding-top: 0.9em;
	border-top: 2px solid var(--border-accent);
}
#pcTransits .pcSectionTitle { margin-top: 0; }
.pcAngles {
	margin-top: 0.5em;
	padding-top: 0.5em;
	border-top: 1px solid var(--separator-accent2);
}
/* chart on the left, the reading beside it; stacks on a narrow panel */
.pcSplit { display: flex; gap: 0.9em; align-items: flex-start; flex-wrap: wrap; }
/* The reading is as wide as its longest line and no wider; the wheel expands
   into whatever is left.
   flex-basis is 0, not the content: with a content basis the wrapper is sized
   by the canvas inside it and the canvas is sized from the wrapper, so each
   waits on the other and the first paint settles on the wrong answer. */
.pcSplit .pcCanvasWrap { flex: 1 1 0; padding: 0; min-width: 180px; justify-content: center; }
/* Sized to its own lines, but capped: the notes underneath are full sentences
   and were stretching the column to 404px, leaving the chart 250px and a
   square drawn into a tall rectangle. */
.pcReading { flex: 0 1 auto; min-width: 0; max-width: 44%; }
/* The notes are sentences; the rows above them are short. Left to itself the
   column takes the width of the longest sentence, which is what was squeezing
   the chart. They wrap to the width the rows need instead. */
.pcReading .profileNote { white-space: normal; max-width: 20em; }
.pcAyan { font-style: italic; }

/* the reading only needs to be as wide as its longest line, so it is sized to
   its content rather than stretching to fill whatever is left */
.pcHouses { display: flex; flex-direction: column; }
.pcHouseBlock {
	border-left: 2px solid var(--border-accent);
	border-bottom: 1px solid var(--separator-accent2);
	padding: 0.3em 0.4em 0.35em 0.5em;
}
.pcHouseBlock:last-child { border-bottom: none; }
.pcHouseHead {
	font-size: 80%; font-weight: 700; letter-spacing: 0.03em;
	color: var(--font-white-1); cursor: help;
}
.pcCell { display: flex; align-items: baseline; gap: 0.35em; font-size: 86%; cursor: help; white-space: nowrap; }
.pcSign { color: var(--font-white-2); cursor: help; }
.pcSign:hover { color: var(--font-white-1); }
.pcAngles { display: flex; gap: 0.9em; font-size: 84%; font-weight: 600; }
.pcAngles span { cursor: help; }

/* one shared hover explanation, following the pointer */
.pcTipBox {
	position: fixed;
	z-index: 4000;
	max-width: 22em;
	font-size: 84%;
	line-height: 1.4em;
	color: var(--font-white-1);
	background-color: var(--menu-bg-accent);
	border: 1px solid var(--border-accent);
	padding: 0.45em 0.6em;
	pointer-events: none;
	box-shadow: 0 2px 10px hsla(0 0% 0% / 0.4);
}

/* number box with its label underneath */
.pcFieldWrap { display: inline-flex; flex-direction: column; align-items: center; }
/* these name the boxes above them, so they have to be read, not sensed */
.pcFieldLab { font-size: 76%; color: var(--font-white-1); padding-top: 0.15em; }
.pcChkBox { padding-left: 0.4em; }
.pcSaveRow { padding-bottom: 0.5em; }
.profileMiniBtn.pcSaveBtn { background-color: hsl(140 40% 30%); border-color: hsl(140 35% 42%); color: hsl(140 25% 92%); }
.profileMiniBtn.pcSaveBtn:hover:not(:disabled) { background-color: hsl(140 44% 36%); }
.pcGlyph { font-size: 115%; }
.pcBody { color: var(--font-white-2); }
.pcPos { color: var(--font-white-2); font-family: var(--font-family-mono), monospace; font-size: 92%; }
.pcRetro { color: hsl(15 70% 62%); font-size: 88%; }
.pcHouse { color: var(--font-white-2); font-size: 84%; }

.pcTransitList { display: flex; flex-direction: column; gap: 0.12em; }
.pcTransit { display: flex; align-items: baseline; gap: 0.35em; font-size: 86%; flex-wrap: wrap; cursor: help; }
.pcAspect { font-weight: 600; }
.pcOrb { color: var(--font-white-2); font-family: var(--font-family-mono), monospace; font-size: 88%; margin-left: auto; }

/* ===================== Friends =====================
   Reuses .profileRow, .profileList and .profileMiniBtn so a friend, a saved
   phrase and a leaderboard entry are visibly the same kind of thing. Only
   what is genuinely new to this tab is defined here. */

/* Icon beside the word, not above it, and at text size rather than a size
   that makes the row read as a toolbar of pictures. The icons are given a
   fixed width so they line up down the column whatever glyph is in them -
   emoji have wildly different advance widths, and without this the labels
   stagger. */
.frTabs { display: flex; gap: 0.25em; padding-bottom: 0.7em; flex-wrap: wrap; }
.intBtn3.frTab {
	width: auto;
	flex: 1 1 auto;
	min-width: 0;
	margin: 0;
	padding: 0.3em 0.55em;
	position: relative;
	display: flex;
	flex-direction: row;
	align-items: center;
	justify-content: center;
	gap: 0.35em;
	line-height: 1.3em;
	transition: color 0.15s ease, background-color 0.15s ease;
}
.frTabIcon {
	font-size: 95%;
	line-height: 1;
	width: 1.15em;
	text-align: center;
	flex: 0 0 auto;
}
.frTabLab { font-size: 84%; overflow: hidden; text-overflow: ellipsis; }
.intBtn3.frTab.frTabOn { background-color: var(--btn-active-accent); color: var(--font-white-1); font-weight: 600; }
/* the site's green, the same one the back button and Find Matches use */
.intBtn3.frTab:hover { color: hsl(140 60% 66%); border-color: hsl(140 45% 45%); }
@media (prefers-reduced-motion: reduce) { .intBtn3.frTab { transition: none; } }
@media (max-width: 420px) { .frTabLab { display: none; } .frTabIcon { font-size: 110%; width: auto; } }

/* the count of requests waiting, on the section button and inline in headings */
.frBadge {
	display: inline-block;
	margin-left: 0.4em;
	position: relative;
	min-width: 1.35em;
	padding: 0 0.3em;
	border-radius: 999px;
	background-color: hsl(5 65% 48%);
	color: #fff;
	font-size: 78%;
	font-weight: 700;
	line-height: 1.45em;
	text-align: center;
}
.frBadgeInline { vertical-align: middle; }
/* the Friends tab itself, when something is waiting */
.profileTab.profileTabAlert { border-color: hsl(5 65% 55%); color: hsl(5 80% 78%); }

.frToolbar { display: flex; align-items: center; gap: 0.3em; flex-wrap: wrap; padding-bottom: 0.6em; }
.frToolLab { font-size: 80%; color: var(--font-white-3); font-weight: 600; padding-right: 0.2em; }
.intBtn3.frChip { width: auto; margin: 0; padding: 0.18em 0.7em; font-size: 82%; }
.intBtn3.frChip.frChipOn { background-color: var(--btn-active-accent); color: var(--font-white-1); font-weight: 600; }

.frSectionTitle {
	font-size: 85%;
	font-weight: 600;
	color: var(--font-white-1);
	padding: 0.7em 0 0.4em 0;
}

.frRow { align-items: center; gap: 0.5em; }
.frAvatar {
	width: 26px; height: 26px;
	border-radius: 50%;
	object-fit: cover;
	flex: 0 0 auto;
	background-color: var(--btn-bg-accent);
}
.frAvatarFallback {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	font-size: 80%;
	font-weight: 700;
	color: var(--font-white-2);
}
.frAvatarBig { width: 56px; height: 56px; font-size: 150%; }

.frWho { flex: 1 1 auto; min-width: 0; cursor: pointer; }
.frWho:hover .frName { color: var(--font-white-1); text-decoration: underline; }
.frName { display: block; color: var(--font-white-2); font-weight: 600; }
/* the handle and the join date are read on purpose, not skipped */
.frSub { display: block; font-size: 80%; color: var(--font-white-3); }

/* Presence is a timestamp, not a flag, so this is "seen in the last five
   minutes" rather than a state a closed browser could leave stuck on. */
.frDot {
	display: inline-block;
	width: 7px; height: 7px;
	border-radius: 50%;
	margin-left: 0.45em;
	vertical-align: middle;
	background-color: var(--font-white-4);
}
.frDot.frDotOn { background-color: hsl(140 60% 50%); box-shadow: 0 0 5px hsl(140 60% 45%); }

.frActions { display: flex; align-items: center; gap: 0.3em; flex: 0 0 auto; }
.profileMiniBtn.frAdd { background-color: hsl(140 40% 30%); border-color: hsl(140 35% 42%); color: hsl(140 25% 92%); }
.profileMiniBtn.frAdd:hover:not(:disabled) { background-color: hsl(140 44% 36%); }
.profileMiniBtn.frAccept { background-color: hsl(140 40% 30%); border-color: hsl(140 35% 42%); color: hsl(140 25% 92%); }
.profileMiniBtn.frAccept:hover:not(:disabled) { background-color: hsl(140 44% 36%); }

.frBack { padding-bottom: 0.5em; }
.frProfile { padding-bottom: 0.4em; }
.frProfileHead { display: flex; align-items: center; gap: 0.8em; padding-bottom: 0.8em; }
.frProfileWho { flex: 1 1 auto; min-width: 0; }
.frProfileName { font-size: 118%; font-weight: 600; color: var(--font-white-1); }
.frProfileActions { flex: 0 0 auto; display: flex; gap: 0.3em; }

.frStats { display: flex; gap: 0.5em; flex-wrap: wrap; }
.frStat {
	flex: 1 1 5.5em;
	background-color: var(--input-bg-accent);
	border: 1px solid var(--border-dark-accent);
	padding: 0.5em 0.4em;
	text-align: center;
}
.frStatVal { font-family: var(--font-family-mono), monospace; font-size: 125%; font-weight: 700; color: var(--font-white-1); }
/* --font-white-4 is the shade for things you are meant to skip; a stat's label
   is the half that says what the number means */
.frStatLab { font-size: 74%; color: var(--font-white-3); padding-top: 0.15em; }

.frBadgeRow { display: flex; gap: 0.35em; flex-wrap: wrap; }
.frAward {
	font-size: 80%;
	color: var(--font-white-2);
	background-color: var(--btn-bg-accent);
	border: 1px solid var(--border-accent);
	padding: 0.2em 0.55em;
	cursor: help;
}

.frToggleRow { padding: 0.25em 0; }
.frToggleHint { font-size: 78%; color: var(--font-white-4); padding-left: 1.9em; }

/* ---- chat ---- */

.profileMiniBtn.frMsg { background-color: hsl(210 40% 32%); border-color: hsl(210 35% 45%); color: hsl(210 25% 92%); }
.profileMiniBtn.frMsg:hover:not(:disabled) { background-color: hsl(210 44% 38%); }

/* one line of preview, cut rather than wrapped: a thread list is a list of
   people, not a list of messages */
.frPreview {
	display: block;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	max-width: 100%;
}

.frChatHead {
	display: flex;
	align-items: center;
	gap: 0.5em;
	padding-bottom: 0.5em;
	border-bottom: 1px solid var(--separator-accent2);
}
.frChatWho { flex: 1 1 auto; font-weight: 600; color: var(--font-white-1); }
.frChatHeadActions { display: flex; gap: 0.3em; flex: 0 0 auto; }

.frChatLog {
	height: 260px;
	overflow-y: auto;
	padding: 0.6em 0.2em;
	display: flex;
	flex-direction: column;
	gap: 0.35em;
}

.frMsgRow { display: flex; flex-direction: column; align-items: flex-start; max-width: 100%; }
.frMsgRow.frMsgMine { align-items: flex-end; }

.frBubble {
	max-width: 78%;
	padding: 0.4em 0.65em;
	background-color: var(--btn-bg-accent);
	border: 1px solid var(--border-dark-accent);
	color: var(--font-white-2);
	font-size: 90%;
	line-height: 1.4em;
	/* a long unbroken string is the one way text can still break a layout */
	overflow-wrap: anywhere;
	white-space: normal;
}
.frMsgMine .frBubble {
	background-color: hsl(210 38% 28%);
	border-color: hsl(210 30% 38%);
	color: hsl(210 20% 94%);
}
/* An edge on the outer side, so which way a message faces survives a bubble
   wide enough that its position no longer says. Colour alone is not enough on
   a phone held at arm's length. */
.frMsgRow .frBubble { border-left: 3px solid var(--font-white-4); }
.frMsgMine .frBubble { border-left: 1px solid hsl(210 30% 38%); border-right: 3px solid hsl(210 55% 62%); }
.frMsgWhen { font-size: 72%; color: var(--font-white-4); padding: 0.1em 0.2em; }

.frChatCompose { display: flex; gap: 0.4em; align-items: flex-end; padding-top: 0.5em; }
.frChatBox {
	flex: 1 1 auto;
	resize: vertical;
	min-height: 2.4em;
	max-height: 8em;
	box-sizing: border-box;
	padding: 0.4em 0.5em;
	font-family: var(--font-family), "Arial", sans-serif;
	font-size: 90%;
	color: var(--font-white-1);
	background-color: var(--input-bg-accent);
	border: 1px solid var(--border-accent);
	outline: none;
}
.frChatBox:focus { border-color: var(--focus-outline); }
.profileMiniBtn.frChatSend { flex: 0 0 auto; align-self: stretch; padding: 0 1em; }

.frChatWarn { font-size: 80%; color: var(--font-white-4); min-height: 1.2em; padding-top: 0.25em; }
.frChatWarn.frChatWarnBad { color: hsl(5 75% 72%); }

/* Mobile: index.html pins the layout viewport to 520px, so this matches on a
   phone and never on a desktop window.
   
   78% of a 465px log leaves 81px of offset - 17% - and at that width a normal
   sentence fills the bubble and both sides read as centred, which is exactly
   what they did. 64% doubles the offset to a third of the width, which is
   unmistakable at a glance. Long messages wrap a line more; being able to tell
   who said what is worth more than that. */
@media (max-width: 620px) {
	.frBubble { max-width: 64%; }
	.frChatLog { height: 300px; }
}

/* the flag on a chat message: quiet until hovered, loud once armed */
.frMsgFlag {
	cursor: pointer;
	padding-left: 0.35em;
	color: var(--font-white-4);
	opacity: 0;
	transition: opacity 0.15s ease;
}
.frMsgRow:hover .frMsgFlag { opacity: 1; }
.frMsgFlag:hover { color: hsl(5 75% 70%); }
.frMsgFlag.frMsgFlagArmed { opacity: 1; color: hsl(5 80% 72%); font-weight: 700; }
@media (prefers-reduced-motion: reduce) { .frMsgFlag { transition: none; } }
/* touch devices have no hover, so the flag has to be permanently visible */
@media (hover: none) { .frMsgFlag { opacity: 0.55; } }

/* admin shortcut in the nav row */
.authNavLink.authNavAdmin { color: hsl(45 85% 72%); }

/* the sort toggle above a contributor's published phrases */
.profileContribSort { display: flex; align-items: center; gap: 0.5em; padding-bottom: 0.5em; }
.profileSectionTitle {
	font-size: 84%;
	font-weight: 600;
	color: var(--font-white-3);
	padding: 0.9em 0 0.4em 0;
	border-top: 1px solid var(--separator-accent2);
	margin-top: 0.6em;
}


/* ---- friends nav: badges and the first-time pip ---- */

.frTab .frBadge {
	position: absolute;
	top: 1px;
	right: 2px;
	margin: 0;
	font-size: 68%;
	line-height: 1.4em;
	min-width: 1.4em;
}
/* Not a count - a nudge. Shown until the section has been opened once, then
   never again, so it cannot become part of the furniture. */
.frPip {
	position: absolute;
	top: 1px;
	right: 3px;
	color: hsl(45 90% 68%);
	font-size: 78%;
	animation: frPipGlow 2.4s ease-in-out infinite;
}
@keyframes frPipGlow { 0%,100% { opacity: 0.45 } 50% { opacity: 1 } }
@media (prefers-reduced-motion: reduce) { .frPip { animation: none; opacity: 0.9 } }

/* ---- one select instead of a row of chips ---- */

.frSelect {
	font-family: var(--font-family), "Arial", sans-serif;
	font-size: 82%;
	color: var(--font-white-1);
	background-color: var(--input-bg-accent);
	border: 1px solid var(--border-accent);
	padding: 0.2em 0.4em;
	outline: none;
	max-width: 14em;
}
.frSelect:focus { border-color: var(--focus-outline); }
.frToolCount { font-size: 80%; color: var(--font-white-3); margin-left: auto; }

/* ---- privacy ---- */

.frPrivHead {
	font-size: 100%;
	font-weight: 600;
	color: var(--font-white-1);
	padding: 1em 0 0.5em 0;
}
.frPrivHead:first-child { padding-top: 0.2em; }
.frPrivFoot {
	font-size: 80%;
	color: var(--font-white-3);
	border-top: 1px solid var(--separator-accent2);
	margin-top: 1em;
	padding-top: 0.7em;
	line-height: 1.45em;
}

/* one question, three answers - a choice, not a filter */
.frChoice { display: flex; flex-direction: column; gap: 0.35em; }
.frChoiceCard {
	display: flex;
	align-items: center;
	gap: 0.7em;
	width: 100%;
	box-sizing: border-box;
	text-align: left;
	font-family: var(--font-family), "Arial", sans-serif;
	background-color: var(--input-bg-accent);
	border: 1px solid var(--border-accent);
	color: var(--font-white-2);
	padding: 0.6em 0.8em;
	cursor: pointer;
	outline: none;
}
.frChoiceCard:hover { background-color: var(--btn-hover-accent); }
.frChoiceCard.frChoiceOn {
	border-color: hsl(140 50% 48%);
	background-color: hsla(140 45% 35% / 0.22);
	color: var(--font-white-1);
}
.frChoiceIcon { font-size: 145%; flex: 0 0 auto; line-height: 1; }
.frChoiceBody { display: flex; flex-direction: column; flex: 1 1 auto; min-width: 0; }
.frChoiceTitle { font-weight: 600; font-size: 95%; }
.frChoiceBlurb { font-size: 80%; color: var(--font-white-3); line-height: 1.35em; }
.frChoiceTick { color: hsl(140 60% 62%); font-weight: 700; font-size: 115%; flex: 0 0 1em; }

/* switches: whole row is the target, green on, grey off */
.frSwitchRow {
	display: flex;
	align-items: center;
	gap: 0.7em;
	padding: 0.55em 0.7em;
	margin-bottom: 0.3em;
	background-color: var(--input-bg-accent);
	border: 1px solid var(--border-dark-accent);
	cursor: pointer;
}
.frSwitchRow:hover { background-color: var(--btn-hover-accent); }
.frSwitchIcon { font-size: 125%; flex: 0 0 auto; line-height: 1; }
.frSwitchBody { display: flex; flex-direction: column; flex: 1 1 auto; min-width: 0; }
.frSwitchTitle { font-size: 92%; color: var(--font-white-2); font-weight: 600; }
.frSwitchRow.frSwitchOn .frSwitchTitle { color: var(--font-white-1); }
.frSwitchBlurb { font-size: 78%; color: var(--font-white-3); line-height: 1.35em; }

.frSwitch {
	flex: 0 0 auto;
	width: 38px;
	height: 21px;
	border-radius: 999px;
	background-color: var(--btn-bg-accent);
	border: 1px solid var(--border-accent);
	position: relative;
	transition: background-color 0.16s ease, border-color 0.16s ease;
}
.frSwitchKnob {
	position: absolute;
	top: 2px;
	left: 2px;
	width: 15px;
	height: 15px;
	border-radius: 50%;
	background-color: var(--font-white-3);
	transition: transform 0.16s ease, background-color 0.16s ease;
}
.frSwitchRow.frSwitchOn .frSwitch {
	background-color: hsl(140 48% 36%);
	border-color: hsl(140 45% 50%);
}
.frSwitchRow.frSwitchOn .frSwitchKnob { transform: translateX(17px); background-color: #fff; }
@media (prefers-reduced-motion: reduce) {
	.frSwitch, .frSwitchKnob { transition: none; }
}

/* ---- profile: roles and favourite cyphers ---- */

.frPreview {
	border: 1px dashed var(--border-accent);
	padding: 0.7em;
	margin-bottom: 0.3em;
}
.frRoleGrid { display: flex; flex-wrap: wrap; gap: 0.3em; }
.frRole {
	font-family: var(--font-family), "Arial", sans-serif;
	font-size: 82%;
	color: var(--font-white-2);
	background-color: var(--btn-bg-accent);
	border: 1px solid var(--border-accent);
	padding: 0.25em 0.6em;
	cursor: pointer;
	outline: none;
}
.frRole:hover { background-color: var(--btn-hover-accent); }
.frRole.frRoleOn {
	background-color: hsla(140 45% 35% / 0.3);
	border-color: hsl(140 45% 48%);
	color: var(--font-white-1);
	font-weight: 600;
}
.frRoleShow { display: flex; flex-wrap: wrap; gap: 0.3em; padding-bottom: 0.6em; }
.frRoleTag {
	font-size: 80%;
	color: var(--font-white-2);
	background-color: var(--btn-bg-accent);
	border: 1px solid var(--border-accent);
	padding: 0.15em 0.55em;
}

.frFavRow, .frFavShow { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35em; padding-bottom: 0.6em; }
.frFavLab { font-size: 80%; color: var(--font-white-3); font-weight: 600; }
.frFav {
	font-size: 82%;
	font-weight: 600;
	color: var(--font-white-2);
	border: 1px solid var(--border-accent);
	padding: 0.15em 0.55em;
	white-space: nowrap;
}
.frFavX { cursor: pointer; padding-left: 0.4em; opacity: 0.7; }
.frFavX:hover { opacity: 1; }

/* ---- leaderboard: a scroll box, and groups inside it ---- */

.profileChipScroll {
	max-height: 300px;
	overflow-y: auto;
	padding-right: 0.2em;
	/* a thin scrollbar rather than the platform's, so a long list does not
	   suddenly grow a wide grey bar down the side of the panel */
	scrollbar-width: thin;
	scrollbar-color: var(--border-accent) transparent;
}
.profileChipScroll::-webkit-scrollbar { width: 8px; }
.profileChipScroll::-webkit-scrollbar-track { background: transparent; }
.profileChipScroll::-webkit-scrollbar-thumb {
	background-color: var(--border-accent);
	border-radius: 999px;
}
.profileChipScroll::-webkit-scrollbar-thumb:hover { background-color: var(--font-white-4); }

/* the value or cypher a run of chips belongs to */
.profileChipGroup {
	flex: 1 0 100%;
	font-size: 78%;
	font-weight: 700;
	color: var(--font-white-3);
	letter-spacing: 0.04em;
	padding: 0.6em 0 0.25em 0;
	border-top: 1px solid var(--separator-accent2);
	margin-top: 0.3em;
}
.profileChipGroup:first-child { border-top: none; margin-top: 0; padding-top: 0; }
.profileContribSort { display: flex; align-items: center; gap: 0.5em; padding-bottom: 0.5em; flex-wrap: wrap; }

/* ---- leaderboard podium ----
   The top three get a metal. Kept to a left edge, a faint wash and a coloured
   rank rather than a glow around the whole row: a leaderboard is a list you
   scan, and three rows lit up like buttons would fight the names for
   attention. */
.profileRow.profileLbRow.frPodium1,
.profileRow.profileLbRow.frPodium2,
.profileRow.profileLbRow.frPodium3 { border-left-width: 3px; border-left-style: solid; }

.profileLbRow.frPodium1 {
	border-left-color: hsl(45 85% 55%);
	background: linear-gradient(90deg, hsla(45 80% 50% / 0.16), transparent 45%);
}
.profileLbRow.frPodium2 {
	border-left-color: hsl(210 12% 72%);
	background: linear-gradient(90deg, hsla(210 10% 70% / 0.14), transparent 45%);
}
.profileLbRow.frPodium3 {
	border-left-color: hsl(25 55% 50%);
	background: linear-gradient(90deg, hsla(25 55% 45% / 0.14), transparent 45%);
}
.profileLbRow.frPodium1 .profileLbRank,
.profileLbRow.frPodium2 .profileLbRank,
.profileLbRow.frPodium3 .profileLbRank { font-size: 105%; }
.profileLbRow.frPodium1 .profileRowPhrase { color: hsl(45 75% 78%); font-weight: 600; }
.profileLbRow.frPodium2 .profileRowPhrase { color: hsl(210 15% 88%); font-weight: 600; }
.profileLbRow.frPodium3 .profileRowPhrase { color: hsl(25 60% 74%); font-weight: 600; }

/* ---- a conversation with something in it ----
   A soft breathing edge rather than a hard highlight: it has to be noticeable
   in a list without being the brightest thing in the panel. Stops the moment
   the thread is opened, because at that point it is no longer news. */
.profileRow.frRow.frThreadUnread {
	border-left: 3px solid hsl(140 55% 48%);
	animation: frThreadGlow 2.6s ease-in-out infinite;
}
@keyframes frThreadGlow {
	0%, 100% { background-color: transparent; }
	50%      { background-color: hsla(140 50% 40% / 0.16); }
}
@media (prefers-reduced-motion: reduce) {
	.profileRow.frRow.frThreadUnread { animation: none; background-color: hsla(140 50% 40% / 0.14); }
}

.frThreadWho { flex: 0 0 auto; cursor: pointer; display: flex; align-items: center; }
.frThreadName { cursor: pointer; }
.frThreadName:hover { color: hsl(140 60% 66%); text-decoration: underline; }
.frChatRules { padding-top: 0.5em; }
.frChatRule {
	font-size: 79%;
	color: var(--font-white-3);
	line-height: 1.45em;
	padding: 0.12em 0;
}

.profileRules { padding-top: 0.6em; }
.profileRule { font-size: 80%; color: var(--font-white-3); line-height: 1.45em; padding: 0.1em 0; }
.profileRule b { color: var(--font-white-2); }

/* ---- membership nav ----
   The tabs run in three groups: what you work with, who you work with, and the
   account. The separator is a gap, not a heading — an earlier version used
   inline "WORKSPACE" / "COMMUNITY" / "ACCOUNT" labels, which sat at tab size,
   looked clickable, were not, and did not survive the row wrapping. Whitespace
   has none of those problems. */
.profileTab.profileTabRun { margin-left: 1.1em; }
@media (max-width: 560px) {
	/* a phone wraps this row several times, so a horizontal gap says nothing —
	   the runs land on their own lines anyway */
	.profileTab.profileTabRun { margin-left: 0; }
}


/* ---- report dialog ---- */
.frReportBack {
	position: fixed; inset: 0; z-index: 400;
	background: hsla(0 0% 0% / 0.55);
}
.frReportBox {
	position: fixed; z-index: 401;
	left: 50%; top: 50%; transform: translate(-50%, -50%);
	width: min(23em, 92vw);
	box-sizing: border-box;
	background-color: var(--menu-bg-accent);
	border: 1px solid var(--border-accent);
	padding: 1em 1.1em 1.1em 1.1em;
	max-height: 88vh; overflow-y: auto;
}
.frReportSel { width: 100%; max-width: 100%; }
.frReportBtns { display: flex; gap: 0.4em; justify-content: flex-end; padding-top: 0.7em; }
.profileMiniBtn.frThreadBtn { padding: 0.1em 0.45em; }

/* ---- first-run onboarding ----
   Sits over the welcome page rather than beside it: one question at a time,
   and nothing else on screen competing for the answer. */
.obBack {
	position: fixed; inset: 0; z-index: 500;
	background: hsla(0 0% 0% / 0.72);
}
.obBox {
	position: fixed; z-index: 501;
	left: 50%; top: 50%; transform: translate(-50%, -50%);
	width: min(27em, 94vw);
	max-height: 92vh;
	box-sizing: border-box;
	display: flex; flex-direction: column;
	background-color: var(--menu-bg-accent);
	border: 1px solid var(--border-accent);
	padding: 1.2em 1.3em 1.1em 1.3em;
}

.obDots { display: flex; gap: 0.35em; justify-content: center; padding-bottom: 1.1em; flex: 0 0 auto; }
.obDot {
	width: 1.6em; height: 3px;
	background-color: var(--separator-accent2);
	transition: background-color 0.2s ease;
}
.obDotDone { background-color: hsl(140 45% 42%); }
.obDotOn   { background-color: hsl(140 60% 60%); }
@media (prefers-reduced-motion: reduce) { .obDot { transition: none; } }

.obBody { flex: 1 1 auto; overflow-y: auto; min-height: 0; }

.obIcon  { font-size: 210%; text-align: center; line-height: 1.1em; padding-bottom: 0.2em; }
.obTitle {
	font-size: 130%; font-weight: 600; text-align: center;
	color: var(--font-white-1);
	padding-bottom: 0.4em;
}
.obLead {
	font-size: 88%; text-align: center; line-height: 1.5em;
	color: var(--font-white-3);
	padding-bottom: 1em;
}
.obNote {
	font-size: 80%; text-align: center; line-height: 1.5em;
	color: var(--font-white-4);
	padding-top: 0.9em;
}
.obField { padding-bottom: 0.2em; }

.obList { display: flex; flex-direction: column; gap: 0.7em; }
.obPoint { display: flex; align-items: flex-start; gap: 0.6em; }
.obPointIcon  { font-size: 125%; flex: 0 0 auto; line-height: 1.2em; }
.obPointBody  { display: flex; flex-direction: column; min-width: 0; }
.obPointTitle { font-size: 90%; font-weight: 600; color: var(--font-white-2); }
.obPointBlurb { font-size: 80%; line-height: 1.45em; color: var(--font-white-3); }

.obNav {
	flex: 0 0 auto;
	display: flex; gap: 0.4em; align-items: center;
	padding-top: 1.1em;
}
.obNav .authBtn { margin: 0; flex: 0 0 auto; width: auto; padding-left: 1em; padding-right: 1em; }
/* Skip sits between Back and Next, quiet but the same size to hit */
.obBtnSkip { margin-left: auto !important; color: var(--font-white-4); }
.obNav .authBtnPrimary { flex: 0 0 auto; }
.obBtnWide { flex: 1 1 auto !important; width: 100% !important; }

