/* ==========================================================================
   Shared shell for the first-party SDK apps (Rooms, Drop, Pulse).
   Loads after design-tokens.css + ui.css and adds only what an app screen
   needs on top of the kit: a header bar, a two-column stage, and the small
   status vocabulary the three of them share.
   ========================================================================== */

html, body { height: 100%; }

body.sdk-app {
    margin: 0;
    display: flex;
    flex-direction: column;
    /* A phone's browser draws its own bar over the bottom of the page, and
       height:100% resolves against the viewport as if that bar were not there.
       With overflow hidden that put the bottom of every one of these apps —
       the tab bar, the message box — underneath it, unreachable rather than
       merely cut off. dvh is the height actually on screen right now. */
    height: 100dvh;
    max-height: 100dvh;
    overflow: hidden;
    background: var(--bg);
    color: var(--text-body);
    font-family: var(--font-sans);
}

/* ---- header -------------------------------------------------------------- */
.sdk-header {
    display: flex;
    align-items: center;
    gap: var(--sp-4);
    padding: 0 var(--sp-5);
    height: 60px;
    flex: none;
    background: var(--surface-1);
    border-bottom: 1px solid var(--border);
}

.sdk-header__mark {
    display: grid;
    place-items: center;
    width: 32px; height: 32px;
    flex: none;
    border-radius: var(--r-md);
    background: var(--surface-2);
    color: var(--brand-ink);
}

.sdk-header h1 { font-size: var(--fs-lg); }

.sdk-room {
    font-family: var(--font-mono);
    font-size: var(--fs-sm);
    color: var(--text-muted);
    padding: 4px 10px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--r-sm);
    max-width: 30ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sdk-header__right {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    margin-left: auto;
    min-width: 0;
}

/* ---- status pill --------------------------------------------------------- */
.pill-status {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2);
    padding: 6px 12px;
    font-size: var(--fs-sm);
    font-weight: 600;
    border-radius: var(--r-pill);
    background: var(--surface-2);
    border: 1px solid var(--border-strong);
    color: var(--text-body);
    white-space: nowrap;
}

.pill-status__dot {
    width: 8px; height: 8px;
    border-radius: var(--r-pill);
    background: var(--text-faint);
    flex: none;
}

.pill-status.is-live { background: var(--success-bg); border-color: rgba(52,211,153,.35); color: var(--success); }
.pill-status.is-live .pill-status__dot { background: var(--success); }
.pill-status.is-busy { background: var(--warning-bg); border-color: rgba(251,191,36,.35); color: var(--warning); }
.pill-status.is-busy .pill-status__dot { background: var(--warning); }
.pill-status.is-off { background: var(--danger-bg); border-color: rgba(248,113,113,.35); color: var(--danger); }
.pill-status.is-off .pill-status__dot { background: var(--danger); }

/* ---- stage --------------------------------------------------------------- */
.sdk-stage {
    display: flex;
    gap: var(--sp-4);
    padding: var(--sp-4);
    flex-grow: 1;
    min-height: 0;
}

.sdk-main {
    flex-grow: 1;
    display: flex;
    flex-direction: column;
    gap: var(--sp-3);
    min-width: 0;
}

.sdk-side {
    width: 280px;
    flex: none;
    display: flex;
    flex-direction: column;
    gap: var(--sp-3);
    min-height: 0;
}

.sdk-side__title {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-2);
    font-size: var(--fs-sm);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-muted);
}

.sdk-note {
    padding: var(--sp-3);
    border: 1px dashed var(--border-strong);
    border-radius: var(--r-md);
    font-size: var(--fs-xs);
    color: var(--text-muted);
    line-height: var(--lh-snug);
}

.sdk-scroll { overflow-y: auto; min-height: 0; }

/* ---- avatars ------------------------------------------------------------- */
.avatar {
    display: grid;
    place-items: center;
    width: 34px; height: 34px;
    flex: none;
    border-radius: var(--r-pill);
    font-weight: 700;
    font-size: var(--fs-sm);
    color: var(--bg);
}

.avatar--lg { width: 44px; height: 44px; }

/* ---- empty state --------------------------------------------------------- */
.sdk-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--sp-3);
    padding: var(--sp-10) var(--sp-6);
    color: var(--text-muted);
    text-align: center;
}

.sdk-empty svg { width: 40px; height: 40px; color: var(--text-faint); }

@media (max-width: 900px) {
    .sdk-stage { flex-direction: column; }
    .sdk-side { width: auto; }

    /* dvh accounts for the browser's collapsing toolbar but not for the home
       indicator drawn over the bottom of the page. Without this the last row
       of an app — a message box, a control bar — sits underneath it. */
    .sdk-stage { padding-bottom: calc(var(--sp-4) + env(safe-area-inset-bottom, 0px)); }
}

/* The header is a single fixed-height row and a phone is 390px wide. Left
   alone the row does not wrap, it simply runs past the right edge — and
   because it widens the document, every overlay sized as a percentage (the
   connection modal above all) is laid out against the overflowed width and
   spills too. Rooms carried its own copy of this; it belongs to the shell,
   so Drop and Pulse get it as well.

   Everything in the row either earns its width or loses its words. */
@media (max-width: 640px) {
    .sdk-header { gap: var(--sp-2); padding: 0 var(--sp-3); }
    .sdk-header h1 { flex: none; }
    .sdk-header__right { gap: var(--sp-2); }

    /* The browser's own back button already goes where this link goes. */
    .sdk-header__away { display: none; }

    /* The room name is the one part that may be arbitrarily long. */
    .sdk-room {
        min-width: 0;
        flex: 0 1 auto;
        max-width: 14ch;
    }

    /* The dot still reports connected, busy or off; the sentence beside it
       does not fit and is not news. */
    .pill-status__text { display: none; }
    .pill-status { padding: 6px; }

    /* Remaining header buttons collapse to their icon. */
    .sdk-header__right .btn > span:not(.sr-only) { display: none; }
    .sdk-header__right .btn {
        min-height: 40px;
        width: 40px;
        padding: 0;
        justify-content: center;
    }
}


/* --- Phone: the header row is the tightest space on the site -------------- */
/*
 * A header button's label is a nicety; its icon is the control. Below this
 * width the labels are what push the row past the right edge — which widens
 * the document and drags every percentage-sized overlay with it.
 *
 * The label is CLIPPED rather than display:none so the button keeps its
 * accessible name. An icon-only button with the text removed outright has no
 * name at all, and the a11y sweep is right to fail that.
 */
@media (max-width: 640px) {
    .sdk-header__right .btn > span {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
    }
    .sdk-header__right .btn { padding-inline: var(--sp-2); }

    /* A status pill's text is written for a laptop and can be a sentence. */
    .pill-status {
        min-width: 0;
        max-width: 13ch;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
}

/* --- Small phones (320px) ------------------------------------------------ */
/*
 * At 390px the header fits; at 320px it is about twenty pixels over, and every
 * item in it was refusing to shrink. Nothing here is removed — the title
 * truncates, the room name and the status pill take less, and the row closes
 * up. Losing a control would be worse than losing a few characters of a name.
 */
@media (max-width: 400px) {
    .sdk-header { gap: var(--sp-1); padding: 0 var(--sp-2); }
    .sdk-header h1 {
        min-width: 0;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    .sdk-room { max-width: 8ch; }
    .pill-status { max-width: 9ch; }
}

/* ---- the wire panel ------------------------------------------------------ */
/*
 * "Show me the call that did that." js/sdk-wire.js wraps an app's connection
 * and prints one row per SDK call; this is what those rows look like. The
 * shape is Under the Hood's log (.hood-log__row) generalised, so the two read
 * as the same idea at two levels of detail.
 */
.sdk-wire {
    display: flex;
    flex-direction: column;
    gap: 5px;
    font-family: var(--font-mono);
    font-size: var(--fs-xs);
    line-height: var(--lh-snug);
    min-height: 0;
}

.sdk-wire__row { display: flex; gap: var(--sp-2); align-items: baseline; }
.sdk-wire__t   { color: var(--text-faint); flex: none; }
.sdk-wire__fn  { color: var(--brand-ink); flex: none; font-weight: 600; }
.sdk-wire__meta{ color: var(--text-muted); overflow-wrap: anywhere; }

/* The distinction the SDK actually makes: addressed, or left to the host. */
.sdk-wire__row--directed  .sdk-wire__fn { color: var(--accent-ink); }
.sdk-wire__row--storage   .sdk-wire__fn { color: var(--success); }

.sdk-wire__empty {
    margin: 0;
    font-family: var(--font-sans);
    font-size: var(--fs-xs);
    color: var(--text-muted);
    line-height: var(--lh-snug);
}

.sdk-wire__count {
    font-family: var(--font-mono);
    font-size: var(--fs-xs);
    font-weight: 400;
    color: var(--text-faint);
    letter-spacing: 0;
}

/* ---- the companion ------------------------------------------------------- */
/*
 * js/companion.js starts a real second connection in this tab so a demo does
 * something for somebody on their own. It must never be mistaken for another
 * human, so it is marked wherever it appears.
 */
.companion-btn.is-on {
    border-color: var(--brand);
    color: var(--brand-ink);
}

.companion-tag { margin-left: var(--sp-2); }

/* A dashed ring says "not a real person" without inventing a new colour. */
.is-companion .avatar,
.avatar--companion {
    border: 2px dashed var(--brand-ink);
    background: var(--surface-2);
    color: var(--brand-ink);
}
