/* ============================================================
   Hive Live — dark honey theme, mobile-first PWA shell
   ============================================================ */
:root {
  --bg: #08080c;
  --bg-2: #0e0e15;
  --panel: rgba(255, 255, 255, 0.035);
  --panel-2: rgba(255, 255, 255, 0.06);
  --line: rgba(255, 255, 255, 0.09);
  --line-strong: rgba(255, 255, 255, 0.16);
  --text: #f2f2f7;
  --muted: #9a9aab;
  --honey: #ffb020;
  --honey-2: #ff8a3d;
  --honey-soft: rgba(255, 176, 32, 0.14);
  --danger: #ff5d6c;
  --ok: #37d67a;
  --radius: 18px;
  --radius-sm: 12px;
  --shadow: 0 18px 50px rgba(0, 0, 0, 0.55);
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-t: env(safe-area-inset-top, 0px);
  font-synthesis: none;
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
/* The document itself never scrolls — this is an app shell, not a document.
   A scrollable body is what lets a phone drag the whole page ("pull up or down
   slightly"), which slides the streamer's video out of view and triggers
   Android's pull-to-refresh. Anything that needs to scroll scrolls inside
   #main, the watch chat panel, or the auth screen instead.
   Trade-off: with the page locked, mobile browsers no longer auto-hide their
   URL bar. That is the point — the stage stops resizing. */
html {
  height: 100%;
  overflow: hidden;
  overscroll-behavior: none; /* no rubber banding, no pull-to-refresh */
}
body {
  position: fixed; /* pinned to the layout viewport: the body cannot be dragged */
  inset: 0; /* and the mobile URL bar cannot resize the stage */
  margin: 0;
  overflow: hidden;
  background:
    radial-gradient(1100px 600px at 15% -10%, rgba(255, 176, 32, 0.1), transparent 60%),
    radial-gradient(900px 500px at 100% 0%, rgba(124, 92, 255, 0.09), transparent 55%),
    var(--bg);
  color: var(--text);
  font: 15px/1.5 ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Inter, sans-serif;
  overscroll-behavior: none;
}
h1, h2, h3 { margin: 0; font-weight: 700; letter-spacing: -0.01em; }
h2 { font-size: 1.15rem; }
h3 { font-size: 1rem; margin-bottom: 10px; }
button, input, select, textarea { font: inherit; color: inherit; }
code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.82rem; }
.muted { color: var(--muted); font-size: 0.85rem; }
.is-hidden { display: none !important; }
/* Every shell (#view-auth, #view-app, #view-watch) fills the locked viewport and
   manages its own internal scrolling. */
.view { height: 100%; overflow: hidden; }

/* ---------------- brand ---------------- */
.brand-hex {
  width: 34px; height: 34px; display: inline-block;
  background: linear-gradient(140deg, var(--honey), var(--honey-2));
  clip-path: polygon(50% 0%, 93% 25%, 93% 75%, 50% 100%, 7% 75%, 7% 25%);
  box-shadow: 0 6px 22px rgba(255, 176, 32, 0.4);
}
.brand-hex.small { width: 20px; height: 20px; }
.auth-view {
  /* Scrolls internally: now that the document is locked, a tall sign-up form
     would otherwise be clipped with no way to reach the button on a short
     phone. flex + margin:auto centres it, and keeps the top reachable when the
     card is taller than the screen (grid's place-items:center would clip it). */
  display: flex; flex-direction: column;
  overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  padding: 24px 16px calc(24px + var(--safe-b));
}
.auth-card {
  margin: auto;
  width: min(430px, 100%); background: var(--panel); border: 1px solid var(--line);
  border-radius: 24px; padding: 26px; backdrop-filter: blur(14px); box-shadow: var(--shadow);
}
.brand { text-align: center; margin-bottom: 20px; }
.brand h1 { font-size: 1.7rem; margin: 12px 0 4px; letter-spacing: 0.14em; }
.brand h1 span { color: var(--honey); }
.tagline { margin: 0; color: var(--muted); font-size: 0.86rem; }
.segmented { display: flex; gap: 6px; background: rgba(0,0,0,0.35); padding: 5px; border-radius: 999px; margin-bottom: 18px; }
.seg {
  flex: 1; border: 0; background: transparent; color: var(--muted); padding: 10px;
  border-radius: 999px; cursor: pointer; font-weight: 600; font-size: 0.9rem;
}
.seg.is-active { background: var(--honey-soft); color: var(--honey); }

/* ---------------- forms ---------------- */
.auth-form, .stack { display: flex; flex-direction: column; gap: 12px; }
label { display: flex; flex-direction: column; gap: 6px; font-size: 0.82rem; color: var(--muted); font-weight: 600; }
label small { font-weight: 400; opacity: 0.8; }
input, select, textarea {
  background: rgba(0,0,0,0.35); border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: 12px 14px; outline: none; transition: border-color .15s, box-shadow .15s; width: 100%;
}
input:focus, select:focus, textarea:focus { border-color: var(--honey); box-shadow: 0 0 0 3px var(--honey-soft); }
.btn {
  border: 1px solid var(--line-strong); background: var(--panel-2); color: var(--text);
  padding: 12px 16px; border-radius: 999px; cursor: pointer; font-weight: 650; letter-spacing: 0.01em;
  transition: transform .08s, filter .15s; white-space: nowrap;
}
.btn:active { transform: scale(0.97); }
.btn-primary {
  background: linear-gradient(135deg, var(--honey), var(--honey-2)); border: 0; color: #17130a;
  box-shadow: 0 10px 26px rgba(255, 140, 40, 0.3);
}
.btn-primary:hover { filter: brightness(1.06); }
.btn-ghost { background: transparent; }
.btn-danger { color: var(--danger); border-color: rgba(255, 93, 108, 0.4); }
.btn-sm { padding: 9px 14px; font-size: 0.86rem; }
.fineprint { color: var(--muted); font-size: 0.76rem; margin: 14px 0 0; line-height: 1.5; }
.icon-btn {
  border: 1px solid var(--line); background: var(--panel); border-radius: 50%;
  width: 40px; height: 40px; display: grid; place-items: center; cursor: pointer; font-size: 1rem;
}

/* ---------------- shell ---------------- */
/* Fixed-height column: the topbar never moves and #main is the only scroller. */
#view-app { display: flex; flex-direction: column; }
.topbar {
  position: relative; flex: 0 0 auto; z-index: 20; display: flex; align-items: center; justify-content: space-between;
  gap: 10px; padding: calc(10px + var(--safe-t)) 14px 10px;
  background: rgba(8, 8, 12, 0.72); backdrop-filter: blur(18px); border-bottom: 1px solid var(--line);
}
.topbar-left, .topbar-right { display: flex; align-items: center; gap: 10px; }
.topbar-left strong { font-size: 0.82rem; letter-spacing: 0.18em; }
.pill {
  display: inline-flex; align-items: center; gap: 6px; padding: 5px 11px; border-radius: 999px;
  background: var(--panel-2); border: 1px solid var(--line); font-size: 0.74rem; font-weight: 650;
}
.pill-live { color: var(--honey); border-color: rgba(255, 176, 32, 0.4); background: var(--honey-soft); }
.dot { width: 7px; height: 7px; border-radius: 50%; background: var(--honey); animation: pulse 1.8s infinite; }
@keyframes pulse { 0%,100% { opacity: 1; transform: scale(1); } 50% { opacity: .45; transform: scale(.78); } }
.conn { color: var(--danger); font-size: 0.7rem; }
.conn.on { color: var(--ok); }
.avatar-btn { border: 0; background: transparent; padding: 0; cursor: pointer; }
.avatar {
  display: grid; place-items: center; width: 34px; height: 34px; border-radius: 50%;
  background: var(--honey); color: #17130a; font-weight: 800; font-size: 0.82rem;
  background-size: cover; background-position: center; overflow: hidden;
}
.avatar.sm { width: 28px; height: 28px; font-size: 0.72rem; }
.avatar-xl { width: 64px; height: 64px; font-size: 1.3rem; }

/* The app's only scroll container. Full-bleed so the scrollbar sits at the
   window edge; the width cap lives on .page instead. No tab-bar-sized bottom
   padding is needed any more: the footer (live strip + tab bar) is a flex row
   below this, not an overlay. */
main {
  flex: 1 1 auto;
  min-height: 0; /* without this a flex child refuses to shrink and never scrolls */
  overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  padding: 16px 14px 24px;
}
.page { max-width: 1200px; margin: 0 auto; }
.page-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin: 6px 2px 14px; }
.page-head:not(:first-child) { margin-top: 26px; }

.grid { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }
.card {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 16px; backdrop-filter: blur(10px); margin-bottom: 14px;
}
.chan {
  display: flex; gap: 12px; align-items: center; padding: 13px; border-radius: var(--radius);
  background: var(--panel); border: 1px solid var(--line); cursor: pointer; text-align: left;
  transition: border-color .15s, transform .08s;
}
.chan:hover { border-color: var(--line-strong); }
.chan:active { transform: scale(0.985); }
.chan.live { border-color: rgba(255, 176, 32, 0.42); box-shadow: inset 0 0 0 1px rgba(255,176,32,.1); }
.chan-meta { min-width: 0; }
.chan-name { font-weight: 700; display: flex; align-items: center; gap: 6px; }
.chan-title { color: var(--muted); font-size: 0.83rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.live-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--honey); animation: pulse 1.8s infinite; }
.viewers { font-size: 0.72rem; color: var(--honey); font-weight: 700; }
.inroom { font-size: 0.72rem; color: var(--muted); }
.search-wrap { margin: 6px 2px 10px; }
.search {
  background: rgba(0,0,0,0.35); border: 1px solid var(--line); border-radius: 999px;
  padding: 13px 18px; width: 100%;
}
.chips-row { display: flex; gap: 8px; overflow-x: auto; padding: 0 2px 6px; scrollbar-width: none; }
.chips-row::-webkit-scrollbar { display: none; }
.chips-row .chip { background: transparent; padding: 7px 14px; white-space: nowrap; }
.chips-row .chip.is-active { border-color: var(--honey); background: var(--honey-soft); color: var(--honey); }
.roster { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 10px; padding-bottom: 10px; border-bottom: 1px solid var(--line); }
.roster:empty { display: none; }
.roster-person {
  display: inline-flex; align-items: center; gap: 5px; background: var(--panel-2);
  border: 1px solid var(--line); border-radius: 999px; padding: 3px 9px 3px 4px; font-size: 0.75rem;
}
.roster-person .avatar { width: 18px; height: 18px; font-size: 0.6rem; }
.roster-person.streamer { border-color: rgba(255,176,32,.5); color: var(--honey); }
.mic-row { display: flex; align-items: center; gap: 10px; margin: 4px 0 2px; font-size: 0.78rem; }
.mic-meter { position: relative; flex: 1; height: 8px; min-width: 60px; background: rgba(0,0,0,.45); border: 1px solid var(--line); border-radius: 999px; overflow: hidden; }
.mic-meter i { display: block; height: 100%; width: 0%; background: linear-gradient(90deg, var(--ok), var(--honey)); transition: width .08s linear; }
.mic-meter b { position: absolute; top: 0; bottom: 0; width: 2px; left: 0; background: rgba(255,255,255,.75); }
.mic-meter i[data-hot="1"] { background: var(--danger); }
.mic-meter[data-muted="1"] i { background: var(--muted); }
.mic-meter.sm { height: 6px; min-width: 48px; flex: 0 0 64px; }

/* ---------------- on-air bar ----------------
   DOCKED, not floating. It is a row of the shell footer (or of the watch chat
   panel while the player is open), so it belongs to a bar and can never sit on
   top of the chat. As a fixed pill at bottom:78px it covered the last 43px of a
   stream's chat and 29px of the message box. */
.onair {
  flex: 0 0 auto; display: flex; align-items: center; gap: 9px; justify-content: center;
  width: 100%; max-width: none; padding: 8px 12px;
  border-radius: 0; border-bottom: 0;
  background: rgba(22,14,14,0.96); border: 1px solid rgba(255,93,108,.45);
  box-shadow: 0 -10px 26px rgba(0,0,0,.45); backdrop-filter: blur(14px);
  font-size: 0.78rem; white-space: nowrap;
}
.onair-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--danger); animation: pulse 1.8s infinite; flex: 0 0 auto; }
.onair-state { font-weight: 800; letter-spacing: .12em; color: var(--danger); }
.onair-time { color: var(--muted); font-variant-numeric: tabular-nums; }
.onair-mic { color: var(--muted); overflow: hidden; text-overflow: ellipsis; max-width: 22vw; }
.onair .chip { padding: 4px 10px; flex: 0 0 auto; }
@media (max-width: 560px) { .onair-mic { display: none; } }
@media (min-width: 1000px) {
  .search-wrap { max-width: 620px; }
}

/* ---------------- chat ---------------- */
.chat-log {
  display: flex; flex-direction: column; gap: 10px; min-height: 45vh; max-height: 58vh;
  /* NOT `scroll-behavior: smooth`: every programmatic pin would animate, and a
     second message arriving mid-animation restarts it, so a busy room never
     reaches the bottom and the newest comment stays half-cut. Pin instantly. */
  overflow-y: auto; padding: 6px 2px 14px; overscroll-behavior: contain;
}
.msg { display: flex; gap: 10px; align-items: flex-start; animation: rise .18s ease-out; }
@keyframes rise { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.msg-body { min-width: 0; flex: 1; }
.msg-head { display: flex; align-items: baseline; gap: 7px; flex-wrap: wrap; }
.msg-name { font-weight: 700; font-size: 0.86rem; }
.msg-time { color: var(--muted); font-size: 0.7rem; }
.msg-text { white-space: pre-wrap; word-wrap: break-word; overflow-wrap: anywhere; }
.msg.system .msg-text, .msg.live_end .msg-text { color: var(--muted); font-style: italic; font-size: 0.84rem; }
.msg.live, .msg.live_end {
  border: 1px solid rgba(255, 176, 32, 0.35); background: var(--honey-soft);
  border-radius: 14px; padding: 12px 14px;
}
.msg-actions { opacity: 0; transition: opacity .15s; }
.msg:hover .msg-actions, .msg:focus-within .msg-actions { opacity: 1; }
.react-btn {
  border: 1px solid var(--line); background: var(--panel-2); border-radius: 999px;
  padding: 2px 8px; cursor: pointer; font-size: 0.78rem; color: var(--muted);
}
.chips { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 5px; }
.chip {
  border: 1px solid var(--line); background: var(--panel-2); border-radius: 999px;
  padding: 3px 10px; font-size: 0.78rem; cursor: pointer; display: inline-flex; gap: 5px; align-items: center;
}
.chip.mine { border-color: var(--honey); background: var(--honey-soft); color: var(--honey); }
.typing { height: 18px; color: var(--muted); font-size: 0.78rem; padding-left: 4px; }
.composer {
  /* NOT position:sticky. Both places that use it are full-height flex columns, and
     sticky offsets left it floating ~90px above the tab bar and, on a shorter
     screen, sitting on top of the last comment. It is simply the last row now. */
  display: flex; gap: 8px; align-items: center; flex: 0 0 auto;
  background: rgba(8,8,12,0.86); backdrop-filter: blur(14px); padding: 8px; border: 1px solid var(--line);
  border-radius: 999px; margin-top: 10px;
}
.composer input { border: 0; background: transparent; padding: 10px 4px; }
.composer input:focus { box-shadow: none; }

/* ---------------- watch ---------------- */
/* The stage is PINNED and only the chat scrolls: on a phone the streamer's video
   can never be pulled out of view, and the page itself cannot move at all. */
#view-watch { display: flex; flex-direction: column; }
.watch { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
@media (min-width: 1000px) {
  .watch { display: grid; grid-template-columns: minmax(0, 1.65fr) minmax(320px, 0.85fr); }
}
.watch-stage {
  flex: 0 0 auto; display: flex; flex-direction: column;
  padding: calc(10px + var(--safe-t)) 12px 12px;
}
/* Short phones: cap the stage so the chat keeps a usable height instead of
   being squeezed out. The video letterboxes inside (object-fit). */
@media (max-width: 999px) { .stage-video { max-height: 62vh; } }
/* Landscape phones: a ~390px-tall viewport cannot stack a 16:9 video AND a
   chat — stacking left the chat 18px tall — so put them side by side instead. */
@media (max-width: 999px) and (min-aspect-ratio: 1/1) {
  .watch { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); }
  .watch-chat { border-top: 0; border-left: 1px solid var(--line); }
}
.stage-head { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.stage-meta { display: flex; align-items: center; gap: 10px; flex: 1; min-width: 0; }
.stage-video { position: relative; background: #000; border-radius: var(--radius); overflow: hidden; aspect-ratio: 16/9; box-shadow: var(--shadow); }
.stage-video video { width: 100%; height: 100%; object-fit: contain; display: block; background: #000; }
.stage-msg { position: absolute; inset: 0; display: grid; place-items: center; text-align: center; padding: 22px; color: var(--muted); font-weight: 600; pointer-events: none; }
.stage-actions { position: absolute; left: 10px; bottom: 10px; display: flex; gap: 8px; flex-wrap: wrap; }
.stage-actions .chip { background: rgba(0,0,0,0.6); backdrop-filter: blur(8px); }
.watch-chat {
  display: flex; flex-direction: column; min-height: 0; flex: 1 1 auto;
  padding: 12px; border-top: 1px solid var(--line);
}
@media (min-width: 1000px) { .watch-chat { border-top: 0; border-left: 1px solid var(--line); } }
.watch-chat-head { font-weight: 700; margin-bottom: 8px; display: flex; justify-content: space-between; }
.watch-chat .chat-log { max-height: none; flex: 1 1 auto; min-height: 0; }

/* ---------------- chat tab: a real chat layout ----------------
   The page fills the space #main gives it, the log takes everything left over and
   scrolls inside itself, and the composer is simply the last row — flush above the
   tab bar instead of floating with a 90px hole beneath it. */
.page[data-page='chat'] {
  display: flex; flex-direction: column;
  height: 100%; min-height: 0;
}
.page[data-page='chat'] .chat-log {
  /* basis 0, not auto: with an auto basis the log's content height makes the
     browser share the shrinking across every row, which squashed the 18px typing
     line down to 4px. Basis 0 means the log absorbs all spare height alone. */
  flex: 1 1 0; min-height: 0; max-height: none;
}
.page[data-page='chat'] > *:not(.chat-log) { flex: 0 0 auto; }
.watch-chat .composer { margin-top: 10px; }

/* ---------------- tabbar ---------------- */
/* A real row at the end of the shell column now, not a fixed overlay: the on-air
   strip docks above it and neither can cover the content. */
.shell-foot { flex: 0 0 auto; display: flex; flex-direction: column; }
.tabbar {
  position: relative; flex: 0 0 auto; z-index: 30; display: flex;
  padding: 8px 8px calc(8px + var(--safe-b));
  background: rgba(8,8,12,0.86); backdrop-filter: blur(20px); border-top: 1px solid var(--line);
}
.tab {
  flex: 1; border: 0; background: transparent; color: var(--muted); cursor: pointer;
  display: flex; flex-direction: column; align-items: center; gap: 3px; padding: 7px 4px;
  font-size: 0.7rem; font-weight: 650; border-radius: 14px; position: relative;
}
.tab.is-active { color: var(--honey); background: var(--honey-soft); }
.tab-ico { font-size: 1.05rem; }
.badge {
  position: absolute; top: 2px; right: 22%; background: var(--honey); color: #17130a;
  border-radius: 999px; font-size: 0.62rem; padding: 1px 5px; font-weight: 800;
}

/* ---------------- studio / profile ---------------- */
.kv { display: flex; flex-direction: column; gap: 4px; margin-bottom: 10px; }
.kv > span { color: var(--muted); font-size: 0.78rem; font-weight: 600; }
.kv code, code.copy {
  display: block; background: rgba(0,0,0,0.42); border: 1px solid var(--line);
  border-radius: var(--radius-sm); padding: 10px 12px; overflow-x: auto; white-space: nowrap; cursor: copy;
}
code.copy::after { content: " ⧉"; color: var(--muted); }
.row { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 8px; }
.cam-preview { width: 100%; border-radius: var(--radius-sm); margin-top: 10px; background: #000; }
details.notes { margin-top: 12px; border-top: 1px solid var(--line); padding-top: 10px; }
details.notes summary { cursor: pointer; color: var(--muted); font-size: 0.8rem; font-weight: 600; list-style: none; }
details.notes summary::-webkit-details-marker { display: none; }
details.notes summary::before { content: '▸ '; }
details.notes[open] summary::before { content: '▾ '; }
details.notes summary:hover { color: var(--text); }
details.notes p { margin: 8px 0 0; }
.profile-card .profile-top { display: flex; gap: 14px; align-items: center; margin-bottom: 16px; }
.profile-name { font-size: 1.15rem; font-weight: 700; }
.accent-row { display: flex; gap: 8px; flex-wrap: wrap; }
.accent-swatch { width: 30px; height: 30px; border-radius: 50%; border: 2px solid transparent; cursor: pointer; }
.accent-swatch.is-active { border-color: #fff; }

/* ---------------- toasts / sheet ---------------- */
.toasts { position: fixed; top: calc(12px + var(--safe-t)); left: 50%; transform: translateX(-50%); z-index: 100; display: flex; flex-direction: column; gap: 8px; width: min(92vw, 420px); }
.toast {
  background: rgba(20,20,28,0.95); border: 1px solid var(--line-strong); border-radius: 14px;
  padding: 11px 14px; font-size: 0.86rem; box-shadow: var(--shadow); animation: rise .2s ease-out;
}
.toast.err { border-color: rgba(255,93,108,.5); }
.sheet { position: fixed; inset: 0; z-index: 90; background: rgba(0,0,0,0.6); backdrop-filter: blur(4px); display: flex; align-items: flex-end; }
.sheet-inner { width: 100%; background: var(--bg-2); border-top: 1px solid var(--line); border-radius: 22px 22px 0 0; padding: 16px 16px calc(16px + var(--safe-b)); animation: rise .18s ease-out; }
.sheet-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; }
.emoji-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(52px, 1fr)); gap: 6px; max-height: 40vh; overflow-y: auto; }
.emoji-cell { font-size: 1.5rem; border: 0; background: transparent; border-radius: 12px; padding: 8px 0; cursor: pointer; }
.emoji-cell:hover { background: var(--panel-2); }
.sheet-foot { margin-top: 10px; text-align: center; }

/* ---------------- update bar (stale client) ---------------- */
/* Only appears when the server serves a newer build AND a broadcast is live,
   because otherwise the page reloads itself. Sits above the on-air bar. */
.update-bar {
  position: fixed; top: calc(8px + var(--safe-t)); left: 50%; transform: translateX(-50%);
  z-index: 110; display: flex; align-items: center; gap: 10px;
  background: rgba(30,23,8,0.97); border: 1px solid rgba(255,196,0,.45);
  border-radius: 999px; padding: 7px 8px 7px 14px; font-size: 0.82rem;
  box-shadow: var(--shadow); max-width: min(94vw, 520px);
}
.update-bar .update-msg { line-height: 1.25; }
.update-bar .update-msg b { color: #ffc400; }
.update-bar .chip { flex: none; white-space: nowrap; }

/* ---------------- build tag (which client build am I running) ---------------- */
.build-tag { opacity: 0.55; }
.build-line { margin: 4px 0 14px; font-size: 0.78rem; }
.build-line .is-stale, #build-state.is-stale { color: #ffc400; }
