/* Arkio web app shell. Utilitarian, calm, out of the way of the 3D scene. Dark by default (the scene reads
   better against dark chrome); a light scheme is provided for completeness. The colours are the 3.0 website's
   (Website/prototype-3.0/handoff/web-app-colors.md, 2026-10-04): neutrals do the work and teal means Arkio and
   action. Teal is a fill or a 2 px line; anything teal that has to be read (text, links, icons, focus rings,
   1 px state borders) uses --accent-text, because Arkio teal is 2.2:1 on white. One teal button per view:
   --accent-ink on --accent, --accent-hover under the pointer. Status colours keep the app's own amber and red,
   darkened in the light theme to pass 4.5:1. */
:root {
  --bg: #0E1A19;            /* deepest surface: app background, sunken inputs (the site's ink on teal) */
  --panel: #152021;         /* panes and toolbars (the site's dark sections) */
  --panel-2: #1B2526;       /* raised surfaces: composer, rails, cards */
  --line: #2E393A;          /* borders and dividers */
  --ink: #E8EEEC;           /* primary text */
  --muted: #B5C3C1;         /* secondary text */
  --accent: #4CC1B8;        /* Arkio teal: primary buttons, selection, the active-tool line. Fills and lines, not text */
  --accent-hover: #3DB3AA;  /* primary button under the pointer */
  --accent-pressed: #34A198;/* primary button pressed */
  --accent-ink: #0E1A19;    /* text and icons on --accent (8.2:1) */
  --accent-text: #7ED8CE;   /* teal that has to be read: text, links, icons, focus rings, 1 px state borders */
  --accent-soft: #1D3F3B;   /* toggles that are on, tints, highlights */
  --range-accent: var(--accent); /* native slider fill and thumb; the light theme needs a darker teal to keep its track gray */
  --amber: #D9A441;         /* warnings and low credits */
  --danger: #E07A6A;        /* errors and destructive actions */
  --user-bubble: #EEF1EF;   /* light bubble on dark chrome */
  --user-ink: #1B2526;
  --divider-w: 6px;
  --app-height: 100vh; /* fallback before JS measures the visible viewport */
  --app-top: 0px;
  /* ---- the player's toolbar, in one place: the line under the active tool (and the tabs to come), inks, sizes ---- */
  --tool-line: var(--accent);      /* 2px line under the active tool and tab */
  --tool-ink: var(--ink);          /* tool icon colour */
  --tool-ink-off: #6F807D;         /* disabled tool icon colour, the same in both themes */
  --toolbar-h: 48px;               /* scene header height, the line the other pane headers align to */
  --tool-w: 36px;                  /* palette button width; a tool is as tall as the toolbar so its line sits on its bottom edge */
  --tool-icon: 20px;               /* glyph size */
  --rail-w: 48px;                 /* the side panel's rail of tabs at the right edge */
}
@media (prefers-color-scheme: light) {
  :root {
    --bg: #EEF1EF; --panel: #FFFFFF; --panel-2: #EEF1EF; --line: #E6E4DD;   /* --panel-2 = --bg on purpose: --line separates them */
    --ink: #1B2526; --muted: #5E6869;
    --accent-text: #1F6F66; --accent-soft: #DDF5F1; --amber: #8B641C; --danger: #C13D28;
    --range-accent: var(--accent-text); /* Chromium gives a light accent a dark contrasting track, even on white panels */
    --user-bubble: #EEF1EF; --user-ink: #1B2526;
    /* --accent, --accent-hover, --accent-pressed, --accent-ink and --tool-ink-off are the same in both themes */
  }
}

@supports (height: 100dvh) { :root { --app-height: 100dvh; } }
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; overflow: hidden; }
/* Safari browser chrome and the keyboard can shrink/pan the visible viewport without changing 100vh.
   app.js maintains its height/top; safe-area padding keeps every pane above the home indicator. */
body {
  position: fixed; top: var(--app-top); left: 0; width: 100%; height: var(--app-height);
  padding: env(safe-area-inset-top, 0px) env(safe-area-inset-right, 0px) env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px);
  background: var(--bg); color: var(--ink);
  font-family: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 15px; line-height: 1.5;
}

#split { display: flex; width: 100%; height: 100%; }

/* ---- sessions sidebar (leftmost) ---- */
#sessions {
  height: 100%; min-width: 150px; display: flex; flex-direction: column; overflow: hidden;
  background: var(--panel-2); border-right: 1px solid var(--line);
}
#new-chat {
  margin: 12px 10px 8px; padding: 9px 12px; text-align: left;
  border: 1px solid var(--line); border-radius: 9px; background: var(--panel);
  color: var(--ink); font: inherit; font-size: 13.5px; font-weight: 600; cursor: pointer;
  transition: border-color .15s ease;
}
#new-chat:hover { border-color: var(--accent-text); }
/* ---- the chats list (design canvas page 27; app.js "sessions UI") ---- */
/* #chats is the list: the two places, a hairline, the chats' head, the scrolling rows and the status line. #place is a
   place drilled into the column in its stead (Media, Samples); New chat above and the account footer below stay. */
#chats, #place { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
#chats[hidden], #place[hidden] { display: none; }
/* The two places, Media and Samples: a glyph tile, two lines and the chevron that says "this opens in the column".
   Buttons, never selected: a place is not a chat. */
.places { flex: 0 0 auto; display: flex; flex-direction: column; gap: 2px; padding: 0 8px 2px; }
/* A place is one line at the chat rows' height: a glyph, the name, the chevron that says it opens in the column. Counts
   and progress belong to the place itself, not to the list. */
.place-row {
  display: flex; align-items: center; gap: 8px; width: 100%; padding: 6px 4px 6px 10px;
  border: 0; border-radius: 8px; background: transparent; color: var(--ink); font: inherit; font-size: 13px; line-height: 1.35; text-align: left; cursor: pointer;
}
.place-row:hover, .place-row:focus-visible { background: var(--chat-hover, rgba(127,127,127,.08)); outline: none; }
.place-glyph { flex: 0 0 auto; display: inline-flex; color: var(--muted); }
.place-glyph svg { width: 15px; height: 15px; }
.place-name { flex: 1 1 auto; min-width: 0; padding: 2px 0; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.place-chevron { flex: 0 0 auto; display: inline-flex; color: var(--muted); }
.place-chevron svg { width: 13px; height: 13px; }
.chats-rule { flex: 0 0 1px; margin: 4px 16px; background: var(--line); }
/* The chats' head: the caption and the List | Cards toggle, the picked view pressed. */
.chats-head { flex: 0 0 auto; display: flex; align-items: center; gap: 8px; padding: 6px 10px 4px 18px; }
.chats-caption { flex: 1 1 auto; font-size: 11px; font-weight: 600; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); }
.view-toggle { display: inline-flex; border: 1px solid var(--line); border-radius: 6px; overflow: hidden; background: var(--panel); }
.view-btn { width: 26px; height: 22px; display: grid; place-items: center; padding: 0; border: 0; background: transparent; color: var(--muted); cursor: pointer; }
.view-btn svg { width: 13px; height: 13px; }
.view-btn:hover, .view-btn:focus-visible { color: var(--ink); outline: none; }
.view-btn[aria-pressed="true"] { color: var(--ink); background: var(--active-item, rgba(127,127,127,.14)); }
/* The rows scroll together: the chats, then Archived and, open, its chats. In the card view the two listboxes are
   grids, two cards to a row whatever the column's width. */
#session-list { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 0 8px 12px; display: flex; flex-direction: column; }
#chat-rows, #archived-rows { display: flex; flex-direction: column; gap: 1px; }
#chat-rows.cards, #archived-rows.cards { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 2px; align-content: start; }
#archived-rows[hidden], #archived-empty[hidden], .archived-foot[hidden] { display: none; }
/* Archived at the foot of the same list: a quiet row with the archive glyph, the word, the count and a chevron that
   turns down while the section is open. A sub-section of the chats, so it keeps its lighter style. */
.archived-foot {
  display: flex; align-items: center; gap: 8px; width: calc(100% - 4px); margin: 4px 2px 0; height: 30px; padding: 0 10px;
  border: 0; border-radius: 7px; background: transparent; color: var(--muted); font: inherit; font-size: 12px; text-align: left; cursor: pointer;
}
.archived-foot:hover, .archived-foot:focus-visible { background: var(--chat-hover, rgba(127,127,127,.08)); color: var(--ink); outline: none; }
.archived-foot svg { flex: 0 0 auto; width: 14px; height: 14px; }
.archived-foot .archived-chevron { width: 12px; height: 12px; transition: transform .15s ease; }
.archived-foot[aria-expanded="true"] .archived-chevron { transform: rotate(90deg); }
.archived-word { flex: 1 1 auto; }
#archived-empty { margin: 6px 10px 4px; font-size: 12px; line-height: 1.4; color: var(--muted); }
#archived-empty strong { display: block; color: var(--ink); font-weight: 600; }
#archived-empty p { margin: 2px 0 0; }
/* An archived chat: muted, its title still readable, Restore under the pointer (and in its menu) and nothing else;
   clicking the row does not open it. */
.session-item.archived { color: var(--muted); }
.session-item.archived:hover, .session-item.archived.menu-open { color: var(--ink); }
.session-item[data-open-disabled="true"], .session-item[data-open-disabled="true"] .session-title { cursor: default; }
.session-restore {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 5px; height: 22px; padding: 0 8px;
  border: 1px solid var(--line); border-radius: 6px; background: var(--panel); color: var(--ink);
  font: inherit; font-size: 11px; font-weight: 600; line-height: 1; white-space: nowrap; cursor: pointer; opacity: 0; transition: opacity .12s ease, border-color .15s ease;
}
.session-restore svg { width: 12px; height: 12px; }
/* In a row the pill leaves the layout while unseen, so the title keeps its width; on a card it sits over the still. */
.session-item .session-restore { display: none; }
.session-item:hover .session-restore, .session-item:focus-within .session-restore, .session-item.menu-open .session-restore { display: inline-flex; }
.session-item:hover .session-restore, .session-item:focus-within .session-restore, .session-item.menu-open .session-restore,
.lib-card:hover .session-restore, .lib-card:focus-within .session-restore, .lib-card.menu-open .session-restore { opacity: 1; }
.session-restore:hover, .session-restore:focus-visible { border-color: var(--accent-text); outline: none; }
.session-restore:disabled { opacity: .45; cursor: default; }
/* The list's one feedback line, at the foot above the account footer: what the last archive or restore did, naming
   the chat, with its one action (Show in Archived, Show in Chats, Retry) and a detail line while the cloud side waits. */
#chats-status { flex: 0 0 auto; margin: 0 10px 8px; padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel); font-size: 12px; line-height: 1.4; color: var(--ink); }
#chats-status[hidden] { display: none; }
#chats-status[data-kind="error"] { border-color: var(--amber); }
.cs-line { display: flex; align-items: baseline; gap: 6px; min-width: 0; flex-wrap: wrap; }
.cs-text { font-weight: 600; }
.cs-name { flex: 1 1 auto; min-width: 0; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cs-action { flex: 0 0 auto; padding: 0; border: 0; background: transparent; color: var(--accent-text); font: inherit; font-size: 12px; font-weight: 600; cursor: pointer; }
.cs-action:hover, .cs-action:focus-visible { text-decoration: underline; outline: none; }
.cs-detail { display: block; margin-top: 2px; color: var(--muted); }
/* A row the status line points at (Show in Archived, Show in Chats) wears the ring for a moment. */
.session-item.highlight, .lib-card.highlight { box-shadow: inset 0 0 0 2px var(--accent); }
.session-item, .lib-card { transition: box-shadow .6s ease; }
/* A place drilled into the column: the back chevron, the name, what it holds at the right, and the body under them.
   The Saved media fixture's one action (Delete saved media) keeps its ⋮ in the Media header while the fixture exists. */
.place-head { flex: 0 0 42px; display: flex; align-items: center; gap: 6px; padding: 0 12px 0 6px; }
#place-back { flex: 0 0 auto; width: 26px; height: 26px; display: grid; place-items: center; padding: 0; border: 0; border-radius: 6px; background: transparent; color: var(--muted); cursor: pointer; }
#place-back svg { width: 15px; height: 15px; }
#place-back:hover, #place-back:focus-visible { color: var(--ink); background: var(--chat-hover, rgba(127,127,127,.08)); outline: none; }
#place-title { flex: 1 0 auto; min-width: 0; font-size: 13.5px; font-weight: 600; color: var(--ink); white-space: nowrap; }
#place-meta { flex: 0 1 auto; min-width: 0; font-size: 11.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#place-menu-btn { opacity: 1; }
#place-menu-btn[hidden] { display: none; }
#place-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; }
/* Cards: the chats in the card view and the samples, two to a row: a still (or a placeholder with a glyph), the name and
   a meta line. A card opens its chat as a row does; the selected chat wears the ring; an empty chat is a blank card. */
.lib-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 2px; padding: 0 8px; align-content: start; }
.lib-card { min-width: 0; display: flex; flex-direction: column; gap: 5px; padding: 6px; border-radius: 9px; color: var(--ink); cursor: pointer; user-select: none; }
.lib-card:hover, .lib-card.menu-open { background: var(--chat-hover, rgba(127,127,127,.08)); }
.lib-card.active { box-shadow: inset 0 0 0 2px var(--accent); }
.lib-card[data-open-disabled="true"] { cursor: default; }
.lib-still { position: relative; height: 76px; border-radius: 6px; overflow: hidden; border: 1px solid var(--line); background: var(--panel); }
.lib-still img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.lib-still-empty { position: absolute; inset: 0; display: grid; place-items: center; background: var(--panel-2); color: var(--muted); }
.lib-still-empty svg { width: 18px; height: 18px; }
.lib-title-row { display: flex; align-items: center; gap: 6px; min-width: 0; }
.lib-dot { flex: 0 0 7px; width: 7px; height: 7px; border-radius: 50%; background: var(--accent); }
.lib-dot[hidden] { display: none; }
.lib-card .session-title { padding: 0; font-size: 12px; font-weight: 600; line-height: 1.25; }
.lib-card .session-meta { margin-top: -3px; }
.lib-card.empty .session-title, .lib-card.archived .session-title { color: var(--muted); }
.lib-card .session-menu-btn { position: absolute; right: 5px; top: 5px; background: var(--panel); border: 1px solid var(--line); }
.lib-card:hover .session-menu-btn, .lib-card.active .session-menu-btn, .lib-card.menu-open .session-menu-btn { opacity: 1; }
.lib-card .session-open { position: absolute; right: 5px; bottom: 5px; display: inline-flex; align-items: center; height: 16px; padding: 0 5px; border-radius: 4px; background: rgba(21, 32, 33, .72); color: #fff; font-size: 10px; font-weight: 600; }
.lib-card .session-restore, .lib-pill { position: absolute; left: 5px; bottom: 5px; }
.lib-pill {
  display: inline-flex; align-items: center; gap: 5px; height: 22px; padding: 0 8px; border: 1px solid var(--line); border-radius: 6px;
  background: var(--panel); color: var(--ink); font: inherit; font-size: 11px; font-weight: 600; line-height: 1; white-space: nowrap; cursor: pointer; opacity: 0; transition: opacity .12s ease, border-color .15s ease;
}
.lib-pill svg { width: 12px; height: 12px; }
.lib-card:hover .lib-pill, .lib-card:focus-within .lib-pill, .lib-pill:focus-visible { opacity: 1; }
.lib-pill:hover, .lib-pill:focus-visible { border-color: var(--accent-text); outline: none; }
.lib-card .session-rename { margin: 0; }
/* The account footer (account.js): Log in, which grows into the email and code steps; signed in, the credits ring,
   the email and Log out. The buttons keep the pane's big-button look (New chat's). */
#account { flex: 0 0 auto; display: flex; flex-direction: column; margin: 0 10px 12px; }
#account [hidden] { display: none; }
.ac-login {
  width: 100%; padding: 9px 12px; text-align: left;
  border: 1px solid var(--line); border-radius: 9px; background: var(--panel);
  color: var(--muted); font: inherit; font-size: 13.5px; font-weight: 600; cursor: pointer;
  transition: border-color .15s ease, color .15s ease;
}
.ac-login:hover:not(:disabled) { border-color: var(--accent-text); color: var(--ink); }
.ac-login:disabled { opacity: .5; cursor: default; }
.ac-status { margin: 6px 2px 0; font-size: 11px; line-height: 1.4; color: var(--muted); }
.ac-form, .ac-in { display: flex; flex-direction: column; gap: 8px; padding: 10px; border: 1px solid var(--line); border-radius: 9px; background: var(--panel); }
.ac-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.ac-title { font-size: 13px; font-weight: 600; color: var(--ink); }
.ac-close { display: inline-grid; place-items: center; width: 22px; height: 22px; padding: 0; border: 0; border-radius: 5px; background: transparent; color: var(--muted); cursor: pointer; }
.ac-close:hover { color: var(--ink); background: var(--active-item, rgba(127, 127, 127, .14)); }
.ac-close svg { width: 12px; height: 12px; }
.ac-note { margin: 0; font-size: 11.5px; line-height: 1.4; color: var(--muted); overflow-wrap: anywhere; }
.ac-email, .ac-code { width: 100%; height: 30px; padding: 0 10px; border: 1px solid var(--line); border-radius: 7px; background: var(--bg); color: var(--ink); font: inherit; font-size: 13px; }
.ac-email:focus, .ac-code:focus { outline: none; border-color: var(--accent-text); }
.ac-email::placeholder, .ac-code::placeholder { color: var(--muted); font-weight: 400; letter-spacing: normal; }
.ac-code { text-align: center; letter-spacing: .2em; text-transform: uppercase; font-weight: 600; }
.ac-error { margin: 0; font-size: 11.5px; line-height: 1.4; color: var(--danger); }
.ac-submit { width: 100%; height: 30px; border: 0; border-radius: 7px; background: var(--accent); color: var(--accent-ink); font: inherit; font-size: 13px; font-weight: 600; cursor: pointer; }
.ac-submit:hover:not(:disabled) { background: var(--accent-hover); }
.ac-submit:disabled { opacity: .5; cursor: default; }
.ac-links { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-size: 11px; color: var(--muted); }
.ac-link { padding: 0; border: 0; background: transparent; color: var(--accent-text); font: inherit; font-size: 11px; cursor: pointer; }
.ac-link:hover:not(:disabled) { text-decoration: underline; }
.ac-link:disabled { color: var(--muted); cursor: default; }
.ac-credits { display: flex; align-items: center; gap: 10px; }
.ac-ring { width: 28px; height: 28px; flex: 0 0 auto; transform: rotate(-90deg); }
.ac-ring-track { fill: none; stroke: var(--line); stroke-width: 3; }
.ac-ring-value { fill: none; stroke: var(--accent); stroke-width: 3; stroke-linecap: round; transition: stroke-dasharray .3s ease; }
#account[data-low="true"] .ac-ring-value { stroke: var(--amber); }
#account[data-low="empty"] .ac-ring-value { stroke: var(--danger); }
.ac-credits-text { display: flex; flex-direction: column; min-width: 0; }
.ac-credits-count { font-size: 13px; font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; }
.ac-credits-label { font-size: 11px; color: var(--muted); }
.ac-email-line { font-size: 11px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* One row per chat: the title, and a ⋮ that opens the row's menu (Open scene in new chat, Delete chat). The whole
   row is the click target for switching; the ⋮ shows on hover, on the active row, while its menu is open and when
   focused, so the list stays quiet until a row is looked at. */
.session-item {
  display: flex; align-items: center; gap: 6px;
  padding: 6px 4px 6px 10px; border-radius: 8px; cursor: pointer; user-select: none;
  color: var(--muted); font-size: 13px; line-height: 1.35;
}
.session-item:hover, .session-item.menu-open { background: var(--chat-hover, rgba(127,127,127,.08)); color: var(--ink); }
.session-item.active { background: var(--agent-bubble, rgba(127,127,127,.14)); color: var(--ink); font-weight: 550; }
.session-title { flex: 1 1 auto; min-width: 0; padding: 2px 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* The name as a field, in place (Rename chat, app.js renameField): the text stays where it stood, the frame's border and
   padding pulled back by the 7 px they add; white on the column, framed in the accent as every focused field is; the
   whole name selected in the accent's tint; the ⋮ and the Open elsewhere badge step aside while it is open. */
.session-rename {
  flex: 1 1 auto; min-width: 0; height: 22px; margin: 0 0 0 -7px; padding: 0 6px;
  border: 1px solid var(--accent-text); border-radius: 5px; background: var(--panel); color: var(--ink);
  font: inherit; outline: none;
}
.session-rename::selection { background: color-mix(in srgb, var(--accent) 22%, transparent); }
.session-rename::placeholder { color: var(--muted); font-weight: 400; }
.session-menu-btn {
  flex: 0 0 auto; width: 22px; height: 22px; display: grid; place-items: center; padding: 0 0 2px;
  border: none; border-radius: 6px; background: transparent; color: var(--muted);
  font: inherit; font-size: 16px; line-height: 1; cursor: pointer; opacity: 0;
  transition: opacity .12s ease, background .15s ease, color .15s ease;
}
.session-item:hover .session-menu-btn, .session-item.active .session-menu-btn, .session-item.menu-open .session-menu-btn,
.session-menu-btn:focus-visible { opacity: 1; }
.session-menu-btn:hover, .session-menu-btn:focus-visible, .session-item.menu-open .session-menu-btn {
  background: var(--line); color: var(--ink); outline: none;
}
/* The pinned tutorial: the first row of the chats, with the accent dot the chat header uses (quiet once the lessons
   are done) and a second line saying where the learner is (chat-list.js tutorialRowMeta). */
.session-item.tutorial { gap: 10px; color: var(--ink); } /* one line like every row: its progress lives in the tutorial itself */
.session-item.tutorial::before {
  content: ""; flex: 0 0 8px; width: 8px; height: 8px; border-radius: 50%; background: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);
}
.session-item.tutorial.done::before { background: var(--line); box-shadow: none; }
.session-item.tutorial .session-title { font-weight: 600; }
.session-meta { font-size: 11px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* A scene the cloud device group sent (chat-list.js unseenDot): a plain accent dot before the name, no halo and no
   bold, on the row and in the card's title row, until the chat is first opened. */
.session-dot { flex: 0 0 7px; width: 7px; height: 7px; border-radius: 50%; background: var(--accent); }
.sessions-locked #new-chat, .sessions-locked .session-item, .sessions-locked .lib-card { opacity: .45; pointer-events: none; }

/* The chat menu popover. Same chrome as the viewer and the tutorial label: panel surface, hairline, soft shadow.
   Fixed at body level and above everything in the shell (the viewer is z 5 inside the scene pane). */
#session-menu {
  position: fixed; z-index: 20; min-width: 210px; padding: 4px;
  background: var(--panel); color: var(--ink); border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, .45);
}
#session-menu[hidden] { display: none; }
.session-menu-item {
  display: block; width: 100%; padding: 7px 12px; text-align: left;
  border: none; border-radius: 7px; background: transparent; color: var(--ink);
  font: inherit; font-size: 13px; line-height: 1.4; cursor: pointer; white-space: nowrap;
}
.session-menu-item:hover:not(:disabled), .session-menu-item:focus-visible { background: var(--chat-hover, rgba(127,127,127,.1)); outline: none; }
.session-menu-item:disabled { opacity: .45; cursor: default; }
.session-menu-item.danger { color: var(--danger); }

/* ---- scene (rightmost) ---- */
#scene { position: relative; height: 100%; min-width: 320px; flex: 1 1 auto; background: #000; overflow: hidden; }
#unity-canvas { width: 100%; height: 100%; display: block; }
.tutorial-scene-transition { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; pointer-events: none; z-index: 1; }

#loading {
  position: absolute; inset: 0; display: grid; place-items: center;
  background: radial-gradient(120% 120% at 50% 40%, #112A27 0%, #0A1213 100%);
  transition: opacity .4s ease; z-index: 2;
}
#loading.hidden { opacity: 0; pointer-events: none; }
#loading-inner { display: flex; flex-direction: column; align-items: center; gap: 18px; }
.spinner {
  width: 34px; height: 34px; border-radius: 50%;
  border: 3px solid rgba(255,255,255,.12); border-top-color: var(--accent);
  animation: spin 900ms linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .spinner { animation: none; } }
#loading-text { color: #B5C3C1; /* on the dark veil in both themes */ font-size: 14px; letter-spacing: .02em; }
#progress-track { width: 200px; height: 3px; border-radius: 3px; background: rgba(255,255,255,.1); overflow: hidden; }
#progress-fill { height: 100%; width: 0%; background: var(--accent); transition: width .2s ease; }

/* ---- dividers ---- */
.divider {
  flex: 0 0 var(--divider-w); cursor: col-resize; background: var(--line);
  position: relative; transition: background .15s ease;
  touch-action: none; user-select: none; -webkit-user-select: none; /* own the drag instead of starting Safari pan/zoom */
}
.divider::after {
  content: ""; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 2px; height: 34px; border-radius: 2px; background: var(--muted); opacity: .5;
}
.divider:hover, .divider.dragging, .divider:focus-visible { background: var(--accent); outline: none; }
/* The live video divider runs across the scene pane and drags up/down: same thickness, the grip turned on its side. */
.divider.horizontal { cursor: row-resize; width: 100%; }
.divider.horizontal::after { width: 34px; height: 2px; }

/* ---- chat (middle) ---- */
#chat {
  height: 100%; min-width: 260px;
  display: flex; flex-direction: column; background: var(--panel);
}
#chat-header {
  display: flex; align-items: center; gap: 8px;
  min-height: var(--toolbar-h); padding: 0 18px; border-bottom: 1px solid var(--line); /* as tall as the player toolbar */
  font-weight: 600; font-size: 14px; letter-spacing: .01em;
}
#chat-header .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent); }
#chat-header .dot[data-busy="true"] { animation: pulse 1.6s ease-in-out infinite; } /* the agent is working: the chat's activity line has the words */
/* The header names the open chat (app.js syncChatTitle) and never wraps: the name takes the room there is and is cut
   short; the Logs button and the save state keep their width at its right (design canvas page 28). */
#chat-title { flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#chat-metrics {
  padding: 8px 18px; border-bottom: 1px solid var(--line);
  color: var(--muted); font-size: 12px; line-height: 1.35;
}

/* ---- tutorial lesson card (above the composer, outside the scrolling transcript) ---- */
#tutorial-panel {
  flex: 0 0 auto; display: flex; flex-direction: column; gap: 6px; padding: 12px 18px 12px;
  border-top: 1px solid var(--line); background: var(--panel-2);
}
#tutorial-panel[hidden] { display: none; }
#tutorial-chapters { display: flex; gap: 6px; list-style: none; margin: 0 0 5px; padding: 0; font-size: 11px; line-height: 1.4; color: var(--muted); }
#tutorial-chapters li { flex: 1; border-top: 3px solid var(--line); padding-top: 6px; }
#tutorial-chapters li[aria-current="step"] { border-color: var(--accent-text); color: var(--ink); font-weight: 600; }
#tutorial-chapters li.done { border-color: var(--accent-text); }
#tutorial-chapters.modelling li { text-align: center; }
#tutorial-files { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
#tutorial-files[hidden] { display: none; }
#tutorial-chapters[hidden], #tutorial-auto[hidden] { display: none; }
#tutorial-demo-note { color: var(--muted); font-size: 11.5px; line-height: 1.4; }
#tutorial-demo-note:empty, #tutorial-error:empty { display: none; }
#tutorial-error { color: var(--ink); font-size: 12.5px; line-height: 1.4; }
#composer-request { display: flex; flex-direction: column; gap: 5px; }
#composer-request.suggested-request { padding: 8px; border: 1px solid var(--accent-text); border-radius: 12px; }
#tutorial-prompt-label { font-size: 11.5px; line-height: 1.4; color: var(--muted); }
#composer-request.needs-action { box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 28%, transparent); animation: tutorial-request-attention 2.4s ease-in-out infinite; }
@keyframes tutorial-request-attention { 50% { box-shadow: 0 0 0 9px color-mix(in srgb, var(--accent) 10%, transparent); } }
@media (prefers-reduced-motion: reduce) { #composer-request.needs-action { animation: none; } }
#tutorial-prompt-label[hidden], #tutorial-modelling[hidden] { display: none; }
.guided-reply::before { content: 'Guided example'; display: block; margin-bottom: 5px; color: var(--muted); font-size: 11px; }
#tutorial-eyebrow { display: flex; align-items: center; gap: 10px; font-size: 11.5px; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); font-weight: 600; }
#tutorial-verdict { margin-left: auto; text-transform: none; letter-spacing: 0; font-size: 12px; font-weight: 600; color: var(--muted); }
#tutorial-verdict.met { color: var(--accent-text); }
#tutorial-title { font-size: 15px; font-weight: 600; color: var(--ink); line-height: 1.3; }
#tutorial-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 4px; }
#tutorial-actions button {
  padding: 6px 12px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel); color: var(--ink);
  font: inherit; font-size: 13px; font-weight: 600; cursor: pointer; transition: border-color .15s ease, opacity .15s ease;
}
#tutorial-actions button:hover:not(:disabled), #tutorial-actions button:focus-visible { border-color: var(--accent-text); outline: none; }
#tutorial-actions button:disabled { opacity: .45; cursor: default; }
#tutorial-actions #tutorial-continue, #tutorial-actions #tutorial-modelling { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
#tutorial-auto { margin-left: auto; display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--muted); cursor: pointer; white-space: nowrap; }
#tutorial-auto input { accent-color: var(--accent); margin: 0; }

/* The transcript flows bottom-up: the column is bottom-anchored (margin-top:auto on the first child), so the
   first user bubble sits just above the composer and everything shifts upward as replies stream in. */
#messages {
  flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 20px 18px;
  display: flex; flex-direction: column; gap: 14px; scroll-behavior: smooth;
}
#messages > :first-child { margin-top: auto; }

.msg { white-space: pre-wrap; word-wrap: break-word; }
/* user: grey chat bubble, right-aligned (light bubble on dark chrome, like the reference) */
.msg.user {
  align-self: flex-end; max-width: 84%;
  background: var(--user-bubble); color: var(--user-ink);
  padding: 11px 15px; border-radius: 16px; border-bottom-right-radius: 6px;
}
/* agent: no bubble - plain left-aligned prose */
.msg.agent { align-self: stretch; color: var(--ink); padding: 0 2px; }
/* URLs the agent writes (help-center articles, web sources) open in a new tab; the accent keeps them visible
   against the plain prose without turning the whole message into a link list. */
.msg a { color: var(--accent-text); text-decoration: none; border-bottom: 1px solid color-mix(in srgb, var(--accent-text) 45%, transparent); word-break: break-all; }
.msg a:hover, .msg a:focus-visible { border-bottom-color: var(--accent-text); outline: none; }

/* ---- tutorial video cards (a [video:id] line in a tutor message) ---- */
.video-card {
  align-self: stretch; display: flex; flex-direction: column; overflow: hidden;
  border: 1px solid var(--line); border-radius: 10px; background: var(--panel-2);
}
.video-card video { display: block; width: 100%; aspect-ratio: 16 / 9; background: #000; }
.video-caption { display: flex; align-items: center; gap: 10px; padding: 8px 10px 8px 12px; font-size: 12.5px; color: var(--muted); }
.video-caption span { flex: 1 1 auto; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--ink); }
.video-caption button {
  flex: 0 0 auto; padding: 4px 10px; border: 1px solid var(--line); border-radius: 7px; background: var(--panel);
  color: var(--ink); font: inherit; font-size: 12px; cursor: pointer; transition: border-color .15s ease;
}
.video-caption button:hover, .video-caption button:focus-visible { border-color: var(--accent-text); outline: none; }
/* Errors stay readable without overpowering the completed work; raw technical detail belongs in the export. */
.msg.error { align-self: stretch; color: var(--muted); font-size: 13px; font-weight: 400; padding: 0 2px; }
/* model reasoning summaries: muted, smaller - "what the agent is thinking" between tool calls */
.msg.thought { align-self: stretch; color: var(--muted); font-size: 13.5px; padding: 0 2px; }

/* streamed activity lines while the agent works ("Thinking…", "Using Arkio tool: …") */
.activity { align-self: stretch; color: var(--muted); font-size: 13px; padding: 0 2px; }
.activity.current { animation: pulse 1.6s ease-in-out infinite; }
@keyframes pulse { 0%, 100% { opacity: .45; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .activity.current { animation: none; } }

/* collapsed per-turn summary once the turn completes (the "Worked for Xs" row) */
.worked {
  align-self: stretch; color: var(--muted); font-size: 13px;
  border-top: 1px solid var(--line); padding: 10px 2px 0;
}
/* Section line in Saved media: which deleted chat the media below came from, and when. */
.history-label {
  align-self: stretch; color: var(--muted); font-size: 12.5px;
  border-top: 1px solid var(--line); padding: 12px 2px 0;
}
.history-label:first-child { border-top: none; padding-top: 0; }

/* Development accounting emitted once per completed user turn. It stays visually subordinate to the conversation
   while retaining the full input/cache/output/reasoning breakdown needed to explain the estimate. */
.usage {
  align-self: stretch; color: var(--muted); font-size: 12px; line-height: 1.45;
  padding: 0 2px;
}

#empty { margin: auto; text-align: center; color: var(--muted); max-width: 260px; }
#empty h2 { font-size: 15px; font-weight: 600; color: var(--ink); margin: 0 0 6px; }
#empty p { margin: 0; font-size: 13px; }

/* ---- composer ---- */
/* The composer keeps its full content height; the transcript gives up space above it as the draft grows. */
#composer { flex: 0 0 auto; display: flex; flex-direction: column; gap: 8px; padding: 14px; border-top: 1px solid var(--line); background: var(--panel-2); }
#composer[hidden] { display: none; } /* Saved media has no one to talk to */
#composer-row { display: flex; gap: 10px; }
/* The chat pane resizes down to 260px. Wrap complete label/control groups, with space between rows,
   so every option stays reachable at narrow widths. */
#composer-options {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px; row-gap: 6px;
  font-size: 12.5px; color: var(--muted);
}
#composer-options label { letter-spacing: .02em; }
/* Keeps a label welded to its control when the row wraps - otherwise "Model" can end one line and its dropdown
   begin the next, which reads as two separate things rather than one setting. */
.opt-group { display: inline-flex; align-items: center; gap: 8px; white-space: nowrap; }
#model-opt[hidden], #chat-model-opt[hidden] { display: none; }
#composer-options .opt-sep { opacity: .45; }
/* All option selectors share their chrome. New selectors
   inherit the same normal, focus and disabled states without requiring a separate list of IDs. */
#composer-options select {
  padding: 4px 8px; border: 1px solid var(--line); border-radius: 7px;
  background: var(--bg); color: var(--ink); font: inherit; font-size: 12.5px; cursor: pointer;
}
#composer-options select:focus { outline: none; border-color: var(--accent-text); }
#composer-options select:disabled { opacity: .55; cursor: default; }
#model, #chat-model {
  max-width: 190px;                      /* unknown catalog IDs may still need their full names */
  text-overflow: ellipsis;
}
/* Stop, while the agent works: a filled square in the mic button's shape beside Queue, red only under the pointer, so
   the row stays about the next message rather than about stopping. */
#stop {
  flex: 0 0 auto; align-self: flex-end; display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; padding: 0; border: 1px solid var(--line); border-radius: 10px;
  background: var(--bg); color: var(--ink); cursor: pointer;
}
#stop svg { width: 20px; height: 20px; }
#stop:hover { border-color: var(--danger); color: var(--danger); }
#stop[hidden] { display: none; } /* the hidden attribute has to beat the display above, as it does for the mic button */
#input, #group-input {
  flex: 1 1 auto; min-width: 0; resize: none; overflow: hidden; padding: 10px 12px;
  border: 1px solid var(--line); border-radius: 10px; background: var(--bg); color: var(--ink);
  font: inherit; line-height: 1.45;
}
#input:focus, #group-input:focus { outline: none; border-color: var(--accent-text); }
#input::placeholder, #group-input::placeholder { color: var(--muted); }
#send, #group-send {
  flex: 0 0 auto; align-self: flex-end; padding: 10px 16px; border: none; border-radius: 10px;
  background: var(--accent); color: var(--accent-ink); font: inherit; font-weight: 600; cursor: pointer;
  transition: opacity .15s ease;
}
#send:hover:not(:disabled), #group-send:hover:not(:disabled) { background: var(--accent-hover); }
#send:disabled, #group-send:disabled { opacity: .4; cursor: not-allowed; }

/* ---- AI render cards (in the transcript) ---- */
/* One grid per run of consecutive renders, so a multi-view request reads as one set. auto-fill against the pane
   width: two-up on a typical chat pane, one-up when the pane is dragged narrow - never a postage stamp. */
.renders {
  align-self: stretch; display: grid; gap: 10px; padding: 0 2px;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}
.render-card { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
/* The frame is a real <button> so the thumbnail is keyboard-reachable; it is disabled until the image exists. */
.render-frame {
  position: relative; display: block; width: 100%; aspect-ratio: 4 / 3; padding: 0; margin: 0; overflow: hidden;
  border: 1px solid var(--line); border-radius: 10px; background: var(--panel-2); color: var(--muted);
  font: inherit; cursor: pointer; text-align: center;
  transition: border-color .15s ease;
}
.render-frame:hover:not(:disabled), .render-frame:focus-visible { border-color: var(--accent-text); outline: none; }
.render-frame:disabled { cursor: default; }
.render-frame img, .render-frame video { display: block; width: 100%; height: 100%; object-fit: cover; }
/* Video cards: the first frame with a play badge and the clip length, so a clip is told apart from a still at a glance. */
.render-play { position: absolute; inset: 0; display: grid; place-items: center; pointer-events: none; }
.render-play span {
  width: 44px; height: 44px; display: grid; place-items: center; border-radius: 50%;
  background: rgba(0, 0, 0, .55); color: #fff; box-shadow: 0 2px 10px rgba(0, 0, 0, .35);
}
.render-play svg { width: 18px; height: 18px; fill: currentColor; margin-left: 2px; }
.render-duration {
  position: absolute; right: 8px; bottom: 8px; padding: 1px 6px; border-radius: 6px; pointer-events: none;
  background: rgba(0, 0, 0, .6); color: #fff; font-size: 11px; font-variant-numeric: tabular-nums;
}
.render-placeholder {
  position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 8px; padding: 12px; font-size: 12.5px; line-height: 1.35;
}
.render-placeholder .spinner { width: 22px; height: 22px; border-width: 2px; }
.render-placeholder .detail { font-size: 11.5px; opacity: .8; max-height: 4.2em; overflow: hidden; }
.render-card.failed .render-frame, .render-card.interrupted .render-frame { color: var(--danger); }
.render-caption { display: flex; align-items: center; gap: 6px; padding: 0 2px; font-size: 12px; color: var(--muted); }
.render-caption-text { flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Retry for one failed image or clip (app.js mediaRetryButton), at the caption's end like the share glyph; the viewer's
   header carries the same word as a hairline action while the open original is unavailable. */
.render-caption .render-retry { flex: 0 0 auto; margin-left: auto; border: 0; padding: 0 2px; background: transparent; color: var(--accent-text); font: inherit; font-size: 12px; cursor: pointer; }
.render-caption .render-retry:hover, .render-caption .render-retry:focus-visible { text-decoration: underline; outline: none; }
.viewer-retry.viewer-action { width: auto; padding: 0 10px; font-size: 12px; }

/* ---- AI render viewer (modal over the scene pane) ---- */
/* Same chrome as the rest of the shell: panel surface, hairline border, slightly rounded corners. Sits inside
   #scene so it covers the Arkio canvas only and the chat stays readable beside it. z-index clears #loading. */
#render-viewer {
  position: absolute; inset: 0; z-index: 5; display: grid; place-items: center; padding: 24px;
  background: rgba(4, 8, 6, .72); backdrop-filter: blur(3px);
}
#render-viewer[hidden] { display: none; }
#render-viewer-panel {
  display: flex; flex-direction: column; width: min(100%, 1400px); max-height: 100%;
  background: var(--panel); color: var(--ink); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 24px 64px rgba(0, 0, 0, .5); overflow: hidden;
}
#render-viewer-header {
  display: flex; align-items: center; gap: 10px; padding: 12px 12px 12px 18px;
  border-bottom: 1px solid var(--line); font-weight: 600; font-size: 14px; letter-spacing: .01em;
}
#render-viewer-count { color: var(--muted); font-weight: 400; font-size: 12.5px; }
#render-viewer-actions { margin-left: auto; display: flex; gap: 10px; }
.viewer-action {
  flex: 0 0 auto; width: 32px; height: 32px; display: grid; place-items: center; padding: 0;
  border: 1px solid var(--line); border-radius: 8px; background: var(--panel-2); color: var(--ink);
  font: inherit; font-size: 14px; line-height: 1; text-decoration: none; cursor: pointer;
  transition: border-color .15s ease;
}
.viewer-action[hidden] { display: none; }
.viewer-action:hover, .viewer-action:focus-visible { border-color: var(--accent-text); outline: none; }
#render-viewer-stage {
  position: relative; flex: 1 1 auto; min-height: 120px; display: grid; place-items: center; background: var(--bg);
}
/* Bounded by the viewport rather than the panel: a grid cell with an indefinite height cannot cap an image's
   max-height reliably, and the header/footer and the scene header above the viewer take a known amount. */
#render-viewer-img { display: block; max-width: 100%; max-height: calc(var(--app-height) - 278px); object-fit: contain; }
#render-viewer-img[hidden] { display: none; }
/* Video mode: the clip plus a small custom control bar. Native controls were dropped so the bar matches the shell and
   so the defaults are ours (muted on open, Space/M keys). The player shares the stage with the image and only one of
   them is visible at a time. */
#render-viewer-player { position: relative; display: flex; flex-direction: column; width: min(100%, 1280px); max-height: calc(var(--app-height) - 278px); }
#render-viewer-player[hidden] { display: none; }
/* The player's pause for data, over the picture: not the download, which the header names while the stage is empty. */
#video-buffering { position: absolute; left: 50%; top: calc(50% - 24px); transform: translate(-50%, -50%); display: inline-flex; align-items: center; gap: 8px; padding: 6px 12px; border-radius: 999px; background: rgba(21, 32, 33, .72); color: #fff; font-size: 12px; pointer-events: none; }
#video-buffering[hidden] { display: none; }
#video-buffering .spinner { width: 14px; height: 14px; border-width: 2px; }
#render-viewer-video { display: block; width: 100%; max-height: calc(var(--app-height) - 328px); background: #000; object-fit: contain; cursor: pointer; }
#video-controls {
  display: flex; align-items: center; gap: 10px; padding: 8px 10px;
  background: var(--panel); border-top: 1px solid var(--line);
}
#video-controls button {
  flex: 0 0 auto; width: 32px; height: 32px; display: grid; place-items: center; padding: 0;
  border: 1px solid var(--line); border-radius: 8px; background: var(--panel-2); color: var(--ink);
  font: inherit; cursor: pointer; transition: border-color .15s ease;
}
#video-controls button:hover, #video-controls button:focus-visible { border-color: var(--accent-text); outline: none; }
#video-controls button svg { width: 16px; height: 16px; fill: currentColor; }
#video-seek { flex: 1 1 auto; min-width: 60px; margin: 0; accent-color: var(--range-accent); cursor: pointer; }
#video-time, #video-duration { flex: 0 0 auto; min-width: 3.6ch; font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
#video-duration { text-align: right; }

/* ---- tutorial highlight over the shell ---- */
/* Body-level so the scene cannot clip toolbar/drawer anchors; ordinary popup menus stay above it (z 20+).
   The SVG is inert to the pointer; only the label and its Dismiss take clicks. */
#tutorial-overlay { position: fixed; inset: 0; z-index: 10; pointer-events: none; }
#tutorial-overlay[hidden] { display: none; }
#tutorial-svg { display: block; width: 100%; height: 100%; }
#tutorial-dim { fill: none; } /* Keep the scene readable while the animated boundary teaches a control. */
/* CreateViz cage green distinguishes the instruction target from teal selected tools. */
#tutorial-ring { fill: none; stroke: #339926; stroke-width: 3; animation: tutorial-pulse 1.6s ease-in-out infinite; }
@keyframes tutorial-pulse { 0%, 100% { stroke-opacity: .55; } 50% { stroke-opacity: 1; } }
@media (prefers-reduced-motion: reduce) { #tutorial-ring { animation: none; } }
#tutorial-label {
  position: absolute; left: 8px; top: 8px; pointer-events: auto; display: flex; align-items: center; gap: 10px;
  max-width: min(340px, calc(100vw - 16px)); padding: 8px 8px 8px 12px; background: var(--panel); color: var(--ink);
  border: 1px solid var(--accent-text); border-radius: 10px; font-size: 13.5px; line-height: 1.35;
  box-shadow: 0 12px 32px rgba(0, 0, 0, .45);
}
#tutorial-dismiss {
  flex: 0 0 auto; padding: 4px 9px; border: 1px solid var(--line); border-radius: 7px; background: var(--panel-2);
  color: var(--muted); font: inherit; font-size: 12px; cursor: pointer; transition: border-color .15s ease, color .15s ease;
}
#tutorial-dismiss:hover, #tutorial-dismiss:focus-visible { border-color: var(--accent-text); color: var(--ink); outline: none; }
.viewer-nav {
  position: absolute; top: 50%; transform: translateY(-50%); width: 40px; height: 56px;
  display: grid; place-items: center; padding: 0 0 4px;
  border: 1px solid var(--line); border-radius: 10px;
  background: color-mix(in srgb, var(--panel) 88%, transparent); color: var(--ink);
  font: inherit; font-size: 28px; line-height: 1; cursor: pointer;
  transition: border-color .15s ease, opacity .15s ease;
}
.viewer-nav:hover:not(:disabled), .viewer-nav:focus-visible { border-color: var(--accent-text); outline: none; }
.viewer-nav:disabled { opacity: .3; cursor: default; }
#render-prev { left: 12px; }
#render-next { right: 12px; }
#render-viewer-footer { padding: 10px 18px 14px; border-top: 1px solid var(--line); }
#render-viewer-caption { font-size: 12.5px; color: var(--muted); }
#render-viewer-desc {
  margin-top: 4px; font-size: 13px; color: var(--ink); line-height: 1.4;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
#render-viewer-desc:empty { display: none; }

/* ---- attachments (files staged for the next message) ---- */
/* The paperclip (#attach) in the composer row and the chips above the input are the group composer's: their rules sit
   with the group chat's at the end of this file (#attach, #group-attach; .gc-chip). A refused pick is one line below. */
#attachments { display: flex; flex-wrap: wrap; gap: 6px; }
#attachments[hidden] { display: none; }
.attachment-note { flex-basis: 100%; color: var(--danger); font-size: 12px; }

/* Conversation export stays available during generation. Temporary: the button leaves the header before the commercial launch. */
#save-conversation { flex: 0 0 auto; }
#save-conversation:disabled { cursor: wait; }
/* The header action: one small hairline button for every pane header (Save conversation, the scene actions,
   the Live render pane's Start/Stop). A toggle carries aria-pressed and borrows the accent while on, so its active
   state is legible from the button. */
.header-btn {
  flex-shrink: 0; padding: 5px 8px; border: 1px solid var(--line); border-radius: 5px;
  background: transparent; color: var(--ink); font: inherit; font-size: 11px; cursor: pointer;
  transition: border-color .15s ease, background .15s ease;
}
.header-btn:hover:not(:disabled), .header-btn:focus-visible { border-color: var(--accent-text); outline: none; }
.header-btn:disabled { opacity: .5; cursor: default; }
.header-btn[aria-pressed="true"] { border-color: var(--accent-text); background: var(--accent-soft); }
#diagnostic-status { padding: 0 16px 8px; font-size: 12px; color: var(--muted); }
#session-open-error { flex: 0 0 auto; margin: 0 16px 8px; padding: 8px; border: 1px solid var(--amber); border-radius: 6px; font-size: 12px; line-height: 1.4; overflow-wrap: anywhere; }
#session-open-error[hidden] { display: none; }

/* A chat reviewed from another tab must never expose this instance’s unrelated editable canvas. */
#session-state { position: absolute; inset: 0; z-index: 4; background: var(--bg); color: var(--ink); display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 32px; text-align: center; gap: 16px; }
#session-state[hidden] { display: none; }
#session-state p { max-width: 420px; line-height: 1.5; }
#continue-here, #continue-local { border: 1px solid var(--accent); border-radius: 6px; padding: 10px 18px; background: var(--accent); color: var(--accent-ink); cursor: pointer; }
#continue-here:hover, #continue-here:focus-visible { background: var(--accent-hover); border-color: var(--accent-hover); outline: none; }
#continue-local { border-color: var(--line); background: var(--panel); color: var(--ink); } /* the way out beside the primary action is the secondary button */
#continue-local:hover, #continue-local:focus-visible { border-color: var(--accent-text); outline: none; }
.session-open { font-size: 10px; color: var(--muted, #9ca8ae); flex: none; }

/* ---- the side panel and its rail (rightmost) ---- */
/* The rail is the panel's permanent tab strip at the shell's right edge, open or closed, so nothing moves between the
   two states. Its band is level with the other headers and holds the one open/close chevron; the open tab carries
   the toolbar's accent line turned vertical, on the edge that faces the body. The body opens to the rail's left in
   the same flex split as the other panes (divider C resizes it) with a header row for the tab's title and, per
   drawer, a row of icon-only sub-tabs in the Chats / Media / Scenes style. Both hide with display:none so the split
   sees the right number of panes. The look comes from the :root toolbar variables. */
#rail {
  flex: 0 0 var(--rail-w); height: 100%; display: flex; flex-direction: column; align-items: center;
  background: var(--panel); border-left: 1px solid var(--line);
}
#rail-band { flex: 0 0 var(--toolbar-h); width: 100%; display: grid; place-items: center; border-bottom: 1px solid var(--line); }
#rail-toggle {
  width: 36px; height: 36px; display: grid; place-items: center; padding: 0; border: 0; border-radius: 7px;
  background: transparent; color: var(--muted); cursor: pointer; transition: color .15s ease;
}
#rail-toggle:hover, #rail-toggle:focus-visible { color: var(--ink); outline: none; }
#rail-toggle[aria-expanded="true"] svg { transform: scaleX(-1); } /* the chevron points at the body it closes */
#rail-tabs { flex: 1 1 auto; min-height: 0; width: 100%; display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 6px 0 8px; }
.rail-tab {
  width: 100%; height: 36px; display: grid; place-items: center; padding: 0 2px 0 0;
  border: 0; border-left: 2px solid transparent; background: transparent; color: var(--tool-ink-off); cursor: pointer;
  transition: color .15s ease;
}
.rail-tab[aria-pressed="true"] { border-left-color: var(--tool-line); color: var(--tool-ink); }
.rail-tab[hidden] { display: none; } /* license-gated tabs must override the rail's grid display */
.rail-tab:hover, .rail-tab:focus-visible { color: var(--tool-ink); outline: none; }
.rail-foot { margin-top: auto; }
/* Settings owns the bottom gap only while the Debug entry above it is hidden. */
.rail-foot:not([hidden]) + .rail-foot { margin-top: 0; }
.rail-svg { width: var(--tool-icon); height: var(--tool-icon); }
/* Create and Paint show the current item and material rather than a glyph: a framed tile and a swatch. */
.rail-current { width: 26px; height: 26px; display: grid; place-items: center; border: 1px solid var(--line); border-radius: 6px; background: var(--panel-2); }
.rail-current svg { display: block; }
.rail-swatch { width: 22px; height: 22px; border-radius: 50%; }
#panel {
  height: 100%; min-width: 220px; display: flex; flex-direction: column;
  background: var(--panel); border-left: 1px solid var(--line);
}
#panel[hidden], #divider-c[hidden] { display: none; }
#panel-header {
  flex: 0 0 var(--toolbar-h); display: flex; align-items: center; gap: 8px; padding: 0 18px;
  border-bottom: 1px solid var(--line); font-weight: 600; font-size: 14px; letter-spacing: .01em;
}
.tab-body { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; overflow: hidden auto; }
#panel .tab-body[hidden] { display: none; } /* outranks #debug-body's own display */
.subtabs { flex: 0 0 auto; display: flex; padding: 0 12px; border-bottom: 1px solid var(--line); }
.subtab {
  flex: 1 1 0; min-width: 0; height: 40px; display: grid; place-items: center; padding: 0; margin-bottom: -1px;
  border: 0; border-bottom: 2px solid transparent; background: transparent; color: var(--muted); cursor: pointer; transition: color .15s ease;
}
.subtab-svg { width: var(--tool-icon); height: var(--tool-icon); }
.subtab:hover, .subtab:focus-visible { color: var(--ink); outline: none; }
.subtab[aria-selected="true"] { color: var(--ink); border-bottom-color: var(--tool-line); }
.drawer-heading { margin: 14px 18px 0; font-size: 11.5px; font-weight: 600; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); }
/* The Create drawer (library.js): search, the heading row, and tiles that refill as the panel is resized. */
.drawer { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; gap: 12px; padding: 12px 18px 16px; }
.drawer-search { display: flex; align-items: center; gap: 8px; height: 32px; padding: 0 10px; border: 1px solid var(--line); border-radius: 8px; background: var(--bg); color: var(--muted); }
.drawer-search svg { flex: 0 0 auto; width: 14px; height: 14px; }
.drawer-search input { flex: 1 1 auto; min-width: 0; border: 0; padding: 0; background: transparent; color: var(--ink); font: inherit; font-size: 12.5px; outline: none; }
.drawer-search input::placeholder { color: var(--muted); }
.drawer-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 24px; }
.drawer-head .drawer-heading { margin: 0; }
.drawer-count { font-size: 11.5px; color: var(--muted); }
.tile-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); gap: 12px 8px; }
.tile {
  display: flex; flex-direction: column; align-items: center; gap: 5px; min-width: 0; padding: 0; border: 0; background: transparent;
  color: var(--muted); font: inherit; font-size: 11.5px; line-height: 1.3; cursor: pointer;
}
.tile-thumb { width: 84px; height: 84px; display: grid; place-items: center; border-radius: 10px; background: var(--panel-2); transition: background .15s ease; }
.tile-thumb svg { display: block; overflow: visible; }
.tile:hover .tile-thumb, .tile:focus-visible .tile-thumb { background: color-mix(in srgb, var(--muted) 18%, var(--panel-2)); }
.tile:focus-visible { outline: none; }
.tile[aria-selected="true"] { color: var(--ink); font-weight: 600; }
.tile[aria-selected="true"] .tile-thumb { background: var(--accent-soft); box-shadow: inset 0 0 0 1px var(--accent-text); }
.tile-name { max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tile-id { max-width: 100%; font: 10px/1.35 ui-monospace, Consolas, monospace; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* debug: source and id */
.drawer-empty { margin: 24px 0; text-align: center; font-size: 12.5px; color: var(--muted); }
/* Colours are discs, Arkio's own convention, six to a row; selected takes the accent ring with a gap of panel colour so it
   holds on dark colours. Materials keep the tile. The rail's Paint entry is a disc too, so it never reads as a primitive. */
.tile-grid.swatch-grid { grid-template-columns: repeat(auto-fill, 32px); justify-content: space-between; gap: 10px; }
.swatch { width: 32px; height: 32px; padding: 0; border: 0; border-radius: 50%; cursor: pointer; box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .14); transition: transform .12s ease, box-shadow .12s ease; }
.swatch:hover, .swatch:focus-visible { transform: scale(1.12); outline: none; }
.swatch[aria-selected="true"] { box-shadow: 0 0 0 2px var(--panel), 0 0 0 4px var(--accent); }
.disc { display: block; border-radius: 50%; box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .14); }
.rail-swatch { overflow: hidden; background: none; box-shadow: none; }
.rail-swatch .disc, .rail-swatch img { width: 22px; height: 22px; display: block; border-radius: 50%; }
.rail-swatch img { box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .14); }
#debug-body { flex: 1 1 auto; overflow-y: auto; padding: 16px 18px; display: flex; flex-direction: column; gap: 4px; }
/* Native details own folding and keyboard access. Scope the arrow to category headers so nested diagnostics
   retain their own disclosure markers; expanding a category never changes the settings it contains. */
.debug-section { flex: 0 0 auto; }
.debug-section[open] { padding-bottom: 12px; }
.debug-section > summary {
  display: flex; align-items: center; gap: 10px; padding: 10px 0; list-style: none; cursor: pointer; color: var(--muted);
}
.debug-section > summary::-webkit-details-marker { display: none; }
.debug-section > summary::before {
  content: ''; flex: 0 0 auto; width: 6px; height: 6px; margin: 0 2px;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(-45deg);
}
.debug-section[open] > summary::before { transform: rotate(45deg); }
.debug-section > summary:hover { color: var(--ink); }
.debug-section > summary:focus-visible { outline: 2px solid var(--accent-text); outline-offset: 2px; border-radius: 3px; }
.debug-section > summary > h2 {
  margin: 0; font-size: 11.5px; font-weight: 600; letter-spacing: .07em; text-transform: uppercase; color: inherit;
}
/* Big tabular figures so a changing fps does not make the row jitter, with the unit underneath in the muted ink. */
.debug-stats { display: flex; flex-wrap: wrap; gap: 10px 22px; } .debug-mem { margin-top: 14px; }
.debug-stat { display: flex; flex-direction: column; min-width: 64px; }
.debug-stat-value { font-size: 26px; font-weight: 600; line-height: 1.15; color: var(--ink); font-variant-numeric: tabular-nums; }
.debug-stat-label { font-size: 11.5px; color: var(--muted); white-space: nowrap; }
/* Frame-time graph: one point per frame, newest at the right, 60 and 30 fps guide lines (drawn by app.js). The CSS
   height is the whole size contract; app.js sizes the backing store from it at devicePixelRatio. */
#debug-frame-graph {
  display: block; width: 100%; height: 64px; margin-top: 12px;
  border: 1px solid var(--line); border-radius: 8px; background: var(--bg);
}
.debug-note { margin-top: 8px; font-size: 12px; line-height: 1.4; color: var(--muted); }
/* Commands keep a usable input in the narrow drawer; long replies wrap inside a bounded, scrollable transcript. */
.debug-console-entry { display: flex; gap: 8px; margin-top: 6px; }
#debug-console-input {
  flex: 1; min-width: 0; width: 0; padding: 7px 8px; border: 1px solid var(--line); border-radius: 7px;
  background: var(--bg); color: var(--ink); font: 12px/1.4 ui-monospace, Consolas, monospace;
}
#debug-console-input:focus { outline: none; border-color: var(--accent-text); }
#debug-console-output {
  max-height: 200px; overflow: auto; white-space: pre-wrap; overflow-wrap: anywhere; padding: 8px;
  border: 1px solid var(--line); border-radius: 7px; background: var(--bg); color: var(--ink);
  font: 12px/1.4 ui-monospace, Consolas, monospace;
}
#debug-console-clear { margin-top: 8px; }
/* Raw logging config stays readable in the narrow developer drawer and can grow vertically. */
#debug-log-config-text {
  display: block; width: 100%; box-sizing: border-box; resize: vertical; margin-top: 6px; padding: 8px;
  border: 1px solid var(--line); border-radius: 7px; background: var(--bg); color: var(--ink);
  font: 12px/1.4 ui-monospace, Consolas, monospace;
}
#debug-log-config-text:focus { outline: none; border-color: var(--accent-text); }
#debug-log-config-save { margin-top: 8px; }
/* Move gizmo switches (app.js "move gizmo experiments"): one labelled control per row, label left and control right;
   ranges carry their value beside them and the selects borrow the options-row look. */
.debug-intro { margin: 0 0 4px; }
.debug-field { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 8px; font-size: 12.5px; color: var(--ink); }
.debug-field:not(.debug-check) { white-space: nowrap; } /* "Ring radius" stays on one line; the slider gives way instead */
/* File categories can be long; keep the diagnostic values aligned without widening the drawer. */
.storage-report .debug-field { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: start; white-space: normal; }
.storage-report .debug-field > :last-child { text-align: right; font-variant-numeric: tabular-nums; }
.debug-field select {
  font: inherit; font-size: 12.5px; padding: 4px 8px; border: 1px solid var(--line); border-radius: 7px;
  background: var(--bg); color: var(--ink); cursor: pointer;
}
.debug-field select:focus { outline: none; border-color: var(--accent-text); }
.debug-range { display: flex; align-items: center; gap: 8px; flex: 0 1 60%; }
.debug-range input[type=range] { flex: 1 1 auto; min-width: 0; accent-color: var(--range-accent); margin: 0; }
.debug-value { min-width: 3.2em; text-align: right; font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
/* Give fine budget adjustments the drawer's full width, including at its narrowest size. */
#debug-hlod-budgets .debug-field { display: block; }
#debug-hlod-budgets .debug-range { margin-top: 4px; }
#debug-hlod-budgets .debug-value { min-width: 5.5em; }
.debug-check { justify-content: flex-start; gap: 8px; cursor: pointer; }
.debug-check input[type=checkbox] { accent-color: var(--accent); margin: 0; }

/* ---- scene header (the player's toolbar) and body ---- */
/* The scene pane is a column: its header, then #scene-body with everything else. The header is the player's toolbar,
   standing in for Arkio's VRLess toolbar that the Web build hides: undo/redo left, the palette centred over the player,
   the scene's switches right. Its look is set once in the :root toolbar variables. The palette is centred by absolute
   positioning and falls back into the row on a narrow pane, where centring would run it into the actions. #scene-body
   is the box the overlays (#session-state, #loading, #render-viewer) cover and the live divider splits. */
#scene { display: flex; flex-direction: column; }
#scene-header {
  flex: 0 0 var(--toolbar-h); position: relative; container-type: inline-size;
  display: flex; align-items: center; gap: 8px; padding: 0 12px;
  border-bottom: 1px solid var(--line); background: var(--panel); color: var(--ink);
}
.tool-group { display: flex; align-items: stretch; gap: 2px; }
/* bottom -1px: the group reaches over the header's hairline, so the active tool's 2px line covers it. */
#tools { position: absolute; left: 50%; top: 0; bottom: -1px; transform: translateX(-50%); }
@container (max-width: 900px) {
  #tools { position: static; transform: none; align-self: stretch; margin: 0 auto -1px; }
  #scene-actions { margin-left: 0; }
}
/* A tool is a plain glyph on the header, as tall as the header so the active line lies on its bottom edge. Clicking the
   active tool deselects it, as in Arkio. */
.tool {
  width: var(--tool-w); height: 100%; display: grid; place-items: center; padding: 0;
  border: 0; border-bottom: 2px solid transparent; background: transparent; color: var(--tool-ink); cursor: pointer;
  transition: color .15s ease;
}
.tool[aria-pressed="true"] { border-bottom-color: var(--tool-line); }
.tool:hover:not(:disabled), .tool:focus-visible { color: var(--accent-text); outline: none; }
.tool:disabled { color: var(--tool-ink-off); cursor: default; }
#history .tool { height: 30px; border-bottom: 0; border-radius: 6px; }
/* Navigate (Orbit, Walk) stands beside history behind a hairline. Like #tools it reaches over the header's hairline so
   its active line lies on the header's bottom edge; being in the row rather than centred, it stretches itself. */
.tool-sep { flex: 0 0 1px; width: 1px; height: 20px; background: var(--line); }
#navigate { align-self: stretch; margin-bottom: -1px; }
/* The palette's glyphs are inline SVG (index.html), sized here; the rail and sub-tab glyphs share the size. */
.tool-svg { width: var(--tool-icon); height: var(--tool-icon); }
/* Follow agent and Live render: the scene's two switches, flipped all day, so on and off must read at a glance. On is
   the .header-btn pressed look at this size; the filled accent stays reserved for Send. aria-pressed drives it. */
.mode-toggle {
  height: 30px; padding: 0 12px; border: 1px solid var(--line); border-radius: 7px; background: transparent;
  color: var(--ink); font: inherit; font-size: 12.5px; font-weight: 600; white-space: nowrap; cursor: pointer;
  transition: border-color .15s ease, background .15s ease, color .15s ease;
}
.mode-toggle:hover:not(:disabled), .mode-toggle:focus-visible { border-color: var(--accent-text); outline: none; }
.mode-toggle:disabled { opacity: .5; cursor: default; }
.mode-toggle[aria-pressed="true"] { border-color: var(--accent-text); background: var(--accent-soft); color: var(--accent-text); }
#scene-actions { margin-left: auto; display: flex; gap: 6px; }
#scene-body { position: relative; flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; overflow: hidden; background: #000; }

/* ---- live video (the scene body split: player above, divider, live AI video below) ---- */
/* #scene-body is a column so #scene-view (top) and #live-pane (bottom) share its height; #session-state, #loading
   and #render-viewer are absolutely positioned against it and keep covering both parts. #scene-view is the player's
   box: syncRenderTarget and legacy player-space tutorial pointers measure it, and #unity-canvas fills it. */
#scene-view { position: relative; flex: 1 1 auto; min-height: 0; width: 100%; overflow: hidden; background: #000; }
/* Same chrome as the debug pane (panel surface, hairline header, a status dot); both it and its divider are display:none
   while hidden, so the scene pane sees only the player again. The dot: muted off, amber while connecting/paused,
   accent while streaming, red when stopped by an error. */
#live-pane { width: 100%; min-height: 0; display: flex; flex-direction: column; background: var(--panel); border-top: 1px solid var(--line); }
#live-pane[hidden], #divider-live[hidden] { display: none; }
#live-header { display: flex; flex-direction: column; gap: 8px; padding: 12px 14px; border-bottom: 1px solid var(--line); }
#live-title-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-weight: 600; font-size: 14px; letter-spacing: .01em; }
#live-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--muted); flex: 0 0 auto; }
#live-dot[data-state="live"] { background: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent); }
#live-dot[data-state="busy"] { background: var(--amber); }
#live-dot[data-state="error"] { background: var(--danger); }
#live-state { flex: 1 1 auto; min-width: 0; font-weight: 400; font-size: 12.5px; color: var(--muted); }
#live-action, #live-orient {
  flex: 0 0 auto; padding: 5px 10px; border: 1px solid var(--line); border-radius: 7px; background: var(--panel-2);
  color: var(--ink); font: inherit; font-size: 12px; font-weight: 600; cursor: pointer; transition: border-color .15s ease;
}
#live-action:hover, #live-action:focus-visible, #live-orient:hover, #live-orient:focus-visible { border-color: var(--accent-text); outline: none; }
#live-action[hidden], #live-orient[hidden], #live-note[hidden] { display: none; }
/* Two tiles of the .debug-stat family (Cost, Lag), a touch smaller than the debug pane's, then one muted metrics line. */
.live-tiles .debug-stat-value { font-size: 22px; }
.live-metrics { font-size: 12px; line-height: 1.4; color: var(--muted); }
.live-metrics:empty { display: none; }
/* The stream, letterboxed: Lucy returns 1280x720 or 720x1280 whatever the pane's shape. The still (the last frame,
   snapshotted at disconnect) sits over it until the next remote frame arrives. */
#live-stage { position: relative; flex: 1 1 auto; min-height: 0; background: #000; }
#live-out, #live-still { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; display: block; background: #000; }
#live-out[hidden], #live-still[hidden] { display: none; }
#live-capture { position: fixed; left: -20000px; top: 0; width: 8px; height: 8px; pointer-events: none; }
/* The prompt row under the composer: one line (label, text, Apply, Send as typed), the editable prompt in effect, and a
   status/counter foot. Same surface as the composer so it reads as part of it. */
#live-prompt-row { display: flex; flex-direction: column; gap: 6px; padding: 10px 14px 12px; border-top: 1px solid var(--line); background: var(--panel-2); }
#live-prompt-row[hidden] { display: none; }
#live-prompt-line { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 12.5px; color: var(--muted); }
.live-prompt-label { letter-spacing: .02em; white-space: nowrap; }
#live-prompt {
  flex: 1 1 160px; min-width: 120px; padding: 6px 10px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--bg); color: var(--ink); font: inherit; font-size: 13px;
}
#live-prompt:focus { outline: none; border-color: var(--accent-text); }
#live-prompt::placeholder { color: var(--muted); }
#live-prompt-apply {
  padding: 5px 10px; border: 1px solid var(--line); border-radius: 7px; background: var(--panel); color: var(--ink);
  font: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer; transition: border-color .15s ease;
}
#live-prompt-apply:hover, #live-prompt-apply:focus-visible { border-color: var(--accent-text); outline: none; }
.live-prompt-raw { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; cursor: pointer; }
.live-prompt-raw input { accent-color: var(--accent); margin: 0; }
#live-prompt-enhanced {
  width: 100%; resize: vertical; min-height: 44px; max-height: 160px; padding: 6px 10px; border: 1px solid var(--line);
  border-radius: 8px; background: var(--bg); color: var(--ink); font: inherit; font-size: 12.5px; line-height: 1.4;
}
#live-prompt-enhanced:focus { outline: none; border-color: var(--accent-text); }
#live-prompt-foot { display: flex; justify-content: space-between; gap: 10px; font-size: 11.5px; color: var(--muted); }

/* Live render shares the player split with video, while keeping still-image status and output separate. Its header is
   the pane-header family in two rows (index.html): the title row with the status dot, the run's current state, the
   interval slider and Start/Stop, then one muted info line. Padding is a touch tighter than the chat and debug headers
   because the image below is what the pane is for. The dot: muted stopped, amber while the agent writes the prompt,
   accent while running, red when a failure stopped the run. */
#live-render-pane { width: 100%; min-height: 0; display: flex; flex-direction: column; background: var(--panel); border-top: 1px solid var(--line); }
#live-render-pane[hidden] { display: none; }
.live-render-header { display: flex; flex-direction: column; gap: 5px; padding: 9px 14px 8px; border-bottom: 1px solid var(--line); }
.live-render-title { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; font-weight: 600; font-size: 14px; letter-spacing: .01em; }
#live-render-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--muted); flex: 0 0 auto; }
#live-render-dot[data-state="live"] { background: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent); }
#live-render-dot[data-state="busy"] { background: var(--amber); }
#live-render-dot[data-state="error"] { background: var(--danger); }
#live-render-state { flex: 1 1 auto; min-width: 0; font-weight: 400; font-size: 12.5px; color: var(--muted); }
.live-render-interval { display: inline-flex; align-items: center; gap: 6px; font-weight: 400; font-size: 11.5px; color: var(--muted); white-space: nowrap; cursor: pointer; }
.live-render-interval input[type=range] { width: 88px; margin: 0; accent-color: var(--range-accent); }
#live-render-interval-value { min-width: 2.6em; text-align: right; font-variant-numeric: tabular-nums; }
.live-render-info { display: flex; flex-wrap: wrap; gap: 2px 14px; font-size: 12px; line-height: 1.4; color: var(--muted); }
.live-render-info b { font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; }
.live-render-info span:empty { display: none; }
.live-render-note { font-size: 12px; line-height: 1.4; color: var(--danger); }
.live-render-note:empty { display: none; }
.live-render-stage { flex: 1; position: relative; min-height: 0; display: grid; place-items: center; background: var(--bg); color: var(--muted); font-size: 13px; }
#live-render-image { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
#live-render-image[hidden], #live-render-empty[hidden] { display: none; }
#live-render-prompt { width: 100%; background: var(--bg); color: var(--ink); border: 1px solid var(--line); border-radius: 6px; padding: 6px; font: inherit; }
.live-render-details { margin-top: 10px; font-size: 12px; line-height: 1.5; }
.live-render-details summary { cursor: pointer; }
#live-render-prompt { resize: vertical; }
#live-render-source-link { display: block; }
#live-render-source-link[hidden] { display: none; }
#live-render-source-image { display: block; width: 100%; height: auto; border: 1px solid var(--line); border-radius: 6px; }

/* ---- floating Live render (the pane as a window over the player) ---- */
/* data-mode="floating" lifts the pane out of the split: absolutely positioned in #scene-body (live-float.js sets left,
   top, width and height), under the overlays that must keep covering it (#loading z 2, #session-state z 4, the viewer
   z 5). The header collapses to one row - dot, state, Start/Stop, dock - and is the drag handle; the four corners
   resize with the aspect locked. The icon buttons are .header-btn at a square size. */
.header-btn.icon-btn { width: 28px; padding: 0; display: inline-grid; place-items: center; align-self: stretch; }
.header-btn.icon-btn svg { width: 15px; height: 15px; }
#live-render-pane[data-mode="floating"] {
  position: absolute; z-index: 1; width: auto; border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 14px 40px rgba(0, 0, 0, .45); overflow: hidden; touch-action: none; cursor: grab; /* the whole window drags */
}
#live-render-pane[data-mode="floating"] .live-render-header { gap: 2px; padding: 6px 12px 5px; user-select: none; -webkit-user-select: none; }
#live-render-pane.dragging, #live-render-pane.dragging * { cursor: grabbing; }
#live-render-pane[data-mode="floating"] .live-render-title { flex-wrap: nowrap; }
#live-render-pane[data-mode="floating"] .header-btn { line-height: 1.25; padding-top: 4px; padding-bottom: 4px; }
#live-render-once[hidden] { display: none; } /* a stream running shows Stop alone */
#live-render-pane[data-mode="floating"] #live-render-title, #live-render-pane[data-mode="floating"] .live-render-interval,
#live-render-pane[data-mode="floating"] .live-render-info, #live-render-pane[data-mode="floating"] #live-render-float { display: none; }
#live-render-pane[data-mode="floating"] #live-render-state { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--ink); font-weight: 500; }
#live-render-pane[data-mode="floating"] .live-render-stage { background: #000; }
#live-render-pane[data-mode="floating"] #live-render-image { pointer-events: none; }
#live-render-pane:not([data-mode="floating"]) #live-render-dock, #live-render-pane:not([data-mode="floating"]) .live-render-corner { display: none; }
/* Resize handles: the bottom corners are 22px squares (nothing else lives there); the top corners are an L along the
   two edges, kept inside the header's padding so the dot and the buttons stay clickable. Each corner shows a tick:
   the lower right always, all four while the pointer is over the window or a gesture is under way. */
.live-render-corner { position: absolute; width: 22px; height: 22px; z-index: 2; }
.live-render-corner[data-corner="nw"] { left: 0; top: 0; cursor: nwse-resize; clip-path: polygon(0 0, 100% 0, 100% 6px, 11px 6px, 11px 100%, 0 100%); }
.live-render-corner[data-corner="ne"] { right: 0; top: 0; cursor: nesw-resize; clip-path: polygon(0 0, 100% 0, 100% 100%, 11px 100%, 11px 6px, 0 6px); }
.live-render-corner[data-corner="sw"] { left: 0; bottom: 0; cursor: nesw-resize; }
.live-render-corner[data-corner="se"] { right: 0; bottom: 0; cursor: nwse-resize; }
.live-render-corner::after { content: ""; position: absolute; width: 8px; height: 8px; border: 0 solid var(--muted); opacity: 0; transition: opacity .15s ease; }
.live-render-corner[data-corner="nw"]::after { left: 4px; top: 4px; border-width: 2px 0 0 2px; }
.live-render-corner[data-corner="ne"]::after { right: 4px; top: 4px; border-width: 2px 2px 0 0; }
.live-render-corner[data-corner="sw"]::after { left: 4px; bottom: 4px; border-width: 0 0 2px 2px; border-color: rgba(255, 255, 255, .75); filter: drop-shadow(0 0 1px rgba(0, 0, 0, .6)); }
.live-render-corner[data-corner="se"]::after { right: 4px; bottom: 4px; border-width: 0 2px 2px 0; border-color: rgba(255, 255, 255, .75); filter: drop-shadow(0 0 1px rgba(0, 0, 0, .6)); opacity: 1; }
#live-render-pane[data-mode="floating"]:hover .live-render-corner::after, #live-render-pane.resizing .live-render-corner::after,
#live-render-pane.dragging .live-render-corner::after { opacity: 1; }

/* ---- virtual joysticks over the player (joysticks.js) ---- */
/* Move at the lower left and Look at the lower right of the player, above the floating Live render window (z 1) and
   under #loading and #session-state. They keep their own inks, white on a dark fill, since the player behind them is dark
   whatever the shell theme, and take no accent. Shown whatever the input device, unless the Settings page's Joysticks
   option hides them (data-joysticks="off" on <body>). A phone gets the larger size. The thumb springs back over 120ms on release
   and follows the finger without a transition while held. */
#joysticks { position: absolute; inset: 0; z-index: 2; display: block; pointer-events: none; --stick: 96px; --thumb: 36px; --stick-inset-x: 20px; --stick-inset-y: 28px; }
@media (pointer: coarse) and (max-width: 640px) { #joysticks { --stick: 120px; --thumb: 44px; } }
body[data-joysticks="off"] #joysticks { display: none; }
.stick { position: absolute; bottom: var(--stick-inset-y); width: var(--stick); height: var(--stick); pointer-events: auto; touch-action: none; user-select: none; -webkit-user-select: none; cursor: grab; }
.stick[data-name="move"] { left: var(--stick-inset-x); }
.stick[data-name="look"] { right: var(--stick-inset-x); }
.stick[data-active="true"] { cursor: grabbing; }
.stick-ring { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.stick-base { fill: rgba(14, 26, 25, .42); stroke: rgba(255, 255, 255, .28); stroke-width: 1; transition: stroke .15s ease, stroke-width .15s ease; }
.stick[data-active="true"] .stick-base { stroke: rgba(255, 255, 255, .6); stroke-width: 1.5; }
.stick-marks, .stick-horizon { fill: none; stroke: rgba(255, 255, 255, .5); stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.stick-horizon { stroke: rgba(255, 255, 255, .28); stroke-width: 1.5; stroke-dasharray: 3 4; }
/* pathLength 100 makes the dash array a percentage: --sprint is the ramp's progress, 0..100, set by joysticks.js. */
.stick-progress { fill: none; stroke: rgba(255, 255, 255, .85); stroke-width: 3; stroke-linecap: round; stroke-dasharray: var(--sprint, 0) 100; transform: rotate(-90deg); transform-origin: 50% 50%; opacity: 0; transition: opacity .15s ease; }
.stick[data-sprint="true"] .stick-progress { opacity: 1; }
.stick-thumb { position: absolute; left: 50%; top: 50%; width: var(--thumb); height: var(--thumb); margin: calc(var(--thumb) / -2) 0 0 calc(var(--thumb) / -2); box-sizing: border-box; border-radius: 50%; background: rgba(232, 238, 236, .94); box-shadow: 0 1px 2px rgba(0, 0, 0, .18); transform: translate(var(--tx, 0px), var(--ty, 0px)); transition: transform .12s ease; }
.stick[data-active="true"] .stick-thumb { transition: none; } /* follows the finger; the spring-back is for the release */
#joysticks[data-unavailable="true"] .stick { opacity: .4; }

/* ---- dimension numpad (numpad.js): a floating window over the player ---- */
/* The Live render window's family - hairline, 10px radius, the same shadow, the header as the drag handle - at a fixed
   236px with no corners; live-float.js places it (its fixed-size mode). Above the sticks (z 2), under #session-state
   (z 4); #loading never shows while it is open. The seeded value is highlighted until the first key replaces it. */
.numpad { position: absolute; z-index: 3; width: 236px; display: flex; flex-direction: column; background: var(--panel); border: 1px solid var(--line); border-radius: 10px; box-shadow: 0 14px 40px rgba(0, 0, 0, .45); overflow: hidden; color: var(--ink); touch-action: none; outline: none; }
.numpad[hidden] { display: none; }
.numpad.dragging, .numpad.dragging * { cursor: grabbing; }
.numpad-header { display: flex; align-items: center; gap: 8px; padding: 8px 8px 8px 12px; border-bottom: 1px solid var(--line); cursor: grab; user-select: none; -webkit-user-select: none; }
.numpad-titles { display: flex; flex-direction: column; gap: 1px; flex: 1 1 auto; min-width: 0; }
.numpad-title { font-size: 12.5px; font-weight: 600; letter-spacing: .01em; line-height: 1.3; }
.numpad-subtitle { font-size: 11px; line-height: 1.3; color: var(--muted); }
.numpad-subtitle:empty { display: none; }
.numpad-value { display: flex; align-items: baseline; justify-content: flex-end; gap: 6px; padding: 14px 14px 4px; font-variant-numeric: tabular-nums; }
#numpad-text { font-size: 28px; font-weight: 600; line-height: 1; padding: 2px 4px; border-radius: 4px; }
#numpad-text[data-fresh="true"] { background: color-mix(in srgb, var(--accent) 18%, transparent); }
.numpad-unit { font-size: 13px; color: var(--muted); }
.numpad-status { min-height: 16px; padding: 0 14px 6px; text-align: right; font-size: 11px; line-height: 1.4; color: var(--danger); }
.numpad-keys { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; padding: 4px 12px 8px; }
.numpad-key { height: 40px; display: grid; place-items: center; padding: 0; border: 1px solid var(--line); border-radius: 7px; background: var(--panel-2); color: var(--ink); font: inherit; font-size: 15px; font-weight: 600; cursor: pointer; transition: border-color .15s ease, background .15s ease; }
.numpad-key svg { width: 18px; height: 18px; }
.numpad-key:hover, .numpad-key:focus-visible { border-color: var(--accent-text); outline: none; }
.numpad-key:active { background: color-mix(in srgb, var(--accent) 18%, var(--panel-2)); }
.numpad-actions { display: flex; gap: 6px; padding: 0 12px 12px; }
.numpad-reset { flex: 1 1 0; height: 30px; padding: 0; border-radius: 7px; font-size: 12.5px; font-weight: 600; }
.numpad-apply { flex: 1.5 1 0; height: 30px; display: inline-flex; align-items: center; justify-content: center; gap: 6px; border: 0; border-radius: 7px; background: var(--accent); color: var(--accent-ink); font: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer; }
.numpad-apply svg { width: 14px; height: 14px; }
.numpad-apply:hover, .numpad-apply:focus-visible { background: var(--accent-hover); outline: none; }

/* ---- API cost: development accounting, shown only while Show API cost is on in the debug panel (app.js) ---- */
/* The usage line under the chat header, each turn's usage and the Live render and video rows (.usage), and the Live
   render pane's figures. The switch adds or removes body.costs-hidden; nothing else needs to know. */
body.costs-hidden #chat-metrics, body.costs-hidden .usage, body.costs-hidden .live-render-info { display: none; }

/* ---- Review drawer (review.js): Views, Layers, BIM data ---- */
/* Rows are the sessions column's: 6px radius, hover grey; every Views row leads with the same 44x28 slot (a still, a
   note's colour card, a frame's card) so the three kinds' names line up. The chips take the header buttons' corners. */
.rv-tab { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.rv-tab[hidden] { display: none; }
.rv-tab .drawer { gap: 10px; }
.rv-tab .drawer[hidden] { display: none; }
.rv-list { flex: 1 1 auto; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; margin: 0 -8px; padding: 0 8px; }
.rv-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 24px; flex: 0 0 auto; }
.rv-list .rv-head { padding: 6px 8px 2px; }
.rv-heading { font-size: 11.5px; font-weight: 600; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); white-space: nowrap; }
.rv-count, .rv-meta { font-size: 11px; color: var(--muted); white-space: nowrap; }
.rv-head-actions { display: flex; gap: 6px; }
.rv-head-actions .header-btn { height: 24px; padding: 0 8px; }
.rv-strip { display: flex; gap: 2px; padding: 2px; border: 1px solid var(--line); border-radius: 7px; background: var(--panel-2); flex: 0 0 auto; }
.rv-strip button { flex: 1 1 0; padding: 4px 0; border: 0; border-radius: 5px; background: transparent; color: var(--ink); font: inherit; font-size: 11.5px; line-height: 1.5; cursor: pointer; }
.rv-strip button:hover { background: var(--panel); }
.rv-row { display: flex; align-items: center; gap: 8px; min-height: 36px; padding: 0 6px 0 8px; border-radius: 6px; cursor: pointer; }
.rv-row:hover, .rv-row.menu-open { background: var(--active-item, rgba(127, 127, 127, .14)); }
.rv-view { min-height: 40px; }
.rv-name { flex: 1 1 auto; min-width: 0; font-size: 12.5px; line-height: 1.3; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rv-name.strong { font-weight: 600; }
.rv-name.muted { color: var(--muted); }
.rv-still { flex: 0 0 auto; width: 44px; height: 28px; border-radius: 4px; object-fit: cover; display: block; box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .10); }
.rv-still-empty, .rv-card { flex: 0 0 auto; width: 44px; height: 28px; display: grid; place-items: center; border-radius: 4px; background: var(--panel-2); color: var(--muted); box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .08); }
.rv-act, .rv-eye, .rv-caret { flex: 0 0 auto; width: 24px; height: 24px; display: grid; place-items: center; padding: 0; border: 0; border-radius: 5px; background: transparent; color: var(--muted); cursor: pointer; }
.rv-act:hover, .rv-eye:hover:not(:disabled), .rv-caret:hover { color: var(--ink); background: var(--panel-2); }
/* the ⋮ is always there, faint, so touch has it; a hovered row and its menu bring it up */
.rv-more { color: var(--line); }
.rv-row:hover .rv-more, .rv-row.menu-open .rv-more, .rv-more:focus-visible { color: var(--ink); }
.rv-update { display: none; }
.rv-row:hover .rv-update, .rv-update:focus-visible { display: grid; }
.rv-rename { flex: 1 1 auto; min-width: 0; height: 26px; padding: 0 6px; border: 1px solid var(--accent-text); border-radius: 5px; background: var(--panel); color: var(--ink); font: inherit; font-size: 12.5px; outline: none; }
.rv-foot { flex: 0 0 auto; display: flex; flex-direction: column; gap: 6px; padding-top: 4px; }
.rv-wide { display: flex; align-items: center; justify-content: center; gap: 6px; height: 32px; border: 1px solid var(--line); border-radius: 8px; background: transparent; color: var(--ink); font: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer; }
.rv-wide:hover:not(:disabled) { border-color: var(--accent-text); }
.rv-wide:disabled { color: var(--muted); opacity: .6; cursor: default; }
.rv-status { margin: 0; font-size: 11.5px; color: var(--muted); text-align: center; }
.rv-status.failed { color: var(--danger); }
#rv-menu { position: fixed; z-index: 60; min-width: 180px; padding: 4px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel); box-shadow: 0 10px 30px rgba(0, 0, 0, .14); }
#rv-menu[hidden] { display: none; }
/* Layers */
.rv-layer, .rv-model { min-height: 32px; padding-right: 4px; }
.rv-layer.child { padding-left: 26px; }
.rv-layer.disabled .rv-name { color: var(--muted); }
.rv-indent { flex: 0 0 16px; }
.rv-caret { width: 16px; height: 16px; }
.rv-caret svg { transition: transform .12s ease; }
.rv-caret[aria-expanded="false"] svg { transform: rotate(-90deg); }
.rv-badge { flex: 0 0 auto; padding: 1px 5px; border: 1px solid var(--line); border-radius: 4px; background: var(--panel-2); font-size: 10px; font-weight: 600; letter-spacing: .04em; color: var(--muted); }
.rv-eye[aria-pressed="true"] { color: var(--ink); }
.rv-eye.mixed { opacity: .5; }
.rv-eye:disabled { opacity: .5; cursor: default; }
.rv-solo { display: none; flex: 0 0 auto; height: 24px; padding: 0 8px; border: 1px solid var(--line); border-radius: 5px; background: transparent; color: var(--ink); font: inherit; font-size: 11.5px; line-height: 1; cursor: pointer; }
.rv-row:hover .rv-solo, .rv-solo:focus-visible { display: inline-flex; align-items: center; }
/* BIM data */
.rv-select { height: 24px; padding: 0 8px; display: inline-flex; align-items: center; gap: 5px; }
.rv-select svg { width: 13px; height: 13px; }
.rv-element { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel-2); flex: 0 0 auto; }
.rv-element[hidden], .rv-sheet[hidden], .rv-bim-empty[hidden], .rv-bim .drawer-search[hidden] { display: none; }
.rv-element-glyph { flex: 0 0 auto; width: 36px; height: 36px; display: grid; place-items: center; border-radius: 7px; background: var(--panel); box-shadow: inset 0 0 0 1px var(--line); color: var(--ink); }
.rv-element-text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.rv-element-name { font-size: 13px; font-weight: 600; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rv-element-sub { font-size: 11.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rv-element-model { display: flex; align-items: center; gap: 6px; font-size: 11px; color: var(--muted); white-space: nowrap; overflow: hidden; }
.rv-element-model > span:last-child { overflow: hidden; text-overflow: ellipsis; }
.rv-sheet { flex: 1 1 auto; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: 6px; margin: 0 -8px; padding: 0 8px; }
.rv-group { display: flex; flex-direction: column; gap: 1px; flex: 0 0 auto; }
.rv-group-head { display: flex; align-items: center; gap: 6px; height: 28px; }
.rv-prop { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr) 20px; align-items: center; gap: 8px; min-height: 26px; padding: 0 4px 0 8px; border-radius: 5px; cursor: copy; }
.rv-prop:hover { background: var(--active-item, rgba(127, 127, 127, .14)); }
.rv-key { font-size: 12px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rv-val { font-size: 12.5px; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-variant-numeric: tabular-nums; }
.rv-copy { display: none; color: var(--muted); }
.rv-prop:hover .rv-copy { display: grid; place-items: center; }
.rv-prop.copied .rv-val { color: var(--accent-text); }
/* the empty and locked states, the same anatomy */
.rv-bim-empty, .rv-locked { flex: 1 1 auto; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; padding: 12px 32px 40px; text-align: center; }
.rv-locked[hidden] { display: none; }
.rv-empty-glyph { width: 44px; height: 44px; display: grid; place-items: center; border-radius: 12px; background: var(--panel-2); color: var(--muted); }
.rv-empty-glyph svg { width: 22px; height: 22px; }
.rv-empty-title { font-size: 13px; font-weight: 600; color: var(--ink); }
.rv-empty-text { font-size: 12px; line-height: 1.45; color: var(--muted); }

/* ---- Scene settings (scene-settings.js): one page of sections ---- */
.sc-page { overflow-y: auto; gap: 10px; }
.sc-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 24px; flex: 0 0 auto; }
.sc-heading { margin: 0; font-size: 11.5px; font-weight: 600; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); }
.sc-head .header-btn { height: 24px; padding: 0 8px; display: inline-flex; align-items: center; gap: 5px; }
.sc-head .header-btn svg { width: 12px; height: 12px; color: var(--muted); }
.sc-rule { border: 0; height: 1px; margin: 4px 0; background: var(--line); flex: 0 0 auto; }
.sc-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 30px; flex: 0 0 auto; }
.sc-row[hidden] { display: none; }
.sc-label { display: flex; flex-direction: column; gap: 1px; min-width: 0; font-size: 12.5px; color: var(--ink); }
.sc-sub { font-size: 11px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sc-sub[hidden] { display: none; }
.sc-shadows-sub, .sc-ao-sub { color: var(--amber); }
.muted-row .sc-label > span:first-child { color: var(--muted); }
.sc-sun-row { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; }
.sc-sun-glyph { display: inline-flex; color: var(--muted); } .sc-sun-glyph svg { width: 16px; height: 16px; }
.sc-time-range, .sc-transparency { flex: 1 1 auto; min-width: 0; height: 18px; margin: 0; accent-color: var(--range-accent); cursor: pointer; }
.sc-time, .sc-day, .sc-month, .sc-reflections, .us-page select { height: 28px; padding: 0 8px; border: 1px solid var(--line); border-radius: 7px; background: var(--bg); color: var(--ink); font: inherit; font-size: 12.5px; font-variant-numeric: tabular-nums; }
.sc-time { width: 84px; text-align: center; }
.sc-time::-webkit-calendar-picker-indicator { display: none; } .sc-day { width: 48px; text-align: center; } .sc-month { width: 108px; } .sc-reflections { width: 124px; }
.sc-time:disabled, .sc-day:disabled, .sc-month:disabled, .sc-reflections:disabled, .sc-time-range:disabled, .sc-transparency:disabled { opacity: .55; cursor: default; }
.sc-date { display: inline-flex; gap: 6px; }
.sc-transparency-row { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; padding-top: 2px; }
.sc-transparency-row[hidden] { display: none; }
.sc-transparency-row .sc-sub { flex: 0 0 auto; font-size: 12px; }
.sc-transparency-value { flex: 0 0 auto; min-width: 3em; text-align: right; font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.sc-modes button[aria-pressed="true"], .sc-section button[aria-pressed="true"], .sc-section-controls .rv-strip button[aria-pressed="true"] { background: var(--accent-soft); color: var(--accent-text); box-shadow: inset 0 0 0 1px var(--accent-text); }
.sc-modes button:disabled, .sc-section button:disabled, .sc-section-controls .rv-strip button:disabled { color: var(--muted); cursor: default; }
/* the switch: a checkbox drawn as the shell's 34x18 track, the accent when on; dimmed while the guard forces it off */
.sc-switch { position: relative; display: inline-flex; flex: 0 0 auto; width: 34px; height: 18px; cursor: pointer; }
.sc-switch input { position: absolute; inset: 0; margin: 0; opacity: 0; cursor: pointer; }
.sc-track { position: absolute; inset: 0; border-radius: 9px; background: var(--line); transition: background .15s; }
.sc-track::after { content: ''; position: absolute; top: 2px; left: 2px; width: 14px; height: 14px; border-radius: 50%; background: var(--panel); box-shadow: 0 1px 2px rgba(0, 0, 0, .18); transition: left .15s; }
.sc-switch input:checked + .sc-track { background: var(--accent); }
.sc-switch input:checked + .sc-track::after { left: 18px; }
.sc-switch input:focus-visible + .sc-track { outline: 2px solid var(--accent-text); outline-offset: 2px; }
.sc-switch input:disabled + .sc-track { opacity: .5; } .sc-switch input:disabled { cursor: default; }
.sc-switch input.forced + .sc-track { opacity: .5; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.sc-stats { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; flex: 0 0 auto; padding: 0 2px; }
.sc-stat { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.sc-stat-top { display: flex; align-items: center; gap: 6px; color: var(--ink); font-size: 13px; font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.sc-stat-top svg { width: 15px; height: 15px; color: var(--muted); flex: 0 0 auto; }
.sc-stat-of { font-weight: 400; color: var(--muted); }
.sc-stat-caption { font-size: 10.5px; color: var(--muted); white-space: nowrap; }

/* ---- Voice (voice-bar.js over agent-voice.js): the mic button at rest, the bar while voice is on, spoken turns ---- */
#voice-start {
  flex: 0 0 auto; align-self: flex-end; display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; padding: 0; border: 1px solid var(--line); border-radius: 10px;
  background: var(--bg); color: var(--ink); cursor: pointer;
}
#voice-start:hover:not(:disabled) { border-color: var(--accent-text); }
#voice-start:disabled { opacity: .4; cursor: default; }
#voice-start[hidden], #voice-start[aria-pressed="true"], #voice-panel[hidden] { display: none; } /* the bar stands in for the button while voice is on */
#voice-panel {
  display: flex; align-items: center; gap: 6px; min-height: 42px; padding: 5px 6px 5px 12px;
  border: 1px solid var(--line); border-radius: 10px; background: var(--panel);
}
#voice-panel[data-state="idle"] { border-color: var(--amber); }
#voice-panel[data-state="error"] { border-color: var(--danger); }
.vb-pill { display: flex; align-items: center; gap: 7px; flex: 1 1 auto; min-width: 0; font-size: 12.5px; font-weight: 600; color: var(--ink); white-space: nowrap; }
#voice-panel[data-state="error"] .vb-pill { white-space: normal; font-weight: 500; line-height: 1.35; }
#voice-panel[data-state="muted"] .vb-pill, #voice-panel[data-state="connecting"] .vb-pill, #voice-panel[data-state="ending"] .vb-pill { color: var(--muted); }
#voice-panel[data-state="idle"] .vb-pill { color: var(--amber); }
.vb-lead { display: inline-flex; align-items: center; flex: 0 0 auto; color: var(--accent-text); }
.vb-lead svg { width: 15px; height: 15px; }
#voice-panel[data-state="muted"] .vb-lead, #voice-panel[data-state="blocked"] .vb-lead { color: var(--muted); }
.vb-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.vb-time { font-weight: 400; color: var(--muted); font-variant-numeric: tabular-nums; }
.vb-time[hidden] { display: none; }
#voice-panel[data-state="idle"] .vb-time { color: inherit; }
.vb-meter { display: inline-flex; align-items: center; gap: 2px; height: 16px; }
.vb-meter span { width: 2px; height: 3px; border-radius: 1px; background: currentColor; transition: height .08s linear; }
#voice-panel[data-state="speaking"] .vb-meter span { animation: vb-pulse .8s ease-in-out infinite alternate; }
#voice-panel[data-state="speaking"] .vb-meter span:nth-child(2) { animation-delay: .12s; }
#voice-panel[data-state="speaking"] .vb-meter span:nth-child(3) { animation-delay: .24s; }
#voice-panel[data-state="speaking"] .vb-meter span:nth-child(4) { animation-delay: .36s; }
#voice-panel[data-state="speaking"] .vb-meter span:nth-child(5) { animation-delay: .48s; }
@keyframes vb-pulse { from { height: 4px; } to { height: 14px; } }
/* The app's one progress ring (ring.js): the credits ring's drawing at every size - the track in the line colour, the
   arc in the accent with round caps, started at the top; turning with a 30 % arc while the share is unknown. The rail's
   importing state, the Import rows, the export status line and the share and voice bubbles all draw this one. */
.ring { display: inline-block; flex: 0 0 auto; transform: rotate(-90deg); vertical-align: middle; }
.ring-track { fill: none; stroke: var(--line); }
.ring-value { fill: none; stroke: var(--accent); stroke-linecap: round; transition: stroke-dasharray .3s ease; }
.ring.is-turning { animation: ring-turn 1s linear infinite; }
.ring.is-turning .ring-value { transition: none; }
.ring[data-tone="amber"] .ring-value { stroke: var(--amber); }
.ring[data-tone="danger"] .ring-value { stroke: var(--danger); }
.ring[data-tone="muted"] .ring-value { stroke: var(--muted); }
.ring[data-tone="white"] .ring-track { stroke: rgba(255, 255, 255, .35); }
.ring[data-tone="white"] .ring-value { stroke: #fff; }
@keyframes ring-turn { from { transform: rotate(-90deg); } to { transform: rotate(270deg); } }
#voice-panel[data-state="ending"] .ring-value, #voice-panel[data-state="connecting"] .ring-value { stroke: var(--muted); }
.vb-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--amber); }
#voice-panel[data-state="error"] .vb-dot { background: var(--danger); }
.vb-mic { position: relative; display: inline-flex; align-items: stretch; height: 30px; border: 1px solid var(--line); border-radius: 7px; flex: 0 0 auto; }
.vb-mic[hidden] { display: none; }
.vb-mic > button { display: inline-flex; align-items: center; padding: 0 7px; border: 0; border-radius: 6px 0 0 6px; background: transparent; color: var(--ink); font: inherit; cursor: pointer; }
.vb-mic > button + button { border-left: 1px solid var(--line); border-radius: 0 6px 6px 0; padding: 0 5px; color: var(--muted); }
.vb-mic > button svg { width: 15px; height: 15px; }
.vb-mic > button:hover:not(:disabled) { background: var(--active-item, rgba(127, 127, 127, .14)); }
.vb-mic > button:disabled { cursor: default; opacity: .5; }
#voice-mute[data-muted="true"] { background: var(--accent-soft); color: var(--accent-text); }
#voice-panel .mode-toggle { flex: 0 0 auto; }
#voice-keep[hidden], #voice-play[hidden], #voice-retry[hidden], #voice-end[hidden], #voice-close[hidden] { display: none; }
#voice-mic, #voice-captions, #voice-cost { display: none; } /* agent-voice.js writes them; the bar reads them */
.vb-picker {
  position: absolute; right: -1px; bottom: calc(100% + 6px); z-index: 5; min-width: 220px; max-width: 280px;
  display: flex; flex-direction: column; gap: 1px; padding: 4px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--panel); box-shadow: 0 10px 30px rgba(0, 0, 0, .35);
}
.vb-picker[hidden] { display: none; }
.vb-picker-head { padding: 6px 8px 2px; font-size: 11px; color: var(--muted); }
.vb-picker button { display: flex; align-items: center; gap: 10px; min-height: 34px; padding: 4px 8px; border: 0; border-radius: 6px; background: transparent; color: var(--ink); font: inherit; font-size: 12.5px; text-align: left; cursor: pointer; }
.vb-picker button:hover { background: var(--active-item, rgba(127, 127, 127, .14)); }
.vb-picker button > span { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vb-picker button svg { width: 14px; height: 14px; flex: 0 0 auto; color: var(--muted); }
.vb-picker button .vb-check svg { color: var(--accent-text); }
/* spoken turns: the same bubbles, a mic or a speaker glyph at their start; the one still being spoken keeps the
   accent ring and a caret until the captions rest */
.msg.voice { display: flex; gap: 8px; align-items: flex-start; }
.msg.voice > svg { flex: 0 0 auto; width: 14px; height: 14px; margin-top: 4px; color: var(--muted); }
.msg.voice > span { min-width: 0; }
.msg.user.voice.live { box-shadow: 0 0 0 1px var(--accent-text); }
.msg.voice.live > span::after { content: ''; display: inline-block; width: 2px; height: 14px; margin-left: 3px; vertical-align: -2px; background: var(--accent); animation: vb-caret 1s steps(2) infinite; }
@keyframes vb-caret { to { opacity: 0; } }

/* Map page (map.js): the search with its results dropping over the page, the location card with its static map, the tool rows */
.mp-page { position: relative; }
.mp-page[hidden] { display: none; }
.mp-search-wrap { position: relative; flex: 0 0 auto; }
.mp-search { display: flex; align-items: center; gap: 8px; height: 32px; padding: 0 10px; border: 1px solid var(--line); border-radius: 8px; background: var(--bg); color: var(--muted); cursor: text; }
.mp-search:focus-within { border-color: var(--accent-text); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent); }
.mp-search svg { width: 14px; height: 14px; flex: 0 0 auto; }
.mp-query { flex: 1 1 auto; min-width: 0; border: 0; padding: 0; background: transparent; color: var(--ink); font: inherit; font-size: 12.5px; outline: none; }
.mp-query::placeholder { color: var(--muted); }
.mp-query:disabled { cursor: default; }
.mp-results { position: absolute; left: 0; right: 0; top: 36px; z-index: 3; display: flex; flex-direction: column; gap: 1px; padding: 4px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel); box-shadow: 0 10px 30px rgba(0, 0, 0, .14); }
.mp-results[hidden] { display: none; }
.mp-result { display: flex; align-items: center; gap: 10px; min-height: 40px; padding: 4px 8px; border: 0; border-radius: 6px; background: transparent; color: var(--ink); font: inherit; text-align: left; cursor: pointer; }
.mp-result:hover, .mp-result[aria-selected="true"] { background: var(--active-item, rgba(127, 127, 127, .14)); }
.mp-result-pin { flex: 0 0 auto; width: 26px; height: 26px; display: grid; place-items: center; border-radius: 6px; background: var(--panel-2, var(--bg)); color: var(--muted); }
.mp-result-pin svg { width: 15px; height: 15px; }
.mp-result-text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.mp-result-name { font-size: 12.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mp-result-where { font-size: 11px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mp-results-note { padding: 8px 8px 6px; font-size: 12px; line-height: 1.4; color: var(--muted); }
.mp-link { border: 0; padding: 0; background: transparent; color: var(--accent-text); font: inherit; font-size: 12px; cursor: pointer; }
.mp-locate { display: flex; align-items: center; gap: 6px; padding: 6px 8px 4px; border: 0; background: transparent; color: var(--muted); font: inherit; font-size: 11px; text-align: left; cursor: pointer; }
.mp-locate svg { width: 12px; height: 12px; }
.mp-locate:hover:not(:disabled) { color: var(--ink); }
.mp-locate:disabled { cursor: default; }
.mp-card { display: flex; flex-direction: column; border: 1px solid var(--line); border-radius: 8px; background: var(--panel-2, var(--bg)); overflow: hidden; flex: 0 0 auto; }
.mp-map { display: block; width: 100%; height: 96px; object-fit: cover; background: var(--line); }
.mp-map[hidden] { display: none; }
.mp-place { display: flex; align-items: center; gap: 10px; padding: 9px 12px; }
.mp-pin { flex: 0 0 auto; width: 28px; height: 28px; display: grid; place-items: center; border-radius: 7px; background: var(--panel); box-shadow: inset 0 0 0 1px var(--line); color: var(--accent-text); }
.mp-pin svg { width: 16px; height: 16px; }
.mp-card.is-default .mp-pin { color: var(--muted); }
.mp-place-text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.mp-address { font-size: 13px; font-weight: 600; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mp-card.is-default .mp-address { color: var(--muted); }
.mp-coords { font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mp-hint { padding: 0 12px 10px; font-size: 11.5px; line-height: 1.4; color: var(--muted); }
.mp-hint[hidden] { display: none; }
.mp-tool { height: 24px; padding: 0 8px; display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; white-space: nowrap; }
.mp-tool svg { width: 12px; height: 12px; color: var(--muted); }
.mp-tool[aria-pressed="true"], .mp-tool[aria-pressed="true"] svg { color: var(--accent-text); }
.mp-spacer { flex: 1 1 auto; min-height: 8px; }
.mp-attribution { flex: 0 0 auto; font-size: 10.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mp-attribution a { color: inherit; text-decoration: none; }
.mp-attribution a.mp-improve, .mp-attribution a:hover { text-decoration: underline; }

/* History page (history.js): the versions by local day in five-minute blocks, the row being previewed or loaded, and
   the preview window over the player. The window borrows the media viewer's chrome (#render-viewer: the same scrim,
   panel surface, hairline border, 12px corners, 32px actions) at a 640px width, so a still of a version reads like an
   opened render rather than a second player. The page is a container so a narrow drawer (300px, down to the panel's
   220px) can drop the hover hint and let a row's time and its Latest save marker wrap. */
.hy-page { gap: 2px; padding: 10px 12px 12px; overflow-y: auto; container-type: inline-size; }
.hy-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; min-height: 22px; padding: 0 2px; font-size: 11.5px; font-weight: 600; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); flex: 0 0 auto; }
.hy-row + .hy-head, .hy-group + .hy-head { margin-top: 8px; }
.hy-count { font-size: 11.5px; font-weight: 400; letter-spacing: 0; text-transform: none; white-space: nowrap; }
.hy-row { display: flex; width: 100%; background: transparent; text-align: left; font: inherit; align-items: center; gap: 8px; min-height: 32px; padding: 0 6px; border: 1px solid transparent; border-radius: 6px; color: var(--ink); cursor: pointer; flex: 0 0 auto; }
.hy-row:hover, .hy-row:focus-visible { background: var(--active-item, rgba(127, 127, 127, .14)); outline: none; }
.hy-row[aria-pressed="true"] { border-color: var(--accent-text); background: var(--accent-soft); }
.hy-row[aria-disabled="true"] { cursor: default; opacity: .6; }
/* The row whose version is downloading and the one in the window stay legible while every row waits. */
.hy-row[aria-disabled="true"][data-status="loading"], .hy-row[aria-disabled="true"][aria-pressed="true"] { opacity: 1; }
.hy-tile { flex: 0 0 auto; width: 22px; height: 22px; display: grid; place-items: center; border-radius: 6px; background: var(--panel-2, var(--bg)); color: var(--muted); }
.hy-tile svg { width: 13px; height: 13px; }
.hy-tile .spinner { width: 13px; height: 13px; border-width: 2px; }
.hy-row[aria-pressed="true"] .hy-tile { background: var(--panel); box-shadow: inset 0 0 0 1px var(--accent-text); color: var(--accent-text); }
.hy-time { flex: 1 1 auto; min-width: 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 8px; font-size: 12.5px; font-weight: 600; font-variant-numeric: tabular-nums; }
.hy-latest { font-size: 10.5px; font-weight: 500; color: var(--muted); white-space: nowrap; }
.hy-hint { display: none; font-size: 11px; color: var(--muted); white-space: nowrap; }
.hy-row:hover .hy-hint, .hy-row:focus-visible .hy-hint { display: inline; }
.hy-row[aria-disabled="true"] .hy-hint { display: none; }
.hy-tag { font-size: 10.5px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--accent-text); white-space: nowrap; }
.hy-tag.hy-loading { color: var(--muted); }
/* A five-minute block: its header row discloses the exact versions behind the newest, which stays in view. */
.hy-group { margin: 2px 0 6px; padding: 2px; border: 1px solid var(--line); border-radius: 7px; flex: 0 0 auto; }
.hy-expand { display: flex; align-items: center; gap: 6px; width: 100%; min-height: 28px; padding: 2px 6px 2px 4px; border: 0; border-radius: 5px; color: var(--muted); background: transparent; font: inherit; font-size: 11.5px; text-align: left; cursor: pointer; }
.hy-expand:hover { background: var(--panel-2); color: var(--ink); }
.hy-expand:focus-visible, .hy-row:focus-visible { outline: 2px solid var(--accent-text); outline-offset: -2px; }
.hy-chev { flex: 0 0 auto; display: inline-grid; place-items: center; width: 14px; height: 14px; transition: transform .15s ease; }
.hy-chev svg { width: 14px; height: 14px; }
.hy-expand[aria-expanded="true"] .hy-chev { transform: rotate(90deg); }
@media (prefers-reduced-motion: reduce) { .hy-chev { transition: none; } }
.hy-range { font-weight: 600; font-variant-numeric: tabular-nums; color: var(--ink); }
.hy-group-count { margin-left: auto; white-space: nowrap; }
.hy-group-mark { color: var(--accent-text); font-weight: 600; }
.hy-group-rows { margin: 2px 0 0 10px; padding-left: 6px; border-left: 1px solid var(--line); }
.hy-group-rows[hidden] { display: none; }
.hy-row.hy-sub { min-height: 30px; }
.hy-row.hy-sub .hy-tile { width: 20px; height: 20px; }
@container (max-width: 250px) { .hy-row .hy-hint { display: none; } .hy-group-count { white-space: normal; text-align: right; } }
/* A failure line: a sentence, and Refresh history when the list has to be read again before another try. */
.hy-error { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; padding: 6px 8px; border: 1px solid var(--amber); border-radius: 6px; font-size: 11.5px; line-height: 1.4; color: var(--ink); flex: 0 0 auto; }
.hy-error[hidden] { display: none; }
.hy-error .hy-error-text { flex: 1 1 160px; min-width: 0; }
.hy-error .header-btn { height: 26px; padding: 0 9px; }
.hy-error .header-btn[hidden] { display: none; }
.hy-empty { flex: 1 1 auto; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; padding: 0 14px 40px; text-align: center; }
.hy-empty[hidden] { display: none; }
.hy-spacer { flex: 1 1 auto; }
.hy-foot { flex: 0 0 auto; padding-top: 8px; font-size: 10.5px; line-height: 1.4; color: var(--muted); }
.hy-foot[hidden] { display: none; }
/* Load older cloud versions (shared-scenes.js appends it under the page while a shared history has more). */
.hy-more { margin: 0 12px 12px; height: 30px; font-size: 12px; }
.hy-more[hidden] { display: none; }
/* ---- the preview window over the player ---- */
#history-banner { position: absolute; inset: 0; z-index: 4; display: grid; place-items: center; padding: 12px; background: rgba(4, 8, 6, .72); backdrop-filter: blur(3px); color: var(--ink); font-size: 13px; line-height: 1.4; }
#history-banner[hidden] { display: none; }
/* A flex column capped at the player's height: in a short player the stage gives way (down to 96px, the still
   letterboxed) before the header, its actions and the note do, and the window scrolls only after that. */
.hy-dialog { display: flex; flex-direction: column; width: min(640px, 100%); max-height: 100%; min-height: 0; overflow: auto; background: var(--panel); color: var(--ink); border: 1px solid var(--line); border-radius: 12px; box-shadow: 0 24px 64px rgba(0, 0, 0, .5); outline: none; }
/* Sticky, so the actions stay reachable in the one case the window still scrolls: a player too short for the stage's
   96px minimum, the header and the note together. */
.hy-preview-header { position: sticky; top: 0; z-index: 1; flex: 0 0 auto; display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; padding: 10px 12px 10px 16px; background: var(--panel); border-bottom: 1px solid var(--line); }
.hy-when { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 8px; min-width: 0; font-weight: 600; font-size: 14px; letter-spacing: .01em; }
.hy-when-label { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; } /* the label gives way first in a narrow player; the time stays whole */
.hy-when-time { flex: 0 0 auto; font-size: 13px; font-variant-numeric: tabular-nums; }
.hy-preview-details { flex: 1 0 100%; order: 3; font-size: 11.5px; color: var(--muted); overflow-wrap: anywhere; }
.hy-preview-details:empty { display: none; }
/* The actions take what is left of the title row and, on a narrow player, the whole next row; they keep to the right
   like the viewer's, Dismiss last, and wrap among themselves only when even a row of their own is too narrow. */
.hy-actions { flex: 1 1 auto; display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 8px; }
.hy-action { flex: 0 0 auto; height: 32px; padding: 0 12px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel-2); color: var(--ink); font: inherit; font-size: 12.5px; font-weight: 600; white-space: nowrap; cursor: pointer; transition: border-color .15s ease; }
.hy-action:hover:not(:disabled), .hy-action:focus-visible { border-color: var(--accent-text); outline: none; }
.hy-action:disabled { opacity: .5; cursor: default; }
.hy-action[hidden] { display: none; }
.hy-preview-stage { position: relative; flex: 1 1 auto; min-height: 96px; aspect-ratio: 8 / 5; display: grid; place-items: center; background: var(--bg); color: var(--ink); }
/* The still is the stage's box, whatever the stage was shrunk to; as a grid item its intrinsic height would hold the
   stage open and push the note out of view. */
.hy-preview-image { position: absolute; inset: 0; display: block; width: 100%; height: 100%; object-fit: contain; user-select: none; }
.hy-preview-image[hidden], .hy-preview-status[hidden] { display: none; }
.hy-preview-status { display: flex; flex-direction: column; align-items: center; gap: 8px; max-width: 400px; padding: 16px; text-align: center; font-size: 12.5px; line-height: 1.4; }
.hy-status-glyph { display: grid; place-items: center; }
.hy-status-glyph .spinner { width: 22px; height: 22px; border-width: 2px; }
.hy-status-glyph svg { width: 22px; height: 22px; color: var(--muted); }
.hy-status-title { font-weight: 600; }
.hy-status-detail { font-size: 11.5px; color: var(--muted); }
.hy-status-detail:empty { display: none; }
.hy-preview-error { margin: 8px 16px 0; }
.hy-preview-foot { flex: 0 0 auto; display: flex; flex-direction: column; gap: 2px; padding: 8px 16px 10px; border-top: 1px solid var(--line); font-size: 11.5px; line-height: 1.4; color: var(--muted); }
.hy-preview-warnings:empty { display: none; }
/* Fingers get the taller targets of the rest of the shell's touch chrome. */
@media (pointer: coarse) { .hy-action { height: 36px; } .hy-row, .hy-row.hy-sub { min-height: 36px; } .hy-expand { min-height: 32px; } }

/* Initial queue layout: the runtime owns the order; this small surface can be restyled independently. */
/* The queued prompts (agent-prompt-queue.js), at the foot of the transcript and continuing its column: an eyebrow, then
   each waiting message as the user bubble's shape hollow - a hairline on the panel's second surface, the words in ink -
   with Send now and Discard as two quiet words under its right edge; a notice as one muted line. The block scrolls
   past two fifths of the pane so a long queue never squeezes the transcript away. */
#prompt-queue { flex: 0 0 auto; display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; column-gap: 10px; row-gap: 10px; max-height: 40vh; overflow-y: auto; padding: 0 18px 14px; background: var(--panel); }
#prompt-queue[hidden] { display: none; }
/* a wrapping row: the eyebrow and Continue queue (ordered before the messages, whatever their place in the markup) share
   the first line at the right; every waiting message and the notice take a full line of their own */
.pq-eyebrow { order: -2; font-size: 11.5px; font-weight: 600; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); }
.pq-resume { order: -1; padding: 0; }
.pq-item, .pq-notice { flex: 0 0 100%; }
/* The first track soaks up the row, so the bubble's percentage cap resolves against the chat column as the transcript's does;
   the two actions are placed under the bubble's right edge rather than sliding into that track. */
.pq-item { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; justify-content: end; column-gap: 12px; row-gap: 5px; }
.pq-item > .pq-act:nth-of-type(1) { grid-column: 2; }
.pq-item > .pq-act:nth-of-type(2) { grid-column: 3; }
.pq-bubble { grid-column: 1 / -1; justify-self: end; max-width: 84%; padding: 10px 14px; border: 1px solid var(--line); border-radius: 16px; border-bottom-right-radius: 6px; background: var(--panel-2); color: var(--ink); white-space: pre-wrap; overflow-wrap: anywhere; font-size: 15px; line-height: 1.5; }
.pq-item:hover .pq-bubble { border-color: var(--muted); }
.pq-bubble[data-files]::after { content: ''; display: inline-block; width: 13px; height: 13px; margin-left: 6px; vertical-align: -2px; background: currentColor; opacity: .6; -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 11.5 12.3 20.2a5 5 0 0 1-7.1-7.1l9-9a3.3 3.3 0 0 1 4.7 4.7l-9 9a1.7 1.7 0 0 1-2.4-2.4l8.3-8.3'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 11.5 12.3 20.2a5 5 0 0 1-7.1-7.1l9-9a3.3 3.3 0 0 1 4.7 4.7l-9 9a1.7 1.7 0 0 1-2.4-2.4l8.3-8.3'/%3E%3C/svg%3E") center / contain no-repeat; }
.pq-act { padding: 0 6px 0 0; border: 0; background: transparent; color: var(--accent-text); font: inherit; font-size: 12px; font-weight: 600; cursor: pointer; white-space: nowrap; }
.pq-act.pq-discard { color: var(--muted); }
.pq-act:hover:not(:disabled) { text-decoration: underline; }
.pq-act:disabled { opacity: .5; cursor: default; }
.pq-notice { padding-right: 6px; font-size: 12px; color: var(--muted); text-align: right; }

/* ---- Settings page: the units strip, native create ranges, and browser scroll controls ---- */
.us-page { gap: 10px; }
.us-page select { cursor: pointer; }
#scroll-controls-status:empty { display: none; }
.us-units button[aria-pressed="true"] { background: var(--accent-soft); color: var(--accent-text); }
.us-setting { display: flex; flex-direction: column; gap: 6px; flex: 0 0 auto; }
.us-setting + .us-setting { margin-top: 6px; }
.us-setting-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; font-size: 12.5px; color: var(--ink); }
.us-value { font-size: 13px; font-weight: 600; font-variant-numeric: tabular-nums; }
.us-setting input[type="range"] { width: 100%; height: 18px; margin: 0; accent-color: var(--range-accent); }
.us-ends { display: flex; justify-content: space-between; padding: 0 2px; font-size: 10.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.us-sub { font-size: 11px; line-height: 1.4; color: var(--muted); }
.us-foot { margin-top: auto; padding-top: 8px; font-size: 10.5px; color: var(--muted); }

/* ---- Cloud tab (cloud-group.js): the device group's invite code and Join, the group's card, what arrived ---- */
.cg-page { gap: 12px; }
.cg-note, .cg-text { font-size: 12.5px; line-height: 1.45; color: var(--muted); }
.cg-heading { font-size: 13px; font-weight: 600; color: var(--ink); }
.cg-field { display: flex; flex-direction: column; gap: 5px; }
.cg-label { font-size: 12px; color: var(--muted); }
.cg-code { height: 34px; padding: 0 10px; border: 1px solid var(--line); border-radius: 7px; background: var(--panel); color: var(--ink); font: inherit; font-size: 13.5px; letter-spacing: .12em; text-transform: uppercase; }
.cg-code::placeholder { color: var(--muted); letter-spacing: 0; text-transform: none; }
.cg-code:focus { outline: none; border-color: var(--accent-text); }
.cg-error { font-size: 12.5px; line-height: 1.45; color: var(--amber); }
.cg-primary { display: inline-flex; align-items: center; justify-content: center; height: 32px; padding: 0 16px; border: 1px solid var(--accent); border-radius: 7px; background: var(--accent); color: #fff; font: inherit; font-size: 13px; font-weight: 600; cursor: pointer; transition: filter .15s ease, opacity .15s ease; }
.cg-primary:hover:not(:disabled), .cg-primary:focus-visible { filter: brightness(1.06); outline: none; }
.cg-primary:disabled { opacity: .5; cursor: default; }
.cg-manage { font-size: 11.5px; color: var(--muted); }
.cg-manage a { color: var(--accent-text); }
.cg-card { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border: 1px solid var(--line); border-radius: 9px; background: var(--panel-2); }
.cg-card-glyph { flex: 0 0 auto; width: 36px; height: 36px; display: grid; place-items: center; border-radius: 9px; border: 1px solid var(--line); background: var(--panel); color: var(--accent-text); }
.cg-card-glyph svg { width: 20px; height: 20px; }
.cg-card-name { flex: 1 1 auto; min-width: 0; font-size: 14px; font-weight: 600; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cg-caption-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.cg-caption { font-size: 11px; font-weight: 600; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); }
.cg-caption-row .sh-textbtn { font-size: 12px; }
.cg-checking { font-size: 12px; color: var(--muted); }
.cg-arrivals { display: flex; flex-direction: column; gap: 1px; margin: -4px -8px 0; }
.cg-arrival { display: flex; align-items: center; gap: 10px; min-height: 44px; padding: 4px 8px; border-radius: 7px; }
.cg-arrival:hover { background: var(--chat-hover, rgba(127,127,127,.08)); }
.cg-arrival-glyph { flex: 0 0 auto; width: 32px; height: 32px; display: grid; place-items: center; border-radius: 7px; border: 1px solid var(--line); background: var(--panel-2); color: var(--muted); }
.cg-arrival-glyph svg { width: 16px; height: 16px; }
.cg-arrival-who { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.cg-arrival-name { font-size: 13px; font-weight: 500; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cg-arrival-meta { font-size: 11.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cg-arrival .sh-textbtn { flex: 0 0 auto; font-size: 12px; }
.cg-empty { font-size: 12.5px; color: var(--muted); }
.cg-foot { margin-top: auto; display: flex; flex-direction: column; gap: 12px; }
.cg-leave { display: inline-flex; align-items: center; gap: 6px; height: 30px; padding: 0 12px; font-size: 12.5px; }
.cg-leave svg { width: 14px; height: 14px; }

/* ---- Share tab (share.js): Collaborate with people, the temporary meeting form, the link, the people rows ---- */
.sh-page { gap: 10px; }
.sh-page [hidden] { display: none; }
.sh-empty { display: flex; flex-direction: column; gap: 14px; }
.sh-intro { display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 26px 14px 6px; text-align: center; }
.sh-intro .header-btn { display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 10px; margin-top: 4px; border-color: var(--accent); background: var(--accent); color: var(--accent-ink); font-size: 12px; font-weight: 600; }
.sh-intro .header-btn svg { width: 13px; height: 13px; }
.sh-form { display: flex; flex-direction: column; gap: 6px; padding: 10px; border: 1px dashed var(--line); border-radius: 9px; }
.sh-temp { font-size: 10.5px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--amber); }
.sh-form input { height: 30px; padding: 0 10px; border: 1px solid var(--line); border-radius: 7px; background: var(--bg); color: var(--ink); font: inherit; font-size: 13px; }
.sh-form input:focus { outline: none; border-color: var(--accent-text); }
.sh-form input::placeholder { color: var(--muted); }
.sh-form .header-btn { height: 30px; font-size: 12.5px; font-weight: 600; }
.sh-connecting { display: flex; align-items: center; gap: 10px; padding: 12px 4px; font-size: 12.5px; color: var(--muted); }
.sh-connecting .header-btn { margin-left: auto; }
.sh-shared { display: flex; flex-direction: column; gap: 8px; flex: 1 1 auto; min-height: 0; }
.sh-link { display: flex; align-items: center; gap: 6px; }
.sh-link-field { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 8px; height: 30px; padding: 0 10px; border: 1px solid var(--line); border-radius: 7px; background: var(--bg); color: var(--ink); font-size: 12.5px; }
.sh-link-field svg { width: 13px; height: 13px; color: var(--muted); flex: 0 0 auto; }
.sh-link-text { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sh-copy { display: inline-flex; align-items: center; gap: 5px; height: 30px; padding: 0 10px; font-size: 12.5px; font-weight: 600; }
.sh-copy svg { width: 13px; height: 13px; color: var(--muted); }
.sh-copy.is-copied { border-color: var(--accent-text); color: var(--accent-text); background: var(--accent-soft); }
.sh-copy.is-copied svg { color: var(--accent-text); }
.sh-sub { font-size: 11px; line-height: 1.4; color: var(--muted); }
.sh-reconnecting { display: flex; align-items: center; gap: 8px; padding: 6px 8px; border: 1px solid var(--amber); border-radius: 7px; font-size: 12px; color: var(--ink); }
.sh-list { display: flex; flex-direction: column; gap: 2px; min-height: 0; overflow-y: auto; }
.sh-row { display: flex; align-items: center; gap: 10px; min-height: 38px; padding: 4px 4px 4px 6px; border-radius: 6px; flex: 0 0 auto; }
.sh-row:hover { background: var(--active-item, rgba(127, 127, 127, .14)); }
.sh-avatar { flex: 0 0 auto; width: 26px; height: 26px; display: grid; place-items: center; border-radius: 50%; color: #fff; }
.sh-avatar svg { width: 14px; height: 14px; }
.sh-who { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.sh-name-line { font-size: 13px; font-weight: 500; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sh-row[data-me] .sh-name-line { font-weight: 600; }
.sh-you { font-weight: 400; color: var(--muted); }
.sh-role { font-size: 11px; color: var(--muted); }
.sh-icon { display: inline-grid; place-items: center; width: 24px; height: 24px; padding: 0; border: 0; border-radius: 5px; background: transparent; color: var(--muted); cursor: pointer; }
.sh-icon svg { width: 15px; height: 15px; }
.sh-row:hover button.sh-icon, .sh-icon:focus-visible { color: var(--ink); outline: none; }
button.sh-icon:hover { background: var(--panel); }
.sh-gather { display: inline-flex; align-items: center; gap: 5px; height: 24px; padding: 0 8px; font-size: 11.5px; }
.sh-gather svg { width: 12px; height: 12px; color: var(--muted); }
.sh-spacer { flex: 1 1 auto; }
.sh-leave { display: flex; align-items: center; justify-content: center; gap: 8px; }
.sh-leave svg { width: 15px; height: 15px; }
.rail-tab { position: relative; }
.rail-dot { position: absolute; right: 7px; top: 6px; width: 7px; height: 7px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 2px var(--panel); }
.rail-dot[data-state="connecting"], .rail-dot[data-state="failed"] { background: var(--amber); }
.rail-dot[hidden] { display: none; }
/* The Import & export entry's importing state: the app's ring, 30 px, turning around the glyph itself (imports.js). */
.rail-ring { position: absolute; left: 50%; top: 50%; width: 30px; height: 30px; margin: -15px 0 0 -14px; pointer-events: none; }
.rail-ring[hidden] { display: none; }
.rail-ring .ring { display: block; }

/* Resource reports remain readable on narrow drawers; status text never replaces the retained evidence. */
.storage-actions, .resource-diagnostics-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.resource-diagnostic { margin-top: 10px; border-top: 1px solid var(--line); padding-top: 8px; }
.resource-diagnostic summary { cursor: pointer; font-size: 12px; overflow-wrap: anywhere; }
.resource-diagnostic summary > div { color: var(--muted); font-size: 11px; margin-top: 3px; }
.resource-diagnostic pre { font: 11px/1.5 ui-monospace, Consolas, monospace; white-space: pre-wrap; overflow-wrap: anywhere; }
.resource-diagnostic.has-error summary { color: var(--danger); }
#resource-diagnostics-result:empty { display: none; }

/* ---- Share tab, voice and the link (share.js): the card, the access chip and its menu, the cloud and voice lines, the mics ---- */
.sh-textbtn { padding: 0; border: 0; background: transparent; color: var(--accent-text); font: inherit; font-size: inherit; font-weight: 600; cursor: pointer; white-space: nowrap; }
.sh-textbtn:hover { text-decoration: underline; }
.sh-intro .sh-share:disabled { border-color: var(--line); background: transparent; color: var(--muted); cursor: default; }
.sh-signin { font-size: 11.5px; color: var(--muted); }
.sh-notice { padding: 6px 8px; border: 1px solid var(--amber); border-radius: 7px; font-size: 11.5px; line-height: 1.4; color: var(--ink); overflow-wrap: anywhere; }
.sh-card { display: flex; flex-direction: column; gap: 10px; padding: 12px; border: 1px solid var(--line); border-radius: 10px; background: var(--panel-2); }
.sh-card-head { display: flex; align-items: center; justify-content: space-between; }
.sh-card-title { font-size: 13px; font-weight: 600; color: var(--ink); }
.sh-card-close { color: var(--muted); }
.sh-card-close:hover { color: var(--ink); }
.sh-card-q { font-size: 12px; color: var(--ink); }
.sh-seg button { display: flex; align-items: center; justify-content: center; gap: 6px; height: 26px; padding: 0; color: var(--muted); font-size: 12px; font-weight: 500; }
.sh-seg button svg { width: 12px; height: 12px; }
.sh-seg button[aria-pressed="true"] { background: var(--accent-soft); color: var(--accent-text); font-weight: 600; }
.sh-card-text { font-size: 11px; line-height: 1.4; color: var(--muted); }
.sh-card-foot { display: flex; justify-content: flex-end; padding-top: 2px; }
.sh-card-foot .header-btn { display: inline-flex; align-items: center; gap: 6px; height: 26px; padding: 0 10px; border-color: var(--accent); background: var(--accent); color: var(--accent-ink); font-size: 12px; font-weight: 600; }
.sh-card-foot .header-btn svg { width: 12px; height: 12px; }
.sh-access { position: relative; display: flex; align-items: center; }
.sh-chip { display: inline-flex; align-items: center; gap: 6px; max-width: 100%; height: 26px; padding: 0 6px 0 8px; border: 1px solid var(--line); border-radius: 6px; background: transparent; color: var(--ink); font: inherit; font-size: 12px; white-space: nowrap; cursor: pointer; }
.sh-chip:hover:not(:disabled) { background: var(--active-item, rgba(127, 127, 127, .14)); }
.sh-chip:disabled { cursor: default; padding-right: 9px; }
.sh-chip:disabled .sh-chip-chevron { display: none; }
.sh-chip[aria-expanded="true"] { border-color: var(--accent-text); background: var(--accent-soft); }
.sh-chip-glyph, .sh-chip-chevron { display: inline-flex; color: var(--muted); }
.sh-chip-glyph svg { width: 13px; height: 13px; }
.sh-chip-chevron svg { width: 11px; height: 11px; }
.sh-chip-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.sh-menu { right: auto; left: 0; bottom: auto; top: calc(100% + 6px); min-width: 260px; max-width: 292px; }
.sh-menu button { align-items: flex-start; padding: 7px 8px; }
.sh-menu button > svg { margin-top: 2px; }
.sh-menu-body { display: flex; flex-direction: column; gap: 2px; white-space: normal; }
.sh-menu-title { font-size: 12.5px; color: var(--ink); }
.sh-menu-text { font-size: 11px; line-height: 1.35; color: var(--muted); }
.sh-menu .vb-check { margin-top: 2px; }
.sh-cloud, .sh-viewing, .sh-voice { display: flex; align-items: center; gap: 6px; min-height: 20px; font-size: 11.5px; line-height: 1.35; color: var(--muted); white-space: nowrap; overflow: hidden; }
.sh-cloud-glyph, .sh-voice-lead { display: inline-flex; flex: 0 0 auto; }
.sh-cloud-glyph svg, .sh-voice-lead svg { width: 13px; height: 13px; }
.sh-cloud-text, .sh-voice-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.sh-cloud[data-kind="failed"] .sh-cloud-glyph, .sh-cloud[data-kind="failed"] .sh-cloud-text { color: var(--amber); }
.sh-voice { padding: 0 6px; flex: 0 0 auto; }
.sh-voice[data-kind="unsupported"] { white-space: normal; }
.sh-voice[data-kind="unsupported"] .sh-voice-text { white-space: normal; }
.sh-voice[data-kind="error"] .sh-voice-text { color: var(--ink); }
.sh-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--amber); margin: 0 2px; flex: 0 0 auto; }
.sh-people { position: relative; display: flex; flex-direction: column; gap: 2px; min-height: 0; }
.sh-mic svg { width: 15px; height: 15px; }
.sh-mic[data-mic="speaking"], .sh-mic-btn[data-mic="speaking"] { color: var(--accent-text); }
span.sh-mic { cursor: default; }
.sh-micsplit { height: 28px; }
.sh-micsplit > button { position: relative; }
.sh-mic-btn[aria-pressed="true"] { background: var(--accent-soft); color: var(--accent-text); }
.sh-mic-btn[aria-pressed="true"]:hover:not(:disabled) { background: color-mix(in srgb, var(--accent) 24%, transparent); }
.sh-warn { position: absolute; right: 1px; bottom: 1px; width: 11px; height: 11px; line-height: 0; }
.sh-warn svg { width: 11px; height: 11px; }
.sh-role.is-warn { color: var(--amber); }
.sh-picker { right: 4px; left: auto; bottom: auto; top: 0; }
.sh-picker-note { padding: 6px 8px 8px; font-size: 11px; line-height: 1.4; color: var(--muted); white-space: normal; }

/* ---- Front view and its views menu (the Navigate group): two buttons in the palette's manner, no box, no hairline, no
   line - the glyph's hit area is 32px with the drawing three units right of centre, the chevron's 12px, so the pair reads
   as one control with two halves. The menu is the voice bar's picker opening downward, its glyphs in ink at 18px. ---- */
.tool-split { position: relative; display: flex; align-items: stretch; }
.tool-split .tool-front { width: 32px; padding-left: 6px; }
.tool-split .tool-chevron { width: 12px; }
.tool-split .tool-chevron .tool-svg { width: 12px; height: 12px; }
#views-menu { left: 0; right: auto; bottom: auto; top: calc(100% + 4px); min-width: 180px; }
#views-menu button svg { width: 18px; height: 18px; color: var(--ink); }
#views-menu .views-rule { height: 1px; margin: 3px 4px; background: var(--line); }
#views-saved { display: flex; flex-direction: column; gap: 1px; } /* the saved viewpoints: a rule, then a camera glyph and the name per row */
#views-menu .views-go { flex: 0 0 auto; display: inline-flex; transform: rotate(-90deg); }
#views-menu .views-go svg { width: 11px; height: 11px; color: var(--muted); }

/* ---- Import & export (transfer.js): the two panes, the format rows with their mono chips, the status line ---- */
.tx-pane { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.tx-pane[hidden] { display: none; }
.tx-empty { flex: 1 1 auto; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; padding: 0 24px 40px; text-align: center; }
.tx-list { display: flex; flex-direction: column; gap: 2px; padding: 6px 8px 0; }
.tx-row { display: flex; align-items: center; gap: 10px; min-height: 44px; padding: 6px 8px 6px 10px; border-radius: 6px; }
.tx-row:hover { background: var(--active-item, rgba(127, 127, 127, .14)); }
.tx-row.is-soon:hover { background: transparent; }
.tx-tag { flex: 0 0 auto; display: inline-grid; place-items: center; width: 38px; height: 22px; border: 1px solid var(--line); border-radius: 5px; font: 600 10.5px/1 ui-monospace, Consolas, monospace; letter-spacing: .04em; color: var(--ink); }
.tx-who { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.tx-name { font-size: 13px; font-weight: 500; color: var(--ink); }
.tx-text { font-size: 11px; line-height: 1.35; color: var(--muted); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.tx-row.is-soon .tx-name, .tx-row.is-soon .tx-tag { color: var(--muted); }
.tx-row.is-soon .tx-tag { opacity: .6; }
.tx-export { height: 26px; padding: 0 10px; border-radius: 6px; font-size: 12px; font-weight: 600; }
.tx-status { display: flex; align-items: center; gap: 6px; min-height: 22px; margin: 8px 18px 0; font-size: 11.5px; line-height: 1.35; color: var(--muted); white-space: nowrap; overflow: hidden; }
.tx-status-lead { display: inline-flex; flex: 0 0 auto; }
.tx-status-lead svg { width: 13px; height: 13px; }
.tx-status-text { flex: 0 0 auto; }
.tx-status-sub { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.tx-status[data-kind="running"] .tx-status-text, .tx-status[data-kind="done"] .tx-status-text { color: var(--ink); }
.tx-status[data-kind="done"] .tx-status-lead { color: var(--accent-text); }
.tx-status[data-kind="failed"] .tx-status-text { color: var(--amber); }

/* ---- the Import pane (imports.js): the list, a file's details, the drop zone, the placing banner ----
   The list: heading row with the count and the sort choice, the search field and the kind choice, then the rows -
   thumbnail, name with its kind chip, one line of facts, the mark at the right (a dot until opened, "in scene", a
   failure), the chevron on hover. Past about 480 px of pane the rows flow into two columns (a container query on the
   pane). The details keep one column: back, name, delete; the preview; the facts on two fixed lines; the controls with
   their labels beside them; the two placement blocks, a rule between them. The choices are native selects in the
   composer's chrome. */
.tx-pane[data-pane="import"] { container-type: inline-size; overflow: hidden auto; }
.im-list, .im-details { display: flex; flex-direction: column; min-width: 0; padding: 12px 18px 16px; }
.im-head { display: flex; align-items: center; gap: 8px; min-height: 26px; min-width: 0; }
.im-head .drawer-heading { margin: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.im-count { flex: 1 1 auto; min-width: 0; font-size: 11.5px; color: var(--muted); white-space: nowrap; }
.im-sort { flex: 0 1 auto; min-width: 0; max-width: 55%; }
.im-sort, .im-kind, .im-version, .im-units, .im-axis {
  height: 26px; padding: 0 24px 0 8px; border: 1px solid var(--line); border-radius: 7px; background: var(--bg); color: var(--ink);
  font: inherit; font-size: 12px; cursor: pointer; appearance: none; -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235c6d66' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 7px center; background-size: 11px;
}
.im-sort:focus, .im-kind:focus, .im-version:focus, .im-units:focus, .im-axis:focus { outline: none; border-color: var(--accent-text); }
.im-sort:disabled, .im-kind:disabled, .im-version:disabled, .im-units:disabled, .im-axis:disabled { opacity: .55; cursor: default; }
.im-tools { display: flex; align-items: center; gap: 8px; margin-top: 10px; }
.im-search { flex: 1 1 auto; min-width: 0; height: 28px; }
.im-rows { display: grid; grid-template-columns: 1fr; gap: 2px; margin: 10px -8px 0; }
@container (min-width: 480px) { .im-rows { grid-template-columns: 1fr 1fr; column-gap: 8px; } }
.im-row { display: flex; align-items: center; gap: 10px; min-width: 0; min-height: 56px; padding: 6px 8px; border-radius: 7px; overflow: hidden; cursor: pointer; }
.im-row:hover, .im-row:focus-visible { background: var(--active-item, rgba(127, 127, 127, .14)); outline: none; }
.im-thumb { position: relative; flex: 0 0 auto; width: 44px; height: 44px; display: grid; place-items: center; border-radius: 6px; background: var(--panel-2, var(--bg)); overflow: hidden; }
.im-thumb .im-pic { width: 100%; height: 100%; object-fit: cover; }
.im-glyph { display: inline-flex; color: var(--muted); }
.im-glyph svg { width: 20px; height: 20px; }
.im-thumb-ring { position: absolute; inset: 0; display: grid; place-items: center; }
.im-thumb-ring .ring { display: block; width: 30px; height: 30px; }
.im-who { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.im-name { display: flex; align-items: center; gap: 6px; min-width: 0; }
.im-title { font-size: 13px; font-weight: 500; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.im-name .tx-tag, .im-dname .tx-tag { width: auto; min-width: 34px; height: 18px; padding: 0 5px; font-size: 10px; }
.im-facts { font-size: 11px; line-height: 1.35; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.im-facts.is-failed, .im-failed { color: var(--amber); }
.im-mark { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 6px; font-size: 11px; color: var(--muted); }
.im-inscene { display: inline-flex; align-items: center; gap: 3px; color: var(--accent-text); }
.im-inscene svg { width: 12px; height: 12px; }
.im-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--accent); }
.im-chev { flex: 0 0 auto; display: inline-flex; color: var(--muted); opacity: 0; transition: opacity .15s ease; }
.im-chev svg { width: 14px; height: 14px; }
.im-row:hover .im-chev, .im-row:focus-visible .im-chev { opacity: 1; }
.im-note { margin-top: 10px; font-size: 11.5px; color: var(--muted); }
.im-empty { display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 32px 12px 24px; text-align: center; font-size: 13px; color: var(--muted); }
.im-empty-sub { font-size: 11.5px; line-height: 1.4; max-width: 300px; }
.im-drop { display: flex; flex-direction: column; align-items: center; gap: 4px; margin-top: 14px; padding: 14px 12px; border: 1px dashed var(--line); border-radius: 9px; color: var(--muted); font-size: 12px; text-align: center; cursor: pointer; transition: border-color .15s ease, background .15s ease; }
.im-drop svg { width: 18px; height: 18px; margin-bottom: 2px; }
.im-drop:hover, .im-drop.is-lit { border-color: var(--accent-text); color: var(--accent-text); background: color-mix(in srgb, var(--accent) 8%, transparent); }
.im-drop-sub { font-size: 11px; color: var(--muted); }
.im-dhead { display: flex; align-items: center; gap: 8px; min-height: 28px; }
.im-back { display: inline-flex; align-items: center; gap: 4px; padding: 4px 8px 4px 5px; }
.im-back svg { width: 13px; height: 13px; }
.im-dname { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 6px; }
.im-dname .im-title { font-size: 14px; font-weight: 600; }
.im-delete { flex: 0 0 auto; display: inline-grid; place-items: center; width: 26px; height: 26px; border: 0; border-radius: 6px; background: transparent; color: var(--muted); cursor: pointer; }
.im-delete:hover, .im-delete:focus-visible { color: var(--danger); background: var(--active-item, rgba(127, 127, 127, .14)); outline: none; }
.im-delete svg { width: 15px; height: 15px; }
.im-confirm { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 8px; padding: 8px 10px; border: 1px solid var(--amber); border-radius: 7px; font-size: 12px; line-height: 1.4; }
.im-confirm span { display: inline-flex; align-items: center; gap: 10px; margin-left: auto; }
.im-preview { position: relative; display: grid; place-items: center; width: 100%; max-width: 320px; aspect-ratio: 4 / 3; margin: 12px auto 0; border-radius: 8px; background: var(--panel-2, var(--bg)); overflow: hidden; }
.im-preview .im-pic { width: 100%; height: 100%; object-fit: contain; }
.im-preview .im-glyph svg { width: 40px; height: 40px; }
.im-dfacts { display: flex; flex-direction: column; gap: 2px; margin-top: 10px; font-size: 12px; line-height: 1.4; color: var(--muted); }
.im-dfacts div { min-height: 17px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.im-dfacts div:first-child { color: var(--ink); font-weight: 500; }
.im-rule { width: 100%; height: 0; margin: 12px 0; border: 0; border-top: 1px solid var(--line); }
.im-ctrl { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; margin-top: 8px; font-size: 12px; } /* a very narrow pane wraps Up axis under Units */
.im-ctrl label { flex: 0 0 auto; width: 56px; color: var(--muted); text-align: right; }
.im-ctrl label + label { width: auto; margin-left: 6px; }
.im-ctrl select { flex: 0 1 auto; min-width: 0; }
.im-ctrl .im-units, .im-ctrl .im-axis { flex: 1 1 0; min-width: 58px; max-width: 120px; } /* outranks .im-ctrl select: never so narrow that the chosen unit is hidden */
.im-version { width: 100%; }
.im-width { width: 82px; height: 26px; padding: 0 8px; border: 1px solid var(--line); border-radius: 7px; background: var(--bg); color: var(--ink); font: inherit; font-size: 12px; }
.im-width:focus { outline: none; border-color: var(--accent-text); }
.im-unit { color: var(--muted); }
.im-tall { color: var(--muted); }
.im-update-row { margin: 8px 0 0 64px; font-size: 12px; }
.im-update-row .sh-textbtn { white-space: normal; text-align: left; }
.im-warning { margin: 8px 0 0 64px; font-size: 11.5px; line-height: 1.4; color: var(--amber); }
.im-failed-box { margin-top: 8px; font-size: 12px; line-height: 1.5; }
.im-failed-box > div { margin-top: 6px; }
.im-muted { color: var(--muted); }
.im-block { display: flex; flex-direction: column; gap: 6px; }
.im-block-head { font-size: 12.5px; font-weight: 600; color: var(--ink); }
.im-block-text { font-size: 11.5px; line-height: 1.4; color: var(--muted); }
.im-block-row { display: flex; gap: 8px; margin-top: 2px; }
.im-block-row .header-btn { flex: 1 1 0; height: 30px; font-size: 12px; font-weight: 600; }
.im-primary { display: inline-flex; align-items: center; justify-content: center; gap: 8px; width: 100%; height: 30px; margin-top: 2px; padding: 0 14px; border: 1px solid var(--accent); border-radius: 7px; background: var(--accent); color: #fff; font: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer; transition: background .15s ease, color .15s ease; }
.im-primary svg { width: 14px; height: 14px; }
.im-primary:hover:not(:disabled), .im-primary:focus-visible { filter: brightness(1.06); outline: none; }
.im-primary:disabled { border-color: var(--line); background: var(--panel-2, var(--bg)); color: var(--muted); cursor: default; }
.im-primary[aria-pressed="true"] { background: var(--accent-soft); color: var(--accent-text); }
#placing-banner { position: absolute; top: 10px; left: 50%; transform: translateX(-50%); z-index: 3; display: flex; align-items: center; gap: 10px; max-width: calc(100% - 20px); padding: 5px 5px 5px 12px; background: var(--panel); color: var(--ink); border: 1px solid var(--accent-text); border-radius: 9px; box-shadow: 0 8px 24px rgba(0, 0, 0, .18); font-size: 12.5px; white-space: nowrap; }
#placing-banner[hidden] { display: none; }
.pb-glyph { display: inline-flex; flex: 0 0 auto; color: var(--accent-text); }
.pb-glyph svg { width: 16px; height: 16px; }
.pb-text { font-weight: 600; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.pb-hint { color: var(--muted); }

/* ---- Group chat (group-chat.js) ---- */
/* The two tabs under the chat header, in the idiom of the chats list's former Chats | Scenes tabs: the open one in ink
   with the accent line, a 6px dot on the other when it has messages you have not seen. */
#chat-tabs { flex: 0 0 auto; display: flex; margin: 0 18px; border-bottom: 1px solid var(--line); }
#chat-tabs[hidden] { display: none; }
.chat-tab {
  flex: 1 1 0; display: inline-flex; align-items: center; justify-content: center; gap: 6px; padding: 6px 0 7px; margin-bottom: -1px;
  border: 0; border-bottom: 2px solid transparent; background: transparent; color: var(--muted); font: inherit; font-size: 12.5px; line-height: 1.3;
  cursor: pointer; transition: color .15s ease;
}
.chat-tab:hover, .chat-tab:focus-visible { color: var(--ink); outline: none; }
.chat-tab[aria-selected="true"] { color: var(--ink); font-weight: 600; border-bottom-color: var(--tool-line); }
.tab-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); }
.tab-dot[hidden] { display: none; }
/* The group pane takes the agent transcript's and composer's place while its tab is open. */
#group-chat { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
#group-chat[hidden] { display: none; }
#chat.group-chat-active > #chat-metrics, #chat.group-chat-active > #diagnostic-status, #chat.group-chat-active > #tutorial-panel,
#chat.group-chat-active > #messages, #chat.group-chat-active > #prompt-queue, #chat.group-chat-active > #composer { display: none; }
/* the transcript: the agent transcript's column, bottom-anchored; a day label opens each day */
.gc-log { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 20px 18px; display: flex; flex-direction: column; gap: 14px; }
.gc-log > :first-child { margin-top: auto; }
.gc-day { align-self: stretch; color: var(--muted); font-size: 12.5px; border-top: 1px solid var(--line); padding: 12px 2px 0; }
.gc-day:first-child { border-top: 0; padding-top: 0; }
/* a run: one sender's consecutive messages under one sender line; mine right-aligned with no line */
.gc-run { display: flex; flex-direction: column; gap: 6px; max-width: 84%; }
.gc-run.other { align-self: flex-start; align-items: flex-start; }
.gc-run.me { align-self: flex-end; align-items: flex-end; }
.gc-who { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--muted); }
.gc-avatar { flex: 0 0 auto; width: 18px; height: 18px; display: grid; place-items: center; border-radius: 50%; color: #fff; font-size: 10px; font-weight: 600; line-height: 1; }
.gc-name { font-weight: 600; color: var(--ink); }
.gc-msg { position: relative; display: flex; flex-direction: column; gap: 6px; max-width: 100%; outline: none; }
.gc-run.me .gc-msg { align-items: flex-end; }
/* someone else's bubble is the agent transcript's second surface with a hairline, squared at the bottom left; mine is the
   user bubble squared at the bottom right, as in the agent chat */
.gc-bubble { position: relative; max-width: 100%; padding: 11px 15px; border-radius: 16px; white-space: pre-wrap; overflow-wrap: anywhere; transition: border-color .15s ease; }
.gc-run.other .gc-bubble { border: 1px solid var(--line); border-bottom-left-radius: 6px; background: var(--panel-2); color: var(--ink); }
.gc-run.other .gc-msg:hover .gc-bubble, .gc-run.other .gc-msg.is-open .gc-bubble { border-color: var(--muted); }
.gc-run.me .gc-bubble { border-bottom-right-radius: 6px; background: var(--user-bubble); color: var(--user-ink); }
.gc-msg.is-dim .gc-bubble { opacity: .55; }
.gc-edited { margin-left: 6px; font-size: 11px; color: var(--muted); }
.gc-text a { color: var(--accent-text); text-decoration: none; border-bottom: 1px solid color-mix(in srgb, var(--accent-text) 45%, transparent); word-break: break-all; }
/* the actions at the bubble's top edge under the pointer (or keyboard focus): React on theirs, Edit and Unsend on mine */
.gc-actions {
  position: absolute; top: -15px; right: 10px; z-index: 2; display: none; gap: 2px; padding: 2px;
  border: 1px solid var(--line); border-radius: 8px; background: var(--panel); box-shadow: 0 4px 14px rgba(0, 0, 0, .10);
}
.gc-run.me .gc-actions { right: auto; left: 10px; }
.gc-msg:hover .gc-actions, .gc-msg:focus-within .gc-actions, .gc-msg.is-open .gc-actions { display: flex; }
.gc-act { width: 26px; height: 26px; display: grid; place-items: center; padding: 0; border: 0; border-radius: 6px; background: transparent; color: var(--muted); cursor: pointer; }
.gc-act:hover, .gc-act:focus-visible, .gc-act[aria-expanded="true"] { background: var(--active-item, rgba(127, 127, 127, .14)); color: var(--ink); outline: none; }
.gc-act svg { width: 15px; height: 15px; }
/* the reaction picker above the strip, in the mic picker's chrome; the chips under the bubble, mine in the accent */
.gc-picker {
  position: absolute; top: -48px; right: 10px; z-index: 3; display: flex; gap: 2px; padding: 4px;
  border: 1px solid var(--line); border-radius: 8px; background: var(--panel); box-shadow: 0 10px 30px rgba(0, 0, 0, .18);
}
.gc-picker button { width: 32px; height: 32px; padding: 0; border: 0; border-radius: 6px; background: transparent; font-size: 18px; line-height: 1; cursor: pointer; }
.gc-picker button:hover, .gc-picker button:focus-visible, .gc-picker button[aria-pressed="true"] { background: var(--active-item, rgba(127, 127, 127, .14)); outline: none; }
.gc-reactions { display: flex; flex-wrap: wrap; gap: 6px; }
.gc-run.me .gc-reactions { justify-content: flex-end; }
.gc-react {
  display: inline-flex; align-items: center; gap: 5px; height: 24px; padding: 0 8px 0 7px; border: 1px solid var(--line); border-radius: 12px;
  background: var(--panel); color: var(--ink); font: inherit; font-size: 12px; cursor: pointer; transition: border-color .15s ease;
}
.gc-react > span:first-child { font-size: 13px; line-height: 1; }
.gc-react:hover:not(.is-static), .gc-react:focus-visible { border-color: var(--muted); outline: none; }
.gc-react[aria-pressed="true"] { border-color: var(--accent-text); background: var(--accent-soft); }
.gc-react.is-static { cursor: default; }
/* what a message carries: a render or a clip as the agent chat's frame, an agent message as a quote */
.gc-card {
  position: relative; display: block; width: 220px; max-width: 100%; margin: 0 0 8px; padding: 0; overflow: hidden;
  border: 1px solid var(--line); border-radius: 10px; background: var(--panel-2); color: var(--muted); font: inherit; cursor: pointer; transition: border-color .15s ease;
}
.gc-card img, .gc-card video { display: block; width: 100%; height: 100%; object-fit: cover; }
.gc-card:hover:not(:disabled), .gc-card:focus-visible { border-color: var(--accent-text); outline: none; }
.gc-card:disabled { cursor: default; }
.gc-card-empty { position: absolute; inset: 0; display: grid; place-items: center; font-size: 12.5px; }
.gc-quote { margin: 0 0 8px; padding: 2px 0 2px 10px; border-left: 2px solid var(--accent); }
.gc-quote-from { margin-bottom: 3px; font-size: 11px; font-weight: 600; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); }
.gc-quote-text { font-size: 14px; line-height: 1.45; }
/* editing in place: the bubble becomes the input; the two quiet words under a bubble (Save · Cancel, Unsend · Keep) */
.gc-edit {
  width: 100%; min-width: 220px; resize: none; overflow: hidden; padding: 10px 14px; border: 1px solid var(--accent-text); border-radius: 16px; border-bottom-right-radius: 6px;
  background: var(--bg); color: var(--ink); font: inherit; line-height: 1.5;
}
.gc-edit:focus { outline: none; }
.gc-words { display: flex; gap: 12px; padding: 0 6px; font-size: 12px; color: var(--muted); }
.gc-words button { padding: 0; border: 0; background: transparent; color: var(--accent-text); font: inherit; font-size: 12px; font-weight: 600; cursor: pointer; white-space: nowrap; }
.gc-words button:hover, .gc-words button:focus-visible { text-decoration: underline; outline: none; }
.gc-words button.is-muted { color: var(--muted); }
.gc-words button.is-danger { color: var(--danger); }
/* before anyone has written; a notice from the relay over the composer */
.gc-empty { margin: auto; text-align: center; color: var(--muted); max-width: 260px; }
.gc-empty h2 { font-size: 15px; font-weight: 600; color: var(--ink); margin: 0 0 6px; }
.gc-empty p { margin: 0; font-size: 13px; }
.gc-notice { flex: 0 0 auto; padding: 0 18px 8px; font-size: 12px; color: var(--muted); }
.gc-notice[hidden] { display: none; }
/* the composer: the agent composer's chrome and row (#group-input and #group-send share #input's and #send's rules) */
.gc-composer { flex: 0 0 auto; display: flex; flex-direction: column; gap: 8px; padding: 14px; border-top: 1px solid var(--line); background: var(--panel-2); }
.gc-row { display: flex; gap: 10px; }
/* what was shared, waiting above the input as chips - a render with its thumbnail, an agent message as a quote chip */
.gc-staged { display: flex; flex-wrap: wrap; gap: 6px; }
.gc-staged[hidden] { display: none; }
.gc-chip { display: inline-flex; align-items: center; gap: 8px; max-width: 100%; height: 40px; padding: 0 6px 0 4px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel); font-size: 12px; color: var(--ink); }
.gc-chip-thumb { flex: 0 0 auto; width: 32px; height: 32px; display: grid; place-items: center; border-radius: 5px; overflow: hidden; background: var(--panel-2); color: var(--accent-text); }
.gc-chip-thumb img { display: block; width: 100%; height: 100%; object-fit: cover; }
.gc-chip-thumb.is-quote { background: color-mix(in srgb, var(--accent) 16%, transparent); }
.gc-chip-thumb svg { width: 15px; height: 15px; }
.gc-chip-label { min-width: 0; max-width: 210px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.gc-chip-remove { width: 20px; height: 20px; display: grid; place-items: center; padding: 0; border: 0; border-radius: 5px; background: transparent; color: var(--muted); cursor: pointer; }
.gc-chip-remove:hover, .gc-chip-remove:focus-visible { background: var(--line); color: var(--ink); outline: none; }
.gc-chip-remove svg { width: 11px; height: 11px; }
/* the way in from the agent chat: the share glyph at a render card's caption end and at an agent message's top right,
   shown when the pointer is on the card or the message */
.gc-share-btn { flex: 0 0 auto; width: 22px; height: 22px; display: grid; place-items: center; padding: 0; border: 0; border-radius: 5px; background: transparent; color: var(--muted); cursor: pointer; opacity: 0; transition: opacity .15s ease; }
.gc-share-btn svg { width: 14px; height: 14px; }
.render-card:hover .gc-share-btn, .msg.agent:hover .gc-share-btn, .gc-share-btn:focus-visible, .gc-share-btn:hover { opacity: 1; }
.gc-share-btn:hover, .gc-share-btn:focus-visible { background: var(--active-item, rgba(127, 127, 127, .14)); color: var(--ink); outline: none; }
.msg.agent.has-share { position: relative; padding-right: 30px; }
.msg.agent .gc-share-btn { position: absolute; top: -2px; right: 0; }

/* History pages preserve the transcript anchor; media fetches are triggered only near the viewport. */
.gc-history { flex: 0 0 auto; align-self: center; margin: 8px; }
.gc-history[hidden] { display: none; }

/* ---- Group chat files (group-chat.js addFiles, chipHtml, renderSending) ---- */
/* the paperclip in the mic button's place and chrome; the pane rings its composer while files are dragged over it */
#attach, #group-attach {
  flex: 0 0 auto; align-self: flex-end; display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; padding: 0; border: 1px solid var(--line); border-radius: 10px; background: var(--bg); color: var(--ink); cursor: pointer;
}
#attach svg, #group-attach svg { width: 19px; height: 19px; }
#attach:hover:not(:disabled), #attach:focus-visible, #group-attach:hover:not(:disabled), #group-attach:focus-visible { border-color: var(--accent-text); outline: none; }
#attach:disabled, #group-attach:disabled { opacity: .4; cursor: default; }
#group-chat.is-drop .gc-composer, #chat.is-drop #composer { box-shadow: inset 0 0 0 2px var(--accent); } /* a file drag over the pane */
/* a chip's body: the name (with the size in muted for a file) and, while on its way, the bar under it */
.gc-sending { display: flex; flex-wrap: wrap; gap: 6px; }
.gc-sending[hidden] { display: none; }
.gc-chip.is-sending { height: 44px; padding-right: 10px; }
.gc-chip-body { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.gc-chip-size { color: var(--muted); }
.gc-bar { display: block; height: 3px; border-radius: 2px; background: var(--line); overflow: hidden; }
.gc-bar > span { display: block; height: 100%; border-radius: 2px; background: var(--accent); transition: width .2s ease; }
/* a file in a bubble: the glyph, the name and the size, a download arrow; pressing it saves the file */
.gc-file {
  display: flex; align-items: center; gap: 10px; width: 240px; max-width: 100%; margin: 0 0 8px; padding: 7px 10px 7px 7px;
  border: 1px solid var(--line); border-radius: 10px; background: var(--panel); color: var(--ink); font: inherit; text-align: left; cursor: pointer; transition: border-color .15s ease;
}
.gc-file:hover, .gc-file:focus-visible { border-color: var(--accent-text); outline: none; }
.gc-file:hover .gc-file-dl { color: var(--ink); }
.gc-file.is-busy { cursor: progress; }
.gc-file-glyph { flex: 0 0 auto; width: 32px; height: 32px; display: grid; place-items: center; border-radius: 6px; background: var(--panel-2); color: var(--muted); }
.gc-file-glyph svg { width: 16px; height: 16px; }
.gc-file-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.gc-file-name { font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.gc-file-size { font-size: 11.5px; color: var(--muted); }
.gc-file-dl { flex: 0 0 auto; color: var(--muted); }
.gc-file-dl svg { width: 15px; height: 15px; }
/* my run's time, where other people's sender line is */
.gc-run.me .gc-who { justify-content: flex-end; }
/* a message of mine still on its way after a moment: Sending… after its words, as the edited mark sits; it appears only
   once the store has taken longer than the eye expects, so a quick save never flashes it */
.gc-pending { margin-left: 6px; font-size: 11px; color: var(--muted); opacity: 0; animation: gc-pending-in .2s ease .8s forwards; }
@keyframes gc-pending-in { to { opacity: 1; } }

/* ---- Attachments in the agent chat (attachment-thumbs.js, app.js addUserMessage, agent-prompt-queue.js stage) ---- */
/* the files of a sent message: the group chat's chips under my bubble, on its side */
.msg-files { align-self: flex-end; max-width: 84%; display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 6px; margin-top: -8px; }
/* a queued message's chips inside its waiting bubble; a message on its way to the queue and the muted word under it */
.pq-files { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.pq-item.is-staging { grid-template-columns: minmax(0, 1fr); }
.pq-staging { justify-self: end; padding-right: 6px; font-size: 12px; color: var(--muted); }

/* Web section controls inherit the Scene panel's density. Hidden groups must not retain flex layout. */
/* Section card (scene-settings.js): the placement and direction strips, the horizontal/Face position field, the range through
   the model, Removes with Flip beside it, Place again, the picking hint; and the banner over the player (#section-banner),
   the History banner's place and shape, lighter, accent-bordered while the plane is live. */
.sc-section-controls { display: flex; flex-direction: column; gap: 10px; }
.sc-section-controls[hidden], .sc-section-directions[hidden], .sc-head .sc-section-adjust[hidden], .sc-section-sweep[hidden], .sc-section-removes-row[hidden], .sc-section-again-row[hidden], .sc-section-hint[hidden] { display: none; }
.sc-section-distance { display: flex; align-items: center; gap: 8px; color: var(--muted); font-size: 12px; }
.sc-section-offset { width: 88px; height: 28px; padding: 0 8px; border: 1px solid var(--line); border-radius: 7px; background: var(--bg); color: var(--ink); font: inherit; font-size: 12.5px; font-variant-numeric: tabular-nums; }
.sc-section-offset:disabled, .sc-section-range:disabled { opacity: .55; }
.sc-section-sweep { display: flex; flex-direction: column; gap: 2px; margin-top: -4px; }
.sc-section-range { width: 100%; height: 18px; margin: 0; accent-color: var(--range-accent); cursor: pointer; }
.sc-section-range:disabled { cursor: default; }
.sc-section-ends { display: flex; justify-content: space-between; font-size: 10.5px; color: var(--muted); }
.sc-section-removes { display: inline-flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--ink); white-space: nowrap; }
.sc-section-hint { padding: 8px 10px; border-radius: 7px; background: var(--panel-2); font-size: 11.5px; line-height: 1.4; color: var(--muted); }
.sc-section-controls .rv-strip button:focus-visible { outline: 2px solid var(--accent-text); outline-offset: 1px; }
#section-banner { position: absolute; top: 10px; left: 50%; transform: translateX(-50%); z-index: 3; display: flex; align-items: center; gap: 12px; max-width: calc(100% - 20px); padding: 5px 5px 5px 12px; background: var(--panel); color: var(--ink); border: 1px solid var(--line); border-radius: 9px; box-shadow: 0 8px 24px rgba(0, 0, 0, .18); font-size: 12.5px; line-height: 1.3; white-space: nowrap; }
#section-banner[hidden] { display: none; }
#section-banner.is-live { border-color: var(--accent-text); }
.sb-glyph { display: inline-flex; color: var(--muted); flex: 0 0 auto; }
#section-banner.is-live .sb-glyph { color: var(--accent-text); }
.sb-glyph svg { width: 16px; height: 16px; }
.sb-text { font-weight: 600; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
#unity-canvas.section-picking { cursor: crosshair; }

/* ---- first run: the welcome and shared-scene cards, the login card, the refusal ---- */
/* The first-visit welcome and the shared-scene card replace the centred placeholder and take the pane's width; the
   login card joins the transcript at its foot. Buttons are real buttons, disabled until the editor is writable. */
#empty.welcome, #empty.shared { max-width: none; width: 100%; margin: auto 0; text-align: left; display: flex; flex-direction: column; gap: 20px; color: var(--muted); }
#empty.welcome h2, #empty.shared h2 { font-size: 18px; line-height: 1.3; margin: 0 0 6px; }
#empty.welcome p, #empty.shared p { font-size: 13.5px; line-height: 1.5; }
.fr-section { display: flex; flex-direction: column; gap: 8px; }
.fr-starter { display: flex; align-items: center; gap: 10px; min-height: 44px; padding: 10px 12px; border: 1px solid var(--line); border-radius: 9px; background: var(--panel-2); color: var(--ink); font: inherit; font-size: 13.5px; line-height: 1.35; text-align: left; cursor: pointer; transition: border-color .15s ease; }
.fr-starter span { flex: 1 1 auto; }
.fr-starter svg { flex: 0 0 auto; width: 16px; height: 16px; color: var(--muted); }
.fr-starter:hover:not(:disabled), .fr-starter:focus-visible { border-color: var(--accent-text); outline: none; }
.fr-card { display: flex; flex-direction: column; gap: 10px; padding: 12px; border: 1px solid var(--line); border-radius: 9px; }
.fr-card.login { flex: 0 0 auto; border-color: var(--accent-text); background: var(--panel-2); box-shadow: 0 12px 32px rgba(0, 0, 0, .35); }
.fr-card-title { display: flex; align-items: center; gap: 8px; font-size: 13.5px; font-weight: 600; color: var(--ink); }
.fr-dot { flex: 0 0 auto; width: 7px; height: 7px; border-radius: 50%; background: var(--accent); }
.fr-meta { margin-left: auto; font-size: 12px; font-weight: 400; color: var(--muted); white-space: nowrap; }
.fr-card p { margin: 0; font-size: 13px; line-height: 1.5; color: var(--muted); }
.fr-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.fr-btn { display: inline-flex; align-items: center; justify-content: center; height: 32px; padding: 0 12px; border: 1px solid var(--line); border-radius: 7px; background: transparent; color: var(--ink); font: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer; transition: border-color .15s ease, color .15s ease; }
.fr-btn:hover:not(:disabled), .fr-btn:focus-visible { border-color: var(--accent-text); outline: none; }
.fr-btn.primary { border-color: var(--accent); background: var(--accent); color: var(--accent-ink); }
.fr-btn.primary:hover:not(:disabled) { opacity: .9; }
.fr-starter:disabled, .fr-btn:disabled { opacity: .45; cursor: default; }
.fr-note { font-size: 12px; line-height: 1.45; color: var(--muted); }
.fr-live { font-size: 12.5px; color: var(--accent-text); }


/* The refusal card: the capability gate's verdict in place of the storage-error sentence. The loading veil behind it,
   #session-state's z so nothing paints over it; the address field shows only when the clipboard is unavailable. */
#boot-refused { position: absolute; inset: 0; z-index: 4; display: grid; place-items: center; padding: 32px; background: radial-gradient(120% 120% at 50% 40%, #112A27 0%, #0A1213 100%); color: #E8EEEC; } /* the veil stays dark in both themes, so its text is fixed light */
#boot-refused[hidden] { display: none; }
.br-card { display: flex; flex-direction: column; gap: 14px; width: min(480px, 100%); padding: 24px; border: 1px solid var(--line); border-radius: 12px; background: var(--panel); color: var(--ink); }
.br-glyph { width: 28px; height: 28px; color: var(--muted); }
.br-card h2 { margin: 0; font-size: 18px; font-weight: 600; line-height: 1.3; }
.br-card p { margin: 0; font-size: 13.5px; line-height: 1.5; color: var(--muted); }
#boot-refused-list { display: flex; flex-direction: column; gap: 10px; margin: 0; padding: 0; list-style: none; font-size: 13px; line-height: 1.45; color: var(--muted); }
#boot-refused-list[hidden] { display: none; }
#boot-refused-list li { display: flex; gap: 10px; align-items: flex-start; }
#boot-refused-list svg { flex: 0 0 auto; width: 18px; height: 18px; margin-top: 1px; color: var(--muted); }
#boot-refused-list li:first-child svg { color: var(--accent-text); }
#boot-refused-list strong { font-weight: 600; color: var(--ink); }
.br-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.br-actions .header-btn { display: inline-flex; align-items: center; height: 32px; padding: 0 12px; font-size: 12.5px; font-weight: 600; text-decoration: none; }
#boot-copy-status { font-size: 12px; color: var(--muted); }
#boot-link { width: 100%; height: 32px; padding: 0 10px; border: 1px solid var(--line); border-radius: 7px; background: var(--bg); color: var(--ink); font: inherit; font-size: 12.5px; }
#boot-link[hidden] { display: none; }
/* Selection bar (selection-bar.js): the verbs that apply to the Select tool's selection, over the player in the Section
   banner's shape; under it when both show. A refusal line wraps onto a second row inside the pill. */
#selection-bar { position: absolute; top: 10px; left: 50%; transform: translateX(-50%); z-index: 3; display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 4px 10px; max-width: calc(100% - 20px); padding: 5px 6px 5px 12px; background: var(--panel); color: var(--ink); border: 1px solid var(--line); border-radius: 9px; box-shadow: 0 8px 24px rgba(0, 0, 0, .18); font-size: 12.5px; line-height: 1.3; white-space: nowrap; }
#selection-bar[hidden] { display: none; }
/* Tool modes: the selection pill's tool glyph and spacing, followed by one action for the alternate mode. */
.tool-mode-bar { position: absolute; top: 10px; left: 50%; transform: translateX(-50%); z-index: 3; display: flex; align-items: center; gap: 10px; max-width: calc(100% - 20px); padding: 5px 6px 5px 12px; background: var(--panel); color: var(--ink); border: 1px solid var(--line); border-radius: 9px; box-shadow: 0 8px 24px rgba(0, 0, 0, .18); }
.tool-mode-bar[hidden] { display: none; }
#section-banner:not([hidden]) ~ .tool-mode-bar, #placing-banner:not([hidden]) ~ .tool-mode-bar { top: 54px; }
#section-banner:not([hidden]) ~ #selection-bar, #placing-banner:not([hidden]) ~ #selection-bar { top: 54px; }
.sl-glyph { display: inline-flex; color: var(--muted); flex: 0 0 auto; }
.sl-glyph svg { width: 16px; height: 16px; }
.sl-verbs { display: flex; align-items: center; gap: 6px; }
.sl-note { flex: 0 0 100%; padding: 0 4px 2px; text-align: center; font-size: 11.5px; color: var(--muted); white-space: normal; }
.sl-note[hidden] { display: none; }
/* Sketch bar (sketch-bar.js): the Sketch tool's pill in the selection bar's shape: In scene and On screen as the bar's verbs
   with the chosen one pressed, a rule, the six inks as dots with the chosen one ringed, and with On screen pressed a rule,
   the eraser and Send to agent, quiet until there are marks. Under a banner it drops as the selection bar does. */
#sketch-bar { position: absolute; top: 10px; left: 50%; transform: translateX(-50%); z-index: 3; display: flex; align-items: center; gap: 10px; max-width: calc(100% - 20px); padding: 5px 12px; background: var(--panel); color: var(--ink); border: 1px solid var(--line); border-radius: 9px; box-shadow: 0 8px 24px rgba(0, 0, 0, .18); font-size: 12.5px; line-height: 1.3; white-space: nowrap; }
#sketch-bar[hidden] { display: none; }
#section-banner:not([hidden]) ~ #sketch-bar, #placing-banner:not([hidden]) ~ #sketch-bar { top: 54px; }
.sk-glyph { display: inline-flex; color: var(--muted); flex: 0 0 auto; }
.sk-glyph svg { width: 16px; height: 16px; }
.sk-modes, .sk-paper { display: flex; align-items: center; gap: 6px; }
.sk-paper { gap: 10px; }
.sk-paper[hidden] { display: none; }
.sk-rule { flex: 0 0 1px; width: 1px; height: 18px; background: var(--line); }
.sk-mode { display: inline-flex; align-items: center; gap: 5px; height: 26px; padding: 0 9px; font-size: 11.5px; }
.sk-mode[aria-pressed="true"] { color: var(--accent-text); font-weight: 600; }
.sk-mode svg { width: 12px; height: 12px; }
.sk-inks { display: flex; align-items: center; gap: 10px; padding: 0 2px; }
.sk-ink { width: 16px; height: 16px; padding: 0; border: 0; border-radius: 50%; background: var(--ink-hex); box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .14); cursor: pointer; }
.sk-ink:hover, .sk-ink:focus-visible { box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .14), 0 0 0 2px var(--panel), 0 0 0 4px var(--muted); outline: none; }
.sk-ink[aria-checked="true"] { box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .14), 0 0 0 2px var(--panel), 0 0 0 4px var(--accent); }
.sk-clear { width: 26px; height: 26px; padding: 0; display: grid; place-items: center; }
.sk-clear svg { width: 15px; height: 15px; }
.sk-send { height: 26px; padding: 0 10px; border: 1px solid var(--accent); border-radius: 5px; background: var(--accent); color: var(--accent-ink); font: inherit; font-size: 11.5px; font-weight: 600; cursor: pointer; transition: background .15s ease, border-color .15s ease; }
.sk-send:hover:not(:disabled), .sk-send:focus-visible { background: var(--accent-hover); border-color: var(--accent-hover); outline: none; }
.sk-send:disabled { background: transparent; color: var(--muted); border-color: var(--line); opacity: .6; cursor: default; }
/* The tracing paper (tracing-paper.js): the layer takes the player's box and the pointer; the sheet is inset from the
   edges so it reads as a sheet laid on the view, slightly white and see-through, a hairline edge, a shadow; the ink
   canvas covers the layer; the × sits in the sheet's corner. While it is down the joysticks go and the header's
   navigation buttons sleep, since the camera is held. */
#paper { position: absolute; inset: 0; z-index: 2; cursor: crosshair; touch-action: none; }
#paper[hidden] { display: none; }
.paper-sheet { position: absolute; inset: 24px; border-radius: 3px; background: rgba(255, 255, 255, .18); border: 1px solid rgba(255, 255, 255, .6); box-shadow: 0 12px 40px rgba(0, 0, 0, .28); pointer-events: none; }
.paper-ink { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.paper-lift { position: absolute; right: 32px; top: 32px; width: 26px; height: 26px; padding: 0; border: 0; border-radius: 50%; background: rgba(255, 255, 255, .94); color: #1B2526; box-shadow: 0 2px 8px rgba(0, 0, 0, .25); display: grid; place-items: center; cursor: pointer; }
.paper-lift:hover, .paper-lift:focus-visible { background: #EEF1EF; outline: none; }
.paper-lift svg { width: 13px; height: 13px; }
body.paper-down #joysticks { display: none; }
body.paper-down #navigate .tool { color: var(--tool-ink-off); pointer-events: none; }
/* Dimension pills (dimensions.js) over the player: the shell's type where Unity measured, an editable one a button; the
   active (being edited) one takes the accent; the drag readout follows the pointer. The hint strip (hints.js) at the foot. */
#dimension-layer { position: absolute; inset: 0; z-index: 2; overflow: hidden; pointer-events: none; }
#dimension-layer[hidden] { display: none; }
.dim-pill { position: absolute; left: 0; top: 0; padding: 3px 8px; border: 1px solid var(--line); border-radius: 6px; background: var(--panel); color: var(--ink); box-shadow: 0 2px 8px rgba(0, 0, 0, .18); font: inherit; font-size: 12.5px; font-variant-numeric: tabular-nums; line-height: 1.3; white-space: nowrap; pointer-events: auto; cursor: pointer; }
.dim-pill.is-static, .dim-pill.is-readout { pointer-events: none; cursor: default; }
.dim-pill.is-area, .dim-pill.is-line { color: var(--muted); }
.dim-pill.is-readout { font-weight: 600; }
.dim-pill:hover, .dim-pill.is-active { border-color: var(--accent-text); }
.dim-pill.is-active { background: var(--accent-soft); }
.dim-pill.is-along { transform-origin: 0 0; border-color: transparent; box-shadow: none; padding: 1px 6px; background: color-mix(in srgb, var(--panel) 85%, transparent); } /* along its line (labelPose): origin 0 0, so the transform's translate(-50%, -50%) puts the centre on the point it turns about */
.dim-pill.is-along.is-active, .dim-pill.is-along:hover { border-color: var(--accent-text); }
.dim-pill.is-along.is-active { background: var(--accent-soft); }
.dim-pill[hidden] { display: none; } /* a line too short on screen to carry its label hides it */
#hint-strip { position: absolute; left: 50%; bottom: 14px; transform: translateX(-50%); z-index: 3; display: block; max-width: calc(100% - 24px); padding: 6px 12px; border: 1px solid var(--line); border-radius: 9px; background: var(--panel); color: var(--muted); box-shadow: 0 8px 24px rgba(0, 0, 0, .18); font-size: 12px; line-height: 1.5; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; pointer-events: none; }
#hint-strip[hidden] { display: none; }
#hint-strip kbd { display: inline-block; min-width: 18px; margin: 0 1px; padding: 0 5px; border: 1px solid var(--line); border-bottom-width: 2px; border-radius: 4px; background: var(--panel-2); color: var(--ink); font: inherit; font-size: 11px; line-height: 16px; text-align: center; vertical-align: 1px; }
/* A first-run hint card steps under the selection bar or the sketch bar when both are up at the top of the player. */
/* The login card in the chat points at the footer form; openLogin rings the form for a moment so the eye finds it. */
#account.ac-attention .ac-form, #account.ac-attention .ac-login { border-color: var(--accent-text); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 45%, transparent); animation: ac-attention 1.2s ease-in-out 3; }
@keyframes ac-attention { 0%, 100% { box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 45%, transparent); } 50% { box-shadow: 0 0 0 6px color-mix(in srgb, var(--accent) 20%, transparent); } }
@media (prefers-reduced-motion: reduce) { #account.ac-attention .ac-form, #account.ac-attention .ac-login { animation: none; } }
/* The lesson card's own text when the player runs lessons itself (tutorial-card.js); empty on the tutor's player. */
#tutorial-text { font-size: 13px; line-height: 1.45; color: var(--ink); }
#tutorial-text:empty { display: none; }
#tutorial-actions #tutorial-new-chat[hidden], #tutorial-actions #tutorial-render[hidden], #tutorial-actions #tutorial-continue[hidden], #tutorial-actions #tutorial-skip[hidden] { display: none; }
/* The lesson card's checklist (one criteria term per line, ticked live) and its how-to behind Show steps. */
#tutorial-checks { margin: 0; padding: 0; list-style: none; display: grid; gap: 3px; font-size: 12.5px; color: var(--muted); }
#tutorial-checks:empty { display: none; }
#tutorial-checks li { display: flex; align-items: baseline; gap: 7px; }
#tutorial-checks li::before { content: "\25CB"; flex: none; font-size: 11px; color: var(--muted); }
#tutorial-checks li.done { color: var(--ink); }
#tutorial-checks li.done::before { content: "\2713"; color: var(--accent-text); font-weight: 700; }
#tutorial-steps-toggle { align-self: flex-start; padding: 0; border: 0; background: none; font: inherit; font-size: 12.5px; color: var(--accent-text); cursor: pointer; }
#tutorial-steps-toggle:hover, #tutorial-steps-toggle:focus-visible { text-decoration: underline; outline: none; }
#tutorial-steps-toggle[hidden] { display: none; }
#tutorial-steps { margin: 0; padding-left: 18px; display: grid; gap: 3px; font-size: 12.5px; line-height: 1.4; color: var(--ink); }
#tutorial-steps[hidden] { display: none; }

/* ---- the account footer as one button, and the Account sheet (account-sheet.js) ----
   The signed-in card keeps the ring, the count and the email and becomes the button that opens the sheet: a chevron
   at the end of the email says so, a tint marks hover, the pressed state stays while the sheet is open. The sheet is
   centred over the dimmed shell, in the render viewer's chrome; under 720 px it fills the window and the tabs move
   under the title. Cards on the panel background; the ring is ring.js's. */
.ac-in { width: 100%; text-align: left; font: inherit; color: var(--ink); cursor: pointer; transition: border-color .15s ease, background .15s ease; }
.ac-in:hover:not(:disabled), .ac-in:focus-visible { background: var(--panel-2); border-color: var(--accent-text); outline: none; }
.ac-in[aria-expanded="true"] { border-color: var(--accent-text); background: var(--accent-soft); }
.ac-in:disabled { opacity: .6; cursor: default; }
.ac-email-row { display: flex; align-items: center; gap: 6px; min-width: 0; }
.ac-email-row .ac-email-line { flex: 1 1 auto; min-width: 0; }
.ac-chevron { flex: 0 0 auto; width: 12px; height: 12px; color: var(--muted); }
#account-sheet { position: fixed; inset: 0; z-index: 24; display: grid; place-items: center; padding: 24px; }
#account-sheet[hidden] { display: none; }
.as-scrim { position: absolute; inset: 0; background: rgba(4, 8, 6, .5); backdrop-filter: blur(2px); }
.as-panel { position: relative; display: flex; flex-direction: column; width: min(880px, 100%); max-height: 100%; background: var(--panel); color: var(--ink); border: 1px solid var(--line); border-radius: 12px; box-shadow: 0 24px 64px rgba(0, 0, 0, .5); overflow: hidden; }
.as-head { display: flex; align-items: center; gap: 14px; flex: 0 0 auto; height: 52px; padding: 0 12px 0 22px; border-bottom: 1px solid var(--line); }
.as-title { font-size: 15px; font-weight: 600; }
.as-tabs { display: flex; align-self: stretch; gap: 2px; margin-left: 4px; }
.as-tab { padding: 0 10px; border: 0; border-bottom: 2px solid transparent; margin-bottom: -1px; background: transparent; color: var(--muted); font: inherit; font-size: 13px; font-weight: 500; cursor: pointer; }
.as-tab[aria-selected="true"] { color: var(--ink); font-weight: 600; border-bottom-color: var(--accent); }
.as-tab[hidden] { display: none; }
.as-tab:hover, .as-tab:focus-visible { color: var(--ink); outline: none; }
.as-esc { margin-left: auto; font-size: 11px; color: var(--muted); }
.as-close { display: inline-grid; place-items: center; width: 28px; height: 28px; padding: 0; border: 0; border-radius: 6px; background: transparent; color: var(--muted); cursor: pointer; }
.as-close:hover, .as-close:focus-visible { color: var(--ink); background: var(--active-item, rgba(127, 127, 127, .14)); outline: none; }
.as-close svg { width: 15px; height: 15px; }
.as-body { flex: 1 1 auto; min-height: 0; overflow: auto; display: flex; flex-direction: column; gap: 14px; padding: 20px 22px 22px; background: var(--bg); }
.as-card { display: flex; flex-direction: column; gap: 10px; padding: 14px 16px; border: 1px solid var(--line); border-radius: 10px; background: var(--panel); }
.as-cap { display: flex; align-items: center; gap: 8px; font-size: 11.5px; font-weight: 600; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); }
.as-beta { padding: 1px 6px; border-radius: 4px; background: var(--panel-2); color: var(--muted); font-size: 10px; letter-spacing: .04em; }
.as-grid { display: grid; grid-template-columns: 320px 1fr; gap: 14px; align-items: start; }
.as-you { flex-direction: row; align-items: center; gap: 12px; }
.as-avatar { flex: 0 0 auto; display: grid; place-items: center; width: var(--size, 38px); height: var(--size, 38px); border-radius: 50%; background: var(--tone, var(--accent)); color: #fff; font-size: calc(var(--size, 38px) * .42); font-weight: 600; }
.as-you-text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.as-you-name { font-size: 14px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.as-you-line { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.as-textglyph { display: inline-grid; place-items: center; width: 20px; height: 20px; padding: 0; border: 0; border-radius: 5px; background: transparent; color: var(--muted); cursor: pointer; }
.as-textglyph:hover, .as-textglyph:focus-visible { color: var(--ink); background: var(--active-item, rgba(127, 127, 127, .14)); outline: none; }
.as-textglyph svg { width: 12px; height: 12px; }
.as-logout { display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 10px; font-size: 12px; font-weight: 600; }
.as-logout svg { width: 13px; height: 13px; }
.as-rename { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 4px; }
.as-rename-input, .as-input { flex: 1 1 200px; min-width: 0; height: 28px; padding: 0 10px; border: 1px solid var(--line); border-radius: 7px; background: var(--bg); color: var(--ink); font: inherit; font-size: 12.5px; }
.as-rename-input:focus, .as-input:focus { outline: none; border-color: var(--accent-text); }
.as-field-error, .as-error { font-size: 11.5px; color: var(--amber); }
.as-error { display: flex; align-items: center; gap: 10px; padding: 8px 12px; border: 1px solid var(--amber); border-radius: 8px; }
.as-plan-name { font-size: 20px; font-weight: 600; line-height: 1.2; }
.as-line { font-size: 12.5px; }
.as-sub { font-size: 11.5px; line-height: 1.4; color: var(--muted); }
.as-note { padding: 2px 4px; }
.as-actions { display: flex; align-items: center; gap: 12px; margin-top: 2px; }
.as-link { display: inline-flex; align-items: center; gap: 4px; color: var(--accent-text); font-size: 12px; font-weight: 600; text-decoration: none; white-space: nowrap; }
.as-link:hover { text-decoration: underline; }
.as-link svg { width: 12px; height: 12px; }
.as-row { display: flex; align-items: center; gap: 14px; }
.as-row .ring { flex: 0 0 auto; }
.as-row-text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.as-big { font-size: 14px; font-weight: 600; font-variant-numeric: tabular-nums; }
.as-big.is-muted, .is-muted { color: var(--muted); font-weight: 500; }
.as-glyph { display: inline-grid; place-items: center; flex: 0 0 auto; width: 28px; height: 28px; border-radius: 50%; background: var(--panel-2); color: var(--accent-text); }
.as-glyph svg { width: 15px; height: 15px; }
.as-bar { display: flex; height: 8px; border-radius: 8px; overflow: hidden; background: var(--line); }
.as-bar span { display: block; height: 100%; background: var(--accent); }
.as-rule { height: 1px; margin: 2px 0; background: var(--line); }
.as-primary { display: inline-flex; align-items: center; justify-content: center; gap: 7px; height: 30px; padding: 0 14px; border: 1px solid var(--accent); border-radius: 7px; background: var(--accent); color: var(--accent-ink); font: inherit; font-size: 12.5px; font-weight: 600; white-space: nowrap; cursor: pointer; }
.as-primary svg { width: 14px; height: 14px; }
.as-primary:hover:not(:disabled), .as-primary:focus-visible { filter: brightness(1.06); outline: none; }
.as-primary:disabled { border-color: var(--line); background: var(--panel-2); color: var(--muted); cursor: default; }
.as-foot-line { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--muted); }
.as-foot-line svg { width: 14px; height: 14px; }
.as-loading { padding: 24px 0; text-align: center; font-size: 12.5px; color: var(--muted); }
.as-invite { flex-direction: row; align-items: center; gap: 8px; padding: 12px 14px; }
.as-chip { display: inline-flex; align-items: center; gap: 4px; height: 20px; padding: 0 7px; border: 1px solid var(--line); border-radius: 5px; background: var(--panel-2); color: var(--muted); font-size: 10.5px; font-weight: 600; white-space: nowrap; }
.as-chip svg { width: 10px; height: 10px; }
.as-members { display: flex; flex-direction: column; padding: 8px 8px 4px; border: 1px solid var(--line); border-radius: 10px; background: var(--panel); }
.as-members-head, .as-member { display: grid; grid-template-columns: 1fr 92px 150px 130px 84px; align-items: center; gap: 12px; padding: 5px 8px; }
.as-members-head { padding-bottom: 6px; border-bottom: 1px solid var(--line); font-size: 10.5px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.as-member { min-height: 44px; border-radius: 7px; font-size: 11.5px; }
.as-member:hover { background: var(--active-item, rgba(127, 127, 127, .14)); }
.as-member-who { display: flex; align-items: center; gap: 10px; min-width: 0; }
.as-member-text { display: flex; flex-direction: column; min-width: 0; }
.as-member-name { font-size: 12.5px; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.as-member-email { font-size: 11px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 720px) {
  #account-sheet { padding: 0; }
  .as-panel { width: 100%; height: 100%; max-height: none; border: 0; border-radius: 0; }
  .as-head { flex-wrap: wrap; height: auto; padding: 10px 10px 0 16px; gap: 8px 12px; }
  .as-tabs { order: 3; flex: 1 0 100%; margin: 4px 0 0 -10px; }
  .as-esc { display: none; }
  .as-body { padding: 14px; }
  .as-grid { grid-template-columns: 1fr; }
  .as-members-head { display: none; }
  .as-member { grid-template-columns: 1fr 84px; }
  .as-member > :nth-child(3), .as-member > :nth-child(4) { display: none; }
}

/* Guided-tutorial pictures: the plan on the request bubble and a replayed render in the reply (app.js guidedPicture) */
.guided-image { margin: 8px 0 0; }
.guided-image img { display: block; max-width: 100%; max-height: 320px; border-radius: 8px; }
.guided-image.attachment img { max-height: 160px; }
.guided-gallery { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.guided-gallery .guided-image:has(.guided-video-preview) { grid-column: 1 / -1; }
.guided-image video { display: block; width: 100%; max-height: 360px; border-radius: 8px; }
.guided-image figcaption { margin-top: 4px; color: var(--muted); font-size: 11px; }
.guided-preview { display: block; padding: 0; border: 0; border-radius: 8px; background: transparent; cursor: pointer; width: 100%; }
.guided-preview:focus-visible { outline: 2px solid var(--accent-text); outline-offset: 3px; }
.guided-video-preview { position: relative; overflow: hidden; aspect-ratio: 16 / 9; display: grid; place-items: center; color: white; background: var(--panel-2); border: 1px solid var(--line); }
.guided-video-preview img { position: absolute; inset: 0; width: 100%; height: 100%; max-height: none; object-fit: cover; }
.guided-video-preview svg { fill: currentColor; position: relative; width: 44px; height: 44px; padding: 10px; border-radius: 50%; background: rgb(0 0 0 / 55%); }
#tutorial-prompt-images[hidden] { display: none; }
#tutorial-prompt-images .guided-image { margin: 0; }
#tutorial-prompt-images img { width: 100%; height: 64px; object-fit: cover; }

.tutorial-prompt-thumb { width: 28px; height: 22px; object-fit: cover; border-radius: 4px; margin-right: 6px; vertical-align: middle; }
/* ---- Cloud scenes (app.js renderCloudState; words in cloud-messages.js) ---- */
/* The status beside the chat name: the label alone in a hairline-less button, muted by default, the alert's amber for
   anything that wants a decision or a retry, the accent while checking or downloading. A click or Enter opens its
   popover, so the sentence behind the label is not hover-only. */
.cloud-save-state {
  border: 0; border-radius: 6px; background: transparent; color: var(--muted); font: inherit; font-size: 11px; padding: 4px 6px;
  flex: 0 0 auto; max-width: min(220px, 50%); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; cursor: pointer; /* a long state gives way before the name does */
  transition: background .15s ease, color .15s ease;
}
.cloud-save-state:hover, .cloud-save-state:focus-visible, .cloud-save-state[aria-expanded="true"] { background: var(--line); color: var(--ink); outline: none; }
.cloud-save-state[data-state="conflict"], .cloud-save-state[data-state="error"], .cloud-save-state[data-state="remote"],
.cloud-save-state[data-state="shared"], .cloud-save-state[data-state="restore"] { color: var(--amber); }
.cloud-save-state[data-state="checking"], .cloud-save-state[data-state="downloading"] { color: var(--accent-text); }
/* Its popover: the label, the sentence and the actions, fixed at body level like the chat menu so the header cannot
   clip it; Escape, a click elsewhere, a resize or a choice closes it. */
#cloud-save-popover {
  position: fixed; z-index: 20; width: min(340px, calc(100vw - 16px)); padding: 12px 14px;
  background: var(--panel); color: var(--ink); border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, .45); font-size: 12.5px; line-height: 1.45;
}
#cloud-save-popover[hidden] { display: none; }
#cloud-save-popover:focus { outline: none; }
.cloud-pop-title { margin: 0 0 4px; font-weight: 600; font-size: 13px; }
.cloud-pop-detail { margin: 0 0 10px; }
.cloud-pop-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.cloud-pop-action {
  padding: 5px 10px; border: 1px solid var(--line); border-radius: 6px; background: var(--panel-2); color: var(--ink);
  font: inherit; font-size: 12px; cursor: pointer; transition: border-color .15s ease;
}
.cloud-pop-action:hover, .cloud-pop-action:focus-visible { border-color: var(--accent-text); outline: none; }
.cloud-pop-close { margin-left: auto; border-color: transparent; background: transparent; color: var(--muted); }
/* The conflict and join decisions (app.js cloudConflict, cloudJoin): one choice per row with its consequence under
   it; the choice that replaces local work in the danger ink the chat menu uses; the failure line in the alert's amber. */
.cloud-conflict { max-width: 520px; padding: 24px; border: 1px solid var(--line); border-radius: 12px; background: var(--panel); color: var(--ink); font-size: 13.5px; }
.cloud-conflict::backdrop { background: #0009; }
.cloud-conflict h2 { font-size: 18px; margin: 0 0 12px; }
.cloud-conflict p { line-height: 1.5; margin: 0 0 12px; }
.cloud-conflict-error { color: var(--amber); }
.cloud-conflict-error:empty { display: none; }
.cloud-choices { display: flex; flex-direction: column; gap: 12px; }
.cloud-choice { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }
.cloud-choice button {
  padding: 8px 12px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel-2); color: var(--ink);
  font: inherit; cursor: pointer; transition: border-color .15s ease;
}
.cloud-choice button:hover:not(:disabled), .cloud-choice button:focus-visible { border-color: var(--accent-text); outline: none; }
.cloud-choice button:disabled { opacity: .5; cursor: default; }
.cloud-choice.discards button { color: var(--danger); }
.cloud-choice-note { font-size: 12px; line-height: 1.4; color: var(--muted); }

/* ---- Notes tab (notes.js) ---- */
/* The list: the search, one row of controls (the Import tab's select chrome), the rows; Add note and Export at the foot. */
.nt-root { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.nt-list { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; gap: 10px; padding: 12px 18px 16px; }
.nt-controls { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; }
.nt-sort, .nt-filter { height: 26px; padding: 0 24px 0 8px; border: 1px solid var(--line); border-radius: 6px; background: var(--panel) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235c6d66' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") no-repeat right 6px center / 11px; color: var(--ink); font: inherit; font-size: 11.5px; appearance: none; -webkit-appearance: none; cursor: pointer; }
.nt-sort { flex: 1 1 124px; min-width: 0; } .nt-filter { flex: 1 1 118px; min-width: 0; } /* they give way, so the scene's toggle keeps its place */
.nt-spacer { flex: 1 1 auto; }
.nt-rows { flex: 1 1 auto; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; margin: 0 -8px; padding: 0 8px; }
/* a row: the colour card the Review rows lead with, the words on one line, who, whom and when; the count at the right,
   Jump and the ⋮ under the pointer */
.nt-row { display: flex; align-items: center; gap: 10px; min-height: 54px; padding: 6px 6px 6px 8px; border-radius: 7px; cursor: pointer; }
.nt-row:hover, .nt-row.menu-open, .nt-row:focus-visible { background: var(--active-item, rgba(127, 127, 127, .14)); outline: none; }
.nt-row.is-open { background: var(--active-item, rgba(127, 127, 127, .14)); box-shadow: inset 2px 0 0 var(--accent); }
.nt-card { flex: 0 0 auto; width: 44px; height: 28px; display: grid; place-items: center; border-radius: 4px; color: var(--ink); box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .08); }
.nt-card.resolved { opacity: .8; }
.nt-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.nt-text { font-size: 12.5px; line-height: 1.3; color: var(--ink); font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nt-text.muted { color: var(--muted); text-decoration: line-through; text-decoration-color: rgba(94, 104, 105, .5); }
.nt-meta { display: flex; align-items: center; gap: 5px; font-size: 11px; color: var(--muted); white-space: nowrap; overflow: hidden; min-width: 0; }
.nt-meta > span { overflow: hidden; text-overflow: ellipsis; }
.nt-faint { opacity: .75; }
.nt-avatar { flex: 0 0 auto; display: grid; place-items: center; border-radius: 50%; color: #fff; font-size: 8px; font-weight: 600; line-height: 1; }
.nt-right { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 4px; }
.nt-badge { display: inline-flex; align-items: center; gap: 3px; height: 18px; padding: 0 6px 0 5px; border-radius: 9px; background: var(--panel-2); color: var(--muted); font-size: 11px; font-weight: 600; }
.nt-row:hover .nt-badge, .nt-row.menu-open .nt-badge { display: none; }
.nt-act { flex: 0 0 auto; width: 24px; height: 24px; display: grid; place-items: center; padding: 0; border: 0; border-radius: 5px; background: transparent; color: var(--muted); cursor: pointer; }
.nt-act:hover:not(:disabled), .nt-act:focus-visible { color: var(--ink); background: var(--panel-2); outline: none; }
.nt-act:disabled { opacity: .5; cursor: default; }
.nt-jump, .nt-more { display: none; }
.nt-row:hover .nt-jump, .nt-row:hover .nt-more, .nt-row.menu-open .nt-more, .nt-row:focus-within .nt-jump, .nt-row:focus-within .nt-more { display: grid; }
.nt-menu { position: fixed; z-index: 60; min-width: 160px; padding: 4px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel); box-shadow: 0 10px 30px rgba(0, 0, 0, .14); }
.nt-menu[hidden] { display: none; }
.nt-foot { flex: 0 0 auto; display: flex; gap: 8px; padding-top: 4px; }
.nt-primary { flex: 1 1 auto; display: flex; align-items: center; justify-content: center; gap: 6px; height: 32px; border: 1px solid var(--accent); border-radius: 8px; background: var(--accent); color: #fff; font: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer; }
.nt-primary:hover:not(:disabled) { filter: brightness(1.05); }
.nt-primary:disabled { opacity: .5; cursor: default; }
.nt-foot .rv-wide { flex: 0 0 auto; padding: 0 12px; }
.nt-empty { display: flex; flex-direction: column; align-items: center; gap: 8px; text-align: center; padding: 30px 12px; }
.nt-empty-glyph { width: 44px; height: 44px; display: grid; place-items: center; border-radius: 12px; background: var(--panel-2); color: var(--muted); }
.nt-empty-title { font-size: 13px; font-weight: 600; color: var(--ink); }
/* A note open: the still, its row, the words in the composer's field, the colours and Resolved, Assigned to, the facts, the comments. */
.nt-note { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.nt-head { flex: 0 0 auto; display: flex; align-items: center; gap: 6px; padding: 8px 10px 8px 8px; border-bottom: 1px solid var(--line); }
.nt-head .nt-act { width: 28px; height: 28px; }
.nt-title { flex: 1 1 auto; font-size: 13px; font-weight: 600; color: var(--ink); }
.nt-pill { display: inline-flex; align-items: center; gap: 3px; height: 18px; padding: 0 6px 0 5px; border-radius: 9px; background: var(--panel-2); color: var(--muted); font-size: 11px; font-weight: 600; }
.nt-pill.is-accent { background: var(--accent-soft); color: var(--accent-text); }
.nt-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: 12px; padding: 12px 14px 10px; }
.nt-still { flex: 0 0 auto; aspect-ratio: 292 / 150; border-radius: 8px; overflow: hidden; border: 1px solid var(--line); background: var(--panel-2); display: grid; place-items: center; color: var(--muted); }
.nt-still img { display: block; width: 100%; height: 100%; object-fit: cover; }
.nt-viewrow { display: flex; align-items: center; gap: 8px; margin-top: -4px; }
.nt-viewrow .header-btn { display: inline-flex; align-items: center; gap: 6px; height: 26px; padding: 0 9px; border-radius: 7px; font-size: 11.5px; font-weight: 500; }
.nt-words { width: 100%; min-height: 60px; resize: none; overflow: hidden; padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px; background: var(--bg); color: var(--ink); font: inherit; font-size: 14px; line-height: 1.45; }
.nt-words:focus { border-color: var(--accent-text); outline: none; }
.nt-words[readonly] { color: var(--muted); }
.nt-counter { margin-top: -8px; text-align: right; font-size: 10.5px; color: var(--muted); }
.nt-counter[hidden] { display: none; }
.nt-rowline { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 30px; }
.nt-label { font-size: 12.5px; color: var(--ink); }
.nt-swatches { display: flex; align-items: center; gap: 8px; }
.nt-swatch { width: 24px; height: 24px; display: grid; place-items: center; padding: 0; border: 0; border-radius: 50%; background: transparent; cursor: pointer; }
.nt-swatch > span { width: 18px; height: 18px; border-radius: 50%; box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .10); }
.nt-swatch[aria-pressed="true"] > span { box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .10), 0 0 0 2px var(--panel), 0 0 0 4px var(--accent); }
.nt-swatch:disabled { cursor: default; opacity: .6; }
.nt-swatch-yellow { background: #fbe9a6; } .nt-swatch-red { background: #f7c9c2; } .nt-swatch-green { background: #cfe8c9; } .nt-swatch-blue { background: #cfe3ee; }
.nt-resolved { display: inline-flex; align-items: center; gap: 10px; font-size: 12.5px; color: var(--ink); cursor: pointer; }
.nt-resolved input { appearance: none; -webkit-appearance: none; width: 34px; height: 18px; margin: 0; border-radius: 9px; background: var(--line); position: relative; cursor: pointer; transition: background .15s ease; }
.nt-resolved input::after { content: ''; position: absolute; top: 2px; left: 2px; width: 14px; height: 14px; border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgba(0, 0, 0, .25); transition: left .15s ease; }
.nt-resolved input:checked { background: var(--accent); }
.nt-resolved input:checked::after { left: 18px; }
.nt-resolved input:disabled { opacity: .5; cursor: default; }
.nt-assignee { width: 150px; height: 24px; padding: 0 8px; border: 1px solid var(--line); border-radius: 6px; background: var(--panel); color: var(--ink); font: inherit; font-size: 11.5px; }
.nt-assignee:focus { border-color: var(--accent-text); outline: none; }
.nt-rule { width: 100%; height: 1px; margin: 0; border: 0; background: var(--line); flex: 0 0 auto; }
.nt-facts { display: flex; flex-direction: column; gap: 5px; font-size: 11.5px; color: var(--muted); }
.nt-facts > span { display: flex; align-items: center; gap: 6px; }
.nt-section { display: flex; flex-direction: column; gap: 4px; }
.nt-cap { font-size: 11.5px; font-weight: 600; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); }
.nt-hint { margin: 0; font-size: 11.5px; line-height: 1.45; color: var(--muted); }
.nt-comment { position: relative; display: flex; gap: 8px; padding: 6px; border-radius: 7px; }
.nt-comment:hover, .nt-comment.is-open { background: var(--active-item, rgba(127, 127, 127, .14)); }
.nt-comment-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.nt-comment-who { display: flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--muted); }
.nt-comment-who > span:first-child { font-weight: 600; color: var(--ink); }
.nt-comment-text { font-size: 12.5px; line-height: 1.45; color: var(--ink); white-space: pre-wrap; overflow-wrap: anywhere; }
.nt-composer { display: flex; align-items: flex-end; gap: 8px; padding-top: 6px; }
.nt-composer .nt-avatar { align-self: center; }
.nt-comment-input { flex: 1 1 auto; min-width: 0; min-height: 30px; resize: none; overflow: hidden; padding: 6px 10px; border: 1px solid var(--line); border-radius: 8px; background: var(--bg); color: var(--ink); font: inherit; font-size: 12.5px; line-height: 1.4; }
.nt-comment-input:focus { border-color: var(--accent-text); outline: none; }
.nt-send { width: 30px; height: 30px; color: var(--accent-text); }
.nt-note .nt-foot { padding: 10px 14px 14px; border-top: 1px solid var(--line); }
.nt-danger { color: var(--danger); }
/* The scene's toggle at the end of the controls row, the selects' height: Collapse all in scene, or Expand all, pressed,
   once nothing is expanded. */
.nt-scene-toggle { flex: 0 0 auto; width: 26px; height: 26px; display: grid; place-items: center; padding: 0; border: 1px solid var(--line); border-radius: 6px; background: var(--panel); color: var(--muted); cursor: pointer; }
.nt-scene-toggle:hover:not(:disabled), .nt-scene-toggle:focus-visible { border-color: var(--accent-text); color: var(--ink); outline: none; }
.nt-scene-toggle.is-on { background: var(--active-item, rgba(127, 127, 127, .14)); color: var(--ink); }
.nt-scene-toggle:disabled { opacity: .5; cursor: default; }
/* The mic at the view row's end, the composer's square button at the row's one height: the accent while Unity records,
   the app's ring while it transcribes, and a line under the field that says which. */
.nt-mic { flex: 0 0 auto; width: 26px; height: 26px; display: grid; place-items: center; padding: 0; border: 1px solid var(--line); border-radius: 7px; background: var(--panel); color: var(--ink); cursor: pointer; transition: border-color .15s ease, background .15s ease; }
.nt-mic:hover:not(:disabled), .nt-mic:focus-visible { border-color: var(--accent-text); outline: none; }
.nt-mic.is-recording { border-color: var(--accent); background: var(--accent); color: var(--accent-ink); }
.nt-mic.is-busy { cursor: progress; }
.nt-mic:disabled:not(.is-busy) { opacity: .5; cursor: default; }
.nt-dictation { display: flex; align-items: center; gap: 6px; margin-top: -6px; font-size: 11px; color: var(--accent-text); }
.nt-dictation.is-busy { color: var(--muted); }
.nt-rec { flex: 0 0 auto; width: 7px; height: 7px; border-radius: 50%; background: var(--accent); }
/* The element line of the facts: the link, the element's name and category cut to the line, the unlink. */
.nt-element { min-width: 0; }
.nt-element > svg { flex: 0 0 auto; margin: 0 1px; }
.nt-element-name { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nt-unlink { flex: 0 0 auto; width: 18px; height: 18px; display: grid; place-items: center; padding: 0; border: 0; border-radius: 4px; background: transparent; color: var(--muted); opacity: .7; cursor: pointer; }
.nt-unlink:hover, .nt-unlink:focus-visible { opacity: 1; color: var(--ink); background: var(--panel-2); outline: none; }
/* A comment's reactions: the group chat's chips under the words and its picker over the row (.gc-reactions, .gc-picker);
   React at the end of the who line under the pointer, on someone else's comment only. */
.nt-react { margin-left: auto; display: none; padding: 0; border: 0; background: transparent; color: var(--accent-text); font: inherit; font-size: 11.5px; font-weight: 600; cursor: pointer; }
.nt-comment:hover .nt-react, .nt-comment:focus-within .nt-react, .nt-comment.is-open .nt-react { display: inline; }
.nt-react:hover, .nt-react:focus-visible { text-decoration: underline; outline: none; }
.nt-comment .gc-reactions { margin-top: 3px; }
.nt-comment .gc-picker { top: -40px; right: 6px; }
/* The comment badge over the player (notes.js createNoteBadges): the list's comment pill in the dimension pills' dress,
   on the note's top-right shoulder, fading with the note's line of sight. */
#note-badge-layer { position: absolute; inset: 0; z-index: 2; overflow: hidden; pointer-events: none; }
#note-badge-layer[hidden] { display: none; }
.note-badge { position: absolute; left: 0; top: 0; display: inline-flex; align-items: center; gap: 3px; height: 18px; padding: 0 6px 0 5px; border: 1px solid var(--line); border-radius: 9px; background: var(--panel); color: var(--muted); box-shadow: 0 2px 8px rgba(0, 0, 0, .18); font: inherit; font-size: 11px; font-weight: 600; line-height: 1; cursor: pointer; pointer-events: auto; opacity: 1; transition: opacity .15s ease; }
.note-badge:hover, .note-badge:focus-visible { border-color: var(--accent-text); color: var(--ink); outline: none; }
.note-badge.is-hidden { opacity: 0; pointer-events: none; }
/* The element under the pointer while a note is placed or moved (notes.js createNoteHover): a pill in the dimension
   pills' dress beside the pointer, as the drag readout follows it, with the element line's link. */
#note-hover-layer { position: absolute; inset: 0; z-index: 2; overflow: hidden; pointer-events: none; }
#note-hover-layer[hidden] { display: none; }
.note-hover { position: absolute; left: 0; top: 0; display: inline-flex; align-items: center; gap: 5px; padding: 3px 8px 3px 7px; border: 1px solid var(--line); border-radius: 6px; background: var(--panel); color: var(--ink); box-shadow: 0 2px 8px rgba(0, 0, 0, .18); font-size: 12px; line-height: 1.3; white-space: nowrap; pointer-events: none; }
.note-hover svg { flex: 0 0 auto; color: var(--accent-text); }
/* The group chat's thread cards and note events (group-chat.js): a note's messages gathered under the note; who added or
   resolved a note, with Jump to note; the note on the composer as a chip while a reply is written. */
.gc-thread { align-self: stretch; display: flex; flex-direction: column; gap: 8px; padding: 8px 10px 10px 12px; border: 1px solid var(--line); border-left: 4px solid var(--note-color, var(--line)); border-radius: 8px; background: var(--panel-2); }
.gc-thread-head { display: flex; align-items: center; gap: 8px; }
.gc-thread-from { flex: 1 1 auto; min-width: 0; font-size: 11px; font-weight: 600; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.gc-thread-words { font-size: 12.5px; line-height: 1.4; color: var(--ink); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.gc-thread-runs { display: flex; flex-direction: column; gap: 10px; }
.gc-thread .gc-run.other .gc-bubble { background: var(--panel); }
.gc-thread-foot { display: flex; align-items: center; gap: 10px; font-size: 12px; color: var(--muted); }
.gc-thread-foot button, .gc-jump { display: inline-flex; align-items: center; gap: 5px; padding: 0; border: 0; background: transparent; color: var(--accent-text); font: inherit; font-size: 12px; font-weight: 600; cursor: pointer; white-space: nowrap; }
.gc-thread-foot button:hover, .gc-jump:hover, .gc-thread-foot button:focus-visible, .gc-jump:focus-visible { text-decoration: underline; outline: none; }
.gc-jump svg { width: 13px; height: 13px; }
.gc-jump.header-btn { height: 26px; padding: 0 9px; border: 1px solid var(--line); border-radius: 7px; color: var(--ink); font-weight: 500; text-decoration: none; }
.gc-jump.header-btn:hover { border-color: var(--accent-text); }
.gc-event { align-self: stretch; display: flex; flex-direction: column; gap: 6px; }
.gc-event-who { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--muted); }
.gc-event-who .gc-name { font-weight: 600; color: var(--ink); }
.gc-event-card { display: flex; align-items: center; gap: 10px; padding: 8px 10px 8px 12px; border: 1px solid var(--line); border-left: 4px solid var(--note-color, var(--line)); border-radius: 8px; background: var(--panel-2); }
.gc-event-card .gc-thread-words { flex: 1 1 auto; min-width: 0; }
.gc-chip-thumb.is-note { color: var(--ink); }
.gc-chip-thumb.is-note svg { width: 15px; height: 15px; }

/* Cloud-library controls are provisional; retain the existing row/menu focus and contrast behavior. */

/* ---- the Media place (media-place.js, canvas page 27): every AI render and video of this browser's chats, drilled into
   the left column under the column's own header. The filters and the sort on one row (the sort wraps under them in a
   narrow column), then 16:9 tiles that share the column's width: two to a row at the design's 300 px, one in a column
   too narrow for two to stay legible, three once it is dragged wide, as the design note has it; a track never takes
   its width from a caption, which ellipsizes. A tile's Open chat and ⋮ sit over its picture and show under the
   pointer, with the keyboard on the tile and while its menu is open; a touch screen, which has no pointer to hover,
   shows them always. The place scrolls its own tiles. ---- */
.mp { flex: 1 1 auto; height: 100%; min-height: 0; display: flex; flex-direction: column; }
.mp-bar { flex: 0 0 auto; display: flex; flex-wrap: wrap; align-items: center; gap: 6px 5px; padding: 2px 10px 8px; }
.mp-filters { flex: 0 0 auto; display: flex; gap: 5px; }
.mp-chip { height: 22px; padding: 0 9px; border: 1px solid var(--line); border-radius: 6px; background: transparent; color: var(--muted); font: inherit; font-size: 11.5px; font-weight: 600; line-height: 1; cursor: pointer; transition: border-color .15s ease, color .15s ease; }
.mp-chip:hover, .mp-chip:focus-visible { color: var(--ink); border-color: var(--accent-text); outline: none; }
.mp-chip[aria-pressed="true"] { border-color: var(--accent-text); background: var(--accent-soft); color: var(--ink); }
.mp-sort { margin-left: auto; flex: 0 1 auto; min-width: 0; height: 22px; padding: 0 22px 0 7px; border: 1px solid var(--line); border-radius: 6px; background: var(--panel) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235c6d66' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") no-repeat right 6px center / 11px; color: var(--ink); font: inherit; font-size: 11.5px; appearance: none; -webkit-appearance: none; cursor: pointer; }
.mp-sort:hover, .mp-sort:focus-visible { border-color: var(--accent-text); outline: none; }
/* the status line under the filters (a word on Open chat, a Download from Downloading… to Download started, a failure's
   reason): a live region that stays in the tree, taking no room while it is empty, so a word arriving is announced */
.mp-notice { flex: 0 0 auto; margin: -2px 12px 6px; font-size: 11.5px; line-height: 1.35; color: var(--muted); }
.mp-notice:empty { margin: 0; }
.mp-scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 0 5px 10px; }
.mp-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 105px), 1fr)); gap: 4px 2px; align-content: start; }
.mp-tile { min-width: 0; display: flex; flex-direction: column; gap: 5px; padding: 5px; border-radius: 9px; transition: background .15s ease; }
.mp-tile:hover, .mp-tile:focus-within, .mp-tile.menu-open { background: var(--chat-hover, rgba(127,127,127,.08)); }
.mp-thumb { position: relative; aspect-ratio: 16 / 9; border: 1px solid var(--line); border-radius: 6px; overflow: hidden; background: var(--panel); container-type: inline-size; }
/* the picture is a real button so the keyboard reaches it; Open chat and the ⋮ are its siblings, over it */
.mp-frame { position: absolute; inset: 0; display: block; width: 100%; height: 100%; padding: 0; margin: 0; border: 0; border-radius: 0; background: transparent; color: var(--muted); font: inherit; cursor: pointer; }
.mp-frame:focus-visible { outline: 2px solid var(--accent-text); outline-offset: -2px; }
.mp-pic { display: block; width: 100%; height: 100%; object-fit: cover; }
.mp-placeholder { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; padding: 6px; font-size: 11px; line-height: 1.25; text-align: center; }
.mp-placeholder .spinner { width: 18px; height: 18px; border-width: 2px; }
.mp-placeholder.is-failed { color: var(--danger); }
.mp-detail { color: var(--muted); font-size: 10.5px; }
.mp-placeholder.is-failed .mp-detail { color: inherit; font-weight: 600; text-decoration: underline; }
.mp-play { position: absolute; left: 50%; top: 50%; width: 28px; height: 28px; transform: translate(-50%, -50%); display: grid; place-items: center; border-radius: 50%; background: rgba(21, 32, 33, .62); color: #fff; pointer-events: none; }
.mp-play svg { width: 15px; height: 15px; fill: currentColor; margin-left: 2px; }
.mp-length { position: absolute; right: 5px; bottom: 5px; height: 16px; padding: 0 5px; display: inline-flex; align-items: center; border-radius: 4px; background: rgba(21, 32, 33, .72); color: #fff; font-size: 10px; font-weight: 600; font-variant-numeric: tabular-nums; pointer-events: none; }
.mp-chat, .mp-more { position: absolute; display: inline-flex; align-items: center; justify-content: center; height: 22px; border: 1px solid var(--line); border-radius: 6px; background: var(--panel); font: inherit; cursor: pointer; opacity: 0; transition: opacity .12s ease, border-color .15s ease, color .15s ease; }
.mp-chat { left: 5px; bottom: 5px; gap: 5px; padding: 0 8px; color: var(--ink); font-size: 11px; font-weight: 600; white-space: nowrap; }
.mp-more { right: 5px; top: 5px; width: 22px; padding: 0; color: var(--muted); }
.mp-tile:hover .mp-chat, .mp-tile:hover .mp-more, .mp-tile:focus-within .mp-chat, .mp-tile:focus-within .mp-more,
.mp-tile.menu-open .mp-chat, .mp-tile.menu-open .mp-more { opacity: 1; }
@media (hover: none) { .mp-chat, .mp-more { opacity: 1; } }
/* a picture too narrow for the words keeps Open chat as its glyph (named by its tooltip), clear of a video's length */
@container (max-width: 123px) { .mp-chat { width: 22px; padding: 0; } .mp-chat-label { display: none; } }
.mp-chat:hover, .mp-chat:focus-visible, .mp-more:hover, .mp-more:focus-visible, .mp-tile.menu-open .mp-more { border-color: var(--accent-text); color: var(--ink); outline: none; }
.mp-caption { font-size: 12px; line-height: 1.25; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mp-meta { margin-top: -3px; font-size: 11px; line-height: 1.3; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mp-foot:empty { display: none; }
/* the foot under the tiles: the gathering with its quiet spinner and the agent's pause, or the chats that could not be
   checked with their one action (Retry, Log in), wrapping in the narrow column; the line takes focus when its action
   went with it, so the status that follows is read */
.mp-line { margin: 14px 8px; text-align: center; font-size: 12px; line-height: 1.4; color: var(--muted); overflow-wrap: anywhere; }
.mp-line:focus { outline: none; }
.mp-line:focus-visible { outline: 2px solid var(--accent-text); outline-offset: 2px; border-radius: 4px; }
.mp-line .spinner { display: inline-block; width: 12px; height: 12px; margin: 0 6px -2px 0; border-width: 2px; border-color: var(--line); border-top-color: var(--accent); }
.mp-line-detail { display: block; margin-top: 2px; }
.mp-line-action { border: 0; padding: 0 2px; background: transparent; color: var(--accent-text); font: inherit; font-size: 12px; font-weight: 600; cursor: pointer; }
.mp-line-action:hover, .mp-line-action:focus-visible { text-decoration: underline; outline: none; }
.mp-note { margin: 4px 10px 10px; text-align: center; font-size: 11px; line-height: 1.4; color: var(--muted); }
.mp-empty { display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 30px 14px; text-align: center; font-size: 12px; line-height: 1.45; color: var(--muted); }
.mp-empty-glyph { width: 44px; height: 44px; display: grid; place-items: center; border-radius: 12px; background: var(--panel); color: var(--muted); }
.mp-empty-title { font-size: 13px; font-weight: 600; color: var(--ink); }
/* the ⋮'s menu: at the body's level, above the column, with the chat menu's items (.session-menu-item); a failed
   preview's reason at its top, where touch reaches it */
.mp-menu { position: fixed; z-index: 60; min-width: 170px; max-width: min(300px, calc(100vw - 16px)); padding: 4px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel); color: var(--ink); box-shadow: 0 10px 30px rgba(0, 0, 0, .14); }
.mp-menu-note { margin: 4px 8px 6px; padding-bottom: 6px; border-bottom: 1px solid var(--line); font-size: 11.5px; line-height: 1.4; color: var(--muted); }

/* ---- the mode chip (index.html #edit-mode, app.js renderEditMode): Viewing in the header's plain pill with the muted ink,
   Editing in the pressed look of the header's two switches; the Share tab's eye or pencil before the word, a chevron
   after. Its menu is the Share tab's access menu (.sh-menu) under the chip: the two modes to pick from when the choice
   is the user's, else the reason in one line (.em-reason) and, for an editor link signed out, Sign in to edit. While
   Viewing, the tools that change the model and the History group hide; a tool or a group is display-set, so [hidden]
   needs saying. ---- */
#edit-mode { align-self: center; }
#edit-mode-btn { display: inline-flex; align-items: center; gap: 6px; padding: 0 8px 0 10px; }
#edit-mode-btn[hidden] { display: none; }
#edit-mode-btn[data-mode="view"] { color: var(--muted); }
#edit-mode-btn[data-mode="edit"], #edit-mode-btn[aria-expanded="true"] { border-color: var(--accent-text); }
#edit-mode-btn[data-mode="edit"] { background: var(--accent-soft); color: var(--accent-text); }
.em-glyph, .em-chevron { display: inline-flex; }
.em-glyph svg { width: 14px; height: 14px; }
.em-chevron svg { width: 11px; height: 11px; }
#edit-mode-menu .em-reason { margin: 0; padding: 2px 8px 8px; font-size: 11.5px; line-height: 1.4; color: var(--muted); white-space: normal; }
#edit-mode-menu .em-action { margin: 0 8px 6px; align-self: flex-start; }
/* the option's body is a picker span, which the picker keeps on one line with an ellipsis (.vb-picker button > span); these
   two lines of explanation wrap instead */
#edit-mode-menu .sh-menu-body { white-space: normal; overflow: visible; }
.tool[hidden], .tool-group[hidden], .tool-sep[hidden] { display: none; }
