/* ============================================================================
   prejoin.css: the page every invite link opens (views/prejoin.ejs)
   ---------------------------------------------------------------------------
   Sits on style_auth.css (tokens, dot grid, Manrope, the primary button) and
   on intro-lobby.css (the camera tile, the checks, the pickers, the card and
   the one-screen phone layout, /talk's design, validated by Alex on 10/09).
   This file only adds what the invite page has and /talk does not: the name
   field, the account chip, the two round camera / microphone buttons on the
   tile, the "who is in the room" line, the sign-in link, the public-room
   note and the in-app-browser note.

   Kept mechanically (rule promoted 2026-08-16): any rule that FORCES a display
   on an element the script may hide with `hidden` carries :not([hidden]).
   ============================================================================ */

/* ── The tile: the person's own choice to walk in with the camera off ────── */
.pj-self {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  color: #ececf3;
}
.pj-video[data-cam="off"][data-state="live"] .pj-self,
.pj-video[data-cam="off"][data-state="camoff"] .pj-self {
  display: flex;
}
/* Camera off by choice: the preview goes dark and the "microphone only"
   overlay (a device that did not come up) steps aside for the avatar. */
.pj-video[data-cam="off"] video {
  opacity: 0 !important;
}
.pj-video[data-cam="off"] .tk-ov--camoff {
  display: none !important;
}
.pj-self-avatar {
  width: 76px;
  height: 76px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: #6366f1;
  color: #fff;
  font: 700 30px/1 var(--sans);
  letter-spacing: -0.02em;
}
.pj-self-avatar:empty {
  background: rgba(255, 255, 255, 0.1);
}
.pj-self-label {
  font: 600 13px/1.2 var(--sans);
  color: #b9b9c9;
}

/* One of the two refused (views/prejoin.ejs, .tk-ov--partial): the same
   overlay grammar as a refusal of both, with the refused device's icon. The
   refusal overlay follows the same data-refused ("both" keeps the camera). */
.tk-video[data-state="partial"] .tk-ov--partial {
  display: flex;
}
.tk-ov--partial .pj-ico-mic,
.tk-ov--denied .pj-ico-mic,
.pj-video[data-refused="mic"] .tk-ov--partial .pj-ico-cam,
.pj-video[data-refused="mic"] .tk-ov--denied .pj-ico-cam {
  display: none;
}
.pj-video[data-refused="mic"] .tk-ov--partial .pj-ico-mic,
.pj-video[data-refused="mic"] .tk-ov--denied .pj-ico-mic {
  display: block;
}

/* The two round buttons, bottom centre of the tile, as every call app has
   taught people. White glass when on, red when off: the colour answers
   "will they hear me?" before the icon is read. */
.pj-toggles {
  position: absolute;
  left: 50%;
  bottom: 12px;
  z-index: 3;
  display: flex;
  gap: 10px;
  transform: translateX(-50%);
}
.pj-tog {
  width: 44px;
  height: 44px;
  padding: 0;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.28);
  background: rgba(15, 15, 22, 0.52);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  color: #fff;
  display: grid;
  place-items: center;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, transform 0.12s;
}
.pj-tog svg {
  display: block;
  width: 19px;
  height: 19px;
}
.pj-tog .pj-ico-off {
  display: none;
}
.pj-tog[aria-pressed="false"] {
  background: #ef4444;
  border-color: #ef4444;
}
.pj-tog[aria-pressed="false"] .pj-ico-on {
  display: none;
}
.pj-tog[aria-pressed="false"] .pj-ico-off {
  display: block;
}
.pj-tog:hover {
  background: rgba(15, 15, 22, 0.72);
}
.pj-tog[aria-pressed="false"]:hover {
  background: #dc2626;
}
.pj-tog:active {
  transform: scale(0.94);
}
.pj-tog:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
}
.pj-tog:disabled {
  opacity: 0.45;
  cursor: default;
}
/* While an overlay speaks (blocked, busy, no device), the buttons would sit on
   its text: they step back until there is a preview to act on. */
.pj-video:not([data-state="live"]):not([data-state="camoff"]) .pj-toggles {
  display: none;
}
/* The name chip moves up on a phone-sized tile so it never sits under the
   buttons; on a laptop tile there is room for both on one line. */
.pj-video .tk-you {
  max-width: calc(50% - 50px);
}

/* "No microphone": a quiet line of its own under the pickers (and in the
   phone's device sheet), the room's no-mic mode chosen before anything opens. */
.pj-nomic {
  flex: 1 1 100%;
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 2px 0 0;
  font: 500 12.5px/1.4 var(--sans);
  color: var(--auth-muted);
  cursor: pointer;
}
.pj-nomic input {
  flex: none;
  width: 15px;
  height: 15px;
  margin: 0;
  accent-color: var(--auth-accent);
  cursor: pointer;
}
.pj-nomic input:focus-visible {
  outline: 2px solid var(--auth-accent);
  outline-offset: 2px;
}

/* ── The card ────────────────────────────────────────────────────────────── */
.pj-panel h1 {
  margin: 0 0 8px;
  overflow-wrap: anywhere;
}
.pj-invite {
  margin: 0 0 8px;
  font: 700 13px/1.35 var(--sans);
  letter-spacing: 0.01em;
  color: var(--auth-accent-text);
}

/* Who is in the room right now: a dot and a line. Green and breathing when
   somebody is there, quiet grey when nobody is or when we could not tell.
   The dot sits on the FIRST line (a long list of names wraps on a phone):
   its top margin is half of what the line height leaves around it. */
.pj-live {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  margin: 0 0 18px;
  font: 600 13.5px/1.35 var(--sans);
  color: var(--auth-muted);
}
.pj-live-dot {
  position: relative;
  width: 9px;
  height: 9px;
  flex: none;
  margin-top: calc(0.675em - 4.5px);
  border-radius: 50%;
  background: var(--auth-placeholder);
}
.pj-live[data-kind="present"] {
  color: var(--auth-ink);
}
.pj-live[data-kind="present"] .pj-live-dot {
  background: #16a34a;
}
.pj-live[data-kind="present"] .pj-live-dot::after {
  content: "";
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  border: 2px solid #16a34a;
  opacity: 0;
  animation: pj-breathe 2.2s ease-out infinite;
}
.pj-live[data-kind="checking"] .pj-live-dot {
  animation: pj-blink 1.2s ease-in-out infinite;
}
@keyframes pj-breathe {
  0% { transform: scale(0.6); opacity: 0.7; }
  100% { transform: scale(1.5); opacity: 0; }
}
@keyframes pj-blink {
  0%, 100% { opacity: 0.35; }
  50% { opacity: 1; }
}

/* A room its owner opened to the world, said in its own warm words above the
   field, never as a hazard notice. */
.pj-open {
  margin: 0 0 16px;
  padding: 12px 14px;
  border: 1px solid var(--auth-info-stroke);
  border-radius: 12px;
  background: var(--auth-info-bg);
  color: var(--auth-muted);
  font-size: 13px;
  line-height: 1.55;
}
.pj-open strong {
  color: var(--auth-ink);
  font-weight: 700;
}

.pj-panel .auth-error {
  margin: 0 0 14px;
}

/* The one field. */
.pj-field {
  margin: 0 0 14px;
}
.pj-label {
  display: block;
  margin: 0 0 7px;
  font: 700 13px/1.2 var(--sans);
  color: var(--auth-ink);
}
.auth-v2 .pj-input {
  height: 48px;
  font-size: 16px; /* 16px: iOS zooms into any smaller field on focus */
}
.pj-input[aria-invalid="true"] {
  border-color: var(--auth-danger);
}
.pj-hint {
  margin: 7px 0 0;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--auth-muted);
}
.pj-hint--err {
  color: var(--auth-danger);
  font-weight: 600;
}
.pj-notyou {
  margin: 6px 0 0;
  font-size: 12.5px;
  color: var(--auth-muted);
}
.pj-notyou a,
.pj-signin a {
  color: var(--auth-accent-text);
  font-weight: 600;
  text-decoration: none;
}
.pj-notyou a:hover,
.pj-signin a:hover {
  text-decoration: underline;
}

/* A signed-in account: who is walking in, instead of the field. */
.pj-account {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 14px;
  padding: 11px 13px;
  border: 1px solid var(--auth-stroke);
  border-radius: 14px;
  background: var(--auth-surface-2);
}
.pj-account-avatar {
  width: 38px;
  height: 38px;
  flex: none;
  border-radius: 50%;
  overflow: hidden;
  display: grid;
  place-items: center;
  background: #6366f1;
  color: #fff;
  font: 700 16px/1 var(--sans);
}
.pj-account-avatar img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.pj-account-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  flex: 1 1 auto;
}
.pj-account-label {
  font-size: 12px;
  color: var(--auth-muted);
}
.pj-account-text strong {
  font-size: 15px;
  font-weight: 700;
  color: var(--auth-ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.pj-account-tag {
  flex: none;
  padding: 4px 9px;
  border-radius: 999px;
  background: var(--auth-info-bg);
  color: var(--auth-accent-text);
  font: 700 11px/1.2 var(--sans);
}

.pj-signin {
  margin: 14px 0 0;
  text-align: center;
  font-size: 13.5px;
  color: var(--auth-muted);
}

/* Under the button, one reassuring line and an (i). Everything joining means
   lives in the tip: shown on hover and keyboard focus on a computer, on a tap
   on a phone (prejoin.js toggles data-open). It stays in the layout, only
   invisible, so the join button's aria-describedby always reads it. */
.pj-trust {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  margin: 12px 0 0;
  font: 600 12.5px/1.3 var(--sans);
  color: var(--auth-muted);
}
.pj-trust-lock {
  flex: none;
  width: 14px;
  height: 14px;
}
.pj-info {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  margin: 0 0 0 -2px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--auth-muted);
  cursor: pointer;
}
.pj-info svg {
  width: 15px;
  height: 15px;
}
.pj-info:hover,
.pj-info[aria-expanded="true"] {
  color: var(--auth-accent-text);
  background: var(--auth-info-bg);
}
.pj-info:focus-visible {
  outline: 2px solid var(--auth-accent-text);
  outline-offset: 1px;
}
.pj-tip {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 8px);
  z-index: 5;
  width: min(320px, calc(100vw - 48px));
  padding: 12px 14px;
  border: 1px solid var(--auth-info-stroke);
  border-radius: 12px;
  background: var(--auth-surface);
  box-shadow: 0 12px 32px rgba(17, 17, 24, 0.14);
  text-align: left;
  font: 500 12.5px/1.5 var(--sans);
  color: var(--auth-ink-2);
  opacity: 0;
  visibility: hidden;
  transform: translate(-50%, 4px);
  transition: opacity 0.15s ease, transform 0.15s ease, visibility 0s linear 0.15s;
}
/* Bridges the 8 px between the line and the tip: the pointer travelling up to
   the link inside never leaves .pj-trust, so the tip stays open under it. */
.pj-tip::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  height: 10px;
}
.pj-tip p {
  margin: 0 0 6px;
}
.pj-tip a {
  color: var(--auth-accent-text);
  font-weight: 700;
  text-decoration: none;
}
.pj-tip a::after {
  content: " \2192";
}
.pj-tip a:hover {
  text-decoration: underline;
}
@media (hover: hover) {
  .pj-trust:hover .pj-tip {
    opacity: 1;
    visibility: visible;
    transform: translate(-50%, 0);
    transition-delay: 0s;
  }
}
/* Keyboard focus opens it too, unless Escape just closed it while the focus
   stayed on the (i) (data-open="0"; prejoin.js clears it when focus leaves). */
.pj-trust:focus-within:not([data-open="0"]) .pj-tip,
.pj-trust[data-open="1"] .pj-tip {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, 0);
  transition-delay: 0s;
}

/* Empty unless it has something to say: "welcome back", or why the name was
   refused. */
.pj-hint:empty {
  display: none;
}

/* Instagram, Facebook, LinkedIn open links in their own web view, where Google
   refuses its sign-in and the camera depends on the app: said once, calmly,
   with the one gesture that fixes it. */
.pj-inapp {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 4px 12px;
  align-items: center;
  margin: 0 0 16px;
  padding: 11px 12px 11px 14px;
  border: 1px solid var(--auth-info-stroke);
  border-radius: 12px;
  background: var(--auth-info-bg);
}
.pj-inapp strong {
  grid-column: 1;
  font-size: 13px;
  color: var(--auth-ink);
}
.pj-inapp span {
  grid-column: 1;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--auth-muted);
}
.pj-inapp-btn {
  grid-column: 2;
  grid-row: 1 / span 2;
  height: 34px;
  padding: 0 12px;
  border-radius: 999px;
  border: 1px solid var(--auth-info-stroke);
  background: var(--auth-surface);
  color: var(--auth-accent-text);
  font: 700 12.5px/1 var(--sans);
  cursor: pointer;
  white-space: nowrap;
}
.pj-inapp-btn:focus-visible {
  outline: 2px solid var(--auth-accent-text);
  outline-offset: 2px;
}

/* ── Phone: one column, one screen ───────────────────────────────────────── */
@media (max-width: 880px) {
  .pj-panel h1 {
    margin-bottom: 6px;
  }
  .pj-live {
    margin-bottom: 12px;
  }
  .pj-toggles {
    bottom: 10px;
    gap: 8px;
  }
  .pj-tog {
    width: 40px;
    height: 40px;
  }
  .pj-self-avatar {
    width: 58px;
    height: 58px;
    font-size: 24px;
  }
  .pj-video .tk-you {
    bottom: auto;
    top: 10px;
    left: 10px;
    max-width: calc(100% - 70px);
  }
  .pj-hint {
    font-size: 12px;
  }
  .pj-field {
    margin-bottom: 10px;
  }
  .pj-trust {
    margin-top: 10px;
  }
  .pj-open {
    margin-bottom: 12px;
    padding: 9px 12px;
    font-size: 12.5px;
    line-height: 1.5;
  }
}

@media (prefers-reduced-motion: reduce) {
  .pj-live-dot,
  .pj-live-dot::after {
    animation: none !important;
  }
}
