/* AirTalk — app integration layer
   Only the rules the live app's own markup needs. Nothing on the marketing page
   is restyled, no colour is invented: every value here is an AirTalk token from
   assets/style.css, and buttons are written through the existing .btn
   custom-property API (--_bg / --_fg / --_bd) rather than by setting paint.
   ------------------------------------------------------------------ */

/* app.js's single visibility switch. Must beat id-level display rules. */
.hidden { display: none !important; }

/* app.js writes "btn btn-primary" / "btn btn-ghost" on markup it builds at
   runtime (friend-request actions), so those two names need the variants. */
.btn-primary { --_bg: var(--accent); --_fg: var(--on-accent); --_bd: var(--accent); }
.btn-ghost { --_fg: var(--ink-muted); --_bd: var(--border-subtle); }
#btnHangup { --_bg: var(--danger); --_fg: var(--surface-base); --_bd: var(--danger); }

/* ====== app bar + tabs =============================================== */
.app-bar {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--space-3); margin-bottom: var(--space-5);
}
.app-tabs { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.app-account { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.tab {
  display: inline-flex; align-items: center; gap: var(--space-2);
  min-height: 44px; padding: var(--space-2) var(--space-5);
  border: 1px solid var(--border-subtle); border-radius: var(--radius-full);
  background: var(--surface-raised); color: var(--ink-muted);
  font: 600 14px/20px var(--font-text); cursor: pointer;
  transition: color var(--d1) ease-out, background-color var(--d1) ease-out, border-color var(--d1) ease-out;
}
.tab:hover { color: var(--ink); background: var(--surface-inset); }
.tab.active { border-color: var(--accent); background: var(--accent-soft); color: var(--accent-text); }
.badge {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 20px; height: 20px; padding: 0 6px; border-radius: var(--radius-full);
  background: var(--accent); color: var(--on-accent); font: 700 11px/20px var(--font-text);
}

/* ====== nav: inbox button + auth ===================================== */
/* .nav-link is written for an <a>; the sign-in control is a button now so it
   can open the auth dialog, and needs the element defaults cleared. */
.nav-link--btn {
  border: 0; background: transparent; cursor: pointer;
  font: 500 14px/20px var(--font-text);
}
#btnPanel { position: relative; overflow: visible; }
.nav-badge {
  position: absolute; top: -4px; right: -4px;
  box-shadow: 0 0 0 2px var(--surface-raised);
}

/* ====== hero call card: state hooks ==================================
   The card is the product now, so idle / searching / connecting / connected /
   ended each have to read differently. The house convention is data-* state
   attributes, so that is what these hang off. */
#orb {
  transition: background-color var(--d2) ease-out, box-shadow var(--d2) ease-out;
}
#orb[data-call-state="searching"],
#orb[data-call-state="connecting"] {
  background: var(--accent-soft); color: var(--accent-text);
  animation: orb-pulse 1600ms ease-out infinite;
}
#orb[data-call-state="connected"] { background: var(--live-soft); color: var(--live); }
@keyframes orb-pulse {
  0% { box-shadow: 0 0 0 0 var(--accent-soft), 0 0 0 2px var(--surface-raised); }
  100% { box-shadow: 0 0 0 12px transparent, 0 0 0 2px var(--surface-raised); }
}

/* .presence hardcodes the live green, so every other state is set here. */
.presence[data-tone="busy"] { background: var(--caution); }
.presence[data-tone="off"] { background: var(--wave-rest); }

/* Same for the status pill: .pill--live is green by definition. */
#callPill[data-tone="demo"],
#callPill[data-tone="off"] {
  background: var(--surface-inset); border-color: var(--border-subtle); color: var(--ink-muted);
}
#callPill[data-tone="busy"] {
  background: var(--surface-inset); border-color: var(--caution); color: var(--caution);
}
#callPill[data-tone="demo"] .dot,
#callPill[data-tone="off"] .dot { background: var(--wave-rest); }
#callPill[data-tone="busy"] .dot { background: var(--caution); }
#callPill[data-tone="demo"] .dot::after,
#callPill[data-tone="off"] .dot::after { display: none; }
#callPill[data-tone="busy"] .dot::after { border-color: var(--caution); }

/* The call controls sit in the card at every state, so the ones that can't act
   yet have to look inert. There is no disabled style for .call-btn upstream. */
.call-btn[disabled] { opacity: .45; cursor: not-allowed; }
.call-btn[disabled]:hover { background: var(--surface-raised); transform: none; }
/* Nor a pressed state — this borrows the .at-choice[aria-pressed] language. */
.call-btn[aria-pressed="true"] {
  background: var(--accent-soft); border-color: var(--accent); color: var(--accent-text);
}

.call-line {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-3); flex-wrap: wrap;
}
/* The chat pane is a second .call-stage inside the card, so it needs to be
   shorter than the standalone pane the old section used. */
#chatPane .messages { height: 180px; padding: var(--space-3); }
#chatPane .news { margin-top: 0; }

/* 375px: four controls plus a 64px-wide end button still have to fit. */
@media (max-width: 380px) {
  .call-controls { gap: var(--space-2); }
  .call-btn { width: 44px; height: 44px; }
  .call-btn--end { width: 56px; }
}

/* ====== requests + inbox panel =======================================
   Wider than the auth card, so it beats `.app-modal .card` on specificity. */
#appPanel > .app-panel-card { width: min(920px, 100%); }
#appPanel .app-bar { margin-bottom: var(--space-5); }
#appPanel .messages { height: 240px; }

/* ====== message panes ================================================ */
.messages {
  display: grid; gap: var(--space-2); align-content: start;
  height: 300px; overflow-y: auto; padding: var(--space-4);
  border-radius: var(--radius-lg); background: var(--surface-sunken);
}
.msg { max-width: 82%; padding: var(--space-2) var(--space-3); border-radius: var(--radius-md); font-size: 14px; line-height: 22px; }
.msg.mine { justify-self: end; background: var(--accent); color: var(--on-accent); }
.msg.theirs { justify-self: start; background: var(--surface-inset); color: var(--ink); }

/* ====== lists app.js fills with <li> ================================= */
.app-list { list-style: none; margin: var(--space-4) 0 0; padding: 0; display: grid; gap: var(--space-2); }
.app-list .row {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
  padding: var(--space-3) var(--space-4); border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md); background: var(--surface-raised);
}
.app-list .row.clickable { cursor: pointer; }
.app-list .row.clickable:hover { background: var(--surface-inset); }
.app-list .who { font: 600 14px/20px var(--font-text); color: var(--ink); }
.app-list .meta { font-size: 13px; line-height: 18px; color: var(--ink-muted); }
.row-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.row-actions .btn { min-height: 36px; padding: var(--space-2) var(--space-4); font-size: 12px; line-height: 16px; border-radius: var(--radius-sm); text-transform: capitalize; }
.app-list .empty {
  padding: var(--space-5); border: 1px dashed var(--border-subtle); border-radius: var(--radius-md);
  font-size: 14px; line-height: 22px; color: var(--ink-muted);
}

/* ====== auth modal ===================================================
   The design system has no dialog component, so this is the one new surface. */
.app-modal {
  position: fixed; inset: 0; z-index: 90;
  display: grid; place-items: center; padding: var(--space-5);
  background: color-mix(in srgb, var(--scrim) 74%, transparent);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}
.app-modal .card { width: min(420px, 100%); max-height: 92vh; overflow-y: auto; overflow-x: hidden; }

/* The form is an implicit single-column grid, and the Turnstile iframe is a
   fixed 300px box — as the widest item it was setting that column for the whole
   form, so on a phone every label, input and button stretched to 300px inside a
   262px card and ran off the right edge. Pinning the column to the card's own
   width keeps the fields where they belong; the widget is what gives way. */
#authForm { grid-template-columns: minmax(0, 1fr); }
#authForm > * { min-width: 0; }
/* No clipping here: the widget is a fixed-size iframe, so below it is scaled
   rather than cut — a half-drawn checkbox is worse than a slightly small one. */
#turnstileHost { max-width: 100%; }

@media (max-width: 480px) {
  /* A phone cannot afford 24px of backdrop gutter and 32px of card padding on
     both sides — that is 112px of the 375 gone before any content. */
  .app-modal { padding: var(--space-3); }
  .app-modal .card { padding: var(--space-5); }
}

/* Below ~364px even the trimmed card is narrower than Turnstile's fixed 300px,
   so the widget is scaled to what is actually left rather than being clipped. */
@media (max-width: 363px) {
  #turnstileHost { transform: scale(.82); transform-origin: left top; height: 54px; }
}
#googleBtnHost:not(:empty) { display: flex; justify-content: center; overflow: hidden; }
/* Google renders its button at a fixed 340px, which is wider than a phone-width
   modal card; let it take the width it actually has instead of being clipped. */
#googleBtnHost > div,
#googleBtnHost > div > div { width: 100% !important; max-width: 100%; }

@media (prefers-reduced-motion: reduce) {
  #orb[data-call-state="searching"],
  #orb[data-call-state="connecting"] { animation: none; }
  #orb, .tab { transition: none; }
}

/* ---- call controls: labelled, with an explicit start-call action ---------
   The bare star gave no clue it meant "add friend", so every control now
   carries a visible label rather than relying on icon literacy. */
.call-controls { align-items: flex-start; }
.call-controls .ctl {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}
.ctl-label {
  font-size: 11px;
  line-height: 1.2;
  color: var(--ink-muted);
  white-space: nowrap;
}
.call-btn--go {
  background: var(--live);
  border-color: var(--live);
  color: var(--on-success, #052e16);
}
.call-btn--go:hover:not(:disabled) { filter: brightness(1.06); }
.call-btn--go:disabled { opacity: .4; }

/* ---- hero: nothing in the copy column may set the column's width ---------
   The live counter is a whole sentence — "No one else is waiting yet — stay
   here and you'll be matched first", which only appears once you are in the
   queue — inside a `white-space: nowrap` pill, so its min-content width was
   418px. Below 1040px the hero is a single `auto` track, and an auto track
   never shrinks below the min-content contribution of its content: the pill
   dragged the headline, the lead text and the whole call card out to 418px
   inside a 375px phone the moment a call started, and `.hero { overflow:
   hidden }` cut the right-hand side off rather than letting it scroll.
   The sentence is allowed to wrap, and the tracks are capped so no future
   long string can do the same thing again. */
.hero-copy > .pill--live { white-space: normal; }

@media (max-width: 1039px) {
  .hero-grid { grid-template-columns: minmax(0, 1fr); }
  .hero-copy { grid-template-columns: minmax(0, 1fr); min-width: 0; }
  .hero-grid > .stage { min-width: 0; }
  .hero-copy > * { max-width: 100%; }
}

/* Live text from the other side of a call, and from the diagnostics line, can
   be a single unbroken string; it breaks rather than widening the card. */
#diag, .call-name, .msg { overflow-wrap: anywhere; }

/* ---- mobile navigation ---------------------------------------------------
   The bar has room for the logo, the theme switch and the menu. Everything
   else — inbox, account, sign in — moves into the drawer, because four
   controls plus a username chip pushed the menu button off the screen. */
.drawer-account { display: none; }

@media (max-width: 900px) {
  /* The bar is sticky, so the card has to stop below it rather than under it. */
  #callCard { scroll-margin-top: 84px; }

  /* Pressing Start used to leave the card ~700px below the fold, and relying on
     a scroll to fix that is fragile. Once a call is under way the card simply
     becomes the first thing in the hero, directly under the button pressed. */
  body[data-call="active"] .hero-grid > .stage { order: -1; }
  body[data-call="active"] .hero-grid { row-gap: var(--space-5); }

  /* A 64px avatar, a 112px status pill and a 16px gap left 74px for the name,
     so "Looking for someone…" wrapped one word per line. On a phone the pill
     drops to its own row and the avatar gives some width back. */
  .call-head { flex-wrap: wrap; row-gap: 10px; }
  .call-peer { flex: 1 1 100%; min-width: 0; }
  .call-head #callPill { flex: 0 0 auto; }
  .call-head .avatar--lg { width: 48px; height: 48px; font-size: 16px; }
  .call-name { overflow-wrap: anywhere; }

  .nav-right #btnPanel,
  .nav-right #btnProfile,
  .nav-right #btnAuth,
  .nav-right #btnSignIn { display: none !important; }

  .drawer-account {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin-top: var(--space-3);
    padding-top: var(--space-3);
    border-top: 1px solid var(--border-subtle);
  }

  .drawer-account a,
  .drawer-btn {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    background: none;
    border: 0;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
    padding: 13px 4px;          /* a 44px-tall target, not a 17px line of text */
  }

  .drawer-account .hidden { display: none !important; }
  .drawer-btn#drawerSignUp { color: var(--accent, #6d5efc); font-weight: 600; }

  /* The drawer overlays the page instead of shoving the hero down the screen. */
  .drawer {
    position: absolute;
    left: var(--space-4);
    right: var(--space-4);
    top: calc(100% + 8px);
    z-index: 60;
    max-height: 76vh;
    overflow-y: auto;
    box-shadow: 0 24px 60px rgba(0, 0, 0, .45);
  }

  .nav { position: relative; }
  .drawer > a { padding: 13px 4px; }

  /* Footer links are text-sized; on a phone they need a finger-sized target. */
  .foot-col a, .foot-links a { display: inline-block; padding: 7px 0; }
}

@media (max-width: 560px) {
  /* .grid--4 stays two columns all the way down, which leaves 163px tracks
     that its own cards overflow. One column reads properly on a phone. */
  .grid--4 { grid-template-columns: minmax(0, 1fr) !important; }

}

/* The microphone-refusal recovery. Sits inside the card, above the call
   controls, and only appears when a request was actually refused. */
.mic-help {
  margin-top: var(--space-4);
  padding: var(--space-4);
  border: 1px solid var(--caution);
  border-radius: var(--radius-md);
  background: var(--surface-inset);
}

.mic-help p {
  margin: 0 0 var(--space-3);
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--ink);
}

.mic-help-actions {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
}

@media (max-width: 420px) {
  .mic-help-actions .btn { flex: 1 1 100%; }
}

/* ---- account screen ------------------------------------------------------
   One place for the things people go looking for after signing in: the name
   others see, the address a reset would go to, the password, the way back in
   if both fail, and the way out. */
.profile-card { max-height: 86vh; overflow-y: auto; width: min(520px, 94vw); }
.profile-sec {
  margin-top: var(--space-5);
  padding-top: var(--space-5);
  border-top: 1px solid var(--border);
}
.profile-sec--last { text-align: right; }
.profile-sec h4 { font: 600 15px/20px var(--font-text); color: var(--ink); }
.profile-sec .body-sm { color: var(--ink-muted); margin-top: 4px; }
.profile-sec form {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-3);
}
.profile-sec form .input { flex: 1 1 220px; min-width: 0; }
.profile-sec form .btn { flex: 0 0 auto; }
#btnProfile { display: inline-flex; align-items: center; gap: 8px; }
#btnProfile .avatar { width: 22px; height: 22px; font-size: 10px; }

/* The stories rail drives itself now, so the scrollbar and the arrow buttons
   are two controls for something nobody has to control. */
.rail { scrollbar-width: none; -ms-overflow-style: none; }
.rail::-webkit-scrollbar { width: 0; height: 0; display: none; }

/* Start and End share one slot, so both are cut to one width — otherwise the
   64px End button would shove the rest of the row sideways when a call starts. */
.ctl--call { min-width: 64px; }
.ctl--call .call-btn { width: 64px; }

/* Single-column layouts size the demo card to its own content, so the longer
   in-call status line ("Waiting for a match") was widening the card and sliding
   the controls a few pixels sideways the moment a call started. Pinning the
   card to its column keeps the Start/End button on the exact same pixel. */
@media (max-width: 900px) {
  .hero-grid > .stage { min-width: 0; }
  #callCard { min-width: 0; grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 420px) {
  /* 10px was small enough to be a guess rather than a label. */
  .ctl-label { font-size: 11px; }
  .call-controls { gap: 10px; }
  .ctl--call, .ctl--call .call-btn { min-width: 56px; width: 56px; }
}

/* A centred nowrap row overflows on both sides once its labels outgrow the
   card, which on the narrowest phones pushed Report past the right edge and
   out of reach. It wraps onto a second line instead of running off. */
@media (max-width: 420px) {
  .call-controls { flex-wrap: wrap; row-gap: var(--space-3); }
  .call-controls .ctl { min-width: 0; }
}
