/* Lassy Meet — pre-join screen.

   A transcription of Teams' `calling-prejoin-screen`. The numbers are the
   reference's own: content column 32rem–101.4rem centred with 2.4rem/2rem
   padding (`f1cgr00c`/`fqd4p9h`/`fcpdi13`/`f1bo9zpg`), header icon 4.4rem
   (`f75xlot`), preview/audio split 1.13 : 1 (`f1kr9b3g` vs `fz7g6wx`),
   action bar 4.8rem tall (`f301xjs`) with a 1px top rule.

   One deliberate addition: Teams already knows who you are, we don't, so
   the display-name field sits under the audio options. It reuses the same
   Fluent field styling so it doesn't read as bolted on.
*/

/* A row now: the card in one column, the background rail in the other. The
   rail is `hidden` until asked for, so with it closed this is exactly the
   centred card it has always been -- the column carries all the old rules. */
.prejoin {
  position: relative;
  display: flex;
  flex-direction: row;
  width: 100%;
  height: 100%;
  background-color: var(--colorNeutralBackground3);
  min-height: 0;
}

.prejoin__col {
  position: relative;
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
  height: 100%;
  overflow-y: auto;
  justify-content: flex-start;
}

.prejoin__rail {
  display: flex;
  flex: 0 0 var(--sidePanelWidth);
  width: var(--sidePanelWidth);
  min-width: 0;
  padding: var(--spacingVerticalS) var(--spacingHorizontalS) var(--spacingVerticalS) 0;
}
.prejoin__rail[hidden] { display: none; }
.prejoin__rail .panel { flex: 1; margin: 0; }

/* Below the point where a side-by-side stops making sense, the rail takes the
   screen -- the same breakpoint the meeting's panel uses. */
@media (max-width: 1000px) {
  .prejoin__rail { position: absolute; inset: 0; flex-basis: auto; width: auto; padding: 0; z-index: 4; }
  .prejoin__rail .panel { border-radius: 0; }
}

.prejoin__content {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100%;
  /* min-width would force a horizontal scrollbar below 320px; the floor
     belongs on the content, not the column. */
  max-width: 101.4rem;
  /* `fcpdi13` — and it is doing more work than centring a column.
     Auto margins in a flex column absorb the free space *before*
     justify-content gets a look in, so the space splits equally above and
     below this block and the footer below it lands on the bottom edge. That
     is where the reference's generous empty top and bottom come from; they
     are not padding.

     When the block is taller than the window the auto margins collapse to
     zero, so it starts at the top and scrolls rather than having its head
     cut off — which is what plain centring does. */
  margin: auto;
  padding: 2.4rem 2rem;
  flex-shrink: 0;
}

/* --------------------------------------------------------------------- */
/* Account chip — signed-in guests only, floating at the top centre        */
/* --------------------------------------------------------------------- */

.account-chip {
  position: absolute;
  top: var(--spacingVerticalM);
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: var(--spacingHorizontalM);
  max-width: calc(100% - 3.2rem);
  padding: var(--spacingVerticalS) var(--spacingHorizontalM);
  background-color: var(--colorNeutralBackground1);
  border: 0.1rem solid var(--colorNeutralStroke2);
  border-radius: var(--borderRadiusMedium);
  box-shadow: var(--shadow4);
  z-index: 2;
}
.account-chip[hidden] { display: none; }
.account-chip__text { min-width: 0; }

/* The anonymous joiner's avatar: a neutral disc with a silhouette, not one of
   the identity-keyed colours — there is no identity to key it to. */
.avatar--guest {
  background-color: var(--colorNeutralBackground4);
  color: var(--colorNeutralForeground3);
  font-size: 16px;
  line-height: 0;
}
.avatar--guest svg { width: 1.6rem; height: 1.6rem; }

/* Change is inert for a guest — there is no other account to switch to. */
.account-chip__change:disabled {
  color: var(--colorNeutralForegroundDisabled);
  cursor: default;
  text-decoration: none;
}
.account-chip__name {
  font-size: var(--fontSizeBase300);
  line-height: var(--lineHeightBase300);
  color: var(--colorNeutralForeground1);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.account-chip__email {
  font-size: var(--fontSizeBase200);
  line-height: var(--lineHeightBase200);
  color: var(--colorNeutralForeground3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  max-width: 18rem;
}
.account-chip__change { flex-shrink: 0; font-size: var(--fontSizeBase300); }

/* --------------------------------------------------------------------- */
/* Header — meeting icon and title                                        */
/* --------------------------------------------------------------------- */

/* Centred column, not a row: `prejoin-meeting-details-content` in the
   reference is `flex-direction: column` + `align-items: center` all the way
   down, with the glyph stacked above the title. */
.prejoin__header {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100%;
  margin-bottom: 1.6rem;
}

.prejoin__header__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 4.4rem;
  min-width: 4.4rem;
  height: 4.4rem;
  min-height: 4.4rem;
  margin-bottom: 1.6rem;
}
.prejoin__header__icon svg,
.prejoin__header__icon img { width: 4.2rem; height: 4.2rem; }

.prejoin__header__text {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.9rem;
  width: 100%;
  min-width: 0;
  text-align: center;
}

/* Waiting for admission: the greeting is a sentence, not a meeting name, so
   it wraps instead of truncating. */
.prejoin__title--lobby {
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
  text-wrap: balance;
  max-width: 62rem;
}

/* The meeting title, demoted to a caption once the greeting takes the heading. */
.prejoin__subtitle {
  margin: 0;
  text-align: center;
  font-size: var(--fontSizeBase300);
  line-height: var(--lineHeightBase300);
  color: var(--colorNeutralForeground1);
}
.prejoin__subtitle[hidden] { display: none; }

.prejoin__title {
  margin: 0;
  text-align: center;
  font-size: var(--fontSizeBase500);
  line-height: var(--lineHeightBase500);
  font-weight: var(--fontWeightSemibold);
  color: var(--colorNeutralForeground1);
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.prejoin__subtitle {
  margin: 0;
  text-align: center;
  font-size: var(--fontSizeBase300);
  line-height: var(--lineHeightBase300);
  font-weight: var(--fontWeightRegular);
  color: var(--colorNeutralForeground2);
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.prejoin__alert { width: 100%; margin-bottom: 1.6rem; }

/* --------------------------------------------------------------------- */
/* Body — preview on the left, audio options on the right                 */
/* --------------------------------------------------------------------- */

/* `align-items: stretch` is what makes the two columns end level. The preview
   sets the height (16:9 stage plus a 4.8rem action bar); the audio column
   stretches to match, and the selected option — which carries `flex: 4` —
   takes up the slack. */
.prejoin__body {
  display: flex;
  flex-direction: row;
  align-items: stretch;
  justify-content: space-between;
  gap: 1.6rem;
  width: 100%;
  margin-bottom: 2.4rem;
  position: relative;
  z-index: 2;
  /* On a short window this is what gives, and it gives *once* — both columns
     are the same height, so capping the row keeps them level and the camera
     stage flexes into whatever is left. Column widths, the 101.4rem cap and
     the action bar are all untouched.

     29.9rem is everything stacked above and below: header, name field,
     buttons, footer link and the 2.4rem padding. The 29.3rem floor is what
     the audio column needs with its header at the minimum — below that the
     page scrolls rather than the options being squeezed into an unreadable
     stack. Above roughly an 840px viewport the subtraction exceeds the
     natural height and none of this applies. */
  max-height: max(29.3rem, calc(100vh - 29.9rem));
}

/* -- video preview ---------------------------------------------------- */

.preview {
  display: flex;
  flex-direction: column;
  flex: 1.13;
  min-width: 0;
  position: relative;
  border: 0.1rem solid var(--colorNeutralStroke2);
  border-radius: var(--borderRadiusMedium);
  background-color: var(--colorNeutralBackground2);
  box-shadow: 0 0.08rem 0.18rem 0 rgba(0, 0, 0, 0.13), 0 0.015rem 0.045rem 0 rgba(0, 0, 0, 0.11);
}

/* The camera-off state sits on the card, not on a dark plate — the container
   is `--colorNeutralBackground2` in the reference (`f1dmdbja`) and the live
   client shows a light preview area. Only actual video paints dark, because
   the frame itself is. */
.preview__stage {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  /* 16:9 is the *preferred* height, not a fixed one: the stage then flexes to
     fill whatever height the card ends up with. Capping the stage directly
     instead left the card taller than stage + action bar on a short window,
     with a visible gap under the bar. */
  aspect-ratio: 16 / 9;
  flex: 1 1 auto;
  min-height: 0;
  position: relative;
  overflow: hidden;
  background-color: var(--colorNeutralBackground2);
  border-radius: var(--borderRadiusMedium) var(--borderRadiusMedium) 0 0;
}
.preview__stage:has(.preview__video) { background-color: var(--grey8); }

.preview__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Self-view is mirrored; what you publish is not. */
  transform: scaleX(-1);
  background-color: var(--grey8);
}

.preview__off {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--spacingVerticalS);
  width: 100%;
  height: 100%;
  color: var(--colorNeutralForeground1);
  text-align: center;
  padding: var(--spacingVerticalL);
}
.preview__off svg { width: 2.4rem; height: 2.4rem; }
.preview__off__text {
  font-size: var(--fontSizeBase300);
  line-height: var(--lineHeightBase300);
  font-weight: var(--fontWeightSemibold);
}

.preview__avatar { --avatar-bg: var(--brand60); }

/* Action bar under the preview. */
.preview__actions {
  display: flex;
  align-items: center;
  justify-content: center;
  /* `f301xjs` + `f15eez92`: the bar reserves 4.8rem but is capped at 4.4rem,
     so 44px is what it actually measures. */
  flex: 0 0 4.8rem;
  max-height: 4.4rem;
  width: 100%;
  /* No padding here — the reference puts it on the toolbar inside. */
  padding: 0;
  border-top: 0.1rem solid var(--colorNeutralStroke2);
  border-radius: 0 0 var(--borderRadiusMedium) var(--borderRadiusMedium);
  background-color: var(--colorNeutralBackground1);
  gap: 0;
}

/* The reference's `fui-Toolbar`, the actions bar's *only* child:
   `fj96rs0` flex 1 1 0%, `fly5x3f` width 100%, `fkb01wt` padding .7rem,
   `fqrbt79` column-gap 0, `f122n59` align-items center — and **no
   justify-content at all**.

   Which is why the camera button sits at the left edge. The bar above it does
   carry `justify-content: center` (`f4d9j23`), but that centres one child
   which is already full width, so it does nothing. Reading the container and
   stopping there is how I got this backwards: the alignment is decided by the
   child, not the parent. */
.preview__actions__group {
  display: flex;
  align-items: center;
  flex: 1 1 0%;
  width: 100%;
  min-width: 0;
  padding: 0.7rem;
  column-gap: 0;
  overflow-x: hidden;
}

/* The camera cluster: mute-style button, flyout chevron, then the switch. */
.toggle-cluster { display: flex; align-items: center; padding-right: 0.2rem; }
.toggle-cluster .btn { min-width: 3.2rem; width: 3.2rem; height: 3.2rem; padding: 0; }
.toggle-cluster__chevron { min-width: 2rem !important; width: 2rem !important; }
.toggle-cluster__chevron .btn__icon { font-size: 12px; }

.preview__actions .divider-v { height: 2rem; align-self: center; margin: 0 var(--spacingHorizontalS); }

.btn--bgfilters {
  min-width: 0;
  gap: var(--spacingHorizontalS);
  font-weight: var(--fontWeightRegular);
  font-size: var(--fontSizeBase300);
  padding: 0 var(--spacingHorizontalS);
  height: 3.2rem;
}

/* -- audio options ---------------------------------------------------- */

.audio-options {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
  gap: 0.6rem;
}

.audio-option {
  display: flex;
  flex-direction: column;
  width: 100%;
  flex: 0 0 auto;
  border-radius: var(--borderRadiusMedium);
}
/* The expanded option absorbs the extra height so the column ends level with
   the preview — `f1st3q4c` in the reference. */
.audio-option[data-checked='true'] { flex: 1 1 auto; }

/* …but it must not absorb the *shortage* too. Because both columns are the
   same height, capping the camera preview on a short window pulls this header
   down with it, and being the only elastic thing in the column it takes the
   whole hit — the label ends up crammed against the rule below it while the
   camera area, which is empty, keeps its size.

   The reference's own floor is 50px (`fg07og7`) and it settles around 85 at a
   normal window height. 7rem holds the look down to roughly a 590px viewport;
   past that the camera keeps shrinking instead, which is the right thing to
   spend first. */
.audio-option[data-checked='true'] .audio-option__head { min-height: 7rem; }
.audio-option[aria-disabled='true'] { opacity: 1; }

/* The slack goes into the *header*, which is why the selected option's title
   row is visibly taller than the other two. Putting it in the body instead
   leaves a dead gap under the device rows. */
.audio-option[data-checked='true'] .audio-option__head { flex: 1 1 auto; }

/* The 2rem left inset is what lines the radio up with the device icons
   below it. Reference: `f158opje { padding: 0 0 0 2rem }` on the radio, plus
   the indicator overrides under it — together they put the circle's left
   edge at 22px, against the mic icon's 21px (1.5rem body padding, then the
   20px glyph centred in its 3.2rem button). Without it the radios sit at
   9px and visibly hug the card edge. */
.audio-option__head {
  display: flex;
  align-items: center;
  justify-content: stretch;
  width: 100%;
  min-height: 50px;
  padding-left: 2rem;
  border: 0.1rem solid var(--colorNeutralStroke2);
  border-radius: var(--borderRadiusMedium);
  background-color: var(--colorNeutralBackground1);
  box-shadow: 0 0.08rem 0.18rem 0 rgba(0, 0, 0, 0.13), 0 0.015rem 0.045rem 0 rgba(0, 0, 0, 0.11);
}
.audio-option[data-checked='true'] .audio-option__head { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }

.audio-option__label {
  display: flex;
  align-items: center;
  flex: 1;
  min-width: 0;
  height: 100%;
  padding-right: var(--spacingHorizontalXL);
}

/* Teams' radio is larger than the Fluent default and sits tighter to the
   card edge: 2rem square rather than 16px, `margin-left: .2rem` instead of
   the default 8px, and 1.2rem of clearance before the label. */
.audio-option .radio__indicator {
  width: 2rem;
  height: 2rem;
  margin: var(--spacingVerticalS) 1.2rem var(--spacingVerticalS) 0.2rem;
}
.audio-option .radio__indicator::after { width: 2rem; height: 2rem; }
.audio-option .radio__input { width: 5.2rem; }
/* No `.radio__label { padding: 0 }` here: this markup collapses the
   reference's radio-span and label into one element, so that rule would
   cancel the 2rem inset above. */
.audio-option__title {
  font-size: var(--fontSizeBase300);
  line-height: var(--lineHeightBase300);
  font-weight: var(--fontWeightSemibold);
  margin-right: 0.4rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* An option you cannot pick should not shout. Regular weight on top of the
   disabled colour the radio already applies. */
.audio-option[aria-disabled='true'] .audio-option__title {
  font-weight: var(--fontWeightRegular);
  color: var(--colorNeutralForegroundDisabled);
}

/* Expanded body of the selected option — mic row and speaker row. */
.audio-option__body {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  width: 100%;
  flex: 0 0 auto;
  padding: 1.3rem 1.5rem;
  background-color: var(--colorNeutralBackground5Selected);
  border: 0.1rem solid var(--colorNeutralStroke2);
  border-top: 0;
  border-radius: 0 0 0.4rem 0.4rem;
  gap: var(--spacingVerticalXS);
}

.device-row {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  width: 100%;
  padding: 0.3rem 0.1rem 0.3rem 0;
  gap: var(--spacingHorizontalXXS);
  min-width: 0;
}
.device-row .btn--icon { min-width: 3.2rem; width: 3.2rem; height: 3.2rem; }

.device-row__picker {
  display: flex;
  align-items: center;
  flex: 1;
  min-width: 0;
  gap: var(--spacingHorizontalXXS);
}
/* The toggle owns the right edge; the device button gets what is left. */
.device-row__picker .switch { margin-left: auto; flex-shrink: 0; }

/* The device name button: text + chevron, transparent, truncates hard.
 *
 * `flex: 0 1 auto` is the detail that matters. Stretching the button parks
 * the chevron against the right edge of the row; sized to its content it
 * follows the name, which is what the reference does — the speaker row shows
 * this plainly, since it has no toggle competing for the space. The
 * microphone row still truncates, because the toggle takes the width first.
 */
.device-btn {
  display: inline-flex;
  align-items: center;
  justify-content: flex-start;
  flex: 0 1 auto;
  min-width: 0;
  max-width: 100%;
  gap: var(--spacingHorizontalXXS);
  height: 3.2rem;
  padding: 0 var(--spacingHorizontalXS);
  background: transparent;
  border: 0.1rem solid transparent;
  border-radius: var(--borderRadiusMedium);
  color: var(--colorNeutralForeground2);
  font-size: var(--fontSizeBase300);
  font-weight: var(--fontWeightRegular);
  cursor: pointer;
  overflow: hidden;
}
.device-btn:hover { background-color: var(--colorSubtleBackgroundHover); color: var(--colorNeutralForeground2BrandHover); }
.device-btn:active { background-color: var(--colorSubtleBackgroundPressed); }
.device-btn__text { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: left; }
.device-btn__chevron { font-size: 12px; flex-shrink: 0; }
.device-btn:disabled { color: var(--colorNeutralForegroundDisabled); cursor: default; background: transparent; }

/* Mic level meter — sits behind the mic icon like Teams' animated fill. */
.mic-meter {
  position: relative;
  width: 3.2rem;
  height: 3.2rem;
  flex-shrink: 0;
}
/* The fill belongs INSIDE the capsule of the mic glyph, not behind the whole
   icon. Geometry, so the numbers are checkable: the glyph is 20px
   (`.btn__icon` font-size) centred in a 32px button, so it starts at 6px. In
   Fluent's mic path the capsule runs y=2 to y=13 of a 20-unit viewBox, which
   lands at y=8..19 in the button -- 11px tall, bottom 13px up from the base.
   Running from the base of the icon, as this did, drew a column down through
   the stand and out the bottom. */
.mic-meter__fill {
  position: absolute;
  left: 50%;
  bottom: 1.3rem;
  transform: translateX(-50%);
  width: 0.4rem;
  height: 0;
  max-height: 1.1rem;
  border-radius: var(--borderRadiusCircular);
  background-color: var(--colorCompoundBrandBackground);
  transition: height 80ms linear;
  pointer-events: none;
}

/* -- name field ------------------------------------------------------- */

/* Sits directly under the title, centred and narrow — the position the real
   anonymous join flow uses. Not full width: a name is a short field, and
   stretching it across the column reads as a search box. */
.prejoin__name {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--spacingVerticalXS);
  width: 30rem;
  max-width: 100%;
  margin-top: 1.6rem;
}
.prejoin__name .input { text-align: left; }
.prejoin__name .field { width: 100%; }

/* Quiet by design: almost everyone opening a join link is a guest, and the
   name field is what they want. The organizer is the one person who goes
   looking for this. */
.prejoin__signin {
  align-self: center;
  font-size: var(--fontSizeBase200);
  margin-top: var(--spacingVerticalXXS);
}

.signin {
  display: flex;
  flex-direction: column;
  gap: var(--spacingVerticalS);
  min-width: 32rem;
}
.signin .field { width: 100%; }
.signin__actions { display: flex; justify-content: flex-end; margin-top: var(--spacingVerticalXS); }
.dialog__text {
  margin: 0;
  color: var(--colorNeutralForeground2);
  font-size: var(--fontSizeBase200);
}

/* --------------------------------------------------------------------- */
/* Footer — Cancel / Join now                                             */
/* --------------------------------------------------------------------- */

.prejoin__footer { display: flex; width: 100%; }
.prejoin__footer__actions {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: flex-end;
  flex: 1;
  position: relative;
  z-index: 1;
}
.prejoin__footer__actions .btn {
  flex: 0 0 auto;
  margin-left: 0.8rem;
  padding-left: 1.2rem;
  padding-right: 1.2rem;
}

.prejoin__help {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  width: 100%;
  padding: 0.8rem 0;
  font-size: 1.2rem;
  background-color: var(--colorNeutralBackground3);
}
.prejoin__help > * { padding-right: 1.6rem; }
.prejoin__help > *:last-child { padding-right: 0; }

/* --------------------------------------------------------------------- */
/* Waiting room — replaces the footer actions once a request is pending   */
/* --------------------------------------------------------------------- */

.waiting {
  display: flex;
  align-items: center;
  gap: var(--spacingHorizontalM);
  width: 100%;
  padding: var(--spacingVerticalM) var(--spacingHorizontalL);
  margin-bottom: var(--spacingVerticalM);
  background-color: var(--colorNeutralBackground1);
  border: 0.1rem solid var(--colorNeutralStroke2);
  border-radius: var(--borderRadiusMedium);
}
.waiting__text { flex: 1; min-width: 0; }
.waiting__title { font-weight: var(--fontWeightSemibold); }
.waiting__sub { font-size: var(--fontSizeBase200); line-height: var(--lineHeightBase200); color: var(--colorNeutralForeground3); }

/* --------------------------------------------------------------------- */
/* Tablet and phone                                                       */
/*                                                                        */
/* The two-column split is the first thing to go: below ~860px the preview */
/* would be too narrow to be worth looking at. Everything then reflows to  */
/* a single column, and touch targets grow rather than shrink.            */
/* --------------------------------------------------------------------- */

@media (max-width: 860px) {
  .prejoin__body {
    flex-direction: column;
    align-items: stretch;
    gap: 1.2rem;
    margin-bottom: 1.6rem;
  }
  .preview, .audio-options { flex: 0 0 auto; width: 100%; }
  .prejoin__content { padding: 1.6rem 1.6rem 2.4rem; }

  /* Stacked, a full-width 16:9 preview is tall enough to push the audio
     options off screen entirely. Cap it and letterbox instead. */
  .preview__stage { aspect-ratio: auto; height: min(42vh, 28rem); }

  /* Absolute positioning would sit on top of the content once the column
     is this narrow. */
  .account-chip {
    position: static;
    transform: none;
    width: 100%;
    max-width: 44rem;
    margin: 1.6rem auto 0;
  }
}

@media (max-width: 600px) {
  .prejoin__content { padding: 1.2rem 1.2rem 2rem; }
  .prejoin__header { margin-bottom: 1.2rem; }
  .prejoin__header__icon { width: 3.6rem; min-width: 3.6rem; height: 3.6rem; min-height: 3.6rem; margin-bottom: 1.2rem; }
  .prejoin__header__icon svg { width: 3.4rem; height: 3.4rem; }
  .prejoin__title { font-size: var(--fontSizeBase400); line-height: var(--lineHeightBase400); }

  .prejoin__name { width: 100%; }

  /* Full-bleed actions read as a phone layout and give a proper tap area.
     DOM order is Cancel then Join, so Join lands at the bottom — nearest the
     thumb, and the harder action to hit by accident. */
  .prejoin__footer__actions {
    flex-direction: column;
    align-items: stretch;
    gap: var(--spacingVerticalS);
  }
  .prejoin__footer__actions .btn {
    margin-left: 0;
    width: 100%;
    min-height: 4.4rem;
  }

  /* The action bar under the preview is the tightest row on the screen. */
  .preview__actions { padding: 0.4rem; }
  .btn--bgfilters { font-size: var(--fontSizeBase200); padding: 0 var(--spacingHorizontalXS); }
  .preview__actions .divider-v { margin: 0 var(--spacingHorizontalXS); }

  .audio-option__body { padding: 1rem 1.1rem; }
  .device-row { gap: 0; }
}

/* Coarse pointers get bigger hit areas regardless of viewport width — a
   tablet in landscape is wide but still touched. */
@media (pointer: coarse) {
  .device-btn { min-height: 4rem; }
  .toggle-cluster .btn,
  .device-row .btn--icon { min-width: 4rem; width: 4rem; height: 4rem; }
  .audio-option__head { min-height: 5.6rem; }
}

/* Short windows — phone landscape, or a half-height desktop window. */
@media (max-height: 560px) and (min-width: 861px) {
  .prejoin__content { padding-block: 1.2rem; }
  .prejoin__header { margin-bottom: 0.8rem; }
  .prejoin__header__icon { margin-bottom: 0.8rem; }
  .prejoin__body { margin-bottom: 1.2rem; }
}

/* --------------------------------------------------------------------- */
/* Lobby resolved — denied, or nobody answered                            */
/* --------------------------------------------------------------------- */

/* The reference clears the screen for this: one sentence and two buttons on
   an empty page, with the preview and every control gone. Hiding rather than
   unmounting keeps Dismiss able to put the card back as it was. */
.prejoin--resolved .prejoin__header,
.prejoin--resolved .prejoin__body,
.prejoin--resolved .prejoin__footer,
.prejoin--resolved .prejoin__help,
.prejoin--resolved .account-chip {
  display: none;
}

.prejoin--resolved .prejoin__content {
  justify-content: center;
  flex: 1;
}

.resolved {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--spacingVerticalL);
  text-align: center;
  padding: var(--spacingVerticalXXL) var(--spacingHorizontalL);
}

.resolved__text {
  margin: 0;
  font-size: var(--fontSizeBase400);
  line-height: var(--lineHeightBase400);
  font-weight: var(--fontWeightSemibold);
  color: var(--colorNeutralForeground1);
  max-width: 56rem;
  text-wrap: balance;
}

.resolved__actions {
  display: flex;
  gap: var(--spacingHorizontalS);
}
