@font-face{font-family:'Geist Mono';font-weight:100 900;font-display:block;src:url(/static/fonts/GeistMono.woff2) format('woff2')}
@font-face{font-family:'Poppins';font-weight:600;font-display:block;src:url(/static/fonts/Poppins-600.woff2) format('woff2')}
@font-face{font-family:'Poppins';font-weight:700;font-display:block;src:url(/static/fonts/Poppins-700.woff2) format('woff2')}

:root{
  --ink:#14191f;--cream:#f2efe8;--paper:#fbfaf6;--line:#d9d4ca;--muted:#6d716f;--gold:#d1a449;--green:#41d17d;
  --peach:#f6dccf;--blue:#dfe3ff;--clawd:#d77757;--codex:#5468ff;
  --sans:'Poppins',system-ui,sans-serif;--mono:'Geist Mono',ui-monospace,Menlo,monospace;
  --pad:22px;--scene-h:clamp(200px,31vh,320px);--sprite:clamp(56px,12vh,112px);--app-h:100dvh;--move:.55s;
  color-scheme:light;
}
*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%;background:var(--cream);color:var(--ink);overflow:hidden;-webkit-text-size-adjust:100%;overscroll-behavior:none}
body{font-family:var(--sans);font-weight:600}
.app{height:var(--app-h);display:grid;grid-template-rows:auto minmax(0,1fr);gap:0;max-width:1100px;margin:0 auto;position:relative}

/* one page, both acts. A grid with named areas: head (the headline), pic (the picture), line (the one top line),
   pane (the bottom: the terminal in act one, a plain chat input in act two), chips (act two only), chat.
   Act one, phone: head / pic / line / pane / chat (the chat collapsed under the terminal).
   Act two, phone: head / pic / line / chat / chips / pane (the chat takes the room the terminal gave up).
   From 900 px the chat is a column on the right: beside the terminal in act one, full height in act two. */
.one{display:grid;position:relative;min-height:0;transition:opacity .6s;grid-template-columns:minmax(0,1fr);
  grid-template-rows:auto var(--scene-h) auto auto minmax(0,1fr) auto;grid-template-areas:"head" "pic" "line" "chat" "pane" "book"}
.one.faded{opacity:0;pointer-events:none}
.headline{grid-area:head}
.picture{grid-area:pic}
.topline{grid-area:line}
.bottom{grid-area:pane;display:flex;flex-direction:column;min-height:0;position:relative}
.pane{flex:1 1 auto}
.chips{grid-area:chips}
.transcript{grid-area:chat}
.one.act2{grid-template-rows:auto auto auto minmax(0,1fr) auto auto auto;grid-template-areas:"head" "pic" "line" "chat" "chips" "pane" "book"}
/* the move between the acts: the picture and the pane carry explicit heights (app.js measures both ends and lets
   the heights transition); on a phone the chat row absorbs the rest */
.one.moving{grid-template-rows:auto auto auto minmax(0,1fr) auto auto auto;grid-template-areas:"head" "pic" "line" "chat" "chips" "pane" "book"}
/* the quiet way to the founders: a plain muted link with a small arrow under everything, 40 px tall, both acts */
.book{grid-area:book;justify-self:start;display:inline-flex;align-items:center;gap:7px;min-height:40px;margin:-8px var(--pad) 6px;padding:0 15px;border:1.5px solid var(--gold);border-radius:999px;background:var(--paper);font-family:var(--sans);font-weight:600;font-size:13px;color:var(--ink);text-decoration:none;-webkit-tap-highlight-color:transparent}   /* a thin gold pill, ink text, no fill beyond the paper, no shadow */
.book svg{width:15px;height:15px;display:block}
.book:hover,.book:focus-visible{border-color:var(--ink);outline:none}
.book[hidden]{display:none}
html.short .book{display:none}
.one.moving .picture{transition:height var(--move) cubic-bezier(.4,0,.2,1)}

/* header */
.top{display:flex;align-items:center;justify-content:space-between;padding:12px var(--pad) 6px}
.brand{display:flex;align-items:center;gap:9px;font-weight:700;font-size:17px;letter-spacing:-.01em;cursor:default;user-select:none}
.brand img{width:22px;height:22px}
.brand b{color:var(--gold);font-weight:700}
.where{font-family:var(--mono);font-size:12px;color:var(--muted);display:flex;gap:10px;align-items:center}
.modetag{border:1px solid var(--line);border-radius:999px;padding:3px 8px;font-size:10.5px;letter-spacing:.12em;text-transform:uppercase}
.modetag:empty{display:none}

/* the one line over the picture (config attract_line) */
.headline{padding:6px var(--pad) 0;font-size:clamp(22px,2.7vw,34px);line-height:1.12;letter-spacing:-.02em;font-weight:700;text-wrap:balance}

/* the picture: act one's scene fills it; the team's field (an iframe of the team page with only its field,
   transparent) lies over it and fades in at the hand-over (.pic2), the scene fades out under it */
.picture{position:relative;margin:0 var(--pad);min-height:0}
.one.act2 .picture{height:calc(var(--app-h) * .28)}   /* three agents and the seats: a shorter picture, the chat gets the room */
.picture .field{position:absolute;inset:0;width:100%;height:100%;border:0;display:block;background:transparent;opacity:0;pointer-events:none;transition:opacity .6s}
.one.pic2 .scene{opacity:0;pointer-events:none}
.one.pic2 .field{opacity:1;pointer-events:auto}

/* scene: both awake from the start; Claude Code's can lies on the floor until presence says he joined */
.scene{position:absolute;inset:0;overflow:visible;transition:opacity .5s}
/* the floor sits low: only the name tags live under it, the narration is the top line below the scene */
.floor{position:absolute;left:0;right:0;bottom:40px;height:3px;background:var(--ink);border-radius:2px}
.ch{position:absolute;bottom:43px;width:0;pointer-events:none;transition:opacity .6s,filter .6s}
.ch.l{left:24%}.ch.r{left:76%}
.ch.gone{opacity:.38;filter:saturate(.25)}
.ch .sprite{position:absolute;bottom:0;left:0;transform:translateX(-50%);transform-origin:50% 100%;animation:bob 3.2s ease-in-out infinite}
.ch.r .sprite{animation-delay:-1.4s}
.ch.gone .sprite{animation:none}
.ch .sprite svg{display:block;height:var(--sprite);width:auto}
.ch .sprite svg.pose{display:none}.ch .sprite svg.pose.rest{display:block}
.ch.thinking .sprite svg.pose.rest,.ch.twitch .sprite svg.pose.rest{display:none}
.ch.thinking .sprite svg.pose.talk,.ch.twitch .sprite svg.pose.talk{display:block}
.ch.wake .sprite{animation:hop .5s ease-out}
.ch.got .sprite{animation:hop .45s ease-out}
@keyframes bob{0%,100%{transform:translateX(-50%) translateY(0)}50%{transform:translateX(-50%) translateY(-3px)}}
@keyframes hop{0%{transform:translateX(-50%) translateY(0)}40%{transform:translateX(-50%) translateY(-10px)}100%{transform:translateX(-50%) translateY(0)}}
.ch .face,.ch .eyes{transform-box:fill-box;transform-origin:center;transition:transform .12s}
.ch.gone .face,.ch.gone .eyes,.ch.blink .face,.ch.blink .eyes{transform:scaleY(.12)}
/* the tin can: at the hand when ready, at the mouth when speaking, at the ear when thinking; on the floor before the join */
.ch .can{position:absolute;bottom:calc(var(--sprite) * .40);width:calc(var(--sprite) * .26);transition:transform .7s cubic-bezier(.3,.9,.3,1.1),bottom .7s cubic-bezier(.3,.9,.3,1.1),left .7s}
.ch .can svg{display:block;width:100%;height:auto}
.ch.l .can{left:calc(var(--sprite) * .86)}
.ch.r .can{right:calc(var(--sprite) * .64)}
.ch.l:not(.in) .can{bottom:-3px;left:calc(var(--sprite) * 1.0);transform:rotate(90deg)}
.ch.l.in.talk .can{transform:translate(calc(var(--sprite) * -.26),calc(var(--sprite) * -.06))}
.ch.r.talk .can{transform:translate(calc(var(--sprite) * .28),calc(var(--sprite) * -.16))}
.ch.l.in.thinking .can{transform:translate(calc(var(--sprite) * .04),calc(var(--sprite) * -.46))}
.ch.r.thinking .can{transform:translate(calc(var(--sprite) * -.04),calc(var(--sprite) * -.50))}
.ch.l.in.twitch .can{transform:translate(calc(var(--sprite) * .02),calc(var(--sprite) * -.40))}
.ch.r.twitch .can{transform:translate(calc(var(--sprite) * -.02),calc(var(--sprite) * -.44))}
/* the tag under the feet: the person big ("Sven"), the tool and where the person sits small ("Claude Code · SF"), one line each */
.ch .tag{position:absolute;top:6px;left:0;transform:translateX(-50%);white-space:nowrap;text-align:center;font-family:var(--mono);font-size:11px;line-height:1.2;color:var(--muted)}
.ch .tag b{display:block;color:var(--ink);font-weight:700;font-family:var(--sans);font-size:15px;line-height:1.15}
.ch .tag small{display:block;font-size:11px}
.ch .tag b:before{content:"";display:inline-block;width:7px;height:7px;border-radius:50%;background:var(--line);margin-right:6px;vertical-align:2px;transition:background .4s}
.ch.in .tag b:before{background:var(--green)}
.ch .think{position:absolute;bottom:calc(var(--sprite) + 10px);left:0;transform:translateX(-50%);display:none;gap:5px}
.ch.thinking .think{display:flex}
.ch .think i{width:7px;height:7px;background:var(--ink);display:block;animation:dots 1.1s infinite ease-in-out}
.ch .think i:nth-child(2){animation-delay:.18s}.ch .think i:nth-child(3){animation-delay:.36s}
@keyframes dots{0%,80%,100%{opacity:.2;transform:translateY(0)}40%{opacity:1;transform:translateY(-3px)}}
.sbub{position:absolute;bottom:calc(var(--sprite) + 14px);transform:translateY(6px);opacity:0;width:max-content;min-width:180px;max-width:min(420px,38vw);z-index:5;
  background:var(--paper);border:2px solid var(--ink);border-radius:12px;box-shadow:0 3px 0 var(--ink);padding:7px 11px;
  font-family:var(--mono);font-size:12.5px;font-weight:400;line-height:1.4;text-align:left;transition:opacity .25s,transform .25s;overflow-wrap:anywhere}
.ch.l .sbub{left:-28px}.ch.r .sbub{right:-28px}
.sbub.on{opacity:1;transform:translateY(0)}
.sbub:after{content:"";position:absolute;bottom:-8px;width:12px;height:12px;background:var(--paper);border:2px solid var(--ink);border-top:0;border-left:0;transform:rotate(45deg)}
.ch.l .sbub:after{left:22px}.ch.r .sbub:after{right:22px}
.sbub .at{color:var(--gold);font-weight:700}
.sbub.other{left:50%;transform:translateX(-50%) translateY(6px);top:8px;bottom:auto;border-color:var(--gold);box-shadow:0 3px 0 var(--gold)}
.sbub.other.on{transform:translateX(-50%) translateY(0)}
.sbub.other:after{display:none}
.sbub .n{display:block;font-weight:700;color:var(--gold);font-size:11px;margin-bottom:2px}
.ch.thinking .sbub{display:none}
/* the string between the cans */
.wire{position:absolute;inset:0;width:100%;height:100%;overflow:visible;pointer-events:none}
.wire path{fill:none;stroke:var(--gold);stroke-width:3;stroke-linecap:round;opacity:.55;transition:opacity .4s}
.wire.on path{opacity:1}
.wire .pulse{fill:var(--gold);stroke:var(--ink);stroke-width:2}
.phone{position:absolute;left:50%;top:6px;transform:translateX(-50%);width:26px;height:44px;border:2px solid var(--ink);border-radius:6px;background:var(--paper);opacity:0;transition:opacity .3s}
.phone i{position:absolute;left:50%;bottom:4px;width:8px;height:3px;margin-left:-4px;background:var(--ink);border-radius:2px}
.phone.on{opacity:1}

/* the one terminal */
.pane{position:relative;display:flex;flex-direction:column;min-height:0;margin:10px var(--pad) 18px;max-height:max(240px,calc(100dvh - 330px));border:2px solid var(--ink);border-radius:12px;box-shadow:0 5px 0 var(--ink);overflow:hidden;background:var(--paper)}
.pane.l{--tint:var(--peach)}
.pane.active{box-shadow:0 5px 0 var(--ink),0 0 0 3px var(--gold)}
.ptitle{position:relative;z-index:2;display:flex;align-items:center;justify-content:space-between;gap:8px;padding:7px 12px;border-bottom:2px solid var(--ink);font-family:var(--mono);font-size:12.5px;font-weight:700;background:var(--paper)}
.ptitle .ps{font-weight:400;color:var(--muted);display:flex;align-items:center;gap:6px}
.ptitle .ps:before{content:"";width:7px;height:7px;border-radius:50%;background:var(--line);display:inline-block}
.ptitle .ps.live:before{background:var(--green)}
/* the padding sits on xterm's own element: the fit addon subtracts that one when it counts rows, so the last row
   (the prompt) never runs under the pane's bottom edge; 12 px of buffer below it */
.term{position:relative;flex:1;min-height:0;background:var(--tint);padding:0}
.term .xterm{height:100%;padding:6px 4px 12px 8px}
.term .xterm-viewport{background:transparent!important;scrollbar-width:none}
.term .xterm-viewport::-webkit-scrollbar{display:none}
.term .xterm-scrollable-element>.scrollbar{display:none}
.overlay{position:absolute;inset:36px 0 0 0;border:0;background:rgba(242,239,232,.82);font-family:var(--sans);font-weight:700;font-size:16px;color:var(--ink);cursor:pointer}
.overlay[hidden]{display:none}
.overlay:active{transform:scale(.99)}
/* act two: no terminal. A plain chat input, one rounded field in the page's paper with a thin ink border and a send
   arrow inside it on the right; 16 px so a phone does not zoom; the line posts in the channel as the person at the booth */
/* the shrunk input keeps the terminal's look (Sven): the same peach, the same ink border, shadow and rounded frame,
   one row tall, no title bar, the send arrow inside on the right */
.ask{display:none;position:relative;flex:none;margin:6px var(--pad) 18px}
.ask input{display:block;width:100%;min-height:48px;padding:0 54px 0 16px;border:2px solid var(--ink);border-radius:12px;box-shadow:0 5px 0 var(--ink);background:var(--peach);color:var(--ink);font-family:var(--mono);font-weight:400;font-size:14px;outline:none;transition:box-shadow .2s}
.ask input::placeholder{color:var(--ink);opacity:.45}
.ask input:focus{box-shadow:0 5px 0 var(--ink),0 0 0 3px var(--gold)}
.ask button{position:absolute;right:5px;top:50%;width:40px;height:40px;margin-top:-20px;padding:0;border:0;border-radius:50%;background:var(--ink);color:var(--paper);display:flex;align-items:center;justify-content:center;cursor:pointer}
.ask button svg{width:20px;height:20px;display:block}
.ask button:active{transform:scale(.94)}
.ask button:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
.one.act2 .pane{display:none}
.one.act2 .ask{display:block}
/* the hand-over: the terminal frame collapses (its height goes to nothing) and fades, the lines behind the title bar
   with it; the chat input fades in under it, where the frame ends */
.one.moving .pane{display:flex;margin-top:0;margin-bottom:0;opacity:0;transition:height var(--move) cubic-bezier(.4,0,.2,1),opacity var(--move) cubic-bezier(.4,0,.2,1)}   /* the fade lasts as long as the collapse, so the frame is seen shrinking */
.one.moving .term{display:block;position:absolute;left:0;right:0;flex:none}
.one.moving .ask{display:block;transition:opacity .35s ease calc(var(--move) * .5)}   /* the input comes in during the second half */
.one.moving .overlay{display:none}
/* ghost text: the suggested line, dimmed, at the cursor. Tab, the right arrow or a click fills the line (Enter sends).
   On a phone the "tap" chip is a real button, 40 px tall, that fills and sends; a tap on the text only fills the line */
.ghost{position:absolute;display:none;pointer-events:auto;cursor:pointer;touch-action:manipulation;white-space:pre;font-family:var(--mono);color:var(--ink);z-index:40}
.ghost:before{content:"";position:absolute;left:0;right:0;top:-10px;bottom:-10px}   /* the tap area is 40 px tall; the line itself stays one cell */
.ghost>span{display:inline-block;text-align:center;opacity:.42}
.ghost span:first-child{color:var(--paper);opacity:1;background:var(--ink);border-radius:2px}
.ghost.on{display:flex}
/* the send button at the end of the suggestion: the same round dark arrow as the team input, 40 px, on every device
   (above the :before tap area, so a tap lands on it); on a keyboard a small muted "Tab" hint beside it */
.ghost .key{position:relative;z-index:1;flex:none;width:40px;height:40px;margin:-10px 0 -10px 10px;padding:0;border:0;border-radius:50%;background:var(--ink);color:var(--paper);display:inline-flex;align-items:center;justify-content:center;align-self:center;cursor:pointer;opacity:1}
.ghost .key svg{width:18px;height:18px;display:block}
.ghost .key:active{transform:scale(.94)}
.ghost .key.word{width:auto;height:30px;margin:-6px 0 -6px 10px;padding:0 12px;border-radius:8px;font-family:var(--mono);font-size:.85em;font-weight:600}

/* act two: the three prepared lines as quiet chips above the input (team/transcript.json prompts); 40 px targets,
   one row that scrolls sideways on a narrow screen, no scrollbar */
.chips{display:none;flex-wrap:nowrap;gap:6px;margin:4px var(--pad) 0;overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch}
.chips::-webkit-scrollbar{display:none}
.chips button{flex:none;min-height:40px;font-family:var(--mono);font-size:11px;font-weight:600;padding:0 11px;border:1.5px solid #c9c3b6;border-radius:999px;background:transparent;color:var(--ink);cursor:pointer;white-space:nowrap}
.chips button:active{background:var(--paper);border-color:var(--ink)}
.chips button:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
.one.act2 .chips{display:flex;animation:in .3s ease both}

/* the chat is never a window (Sven): plain scrollable text flat on the cream, one row per line said, newest at the
   bottom, the name in colour with the handle small, a time column from 900 px, no scrollbar. Beside the terminal from
   900 px; on a phone above the terminal in act one (about four lines), between the line and the chips in act two */
.transcript{display:flex;flex-direction:column;min-height:0;margin:10px var(--pad) 18px 0;max-height:max(240px,calc(100dvh - 330px));overflow-y:auto;overscroll-behavior:contain;scrollbar-width:none}
.transcript::-webkit-scrollbar{display:none}   /* no scrollbar, as in the terminal; scrolling still works */
/* the head: the two rooms as plain text tabs (the one selected in ink with a short underline, the other muted, 40 px
   targets) and the count; sticky over the rows (z-index: the rows keep a filled transform animation) */
.chan{position:sticky;top:0;z-index:1;flex:none;background:var(--cream);font-family:var(--mono);font-size:11.5px;color:var(--muted);padding:0 0 2px;display:flex;justify-content:space-between;align-items:center;gap:8px}
.chan span{font-weight:400;white-space:nowrap}
.rooms{display:inline-flex;gap:18px}
.room{all:unset;cursor:pointer;position:relative;display:inline-flex;align-items:center;min-height:40px;padding:0 2px;font-family:var(--sans);font-weight:600;font-size:13px;color:var(--muted);-webkit-tap-highlight-color:transparent}
.room.on{color:var(--ink)}
.room.on:after{content:"";position:absolute;left:2px;bottom:7px;width:24px;height:2px;border-radius:1px;background:var(--ink)}
.room:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
.room .dot{display:none;width:8px;height:8px;border-radius:50%;background:var(--gold);margin-left:6px}   /* something new in that room */
.room.unread .dot{display:inline-block}
.one:not(.act2) .chan,.one.moving .chan{display:none}   /* the onboarding needs no tabs: the rooms come with the team part */
.rows{display:none}
.rows.on{display:block}
.one.moving #rows-onboarding{opacity:0;transition:opacity var(--move) ease}   /* the onboarding chat fades out with the terminal */
#rows-agents .empty{color:var(--muted)}   /* "Ask @events what is on tonight." until the first post */
.transcript .empty{font-family:var(--mono);font-size:12.5px;font-weight:400;color:var(--muted);padding:8px 0 8px 10px}
.rows:has(.row) .empty{display:none}
.row{flex:none;display:grid;grid-template-columns:40px minmax(0,1fr);grid-template-areas:"time n" "time t";column-gap:8px;padding:7px 4px 7px 10px;border-left:3px solid transparent;animation:in .3s ease both}   /* flex:none: a row in the scrolling column never shrinks */
.row time{grid-area:time;font-family:var(--mono);font-size:11px;color:var(--muted);padding-top:1px;white-space:nowrap}
.row .n{grid-area:n;font-family:var(--mono);font-size:11px;font-weight:700}
.row .t{grid-area:t}
.row .n small{font-weight:400;color:var(--muted);margin-left:8px}
.row .t{font-family:var(--mono);font-size:13px;line-height:1.5;margin-top:3px;font-weight:400;overflow-wrap:anywhere}
.row.clawd .n{color:var(--clawd)}.row.codex .n{color:var(--codex)}
.row.human .n{color:#9c6e2a}.row.human{border-left-color:var(--gold)}
.row.other .n,.row.seat .n{color:var(--ink)}
.row.sys .t{color:var(--muted);font-size:12px}
.row.join{padding-top:4px;padding-bottom:4px}   /* "Mia joined.": one quiet line, no name, muted small */
.row.join .n{display:none}
.row.join .t{color:var(--muted);font-size:11.5px;margin-top:0}
.row .at{color:var(--gold);font-weight:700}
.row a{color:var(--ink);font-weight:600;text-decoration:underline;text-decoration-color:var(--gold);text-decoration-thickness:1.5px;text-underline-offset:2px;word-break:normal;padding:12px 0}   /* a URL as a short link: the host and an ellipsis; the vertical padding is a 40 px tap area, it does not move the lines */
.row .t{white-space:pre-line}   /* an events answer keeps its lines */
/* an events pick: a flat card, a hairline round it, the whole card the link */
.row a.pick{display:block;margin:4px 0 0;padding:7px 10px;border:1px solid var(--line);border-radius:8px;text-decoration:none;white-space:normal;min-height:44px}   /* 4 px under the head line */
.row a.pick+a.pick{margin-top:6px}   /* 6 px between cards */
.row a.pick b{display:block;font-weight:700;font-size:12.5px;line-height:1.35;color:var(--ink)}
.row a.pick small{display:block;font-size:11px;line-height:1.3;color:var(--muted);margin-top:1px}
.row a.pick:active{background:var(--paper)}
.one.act2 .transcript{max-height:none}

/* the QR corner in act two: phones scan it for a seat of their own (hidden until run.sh tunnel posts a URL, and on phones) */
.qr{position:absolute;right:0;bottom:8px;z-index:6;display:flex;align-items:center;gap:12px;background:var(--cream);border:1px solid var(--line);border-radius:12px;padding:8px 12px 8px 8px;box-shadow:0 2px 0 var(--line)}
.qr[hidden]{display:none}
.picture .qr{display:none}
.one.pic2 .picture .qr:not([hidden]){display:flex}
.qr img{width:92px;height:92px;display:block;border-radius:6px;background:#fff}
.qr span{display:flex;flex-direction:column;gap:4px;font-family:var(--sans);font-size:14px;line-height:1.2;color:var(--ink)}
.qr span b{font-weight:600}
.qr span small{font-family:var(--mono);font-size:10.5px;letter-spacing:.02em;color:var(--muted);max-width:170px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* a spectator's phone: ?watch=1 shows the picture, the top line while it narrates (not the instructions, the
   spectator has no keyboard), and the chat alone, plain: no terminal, no chips, no dots, no frame */
.watch .bottom,.watch .one .chips,.watch .headline,.watch .dots,.watch .topline[data-kind=step]{display:none}   /* .one .chips: outranks act two's display:flex */
.watch .one,.watch .one.act2{grid-template-columns:minmax(0,1fr);grid-template-rows:var(--scene-h) auto minmax(0,1fr) auto;grid-template-areas:"pic" "line" "chat" "book"}
.watch .one.act2{grid-template-rows:auto auto minmax(0,1fr) auto}   /* the picture keeps its act-two height, the team walks in for the spectator too */
.watch .one.act2 .picture{height:calc(var(--app-h) * .28)!important}   /* also on a laptop, where act two otherwise lets the picture fill a flexible row */
.watch .transcript{display:block;margin:6px var(--pad) 0;max-height:none;border-top:1px solid var(--line);padding-bottom:16px}
.watch .chan{padding:4px 0 2px}
@keyframes in{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
.static *{animation-duration:0s!important;transition:none!important}

/* the one top line (config steps.<step>.line and the moments inside a step): what is happening now or what to do
   next, one sentence or two, and four quiet dots for the progress (done ink, now gold). The command itself is the
   ghost text in the terminal. On a laptop one line, ellipsized; on a phone two lines at most */
.topline{display:flex;align-items:flex-start;gap:10px;padding:8px var(--pad) 0;min-height:29px}
.dots{list-style:none;display:flex;gap:5px;align-items:center;flex:none;height:21px}
.dots li{width:7px;height:7px;border-radius:50%;border:1.5px solid var(--line);background:transparent;transition:background .3s,border-color .3s}
.dots li.done{background:var(--ink);border-color:var(--ink)}
.dots li.now{background:var(--gold);border-color:var(--gold)}
.line{min-width:0;font-family:var(--sans);font-weight:600;font-size:15px;line-height:1.4;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.line .at{color:var(--gold);font-weight:700}

/* attract mode: the whole team page (the recording) in an overlay, cross-faded over the page; app.js sets its top to the header's height */
.team{position:absolute;inset:0;top:50px;opacity:0;transition:opacity .6s;background:var(--cream)}
.team[hidden]{display:none}
.team.on{opacity:1}
.team iframe{width:100%;height:100%;border:0;display:block;background:var(--cream)}
.team .qr{right:var(--pad);bottom:14px}
/* "recording, this morning" sits in the booth's own header while the attract loop plays, so it covers nothing on the team page */
.where .rec{font-size:10.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--ink);border:1px solid var(--ink);border-radius:999px;padding:3px 8px;background:var(--cream)}
.where .rec[hidden]{display:none}

/* from 900 px: the chat is a column on the right (two fifths). Act one: beside the terminal, the headline, the
   picture and the line span both columns. Act two: full height beside everything; the picture takes the room the
   terminal gave up (its row is the flexible one) */
@media (min-width:900px){
  .one{grid-template-columns:minmax(0,3fr) minmax(0,2fr);grid-template-rows:auto var(--scene-h) auto minmax(0,1fr) auto;grid-template-areas:"head head" "pic pic" "line line" "pane chat" "book book"}
  .one.act2{grid-template-rows:auto minmax(0,1fr) auto auto auto auto;grid-template-areas:"head chat" "pic chat" "line chat" "chips chat" "pane chat" "book book"}
  .one.act2 .picture{height:auto}
  .one.moving{grid-template-rows:auto auto auto auto auto auto;grid-template-areas:"head chat" "pic chat" "line chat" "chips chat" "pane chat" "book book"}
  .one.act2 .chips{margin-bottom:0}
}

/* the keyboard is up (visual viewport under 620 px): the terminal keeps its rows; the scene shrinks to the two
   sprites and their names (no bubbles, they would sit over the header), the headline goes, the top line stays at one row */
html.short{--scene-h:120px;--sprite:48px}
html.short .pane{max-height:none}
html.short .headline,html.short .sbub,html.short .phone{display:none}
html.short .one:not(.act2):not(.moving) .transcript{display:none}   /* the keyboard is up in act one: the terminal keeps the room */
html.short .one.act2 .picture{display:none}   /* act two: six faces do not fit a 130 px strip; the picture returns when the keyboard goes */
html.short .floor{bottom:36px}html.short .ch{bottom:39px}
html.short .topline{padding-top:4px}
html.short .line{display:block;white-space:nowrap;-webkit-line-clamp:unset;min-height:0}

/* phone: the brand and the space on one row, no mode tag; the headline at 24 px; the tags one line each; the top line
   takes two lines at most */
@media (max-width:640px){
  :root{--pad:12px;--scene-h:clamp(170px,30vh,240px);--sprite:clamp(48px,10vh,76px)}
  .top{padding:10px var(--pad) 4px}
  .brand{font-size:15px}.brand span{white-space:nowrap}
  .where{font-size:11px}.modetag{display:none}
  .headline{font-size:24px;padding:4px var(--pad) 0}
  .ch.l{left:25%}.ch.r{left:75%}
  .ch .tag{font-size:10.5px;max-width:44vw}
  .ch .tag b{font-size:14px}.ch .tag small{font-size:10.5px}
  .sbub{max-width:62vw;font-size:11.5px;min-width:130px}
  .topline{padding-top:6px;gap:8px;min-height:26px}
  .dots{height:19px;gap:4px}.dots li{width:6px;height:6px}
  .line{font-size:14px;line-height:1.35;min-height:2.7em;white-space:normal;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}   /* two rows reserved, so the terminal does not resize at every change */
  .ptitle{font-size:11.5px;padding:6px 10px}
  .chips{margin-top:2px}
  .chips button{padding:0 10px}
  .ask input{font-size:16px}   /* 16 px: the phone does not zoom into the input */
  .picture .qr{display:none!important}
  .one.act2 .headline{display:none}   /* act two on a phone: the faces and the chat get the headline's room */
  .book{justify-self:center}   /* centred on a phone, left on a laptop */
}
/* under 900 px (phones, tablets in portrait). Act one: the flat chat above the terminal, between the top line and the
   frame, about four lines tall, scrollable, newest at the bottom; it fills as the onboarding runs. Act two (and the
   move): the same flat chat between the line and the chips with all the room the terminal gave up, no time column.
   ?watch=1 keeps the plain full chat */
@media (max-width:899px){
  .row{display:block}
  .row time{display:none}
  html:not(.watch) .one:not(.act2):not(.moving) .transcript{height:98px;margin:2px var(--pad) 0;max-height:none}   /* about four lines, no tabs */
  html:not(.watch) .one.act2 .transcript,html:not(.watch) .one.moving .transcript{margin:4px var(--pad) 4px;max-height:none}
  .row{padding:6px 0 6px 8px}
}
/* test frame: ?w=390 applies the phone rules inside a wider window (headless Chrome's own screenshot mode cannot go below about 500 px) */
.narrow{--pad:12px;--scene-h:clamp(170px,30vh,240px);--sprite:clamp(48px,10vh,76px)}
.narrow .app{margin:0 auto;border-left:1px solid var(--line);border-right:1px solid var(--line)}
.narrow .top{padding:10px var(--pad) 4px;flex-wrap:wrap;row-gap:2px}
.narrow .brand{font-size:15px}.narrow .brand span{white-space:nowrap}
.narrow .where{font-size:11px}.narrow .modetag{display:none}
.narrow .headline{font-size:24px;padding:4px var(--pad) 0}
.narrow .ch.l{left:25%}.narrow .ch.r{left:75%}
.narrow .ch .tag{font-size:10.5px;max-width:44vw}
.narrow .ch .tag b{font-size:14px}.narrow .ch .tag small{font-size:10.5px}
.narrow .sbub{max-width:52vw;font-size:11.5px;min-width:130px}
.narrow .topline{padding-top:6px;gap:8px;min-height:26px}
.narrow .dots{height:19px;gap:4px}.narrow .dots li{width:6px;height:6px}
.narrow .line{font-size:14px;line-height:1.35;min-height:2.7em;white-space:normal;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
.narrow .ptitle{font-size:11.5px;padding:6px 10px}
