/*
 * Plural Profiles — application styles
 */

/* Ensure the HTML `hidden` attribute always wins, even when an element has
   an explicit display value set by other rules. */
[hidden] { display: none !important; }

:root {
  --page-bg: #0b221b;
  --pane-bg: #133b2f;
  --header-bg: #0e2e24;
  --pane-border: #02120e;
  --heading: #5ea389;
  --text: #5ea389;
  --link: #3ab580;
  --spoiler: #3A3A3A;
  --primary-button-bg: #12684e;
  --primary-button-text: #4ec59a;
  --secondary-button-bg: #155642;
  --secondary-button-text: #4dbb8f;
  --primary-button-border: var(--primary-button-text);
  --secondary-button-border: var(--secondary-button-text);
  --danger-button-bg: #9d1d46;
  --danger-button-text: #d8b5c0;
  --danger-button-border: var(--danger-button-text);
  --input-label: #599981;
  --input-bg: #263a2e;
  --input-border: #3c6f5f;
  --input-text: var(--text);
  --notice-bg: var(--pane-bg);
  --notice-border: var(--text);
  --notice-text: var(--text);
  --alert-bg: #11694a;
  --alert-border: #58cc9d;
  --alert-text: var(--alert-border);
  --warning-bg: #a81d49;
  --warning-border: #e6c4cf;
  --warning-text: var(--warning-border);
  --tree-guide: color-mix(in srgb, var(--text) 30%, transparent);
  --avatar-placeholder-border: color-mix(in srgb, var(--text) 50%, transparent);
}

html {
  background-color: #444;
}

*, *::before, *::after {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  background-color: var(--page-bg);
  color: var(--text);
  line-height: 1.6;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  overscroll-behavior: none;
}

.site-header {
  background-color: var(--header-bg);
  padding: 0.5rem 1.25rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-bottom: 1px solid var(--pane-border);
}

.site-header__brand {
  display: flex;
  align-items: center;
  gap: 0.85rem;
}

.site-header .logo {
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--heading);
  text-decoration: none;
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.site-header .logo svg {
  width: 1.4em;
  height: 1.4em;
}

.site-header nav a,
.site-header nav .link-button {
  color: var(--link);
  text-decoration: none;
  margin-left: 1.5rem;
  font-size: 0.9rem;
}

.site-header nav a:hover,
.site-header nav .link-button:hover {
  text-decoration: underline;
  background-color: transparent;
}

.site-header__signout {
  display: inline;
}

.link-button {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  cursor: pointer;
}

/* Forced-colors mode (e.g. Firefox/Windows high-contrast) applies its
   link-text color to real <a> elements but not to <button>-based
   look-alikes like .link-button, so it's left showing our themed color
   instead of the OS-forced one. Force it back to CanvasText to match. */
@media (forced-colors: active) {
  .site-header nav .link-button {
    color: CanvasText;
  }
}

.admin-badge {
  margin-left: 1.5rem;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  padding: 0.2em 0.5em;
  border-radius: 3px;
  background: color-mix(in srgb, var(--danger-button-bg) 85%, transparent);
  color: var(--danger-button-text);
  border: 1px solid color-mix(in srgb, var(--danger-button-border) 40%, transparent);
  vertical-align: middle;
  text-transform: uppercase;
}

.site-header .action-dropdown__menu a {
  margin-left: 0;
}

@media (forced-colors: active) {
  .admin-badge {
    border: 1px solid ButtonText;
    color: ButtonText;
    background: ButtonFace;
  }
}

.container {
  width: 100%;
  max-width: 960px;
  margin: 2rem auto;
  padding: 0 1.5rem;
  flex: 1;
}

.container:has(.layout),
.container:has(.explorer) {
  max-width: 1200px;
}

.container.narrow {
  max-width: 540px;
}

/* Layout: sidebar + main */
.layout {
  display: grid;
  grid-template-columns: 320px 1fr;
  gap: 2rem;
}

.sidebar {
  position: sticky;
  overflow-y: auto;
  top: 2rem;
  max-height: calc(100vh - 4rem);
  align-self: start;
  background-color: var(--pane-bg);
  border-radius: 8px;
  padding: 0.75rem;
  padding-top: 2rem;
  border: 1px solid var(--pane-border);
}

.sidebar hr {
  border: none;
  border-top: 1px solid var(--pane-border);
  margin: 0.5rem 0.5rem;
}

.sidebar__search {
  padding: 0 0.5rem;
}

.sidebar__search input[type="search"] {
  font-size: 0.9rem;
  padding: 0.4rem 0.6rem;
}

.form-divider {
  border: none;
  border-top: 1px solid color-mix(in srgb, var(--input-border) 40%, transparent);
  margin: 2rem 0;
}

.form-section-summary {
  cursor: pointer;
  font-size: 1rem;
  font-weight: 600;
  color: var(--heading);
  list-style: none;
  user-select: none;
  padding: 0.25rem 0;
}

.form-section-summary::-webkit-details-marker,
.form-section-summary::marker {
  display: none;
}

.form-section-summary::before {
  content: "▶ ";
  font-size: 0.75rem;
  opacity: 0.6;
}

details[open] > .form-section-summary::before {
  content: "▼ ";
}

@media (forced-colors: active) {
  .form-section-summary {
    outline: 1px solid ButtonText;
    padding: 0.25rem 0.5rem;
  }
}

.terms {
  background: var(--pane-bg);
  border: 1px solid var(--pane-border);
  border-radius: 6px;
  padding: 1rem 1.2rem;
  margin-bottom: 1rem;
  font-size: 0.92rem;
  line-height: 1.5;
}

.terms p {
  margin: 0 0 0.4rem;
}

.terms .checkbox-label {
  margin-top: 1rem;
}

.sidebar details {
  margin-bottom: 0.5rem;
}

.sidebar details:last-child {
  margin-bottom: 0;
}

.sidebar summary {
  cursor: pointer;
  font-weight: 700;
  color: var(--heading);
  font-size: 0.85rem;
  letter-spacing: 0.05em;
  padding: 0.4rem 0.5rem;
  list-style: none;
  display: flex;
  align-items: flex-start;
  gap: 0.4rem;
  user-select: none;
}

.sidebar summary::-webkit-details-marker {
  display: none;
}

.sidebar summary::before {
  content: "▶";
  font-size: 0.75rem;
  display: inline-block;
  width: 1rem;
  text-align: center;
  line-height: 1;
  transition: transform 0.15s ease;
  margin-top: 0.3rem;
}

.sidebar details[open] > summary::before {
  transform: rotate(90deg);
}

.sidebar__list {
  list-style: none;
  margin: 0.25rem 0 0;
  padding: 0;
}

.sidebar__item {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  padding: 0.35rem 0.5rem 0.35rem 1.25rem;
  border-radius: 4px;
  font-size: 0.9rem;
}

.sidebar__item:hover {
  background-color: color-mix(in srgb, var(--text) 10%, transparent);
}

.sidebar__item--active {
  background-color: color-mix(in srgb, var(--text) 20%, transparent);
}

.sidebar__item--active .sidebar__link {
  color: var(--heading);
  font-weight: 600;
}

.sidebar__avatar {
  width: 24px;
  height: 24px;
  border-radius: 25%;
  flex-shrink: 0;
  object-fit: cover;
}

.sidebar__avatar--placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
}

.sidebar__link {
  color: var(--link);
  text-decoration: none;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.sidebar__link:hover {
  color: var(--heading);
}

.sidebar__link--action {
  color: var(--link);
  font-size: 0.85rem;
  font-weight: 600;
}

.sidebar__link--action:hover {
  color: var(--heading);
}

/* ---- Sidebar tree ---- */
.sidebar-tree {
  list-style: none;
  margin: 0.25rem 0 0;
  padding: 0;
}

.sidebar-tree__controls {
  display: flex;
  gap: 0.5rem;
  padding: 0.5rem;
  padding-left: 2rem;
}

.sidebar-tree__control-btn {
  background: none;
  border: none;
  padding: 0 0.2rem;
  font-size: 0.75rem;
  color: var(--link);
  cursor: pointer;
}

@media (forced-colors: active) {
  .sidebar-tree__control-btn {
    color: LinkText;
  }
}

.sidebar-tree,
.sidebar-tree__folder,
.sidebar-tree__children {
  --st-indent: 0.875rem;
  --st-arrow-width: 1rem;
  --st-row-center: 0.875rem;
  --st-guide-inset: 0;
  --st-leaf-connector: 0.8rem;
}

.sidebar-tree__children {
  list-style: none;
  margin: 0;
  padding: 0;
  padding-left: var(--st-indent);
}

/* Tree guide lines */
.sidebar-tree__children > li {
  position: relative;
}

.sidebar-tree__children > li::before {
  content: "";
  position: absolute;
  left: var(--st-guide-inset);
  top: 0;
  bottom: 0;
  border-left: 1px solid var(--tree-guide);
  pointer-events: none;
}

.sidebar-tree__children > .sidebar-tree__leaf::after {
  content: "";
  position: absolute;
  left: var(--st-guide-inset);
  top: var(--st-row-center);
  width: var(--st-leaf-connector);
  border-top: 1px solid var(--tree-guide);
  pointer-events: none;
}

.sidebar-tree__children > li:last-child::before {
  bottom: auto;
  height: var(--st-row-center);
}

.sidebar-tree__folder {
  margin: 0;
}

.sidebar-tree__leaf {
  display: flex;
  align-items: flex-start;
  flex-wrap: wrap;
  gap: 0.4rem;
  padding: 0.3rem 0.4rem;
  padding-left: var(--st-arrow-width);
  border-radius: 4px;
  font-size: 0.9rem;
}

.sidebar-tree__leaf:hover {
  background-color: color-mix(in srgb, var(--text) 10%, transparent);
}

.sidebar-tree__leaf--active {
  background-color: color-mix(in srgb, var(--text) 20%, transparent);
}

.sidebar-tree__leaf--active .sidebar-tree__label {
  color: var(--heading);
  font-weight: 600;
}

/* A live broadcast has no way to know whether the recipient is already
   looking at this exact channel, so it may push an "unread" dot here even
   while they're actively reading it live. The active row's own class is set
   at page render time and untouched by that broadcast (it only replaces the
   small dot element below), so hiding the dot whenever the row is active is
   what actually suppresses the false positive. */
.sidebar-tree__leaf--active .unread-dot {
  display: none;
}

.sidebar-tree__row {
  display: flex;
  align-items: flex-start;
  flex-wrap: wrap;
  gap: 0.4rem;
  border-radius: 4px;
}

/* Higher specificity (0,2,0) to beat .sidebar summary (0,1,1) */
.sidebar .sidebar-tree__row {
  font-weight: normal;
  color: var(--text);
  font-size: 0.9rem;
  letter-spacing: normal;
  padding: 0.3rem 0.4rem;
}

.sidebar-tree__row:hover {
  background-color: color-mix(in srgb, var(--text) 10%, transparent);
  text-decoration: none;
}

.sidebar-tree__row--active {
  background-color: color-mix(in srgb, var(--text) 20%, transparent);
}

.sidebar-tree__row--active .sidebar-tree__link {
  color: var(--heading);
  font-weight: 600;
}

.sidebar-tree__avatar {
  width: 24px;
  height: 24px;
  border-radius: 25%;
  flex-shrink: 0;
  object-fit: cover;
}

.sidebar-tree__avatar--placeholder {
  width: 24px;
  height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  border-radius: 25%;
  min-width: 24px;
  min-height: 24px;
}

.sidebar-tree__link {
  color: var(--link);
  text-decoration: none;
  overflow: visible;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  flex: 1;
  min-width: 0;
}

.sidebar-tree__link:hover {
  color: var(--heading);
  text-decoration: none;
}

.sidebar-tree__label {
  width: 100%;
  min-width: 0;
  overflow-wrap: break-word;
}

.sidebar-tree__subtitle {
  font-size: 0.75rem;
  color: color-mix(in srgb, var(--text) 75%, transparent);
  width: 100%;
  min-width: 0;
  overflow-wrap: break-word;
}

.sidebar-tree__label--repeated {
  opacity: 0.55;
  font-style: italic;
}

@media (forced-colors: active) {
  .sidebar-tree__label--repeated {
    opacity: 1;
    color: GrayText;
  }

  .sidebar-tree__children > li::before,
  .sidebar-tree__children > .sidebar-tree__leaf::after {
    border-color: CanvasText;
  }

  .sidebar-tree__leaf--active,
  .sidebar-tree__row--active {
    background: Highlight;
    color: HighlightText;
  }

  .sidebar-tree__leaf--active .sidebar-tree__label,
  .sidebar-tree__leaf--active .sidebar-tree__link,
  .sidebar-tree__row--active .sidebar-tree__label,
  .sidebar-tree__row--active .sidebar-tree__link {
    color: HighlightText;
  }
}

.main-content {
  min-width: 0;
}

h1, h2, h3 {
  color: var(--heading);
  margin-top: 0;
}

h1 { font-size: 1.75rem; }
h2 { font-size: 1.4rem; }

/* Page title row with inline label badges */
.profile-title {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1rem;
}

.profile-title h1 {
  margin-bottom: 0;
}

.profile-title .label-badges {
  margin-top: 0;
}

/* Inline name + labels row inside card headers */
.name-with-labels {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.name-with-labels h1,
.name-with-labels h2 {
  margin-bottom: 0;
}

.name-with-labels .label-badges {
  margin-top: 0;
  transform: translateY(-0.15em);
}

.subtitle {
  margin: 0 0 0.5rem;
  font-size: 0.9rem;
  color: color-mix(in srgb, var(--text) 80%, transparent);
}

.tag-line {
  margin: 0 0 0.75rem;
  font-size: 1.1rem;
  font-style: italic;
  color: color-mix(in srgb, var(--text) 80%, transparent);
}

.profile-card .tag-line {
  margin-top: auto;
  padding-top: 0.5rem;
  font-style: italic;
  font-size: 1rem;
  color: color-mix(in srgb, var(--text) 80%, transparent);
  text-align: center;
}

h2 a { color: inherit; }
h2 a:hover { text-decoration: none; opacity: 0.8; }

a {
  color: var(--link);
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

a.btn:hover {
  text-decoration: none;
}

/* Flash messages */
.flash {
  padding: 0.75rem 1rem;
  border-radius: 6px;
  margin-bottom: 1.5rem;
  font-size: 0.9rem;
}

.flash--notice {
  background-color: var(--notice-bg);
  border: 1px solid var(--notice-border);
  color: var(--notice-text);
}

.flash--alert {
  background-color: var(--alert-bg);
  border: 1px solid var(--alert-border);
  color: var(--alert-text);
}

.flash--warning {
  background-color: var(--warning-bg);
  border: 1px solid var(--warning-border);
  color: var(--warning-text);
}

/* Forms */
.form-group {
  margin-bottom: 1.25rem;
}

fieldset.form-group {
  border: 1px solid var(--input-border);
  border-radius: 6px;
  padding: 0.75rem 1rem;
}

fieldset.form-group legend {
  font-size: 0.9rem;
  color: var(--input-label);
  padding: 0 0.35rem;
}

.checkbox-list {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.checkbox-label {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  cursor: pointer;
  font-size: 0.95rem;
}

.checkbox-label input[type="checkbox"] {
  width: auto;
  margin-top: 0.4rem;
}

.checkbox-label__text {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.25rem 0.4rem;
}

.checkbox-label__subtitle {
  display: block;
  width: 100%;
  font-size: 0.8rem;
  color: color-mix(in srgb, var(--text) 80%, transparent);
}

label {
  display: block;
  margin-bottom: 0.35rem;
  font-size: 0.9rem;
  color: var(--input-label);
}

.datetime-picker {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

.datetime-picker__field.datetime-picker__field--month select {
  width: 10rem;
}

.datetime-picker__field.datetime-picker__field--day select,
.datetime-picker__field.datetime-picker__field--hour select,
.datetime-picker__field.datetime-picker__field--minute select {
  width: 4.5rem;
}

.datetime-picker__field.datetime-picker__field--year input[type="number"] {
  width: 6rem;
}

.datetime-picker__separator {
  color: var(--input-label);
}

input[type="text"],
input[type="email"],
input[type="password"],
input[type="url"],
input[type="number"],
input[type="search"],
textarea,
select {
  width: 100%;
  padding: 0.6rem 0.75rem;
  background-color: var(--input-bg);
  border: 1px solid var(--input-border);
  border-radius: 6px;
  color: var(--input-text);
  font-family: inherit;
  font-size: 1rem;
  outline: none;
  transition: border-color 0.2s;
}

input:focus,
textarea:focus,
select:focus {
  border-color: var(--link);
}

/* Chrome autofill: override the forced white background */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
textarea:-webkit-autofill,
select:-webkit-autofill {
  -webkit-text-fill-color: var(--input-text);
  -webkit-box-shadow: 0 0 0 1000px var(--input-bg) inset;
  border-color: var(--input-border);
  caret-color: var(--input-text);
  transition: background-color 5000s ease-in-out 0s;
}

textarea {
  resize: vertical;
  min-height: 100px;
}

input[type="file"] {
  color: var(--text);
}

input[type="file"]::file-selector-button {
  background-color: var(--primary-button-bg);
  color: var(--primary-button-text);
  border: 1px solid var(--primary-button-border);
  border-radius: 6px;
  padding: 0.4rem 1rem;
  font-size: 0.9rem;
  cursor: pointer;
  margin-right: 0.75rem;
  transition: background-color 0.2s;
}

input[type="file"]::file-selector-button:hover {
  background-color: color-mix(in srgb, var(--primary-button-bg) 60%, transparent);
}

/* Disabled form controls */
input:disabled,
textarea:disabled,
select:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

input[type="checkbox"]:disabled,
input[type="radio"]:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

input[type="submit"]:disabled,
button:disabled,
.btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

input[type="submit"],
button,
.btn {
  display: inline-block;
  padding: 0.6rem 1.5rem;
  background-color: var(--primary-button-bg);
  color: var(--primary-button-text);
  border: 1px solid var(--primary-button-border);
  border-radius: 6px;
  font-size: 0.95rem;
  font-family: inherit;
  line-height: 1.6;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 0.2s;
}

.form-group input[type="submit"] + .btn,
.form-group .btn + .btn,
.form-group .btn + input[type="submit"] {
  margin-left: 0.75rem;
}

input[type="submit"]:hover,
button:hover,
.btn:hover {
  background-color: color-mix(in srgb, var(--primary-button-bg) 60%, transparent);
}

.btn--secondary {
  background-color: var(--secondary-button-bg);
  border: 1px solid var(--secondary-button-border);
  color: var(--secondary-button-text);
}

.btn--secondary:hover {
  background-color: color-mix(in srgb, var(--secondary-button-bg) 60%, transparent);
  color: var(--secondary-button-text);
}

/* Card */
.card {
  background-color: var(--pane-bg);
  border: 1px solid var(--pane-border);
  border-radius: 8px;
  padding: 2rem;
  margin-bottom: 1.5rem;
}

/* Error list */
.error-messages p {
  color: var(--error);
  margin: 0.25rem 0;
  font-size: 0.9rem;
}

/* Helper links below forms */
.form-links {
  margin-top: 1.5rem;
  font-size: 0.9rem;
}

.form-links p {
  margin: 0.35rem 0;
}

/* Dashboard grid */
.dashboard-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1.5rem;
}

/* Card list */
.card-list {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.card--row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1rem 1.5rem;
}

.card__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-top: 0.6rem;
}

.card__header {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.card__header h1 {
  margin-bottom: 0.5rem;
}

.card__header h2,
.card__header h3 {
  margin: 0;
}

.card__actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  flex-shrink: 0;
}

.card__tags + .card__actions {
  margin-top: 1rem;
}

.btn--outline {
  background-color: var(--secondary-button-bg);
  border: 1px solid var(--secondary-button-border);
  color: var(--secondary-button-text);
}

.btn--outline:hover {
  background-color: color-mix(in srgb, var(--secondary-button-bg) 60%, transparent);
  color: var(--secondary-button-text);
}

/* Stats grid */
.stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 1rem;
}

.stats-card {
  text-align: center;
  padding: 2rem 1rem;
}

.stats-card__number {
  font-size: 2.5rem;
  font-weight: 700;
  line-height: 1;
  color: var(--link);
}

.stats-card__label {
  margin-top: 0.5rem;
  font-size: 0.95rem;
  color: var(--text-muted);
}

/* Profile grid (public group view) */
.profile-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 1rem;
}

.profile-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 1.5rem 1rem;
  cursor: pointer;
  color: var(--text);
}

.profile-card:hover {
  color: var(--text);
}

@media (forced-colors: active) {
  .profile-card {
    border: 1px solid CanvasText;
  }
}

.profile-card h3 {
  margin: 0.75rem 0 0.25rem;
  font-size: 1rem;
}

.profile-card h3 a:hover {
  text-decoration: none;
}

/* Private cards in the authenticated .layout view: stretch the h3 link to
   cover the whole card so clicking anywhere navigates (not just the name).
   Spoilers still intercept clicks because .spoiler has z-index: 1 (above
   the z-index: auto ::after overlay). Action buttons use z-index: 1 too. */
.layout .profile-card {
  position: relative;
}

.layout .profile-card h3 a::after {
  content: "";
  position: absolute;
  inset: 0;
}

.layout .profile-card .btn {
  position: relative;
  z-index: 1;
}

.profile-card .label-badges,
.profile-card .pronouns {
  justify-content: center;
}

.profile-card .btn {
  margin-top: auto;
}

.profile-card__action-spacer {
  flex: 1;
  min-height: 1rem;
}

/* Profile header (show pages) — edge-to-edge banner inside .card */
.card > .card__header {
  background-color: var(--header-bg);
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 1.25rem;
  margin: -2rem -2rem 1.5rem -2rem;
  padding: 2rem;
  border-radius: 7px 7px 0 0;
}

.card > .card__header > .tag-line {
  flex-basis: 100%;
  margin: -0.5rem 0 0;
}

.card__header {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  margin-bottom: 1.5rem;
}

.profile-description,
.group-description {
  margin-bottom: 1.5rem;
}

@media (forced-colors: active) {
  .card > .card__header {
    border-bottom: 1px solid CanvasText;
  }
}

.profile-description details summary,
.group-description details summary {
  cursor: pointer;
  text-decoration: underline;
}

/* "Click to close" hint shown at the bottom of open <details> blocks */
.details-close {
  display: none;
  background: none;
  border: none;
  padding: 0;
  color: inherit;
  font-size: 0.8em;
  text-align: left;
  opacity: 0.8;
  margin-top: 0.25rem;
  cursor: pointer;
}

details[open] .details-close {
  display: block;
}

@media (forced-colors: active) {
  .details-close {
    color: CanvasText;
  }
}

/* Inline formatting tags allowed in descriptions */
.profile-description b,
.group-description b {
  font-weight: 700;
}

.profile-description i,
.group-description i {
  font-style: italic;
}

.profile-description u,
.group-description u {
  text-decoration: underline;
}

.profile-description s,
.group-description s {
  text-decoration: line-through;
}

/* Tables in descriptions */
.profile-description table,
.group-description table {
  border-collapse: collapse;
}

.profile-description td,
.profile-description th,
.group-description td,
.group-description th {
  padding: 0 1em 0.5em 0;
}

.profile-description td:last-child,
.profile-description th:last-child,
.group-description td:last-child,
.group-description th:last-child {
  padding-right: 0;
}

/* Image/text layout utility classes usable in descriptions */

/* Side-by-side layout: <div class="img-row"><img ...><p>text</p></div> */
.profile-description .img-row,
.group-description .img-row {
  display: flex;
  gap: 1em;
  align-items: flex-start;
  flex-wrap: wrap;
}

/* simple_format turns newlines inside the div into <br> tags; suppress them
   so they don't become phantom flex children that introduce a leading gap. */
.profile-description .img-row > br,
.group-description .img-row > br {
  display: none;
}

/* Float an image left with text wrapping around it.
   Wrap image + text in a block element (e.g. <div>) to clear the float. */
.profile-description img.float-left,
.group-description img.float-left {
  float: left;
  margin: 0 1em 0.5em 0;
}

.profile-description img.float-right,
.group-description img.float-right {
  float: right;
  margin: 0 0 0.5em 1em;
}

/* Use on a wrapper div to clear floated images inside it */
.profile-description .clearfix,
.group-description .clearfix {
  display: flow-root;
}

/* Spoiler text (Discord-style ||hidden||) */
.spoiler {
  background-color: var(--spoiler);
  color: transparent;
  border: 1px solid var(--spoiler);
  border-radius: 3px;
  padding: 0 0.2em;
  cursor: pointer;
  transition: background-color 0.2s ease, color 0.2s ease;
  user-select: none;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
  text-decoration-line: none !important;
  /* Ensure spoilers sit above stretched-link ::after overlays on cards */
  position: relative;
  z-index: 1;
}

a:hover .spoiler {
  text-decoration-line: none !important;
}

.spoiler:focus-visible {
  outline: 2px solid var(--spoiler);
  outline-offset: 1px;
}

.spoiler--revealed {
  background-color: color-mix(in srgb, var(--spoiler) 10%, transparent);
  color: inherit;
  user-select: auto;
}

a .spoiler {
  /* Don't show "click to reveal" cursor on spoilers inside links, since the
     whole link is already clickable. */
  cursor: inherit;
}

/* Inside a link, a revealed spoiler signals "click to navigate" */
a .spoiler--revealed {
  cursor: pointer;
}

.spoiler img {
  visibility: hidden;
}

.spoiler--revealed img {
  visibility: visible;
}

@media (forced-colors: active) {
  .spoiler {
    forced-color-adjust: none;
    background-color: var(--spoiler);
    color: transparent;
    border: 1px solid CanvasText;
  }

  .spoiler:focus-visible {
    outline-color: CanvasText;
  }

  .spoiler--revealed {
    background-color: Canvas;
    color: CanvasText;
    border-color: CanvasText;
  }
}

/* Spoiler hint tooltip (||secret||[hint] or [hint]||secret||) */
.spoiler--with-hint {
  position: relative;
}

.spoiler--with-hint[aria-expanded="false"]::after {
  content: attr(data-spoiler-hint);
  position: absolute;
  bottom: calc(100% + 5px);
  left: 50%;
  transform: translateX(-50%);
  /* Fallback for older browsers: layer pane-bg over page-bg */
  background-color: var(--page-bg);
  background-image: linear-gradient(var(--pane-bg), var(--pane-bg));
  /* Modern browsers (Chrome 119+, FF 128+, Safari 16.4+): force alpha to 1
     via CSS Relative Color Syntax so an 8-digit hex --pane-bg with alpha
     renders fully opaque. The background shorthand intentionally overrides
     the fallback lines above when supported. */
  background: oklch(from var(--pane-bg) l c h / 1);
  border: 1px solid var(--pane-border);
  color: var(--text);
  border-radius: 4px;
  padding: 2px 8px;
  box-shadow: 0 2px 6px color-mix(in srgb, var(--pane-border) 50%, transparent);
  font-size: 0.75rem;
  font-weight: 500;
  font-style: normal;
  width: max-content;
  max-width: min(16rem, 90vw);
  white-space: normal;
  word-wrap: break-word;
  pointer-events: none;
  z-index: 10;
  visibility: hidden;
  opacity: 0;
  transition: opacity 0.25s ease;
}

/* Desktop: show on hover or focus */
.spoiler--with-hint[aria-expanded="false"]:hover::after,
.spoiler--with-hint[aria-expanded="false"]:focus-visible::after {
  visibility: visible;
  opacity: 1;
}

/* Touch state 2: hint explicitly shown by JS after first tap */
.spoiler--with-hint.spoiler--hint-showing::after {
  visibility: visible;
  opacity: 1;
}

@media (forced-colors: active) {
  .spoiler--with-hint[aria-expanded="false"]::after {
    forced-color-adjust: none;
    background: Canvas;
    color: CanvasText;
    border-color: CanvasText;
  }
}

.profile-actions {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-bottom: 1.5rem;
}

/* Avatars */
.avatar {
  border-radius: 25%;
  object-fit: cover;
}

.avatar--small {
  width: 40px;
  height: 40px;
  font-size: 1rem;
}

.avatar--large {
  width: 96px;
  height: 96px;
  font-size: 2.5rem;
}

.avatar--inline {
  vertical-align: middle;
  margin-right: 0.35em;
}

.avatar--placeholder,
.sidebar__avatar--placeholder,
.sidebar-tree__avatar--placeholder,
.tree__avatar--placeholder {
  color: var(--text);
  border: 1px solid var(--avatar-placeholder-border);
}

.avatar--placeholder svg,
.sidebar__avatar--placeholder svg,
.sidebar-tree__avatar--placeholder svg,
.tree__avatar--placeholder svg {
  width: 75%;
  height: 75%;
}

.avatar--placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 25%;
  width: 64px;
  height: 64px;
  min-width: 64px;
  min-height: 64px;
  flex-shrink: 0;
}

.profile-card .avatar--placeholder {
  margin-left: auto;
  margin-right: auto;
}

.avatar--small.avatar--placeholder {
  width: 40px;
  height: 40px;
  min-width: 40px;
  min-height: 40px;
}

.avatar--large.avatar--placeholder {
  width: 96px;
  height: 96px;
}

/* Pronouns */
.group-list-subtitle {
  display: block;
  font-size: 0.85rem;
  color: color-mix(in srgb, var(--text) 80%, transparent);
}

.pronouns {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  font-style: italic;
  color: color-mix(in srgb, var(--text) 80%, transparent);
  font-size: 0.9rem;
}

/* Avatar shape modifiers */
.avatar--circle,
.avatar--circle.avatar--placeholder,
.sidebar-tree__avatar--circle,
.tree__avatar.tree__avatar--circle {
  border-radius: 50%;
}

.avatar--square,
.avatar--square.avatar--placeholder,
.sidebar-tree__avatar--square,
.tree__avatar.tree__avatar--square {
  border-radius: 0;
}

/* When JS is active, hide the avatar editor dialog unless it's open as a modal.
   Without JS, the dialog has [open] and renders inline so users can access the fields. */
.js .avatar-editor-dialog:not(:modal) {
  display: none;
}

/* Without JS, override the browser's default `position: absolute` on <dialog>
   so it flows inline with the form instead of overlapping other content. */
html:not(.js) .avatar-editor-dialog {
  position: static;
  width: auto;
  max-height: none;
  margin: 0;
}

html:not(.js) .avatar-editor__current,
html:not(.js) .avatar-editor-dialog__actions {
  display: none;
}

/* Avatar editor dialog */
.avatar-editor__current {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.avatar-editor-dialog {
  background-color: var(--pane-bg);
  border: 1px solid var(--pane-border);
  border-radius: 8px;
  color: var(--text);
  padding: 1.5rem;
  width: min(480px, 90vw);
  max-height: 90vh;
  overflow-y: auto;
}

.avatar-editor-dialog::backdrop {
  background-color: color-mix(in srgb, var(--page-bg) 60%, transparent);
}

.avatar-editor-dialog__title {
  font-size: 1.2rem;
  font-weight: 600;
  color: var(--heading);
  margin: 0 0 1.25rem;
}

.avatar-editor-dialog__preview {
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 1.25rem;
}

.avatar-editor-dialog__preview img,
.avatar-editor-dialog__preview .avatar--placeholder {
  width: 96px;
  height: 96px;
}

.avatar-shape-picker {
  display: flex;
  gap: 1rem;
  margin-bottom: 1.25rem;
}

.avatar-shape-picker__option {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
  cursor: pointer;
  font-size: 0.85rem;
  color: var(--text);
}

.avatar-shape-picker__option input[type="radio"] {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.avatar-shape-picker__sample {
  width: 48px;
  height: 48px;
  background-color: var(--input-border);
  outline: 2px solid transparent;
  outline-offset: 2px;
  transition: outline-color 0.1s;
}

.avatar-shape-picker__sample--rounded {
  border-radius: 25%;
}

.avatar-shape-picker__sample--circle {
  border-radius: 50%;
}

.avatar-shape-picker__sample--square {
  border-radius: 0;
}

.avatar-shape-picker__option input[type="radio"]:checked ~ .avatar-shape-picker__sample {
  outline-color: var(--link);
}

.avatar-shape-picker__option input[type="radio"]:focus-visible ~ .avatar-shape-picker__sample {
  outline-color: var(--link);
}

.avatar-editor-dialog__actions {
  display: flex;
  gap: 0.75rem;
  margin-top: 1.25rem;
}

@media (forced-colors: active) {
  .avatar-editor-dialog {
    border: 2px solid ButtonText;
  }

  .avatar-shape-picker__sample {
    background-color: ButtonFace;
    border: 2px solid ButtonText;
  }

  .avatar-shape-picker__option input[type="radio"]:checked ~ .avatar-shape-picker__sample {
    outline-color: Highlight;
    background-color: Highlight;
  }
}

/* Explorer layout (public group tree view) */
.explorer {
  display: none;
  grid-template-columns: 280px 1fr;
  gap: 1.5rem;
  min-height: 400px;
}

.explorer--active {
  display: grid;
}

.explorer__fallback[hidden] {
  display: none;
}

.js .explorer__fallback {
  display: none;
}

.explorer__sidebar {
  background-color: var(--pane-bg);
  border: 1px solid var(--pane-border);
  border-radius: 8px;
  padding: 0.5rem;
  padding-top: 1.5rem;
  overflow-y: auto;
  max-height: 80vh;
  position: sticky;
  top: 2rem;
  align-self: start;
}

.explorer__content {
  min-width: 0;
}

/* Tree */
.tree,
.tree__children {
  --tree-indent: 1rem;
  --tree-arrow-width: 1.4rem;
  --tree-row-center: 0.95rem;        /* vertical midpoint of a row */
  --tree-guide-inset: -0.35rem;      /* guide line offset within indent */
  --tree-leaf-connector: 1.6rem;     /* horizontal line reaching into leaf */

  list-style: none;
  margin: 0;
  padding: 0;
}

.tree__children {
  padding-left: var(--tree-indent);
}

/* Tree guide lines */
.tree__children > li {
  position: relative;
}

.tree__children > li::before {
  content: "";
  position: absolute;
  left: var(--tree-guide-inset);
  top: 0;
  bottom: 0;
  border-left: 1px solid var(--tree-guide);
  pointer-events: none;
}

.tree__children > .tree__leaf::after {
  content: "";
  position: absolute;
  left: var(--tree-guide-inset);
  top: var(--tree-row-center);
  width: var(--tree-leaf-connector);
  border-top: 1px solid var(--tree-guide);
  pointer-events: none;
}

.tree__children > li:last-child::before {
  bottom: auto;
  height: var(--tree-row-center);
}

.tree__folder {
  margin: 0;
}

.tree__leaf {
  margin: 0;
  padding-left: var(--tree-arrow-width);
}

.tree__row {
  display: flex;
  align-items: flex-start;
}

.tree__arrow-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--tree-arrow-width);
  flex-shrink: 0;
  padding: 0.6rem 0;
  border: none;
  background: none;
  color: var(--text);
  cursor: pointer;
  border-radius: 4px;
  user-select: none;
}

.tree__arrow-btn:hover {
  background-color: color-mix(in srgb, var(--text) 15%, transparent);
}

.tree__item {
  display: flex;
  align-items: flex-start;
  gap: 0.4rem;
  flex: 1;
  min-width: 0;
  padding: 0.3rem 0.5rem;
  border: none;
  border-radius: 4px;
  background: none;
  color: var(--text);
  cursor: pointer;
  text-align: left;
  text-decoration: none;
  overflow: visible;
}

.tree__item:hover {
  background-color: color-mix(in srgb, var(--text) 10%, transparent);
  text-decoration: none;
}

.tree__item--active {
  background-color: color-mix(in srgb, var(--text) 20%, transparent);
  color: var(--heading);
  font-weight: 600;
}

.tree__arrow {
  font-size: 0.75rem;
  flex-shrink: 0;
  width: 1rem;
  text-align: center;
  display: inline-block;
  line-height: 1;
  vertical-align: middle;
  transition: transform 0.15s ease;
}

.tree__arrow--open {
  transform: rotate(90deg);
}

.tree__avatar {
  width: 24px;
  height: 24px;
  border-radius: 25%;
  flex-shrink: 0;
  object-fit: cover;
}

.tree__avatar--placeholder {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.tree__label-block {
  display: flex;
  flex-direction: column;
  overflow: visible;
  flex: 1;
  min-width: 0;
}

.tree__label {
  min-width: 0;
  overflow-wrap: break-word;
}

.tree__label--repeated {
  opacity: 0.55;
  font-style: italic;
}

.tree__subtitle {
  font-size: 0.75rem;
  color: color-mix(in srgb, var(--text) 75%, transparent);
  min-width: 0;
  overflow-wrap: break-word;
}

@media (forced-colors: active) {
  .tree__label--repeated {
    opacity: 1;
    color: GrayText;
  }
}

.tree__overlapping-hint {
  font-size: 0.7rem;
  opacity: 0.6;
  flex-shrink: 0;
  margin-left: auto;
  padding-left: 0.25rem;
  cursor: help;
}

/* ── Tree editor (authenticated group management) ──────── */

.tree-editor {
  margin-bottom: 2rem;
}

.tree-editor__hint {
  font-size: 0.9rem;
  opacity: 0.8;
  margin-bottom: 1.25rem;
}

/* ── Layout variables (mirrors public tree) ──────────── */
.tree-editor__folder,
.tree-editor__children {
  --te-indent: 1.5rem;
  --te-arrow-width: 1.4rem;
  --te-row-center: 0.95rem;
  --te-guide-inset: -0.35rem;
  --te-leaf-connector: 1.6rem;
}

/* ── Folder (details/summary) ────────────────────────── */
.tree-editor__folder {
  margin: 0;
  position: relative;
}

.tree-editor__summary {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.3rem 0.5rem;
  cursor: pointer;
  list-style: none;
  border-radius: 4px;
}

.tree-editor__summary::-webkit-details-marker {
  display: none;
}

.tree-editor__summary::before {
  content: "▶";
  font-size: 0.75rem;
  flex-shrink: 0;
  display: inline-block;
  transition: transform 0.15s ease;
  width: var(--te-arrow-width);
  text-align: center;
  line-height: 1;
}

details[open] > .tree-editor__summary::before {
  transform: rotate(90deg);
}

.tree-editor__summary:hover,
.tree-editor__leaf:hover {
  background-color: color-mix(in srgb, var(--text) 10%, transparent);
}

.tree-editor__summary .tree-editor__item-info {
  flex: 1;
  min-width: 0;
}

.tree-editor__summary .tree-editor__actions {
  margin-left: auto;
}

/* ── Children container (indented with guide lines) ──── */
.tree-editor__children {
  padding-left: var(--te-indent);
  margin: 0;
}

/* Vertical + horizontal guide lines on direct children */
.tree-editor__children > .tree-editor__folder,
.tree-editor__children > .tree-editor__leaf {
  position: relative;
}

/* Vertical guide line running down the left */
.tree-editor__children > .tree-editor__folder::before,
.tree-editor__children > .tree-editor__leaf::before {
  content: "";
  position: absolute;
  left: var(--te-guide-inset);
  top: 0;
  bottom: 0;
  border-left: 1px solid var(--tree-guide);
  pointer-events: none;
}

/* Last child: vertical line stops at the row center */
.tree-editor__children > .tree-editor__folder:last-child::before,
.tree-editor__children > .tree-editor__leaf:last-child::before {
  bottom: auto;
  height: var(--te-row-center);
}

/* Horizontal connector line into leaf items */
.tree-editor__children > .tree-editor__leaf::after {
  content: "";
  position: absolute;
  left: var(--te-guide-inset);
  top: var(--te-row-center);
  width: var(--te-leaf-connector);
  border-top: 1px solid var(--tree-guide);
  pointer-events: none;
}

/* ── Leaf items (profiles + groups without children) ─── */
.tree-editor__leaf {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.3rem 0.5rem;
  padding-left: calc(var(--te-arrow-width) + 0.5rem);
  margin: 0;
}

/* ── Common elements ─────────────────────────────────── */
.tree-editor__toggle-form {
  display: contents;
}

.tree-editor__item-info {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  min-width: 0;
}

.tree-editor__item-info .btn {
  margin-left: 0.6rem;
}

.tree-editor__name-block {
  display: inline-flex;
  flex-direction: column;
  overflow: hidden;
  min-width: 0;
}

.tree-editor__name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--heading);
}

.tree-editor__subtitle {
  font-size: 0.75rem;
  opacity: 0.75;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tree-editor__node--hidden .tree-editor__name {
  font-style: italic;
  opacity: 0.5;
}

.tree-editor__actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-shrink: 0;
  margin-left: auto;
  line-height: 24px;
}

.tree-editor__hide-label {
  color: var(--text);
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  cursor: pointer;
  font-size: 0.85rem;
  white-space: nowrap;
  user-select: none;
  line-height: 24px;
  vertical-align: middle;
  margin-bottom: 0;
}

.tree-editor__hide-label input[type="checkbox"] {
  flex-shrink: 0;
}

/* ── Status tags / badges ──────────────────────────────── */
.tag {
  display: inline-block;
  padding: 0.1rem 0.45rem;
  border-radius: 4px;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  white-space: nowrap;
}

.tag--active, .tag--default {
  background-color: color-mix(in srgb, var(--primary-button-bg) 35%, transparent);
  color: var(--text);
}

@media (forced-colors: active) {
  .tag--active, .tag--default {
    outline: 1px solid CanvasText;
  }
}

/* Descriptive tags shown on theme cards */
.tag--theme {
  background-color: color-mix(in srgb, var(--input-border) 20%, transparent);
  color: var(--text);
  border: 1px solid color-mix(in srgb, var(--input-border) 50%, transparent);
}

@media (forced-colors: active) {
  .tag--theme {
    outline: 1px solid CanvasText;
  }
}



.tag--filter {
  background-color: color-mix(in srgb, var(--input-border) 15%, transparent);
  color: var(--text);
  border: 1px solid color-mix(in srgb, var(--input-border) 40%, transparent);
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.1s ease, border-color 0.1s ease;
}

.tag--filter:hover {
  background-color: color-mix(in srgb, var(--input-border) 30%, transparent);
  text-decoration: none;
}

.tag--filter-active {
  background-color: color-mix(in srgb, var(--link) 25%, transparent);
  color: var(--heading);
  border-color: color-mix(in srgb, var(--link) 60%, transparent);
  font-weight: 600;
}

.tag--filter-active:hover {
  background-color: color-mix(in srgb, var(--link) 35%, transparent);
}

@media (forced-colors: active) {
  .tag--filter {
    outline: 1px solid ButtonText;
  }

  .tag--filter-active {
    outline: 2px solid Highlight;
    color: HighlightText;
    background-color: Highlight;
  }
}



.tree-editor__tag {
  display: inline-block;
  padding: 0.1rem 0.45rem;
  border-radius: 4px;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  white-space: nowrap;
  margin-left: 0.35rem;
  flex-shrink: 0;
}

.tree-editor__tag--hidden {
  display: none;
  background-color: color-mix(in srgb, var(--danger-button-bg) 35%, transparent);
  color: var(--danger-button-text);
}

.tree-editor__node--hidden .tree-editor__tag--hidden {
  display: inline-block;
}

/* Duplication preview tags (new copy / existing copy) */
.tree-editor__tag--new {
  background-color: color-mix(in srgb, var(--primary-button-bg) 35%, transparent);
  color: var(--text);
}

.tree-editor__tag--reuse {
  background-color: color-mix(in srgb, var(--input-border) 25%, transparent);
  color: var(--text);
}

/* ── Save indicator ──────────────────────────────────── */
.tree-editor__save-indicator {
  font-size: 0.8rem;
  color: var(--primary-button-text);
  opacity: 0;
  transition: opacity 0.2s;
  flex-shrink: 0;
  white-space: nowrap;
}

.tree-editor__save-indicator--visible {
  opacity: 1;
}

.tree-editor__save-indicator--error {
  color: var(--danger-button-text);
  opacity: 1;
}

@media (max-width: 600px) {
  .tree-editor__summary {
    flex-wrap: wrap;
  }

  .tree-editor__leaf {
    flex-wrap: wrap;
  }

  .tree-editor__children {
    padding-left: 0.5rem;
  }
}

/* ── Forced-colors overrides for tree editor ───────────── */
@media (forced-colors: active) {
  .tree-editor__name {
    color: CanvasText;
  }

  .tree-editor__tag {
    background-color: Canvas;
    border: 1px solid CanvasText;
    color: CanvasText;
  }

  .tree-editor__tag--hidden {
    background-color: Canvas;
    border-color: CanvasText;
    color: CanvasText;
  }

  .tree-editor__tag--new,
  .tree-editor__tag--reuse {
    background-color: Canvas;
    border: 1px solid CanvasText;
    color: CanvasText;
  }

  .tree-editor__children > .tree-editor__folder::before,
  .tree-editor__children > .tree-editor__leaf::before,
  .tree-editor__children > .tree-editor__leaf::after {
    border-color: CanvasText;
  }

  .tree-editor__save-indicator {
    color: CanvasText;
  }

  .tree-editor__save-indicator--error {
    color: CanvasText;
  }

  .tree-editor__summary {
    color: CanvasText;
  }

  .tree-editor__summary:hover,
  .tree-editor__leaf:hover {
    outline: 1px solid GrayText;
  }
}

/* Metadata */
.profile-chat-proxy code {
  background-color: color-mix(in srgb, var(--input-border) 15%, transparent);
  border: 1px solid color-mix(in srgb, var(--input-border) 40%, transparent);
  border-radius: 4px;
  padding: 0.1rem 0.4rem;
}

.metadata {
  font-size: 0.85rem;
  border-top: 1px solid var(--input-border);
  padding-top: 1rem;
  margin-bottom: 1.5rem;
}

.metadata p {
  margin: 0.25rem 0;
}

.metadata strong {
  color: var(--heading);
}

.metadata time {
  margin-left: 0.25rem;
}

.metadata .time-ago {
  opacity: 0.7;
}

/* Share URL styles */
.share-url {
  display: flex;
  gap: 0.5rem;
}

.share-url input[type="text"] {
  flex: 1;
  font-size: 0.85rem;
}

.share-url-hint {
  font-size: 0.85rem;
  margin-top: 0.75rem;
  margin-bottom: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem;
}

/* Text helpers */
.text-muted {
  opacity: 0.7;
  font-size: 0.9rem;
}

.form-hint {
  font-size: 0.85rem;
  opacity: 0.7;
  margin-top: 0.5rem;
}

.chat-bracket-fields {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.chat-bracket-fields input {
  width: auto;
  flex: 1 1 0;
  min-width: 0;
  text-align: center;
}

.chat-bracket-fields__sample {
  flex-shrink: 0;
  opacity: 0.7;
}

/* Button sizes */
input[type="submit"].btn--small,
.btn--small {
  padding: 0.35rem 0.75rem;
  font-size: 0.8rem;
}

.btn--danger {
  background-color: var(--danger-button-bg);
  border: 1px solid var(--danger-button-border);
  color: var(--danger-button-text);
}

.btn--danger:hover {
  background-color: color-mix(in srgb, var(--danger-button-bg) 80%, transparent);
  color: var(--danger-button-text);
}

/* Utility classes (for user-generated content) */
.font-bold { font-weight: 700; }
.font-italic { font-style: italic; }
.text-center { text-align: center; }
.text-left { text-align: left; }
.text-lg { font-size: 1.2rem; }
.text-right { text-align: right; }
.text-sm { font-size: 0.85rem; }

/* ---- Forced-colors: form controls & buttons ---- */
@media (forced-colors: active) {
  /* Text inputs, textareas, selects — take full control */
  input[type="text"],
  input[type="email"],
  input[type="password"],
  input[type="url"],
  input[type="number"],
  input[type="search"],
  textarea,
  select {
    forced-color-adjust: none;
    background-color: Canvas;
    color: CanvasText;
    border: 1px solid CanvasText;
  }

  /* Prevent Firefox autofill from overriding */
  input:-moz-autofill,
  textarea:-moz-autofill,
  select:-moz-autofill,
  input:autofill,
  textarea:autofill,
  select:autofill {
    forced-color-adjust: none;
    background-color: Canvas !important;
    color: CanvasText !important;
    -webkit-text-fill-color: CanvasText;
    border-color: CanvasText !important;
  }

  /* Override Chrome autofill box-shadow trick for forced-colors */
  input:-webkit-autofill,
  input:-webkit-autofill:hover,
  input:-webkit-autofill:focus,
  textarea:-webkit-autofill,
  select:-webkit-autofill {
    -webkit-text-fill-color: CanvasText;
    -webkit-box-shadow: none;
    background-color: Canvas !important;
    border-color: CanvasText;
  }

  input[type="text"]:focus,
  input[type="email"]:focus,
  input[type="password"]:focus,
  input[type="url"]:focus,
  input[type="number"]:focus,
  input[type="search"]:focus,
  textarea:focus,
  select:focus {
    border: 1px solid CanvasText;
    outline: 2px solid CanvasText;
  }

  /* Labels & legends */
  label,
  fieldset.form-group legend {
    color: CanvasText;
  }

  /* Checkboxes — replace native control, manual system-color styling. */
  input[type="checkbox"],
  .checkbox-label input[type="checkbox"] {
    forced-color-adjust: none;
    -webkit-appearance: none;
    appearance: none;
    width: 1.15em;
    height: 1.15em;
    min-width: 1.15em;
    min-height: 1.15em;
    margin: 0;
    flex-shrink: 0;
    background-color: Canvas;
    border: 2px solid CanvasText;
    border-radius: 3px;
    vertical-align: middle;
    cursor: pointer;
  }

  input[type="checkbox"]:checked {
    background-color: CanvasText;
    border-color: CanvasText;
    /* Use a mask so the Canvas background shows through as the checkmark */
    background-image: none;
    position: relative;
  }

  input[type="checkbox"]:checked::after {
    content: "";
    display: block;
    width: 100%;
    height: 100%;
    background-color: Canvas;
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round' d='M3.5 8.5 6.5 11.5 12.5 4.5'/%3E%3C/svg%3E");
    -webkit-mask-size: 100% 100%;
    -webkit-mask-repeat: no-repeat;
    -webkit-mask-position: center;
    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round' d='M3.5 8.5 6.5 11.5 12.5 4.5'/%3E%3C/svg%3E");
    mask-size: 100% 100%;
    mask-repeat: no-repeat;
    mask-position: center;
  }

  input[type="checkbox"]:focus-visible {
    outline: 2px solid CanvasText;
    outline-offset: 2px;
  }

  /* Radio buttons — pure CSS dot using box-shadow, no SVG needed */
  input[type="radio"] {
    forced-color-adjust: none;
    -webkit-appearance: none;
    appearance: none;
    width: 1.15em;
    height: 1.15em;
    margin: 0;
    flex-shrink: 0;
    background-color: Canvas;
    border: 2px solid CanvasText;
    border-radius: 50%;
    vertical-align: middle;
    cursor: pointer;
  }

  input[type="radio"]:checked {
    border: 2px solid CanvasText;
    background-color: CanvasText;
    /* Inset Canvas ring creates the gap around the CanvasText dot */
    box-shadow: inset 0 0 0 0.13em Canvas;
  }

  input[type="radio"]:focus-visible {
    outline: 2px solid CanvasText;
    outline-offset: 2px;
  }

  /* Disabled controls in forced-colors */
  input:disabled,
  textarea:disabled,
  select:disabled {
    color: GrayText;
    border-color: GrayText;
    cursor: not-allowed;
  }

  input[type="checkbox"]:disabled,
  input[type="radio"]:disabled {
    border-color: GrayText;
    background-color: GrayText;
    cursor: not-allowed;
  }

  input[type="submit"]:disabled,
  button:disabled,
  .btn:disabled {
    background-color: GrayText;
    border-color: GrayText;
    color: Canvas;
    cursor: not-allowed;
  }

  /* Primary buttons */
  input[type="submit"],
  button,
  .btn {
    forced-color-adjust: none;
    background-color: CanvasText;
    color: Canvas;
    border: 1px solid CanvasText;
  }

  /* File input browse button */
  input[type="file"] {
    color: CanvasText;
  }

  input[type="file"]::file-selector-button {
    forced-color-adjust: none;
    background-color: CanvasText;
    color: Canvas;
    border: 1px solid CanvasText;
    border-radius: 4px;
    padding: 0.3rem 0.75rem;
    cursor: pointer;
  }

  input[type="file"]::file-selector-button:hover {
    background-color: Canvas;
    color: CanvasText;
  }

  input[type="submit"]:hover,
  button:hover,
  .btn:hover {
    background-color: Canvas;
    color: CanvasText;
  }

  input[type="submit"]:focus-visible,
  button:focus-visible,
  .btn:focus-visible {
    outline: 2px solid CanvasText;
    outline-offset: 2px;
  }

  /* Secondary / outline buttons */
  .btn--secondary,
  .btn--outline {
    background-color: Canvas;
    color: CanvasText;
    border: 1px solid CanvasText;
  }

  .btn--secondary:hover,
  .btn--outline:hover {
    background-color: CanvasText;
    color: Canvas;
  }

  /* Fieldset borders */
  fieldset.form-group,
  fieldset.inclusion-radios,
  fieldset.inclusion-checkboxes,
  fieldset.inclusion-profiles {
    border-color: CanvasText;
  }

  /* Bare chrome-less buttons (tree controls, etc.) */
  .tree__arrow-btn,
  .tree__item {
    background-color: transparent;
    color: CanvasText;
    border-color: transparent;
  }

  .tree__arrow-btn:hover,
  .tree__item:hover {
    opacity: 0.7;
  }

  .tree__item--active {
    outline: 2px solid CanvasText;
    font-weight: 700;
  }
}

/* ---- Responsive ---- */

/* Tablet (768px and below) */
@media (max-width: 768px) {
  .layout {
    grid-template-columns: 280px 1fr;
    gap: 1.5rem;
  }

  .container {
    padding: 0 1rem;
  }

  .card {
    padding: 1.5rem;
  }

  .site-header {
    padding: 0.5rem 1rem;
  }
}

/* Mobile (600px and below) */
@media (max-width: 600px) {
  .layout {
    grid-template-columns: 1fr;
  }

  .sidebar {
    position: static;
  }

  .explorer--active {
    grid-template-columns: 1fr;
  }

  .explorer__sidebar {
    position: static;
    max-height: none;
  }

  .container {
    margin: 1rem auto;
    padding: 0 1rem;
  }

  .card {
    padding: 1.25rem;
  }

  h1 { font-size: 1.4rem; }
  h2 { font-size: 1.2rem; }

  .site-header {
    flex-direction: column;
    gap: 0.5rem;
    text-align: center;
  }

  .site-header nav a {
    margin-left: 0;
    margin-right: 1rem;
  }

  .site-header nav a:last-child {
    margin-right: 0;
  }

  .profile-grid {
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  }

  .card__header {
    flex-direction: column;
    text-align: center;
  }

  .share-url {
    flex-direction: column;
    align-items: center;
  }

  .dashboard-grid {
    grid-template-columns: 1fr;
  }

  .profile-actions {
    justify-content: center;
  }
}

/* Invite codes */
.invite-code-list {
  list-style: none;
  padding: 0;
  margin: 0 0 1rem 0;
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.invite-code-item {
  display: flex;
  align-items: center;
  background-color: var(--input-bg);
  border: 1px solid var(--input-border);
  border-radius: 4px;
}

.invite-code {
  font-family: monospace;
  font-size: 1.1rem;
  letter-spacing: 0.1em;
  padding: 0.4rem 0.75rem;
}

.invite-code-delete {
  padding: 0.4rem 0.6rem;
  margin: 0 0.5rem;
  line-height: 1;
  font-size: 1rem;
  background-color: transparent;
  color: var(--text);
}

.invite-code-delete:hover {
  background-color: transparent;
  color: var(--error);
}

.invite-code-input {
  font-family: monospace;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.muted {
  opacity: 0.65;
  font-style: italic;
}

/* ── Heart emoji picker ────────────────────────────────── */

.heart-picker__grid,
.heart-display__grid {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  margin-left: 0.5rem;
}

.heart-picker__heart {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 4px;
  border: 2px solid transparent;
  border-radius: 0.5rem;
  background: none;
  cursor: pointer;
  transition: opacity 0.15s, border-color 0.15s, transform 0.15s;
}

.heart-picker__heart:has(input:checked) {
  opacity: 1;
  border-color: var(--input-border);
}

.heart-picker__heart img {
  pointer-events: none;
}

/* Checkbox is always hidden — the label itself is the interactive control */
.heart-picker__checkbox {
  -webkit-appearance: none;
  appearance: none;
  position: absolute;
  inset: 0;
  opacity: 0;
  margin: 0;
  cursor: pointer;
  outline: none;
}

.heart-picker__heart:has(input:focus-visible) {
  outline: 3px solid var(--input-border);
  outline-offset: 2px;
}

.heart-display__heart {
  display: flex;
  align-items: center;
  justify-content: center;
}

.heart-display {
  margin: 1rem 0;
}

.heart-display h3 {
  margin-bottom: 0.5rem;
}

@media (forced-colors: active) {
  .heart-picker__heart {
    border: none;
    opacity: 1;
    background: Canvas;
  }

  .heart-picker__heart:has(input:checked) {
    border: 2px solid CanvasText;
    background: Canvas;
  }

  .heart-picker__heart:has(input:focus-visible) {
    outline: 3px solid CanvasText;
    outline-offset: 2px;
  }

  .heart-picker__checkbox,
  .heart-picker__checkbox:checked {
    forced-color-adjust: none;
    position: absolute;
    inset: 0;
    width: auto;
    height: auto;
    min-width: 0;
    min-height: 0;
    border: 0;
    background: none;
    opacity: 0;
  }

  .heart-picker__checkbox:checked::after {
    content: none;
  }
}

@media (forced-colors: active) {
  .invite-code-item {
    border: 1px solid CanvasText;
    background-color: Canvas;
  }

  .invite-code {
    color: CanvasText;
  }

  .invite-code-delete {
    border-left-color: CanvasText;
  }

  .form-divider {
    border-top-color: GrayText;
  }

  .sidebar hr {
    border-top-color: CanvasText;
  }
}

/* ── Inline heart emojis ────────────────── */

.heart-inline {
  display: inline;
  vertical-align: -0.35em;
  width: auto;
}

h1 .heart-inline {
  vertical-align: -0.1em;
}

/* ── Utilities ─────────────────────────────────────────── */

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ── Theme designer ────────────────────────────────────── */

.theme-designer-container {
  max-width: 1400px;
}

.theme-designer {
  display: grid;
  grid-template-columns: 380px 1fr;
  gap: 2rem;
  align-items: start;
}

.theme-designer__controls {
  position: sticky;
  top: 2rem;
  max-height: calc(100vh - 4rem);
  overflow-y: auto;
}

.theme-designer__controls details[open] > summary {
  margin-bottom: 0.75rem;
}

.theme-designer__color-group {
  margin-bottom: 0.75rem;
}

.theme-designer__color-input {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

/* No-JS: native colour input */
.theme-designer__color-input input[type="color"] {
  width: 48px;
  height: 36px;
  padding: 2px;
  border: 1px solid var(--input-border);
  border-radius: 4px;
  background-color: var(--input-bg);
  cursor: pointer;
}

.theme-designer__color-input input[type="color"]::-webkit-color-swatch-wrapper {
  padding: 2px;
}

.theme-designer__color-input input[type="color"]::-webkit-color-swatch {
  border: none;
  border-radius: 2px;
}

/* JS-enhanced: Coloris wraps the hex input in .clr-field */
.theme-designer__color-input .clr-field {
  flex: 1;
}

/* Swatch button: left-aligned, wider, inset inside the field border */
.theme-designer__color-input .clr-field button {
  left: 2px;
  right: auto;
  width: 2.8rem;
  height: calc(100% - 4px);
  border-radius: 4px 0 0 4px;
}

.theme-designer__hex-input {
  width: calc(9ch + 2.8rem);
  font-family: monospace;
  font-size: 0.85rem;
  text-transform: uppercase;
}

/* When inside Coloris wrapper, fill the flex space with padding for swatch */
.clr-field .theme-designer__hex-input {
  width: 100%;
  padding-left: calc(2.8rem + 10px);
  padding-right: 0.75rem;
  box-sizing: border-box;
}

/* Coloris picker z-index — sit above form elements */
.clr-picker {
  z-index: 9999;
}

@media (forced-colors: active) {
  .theme-designer__color-input .clr-field button {
    forced-color-adjust: none;
  }
}

.theme-designer__css-output {
  font-family: monospace;
  font-size: 0.8rem;
  resize: vertical;
  min-height: 80px;
}

/* ── Theme preview panel ───────────────────────────────── */

.theme-preview {
  background-color: var(--page-bg);
  color: var(--text);
  border-radius: 8px;
  padding: 1.5rem;
  border: 1px solid var(--pane-border);
}

.theme-preview a {
  color: var(--link);
}

.theme-preview h2,
.theme-preview h3 {
  color: var(--heading);
}

.theme-preview__section {
  margin-bottom: 1.5rem;
}

.theme-preview__section:last-child {
  margin-bottom: 0;
}

.theme-preview__buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.theme-preview__header {
  background-color: var(--pane-bg);
  border: 1px solid var(--pane-border);
  border-radius: 6px;
  padding: 0.75rem 1rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.theme-preview__logo {
  font-weight: 700;
  color: var(--heading);
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.theme-preview__logo svg {
  width: 1.4em;
  height: 1.4em;
}

.theme-preview__header nav a {
  color: var(--link);
  text-decoration: none;
  margin-left: 1rem;
  font-size: 0.9rem;
}

.theme-bg-preview {
  display: block;
  border-radius: 4px;
  border: 1px solid var(--pane-border);
  object-fit: cover;
  margin-top: 0.5rem;
}

@media (forced-colors: active) {
  body {
    background-image: none !important;
  }
}

/* ── Import theme dialog ────────────────────────────────── */



.import-dialog {
  background-color: var(--pane-bg);
  color: var(--text);
  border: 1px solid var(--pane-border);
  border-radius: 8px;
  padding: 2rem;
  max-width: 560px;
  width: 90vw;
}

.import-dialog::backdrop {
  background-color: color-mix(in srgb, black 60%, transparent);
}

.import-dialog h2 {
  color: var(--heading);
  margin-top: 0;
  margin-bottom: 0.5rem;
}

.import-dialog p {
  margin-top: 0;
  margin-bottom: 0.75rem;
}

.import-dialog__textarea {
  font-family: monospace;
  font-size: 0.8rem;
  width: 100%;
  box-sizing: border-box;
  resize: vertical;
  min-height: 200px;
  background-color: var(--input-bg);
  color: var(--input-text);
  border: 1px solid var(--input-border);
  border-radius: 4px;
  padding: 0.5rem;
}

.import-dialog__error {
  color: var(--alert-text);
  background-color: var(--alert-bg);
  border: 1px solid var(--alert-border);
  border-radius: 4px;
  padding: 0.5rem 0.75rem;
  font-size: 0.9rem;
  margin-top: 0.5rem;
  margin-bottom: 0;
}

.import-dialog__error:empty {
  display: none;
}

.import-dialog__actions {
  display: flex;
  gap: 0.5rem;
  margin-top: 1rem;
  justify-content: flex-end;
}

@media (forced-colors: active) {
  .import-dialog {
    border: 2px solid ButtonText;
  }
}

/* Responsive: stack on narrow screens */
@media (max-width: 900px) {
  .theme-designer {
    grid-template-columns: 1fr;
  }

  .theme-designer__controls {
    position: static;
    max-height: none;
  }
}

@media (max-width: 600px) {
  .theme-designer-container {
    max-width: 100%;
  }
}

/* ── Duplication wizard ──────────────────────────────────── */
.duplicate-comparison {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
  margin: 1rem 0;
}

.duplicate-comparison__card {
  padding: 1rem;
  border: 1px solid var(--pane-border);
  border-radius: 0.5rem;
  background: var(--pane-bg);
}

.duplicate-comparison__item {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.duplicate-comparison__description {
  font-size: 0.875rem;
  color: var(--text);
  opacity: 0.8;
}

.radio-group {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 0.5rem;
  margin-bottom: 0.75rem;
}

.radio-group input[type="radio"] {
  flex-shrink: 0;
}

.radio-group label {
  flex: 1;
}

.radio-group .form-hint {
  width: 100%;
  margin-top: 0.25rem;
  margin-bottom: 0;
}

@media (max-width: 600px) {
  .duplicate-comparison {
    grid-template-columns: 1fr;
  }
}

@media (forced-colors: active) {
  .duplicate-comparison__card {
    border-color: CanvasText;
  }
  .radio-group input[type="radio"] {
    accent-color: Highlight;
  }
}

/* ── Label badges ───────────────────────────────────────── */
.label-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  margin-top: 0.25rem;
}

.label-badge {
  display: inline-block;
  padding: 0.125rem 0.5rem;
  border-radius: 999px;
  font-size: 0.75rem;
  background: color-mix(in srgb, var(--primary-button-bg) 60%, transparent);
  color: var(--primary-button-text);
  border: 1px solid color-mix(in srgb, var(--primary-button-border) 40%, transparent);
}

.label-badge--sidebar {
  font-size: 0.65rem;
  padding: 0.1rem 0.35rem;
  font-weight: normal;
}

@media (forced-colors: active) {
  .label-badge {
    border: 1px solid CanvasText;
    background: Canvas;
    color: CanvasText;
  }
}

/* ── Label filter bar ───────────────────────────────────── */
.filter-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 1rem;
}

.filter-bar__label {
  font-size: 0.875rem;
  color: var(--text);
}

.filter-bar__clear {
  font-size: 0.8rem;
  color: var(--link);
  text-decoration: underline;
}

/* ── Theme credit footer bar ─────────────────────────────── */
.theme-credit {
  background-color: var(--pane-bg);
  border-top: 1px solid var(--pane-border);
  padding: 0.75rem 2rem;
  text-align: center;
  font-size: 0.85rem;
  color: var(--text);
}

.theme-credit__name {
  font-weight: 600;
}

.theme-credit a {
  color: var(--link);
  font-weight: bold;
}

@media (forced-colors: active) {
  .theme-credit {
    color: CanvasText;
    border-top: 1px solid CanvasText;
  }
  .theme-credit a {
    color: LinkText;
  }
}

/* ── Theme index: rows ──────────────────────────────────── */

.theme-row {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
  padding: 0.875rem 2rem;
  border-bottom: 1px solid var(--pane-border);
}

.theme-row:last-child {
  border-bottom: none;
}

.theme-row--active {
  border-left: 3px solid var(--link);
  padding-left: calc(2rem - 3px);
}

.theme-row__info {
  flex: 1;
  min-width: 0;
}

.theme-row__name-line {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.theme-row__name-line h3 {
  margin: 0;
  font-size: 1rem;
}

.theme-row__credit {
  font-size: 0.85rem;
  margin: 0.15rem 0 0;
}

.theme-row__notes {
  font-size: 0.85rem;
  font-style: italic;
  margin: 0.2rem 0 0;
}

.theme-row__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  margin-top: 0.4rem;
}

.theme-row__end {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-shrink: 0;
  padding-top: 0.1rem;
}

/* ── Theme swatches ─────────────────────────────────────── */

.theme-swatches {
  display: flex;
  flex-shrink: 0;
}

.theme-swatches__dot {
  width: 18px;
  height: 18px;
  border-radius: 0;
  border: 1px solid color-mix(in srgb, var(--pane-border) 60%, transparent);
  margin-left: -1px;
}

.theme-swatches__dot:first-child {
  border-radius: 3px 0 0 3px;
  margin-left: 0;
}

.theme-swatches__dot:last-child {
  border-radius: 0 3px 3px 0;
}

@media (forced-colors: active) {
  .theme-swatches {
    display: none;
  }
}

/* ── Action dropdown ────────────────────────────────────── */

.action-dropdown {
  position: relative;
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
}

.action-dropdown__trigger {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.35rem 0.65rem;
  border-radius: 4px;
  cursor: pointer;
  color: var(--secondary-button-text);
  background-color: var(--secondary-button-bg);
  border: 1px solid var(--secondary-button-border);
  font-size: 0.85rem;
  font-weight: 500;
  line-height: 1.4;
  list-style: none;
  user-select: none;
  white-space: nowrap;
}

.action-dropdown__trigger:hover {
  background-color: color-mix(in srgb, var(--secondary-button-bg) 80%, transparent);
}

.action-dropdown__trigger::after {
  content: " ▾";
  font-size: 0.7rem;
  opacity: 0.8;
}

.action-dropdown__trigger::-webkit-details-marker,
.action-dropdown__trigger::marker {
  display: none;
}

.action-dropdown__menu {
  position: absolute;
  right: 0;
  top: calc(100% + 4px);
  z-index: 10;
  min-width: 170px;
  background-color: var(--pane-bg);
  border: 1px solid var(--pane-border);
  border-radius: 8px;
  padding: 0.35rem 0;
  box-shadow: 0 4px 12px color-mix(in srgb, var(--pane-border) 25%, transparent);
}

/* The domain switcher sits at the left edge of the header now, next to the
   logo — right: 0 (the default, for menus that hang off a right-aligned nav
   item) would make it spill further left past its trigger. Open it flush
   with the trigger's left edge instead. */
.site-header__brand .action-dropdown__menu {
  left: 0;
  right: auto;
}

.action-dropdown__item {
  display: block;
  padding: 0.5rem 1rem;
  color: var(--text);
  text-decoration: none;
  font-size: 0.9rem;
  white-space: nowrap;
}

.action-dropdown__item:hover {
  background-color: color-mix(in srgb, var(--text) 8%, transparent);
  text-decoration: none;
  color: var(--text);
}

.action-dropdown__divider {
  border: none;
  border-top: 1px solid var(--pane-border);
  margin: 0.35rem 0;
}

@media (forced-colors: active) {
  .action-dropdown__trigger {
    border: 1px solid CanvasText;
  }

  .action-dropdown__trigger:hover {
    outline: 1px solid CanvasText;
  }

  .action-dropdown__menu {
    border: 2px solid CanvasText;
  }

  .action-dropdown__divider {
    border-top-color: CanvasText;
  }

  .action-dropdown__item:hover {
    font-weight: bold;
    background-color: Highlight;
  }
}

/* ── Theme heading card ─────────────────────────────────── */

.theme-heading__bar {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
}

.theme-heading__active {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  flex: 1;
  min-width: 200px;
}

.theme-heading__active-label {
  font-size: 0.95rem;
}

.theme-heading__actions {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  flex-shrink: 0;
}

.card > .filter-bar {
  margin-bottom: 0;
}

/* ── Theme section cards (collapsible) ──────────────────── */

/* padding: 2rem inherited from .card — do NOT override to 0 or the
   card__header negative-margin trick breaks. Instead, .theme-list
   uses negative margins to bleed its rows to the card edges. */
.theme-section-card {
  /* inherits .card styles — no overrides needed */
}

.theme-section-card__header {
  cursor: pointer;
  list-style: none;
  user-select: none;
}

.card__header.theme-section-card__header {
  margin-bottom: 0;
}

.theme-section-card__header::-webkit-details-marker,
.theme-section-card__header::marker {
  display: none;
}

.theme-section-card__header h2 {
  margin: 0;
}

.theme-section-card__header h2::before {
  content: "▾ ";
  opacity: 0.7;
}

details.theme-section-card:not([open]) .theme-section-card__header h2::before {
  content: "▸ ";
}

details.theme-section-card:not([open]) {
  padding-bottom: 0;
}

details.theme-section-card:not([open]) .theme-section-card__header {
  margin-bottom: 0;
  border-radius: 7px;
}

/* Bleed theme rows to the card edges, cancelling the 2rem card padding
   on left, right, and bottom. Do NOT use overflow:hidden — it clips dropdowns. */
.theme-list {
  margin: 0 -2rem -2rem;
}

.theme-section-card__empty {
  margin: 1.5rem 0 0 0;
  font-size: 0.95rem;
}

/* ---- Chat ---- */

/* The shared `body` rule only sets min-height: 100vh, which lets the whole
   page grow past the viewport for tall content — fine for ordinary pages,
   but it means .chat-shell's flex:1 never gets a definite height to fill,
   so its own overflow:auto areas (the message history) never actually
   engage and the composer at the bottom ends up pushed off-screen instead.
   Pin chat pages to exactly the viewport height so the flex chain resolves
   properly and only the message history scrolls. */
.chat-body {
  height: 100vh;
  height: 100dvh;
}

.server-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.server-list__link {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.5rem 0.75rem;
  border-radius: 6px;
  color: var(--text);
  text-decoration: none;
}

.server-list__link:hover {
  background-color: color-mix(in srgb, var(--text) 8%, transparent);
}

.server-list__link .avatar {
  width: 32px;
  height: 32px;
  min-width: 32px;
  min-height: 32px;
}

.server-list__text {
  display: flex;
  flex-direction: column;
  min-width: 0;
  flex: 1 1 auto;
}

.server-list__title-row {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  min-width: 0;
}

.server-list__name {
  font-weight: 600;
  flex-shrink: 0;
  overflow-wrap: anywhere;
}

.server-list__description {
  font-size: 0.85rem;
  color: color-mix(in srgb, var(--text) 80%, transparent);
  min-width: 0;
  flex: 1 1 auto;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.server-list__subtitle {
  font-size: 0.85rem;
  color: color-mix(in srgb, var(--text) 80%, transparent);
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.chat-shell {
  flex: 1;
  min-height: 0;
  display: flex;
}

.server-rail {
  width: 72px;
  flex-shrink: 0;
  background-color: var(--pane-border);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.7rem;
  padding: 0.85rem 0;
  overflow-y: auto;
}

.server-rail__icon {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  flex-shrink: 0;
  border-radius: 25%;
  color: var(--text);
  text-decoration: none;
  border: 2px solid transparent;
}

/* Kept in sync with the avatar's own shape modifier (avatar_shape_class),
   so the ring below always hugs the same outline as the image inside it —
   a mismatched fixed radius here made the ring look broken on square
   avatars. */
.server-rail__icon--circle {
  border-radius: 50%;
}

.server-rail__icon--square {
  border-radius: 0;
}

.server-rail__icon .avatar {
  width: 42px;
  height: 42px;
  min-width: 42px;
  min-height: 42px;
}

.server-rail__icon:hover {
  border-color: color-mix(in srgb, var(--text) 40%, transparent);
}

.server-rail__icon--active {
  border-color: transparent;
  box-shadow: 0 0 0 2px var(--pane-border), 0 0 0 4px var(--heading);
}

.server-rail__icon--add {
  border: 1px dashed color-mix(in srgb, var(--text) 40%, transparent);
  color: var(--link);
  font-size: 1.3rem;
  text-decoration: none;
}

.unread-dot {
  display: inline-block;
  align-self: center;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: var(--primary-button-text);
  flex-shrink: 0;
}

.unread-dot--rail {
  position: absolute;
  top: 0;
  right: 0;
  border: 2px solid var(--pane-border);
}

@media (forced-colors: active) {
  /* Background colors are the first thing forced-colors mode flattens away,
     so without an explicit border the rail is indistinguishable from the
     panes either side of it. Same story for the active-server ring and the
     unread dots below — box-shadow is dropped outright in forced-colors
     mode, and background-color fills get replaced with the page background
     (Canvas), unless the color is an explicit system keyword. */
  .server-rail {
    border-right: 1px solid CanvasText;
  }

  .server-rail__icon--active {
    outline: 2px solid CanvasText;
    outline-offset: 2px;
  }

  .unread-dot {
    background-color: CanvasText;
  }

  .unread-dot--rail {
    border-color: Canvas;
  }
}

.channel-pane {
  width: 200px;
  flex-shrink: 0;
  background-color: var(--pane-bg);
  border-right: 1px solid var(--pane-border);
  padding: 1rem 0.75rem;
  overflow-y: auto;
}

/* The channel list reuses the group/profile sidebar's tree-guide-line
   markup for visual consistency, but a channel list has no actual
   hierarchy to show — the connector lines just imply a nesting that isn't
   there, so drop them here while keeping the rest of the leaf styling. */
.channel-pane .sidebar-tree__children > li::before,
.channel-pane .sidebar-tree__children > .sidebar-tree__leaf::after {
  display: none;
}

/* The shared --st-indent left-padding exists to make room for the
   tree-guide line — with that line hidden above, it's just dead space. */
.channel-pane .sidebar-tree__children {
  padding-left: 0;
}

.channel-pane__server-name {
  display: block;
  font-weight: 700;
  color: var(--heading);
  text-decoration: none;
  margin-bottom: 0.75rem;
}

.channel-pane__server-name:hover {
  text-decoration: underline;
}

.channel-pane__add-channel {
  display: block;
  margin-top: 0.6rem;
  padding-left: 1.1rem;
  font-size: 0.85rem;
  color: var(--link);
  text-decoration: none;
}

.channel-pane__add-channel:hover {
  text-decoration: underline;
}

.chat-main {
  flex: 1;
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  padding: 1.5rem;
  overflow-y: auto;
  /* Left transparent (rather than --pane-bg) so plain pages — server list,
     server/channel settings, invite page — show the themed page background
     (colour and background-image) behind their .card content, same as every
     other themed page in the app. */
}

/* .chat-channel (channel#show) owns its own padding per-section so the
   composer can sit flush against the bottom of the pane — cancel .chat-main's
   padding only when it's present, leaving plain pages (server list/settings
   etc.) with their normal padding.

   It also restores the solid pane background that .chat-main otherwise
   leaves transparent: without it, the message pane falls through to the
   bare page background — which, depending on the active theme, can end up
   matching --spoiler exactly (spoilers are styled background === border ===
   --spoiler), making spoiler text completely invisible instead of an
   obviously-clickable redacted box. */
.chat-main:has(.chat-channel) {
  padding: 0;
  overflow-y: hidden;
  background-color: var(--pane-bg);
}

/* Wraps the header, the scrollable history, and the composer for a single
   channel — a plain flex column so the composer can stay pinned to the
   bottom (flex-shrink: 0) while only the history area scrolls. */
.chat-channel {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

.chat-channel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.6rem 1.25rem 0.9rem;
  border-bottom: 1px solid var(--pane-border);
  flex-shrink: 0;
}

.chat-channel-header h1 {
  margin: 0;
  font-size: 1.15rem;
  flex-shrink: 0;
  overflow-wrap: anywhere;
}

.chat-channel-header__actions {
  display: flex;
  gap: 0.75rem;
  flex-shrink: 0;
}

.chat-channel-header__title {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
  flex: 1;
}

.chat-channel-header__title-column {
  display: flex;
  flex-direction: column;
  min-width: 0;
  flex: 1;
}

/* Name and description share one line rather than stacking — the description is
   the one that gives way (ellipsis) since the channel name is what
   identifies the channel and should never get cut off. The subtitle, if
   present, runs on its own line underneath. */
.chat-channel-header__title-text {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  min-width: 0;
}

.chat-channel-header__title-text .description {
  margin: 0;
  min-width: 0;
  flex: 1 1 auto;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.chat-channel-header__title-column .subtitle {
  margin: 0.15rem 0 0;
}

/* Hidden by default — only shown at the small-screen breakpoint below,
   where the server rail and channel list collapse away and this is the
   only way back to them. */
.chat-channel-back {
  display: none;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  border-radius: 6px;
  color: var(--text);
  text-decoration: none;
  font-size: 1.5rem;
  line-height: 1;
}

.chat-channel-back:hover {
  background-color: color-mix(in srgb, var(--text) 10%, transparent);
}

/* Mobile (600px and below): collapse to a single pane at a time, matching
   Discord's small-screen behaviour. Reading a specific channel's messages
   (.chat-shell--channel-open, set by the layout whenever @in_channel_chat is
   true) hides the server rail and channel list entirely and shows the back
   arrow above to return to them; everywhere else in chat is unaffected. */
@media (max-width: 600px) {
  .chat-shell--channel-open .server-rail,
  .chat-shell--channel-open .channel-pane {
    display: none;
  }

  .chat-channel-back {
    display: flex;
  }
}

.chat-messages-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 1rem 1.5rem;
}

/* turbo-frame has no default display value browsers agree on. `display:
   contents` would make it transparent to layout, but Turbo's loading="lazy"
   detects scroll visibility with an IntersectionObserver on the frame
   element itself — an element with `display: contents` generates no box at
   all, so it can never intersect the viewport and the lazy load silently
   never fires. Use a plain block instead, and give messages/dividers their
   own margin (below) rather than relying on the parent's flex `gap`, so
   spacing still looks right regardless of the frame wrapping some of them. */
turbo-frame {
  display: block;
}

/* An unloaded lazy turbo-frame is empty, so as a plain block it collapses to
   ~0 height — an easy target to scroll straight past without it ever truly
   crossing into the viewport for the IntersectionObserver driving
   loading="lazy" to catch. Give it a reliable minimum height to scroll onto. */
#older-messages:not([complete]) {
  min-height: 40px;
}

.chat-messages {
  display: flex;
  flex-direction: column;
}

.chat-message,
.chat-date-divider {
  margin-bottom: 1rem;
}

.chat-messages > :last-child {
  margin-bottom: 0;
}

.chat-date-divider {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding-top: 1.5rem;
  color: color-mix(in srgb, var(--text) 65%, transparent);
  font-size: 0.76rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.chat-date-divider::before,
.chat-date-divider::after {
  content: "";
  flex: 1;
  /* Same muted, translucent tone as the sidebar tree-guide lines, rather
     than the harder --pane-border — and a border (not a background bar) so
     the same CanvasText override used for tree-guide lines elsewhere in
     forced-colors mode applies here too. */
  border-top: 1px solid var(--tree-guide);
}

@media (forced-colors: active) {
  .chat-date-divider::before,
  .chat-date-divider::after {
    border-color: CanvasText;
  }
}

.chat-message {
  display: flex;
  gap: 0.65rem;
}

.chat-message__avatar .avatar {
  width: 34px;
  height: 34px;
  min-width: 34px;
  min-height: 34px;
}

.chat-message__content {
  flex: 1;
  min-width: 0;
}

.chat-message__who {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.chat-message__avatar-trigger,
.chat-message__name-link {
  background: none;
  border: none;
  margin: 0;
  padding: 0;
  font: inherit;
  color: inherit;
  cursor: pointer;
}

/* The global button:hover rule (for .btn-style buttons) has higher
   specificity than a plain class selector, so it wins over the reset
   above on hover without this. */
.chat-message__avatar-trigger:hover,
.chat-message__name-link:hover {
  background: none;
}

.chat-message__avatar-trigger {
  display: block;
  border-radius: 999px;
}

.chat-message__name-link:hover .chat-message__name {
  text-decoration: underline;
}

.chat-message__name {
  font-weight: 700;
  font-size: 0.9rem;
  color: var(--heading);
}

/* Same forced-colors issue as .link-button above: the name is a <button>
   (it opens the mini-profile popover), so forced-colors mode leaves it in
   our themed --heading color instead of switching it to CanvasText. */
@media (forced-colors: active) {
  .chat-message__name-link .chat-message__name {
    color: CanvasText;
  }
}

.chat-message__name--deleted {
  font-style: italic;
  font-weight: 500;
  font-size: 0.9rem;
  color: color-mix(in srgb, var(--text) 65%, transparent);
}

.chat-message__pronouns,
.chat-message__time {
  font-size: 0.76rem;
  color: color-mix(in srgb, var(--text) 65%, transparent);
}

.chat-message__pronouns {
  font-style: italic;
}

.chat-message__subtitle {
  display: block;
  font-size: 0.78rem;
  color: color-mix(in srgb, var(--text) 75%, transparent);
}

.chat-message__body {
  font-size: 0.92rem;
  margin-top: 0.15rem;
}

.composer {
  flex-shrink: 0;
  border-top: 1px solid var(--pane-border);
  padding: 0.5rem 1.25rem 0.75rem;
}

/* Shared "post as" searchable profile picker — used by the composer's
   identity switcher and by any plain form field that needs to choose a
   profile (server creation, joining a server). Selection-context specifics
   (immediate PATCH vs. a hidden form field, upward vs. downward opening)
   live in profile_picker_controller.js / composer_controller.js and the
   .composer-posting-as modifier below, not here. */
.profile-picker {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  background-color: color-mix(in srgb, var(--pane-bg) 85%, var(--page-bg) 15%);
  border: 1px solid color-mix(in srgb, var(--text) 35%, transparent);
  border-radius: 7px;
  padding: 0.3rem 0.6rem 0.3rem 0.4rem;
  font-size: 0.82rem;
}

/* .avatar--placeholder carries its own min-width/min-height (see the base
   rule) to stay visible at its default 64px size elsewhere — here it needs
   overriding too, or the placeholder ignores the width/height below and
   renders oversized next to profiles that do have a real avatar image. */
.profile-picker .avatar {
  width: 22px;
  height: 22px;
  min-width: 22px;
  min-height: 22px;
}

.profile-picker__option .avatar {
  width: 20px;
  height: 20px;
  min-width: 20px;
  min-height: 20px;
  margin-top: 0.1rem;
}

.profile-picker__trigger {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  cursor: pointer;
  list-style: none;
}

/* Without this, the wrapping span is a block box around an inline <img>,
   which leaves a few px of baseline whitespace below the image — inflating
   the span taller than the 22px avatar and pushing it toward the top of the
   trigger row instead of centering it. */
.profile-picker__trigger-avatar {
  display: flex;
}

.profile-picker__trigger-pronouns {
  margin-left: 0.3rem;
  font-size: 0.78rem;
  font-style: italic;
  color: color-mix(in srgb, var(--text) 75%, transparent);
}

.profile-picker__trigger::-webkit-details-marker,
.profile-picker__trigger::marker {
  display: none;
}

/* The default .action-dropdown__menu anchors to its trigger's right edge and
   grows leftward, which overflows off-screen whenever the trigger sits near
   the left edge of a narrower container (a form dialog, the composer at the
   bottom of the pane) — anchor left and grow rightward instead. */
.profile-picker .action-dropdown__menu {
  left: 0;
  right: auto;
}

/* The composer's picker additionally opens upward, since it sits at the very
   bottom of the pane and there's no room to open downward. */
.composer-posting-as {
  margin-bottom: 0.55rem;
}

.composer-posting-as .action-dropdown__menu {
  top: auto;
  bottom: calc(100% + 4px);
}

.profile-picker__menu {
  width: max-content;
  min-width: 260px;
  max-width: 340px;
  padding: 0.4rem;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.profile-picker__search {
  width: 100%;
  padding: 0.4rem 0.6rem;
  border-radius: 5px;
  border: 1px solid var(--pane-border);
  background-color: var(--page-bg);
  color: var(--text);
  font-size: 0.85rem;
}

.profile-picker__options {
  max-height: 260px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}

.profile-picker__option {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  white-space: normal;
  outline: none;
}

/* Explicit ring rather than relying on the browser's native default — a
   <button> and an <a> (the composer uses a link, the plain-form pickers use
   a button) don't reliably render the same default focus indicator. Outline
   only appears on focus (rather than an always-on "transparent" placeholder
   that flips color) because forced-colors mode refuses to treat a transparent
   outline as invisible — any non-"none" outline-style gets forced to a
   visible system color regardless of focus state, which would otherwise put
   a box around every option, focused or not. */
.profile-picker__option:focus-visible {
  outline: 2px solid var(--link);
  outline-offset: -2px;
}

@media (forced-colors: active) {
  .profile-picker__option:focus-visible {
    outline-color: CanvasText;
  }
}

/* The composer's picker uses a link (it fires an immediate PATCH); the
   plain-form "post as" pickers use a <button> instead (there's nothing to
   navigate to, just a hidden field to fill in) — reset the UA button chrome
   without touching the font-size/color already set above for both.
   appearance: none keeps the button under our own styling (background,
   border, outline) in forced-colors mode too — without it, some browsers
   fall back to native widget rendering for real <button> elements there and
   ignore the authored focus ring entirely. */
button.profile-picker__option {
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  appearance: none;
  font-family: inherit;
  cursor: pointer;
}

.profile-picker__option--current {
  background-color: color-mix(in srgb, var(--text) 10%, transparent);
}

.profile-picker__option-info {
  min-width: 0;
  flex: 1;
}

.profile-picker__option-name-row {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  flex-wrap: wrap;
}

.profile-picker__option-name {
  font-weight: 500;
}

.profile-picker__option-pronouns {
  font-size: 0.78rem;
  font-style: italic;
  color: color-mix(in srgb, var(--text) 75%, transparent);
}

.profile-picker__option-subtitle {
  display: block;
  font-size: 0.78rem;
  color: color-mix(in srgb, var(--text) 75%, transparent);
}

.profile-picker__empty {
  padding: 0.5rem 0.75rem;
  margin: 0;
  font-size: 0.85rem;
  color: color-mix(in srgb, var(--text) 65%, transparent);
}

/* Separates the profile options from the group options within the same
   picker menu — a heading rather than a second scrollable list, so the
   profile-filter controller's flat option list (and its "no matches" empty
   state) keeps working unmodified across both sections. */
.profile-picker__group-label {
  margin: 0.4rem 0 0.1rem;
  padding: 0 0.6rem;
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: color-mix(in srgb, var(--text) 60%, transparent);
}

.profile-picker__group-label:first-child {
  margin-top: 0;
}

.composer-input-row {
  display: flex;
  gap: 0.6rem;
  align-items: flex-end;
}

.composer-input-row textarea {
  flex: 1;
  line-height: 1.4;
  /* The shared textarea rule sets a 100px min-height sized for full-page
     forms — way more than the composer's own rows="1" needs, and on a
     fixed-viewport chat layout every extra pixel here is one less pixel for
     the message history. composer_controller.js#autoGrow drives the actual
     height as you type via an inline style; these are just the floor (one
     line) and ceiling (six lines) it's clamped between. */
  min-height: 2.6rem;
  max-height: 9.6rem;
  resize: none;
  overflow-y: auto;
}

/* Server invites */
.invite-generator {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.invite-generator__regenerate {
  margin-top: 1rem;
}

.invite-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.5rem;
  padding: 1rem 0;
}

.invite-card .avatar {
  margin-bottom: 0.25rem;
}

.invite-card__title {
  margin: 0;
}

.invite-card__subtitle,
.invite-card__description {
  margin: 0;
  font-size: 0.85rem;
  color: color-mix(in srgb, var(--text) 80%, transparent);
}

.invite-card__description {
  margin-bottom: 0.75rem;
}

.invite-card__accept-preview {
  pointer-events: none;
  opacity: 0.85;
}

/* ── Chat identity settings ────────────────────────────── */

.chat-identity-page {
  max-width: 1200px;
}

.back-link {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  color: color-mix(in srgb, var(--text) 80%, transparent);
  text-decoration: none;
  font-size: 0.85rem;
  margin-bottom: 0.75rem;
}

.back-link:hover {
  color: var(--text);
  text-decoration: underline;
}

.back-link span {
  font-size: 1.1rem;
}

.chat-identity-intro__sub {
  display: block;
  margin-top: 0.35rem;
  color: color-mix(in srgb, var(--text) 75%, transparent);
  font-size: 0.85rem;
}

.chat-identity-layout {
  display: grid;
  grid-template-columns: 1fr 380px;
  gap: 2rem;
  align-items: start;
}

.chat-identity-preview-col {
  position: sticky;
  top: 2rem;
  max-height: calc(100vh - 4rem);
  overflow-y: auto;
}

/* Field cards: "Use main" / "Set for chat" per field */

.chat-identity-field__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
}

.chat-identity-field__head h3 {
  margin: 0 0 0.25rem;
  font-size: 1.05rem;
}

.chat-identity-field__head .form-hint {
  margin: 0;
  max-width: 38ch;
}

.chat-identity-toggle {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  border: 1px solid var(--input-border);
  border-radius: 999px;
  padding: 3px;
  gap: 2px;
  background-color: var(--input-bg);
}

.chat-identity-toggle__option {
  position: relative;
  display: inline-block;
  margin-bottom: 0;
  cursor: pointer;
}

.chat-identity-toggle__input {
  position: absolute;
  inset: 0;
  opacity: 0;
  pointer-events: none;
}

.chat-identity-toggle__option-label {
  display: inline-block;
  line-height: 1;
  padding: 0.4rem 0.8rem;
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 600;
  color: color-mix(in srgb, var(--text) 70%, transparent);
  white-space: nowrap;
  transition: background-color 0.12s ease, color 0.12s ease;
}

.chat-identity-toggle__option-label:hover {
  color: var(--heading);
}

.chat-identity-toggle__input:checked + .chat-identity-toggle__option-label {
  background-color: var(--secondary-button-bg);
  color: var(--secondary-button-text);
}

.chat-identity-toggle__input:focus-visible + .chat-identity-toggle__option-label {
  outline: 2px solid var(--link);
  outline-offset: 2px;
}

@media (forced-colors: active) {
  /* The checked/unchecked distinction is otherwise carried entirely by
     background-color, which forced-colors mode flattens away — nothing
     then shows which pill is selected. outline (not border) so it draws
     inward rather than shifting the pill's box size. */
  .chat-identity-toggle__input:checked + .chat-identity-toggle__option-label {
    outline: 2px solid CanvasText;
    outline-offset: -2px;
  }
}

.chat-identity-field__inherited {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.5rem;
  padding: 0.6rem 0.85rem;
  border-radius: 6px;
  background-color: color-mix(in srgb, var(--link) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--link) 30%, transparent);
  font-size: 0.9rem;
}

/* The avatar card's "Use main" state is just the image — the tinted
   panel styling that works for a line of text looks like an unnecessary box
   around it, so this variant keeps the same element (still what the JS
   toggle shows/hides) without the surrounding chrome. */
.chat-identity-field__inherited--plain {
  padding: 0;
  border: none;
  background: none;
}

.chat-identity-field__value {
  min-width: 0;
}

.chat-identity-field__blank {
  font-style: italic;
  color: color-mix(in srgb, var(--text) 65%, transparent);
}

.chat-identity-field__override {
  margin-top: 0.85rem;
}

.chat-identity-field__override .form-hint {
  margin-top: 0.4rem;
  margin-bottom: 0;
}

/* Live preview column */

.preview-block {
  background-color: var(--pane-bg);
  border: 1px solid var(--pane-border);
  border-radius: 8px;
  margin-bottom: 1rem;
  overflow: hidden;
}

.preview-block:last-child {
  margin-bottom: 0;
}

.preview-block__body {
  padding: 1rem;
}

.mini-profile__header {
  display: flex;
  flex-wrap: wrap;
  gap: 0.85rem;
  align-items: flex-start;
}

.mini-profile__header .avatar {
  flex-shrink: 0;
}

.mini-profile__header .tag-line {
  flex-basis: 100%;
  margin: 0;
}

/* Edge-to-edge banner, same technique as .card > .card__header — the
   negative margin equals whichever ancestor's own padding it needs to
   counteract, since the real popover and the settings-page preview wrap
   .mini-profile in differently-padded containers. */
.mini-profile-popover > .mini-profile > .mini-profile__header {
  background-color: var(--header-bg);
  margin: -1.25rem -1.25rem 1rem;
  padding: 1.25rem;
  border-radius: 9px 9px 0 0;
}

.preview-block__body > .mini-profile > .mini-profile__header {
  background-color: var(--header-bg);
  margin: -1rem -1rem 1rem;
  padding: 1rem;
  border-radius: 7px 7px 0 0;
}

/* No description and the full-page link is off (or this is a Group, which
   has no link-toggle-independent description either way) — the header is
   .mini-profile's only child, so there's nothing left to reserve the
   trailing margin for. Collapse it flush with the container's own bottom
   edge instead of leaving dead empty space below the header. */
.mini-profile-popover > .mini-profile > .mini-profile__header:last-child {
  margin-bottom: -1.25rem;
  border-radius: 9px;
}

.preview-block__body > .mini-profile > .mini-profile__header:last-child {
  margin-bottom: -1rem;
  border-radius: 7px;
}

@media (forced-colors: active) {
  .mini-profile-popover > .mini-profile > .mini-profile__header,
  .preview-block__body > .mini-profile > .mini-profile__header {
    border-bottom: 1px solid CanvasText;
  }
}

.mini-profile__name {
  margin: 0;
  font-size: 1.1rem;
  color: var(--heading);
}

.mini-profile__description {
  margin-top: 0.85rem;
  margin-bottom: 0.5rem;
  padding-top: 0.85rem;
  max-height: 12rem;
  overflow-y: auto;
}

.mini-profile__link {
  margin-top: 0.85rem;
  padding-top: 0.85rem;
  font-size: 0.85rem;
}

/* The real chat popover, fetched on demand — .mini-profile itself (above)
   is shared with the settings-page preview, which wraps it in .preview-block
   instead of this. Positioned via inline left/top set by
   mini_profile_popover_controller.js; inset/margin here override the
   browser's default centered [popover] placement so those take effect. */
.mini-profile-popover {
  /* Explicit, rather than relying on the browser's default [popover]
     hiding — that default apparently doesn't reliably apply to a
     <turbo-frame>, a custom element, so it rendered visibly inline above
     every message before ever being opened. */
  display: none;
  position: fixed;
  inset: auto;
  margin: 0;
  width: min(320px, calc(100vw - 1rem));
  max-height: min(28rem, calc(100vh - 1rem));
  overflow-y: auto;
  padding: 1.25rem;
  background-color: var(--pane-bg);
  /* The [popover] UA stylesheet also defaults color to CanvasText — without
     overriding it here too, anything inside that doesn't set its own color
     (e.g. .profile-description) inherits that instead of the theme. */
  color: var(--text);
  border: 1px solid var(--pane-border);
  border-radius: 10px;
  box-shadow: 0 8px 24px color-mix(in srgb, var(--pane-border) 60%, transparent);
}

.mini-profile-popover:popover-open {
  display: block;
}

/* Responsive: stack the preview under the form on narrow screens */
@media (max-width: 900px) {
  .chat-identity-layout {
    grid-template-columns: 1fr;
  }

  .chat-identity-preview-col {
    position: static;
    max-height: none;
  }
}

@media (max-width: 600px) {
  .chat-identity-page {
    max-width: 100%;
  }
}
