.library__header {
  display: flex;
  flex-direction: column;
  gap: var(--inline-space-half);
}

.library__title {
  font-size: 1.15rem;
  font-weight: 600;
  line-height: 1.2;
  display: none;
}

.panel {
  --panel-width: 50ch;
  --panel-padding: 1em;
  --panel-shadow:
    0 0 0 1px oklch(var(--lch-always-black) / 0.02),
    0 .2em 1.6em -0.8em oklch(var(--lch-always-black) / 0.2),
    0 .4em 2.4em -1em oklch(var(--lch-always-black) / 0.3),
    0 .4em .8em -1.2em oklch(var(--lch-always-black) / 0.4),
    0 .8em 1.2em -1.6em oklch(var(--lch-always-black) / 0.5),
    0 1.2em 1.6em -2em oklch(var(--lch-always-black) / 0.6);

  inline-size: var(--panel-width);
  margin: var(--block-space-double) auto var(--block-space);
  max-inline-size: 100vw;
  padding: var(--panel-padding);

  @media (min-width: 1024px) {
    --panel-padding: 2em;

    box-shadow: var(--panel-shadow);
    background-color: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: 0.8em;
  }
}

/* Room-edit tabs ride the shared segmented-control look */
/* Room settings — an in-shell column: tab pill, then the settings cards */
body.room-settings #main-content {
  justify-content: flex-start;
}

.room-settings-page {
  display: flex;
  flex-direction: column;
  gap: 16px;
  max-inline-size: 676px;
  padding: 16px 18px 40px;

  [role="tabpanel"]:not([hidden]) {
    display: flex;
    flex-direction: column;
    gap: 16px;
  }

  /* The stack's gap does the spacing between labelled cards; the label hugs
     its own card instead */
  .settings-label {
    margin-block-end: -10px;
  }
}

/* The name/description card (labels + inputs bring their own rhythm, so no
   per-child hairlines here) */
.room-settings-card {
  padding-block: 18px;

  > * {
    padding-block: 0;
  }

  > * + * {
    border-block-start: none;
  }
}

.room-settings-form__submit {
  margin-block-start: 18px;
}

.room-settings-form__name {
  font-size: 1.1875rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  margin: 0;
}

.setting-row--disabled {
  opacity: 0.55;
}

.room-tabs {
  align-items: center;
  align-self: flex-start;
  background-color: var(--color-border);
  border-radius: var(--border-radius-pill);
  display: inline-flex;
  gap: 2px;
  padding: 3px;
}

.room-tabs [role="tab"] {
  background: none;
  border: none;
  border-radius: var(--border-radius-pill);
  color: var(--color-text-muted);
  cursor: pointer;
  font: inherit;
  font-size: 0.8125rem;
  font-weight: 600;
  line-height: 1.2;
  padding: 5px 14px;
  text-align: center;
  white-space: nowrap;
}

.room-tabs [role="tab"][aria-selected="true"] {
  background-color: var(--color-bg);
  box-shadow: var(--shadow-raise);
  color: var(--color-text);
}

.room-tabs [role="tab"]:hover:not([aria-selected="true"]) {
  color: var(--color-text);
}

.panel--wide {
  --panel-width: 80ch;
}

.panel--centered {
  --panel-width: 28rem;
  --panel-padding: 1.5em;
  max-inline-size: calc(100vw - 2rem);
  margin: 0;
  box-shadow: var(--panel-shadow);
  background-color: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: 0.8em;
}

.panel--centered fieldset {
  min-inline-size: 0;
}

@media (max-width: 480px) {
  .panel--centered .txt-large {
    font-size: 1.1rem;
  }
}

/* Members directory: small-caps heading above a bordered card of list rows.
   The card keeps the {role}s_section id — Turbo Streams append rows to it. */
/* Members directory — one bordered roster card. Role groups are sunk header
   bands inside it, not separate cards, so the page reads as a single list. */
.members-roster {
  background-color: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: 14px;
  overflow: hidden;
}

/* Groups with no one in them are omitted rather than shown empty. */
.members-roster__group:not(:has(turbo-frame[id^="user_"])) {
  display: none;
}

.members-roster__band {
  align-items: baseline;
  background-color: var(--color-bg-sunk);
  border-block: 1px solid var(--color-border);
  display: flex;
  gap: 8px;
  padding: 9px 15px;
}

/* The first band rides the card's own top border rather than doubling it. */
.members-roster > :first-child .members-roster__band,
.members-roster > .members-roster__band:first-child {
  border-block-start: 0;
}

.members-roster__band-label {
  color: var(--color-text-subtle);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

.members-roster__band-count {
  color: var(--color-text-subtle);
  font-size: 0.6875rem;
  font-variant-numeric: tabular-nums;
}

/* Rows sit directly on the card; the band carries the separation. */
.role-section {
  border: 0;
  border-radius: 0;
}

/* Deactivated and banned rows gray the NAME only — the avatar stays at full
   opacity so a dimmed row never reads as still loading. */
.is-deactivated .list-row__title strong,
.is-banned .list-row__title strong {
  color: var(--color-text-subtle);
}

.status-chip {
  border-radius: 4px;
  flex: none;
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  padding: 1px 6px;
  text-transform: uppercase;
}

.status-chip--deactivated {
  background-color: var(--color-bg-sunk);
  color: var(--color-text-subtle);
}

.status-chip--banned {
  background-color: var(--color-bg-negative);
  color: var(--color-negative);
}

/* Member row extras on the shared .list-row rhythm */
.member-row__avatar {
  position: relative;
}

.member-row__dot {
  border: 2px solid var(--color-bg);
  block-size: 10px;
  inline-size: 10px;
  inset-block-end: -2px;
  inset-inline-end: -2px;
  position: absolute;
}

.member-badge {
  --badge-color: var(--color-accent-brand);

  background-color: color-mix(in srgb, var(--badge-color) 14%, transparent);
  border-radius: 4px;
  color: var(--badge-color);
  flex: none;
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  padding: 1px 6px;
  text-transform: uppercase;
}

/* Members directory page — an in-shell column: toolbar row (search + status
   tabs), then the role-section cards */
body.members #main-content {
  justify-content: flex-start;
}

.members-page {
  /* No horizontal padding: the settings shell's inner already insets the
     column, and adding more here pushes the toolbar and roster out of line
     with the settings-header above them. */
  padding: 0 0 28px;
}

.members-toolbar {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  padding-block: 14px 12px;
}

.members-toolbar__form {
  flex: 1;
  max-inline-size: 340px;
  min-inline-size: 220px;
}

.members-toolbar__search {
  inline-size: 100%;
}

.members-list {
  max-inline-size: 820px;
}

.members-page .member-row {
  flex-wrap: nowrap;
}

/* Role control lives in a fixed column so every caret lines up on the right. */
.member-controls {
  align-items: center;
  display: flex;
  flex: none;
  gap: 8px;
  inline-size: 130px;
  justify-content: flex-end;
}

/* Ghost button that opens the manage-member modal — border and fill appear on
   hover only. */
.member-role__control {
  align-items: center;
  border: 1px solid transparent;
  border-radius: 8px;
  color: var(--color-text-muted);
  cursor: pointer;
  display: inline-flex;
  font-size: 0.78125rem;
  font-weight: 600;
  gap: 6px;
  padding: 5px 10px;
  text-decoration: none;
}

@media (any-hover: hover) {
  .member-role__control:hover {
    background-color: var(--color-bg-hover);
    border-color: var(--color-border);
  }
}

.member-role__caret {
  font-size: 0.5625rem;
  opacity: 0.7;
}

/* Your own row, or a viewer who can't act — the role renders as plain text. */
.member-role__readonly {
  color: var(--color-text-subtle);
  font-size: 0.78125rem;
  font-weight: 600;
  padding: 5px 10px;
}

/* Lazy-page sentinel — three placeholder rows on the real row rhythm, fading
   away, so the incoming frame swaps in where they sat instead of pushing the
   list down. The frame needs its own box (turbo-frame is display:contents by
   default) or Turbo's lazy IntersectionObserver has nothing to observe and the
   next page never loads. */
.members-skeleton {
  display: block;
}

.member-skeleton {
  align-items: center;
  border-block-end: 1px solid var(--color-border);
  display: flex;
  gap: 11px;
  opacity: calc(1 - var(--row) * 0.35);
  padding: 12px 15px;
}

.member-skeleton:last-child {
  border-block-end: 0;
}

.member-skeleton__avatar {
  background-color: var(--color-bg-sunk);
  block-size: 32px;
  border-radius: 50%;
  flex: none;
  inline-size: 32px;
}

.member-skeleton__lines {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 6px;
}

.member-skeleton__bar {
  background-color: var(--color-bg-sunk);
  block-size: 9px;
  border-radius: 5px;
}

.member-skeleton__bar--name {
  inline-size: 40%;
}

.member-skeleton__bar--sub {
  inline-size: 26%;
}

.member-skeleton__role {
  background-color: var(--color-bg-sunk);
  block-size: 24px;
  border-radius: 8px;
  flex: none;
  inline-size: 92px;
}

/* Browse rooms: an in-shell column holding a bordered card of list rows */
body.browse #main-content {
  justify-content: flex-start;
}

.browse-page {
  padding: 16px 18px 30px;
}

.browse-card {
  border: 1px solid var(--color-border);
  border-radius: 12px;

  .browse-page & {
    max-inline-size: 760px;
  }
}

.browse-room__glyph {
  align-items: center;
  display: inline-flex;
  flex: none;
  inline-size: 20px;
  justify-content: center;
}

/* Non-action state for rooms you're already in */
.browse-room__joined {
  border: 1px solid var(--color-border);
  border-radius: 8px;
  color: var(--color-text-muted);
  display: inline-block;
  font-size: 0.78125rem;
  font-weight: 600;
  padding: 6px 13px;
}

.status-dot {
  width: 0.5em;
  height: 0.5em;
  border-radius: 50%;
  flex-shrink: 0;
  align-self: center;
}

.status--active  { background-color: var(--color-positive); }
.status--away    { background-color: var(--color-alert); }
.status--offline { background-color: var(--color-border-darker); }

@media (max-width: 480px) {
  /* Keep the row on one line — the compact role control sizes to its content
     rather than reserving the desktop 130px alignment column, so the name
     keeps room and nothing wraps to an awkward second line. */
  .members-page .member-row .member-controls {
    inline-size: auto;
  }
}

.panel__button {
  inset-block-start: var(--block-space);
  inset-inline-start: var(--block-space);
  position: absolute;
}

.library {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  gap: var(--block-space-double);
  overflow-y: auto;
  padding: var(--block-space-double) var(--inline-space);
  margin-top: 40px;
}

.library__section {
  display: flex;
  flex-direction: column;
  padding: var(--block-space) var(--inline-space);
}

.library__section-title {
  font-size: 1.6rem;
  font-weight: 600;
}

.library__card {
  display: flex;
  flex-direction: column;
  gap: var(--block-space);
  padding-top: 2px;
  padding-bottom: 4px;
}

.library__videos {
  display: flex;
  flex-direction: column;
  gap: var(--block-space-double);
}



.library__iframe {
  position: relative;
  padding-block-start: var(--library-aspect, 56.25%);
}

.library__iframe > iframe {
  aspect-ratio: 16 / 9;
  border: 0;
  border-radius: 0.8em;
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
}

.library__actions {
  display: flex;
  gap: var(--inline-space);
}

.library__download-dialog {
  --width: 32rem;
  min-block-size: 18rem;

  @media (max-width: 1024px) {
    --width: calc(100vw - 2rem);
    max-inline-size: calc(100vw - 1rem);
    margin: 0.5rem;
  }
}

.library__download-header {
  display: flex;
  flex-direction: column;
  gap: var(--inline-space-half);
  padding: 1.5rem 1.5rem 1rem;

  @media (max-width: 1024px) {
    padding: 1rem 1rem 0.75rem;
  }
}

.library__download-title {
  font-size: 1.25rem;
  font-weight: 600;

  @media (max-width: 1024px) {
    font-size: 1.1rem;
  }
}

.library__download-subtitle {
  color: var(--color-text-lighter);
  font-size: 0.95rem;

  @media (max-width: 1024px) {
    font-size: 0.9rem;
  }
}

.library__download-body {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  min-block-size: 12rem;
  padding: 0 1.5rem 1.5rem;

  @media (max-width: 1024px) {
    gap: 0.75rem;
    padding: 0 1rem 1rem;
  }
}

.library__download-loading {
  align-items: center;
  color: var(--color-text-lighter);
  display: flex;
  font-size: 0.95rem;
  gap: 0.75rem;
  justify-content: center;
  min-block-size: 5rem;

  @media (max-width: 1024px) {
    flex-direction: column;
    gap: 0.5rem;
    text-align: center;
  }
}

.library__download-loading-text {
  flex: 1;

  @media (max-width: 1024px) {
    flex: none;
  }
}

.library__download-error {
  color: var(--color-text-lighter);
  font-size: 0.95rem;
  min-block-size: 5rem;
  text-align: center;
}

.library__download-loading .spinner {
  block-size: 1.75rem;
  color: currentColor;
  inline-size: 1.75rem;

  @media (max-width: 1024px) {
    block-size: 1.5rem;
    inline-size: 1.5rem;
  }
}

.library__download-error[hidden] {
  display: none;
}

.library__download-list {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin: 0;
  padding: 0;
  list-style: none;

  @media (max-width: 1024px) {
    gap: 0.5rem;
  }
}

.library__download-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.75rem;
  padding: 0.75rem 1rem;
  border: 1px solid var(--color-border);
  border-radius: 0.75rem;

  @media (max-width: 1024px) {
    flex-direction: column;
    align-items: stretch;
    gap: 0.5rem;
    padding: 0.75rem;
  }
}

.library__download-meta {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;

  @media (max-width: 1024px) {
    align-items: center;
    text-align: center;
  }
}

.library__download-quality {
  font-weight: 600;
}

.library__download-details {
  color: var(--color-text-lighter);
  font-size: 0.9rem;
}

.library__download-link {
  --btn-border-radius: 999px;
  --btn-padding: 0.45rem 1rem;
  text-decoration: none;

  @media (max-width: 1024px) {
    inline-size: 100%;
    justify-content: center;
  }
}

.library__download-fallback {
  display: inline-flex;
  flex-direction: column;
  gap: 0.2rem;
  align-items: center;
  justify-content: center;
  padding: 0.75rem 1rem;
  border: 1px solid var(--color-border);
  border-radius: 0.75rem;
  text-decoration: none;
  color: inherit;
  transition: background-color 0.15s ease, border-color 0.15s ease;
  min-width: fit-content;

  @media (max-width: 1024px) {
    inline-size: 100%;
    padding: 0.75rem;
  }
}

.library__download-fallback:hover {
  background-color: var(--color-background-hover);
  border-color: var(--color-border-hover);
}

.library__download-fallback-text {
  font-weight: 600;
  text-align: center;
}

.library__download-fallback-size {
  color: var(--color-text-lighter);
  font-size: 0.9rem;
  text-align: center;
}

.library__download-fallback[hidden] {
  display: none;
}

/* Inline message block — sits inside a form or section, not the page-level flash. */
.callout {
  align-items: flex-start;
  border-radius: 1em;
  display: flex;
  gap: var(--inline-space);
  padding: var(--block-space-half) var(--inline-space-half);
}

.callout--alert {
  background-color: color-mix(in oklch, var(--color-alert) 12%, transparent);
}

